hyper-html-api 0.10.0 → 0.11.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/conformance/MANIFEST.json +1 -1
- package/conformance/cases/props-empty-attr-vs-empty-prop.expected.json +1 -1
- package/conformance/write-policy.json +2 -1
- package/dist/hyper-html-api.engine.esm.js +1 -0
- package/dist/hyper-html-api.engine.min.js +1 -1
- package/dist/hyper-html-api.min.js +8 -6
- package/dist/hyper-html-api.upgrade.min.js +2 -2
- package/package.json +6 -5
- package/src/adapters/cheerio.js +22 -2
- package/src/adapters/dom.js +91 -2
- package/src/cms/form-builder.js +1 -1
- package/src/cms/scaffold.js +71 -3
- package/src/engine/apply.js +7 -14
- package/src/engine/diff.js +221 -25
- package/src/engine/dom-properties.js +16 -0
- package/src/engine/errors.js +20 -2
- package/src/engine/extract.js +1 -1
- package/src/engine/index.js +1 -0
- package/src/engine/round-trip.js +171 -0
- package/src/engine/row-match.js +16 -10
- package/src/engine/rule-syntax.js +71 -0
- package/src/engine/splice.js +14 -0
- package/src/engine/write-policy.js +3 -0
- package/src/lib/content-dom.js +58 -28
- package/src/lib/region-capabilities.js +1 -0
- package/src/write.js +37 -5
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var hyperHtmlApiUpgrade=(()=>{var re=Object.defineProperty;var Ge=Object.getOwnPropertyDescriptor;var Xe=Object.getOwnPropertyNames;var Ze=Object.prototype.hasOwnProperty;var xe=(e,t)=>{for(var n in t)re(e,n,{get:t[n],enumerable:!0})},Qe=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of Xe(t))!Ze.call(e,r)&&r!==n&&re(e,r,{get:()=>t[r],enumerable:!(o=Ge(t,r))||o.enumerable});return e};var et=e=>Qe(re({},"__esModule",{value:!0}),e);var kt={};xe(kt,{default:()=>jt,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"],oe=new Set(J),Ee=new Set(["textContent","innerText","innerHTML","value","checked","selected","disabled","readOnly","type","id","className","title"]),Y=new Set(["tagName","nodeName","nodeType","nodeValue","childElementCount","classList","baseURI","documentURI","contentType","offsetWidth","offsetHeight","clientWidth","clientHeight","scrollWidth","scrollHeight","currentSrc","duration","paused","dataset"]);var X={};xe(X,{EmptyListInsert:()=>U,MAX_RULE_DEPTH:()=>D,MaxRuleDepthExceeded:()=>j,NoRulesTag:()=>ie,RuleTargetReadOnly:()=>H,RulesParseError:()=>_,ShapeMismatch:()=>W,UnknownRulesVersion:()=>I,WriteRefused:()=>G,WriteRejected:()=>se});var _=class extends Error{constructor(t,n){super(t),this.name="RulesParseError",this.cause=n}},I=class extends Error{constructor(t){super(`unknown rules version: ${t}. Library supports "1".`),this.name="UnknownRulesVersion",this.version=t}},D=20,j=class extends Error{constructor(t){super(`rule depth exceeded ${D} at path: ${t.join(".")}`),this.name="MaxRuleDepthExceeded",this.path=t}},W=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}},G=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,n){super(`write rejected: ${t.length} unknown key(s), ${n.length} rule(s) with no matching element`),this.name="WriteRejected",this.unknownKeys=t,this.unmatched=n}};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 ce(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 le(e,t,n,{depth:0,path:[]},o)}function le(e,t,n,o,r){if(o.depth>D)throw new j(o.path);if(typeof n=="string")return tt(e,t,n,o,r);if(Array.isArray(n)){let[i,l]=n,s=e.find(t,i,r);return be(r,o,s),s.map((c,a)=>le(e,c,l,{depth:o.depth+1,path:[...o.path,a]},r))}if(typeof n=="object"&&n!==null){let i={};for(let[l,s]of Object.entries(n))i[l]=le(e,t,s,{depth:o.depth+1,path:[...o.path,l]},r);return i}return null}function tt(e,t,n,o,r){if(n.endsWith("[]")){let s=n.slice(0,-2),c=e.find(t,s,r);return be(r,o,c),c.map(a=>e.text(a))}if(n.startsWith("@"))return Oe(e,t,n.slice(1));let i=N(n);if(i!==-1){let s=n.slice(0,i),c=n.slice(i+1),a=s?e.find(t,s,r):[t];return a.length===0?null:Oe(e,a[0],c)}if(n===".")return e.text(t);let l=e.find(t,n,r);return l.length===0?null:e.text(l[0])}function be(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 Oe(e,t,n){if(oe.has(n)){let r=e.prop(t,n);return r==null?null:String(r)}let o=e.attr(t,n);return o||null}function Ne(e,t,n,o){let r=e.length,i=t.length,l=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)||(l[p]=g,u.add(g))}}if(r===0||i===0)return l;let s=e.map(u=>Se(u,n)),c=t.map(u=>Se(u,n)),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<r;u++)l[u]<0&&d.push(u);let A=[];for(let u=0;u<i;u++)a[u]||A.push(u);if(d.length===0||A.length===0)return l;let h=r*i+1,m=(u,p)=>nt(e[u],t[p],n)*h+Math.abs(u-p);for(let[u,p]of rt(d,A,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 n=Object.keys(t);return JSON.stringify(n.map(o=>{let r=JSON.stringify(e?.[o]);return r===void 0?" undef":r}))}function nt(e,t,n){if(!Me(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 l=JSON.stringify(e?.[i]),s=JSON.stringify(t?.[i]);l!==s&&r++}return r}function rt(e,t,n){return e.length<=t.length?Re(e,t,n,!1):Re(t,e,(o,r)=>n(r,o),!0)}function Re(e,t,n,o){let r=e.length,i=t.length,l=[];for(let y=0;y<=r;y++)l.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++)l[r][y]=0;for(let y=r-1;y>=0;y--)for(let d=i-1;d>=0;d--){let A=n(e[y],t[d])+l[y+1][d+1],h=l[y][d+1];A<=h?(l[y][d]=A,s[y][d]=1):l[y][d]=h}let c=[],a=0,f=0;for(;a<r&&f<i;)s[a][f]&&(c.push(o?[t[f],e[a]]:[e[a],t[f]]),a++),f++;return c}function ue(e,t,n,o,r,i,l,s={}){let c=e.find(t,n,s);if(r.length===0){c.forEach(w=>e.remove(w)),fe(s,"onRowsApplied",i.path,[]);return}let a=r.length>c.length,f=c[0]||null;if(a&&!f&&(f=ct(e,t,n,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 A=Ne(r,y,o,ot(e,c,r,i,s)),h=c[0]||f,m=e.parent(h),u=c.length>0?Ce(e,m,h):0,p=lt(e,c),g=new Set,O=[],E=r.map((w,x)=>{let T=A[x];if(T>=0)return g.add(T),O.push(!1),c[T];O.push(!0);let R=e.clone(d);return e.stripIds(R),R});c.forEach((w,x)=>{g.has(x)||e.remove(w)}),p?E.forEach((w,x)=>{let T=u+x;e.children(m).findIndex(Ye=>e.sameNode(Ye,w))!==T&&e.insertAt(m,w,T)}):ft(e,E,O,m,u),it(e,E,o,r,i,l,s),fe(s,"onRowsApplied",i.path,E)}function fe(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 ot(e,t,n,o,r){let i=fe(r,"identifyRows",o.path,n);if(!Array.isArray(i))return null;let l=new Array(n.length).fill(-1),s=new Set;for(let c=0;c<n.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,n,o,r,i,l){t.forEach((s,c)=>{if(n===null){let a=o[c],f=a==null?"":String(a);e.text(s)!==f&&e.text(s,f)}else{let a=i(e,s,n,o[c],{depth:r.depth+1,path:[...r.path,c]},l);a&&a!==s&&(t[c]=a)}})}function st(e,t,n,o){return n===null?e.text(t):M(e,t,n,o.onRowsRead?{...o,onRowsRead:void 0}:o)}function Ce(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 ct(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 l of i)if(e.attr(l,o.templateAttr)!=null)return l;r=e.parent(r)}return null}function lt(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 l=o.findIndex(s=>e.sameNode(s,i));if(l===-1)return!1;r.push(l)}return r.sort((i,l)=>i-l),r[r.length-1]-r[0]===r.length-1}function ft(e,t,n,o,r){let i=null,l=r;for(let s=0;s<t.length;s++){if(!n[s]){i=t[s];continue}let c=i?e.parent(i):o;if(!c)continue;let a=i?Ce(e,c,i)+1:l++;e.insertAt(c,t[s],a),i=t[s]}}var Ie=new Set(["checked","selected","disabled","readOnly","paused"]);function k(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(ae(n,o,[],i),i.length)throw new W(i);Z(e,t,n,o,{depth:0,path:[]},r)}function Z(e,t,n,o,r,i={}){if(r.depth>D)throw new j(r.path);if(o===void 0)return t;if(typeof n=="string")return ut(e,t,n,o,r,i);if(Array.isArray(n)){let[l,s]=n;return ue(e,t,l,s,o,r,Z,i),t}if(typeof n=="object"&&n!==null){for(let[l,s]of Object.entries(n)){let c=Z(e,t,s,o==null?o:o[l],{depth:r.depth+1,path:[...r.path,l]},i);c&&c!==t&&(t=c)}return t}return t}function ut(e,t,n,o,r,i){if(n.endsWith("[]")){let c=n.slice(0,-2);return ue(e,t,c,null,o,r,Z,i),t}if(n.startsWith("@"))return ke(e,t,n.slice(1),o);let l=N(n);if(l!==-1){let c=n.slice(0,l),a=n.slice(l+1),f=c?e.find(t,c,i):[t];return f.length===0||ke(e,f[0],a,o),t}if(n===".")return je(e,t,o),t;let s=e.find(t,n,i);return s.length===0||je(e,s[0],o),t}function je(e,t,n){let o=n==null?"":String(n);e.text(t)!==o&&e.text(t,o)}function ke(e,t,n,o){if(Y.has(n)){let i=e.prop(t,n);if(i===o||i!=null&&o!=null&&String(i)===String(o))return t;throw new H(n)}if(n==="outerHTML"){let i=o==null?"":String(o);return e.replaceWith(t,i)}if(Ee.has(n)){let i=at(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 at(e,t){return t==null?Ie.has(e)?!1:"":Ie.has(e)?t==="false"?!1:!!t:t}function ae(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:v(r)})}):o.push({path:q(n),expected:"array",got:v(t)});return}t!==null&&typeof t=="object"&&o.push({path:q(n),expected:"scalar",got:v(t)});return}if(Array.isArray(e)){if(!Array.isArray(t)){o.push({path:q(n),expected:"array",got:v(t)});return}let r=e[1];t.forEach((i,l)=>ae(r,i,[...n,l],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:v(t)});return}for(let[r,i]of Object.entries(e))ae(i,t[r],[...n,r],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 _(`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=[],l=0;for(;l<r.length;){let s=r[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<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}),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<r.length&&r[d]!==y;)r[d]==="\\"&&d++,d++;i.push({type:t.STRING,value:r.substring(l+1,d),quoted:!0,sourceQuote:y}),l=d+1;continue}let c=l,a;for(;c<r.length&&!/[{},]/.test(r[c]);)if(r[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 A of y){let h=A.substring(1);if(r.substring(c+1,c+1+h.length)===h){d=!0,c+=h.length;break}}if(!d)break}else if(r[c]==="["){for(c++;c<r.length&&r[c]!=="]";){if(r[c]==='"'||r[c]==="'"){let y=r[c];for(c++;c<r.length&&r[c]!==y;)r[c]==="\\"&&c++,c++}c++}c<r.length&&r[c]==="]"&&c++}else c++;a=r.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(r){let i="";for(let l=0;l<r.length;l++){let s=r[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=r[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 r=n(e),i=o(r);return JSON.parse(i)}catch(r){throw new _("Invalid extraction rules syntax: "+r.message,r)}}var pe="1",Le=/^[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"||!Le.test(n))throw new Error(`hyper-html-api: invalid rules token ${JSON.stringify(n)} (must match ${Le})`);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],l=e.attr(i,"data-rules-version");if(l!==pe)throw new I(l);return{rules:L(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"])}),_e=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 n=e.getAttribute?.("clay");return!!(n&&n.split(/\s+/).includes(t)||e.hasAttribute?.(t))}function pt(e,t){if(he(e,t))return!0;for(let[n,o]of Object.entries(dt))if(o.includes(t)&&he(e,n))return!0;return!1}function K(e){let t=Pe[e];if(!t)throw new Error(`Unknown region capability: ${e}`);return[...t.tokens,...t.bundles].flatMap(n=>[`[clay~="${n}"]`,`[${n}]`]).join(", ")}function ht(e,t){let n=e&&e.nodeType===1?e:e?.parentElement;for(;n&&n.nodeType===1;){let o=Pe[t];if(!o)throw new Error(`Unknown region capability: ${t}`);if(o.tokens.some(r=>pt(n,r))||o.bundles.some(r=>he(n,r)))return n;n=n.parentElement}return null}function De(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",..._e],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,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 Tt=/:(?:focus(?:-within|-visible)?|hover|active|visited|defined)\b/i;function $e(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"&&n!=="file"&&(t.value=e.value),e.tagName==="INPUT"&&(n==="checkbox"||n==="radio")&&(t.checked=e.checked),e.tagName==="OPTION"&&(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 We(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 Ue(e,t,n,o,r,i,l,s){if(e.nodeType===1&&((l?De(e,n):We(e,o,i,!1))||r&&(l&&e!==i?e.matches(r):We(e,r,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,n,o,r,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: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(""),l=new WeakMap,s=new WeakMap,c=e.nodeType===9?e.documentElement:e;n&&i.documentElement.matches(n);let a=K(t),f=Ue(c,i,t,a,n,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(Tt.test(d))throw new Error(`Filtered content queries do not support stateful selector: ${d}`)};return{root:f,document:i,capability:t,selector:K(t),cloneToLive:l,liveToClone:s,original(d){return l.get(d)||null},cloneOf(d){return s.get(d)||null},query(d,A=f){return y(d),Array.from(A.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 A=d===f?f:s.get(d);return A?i.importNode(A,!0):null}}}function He(e){return e&&e.nodeType===1&&e.tagName==="SCRIPT"&&e.hasAttribute&&e.hasAttribute("data-rules-name")}function At(e){return e?(e.nodeType===9||e.nodeType===11,e):null}var b={semanticExclude:!0,find(e,t,n={}){let o=At(e);if(!o||!o.querySelectorAll)return[];let r=Array.from(o.querySelectorAll(t));n.includeRulesTag||(r=r.filter(s=>!He(s)));let i=[];n.skip&&i.push(n.skip);let l=n.templateAttr===null?null:n.templateAttr||"cms-template";if(l&&i.push("["+l+"]"),i.length){let s=i.join(", ");r=r.filter(c=>!c.closest||!c.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 z(e,t={}){if(t.exclude===null)return b;let n=[K("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,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(T=>s.cloneOf(T)),E=g[0];for(;E&&g.includes(E);)E=E.nextSibling;for(let T of g)T.remove();if(u==="innerHTML"){let T=l.createElement("template");T.innerHTML=p;for(let R of Array.from(T.content.childNodes))h.insertBefore(R,E||null)}else h.insertBefore(l.createTextNode(p),E||null);let w=F(h,{capability:"data",exclude:t.exclude||null});m.replaceChildren(...Array.from(w.root?.childNodes||[]));let x=T=>{let R=w.original(T);R&&(s.liveToClone.set(R,T),s.cloneToLive.set(T,R));for(let Ae of Array.from(T.childNodes||[]))x(Ae)};for(let T of Array.from(m.childNodes))x(T)},A={...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=>!He(w)));let O=[];u.skip&&O.push(u.skip);let E=u.templateAttr===null?null:u.templateAttr||"cms-template";if(E&&O.push(`[${E}]`),O.length){let w=O.join(", ");g=g.filter(x=>!x.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?.(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=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=A.children(p)[u]||(()=>{for(let x=p.children.length-1;x>=0;x--){let T=p.children[x];if(c().cloneOf(T))return T.nextElementSibling}return p.firstElementChild})(),E=f(m);p.insertBefore(E,O||null);let w=c().cloneOf(p);if(w){let x=c().cloneOf(E);x||(x=l.importNode(E,!0),y(E,x));let T=Array.from(w.children);w.insertBefore(x,T[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 E=w=>{let x=O.original(w);x&&(s.liveToClone.set(x,w),s.cloneToLive.set(w,x));for(let T of Array.from(w.childNodes||[]))E(T)};E(O.root)}}return g}};return A}var S=b;var ye={extract:(e,t,n={})=>M(z(e,n),e,t,n),apply:(e,t,n,o={})=>k(z(e,{...o,_write:!0}),e,t,n,o),findRulesIn:(e,t)=>B(S,e,t),findRules:(e,t)=>me(S,e,t),bind:(e,t,n={})=>{let o=me(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(z(e,n),e,o.rules,n),set:r=>k(z(e,{...n,_write:!0}),e,o.rules,r,n)}},parseStrict:de,parseRelaxed:L,ruleAttrIndex:N,splitRule:ce,errors:X,DOM_PROPERTIES:J};var xt="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 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 Et(e,t){let n=ve(e),o=ve(t);if(!n||!o)return!1;let r=Math.max(n.length,o.length);for(let i=0;i<r;i++){let l=n[i]||0,s=o[i]||0;if(l!==s)return l>s}return!1}function Ot(e){try{let t=globalThis.localStorage.getItem(e);return t?JSON.parse(t):null}catch{return null}}function bt(e,t){try{globalThis.localStorage.setItem(e,JSON.stringify(t))}catch{}}async function qe({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 l=C(t,"hyper-source");if(!l)return null;let s=C(t,"hyper-version"),c;try{c=new URL(l,n?n.href:void 0)}catch{return null}if(n&&c.origin===n.origin&&c.pathname===n.pathname)return null;let a=`${xt}${c.href}:${s||"none"}`,f,y=e?null:Ot(a);if(y&&typeof y.checkedAt=="number"&&r-y.checkedAt<i)f=y.sourceVersion;else{try{let d=await o(c.href);if(!d.ok)throw new Error(`HTTP ${d.status}`);let A=await d.text(),h=new DOMParser().parseFromString(A,"text/html");f=C(h,"hyper-version")}catch{f=null}bt(a,{checkedAt:r,sourceVersion:f})}return f?{available:Et(f,s||"0.0.0"),currentVersion:s,sourceVersion:f,sourceUrl:c.href}:null}var St="script[data-rules-name]";function Rt(e){return typeof e=="string"?e.trim().replace(/\s+/g," "):""}function Q(e,t){let n=e.find(t,St,{includeRulesTag:!0}),o=new Set,r=[];for(let i of n){let l=Rt(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 I(s);o.add(l),r.push({name:l,rules:L(e.text(i))})}return r}function ge(e,t){let n={};for(let{name:o,rules:r}of Q(e,t))n[o]=M(e,t,r);return n}function Be(e){let t=e||document,n=t.nodeType===9?t:t.ownerDocument||t;return{dataByName:ge(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}},ee=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,n){super(t),this.name="UpgradeTransformInvalid",this.cause=n}},te=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 Nt="text/hyper-upgrade";function Ke(e,t){let n=e.find(t,`script[type="${Nt}"]`);if(n.length===0)return null;if(n.length>1)throw new te(n.length);return e.text(n[0])||null}var Mt=new Function("url","return import(url)");async function Fe(e){let t=new Blob([e],{type:"text/javascript"}),n=URL.createObjectURL(t),o;try{o=await Mt(n)}catch(r){throw new P(`transform failed to load: ${r&&r.message?r.message:r}`,r)}finally{URL.revokeObjectURL(n)}if(typeof o.default!="function")throw new P("transform must `export default` a function");return o.default}function ne(e,t){let n={carriedOver:0,discarded:0,listItems:0},o=we(t,e,n);return Te(t,e,n),{data:o,summary:n}}function we(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=>we(o,r,n))):void 0}if(typeof e=="object"&&e!==null){let o={};for(let[r,i]of Object.entries(e)){let l=we(i,t?.[r],n);l!==void 0&&(o[r]=l)}return o}}function Te(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)?Te(e[r],t[r],n):n.discarded+=$(t[r]);return}if(Array.isArray(e)&&Array.isArray(t)){let o=e[1];t.forEach(r=>Te(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 ze(e,t,n){let o=Q(e,t),r={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(n,s)){i[s]={carriedOver:0,discarded:0,listItems:0};continue}let{data:a,summary:f}=ne(n[s],c);k(e,t,c,a),i[s]=f,r.carriedOver+=f.carriedOver,r.discarded+=f.discarded,r.listItems+=f.listItems}for(let s of Object.keys(n))l.has(s)||(r.discarded+=$(n[s]));return{totals:r,byName:i,rulesTagCount:o.length}}async function Ve({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 l=new URL(e,r?r.href:void 0);n=n!==void 0?n:C(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=C(a,"hyper-version"),y=t,d=!1,A=Ke(S,a);if(A){let g=await(await Fe(A))(y,{fromVersion:n,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}=ze(S,a,y);if(u===0&&Object.keys(y).length>0)throw new ee(l.href);return{html:Ct(a),fromVersion:n,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
|
|
1
|
+
var hyperHtmlApiUpgrade=(()=>{var ce=Object.defineProperty;var st=Object.getOwnPropertyDescriptor;var ct=Object.getOwnPropertyNames;var lt=Object.prototype.hasOwnProperty;var Re=(e,t)=>{for(var n in t)ce(e,n,{get:t[n],enumerable:!0})},ft=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of ct(t))!lt.call(e,r)&&r!==n&&ce(e,r,{get:()=>t[r],enumerable:!(o=st(t,r))||o.enumerable});return e};var ut=e=>ft(ce({},"__esModule",{value:!0}),e);var Xt={};Re(Xt,{default:()=>Gt,engine:()=>Ee,upgrade:()=>ot});var Y=["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"],G=new Set(Y),le=new Set(["textContent","innerText","innerHTML","value","checked","selected","disabled","readOnly","type","id","className","title"]),X=new Set(["tagName","nodeName","nodeType","nodeValue","childElementCount","classList","baseURI","documentURI","contentType","offsetWidth","offsetHeight","clientWidth","clientHeight","scrollWidth","scrollHeight","currentSrc","duration","paused","dataset"]),Ne=new Set(["checked","selected","disabled","readOnly","paused"]);function fe(e,t){return t==null?Ne.has(e)?!1:"":Ne.has(e)?t==="false"?!1:!!t:t}var ee={};Re(ee,{EmptyListInsert:()=>M,MAX_RULE_DEPTH:()=>D,MaxRuleDepthExceeded:()=>P,NoRulesTag:()=>ue,RuleTargetReadOnly:()=>v,RulesParseError:()=>_,ShapeMismatch:()=>U,UnknownRulesVersion:()=>k,WriteNotRoundTripped:()=>Q,WriteRefused:()=>Z,WriteRejected:()=>ae});var _=class extends Error{constructor(t,n){super(t),this.name="RulesParseError",this.cause=n}},k=class extends Error{constructor(t){super(`unknown rules version: ${t}. Library supports "1".`),this.name="UnknownRulesVersion",this.version=t}},D=20,P=class extends Error{constructor(t){super(`rule depth exceeded ${D} at path: ${t.join(".")}`),this.name="MaxRuleDepthExceeded",this.path=t}},U=class extends Error{constructor(t){super(`shape mismatch: ${t.length} field(s) failed validation`),this.name="ShapeMismatch",this.mismatches=t}},M=class extends Error{constructor(t,n){super(n?`cannot add items to empty list at "${t.join(".")}" \u2014 ${n}`:`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}},v=class extends Error{constructor(t){super(`cannot write to read-only DOM property "${t}"`),this.name="RuleTargetReadOnly",this.target=t}},Z=class extends Error{constructor(t){super(`write refused: ${t.length} write(s) broke the content-only policy`),this.name="WriteRefused",this.refusals=t}};function at(e){return e.reduce((n,o)=>typeof o=="number"?`${n}[${o}]`:n?`${n}.${o}`:String(o),"")||"(root)"}var Q=class extends Error{constructor(t){super(`write did not round-trip at "${at(t)}"`),this.name="WriteNotRoundTripped",this.path=t}},ue=class extends Error{constructor(t){super(`no <script data-rules-name~="${t}"> rules tag in this document`),this.name="NoRulesTag",this.token=t}},ae=class extends Error{constructor(t,n){super(`write rejected: ${t.length} unknown key(s), ${n.length} rule(s) with no matching element`),this.name="WriteRejected",this.unknownKeys=t,this.unmatched=n}};function S(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 de(e){let t=S(e);return t===-1?{selector:e,prop:null}:{selector:e.slice(0,t),prop:e.slice(t+1)||null}}function he(e){let t=0,n=null,o=-1,r=!1;for(let i=0;i<e.length;i++){let s=e[i];s==="\\"?i++:n?s===n&&(n=null):s==='"'||s==="'"?n=s:s==="["||s==="("?t++:s==="]"||s===")"?t>0&&t--:t===0&&s===">"?o=i:t===0&&s===","&&(r=!0)}return r||o===-1||!dt(e,o+1)?null:e.slice(0,o).trim()||null}function dt(e,t){let n=t,o=e.replace(/\s+$/,"").length;for(;n<o&&/\s/.test(e[n]);)n++;let r=0,i=null;for(;n<o;n++){let s=e[n];if(s==="\\")n++;else if(i)s===i&&(i=null);else if(s==='"'||s==="'")i=s;else if(s==="["||s==="(")r++;else if(s==="]"||s===")")r>0&&r--;else if(r===0&&(s==="+"||s==="~"||/\s/.test(s)))return!1}return!0}function N(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 pe(e,t,n,{depth:0,path:[]},o)}function pe(e,t,n,o,r){if(o.depth>D)throw new P(o.path);if(typeof n=="string")return ht(e,t,n,o,r);if(Array.isArray(n)){let[i,s]=n,c=e.find(t,i,r);return Me(r,o,c),c.map((l,d)=>pe(e,l,s,{depth:o.depth+1,path:[...o.path,d]},r))}if(typeof n=="object"&&n!==null){let i={};for(let[s,c]of Object.entries(n))i[s]=pe(e,t,c,{depth:o.depth+1,path:[...o.path,s]},r);return i}return null}function ht(e,t,n,o,r){if(n.endsWith("[]")){let c=n.slice(0,-2),l=e.find(t,c,r);return Me(r,o,l),l.map(d=>e.text(d))}if(n.startsWith("@"))return Ce(e,t,n.slice(1));let i=S(n);if(i!==-1){let c=n.slice(0,i),l=n.slice(i+1),d=c?e.find(t,c,r):[t];return d.length===0?null:Ce(e,d[0],l)}if(n===".")return e.text(t);let s=e.find(t,n,r);return s.length===0?null:e.text(s[0])}function Me(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 Ce(e,t,n){if(G.has(n)){let r=e.prop(t,n);return r==null?null:String(r)}let o=e.attr(t,n);return o??null}function Ie(e,t,n,o){let r=e.length,i=t.length,s=new Array(r).fill(-1);if(o){let u=new Set;for(let m=0;m<r;m++){let A=o[m];!(A>=0&&A<i)||u.has(A)||(s[m]=A,u.add(A))}}if(r===0||i===0)return s;let c=e.map(u=>ke(u,n)),l=t.map(u=>ke(u,n)),d=new Array(i).fill(!1);for(let u of s)u>=0&&(d[u]=!0);let a=new Map;l.forEach((u,m)=>{d[m]||a.set(u,a.has(u)?-1:m)});let g=new Map;c.forEach((u,m)=>{s[m]>=0||g.set(u,(g.get(u)||0)+1)}),c.forEach((u,m)=>{if(s[m]>=0||g.get(u)!==1)return;let A=a.get(u);A===void 0||A===-1||d[A]||(s[m]=A,d[A]=!0)});let p=[];for(let u=0;u<r;u++)s[u]<0&&p.push(u);let w=[];for(let u=0;u<i;u++)d[u]||w.push(u);if(p.length===0||w.length===0)return s;let f=r*i+1,h=pt(e,t,n),y=(u,m)=>h(u,m)*f+Math.abs(u-m);for(let[u,m]of mt(p,w,y))s[u]=m;return s}var Le=e=>typeof e=="object"&&e!==null;function ke(e,t){if(!Le(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 pt(e,t,n){if(!Le(n))return(c,l)=>e[c]===t[l]?0:1;let o=Object.keys(n),r=c=>o.map(l=>JSON.stringify(c?.[l])),i=e.map(r),s=t.map(r);return(c,l)=>{let d=i[c],a=s[l],g=0;for(let p=0;p<o.length;p++)d[p]!==a[p]&&g++;return g}}function mt(e,t,n){return e.length<=t.length?Pe(e,t,n,!1):Pe(t,e,(o,r)=>n(r,o),!0)}function Pe(e,t,n,o){let r=e.length,i=t.length,s=[];for(let g=0;g<=r;g++)s.push(new Float64Array(i+1).fill(1/0));let c=[];for(let g=0;g<=r;g++)c.push(new Uint8Array(i+1));for(let g=0;g<=i;g++)s[r][g]=0;for(let g=r-1;g>=0;g--)for(let p=i-1;p>=0;p--){let w=n(e[g],t[p])+s[g+1][p+1],f=s[g][p+1];w<=f?(s[g][p]=w,c[g][p]=1):s[g][p]=f}let l=[],d=0,a=0;for(;d<r&&a<i;)c[d][a]&&(l.push(o?[t[a],e[d]]:[e[d],t[a]]),d++),a++;return l}function ye(e,t,n,o,r,i,s,c={}){let l=e.find(t,n,c);if(r.length===0){l.forEach(T=>e.remove(T)),me(c,"onRowsApplied",i.path,[]);return}let d=r.length>l.length,a=l[0]||null;if(d&&!a&&(a=Tt(e,t,n,c),!a))throw new M(i.path);let g=l.map(T=>At(e,T,o,c)),p=null;if(d&&a){p=e.clone(a),c.templateAttr&&e.removeAttr(p,c.templateAttr);let T=e.stripIds(p);T>0&&console.warn(`[hyper-html-api] stripped ${T} id attribute(s) from cloned template at "${i.path.join(".")||"(root)"}"`)}let w=Ie(r,g,o,yt(e,l,r,i,c)),f=l.length>0?e.parent(l[0]):Ot(e,t,n,a,i,c),h=l.length>0?We(e,f,l[0]):0,y=Rt(e,l),u=new Set,m=[],A=r.map((T,b)=>{let E=w[b];if(E>=0)return u.add(E),m.push(!1),l[E];m.push(!0);let x=e.clone(p);return e.stripIds(x),x});l.forEach((T,b)=>{u.has(b)||e.remove(T)}),y?St(e,f,h,A,m):Nt(e,A,m,f,h),gt(e,A,o,r,i,s,c),me(c,"onRowsApplied",i.path,A)}function me(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 yt(e,t,n,o,r){let i=me(r,"identifyRows",o.path,n);if(!Array.isArray(i))return null;let s=new Array(n.length).fill(-1),c=new Set,l=new Map(t.map((d,a)=>[e.identity(d),a]));for(let d=0;d<n.length;d++){if(!i[d])continue;let a=l.get(e.identity(i[d]));a===void 0||c.has(a)||(s[d]=a,c.add(a))}return s}function gt(e,t,n,o,r,i,s){t.forEach((c,l)=>{if(n===null){let d=o[l],a=d==null?"":String(d);e.text(c)!==a&&e.text(c,a)}else{let d=i(e,c,n,o[l],{depth:r.depth+1,path:[...r.path,l]},s);d&&d!==c&&(t[l]=d)}})}function At(e,t,n,o){return n===null?e.text(t):N(e,t,n,o.onRowsRead?{...o,onRowsRead:void 0}:o)}function We(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 Tt(e,t,n,o){if(!o.templateAttr)return null;let r=/^\s*:scope\s*>\s*/.test(n),i=n.replace(/^\s*:scope\s*>\s*/,""),s=r?wt(i):0,c=he(i),l=t;for(;l;){let d=e.find(l,i,{includeRulesTag:!1,templateAttr:null});for(let a of d)if(e.attr(a,o.templateAttr)!=null&&!(r&&!Et(e,t,a,s))&&!(c&&!e.matches(e.parent(a),c)))return a;l=e.parent(l)}return null}function wt(e){let t=0,n=null,o=1;for(let r=0;r<e.length;r++){let i=e[r];if(i==="\\")r++;else if(n)i===n&&(n=null);else if(i==='"'||i==="'")n=i;else if(i==="["||i==="(")t++;else if(i==="]"||i===")")t>0&&t--;else if(t===0&&i===">")o++;else{if(t===0&&(i==="+"||i==="~"))return null;if(t===0&&/\s/.test(i)){if(!xt(e,r))return null;for(;r+1<e.length&&/\s/.test(e[r+1]);)r++}}}return o}function xt(e,t){let n=t;for(;n<e.length&&/\s/.test(e[n]);)n++;let o=t>0?e[t-1]:"",r=n<e.length?e[n]:"";return je(o)||je(r)}function je(e){return e===">"||e==="+"||e==="~"}function Et(e,t,n,o){if(o===null)return!0;let r=n;for(let l=0;l<o;l++)if(r=e.parent(r),!r)return!1;let i=e.prop(t,"tagName");if(!i)return!0;let s=e.prop(r,"tagName");if(!s||String(s).toLowerCase()!==String(i).toLowerCase())return!1;let c=new Set(_e(e,r));return _e(e,t).every(l=>c.has(l))}function _e(e,t){let n=e.attr(t,"class");return n?String(n).split(/\s+/).filter(Boolean):[]}function Ot(e,t,n,o,r,i){let s=e.parent(o);if(s&&bt(e,t,s)&&!$e(e,s,i))return s;let c=he(n);if(!c)throw new M(r.path,`the list selector "${n}" names no container to hold the new rows \u2014 write it as "container > row" (for example "ol.comments > li") so the cloned row lands in the list`);let d=(c===":scope"?e.prop(t,"tagName")?[t]:[]:e.find(t,c,i)).filter(a=>!$e(e,a,i));if(d.length===0)throw new M(r.path,`no container matching "${c}" inside this context to hold the new rows`);if(d.length>1)throw new M(r.path,`"${c}" matches ${d.length} containers inside this context, so the new rows have no single destination`);return d[0]}function bt(e,t,n){let o=n;for(;o;){if(e.sameNode(o,t))return!0;o=e.parent(o)}return e.parent(t)?!1:e.find(t,"*",{includeRulesTag:!0,templateAttr:null}).some(r=>e.sameNode(r,n))}var De=["no-data","editor-ui"];function $e(e,t,n){let o=t;for(;o;){if(n.templateAttr&&e.attr(o,n.templateAttr)!=null||De.some(i=>e.attr(o,i)!=null))return!0;let r=e.attr(o,"clay");if(r&&r.split(/\s+/).some(i=>De.includes(i)))return!0;o=e.parent(o)}return!1}function St(e,t,n,o,r){let i=e.children(t),s=i.map(l=>e.identity(l)),c=!1;o.forEach((l,d)=>{let a=e.identity(l),g=n+d;if(s[g]===a)return;if(!r[d]){let w=s.indexOf(a);w!==-1&&(s.splice(w,1),i.splice(w,1))}let p=Math.min(g,i.length);p<i.length?e.insertBefore(i[p],l):i.length?c?e.insertAfter(i[i.length-1],l):(e.insertAt(t,l,g),c=!0):e.insertAt(t,l,0),s.splice(p,0,a),i.splice(p,0,l)})}function Rt(e,t){if(t.length<=1)return!0;let n=e.parent(t[0]);if(!n)return!1;let o=new Map(e.children(n).map((i,s)=>[e.identity(i),s])),r=[];for(let i of t){let s=o.get(e.identity(i));if(s===void 0)return!1;r.push(s)}return r.sort((i,s)=>i-s),r[r.length-1]-r[0]===r.length-1}function Nt(e,t,n,o,r){let i=null,s=r;for(let c=0;c<t.length;c++){if(!n[c]){i=t[c];continue}let l=i?e.parent(i):o;if(!l)continue;let d=i?We(e,l,i)+1:s++;e.insertAt(l,t[c],d),i=t[c]}}function I(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(ge(n,o,[],i),i.length)throw new U(i);te(e,t,n,o,{depth:0,path:[]},r)}function te(e,t,n,o,r,i={}){if(r.depth>D)throw new P(r.path);if(o===void 0)return t;if(typeof n=="string")return Ct(e,t,n,o,r,i);if(Array.isArray(n)){let[s,c]=n;return ye(e,t,s,c,o,r,te,i),t}if(typeof n=="object"&&n!==null){for(let[s,c]of Object.entries(n)){let l=te(e,t,c,o==null?o:o[s],{depth:r.depth+1,path:[...r.path,s]},i);l&&l!==t&&(t=l)}return t}return t}function Ct(e,t,n,o,r,i){if(n.endsWith("[]")){let l=n.slice(0,-2);return ye(e,t,l,null,o,r,te,i),t}if(n.startsWith("@"))return ve(e,t,n.slice(1),o);let s=S(n);if(s!==-1){let l=n.slice(0,s),d=n.slice(s+1),a=l?e.find(t,l,i):[t];return a.length===0||ve(e,a[0],d,o),t}if(n===".")return Ue(e,t,o),t;let c=e.find(t,n,i);return c.length===0||Ue(e,c[0],o),t}function Ue(e,t,n){let o=n==null?"":String(n);e.text(t)!==o&&e.text(t,o)}function ve(e,t,n,o){if(X.has(n)){let r=e.prop(t,n);if(r===o||r!=null&&o!=null&&String(r)===String(o))return t;throw new v(n)}if(n==="outerHTML"){let r=o==null?"":String(o);return e.replaceWith(t,r)}if(le.has(n)){let r=fe(n,o);return e.prop(t,n)!==r&&e.prop(t,n,r),t}if(o==null)e.attr(t,n)!=null&&e.removeAttr(t,n);else{let r=String(o);e.attr(t,n)!==r&&e.attr(t,n,r)}return t}function ge(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:B([...n,i]),expected:"scalar",got:H(r)})}):o.push({path:B(n),expected:"array",got:H(t)});return}t!==null&&typeof t=="object"&&o.push({path:B(n),expected:"scalar",got:H(t)});return}if(Array.isArray(e)){if(!Array.isArray(t)){o.push({path:B(n),expected:"array",got:H(t)});return}let r=e[1];t.forEach((i,s)=>ge(r,i,[...n,s],o));return}if(typeof e=="object"&&e!==null){if(t===null||Array.isArray(t)||typeof t!="object"){o.push({path:B(n),expected:"object",got:H(t)});return}for(let[r,i]of Object.entries(e))ge(i,t[r],[...n,r],o)}}}function H(e){return e===null?"null":Array.isArray(e)?"array":typeof e}function B(e){return e.join(".")}function Ae(e){try{return JSON.parse(e)}catch(t){throw new _(`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=[],s=0;for(;s<r.length;){let c=r[s];if(/\s/.test(c)){s++;continue}if("{}".includes(c)){i.push({type:c,value:c}),s++;continue}if(c==="["){let g=!1,p=s+1;for(;p<r.length&&/\s/.test(r[p]);)p++;if(p<r.length&&/[a-zA-Z_]/.test(r[p])&&(g=!0),!g){i.push({type:c,value:c}),s++;continue}}if(c==="]"){i.push({type:c,value:c}),s++;continue}if(c===":"){i.push({type:t.COLON,value:c}),s++;continue}if(c===","){i.push({type:t.COMMA,value:c}),s++;continue}if(c==='"'||c==="'"){let g=c,p=s+1;for(;p<r.length&&r[p]!==g;)r[p]==="\\"&&p++,p++;i.push({type:t.STRING,value:r.substring(s+1,p),quoted:!0,sourceQuote:g}),s=p+1;continue}let l=s,d;for(;l<r.length&&!/[{},]/.test(r[l]);)if(r[l]===":"){let g=[":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"],p=!1;for(let w of g){let f=w.substring(1);if(r.substring(l+1,l+1+f.length)===f){p=!0,l+=f.length;break}}if(!p)break}else if(r[l]==="["){for(l++;l<r.length&&r[l]!=="]";){if(r[l]==='"'||r[l]==="'"){let g=r[l];for(l++;l<r.length&&r[l]!==g;)r[l]==="\\"&&l++,l++}l++}l<r.length&&r[l]==="]"&&l++}else l++;d=r.substring(s,l);let a=t.IDENTIFIER;/^-?\d+(\.\d+)?$/.test(d)?a=t.NUMBER:d==="true"||d==="false"||d==="null"?a=t.BOOLEAN:/^[.#@\[]|[.#@\[]| /.test(d)&&(a=t.SELECTOR),i.push({type:a,value:d,quoted:!1}),s=l}return i}function o(r){let i="";for(let s=0;s<r.length;s++){let c=r[s];if("{}".includes(c.type)||"[]".includes(c.type)){i+=c.value;continue}if(c.type===t.COLON){i+=c.value;continue}if(c.type===t.COMMA){let l=r[s+1];if(l&&(l.type==="}"||l.type==="]"))continue;i+=c.value;continue}if(c.type===t.STRING&&c.quoted){let l=c.value;c.sourceQuote==="'"&&(l=l.replace(/\\'/g,"'"),l=l.replace(/(\\*)"/g,(d,a)=>a.length%2===0?a+'\\"':d)),i+=`"${l}"`;continue}if(c.type===t.NUMBER||c.type===t.BOOLEAN){i+=c.value;continue}if(c.type===t.SELECTOR||c.type===t.IDENTIFIER){i+=`"${c.value}"`;continue}i+=`"${c.value}"`}return i}try{let r=n(e),i=o(r);return JSON.parse(i)}catch(r){throw new _("Invalid extraction rules syntax: "+r.message,r)}}var Te="1",He=/^[a-zA-Z0-9_-]+$/;function q(e,t,n){let o;if(n===void 0)o="script[data-rules-name]";else{if(typeof n!="string"||!He.test(n))throw new Error(`hyper-html-api: invalid rules token ${JSON.stringify(n)} (must match ${He})`);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],s=e.attr(i,"data-rules-version");if(s!==Te)throw new k(s);return{rules:L(e.text(i)),tagNode:i}}var ne=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"]})}),Mt=Object.freeze({"editor-ui":Object.freeze(["no-data","no-save","no-snapshot","no-watch","no-undo"])}),Be=Object.freeze(["no-save","no-snapshot","no-trigger-autosave","no-dirty","no-watch","no-undo","no-data","freeze","editor-ui","live"]);function K(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 we(e,t){if(K(e,t))return!0;for(let[n,o]of Object.entries(Mt))if(o.includes(t)&&K(e,n))return!0;return!1}function F(e){let t=ne[e];if(!t)throw new Error(`Unknown region capability: ${e}`);return[...t.tokens,...t.bundles].flatMap(n=>[`[clay~="${n}"]`,`[${n}]`]).join(", ")}function kt(e,t){let n=e&&e.nodeType===1?e:e?.parentElement;for(;n&&n.nodeType===1;){let o=ne[t];if(!o)throw new Error(`Unknown region capability: ${t}`);if(o.tokens.some(r=>we(n,r))||o.bundles.some(r=>K(n,r)))return n;n=n.parentElement}return null}function qe(e,t){return!!kt(e,t)}var Pt=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",...Be],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 xe(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 q(e,o,n)}return null}var _t=/:(?:focus(?:-within|-visible)?|hover|active|visited|defined)\b/i;function Dt(e,t){if(!/^(INPUT|TEXTAREA|SELECT|OPTION)$/.test(e.tagName||""))return;let n=(e.getAttribute?.("type")||"").toLowerCase();"value"in e&&"value"in t&&e.tagName!=="OPTION"&&n!=="checkbox"&&n!=="radio"&&n!=="file"&&(t.value=e.value),e.tagName==="INPUT"&&(n==="checkbox"||n==="radio")&&(t.checked=e.checked),e.tagName==="OPTION"&&(t.selected=e.selected),"indeterminate"in e&&"indeterminate"in t&&(t.indeterminate=e.indeterminate)}function Ke(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 Fe(e,t,n,o,r,i){return(i?qe(e,t):Ke(e,n,r,!1))||!!(o&&(i&&e!==r?e.matches(o):Ke(e,o,r,i)))}function $t(e,t){let n=ne[t];return n.tokens.some(o=>we(e,o))||n.bundles.some(o=>K(e,o))}var Wt=new Set(["INPUT","TEXTAREA","SELECT","OPTION"]);function ze(e,t,n,o){if(e.nodeType===1&&o(e)){n.dropped.push(t);return}n.cloneToLive.set(t,e),n.liveToClone.set(e,t);let r=e,i=t;if(e.nodeType===1){if(Wt.has(e.tagName)&&n.controls.push(e,t),e.tagName==="TEMPLATE"){for(;t.firstChild;)t.removeChild(t.firstChild);r=e.content,i=t.content,n.cloneToLive.set(i,r),n.liveToClone.set(r,i)}}else if(e.nodeType!==11)return;let s=i.firstChild;for(let c=r.firstChild;c&&s;c=c.nextSibling)ze(c,s,n,o),s=s.nextSibling}function z(e,{capability:t="data",exclude:n=null,inherit:o=!0,provenance:r=null}={}){if(!e)throw new TypeError("createContentView requires a DOM context");let i=e.nodeType===9?e:e.ownerDocument;if(!i?.implementation?.createHTMLDocument)throw new TypeError("createContentView requires an HTML DOM implementation");let s=i.implementation.createHTMLDocument(""),c=r||new WeakMap,l=new WeakMap,d=e.nodeType===9?e.documentElement:e;n&&s.documentElement.matches(n);let a=F(t),g=o?f=>$t(f,t)||!!(n&&f.matches(n)):f=>Fe(f,t,a,n,d,!1),p=null;if(d.nodeType!==1||!Fe(d,t,a,n,d,o)){p=s.importNode(d,!0);let f={cloneToLive:c,liveToClone:l,dropped:[],controls:[]};ze(d,p,f,g);for(let h of f.dropped)h.remove();for(let h=0;h<f.controls.length;h+=2)Dt(f.controls[h],f.controls[h+1])}e.nodeType===9&&p&&(s.replaceChild(p,s.documentElement),l.set(e,s),c.set(s,e));let w=f=>{if(_t.test(f))throw new Error(`Filtered content queries do not support stateful selector: ${f}`)};return{root:p,document:s,capability:t,selector:F(t),cloneToLive:c,liveToClone:l,original(f){return c.get(f)||null},cloneOf(f){return l.get(f)||null},query(f,h=p){return w(f),Array.from(h.querySelectorAll(f),y=>c.get(y)||y)},text(f=p){return(f===p?p:l.get(f))?.textContent||""},html(f=p){return(f===p?p:l.get(f))?.innerHTML??""},clone(f=p){let h=f===p?p:l.get(f);return h?s.importNode(h,!0):null}}}function Je(e){return e&&e.nodeType===1&&e.tagName==="SCRIPT"&&e.hasAttribute&&e.hasAttribute("data-rules-name")}function Ut(e){return e?(e.nodeType===9||e.nodeType===11,e):null}function Ve(e,t,n){!e||e.nodeType!==1||(t==="value"&&e.tagName==="INPUT"?e.value=n===null?"":n:t==="checked"&&e.tagName==="INPUT"?e.checked=n!==null:t==="selected"&&e.tagName==="OPTION"&&(e.selected=n!==null))}function Ye(e,t){e&&e.tagName==="TEXTAREA"&&(e.value=t)}function Ge(e){if(!e||e.nodeType!==1)return;let t=[e,...e.querySelectorAll?e.querySelectorAll("textarea, input, option"):[]];for(let n of t)if(n.tagName==="TEXTAREA")n.value=n.defaultValue;else if(n.tagName==="INPUT"){let o=n.type;o!=="file"&&o!=="checkbox"&&o!=="radio"&&(n.value=n.defaultValue),n.checked=n.defaultChecked}else n.tagName==="OPTION"&&(n.selected=n.defaultSelected)}var O={semanticExclude:!0,find(e,t,n={}){let o=Ut(e);if(!o||!o.querySelectorAll)return[];let r=Array.from(o.querySelectorAll(t));n.includeRulesTag||(r=r.filter(c=>!Je(c)));let i=[];n.skip&&i.push(n.skip);let s=n.templateAttr===null?null:n.templateAttr||"cms-template";if(s&&i.push("["+s+"]"),i.length){let c=i.join(", ");r=r.filter(l=>!l.closest||!l.closest(c))}return r},parent(e){return e?e.parentElement:null},children(e){return e?Array.from(e.children):[]},matches(e,t){return!!(e&&e.matches)&&e.matches(t)},text(e,t){if(t===void 0)return(e.textContent||"").trim();e.textContent=t,Ye(e,t)},attr(e,t,n){if(n===void 0)return e.hasAttribute&&e.hasAttribute(t)?e.getAttribute(t):null;e.setAttribute(t,n),Ve(e,t,n)},removeAttr(e,t){e&&e.removeAttribute&&e.removeAttribute(t),Ve(e,t,null)},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){let t=e.cloneNode(!0);return Ge(t),t},insertAt(e,t,n){let o=e.children[n]||null;e.insertBefore(t,o)},insertBefore(e,t){e.parentNode.insertBefore(t,e)},insertAfter(e,t){e.parentNode.insertBefore(t,e.nextSibling)},identity(e){return e||null},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 V(e,t={}){if(t.exclude===null)return O;let n=[F("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 O;let i=e.nodeType===9||!e.isConnected?e:e.ownerDocument,s=e.nodeType===9?e:e.ownerDocument,c=null,l=()=>c||(c=z(i,{capability:"data",exclude:t.exclude||null})),d=f=>{let h=l();return f===e?h.cloneOf(e):h.cloneOf(f)||f},a=f=>c?.original(f)||f,g=(f,h)=>{l().liveToClone.set(f,h),l().cloneToLive.set(h,f);let y=f.childNodes||[],u=h.childNodes||[];for(let m=0;m<Math.min(y.length,u.length);m++)g(y[m],u[m])},p=(f,h,y,u)=>{let m=Array.from(f.childNodes).filter(x=>c.cloneOf(x)),T=m[0];for(;T&&m.includes(T);)T=T.nextSibling;for(let x of m)x.remove();if(y==="innerHTML"){let x=s.createElement("template");x.innerHTML=u;for(let W of Array.from(x.content.childNodes))f.insertBefore(W,T||null)}else f.insertBefore(s.createTextNode(u),T||null),Ye(f,u);let b=z(f,{capability:"data",exclude:t.exclude||null});h.replaceChildren(...Array.from(b.root?.childNodes||[]));let E=x=>{let W=b.original(x);W&&(c.liveToClone.set(W,x),c.cloneToLive.set(x,W));for(let it of Array.from(x.childNodes||[]))E(it)};for(let x of Array.from(h.childNodes))E(x)},w={...O,find(f,h,y={}){let u=d(f);if(!u?.querySelectorAll)return[];let m=l().query(h,u);y.includeRulesTag||(m=m.filter(b=>!Je(b)));let A=[];y.skip&&A.push(y.skip);let T=y.templateAttr===null?null:y.templateAttr||"cms-template";if(T&&A.push(`[${T}]`),A.length){let b=A.join(", ");m=m.filter(E=>!E.closest?.(b))}return m},parent(f){let h=d(f)?.parentElement;return h?a(h):null},children(f){return Array.from(d(f)?.children||[],a)},text(f,h){if(h===void 0){let m=a(f);return!m?.matches?.(n)&&!m?.querySelector?.(n)?O.text(m):(d(f)?.textContent||"").trim()}let y=a(f);if(!y?.matches?.(n)&&!y?.querySelector?.(n)&&!c){O.text(y,h);return}let u=l().cloneOf(y);u?p(y,u,"textContent",h):O.text(y,h)},attr(f,h,y){let u=a(f);if(y===void 0)return O.attr(u,h);O.attr(u,h,y);let m=c?.cloneOf(u);m&&(O.attr(m,h,y),z(u,{capability:"data",exclude:t.exclude||null}).root===null&&(m.remove(),c.liveToClone.delete(u),c.cloneToLive.delete(m)))},removeAttr(f,h){let y=a(f);O.removeAttr(y,h);let u=c?.cloneOf(y);u&&O.removeAttr(u,h)},prop(f,h,y){let u=a(f);if(y===void 0)return h==="innerHTML"||h==="outerHTML"||h==="textContent"||h==="innerText"?O.prop(d(u),h):O.prop(u,h);let m=h==="innerHTML"||h==="textContent"||h==="innerText",A=m?l().cloneOf(u):c?.cloneOf(u);A&&m?p(u,A,h,y):(O.prop(u,h,y),A&&O.prop(A,h,y))},clone(f){let h=d(f);if(h===f)return O.clone(f);let y=s.importNode(h,!0);return Ge(y),y},insertAt(f,h,y){let u=a(f),A=w.children(u)[y]||(()=>{for(let E=u.children.length-1;E>=0;E--){let x=u.children[E];if(l().cloneOf(x))return x.nextElementSibling}return u.firstElementChild})(),T=a(h);u.insertBefore(T,A||null);let b=l().cloneOf(u);if(b){let E=l().cloneOf(T);E||(E=s.importNode(T,!0),g(T,E));let x=Array.from(b.children);b.insertBefore(E,x[y]||null)}},insertBefore(f,h){let y=a(f),u=a(h);y.parentNode.insertBefore(u,y);let m=l().cloneOf(y.parentNode);if(m){let A=l().cloneOf(u);A||(A=s.importNode(u,!0),g(u,A));let T=l().cloneOf(y);T?T.before(A):m.appendChild(A)}},insertAfter(f,h){let y=a(f),u=a(h);y.parentNode.insertBefore(u,y.nextSibling);let m=l().cloneOf(y.parentNode);if(m){let A=l().cloneOf(u);A||(A=s.importNode(u,!0),g(u,A));let T=l().cloneOf(y);T?T.after(A):m.appendChild(A)}},identity(f){return a(f)||null},remove(f){let h=a(f),y=l().cloneOf(h);O.remove(h),y&&O.remove(y)},replaceWith(f,h){let y=a(f),u=l().cloneOf(y),m=O.replaceWith(y,h);if(u){let A=z(m,{capability:"data",exclude:t.exclude||null});if(!A.root)u.remove();else{u.replaceWith(A.root);let T=b=>{let E=A.original(b);E&&(c.liveToClone.set(E,b),c.cloneToLive.set(b,E));for(let x of Array.from(b.childNodes||[]))T(x)};T(A.root)}}return m}};return w}var R=O;var Ee={extract:(e,t,n={})=>N(V(e,n),e,t,n),apply:(e,t,n,o={})=>I(V(e,{...o,_write:!0}),e,t,n,o),findRulesIn:(e,t)=>q(R,e,t),findRules:(e,t)=>xe(R,e,t),bind:(e,t,n={})=>{let o=xe(R,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:()=>N(V(e,n),e,o.rules,n),set:r=>I(V(e,{...n,_write:!0}),e,o.rules,r,n)}},parseStrict:Ae,parseRelaxed:L,ruleAttrIndex:S,splitRule:de,errors:ee,DOM_PROPERTIES:Y};var vt="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 Xe(e){if(typeof e!="string")return null;let t=e.trim().replace(/^v/,"");return/^\d+(\.\d+)*$/.test(t)?t.split(".").map(Number):null}function Ht(e,t){let n=Xe(e),o=Xe(t);if(!n||!o)return!1;let r=Math.max(n.length,o.length);for(let i=0;i<r;i++){let s=n[i]||0,c=o[i]||0;if(s!==c)return s>c}return!1}function Bt(e){try{let t=globalThis.localStorage.getItem(e);return t?JSON.parse(t):null}catch{return null}}function qt(e,t){try{globalThis.localStorage.setItem(e,JSON.stringify(t))}catch{}}async function Ze({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||(p=>fetch(p)),r=r??Date.now(),!t)return null;let s=C(t,"hyper-source");if(!s)return null;let c=C(t,"hyper-version"),l;try{l=new URL(s,n?n.href:void 0)}catch{return null}if(n&&l.origin===n.origin&&l.pathname===n.pathname)return null;let d=`${vt}${l.href}:${c||"none"}`,a,g=e?null:Bt(d);if(g&&typeof g.checkedAt=="number"&&r-g.checkedAt<i)a=g.sourceVersion;else{try{let p=await o(l.href);if(!p.ok)throw new Error(`HTTP ${p.status}`);let w=await p.text(),f=new DOMParser().parseFromString(w,"text/html");a=C(f,"hyper-version")}catch{a=null}qt(d,{checkedAt:r,sourceVersion:a})}return a?{available:Ht(a,c||"0.0.0"),currentVersion:c,sourceVersion:a,sourceUrl:l.href}:null}var Kt="script[data-rules-name]";function Ft(e){return typeof e=="string"?e.trim().replace(/\s+/g," "):""}function re(e,t){let n=e.find(t,Kt,{includeRulesTag:!0}),o=new Set,r=[];for(let i of n){let s=Ft(e.attr(i,"data-rules-name"));if(!s)continue;if(o.has(s)){console.warn(`hyper-html-api: duplicate rules tag name "${s}"; using the first.`);continue}let c=e.attr(i,"data-rules-version");if(c!==Te)throw new k(c);o.add(s),r.push({name:s,rules:L(e.text(i))})}return r}function Oe(e,t){let n={};for(let{name:o,rules:r}of re(e,t))n[o]=N(e,t,r);return n}function Qe(e){let t=e||document,n=t.nodeType===9?t:t.ownerDocument||t;return{dataByName:Oe(R,t),version:C(n,"hyper-version")}}var J=class extends Error{constructor(t,n){super(`could not fetch upgrade source: ${t}`),this.name="UpgradeSourceUnreachable",this.sourceUrl=t,this.cause=n}},oe=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}},j=class extends Error{constructor(t,n){super(t),this.name="UpgradeTransformInvalid",this.cause=n}},ie=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 zt="text/hyper-upgrade";function et(e,t){let n=e.find(t,`script[type="${zt}"]`);if(n.length===0)return null;if(n.length>1)throw new ie(n.length);return e.text(n[0])||null}var Vt=new Function("url","return import(url)");async function tt(e){let t=new Blob([e],{type:"text/javascript"}),n=URL.createObjectURL(t),o;try{o=await Vt(n)}catch(r){throw new j(`transform failed to load: ${r&&r.message?r.message:r}`,r)}finally{URL.revokeObjectURL(n)}if(typeof o.default!="function")throw new j("transform must `export default` a function");return o.default}function se(e,t){let n={carriedOver:0,discarded:0,listItems:0},o=be(t,e,n);return Se(t,e,n),{data:o,summary:n}}function be(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=>be(o,r,n))):void 0}if(typeof e=="object"&&e!==null){let o={};for(let[r,i]of Object.entries(e)){let s=be(i,t?.[r],n);s!==void 0&&(o[r]=s)}return o}}function Se(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)?Se(e[r],t[r],n):n.discarded+=$(t[r]);return}if(Array.isArray(e)&&Array.isArray(t)){let o=e[1];t.forEach(r=>Se(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 nt(e,t,n){let o=re(e,t),r={carriedOver:0,discarded:0,listItems:0},i={},s=new Set;for(let{name:c,rules:l}of o){if(s.add(c),!Object.prototype.hasOwnProperty.call(n,c)){i[c]={carriedOver:0,discarded:0,listItems:0};continue}let{data:d,summary:a}=se(n[c],l);I(e,t,l,d),i[c]=a,r.carriedOver+=a.carriedOver,r.discarded+=a.discarded,r.listItems+=a.listItems}for(let c of Object.keys(n))s.has(c)||(r.discarded+=$(n[c]));return{totals:r,byName:i,rulesTagCount:o.length}}async function rt({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||(u=>fetch(u)),!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 s=new URL(e,r?r.href:void 0);n=n!==void 0?n:C(o,"hyper-version"),t=t||Oe(R,o);let c;try{c=await i(s.href)}catch(u){throw new J(s.href,u)}if(!c.ok)throw new J(s.href,new Error(`HTTP ${c.status}`));let l=await c.text(),d=new DOMParser().parseFromString(l,"text/html"),a=C(d,"hyper-version"),g=t,p=!1,w=et(R,d);if(w){let m=await(await tt(w))(g,{fromVersion:n,toVersion:a});if(!m||typeof m!="object"||Array.isArray(m))throw new j("transform must return a plain object map of { rulesName: data }");g=m,p=!0}let{totals:f,byName:h,rulesTagCount:y}=nt(R,d,g);if(y===0&&Object.keys(g).length>0)throw new oe(s.href);return{html:Jt(d),fromVersion:n,toVersion:a,summary:{transformApplied:p,totals:f,byName:h}}}function Jt(e){return`<!DOCTYPE ${e.doctype&&e.doctype.name?e.doctype.name:"html"}>
|
|
2
|
+
`+e.documentElement.outerHTML}var ot={checkForUpdate:Ze,run:rt,extractAll:Qe,shapeMatch:se};var Yt={engine:Ee,upgrade:ot},Gt=Yt;return ut(Xt);})();
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"apply",
|
|
10
10
|
"CMS"
|
|
11
11
|
],
|
|
12
|
-
"version": "0.
|
|
12
|
+
"version": "0.11.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"
|
|
@@ -37,12 +37,13 @@
|
|
|
37
37
|
"./write": "./src/write.js"
|
|
38
38
|
},
|
|
39
39
|
"scripts": {
|
|
40
|
-
"build": "npx esbuild src/hyper-html-api.js --bundle --minify --format=iife --global-name=HyperHtmlApi --outfile=dist/hyper-html-api.min.js",
|
|
40
|
+
"build": "npx esbuild src/hyper-html-api.js --bundle --minify --format=iife --global-name=HyperHtmlApi --outfile=dist/hyper-html-api.min.js && npm run build:engine && npm run build:engine:esm",
|
|
41
41
|
"build:engine": "npx esbuild src/data.js --bundle --minify --format=iife --global-name=hyperHtmlApiData --outfile=dist/hyper-html-api.engine.min.js",
|
|
42
|
+
"build:engine:esm": "npx esbuild src/data.js --bundle --minify --format=esm --outfile=dist/hyper-html-api.engine.esm.js",
|
|
42
43
|
"build:upgrade": "npx esbuild src/upgrade.js --bundle --minify --format=iife --global-name=hyperHtmlApiUpgrade --outfile=dist/hyper-html-api.upgrade.min.js",
|
|
43
44
|
"copy-to-hyperclayjs": "npm run build:engine && npm run build:upgrade && node scripts/copy-to-hyperclayjs.js",
|
|
44
|
-
"copy-to-clayjs": "npm run build:engine && node scripts/copy-to-clayjs.js",
|
|
45
|
-
"prepublishOnly": "npm run build && npm run build:
|
|
45
|
+
"copy-to-clayjs": "npm run build:engine && npm run build:engine:esm && node scripts/copy-to-clayjs.js",
|
|
46
|
+
"prepublishOnly": "npm run build && npm run build:upgrade",
|
|
46
47
|
"demo": "http-server . -p 5693 -c-1 -o /demo/",
|
|
47
48
|
"test": "web-test-runner",
|
|
48
49
|
"test:debug": "web-test-runner --manual --open",
|
|
@@ -63,7 +64,7 @@
|
|
|
63
64
|
"url": "git+https://github.com/panphora/hyper-html-api.git"
|
|
64
65
|
},
|
|
65
66
|
"dependencies": {
|
|
66
|
-
"hyper-morph": "^1.3
|
|
67
|
+
"hyper-morph": "^1.6.3"
|
|
67
68
|
},
|
|
68
69
|
"devDependencies": {
|
|
69
70
|
"@web/test-runner": "^0.20.0",
|
package/src/adapters/cheerio.js
CHANGED
|
@@ -103,6 +103,10 @@ const cheerioAdapter = {
|
|
|
103
103
|
return p && p.length ? p : null
|
|
104
104
|
},
|
|
105
105
|
|
|
106
|
+
matches(node, selector) {
|
|
107
|
+
return !!node && node.length > 0 && isElement(node) && node.is(selector)
|
|
108
|
+
},
|
|
109
|
+
|
|
106
110
|
children(node) {
|
|
107
111
|
if (!node || !node.children) return []
|
|
108
112
|
const kids = node.children()
|
|
@@ -128,8 +132,12 @@ const cheerioAdapter = {
|
|
|
128
132
|
|
|
129
133
|
attr(node, name, value) {
|
|
130
134
|
if (value === undefined) {
|
|
131
|
-
|
|
132
|
-
|
|
135
|
+
// Read the raw attribs map rather than .attr(): cheerio's getter returns
|
|
136
|
+
// the attribute NAME for HTML boolean attributes (hidden, open, required,
|
|
137
|
+
// multiple, autofocus...), which is not what the DOM adapter reports.
|
|
138
|
+
const attribs = node[0] && node[0].attribs
|
|
139
|
+
if (!attribs || !Object.prototype.hasOwnProperty.call(attribs, name)) return null
|
|
140
|
+
return attribs[name]
|
|
133
141
|
}
|
|
134
142
|
node.attr(name, value)
|
|
135
143
|
},
|
|
@@ -207,6 +215,18 @@ const cheerioAdapter = {
|
|
|
207
215
|
else parent.append(node)
|
|
208
216
|
},
|
|
209
217
|
|
|
218
|
+
insertBefore(ref, node) {
|
|
219
|
+
ref.before(node)
|
|
220
|
+
},
|
|
221
|
+
|
|
222
|
+
insertAfter(ref, node) {
|
|
223
|
+
ref.after(node)
|
|
224
|
+
},
|
|
225
|
+
|
|
226
|
+
identity(node) {
|
|
227
|
+
return node && node[0] ? node[0] : null
|
|
228
|
+
},
|
|
229
|
+
|
|
210
230
|
remove(node) {
|
|
211
231
|
if (node) node.remove()
|
|
212
232
|
},
|
package/src/adapters/dom.js
CHANGED
|
@@ -13,6 +13,35 @@ function resolveSearchRoot(ctx) {
|
|
|
13
13
|
return ctx
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
function mirrorLiveState(node, name, value) {
|
|
17
|
+
if (!node || node.nodeType !== 1) return
|
|
18
|
+
if (name === 'value' && node.tagName === 'INPUT') node.value = value === null ? '' : value
|
|
19
|
+
else if (name === 'checked' && node.tagName === 'INPUT') node.checked = value !== null
|
|
20
|
+
else if (name === 'selected' && node.tagName === 'OPTION') node.selected = value !== null
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function syncTextareaValue(node, value) {
|
|
24
|
+
if (node && node.tagName === 'TEXTAREA') node.value = value
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function resetFormState(node) {
|
|
28
|
+
if (!node || node.nodeType !== 1) return
|
|
29
|
+
const controls = [node, ...(node.querySelectorAll ? node.querySelectorAll('textarea, input, option') : [])]
|
|
30
|
+
for (const control of controls) {
|
|
31
|
+
if (control.tagName === 'TEXTAREA') {
|
|
32
|
+
control.value = control.defaultValue
|
|
33
|
+
} else if (control.tagName === 'INPUT') {
|
|
34
|
+
const type = control.type
|
|
35
|
+
// A checkbox or radio has no value content attribute by default, and
|
|
36
|
+
// assigning one writes the attribute: the clone would carry value="".
|
|
37
|
+
if (type !== 'file' && type !== 'checkbox' && type !== 'radio') control.value = control.defaultValue
|
|
38
|
+
control.checked = control.defaultChecked
|
|
39
|
+
} else if (control.tagName === 'OPTION') {
|
|
40
|
+
control.selected = control.defaultSelected
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
16
45
|
const dom = {
|
|
17
46
|
semanticExclude: true,
|
|
18
47
|
find(ctx, selector, opts = {}) {
|
|
@@ -43,9 +72,14 @@ const dom = {
|
|
|
43
72
|
return node ? Array.from(node.children) : []
|
|
44
73
|
},
|
|
45
74
|
|
|
75
|
+
matches(node, selector) {
|
|
76
|
+
return !!(node && node.matches) && node.matches(selector)
|
|
77
|
+
},
|
|
78
|
+
|
|
46
79
|
text(node, value) {
|
|
47
80
|
if (value === undefined) return (node.textContent || '').trim()
|
|
48
81
|
node.textContent = value
|
|
82
|
+
syncTextareaValue(node, value)
|
|
49
83
|
},
|
|
50
84
|
|
|
51
85
|
attr(node, name, value) {
|
|
@@ -53,10 +87,12 @@ const dom = {
|
|
|
53
87
|
return node.hasAttribute && node.hasAttribute(name) ? node.getAttribute(name) : null
|
|
54
88
|
}
|
|
55
89
|
node.setAttribute(name, value)
|
|
90
|
+
mirrorLiveState(node, name, value)
|
|
56
91
|
},
|
|
57
92
|
|
|
58
93
|
removeAttr(node, name) {
|
|
59
94
|
if (node && node.removeAttribute) node.removeAttribute(name)
|
|
95
|
+
mirrorLiveState(node, name, null)
|
|
60
96
|
},
|
|
61
97
|
|
|
62
98
|
prop(node, name, value) {
|
|
@@ -68,7 +104,9 @@ const dom = {
|
|
|
68
104
|
},
|
|
69
105
|
|
|
70
106
|
clone(node) {
|
|
71
|
-
|
|
107
|
+
const copy = node.cloneNode(true)
|
|
108
|
+
resetFormState(copy)
|
|
109
|
+
return copy
|
|
72
110
|
},
|
|
73
111
|
|
|
74
112
|
insertAt(parent, node, index) {
|
|
@@ -76,6 +114,18 @@ const dom = {
|
|
|
76
114
|
parent.insertBefore(node, ref)
|
|
77
115
|
},
|
|
78
116
|
|
|
117
|
+
insertBefore(ref, node) {
|
|
118
|
+
ref.parentNode.insertBefore(node, ref)
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
insertAfter(ref, node) {
|
|
122
|
+
ref.parentNode.insertBefore(node, ref.nextSibling)
|
|
123
|
+
},
|
|
124
|
+
|
|
125
|
+
identity(node) {
|
|
126
|
+
return node || null
|
|
127
|
+
},
|
|
128
|
+
|
|
79
129
|
remove(node) {
|
|
80
130
|
if (node && node.parentNode) node.parentNode.removeChild(node)
|
|
81
131
|
},
|
|
@@ -151,6 +201,7 @@ export function createDomAdapter(operationRoot, opts = {}) {
|
|
|
151
201
|
for (const child of Array.from(template.content.childNodes)) target.insertBefore(child, anchor || null)
|
|
152
202
|
} else {
|
|
153
203
|
target.insertBefore(outputDocument.createTextNode(value), anchor || null)
|
|
204
|
+
syncTextareaValue(target, value)
|
|
154
205
|
}
|
|
155
206
|
const filteredView = createContentView(target, { capability: 'data', exclude: opts.exclude || null })
|
|
156
207
|
copy.replaceChildren(...Array.from(filteredView.root?.childNodes || []))
|
|
@@ -243,7 +294,10 @@ export function createDomAdapter(operationRoot, opts = {}) {
|
|
|
243
294
|
},
|
|
244
295
|
clone(node) {
|
|
245
296
|
const copy = projected(node)
|
|
246
|
-
|
|
297
|
+
if (copy === node) return dom.clone(node)
|
|
298
|
+
const clone = outputDocument.importNode(copy, true)
|
|
299
|
+
resetFormState(clone)
|
|
300
|
+
return clone
|
|
247
301
|
},
|
|
248
302
|
insertAt(parent, node, index) {
|
|
249
303
|
const targetParent = live(parent)
|
|
@@ -268,6 +322,41 @@ export function createDomAdapter(operationRoot, opts = {}) {
|
|
|
268
322
|
parentCopy.insertBefore(nodeCopy, copyContentChildren[index] || null)
|
|
269
323
|
}
|
|
270
324
|
},
|
|
325
|
+
insertBefore(ref, node) {
|
|
326
|
+
const targetRef = live(ref)
|
|
327
|
+
const targetNode = live(node)
|
|
328
|
+
targetRef.parentNode.insertBefore(targetNode, targetRef)
|
|
329
|
+
const parentCopy = contentView().cloneOf(targetRef.parentNode)
|
|
330
|
+
if (parentCopy) {
|
|
331
|
+
let nodeCopy = contentView().cloneOf(targetNode)
|
|
332
|
+
if (!nodeCopy) {
|
|
333
|
+
nodeCopy = outputDocument.importNode(targetNode, true)
|
|
334
|
+
mapParallel(targetNode, nodeCopy)
|
|
335
|
+
}
|
|
336
|
+
const refCopy = contentView().cloneOf(targetRef)
|
|
337
|
+
if (refCopy) refCopy.before(nodeCopy)
|
|
338
|
+
else parentCopy.appendChild(nodeCopy)
|
|
339
|
+
}
|
|
340
|
+
},
|
|
341
|
+
insertAfter(ref, node) {
|
|
342
|
+
const targetRef = live(ref)
|
|
343
|
+
const targetNode = live(node)
|
|
344
|
+
targetRef.parentNode.insertBefore(targetNode, targetRef.nextSibling)
|
|
345
|
+
const parentCopy = contentView().cloneOf(targetRef.parentNode)
|
|
346
|
+
if (parentCopy) {
|
|
347
|
+
let nodeCopy = contentView().cloneOf(targetNode)
|
|
348
|
+
if (!nodeCopy) {
|
|
349
|
+
nodeCopy = outputDocument.importNode(targetNode, true)
|
|
350
|
+
mapParallel(targetNode, nodeCopy)
|
|
351
|
+
}
|
|
352
|
+
const refCopy = contentView().cloneOf(targetRef)
|
|
353
|
+
if (refCopy) refCopy.after(nodeCopy)
|
|
354
|
+
else parentCopy.appendChild(nodeCopy)
|
|
355
|
+
}
|
|
356
|
+
},
|
|
357
|
+
identity(node) {
|
|
358
|
+
return live(node) || null
|
|
359
|
+
},
|
|
271
360
|
remove(node) {
|
|
272
361
|
const target = live(node)
|
|
273
362
|
const copy = contentView().cloneOf(target)
|
package/src/cms/form-builder.js
CHANGED
|
@@ -110,7 +110,7 @@ function handleClick(e) {
|
|
|
110
110
|
const rule = getRuleAtPath(rules, path)
|
|
111
111
|
if (!Array.isArray(rule)) return
|
|
112
112
|
const current = getValueAtPath(getData(), path) || []
|
|
113
|
-
onChange(setAtPath(getData(), path, [...current, scaffold(rule[1])]), {
|
|
113
|
+
onChange(setAtPath(getData(), path, [...current, scaffold(rule[1], rule[0])]), {
|
|
114
114
|
structural: true,
|
|
115
115
|
})
|
|
116
116
|
return
|
package/src/cms/scaffold.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { DOM_PROPERTIES_SET } from '../engine/dom-properties.js'
|
|
2
|
+
import { splitRule } from '../engine/rule-syntax.js'
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
5
|
* Produce an empty value matching a rule shape.
|
|
3
6
|
*
|
|
@@ -6,19 +9,84 @@
|
|
|
6
9
|
* list.
|
|
7
10
|
*
|
|
8
11
|
* "title" → ""
|
|
12
|
+
* "@data-id" → null (an attribute: absent, not present-and-empty)
|
|
9
13
|
* "li[]" → []
|
|
10
14
|
* ["sel", { ... }] → []
|
|
11
15
|
* { name: "h1", ... } → { name: "" , ... }
|
|
12
16
|
*
|
|
17
|
+
* `rowSelector` is the list rule's own selector ("ul > li[data-id]"), so an
|
|
18
|
+
* attribute the row cannot be a row without arrives present-and-empty instead.
|
|
19
|
+
*
|
|
13
20
|
* Anything else falls through to the scalar default ("").
|
|
14
21
|
*/
|
|
15
|
-
export function scaffold(shape) {
|
|
16
|
-
if (typeof shape === 'string')
|
|
22
|
+
export function scaffold(shape, rowSelector) {
|
|
23
|
+
if (typeof shape === 'string') {
|
|
24
|
+
if (shape.endsWith('[]')) return []
|
|
25
|
+
if (!isAttributeRule(shape)) return ''
|
|
26
|
+
return rowRequiresAttribute(rowSelector, splitRule(shape).prop) ? '' : null
|
|
27
|
+
}
|
|
17
28
|
if (Array.isArray(shape)) return []
|
|
18
29
|
if (typeof shape === 'object' && shape !== null) {
|
|
19
30
|
const out = {}
|
|
20
|
-
for (const [k, v] of Object.entries(shape)) out[k] = scaffold(v)
|
|
31
|
+
for (const [k, v] of Object.entries(shape)) out[k] = scaffold(v, rowSelector)
|
|
21
32
|
return out
|
|
22
33
|
}
|
|
23
34
|
return ''
|
|
24
35
|
}
|
|
36
|
+
|
|
37
|
+
// "" is the present-and-empty value for an attribute, so a scaffolded row that
|
|
38
|
+
// used it would arrive with every presence flag set (a new task done, a new
|
|
39
|
+
// card archived). An attribute field starts null — the writer removes the
|
|
40
|
+
// attribute — while text fields keep "". DOM properties have no presence to
|
|
41
|
+
// speak of and keep "" too.
|
|
42
|
+
function isAttributeRule(rule) {
|
|
43
|
+
const { prop } = splitRule(rule)
|
|
44
|
+
return prop !== null && !DOM_PROPERTIES_SET.has(prop)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// An attribute the row selector itself requires is structural: apply removes a
|
|
48
|
+
// null attribute, and a row without "data-id" falls straight out of the data on
|
|
49
|
+
// the next read. Only the selector's final compound speaks for the row; an
|
|
50
|
+
// attribute named earlier belongs to an ancestor.
|
|
51
|
+
function rowRequiresAttribute(rowSelector, prop) {
|
|
52
|
+
if (!rowSelector || !prop) return false
|
|
53
|
+
const compound = lastCompound(rowSelector)
|
|
54
|
+
const wanted = prop.toLowerCase()
|
|
55
|
+
for (let i = 0; i < compound.length; i++) {
|
|
56
|
+
if (compound[i] === '\\') {
|
|
57
|
+
i++
|
|
58
|
+
} else if (compound[i] === '[') {
|
|
59
|
+
const end = compound.indexOf(']', i)
|
|
60
|
+
if (end === -1) return false
|
|
61
|
+
const name = /^\s*([^\s\]=~^|*$]+)/.exec(compound.slice(i + 1, end))
|
|
62
|
+
if (name && name[1].toLowerCase() === wanted) return true
|
|
63
|
+
i = end
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return false
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Everything after the last top-level combinator, which is the compound that
|
|
70
|
+
// describes the row itself.
|
|
71
|
+
function lastCompound(selector) {
|
|
72
|
+
let depth = 0
|
|
73
|
+
let quote = null
|
|
74
|
+
let start = 0
|
|
75
|
+
for (let i = 0; i < selector.length; i++) {
|
|
76
|
+
const ch = selector[i]
|
|
77
|
+
if (ch === '\\') {
|
|
78
|
+
i++
|
|
79
|
+
} else if (quote) {
|
|
80
|
+
if (ch === quote) quote = null
|
|
81
|
+
} else if (ch === '"' || ch === "'") {
|
|
82
|
+
quote = ch
|
|
83
|
+
} else if (ch === '[' || ch === '(') {
|
|
84
|
+
depth++
|
|
85
|
+
} else if (ch === ']' || ch === ')') {
|
|
86
|
+
if (depth > 0) depth--
|
|
87
|
+
} else if (depth === 0 && (ch === '>' || ch === '+' || ch === '~' || /\s/.test(ch))) {
|
|
88
|
+
start = i + 1
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return selector.slice(start)
|
|
92
|
+
}
|
package/src/engine/apply.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DOM_PROPERTIES_WRITE_SET,
|
|
3
3
|
DOM_PROPERTIES_READ_ONLY_SET,
|
|
4
|
+
coercePropValue,
|
|
4
5
|
} from './dom-properties.js'
|
|
5
6
|
import {
|
|
6
7
|
MaxRuleDepthExceeded,
|
|
@@ -11,8 +12,6 @@ import {
|
|
|
11
12
|
import { listDiff } from './diff.js'
|
|
12
13
|
import { ruleAttrIndex } from './rule-syntax.js'
|
|
13
14
|
|
|
14
|
-
const BOOLEAN_PROPS = new Set(['checked', 'selected', 'disabled', 'readOnly', 'paused'])
|
|
15
|
-
|
|
16
15
|
export function apply(adapter, root, rules, data, opts = {}) {
|
|
17
16
|
if (Object.prototype.hasOwnProperty.call(opts, 'exclude') && adapter.semanticExclude === false) {
|
|
18
17
|
throw new Error('This adapter does not support semantic exclude queries; omit exclude or use the DOM adapter.')
|
|
@@ -126,19 +125,13 @@ function writePropOrAttr(adapter, node, name, value) {
|
|
|
126
125
|
if (adapter.prop(node, name) !== next) adapter.prop(node, name, next)
|
|
127
126
|
return node
|
|
128
127
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
function coercePropValue(name, value) {
|
|
135
|
-
if (value === null || value === undefined) {
|
|
136
|
-
return BOOLEAN_PROPS.has(name) ? false : ''
|
|
128
|
+
if (value == null) {
|
|
129
|
+
if (adapter.attr(node, name) != null) adapter.removeAttr(node, name)
|
|
130
|
+
} else {
|
|
131
|
+
const next = String(value)
|
|
132
|
+
if (adapter.attr(node, name) !== next) adapter.attr(node, name, next)
|
|
137
133
|
}
|
|
138
|
-
|
|
139
|
-
// Boolean("false") is true: writing "false" would CHECK an unchecked box.
|
|
140
|
-
if (BOOLEAN_PROPS.has(name)) return value === 'false' ? false : Boolean(value)
|
|
141
|
-
return value
|
|
134
|
+
return node
|
|
142
135
|
}
|
|
143
136
|
|
|
144
137
|
function validateShape(rule, value, path, mismatches) {
|