hyper-html-api 0.11.0 → 0.11.2
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/dist/hyper-html-api.engine.esm.js +1 -1
- package/dist/hyper-html-api.engine.min.js +1 -1
- package/dist/hyper-html-api.min.js +8 -8
- package/dist/hyper-html-api.upgrade.min.js +2 -2
- package/package.json +1 -1
- package/src/engine/diff.js +4 -1
- package/src/engine/round-trip.js +20 -64
- package/src/engine/splice.js +31 -3
- package/src/write.js +1 -5
|
@@ -1,2 +1,2 @@
|
|
|
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},
|
|
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 Gt={};Re(Gt,{default:()=>Xt,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"],X=new Set(Y),le=new Set(["textContent","innerText","innerHTML","value","checked","selected","disabled","readOnly","type","id","className","title"]),G=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:()=>k,NoRulesTag:()=>ue,RuleTargetReadOnly:()=>v,RulesParseError:()=>_,ShapeMismatch:()=>U,UnknownRulesVersion:()=>P,WriteNotRoundTripped:()=>Q,WriteRefused:()=>Z,WriteRejected:()=>ae});var _=class extends Error{constructor(t,n){super(t),this.name="RulesParseError",this.cause=n}},P=class extends Error{constructor(t){super(`unknown rules version: ${t}. Library supports "1".`),this.name="UnknownRulesVersion",this.version=t}},D=20,k=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 k(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,a)=>pe(e,l,s,{depth:o.depth+1,path:[...o.path,a]},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(a=>e.text(a))}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),a=c?e.find(t,c,r):[t];return a.length===0?null:Ce(e,a[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(X.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 w=o[m];!(w>=0&&w<i)||u.has(w)||(s[m]=w,u.add(w))}}if(r===0||i===0)return s;let c=e.map(u=>Pe(u,n)),l=t.map(u=>Pe(u,n)),a=new Array(i).fill(!1);for(let u of s)u>=0&&(a[u]=!0);let d=new Map;l.forEach((u,m)=>{a[m]||d.set(u,d.has(u)?-1:m)});let y=new Map;c.forEach((u,m)=>{s[m]>=0||y.set(u,(y.get(u)||0)+1)}),c.forEach((u,m)=>{if(s[m]>=0||y.get(u)!==1)return;let w=d.get(u);w===void 0||w===-1||a[w]||(s[m]=w,a[w]=!0)});let p=[];for(let u=0;u<r;u++)s[u]<0&&p.push(u);let T=[];for(let u=0;u<i;u++)a[u]||T.push(u);if(p.length===0||T.length===0)return s;let f=r*i+1,h=pt(e,t,n),g=(u,m)=>h(u,m)*f+Math.abs(u-m);for(let[u,m]of mt(p,T,g))s[u]=m;return s}var Le=e=>typeof e=="object"&&e!==null;function Pe(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 a=i[c],d=s[l],y=0;for(let p=0;p<o.length;p++)a[p]!==d[p]&&y++;return y}}function mt(e,t,n){return e.length<=t.length?ke(e,t,n,!1):ke(t,e,(o,r)=>n(r,o),!0)}function ke(e,t,n,o){let r=e.length,i=t.length,s=[];for(let y=0;y<=r;y++)s.push(new Float64Array(i+1).fill(1/0));let c=[];for(let y=0;y<=r;y++)c.push(new Uint8Array(i+1));for(let y=0;y<=i;y++)s[r][y]=0;for(let y=r-1;y>=0;y--)for(let p=i-1;p>=0;p--){let T=n(e[y],t[p])+s[y+1][p+1],f=s[y][p+1];T<=f?(s[y][p]=T,c[y][p]=1):s[y][p]=f}let l=[],a=0,d=0;for(;a<r&&d<i;)c[a][d]&&(l.push(o?[t[d],e[a]]:[e[a],t[d]]),a++),d++;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(A=>e.remove(A)),me(c,"onRowsApplied",i.path,[]);return}let a=r.length>l.length,d=l[0]||null;if(a&&!d&&(d=At(e,t,n,c),!d))throw new M(i.path);let y=l.map(A=>wt(e,A,o,c)),p=null;if(a&&d){p=e.clone(d),c.templateAttr&&e.removeAttr(p,c.templateAttr);let A=e.stripIds(p);A>0&&console.warn(`[hyper-html-api] stripped ${A} id attribute(s) from cloned template at "${i.path.join(".")||"(root)"}"`)}let T=Ie(r,y,o,yt(e,l,r,i,c)),f=l.length>0?e.parent(l[0]):Ot(e,t,n,d,i,c),h=l.length>0?We(e,f,l[0]):0,g=Rt(e,l),u=new Set,m=[],w=r.map((A,b)=>{let E=T[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((A,b)=>{u.has(b)||e.remove(A)}),g?St(e,f,h,w,m):Nt(e,w,m,f,h),gt(e,w,o,r,i,s,c),me(c,"onRowsApplied",i.path,w)}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((a,d)=>[e.identity(a),d]));for(let a=0;a<n.length;a++){if(!i[a])continue;let d=l.get(e.identity(i[a]));d===void 0||c.has(d)||(s[a]=d,c.add(d))}return s}function gt(e,t,n,o,r,i,s){t.forEach((c,l)=>{if(n===null){let a=o[l],d=a==null?"":String(a);e.text(c)!==d&&e.text(c,d)}else{let a=i(e,c,n,o[l],{depth:r.depth+1,path:[...r.path,l]},s);a&&a!==c&&(t[l]=a)}})}function wt(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 At(e,t,n,o){if(!o.templateAttr)return null;let r=/^\s*:scope\s*>\s*/.test(n),i=new RegExp(":not\\(\\["+o.templateAttr.replace(/[.*+?^${}()|[\]\\-]/g,"\\$&")+"\\]\\)","g"),s=n.replace(/^\s*:scope\s*>\s*/,"").replace(i,""),c=r?Tt(s):0,l=he(s),a=t;for(;a;){let d=e.find(a,s,{includeRulesTag:!1,templateAttr:null});for(let y of d)if(e.attr(y,o.templateAttr)!=null&&!(r&&!Et(e,t,y,c))&&!(l&&!e.matches(e.parent(y),l)))return y;a=e.parent(a)}return null}function Tt(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 a=(c===":scope"?e.prop(t,"tagName")?[t]:[]:e.find(t,c,i)).filter(d=>!$e(e,d,i));if(a.length===0)throw new M(r.path,`no container matching "${c}" inside this context to hold the new rows`);if(a.length>1)throw new M(r.path,`"${c}" matches ${a.length} containers inside this context, so the new rows have no single destination`);return a[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,a)=>{let d=e.identity(l),y=n+a;if(s[y]===d)return;if(!r[a]){let T=s.indexOf(d);T!==-1&&(s.splice(T,1),i.splice(T,1))}let p=Math.min(y,i.length);p<i.length?e.insertBefore(i[p],l):i.length?c?e.insertAfter(i[i.length-1],l):(e.insertAt(t,l,y),c=!0):e.insertAt(t,l,0),s.splice(p,0,d),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 a=i?We(e,l,i)+1:s++;e.insertAt(l,t[c],a),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 k(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),a=n.slice(s+1),d=l?e.find(t,l,i):[t];return d.length===0||ve(e,d[0],a,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(G.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 we(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 y=!1,p=s+1;for(;p<r.length&&/\s/.test(r[p]);)p++;if(p<r.length&&/[a-zA-Z_]/.test(r[p])&&(y=!0),!y){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 y=c,p=s+1;for(;p<r.length&&r[p]!==y;)r[p]==="\\"&&p++,p++;i.push({type:t.STRING,value:r.substring(s+1,p),quoted:!0,sourceQuote:y}),s=p+1;continue}let l=s,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"],p=!1;for(let T of y){let f=T.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 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(s,l);let d=t.IDENTIFIER;/^-?\d+(\.\d+)?$/.test(a)?d=t.NUMBER:a==="true"||a==="false"||a==="null"?d=t.BOOLEAN:/^[.#@\[]|[.#@\[]| /.test(a)&&(d=t.SELECTOR),i.push({type:d,value:a,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,(a,d)=>d.length%2===0?d+'\\"':a)),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 Ae="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!==Ae)throw new P(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 Te(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 z(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 Pt(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=>Te(n,r))||o.bundles.some(r=>K(n,r)))return n;n=n.parentElement}return null}function qe(e,t){return!!Pt(e,t)}var kt=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 ze(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=>Te(e,o))||n.bundles.some(o=>K(e,o))}var Wt=new Set(["INPUT","TEXTAREA","SELECT","OPTION"]);function Fe(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)Fe(c,s,n,o),s=s.nextSibling}function F(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,a=e.nodeType===9?e.documentElement:e;n&&s.documentElement.matches(n);let d=z(t),y=o?f=>$t(f,t)||!!(n&&f.matches(n)):f=>ze(f,t,d,n,a,!1),p=null;if(a.nodeType!==1||!ze(a,t,d,n,a,o)){p=s.importNode(a,!0);let f={cloneToLive:c,liveToClone:l,dropped:[],controls:[]};Fe(a,p,f,y);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 T=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:z(t),cloneToLive:c,liveToClone:l,original(f){return c.get(f)||null},cloneOf(f){return l.get(f)||null},query(f,h=p){return T(f),Array.from(h.querySelectorAll(f),g=>c.get(g)||g)},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 Xe(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 Xe(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=[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 O;let i=e.nodeType===9||!e.isConnected?e:e.ownerDocument,s=e.nodeType===9?e:e.ownerDocument,c=null,l=()=>c||(c=F(i,{capability:"data",exclude:t.exclude||null})),a=f=>{let h=l();return f===e?h.cloneOf(e):h.cloneOf(f)||f},d=f=>c?.original(f)||f,y=(f,h)=>{l().liveToClone.set(f,h),l().cloneToLive.set(h,f);let g=f.childNodes||[],u=h.childNodes||[];for(let m=0;m<Math.min(g.length,u.length);m++)y(g[m],u[m])},p=(f,h,g,u)=>{let m=Array.from(f.childNodes).filter(x=>c.cloneOf(x)),A=m[0];for(;A&&m.includes(A);)A=A.nextSibling;for(let x of m)x.remove();if(g==="innerHTML"){let x=s.createElement("template");x.innerHTML=u;for(let W of Array.from(x.content.childNodes))f.insertBefore(W,A||null)}else f.insertBefore(s.createTextNode(u),A||null),Ye(f,u);let b=F(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)},T={...O,find(f,h,g={}){let u=a(f);if(!u?.querySelectorAll)return[];let m=l().query(h,u);g.includeRulesTag||(m=m.filter(b=>!Je(b)));let w=[];g.skip&&w.push(g.skip);let A=g.templateAttr===null?null:g.templateAttr||"cms-template";if(A&&w.push(`[${A}]`),w.length){let b=w.join(", ");m=m.filter(E=>!E.closest?.(b))}return m},parent(f){let h=a(f)?.parentElement;return h?d(h):null},children(f){return Array.from(a(f)?.children||[],d)},text(f,h){if(h===void 0){let m=d(f);return!m?.matches?.(n)&&!m?.querySelector?.(n)?O.text(m):(a(f)?.textContent||"").trim()}let g=d(f);if(!g?.matches?.(n)&&!g?.querySelector?.(n)&&!c){O.text(g,h);return}let u=l().cloneOf(g);u?p(g,u,"textContent",h):O.text(g,h)},attr(f,h,g){let u=d(f);if(g===void 0)return O.attr(u,h);O.attr(u,h,g);let m=c?.cloneOf(u);m&&(O.attr(m,h,g),F(u,{capability:"data",exclude:t.exclude||null}).root===null&&(m.remove(),c.liveToClone.delete(u),c.cloneToLive.delete(m)))},removeAttr(f,h){let g=d(f);O.removeAttr(g,h);let u=c?.cloneOf(g);u&&O.removeAttr(u,h)},prop(f,h,g){let u=d(f);if(g===void 0)return h==="innerHTML"||h==="outerHTML"||h==="textContent"||h==="innerText"?O.prop(a(u),h):O.prop(u,h);let m=h==="innerHTML"||h==="textContent"||h==="innerText",w=m?l().cloneOf(u):c?.cloneOf(u);w&&m?p(u,w,h,g):(O.prop(u,h,g),w&&O.prop(w,h,g))},clone(f){let h=a(f);if(h===f)return O.clone(f);let g=s.importNode(h,!0);return Xe(g),g},insertAt(f,h,g){let u=d(f),w=T.children(u)[g]||(()=>{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})(),A=d(h);u.insertBefore(A,w||null);let b=l().cloneOf(u);if(b){let E=l().cloneOf(A);E||(E=s.importNode(A,!0),y(A,E));let x=Array.from(b.children);b.insertBefore(E,x[g]||null)}},insertBefore(f,h){let g=d(f),u=d(h);g.parentNode.insertBefore(u,g);let m=l().cloneOf(g.parentNode);if(m){let w=l().cloneOf(u);w||(w=s.importNode(u,!0),y(u,w));let A=l().cloneOf(g);A?A.before(w):m.appendChild(w)}},insertAfter(f,h){let g=d(f),u=d(h);g.parentNode.insertBefore(u,g.nextSibling);let m=l().cloneOf(g.parentNode);if(m){let w=l().cloneOf(u);w||(w=s.importNode(u,!0),y(u,w));let A=l().cloneOf(g);A?A.after(w):m.appendChild(w)}},identity(f){return d(f)||null},remove(f){let h=d(f),g=l().cloneOf(h);O.remove(h),g&&O.remove(g)},replaceWith(f,h){let g=d(f),u=l().cloneOf(g),m=O.replaceWith(g,h);if(u){let w=F(m,{capability:"data",exclude:t.exclude||null});if(!w.root)u.remove();else{u.replaceWith(w.root);let A=b=>{let E=w.original(b);E&&(c.liveToClone.set(E,b),c.cloneToLive.set(b,E));for(let x of Array.from(b.childNodes||[]))A(x)};A(w.root)}}return m}};return T}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:we,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 Ge(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=Ge(e),o=Ge(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 a=`${vt}${l.href}:${c||"none"}`,d,y=e?null:Bt(a);if(y&&typeof y.checkedAt=="number"&&r-y.checkedAt<i)d=y.sourceVersion;else{try{let p=await o(l.href);if(!p.ok)throw new Error(`HTTP ${p.status}`);let T=await p.text(),f=new DOMParser().parseFromString(T,"text/html");d=C(f,"hyper-version")}catch{d=null}qt(a,{checkedAt:r,sourceVersion:d})}return d?{available:Ht(d,c||"0.0.0"),currentVersion:c,sourceVersion:d,sourceUrl:l.href}:null}var Kt="script[data-rules-name]";function zt(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=zt(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!==Ae)throw new P(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 Ft="text/hyper-upgrade";function et(e,t){let n=e.find(t,`script[type="${Ft}"]`);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:a,summary:d}=se(n[c],l);I(e,t,l,a),i[c]=d,r.carriedOver+=d.carriedOver,r.discarded+=d.discarded,r.listItems+=d.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(),a=new DOMParser().parseFromString(l,"text/html"),d=C(a,"hyper-version"),y=t,p=!1,T=et(R,a);if(T){let m=await(await tt(T))(y,{fromVersion:n,toVersion:d});if(!m||typeof m!="object"||Array.isArray(m))throw new j("transform must return a plain object map of { rulesName: data }");y=m,p=!0}let{totals:f,byName:h,rulesTagCount:g}=nt(R,a,y);if(g===0&&Object.keys(y).length>0)throw new oe(s.href);return{html:Jt(a),fromVersion:n,toVersion:d,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},Xt=Yt;return ut(Gt);})();
|
package/package.json
CHANGED
package/src/engine/diff.js
CHANGED
|
@@ -184,7 +184,10 @@ function findFallbackTemplate(adapter, parentCtx, selector, opts) {
|
|
|
184
184
|
// descendant. Dropping just that anchor searches the ancestors for the rest of
|
|
185
185
|
// the selector, so a checklist item seed still cannot pass for a comment seed.
|
|
186
186
|
const anchored = /^\s*:scope\s*>\s*/.test(selector)
|
|
187
|
-
|
|
187
|
+
// A row selector that excludes seeds by hand (":not([cms-template])") would hide
|
|
188
|
+
// the very seed this lookup is for.
|
|
189
|
+
const exclusion = new RegExp(':not\\(\\[' + opts.templateAttr.replace(/[.*+?^${}()|[\]\\-]/g, '\\$&') + '\\]\\)', 'g')
|
|
190
|
+
const search = selector.replace(/^\s*:scope\s*>\s*/, '').replace(exclusion, '')
|
|
188
191
|
// The stripped anchor makes the rest of the selector far too loose on its own:
|
|
189
192
|
// "p" or "div" matches any seed in any ancestor, including the seed bank root
|
|
190
193
|
// itself. The seed's own selector says how deep its row's context sits and what
|
package/src/engine/round-trip.js
CHANGED
|
@@ -12,46 +12,42 @@ const UNTRIMMED_PROPS = new Set(['textContent', 'innerText'])
|
|
|
12
12
|
|
|
13
13
|
// Elements whose content loses one leading LF to the HTML parser: the tokenizer
|
|
14
14
|
// drops a newline that immediately follows the start tag.
|
|
15
|
-
const NEWLINE_DROPPING_TAGS = new Set(['pre', 'textarea'])
|
|
16
|
-
|
|
17
15
|
// Compares what the caller asked for against a fresh extraction of the
|
|
18
16
|
// serialized source, so a write that serialized away or never landed throws
|
|
19
17
|
// WriteNotRoundTripped instead of returning a false success. Only the supplied
|
|
20
18
|
// projection is checked: omitted keys and undefined are skipped exactly as the
|
|
21
|
-
// writer skips them, which is what keeps partial updates working.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
export function assertRoundTrip(rules, requested, actual, source) {
|
|
25
|
-
check(rules, requested, actual, [], source ? { ...source, rules } : null)
|
|
19
|
+
// writer skips them, which is what keeps partial updates working.
|
|
20
|
+
export function assertRoundTrip(rules, requested, actual) {
|
|
21
|
+
check(rules, requested, actual, [])
|
|
26
22
|
}
|
|
27
23
|
|
|
28
|
-
function check(rule, want, got, path
|
|
24
|
+
function check(rule, want, got, path) {
|
|
29
25
|
if (want === undefined) return
|
|
30
26
|
if (typeof rule === 'string') {
|
|
31
|
-
checkScalarRule(rule, want, got, path
|
|
27
|
+
checkScalarRule(rule, want, got, path)
|
|
32
28
|
return
|
|
33
29
|
}
|
|
34
30
|
if (Array.isArray(rule)) {
|
|
35
|
-
checkList(rule[1], want, got, path
|
|
31
|
+
checkList(rule[1], want, got, path)
|
|
36
32
|
return
|
|
37
33
|
}
|
|
38
34
|
if (typeof rule === 'object' && rule !== null) {
|
|
39
|
-
checkObject(rule, want, got, path
|
|
35
|
+
checkObject(rule, want, got, path)
|
|
40
36
|
}
|
|
41
37
|
}
|
|
42
38
|
|
|
43
|
-
function checkScalarRule(rule, want, got, path
|
|
39
|
+
function checkScalarRule(rule, want, got, path) {
|
|
44
40
|
if (rule.endsWith('[]')) {
|
|
45
41
|
checkTextList(want, got, path)
|
|
46
42
|
return
|
|
47
43
|
}
|
|
48
44
|
if (rule.startsWith('@')) {
|
|
49
|
-
checkPropOrAttr(rule.slice(1), want, got, path
|
|
45
|
+
checkPropOrAttr(rule.slice(1), want, got, path)
|
|
50
46
|
return
|
|
51
47
|
}
|
|
52
48
|
const at = ruleAttrIndex(rule)
|
|
53
49
|
if (at !== -1) {
|
|
54
|
-
checkPropOrAttr(rule.slice(at + 1), want, got, path
|
|
50
|
+
checkPropOrAttr(rule.slice(at + 1), want, got, path)
|
|
55
51
|
return
|
|
56
52
|
}
|
|
57
53
|
checkText(want, got, path)
|
|
@@ -66,19 +62,19 @@ function checkTextList(want, got, path) {
|
|
|
66
62
|
for (let i = 0; i < want.length; i++) checkText(want[i], got[i], [...path, i])
|
|
67
63
|
}
|
|
68
64
|
|
|
69
|
-
function checkObject(rule, want, got, path
|
|
65
|
+
function checkObject(rule, want, got, path) {
|
|
70
66
|
if (!isPlainObject(want) || !isPlainObject(got)) fail(path)
|
|
71
67
|
for (const [key, sub] of Object.entries(rule)) {
|
|
72
|
-
check(sub, want[key], got[key], [...path, key]
|
|
68
|
+
check(sub, want[key], got[key], [...path, key])
|
|
73
69
|
}
|
|
74
70
|
}
|
|
75
71
|
|
|
76
|
-
function checkList(shape, want, got, path
|
|
72
|
+
function checkList(shape, want, got, path) {
|
|
77
73
|
if (!Array.isArray(want) || !Array.isArray(got) || want.length !== got.length) fail(path)
|
|
78
|
-
for (let i = 0; i < want.length; i++) check(shape, want[i], got[i], [...path, i]
|
|
74
|
+
for (let i = 0; i < want.length; i++) check(shape, want[i], got[i], [...path, i])
|
|
79
75
|
}
|
|
80
76
|
|
|
81
|
-
function checkPropOrAttr(name, want, got, path
|
|
77
|
+
function checkPropOrAttr(name, want, got, path) {
|
|
82
78
|
if (!DOM_PROPERTIES_SET.has(name)) {
|
|
83
79
|
if (want == null) {
|
|
84
80
|
if (got != null) fail(path)
|
|
@@ -88,7 +84,7 @@ function checkPropOrAttr(name, want, got, path, selector, source) {
|
|
|
88
84
|
return
|
|
89
85
|
}
|
|
90
86
|
if (UNTRIMMED_PROPS.has(name)) {
|
|
91
|
-
if (!sameUntrimmed(String(want ?? ''), got
|
|
87
|
+
if (!sameUntrimmed(String(want ?? ''), got)) fail(path)
|
|
92
88
|
return
|
|
93
89
|
}
|
|
94
90
|
if (DOM_PROPERTIES_WRITE_SET.has(name)) {
|
|
@@ -116,50 +112,10 @@ function sameString(want, got) {
|
|
|
116
112
|
return got != null && normalizeNewlines(want) === normalizeNewlines(got)
|
|
117
113
|
}
|
|
118
114
|
|
|
119
|
-
// @textContent compares exactly
|
|
120
|
-
// pre/textarea start tag
|
|
121
|
-
function sameUntrimmed(want, got
|
|
122
|
-
|
|
123
|
-
const wantText = normalizeNewlines(want)
|
|
124
|
-
const gotText = normalizeNewlines(got)
|
|
125
|
-
if (wantText === gotText) return true
|
|
126
|
-
return wantText.startsWith('\n') && wantText.slice(1) === gotText && dropsLeadingNewline(selector, path, source)
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// Which element the rule matched decides the allowance, not how its selector is
|
|
130
|
-
// spelled: an ID or class selector names a pre just as "pre" does. An element
|
|
131
|
-
// that cannot be found refuses, which is the safe answer: the caller compares
|
|
132
|
-
// exactly.
|
|
133
|
-
function dropsLeadingNewline(selector, path, source) {
|
|
134
|
-
const node = matchedNode(selector, path, source)
|
|
135
|
-
if (!node) return false
|
|
136
|
-
const tag = source.adapter.prop(node, 'tagName')
|
|
137
|
-
return tag != null && NEWLINE_DROPPING_TAGS.has(String(tag).toLowerCase())
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// The element a scalar rule reads, found the way extraction found it: walk the
|
|
141
|
-
// rule tree by the reported path to the rule's own context, then match the
|
|
142
|
-
// rule's selector there. Only called for a text rule whose value lost a leading
|
|
143
|
-
// newline, so an ordinary write pays nothing for it.
|
|
144
|
-
function matchedNode(selector, path, source) {
|
|
145
|
-
if (!source || !source.adapter || !source.root) return null
|
|
146
|
-
const { adapter, root, opts } = source
|
|
147
|
-
let rule = source.rules
|
|
148
|
-
let ctx = root
|
|
149
|
-
for (const key of path) {
|
|
150
|
-
if (Array.isArray(rule)) {
|
|
151
|
-
const match = adapter.find(ctx, rule[0], opts)[key]
|
|
152
|
-
if (!match) return null
|
|
153
|
-
ctx = match
|
|
154
|
-
rule = rule[1]
|
|
155
|
-
} else if (isPlainObject(rule)) {
|
|
156
|
-
rule = rule[key]
|
|
157
|
-
} else {
|
|
158
|
-
return null
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
if (!selector) return ctx
|
|
162
|
-
return adapter.find(ctx, selector, opts)[0] || null
|
|
115
|
+
// @textContent compares exactly. The writer serializes the extra newline a
|
|
116
|
+
// pre/textarea start tag needs, so a leading newline comes back too.
|
|
117
|
+
function sameUntrimmed(want, got) {
|
|
118
|
+
return got != null && normalizeNewlines(want) === normalizeNewlines(got)
|
|
163
119
|
}
|
|
164
120
|
|
|
165
121
|
function isPlainObject(value) {
|
package/src/engine/splice.js
CHANGED
|
@@ -103,12 +103,40 @@ function hasAncestorIn(r, set) {
|
|
|
103
103
|
return false
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
+
// The HTML serializer writes an extra newline after a pre, textarea or listing
|
|
107
|
+
// start tag when the text starts with one, because the parser drops the first.
|
|
108
|
+
// Cheerio's serializer skips that step, so a leading blank line would be lost.
|
|
109
|
+
// Only HTML elements drop it (an SVG or MathML textarea keeps it), and a
|
|
110
|
+
// written value can still carry a CR, which the parser turns into that LF.
|
|
111
|
+
const NEWLINE_DROPPING = new Set(['pre', 'textarea', 'listing'])
|
|
112
|
+
const HTML_NS = 'http://www.w3.org/1999/xhtml'
|
|
113
|
+
|
|
114
|
+
function serialize($, r) {
|
|
115
|
+
const fixed = []
|
|
116
|
+
const visit = (n) => {
|
|
117
|
+
if (n.type === 'tag' && NEWLINE_DROPPING.has(n.name) && (n.namespace == null || n.namespace === HTML_NS)) {
|
|
118
|
+
const first = n.children && n.children[0]
|
|
119
|
+
if (first && first.type === 'text' && /^[\n\r]/.test(first.data)) {
|
|
120
|
+
fixed.push(first)
|
|
121
|
+
first.data = '\n' + first.data
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
for (const c of n.children || []) visit(c)
|
|
125
|
+
}
|
|
126
|
+
visit(r || raw($.root()))
|
|
127
|
+
try {
|
|
128
|
+
return r ? $.html(r) : $.html()
|
|
129
|
+
} finally {
|
|
130
|
+
for (const t of fixed) t.data = t.data.slice(1)
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
106
134
|
// Replaces the source span of each topmost changed element with its fresh
|
|
107
135
|
// serialization, then proves the result by reparsing: the spliced text must
|
|
108
136
|
// render exactly like the mutated tree. Anything unprovable falls back to the
|
|
109
137
|
// whole-document render.
|
|
110
138
|
export function spliceDocument(load, src, $, tracker) {
|
|
111
|
-
const full =
|
|
139
|
+
const full = serialize($)
|
|
112
140
|
const fallback = { html: full, spliced: false }
|
|
113
141
|
const docRoot = raw($.root())
|
|
114
142
|
const targets = new Set()
|
|
@@ -125,8 +153,8 @@ export function spliceDocument(load, src, $, tracker) {
|
|
|
125
153
|
for (const r of top) {
|
|
126
154
|
const { startOffset, endOffset } = r.sourceCodeLocation
|
|
127
155
|
if (endOffset > prevStart) return fallback
|
|
128
|
-
out = out.slice(0, startOffset) +
|
|
156
|
+
out = out.slice(0, startOffset) + serialize($, r) + out.slice(endOffset)
|
|
129
157
|
prevStart = startOffset
|
|
130
158
|
}
|
|
131
|
-
return load(out)
|
|
159
|
+
return serialize(load(out)) === full ? { html: out, spliced: true } : fallback
|
|
132
160
|
}
|
package/src/write.js
CHANGED
|
@@ -46,11 +46,7 @@ export function writeDocument(load, src, data, options = {}) {
|
|
|
46
46
|
// pays for the field it wrote, not for every rule in the document.
|
|
47
47
|
const written = writtenRules(rules, data)
|
|
48
48
|
const writtenRoot = load(html).root()
|
|
49
|
-
assertRoundTrip(written, data, extract(cheerioAdapter, writtenRoot, written, opts)
|
|
50
|
-
adapter: cheerioAdapter,
|
|
51
|
-
root: writtenRoot,
|
|
52
|
-
opts,
|
|
53
|
-
})
|
|
49
|
+
assertRoundTrip(written, data, extract(cheerioAdapter, writtenRoot, written, opts))
|
|
54
50
|
return { html, changed: html !== src, spliced }
|
|
55
51
|
}
|
|
56
52
|
|