wiki-plugin-livecode 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/livecode.js +4 -4
- package/client/livecode.js.map +3 -3
- package/package.json +1 -1
package/client/livecode.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
(()=>{var
|
|
2
|
-
`)},
|
|
3
|
-
`);for(let
|
|
4
|
-
`),e.name||(e.name=
|
|
1
|
+
(()=>{var S="https://wasm.livecode.wiki/assets/wasm/v11/stack.html",W=t=>{let e=Array.isArray(t)&&t.length===3?t:["Left","Centre","Right"],n=s=>String(s).replace(/"/g,"'").replace(/[\r\n]/g," ");return['script "Triptych"',"","on preOpenStack"," buildTriptych","end preOpenStack","on startup"," buildTriptych","end startup","on openStack"," buildTriptych","end openStack","","local sBuilt","","command buildTriptych"," if sBuilt is true then exit buildTriptych"," put true into sBuilt"," repeat the number of controls of this card"," delete last control"," end repeat"," local tW, tH, p, zw"," put winWidth() into tW"," put winHeight() into tH"," set the rect of this stack to 0, 0, tW, tH"," set the resizable of this stack to true",' set the backgroundColor of this card to "248,249,251"'," put 14 into p"," put trunc((tW - 4 * p) / 3) into zw",` makeColumn "col1", p, zw, tH, "${n(e[0])}", "225,235,252"`,` makeColumn "col2", p + zw + p, zw, tH, "${n(e[1])}", "255,248,232"`,` makeColumn "col3", p + 2 * (zw + p), zw, tH, "${n(e[2])}", "228,244,230"`,"end buildTriptych","","on resizeStack pW, pH"," if sBuilt is true then"," layoutTriptych pW, pH"," end if","end resizeStack","","command layoutTriptych tW, tH"," local p, zw"," put 14 into p"," put trunc((tW - 4 * p) / 3) into zw",' layoutColumn "col1", p, zw, tH',' layoutColumn "col2", p + zw + p, zw, tH',' layoutColumn "col3", p + 2 * (zw + p), zw, tH',"end layoutTriptych","","command layoutColumn pName, pX, pW, pH"," set the rect of graphic pName to pX, 14, pX + pW, pH - 14",' set the rect of field (pName & "L") to pX, 22, pX + pW, 48',"end layoutColumn","","command makeColumn pName, pX, pW, pH, pLabel, pColor"," create graphic pName",' set the style of graphic pName to "roundrect"'," set the rect of graphic pName to pX, 14, pX + pW, pH - 14"," set the opaque of graphic pName to true"," set the backgroundColor of graphic pName to pColor",' set the lineColor of graphic pName to "205,210,220"',' create field (pName & "L")',' set the rect of field (pName & "L") to pX, 22, pX + pW, 48',' set the textAlign of field (pName & "L") to "center"',' set the textSize of field (pName & "L") to 15',' set the borderWidth of field (pName & "L") to 0',' set the opaque of field (pName & "L") to false',' set the lockText of field (pName & "L") to true',' put pLabel into field (pName & "L")',"end makeColumn","","function winWidth"," local w",' do "window.innerWidth" as "javascript"'," put the result into w"," if w is not a number or w < 200 then put 700 into w"," return w","end winWidth","","function winHeight"," local h",' do "window.innerHeight" as "javascript"'," put the result into h"," if h is not a number or h < 120 then put 340 into h"," return h","end winHeight"].join(`
|
|
2
|
+
`)},C=t=>{let e={engine:null,title:null,height:420,width:null,triptych:!1,columns:null,boot:"auto",fullscreen:"fixed",name:null,script:null,transparent:!1,behind:null,zone:null},n=!1,s=!1,o=(t||"").split(`
|
|
3
|
+
`);for(let i=0;i<o.length;i++){let a=o[i].match(/^\s*script\s+"([^"]+)"/);if(a){e.script=o.slice(i).join(`
|
|
4
|
+
`),e.name||(e.name=a[1]),e.title||(e.title=a[1]);break}if(/^\s*TRIPTYCH\s*$/i.test(o[i])){e.triptych=!0;continue}if(/^\s*TRANSPARENT\s*$/i.test(o[i])){e.transparent=!0;continue}let u=o[i].trim().match(/^([A-Z]+):?\s+(.*)$/);if(!u)continue;let[,d,h]=u,c=h.trim();if(d==="ENGINE"||d==="STACK")e.engine=c;else if(d==="TITLE")e.title=c;else if(d==="HEIGHT"){let r=parseInt(c,10);r&&(e.height=r,s=!0)}else if(d==="ZONE"){let r=c.replace(/[:,]/g,"").trim();e.zone=r||"zone"}else if(d==="BOOT")e.boot=c.toLowerCase()==="click"?"click":"auto";else if(d==="FULLSCREEN"){let r=c.toLowerCase();e.fullscreen=["fixed","scale","resize"].includes(r)?r:"fixed",n=!0}else if(d==="NAME")e.name=c;else if(d==="WIDTH"){let r=c.toLowerCase();e.width=r==="full"||r==="page"||r==="lineup"?"full":parseInt(c,10)||null}else d==="TRIPTYCH"?(e.triptych=!0,c&&(e.columns=c.split("|").map(r=>r.trim()).filter(Boolean))):d==="COLUMNS"?e.columns=c.split("|").map(r=>r.trim()).filter(Boolean):d==="BEHIND"&&(e.behind=c)}if(e.triptych&&!e.script&&(e.script=W(e.columns),e.name||(e.name="Triptych"),e.title||(e.title="Triptych"),n||(e.fullscreen="resize")),e.zone)return e.engine=null,e.script=null,e.triptych=!1,s||(e.height=200),e.title||(e.title=e.zone),e;if(e.script&&!e.engine&&(e.engine=S),!e.title&&e.engine){let i=e.engine.split("/").pop()||"";e.title=(i.split("?")[0]||"").replace(/\.html?$/i,"")||"Livecode stack"}return e},y=t=>String(t).replace(/[&<>"']/g,e=>({"&":"&","<":"<",">":">",'"':""","'":"'"})[e]),T=(t,e)=>/^https?:\/\//i.test(e)?e:`//${t.parents(".page").data("site")||window.location.host}/${e.replace(/^\//,"")}`,E=()=>{let t=[...document.querySelectorAll(".page")];return t.length<2?"":t.map(e=>{let n=e.getBoundingClientRect();return Math.round(n.left)+":"+Math.round(n.width)}).join(",")},M=(t,e)=>{let n={};return[...document.querySelectorAll(".item[data-zone]")].map(s=>{let o=s.dataset.zone||"zone";n[o]=(n[o]||0)+1,n[o]>1&&(o+=n[o]);let i=s.getBoundingClientRect();return[o,Math.round(i.left-(t||0)),Math.round(i.top-(e||0)),Math.round(i.width),Math.round(i.height)].join(":")}).join(",")},x=(t,e,n)=>{let s=e.querySelector(".livecode-bar"),o=s?s.offsetHeight:0;e.style.minHeight=n+o+"px";let i=e.getBoundingClientRect();return t.style.setProperty("position","fixed","important"),t.style.setProperty("left","0px","important"),t.style.setProperty("width","100vw","important"),t.style.setProperty("max-width","100vw","important"),t.style.setProperty("top",Math.round(i.top+o)+"px","important"),t.style.marginLeft="0px",Math.abs(t.getBoundingClientRect().left)<=2},L=t=>{let e=t.__livecode;e&&(clearInterval(e.watch),window.removeEventListener("message",e.onMessage),document.removeEventListener("fullscreenchange",e.onFsChange),e.onResize&&window.removeEventListener("resize",e.onResize),e.onScroll&&(window.removeEventListener("scroll",e.onScroll,!0),e.scroller&&e.scroller.removeEventListener("scroll",e.onScroll)),e.observer&&e.observer.disconnect(),(e.mount||e.frame).remove(),e.bar.remove(),e.poster.style.display="",t.__livecode=null)},_=(t,e,n,s)=>{if(t.__livecode)return;if(s+=(s.includes("?")?"&":"?")+"fs="+n.fullscreen,n.name&&(s+="&stack="+encodeURIComponent(n.name)),n.script&&(s+="&boot=script"),n.transparent&&(s+="&bg=transparent"),n.width==="full"){let l=E();l&&(s+="&zones="+encodeURIComponent(l))}let o=document.createElement("div");o.className="livecode-bar",o.style.cssText="display:flex;justify-content:space-between;align-items:center;font-size:12px;color:#666;padding:2px 4px 4px",o.innerHTML=`<span>${y(n.title)}</span><span><span class="livecode-full" style="cursor:pointer;color:#666;margin-right:12px" title="fullscreen (${y(n.fullscreen)})">⛶ full</span><span class="livecode-stop" style="cursor:pointer;color:#b5511d">■ stop</span></span>`;let i=document.createElement("iframe");i.className="livecode-frame",i.src=s,i.setAttribute("allow","fullscreen"),i.setAttribute("allowfullscreen",""),n.transparent&&i.setAttribute("allowtransparency","true"),i.style.cssText=`width:100%;height:${n.height}px;border-radius:6px;`+(n.transparent?"border:0;background:transparent":"border:1px solid #e0e0e0;background:#fff");let a=i;if(n.behind){let l=document.createElement("div");l.className="livecode-stage",l.style.cssText=`position:relative;width:100%;height:${n.height}px;border-radius:6px;overflow:hidden`;let p=document.createElement("iframe");p.className="livecode-behind",p.src=n.behind,p.setAttribute("scrolling","no"),p.style.cssText="position:absolute;inset:0;width:100%;height:100%;border:0;z-index:0",i.style.position="absolute",i.style.inset="0",i.style.width="100%",i.style.height="100%",i.style.borderRadius="0",i.style.zIndex="1",l.appendChild(p),l.appendChild(i),a=l}n.width==="full"?(requestAnimationFrame(()=>requestAnimationFrame(()=>{let l=x(a,t,n.height);t.dataset.fullWidth=l?"ok":"retrying",l||setTimeout(()=>{t.dataset.fullWidth=x(a,t,n.height)?"ok":"failed"},250)})),a.style.position="relative",a.style.zIndex="30",t.style.overflow="visible"):typeof n.width=="number"&&(a.style.width=n.width+"px",a.style.maxWidth="none",t.style.overflow="visible");let u=l=>{try{i.contentWindow.postMessage({livecode:{command:l,mode:n.fullscreen}},"*")}catch{}},d=l=>{if(!t.__livecode||l.source!==i.contentWindow)return;let p=l.data&&l.data.livecode;p&&p.ready==="script"&&n.script&&i.contentWindow.postMessage({livecode:{bootScript:n.script}},"*"),t.dataset.lastMessage=JSON.stringify(l.data),window.$&&window.$(t).trigger("livecodeMessage",[l.data])};window.addEventListener("message",d);let h=()=>{t.__livecode&&(document.fullscreenElement===i?u("fullscreen"):document.fullscreenElement||u("fullscreenExit"))};document.addEventListener("fullscreenchange",h);let c=null,r=null,m=()=>{if(!t.__livecode)return;n.width==="full"&&x(a,t,n.height);let l=E();if(l!==c){c=l;try{i.contentWindow.postMessage({livecode:{command:"zones",zones:l}},"*")}catch{}}let p=i.getBoundingClientRect(),v=M(p.left,p.top);if(v!==r){r=v;try{i.contentWindow.postMessage({livecode:{command:"marks",marks:v}},"*")}catch{}}};i.addEventListener("load",()=>setTimeout(m,400));let z=null,k=()=>{t.__livecode&&(clearTimeout(z),z=setTimeout(m,150))};window.addEventListener("resize",k);let w=!1,g=null,f=null,b=null;if(n.width==="full"&&(g=()=>{w||!t.__livecode||(w=!0,requestAnimationFrame(()=>{w=!1,m()}))},window.addEventListener("scroll",g,!0),f=document.querySelector(".main"),f&&f.addEventListener("scroll",g),f&&typeof MutationObserver<"u")){let l=null;b=new MutationObserver(()=>{clearTimeout(l),l=setTimeout(m,200)}),b.observe(f,{childList:!0})}let N=setInterval(()=>{document.body.contains(t)||L(t)},4e3);e.style.display="none",t.appendChild(o),t.appendChild(a),o.querySelector(".livecode-stop").addEventListener("click",()=>L(t)),o.querySelector(".livecode-full").addEventListener("click",()=>{i.requestFullscreen&&i.requestFullscreen()}),t.__livecode={poster:e,frame:i,mount:a,bar:o,watch:N,onMessage:d,onFsChange:h,onResize:k,onScroll:g,scroller:f,observer:b}},A=(t,e)=>{let n=C(e.text||"");if(n.zone){t.html(`<div class="livecode-zone" style="height:${n.height}px;border:2px dashed #b8c4d8;border-radius:8px;background:#f8fafd;display:flex;align-items:center;justify-content:center;color:#8a97ad;font-size:14px">▢ zone: ${y(n.zone)}</div>`),t[0].dataset.zone=n.zone,t[0].dataset.height=n.height;return}if(delete t[0].dataset.zone,delete t[0].dataset.height,!n.engine){t.html('<div class="livecode-widget" style="border:1px dashed #ccc;border-radius:6px;padding:12px;color:#888;font-size:13px">livecode — no STACK given. Double click to edit, e.g.<br><code>STACK https://wasm.livecode.wiki/assets/wasm/shared/stack.html?zip=hexagon.zip</code></div>');return}t.html(`<div class="livecode-widget"><div class="livecode-poster" style="cursor:pointer;border:1px solid #e0d5c5;border-radius:6px;padding:14px 16px;background:linear-gradient(135deg,#fff7ee,#ffffff)"><div style="font-weight:bold;font-size:15px">▶ ${y(n.title)}</div><div style="font-size:12px;color:#888;margin-top:4px">Livecode wasm — ${n.script?"runs this item's script with":"loads"} the ${6.4} MB engine</div></div></div>`)},$=(t,e)=>{t.on("dblclick",()=>window.wiki.textEditor(t,e));let n=C(e.text||"");if(n.zone)return;let s=t.find(".livecode-widget")[0],o=t.find(".livecode-poster")[0];if(!n.engine||!s||!o)return;n.behind&&(n.behind=T(t,n.behind));let i=T(t,n.engine),a=u=>{u&&u.stopPropagation(),_(s,o,n,i)};o.addEventListener("click",a),n.boot==="auto"&&a()};typeof window<"u"&&(window.plugins=window.plugins||{},window.plugins.livecode={emit:A,bind:$});})();
|
|
5
5
|
//# sourceMappingURL=livecode.js.map
|
package/client/livecode.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/client/livecode.js"],
|
|
4
|
-
"sourcesContent": ["// wiki-plugin-livecode \u2014 Livecode wasm stacks as wiki widgets.\n//\n// Item text DSL (UPPERCASE commands, per the house fedwiki-dsl convention):\n//\n// STACK wasm/Hexagon/Hexagon.html relative to the item's origin site\n// STACK https://site/assets/.../x.html or absolute\n// TITLE Hexagon poster label (default: file name)\n// HEIGHT 420 iframe height in px (default 420)\n// BOOT auto auto (default) or click\n// FULLSCREEN fixed fixed (default), scale, or resize\n// NAME MyStack stack name for the JS bridge\n// WIDTH full break out of the column: full (page\n// width) or a pixel number (default:\n// column width). The stack reads its\n// real size from window.innerWidth.\n// TRIPTYCH a | b | c turnkey mode: one engine draws three\n// labelled columns (default Left |\n// Centre | Right), sized to the window.\n// COLUMNS a | b | c the three column labels for TRIPTYCH.\n// TRANSPARENT render the stack with a transparent\n// background (opt-in ?bg=transparent on\n// the shell) so the page behind shows\n// through. The stack must leave its\n// card background empty.\n// BEHIND <url> an HTML page drawn behind the (usually\n// TRANSPARENT) stack, inside the same\n// widget \u2014 the animation composites over\n// ordinary web content. Give a full URL.\n//\n// Design (door two of Three Livecode Doors): a livecode item loads and\n// displays its stack by default. BOOT click opts a widget into a light\n// collapsible poster that boots on demand. Every widget runs independently;\n// a watchdog tears a frame down when its item leaves the lineup (fedwiki\n// has no plugin dispose hook \u2014 the htv pattern), and the stop control\n// collapses a running widget back to its poster.\n\nconst ENGINE_MB = 6.4\nconst SHARED_SHELL = 'https://wasm.livecode.wiki/assets/wasm/shared/stack.html'\n\n// TRIPTYCH mode \u2014 generate the LiveCode scaffold for one engine drawing three\n// positioned, labelled columns. It clears the donor capsule's leftover controls\n// (8 hexagon parts on the boot card), reads its real size from the browser\n// window, and lays the columns out proportionally. Authors get three columns\n// with no hand-written LiveCode; behaviour can be layered on later.\nconst triptychScript = (columns) => {\n const cols = (Array.isArray(columns) && columns.length === 3) ? columns : ['Left', 'Centre', 'Right']\n const lab = (s) => String(s).replace(/\"/g, \"'\").replace(/[\\r\\n]/g, ' ')\n return [\n 'script \"Triptych\"',\n '',\n 'on preOpenStack',\n ' buildTriptych',\n 'end preOpenStack',\n 'on startup',\n ' buildTriptych',\n 'end startup',\n 'on openStack',\n ' buildTriptych',\n 'end openStack',\n '',\n 'local sBuilt',\n '',\n 'command buildTriptych',\n ' if sBuilt is true then exit buildTriptych',\n ' put true into sBuilt',\n ' repeat the number of controls of this card',\n ' delete last control',\n ' end repeat',\n ' local tW, tH, p, zw',\n ' put winWidth() into tW',\n ' put winHeight() into tH',\n ' set the rect of this stack to 0, 0, tW, tH',\n ' set the backgroundColor of this card to \"248,249,251\"',\n ' put 14 into p',\n ' put trunc((tW - 4 * p) / 3) into zw',\n ` makeColumn \"col1\", p, zw, tH, \"${lab(cols[0])}\", \"225,235,252\"`,\n ` makeColumn \"col2\", p + zw + p, zw, tH, \"${lab(cols[1])}\", \"255,248,232\"`,\n ` makeColumn \"col3\", p + 2 * (zw + p), zw, tH, \"${lab(cols[2])}\", \"228,244,230\"`,\n 'end buildTriptych',\n '',\n 'command makeColumn pName, pX, pW, pH, pLabel, pColor',\n ' create graphic pName',\n ' set the style of graphic pName to \"roundrect\"',\n ' set the rect of graphic pName to pX, 14, pX + pW, pH - 14',\n ' set the opaque of graphic pName to true',\n ' set the backgroundColor of graphic pName to pColor',\n ' set the lineColor of graphic pName to \"205,210,220\"',\n ' create field (pName & \"L\")',\n ' set the rect of field (pName & \"L\") to pX, 22, pX + pW, 48',\n ' set the textAlign of field (pName & \"L\") to \"center\"',\n ' set the textSize of field (pName & \"L\") to 15',\n ' set the borderWidth of field (pName & \"L\") to 0',\n ' set the opaque of field (pName & \"L\") to false',\n ' set the lockText of field (pName & \"L\") to true',\n ' put pLabel into field (pName & \"L\")',\n 'end makeColumn',\n '',\n 'function winWidth',\n ' local w',\n ' do \"window.innerWidth\" as \"javascript\"',\n ' put the result into w',\n ' if w is not a number or w < 200 then put 700 into w',\n ' return w',\n 'end winWidth',\n '',\n 'function winHeight',\n ' local h',\n ' do \"window.innerHeight\" as \"javascript\"',\n ' put the result into h',\n ' if h is not a number or h < 120 then put 340 into h',\n ' return h',\n 'end winHeight'\n ].join('\\n')\n}\n\nexport const parse = (text) => {\n const spec = { stack: null, title: null, height: 420, width: null, triptych: false, columns: null, boot: 'auto', fullscreen: 'fixed', name: null, script: null, transparent: false, behind: null }\n const lines = (text || '').split('\\n')\n for (let i = 0; i < lines.length; i++) {\n // a script-only stack begins `script \"Name\"` \u2014 everything from that\n // line on is the stack's script, booted directly by the shared shell\n const sm = lines[i].match(/^\\s*script\\s+\"([^\"]+)\"/)\n if (sm) {\n spec.script = lines.slice(i).join('\\n')\n if (!spec.name) spec.name = sm[1]\n if (!spec.title) spec.title = sm[1]\n break\n }\n // a bare TRIPTYCH line (no args) turns on turnkey mode with default labels\n if (/^\\s*TRIPTYCH\\s*$/i.test(lines[i])) { spec.triptych = true; continue }\n // a bare TRANSPARENT line renders the stack with a transparent background\n // (opt-in ?bg=transparent on the shell) so anything behind shows through\n if (/^\\s*TRANSPARENT\\s*$/i.test(lines[i])) { spec.transparent = true; continue }\n const m = lines[i].trim().match(/^([A-Z]+):?\\s+(.*)$/)\n if (!m) continue\n const [, cmd, restRaw] = m\n const rest = restRaw.trim()\n if (cmd === 'STACK') spec.stack = rest\n else if (cmd === 'TITLE') spec.title = rest\n else if (cmd === 'HEIGHT') spec.height = parseInt(rest, 10) || spec.height\n else if (cmd === 'BOOT') spec.boot = rest.toLowerCase() === 'click' ? 'click' : 'auto'\n else if (cmd === 'FULLSCREEN') {\n const mode = rest.toLowerCase()\n spec.fullscreen = ['fixed', 'scale', 'resize'].includes(mode) ? mode : 'fixed'\n } else if (cmd === 'NAME') spec.name = rest\n else if (cmd === 'WIDTH') {\n const v = rest.toLowerCase()\n spec.width = (v === 'full' || v === 'page' || v === 'lineup') ? 'full' : (parseInt(rest, 10) || null)\n }\n else if (cmd === 'TRIPTYCH') {\n spec.triptych = true\n if (rest) spec.columns = rest.split('|').map((s) => s.trim()).filter(Boolean)\n }\n else if (cmd === 'COLUMNS') spec.columns = rest.split('|').map((s) => s.trim()).filter(Boolean)\n else if (cmd === 'BEHIND') spec.behind = rest\n }\n // TRIPTYCH mode generates its own script-only stack from the column labels\n if (spec.triptych && !spec.script) {\n spec.script = triptychScript(spec.columns)\n if (!spec.name) spec.name = 'Triptych'\n if (!spec.title) spec.title = 'Triptych'\n }\n if (spec.script && !spec.stack) spec.stack = SHARED_SHELL\n if (!spec.title && spec.stack) {\n const leaf = spec.stack.split('/').pop() || ''\n spec.title = (leaf.split('?')[0] || '').replace(/\\.html?$/i, '') || 'Livecode stack'\n }\n return spec\n}\n\nconst escapeHtml = (s) =>\n String(s).replace(/[&<>\"']/g, (c) =>\n ({ '&': '&', '<': '<', '>': '>', '\"': '"', \"'\": ''' })[c])\n\nconst resolveUrl = (div, stack) => {\n if (/^https?:\\/\\//i.test(stack)) return stack\n const site = div.parents('.page').data('site') || window.location.host\n return `//${site}/${stack.replace(/^\\//, '')}`\n}\n\n// ---- per-widget lifecycle ---------------------------------------------\n\nconst stopWidget = (widget) => {\n const inst = widget.__livecode\n if (!inst) return\n clearInterval(inst.watch)\n window.removeEventListener('message', inst.onMessage)\n document.removeEventListener('fullscreenchange', inst.onFsChange)\n ;(inst.mount || inst.frame).remove()\n inst.bar.remove()\n inst.poster.style.display = ''\n widget.__livecode = null\n}\n\nconst boot = (widget, poster, spec, url) => {\n if (widget.__livecode) return\n\n // arm the shell's fullscreen mode from load \u2014 deterministic, no message race\n url += (url.includes('?') ? '&' : '?') + 'fs=' + spec.fullscreen\n if (spec.name) {\n url += '&stack=' + encodeURIComponent(spec.name)\n }\n if (spec.script) {\n url += '&boot=script'\n }\n if (spec.transparent) {\n url += '&bg=transparent'\n }\n // WIDTH full pulls the iframe to the viewport's left edge, so iframe x-coords\n // equal viewport x-coords. Hand the stack the REAL lineup column geometry \u2014\n // one x:width pair per .page \u2014 so it can lay zones over the actual columns.\n if (spec.width === 'full') {\n const pages = [...document.querySelectorAll('.page')]\n if (pages.length >= 2) {\n const zones = pages.map((p) => {\n const r = p.getBoundingClientRect()\n return Math.round(r.left) + ':' + Math.round(r.width)\n }).join(',')\n url += '&zones=' + encodeURIComponent(zones)\n }\n }\n\n const bar = document.createElement('div')\n bar.className = 'livecode-bar'\n bar.style.cssText =\n 'display:flex;justify-content:space-between;align-items:center;' +\n 'font-size:12px;color:#666;padding:2px 4px 4px'\n bar.innerHTML =\n `<span>${escapeHtml(spec.title)}</span>` +\n '<span>' +\n `<span class=\"livecode-full\" style=\"cursor:pointer;color:#666;margin-right:12px\" ` +\n `title=\"fullscreen (${escapeHtml(spec.fullscreen)})\">⛶ full</span>` +\n `<span class=\"livecode-stop\" style=\"cursor:pointer;color:#b5511d\">■ stop</span>` +\n '</span>'\n\n const frame = document.createElement('iframe')\n frame.className = 'livecode-frame'\n frame.src = url\n frame.setAttribute('allow', 'fullscreen')\n frame.setAttribute('allowfullscreen', '')\n if (spec.transparent) frame.setAttribute('allowtransparency', 'true')\n frame.style.cssText =\n `width:100%;height:${spec.height}px;border-radius:6px;` +\n (spec.transparent\n ? 'border:0;background:transparent'\n : 'border:1px solid #e0e0e0;background:#fff')\n\n // BEHIND: render an HTML page behind a (usually transparent) stack, both\n // inside one positioned stage, so the livecode animation composites over\n // ordinary web content. Without BEHIND the frame mounts directly as before.\n let mount = frame\n if (spec.behind) {\n const stage = document.createElement('div')\n stage.className = 'livecode-stage'\n stage.style.cssText =\n `position:relative;width:100%;height:${spec.height}px;` +\n 'border-radius:6px;overflow:hidden'\n const back = document.createElement('iframe')\n back.className = 'livecode-behind'\n back.src = spec.behind\n back.setAttribute('scrolling', 'no')\n back.style.cssText =\n 'position:absolute;inset:0;width:100%;height:100%;border:0;z-index:0'\n frame.style.position = 'absolute'\n frame.style.inset = '0'\n frame.style.width = '100%'\n frame.style.height = '100%'\n frame.style.borderRadius = '0'\n frame.style.zIndex = '1'\n stage.appendChild(back)\n stage.appendChild(frame)\n mount = stage\n }\n\n // WIDTH: break the widget out of its fedwiki column so a triptych can span\n // the page. 'full' is the classic full-bleed (100vw pulled to the viewport\n // edge); a number widens to that many px. The stack sizes itself to the\n // resulting window.innerWidth.\n if (spec.width === 'full') {\n mount.style.width = '100vw'\n mount.style.maxWidth = '100vw'\n // pull the mount to the viewport's LEFT EDGE exactly. The classic\n // calc(50% - 50vw) only works when the parent is viewport-centred \u2014 inside\n // a fedwiki column it is not, so measure and pull by the real offset. The\n // zones param is in viewport coords, so iframe x MUST equal viewport x.\n requestAnimationFrame(() => {\n mount.style.marginLeft = '0px'\n const left = mount.getBoundingClientRect().left\n mount.style.marginLeft = (-left) + 'px'\n })\n widget.style.overflow = 'visible'\n } else if (typeof spec.width === 'number') {\n mount.style.width = spec.width + 'px'\n mount.style.maxWidth = 'none'\n widget.style.overflow = 'visible'\n }\n\n const tell = (command) => {\n try {\n frame.contentWindow.postMessage({ livecode: { command, mode: spec.fullscreen } }, '*')\n } catch (e) { /* frame gone */ }\n }\n\n const onMessage = (event) => {\n if (!widget.__livecode || event.source !== frame.contentWindow) return\n const d = event.data && event.data.livecode\n if (d && d.ready === 'script' && spec.script) {\n frame.contentWindow.postMessage({ livecode: { bootScript: spec.script } }, '*')\n }\n widget.dataset.lastMessage = JSON.stringify(event.data)\n if (window.$) window.$(widget).trigger('livecodeMessage', [event.data])\n }\n window.addEventListener('message', onMessage)\n\n const onFsChange = () => {\n if (!widget.__livecode) return\n if (document.fullscreenElement === frame) tell('fullscreen')\n else if (!document.fullscreenElement) tell('fullscreenExit')\n }\n document.addEventListener('fullscreenchange', onFsChange)\n\n // watchdog: fedwiki never tells a plugin its item left the lineup\n const watch = setInterval(() => {\n if (!document.body.contains(widget)) stopWidget(widget)\n }, 4000)\n\n poster.style.display = 'none'\n widget.appendChild(bar)\n widget.appendChild(mount)\n bar.querySelector('.livecode-stop').addEventListener('click', () => stopWidget(widget))\n bar.querySelector('.livecode-full').addEventListener('click', () => {\n if (frame.requestFullscreen) frame.requestFullscreen()\n })\n widget.__livecode = { poster, frame, mount, bar, watch, onMessage, onFsChange }\n}\n\n// ---- fedwiki plugin surface -------------------------------------------\n\nexport const emit = (div, item) => {\n const spec = parse(item.text || '')\n if (!spec.stack) {\n div.html(\n '<div class=\"livecode-widget\" style=\"border:1px dashed #ccc;border-radius:6px;' +\n 'padding:12px;color:#888;font-size:13px\">livecode — no STACK given. ' +\n 'Double click to edit, e.g.<br><code>STACK https://wasm.livecode.wiki/assets/wasm/shared/stack.html?zip=hexagon.zip</code></div>')\n return\n }\n div.html(\n '<div class=\"livecode-widget\">' +\n '<div class=\"livecode-poster\" style=\"cursor:pointer;border:1px solid #e0d5c5;' +\n 'border-radius:6px;padding:14px 16px;background:linear-gradient(135deg,#fff7ee,#ffffff)\">' +\n `<div style=\"font-weight:bold;font-size:15px\">▶ ${escapeHtml(spec.title)}</div>` +\n `<div style=\"font-size:12px;color:#888;margin-top:4px\">Livecode wasm — ` +\n `${spec.script ? \"runs this item's script with\" : 'loads'} the ${ENGINE_MB} MB engine</div>` +\n '</div></div>')\n}\n\nexport const bind = (div, item) => {\n div.on('dblclick', () => window.wiki.textEditor(div, item))\n const spec = parse(item.text || '')\n const widget = div.find('.livecode-widget')[0]\n const poster = div.find('.livecode-poster')[0]\n if (!spec.stack || !widget || !poster) return\n if (spec.behind) spec.behind = resolveUrl(div, spec.behind)\n const url = resolveUrl(div, spec.stack)\n const start = (event) => {\n if (event) event.stopPropagation()\n boot(widget, poster, spec, url)\n }\n poster.addEventListener('click', start)\n if (spec.boot === 'auto') start()\n}\n\nif (typeof window !== 'undefined') {\n window.plugins = window.plugins || {}\n window.plugins['livecode'] = { emit, bind }\n}\n"],
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": ["SHARED_SHELL", "triptychScript", "columns", "cols", "lab", "parse", "text", "spec", "
|
|
4
|
+
"sourcesContent": ["// wiki-plugin-livecode \u2014 Livecode wasm stacks as wiki widgets.\n//\n// Item text DSL (UPPERCASE commands, per the house fedwiki-dsl convention):\n//\n// ENGINE wasm/v11/stack.html relative to the item's origin site\n// ENGINE https://site/assets/.../x.html or absolute. This URL is the SHELL\n// that hosts the LiveCode ENGINE \u2014 it\n// is not a stack. A stack is the\n// binary document the engine runs,\n// named by the shell's ?zip= today.\n// STACK <url> legacy alias for ENGINE, still\n// accepted: 36 items across six sites\n// were authored with it, including the\n// frozen v10 archive. Prefer ENGINE.\n// TITLE Hexagon poster label (default: file name)\n// HEIGHT 420 iframe height in px (default 420)\n// BOOT auto auto (default) or click\n// FULLSCREEN fixed fixed (default), scale, or resize\n// NAME MyStack stack name for the JS bridge\n// WIDTH full break out of the column: full (page\n// width) or a pixel number (default:\n// column width). The stack reads its\n// real size from window.innerWidth.\n// ZONE <name> placeholder variant: renders a light\n// dashed box only \u2014 no iframe, no\n// engine \u2014 and publishes its rect as\n// data-zone / data-height attributes on\n// the item div (the frame plugin's\n// data-height precedent). A WIDTH full\n// engine item measures every zone in\n// the lineup and feeds them to its\n// stack as marks (name:x:y:w:h in\n// viewport coords) \u2014 the generic DOM\n// protocol any plugin may adopt.\n// TRIPTYCH a | b | c turnkey mode: one engine draws three\n// labelled columns (default Left |\n// Centre | Right), sized to the window.\n// COLUMNS a | b | c the three column labels for TRIPTYCH.\n// TRANSPARENT render the stack with a transparent\n// background (opt-in ?bg=transparent on\n// the shell) so the page behind shows\n// through. The stack must leave its\n// card background empty.\n// BEHIND <url> an HTML page drawn behind the (usually\n// TRANSPARENT) stack, inside the same\n// widget \u2014 the animation composites over\n// ordinary web content. Give a full URL.\n//\n// Design (door two of Three Livecode Doors): a livecode item loads and\n// displays its stack by default. BOOT click opts a widget into a light\n// collapsible poster that boots on demand. Every widget runs independently;\n// a watchdog tears a frame down when its item leaves the lineup (fedwiki\n// has no plugin dispose hook \u2014 the htv pattern), and the stop control\n// collapses a running widget back to its poster.\n\nconst ENGINE_MB = 6.4\n// The DEFAULT engine is v11. Pages that need the old 10.0.2-rc-4 engine\n// name it in their own STACK line \u2014 see v10.demo.localhost, where every\n// item is pinned to that site's own copy. Rolling back is this one line.\nconst SHARED_SHELL = 'https://wasm.livecode.wiki/assets/wasm/v11/stack.html'\n\n// TRIPTYCH mode \u2014 generate the LiveCode scaffold for one engine drawing three\n// positioned, labelled columns. It clears the donor capsule's leftover controls\n// (8 hexagon parts on the boot card), reads its real size from the browser\n// window, and lays the columns out proportionally. Authors get three columns\n// with no hand-written LiveCode; behaviour can be layered on later.\nconst triptychScript = (columns) => {\n const cols = (Array.isArray(columns) && columns.length === 3) ? columns : ['Left', 'Centre', 'Right']\n const lab = (s) => String(s).replace(/\"/g, \"'\").replace(/[\\r\\n]/g, ' ')\n return [\n 'script \"Triptych\"',\n '',\n 'on preOpenStack',\n ' buildTriptych',\n 'end preOpenStack',\n 'on startup',\n ' buildTriptych',\n 'end startup',\n 'on openStack',\n ' buildTriptych',\n 'end openStack',\n '',\n 'local sBuilt',\n '',\n 'command buildTriptych',\n ' if sBuilt is true then exit buildTriptych',\n ' put true into sBuilt',\n ' repeat the number of controls of this card',\n ' delete last control',\n ' end repeat',\n ' local tW, tH, p, zw',\n ' put winWidth() into tW',\n ' put winHeight() into tH',\n ' set the rect of this stack to 0, 0, tW, tH',\n ' set the resizable of this stack to true',\n ' set the backgroundColor of this card to \"248,249,251\"',\n ' put 14 into p',\n ' put trunc((tW - 4 * p) / 3) into zw',\n ` makeColumn \"col1\", p, zw, tH, \"${lab(cols[0])}\", \"225,235,252\"`,\n ` makeColumn \"col2\", p + zw + p, zw, tH, \"${lab(cols[1])}\", \"255,248,232\"`,\n ` makeColumn \"col3\", p + 2 * (zw + p), zw, tH, \"${lab(cols[2])}\", \"228,244,230\"`,\n 'end buildTriptych',\n '',\n 'on resizeStack pW, pH',\n ' if sBuilt is true then',\n ' layoutTriptych pW, pH',\n ' end if',\n 'end resizeStack',\n '',\n 'command layoutTriptych tW, tH',\n ' local p, zw',\n ' put 14 into p',\n ' put trunc((tW - 4 * p) / 3) into zw',\n ' layoutColumn \"col1\", p, zw, tH',\n ' layoutColumn \"col2\", p + zw + p, zw, tH',\n ' layoutColumn \"col3\", p + 2 * (zw + p), zw, tH',\n 'end layoutTriptych',\n '',\n 'command layoutColumn pName, pX, pW, pH',\n ' set the rect of graphic pName to pX, 14, pX + pW, pH - 14',\n ' set the rect of field (pName & \"L\") to pX, 22, pX + pW, 48',\n 'end layoutColumn',\n '',\n 'command makeColumn pName, pX, pW, pH, pLabel, pColor',\n ' create graphic pName',\n ' set the style of graphic pName to \"roundrect\"',\n ' set the rect of graphic pName to pX, 14, pX + pW, pH - 14',\n ' set the opaque of graphic pName to true',\n ' set the backgroundColor of graphic pName to pColor',\n ' set the lineColor of graphic pName to \"205,210,220\"',\n ' create field (pName & \"L\")',\n ' set the rect of field (pName & \"L\") to pX, 22, pX + pW, 48',\n ' set the textAlign of field (pName & \"L\") to \"center\"',\n ' set the textSize of field (pName & \"L\") to 15',\n ' set the borderWidth of field (pName & \"L\") to 0',\n ' set the opaque of field (pName & \"L\") to false',\n ' set the lockText of field (pName & \"L\") to true',\n ' put pLabel into field (pName & \"L\")',\n 'end makeColumn',\n '',\n 'function winWidth',\n ' local w',\n ' do \"window.innerWidth\" as \"javascript\"',\n ' put the result into w',\n ' if w is not a number or w < 200 then put 700 into w',\n ' return w',\n 'end winWidth',\n '',\n 'function winHeight',\n ' local h',\n ' do \"window.innerHeight\" as \"javascript\"',\n ' put the result into h',\n ' if h is not a number or h < 120 then put 340 into h',\n ' return h',\n 'end winHeight'\n ].join('\\n')\n}\n\nexport const parse = (text) => {\n const spec = { engine: null, title: null, height: 420, width: null, triptych: false, columns: null, boot: 'auto', fullscreen: 'fixed', name: null, script: null, transparent: false, behind: null, zone: null }\n let fsExplicit = false\n let heightExplicit = false\n const lines = (text || '').split('\\n')\n for (let i = 0; i < lines.length; i++) {\n // a script-only stack begins `script \"Name\"` \u2014 everything from that\n // line on is the stack's script, booted directly by the shared shell\n const sm = lines[i].match(/^\\s*script\\s+\"([^\"]+)\"/)\n if (sm) {\n spec.script = lines.slice(i).join('\\n')\n if (!spec.name) spec.name = sm[1]\n if (!spec.title) spec.title = sm[1]\n break\n }\n // a bare TRIPTYCH line (no args) turns on turnkey mode with default labels\n if (/^\\s*TRIPTYCH\\s*$/i.test(lines[i])) { spec.triptych = true; continue }\n // a bare TRANSPARENT line renders the stack with a transparent background\n // (opt-in ?bg=transparent on the shell) so anything behind shows through\n if (/^\\s*TRANSPARENT\\s*$/i.test(lines[i])) { spec.transparent = true; continue }\n const m = lines[i].trim().match(/^([A-Z]+):?\\s+(.*)$/)\n if (!m) continue\n const [, cmd, restRaw] = m\n const rest = restRaw.trim()\n // ENGINE is the directive; STACK is the legacy alias for it\n if (cmd === 'ENGINE' || cmd === 'STACK') spec.engine = rest\n else if (cmd === 'TITLE') spec.title = rest\n else if (cmd === 'HEIGHT') {\n const h = parseInt(rest, 10)\n if (h) { spec.height = h; heightExplicit = true }\n }\n else if (cmd === 'ZONE') {\n // the wire format is colon-and-comma delimited, so the name can't be\n const clean = rest.replace(/[:,]/g, '').trim()\n spec.zone = clean || 'zone'\n }\n else if (cmd === 'BOOT') spec.boot = rest.toLowerCase() === 'click' ? 'click' : 'auto'\n else if (cmd === 'FULLSCREEN') {\n const mode = rest.toLowerCase()\n spec.fullscreen = ['fixed', 'scale', 'resize'].includes(mode) ? mode : 'fixed'\n fsExplicit = true\n } else if (cmd === 'NAME') spec.name = rest\n else if (cmd === 'WIDTH') {\n const v = rest.toLowerCase()\n spec.width = (v === 'full' || v === 'page' || v === 'lineup') ? 'full' : (parseInt(rest, 10) || null)\n }\n else if (cmd === 'TRIPTYCH') {\n spec.triptych = true\n if (rest) spec.columns = rest.split('|').map((s) => s.trim()).filter(Boolean)\n }\n else if (cmd === 'COLUMNS') spec.columns = rest.split('|').map((s) => s.trim()).filter(Boolean)\n else if (cmd === 'BEHIND') spec.behind = rest\n }\n // TRIPTYCH mode generates its own script-only stack from the column labels;\n // it lays out on resizeStack, so default the shell to resize mode (the\n // fixed default would swallow the window resizes that drive it)\n if (spec.triptych && !spec.script) {\n spec.script = triptychScript(spec.columns)\n if (!spec.name) spec.name = 'Triptych'\n if (!spec.title) spec.title = 'Triptych'\n if (!fsExplicit) spec.fullscreen = 'resize'\n }\n // ZONE is a placeholder: it beats STACK/script/TRIPTYCH, boots nothing,\n // and defaults to a shallower box than a running widget\n if (spec.zone) {\n spec.engine = null\n spec.script = null\n spec.triptych = false\n if (!heightExplicit) spec.height = 200\n if (!spec.title) spec.title = spec.zone\n return spec\n }\n if (spec.script && !spec.engine) spec.engine = SHARED_SHELL\n if (!spec.title && spec.engine) {\n const leaf = spec.engine.split('/').pop() || ''\n spec.title = (leaf.split('?')[0] || '').replace(/\\.html?$/i, '') || 'Livecode stack'\n }\n return spec\n}\n\nconst escapeHtml = (s) =>\n String(s).replace(/[&<>\"']/g, (c) =>\n ({ '&': '&', '<': '<', '>': '>', '\"': '"', \"'\": ''' })[c])\n\nconst resolveUrl = (div, stack) => {\n if (/^https?:\\/\\//i.test(stack)) return stack\n const site = div.parents('.page').data('site') || window.location.host\n return `//${site}/${stack.replace(/^\\//, '')}`\n}\n\n// ---- lineup geometry ---------------------------------------------------\n// Everything here is viewport coords, and the whole contract rests on the\n// WIDTH full mount being pinned to the viewport (pullToViewport) \u2014 iframe\n// coords equal viewport coords only while that holds.\n\n// zones: one x:width pair per lineup column ('' when not a lineup)\nconst collectZones = () => {\n const pages = [...document.querySelectorAll('.page')]\n if (pages.length < 2) return ''\n return pages.map((p) => {\n const r = p.getBoundingClientRect()\n return Math.round(r.left) + ':' + Math.round(r.width)\n }).join(',')\n}\n\n// marks: one name:x:y:w:h per ZONE item anywhere in the lineup, translated\n// into the ENGINE FRAME's coordinate space (the stack draws in iframe\n// coords, and a cross-origin stack cannot read frameElement to translate\n// for itself). Duplicate names (same page open twice) dedupe by suffix:\n// left, left2, ...\nconst collectMarks = (offsetLeft, offsetTop) => {\n const seen = {}\n return [...document.querySelectorAll('.item[data-zone]')].map((el) => {\n let name = el.dataset.zone || 'zone'\n seen[name] = (seen[name] || 0) + 1\n if (seen[name] > 1) name += seen[name]\n const r = el.getBoundingClientRect()\n return [name, Math.round(r.left - (offsetLeft || 0)),\n Math.round(r.top - (offsetTop || 0)),\n Math.round(r.width), Math.round(r.height)].join(':')\n }).join(',')\n}\n\n// Pin a WIDTH full mount across the viewport. A negative margin is NOT\n// enough: `.page` is overflow:auto, so a 100vw child is CLIPPED to its\n// column and anything drawn beyond the column edge silently disappears \u2014\n// which is what hid every zone window while the DOM insisted they were\n// visible and correctly placed. Fixed positioning escapes ancestor overflow\n// (no transformed ancestors in the fedwiki chain), so the overlay survives.\n// The widget keeps a spacer of the same height so the column still flows.\n// Runs at boot AND on every scroll/resize \u2014 the anchor moves constantly.\nconst pullToViewport = (mount, widget, height) => {\n const bar = widget.querySelector('.livecode-bar')\n const barH = bar ? bar.offsetHeight : 0\n widget.style.minHeight = (height + barH) + 'px'\n const anchor = widget.getBoundingClientRect()\n mount.style.setProperty('position', 'fixed', 'important')\n mount.style.setProperty('left', '0px', 'important')\n mount.style.setProperty('width', '100vw', 'important')\n mount.style.setProperty('max-width', '100vw', 'important')\n mount.style.setProperty('top', Math.round(anchor.top + barH) + 'px', 'important')\n mount.style.marginLeft = '0px'\n return Math.abs(mount.getBoundingClientRect().left) <= 2\n}\n\n// ---- per-widget lifecycle ---------------------------------------------\n\nconst stopWidget = (widget) => {\n const inst = widget.__livecode\n if (!inst) return\n clearInterval(inst.watch)\n window.removeEventListener('message', inst.onMessage)\n document.removeEventListener('fullscreenchange', inst.onFsChange)\n if (inst.onResize) window.removeEventListener('resize', inst.onResize)\n if (inst.onScroll) {\n window.removeEventListener('scroll', inst.onScroll, true)\n if (inst.scroller) inst.scroller.removeEventListener('scroll', inst.onScroll)\n }\n if (inst.observer) inst.observer.disconnect()\n ;(inst.mount || inst.frame).remove()\n inst.bar.remove()\n inst.poster.style.display = ''\n widget.__livecode = null\n}\n\nconst boot = (widget, poster, spec, url) => {\n if (widget.__livecode) return\n\n // arm the shell's fullscreen mode from load \u2014 deterministic, no message race\n url += (url.includes('?') ? '&' : '?') + 'fs=' + spec.fullscreen\n if (spec.name) {\n url += '&stack=' + encodeURIComponent(spec.name)\n }\n if (spec.script) {\n url += '&boot=script'\n }\n if (spec.transparent) {\n url += '&bg=transparent'\n }\n // WIDTH full pulls the iframe to the viewport's left edge, so iframe x-coords\n // equal viewport x-coords. Hand the stack the REAL lineup geometry: zones\n // (one x:width per column) and marks (one name:x:y:w:h per ZONE item).\n if (spec.width === 'full') {\n const zones = collectZones()\n if (zones) url += '&zones=' + encodeURIComponent(zones)\n // marks are NOT sent on the url: they are frame-relative, and the frame\n // has no geometry until it has mounted \u2014 the load listener below sends\n // the first translated set\n }\n\n const bar = document.createElement('div')\n bar.className = 'livecode-bar'\n bar.style.cssText =\n 'display:flex;justify-content:space-between;align-items:center;' +\n 'font-size:12px;color:#666;padding:2px 4px 4px'\n bar.innerHTML =\n `<span>${escapeHtml(spec.title)}</span>` +\n '<span>' +\n `<span class=\"livecode-full\" style=\"cursor:pointer;color:#666;margin-right:12px\" ` +\n `title=\"fullscreen (${escapeHtml(spec.fullscreen)})\">⛶ full</span>` +\n `<span class=\"livecode-stop\" style=\"cursor:pointer;color:#b5511d\">■ stop</span>` +\n '</span>'\n\n const frame = document.createElement('iframe')\n frame.className = 'livecode-frame'\n frame.src = url\n frame.setAttribute('allow', 'fullscreen')\n frame.setAttribute('allowfullscreen', '')\n if (spec.transparent) frame.setAttribute('allowtransparency', 'true')\n frame.style.cssText =\n `width:100%;height:${spec.height}px;border-radius:6px;` +\n (spec.transparent\n ? 'border:0;background:transparent'\n : 'border:1px solid #e0e0e0;background:#fff')\n\n // BEHIND: render an HTML page behind a (usually transparent) stack, both\n // inside one positioned stage, so the livecode animation composites over\n // ordinary web content. Without BEHIND the frame mounts directly as before.\n let mount = frame\n if (spec.behind) {\n const stage = document.createElement('div')\n stage.className = 'livecode-stage'\n stage.style.cssText =\n `position:relative;width:100%;height:${spec.height}px;` +\n 'border-radius:6px;overflow:hidden'\n const back = document.createElement('iframe')\n back.className = 'livecode-behind'\n back.src = spec.behind\n back.setAttribute('scrolling', 'no')\n back.style.cssText =\n 'position:absolute;inset:0;width:100%;height:100%;border:0;z-index:0'\n frame.style.position = 'absolute'\n frame.style.inset = '0'\n frame.style.width = '100%'\n frame.style.height = '100%'\n frame.style.borderRadius = '0'\n frame.style.zIndex = '1'\n stage.appendChild(back)\n stage.appendChild(frame)\n mount = stage\n }\n\n // WIDTH: break the widget out of its fedwiki column so a triptych can span\n // the page. 'full' is the classic full-bleed (100vw pulled to the viewport\n // edge); a number widens to that many px. The stack sizes itself to the\n // resulting window.innerWidth.\n if (spec.width === 'full') {\n // pull the mount to the viewport's LEFT EDGE exactly. The classic\n // calc(50% - 50vw) only works when the parent is viewport-centred \u2014 inside\n // a fedwiki column it is not, so measure and pull by the real offset. The\n // zones/marks params are viewport coords, so iframe x MUST equal viewport\n // x. Double-rAF so the first layout has settled; postcondition + one\n // retry, stamped for observability.\n requestAnimationFrame(() => requestAnimationFrame(() => {\n const ok = pullToViewport(mount, widget, spec.height)\n widget.dataset.fullWidth = ok ? 'ok' : 'retrying'\n if (!ok) setTimeout(() => {\n widget.dataset.fullWidth = pullToViewport(mount, widget, spec.height) ? 'ok' : 'failed'\n }, 250)\n }))\n // the full-bleed frame belongs to ITS page's DOM, and later .page\n // columns otherwise paint over its overflow \u2014 the engine renders fine\n // and the columns quietly bury it. Raising the mount alone is not\n // enough: z-index competes only within the ancestor page's stacking\n // context, so the page itself must rise above its later siblings.\n // (Pair with TRANSPARENT or the frame's own background hides the wiki;\n // clicks over other columns now land on the frame - the overlay price.)\n mount.style.position = 'relative'\n mount.style.zIndex = '30'\n widget.style.overflow = 'visible'\n } else if (typeof spec.width === 'number') {\n mount.style.width = spec.width + 'px'\n mount.style.maxWidth = 'none'\n widget.style.overflow = 'visible'\n }\n\n const tell = (command) => {\n try {\n frame.contentWindow.postMessage({ livecode: { command, mode: spec.fullscreen } }, '*')\n } catch (e) { /* frame gone */ }\n }\n\n const onMessage = (event) => {\n if (!widget.__livecode || event.source !== frame.contentWindow) return\n const d = event.data && event.data.livecode\n if (d && d.ready === 'script' && spec.script) {\n frame.contentWindow.postMessage({ livecode: { bootScript: spec.script } }, '*')\n }\n widget.dataset.lastMessage = JSON.stringify(event.data)\n if (window.$) window.$(widget).trigger('livecodeMessage', [event.data])\n }\n window.addEventListener('message', onMessage)\n\n const onFsChange = () => {\n if (!widget.__livecode) return\n if (document.fullscreenElement === frame) tell('fullscreen')\n else if (!document.fullscreenElement) tell('fullscreenExit')\n }\n document.addEventListener('fullscreenchange', onFsChange)\n\n // parent-side geometry refresh: the WIDTH full margin-pull and the zones\n // and marks strings are all viewport-relative, so scroll, resize and\n // lineup changes all go stale without this. The shell mirrors both into\n // window.__wikiZones / window.__wikiMarks; the stack pulls them fresh.\n let lastZones = null\n let lastMarks = null\n const sendGeometry = () => {\n if (!widget.__livecode) return\n if (spec.width === 'full') pullToViewport(mount, widget, spec.height)\n const zones = collectZones()\n if (zones !== lastZones) {\n lastZones = zones\n try { frame.contentWindow.postMessage({ livecode: { command: 'zones', zones } }, '*') } catch (e) { /* frame gone */ }\n }\n const fr = frame.getBoundingClientRect()\n const marks = collectMarks(fr.left, fr.top)\n if (marks !== lastMarks) {\n lastMarks = marks\n try { frame.contentWindow.postMessage({ livecode: { command: 'marks', marks } }, '*') } catch (e) { /* frame gone */ }\n }\n }\n // first translated marks once the frame exists and has laid out\n frame.addEventListener('load', () => setTimeout(sendGeometry, 400))\n\n let resizeTimer = null\n const onResize = () => {\n if (!widget.__livecode) return\n clearTimeout(resizeTimer)\n resizeTimer = setTimeout(sendGeometry, 150)\n }\n window.addEventListener('resize', onResize)\n\n // scroll must track live (windows are seated at mark rects), so rAF-throttle\n // rather than debounce. Capture-phase on window catches the .main horizontal\n // scroller and any inner vertical scroll in one registration.\n let scrollQueued = false\n let onScroll = null\n let scroller = null\n let observer = null\n if (spec.width === 'full') {\n onScroll = () => {\n if (scrollQueued || !widget.__livecode) return\n scrollQueued = true\n requestAnimationFrame(() => { scrollQueued = false; sendGeometry() })\n }\n window.addEventListener('scroll', onScroll, true)\n scroller = document.querySelector('.main')\n if (scroller) scroller.addEventListener('scroll', onScroll)\n // pages joining or leaving the lineup move every zone\n if (scroller && typeof MutationObserver !== 'undefined') {\n let mutTimer = null\n observer = new MutationObserver(() => {\n clearTimeout(mutTimer)\n mutTimer = setTimeout(sendGeometry, 200)\n })\n observer.observe(scroller, { childList: true })\n }\n }\n\n // watchdog: fedwiki never tells a plugin its item left the lineup\n const watch = setInterval(() => {\n if (!document.body.contains(widget)) stopWidget(widget)\n }, 4000)\n\n poster.style.display = 'none'\n widget.appendChild(bar)\n widget.appendChild(mount)\n bar.querySelector('.livecode-stop').addEventListener('click', () => stopWidget(widget))\n bar.querySelector('.livecode-full').addEventListener('click', () => {\n if (frame.requestFullscreen) frame.requestFullscreen()\n })\n widget.__livecode = { poster, frame, mount, bar, watch, onMessage, onFsChange, onResize, onScroll, scroller, observer }\n}\n\n// ---- fedwiki plugin surface -------------------------------------------\n\nexport const emit = (div, item) => {\n const spec = parse(item.text || '')\n if (spec.zone) {\n // a placeholder, not a widget: no iframe, no engine. The data attributes\n // on the ITEM div are the whole cross-plugin protocol \u2014 anything can\n // measure .item[data-zone] without depending on this plugin.\n div.html(\n `<div class=\"livecode-zone\" style=\"height:${spec.height}px;` +\n 'border:2px dashed #b8c4d8;border-radius:8px;background:#f8fafd;' +\n 'display:flex;align-items:center;justify-content:center;color:#8a97ad;' +\n `font-size:14px\">▢ zone: ${escapeHtml(spec.zone)}</div>`)\n div[0].dataset.zone = spec.zone\n div[0].dataset.height = spec.height\n return\n }\n delete div[0].dataset.zone\n delete div[0].dataset.height\n if (!spec.engine) {\n div.html(\n '<div class=\"livecode-widget\" style=\"border:1px dashed #ccc;border-radius:6px;' +\n 'padding:12px;color:#888;font-size:13px\">livecode — no STACK given. ' +\n 'Double click to edit, e.g.<br><code>STACK https://wasm.livecode.wiki/assets/wasm/shared/stack.html?zip=hexagon.zip</code></div>')\n return\n }\n div.html(\n '<div class=\"livecode-widget\">' +\n '<div class=\"livecode-poster\" style=\"cursor:pointer;border:1px solid #e0d5c5;' +\n 'border-radius:6px;padding:14px 16px;background:linear-gradient(135deg,#fff7ee,#ffffff)\">' +\n `<div style=\"font-weight:bold;font-size:15px\">▶ ${escapeHtml(spec.title)}</div>` +\n `<div style=\"font-size:12px;color:#888;margin-top:4px\">Livecode wasm — ` +\n `${spec.script ? \"runs this item's script with\" : 'loads'} the ${ENGINE_MB} MB engine</div>` +\n '</div></div>')\n}\n\nexport const bind = (div, item) => {\n div.on('dblclick', () => window.wiki.textEditor(div, item))\n const spec = parse(item.text || '')\n if (spec.zone) return\n const widget = div.find('.livecode-widget')[0]\n const poster = div.find('.livecode-poster')[0]\n if (!spec.engine || !widget || !poster) return\n if (spec.behind) spec.behind = resolveUrl(div, spec.behind)\n const url = resolveUrl(div, spec.engine)\n const start = (event) => {\n if (event) event.stopPropagation()\n boot(widget, poster, spec, url)\n }\n poster.addEventListener('click', start)\n if (spec.boot === 'auto') start()\n}\n\nif (typeof window !== 'undefined') {\n window.plugins = window.plugins || {}\n window.plugins['livecode'] = { emit, bind }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["SHARED_SHELL", "triptychScript", "columns", "cols", "lab", "parse", "text", "spec", "fsExplicit", "heightExplicit", "lines", "sm", "m", "cmd", "restRaw", "rest", "h", "clean", "mode", "v", "s", "leaf", "escapeHtml", "c", "resolveUrl", "div", "stack", "collectZones", "pages", "p", "r", "collectMarks", "offsetLeft", "offsetTop", "seen", "el", "name", "pullToViewport", "mount", "widget", "height", "bar", "barH", "anchor", "stopWidget", "inst", "boot", "poster", "url", "zones", "frame", "stage", "back", "ok", "tell", "command", "onMessage", "event", "d", "onFsChange", "lastZones", "lastMarks", "sendGeometry", "fr", "marks", "resizeTimer", "onResize", "scrollQueued", "onScroll", "scroller", "observer", "mutTimer", "watch", "emit", "item", "bind", "start"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wiki-plugin-livecode",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Run a Livecode wasm stack as a lazy wiki widget — poster card, click to boot, one live widget at a time, clean teardown.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "client/livecode.js",
|