capybara-simulated 0.1.0 → 0.2.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.
@@ -3061,22 +3061,6 @@
3061
3061
  else n._attrs.checked = "";
3062
3062
  }
3063
3063
  __name(toggleChecked, "toggleChecked");
3064
- function formNamedAccess(form) {
3065
- if (form._namedAccessProxy) return form._namedAccessProxy;
3066
- const proxy = new Proxy(form, {
3067
- get(target, key) {
3068
- if (key in target) return target[key];
3069
- if (typeof key !== "string") return target[key];
3070
- for (const f of target.elements || []) {
3071
- if (f._attrs && (f._attrs.name === key || f._attrs.id === key)) return f;
3072
- }
3073
- return void 0;
3074
- }
3075
- });
3076
- form._namedAccessProxy = proxy;
3077
- return proxy;
3078
- }
3079
- __name(formNamedAccess, "formNamedAccess");
3080
3064
  function checkedRadioInGroup(n) {
3081
3065
  const name = n._attrs.name;
3082
3066
  if (!name) return n._attrs.checked != null ? n : null;
@@ -3290,7 +3274,7 @@
3290
3274
  event.target = event._csimRetargets.has(node) ? event._csimRetargets.get(node) : event._csimTopRetarget;
3291
3275
  }
3292
3276
  if (!capture && node._attrs && !event._immediatePropagationStopped) {
3293
- const attrName = "on" + event.type;
3277
+ const attrName = "on" + event.type.toLowerCase();
3294
3278
  const propHandler = typeof node[attrName] === "function" ? node[attrName] : null;
3295
3279
  const attrVal = propHandler ? null : node._attrs[attrName];
3296
3280
  let handler = propHandler;
@@ -3535,6 +3519,18 @@
3535
3519
  });
3536
3520
  }
3537
3521
  __name(fireCEDisconnect, "fireCEDisconnect");
3522
+ function fireCEMoveReactions(subtree) {
3523
+ walk(subtree, (el) => {
3524
+ if (!registry.has(el._tag)) return;
3525
+ if (typeof el.connectedMoveCallback === "function") {
3526
+ fireCEHook(el, "connectedMoveCallback");
3527
+ } else {
3528
+ fireCEHook(el, "disconnectedCallback");
3529
+ fireCEHook(el, "connectedCallback");
3530
+ }
3531
+ });
3532
+ }
3533
+ __name(fireCEMoveReactions, "fireCEMoveReactions");
3538
3534
  globalThis.customElements = customElements;
3539
3535
 
3540
3536
  // lib/capybara/simulated/js/src/html-parser.js
@@ -3681,7 +3677,7 @@
3681
3677
  ]);
3682
3678
  var P_SCOPE_BOUNDARY = /* @__PURE__ */ new Set(["applet", "caption", "html", "table", "td", "th", "marquee", "object", "template", "button"]);
3683
3679
  var DOCTYPE_RE = /^\s*<!doctype\s+([^\s>]+)(?:\s+(?:public\s+("[^"]*"|'[^']*')(?:\s+("[^"]*"|'[^']*'))?|system\s+("[^"]*"|'[^']*')))?[^>]*>/i;
3684
- function installHtmlParser({ Document: Document2, Element: Element2, Text: Text2, Comment: Comment2, DocumentFragment: DocumentFragment2, DocumentType: DocumentType2 }) {
3680
+ function installHtmlParser({ Document: Document2, Element: Element2, Text: Text2, Comment: Comment2, DocumentFragment: DocumentFragment2, DocumentType: DocumentType2, createHtmlPageDocument: createHtmlPageDocument2, registerNamedAccess: registerNamedAccess2 }) {
3685
3681
  const unquote = /* @__PURE__ */ __name((s) => s == null ? "" : s.slice(1, -1), "unquote");
3686
3682
  const HTML_NS_P = "http://www.w3.org/1999/xhtml";
3687
3683
  const SVG_NS_P = "http://www.w3.org/2000/svg";
@@ -3690,7 +3686,7 @@
3690
3686
  const XML_NS_P = "http://www.w3.org/XML/1998/namespace";
3691
3687
  const XMLNS_NS_P = "http://www.w3.org/2000/xmlns/";
3692
3688
  function parseDocument2(html) {
3693
- const doc = new Document2();
3689
+ const doc = createHtmlPageDocument2(false);
3694
3690
  const dt = DocumentType2 && DOCTYPE_RE.exec(html);
3695
3691
  if (dt) {
3696
3692
  const node = new DocumentType2(dt[1], unquote(dt[2]), unquote(dt[3] || dt[4]), doc);
@@ -3698,7 +3694,6 @@
3698
3694
  doc._children.push(node);
3699
3695
  }
3700
3696
  const root = new Element2("html");
3701
- doc.documentElement = root;
3702
3697
  root._parent = doc;
3703
3698
  doc._children.push(root);
3704
3699
  const head = new Element2("head");
@@ -3976,7 +3971,10 @@
3976
3971
  if (fa) (el._attrNS || (el._attrNS = {}))[fa.key] = fa.meta;
3977
3972
  continue;
3978
3973
  }
3979
- el._attrs[asciiLowerAttr(m[1])] = decodeEntities(v);
3974
+ const k = asciiLowerAttr(m[1]);
3975
+ const dv = decodeEntities(v);
3976
+ el._attrs[k] = dv;
3977
+ if (k === "id" || k === "name") registerNamedAccess2(el, k, dv);
3980
3978
  }
3981
3979
  }
3982
3980
  __name(applyAttributes, "applyAttributes");
@@ -4645,6 +4643,16 @@
4645
4643
  } catch (_) {
4646
4644
  globalThis.document = void 0;
4647
4645
  }
4646
+ try {
4647
+ delete globalThis.open;
4648
+ } catch (_) {
4649
+ globalThis.open = void 0;
4650
+ }
4651
+ try {
4652
+ delete globalThis.opener;
4653
+ } catch (_) {
4654
+ globalThis.opener = void 0;
4655
+ }
4648
4656
  globalThis.WorkerGlobalScope = globalThis.WorkerGlobalScope || /* @__PURE__ */ __name(function WorkerGlobalScope() {
4649
4657
  }, "WorkerGlobalScope");
4650
4658
  globalThis.DedicatedWorkerGlobalScope = globalThis.DedicatedWorkerGlobalScope || /* @__PURE__ */ __name(function DedicatedWorkerGlobalScope() {
@@ -6267,7 +6275,13 @@
6267
6275
  // lib/capybara/simulated/js/src/xml-parser.js
6268
6276
  var XML_NS = "http://www.w3.org/XML/1998/namespace";
6269
6277
  var XMLNS_NS = "http://www.w3.org/2000/xmlns/";
6278
+ var PARSERERROR_NS = "http://www.mozilla.org/newlayout/xml/parsererror.xml";
6270
6279
  var isWs = /* @__PURE__ */ __name((c) => c === " " || c === " " || c === "\n" || c === "\r" || c === "\f", "isWs");
6280
+ var isNCName = /* @__PURE__ */ __name((s) => /^[A-Za-z_][\w.\-]*$/.test(s), "isNCName");
6281
+ var isQName = /* @__PURE__ */ __name((s) => {
6282
+ const c = s.indexOf(":");
6283
+ return c === -1 ? isNCName(s) : isNCName(s.slice(0, c)) && isNCName(s.slice(c + 1));
6284
+ }, "isQName");
6271
6285
  function findTagEnd(s, lt) {
6272
6286
  let q = null;
6273
6287
  for (let i = lt + 1; i < s.length; i++) {
@@ -6283,6 +6297,7 @@
6283
6297
  function parseTag(inner) {
6284
6298
  let i = 0;
6285
6299
  const n = inner.length;
6300
+ let err = false;
6286
6301
  while (i < n && isWs(inner[i])) i++;
6287
6302
  let nameEnd = i;
6288
6303
  while (nameEnd < n && !isWs(inner[nameEnd])) nameEnd++;
@@ -6292,30 +6307,35 @@
6292
6307
  while (i < n) {
6293
6308
  while (i < n && (isWs(inner[i]) || inner[i] === "/")) i++;
6294
6309
  if (i >= n) break;
6310
+ if (inner[i] === "=") {
6311
+ err = true;
6312
+ break;
6313
+ }
6295
6314
  let ae = i;
6296
6315
  while (ae < n && !isWs(inner[ae]) && inner[ae] !== "=") ae++;
6297
6316
  const aname = inner.slice(i, ae);
6298
6317
  i = ae;
6299
6318
  while (i < n && isWs(inner[i])) i++;
6300
- let avalue = "";
6301
- if (inner[i] === "=") {
6302
- i++;
6303
- while (i < n && isWs(inner[i])) i++;
6304
- const q = inner[i];
6305
- if (q === '"' || q === "'") {
6306
- const end = inner.indexOf(q, i + 1);
6307
- avalue = end === -1 ? inner.slice(i + 1) : inner.slice(i + 1, end);
6308
- i = end === -1 ? n : end + 1;
6309
- } else {
6310
- let ve = i;
6311
- while (ve < n && !isWs(inner[ve])) ve++;
6312
- avalue = inner.slice(i, ve);
6313
- i = ve;
6314
- }
6319
+ if (inner[i] !== "=") {
6320
+ err = true;
6321
+ break;
6322
+ }
6323
+ i++;
6324
+ while (i < n && isWs(inner[i])) i++;
6325
+ const q = inner[i];
6326
+ if (q !== '"' && q !== "'") {
6327
+ err = true;
6328
+ break;
6315
6329
  }
6316
- if (aname) attrs.push({ name: aname, value: decodeEntities(avalue) });
6330
+ const end = inner.indexOf(q, i + 1);
6331
+ if (end === -1) {
6332
+ err = true;
6333
+ break;
6334
+ }
6335
+ attrs.push({ name: aname, value: decodeEntities(inner.slice(i + 1, end)) });
6336
+ i = end + 1;
6317
6337
  }
6318
- return { name, attrs };
6338
+ return { name, attrs, err };
6319
6339
  }
6320
6340
  __name(parseTag, "parseTag");
6321
6341
  function installXmlParser({ Element: Element2, Text: Text2, Comment: Comment2, ProcessingInstruction: ProcessingInstruction2, CDATASection: CDATASection2, DocumentType: DocumentType2 }) {
@@ -6342,6 +6362,7 @@
6342
6362
  const stack = [];
6343
6363
  const nsStack = [{ xml: XML_NS }];
6344
6364
  let i = 0;
6365
+ let err = false;
6345
6366
  const append = /* @__PURE__ */ __name((node) => {
6346
6367
  if (stack.length) {
6347
6368
  node._parent = stack[stack.length - 1];
@@ -6381,30 +6402,58 @@
6381
6402
  }
6382
6403
  } else if (s[i + 1] === "/") {
6383
6404
  const end = s.indexOf(">", i);
6384
- if (stack.length) {
6405
+ const raw = end === -1 ? s.slice(i + 2) : s.slice(i + 2, end);
6406
+ const endName = raw.replace(/\s+$/, "");
6407
+ if (end === -1 || /^\s/.test(raw) || !endName) err = true;
6408
+ if (stack.length === 0) {
6409
+ err = true;
6410
+ } else {
6411
+ const top2 = stack[stack.length - 1];
6412
+ const openName = top2._prefix ? top2._prefix + ":" + top2._localName : top2._localName;
6413
+ if (endName !== openName) err = true;
6385
6414
  stack.pop();
6386
6415
  nsStack.pop();
6387
6416
  }
6388
6417
  i = end === -1 ? n : end + 1;
6389
6418
  } else {
6419
+ if (isWs(s[i + 1])) err = true;
6390
6420
  const end = findTagEnd(s, i);
6391
6421
  if (end === -1) {
6422
+ err = true;
6392
6423
  i = n;
6393
6424
  break;
6394
6425
  }
6395
6426
  let inner = s.slice(i + 1, end);
6396
6427
  const selfClose = /\/\s*$/.test(inner);
6397
6428
  if (selfClose) inner = inner.replace(/\/\s*$/, "");
6398
- const { name, attrs } = parseTag(inner);
6429
+ const { name, attrs, err: tagErr } = parseTag(inner);
6430
+ if (tagErr || !isQName(name)) err = true;
6399
6431
  i = end + 1;
6400
6432
  const scope = Object.assign({}, nsStack[nsStack.length - 1]);
6401
6433
  for (const a of attrs) {
6402
- if (a.name === "xmlns") scope[""] = a.value || null;
6403
- else if (a.name.slice(0, 6) === "xmlns:") scope[a.name.slice(6)] = a.value || null;
6434
+ if (a.name === "xmlns") {
6435
+ scope[""] = a.value || null;
6436
+ } else if (a.name.slice(0, 6) === "xmlns:") {
6437
+ const p = a.name.slice(6);
6438
+ if (!isNCName(p) || p === "xmlns") err = true;
6439
+ else scope[p] = a.value || null;
6440
+ }
6441
+ }
6442
+ for (const a of attrs) {
6443
+ if (a.name === "xmlns" || a.name.slice(0, 6) === "xmlns:") continue;
6444
+ if (!isQName(a.name)) {
6445
+ err = true;
6446
+ continue;
6447
+ }
6448
+ const ac = a.name.indexOf(":");
6449
+ if (ac !== -1 && a.name.slice(0, ac) !== "xml" && !(a.name.slice(0, ac) in scope)) {
6450
+ err = true;
6451
+ }
6404
6452
  }
6405
6453
  const colon = name.indexOf(":");
6406
6454
  const prefix = colon === -1 ? null : name.slice(0, colon);
6407
6455
  const localName = colon === -1 ? name : name.slice(colon + 1);
6456
+ if (prefix && prefix !== "xml" && !(prefix in scope)) err = true;
6408
6457
  const ns = prefix ? scope[prefix] || null : scope[""] || null;
6409
6458
  const el = new Element2(name);
6410
6459
  el._localName = localName;
@@ -6438,6 +6487,16 @@
6438
6487
  i = j;
6439
6488
  }
6440
6489
  }
6490
+ if (stack.length > 0) err = true;
6491
+ if (err) {
6492
+ const pe = new Element2("parsererror");
6493
+ pe._localName = "parsererror";
6494
+ pe._ns = PARSERERROR_NS;
6495
+ const msg = new Text2("XML parsing error");
6496
+ msg._parent = pe;
6497
+ pe._children.push(msg);
6498
+ return [pe];
6499
+ }
6441
6500
  return top;
6442
6501
  }
6443
6502
  __name(parseXml2, "parseXml");
@@ -7071,9 +7130,13 @@
7071
7130
  this.nodeType = NODE_ELEMENT;
7072
7131
  this._ownerDoc = null;
7073
7132
  }
7074
- getRootNode(_options) {
7133
+ getRootNode(options) {
7134
+ const composed = !!(options && options.composed);
7075
7135
  let cur = this;
7076
- while (cur._parent) cur = cur._parent;
7136
+ while (cur._parent) {
7137
+ if (!composed && cur._isShadowRoot) break;
7138
+ cur = cur._parent;
7139
+ }
7077
7140
  return cur;
7078
7141
  }
7079
7142
  // Per DOM, `nodeValue` is null for every node type except Attr (its value)
@@ -7430,7 +7493,6 @@
7430
7493
  copy._children.push(cc);
7431
7494
  }
7432
7495
  if (copy.nodeType === NODE_DOC) {
7433
- copy.documentElement = copy._children.find((c) => c.nodeType === NODE_ELEMENT) || null;
7434
7496
  for (const c of copy._children) walkSubtree(c, (n) => {
7435
7497
  n._ownerDoc = copy;
7436
7498
  });
@@ -7846,12 +7908,14 @@
7846
7908
  const prevSib = idx > 0 ? this._children[idx - 1] : null;
7847
7909
  const nextSib = idx < this._children.length ? this._children[idx] : null;
7848
7910
  this._children.splice(idx, 0, ...moved);
7911
+ liveRangesOnInsert(this, idx, moved.length);
7849
7912
  const connected = isConnected(this);
7850
7913
  for (const c of moved) {
7851
7914
  c._parent = this;
7852
7915
  registerSubtree(c);
7853
7916
  }
7854
7917
  recordChildList(this, moved.slice(), [], prevSib, nextSib);
7918
+ if (this._tag === "script") globalThis.__csimScriptChildrenChanged(this);
7855
7919
  if (connected) for (const c of moved) globalThis.__csimFireCEConnect(c);
7856
7920
  for (const c of moved) askForReset(c);
7857
7921
  return frag;
@@ -7868,9 +7932,11 @@
7868
7932
  const prevSib = i > 0 ? this._children[i - 1] : null;
7869
7933
  const nextSib = i + 1 < this._children.length ? this._children[i + 1] : null;
7870
7934
  for (const c of nodes) adoptIntoParent(this, c);
7935
+ liveRangesOnRemove(this, old, i);
7871
7936
  old._parent = null;
7872
7937
  unregisterSubtree(old);
7873
7938
  this._children.splice(i, 1, ...nodes);
7939
+ liveRangesOnInsert(this, i, nodes.length);
7874
7940
  for (const c of nodes) {
7875
7941
  c._parent = this;
7876
7942
  registerSubtree(c);
@@ -7888,9 +7954,12 @@
7888
7954
  if (child && child.nodeType === NODE_FRAGMENT) return this._insertFragmentChildren(child, null);
7889
7955
  adoptIntoParent(this, child);
7890
7956
  child._parent = this;
7957
+ const insertIndex = this._children.length;
7891
7958
  this._children.push(child);
7959
+ liveRangesOnInsert(this, insertIndex, 1);
7892
7960
  registerSubtree(child);
7893
7961
  recordChildList(this, [child], []);
7962
+ if (this._tag === "script") globalThis.__csimScriptChildrenChanged(this);
7894
7963
  if (isConnected(this)) globalThis.__csimFireCEConnect(child);
7895
7964
  askForReset(child);
7896
7965
  return child;
@@ -7908,9 +7977,14 @@
7908
7977
  const prevSib = i > 0 ? this._children[i - 1] : null;
7909
7978
  const nextSib = i + 1 < this._children.length ? this._children[i + 1] : null;
7910
7979
  const wasConnected = isConnected(this);
7980
+ nodeIteratorPreRemove(child);
7981
+ liveRangesOnRemove(this, child, i);
7911
7982
  this._children.splice(i, 1);
7912
7983
  child._parent = null;
7913
7984
  unregisterSubtree(child);
7985
+ const doc = globalThis.document;
7986
+ const ae = doc && doc._activeElement;
7987
+ if (ae && (ae === child || nodeContains(child, ae))) doc._activeElement = null;
7914
7988
  recordChildList(this, [], [child], prevSib, nextSib);
7915
7989
  if (wasConnected) fireCEDisconnect(child);
7916
7990
  return child;
@@ -7930,8 +8004,10 @@
7930
8004
  if (i < 0) return this.appendChild(child);
7931
8005
  child._parent = this;
7932
8006
  this._children.splice(i, 0, child);
8007
+ liveRangesOnInsert(this, i, 1);
7933
8008
  registerSubtree(child);
7934
8009
  recordChildList(this, [child], []);
8010
+ if (this._tag === "script") globalThis.__csimScriptChildrenChanged(this);
7935
8011
  if (isConnected(this)) globalThis.__csimFireCEConnect(child);
7936
8012
  askForReset(child);
7937
8013
  return child;
@@ -7959,9 +8035,11 @@
7959
8035
  const wasConnected = isConnected(this);
7960
8036
  adoptIntoParent(this, neu);
7961
8037
  const j = this._children.indexOf(old);
8038
+ liveRangesOnRemove(this, old, j);
7962
8039
  neu._parent = this;
7963
8040
  old._parent = null;
7964
8041
  this._children[j] = neu;
8042
+ liveRangesOnInsert(this, j, 1);
7965
8043
  unregisterSubtree(old);
7966
8044
  registerSubtree(neu);
7967
8045
  recordChildList(this, [neu], [old]);
@@ -8056,6 +8134,7 @@
8056
8134
  }
8057
8135
  _setData(next) {
8058
8136
  const prev = this._data;
8137
+ liveRangesOnReplaceData(this, 0, prev.length, next.length);
8059
8138
  if (prev === next) return;
8060
8139
  this._data = next;
8061
8140
  recordCharacterData(this, prev);
@@ -8118,7 +8197,9 @@
8118
8197
  const len = prev.length;
8119
8198
  if (offset > len) throw new globalThis.DOMException("The offset is greater than the data length.", "IndexSizeError");
8120
8199
  if (offset + count > len) count = len - offset;
8121
- this._data = prev.slice(0, offset) + String(data) + prev.slice(offset + count);
8200
+ const str = String(data);
8201
+ liveRangesOnReplaceData(this, offset, count, str.length);
8202
+ this._data = prev.slice(0, offset) + str + prev.slice(offset + count);
8122
8203
  recordCharacterData(this, prev);
8123
8204
  }
8124
8205
  };
@@ -8146,19 +8227,24 @@
8146
8227
  // install chain on that template (including `{{on "click"}}` on
8147
8228
  // search-result anchors).
8148
8229
  splitText(offset) {
8230
+ offset = offset >>> 0;
8149
8231
  const len = this._data.length;
8150
- if (offset < 0 || offset > len) {
8232
+ if (offset > len) {
8151
8233
  throw new globalThis.DOMException("Index or size is negative or greater than the allowed amount", "IndexSizeError");
8152
8234
  }
8153
- const suffix = this._data.substring(offset);
8154
- const newNode = new this.constructor(suffix);
8235
+ const count = len - offset;
8236
+ const newNode = new this.constructor(this._data.substring(offset));
8155
8237
  newNode._ownerDoc = this._ownerDoc;
8156
- if (this._parent) {
8157
- const idx = this._parent._children.indexOf(this);
8158
- this._parent._children.splice(idx + 1, 0, newNode);
8159
- newNode._parent = this._parent;
8238
+ const parent = this._parent;
8239
+ if (parent) {
8240
+ const idx = parent._children.indexOf(this);
8241
+ parent._children.splice(idx + 1, 0, newNode);
8242
+ newNode._parent = parent;
8243
+ registerSubtree(newNode);
8244
+ recordChildList(parent, [newNode], []);
8245
+ liveRangesOnSplit(this, offset, newNode, parent, idx);
8160
8246
  }
8161
- this.data = this._data.substring(0, offset);
8247
+ this._replaceData(offset, count, "");
8162
8248
  return newNode;
8163
8249
  }
8164
8250
  // DOM `Text.wholeText`: the concatenated data of this node and its contiguous
@@ -8465,6 +8551,7 @@
8465
8551
  this._vtGen = -1;
8466
8552
  this._vtCV = -1;
8467
8553
  this._attrsColl = null;
8554
+ if (this._tag === "form") Object.setPrototypeOf(this, FormNamedProto);
8468
8555
  }
8469
8556
  _cloneShell() {
8470
8557
  const e = new _Element(this._tag);
@@ -8473,6 +8560,7 @@
8473
8560
  e._ns = this._ns;
8474
8561
  e._prefix = this._prefix;
8475
8562
  e._localName = this._localName;
8563
+ if (this._tag === "script" && this._csimRan) e._csimRan = true;
8476
8564
  return e;
8477
8565
  }
8478
8566
  // tagName / nodeName: the qualified name, ASCII-uppercased only for an
@@ -8521,6 +8609,61 @@
8521
8609
  }
8522
8610
  Object.defineProperty(this, "content", { value: v, writable: true, configurable: true, enumerable: true });
8523
8611
  }
8612
+ // `HTMLStyleElement.sheet` — the CSSStyleSheet associated with a connected
8613
+ // `<style>` (CSSOM). It exists once the element is in a document and reflects
8614
+ // the element's current text content, so an earlier-inserted script can
8615
+ // observe a later-inserted `<style>` already applied (cssRules track the text
8616
+ // live). Disconnected → null; `<link>` sheets (which need the fetched
8617
+ // resource) are not modelled here. Created lazily and cached for stable identity.
8618
+ get sheet() {
8619
+ if (this._tag === "style") {
8620
+ if (!this.isConnected) {
8621
+ this._sheet = null;
8622
+ return null;
8623
+ }
8624
+ const type = (this._attrs.type || "").toLowerCase();
8625
+ if (type && type !== "text/css") {
8626
+ this._sheet = null;
8627
+ return null;
8628
+ }
8629
+ if (!this._sheet) {
8630
+ this._sheet = new globalThis.CSSStyleSheet();
8631
+ this._sheet.ownerNode = this;
8632
+ }
8633
+ this._sheet.replaceSync(this.textContent || "");
8634
+ return this._sheet;
8635
+ }
8636
+ if (this._tag === "link") {
8637
+ const rel = (this._attrs.rel || "").toLowerCase().split(/\s+/);
8638
+ const href = this._attrs.href;
8639
+ if (!this.isConnected || !rel.includes("stylesheet") || !href) {
8640
+ this._sheet = null;
8641
+ return null;
8642
+ }
8643
+ if (!this._sheet) {
8644
+ this._sheet = new globalThis.CSSStyleSheet();
8645
+ this._sheet.ownerNode = this;
8646
+ this._sheet.href = href;
8647
+ let css = "";
8648
+ const dataCss = /^data:text\/css[^,]*,(.*)$/is.exec(href);
8649
+ if (dataCss) {
8650
+ try {
8651
+ css = decodeURIComponent(dataCss[1]);
8652
+ } catch (_) {
8653
+ css = dataCss[1];
8654
+ }
8655
+ } else {
8656
+ try {
8657
+ css = globalThis.__csimExternalAsset(href) || "";
8658
+ } catch (_) {
8659
+ }
8660
+ }
8661
+ this._sheet.replaceSync(css);
8662
+ }
8663
+ return this._sheet;
8664
+ }
8665
+ return void 0;
8666
+ }
8524
8667
  // `<dialog>` HTML interface — show() / showModal() / close() per
8525
8668
  // HTMLDialogElement. Turbo's confirm flow uses this: opens
8526
8669
  // `<dialog id="turbo-confirm">` via `showModal()`, waits for the
@@ -8589,6 +8732,7 @@
8589
8732
  const old = this._attrs[n];
8590
8733
  const next = String(value);
8591
8734
  this._attrs[n] = next;
8735
+ if ((n === "id" || n === "name") && next) registerNamedAccess(this, n, next);
8592
8736
  if ((n === "src" || n === "srcdoc") && (this._tag === "iframe" || this._tag === "frame") && old !== next) {
8593
8737
  const oldRealmId = this._frameRealmId;
8594
8738
  this._frameWindow = null;
@@ -8621,6 +8765,7 @@
8621
8765
  const old = this._attrs[key];
8622
8766
  const next = String(value);
8623
8767
  this._attrs[key] = next;
8768
+ if (rns === null && (localName === "id" || localName === "name") && next) registerNamedAccess(this, localName, next);
8624
8769
  if (rns !== null || prefix !== null || key !== qn) {
8625
8770
  (this._attrNS || (this._attrNS = {}))[key] = { ns: rns, prefix, localName };
8626
8771
  } else if (this._attrNS) {
@@ -8690,6 +8835,7 @@
8690
8835
  _setAttrNodeValue(key, value) {
8691
8836
  const old = this._attrs[key];
8692
8837
  this._attrs[key] = value;
8838
+ if ((key === "id" || key === "name") && value) registerNamedAccess(this, key, value);
8693
8839
  recordAttrMutation(this, key, old == null ? null : old);
8694
8840
  if (old !== value) fireAttrChangedCallback(this, key, old == null ? null : old, value, _Element);
8695
8841
  }
@@ -8711,6 +8857,7 @@
8711
8857
  const key = hasNs ? this._attrKeyByNS(attr._ns, attr._localName) || freshAttrKey(this, qn) : asciiLower2(qn);
8712
8858
  const old = this._attrs[key];
8713
8859
  this._attrs[key] = attr._value;
8860
+ if (!hasNs && (key === "id" || key === "name") && attr._value) registerNamedAccess(this, key, attr._value);
8714
8861
  if (hasNs) (this._attrNS || (this._attrNS = {}))[key] = { ns: attr._ns, prefix: attr._prefix, localName: attr._localName };
8715
8862
  else if (this._attrNS) delete this._attrNS[key];
8716
8863
  attr._ownerElement = this;
@@ -9100,8 +9247,7 @@
9100
9247
  // `this.form` the onclick threw and the columns never moved.
9101
9248
  get form() {
9102
9249
  if (!FORM_ASSOCIATED_TAGS.has(this._tag)) return void 0;
9103
- const form = formForControl(this);
9104
- return form ? formNamedAccess(form) : null;
9250
+ return formForControl(this) || null;
9105
9251
  }
9106
9252
  // Form-control IDL attributes — expose the pair-of-attr-and-IDL
9107
9253
  // shape so JS like `input.value = 'x'` / `input.checked = true`
@@ -10650,6 +10796,93 @@
10650
10796
  return globalThis.customElements || null;
10651
10797
  }
10652
10798
  });
10799
+ var FormNamedProto = Object.create(Element.prototype);
10800
+ var FORM_NAMED_PROPS = /* @__PURE__ */ new Set();
10801
+ var FORM_NAMED_TAGS = /* @__PURE__ */ new Set(["input", "select", "textarea", "button", "fieldset", "object"]);
10802
+ function formNamedLookup(form, name) {
10803
+ if (!form || form._tag !== "form") return void 0;
10804
+ const els = form.elements;
10805
+ if (els) for (const c of els) {
10806
+ if (c._attrs && (c._attrs.name === name || c._attrs.id === name)) return c;
10807
+ }
10808
+ return void 0;
10809
+ }
10810
+ __name(formNamedLookup, "formNamedLookup");
10811
+ function registerFormName(el, value) {
10812
+ if (!value || !FORM_NAMED_TAGS.has(el._tag)) return;
10813
+ if (FORM_NAMED_PROPS.has(value)) return;
10814
+ FORM_NAMED_PROPS.add(value);
10815
+ if (value in FormNamedProto) return;
10816
+ Object.defineProperty(FormNamedProto, value, {
10817
+ configurable: true,
10818
+ enumerable: false,
10819
+ get() {
10820
+ return formNamedLookup(this, value);
10821
+ },
10822
+ // Assigning `form.<name> = x` creates an OWN property that shadows the
10823
+ // named getter — matching browser LegacyPlatformObject semantics (named
10824
+ // properties are configurable). Without a setter, strict-mode assignment
10825
+ // to a getter-only property THROWS; jQuery stores its private-data expando
10826
+ // directly on the element (`form[expando] = cache`) and also parks its
10827
+ // marker on `id`/`name` during scoped queries, so a getter-only named prop
10828
+ // would break every form jQuery binds an event to or calls `.data()` on.
10829
+ set(v) {
10830
+ Object.defineProperty(this, value, { value: v, writable: true, enumerable: true, configurable: true });
10831
+ }
10832
+ });
10833
+ }
10834
+ __name(registerFormName, "registerFormName");
10835
+ var WINDOW_NAMED_PROPS = /* @__PURE__ */ new Set();
10836
+ var WINDOW_NAME_VALUES = /* @__PURE__ */ new Set();
10837
+ var WINDOW_NAME_TAGS = /* @__PURE__ */ new Set(["a", "applet", "area", "embed", "form", "frameset", "frame", "iframe", "img", "object"]);
10838
+ var WindowNamedProps = Object.create(Object.getPrototypeOf(globalThis));
10839
+ if (!globalThis.__csimWindowNamedProps) {
10840
+ globalThis.__csimWindowNamedProps = WindowNamedProps;
10841
+ Object.setPrototypeOf(globalThis, WindowNamedProps);
10842
+ }
10843
+ function windowNamedLookup(name) {
10844
+ const doc = globalThis.document;
10845
+ if (!doc) return void 0;
10846
+ const byId2 = doc.getElementById && doc.getElementById(name);
10847
+ if (byId2) return byId2;
10848
+ if (!WINDOW_NAME_VALUES.has(name)) return void 0;
10849
+ let found;
10850
+ walkSubtree(doc, (el) => {
10851
+ if (found || el.nodeType !== NODE_ELEMENT) return;
10852
+ if (WINDOW_NAME_TAGS.has(el._tag) && el._attrs && el._attrs.name === name) found = el;
10853
+ });
10854
+ return found;
10855
+ }
10856
+ __name(windowNamedLookup, "windowNamedLookup");
10857
+ function registerWindowName(el, attrName, value) {
10858
+ if (!value) return;
10859
+ if (attrName === "name") {
10860
+ if (!WINDOW_NAME_TAGS.has(el._tag)) return;
10861
+ WINDOW_NAME_VALUES.add(value);
10862
+ }
10863
+ if (WINDOW_NAMED_PROPS.has(value)) return;
10864
+ WINDOW_NAMED_PROPS.add(value);
10865
+ if (value in globalThis) return;
10866
+ Object.defineProperty(globalThis.__csimWindowNamedProps, value, {
10867
+ configurable: true,
10868
+ enumerable: false,
10869
+ get() {
10870
+ return windowNamedLookup(value);
10871
+ },
10872
+ // As with form named access, assignment shadows the getter with an own
10873
+ // property (configurable named properties); without a setter, strict-mode
10874
+ // `window.foo = x` for an id-named `foo` would throw.
10875
+ set(v) {
10876
+ Object.defineProperty(globalThis, value, { value: v, writable: true, enumerable: true, configurable: true });
10877
+ }
10878
+ });
10879
+ }
10880
+ __name(registerWindowName, "registerWindowName");
10881
+ function registerNamedAccess(el, attrName, value) {
10882
+ registerFormName(el, value);
10883
+ registerWindowName(el, attrName, value);
10884
+ }
10885
+ __name(registerNamedAccess, "registerNamedAccess");
10653
10886
  var DocumentFragment = class extends Node {
10654
10887
  static {
10655
10888
  __name(this, "DocumentFragment");
@@ -10847,7 +11080,95 @@
10847
11080
  for (const __h of GLOBAL_EVENT_HANDLER_ATTRS) {
10848
11081
  if (!(__h in Element.prototype)) Element.prototype[__h] = null;
10849
11082
  }
10850
- var Document = class _Document extends Node {
11083
+ var DOMImplementation = class {
11084
+ static {
11085
+ __name(this, "DOMImplementation");
11086
+ }
11087
+ constructor(doc) {
11088
+ this._doc = doc;
11089
+ }
11090
+ // Legacy: `hasFeature` always returns true (DOM §4.5.1).
11091
+ hasFeature() {
11092
+ return true;
11093
+ }
11094
+ // `createHTMLDocument(title)` — DOMParser shims and Turbo Drive's page-
11095
+ // snapshot logic both probe it. Returns a fresh Document with a minimal
11096
+ // `<!DOCTYPE html><html><head><title>X</title></head><body></body></html>`
11097
+ // skeleton; full HTML-spec construction (quirks-mode flag) is out of scope.
11098
+ createHTMLDocument(...args) {
11099
+ const d = new Document();
11100
+ const doctype = new DocumentType("html", "", "", d);
11101
+ doctype._parent = d;
11102
+ const html = new Element("html");
11103
+ const head = new Element("head");
11104
+ const body = new Element("body");
11105
+ html._children = newChildList([head, body]);
11106
+ head._parent = html;
11107
+ body._parent = html;
11108
+ html._parent = d;
11109
+ d._children = newChildList([doctype, html]);
11110
+ if (args.length > 0 && args[0] !== void 0) {
11111
+ const t = new Element("title");
11112
+ t._children = newChildList([Object.assign(new Text(String(args[0])), { _parent: t })]);
11113
+ t._parent = head;
11114
+ head._children.push(t);
11115
+ }
11116
+ d._contentType = "text/html";
11117
+ walkSubtree(d, (n) => {
11118
+ n._ownerDoc = d;
11119
+ });
11120
+ return d;
11121
+ }
11122
+ // createDocumentType(qualifiedName, publicId, systemId) — modern spec
11123
+ // validates only the name (a "valid doctype name"); no namespace checks.
11124
+ createDocumentType(qualifiedName, publicId, systemId) {
11125
+ const name = String(qualifiedName);
11126
+ if (!isValidDoctypeName(name)) {
11127
+ throw new globalThis.DOMException(
11128
+ `The qualified name '${name}' is not a valid doctype name.`,
11129
+ "InvalidCharacterError"
11130
+ );
11131
+ }
11132
+ return new DocumentType(name, publicId, systemId, this._doc);
11133
+ }
11134
+ // createDocument(namespace, qualifiedName, doctype) — a fresh XMLDocument with
11135
+ // an optional root element (from the validated qualifiedName) and an optional
11136
+ // doctype, in [doctype?, element?] order.
11137
+ createDocument(...args) {
11138
+ if (args.length < 2) {
11139
+ throw new TypeError("Failed to execute 'createDocument': 2 arguments required.");
11140
+ }
11141
+ const namespace = args[0], qualifiedName = args[1], doctype = args[2];
11142
+ if (doctype != null && !(doctype instanceof DocumentType)) {
11143
+ throw new TypeError("Failed to execute 'createDocument': parameter 3 is not of type 'DocumentType'.");
11144
+ }
11145
+ const ns = namespace == null || namespace === "" ? null : String(namespace);
11146
+ const qn = qualifiedName === null ? "" : String(qualifiedName);
11147
+ let rns = null, prefix = null, localName = null;
11148
+ if (qn !== "") ({ namespace: rns, prefix, localName } = validateAndExtract(ns, qn, "element"));
11149
+ const d = new XMLDocument();
11150
+ d._contentType = ns === HTML_NS3 ? "application/xhtml+xml" : ns === SVG_NS2 ? "image/svg+xml" : "application/xml";
11151
+ d._children = newChildList();
11152
+ d.readyState = "complete";
11153
+ if (doctype != null) {
11154
+ if (doctype._parent) {
11155
+ const i = doctype._parent._children.indexOf(doctype);
11156
+ if (i >= 0) doctype._parent._children.splice(i, 1);
11157
+ }
11158
+ doctype._parent = d;
11159
+ doctype._ownerDoc = d;
11160
+ d._children.push(doctype);
11161
+ }
11162
+ if (qn !== "") {
11163
+ const el = d._createElement(rns, prefix, localName);
11164
+ el._parent = d;
11165
+ d._children.push(el);
11166
+ }
11167
+ return d;
11168
+ }
11169
+ };
11170
+ globalThis.DOMImplementation = DOMImplementation;
11171
+ var Document = class extends Node {
10851
11172
  static {
10852
11173
  __name(this, "Document");
10853
11174
  }
@@ -10962,27 +11283,37 @@
10962
11283
  constructor() {
10963
11284
  super();
10964
11285
  this.nodeType = NODE_DOC;
10965
- this.readyState = "loading";
10966
- const html = new Element("html");
10967
- const head = new Element("head");
10968
- const body = new Element("body");
10969
- html._parent = this;
10970
- this._children.push(html);
10971
- head._parent = html;
10972
- html._children.push(head);
10973
- body._parent = html;
10974
- html._children.push(body);
10975
- this.documentElement = html;
11286
+ this.readyState = "complete";
11287
+ this._contentType = "application/xml";
11288
+ this._url = "about:blank";
11289
+ this._noBrowsingContext = true;
10976
11290
  for (const name of GLOBAL_EVENT_HANDLER_ATTRS) this[name] = null;
10977
11291
  }
11292
+ // The document element is the document's (single) element child — derived
11293
+ // from the tree rather than maintained as a field, so it stays correct after
11294
+ // any insert / remove (e.g. `new Document().appendChild(html)`), not just the
11295
+ // explicit parser / graft paths. A Document's child list is tiny (an optional
11296
+ // doctype + the root), so the scan is effectively free; the manual loop
11297
+ // avoids a per-access closure allocation on this hot getter.
11298
+ get documentElement() {
11299
+ const kids = this._children;
11300
+ for (let i = 0; i < kids.length; i++) {
11301
+ if (kids[i].nodeType === NODE_ELEMENT) return kids[i];
11302
+ }
11303
+ return null;
11304
+ }
10978
11305
  // jQuery's `mc(node)` helper resolves a node back to its window
10979
11306
  // via `doc.defaultView || doc.parentWindow`; without these the
10980
11307
  // offset / scroll path throws "Cannot read properties of
10981
11308
  // undefined (reading 'pageYOffset')".
10982
11309
  // The main document's window is the global; a nested (iframe) document
10983
11310
  // carries its own `_defaultView` (a frame-window proxy) set at load time.
11311
+ // A document with no browsing context (`new Document()`, createHTMLDocument,
11312
+ // createDocument) has no associated window — `defaultView` is null (DOM
11313
+ // §4.5.1). Returning the global here would splice the live window (and its
11314
+ // document) into a detached document's event path, cycling it unbounded.
10984
11315
  get defaultView() {
10985
- return this._defaultView || globalThis;
11316
+ return this._noBrowsingContext ? null : this._defaultView || globalThis;
10986
11317
  }
10987
11318
  get parentWindow() {
10988
11319
  return this.defaultView;
@@ -11003,15 +11334,14 @@
11003
11334
  return null;
11004
11335
  }
11005
11336
  // Cloning a Document yields a new EMPTY document of the same kind, carrying
11006
- // the content type — children are copied only on a deep clone (cloneNode
11007
- // handles that + sets documentElement). The base shell would re-run the
11008
- // constructor's html/head/body skeleton, leaving a shallow clone non-empty.
11337
+ // the content type and browsing-context-ness — children are copied only on a
11338
+ // deep clone (cloneNode handles that + sets documentElement).
11009
11339
  _cloneShell() {
11010
11340
  const d = new this.constructor();
11011
11341
  d._children = newChildList();
11012
- d.documentElement = null;
11013
11342
  d._contentType = this._contentType;
11014
- if (this._url) d._url = this._url;
11343
+ d._noBrowsingContext = this._noBrowsingContext;
11344
+ d._url = this._url;
11015
11345
  d.readyState = "complete";
11016
11346
  return d;
11017
11347
  }
@@ -11019,8 +11349,10 @@
11019
11349
  // searchParams.js reads `document.location.search`; without this
11020
11350
  // getter the call hits `undefined.search` and the whole bundle's
11021
11351
  // top-level module init aborts before the search-feed fetch fires.
11352
+ // A document with no browsing context (createHTMLDocument) has `location`
11353
+ // null; the main / frame documents return the live location object.
11022
11354
  get location() {
11023
- return globalThis.location;
11355
+ return this._noBrowsingContext ? null : globalThis.location;
11024
11356
  }
11025
11357
  set location(v) {
11026
11358
  globalThis.__locationAssign(String(v));
@@ -11257,7 +11589,9 @@
11257
11589
  // the live tree via `appendChild`. We give it just enough surface
11258
11590
  // for `appendChild` / `childNodes` to work.
11259
11591
  createDocumentFragment() {
11260
- return new DocumentFragment();
11592
+ const f = new DocumentFragment();
11593
+ f._ownerDoc = this;
11594
+ return f;
11261
11595
  }
11262
11596
  // `Document.createEvent(interfaceName)` — legacy DOM Level 2 API
11263
11597
  // still used by libraries that target older browsers (Trix's
@@ -11302,100 +11636,31 @@
11302
11636
  }
11303
11637
  }
11304
11638
  const dest = this;
11639
+ const oldDoc = node.ownerDocument;
11305
11640
  walkSubtree(node, (n) => {
11306
11641
  n._ownerDoc = dest;
11307
11642
  });
11643
+ const oldReg = oldDoc && oldDoc._liveRanges;
11644
+ if (oldReg && oldReg.size) {
11645
+ for (const r of [...oldReg]) {
11646
+ if (sameTreeContains(node, r.startContainer) || sameTreeContains(node, r.endContainer)) r._track();
11647
+ }
11648
+ }
11308
11649
  return node;
11309
11650
  }
11310
- // `document.implementation.createHTMLDocument(title)` — DOMParser
11311
- // shims and Turbo Drive page-snapshot logic both probe it. We
11312
- // return a fresh Document with a minimal `<html><head><title>X</title>
11313
- // </head><body></body></html>` skeleton; full HTML-spec
11314
- // construction (DOCTYPE / quirks-mode flag) is out of scope.
11651
+ // `document.implementation` — a per-document, cached `DOMImplementation`
11652
+ // (createHTMLDocument / createDocument / createDocumentType / hasFeature).
11653
+ // Cached so repeated reads return the same instance, and a real class so
11654
+ // `instanceof DOMImplementation` holds.
11315
11655
  get implementation() {
11316
- return {
11317
- createHTMLDocument: /* @__PURE__ */ __name((...args) => {
11318
- const d = new _Document();
11319
- const doctype = new DocumentType("html", "", "", d);
11320
- doctype._parent = d;
11321
- const html = new Element("html");
11322
- const head = new Element("head");
11323
- const body = new Element("body");
11324
- html._children = newChildList([head, body]);
11325
- head._parent = html;
11326
- body._parent = html;
11327
- d.documentElement = html;
11328
- html._parent = d;
11329
- d._children = newChildList([doctype, html]);
11330
- if (args.length > 0 && args[0] !== void 0) {
11331
- const t = new Element("title");
11332
- t._children = newChildList([Object.assign(new Text(String(args[0])), { _parent: t })]);
11333
- t._parent = head;
11334
- head._children.push(t);
11335
- }
11336
- walkSubtree(d, (n) => {
11337
- n._ownerDoc = d;
11338
- });
11339
- return d;
11340
- }, "createHTMLDocument"),
11341
- // createDocumentType(qualifiedName, publicId, systemId) — modern spec
11342
- // validates only the name (a "valid doctype name"); no namespace checks.
11343
- createDocumentType: /* @__PURE__ */ __name((qualifiedName, publicId, systemId) => {
11344
- const name = String(qualifiedName);
11345
- if (!isValidDoctypeName(name)) {
11346
- throw new globalThis.DOMException(
11347
- `The qualified name '${name}' is not a valid doctype name.`,
11348
- "InvalidCharacterError"
11349
- );
11350
- }
11351
- return new DocumentType(name, publicId, systemId, this);
11352
- }, "createDocumentType"),
11353
- // createDocument(namespace, qualifiedName, doctype) — a fresh XMLDocument
11354
- // with an optional root element (from the validated qualifiedName) and an
11355
- // optional doctype, in [doctype?, element?] order.
11356
- createDocument: /* @__PURE__ */ __name((...args) => {
11357
- if (args.length < 2) {
11358
- throw new TypeError("Failed to execute 'createDocument': 2 arguments required.");
11359
- }
11360
- const namespace = args[0], qualifiedName = args[1], doctype = args[2];
11361
- if (doctype != null && !(doctype instanceof DocumentType)) {
11362
- throw new TypeError("Failed to execute 'createDocument': parameter 3 is not of type 'DocumentType'.");
11363
- }
11364
- const ns = namespace == null || namespace === "" ? null : String(namespace);
11365
- const qn = qualifiedName === null ? "" : String(qualifiedName);
11366
- let rns = null, prefix = null, localName = null;
11367
- if (qn !== "") ({ namespace: rns, prefix, localName } = validateAndExtract(ns, qn, "element"));
11368
- const d = new XMLDocument();
11369
- d._contentType = ns === HTML_NS3 ? "application/xhtml+xml" : ns === SVG_NS2 ? "image/svg+xml" : "application/xml";
11370
- d._children = newChildList();
11371
- d.documentElement = null;
11372
- d.readyState = "complete";
11373
- if (doctype != null) {
11374
- if (doctype._parent) {
11375
- const i = doctype._parent._children.indexOf(doctype);
11376
- if (i >= 0) doctype._parent._children.splice(i, 1);
11377
- }
11378
- doctype._parent = d;
11379
- doctype._ownerDoc = d;
11380
- d._children.push(doctype);
11381
- }
11382
- if (qn !== "") {
11383
- const el = d._createElement(rns, prefix, localName);
11384
- el._parent = d;
11385
- d._children.push(el);
11386
- d.documentElement = el;
11387
- }
11388
- return d;
11389
- }, "createDocument"),
11390
- hasFeature: /* @__PURE__ */ __name(() => true, "hasFeature")
11391
- };
11656
+ return this._implementation || (this._implementation = new DOMImplementation(this));
11392
11657
  }
11393
11658
  // Minimal Range stub for `document.createRange()`. We don't model
11394
11659
  // partial-range selection (start/end offsets on text nodes etc.);
11395
11660
  // only document-order comparison between two nodes' start containers
11396
11661
  // via `compareBoundaryPoints`, which is all the consumers here drive.
11397
11662
  createRange() {
11398
- return new DocumentOrderRange();
11663
+ return new DocumentOrderRange(this);
11399
11664
  }
11400
11665
  // Minimal NodeIterator. DOMPurify is the canonical consumer —
11401
11666
  // it walks a freshly-parsed sanitisation fragment via
@@ -11404,49 +11669,58 @@
11404
11669
  // DOMPurify operates on small per-call fragments so the up-front
11405
11670
  // walk is cheaper than the per-step sibling/ancestor traversal.
11406
11671
  createNodeIterator(root, whatToShow, filter) {
11407
- if (whatToShow == null) whatToShow = 4294967295;
11408
- const all = [];
11409
- walkSubtree(root, (n) => all.push(n));
11672
+ if (!isNodeArg(root)) {
11673
+ throw new TypeError("Failed to execute 'createNodeIterator': parameter 1 is not of type 'Node'.");
11674
+ }
11675
+ whatToShow = whatToShow === void 0 ? 4294967295 : whatToShow >>> 0;
11676
+ if (filter === void 0) filter = null;
11677
+ const state2 = { node: root, before: true, active: false };
11410
11678
  const accept = /* @__PURE__ */ __name((n) => {
11411
- const mask = 1 << n.nodeType - 1;
11412
- if (!(mask & whatToShow)) return 3;
11679
+ if (!(1 << n.nodeType - 1 & whatToShow)) return 3;
11413
11680
  if (filter) {
11414
11681
  const fn = typeof filter === "function" ? filter : filter && filter.acceptNode;
11415
11682
  if (fn) {
11416
- const r = fn.call(filter || null, n);
11683
+ if (state2.active) {
11684
+ throw new globalThis.DOMException("Failed to execute 'nextNode' on 'NodeIterator': the iterator's filter is already active.", "InvalidStateError");
11685
+ }
11686
+ state2.active = true;
11687
+ let r;
11688
+ try {
11689
+ r = fn.call(filter || null, n);
11690
+ } finally {
11691
+ state2.active = false;
11692
+ }
11417
11693
  if (r === 2 || r === 3 || r === false) return 3;
11418
11694
  }
11419
11695
  }
11420
11696
  return 1;
11421
11697
  }, "accept");
11422
- let i = -1;
11423
- return {
11424
- root,
11425
- whatToShow,
11426
- filter,
11427
- referenceNode: root,
11428
- pointerBeforeReferenceNode: true,
11698
+ const it = {
11429
11699
  nextNode() {
11430
- while (++i < all.length) {
11431
- if (accept(all[i]) !== 1) continue;
11432
- this.referenceNode = all[i];
11433
- this.pointerBeforeReferenceNode = false;
11434
- return all[i];
11435
- }
11436
- return null;
11700
+ return nodeIteratorTraverse(this, true);
11437
11701
  },
11438
11702
  previousNode() {
11439
- while (--i >= 0) {
11440
- if (accept(all[i]) !== 1) continue;
11441
- this.referenceNode = all[i];
11442
- this.pointerBeforeReferenceNode = false;
11443
- return all[i];
11444
- }
11445
- return null;
11703
+ return nodeIteratorTraverse(this, false);
11446
11704
  },
11447
11705
  detach() {
11448
11706
  }
11449
11707
  };
11708
+ Object.defineProperties(it, {
11709
+ _state: { value: state2, writable: false, enumerable: false },
11710
+ _accept: { value: accept, writable: false, enumerable: false },
11711
+ root: { value: root, enumerable: true },
11712
+ whatToShow: { value: whatToShow, enumerable: true },
11713
+ filter: { value: filter, enumerable: true },
11714
+ referenceNode: { get() {
11715
+ return state2.node;
11716
+ }, enumerable: true },
11717
+ pointerBeforeReferenceNode: { get() {
11718
+ return state2.before;
11719
+ }, enumerable: true },
11720
+ [Symbol.toStringTag]: { value: "NodeIterator" }
11721
+ });
11722
+ LIVE_NODE_ITERATORS.add(it);
11723
+ return it;
11450
11724
  }
11451
11725
  // `Document.createTreeWalker(root, whatToShow, filter)` — Trix
11452
11726
  // builds one to traverse the editable subtree by nodeType (its
@@ -11892,65 +12166,299 @@
11892
12166
  // no browsing context; documentURI follows via this.URL
11893
12167
  };
11894
12168
  globalThis.XMLDocument = XMLDocument;
12169
+ function createHtmlPageDocument(withSkeleton) {
12170
+ const doc = new Document();
12171
+ doc._contentType = void 0;
12172
+ doc._url = void 0;
12173
+ doc._noBrowsingContext = false;
12174
+ doc.readyState = "loading";
12175
+ if (withSkeleton) {
12176
+ const html = new Element("html");
12177
+ const head = new Element("head");
12178
+ const body = new Element("body");
12179
+ html._parent = doc;
12180
+ doc._children.push(html);
12181
+ head._parent = html;
12182
+ html._children.push(head);
12183
+ body._parent = html;
12184
+ html._children.push(body);
12185
+ }
12186
+ return doc;
12187
+ }
12188
+ __name(createHtmlPageDocument, "createHtmlPageDocument");
12189
+ function rangesFor(node) {
12190
+ const d = node && (node.nodeType === NODE_DOC ? node : node.ownerDocument);
12191
+ return d ? d._liveRanges : null;
12192
+ }
12193
+ __name(rangesFor, "rangesFor");
12194
+ function liveRangesOnInsert(parent, index, count) {
12195
+ const reg = rangesFor(parent);
12196
+ if (!reg || reg.size === 0) return;
12197
+ for (const r of reg) {
12198
+ if (r.startContainer === parent && r.startOffset > index) r.startOffset += count;
12199
+ if (r.endContainer === parent && r.endOffset > index) r.endOffset += count;
12200
+ }
12201
+ }
12202
+ __name(liveRangesOnInsert, "liveRangesOnInsert");
12203
+ function sameTreeContains(ancestor, descendant) {
12204
+ for (let n = descendant; n; n = n._parent) {
12205
+ if (n === ancestor) return true;
12206
+ if (n._isShadowRoot) return false;
12207
+ }
12208
+ return false;
12209
+ }
12210
+ __name(sameTreeContains, "sameTreeContains");
12211
+ function liveRangesOnRemove(oldParent, node, index) {
12212
+ const reg = rangesFor(oldParent);
12213
+ if (!reg || reg.size === 0) return;
12214
+ for (const r of reg) {
12215
+ if (sameTreeContains(node, r.startContainer)) {
12216
+ r.startContainer = oldParent;
12217
+ r.startOffset = index;
12218
+ }
12219
+ if (sameTreeContains(node, r.endContainer)) {
12220
+ r.endContainer = oldParent;
12221
+ r.endOffset = index;
12222
+ }
12223
+ if (r.startContainer === oldParent && r.startOffset > index) r.startOffset -= 1;
12224
+ if (r.endContainer === oldParent && r.endOffset > index) r.endOffset -= 1;
12225
+ }
12226
+ }
12227
+ __name(liveRangesOnRemove, "liveRangesOnRemove");
12228
+ function liveRangesOnReplaceData(node, offset, count, dataLen) {
12229
+ const reg = rangesFor(node);
12230
+ if (!reg || reg.size === 0) return;
12231
+ const delta = dataLen - count;
12232
+ for (const r of reg) {
12233
+ if (r.startContainer === node) {
12234
+ if (r.startOffset > offset && r.startOffset <= offset + count) r.startOffset = offset;
12235
+ else if (r.startOffset > offset + count) r.startOffset += delta;
12236
+ }
12237
+ if (r.endContainer === node) {
12238
+ if (r.endOffset > offset && r.endOffset <= offset + count) r.endOffset = offset;
12239
+ else if (r.endOffset > offset + count) r.endOffset += delta;
12240
+ }
12241
+ }
12242
+ }
12243
+ __name(liveRangesOnReplaceData, "liveRangesOnReplaceData");
12244
+ function liveRangesOnSplit(node, offset, newNode, parent, nodeIndex) {
12245
+ const reg = rangesFor(node);
12246
+ if (!reg || reg.size === 0) return;
12247
+ for (const r of reg) {
12248
+ if (r.startContainer === node && r.startOffset > offset) {
12249
+ r.startContainer = newNode;
12250
+ r.startOffset -= offset;
12251
+ }
12252
+ if (r.endContainer === node && r.endOffset > offset) {
12253
+ r.endContainer = newNode;
12254
+ r.endOffset -= offset;
12255
+ }
12256
+ if (parent) {
12257
+ if (r.startContainer === parent && r.startOffset === nodeIndex + 1) r.startOffset += 1;
12258
+ if (r.endContainer === parent && r.endOffset === nodeIndex + 1) r.endOffset += 1;
12259
+ }
12260
+ }
12261
+ }
12262
+ __name(liveRangesOnSplit, "liveRangesOnSplit");
12263
+ var LIVE_NODE_ITERATORS = /* @__PURE__ */ new Set();
12264
+ function followingSkippingSubtree(node, root) {
12265
+ for (let cur = node; cur && cur !== root; cur = cur._parent) {
12266
+ const p = cur._parent;
12267
+ if (p) {
12268
+ const sibs = p._children, i = sibs.indexOf(cur);
12269
+ if (i >= 0 && i + 1 < sibs.length) return sibs[i + 1];
12270
+ }
12271
+ }
12272
+ return null;
12273
+ }
12274
+ __name(followingSkippingSubtree, "followingSkippingSubtree");
12275
+ function followingWithinRoot(node, root) {
12276
+ if (node._children && node._children.length) return node._children[0];
12277
+ return followingSkippingSubtree(node, root);
12278
+ }
12279
+ __name(followingWithinRoot, "followingWithinRoot");
12280
+ function precedingWithinRoot(node, root) {
12281
+ if (node === root || !node._parent) return null;
12282
+ const sibs = node._parent._children, i = sibs.indexOf(node);
12283
+ if (i > 0) {
12284
+ let n = sibs[i - 1];
12285
+ while (n._children && n._children.length) n = n._children[n._children.length - 1];
12286
+ return n;
12287
+ }
12288
+ return node._parent;
12289
+ }
12290
+ __name(precedingWithinRoot, "precedingWithinRoot");
12291
+ function nodeIteratorTraverse(it, forward) {
12292
+ let node = it._state.node;
12293
+ let before = it._state.before;
12294
+ while (true) {
12295
+ if (forward) {
12296
+ if (!before) {
12297
+ const n = followingWithinRoot(node, it.root);
12298
+ if (!n) return null;
12299
+ node = n;
12300
+ } else before = false;
12301
+ } else {
12302
+ if (before) {
12303
+ const n = precedingWithinRoot(node, it.root);
12304
+ if (!n) return null;
12305
+ node = n;
12306
+ } else before = true;
12307
+ }
12308
+ if (it._accept(node) === 1) break;
12309
+ }
12310
+ it._state.node = node;
12311
+ it._state.before = before;
12312
+ return node;
12313
+ }
12314
+ __name(nodeIteratorTraverse, "nodeIteratorTraverse");
12315
+ function nodeIteratorPreRemove(toBeRemoved) {
12316
+ if (LIVE_NODE_ITERATORS.size === 0) return;
12317
+ const removedDoc = toBeRemoved.nodeType === NODE_DOC ? toBeRemoved : toBeRemoved.ownerDocument;
12318
+ for (const it of LIVE_NODE_ITERATORS) {
12319
+ const st = it._state;
12320
+ if (nodeContains(toBeRemoved, it.root)) continue;
12321
+ const itDoc = it.root.nodeType === NODE_DOC ? it.root : it.root.ownerDocument;
12322
+ if (itDoc !== removedDoc) continue;
12323
+ if (!nodeContains(toBeRemoved, st.node)) continue;
12324
+ if (st.before) {
12325
+ const next = followingSkippingSubtree(toBeRemoved, null);
12326
+ if (next) {
12327
+ st.node = next;
12328
+ continue;
12329
+ }
12330
+ st.before = false;
12331
+ }
12332
+ const prevSib = toBeRemoved.previousSibling;
12333
+ if (!prevSib) {
12334
+ st.node = toBeRemoved._parent;
12335
+ } else {
12336
+ let n = prevSib;
12337
+ while (n._children && n._children.length) n = n._children[n._children.length - 1];
12338
+ st.node = n;
12339
+ }
12340
+ }
12341
+ }
12342
+ __name(nodeIteratorPreRemove, "nodeIteratorPreRemove");
12343
+ function nodeLength(node) {
12344
+ const t = node.nodeType;
12345
+ if (t === NODE_DOCTYPE) return 0;
12346
+ if (t === NODE_TEXT || t === NODE_CDATA || t === NODE_COMMENT || t === NODE_PI) {
12347
+ return (node.data || "").length;
12348
+ }
12349
+ return node._children ? node._children.length : 0;
12350
+ }
12351
+ __name(nodeLength, "nodeLength");
12352
+ function setRangeBoundary(range, node, offset, which) {
12353
+ const fn = which === "start" ? "setStart" : "setEnd";
12354
+ if (!isNodeArg(node)) {
12355
+ throw new TypeError(`Failed to execute '${fn}' on 'Range': parameter 1 is not of type 'Node'.`);
12356
+ }
12357
+ if (node.nodeType === NODE_DOCTYPE) {
12358
+ throw new globalThis.DOMException(`Failed to execute '${fn}' on 'Range': the node is a doctype.`, "InvalidNodeTypeError");
12359
+ }
12360
+ offset = offset >>> 0;
12361
+ if (offset > nodeLength(node)) {
12362
+ throw new globalThis.DOMException(`Failed to execute '${fn}' on 'Range': the offset ${offset} is larger than the node's length.`, "IndexSizeError");
12363
+ }
12364
+ const newRoot = ancestorChain(node)[0];
12365
+ if (which === "start") {
12366
+ const endRoot = range.endContainer && ancestorChain(range.endContainer)[0];
12367
+ if (newRoot !== endRoot || compareBoundaryPoint(node, offset, range.endContainer, range.endOffset) > 0) {
12368
+ range.endContainer = node;
12369
+ range.endOffset = offset;
12370
+ }
12371
+ range.startContainer = node;
12372
+ range.startOffset = offset;
12373
+ } else {
12374
+ const startRoot = range.startContainer && ancestorChain(range.startContainer)[0];
12375
+ if (newRoot !== startRoot || compareBoundaryPoint(node, offset, range.startContainer, range.startOffset) < 0) {
12376
+ range.startContainer = node;
12377
+ range.startOffset = offset;
12378
+ }
12379
+ range.endContainer = node;
12380
+ range.endOffset = offset;
12381
+ }
12382
+ range._track();
12383
+ }
12384
+ __name(setRangeBoundary, "setRangeBoundary");
12385
+ function boundaryRelativeToNode(range, node, which, after) {
12386
+ const fn = (which === "start" ? "setStart" : "setEnd") + (after ? "After" : "Before");
12387
+ const parent = node && node._parent;
12388
+ if (!parent) {
12389
+ throw new globalThis.DOMException(`Failed to execute '${fn}' on 'Range': the node has no parent.`, "InvalidNodeTypeError");
12390
+ }
12391
+ const index = parent._children.indexOf(node);
12392
+ setRangeBoundary(range, parent, index + (after ? 1 : 0), which);
12393
+ }
12394
+ __name(boundaryRelativeToNode, "boundaryRelativeToNode");
11895
12395
  var DocumentOrderRange = class _DocumentOrderRange {
11896
12396
  static {
11897
12397
  __name(this, "DocumentOrderRange");
11898
12398
  }
11899
- constructor() {
11900
- const doc = globalThis.document || null;
11901
- this.startContainer = doc;
12399
+ constructor(doc) {
12400
+ const d = doc || globalThis.document || null;
12401
+ this.startContainer = d;
11902
12402
  this.startOffset = 0;
11903
- this.endContainer = doc;
12403
+ this.endContainer = d;
11904
12404
  this.endOffset = 0;
12405
+ this._reg = null;
12406
+ this._track();
12407
+ }
12408
+ // (Re-)register this range in its current document's live-range set. Called
12409
+ // after every boundary change so a range that moves to another document is
12410
+ // tracked there (the registry hangs off the shared document, not a realm).
12411
+ _track() {
12412
+ const sc = this.startContainer;
12413
+ const d = sc && (sc.nodeType === NODE_DOC ? sc : sc.ownerDocument);
12414
+ const reg = d ? d._liveRanges || (d._liveRanges = /* @__PURE__ */ new Set()) : null;
12415
+ if (reg === this._reg) return;
12416
+ if (this._reg) this._reg.delete(this);
12417
+ this._reg = reg;
12418
+ if (reg) reg.add(this);
11905
12419
  }
11906
12420
  setStart(node, offset) {
11907
- this.startContainer = node;
11908
- this.startOffset = offset | 0;
12421
+ setRangeBoundary(this, node, offset, "start");
11909
12422
  }
11910
12423
  setEnd(node, offset) {
11911
- this.endContainer = node;
11912
- this.endOffset = offset | 0;
11913
- }
11914
- // Boundary helpers — node-relative variants of setStart / setEnd.
11915
- // `setStartBefore(n)` puts the range start at (n.parentNode,
11916
- // indexOf(n)); `setStartAfter` adds 1; ditto for end. Per HTML
11917
- // spec — the offset is the position of `n` among its parent's
11918
- // children. The old "offset=0" approximation broke partial-quote
11919
- // tests where the range was supposed to skip past leading
11920
- // siblings, and quote-reply's cloneContents walked from the
11921
- // wrong start position.
12424
+ setRangeBoundary(this, node, offset, "end");
12425
+ }
11922
12426
  setStartBefore(node) {
11923
- const p = node && node._parent;
11924
- this.startContainer = p || node;
11925
- this.startOffset = p ? p._children.indexOf(node) : 0;
12427
+ boundaryRelativeToNode(this, node, "start", false);
11926
12428
  }
11927
12429
  setStartAfter(node) {
11928
- const p = node && node._parent;
11929
- this.startContainer = p || node;
11930
- this.startOffset = p ? p._children.indexOf(node) + 1 : 0;
12430
+ boundaryRelativeToNode(this, node, "start", true);
11931
12431
  }
11932
12432
  setEndBefore(node) {
11933
- const p = node && node._parent;
11934
- this.endContainer = p || node;
11935
- this.endOffset = p ? p._children.indexOf(node) : 0;
12433
+ boundaryRelativeToNode(this, node, "end", false);
11936
12434
  }
11937
12435
  setEndAfter(node) {
11938
- const p = node && node._parent;
11939
- this.endContainer = p || node;
11940
- this.endOffset = p ? p._children.indexOf(node) + 1 : 0;
11941
- }
11942
- // Real DOM: selectNode sets the range to span the given node
11943
- // *within* its parent. Collapse moves both endpoints to one side.
11944
- // Consumers here only care that the start container ends up
11945
- // referring to the node we passed.
11946
- selectNode(node) {
11947
- this.startContainer = this.endContainer = node;
11948
- this.startOffset = this.endOffset = 0;
12436
+ boundaryRelativeToNode(this, node, "end", true);
11949
12437
  }
12438
+ // selectNode spans `node` within its parent: start (parent, index),
12439
+ // end (parent, index+1). A parentless node → InvalidNodeTypeError.
12440
+ selectNode(node) {
12441
+ const parent = node && node._parent;
12442
+ if (!parent) {
12443
+ throw new globalThis.DOMException("Failed to execute 'selectNode' on 'Range': the node has no parent.", "InvalidNodeTypeError");
12444
+ }
12445
+ const index = parent._children.indexOf(node);
12446
+ this.startContainer = parent;
12447
+ this.startOffset = index;
12448
+ this.endContainer = parent;
12449
+ this.endOffset = index + 1;
12450
+ this._track();
12451
+ }
12452
+ // selectNodeContents spans the whole node: start (node, 0), end (node, length).
12453
+ // A doctype has no contents to select → InvalidNodeTypeError.
11950
12454
  selectNodeContents(node) {
12455
+ if (node.nodeType === NODE_DOCTYPE) {
12456
+ throw new globalThis.DOMException("Failed to execute 'selectNodeContents' on 'Range': the node is a doctype.", "InvalidNodeTypeError");
12457
+ }
11951
12458
  this.startContainer = this.endContainer = node;
11952
12459
  this.startOffset = 0;
11953
- this.endOffset = node.nodeType === NODE_TEXT ? (node.data || "").length : node._children ? node._children.length : 0;
12460
+ this.endOffset = nodeLength(node);
12461
+ this._track();
11954
12462
  }
11955
12463
  // `Range.createContextualFragment(html)` — parse `html` as a fragment using
11956
12464
  // the range's start node as context, returning a DocumentFragment owned by the
@@ -11992,9 +12500,7 @@
11992
12500
  return cloneRangeContents(this);
11993
12501
  }
11994
12502
  extractContents() {
11995
- const frag = cloneRangeContents(this);
11996
- deleteRangeContents(this);
11997
- return frag;
12503
+ return extractRangeContents(this);
11998
12504
  }
11999
12505
  // Spec: removes everything inside the range from its container.
12000
12506
  // Turbo's `FrameRenderer` calls `selectNodeContents(currentElement);
@@ -12030,6 +12536,7 @@
12030
12536
  r.startOffset = this.startOffset;
12031
12537
  r.endContainer = this.endContainer;
12032
12538
  r.endOffset = this.endOffset;
12539
+ r._track();
12033
12540
  return r;
12034
12541
  }
12035
12542
  // DOM spec Range#toString: concatenates the text of all Text nodes
@@ -12069,35 +12576,50 @@
12069
12576
  // containers, inserts at child index `startOffset`. Tiptap /
12070
12577
  // ProseMirror's text-insertion fallback uses this.
12071
12578
  insertNode(node) {
12579
+ if (!isNodeArg(node)) throw new TypeError("Failed to execute 'insertNode' on 'Range': parameter 1 is not of type 'Node'.");
12072
12580
  const sc = this.startContainer;
12073
- if (!sc) return;
12074
- if (sc.nodeType === NODE_TEXT) {
12075
- const parent = sc._parent;
12076
- if (!parent) return;
12077
- const text = sc.data || "";
12078
- const before = text.slice(0, this.startOffset);
12079
- const after = text.slice(this.startOffset);
12080
- sc.data = before;
12081
- const idx = parent._children.indexOf(sc);
12082
- if (after.length > 0) {
12083
- const tail = new Text(after);
12084
- parent.insertBefore(tail, parent._children[idx + 1] || null);
12085
- }
12086
- parent.insertBefore(node, parent._children[idx + 1] || null);
12087
- } else {
12088
- const ref = sc._children ? sc._children[this.startOffset] : null;
12089
- sc.insertBefore(node, ref || null);
12581
+ const startIsText = sc.nodeType === NODE_TEXT || sc.nodeType === NODE_CDATA;
12582
+ if (sc.nodeType === NODE_PI || sc.nodeType === NODE_COMMENT || startIsText && !sc._parent || node === sc || nodeContains(node, sc)) {
12583
+ throw new globalThis.DOMException("Failed to execute 'insertNode' on 'Range': the node may not be inserted here.", "HierarchyRequestError");
12584
+ }
12585
+ let referenceNode = startIsText ? sc : sc._children ? sc._children[this.startOffset] || null : null;
12586
+ const parent = referenceNode == null ? sc : referenceNode._parent;
12587
+ ensurePreInsertionValidity(node, parent, referenceNode);
12588
+ if (startIsText) referenceNode = sc.splitText(this.startOffset);
12589
+ if (node === referenceNode) referenceNode = node.nextSibling;
12590
+ if (node._parent) node._parent.removeChild(node);
12591
+ let newOffset = referenceNode == null ? nodeLength(parent) : parent._children.indexOf(referenceNode);
12592
+ newOffset += node.nodeType === NODE_FRAGMENT ? nodeLength(node) : 1;
12593
+ parent.insertBefore(node, referenceNode);
12594
+ if (this.collapsed) {
12595
+ this.endContainer = parent;
12596
+ this.endOffset = newOffset;
12090
12597
  }
12091
- this.setStartAfter(node);
12092
- this.collapse(true);
12093
12598
  }
12094
12599
  // Range#surroundContents(newParent): extract range contents, wrap
12095
12600
  // in `newParent`, insert wrapper at the range's start. Used by
12096
12601
  // highlight / annotate libraries.
12097
12602
  surroundContents(newParent) {
12098
- const frag = this.extractContents();
12099
- newParent.appendChild(frag);
12603
+ const common = this.commonAncestorContainer;
12604
+ const partialNonText = /* @__PURE__ */ __name((boundary, other) => {
12605
+ if (nodeContains(boundary, other)) return false;
12606
+ for (let n = boundary; n && n !== common; n = n._parent) {
12607
+ if (n.nodeType !== NODE_TEXT && n.nodeType !== NODE_CDATA) return true;
12608
+ }
12609
+ return false;
12610
+ }, "partialNonText");
12611
+ if (partialNonText(this.startContainer, this.endContainer) || partialNonText(this.endContainer, this.startContainer)) {
12612
+ throw new globalThis.DOMException("Failed to execute 'surroundContents' on 'Range': the range partially selects a non-Text node.", "InvalidStateError");
12613
+ }
12614
+ const nt = newParent.nodeType;
12615
+ if (nt === NODE_DOC || nt === NODE_DOCTYPE || nt === NODE_FRAGMENT) {
12616
+ throw new globalThis.DOMException("Failed to execute 'surroundContents' on 'Range': the new parent is a Document, DocumentType, or DocumentFragment node.", "InvalidNodeTypeError");
12617
+ }
12618
+ const fragment = extractRangeContents(this);
12619
+ if (newParent._children) for (const c of newParent._children.slice()) newParent.removeChild(c);
12100
12620
  this.insertNode(newParent);
12621
+ newParent.appendChild(fragment);
12622
+ this.selectNode(newParent);
12101
12623
  }
12102
12624
  // Range#comparePoint(node, offset) — -1/0/+1 vs the range.
12103
12625
  // Range#isPointInRange(node, offset) — true if inside.
@@ -12106,12 +12628,30 @@
12106
12628
  if (ancestorChain(node)[0] !== ancestorChain(this.startContainer)[0]) {
12107
12629
  throw new globalThis.DOMException("The node provided is in a different tree than this Range.", "WrongDocumentError");
12108
12630
  }
12109
- if (compareDocOrder(node, this.startContainer) < 0) return -1;
12110
- if (compareDocOrder(node, this.endContainer) > 0) return 1;
12631
+ if (node.nodeType === NODE_DOCTYPE) {
12632
+ throw new globalThis.DOMException("Failed to execute 'comparePoint' on 'Range': the node is a doctype.", "InvalidNodeTypeError");
12633
+ }
12634
+ offset = offset >>> 0;
12635
+ if (offset > nodeLength(node)) {
12636
+ throw new globalThis.DOMException(`Failed to execute 'comparePoint' on 'Range': the offset ${offset} is larger than the node's length.`, "IndexSizeError");
12637
+ }
12638
+ if (compareBoundaryPoint(node, offset, this.startContainer, this.startOffset) < 0) return -1;
12639
+ if (compareBoundaryPoint(node, offset, this.endContainer, this.endOffset) > 0) return 1;
12111
12640
  return 0;
12112
12641
  }
12113
12642
  isPointInRange(node, offset) {
12114
- return this.comparePoint(node, offset) === 0;
12643
+ if (!isNodeArg(node)) throw new TypeError("Failed to execute 'isPointInRange' on 'Range': parameter 1 is not of type 'Node'.");
12644
+ if (ancestorChain(node)[0] !== ancestorChain(this.startContainer)[0]) return false;
12645
+ if (node.nodeType === NODE_DOCTYPE) {
12646
+ throw new globalThis.DOMException("Failed to execute 'isPointInRange' on 'Range': the node is a doctype.", "InvalidNodeTypeError");
12647
+ }
12648
+ offset = offset >>> 0;
12649
+ if (offset > nodeLength(node)) {
12650
+ throw new globalThis.DOMException(`Failed to execute 'isPointInRange' on 'Range': the offset ${offset} is larger than the node's length.`, "IndexSizeError");
12651
+ }
12652
+ if (compareBoundaryPoint(node, offset, this.startContainer, this.startOffset) < 0) return false;
12653
+ if (compareBoundaryPoint(node, offset, this.endContainer, this.endOffset) > 0) return false;
12654
+ return true;
12115
12655
  }
12116
12656
  get collapsed() {
12117
12657
  return this.startContainer === this.endContainer && this.startOffset === this.endOffset;
@@ -12125,8 +12665,40 @@
12125
12665
  while (i < a.length && i < b.length && a[i] === b[i]) i++;
12126
12666
  return i > 0 ? a[i - 1] : this.startContainer;
12127
12667
  }
12128
- compareBoundaryPoints(_how, other) {
12129
- return compareDocOrder(this.startContainer, other.startContainer);
12668
+ // compareBoundaryPoints(how, sourceRange): compares the two ranges' boundary
12669
+ // points selected by `how`. `how` is a WebIDL unsigned short; a value outside
12670
+ // {0,1,2,3} → NotSupportedError. Different roots → WrongDocumentError.
12671
+ compareBoundaryPoints(how, other) {
12672
+ how = how & 65535;
12673
+ if (how > 3) {
12674
+ throw new globalThis.DOMException("Failed to execute 'compareBoundaryPoints' on 'Range': the comparison method must be 0, 1, 2 or 3.", "NotSupportedError");
12675
+ }
12676
+ if (ancestorChain(this.startContainer)[0] !== ancestorChain(other.startContainer)[0]) {
12677
+ throw new globalThis.DOMException("The two Ranges are not in the same tree.", "WrongDocumentError");
12678
+ }
12679
+ let tn, to, on, oo;
12680
+ if (how === 0) {
12681
+ tn = this.startContainer;
12682
+ to = this.startOffset;
12683
+ on = other.startContainer;
12684
+ oo = other.startOffset;
12685
+ } else if (how === 1) {
12686
+ tn = this.endContainer;
12687
+ to = this.endOffset;
12688
+ on = other.startContainer;
12689
+ oo = other.startOffset;
12690
+ } else if (how === 2) {
12691
+ tn = this.endContainer;
12692
+ to = this.endOffset;
12693
+ on = other.endContainer;
12694
+ oo = other.endOffset;
12695
+ } else {
12696
+ tn = this.startContainer;
12697
+ to = this.startOffset;
12698
+ on = other.endContainer;
12699
+ oo = other.endOffset;
12700
+ }
12701
+ return compareBoundaryPoint(tn, to, on, oo);
12130
12702
  }
12131
12703
  };
12132
12704
  DocumentOrderRange.START_TO_START = 0;
@@ -12176,54 +12748,6 @@
12176
12748
  return cur && cur._parent === ancestor ? cur : null;
12177
12749
  }
12178
12750
  __name(__rangeAncestorChild, "__rangeAncestorChild");
12179
- function __appendCloned(parent, child) {
12180
- child._parent = parent;
12181
- parent._children.push(child);
12182
- }
12183
- __name(__appendCloned, "__appendCloned");
12184
- function __emitSlice(target, subtree, startCut, endCut) {
12185
- const kids = subtree._children || [];
12186
- let startIdx = 0, startChild = null;
12187
- if (startCut) {
12188
- if (startCut.container === subtree) {
12189
- startIdx = startCut.offset;
12190
- } else {
12191
- startChild = __rangeAncestorChild(subtree, startCut.container);
12192
- if (startChild) startIdx = kids.indexOf(startChild) + 1;
12193
- }
12194
- }
12195
- let endIdx = kids.length, endChild = null;
12196
- if (endCut) {
12197
- if (endCut.container === subtree) {
12198
- endIdx = endCut.offset;
12199
- } else {
12200
- endChild = __rangeAncestorChild(subtree, endCut.container);
12201
- if (endChild) endIdx = kids.indexOf(endChild);
12202
- }
12203
- }
12204
- if (startChild && startChild === endChild) {
12205
- __appendCloned(target, __cloneSlice(startChild, startCut, endCut));
12206
- return;
12207
- }
12208
- if (startChild) __appendCloned(target, __cloneSlice(startChild, startCut, null));
12209
- for (let i = startIdx; i < endIdx; i++) {
12210
- if (kids[i]) __appendCloned(target, kids[i].cloneNode(true));
12211
- }
12212
- if (endChild) __appendCloned(target, __cloneSlice(endChild, null, endCut));
12213
- }
12214
- __name(__emitSlice, "__emitSlice");
12215
- function __cloneSlice(subtree, startCut, endCut) {
12216
- if (subtree.nodeType === NODE_TEXT) {
12217
- const data = subtree.data || "";
12218
- const lo = startCut && startCut.container === subtree ? startCut.offset : 0;
12219
- const hi = endCut && endCut.container === subtree ? endCut.offset : data.length;
12220
- return new Text(data.slice(lo, hi));
12221
- }
12222
- const shell = subtree.cloneNode(false);
12223
- __emitSlice(shell, subtree, startCut, endCut);
12224
- return shell;
12225
- }
12226
- __name(__cloneSlice, "__cloneSlice");
12227
12751
  function __csimInsertTextAtSelection(text) {
12228
12752
  const sel = globalThis.getSelection && globalThis.getSelection();
12229
12753
  if (!sel || !sel._ranges.length) return false;
@@ -12294,93 +12818,113 @@
12294
12818
  }
12295
12819
  __name(__csimInsertTextAtSelection, "__csimInsertTextAtSelection");
12296
12820
  globalThis.__csimInsertTextAtSelection = __csimInsertTextAtSelection;
12297
- function __deleteSlice(subtree, startCut, endCut) {
12298
- if (subtree.nodeType === NODE_TEXT) {
12299
- const data = subtree.data || "";
12300
- const lo = startCut && startCut.container === subtree ? startCut.offset : 0;
12301
- const hi = endCut && endCut.container === subtree ? endCut.offset : data.length;
12302
- subtree.data = data.slice(0, lo) + data.slice(hi);
12303
- return;
12304
- }
12305
- __emitSliceDelete(subtree, startCut, endCut);
12821
+ function isCharacterData(n) {
12822
+ return n != null && (n.nodeType === NODE_TEXT || n.nodeType === NODE_CDATA || n.nodeType === NODE_COMMENT || n.nodeType === NODE_PI);
12306
12823
  }
12307
- __name(__deleteSlice, "__deleteSlice");
12308
- function __emitSliceDelete(subtree, startCut, endCut) {
12309
- const kids = subtree._children || [];
12310
- let startIdx = 0, startChild = null;
12311
- if (startCut) {
12312
- if (startCut.container === subtree) {
12313
- startIdx = startCut.offset;
12314
- } else {
12315
- startChild = __rangeAncestorChild(subtree, startCut.container);
12316
- if (startChild) startIdx = kids.indexOf(startChild) + 1;
12317
- }
12318
- }
12319
- let endIdx = kids.length, endChild = null;
12320
- if (endCut) {
12321
- if (endCut.container === subtree) {
12322
- endIdx = endCut.offset;
12323
- } else {
12324
- endChild = __rangeAncestorChild(subtree, endCut.container);
12325
- if (endChild) endIdx = kids.indexOf(endChild);
12326
- }
12327
- }
12328
- if (startChild && startChild === endChild) {
12329
- __deleteSlice(startChild, startCut, endCut);
12330
- return;
12824
+ __name(isCharacterData, "isCharacterData");
12825
+ function processRangeContents(range, mode) {
12826
+ const sc = range.startContainer, so = range.startOffset;
12827
+ const ec = range.endContainer, eo = range.endOffset;
12828
+ const ownerDoc = sc && (sc.nodeType === NODE_DOC ? sc : sc.ownerDocument) || globalThis.document;
12829
+ const frag = mode === "delete" ? null : ownerDoc.createDocumentFragment();
12830
+ if (!sc || !ec) return frag;
12831
+ if (sc === ec && so === eo) return frag;
12832
+ if (sc === ec && isCharacterData(sc)) {
12833
+ if (mode !== "delete") {
12834
+ const clone = sc.cloneNode(false);
12835
+ clone._data = (sc.data || "").slice(so, eo);
12836
+ frag.appendChild(clone);
12837
+ }
12838
+ if (mode !== "clone") sc._replaceData(so, eo - so, "");
12839
+ return frag;
12331
12840
  }
12332
- if (startChild) __deleteSlice(startChild, startCut, null);
12333
- if (endChild) __deleteSlice(endChild, null, endCut);
12334
- for (let i = endIdx - 1; i >= startIdx; i--) {
12335
- if (kids[i]) subtree.removeChild(kids[i]);
12841
+ const common = range.commonAncestorContainer;
12842
+ const firstPC = nodeContains(sc, ec) ? null : __rangeAncestorChild(common, sc);
12843
+ const lastPC = nodeContains(ec, sc) ? null : __rangeAncestorChild(common, ec);
12844
+ const contained = [];
12845
+ const kids = common._children || [];
12846
+ for (let i = 0; i < kids.length; i++) {
12847
+ if (compareBoundaryPoint(common, i, sc, so) >= 0 && compareBoundaryPoint(common, i + 1, ec, eo) <= 0) {
12848
+ contained.push(kids[i]);
12849
+ }
12850
+ }
12851
+ let newNode = sc, newOffset = so;
12852
+ if (mode !== "clone" && !nodeContains(sc, ec)) {
12853
+ let ref = sc;
12854
+ while (ref._parent && !nodeContains(ref._parent, ec)) ref = ref._parent;
12855
+ newNode = ref._parent;
12856
+ newOffset = newNode._children.indexOf(ref) + 1;
12857
+ }
12858
+ if (isCharacterData(firstPC)) {
12859
+ if (mode !== "delete") {
12860
+ const clone = sc.cloneNode(false);
12861
+ clone._data = (sc.data || "").slice(so);
12862
+ frag.appendChild(clone);
12863
+ }
12864
+ if (mode !== "clone") sc._replaceData(so, nodeLength(sc) - so, "");
12865
+ } else if (firstPC) {
12866
+ let clone = null;
12867
+ if (mode !== "delete") {
12868
+ clone = firstPC.cloneNode(false);
12869
+ frag.appendChild(clone);
12870
+ }
12871
+ const sub = new DocumentOrderRange(ownerDoc);
12872
+ sub.startContainer = sc;
12873
+ sub.startOffset = so;
12874
+ sub.endContainer = firstPC;
12875
+ sub.endOffset = nodeLength(firstPC);
12876
+ const subResult = processRangeContents(sub, mode);
12877
+ if (clone) clone.appendChild(subResult);
12878
+ if (sub._reg) sub._reg.delete(sub);
12879
+ }
12880
+ for (const child of contained) {
12881
+ if (mode === "clone") frag.appendChild(child.cloneNode(true));
12882
+ else if (mode === "extract") frag.appendChild(child);
12883
+ else if (child._parent) child._parent.removeChild(child);
12884
+ }
12885
+ if (isCharacterData(lastPC)) {
12886
+ if (mode !== "delete") {
12887
+ const clone = ec.cloneNode(false);
12888
+ clone._data = (ec.data || "").slice(0, eo);
12889
+ frag.appendChild(clone);
12890
+ }
12891
+ if (mode !== "clone") ec._replaceData(0, eo, "");
12892
+ } else if (lastPC) {
12893
+ let clone = null;
12894
+ if (mode !== "delete") {
12895
+ clone = lastPC.cloneNode(false);
12896
+ frag.appendChild(clone);
12897
+ }
12898
+ const sub = new DocumentOrderRange(ownerDoc);
12899
+ sub.startContainer = lastPC;
12900
+ sub.startOffset = 0;
12901
+ sub.endContainer = ec;
12902
+ sub.endOffset = eo;
12903
+ const subResult = processRangeContents(sub, mode);
12904
+ if (clone) clone.appendChild(subResult);
12905
+ if (sub._reg) sub._reg.delete(sub);
12906
+ }
12907
+ if (mode !== "clone") {
12908
+ range.startContainer = newNode;
12909
+ range.startOffset = newOffset;
12910
+ range.endContainer = newNode;
12911
+ range.endOffset = newOffset;
12336
12912
  }
12913
+ return frag;
12337
12914
  }
12338
- __name(__emitSliceDelete, "__emitSliceDelete");
12915
+ __name(processRangeContents, "processRangeContents");
12339
12916
  function deleteRangeContents(range) {
12340
- const sc = range.startContainer, so = range.startOffset | 0;
12341
- const ec = range.endContainer, eo = range.endOffset | 0;
12342
- if (sc === ec && sc && sc.nodeType === NODE_TEXT) {
12343
- const data = sc.data || "";
12344
- sc.data = data.slice(0, so) + data.slice(eo);
12345
- range.endOffset = range.startOffset;
12346
- } else if (sc === ec && sc && sc._children) {
12347
- const end = Math.min(eo, sc._children.length);
12348
- const doomed = sc._children.slice(so, end);
12349
- for (const child of doomed) sc.removeChild(child);
12350
- range.endOffset = range.startOffset;
12351
- range.endContainer = range.startContainer;
12352
- } else if (sc && ec) {
12353
- const ancestor = range.commonAncestorContainer;
12354
- if (ancestor) {
12355
- __deleteSlice(ancestor, { container: sc, offset: so }, { container: ec, offset: eo });
12356
- }
12357
- range.endContainer = sc;
12358
- range.endOffset = so;
12359
- }
12917
+ processRangeContents(range, "delete");
12360
12918
  }
12361
12919
  __name(deleteRangeContents, "deleteRangeContents");
12362
12920
  function cloneRangeContents(range) {
12363
- const frag = new DocumentFragment();
12364
- if (!range.startContainer || !range.endContainer) return frag;
12365
- const sc = range.startContainer, so = range.startOffset;
12366
- const ec = range.endContainer, eo = range.endOffset;
12367
- if (sc === ec) {
12368
- if (sc.nodeType === NODE_TEXT) {
12369
- __appendCloned(frag, new Text((sc.data || "").slice(so, eo)));
12370
- } else if (sc._children) {
12371
- for (let i = so; i < Math.min(eo, sc._children.length); i++) {
12372
- __appendCloned(frag, sc._children[i].cloneNode(true));
12373
- }
12374
- }
12375
- return frag;
12376
- }
12377
- const ancestor = range.commonAncestorContainer;
12378
- if (ancestor) {
12379
- __emitSlice(frag, ancestor, { container: sc, offset: so }, { container: ec, offset: eo });
12380
- }
12381
- return frag;
12921
+ return processRangeContents(range, "clone");
12382
12922
  }
12383
12923
  __name(cloneRangeContents, "cloneRangeContents");
12924
+ function extractRangeContents(range) {
12925
+ return processRangeContents(range, "extract");
12926
+ }
12927
+ __name(extractRangeContents, "extractRangeContents");
12384
12928
  DocumentOrderRange.END_TO_START = 3;
12385
12929
  DocumentOrderRange.prototype.START_TO_START = 0;
12386
12930
  DocumentOrderRange.prototype.START_TO_END = 1;
@@ -12510,7 +13054,7 @@
12510
13054
  assertNodeArg(node);
12511
13055
  if (child != null) assertNodeArg(child);
12512
13056
  const parent = this;
12513
- if (node.getRootNode() !== parent.getRootNode()) {
13057
+ if (node.getRootNode({ composed: true }) !== parent.getRootNode({ composed: true })) {
12514
13058
  throw hierarchyError("moveBefore: node and new parent are not in the same tree");
12515
13059
  }
12516
13060
  if (isInclusiveAncestor(node, parent)) {
@@ -12549,6 +13093,7 @@
12549
13093
  askForReset(node);
12550
13094
  if (oldParent) recordChildList(oldParent, [], [node], prevSib, nextSib);
12551
13095
  recordChildList(parent, [node], []);
13096
+ if (isConnected(node)) fireCEMoveReactions(node);
12552
13097
  return void 0;
12553
13098
  }
12554
13099
  __name(moveBeforeImpl, "moveBeforeImpl");
@@ -12612,7 +13157,7 @@
12612
13157
  return el._attrNodeFor(key);
12613
13158
  }
12614
13159
  __name(makeAttr, "makeAttr");
12615
- var { parseDocument, parseFragment } = installHtmlParser({ Document, Element, Text, Comment, DocumentFragment, DocumentType });
13160
+ var { parseDocument, parseFragment } = installHtmlParser({ Document, Element, Text, Comment, DocumentFragment, DocumentType, createHtmlPageDocument, registerNamedAccess });
12616
13161
  var { parseXml } = installXmlParser({ Element, Text, Comment, ProcessingInstruction, CDATASection, DocumentType });
12617
13162
 
12618
13163
  // lib/capybara/simulated/js/src/abort.js
@@ -15038,10 +15583,12 @@
15038
15583
  const subAction = submitter && submitter._attrs && submitter._attrs.formaction;
15039
15584
  const subMethod = submitter && submitter._attrs && submitter._attrs.formmethod;
15040
15585
  const subEnctype = submitter && submitter._attrs && submitter._attrs.formenctype;
15586
+ const subTarget = submitter && submitter._attrs && submitter._attrs.formtarget;
15041
15587
  return {
15042
15588
  action: subAction != null ? subAction : form._attrs.action != null ? form._attrs.action : "",
15043
15589
  method: (subMethod || form._attrs.method || "get").toLowerCase(),
15044
15590
  enctype: (subEnctype || form._attrs.enctype || "application/x-www-form-urlencoded").toLowerCase(),
15591
+ target: subTarget != null ? subTarget : form._attrs.target != null ? form._attrs.target : "",
15045
15592
  fields,
15046
15593
  fileInputs
15047
15594
  };
@@ -15342,6 +15889,28 @@
15342
15889
  const n = handles.get(h);
15343
15890
  return n != null && isConnected(n);
15344
15891
  };
15892
+ globalThis.__csimEnsureFrameRealm = function(h) {
15893
+ const el = lookup(h);
15894
+ if (!el || el._tag !== "iframe" && el._tag !== "frame") return 0;
15895
+ if (typeof globalThis.__csimFrameWindow !== "function") return 0;
15896
+ globalThis.__csimFrameWindow(el);
15897
+ return el._frameRealmId != null ? el._frameRealmId : 0;
15898
+ };
15899
+ globalThis.__csimLocationHref = function() {
15900
+ return globalThis.location && globalThis.location.href || "";
15901
+ };
15902
+ globalThis.__csimRebindFrameRealm = function(h, oldId, newId) {
15903
+ const el = lookup(h);
15904
+ if (el) {
15905
+ el._frameRealmId = newId || null;
15906
+ el._frameWindow = null;
15907
+ }
15908
+ const ids = globalThis.__csimChildRealmIds;
15909
+ if (ids) {
15910
+ if (oldId) ids.delete(oldId);
15911
+ if (newId) ids.add(newId);
15912
+ }
15913
+ };
15345
15914
  globalThis.__csimValue = function(h) {
15346
15915
  const n = lookup(h);
15347
15916
  if (!n || n.nodeType !== NODE_ELEMENT) return null;
@@ -17316,6 +17885,101 @@
17316
17885
  }
17317
17886
  };
17318
17887
  globalThis.BroadcastChannel = BroadcastChannel;
17888
+ var __csimWindowProxies = /* @__PURE__ */ new Map();
17889
+ function csimWindowProxy(handle) {
17890
+ if (handle == null || handle === "") return null;
17891
+ let proxy = __csimWindowProxies.get(handle);
17892
+ if (proxy) return proxy;
17893
+ const location = {
17894
+ get href() {
17895
+ return globalThis.__csimWindowLocation(handle);
17896
+ },
17897
+ set href(v) {
17898
+ globalThis.__csimWindowSetLocation(handle, String(v));
17899
+ },
17900
+ assign(v) {
17901
+ globalThis.__csimWindowSetLocation(handle, String(v));
17902
+ },
17903
+ replace(v) {
17904
+ globalThis.__csimWindowSetLocation(handle, String(v));
17905
+ },
17906
+ toString() {
17907
+ return globalThis.__csimWindowLocation(handle);
17908
+ }
17909
+ };
17910
+ proxy = {
17911
+ get closed() {
17912
+ return !!globalThis.__csimWindowClosed(handle);
17913
+ },
17914
+ close() {
17915
+ globalThis.__csimWindowClose(handle);
17916
+ },
17917
+ focus() {
17918
+ },
17919
+ blur() {
17920
+ },
17921
+ // Cross-window postMessage. The data round-trips JS→Ruby→JS through the
17922
+ // host marshaller rather than a true structured-clone: plain
17923
+ // primitives/arrays/objects survive, but `undefined`→null, functions /
17924
+ // symbols drop (no DataCloneError is thrown), and prototypes/identity are
17925
+ // lost — fine for the JSON-ish payloads postMessage carries in practice.
17926
+ // `targetOrigin` is accepted but, like the single-origin model elsewhere,
17927
+ // not enforced.
17928
+ postMessage(data, targetOrigin, _transfer) {
17929
+ globalThis.__csimWindowPostMessage(handle, data, String(targetOrigin == null ? "*" : targetOrigin));
17930
+ },
17931
+ get location() {
17932
+ return location;
17933
+ },
17934
+ set location(v) {
17935
+ location.href = v;
17936
+ },
17937
+ get window() {
17938
+ return proxy;
17939
+ },
17940
+ get self() {
17941
+ return proxy;
17942
+ },
17943
+ get __csimWindowHandle() {
17944
+ return handle;
17945
+ }
17946
+ };
17947
+ __csimWindowProxies.set(handle, proxy);
17948
+ return proxy;
17949
+ }
17950
+ __name(csimWindowProxy, "csimWindowProxy");
17951
+ globalThis.open = function(url, name, _features) {
17952
+ const fn = globalThis.__csimWindowOpen;
17953
+ if (typeof fn !== "function") return null;
17954
+ const handle = fn(url == null ? "" : String(url), name == null ? "" : String(name));
17955
+ return handle ? csimWindowProxy(handle) : null;
17956
+ };
17957
+ var __csimOpenerOverride;
17958
+ Object.defineProperty(globalThis, "opener", {
17959
+ configurable: true,
17960
+ get() {
17961
+ if (__csimOpenerOverride !== void 0) return __csimOpenerOverride;
17962
+ const fn = globalThis.__csimWindowOpener;
17963
+ const handle = typeof fn === "function" ? fn() : null;
17964
+ return handle ? csimWindowProxy(handle) : null;
17965
+ },
17966
+ set(v) {
17967
+ __csimOpenerOverride = v;
17968
+ }
17969
+ });
17970
+ globalThis.__csim_deliverWindowMessages = function(events) {
17971
+ if (!events || !events.length) return;
17972
+ for (const ev of events) {
17973
+ const source = ev && ev.sourceHandle ? csimWindowProxy(ev.sourceHandle) : null;
17974
+ dispatchWithOnHandler(globalThis, new MessageEvent("message", {
17975
+ data: ev ? ev.data : void 0,
17976
+ origin: ev && ev.origin || "",
17977
+ source,
17978
+ lastEventId: "",
17979
+ ports: []
17980
+ }));
17981
+ }
17982
+ };
17319
17983
  globalThis.NodeFilter = {
17320
17984
  SHOW_ALL: 4294967295,
17321
17985
  SHOW_ELEMENT: 1,
@@ -17816,10 +18480,15 @@
17816
18480
  this._url = _url || null;
17817
18481
  if (typeof init === "string") {
17818
18482
  this._parseQuery(init);
18483
+ } else if (Array.isArray(init)) {
18484
+ for (const e of init) {
18485
+ if (e == null || e.length !== 2) {
18486
+ throw new TypeError("Failed to construct 'URLSearchParams': each pair must have exactly two elements.");
18487
+ }
18488
+ this._entries.push([String(e[0]), String(e[1])]);
18489
+ }
17819
18490
  } else if (init && typeof init.forEach === "function") {
17820
18491
  init.forEach((v, k) => this._entries.push([String(k), String(v)]));
17821
- } else if (Array.isArray(init)) {
17822
- for (const e of init) this._entries.push([String(e[0]), String(e[1])]);
17823
18492
  } else if (init && typeof init === "object") {
17824
18493
  for (const k of Object.keys(init)) this._entries.push([k, String(init[k])]);
17825
18494
  }
@@ -18347,7 +19016,7 @@
18347
19016
  function fireCEConnect(subtree) {
18348
19017
  walkSubtree(subtree, (el) => {
18349
19018
  if (el.nodeType !== NODE_ELEMENT) return;
18350
- if (!__inHTMLGrafting && el._tag === "script" && !el._csimRan) maybeRunScript(el);
19019
+ if (!__inHTMLGrafting && el._tag === "script" && !el._csimRan && el.isConnected) maybeRunScript(el);
18351
19020
  if (el._tag === "link") maybeFireLinkLoad(el);
18352
19021
  if (el._tag === "iframe" || el._tag === "frame") maybeFireFrameLoad(el);
18353
19022
  ceTryConnect(el);
@@ -18409,9 +19078,9 @@
18409
19078
  function maybeRunScript(el) {
18410
19079
  const type = (el._attrs.type || "").toLowerCase();
18411
19080
  if (type && type !== "text/javascript" && type !== "application/javascript" && type !== "application/x-javascript" && type !== "text/ecmascript") return;
18412
- el._csimRan = true;
18413
19081
  let body;
18414
19082
  if (el._attrs.src) {
19083
+ el._csimRan = true;
18415
19084
  try {
18416
19085
  const resp = __rackFetch("GET", el._attrs.src, "", null, "follow");
18417
19086
  if (!resp || resp.status >= 400) {
@@ -18423,12 +19092,14 @@
18423
19092
  dispatchScriptLoad(el, false);
18424
19093
  return;
18425
19094
  }
19095
+ if (!body) {
19096
+ dispatchScriptLoad(el, true);
19097
+ return;
19098
+ }
18426
19099
  } else {
18427
19100
  body = scriptText(el);
18428
- }
18429
- if (!body) {
18430
- dispatchScriptLoad(el, true);
18431
- return;
19101
+ if (!body) return;
19102
+ el._csimRan = true;
18432
19103
  }
18433
19104
  const label = el._attrs.src || "inline://" + hashStr(body);
18434
19105
  let _ok = true;
@@ -18441,6 +19112,11 @@
18441
19112
  dispatchScriptLoad(el, _ok);
18442
19113
  }
18443
19114
  __name(maybeRunScript, "maybeRunScript");
19115
+ globalThis.__csimScriptChildrenChanged = function(el) {
19116
+ if (!__inHTMLGrafting && el && el._tag === "script" && !el._csimRan && el.isConnected) {
19117
+ maybeRunScript(el);
19118
+ }
19119
+ };
18444
19120
  globalThis.Document = Document;
18445
19121
  globalThis.Element = Element;
18446
19122
  installXPath(Document.prototype);
@@ -18453,7 +19129,7 @@
18453
19129
  installNodeConstants(Node);
18454
19130
  globalThis.Text = Text;
18455
19131
  installDomClassAliases({ Element, Document, Text });
18456
- globalThis.document = new Document();
19132
+ globalThis.document = createHtmlPageDocument(true);
18457
19133
  globalThis.window = globalThis;
18458
19134
  globalThis.EventTarget = EventTarget;
18459
19135
  globalThis.Blob = Blob;
@@ -18487,17 +19163,19 @@
18487
19163
  });
18488
19164
  const ownerURL = (this._ownerDoc || globalThis.document).URL;
18489
19165
  if (ownerURL) doc._url = ownerURL;
19166
+ doc._noBrowsingContext = true;
18490
19167
  return doc;
18491
19168
  }
18492
19169
  };
18493
19170
  function parseXMLDocument(xml) {
18494
19171
  const doc = new Document();
18495
19172
  doc._children = newChildList();
18496
- doc.documentElement = null;
19173
+ doc._url = void 0;
19174
+ doc._noBrowsingContext = false;
19175
+ doc.readyState = "loading";
18497
19176
  for (const node of parseXml(String(xml == null ? "" : xml))) {
18498
19177
  node._parent = doc;
18499
19178
  doc._children.push(node);
18500
- if (node.nodeType === NODE_ELEMENT && !doc.documentElement) doc.documentElement = node;
18501
19179
  }
18502
19180
  return doc;
18503
19181
  }
@@ -18555,7 +19233,8 @@
18555
19233
  }
18556
19234
  }
18557
19235
  if (typeof globalThis.__csim_createFrameRealm === "function" && globalThis.RustyRacer && typeof globalThis.RustyRacer.contextGlobal === "function") {
18558
- const id = globalThis.__csim_createFrameRealm(frameUrl, body, contentType);
19236
+ const parentId = typeof globalThis.RustyRacer.contextOf === "function" ? globalThis.RustyRacer.contextOf(globalThis) : 0;
19237
+ const id = globalThis.__csim_createFrameRealm(frameUrl, body, contentType, parentId);
18559
19238
  if (id != null) {
18560
19239
  frameEl._frameRealmId = id;
18561
19240
  (globalThis.__csimChildRealmIds || (globalThis.__csimChildRealmIds = /* @__PURE__ */ new Set())).add(id);
@@ -18702,7 +19381,6 @@
18702
19381
  c._parent = null;
18703
19382
  }
18704
19383
  dx._children = newChildList();
18705
- dx.documentElement = null;
18706
19384
  dx._contentType = __ct;
18707
19385
  for (const c of xmlDoc._children) {
18708
19386
  c._parent = dx;
@@ -18710,7 +19388,6 @@
18710
19388
  n._ownerDoc = dx;
18711
19389
  });
18712
19390
  dx._children.push(c);
18713
- if (c.nodeType === NODE_ELEMENT && !dx.documentElement) dx.documentElement = c;
18714
19391
  }
18715
19392
  registerSubtree(dx);
18716
19393
  globalThis.__csimFireCEConnect(dx);
@@ -18832,7 +19509,10 @@
18832
19509
  } else {
18833
19510
  body = scriptText(s);
18834
19511
  }
18835
- if (!body) continue;
19512
+ if (!body) {
19513
+ s._csimRan = false;
19514
+ continue;
19515
+ }
18836
19516
  const label = s._attrs.src || "inline://" + hashStr(body);
18837
19517
  const prevCurrent = globalThis.document && globalThis.document._currentScript;
18838
19518
  if (globalThis.document) globalThis.document._currentScript = s;