34caa2224d388042a45cdb729003cb5de9ab487b
[WebKit-https.git] / Source / WebCore / dom / Element.cpp
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  *           (C) 2007 David Smith (catfish.man@gmail.com)
7  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
8  *           (C) 2007 Eric Seidel (eric@webkit.org)
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public License
21  * along with this library; see the file COPYING.LIB.  If not, write to
22  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23  * Boston, MA 02110-1301, USA.
24  */
25
26 #include "config.h"
27 #include "Element.h"
28
29 #include "AXObjectCache.h"
30 #include "Attr.h"
31 #include "CSSParser.h"
32 #include "CSSSelectorList.h"
33 #include "CSSStyleSelector.h"
34 #include "ClassList.h"
35 #include "ClientRect.h"
36 #include "ClientRectList.h"
37 #include "DOMTokenList.h"
38 #include "DatasetDOMStringMap.h"
39 #include "Document.h"
40 #include "DocumentFragment.h"
41 #include "ElementRareData.h"
42 #include "ExceptionCode.h"
43 #include "FocusController.h"
44 #include "Frame.h"
45 #include "FrameView.h"
46 #include "HTMLElement.h"
47 #include "HTMLNames.h"
48 #include "HTMLParserIdioms.h"
49 #include "InspectorInstrumentation.h"
50 #include "NodeList.h"
51 #include "NodeRenderStyle.h"
52 #include "Page.h"
53 #include "RenderLayer.h"
54 #include "RenderView.h"
55 #include "RenderWidget.h"
56 #include "Settings.h"
57 #include "TextIterator.h"
58 #include "XMLNames.h"
59 #include <wtf/text/CString.h>
60
61 #if ENABLE(SVG)
62 #include "SVGElement.h"
63 #include "SVGNames.h"
64 #endif
65
66 namespace WebCore {
67
68 using namespace HTMLNames;
69 using namespace XMLNames;
70     
71 PassRefPtr<Element> Element::create(const QualifiedName& tagName, Document* document)
72 {
73     return adoptRef(new Element(tagName, document, CreateElement));
74 }
75
76 Element::~Element()
77 {
78     if (m_attributeMap)
79         m_attributeMap->detachFromElement();
80 }
81
82 inline ElementRareData* Element::rareData() const
83 {
84     ASSERT(hasRareData());
85     return static_cast<ElementRareData*>(NodeRareData::rareDataFromMap(this));
86 }
87     
88 inline ElementRareData* Element::ensureRareData()
89 {
90     return static_cast<ElementRareData*>(Node::ensureRareData());
91 }
92     
93 NodeRareData* Element::createRareData()
94 {
95     return new ElementRareData;
96 }
97
98 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, blur);
99 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, error);
100 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, focus);
101 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, load);
102
103 PassRefPtr<DocumentFragment> Element::deprecatedCreateContextualFragment(const String& markup, FragmentScriptingPermission scriptingPermission)
104 {
105     RefPtr<DocumentFragment> fragment = document()->createDocumentFragment();
106
107     if (document()->isHTMLDocument())
108         fragment->parseHTML(markup, this, scriptingPermission);
109     else {
110         if (!fragment->parseXML(markup, this, scriptingPermission))
111             // FIXME: We should propagate a syntax error exception out here.
112             return 0;
113     }
114
115     // Exceptions are ignored because none ought to happen here.
116     ExceptionCode ignoredExceptionCode;
117
118     // We need to pop <html> and <body> elements and remove <head> to
119     // accommodate folks passing complete HTML documents to make the
120     // child of an element.
121
122     RefPtr<Node> nextNode;
123     for (RefPtr<Node> node = fragment->firstChild(); node; node = nextNode) {
124         nextNode = node->nextSibling();
125         if (node->hasTagName(htmlTag) || node->hasTagName(bodyTag)) {
126             HTMLElement* element = static_cast<HTMLElement*>(node.get());
127             Node* firstChild = element->firstChild();
128             if (firstChild)
129                 nextNode = firstChild;
130             RefPtr<Node> nextChild;
131             for (RefPtr<Node> child = firstChild; child; child = nextChild) {
132                 nextChild = child->nextSibling();
133                 element->removeChild(child.get(), ignoredExceptionCode);
134                 ASSERT(!ignoredExceptionCode);
135                 fragment->insertBefore(child, element, ignoredExceptionCode);
136                 ASSERT(!ignoredExceptionCode);
137             }
138             fragment->removeChild(element, ignoredExceptionCode);
139             ASSERT(!ignoredExceptionCode);
140         } else if (node->hasTagName(headTag)) {
141             fragment->removeChild(node.get(), ignoredExceptionCode);
142             ASSERT(!ignoredExceptionCode);
143         }
144     }
145     return fragment.release();
146 }
147     
148 PassRefPtr<Node> Element::cloneNode(bool deep)
149 {
150     return deep ? cloneElementWithChildren() : cloneElementWithoutChildren();
151 }
152
153 PassRefPtr<Element> Element::cloneElementWithChildren()
154 {
155     RefPtr<Element> clone = cloneElementWithoutChildren();
156     cloneChildNodes(clone.get());
157     return clone.release();
158 }
159
160 PassRefPtr<Element> Element::cloneElementWithoutChildren()
161 {
162     RefPtr<Element> clone = cloneElementWithoutAttributesAndChildren();
163     // This will catch HTML elements in the wrong namespace that are not correctly copied.
164     // This is a sanity check as HTML overloads some of the DOM methods.
165     ASSERT(isHTMLElement() == clone->isHTMLElement());
166
167     // Call attributes(true) to force attribute synchronization to occur for SVG and style attributes.
168     if (NamedNodeMap* attributeMap = attributes(true))
169         clone->attributes()->setAttributes(*attributeMap);
170
171     clone->copyNonAttributeProperties(this);
172
173     return clone.release();
174 }
175
176 PassRefPtr<Element> Element::cloneElementWithoutAttributesAndChildren() const
177 {
178     return document()->createElement(tagQName(), false);
179 }
180
181 void Element::removeAttribute(const QualifiedName& name, ExceptionCode& ec)
182 {
183     if (m_attributeMap) {
184         ec = 0;
185         m_attributeMap->removeNamedItem(name, ec);
186         if (ec == NOT_FOUND_ERR)
187             ec = 0;
188     }
189 }
190
191 void Element::setAttribute(const QualifiedName& name, const AtomicString& value)
192 {
193     ExceptionCode ec;
194     setAttribute(name, value, ec);
195 }
196     
197 void Element::setCStringAttribute(const QualifiedName& name, const char* cStringValue)
198 {
199     ExceptionCode ec;
200     setAttribute(name, AtomicString(cStringValue), ec);
201 }
202
203 void Element::setBooleanAttribute(const QualifiedName& name, bool b)
204 {
205     if (b)
206         setAttribute(name, emptyAtom);
207     else {
208         ExceptionCode ex;
209         removeAttribute(name, ex);
210     }
211 }
212
213 Node::NodeType Element::nodeType() const
214 {
215     return ELEMENT_NODE;
216 }
217
218 bool Element::hasAttribute(const QualifiedName& name) const
219 {
220     return hasAttributeNS(name.namespaceURI(), name.localName());
221 }
222
223 const AtomicString& Element::getAttribute(const QualifiedName& name) const
224 {
225     if (UNLIKELY(name == styleAttr) && !isStyleAttributeValid())
226         updateStyleAttribute();
227
228 #if ENABLE(SVG)
229     if (UNLIKELY(!areSVGAttributesValid()))
230         updateAnimatedSVGAttribute(name);
231 #endif
232
233     return fastGetAttribute(name);
234 }
235
236 void Element::scrollIntoView(bool alignToTop) 
237 {
238     document()->updateLayoutIgnorePendingStylesheets();
239     IntRect bounds = getRect();    
240     if (renderer()) {
241         // Align to the top / bottom and to the closest edge.
242         if (alignToTop)
243             renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
244         else
245             renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignBottomAlways);
246     }
247 }
248
249 void Element::scrollIntoViewIfNeeded(bool centerIfNeeded)
250 {
251     document()->updateLayoutIgnorePendingStylesheets();
252     IntRect bounds = getRect();    
253     if (renderer()) {
254         if (centerIfNeeded)
255             renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, ScrollAlignment::alignCenterIfNeeded, ScrollAlignment::alignCenterIfNeeded);
256         else
257             renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
258     }
259 }
260
261 void Element::scrollByUnits(int units, ScrollGranularity granularity)
262 {
263     document()->updateLayoutIgnorePendingStylesheets();
264     if (RenderObject *rend = renderer()) {
265         if (rend->hasOverflowClip()) {
266             ScrollDirection direction = ScrollDown;
267             if (units < 0) {
268                 direction = ScrollUp;
269                 units = -units;
270             }
271             toRenderBox(rend)->layer()->scroll(direction, granularity, units);
272         }
273     }
274 }
275
276 void Element::scrollByLines(int lines)
277 {
278     scrollByUnits(lines, ScrollByLine);
279 }
280
281 void Element::scrollByPages(int pages)
282 {
283     scrollByUnits(pages, ScrollByPage);
284 }
285
286 static float localZoomForRenderer(RenderObject* renderer)
287 {
288     // FIXME: This does the wrong thing if two opposing zooms are in effect and canceled each
289     // other out, but the alternative is that we'd have to crawl up the whole render tree every
290     // time (or store an additional bit in the RenderStyle to indicate that a zoom was specified).
291     float zoomFactor = 1;
292     if (renderer->style()->effectiveZoom() != 1) {
293         // Need to find the nearest enclosing RenderObject that set up
294         // a differing zoom, and then we divide our result by it to eliminate the zoom.
295         RenderObject* prev = renderer;
296         for (RenderObject* curr = prev->parent(); curr; curr = curr->parent()) {
297             if (curr->style()->effectiveZoom() != prev->style()->effectiveZoom()) {
298                 zoomFactor = prev->style()->zoom();
299                 break;
300             }
301             prev = curr;
302         }
303         if (prev->isRenderView())
304             zoomFactor = prev->style()->zoom();
305     }
306     return zoomFactor;
307 }
308
309 static int adjustForLocalZoom(int value, RenderObject* renderer)
310 {
311     float zoomFactor = localZoomForRenderer(renderer);
312     if (zoomFactor == 1)
313         return value;
314     // Needed because computeLengthInt truncates (rather than rounds) when scaling up.
315     if (zoomFactor > 1)
316         value++;
317     return static_cast<int>(value / zoomFactor);
318 }
319
320 int Element::offsetLeft()
321 {
322     document()->updateLayoutIgnorePendingStylesheets();
323     if (RenderBoxModelObject* rend = renderBoxModelObject())
324         return adjustForLocalZoom(rend->offsetLeft(), rend);
325     return 0;
326 }
327
328 int Element::offsetTop()
329 {
330     document()->updateLayoutIgnorePendingStylesheets();
331     if (RenderBoxModelObject* rend = renderBoxModelObject())
332         return adjustForLocalZoom(rend->offsetTop(), rend);
333     return 0;
334 }
335
336 int Element::offsetWidth()
337 {
338     document()->updateLayoutIgnorePendingStylesheets();
339     if (RenderBoxModelObject* rend = renderBoxModelObject())
340         return adjustForAbsoluteZoom(rend->offsetWidth(), rend);
341     return 0;
342 }
343
344 int Element::offsetHeight()
345 {
346     document()->updateLayoutIgnorePendingStylesheets();
347     if (RenderBoxModelObject* rend = renderBoxModelObject())
348         return adjustForAbsoluteZoom(rend->offsetHeight(), rend);
349     return 0;
350 }
351
352 Element* Element::offsetParent()
353 {
354     document()->updateLayoutIgnorePendingStylesheets();
355     if (RenderObject* rend = renderer())
356         if (RenderObject* offsetParent = rend->offsetParent())
357             return static_cast<Element*>(offsetParent->node());
358     return 0;
359 }
360
361 int Element::clientLeft()
362 {
363     document()->updateLayoutIgnorePendingStylesheets();
364
365     if (RenderBox* rend = renderBox())
366         return adjustForAbsoluteZoom(rend->clientLeft(), rend);
367     return 0;
368 }
369
370 int Element::clientTop()
371 {
372     document()->updateLayoutIgnorePendingStylesheets();
373
374     if (RenderBox* rend = renderBox())
375         return adjustForAbsoluteZoom(rend->clientTop(), rend);
376     return 0;
377 }
378
379 int Element::clientWidth()
380 {
381     document()->updateLayoutIgnorePendingStylesheets();
382
383     // When in strict mode, clientWidth for the document element should return the width of the containing frame.
384     // When in quirks mode, clientWidth for the body element should return the width of the containing frame.
385     bool inQuirksMode = document()->inQuirksMode();
386     if ((!inQuirksMode && document()->documentElement() == this) ||
387         (inQuirksMode && isHTMLElement() && document()->body() == this)) {
388         if (FrameView* view = document()->view()) {
389             if (RenderView* renderView = document()->renderView())
390                 return adjustForAbsoluteZoom(view->layoutWidth(), renderView);
391         }
392     }
393     
394     if (RenderBox* rend = renderBox())
395         return adjustForAbsoluteZoom(rend->clientWidth(), rend);
396     return 0;
397 }
398
399 int Element::clientHeight()
400 {
401     document()->updateLayoutIgnorePendingStylesheets();
402
403     // When in strict mode, clientHeight for the document element should return the height of the containing frame.
404     // When in quirks mode, clientHeight for the body element should return the height of the containing frame.
405     bool inQuirksMode = document()->inQuirksMode();     
406
407     if ((!inQuirksMode && document()->documentElement() == this) ||
408         (inQuirksMode && isHTMLElement() && document()->body() == this)) {
409         if (FrameView* view = document()->view()) {
410             if (RenderView* renderView = document()->renderView())
411                 return adjustForAbsoluteZoom(view->layoutHeight(), renderView);
412         }
413     }
414     
415     if (RenderBox* rend = renderBox())
416         return adjustForAbsoluteZoom(rend->clientHeight(), rend);
417     return 0;
418 }
419
420 int Element::scrollLeft() const
421 {
422     document()->updateLayoutIgnorePendingStylesheets();
423     if (RenderBox* rend = renderBox())
424         return adjustForAbsoluteZoom(rend->scrollLeft(), rend);
425     return 0;
426 }
427
428 int Element::scrollTop() const
429 {
430     document()->updateLayoutIgnorePendingStylesheets();
431     if (RenderBox* rend = renderBox())
432         return adjustForAbsoluteZoom(rend->scrollTop(), rend);
433     return 0;
434 }
435
436 void Element::setScrollLeft(int newLeft)
437 {
438     document()->updateLayoutIgnorePendingStylesheets();
439     if (RenderBox* rend = renderBox())
440         rend->setScrollLeft(static_cast<int>(newLeft * rend->style()->effectiveZoom()));
441 }
442
443 void Element::setScrollTop(int newTop)
444 {
445     document()->updateLayoutIgnorePendingStylesheets();
446     if (RenderBox* rend = renderBox())
447         rend->setScrollTop(static_cast<int>(newTop * rend->style()->effectiveZoom()));
448 }
449
450 int Element::scrollWidth() const
451 {
452     document()->updateLayoutIgnorePendingStylesheets();
453     if (RenderBox* rend = renderBox())
454         return adjustForAbsoluteZoom(rend->scrollWidth(), rend);
455     return 0;
456 }
457
458 int Element::scrollHeight() const
459 {
460     document()->updateLayoutIgnorePendingStylesheets();
461     if (RenderBox* rend = renderBox())
462         return adjustForAbsoluteZoom(rend->scrollHeight(), rend);
463     return 0;
464 }
465
466 IntRect Element::boundsInWindowSpace() const
467 {
468     document()->updateLayoutIgnorePendingStylesheets();
469
470     FrameView* view = document()->view();
471     if (!view)
472         return IntRect();
473
474     Vector<FloatQuad> quads;
475 #if ENABLE(SVG)
476     if (isSVGElement() && renderer()) {
477         // Get the bounding rectangle from the SVG model.
478         const SVGElement* svgElement = static_cast<const SVGElement*>(this);
479         FloatRect localRect;
480         if (svgElement->boundingBox(localRect))
481             quads.append(renderer()->localToAbsoluteQuad(localRect));
482     } else
483 #endif
484     {
485         // Get the bounding rectangle from the box model.
486         if (renderBoxModelObject())
487             renderBoxModelObject()->absoluteQuads(quads);
488     }
489
490     if (quads.isEmpty())
491         return IntRect();
492
493     IntRect result = quads[0].enclosingBoundingBox();
494     for (size_t i = 1; i < quads.size(); ++i)
495         result.unite(quads[i].enclosingBoundingBox());
496
497     result = view->contentsToWindow(result);
498     return result;
499 }
500
501 PassRefPtr<ClientRectList> Element::getClientRects() const
502 {
503     document()->updateLayoutIgnorePendingStylesheets();
504
505     RenderBoxModelObject* renderBoxModelObject = this->renderBoxModelObject();
506     if (!renderBoxModelObject)
507         return ClientRectList::create();
508
509     // FIXME: Handle SVG elements.
510     // FIXME: Handle table/inline-table with a caption.
511
512     Vector<FloatQuad> quads;
513     renderBoxModelObject->absoluteQuads(quads);
514
515     if (FrameView* view = document()->view()) {
516         IntRect visibleContentRect = view->visibleContentRect();
517         for (size_t i = 0; i < quads.size(); ++i) {
518             quads[i].move(-visibleContentRect.x(), -visibleContentRect.y());
519             adjustFloatQuadForAbsoluteZoom(quads[i], renderBoxModelObject);
520         }
521     }
522
523     return ClientRectList::create(quads);
524 }
525
526 PassRefPtr<ClientRect> Element::getBoundingClientRect() const
527 {
528     document()->updateLayoutIgnorePendingStylesheets();
529
530     Vector<FloatQuad> quads;
531 #if ENABLE(SVG)
532     if (isSVGElement() && renderer()) {
533         // Get the bounding rectangle from the SVG model.
534         const SVGElement* svgElement = static_cast<const SVGElement*>(this);
535         FloatRect localRect;
536         if (svgElement->boundingBox(localRect))
537             quads.append(renderer()->localToAbsoluteQuad(localRect));
538     } else
539 #endif
540     {
541         // Get the bounding rectangle from the box model.
542         if (renderBoxModelObject())
543             renderBoxModelObject()->absoluteQuads(quads);
544     }
545
546     if (quads.isEmpty())
547         return ClientRect::create();
548
549     FloatRect result = quads[0].boundingBox();
550     for (size_t i = 1; i < quads.size(); ++i)
551         result.unite(quads[i].boundingBox());
552
553     if (FrameView* view = document()->view()) {
554         IntRect visibleContentRect = view->visibleContentRect();
555         result.move(-visibleContentRect.x(), -visibleContentRect.y());
556     }
557
558     adjustFloatRectForAbsoluteZoom(result, renderer());
559     return ClientRect::create(result);
560 }
561     
562 IntRect Element::screenRect() const
563 {
564     if (!renderer())
565         return IntRect();
566     return renderer()->view()->frameView()->contentsToScreen(renderer()->absoluteBoundingBoxRect());
567 }
568
569 static inline bool shouldIgnoreAttributeCase(const Element* e)
570 {
571     return e && e->document()->isHTMLDocument() && e->isHTMLElement();
572 }
573
574 const AtomicString& Element::getAttribute(const String& name) const
575 {
576     bool ignoreCase = shouldIgnoreAttributeCase(this);
577     
578     // Update the 'style' attribute if it's invalid and being requested:
579     if (!isStyleAttributeValid() && equalPossiblyIgnoringCase(name, styleAttr.localName(), ignoreCase))
580         updateStyleAttribute();
581
582 #if ENABLE(SVG)
583     if (!areSVGAttributesValid()) {
584         // We're not passing a namespace argument on purpose. SVGNames::*Attr are defined w/o namespaces as well.
585         updateAnimatedSVGAttribute(QualifiedName(nullAtom, name, nullAtom));
586     }
587 #endif
588
589     if (m_attributeMap) {
590         if (Attribute* attribute = m_attributeMap->getAttributeItem(name, ignoreCase))
591             return attribute->value();
592     }
593
594     return nullAtom;
595 }
596
597 const AtomicString& Element::getAttributeNS(const String& namespaceURI, const String& localName) const
598 {
599     return getAttribute(QualifiedName(nullAtom, localName, namespaceURI));
600 }
601
602 void Element::setAttribute(const AtomicString& name, const AtomicString& value, ExceptionCode& ec)
603 {
604     if (!Document::isValidName(name)) {
605         ec = INVALID_CHARACTER_ERR;
606         return;
607     }
608
609 #if ENABLE(INSPECTOR)
610     if (!isSynchronizingStyleAttribute())
611         InspectorInstrumentation::willModifyDOMAttr(document(), this);
612 #endif
613
614     const AtomicString& localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
615
616     // Allocate attribute map if necessary.
617     Attribute* old = attributes(false)->getAttributeItem(localName, false);
618
619     document()->incDOMTreeVersion();
620
621     // FIXME: This check is probably not correct for the case where the document has an id attribute
622     // with a non-null namespace, because it will return true if the local name happens to match
623     // but the namespace does not.
624     if (localName == document()->idAttributeName().localName())
625         updateId(old ? old->value() : nullAtom, value);
626
627     if (old && value.isNull())
628         m_attributeMap->removeAttribute(old->name());
629     else if (!old && !value.isNull())
630         m_attributeMap->addAttribute(createAttribute(QualifiedName(nullAtom, localName, nullAtom), value));
631     else if (old && !value.isNull()) {
632         if (Attr* attrNode = old->attr())
633             attrNode->setValue(value);
634         else
635             old->setValue(value);
636         attributeChanged(old);
637     }
638
639 #if ENABLE(INSPECTOR)
640     if (!isSynchronizingStyleAttribute())
641         InspectorInstrumentation::didModifyDOMAttr(document(), this);
642 #endif
643 }
644
645 void Element::setAttribute(const QualifiedName& name, const AtomicString& value, ExceptionCode&)
646 {
647 #if ENABLE(INSPECTOR)
648     if (!isSynchronizingStyleAttribute())
649         InspectorInstrumentation::willModifyDOMAttr(document(), this);
650 #endif
651
652     document()->incDOMTreeVersion();
653
654     // Allocate attribute map if necessary.
655     Attribute* old = attributes(false)->getAttributeItem(name);
656
657     if (isIdAttributeName(name))
658         updateId(old ? old->value() : nullAtom, value);
659
660     if (old && value.isNull())
661         m_attributeMap->removeAttribute(name);
662     else if (!old && !value.isNull())
663         m_attributeMap->addAttribute(createAttribute(name, value));
664     else if (old) {
665         if (Attr* attrNode = old->attr())
666             attrNode->setValue(value);
667         else
668             old->setValue(value);
669         attributeChanged(old);
670     }
671
672 #if ENABLE(INSPECTOR)
673     if (!isSynchronizingStyleAttribute())
674         InspectorInstrumentation::didModifyDOMAttr(document(), this);
675 #endif
676 }
677
678 PassRefPtr<Attribute> Element::createAttribute(const QualifiedName& name, const AtomicString& value)
679 {
680     return Attribute::create(name, value);
681 }
682
683 void Element::attributeChanged(Attribute* attr, bool)
684 {
685     recalcStyleIfNeededAfterAttributeChanged(attr);
686     updateAfterAttributeChanged(attr);
687 }
688
689 void Element::updateAfterAttributeChanged(Attribute* attr)
690 {
691     if (!AXObjectCache::accessibilityEnabled())
692         return;
693
694     const QualifiedName& attrName = attr->name();
695     if (attrName == aria_activedescendantAttr) {
696         // any change to aria-activedescendant attribute triggers accessibility focus change, but document focus remains intact
697         document()->axObjectCache()->handleActiveDescendantChanged(renderer());
698     } else if (attrName == roleAttr) {
699         // the role attribute can change at any time, and the AccessibilityObject must pick up these changes
700         document()->axObjectCache()->handleAriaRoleChanged(renderer());
701     } else if (attrName == aria_valuenowAttr) {
702         // If the valuenow attribute changes, AX clients need to be notified.
703         document()->axObjectCache()->postNotification(renderer(), AXObjectCache::AXValueChanged, true);
704     } else if (attrName == aria_labelAttr || attrName == aria_labeledbyAttr || attrName == altAttr || attrName == titleAttr) {
705         // If the content of an element changes due to an attribute change, notify accessibility.
706         document()->axObjectCache()->contentChanged(renderer());
707     } else if (attrName == aria_selectedAttr)
708         document()->axObjectCache()->selectedChildrenChanged(renderer());
709     else if (attrName == aria_expandedAttr)
710         document()->axObjectCache()->handleAriaExpandedChange(renderer());
711     else if (attrName == aria_hiddenAttr)
712         document()->axObjectCache()->childrenChanged(renderer());
713     else if (attrName == aria_invalidAttr)
714         document()->axObjectCache()->postNotification(renderer(), AXObjectCache::AXInvalidStatusChanged, true);
715 }
716     
717 void Element::recalcStyleIfNeededAfterAttributeChanged(Attribute* attr)
718 {
719     if (document()->attached() && document()->styleSelector()->hasSelectorForAttribute(attr->name().localName()))
720         setNeedsStyleRecalc();
721 }
722
723 // Returns true is the given attribute is an event handler.
724 // We consider an event handler any attribute that begins with "on".
725 // It is a simple solution that has the advantage of not requiring any
726 // code or configuration change if a new event handler is defined.
727
728 static bool isEventHandlerAttribute(const QualifiedName& name)
729 {
730     return name.namespaceURI().isNull() && name.localName().startsWith("on");
731 }
732
733 static bool isAttributeToRemove(const QualifiedName& name, const AtomicString& value)
734 {    
735     return (name.localName().endsWith(hrefAttr.localName()) || name == srcAttr || name == actionAttr) && protocolIsJavaScript(stripLeadingAndTrailingHTMLSpaces(value));       
736 }
737
738 void Element::setAttributeMap(PassRefPtr<NamedNodeMap> list, FragmentScriptingPermission scriptingPermission)
739 {
740     document()->incDOMTreeVersion();
741
742     // If setting the whole map changes the id attribute, we need to call updateId.
743
744     const QualifiedName& idName = document()->idAttributeName();
745     Attribute* oldId = m_attributeMap ? m_attributeMap->getAttributeItem(idName) : 0;
746     Attribute* newId = list ? list->getAttributeItem(idName) : 0;
747
748     if (oldId || newId)
749         updateId(oldId ? oldId->value() : nullAtom, newId ? newId->value() : nullAtom);
750
751     if (m_attributeMap)
752         m_attributeMap->m_element = 0;
753
754     m_attributeMap = list;
755
756     if (m_attributeMap) {
757         m_attributeMap->m_element = this;
758         // If the element is created as result of a paste or drag-n-drop operation
759         // we want to remove all the script and event handlers.
760         if (scriptingPermission == FragmentScriptingNotAllowed) {
761             unsigned i = 0;
762             while (i < m_attributeMap->length()) {
763                 const QualifiedName& attributeName = m_attributeMap->m_attributes[i]->name();
764                 if (isEventHandlerAttribute(attributeName)) {
765                     m_attributeMap->m_attributes.remove(i);
766                     continue;
767                 }
768
769                 if (isAttributeToRemove(attributeName, m_attributeMap->m_attributes[i]->value()))
770                     m_attributeMap->m_attributes[i]->setValue(nullAtom);
771                 i++;
772             }
773         }
774         // Store the set of attributes that changed on the stack in case
775         // attributeChanged mutates m_attributeMap.
776         Vector<RefPtr<Attribute> > attributes;
777         m_attributeMap->copyAttributesToVector(attributes);
778         for (Vector<RefPtr<Attribute> >::iterator iter = attributes.begin(); iter != attributes.end(); ++iter)
779             attributeChanged(iter->get());
780         // FIXME: What about attributes that were in the old map that are not in the new map?
781     }
782 }
783
784 bool Element::hasAttributes() const
785 {
786     if (!isStyleAttributeValid())
787         updateStyleAttribute();
788
789 #if ENABLE(SVG)
790     if (!areSVGAttributesValid())
791         updateAnimatedSVGAttribute(anyQName());
792 #endif
793
794     return m_attributeMap && m_attributeMap->length();
795 }
796
797 String Element::nodeName() const
798 {
799     return m_tagName.toString();
800 }
801
802 String Element::nodeNamePreservingCase() const
803 {
804     return m_tagName.toString();
805 }
806
807 void Element::setPrefix(const AtomicString& prefix, ExceptionCode& ec)
808 {
809     ec = 0;
810     checkSetPrefix(prefix, ec);
811     if (ec)
812         return;
813
814     m_tagName.setPrefix(prefix.isEmpty() ? AtomicString() : prefix);
815 }
816
817 KURL Element::baseURI() const
818 {
819     const AtomicString& baseAttribute = getAttribute(baseAttr);
820     KURL base(KURL(), baseAttribute);
821     if (!base.protocol().isEmpty())
822         return base;
823
824     ContainerNode* parent = parentNode();
825     if (!parent)
826         return base;
827
828     const KURL& parentBase = parent->baseURI();
829     if (parentBase.isNull())
830         return base;
831
832     return KURL(parentBase, baseAttribute);
833 }
834
835 void Element::createAttributeMap() const
836 {
837     m_attributeMap = NamedNodeMap::create(const_cast<Element*>(this));
838 }
839
840 bool Element::isURLAttribute(Attribute*) const
841 {
842     return false;
843 }
844
845 const QualifiedName& Element::imageSourceAttributeName() const
846 {
847     return srcAttr;
848 }
849
850 RenderObject* Element::createRenderer(RenderArena* arena, RenderStyle* style)
851 {
852     if (document()->documentElement() == this && style->display() == NONE) {
853         // Ignore display: none on root elements.  Force a display of block in that case.
854         RenderBlock* result = new (arena) RenderBlock(this);
855         if (result)
856             result->setAnimatableStyle(style);
857         return result;
858     }
859     return RenderObject::createObject(this, style);
860 }
861
862
863 void Element::insertedIntoDocument()
864 {
865     // need to do superclass processing first so inDocument() is true
866     // by the time we reach updateId
867     ContainerNode::insertedIntoDocument();
868     if (Node* shadow = shadowRoot())
869         shadow->insertedIntoDocument();
870
871     if (hasID()) {
872         if (m_attributeMap) {
873             Attribute* idItem = m_attributeMap->getAttributeItem(document()->idAttributeName());
874             if (idItem && !idItem->isNull())
875                 updateId(nullAtom, idItem->value());
876         }
877     }
878 }
879
880 void Element::removedFromDocument()
881 {
882     if (hasID()) {
883         if (m_attributeMap) {
884             Attribute* idItem = m_attributeMap->getAttributeItem(document()->idAttributeName());
885             if (idItem && !idItem->isNull())
886                 updateId(idItem->value(), nullAtom);
887         }
888     }
889
890     ContainerNode::removedFromDocument();
891     if (Node* shadow = shadowRoot())
892         shadow->removedFromDocument();
893 }
894
895 void Element::insertedIntoTree(bool deep)
896 {
897     ContainerNode::insertedIntoTree(deep);
898     if (!deep)
899         return;
900     if (Node* shadow = shadowRoot())
901         shadow->insertedIntoTree(true);
902 }
903
904 void Element::removedFromTree(bool deep)
905 {
906     ContainerNode::removedFromTree(deep);
907     if (!deep)
908         return;
909     if (Node* shadow = shadowRoot())
910         shadow->removedFromTree(true);
911 }
912
913 void Element::attach()
914 {
915     suspendPostAttachCallbacks();
916     RenderWidget::suspendWidgetHierarchyUpdates();
917
918     createRendererIfNeeded();
919     ContainerNode::attach();
920     if (Node* shadow = shadowRoot())
921         shadow->attach();
922     if (hasRareData()) {   
923         ElementRareData* data = rareData();
924         if (data->needsFocusAppearanceUpdateSoonAfterAttach()) {
925             if (isFocusable() && document()->focusedNode() == this)
926                 document()->updateFocusAppearanceSoon(false /* don't restore selection */);
927             data->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
928         }
929     }
930
931     RenderWidget::resumeWidgetHierarchyUpdates();
932     resumePostAttachCallbacks();
933 }
934
935 void Element::detach()
936 {
937     RenderWidget::suspendWidgetHierarchyUpdates();
938
939     cancelFocusAppearanceUpdate();
940     if (hasRareData())
941         rareData()->resetComputedStyle();
942     ContainerNode::detach();
943     if (Node* shadow = shadowRoot())
944         shadow->detach();
945
946     RenderWidget::resumeWidgetHierarchyUpdates();
947 }
948
949 bool Element::pseudoStyleCacheIsInvalid(const RenderStyle* currentStyle, RenderStyle* newStyle)
950 {
951     ASSERT(currentStyle == renderStyle());
952
953     if (!renderer() || !currentStyle)
954         return false;
955
956     const PseudoStyleCache* pseudoStyleCache = currentStyle->cachedPseudoStyles();
957     if (!pseudoStyleCache)
958         return false;
959
960     size_t cacheSize = pseudoStyleCache->size();
961     for (size_t i = 0; i < cacheSize; ++i) {
962         RefPtr<RenderStyle> newPseudoStyle;
963         PseudoId pseudoId = pseudoStyleCache->at(i)->styleType();
964         if (pseudoId == VISITED_LINK) {
965             newPseudoStyle =  newStyle->getCachedPseudoStyle(VISITED_LINK); // This pseudo-style was aggressively computed already when we first called styleForElement on the new style.
966             if (!newPseudoStyle || *newPseudoStyle != *pseudoStyleCache->at(i))
967                 return true;
968         } else if (pseudoId == FIRST_LINE || pseudoId == FIRST_LINE_INHERITED)
969             newPseudoStyle = renderer()->uncachedFirstLineStyle(newStyle);
970         else
971             newPseudoStyle = renderer()->getUncachedPseudoStyle(pseudoId, newStyle, newStyle);
972         if (!newPseudoStyle)
973             return true;
974         if (*newPseudoStyle != *pseudoStyleCache->at(i)) {
975             if (pseudoId < FIRST_INTERNAL_PSEUDOID)
976                 newStyle->setHasPseudoStyle(pseudoId);
977             newStyle->addCachedPseudoStyle(newPseudoStyle);
978             if (pseudoId == FIRST_LINE || pseudoId == FIRST_LINE_INHERITED) {
979                 // FIXME: We should do an actual diff to determine whether a repaint vs. layout
980                 // is needed, but for now just assume a layout will be required.  The diff code
981                 // in RenderObject::setStyle would need to be factored out so that it could be reused.
982                 renderer()->setNeedsLayoutAndPrefWidthsRecalc();
983             }
984             return true;
985         }
986     }
987     return false;
988 }
989
990 void Element::recalcStyle(StyleChange change)
991 {
992     // Ref currentStyle in case it would otherwise be deleted when setRenderStyle() is called.
993     RefPtr<RenderStyle> currentStyle(renderStyle());
994     bool hasParentStyle = parentOrHostNode() ? parentOrHostNode()->renderStyle() : false;
995     bool hasPositionalRules = needsStyleRecalc() && currentStyle && currentStyle->childrenAffectedByPositionalRules();
996     bool hasDirectAdjacentRules = currentStyle && currentStyle->childrenAffectedByDirectAdjacentRules();
997
998     if ((change > NoChange || needsStyleRecalc())) {
999         if (hasRareData())
1000             rareData()->resetComputedStyle();
1001     }
1002     if (hasParentStyle && (change >= Inherit || needsStyleRecalc())) {
1003         RefPtr<RenderStyle> newStyle = document()->styleSelector()->styleForElement(this);
1004         StyleChange ch = diff(currentStyle.get(), newStyle.get());
1005         if (ch == Detach || !currentStyle) {
1006             if (attached())
1007                 detach();
1008             attach(); // FIXME: The style gets computed twice by calling attach. We could do better if we passed the style along.
1009             // attach recalulates the style for all children. No need to do it twice.
1010             clearNeedsStyleRecalc();
1011             clearChildNeedsStyleRecalc();
1012             return;
1013         }
1014
1015         if (currentStyle) {
1016             // Preserve "affected by" bits that were propagated to us from descendants in the case where we didn't do a full
1017             // style change (e.g., only inline style changed).
1018             if (currentStyle->affectedByHoverRules())
1019                 newStyle->setAffectedByHoverRules(true);
1020             if (currentStyle->affectedByActiveRules())
1021                 newStyle->setAffectedByActiveRules(true);
1022             if (currentStyle->affectedByDragRules())
1023                 newStyle->setAffectedByDragRules(true);
1024             if (currentStyle->childrenAffectedByForwardPositionalRules())
1025                 newStyle->setChildrenAffectedByForwardPositionalRules();
1026             if (currentStyle->childrenAffectedByBackwardPositionalRules())
1027                 newStyle->setChildrenAffectedByBackwardPositionalRules();
1028             if (currentStyle->childrenAffectedByFirstChildRules())
1029                 newStyle->setChildrenAffectedByFirstChildRules();
1030             if (currentStyle->childrenAffectedByLastChildRules())
1031                 newStyle->setChildrenAffectedByLastChildRules();
1032             if (currentStyle->childrenAffectedByDirectAdjacentRules())
1033                 newStyle->setChildrenAffectedByDirectAdjacentRules();
1034         }
1035
1036         if (ch != NoChange || pseudoStyleCacheIsInvalid(currentStyle.get(), newStyle.get()) || (change == Force && renderer() && renderer()->requiresForcedStyleRecalcPropagation())) {
1037             setRenderStyle(newStyle);
1038         } else if (needsStyleRecalc() && (styleChangeType() != SyntheticStyleChange) && (document()->usesSiblingRules() || document()->usesDescendantRules())) {
1039             // Although no change occurred, we use the new style so that the cousin style sharing code won't get
1040             // fooled into believing this style is the same.  This is only necessary if the document actually uses
1041             // sibling/descendant rules, since otherwise it isn't possible for ancestor styles to affect sharing of
1042             // descendants.
1043             if (renderer())
1044                 renderer()->setStyleInternal(newStyle.get());
1045             else
1046                 setRenderStyle(newStyle);
1047         } else if (styleChangeType() == SyntheticStyleChange)
1048              setRenderStyle(newStyle);
1049
1050         if (change != Force) {
1051             // If "rem" units are used anywhere in the document, and if the document element's font size changes, then go ahead and force font updating
1052             // all the way down the tree.  This is simpler than having to maintain a cache of objects (and such font size changes should be rare anyway).
1053             if (document()->usesRemUnits() && ch != NoChange && currentStyle && newStyle && currentStyle->fontSize() != newStyle->fontSize() && document()->documentElement() == this)
1054                 change = Force;
1055             else if ((document()->usesDescendantRules() || hasPositionalRules) && styleChangeType() >= FullStyleChange)
1056                 change = Force;
1057             else
1058                 change = ch;
1059         }
1060     }
1061
1062     // FIXME: This check is good enough for :hover + foo, but it is not good enough for :hover + foo + bar.
1063     // For now we will just worry about the common case, since it's a lot trickier to get the second case right
1064     // without doing way too much re-resolution.
1065     bool forceCheckOfNextElementSibling = false;
1066     for (Node *n = firstChild(); n; n = n->nextSibling()) {
1067         bool childRulesChanged = n->needsStyleRecalc() && n->styleChangeType() == FullStyleChange;
1068         if (forceCheckOfNextElementSibling && n->isElementNode())
1069             n->setNeedsStyleRecalc();
1070         if (change >= Inherit || n->isTextNode() || n->childNeedsStyleRecalc() || n->needsStyleRecalc())
1071             n->recalcStyle(change);
1072         if (n->isElementNode())
1073             forceCheckOfNextElementSibling = childRulesChanged && hasDirectAdjacentRules;
1074     }
1075     // FIXME: This does not care about sibling combinators. Will be necessary in XBL2 world.
1076     if (Node* shadow = shadowRoot()) {
1077         if (change >= Inherit || shadow->isTextNode() || shadow->childNeedsStyleRecalc() || shadow->needsStyleRecalc())
1078             shadow->recalcStyle(change);
1079     }
1080
1081     clearNeedsStyleRecalc();
1082     clearChildNeedsStyleRecalc();
1083 }
1084
1085 Node* Element::shadowRoot()
1086 {
1087     return hasRareData() ? rareData()->m_shadowRoot : 0;
1088 }
1089
1090 void Element::setShadowRoot(PassRefPtr<Node> node)
1091 {
1092     // FIXME: Because today this is never called from script directly, we don't have to worry
1093     // about compromising DOM tree integrity (eg. node being a parent of this). However,
1094     // once we implement XBL2, we will have to add integrity checks here.
1095     removeShadowRoot();
1096     if (!node)
1097         return;
1098
1099     ElementRareData* data = ensureRareData();
1100     data->m_shadowRoot = node.leakRef();
1101     data->m_shadowRoot->setShadowHost(this);
1102 }
1103
1104 void Element::removeShadowRoot()
1105 {
1106     if (ElementRareData* data = rareData()) {
1107         if (!data->m_shadowRoot)
1108             return;
1109         RefPtr<Node> oldRoot = data->m_shadowRoot;
1110         data->m_shadowRoot = 0;
1111         document()->removeFocusedNodeOfSubtree(oldRoot.get());
1112         oldRoot->setShadowHost(0);
1113         if (oldRoot->inDocument())
1114             oldRoot->removedFromDocument();
1115         else
1116             oldRoot->removedFromTree(true);
1117     }
1118 }
1119
1120 bool Element::childTypeAllowed(NodeType type)
1121 {
1122     switch (type) {
1123     case ELEMENT_NODE:
1124     case TEXT_NODE:
1125     case COMMENT_NODE:
1126     case PROCESSING_INSTRUCTION_NODE:
1127     case CDATA_SECTION_NODE:
1128     case ENTITY_REFERENCE_NODE:
1129         return true;
1130     default:
1131         break;
1132     }
1133     return false;
1134 }
1135
1136 static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool finishedParsingCallback,
1137                                         Node* beforeChange, Node* afterChange, int childCountDelta)
1138 {
1139     if (!style || (e->needsStyleRecalc() && style->childrenAffectedByPositionalRules()))
1140         return;
1141
1142     // :first-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
1143     // In the DOM case, we only need to do something if |afterChange| is not 0.
1144     // |afterChange| is 0 in the parser case, so it works out that we'll skip this block.
1145     if (style->childrenAffectedByFirstChildRules() && afterChange) {
1146         // Find our new first child.
1147         Node* newFirstChild = 0;
1148         for (newFirstChild = e->firstChild(); newFirstChild && !newFirstChild->isElementNode(); newFirstChild = newFirstChild->nextSibling()) {};
1149         
1150         // Find the first element node following |afterChange|
1151         Node* firstElementAfterInsertion = 0;
1152         for (firstElementAfterInsertion = afterChange;
1153              firstElementAfterInsertion && !firstElementAfterInsertion->isElementNode();
1154              firstElementAfterInsertion = firstElementAfterInsertion->nextSibling()) {};
1155         
1156         // This is the insert/append case.
1157         if (newFirstChild != firstElementAfterInsertion && firstElementAfterInsertion && firstElementAfterInsertion->attached() &&
1158             firstElementAfterInsertion->renderStyle() && firstElementAfterInsertion->renderStyle()->firstChildState())
1159             firstElementAfterInsertion->setNeedsStyleRecalc();
1160             
1161         // We also have to handle node removal.
1162         if (childCountDelta < 0 && newFirstChild == firstElementAfterInsertion && newFirstChild && newFirstChild->renderStyle() && !newFirstChild->renderStyle()->firstChildState())
1163             newFirstChild->setNeedsStyleRecalc();
1164     }
1165
1166     // :last-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
1167     // In the DOM case, we only need to do something if |afterChange| is not 0.
1168     if (style->childrenAffectedByLastChildRules() && beforeChange) {
1169         // Find our new last child.
1170         Node* newLastChild = 0;
1171         for (newLastChild = e->lastChild(); newLastChild && !newLastChild->isElementNode(); newLastChild = newLastChild->previousSibling()) {};
1172         
1173         // Find the last element node going backwards from |beforeChange|
1174         Node* lastElementBeforeInsertion = 0;
1175         for (lastElementBeforeInsertion = beforeChange;
1176              lastElementBeforeInsertion && !lastElementBeforeInsertion->isElementNode();
1177              lastElementBeforeInsertion = lastElementBeforeInsertion->previousSibling()) {};
1178         
1179         if (newLastChild != lastElementBeforeInsertion && lastElementBeforeInsertion && lastElementBeforeInsertion->attached() &&
1180             lastElementBeforeInsertion->renderStyle() && lastElementBeforeInsertion->renderStyle()->lastChildState())
1181             lastElementBeforeInsertion->setNeedsStyleRecalc();
1182             
1183         // We also have to handle node removal.  The parser callback case is similar to node removal as well in that we need to change the last child
1184         // to match now.
1185         if ((childCountDelta < 0 || finishedParsingCallback) && newLastChild == lastElementBeforeInsertion && newLastChild && newLastChild->renderStyle() && !newLastChild->renderStyle()->lastChildState())
1186             newLastChild->setNeedsStyleRecalc();
1187     }
1188
1189     // The + selector.  We need to invalidate the first element following the insertion point.  It is the only possible element
1190     // that could be affected by this DOM change.
1191     if (style->childrenAffectedByDirectAdjacentRules() && afterChange) {
1192         Node* firstElementAfterInsertion = 0;
1193         for (firstElementAfterInsertion = afterChange;
1194              firstElementAfterInsertion && !firstElementAfterInsertion->isElementNode();
1195              firstElementAfterInsertion = firstElementAfterInsertion->nextSibling()) {};
1196         if (firstElementAfterInsertion && firstElementAfterInsertion->attached())
1197             firstElementAfterInsertion->setNeedsStyleRecalc();
1198     }
1199
1200     // Forward positional selectors include the ~ selector, nth-child, nth-of-type, first-of-type and only-of-type.
1201     // Backward positional selectors include nth-last-child, nth-last-of-type, last-of-type and only-of-type.
1202     // We have to invalidate everything following the insertion point in the forward case, and everything before the insertion point in the
1203     // backward case.
1204     // |afterChange| is 0 in the parser callback case, so we won't do any work for the forward case if we don't have to.
1205     // For performance reasons we just mark the parent node as changed, since we don't want to make childrenChanged O(n^2) by crawling all our kids
1206     // here.  recalcStyle will then force a walk of the children when it sees that this has happened.
1207     if ((style->childrenAffectedByForwardPositionalRules() && afterChange) ||
1208         (style->childrenAffectedByBackwardPositionalRules() && beforeChange))
1209         e->setNeedsStyleRecalc();
1210     
1211     // :empty selector.
1212     if (style->affectedByEmpty() && (!style->emptyState() || e->hasChildNodes()))
1213         e->setNeedsStyleRecalc();
1214 }
1215
1216 void Element::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
1217 {
1218     ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
1219     if (!changedByParser)
1220         checkForSiblingStyleChanges(this, renderStyle(), false, beforeChange, afterChange, childCountDelta);
1221 }
1222
1223 void Element::finishParsingChildren()
1224 {
1225     ContainerNode::finishParsingChildren();
1226     setIsParsingChildrenFinished();
1227     checkForSiblingStyleChanges(this, renderStyle(), true, lastChild(), 0, 0);
1228 }
1229
1230 void Element::dispatchAttrRemovalEvent(Attribute*)
1231 {
1232     ASSERT(!eventDispatchForbidden());
1233
1234 #if 0
1235     if (!document()->hasListenerType(Document::DOMATTRMODIFIED_LISTENER))
1236         return;
1237     ExceptionCode ec = 0;
1238     dispatchScopedEvent(MutationEvent::create(DOMAttrModifiedEvent, true, attr, attr->value(),
1239         attr->value(), document()->attrName(attr->id()), MutationEvent::REMOVAL), ec);
1240 #endif
1241 }
1242
1243 void Element::dispatchAttrAdditionEvent(Attribute*)
1244 {
1245     ASSERT(!eventDispatchForbidden());
1246
1247 #if 0
1248     if (!document()->hasListenerType(Document::DOMATTRMODIFIED_LISTENER))
1249         return;
1250     ExceptionCode ec = 0;
1251     dispatchScopedEvent(MutationEvent::create(DOMAttrModifiedEvent, true, attr, attr->value(),
1252         attr->value(), document()->attrName(attr->id()), MutationEvent::ADDITION), ec);
1253 #endif
1254 }
1255
1256 String Element::openTagStartToString() const
1257 {
1258     String result = "<" + nodeName();
1259
1260     NamedNodeMap* attrMap = attributes(true);
1261
1262     if (attrMap) {
1263         unsigned numAttrs = attrMap->length();
1264         for (unsigned i = 0; i < numAttrs; i++) {
1265             result += " ";
1266
1267             Attribute *attribute = attrMap->attributeItem(i);
1268             result += attribute->name().toString();
1269             if (!attribute->value().isNull()) {
1270                 result += "=\"";
1271                 // FIXME: substitute entities for any instances of " or '
1272                 result += attribute->value();
1273                 result += "\"";
1274             }
1275         }
1276     }
1277
1278     return result;
1279 }
1280
1281 #ifndef NDEBUG
1282 void Element::formatForDebugger(char* buffer, unsigned length) const
1283 {
1284     String result;
1285     String s;
1286     
1287     s = nodeName();
1288     if (s.length() > 0) {
1289         result += s;
1290     }
1291           
1292     s = getIdAttribute();
1293     if (s.length() > 0) {
1294         if (result.length() > 0)
1295             result += "; ";
1296         result += "id=";
1297         result += s;
1298     }
1299           
1300     s = getAttribute(classAttr);
1301     if (s.length() > 0) {
1302         if (result.length() > 0)
1303             result += "; ";
1304         result += "class=";
1305         result += s;
1306     }
1307           
1308     strncpy(buffer, result.utf8().data(), length - 1);
1309 }
1310 #endif
1311
1312 PassRefPtr<Attr> Element::setAttributeNode(Attr* attr, ExceptionCode& ec)
1313 {
1314     if (!attr) {
1315         ec = TYPE_MISMATCH_ERR;
1316         return 0;
1317     }
1318     return static_pointer_cast<Attr>(attributes(false)->setNamedItem(attr, ec));
1319 }
1320
1321 PassRefPtr<Attr> Element::setAttributeNodeNS(Attr* attr, ExceptionCode& ec)
1322 {
1323     if (!attr) {
1324         ec = TYPE_MISMATCH_ERR;
1325         return 0;
1326     }
1327     return static_pointer_cast<Attr>(attributes(false)->setNamedItem(attr, ec));
1328 }
1329
1330 PassRefPtr<Attr> Element::removeAttributeNode(Attr* attr, ExceptionCode& ec)
1331 {
1332     if (!attr) {
1333         ec = TYPE_MISMATCH_ERR;
1334         return 0;
1335     }
1336     if (attr->ownerElement() != this) {
1337         ec = NOT_FOUND_ERR;
1338         return 0;
1339     }
1340     if (document() != attr->document()) {
1341         ec = WRONG_DOCUMENT_ERR;
1342         return 0;
1343     }
1344
1345     NamedNodeMap* attrs = attributes(true);
1346     if (!attrs)
1347         return 0;
1348
1349     return static_pointer_cast<Attr>(attrs->removeNamedItem(attr->qualifiedName(), ec));
1350 }
1351
1352 void Element::setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode& ec, FragmentScriptingPermission scriptingPermission)
1353 {
1354     String prefix, localName;
1355     if (!Document::parseQualifiedName(qualifiedName, prefix, localName, ec))
1356         return;
1357
1358     if (namespaceURI.isNull() && !prefix.isNull()) {
1359         ec = NAMESPACE_ERR;
1360         return;
1361     }
1362
1363     QualifiedName qName(prefix, localName, namespaceURI);
1364
1365     if (scriptingPermission == FragmentScriptingNotAllowed && (isEventHandlerAttribute(qName) || isAttributeToRemove(qName, value)))
1366         return;
1367
1368     setAttribute(qName, value, ec);
1369 }
1370
1371 void Element::removeAttribute(const String& name, ExceptionCode& ec)
1372 {
1373     InspectorInstrumentation::willModifyDOMAttr(document(), this);
1374
1375     String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
1376
1377     if (m_attributeMap) {
1378         m_attributeMap->removeNamedItem(localName, ec);
1379         if (ec == NOT_FOUND_ERR)
1380             ec = 0;
1381     }
1382     
1383     InspectorInstrumentation::didModifyDOMAttr(document(), this);
1384 }
1385
1386 void Element::removeAttributeNS(const String& namespaceURI, const String& localName, ExceptionCode& ec)
1387 {
1388     removeAttribute(QualifiedName(nullAtom, localName, namespaceURI), ec);
1389 }
1390
1391 PassRefPtr<Attr> Element::getAttributeNode(const String& name)
1392 {
1393     NamedNodeMap* attrs = attributes(true);
1394     if (!attrs)
1395         return 0;
1396     String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
1397     return static_pointer_cast<Attr>(attrs->getNamedItem(localName));
1398 }
1399
1400 PassRefPtr<Attr> Element::getAttributeNodeNS(const String& namespaceURI, const String& localName)
1401 {
1402     NamedNodeMap* attrs = attributes(true);
1403     if (!attrs)
1404         return 0;
1405     return static_pointer_cast<Attr>(attrs->getNamedItem(QualifiedName(nullAtom, localName, namespaceURI)));
1406 }
1407
1408 bool Element::hasAttribute(const String& name) const
1409 {
1410     NamedNodeMap* attrs = attributes(true);
1411     if (!attrs)
1412         return false;
1413
1414     // This call to String::lower() seems to be required but
1415     // there may be a way to remove it.
1416     String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
1417     return attrs->getAttributeItem(localName, false);
1418 }
1419
1420 bool Element::hasAttributeNS(const String& namespaceURI, const String& localName) const
1421 {
1422     NamedNodeMap* attrs = attributes(true);
1423     if (!attrs)
1424         return false;
1425     return attrs->getAttributeItem(QualifiedName(nullAtom, localName, namespaceURI));
1426 }
1427
1428 CSSStyleDeclaration *Element::style()
1429 {
1430     return 0;
1431 }
1432
1433 void Element::focus(bool restorePreviousSelection)
1434 {
1435     Document* doc = document();
1436     if (doc->focusedNode() == this)
1437         return;
1438
1439     // If the stylesheets have already been loaded we can reliably check isFocusable.
1440     // If not, we continue and set the focused node on the focus controller below so
1441     // that it can be updated soon after attach. 
1442     if (doc->haveStylesheetsLoaded()) {
1443         doc->updateLayoutIgnorePendingStylesheets();
1444         if (!isFocusable())
1445             return;
1446     }
1447
1448     if (!supportsFocus())
1449         return;
1450
1451     RefPtr<Node> protect;
1452     if (Page* page = doc->page()) {
1453         // Focus and change event handlers can cause us to lose our last ref.
1454         // If a focus event handler changes the focus to a different node it
1455         // does not make sense to continue and update appearence.
1456         protect = this;
1457         if (!page->focusController()->setFocusedNode(this, doc->frame()))
1458             return;
1459     }
1460
1461     // Setting the focused node above might have invalidated the layout due to scripts.
1462     doc->updateLayoutIgnorePendingStylesheets();
1463
1464     if (!isFocusable()) {
1465         ensureRareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(true);
1466         return;
1467     }
1468         
1469     cancelFocusAppearanceUpdate();
1470     updateFocusAppearance(restorePreviousSelection);
1471 }
1472
1473 void Element::updateFocusAppearance(bool /*restorePreviousSelection*/)
1474 {
1475     if (this == rootEditableElement()) { 
1476         Frame* frame = document()->frame();
1477         if (!frame)
1478             return;
1479         
1480         // When focusing an editable element in an iframe, don't reset the selection if it already contains a selection.
1481         if (this == frame->selection()->rootEditableElement())
1482             return;
1483
1484         // FIXME: We should restore the previous selection if there is one.
1485         VisibleSelection newSelection = VisibleSelection(firstPositionInNode(this), DOWNSTREAM);
1486         
1487         if (frame->selection()->shouldChangeSelection(newSelection)) {
1488             frame->selection()->setSelection(newSelection);
1489             frame->selection()->revealSelection();
1490         }
1491     } else if (renderer() && !renderer()->isWidget())
1492         renderer()->enclosingLayer()->scrollRectToVisible(getRect());
1493 }
1494
1495 void Element::blur()
1496 {
1497     cancelFocusAppearanceUpdate();
1498     Document* doc = document();
1499     if (doc->focusedNode() == this) {
1500         if (doc->frame())
1501             doc->frame()->page()->focusController()->setFocusedNode(0, doc->frame());
1502         else
1503             doc->setFocusedNode(0);
1504     }
1505 }
1506
1507 String Element::innerText() const
1508 {
1509     // We need to update layout, since plainText uses line boxes in the render tree.
1510     document()->updateLayoutIgnorePendingStylesheets();
1511
1512     if (!renderer())
1513         return textContent(true);
1514
1515     return plainText(rangeOfContents(const_cast<Element*>(this)).get());
1516 }
1517
1518 String Element::outerText() const
1519 {
1520     // Getting outerText is the same as getting innerText, only
1521     // setting is different. You would think this should get the plain
1522     // text for the outer range, but this is wrong, <br> for instance
1523     // would return different values for inner and outer text by such
1524     // a rule, but it doesn't in WinIE, and we want to match that.
1525     return innerText();
1526 }
1527
1528 String Element::title() const
1529 {
1530     return String();
1531 }
1532
1533 IntSize Element::minimumSizeForResizing() const
1534 {
1535     return hasRareData() ? rareData()->m_minimumSizeForResizing : defaultMinimumSizeForResizing();
1536 }
1537
1538 void Element::setMinimumSizeForResizing(const IntSize& size)
1539 {
1540     if (size == defaultMinimumSizeForResizing() && !hasRareData())
1541         return;
1542     ensureRareData()->m_minimumSizeForResizing = size;
1543 }
1544
1545 RenderStyle* Element::computedStyle(PseudoId pseudoElementSpecifier)
1546 {
1547     // FIXME: Find and use the renderer from the pseudo element instead of the actual element so that the 'length'
1548     // properties, which are only known by the renderer because it did the layout, will be correct and so that the
1549     // values returned for the ":selection" pseudo-element will be correct.
1550     if (RenderStyle* usedStyle = renderStyle())
1551         return pseudoElementSpecifier ? usedStyle->getCachedPseudoStyle(pseudoElementSpecifier) : usedStyle;
1552
1553     if (!attached())
1554         // FIXME: Try to do better than this. Ensure that styleForElement() works for elements that are not in the
1555         // document tree and figure out when to destroy the computed style for such elements.
1556         return 0;
1557
1558     ElementRareData* data = ensureRareData();
1559     if (!data->m_computedStyle)
1560         data->m_computedStyle = document()->styleForElementIgnoringPendingStylesheets(this);
1561     return pseudoElementSpecifier ? data->m_computedStyle->getCachedPseudoStyle(pseudoElementSpecifier) : data->m_computedStyle.get();
1562 }
1563
1564 AtomicString Element::computeInheritedLanguage() const
1565 {
1566     const Node* n = this;
1567     AtomicString value;
1568     // The language property is inherited, so we iterate over the parents to find the first language.
1569     while (n && value.isNull()) {
1570         if (n->isElementNode()) {
1571             // Spec: xml:lang takes precedence -- http://www.w3.org/TR/xhtml1/#C_7
1572             value = static_cast<const Element*>(n)->fastGetAttribute(XMLNames::langAttr);
1573             if (value.isNull())
1574                 value = static_cast<const Element*>(n)->fastGetAttribute(HTMLNames::langAttr);
1575         } else if (n->isDocumentNode()) {
1576             // checking the MIME content-language
1577             value = static_cast<const Document*>(n)->contentLanguage();
1578         }
1579
1580         n = n->parentNode();
1581     }
1582
1583     return value;
1584 }
1585
1586 void Element::cancelFocusAppearanceUpdate()
1587 {
1588     if (hasRareData())
1589         rareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
1590     if (document()->focusedNode() == this)
1591         document()->cancelFocusAppearanceUpdate();
1592 }
1593
1594 void Element::normalizeAttributes()
1595 {
1596     // Normalize attributes.
1597     NamedNodeMap* attrs = attributes(true);
1598     if (!attrs)
1599         return;
1600
1601     if (attrs->isEmpty())
1602         return;
1603
1604     Vector<RefPtr<Attribute> > attributeVector;
1605     attrs->copyAttributesToVector(attributeVector);
1606     size_t numAttrs = attributeVector.size();
1607     for (size_t i = 0; i < numAttrs; ++i) {
1608         if (Attr* attr = attributeVector[i]->attr())
1609             attr->normalize();
1610     }
1611 }
1612
1613 // ElementTraversal API
1614 Element* Element::firstElementChild() const
1615 {
1616     Node* n = firstChild();
1617     while (n && !n->isElementNode())
1618         n = n->nextSibling();
1619     return static_cast<Element*>(n);
1620 }
1621
1622 Element* Element::lastElementChild() const
1623 {
1624     Node* n = lastChild();
1625     while (n && !n->isElementNode())
1626         n = n->previousSibling();
1627     return static_cast<Element*>(n);
1628 }
1629
1630 Element* Element::previousElementSibling() const
1631 {
1632     Node* n = previousSibling();
1633     while (n && !n->isElementNode())
1634         n = n->previousSibling();
1635     return static_cast<Element*>(n);
1636 }
1637
1638 Element* Element::nextElementSibling() const
1639 {
1640     Node* n = nextSibling();
1641     while (n && !n->isElementNode())
1642         n = n->nextSibling();
1643     return static_cast<Element*>(n);
1644 }
1645
1646 unsigned Element::childElementCount() const
1647 {
1648     unsigned count = 0;
1649     Node* n = firstChild();
1650     while (n) {
1651         count += n->isElementNode();
1652         n = n->nextSibling();
1653     }
1654     return count;
1655 }
1656
1657 bool Element::webkitMatchesSelector(const String& selector, ExceptionCode& ec)
1658 {
1659     if (selector.isEmpty()) {
1660         ec = SYNTAX_ERR;
1661         return false;
1662     }
1663
1664     bool strictParsing = !document()->inQuirksMode();
1665     CSSParser p(strictParsing);
1666
1667     CSSSelectorList selectorList;
1668     p.parseSelector(selector, document(), selectorList);
1669
1670     if (!selectorList.first()) {
1671         ec = SYNTAX_ERR;
1672         return false;
1673     }
1674
1675     // Throw a NAMESPACE_ERR if the selector includes any namespace prefixes.
1676     if (selectorList.selectorsNeedNamespaceResolution()) {
1677         ec = NAMESPACE_ERR;
1678         return false;
1679     }
1680
1681     CSSStyleSelector::SelectorChecker selectorChecker(document(), strictParsing);
1682     for (CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector)) {
1683         if (selectorChecker.checkSelector(selector, this))
1684             return true;
1685     }
1686
1687     return false;
1688 }
1689
1690 DOMTokenList* Element::classList()
1691 {
1692     ElementRareData* data = ensureRareData();
1693     if (!data->m_classList)
1694         data->m_classList = ClassList::create(this);
1695     return data->m_classList.get();
1696 }
1697
1698 DOMTokenList* Element::optionalClassList() const
1699 {
1700     if (!hasRareData())
1701         return 0;
1702     return rareData()->m_classList.get();
1703 }
1704
1705 DOMStringMap* Element::dataset()
1706 {
1707     ElementRareData* data = ensureRareData();
1708     if (!data->m_datasetDOMStringMap)
1709         data->m_datasetDOMStringMap = DatasetDOMStringMap::create(this);
1710     return data->m_datasetDOMStringMap.get();
1711 }
1712
1713 DOMStringMap* Element::optionalDataset() const
1714 {
1715     if (!hasRareData())
1716         return 0;
1717     return rareData()->m_datasetDOMStringMap.get();
1718 }
1719
1720 KURL Element::getURLAttribute(const QualifiedName& name) const
1721 {
1722 #if !ASSERT_DISABLED
1723     if (m_attributeMap) {
1724         if (Attribute* attribute = m_attributeMap->getAttributeItem(name))
1725             ASSERT(isURLAttribute(attribute));
1726     }
1727 #endif
1728     return document()->completeURL(stripLeadingAndTrailingHTMLSpaces(getAttribute(name)));
1729 }
1730
1731 KURL Element::getNonEmptyURLAttribute(const QualifiedName& name) const
1732 {
1733 #if !ASSERT_DISABLED
1734     if (m_attributeMap) {
1735         if (Attribute* attribute = m_attributeMap->getAttributeItem(name))
1736             ASSERT(isURLAttribute(attribute));
1737     }
1738 #endif
1739     String value = stripLeadingAndTrailingHTMLSpaces(getAttribute(name));
1740     if (value.isEmpty())
1741         return KURL();
1742     return document()->completeURL(value);
1743 }
1744
1745 int Element::getIntegralAttribute(const QualifiedName& attributeName) const
1746 {
1747     return getAttribute(attributeName).string().toInt();
1748 }
1749
1750 void Element::setIntegralAttribute(const QualifiedName& attributeName, int value)
1751 {
1752     // FIXME: Need an AtomicString version of String::number.
1753     ExceptionCode ec;
1754     setAttribute(attributeName, String::number(value), ec);
1755 }
1756
1757 unsigned Element::getUnsignedIntegralAttribute(const QualifiedName& attributeName) const
1758 {
1759     return getAttribute(attributeName).string().toUInt();
1760 }
1761
1762 void Element::setUnsignedIntegralAttribute(const QualifiedName& attributeName, unsigned value)
1763 {
1764     // FIXME: Need an AtomicString version of String::number.
1765     ExceptionCode ec;
1766     setAttribute(attributeName, String::number(value), ec);
1767 }
1768
1769 #if ENABLE(SVG)
1770 bool Element::childShouldCreateRenderer(Node* child) const
1771 {
1772     // Only create renderers for SVG elements whose parents are SVG elements, or for proper <svg xmlns="svgNS"> subdocuments.
1773     if (child->isSVGElement())
1774         return child->hasTagName(SVGNames::svgTag) || isSVGElement();
1775
1776     return Node::childShouldCreateRenderer(child);
1777 }
1778 #endif
1779     
1780 #if ENABLE(FULLSCREEN_API)
1781 void Element::webkitRequestFullScreen(unsigned short flags)
1782 {
1783     document()->webkitRequestFullScreenForElement(this, flags);
1784 }
1785 #endif    
1786
1787 SpellcheckAttributeState Element::spellcheckAttributeState() const
1788 {
1789     if (!hasAttribute(HTMLNames::spellcheckAttr))
1790         return SpellcheckAttributeDefault;
1791
1792     const AtomicString& value = getAttribute(HTMLNames::spellcheckAttr);
1793     if (equalIgnoringCase(value, "true") || equalIgnoringCase(value, ""))
1794         return SpellcheckAttributeTrue;
1795     if (equalIgnoringCase(value, "false"))
1796         return SpellcheckAttributeFalse;
1797
1798     return SpellcheckAttributeDefault;
1799 }
1800
1801 bool Element::isSpellCheckingEnabled() const
1802 {
1803     const Element* element = this;
1804     while (element) {
1805         switch (element->spellcheckAttributeState()) {
1806         case SpellcheckAttributeTrue:
1807             return true;
1808         case SpellcheckAttributeFalse:
1809             return false;
1810         case SpellcheckAttributeDefault:
1811             break;
1812         }
1813
1814         ContainerNode* parent = const_cast<Element*>(element)->parentOrHostNode();
1815         element = (parent && parent->isElementNode()) ? toElement(parent) : 0;
1816     }
1817
1818     return true;
1819 }
1820
1821 } // namespace WebCore