Closed Bug 1032979 Opened 5 years ago Closed 4 years ago

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

Categories

(Core :: DOM: Core & HTML, defect, major)

x86_64
All
defect
Not set
major

Tracking

()

RESOLVED FIXED
mozilla46
Tracking Status
firefox46 --- fixed

People

(Reporter: 11samype, Assigned: bzbarsky)

References

()

Details

Attachments

(3 files)

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36

Steps to reproduce:

Go to connect.garmin.com/reports (account required), change either the time interval or activity type drop downs. The elements disappear.


Actual results:

Those drop down menus make an ajax call: A4J.AJAX.Submit('reportFilterForm',event,{'similarityGroupingId':'reportFilterForm:hiddenReportSubmit','parameters':{'reportFilterForm:hiddenReportSubmit':'reportFilterForm:hiddenReportSubmit'} ,'actionUrl':'/reports'} ). Running through the debugger shows that Firefox does not properly handle this call (other browsers work fine). The source file (3_3_3.Finalorg.ajax4jsf.javascript is minified and the definition of A4J.AJAX.Submit() is in the middle of the line. Instead of running there, Firefox seems to got to the beginning of the line which is in the middle of the A4J.AJAX.SubmitQuery() function. This behavior makes no sense.


Expected results:

The drop down menus should not disappear and the call to A4J.AJAX.Submit() should function properly.
Hardware: x86 → x86_64
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
Version: 30 Branch → 31 Branch
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
Flags: needinfo?(vlad.bacia)
Hi,

The steps that I have followed are: 

1. I've accessed https://connect.garmin.com/reports .
2. Login using the following credentials:
User: garmin.testingjohn@mailinator.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
Flags: needinfo?(bugs)
Attachment #8707617 - Flags: review?(bugs) → review+
Attachment #8707618 - Flags: review?(bugs) → review+
We do have quite some serializer tests somewhere, those might need some tweaking.
https://hg.mozilla.org/mozilla-central/rev/2e8e06c6d251
https://hg.mozilla.org/mozilla-central/rev/6b1aff2a5757
Status: ASSIGNED → RESOLVED
Closed: 4 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla46
You need to log in before you can comment on or make changes to this bug.