Commit bf259502 authored by mjs@apple.com's avatar mjs@apple.com

WebCore:

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
parent 1e23d36d
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.
......@@ -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)]
......
b848821df77004913ca9911a4295871d
\ No newline at end of file
4cff5283c5881787befeab5eccf5c139
\ No newline at end of file
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
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
......@@ -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];
......
......@@ -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();
}
......
......@@ -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; }
......
......@@ -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.
......
......@@ -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;
......
......@@ -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; }
......
......@@ -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 {