root/trunk/WebCore/dom/Element.h

Revision 48723, 12.6 KB (checked in by weinig@apple.com, 2 months ago)

WebCore: Fix for  https://bugs.webkit.org/show_bug.cgi?id=29703
Add a function to element to check whether it matches a CSS selector

Reviewed by Dan Bernstein.

Implement Element.webkitMatchesSelector.

* css/CSSSelectorList.cpp:
(WebCore::forEachTagSelector):
(WebCore::forEachSelector):
(WebCore::SelectorNeedsNamespaceResolutionFunctor::operator()):
(WebCore::CSSSelectorList::selectorsNeedNamespaceResolution):
* css/CSSSelectorList.h:
Moved code to iterate the CSSSelectorList and determine if any
selectors need namespace resolution from a static function in
Node.cpp to CSSSelectorList so that it can be used by webkitMatchesSelector
as well as querySelector/querySelectorAll.

* dom/Element.cpp:
(WebCore::Element::webkitMatchesSelector):
* dom/Element.h:
* dom/Element.idl:
Implement the new function. Handles exceptional cases identically to
querySelector/querySelectorAll.

* dom/Node.cpp:
(WebCore::Node::querySelector):
(WebCore::Node::querySelectorAll):
Moved selectorsNeedNamespaceResolution to CSSSelectorList from here.

LayoutTests: Update tests for  https://bugs.webkit.org/show_bug.cgi?id=29703
Add a function to element to check whether it matches a CSS selector

Reviewed by Dan Bernstein.

Add webkitMatchesSelector to SelectorAPI tests.

* fast/dom/SelectorAPI/caseID-almost-strict-expected.txt:
* fast/dom/SelectorAPI/caseID-almost-strict.html:
* fast/dom/SelectorAPI/caseID-expected.txt:
* fast/dom/SelectorAPI/caseID-strict-expected.txt:
* fast/dom/SelectorAPI/caseID-strict.html:
* fast/dom/SelectorAPI/caseID.html:
* fast/dom/SelectorAPI/caseTag-expected.txt:
* fast/dom/SelectorAPI/caseTag.html:
* fast/dom/SelectorAPI/caseTagX-expected.txt:
* fast/dom/SelectorAPI/caseTagX.xhtml:
* fast/dom/SelectorAPI/detached-element-expected.txt:
* fast/dom/SelectorAPI/not-supported-namespace-in-selector-expected.txt:
* fast/dom/SelectorAPI/not-supported-namespace-in-selector.html:
* fast/dom/SelectorAPI/script-tests/detached-element.js:
* fast/dom/SelectorAPI/script-tests/undefined-null-stringify.js:
* fast/dom/SelectorAPI/script-tests/viewless-document.js:
* fast/dom/SelectorAPI/undefined-null-stringify-expected.txt:
* fast/dom/SelectorAPI/viewless-document-expected.txt:
* fast/dom/Window/window-properties-expected.txt:
* fast/dom/domListEnumeration-expected.txt:
* fast/dom/script-tests/domListEnumeration.js:

  • Property svn:eol-style set to native
Line 
1/*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4 *           (C) 2001 Peter Kelly (pmk@post.com)
5 *           (C) 2001 Dirk Mueller (mueller@kde.org)
6 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB.  If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 *
23 */
24
25#ifndef Element_h
26#define Element_h
27
28#include "ContainerNode.h"
29#include "QualifiedName.h"
30#include "ScrollTypes.h"
31
32namespace WebCore {
33
34class Attr;
35class Attribute;
36class CSSStyleDeclaration;
37class ClientRect;
38class ClientRectList;
39class ElementRareData;
40class IntSize;
41
42class Element : public ContainerNode {
43public:
44    static PassRefPtr<Element> create(const QualifiedName&, Document*);
45    virtual ~Element();
46
47    DEFINE_ATTRIBUTE_EVENT_LISTENER(abort);
48    DEFINE_ATTRIBUTE_EVENT_LISTENER(change);
49    DEFINE_ATTRIBUTE_EVENT_LISTENER(click);
50    DEFINE_ATTRIBUTE_EVENT_LISTENER(contextmenu);
51    DEFINE_ATTRIBUTE_EVENT_LISTENER(dblclick);
52    DEFINE_ATTRIBUTE_EVENT_LISTENER(dragenter);
53    DEFINE_ATTRIBUTE_EVENT_LISTENER(dragover);
54    DEFINE_ATTRIBUTE_EVENT_LISTENER(dragleave);
55    DEFINE_ATTRIBUTE_EVENT_LISTENER(drop);
56    DEFINE_ATTRIBUTE_EVENT_LISTENER(dragstart);
57    DEFINE_ATTRIBUTE_EVENT_LISTENER(drag);
58    DEFINE_ATTRIBUTE_EVENT_LISTENER(dragend);
59    DEFINE_ATTRIBUTE_EVENT_LISTENER(input);
60    DEFINE_ATTRIBUTE_EVENT_LISTENER(invalid);
61    DEFINE_ATTRIBUTE_EVENT_LISTENER(keydown);
62    DEFINE_ATTRIBUTE_EVENT_LISTENER(keypress);
63    DEFINE_ATTRIBUTE_EVENT_LISTENER(keyup);
64    DEFINE_ATTRIBUTE_EVENT_LISTENER(mousedown);
65    DEFINE_ATTRIBUTE_EVENT_LISTENER(mousemove);
66    DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseout);
67    DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseover);
68    DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseup);
69    DEFINE_ATTRIBUTE_EVENT_LISTENER(mousewheel);
70    DEFINE_ATTRIBUTE_EVENT_LISTENER(scroll);
71    DEFINE_ATTRIBUTE_EVENT_LISTENER(select);
72    DEFINE_ATTRIBUTE_EVENT_LISTENER(submit);
73
74    // These 4 attribute event handler attributes are overrided by HTMLBodyElement
75    // and HTMLFrameSetElement to forward to the DOMWindow.
76    DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(blur);
77    DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(error);
78    DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(focus);
79    DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(load);
80
81    // WebKit extensions
82    DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecut);
83    DEFINE_ATTRIBUTE_EVENT_LISTENER(cut);
84    DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy);
85    DEFINE_ATTRIBUTE_EVENT_LISTENER(copy);
86    DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste);
87    DEFINE_ATTRIBUTE_EVENT_LISTENER(paste);
88    DEFINE_ATTRIBUTE_EVENT_LISTENER(reset);
89    DEFINE_ATTRIBUTE_EVENT_LISTENER(search);
90    DEFINE_ATTRIBUTE_EVENT_LISTENER(selectstart);
91
92    const AtomicString& getIDAttribute() const;
93    bool hasAttribute(const QualifiedName&) const;
94    const AtomicString& getAttribute(const QualifiedName&) const;
95    void setAttribute(const QualifiedName&, const AtomicString& value, ExceptionCode&);
96    void removeAttribute(const QualifiedName&, ExceptionCode&);
97
98    bool hasAttributes() const;
99
100    bool hasAttribute(const String& name) const;
101    bool hasAttributeNS(const String& namespaceURI, const String& localName) const;
102
103    const AtomicString& getAttribute(const String& name) const;
104    const AtomicString& getAttributeNS(const String& namespaceURI, const String& localName) const;
105
106    void setAttribute(const AtomicString& name, const AtomicString& value, ExceptionCode&);
107    void setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode&);
108
109    void scrollIntoView(bool alignToTop = true);
110    void scrollIntoViewIfNeeded(bool centerIfNeeded = true);
111
112    void scrollByLines(int lines);
113    void scrollByPages(int pages);
114
115    int offsetLeft();
116    int offsetTop();
117    int offsetWidth();
118    int offsetHeight();
119    Element* offsetParent();
120    int clientLeft();
121    int clientTop();
122    int clientWidth();
123    int clientHeight();
124    virtual int scrollLeft() const;
125    virtual int scrollTop() const;
126    virtual void setScrollLeft(int);
127    virtual void setScrollTop(int);
128    virtual int scrollWidth() const;
129    virtual int scrollHeight() const;
130
131    PassRefPtr<ClientRectList> getClientRects() const;
132    PassRefPtr<ClientRect> getBoundingClientRect() const;
133
134    void removeAttribute(const String& name, ExceptionCode&);
135    void removeAttributeNS(const String& namespaceURI, const String& localName, ExceptionCode&);
136
137    PassRefPtr<Attr> getAttributeNode(const String& name);
138    PassRefPtr<Attr> getAttributeNodeNS(const String& namespaceURI, const String& localName);
139    PassRefPtr<Attr> setAttributeNode(Attr*, ExceptionCode&);
140    PassRefPtr<Attr> setAttributeNodeNS(Attr*, ExceptionCode&);
141    PassRefPtr<Attr> removeAttributeNode(Attr*, ExceptionCode&);
142   
143    virtual CSSStyleDeclaration* style();
144
145    const QualifiedName& tagQName() const { return m_tagName; }
146    String tagName() const { return nodeName(); }
147    bool hasTagName(const QualifiedName& tagName) const { return m_tagName.matches(tagName); }
148   
149    // A fast function for checking the local name against another atomic string.
150    bool hasLocalName(const AtomicString& other) const { return m_tagName.localName() == other; }
151    bool hasLocalName(const QualifiedName& other) const { return m_tagName.localName() == other.localName(); }
152
153    const AtomicString& localName() const { return m_tagName.localName(); }
154    const AtomicString& prefix() const { return m_tagName.prefix(); }
155    const AtomicString& namespaceURI() const { return m_tagName.namespaceURI(); }
156
157    virtual KURL baseURI() const;
158
159    virtual String nodeName() const;
160
161    PassRefPtr<Element> cloneElementWithChildren();
162    PassRefPtr<Element> cloneElementWithoutChildren();
163
164    void normalizeAttributes();
165    String nodeNamePreservingCase() const;
166
167    // convenience methods which ignore exceptions
168    void setAttribute(const QualifiedName&, const AtomicString& value);
169    void setBooleanAttribute(const QualifiedName& name, bool);
170
171    virtual NamedNodeMap* attributes() const;
172    NamedNodeMap* attributes(bool readonly) const;
173
174    // This method is called whenever an attribute is added, changed or removed.
175    virtual void attributeChanged(Attribute*, bool preserveDecls = false);
176
177    // not part of the DOM
178    void setAttributeMap(PassRefPtr<NamedNodeMap>);
179    NamedNodeMap* attributeMap() const { return namedAttrMap.get(); }
180
181    virtual void copyNonAttributeProperties(const Element* /*source*/) { }
182
183    virtual void attach();
184    virtual void detach();
185    virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
186    virtual void recalcStyle(StyleChange = NoChange);
187
188    virtual RenderStyle* computedStyle();
189
190    void dispatchAttrRemovalEvent(Attribute*);
191    void dispatchAttrAdditionEvent(Attribute*);
192
193    virtual void accessKeyAction(bool /*sendToAnyEvent*/) { }
194
195    virtual bool isURLAttribute(Attribute*) const;
196    KURL getURLAttribute(const QualifiedName&) const;
197    virtual const QualifiedName& imageSourceAttributeName() const;
198    virtual String target() const { return String(); }
199
200    virtual void focus(bool restorePreviousSelection = true);
201    virtual void updateFocusAppearance(bool restorePreviousSelection);
202    void blur();
203
204    String innerText() const;
205    String outerText() const;
206 
207    virtual String title() const;
208
209    String openTagStartToString() const;
210
211    void updateId(const AtomicString& oldId, const AtomicString& newId);
212
213    IntSize minimumSizeForResizing() const;
214    void setMinimumSizeForResizing(const IntSize&);
215
216    // Use Document::registerForDocumentActivationCallbacks() to subscribe to these
217    virtual void documentWillBecomeInactive() { }
218    virtual void documentDidBecomeActive() { }
219
220    // Use Document::registerForMediaVolumeCallbacks() to subscribe to this
221    virtual void mediaVolumeDidChange() { }
222
223    bool isFinishedParsingChildren() const { return m_parsingChildrenFinished; }
224    virtual void finishParsingChildren();
225    virtual void beginParsingChildren() { m_parsingChildrenFinished = false; }
226
227    // ElementTraversal API
228    Element* firstElementChild() const;
229    Element* lastElementChild() const;
230    Element* previousElementSibling() const;
231    Element* nextElementSibling() const;
232    unsigned childElementCount() const;
233
234    bool webkitMatchesSelector(const String& selectors, ExceptionCode&);
235
236    virtual bool isFormControlElement() const { return false; }
237    virtual bool isEnabledFormControl() const { return true; }
238    virtual bool isReadOnlyFormControl() const { return false; }
239    virtual bool isTextFormControl() const { return false; }
240    virtual bool isOptionalFormControl() const { return false; }
241    virtual bool isRequiredFormControl() const { return false; }
242    virtual bool isDefaultButtonForForm() const { return false; }
243    virtual bool willValidate() const { return false; }
244    virtual bool isValidFormControlElement() { return false; }
245
246    virtual bool formControlValueMatchesRenderer() const { return false; }
247    virtual void setFormControlValueMatchesRenderer(bool) { }
248
249    virtual const AtomicString& formControlName() const { return nullAtom; }
250    virtual const AtomicString& formControlType() const { return nullAtom; }
251
252    virtual bool saveFormControlState(String&) const { return false; }
253    virtual void restoreFormControlState(const String&) { }
254
255    virtual void dispatchFormControlChangeEvent() { }
256
257protected:
258    Element(const QualifiedName&, Document*, ConstructionType);
259
260    virtual void insertedIntoDocument();
261    virtual void removedFromDocument();
262    virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
263
264    // The implementation of Element::attributeChanged() calls the following two functions.
265    // They are separated to allow a different flow of control in StyledElement::attributeChanged().
266    void recalcStyleIfNeededAfterAttributeChanged(Attribute*);
267    void updateAfterAttributeChanged(Attribute*);
268
269private:
270    void scrollByUnits(int units, ScrollGranularity);
271
272    virtual void setPrefix(const AtomicString&, ExceptionCode&);
273    virtual NodeType nodeType() const;
274    virtual bool childTypeAllowed(NodeType);
275
276    virtual PassRefPtr<Attribute> createAttribute(const QualifiedName&, const AtomicString& value);
277   
278#ifndef NDEBUG
279    virtual void formatForDebugger(char* buffer, unsigned length) const;
280#endif
281
282    bool pseudoStyleCacheIsInvalid(const RenderStyle* currentStyle, RenderStyle* newStyle);
283
284    virtual void createAttributeMap() const;
285
286    virtual void updateStyleAttribute() const { }
287
288#if ENABLE(SVG)
289    virtual void updateAnimatedSVGAttribute(const String&) const { }
290#endif
291
292    void updateFocusAppearanceSoonAfterAttach();
293    void cancelFocusAppearanceUpdate();
294
295    virtual const AtomicString& virtualPrefix() const { return prefix(); }
296    virtual const AtomicString& virtualLocalName() const { return localName(); }
297    virtual const AtomicString& virtualNamespaceURI() const { return namespaceURI(); }
298   
299    // cloneNode is private so that non-virtual cloneElementWithChildren and cloneElementWithoutChildren
300    // are used instead.
301    virtual PassRefPtr<Node> cloneNode(bool deep);
302
303    QualifiedName m_tagName;
304    virtual NodeRareData* createRareData();
305
306    ElementRareData* rareData() const;
307    ElementRareData* ensureRareData();
308   
309protected:
310    mutable RefPtr<NamedNodeMap> namedAttrMap;
311};
312   
313inline bool Node::hasTagName(const QualifiedName& name) const
314{
315    return isElementNode() && static_cast<const Element*>(this)->hasTagName(name);
316}
317
318inline bool Node::hasAttributes() const
319{
320    return isElementNode() && static_cast<const Element*>(this)->hasAttributes();
321}
322
323inline NamedNodeMap* Node::attributes() const
324{
325    return isElementNode() ? static_cast<const Element*>(this)->attributes() : 0;
326}
327
328inline Element* Node::parentElement() const
329{
330    Node* parent = parentNode();
331    return parent && parent->isElementNode() ? static_cast<Element*>(parent) : 0;
332}
333
334} //namespace
335
336#endif
Note: See TracBrowser for help on using the browser.