Unreviewed, rolling out r134367.
[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, 2012 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 "ClassList.h"
34 #include "ClientRect.h"
35 #include "ClientRectList.h"
36 #include "DOMTokenList.h"
37 #include "DatasetDOMStringMap.h"
38 #include "Document.h"
39 #include "DocumentFragment.h"
40 #include "ElementRareData.h"
41 #include "ExceptionCode.h"
42 #include "FlowThreadController.h"
43 #include "FocusController.h"
44 #include "Frame.h"
45 #include "FrameView.h"
46 #include "HTMLCollection.h"
47 #include "HTMLDocument.h"
48 #include "HTMLElement.h"
49 #include "HTMLFormCollection.h"
50 #include "HTMLFrameOwnerElement.h"
51 #include "HTMLLabelElement.h"
52 #include "HTMLNames.h"
53 #include "HTMLOptionsCollection.h"
54 #include "HTMLParserIdioms.h"
55 #include "HTMLTableRowsCollection.h"
56 #include "InspectorInstrumentation.h"
57 #include "MutationObserverInterestGroup.h"
58 #include "MutationRecord.h"
59 #include "NamedNodeMap.h"
60 #include "NodeList.h"
61 #include "NodeRenderStyle.h"
62 #include "NodeRenderingContext.h"
63 #include "Page.h"
64 #include "PointerLockController.h"
65 #include "RenderRegion.h"
66 #include "RenderView.h"
67 #include "RenderWidget.h"
68 #include "SelectorQuery.h"
69 #include "Settings.h"
70 #include "ShadowRoot.h"
71 #include "StyleResolver.h"
72 #include "Text.h"
73 #include "TextIterator.h"
74 #include "VoidCallback.h"
75 #include "WebCoreMemoryInstrumentation.h"
76 #include "WebKitAnimationList.h"
77 #include "XMLNSNames.h"
78 #include "XMLNames.h"
79 #include "htmlediting.h"
80 #include <wtf/BitVector.h>
81 #include <wtf/text/CString.h>
82
83 #if ENABLE(SVG)
84 #include "SVGElement.h"
85 #include "SVGNames.h"
86 #endif
87
88 namespace WebCore {
89
90 using namespace HTMLNames;
91 using namespace XMLNames;
92     
93 class StyleResolverParentPusher {
94 public:
95     StyleResolverParentPusher(Element* parent)
96         : m_parent(parent)
97         , m_pushedStyleResolver(0)
98     {
99     }
100     void push()
101     {
102         if (m_pushedStyleResolver)
103             return;
104         m_pushedStyleResolver = m_parent->document()->styleResolver();
105         m_pushedStyleResolver->pushParentElement(m_parent);
106     }
107     ~StyleResolverParentPusher()
108     {
109
110         if (!m_pushedStyleResolver)
111             return;
112
113         // This tells us that our pushed style selector is in a bad state,
114         // so we should just bail out in that scenario.
115         ASSERT(m_pushedStyleResolver == m_parent->document()->styleResolver());
116         if (m_pushedStyleResolver != m_parent->document()->styleResolver())
117             return;
118
119         m_pushedStyleResolver->popParentElement(m_parent);
120     }
121
122 private:
123     Element* m_parent;
124     StyleResolver* m_pushedStyleResolver;
125 };
126
127 typedef Vector<RefPtr<Attr> > AttrNodeList;
128 typedef HashMap<Element*, OwnPtr<AttrNodeList> > AttrNodeListMap;
129
130 static AttrNodeListMap& attrNodeListMap()
131 {
132     DEFINE_STATIC_LOCAL(AttrNodeListMap, map, ());
133     return map;
134 }
135
136 static AttrNodeList* attrNodeListForElement(Element* element)
137 {
138     if (!element->hasSyntheticAttrChildNodes())
139         return 0;
140     ASSERT(attrNodeListMap().contains(element));
141     return attrNodeListMap().get(element);
142 }
143
144 static AttrNodeList* ensureAttrNodeListForElement(Element* element)
145 {
146     if (element->hasSyntheticAttrChildNodes()) {
147         ASSERT(attrNodeListMap().contains(element));
148         return attrNodeListMap().get(element);
149     }
150     ASSERT(!attrNodeListMap().contains(element));
151     element->setHasSyntheticAttrChildNodes(true);
152     AttrNodeListMap::AddResult result = attrNodeListMap().add(element, adoptPtr(new AttrNodeList));
153     return result.iterator->value.get();
154 }
155
156 static void removeAttrNodeListForElement(Element* element)
157 {
158     ASSERT(element->hasSyntheticAttrChildNodes());
159     ASSERT(attrNodeListMap().contains(element));
160     attrNodeListMap().remove(element);
161     element->setHasSyntheticAttrChildNodes(false);
162 }
163
164 static Attr* findAttrNodeInList(AttrNodeList* attrNodeList, const QualifiedName& name)
165 {
166     for (unsigned i = 0; i < attrNodeList->size(); ++i) {
167         if (attrNodeList->at(i)->qualifiedName() == name)
168             return attrNodeList->at(i).get();
169     }
170     return 0;
171 }
172
173 PassRefPtr<Element> Element::create(const QualifiedName& tagName, Document* document)
174 {
175     return adoptRef(new Element(tagName, document, CreateElement));
176 }
177
178 Element::~Element()
179 {
180 #ifndef NDEBUG
181     if (document() && document()->renderer()) {
182         // When the document is not destroyed, an element that was part of a named flow
183         // content nodes should have been removed from the content nodes collection
184         // and the inNamedFlow flag reset.
185         ASSERT(!inNamedFlow());
186     }
187 #endif
188
189     if (ElementShadow* elementShadow = shadow()) {
190         elementShadow->removeAllShadowRoots();
191         elementRareData()->m_shadow.clear();
192     }
193
194     if (hasSyntheticAttrChildNodes())
195         detachAllAttrNodesFromElement();
196 }
197
198 inline ElementRareData* Element::elementRareData() const
199 {
200     ASSERT(hasRareData());
201     return static_cast<ElementRareData*>(rareData());
202 }
203
204 inline ElementRareData* Element::ensureElementRareData()
205 {
206     return static_cast<ElementRareData*>(ensureRareData());
207 }
208     
209 OwnPtr<NodeRareData> Element::createRareData()
210 {
211     return adoptPtr(new ElementRareData);
212 }
213
214 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, blur);
215 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, error);
216 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, focus);
217 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, load);
218
219 PassRefPtr<Node> Element::cloneNode(bool deep)
220 {
221     return deep ? cloneElementWithChildren() : cloneElementWithoutChildren();
222 }
223
224 PassRefPtr<Element> Element::cloneElementWithChildren()
225 {
226     RefPtr<Element> clone = cloneElementWithoutChildren();
227     cloneChildNodes(clone.get());
228     return clone.release();
229 }
230
231 PassRefPtr<Element> Element::cloneElementWithoutChildren()
232 {
233     RefPtr<Element> clone = cloneElementWithoutAttributesAndChildren();
234     // This will catch HTML elements in the wrong namespace that are not correctly copied.
235     // This is a sanity check as HTML overloads some of the DOM methods.
236     ASSERT(isHTMLElement() == clone->isHTMLElement());
237
238     clone->cloneDataFromElement(*this);
239     return clone.release();
240 }
241
242 PassRefPtr<Element> Element::cloneElementWithoutAttributesAndChildren()
243 {
244     return document()->createElement(tagQName(), false);
245 }
246
247 PassRefPtr<Attr> Element::detachAttribute(size_t index)
248 {
249     ASSERT(attributeData());
250
251     const Attribute* attribute = attributeData()->attributeItem(index);
252     ASSERT(attribute);
253
254     RefPtr<Attr> attrNode = attrIfExists(attribute->name());
255     if (attrNode)
256         detachAttrNodeFromElementWithValue(attrNode.get(), attribute->value());
257     else
258         attrNode = Attr::create(document(), attribute->name(), attribute->value());
259
260     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
261     return attrNode.release();
262 }
263
264 void Element::removeAttribute(const QualifiedName& name)
265 {
266     if (!attributeData())
267         return;
268
269     size_t index = attributeData()->getAttributeItemIndex(name);
270     if (index == notFound)
271         return;
272
273     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
274 }
275
276 void Element::setBooleanAttribute(const QualifiedName& name, bool value)
277 {
278     if (value)
279         setAttribute(name, emptyAtom);
280     else
281         removeAttribute(name);
282 }
283
284 NamedNodeMap* Element::attributes() const
285 {
286     ensureUpdatedAttributeData();
287     ElementRareData* rareData = const_cast<Element*>(this)->ensureElementRareData();
288     if (NamedNodeMap* attributeMap = rareData->m_attributeMap.get())
289         return attributeMap;
290
291     rareData->m_attributeMap = NamedNodeMap::create(const_cast<Element*>(this));
292     return rareData->m_attributeMap.get();
293 }
294
295 Node::NodeType Element::nodeType() const
296 {
297     return ELEMENT_NODE;
298 }
299
300 bool Element::hasAttribute(const QualifiedName& name) const
301 {
302     return hasAttributeNS(name.namespaceURI(), name.localName());
303 }
304
305 const AtomicString& Element::getAttribute(const QualifiedName& name) const
306 {
307     if (UNLIKELY(name == styleAttr) && !isStyleAttributeValid())
308         updateStyleAttribute();
309
310 #if ENABLE(SVG)
311     if (UNLIKELY(!areSVGAttributesValid()))
312         updateAnimatedSVGAttribute(name);
313 #endif
314
315     if (attributeData()) {
316         if (const Attribute* attribute = getAttributeItem(name))
317             return attribute->value();
318     }
319     return nullAtom;
320 }
321
322 void Element::scrollIntoView(bool alignToTop) 
323 {
324     document()->updateLayoutIgnorePendingStylesheets();
325
326     if (!renderer())
327         return;
328
329     LayoutRect bounds = boundingBox();
330     // Align to the top / bottom and to the closest edge.
331     if (alignToTop)
332         renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
333     else
334         renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignBottomAlways);
335 }
336
337 void Element::scrollIntoViewIfNeeded(bool centerIfNeeded)
338 {
339     document()->updateLayoutIgnorePendingStylesheets();
340
341     if (!renderer())
342         return;
343
344     LayoutRect bounds = boundingBox();
345     if (centerIfNeeded)
346         renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignCenterIfNeeded, ScrollAlignment::alignCenterIfNeeded);
347     else
348         renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
349 }
350
351 void Element::scrollByUnits(int units, ScrollGranularity granularity)
352 {
353     document()->updateLayoutIgnorePendingStylesheets();
354
355     if (!renderer())
356         return;
357
358     if (!renderer()->hasOverflowClip())
359         return;
360
361     ScrollDirection direction = ScrollDown;
362     if (units < 0) {
363         direction = ScrollUp;
364         units = -units;
365     }
366     Node* stopNode = this;
367     toRenderBox(renderer())->scroll(direction, granularity, units, &stopNode);
368 }
369
370 void Element::scrollByLines(int lines)
371 {
372     scrollByUnits(lines, ScrollByLine);
373 }
374
375 void Element::scrollByPages(int pages)
376 {
377     scrollByUnits(pages, ScrollByPage);
378 }
379
380 static float localZoomForRenderer(RenderObject* renderer)
381 {
382     // FIXME: This does the wrong thing if two opposing zooms are in effect and canceled each
383     // other out, but the alternative is that we'd have to crawl up the whole render tree every
384     // time (or store an additional bit in the RenderStyle to indicate that a zoom was specified).
385     float zoomFactor = 1;
386     if (renderer->style()->effectiveZoom() != 1) {
387         // Need to find the nearest enclosing RenderObject that set up
388         // a differing zoom, and then we divide our result by it to eliminate the zoom.
389         RenderObject* prev = renderer;
390         for (RenderObject* curr = prev->parent(); curr; curr = curr->parent()) {
391             if (curr->style()->effectiveZoom() != prev->style()->effectiveZoom()) {
392                 zoomFactor = prev->style()->zoom();
393                 break;
394             }
395             prev = curr;
396         }
397         if (prev->isRenderView())
398             zoomFactor = prev->style()->zoom();
399     }
400     return zoomFactor;
401 }
402
403 static int adjustForLocalZoom(LayoutUnit value, RenderObject* renderer)
404 {
405     float zoomFactor = localZoomForRenderer(renderer);
406     if (zoomFactor == 1)
407         return value;
408 #if ENABLE(SUBPIXEL_LAYOUT)
409     return lroundf(value / zoomFactor);
410 #else
411     // Needed because computeLengthInt truncates (rather than rounds) when scaling up.
412     if (zoomFactor > 1)
413         value++;
414     return static_cast<int>(value / zoomFactor);
415 #endif
416 }
417
418 int Element::offsetLeft()
419 {
420     document()->updateLayoutIgnorePendingStylesheets();
421     if (RenderBoxModelObject* renderer = renderBoxModelObject())
422         return adjustForLocalZoom(renderer->pixelSnappedOffsetLeft(), renderer);
423     return 0;
424 }
425
426 int Element::offsetTop()
427 {
428     document()->updateLayoutIgnorePendingStylesheets();
429     if (RenderBoxModelObject* renderer = renderBoxModelObject())
430         return adjustForLocalZoom(renderer->pixelSnappedOffsetTop(), renderer);
431     return 0;
432 }
433
434 int Element::offsetWidth()
435 {
436     document()->updateLayoutIgnorePendingStylesheets();
437     if (RenderBoxModelObject* renderer = renderBoxModelObject())
438         return adjustForAbsoluteZoom(renderer->pixelSnappedOffsetWidth(), renderer);
439     return 0;
440 }
441
442 int Element::offsetHeight()
443 {
444     document()->updateLayoutIgnorePendingStylesheets();
445     if (RenderBoxModelObject* renderer = renderBoxModelObject())
446         return adjustForAbsoluteZoom(renderer->pixelSnappedOffsetHeight(), renderer);
447     return 0;
448 }
449
450 Element* Element::offsetParent()
451 {
452     document()->updateLayoutIgnorePendingStylesheets();
453     if (RenderObject* rend = renderer())
454         if (RenderObject* offsetParent = rend->offsetParent())
455             return static_cast<Element*>(offsetParent->node());
456     return 0;
457 }
458
459 int Element::clientLeft()
460 {
461     document()->updateLayoutIgnorePendingStylesheets();
462
463     if (RenderBox* renderer = renderBox())
464         return adjustForAbsoluteZoom(roundToInt(renderer->clientLeft()), renderer);
465     return 0;
466 }
467
468 int Element::clientTop()
469 {
470     document()->updateLayoutIgnorePendingStylesheets();
471
472     if (RenderBox* renderer = renderBox())
473         return adjustForAbsoluteZoom(roundToInt(renderer->clientTop()), renderer);
474     return 0;
475 }
476
477 int Element::clientWidth()
478 {
479     document()->updateLayoutIgnorePendingStylesheets();
480
481     // When in strict mode, clientWidth for the document element should return the width of the containing frame.
482     // When in quirks mode, clientWidth for the body element should return the width of the containing frame.
483     bool inQuirksMode = document()->inQuirksMode();
484     if ((!inQuirksMode && document()->documentElement() == this) ||
485         (inQuirksMode && isHTMLElement() && document()->body() == this)) {
486         if (FrameView* view = document()->view()) {
487             if (RenderView* renderView = document()->renderView())
488                 return adjustForAbsoluteZoom(view->layoutWidth(), renderView);
489         }
490     }
491     
492     if (RenderBox* renderer = renderBox())
493         return adjustForAbsoluteZoom(renderer->pixelSnappedClientWidth(), renderer);
494     return 0;
495 }
496
497 int Element::clientHeight()
498 {
499     document()->updateLayoutIgnorePendingStylesheets();
500
501     // When in strict mode, clientHeight for the document element should return the height of the containing frame.
502     // When in quirks mode, clientHeight for the body element should return the height of the containing frame.
503     bool inQuirksMode = document()->inQuirksMode();     
504
505     if ((!inQuirksMode && document()->documentElement() == this) ||
506         (inQuirksMode && isHTMLElement() && document()->body() == this)) {
507         if (FrameView* view = document()->view()) {
508             if (RenderView* renderView = document()->renderView())
509                 return adjustForAbsoluteZoom(view->layoutHeight(), renderView);
510         }
511     }
512     
513     if (RenderBox* renderer = renderBox())
514         return adjustForAbsoluteZoom(renderer->pixelSnappedClientHeight(), renderer);
515     return 0;
516 }
517
518 int Element::scrollLeft()
519 {
520     document()->updateLayoutIgnorePendingStylesheets();
521     if (RenderBox* rend = renderBox())
522         return adjustForAbsoluteZoom(rend->scrollLeft(), rend);
523     return 0;
524 }
525
526 int Element::scrollTop()
527 {
528     document()->updateLayoutIgnorePendingStylesheets();
529     if (RenderBox* rend = renderBox())
530         return adjustForAbsoluteZoom(rend->scrollTop(), rend);
531     return 0;
532 }
533
534 void Element::setScrollLeft(int newLeft)
535 {
536     document()->updateLayoutIgnorePendingStylesheets();
537     if (RenderBox* rend = renderBox())
538         rend->setScrollLeft(static_cast<int>(newLeft * rend->style()->effectiveZoom()));
539 }
540
541 void Element::setScrollTop(int newTop)
542 {
543     document()->updateLayoutIgnorePendingStylesheets();
544     if (RenderBox* rend = renderBox())
545         rend->setScrollTop(static_cast<int>(newTop * rend->style()->effectiveZoom()));
546 }
547
548 int Element::scrollWidth()
549 {
550     document()->updateLayoutIgnorePendingStylesheets();
551     if (RenderBox* rend = renderBox())
552         return adjustForAbsoluteZoom(rend->scrollWidth(), rend);
553     return 0;
554 }
555
556 int Element::scrollHeight()
557 {
558     document()->updateLayoutIgnorePendingStylesheets();
559     if (RenderBox* rend = renderBox())
560         return adjustForAbsoluteZoom(rend->scrollHeight(), rend);
561     return 0;
562 }
563
564 IntRect Element::boundsInRootViewSpace()
565 {
566     document()->updateLayoutIgnorePendingStylesheets();
567
568     FrameView* view = document()->view();
569     if (!view)
570         return IntRect();
571
572     Vector<FloatQuad> quads;
573 #if ENABLE(SVG)
574     if (isSVGElement() && renderer()) {
575         // Get the bounding rectangle from the SVG model.
576         SVGElement* svgElement = static_cast<SVGElement*>(this);
577         FloatRect localRect;
578         if (svgElement->getBoundingBox(localRect))
579             quads.append(renderer()->localToAbsoluteQuad(localRect));
580     } else
581 #endif
582     {
583         // Get the bounding rectangle from the box model.
584         if (renderBoxModelObject())
585             renderBoxModelObject()->absoluteQuads(quads);
586     }
587
588     if (quads.isEmpty())
589         return IntRect();
590
591     IntRect result = quads[0].enclosingBoundingBox();
592     for (size_t i = 1; i < quads.size(); ++i)
593         result.unite(quads[i].enclosingBoundingBox());
594
595     result = view->contentsToRootView(result);
596     return result;
597 }
598
599 PassRefPtr<ClientRectList> Element::getClientRects()
600 {
601     document()->updateLayoutIgnorePendingStylesheets();
602
603     RenderBoxModelObject* renderBoxModelObject = this->renderBoxModelObject();
604     if (!renderBoxModelObject)
605         return ClientRectList::create();
606
607     // FIXME: Handle SVG elements.
608     // FIXME: Handle table/inline-table with a caption.
609
610     Vector<FloatQuad> quads;
611     renderBoxModelObject->absoluteQuads(quads);
612     document()->adjustFloatQuadsForScrollAndAbsoluteZoomAndFrameScale(quads, renderBoxModelObject);
613     return ClientRectList::create(quads);
614 }
615
616 PassRefPtr<ClientRect> Element::getBoundingClientRect()
617 {
618     document()->updateLayoutIgnorePendingStylesheets();
619
620     Vector<FloatQuad> quads;
621 #if ENABLE(SVG)
622     if (isSVGElement() && renderer() && !renderer()->isSVGRoot()) {
623         // Get the bounding rectangle from the SVG model.
624         SVGElement* svgElement = static_cast<SVGElement*>(this);
625         FloatRect localRect;
626         if (svgElement->getBoundingBox(localRect))
627             quads.append(renderer()->localToAbsoluteQuad(localRect));
628     } else
629 #endif
630     {
631         // Get the bounding rectangle from the box model.
632         if (renderBoxModelObject())
633             renderBoxModelObject()->absoluteQuads(quads);
634     }
635
636     if (quads.isEmpty())
637         return ClientRect::create();
638
639     FloatRect result = quads[0].boundingBox();
640     for (size_t i = 1; i < quads.size(); ++i)
641         result.unite(quads[i].boundingBox());
642
643     document()->adjustFloatRectForScrollAndAbsoluteZoomAndFrameScale(result, renderer());
644     return ClientRect::create(result);
645 }
646     
647 IntRect Element::screenRect() const
648 {
649     if (!renderer())
650         return IntRect();
651     // FIXME: this should probably respect transforms
652     return document()->view()->contentsToScreen(renderer()->absoluteBoundingBoxRectIgnoringTransforms());
653 }
654
655 static inline bool shouldIgnoreAttributeCase(const Element* e)
656 {
657     return e && e->document()->isHTMLDocument() && e->isHTMLElement();
658 }
659
660 const AtomicString& Element::getAttribute(const AtomicString& name) const
661 {
662     bool ignoreCase = shouldIgnoreAttributeCase(this);
663
664     // Update the 'style' attribute if it's invalid and being requested:
665     if (!isStyleAttributeValid() && equalPossiblyIgnoringCase(name, styleAttr.localName(), ignoreCase))
666         updateStyleAttribute();
667
668 #if ENABLE(SVG)
669     if (!areSVGAttributesValid()) {
670         // We're not passing a namespace argument on purpose. SVGNames::*Attr are defined w/o namespaces as well.
671         updateAnimatedSVGAttribute(QualifiedName(nullAtom, name, nullAtom));
672     }
673 #endif
674
675     if (attributeData()) {
676         if (const Attribute* attribute = attributeData()->getAttributeItem(name, ignoreCase))
677             return attribute->value();
678     }
679
680     return nullAtom;
681 }
682
683 const AtomicString& Element::getAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const
684 {
685     return getAttribute(QualifiedName(nullAtom, localName, namespaceURI));
686 }
687
688 void Element::setAttribute(const AtomicString& name, const AtomicString& value, ExceptionCode& ec)
689 {
690     if (!Document::isValidName(name)) {
691         ec = INVALID_CHARACTER_ERR;
692         return;
693     }
694
695     const AtomicString& localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
696
697     size_t index = ensureUpdatedAttributeData()->getAttributeItemIndex(localName, false);
698     const QualifiedName& qName = index != notFound ? attributeItem(index)->name() : QualifiedName(nullAtom, localName, nullAtom);
699     setAttributeInternal(index, qName, value, NotInSynchronizationOfLazyAttribute);
700 }
701
702 void Element::setAttribute(const QualifiedName& name, const AtomicString& value)
703 {
704     setAttributeInternal(ensureUpdatedAttributeData()->getAttributeItemIndex(name), name, value, NotInSynchronizationOfLazyAttribute);
705 }
706
707 void Element::setSynchronizedLazyAttribute(const QualifiedName& name, const AtomicString& value)
708 {
709     setAttributeInternal(mutableAttributeData()->getAttributeItemIndex(name), name, value, InSynchronizationOfLazyAttribute);
710 }
711
712 inline void Element::setAttributeInternal(size_t index, const QualifiedName& name, const AtomicString& newValue, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
713 {
714     if (newValue.isNull()) {
715         if (index != notFound)
716             removeAttributeInternal(index, inSynchronizationOfLazyAttribute);
717         return;
718     }
719
720     if (index == notFound) {
721         addAttributeInternal(name, newValue, inSynchronizationOfLazyAttribute);
722         return;
723     }
724
725     if (!inSynchronizationOfLazyAttribute)
726         willModifyAttribute(name, attributeItem(index)->value(), newValue);
727
728     if (newValue != attributeItem(index)->value()) {
729         // If there is an Attr node hooked to this attribute, the Attr::setValue() call below
730         // will write into the ElementAttributeData.
731         // FIXME: Refactor this so it makes some sense.
732         if (RefPtr<Attr> attrNode = attrIfExists(name))
733             attrNode->setValue(newValue);
734         else
735             mutableAttributeData()->attributeItem(index)->setValue(newValue);
736     }
737
738     if (!inSynchronizationOfLazyAttribute)
739         didModifyAttribute(name, newValue);
740 }
741
742 static inline AtomicString makeIdForStyleResolution(const AtomicString& value, bool inQuirksMode)
743 {
744     if (inQuirksMode)
745         return value.lower();
746     return value;
747 }
748
749 static bool checkNeedsStyleInvalidationForIdChange(const AtomicString& oldId, const AtomicString& newId, StyleResolver* styleResolver)
750 {
751     ASSERT(newId != oldId);
752     if (!oldId.isEmpty() && styleResolver->hasSelectorForId(oldId))
753         return true;
754     if (!newId.isEmpty() && styleResolver->hasSelectorForId(newId))
755         return true;
756     return false;
757 }
758
759 void Element::attributeChanged(const QualifiedName& name, const AtomicString& newValue)
760 {
761     parseAttribute(Attribute(name, newValue));
762
763     document()->incDOMTreeVersion();
764
765     StyleResolver* styleResolver = document()->styleResolverIfExists();
766     bool testShouldInvalidateStyle = attached() && styleResolver && styleChangeType() < FullStyleChange;
767     bool shouldInvalidateStyle = false;
768
769     if (isIdAttributeName(name)) {
770         AtomicString oldId = attributeData()->idForStyleResolution();
771         AtomicString newId = makeIdForStyleResolution(newValue, document()->inQuirksMode());
772         if (newId != oldId) {
773             attributeData()->setIdForStyleResolution(newId);
774             shouldInvalidateStyle = testShouldInvalidateStyle && checkNeedsStyleInvalidationForIdChange(oldId, newId, styleResolver);
775         }
776     } else if (name == HTMLNames::nameAttr)
777         setHasName(!newValue.isNull());
778     else if (name == HTMLNames::pseudoAttr)
779         shouldInvalidateStyle |= testShouldInvalidateStyle && isInShadowTree();
780
781     shouldInvalidateStyle |= testShouldInvalidateStyle && styleResolver->hasSelectorForAttribute(name.localName());
782
783     invalidateNodeListCachesInAncestors(&name, this);
784
785     if (shouldInvalidateStyle)
786         setNeedsStyleRecalc();
787
788     if (AXObjectCache::accessibilityEnabled())
789         document()->axObjectCache()->handleAttributeChanged(name, this);
790 }
791
792 void Element::parseAttribute(const Attribute& attribute)
793 {
794     if (attribute.name() == classAttr)
795         classAttributeChanged(attribute.value());
796 }
797
798 template <typename CharacterType>
799 static inline bool classStringHasClassName(const CharacterType* characters, unsigned length)
800 {
801     ASSERT(length > 0);
802
803     unsigned i = 0;
804     do {
805         if (isNotHTMLSpace(characters[i]))
806             break;
807         ++i;
808     } while (i < length);
809
810     return i < length;
811 }
812
813 static inline bool classStringHasClassName(const AtomicString& newClassString)
814 {
815     unsigned length = newClassString.length();
816
817     if (!length)
818         return false;
819
820     if (newClassString.is8Bit())
821         return classStringHasClassName(newClassString.characters8(), length);
822     return classStringHasClassName(newClassString.characters16(), length);
823 }
824
825 static bool checkNeedsStyleInvalidationForClassChange(const SpaceSplitString& changedClasses, StyleResolver* styleResolver)
826 {
827     unsigned changedSize = changedClasses.size();
828     for (unsigned i = 0; i < changedSize; ++i) {
829         if (styleResolver->hasSelectorForClass(changedClasses[i]))
830             return true;
831     }
832     return false;
833 }
834
835 static bool checkNeedsStyleInvalidationForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses, StyleResolver* styleResolver)
836 {
837     unsigned oldSize = oldClasses.size();
838     if (!oldSize)
839         return checkNeedsStyleInvalidationForClassChange(newClasses, styleResolver);
840     BitVector remainingClassBits;
841     remainingClassBits.ensureSize(oldSize);
842     // Class vectors tend to be very short. This is faster than using a hash table.
843     unsigned newSize = newClasses.size();
844     for (unsigned i = 0; i < newSize; ++i) {
845         for (unsigned j = 0; j < oldSize; ++j) {
846             if (newClasses[i] == oldClasses[j]) {
847                 remainingClassBits.quickSet(j);
848                 continue;
849             }
850         }
851         if (styleResolver->hasSelectorForClass(newClasses[i]))
852             return true;
853     }
854     for (unsigned i = 0; i < oldSize; ++i) {
855         // If the bit is not set the the corresponding class has been removed.
856         if (remainingClassBits.quickGet(i))
857             continue;
858         if (styleResolver->hasSelectorForClass(oldClasses[i]))
859             return true;
860     }
861     return false;
862 }
863
864 void Element::classAttributeChanged(const AtomicString& newClassString)
865 {
866     StyleResolver* styleResolver = document()->styleResolverIfExists();
867     bool testShouldInvalidateStyle = attached() && styleResolver && styleChangeType() < FullStyleChange;
868     bool shouldInvalidateStyle = false;
869
870     if (classStringHasClassName(newClassString)) {
871         const ElementAttributeData* attributeData = ensureAttributeData();
872         const bool shouldFoldCase = document()->inQuirksMode();
873         const SpaceSplitString oldClasses = attributeData->classNames();
874
875         attributeData->setClass(newClassString, shouldFoldCase);
876
877         const SpaceSplitString& newClasses = attributeData->classNames();
878         shouldInvalidateStyle = testShouldInvalidateStyle && checkNeedsStyleInvalidationForClassChange(oldClasses, newClasses, styleResolver);
879     } else if (const ElementAttributeData* attributeData = this->attributeData()) {
880         const SpaceSplitString& oldClasses = attributeData->classNames();
881         shouldInvalidateStyle = testShouldInvalidateStyle && checkNeedsStyleInvalidationForClassChange(oldClasses, styleResolver);
882
883         attributeData->clearClass();
884     }
885
886     if (DOMTokenList* classList = optionalClassList())
887         static_cast<ClassList*>(classList)->reset(newClassString);
888
889     if (shouldInvalidateStyle)
890         setNeedsStyleRecalc();
891 }
892
893 // Returns true is the given attribute is an event handler.
894 // We consider an event handler any attribute that begins with "on".
895 // It is a simple solution that has the advantage of not requiring any
896 // code or configuration change if a new event handler is defined.
897
898 static bool isEventHandlerAttribute(const QualifiedName& name)
899 {
900     return name.namespaceURI().isNull() && name.localName().startsWith("on");
901 }
902
903 // FIXME: Share code with Element::isURLAttribute.
904 static bool isAttributeToRemove(const QualifiedName& name, const AtomicString& value)
905 {
906     return (name.localName() == hrefAttr.localName() || name.localName() == nohrefAttr.localName()
907         || name == srcAttr || name == actionAttr || name == formactionAttr) && protocolIsJavaScript(stripLeadingAndTrailingHTMLSpaces(value));
908 }
909
910 void Element::parserSetAttributes(const Vector<Attribute>& attributeVector, FragmentScriptingPermission scriptingPermission)
911 {
912     ASSERT(!inDocument());
913     ASSERT(!parentNode());
914
915     ASSERT(!m_attributeData);
916
917     if (attributeVector.isEmpty())
918         return;
919
920     Vector<Attribute> filteredAttributes = attributeVector;
921
922     // If the element is created as result of a paste or drag-n-drop operation
923     // we want to remove all the script and event handlers.
924     if (scriptingPermission == DisallowScriptingContent) {
925         unsigned i = 0;
926         while (i < filteredAttributes.size()) {
927             Attribute& attribute = filteredAttributes[i];
928             if (isEventHandlerAttribute(attribute.name())) {
929                 filteredAttributes.remove(i);
930                 continue;
931             }
932
933             if (isAttributeToRemove(attribute.name(), attribute.value()))
934                 attribute.setValue(emptyAtom);
935             i++;
936         }
937     }
938
939     // When the document is in parsing state, we cache immutable ElementAttributeData objects with the
940     // input attribute vector (and the tag name) as key. (This cache is held by Document.)
941     if (!document() || !document()->parsing())
942         m_attributeData = ElementAttributeData::createImmutable(filteredAttributes);
943     else
944         m_attributeData = document()->cachedImmutableAttributeData(this, filteredAttributes);
945
946     // Iterate over the set of attributes we already have on the stack in case
947     // attributeChanged mutates m_attributeData.
948     // FIXME: Find a way so we don't have to do this.
949     for (unsigned i = 0; i < filteredAttributes.size(); ++i)
950         attributeChanged(filteredAttributes[i].name(), filteredAttributes[i].value());
951 }
952
953 bool Element::hasAttributes() const
954 {
955     updateInvalidAttributes();
956     return attributeData() && attributeData()->length();
957 }
958
959 bool Element::hasEquivalentAttributes(const Element* other) const
960 {
961     const ElementAttributeData* attributeData = updatedAttributeData();
962     const ElementAttributeData* otherAttributeData = other->updatedAttributeData();
963     if (attributeData)
964         return attributeData->isEquivalent(otherAttributeData);
965     if (otherAttributeData)
966         return otherAttributeData->isEquivalent(attributeData);
967     return true;
968 }
969
970 String Element::nodeName() const
971 {
972     return m_tagName.toString();
973 }
974
975 String Element::nodeNamePreservingCase() const
976 {
977     return m_tagName.toString();
978 }
979
980 void Element::setPrefix(const AtomicString& prefix, ExceptionCode& ec)
981 {
982     ec = 0;
983     checkSetPrefix(prefix, ec);
984     if (ec)
985         return;
986
987     m_tagName.setPrefix(prefix.isEmpty() ? AtomicString() : prefix);
988 }
989
990 KURL Element::baseURI() const
991 {
992     const AtomicString& baseAttribute = getAttribute(baseAttr);
993     KURL base(KURL(), baseAttribute);
994     if (!base.protocol().isEmpty())
995         return base;
996
997     ContainerNode* parent = parentNode();
998     if (!parent)
999         return base;
1000
1001     const KURL& parentBase = parent->baseURI();
1002     if (parentBase.isNull())
1003         return base;
1004
1005     return KURL(parentBase, baseAttribute);
1006 }
1007
1008 const QualifiedName& Element::imageSourceAttributeName() const
1009 {
1010     return srcAttr;
1011 }
1012
1013 RenderObject* Element::createRenderer(RenderArena* arena, RenderStyle* style)
1014 {
1015     if (document()->documentElement() == this && style->display() == NONE) {
1016         // Ignore display: none on root elements.  Force a display of block in that case.
1017         RenderBlock* result = new (arena) RenderBlock(this);
1018         if (result)
1019             result->setAnimatableStyle(style);
1020         return result;
1021     }
1022     return RenderObject::createObject(this, style);
1023 }
1024
1025 bool Element::wasChangedSinceLastFormControlChangeEvent() const
1026 {
1027     return false;
1028 }
1029
1030 void Element::setChangedSinceLastFormControlChangeEvent(bool)
1031 {
1032 }
1033
1034 Node::InsertionNotificationRequest Element::insertedInto(ContainerNode* insertionPoint)
1035 {
1036     // need to do superclass processing first so inDocument() is true
1037     // by the time we reach updateId
1038     ContainerNode::insertedInto(insertionPoint);
1039
1040 #if ENABLE(FULLSCREEN_API)
1041     if (containsFullScreenElement() && parentElement() && !parentElement()->containsFullScreenElement())
1042         setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(true);
1043 #endif
1044
1045     if (!insertionPoint->inDocument())
1046         return InsertionDone;
1047
1048     const AtomicString& idValue = getIdAttribute();
1049     if (!idValue.isNull())
1050         updateId(nullAtom, idValue);
1051
1052     const AtomicString& nameValue = getNameAttribute();
1053     if (!nameValue.isNull())
1054         updateName(nullAtom, nameValue);
1055
1056     if (hasTagName(labelTag)) {
1057         TreeScope* scope = treeScope();
1058         if (scope->shouldCacheLabelsByForAttribute())
1059             updateLabel(scope, nullAtom, fastGetAttribute(forAttr));
1060     }
1061
1062     return InsertionDone;
1063 }
1064
1065 void Element::removedFrom(ContainerNode* insertionPoint)
1066 {
1067 #if ENABLE(FULLSCREEN_API)
1068     if (containsFullScreenElement())
1069         setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false);
1070 #endif
1071 #if ENABLE(POINTER_LOCK)
1072     if (document()->page())
1073         document()->page()->pointerLockController()->elementRemoved(this);
1074 #endif
1075
1076     setSavedLayerScrollOffset(IntSize());
1077
1078     if (insertionPoint->inDocument()) {
1079         const AtomicString& idValue = getIdAttribute();
1080         if (!idValue.isNull() && inDocument())
1081             updateId(insertionPoint->treeScope(), idValue, nullAtom);
1082
1083         const AtomicString& nameValue = getNameAttribute();
1084         if (!nameValue.isNull())
1085             updateName(nameValue, nullAtom);
1086
1087         if (hasTagName(labelTag)) {
1088             TreeScope* treeScope = insertionPoint->treeScope();
1089             if (treeScope->shouldCacheLabelsByForAttribute())
1090                 updateLabel(treeScope, fastGetAttribute(forAttr), nullAtom);
1091         }
1092     }
1093
1094     ContainerNode::removedFrom(insertionPoint);
1095 }
1096
1097 void Element::attach()
1098 {
1099     suspendPostAttachCallbacks();
1100     WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
1101
1102     createRendererIfNeeded();
1103     StyleResolverParentPusher parentPusher(this);
1104
1105     if (parentElement() && parentElement()->isInCanvasSubtree())
1106         setIsInCanvasSubtree(true);
1107
1108     // When a shadow root exists, it does the work of attaching the children.
1109     if (ElementShadow* shadow = this->shadow()) {
1110         parentPusher.push();
1111         shadow->attach();
1112     } else {
1113         if (firstChild())
1114             parentPusher.push();
1115     }
1116     ContainerNode::attach();
1117
1118     if (hasRareData()) {   
1119         ElementRareData* data = elementRareData();
1120         if (data->needsFocusAppearanceUpdateSoonAfterAttach()) {
1121             if (isFocusable() && document()->focusedNode() == this)
1122                 document()->updateFocusAppearanceSoon(false /* don't restore selection */);
1123             data->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
1124         }
1125     }
1126
1127     resumePostAttachCallbacks();
1128 }
1129
1130 void Element::unregisterNamedFlowContentNode()
1131 {
1132     if (document()->cssRegionsEnabled() && inNamedFlow() && document()->renderView())
1133         document()->renderView()->flowThreadController()->unregisterNamedFlowContentNode(this);
1134 }
1135
1136 void Element::detach()
1137 {
1138     WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
1139     unregisterNamedFlowContentNode();
1140     cancelFocusAppearanceUpdate();
1141     if (hasRareData()) {
1142         ElementRareData* data = elementRareData();
1143         data->setIsInCanvasSubtree(false);
1144         data->resetComputedStyle();
1145     }
1146
1147     if (ElementShadow* shadow = this->shadow()) {
1148         detachChildrenIfNeeded();
1149         shadow->detach();
1150     }
1151     ContainerNode::detach();
1152 }
1153
1154 bool Element::pseudoStyleCacheIsInvalid(const RenderStyle* currentStyle, RenderStyle* newStyle)
1155 {
1156     ASSERT(currentStyle == renderStyle());
1157     ASSERT(renderer());
1158
1159     if (!currentStyle)
1160         return false;
1161
1162     const PseudoStyleCache* pseudoStyleCache = currentStyle->cachedPseudoStyles();
1163     if (!pseudoStyleCache)
1164         return false;
1165
1166     size_t cacheSize = pseudoStyleCache->size();
1167     for (size_t i = 0; i < cacheSize; ++i) {
1168         RefPtr<RenderStyle> newPseudoStyle;
1169         PseudoId pseudoId = pseudoStyleCache->at(i)->styleType();
1170         if (pseudoId == FIRST_LINE || pseudoId == FIRST_LINE_INHERITED)
1171             newPseudoStyle = renderer()->uncachedFirstLineStyle(newStyle);
1172         else
1173             newPseudoStyle = renderer()->getUncachedPseudoStyle(pseudoId, newStyle, newStyle);
1174         if (!newPseudoStyle)
1175             return true;
1176         if (*newPseudoStyle != *pseudoStyleCache->at(i)) {
1177             if (pseudoId < FIRST_INTERNAL_PSEUDOID)
1178                 newStyle->setHasPseudoStyle(pseudoId);
1179             newStyle->addCachedPseudoStyle(newPseudoStyle);
1180             if (pseudoId == FIRST_LINE || pseudoId == FIRST_LINE_INHERITED) {
1181                 // FIXME: We should do an actual diff to determine whether a repaint vs. layout
1182                 // is needed, but for now just assume a layout will be required.  The diff code
1183                 // in RenderObject::setStyle would need to be factored out so that it could be reused.
1184                 renderer()->setNeedsLayoutAndPrefWidthsRecalc();
1185             }
1186             return true;
1187         }
1188     }
1189     return false;
1190 }
1191
1192 PassRefPtr<RenderStyle> Element::styleForRenderer()
1193 {
1194     if (hasCustomCallbacks()) {
1195         if (RefPtr<RenderStyle> style = customStyleForRenderer())
1196             return style.release();
1197     }
1198
1199     return document()->styleResolver()->styleForElement(this);
1200 }
1201
1202 void Element::recalcStyle(StyleChange change)
1203 {
1204     if (hasCustomCallbacks()) {
1205         if (!willRecalcStyle(change))
1206             return;
1207     }
1208
1209     // Ref currentStyle in case it would otherwise be deleted when setting the new style in the renderer.
1210     RefPtr<RenderStyle> currentStyle(renderStyle());
1211     bool hasParentStyle = parentNodeForRenderingAndStyle() ? static_cast<bool>(parentNodeForRenderingAndStyle()->renderStyle()) : false;
1212     bool hasDirectAdjacentRules = currentStyle && currentStyle->childrenAffectedByDirectAdjacentRules();
1213     bool hasIndirectAdjacentRules = currentStyle && currentStyle->childrenAffectedByForwardPositionalRules();
1214
1215     if ((change > NoChange || needsStyleRecalc())) {
1216         if (hasRareData()) {
1217             ElementRareData* data = elementRareData();
1218             data->resetComputedStyle();
1219             data->setStyleAffectedByEmpty(false);
1220         }
1221     }
1222     if (hasParentStyle && (change >= Inherit || needsStyleRecalc())) {
1223         RefPtr<RenderStyle> newStyle = styleForRenderer();
1224         StyleChange ch = Node::diff(currentStyle.get(), newStyle.get(), document());
1225         if (ch == Detach || !currentStyle) {
1226             // FIXME: The style gets computed twice by calling attach. We could do better if we passed the style along.
1227             reattach();
1228             // attach recalculates the style for all children. No need to do it twice.
1229             clearNeedsStyleRecalc();
1230             clearChildNeedsStyleRecalc();
1231
1232             if (hasCustomCallbacks())
1233                 didRecalcStyle(change);
1234             return;
1235         }
1236
1237         if (currentStyle) {
1238             // Preserve "affected by" bits that were propagated to us from descendants in the case where we didn't do a full
1239             // style change (e.g., only inline style changed).
1240             if (currentStyle->affectedByHoverRules())
1241                 newStyle->setAffectedByHoverRules(true);
1242             if (currentStyle->affectedByActiveRules())
1243                 newStyle->setAffectedByActiveRules(true);
1244             if (currentStyle->affectedByDragRules())
1245                 newStyle->setAffectedByDragRules(true);
1246             if (currentStyle->childrenAffectedByForwardPositionalRules())
1247                 newStyle->setChildrenAffectedByForwardPositionalRules();
1248             if (currentStyle->childrenAffectedByBackwardPositionalRules())
1249                 newStyle->setChildrenAffectedByBackwardPositionalRules();
1250             if (currentStyle->childrenAffectedByFirstChildRules())
1251                 newStyle->setChildrenAffectedByFirstChildRules();
1252             if (currentStyle->childrenAffectedByLastChildRules())
1253                 newStyle->setChildrenAffectedByLastChildRules();
1254             if (currentStyle->childrenAffectedByDirectAdjacentRules())
1255                 newStyle->setChildrenAffectedByDirectAdjacentRules();
1256         }
1257
1258         if (RenderObject* renderer = this->renderer()) {
1259             if (ch != NoChange || pseudoStyleCacheIsInvalid(currentStyle.get(), newStyle.get()) || (change == Force && renderer->requiresForcedStyleRecalcPropagation()) || styleChangeType() == SyntheticStyleChange)
1260                 renderer->setAnimatableStyle(newStyle.get());
1261             else if (needsStyleRecalc()) {
1262                 // Although no change occurred, we use the new style so that the cousin style sharing code won't get
1263                 // fooled into believing this style is the same.
1264                 renderer->setStyleInternal(newStyle.get());
1265             }
1266         }
1267
1268         // 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
1269         // 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).
1270         if (document()->styleSheetCollection()->usesRemUnits() && document()->documentElement() == this && ch != NoChange && currentStyle && newStyle && currentStyle->fontSize() != newStyle->fontSize()) {
1271             // Cached RenderStyles may depend on the rem units.
1272             document()->styleResolver()->invalidateMatchedPropertiesCache();
1273             change = Force;
1274         }
1275
1276         if (change != Force) {
1277             if (styleChangeType() >= FullStyleChange)
1278                 change = Force;
1279             else
1280                 change = ch;
1281         }
1282     }
1283     StyleResolverParentPusher parentPusher(this);
1284
1285     // FIXME: This does not care about sibling combinators. Will be necessary in XBL2 world.
1286     if (ElementShadow* shadow = this->shadow()) {
1287         if (change >= Inherit || shadow->childNeedsStyleRecalc() || shadow->needsStyleRecalc()) {
1288             parentPusher.push();
1289             shadow->recalcStyle(change);
1290         }
1291     }
1292
1293     // FIXME: This check is good enough for :hover + foo, but it is not good enough for :hover + foo + bar.
1294     // For now we will just worry about the common case, since it's a lot trickier to get the second case right
1295     // without doing way too much re-resolution.
1296     bool forceCheckOfNextElementSibling = false;
1297     bool forceCheckOfAnyElementSibling = false;
1298     for (Node *n = firstChild(); n; n = n->nextSibling()) {
1299         if (n->isTextNode()) {
1300             toText(n)->recalcTextStyle(change);
1301             continue;
1302         } 
1303         if (!n->isElementNode()) 
1304             continue;
1305         Element* element = static_cast<Element*>(n);
1306         bool childRulesChanged = element->needsStyleRecalc() && element->styleChangeType() == FullStyleChange;
1307         if ((forceCheckOfNextElementSibling || forceCheckOfAnyElementSibling))
1308             element->setNeedsStyleRecalc();
1309         if (change >= Inherit || element->childNeedsStyleRecalc() || element->needsStyleRecalc()) {
1310             parentPusher.push();
1311             element->recalcStyle(change);
1312         }
1313         forceCheckOfNextElementSibling = childRulesChanged && hasDirectAdjacentRules;
1314         forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childRulesChanged && hasIndirectAdjacentRules);
1315     }
1316
1317     clearNeedsStyleRecalc();
1318     clearChildNeedsStyleRecalc();
1319     
1320     if (hasCustomCallbacks())
1321         didRecalcStyle(change);
1322 }
1323
1324 ElementShadow* Element::shadow() const
1325 {
1326     if (!hasRareData())
1327         return 0;
1328
1329     return elementRareData()->m_shadow.get();
1330 }
1331
1332 ElementShadow* Element::ensureShadow()
1333 {
1334     if (ElementShadow* shadow = ensureElementRareData()->m_shadow.get())
1335         return shadow;
1336
1337     ElementRareData* data = elementRareData();
1338     data->m_shadow = adoptPtr(new ElementShadow());
1339     return data->m_shadow.get();
1340 }
1341
1342 ShadowRoot* Element::userAgentShadowRoot() const
1343 {
1344     if (ElementShadow* elementShadow = shadow()) {
1345         if (ShadowRoot* shadowRoot = elementShadow->oldestShadowRoot()) {
1346             ASSERT(shadowRoot->type() == ShadowRoot::UserAgentShadowRoot);
1347             return shadowRoot;
1348         }
1349     }
1350
1351     return 0;
1352 }
1353
1354 const AtomicString& Element::shadowPseudoId() const
1355 {
1356     return pseudo();
1357 }
1358
1359 bool Element::childTypeAllowed(NodeType type) const
1360 {
1361     switch (type) {
1362     case ELEMENT_NODE:
1363     case TEXT_NODE:
1364     case COMMENT_NODE:
1365     case PROCESSING_INSTRUCTION_NODE:
1366     case CDATA_SECTION_NODE:
1367     case ENTITY_REFERENCE_NODE:
1368         return true;
1369     default:
1370         break;
1371     }
1372     return false;
1373 }
1374
1375 static void checkForEmptyStyleChange(Element* element, RenderStyle* style)
1376 {
1377     if (!style && !element->styleAffectedByEmpty())
1378         return;
1379
1380     if (!style || (style->affectedByEmpty() && (!style->emptyState() || element->hasChildNodes())))
1381         element->setNeedsStyleRecalc();
1382 }
1383
1384 static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool finishedParsingCallback,
1385                                         Node* beforeChange, Node* afterChange, int childCountDelta)
1386 {
1387     // :empty selector.
1388     checkForEmptyStyleChange(e, style);
1389     
1390     if (!style || (e->needsStyleRecalc() && style->childrenAffectedByPositionalRules()))
1391         return;
1392
1393     // :first-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
1394     // In the DOM case, we only need to do something if |afterChange| is not 0.
1395     // |afterChange| is 0 in the parser case, so it works out that we'll skip this block.
1396     if (style->childrenAffectedByFirstChildRules() && afterChange) {
1397         // Find our new first child.
1398         Node* newFirstChild = 0;
1399         for (newFirstChild = e->firstChild(); newFirstChild && !newFirstChild->isElementNode(); newFirstChild = newFirstChild->nextSibling()) {};
1400         
1401         // Find the first element node following |afterChange|
1402         Node* firstElementAfterInsertion = 0;
1403         for (firstElementAfterInsertion = afterChange;
1404              firstElementAfterInsertion && !firstElementAfterInsertion->isElementNode();
1405              firstElementAfterInsertion = firstElementAfterInsertion->nextSibling()) {};
1406         
1407         // This is the insert/append case.
1408         if (newFirstChild != firstElementAfterInsertion && firstElementAfterInsertion && firstElementAfterInsertion->attached() &&
1409             firstElementAfterInsertion->renderStyle() && firstElementAfterInsertion->renderStyle()->firstChildState())
1410             firstElementAfterInsertion->setNeedsStyleRecalc();
1411             
1412         // We also have to handle node removal.
1413         if (childCountDelta < 0 && newFirstChild == firstElementAfterInsertion && newFirstChild && (!newFirstChild->renderStyle() || !newFirstChild->renderStyle()->firstChildState()))
1414             newFirstChild->setNeedsStyleRecalc();
1415     }
1416
1417     // :last-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
1418     // In the DOM case, we only need to do something if |afterChange| is not 0.
1419     if (style->childrenAffectedByLastChildRules() && beforeChange) {
1420         // Find our new last child.
1421         Node* newLastChild = 0;
1422         for (newLastChild = e->lastChild(); newLastChild && !newLastChild->isElementNode(); newLastChild = newLastChild->previousSibling()) {};
1423         
1424         // Find the last element node going backwards from |beforeChange|
1425         Node* lastElementBeforeInsertion = 0;
1426         for (lastElementBeforeInsertion = beforeChange;
1427              lastElementBeforeInsertion && !lastElementBeforeInsertion->isElementNode();
1428              lastElementBeforeInsertion = lastElementBeforeInsertion->previousSibling()) {};
1429         
1430         if (newLastChild != lastElementBeforeInsertion && lastElementBeforeInsertion && lastElementBeforeInsertion->attached() &&
1431             lastElementBeforeInsertion->renderStyle() && lastElementBeforeInsertion->renderStyle()->lastChildState())
1432             lastElementBeforeInsertion->setNeedsStyleRecalc();
1433             
1434         // 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
1435         // to match now.
1436         if ((childCountDelta < 0 || finishedParsingCallback) && newLastChild == lastElementBeforeInsertion && newLastChild && (!newLastChild->renderStyle() || !newLastChild->renderStyle()->lastChildState()))
1437             newLastChild->setNeedsStyleRecalc();
1438     }
1439
1440     // The + selector.  We need to invalidate the first element following the insertion point.  It is the only possible element
1441     // that could be affected by this DOM change.
1442     if (style->childrenAffectedByDirectAdjacentRules() && afterChange) {
1443         Node* firstElementAfterInsertion = 0;
1444         for (firstElementAfterInsertion = afterChange;
1445              firstElementAfterInsertion && !firstElementAfterInsertion->isElementNode();
1446              firstElementAfterInsertion = firstElementAfterInsertion->nextSibling()) {};
1447         if (firstElementAfterInsertion && firstElementAfterInsertion->attached())
1448             firstElementAfterInsertion->setNeedsStyleRecalc();
1449     }
1450
1451     // Forward positional selectors include the ~ selector, nth-child, nth-of-type, first-of-type and only-of-type.
1452     // Backward positional selectors include nth-last-child, nth-last-of-type, last-of-type and only-of-type.
1453     // We have to invalidate everything following the insertion point in the forward case, and everything before the insertion point in the
1454     // backward case.
1455     // |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.
1456     // 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
1457     // here.  recalcStyle will then force a walk of the children when it sees that this has happened.
1458     if ((style->childrenAffectedByForwardPositionalRules() && afterChange) ||
1459         (style->childrenAffectedByBackwardPositionalRules() && beforeChange))
1460         e->setNeedsStyleRecalc();
1461 }
1462
1463 void Element::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
1464 {
1465     ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
1466     if (changedByParser)
1467         checkForEmptyStyleChange(this, renderStyle());
1468     else
1469         checkForSiblingStyleChanges(this, renderStyle(), false, beforeChange, afterChange, childCountDelta);
1470
1471     if (ElementShadow * shadow = this->shadow())
1472         shadow->invalidateDistribution();
1473 }
1474
1475 void Element::beginParsingChildren()
1476 {
1477     clearIsParsingChildrenFinished();
1478     StyleResolver* styleResolver = document()->styleResolverIfExists();
1479     if (styleResolver && attached())
1480         styleResolver->pushParentElement(this);
1481 }
1482
1483 void Element::finishParsingChildren()
1484 {
1485     ContainerNode::finishParsingChildren();
1486     setIsParsingChildrenFinished();
1487     checkForSiblingStyleChanges(this, renderStyle(), true, lastChild(), 0, 0);
1488     if (StyleResolver* styleResolver = document()->styleResolverIfExists())
1489         styleResolver->popParentElement(this);
1490 }
1491
1492 #ifndef NDEBUG
1493 void Element::formatForDebugger(char* buffer, unsigned length) const
1494 {
1495     StringBuilder result;
1496     String s;
1497
1498     result.append(nodeName());
1499
1500     s = getIdAttribute();
1501     if (s.length() > 0) {
1502         if (result.length() > 0)
1503             result.appendLiteral("; ");
1504         result.appendLiteral("id=");
1505         result.append(s);
1506     }
1507
1508     s = getAttribute(classAttr);
1509     if (s.length() > 0) {
1510         if (result.length() > 0)
1511             result.appendLiteral("; ");
1512         result.appendLiteral("class=");
1513         result.append(s);
1514     }
1515
1516     strncpy(buffer, result.toString().utf8().data(), length - 1);
1517 }
1518 #endif
1519
1520 PassRefPtr<Attr> Element::setAttributeNode(Attr* attrNode, ExceptionCode& ec)
1521 {
1522     if (!attrNode) {
1523         ec = NATIVE_TYPE_ERR;
1524         return 0;
1525     }
1526
1527     RefPtr<Attr> oldAttrNode = attrIfExists(attrNode->qualifiedName());
1528     if (oldAttrNode.get() == attrNode)
1529         return attrNode; // This Attr is already attached to the element.
1530
1531     // INUSE_ATTRIBUTE_ERR: Raised if node is an Attr that is already an attribute of another Element object.
1532     // The DOM user must explicitly clone Attr nodes to re-use them in other elements.
1533     if (attrNode->ownerElement()) {
1534         ec = INUSE_ATTRIBUTE_ERR;
1535         return 0;
1536     }
1537
1538     updateInvalidAttributes();
1539     ElementAttributeData* attributeData = mutableAttributeData();
1540
1541     size_t index = attributeData->getAttributeItemIndex(attrNode->qualifiedName());
1542     if (index != notFound) {
1543         if (oldAttrNode)
1544             detachAttrNodeFromElementWithValue(oldAttrNode.get(), attributeData->attributeItem(index)->value());
1545         else
1546             oldAttrNode = Attr::create(document(), attrNode->qualifiedName(), attributeData->attributeItem(index)->value());
1547     }
1548
1549     setAttributeInternal(index, attrNode->qualifiedName(), attrNode->value(), NotInSynchronizationOfLazyAttribute);
1550
1551     attrNode->attachToElement(this);
1552     ensureAttrNodeListForElement(this)->append(attrNode);
1553
1554     return oldAttrNode.release();
1555 }
1556
1557 PassRefPtr<Attr> Element::setAttributeNodeNS(Attr* attr, ExceptionCode& ec)
1558 {
1559     return setAttributeNode(attr, ec);
1560 }
1561
1562 PassRefPtr<Attr> Element::removeAttributeNode(Attr* attr, ExceptionCode& ec)
1563 {
1564     if (!attr) {
1565         ec = NATIVE_TYPE_ERR;
1566         return 0;
1567     }
1568     if (attr->ownerElement() != this) {
1569         ec = NOT_FOUND_ERR;
1570         return 0;
1571     }
1572
1573     ASSERT(document() == attr->document());
1574
1575     const ElementAttributeData* attributeData = updatedAttributeData();
1576     ASSERT(attributeData);
1577
1578     size_t index = attributeData->getAttributeItemIndex(attr->qualifiedName());
1579     if (index == notFound) {
1580         ec = NOT_FOUND_ERR;
1581         return 0;
1582     }
1583
1584     return detachAttribute(index);
1585 }
1586
1587 bool Element::parseAttributeName(QualifiedName& out, const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionCode& ec)
1588 {
1589     String prefix, localName;
1590     if (!Document::parseQualifiedName(qualifiedName, prefix, localName, ec))
1591         return false;
1592     ASSERT(!ec);
1593
1594     QualifiedName qName(prefix, localName, namespaceURI);
1595
1596     if (!Document::hasValidNamespaceForAttributes(qName)) {
1597         ec = NAMESPACE_ERR;
1598         return false;
1599     }
1600
1601     out = qName;
1602     return true;
1603 }
1604
1605 void Element::setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode& ec)
1606 {
1607     QualifiedName parsedName = anyName;
1608     if (!parseAttributeName(parsedName, namespaceURI, qualifiedName, ec))
1609         return;
1610     setAttribute(parsedName, value);
1611 }
1612
1613 void Element::removeAttributeInternal(size_t index, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
1614 {
1615     ASSERT(index < attributeCount());
1616
1617     ElementAttributeData* attributeData = mutableAttributeData();
1618
1619     QualifiedName name = attributeData->attributeItem(index)->name();
1620     AtomicString valueBeingRemoved = attributeData->attributeItem(index)->value();
1621
1622     if (!inSynchronizationOfLazyAttribute) {
1623         if (!valueBeingRemoved.isNull())
1624             willModifyAttribute(name, valueBeingRemoved, nullAtom);
1625     }
1626
1627     if (RefPtr<Attr> attrNode = attrIfExists(name))
1628         detachAttrNodeFromElementWithValue(attrNode.get(), attributeData->attributeItem(index)->value());
1629
1630     attributeData->removeAttribute(index);
1631
1632     if (!inSynchronizationOfLazyAttribute)
1633         didRemoveAttribute(name);
1634 }
1635
1636 void Element::addAttributeInternal(const QualifiedName& name, const AtomicString& value, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
1637 {
1638     if (!inSynchronizationOfLazyAttribute)
1639         willModifyAttribute(name, nullAtom, value);
1640     mutableAttributeData()->addAttribute(Attribute(name, value));
1641     if (!inSynchronizationOfLazyAttribute)
1642         didAddAttribute(name, value);
1643 }
1644
1645 void Element::removeAttribute(const AtomicString& name)
1646 {
1647     if (!attributeData())
1648         return;
1649
1650     AtomicString localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
1651     size_t index = attributeData()->getAttributeItemIndex(localName, false);
1652     if (index == notFound) {
1653         if (UNLIKELY(localName == styleAttr) && !isStyleAttributeValid() && isStyledElement())
1654             static_cast<StyledElement*>(this)->removeAllInlineStyleProperties();
1655         return;
1656     }
1657
1658     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
1659 }
1660
1661 void Element::removeAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName)
1662 {
1663     removeAttribute(QualifiedName(nullAtom, localName, namespaceURI));
1664 }
1665
1666 PassRefPtr<Attr> Element::getAttributeNode(const AtomicString& name)
1667 {
1668     const ElementAttributeData* attributeData = updatedAttributeData();
1669     if (!attributeData)
1670         return 0;
1671     const Attribute* attribute = attributeData->getAttributeItem(name, shouldIgnoreAttributeCase(this));
1672     if (!attribute)
1673         return 0;
1674     return ensureAttr(attribute->name());
1675 }
1676
1677 PassRefPtr<Attr> Element::getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName)
1678 {
1679     const ElementAttributeData* attributeData = updatedAttributeData();
1680     if (!attributeData)
1681         return 0;
1682     const Attribute* attribute = attributeData->getAttributeItem(QualifiedName(nullAtom, localName, namespaceURI));
1683     if (!attribute)
1684         return 0;
1685     return ensureAttr(attribute->name());
1686 }
1687
1688 bool Element::hasAttribute(const AtomicString& name) const
1689 {
1690     if (!attributeData())
1691         return false;
1692
1693     // This call to String::lower() seems to be required but
1694     // there may be a way to remove it.
1695     AtomicString localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
1696     return updatedAttributeData()->getAttributeItem(localName, false);
1697 }
1698
1699 bool Element::hasAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const
1700 {
1701     const ElementAttributeData* attributeData = updatedAttributeData();
1702     if (!attributeData)
1703         return false;
1704     return attributeData->getAttributeItem(QualifiedName(nullAtom, localName, namespaceURI));
1705 }
1706
1707 CSSStyleDeclaration *Element::style()
1708 {
1709     return 0;
1710 }
1711
1712 void Element::focus(bool restorePreviousSelection)
1713 {
1714     if (!inDocument())
1715         return;
1716
1717     Document* doc = document();
1718     if (doc->focusedNode() == this)
1719         return;
1720
1721     // If the stylesheets have already been loaded we can reliably check isFocusable.
1722     // If not, we continue and set the focused node on the focus controller below so
1723     // that it can be updated soon after attach. 
1724     if (doc->haveStylesheetsLoaded()) {
1725         doc->updateLayoutIgnorePendingStylesheets();
1726         if (!isFocusable())
1727             return;
1728     }
1729
1730     if (!supportsFocus())
1731         return;
1732
1733     RefPtr<Node> protect;
1734     if (Page* page = doc->page()) {
1735         // Focus and change event handlers can cause us to lose our last ref.
1736         // If a focus event handler changes the focus to a different node it
1737         // does not make sense to continue and update appearence.
1738         protect = this;
1739         if (!page->focusController()->setFocusedNode(this, doc->frame()))
1740             return;
1741     }
1742
1743     // Setting the focused node above might have invalidated the layout due to scripts.
1744     doc->updateLayoutIgnorePendingStylesheets();
1745
1746     if (!isFocusable()) {
1747         ensureElementRareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(true);
1748         return;
1749     }
1750         
1751     cancelFocusAppearanceUpdate();
1752     updateFocusAppearance(restorePreviousSelection);
1753 }
1754
1755 void Element::updateFocusAppearance(bool /*restorePreviousSelection*/)
1756 {
1757     if (isRootEditableElement()) {
1758         Frame* frame = document()->frame();
1759         if (!frame)
1760             return;
1761         
1762         // When focusing an editable element in an iframe, don't reset the selection if it already contains a selection.
1763         if (this == frame->selection()->rootEditableElement())
1764             return;
1765
1766         // FIXME: We should restore the previous selection if there is one.
1767         VisibleSelection newSelection = VisibleSelection(firstPositionInOrBeforeNode(this), DOWNSTREAM);
1768         
1769         if (frame->selection()->shouldChangeSelection(newSelection)) {
1770             frame->selection()->setSelection(newSelection);
1771             frame->selection()->revealSelection();
1772         }
1773     } else if (renderer() && !renderer()->isWidget())
1774         renderer()->scrollRectToVisible(boundingBox());
1775 }
1776
1777 void Element::blur()
1778 {
1779     cancelFocusAppearanceUpdate();
1780     Document* doc = document();
1781     if (treeScope()->focusedNode() == this) {
1782         if (doc->frame())
1783             doc->frame()->page()->focusController()->setFocusedNode(0, doc->frame());
1784         else
1785             doc->setFocusedNode(0);
1786     }
1787 }
1788
1789 String Element::innerText()
1790 {
1791     // We need to update layout, since plainText uses line boxes in the render tree.
1792     document()->updateLayoutIgnorePendingStylesheets();
1793
1794     if (!renderer())
1795         return textContent(true);
1796
1797     return plainText(rangeOfContents(const_cast<Element*>(this)).get());
1798 }
1799
1800 String Element::outerText()
1801 {
1802     // Getting outerText is the same as getting innerText, only
1803     // setting is different. You would think this should get the plain
1804     // text for the outer range, but this is wrong, <br> for instance
1805     // would return different values for inner and outer text by such
1806     // a rule, but it doesn't in WinIE, and we want to match that.
1807     return innerText();
1808 }
1809
1810 String Element::title() const
1811 {
1812     return String();
1813 }
1814
1815 const AtomicString& Element::pseudo() const
1816 {
1817     return getAttribute(pseudoAttr);
1818 }
1819
1820 void Element::setPseudo(const AtomicString& value)
1821 {
1822     setAttribute(pseudoAttr, value);
1823 }
1824
1825 LayoutSize Element::minimumSizeForResizing() const
1826 {
1827     return hasRareData() ? elementRareData()->m_minimumSizeForResizing : defaultMinimumSizeForResizing();
1828 }
1829
1830 void Element::setMinimumSizeForResizing(const LayoutSize& size)
1831 {
1832     if (size == defaultMinimumSizeForResizing() && !hasRareData())
1833         return;
1834     ensureElementRareData()->m_minimumSizeForResizing = size;
1835 }
1836
1837 RenderStyle* Element::computedStyle(PseudoId pseudoElementSpecifier)
1838 {
1839     // FIXME: Find and use the renderer from the pseudo element instead of the actual element so that the 'length'
1840     // properties, which are only known by the renderer because it did the layout, will be correct and so that the
1841     // values returned for the ":selection" pseudo-element will be correct.
1842     if (RenderStyle* usedStyle = renderStyle()) {
1843         if (pseudoElementSpecifier) {
1844             RenderStyle* cachedPseudoStyle = usedStyle->getCachedPseudoStyle(pseudoElementSpecifier);
1845             return cachedPseudoStyle ? cachedPseudoStyle : usedStyle;
1846          } else
1847             return usedStyle;
1848     }
1849
1850     if (!attached())
1851         // FIXME: Try to do better than this. Ensure that styleForElement() works for elements that are not in the
1852         // document tree and figure out when to destroy the computed style for such elements.
1853         return 0;
1854
1855     ElementRareData* data = ensureElementRareData();
1856     if (!data->m_computedStyle)
1857         data->m_computedStyle = document()->styleForElementIgnoringPendingStylesheets(this);
1858     return pseudoElementSpecifier ? data->m_computedStyle->getCachedPseudoStyle(pseudoElementSpecifier) : data->m_computedStyle.get();
1859 }
1860
1861 void Element::setStyleAffectedByEmpty()
1862 {
1863     ensureElementRareData()->setStyleAffectedByEmpty(true);
1864 }
1865
1866 bool Element::styleAffectedByEmpty() const
1867 {
1868     return hasRareData() && elementRareData()->styleAffectedByEmpty();
1869 }
1870
1871 void Element::setIsInCanvasSubtree(bool isInCanvasSubtree)
1872 {
1873     ensureElementRareData()->setIsInCanvasSubtree(isInCanvasSubtree);
1874 }
1875
1876 bool Element::isInCanvasSubtree() const
1877 {
1878     return hasRareData() && elementRareData()->isInCanvasSubtree();
1879 }
1880
1881 AtomicString Element::computeInheritedLanguage() const
1882 {
1883     const Node* n = this;
1884     AtomicString value;
1885     // The language property is inherited, so we iterate over the parents to find the first language.
1886     do {
1887         if (n->isElementNode()) {
1888             if (const ElementAttributeData* attributeData = static_cast<const Element*>(n)->attributeData()) {
1889                 // Spec: xml:lang takes precedence -- http://www.w3.org/TR/xhtml1/#C_7
1890                 if (const Attribute* attribute = attributeData->getAttributeItem(XMLNames::langAttr))
1891                     value = attribute->value();
1892                 else if (const Attribute* attribute = attributeData->getAttributeItem(HTMLNames::langAttr))
1893                     value = attribute->value();
1894             }
1895         } else if (n->isDocumentNode()) {
1896             // checking the MIME content-language
1897             value = static_cast<const Document*>(n)->contentLanguage();
1898         }
1899
1900         n = n->parentNode();
1901     } while (n && value.isNull());
1902
1903     return value;
1904 }
1905
1906 Locale& Element::locale() const
1907 {
1908     return document()->getCachedLocale(computeInheritedLanguage());
1909 }
1910
1911 void Element::cancelFocusAppearanceUpdate()
1912 {
1913     if (hasRareData())
1914         elementRareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
1915     if (document()->focusedNode() == this)
1916         document()->cancelFocusAppearanceUpdate();
1917 }
1918
1919 void Element::normalizeAttributes()
1920 {
1921     updateInvalidAttributes();
1922     if (AttrNodeList* attrNodeList = attrNodeListForElement(this)) {
1923         for (unsigned i = 0; i < attrNodeList->size(); ++i)
1924             attrNodeList->at(i)->normalize();
1925     }
1926 }
1927
1928 // ElementTraversal API
1929 Element* Element::firstElementChild() const
1930 {
1931     return WebCore::firstElementChild(this);
1932 }
1933
1934 Element* Element::lastElementChild() const
1935 {
1936     Node* n = lastChild();
1937     while (n && !n->isElementNode())
1938         n = n->previousSibling();
1939     return static_cast<Element*>(n);
1940 }
1941
1942 unsigned Element::childElementCount() const
1943 {
1944     unsigned count = 0;
1945     Node* n = firstChild();
1946     while (n) {
1947         count += n->isElementNode();
1948         n = n->nextSibling();
1949     }
1950     return count;
1951 }
1952
1953 bool Element::shouldMatchReadOnlySelector() const
1954 {
1955     return false;
1956 }
1957
1958 bool Element::shouldMatchReadWriteSelector() const
1959 {
1960     return false;
1961 }
1962
1963 bool Element::webkitMatchesSelector(const String& selector, ExceptionCode& ec)
1964 {
1965     if (selector.isEmpty()) {
1966         ec = SYNTAX_ERR;
1967         return false;
1968     }
1969
1970     SelectorQuery* selectorQuery = document()->selectorQueryCache()->add(selector, document(), ec);
1971     if (!selectorQuery)
1972         return false;
1973     return selectorQuery->matches(this);
1974 }
1975
1976 DOMTokenList* Element::classList()
1977 {
1978     ElementRareData* data = ensureElementRareData();
1979     if (!data->m_classList)
1980         data->m_classList = ClassList::create(this);
1981     return data->m_classList.get();
1982 }
1983
1984 DOMTokenList* Element::optionalClassList() const
1985 {
1986     if (!hasRareData())
1987         return 0;
1988     return elementRareData()->m_classList.get();
1989 }
1990
1991 DOMStringMap* Element::dataset()
1992 {
1993     ElementRareData* data = ensureElementRareData();
1994     if (!data->m_datasetDOMStringMap)
1995         data->m_datasetDOMStringMap = DatasetDOMStringMap::create(this);
1996     return data->m_datasetDOMStringMap.get();
1997 }
1998
1999 KURL Element::getURLAttribute(const QualifiedName& name) const
2000 {
2001 #if !ASSERT_DISABLED
2002     if (attributeData()) {
2003         if (const Attribute* attribute = getAttributeItem(name))
2004             ASSERT(isURLAttribute(*attribute));
2005     }
2006 #endif
2007     return document()->completeURL(stripLeadingAndTrailingHTMLSpaces(getAttribute(name)));
2008 }
2009
2010 KURL Element::getNonEmptyURLAttribute(const QualifiedName& name) const
2011 {
2012 #if !ASSERT_DISABLED
2013     if (attributeData()) {
2014         if (const Attribute* attribute = getAttributeItem(name))
2015             ASSERT(isURLAttribute(*attribute));
2016     }
2017 #endif
2018     String value = stripLeadingAndTrailingHTMLSpaces(getAttribute(name));
2019     if (value.isEmpty())
2020         return KURL();
2021     return document()->completeURL(value);
2022 }
2023
2024 int Element::getIntegralAttribute(const QualifiedName& attributeName) const
2025 {
2026     return getAttribute(attributeName).string().toInt();
2027 }
2028
2029 void Element::setIntegralAttribute(const QualifiedName& attributeName, int value)
2030 {
2031     // FIXME: Need an AtomicString version of String::number.
2032     setAttribute(attributeName, String::number(value));
2033 }
2034
2035 unsigned Element::getUnsignedIntegralAttribute(const QualifiedName& attributeName) const
2036 {
2037     return getAttribute(attributeName).string().toUInt();
2038 }
2039
2040 void Element::setUnsignedIntegralAttribute(const QualifiedName& attributeName, unsigned value)
2041 {
2042     // FIXME: Need an AtomicString version of String::number.
2043     setAttribute(attributeName, String::number(value));
2044 }
2045
2046 #if ENABLE(SVG)
2047 bool Element::childShouldCreateRenderer(const NodeRenderingContext& childContext) const
2048 {
2049     // Only create renderers for SVG elements whose parents are SVG elements, or for proper <svg xmlns="svgNS"> subdocuments.
2050     if (childContext.node()->isSVGElement())
2051         return childContext.node()->hasTagName(SVGNames::svgTag) || isSVGElement();
2052
2053     return Node::childShouldCreateRenderer(childContext);
2054 }
2055 #endif
2056     
2057 #if ENABLE(FULLSCREEN_API)
2058 void Element::webkitRequestFullscreen()
2059 {
2060     document()->requestFullScreenForElement(this, ALLOW_KEYBOARD_INPUT, Document::EnforceIFrameAllowFullScreenRequirement);
2061 }
2062
2063 void Element::webkitRequestFullScreen(unsigned short flags)
2064 {
2065     document()->requestFullScreenForElement(this, (flags | LEGACY_MOZILLA_REQUEST), Document::EnforceIFrameAllowFullScreenRequirement);
2066 }
2067
2068 bool Element::containsFullScreenElement() const
2069 {
2070     return hasRareData() && elementRareData()->containsFullScreenElement();
2071 }
2072
2073 void Element::setContainsFullScreenElement(bool flag)
2074 {
2075     ensureElementRareData()->setContainsFullScreenElement(flag);
2076     setNeedsStyleRecalc(SyntheticStyleChange);
2077 }
2078
2079 static Element* parentCrossingFrameBoundaries(Element* element)
2080 {
2081     ASSERT(element);
2082     return element->parentElement() ? element->parentElement() : element->document()->ownerElement();
2083 }
2084
2085 void Element::setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(bool flag)
2086 {
2087     Element* element = this;
2088     while ((element = parentCrossingFrameBoundaries(element)))
2089         element->setContainsFullScreenElement(flag);
2090 }
2091 #endif    
2092
2093 #if ENABLE(POINTER_LOCK)
2094 void Element::webkitRequestPointerLock()
2095 {
2096     if (document()->page())
2097         document()->page()->pointerLockController()->requestPointerLock(this);
2098 }
2099 #endif
2100
2101 SpellcheckAttributeState Element::spellcheckAttributeState() const
2102 {
2103     const AtomicString& value = getAttribute(HTMLNames::spellcheckAttr);
2104     if (value == nullAtom)
2105         return SpellcheckAttributeDefault;
2106     if (equalIgnoringCase(value, "true") || equalIgnoringCase(value, ""))
2107         return SpellcheckAttributeTrue;
2108     if (equalIgnoringCase(value, "false"))
2109         return SpellcheckAttributeFalse;
2110
2111     return SpellcheckAttributeDefault;
2112 }
2113
2114 bool Element::isSpellCheckingEnabled() const
2115 {
2116     const Element* element = this;
2117     while (element) {
2118         switch (element->spellcheckAttributeState()) {
2119         case SpellcheckAttributeTrue:
2120             return true;
2121         case SpellcheckAttributeFalse:
2122             return false;
2123         case SpellcheckAttributeDefault:
2124             break;
2125         }
2126
2127         ContainerNode* parent = const_cast<Element*>(element)->parentOrHostNode();
2128         if (parent && parent->isElementNode())
2129             element = toElement(parent);
2130         else if (parent && parent->isShadowRoot())
2131             element = toElement(parent->parentOrHostNode());
2132         else
2133             element = 0;
2134     }
2135
2136     return true;
2137 }
2138
2139 PassRefPtr<WebKitAnimationList> Element::webkitGetAnimations() const
2140 {
2141     if (!renderer())
2142         return 0;
2143
2144     AnimationController* animController = renderer()->animation();
2145
2146     if (!animController)
2147         return 0;
2148     
2149     return animController->animationsForRenderer(renderer());
2150 }
2151
2152 RenderRegion* Element::renderRegion() const
2153 {
2154     if (renderer() && renderer()->isRenderRegion())
2155         return toRenderRegion(renderer());
2156
2157     return 0;
2158 }
2159
2160 #if ENABLE(CSS_REGIONS)
2161
2162 const AtomicString& Element::webkitRegionOverset() const
2163 {
2164     document()->updateLayoutIgnorePendingStylesheets();
2165
2166     DEFINE_STATIC_LOCAL(AtomicString, undefinedState, ("undefined", AtomicString::ConstructFromLiteral));
2167     if (!document()->cssRegionsEnabled() || !renderRegion())
2168         return undefinedState;
2169
2170     switch (renderRegion()->regionState()) {
2171     case RenderRegion::RegionFit: {
2172         DEFINE_STATIC_LOCAL(AtomicString, fitState, ("fit", AtomicString::ConstructFromLiteral));
2173         return fitState;
2174     }
2175     case RenderRegion::RegionEmpty: {
2176         DEFINE_STATIC_LOCAL(AtomicString, emptyState, ("empty", AtomicString::ConstructFromLiteral));
2177         return emptyState;
2178     }
2179     case RenderRegion::RegionOverset: {
2180         DEFINE_STATIC_LOCAL(AtomicString, overflowState, ("overset", AtomicString::ConstructFromLiteral));
2181         return overflowState;
2182     }
2183     case RenderRegion::RegionUndefined:
2184         return undefinedState;
2185     }
2186
2187     ASSERT_NOT_REACHED();
2188     return undefinedState;
2189 }
2190
2191 Vector<RefPtr<Range> > Element::webkitGetRegionFlowRanges() const
2192 {
2193     document()->updateLayoutIgnorePendingStylesheets();
2194
2195     Vector<RefPtr<Range> > rangeObjects;
2196     if (document()->cssRegionsEnabled() && renderer() && renderer()->isRenderRegion()) {
2197         RenderRegion* region = toRenderRegion(renderer());
2198         if (region->isValid())
2199             region->getRanges(rangeObjects);
2200     }
2201
2202     return rangeObjects;
2203 }
2204
2205 #endif
2206
2207 #ifndef NDEBUG
2208 bool Element::fastAttributeLookupAllowed(const QualifiedName& name) const
2209 {
2210     if (name == HTMLNames::styleAttr)
2211         return false;
2212
2213 #if ENABLE(SVG)
2214     if (isSVGElement())
2215         return !SVGElement::isAnimatableAttribute(name);
2216 #endif
2217
2218     return true;
2219 }
2220 #endif
2221
2222 #ifdef DUMP_NODE_STATISTICS
2223 bool Element::hasNamedNodeMap() const
2224 {
2225     return hasRareData() && elementRareData()->m_attributeMap;
2226 }
2227 #endif
2228
2229 void Element::updateLabel(TreeScope* scope, const AtomicString& oldForAttributeValue, const AtomicString& newForAttributeValue)
2230 {
2231     ASSERT(hasTagName(labelTag));
2232
2233     if (!inDocument())
2234         return;
2235
2236     if (oldForAttributeValue == newForAttributeValue)
2237         return;
2238
2239     if (!oldForAttributeValue.isEmpty())
2240         scope->removeLabel(oldForAttributeValue, static_cast<HTMLLabelElement*>(this));
2241     if (!newForAttributeValue.isEmpty())
2242         scope->addLabel(newForAttributeValue, static_cast<HTMLLabelElement*>(this));
2243 }
2244
2245 void Element::willModifyAttribute(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue)
2246 {
2247     if (isIdAttributeName(name))
2248         updateId(oldValue, newValue);
2249     else if (name == HTMLNames::nameAttr)
2250         updateName(oldValue, newValue);
2251     else if (name == HTMLNames::forAttr && hasTagName(labelTag)) {
2252         TreeScope* scope = treeScope();
2253         if (scope->shouldCacheLabelsByForAttribute())
2254             updateLabel(scope, oldValue, newValue);
2255     }
2256
2257 #if ENABLE(MUTATION_OBSERVERS)
2258     if (OwnPtr<MutationObserverInterestGroup> recipients = MutationObserverInterestGroup::createForAttributesMutation(this, name))
2259         recipients->enqueueMutationRecord(MutationRecord::createAttributes(this, name, oldValue));
2260 #endif
2261
2262 #if ENABLE(INSPECTOR)
2263     InspectorInstrumentation::willModifyDOMAttr(document(), this, oldValue, newValue);
2264 #endif
2265 }
2266
2267 void Element::didAddAttribute(const QualifiedName& name, const AtomicString& value)
2268 {
2269     attributeChanged(name, value);
2270     InspectorInstrumentation::didModifyDOMAttr(document(), this, name.localName(), value);
2271     dispatchSubtreeModifiedEvent();
2272 }
2273
2274 void Element::didModifyAttribute(const QualifiedName& name, const AtomicString& value)
2275 {
2276     attributeChanged(name, value);
2277     InspectorInstrumentation::didModifyDOMAttr(document(), this, name.localName(), value);
2278     // Do not dispatch a DOMSubtreeModified event here; see bug 81141.
2279 }
2280
2281 void Element::didRemoveAttribute(const QualifiedName& name)
2282 {
2283     attributeChanged(name, nullAtom);
2284     InspectorInstrumentation::didRemoveDOMAttr(document(), this, name.localName());
2285     dispatchSubtreeModifiedEvent();
2286 }
2287
2288
2289 void Element::updateNamedItemRegistration(const AtomicString& oldName, const AtomicString& newName)
2290 {
2291     if (!document()->isHTMLDocument())
2292         return;
2293
2294     if (!oldName.isEmpty())
2295         static_cast<HTMLDocument*>(document())->removeNamedItem(oldName);
2296
2297     if (!newName.isEmpty())
2298         static_cast<HTMLDocument*>(document())->addNamedItem(newName);
2299 }
2300
2301 void Element::updateExtraNamedItemRegistration(const AtomicString& oldId, const AtomicString& newId)
2302 {
2303     if (!document()->isHTMLDocument())
2304         return;
2305
2306     if (!oldId.isEmpty())
2307         static_cast<HTMLDocument*>(document())->removeExtraNamedItem(oldId);
2308
2309     if (!newId.isEmpty())
2310         static_cast<HTMLDocument*>(document())->addExtraNamedItem(newId);
2311 }
2312
2313 PassRefPtr<HTMLCollection> Element::ensureCachedHTMLCollection(CollectionType type)
2314 {
2315     return ensureElementRareData()->ensureCachedHTMLCollection(this, type);
2316 }
2317
2318 PassRefPtr<HTMLCollection> ElementRareData::ensureCachedHTMLCollection(Element* element, CollectionType type)
2319 {
2320     if (!m_cachedCollections) {
2321         m_cachedCollections = adoptPtr(new CachedHTMLCollectionArray);
2322         for (unsigned i = 0; i < NumNodeCollectionTypes; i++)
2323             (*m_cachedCollections)[i] = 0;
2324     }
2325
2326     if (HTMLCollection* collection = (*m_cachedCollections)[type - FirstNodeCollectionType])
2327         return collection;
2328
2329     RefPtr<HTMLCollection> collection;
2330     if (type == TableRows) {
2331         ASSERT(element->hasTagName(tableTag));
2332         collection = HTMLTableRowsCollection::create(element);
2333     } else if (type == SelectOptions) {
2334         ASSERT(element->hasTagName(selectTag));
2335         collection = HTMLOptionsCollection::create(element);
2336     } else if (type == FormControls) {
2337         ASSERT(element->hasTagName(formTag) || element->hasTagName(fieldsetTag));
2338         collection = HTMLFormCollection::create(element);
2339 #if ENABLE(MICRODATA)
2340     } else if (type == ItemProperties) {
2341         collection = HTMLPropertiesCollection::create(element);
2342 #endif
2343     } else
2344         collection = HTMLCollection::create(element, type);
2345     (*m_cachedCollections)[type - FirstNodeCollectionType] = collection.get();
2346     return collection.release();
2347 }
2348
2349 HTMLCollection* Element::cachedHTMLCollection(CollectionType type)
2350 {
2351     return hasRareData() ? elementRareData()->cachedHTMLCollection(type) : 0;
2352 }
2353
2354 void Element::removeCachedHTMLCollection(HTMLCollection* collection, CollectionType type)
2355 {
2356     ASSERT(hasRareData());
2357     elementRareData()->removeCachedHTMLCollection(collection, type);
2358 }
2359
2360 IntSize Element::savedLayerScrollOffset() const
2361 {
2362     return hasRareData() ? elementRareData()->m_savedLayerScrollOffset : IntSize();
2363 }
2364
2365 void Element::setSavedLayerScrollOffset(const IntSize& size)
2366 {
2367     if (size.isZero() && !hasRareData())
2368         return;
2369     ensureElementRareData()->m_savedLayerScrollOffset = size;
2370 }
2371
2372 PassRefPtr<Attr> Element::attrIfExists(const QualifiedName& name)
2373 {
2374     if (AttrNodeList* attrNodeList = attrNodeListForElement(this))
2375         return findAttrNodeInList(attrNodeList, name);
2376     return 0;
2377 }
2378
2379 PassRefPtr<Attr> Element::ensureAttr(const QualifiedName& name)
2380 {
2381     AttrNodeList* attrNodeList = ensureAttrNodeListForElement(this);
2382     RefPtr<Attr> attrNode = findAttrNodeInList(attrNodeList, name);
2383     if (!attrNode) {
2384         attrNode = Attr::create(this, name);
2385         attrNodeList->append(attrNode);
2386     }
2387     return attrNode.release();
2388 }
2389
2390 void Element::detachAttrNodeFromElementWithValue(Attr* attrNode, const AtomicString& value)
2391 {
2392     ASSERT(hasSyntheticAttrChildNodes());
2393     attrNode->detachFromElementWithValue(value);
2394
2395     AttrNodeList* attrNodeList = attrNodeListForElement(this);
2396     for (unsigned i = 0; i < attrNodeList->size(); ++i) {
2397         if (attrNodeList->at(i)->qualifiedName() == attrNode->qualifiedName()) {
2398             attrNodeList->remove(i);
2399             if (attrNodeList->isEmpty())
2400                 removeAttrNodeListForElement(this);
2401             return;
2402         }
2403     }
2404     ASSERT_NOT_REACHED();
2405 }
2406
2407 void Element::detachAllAttrNodesFromElement()
2408 {
2409     AttrNodeList* attrNodeList = attrNodeListForElement(this);
2410     ASSERT(attrNodeList);
2411
2412     for (unsigned i = 0; i < attributeCount(); ++i) {
2413         const Attribute* attribute = attributeItem(i);
2414         if (RefPtr<Attr> attrNode = findAttrNodeInList(attrNodeList, attribute->name()))
2415             attrNode->detachFromElementWithValue(attribute->value());
2416     }
2417
2418     removeAttrNodeListForElement(this);
2419 }
2420
2421 bool Element::willRecalcStyle(StyleChange)
2422 {
2423     ASSERT(hasCustomCallbacks());
2424     return true;
2425 }
2426
2427 void Element::didRecalcStyle(StyleChange)
2428 {
2429     ASSERT(hasCustomCallbacks());
2430 }
2431
2432
2433 PassRefPtr<RenderStyle> Element::customStyleForRenderer()
2434 {
2435     ASSERT(hasCustomCallbacks());
2436     return 0;
2437 }
2438
2439
2440 void Element::cloneAttributesFromElement(const Element& other)
2441 {
2442     if (hasSyntheticAttrChildNodes())
2443         detachAllAttrNodesFromElement();
2444
2445     setIsStyleAttributeValid(other.isStyleAttributeValid());
2446
2447     other.updateInvalidAttributes();
2448     if (!other.m_attributeData) {
2449         m_attributeData.clear();
2450         return;
2451     }
2452
2453     const AtomicString& oldID = getIdAttribute();
2454     const AtomicString& newID = other.getIdAttribute();
2455
2456     if (!oldID.isNull() || !newID.isNull())
2457         updateId(oldID, newID);
2458
2459     const AtomicString& oldName = getNameAttribute();
2460     const AtomicString& newName = other.getNameAttribute();
2461
2462     if (!oldName.isNull() || !newName.isNull())
2463         updateName(oldName, newName);
2464
2465     // If 'other' has a mutable ElementAttributeData, convert it to an immutable one so we can share it between both elements.
2466     // We can only do this if there is no CSSOM wrapper for other's inline style (the isMutable() check.)
2467     if (other.m_attributeData->isMutable() && (!other.m_attributeData->inlineStyle() || !other.m_attributeData->inlineStyle()->isMutable()))
2468         const_cast<Element&>(other).m_attributeData = other.m_attributeData->makeImmutableCopy();
2469
2470     if (!other.m_attributeData->isMutable())
2471         m_attributeData = other.m_attributeData;
2472     else
2473         m_attributeData = other.m_attributeData->makeMutableCopy();
2474
2475     for (unsigned i = 0; i < m_attributeData->length(); ++i) {
2476         const Attribute* attribute = const_cast<const ElementAttributeData*>(m_attributeData.get())->attributeItem(i);
2477         // This optimization isn't very nicely factored, but a huge win for cloning elements with inline style.
2478         if (isStyledElement() && attribute->name() == HTMLNames::styleAttr) {
2479             static_cast<StyledElement*>(this)->styleAttributeChanged(attribute->value(), StyledElement::DoNotReparseStyleAttribute);
2480             continue;
2481         }
2482         attributeChanged(attribute->name(), attribute->value());
2483     }
2484 }
2485
2486 void Element::cloneDataFromElement(const Element& other)
2487 {
2488     cloneAttributesFromElement(other);
2489     copyNonAttributePropertiesFromElement(other);
2490 }
2491
2492 void Element::createMutableAttributeData()
2493 {
2494     if (!m_attributeData)
2495         m_attributeData = ElementAttributeData::create();
2496     else
2497         m_attributeData = m_attributeData->makeMutableCopy();
2498 }
2499
2500 void Element::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
2501 {
2502     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM);
2503     ContainerNode::reportMemoryUsage(memoryObjectInfo);
2504     info.addMember(m_tagName);
2505     info.addMember(m_attributeData);
2506 }
2507
2508 } // namespace WebCore