From 200393c4d47f00581928cec4d53027d304d65968 Mon Sep 17 00:00:00 2001 From: veypi Date: Mon, 25 Nov 2024 22:42:49 +0800 Subject: [PATCH] test: front --- oa/front/audio.html | 50 +++++++++++ oa/front/card.html | 26 ++++++ oa/front/favicon.ico | Bin 0 -> 3694 bytes oa/front/index.html | 31 +++++++ oa/front/layout/default.html | 12 +++ oa/front/router.html | 6 ++ oa/front/tailwind.config.js | 28 +++++++ oa/front/v.js | 158 +++++++++++++++++++++++++++++++++++ oa/front/v2dom/v.js | 10 +++ 9 files changed, 321 insertions(+) create mode 100644 oa/front/audio.html create mode 100644 oa/front/card.html create mode 100644 oa/front/favicon.ico create mode 100644 oa/front/index.html create mode 100644 oa/front/layout/default.html create mode 100644 oa/front/router.html create mode 100644 oa/front/tailwind.config.js create mode 100644 oa/front/v.js create mode 100644 oa/front/v2dom/v.js diff --git a/oa/front/audio.html b/oa/front/audio.html new file mode 100644 index 0000000..07b5f23 --- /dev/null +++ b/oa/front/audio.html @@ -0,0 +1,50 @@ + + + + + + + Music Player + + + + +
+ + + +
+
+
+ + + + + diff --git a/oa/front/card.html b/oa/front/card.html new file mode 100644 index 0000000..58a05b2 --- /dev/null +++ b/oa/front/card.html @@ -0,0 +1,26 @@ + + + + + + Card + + + + +
+ slot a +
+
+ +
+
+
+ + + + diff --git a/oa/front/favicon.ico b/oa/front/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..e26bc40e2c5fe25f828982150e79a809d3fb68f8 GIT binary patch literal 3694 zcmeHKdpMNa8vh1`ia06?d+a2%F_hhC$fe{~!gN7x_dA)vFz!srB{8CLDSI-xWU7Nb zWD>cQTtdcX7|k@X6GAg$LM}7Ts&oE1f1Kz1bN)Qv^Q`ZE*7|)t>7)}j^F|z5ny3&0YS8!?HgWOz#N7{Tc3cc`&DMZM9s$r zZ4W_l2O)@X9fH=t65$gBMd?G(tS1DaiXcca?Ds||6YycH_i1ZOAi=YGvMCt|=`b5t z9FR6YhSlp3Q?QTiww4y>W7s^dTbA2}y`2jI*&3d$fiKWSgBK4eo!nvIX{$4nnz64s zQ$~Yw-%##)QIS&ffU_J?5E~Ubaa#Ru7bgS91*r3hL&K1)+@J z_j1P8-ISbkpNT zS(RJ9u^jp+L;cQQUaH&gl|M;N&bo5<0lv!|p=REgri|Ra$HvaC7}-U;srQI`L6Nqx zHb;BrlTO^Jq-vI0&rxe)>#2iiQCjk~Q13WKCZT&^TOyHS<@N6xTpJwGX!cVC z@y(rcO~0IZrHr-YK0Bv6?T@xyD7k@I8#g-Yro;O(7s!}Xrjg8q{FPrME zDn!61iqRW&{d56y^tJ=>Q9(2>bG~;j6hH5uC==`{F^DR2&NSOhV7_?4cDw&ZB!Fkf z-of2N^+qx7DZS0gV)B)muR=kp9CzA&x?uQXn{W4v+)7J9w?9kIwm^_Ebwks|BW1yJ z+v7wXkJyU$cY2_My+M_yn!kPMKQz;@Io5gi#GKUKa#GHb)RCHR8NsSZ%ux)9M7mg0 z&6NoYmfZPhqLdKrK%QJW+Jx`uJ~(z#hD-czP}J+;y}sBR5-on_Uc$}0&GAti9T2eS z-&-JcH(B@?-(_@6tQ_1R!^tDYi-#e^-HX?o{UmR1r_Bww=Jm?~@6vcFl0NHwM}U$i zr$I=WKD~4eSqeB~pL0BRQ50Z<2i=l5^X?r8DZ=u^VfRSo-pfzz?Ce@M6IIwWb>ei? z_SJ~NSiy(&Mc%yNTHmRgrFyP|u^StLvZ>t@(AhM|LUFWKW7fIlZ_d*uqHj#08$EIP zZJrL|(gAI4U3V3a-WRv$nsTP0o~Y8C9b4Ji5A#N7p?iE&o92mY!!`IZw=3L+JI61h z(U)p1Rj-n)O*HqxCOvz)6m_V=V0H>lE%c@GpD2lpCrOD3jtMg$a33=03?p^AqV6C~ zZIA;qJap^quZK}9@2K33ZXdC7`xy00l_lc7>v-FOLPS8v;&~cxRp1l<_ONY%q~vgT zb>Q1tYD&t&lAwQxMyY)s8T6TP_gA4%;h&ZgmDLK&gfmh^`{H0^iUN(d0c#2KViIvD z3ydF395(RoQLk8u_)`pc@VR`|P!4SIX={gMyI0mu zH}tXM9URb;kRpVmgkRaJ6gMe3Xu|6bWT7c0(H3){B32NLyo&$X9LgFR_vFd`fZh(9 zI9Ouh@dpKu3{(U#?cWl@&sV=Z@tyMeK*eNl2%zjYhkk#lY3ACL;>qGeWT4jP58j<4 zKJmkk*xc*t*5IUbpYbxE^ZB+|&=A99CBm99RKVMU22zRoVj^@FA*S_l2- zF(_HXuZ8o;^~UC!R)7^Y;m?1k6rLcQ%gY<=C(mY%cgw0!xiFN07%VO?H2Jd+tr_FS ztPd%hy8V$mwK^U0W2Xbd|0?Qh8`BdmvRS9~9&)+9Esn8cEo^&Gl*A&pATf&qBU8a0 zD)POSwzeD2{&NZb5>Kzv5gqrL_D|50JY{5|hn}|f-N@B~LY@u2Z~7RYblHhtZ*Mq4yya3wcUK56CU z=bKm;ZS7Xxfeg#ahF}k_ht{~rb5`%6S#FB?*6l=w$L78zhvY|G=}s#Gr0}8hO`b+x z9{MMzkGMT>Q5cWkIHZgP={#3u5Y-X-j*|(&Iy>kAZ}NO&mu8LdL-qii*^Aek-IscP zae~LF&2poyJwLNAG#xpkCnn*B`Fg<-`A+TiqGGGkdTj8vb91jX%VcFv3Ewij?J_wv zD<}YZnO%H@k;S|4xO6JsB60Q{tt8JS1DPrdC$8P}uoQ|`)V1iCD(>D{HS>YPWtEib z=jbl}mV88syIu>D>H#sIcx}2VNK%)X2uFdmjcxPvg@7yT9b>k(UtDL`^Gt|8}wh1Ce zMy5lQldPioY*RSTesjM`POWOl0e0=-uwkCgbi6HaR87)u^_$NZm9^S;?HM>CT4hkp zR&N~Wonv)%e|Q@Z5}o$mk^s4d2>fje<{N)mP8JkPW##6w$@k4bHqB)}(??XidTGKu zMS!Z>Uz$Wpf>@jyb}kcbOgph^awtkaRde_1{{*7%c&AGd(s0++g|W>MjI5Rg0lLk9 zgVbjne6hpQ&JzVdrju*vd|gZ3~o;3Oj*# zF1PePzU+OpN0!cFIHgryt%`(T{eG+tuPOYC>(JL*$f(udX|z|YJb!VLEYZz0iqW4< zlW_vuzvjKd2l}|zp`Z$rQ?+4Uyt8rbJ~=ZW8nv~Bi-qC+`_0s(&7}bq|2ZRWrlQ_> zMo*_te1LUjeVLQP9U;ekK$)oIG&b|-RNNFZX$7L}=lrCS#Wv)9qg1=?gcAv)fBZaq z!Ff2T5TbOvYgpyZvln2d+^G5YRFCyb%sNK35CfSjhEMoU_TUpJ4i{AS-e5fopP=QY zhHBm;Nka+&95Z2%vFR7hOFLCE)_7QJPaRkEdgXTLcprV5k<%C-ZG3I~{1V8ioyT`A z-3=*inNO@wz6%YcgJRQYXqvIY3$b?mxc1?uQ>%bXg|9jCO7=kGMwoXAdCDcy*DKNw<=L;4Bu6W^azF2I89#C}lD@GaUg=|lqwX8nj GdF>ys{&!RW literal 0 HcmV?d00001 diff --git a/oa/front/index.html b/oa/front/index.html new file mode 100644 index 0000000..6e89a6b --- /dev/null +++ b/oa/front/index.html @@ -0,0 +1,31 @@ + + + + + + Index + + + + + +
+
123
+
123
+
123
+
+
111
+
c1
+
333
+
+
+
c2
+
+
+ + + + + diff --git a/oa/front/layout/default.html b/oa/front/layout/default.html new file mode 100644 index 0000000..3b9a9b1 --- /dev/null +++ b/oa/front/layout/default.html @@ -0,0 +1,12 @@ + + + Default + + +
+
+ +
+ diff --git a/oa/front/router.html b/oa/front/router.html new file mode 100644 index 0000000..969d7a5 --- /dev/null +++ b/oa/front/router.html @@ -0,0 +1,6 @@ + + > + + + diff --git a/oa/front/tailwind.config.js b/oa/front/tailwind.config.js new file mode 100644 index 0000000..16b1323 --- /dev/null +++ b/oa/front/tailwind.config.js @@ -0,0 +1,28 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: [ + "./components/**/*.{js,vue,ts}", + "./layouts/**/*.vue", + "./pages/**/*.vue", + "./plugins/**/*.{js,ts}", + "./app.vue", + "./error.vue", + "*.html", + ], + theme: { + extend: { + colors: { + vprimary: '#2196f3', + vsecondary: '#ecc94b', + vaccents: '#ff9800', + verror: '#f44336', + vwaring: '#ff5722', + vinfo: '#ffc107', + vsuccess: '#53de58', + vignore: '#d1d5db', + } + }, + }, + plugins: [], +} + diff --git a/oa/front/v.js b/oa/front/v.js new file mode 100644 index 0000000..c2f26c8 --- /dev/null +++ b/oa/front/v.js @@ -0,0 +1,158 @@ +/* + * v.js + * Copyright (C) 2024 veypi + * + * Distributed under terms of the GPL license. + */ + +(function () { + 'use strict'; + + const config = { childList: true, subtree: true }; + + const callback = function (mutationsList, observer) { + for (let mutation of mutationsList) { + if (mutation.type === 'childList') { + // console.log(mutation) + // console.log('A child node has been added or removed.'); + } + } + }; + + const observer = new MutationObserver(callback); + + var cacheUrl = {} + var pendingRequests = {}; + + async function fetchFileWithCache(url) { + if (cacheUrl[url]) { + return Promise.resolve(cacheUrl[url]); + } + if (pendingRequests[url]) { + return pendingRequests[url]; + } + const promise = fetch(url) + .then(response => { + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + return response.text(); + }) + .then(txt => { + cacheUrl[url] = txt; + return txt; + }) + .catch(error => { + console.error('Error fetching the file:', error); + delete pendingRequests[url]; + throw error; + }) + .finally(() => { + delete pendingRequests[url]; + }); + pendingRequests[url] = promise; + return promise; + } + + + function extractBodyAndScript(htmlString) { + const bodyMatch = htmlString.match(/]*>([\s\S]*)<\/body>/i); + const bodyContent = bodyMatch ? bodyMatch[1] : ''; + + let scriptMatches = htmlString.match(/]*>([\s\S]*?)<\/script>/ig); + + + let scriptContents = [] + let srcReg = /]*src=["']([^"']+)["'][^>]*>/ + for (let s of scriptMatches) { + let match = srcReg.exec(s) + if (match && match.length) { + // handle src script + // console.log(match[1]) + } else { + scriptContents.push(s.replace(/]*>|<\/script>/ig, '')) + } + } + return { + bodyContent, + scriptContents + }; + } + + /* + * @param {HTMLElement} node + * @return {Promise} + * */ + async function setupRef(node, data, itercount = 0) { + console.log(itercount) + if (itercount > 100) { + log.warn('infinite loop') + return + } + const ref = node.getAttribute('ref') + node.setAttribute('tag', ref) + node.removeAttribute('ref') + const txt = await fetchFileWithCache(ref + ".html") + let ast = extractBodyAndScript(txt) + + let div = document.createElement('div') + div.innerHTML = ast.bodyContent + + handleSlots(node, div) + // + node.innerHTML = div.innerHTML + + let resp = new Function("{vnode,data}", ast.scriptContents.join('\n'))({ vnode: node, data: data }) + + for (let n of node.querySelectorAll("div[ref]")) { + // 确保子元素先加载完 + await setupRef(n, resp?.data || {}, itercount + 1) + } + } + + function handleSlots(origin, template) { + // handle slots + let originSnap = { '': [] } + let i = 0 + let child + while (child = origin.children.item(i)) { + i++ + let slotname = child.getAttribute ? child.getAttribute('slot') || '' : '' + if (slotname !== '') { + child.removeAttribute('slot') + originSnap[slotname] = child + } else { + originSnap[''].push(child) + } + } + + app.b = originSnap + let slots = template.querySelectorAll('slot') + slots.forEach((slot) => { + let slotname = slot.getAttribute('name') || '' + let snap = originSnap[slotname] + if (snap && snap.length !== 0) { + if (slotname === '') { + slot.replaceWith(...snap) + } else { + slot.replaceWith(snap) + } + } else { + slot.replaceWith(...slot.childNodes) + } + }) + } + + document.addEventListener('DOMContentLoaded', () => { + console.log('DOMContentLoaded'); + const node = document.getElementById('app'); + observer.observe(node, config); + const sync = () => { + let test = node.querySelectorAll("div[ref]") + test.forEach(n => setupRef(n, app)) + } + sync() + // setInterval(sync, 10) + }); + +})(); diff --git a/oa/front/v2dom/v.js b/oa/front/v2dom/v.js new file mode 100644 index 0000000..f153290 --- /dev/null +++ b/oa/front/v2dom/v.js @@ -0,0 +1,10 @@ +/* + * v.js + * Copyright (C) 2024 veypi + * + * Distributed under terms of the GPL license. + */ + +export default { + a: 123 +}