html2canvas-pro 2.0.1 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * html2canvas-pro 2.0.1 <https://yorickshan.github.io/html2canvas-pro/>
2
+ * html2canvas-pro 2.0.2 <https://yorickshan.github.io/html2canvas-pro/>
3
3
  * Copyright (c) 2024-present yorickshan and html2canvas-pro contributors
4
4
  * Released under MIT License
5
5
  */
@@ -6597,36 +6597,50 @@
6597
6597
  * */
6598
6598
  const baseUri = documentClone.baseURI;
6599
6599
  documentClone.open();
6600
+ const rawHTML = serializeDoctype(document.doctype) + '<html></html>';
6600
6601
  try {
6601
- // fixing "This document requires 'TrustedHTML' assignment. The action has been blocked." error
6602
- // @ts-ignore
6603
- const policy = trustedTypes.createPolicy('my-policy', {
6604
- createHTML: (string) => string
6605
- });
6606
- const rawHTML = serializeDoctype(document.doctype) + '<html></html>';
6607
- const trustedHTML = policy.createHTML(rawHTML);
6608
- documentClone.write(trustedHTML);
6602
+ // Fixing "This document requires 'TrustedHTML' assignment. The action has been blocked." error.
6603
+ // Reuse existing policy when present (e.g. second html2canvas call) to avoid createPolicy duplicate-name throw.
6604
+ const ownerWindow = this.referenceElement.ownerDocument?.defaultView;
6605
+ const trustedTypesFactory = ownerWindow && ownerWindow.trustedTypes;
6606
+ let policy = trustedTypesFactory?.getPolicy?.('html2canvas-pro');
6607
+ if (!policy && trustedTypesFactory) {
6608
+ policy = trustedTypesFactory.createPolicy('html2canvas-pro', {
6609
+ createHTML: (string) => string
6610
+ });
6611
+ }
6612
+ if (policy) {
6613
+ documentClone.write(policy.createHTML(rawHTML));
6614
+ }
6615
+ else {
6616
+ documentClone.write(rawHTML);
6617
+ }
6609
6618
  }
6610
- catch (e) {
6611
- // if browser does not support trustedTypes
6612
- documentClone.write(serializeDoctype(document.doctype) + '<html></html>');
6619
+ catch (_e) {
6620
+ documentClone.write(rawHTML);
6613
6621
  }
6614
6622
  // Chrome scrolls the parent document for some reason after the write to the cloned window???
6615
6623
  restoreOwnerScroll(this.referenceElement.ownerDocument, scrollX, scrollY);
6616
6624
  /**
6617
- * Note: adoptNode() should be called AFTER documentClone.open() and close()
6625
+ * IMPORTANT: documentClone.close() MUST be called BEFORE adoptNode().
6618
6626
  *
6619
- * In Chrome, calling adoptNode() before or during open/write may cause
6620
- * styles with uppercase characters in class names (e.g. ".MyClass") to not apply correctly.
6627
+ * In Chrome, calling adoptNode() while the document is still "open"
6628
+ * (between document.open() and document.close()) causes CSS rules with
6629
+ * uppercase characters in class names (e.g. ".MyClass") to not match
6630
+ * correctly. Chrome's CSS engine only enters a fully-resolved matching
6631
+ * mode once the document is closed.
6621
6632
  *
6622
- * Fix:
6623
- * - Make sure adoptNode() is called after documentClone.open() and close()
6624
- * - This allows Chrome to properly match and apply all CSS rules including mixed-case class selectors.
6625
- * */
6633
+ * Correct order: open() → write() → close() → adoptNode() → replaceChild()
6634
+ *
6635
+ * Timing: close() queues the iframe 'load' event; because JS is single-threaded,
6636
+ * the synchronous adoptNode() and replaceChild() below complete before that
6637
+ * event is dispatched. iframeLoader's setInterval will therefore see the body
6638
+ * already populated on its first tick.
6639
+ */
6640
+ documentClone.close();
6626
6641
  const adoptedNode = documentClone.adoptNode(this.documentElement);
6627
6642
  addBase(adoptedNode, baseUri);
6628
6643
  documentClone.replaceChild(adoptedNode, documentClone.documentElement);
6629
- documentClone.close();
6630
6644
  return iframeLoad;
6631
6645
  }
6632
6646
  createElementClone(node) {
@@ -7155,13 +7169,16 @@
7155
7169
  str += doctype.name;
7156
7170
  }
7157
7171
  if (doctype.internalSubset) {
7158
- str += doctype.internalSubset;
7172
+ str += ' ' + doctype.internalSubset.replace(/"/g, '&quot;').replace(/>/g, '&gt;');
7159
7173
  }
7160
7174
  if (doctype.publicId) {
7161
- str += `"${doctype.publicId}"`;
7175
+ str += ' PUBLIC "' + doctype.publicId.replace(/"/g, '&quot;') + '"';
7176
+ if (doctype.systemId) {
7177
+ str += ' "' + doctype.systemId.replace(/"/g, '&quot;') + '"';
7178
+ }
7162
7179
  }
7163
- if (doctype.systemId) {
7164
- str += `"${doctype.systemId}"`;
7180
+ else if (doctype.systemId) {
7181
+ str += ' SYSTEM "' + doctype.systemId.replace(/"/g, '&quot;') + '"';
7165
7182
  }
7166
7183
  str += '>';
7167
7184
  }