djledda.de main
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

GEDeutschArticle.tsx 2.8 KiB

2 miesięcy temu
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import { h, inject, defineComponent, ref, createTextVNode, type VNode } from 'vue';
  2. import { RouterLink } from 'vue-router';
  3. import useAsyncState from "@/useAsyncState.ts";
  4. export default defineComponent({
  5. name: 'ge-deutsch-article',
  6. props: {
  7. articleName: {
  8. type: String,
  9. required: true,
  10. },
  11. },
  12. async setup(props) {
  13. const currentLang = ref<"en" | "de">("de");
  14. function clickBtn() {
  15. currentLang.value = currentLang.value === "en" ? "de" : "en";
  16. }
  17. const parseDom = inject('dom-parse', (innerHTML: string) => Object.assign(document.createElement('div'), { innerHTML }));
  18. const { result: articleContent, stateIsReady } = useAsyncState('ge-deutsch-article-data', async ({ hostUrl }) => {
  19. const articleResponse = await fetch(`${ hostUrl }/generative-energy/static/content/${ props.articleName }.html`);
  20. return await articleResponse.text();
  21. });
  22. function transformArticleNode(node: Node): VNode | string {
  23. if (node.nodeType === node.ELEMENT_NODE) {
  24. const el = node as Element;
  25. const attrs: Record<string, string> = {};
  26. const children = [...node.childNodes].map(_ => transformArticleNode(_));
  27. if (el.tagName === 'P') {
  28. el.classList.add('text-slab');
  29. children.unshift(h('button', { class: 'swap', onClick: (e) => {
  30. e.target.parentElement.classList.toggle('swap');
  31. } }, '↻'));
  32. }
  33. for (let i = 0; i < el.attributes.length; i++) {
  34. const item = el.attributes.item(i);
  35. if (item) {
  36. attrs[item.name] = item.value;
  37. }
  38. }
  39. return h((node as Element).tagName, attrs, children);
  40. } else {
  41. return createTextVNode(node.textContent ?? '');
  42. }
  43. }
  44. function ArticleContentTransformed() {
  45. if (articleContent.value) {
  46. const dom = parseDom(articleContent.value);
  47. return h('div', {}, [...dom.children].map(_ => transformArticleNode(_)));
  48. }
  49. return <div>Artikel lädt...</div>;
  50. }
  51. await stateIsReady;
  52. return () => <div class="ge-article">
  53. <div class="header">
  54. <RouterLink to={{ name: 'GEDeutsch' }}>Zur Artikelübersicht</RouterLink>
  55. <button onClick={clickBtn}>
  56. Sprache auf <span>{currentLang.value === "en" ? "Deutsch" : "Englisch"}</span> umschalten
  57. </button>
  58. </div>
  59. <article class={`lang-${ currentLang.value }`}>
  60. <ArticleContentTransformed />
  61. </article>
  62. </div>;
  63. }
  64. });