HS behavioral tests: 478→509/831 (57%→61%), parser/compiler/runtime fixes
Parser: am-a/am-not-a type checks, transition element/selector targeting, take @attr=value with replacement, toggle my/the possessive, <selector/> syntax in parse-atom, the-of for style/attr/class/selector, when-clause filtering for add, starts/ends-with ignoring case. Compiler: take attr passthrough, toggle-style nil→me default, scoped querySelectorAll for add/remove/toggle-class, has-class? entry, matches? extracts selector from (query sel), add-class-when with for-each filter, starts/ends-with-ic entries, hs-add replaces + for polymorphic add. Runtime: hs-take! proper attr values, hs-type-check Element/Node via host-typeof, hs-toggle-style! opacity 0↔1, hs-coerce +8 coercions (Keys/Values/Entries/Reversed/Unique/Flat/JSON/Object), hs-query-all bypasses broken dom-query-all (WASM auto-converts arrays), hs-matches? handles DOM el.matches(selector), hs-add list+string+number polymorphic, hs-starts/ends-with-ic for case-insensitive comparison. DOM mock: mkStyle() with setProperty/getPropertyValue, fndAll.item(). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -21,8 +21,9 @@ function setStepLimit(n) { K.setStepLimit(n); }
|
||||
function resetStepCount() { K.resetStepCount(); }
|
||||
|
||||
// ─── DOM mock ──────────────────────────────────────────────────
|
||||
function mkStyle() { const s={}; s.setProperty=function(p,v){s[p]=v;}; s.getPropertyValue=function(p){return s[p]||'';}; s.removeProperty=function(p){delete s[p];}; return s; }
|
||||
class El {
|
||||
constructor(t) { this.tagName=t.toUpperCase(); this.nodeName=this.tagName; this.nodeType=1; this.id=''; this.className=''; this.classList=new CL(this); this.style={}; this.attributes={}; this.children=[]; this.childNodes=[]; this.parentElement=null; this.parentNode=null; this.textContent=''; this.innerHTML=''; this._listeners={}; this.dataset={}; this.open=false; this.value=''; this.checked=false; this.disabled=false; this.type=''; this.name=''; this.selectedIndex=-1; this.options=[]; }
|
||||
constructor(t) { this.tagName=t.toUpperCase(); this.nodeName=this.tagName; this.nodeType=1; this.id=''; this.className=''; this.classList=new CL(this); this.style=mkStyle(); this.attributes={}; this.children=[]; this.childNodes=[]; this.parentElement=null; this.parentNode=null; this.textContent=''; this.innerHTML=''; this._listeners={}; this.dataset={}; this.open=false; this.value=''; this.checked=false; this.disabled=false; this.type=''; this.name=''; this.selectedIndex=-1; this.options=[]; }
|
||||
setAttribute(n,v) { this.attributes[n]=String(v); if(n==='id')this.id=v; if(n==='class'){this.className=v;this.classList._sync(v);} if(n==='value')this.value=v; if(n==='disabled')this.disabled=true; }
|
||||
getAttribute(n) { return this.attributes[n]!==undefined?this.attributes[n]:null; }
|
||||
removeAttribute(n) { delete this.attributes[n]; if(n==='disabled')this.disabled=false; }
|
||||
@@ -39,7 +40,7 @@ class El {
|
||||
closest(s) { let e=this; while(e){if(mt(e,s))return e; e=e.parentElement;} return null; }
|
||||
matches(s) { return mt(this,s); }
|
||||
contains(o) { if(o===this)return true; for(const c of this.children)if(c===o||c.contains(o))return true; return false; }
|
||||
cloneNode(d) { const e=new El(this.tagName.toLowerCase()); Object.assign(e.attributes,this.attributes); e.id=this.id; e.className=this.className; e.classList._sync(this.className); Object.assign(e.style,this.style); e.textContent=this.textContent; e.innerHTML=this.innerHTML; e.value=this.value; if(d)for(const c of this.children)e.appendChild(c.cloneNode(true)); return e; }
|
||||
cloneNode(d) { const e=new El(this.tagName.toLowerCase()); Object.assign(e.attributes,this.attributes); e.id=this.id; e.className=this.className; e.classList._sync(this.className); for(const k of Object.keys(this.style)){if(typeof this.style[k]!=='function')e.style[k]=this.style[k];} e.textContent=this.textContent; e.innerHTML=this.innerHTML; e.value=this.value; if(d)for(const c of this.children)e.appendChild(c.cloneNode(true)); return e; }
|
||||
focus(){} blur(){} click(){this.dispatchEvent(new Ev('click',{bubbles:true}));} remove(){if(this.parentElement)this.parentElement.removeChild(this);}
|
||||
_syncText() {
|
||||
// Sync textContent from children
|
||||
@@ -149,7 +150,7 @@ function mt(e,s) {
|
||||
return e.tagName.toLowerCase() === s.toLowerCase();
|
||||
}
|
||||
function fnd(e,s) { for(const c of(e.children||[])){if(mt(c,s))return c;const f=fnd(c,s);if(f)return f;} return null; }
|
||||
function fndAll(e,s) { const r=[];for(const c of(e.children||[])){if(mt(c,s))r.push(c);r.push(...fndAll(c,s));}return r; }
|
||||
function fndAll(e,s) { const r=[];for(const c of(e.children||[])){if(mt(c,s))r.push(c);r.push(...fndAll(c,s));}r.item=function(i){return r[i]||null;};return r; }
|
||||
|
||||
const _body = new El('body');
|
||||
const _html = new El('html');
|
||||
|
||||
Reference in New Issue
Block a user