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