Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/browser/ui/dom/setInnerHTML.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,21 @@ var setInnerHTML = function(node, html) {
};

if (ExecutionEnvironment.canUseDOM) {
if (document.contentType === "application/xhtml+xml") {
// XML mode: Turn HTML into valid XML before setting innerHTML
setInnerHTML = function(node, html) {
var dom = new DOMParser().parseFromString(html, 'text/html');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HTML format is not supported by Safari browsers (both, desktop and mobile). We need to do something like this

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added support to Safari as per your suggestion. Now it works in iBooks.app too! ❤️

node.innerHTML = new XMLSerializer().serializeToString(dom.body).replace(/^<body[^>]*>/, '').replace(/<\/body>$/, '');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At a glance the whole thing seems pretty reasonable, but I haven't looked closely.

The first things that jumps out at me here is that we should pull these regexs out to constants to dedupe (and to only create them once).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks rather slow. Perhaps we can generate XHTML-compatible markup from the start instead.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@spicyj I imagine it should be quite simple, but perhaps SVG could be an obstacle?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can just read innerHTML from body?

node.innerHTML = dom.body.innerHTML

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexeyraspopov Well, this evaluates to <br> not <br /> and hence still fails to validate as XML:

new DOMParser().parseFromString("<br>", "text/html").body.innerHTML;

Unless there is a way to cast a HTMLDocument into XMLDocument, serialization still seems required.

};
}
else if (document.xmlVersion) {
// Safari: Same thing, different API
setInnerHTML = function(node, html) {
var dom = document.implementation.createHTMLDocument('');
dom.body.innerHTML = html;
node.innerHTML = new XMLSerializer().serializeToString(dom.body).replace(/^<body[^>]*>/, '').replace(/<\/body>$/, '');
};
}
// IE8: When updating a just created node with innerHTML only leading
// whitespace is removed. When updating an existing node with innerHTML
// whitespace in root TextNodes is also collapsed.
Expand Down