Changeset 116694 in webkit


Ignore:
Timestamp:
May 10, 2012 3:11:57 PM (12 years ago)
Author:
eric@webkit.org
Message:

Make IFRAME_SEAMLESS child documents inherit styles from their parent iframe element
https://bugs.webkit.org/show_bug.cgi?id=85940

Reviewed by Ojan Vafai.

Source/WebCore:

The HTML5 <iframe seamless> spec says:
In a CSS-supporting user agent: the user agent must, for the purpose of CSS property
inheritance only, treat the root element of the active document of the iframe
element's nested browsing context as being a child of the iframe element.
(Thus inherited properties on the root element of the document in the
iframe will inherit the computed values of those properties on the iframe
element instead of taking their initial values.)

Initially I implemented this support to the letter of the spec. However, doing so I learned
that WebKit has a RenderStyle for the Document Node, not just the root element of the document.
In this RenderStyle on the Document, we add a bunch of per-document styles from settings
including designMode.

This change makes StyleResolver::styleForDocument inherit style from the parent iframe's
style, before applying any of these per-document styles. This may or may not be correct
depending on what behavior we want for rtl-ordering, page-zoom, locale, design mode, etc.
For now, we continue to treat the iframe's document as independent in these regards, and
the settings on that document override those inherited from the iframe.

Also, intially when making this work, I added redirects in recalcStyle and scheduleStyleRecalc
from the child document to the parent document in the case of seamless (since the parent
document effectively manages the style resolve and layout of the child in seamless mode).
However, I was not able to find a test which depended on this code change, so in this final patch
I have removed both of these modifications and replaced them with FIXMEs. Based on discussions
with Ojan and James Robinson, I believe both of those changes may eventually be wanted.

This change basically does 3 things:

  1. Makes StyleResolver::styleForDocument inherit from the parent iframe.
  2. Makes any recalcStyle calls on the iframe propogate down into the child document (HTMLIFrameElement::didRecalcStyle).
  3. Makes Document::recalcStyle aware of the fact that the Document's style *can* change

for reasons other than recalcStyle(Force).

I'm open to more testing suggestions, if reviewers have settings on the Document's style
that you want to make sure we inherit from the parent iframe, or don't inherit, etc.
I view this as a complete solution to this aspect of the current <iframe seamless> spec,
but likely not the last code we will write for this aspect of the seamless feature. :)

Tested by fast/frames/seamlesss/seamless-css-cascade.html and seamless-designMode.html

  • css/StyleResolver.cpp:

(WebCore::StyleResolver::collectMatchingRulesForList):

  • dom/Document.cpp:

(WebCore::Document::scheduleStyleRecalc):
(WebCore::Document::recalcStyle):

  • html/HTMLIFrameElement.cpp:

(WebCore::HTMLIFrameElement::HTMLIFrameElement):
(WebCore::HTMLIFrameElement::didRecalcStyle):
(WebCore):

  • html/HTMLIFrameElement.h:

(HTMLIFrameElement):

LayoutTests:

This single pass is deceptive. seamless-designMode exists
to make sure that we do not regress application of Document-level
styles in the child document.

  • fast/frames/seamless/seamless-css-cascade-expected.txt:
Location:
trunk
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r116693 r116694  
     12012-05-10  Eric Seidel  <eric@webkit.org>
     2
     3        Make IFRAME_SEAMLESS child documents inherit styles from their parent iframe element
     4        https://bugs.webkit.org/show_bug.cgi?id=85940
     5
     6        Reviewed by Ojan Vafai.
     7
     8        This single pass is deceptive.  seamless-designMode exists
     9        to make sure that we do not regress application of Document-level
     10        styles in the child document.
     11
     12        * fast/frames/seamless/seamless-css-cascade-expected.txt:
     13
    1142012-05-10  Julien Chaffraix  <jchaffraix@webkit.org>
    215
  • trunk/LayoutTests/fast/frames/seamless/seamless-css-cascade-expected.txt

    r116471 r116694  
    33PASS window.getComputedStyle(two).color is "rgb(128, 0, 128)"
    44PASS window.getComputedStyle(three).color is "rgb(255, 255, 255)"
    5 FAIL window.getComputedStyle(rootElement).color should be rgb(255, 165, 0). Was rgb(0, 0, 0).
    6 FAIL window.getComputedStyle(rootElement).color should be rgb(1, 2, 3). Was rgb(0, 0, 0).
     5PASS window.getComputedStyle(rootElement).color is "rgb(255, 165, 0)"
     6PASS window.getComputedStyle(rootElement).color is "rgb(1, 2, 3)"
    77PASS window.getComputedStyle(one).color is "rgb(3, 2, 1)"
    88
  • trunk/Source/WebCore/ChangeLog

    r116693 r116694  
     12012-05-10  Eric Seidel  <eric@webkit.org>
     2
     3        Make IFRAME_SEAMLESS child documents inherit styles from their parent iframe element
     4        https://bugs.webkit.org/show_bug.cgi?id=85940
     5
     6        Reviewed by Ojan Vafai.
     7
     8        The HTML5 <iframe seamless> spec says:
     9        In a CSS-supporting user agent: the user agent must, for the purpose of CSS property
     10        inheritance only, treat the root element of the active document of the iframe
     11        element's nested browsing context as being a child of the iframe element.
     12        (Thus inherited properties on the root element of the document in the
     13        iframe will inherit the computed values of those properties on the iframe
     14        element instead of taking their initial values.)
     15
     16        Initially I implemented this support to the letter of the spec. However, doing so I learned
     17        that WebKit has a RenderStyle for the Document Node, not just the root element of the document.
     18        In this RenderStyle on the Document, we add a bunch of per-document styles from settings
     19        including designMode.
     20
     21        This change makes StyleResolver::styleForDocument inherit style from the parent iframe's
     22        style, before applying any of these per-document styles.  This may or may not be correct
     23        depending on what behavior we want for rtl-ordering, page-zoom, locale, design mode, etc.
     24        For now, we continue to treat the iframe's document as independent in these regards, and
     25        the settings on that document override those inherited from the iframe.
     26
     27        Also, intially when making this work, I added redirects in recalcStyle and scheduleStyleRecalc
     28        from the child document to the parent document in the case of seamless (since the parent
     29        document effectively manages the style resolve and layout of the child in seamless mode).
     30        However, I was not able to find a test which depended on this code change, so in this final patch
     31        I have removed both of these modifications and replaced them with FIXMEs.  Based on discussions
     32        with Ojan and James Robinson, I believe both of those changes may eventually be wanted.
     33
     34        This change basically does 3 things:
     35        1.  Makes StyleResolver::styleForDocument inherit from the parent iframe.
     36        2.  Makes any recalcStyle calls on the iframe propogate down into the child document (HTMLIFrameElement::didRecalcStyle).
     37        3.  Makes Document::recalcStyle aware of the fact that the Document's style *can* change
     38            for reasons other than recalcStyle(Force).
     39
     40        I'm open to more testing suggestions, if reviewers have settings on the Document's style
     41        that you want to make sure we inherit from the parent iframe, or don't inherit, etc.
     42        I view this as a complete solution to this aspect of the current <iframe seamless> spec,
     43        but likely not the last code we will write for this aspect of the seamless feature. :)
     44
     45        Tested by fast/frames/seamlesss/seamless-css-cascade.html and seamless-designMode.html
     46
     47        * css/StyleResolver.cpp:
     48        (WebCore::StyleResolver::collectMatchingRulesForList):
     49        * dom/Document.cpp:
     50        (WebCore::Document::scheduleStyleRecalc):
     51        (WebCore::Document::recalcStyle):
     52        * html/HTMLIFrameElement.cpp:
     53        (WebCore::HTMLIFrameElement::HTMLIFrameElement):
     54        (WebCore::HTMLIFrameElement::didRecalcStyle):
     55        (WebCore):
     56        * html/HTMLIFrameElement.h:
     57        (HTMLIFrameElement):
     58
    1592012-05-10  Julien Chaffraix  <jchaffraix@webkit.org>
    260
  • trunk/Source/WebCore/css/StyleResolver.cpp

    r116521 r116694  
    15281528    Frame* frame = document->frame();
    15291529
     1530    // HTML5 states that seamless iframes should replace default CSS values
     1531    // with values inherited from the containing iframe element. However,
     1532    // some values (such as the case of designMode = "on") still need to
     1533    // be set by this "document style".
    15301534    RefPtr<RenderStyle> documentStyle = RenderStyle::create();
     1535    bool seamlessWithParent = document->shouldDisplaySeamlesslyWithParent();
     1536    if (seamlessWithParent) {
     1537        RenderStyle* iframeStyle = document->seamlessParentIFrame()->renderStyle();
     1538        if (iframeStyle)
     1539            documentStyle->inheritFrom(iframeStyle);
     1540    }
     1541
     1542    // FIXME: It's not clear which values below we want to override in the seamless case!
    15311543    documentStyle->setDisplay(BLOCK);
    1532     documentStyle->setRTLOrdering(document->visuallyOrdered() ? VisualOrder : LogicalOrder);
    1533     documentStyle->setZoom(frame && !document->printing() ? frame->pageZoomFactor() : 1);
    1534     documentStyle->setPageScaleTransform(frame ? frame->frameScaleFactor() : 1);
     1544    if (!seamlessWithParent) {
     1545        documentStyle->setRTLOrdering(document->visuallyOrdered() ? VisualOrder : LogicalOrder);
     1546        documentStyle->setZoom(frame && !document->printing() ? frame->pageZoomFactor() : 1);
     1547        documentStyle->setPageScaleTransform(frame ? frame->frameScaleFactor() : 1);
     1548        documentStyle->setLocale(document->contentLanguage());
     1549    }
     1550    // FIXME: This overrides any -webkit-user-modify inherited from the parent iframe.
    15351551    documentStyle->setUserModify(document->inDesignMode() ? READ_WRITE : READ_ONLY);
    1536     documentStyle->setLocale(document->contentLanguage());
    15371552
    15381553    Element* docElement = document->documentElement();
     
    15621577        }
    15631578    }
     1579
     1580    // Seamless iframes want to inherit their font from their parent iframe, so early return before setting the font.
     1581    if (seamlessWithParent)
     1582        return documentStyle.release();
    15641583
    15651584    FontDescription fontDescription;
  • trunk/Source/WebCore/dom/Document.cpp

    r116644 r116694  
    16521652void Document::scheduleStyleRecalc()
    16531653{
     1654    // FIXME: In the seamless case, we should likely schedule a style recalc
     1655    // on our parent and instead return early here.
     1656
    16541657    if (m_styleRecalcTimer.isActive() || inPageCache())
    16551658        return;
     
    17051708    if (m_inStyleRecalc)
    17061709        return; // Guard against re-entrancy. -dwh
    1707    
     1710
     1711    // FIXME: In the seamless case, we may wish to exit early in the child after recalcing our parent chain.
     1712    // I have not yet found a test which requires such.
     1713
    17081714    if (m_hasDirtyStyleResolver)
    17091715        updateActiveStylesheets(RecalcStyleImmediately);
     
    17311737        change = Force;
    17321738
    1733     if (change == Force) {
     1739    // Recalculating the root style (on the document) is not needed in the common case.
     1740    if ((change == Force) || (shouldDisplaySeamlesslyWithParent() && (change >= Inherit))) {
    17341741        // style selector may set this again during recalc
    17351742        m_hasNodesWithPlaceholderStyle = false;
  • trunk/Source/WebCore/html/HTMLIFrameElement.cpp

    r115773 r116694  
    4242{
    4343    ASSERT(hasTagName(iframeTag));
     44    setHasCustomWillOrDidRecalcStyle();
    4445}
    4546
     
    121122}
    122123
     124void HTMLIFrameElement::didRecalcStyle(StyleChange styleChange)
     125{
     126    if (!shouldDisplaySeamlessly())
     127        return;
     128    Document* childDocument = contentDocument();
     129    if (styleChange >= Inherit || childDocument->childNeedsStyleRecalc() || childDocument->needsStyleRecalc())
     130        contentDocument()->recalcStyle(styleChange);
     131}
     132
    123133#if ENABLE(MICRODATA)
    124134String HTMLIFrameElement::itemValueText() const
  • trunk/Source/WebCore/html/HTMLIFrameElement.h

    r115773 r116694  
    4444    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
    4545    virtual void removedFrom(Node*) OVERRIDE;
    46    
     46
    4747    virtual bool rendererIsNeeded(const NodeRenderingContext&);
    4848    virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
    49        
     49
     50    virtual void didRecalcStyle(StyleChange) OVERRIDE;
     51
    5052#if ENABLE(MICRODATA)
    5153    virtual String itemValueText() const OVERRIDE;
Note: See TracChangeset for help on using the changeset viewer.