single-file-core 1.6.10 → 1.6.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/core/helper.js CHANGED
@@ -94,6 +94,13 @@ const EMPTY_RESOURCE = "data:,";
94
94
  const POSTER_CONTENT_TYPES = ["image/webp", "image/jpeg"];
95
95
  const POSTER_QUALITY = 0.8;
96
96
  const NESTING_TRACK_ID_ATTRIBUTE_NAME = "data-sf-nesting-track-id";
97
+ const NESTING_START_MARKER = NESTING_TRACK_ID_ATTRIBUTE_NAME + "-start ";
98
+ const NESTING_END_MARKER = NESTING_TRACK_ID_ATTRIBUTE_NAME + "-end ";
99
+ const NESTING_RECREATED_ATTRIBUTE_NAME = NESTING_TRACK_ID_ATTRIBUTE_NAME + "-recreated";
100
+ const NESTING_SHADOW_ROOT_TRACK_ID_PREFIX = "s";
101
+ const HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
102
+ const RAW_TEXT_TAG_NAMES = ["SCRIPT", "STYLE", "TEXTAREA", "TITLE", "XMP", "IFRAME", "NOEMBED", "NOFRAMES", "PLAINTEXT", "NOSCRIPT"];
103
+ const COMMENT_NODE_FILTER = 128;
97
104
  const DEPRECATED_OPTION_NAMES = {
98
105
  loadDeferredImages: "loadDeferredContent",
99
106
  loadDeferredImagesMaxIdleTime: "loadDeferredContentMaxIdleTime",
@@ -141,6 +148,8 @@ export {
141
148
  parseDocContent,
142
149
  markInvalidNesting,
143
150
  fixInvalidNesting,
151
+ removeNestingMarkers,
152
+ getNestingMarkerData,
144
153
  normalizeOptions,
145
154
  ON_BEFORE_CAPTURE_EVENT_NAME,
146
155
  ON_AFTER_CAPTURE_EVENT_NAME,
@@ -171,6 +180,9 @@ export {
171
180
  MESSAGE_PREFIX,
172
181
  NO_SCRIPT_PROPERTY_NAME,
173
182
  NESTING_TRACK_ID_ATTRIBUTE_NAME,
183
+ NESTING_START_MARKER,
184
+ NESTING_END_MARKER,
185
+ NESTING_RECREATED_ATTRIBUTE_NAME,
174
186
  getPosterDataURI
175
187
  };
176
188
 
@@ -311,6 +323,7 @@ function preProcessDoc(doc, win, options) {
311
323
  markedElements: []
312
324
  };
313
325
  }
326
+ setNestingMarkersData(doc);
314
327
  let referrer = "";
315
328
  if (doc.referrer) {
316
329
  try {
@@ -343,18 +356,30 @@ function markInvalidNesting(doc) {
343
356
  if (!doc.body) {
344
357
  return;
345
358
  }
346
- addTrackIds(doc.body);
347
- const verificationDoc = parseDocContent(serialize(doc));
348
- const markedMap = buildTrackIdMap(doc.body);
349
- const normalizedMap = buildTrackIdMap(verificationDoc.body);
359
+ removeNestingMarkers(doc);
360
+ markInvalidNestingInRoot(doc, doc.body, "", () => serialize(doc));
361
+ getShadowRoots(doc.body).forEach((shadowRoot, indexShadowRoot) =>
362
+ markInvalidNestingInRoot(doc, shadowRoot, NESTING_SHADOW_ROOT_TRACK_ID_PREFIX + indexShadowRoot, () => shadowRoot.innerHTML));
363
+ }
364
+
365
+ function markInvalidNestingInRoot(doc, root, rootTrackId, getContent) {
366
+ if (rootTrackId) {
367
+ Array.from(root.children).forEach((child, indexChild) => addTrackIds(child, indexChild, rootTrackId));
368
+ } else {
369
+ addTrackIds(root);
370
+ }
371
+ const verificationDoc = parseDocContent(getContent());
372
+ const markedMap = buildTrackIdMap(root);
373
+ const normalizedMap = buildTrackIdMap(verificationDoc.documentElement);
350
374
  const trackIds = new Set();
375
+ const droppedElements = [];
351
376
  Object.keys(markedMap).forEach(id => {
352
377
  if (id in normalizedMap) {
353
378
  const markedParent = markedMap[id].parentElement?.getAttribute(NESTING_TRACK_ID_ATTRIBUTE_NAME) || null;
354
379
  const normalizedParent = normalizedMap[id]?.parentElement?.getAttribute(NESTING_TRACK_ID_ATTRIBUTE_NAME) || null;
355
380
  if (markedParent !== normalizedParent) {
356
381
  let current = markedMap[id];
357
- while (current && current !== doc.body) {
382
+ while (current && current !== root) {
358
383
  const currentId = current.getAttribute(NESTING_TRACK_ID_ATTRIBUTE_NAME);
359
384
  if (currentId) {
360
385
  trackIds.add(currentId);
@@ -362,9 +387,22 @@ function markInvalidNesting(doc) {
362
387
  current = current.parentElement;
363
388
  }
364
389
  }
390
+ } else if (testDroppedElement(markedMap[id])) {
391
+ trackIds.add(id);
392
+ droppedElements.push(markedMap[id]);
365
393
  }
366
394
  });
367
- cleanupTrackIds(doc.body, trackIds);
395
+ droppedElements.forEach(element => {
396
+ const id = element.getAttribute(NESTING_TRACK_ID_ATTRIBUTE_NAME);
397
+ element.prepend(doc.createComment(NESTING_START_MARKER + id));
398
+ element.append(doc.createComment(NESTING_END_MARKER + id));
399
+ });
400
+ setNestingMarkersData(root);
401
+ if (rootTrackId) {
402
+ Array.from(root.children).forEach(child => cleanupTrackIds(child, trackIds));
403
+ } else {
404
+ cleanupTrackIds(root, trackIds);
405
+ }
368
406
 
369
407
  function addTrackIds(element, index = 0, parentTrackId = "") {
370
408
  const trackId = parentTrackId ? `${parentTrackId}.${index + 1}` : `${index + 1}`;
@@ -375,9 +413,13 @@ function markInvalidNesting(doc) {
375
413
  Array.from(element.children).forEach((child, indexChild) => addTrackIds(child, indexChild, trackId));
376
414
  }
377
415
 
378
- function buildTrackIdMap(element) {
416
+ function buildTrackIdMap(root) {
379
417
  const trackIds = {};
380
- traverse(element);
418
+ if (root.getAttribute) {
419
+ traverse(root);
420
+ } else {
421
+ Array.from(root.children).forEach(traverse);
422
+ }
381
423
  return trackIds;
382
424
 
383
425
  function traverse(element) {
@@ -391,6 +433,21 @@ function markInvalidNesting(doc) {
391
433
  }
392
434
  }
393
435
 
436
+ function testDroppedElement(element) {
437
+ if (element.namespaceURI != HTML_NAMESPACE) {
438
+ return false;
439
+ }
440
+ let ancestor = element.parentElement;
441
+ while (ancestor) {
442
+ const tagName = ancestor.tagName.toUpperCase();
443
+ if (tagName == "TEMPLATE" || RAW_TEXT_TAG_NAMES.includes(tagName)) {
444
+ return false;
445
+ }
446
+ ancestor = ancestor.parentElement;
447
+ }
448
+ return true;
449
+ }
450
+
394
451
  function cleanupTrackIds(element, toKeep) {
395
452
  const id = element.getAttribute(NESTING_TRACK_ID_ATTRIBUTE_NAME);
396
453
  if (id && !toKeep.has(id)) {
@@ -400,33 +457,180 @@ function markInvalidNesting(doc) {
400
457
  }
401
458
  }
402
459
 
403
- function fixInvalidNesting(document, NESTING_TRACK_ID_ATTRIBUTE_NAME, preventCleanup = false) {
404
- const trackIds = {};
460
+ function getShadowRoots(element, shadowRoots = []) {
461
+ Array.from(element.children).forEach(child => {
462
+ if (child.namespaceURI == HTML_NAMESPACE && !child.classList.contains(SINGLE_FILE_UI_ELEMENT_CLASS) && child.tagName.toLowerCase() != INFOBAR_TAGNAME) {
463
+ const shadowRoot = getShadowRoot(child);
464
+ if (shadowRoot) {
465
+ shadowRoots.push(shadowRoot);
466
+ getShadowRoots(shadowRoot, shadowRoots);
467
+ }
468
+ }
469
+ getShadowRoots(child, shadowRoots);
470
+ });
471
+ return shadowRoots;
472
+ }
473
+
474
+ function getNestingMarkerData(element) {
475
+ return encodeURIComponent(JSON.stringify({
476
+ tag: element.localName,
477
+ attributes: Array.from(element.attributes)
478
+ .filter(attribute => attribute.name != NESTING_RECREATED_ATTRIBUTE_NAME)
479
+ .map(attribute => [attribute.name, attribute.value])
480
+ }));
481
+ }
482
+
483
+ function setNestingMarkersData(root) {
484
+ const walker = (root.ownerDocument || root).createTreeWalker(root, COMMENT_NODE_FILTER);
485
+ while (walker.nextNode()) {
486
+ const comment = walker.currentNode;
487
+ if (comment.data.startsWith(NESTING_START_MARKER)) {
488
+ const id = comment.data.substring(NESTING_START_MARKER.length).split(" ")[0];
489
+ comment.data = NESTING_START_MARKER + id + " " + getNestingMarkerData(comment.parentNode);
490
+ }
491
+ }
492
+ }
493
+
494
+ function removeNestingMarkers(doc) {
495
+ if (doc.body) {
496
+ [doc, ...getShadowRoots(doc.body)].forEach(root => {
497
+ const comments = [];
498
+ const walker = doc.createTreeWalker(root, COMMENT_NODE_FILTER);
499
+ while (walker.nextNode()) {
500
+ if (walker.currentNode.data.startsWith(NESTING_START_MARKER) || walker.currentNode.data.startsWith(NESTING_END_MARKER)) {
501
+ comments.push(walker.currentNode);
502
+ }
503
+ }
504
+ comments.forEach(comment => comment.remove());
505
+ });
506
+ }
507
+ }
508
+
509
+ function fixInvalidNesting(document, NESTING_TRACK_ID_ATTRIBUTE_NAME, preventCleanup = false, options = {}) {
510
+ const START_MARKER = NESTING_TRACK_ID_ATTRIBUTE_NAME + "-start ";
511
+ const END_MARKER = NESTING_TRACK_ID_ATTRIBUTE_NAME + "-end ";
512
+ const RECREATED_ATTRIBUTE_NAME = NESTING_TRACK_ID_ATTRIBUTE_NAME + "-recreated";
405
513
  if (document.currentScript) {
406
514
  document.currentScript.remove();
407
515
  }
408
- buildTrackIdMap(document.body);
409
- Object.keys(trackIds).forEach(id => {
410
- const element = trackIds[id];
411
- const idParts = id.split(".");
412
- if (idParts.length > 1) {
413
- const parentId = idParts.slice(0, -1).join(".");
414
- const expectedParent = trackIds[parentId];
415
- if (expectedParent && element.parentElement !== expectedParent && !element.contains(expectedParent)) {
416
- expectedParent.appendChild(element);
417
- }
516
+ const roots = [];
517
+ if (options.rootElement) {
518
+ roots.push(options.rootElement);
519
+ } else if (document.body) {
520
+ addRoots(document.body);
521
+ }
522
+ roots.forEach(root => {
523
+ recreateElements(root);
524
+ if (!options.recreateOnly) {
525
+ moveElements(root);
418
526
  }
419
527
  });
420
528
  if (!preventCleanup) {
421
- document.querySelectorAll("[" + NESTING_TRACK_ID_ATTRIBUTE_NAME + "]").forEach(element => element.removeAttribute(NESTING_TRACK_ID_ATTRIBUTE_NAME));
529
+ roots.forEach(root => {
530
+ const elements = Array.from(root.querySelectorAll("[" + NESTING_TRACK_ID_ATTRIBUTE_NAME + "]"));
531
+ if (root.getAttribute && root.getAttribute(NESTING_TRACK_ID_ATTRIBUTE_NAME)) {
532
+ elements.push(root);
533
+ }
534
+ elements.forEach(element => element.removeAttribute(NESTING_TRACK_ID_ATTRIBUTE_NAME));
535
+ });
422
536
  }
423
537
 
424
- function buildTrackIdMap(element) {
425
- const id = element.getAttribute(NESTING_TRACK_ID_ATTRIBUTE_NAME);
426
- if (id) {
427
- trackIds[id] = element;
538
+ function addRoots(root) {
539
+ roots.push(root);
540
+ root.querySelectorAll("*").forEach(element => {
541
+ if (element.shadowRoot) {
542
+ addRoots(element.shadowRoot);
543
+ }
544
+ });
545
+ }
546
+
547
+ function recreateElements(root) {
548
+ const startComments = [];
549
+ const walker = document.createTreeWalker(root, 128);
550
+ while (walker.nextNode()) {
551
+ if (walker.currentNode.data.startsWith(START_MARKER)) {
552
+ startComments.push(walker.currentNode);
553
+ }
554
+ }
555
+ startComments.forEach(startComment => {
556
+ const separatorIndex = startComment.data.indexOf(" ", START_MARKER.length);
557
+ let endComment, data;
558
+ if (separatorIndex != -1) {
559
+ const id = startComment.data.substring(START_MARKER.length, separatorIndex);
560
+ endComment = startComment.nextSibling;
561
+ while (endComment && !(endComment.nodeType == 8 && endComment.data == END_MARKER + id)) {
562
+ endComment = endComment.nextSibling;
563
+ }
564
+ try {
565
+ data = globalThis.JSON.parse(decodeURIComponent(startComment.data.substring(separatorIndex + 1)));
566
+ } catch {
567
+ /* ignored */
568
+ }
569
+ }
570
+ if (endComment && data) {
571
+ const element = document.createElement(data.tag);
572
+ data.attributes.forEach(([name, value]) => {
573
+ try {
574
+ element.setAttribute(name, value);
575
+ } catch {
576
+ /* ignored */
577
+ }
578
+ });
579
+ if (preventCleanup) {
580
+ element.setAttribute(RECREATED_ATTRIBUTE_NAME, "");
581
+ }
582
+ startComment.before(element);
583
+ while (startComment.nextSibling != endComment) {
584
+ element.appendChild(startComment.nextSibling);
585
+ }
586
+ startComment.remove();
587
+ endComment.remove();
588
+ }
589
+ });
590
+ }
591
+
592
+ function moveElements(root) {
593
+ const trackIds = {};
594
+ const elements = [];
595
+ if (root.getAttribute) {
596
+ buildTrackIdMap(root);
597
+ } else {
598
+ Array.from(root.children).forEach(buildTrackIdMap);
599
+ }
600
+ elements.forEach(element => {
601
+ const id = element.getAttribute(NESTING_TRACK_ID_ATTRIBUTE_NAME);
602
+ const originalElement = trackIds[id];
603
+ if (originalElement != element) {
604
+ if (!preventCleanup) {
605
+ if (originalElement.contains(element)) {
606
+ element.replaceWith(...element.childNodes);
607
+ } else {
608
+ originalElement.append(...element.childNodes);
609
+ element.remove();
610
+ }
611
+ }
612
+ } else {
613
+ const idParts = id.split(".");
614
+ if (idParts.length > 1) {
615
+ const parentId = idParts.slice(0, -1).join(".");
616
+ const expectedParent = trackIds[parentId];
617
+ if (expectedParent && element.parentElement !== expectedParent && !element.contains(expectedParent)) {
618
+ expectedParent.appendChild(element);
619
+ }
620
+ }
621
+ }
622
+ });
623
+
624
+ function buildTrackIdMap(element) {
625
+ const id = element.getAttribute(NESTING_TRACK_ID_ATTRIBUTE_NAME);
626
+ if (id) {
627
+ if (!(id in trackIds)) {
628
+ trackIds[id] = element;
629
+ }
630
+ elements.push(element);
631
+ }
632
+ Array.from(element.children).forEach(buildTrackIdMap);
428
633
  }
429
- Array.from(element.children).forEach(buildTrackIdMap);
430
634
  }
431
635
  }
432
636
 
@@ -509,6 +713,7 @@ function getElementsInfo(win, doc, element, options, data = { usedFonts: new Map
509
713
  // ignored
510
714
  }
511
715
  getElementsInfo(win, doc, shadowRoot, options, data, adoptedStyleSheetsCache, elementHidden);
716
+ setNestingMarkersData(shadowRoot);
512
717
  shadowRootInfo.content = shadowRoot.innerHTML;
513
718
  shadowRootInfo.mode = shadowRoot.mode;
514
719
  shadowRootInfo.delegateFocus = shadowRoot.delegatesFocus;
@@ -852,6 +1057,7 @@ function testHiddenElement(element, computedStyle) {
852
1057
  }
853
1058
 
854
1059
  function postProcessDoc(doc, markedElements, invalidElements) {
1060
+ removeNestingMarkers(doc);
855
1061
  doc.querySelectorAll("[" + DISABLED_NOSCRIPT_ATTRIBUTE_NAME + "]").forEach(element => {
856
1062
  element.textContent = element.getAttribute(DISABLED_NOSCRIPT_ATTRIBUTE_NAME);
857
1063
  element.removeAttribute(DISABLED_NOSCRIPT_ATTRIBUTE_NAME);
package/core/index.js CHANGED
@@ -212,6 +212,9 @@ class Runner {
212
212
  this.options.frames = [];
213
213
  }
214
214
  this.options.content = this.options.content || (rootDocDefined ? util.serialize(this.options.doc) : null);
215
+ if (rootDocDefined) {
216
+ util.removeNestingMarkers(this.options.doc);
217
+ }
215
218
  this.onprogress = options.onprogress || (() => { });
216
219
  }
217
220
 
@@ -498,6 +501,7 @@ class Processor {
498
501
  pageContent = content.data || "";
499
502
  }
500
503
  this.doc = util.parseDocContent(pageContent, this.baseURI);
504
+ util.fixInvalidNesting(this.doc, true, { recreateOnly: true });
501
505
  removeInsertedParagraphs(this.doc);
502
506
  this.nestingPositions = getNestingPositions(this.doc);
503
507
  util.fixInvalidNesting(this.doc);
@@ -609,7 +613,8 @@ class Processor {
609
613
  size = util.getContentSize(this.doc.documentElement.outerHTML);
610
614
  }
611
615
  restoreNestingPositions(this.nestingPositions);
612
- if (this.doc.querySelector(`[${util.NESTING_TRACK_ID_ATTRIBUTE_NAME}]`)) {
616
+ const collapsedElementCount = collapseRecreatedElements(this.doc);
617
+ if (collapsedElementCount || this.doc.querySelector(`[${util.NESTING_TRACK_ID_ATTRIBUTE_NAME}]`)) {
613
618
  const scriptElement = this.doc.createElement("script");
614
619
  scriptElement.textContent = `(${util.getFixInvalidNestingSource()})(document, "${util.NESTING_TRACK_ID_ATTRIBUTE_NAME}");`;
615
620
  this.doc.body.appendChild(scriptElement);
@@ -1442,6 +1447,7 @@ class Processor {
1442
1447
  insertShadowRootContents() {
1443
1448
  const doc = this.doc;
1444
1449
  const options = this.options;
1450
+ const nestingPositions = this.nestingPositions || [];
1445
1451
  if (options.shadowRoots && options.shadowRoots.length) {
1446
1452
  processElement(this.doc);
1447
1453
  }
@@ -1482,6 +1488,13 @@ class Processor {
1482
1488
  if (shadowDoc.body) {
1483
1489
  shadowDoc.body.childNodes.forEach(node => templateElement.appendChild(shadowDoc.importNode(node, true)));
1484
1490
  }
1491
+ util.fixInvalidNesting(doc, true, { rootElement: templateElement, recreateOnly: true });
1492
+ removeInsertedParagraphs(templateElement);
1493
+ nestingPositions.push(...getNestingPositions(templateElement));
1494
+ util.fixInvalidNesting(doc, true, { rootElement: templateElement });
1495
+ if (templateElement.querySelector(`[${util.NESTING_TRACK_ID_ATTRIBUTE_NAME}]`)) {
1496
+ templateElement.setAttribute(SHADOWROOT_ATTRIBUTE_NAME, "open");
1497
+ }
1485
1498
  processElement(templateElement);
1486
1499
  if (element.firstChild) {
1487
1500
  element.insertBefore(templateElement, element.firstChild);
@@ -1799,15 +1812,20 @@ function getNestingPositions(doc) {
1799
1812
  return Array.from(doc.querySelectorAll(`[${util.NESTING_TRACK_ID_ATTRIBUTE_NAME}]`)).map(element => ({
1800
1813
  element,
1801
1814
  parentNode: element.parentNode,
1815
+ previousSibling: element.previousSibling,
1802
1816
  nextSibling: element.nextSibling
1803
1817
  }));
1804
1818
  }
1805
1819
 
1806
1820
  function restoreNestingPositions(positions) {
1807
1821
  if (positions) {
1808
- positions.slice().reverse().forEach(({ element, parentNode, nextSibling }) => {
1822
+ positions.forEach(({ element, parentNode, previousSibling, nextSibling }) => {
1809
1823
  if (element.isConnected && parentNode && parentNode.isConnected) {
1810
- if (nextSibling && nextSibling.parentNode == parentNode) {
1824
+ if (previousSibling && previousSibling.parentNode == parentNode) {
1825
+ parentNode.insertBefore(element, previousSibling.nextSibling);
1826
+ } else if (!previousSibling) {
1827
+ parentNode.insertBefore(element, parentNode.firstChild);
1828
+ } else if (nextSibling && nextSibling.parentNode == parentNode) {
1811
1829
  parentNode.insertBefore(element, nextSibling);
1812
1830
  } else {
1813
1831
  parentNode.appendChild(element);
@@ -1817,6 +1835,20 @@ function restoreNestingPositions(positions) {
1817
1835
  }
1818
1836
  }
1819
1837
 
1838
+ function collapseRecreatedElements(doc) {
1839
+ const elements = Array.from(doc.querySelectorAll(`[${util.NESTING_RECREATED_ATTRIBUTE_NAME}]`)).reverse();
1840
+ elements.forEach(element => {
1841
+ const id = element.getAttribute(util.NESTING_TRACK_ID_ATTRIBUTE_NAME);
1842
+ element.before(doc.createComment(util.NESTING_START_MARKER + id + " " + util.getNestingMarkerData(element)));
1843
+ while (element.firstChild) {
1844
+ element.before(element.firstChild);
1845
+ }
1846
+ element.before(doc.createComment(util.NESTING_END_MARKER + id));
1847
+ element.remove();
1848
+ });
1849
+ return elements.length;
1850
+ }
1851
+
1820
1852
  function removeInsertedParagraphs(doc) {
1821
1853
  const trackedElements = new Map();
1822
1854
  doc.querySelectorAll(`[${util.NESTING_TRACK_ID_ATTRIBUTE_NAME}]`).forEach(element =>
package/core/util.js CHANGED
@@ -128,8 +128,14 @@ function getInstance(utilOptions) {
128
128
  return doc;
129
129
  }
130
130
  },
131
- fixInvalidNesting(doc, preventCleanup = true) {
132
- helper.fixInvalidNesting(doc, helper.NESTING_TRACK_ID_ATTRIBUTE_NAME, preventCleanup);
131
+ fixInvalidNesting(doc, preventCleanup = true, options) {
132
+ helper.fixInvalidNesting(doc, helper.NESTING_TRACK_ID_ATTRIBUTE_NAME, preventCleanup, options);
133
+ },
134
+ removeNestingMarkers(doc) {
135
+ helper.removeNestingMarkers(doc);
136
+ },
137
+ getNestingMarkerData(element) {
138
+ return helper.getNestingMarkerData(element);
133
139
  },
134
140
  markInvalidNesting(doc) {
135
141
  helper.markInvalidNesting(doc, helper.NESTING_TRACK_ID_ATTRIBUTE_NAME);
@@ -226,6 +232,9 @@ function getInstance(utilOptions) {
226
232
  WAIT_FOR_USERSCRIPT_PROPERTY_NAME: helper.WAIT_FOR_USERSCRIPT_PROPERTY_NAME,
227
233
  NO_SCRIPT_PROPERTY_NAME: helper.NO_SCRIPT_PROPERTY_NAME,
228
234
  NESTING_TRACK_ID_ATTRIBUTE_NAME: helper.NESTING_TRACK_ID_ATTRIBUTE_NAME,
235
+ NESTING_START_MARKER: helper.NESTING_START_MARKER,
236
+ NESTING_END_MARKER: helper.NESTING_END_MARKER,
237
+ NESTING_RECREATED_ATTRIBUTE_NAME: helper.NESTING_RECREATED_ATTRIBUTE_NAME,
229
238
  getPosterDataURI: helper.getPosterDataURI
230
239
  };
231
240
 
@@ -77,13 +77,13 @@ function process(doc, compressHTML) {
77
77
  return docTypeString + serialize(doc.documentElement, compressHTML);
78
78
  }
79
79
 
80
- function serialize(node, compressHTML, isSVG) {
80
+ function serialize(node, compressHTML) {
81
81
  if (node.nodeType == Node_TEXT_NODE) {
82
82
  return serializeTextNode(node);
83
83
  } else if (node.nodeType == Node_COMMENT_NODE) {
84
84
  return serializeCommentNode(node);
85
85
  } else if (node.nodeType == Node_ELEMENT_NODE) {
86
- return serializeElement(node, compressHTML, isSVG);
86
+ return serializeElement(node, compressHTML);
87
87
  }
88
88
  }
89
89
 
@@ -107,7 +107,7 @@ function serializeCommentNode(commentNode) {
107
107
  return "<!--" + commentNode.textContent + "-->";
108
108
  }
109
109
 
110
- function serializeElement(element, compressHTML, isSVG) {
110
+ function serializeElement(element, compressHTML) {
111
111
  const tagName = getTagName(element);
112
112
  const omittedStartTag = compressHTML && OMITTED_START_TAGS.find(omittedStartTag => tagName == getTagName(omittedStartTag) && omittedStartTag.accept(element));
113
113
  let content = "";
@@ -119,10 +119,10 @@ function serializeElement(element, compressHTML, isSVG) {
119
119
  if (tagName == "TEMPLATE" && !element.childNodes.length) {
120
120
  content += element.innerHTML;
121
121
  } else {
122
- Array.from(element.childNodes).forEach(childNode => content += serialize(childNode, compressHTML, isSVG || tagName == "svg"));
122
+ Array.from(element.childNodes).forEach(childNode => content += serialize(childNode, compressHTML));
123
123
  }
124
124
  const omittedEndTag = compressHTML && OMITTED_END_TAGS.find(omittedEndTag => tagName == getTagName(omittedEndTag) && omittedEndTag.accept(element.nextSibling, element));
125
- if (isSVG || (!omittedEndTag && !VOID_TAG_NAMES.includes(tagName))) {
125
+ if (!omittedEndTag && !VOID_TAG_NAMES.includes(tagName)) {
126
126
  content += "</" + tagName.toLowerCase() + ">";
127
127
  }
128
128
  return content;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "single-file-core",
3
- "version": "1.6.10",
3
+ "version": "1.6.12",
4
4
  "description": "SingleFile Core",
5
5
  "author": "Gildas Lormeau",
6
6
  "license": "AGPL-3.0-or-later",
@@ -31,6 +31,7 @@ import {
31
31
  WAIT_FOR_USERSCRIPT_PROPERTY_NAME,
32
32
  preProcessDoc,
33
33
  postProcessDoc,
34
+ markInvalidNesting,
34
35
  getShadowRoot
35
36
  } from "./core/helper.js";
36
37
 
@@ -46,6 +47,7 @@ const helper = {
46
47
  serialize(doc, compressHTML) {
47
48
  return serializer.process(doc, compressHTML);
48
49
  },
50
+ markInvalidNesting,
49
51
  getShadowRoot
50
52
  };
51
53