Closed
Bug 1245424
Opened 9 years ago
Closed 9 years ago
Fix crash on display:none summary and add test cases described in description
Categories
(Core :: Layout, defect)
Core
Layout
Tracking
()
RESOLVED
FIXED
mozilla48
People
(Reporter: TYLin, Assigned: TYLin)
References
(Blocks 1 open bug)
Details
Attachments
(3 files)
File this bug per bug 591737 comment 222.
bz: Also of interest are cases in which a capturing event listener higher up the DOM sets the <details> or <summary> to display:none. Or moves the <summary> to a different <details> element, for that matter. Please check what Chrome/Safari do in all three of those situations?
Currently, display:none summary will crash. Block bug 1226455.
Assignee | ||
Updated•9 years ago
|
Summary: Add test cases for display:none details and summary → Fix crash on display:none summary and add test cases described in description
Updated•9 years ago
|
No longer blocks: ship-details-summary
Assignee | ||
Updated•9 years ago
|
Assignee: nobody → tlin
Status: NEW → ASSIGNED
Assignee | ||
Comment 1•9 years ago
|
||
If the summary element has 'display: none' style, no summary frame will
be generated. So we only need to check the summary frame is generated
when the summary element doesn't have 'display: none'.
Review commit: https://reviewboard.mozilla.org/r/41415/diff/#index_header
See other reviews: https://reviewboard.mozilla.org/r/41415/
Attachment #8732887 -
Flags: review?(bzbarsky)
Assignee | ||
Comment 2•9 years ago
|
||
These tests modify details or summary elements in the 'click' event
listener in capturing phase higher up in the DOM tree.
Review commit: https://reviewboard.mozilla.org/r/41435/diff/#index_header
See other reviews: https://reviewboard.mozilla.org/r/41435/
Comment 3•9 years ago
|
||
Comment on attachment 8732887 [details]
MozReview Request: Bug 1245424 Part 1 - Fix assert for a display:none summary on debug build.
https://reviewboard.mozilla.org/r/41415/#review37881
::: layout/generic/DetailsFrame.cpp:76
(Diff revision 1)
> - nsIFrame* realFrame =
> - nsPlaceholderFrame::GetRealFrameFor(isOpen ?
> - aChildList.FirstChild() :
> - aChildList.OnlyChild());
> + HTMLSummaryElement* summary =
> + HTMLSummaryElement::FromContentOrNull(details->GetFirstSummary());
> + if (summary) {
> + nsIPresShell* presShell =
> + nsComputedDOMStyle::GetPresShellForContent(summary);
> + if (!nsGenericHTMLElement::IsOrHasAncestorWithDisplayNone(summary,
I don't think it's worth going to all these lengths. If display:none summary means that we have no kids, then the assert that we have kids is bogus and we should just take it out instead of trying to hedge it with complicated detection of the case when we might not have kids.
Attachment #8732887 -
Flags: review?(bzbarsky)
Assignee | ||
Comment 4•9 years ago
|
||
https://reviewboard.mozilla.org/r/41435/#review37885
Before asking review for part 2, I want to have a feedback about whether we need to persue the compactness with Chrome, i.e. we check whether details is display: none before toggle the 'open' attribute when summary receives a click event. https://hg.mozilla.org/mozilla-central/annotate/a2fe8535e63b/dom/html/HTMLSummaryElement.cpp#l63 These tests might rarely occur in real web pages, but they reveal a fact that we might never compact with Chrome in every corner cases.
Per discussion in [html spec issue](https://github.com/whatwg/html/issues/517#issuecomment-198460384), Olli also feels this behavior is weird. How risky if we do not compact in this case?
::: layout/reftests/details-summary/mouse-click-change-details-to-display-none.html:8
(Diff revision 1)
> + - http://creativecommons.org/publicdomain/zero/1.0/ -->
> +
> +<html class="reftest-wait">
> + <script>
> + function runTest() {
> + // Both Chrome and Safari add the 'open' attribute to the details element,
In this test case, I think our implmentation make sense because we correctly flush the frame in https://hg.mozilla.org/mozilla-central/annotate/a2fe8535e63b/dom/html/HTMLSummaryElement.cpp#l67 , so we don't toggle the details.
::: layout/reftests/details-summary/mouse-click-move-summary-to-different-details.html:8
(Diff revision 1)
> + - http://creativecommons.org/publicdomain/zero/1.0/ -->
> +
> +<html class="reftest-wait">
> + <script>
> + function runTest() {
> + // Both Chrome and Safari do not add the 'open' attribute to details1
This case is more interesting. Again, I think our implementations make sense.
Assignee | ||
Comment 6•9 years ago
|
||
https://reviewboard.mozilla.org/r/41415/#review37881
> I don't think it's worth going to all these lengths. If display:none summary means that we have no kids, then the assert that we have kids is bogus and we should just take it out instead of trying to hedge it with complicated detection of the case when we might not have kids.
display:none summary does not mean a details frame have no child. It just means it does not have a summary frame as its first child. If we can find a non-bogus way for this, I would still like to assert a fact that a details frame's first child should be a summary frame (either \<summay\> or a generated one) assuming the summary is not display:none. This catch many bugs when I did the work in nsCSSFrameConstructor.
Comment 7•9 years ago
|
||
> How risky if we do not compact in this case?
As in, if we toggle for a synthetic click on a display:none summary? I think that should be fine, personally... I expect it not working in Chrome is a side-effect of part of their impl living in the layout object or something. But it's worth checking with the Chrome folks explicitly to see why their behavior is as it is and whether they are open to changing it.
Same for the two tests you mention.
Comment 8•9 years ago
|
||
> display:none summary does not mean a details frame have no child. It just
> means it does not have a summary frame as its first child.
Yes, I understand that.
But my point is that once we have this exception, things get complicated. In particular, are we 100% sure that display:none is the only way for the <summary> to not have a frame? I'm about 90% sure it's not (e.g. I expect you can get there with XBL bindings, and there might be other stuff I'm just not thinking of right now)...
You _could_ assert that there is no summary frame anywhere in the child list if it's not in the right position. That seems like a valid assert to me, and much more robust. It has the drawback of being slow, but that would only matter if there is no summary frame in the right position, right?
One other thing, now that I'm thinking about this. Should all this "have a summary child" stuff be operating on the light DOM or the flattened tree, when shadow DOM is involved? And if the former, then what should happen for display:none on a flattened tree, but not DOM, ancestor of the <summary>?
Flags: needinfo?(bzbarsky)
Assignee | ||
Comment 9•9 years ago
|
||
Re comment #7: Filed a chromium bug https://bugs.chromium.org/p/chromium/issues/detail?id=596773
Assignee | ||
Comment 10•9 years ago
|
||
(In reply to Boris Zbarsky [:bz] from comment #8)
> > display:none summary does not mean a details frame have no child. It just
> > means it does not have a summary frame as its first child.
>
> Yes, I understand that.
>
> But my point is that once we have this exception, things get complicated.
> In particular, are we 100% sure that display:none is the only way for the
> <summary> to not have a frame? I'm about 90% sure it's not (e.g. I expect
> you can get there with XBL bindings, and there might be other stuff I'm just
> not thinking of right now)...
Yes. There might be other cases that I don't know of which could make summary to not have a frame.
> You _could_ assert that there is no summary frame anywhere in the child list
> if it's not in the right position. That seems like a valid assert to me,
> and much more robust. It has the drawback of being slow, but that would
> only matter if there is no summary frame in the right position, right?
Yes. A "display:none" summary isn't a normal case. Your approach should work, and I'll use it in my next patch set.
> One other thing, now that I'm thinking about this. Should all this "have a
> summary child" stuff be operating on the light DOM or the flattened tree,
> when shadow DOM is involved? And if the former, then what should happen for
> display:none on a flattened tree, but not DOM, ancestor of the <summary>?
Per html spec [1] , summary can be used only as the first child of a details element. We follow Chrome's behavior to extend it a bit to allow summary to have meaning if it's the direct child of an details element. So I think details/summary relationship only works in light DOM.
Assume a details element is in document tree as the shadow host the and the summary is in a shadow tree, we should add a default summary to the details, and any click event dispatches to the summary in shadow tree should do nothing. (I just learn shadow DOM today, so I might miss something :) )
[1] https://html.spec.whatwg.org/multipage/forms.html#the-summary-element
Comment 11•9 years ago
|
||
> So I think details/summary relationship only works in light DOM.
Is that what happens in Chrome? Because if we want it to work this way, then the summary frame thing is totally wrong: a <summary> that's a child in the light DOM may well be a grandchild in the flattened tree.
> Assume a details element is in document tree as the shadow host the and the
> summary is in a shadow tree, we should add a default summary to the details
OK, that sounds like you want to use the parent/child relationships in the flattened tree, not the light DOM....
Assignee | ||
Comment 12•9 years ago
|
||
(In reply to Boris Zbarsky [:bz] from comment #11)
> OK, that sounds like you want to use the parent/child relationships in the
> flattened tree, not the light DOM....
Yes, that's what I meant. Sorry for being confused by the terminology. File bug 1258948 for investigating details/summary involving with Shadow DOM. It seems that Chrome has a different thought about details being a shadow root.
Assignee | ||
Updated•9 years ago
|
Attachment #8732887 -
Flags: review?(bzbarsky)
Assignee | ||
Comment 13•9 years ago
|
||
Comment on attachment 8732887 [details]
MozReview Request: Bug 1245424 Part 1 - Fix assert for a display:none summary on debug build.
Review request updated; see interdiff: https://reviewboard.mozilla.org/r/41415/diff/1-2/
Assignee | ||
Comment 14•9 years ago
|
||
Review commit: https://reviewboard.mozilla.org/r/41937/diff/#index_header
See other reviews: https://reviewboard.mozilla.org/r/41937/
Attachment #8733748 -
Flags: review?(bzbarsky)
Assignee | ||
Updated•9 years ago
|
Attachment #8732888 -
Attachment description: MozReview Request: Bug 1245424 Part 2 - Add reftest for click events with actions in capturing phase. → MozReview Request: Bug 1245424 Part 3 - Add reftest for click events with actions in capturing phase.
Attachment #8732888 -
Flags: review?(bzbarsky)
Assignee | ||
Comment 15•9 years ago
|
||
Comment on attachment 8732888 [details]
MozReview Request: Bug 1245424 Part 3 - Add reftest for click events with actions in capturing phase.
Review request updated; see interdiff: https://reviewboard.mozilla.org/r/41435/diff/1-2/
Comment 16•9 years ago
|
||
FWIW, summary not details can be a shadow dom host.
http://w3c.github.io/webcomponents/spec/shadow/#widl-Element-attachShadow-ShadowRoot-ShadowRootInit-shadowRootInitDict
Comment 17•9 years ago
|
||
s/not/nor/
Assignee | ||
Comment 18•9 years ago
|
||
Re comment 16: Olli, thank you for the information!
Updated•9 years ago
|
Attachment #8732888 -
Flags: review?(bzbarsky) → review+
Comment 19•9 years ago
|
||
Comment on attachment 8732888 [details]
MozReview Request: Bug 1245424 Part 3 - Add reftest for click events with actions in capturing phase.
https://reviewboard.mozilla.org/r/41435/#review38551
::: layout/reftests/details-summary/mouse-click-change-details-to-display-none.html:20
(Diff revision 2)
> + }, true);
> +
> + summary.dispatchEvent(new MouseEvent("click"));
> +
> + details.style.display = "block";
> + document.documentElement.removeAttribute("class");
document.documentElement.className = "";
is probably simpler.
::: layout/reftests/details-summary/mouse-click-move-summary-to-different-details.html:15
(Diff revision 2)
> + // moved to details1 before receiving the 'click' event.
> + var details1 = document.getElementById("details1");
> + var summary2 = document.getElementById("summary2");
> +
> + document.body.addEventListener("click", function () {
> + // Move summary2 into details1 to be the main summary in capturing phase.
You mean in the default action phase, right?
Comment 20•9 years ago
|
||
Comment on attachment 8732887 [details]
MozReview Request: Bug 1245424 Part 1 - Fix assert for a display:none summary on debug build.
https://reviewboard.mozilla.org/r/41415/#review38555
::: layout/generic/DetailsFrame.cpp:77
(Diff revision 2)
> - aChildList.FirstChild() :
> - aChildList.OnlyChild());
> - MOZ_ASSERT(realFrame, "Principal list of details should not be empty!");
> - nsIFrame* summaryFrame = realFrame->GetContentInsertionFrame();
> - MOZ_ASSERT(summaryFrame->GetType() == nsGkAtoms::summaryFrame,
> - "The frame should be summary frame!");
> + HTMLSummaryElement* summary =
> + HTMLSummaryElement::FromContent(firstChild->GetContent());
> +
> + if (!summary || !summary->IsMainSummary()) {
> + for (nsIFrame* child = firstChild->GetNextSibling();
> + child;
Please use an nsFrameList::Enumerator or range-based iteration over aChildList instead of a manual GetNextSibling walk.
Attachment #8732887 -
Flags: review?(bzbarsky) → review+
Comment 21•9 years ago
|
||
Comment on attachment 8733748 [details]
MozReview Request: Bug 1245424 Part 2 - Stop checking the existence of details frame before toggling.
https://reviewboard.mozilla.org/r/41937/#review38557
Attachment #8733748 -
Flags: review?(bzbarsky) → review+
Assignee | ||
Comment 22•9 years ago
|
||
Comment on attachment 8732887 [details]
MozReview Request: Bug 1245424 Part 1 - Fix assert for a display:none summary on debug build.
Review request updated; see interdiff: https://reviewboard.mozilla.org/r/41415/diff/2-3/
Assignee | ||
Comment 23•9 years ago
|
||
Comment on attachment 8733748 [details]
MozReview Request: Bug 1245424 Part 2 - Stop checking the existence of details frame before toggling.
Review request updated; see interdiff: https://reviewboard.mozilla.org/r/41937/diff/1-2/
Assignee | ||
Comment 24•9 years ago
|
||
Comment on attachment 8732888 [details]
MozReview Request: Bug 1245424 Part 3 - Add reftest for click events with actions in capturing phase.
Review request updated; see interdiff: https://reviewboard.mozilla.org/r/41435/diff/2-3/
Assignee | ||
Comment 25•9 years ago
|
||
https://reviewboard.mozilla.org/r/41415/#review38555
> Please use an nsFrameList::Enumerator or range-based iteration over aChildList instead of a manual GetNextSibling walk.
Thanks for the suggestion. I use range-based for-loop to rewrite it, and it becomes simpler!
Assignee | ||
Comment 26•9 years ago
|
||
https://reviewboard.mozilla.org/r/41435/#review38551
> document.documentElement.className = "";
>
> is probably simpler.
Indeed, but other details & summary tests already used removeAttribute. I would like to keep it as it is, so it would be easier to search and replace when we migrate these tests to web-platform-test.
> You mean in the default action phase, right?
The click event handler will move the summary2 to details1 while the click event is in capturing phase, and the details1 will be toggled is in default action phase.
Comment 27•9 years ago
|
||
> I would like to keep it as it is
OK.
> The click event handler will move the summary2 to details1 while the click event is
> in capturing phase, and the details1 will be toggled is in default action phase.
Right. I guess the thing that confused me was whether "in capturing phase" referred to "move" or to "be the main summary". The idea is that the move happens in the capturing phase, so that by the default action phase we're the main summary.
Assignee | ||
Comment 28•9 years ago
|
||
(In reply to Boris Zbarsky [:bz] from comment #27)
> Right. I guess the thing that confused me was whether "in capturing phase"
> referred to "move" or to "be the main summary". The idea is that the move
> happens in the capturing phase, so that by the default action phase we're
> the main summary.
Ah. Now I see why you get confused. Sorry for my English. I can reword the sentence as "Move summary2 into details1 at capture phase, and summary2 will be the main summary of details1 at target phase."
Comment 29•9 years ago
|
||
That sounds perfect, thanks!
Assignee | ||
Comment 30•9 years ago
|
||
Comment on attachment 8732888 [details]
MozReview Request: Bug 1245424 Part 3 - Add reftest for click events with actions in capturing phase.
Review request updated; see interdiff: https://reviewboard.mozilla.org/r/41435/diff/3-4/
Comment 31•9 years ago
|
||
Comment 32•9 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/01e5078734f5
https://hg.mozilla.org/mozilla-central/rev/0e7a2d01c65f
https://hg.mozilla.org/mozilla-central/rev/777d18c1f521
Status: ASSIGNED → RESOLVED
Closed: 9 years ago
status-firefox48:
--- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla48
You need to log in
before you can comment on or make changes to this bug.
Description
•