Summary: | HTML5 <details> and <summary>: rendering | ||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Product: | WebKit | Reporter: | Luiz Agostini <luiz> | ||||||||||||||||||||||||||||||||||||||||
Component: | Layout and Rendering | Assignee: | Luiz Agostini <luiz> | ||||||||||||||||||||||||||||||||||||||||
Status: | RESOLVED FIXED | ||||||||||||||||||||||||||||||||||||||||||
Severity: | Normal | CC: | abarth, buildbot, cmarcelo, dglazkov, eric, gustavo, hyatt, info, jamesr, kenneth, mathias, morrita, tkent, webkit-ews, webkit.review.bot, xan.lopez | ||||||||||||||||||||||||||||||||||||||||
Priority: | P2 | Keywords: | HTML5 | ||||||||||||||||||||||||||||||||||||||||
Version: | 528+ (Nightly build) | ||||||||||||||||||||||||||||||||||||||||||
Hardware: | All | ||||||||||||||||||||||||||||||||||||||||||
OS: | All | ||||||||||||||||||||||||||||||||||||||||||
Bug Depends on: | 54260, 54584 | ||||||||||||||||||||||||||||||||||||||||||
Bug Blocks: | 32934, 56773, 56967, 57762 | ||||||||||||||||||||||||||||||||||||||||||
Attachments: |
|
Description
Luiz Agostini
2010-12-14 16:20:05 PST
Created attachment 76592 [details]
patch
Attachment 76592 [details] did not build on chromium: Build output: http://queues.webkit.org/results/7113004 Attachment 76592 [details] did not build on qt: Build output: http://queues.webkit.org/results/7176003 Attachment 76592 [details] did not build on win: Build output: http://queues.webkit.org/results/7152007 Comment on attachment 76592 [details] patch View in context: https://bugs.webkit.org/attachment.cgi?id=76592&action=review > WebCore/ChangeLog:5 > + RenderDetails: the first <summary> element child of a <details> element I do not understand this description. It is like something is missing. Maybe: Render the first summary element who is a child of a details element? or similar. > WebCore/rendering/RenderDetails.cpp:44 > +RenderBox* RenderDetails::findSummary() const Maybe firstSummary()? It sounds from the change log like there can be more > WebCore/rendering/RenderDetails.cpp:46 > + for (RenderObject* summary = firstChild(); summary; summary = summary->nextSibling()) { I guess this 'summary' is really potentialSummary? I guess calling it child instead would be better. What is used elsewhere? > WebCore/rendering/RenderDetails.cpp:53 > +RenderObject* RenderDetails::layoutSpecialExcludedChild(bool relayoutChildren) From the function name im not sure what exactly it does. It is the child that is special? or are you doing a special layout? > WebCore/rendering/RenderDetails.cpp:56 > + if (summary) { an early return seems better (In reply to comment #5) > (From update of attachment 76592 [details]) > View in context: https://bugs.webkit.org/attachment.cgi?id=76592&action=review > > > WebCore/rendering/RenderDetails.cpp:53 > > +RenderObject* RenderDetails::layoutSpecialExcludedChild(bool relayoutChildren) > > From the function name im not sure what exactly it does. It is the child that is special? or are you doing a special layout? Both. It is a special layout for a special child. It is an override of a virtual method of class RenderBlock. (In reply to comment #6) > (In reply to comment #5) > > (From update of attachment 76592 [details] [details]) > > View in context: https://bugs.webkit.org/attachment.cgi?id=76592&action=review > > > > > WebCore/rendering/RenderDetails.cpp:53 > > > +RenderObject* RenderDetails::layoutSpecialExcludedChild(bool relayoutChildren) > > > > From the function name im not sure what exactly it does. It is the child that is special? or are you doing a special layout? > > Both. It is a special layout for a special child. It is an override of a virtual method of class RenderBlock. Oh ok :-) not much you can do then. Maybe add a short comment in the method to what it is doing. Created attachment 76638 [details]
patch
Attachment 76592 [details] did not build on mac: Build output: http://queues.webkit.org/results/7089009 Hi Hyatt and Simon, can one of you have a look at this one? Are there any layout tests? This looks to introduce new layout code, so we should have one(or more). And I'm curious how <details> would work ;-) Created attachment 80917 [details]
patch
(In reply to comment #11) > Are there any layout tests? > This looks to introduce new layout code, so we should have one(or more). > And I'm curious how <details> would work ;-) Yes, we will need layout tests for sure! I will work on them soon. :) I will upload an html file that I am using for testing. Attachment 80917 [details] did not build on win: Build output: http://queues.webkit.org/results/7685925 Attachment 80917 [details] did not build on mac: Build output: http://queues.webkit.org/results/7689213 Created attachment 80928 [details]
patch
build fix
Comment on attachment 80928 [details] patch View in context: https://bugs.webkit.org/attachment.cgi?id=80928&action=review > Source/WebCore/rendering/RenderDetails.cpp:109 > + m_interactiveArea = IntRect(m_mainSummary->logicalLeft(), m_mainSummary->logicalTop(), m_mainSummary->logicalWidth(), m_mainSummary->logicalHeight()); This seems hard-coded to horizontal text. > Source/WebCore/rendering/RenderDetailsMarker.cpp:107 > +static Path getCannonicalPath(bool isOpen, bool isLtr) This should be getCanonicalPath. It also seems like this appearance may be hardcoded assuming a particular orientation (horizontal). Have you tested this element in vertical text mode (and/or decided what it's going to do in that mode)? > Source/WebCore/rendering/RenderObject.cpp:135 > + if (node->hasTagName(summaryTag)) > + return new (arena) RenderSummary(node); Since this is tied directly to a specific DOM element, don't put this in the generic RenderObject creation method. That's reserved only for objects that have display types. Assuming there is a DOM subclass for HTMLSummaryElement, put the creation there. > Source/WebCore/rendering/RenderSummary.cpp:86 > +RenderObject* RenderSummary::getParentOfFirstLineBox(RenderBlock* curr) This looks like a duplication of the RenderListItem function, even down to the odd quirks mode behavior for lists. I'm not sure why you'd want to propagate list item quirks into a brand new HTML5 element. (In reply to comment #17) > (From update of attachment 80928 [details]) > View in context: https://bugs.webkit.org/attachment.cgi?id=80928&action=review > > > Source/WebCore/rendering/RenderDetails.cpp:109 > > + m_interactiveArea = IntRect(m_mainSummary->logicalLeft(), m_mainSummary->logicalTop(), m_mainSummary->logicalWidth(), m_mainSummary->logicalHeight()); > > This seems hard-coded to horizontal text. If I understood it right it is not. For example, this is the implementation of RenderBox::logicalLeft int logicalLeft() const { return style()->isHorizontalWritingMode() ? x() : y(); } Am I wrong? > > > Source/WebCore/rendering/RenderDetailsMarker.cpp:107 > > +static Path getCannonicalPath(bool isOpen, bool isLtr) > > This should be getCanonicalPath. It also seems like this appearance may be hardcoded assuming a particular orientation (horizontal). Have you tested this element in vertical text mode (and/or decided what it's going to do in that mode)? Yes, it is assuming horizontal orientation. I will fix it. > > > Source/WebCore/rendering/RenderObject.cpp:135 > > + if (node->hasTagName(summaryTag)) > > + return new (arena) RenderSummary(node); > > Since this is tied directly to a specific DOM element, don't put this in the generic RenderObject creation method. That's reserved only for objects that have display types. Assuming there is a DOM subclass for HTMLSummaryElement, put the creation there. It would be nice to have a DOM subclass for HTMLSummaryElement but specification says that the interface is HTMLElement (http://www.w3.org/TR/html5/interactive-elements.html#the-summary-element). May I create the HTMLSummaryElement anyway? > > > Source/WebCore/rendering/RenderSummary.cpp:86 > > +RenderObject* RenderSummary::getParentOfFirstLineBox(RenderBlock* curr) > > This looks like a duplication of the RenderListItem function, even down to the odd quirks mode behavior for lists. I'm not sure why you'd want to propagate list item quirks into a brand new HTML5 element. Yes, I did duplicate some functions of RenderListItem keeping them as is for the duplication to be clear. I just made minor changes to getParentOfFirstLineBox but of course quirks mode should not be considered. Created attachment 81141 [details]
patch
I made some optimizations and prepared the way for creating own legend if there is no <summary> element.
I made some changes according to the review comments as well but did not cover all of them yet.
Next steps will probably be:
- to create <details> own legend when there is no <summary> element.
- to provide layout tests.
- to fix pending layout issues.
Created attachment 81657 [details]
patch
Attachment 81657 [details] did not build on chromium: Build output: http://queues.webkit.org/results/7763149 Attachment 81657 [details] did not build on gtk: Build output: http://queues.webkit.org/results/7763150 Attachment 81657 [details] did not build on win: Build output: http://queues.webkit.org/results/7819162 Attachment 81657 [details] did not build on qt: Build output: http://queues.webkit.org/results/7797148 Attachment 81657 [details] did not build on chromium: Build output: http://queues.webkit.org/results/7847145 Attachment 81657 [details] did not build on mac: Build output: http://queues.webkit.org/results/7847148 Created attachment 81678 [details]
patch
Attachment 81678 [details] did not build on chromium: Build output: http://queues.webkit.org/results/7819190 Created attachment 81680 [details]
patch
build fix
Created attachment 81865 [details]
patch
(In reply to comment #17) > (From update of attachment 80928 [details]) > View in context: https://bugs.webkit.org/attachment.cgi?id=80928&action=review > > > Source/WebCore/rendering/RenderDetails.cpp:109 > > + m_interactiveArea = IntRect(m_mainSummary->logicalLeft(), m_mainSummary->logicalTop(), m_mainSummary->logicalWidth(), m_mainSummary->logicalHeight()); > > This seems hard-coded to horizontal text. It should be ok in last patch. > > > Source/WebCore/rendering/RenderDetailsMarker.cpp:107 > > +static Path getCannonicalPath(bool isOpen, bool isLtr) > > This should be getCanonicalPath. It also seems like this appearance may be hardcoded assuming a particular orientation (horizontal). Have you tested this element in vertical text mode (and/or decided what it's going to do in that mode)? It should be ok in last patch as well. > > > Source/WebCore/rendering/RenderObject.cpp:135 > > + if (node->hasTagName(summaryTag)) > > + return new (arena) RenderSummary(node); > > Since this is tied directly to a specific DOM element, don't put this in the generic RenderObject creation method. That's reserved only for objects that have display types. Assuming there is a DOM subclass for HTMLSummaryElement, put the creation there. May I create a DOM subclass for HTMLSummaryElement? Specification says that the interface is HTMLElement (http://www.w3.org/TR/html5/interactive-elements.html#the-summary-element). Attachment 81865 [details] did not build on win: Build output: http://queues.webkit.org/results/7874059 Attachment 81865 [details] did not build on qt: Build output: http://queues.webkit.org/results/7869068 Attachment 81865 [details] did not build on chromium: Build output: http://queues.webkit.org/results/7870080 Attachment 81865 [details] did not build on mac: Build output: http://queues.webkit.org/results/7884214 Created attachment 81971 [details]
patch
Attachment 81971 [details] did not pass style-queue:
Failed to run "['Tools/Scripts/check-webkit-style', '--diff-files', u'Source/WebCore/ChangeLog', u'Source/WebCor..." exit_code: 1
Source/WebCore/rendering/RenderDetailsMarker.cpp:100: Code inside a namespace should not be indented. [whitespace/indent] [4]
Total errors found: 1 in 36 files
If any of these errors are false positives, please file a bug against check-webkit-style.
Created attachment 82030 [details]
patch
Created attachment 82045 [details]
sample html
Created attachment 82046 [details]
screen shot
Created attachment 82092 [details] patch I removed the localization code from this patch. Now this bug depends on bug 54260. Created attachment 82536 [details]
patch
some layout tests
Comment on attachment 82536 [details] patch View in context: https://bugs.webkit.org/attachment.cgi?id=82536&action=review Thanks for adding all the writing mode logic. This looks great. Just a few comments. > Source/WebCore/rendering/RenderDetails.cpp:179 > + switch (style()->writingMode()) { > + case TopToBottomWritingMode: > + case LeftToRightWritingMode: > + break; > + case RightToLeftWritingMode: { > + m_interactiveArea.setX(width() - m_interactiveArea.x() - m_interactiveArea.width()); > + break; > + } > + case BottomToTopWritingMode: { > + m_interactiveArea.setY(height() - m_interactiveArea.y() - m_interactiveArea.height()); > + break; > + } > + } > +} The interactive area is supposed to be in the local coordinates of the RenderDetails. I suspect you're just working around the fact that absoluteToLocal has not been patched to handle flipped blocks writing modes yet. I would just yank this code, since once absoluteToLocal works correctly, you won't need it. Note that if you could somehow get back to the hit test result, there are correct local mouse event coordinates in there for the renderer that was hit. I'm not sure if that's possible from defaultEventHandler though. At any rate, you have my blessing for this to be broken with flipped blocks writing modes, since absoluteToLocal does need to be patched eventually. > Source/WebCore/rendering/RenderDetailsMarker.cpp:135 > + switch (style()->direction()) { We're trying to avoid querying direction like this nowadays. Use style()->isLeftToRightDirection() instead. It will cut down on the use of these LTR/RTL constants when we get around to renaming them. > Source/WebCore/rendering/RenderDetailsMarker.cpp:140 > + switch (style()->direction()) { Here too. > Source/WebCore/rendering/RenderDetailsMarker.cpp:145 > + switch (style()->direction()) { And here. > Source/WebCore/rendering/RenderDetailsMarker.cpp:150 > + switch (style()->direction()) { And here. > Source/WebCore/rendering/RenderObject.cpp:135 > + if (node->hasTagName(summaryTag)) > + return HTMLDetailsElement::createSummaryRenderer(arena, node); Still don't like this. It's ok to make an HTMLSummaryElement subclass without having any special DOM bindings for it. I'd prefer you did that. I think you'll find once you have that element that there will be other things you may want to put there in the future anwyay. Created attachment 82873 [details]
patch
Comment on attachment 82873 [details] patch View in context: https://bugs.webkit.org/attachment.cgi?id=82873&action=review > Source/WebCore/html/HTMLDetailsElement.cpp:68 > + if (oldSummary != m_mainSummary && attached()) { > + detach(); > + attach(); > + } Can you explain why this is necessary? Detaching and re-attaching seems hacky to me. > Source/WebCore/html/HTMLDetailsElement.cpp:92 > + if (attached() && oldValue != m_isOpen) { > + detach(); > + attach(); > + } Can you explain why this is necessary? Detaching and re-attaching seems hacky to me. (In reply to comment #45) > (From update of attachment 82873 [details]) > View in context: https://bugs.webkit.org/attachment.cgi?id=82873&action=review > > > Source/WebCore/html/HTMLDetailsElement.cpp:68 > > + if (oldSummary != m_mainSummary && attached()) { > > + detach(); > > + attach(); > > + } > If a <summary> element is added before all other <summary> elements in a <details> element it will become its main <summary>. The previous main <summary> element will have its rendering changed. It may be that the previous main <summary> will not even be rendered depending on the current value of the 'open' attribute of the <details>. But it may be that, in this case, it could be optimized. > Can you explain why this is necessary? Detaching and re-attaching seems hacky to me. > > > Source/WebCore/html/HTMLDetailsElement.cpp:92 > > + if (attached() && oldValue != m_isOpen) { > > + detach(); > > + attach(); > > + } > > Can you explain why this is necessary? Detaching and re-attaching seems hacky to me. If the open attribute of <details> is false then its children will not be rendered (except its main <summary>). When closed, no render is created to <details> children. When open changes the <details> is re-attached to remove its children renderes if 'open' has changed to false, or to create children renderers if 'open' has changed to true. (In reply to comment #46) > (In reply to comment #45) > > (From update of attachment 82873 [details] [details]) > > View in context: https://bugs.webkit.org/attachment.cgi?id=82873&action=review > > > > > Source/WebCore/html/HTMLDetailsElement.cpp:68 > > > + if (oldSummary != m_mainSummary && attached()) { > > > + detach(); > > > + attach(); > > > + } > > > > If a <summary> element is added before all other <summary> elements in a <details> element it will become its main <summary>. The previous main <summary> element will have its rendering changed. It may be that the previous main <summary> will not even be rendered depending on the current value of the 'open' attribute of the <details>. > Yeah but it's still a RenderSummary in both cases, so I don't buy that you have to nuke the entire RenderDetails and all of its descendants just because a different summary became the main one. It doesn't seem hard to shift what the main summary is, since the render object types aren't changing. > But it may be that, in this case, it could be optimized. > > > Can you explain why this is necessary? Detaching and re-attaching seems hacky to me. > > > > > Source/WebCore/html/HTMLDetailsElement.cpp:92 > > > + if (attached() && oldValue != m_isOpen) { > > > + detach(); > > > + attach(); > > > + } > > > > Can you explain why this is necessary? Detaching and re-attaching seems hacky to me. > > If the open attribute of <details> is false then its children will not be rendered (except its main <summary>). When closed, no render is created to <details> children. > When open changes the <details> is re-attached to remove its children renderes if 'open' has changed to false, or to create children renderers if 'open' has changed to true. Ok I buy this one. As long as this patch isn’t landed, WebKit false positives on the feature test for native <details> support (without actually supporting it): 'open' in document.createElement('details'); // true See data:text/html,<details><summary>Foo</summary>Bar</details><script>console.log('open' in document.createElement('details'));</script> Created attachment 84073 [details]
patch
Comment on attachment 84073 [details] patch View in context: https://bugs.webkit.org/attachment.cgi?id=84073&action=review Comments below; > Source/WebCore/html/HTMLDetailsElement.cpp:59 > + for (Node* child = firstChild(); !m_mainSummary && child; child = child->nextSibling()) { > + if (child->hasTagName(summaryTag)) > + m_mainSummary = child; > + } Kind of a funny way to write this. I'd just do a break rather than testing !m_mainSummary in the condition. > Source/WebCore/html/HTMLDetailsElement.cpp:78 > + if (!changedByParser) { > + Node* oldSummary = m_mainSummary; > + findMainSummary(); > + > + if (oldSummary != m_mainSummary && !m_isOpen && attached()) { > + if (oldSummary && oldSummary->attached()) > + oldSummary->detach(); > + if (m_mainSummary && childCountDelta < 0 && !m_mainSummary->renderer()) { > + m_mainSummary->detach(); > + m_mainSummary->attach(); > + } > + } > + } > +} Can you explain this case? I'm having trouble understanding what's going on here. In particular childCountDelta < 0? I get why you have to detach the old summary since it's now inside the unrevealed content, but I don't understand the mainSummary case. > Source/WebCore/html/HTMLDetailsElement.cpp:87 > + if (attached() && m_mainSummary && !m_mainSummary->renderer()) { > + m_mainSummary->detach(); > + m_mainSummary->attach(); > + } It feels like this has some overlap with the code in childrenChanged... maybe you should incorporate the attach/detach updating into findMainSummary? > Source/WebCore/html/HTMLDetailsElement.cpp:122 > + FloatPoint absolutePosition = renderDetails->absoluteToLocal(FloatPoint(mouseEvent->pageX() * factor, mouseEvent->pageY() * factor)); You should rename this. The point is a local position not an absolute position.. (In reply to comment #50) > (From update of attachment 84073 [details]) > View in context: https://bugs.webkit.org/attachment.cgi?id=84073&action=review > > Comments below; > > > Source/WebCore/html/HTMLDetailsElement.cpp:59 > > + for (Node* child = firstChild(); !m_mainSummary && child; child = child->nextSibling()) { > > + if (child->hasTagName(summaryTag)) > > + m_mainSummary = child; > > + } > > Kind of a funny way to write this. I'd just do a break rather than testing !m_mainSummary in the condition. ok > > > Source/WebCore/html/HTMLDetailsElement.cpp:78 > > + if (!changedByParser) { > > + Node* oldSummary = m_mainSummary; > > + findMainSummary(); > > + > > + if (oldSummary != m_mainSummary && !m_isOpen && attached()) { > > + if (oldSummary && oldSummary->attached()) > > + oldSummary->detach(); > > + if (m_mainSummary && childCountDelta < 0 && !m_mainSummary->renderer()) { > > + m_mainSummary->detach(); > > + m_mainSummary->attach(); > > + } > > + } > > + } > > +} > > Can you explain this case? I'm having trouble understanding what's going on here. In particular childCountDelta < 0? I get why you have to detach the old summary since it's now inside the unrevealed content, but I don't understand the mainSummary case. If childCountDelta is less then zero and the main summary has changed it must be because previous main summary was removed. The new main summary was then inside the unrevealed content and needs to be reattached to create its renderer. If childCountDelta is not less then zero then a new <summary> was added and it will be attached without my help. > > > Source/WebCore/html/HTMLDetailsElement.cpp:87 > > + if (attached() && m_mainSummary && !m_mainSummary->renderer()) { > > + m_mainSummary->detach(); > > + m_mainSummary->attach(); > > + } > > It feels like this has some overlap with the code in childrenChanged... maybe you should incorporate the attach/detach updating into findMainSummary? It is similar to what is done in childrenChanged but not equal. I considered adding parameters to findMainSummary but at the end I found that it would more clear for each method to do what it needs alone. > > > Source/WebCore/html/HTMLDetailsElement.cpp:122 > > + FloatPoint absolutePosition = renderDetails->absoluteToLocal(FloatPoint(mouseEvent->pageX() * factor, mouseEvent->pageY() * factor)); > > You should rename this. The point is a local position not an absolute position.. ok. Created attachment 84097 [details]
patch
Nice work, Luiz! Shouldn’t the first <summary> element of every <details> element be keyboard accessible? (In reply to comment #53) > Nice work, Luiz! Thanks. > > Shouldn’t the first <summary> element of every <details> element be keyboard accessible? Yes, I think it should. I will handle accessibility issues in future patches. Created attachment 85360 [details]
patch
Comment on attachment 85360 [details]
patch
r=me
Committed r81035: <http://trac.webkit.org/changeset/81035> http://trac.webkit.org/changeset/81035 might have broken Leopard Intel Release (Build) This is causing crashes: https://bugs.webkit.org/show_bug.cgi?id=56773 This probably should've been implemented using the new shadow DOM plumbing. I'll try to convert. (In reply to comment #60) > This probably should've been implemented using the new shadow DOM plumbing. I'll try to convert. Oh you implemented parts of ideas from XBL2? Can you give me the relavant commit revision to have a look? :-) (In reply to comment #61) > (In reply to comment #60) > > This probably should've been implemented using the new shadow DOM plumbing. I'll try to convert. > > Oh you implemented parts of ideas from XBL2? Can you give me the relavant commit revision to have a look? :-) The trail starts here: https://bugs.webkit.org/showdependencytree.cgi?id=52962&hide_resolved=0 (In reply to comment #62) > (In reply to comment #61) > > (In reply to comment #60) > > > This probably should've been implemented using the new shadow DOM plumbing. I'll try to convert. > > > > Oh you implemented parts of ideas from XBL2? Can you give me the relavant commit revision to have a look? :-) > > The trail starts here: https://bugs.webkit.org/showdependencytree.cgi?id=52962&hide_resolved=0 Thanks! Seems that you guys have been quite busy, nice work |