WebCore:
authordsmith@webkit.org <dsmith@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 26 Dec 2007 00:46:46 +0000 (00:46 +0000)
committerdsmith@webkit.org <dsmith@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 26 Dec 2007 00:46:46 +0000 (00:46 +0000)
        Reviewed by Oliver.

        - http://bugs.webkit.org/show_bug.cgi?id=16587
        Implement the most useful part of the W3C Selectors API.

        * WebCore.xcodeproj/project.pbxproj:
        * css/CSSStyleSelector.h: Make Node a friend of CSSStyleSelector so it can use checkSelector()
        * dom/ChildNodeList.cpp:
        (WebCore::ChildNodeList::ChildNodeList): Change to being a DynamicNodeList
        * dom/ChildNodeList.h:
        * dom/ClassNodeList.cpp:
        (WebCore::ClassNodeList::ClassNodeList): Change to being a DynamicNodeList
        * dom/ClassNodeList.h:
        * dom/Document.idl: Add the new functions
        * dom/DynamicNodeList.cpp: Copied from WebCore/dom/NodeList.cpp.
        (WebCore::DynamicNodeList::DynamicNodeList): Rename NodeList to DynamicNodeList, to differentiate it from the new StaticNodeList
        (WebCore::DynamicNodeList::~DynamicNodeList):
        (WebCore::DynamicNodeList::recursiveLength):
        (WebCore::DynamicNodeList::itemForwardsFromCurrent):
        (WebCore::DynamicNodeList::itemBackwardsFromCurrent):
        (WebCore::DynamicNodeList::recursiveItem):
        (WebCore::DynamicNodeList::itemWithName):
        (WebCore::DynamicNodeList::rootNodeChildrenChanged):
        (WebCore::DynamicNodeList::Caches::Caches):
        (WebCore::DynamicNodeList::Caches::reset):
        * dom/DynamicNodeList.h: Copied from WebCore/dom/NodeList.h.
        (WebCore::DynamicNodeList::rootNodeAttributeChanged):
        * dom/Element.idl: Add the new functions
        * dom/NameNodeList.cpp: Change to being a DynamicNodeList
        (WebCore::NameNodeList::NameNodeList):
        * dom/NameNodeList.h:
        (WebCore::NameNodeList::rootNodeAttributeChanged):
        * dom/Node.cpp:
        (WebCore::TagNodeList::TagNodeList): Change to being a DynamicNodeList
        (WebCore::Node::registerDynamicNodeList):
        (WebCore::Node::unregisterDynamicNodeList):
        (WebCore::Node::getElementsByName):
        (WebCore::Node::getElementsByClassName):
        (WebCore::Node::querySelector): new
        (WebCore::Node::querySelectorAll): new
        * dom/Node.h:
        * dom/NodeList.cpp: Removed.
        * dom/NodeList.h: This is now an abstract superclass of DynamicNodeList and StaticNodeList
        (WebCore::NodeList::NodeList):
        (WebCore::NodeList::~NodeList):
        * dom/SelectorNodeList.cpp: Added.
        (WebCore::SelectorNodeList::SelectorNodeList): New StaticNodeList subclass that filters elements by CSS selector
        * dom/SelectorNodeList.h: Added.
        * dom/StaticNodeList.cpp: Added.
        (WebCore::StaticNodeList::length):
        (WebCore::StaticNodeList::item):
        (WebCore::StaticNodeList::itemWithName):
        * dom/StaticNodeList.h: Added.
        (WebCore::StaticNodeList::StaticNodeList):
        (WebCore::StaticNodeList::~StaticNodeList):

LayoutTests:

        Reviewed by Oliver.

        - http://bugs.webkit.org/show_bug.cgi?id=16587
        Implement the most useful part of the W3C Selectors API.

        * fast/dom/SelectorAPI: Copied from LayoutTests/fast/dom/getElementsByClassName.
        * fast/dom/SelectorAPI/dumpNodeList-expected.txt:
        * fast/dom/SelectorAPI/dumpNodeList.html: Modified to test querySelector and querySelectorAll instead of getElementsByClassName
        * fast/dom/Window/window-properties-expected.txt: Added querySelector and querySelectorAll

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

24 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/dom/SelectorAPI/dumpNodeList-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/SelectorAPI/dumpNodeList.html [new file with mode: 0644]
LayoutTests/fast/dom/Window/window-properties-expected.txt
WebCore/ChangeLog
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/css/CSSStyleSelector.h
WebCore/dom/ChildNodeList.cpp
WebCore/dom/ChildNodeList.h
WebCore/dom/ClassNodeList.cpp
WebCore/dom/ClassNodeList.h
WebCore/dom/Document.idl
WebCore/dom/DynamicNodeList.cpp [moved from WebCore/dom/NodeList.cpp with 81% similarity]
WebCore/dom/DynamicNodeList.h [new file with mode: 0644]
WebCore/dom/Element.idl
WebCore/dom/NameNodeList.cpp
WebCore/dom/NameNodeList.h
WebCore/dom/Node.cpp
WebCore/dom/Node.h
WebCore/dom/NodeList.h
WebCore/dom/SelectorNodeList.cpp [new file with mode: 0644]
WebCore/dom/SelectorNodeList.h [new file with mode: 0644]
WebCore/dom/StaticNodeList.cpp [new file with mode: 0644]
WebCore/dom/StaticNodeList.h [new file with mode: 0644]

index 489bc58fcd32cb0bd52c28cd5de6723ddc8bf59f..af7558e32530e953c58817b36a7e329d1bb424d2 100644 (file)
@@ -1,3 +1,15 @@
+2007-12-25  David Smith  <catfish.man@gmail.com> and Sam Weinig  <sam@webkit.org>
+
+        Reviewed by Oliver.
+        
+        - http://bugs.webkit.org/show_bug.cgi?id=16587
+        Implement the most useful part of the W3C Selectors API.
+
+        * fast/dom/SelectorAPI: Copied from LayoutTests/fast/dom/getElementsByClassName.
+        * fast/dom/SelectorAPI/dumpNodeList-expected.txt:
+        * fast/dom/SelectorAPI/dumpNodeList.html: Modified to test querySelector and querySelectorAll instead of getElementsByClassName
+        * fast/dom/Window/window-properties-expected.txt: Added querySelector and querySelectorAll
+
 2007-12-23  Darin Adler  <darin@apple.com>
 
         - updated results (character used for controls changed in r28945)
diff --git a/LayoutTests/fast/dom/SelectorAPI/dumpNodeList-expected.txt b/LayoutTests/fast/dom/SelectorAPI/dumpNodeList-expected.txt
new file mode 100644 (file)
index 0000000..4d2f20a
--- /dev/null
@@ -0,0 +1,42 @@
+Line 1
+Line 2
+Line 3
+
+line 4
+line 5
+
+[object HTMLDivElement], length: 1
+[object HTMLDivElement], [object HTMLDivElement], [object HTMLDivElement], [object HTMLParagraphElement], length: 4
+[object HTMLDivElement], [object HTMLDivElement], [object HTMLDivElement], [object HTMLDivElement], [object HTMLParagraphElement], length: 5
+Error: SYNTAX_ERR: DOM Exception 12
+Error: SYNTAX_ERR: DOM Exception 12
+Error: SYNTAX_ERR: DOM Exception 12
+Error: SYNTAX_ERR: DOM Exception 12
+Error: SYNTAX_ERR: DOM Exception 12
+length: 0
+[object HTMLDivElement], length: 1
+[object HTMLDivElement], [object HTMLParagraphElement], length: 2
+[object HTMLDivElement], [object HTMLParagraphElement], length: 2
+Error: SYNTAX_ERR: DOM Exception 12
+Error: SYNTAX_ERR: DOM Exception 12
+Error: SYNTAX_ERR: DOM Exception 12
+Error: SYNTAX_ERR: DOM Exception 12
+Error: SYNTAX_ERR: DOM Exception 12
+[object HTMLDivElement]
+[object HTMLDivElement]
+[object HTMLDivElement]
+Error: SYNTAX_ERR: DOM Exception 12
+Error: SYNTAX_ERR: DOM Exception 12
+Error: SYNTAX_ERR: DOM Exception 12
+Error: SYNTAX_ERR: DOM Exception 12
+Error: SYNTAX_ERR: DOM Exception 12
+TypeError: Null value
+[object HTMLDivElement]
+[object HTMLDivElement]
+[object HTMLDivElement]
+Error: SYNTAX_ERR: DOM Exception 12
+Error: SYNTAX_ERR: DOM Exception 12
+Error: SYNTAX_ERR: DOM Exception 12
+Error: SYNTAX_ERR: DOM Exception 12
+Error: SYNTAX_ERR: DOM Exception 12
+
diff --git a/LayoutTests/fast/dom/SelectorAPI/dumpNodeList.html b/LayoutTests/fast/dom/SelectorAPI/dumpNodeList.html
new file mode 100644 (file)
index 0000000..d267a73
--- /dev/null
@@ -0,0 +1,77 @@
+<html>
+<body>
+<div class="one">Line 1<div class="two">Line 2</div><p>Line <i>3</i></p></div>
+<div id="test" class="one two"><div id="test2" class="one two">line 4</div><p class="two">line 5</p></div>
+<p><ol id="console"></ol></p>
+<script type="text/javascript">
+    if (window.layoutTestController)
+        layoutTestController.dumpAsText();
+
+    function log(message)
+    {
+        var item = document.createElement("li");
+        item.appendChild(document.createTextNode(message));
+        document.getElementById("console").appendChild(item);
+    }
+    
+    Element.prototype.dump = function()
+    {
+        return this;
+    }
+    
+    NodeList.prototype.dump = function()
+    {
+        var result = "";
+        var i = 0;
+        for (; i < this.length; i++)
+            result += this[i] + ", ";
+        result += "length: " + i;
+        return result;
+    }
+
+    try {
+        var elm = document.getElementById("test");
+        
+        try { log(document.querySelectorAll("#test").dump());      } catch (e) { log(e) }
+        try { log(document.querySelectorAll(".two").dump());       } catch (e) { log(e) }
+        try { log(document.querySelectorAll(".one, .two").dump()); } catch (e) { log(e) }
+        try { log(document.querySelectorAll("@font-face").dump()); } catch (e) { log(e) }
+        try { log(document.querySelectorAll("").dump());           } catch (e) { log(e) }
+        try { log(document.querySelectorAll().dump());             } catch (e) { log(e) }
+        try { log(document.querySelectorAll(null).dump());         } catch (e) { log(e) }
+        try { log(document.querySelectorAll(undefined).dump());    } catch (e) { log(e) }
+
+        try { log(elm.querySelectorAll("#test").dump());           } catch (e) { log(e) }
+        try { log(elm.querySelectorAll("#test2").dump());          } catch (e) { log(e) }
+        try { log(elm.querySelectorAll(".two").dump());            } catch (e) { log(e) }
+        try { log(elm.querySelectorAll(".one, .two").dump());      } catch (e) { log(e) }
+        try { log(elm.querySelectorAll("@font-face").dump());      } catch (e) { log(e) }
+        try { log(elm.querySelectorAll("").dump());                } catch (e) { log(e) }
+        try { log(elm.querySelectorAll().dump());                  } catch (e) { log(e) }
+        try { log(elm.querySelectorAll(null).dump());              } catch (e) { log(e) }
+        try { log(elm.querySelectorAll(undefined).dump());         } catch (e) { log(e) }
+
+        try { log(document.querySelector("#test").dump());         } catch (e) { log(e) }
+        try { log(document.querySelector(".two").dump());          } catch (e) { log(e) }
+        try { log(document.querySelector(".one, .two").dump());    } catch (e) { log(e) }
+        try { log(document.querySelector("@font-face").dump());    } catch (e) { log(e) }
+        try { log(document.querySelector("").dump());              } catch (e) { log(e) }
+        try { log(document.querySelector().dump());                } catch (e) { log(e) }
+        try { log(document.querySelector(null).dump());            } catch (e) { log(e) }
+        try { log(document.querySelector(undefined).dump());       } catch (e) { log(e) }
+
+        try { log(elm.querySelector("#test").dump());              } catch (e) { log(e) }
+        try { log(elm.querySelector("#test2").dump());             } catch (e) { log(e) }
+        try { log(elm.querySelector(".two").dump());               } catch (e) { log(e) }
+        try { log(elm.querySelector(".one, .two").dump());         } catch (e) { log(e) }
+        try { log(elm.querySelector("@font-face").dump());         } catch (e) { log(e) }
+        try { log(elm.querySelector("").dump());                   } catch (e) { log(e) }
+        try { log(elm.querySelector().dump());                     } catch (e) { log(e) }
+        try { log(elm.querySelector(null).dump());                 } catch (e) { log(e) }
+        try { log(elm.querySelector(undefined).dump());            } catch (e) { log(e) }
+    } catch (ex) {
+        log("Exception: " + ex.description);
+    }
+</script>
+</body>
+</html>
index 0099c33286ff2b25d8cc22fd494017886d03a5b0..6b056364094f9708389fe9c025b956b4a35f63ea 100644 (file)
@@ -338,6 +338,8 @@ window.Document.prototype.queryCommandIndeterm [function]
 window.Document.prototype.queryCommandState [function]
 window.Document.prototype.queryCommandSupported [function]
 window.Document.prototype.queryCommandValue [function]
+window.Document.prototype.querySelector [function]
+window.Document.prototype.querySelectorAll [function]
 window.Document.prototype.removeChild [function]
 window.Document.prototype.removeEventListener [function]
 window.Document.prototype.replaceChild [function]
@@ -441,6 +443,8 @@ window.Element.prototype.isSupported [function]
 window.Element.prototype.lookupNamespaceURI [function]
 window.Element.prototype.lookupPrefix [function]
 window.Element.prototype.normalize [function]
+window.Element.prototype.querySelector [function]
+window.Element.prototype.querySelectorAll [function]
 window.Element.prototype.removeAttribute [function]
 window.Element.prototype.removeAttributeNS [function]
 window.Element.prototype.removeAttributeNode [function]
index 89822e04d3991521addf567092f9ea2d74493635..8468a80942e0487a188f75b1c52d259c900316c0 100644 (file)
@@ -1,3 +1,61 @@
+2007-12-25  David Smith  <catfish.man@gmail.com> and Sam Weinig  <sam@webkit.org>
+
+        Reviewed by Oliver.
+        
+        - http://bugs.webkit.org/show_bug.cgi?id=16587
+        Implement the most useful part of the W3C Selectors API.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * css/CSSStyleSelector.h: Make Node a friend of CSSStyleSelector so it can use checkSelector()
+        * dom/ChildNodeList.cpp:
+        (WebCore::ChildNodeList::ChildNodeList): Change to being a DynamicNodeList
+        * dom/ChildNodeList.h:
+        * dom/ClassNodeList.cpp:
+        (WebCore::ClassNodeList::ClassNodeList): Change to being a DynamicNodeList
+        * dom/ClassNodeList.h:
+        * dom/Document.idl: Add the new functions
+        * dom/DynamicNodeList.cpp: Copied from WebCore/dom/NodeList.cpp.
+        (WebCore::DynamicNodeList::DynamicNodeList): Rename NodeList to DynamicNodeList, to differentiate it from the new StaticNodeList
+        (WebCore::DynamicNodeList::~DynamicNodeList):
+        (WebCore::DynamicNodeList::recursiveLength):
+        (WebCore::DynamicNodeList::itemForwardsFromCurrent):
+        (WebCore::DynamicNodeList::itemBackwardsFromCurrent):
+        (WebCore::DynamicNodeList::recursiveItem):
+        (WebCore::DynamicNodeList::itemWithName):
+        (WebCore::DynamicNodeList::rootNodeChildrenChanged):
+        (WebCore::DynamicNodeList::Caches::Caches):
+        (WebCore::DynamicNodeList::Caches::reset):
+        * dom/DynamicNodeList.h: Copied from WebCore/dom/NodeList.h.
+        (WebCore::DynamicNodeList::rootNodeAttributeChanged):
+        * dom/Element.idl: Add the new functions
+        * dom/NameNodeList.cpp: Change to being a DynamicNodeList
+        (WebCore::NameNodeList::NameNodeList):
+        * dom/NameNodeList.h:
+        (WebCore::NameNodeList::rootNodeAttributeChanged):
+        * dom/Node.cpp:
+        (WebCore::TagNodeList::TagNodeList): Change to being a DynamicNodeList
+        (WebCore::Node::registerDynamicNodeList):
+        (WebCore::Node::unregisterDynamicNodeList):
+        (WebCore::Node::getElementsByName):
+        (WebCore::Node::getElementsByClassName):
+        (WebCore::Node::querySelector): new
+        (WebCore::Node::querySelectorAll): new
+        * dom/Node.h:
+        * dom/NodeList.cpp: Removed.
+        * dom/NodeList.h: This is now an abstract superclass of DynamicNodeList and StaticNodeList
+        (WebCore::NodeList::NodeList):
+        (WebCore::NodeList::~NodeList):
+        * dom/SelectorNodeList.cpp: Added.
+        (WebCore::SelectorNodeList::SelectorNodeList): New StaticNodeList subclass that filters elements by CSS selector
+        * dom/SelectorNodeList.h: Added.
+        * dom/StaticNodeList.cpp: Added.
+        (WebCore::StaticNodeList::length):
+        (WebCore::StaticNodeList::item):
+        (WebCore::StaticNodeList::itemWithName):
+        * dom/StaticNodeList.h: Added.
+        (WebCore::StaticNodeList::StaticNodeList):
+        (WebCore::StaticNodeList::~StaticNodeList):
+
 2007-12-25  Mark Rowe  <mrowe@apple.com>
 
         Reviewed by Sam Weinig.
index 325d1a7e1ea5aeeba101968b71ed0ed490518be2..dd91dce726c2c5aa3ae016bda84092a475c78b96 100644 (file)
                A818721E0977D3C0005826D9 /* NameNodeList.h in Headers */ = {isa = PBXBuildFile; fileRef = A81872130977D3C0005826D9 /* NameNodeList.h */; };
                A818721F0977D3C0005826D9 /* ContainerNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A81872140977D3C0005826D9 /* ContainerNode.cpp */; };
                A81872200977D3C0005826D9 /* ChildNodeList.h in Headers */ = {isa = PBXBuildFile; fileRef = A81872150977D3C0005826D9 /* ChildNodeList.h */; };
-               A81872210977D3C0005826D9 /* NodeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A81872160977D3C0005826D9 /* NodeList.cpp */; };
                A81872230977D3C0005826D9 /* NamedNodeMap.h in Headers */ = {isa = PBXBuildFile; fileRef = A81872180977D3C0005826D9 /* NamedNodeMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A81872240977D3C0005826D9 /* NameNodeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A81872190977D3C0005826D9 /* NameNodeList.cpp */; };
                A81872250977D3C0005826D9 /* ChildNodeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A818721A0977D3C0005826D9 /* ChildNodeList.cpp */; };
                BC772C4F0C4EB3040083285F /* MIMETypeRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = BC772C4D0C4EB3040083285F /* MIMETypeRegistry.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BC772C5E0C4EB3440083285F /* MIMETypeRegistryMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = BC772C5D0C4EB3440083285F /* MIMETypeRegistryMac.mm */; };
                BC7F44A80B9E324E00A9D081 /* ImageObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = BC7F44A70B9E324E00A9D081 /* ImageObserver.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               BC7FA6200D1F0CBD00DB22A9 /* DynamicNodeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC7FA61E0D1F0CBD00DB22A9 /* DynamicNodeList.cpp */; };
+               BC7FA6210D1F0CBD00DB22A9 /* DynamicNodeList.h in Headers */ = {isa = PBXBuildFile; fileRef = BC7FA61F0D1F0CBD00DB22A9 /* DynamicNodeList.h */; };
+               BC7FA62D0D1F0EFF00DB22A9 /* StaticNodeList.h in Headers */ = {isa = PBXBuildFile; fileRef = BC7FA62B0D1F0EFF00DB22A9 /* StaticNodeList.h */; };
+               BC7FA62E0D1F0EFF00DB22A9 /* StaticNodeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC7FA62C0D1F0EFF00DB22A9 /* StaticNodeList.cpp */; };
+               BC7FA6810D1F167900DB22A9 /* SelectorNodeList.h in Headers */ = {isa = PBXBuildFile; fileRef = BC7FA67F0D1F167900DB22A9 /* SelectorNodeList.h */; };
+               BC7FA6820D1F167900DB22A9 /* SelectorNodeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC7FA6800D1F167900DB22A9 /* SelectorNodeList.cpp */; };
                BC80C9870CD294EE00A0B7B3 /* CSSTimingFunctionValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC80C9850CD294EE00A0B7B3 /* CSSTimingFunctionValue.cpp */; };
                BC80C9880CD294EE00A0B7B3 /* CSSTimingFunctionValue.h in Headers */ = {isa = PBXBuildFile; fileRef = BC80C9860CD294EE00A0B7B3 /* CSSTimingFunctionValue.h */; };
                BC80C98B0CD2950500A0B7B3 /* AnimationController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC80C9890CD2950500A0B7B3 /* AnimationController.cpp */; };
                A81872130977D3C0005826D9 /* NameNodeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = NameNodeList.h; sourceTree = "<group>"; };
                A81872140977D3C0005826D9 /* ContainerNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ContainerNode.cpp; sourceTree = "<group>"; };
                A81872150977D3C0005826D9 /* ChildNodeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ChildNodeList.h; sourceTree = "<group>"; };
-               A81872160977D3C0005826D9 /* NodeList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = NodeList.cpp; sourceTree = "<group>"; };
                A81872180977D3C0005826D9 /* NamedNodeMap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = NamedNodeMap.h; sourceTree = "<group>"; };
                A81872190977D3C0005826D9 /* NameNodeList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = NameNodeList.cpp; sourceTree = "<group>"; };
                A818721A0977D3C0005826D9 /* ChildNodeList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ChildNodeList.cpp; sourceTree = "<group>"; };
                BC7B2AF80450824100A8000F /* ScrollBar.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = ScrollBar.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                BC7B2AF90450824100A8000F /* PlatformScrollBarMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PlatformScrollBarMac.mm; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                BC7F44A70B9E324E00A9D081 /* ImageObserver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ImageObserver.h; sourceTree = "<group>"; };
+               BC7FA61E0D1F0CBD00DB22A9 /* DynamicNodeList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DynamicNodeList.cpp; sourceTree = "<group>"; };
+               BC7FA61F0D1F0CBD00DB22A9 /* DynamicNodeList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DynamicNodeList.h; sourceTree = "<group>"; };
+               BC7FA62B0D1F0EFF00DB22A9 /* StaticNodeList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StaticNodeList.h; sourceTree = "<group>"; };
+               BC7FA62C0D1F0EFF00DB22A9 /* StaticNodeList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StaticNodeList.cpp; sourceTree = "<group>"; };
+               BC7FA67F0D1F167900DB22A9 /* SelectorNodeList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectorNodeList.h; sourceTree = "<group>"; };
+               BC7FA6800D1F167900DB22A9 /* SelectorNodeList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SelectorNodeList.cpp; sourceTree = "<group>"; };
                BC80C9850CD294EE00A0B7B3 /* CSSTimingFunctionValue.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSSTimingFunctionValue.cpp; sourceTree = "<group>"; };
                BC80C9860CD294EE00A0B7B3 /* CSSTimingFunctionValue.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSSTimingFunctionValue.h; sourceTree = "<group>"; };
                BC80C9890CD2950500A0B7B3 /* AnimationController.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AnimationController.cpp; sourceTree = "<group>"; };
                                A8185F3609765765005826D9 /* DOMImplementation.cpp */,
                                A8185F3309765765005826D9 /* DOMImplementation.h */,
                                93EEC1E909C2877700C515D1 /* DOMImplementation.idl */,
+                               BC7FA61E0D1F0CBD00DB22A9 /* DynamicNodeList.cpp */,
+                               BC7FA61F0D1F0CBD00DB22A9 /* DynamicNodeList.h */,
                                6550B699099DF0270090D781 /* EditingText.cpp */,
                                6550B69A099DF0270090D781 /* EditingText.h */,
                                A8C4A7F609D563270003AC8D /* Element.cpp */,
                                854FE72A0A2297BE0058D7AD /* NodeIterator.cpp */,
                                854FE72B0A2297BE0058D7AD /* NodeIterator.h */,
                                1A750D870A90E394000FF215 /* NodeIterator.idl */,
-                               A81872160977D3C0005826D9 /* NodeList.cpp */,
                                A81872100977D3C0005826D9 /* NodeList.h */,
                                85ACA9FA0A9B631000671E90 /* NodeList.idl */,
                                A8EA7EB70A1945D000A8EF5F /* Notation.cpp */,
                                D23CA5480AB0E983005108A5 /* RangeException.idl */,
                                85031B350A44EFC700F992E0 /* RegisteredEventListener.cpp */,
                                85031B360A44EFC700F992E0 /* RegisteredEventListener.h */,
+                               BC7FA6800D1F167900DB22A9 /* SelectorNodeList.cpp */,
+                               BC7FA67F0D1F167900DB22A9 /* SelectorNodeList.h */,
+                               BC7FA62C0D1F0EFF00DB22A9 /* StaticNodeList.cpp */,
+                               BC7FA62B0D1F0EFF00DB22A9 /* StaticNodeList.h */,
                                A8C4A7EC09D563270003AC8D /* StyledElement.cpp */,
                                A8C4A7EB09D563270003AC8D /* StyledElement.h */,
                                AA4C3A740B2B1679002334A2 /* StyleElement.cpp */,
                                93309E1E099E64920056E581 /* visible_units.h in Headers */,
                                BCA379150D163E5500B793D6 /* JSLocation.h in Headers */,
                                BCA3793F0D1647E000B793D6 /* JSLocation.lut.h in Headers */,
+                               BC7FA6210D1F0CBD00DB22A9 /* DynamicNodeList.h in Headers */,
+                               BC7FA62D0D1F0EFF00DB22A9 /* StaticNodeList.h in Headers */,
+                               BC7FA6810D1F167900DB22A9 /* SelectorNodeList.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                854FE7300A2297BE0058D7AD /* NodeFilter.cpp in Sources */,
                                854FE7320A2297BE0058D7AD /* NodeFilterCondition.cpp in Sources */,
                                854FE7340A2297BE0058D7AD /* NodeIterator.cpp in Sources */,
-                               A81872210977D3C0005826D9 /* NodeList.cpp in Sources */,
                                A8EA7EBF0A1945D000A8EF5F /* Notation.cpp in Sources */,
                                1A0D57360A5C77FE007EDD4C /* OverflowEvent.cpp in Sources */,
                                B27535640B053814002CE64F /* PDFDocumentImage.cpp in Sources */,
                                93309DF7099E64920056E581 /* markup.cpp in Sources */,
                                93309E1D099E64920056E581 /* visible_units.cpp in Sources */,
                                BCA379140D163E5500B793D6 /* JSLocation.cpp in Sources */,
+                               BC7FA6200D1F0CBD00DB22A9 /* DynamicNodeList.cpp in Sources */,
+                               BC7FA62E0D1F0EFF00DB22A9 /* StaticNodeList.cpp in Sources */,
+                               BC7FA6820D1F167900DB22A9 /* SelectorNodeList.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index a844e5c06eee6162141404be5e752d1c6dda1da2..1616aeffa3b0d528cd72308f28544829b56dddc9 100644 (file)
@@ -129,11 +129,11 @@ class StyledElement;
  
         CSSFontSelector* fontSelector() { return m_fontSelector.get(); }
 
-    protected:
-
         /* checks if a compound selector (which can consist of multiple simple selectors)
            matches the given Element */
-        bool checkSelector(CSSSelector* selector);
+        bool checkSelector(CSSSelector*);
+
+    protected:
         enum SelectorMatch { SelectorMatches=0, SelectorFailsLocally, SelectorFailsCompletely};
         SelectorMatch checkSelector(CSSSelector* selector, Element *e, bool isAncestor, bool isSubSelector);
 
@@ -242,6 +242,7 @@ class StyledElement;
 #endif
 
         friend class CSSRuleSet;
+        friend class Node;
     };
 
     class CSSRuleData {
index a171fecd5e12cd2cf116d071c78dc71d6b5cb64b..5b1d3e8bb4733ab5d0ad1794fd7fb2d3dbfe72b6 100644 (file)
@@ -30,8 +30,8 @@ using namespace WebCore;
 
 namespace WebCore {
 
-ChildNodeList::ChildNodeList(Node* n, NodeList::Caches* info)
-    : NodeList(n, info, false)
+ChildNodeList::ChildNodeList(Node* n, DynamicNodeList::Caches* info)
+    : DynamicNodeList(n, info, false)
 {
 }
 
index f32ae60408292a7832b38561c5893e9c93678352..b9e56c622e46ac34d08416ef96999b892029865a 100644 (file)
@@ -1,10 +1,8 @@
 /*
- * This file is part of the DOM implementation for KDE.
- *
  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
  *           (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004 Apple Computer, Inc.
+ * Copyright (C) 2004, 2007 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
  * Boston, MA 02110-1301, USA.
  *
  */
+
 #ifndef ChildNodeList_h
 #define ChildNodeList_h
 
-#include "NodeList.h"
+#include "DynamicNodeList.h"
 
 namespace WebCore {
 
-class ChildNodeList : public NodeList {
+class ChildNodeList : public DynamicNodeList {
 public:
-    ChildNodeList(Node*, NodeList::Caches*);
+    ChildNodeList(Node*, DynamicNodeList::Caches*);
 
     virtual unsigned length() const;
     virtual Node* item(unsigned index) const;
index 59d976bd630ef3f89f0dfbb8f0db3359e54d73d3..0e2184f11136220c7ad758d04bc9926e9ae36516 100644 (file)
@@ -36,8 +36,8 @@
 
 namespace WebCore {
 
-ClassNodeList::ClassNodeList(PassRefPtr<Node> rootNode, const String& classNames, NodeList::Caches* caches)
-    : NodeList(rootNode, caches, true)
+ClassNodeList::ClassNodeList(PassRefPtr<Node> rootNode, const String& classNames, DynamicNodeList::Caches* caches)
+    : DynamicNodeList(rootNode, caches, true)
 {
     m_classNames.parseClassAttribute(classNames, m_rootNode->document()->inCompatMode());
 }
index 5c631fcaca5f7c6a73abd22f4781dcd8107fdbfe..54bdd928d7ef344c7acd169e79dde8069af0a1e0 100644 (file)
 #define ClassNodeList_h
 
 #include "ClassNames.h"
-#include "NodeList.h"
+#include "DynamicNodeList.h"
 
 namespace WebCore {
 
     class String;
 
-    class ClassNodeList : public NodeList {
+    class ClassNodeList : public DynamicNodeList {
     public:
-        ClassNodeList(PassRefPtr<Node> rootNode, const String& classNames, NodeList::Caches*);
+        ClassNodeList(PassRefPtr<Node> rootNode, const String& classNames, DynamicNodeList::Caches*);
 
         virtual unsigned length() const;
         virtual Node* item(unsigned index) const;
index 544aedca9f49fe639af009834c050c6a4fbadc52..6de51d7e4c0314109b33b915d32509c0af9ae3fe 100644 (file)
@@ -222,6 +222,12 @@ module core {
 
         // HTML 5
         NodeList            getElementsByClassName(in DOMString tagname);
+
+        // DocumentSelector - Selector API
+        Element             querySelector(in [ConvertUndefinedOrNullToNullString] DOMString selectors)
+            raises(DOMException);
+        NodeList            querySelectorAll(in [ConvertUndefinedOrNullToNullString] DOMString selectors)
+            raises(DOMException);
     };
 
 }
similarity index 81%
rename from WebCore/dom/NodeList.cpp
rename to WebCore/dom/DynamicNodeList.cpp
index a44d0e32efe990ca865b41daba198a77ed77a139..14e73221fd98d6c08a901e8ffc89ae6ece22baa6 100644 (file)
@@ -1,10 +1,8 @@
 /**
- * This file is part of the DOM implementation for KDE.
- *
  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
  *           (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2006 Apple Computer, Inc.
+ * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
  */
 
 #include "config.h"
-#include "NodeList.h"
+#include "DynamicNodeList.h"
 
 #include "Document.h"
 #include "Element.h"
 
 namespace WebCore {
 
-NodeList::NodeList(PassRefPtr<Node> rootNode, bool needsNotifications)
+DynamicNodeList::DynamicNodeList(PassRefPtr<Node> rootNode, bool needsNotifications)
     : m_rootNode(rootNode)
     , m_caches(new Caches)
     , m_ownsCaches(true)
     , m_needsNotifications(needsNotifications)
 {
-    m_rootNode->registerNodeList(this);
+    m_rootNode->registerDynamicNodeList(this);
 }    
 
-NodeList::NodeList(PassRefPtr<Node> rootNode, NodeList::Caches* info, bool needsNotifications)
+DynamicNodeList::DynamicNodeList(PassRefPtr<Node> rootNode, DynamicNodeList::Caches* info, bool needsNotifications)
     : m_rootNode(rootNode)
     , m_caches(info)
     , m_ownsCaches(false)
     , m_needsNotifications(needsNotifications)
 {
-    m_rootNode->registerNodeList(this);
+    m_rootNode->registerDynamicNodeList(this);
 }    
 
-NodeList::~NodeList()
+DynamicNodeList::~DynamicNodeList()
 {
-    m_rootNode->unregisterNodeList(this);
+    m_rootNode->unregisterDynamicNodeList(this);
     if (m_ownsCaches)
         delete m_caches;
 }
 
-unsigned NodeList::recursiveLength(Node* start) const
+unsigned DynamicNodeList::recursiveLength(Node* start) const
 {
     if (!start)
         start = m_rootNode.get();
@@ -80,7 +78,7 @@ unsigned NodeList::recursiveLength(Node* start) const
     return len;
 }
 
-Node* NodeList::itemForwardsFromCurrent(Node* start, unsigned offset, int remainingOffset) const
+Node* DynamicNodeList::itemForwardsFromCurrent(Node* start, unsigned offset, int remainingOffset) const
 {
     ASSERT(remainingOffset >= 0);
 
@@ -101,7 +99,7 @@ Node* NodeList::itemForwardsFromCurrent(Node* start, unsigned offset, int remain
     return 0; // no matching node in this subtree
 }
 
-Node* NodeList::itemBackwardsFromCurrent(Node* start, unsigned offset, int remainingOffset) const
+Node* DynamicNodeList::itemBackwardsFromCurrent(Node* start, unsigned offset, int remainingOffset) const
 {
     ASSERT(remainingOffset < 0);
     for (Node *n = start; n; n = n->traversePreviousNode(m_rootNode.get())) {
@@ -121,7 +119,7 @@ Node* NodeList::itemBackwardsFromCurrent(Node* start, unsigned offset, int remai
     return 0; // no matching node in this subtree
 }
 
-Node* NodeList::recursiveItem(unsigned offset, Node* start) const
+Node* DynamicNodeList::recursiveItem(unsigned offset, Node* start) const
 {
     int remainingOffset = offset;
     if (!start) {
@@ -142,7 +140,7 @@ Node* NodeList::recursiveItem(unsigned offset, Node* start) const
         return itemForwardsFromCurrent(start, offset, remainingOffset);
 }
 
-Node* NodeList::itemWithName(const AtomicString& elementId) const
+Node* DynamicNodeList::itemWithName(const AtomicString& elementId) const
 {
     if (m_rootNode->isDocumentNode() || m_rootNode->inDocument()) {
         Node* node = m_rootNode->document()->getElementById(elementId);
@@ -167,20 +165,20 @@ Node* NodeList::itemWithName(const AtomicString& elementId) const
     return 0;
 }
 
-void NodeList::rootNodeChildrenChanged()
+void DynamicNodeList::rootNodeChildrenChanged()
 {
     m_caches->reset();
 }
 
 
-NodeList::Caches::Caches()
+DynamicNodeList::Caches::Caches()
     : lastItem(0)
     , isLengthCacheValid(false)
     , isItemCacheValid(false)
 {
 }
 
-void NodeList::Caches::reset()
+void DynamicNodeList::Caches::reset()
 {
     lastItem = 0;
     isLengthCacheValid = false;
diff --git a/WebCore/dom/DynamicNodeList.h b/WebCore/dom/DynamicNodeList.h
new file mode 100644 (file)
index 0000000..03cd734
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ *           (C) 1999 Antti Koivisto (koivisto@kde.org)
+ *           (C) 2001 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef DynamicNodeList_h
+#define DynamicNodeList_h
+
+#include "NodeList.h"
+#include <wtf/RefCounted.h>
+#include <wtf/Forward.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class AtomicString;
+class Node;
+
+class DynamicNodeList : public NodeList {
+public:
+    struct Caches {
+        Caches();
+        void reset();
+
+        unsigned cachedLength;
+        Node* lastItem;
+        unsigned lastItemOffset;
+        bool isLengthCacheValid : 1;
+        bool isItemCacheValid : 1;
+    };
+
+    DynamicNodeList(PassRefPtr<Node> rootNode, bool needsNotifications);
+    DynamicNodeList(PassRefPtr<Node> rootNode, Caches*, bool needsNotifications);
+    virtual ~DynamicNodeList();
+
+    bool needsNotifications() const { return m_needsNotifications; }
+
+    // DOM methods & attributes for NodeList
+    virtual unsigned length() const = 0;
+    virtual Node* item(unsigned index) const = 0;
+    Node* itemWithName(const AtomicString&) const;
+
+    // Other methods (not part of DOM)
+    virtual void rootNodeChildrenChanged();
+    virtual void rootNodeAttributeChanged() { }
+
+protected:
+    // helper functions for searching all ElementImpls in a tree
+    unsigned recursiveLength(Node* start = 0) const;
+    Node* recursiveItem (unsigned offset, Node* start = 0) const;
+    virtual bool nodeMatches(Node* testNode) const = 0;
+
+    RefPtr<Node> m_rootNode;
+    mutable Caches* m_caches;
+    bool m_ownsCaches;
+    bool m_needsNotifications;
+
+private:
+    Node* itemForwardsFromCurrent(Node* start, unsigned offset, int remainingOffset) const;
+    Node* itemBackwardsFromCurrent(Node* start, unsigned offset, int remainingOffset) const;
+};
+
+} // namespace WebCore
+
+#endif // DynamicNodeList_h
index 103eddab275b55461594bda02dae2a90ffc5e9a1..427706f8997b4da5102179e10c8de6f69ed70009 100644 (file)
@@ -105,6 +105,12 @@ module core {
         // HTML 5
         NodeList getElementsByClassName(in DOMString name);
 
+        // ElementSelector - Selector API
+        Element             querySelector(in [ConvertUndefinedOrNullToNullString] DOMString selectors)
+            raises(DOMException);
+        NodeList            querySelectorAll(in [ConvertUndefinedOrNullToNullString] DOMString selectors)
+            raises(DOMException);
+
 #if defined(LANGUAGE_OBJECTIVE_C)
         // Objective-C extensions
         readonly attribute DOMString innerText;
index 3d50f85a30f02740d2dbd0c28e2f55b955b30ef7..4399370255edb1732066fa9eb939f8882a12e812 100644 (file)
@@ -30,8 +30,8 @@ namespace WebCore {
 
 using namespace HTMLNames;
 
-NameNodeList::NameNodeList(Node* root, const String& name, NodeList::Caches* caches)
-    : NodeList(root, caches, true)
+NameNodeList::NameNodeList(Node* root, const String& name, DynamicNodeList::Caches* caches)
+    : DynamicNodeList(root, caches, true)
     , m_nodeName(name)
 {
 }
index 25aaf99d61d8b9a492bef81d2cdc8c75bba828df..3901d030be1b4a7fcb5b8a002af59fb7a872f632 100644 (file)
  * Boston, MA 02110-1301, USA.
  *
  */
+
 #ifndef NameNodeList_h
 #define NameNodeList_h
 
-#include "NodeList.h"
+#include "DynamicNodeList.h"
 #include "PlatformString.h"
 
 namespace WebCore {
@@ -31,9 +32,9 @@ namespace WebCore {
 /**
  * NodeList which lists all Nodes in a Element with a given "name=" tag
  */
-class NameNodeList : public NodeList {
+class NameNodeList : public DynamicNodeList {
 public:
-    NameNodeList(Node* root, const String& name, NodeList::Caches*);
+    NameNodeList(Node* root, const String& name, DynamicNodeList::Caches*);
 
     // DOM methods overridden from  parent classes
 
@@ -42,7 +43,7 @@ public:
 
     // Other methods (not part of DOM)
     
-    virtual void rootNodeAttributeChanged() { NodeList::rootNodeChildrenChanged(); }
+    virtual void rootNodeAttributeChanged() { DynamicNodeList::rootNodeChildrenChanged(); }
 
 protected:
     virtual bool nodeMatches(Node* testNode) const;
index ce265bf0d8764e912db2f257014d5f99e70670dc..0d6e8d968b1475ae705a4cb5172892b545d9fd2a 100644 (file)
 #include "config.h"
 #include "Node.h"
 
+#include "CSSRule.h"
+#include "CSSRuleList.h"
+#include "CSSStyleRule.h"
+#include "CSSStyleSelector.h"
+#include "CSSStyleSheet.h"
+#include "CSSParser.h"
+#include "CSSSelector.h"
 #include "CString.h"
 #include "ChildNodeList.h"
 #include "ClassNodeList.h"
 #include "DOMImplementation.h"
 #include "Document.h"
+#include "DynamicNodeList.h"
 #include "Element.h"
 #include "ExceptionCode.h"
 #include "Frame.h"
@@ -39,6 +47,7 @@
 #include "NameNodeList.h"
 #include "NamedAttrMap.h"
 #include "RenderObject.h"
+#include "SelectorNodeList.h"
 #include "Text.h"
 #include "TextStream.h"
 #include "XMLNames.h"
@@ -49,16 +58,16 @@ namespace WebCore {
 
 using namespace HTMLNames;
 
-typedef HashSet<NodeList*> NodeListSet;
+typedef HashSet<DynamicNodeList*> NodeListSet;
 struct NodeListsNodeData {
     NodeListSet m_listsToNotify;
-    NodeList::Caches m_childNodeListCaches;
-    HashMap<String, NodeList::Caches> m_classNodeListCaches;
-    HashMap<String, NodeList::Caches> m_nameNodeListCaches;
+    DynamicNodeList::Caches m_childNodeListCaches;
+    HashMap<String, DynamicNodeList::Caches> m_classNodeListCaches;
+    HashMap<String, DynamicNodeList::Caches> m_nameNodeListCaches;
 };
 
 // NodeList that limits to a particular tag.
-class TagNodeList : public NodeList {
+class TagNodeList : public DynamicNodeList {
 public:
     TagNodeList(PassRefPtr<Node> rootNode, const AtomicString& namespaceURI, const AtomicString& localName);
 
@@ -73,7 +82,7 @@ private:
 };
 
 inline TagNodeList::TagNodeList(PassRefPtr<Node> rootNode, const AtomicString& namespaceURI, const AtomicString& localName)
-    : NodeList(rootNode, true)
+    : DynamicNodeList(rootNode, true)
     , m_namespaceURI(namespaceURI)
     , m_localName(localName)
 {
@@ -441,7 +450,7 @@ unsigned Node::nodeIndex() const
     return count;
 }
 
-void Node::registerNodeList(NodeList* list)
+void Node::registerDynamicNodeList(DynamicNodeList* list)
 {
     if (!m_nodeLists)
         m_nodeLists.set(new NodeListsNodeData);
@@ -454,7 +463,7 @@ void Node::registerNodeList(NodeList* list)
     m_document->addNodeList();
 }
 
-void Node::unregisterNodeList(NodeList* list)
+void Node::unregisterDynamicNodeList(DynamicNodeList* list)
 {
     ASSERT(m_nodeLists);
     m_document->removeNodeList();
@@ -1215,7 +1224,7 @@ PassRefPtr<NodeList> Node::getElementsByName(const String& elementName)
     if (!m_nodeLists)
         m_nodeLists.set(new NodeListsNodeData);
 
-    return new NameNodeList(this, elementName, &m_nodeLists->m_nameNodeListCaches.add(elementName, NodeList::Caches()).first->second);
+    return new NameNodeList(this, elementName, &m_nodeLists->m_nameNodeListCaches.add(elementName, DynamicNodeList::Caches()).first->second);
 }
 
 PassRefPtr<NodeList> Node::getElementsByClassName(const String& classNames)
@@ -1223,7 +1232,58 @@ PassRefPtr<NodeList> Node::getElementsByClassName(const String& classNames)
     if (!m_nodeLists)
         m_nodeLists.set(new NodeListsNodeData);
 
-    return new ClassNodeList(this, classNames, &m_nodeLists->m_classNodeListCaches.add(classNames, NodeList::Caches()).first->second);
+    return new ClassNodeList(this, classNames, &m_nodeLists->m_classNodeListCaches.add(classNames, DynamicNodeList::Caches()).first->second);
+}
+
+PassRefPtr<Element> Node::querySelector(const String& selectors, ExceptionCode& ec)
+{
+    if (selectors.isNull() || selectors.isEmpty()) {
+        ec = SYNTAX_ERR;
+        return 0;
+    }
+    CSSStyleSheet tempStyleSheet(document());
+    CSSParser p(true);
+    RefPtr<CSSRule> rule = p.parseRule(&tempStyleSheet, selectors + "{}");
+    if (!rule || !rule->isStyleRule()) {
+        ec = SYNTAX_ERR;
+        return 0;
+    }
+
+    CSSStyleSelector* styleSelector = document()->styleSelector();
+    CSSSelector* querySelector = static_cast<CSSStyleRule*>(rule.get())->selector();
+    
+    // FIXME: We can speed this up by implementing caching similar to the one use by getElementById
+    for (Node *n = traverseNextNode(); n; n = n->traverseNextNode()) {
+        if (n->isElementNode()) {
+            Element* element = static_cast<Element*>(n);
+            styleSelector->initElementAndPseudoState(element);
+            for (CSSSelector* selector = querySelector; selector; selector = selector->next()) {
+                if (styleSelector->checkSelector(selector))
+                    return element;
+            }
+        }
+    }
+    
+    return 0;
+}
+
+PassRefPtr<NodeList> Node::querySelectorAll(const String& selectors, ExceptionCode& ec)
+{
+    if (selectors.isNull() || selectors.isEmpty()) {
+        ec = SYNTAX_ERR;
+        return 0;
+    }
+    CSSStyleSheet tempStyleSheet(document());
+    CSSParser p(true);
+    RefPtr<CSSRule> rule = p.parseRule(&tempStyleSheet, selectors + "{}");
+    if (!rule || !rule->isStyleRule()) {
+        ec = SYNTAX_ERR;
+        return 0;
+    }
+    
+    SelectorNodeList* resultList = new SelectorNodeList(this, static_cast<CSSStyleRule*>(rule.get())->selector());
+
+    return resultList;
 }
 
 Document *Node::ownerDocument() const
index 511234f575725bf89d9246ab224b47a104214b98..fe192a0b5d27e2a108bd6232bf0f6f05866f75d0 100644 (file)
@@ -38,6 +38,7 @@ namespace WebCore {
 class AtomicString;
 class ContainerNode;
 class Document;
+class DynamicNodeList;
 class Element;
 class Event;
 class EventListener;
@@ -442,8 +443,8 @@ public:
     void showTreeAndMark(const Node* markedNode1, const char* markedLabel1, const Node* markedNode2 = 0, const char* markedLabel2 = 0) const;
 #endif
 
-    void registerNodeList(NodeList*);
-    void unregisterNodeList(NodeList*);
+    void registerDynamicNodeList(DynamicNodeList*);
+    void unregisterDynamicNodeList(DynamicNodeList*);
     void notifyNodeListsChildrenChanged();
     void notifyLocalNodeListsChildrenChanged();
     void notifyNodeListsAttributeChanged();
@@ -451,10 +452,12 @@ public:
     
     PassRefPtr<NodeList> getElementsByTagName(const String&);
     PassRefPtr<NodeList> getElementsByTagNameNS(const String& namespaceURI, const String& localName);
-
     PassRefPtr<NodeList> getElementsByName(const String& elementName);
     PassRefPtr<NodeList> getElementsByClassName(const String& classNames);
 
+    PassRefPtr<Element> querySelector(const String& selectors, ExceptionCode&);
+    PassRefPtr<NodeList> querySelectorAll(const String& selectors, ExceptionCode&);
+
 private: // members
     DocPtr<Document> m_document;
     Node* m_previous;
index 8843fe2b031e94c486a9b07eadd5bed258c786ac..bbb9c15988f5e6e3c380f1938b358f941f118578 100644 (file)
 
 #include <wtf/RefCounted.h>
 #include <wtf/Forward.h>
-#include <wtf/RefPtr.h>
 
 namespace WebCore {
 
-class AtomicString;
-class Node;
+    class AtomicString;
+    class Node;
 
-class NodeList : public RefCounted<NodeList> {
-public:
+    class NodeList : public RefCounted<NodeList> {
+    public:
+        NodeList() { }
+        virtual ~NodeList() { }
 
-    struct Caches {
-        Caches();
-        void reset();
-        
-        unsigned cachedLength;
-        Node* lastItem;
-        unsigned lastItemOffset;
-        bool isLengthCacheValid : 1;
-        bool isItemCacheValid : 1;
+        // DOM methods & attributes for NodeList
+        virtual unsigned length() const = 0;
+        virtual Node* item(unsigned index) const = 0;
+        virtual Node* itemWithName(const AtomicString&) const = 0;
     };
 
-    NodeList(PassRefPtr<Node> rootNode, bool needsNotifications);
-    NodeList(PassRefPtr<Node> rootNode, Caches*, bool needsNotifications);
-    virtual ~NodeList();
+} // namespace WebCore
 
-    bool needsNotifications() const { return m_needsNotifications; }
-
-    // DOM methods & attributes for NodeList
-    virtual unsigned length() const = 0;
-    virtual Node* item(unsigned index) const = 0;
-    Node* itemWithName(const AtomicString&) const;
-
-    // Other methods (not part of DOM)
-    virtual void rootNodeChildrenChanged();
-    virtual void rootNodeAttributeChanged() {}
-
-protected:
-    // helper functions for searching all ElementImpls in a tree
-    unsigned recursiveLength(Node* start = 0) const;
-    Node* recursiveItem (unsigned offset, Node* start = 0) const;
-    virtual bool nodeMatches(Node* testNode) const = 0;
-
-    RefPtr<Node> m_rootNode;
-    mutable Caches* m_caches;
-    bool m_ownsCaches;
-    bool m_needsNotifications;
-
- private:
-    Node* itemForwardsFromCurrent(Node* start, unsigned offset, int remainingOffset) const;
-    Node* itemBackwardsFromCurrent(Node* start, unsigned offset, int remainingOffset) const;
-};
-
-} //namespace
-
-#endif
+#endif NodeList_h
diff --git a/WebCore/dom/SelectorNodeList.cpp b/WebCore/dom/SelectorNodeList.cpp
new file mode 100644 (file)
index 0000000..819bed4
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2007 Apple 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:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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 "SelectorNodeList.h"
+
+#include "CSSSelector.h"
+#include "CSSStyleSelector.h"
+#include "Document.h"
+#include "Element.h"
+#include "Node.h"
+
+namespace WebCore {
+
+SelectorNodeList::SelectorNodeList(PassRefPtr<Node> rootNode, CSSSelector* querySelector)
+{
+    Document* document = rootNode->document();
+    CSSStyleSelector* styleSelector = document->styleSelector();
+    for (Node* n = rootNode->traverseNextNode(); n; n = n->traverseNextNode()) {
+        if (n->isElementNode()) {
+            styleSelector->initElementAndPseudoState(static_cast<Element*>(n));
+            for (CSSSelector* selector = querySelector; selector; selector = selector->next()) {
+                if (styleSelector->checkSelector(selector)) {
+                    m_nodes.append(n);
+                    break;
+                }
+            }
+        }
+    }
+}
+
+} // namespace WebCore
diff --git a/WebCore/dom/SelectorNodeList.h b/WebCore/dom/SelectorNodeList.h
new file mode 100644 (file)
index 0000000..952258f
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007 Apple 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:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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 SelectorNodeList_h
+#define SelectorNodeList_h
+
+#include "StaticNodeList.h"
+#include <wtf/Forward.h>
+
+namespace WebCore {
+
+    class Node;
+    class CSSSelector;
+
+    class SelectorNodeList : public StaticNodeList {
+    public:
+        SelectorNodeList(PassRefPtr<Node> rootNode, CSSSelector* selector);
+    };
+
+} // namespace WebCore
+
+#endif // SelectorNodeList_h
diff --git a/WebCore/dom/StaticNodeList.cpp b/WebCore/dom/StaticNodeList.cpp
new file mode 100644 (file)
index 0000000..3d7c70d
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2007 Apple 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:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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 "StaticNodeList.h"
+
+#include "AtomicString.h"
+#include "Node.h"
+#include "Element.h"
+
+namespace WebCore {
+
+unsigned StaticNodeList::length() const
+{
+    return m_nodes.size();
+}
+
+Node* StaticNodeList::item(unsigned index) const
+{
+    if (index < m_nodes.size())
+        return m_nodes[index].get();
+    return 0;
+}
+
+Node* StaticNodeList::itemWithName(const AtomicString& elementId) const
+{
+    size_t length = m_nodes.size();
+    for (size_t i = 0; i < length; ++i) {
+        Node* node = m_nodes[i].get();
+        if (node->isElementNode() && static_cast<Element*>(node)->getIDAttribute() == elementId)
+            return node;
+    }
+
+    return 0;
+}
+
+} // namespace WebCore
diff --git a/WebCore/dom/StaticNodeList.h b/WebCore/dom/StaticNodeList.h
new file mode 100644 (file)
index 0000000..aacd1ca
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2007 Apple 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:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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 StaticNodeList_h
+#define StaticNodeList_h
+
+#include "NodeList.h"
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+    class Node;
+
+    class StaticNodeList : public NodeList {
+    public:
+        // Derived classes should build up the Vector in their constructor.
+        StaticNodeList() { }
+        virtual ~StaticNodeList() { }
+
+        virtual unsigned length() const;
+        virtual Node* item(unsigned index) const;
+        virtual Node* itemWithName(const AtomicString&) const;
+
+    protected:
+        Vector<RefPtr<Node> > m_nodes;
+    };
+
+} // namespace WebCore
+
+#endif // StaticNodeList_h