-
-
Save eligrey/1129031 to your computer and use it in GitHub Desktop.
/* | |
* DOMParser HTML extension | |
* 2019-11-13 | |
* | |
* By Eli Grey, http://eligrey.com | |
* Public domain. | |
* NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. | |
*/ | |
/*! @source https://gist.github.com/1129031 */ | |
/*global document, DOMParser*/ | |
(function(DOMParser) { | |
"use strict"; | |
var DOMParser_proto = DOMParser.prototype; | |
var real_parseFromString = DOMParser_proto.parseFromString; | |
// Firefox/Opera/IE throw errors on unsupported types | |
try { | |
// WebKit returns null on unsupported types | |
if ((new DOMParser).parseFromString("", "text/html")) { | |
// text/html parsing is natively supported | |
return; | |
} | |
} catch (ex) {} | |
DOMParser_proto.parseFromString = function(markup, type) { | |
if (/^\s*text\/html\s*(?:;|$)/i.test(type)) { | |
var doc = document.implementation.createHTMLDocument(""); | |
doc.documentElement.innerHTML = markup; | |
return doc; | |
} else { | |
return real_parseFromString.apply(this, arguments); | |
} | |
}; | |
}(DOMParser)); |
This is nice, but attributes on the documentElement will not be available in the DOMParser since this uses 'doc.documentElement.innerHTML' and the documentElement is read only in a DOM Implementation. So the attributes would need to be added manually. It's an edge case, but just adding a note for anyone that might run into that.
Since this polyfill assumes DOMParser is defined, you should add the following wrapper for your code :
if (window.DOMParser !== undefined){
[ your code ]
}
That way, your polyfill will just be ignored in browsers that don't support DOMParser (which happens to include IE8) instead of generating an error.
@jslegers: The code excerpt below is solving for that. You can't just do a check against the window for "DOMParser" because Safari supports DOMParser for XML, just not HTML. This can't be determined any other way besides using a try/catch.
try {
// WebKit returns null on unsupported types
if ((new DOMParser).parseFromString("", "text/html")) {
// text/html parsing is natively supported
return;
}
} catch (ex) {}
@DrewML not trying to troll, but jslegers isn't talking about that at all, but the presence of DOMParser in the first place.
Only bothering to leave this as I had to read your comment and his a couple times before realizing what was going on.
(never even had to deal with DOMParser before this ridiculous bug that should be dealt with on the server side but isn't... but that's just me whinging)
Awesome, works for me on iOS pulling whole pages and parsing them with XMLHttpRequest :)
I add this code In my scripts files and works fine but this code run several times , How can i prevent this ? maybe some codes simlar below codes
DOMParserFlag = false;
if (DOMParserFlag == false) {
function DOMParser() {
"use strict";
..........
}
DOMParserFlag = true;
}
Setting .innerHTML
will load image ressources (even if element is not appended to DOM), which is not the case with DOMParser
.
I remove this
if (markup.toLowerCase().indexOf('<!doctype') > -1) {
console.log(markup);
console.log('inserindo o elemento doc \n\n');
//doc.documentElement.innerHTML = markup;
doc.body.innerHTML = markup;
} else {
doc.body.innerHTML = markup;
}
and i changed for this
doc.body.innerHTML = markup;
and I got the result I needed.
@kube I tested and it seems that using document.implementation.createHTMLDocument("")
creates a new document, which not being attached to any window prevents arbitrary execution of anything (at least in the latest Chrome):
var doc = document.implementation.createHTMLDocument("")
doc.documentElement.innerHTML = '<img src="ERROR" onerror="console.log(456)" />'
@kethinov I merged in your changes.