OSDN Git Service

Merge changes I55c6d71a,Ifb3277d4,Ia1b847a2,I7ba9cf3f,Ida2b2a8a,I1280ec90,I72f818d5...
[android-x86/external-webkit.git] / Source / WebCore / dom / Element.h
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, 2010, 2011 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 "Document.h"
29 #include "FragmentScriptingPermission.h"
30 #include "NamedNodeMap.h"
31 #include "ScrollTypes.h"
32
33 namespace WebCore {
34
35 class Attribute;
36 class ClientRect;
37 class ClientRectList;
38 class DOMStringMap;
39 class DOMTokenList;
40 class ElementRareData;
41 class IntSize;
42 class WebKitAnimationList;
43
44 enum SpellcheckAttributeState {
45     SpellcheckAttributeTrue,
46     SpellcheckAttributeFalse,
47     SpellcheckAttributeDefault
48 };
49
50 class Element : public ContainerNode {
51 public:
52     static PassRefPtr<Element> create(const QualifiedName&, Document*);
53     virtual ~Element();
54
55     DEFINE_ATTRIBUTE_EVENT_LISTENER(abort);
56     DEFINE_ATTRIBUTE_EVENT_LISTENER(change);
57     DEFINE_ATTRIBUTE_EVENT_LISTENER(click);
58     DEFINE_ATTRIBUTE_EVENT_LISTENER(contextmenu);
59     DEFINE_ATTRIBUTE_EVENT_LISTENER(dblclick);
60     DEFINE_ATTRIBUTE_EVENT_LISTENER(dragenter);
61     DEFINE_ATTRIBUTE_EVENT_LISTENER(dragover);
62     DEFINE_ATTRIBUTE_EVENT_LISTENER(dragleave);
63     DEFINE_ATTRIBUTE_EVENT_LISTENER(drop);
64     DEFINE_ATTRIBUTE_EVENT_LISTENER(dragstart);
65     DEFINE_ATTRIBUTE_EVENT_LISTENER(drag);
66     DEFINE_ATTRIBUTE_EVENT_LISTENER(dragend);
67     DEFINE_ATTRIBUTE_EVENT_LISTENER(formchange);
68     DEFINE_ATTRIBUTE_EVENT_LISTENER(forminput);
69     DEFINE_ATTRIBUTE_EVENT_LISTENER(input);
70     DEFINE_ATTRIBUTE_EVENT_LISTENER(invalid);
71     DEFINE_ATTRIBUTE_EVENT_LISTENER(keydown);
72     DEFINE_ATTRIBUTE_EVENT_LISTENER(keypress);
73     DEFINE_ATTRIBUTE_EVENT_LISTENER(keyup);
74     DEFINE_ATTRIBUTE_EVENT_LISTENER(mousedown);
75     DEFINE_ATTRIBUTE_EVENT_LISTENER(mousemove);
76     DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseout);
77     DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseover);
78     DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseup);
79     DEFINE_ATTRIBUTE_EVENT_LISTENER(mousewheel);
80     DEFINE_ATTRIBUTE_EVENT_LISTENER(scroll);
81     DEFINE_ATTRIBUTE_EVENT_LISTENER(select);
82     DEFINE_ATTRIBUTE_EVENT_LISTENER(submit);
83
84     // These four attribute event handler attributes are overridden by HTMLBodyElement
85     // and HTMLFrameSetElement to forward to the DOMWindow.
86     DECLARE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(blur);
87     DECLARE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(error);
88     DECLARE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(focus);
89     DECLARE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(load);
90
91     // WebKit extensions
92     DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecut);
93     DEFINE_ATTRIBUTE_EVENT_LISTENER(cut);
94     DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy);
95     DEFINE_ATTRIBUTE_EVENT_LISTENER(copy);
96     DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste);
97     DEFINE_ATTRIBUTE_EVENT_LISTENER(paste);
98     DEFINE_ATTRIBUTE_EVENT_LISTENER(reset);
99     DEFINE_ATTRIBUTE_EVENT_LISTENER(search);
100     DEFINE_ATTRIBUTE_EVENT_LISTENER(selectstart);
101 #if ENABLE(TOUCH_EVENTS)
102     DEFINE_ATTRIBUTE_EVENT_LISTENER(touchstart);
103     DEFINE_ATTRIBUTE_EVENT_LISTENER(touchmove);
104     DEFINE_ATTRIBUTE_EVENT_LISTENER(touchend);
105     DEFINE_ATTRIBUTE_EVENT_LISTENER(touchcancel);
106 #endif
107 #if ENABLE(FULLSCREEN_API)
108     DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitfullscreenchange);
109 #endif
110
111     virtual PassRefPtr<DocumentFragment> deprecatedCreateContextualFragment(const String&, FragmentScriptingPermission = FragmentScriptingAllowed);
112
113     bool hasAttribute(const QualifiedName&) const;
114     const AtomicString& getAttribute(const QualifiedName&) const;
115     void setAttribute(const QualifiedName&, const AtomicString& value, ExceptionCode&);
116     void removeAttribute(const QualifiedName&, ExceptionCode&);
117
118     // Typed getters and setters for language bindings.
119     int getIntegralAttribute(const QualifiedName& attributeName) const;
120     void setIntegralAttribute(const QualifiedName& attributeName, int value);
121     unsigned getUnsignedIntegralAttribute(const QualifiedName& attributeName) const;
122     void setUnsignedIntegralAttribute(const QualifiedName& attributeName, unsigned value);
123
124     // Call this to get the value of an attribute that is known not to be the style
125     // attribute or one of the SVG animatable attributes.
126     bool fastHasAttribute(const QualifiedName&) const;
127     const AtomicString& fastGetAttribute(const QualifiedName&) const;
128
129     bool hasAttributes() const;
130
131     bool hasAttribute(const String& name) const;
132     bool hasAttributeNS(const String& namespaceURI, const String& localName) const;
133
134     const AtomicString& getAttribute(const String& name) const;
135     const AtomicString& getAttributeNS(const String& namespaceURI, const String& localName) const;
136
137     void setAttribute(const AtomicString& name, const AtomicString& value, ExceptionCode&);
138     void setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode&, FragmentScriptingPermission = FragmentScriptingAllowed);
139
140     bool isIdAttributeName(const QualifiedName&) const;
141     const AtomicString& getIdAttribute() const;
142     void setIdAttribute(const AtomicString&);
143
144     // Call this to get the value of the id attribute for style resolution purposes.
145     // The value will already be lowercased if the document is in compatibility mode,
146     // so this function is not suitable for non-style uses.
147     const AtomicString& idForStyleResolution() const;
148
149     void scrollIntoView(bool alignToTop = true);
150     void scrollIntoViewIfNeeded(bool centerIfNeeded = true);
151
152     void scrollByLines(int lines);
153     void scrollByPages(int pages);
154
155     int offsetLeft();
156     int offsetTop();
157     int offsetWidth();
158     int offsetHeight();
159     Element* offsetParent();
160     int clientLeft();
161     int clientTop();
162     int clientWidth();
163     int clientHeight();
164     virtual int scrollLeft() const;
165     virtual int scrollTop() const;
166     virtual void setScrollLeft(int);
167     virtual void setScrollTop(int);
168     virtual int scrollWidth() const;
169     virtual int scrollHeight() const;
170
171     IntRect boundsInWindowSpace() const;
172
173     PassRefPtr<ClientRectList> getClientRects() const;
174     PassRefPtr<ClientRect> getBoundingClientRect() const;
175     
176     // Returns the absolute bounding box translated into screen coordinates:
177     IntRect screenRect() const;
178
179     void removeAttribute(const String& name, ExceptionCode&);
180     void removeAttributeNS(const String& namespaceURI, const String& localName, ExceptionCode&);
181
182     PassRefPtr<Attr> getAttributeNode(const String& name);
183     PassRefPtr<Attr> getAttributeNodeNS(const String& namespaceURI, const String& localName);
184     PassRefPtr<Attr> setAttributeNode(Attr*, ExceptionCode&);
185     PassRefPtr<Attr> setAttributeNodeNS(Attr*, ExceptionCode&);
186     PassRefPtr<Attr> removeAttributeNode(Attr*, ExceptionCode&);
187     
188     virtual CSSStyleDeclaration* style();
189
190     const QualifiedName& tagQName() const { return m_tagName; }
191     String tagName() const { return nodeName(); }
192     bool hasTagName(const QualifiedName& tagName) const { return m_tagName.matches(tagName); }
193     
194     // A fast function for checking the local name against another atomic string.
195     bool hasLocalName(const AtomicString& other) const { return m_tagName.localName() == other; }
196     bool hasLocalName(const QualifiedName& other) const { return m_tagName.localName() == other.localName(); }
197
198     const AtomicString& localName() const { return m_tagName.localName(); }
199     const AtomicString& prefix() const { return m_tagName.prefix(); }
200     const AtomicString& namespaceURI() const { return m_tagName.namespaceURI(); }
201
202     virtual KURL baseURI() const;
203
204     virtual String nodeName() const;
205
206     PassRefPtr<Element> cloneElementWithChildren();
207     PassRefPtr<Element> cloneElementWithoutChildren();
208
209     void normalizeAttributes();
210     String nodeNamePreservingCase() const;
211
212     // convenience methods which ignore exceptions
213     void setAttribute(const QualifiedName&, const AtomicString& value);
214     void setBooleanAttribute(const QualifiedName& name, bool);
215     // Please don't use setCStringAttribute in performance-sensitive code;
216     // use a static AtomicString value instead to avoid the conversion overhead.
217     void setCStringAttribute(const QualifiedName&, const char* cStringValue);
218
219     NamedNodeMap* attributes(bool readonly = false) const;
220
221     // This method is called whenever an attribute is added, changed or removed.
222     virtual void attributeChanged(Attribute*, bool preserveDecls = false);
223
224     void setAttributeMap(PassRefPtr<NamedNodeMap>, FragmentScriptingPermission = FragmentScriptingAllowed);
225     NamedNodeMap* attributeMap() const { return m_attributeMap.get(); }
226
227     virtual void copyNonAttributeProperties(const Element* /*source*/) { }
228
229     virtual void attach();
230     virtual void detach();
231     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
232     virtual void recalcStyle(StyleChange = NoChange);
233
234     Node* shadowRoot();
235     void setShadowRoot(PassRefPtr<Node>);
236     virtual const AtomicString& shadowPseudoId() const;
237
238     RenderStyle* computedStyle(PseudoId = NOPSEUDO);
239
240     AtomicString computeInheritedLanguage() const;
241
242     void dispatchAttrRemovalEvent(Attribute*);
243     void dispatchAttrAdditionEvent(Attribute*);
244
245     virtual void accessKeyAction(bool /*sendToAnyEvent*/) { }
246
247     virtual bool isURLAttribute(Attribute*) const;
248
249     KURL getURLAttribute(const QualifiedName&) const;
250     KURL getNonEmptyURLAttribute(const QualifiedName&) const;
251
252     virtual const QualifiedName& imageSourceAttributeName() const;
253     virtual String target() const { return String(); }
254
255     virtual void focus(bool restorePreviousSelection = true);
256     virtual void updateFocusAppearance(bool restorePreviousSelection);
257     void blur();
258
259     String innerText() const;
260     String outerText() const;
261  
262     virtual String title() const;
263
264     String openTagStartToString() const;
265
266     void updateId(const AtomicString& oldId, const AtomicString& newId);
267
268     IntSize minimumSizeForResizing() const;
269     void setMinimumSizeForResizing(const IntSize&);
270
271     // Use Document::registerForDocumentActivationCallbacks() to subscribe to these
272     virtual void documentWillBecomeInactive() { }
273     virtual void documentDidBecomeActive() { }
274
275     // Use Document::registerForMediaVolumeCallbacks() to subscribe to this
276     virtual void mediaVolumeDidChange() { }
277
278     // Use Document::registerForPrivateBrowsingStateChangedCallbacks() to subscribe to this.
279     virtual void privateBrowsingStateDidChange() { }
280
281     bool isFinishedParsingChildren() const { return isParsingChildrenFinished(); }
282     virtual void finishParsingChildren();
283     virtual void beginParsingChildren();
284
285     // ElementTraversal API
286     Element* firstElementChild() const;
287     Element* lastElementChild() const;
288     Element* previousElementSibling() const;
289     Element* nextElementSibling() const;
290     unsigned childElementCount() const;
291
292     bool webkitMatchesSelector(const String& selectors, ExceptionCode&);
293
294     DOMTokenList* classList();
295     DOMTokenList* optionalClassList() const;
296
297     DOMStringMap* dataset();
298     DOMStringMap* optionalDataset() const;
299
300 #if ENABLE(MATHML)
301     virtual bool isMathMLElement() const { return false; }
302 #else
303     static bool isMathMLElement() { return false; }
304 #endif
305
306     virtual bool isFormControlElement() const { return false; }
307     virtual bool isEnabledFormControl() const { return true; }
308     virtual bool isReadOnlyFormControl() const { return false; }
309     virtual bool isSpinButtonElement() const { return false; }
310     virtual bool isTextFormControl() const { return false; }
311     virtual bool isOptionalFormControl() const { return false; }
312     virtual bool isRequiredFormControl() const { return false; }
313     virtual bool isDefaultButtonForForm() const { return false; }
314     virtual bool willValidate() const { return false; }
315     virtual bool isValidFormControlElement() { return false; }
316     virtual bool hasUnacceptableValue() const { return false; }
317     virtual bool isInRange() const { return false; }
318     virtual bool isOutOfRange() const { return false; }
319
320     virtual bool formControlValueMatchesRenderer() const { return false; }
321     virtual void setFormControlValueMatchesRenderer(bool) { }
322
323     virtual const AtomicString& formControlName() const { return nullAtom; }
324     virtual const AtomicString& formControlType() const { return nullAtom; }
325
326     virtual bool shouldSaveAndRestoreFormControlState() const { return true; }
327     virtual bool saveFormControlState(String&) const { return false; }
328     virtual void restoreFormControlState(const String&) { }
329
330     virtual bool wasChangedSinceLastFormControlChangeEvent() const;
331     virtual void setChangedSinceLastFormControlChangeEvent(bool);
332     virtual void dispatchFormControlChangeEvent() { }
333
334 #if ENABLE(SVG)
335     virtual bool childShouldCreateRenderer(Node*) const; 
336 #endif
337     
338 #if ENABLE(FULLSCREEN_API)
339     enum {
340         ALLOW_KEYBOARD_INPUT = 1
341     };
342     
343     void webkitRequestFullScreen(unsigned short flags);
344 #endif
345
346     virtual bool isSpellCheckingEnabled() const;
347
348     PassRefPtr<WebKitAnimationList> webkitGetAnimations() const;
349
350 protected:
351     Element(const QualifiedName& tagName, Document* document, ConstructionType type)
352         : ContainerNode(document, type)
353         , m_tagName(tagName)
354     {
355     }
356
357     virtual void insertedIntoDocument();
358     virtual void removedFromDocument();
359     virtual void insertedIntoTree(bool);
360     virtual void removedFromTree(bool);
361     virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
362
363     // The implementation of Element::attributeChanged() calls the following two functions.
364     // They are separated to allow a different flow of control in StyledElement::attributeChanged().
365     void recalcStyleIfNeededAfterAttributeChanged(Attribute*);
366     void updateAfterAttributeChanged(Attribute*);
367
368 private:
369     void scrollByUnits(int units, ScrollGranularity);
370
371     virtual void setPrefix(const AtomicString&, ExceptionCode&);
372     virtual NodeType nodeType() const;
373     virtual bool childTypeAllowed(NodeType);
374
375     virtual PassRefPtr<Attribute> createAttribute(const QualifiedName&, const AtomicString& value);
376     
377 #ifndef NDEBUG
378     virtual void formatForDebugger(char* buffer, unsigned length) const;
379 #endif
380
381     bool pseudoStyleCacheIsInvalid(const RenderStyle* currentStyle, RenderStyle* newStyle);
382
383     void createAttributeMap() const;
384
385     virtual void updateStyleAttribute() const { }
386
387 #if ENABLE(SVG)
388     virtual void updateAnimatedSVGAttribute(const QualifiedName&) const { }
389 #endif
390
391     void cancelFocusAppearanceUpdate();
392
393     virtual const AtomicString& virtualPrefix() const { return prefix(); }
394     virtual const AtomicString& virtualLocalName() const { return localName(); }
395     virtual const AtomicString& virtualNamespaceURI() const { return namespaceURI(); }
396     virtual RenderStyle* virtualComputedStyle(PseudoId pseudoElementSpecifier = NOPSEUDO) { return computedStyle(pseudoElementSpecifier); }
397     
398     // cloneNode is private so that non-virtual cloneElementWithChildren and cloneElementWithoutChildren
399     // are used instead.
400     virtual PassRefPtr<Node> cloneNode(bool deep);
401     virtual PassRefPtr<Element> cloneElementWithoutAttributesAndChildren() const;
402
403     QualifiedName m_tagName;
404     virtual NodeRareData* createRareData();
405
406     ElementRareData* rareData() const;
407     ElementRareData* ensureRareData();
408
409     SpellcheckAttributeState spellcheckAttributeState() const;
410     void removeShadowRoot();
411
412 private:
413     mutable RefPtr<NamedNodeMap> m_attributeMap;
414 };
415     
416 inline Element* toElement(Node* node)
417 {
418     ASSERT(!node || node->isElementNode());
419     return static_cast<Element*>(node);
420 }
421
422 inline const Element* toElement(const Node* node)
423 {
424     ASSERT(!node || node->isElementNode());
425     return static_cast<const Element*>(node);
426 }
427
428 // This will catch anyone doing an unnecessary cast.
429 void toElement(const Element*);
430
431 inline bool Node::hasTagName(const QualifiedName& name) const
432 {
433     return isElementNode() && toElement(this)->hasTagName(name);
434 }
435     
436 inline bool Node::hasLocalName(const AtomicString& name) const
437 {
438     return isElementNode() && toElement(this)->hasLocalName(name);
439 }
440
441 inline bool Node::hasAttributes() const
442 {
443     return isElementNode() && toElement(this)->hasAttributes();
444 }
445
446 inline NamedNodeMap* Node::attributes() const
447 {
448     return isElementNode() ? toElement(this)->attributes() : 0;
449 }
450
451 inline Element* Node::parentElement() const
452 {
453     ContainerNode* parent = parentNode();
454     return parent && parent->isElementNode() ? toElement(parent) : 0;
455 }
456
457 inline NamedNodeMap* Element::attributes(bool readonly) const
458 {
459     if (!isStyleAttributeValid())
460         updateStyleAttribute();
461
462 #if ENABLE(SVG)
463     if (!areSVGAttributesValid())
464         updateAnimatedSVGAttribute(anyQName());
465 #endif
466
467     if (!readonly && !m_attributeMap)
468         createAttributeMap();
469     return m_attributeMap.get();
470 }
471
472 inline void Element::updateId(const AtomicString& oldId, const AtomicString& newId)
473 {
474     if (!inDocument())
475         return;
476
477     if (oldId == newId)
478         return;
479
480     Document* doc = document();
481     if (!oldId.isEmpty())
482         doc->removeElementById(oldId, this);
483     if (!newId.isEmpty())
484         doc->addElementById(newId, this);
485 }
486
487 inline bool Element::fastHasAttribute(const QualifiedName& name) const
488 {
489     return m_attributeMap && m_attributeMap->getAttributeItem(name);
490 }
491
492 inline const AtomicString& Element::fastGetAttribute(const QualifiedName& name) const
493 {
494     if (m_attributeMap) {
495         if (Attribute* attribute = m_attributeMap->getAttributeItem(name))
496             return attribute->value();
497     }
498     return nullAtom;
499 }
500
501 inline const AtomicString& Element::idForStyleResolution() const
502 {
503     ASSERT(hasID());
504     return m_attributeMap->idForStyleResolution();
505 }
506
507 inline bool Element::isIdAttributeName(const QualifiedName& attributeName) const
508 {
509     // FIXME: This check is probably not correct for the case where the document has an id attribute
510     // with a non-null namespace, because it will return false, a false negative, if the prefixes
511     // don't match but the local name and namespace both do. However, since this has been like this
512     // for a while and the code paths may be hot, we'll have to measure performance if we fix it.
513     return attributeName == document()->idAttributeName();
514 }
515
516 inline const AtomicString& Element::getIdAttribute() const
517 {
518     return fastGetAttribute(document()->idAttributeName());
519 }
520
521 inline void Element::setIdAttribute(const AtomicString& value)
522 {
523     setAttribute(document()->idAttributeName(), value);
524 }
525
526 inline const AtomicString& Element::shadowPseudoId() const
527 {
528     return nullAtom;
529 }
530     
531 inline Element* firstElementChild(const ContainerNode* container)
532 {
533     ASSERT_ARG(container, container);
534     Node* child = container->firstChild();
535     while (child && !child->isElementNode())
536         child = child->nextSibling();
537     return static_cast<Element*>(child);
538 }
539
540 } // namespace
541
542 #endif