WebCore:
authormjs@apple.com <mjs@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 May 2008 08:05:12 +0000 (08:05 +0000)
committermjs@apple.com <mjs@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 May 2008 08:05:12 +0000 (08:05 +0000)
2008-05-29  Maciej Stachowiak  <mjs@apple.com>

        Reviewed by Dave Hyatt.

        - speed up DHTML using lazy style resolution and rendere creation

        This change introduces the concept of "lazy attach" - when a node
        is lazy attached, then instead of resolving style and creating a
        renderer right away, we just mark it as needing a style recalc.

        The patch makes use of this mechanism when inserting nodes directly
        using DOM APIs from script. For now this is only done for the
        JavaScript language binding but could also be done for other
        bindings in the future.

        Lazy attach helps some common DHTML patterns - when a node is
        added to the DOM, and then subsequently changed in a
        style-affecting way, this causes an extra style recalc. This is a
        fairly common pattern so it is better to be lazy.

        * bindings/js/JSNodeCustom.cpp:
        (WebCore::JSNode::insertBefore): Request lazy attach.
        (WebCore::JSNode::replaceChild): ditto
        (WebCore::JSNode::appendChild): ditto
        * dom/ContainerNode.cpp:
        (WebCore::ContainerNode::insertBefore): Support lazy attach.
        (WebCore::ContainerNode::replaceChild): ditto
        (WebCore::ContainerNode::appendChild): ditto
        (WebCore::ContainerNode::detach): Clear "changed child" bit if still set.
        * dom/ContainerNode.h:
        * dom/Element.cpp:
        (WebCore::Element::recalcStyle): Adjusted to properly reattach a
        lazy-attached node.
        * dom/Node.cpp:
        (WebCore::Node::insertBefore): Extra parameter for lazy attach
        (still doesn't do anything).
        (WebCore::Node::replaceChild): ditto
        (WebCore::Node::appendChild): ditto
        (WebCore::Node::setChanged): Unrelated but obvious optimization -
        stop marking ancestor as having a changed child once we already reach
        an ancestor so marked.
        (WebCore::outermostLazyAttachedAncestor): Helper function for lazyAttach.
        (WebCore::Node::lazyAttach): Implement lazy attach.
        (WebCore::Node::canLazyAttach): Virtual method - true for most nodes.
        * dom/Node.h:
        * dom/Text.cpp:
        (WebCore::Text::recalcStyle): Properly handle the case of a reattached node.
        * html/HTMLEmbedElement.h:
        (WebCore::HTMLEmbedElement::canLazyAttach): Refuse lazy attach, since
        plugins and frames do important work at rederer creation time.
        * html/HTMLFrameElementBase.h:
        (WebCore::HTMLFrameElementBase::canLazyAttach): Refuse lazy attach, since
        plugins and frames do important work at rederer creation time.
        * html/HTMLFrameSetElement.cpp:
        (WebCore::HTMLFrameSetElement::recalcStyle): Change order so that
        reattach works properly.
        * html/HTMLObjectElement.h:
        (WebCore::HTMLObjectElement::canLazyAttach): Refuse lazy attach, since
        plugins and frames do important work at rederer creation time.
        * html/HTMLOptGroupElement.cpp:
        (WebCore::HTMLOptGroupElement::insertBefore): Pass along extra param.
        (WebCore::HTMLOptGroupElement::replaceChild): ditto
        (WebCore::HTMLOptGroupElement::appendChild): ditto
        * html/HTMLOptGroupElement.h:
        * html/HTMLSelectElement.cpp:
        (WebCore::HTMLSelectElement::insertBefore): Pass along extra param.
        (WebCore::HTMLSelectElement::replaceChild): ditto
        (WebCore::HTMLSelectElement::appendChild): ditto
        * html/HTMLSelectElement.h:
        * svg/SVGLocatable.cpp:
        (WebCore::SVGLocatable::getBBox): Add missing updateLayout call.
        * svg/SVGTextContentElement.cpp:
        (WebCore::SVGTextContentElement::getNumberOfChars): ditto
        (WebCore::SVGTextContentElement::getComputedTextLength): ditto
        (WebCore::SVGTextContentElement::getSubStringLength): ditto
        (WebCore::SVGTextContentElement::getStartPositionOfChar): ditto
        (WebCore::SVGTextContentElement::getEndPositionOfChar): ditto
        (WebCore::SVGTextContentElement::getExtentOfChar): ditto
        (WebCore::SVGTextContentElement::getRotationOfChar): ditto
        (WebCore::SVGTextContentElement::getCharNumAtPosition): ditto

LayoutTests:

2008-05-29  Maciej Stachowiak  <mjs@apple.com>

        Reviewed by Dave Hyatt.

        - Test cases for this change: "speed up DHTML using lazy style resolution and rendere creation"

        * http/tests/misc/acid3-expected.txt:
        * platform/mac/fast/dynamic/insert-before-table-part-in-continuation-expected.checksum:
        * platform/mac/fast/dynamic/insert-before-table-part-in-continuation-expected.png:
        * platform/mac/fast/dynamic/insert-before-table-part-in-continuation-expected.txt:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@34193 268f45cc-cd09-0410-ab3c-d52691b4dbfc

23 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/misc/acid3-expected.txt
LayoutTests/platform/mac/fast/dynamic/insert-before-table-part-in-continuation-expected.checksum
LayoutTests/platform/mac/fast/dynamic/insert-before-table-part-in-continuation-expected.png
LayoutTests/platform/mac/fast/dynamic/insert-before-table-part-in-continuation-expected.txt
WebCore/ChangeLog
WebCore/bindings/js/JSNodeCustom.cpp
WebCore/dom/ContainerNode.cpp
WebCore/dom/ContainerNode.h
WebCore/dom/Element.cpp
WebCore/dom/Node.cpp
WebCore/dom/Node.h
WebCore/dom/Text.cpp
WebCore/html/HTMLEmbedElement.h
WebCore/html/HTMLFrameElementBase.h
WebCore/html/HTMLFrameSetElement.cpp
WebCore/html/HTMLObjectElement.h
WebCore/html/HTMLOptGroupElement.cpp
WebCore/html/HTMLOptGroupElement.h
WebCore/html/HTMLSelectElement.cpp
WebCore/html/HTMLSelectElement.h
WebCore/svg/SVGLocatable.cpp
WebCore/svg/SVGTextContentElement.cpp

index c30722d61f6598ea92251decd21d6021af46bf4f..89c4985070470007a053fd340d8caa8b6b61449b 100644 (file)
@@ -1,3 +1,14 @@
+2008-05-29  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Dave Hyatt.
+
+        - Test cases for this change: "speed up DHTML using lazy style resolution and rendere creation"
+
+        * http/tests/misc/acid3-expected.txt:
+        * platform/mac/fast/dynamic/insert-before-table-part-in-continuation-expected.checksum:
+        * platform/mac/fast/dynamic/insert-before-table-part-in-continuation-expected.png:
+        * platform/mac/fast/dynamic/insert-before-table-part-in-continuation-expected.txt:
+
 2008-05-28  Oliver Hunt  <oliver@apple.com>
 
         Reviewed by Anders.
index 434fa9c2e777707a399e03be702ce859ab8cf2d4..c14771aa942c039a75f025fd9a7a560da4462b78 100644 (file)
@@ -6,7 +6,6 @@ layer at (20,20) size 644x457
       RenderBlock {H1} at (41,41) size 562x120
         RenderText {#text} at (0,4) size 273x112
           text run at (0,4) width 273: "Acid3"
-      RenderBlock (anonymous) at (41,121) size 562x0
       RenderBlock {DIV} at (41,121) size 562x312
         RenderBlock {P} at (7,80) size 54x42 [bgcolor=#FF0000] [border: (1px solid #000000)]
         RenderBlock {P} at (70,64) size 64x50 [bgcolor=#FFA500] [border: (1px solid #000000)]
index 674fa0b9d2224e840cf9b886f7f46c2c26c8d481..1aaaa7226596ea2d5387e0e8316749c9551a5edf 100644 (file)
@@ -1 +1 @@
-b848821df77004913ca9911a4295871d
\ No newline at end of file
+4cff5283c5881787befeab5eccf5c139
\ No newline at end of file
index e803cc8863b8a38a0c9ae8014864202d741df83a..96352699bf04d4a2c78601c642c8a6b690a92c38 100644 (file)
Binary files a/LayoutTests/platform/mac/fast/dynamic/insert-before-table-part-in-continuation-expected.png and b/LayoutTests/platform/mac/fast/dynamic/insert-before-table-part-in-continuation-expected.png differ
index df83be5c317de2c25b2fef166587280f142fa895..37caa6abe149611262c4e502c1604e722409077a 100644 (file)
@@ -1,8 +1,8 @@
-layer at (0,0) size 785x742
+layer at (0,0) size 785x678
   RenderView at (0,0) size 785x600
-layer at (0,0) size 785x742
-  RenderBlock {HTML} at (0,0) size 785x742
-    RenderBody {BODY} at (8,8) size 769x726
+layer at (0,0) size 785x678
+  RenderBlock {HTML} at (0,0) size 785x678
+    RenderBody {BODY} at (8,8) size 769x662
       RenderBlock {P} at (0,0) size 769x18
         RenderText {#text} at (0,0) size 53x18
           text run at (0,0) width 53: "Test for "
@@ -23,17 +23,16 @@ layer at (0,0) size 785x742
           text run at (0,54) width 122: "parent was a block."
       RenderBlock {DIV} at (0,122) size 769x36
         RenderBlock (anonymous) at (0,0) size 769x18
-          RenderInline {SPAN} at (0,0) size 41x18
+          RenderInline {SPAN} at (0,0) size 128x18
             RenderText {#text} at (0,0) size 41x18
               text run at (0,0) width 41: "Text..."
+            RenderText {#text} at (41,0) size 87x18
+              text run at (41,0) width 87: "goes here and"
         RenderBlock (anonymous) at (0,18) size 769x18
-          RenderTable at (0,0) size 190x18
-            RenderTableSection (anonymous) at (0,0) size 190x18
-              RenderTableRow (anonymous) at (0,0) size 190x18
-                RenderTableCell (anonymous) at (0,0) size 87x18 [r=0 c=0 rs=1 cs=1]
-                  RenderText {#text} at (0,0) size 87x18
-                    text run at (0,0) width 87: "goes here and"
-                RenderTableCell {DIV} at (87,0) size 103x18 [r=0 c=1 rs=1 cs=1]
+          RenderTable at (0,0) size 103x18
+            RenderTableSection (anonymous) at (0,0) size 103x18
+              RenderTableRow (anonymous) at (0,0) size 103x18
+                RenderTableCell {DIV} at (0,0) size 103x18 [r=0 c=0 rs=1 cs=1]
                   RenderText {#text} at (0,0) size 103x18
                     text run at (0,0) width 103: "...continues here"
         RenderBlock (anonymous) at (0,36) size 769x0
@@ -73,13 +72,12 @@ layer at (0,0) size 785x742
           RenderInline {SPAN} at (0,0) size 41x18
             RenderText {#text} at (0,0) size 41x18
               text run at (0,0) width 41: "Text..."
+            RenderInline {SPAN} at (0,0) size 0x18
         RenderBlock (anonymous) at (0,18) size 769x18
-          RenderTable at (0,0) size 104x18
-            RenderTableSection (anonymous) at (0,0) size 104x18
-              RenderTableRow (anonymous) at (0,0) size 104x18
-                RenderTableCell (anonymous) at (0,0) size 1x0 [r=0 c=0 rs=1 cs=1]
-                  RenderInline {SPAN} at (0,0) size 0x0
-                RenderTableCell {DIV} at (1,0) size 103x18 [r=0 c=1 rs=1 cs=1]
+          RenderTable at (0,0) size 103x18
+            RenderTableSection (anonymous) at (0,0) size 103x18
+              RenderTableRow (anonymous) at (0,0) size 103x18
+                RenderTableCell {DIV} at (0,0) size 103x18 [r=0 c=0 rs=1 cs=1]
                   RenderText {#text} at (0,0) size 103x18
                     text run at (0,0) width 103: "...continues here"
         RenderBlock (anonymous) at (0,36) size 769x0
@@ -90,35 +88,32 @@ layer at (0,0) size 785x742
             RenderText {#text} at (0,0) size 41x18
               text run at (0,0) width 41: "Text..."
         RenderBlock (anonymous) at (0,18) size 769x18
-          RenderTable at (0,0) size 104x18
-            RenderTableSection (anonymous) at (0,0) size 104x18
-              RenderTableRow (anonymous) at (0,0) size 104x18
-                RenderTableCell (anonymous) at (0,14) size 1x0 [r=0 c=0 rs=1 cs=1]
-                  RenderBlock {DIV} at (0,0) size 1x0
-                RenderTableCell {DIV} at (1,0) size 103x18 [r=0 c=1 rs=1 cs=1]
+          RenderTable at (0,0) size 103x18
+            RenderTableSection (anonymous) at (0,0) size 103x18
+              RenderTableRow (anonymous) at (0,0) size 103x18
+                RenderTableCell {DIV} at (0,0) size 103x18 [r=0 c=0 rs=1 cs=1]
                   RenderText {#text} at (0,0) size 103x18
                     text run at (0,0) width 103: "...continues here"
+          RenderBlock {DIV} at (0,18) size 769x0
         RenderBlock (anonymous) at (0,36) size 769x0
           RenderInline {SPAN} at (0,0) size 0x0
-      RenderBlock {DIV} at (0,302) size 769x54
+      RenderBlock {DIV} at (0,302) size 769x36
         RenderBlock (anonymous) at (0,0) size 769x18
-          RenderInline {SPAN} at (0,0) size 41x18
+          RenderInline {SPAN} at (0,0) size 128x18
             RenderText {#text} at (0,0) size 41x18
               text run at (0,0) width 41: "Text..."
-        RenderBlock (anonymous) at (0,18) size 769x36
-          RenderTable at (0,0) size 103x36
-            RenderTableSection (anonymous) at (0,0) size 103x36
-              RenderTableRow (anonymous) at (0,0) size 103x18
+            RenderText {#text} at (41,0) size 87x18
+              text run at (41,0) width 87: "goes here and"
+        RenderBlock (anonymous) at (0,18) size 769x18
+          RenderTable at (0,0) size 103x18
+            RenderTableSection (anonymous) at (0,0) size 103x18
+              RenderTableRow {DIV} at (0,0) size 103x18
                 RenderTableCell (anonymous) at (0,0) size 103x18 [r=0 c=0 rs=1 cs=1]
-                  RenderText {#text} at (0,0) size 87x18
-                    text run at (0,0) width 87: "goes here and"
-              RenderTableRow {DIV} at (0,18) size 103x18
-                RenderTableCell (anonymous) at (0,18) size 103x18 [r=1 c=0 rs=1 cs=1]
                   RenderText {#text} at (0,0) size 103x18
                     text run at (0,0) width 103: "...continues here"
-        RenderBlock (anonymous) at (0,54) size 769x0
+        RenderBlock (anonymous) at (0,36) size 769x0
           RenderInline {SPAN} at (0,0) size 0x0
-      RenderBlock {DIV} at (0,356) size 769x36
+      RenderBlock {DIV} at (0,338) size 769x36
         RenderBlock (anonymous) at (0,0) size 769x18
           RenderInline {SPAN} at (0,0) size 41x18
             RenderText {#text} at (0,0) size 41x18
@@ -134,7 +129,7 @@ layer at (0,0) size 785x742
                     text run at (0,0) width 103: "...continues here"
         RenderBlock (anonymous) at (0,36) size 769x0
           RenderInline {SPAN} at (0,0) size 0x0
-      RenderBlock {DIV} at (0,392) size 769x36
+      RenderBlock {DIV} at (0,374) size 769x36
         RenderBlock (anonymous) at (0,0) size 769x18
           RenderInline {SPAN} at (0,0) size 41x18
             RenderText {#text} at (0,0) size 41x18
@@ -149,24 +144,22 @@ layer at (0,0) size 785x742
                     text run at (0,0) width 103: "...continues here"
         RenderBlock (anonymous) at (0,36) size 769x0
           RenderInline {SPAN} at (0,0) size 0x0
-      RenderBlock {DIV} at (0,428) size 769x50
+      RenderBlock {DIV} at (0,410) size 769x36
         RenderBlock (anonymous) at (0,0) size 769x18
           RenderInline {SPAN} at (0,0) size 41x18
             RenderText {#text} at (0,0) size 41x18
               text run at (0,0) width 41: "Text..."
-        RenderBlock (anonymous) at (0,18) size 769x32
-          RenderTable at (0,0) size 103x32
-            RenderTableSection (anonymous) at (0,0) size 103x32
-              RenderTableRow (anonymous) at (0,0) size 103x14
-                RenderTableCell (anonymous) at (0,0) size 103x0 [r=0 c=0 rs=1 cs=1]
-                  RenderInline {SPAN} at (0,0) size 0x0
-              RenderTableRow {DIV} at (0,14) size 103x18
-                RenderTableCell (anonymous) at (0,14) size 103x18 [r=1 c=0 rs=1 cs=1]
+            RenderInline {SPAN} at (0,0) size 0x18
+        RenderBlock (anonymous) at (0,18) size 769x18
+          RenderTable at (0,0) size 103x18
+            RenderTableSection (anonymous) at (0,0) size 103x18
+              RenderTableRow {DIV} at (0,0) size 103x18
+                RenderTableCell (anonymous) at (0,0) size 103x18 [r=0 c=0 rs=1 cs=1]
                   RenderText {#text} at (0,0) size 103x18
                     text run at (0,0) width 103: "...continues here"
-        RenderBlock (anonymous) at (0,50) size 769x0
+        RenderBlock (anonymous) at (0,36) size 769x0
           RenderInline {SPAN} at (0,0) size 0x0
-      RenderBlock {DIV} at (0,478) size 769x36
+      RenderBlock {DIV} at (0,446) size 769x36
         RenderBlock (anonymous) at (0,0) size 769x18
           RenderInline {SPAN} at (0,0) size 41x18
             RenderText {#text} at (0,0) size 41x18
@@ -174,35 +167,30 @@ layer at (0,0) size 785x742
         RenderBlock (anonymous) at (0,18) size 769x18
           RenderTable at (0,0) size 103x18
             RenderTableSection (anonymous) at (0,0) size 103x18
-              RenderTableRow (anonymous) at (0,0) size 103x0
-                RenderTableCell (anonymous) at (0,0) size 103x0 [r=0 c=0 rs=1 cs=1]
-                  RenderBlock {DIV} at (0,0) size 103x0
               RenderTableRow {DIV} at (0,0) size 103x18
-                RenderTableCell (anonymous) at (0,0) size 103x18 [r=1 c=0 rs=1 cs=1]
+                RenderTableCell (anonymous) at (0,0) size 103x18 [r=0 c=0 rs=1 cs=1]
                   RenderText {#text} at (0,0) size 103x18
                     text run at (0,0) width 103: "...continues here"
+          RenderBlock {DIV} at (0,18) size 769x0
         RenderBlock (anonymous) at (0,36) size 769x0
           RenderInline {SPAN} at (0,0) size 0x0
-      RenderBlock {DIV} at (0,514) size 769x54
+      RenderBlock {DIV} at (0,482) size 769x36
         RenderBlock (anonymous) at (0,0) size 769x18
-          RenderInline {SPAN} at (0,0) size 41x18
+          RenderInline {SPAN} at (0,0) size 128x18
             RenderText {#text} at (0,0) size 41x18
               text run at (0,0) width 41: "Text..."
-        RenderBlock (anonymous) at (0,18) size 769x36
-          RenderTable at (0,0) size 103x36
-            RenderTableSection (anonymous) at (0,0) size 103x18
-              RenderTableRow (anonymous) at (0,0) size 103x18
-                RenderTableCell (anonymous) at (0,0) size 103x18 [r=0 c=0 rs=1 cs=1]
-                  RenderText {#text} at (0,0) size 87x18
-                    text run at (0,0) width 87: "goes here and"
-            RenderTableSection {DIV} at (0,18) size 103x18
+            RenderText {#text} at (41,0) size 87x18
+              text run at (41,0) width 87: "goes here and"
+        RenderBlock (anonymous) at (0,18) size 769x18
+          RenderTable at (0,0) size 103x18
+            RenderTableSection {DIV} at (0,0) size 103x18
               RenderTableRow (anonymous) at (0,0) size 103x18
                 RenderTableCell (anonymous) at (0,0) size 103x18 [r=0 c=0 rs=1 cs=1]
                   RenderText {#text} at (0,0) size 103x18
                     text run at (0,0) width 103: "...continues here"
-        RenderBlock (anonymous) at (0,54) size 769x0
+        RenderBlock (anonymous) at (0,36) size 769x0
           RenderInline {SPAN} at (0,0) size 0x0
-      RenderBlock {DIV} at (0,568) size 769x36
+      RenderBlock {DIV} at (0,518) size 769x36
         RenderBlock (anonymous) at (0,0) size 769x18
           RenderInline {SPAN} at (0,0) size 41x18
             RenderText {#text} at (0,0) size 41x18
@@ -219,7 +207,7 @@ layer at (0,0) size 785x742
                     text run at (0,0) width 103: "...continues here"
         RenderBlock (anonymous) at (0,36) size 769x0
           RenderInline {SPAN} at (0,0) size 0x0
-      RenderBlock {DIV} at (0,604) size 769x36
+      RenderBlock {DIV} at (0,554) size 769x36
         RenderBlock (anonymous) at (0,0) size 769x18
           RenderInline {SPAN} at (0,0) size 41x18
             RenderText {#text} at (0,0) size 41x18
@@ -235,39 +223,33 @@ layer at (0,0) size 785x742
                     text run at (0,0) width 103: "...continues here"
         RenderBlock (anonymous) at (0,36) size 769x0
           RenderInline {SPAN} at (0,0) size 0x0
-      RenderBlock {DIV} at (0,640) size 769x50
+      RenderBlock {DIV} at (0,590) size 769x36
         RenderBlock (anonymous) at (0,0) size 769x18
           RenderInline {SPAN} at (0,0) size 41x18
             RenderText {#text} at (0,0) size 41x18
               text run at (0,0) width 41: "Text..."
-        RenderBlock (anonymous) at (0,18) size 769x32
-          RenderTable at (0,0) size 103x32
-            RenderTableSection (anonymous) at (0,0) size 103x14
-              RenderTableRow (anonymous) at (0,0) size 103x14
-                RenderTableCell (anonymous) at (0,0) size 103x0 [r=0 c=0 rs=1 cs=1]
-                  RenderInline {SPAN} at (0,0) size 0x0
-            RenderTableSection {DIV} at (0,14) size 103x18
+            RenderInline {SPAN} at (0,0) size 0x18
+        RenderBlock (anonymous) at (0,18) size 769x18
+          RenderTable at (0,0) size 103x18
+            RenderTableSection {DIV} at (0,0) size 103x18
               RenderTableRow (anonymous) at (0,0) size 103x18
                 RenderTableCell (anonymous) at (0,0) size 103x18 [r=0 c=0 rs=1 cs=1]
                   RenderText {#text} at (0,0) size 103x18
                     text run at (0,0) width 103: "...continues here"
-        RenderBlock (anonymous) at (0,50) size 769x0
+        RenderBlock (anonymous) at (0,36) size 769x0
           RenderInline {SPAN} at (0,0) size 0x0
-      RenderBlock {DIV} at (0,690) size 769x36
+      RenderBlock {DIV} at (0,626) size 769x36
         RenderBlock (anonymous) at (0,0) size 769x18
           RenderInline {SPAN} at (0,0) size 41x18
             RenderText {#text} at (0,0) size 41x18
               text run at (0,0) width 41: "Text..."
         RenderBlock (anonymous) at (0,18) size 769x18
           RenderTable at (0,0) size 103x18
-            RenderTableSection (anonymous) at (0,0) size 103x0
-              RenderTableRow (anonymous) at (0,0) size 103x0
-                RenderTableCell (anonymous) at (0,0) size 103x0 [r=0 c=0 rs=1 cs=1]
-                  RenderBlock {DIV} at (0,0) size 103x0
             RenderTableSection {DIV} at (0,0) size 103x18
               RenderTableRow (anonymous) at (0,0) size 103x18
                 RenderTableCell (anonymous) at (0,0) size 103x18 [r=0 c=0 rs=1 cs=1]
                   RenderText {#text} at (0,0) size 103x18
                     text run at (0,0) width 103: "...continues here"
+          RenderBlock {DIV} at (0,18) size 769x0
         RenderBlock (anonymous) at (0,36) size 769x0
           RenderInline {SPAN} at (0,0) size 0x0
index 3874b99d6dd7835a2553a6bbaf05e2edc23d0a89..81356a0b2d634d1e9737ea3db388df1758663ac8 100644 (file)
@@ -1,3 +1,84 @@
+2008-05-29  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Dave Hyatt.
+
+        - speed up DHTML using lazy style resolution and rendere creation
+
+        This change introduces the concept of "lazy attach" - when a node
+        is lazy attached, then instead of resolving style and creating a
+        renderer right away, we just mark it as needing a style recalc.
+        
+        The patch makes use of this mechanism when inserting nodes directly
+        using DOM APIs from script. For now this is only done for the
+        JavaScript language binding but could also be done for other
+        bindings in the future.
+        
+        Lazy attach helps some common DHTML patterns - when a node is
+        added to the DOM, and then subsequently changed in a
+        style-affecting way, this causes an extra style recalc. This is a
+        fairly common pattern so it is better to be lazy.
+        
+        * bindings/js/JSNodeCustom.cpp:
+        (WebCore::JSNode::insertBefore): Request lazy attach.
+        (WebCore::JSNode::replaceChild): ditto
+        (WebCore::JSNode::appendChild): ditto
+        * dom/ContainerNode.cpp:
+        (WebCore::ContainerNode::insertBefore): Support lazy attach.
+        (WebCore::ContainerNode::replaceChild): ditto
+        (WebCore::ContainerNode::appendChild): ditto
+        (WebCore::ContainerNode::detach): Clear "changed child" bit if still set.
+        * dom/ContainerNode.h:
+        * dom/Element.cpp:
+        (WebCore::Element::recalcStyle): Adjusted to properly reattach a
+        lazy-attached node.
+        * dom/Node.cpp:
+        (WebCore::Node::insertBefore): Extra parameter for lazy attach
+        (still doesn't do anything).
+        (WebCore::Node::replaceChild): ditto
+        (WebCore::Node::appendChild): ditto
+        (WebCore::Node::setChanged): Unrelated but obvious optimization -
+        stop marking ancestor as having a changed child once we already reach
+        an ancestor so marked.
+        (WebCore::outermostLazyAttachedAncestor): Helper function for lazyAttach.
+        (WebCore::Node::lazyAttach): Implement lazy attach.
+        (WebCore::Node::canLazyAttach): Virtual method - true for most nodes.
+        * dom/Node.h:
+        * dom/Text.cpp:
+        (WebCore::Text::recalcStyle): Properly handle the case of a reattached node.
+        * html/HTMLEmbedElement.h:
+        (WebCore::HTMLEmbedElement::canLazyAttach): Refuse lazy attach, since
+        plugins and frames do important work at rederer creation time.
+        * html/HTMLFrameElementBase.h:
+        (WebCore::HTMLFrameElementBase::canLazyAttach): Refuse lazy attach, since
+        plugins and frames do important work at rederer creation time.
+        * html/HTMLFrameSetElement.cpp:
+        (WebCore::HTMLFrameSetElement::recalcStyle): Change order so that
+        reattach works properly.
+        * html/HTMLObjectElement.h:
+        (WebCore::HTMLObjectElement::canLazyAttach): Refuse lazy attach, since
+        plugins and frames do important work at rederer creation time.
+        * html/HTMLOptGroupElement.cpp:
+        (WebCore::HTMLOptGroupElement::insertBefore): Pass along extra param.
+        (WebCore::HTMLOptGroupElement::replaceChild): ditto
+        (WebCore::HTMLOptGroupElement::appendChild): ditto
+        * html/HTMLOptGroupElement.h:
+        * html/HTMLSelectElement.cpp:
+        (WebCore::HTMLSelectElement::insertBefore): Pass along extra param.
+        (WebCore::HTMLSelectElement::replaceChild): ditto
+        (WebCore::HTMLSelectElement::appendChild): ditto
+        * html/HTMLSelectElement.h:
+        * svg/SVGLocatable.cpp:
+        (WebCore::SVGLocatable::getBBox): Add missing updateLayout call.
+        * svg/SVGTextContentElement.cpp:
+        (WebCore::SVGTextContentElement::getNumberOfChars): ditto
+        (WebCore::SVGTextContentElement::getComputedTextLength): ditto
+        (WebCore::SVGTextContentElement::getSubStringLength): ditto
+        (WebCore::SVGTextContentElement::getStartPositionOfChar): ditto
+        (WebCore::SVGTextContentElement::getEndPositionOfChar): ditto
+        (WebCore::SVGTextContentElement::getExtentOfChar): ditto
+        (WebCore::SVGTextContentElement::getRotationOfChar): ditto
+        (WebCore::SVGTextContentElement::getCharNumAtPosition): ditto
+
 2008-05-28  Ada Chan  <adachan@apple.com>
 
         <rdar://problem/5957036> REGRESSION (r31960): 20-30% slowdown in i-Bench JavaScript test on XP Home
index c558145b71b5233d77acddd46e64180431e39210..4db46d78abd58a74b42a92c6d4a4f66f97b1eed1 100644 (file)
@@ -69,7 +69,7 @@ typedef int ExpectionCode;
 JSValue* JSNode::insertBefore(ExecState* exec, const List& args)
 {
     ExceptionCode ec = 0;
-    bool ok = impl()->insertBefore(toNode(args[0]), toNode(args[1]), ec);
+    bool ok = impl()->insertBefore(toNode(args[0]), toNode(args[1]), ec, true);
     setDOMException(exec, ec);
     if (ok)
         return args[0];
@@ -79,7 +79,7 @@ JSValue* JSNode::insertBefore(ExecState* exec, const List& args)
 JSValue* JSNode::replaceChild(ExecState* exec, const List& args)
 {
     ExceptionCode ec = 0;
-    bool ok = impl()->replaceChild(toNode(args[0]), toNode(args[1]), ec);
+    bool ok = impl()->replaceChild(toNode(args[0]), toNode(args[1]), ec, true);
     setDOMException(exec, ec);
     if (ok)
         return args[1];
@@ -99,7 +99,7 @@ JSValue* JSNode::removeChild(ExecState* exec, const List& args)
 JSValue* JSNode::appendChild(ExecState* exec, const List& args)
 {
     ExceptionCode ec = 0;
-    bool ok = impl()->appendChild(toNode(args[0]), ec);
+    bool ok = impl()->appendChild(toNode(args[0]), ec, true);
     setDOMException(exec, ec);
     if (ok)
         return args[0];
index 7082fe6928c038c7b32a4eb3c57867044dac89c4..2942acfd159eb386cf6eeb46212c676a5d0d6897 100644 (file)
@@ -128,7 +128,7 @@ Node* ContainerNode::virtualLastChild() const
     return m_lastChild;
 }
 
-bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode& ec)
+bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode& ec, bool shouldLazyAttach)
 {
     // Check that this node is not "floating".
     // If it is, it can be deleted as a side effect of sending mutation events.
@@ -138,7 +138,7 @@ bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
 
     // insertBefore(node, 0) is equivalent to appendChild(node)
     if (!refChild)
-        return appendChild(newChild, ec);
+        return appendChild(newChild, ec, shouldLazyAttach);
 
     // Make sure adding the new child is OK.
     checkAddChild(newChild.get(), ec);
@@ -217,8 +217,12 @@ bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
         dispatchChildInsertionEvents(child.get(), ec);
                 
         // Add child to the rendering tree.
-        if (attached() && !child->attached() && child->parent() == this)
-            child->attach();
+        if (attached() && !child->attached() && child->parent() == this) {
+            if (shouldLazyAttach)
+                child->lazyAttach();
+            else
+                child->attach();
+        }
 
         child = nextChild.release();
     }
@@ -230,7 +234,7 @@ bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
     return true;
 }
 
-bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode& ec)
+bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode& ec, bool shouldLazyAttach)
 {
     // Check that this node is not "floating".
     // If it is, it can be deleted as a side effect of sending mutation events.
@@ -327,8 +331,12 @@ bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce
         dispatchChildInsertionEvents(child.get(), ec);
                 
         // Add child to the rendering tree
-        if (attached() && !child->attached() && child->parent() == this)
-            child->attach();
+        if (attached() && !child->attached() && child->parent() == this) {
+            if (shouldLazyAttach)
+                child->lazyAttach();
+            else
+                child->attach();
+        }
 
         prev = child;
         child = nextChild.release();
@@ -502,7 +510,7 @@ bool ContainerNode::removeChildren()
     return true;
 }
 
-bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec)
+bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bool shouldLazyAttach)
 {
     // Check that this node is not "floating".
     // If it is, it can be deleted as a side effect of sending mutation events.
@@ -562,8 +570,12 @@ bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec)
         dispatchChildInsertionEvents(child.get(), ec);
 
         // Add child to the rendering tree
-        if (attached() && !child->attached() && child->parent() == this)
-            child->attach();
+        if (attached() && !child->attached() && child->parent() == this) {
+            if (shouldLazyAttach)
+                child->lazyAttach();
+            else
+                child->attach();
+        }
         
         child = nextChild.release();
     }
@@ -655,6 +667,7 @@ void ContainerNode::detach()
 {
     for (Node* child = m_firstChild; child; child = child->nextSibling())
         child->detach();
+    setHasChangedChild(false);
     EventTargetNode::detach();
 }
 
index 28563f29550f3d52c26b1327958eef84356d1354..70429fa5d651558d53b2080ceb9377163e5982a3 100644 (file)
@@ -38,10 +38,10 @@ public:
     Node* firstChild() const { return m_firstChild; }
     Node* lastChild() const { return m_lastChild; }
 
-    virtual bool insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode&);
-    virtual bool replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode&);
+    virtual bool insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode&, bool shouldLazyAttach = false);
+    virtual bool replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode&, bool shouldLazyAttach = false);
     virtual bool removeChild(Node* child, ExceptionCode&);
-    virtual bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&);
+    virtual bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&, bool shouldLazyAttach = false);
 
     virtual ContainerNode* addChild(PassRefPtr<Node>);
     bool hasChildNodes() const { return m_firstChild; }
index a32794b29448914ff29ae102d428335928d2036c..525202dcd005db18ead31cec82b2604cc4c0a44b 100644 (file)
@@ -757,7 +757,7 @@ void Element::recalcStyle(StyleChange change)
     if (hasParentStyle && (change >= Inherit || changed())) {
         RenderStyle *newStyle = document()->styleSelector()->styleForElement(this);
         StyleChange ch = diff(currentStyle, newStyle);
-        if (ch == Detach) {
+        if (ch == Detach || !currentStyle) {
             if (attached())
                 detach();
             // ### Suboptimal. Style gets calculated again.
index cd91ec407e0539f3a9ad2b0ffeaadf56f222270a..ab7c5b4f303012f8075eb3b0eb17c1a1749dc074 100644 (file)
@@ -244,13 +244,13 @@ Node* Node::firstDescendant() const
     return n;
 }
 
-bool Node::insertBefore(PassRefPtr<Node>, Node*, ExceptionCode& ec)
+bool Node::insertBefore(PassRefPtr<Node>, Node*, ExceptionCode& ec, bool)
 {
     ec = HIERARCHY_REQUEST_ERR;
     return false;
 }
 
-bool Node::replaceChild(PassRefPtr<Node>, Node*, ExceptionCode& ec)
+bool Node::replaceChild(PassRefPtr<Node>, Node*, ExceptionCode& ec, bool)
 {
     ec = HIERARCHY_REQUEST_ERR;
     return false;
@@ -262,7 +262,7 @@ bool Node::removeChild(Node*, ExceptionCode& ec)
     return false;
 }
 
-bool Node::appendChild(PassRefPtr<Node>, ExceptionCode& ec)
+bool Node::appendChild(PassRefPtr<Node>, ExceptionCode& ec, bool)
 {
     ec = HIERARCHY_REQUEST_ERR;
     return false;
@@ -383,12 +383,52 @@ void Node::setChanged(StyleChangeType changeType)
         m_styleChange = changeType;
 
     if (m_styleChange != NoStyleChange) {
-        for (Node* p = parentNode(); p; p = p->parentNode())
+        for (Node* p = parentNode(); p && !p->hasChangedChild(); p = p->parentNode())
             p->setHasChangedChild(true);
         document()->setDocumentChanged(true);
     }
 }
 
+static Node* outermostLazyAttachedAncestor(Node* start)
+{
+    Node* p = start;
+    for (Node* next = p->parentNode(); !next->renderer(); p = next, next = next->parentNode()) {}
+    return p;
+}
+
+void Node::lazyAttach()
+{
+    bool mustDoFullAttach = false;
+
+    for (Node* n = this; n; n = n->traverseNextNode(this)) {
+        if (!n->canLazyAttach()) {
+            mustDoFullAttach = true;
+            break;
+        }
+
+        if (n->firstChild())
+            n->setHasChangedChild(true);
+        n->m_styleChange = FullStyleChange;
+        n->m_attached = true;
+    }
+
+    if (mustDoFullAttach) {
+        Node* lazyAttachedAncestor = outermostLazyAttachedAncestor(this);
+        if (lazyAttachedAncestor->attached())
+            lazyAttachedAncestor->detach();
+        lazyAttachedAncestor->attach();
+    } else {
+        for (Node* p = parentNode(); p && !p->hasChangedChild(); p = p->parentNode())
+            p->setHasChangedChild(true);
+        document()->setDocumentChanged(true);
+    }
+}
+
+bool Node::canLazyAttach()
+{
+    return shadowAncestorNode() == this;
+}
+
 bool Node::isFocusable() const
 {
     return m_tabIndexSetExplicitly;
index cd1792ed2d8c3f907c7cd0e78288d46bb0250fd2..2494b45a27add1d57bbba6b5acc51a672bcf0255 100644 (file)
@@ -114,10 +114,10 @@ public:
     // These should all actually return a node, but this is only important for language bindings,
     // which will already know and hold a ref on the right node to return. Returning bool allows
     // these methods to be more efficient since they don't need to return a ref
-    virtual bool insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode&);
-    virtual bool replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode&);
+    virtual bool insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode&, bool shouldLazyAttach = false);
+    virtual bool replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode&, bool shouldLazyAttach = false);
     virtual bool removeChild(Node* child, ExceptionCode&);
-    virtual bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&);
+    virtual bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&, bool shouldLazyAttach = false);
 
     virtual void remove(ExceptionCode&);
     bool hasChildNodes() const { return firstChild(); }
@@ -248,6 +248,9 @@ public:
     void setInActiveChain(bool b = true) { m_inActiveChain = b; }
     void setChanged(StyleChangeType changeType = FullStyleChange);
 
+    void lazyAttach();
+    virtual bool canLazyAttach();
+
     virtual void setFocus(bool b = true) { m_focused = b; }
     virtual void setActive(bool b = true, bool pause=false) { m_active = b; }
     virtual void setHovered(bool b = true) { m_hovered = b; }
index 61f90c300233810f9b015ada1d2f15cf4744b798..723997ec73f16763dc5b0b56cfbdc0d3124b1943 100644 (file)
@@ -248,8 +248,16 @@ void Text::recalcStyle(StyleChange change)
         if (renderer())
             renderer()->setStyle(parentNode()->renderer()->style());
     }
-    if (changed() && renderer() && renderer()->isText())
-        static_cast<RenderText*>(renderer())->setText(m_data);
+    if (changed()) {
+        if (renderer()) {
+            if (renderer()->isText())
+                static_cast<RenderText*>(renderer())->setText(m_data);
+        } else {
+            if (attached())
+                detach();
+            attach();
+        }
+    }
     setChanged(NoStyleChange);
 }
 
index c852bd5d53269a2525bc34bdfd680563c7f2a900..fb4bc4d42d69f7e083d6d25ae631abc5af118b6c 100644 (file)
@@ -47,6 +47,7 @@ public:
     virtual void parseMappedAttribute(MappedAttribute*);
 
     virtual void attach();
+    virtual bool canLazyAttach() { return false; }
     virtual void detach();
     virtual bool rendererIsNeeded(RenderStyle*);
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
index 62b7bd8e81232e5ec983769cbd1a4503fd6b45d3..4a2445141c730903d3c59246c5cbdec6fcd7630c 100644 (file)
@@ -37,6 +37,7 @@ public:
     virtual void removedFromDocument();
 
     virtual void attach();
+    virtual bool canLazyAttach() { return false; }
 
     KURL location() const;
     void setLocation(const String&);
index 1bd15a9680b8bc530f250c248a6547dd0d39a49b..71a8e827546a4fb4c291ec2d2c6193d380de26a5 100644 (file)
@@ -187,11 +187,11 @@ void HTMLFrameSetElement::defaultEventHandler(Event* evt)
 
 void HTMLFrameSetElement::recalcStyle(StyleChange ch)
 {
+    HTMLElement::recalcStyle(ch);
     if (changed() && renderer()) {
         renderer()->setNeedsLayout(true);
         setChanged(NoStyleChange);
     }
-    HTMLElement::recalcStyle(ch);
 }
 
 String HTMLFrameSetElement::cols() const
index 295f6e2d7e29dac7b6938de5c4b5db280d9fa570..f50c0383af2981e2f34188cba3a1eeaa154007fd 100644 (file)
@@ -41,6 +41,7 @@ public:
     virtual void parseMappedAttribute(MappedAttribute*);
 
     virtual void attach();
+    virtual bool canLazyAttach() { return false; }
     virtual bool rendererIsNeeded(RenderStyle*);
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
     virtual void finishParsingChildren();
index 7132ae0a1006c9977c99fbfd6e7bf5a404c773c4..afa230ca2e3eb11a9e567b3ee01fea8abe2041cc 100644 (file)
@@ -52,17 +52,17 @@ const AtomicString& HTMLOptGroupElement::type() const
     return optgroup;
 }
 
-bool HTMLOptGroupElement::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode& ec)
+bool HTMLOptGroupElement::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode& ec, bool shouldLazyAttach)
 {
-    bool result = HTMLGenericFormElement::insertBefore(newChild, refChild, ec);
+    bool result = HTMLGenericFormElement::insertBefore(newChild, refChild, ec, shouldLazyAttach);
     if (result)
         recalcSelectOptions();
     return result;
 }
 
-bool HTMLOptGroupElement::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode& ec)
+bool HTMLOptGroupElement::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode& ec, bool shouldLazyAttach)
 {
-    bool result = HTMLGenericFormElement::replaceChild(newChild, oldChild, ec);
+    bool result = HTMLGenericFormElement::replaceChild(newChild, oldChild, ec, shouldLazyAttach);
     if (result)
         recalcSelectOptions();
     return result;
@@ -76,9 +76,9 @@ bool HTMLOptGroupElement::removeChild(Node* oldChild, ExceptionCode& ec)
     return result;
 }
 
-bool HTMLOptGroupElement::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec)
+bool HTMLOptGroupElement::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bool shouldLazyAttach)
 {
-    bool result = HTMLGenericFormElement::appendChild(newChild, ec);
+    bool result = HTMLGenericFormElement::appendChild(newChild, ec, shouldLazyAttach);
     if (result)
         recalcSelectOptions();
     return result;
index c635a323530957e330d52f6c7ca65ea26738f069..f7124ead88255680b50ec98dc399a77022206754 100644 (file)
@@ -44,10 +44,10 @@ public:
     virtual RenderStyle* renderStyle() const { return m_style; }
     virtual void setRenderStyle(RenderStyle*);
 
-    virtual bool insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode&);
-    virtual bool replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode&);
+    virtual bool insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode&, bool shouldLazyAttach = false);
+    virtual bool replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode&, bool shouldLazyAttach = false);
     virtual bool removeChild(Node* child, ExceptionCode&);
-    virtual bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&);
+    virtual bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&, bool shouldLazyAttach = false);
     virtual bool removeChildren();
     virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
 
index 6a7cebc84482af76939b709abf64b72da3b8368b..3f7799b298658dd1cd9b747bd0ca7187389523eb 100644 (file)
@@ -302,17 +302,17 @@ void HTMLSelectElement::restoreState(const String& state)
     setChanged();
 }
 
-bool HTMLSelectElement::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode& ec)
+bool HTMLSelectElement::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode& ec, bool shouldLazyAttach)
 {
-    bool result = HTMLFormControlElementWithState::insertBefore(newChild, refChild, ec);
+    bool result = HTMLFormControlElementWithState::insertBefore(newChild, refChild, ec, shouldLazyAttach);
     if (result)
         setRecalcListItems();
     return result;
 }
 
-bool HTMLSelectElement::replaceChild(PassRefPtr<Node> newChild, Node *oldChild, ExceptionCode& ec)
+bool HTMLSelectElement::replaceChild(PassRefPtr<Node> newChild, Node *oldChild, ExceptionCode& ec, bool shouldLazyAttach)
 {
-    bool result = HTMLFormControlElementWithState::replaceChild(newChild, oldChild, ec);
+    bool result = HTMLFormControlElementWithState::replaceChild(newChild, oldChild, ec, shouldLazyAttach);
     if (result)
         setRecalcListItems();
     return result;
@@ -326,9 +326,9 @@ bool HTMLSelectElement::removeChild(Node* oldChild, ExceptionCode& ec)
     return result;
 }
 
-bool HTMLSelectElement::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec)
+bool HTMLSelectElement::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bool shouldLazyAttach)
 {
-    bool result = HTMLFormControlElementWithState::appendChild(newChild, ec);
+    bool result = HTMLFormControlElementWithState::appendChild(newChild, ec, shouldLazyAttach);
     if (result)
         setRecalcListItems();
     return result;
index 3117e0ff046f3e2755a2a5324c6bcf3a0f390539..af142e44380d90a461fa350f6c2d7f15c3dc77f6 100644 (file)
@@ -82,10 +82,10 @@ public:
     virtual bool saveState(String& value) const;
     virtual void restoreState(const String&);
 
-    virtual bool insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode&);
-    virtual bool replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode&);
+    virtual bool insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode&, bool shouldLazyAttach = false);
+    virtual bool replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode&, bool shouldLazyAttach = false);
     virtual bool removeChild(Node* child, ExceptionCode&);
-    virtual bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&);
+    virtual bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&, bool shouldLazyAttach = false);
     virtual bool removeChildren();
     virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
 
index 91564a55a1525dc4ca4d55729fa0651c976c9724..65192fa1f3a296ad0a00a8e04ce8f02aeecfd54a 100644 (file)
@@ -87,10 +87,11 @@ FloatRect SVGLocatable::getBBox(const SVGStyledElement* e)
 {
     FloatRect bboxRect;
 
+    e->document()->updateLayoutIgnorePendingStylesheets();
+
     if (e && e->renderer()) {
         // Need this to make sure we have render object dimensions.
         // See bug 11686.
-        e->document()->updateLayoutIgnorePendingStylesheets();
         bboxRect = e->renderer()->relativeBBox(false);
     }
 
index 2ebf4b9b0d8b843c661271ead42aa2bb35a1c714..3eddb2d666eab91b9c1f12a046d91802827f3361 100644 (file)
@@ -369,16 +369,22 @@ static inline SVGInlineTextBoxQueryWalker executeTextQuery(const SVGTextContentE
 
 long SVGTextContentElement::getNumberOfChars() const
 {
+    document()->updateLayoutIgnorePendingStylesheets();
+
     return executeTextQuery(this, SVGInlineTextBoxQueryWalker::NumberOfCharacters).longResult();
 }
 
 float SVGTextContentElement::getComputedTextLength() const
 {
+    document()->updateLayoutIgnorePendingStylesheets();
+
     return executeTextQuery(this, SVGInlineTextBoxQueryWalker::TextLength).floatResult();
 }
 
 float SVGTextContentElement::getSubStringLength(long charnum, long nchars, ExceptionCode& ec) const
 {
+    document()->updateLayoutIgnorePendingStylesheets();
+
     // Differences to SVG 1.1 spec, as the spec is clearly wrong. TODO: Raise SVG WG issue!
     // #1: We accept a 'long nchars' parameter instead of 'unsigned long nchars' to be able
     //     to catch cases where someone called us with a negative 'nchars' value - in those
@@ -401,6 +407,8 @@ float SVGTextContentElement::getSubStringLength(long charnum, long nchars, Excep
 
 FloatPoint SVGTextContentElement::getStartPositionOfChar(long charnum, ExceptionCode& ec) const
 {
+    document()->updateLayoutIgnorePendingStylesheets();
+
     if (charnum < 0 || charnum > getNumberOfChars()) {
         ec = INDEX_SIZE_ERR;
         return FloatPoint();
@@ -411,6 +419,8 @@ FloatPoint SVGTextContentElement::getStartPositionOfChar(long charnum, Exception
 
 FloatPoint SVGTextContentElement::getEndPositionOfChar(long charnum, ExceptionCode& ec) const
 {
+    document()->updateLayoutIgnorePendingStylesheets();
+
     if (charnum < 0 || charnum > getNumberOfChars()) {
         ec = INDEX_SIZE_ERR;
         return FloatPoint();
@@ -421,6 +431,8 @@ FloatPoint SVGTextContentElement::getEndPositionOfChar(long charnum, ExceptionCo
 
 FloatRect SVGTextContentElement::getExtentOfChar(long charnum, ExceptionCode& ec) const
 {
+    document()->updateLayoutIgnorePendingStylesheets();
+
     if (charnum < 0 || charnum > getNumberOfChars()) {
         ec = INDEX_SIZE_ERR;
         return FloatRect();
@@ -431,6 +443,8 @@ FloatRect SVGTextContentElement::getExtentOfChar(long charnum, ExceptionCode& ec
 
 float SVGTextContentElement::getRotationOfChar(long charnum, ExceptionCode& ec) const
 {
+    document()->updateLayoutIgnorePendingStylesheets();
+
     if (charnum < 0 || charnum > getNumberOfChars()) {
         ec = INDEX_SIZE_ERR;
         return 0.0f;
@@ -441,6 +455,8 @@ float SVGTextContentElement::getRotationOfChar(long charnum, ExceptionCode& ec)
 
 long SVGTextContentElement::getCharNumAtPosition(const FloatPoint& point) const
 {
+    document()->updateLayoutIgnorePendingStylesheets();
+
     return executeTextQuery(this, SVGInlineTextBoxQueryWalker::CharacterNumberAtPosition, 0.0f, 0.0f, point).longResult();
 }