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