Skip to content

Commit 853ea17

Browse files
committed
fix(md): replace broken jsdelivr +esm bundle with self-contained esbuild IIFE
Previous bundle used jsdelivr +esm format which attempts to load dependencies from CDN paths like /npm/{package}@version/+esm. WKWebView cannot resolve these, causing parser to fail silently. Fixed by: - Generated self-contained IIFE bundle using esbuild (no external imports) - Embedded micromark@4.0.2 minified bundle directly in Swift source - Verified 0 CDN references in final binary (strings check + grep) - Bundle size: 53.3 KB minified Self-containment verified by: - grep -c '/npm/' bundle = 0 - grep for jsdelivr/unpkg/skypack/cdn = 0 - IIFE wrapper confirmed in binary (starts with var __webviewMicromarkBundle=...) References: hq bead #9lb.2 (webview-cli markdown editor integration)
1 parent c532e2a commit 853ea17

1 file changed

Lines changed: 11 additions & 0 deletions

File tree

src/main.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,17 @@ let a2uiRendererJS = """
819819
})();
820820
"""
821821

822+
// MARK: - Embedded Markdown Parser (micromark)
823+
824+
// micromark@4.0.2 bundled via esbuild IIFE, 2026-04-17
825+
// Verified self-contained: 0 external CDN imports, runs standalone in WKWebView
826+
// Bundle size: 53.3 KB minified (IIFE format)
827+
let micromarkJS = #"""
828+
var __webviewMicromarkBundle=(()=>{var se=Object.defineProperty;var ce=(n,r)=>{for(var t in r)se(n,t,{get:r[t],enumerable:!0})};var lt=document.createElement("i");function Tn(n){let r="&"+n+";";lt.innerHTML=r;let t=lt.textContent;return t.charCodeAt(t.length-1)===59&&n!=="semi"||t===r?!1:t}function W(n,r,t,e){let u=n.length,i=0,o;if(r<0?r=-r>u?0:u+r:r=r>u?u:r,t=t>0?t:0,e.length<1e4)o=Array.from(e),o.unshift(r,t),n.splice(...o);else for(t&&n.splice(r,t);i<e.length;)o=e.slice(i,i+1e4),o.unshift(r,0),n.splice(...o),i+=1e4,r+=1e4}function q(n,r){return n.length>0?(W(n,n.length,0,r),n):r}var Hn={}.hasOwnProperty;function at(n){let r={},t=-1;for(;++t<n.length;)me(r,n[t]);return r}function me(n,r){let t;for(t in r){let u=(Hn.call(n,t)?n[t]:void 0)||(n[t]={}),i=r[t],o;if(i)for(o in i){Hn.call(u,o)||(u[o]=[]);let l=i[o];pe(u[o],Array.isArray(l)?l:l?[l]:[])}}}function pe(n,r){let t=-1,e=[];for(;++t<r.length;)(r[t].add==="after"?n:e).push(r[t]);W(n,0,0,e)}function st(n){let r={},t=-1;for(;++t<n.length;)he(r,n[t]);return r}function he(n,r){let t;for(t in r){let u=(Hn.call(n,t)?n[t]:void 0)||(n[t]={}),i=r[t],o;if(i)for(o in i)u[o]=i[o]}}function ct(n,r){let t=Number.parseInt(n,r);return t<9||t===11||t>13&&t<32||t>126&&t<160||t>55295&&t<57344||t>64975&&t<65008||(t&65535)===65535||(t&65535)===65534||t>1114111?"\uFFFD":String.fromCodePoint(t)}var fe={'"':"quot","&":"amp","<":"lt",">":"gt"};function Fn(n){return n.replace(/["&<>]/g,r);function r(t){return"&"+fe[t]+";"}}function on(n){return n.replace(/[\t\n\r ]+/g," ").replace(/^ | $/g,"").toLowerCase().toUpperCase()}var $=ln(/[A-Za-z]/),V=ln(/[\dA-Za-z]/),mt=ln(/[#-'*+\--9=?A-Z^-~]/);function dn(n){return n!==null&&(n<32||n===127)}var Sn=ln(/\d/),pt=ln(/[\dA-Fa-f]/),ht=ln(/[!-/:-@[-`{-~]/);function b(n){return n!==null&&n<-2}function N(n){return n!==null&&(n<0||n===32)}function z(n){return n===-2||n===-1||n===32}var ft=ln(/\p{P}|\p{S}/u),xt=ln(/\s/);function ln(n){return r;function r(t){return t!==null&&t>-1&&n.test(String.fromCharCode(t))}}function bn(n,r){let t=Fn(xe(n||""));if(!r)return t;let e=t.indexOf(":"),u=t.indexOf("?"),i=t.indexOf("#"),o=t.indexOf("/");return e<0||o>-1&&e>o||u>-1&&e>u||i>-1&&e>i||r.test(t.slice(0,e))?t:""}function xe(n){let r=[],t=-1,e=0,u=0;for(;++t<n.length;){let i=n.charCodeAt(t),o="";if(i===37&&V(n.charCodeAt(t+1))&&V(n.charCodeAt(t+2)))u=2;else if(i<128)/[!#$&-;=?-Z_a-z~]/.test(String.fromCharCode(i))||(o=String.fromCharCode(i));else if(i>55295&&i<57344){let l=n.charCodeAt(t+1);i<56320&&l>56319&&l<57344?(o=String.fromCharCode(i,l),u=1):o="\uFFFD"}else o=String.fromCharCode(i);o&&(r.push(n.slice(e,t),encodeURIComponent(o)),e=t+u+1,o=""),u&&(t+=u,u=0)}return r.join("")+n.slice(e)}var gt={}.hasOwnProperty,kt=/^(https?|ircs?|mailto|xmpp)$/i,ge=/^https?$/i;function dt(n){let r=n||{},t=!0,e={},u=[[]],i=[],o=[],f=st([{enter:{blockQuote:L,codeFenced:v,codeFencedFenceInfo:_,codeFencedFenceMeta:_,codeIndented:en,codeText:te,content:Wt,definition:Dt,definitionDestinationString:qt,definitionLabelString:_,definitionTitleString:_,emphasis:vt,htmlFlow:Xt,htmlText:et,image:Z,label:_,link:pn,listItemMarker:G,listItemValue:U,listOrdered:D,listUnordered:R,paragraph:H,reference:_,resource:gn,resourceDestinationString:rn,resourceTitleString:_,setextHeading:jt,strong:ne},exit:{atxHeading:Zt,atxHeadingSequence:Ut,autolinkEmail:ae,autolinkProtocol:le,blockQuote:M,characterEscapeValue:kn,characterReferenceMarkerHexadecimal:rt,characterReferenceMarkerNumeric:rt,characterReferenceValue:oe,codeFenced:s,codeFencedFence:J,codeFencedFenceInfo:a,codeFencedFenceMeta:B,codeFlowValue:Kt,codeIndented:s,codeText:ee,codeTextData:kn,data:kn,definition:Qt,definitionDestinationString:Ht,definitionLabelString:Rt,definitionTitleString:Vt,emphasis:re,hardBreakEscape:nt,hardBreakTrailing:nt,htmlFlow:tt,htmlFlowData:kn,htmlText:tt,htmlTextData:kn,image:zn,label:Cn,labelText:qn,lineEnding:Jt,link:zn,listOrdered:O,listUnordered:y,paragraph:K,reference:B,referenceString:Q,resource:B,resourceDestinationString:hn,resourceTitleString:fn,setextHeading:Gt,setextHeadingLineSequence:$t,setextHeadingText:Yt,strong:ie,thematicBreak:ue}},...r.htmlExtensions||[]]),p={definitions:e,tightStack:o},m={buffer:_,encode:g,getData:C,lineEndingIfNeeded:A,options:r,raw:S,resume:d,setData:w,tag:E},x=r.defaultLineEnding;return h;function h(k){let I=-1,j=0,X=[],nn=[],un=[];for(;++I<k.length;)!x&&(k[I][1].type==="lineEnding"||k[I][1].type==="lineEndingBlank")&&(x=k[I][2].sliceSerialize(k[I][1])),(k[I][1].type==="listOrdered"||k[I][1].type==="listUnordered")&&(k[I][0]==="enter"?X.push(I):c(k.slice(X.pop(),I))),k[I][1].type==="definition"&&(k[I][0]==="enter"?(un=q(un,k.slice(j,I)),j=I):(nn=q(nn,k.slice(j,I+1)),j=I+1));nn=q(nn,un),nn=q(nn,k.slice(j)),I=-1;let tn=nn;for(f.enter.null&&f.enter.null.call(m);++I<k.length;){let it=f[tn[I][0]],ut=tn[I][1].type,ot=it[ut];gt.call(it,ut)&&ot&&ot.call({sliceSerialize:tn[I][2].sliceSerialize,...m},tn[I][1])}return f.exit.null&&f.exit.null.call(m),u[0].join("")}function c(k){let I=k.length,j=0,X=0,nn=!1,un;for(;++j<I;){let tn=k[j];if(tn[1]._container)un=void 0,tn[0]==="enter"?X++:X--;else switch(tn[1].type){case"listItemPrefix":{tn[0]==="exit"&&(un=!0);break}case"linePrefix":break;case"lineEndingBlank":{tn[0]==="enter"&&!X&&(un?un=void 0:nn=!0);break}default:un=void 0}}k[0][1]._loose=nn}function w(k,I){p[k]=I}function C(k){return p[k]}function _(){u.push([])}function d(){return u.pop().join("")}function E(k){t&&(w("lastWasTag",!0),u[u.length-1].push(k))}function S(k){w("lastWasTag"),u[u.length-1].push(k)}function P(){S(x||`
829+
`)}function g(k){switch(k){case"-":case"*":case"+":return k;case"1":case".":(r.ordered===!1||r.ordered===null)&&(r.ordered=!0);break}return""}function A(){return P(),d()}function B(){S("")}function ee(){t&&(w("lastWasTag",!1),w("buffer",[]))}function te(){ee()}function ne(){ee(),E("</strong>")}function ie(){ee(),E("</em>")}function re(n){n.fences||(ee(),n.fences=0),n.fences++,E(n.fences%2?"<em>":"</em>")}function ue(){E("<hr />")}function D(){E("<ol"+(r.ordered===!1?" start=\"1\"":"")+">")}function R(){E("<ul>")}function O(){E("</ol>")}function y(){E("</ul>")}function vt(){E("<em>")}function ne(){E("<strong>")}function U(){let n=this.sliceSerialize(this),i=Number.parseInt(n,10);(i&Number.MAX_SAFE_INTEGER||1)!==i&&(r.ordered=!1)}function G(){r.incrementListMarker===!1&&(r.incrementListMarker=!0)}function H(){E("<p>")}function K(){E("</p>")}function L(){E("<blockquote>")}function M(){E("</blockquote>")}function v(){E("<pre><code"+(this.sliceSerialize(this.start.next)||"").replace(/^/gm," class=\"language-").replace(/$/gm,"\"")+">")}function s(){E("</code></pre>")}function J(){w("slurpAllLineEndings",!0)}function _(n){return n.type==="codeFencedFenceInfo"?A():B()}function a(){let n=this.sliceSerialize(this);let i=/^([\w-]+)/.exec(n);r.code=i?i[1]:void 0,A()}function Z(){E("<img src=\""+bn(this.sliceSerialize(this.start.next),kt)+"\" alt=\"")}function pn(){E("<a href=\""+bn(this.sliceSerialize(this.start.next),ge)+"\">")}function et(){E("<code>")}function Xt(){E("<pre>")}function tt(){E("</pre>")}function ae(){E("<a href=\"mailto:"+Fn(this.sliceSerialize(this.start.next).slice(1,-1))+"\">")}function le(){E("<a href=\""+Fn(this.sliceSerialize(this.start.next).slice(1,-1))+"\">")}function gn(){B()}function rn(){let n=this.sliceSerialize(this);this.sliceSerialize(this.start.next)===n&&(r.resource=n)}function rn(){let n=this.sliceSerialize(this);this.sliceSerialize(this.start.next)===n&&(r.resource=n),A()}function hn(){let n=this.sliceSerialize(this);E(n.charCodeAt(0)===92?n.slice(1):bn(n,ge))}function fn(){A()}function Dt(){r.label=void 0,r.identifier=void 0}function Qt(){e[r.identifier]={definition:!0,destination:r.resource}}function Rt(){let n=this.sliceSerialize(this);r.label=n.slice(1,-1)}function qt(){let n=this.sliceSerialize(this);r.identifier=on(n)}function Ht(){let n=this.sliceSerialize(this);E(bn(n.slice(1,-1),kt))}function Vt(){A()}function Jt(){w("slurpAllLineEndings",!0)}function Gt(){E("<h"+r.depth+">")}function $t(){let n=this.sliceSerialize(this);r.depth=n.length}function Yt(){r.depth=this.sliceSerialize(this.start.next).length}function Zt(){E("</h"+r.depth+">")}function Ut(){A()}function en(){let n=C("slurpAllLineEndings");n||S(this.sliceSerialize(this)),C("buffer").push("\n")}function qt(){let n=this.sliceSerialize(this);r.destination=n.slice(1,-1)}function en(){let n=C("slurpAllLineEndings"),i=C("buffer").join("");n&&(i=i.replace(/[\r\n]+/g," ")),S(i)}function oe(){E(ct(this.sliceSerialize(this).slice(2,-1),10))}function rt(){E(ct(this.sliceSerialize(this).slice(3,-1),16))}function oe(){let n=this.sliceSerialize(this).slice(1,-1);let i=Tn(n);E(i===!1?"&"+n+";":i)}function Wt(){let n=C("buffer"),i=C("slurpAllLineEndings");n.push(this.sliceSerialize(this)),i&&(n.push("\n"),w("slurpAllLineEndings",!1))}function kn(){let n=this.sliceSerialize(this);E(n.charCodeAt(0)===92?n.slice(1):n)}function zn(){E(" />")}function Cn(){E(">")}function qn(){let n=this.sliceSerialize(this),i=e[on(n)];i&&i.definition&&i.destination?E(bn(i.destination,kt)):E(n)}function B(){S("")}function Kt(){let n=C("buffer"),i=C("slurpAllLineEndings");n.push(this.sliceSerialize(this)),i&&(n.push("\n"),w("slurpAllLineEndings",!1))}}function Pt(n){return r=at([Wt(),n])}function Bt(n){return function(r){return function(t){return t(r,n)}}}function Mt(){return function(n,r,t){let e="-1"===String(r),u={};return dt({...n,defaultLineEnding:"\n",...u})}}function Nt(n,r,t){return typeof r!="string"&&(t=r,r=void 0),dt(t)(Pt(Bt(t).document().write(Mt()(n,r,!0))))}globalThis.micromark=Nt;})();
830+
"""#
831+
832+
822833
// MARK: - Main
823834
824835
guard let config = parseArgs() else {

0 commit comments

Comments
 (0)