dompurify 2.0.15 → 2.1.1
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/README.md +6 -8
- package/dist/purify.cjs.js +16 -83
- package/dist/purify.cjs.js.map +1 -1
- package/dist/purify.es.js +16 -83
- package/dist/purify.es.js.map +1 -1
- package/dist/purify.js +16 -83
- package/dist/purify.js.map +1 -1
- package/dist/purify.min.js +1 -1
- package/dist/purify.min.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
|
|
7
7
|
DOMPurify is a DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML and SVG.
|
|
8
8
|
|
|
9
|
-
It's also very simple to use and get started with. DOMPurify was [started in February 2014](https://github.com/cure53/DOMPurify/commit/a630922616927373485e0e787ab19e73e3691b2b) and, meanwhile, has reached version 2.0.
|
|
9
|
+
It's also very simple to use and get started with. DOMPurify was [started in February 2014](https://github.com/cure53/DOMPurify/commit/a630922616927373485e0e787ab19e73e3691b2b) and, meanwhile, has reached version 2.1.0.
|
|
10
10
|
|
|
11
|
-
DOMPurify is written in JavaScript and works in all modern browsers (Safari, Opera (15+), Internet Explorer (10+), Edge, Firefox and Chrome - as well as almost anything else using Blink or WebKit). It doesn't break on MSIE6 or other legacy browsers. It either uses [a fall-back](#what-about-older-browsers-like-msie8) or simply does nothing.
|
|
11
|
+
DOMPurify is written in JavaScript and works in all modern browsers (Safari (10+), Opera (15+), Internet Explorer (10+), Edge, Firefox and Chrome - as well as almost anything else using Blink or WebKit). It doesn't break on MSIE6 or other legacy browsers. It either uses [a fall-back](#what-about-older-browsers-like-msie8) or simply does nothing.
|
|
12
12
|
|
|
13
|
-
Our automated tests cover [
|
|
13
|
+
Our automated tests cover [15 different browsers](https://github.com/cure53/DOMPurify/blob/main/test/karma.custom-launchers.config.js#L5) right now, more to come. We also cover Node.js v12, v13, v14.0.0, running DOMPurify on [jsdom](https://github.com/tmpvar/jsdom). Older Node.js versions are known to work as well.
|
|
14
14
|
|
|
15
15
|
DOMPurify is written by security people who have vast background in web attacks and XSS. Fear not. For more details please also read about our [Security Goals & Threat Model](https://github.com/cure53/DOMPurify/wiki/Security-Goals-&-Threat-Model). Please, read it. Like, really.
|
|
16
16
|
|
|
@@ -40,7 +40,7 @@ Afterwards you can sanitize strings by executing the following code:
|
|
|
40
40
|
var clean = DOMPurify.sanitize(dirty);
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
The resulting HTML can be written into a DOM element using `innerHTML` or the DOM using `document.write()`. That is fully up to you.
|
|
43
|
+
The resulting HTML can be written into a DOM element using `innerHTML` or the DOM using `document.write()`. That is fully up to you.
|
|
44
44
|
|
|
45
45
|
### Is there any foot-gun potential?
|
|
46
46
|
|
|
@@ -115,7 +115,7 @@ DOMPurify.sanitize('<UL><li><A HREF=//google.com>click</UL>'); // becomes <ul><l
|
|
|
115
115
|
|
|
116
116
|
## What is supported?
|
|
117
117
|
|
|
118
|
-
DOMPurify currently supports HTML5, SVG and MathML. DOMPurify per default allows CSS, HTML custom data attributes. DOMPurify also supports the Shadow DOM - and sanitizes DOM templates recursively. DOMPurify also allows you to sanitize HTML for being used with the jQuery `$()` and `elm.html()`
|
|
118
|
+
DOMPurify currently supports HTML5, SVG and MathML. DOMPurify per default allows CSS, HTML custom data attributes. DOMPurify also supports the Shadow DOM - and sanitizes DOM templates recursively. DOMPurify also allows you to sanitize HTML for being used with the jQuery `$()` and `elm.html()` API without any known problems.
|
|
119
119
|
|
|
120
120
|
## What about older browsers like MSIE8?
|
|
121
121
|
|
|
@@ -140,8 +140,6 @@ Yes. The included default configuration values are pretty good already - but you
|
|
|
140
140
|
/**
|
|
141
141
|
* General settings
|
|
142
142
|
*/
|
|
143
|
-
// make output safe for usage in jQuery's $()/html() method (default is false)
|
|
144
|
-
var clean = DOMPurify.sanitize(dirty, {SAFE_FOR_JQUERY: true});
|
|
145
143
|
|
|
146
144
|
// strip {{ ... }} and <% ... %> to make output safe for template systems
|
|
147
145
|
// be careful please, this mode is not recommended for production usage.
|
|
@@ -328,7 +326,7 @@ Feature releases will not be announced to this list.
|
|
|
328
326
|
|
|
329
327
|
Many people helped and help DOMPurify become what it is and need to be acknowledged here!
|
|
330
328
|
|
|
331
|
-
[oreoshake 💸](https://github.com/oreoshake), [dcramer 💸](https://github.com/dcramer),[tdeekens ❤️](https://github.com/tdeekens), [peernohell ❤️](https://github.com/peernohell), [neilj](https://github.com/neilj), [fhemberger](https://github.com/fhemberger), [Joris-van-der-Wel](https://github.com/Joris-van-der-Wel), [ydaniv](https://github.com/ydaniv), [filedescriptor](https://github.com/filedescriptor), [ConradIrwin](https://github.com/ConradIrwin), [gibson042](https://github.com/gibson042), [choumx](https://github.com/choumx), [0xSobky](https://github.com/0xSobky), [styfle](https://github.com/styfle), [koto](https://github.com/koto), [tlau88](https://github.com/tlau88), [strugee](https://github.com/strugee), [oparoz](https://github.com/oparoz), [mathiasbynens](https://github.com/mathiasbynens), [edg2s](https://github.com/edg2s), [dnkolegov](https://github.com/dnkolegov), [dhardtke](https://github.com/dhardtke), [wirehead](https://github.com/wirehead), [thorn0](https://github.com/thorn0), [styu](https://github.com/styu), [mozfreddyb](https://github.com/mozfreddyb), [mikesamuel](https://github.com/mikesamuel), [jorangreef](https://github.com/jorangreef), [jimmyhchan](https://github.com/jimmyhchan), [jameydeorio](https://github.com/jameydeorio), [jameskraus](https://github.com/jameskraus), [hyderali](https://github.com/hyderali), [hansottowirtz](https://github.com/hansottowirtz), [hackvertor](https://github.com/hackvertor), [freddyb](https://github.com/freddyb), [flavorjones](https://github.com/flavorjones), [djfarrelly](https://github.com/djfarrelly), [devd](https://github.com/devd), [camerondunford](https://github.com/camerondunford), [buu700](https://github.com/buu700), [buildog](https://github.com/buildog), [alabiaga](https://github.com/alabiaga), [Vector919](https://github.com/Vector919), [Robbert](https://github.com/Robbert), [GreLI](https://github.com/GreLI), [FuzzySockets](https://github.com/FuzzySockets), [ArtemBernatskyy](https://github.com/ArtemBernatskyy), [@garethheyes](https://twitter.com/garethheyes), [@
|
|
329
|
+
[oreoshake 💸](https://github.com/oreoshake), [dcramer 💸](https://github.com/dcramer),[tdeekens ❤️](https://github.com/tdeekens), [peernohell ❤️](https://github.com/peernohell), [neilj](https://github.com/neilj), [fhemberger](https://github.com/fhemberger), [Joris-van-der-Wel](https://github.com/Joris-van-der-Wel), [ydaniv](https://github.com/ydaniv), [terjanq](https://twitter.com/terjanq), [filedescriptor](https://github.com/filedescriptor), [ConradIrwin](https://github.com/ConradIrwin), [gibson042](https://github.com/gibson042), [choumx](https://github.com/choumx), [0xSobky](https://github.com/0xSobky), [styfle](https://github.com/styfle), [koto](https://github.com/koto), [tlau88](https://github.com/tlau88), [strugee](https://github.com/strugee), [oparoz](https://github.com/oparoz), [mathiasbynens](https://github.com/mathiasbynens), [edg2s](https://github.com/edg2s), [dnkolegov](https://github.com/dnkolegov), [dhardtke](https://github.com/dhardtke), [wirehead](https://github.com/wirehead), [thorn0](https://github.com/thorn0), [styu](https://github.com/styu), [mozfreddyb](https://github.com/mozfreddyb), [mikesamuel](https://github.com/mikesamuel), [jorangreef](https://github.com/jorangreef), [jimmyhchan](https://github.com/jimmyhchan), [jameydeorio](https://github.com/jameydeorio), [jameskraus](https://github.com/jameskraus), [hyderali](https://github.com/hyderali), [hansottowirtz](https://github.com/hansottowirtz), [hackvertor](https://github.com/hackvertor), [freddyb](https://github.com/freddyb), [flavorjones](https://github.com/flavorjones), [djfarrelly](https://github.com/djfarrelly), [devd](https://github.com/devd), [camerondunford](https://github.com/camerondunford), [buu700](https://github.com/buu700), [buildog](https://github.com/buildog), [alabiaga](https://github.com/alabiaga), [Vector919](https://github.com/Vector919), [Robbert](https://github.com/Robbert), [GreLI](https://github.com/GreLI), [FuzzySockets](https://github.com/FuzzySockets), [ArtemBernatskyy](https://github.com/ArtemBernatskyy), [@garethheyes](https://twitter.com/garethheyes), [@shafigullin](https://twitter.com/shafigullin), [@mmrupp](https://twitter.com/mmrupp), [@irsdl](https://twitter.com/irsdl),[ShikariSenpai](https://github.com/ShikariSenpai), [ansjdnakjdnajkd](https://github.com/ansjdnakjdnajkd), [@asutherland](https://twitter.com/asutherland), [@mathias](https://twitter.com/mathias), [@cgvwzq](https://twitter.com/cgvwzq), [@robbertatwork](https://twitter.com/robbertatwork), [@giutro](https://twitter.com/giutro) and especially [@masatokinugawa](https://twitter.com/masatokinugawa)
|
|
332
330
|
|
|
333
331
|
## Testing powered by
|
|
334
332
|
<a target="_blank" href="https://www.browserstack.com/"><img width="200" src="https://www.browserstack.com/images/layout/browserstack-logo-600x315.png"></a><br>
|
package/dist/purify.cjs.js
CHANGED
|
@@ -6,8 +6,7 @@ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr
|
|
|
6
6
|
|
|
7
7
|
var hasOwnProperty = Object.hasOwnProperty,
|
|
8
8
|
setPrototypeOf = Object.setPrototypeOf,
|
|
9
|
-
isFrozen = Object.isFrozen
|
|
10
|
-
objectKeys = Object.keys;
|
|
9
|
+
isFrozen = Object.isFrozen;
|
|
11
10
|
var freeze = Object.freeze,
|
|
12
11
|
seal = Object.seal,
|
|
13
12
|
create = Object.create; // eslint-disable-line import/no-mutable-exports
|
|
@@ -41,11 +40,8 @@ if (!construct) {
|
|
|
41
40
|
}
|
|
42
41
|
|
|
43
42
|
var arrayForEach = unapply(Array.prototype.forEach);
|
|
44
|
-
var arrayIndexOf = unapply(Array.prototype.indexOf);
|
|
45
|
-
var arrayJoin = unapply(Array.prototype.join);
|
|
46
43
|
var arrayPop = unapply(Array.prototype.pop);
|
|
47
44
|
var arrayPush = unapply(Array.prototype.push);
|
|
48
|
-
var arraySlice = unapply(Array.prototype.slice);
|
|
49
45
|
|
|
50
46
|
var stringToLowerCase = unapply(String.prototype.toLowerCase);
|
|
51
47
|
var stringMatch = unapply(String.prototype.match);
|
|
@@ -54,7 +50,6 @@ var stringIndexOf = unapply(String.prototype.indexOf);
|
|
|
54
50
|
var stringTrim = unapply(String.prototype.trim);
|
|
55
51
|
|
|
56
52
|
var regExpTest = unapply(RegExp.prototype.test);
|
|
57
|
-
var regExpCreate = unconstruct(RegExp);
|
|
58
53
|
|
|
59
54
|
var typeErrorCreate = unconstruct(TypeError);
|
|
60
55
|
|
|
@@ -210,7 +205,7 @@ function createDOMPurify() {
|
|
|
210
205
|
* Version label, exposed for easier checks
|
|
211
206
|
* if DOMPurify is up to date or not
|
|
212
207
|
*/
|
|
213
|
-
DOMPurify.version = '2.
|
|
208
|
+
DOMPurify.version = '2.1.1';
|
|
214
209
|
|
|
215
210
|
/**
|
|
216
211
|
* Array of elements that DOMPurify removed during sanitation.
|
|
@@ -227,7 +222,6 @@ function createDOMPurify() {
|
|
|
227
222
|
}
|
|
228
223
|
|
|
229
224
|
var originalDocument = window.document;
|
|
230
|
-
var removeTitle = false;
|
|
231
225
|
|
|
232
226
|
var document = window.document;
|
|
233
227
|
var DocumentFragment = window.DocumentFragment,
|
|
@@ -266,7 +260,10 @@ function createDOMPurify() {
|
|
|
266
260
|
var importNode = originalDocument.importNode;
|
|
267
261
|
|
|
268
262
|
|
|
269
|
-
var documentMode =
|
|
263
|
+
var documentMode = {};
|
|
264
|
+
try {
|
|
265
|
+
documentMode = clone(document).documentMode ? document.documentMode : {};
|
|
266
|
+
} catch (_) {}
|
|
270
267
|
|
|
271
268
|
var hooks = {};
|
|
272
269
|
|
|
@@ -312,9 +309,6 @@ function createDOMPurify() {
|
|
|
312
309
|
/* Decide if unknown protocols are okay */
|
|
313
310
|
var ALLOW_UNKNOWN_PROTOCOLS = false;
|
|
314
311
|
|
|
315
|
-
/* Output should be safe for jQuery's $() factory? */
|
|
316
|
-
var SAFE_FOR_JQUERY = false;
|
|
317
|
-
|
|
318
312
|
/* Output should be safe for common template engines.
|
|
319
313
|
* This means, DOMPurify removes data attributes, mustaches and ERB
|
|
320
314
|
*/
|
|
@@ -412,7 +406,6 @@ function createDOMPurify() {
|
|
|
412
406
|
ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true
|
|
413
407
|
ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true
|
|
414
408
|
ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false
|
|
415
|
-
SAFE_FOR_JQUERY = cfg.SAFE_FOR_JQUERY || false; // Default false
|
|
416
409
|
SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false
|
|
417
410
|
WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false
|
|
418
411
|
RETURN_DOM = cfg.RETURN_DOM || false; // Default false
|
|
@@ -567,11 +560,6 @@ function createDOMPurify() {
|
|
|
567
560
|
doc = new DOMParser().parseFromString(dirtyPayload, 'text/html');
|
|
568
561
|
} catch (_) {}
|
|
569
562
|
|
|
570
|
-
/* Remove title to fix a mXSS bug in older MS Edge */
|
|
571
|
-
if (removeTitle) {
|
|
572
|
-
addToSet(FORBID_TAGS, ['title']);
|
|
573
|
-
}
|
|
574
|
-
|
|
575
563
|
/* Use createHTMLDocument in case DOMParser is not available */
|
|
576
564
|
if (!doc || !doc.documentElement) {
|
|
577
565
|
doc = implementation.createHTMLDocument('');
|
|
@@ -590,18 +578,6 @@ function createDOMPurify() {
|
|
|
590
578
|
return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];
|
|
591
579
|
};
|
|
592
580
|
|
|
593
|
-
/* Here we test for a broken feature in Edge that might cause mXSS */
|
|
594
|
-
if (DOMPurify.isSupported) {
|
|
595
|
-
(function () {
|
|
596
|
-
try {
|
|
597
|
-
var doc = _initDocument('<x/><title></title><img>');
|
|
598
|
-
if (regExpTest(/<\/title/, doc.querySelector('title').innerHTML)) {
|
|
599
|
-
removeTitle = true;
|
|
600
|
-
}
|
|
601
|
-
} catch (_) {}
|
|
602
|
-
})();
|
|
603
|
-
}
|
|
604
|
-
|
|
605
581
|
/**
|
|
606
582
|
* _createIterator
|
|
607
583
|
*
|
|
@@ -670,7 +646,6 @@ function createDOMPurify() {
|
|
|
670
646
|
* @param {Node} currentNode to check for permission to exist
|
|
671
647
|
* @return {Boolean} true if node was killed, false if left alive
|
|
672
648
|
*/
|
|
673
|
-
// eslint-disable-next-line complexity
|
|
674
649
|
var _sanitizeElements = function _sanitizeElements(currentNode) {
|
|
675
650
|
var content = void 0;
|
|
676
651
|
|
|
@@ -704,6 +679,12 @@ function createDOMPurify() {
|
|
|
704
679
|
return true;
|
|
705
680
|
}
|
|
706
681
|
|
|
682
|
+
/* Detect mXSS attempts abusing namespace confusion */
|
|
683
|
+
if (!_isNode(currentNode.firstElementChild) && (!_isNode(currentNode.content) || !_isNode(currentNode.content.firstElementChild)) && regExpTest(/<[!/\w]/g, currentNode.innerHTML) && regExpTest(/<[!/\w]/g, currentNode.textContent)) {
|
|
684
|
+
_forceRemove(currentNode);
|
|
685
|
+
return true;
|
|
686
|
+
}
|
|
687
|
+
|
|
707
688
|
/* Remove element if anything forbids its presence */
|
|
708
689
|
if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
|
|
709
690
|
/* Keep content except for bad-listed elements */
|
|
@@ -719,26 +700,11 @@ function createDOMPurify() {
|
|
|
719
700
|
}
|
|
720
701
|
|
|
721
702
|
/* Remove in case a noscript/noembed XSS is suspected */
|
|
722
|
-
if (tagName === 'noscript' && regExpTest(/<\/
|
|
723
|
-
_forceRemove(currentNode);
|
|
724
|
-
return true;
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
if (tagName === 'noembed' && regExpTest(/<\/noembed/i, currentNode.innerHTML)) {
|
|
703
|
+
if ((tagName === 'noscript' || tagName === 'noembed') && regExpTest(/<\/no(script|embed)/i, currentNode.innerHTML)) {
|
|
728
704
|
_forceRemove(currentNode);
|
|
729
705
|
return true;
|
|
730
706
|
}
|
|
731
707
|
|
|
732
|
-
/* Convert markup to cover jQuery behavior */
|
|
733
|
-
if (SAFE_FOR_JQUERY && !_isNode(currentNode.firstElementChild) && (!_isNode(currentNode.content) || !_isNode(currentNode.content.firstElementChild)) && regExpTest(/</g, currentNode.textContent)) {
|
|
734
|
-
arrayPush(DOMPurify.removed, { element: currentNode.cloneNode() });
|
|
735
|
-
if (currentNode.innerHTML) {
|
|
736
|
-
currentNode.innerHTML = stringReplace(currentNode.innerHTML, /</g, '<');
|
|
737
|
-
} else {
|
|
738
|
-
currentNode.innerHTML = stringReplace(currentNode.textContent, /</g, '<');
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
|
|
742
708
|
/* Sanitize element content to be template-safe */
|
|
743
709
|
if (SAFE_FOR_TEMPLATES && currentNode.nodeType === 3) {
|
|
744
710
|
/* Get the element's text content */
|
|
@@ -797,12 +763,10 @@ function createDOMPurify() {
|
|
|
797
763
|
*
|
|
798
764
|
* @param {Node} currentNode to sanitize
|
|
799
765
|
*/
|
|
800
|
-
// eslint-disable-next-line complexity
|
|
801
766
|
var _sanitizeAttributes = function _sanitizeAttributes(currentNode) {
|
|
802
767
|
var attr = void 0;
|
|
803
768
|
var value = void 0;
|
|
804
769
|
var lcName = void 0;
|
|
805
|
-
var idAttr = void 0;
|
|
806
770
|
var l = void 0;
|
|
807
771
|
/* Execute a hook if present */
|
|
808
772
|
_executeHook('beforeSanitizeAttributes', currentNode, null);
|
|
@@ -846,32 +810,7 @@ function createDOMPurify() {
|
|
|
846
810
|
}
|
|
847
811
|
|
|
848
812
|
/* Remove attribute */
|
|
849
|
-
|
|
850
|
-
// remove a "name" attribute from an <img> tag that has an "id"
|
|
851
|
-
// attribute at the time.
|
|
852
|
-
if (lcName === 'name' && currentNode.nodeName === 'IMG' && attributes.id) {
|
|
853
|
-
idAttr = attributes.id;
|
|
854
|
-
attributes = arraySlice(attributes, []);
|
|
855
|
-
_removeAttribute('id', currentNode);
|
|
856
|
-
_removeAttribute(name, currentNode);
|
|
857
|
-
if (arrayIndexOf(attributes, idAttr) > l) {
|
|
858
|
-
currentNode.setAttribute('id', idAttr.value);
|
|
859
|
-
}
|
|
860
|
-
} else if (
|
|
861
|
-
// This works around a bug in Safari, where input[type=file]
|
|
862
|
-
// cannot be dynamically set after type has been removed
|
|
863
|
-
currentNode.nodeName === 'INPUT' && lcName === 'type' && value === 'file' && hookEvent.keepAttr && (ALLOWED_ATTR[lcName] || !FORBID_ATTR[lcName])) {
|
|
864
|
-
continue;
|
|
865
|
-
} else {
|
|
866
|
-
// This avoids a crash in Safari v9.0 with double-ids.
|
|
867
|
-
// The trick is to first set the id to be empty and then to
|
|
868
|
-
// remove the attribute
|
|
869
|
-
if (name === 'id') {
|
|
870
|
-
currentNode.setAttribute(name, '');
|
|
871
|
-
}
|
|
872
|
-
|
|
873
|
-
_removeAttribute(name, currentNode);
|
|
874
|
-
}
|
|
813
|
+
_removeAttribute(name, currentNode);
|
|
875
814
|
|
|
876
815
|
/* Did the hooks approve of the attribute? */
|
|
877
816
|
if (!hookEvent.keepAttr) {
|
|
@@ -879,13 +818,7 @@ function createDOMPurify() {
|
|
|
879
818
|
}
|
|
880
819
|
|
|
881
820
|
/* Work around a security issue in jQuery 3.0 */
|
|
882
|
-
if (
|
|
883
|
-
_removeAttribute(name, currentNode);
|
|
884
|
-
continue;
|
|
885
|
-
}
|
|
886
|
-
|
|
887
|
-
/* Take care of an mXSS pattern using namespace switches */
|
|
888
|
-
if (regExpTest(/svg|math/i, currentNode.namespaceURI) && regExpTest(regExpCreate('</(' + arrayJoin(objectKeys(FORBID_CONTENTS), '|') + ')', 'i'), value)) {
|
|
821
|
+
if (regExpTest(/\/>/i, value)) {
|
|
889
822
|
_removeAttribute(name, currentNode);
|
|
890
823
|
continue;
|
|
891
824
|
}
|
|
@@ -1018,7 +951,7 @@ function createDOMPurify() {
|
|
|
1018
951
|
if (IN_PLACE) ; else if (dirty instanceof Node) {
|
|
1019
952
|
/* If dirty is a DOM element, append to an empty document to avoid
|
|
1020
953
|
elements being stripped by the parser */
|
|
1021
|
-
body = _initDocument('
|
|
954
|
+
body = _initDocument('<!---->');
|
|
1022
955
|
importedNode = body.ownerDocument.importNode(dirty, true);
|
|
1023
956
|
if (importedNode.nodeType === 1 && importedNode.nodeName === 'BODY') {
|
|
1024
957
|
/* Node is already a body, use as is */
|