Changeset 147756 in webkit


Ignore:
Timestamp:
Apr 5, 2013 10:15:09 AM (11 years ago)
Author:
commit-queue@webkit.org
Message:

[CSS Regions] Elements in a region should be assignable to a named flow
https://bugs.webkit.org/show_bug.cgi?id=74144

Patch by Mihai Maerean <Mihai Maerean> on 2013-04-05
Reviewed by David Hyatt.

Source/WebCore:

DOM children of a region must not be rendered as children of the region, but can be collected in flow threads.

NodeRenderingContext::parentRenderer now creates the parent render flow thread if it doesn't exist.

Element::moveToFlowThreadIsNeeded is a virtual method that is overriden in PseudoElement to return false and
in SVGElement so only svg root elements can directly be collected by a render flow thread.

RenderObject::canDOMChildrenHaveRenderParent exists to optimize the code so nodes inside regions (and maybe
other types of renderers in the future) can still have renderers if they need to be in a flow thread while the
rest of renderers that can't have children skip the new instructions.

Tests: fast/regions/flow-body-in-html.html . To test the duplicate bug #103685.

fast/regions/region-content-flown-into-region.html
fast/regions/universal-selector-children-to-the-same-region.html . To test the duplicate bug #103685.

  • dom/Element.cpp:

(WebCore::Element::moveToFlowThreadIsNeeded):

  • dom/Element.h:
  • dom/NodeRenderingContext.cpp:

(WebCore::NodeRenderingContext::parentRenderer): the renderer that will be the parent for this node's renderer.
In the case of RenderFlowThreads, it may need to create it.
(WebCore::NodeRenderingContext::shouldCreateRenderer): In a region, only the children that need to be in a flow
thread should have a renderer.
(WebCore::NodeRenderingContext::moveToFlowThreadIfNeeded):
(WebCore::NodeRenderingContext::moveToFlowThread):

  • dom/NodeRenderingContext.h:

(NodeRenderingContext):

  • dom/PseudoElement.h: pseudo-elements cannot be directly collected into a named flow.
  • dom/Text.cpp:

(WebCore::Text::textRendererIsNeeded):
(WebCore::Text::updateTextRenderer): Because calling textRendererIsNeeded(NodeRenderingContext(...)) on a
non-const l-value NodeRenderingContext cannot be done on a temporary object on the stack.

  • dom/Text.h:
  • rendering/FlowThreadController.cpp:

(WebCore::FlowThreadController::isContentNodeRegisteredWithAnyNamedFlow):

  • rendering/FlowThreadController.h:
  • rendering/RenderObject.h:

(WebCore::RenderObject::canDOMChildrenHaveRenderParent): Even if this render object can't have render children,
the children in the DOM tree may have a render parent (that is different from this render object).

  • rendering/RenderRegion.h:
  • svg/SVGElement.cpp:

(WebCore::SVGElement::moveToFlowThreadIsNeeded): Allow only svg root elements to be directly collected by a
render flow thread.

  • svg/SVGElement.h:

(SVGElement):

LayoutTests:

  • fast/regions/flow-body-in-html-expected.txt: Added.
  • fast/regions/flow-body-in-html.html: Added. To test the duplicate bug #103685.
  • fast/regions/region-content-flown-into-region-expected.html: Added.
  • fast/regions/region-content-flown-into-region.html: Added.
  • fast/regions/universal-selector-children-to-the-same-region-expected.txt: Added.
  • fast/regions/universal-selector-children-to-the-same-region.html: Added. To test the duplicate bug #103685.
Location:
trunk
Files:
6 added
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r147739 r147756  
     12013-04-05  Mihai Maerean  <mmaerean@adobe.com>
     2
     3        [CSS Regions] Elements in a region should be assignable to a named flow
     4        https://bugs.webkit.org/show_bug.cgi?id=74144
     5
     6        Reviewed by David Hyatt.
     7
     8        * fast/regions/flow-body-in-html-expected.txt: Added.
     9        * fast/regions/flow-body-in-html.html: Added. To test the duplicate bug #103685.
     10        * fast/regions/region-content-flown-into-region-expected.html: Added.
     11        * fast/regions/region-content-flown-into-region.html: Added.
     12        * fast/regions/universal-selector-children-to-the-same-region-expected.txt: Added.
     13        * fast/regions/universal-selector-children-to-the-same-region.html: Added. To test the duplicate bug #103685.
     14
    1152013-04-05  Aivo Paas  <aivopaas@gmail.com>
    216
  • trunk/Source/WebCore/ChangeLog

    r147751 r147756  
     12013-04-05  Mihai Maerean  <mmaerean@adobe.com>
     2
     3        [CSS Regions] Elements in a region should be assignable to a named flow
     4        https://bugs.webkit.org/show_bug.cgi?id=74144
     5
     6        Reviewed by David Hyatt.
     7
     8        DOM children of a region must not be rendered as children of the region, but can be collected in flow threads.
     9
     10        NodeRenderingContext::parentRenderer now creates the parent render flow thread if it doesn't exist.
     11
     12        Element::moveToFlowThreadIsNeeded is a virtual method that is overriden in PseudoElement to return false and
     13        in SVGElement so only svg root elements can directly be collected by a render flow thread.
     14
     15        RenderObject::canDOMChildrenHaveRenderParent exists to optimize the code so nodes inside regions (and maybe
     16        other types of renderers in the future) can still have renderers if they need to be in a flow thread while the
     17        rest of renderers that can't have children skip the new instructions.
     18
     19        Tests: fast/regions/flow-body-in-html.html . To test the duplicate bug #103685.
     20               fast/regions/region-content-flown-into-region.html
     21               fast/regions/universal-selector-children-to-the-same-region.html . To test the duplicate bug #103685.
     22
     23        * dom/Element.cpp:
     24        (WebCore::Element::moveToFlowThreadIsNeeded):
     25        * dom/Element.h:
     26        * dom/NodeRenderingContext.cpp:
     27        (WebCore::NodeRenderingContext::parentRenderer): the renderer that will be the parent for this node's renderer.
     28        In the case of RenderFlowThreads, it may need to create it.
     29        (WebCore::NodeRenderingContext::shouldCreateRenderer): In a region, only the children that need to be in a flow
     30        thread should have a renderer.
     31        (WebCore::NodeRenderingContext::moveToFlowThreadIfNeeded):
     32        (WebCore::NodeRenderingContext::moveToFlowThread):
     33        * dom/NodeRenderingContext.h:
     34        (NodeRenderingContext):
     35        * dom/PseudoElement.h: pseudo-elements cannot be directly collected into a named flow.
     36        * dom/Text.cpp:
     37        (WebCore::Text::textRendererIsNeeded):
     38        (WebCore::Text::updateTextRenderer): Because calling textRendererIsNeeded(NodeRenderingContext(...)) on a
     39        non-const l-value NodeRenderingContext cannot be done on a temporary object on the stack.
     40        * dom/Text.h:
     41        * rendering/FlowThreadController.cpp:
     42        (WebCore::FlowThreadController::isContentNodeRegisteredWithAnyNamedFlow):
     43        * rendering/FlowThreadController.h:
     44        * rendering/RenderObject.h:
     45        (WebCore::RenderObject::canDOMChildrenHaveRenderParent): Even if this render object can't have render children,
     46        the children in the DOM tree may have a render parent (that is different from this render object).
     47        * rendering/RenderRegion.h:
     48        * svg/SVGElement.cpp:
     49        (WebCore::SVGElement::moveToFlowThreadIsNeeded): Allow only svg root elements to be directly collected by a
     50        render flow thread.
     51        * svg/SVGElement.h:
     52        (SVGElement):
     53
    1542013-04-05  Allan Sandfeld Jensen  <allan.jensen@digia.com>
    255
  • trunk/Source/WebCore/dom/Element.cpp

    r147558 r147756  
    25592559}
    25602560
     2561bool Element::moveToFlowThreadIsNeeded(RefPtr<RenderStyle>& cachedStyle)
     2562{
     2563    Document* doc = document();
     2564   
     2565    if (!doc->cssRegionsEnabled())
     2566        return false;
     2567
     2568#if ENABLE(FULLSCREEN_API)
     2569    if (doc->webkitIsFullScreen() && doc->webkitCurrentFullScreenElement() == this)
     2570        return false;
     2571#endif
     2572
     2573    if (isInShadowTree())
     2574        return false;
     2575
     2576    if (!cachedStyle)
     2577        cachedStyle = styleForRenderer();
     2578    if (!cachedStyle)
     2579        return false;
     2580
     2581    if (cachedStyle->flowThread().isEmpty())
     2582        return false;
     2583
     2584    return !document()->renderView()->flowThreadController()->isContentNodeRegisteredWithAnyNamedFlow(this);
     2585}
     2586
    25612587#if ENABLE(CSS_REGIONS)
    25622588
  • trunk/Source/WebCore/dom/Element.h

    r147558 r147756  
    610610
    611611    RenderRegion* renderRegion() const;
     612    virtual bool moveToFlowThreadIsNeeded(RefPtr<RenderStyle>& cachedStyle);
    612613#if ENABLE(CSS_REGIONS)
    613614    const AtomicString& webkitRegionOverset() const;
  • trunk/Source/WebCore/dom/NodeRenderingContext.cpp

    r144461 r147756  
    149149}
    150150
    151 RenderObject* NodeRenderingContext::parentRenderer() const
     151RenderObject* NodeRenderingContext::parentRenderer()
    152152{
    153153    if (RenderObject* renderer = m_node->renderer())
     
    171171        return m_parentFlowRenderer;
    172172
     173    if (m_node->isElementNode() && toElement(m_node)->moveToFlowThreadIsNeeded(m_style)) {
     174        moveToFlowThread();
     175        return m_parentFlowRenderer;
     176    }
     177
    173178    return m_renderingParent ? m_renderingParent->renderer() : 0;
    174179}
    175180
    176 bool NodeRenderingContext::shouldCreateRenderer() const
     181bool NodeRenderingContext::shouldCreateRenderer()
    177182{
    178183    if (!m_node->document()->shouldCreateRenderers())
     
    183188    if (!parentRenderer)
    184189        return false;
    185     if (!parentRenderer->canHaveChildren())
    186         return false;
     190    if (!parentRenderer->canHaveChildren()) {
     191        if (parentRenderer->canDOMChildrenHaveRenderParent()) {
     192            // In a region, only the children that need to be in a flow thread should have a renderer.
     193            bool shouldBeInNamedFlow = m_node->isElementNode() && toElement(m_node)->moveToFlowThreadIsNeeded(m_style);
     194            if (!shouldBeInNamedFlow)
     195                return false;
     196        } else
     197            return false;
     198    }
     199
    187200    if (!m_renderingParent->childShouldCreateRenderer(*this))
    188201        return false;
     
    193206{
    194207    ASSERT(m_node->isElementNode());
     208
     209    if (!toElement(m_node)->moveToFlowThreadIsNeeded(m_style))
     210        return;
     211
     212    moveToFlowThread();
     213}
     214
     215void NodeRenderingContext::moveToFlowThread()
     216{
     217    ASSERT(m_node->isElementNode());
     218    ASSERT(toElement(m_node)->moveToFlowThreadIsNeeded(m_style));
     219
     220    if (!m_style)
     221        m_style = toElement(m_node)->styleForRenderer();
    195222    ASSERT(m_style);
    196     if (!m_node->document()->cssRegionsEnabled())
    197         return;
    198 
    199     if (m_style->flowThread().isEmpty())
    200         return;
    201 
    202     // As per http://dev.w3.org/csswg/css3-regions/#flow-into, pseudo-elements such as ::first-line, ::first-letter, ::before or ::after
    203     // cannot be directly collected into a named flow.
    204     if (m_node->isPseudoElement())
    205         return;
    206 
    207     // FIXME: Do not collect elements if they are in shadow tree.
    208     if (m_node->isInShadowTree())
    209         return;
    210 
    211 #if ENABLE(FULLSCREEN_API)
    212     Document* document = m_node->document();
    213     if (document->webkitIsFullScreen() && document->webkitCurrentFullScreenElement() == m_node)
    214         return;
    215 #endif
    216 
    217 #if ENABLE(SVG)
    218     // Allow only svg root elements to be directly collected by a render flow thread.
    219     if (m_node->isSVGElement()
    220         && (!(m_node->hasTagName(SVGNames::svgTag) && m_node->parentNode() && !m_node->parentNode()->isSVGElement())))
    221         return;
    222 #endif
    223 
    224223    m_flowThread = m_style->flowThread();
    225224    ASSERT(m_node->document()->renderView());
  • trunk/Source/WebCore/dom/NodeRenderingContext.h

    r137715 r147756  
    5656    ContainerNode* parentNodeForRenderingAndStyle() const;
    5757    bool resetStyleInheritance() const;
    58     RenderObject* parentRenderer() const;
     58    RenderObject* parentRenderer(); // the renderer that will be the parent for this node's renderer. In the case of RenderFlowThreads, it may need to create it.
    5959    RenderObject* nextRenderer() const;
    6060    RenderObject* previousRenderer() const;
     
    6767
    6868private:
    69     bool shouldCreateRenderer() const;
     69    bool shouldCreateRenderer();
     70    void moveToFlowThread();
    7071    void moveToFlowThreadIfNeeded();
    7172
  • trunk/Source/WebCore/dom/PseudoElement.h

    r145057 r147756  
    4747    virtual bool rendererIsNeeded(const NodeRenderingContext&) OVERRIDE;
    4848
     49    // As per http://dev.w3.org/csswg/css3-regions/#flow-into, pseudo-elements such as ::first-line, ::first-letter, ::before or ::after
     50    // cannot be directly collected into a named flow.
     51    virtual bool moveToFlowThreadIsNeeded(RefPtr<RenderStyle>& cachedStyle) OVERRIDE
     52    {
     53        UNUSED_PARAM(cachedStyle);
     54        return false;
     55    }
     56
    4957    virtual bool canStartSelection() const OVERRIDE { return false; }
    5058    virtual bool canContainRangeEndPoint() const OVERRIDE { return false; }
  • trunk/Source/WebCore/dom/Text.cpp

    r142271 r147756  
    198198}
    199199
    200 bool Text::textRendererIsNeeded(const NodeRenderingContext& context)
     200bool Text::textRendererIsNeeded(NodeRenderingContext& context)
    201201{
    202202    if (isEditingText())
     
    303303        return;
    304304    RenderText* textRenderer = toRenderText(renderer());
    305     if (!textRenderer || !textRendererIsNeeded(NodeRenderingContext(this, textRenderer->style()))) {
     305    if (!textRenderer) {
     306        reattach();
     307        return;
     308    }
     309    NodeRenderingContext renderingContext(this, textRenderer->style());
     310    if (!textRendererIsNeeded(renderingContext)) {
    306311        reattach();
    307312        return;
  • trunk/Source/WebCore/dom/Text.h

    r141516 r147756  
    4747    void recalcTextStyle(StyleChange);
    4848    void createTextRendererIfNeeded();
    49     bool textRendererIsNeeded(const NodeRenderingContext&);
     49    bool textRendererIsNeeded(NodeRenderingContext&);
    5050    RenderText* createTextRenderer(RenderArena*, RenderStyle*);
    5151    void updateTextRenderer(unsigned offsetOfReplacedData, unsigned lengthOfReplacedData);
  • trunk/Source/WebCore/rendering/FlowThreadController.cpp

    r147426 r147756  
    228228}
    229229
     230bool FlowThreadController::isContentNodeRegisteredWithAnyNamedFlow(Node* contentNode) const
     231{
     232    return m_mapNamedFlowContentNodes.contains(contentNode);
     233}
     234
    230235#ifndef NDEBUG
    231236bool FlowThreadController::isAutoLogicalHeightRegionsCountConsistent() const
  • trunk/Source/WebCore/rendering/FlowThreadController.h

    r147426 r147756  
    6767    void registerNamedFlowContentNode(Node*, RenderNamedFlowThread*);
    6868    void unregisterNamedFlowContentNode(Node*);
     69    bool isContentNodeRegisteredWithAnyNamedFlow(Node*) const;
    6970
    7071    bool hasFlowThreadsWithAutoLogicalHeightRegions() const { return m_flowThreadsWithAutoLogicalHeightRegions; }
  • trunk/Source/WebCore/rendering/RenderObject.h

    r147495 r147756  
    258258    //////////////////////////////////////////
    259259    virtual bool canHaveChildren() const { return virtualChildren(); }
     260    virtual bool canDOMChildrenHaveRenderParent() const { return false; } // Even if this render object can't have render children, the children in the DOM tree may have a render parent (that is different from this object).
    260261    virtual bool canHaveGeneratedChildren() const;
    261262    virtual bool isChildAllowed(RenderObject*, RenderStyle*) const { return true; }
  • trunk/Source/WebCore/rendering/RenderRegion.h

    r146748 r147756  
    146146
    147147    virtual bool canHaveChildren() const OVERRIDE { return false; }
     148    virtual bool canDOMChildrenHaveRenderParent() const OVERRIDE { return true; }
    148149
    149150    virtual void insertedIntoTree() OVERRIDE;
  • trunk/Source/WebCore/svg/SVGElement.cpp

    r147558 r147756  
    451451
    452452    return false;
     453}
     454
     455bool SVGElement::moveToFlowThreadIsNeeded(RefPtr<RenderStyle>& cachedStyle)
     456{
     457    // Allow only svg root elements to be directly collected by a render flow thread.
     458    return parentNode() && !parentNode()->isSVGElement() && hasTagName(SVGNames::svgTag) && Element::moveToFlowThreadIsNeeded(cachedStyle);
    453459}
    454460
  • trunk/Source/WebCore/svg/SVGElement.h

    r147558 r147756  
    121121    virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture) OVERRIDE;
    122122
     123    virtual bool moveToFlowThreadIsNeeded(RefPtr<RenderStyle>& cachedStyle) OVERRIDE;
     124
    123125protected:
    124126    SVGElement(const QualifiedName&, Document*, ConstructionType = CreateSVGElement);
Note: See TracChangeset for help on using the changeset viewer.