Closed Bug 1032979 Opened 7 years ago Closed 5 years ago
Dropdowns for modifying the report disappear on Garmin Connect when you pick a value because outer
HTML on a node from an XML document outputs self-closing tags for empty HTML containers
365.94 KB, image/png
6.85 KB, patch
|Details | Diff | Splinter Review|
part 2. Getting outerHTML on a node from an XML document should not use the self-closing form of empty container tags from the HTML namespace
18.35 KB, patch
|Details | Diff | Splinter Review|
Attachment #8448909 - Attachment description: Debugger stops at line 1427 but never goes to 1434 (the function that is called) → Debugger starts at line 1427, never goes to 1434 (the function that is called)
Summary: a4j.ajax.submit does not function properly → a4j.ajax.submit() does not function properly
Severity: normal → major
Summary: a4j.ajax.submit() does not function properly → a4j.ajax.submit() does not function properly on Garmin Connect
This bug affects every version of Firefox starting from version 11
I can reproduce this issue on the latest release(43.0.4) and the latest Nightly(46.0a1). User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:43.0) Gecko/20100101 Firefox/43.0 Build ID: 20160105164030 User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:46.0) Gecko/20100101 Firefox/46.0 Build ID: 20160110030214 This issue is also reproducible on Windows 8.1 with latest release(43.0.4) and the latest Nightly(46.0a1) builds. I've compared the results against other browsers like Chrome, IE 11, Safari and the issue is only encountered in latest Firefox release(43.0.4) and latest Nightly(46.0a1). Regarding this, I will change the Status to NEW and adding the component Core: HTML: Form Submission. If anyone considers that the component is not the right one, please change it to a more appropriate one. Thank you, Vlad
Status: UNCONFIRMED → NEW
Component: Untriaged → HTML: Form Submission
Ever confirmed: true
OS: Mac OS X → All
Product: Firefox → Core
Version: 31 Branch → Trunk
This isn't a form submission at all. It's an XHR request. If you can reproduce, what are the exact steps you used to reproduce (if they're different from comment 0)? If you created some sort of throwaway account for this, are its credentials available somewhere or are you able to post them here?
Component: HTML: Form Submission → Untriaged
Hi, The steps that I have followed are: 1. I've accessed https://connect.garmin.com/reports . 2. Login using the following credentials: User: email@example.com Pass: Test1234 3. After login, insert the URL https://connect.garmin.com/reports in the address bar and access it. 4. Hover the cursor of the mouse over "Analyze" button and click on `Reports` from the drop-down. 5. Change the Period or Activity Type. Actual results: Filter fields disappear. I've searched for similar issues regarding `XHR request`, but the issues are spread over many components. I thought that the component would be XML or DOM. What component would you suggest in this case? Thank you, Vlad
Flags: needinfo?(vlad.bacia) → needinfo?(bzbarsky)
Please use "DOM" for issues like this, where it's not even clear whether the XHR request is the problem. In any case, I can reproduce using the steps from comment 4. What's going on here is that the page wipes out the part of the DOM that has those <select> elements and replaces it with content it got via XHR like so: oldnode.outerHTML = new XMLSerializer().serializeToString(newnode); Now the thing is, it's actually overriding XMLSerializer, so the above code gets newnode.outerHTML instead of using the real XMLSerializer.serializeToString. And newnode has the following tree structure (greatly simplified): span div style="display:none" div div select select Now the thing is, the outerHTML getter sets up a document encoder using the MIME type of the document the node belongs to, which in this case is "text/xml" (which is what XHR returned). And in that case we end up serializing empty tags with the self-closing "/>" convention of XML even if they're in the HTML namespace. The upshot is that newnode.outerHTML looks like this: <span xmlns="http://www.w3.org/1999/xhtml"> <div style="display: none"> <div/> </div> <div> <select></select> <select></select> </div> </span> Now this is assigned to innerHTML, parsed with the HTML parser, and the "<div/>" is treated as an unclosed tag. So the </div> following it is treated as closing the _inner_ divs, and the <div> containing the <select>s end up inside the display:none thing. In Chrome, the empty div is serialized as "<div></div>" so it doesn't have this problem. OK, so what does the spec say for .outerHTML? https://w3c.github.io/DOM-Parsing/#widl-Element-outerHTML calls https://w3c.github.io/DOM-Parsing/#dfn-concept-fragment-serializing-algorithm which talks about the node document of the given node. The given node is the fictional one from the outerHTML bits, but it makes sense to assume that this is just the node document of the node outerHTML is being gotten on, which in this case is an "XML document". So we jump to the https://w3c.github.io/DOM-Parsing/#dfn-concept-serialize-xml algorithm which calls https://w3c.github.io/DOM-Parsing/#dfn-concept-xml-serialization-algorithm which will only do the self-closing thing for non-HTML nodes or for a certain whitelist of HTML nodes. So we're not doing the right thing here. It looks to me like this would work correctly if the page actually used an XMLSerializer, because that always serializes as the XHTML MIME type, and in that case we _do_ in fact do what the DOM-Parsing spec says to do for XML serialization in terms of not using the self-closing form for empty HTML container tags. This was fixed for XMLSerializer in bug 500937 afaict. So I think we have two main options. Option 1 is to change FragmentOrElement::GetMarkup to always use the "application/xhtml+xml" MIME type for non-HTML documents. Option 2 is to hoist the special-casing of HTML up from nsXHTMLContentSerializer::AppendEndOfElementStart to nsXMLContentSerializer::AppendEndOfElementStart so it's always done when serializing XML. Option 1 is probably less invasive, but option 2 is more likely to not have this keep popping up as a problem. Olli, do you have a preference?
Component: Untriaged → DOM: Core & HTML
Flags: needinfo?(bzbarsky) → needinfo?(bugs)
Summary: a4j.ajax.submit() does not function properly on Garmin Connect → a4j.ajax.submit() does not function properly on Garmin Connect because outerHTML on a node from an XML document outputs self-closing tags for empty HTML containers
Summary: a4j.ajax.submit() does not function properly on Garmin Connect because outerHTML on a node from an XML document outputs self-closing tags for empty HTML containers → Dropdowns for modifying the report disappear on Garmin Connect when you pick a value because outerHTML on a node from an XML document outputs self-closing tags for empty HTML containers
I think I'd prefer 2.
Assignee: nobody → bzbarsky
Status: NEW → ASSIGNED
Attachment #8707617 - Flags: review?(bugs) → review+
We do have quite some serializer tests somewhere, those might need some tweaking.
Try run at https://treeherder.mozilla.org/#/jobs?repo=try&revision=06c5bed956a7 says no tweaking needed.
You need to log in before you can comment on or make changes to this bug.