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