This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 17924 - Setting innerHTML on an SVG element will parse into HTML elements. Since innerHTML is available on Element now, we should check if the context element is an SVG element (or MathML element) other than foreignObject (etc) and use the foreign lands insertion
Summary: Setting innerHTML on an SVG element will parse into HTML elements. Since inne...
Status: RESOLVED FIXED
Alias: None
Product: WHATWG
Classification: Unclassified
Component: HTML (show other bugs)
Version: unspecified
Hardware: Other other
: P3 blocker
Target Milestone: Unsorted
Assignee: Ian 'Hixie' Hickson
QA Contact: contributor
URL: http://www.whatwg.org/specs/web-apps/...
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-07-18 07:17 UTC by contributor
Modified: 2013-06-06 19:56 UTC (History)
13 users (show)

See Also:


Attachments

Description contributor 2012-07-18 07:17:58 UTC
This was was cloned from bug 16635 as part of operation convergence.
Originally filed: 2012-04-04 10:58:00 +0000

================================================================================
 #0   contributor@whatwg.org                          2012-04-04 10:58:52 +0000 
--------------------------------------------------------------------------------
Specification: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html
Multipage: http://www.whatwg.org/C#parsing-html-fragments
Complete: http://www.whatwg.org/c#parsing-html-fragments

Comment:
Setting innerHTML on an SVG element will parse into HTML elements. Since
innerHTML is available on Element now, we should check if the context element
is an SVG element (or MathML element) other than foreignObject (etc) and use
the foreign lands insertion mode.

Posted from: 88.131.66.80 by simonp@opera.com
User agent: Opera/9.80 (Macintosh; Intel Mac OS X 10.7.2; U; en) Presto/2.10.229 Version/11.62
================================================================================
 #1   Cameron McCormack                               2012-04-04 11:19:56 +0000 
--------------------------------------------------------------------------------
That'd be awesome if it could work, yeah.
================================================================================
 #2   Simon Pieters                                   2012-04-05 07:11:43 +0000 
--------------------------------------------------------------------------------
Cases to consider:

context element is one of the following

<svg><g/><foreignobject/><desc/><title/></svg>
<math><mrow/><mi/><mo/><mn/><ms/><mtext/><annotation-xml/><annotatoin-xml encoding=text/html /></math>

markup is one of the following

"<b>x"
"<svg>"
"<p>"
"</svg>"
"<mglyph>"
"<malignmark>"
...
================================================================================
 #3   Simon Pieters                                   2012-04-05 07:38:07 +0000 
--------------------------------------------------------------------------------
http://software.hixie.ch/utilities/js/live-dom-viewer/saved/1451
================================================================================
 #4   Simon Pieters                                   2012-04-05 12:53:12 +0000 
--------------------------------------------------------------------------------
Desired outcome, I think (using html5lib test syntax to indicate namespace):

<math math>.innerHTML = '<b>x';
| <math math>
|   <b>
|     "x"

<math math>.innerHTML = '<foo><b>x';
| <math math>
|   <math foo>
| <b>
|   "x"

i.e. the "break out" step needs to be changed to not pop the current element if that's an html element (fragment case), but should otherwise work like normal.

<math mi>.innerHTML = '<b>x';
| <math mi>
|   <b>
|     "x"

<math mi>.innerHTML = '<foo><b>x';
| <math mi>
|   <foo>
|     <b>
|       "x"

<math mi>.innerHTML = '<mglyph>';
| <math mi>
|   <math mglyph>

<math mi>.innerHTML = '<malignmark>';
| <math mi>
|   <math malignmark>

<math mi>.innerHTML = '<svg>';
| <math mi>
|   <svg svg>

<math annotation-xml>.innerHTML = '<svg>';
| <math annotation-xml>
|   <svg svg>

<math annotation-xml>.innerHTML = '<foo>';
| <math annotation-xml>
|   <math foo>

<math annotation-xml encoding="text/html">.innerHTML = '<foo>';
| <math annotation-xml>
|   encoding="text/html"
|   <foo>
================================================================================
 #5   Simon Pieters                                   2012-04-05 12:53:13 +0000 
--------------------------------------------------------------------------------
Desired outcome, I think (using html5lib test syntax to indicate namespace):

<math math>.innerHTML = '<b>x';
| <math math>
|   <b>
|     "x"

<math math>.innerHTML = '<foo><b>x';
| <math math>
|   <math foo>
| <b>
|   "x"

i.e. the "break out" step needs to be changed to not pop the current element if that's an html element (fragment case), but should otherwise work like normal.

<math mi>.innerHTML = '<b>x';
| <math mi>
|   <b>
|     "x"

<math mi>.innerHTML = '<foo><b>x';
| <math mi>
|   <foo>
|     <b>
|       "x"

<math mi>.innerHTML = '<mglyph>';
| <math mi>
|   <math mglyph>

<math mi>.innerHTML = '<malignmark>';
| <math mi>
|   <math malignmark>

<math mi>.innerHTML = '<svg>';
| <math mi>
|   <svg svg>

<math annotation-xml>.innerHTML = '<svg>';
| <math annotation-xml>
|   <svg svg>

<math annotation-xml>.innerHTML = '<foo>';
| <math annotation-xml>
|   <math foo>

<math annotation-xml encoding="text/html">.innerHTML = '<foo>';
| <math annotation-xml>
|   encoding="text/html"
|   <foo>
================================================================================
 #6   Simon Pieters                                   2012-04-05 12:55:59 +0000 
--------------------------------------------------------------------------------
(In reply to comment #4)
> <math math>.innerHTML = '<foo><b>x';
> | <math math>
> |   <math foo>
> | <b>
> |   "x"

Oops. I meant this:

<math math>.innerHTML = '<foo><b>x';
| <math math>
|   <math foo>
|   <b>
|     "x"
================================================================================
Comment 1 Ian 'Hixie' Hickson 2012-08-24 22:17:19 UTC
Proposal:

- In the tree construction dispatch algorithm, change the references to "current node" to be references to a concept that is equal to current node like today except when the current node is the only element in the stack and we're in a fragment parsing scenario ("If the parser was originally created for the HTML fragment parsing algorithm"), in which case it instead is equal to the context node (fragment case).
- In the foreign content rules, in the handling of "b" start tags etc, skip the paragraph that does the popping if the current node is the only node in the stack (fragment case).
- In the foreign content rules, in the handling of "b" start tags etc, if the current node is the only node in the stack, instead of reprocessing the token, specifically reprocess it in the "in body" mode (fragment case).
- In the foreign content rules, "any other end tag", at the start of the loop step, abort if /node/ is the only node in the stack (fragment case). (This is needed to avoid problems with <svg>.innerHTML = "</html>".)
Comment 2 Ian 'Hixie' Hickson 2012-10-30 22:32:41 UTC
Anyone object to the parser changes in comment 1?
Comment 3 Ian 'Hixie' Hickson 2013-01-31 17:51:44 UTC
Last chance to object to this HTML parser change before I go ahead and do it.
Comment 4 Adam Barth 2013-01-31 20:14:21 UTC
I haven't reviewed the details, but the general approach sounds reasonable.
Comment 5 Travis Leithead [MSFT] 2013-02-01 19:19:35 UTC
This sounds reasonable to me too.
Comment 6 Ian 'Hixie' Hickson 2013-03-25 22:12:32 UTC
Let me know if this breaks anything...
Comment 7 contributor 2013-03-25 22:29:57 UTC
Checked in as WHATWG revision r7768.
Check-in comment: Parser change: Handle fragment case for non-HTML nodes. This _should_ have no effect on any other case, so please do let me know if this breaks any tests!
http://html5.org/tools/web-apps-tracker?from=7767&to=7768
Comment 8 Peter Occil 2013-03-30 08:32:14 UTC
The change fails on the following case (found in parsing/test_tests9.html of the approved test cases):

<!DOCTYPE html><math><annotation-xml><svg><u>

Note that this isn't a fragment case.
Comment 9 Ian 'Hixie' Hickson 2013-04-15 22:42:46 UTC
What's the output with that case now?
Comment 10 Peter Occil 2013-04-16 00:39:44 UTC
(In reply to comment #9)
> What's the output with that case now?

With my HTML parser, before I fixed the issue by checking for the fragment case explicitly, I had the following output:

| <!DOCTYPE html>
| <html>
|   <head>
|   <body>
|     <math math>
|       <math annotation-xml>
|         <svg svg>
|           <u>

The correct output according to that test is:

| <!DOCTYPE html>
| <html>
|   <head>
|   <body>
|     <math math>
|       <math annotation-xml>
|         <svg svg>
|     <u>
Comment 11 Ian 'Hixie' Hickson 2013-04-26 22:30:25 UTC
Oh, I see. I screwed up when using the "in scope" thing in the text I added to handle <u> and company in foreign content.

I think I meant to check if the stack of open elements has one of the listed element in it at all, not just if it's in scope. So I just need to strike "in scope".

Anyone disagree?
Comment 12 Ian 'Hixie' Hickson 2013-06-06 19:54:30 UTC
I just turned this quirk off entirely in innerHTML.
Comment 13 contributor 2013-06-06 19:56:40 UTC
Checked in as WHATWG revision r7918.
Check-in comment: Turn off a quirk in foreign lands when doing innerHTML parsing
http://html5.org/tools/web-apps-tracker?from=7917&to=7918