Changeset 171341 in webkit


Ignore:
Timestamp:
Jul 22, 2014 6:27:38 AM (10 years ago)
Author:
krit@webkit.org
Message:

Turn width/height to presentation attributes
https://bugs.webkit.org/show_bug.cgi?id=135046

Patch by Dirk Schulze <krit@webkit.org> on 2014-07-18
Reviewed by Dean Jackson.

Source/WebCore:
The elements <svg>, <image>, <pattern>, <mask> and <foreignObject> have the
'width' and 'height' attributes. So far they can just be set by SVG DOM or
setAttribute. Furthermore, animations just work with SVG Animation - No support
for CSS Animations and CSS Transitions. We started to turn the width and height
attributes on SVG roots to presentation attributes already. A presentation
attribute is a CSS property that can also be set by DOM (or now by SVG DOM).

This patch turns all width and height attributes to presentation attributes. It
basically allows authors to style width and height with CSS as well. Width and
height can now be set with CSS style sheets and can be animated with CSS.

To some degree it made it possible to remove code duplication. However, since
SVG DOM requires us to use SVGLength types and since we did not turn all
SVG attributes to the CSS length values (and our internal Length struct) yet,
we still need a hybrid - a bridge between SVGLength (for SVG DOM) and Length (for
RenderStyle). Once we move all attributes to use the Length struct, we can make SVGLength
a wrapper for Length and can move more code to the render tree.

The current challenge is to synchronize SVG DOM, normal DOM and RenderStyle.
With this patch we handle most part in RenderStyle. SVG DOM changes are
synchronized to DOM and RenderStyle will call needsStyleRecalc. Furthermore,
SVG Animations will continue to animate the SVG DOM (and synchronize the changes
back to RenderStyle) if the element has a JS property for the currently animated
attribute.

Short example:

<rect>

<animate attributeName="width">

</rect>

The <rect> element has the SVG DOM property 'width'. Therefore, we animate the SVG DOM
property and synchronize RenderStyle.

<ellipse>

<animate attributeName="width">

</ellipse>

The <ellipse> element does NOT have the SVG DOM property 'width'. Therefore, we
animate the CSS property directly. With synchronizing RenderStyle in all cases, we
make sure that the CSS cascade works even on animating on multiple SVG hierarchy
levels (animation of 'width' on <g> and inheriting the property value on a child
<rect>).

With using presentation attributes, we also inherit the CSS property parsing for
SVG attributes. <rect width=" 100px "> is possible now. (Note the trailing whitespaces.)
This follows a recent resolution of the SVG WG.

Since we turned width and height to presentation attributes, the layout optimization
selfHasRelativeLengths() in the DOM can't be used anymore. selfHasRelativeLengths() was
intended to solve a problem where we did not layout relatively position/sized elements
when the parent changes its size. However, as a side effect it did not call layout
for absolutely positioned/sized elements since the layout does not change. I run
all performance tests that we have and even wrote a test with hundreds of elements
that would be affected by this optimization. The differences were inside the sigma
of a normal test run. (Means I couldn't measure a performance difference.)
Therefore, it is not worth it to keep the "optimization" around and I will probably
remove it entirely for all basic shapes but <path> and <polygon> in future patches.

Tests: svg/css/parse-height.html

svg/css/parse-width.html
svg/css/width-height-presentation-attribute-expected.svg
svg/css/width-height-presentation-attribute.svg

  • css/CSSComputedStyleDeclaration.cpp:

(WebCore::ComputedStyleExtractor::propertyValue): We never calculated the computed

value of width/height for SVG elements and returned auto instead. This is based
on a rule of CSS 2 and needs to be fixed in CSS3.

  • css/DeprecatedStyleBuilder.cpp:

(WebCore::ApplyPropertyLength::applyValue): Length always incorporates the zoom level.

In SVG we still apply the zoom after all operations by scaling the context. We need
to take this in account for Length and don't apply zoom on SVG inline elements.

  • css/StyleResolver.cpp:

(WebCore::StyleResolver::useSVGZoomRulesForLength):

See above.

  • css/StyleResolver.h:
  • rendering/svg/RenderSVGRect.cpp:

(WebCore::RenderSVGRect::updateShapeFromElement): Do not call width() and height() on

SVG DOM but use the values of RenderStyle instead.

  • rendering/svg/SVGPathData.cpp:

(WebCore::updatePathFromRectElement): Ditto.

  • svg/SVGAnimateElement.cpp:

(WebCore::SVGAnimateElement::resetAnimatedType): We need to differ between CSS properties

with and without SVG DOM on the current element. In the later case we animate the
SVG DOM and need to synch RenderStyle.

(WebCore::SVGAnimateElement::clearAnimatedType): Ditto.
(WebCore::SVGAnimateElement::applyResultsToTarget): Ditto.

  • svg/SVGAnimationElement.cpp:

(WebCore::SVGAnimationElement::isTargetAttributeCSSProperty): This checks if the CSS property

has to be synched with SVG DOM.

(WebCore::SVGAnimationElement::shouldApplyAnimation): Ditto.

  • svg/SVGAnimationElement.h:
  • svg/SVGElement.cpp:

(WebCore::populateAttributeNameToCSSPropertyIDMap): Add width and heigth to the CSS property

list for presentation attributes.

(WebCore::populateCSSPropertyWithSVGDOMNameToAnimatedPropertyTypeMap): CSS properties with

SVG DOM synchronization need to be treated differently. Collect them in a separate map.

(WebCore::cssPropertyWithSVGDOMNameToAnimatedPropertyTypeMap): Caller for the map.
(WebCore::SVGElement::animatedPropertyTypeForAttribute): We need to check both maps here:

CSS properties and CSS properties with SVG DOM synch.

(WebCore::SVGElement::isAnimatableCSSProperty): Ditto.
(WebCore::SVGElement::isPresentationAttributeWithSVGDOM): Just return true if the property name

is in the map of properties with SVG DOM for the current element.

  • svg/SVGElement.h:

(WebCore::SVGElement::invalidateSVGPresentationAttributeStyle): Call needsStyleRecalc.

  • svg/SVGFilterElement.cpp: Make width/height presentation attribute.

(WebCore::SVGFilterElement::svgAttributeChanged):
(WebCore::SVGFilterElement::selfHasRelativeLengths): Deleted.

  • svg/SVGFilterElement.h: Ditto.
  • svg/SVGForeignObjectElement.cpp:

(WebCore::SVGForeignObjectElement::svgAttributeChanged):
(WebCore::SVGForeignObjectElement::selfHasRelativeLengths): Deleted.

  • svg/SVGForeignObjectElement.h:
  • svg/SVGImageElement.cpp: Ditto.

(WebCore::SVGImageElement::svgAttributeChanged):
(WebCore::SVGImageElement::isPresentationAttribute): Deleted.
(WebCore::SVGImageElement::collectStyleForPresentationAttribute): Deleted.
(WebCore::SVGImageElement::selfHasRelativeLengths): Deleted.

  • svg/SVGImageElement.h:
  • svg/SVGLength.h: Transform an Length value to an absolute value by taking the SVG viewport

into account. (An SVG viewport is not the same as the CSS viewport.)

  • svg/SVGLengthContext.cpp: Ditto.

(WebCore::SVGLengthContext::valueForLength):

  • svg/SVGLengthContext.h:
  • svg/SVGMaskElement.cpp: Make width/height presentation attribute.

(WebCore::SVGMaskElement::svgAttributeChanged):
(WebCore::SVGMaskElement::selfHasRelativeLengths): Deleted.

  • svg/SVGMaskElement.h:
  • svg/SVGPatternElement.cpp: Ditto.

(WebCore::SVGPatternElement::svgAttributeChanged):
(WebCore::SVGPatternElement::selfHasRelativeLengths): Deleted.

  • svg/SVGPatternElement.h:
  • svg/SVGRectElement.cpp: Ditto.

(WebCore::SVGRectElement::svgAttributeChanged):
(WebCore::SVGRectElement::selfHasRelativeLengths): Deleted.

  • svg/SVGRectElement.h:
  • svg/SVGSVGElement.cpp: Ditto.

(WebCore::SVGSVGElement::svgAttributeChanged): Clean up redundant layout calls.
(WebCore::SVGSVGElement::isPresentationAttribute): Deleted.
(WebCore::SVGSVGElement::collectStyleForPresentationAttribute): Deleted.

  • svg/SVGSVGElement.h:
  • svg/properties/SVGAnimatedProperty.cpp: Synchronize SVG DOM with DOM.

(WebCore::SVGAnimatedProperty::commitChange):

LayoutTests:
We already had a lot of tests for animating width/height as property.
So far they assumed that this is not possible. They simply needed to
be updated.

Furthermore, I added reference tests to test different inheritance
scenarios of CSS properties and setting them to elements.

A parsing test makes sure that the global property values inherit is
supported as well as CSS parsing rules for SVG attributes.
Negative tests test not-allowed behavior.

  • platform/mac/svg/W3C-SVG-1.1/coords-units-03-b-expected.txt:
  • svg/animations/attributeTypes-expected.txt:
  • svg/animations/resources/attributeTypes.svg:
  • svg/animations/script-tests/attributeTypes.js:

(sample1):
(sample2):
(sample3):

  • svg/css/getComputedStyle-basic-expected.txt:
  • svg/css/parse-height-expected.txt: Added.
  • svg/css/parse-height.html: Added.
  • svg/css/parse-width-expected.txt: Added.
  • svg/css/parse-width.html: Added.
  • svg/css/width-height-presentation-attribute-expected.svg: Added.
  • svg/css/width-height-presentation-attribute.svg: Added.
  • svg/custom/mask-excessive-malloc-expected.txt:
  • svg/hixie/error/015-expected.txt:
Location:
trunk
Files:
6 added
39 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r171323 r171341  
     12014-07-18  Dirk Schulze  <krit@webkit.org>
     2
     3        Turn width/height to presentation attributes
     4        https://bugs.webkit.org/show_bug.cgi?id=135046
     5
     6        Reviewed by Dean Jackson.
     7
     8        We already had a lot of tests for animating width/height as property.
     9        So far they assumed that this is not possible. They simply needed to
     10        be updated.
     11
     12        Furthermore, I added reference tests to test different inheritance
     13        scenarios of CSS properties and setting them to elements.
     14
     15        A parsing test makes sure that the global property values inherit is
     16        supported as well as CSS parsing rules for SVG attributes.
     17        Negative tests test not-allowed behavior.
     18
     19        * platform/mac/svg/W3C-SVG-1.1/coords-units-03-b-expected.txt:
     20        * svg/animations/attributeTypes-expected.txt:
     21        * svg/animations/resources/attributeTypes.svg:
     22        * svg/animations/script-tests/attributeTypes.js:
     23        (sample1):
     24        (sample2):
     25        (sample3):
     26        * svg/css/getComputedStyle-basic-expected.txt:
     27        * svg/css/parse-height-expected.txt: Added.
     28        * svg/css/parse-height.html: Added.
     29        * svg/css/parse-width-expected.txt: Added.
     30        * svg/css/parse-width.html: Added.
     31        * svg/css/width-height-presentation-attribute-expected.svg: Added.
     32        * svg/css/width-height-presentation-attribute.svg: Added.
     33        * svg/custom/mask-excessive-malloc-expected.txt:
     34        * svg/hixie/error/015-expected.txt:
     35
    1362014-07-21  Diego Pino Garcia  <dpino@igalia.com>
    237
  • trunk/LayoutTests/platform/mac/svg/W3C-SVG-1.1/coords-units-03-b-expected.txt

    r161884 r171341  
    3939          RenderSVGInlineText {#text} at (0,0) size 158x15
    4040            chunk 1 text run 1 at (230.00,80.00) startOffset 0 endOffset 30 width 158.00: "Relative to font x-height (ex)"
    41         RenderSVGContainer {g} at (20,140) size 200x1
    42           RenderSVGRect {rect} at (20,140) size 200x1 [fill={[type=SOLID] [color=#000000]}] [x=20.00] [y=80.00] [width=200.00] [height=1.00]
     41        RenderSVGContainer {g} at (20,140) size 180x1
     42          RenderSVGRect {rect} at (20,140) size 180x1 [fill={[type=SOLID] [color=#000000]}] [x=20.00] [y=80.00] [width=200.00] [height=1.00]
    4343        RenderSVGText {text} at (20,86) size 93x16 contains 1 chunk(s)
    4444          RenderSVGInlineText {#text} at (0,0) size 93x15
  • trunk/LayoutTests/platform/mac/svg/zoom/page/zoom-foreignObject-expected.txt

    r168350 r171341  
    1717    RenderSVGRect {rect} at (0,0) size 361x289 [stroke={[type=SOLID] [color=#008000]}] [x=0.00] [y=0.00] [width=250.00] [height=200.00]
    1818    RenderSVGForeignObject {foreignObject} at (260,0) size 250x200
    19       RenderSVGRoot {svg} at (260,5) size 250x145
    20         RenderSVGContainer {g} at (260,5) size 250x145 [transform={m=((3.00,0.26)(0.26,3.02)) t=(0.00,0.00)}]
     19      RenderSVGRoot {svg} at (260,5) size 250x195
     20        RenderSVGContainer {g} at (260,5) size 250x195 [transform={m=((3.00,0.26)(0.26,3.02)) t=(0.00,0.00)}]
    2121          RenderSVGText {text} at (0,1) size 82x19 contains 1 chunk(s)
    2222            RenderSVGInlineText {#text} at (0,0) size 82x19
  • trunk/LayoutTests/svg/animations/attributeTypes-expected.txt

    r110574 r171341  
    1212PASS color.green.getFloatValue(CSSPrimitiveValue.CSS_NUMBER) is 128
    1313PASS color.blue.getFloatValue(CSSPrimitiveValue.CSS_NUMBER) is 0
    14 PASS rect2.width.animVal.value is 100
    15 PASS rect2.width.baseVal.value is 100
     14PASS rect2.width.animVal.value is 10
     15PASS rect2.width.baseVal.value is 10
    1616PASS color.red.getFloatValue(CSSPrimitiveValue.CSS_NUMBER) is 0
    1717PASS color.green.getFloatValue(CSSPrimitiveValue.CSS_NUMBER) is 128
     
    3434PASS color.green.getFloatValue(CSSPrimitiveValue.CSS_NUMBER) is 128
    3535PASS color.blue.getFloatValue(CSSPrimitiveValue.CSS_NUMBER) is 0
    36 PASS rect2.width.animVal.value is 100
    37 PASS rect2.width.baseVal.value is 100
     36PASS rect2.width.animVal.value is 55
     37PASS rect2.width.baseVal.value is 10
    3838PASS color.red.getFloatValue(CSSPrimitiveValue.CSS_NUMBER) is 0
    3939PASS color.green.getFloatValue(CSSPrimitiveValue.CSS_NUMBER) is 128
     
    5757PASS color.blue.getFloatValue(CSSPrimitiveValue.CSS_NUMBER) is 0
    5858PASS rect2.width.animVal.value is 100
    59 PASS rect2.width.baseVal.value is 100
     59PASS rect2.width.baseVal.value is 10
    6060PASS color.red.getFloatValue(CSSPrimitiveValue.CSS_NUMBER) is 0
    6161PASS color.green.getFloatValue(CSSPrimitiveValue.CSS_NUMBER) is 128
     
    7979PASS color.blue.getFloatValue(CSSPrimitiveValue.CSS_NUMBER) is 0
    8080PASS rect2.width.animVal.value is 100
    81 PASS rect2.width.baseVal.value is 100
     81PASS rect2.width.baseVal.value is 10
    8282PASS color.red.getFloatValue(CSSPrimitiveValue.CSS_NUMBER) is 0
    8383PASS color.green.getFloatValue(CSSPrimitiveValue.CSS_NUMBER) is 128
  • trunk/LayoutTests/svg/animations/resources/attributeTypes.svg

    r109679 r171341  
    99
    1010<!-- 'width' is a XML attribute, attributeType is set to "CSS". 'width' is not a presentation attribute, so this animation won't run. -->
    11 <rect x="150" width="100" height="100" fill="green">
    12     <animate id="an2" attributeType="CSS" attributeName="width" fill="freeze" from="100" to="10" begin="0s" dur="4s"/>
     11<rect x="150" width="10" height="100" fill="green">
     12    <animate id="an2" attributeType="CSS" attributeName="width" fill="freeze" from="10" to="100" begin="0s" dur="4s"/>
    1313</rect>
    1414
  • trunk/LayoutTests/svg/animations/script-tests/attributeTypes.js

    r110574 r171341  
    88    expectFillColor(rect1, 0, 128, 0);
    99
    10     shouldBe("rect2.width.animVal.value", "100");
    11     shouldBe("rect2.width.baseVal.value", "100");
     10    shouldBeCloseEnough("rect2.width.animVal.value", "10");
     11    shouldBe("rect2.width.baseVal.value", "10");
    1212    expectFillColor(rect2, 0, 128, 0);
    1313
     
    2828    expectFillColor(rect1, 0, 128, 0);
    2929
    30     shouldBe("rect2.width.animVal.value", "100");
    31     shouldBe("rect2.width.baseVal.value", "100");
     30    shouldBeCloseEnough("rect2.width.animVal.value", "55");
     31    shouldBe("rect2.width.baseVal.value", "10");
    3232    expectFillColor(rect2, 0, 128, 0);
    3333
     
    4848    expectFillColor(rect1, 0, 128, 0);
    4949
    50     shouldBe("rect2.width.animVal.value", "100");
    51     shouldBe("rect2.width.baseVal.value", "100");
     50    shouldBeCloseEnough("rect2.width.animVal.value", "100");
     51    shouldBe("rect2.width.baseVal.value", "10");
    5252    expectFillColor(rect2, 0, 128, 0);
    5353
  • trunk/LayoutTests/svg/css/getComputedStyle-basic-expected.txt

    r170996 r171341  
    9191rect: style.getPropertyValue(font-weight) : normal
    9292rect: style.getPropertyCSSValue(font-weight) : [object CSSPrimitiveValue]
    93 rect: style.getPropertyValue(height) : auto
     93rect: style.getPropertyValue(height) : 100px
    9494rect: style.getPropertyCSSValue(height) : [object CSSPrimitiveValue]
    9595rect: style.getPropertyValue(image-rendering) : auto
     
    191191rect: style.getPropertyValue(widows) : auto
    192192rect: style.getPropertyCSSValue(widows) : [object CSSPrimitiveValue]
    193 rect: style.getPropertyValue(width) : auto
     193rect: style.getPropertyValue(width) : 100px
    194194rect: style.getPropertyCSSValue(width) : [object CSSPrimitiveValue]
    195195rect: style.getPropertyValue(word-break) : normal
  • trunk/LayoutTests/svg/custom/mask-excessive-malloc-expected.txt

    r149088 r171341  
    66      RenderSVGRect {rect} at (0,0) size 800x600 [fill={[type=SOLID] [color=#FFFFFF]}] [x=0.00] [y=0.00] [width=2147483648.00] [height=2147483648.00]
    77    RenderSVGPath {path} at (200,200) size 100x200 [fill={[type=SOLID] [color=#0000FF]}] [data="M 200 200 L 300 200 L 300 400 L 200 400 Z"]
    8       [masker="mask"] RenderSVGResourceMasker {mask} at (190,180) size 2147483520x2147483520
     8      [masker="mask"] RenderSVGResourceMasker {mask} at (190,180) size 33554238x33554248
  • trunk/LayoutTests/svg/hixie/error/015-expected.txt

    r149088 r171341  
    55  RenderSVGRoot {svg} at (0,0) size 300x200
    66    RenderSVGRect {rect} at (0,0) size 300x200 [fill={[type=SOLID] [color=#008000]}] [x=0.00] [y=0.00] [width=300.00] [height=200.00]
    7     RenderSVGRect {rect} at (0,0) size 0x0 [fill={[type=SOLID] [color=#FF0000]}] [x=0.00] [y=0.00] [width=0.00] [height=200.00]
     7    RenderSVGRect {rect} at (0,0) size 300x200 [fill={[type=SOLID] [color=#FF0000]}] [x=0.00] [y=0.00] [width=0.00] [height=200.00]
  • trunk/Source/WebCore/ChangeLog

    r171339 r171341  
     12014-07-18  Dirk Schulze  <krit@webkit.org>
     2
     3        Turn width/height to presentation attributes
     4        https://bugs.webkit.org/show_bug.cgi?id=135046
     5
     6        Reviewed by Dean Jackson.
     7
     8        The elements <svg>, <image>, <pattern>, <mask> and <foreignObject> have the
     9        'width' and 'height' attributes. So far they can just be set by SVG DOM or
     10        setAttribute. Furthermore, animations just work with SVG Animation - No support
     11        for CSS Animations and CSS Transitions. We started to turn the width and height
     12        attributes on SVG roots to presentation attributes already. A presentation
     13        attribute is a CSS property that can also be set by DOM (or now by SVG DOM).
     14
     15        This patch turns all width and height attributes to presentation attributes. It
     16        basically allows authors to style width and height with CSS as well. Width and
     17        height can now be set with CSS style sheets and can be animated with CSS.
     18
     19        To some degree it made it possible to remove code duplication. However, since
     20        SVG DOM requires us to use SVGLength types and since we did not turn all
     21        SVG attributes to the CSS length values (and our internal Length struct) yet,
     22        we still need a hybrid - a bridge between SVGLength (for SVG DOM) and Length (for
     23        RenderStyle). Once we move all attributes to use the Length struct, we can make SVGLength
     24        a wrapper for Length and can move more code to the render tree.
     25
     26        The current challenge is to synchronize SVG DOM, normal DOM and RenderStyle.
     27        With this patch we handle most part in RenderStyle. SVG DOM changes are
     28        synchronized to DOM and RenderStyle will call needsStyleRecalc. Furthermore,
     29        SVG Animations will continue to animate the SVG DOM (and synchronize the changes
     30        back to RenderStyle) if the element has a JS property for the currently animated
     31        attribute.
     32
     33        Short example:
     34
     35            <rect>
     36                <animate attributeName="width">
     37            </rect>
     38
     39        The <rect> element has the SVG DOM property 'width'. Therefore, we animate the SVG DOM
     40        property and synchronize RenderStyle.
     41
     42            <ellipse>
     43                <animate attributeName="width">
     44            </ellipse>
     45
     46        The <ellipse> element does NOT have the SVG DOM property 'width'. Therefore, we
     47        animate the CSS property directly. With synchronizing RenderStyle in all cases, we
     48        make sure that the CSS cascade works even on animating on multiple SVG hierarchy
     49        levels (animation of 'width' on <g> and inheriting the property value on a child
     50        <rect>).
     51
     52        With using presentation attributes, we also inherit the CSS property parsing for
     53        SVG attributes. <rect width="  100px  "> is possible now. (Note the trailing whitespaces.)
     54        This follows a recent resolution of the SVG WG.
     55
     56        Since we turned width and height to presentation attributes, the layout optimization
     57        selfHasRelativeLengths() in the DOM can't be used anymore. selfHasRelativeLengths() was
     58        intended to solve a problem where we did not layout relatively position/sized elements
     59        when the parent changes its size. However, as a side effect it did not call layout
     60        for absolutely positioned/sized elements since the layout does not change. I run
     61        all performance tests that we have and even wrote a test with hundreds of elements
     62        that would be affected by this optimization. The differences were inside the sigma
     63        of a normal test run. (Means I couldn't measure a performance difference.)
     64        Therefore, it is not worth it to keep the "optimization" around and I will probably
     65        remove it entirely for all basic shapes but <path> and <polygon> in future patches.
     66
     67        Tests: svg/css/parse-height.html
     68               svg/css/parse-width.html
     69               svg/css/width-height-presentation-attribute-expected.svg
     70               svg/css/width-height-presentation-attribute.svg
     71
     72        * css/CSSComputedStyleDeclaration.cpp:
     73        (WebCore::ComputedStyleExtractor::propertyValue): We never calculated the computed
     74            value of width/height for SVG elements and returned auto instead. This is based
     75            on a rule of CSS 2 and needs to be fixed in CSS3.
     76        * css/DeprecatedStyleBuilder.cpp:
     77        (WebCore::ApplyPropertyLength::applyValue): Length always incorporates the zoom level.
     78            In SVG we still apply the zoom after all operations by scaling the context. We need
     79            to take this in account for Length and don't apply zoom on SVG inline elements.
     80        * css/StyleResolver.cpp:
     81        (WebCore::StyleResolver::useSVGZoomRulesForLength):
     82            See above.
     83        * css/StyleResolver.h:
     84        * rendering/svg/RenderSVGRect.cpp:
     85        (WebCore::RenderSVGRect::updateShapeFromElement): Do not call width() and height() on
     86            SVG DOM but use the values of RenderStyle instead.
     87        * rendering/svg/SVGPathData.cpp:
     88        (WebCore::updatePathFromRectElement): Ditto.
     89        * svg/SVGAnimateElement.cpp:
     90        (WebCore::SVGAnimateElement::resetAnimatedType): We need to differ between CSS properties
     91            with and without SVG DOM on the current element. In the later case we animate the
     92            SVG DOM and need to synch RenderStyle.
     93        (WebCore::SVGAnimateElement::clearAnimatedType): Ditto.
     94        (WebCore::SVGAnimateElement::applyResultsToTarget): Ditto.
     95        * svg/SVGAnimationElement.cpp:
     96        (WebCore::SVGAnimationElement::isTargetAttributeCSSProperty): This checks if the CSS property
     97            has to be synched with SVG DOM.
     98        (WebCore::SVGAnimationElement::shouldApplyAnimation): Ditto.
     99        * svg/SVGAnimationElement.h:
     100        * svg/SVGElement.cpp:
     101        (WebCore::populateAttributeNameToCSSPropertyIDMap): Add width and heigth to the CSS property
     102            list for presentation attributes.
     103        (WebCore::populateCSSPropertyWithSVGDOMNameToAnimatedPropertyTypeMap): CSS properties with
     104            SVG DOM synchronization need to be treated differently. Collect them in a separate map.
     105        (WebCore::cssPropertyWithSVGDOMNameToAnimatedPropertyTypeMap): Caller for the map.
     106        (WebCore::SVGElement::animatedPropertyTypeForAttribute): We need to check both maps here:
     107            CSS properties and CSS properties with SVG DOM synch.
     108        (WebCore::SVGElement::isAnimatableCSSProperty): Ditto.
     109        (WebCore::SVGElement::isPresentationAttributeWithSVGDOM): Just return true if the property name
     110            is in the map of properties with SVG DOM for the current element.
     111        * svg/SVGElement.h:
     112        (WebCore::SVGElement::invalidateSVGPresentationAttributeStyle): Call needsStyleRecalc.
     113        * svg/SVGFilterElement.cpp: Make width/height presentation attribute.
     114        (WebCore::SVGFilterElement::svgAttributeChanged):
     115        (WebCore::SVGFilterElement::selfHasRelativeLengths): Deleted.
     116        * svg/SVGFilterElement.h: Ditto.
     117        * svg/SVGForeignObjectElement.cpp:
     118        (WebCore::SVGForeignObjectElement::svgAttributeChanged):
     119        (WebCore::SVGForeignObjectElement::selfHasRelativeLengths): Deleted.
     120        * svg/SVGForeignObjectElement.h:
     121        * svg/SVGImageElement.cpp: Ditto.
     122        (WebCore::SVGImageElement::svgAttributeChanged):
     123        (WebCore::SVGImageElement::isPresentationAttribute): Deleted.
     124        (WebCore::SVGImageElement::collectStyleForPresentationAttribute): Deleted.
     125        (WebCore::SVGImageElement::selfHasRelativeLengths): Deleted.
     126        * svg/SVGImageElement.h:
     127        * svg/SVGLength.h: Transform an Length value to an absolute value by taking the SVG viewport
     128            into account. (An SVG viewport is not the same as the CSS viewport.)
     129        * svg/SVGLengthContext.cpp: Ditto.
     130        (WebCore::SVGLengthContext::valueForLength):
     131        * svg/SVGLengthContext.h:
     132        * svg/SVGMaskElement.cpp: Make width/height presentation attribute.
     133        (WebCore::SVGMaskElement::svgAttributeChanged):
     134        (WebCore::SVGMaskElement::selfHasRelativeLengths): Deleted.
     135        * svg/SVGMaskElement.h:
     136        * svg/SVGPatternElement.cpp: Ditto.
     137        (WebCore::SVGPatternElement::svgAttributeChanged):
     138        (WebCore::SVGPatternElement::selfHasRelativeLengths): Deleted.
     139        * svg/SVGPatternElement.h:
     140        * svg/SVGRectElement.cpp: Ditto.
     141        (WebCore::SVGRectElement::svgAttributeChanged):
     142        (WebCore::SVGRectElement::selfHasRelativeLengths): Deleted.
     143        * svg/SVGRectElement.h:
     144        * svg/SVGSVGElement.cpp: Ditto.
     145        (WebCore::SVGSVGElement::svgAttributeChanged): Clean up redundant layout calls.
     146        (WebCore::SVGSVGElement::isPresentationAttribute): Deleted.
     147        (WebCore::SVGSVGElement::collectStyleForPresentationAttribute): Deleted.
     148        * svg/SVGSVGElement.h:
     149        * svg/properties/SVGAnimatedProperty.cpp: Synchronize SVG DOM with DOM.
     150        (WebCore::SVGAnimatedProperty::commitChange):
     151
    11522014-07-22  Adrian Perez de Castro  <aperez@igalia.com>
    2153
  • trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp

    r171010 r171341  
    21182118#endif /* ENABLE(CSS_GRID_LAYOUT) */
    21192119        case CSSPropertyHeight:
    2120             if (renderer) {
     2120            if (renderer && !renderer->isRenderSVGModelObject()) {
    21212121                // According to http://www.w3.org/TR/CSS2/visudet.html#the-height-property,
    21222122                // the "height" property does not apply for non-replaced inline elements.
     
    24222422            return cssValuePool().createValue(style->widows(), CSSPrimitiveValue::CSS_NUMBER);
    24232423        case CSSPropertyWidth:
    2424             if (renderer) {
     2424            if (renderer && !renderer->isRenderSVGModelObject()) {
    24252425                // According to http://www.w3.org/TR/CSS2/visudet.html#the-width-property,
    24262426                // the "width" property does not apply for non-replaced inline elements.
  • trunk/Source/WebCore/css/DeprecatedStyleBuilder.cpp

    r170996 r171341  
    385385        }
    386386
     387        CSSToLengthConversionData conversionData = styleResolver->useSVGZoomRulesForLength() ?
     388            styleResolver->state().cssToLengthConversionData().copyWithAdjustedZoom(1.0f)
     389            : styleResolver->state().cssToLengthConversionData();
    387390        if (autoEnabled && primitiveValue->getValueID() == CSSValueAuto)
    388391            setValue(styleResolver->style(), Length());
    389392        else if (primitiveValue->isLength()) {
    390             Length length = primitiveValue->computeLength<Length>(styleResolver->state().cssToLengthConversionData());
     393            Length length = primitiveValue->computeLength<Length>(conversionData);
    391394            length.setHasQuirk(primitiveValue->isQuirkValue());
    392395            setValue(styleResolver->style(), length);
     
    394397            setValue(styleResolver->style(), Length(primitiveValue->getDoubleValue(), Percent));
    395398        else if (primitiveValue->isCalculatedPercentageWithLength())
    396             setValue(styleResolver->style(), Length(primitiveValue->cssCalcValue()->createCalculationValue(styleResolver->state().cssToLengthConversionData())));
     399            setValue(styleResolver->style(), Length(primitiveValue->cssCalcValue()->createCalculationValue(conversionData)));
    397400    }
    398401
  • trunk/Source/WebCore/css/StyleResolver.cpp

    r171321 r171341  
    105105#include "SVGDocument.h"
    106106#include "SVGDocumentExtensions.h"
    107 #include "SVGElement.h"
    108107#include "SVGFontFaceElement.h"
    109108#include "SVGNames.h"
     109#include "SVGSVGElement.h"
    110110#include "SVGURIReference.h"
    111111#include "SecurityOrigin.h"
     
    18601860{
    18611861    return m_state.element() && m_state.element()->isSVGElement();
     1862}
     1863
     1864// Scale with/height properties on inline SVG root.
     1865bool StyleResolver::useSVGZoomRulesForLength()
     1866{
     1867    return m_state.element() && m_state.element()->isSVGElement() && !(isSVGSVGElement(m_state.element()) && m_state.element()->parentNode());
    18621868}
    18631869
  • trunk/Source/WebCore/css/StyleResolver.h

    r171138 r171341  
    207207public:
    208208    bool useSVGZoomRules();
     209    bool useSVGZoomRulesForLength();
    209210
    210211    static bool colorFromPrimitiveValueIsDerivedFromElement(CSSPrimitiveValue*);
  • trunk/Source/WebCore/rendering/svg/RenderSVGRect.cpp

    r171046 r171341  
    5757
    5858    SVGLengthContext lengthContext(&rectElement());
    59     FloatSize boundingBoxSize(rectElement().width().value(lengthContext), rectElement().height().value(lengthContext));
     59    FloatSize boundingBoxSize(lengthContext.valueForLength(style().width(), LengthModeWidth), lengthContext.valueForLength(style().height(), LengthModeHeight));
    6060
    6161    // Element is invalid if either dimension is negative.
  • trunk/Source/WebCore/rendering/svg/SVGPathData.cpp

    r163440 r171341  
    2222
    2323#include "Path.h"
     24#include "RenderElement.h"
     25#include "RenderStyle.h"
    2426#include "SVGCircleElement.h"
    2527#include "SVGEllipseElement.h"
     28#include "SVGLengthContext.h"
    2629#include "SVGLineElement.h"
    2730#include "SVGNames.h"
     
    105108{
    106109    SVGRectElement* rect = toSVGRectElement(element);
     110    RenderElement* renderer = rect->renderer();
     111    if (!renderer)
     112        return;
    107113
     114    RenderStyle& style = renderer->style();
    108115    SVGLengthContext lengthContext(element);
    109     float width = rect->width().value(lengthContext);
     116    float width = lengthContext.valueForLength(style.width(), LengthModeWidth);
    110117    if (width <= 0)
    111118        return;
    112     float height = rect->height().value(lengthContext);
     119    float height = lengthContext.valueForLength(style.height(), LengthModeHeight);
    113120    if (height <= 0)
    114121        return;
  • trunk/Source/WebCore/svg/SVGAnimateElement.cpp

    r163440 r171341  
    207207        return;
    208208
    209     if (shouldApply == ApplyXMLAnimation) {
     209    if (shouldApply == ApplyXMLAnimation || shouldApply == ApplyXMLandCSSAnimation) {
    210210        // SVG DOM animVal animation code-path.
    211211        m_animatedProperties = animator->findAnimatedPropertiesForAttributeName(targetElement, attributeName);
     
    335335    }
    336336
     337    ShouldApplyAnimation shouldApply = shouldApplyAnimation(targetElement, attributeName());
     338    if (shouldApply == ApplyXMLandCSSAnimation)
     339        removeCSSPropertyFromTargetAndInstances(targetElement, attributeName());
     340
    337341    // SVG DOM animVal animation code-path.
    338342    if (m_animator) {
     
    355359        return;
    356360
     361    SVGElement* targetElement = this->targetElement();
     362    const QualifiedName& attributeName = this->attributeName();
    357363    if (m_animatedProperties.isEmpty()) {
    358364        // CSS properties animation code-path.
    359365        // Convert the result of the animation to a String and apply it as CSS property on the target & all instances.
    360         applyCSSPropertyToTargetAndInstances(targetElement(), attributeName(), m_animatedType->valueAsString());
    361         return;
    362     }
     366        applyCSSPropertyToTargetAndInstances(targetElement, attributeName, m_animatedType->valueAsString());
     367        return;
     368    }
     369
     370    // We do update the style and the animation property independent of each other.
     371    ShouldApplyAnimation shouldApply = shouldApplyAnimation(targetElement, attributeName);
     372    if (shouldApply == ApplyXMLandCSSAnimation)
     373        applyCSSPropertyToTargetAndInstances(targetElement, attributeName, m_animatedType->valueAsString());
    363374
    364375    // SVG DOM animVal animation code-path.
     
    366377    // We only have to trigger update notifications here.
    367378    m_animator->animValDidChange(m_animatedProperties);
    368     notifyTargetAndInstancesAboutAnimValChange(targetElement(), attributeName());
     379    notifyTargetAndInstancesAboutAnimValChange(targetElement, attributeName);
    369380}
    370381
  • trunk/Source/WebCore/svg/SVGAnimationElement.cpp

    r168469 r171341  
    354354}
    355355
    356 bool SVGAnimationElement::isTargetAttributeCSSProperty(SVGElement*, const QualifiedName& attributeName)
    357 {
     356bool SVGAnimationElement::isTargetAttributeCSSProperty(SVGElement* element, const QualifiedName& attributeName)
     357{
     358    // FIXME: Must be isSVGTextPositioningElement(element) instead.
     359    if (isSVGTextElement(element)
     360        && (attributeName == SVGNames::xAttr || attributeName == SVGNames::yAttr))
     361        return false;
     362
    358363    return SVGElement::isAnimatableCSSProperty(attributeName);
    359364}
     
    365370
    366371    // Always animate CSS properties, using the ApplyCSSAnimation code path, regardless of the attributeType value.
    367     if (isTargetAttributeCSSProperty(targetElement, attributeName))
     372    if (isTargetAttributeCSSProperty(targetElement, attributeName)) {
     373        if (targetElement->isPresentationAttributeWithSVGDOM(attributeName))
     374            return ApplyXMLandCSSAnimation;
    368375        return ApplyCSSAnimation;
     376    }
     377
    369378
    370379    // If attributeType="CSS" and attributeName doesn't point to a CSS property, ignore the animation.
  • trunk/Source/WebCore/svg/SVGAnimationElement.h

    r163440 r171341  
    8888        DontApplyAnimation,
    8989        ApplyCSSAnimation,
    90         ApplyXMLAnimation
     90        ApplyXMLAnimation,
     91        ApplyXMLandCSSAnimation // For presentation attributes with SVG DOM properties.
    9192    };
    9293
  • trunk/Source/WebCore/svg/SVGElement.cpp

    r168921 r171341  
    112112        &glyph_orientation_verticalAttr,
    113113        &image_renderingAttr,
     114        &SVGNames::heightAttr,
    114115        &kerningAttr,
    115116        &letter_spacingAttr,
     
    141142        &vector_effectAttr,
    142143        &visibilityAttr,
     144        &SVGNames::widthAttr,
    143145        &word_spacingAttr,
    144146        &writing_modeAttr,
     
    233235}
    234236
     237static NEVER_INLINE void populateCSSPropertyWithSVGDOMNameToAnimatedPropertyTypeMap(HashMap<QualifiedName::QualifiedNameImpl*, AnimatedPropertyType>& map)
     238{
     239    struct TableEntry {
     240        const QualifiedName& attributeName;
     241        AnimatedPropertyType type;
     242    };
     243
     244    static const TableEntry table[] = {
     245        { SVGNames::heightAttr, AnimatedLength },
     246        { SVGNames::widthAttr, AnimatedLength },
     247    };
     248
     249    for (unsigned i = 0; i < WTF_ARRAY_LENGTH(table); ++i)
     250        map.add(table[i].attributeName.impl(), table[i].type);
     251}
     252
     253static inline HashMap<QualifiedName::QualifiedNameImpl*, AnimatedPropertyType>& cssPropertyWithSVGDOMNameToAnimatedPropertyTypeMap()
     254{
     255    static NeverDestroyed<HashMap<QualifiedName::QualifiedNameImpl*, AnimatedPropertyType>> map;
     256    if (map.get().isEmpty())
     257        populateCSSPropertyWithSVGDOMNameToAnimatedPropertyTypeMap(map);
     258    return map;
     259}
     260
    235261SVGElement::SVGElement(const QualifiedName& tagName, Document& document)
    236262    : StyledElement(tagName, document, CreateSVGElement)
     
    509535    auto& map = attributeNameToAnimatedPropertyTypeMap();
    510536    auto it = map.find(attributeName.impl());
    511     if (it != map.end())
     537    if (it != map.end()) {
    512538        propertyTypes.append(it->value);
     539        return;
     540    }
     541
     542    auto& cssPropertyWithSVGDOMMap = cssPropertyWithSVGDOMNameToAnimatedPropertyTypeMap();
     543    auto svgPropertyIterator = cssPropertyWithSVGDOMMap.find(attributeName.impl());
     544    if (svgPropertyIterator != cssPropertyWithSVGDOMMap.end())
     545        propertyTypes.append(svgPropertyIterator->value);
    513546}
    514547
     
    966999bool SVGElement::isAnimatableCSSProperty(const QualifiedName& attributeName)
    9671000{
    968     return attributeNameToAnimatedPropertyTypeMap().contains(attributeName.impl());
     1001    return attributeNameToAnimatedPropertyTypeMap().contains(attributeName.impl())
     1002        || cssPropertyWithSVGDOMNameToAnimatedPropertyTypeMap().contains(attributeName.impl());
     1003}
     1004
     1005bool SVGElement::isPresentationAttributeWithSVGDOM(const QualifiedName& attributeName)
     1006{
     1007    Vector<AnimatedPropertyType> propertyTypes;
     1008    localAttributeToPropertyMap().animatedPropertyTypeForAttribute(attributeName, propertyTypes);
     1009    return !propertyTypes.isEmpty();
    9691010}
    9701011
  • trunk/Source/WebCore/svg/SVGElement.h

    r168921 r171341  
    6565    virtual String title() const override;
    6666    static bool isAnimatableCSSProperty(const QualifiedName&);
     67    bool isPresentationAttributeWithSVGDOM(const QualifiedName&);
    6768    bool isKnownAttribute(const QualifiedName&);
    6869    PassRefPtr<CSSValue> getPresentationAttribute(const String& name);
     
    8788    virtual void svgAttributeChanged(const QualifiedName&);
    8889
    89     virtual void animatedPropertyTypeForAttribute(const QualifiedName&, Vector<AnimatedPropertyType>&);
     90    void animatedPropertyTypeForAttribute(const QualifiedName&, Vector<AnimatedPropertyType>&);
    9091
    9192    void sendSVGLoadEventIfPossible(bool sendParentLoadEvents = false);
     
    9798
    9899    void invalidateSVGAttributes() { ensureUniqueElementData().setAnimatedSVGAttributesAreDirty(true); }
    99     void invalidateSVGPresentationAttributeStyle() { ensureUniqueElementData().setPresentationAttributeStyleIsDirty(true); }
     100    void invalidateSVGPresentationAttributeStyle()
     101    {
     102        ensureUniqueElementData().setPresentationAttributeStyleIsDirty(true);
     103        // Trigger style recalculation for "elements as resource" (e.g. referenced by feImage).
     104        setNeedsStyleRecalc(InlineStyleChange);
     105    }
    100106
    101107    const HashSet<SVGElementInstance*>& instancesForElement() const;
  • trunk/Source/WebCore/svg/SVGFilterElement.cpp

    r170774 r171341  
    168168
    169169    SVGElementInstance::InvalidationGuard invalidationGuard(this);
    170    
     170
     171    if (attrName == SVGNames::widthAttr
     172        || attrName == SVGNames::heightAttr) {
     173        invalidateSVGPresentationAttributeStyle();
     174        return;
     175    }
     176
    171177    if (attrName == SVGNames::xAttr
    172         || attrName == SVGNames::yAttr
    173         || attrName == SVGNames::widthAttr
    174         || attrName == SVGNames::heightAttr)
     178        || attrName == SVGNames::yAttr)
    175179        updateRelativeLengthsInformation();
    176180
     
    234238}
    235239
    236 bool SVGFilterElement::selfHasRelativeLengths() const
    237 {
    238     return x().isRelative()
    239         || y().isRelative()
    240         || width().isRelative()
    241         || height().isRelative();
    242 }
    243 
    244240}
    245241
  • trunk/Source/WebCore/svg/SVGFilterElement.h

    r163440 r171341  
    5858    virtual bool childShouldCreateRenderer(const Node&) const override;
    5959
    60     virtual bool selfHasRelativeLengths() const override;
     60    virtual bool selfHasRelativeLengths() const override { return true; }
    6161
    6262    static const AtomicString& filterResXIdentifier();
  • trunk/Source/WebCore/svg/SVGForeignObjectElement.cpp

    r170774 r171341  
    113113
    114114    SVGElementInstance::InvalidationGuard invalidationGuard(this);
    115    
    116     bool isLengthAttribute = attrName == SVGNames::xAttr
    117                           || attrName == SVGNames::yAttr
    118                           || attrName == SVGNames::widthAttr
    119                           || attrName == SVGNames::heightAttr;
    120115
    121     if (isLengthAttribute)
     116    if (attrName == SVGNames::widthAttr
     117        || attrName == SVGNames::heightAttr) {
     118        invalidateSVGPresentationAttributeStyle();
     119        return;
     120    }
     121
     122    if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr)
    122123        updateRelativeLengthsInformation();
    123124
     
    159160}
    160161
    161 bool SVGForeignObjectElement::selfHasRelativeLengths() const
    162 {
    163     return x().isRelative()
    164         || y().isRelative()
    165         || width().isRelative()
    166         || height().isRelative();
    167162}
    168 
    169 }
  • trunk/Source/WebCore/svg/SVGForeignObjectElement.h

    r163440 r171341  
    4747    virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
    4848
    49     virtual bool selfHasRelativeLengths() const override;
     49    virtual bool selfHasRelativeLengths() const override { return true; }
    5050
    5151    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGForeignObjectElement)
  • trunk/Source/WebCore/svg/SVGImageElement.cpp

    r170774 r171341  
    8888}
    8989
    90 bool SVGImageElement::isPresentationAttribute(const QualifiedName& name) const
    91 {
    92     if (name == SVGNames::widthAttr || name == SVGNames::heightAttr)
    93         return true;
    94     return SVGGraphicsElement::isPresentationAttribute(name);
    95 }
    96 
    97 void SVGImageElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStyleProperties& style)
    98 {
    99     if (!isSupportedAttribute(name))
    100         SVGGraphicsElement::collectStyleForPresentationAttribute(name, value, style);
    101     else if (name == SVGNames::widthAttr)
    102         addPropertyToPresentationAttributeStyle(style, CSSPropertyWidth, value);
    103     else if (name == SVGNames::heightAttr)
    104         addPropertyToPresentationAttributeStyle(style, CSSPropertyHeight, value);
    105 }
    106 
    10790void SVGImageElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
    10891{
     
    140123
    141124    SVGElementInstance::InvalidationGuard invalidationGuard(this);
    142    
     125
     126    if (attrName == SVGNames::widthAttr
     127        || attrName == SVGNames::heightAttr) {
     128        invalidateSVGPresentationAttributeStyle();
     129        return;
     130    }
     131
    143132    bool isLengthAttribute = attrName == SVGNames::xAttr
    144133                          || attrName == SVGNames::yAttr
     
    172161
    173162    ASSERT_NOT_REACHED();
    174 }
    175 
    176 bool SVGImageElement::selfHasRelativeLengths() const
    177 {
    178     return x().isRelative()
    179         || y().isRelative()
    180         || width().isRelative()
    181         || height().isRelative();
    182163}
    183164
  • trunk/Source/WebCore/svg/SVGImageElement.h

    r168313 r171341  
    4545    bool isSupportedAttribute(const QualifiedName&);
    4646    virtual void parseAttribute(const QualifiedName&, const AtomicString&) override;
    47     virtual bool isPresentationAttribute(const QualifiedName&) const override;
    48     virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) override;
    4947    virtual void svgAttributeChanged(const QualifiedName&) override;
    5048
     
    5957    virtual bool haveLoadedRequiredResources() override;
    6058
    61     virtual bool selfHasRelativeLengths() const override;
     59    virtual bool selfHasRelativeLengths() const override { return true; }
    6260    virtual void didMoveToNewDocument(Document* oldDocument) override;
    6361
  • trunk/Source/WebCore/svg/SVGLength.h

    r163440 r171341  
    5757    };
    5858
     59    // FIXME: Once all SVGLength users use Length internally, we make this a wrapper for Length.
    5960    SVGLength(SVGLengthMode = LengthModeOther, const String& valueAsString = String());
    6061    SVGLength(const SVGLengthContext&, float, SVGLengthMode = LengthModeOther, SVGLengthType = LengthTypeNumber);
  • trunk/Source/WebCore/svg/SVGLengthContext.cpp

    r163440 r171341  
    2828#include "FontMetrics.h"
    2929#include "Frame.h"
     30#include "LengthFunctions.h"
    3031#include "RenderSVGRoot.h"
    3132#include "RenderSVGViewportContainer.h"
     
    8485    // FIXME: valueAsPercentage() won't be correct for eg. cm units. They need to be resolved in user space and then be considered in objectBoundingBox space.
    8586    return x.valueAsPercentage();
     87}
     88
     89float SVGLengthContext::valueForLength(const Length& length, SVGLengthMode mode)
     90{
     91    if (length.isPercent())
     92        return convertValueFromPercentageToUserUnits(length.value() / 100, mode, IGNORE_EXCEPTION);
     93    if (length.isAuto())
     94        return 0;
     95
     96    FloatSize viewportSize;
     97    determineViewport(viewportSize);
     98
     99    switch (mode) {
     100    case LengthModeWidth:
     101        return floatValueForLength(length, viewportSize.width());
     102    case LengthModeHeight:
     103        return floatValueForLength(length, viewportSize.height());
     104    case LengthModeOther:
     105        return floatValueForLength(length, sqrtf(viewportSize.diagonalLengthSquared() / 2));
     106    };
     107    return 0;
    86108}
    87109
  • trunk/Source/WebCore/svg/SVGLengthContext.h

    r163440 r171341  
    2828class SVGElement;
    2929class SVGLength;
     30struct Length;
    3031
    3132typedef int ExceptionCode;
     
    6566    static float resolveLength(const SVGElement*, SVGUnitTypes::SVGUnitType, const SVGLength&);
    6667
     68    float valueForLength(const Length&, SVGLengthMode = LengthModeOther);
    6769    float convertValueToUserUnits(float, SVGLengthMode, SVGLengthType fromUnit, ExceptionCode&) const;
    6870    float convertValueFromUserUnits(float, SVGLengthMode, SVGLengthType toUnit, ExceptionCode&) const;
  • trunk/Source/WebCore/svg/SVGMaskElement.cpp

    r170774 r171341  
    135135
    136136    SVGElementInstance::InvalidationGuard invalidationGuard(this);
    137    
     137
     138    if (attrName == SVGNames::widthAttr
     139        || attrName == SVGNames::heightAttr) {
     140        invalidateSVGPresentationAttributeStyle();
     141        return;
     142    }
     143
    138144    if (attrName == SVGNames::xAttr
    139         || attrName == SVGNames::yAttr
    140         || attrName == SVGNames::widthAttr
    141         || attrName == SVGNames::heightAttr)
     145        || attrName == SVGNames::yAttr)
    142146        updateRelativeLengthsInformation();
    143147
     
    162166}
    163167
    164 bool SVGMaskElement::selfHasRelativeLengths() const
    165 {
    166     return x().isRelative()
    167         || y().isRelative()
    168         || width().isRelative()
    169         || height().isRelative();
    170168}
    171 
    172 }
  • trunk/Source/WebCore/svg/SVGMaskElement.h

    r163440 r171341  
    5151    virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
    5252
    53     virtual bool selfHasRelativeLengths() const override;
     53    virtual bool selfHasRelativeLengths() const override { return true; }
    5454
    5555    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGMaskElement)
  • trunk/Source/WebCore/svg/SVGPatternElement.cpp

    r170774 r171341  
    160160
    161161    SVGElementInstance::InvalidationGuard invalidationGuard(this);
    162    
     162
     163    if (attrName == SVGNames::widthAttr
     164        || attrName == SVGNames::heightAttr) {
     165        invalidateSVGPresentationAttributeStyle();
     166        return;
     167    }
     168
    163169    if (attrName == SVGNames::xAttr
    164         || attrName == SVGNames::yAttr
    165         || attrName == SVGNames::widthAttr
    166         || attrName == SVGNames::heightAttr)
     170        || attrName == SVGNames::yAttr)
    167171        updateRelativeLengthsInformation();
    168172
     
    253257}
    254258
    255 bool SVGPatternElement::selfHasRelativeLengths() const
    256 {
    257     return x().isRelative()
    258         || y().isRelative()
    259         || width().isRelative()
    260         || height().isRelative();
    261 }
    262 
    263 }
     259}
  • trunk/Source/WebCore/svg/SVGPatternElement.h

    r163440 r171341  
    6565    virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
    6666
    67     virtual bool selfHasRelativeLengths() const override;
     67    virtual bool selfHasRelativeLengths() const override { return true; }
    6868
    6969    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGPatternElement)
  • trunk/Source/WebCore/svg/SVGRectElement.cpp

    r170774 r171341  
    121121
    122122    SVGElementInstance::InvalidationGuard invalidationGuard(this);
    123    
     123
     124    if (attrName == SVGNames::widthAttr
     125        || attrName == SVGNames::heightAttr) {
     126        invalidateSVGPresentationAttributeStyle();
     127        return;
     128    }
     129
    124130    bool isLengthAttribute = attrName == SVGNames::xAttr
    125131                          || attrName == SVGNames::yAttr
    126                           || attrName == SVGNames::widthAttr
    127                           || attrName == SVGNames::heightAttr
    128132                          || attrName == SVGNames::rxAttr
    129133                          || attrName == SVGNames::ryAttr;
     
    150154}
    151155
    152 bool SVGRectElement::selfHasRelativeLengths() const
    153 {
    154     return x().isRelative()
    155         || y().isRelative()
    156         || width().isRelative()
    157         || height().isRelative()
    158         || rx().isRelative()
    159         || ry().isRelative();
    160 }
    161 
    162156RenderPtr<RenderElement> SVGRectElement::createElementRenderer(PassRef<RenderStyle> style)
    163157{
  • trunk/Source/WebCore/svg/SVGRectElement.h

    r168313 r171341  
    4444    virtual void svgAttributeChanged(const QualifiedName&) override;
    4545
    46     virtual bool selfHasRelativeLengths() const override;
     46    virtual bool selfHasRelativeLengths() const override { return true; }
    4747
    4848    virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
  • trunk/Source/WebCore/svg/SVGSVGElement.cpp

    r170774 r171341  
    271271}
    272272
    273 bool SVGSVGElement::isPresentationAttribute(const QualifiedName& name) const
    274 {
    275     if (isOutermostSVGSVGElement() && (name == SVGNames::widthAttr || name == SVGNames::heightAttr))
    276         return true;
    277     return SVGGraphicsElement::isPresentationAttribute(name);
    278 }
    279 
    280 void SVGSVGElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStyleProperties& style)
    281 {
    282     if (isOutermostSVGSVGElement() && (name == SVGNames::widthAttr || name == SVGNames::heightAttr)) {
    283         if (name == SVGNames::widthAttr)
    284             addPropertyToPresentationAttributeStyle(style, CSSPropertyWidth, value);
    285         else if (name == SVGNames::heightAttr)
    286             addPropertyToPresentationAttributeStyle(style, CSSPropertyHeight, value);
    287     } else
    288         SVGGraphicsElement::collectStyleForPresentationAttribute(name, value, style);
    289 }
    290 
    291273void SVGSVGElement::svgAttributeChanged(const QualifiedName& attrName)
    292274{
    293275    bool updateRelativeLengthsOrViewBox = false;
    294     bool widthChanged = attrName == SVGNames::widthAttr;
    295     bool heightChanged = attrName == SVGNames::heightAttr;
    296     if (widthChanged || heightChanged
     276    if (attrName == SVGNames::widthAttr
     277        || attrName == SVGNames::heightAttr
    297278        || attrName == SVGNames::xAttr
    298279        || attrName == SVGNames::yAttr) {
     280        invalidateSVGPresentationAttributeStyle();
    299281        updateRelativeLengthsOrViewBox = true;
    300         updateRelativeLengthsInformation();
    301 
    302         // At the SVG/HTML boundary (aka RenderSVGRoot), the width and
    303         // height attributes can affect the replaced size so we need
    304         // to mark it for updating.
    305         if (widthChanged || heightChanged) {
    306             // FIXME: This is a hack to synchronize changes from SVG DOM earlier in the
    307             // run. We need these changes in the style calculation process earlier than
    308             // usual.
    309             synchronizeAllAttributes();
    310             RenderObject* renderObject = renderer();
    311             if (renderObject && renderObject->isSVGRoot()) {
    312                 invalidateSVGPresentationAttributeStyle();
    313                 setNeedsStyleRecalc();
    314             }
    315         }
    316282    }
    317283
  • trunk/Source/WebCore/svg/SVGSVGElement.h

    r171147 r171341  
    134134
    135135    virtual void parseAttribute(const QualifiedName&, const AtomicString&) override;
    136     virtual bool isPresentationAttribute(const QualifiedName&) const override;
    137     virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) override;
    138136
    139137    virtual bool rendererIsNeeded(const RenderStyle&) override;
  • trunk/Source/WebCore/svg/properties/SVGAnimatedProperty.cpp

    r163440 r171341  
    5656    m_contextElement->invalidateSVGAttributes();
    5757    m_contextElement->svgAttributeChanged(m_attributeName);
     58    // Needed to synchronize with CSSOM for presentation attributes with SVG DOM.
     59    m_contextElement->synchronizeAnimatedSVGAttribute(m_attributeName);
    5860}
    5961
Note: See TracChangeset for help on using the changeset viewer.