2011-04-07 Dominic Cooney <dominicc@google.com>
authortkent@chromium.org <tkent@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 8 Apr 2011 06:03:31 +0000 (06:03 +0000)
committertkent@chromium.org <tkent@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 8 Apr 2011 06:03:31 +0000 (06:03 +0000)
        Reviewed by Dimitri Glazkov.

        Let shadow DOM have a list of nodes at the top level of a shadow.
        https://bugs.webkit.org/show_bug.cgi?id=57813

        * fast/dom/HTMLKeygenElement/keygen-expected.txt: shadow DOM changed
        * fast/dom/HTMLKeygenElement/keygen.html: added assertion on shadow
2011-04-07  Dominic Cooney  <dominicc@google.com>

        Reviewed by Dimitri Glazkov.

        Let shadow DOM have a list of nodes at the top level of a shadow.
        https://bugs.webkit.org/show_bug.cgi?id=57813

        Adds ShadowRoot, a list of nodes, to be a parent for top-level
        shadow children. Forwards rendering through the root and into the
        host's renderer.

        Covered by existing tests of elements that use this style of shadow.

        * Android.mk: add ShadowRoot.h/cpp
        * CMakeLists.txt:
        * GNUmakefile.am:
        * WebCore.exp.in:
        * WebCore.gypi:
        * WebCore.pro:
        * WebCore.vcproj/WebCore.vcproj:
        * WebCore.xcodeproj/project.pbxproj:
        * css/CSSStyleSelector.cpp:
        (WebCore::CSSStyleSelector::initForStyleResolve): proxy style to host
        * dom/ContainerNode.cpp: parent nodes that are shadow roots are alive
        (WebCore::ContainerNode::insertBefore):
        (WebCore::ContainerNode::replaceChild):
        (WebCore::ContainerNode::removeChild):
        (WebCore::ContainerNode::appendChild):
        * dom/DocumentFragment.cpp:
        (WebCore::DocumentFragment::DocumentFragment):
        * dom/DocumentFragment.h:
        * dom/Element.cpp:
        (WebCore::Element::recalcStyle): look through ShadowRoots for host's style
        (WebCore::Element::shadowRoot): should be const
        (WebCore::Element::ensureShadowRoot): simpler than setShadowRoot
        * dom/Element.h:
        * dom/ElementRareData.h:
        * dom/Node.cpp:
        (WebCore::Node::parentNodeForRenderingAndStyle): indirection so
          ShadowRoot can forward to the host's renderer
        (WebCore::Node::createRendererAndStyle):
        (WebCore::Node::createRendererIfNeeded):
        * dom/Node.h:
        (WebCore::Node::isShadowBoundary): temporary, to differentiate
          old- and new-style, until all roots are ShadowRoot instances
        * dom/ShadowRoot.cpp: Added.
        (WebCore::ShadowRoot::ShadowRoot):
        (WebCore::ShadowRoot::recalcStyle): forward recalc to children
        * dom/ShadowRoot.h: Added.
        (WebCore::ShadowRoot::isShadowBoundary):
        (WebCore::ShadowRoot::create):
        * html/HTMLKeygenElement.cpp: use ensureShadowRoot
        (WebCore::HTMLKeygenElement::HTMLKeygenElement):
        (WebCore::HTMLKeygenElement::parseMappedAttribute):
        (WebCore::HTMLKeygenElement::appendFormData):
        (WebCore::HTMLKeygenElement::reset):
        (WebCore::HTMLKeygenElement::shadowSelect):
        * html/HTMLKeygenElement.h:
        * html/HTMLMeterElement.cpp: use ensureShadowRoot
        (WebCore::HTMLMeterElement::createShadowSubtree):
        * html/HTMLProgressElement.cpp: use ensureShadowRoot
        (WebCore::HTMLProgressElement::createShadowSubtree):
        * html/InputType.cpp: use ensureShadowRoot
        (WebCore::InputType::destroyShadowSubtree):
        * html/RangeInputType.cpp: use ensureShadowRoot
        (WebCore::RangeInputType::handleMouseDownEvent):
        (WebCore::RangeInputType::createShadowSubtree):
        (WebCore::RangeInputType::valueChanged):
        (WebCore::RangeInputType::shadowSliderThumb):
        * html/RangeInputType.h:
        * html/ValidationMessage.cpp: use ensureShadowRoot
        (WebCore::ValidationMessage::buildBubbleTree):
        (WebCore::ValidationMessage::deleteBubbleTree):
        * html/shadow/SliderThumbElement.cpp:
        (WebCore::SliderThumbElement::setPositionFromPoint):
        (WebCore::SliderThumbElement::hostInput):
        * html/shadow/SliderThumbElement.h:
        * rendering/MediaControlElements.cpp: use ensureShadowRoot
        (WebCore::MediaControlInputElement::attach):
        (WebCore::MediaControlInputElement::updateStyle):
        * rendering/RenderSlider.cpp: use ensureShadowRoot
        (WebCore::RenderSlider::thumbRect):
        (WebCore::RenderSlider::layout):
        (WebCore::RenderSlider::shadowSliderThumb):
        (WebCore::RenderSlider::inDragMode):
        * rendering/RenderSlider.h:
2011-04-07  Dominic Cooney  <dominicc@google.com>

        Reviewed by Dimitri Glazkov.

        Let shadow DOM have a list of nodes at the top level of a shadow.
        https://bugs.webkit.org/show_bug.cgi?id=57813

        * src/WebElement.cpp:
        (WebKit::WebElement::shadowRoot): shadow roots are ContainerNodes now

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

39 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/dom/HTMLKeygenElement/keygen-expected.txt
LayoutTests/fast/dom/HTMLKeygenElement/keygen.html
Source/WebCore/Android.mk
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/GNUmakefile.am
Source/WebCore/WebCore.exp.in
Source/WebCore/WebCore.gypi
Source/WebCore/WebCore.pro
Source/WebCore/WebCore.vcproj/WebCore.vcproj
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/css/CSSStyleSelector.cpp
Source/WebCore/dom/ContainerNode.cpp
Source/WebCore/dom/DOMAllInOne.cpp
Source/WebCore/dom/DocumentFragment.cpp
Source/WebCore/dom/DocumentFragment.h
Source/WebCore/dom/Element.cpp
Source/WebCore/dom/Element.h
Source/WebCore/dom/ElementRareData.h
Source/WebCore/dom/Node.cpp
Source/WebCore/dom/Node.h
Source/WebCore/dom/ShadowRoot.cpp [new file with mode: 0644]
Source/WebCore/dom/ShadowRoot.h [new file with mode: 0644]
Source/WebCore/html/HTMLKeygenElement.cpp
Source/WebCore/html/HTMLKeygenElement.h
Source/WebCore/html/HTMLMeterElement.cpp
Source/WebCore/html/HTMLProgressElement.cpp
Source/WebCore/html/InputType.cpp
Source/WebCore/html/RangeInputType.cpp
Source/WebCore/html/RangeInputType.h
Source/WebCore/html/ValidationMessage.cpp
Source/WebCore/html/shadow/SliderThumbElement.cpp
Source/WebCore/html/shadow/SliderThumbElement.h
Source/WebCore/rendering/MediaControlElements.cpp
Source/WebCore/rendering/RenderSlider.cpp
Source/WebCore/rendering/RenderSlider.h
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/src/WebElement.cpp

index 5154bb0..b92d46c 100644 (file)
@@ -1,3 +1,13 @@
+2011-04-07  Dominic Cooney  <dominicc@google.com>
+
+        Reviewed by Dimitri Glazkov.
+
+        Let shadow DOM have a list of nodes at the top level of a shadow.
+        https://bugs.webkit.org/show_bug.cgi?id=57813
+
+        * fast/dom/HTMLKeygenElement/keygen-expected.txt: shadow DOM changed
+        * fast/dom/HTMLKeygenElement/keygen.html: added assertion on shadow
+
 2011-04-07  Maciej Stachowiak  <mjs@apple.com>
 
         Reviewed by Simon Fraser.
index 745f016..a8b2ee5 100644 (file)
@@ -2,8 +2,9 @@
 This tests the keygen element.
 
 PASS keygen.options is undefined
-PASS shadow.tagName is "SELECT"
-PASS layoutTestController.shadowRoot(shadow) is null
+PASS shadow.firstChild.tagName is "SELECT"
+PASS layoutTestController.shadowRoot(shadow) is undefined
+PASS layoutTestController.shadowRoot(shadow.firstChild) is null
 PASS successfullyParsed is true
 
 TEST COMPLETE
index ed9cdca..cb88316 100644 (file)
@@ -15,8 +15,9 @@ shouldBe('keygen.options', 'undefined');  // keygen is not a select
 
 if (window.layoutTestController) {
   var shadow = layoutTestController.shadowRoot(keygen);
-  shouldBe('shadow.tagName', '"SELECT"');
-  shouldBe('layoutTestController.shadowRoot(shadow)', 'null');
+  shouldBe('shadow.firstChild.tagName', '"SELECT"');
+  shouldBe('layoutTestController.shadowRoot(shadow)', 'undefined');
+  shouldBe('layoutTestController.shadowRoot(shadow.firstChild)', 'null');
 }
 
 var successfullyParsed = true;
index 9288177..ed63e2b 100644 (file)
@@ -175,6 +175,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
        dom/ScriptRunner.cpp \
        dom/SelectElement.cpp \
        dom/SelectorNodeList.cpp \
+       dom/ShadowRoot.cpp \
        dom/SpaceSplitString.cpp \
        dom/StaticHashSetNodeList.cpp \
        dom/StaticNodeList.cpp \
index 900a792..b5180c9 100644 (file)
@@ -603,6 +603,7 @@ SET(WebCore_SOURCES
     dom/ScriptRunner.cpp
     dom/SelectElement.cpp
     dom/SelectorNodeList.cpp
+    dom/ShadowRoot.cpp
     dom/SpaceSplitString.cpp
     dom/StaticHashSetNodeList.cpp
     dom/StaticNodeList.cpp
index e393ff4..4379107 100644 (file)
@@ -1,3 +1,90 @@
+2011-04-07  Dominic Cooney  <dominicc@google.com>
+
+        Reviewed by Dimitri Glazkov.
+
+        Let shadow DOM have a list of nodes at the top level of a shadow.
+        https://bugs.webkit.org/show_bug.cgi?id=57813
+
+        Adds ShadowRoot, a list of nodes, to be a parent for top-level
+        shadow children. Forwards rendering through the root and into the
+        host's renderer.
+
+        Covered by existing tests of elements that use this style of shadow.
+
+        * Android.mk: add ShadowRoot.h/cpp
+        * CMakeLists.txt:
+        * GNUmakefile.am:
+        * WebCore.exp.in:
+        * WebCore.gypi:
+        * WebCore.pro:
+        * WebCore.vcproj/WebCore.vcproj:
+        * WebCore.xcodeproj/project.pbxproj:
+        * css/CSSStyleSelector.cpp:
+        (WebCore::CSSStyleSelector::initForStyleResolve): proxy style to host
+        * dom/ContainerNode.cpp: parent nodes that are shadow roots are alive
+        (WebCore::ContainerNode::insertBefore):
+        (WebCore::ContainerNode::replaceChild):
+        (WebCore::ContainerNode::removeChild):
+        (WebCore::ContainerNode::appendChild):
+        * dom/DocumentFragment.cpp:
+        (WebCore::DocumentFragment::DocumentFragment):
+        * dom/DocumentFragment.h:
+        * dom/Element.cpp:
+        (WebCore::Element::recalcStyle): look through ShadowRoots for host's style
+        (WebCore::Element::shadowRoot): should be const
+        (WebCore::Element::ensureShadowRoot): simpler than setShadowRoot
+        * dom/Element.h:
+        * dom/ElementRareData.h:
+        * dom/Node.cpp:
+        (WebCore::Node::parentNodeForRenderingAndStyle): indirection so
+          ShadowRoot can forward to the host's renderer
+        (WebCore::Node::createRendererAndStyle):
+        (WebCore::Node::createRendererIfNeeded):
+        * dom/Node.h:
+        (WebCore::Node::isShadowBoundary): temporary, to differentiate
+          old- and new-style, until all roots are ShadowRoot instances
+        * dom/ShadowRoot.cpp: Added.
+        (WebCore::ShadowRoot::ShadowRoot):
+        (WebCore::ShadowRoot::recalcStyle): forward recalc to children
+        * dom/ShadowRoot.h: Added.
+        (WebCore::ShadowRoot::isShadowBoundary):
+        (WebCore::ShadowRoot::create):
+        * html/HTMLKeygenElement.cpp: use ensureShadowRoot
+        (WebCore::HTMLKeygenElement::HTMLKeygenElement):
+        (WebCore::HTMLKeygenElement::parseMappedAttribute):
+        (WebCore::HTMLKeygenElement::appendFormData):
+        (WebCore::HTMLKeygenElement::reset):
+        (WebCore::HTMLKeygenElement::shadowSelect):
+        * html/HTMLKeygenElement.h:
+        * html/HTMLMeterElement.cpp: use ensureShadowRoot
+        (WebCore::HTMLMeterElement::createShadowSubtree):
+        * html/HTMLProgressElement.cpp: use ensureShadowRoot
+        (WebCore::HTMLProgressElement::createShadowSubtree):
+        * html/InputType.cpp: use ensureShadowRoot
+        (WebCore::InputType::destroyShadowSubtree):
+        * html/RangeInputType.cpp: use ensureShadowRoot
+        (WebCore::RangeInputType::handleMouseDownEvent):
+        (WebCore::RangeInputType::createShadowSubtree):
+        (WebCore::RangeInputType::valueChanged):
+        (WebCore::RangeInputType::shadowSliderThumb):
+        * html/RangeInputType.h:
+        * html/ValidationMessage.cpp: use ensureShadowRoot
+        (WebCore::ValidationMessage::buildBubbleTree):
+        (WebCore::ValidationMessage::deleteBubbleTree):
+        * html/shadow/SliderThumbElement.cpp:
+        (WebCore::SliderThumbElement::setPositionFromPoint):
+        (WebCore::SliderThumbElement::hostInput):
+        * html/shadow/SliderThumbElement.h:
+        * rendering/MediaControlElements.cpp: use ensureShadowRoot
+        (WebCore::MediaControlInputElement::attach):
+        (WebCore::MediaControlInputElement::updateStyle):
+        * rendering/RenderSlider.cpp: use ensureShadowRoot
+        (WebCore::RenderSlider::thumbRect):
+        (WebCore::RenderSlider::layout):
+        (WebCore::RenderSlider::shadowSliderThumb):
+        (WebCore::RenderSlider::inDragMode):
+        * rendering/RenderSlider.h:
+
 2011-04-07  Maciej Stachowiak  <mjs@apple.com>
 
         Reviewed by Simon Fraser.
index 7e17eb0..923262f 100644 (file)
@@ -1331,6 +1331,8 @@ webcore_sources += \
        Source/WebCore/dom/SelectElement.h \
        Source/WebCore/dom/SelectorNodeList.cpp \
        Source/WebCore/dom/SelectorNodeList.h \
+       Source/WebCore/dom/ShadowRoot.cpp \
+       Source/WebCore/dom/ShadowRoot.h \
        Source/WebCore/dom/SpaceSplitString.cpp \
        Source/WebCore/dom/SpaceSplitString.h \
        Source/WebCore/dom/StaticHashSetNodeList.cpp \
index 8d3146a..1e62a51 100644 (file)
@@ -800,7 +800,6 @@ __ZN7WebCore6WidgetD2Ev
 __ZN7WebCore6toNodeEN3JSC7JSValueE
 __ZN7WebCore7Console21shouldPrintExceptionsEv
 __ZN7WebCore7Console24setShouldPrintExceptionsEb
-__ZN7WebCore7Element10shadowRootEv
 __ZN7WebCore7IntRect5scaleEf
 __ZN7WebCore7IntRect5uniteERKS0_
 __ZN7WebCore7IntRect9intersectERKS0_
@@ -1252,6 +1251,7 @@ __ZNK7WebCore6Widget25convertToContainingWindowERKNS_7IntRectE
 __ZNK7WebCore6Widget25convertToContainingWindowERKNS_8IntPointE
 __ZNK7WebCore6Widget9frameRectEv
 __ZNK7WebCore7Element10screenRectEv
+__ZNK7WebCore7Element10shadowRootEv
 __ZNK7WebCore7Element12getAttributeERKNS_13QualifiedNameE
 __ZNK7WebCore7Element19boundsInWindowSpaceEv
 __ZNK7WebCore7Element9innerTextEv
index d800322..ccca479 100644 (file)
             'dom/RegisteredEventListener.h',
             'dom/ScriptExecutionContext.h',
             'dom/ScriptRunner.h',
+            'dom/ShadowRoot.h',
             'dom/SpaceSplitString.h',
             'dom/StyledElement.h',
             'dom/Text.h',
             'dom/SelectElement.h',
             'dom/SelectorNodeList.cpp',
             'dom/SelectorNodeList.h',
+            'dom/ShadowRoot.cpp',
+            'dom/ShadowRoot.h',
             'dom/SpaceSplitString.cpp',
             'dom/StaticHashSetNodeList.cpp',
             'dom/StaticHashSetNodeList.h',
index e62a940..df3369c 100644 (file)
@@ -534,6 +534,7 @@ SOURCES += \
     dom/ScriptRunner.cpp \
     dom/SelectElement.cpp \
     dom/SelectorNodeList.cpp \
+    dom/ShadowRoot.cpp \
     dom/SpaceSplitString.cpp \
     dom/StaticNodeList.cpp \
     dom/StyledElement.cpp \
@@ -1497,6 +1498,7 @@ HEADERS += \
     dom/ScriptExecutionContext.h \
     dom/SelectElement.h \
     dom/SelectorNodeList.h \
+    dom/ShadowRoot.h \
     dom/SpaceSplitString.h \
     dom/StaticNodeList.h \
     dom/StyledElement.h \
index 17530da..c2e3a54 100755 (executable)
                                >
                        </File>
                        <File
+                               RelativePath="..\dom\ShadowRoot.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\dom\ShadowRoot.h"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\dom\SpaceSplitString.cpp"
                                >
                                <FileConfiguration
index 8ba7e36..8fad1bf 100644 (file)
                A622A8FC122C44A600A785B3 /* BindingSecurityBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A622A8F6122C44A600A785B3 /* BindingSecurityBase.cpp */; };
                A622A8FD122C44A600A785B3 /* BindingSecurityBase.h in Headers */ = {isa = PBXBuildFile; fileRef = A622A8F7122C44A600A785B3 /* BindingSecurityBase.h */; };
                A622A8FF122C44A600A785B3 /* GenericBinding.h in Headers */ = {isa = PBXBuildFile; fileRef = A622A8F9122C44A600A785B3 /* GenericBinding.h */; };
+               A6D169621346B49B000EB770 /* ShadowRoot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A6D169611346B49B000EB770 /* ShadowRoot.cpp */; };
+               A6D169641346B4C1000EB770 /* ShadowRoot.h in Headers */ = {isa = PBXBuildFile; fileRef = A6D169631346B4C1000EB770 /* ShadowRoot.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A7151BD812F1558F005A0F64 /* TextCheckerClient.h in Headers */ = {isa = PBXBuildFile; fileRef = A7151BD712F1558F005A0F64 /* TextCheckerClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A715E652134BBBEC00D8E713 /* ProgressShadowElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A715E650134BBBEC00D8E713 /* ProgressShadowElement.cpp */; };
                A715E653134BBBEC00D8E713 /* ProgressShadowElement.h in Headers */ = {isa = PBXBuildFile; fileRef = A715E651134BBBEC00D8E713 /* ProgressShadowElement.h */; };
                A622A8F6122C44A600A785B3 /* BindingSecurityBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BindingSecurityBase.cpp; path = generic/BindingSecurityBase.cpp; sourceTree = "<group>"; };
                A622A8F7122C44A600A785B3 /* BindingSecurityBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BindingSecurityBase.h; path = generic/BindingSecurityBase.h; sourceTree = "<group>"; };
                A622A8F9122C44A600A785B3 /* GenericBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GenericBinding.h; path = generic/GenericBinding.h; sourceTree = "<group>"; };
+               A6D169611346B49B000EB770 /* ShadowRoot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ShadowRoot.cpp; sourceTree = "<group>"; };
+               A6D169631346B4C1000EB770 /* ShadowRoot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShadowRoot.h; sourceTree = "<group>"; };
                A7151BD712F1558F005A0F64 /* TextCheckerClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextCheckerClient.h; sourceTree = "<group>"; };
                A715E650134BBBEC00D8E713 /* ProgressShadowElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProgressShadowElement.cpp; sourceTree = "<group>"; };
                A715E651134BBBEC00D8E713 /* ProgressShadowElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProgressShadowElement.h; sourceTree = "<group>"; };
                                084AEBE30FB505FA0038483E /* SelectElement.h */,
                                BC7FA6800D1F167900DB22A9 /* SelectorNodeList.cpp */,
                                BC7FA67F0D1F167900DB22A9 /* SelectorNodeList.h */,
+                               A6D169611346B49B000EB770 /* ShadowRoot.cpp */,
+                               A6D169631346B4C1000EB770 /* ShadowRoot.h */,
                                D01A27AB10C9BFD800026A42 /* SpaceSplitString.cpp */,
                                D01A27AC10C9BFD800026A42 /* SpaceSplitString.h */,
                                CEA3949A11D45CDA003094CF /* StaticHashSetNodeList.cpp */,
                                BCD533640ED6848900887468 /* CachedScriptSourceProvider.h in Headers */,
                                BCB16C280979C3BD00467741 /* CachedXSLStyleSheet.h in Headers */,
                                93F1995008245E59001E9ABC /* CachePolicy.h in Headers */,
+                               B1D5ECB5134B58DA0087C78F /* CallbackFunction.h in Headers */,
                                6E4E91AD10F7FB3100A2779C /* CanvasContextAttributes.h in Headers */,
                                49484FC2102CF23C00187DD3 /* CanvasGradient.h in Headers */,
                                49484FC5102CF23C00187DD3 /* CanvasPattern.h in Headers */,
                                A8C228A111D5722E00D5A7D3 /* DecodedDataDocumentParser.h in Headers */,
                                4162A451101145AE00DFF3ED /* DedicatedWorkerContext.h in Headers */,
                                41A3D58F101C152D00316D07 /* DedicatedWorkerThread.h in Headers */,
+                               FD06DFA6134A4DEF006F5D7D /* DefaultAudioDestinationNode.h in Headers */,
+                               FD06DFA6134A4DEF006F5D7D /* DefaultAudioDestinationNode.h in Headers */,
                                BCC36EB91342AA3F004BEEF7 /* DefaultLocalizationStrategy.h in Headers */,
                                4167EBF6102962BA003D252A /* DefaultSharedWorkerRepository.h in Headers */,
                                FD31602C12B0267600C1A359 /* DelayDSPKernel.h in Headers */,
                                93F199E508245E59001E9ABC /* HTMLCanvasElement.h in Headers */,
                                A8DF3FD0097FA0FC0052981B /* HTMLCollection.h in Headers */,
                                977B3865122883E900B81FF8 /* HTMLConstructionSite.h in Headers */,
+                               E1A31663134BCAE8007C9A4F /* HTMLConverter.h in Headers */,
                                BC77CDBC0FEFF1420070887B /* HTMLDataGridCellElement.h in Headers */,
                                BC77CB870FEBF5AF0070887B /* HTMLDataGridColElement.h in Headers */,
                                BC212A1F0FE8333200EC3708 /* HTMLDataGridElement.h in Headers */,
                                9001788112E0370700648462 /* JSOESStandardDerivatives.h in Headers */,
                                6EBF0E7712A9868800DB1709 /* JSOESTextureFloat.h in Headers */,
                                77A17AA712F28B2A004E02F6 /* JSOESVertexArrayObject.h in Headers */,
+                               FDF6BAF9134A4C9800822920 /* JSOfflineAudioCompletionEvent.h in Headers */,
+                               FDF6BAF9134A4C9800822920 /* JSOfflineAudioCompletionEvent.h in Headers */,
                                A826E8AE0A1A8F2300CD1BB6 /* JSOptionConstructor.h in Headers */,
                                1A0D57410A5C7867007EDD4C /* JSOverflowEvent.h in Headers */,
                                E1284BB110449FFA00EAEB52 /* JSPageTransitionEvent.h in Headers */,
                                9001774112E0347800648462 /* OESStandardDerivatives.h in Headers */,
                                6EBF0E4912A8926100DB1709 /* OESTextureFloat.h in Headers */,
                                77A17A7212F28182004E02F6 /* OESVertexArrayObject.h in Headers */,
+                               FDA3E95A134A49EF008D4B5A /* OfflineAudioCompletionEvent.h in Headers */,
+                               FDA3E95A134A49EF008D4B5A /* OfflineAudioCompletionEvent.h in Headers */,
+                               FDA3E95C134A49EF008D4B5A /* OfflineAudioDestinationNode.h in Headers */,
+                               FDA3E95C134A49EF008D4B5A /* OfflineAudioDestinationNode.h in Headers */,
                                F4EAF4AF10C742B1009100D3 /* OpenTypeSanitizer.h in Headers */,
                                087281560F26B9B600AFC596 /* OptionElement.h in Headers */,
                                087281580F26B9B600AFC596 /* OptionGroupElement.h in Headers */,
                                0F3DD45012F5EA1B000D9190 /* ShadowBlur.h in Headers */,
                                BC5EB8C40E82031B00B25965 /* ShadowData.h in Headers */,
                                A7F338A411C0EFCA00A320A7 /* ShadowElement.h in Headers */,
+                               A6D169641346B4C1000EB770 /* ShadowRoot.h in Headers */,
                                A80E6CE80A1989CA007FB8C5 /* ShadowValue.h in Headers */,
                                B2AFFC940D00A5DF0030074D /* ShapeArabic.h in Headers */,
                                1A4A954E0B4EDCCB002D8C3C /* SharedBuffer.h in Headers */,
                                494BD7950F55C8EE00747828 /* WebKitPoint.h in Headers */,
                                31C0FF250E4CEB6E007D6FE5 /* WebKitTransitionEvent.h in Headers */,
                                0FCF332F0F2B9A25004B6795 /* WebLayer.h in Headers */,
+                               E1A3162D134BC32D007C9A4F /* WebNSAttributedStringExtras.h in Headers */,
                                1CAF34810A6C405200ABE06E /* WebScriptObject.h in Headers */,
                                1A569D1B0D7E2B82007C3983 /* WebScriptObject.h in Headers */,
                                1CAF34830A6C405200ABE06E /* WebScriptObjectPrivate.h in Headers */,
                                93F199ED08245E59001E9ABC /* XSLTProcessor.h in Headers */,
                                E1BE512E0CF6C512002EA959 /* XSLTUnicodeSort.h in Headers */,
                                977E2E0F12F0FC9C00C13379 /* XSSFilter.h in Headers */,
-                               FDA3E95A134A49EF008D4B5A /* OfflineAudioCompletionEvent.h in Headers */,
-                               FDA3E95C134A49EF008D4B5A /* OfflineAudioDestinationNode.h in Headers */,
-                               FDF6BAF9134A4C9800822920 /* JSOfflineAudioCompletionEvent.h in Headers */,
-                               FD06DFA6134A4DEF006F5D7D /* DefaultAudioDestinationNode.h in Headers */,
-                               E1A3162D134BC32D007C9A4F /* WebNSAttributedStringExtras.h in Headers */,
-                               E1A31663134BCAE8007C9A4F /* HTMLConverter.h in Headers */,
-                               B1D5ECB5134B58DA0087C78F /* CallbackFunction.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                D0D141B212B2BF5200E39620 /* CachedResourceRequest.cpp in Sources */,
                                BCB16C230979C3BD00467741 /* CachedScript.cpp in Sources */,
                                BCB16C270979C3BD00467741 /* CachedXSLStyleSheet.cpp in Sources */,
+                               B1827493134CA4C100B98C2D /* CallbackFunction.cpp in Sources */,
                                6E4E91AC10F7FB3100A2779C /* CanvasContextAttributes.cpp in Sources */,
                                49484FC1102CF23C00187DD3 /* CanvasGradient.cpp in Sources */,
                                49484FC4102CF23C00187DD3 /* CanvasPattern.cpp in Sources */,
                                A8C228A211D5722E00D5A7D3 /* DecodedDataDocumentParser.cpp in Sources */,
                                4162A450101145AE00DFF3ED /* DedicatedWorkerContext.cpp in Sources */,
                                41A3D58E101C152D00316D07 /* DedicatedWorkerThread.cpp in Sources */,
+                               FD06DFA5134A4DEF006F5D7D /* DefaultAudioDestinationNode.cpp in Sources */,
+                               FD06DFA5134A4DEF006F5D7D /* DefaultAudioDestinationNode.cpp in Sources */,
                                BCC36EB81342AA3F004BEEF7 /* DefaultLocalizationStrategy.cpp in Sources */,
                                4167EBF5102962BA003D252A /* DefaultSharedWorkerRepository.cpp in Sources */,
                                FD31602B12B0267600C1A359 /* DelayDSPKernel.cpp in Sources */,
                                9001788012E0370700648462 /* JSOESStandardDerivatives.cpp in Sources */,
                                6EBF0E7612A9868800DB1709 /* JSOESTextureFloat.cpp in Sources */,
                                77A17AA612F28B2A004E02F6 /* JSOESVertexArrayObject.cpp in Sources */,
+                               FDF6BAF8134A4C9800822920 /* JSOfflineAudioCompletionEvent.cpp in Sources */,
+                               FDF6BAF8134A4C9800822920 /* JSOfflineAudioCompletionEvent.cpp in Sources */,
                                A826EC480A1B0CBE00CD1BB6 /* JSOptionConstructor.cpp in Sources */,
                                1A0D57400A5C7867007EDD4C /* JSOverflowEvent.cpp in Sources */,
                                E1284BB210449FFA00EAEB52 /* JSPageTransitionEvent.cpp in Sources */,
                                9001774012E0347800648462 /* OESStandardDerivatives.cpp in Sources */,
                                6EBF0E4812A8926100DB1709 /* OESTextureFloat.cpp in Sources */,
                                77A17A7112F28182004E02F6 /* OESVertexArrayObject.cpp in Sources */,
+                               FDA3E959134A49EF008D4B5A /* OfflineAudioCompletionEvent.cpp in Sources */,
+                               FDA3E959134A49EF008D4B5A /* OfflineAudioCompletionEvent.cpp in Sources */,
+                               FDA3E95B134A49EF008D4B5A /* OfflineAudioDestinationNode.cpp in Sources */,
+                               FDA3E95B134A49EF008D4B5A /* OfflineAudioDestinationNode.cpp in Sources */,
                                F4EAF4AE10C742B1009100D3 /* OpenTypeSanitizer.cpp in Sources */,
                                087281550F26B9B600AFC596 /* OptionElement.cpp in Sources */,
                                087281570F26B9B600AFC596 /* OptionGroupElement.cpp in Sources */,
                                0F3DD44F12F5EA1B000D9190 /* ShadowBlur.cpp in Sources */,
                                BC5EB8C30E82031B00B25965 /* ShadowData.cpp in Sources */,
                                A7F338A311C0EFCA00A320A7 /* ShadowElement.cpp in Sources */,
+                               A6D169621346B49B000EB770 /* ShadowRoot.cpp in Sources */,
                                A80E6CF40A1989CA007FB8C5 /* ShadowValue.cpp in Sources */,
                                B2AFFC930D00A5DF0030074D /* ShapeArabic.c in Sources */,
                                1A4A954D0B4EDCCB002D8C3C /* SharedBuffer.cpp in Sources */,
                                93F1D5BA12D532C400832BEC /* WebKitLoseContext.cpp in Sources */,
                                31C0FF240E4CEB6E007D6FE5 /* WebKitTransitionEvent.cpp in Sources */,
                                0FCF332E0F2B9A25004B6795 /* WebLayer.mm in Sources */,
+                               E1A3162E134BC32D007C9A4F /* WebNSAttributedStringExtras.mm in Sources */,
                                1CAF34820A6C405200ABE06E /* WebScriptObject.mm in Sources */,
                                518A34C11026C831001B6896 /* WebSocket.cpp in Sources */,
                                510D4A4E103177A20049EA54 /* WebSocketChannel.cpp in Sources */,
                                93F19B0508245E59001E9ABC /* XSLTProcessorLibxslt.cpp in Sources */,
                                E1BE512D0CF6C512002EA959 /* XSLTUnicodeSort.cpp in Sources */,
                                977E2E0E12F0FC9C00C13379 /* XSSFilter.cpp in Sources */,
-                               FDA3E959134A49EF008D4B5A /* OfflineAudioCompletionEvent.cpp in Sources */,
-                               FDA3E95B134A49EF008D4B5A /* OfflineAudioDestinationNode.cpp in Sources */,
-                               FDF6BAF8134A4C9800822920 /* JSOfflineAudioCompletionEvent.cpp in Sources */,
-                               FD06DFA5134A4DEF006F5D7D /* DefaultAudioDestinationNode.cpp in Sources */,
-                               E1A3162E134BC32D007C9A4F /* WebNSAttributedStringExtras.mm in Sources */,
-                               B1827493134CA4C100B98C2D /* CallbackFunction.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index 810fd32..a415f4e 100644 (file)
@@ -893,7 +893,7 @@ inline void CSSStyleSelector::initForStyleResolve(Element* e, RenderStyle* paren
 {
     m_checker.m_pseudoStyle = pseudoID;
 
-    m_parentNode = e ? e->parentOrHostNode() : 0;
+    m_parentNode = e ? e->parentNodeForRenderingAndStyle() : 0;
 
     if (parentStyle)
         m_parentStyle = parentStyle;
index ea03848..5659f9e 100644 (file)
@@ -104,7 +104,7 @@ bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
 {
     // Check that this node is not "floating".
     // If it is, it can be deleted as a side effect of sending mutation events.
-    ASSERT(refCount() || parentNode());
+    ASSERT(refCount() || parentOrHostNode());
 
     ec = 0;
 
@@ -244,7 +244,7 @@ bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce
 {
     // Check that this node is not "floating".
     // If it is, it can be deleted as a side effect of sending mutation events.
-    ASSERT(refCount() || parentNode());
+    ASSERT(refCount() || parentOrHostNode());
 
     ec = 0;
 
@@ -401,7 +401,7 @@ bool ContainerNode::removeChild(Node* oldChild, ExceptionCode& ec)
 {
     // Check that this node is not "floating".
     // If it is, it can be deleted as a side effect of sending mutation events.
-    ASSERT(refCount() || parentNode());
+    ASSERT(refCount() || parentOrHostNode());
 
     ec = 0;
 
@@ -561,7 +561,7 @@ bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bo
 {
     // Check that this node is not "floating".
     // If it is, it can be deleted as a side effect of sending mutation events.
-    ASSERT(refCount() || parentNode());
+    ASSERT(refCount() || parentOrHostNode());
 
     ec = 0;
 
index c6084ce..4a51d90 100644 (file)
 #include "ScriptableDocumentParser.cpp"
 #include "SelectElement.cpp"
 #include "SelectorNodeList.cpp"
+#include "ShadowRoot.cpp"
 #include "SpaceSplitString.cpp"
 #include "StaticHashSetNodeList.cpp"
 #include "StaticNodeList.cpp"
index c9c3020..e98ef9e 100644 (file)
@@ -31,7 +31,7 @@
 
 namespace WebCore {
 
-inline DocumentFragment::DocumentFragment(Document* document)
+DocumentFragment::DocumentFragment(Document* document)
     : ContainerNode(document)
 {
     ASSERT(document);
index d588b4e..f567536 100644 (file)
@@ -36,9 +36,10 @@ public:
     void parseHTML(const String&, Element* contextElement, FragmentScriptingPermission = FragmentScriptingAllowed);
     bool parseXML(const String&, Element* contextElement, FragmentScriptingPermission = FragmentScriptingAllowed);
 
-private:
+protected:
     DocumentFragment(Document*);
 
+private:
     virtual String nodeName() const;
     virtual NodeType nodeType() const;
     virtual PassRefPtr<Node> cloneNode(bool deep);
index b57f3d2..2f8dedc 100644 (file)
@@ -54,6 +54,7 @@
 #include "RenderView.h"
 #include "RenderWidget.h"
 #include "Settings.h"
+#include "ShadowRoot.h"
 #include "TextIterator.h"
 #include "WebKitAnimationList.h"
 #include "XMLNames.h"
@@ -1065,7 +1066,7 @@ void Element::recalcStyle(StyleChange change)
 {
     // Ref currentStyle in case it would otherwise be deleted when setRenderStyle() is called.
     RefPtr<RenderStyle> currentStyle(renderStyle());
-    bool hasParentStyle = parentOrHostNode() ? parentOrHostNode()->renderStyle() : false;
+    bool hasParentStyle = parentNodeForRenderingAndStyle() ? parentNodeForRenderingAndStyle()->renderStyle() : false;
     bool hasDirectAdjacentRules = currentStyle && currentStyle->childrenAffectedByDirectAdjacentRules();
 
     if ((change > NoChange || needsStyleRecalc())) {
@@ -1147,7 +1148,7 @@ void Element::recalcStyle(StyleChange change)
     }
     // FIXME: This does not care about sibling combinators. Will be necessary in XBL2 world.
     if (Node* shadow = shadowRoot()) {
-        if (change >= Inherit || shadow->isTextNode() || shadow->childNeedsStyleRecalc() || shadow->needsStyleRecalc()) {
+        if (change >= Inherit || shadow->childNeedsStyleRecalc() || shadow->needsStyleRecalc()) {
             parentPusher.push();
             shadow->recalcStyle(change);
         }
@@ -1157,28 +1158,24 @@ void Element::recalcStyle(StyleChange change)
     clearChildNeedsStyleRecalc();
 }
 
-Node* Element::shadowRoot()
+ContainerNode* Element::shadowRoot() const
 {
     return hasRareData() ? rareData()->m_shadowRoot : 0;
 }
 
-void Element::setShadowRoot(PassRefPtr<Node> node)
+ContainerNode* Element::ensureShadowRoot()
 {
-    // FIXME: Because today this is never called from script directly, we don't have to worry
-    // about compromising DOM tree integrity (eg. node being a parent of this). However,
-    // once we implement XBL2, we will have to add integrity checks here.
-    removeShadowRoot();
-
-    RefPtr<Node> newRoot = node;
-    if (!newRoot)
-        return;
+    if (ContainerNode* existingRoot = shadowRoot())
+        return existingRoot;
 
+    RefPtr<ShadowRoot> newRoot = ShadowRoot::create(document());
     ensureRareData()->m_shadowRoot = newRoot.get();
     newRoot->setShadowHost(this);
     if (inDocument())
         newRoot->insertedIntoDocument();
-    if (attached() && !newRoot->attached())
+    if (attached())
         newRoot->lazyAttach();
+    return newRoot.get();
 }
 
 void Element::removeShadowRoot()
index 618ad27..5907a1a 100644 (file)
@@ -229,8 +229,10 @@ public:
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
     virtual void recalcStyle(StyleChange = NoChange);
 
-    Node* shadowRoot();
-    void setShadowRoot(PassRefPtr<Node>);
+    ContainerNode* shadowRoot() const;
+    ContainerNode* ensureShadowRoot();
+    void removeShadowRoot();
+
     virtual const AtomicString& shadowPseudoId() const;
 
     RenderStyle* computedStyle(PseudoId = NOPSEUDO);
@@ -411,7 +413,6 @@ private:
     ElementRareData* ensureRareData();
 
     SpellcheckAttributeState spellcheckAttributeState() const;
-    void removeShadowRoot();
 
 private:
     mutable RefPtr<NamedNodeMap> m_attributeMap;
index 818a2c2..14ceef2 100644 (file)
@@ -30,6 +30,8 @@
 
 namespace WebCore {
 
+class ShadowRoot;
+
 class ElementRareData : public NodeRareData {
 public:
     ElementRareData();
@@ -42,7 +44,7 @@ public:
 
     IntSize m_minimumSizeForResizing;
     RefPtr<RenderStyle> m_computedStyle;
-    Node* m_shadowRoot;
+    ShadowRoot* m_shadowRoot;
 
     OwnPtr<DatasetDOMStringMap> m_datasetDOMStringMap;
     OwnPtr<ClassList> m_classList;
index 15cb8a8..1a5310f 100644 (file)
@@ -1402,18 +1402,25 @@ Node *Node::nextLeafNode() const
     return 0;
 }
 
+ContainerNode* Node::parentNodeForRenderingAndStyle() const
+{
+    ContainerNode* parent = parentOrHostNode();
+    return parent && parent->isShadowBoundary() ? parent->shadowHost() : parent;
+}
+
 RenderObject* Node::createRendererAndStyle()
 {
     ASSERT(!renderer());
     ASSERT(document()->shouldCreateRenderers());
 
-    ContainerNode* parent = parentOrHostNode();
+    ContainerNode* parent = parentNodeForRenderingAndStyle();
     ASSERT(parent);
+
     RenderObject* parentRenderer = parent->renderer();
 
     // FIXME: Ignoring canHaveChildren() in a case of isShadowRoot() might be wrong.
     // See https://bugs.webkit.org/show_bug.cgi?id=52423
-    if (!parentRenderer || (!parentRenderer->canHaveChildren() && !isShadowRoot()) || !parent->childShouldCreateRenderer(this))
+    if (!parentRenderer || (!parentRenderer->canHaveChildren() && !(isShadowRoot() || parentNode()->isShadowBoundary())) || !parent->childShouldCreateRenderer(this))
         return 0;
 
     RefPtr<RenderStyle> style = styleForRenderer();
@@ -1465,7 +1472,7 @@ void Node::createRendererIfNeeded()
         return;
 
     // Note: Adding newRenderer instead of renderer(). renderer() may be a child of newRenderer.
-    parentOrHostNode()->renderer()->addChild(newRenderer, nextRenderer());
+    parentNodeForRenderingAndStyle()->renderer()->addChild(newRenderer, nextRenderer());
 }
 
 PassRefPtr<RenderStyle> Node::styleForRenderer()
index c225dba..c492b4d 100644 (file)
@@ -203,6 +203,8 @@ public:
     virtual bool isCharacterDataNode() const { return false; }
     bool isDocumentNode() const;
     bool isShadowRoot() const { return getFlag(IsShadowRootFlag); }
+    // FIXME: Remove this when all shadow roots are ShadowRoots.
+    virtual bool isShadowBoundary() const { return false; }
     Node* shadowAncestorNode();
     Node* shadowTreeRootNode();
     bool isInShadowTree();
@@ -444,6 +446,7 @@ public:
     virtual bool rendererIsNeeded(RenderStyle*);
     virtual bool childShouldCreateRenderer(Node*) const { return true; }
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+    ContainerNode* parentNodeForRenderingAndStyle() const;
     
     // Wrapper for nodes that don't have a renderer, but still cache the style (like HTMLOptionElement).
     RenderStyle* renderStyle() const;
diff --git a/Source/WebCore/dom/ShadowRoot.cpp b/Source/WebCore/dom/ShadowRoot.cpp
new file mode 100644 (file)
index 0000000..eaf5808
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ShadowRoot.h"
+
+namespace WebCore {
+
+ShadowRoot::ShadowRoot(Document* document)
+    : DocumentFragment(document)
+{
+    ASSERT(document);
+}
+
+void ShadowRoot::recalcStyle(StyleChange change)
+{
+    for (Node* n = firstChild(); n; n = n->nextSibling())
+        n->recalcStyle(change);
+
+    clearNeedsStyleRecalc();
+    clearChildNeedsStyleRecalc();
+}
+
+}
diff --git a/Source/WebCore/dom/ShadowRoot.h b/Source/WebCore/dom/ShadowRoot.h
new file mode 100644 (file)
index 0000000..9ffddff
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ShadowRoot_h
+#define ShadowRoot_h
+
+#include "DocumentFragment.h"
+
+namespace WebCore {
+
+class Document;
+
+class ShadowRoot : public DocumentFragment {
+public:
+    static PassRefPtr<ShadowRoot> create(Document*);
+
+    virtual bool isShadowBoundary() const { return true; }
+    virtual void recalcStyle(StyleChange = NoChange);
+
+private:
+    ShadowRoot(Document*);
+};
+
+inline PassRefPtr<ShadowRoot> ShadowRoot::create(Document* document)
+{
+    return adoptRef(new ShadowRoot(document));
+}
+
+} // namespace
+
+#endif
index b90335e..29c9deb 100644 (file)
@@ -32,6 +32,7 @@
 #include "HTMLSelectElement.h"
 #include "HTMLOptionElement.h"
 #include "SSLKeyGenerator.h"
+#include "ShadowRoot.h"
 #include "Text.h"
 #include <wtf/StdLibExtras.h>
 
@@ -67,15 +68,18 @@ inline HTMLKeygenElement::HTMLKeygenElement(const QualifiedName& tagName, Docume
     ASSERT(hasTagName(keygenTag));
 
     // Create a select element with one option element for each key size.
-    RefPtr<HTMLSelectElement> select = KeygenSelectElement::create(document);
     Vector<String> keys;
     getSupportedKeySizes(keys);
+
+    RefPtr<HTMLSelectElement> select = KeygenSelectElement::create(document);
+    ExceptionCode ec = 0;
     for (size_t i = 0; i < keys.size(); ++i) {
         RefPtr<HTMLOptionElement> option = HTMLOptionElement::create(document, this->form());
-        select->parserAddChild(option);
-        option->parserAddChild(Text::create(document, keys[i]));
+        select->appendChild(option, ec);
+        option->appendChild(Text::create(document, keys[i]), ec);
     }
-    setShadowRoot(select);
+
+    ensureShadowRoot()->appendChild(select, ec);
 }
 
 PassRefPtr<HTMLKeygenElement> HTMLKeygenElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
@@ -87,7 +91,7 @@ void HTMLKeygenElement::parseMappedAttribute(Attribute* attr)
 {
     // Reflect disabled attribute on the shadow select element
     if (attr->name() == disabledAttr)
-        selectShadow()->setAttribute(attr->name(), attr->value());
+        shadowSelect()->setAttribute(attr->name(), attr->value());
 
     if (attr->name() == challengeAttr)
         m_challenge = attr->value();
@@ -102,7 +106,7 @@ bool HTMLKeygenElement::appendFormData(FormDataList& encoded_values, bool)
     // Only RSA is supported at this time.
     if (!m_keyType.isNull() && !equalIgnoringCase(m_keyType, "rsa"))
         return false;
-    String value = signedPublicKeyAndChallengeString(selectShadow()->selectedIndex(), m_challenge, document()->baseURL());
+    String value = signedPublicKeyAndChallengeString(shadowSelect()->selectedIndex(), m_challenge, document()->baseURL());
     if (value.isNull())
         return false;
     encoded_values.appendData(name(), value.utf8());
@@ -117,12 +121,14 @@ const AtomicString& HTMLKeygenElement::formControlType() const
 
 void HTMLKeygenElement::reset()
 {
-    static_cast<HTMLFormControlElement*>(selectShadow())->reset();
+    static_cast<HTMLFormControlElement*>(shadowSelect())->reset();
 }
 
-HTMLSelectElement* HTMLKeygenElement::selectShadow()
+HTMLSelectElement* HTMLKeygenElement::shadowSelect() const
 {
-    return static_cast<HTMLSelectElement*>(shadowRoot());
+    Node* shadow = shadowRoot();
+    ASSERT(shadow);
+    return shadow ? static_cast<HTMLSelectElement*>(shadow->firstChild()) : 0;
 }
 
 } // namespace
index 02003e8..88782c8 100644 (file)
@@ -51,7 +51,7 @@ private:
 
     virtual void reset();
 
-    HTMLSelectElement* selectShadow();
+    HTMLSelectElement* shadowSelect() const;
 
     AtomicString m_challenge;
     AtomicString m_keyType;
index 7687283..88b1622 100644 (file)
@@ -31,6 +31,7 @@
 #include "HTMLParserIdioms.h"
 #include "MeterShadowElement.h"
 #include "RenderMeter.h"
+#include "ShadowRoot.h"
 #include <wtf/StdLibExtras.h>
 
 namespace WebCore {
@@ -230,7 +231,7 @@ void HTMLMeterElement::createShadowSubtree()
     m_value = MeterValueElement::create(document());
     ExceptionCode ec = 0;
     bar->appendChild(m_value, ec);
-    setShadowRoot(bar);
+    ensureShadowRoot()->appendChild(bar, ec);
 }
 
 } // namespace
index dfb8d44..39b129b 100644 (file)
@@ -32,6 +32,7 @@
 #include "HTMLParserIdioms.h"
 #include "ProgressShadowElement.h"
 #include "RenderProgress.h"
+#include "ShadowRoot.h"
 #include <wtf/StdLibExtras.h>
 
 namespace WebCore {
@@ -137,9 +138,9 @@ void HTMLProgressElement::createShadowSubtree()
 {
     RefPtr<ProgressBarElement> bar = ProgressBarElement::create(document());
     m_value = ProgressValueElement::create(document());
-    ExceptionCode e = 0;
-    bar->appendChild(m_value, e);
-    setShadowRoot(bar);
+    ExceptionCode ec = 0;
+    bar->appendChild(m_value, ec);
+    ensureShadowRoot()->appendChild(bar, ec);
 }
 
 } // namespace
index e708a35..ba27408 100644 (file)
@@ -55,6 +55,7 @@
 #include "RenderObject.h"
 #include "ResetInputType.h"
 #include "SearchInputType.h"
+#include "ShadowRoot.h"
 #include "SubmitInputType.h"
 #include "TelephoneInputType.h"
 #include "TextInputType.h"
@@ -359,7 +360,7 @@ void InputType::createShadowSubtree()
 
 void InputType::destroyShadowSubtree()
 {
-    element()->setShadowRoot(0);
+    element()->removeShadowRoot();
 }
 
 double InputType::parseToDouble(const String&, double defaultValue) const
index f7ee674..28aaa77 100644 (file)
@@ -39,6 +39,7 @@
 #include "MouseEvent.h"
 #include "PlatformMouseEvent.h"
 #include "RenderSlider.h"
+#include "ShadowRoot.h"
 #include "SliderThumbElement.h"
 #include "StepRange.h"
 #include <limits>
@@ -148,7 +149,7 @@ void RangeInputType::handleMouseDownEvent(MouseEvent* event)
     if (event->button() != LeftButton || event->target() != element())
         return;
 
-    if (SliderThumbElement* thumb = toSliderThumbElement(element()->shadowRoot()))
+    if (SliderThumbElement* thumb = shadowSliderThumb())
         thumb->dragFrom(event->absoluteLocation());
 }
 
@@ -196,7 +197,8 @@ void RangeInputType::handleKeydownEvent(KeyboardEvent* event)
 
 void RangeInputType::createShadowSubtree()
 {
-    element()->setShadowRoot(SliderThumbElement::create(element()->document()));
+    ExceptionCode ec = 0;
+    element()->ensureShadowRoot()->appendChild(SliderThumbElement::create(element()->document()), ec);
 }
 
 RenderObject* RangeInputType::createRenderer(RenderArena* arena, RenderStyle*) const
@@ -241,7 +243,7 @@ void RangeInputType::minOrMaxAttributeChanged()
 
 void RangeInputType::valueChanged()
 {
-    toSliderThumbElement(element()->shadowRoot())->setPositionFromValue();
+    shadowSliderThumb()->setPositionFromValue();
 }
 
 String RangeInputType::fallbackValue()
@@ -265,4 +267,10 @@ bool RangeInputType::shouldRespectListAttribute()
     return true;
 }
 
+SliderThumbElement* RangeInputType::shadowSliderThumb() const
+{
+    Node* shadow = element()->shadowRoot();
+    return shadow ? toSliderThumbElement(shadow->firstChild()) : 0;
+}
+
 } // namespace WebCore
index 3752985..75e7a17 100644 (file)
@@ -35,6 +35,8 @@
 
 namespace WebCore {
 
+class SliderThumbElement;
+
 class RangeInputType : public InputType {
 public:
     static PassOwnPtr<InputType> create(HTMLInputElement*);
@@ -67,6 +69,8 @@ private:
     virtual String fallbackValue();
     virtual String sanitizeValue(const String& proposedValue);
     virtual bool shouldRespectListAttribute();
+
+    SliderThumbElement* shadowSliderThumb() const;
 };
 
 } // namespace WebCore
index 59a1467..48912d7 100644 (file)
@@ -40,6 +40,7 @@
 #include "Page.h"
 #include "RenderObject.h"
 #include "Settings.h"
+#include "ShadowRoot.h"
 #include "Text.h"
 #include <wtf/PassOwnPtr.h>
 
@@ -129,12 +130,7 @@ void ValidationMessage::buildBubbleTree(Timer<ValidationMessage>*)
     // contains non-absolute or non-fixed renderers as children.
     m_bubble->getInlineStyleDecl()->setProperty(CSSPropertyPosition, CSSValueAbsolute);
     ExceptionCode ec = 0;
-    // FIXME: We need a way to host multiple shadow roots in a single node, or
-    // to inherit an existing shadow tree.
-    if (host->shadowRoot())
-        host->shadowRoot()->appendChild(m_bubble.get(), ec);
-    else
-        host->setShadowRoot(m_bubble);
+    host->ensureShadowRoot()->appendChild(m_bubble.get(), ec);
 
     RefPtr<HTMLElement> clipper = ElementWithPseudoId::create(doc, "-webkit-validation-bubble-arrow-clipper");
     clipper->appendChild(ElementWithPseudoId::create(doc, "-webkit-validation-bubble-arrow"), ec);
@@ -161,12 +157,8 @@ void ValidationMessage::deleteBubbleTree(Timer<ValidationMessage>*)
     if (m_bubble) {
         m_bubbleMessage = 0;
         HTMLElement* host = toHTMLElement(m_element);
-        if (m_bubble->isShadowRoot())
-            host->setShadowRoot(0);
-        else {
-            ExceptionCode ec;
-            host->shadowRoot()->removeChild(m_bubble.get(), ec);
-        }
+        ExceptionCode ec;
+        host->shadowRoot()->removeChild(m_bubble.get(), ec);
         m_bubble = 0;
     }
     m_message = String();
index 6353259..8a06cb3 100644 (file)
@@ -105,7 +105,7 @@ void SliderThumbElement::dragFrom(const IntPoint& point)
 
 void SliderThumbElement::setPositionFromPoint(const IntPoint& point)
 {
-    HTMLInputElement* input = static_cast<HTMLInputElement*>(shadowHost());
+    HTMLInputElement* input = hostInput();
     ASSERT(input);
 
     if (!input->renderer() || !renderer())
@@ -198,6 +198,12 @@ void SliderThumbElement::detach()
     HTMLDivElement::detach();
 }
 
+HTMLInputElement* SliderThumbElement::hostInput()
+{
+    ASSERT(parentNode());
+    return static_cast<HTMLInputElement*>(parentNode()->shadowHost());
+}
+
 const AtomicString& SliderThumbElement::shadowPseudoId() const
 {
     DEFINE_STATIC_LOCAL(AtomicString, sliderThumb, ("-webkit-slider-thumb"));
index 9414ac4..2fa60cb 100644 (file)
@@ -41,6 +41,7 @@
 namespace WebCore {
 
 class HTMLElement;
+class HTMLInputElement;
 class Event;
 class FloatPoint;
 
@@ -62,6 +63,7 @@ private:
     void startDragging();
     void stopDragging();
     void setPositionFromPoint(const IntPoint&);
+    HTMLInputElement* hostInput();
 
     FloatPoint m_offsetToThumb;
     bool m_inDragMode;
index 49c4578..b8ad3d3 100644 (file)
@@ -456,7 +456,7 @@ void MediaControlInputElement::attach()
         parentNode()->renderer()->addChild(renderer, sibling ? sibling->renderer() : 0);
     }  
     ContainerNode::attach();
-    // FIXME: Currently, MeidaControlInput circumvents the normal attachment
+    // FIXME: Currently, MediaControlInput circumvents the normal attachment
     // and style recalc cycle and thus we need to add extra logic to be aware of
     // the shadow DOM. Remove this once all media controls are transitioned to use the regular
     // style calculation.
@@ -481,7 +481,7 @@ void MediaControlInputElement::updateStyle()
     else if (renderer())
         renderer()->setStyle(style.get());
 
-    // FIXME: Currently, MeidaControlInput circumvents the normal attachment
+    // FIXME: Currently, MediaControlInput circumvents the normal attachment
     // and style recalc cycle and thus we need to add extra logic to be aware of
     // the shadow DOM. Remove this once all media controls are transitioned to use
     // the new shadow DOM.
index 1661b7a..ad5ab1a 100644 (file)
@@ -33,6 +33,7 @@
 #include "HTMLParserIdioms.h"
 #include "MediaControlElements.h"
 #include "MouseEvent.h"
+#include "Node.h"
 #include "RenderLayer.h"
 #include "RenderTheme.h"
 #include "RenderView.h"
@@ -101,7 +102,7 @@ void RenderSlider::computePreferredLogicalWidths()
 
 IntRect RenderSlider::thumbRect()
 {
-    SliderThumbElement* thumbElement = sliderThumbElement();
+    SliderThumbElement* thumbElement = shadowSliderThumb();
     if (!thumbElement)
         return IntRect();
 
@@ -128,7 +129,7 @@ void RenderSlider::layout()
 {
     ASSERT(needsLayout());
 
-    SliderThumbElement* thumbElement = sliderThumbElement();
+    SliderThumbElement* thumbElement = shadowSliderThumb();
     RenderBox* thumb = thumbElement ? toRenderBox(thumbElement->renderer()) : 0;
 
     IntSize baseSize(borderAndPaddingWidth(), borderAndPaddingHeight());
@@ -176,14 +177,15 @@ void RenderSlider::layout()
     setNeedsLayout(false);
 }
 
-SliderThumbElement* RenderSlider::sliderThumbElement() const
+SliderThumbElement* RenderSlider::shadowSliderThumb() const
 {
-    return toSliderThumbElement(static_cast<Element*>(node())->shadowRoot());
+    Node* shadow = static_cast<Element*>(node())->shadowRoot();
+    return shadow ? toSliderThumbElement(shadow->firstChild()) : 0;
 }
 
 bool RenderSlider::inDragMode() const
 {
-    SliderThumbElement* thumbElement = sliderThumbElement();
+    SliderThumbElement* thumbElement = shadowSliderThumb();
     return thumbElement && thumbElement->inDragMode();
 }
 
index 0162b71..4e17f30 100644 (file)
@@ -46,8 +46,8 @@ namespace WebCore {
         virtual void layout();
 
         // FIXME: Eventually, the logic of manipulating slider thumb should move to
-        // SliderThumbElement and accessing sliderThumbElement should not be necessary in this class.
-        SliderThumbElement* sliderThumbElement() const;
+        // SliderThumbElement and accessing shadowSliderThumb should not be necessary in this class.
+        SliderThumbElement* shadowSliderThumb() const;
 
         virtual bool requiresForcedStyleRecalcPropagation() const { return true; }
     };
index b4f9803..07724ff 100644 (file)
@@ -1,3 +1,13 @@
+2011-04-07  Dominic Cooney  <dominicc@google.com>
+
+        Reviewed by Dimitri Glazkov.
+
+        Let shadow DOM have a list of nodes at the top level of a shadow.
+        https://bugs.webkit.org/show_bug.cgi?id=57813
+
+        * src/WebElement.cpp:
+        (WebKit::WebElement::shadowRoot): shadow roots are ContainerNodes now
+
 2011-04-07  Magnus Danielsson  <public@fuzzac.com>
 
         Reviewed by Darin Fisher.
index ee7ec09..66e3e95 100644 (file)
@@ -92,7 +92,7 @@ WebString WebElement::innerText() const
 
 WebNode WebElement::shadowRoot()
 {
-    return adoptRef(unwrap<Element>()->shadowRoot());
+    return adoptRef(static_cast<Node*>(unwrap<Element>()->shadowRoot()));
 }
 
 WebString WebElement::computeInheritedLanguage() const