html2canvas-pro 2.0.1 → 2.0.3
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/dist/html2canvas-pro.esm.js +46 -28
- package/dist/html2canvas-pro.esm.js.map +1 -1
- package/dist/html2canvas-pro.js +46 -28
- package/dist/html2canvas-pro.js.map +1 -1
- package/dist/html2canvas-pro.min.js +2 -2
- package/dist/lib/css/property-descriptors/__tests__/image-rendering-integration.test.js +7 -6
- package/dist/lib/css/property-descriptors/__tests__/image-rendering-integration.test.js.map +1 -1
- package/dist/lib/dom/__tests__/dom-normalizer.test.js +6 -6
- package/dist/lib/dom/__tests__/dom-normalizer.test.js.map +1 -1
- package/dist/lib/dom/document-cloner.js +45 -27
- package/dist/lib/dom/document-cloner.js.map +1 -1
- package/karma.conf.cjs +6 -1
- package/package.json +5 -4
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* html2canvas-pro 2.0.
|
|
2
|
+
* html2canvas-pro 2.0.3 <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
|
*/
|
|
@@ -6586,41 +6586,56 @@ class DocumentCloner {
|
|
|
6586
6586
|
return iframe;
|
|
6587
6587
|
});
|
|
6588
6588
|
/**
|
|
6589
|
-
* The
|
|
6590
|
-
*
|
|
6591
|
-
*
|
|
6592
|
-
|
|
6589
|
+
* The base URI used for resolving relative URLs (e.g. background-image) in the clone.
|
|
6590
|
+
* Must come from the source document: the iframe document is about:blank, so
|
|
6591
|
+
* documentClone.baseURI would break getComputedStyle() for relative background URLs.
|
|
6592
|
+
*/
|
|
6593
|
+
const baseUri = ownerDocument.baseURI;
|
|
6593
6594
|
documentClone.open();
|
|
6595
|
+
const rawHTML = serializeDoctype(document.doctype) + '<html></html>';
|
|
6594
6596
|
try {
|
|
6595
|
-
//
|
|
6596
|
-
//
|
|
6597
|
-
const
|
|
6598
|
-
|
|
6599
|
-
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
|
|
6597
|
+
// Fixing "This document requires 'TrustedHTML' assignment. The action has been blocked." error.
|
|
6598
|
+
// Reuse existing policy when present (e.g. second html2canvas call) to avoid createPolicy duplicate-name throw.
|
|
6599
|
+
const ownerWindow = this.referenceElement.ownerDocument?.defaultView;
|
|
6600
|
+
const trustedTypesFactory = ownerWindow && ownerWindow.trustedTypes;
|
|
6601
|
+
let policy = trustedTypesFactory?.getPolicy?.('html2canvas-pro');
|
|
6602
|
+
if (!policy && trustedTypesFactory) {
|
|
6603
|
+
policy = trustedTypesFactory.createPolicy('html2canvas-pro', {
|
|
6604
|
+
createHTML: (string) => string
|
|
6605
|
+
});
|
|
6606
|
+
}
|
|
6607
|
+
if (policy) {
|
|
6608
|
+
documentClone.write(policy.createHTML(rawHTML));
|
|
6609
|
+
}
|
|
6610
|
+
else {
|
|
6611
|
+
documentClone.write(rawHTML);
|
|
6612
|
+
}
|
|
6603
6613
|
}
|
|
6604
|
-
catch (
|
|
6605
|
-
|
|
6606
|
-
documentClone.write(serializeDoctype(document.doctype) + '<html></html>');
|
|
6614
|
+
catch (_e) {
|
|
6615
|
+
documentClone.write(rawHTML);
|
|
6607
6616
|
}
|
|
6608
6617
|
// Chrome scrolls the parent document for some reason after the write to the cloned window???
|
|
6609
6618
|
restoreOwnerScroll(this.referenceElement.ownerDocument, scrollX, scrollY);
|
|
6610
6619
|
/**
|
|
6611
|
-
*
|
|
6620
|
+
* IMPORTANT: documentClone.close() MUST be called BEFORE adoptNode().
|
|
6621
|
+
*
|
|
6622
|
+
* In Chrome, calling adoptNode() while the document is still "open"
|
|
6623
|
+
* (between document.open() and document.close()) causes CSS rules with
|
|
6624
|
+
* uppercase characters in class names (e.g. ".MyClass") to not match
|
|
6625
|
+
* correctly. Chrome's CSS engine only enters a fully-resolved matching
|
|
6626
|
+
* mode once the document is closed.
|
|
6612
6627
|
*
|
|
6613
|
-
*
|
|
6614
|
-
* styles with uppercase characters in class names (e.g. ".MyClass") to not apply correctly.
|
|
6628
|
+
* Correct order: open() → write() → close() → adoptNode() → replaceChild()
|
|
6615
6629
|
*
|
|
6616
|
-
*
|
|
6617
|
-
*
|
|
6618
|
-
*
|
|
6619
|
-
*
|
|
6630
|
+
* Timing: close() queues the iframe 'load' event; because JS is single-threaded,
|
|
6631
|
+
* the synchronous adoptNode() and replaceChild() below complete before that
|
|
6632
|
+
* event is dispatched. iframeLoader's setInterval will therefore see the body
|
|
6633
|
+
* already populated on its first tick.
|
|
6634
|
+
*/
|
|
6635
|
+
documentClone.close();
|
|
6620
6636
|
const adoptedNode = documentClone.adoptNode(this.documentElement);
|
|
6621
6637
|
addBase(adoptedNode, baseUri);
|
|
6622
6638
|
documentClone.replaceChild(adoptedNode, documentClone.documentElement);
|
|
6623
|
-
documentClone.close();
|
|
6624
6639
|
return iframeLoad;
|
|
6625
6640
|
}
|
|
6626
6641
|
createElementClone(node) {
|
|
@@ -7149,13 +7164,16 @@ const serializeDoctype = (doctype) => {
|
|
|
7149
7164
|
str += doctype.name;
|
|
7150
7165
|
}
|
|
7151
7166
|
if (doctype.internalSubset) {
|
|
7152
|
-
str += doctype.internalSubset;
|
|
7167
|
+
str += ' ' + doctype.internalSubset.replace(/"/g, '"').replace(/>/g, '>');
|
|
7153
7168
|
}
|
|
7154
7169
|
if (doctype.publicId) {
|
|
7155
|
-
str +=
|
|
7170
|
+
str += ' PUBLIC "' + doctype.publicId.replace(/"/g, '"') + '"';
|
|
7171
|
+
if (doctype.systemId) {
|
|
7172
|
+
str += ' "' + doctype.systemId.replace(/"/g, '"') + '"';
|
|
7173
|
+
}
|
|
7156
7174
|
}
|
|
7157
|
-
if (doctype.systemId) {
|
|
7158
|
-
str +=
|
|
7175
|
+
else if (doctype.systemId) {
|
|
7176
|
+
str += ' SYSTEM "' + doctype.systemId.replace(/"/g, '"') + '"';
|
|
7159
7177
|
}
|
|
7160
7178
|
str += '>';
|
|
7161
7179
|
}
|