• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "Document.h"
30 #include "HTMLNames.h"
31 #include "MappedAttributeEntry.h"
32 #include "QualifiedName.h"
33 #include "ScrollTypes.h"
34 
35 namespace WebCore {
36 
37 class Attr;
38 class Attribute;
39 class CSSStyleDeclaration;
40 class ClientRect;
41 class ClientRectList;
42 class ElementRareData;
43 class IntSize;
44 
45 class Element : public ContainerNode {
46 public:
47     static PassRefPtr<Element> create(const QualifiedName&, Document*);
48     virtual ~Element();
49 
50     DEFINE_ATTRIBUTE_EVENT_LISTENER(abort);
51     DEFINE_ATTRIBUTE_EVENT_LISTENER(change);
52     DEFINE_ATTRIBUTE_EVENT_LISTENER(click);
53     DEFINE_ATTRIBUTE_EVENT_LISTENER(contextmenu);
54     DEFINE_ATTRIBUTE_EVENT_LISTENER(dblclick);
55     DEFINE_ATTRIBUTE_EVENT_LISTENER(dragenter);
56     DEFINE_ATTRIBUTE_EVENT_LISTENER(dragover);
57     DEFINE_ATTRIBUTE_EVENT_LISTENER(dragleave);
58     DEFINE_ATTRIBUTE_EVENT_LISTENER(drop);
59     DEFINE_ATTRIBUTE_EVENT_LISTENER(dragstart);
60     DEFINE_ATTRIBUTE_EVENT_LISTENER(drag);
61     DEFINE_ATTRIBUTE_EVENT_LISTENER(dragend);
62     DEFINE_ATTRIBUTE_EVENT_LISTENER(input);
63     DEFINE_ATTRIBUTE_EVENT_LISTENER(invalid);
64     DEFINE_ATTRIBUTE_EVENT_LISTENER(keydown);
65     DEFINE_ATTRIBUTE_EVENT_LISTENER(keypress);
66     DEFINE_ATTRIBUTE_EVENT_LISTENER(keyup);
67     DEFINE_ATTRIBUTE_EVENT_LISTENER(mousedown);
68     DEFINE_ATTRIBUTE_EVENT_LISTENER(mousemove);
69     DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseout);
70     DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseover);
71     DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseup);
72     DEFINE_ATTRIBUTE_EVENT_LISTENER(mousewheel);
73     DEFINE_ATTRIBUTE_EVENT_LISTENER(scroll);
74     DEFINE_ATTRIBUTE_EVENT_LISTENER(select);
75     DEFINE_ATTRIBUTE_EVENT_LISTENER(submit);
76 
77     // These four attribute event handler attributes are overridden by HTMLBodyElement
78     // and HTMLFrameSetElement to forward to the DOMWindow.
79     DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(blur);
80     DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(error);
81     DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(focus);
82     DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(load);
83 
84     // WebKit extensions
85     DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecut);
86     DEFINE_ATTRIBUTE_EVENT_LISTENER(cut);
87     DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy);
88     DEFINE_ATTRIBUTE_EVENT_LISTENER(copy);
89     DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste);
90     DEFINE_ATTRIBUTE_EVENT_LISTENER(paste);
91     DEFINE_ATTRIBUTE_EVENT_LISTENER(reset);
92     DEFINE_ATTRIBUTE_EVENT_LISTENER(search);
93     DEFINE_ATTRIBUTE_EVENT_LISTENER(selectstart);
94 #if ENABLE(TOUCH_EVENTS)
95     DEFINE_ATTRIBUTE_EVENT_LISTENER(touchstart);
96     DEFINE_ATTRIBUTE_EVENT_LISTENER(touchmove);
97     DEFINE_ATTRIBUTE_EVENT_LISTENER(touchend);
98     DEFINE_ATTRIBUTE_EVENT_LISTENER(touchcancel);
99 #endif
100 
101     const AtomicString& getIDAttribute() const;
102     bool hasAttribute(const QualifiedName&) const;
103     const AtomicString& getAttribute(const QualifiedName&) const;
104     void setAttribute(const QualifiedName&, const AtomicString& value, ExceptionCode&);
105     void removeAttribute(const QualifiedName&, ExceptionCode&);
106 
107     bool hasAttributes() const;
108 
109     bool hasAttribute(const String& name) const;
110     bool hasAttributeNS(const String& namespaceURI, const String& localName) const;
111 
112     const AtomicString& getAttribute(const String& name) const;
113     const AtomicString& getAttributeNS(const String& namespaceURI, const String& localName) const;
114 
115     void setAttribute(const AtomicString& name, const AtomicString& value, ExceptionCode&);
116     void setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode&, FragmentScriptingPermission = FragmentScriptingAllowed);
117 
118     const QualifiedName& idAttributeName() const;
119 
120     void scrollIntoView(bool alignToTop = true);
121     void scrollIntoViewIfNeeded(bool centerIfNeeded = true);
122 
123     void scrollByLines(int lines);
124     void scrollByPages(int pages);
125 
126     int offsetLeft();
127     int offsetTop();
128     int offsetWidth();
129     int offsetHeight();
130     Element* offsetParent();
131     int clientLeft();
132     int clientTop();
133     int clientWidth();
134     int clientHeight();
135     virtual int scrollLeft() const;
136     virtual int scrollTop() const;
137     virtual void setScrollLeft(int);
138     virtual void setScrollTop(int);
139     virtual int scrollWidth() const;
140     virtual int scrollHeight() const;
141 
142     PassRefPtr<ClientRectList> getClientRects() const;
143     PassRefPtr<ClientRect> getBoundingClientRect() const;
144 
145     void removeAttribute(const String& name, ExceptionCode&);
146     void removeAttributeNS(const String& namespaceURI, const String& localName, ExceptionCode&);
147 
148     PassRefPtr<Attr> getAttributeNode(const String& name);
149     PassRefPtr<Attr> getAttributeNodeNS(const String& namespaceURI, const String& localName);
150     PassRefPtr<Attr> setAttributeNode(Attr*, ExceptionCode&);
151     PassRefPtr<Attr> setAttributeNodeNS(Attr*, ExceptionCode&);
152     PassRefPtr<Attr> removeAttributeNode(Attr*, ExceptionCode&);
153 
154     virtual CSSStyleDeclaration* style();
155 
tagQName()156     const QualifiedName& tagQName() const { return m_tagName; }
tagName()157     String tagName() const { return nodeName(); }
hasTagName(const QualifiedName & tagName)158     bool hasTagName(const QualifiedName& tagName) const { return m_tagName.matches(tagName); }
159 
160     // A fast function for checking the local name against another atomic string.
hasLocalName(const AtomicString & other)161     bool hasLocalName(const AtomicString& other) const { return m_tagName.localName() == other; }
hasLocalName(const QualifiedName & other)162     bool hasLocalName(const QualifiedName& other) const { return m_tagName.localName() == other.localName(); }
163 
localName()164     const AtomicString& localName() const { return m_tagName.localName(); }
prefix()165     const AtomicString& prefix() const { return m_tagName.prefix(); }
namespaceURI()166     const AtomicString& namespaceURI() const { return m_tagName.namespaceURI(); }
167 
168     virtual KURL baseURI() const;
169 
170     virtual String nodeName() const;
171 
172     PassRefPtr<Element> cloneElementWithChildren();
173     PassRefPtr<Element> cloneElementWithoutChildren();
174 
175     void normalizeAttributes();
176     String nodeNamePreservingCase() const;
177 
178     // convenience methods which ignore exceptions
179     void setAttribute(const QualifiedName&, const AtomicString& value);
180     void setBooleanAttribute(const QualifiedName& name, bool);
181     // Please don't use setCStringAttribute in performance-sensitive code;
182     // use a static AtomicString value instead to avoid the conversion overhead.
183     void setCStringAttribute(const QualifiedName&, const char* cStringValue);
184 
185     virtual NamedNodeMap* attributes() const;
186     NamedNodeMap* attributes(bool readonly) const;
187 
188     // This method is called whenever an attribute is added, changed or removed.
189     virtual void attributeChanged(Attribute*, bool preserveDecls = false);
190 
191     // not part of the DOM
192     void setAttributeMap(PassRefPtr<NamedNodeMap>, FragmentScriptingPermission = FragmentScriptingAllowed);
attributeMap()193     NamedNodeMap* attributeMap() const { return namedAttrMap.get(); }
194 
copyNonAttributeProperties(const Element *)195     virtual void copyNonAttributeProperties(const Element* /*source*/) { }
196 
197     virtual void attach();
198     virtual void detach();
199     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
200     virtual void recalcStyle(StyleChange = NoChange);
201 
202     virtual RenderStyle* computedStyle();
203 
204     void dispatchAttrRemovalEvent(Attribute*);
205     void dispatchAttrAdditionEvent(Attribute*);
206 
accessKeyAction(bool)207     virtual void accessKeyAction(bool /*sendToAnyEvent*/) { }
208 
209     virtual bool isURLAttribute(Attribute*) const;
210     KURL getURLAttribute(const QualifiedName&) const;
211     virtual const QualifiedName& imageSourceAttributeName() const;
target()212     virtual String target() const { return String(); }
213 
214     virtual void focus(bool restorePreviousSelection = true);
215     virtual void updateFocusAppearance(bool restorePreviousSelection);
216     void blur();
217 
218     String innerText() const;
219     String outerText() const;
220 
221     virtual String title() const;
222 
223     String openTagStartToString() const;
224 
225     void updateId(const AtomicString& oldId, const AtomicString& newId);
226 
227     IntSize minimumSizeForResizing() const;
228     void setMinimumSizeForResizing(const IntSize&);
229 
230     // Use Document::registerForDocumentActivationCallbacks() to subscribe to these
documentWillBecomeInactive()231     virtual void documentWillBecomeInactive() { }
documentDidBecomeActive()232     virtual void documentDidBecomeActive() { }
233 
234     // Use Document::registerForMediaVolumeCallbacks() to subscribe to this
mediaVolumeDidChange()235     virtual void mediaVolumeDidChange() { }
236 
isFinishedParsingChildren()237     bool isFinishedParsingChildren() const { return m_parsingChildrenFinished; }
238     virtual void finishParsingChildren();
beginParsingChildren()239     virtual void beginParsingChildren() { m_parsingChildrenFinished = false; }
240 
241     // ElementTraversal API
242     Element* firstElementChild() const;
243     Element* lastElementChild() const;
244     Element* previousElementSibling() const;
245     Element* nextElementSibling() const;
246     unsigned childElementCount() const;
247 
248     bool webkitMatchesSelector(const String& selectors, ExceptionCode&);
249 
isFormControlElement()250     virtual bool isFormControlElement() const { return false; }
isEnabledFormControl()251     virtual bool isEnabledFormControl() const { return true; }
isReadOnlyFormControl()252     virtual bool isReadOnlyFormControl() const { return false; }
isTextFormControl()253     virtual bool isTextFormControl() const { return false; }
isOptionalFormControl()254     virtual bool isOptionalFormControl() const { return false; }
isRequiredFormControl()255     virtual bool isRequiredFormControl() const { return false; }
isDefaultButtonForForm()256     virtual bool isDefaultButtonForForm() const { return false; }
willValidate()257     virtual bool willValidate() const { return false; }
isValidFormControlElement()258     virtual bool isValidFormControlElement() { return false; }
259 
formControlValueMatchesRenderer()260     virtual bool formControlValueMatchesRenderer() const { return false; }
setFormControlValueMatchesRenderer(bool)261     virtual void setFormControlValueMatchesRenderer(bool) { }
262 
formControlName()263     virtual const AtomicString& formControlName() const { return nullAtom; }
formControlType()264     virtual const AtomicString& formControlType() const { return nullAtom; }
265 
saveFormControlState(String &)266     virtual bool saveFormControlState(String&) const { return false; }
restoreFormControlState(const String &)267     virtual void restoreFormControlState(const String&) { }
268 
dispatchFormControlChangeEvent()269     virtual void dispatchFormControlChangeEvent() { }
270 
271 protected:
272     Element(const QualifiedName&, Document*, ConstructionType);
273 
274     virtual void insertedIntoDocument();
275     virtual void removedFromDocument();
276     virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
277 
278     // The implementation of Element::attributeChanged() calls the following two functions.
279     // They are separated to allow a different flow of control in StyledElement::attributeChanged().
280     void recalcStyleIfNeededAfterAttributeChanged(Attribute*);
281     void updateAfterAttributeChanged(Attribute*);
282 
283 private:
284     void scrollByUnits(int units, ScrollGranularity);
285 
286     virtual void setPrefix(const AtomicString&, ExceptionCode&);
287     virtual NodeType nodeType() const;
288     virtual bool childTypeAllowed(NodeType);
289 
290     virtual PassRefPtr<Attribute> createAttribute(const QualifiedName&, const AtomicString& value);
291     const QualifiedName& rareIDAttributeName() const;
292 
293 #ifndef NDEBUG
294     virtual void formatForDebugger(char* buffer, unsigned length) const;
295 #endif
296 
297     bool pseudoStyleCacheIsInvalid(const RenderStyle* currentStyle, RenderStyle* newStyle);
298 
299     virtual void createAttributeMap() const;
300 
updateStyleAttribute()301     virtual void updateStyleAttribute() const { }
302 
303 #if ENABLE(SVG)
updateAnimatedSVGAttribute(const QualifiedName &)304     virtual void updateAnimatedSVGAttribute(const QualifiedName&) const { }
305 #endif
306 
307     void cancelFocusAppearanceUpdate();
308 
virtualPrefix()309     virtual const AtomicString& virtualPrefix() const { return prefix(); }
virtualLocalName()310     virtual const AtomicString& virtualLocalName() const { return localName(); }
virtualNamespaceURI()311     virtual const AtomicString& virtualNamespaceURI() const { return namespaceURI(); }
312 
313     // cloneNode is private so that non-virtual cloneElementWithChildren and cloneElementWithoutChildren
314     // are used instead.
315     virtual PassRefPtr<Node> cloneNode(bool deep);
316 
317     QualifiedName m_tagName;
318     virtual NodeRareData* createRareData();
319 
320     ElementRareData* rareData() const;
321     ElementRareData* ensureRareData();
322 
323 protected:
324     mutable RefPtr<NamedNodeMap> namedAttrMap;
325 };
326 
hasTagName(const QualifiedName & name)327 inline bool Node::hasTagName(const QualifiedName& name) const
328 {
329     return isElementNode() && static_cast<const Element*>(this)->hasTagName(name);
330 }
331 
hasAttributes()332 inline bool Node::hasAttributes() const
333 {
334     return isElementNode() && static_cast<const Element*>(this)->hasAttributes();
335 }
336 
attributes()337 inline NamedNodeMap* Node::attributes() const
338 {
339     return isElementNode() ? static_cast<const Element*>(this)->attributes() : 0;
340 }
341 
parentElement()342 inline Element* Node::parentElement() const
343 {
344     Node* parent = parentNode();
345     return parent && parent->isElementNode() ? static_cast<Element*>(parent) : 0;
346 }
347 
idAttributeName()348 inline const QualifiedName& Element::idAttributeName() const
349 {
350     return hasRareData() ? rareIDAttributeName() : HTMLNames::idAttr;
351 }
352 
attributes(bool readonly)353 inline NamedNodeMap* Element::attributes(bool readonly) const
354 {
355     if (!m_isStyleAttributeValid)
356         updateStyleAttribute();
357 
358 #if ENABLE(SVG)
359     if (!m_areSVGAttributesValid)
360         updateAnimatedSVGAttribute(anyQName());
361 #endif
362 
363     if (!readonly && !namedAttrMap)
364         createAttributeMap();
365     return namedAttrMap.get();
366 }
367 
updateId(const AtomicString & oldId,const AtomicString & newId)368 inline void Element::updateId(const AtomicString& oldId, const AtomicString& newId)
369 {
370     if (!inDocument())
371         return;
372 
373     if (oldId == newId)
374         return;
375 
376     Document* doc = document();
377     if (!oldId.isEmpty())
378         doc->removeElementById(oldId, this);
379     if (!newId.isEmpty())
380         doc->addElementById(newId, this);
381 }
382 
383 } //namespace
384 
385 #endif
386