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