hyper-html-api 0.8.1 → 0.9.0
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/README.md +28 -0
- package/conformance/MANIFEST.json +2 -2
- package/conformance/cases/no-data-list-skipped.expected.json +6 -0
- package/conformance/cases/no-data-list-skipped.html +1 -0
- package/conformance/cases/no-data-list-skipped.meta +4 -0
- package/conformance/cases/no-data-list-skipped.parsed.json +3 -0
- package/conformance/cases/no-data-list-skipped.rules +1 -0
- package/conformance/cases/no-data-text-projected.expected.json +3 -0
- package/conformance/cases/no-data-text-projected.html +1 -0
- package/conformance/cases/no-data-text-projected.meta +4 -0
- package/conformance/cases/no-data-text-projected.parsed.json +3 -0
- package/conformance/cases/no-data-text-projected.rules +1 -0
- package/conformance/cases/props-type-is-attribute.expected.json +5 -0
- package/conformance/cases/props-type-is-attribute.meta +4 -0
- package/conformance/cases/write-attr-app-scheme.after.html +1 -0
- package/conformance/cases/write-attr-app-scheme.after.json +3 -0
- package/conformance/cases/write-attr-app-scheme.data.json +1 -0
- package/conformance/cases/write-attr-app-scheme.html +1 -0
- package/conformance/cases/write-attr-app-scheme.meta +4 -0
- package/conformance/cases/write-attr-app-scheme.write.json +4 -0
- package/conformance/cases/write-attr-href.after.html +1 -0
- package/conformance/cases/write-attr-href.after.json +3 -0
- package/conformance/cases/write-attr-href.data.json +1 -0
- package/conformance/cases/write-attr-href.html +1 -0
- package/conformance/cases/write-attr-href.meta +4 -0
- package/conformance/cases/write-attr-href.write.json +4 -0
- package/conformance/cases/write-checked-false.after.html +1 -0
- package/conformance/cases/write-checked-false.after.json +3 -0
- package/conformance/cases/write-checked-false.data.json +1 -0
- package/conformance/cases/write-checked-false.html +1 -0
- package/conformance/cases/write-checked-false.meta +4 -0
- package/conformance/cases/write-checked-false.write.json +4 -0
- package/conformance/cases/write-checked-true.after.html +1 -0
- package/conformance/cases/write-checked-true.after.json +3 -0
- package/conformance/cases/write-checked-true.data.json +1 -0
- package/conformance/cases/write-checked-true.html +1 -0
- package/conformance/cases/write-checked-true.meta +4 -0
- package/conformance/cases/write-checked-true.write.json +4 -0
- package/conformance/cases/write-crlf-multi.after.html +12 -0
- package/conformance/cases/write-crlf-multi.after.json +8 -0
- package/conformance/cases/write-crlf-multi.data.json +1 -0
- package/conformance/cases/write-crlf-multi.html +12 -0
- package/conformance/cases/write-crlf-multi.meta +4 -0
- package/conformance/cases/write-crlf-multi.write.json +4 -0
- package/conformance/cases/write-fallback-implied.after.html +1 -0
- package/conformance/cases/write-fallback-implied.after.json +3 -0
- package/conformance/cases/write-fallback-implied.data.json +1 -0
- package/conformance/cases/write-fallback-implied.html +1 -0
- package/conformance/cases/write-fallback-implied.meta +4 -0
- package/conformance/cases/write-fallback-implied.write.json +4 -0
- package/conformance/cases/write-flatten.after.html +1 -0
- package/conformance/cases/write-flatten.after.json +3 -0
- package/conformance/cases/write-flatten.data.json +1 -0
- package/conformance/cases/write-flatten.html +1 -0
- package/conformance/cases/write-flatten.meta +4 -0
- package/conformance/cases/write-flatten.write.json +4 -0
- package/conformance/cases/write-list-empty-no-seed.data.json +1 -0
- package/conformance/cases/write-list-empty-no-seed.error.json +8 -0
- package/conformance/cases/write-list-empty-no-seed.html +1 -0
- package/conformance/cases/write-list-empty-no-seed.meta +4 -0
- package/conformance/cases/write-list-grow-from-template.after.html +1 -0
- package/conformance/cases/write-list-grow-from-template.after.json +5 -0
- package/conformance/cases/write-list-grow-from-template.data.json +1 -0
- package/conformance/cases/write-list-grow-from-template.html +1 -0
- package/conformance/cases/write-list-grow-from-template.meta +4 -0
- package/conformance/cases/write-list-grow-from-template.write.json +4 -0
- package/conformance/cases/write-list-object-clone.after.html +1 -0
- package/conformance/cases/write-list-object-clone.after.json +12 -0
- package/conformance/cases/write-list-object-clone.data.json +1 -0
- package/conformance/cases/write-list-object-clone.html +1 -0
- package/conformance/cases/write-list-object-clone.meta +4 -0
- package/conformance/cases/write-list-object-clone.write.json +4 -0
- package/conformance/cases/write-list-scalar-grow.after.html +4 -0
- package/conformance/cases/write-list-scalar-grow.after.json +7 -0
- package/conformance/cases/write-list-scalar-grow.data.json +1 -0
- package/conformance/cases/write-list-scalar-grow.html +4 -0
- package/conformance/cases/write-list-scalar-grow.meta +4 -0
- package/conformance/cases/write-list-scalar-grow.write.json +4 -0
- package/conformance/cases/write-list-scalar-shrink.after.html +4 -0
- package/conformance/cases/write-list-scalar-shrink.after.json +5 -0
- package/conformance/cases/write-list-scalar-shrink.data.json +1 -0
- package/conformance/cases/write-list-scalar-shrink.html +4 -0
- package/conformance/cases/write-list-scalar-shrink.meta +4 -0
- package/conformance/cases/write-list-scalar-shrink.write.json +4 -0
- package/conformance/cases/write-list-shrink-zero.after.html +1 -0
- package/conformance/cases/write-list-shrink-zero.after.json +3 -0
- package/conformance/cases/write-list-shrink-zero.data.json +1 -0
- package/conformance/cases/write-list-shrink-zero.html +1 -0
- package/conformance/cases/write-list-shrink-zero.meta +4 -0
- package/conformance/cases/write-list-shrink-zero.write.json +4 -0
- package/conformance/cases/write-no-data-kept.after.html +1 -0
- package/conformance/cases/write-no-data-kept.after.json +3 -0
- package/conformance/cases/write-no-data-kept.data.json +1 -0
- package/conformance/cases/write-no-data-kept.html +1 -0
- package/conformance/cases/write-no-data-kept.meta +4 -0
- package/conformance/cases/write-no-data-kept.write.json +4 -0
- package/conformance/cases/write-no-rules-tag.data.json +1 -0
- package/conformance/cases/write-no-rules-tag.error.json +6 -0
- package/conformance/cases/write-no-rules-tag.html +1 -0
- package/conformance/cases/write-no-rules-tag.meta +4 -0
- package/conformance/cases/write-noop.after.html +3 -0
- package/conformance/cases/write-noop.after.json +3 -0
- package/conformance/cases/write-noop.data.json +1 -0
- package/conformance/cases/write-noop.html +3 -0
- package/conformance/cases/write-noop.meta +4 -0
- package/conformance/cases/write-noop.write.json +4 -0
- package/conformance/cases/write-outerhtml-unchanged.after.html +1 -0
- package/conformance/cases/write-outerhtml-unchanged.after.json +3 -0
- package/conformance/cases/write-outerhtml-unchanged.data.json +1 -0
- package/conformance/cases/write-outerhtml-unchanged.html +1 -0
- package/conformance/cases/write-outerhtml-unchanged.meta +4 -0
- package/conformance/cases/write-outerhtml-unchanged.write.json +4 -0
- package/conformance/cases/write-readonly-changed.data.json +1 -0
- package/conformance/cases/write-readonly-changed.error.json +6 -0
- package/conformance/cases/write-readonly-changed.html +1 -0
- package/conformance/cases/write-readonly-changed.meta +4 -0
- package/conformance/cases/write-readonly-unchanged.after.html +1 -0
- package/conformance/cases/write-readonly-unchanged.after.json +4 -0
- package/conformance/cases/write-readonly-unchanged.data.json +1 -0
- package/conformance/cases/write-readonly-unchanged.html +1 -0
- package/conformance/cases/write-readonly-unchanged.meta +4 -0
- package/conformance/cases/write-readonly-unchanged.write.json +4 -0
- package/conformance/cases/write-refused-animate.data.json +1 -0
- package/conformance/cases/write-refused-animate.error.json +11 -0
- package/conformance/cases/write-refused-animate.html +1 -0
- package/conformance/cases/write-refused-animate.meta +4 -0
- package/conformance/cases/write-refused-attr-name.data.json +1 -0
- package/conformance/cases/write-refused-attr-name.error.json +11 -0
- package/conformance/cases/write-refused-attr-name.html +1 -0
- package/conformance/cases/write-refused-attr-name.meta +4 -0
- package/conformance/cases/write-refused-data-url.data.json +1 -0
- package/conformance/cases/write-refused-data-url.error.json +11 -0
- package/conformance/cases/write-refused-data-url.html +1 -0
- package/conformance/cases/write-refused-data-url.meta +4 -0
- package/conformance/cases/write-refused-innerhtml.data.json +1 -0
- package/conformance/cases/write-refused-innerhtml.error.json +11 -0
- package/conformance/cases/write-refused-innerhtml.html +1 -0
- package/conformance/cases/write-refused-innerhtml.meta +4 -0
- package/conformance/cases/write-refused-javascript-url.data.json +1 -0
- package/conformance/cases/write-refused-javascript-url.error.json +11 -0
- package/conformance/cases/write-refused-javascript-url.html +1 -0
- package/conformance/cases/write-refused-javascript-url.meta +4 -0
- package/conformance/cases/write-refused-list-removes-rules-tag.data.json +1 -0
- package/conformance/cases/write-refused-list-removes-rules-tag.error.json +11 -0
- package/conformance/cases/write-refused-list-removes-rules-tag.html +1 -0
- package/conformance/cases/write-refused-list-removes-rules-tag.meta +4 -0
- package/conformance/cases/write-refused-multiple.data.json +1 -0
- package/conformance/cases/write-refused-multiple.error.json +15 -0
- package/conformance/cases/write-refused-multiple.html +1 -0
- package/conformance/cases/write-refused-multiple.meta +4 -0
- package/conformance/cases/write-refused-onclick.data.json +1 -0
- package/conformance/cases/write-refused-onclick.error.json +11 -0
- package/conformance/cases/write-refused-onclick.html +1 -0
- package/conformance/cases/write-refused-onclick.meta +4 -0
- package/conformance/cases/write-refused-rules-tag-ancestor.data.json +1 -0
- package/conformance/cases/write-refused-rules-tag-ancestor.error.json +11 -0
- package/conformance/cases/write-refused-rules-tag-ancestor.html +1 -0
- package/conformance/cases/write-refused-rules-tag-ancestor.meta +4 -0
- package/conformance/cases/write-refused-script.data.json +1 -0
- package/conformance/cases/write-refused-script.error.json +11 -0
- package/conformance/cases/write-refused-script.html +1 -0
- package/conformance/cases/write-refused-script.meta +4 -0
- package/conformance/cases/write-shape-mismatch.data.json +1 -0
- package/conformance/cases/write-shape-mismatch.error.json +12 -0
- package/conformance/cases/write-shape-mismatch.html +1 -0
- package/conformance/cases/write-shape-mismatch.meta +4 -0
- package/conformance/cases/write-text-basic.after.html +3 -0
- package/conformance/cases/write-text-basic.after.json +3 -0
- package/conformance/cases/write-text-basic.data.json +1 -0
- package/conformance/cases/write-text-basic.html +3 -0
- package/conformance/cases/write-text-basic.meta +4 -0
- package/conformance/cases/write-text-basic.write.json +4 -0
- package/conformance/cases/write-text-escape.after.html +1 -0
- package/conformance/cases/write-text-escape.after.json +3 -0
- package/conformance/cases/write-text-escape.data.json +1 -0
- package/conformance/cases/write-text-escape.html +1 -0
- package/conformance/cases/write-text-escape.meta +4 -0
- package/conformance/cases/write-text-escape.write.json +4 -0
- package/conformance/cases/write-text-null-clears.after.html +1 -0
- package/conformance/cases/write-text-null-clears.after.json +3 -0
- package/conformance/cases/write-text-null-clears.data.json +1 -0
- package/conformance/cases/write-text-null-clears.html +1 -0
- package/conformance/cases/write-text-null-clears.meta +4 -0
- package/conformance/cases/write-text-null-clears.write.json +4 -0
- package/conformance/cases/write-type-attribute.after.html +1 -0
- package/conformance/cases/write-type-attribute.after.json +3 -0
- package/conformance/cases/write-type-attribute.data.json +1 -0
- package/conformance/cases/write-type-attribute.html +1 -0
- package/conformance/cases/write-type-attribute.meta +4 -0
- package/conformance/cases/write-type-attribute.write.json +4 -0
- package/conformance/cases/write-unknown-key.data.json +1 -0
- package/conformance/cases/write-unknown-key.error.json +11 -0
- package/conformance/cases/write-unknown-key.html +3 -0
- package/conformance/cases/write-unknown-key.meta +4 -0
- package/conformance/cases/write-unmatched.data.json +1 -0
- package/conformance/cases/write-unmatched.error.json +14 -0
- package/conformance/cases/write-unmatched.html +1 -0
- package/conformance/cases/write-unmatched.meta +4 -0
- package/conformance/write-policy.json +78 -0
- package/dist/hyper-html-api.engine.min.js +1 -1
- package/dist/hyper-html-api.min.js +5 -4
- package/dist/hyper-html-api.upgrade.min.js +2 -2
- package/package.json +4 -3
- package/packed-contract.json +1 -1
- package/src/adapters/cheerio.js +105 -10
- package/src/engine/apply.js +2 -0
- package/src/engine/errors.js +25 -0
- package/src/engine/index.js +3 -0
- package/src/engine/splice.js +118 -0
- package/src/engine/write-plan.js +52 -0
- package/src/engine/write-policy.js +136 -0
- package/src/write.js +29 -0
- package/conformance/cases/props-type-is-node-type.expected.json +0 -5
- package/conformance/cases/props-type-is-node-type.meta +0 -11
- /package/conformance/cases/{props-type-is-node-type.html → props-type-is-attribute.html} +0 -0
- /package/conformance/cases/{props-type-is-node-type.parsed.json → props-type-is-attribute.parsed.json} +0 -0
- /package/conformance/cases/{props-type-is-node-type.rules → props-type-is-attribute.rules} +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var hyperHtmlApiUpgrade=(()=>{var te=Object.defineProperty;var Ke=Object.getOwnPropertyDescriptor;var Ve=Object.getOwnPropertyNames;var Je=Object.prototype.hasOwnProperty;var Ee=(e,t)=>{for(var n in t)te(e,n,{get:t[n],enumerable:!0})},Ye=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of Ve(t))!Je.call(e,r)&&r!==n&&te(e,r,{get:()=>t[r],enumerable:!(o=Ke(t,r))||o.enumerable});return e};var Ge=e=>Ye(te({},"__esModule",{value:!0}),e);var St={};Ee(St,{default:()=>bt,engine:()=>pe,upgrade:()=>ze});var J=["textContent","innerText","innerHTML","outerHTML","value","checked","selected","disabled","readOnly","type","tagName","nodeName","nodeType","nodeValue","childElementCount","id","className","classList","baseURI","offsetWidth","offsetHeight","clientWidth","clientHeight","scrollWidth","scrollHeight","dataset","currentSrc","duration","paused","title","documentURI","contentType"],ne=new Set(J),we=new Set(["textContent","innerText","innerHTML","value","checked","selected","disabled","readOnly","type","id","className","title"]),re=new Set(["tagName","nodeName","nodeType","nodeValue","childElementCount","classList","baseURI","documentURI","contentType","offsetWidth","offsetHeight","clientWidth","clientHeight","scrollWidth","scrollHeight","currentSrc","duration","paused","dataset"]);var Y={};Ee(Y,{EmptyListInsert:()=>U,MAX_RULE_DEPTH:()=>_,MaxRuleDepthExceeded:()=>I,RuleTargetReadOnly:()=>H,RulesParseError:()=>k,ShapeMismatch:()=>v,UnknownRulesVersion:()=>j});var k=class extends Error{constructor(t,n){super(t),this.name="RulesParseError",this.cause=n}},j=class extends Error{constructor(t){super(`unknown rules version: ${t}. Library supports "1".`),this.name="UnknownRulesVersion",this.version=t}},_=20,I=class extends Error{constructor(t){super(`rule depth exceeded ${_} at path: ${t.join(".")}`),this.name="MaxRuleDepthExceeded",this.path=t}},v=class extends Error{constructor(t){super(`shape mismatch: ${t.length} field(s) failed validation`),this.name="ShapeMismatch",this.mismatches=t}},U=class extends Error{constructor(t){super(`cannot add items to empty list at "${t.join(".")}" \u2014 no sibling to clone as template. Seed the list with a hidden item first.`),this.name="EmptyListInsert",this.path=t}},H=class extends Error{constructor(t){super(`cannot write to read-only DOM property "${t}"`),this.name="RuleTargetReadOnly",this.target=t}};function N(e){let t=0,n=null,o=-1;for(let r=0;r<e.length;r++){let i=e[r];i==="\\"?r++:n?i===n&&(n=null):i==='"'||i==="'"?n=i:i==="["||i==="("?t++:i==="]"||i===")"?t>0&&t--:i==="@"&&t===0&&(o=r)}return o}function oe(e){let t=N(e);return t===-1?{selector:e,prop:null}:{selector:e.slice(0,t),prop:e.slice(t+1)||null}}function M(e,t,n,o={}){if(Object.prototype.hasOwnProperty.call(o,"exclude")&&e.semanticExclude===!1)throw new Error("This adapter does not support semantic exclude queries; omit exclude or use the DOM adapter.");return ie(e,t,n,{depth:0,path:[]},o)}function ie(e,t,n,o,r){if(o.depth>_)throw new I(o.path);if(typeof n=="string")return Xe(e,t,n,o,r);if(Array.isArray(n)){let[i,c]=n,s=e.find(t,i,r);return xe(r,o,s),s.map((l,a)=>ie(e,l,c,{depth:o.depth+1,path:[...o.path,a]},r))}if(typeof n=="object"&&n!==null){let i={};for(let[c,s]of Object.entries(n))i[c]=ie(e,t,s,{depth:o.depth+1,path:[...o.path,c]},r);return i}return null}function Xe(e,t,n,o,r){if(n.endsWith("[]")){let s=n.slice(0,-2),l=e.find(t,s,r);return xe(r,o,l),l.map(a=>e.text(a))}if(n.startsWith("@"))return Te(e,t,n.slice(1));let i=N(n);if(i!==-1){let s=n.slice(0,i),l=n.slice(i+1),a=s?e.find(t,s,r):[t];return a.length===0?null:Te(e,a[0],l)}if(n===".")return e.text(t);let c=e.find(t,n,r);return c.length===0?null:e.text(c[0])}function xe(e,t,n){if(typeof e.onRowsRead=="function")try{e.onRowsRead(t.path.slice(),n)}catch(o){console.warn(`[hyper-html-api] onRowsRead threw at "${t.path.join(".")||"(root)"}"`,o)}}function Te(e,t,n){if(ne.has(n)){let r=e.prop(t,n);return r==null?null:String(r)}let o=e.attr(t,n);return o||null}function be(e,t,n,o){let r=e.length,i=t.length,c=new Array(r).fill(-1);if(o){let u=new Set;for(let p=0;p<r;p++){let g=o[p];!(g>=0&&g<i)||u.has(g)||(c[p]=g,u.add(g))}}if(r===0||i===0)return c;let s=e.map(u=>Oe(u,n)),l=t.map(u=>Oe(u,n)),a=new Array(i).fill(!1);for(let u of c)u>=0&&(a[u]=!0);let f=new Map;l.forEach((u,p)=>{a[p]||f.set(u,f.has(u)?-1:p)});let y=new Map;s.forEach((u,p)=>{c[p]>=0||y.set(u,(y.get(u)||0)+1)}),s.forEach((u,p)=>{if(c[p]>=0||y.get(u)!==1)return;let g=f.get(u);g===void 0||g===-1||a[g]||(c[p]=g,a[g]=!0)});let d=[];for(let u=0;u<r;u++)c[u]<0&&d.push(u);let T=[];for(let u=0;u<i;u++)a[u]||T.push(u);if(d.length===0||T.length===0)return c;let h=r*i+1,m=(u,p)=>Qe(e[u],t[p],n)*h+Math.abs(u-p);for(let[u,p]of Ze(d,T,m))c[u]=p;return c}var Se=e=>typeof e=="object"&&e!==null;function Oe(e,t){if(!Se(t))return e==null?" null":String(e);let n=Object.keys(t);return JSON.stringify(n.map(o=>{let r=JSON.stringify(e?.[o]);return r===void 0?" undef":r}))}function Qe(e,t,n){if(!Se(n))return e===t?0:1;let o=Object.keys(n);if(o.length===0)return 0;let r=0;for(let i of o){let c=JSON.stringify(e?.[i]),s=JSON.stringify(t?.[i]);c!==s&&r++}return r}function Ze(e,t,n){return e.length<=t.length?Ae(e,t,n,!1):Ae(t,e,(o,r)=>n(r,o),!0)}function Ae(e,t,n,o){let r=e.length,i=t.length,c=[];for(let y=0;y<=r;y++)c.push(new Float64Array(i+1).fill(1/0));let s=[];for(let y=0;y<=r;y++)s.push(new Uint8Array(i+1));for(let y=0;y<=i;y++)c[r][y]=0;for(let y=r-1;y>=0;y--)for(let d=i-1;d>=0;d--){let T=n(e[y],t[d])+c[y+1][d+1],h=c[y][d+1];T<=h?(c[y][d]=T,s[y][d]=1):c[y][d]=h}let l=[],a=0,f=0;for(;a<r&&f<i;)s[a][f]&&(l.push(o?[t[f],e[a]]:[e[a],t[f]]),a++),f++;return l}function le(e,t,n,o,r,i,c,s={}){let l=e.find(t,n,s);if(r.length===0){l.forEach(E=>e.remove(E)),se(s,"onRowsApplied",i.path,[]);return}let a=r.length>l.length,f=l[0]||null;if(a&&!f&&(f=rt(e,t,n,s),!f))throw new U(i.path);let y=l.map(E=>nt(e,E,o,s)),d=null;if(a&&f){d=e.clone(f),s.templateAttr&&e.removeAttr(d,s.templateAttr);let E=e.stripIds(d);E>0&&console.warn(`[hyper-html-api] stripped ${E} id attribute(s) from cloned template at "${i.path.join(".")||"(root)"}"`)}let T=be(r,y,o,et(e,l,r,i,s)),h=l[0]||f,m=e.parent(h),u=l.length>0?Re(e,m,h):0,p=ot(e,l),g=new Set,A=[],O=r.map((E,x)=>{let w=T[x];if(w>=0)return g.add(w),A.push(!1),l[w];A.push(!0);let R=e.clone(d);return e.stripIds(R),R});l.forEach((E,x)=>{g.has(x)||e.remove(E)}),p?O.forEach((E,x)=>{let w=u+x;e.children(m).findIndex(Fe=>e.sameNode(Fe,E))!==w&&e.insertAt(m,E,w)}):it(e,O,A,m,u),tt(e,O,o,r,i,c,s),se(s,"onRowsApplied",i.path,O)}function se(e,t,n,o){if(typeof e[t]=="function")try{return e[t](n.slice(),o)}catch(r){console.warn(`[hyper-html-api] ${t} threw at "${n.join(".")||"(root)"}"`,r);return}}function et(e,t,n,o,r){let i=se(r,"identifyRows",o.path,n);if(!Array.isArray(i))return null;let c=new Array(n.length).fill(-1),s=new Set;for(let l=0;l<n.length;l++)if(i[l]){for(let a=0;a<t.length;a++)if(!(s.has(a)||!e.sameNode(t[a],i[l]))){c[l]=a,s.add(a);break}}return c}function tt(e,t,n,o,r,i,c){t.forEach((s,l)=>{if(n===null){let a=o[l],f=a==null?"":String(a);e.text(s)!==f&&e.text(s,f)}else{let a=i(e,s,n,o[l],{depth:r.depth+1,path:[...r.path,l]},c);a&&a!==s&&(t[l]=a)}})}function nt(e,t,n,o){return n===null?e.text(t):M(e,t,n,o.onRowsRead?{...o,onRowsRead:void 0}:o)}function Re(e,t,n){let o=e.children(t);for(let r=0;r<o.length;r++)if(e.sameNode(o[r],n))return r;return-1}function rt(e,t,n,o){if(!o.templateAttr)return null;let r=t;for(;r;){let i=e.find(r,n,{includeRulesTag:!1,templateAttr:null});for(let c of i)if(e.attr(c,o.templateAttr)!=null)return c;r=e.parent(r)}return null}function ot(e,t){if(t.length<=1)return!0;let n=e.parent(t[0]);if(!n)return!1;let o=e.children(n),r=[];for(let i of t){let c=o.findIndex(s=>e.sameNode(s,i));if(c===-1)return!1;r.push(c)}return r.sort((i,c)=>i-c),r[r.length-1]-r[0]===r.length-1}function it(e,t,n,o,r){let i=null,c=r;for(let s=0;s<t.length;s++){if(!n[s]){i=t[s];continue}let l=i?e.parent(i):o;if(!l)continue;let a=i?Re(e,l,i)+1:c++;e.insertAt(l,t[s],a),i=t[s]}}var Me=new Set(["checked","selected","disabled","readOnly","paused"]);function P(e,t,n,o,r={}){if(Object.prototype.hasOwnProperty.call(r,"exclude")&&e.semanticExclude===!1)throw new Error("This adapter does not support semantic exclude queries; omit exclude or use the DOM adapter.");let i=[];if(ce(n,o,[],i),i.length)throw new v(i);G(e,t,n,o,{depth:0,path:[]},r)}function G(e,t,n,o,r,i={}){if(r.depth>_)throw new I(r.path);if(o===void 0)return t;if(typeof n=="string")return st(e,t,n,o,r,i);if(Array.isArray(n)){let[c,s]=n;return le(e,t,c,s,o,r,G,i),t}if(typeof n=="object"&&n!==null){for(let[c,s]of Object.entries(n)){let l=G(e,t,s,o==null?o:o[c],{depth:r.depth+1,path:[...r.path,c]},i);l&&l!==t&&(t=l)}return t}return t}function st(e,t,n,o,r,i){if(n.endsWith("[]")){let l=n.slice(0,-2);return le(e,t,l,null,o,r,G,i),t}if(n.startsWith("@"))return Ne(e,t,n.slice(1),o);let c=N(n);if(c!==-1){let l=n.slice(0,c),a=n.slice(c+1),f=l?e.find(t,l,i):[t];return f.length===0||Ne(e,f[0],a,o),t}if(n===".")return Ce(e,t,o),t;let s=e.find(t,n,i);return s.length===0||Ce(e,s[0],o),t}function Ce(e,t,n){let o=n==null?"":String(n);e.text(t)!==o&&e.text(t,o)}function Ne(e,t,n,o){if(re.has(n))throw new H(n);if(n==="outerHTML"){let i=o==null?"":String(o);return e.replaceWith(t,i)}if(we.has(n)){let i=lt(n,o);return e.prop(t,n)!==i&&e.prop(t,n,i),t}let r=o==null?"":String(o);return e.attr(t,n)!==r&&e.attr(t,n,r),t}function lt(e,t){return t==null?Me.has(e)?!1:"":Me.has(e)?t==="false"?!1:!!t:t}function ce(e,t,n,o){if(t!==void 0){if(typeof e=="string"){if(e.endsWith("[]")){Array.isArray(t)?t.forEach((r,i)=>{typeof r=="object"&&r!==null&&o.push({path:q([...n,i]),expected:"scalar",got:W(r)})}):o.push({path:q(n),expected:"array",got:W(t)});return}t!==null&&typeof t=="object"&&o.push({path:q(n),expected:"scalar",got:W(t)});return}if(Array.isArray(e)){if(!Array.isArray(t)){o.push({path:q(n),expected:"array",got:W(t)});return}let r=e[1];t.forEach((i,c)=>ce(r,i,[...n,c],o));return}if(typeof e=="object"&&e!==null){if(t===null||Array.isArray(t)||typeof t!="object"){o.push({path:q(n),expected:"object",got:W(t)});return}for(let[r,i]of Object.entries(e))ce(i,t[r],[...n,r],o)}}}function W(e){return e===null?"null":Array.isArray(e)?"array":typeof e}function q(e){return e.join(".")}function fe(e){try{return JSON.parse(e)}catch(t){throw new k(`Invalid strict JSON: ${t.message}`,t)}}function L(e){try{return JSON.parse(e)}catch{}let t={BRACE_OPEN:"{",BRACE_CLOSE:"}",BRACKET_OPEN:"[",BRACKET_CLOSE:"]",COLON:":",COMMA:",",STRING:"STRING",SELECTOR:"SELECTOR",IDENTIFIER:"IDENTIFIER",NUMBER:"NUMBER",BOOLEAN:"BOOLEAN"};function n(r){let i=[],c=0;for(;c<r.length;){let s=r[c];if(/\s/.test(s)){c++;continue}if("{}".includes(s)){i.push({type:s,value:s}),c++;continue}if(s==="["){let y=!1,d=c+1;for(;d<r.length&&/\s/.test(r[d]);)d++;if(d<r.length&&/[a-zA-Z_]/.test(r[d])&&(y=!0),!y){i.push({type:s,value:s}),c++;continue}}if(s==="]"){i.push({type:s,value:s}),c++;continue}if(s===":"){i.push({type:t.COLON,value:s}),c++;continue}if(s===","){i.push({type:t.COMMA,value:s}),c++;continue}if(s==='"'||s==="'"){let y=s,d=c+1;for(;d<r.length&&r[d]!==y;)r[d]==="\\"&&d++,d++;i.push({type:t.STRING,value:r.substring(c+1,d),quoted:!0,sourceQuote:y}),c=d+1;continue}let l=c,a;for(;l<r.length&&!/[{},]/.test(r[l]);)if(r[l]===":"){let y=[":first",":last",":nth-child",":nth-of-type",":first-child",":last-child",":first-of-type",":last-of-type",":only-child",":only-of-type",":hover",":focus",":active",":visited",":disabled",":enabled",":checked",":empty",":root",":target",":not",":before",":after",":nth-last-child",":nth-last-of-type"],d=!1;for(let T of y){let h=T.substring(1);if(r.substring(l+1,l+1+h.length)===h){d=!0,l+=h.length;break}}if(!d)break}else if(r[l]==="["){for(l++;l<r.length&&r[l]!=="]";){if(r[l]==='"'||r[l]==="'"){let y=r[l];for(l++;l<r.length&&r[l]!==y;)r[l]==="\\"&&l++,l++}l++}l<r.length&&r[l]==="]"&&l++}else l++;a=r.substring(c,l);let f=t.IDENTIFIER;/^-?\d+(\.\d+)?$/.test(a)?f=t.NUMBER:a==="true"||a==="false"||a==="null"?f=t.BOOLEAN:/^[.#@\[]|[.#@\[]| /.test(a)&&(f=t.SELECTOR),i.push({type:f,value:a,quoted:!1}),c=l}return i}function o(r){let i="";for(let c=0;c<r.length;c++){let s=r[c];if("{}".includes(s.type)||"[]".includes(s.type)){i+=s.value;continue}if(s.type===t.COLON){i+=s.value;continue}if(s.type===t.COMMA){let l=r[c+1];if(l&&(l.type==="}"||l.type==="]"))continue;i+=s.value;continue}if(s.type===t.STRING&&s.quoted){let l=s.value;s.sourceQuote==="'"&&(l=l.replace(/\\'/g,"'"),l=l.replace(/(\\*)"/g,(a,f)=>f.length%2===0?f+'\\"':a)),i+=`"${l}"`;continue}if(s.type===t.NUMBER||s.type===t.BOOLEAN){i+=s.value;continue}if(s.type===t.SELECTOR||s.type===t.IDENTIFIER){i+=`"${s.value}"`;continue}i+=`"${s.value}"`}return i}try{let r=n(e),i=o(r);return JSON.parse(i)}catch(r){throw new k("Invalid extraction rules syntax: "+r.message,r)}}var ue="1",je=/^[a-zA-Z0-9_-]+$/;function B(e,t,n){let o;if(n===void 0)o="script[data-rules-name]";else{if(typeof n!="string"||!je.test(n))throw new Error(`hyper-html-api: invalid rules token ${JSON.stringify(n)} (must match ${je})`);o=`script[data-rules-name~="${n}"]`}let r=e.find(t,o,{includeRulesTag:!0});if(r.length===0)return null;n!==void 0&&r.length>1&&console.warn(`hyper-html-api: ${r.length} rules tags match data-rules-name~="${n}"; using the first.`);let i=r[0],c=e.attr(i,"data-rules-version");if(c!==ue)throw new j(c);return{rules:L(e.text(i)),tagNode:i}}function ae(e,t,n){if(n&&typeof n=="object")return{rules:n,tagNode:null};if(typeof n=="string"){let o=t&&t.ownerDocument?t.ownerDocument:t;return B(e,o,n)}return null}var Ie=Object.freeze({data:Object.freeze({tokens:["no-data"],bundles:["editor-ui"]}),save:Object.freeze({tokens:["no-save"],bundles:["editor-ui"]}),snapshot:Object.freeze({tokens:["no-snapshot"],bundles:["editor-ui"]}),watch:Object.freeze({tokens:["no-watch"],bundles:["editor-ui"]}),undo:Object.freeze({tokens:["no-undo"],bundles:["editor-ui"]}),history:Object.freeze({tokens:[],bundles:["editor-ui"]})}),ft=Object.freeze({"editor-ui":Object.freeze(["no-data","no-save","no-snapshot","no-watch","no-undo"])}),rn=Object.freeze(["no-save","no-snapshot","no-trigger-autosave","no-dirty","no-watch","no-undo","no-data","freeze","editor-ui"]);function de(e,t){if(!e||e.nodeType!==1)return!1;let n=e.getAttribute?.("clay");return!!(n&&n.split(/\s+/).includes(t)||e.hasAttribute?.(t))}function ut(e,t){if(de(e,t))return!0;for(let[n,o]of Object.entries(ft))if(o.includes(t)&&de(e,n))return!0;return!1}function z(e){let t=Ie[e];if(!t)throw new Error(`Unknown region capability: ${e}`);return[...t.tokens,...t.bundles].flatMap(n=>[`[clay~="${n}"]`,`[${n}]`]).join(", ")}function at(e,t){let n=e&&e.nodeType===1?e:e?.parentElement;for(;n&&n.nodeType===1;){let o=Ie[t];if(!o)throw new Error(`Unknown region capability: ${t}`);if(o.tokens.some(r=>ut(n,r))||o.bundles.some(r=>de(n,r)))return n;n=n.parentElement}return null}function Pe(e,t){return!!at(e,t)}var dt=/:(?:focus(?:-within|-visible)?|hover|active|visited|defined)\b/i;function Le(e,t){if(!/^(INPUT|TEXTAREA|SELECT|OPTION)$/.test(e.tagName||""))return;let n=(e.getAttribute?.("type")||"").toLowerCase();if("value"in e&&"value"in t&&e.tagName!=="OPTION"&&n!=="checkbox"&&n!=="radio"&&(t.value=e.value),"checked"in e&&"checked"in t&&(t.checked=e.checked),"selected"in e&&"selected"in t&&(t.selected=e.selected),e.tagName==="SELECT")for(let o=0;o<e.options.length;o++)t.options[o].selected=e.options[o].selected;"indeterminate"in e&&"indeterminate"in t&&(t.indeterminate=e.indeterminate)}function De(e,t,n,o){if(o)return!!e.closest?.(t);let r=e;for(;r?.nodeType===1;){if(r.matches(t))return!0;if(r===n)break;r=r.parentElement}return!1}function ke(e,t,n,o,r,i,c,s){if(e.nodeType===1&&((c?Pe(e,n):De(e,o,i,!1))||r&&De(e,r,i,c)))return null;let l=t.importNode(e,!1);s.cloneToLive.set(l,e),s.liveToClone.set(e,l);let a=e.nodeType===1&&e.tagName==="TEMPLATE"?e.content:e,f=l.nodeType===1&&l.tagName==="TEMPLATE"?l.content:l;a!==e&&(s.cloneToLive.set(f,a),s.liveToClone.set(a,f));for(let y of a.childNodes||[]){let d=ke(y,t,n,o,r,i,c,s);d&&(f.appendChild(d),y.nodeType===1&&Le(y,d))}return e.nodeType===1&&Le(e,l),l}function F(e,{capability:t="data",exclude:n=null,inherit:o=!0}={}){if(!e)throw new TypeError("createContentView requires a DOM context");let r=e.nodeType===9?e:e.ownerDocument;if(!r?.implementation?.createHTMLDocument)throw new TypeError("createContentView requires an HTML DOM implementation");let i=r.implementation.createHTMLDocument(""),c=new WeakMap,s=new WeakMap,l=e.nodeType===9?e.documentElement:e;n&&i.documentElement.matches(n);let a=z(t),f=ke(l,i,t,a,n,l,o,{cloneToLive:c,liveToClone:s});e.nodeType===9&&f&&(i.replaceChild(f,i.documentElement),s.set(e,i),c.set(i,e));let y=d=>{if(dt.test(d))throw new Error(`Filtered content queries do not support stateful selector: ${d}`)};return{root:f,document:i,capability:t,selector:z(t),cloneToLive:c,liveToClone:s,original(d){return c.get(d)||null},cloneOf(d){return s.get(d)||null},query(d,T=f){return y(d),Array.from(T.querySelectorAll(d),h=>c.get(h)||h)},text(d=f){return(d===f?f:s.get(d))?.textContent||""},html(d=f){return(d===f?f:s.get(d))?.innerHTML??""},clone(d=f){let T=d===f?f:s.get(d);return T?i.importNode(T,!0):null}}}function _e(e){return e&&e.nodeType===1&&e.tagName==="SCRIPT"&&e.hasAttribute&&e.hasAttribute("data-rules-name")}function pt(e){return e?(e.nodeType===9||e.nodeType===11,e):null}var b={semanticExclude:!0,find(e,t,n={}){let o=pt(e);if(!o||!o.querySelectorAll)return[];let r=Array.from(o.querySelectorAll(t));n.includeRulesTag||(r=r.filter(s=>!_e(s)));let i=[];n.skip&&i.push(n.skip);let c=n.templateAttr===null?null:n.templateAttr||"cms-template";if(c&&i.push("["+c+"]"),i.length){let s=i.join(", ");r=r.filter(l=>!l.closest||!l.closest(s))}return r},parent(e){return e?e.parentElement:null},children(e){return e?Array.from(e.children):[]},text(e,t){if(t===void 0)return(e.textContent||"").trim();e.textContent=t},attr(e,t,n){if(n===void 0)return e.hasAttribute&&e.hasAttribute(t)?e.getAttribute(t):null;e.setAttribute(t,n)},removeAttr(e,t){e&&e.removeAttribute&&e.removeAttribute(t)},prop(e,t,n){if(n===void 0){let o=e?e[t]:void 0;return o!==void 0?o:null}e[t]=n},clone(e){return e.cloneNode(!0)},insertAt(e,t,n){let o=e.children[n]||null;e.insertBefore(t,o)},remove(e){e&&e.parentNode&&e.parentNode.removeChild(e)},replaceWith(e,t){if(!e||!e.parentNode)throw new Error("dom.replaceWith: node has no parent");let o=e.ownerDocument.createElement("template");o.innerHTML=t;let r=o.content.firstElementChild;if(!r)throw new Error("dom.replaceWith: html did not parse to an element");return e.parentNode.replaceChild(r,e),r},stripIds(e){let t=0;return e.id&&(e.removeAttribute("id"),t++),(e.querySelectorAll?e.querySelectorAll("[id]"):[]).forEach(o=>{o.removeAttribute("id"),t++}),t},sameNode(e,t){return e===t}};function K(e,t={}){if(t.exclude===null)return b;let n=[z("data"),t.exclude].filter(Boolean).join(", "),o=e.nodeType===9?e:e.ownerDocument||e,r=e.nodeType===9?e.documentElement:e;if(!t._write&&!r?.matches?.(n)&&!r?.querySelector?.(n)&&!o?.querySelector?.(n))return b;let i=e.nodeType===9||!e.isConnected?e:e.ownerDocument,c=e.nodeType===9?e:e.ownerDocument,s=null,l=()=>s||(s=F(i,{capability:"data",exclude:t.exclude||null})),a=h=>{let m=l();return h===e?m.cloneOf(e):m.cloneOf(h)||h},f=h=>s?.original(h)||h,y=(h,m)=>{l().liveToClone.set(h,m),l().cloneToLive.set(m,h);let u=h.childNodes||[],p=m.childNodes||[];for(let g=0;g<Math.min(u.length,p.length);g++)y(u[g],p[g])},d=(h,m,u,p)=>{let g=Array.from(h.childNodes).filter(w=>s.cloneOf(w)),O=g[0];for(;O&&g.includes(O);)O=O.nextSibling;for(let w of g)w.remove();if(u==="innerHTML"){let w=c.createElement("template");w.innerHTML=p;for(let R of Array.from(w.content.childNodes))h.insertBefore(R,O||null)}else h.insertBefore(c.createTextNode(p),O||null);let E=F(h,{capability:"data",exclude:t.exclude||null});m.replaceChildren(...Array.from(E.root?.childNodes||[]));let x=w=>{let R=E.original(w);R&&(s.liveToClone.set(R,w),s.cloneToLive.set(w,R));for(let ge of Array.from(w.childNodes||[]))x(ge)};for(let w of Array.from(m.childNodes))x(w)},T={...b,find(h,m,u={}){let p=a(h);if(!p?.querySelectorAll)return[];let g=l().query(m,p);u.includeRulesTag||(g=g.filter(E=>!_e(E)));let A=[];u.skip&&A.push(u.skip);let O=u.templateAttr===null?null:u.templateAttr||"cms-template";if(O&&A.push(`[${O}]`),A.length){let E=A.join(", ");g=g.filter(x=>!x.closest?.(E))}return g},parent(h){let m=a(h)?.parentElement;return m?f(m):null},children(h){return Array.from(a(h)?.children||[],f)},text(h,m){if(m===void 0){let g=f(h);return!g?.matches?.(n)&&!g?.querySelector?.(n)?b.text(g):(a(h)?.textContent||"").trim()}let u=f(h);if(!u?.matches?.(n)&&!u?.querySelector?.(n)&&!s){b.text(u,m);return}let p=l().cloneOf(u);p?d(u,p,"textContent",m):b.text(u,m)},attr(h,m,u){let p=f(h);if(u===void 0)return b.attr(p,m);b.attr(p,m,u);let g=s?.cloneOf(p);g&&(b.attr(g,m,u),F(p,{capability:"data",exclude:t.exclude||null}).root===null&&(g.remove(),s.liveToClone.delete(p),s.cloneToLive.delete(g)))},removeAttr(h,m){let u=f(h);b.removeAttr(u,m);let p=s?.cloneOf(u);p&&b.removeAttr(p,m)},prop(h,m,u){let p=f(h);if(u===void 0)return m==="innerHTML"||m==="outerHTML"||m==="textContent"||m==="innerText"?b.prop(a(p),m):b.prop(p,m);let g=m==="innerHTML"||m==="textContent"||m==="innerText",A=g?l().cloneOf(p):s?.cloneOf(p);A&&g?d(p,A,m,u):(b.prop(p,m,u),A&&b.prop(A,m,u))},clone(h){let m=a(h);return m===h?b.clone(h):c.importNode(m,!0)},insertAt(h,m,u){let p=f(h),A=T.children(p)[u]||(()=>{for(let x=p.children.length-1;x>=0;x--){let w=p.children[x];if(l().cloneOf(w))return w.nextElementSibling}return p.firstElementChild})(),O=f(m);p.insertBefore(O,A||null);let E=l().cloneOf(p);if(E){let x=l().cloneOf(O);x||(x=c.importNode(O,!0),y(O,x));let w=Array.from(E.children);E.insertBefore(x,w[u]||null)}},remove(h){let m=f(h),u=l().cloneOf(m);b.remove(m),u&&b.remove(u)},replaceWith(h,m){let u=f(h),p=l().cloneOf(u),g=b.replaceWith(u,m);if(p){let A=F(g,{capability:"data",exclude:t.exclude||null});if(!A.root)p.remove();else{p.replaceWith(A.root);let O=E=>{let x=A.original(E);x&&(s.liveToClone.set(x,E),s.cloneToLive.set(E,x));for(let w of Array.from(E.childNodes||[]))O(w)};O(A.root)}}return g}};return T}var S=b;var pe={extract:(e,t,n={})=>M(K(e,n),e,t,n),apply:(e,t,n,o={})=>P(K(e,{...o,_write:!0}),e,t,n,o),findRulesIn:(e,t)=>B(S,e,t),findRules:(e,t)=>ae(S,e,t),bind:(e,t,n={})=>{let o=ae(S,e,t);if(!o){let r=typeof t=="string"?`data-rules-name~="${t}"`:"the provided rules object";throw new Error(`hyper-html-api: could not resolve rules for ${r}`)}return{...o,get:()=>M(K(e,n),e,o.rules,n),set:r=>P(K(e,{...n,_write:!0}),e,o.rules,r,n)}},parseStrict:fe,parseRelaxed:L,ruleAttrIndex:N,splitRule:oe,errors:Y,DOM_PROPERTIES:J};var ht="hha:upgrade-check:";function C(e,t){let n=e.querySelector(`meta[name="${t}"]`),o=n?n.getAttribute("content"):null;return o&&o.trim()?o.trim():null}function $e(e){if(typeof e!="string")return null;let t=e.trim().replace(/^v/,"");return/^\d+(\.\d+)*$/.test(t)?t.split(".").map(Number):null}function mt(e,t){let n=$e(e),o=$e(t);if(!n||!o)return!1;let r=Math.max(n.length,o.length);for(let i=0;i<r;i++){let c=n[i]||0,s=o[i]||0;if(c!==s)return c>s}return!1}function yt(e){try{let t=globalThis.localStorage.getItem(e);return t?JSON.parse(t):null}catch{return null}}function gt(e,t){try{globalThis.localStorage.setItem(e,JSON.stringify(t))}catch{}}async function ve({force:e=!1,doc:t,loc:n,fetchFn:o,now:r,ttlMs:i=864e5}={}){if(t=t||(typeof document<"u"?document:null),n=n||(typeof location<"u"?location:null),o=o||(d=>fetch(d)),r=r??Date.now(),!t)return null;let c=C(t,"hyper-source");if(!c)return null;let s=C(t,"hyper-version"),l;try{l=new URL(c,n?n.href:void 0)}catch{return null}if(n&&l.origin===n.origin&&l.pathname===n.pathname)return null;let a=`${ht}${l.href}:${s||"none"}`,f,y=e?null:yt(a);if(y&&typeof y.checkedAt=="number"&&r-y.checkedAt<i)f=y.sourceVersion;else{try{let d=await o(l.href);if(!d.ok)throw new Error(`HTTP ${d.status}`);let T=await d.text(),h=new DOMParser().parseFromString(T,"text/html");f=C(h,"hyper-version")}catch{f=null}gt(a,{checkedAt:r,sourceVersion:f})}return f?{available:mt(f,s||"0.0.0"),currentVersion:s,sourceVersion:f,sourceUrl:l.href}:null}var Et="script[data-rules-name]";function wt(e){return typeof e=="string"?e.trim().replace(/\s+/g," "):""}function X(e,t){let n=e.find(t,Et,{includeRulesTag:!0}),o=new Set,r=[];for(let i of n){let c=wt(e.attr(i,"data-rules-name"));if(!c)continue;if(o.has(c)){console.warn(`hyper-html-api: duplicate rules tag name "${c}"; using the first.`);continue}let s=e.attr(i,"data-rules-version");if(s!==ue)throw new j(s);o.add(c),r.push({name:c,rules:L(e.text(i))})}return r}function he(e,t){let n={};for(let{name:o,rules:r}of X(e,t))n[o]=M(e,t,r);return n}function Ue(e){let t=e||document,n=t.nodeType===9?t:t.ownerDocument||t;return{dataByName:he(S,t),version:C(n,"hyper-version")}}var V=class extends Error{constructor(t,n){super(`could not fetch upgrade source: ${t}`),this.name="UpgradeSourceUnreachable",this.sourceUrl=t,this.cause=n}},Q=class extends Error{constructor(t){super(`upgrade source has no rules tags; refusing to drop all existing data: ${t}`),this.name="UpgradeSourceHasNoRules",this.sourceUrl=t}},D=class extends Error{constructor(t,n){super(t),this.name="UpgradeTransformInvalid",this.cause=n}},Z=class extends Error{constructor(t){super(`found ${t} script[type="text/hyper-upgrade"] tags; only one is allowed per document.`),this.name="UpgradeMultipleTransforms",this.count=t}};var Tt="text/hyper-upgrade";function He(e,t){let n=e.find(t,`script[type="${Tt}"]`);if(n.length===0)return null;if(n.length>1)throw new Z(n.length);return e.text(n[0])||null}var xt=new Function("url","return import(url)");async function We(e){let t=new Blob([e],{type:"text/javascript"}),n=URL.createObjectURL(t),o;try{o=await xt(n)}catch(r){throw new D(`transform failed to load: ${r&&r.message?r.message:r}`,r)}finally{URL.revokeObjectURL(n)}if(typeof o.default!="function")throw new D("transform must `export default` a function");return o.default}function ee(e,t){let n={carriedOver:0,discarded:0,listItems:0},o=me(t,e,n);return ye(t,e,n),{data:o,summary:n}}function me(e,t,n){if(typeof e=="string")return e.endsWith("[]")?Array.isArray(t)?(n.listItems+=t.length,n.carriedOver+=t.length,t):void 0:t==null||typeof t=="object"?void 0:(n.carriedOver++,t);if(Array.isArray(e)){let[,o]=e;return Array.isArray(t)?(n.listItems+=t.length,t.map(r=>me(o,r,n))):void 0}if(typeof e=="object"&&e!==null){let o={};for(let[r,i]of Object.entries(e)){let c=me(i,t?.[r],n);c!==void 0&&(o[r]=c)}return o}}function ye(e,t,n){if(t!=null){if(typeof e=="object"&&e!==null&&!Array.isArray(e)){if(typeof t!="object"||Array.isArray(t))return;let o=new Set(Object.keys(e));for(let r of Object.keys(t))o.has(r)?ye(e[r],t[r],n):n.discarded+=$(t[r]);return}if(Array.isArray(e)&&Array.isArray(t)){let o=e[1];t.forEach(r=>ye(o,r,n));return}typeof e=="string"&&!e.endsWith("[]")&&typeof t=="object"&&t!==null&&(n.discarded+=$(t))}}function $(e){return e==null?0:Array.isArray(e)?e.reduce((t,n)=>t+$(n),0):typeof e=="object"?Object.values(e).reduce((t,n)=>t+$(n),0):1}function qe(e,t,n){let o=X(e,t),r={carriedOver:0,discarded:0,listItems:0},i={},c=new Set;for(let{name:s,rules:l}of o){if(c.add(s),!Object.prototype.hasOwnProperty.call(n,s)){i[s]={carriedOver:0,discarded:0,listItems:0};continue}let{data:a,summary:f}=ee(n[s],l);P(e,t,l,a),i[s]=f,r.carriedOver+=f.carriedOver,r.discarded+=f.discarded,r.listItems+=f.listItems}for(let s of Object.keys(n))c.has(s)||(r.discarded+=$(n[s]));return{totals:r,byName:i,rulesTagCount:o.length}}async function Be({sourceUrl:e,dataByName:t,fromVersion:n,doc:o,loc:r,fetchFn:i}={}){if(o=o||(typeof document<"u"?document:null),r=r||(typeof location<"u"?location:null),i=i||(p=>fetch(p)),!o)throw new Error("upgrade.run requires a document context");if(e=e||C(o,"hyper-source"),!e)throw new Error("upgrade.run: no sourceUrl given and no hyper-source meta tag found");let c=new URL(e,r?r.href:void 0);n=n!==void 0?n:C(o,"hyper-version"),t=t||he(S,o);let s;try{s=await i(c.href)}catch(p){throw new V(c.href,p)}if(!s.ok)throw new V(c.href,new Error(`HTTP ${s.status}`));let l=await s.text(),a=new DOMParser().parseFromString(l,"text/html"),f=C(a,"hyper-version"),y=t,d=!1,T=He(S,a);if(T){let g=await(await We(T))(y,{fromVersion:n,toVersion:f});if(!g||typeof g!="object"||Array.isArray(g))throw new D("transform must return a plain object map of { rulesName: data }");y=g,d=!0}let{totals:h,byName:m,rulesTagCount:u}=qe(S,a,y);if(u===0&&Object.keys(y).length>0)throw new Q(c.href);return{html:Ot(a),fromVersion:n,toVersion:f,summary:{transformApplied:d,totals:h,byName:m}}}function Ot(e){return`<!DOCTYPE ${e.doctype&&e.doctype.name?e.doctype.name:"html"}>
|
|
2
|
-
`+e.documentElement.outerHTML}var
|
|
1
|
+
var hyperHtmlApiUpgrade=(()=>{var re=Object.defineProperty;var Xe=Object.getOwnPropertyDescriptor;var Ge=Object.getOwnPropertyNames;var Ze=Object.prototype.hasOwnProperty;var Ee=(e,t)=>{for(var r in t)re(e,r,{get:t[r],enumerable:!0})},Qe=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Ge(t))!Ze.call(e,n)&&n!==r&&re(e,n,{get:()=>t[n],enumerable:!(o=Xe(t,n))||o.enumerable});return e};var et=e=>Qe(re({},"__esModule",{value:!0}),e);var jt={};Ee(jt,{default:()=>Nt,engine:()=>ye,upgrade:()=>Je});var J=["textContent","innerText","innerHTML","outerHTML","value","checked","selected","disabled","readOnly","type","tagName","nodeName","nodeType","nodeValue","childElementCount","id","className","classList","baseURI","offsetWidth","offsetHeight","clientWidth","clientHeight","scrollWidth","scrollHeight","dataset","currentSrc","duration","paused","title","documentURI","contentType"],ne=new Set(J),Ae=new Set(["textContent","innerText","innerHTML","value","checked","selected","disabled","readOnly","type","id","className","title"]),oe=new Set(["tagName","nodeName","nodeType","nodeValue","childElementCount","classList","baseURI","documentURI","contentType","offsetWidth","offsetHeight","clientWidth","clientHeight","scrollWidth","scrollHeight","currentSrc","duration","paused","dataset"]);var X={};Ee(X,{EmptyListInsert:()=>U,MAX_RULE_DEPTH:()=>_,MaxRuleDepthExceeded:()=>I,NoRulesTag:()=>ie,RuleTargetReadOnly:()=>W,RulesParseError:()=>D,ShapeMismatch:()=>H,UnknownRulesVersion:()=>j,WriteRefused:()=>Y,WriteRejected:()=>se});var D=class extends Error{constructor(t,r){super(t),this.name="RulesParseError",this.cause=r}},j=class extends Error{constructor(t){super(`unknown rules version: ${t}. Library supports "1".`),this.name="UnknownRulesVersion",this.version=t}},_=20,I=class extends Error{constructor(t){super(`rule depth exceeded ${_} at path: ${t.join(".")}`),this.name="MaxRuleDepthExceeded",this.path=t}},H=class extends Error{constructor(t){super(`shape mismatch: ${t.length} field(s) failed validation`),this.name="ShapeMismatch",this.mismatches=t}},U=class extends Error{constructor(t){super(`cannot add items to empty list at "${t.join(".")}" \u2014 no sibling to clone as template. Seed the list with a hidden item first.`),this.name="EmptyListInsert",this.path=t}},W=class extends Error{constructor(t){super(`cannot write to read-only DOM property "${t}"`),this.name="RuleTargetReadOnly",this.target=t}},Y=class extends Error{constructor(t){super(`write refused: ${t.length} write(s) broke the content-only policy`),this.name="WriteRefused",this.refusals=t}},ie=class extends Error{constructor(t){super(`no <script data-rules-name~="${t}"> rules tag in this document`),this.name="NoRulesTag",this.token=t}},se=class extends Error{constructor(t,r){super(`write rejected: ${t.length} unknown key(s), ${r.length} rule(s) with no matching element`),this.name="WriteRejected",this.unknownKeys=t,this.unmatched=r}};function C(e){let t=0,r=null,o=-1;for(let n=0;n<e.length;n++){let i=e[n];i==="\\"?n++:r?i===r&&(r=null):i==='"'||i==="'"?r=i:i==="["||i==="("?t++:i==="]"||i===")"?t>0&&t--:i==="@"&&t===0&&(o=n)}return o}function ce(e){let t=C(e);return t===-1?{selector:e,prop:null}:{selector:e.slice(0,t),prop:e.slice(t+1)||null}}function M(e,t,r,o={}){if(Object.prototype.hasOwnProperty.call(o,"exclude")&&e.semanticExclude===!1)throw new Error("This adapter does not support semantic exclude queries; omit exclude or use the DOM adapter.");return le(e,t,r,{depth:0,path:[]},o)}function le(e,t,r,o,n){if(o.depth>_)throw new I(o.path);if(typeof r=="string")return tt(e,t,r,o,n);if(Array.isArray(r)){let[i,l]=r,s=e.find(t,i,n);return be(n,o,s),s.map((c,a)=>le(e,c,l,{depth:o.depth+1,path:[...o.path,a]},n))}if(typeof r=="object"&&r!==null){let i={};for(let[l,s]of Object.entries(r))i[l]=le(e,t,s,{depth:o.depth+1,path:[...o.path,l]},n);return i}return null}function tt(e,t,r,o,n){if(r.endsWith("[]")){let s=r.slice(0,-2),c=e.find(t,s,n);return be(n,o,c),c.map(a=>e.text(a))}if(r.startsWith("@"))return Oe(e,t,r.slice(1));let i=C(r);if(i!==-1){let s=r.slice(0,i),c=r.slice(i+1),a=s?e.find(t,s,n):[t];return a.length===0?null:Oe(e,a[0],c)}if(r===".")return e.text(t);let l=e.find(t,r,n);return l.length===0?null:e.text(l[0])}function be(e,t,r){if(typeof e.onRowsRead=="function")try{e.onRowsRead(t.path.slice(),r)}catch(o){console.warn(`[hyper-html-api] onRowsRead threw at "${t.path.join(".")||"(root)"}"`,o)}}function Oe(e,t,r){if(ne.has(r)){let n=e.prop(t,r);return n==null?null:String(n)}let o=e.attr(t,r);return o||null}function Ce(e,t,r,o){let n=e.length,i=t.length,l=new Array(n).fill(-1);if(o){let u=new Set;for(let p=0;p<n;p++){let g=o[p];!(g>=0&&g<i)||u.has(g)||(l[p]=g,u.add(g))}}if(n===0||i===0)return l;let s=e.map(u=>Se(u,r)),c=t.map(u=>Se(u,r)),a=new Array(i).fill(!1);for(let u of l)u>=0&&(a[u]=!0);let f=new Map;c.forEach((u,p)=>{a[p]||f.set(u,f.has(u)?-1:p)});let y=new Map;s.forEach((u,p)=>{l[p]>=0||y.set(u,(y.get(u)||0)+1)}),s.forEach((u,p)=>{if(l[p]>=0||y.get(u)!==1)return;let g=f.get(u);g===void 0||g===-1||a[g]||(l[p]=g,a[g]=!0)});let d=[];for(let u=0;u<n;u++)l[u]<0&&d.push(u);let T=[];for(let u=0;u<i;u++)a[u]||T.push(u);if(d.length===0||T.length===0)return l;let h=n*i+1,m=(u,p)=>rt(e[u],t[p],r)*h+Math.abs(u-p);for(let[u,p]of nt(d,T,m))l[u]=p;return l}var Me=e=>typeof e=="object"&&e!==null;function Se(e,t){if(!Me(t))return e==null?" null":String(e);let r=Object.keys(t);return JSON.stringify(r.map(o=>{let n=JSON.stringify(e?.[o]);return n===void 0?" undef":n}))}function rt(e,t,r){if(!Me(r))return e===t?0:1;let o=Object.keys(r);if(o.length===0)return 0;let n=0;for(let i of o){let l=JSON.stringify(e?.[i]),s=JSON.stringify(t?.[i]);l!==s&&n++}return n}function nt(e,t,r){return e.length<=t.length?Re(e,t,r,!1):Re(t,e,(o,n)=>r(n,o),!0)}function Re(e,t,r,o){let n=e.length,i=t.length,l=[];for(let y=0;y<=n;y++)l.push(new Float64Array(i+1).fill(1/0));let s=[];for(let y=0;y<=n;y++)s.push(new Uint8Array(i+1));for(let y=0;y<=i;y++)l[n][y]=0;for(let y=n-1;y>=0;y--)for(let d=i-1;d>=0;d--){let T=r(e[y],t[d])+l[y+1][d+1],h=l[y][d+1];T<=h?(l[y][d]=T,s[y][d]=1):l[y][d]=h}let c=[],a=0,f=0;for(;a<n&&f<i;)s[a][f]&&(c.push(o?[t[f],e[a]]:[e[a],t[f]]),a++),f++;return c}function ue(e,t,r,o,n,i,l,s={}){let c=e.find(t,r,s);if(n.length===0){c.forEach(w=>e.remove(w)),fe(s,"onRowsApplied",i.path,[]);return}let a=n.length>c.length,f=c[0]||null;if(a&&!f&&(f=ct(e,t,r,s),!f))throw new U(i.path);let y=c.map(w=>st(e,w,o,s)),d=null;if(a&&f){d=e.clone(f),s.templateAttr&&e.removeAttr(d,s.templateAttr);let w=e.stripIds(d);w>0&&console.warn(`[hyper-html-api] stripped ${w} id attribute(s) from cloned template at "${i.path.join(".")||"(root)"}"`)}let T=Ce(n,y,o,ot(e,c,n,i,s)),h=c[0]||f,m=e.parent(h),u=c.length>0?Ne(e,m,h):0,p=lt(e,c),g=new Set,O=[],A=n.map((w,E)=>{let x=T[E];if(x>=0)return g.add(x),O.push(!1),c[x];O.push(!0);let R=e.clone(d);return e.stripIds(R),R});c.forEach((w,E)=>{g.has(E)||e.remove(w)}),p?A.forEach((w,E)=>{let x=u+E;e.children(m).findIndex(Ye=>e.sameNode(Ye,w))!==x&&e.insertAt(m,w,x)}):ft(e,A,O,m,u),it(e,A,o,n,i,l,s),fe(s,"onRowsApplied",i.path,A)}function fe(e,t,r,o){if(typeof e[t]=="function")try{return e[t](r.slice(),o)}catch(n){console.warn(`[hyper-html-api] ${t} threw at "${r.join(".")||"(root)"}"`,n);return}}function ot(e,t,r,o,n){let i=fe(n,"identifyRows",o.path,r);if(!Array.isArray(i))return null;let l=new Array(r.length).fill(-1),s=new Set;for(let c=0;c<r.length;c++)if(i[c]){for(let a=0;a<t.length;a++)if(!(s.has(a)||!e.sameNode(t[a],i[c]))){l[c]=a,s.add(a);break}}return l}function it(e,t,r,o,n,i,l){t.forEach((s,c)=>{if(r===null){let a=o[c],f=a==null?"":String(a);e.text(s)!==f&&e.text(s,f)}else{let a=i(e,s,r,o[c],{depth:n.depth+1,path:[...n.path,c]},l);a&&a!==s&&(t[c]=a)}})}function st(e,t,r,o){return r===null?e.text(t):M(e,t,r,o.onRowsRead?{...o,onRowsRead:void 0}:o)}function Ne(e,t,r){let o=e.children(t);for(let n=0;n<o.length;n++)if(e.sameNode(o[n],r))return n;return-1}function ct(e,t,r,o){if(!o.templateAttr)return null;let n=t;for(;n;){let i=e.find(n,r,{includeRulesTag:!1,templateAttr:null});for(let l of i)if(e.attr(l,o.templateAttr)!=null)return l;n=e.parent(n)}return null}function lt(e,t){if(t.length<=1)return!0;let r=e.parent(t[0]);if(!r)return!1;let o=e.children(r),n=[];for(let i of t){let l=o.findIndex(s=>e.sameNode(s,i));if(l===-1)return!1;n.push(l)}return n.sort((i,l)=>i-l),n[n.length-1]-n[0]===n.length-1}function ft(e,t,r,o,n){let i=null,l=n;for(let s=0;s<t.length;s++){if(!r[s]){i=t[s];continue}let c=i?e.parent(i):o;if(!c)continue;let a=i?Ne(e,c,i)+1:l++;e.insertAt(c,t[s],a),i=t[s]}}var je=new Set(["checked","selected","disabled","readOnly","paused"]);function L(e,t,r,o,n={}){if(Object.prototype.hasOwnProperty.call(n,"exclude")&&e.semanticExclude===!1)throw new Error("This adapter does not support semantic exclude queries; omit exclude or use the DOM adapter.");let i=[];if(ae(r,o,[],i),i.length)throw new H(i);G(e,t,r,o,{depth:0,path:[]},n)}function G(e,t,r,o,n,i={}){if(n.depth>_)throw new I(n.path);if(o===void 0)return t;if(typeof r=="string")return ut(e,t,r,o,n,i);if(Array.isArray(r)){let[l,s]=r;return ue(e,t,l,s,o,n,G,i),t}if(typeof r=="object"&&r!==null){for(let[l,s]of Object.entries(r)){let c=G(e,t,s,o==null?o:o[l],{depth:n.depth+1,path:[...n.path,l]},i);c&&c!==t&&(t=c)}return t}return t}function ut(e,t,r,o,n,i){if(r.endsWith("[]")){let c=r.slice(0,-2);return ue(e,t,c,null,o,n,G,i),t}if(r.startsWith("@"))return Le(e,t,r.slice(1),o);let l=C(r);if(l!==-1){let c=r.slice(0,l),a=r.slice(l+1),f=c?e.find(t,c,i):[t];return f.length===0||Le(e,f[0],a,o),t}if(r===".")return Ie(e,t,o),t;let s=e.find(t,r,i);return s.length===0||Ie(e,s[0],o),t}function Ie(e,t,r){let o=r==null?"":String(r);e.text(t)!==o&&e.text(t,o)}function Le(e,t,r,o){if(oe.has(r)){let i=e.prop(t,r);if(i===o||i!=null&&o!=null&&String(i)===String(o))return t;throw new W(r)}if(r==="outerHTML"){let i=o==null?"":String(o);return e.replaceWith(t,i)}if(Ae.has(r)){let i=at(r,o);return e.prop(t,r)!==i&&e.prop(t,r,i),t}let n=o==null?"":String(o);return e.attr(t,r)!==n&&e.attr(t,r,n),t}function at(e,t){return t==null?je.has(e)?!1:"":je.has(e)?t==="false"?!1:!!t:t}function ae(e,t,r,o){if(t!==void 0){if(typeof e=="string"){if(e.endsWith("[]")){Array.isArray(t)?t.forEach((n,i)=>{typeof n=="object"&&n!==null&&o.push({path:q([...r,i]),expected:"scalar",got:v(n)})}):o.push({path:q(r),expected:"array",got:v(t)});return}t!==null&&typeof t=="object"&&o.push({path:q(r),expected:"scalar",got:v(t)});return}if(Array.isArray(e)){if(!Array.isArray(t)){o.push({path:q(r),expected:"array",got:v(t)});return}let n=e[1];t.forEach((i,l)=>ae(n,i,[...r,l],o));return}if(typeof e=="object"&&e!==null){if(t===null||Array.isArray(t)||typeof t!="object"){o.push({path:q(r),expected:"object",got:v(t)});return}for(let[n,i]of Object.entries(e))ae(i,t[n],[...r,n],o)}}}function v(e){return e===null?"null":Array.isArray(e)?"array":typeof e}function q(e){return e.join(".")}function de(e){try{return JSON.parse(e)}catch(t){throw new D(`Invalid strict JSON: ${t.message}`,t)}}function k(e){try{return JSON.parse(e)}catch{}let t={BRACE_OPEN:"{",BRACE_CLOSE:"}",BRACKET_OPEN:"[",BRACKET_CLOSE:"]",COLON:":",COMMA:",",STRING:"STRING",SELECTOR:"SELECTOR",IDENTIFIER:"IDENTIFIER",NUMBER:"NUMBER",BOOLEAN:"BOOLEAN"};function r(n){let i=[],l=0;for(;l<n.length;){let s=n[l];if(/\s/.test(s)){l++;continue}if("{}".includes(s)){i.push({type:s,value:s}),l++;continue}if(s==="["){let y=!1,d=l+1;for(;d<n.length&&/\s/.test(n[d]);)d++;if(d<n.length&&/[a-zA-Z_]/.test(n[d])&&(y=!0),!y){i.push({type:s,value:s}),l++;continue}}if(s==="]"){i.push({type:s,value:s}),l++;continue}if(s===":"){i.push({type:t.COLON,value:s}),l++;continue}if(s===","){i.push({type:t.COMMA,value:s}),l++;continue}if(s==='"'||s==="'"){let y=s,d=l+1;for(;d<n.length&&n[d]!==y;)n[d]==="\\"&&d++,d++;i.push({type:t.STRING,value:n.substring(l+1,d),quoted:!0,sourceQuote:y}),l=d+1;continue}let c=l,a;for(;c<n.length&&!/[{},]/.test(n[c]);)if(n[c]===":"){let y=[":first",":last",":nth-child",":nth-of-type",":first-child",":last-child",":first-of-type",":last-of-type",":only-child",":only-of-type",":hover",":focus",":active",":visited",":disabled",":enabled",":checked",":empty",":root",":target",":not",":before",":after",":nth-last-child",":nth-last-of-type"],d=!1;for(let T of y){let h=T.substring(1);if(n.substring(c+1,c+1+h.length)===h){d=!0,c+=h.length;break}}if(!d)break}else if(n[c]==="["){for(c++;c<n.length&&n[c]!=="]";){if(n[c]==='"'||n[c]==="'"){let y=n[c];for(c++;c<n.length&&n[c]!==y;)n[c]==="\\"&&c++,c++}c++}c<n.length&&n[c]==="]"&&c++}else c++;a=n.substring(l,c);let f=t.IDENTIFIER;/^-?\d+(\.\d+)?$/.test(a)?f=t.NUMBER:a==="true"||a==="false"||a==="null"?f=t.BOOLEAN:/^[.#@\[]|[.#@\[]| /.test(a)&&(f=t.SELECTOR),i.push({type:f,value:a,quoted:!1}),l=c}return i}function o(n){let i="";for(let l=0;l<n.length;l++){let s=n[l];if("{}".includes(s.type)||"[]".includes(s.type)){i+=s.value;continue}if(s.type===t.COLON){i+=s.value;continue}if(s.type===t.COMMA){let c=n[l+1];if(c&&(c.type==="}"||c.type==="]"))continue;i+=s.value;continue}if(s.type===t.STRING&&s.quoted){let c=s.value;s.sourceQuote==="'"&&(c=c.replace(/\\'/g,"'"),c=c.replace(/(\\*)"/g,(a,f)=>f.length%2===0?f+'\\"':a)),i+=`"${c}"`;continue}if(s.type===t.NUMBER||s.type===t.BOOLEAN){i+=s.value;continue}if(s.type===t.SELECTOR||s.type===t.IDENTIFIER){i+=`"${s.value}"`;continue}i+=`"${s.value}"`}return i}try{let n=r(e),i=o(n);return JSON.parse(i)}catch(n){throw new D("Invalid extraction rules syntax: "+n.message,n)}}var pe="1",ke=/^[a-zA-Z0-9_-]+$/;function B(e,t,r){let o;if(r===void 0)o="script[data-rules-name]";else{if(typeof r!="string"||!ke.test(r))throw new Error(`hyper-html-api: invalid rules token ${JSON.stringify(r)} (must match ${ke})`);o=`script[data-rules-name~="${r}"]`}let n=e.find(t,o,{includeRulesTag:!0});if(n.length===0)return null;r!==void 0&&n.length>1&&console.warn(`hyper-html-api: ${n.length} rules tags match data-rules-name~="${r}"; using the first.`);let i=n[0],l=e.attr(i,"data-rules-version");if(l!==pe)throw new j(l);return{rules:k(e.text(i)),tagNode:i}}var Pe=Object.freeze({data:Object.freeze({tokens:["no-data"],bundles:["editor-ui"]}),save:Object.freeze({tokens:["no-save"],bundles:["editor-ui"]}),snapshot:Object.freeze({tokens:["no-snapshot"],bundles:["editor-ui"]}),watch:Object.freeze({tokens:["no-watch"],bundles:["editor-ui"]}),undo:Object.freeze({tokens:["no-undo"],bundles:["editor-ui"]}),history:Object.freeze({tokens:[],bundles:["editor-ui"]})}),dt=Object.freeze({"editor-ui":Object.freeze(["no-data","no-save","no-snapshot","no-watch","no-undo"])}),De=Object.freeze(["no-save","no-snapshot","no-trigger-autosave","no-dirty","no-watch","no-undo","no-data","freeze","editor-ui"]);function he(e,t){if(!e||e.nodeType!==1)return!1;let r=e.getAttribute?.("clay");return!!(r&&r.split(/\s+/).includes(t)||e.hasAttribute?.(t))}function pt(e,t){if(he(e,t))return!0;for(let[r,o]of Object.entries(dt))if(o.includes(t)&&he(e,r))return!0;return!1}function z(e){let t=Pe[e];if(!t)throw new Error(`Unknown region capability: ${e}`);return[...t.tokens,...t.bundles].flatMap(r=>[`[clay~="${r}"]`,`[${r}]`]).join(", ")}function ht(e,t){let r=e&&e.nodeType===1?e:e?.parentElement;for(;r&&r.nodeType===1;){let o=Pe[t];if(!o)throw new Error(`Unknown region capability: ${t}`);if(o.tokens.some(n=>pt(r,n))||o.bundles.some(n=>he(r,n)))return r;r=r.parentElement}return null}function _e(e,t){return!!ht(e,t)}var mt=Object.freeze({refusedRuleForms:["innerHTML","outerHTML"],refusedTargets:["script","style","template","noscript","iframe","object","embed","xmp","plaintext","noembed","noframes","meta","link","base","animate","set","animatemotion","animatetransform"],refusedAttributes:["style","srcdoc","is","http-equiv","sandbox","allow","nonce","integrity","charset","htmlclaytoken","htmlclayid","data-rules-name","data-rules-version","clay","contenteditable",...De],refusedAttributePrefixes:["on"],urlAttributes:["href","src","srcset","action","formaction","poster","cite","data","ping","background","longdesc","usemap","xlink:href","manifest","codebase","icon"],refusedSchemes:["javascript","vbscript","data"]});function me(e,t,r){if(r&&typeof r=="object")return{rules:r,tagNode:null};if(typeof r=="string"){let o=t&&t.ownerDocument?t.ownerDocument:t;return B(e,o,r)}return null}var gt=/:(?:focus(?:-within|-visible)?|hover|active|visited|defined)\b/i;function $e(e,t){if(!/^(INPUT|TEXTAREA|SELECT|OPTION)$/.test(e.tagName||""))return;let r=(e.getAttribute?.("type")||"").toLowerCase();if("value"in e&&"value"in t&&e.tagName!=="OPTION"&&r!=="checkbox"&&r!=="radio"&&(t.value=e.value),"checked"in e&&"checked"in t&&(t.checked=e.checked),"selected"in e&&"selected"in t&&(t.selected=e.selected),e.tagName==="SELECT")for(let o=0;o<e.options.length;o++)t.options[o].selected=e.options[o].selected;"indeterminate"in e&&"indeterminate"in t&&(t.indeterminate=e.indeterminate)}function He(e,t,r,o){if(o)return!!e.closest?.(t);let n=e;for(;n?.nodeType===1;){if(n.matches(t))return!0;if(n===r)break;n=n.parentElement}return!1}function Ue(e,t,r,o,n,i,l,s){if(e.nodeType===1&&((l?_e(e,r):He(e,o,i,!1))||n&&He(e,n,i,l)))return null;let c=t.importNode(e,!1);s.cloneToLive.set(c,e),s.liveToClone.set(e,c);let a=e.nodeType===1&&e.tagName==="TEMPLATE"?e.content:e,f=c.nodeType===1&&c.tagName==="TEMPLATE"?c.content:c;a!==e&&(s.cloneToLive.set(f,a),s.liveToClone.set(a,f));for(let y of a.childNodes||[]){let d=Ue(y,t,r,o,n,i,l,s);d&&(f.appendChild(d),y.nodeType===1&&$e(y,d))}return e.nodeType===1&&$e(e,c),c}function F(e,{capability:t="data",exclude:r=null,inherit:o=!0}={}){if(!e)throw new TypeError("createContentView requires a DOM context");let n=e.nodeType===9?e:e.ownerDocument;if(!n?.implementation?.createHTMLDocument)throw new TypeError("createContentView requires an HTML DOM implementation");let i=n.implementation.createHTMLDocument(""),l=new WeakMap,s=new WeakMap,c=e.nodeType===9?e.documentElement:e;r&&i.documentElement.matches(r);let a=z(t),f=Ue(c,i,t,a,r,c,o,{cloneToLive:l,liveToClone:s});e.nodeType===9&&f&&(i.replaceChild(f,i.documentElement),s.set(e,i),l.set(i,e));let y=d=>{if(gt.test(d))throw new Error(`Filtered content queries do not support stateful selector: ${d}`)};return{root:f,document:i,capability:t,selector:z(t),cloneToLive:l,liveToClone:s,original(d){return l.get(d)||null},cloneOf(d){return s.get(d)||null},query(d,T=f){return y(d),Array.from(T.querySelectorAll(d),h=>l.get(h)||h)},text(d=f){return(d===f?f:s.get(d))?.textContent||""},html(d=f){return(d===f?f:s.get(d))?.innerHTML??""},clone(d=f){let T=d===f?f:s.get(d);return T?i.importNode(T,!0):null}}}function We(e){return e&&e.nodeType===1&&e.tagName==="SCRIPT"&&e.hasAttribute&&e.hasAttribute("data-rules-name")}function wt(e){return e?(e.nodeType===9||e.nodeType===11,e):null}var b={semanticExclude:!0,find(e,t,r={}){let o=wt(e);if(!o||!o.querySelectorAll)return[];let n=Array.from(o.querySelectorAll(t));r.includeRulesTag||(n=n.filter(s=>!We(s)));let i=[];r.skip&&i.push(r.skip);let l=r.templateAttr===null?null:r.templateAttr||"cms-template";if(l&&i.push("["+l+"]"),i.length){let s=i.join(", ");n=n.filter(c=>!c.closest||!c.closest(s))}return n},parent(e){return e?e.parentElement:null},children(e){return e?Array.from(e.children):[]},text(e,t){if(t===void 0)return(e.textContent||"").trim();e.textContent=t},attr(e,t,r){if(r===void 0)return e.hasAttribute&&e.hasAttribute(t)?e.getAttribute(t):null;e.setAttribute(t,r)},removeAttr(e,t){e&&e.removeAttribute&&e.removeAttribute(t)},prop(e,t,r){if(r===void 0){let o=e?e[t]:void 0;return o!==void 0?o:null}e[t]=r},clone(e){return e.cloneNode(!0)},insertAt(e,t,r){let o=e.children[r]||null;e.insertBefore(t,o)},remove(e){e&&e.parentNode&&e.parentNode.removeChild(e)},replaceWith(e,t){if(!e||!e.parentNode)throw new Error("dom.replaceWith: node has no parent");let o=e.ownerDocument.createElement("template");o.innerHTML=t;let n=o.content.firstElementChild;if(!n)throw new Error("dom.replaceWith: html did not parse to an element");return e.parentNode.replaceChild(n,e),n},stripIds(e){let t=0;return e.id&&(e.removeAttribute("id"),t++),(e.querySelectorAll?e.querySelectorAll("[id]"):[]).forEach(o=>{o.removeAttribute("id"),t++}),t},sameNode(e,t){return e===t}};function K(e,t={}){if(t.exclude===null)return b;let r=[z("data"),t.exclude].filter(Boolean).join(", "),o=e.nodeType===9?e:e.ownerDocument||e,n=e.nodeType===9?e.documentElement:e;if(!t._write&&!n?.matches?.(r)&&!n?.querySelector?.(r)&&!o?.querySelector?.(r))return b;let i=e.nodeType===9||!e.isConnected?e:e.ownerDocument,l=e.nodeType===9?e:e.ownerDocument,s=null,c=()=>s||(s=F(i,{capability:"data",exclude:t.exclude||null})),a=h=>{let m=c();return h===e?m.cloneOf(e):m.cloneOf(h)||h},f=h=>s?.original(h)||h,y=(h,m)=>{c().liveToClone.set(h,m),c().cloneToLive.set(m,h);let u=h.childNodes||[],p=m.childNodes||[];for(let g=0;g<Math.min(u.length,p.length);g++)y(u[g],p[g])},d=(h,m,u,p)=>{let g=Array.from(h.childNodes).filter(x=>s.cloneOf(x)),A=g[0];for(;A&&g.includes(A);)A=A.nextSibling;for(let x of g)x.remove();if(u==="innerHTML"){let x=l.createElement("template");x.innerHTML=p;for(let R of Array.from(x.content.childNodes))h.insertBefore(R,A||null)}else h.insertBefore(l.createTextNode(p),A||null);let w=F(h,{capability:"data",exclude:t.exclude||null});m.replaceChildren(...Array.from(w.root?.childNodes||[]));let E=x=>{let R=w.original(x);R&&(s.liveToClone.set(R,x),s.cloneToLive.set(x,R));for(let Te of Array.from(x.childNodes||[]))E(Te)};for(let x of Array.from(m.childNodes))E(x)},T={...b,find(h,m,u={}){let p=a(h);if(!p?.querySelectorAll)return[];let g=c().query(m,p);u.includeRulesTag||(g=g.filter(w=>!We(w)));let O=[];u.skip&&O.push(u.skip);let A=u.templateAttr===null?null:u.templateAttr||"cms-template";if(A&&O.push(`[${A}]`),O.length){let w=O.join(", ");g=g.filter(E=>!E.closest?.(w))}return g},parent(h){let m=a(h)?.parentElement;return m?f(m):null},children(h){return Array.from(a(h)?.children||[],f)},text(h,m){if(m===void 0){let g=f(h);return!g?.matches?.(r)&&!g?.querySelector?.(r)?b.text(g):(a(h)?.textContent||"").trim()}let u=f(h);if(!u?.matches?.(r)&&!u?.querySelector?.(r)&&!s){b.text(u,m);return}let p=c().cloneOf(u);p?d(u,p,"textContent",m):b.text(u,m)},attr(h,m,u){let p=f(h);if(u===void 0)return b.attr(p,m);b.attr(p,m,u);let g=s?.cloneOf(p);g&&(b.attr(g,m,u),F(p,{capability:"data",exclude:t.exclude||null}).root===null&&(g.remove(),s.liveToClone.delete(p),s.cloneToLive.delete(g)))},removeAttr(h,m){let u=f(h);b.removeAttr(u,m);let p=s?.cloneOf(u);p&&b.removeAttr(p,m)},prop(h,m,u){let p=f(h);if(u===void 0)return m==="innerHTML"||m==="outerHTML"||m==="textContent"||m==="innerText"?b.prop(a(p),m):b.prop(p,m);let g=m==="innerHTML"||m==="textContent"||m==="innerText",O=g?c().cloneOf(p):s?.cloneOf(p);O&&g?d(p,O,m,u):(b.prop(p,m,u),O&&b.prop(O,m,u))},clone(h){let m=a(h);return m===h?b.clone(h):l.importNode(m,!0)},insertAt(h,m,u){let p=f(h),O=T.children(p)[u]||(()=>{for(let E=p.children.length-1;E>=0;E--){let x=p.children[E];if(c().cloneOf(x))return x.nextElementSibling}return p.firstElementChild})(),A=f(m);p.insertBefore(A,O||null);let w=c().cloneOf(p);if(w){let E=c().cloneOf(A);E||(E=l.importNode(A,!0),y(A,E));let x=Array.from(w.children);w.insertBefore(E,x[u]||null)}},remove(h){let m=f(h),u=c().cloneOf(m);b.remove(m),u&&b.remove(u)},replaceWith(h,m){let u=f(h),p=c().cloneOf(u),g=b.replaceWith(u,m);if(p){let O=F(g,{capability:"data",exclude:t.exclude||null});if(!O.root)p.remove();else{p.replaceWith(O.root);let A=w=>{let E=O.original(w);E&&(s.liveToClone.set(E,w),s.cloneToLive.set(w,E));for(let x of Array.from(w.childNodes||[]))A(x)};A(O.root)}}return g}};return T}var S=b;var ye={extract:(e,t,r={})=>M(K(e,r),e,t,r),apply:(e,t,r,o={})=>L(K(e,{...o,_write:!0}),e,t,r,o),findRulesIn:(e,t)=>B(S,e,t),findRules:(e,t)=>me(S,e,t),bind:(e,t,r={})=>{let o=me(S,e,t);if(!o){let n=typeof t=="string"?`data-rules-name~="${t}"`:"the provided rules object";throw new Error(`hyper-html-api: could not resolve rules for ${n}`)}return{...o,get:()=>M(K(e,r),e,o.rules,r),set:n=>L(K(e,{...r,_write:!0}),e,o.rules,n,r)}},parseStrict:de,parseRelaxed:k,ruleAttrIndex:C,splitRule:ce,errors:X,DOM_PROPERTIES:J};var xt="hha:upgrade-check:";function N(e,t){let r=e.querySelector(`meta[name="${t}"]`),o=r?r.getAttribute("content"):null;return o&&o.trim()?o.trim():null}function ve(e){if(typeof e!="string")return null;let t=e.trim().replace(/^v/,"");return/^\d+(\.\d+)*$/.test(t)?t.split(".").map(Number):null}function Tt(e,t){let r=ve(e),o=ve(t);if(!r||!o)return!1;let n=Math.max(r.length,o.length);for(let i=0;i<n;i++){let l=r[i]||0,s=o[i]||0;if(l!==s)return l>s}return!1}function Et(e){try{let t=globalThis.localStorage.getItem(e);return t?JSON.parse(t):null}catch{return null}}function At(e,t){try{globalThis.localStorage.setItem(e,JSON.stringify(t))}catch{}}async function qe({force:e=!1,doc:t,loc:r,fetchFn:o,now:n,ttlMs:i=864e5}={}){if(t=t||(typeof document<"u"?document:null),r=r||(typeof location<"u"?location:null),o=o||(d=>fetch(d)),n=n??Date.now(),!t)return null;let l=N(t,"hyper-source");if(!l)return null;let s=N(t,"hyper-version"),c;try{c=new URL(l,r?r.href:void 0)}catch{return null}if(r&&c.origin===r.origin&&c.pathname===r.pathname)return null;let a=`${xt}${c.href}:${s||"none"}`,f,y=e?null:Et(a);if(y&&typeof y.checkedAt=="number"&&n-y.checkedAt<i)f=y.sourceVersion;else{try{let d=await o(c.href);if(!d.ok)throw new Error(`HTTP ${d.status}`);let T=await d.text(),h=new DOMParser().parseFromString(T,"text/html");f=N(h,"hyper-version")}catch{f=null}At(a,{checkedAt:n,sourceVersion:f})}return f?{available:Tt(f,s||"0.0.0"),currentVersion:s,sourceVersion:f,sourceUrl:c.href}:null}var Ot="script[data-rules-name]";function bt(e){return typeof e=="string"?e.trim().replace(/\s+/g," "):""}function Z(e,t){let r=e.find(t,Ot,{includeRulesTag:!0}),o=new Set,n=[];for(let i of r){let l=bt(e.attr(i,"data-rules-name"));if(!l)continue;if(o.has(l)){console.warn(`hyper-html-api: duplicate rules tag name "${l}"; using the first.`);continue}let s=e.attr(i,"data-rules-version");if(s!==pe)throw new j(s);o.add(l),n.push({name:l,rules:k(e.text(i))})}return n}function ge(e,t){let r={};for(let{name:o,rules:n}of Z(e,t))r[o]=M(e,t,n);return r}function Be(e){let t=e||document,r=t.nodeType===9?t:t.ownerDocument||t;return{dataByName:ge(S,t),version:N(r,"hyper-version")}}var V=class extends Error{constructor(t,r){super(`could not fetch upgrade source: ${t}`),this.name="UpgradeSourceUnreachable",this.sourceUrl=t,this.cause=r}},Q=class extends Error{constructor(t){super(`upgrade source has no rules tags; refusing to drop all existing data: ${t}`),this.name="UpgradeSourceHasNoRules",this.sourceUrl=t}},P=class extends Error{constructor(t,r){super(t),this.name="UpgradeTransformInvalid",this.cause=r}},ee=class extends Error{constructor(t){super(`found ${t} script[type="text/hyper-upgrade"] tags; only one is allowed per document.`),this.name="UpgradeMultipleTransforms",this.count=t}};var St="text/hyper-upgrade";function ze(e,t){let r=e.find(t,`script[type="${St}"]`);if(r.length===0)return null;if(r.length>1)throw new ee(r.length);return e.text(r[0])||null}var Rt=new Function("url","return import(url)");async function Fe(e){let t=new Blob([e],{type:"text/javascript"}),r=URL.createObjectURL(t),o;try{o=await Rt(r)}catch(n){throw new P(`transform failed to load: ${n&&n.message?n.message:n}`,n)}finally{URL.revokeObjectURL(r)}if(typeof o.default!="function")throw new P("transform must `export default` a function");return o.default}function te(e,t){let r={carriedOver:0,discarded:0,listItems:0},o=we(t,e,r);return xe(t,e,r),{data:o,summary:r}}function we(e,t,r){if(typeof e=="string")return e.endsWith("[]")?Array.isArray(t)?(r.listItems+=t.length,r.carriedOver+=t.length,t):void 0:t==null||typeof t=="object"?void 0:(r.carriedOver++,t);if(Array.isArray(e)){let[,o]=e;return Array.isArray(t)?(r.listItems+=t.length,t.map(n=>we(o,n,r))):void 0}if(typeof e=="object"&&e!==null){let o={};for(let[n,i]of Object.entries(e)){let l=we(i,t?.[n],r);l!==void 0&&(o[n]=l)}return o}}function xe(e,t,r){if(t!=null){if(typeof e=="object"&&e!==null&&!Array.isArray(e)){if(typeof t!="object"||Array.isArray(t))return;let o=new Set(Object.keys(e));for(let n of Object.keys(t))o.has(n)?xe(e[n],t[n],r):r.discarded+=$(t[n]);return}if(Array.isArray(e)&&Array.isArray(t)){let o=e[1];t.forEach(n=>xe(o,n,r));return}typeof e=="string"&&!e.endsWith("[]")&&typeof t=="object"&&t!==null&&(r.discarded+=$(t))}}function $(e){return e==null?0:Array.isArray(e)?e.reduce((t,r)=>t+$(r),0):typeof e=="object"?Object.values(e).reduce((t,r)=>t+$(r),0):1}function Ke(e,t,r){let o=Z(e,t),n={carriedOver:0,discarded:0,listItems:0},i={},l=new Set;for(let{name:s,rules:c}of o){if(l.add(s),!Object.prototype.hasOwnProperty.call(r,s)){i[s]={carriedOver:0,discarded:0,listItems:0};continue}let{data:a,summary:f}=te(r[s],c);L(e,t,c,a),i[s]=f,n.carriedOver+=f.carriedOver,n.discarded+=f.discarded,n.listItems+=f.listItems}for(let s of Object.keys(r))l.has(s)||(n.discarded+=$(r[s]));return{totals:n,byName:i,rulesTagCount:o.length}}async function Ve({sourceUrl:e,dataByName:t,fromVersion:r,doc:o,loc:n,fetchFn:i}={}){if(o=o||(typeof document<"u"?document:null),n=n||(typeof location<"u"?location:null),i=i||(p=>fetch(p)),!o)throw new Error("upgrade.run requires a document context");if(e=e||N(o,"hyper-source"),!e)throw new Error("upgrade.run: no sourceUrl given and no hyper-source meta tag found");let l=new URL(e,n?n.href:void 0);r=r!==void 0?r:N(o,"hyper-version"),t=t||ge(S,o);let s;try{s=await i(l.href)}catch(p){throw new V(l.href,p)}if(!s.ok)throw new V(l.href,new Error(`HTTP ${s.status}`));let c=await s.text(),a=new DOMParser().parseFromString(c,"text/html"),f=N(a,"hyper-version"),y=t,d=!1,T=ze(S,a);if(T){let g=await(await Fe(T))(y,{fromVersion:r,toVersion:f});if(!g||typeof g!="object"||Array.isArray(g))throw new P("transform must return a plain object map of { rulesName: data }");y=g,d=!0}let{totals:h,byName:m,rulesTagCount:u}=Ke(S,a,y);if(u===0&&Object.keys(y).length>0)throw new Q(l.href);return{html:Ct(a),fromVersion:r,toVersion:f,summary:{transformApplied:d,totals:h,byName:m}}}function Ct(e){return`<!DOCTYPE ${e.doctype&&e.doctype.name?e.doctype.name:"html"}>
|
|
2
|
+
`+e.documentElement.outerHTML}var Je={checkForUpdate:qe,run:Ve,extractAll:Be,shapeMatch:te};var Mt={engine:ye,upgrade:Je},Nt=Mt;return et(jt);})();
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"apply",
|
|
10
10
|
"CMS"
|
|
11
11
|
],
|
|
12
|
-
"version": "0.
|
|
12
|
+
"version": "0.9.0",
|
|
13
13
|
"homepage": "https://github.com/panphora/hyper-html-api",
|
|
14
14
|
"bugs": {
|
|
15
15
|
"url": "https://github.com/panphora/hyper-html-api/issues"
|
|
@@ -33,7 +33,8 @@
|
|
|
33
33
|
"./cheerio": "./src/adapters/cheerio.js",
|
|
34
34
|
"./dom": "./src/adapters/dom.js",
|
|
35
35
|
"./data": "./src/data.js",
|
|
36
|
-
"./upgrade": "./src/upgrade.js"
|
|
36
|
+
"./upgrade": "./src/upgrade.js",
|
|
37
|
+
"./write": "./src/write.js"
|
|
37
38
|
},
|
|
38
39
|
"scripts": {
|
|
39
40
|
"build": "npx esbuild src/hyper-html-api.js --bundle --minify --format=iife --global-name=HyperHtmlApi --outfile=dist/hyper-html-api.min.js",
|
|
@@ -62,7 +63,7 @@
|
|
|
62
63
|
"url": "git+https://github.com/panphora/hyper-html-api.git"
|
|
63
64
|
},
|
|
64
65
|
"dependencies": {
|
|
65
|
-
"hyper-morph": "^0.
|
|
66
|
+
"hyper-morph": "^1.0.0"
|
|
66
67
|
},
|
|
67
68
|
"devDependencies": {
|
|
68
69
|
"@web/test-runner": "^0.20.0",
|
package/packed-contract.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"load":["hyper-html-api","hyper-html-api/cheerio","hyper-html-api/cms","hyper-html-api/data","hyper-html-api/dom","hyper-html-api/engine","hyper-html-api/upgrade"]}
|
|
1
|
+
{"load":["hyper-html-api","hyper-html-api/cheerio","hyper-html-api/cms","hyper-html-api/data","hyper-html-api/dom","hyper-html-api/engine","hyper-html-api/upgrade","hyper-html-api/write"]}
|
package/src/adapters/cheerio.js
CHANGED
|
@@ -1,3 +1,64 @@
|
|
|
1
|
+
import { capabilitySelector } from '../lib/region-capabilities.js'
|
|
2
|
+
|
|
3
|
+
const NO_DATA = capabilitySelector('data')
|
|
4
|
+
const NO_DATA_TOKENS = ['no-data', 'editor-ui']
|
|
5
|
+
|
|
6
|
+
function isElement(node) {
|
|
7
|
+
const t = node && node[0] && node[0].type
|
|
8
|
+
return t === 'tag' || t === 'script' || t === 'style'
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// The same test as the NO_DATA selector, without running css-select once per sibling:
|
|
12
|
+
// children() and insertAt() call it for every row of a list, and .is() made list writes quadratic
|
|
13
|
+
// with a large constant.
|
|
14
|
+
export function isNoDataEl(el) {
|
|
15
|
+
const attribs = el && el.attribs
|
|
16
|
+
if (!attribs) return false
|
|
17
|
+
if (NO_DATA_TOKENS.some((t) => Object.prototype.hasOwnProperty.call(attribs, t))) return true
|
|
18
|
+
const clay = attribs.clay
|
|
19
|
+
return typeof clay === 'string' && clay.split(/[\t\n\f\r ]+/).some((t) => NO_DATA_TOKENS.includes(t))
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function isNoData(node) {
|
|
23
|
+
return isElement(node) && isNoDataEl(node[0])
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function hasNoData(node) {
|
|
27
|
+
return !!node && node.length > 0 && isElement(node) && (node.is(NO_DATA) || node.find(NO_DATA).length > 0)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function inNoData(node) {
|
|
31
|
+
return !!node && !!node.closest && node.closest(NO_DATA).length > 0
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function projectedClone(node) {
|
|
35
|
+
const copy = node.clone()
|
|
36
|
+
copy.find(NO_DATA).remove()
|
|
37
|
+
return copy
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function escapeText(value) {
|
|
41
|
+
return String(value).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Mirrors dom.js replaceProjectedContent: remove only the children that are
|
|
45
|
+
// not no-data, then insert the new content where the first removed child was,
|
|
46
|
+
// so no-data children stay where they are.
|
|
47
|
+
function replaceProjected(node, html) {
|
|
48
|
+
const contents = node.contents()
|
|
49
|
+
const all = []
|
|
50
|
+
for (let i = 0; i < contents.length; i++) all.push(contents.eq(i))
|
|
51
|
+
const included = all.filter((k) => !isNoData(k))
|
|
52
|
+
const includedSet = new Set(included.map((k) => k[0]))
|
|
53
|
+
let anchorIdx = included.length ? all.findIndex((k) => k[0] === included[0][0]) : -1
|
|
54
|
+
while (anchorIdx !== -1 && anchorIdx < all.length && includedSet.has(all[anchorIdx][0])) anchorIdx++
|
|
55
|
+
const anchor = anchorIdx === -1 || anchorIdx >= all.length ? null : all[anchorIdx]
|
|
56
|
+
for (const k of included) k.remove()
|
|
57
|
+
if (html === '') return
|
|
58
|
+
if (anchor) anchor.before(html)
|
|
59
|
+
else node.append(html)
|
|
60
|
+
}
|
|
61
|
+
|
|
1
62
|
function isRulesTag(node) {
|
|
2
63
|
if (!node || !node.attr) return false
|
|
3
64
|
const tag = node.prop ? node.prop('tagName') : ''
|
|
@@ -20,6 +81,7 @@ const cheerioAdapter = {
|
|
|
20
81
|
if (!ctx || !ctx.find) return []
|
|
21
82
|
let matches = toWrappers(ctx.find(selector))
|
|
22
83
|
if (!opts.includeRulesTag) matches = matches.filter((n) => !isRulesTag(n))
|
|
84
|
+
matches = matches.filter((n) => !inNoData(n))
|
|
23
85
|
const skipParts = []
|
|
24
86
|
if (opts.skip) skipParts.push(opts.skip)
|
|
25
87
|
// The cms-template seed marker means "not data" for EVERY consumer, so skip
|
|
@@ -43,12 +105,25 @@ const cheerioAdapter = {
|
|
|
43
105
|
|
|
44
106
|
children(node) {
|
|
45
107
|
if (!node || !node.children) return []
|
|
46
|
-
|
|
108
|
+
const kids = node.children()
|
|
109
|
+
const out = []
|
|
110
|
+
for (let i = 0; i < kids.length; i++) {
|
|
111
|
+
if (!isNoDataEl(kids[i])) out.push(kids.eq(i))
|
|
112
|
+
}
|
|
113
|
+
return out
|
|
47
114
|
},
|
|
48
115
|
|
|
49
116
|
text(node, value) {
|
|
50
|
-
if (value === undefined)
|
|
51
|
-
|
|
117
|
+
if (value === undefined) {
|
|
118
|
+
if (!hasNoData(node)) return node.text().trim()
|
|
119
|
+
if (isNoData(node)) return ''
|
|
120
|
+
return projectedClone(node).text().trim()
|
|
121
|
+
}
|
|
122
|
+
if (!hasNoData(node)) {
|
|
123
|
+
node.text(value)
|
|
124
|
+
return
|
|
125
|
+
}
|
|
126
|
+
replaceProjected(node, escapeText(value))
|
|
52
127
|
},
|
|
53
128
|
|
|
54
129
|
attr(node, name, value) {
|
|
@@ -68,12 +143,22 @@ const cheerioAdapter = {
|
|
|
68
143
|
// Cheerio's .prop() doesn't expose innerHTML/textContent/className as
|
|
69
144
|
// proper properties. Route reads through the matching cheerio API so
|
|
70
145
|
// they're symmetric with the writes below (and with the DOM adapter).
|
|
71
|
-
if (name === 'innerHTML')
|
|
72
|
-
|
|
146
|
+
if (name === 'innerHTML') {
|
|
147
|
+
if (!hasNoData(node)) return node.html()
|
|
148
|
+
return isNoData(node) ? '' : projectedClone(node).html()
|
|
149
|
+
}
|
|
150
|
+
if (name === 'textContent' || name === 'innerText') {
|
|
151
|
+
if (!hasNoData(node)) return node.text()
|
|
152
|
+
return isNoData(node) ? '' : projectedClone(node).text()
|
|
153
|
+
}
|
|
73
154
|
if (name === 'className') {
|
|
74
155
|
const v = node.attr('class')
|
|
75
156
|
return v !== undefined ? v : null
|
|
76
157
|
}
|
|
158
|
+
if (name === 'type') {
|
|
159
|
+
const v = node.attr('type')
|
|
160
|
+
return v !== undefined ? v : null
|
|
161
|
+
}
|
|
77
162
|
const v = node.prop(name)
|
|
78
163
|
return v !== undefined ? v : null
|
|
79
164
|
}
|
|
@@ -82,9 +167,10 @@ const cheerioAdapter = {
|
|
|
82
167
|
// For names that have semantic write meaning, route through the right
|
|
83
168
|
// cheerio API instead.
|
|
84
169
|
const v = value == null ? '' : String(value)
|
|
85
|
-
if (name === 'innerHTML') return node.html(v)
|
|
86
|
-
if (name === 'textContent' || name === 'innerText') return node.text(v)
|
|
170
|
+
if (name === 'innerHTML') return hasNoData(node) ? replaceProjected(node, v) : node.html(v)
|
|
171
|
+
if (name === 'textContent' || name === 'innerText') return hasNoData(node) ? replaceProjected(node, escapeText(v)) : node.text(v)
|
|
87
172
|
if (name === 'className') return node.attr('class', v)
|
|
173
|
+
if (name === 'type') return node.attr('type', v)
|
|
88
174
|
node.prop(name, value)
|
|
89
175
|
},
|
|
90
176
|
|
|
@@ -103,13 +189,22 @@ const cheerioAdapter = {
|
|
|
103
189
|
},
|
|
104
190
|
|
|
105
191
|
clone(node) {
|
|
106
|
-
return node.clone()
|
|
192
|
+
return hasNoData(node) ? projectedClone(node) : node.clone()
|
|
107
193
|
},
|
|
108
194
|
|
|
109
195
|
insertAt(parent, node, index) {
|
|
110
196
|
const siblings = parent.children()
|
|
111
|
-
|
|
112
|
-
|
|
197
|
+
const all = toWrappers(siblings)
|
|
198
|
+
const content = all.filter((k) => !isNoDataEl(k[0]))
|
|
199
|
+
if (content.length === all.length) {
|
|
200
|
+
if (index >= siblings.length) parent.append(node)
|
|
201
|
+
else siblings.eq(index).before(node)
|
|
202
|
+
return
|
|
203
|
+
}
|
|
204
|
+
if (index < content.length) content[index].before(node)
|
|
205
|
+
else if (content.length) content[content.length - 1].after(node)
|
|
206
|
+
else if (all.length) all[0].before(node)
|
|
207
|
+
else parent.append(node)
|
|
113
208
|
},
|
|
114
209
|
|
|
115
210
|
remove(node) {
|
package/src/engine/apply.js
CHANGED
|
@@ -106,6 +106,8 @@ function writeText(adapter, node, value) {
|
|
|
106
106
|
// For every other write, returns the original node unchanged.
|
|
107
107
|
function writePropOrAttr(adapter, node, name, value) {
|
|
108
108
|
if (DOM_PROPERTIES_READ_ONLY_SET.has(name)) {
|
|
109
|
+
const current = adapter.prop(node, name)
|
|
110
|
+
if (current === value || (current != null && value != null && String(current) === String(value))) return node
|
|
109
111
|
throw new RuleTargetReadOnly(name)
|
|
110
112
|
}
|
|
111
113
|
if (name === 'outerHTML') {
|
package/src/engine/errors.js
CHANGED
|
@@ -49,3 +49,28 @@ export class RuleTargetReadOnly extends Error {
|
|
|
49
49
|
this.target = name
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
+
|
|
53
|
+
export class WriteRefused extends Error {
|
|
54
|
+
constructor(refusals) {
|
|
55
|
+
super(`write refused: ${refusals.length} write(s) broke the content-only policy`)
|
|
56
|
+
this.name = 'WriteRefused'
|
|
57
|
+
this.refusals = refusals
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export class NoRulesTag extends Error {
|
|
62
|
+
constructor(token) {
|
|
63
|
+
super(`no <script data-rules-name~="${token}"> rules tag in this document`)
|
|
64
|
+
this.name = 'NoRulesTag'
|
|
65
|
+
this.token = token
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export class WriteRejected extends Error {
|
|
70
|
+
constructor(unknownKeys, unmatched) {
|
|
71
|
+
super(`write rejected: ${unknownKeys.length} unknown key(s), ${unmatched.length} rule(s) with no matching element`)
|
|
72
|
+
this.name = 'WriteRejected'
|
|
73
|
+
this.unknownKeys = unknownKeys
|
|
74
|
+
this.unmatched = unmatched
|
|
75
|
+
}
|
|
76
|
+
}
|
package/src/engine/index.js
CHANGED
|
@@ -9,6 +9,9 @@ export { parseStrict, parseRelaxed } from './rules.js'
|
|
|
9
9
|
export { ruleAttrIndex, splitRule } from './rule-syntax.js'
|
|
10
10
|
export * as errors from './errors.js'
|
|
11
11
|
export { DOM_PROPERTIES, DOM_PROPERTIES_SET, DOM_PROPERTIES_READ_ONLY_SET } from './dom-properties.js'
|
|
12
|
+
export { WRITE_POLICY, guardAdapter, checkAttribute, urlScheme } from './write-policy.js'
|
|
13
|
+
export { planWrite } from './write-plan.js'
|
|
14
|
+
export { trackAdapter, spliceDocument } from './splice.js'
|
|
12
15
|
|
|
13
16
|
// source: object literal → use as-is (no tag); string → look up by token.
|
|
14
17
|
// For an element root, search the whole document (root.ownerDocument) so a
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
function raw(node) {
|
|
2
|
+
return node && node[0] ? node[0] : node
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
// Records which nodes a write touched. Structural changes mark the parent,
|
|
6
|
+
// since the parent's children are what changed. Clones are recorded so their
|
|
7
|
+
// copied source locations are never trusted.
|
|
8
|
+
export function trackAdapter(adapter) {
|
|
9
|
+
const dirty = new Set()
|
|
10
|
+
const cloned = new WeakSet()
|
|
11
|
+
const mark = (node) => {
|
|
12
|
+
const r = raw(node)
|
|
13
|
+
if (r) dirty.add(r)
|
|
14
|
+
}
|
|
15
|
+
const markTree = (r) => {
|
|
16
|
+
if (!r) return
|
|
17
|
+
cloned.add(r)
|
|
18
|
+
for (const c of r.children || []) markTree(c)
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
...adapter,
|
|
22
|
+
text(node, value) {
|
|
23
|
+
if (value === undefined) return adapter.text(node)
|
|
24
|
+
mark(node)
|
|
25
|
+
return adapter.text(node, value)
|
|
26
|
+
},
|
|
27
|
+
attr(node, name, value) {
|
|
28
|
+
if (value === undefined) return adapter.attr(node, name)
|
|
29
|
+
mark(node)
|
|
30
|
+
return adapter.attr(node, name, value)
|
|
31
|
+
},
|
|
32
|
+
removeAttr(node, name) {
|
|
33
|
+
mark(node)
|
|
34
|
+
return adapter.removeAttr(node, name)
|
|
35
|
+
},
|
|
36
|
+
prop(node, name, value) {
|
|
37
|
+
if (value === undefined) return adapter.prop(node, name)
|
|
38
|
+
mark(node)
|
|
39
|
+
return adapter.prop(node, name, value)
|
|
40
|
+
},
|
|
41
|
+
replaceWith(node, html) {
|
|
42
|
+
const p = adapter.parent(node)
|
|
43
|
+
if (p) mark(p)
|
|
44
|
+
return adapter.replaceWith(node, html)
|
|
45
|
+
},
|
|
46
|
+
clone(node) {
|
|
47
|
+
const c = adapter.clone(node)
|
|
48
|
+
markTree(raw(c))
|
|
49
|
+
return c
|
|
50
|
+
},
|
|
51
|
+
insertAt(parent, node, index) {
|
|
52
|
+
mark(parent)
|
|
53
|
+
const from = adapter.parent(node)
|
|
54
|
+
if (from) mark(from)
|
|
55
|
+
return adapter.insertAt(parent, node, index)
|
|
56
|
+
},
|
|
57
|
+
remove(node) {
|
|
58
|
+
const p = adapter.parent(node)
|
|
59
|
+
if (p) mark(p)
|
|
60
|
+
return adapter.remove(node)
|
|
61
|
+
},
|
|
62
|
+
dirty,
|
|
63
|
+
cloned,
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function attached(r, docRoot) {
|
|
68
|
+
let n = r
|
|
69
|
+
while (n && n.parent) n = n.parent
|
|
70
|
+
return n === docRoot
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function located(r, cloned) {
|
|
74
|
+
let n = r
|
|
75
|
+
while (n && n.type !== 'root') {
|
|
76
|
+
const loc = n.sourceCodeLocation
|
|
77
|
+
if (!cloned.has(n) && loc && loc.startOffset != null && loc.endOffset != null) return n
|
|
78
|
+
n = n.parent
|
|
79
|
+
}
|
|
80
|
+
return null
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function hasAncestorIn(r, set) {
|
|
84
|
+
let n = r.parent
|
|
85
|
+
while (n) {
|
|
86
|
+
if (set.has(n)) return true
|
|
87
|
+
n = n.parent
|
|
88
|
+
}
|
|
89
|
+
return false
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Replaces the source span of each topmost changed element with its fresh
|
|
93
|
+
// serialization, then proves the result by reparsing: the spliced text must
|
|
94
|
+
// render exactly like the mutated tree. Anything unprovable falls back to the
|
|
95
|
+
// whole-document render.
|
|
96
|
+
export function spliceDocument(load, src, $, tracker) {
|
|
97
|
+
const full = $.html()
|
|
98
|
+
const fallback = { html: full, spliced: false }
|
|
99
|
+
const docRoot = raw($.root())
|
|
100
|
+
const targets = new Set()
|
|
101
|
+
for (const r of tracker.dirty) {
|
|
102
|
+
if (!attached(r, docRoot)) continue
|
|
103
|
+
const at = located(r, tracker.cloned)
|
|
104
|
+
if (!at) return fallback
|
|
105
|
+
targets.add(at)
|
|
106
|
+
}
|
|
107
|
+
const top = [...targets].filter((r) => !hasAncestorIn(r, targets))
|
|
108
|
+
top.sort((a, b) => b.sourceCodeLocation.startOffset - a.sourceCodeLocation.startOffset)
|
|
109
|
+
let out = src
|
|
110
|
+
let prevStart = Infinity
|
|
111
|
+
for (const r of top) {
|
|
112
|
+
const { startOffset, endOffset } = r.sourceCodeLocation
|
|
113
|
+
if (endOffset > prevStart) return fallback
|
|
114
|
+
out = out.slice(0, startOffset) + $.html(r) + out.slice(endOffset)
|
|
115
|
+
prevStart = startOffset
|
|
116
|
+
}
|
|
117
|
+
return load(out).html() === full ? { html: out, spliced: true } : fallback
|
|
118
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ruleAttrIndex } from './rule-syntax.js'
|
|
2
|
+
|
|
3
|
+
function isPlainObject(v) {
|
|
4
|
+
return v !== null && typeof v === 'object' && !Array.isArray(v)
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function label(path) {
|
|
8
|
+
return path.reduce((out, part) => (typeof part === 'number' ? `${out}[${part}]` : out ? `${out}.${part}` : part), '')
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// Walks rules against data without touching the document. Reports data keys
|
|
12
|
+
// the rules do not define, and scalar rules whose selector matches nothing.
|
|
13
|
+
// Shape problems are left to apply(), which already reports them. Inside list
|
|
14
|
+
// items only unknown keys are checked, because new rows do not exist yet.
|
|
15
|
+
export function planWrite(adapter, root, rules, data, opts = {}) {
|
|
16
|
+
const unknownKeys = []
|
|
17
|
+
const unmatched = []
|
|
18
|
+
|
|
19
|
+
function checkKeys(rule, value, path) {
|
|
20
|
+
if (Array.isArray(rule)) {
|
|
21
|
+
const [, shape] = rule
|
|
22
|
+
if (!Array.isArray(value) || !isPlainObject(shape)) return
|
|
23
|
+
value.forEach((item, i) => checkKeys(shape, item, [...path, i]))
|
|
24
|
+
return
|
|
25
|
+
}
|
|
26
|
+
if (!isPlainObject(rule) || !isPlainObject(value)) return
|
|
27
|
+
for (const key of Object.keys(value)) {
|
|
28
|
+
if (!Object.prototype.hasOwnProperty.call(rule, key)) unknownKeys.push(label([...path, key]))
|
|
29
|
+
else checkKeys(rule[key], value[key], [...path, key])
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function checkTargets(ctx, rule, value, path) {
|
|
34
|
+
if (value === undefined) return
|
|
35
|
+
if (typeof rule === 'string') {
|
|
36
|
+
if (rule.endsWith('[]') || rule === '.' || rule.startsWith('@')) return
|
|
37
|
+
const at = ruleAttrIndex(rule)
|
|
38
|
+
const selector = at === -1 ? rule : rule.slice(0, at)
|
|
39
|
+
if (!selector) return
|
|
40
|
+
if (adapter.find(ctx, selector, opts).length === 0) unmatched.push({ path: label(path), selector })
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
if (Array.isArray(rule)) return
|
|
44
|
+
if (isPlainObject(rule) && isPlainObject(value)) {
|
|
45
|
+
for (const [key, sub] of Object.entries(rule)) checkTargets(ctx, sub, value[key], [...path, key])
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
checkKeys(rules, data, [])
|
|
50
|
+
checkTargets(root, rules, data, [])
|
|
51
|
+
return { unknownKeys, unmatched }
|
|
52
|
+
}
|