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