Node::document() should return a reference.
[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().renderer()) {
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     if (!inSynchronizationOfLazyAttribute)
967         willModifyAttribute(name, attributeAt(index).value(), newValue);
968
969     if (newValue != attributeAt(index).value()) {
970         // If there is an Attr node hooked to this attribute, the Attr::setValue() call below
971         // will write into the ElementData.
972         // FIXME: Refactor this so it makes some sense.
973         if (RefPtr<Attr> attrNode = inSynchronizationOfLazyAttribute ? 0 : attrIfExists(name))
974             attrNode->setValue(newValue);
975         else
976             ensureUniqueElementData().attributeAt(index).setValue(newValue);
977     }
978
979     if (!inSynchronizationOfLazyAttribute)
980         didModifyAttribute(name, newValue);
981 }
982
983 static inline AtomicString makeIdForStyleResolution(const AtomicString& value, bool inQuirksMode)
984 {
985     if (inQuirksMode)
986         return value.lower();
987     return value;
988 }
989
990 static bool checkNeedsStyleInvalidationForIdChange(const AtomicString& oldId, const AtomicString& newId, StyleResolver* styleResolver)
991 {
992     ASSERT(newId != oldId);
993     if (!oldId.isEmpty() && styleResolver->hasSelectorForId(oldId))
994         return true;
995     if (!newId.isEmpty() && styleResolver->hasSelectorForId(newId))
996         return true;
997     return false;
998 }
999
1000 void Element::attributeChanged(const QualifiedName& name, const AtomicString& newValue, AttributeModificationReason)
1001 {
1002     parseAttribute(name, newValue);
1003
1004     document().incDOMTreeVersion();
1005
1006     StyleResolver* styleResolver = document().styleResolverIfExists();
1007     bool testShouldInvalidateStyle = attached() && styleResolver && styleChangeType() < FullStyleChange;
1008     bool shouldInvalidateStyle = false;
1009
1010     if (isIdAttributeName(name)) {
1011         AtomicString oldId = elementData()->idForStyleResolution();
1012         AtomicString newId = makeIdForStyleResolution(newValue, document().inQuirksMode());
1013         if (newId != oldId) {
1014             elementData()->setIdForStyleResolution(newId);
1015             shouldInvalidateStyle = testShouldInvalidateStyle && checkNeedsStyleInvalidationForIdChange(oldId, newId, styleResolver);
1016         }
1017     } else if (name == classAttr)
1018         classAttributeChanged(newValue);
1019     else if (name == HTMLNames::nameAttr)
1020         elementData()->m_hasNameAttribute = !newValue.isNull();
1021     else if (name == HTMLNames::pseudoAttr)
1022         shouldInvalidateStyle |= testShouldInvalidateStyle && isInShadowTree();
1023
1024
1025     invalidateNodeListCachesInAncestors(&name, this);
1026
1027     // If there is currently no StyleResolver, we can't be sure that this attribute change won't affect style.
1028     shouldInvalidateStyle |= !styleResolver;
1029
1030     if (shouldInvalidateStyle)
1031         setNeedsStyleRecalc();
1032
1033     if (AXObjectCache* cache = document().existingAXObjectCache())
1034         cache->handleAttributeChanged(name, this);
1035 }
1036
1037 inline void Element::attributeChangedFromParserOrByCloning(const QualifiedName& name, const AtomicString& newValue, AttributeModificationReason reason)
1038 {
1039 #if ENABLE(CUSTOM_ELEMENTS)
1040     if (name == isAttr) {
1041         if (CustomElementRegistry* registry = document().registry())
1042             registry->didGiveTypeExtension(this);
1043     }
1044 #endif
1045     attributeChanged(name, newValue, reason);
1046 }
1047
1048 template <typename CharacterType>
1049 static inline bool classStringHasClassName(const CharacterType* characters, unsigned length)
1050 {
1051     ASSERT(length > 0);
1052
1053     unsigned i = 0;
1054     do {
1055         if (isNotHTMLSpace(characters[i]))
1056             break;
1057         ++i;
1058     } while (i < length);
1059
1060     return i < length;
1061 }
1062
1063 static inline bool classStringHasClassName(const AtomicString& newClassString)
1064 {
1065     unsigned length = newClassString.length();
1066
1067     if (!length)
1068         return false;
1069
1070     if (newClassString.is8Bit())
1071         return classStringHasClassName(newClassString.characters8(), length);
1072     return classStringHasClassName(newClassString.characters16(), length);
1073 }
1074
1075 template<typename Checker>
1076 static bool checkSelectorForClassChange(const SpaceSplitString& changedClasses, const Checker& checker)
1077 {
1078     unsigned changedSize = changedClasses.size();
1079     for (unsigned i = 0; i < changedSize; ++i) {
1080         if (checker.hasSelectorForClass(changedClasses[i]))
1081             return true;
1082     }
1083     return false;
1084 }
1085
1086 template<typename Checker>
1087 static bool checkSelectorForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses, const Checker& checker)
1088 {
1089     unsigned oldSize = oldClasses.size();
1090     if (!oldSize)
1091         return checkSelectorForClassChange(newClasses, checker);
1092     BitVector remainingClassBits;
1093     remainingClassBits.ensureSize(oldSize);
1094     // Class vectors tend to be very short. This is faster than using a hash table.
1095     unsigned newSize = newClasses.size();
1096     for (unsigned i = 0; i < newSize; ++i) {
1097         for (unsigned j = 0; j < oldSize; ++j) {
1098             if (newClasses[i] == oldClasses[j]) {
1099                 remainingClassBits.quickSet(j);
1100                 continue;
1101             }
1102         }
1103         if (checker.hasSelectorForClass(newClasses[i]))
1104             return true;
1105     }
1106     for (unsigned i = 0; i < oldSize; ++i) {
1107         // If the bit is not set the the corresponding class has been removed.
1108         if (remainingClassBits.quickGet(i))
1109             continue;
1110         if (checker.hasSelectorForClass(oldClasses[i]))
1111             return true;
1112     }
1113     return false;
1114 }
1115
1116 void Element::classAttributeChanged(const AtomicString& newClassString)
1117 {
1118     StyleResolver* styleResolver = document().styleResolverIfExists();
1119     bool testShouldInvalidateStyle = attached() && styleResolver && styleChangeType() < FullStyleChange;
1120     bool shouldInvalidateStyle = false;
1121
1122     if (classStringHasClassName(newClassString)) {
1123         const bool shouldFoldCase = document().inQuirksMode();
1124         const SpaceSplitString oldClasses = ensureUniqueElementData().classNames();
1125         elementData()->setClass(newClassString, shouldFoldCase);
1126         const SpaceSplitString& newClasses = elementData()->classNames();
1127         shouldInvalidateStyle = testShouldInvalidateStyle && checkSelectorForClassChange(oldClasses, newClasses, *styleResolver);
1128     } else if (elementData()) {
1129         const SpaceSplitString& oldClasses = elementData()->classNames();
1130         shouldInvalidateStyle = testShouldInvalidateStyle && checkSelectorForClassChange(oldClasses, *styleResolver);
1131         elementData()->clearClass();
1132     }
1133
1134     if (hasRareData())
1135         elementRareData()->clearClassListValueForQuirksMode();
1136
1137     if (shouldInvalidateStyle)
1138         setNeedsStyleRecalc();
1139 }
1140
1141 // Returns true is the given attribute is an event handler.
1142 // We consider an event handler any attribute that begins with "on".
1143 // It is a simple solution that has the advantage of not requiring any
1144 // code or configuration change if a new event handler is defined.
1145
1146 static inline bool isEventHandlerAttribute(const Attribute& attribute)
1147 {
1148     return attribute.name().namespaceURI().isNull() && attribute.name().localName().startsWith("on");
1149 }
1150
1151 bool Element::isJavaScriptURLAttribute(const Attribute& attribute) const
1152 {
1153     return isURLAttribute(attribute) && protocolIsJavaScript(stripLeadingAndTrailingHTMLSpaces(attribute.value()));
1154 }
1155
1156 void Element::stripScriptingAttributes(Vector<Attribute>& attributeVector) const
1157 {
1158     size_t destination = 0;
1159     for (size_t source = 0; source < attributeVector.size(); ++source) {
1160         if (isEventHandlerAttribute(attributeVector[source])
1161             || isJavaScriptURLAttribute(attributeVector[source])
1162             || isHTMLContentAttribute(attributeVector[source]))
1163             continue;
1164
1165         if (source != destination)
1166             attributeVector[destination] = attributeVector[source];
1167
1168         ++destination;
1169     }
1170     attributeVector.shrink(destination);
1171 }
1172
1173 void Element::parserSetAttributes(const Vector<Attribute>& attributeVector)
1174 {
1175     ASSERT(!inDocument());
1176     ASSERT(!parentNode());
1177     ASSERT(!m_elementData);
1178
1179     if (attributeVector.isEmpty())
1180         return;
1181
1182     if (document().sharedObjectPool())
1183         m_elementData = document().sharedObjectPool()->cachedShareableElementDataWithAttributes(attributeVector);
1184     else
1185         m_elementData = ShareableElementData::createWithAttributes(attributeVector);
1186
1187     // Use attributeVector instead of m_elementData because attributeChanged might modify m_elementData.
1188     for (unsigned i = 0; i < attributeVector.size(); ++i)
1189         attributeChangedFromParserOrByCloning(attributeVector[i].name(), attributeVector[i].value(), ModifiedDirectly);
1190 }
1191
1192 bool Element::hasAttributes() const
1193 {
1194     synchronizeAllAttributes();
1195     return elementData() && elementData()->length();
1196 }
1197
1198 bool Element::hasEquivalentAttributes(const Element* other) const
1199 {
1200     synchronizeAllAttributes();
1201     other->synchronizeAllAttributes();
1202     if (elementData() == other->elementData())
1203         return true;
1204     if (elementData())
1205         return elementData()->isEquivalent(other->elementData());
1206     if (other->elementData())
1207         return other->elementData()->isEquivalent(elementData());
1208     return true;
1209 }
1210
1211 String Element::nodeName() const
1212 {
1213     return m_tagName.toString();
1214 }
1215
1216 String Element::nodeNamePreservingCase() const
1217 {
1218     return m_tagName.toString();
1219 }
1220
1221 void Element::setPrefix(const AtomicString& prefix, ExceptionCode& ec)
1222 {
1223     ec = 0;
1224     checkSetPrefix(prefix, ec);
1225     if (ec)
1226         return;
1227
1228     m_tagName.setPrefix(prefix.isEmpty() ? AtomicString() : prefix);
1229 }
1230
1231 KURL Element::baseURI() const
1232 {
1233     const AtomicString& baseAttribute = getAttribute(baseAttr);
1234     KURL base(KURL(), baseAttribute);
1235     if (!base.protocol().isEmpty())
1236         return base;
1237
1238     ContainerNode* parent = parentNode();
1239     if (!parent)
1240         return base;
1241
1242     const KURL& parentBase = parent->baseURI();
1243     if (parentBase.isNull())
1244         return base;
1245
1246     return KURL(parentBase, baseAttribute);
1247 }
1248
1249 const AtomicString& Element::imageSourceURL() const
1250 {
1251     return getAttribute(srcAttr);
1252 }
1253
1254 bool Element::rendererIsNeeded(const RenderStyle& style)
1255 {
1256     return style.display() != NONE;
1257 }
1258
1259 RenderObject* Element::createRenderer(RenderArena*, RenderStyle* style)
1260 {
1261     return RenderObject::createObject(this, style);
1262 }
1263
1264 Node::InsertionNotificationRequest Element::insertedInto(ContainerNode* insertionPoint)
1265 {
1266     bool wasInDocument = inDocument();
1267     // need to do superclass processing first so inDocument() is true
1268     // by the time we reach updateId
1269     ContainerNode::insertedInto(insertionPoint);
1270     ASSERT(!wasInDocument || inDocument());
1271
1272 #if ENABLE(FULLSCREEN_API)
1273     if (containsFullScreenElement() && parentElement() && !parentElement()->containsFullScreenElement())
1274         setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(true);
1275 #endif
1276
1277     if (!insertionPoint->isInTreeScope())
1278         return InsertionDone;
1279
1280     if (hasRareData())
1281         elementRareData()->clearClassListValueForQuirksMode();
1282
1283     TreeScope* newScope = insertionPoint->treeScope();
1284     HTMLDocument* newDocument = !wasInDocument && inDocument() && newScope->documentScope()->isHTMLDocument() ? toHTMLDocument(newScope->documentScope()) : 0;
1285     if (newScope != treeScope())
1286         newScope = 0;
1287
1288     const AtomicString& idValue = getIdAttribute();
1289     if (!idValue.isNull()) {
1290         if (newScope)
1291             updateIdForTreeScope(newScope, nullAtom, idValue);
1292         if (newDocument)
1293             updateIdForDocument(newDocument, nullAtom, idValue, AlwaysUpdateHTMLDocumentNamedItemMaps);
1294     }
1295
1296     const AtomicString& nameValue = getNameAttribute();
1297     if (!nameValue.isNull()) {
1298         if (newScope)
1299             updateNameForTreeScope(newScope, nullAtom, nameValue);
1300         if (newDocument)
1301             updateNameForDocument(newDocument, nullAtom, nameValue);
1302     }
1303
1304     if (newScope && hasTagName(labelTag)) {
1305         if (newScope->shouldCacheLabelsByForAttribute())
1306             updateLabel(newScope, nullAtom, fastGetAttribute(forAttr));
1307     }
1308
1309     return InsertionDone;
1310 }
1311
1312 void Element::removedFrom(ContainerNode* insertionPoint)
1313 {
1314 #if ENABLE(FULLSCREEN_API)
1315     if (containsFullScreenElement())
1316         setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false);
1317 #endif
1318 #if ENABLE(POINTER_LOCK)
1319     if (document().page())
1320         document().page()->pointerLockController()->elementRemoved(this);
1321 #endif
1322
1323     setSavedLayerScrollOffset(IntSize());
1324
1325     if (insertionPoint->isInTreeScope()) {
1326         TreeScope* oldScope = insertionPoint->treeScope();
1327         HTMLDocument* oldDocument = inDocument() && oldScope->documentScope()->isHTMLDocument() ? toHTMLDocument(oldScope->documentScope()) : 0;
1328         if (oldScope != treeScope())
1329             oldScope = 0;
1330
1331         const AtomicString& idValue = getIdAttribute();
1332         if (!idValue.isNull()) {
1333             if (oldScope)
1334                 updateIdForTreeScope(oldScope, idValue, nullAtom);
1335             if (oldDocument)
1336                 updateIdForDocument(oldDocument, idValue, nullAtom, AlwaysUpdateHTMLDocumentNamedItemMaps);
1337         }
1338
1339         const AtomicString& nameValue = getNameAttribute();
1340         if (!nameValue.isNull()) {
1341             if (oldScope)
1342                 updateNameForTreeScope(oldScope, nameValue, nullAtom);
1343             if (oldDocument)
1344                 updateNameForDocument(oldDocument, nameValue, nullAtom);
1345         }
1346
1347         if (oldScope && hasTagName(labelTag)) {
1348             if (oldScope->shouldCacheLabelsByForAttribute())
1349                 updateLabel(oldScope, fastGetAttribute(forAttr), nullAtom);
1350         }
1351     }
1352
1353     ContainerNode::removedFrom(insertionPoint);
1354 #if ENABLE(SVG)
1355     if (hasPendingResources())
1356         document().accessSVGExtensions()->removeElementFromPendingResources(this);
1357 #endif
1358 }
1359
1360 void Element::unregisterNamedFlowContentNode()
1361 {
1362     if (document().cssRegionsEnabled() && inNamedFlow() && document().renderView())
1363         document().renderView()->flowThreadController().unregisterNamedFlowContentNode(this);
1364 }
1365
1366 void Element::lazyReattach(ShouldSetAttached shouldSetAttached)
1367 {
1368     if (attached())
1369         Style::detachRenderTreeInReattachMode(this);
1370     lazyAttach(shouldSetAttached);
1371 }
1372
1373 void Element::lazyAttach(ShouldSetAttached shouldSetAttached)
1374 {
1375     for (Node* node = this; node; node = NodeTraversal::next(node, this)) {
1376         if (!node->isTextNode() && !node->isElementNode())
1377             continue;
1378         if (node->hasChildNodes())
1379             node->setChildNeedsStyleRecalc();
1380         if (node->isElementNode())
1381             toElement(node)->setStyleChange(FullStyleChange);
1382         if (shouldSetAttached == SetAttached)
1383             node->setAttached(true);
1384     }
1385     markAncestorsWithChildNeedsStyleRecalc();
1386 }
1387
1388 PassRefPtr<RenderStyle> Element::styleForRenderer()
1389 {
1390     if (hasCustomStyleResolveCallbacks()) {
1391         if (RefPtr<RenderStyle> style = customStyleForRenderer())
1392             return style.release();
1393     }
1394
1395     return document().ensureStyleResolver().styleForElement(this);
1396 }
1397
1398 ShadowRoot* Element::shadowRoot() const
1399 {
1400     return hasRareData() ? elementRareData()->shadowRoot() : 0;
1401 }
1402
1403 void Element::didAffectSelector(AffectedSelectorMask)
1404 {
1405     setNeedsStyleRecalc();
1406 }
1407
1408 void Element::addShadowRoot(PassRefPtr<ShadowRoot> newShadowRoot)
1409 {
1410     ASSERT(!shadowRoot());
1411
1412     ShadowRoot* shadowRoot = newShadowRoot.get();
1413     ensureElementRareData().setShadowRoot(newShadowRoot);
1414
1415     shadowRoot->setHostElement(this);
1416     shadowRoot->setParentTreeScope(treeScope());
1417     shadowRoot->distributor().didShadowBoundaryChange(this);
1418
1419     ChildNodeInsertionNotifier(this).notify(shadowRoot);
1420
1421     // Existence of shadow roots requires the host and its children to do traversal using ComposedShadowTreeWalker.
1422     setNeedsShadowTreeWalker();
1423
1424     // FIXME(94905): ShadowHost should be reattached during recalcStyle.
1425     // Set some flag here and recreate shadow hosts' renderer in
1426     // Element::recalcStyle.
1427     if (attached())
1428         lazyReattach();
1429
1430     InspectorInstrumentation::didPushShadowRoot(this, shadowRoot);
1431 }
1432
1433 void Element::removeShadowRoot()
1434 {
1435     RefPtr<ShadowRoot> oldRoot = shadowRoot();
1436     if (!oldRoot)
1437         return;
1438     InspectorInstrumentation::willPopShadowRoot(this, oldRoot.get());
1439     document().removeFocusedNodeOfSubtree(oldRoot.get());
1440
1441     ASSERT(!oldRoot->attached());
1442
1443     elementRareData()->clearShadowRoot();
1444
1445     oldRoot->setHostElement(0);
1446     oldRoot->setParentTreeScope(&document());
1447
1448     ChildNodeRemovalNotifier(this).notify(oldRoot.get());
1449
1450     oldRoot->distributor().invalidateDistribution(this);
1451 }
1452
1453 PassRefPtr<ShadowRoot> Element::createShadowRoot(ExceptionCode& ec)
1454 {
1455     if (alwaysCreateUserAgentShadowRoot())
1456         ensureUserAgentShadowRoot();
1457
1458 #if ENABLE(SHADOW_DOM)
1459     if (RuntimeEnabledFeatures::authorShadowDOMForAnyElementEnabled()) {
1460         addShadowRoot(ShadowRoot::create(document(), ShadowRoot::AuthorShadowRoot));
1461         return shadowRoot();
1462     }
1463 #endif
1464
1465     // Since some elements recreates shadow root dynamically, multiple shadow
1466     // subtrees won't work well in that element. Until they are fixed, we disable
1467     // adding author shadow root for them.
1468     if (!areAuthorShadowsAllowed()) {
1469         ec = HIERARCHY_REQUEST_ERR;
1470         return 0;
1471     }
1472     addShadowRoot(ShadowRoot::create(&document(), ShadowRoot::AuthorShadowRoot));
1473
1474     return shadowRoot();
1475 }
1476
1477 ShadowRoot* Element::authorShadowRoot() const
1478 {
1479     ShadowRoot* shadowRoot = this->shadowRoot();
1480     if (shadowRoot->type() == ShadowRoot::AuthorShadowRoot)
1481         return shadowRoot;
1482     return 0;
1483 }
1484
1485 ShadowRoot* Element::userAgentShadowRoot() const
1486 {
1487     if (ShadowRoot* shadowRoot = this->shadowRoot()) {
1488         ASSERT(shadowRoot->type() == ShadowRoot::UserAgentShadowRoot);
1489         return shadowRoot;
1490     }
1491     return 0;
1492 }
1493
1494 ShadowRoot& Element::ensureUserAgentShadowRoot()
1495 {
1496     ShadowRoot* shadowRoot = userAgentShadowRoot();
1497     if (!shadowRoot) {
1498         addShadowRoot(ShadowRoot::create(&document(), ShadowRoot::UserAgentShadowRoot));
1499         shadowRoot = userAgentShadowRoot();
1500         didAddUserAgentShadowRoot(shadowRoot);
1501     }
1502     return *shadowRoot;
1503 }
1504
1505 const AtomicString& Element::shadowPseudoId() const
1506 {
1507     return pseudo();
1508 }
1509
1510 bool Element::childTypeAllowed(NodeType type) const
1511 {
1512     switch (type) {
1513     case ELEMENT_NODE:
1514     case TEXT_NODE:
1515     case COMMENT_NODE:
1516     case PROCESSING_INSTRUCTION_NODE:
1517     case CDATA_SECTION_NODE:
1518     case ENTITY_REFERENCE_NODE:
1519         return true;
1520     default:
1521         break;
1522     }
1523     return false;
1524 }
1525
1526 static void checkForEmptyStyleChange(Element* element, RenderStyle* style)
1527 {
1528     if (!style && !element->styleAffectedByEmpty())
1529         return;
1530
1531     if (!style || (element->styleAffectedByEmpty() && (!style->emptyState() || element->hasChildNodes())))
1532         element->setNeedsStyleRecalc();
1533 }
1534
1535 static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool finishedParsingCallback,
1536                                         Node* beforeChange, Node* afterChange, int childCountDelta)
1537 {
1538     // :empty selector.
1539     checkForEmptyStyleChange(e, style);
1540     
1541     if (!style || (e->needsStyleRecalc() && e->childrenAffectedByPositionalRules()))
1542         return;
1543
1544     // :first-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
1545     // In the DOM case, we only need to do something if |afterChange| is not 0.
1546     // |afterChange| is 0 in the parser case, so it works out that we'll skip this block.
1547     if (e->childrenAffectedByFirstChildRules() && afterChange) {
1548         // Find our new first child.
1549         Node* newFirstChild = 0;
1550         for (newFirstChild = e->firstChild(); newFirstChild && !newFirstChild->isElementNode(); newFirstChild = newFirstChild->nextSibling()) {};
1551         
1552         // Find the first element node following |afterChange|
1553         Node* firstElementAfterInsertion = 0;
1554         for (firstElementAfterInsertion = afterChange;
1555              firstElementAfterInsertion && !firstElementAfterInsertion->isElementNode();
1556              firstElementAfterInsertion = firstElementAfterInsertion->nextSibling()) {};
1557         
1558         // This is the insert/append case.
1559         if (newFirstChild != firstElementAfterInsertion && firstElementAfterInsertion && firstElementAfterInsertion->attached() &&
1560             firstElementAfterInsertion->renderStyle() && firstElementAfterInsertion->renderStyle()->firstChildState())
1561             firstElementAfterInsertion->setNeedsStyleRecalc();
1562             
1563         // We also have to handle node removal.
1564         if (childCountDelta < 0 && newFirstChild == firstElementAfterInsertion && newFirstChild && (!newFirstChild->renderStyle() || !newFirstChild->renderStyle()->firstChildState()))
1565             newFirstChild->setNeedsStyleRecalc();
1566     }
1567
1568     // :last-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
1569     // In the DOM case, we only need to do something if |afterChange| is not 0.
1570     if (e->childrenAffectedByLastChildRules() && beforeChange) {
1571         // Find our new last child.
1572         Node* newLastChild = 0;
1573         for (newLastChild = e->lastChild(); newLastChild && !newLastChild->isElementNode(); newLastChild = newLastChild->previousSibling()) {};
1574         
1575         // Find the last element node going backwards from |beforeChange|
1576         Node* lastElementBeforeInsertion = 0;
1577         for (lastElementBeforeInsertion = beforeChange;
1578              lastElementBeforeInsertion && !lastElementBeforeInsertion->isElementNode();
1579              lastElementBeforeInsertion = lastElementBeforeInsertion->previousSibling()) {};
1580         
1581         if (newLastChild != lastElementBeforeInsertion && lastElementBeforeInsertion && lastElementBeforeInsertion->attached() &&
1582             lastElementBeforeInsertion->renderStyle() && lastElementBeforeInsertion->renderStyle()->lastChildState())
1583             lastElementBeforeInsertion->setNeedsStyleRecalc();
1584             
1585         // 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
1586         // to match now.
1587         if ((childCountDelta < 0 || finishedParsingCallback) && newLastChild == lastElementBeforeInsertion && newLastChild && (!newLastChild->renderStyle() || !newLastChild->renderStyle()->lastChildState()))
1588             newLastChild->setNeedsStyleRecalc();
1589     }
1590
1591     // The + selector.  We need to invalidate the first element following the insertion point.  It is the only possible element
1592     // that could be affected by this DOM change.
1593     if (e->childrenAffectedByDirectAdjacentRules() && afterChange) {
1594         Node* firstElementAfterInsertion = 0;
1595         for (firstElementAfterInsertion = afterChange;
1596              firstElementAfterInsertion && !firstElementAfterInsertion->isElementNode();
1597              firstElementAfterInsertion = firstElementAfterInsertion->nextSibling()) {};
1598         if (firstElementAfterInsertion && firstElementAfterInsertion->attached())
1599             firstElementAfterInsertion->setNeedsStyleRecalc();
1600     }
1601
1602     // Forward positional selectors include the ~ selector, nth-child, nth-of-type, first-of-type and only-of-type.
1603     // Backward positional selectors include nth-last-child, nth-last-of-type, last-of-type and only-of-type.
1604     // We have to invalidate everything following the insertion point in the forward case, and everything before the insertion point in the
1605     // backward case.
1606     // |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.
1607     // 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
1608     // here.  recalcStyle will then force a walk of the children when it sees that this has happened.
1609     if ((e->childrenAffectedByForwardPositionalRules() && afterChange)
1610         || (e->childrenAffectedByBackwardPositionalRules() && beforeChange))
1611         e->setNeedsStyleRecalc();
1612 }
1613
1614 void Element::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
1615 {
1616     ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
1617     if (changedByParser)
1618         checkForEmptyStyleChange(this, renderStyle());
1619     else
1620         checkForSiblingStyleChanges(this, renderStyle(), false, beforeChange, afterChange, childCountDelta);
1621
1622     if (ShadowRoot* shadowRoot = this->shadowRoot())
1623         shadowRoot->invalidateDistribution();
1624 }
1625
1626 void Element::removeAllEventListeners()
1627 {
1628     ContainerNode::removeAllEventListeners();
1629     if (ShadowRoot* shadowRoot = this->shadowRoot())
1630         shadowRoot->removeAllEventListeners();
1631 }
1632
1633 void Element::beginParsingChildren()
1634 {
1635     clearIsParsingChildrenFinished();
1636     StyleResolver* styleResolver = document().styleResolverIfExists();
1637     if (styleResolver && attached())
1638         styleResolver->pushParentElement(this);
1639 }
1640
1641 void Element::finishParsingChildren()
1642 {
1643     ContainerNode::finishParsingChildren();
1644     setIsParsingChildrenFinished();
1645     checkForSiblingStyleChanges(this, renderStyle(), true, lastChild(), 0, 0);
1646     if (StyleResolver* styleResolver = document().styleResolverIfExists())
1647         styleResolver->popParentElement(this);
1648 }
1649
1650 #ifndef NDEBUG
1651 void Element::formatForDebugger(char* buffer, unsigned length) const
1652 {
1653     StringBuilder result;
1654     String s;
1655
1656     result.append(nodeName());
1657
1658     s = getIdAttribute();
1659     if (s.length() > 0) {
1660         if (result.length() > 0)
1661             result.appendLiteral("; ");
1662         result.appendLiteral("id=");
1663         result.append(s);
1664     }
1665
1666     s = getAttribute(classAttr);
1667     if (s.length() > 0) {
1668         if (result.length() > 0)
1669             result.appendLiteral("; ");
1670         result.appendLiteral("class=");
1671         result.append(s);
1672     }
1673
1674     strncpy(buffer, result.toString().utf8().data(), length - 1);
1675 }
1676 #endif
1677
1678 const Vector<RefPtr<Attr> >& Element::attrNodeList()
1679 {
1680     ASSERT(hasSyntheticAttrChildNodes());
1681     return *attrNodeListForElement(this);
1682 }
1683
1684 PassRefPtr<Attr> Element::setAttributeNode(Attr* attrNode, ExceptionCode& ec)
1685 {
1686     if (!attrNode) {
1687         ec = TYPE_MISMATCH_ERR;
1688         return 0;
1689     }
1690
1691     RefPtr<Attr> oldAttrNode = attrIfExists(attrNode->qualifiedName());
1692     if (oldAttrNode.get() == attrNode)
1693         return attrNode; // This Attr is already attached to the element.
1694
1695     // INUSE_ATTRIBUTE_ERR: Raised if node is an Attr that is already an attribute of another Element object.
1696     // The DOM user must explicitly clone Attr nodes to re-use them in other elements.
1697     if (attrNode->ownerElement()) {
1698         ec = INUSE_ATTRIBUTE_ERR;
1699         return 0;
1700     }
1701
1702     synchronizeAllAttributes();
1703     UniqueElementData& elementData = ensureUniqueElementData();
1704
1705     unsigned index = elementData.findAttributeIndexByNameForAttributeNode(attrNode, shouldIgnoreAttributeCase(this));
1706     if (index != ElementData::attributeNotFound) {
1707         if (oldAttrNode)
1708             detachAttrNodeFromElementWithValue(oldAttrNode.get(), elementData.attributeAt(index).value());
1709         else
1710             oldAttrNode = Attr::create(&document(), attrNode->qualifiedName(), elementData.attributeAt(index).value());
1711     }
1712
1713     setAttributeInternal(index, attrNode->qualifiedName(), attrNode->value(), NotInSynchronizationOfLazyAttribute);
1714
1715     attrNode->attachToElement(this);
1716     treeScope()->adoptIfNeeded(attrNode);
1717     ensureAttrNodeListForElement(this).append(attrNode);
1718
1719     return oldAttrNode.release();
1720 }
1721
1722 PassRefPtr<Attr> Element::setAttributeNodeNS(Attr* attr, ExceptionCode& ec)
1723 {
1724     return setAttributeNode(attr, ec);
1725 }
1726
1727 PassRefPtr<Attr> Element::removeAttributeNode(Attr* attr, ExceptionCode& ec)
1728 {
1729     if (!attr) {
1730         ec = TYPE_MISMATCH_ERR;
1731         return 0;
1732     }
1733     if (attr->ownerElement() != this) {
1734         ec = NOT_FOUND_ERR;
1735         return 0;
1736     }
1737
1738     ASSERT(&document() == &attr->document());
1739
1740     synchronizeAttribute(attr->qualifiedName());
1741
1742     unsigned index = elementData()->findAttributeIndexByNameForAttributeNode(attr);
1743     if (index == ElementData::attributeNotFound) {
1744         ec = NOT_FOUND_ERR;
1745         return 0;
1746     }
1747
1748     RefPtr<Attr> attrNode = attr;
1749     detachAttrNodeFromElementWithValue(attr, elementData()->attributeAt(index).value());
1750     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
1751     return attrNode.release();
1752 }
1753
1754 bool Element::parseAttributeName(QualifiedName& out, const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionCode& ec)
1755 {
1756     String prefix, localName;
1757     if (!Document::parseQualifiedName(qualifiedName, prefix, localName, ec))
1758         return false;
1759     ASSERT(!ec);
1760
1761     QualifiedName qName(prefix, localName, namespaceURI);
1762
1763     if (!Document::hasValidNamespaceForAttributes(qName)) {
1764         ec = NAMESPACE_ERR;
1765         return false;
1766     }
1767
1768     out = qName;
1769     return true;
1770 }
1771
1772 void Element::setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode& ec)
1773 {
1774     QualifiedName parsedName = anyName;
1775     if (!parseAttributeName(parsedName, namespaceURI, qualifiedName, ec))
1776         return;
1777     setAttribute(parsedName, value);
1778 }
1779
1780 void Element::removeAttributeInternal(unsigned index, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
1781 {
1782     ASSERT_WITH_SECURITY_IMPLICATION(index < attributeCount());
1783
1784     UniqueElementData& elementData = ensureUniqueElementData();
1785
1786     QualifiedName name = elementData.attributeAt(index).name();
1787     AtomicString valueBeingRemoved = elementData.attributeAt(index).value();
1788
1789     if (!inSynchronizationOfLazyAttribute) {
1790         if (!valueBeingRemoved.isNull())
1791             willModifyAttribute(name, valueBeingRemoved, nullAtom);
1792     }
1793
1794     if (RefPtr<Attr> attrNode = attrIfExists(name))
1795         detachAttrNodeFromElementWithValue(attrNode.get(), elementData.attributeAt(index).value());
1796
1797     elementData.removeAttribute(index);
1798
1799     if (!inSynchronizationOfLazyAttribute)
1800         didRemoveAttribute(name);
1801 }
1802
1803 void Element::addAttributeInternal(const QualifiedName& name, const AtomicString& value, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
1804 {
1805     if (!inSynchronizationOfLazyAttribute)
1806         willModifyAttribute(name, nullAtom, value);
1807     ensureUniqueElementData().addAttribute(name, value);
1808     if (!inSynchronizationOfLazyAttribute)
1809         didAddAttribute(name, value);
1810 }
1811
1812 void Element::removeAttribute(const AtomicString& name)
1813 {
1814     if (!elementData())
1815         return;
1816
1817     AtomicString localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
1818     unsigned index = elementData()->findAttributeIndexByName(localName, false);
1819     if (index == ElementData::attributeNotFound) {
1820         if (UNLIKELY(localName == styleAttr) && elementData()->m_styleAttributeIsDirty && isStyledElement())
1821             static_cast<StyledElement*>(this)->removeAllInlineStyleProperties();
1822         return;
1823     }
1824
1825     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
1826 }
1827
1828 void Element::removeAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName)
1829 {
1830     removeAttribute(QualifiedName(nullAtom, localName, namespaceURI));
1831 }
1832
1833 PassRefPtr<Attr> Element::getAttributeNode(const AtomicString& localName)
1834 {
1835     if (!elementData())
1836         return 0;
1837     synchronizeAttribute(localName);
1838     const Attribute* attribute = elementData()->findAttributeByName(localName, shouldIgnoreAttributeCase(this));
1839     if (!attribute)
1840         return 0;
1841     return ensureAttr(attribute->name());
1842 }
1843
1844 PassRefPtr<Attr> Element::getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName)
1845 {
1846     if (!elementData())
1847         return 0;
1848     QualifiedName qName(nullAtom, localName, namespaceURI);
1849     synchronizeAttribute(qName);
1850     const Attribute* attribute = elementData()->findAttributeByName(qName);
1851     if (!attribute)
1852         return 0;
1853     return ensureAttr(attribute->name());
1854 }
1855
1856 bool Element::hasAttribute(const AtomicString& localName) const
1857 {
1858     if (!elementData())
1859         return false;
1860     synchronizeAttribute(localName);
1861     return elementData()->findAttributeByName(shouldIgnoreAttributeCase(this) ? localName.lower() : localName, false);
1862 }
1863
1864 bool Element::hasAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const
1865 {
1866     if (!elementData())
1867         return false;
1868     QualifiedName qName(nullAtom, localName, namespaceURI);
1869     synchronizeAttribute(qName);
1870     return elementData()->findAttributeByName(qName);
1871 }
1872
1873 CSSStyleDeclaration *Element::style()
1874 {
1875     return 0;
1876 }
1877
1878 void Element::focus(bool restorePreviousSelection, FocusDirection direction)
1879 {
1880     if (!inDocument())
1881         return;
1882
1883     if (document().focusedElement() == this)
1884         return;
1885
1886     // If the stylesheets have already been loaded we can reliably check isFocusable.
1887     // If not, we continue and set the focused node on the focus controller below so
1888     // that it can be updated soon after attach. 
1889     if (document().haveStylesheetsLoaded()) {
1890         document().updateLayoutIgnorePendingStylesheets();
1891         if (!isFocusable())
1892             return;
1893     }
1894
1895     if (!supportsFocus())
1896         return;
1897
1898     RefPtr<Node> protect;
1899     if (Page* page = document().page()) {
1900         // Focus and change event handlers can cause us to lose our last ref.
1901         // If a focus event handler changes the focus to a different node it
1902         // does not make sense to continue and update appearence.
1903         protect = this;
1904         if (!page->focusController().setFocusedElement(this, document().frame(), direction))
1905             return;
1906     }
1907
1908     // Setting the focused node above might have invalidated the layout due to scripts.
1909     document().updateLayoutIgnorePendingStylesheets();
1910
1911     if (!isFocusable()) {
1912         ensureElementRareData().setNeedsFocusAppearanceUpdateSoonAfterAttach(true);
1913         return;
1914     }
1915         
1916     cancelFocusAppearanceUpdate();
1917     updateFocusAppearance(restorePreviousSelection);
1918 }
1919
1920 void Element::updateFocusAppearanceAfterAttachIfNeeded()
1921 {
1922     if (!hasRareData())
1923         return;
1924     ElementRareData* data = elementRareData();
1925     if (!data->needsFocusAppearanceUpdateSoonAfterAttach())
1926         return;
1927     if (isFocusable() && document().focusedElement() == this)
1928         document().updateFocusAppearanceSoon(false /* don't restore selection */);
1929     data->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
1930 }
1931
1932 void Element::updateFocusAppearance(bool /*restorePreviousSelection*/)
1933 {
1934     if (isRootEditableElement()) {
1935         Frame* frame = document().frame();
1936         if (!frame)
1937             return;
1938         
1939         // When focusing an editable element in an iframe, don't reset the selection if it already contains a selection.
1940         if (this == frame->selection().rootEditableElement())
1941             return;
1942
1943         // FIXME: We should restore the previous selection if there is one.
1944         VisibleSelection newSelection = VisibleSelection(firstPositionInOrBeforeNode(this), DOWNSTREAM);
1945         
1946         if (frame->selection().shouldChangeSelection(newSelection)) {
1947             frame->selection().setSelection(newSelection);
1948             frame->selection().revealSelection();
1949         }
1950     } else if (renderer() && !renderer()->isWidget())
1951         renderer()->scrollRectToVisible(boundingBox());
1952 }
1953
1954 void Element::blur()
1955 {
1956     cancelFocusAppearanceUpdate();
1957     if (treeScope()->focusedElement() == this) {
1958         if (Frame* frame = document().frame())
1959             frame->page()->focusController().setFocusedElement(0, frame);
1960         else
1961             document().setFocusedElement(0);
1962     }
1963 }
1964
1965 void Element::dispatchFocusInEvent(const AtomicString& eventType, PassRefPtr<Element> oldFocusedElement)
1966 {
1967     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
1968     ASSERT(eventType == eventNames().focusinEvent || eventType == eventNames().DOMFocusInEvent);
1969     dispatchScopedEventDispatchMediator(FocusInEventDispatchMediator::create(FocusEvent::create(eventType, true, false, document().defaultView(), 0, oldFocusedElement)));
1970 }
1971
1972 void Element::dispatchFocusOutEvent(const AtomicString& eventType, PassRefPtr<Element> newFocusedElement)
1973 {
1974     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
1975     ASSERT(eventType == eventNames().focusoutEvent || eventType == eventNames().DOMFocusOutEvent);
1976     dispatchScopedEventDispatchMediator(FocusOutEventDispatchMediator::create(FocusEvent::create(eventType, true, false, document().defaultView(), 0, newFocusedElement)));
1977 }
1978
1979 void Element::dispatchFocusEvent(PassRefPtr<Element> oldFocusedElement, FocusDirection)
1980 {
1981     if (document().page())
1982         document().page()->chrome().client().elementDidFocus(this);
1983
1984     RefPtr<FocusEvent> event = FocusEvent::create(eventNames().focusEvent, false, false, document().defaultView(), 0, oldFocusedElement);
1985     EventDispatcher::dispatchEvent(this, FocusEventDispatchMediator::create(event.release()));
1986 }
1987
1988 void Element::dispatchBlurEvent(PassRefPtr<Element> newFocusedElement)
1989 {
1990     if (document().page())
1991         document().page()->chrome().client().elementDidBlur(this);
1992
1993     RefPtr<FocusEvent> event = FocusEvent::create(eventNames().blurEvent, false, false, document().defaultView(), 0, newFocusedElement);
1994     EventDispatcher::dispatchEvent(this, BlurEventDispatchMediator::create(event.release()));
1995 }
1996
1997
1998 String Element::innerText()
1999 {
2000     // We need to update layout, since plainText uses line boxes in the render tree.
2001     document().updateLayoutIgnorePendingStylesheets();
2002
2003     if (!renderer())
2004         return textContent(true);
2005
2006     return plainText(rangeOfContents(const_cast<Element*>(this)).get());
2007 }
2008
2009 String Element::outerText()
2010 {
2011     // Getting outerText is the same as getting innerText, only
2012     // setting is different. You would think this should get the plain
2013     // text for the outer range, but this is wrong, <br> for instance
2014     // would return different values for inner and outer text by such
2015     // a rule, but it doesn't in WinIE, and we want to match that.
2016     return innerText();
2017 }
2018
2019 String Element::title() const
2020 {
2021     return String();
2022 }
2023
2024 const AtomicString& Element::pseudo() const
2025 {
2026     return getAttribute(pseudoAttr);
2027 }
2028
2029 void Element::setPseudo(const AtomicString& value)
2030 {
2031     setAttribute(pseudoAttr, value);
2032 }
2033
2034 LayoutSize Element::minimumSizeForResizing() const
2035 {
2036     return hasRareData() ? elementRareData()->minimumSizeForResizing() : defaultMinimumSizeForResizing();
2037 }
2038
2039 void Element::setMinimumSizeForResizing(const LayoutSize& size)
2040 {
2041     if (!hasRareData() && size == defaultMinimumSizeForResizing())
2042         return;
2043     ensureElementRareData().setMinimumSizeForResizing(size);
2044 }
2045
2046 static PseudoElement* beforeOrAfterPseudoElement(Element* host, PseudoId pseudoElementSpecifier)
2047 {
2048     switch (pseudoElementSpecifier) {
2049     case BEFORE:
2050         return host->beforePseudoElement();
2051     case AFTER:
2052         return host->afterPseudoElement();
2053     default:
2054         return 0;
2055     }
2056 }
2057
2058 RenderStyle* Element::computedStyle(PseudoId pseudoElementSpecifier)
2059 {
2060     if (PseudoElement* pseudoElement = beforeOrAfterPseudoElement(this, pseudoElementSpecifier))
2061         return pseudoElement->computedStyle();
2062
2063     // FIXME: Find and use the renderer from the pseudo element instead of the actual element so that the 'length'
2064     // properties, which are only known by the renderer because it did the layout, will be correct and so that the
2065     // values returned for the ":selection" pseudo-element will be correct.
2066     if (RenderStyle* usedStyle = renderStyle()) {
2067         if (pseudoElementSpecifier) {
2068             RenderStyle* cachedPseudoStyle = usedStyle->getCachedPseudoStyle(pseudoElementSpecifier);
2069             return cachedPseudoStyle ? cachedPseudoStyle : usedStyle;
2070          } else
2071             return usedStyle;
2072     }
2073
2074     if (!attached())
2075         // FIXME: Try to do better than this. Ensure that styleForElement() works for elements that are not in the
2076         // document tree and figure out when to destroy the computed style for such elements.
2077         return 0;
2078
2079     ElementRareData& data = ensureElementRareData();
2080     if (!data.computedStyle())
2081         data.setComputedStyle(document().styleForElementIgnoringPendingStylesheets(this));
2082     return pseudoElementSpecifier ? data.computedStyle()->getCachedPseudoStyle(pseudoElementSpecifier) : data.computedStyle();
2083 }
2084
2085 void Element::setStyleAffectedByEmpty()
2086 {
2087     ensureElementRareData().setStyleAffectedByEmpty(true);
2088 }
2089
2090 void Element::setChildrenAffectedByHover(bool value)
2091 {
2092     if (value || hasRareData())
2093         ensureElementRareData().setChildrenAffectedByHover(value);
2094 }
2095
2096 void Element::setChildrenAffectedByActive(bool value)
2097 {
2098     if (value || hasRareData())
2099         ensureElementRareData().setChildrenAffectedByActive(value);
2100 }
2101
2102 void Element::setChildrenAffectedByDrag(bool value)
2103 {
2104     if (value || hasRareData())
2105         ensureElementRareData().setChildrenAffectedByDrag(value);
2106 }
2107
2108 void Element::setChildrenAffectedByFirstChildRules()
2109 {
2110     ensureElementRareData().setChildrenAffectedByFirstChildRules(true);
2111 }
2112
2113 void Element::setChildrenAffectedByLastChildRules()
2114 {
2115     ensureElementRareData().setChildrenAffectedByLastChildRules(true);
2116 }
2117
2118 void Element::setChildrenAffectedByDirectAdjacentRules()
2119 {
2120     ensureElementRareData().setChildrenAffectedByDirectAdjacentRules(true);
2121 }
2122
2123 void Element::setChildrenAffectedByForwardPositionalRules()
2124 {
2125     ensureElementRareData().setChildrenAffectedByForwardPositionalRules(true);
2126 }
2127
2128 void Element::setChildrenAffectedByBackwardPositionalRules()
2129 {
2130     ensureElementRareData().setChildrenAffectedByBackwardPositionalRules(true);
2131 }
2132
2133 void Element::setChildIndex(unsigned index)
2134 {
2135     ElementRareData& rareData = ensureElementRareData();
2136     if (RenderStyle* style = renderStyle())
2137         style->setUnique();
2138     rareData.setChildIndex(index);
2139 }
2140
2141 bool Element::hasFlagsSetDuringStylingOfChildren() const
2142 {
2143     if (!hasRareData())
2144         return false;
2145     return rareDataChildrenAffectedByHover()
2146         || rareDataChildrenAffectedByActive()
2147         || rareDataChildrenAffectedByDrag()
2148         || rareDataChildrenAffectedByFirstChildRules()
2149         || rareDataChildrenAffectedByLastChildRules()
2150         || rareDataChildrenAffectedByDirectAdjacentRules()
2151         || rareDataChildrenAffectedByForwardPositionalRules()
2152         || rareDataChildrenAffectedByBackwardPositionalRules();
2153 }
2154
2155 bool Element::rareDataStyleAffectedByEmpty() const
2156 {
2157     ASSERT(hasRareData());
2158     return elementRareData()->styleAffectedByEmpty();
2159 }
2160
2161 bool Element::rareDataChildrenAffectedByHover() const
2162 {
2163     ASSERT(hasRareData());
2164     return elementRareData()->childrenAffectedByHover();
2165 }
2166
2167 bool Element::rareDataChildrenAffectedByActive() const
2168 {
2169     ASSERT(hasRareData());
2170     return elementRareData()->childrenAffectedByActive();
2171 }
2172
2173 bool Element::rareDataChildrenAffectedByDrag() const
2174 {
2175     ASSERT(hasRareData());
2176     return elementRareData()->childrenAffectedByDrag();
2177 }
2178
2179 bool Element::rareDataChildrenAffectedByFirstChildRules() const
2180 {
2181     ASSERT(hasRareData());
2182     return elementRareData()->childrenAffectedByFirstChildRules();
2183 }
2184
2185 bool Element::rareDataChildrenAffectedByLastChildRules() const
2186 {
2187     ASSERT(hasRareData());
2188     return elementRareData()->childrenAffectedByLastChildRules();
2189 }
2190
2191 bool Element::rareDataChildrenAffectedByDirectAdjacentRules() const
2192 {
2193     ASSERT(hasRareData());
2194     return elementRareData()->childrenAffectedByDirectAdjacentRules();
2195 }
2196
2197 bool Element::rareDataChildrenAffectedByForwardPositionalRules() const
2198 {
2199     ASSERT(hasRareData());
2200     return elementRareData()->childrenAffectedByForwardPositionalRules();
2201 }
2202
2203 bool Element::rareDataChildrenAffectedByBackwardPositionalRules() const
2204 {
2205     ASSERT(hasRareData());
2206     return elementRareData()->childrenAffectedByBackwardPositionalRules();
2207 }
2208
2209 unsigned Element::rareDataChildIndex() const
2210 {
2211     ASSERT(hasRareData());
2212     return elementRareData()->childIndex();
2213 }
2214
2215 void Element::setIsInCanvasSubtree(bool isInCanvasSubtree)
2216 {
2217     ensureElementRareData().setIsInCanvasSubtree(isInCanvasSubtree);
2218 }
2219
2220 bool Element::isInCanvasSubtree() const
2221 {
2222     return hasRareData() && elementRareData()->isInCanvasSubtree();
2223 }
2224
2225 void Element::setIsInsideRegion(bool value)
2226 {
2227     if (value == isInsideRegion())
2228         return;
2229
2230     ensureElementRareData().setIsInsideRegion(value);
2231 }
2232
2233 bool Element::isInsideRegion() const
2234 {
2235     return hasRareData() ? elementRareData()->isInsideRegion() : false;
2236 }
2237
2238 void Element::setRegionOversetState(RegionOversetState state)
2239 {
2240     ensureElementRareData().setRegionOversetState(state);
2241 }
2242
2243 RegionOversetState Element::regionOversetState() const
2244 {
2245     return hasRareData() ? elementRareData()->regionOversetState() : RegionUndefined;
2246 }
2247
2248 AtomicString Element::computeInheritedLanguage() const
2249 {
2250     const Node* n = this;
2251     AtomicString value;
2252     // The language property is inherited, so we iterate over the parents to find the first language.
2253     do {
2254         if (n->isElementNode()) {
2255             if (const ElementData* elementData = toElement(n)->elementData()) {
2256                 // Spec: xml:lang takes precedence -- http://www.w3.org/TR/xhtml1/#C_7
2257                 if (const Attribute* attribute = elementData->findAttributeByName(XMLNames::langAttr))
2258                     value = attribute->value();
2259                 else if (const Attribute* attribute = elementData->findAttributeByName(HTMLNames::langAttr))
2260                     value = attribute->value();
2261             }
2262         } else if (n->isDocumentNode()) {
2263             // checking the MIME content-language
2264             value = toDocument(n)->contentLanguage();
2265         }
2266
2267         n = n->parentNode();
2268     } while (n && value.isNull());
2269
2270     return value;
2271 }
2272
2273 Locale& Element::locale() const
2274 {
2275     return document().getCachedLocale(computeInheritedLanguage());
2276 }
2277
2278 void Element::cancelFocusAppearanceUpdate()
2279 {
2280     if (hasRareData())
2281         elementRareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
2282     if (document().focusedElement() == this)
2283         document().cancelFocusAppearanceUpdate();
2284 }
2285
2286 void Element::normalizeAttributes()
2287 {
2288     if (!hasAttributes())
2289         return;
2290     for (unsigned i = 0; i < attributeCount(); ++i) {
2291         if (RefPtr<Attr> attr = attrIfExists(attributeAt(i).name()))
2292             attr->normalize();
2293     }
2294 }
2295
2296 bool Element::updateExistingPseudoElement(PseudoElement* existingPseudoElement, Style::Change change)
2297 {
2298     // PseudoElement styles hang off their parent element's style so if we needed
2299     // a style recalc we should Force one on the pseudo.
2300     Style::resolveTree(existingPseudoElement, needsStyleRecalc() ? Style::Force : change);
2301
2302     // FIXME: This is silly.
2303     // Wait until our parent is not displayed or pseudoElementRendererIsNeeded
2304     // is false, otherwise we could continously create and destroy PseudoElements
2305     // when RenderObject::isChildAllowed on our parent returns false for the
2306     // PseudoElement's renderer for each style recalc.
2307     return renderer() && pseudoElementRendererIsNeeded(existingPseudoElement->renderStyle());
2308 }
2309
2310 PassRefPtr<PseudoElement> Element::createPseudoElementIfNeeded(PseudoId pseudoId)
2311 {
2312     if (!document().styleSheetCollection()->usesBeforeAfterRules())
2313         return 0;
2314     if (!renderer() || !renderer()->canHaveGeneratedChildren())
2315         return 0;
2316     if (isPseudoElement())
2317         return 0;
2318     if (!pseudoElementRendererIsNeeded(renderer()->getCachedPseudoStyle(pseudoId)))
2319         return 0;
2320     RefPtr<PseudoElement> pseudoElement = PseudoElement::create(this, pseudoId);
2321     Style::attachRenderTree(pseudoElement.get());
2322     return pseudoElement.release();
2323 }
2324
2325 void Element::updateBeforePseudoElement(Style::Change change)
2326 {
2327     if (PseudoElement* existingPseudoElement = beforePseudoElement()) {
2328         if (!updateExistingPseudoElement(existingPseudoElement, change))
2329             clearBeforePseudoElement();
2330         return;
2331     }
2332     if (RefPtr<PseudoElement> pseudo = createPseudoElementIfNeeded(BEFORE))
2333         setBeforePseudoElement(pseudo.release());
2334 }
2335
2336 void Element::updateAfterPseudoElement(Style::Change change)
2337 {
2338     if (PseudoElement* existingPseudoElement = afterPseudoElement()) {
2339         if (!updateExistingPseudoElement(existingPseudoElement, change))
2340             clearAfterPseudoElement();
2341         return;
2342     }
2343     if (RefPtr<PseudoElement> pseudo = createPseudoElementIfNeeded(AFTER))
2344         setAfterPseudoElement(pseudo.release());
2345 }
2346
2347 PseudoElement* Element::beforePseudoElement() const
2348 {
2349     return hasRareData() ? elementRareData()->beforePseudoElement() : 0;
2350 }
2351
2352 PseudoElement* Element::afterPseudoElement() const
2353 {
2354     return hasRareData() ? elementRareData()->afterPseudoElement() : 0;
2355 }
2356
2357 void Element::setBeforePseudoElement(PassRefPtr<PseudoElement> element)
2358 {
2359     ensureElementRareData().setBeforePseudoElement(element);
2360     resetNeedsShadowTreeWalker();
2361 }
2362
2363 void Element::setAfterPseudoElement(PassRefPtr<PseudoElement> element)
2364 {
2365     ensureElementRareData().setAfterPseudoElement(element);
2366     resetNeedsShadowTreeWalker();
2367 }
2368
2369 static void disconnectPseudoElement(PseudoElement* pseudoElement)
2370 {
2371     if (!pseudoElement)
2372         return;
2373     if (pseudoElement->attached())
2374         Style::detachRenderTree(pseudoElement);
2375     ASSERT(pseudoElement->hostElement());
2376     pseudoElement->clearHostElement();
2377 }
2378
2379 void Element::clearBeforePseudoElement()
2380 {
2381     if (!hasRareData())
2382         return;
2383     disconnectPseudoElement(elementRareData()->beforePseudoElement());
2384     elementRareData()->setBeforePseudoElement(nullptr);
2385 }
2386
2387 void Element::clearAfterPseudoElement()
2388 {
2389     if (!hasRareData())
2390         return;
2391     disconnectPseudoElement(elementRareData()->afterPseudoElement());
2392     elementRareData()->setAfterPseudoElement(nullptr);
2393 }
2394
2395 // ElementTraversal API
2396 Element* Element::firstElementChild() const
2397 {
2398     return ElementTraversal::firstWithin(this);
2399 }
2400
2401 Element* Element::lastElementChild() const
2402 {
2403     return ElementTraversal::lastWithin(this);
2404 }
2405
2406 Element* Element::previousElementSibling() const
2407 {
2408     return ElementTraversal::previousSibling(this);
2409 }
2410
2411 Element* Element::nextElementSibling() const
2412 {
2413     return ElementTraversal::nextSibling(this);
2414 }
2415
2416 unsigned Element::childElementCount() const
2417 {
2418     unsigned count = 0;
2419     Node* n = firstChild();
2420     while (n) {
2421         count += n->isElementNode();
2422         n = n->nextSibling();
2423     }
2424     return count;
2425 }
2426
2427 bool Element::matchesReadOnlyPseudoClass() const
2428 {
2429     return false;
2430 }
2431
2432 bool Element::matchesReadWritePseudoClass() const
2433 {
2434     return false;
2435 }
2436
2437 bool Element::webkitMatchesSelector(const String& selector, ExceptionCode& ec)
2438 {
2439     if (selector.isEmpty()) {
2440         ec = SYNTAX_ERR;
2441         return false;
2442     }
2443
2444     SelectorQuery* selectorQuery = document().selectorQueryCache().add(selector, &document(), ec);
2445     if (!selectorQuery)
2446         return false;
2447     return selectorQuery->matches(this);
2448 }
2449
2450 bool Element::shouldAppearIndeterminate() const
2451 {
2452     return false;
2453 }
2454
2455 DOMTokenList* Element::classList()
2456 {
2457     ElementRareData& data = ensureElementRareData();
2458     if (!data.classList())
2459         data.setClassList(ClassList::create(this));
2460     return data.classList();
2461 }
2462
2463 DOMStringMap* Element::dataset()
2464 {
2465     ElementRareData& data = ensureElementRareData();
2466     if (!data.dataset())
2467         data.setDataset(DatasetDOMStringMap::create(this));
2468     return data.dataset();
2469 }
2470
2471 KURL Element::getURLAttribute(const QualifiedName& name) const
2472 {
2473 #if !ASSERT_DISABLED
2474     if (elementData()) {
2475         if (const Attribute* attribute = findAttributeByName(name))
2476             ASSERT(isURLAttribute(*attribute));
2477     }
2478 #endif
2479     return document().completeURL(stripLeadingAndTrailingHTMLSpaces(getAttribute(name)));
2480 }
2481
2482 KURL Element::getNonEmptyURLAttribute(const QualifiedName& name) const
2483 {
2484 #if !ASSERT_DISABLED
2485     if (elementData()) {
2486         if (const Attribute* attribute = findAttributeByName(name))
2487             ASSERT(isURLAttribute(*attribute));
2488     }
2489 #endif
2490     String value = stripLeadingAndTrailingHTMLSpaces(getAttribute(name));
2491     if (value.isEmpty())
2492         return KURL();
2493     return document().completeURL(value);
2494 }
2495
2496 int Element::getIntegralAttribute(const QualifiedName& attributeName) const
2497 {
2498     return getAttribute(attributeName).string().toInt();
2499 }
2500
2501 void Element::setIntegralAttribute(const QualifiedName& attributeName, int value)
2502 {
2503     // FIXME: Need an AtomicString version of String::number.
2504     setAttribute(attributeName, String::number(value));
2505 }
2506
2507 unsigned Element::getUnsignedIntegralAttribute(const QualifiedName& attributeName) const
2508 {
2509     return getAttribute(attributeName).string().toUInt();
2510 }
2511
2512 void Element::setUnsignedIntegralAttribute(const QualifiedName& attributeName, unsigned value)
2513 {
2514     // FIXME: Need an AtomicString version of String::number.
2515     setAttribute(attributeName, String::number(value));
2516 }
2517
2518 #if ENABLE(INDIE_UI)
2519 void Element::setUIActions(const AtomicString& actions)
2520 {
2521     setAttribute(uiactionsAttr, actions);
2522 }
2523
2524 const AtomicString& Element::UIActions() const
2525 {
2526     return getAttribute(uiactionsAttr);
2527 }
2528 #endif
2529
2530     
2531 #if ENABLE(SVG)
2532 bool Element::childShouldCreateRenderer(const Node* child) const
2533 {
2534     // Only create renderers for SVG elements whose parents are SVG elements, or for proper <svg xmlns="svgNS"> subdocuments.
2535     if (child->isSVGElement())
2536         return child->hasTagName(SVGNames::svgTag) || isSVGElement();
2537
2538     return ContainerNode::childShouldCreateRenderer(child);
2539 }
2540 #endif
2541
2542 #if ENABLE(FULLSCREEN_API)
2543 void Element::webkitRequestFullscreen()
2544 {
2545     document().requestFullScreenForElement(this, ALLOW_KEYBOARD_INPUT, Document::EnforceIFrameAllowFullScreenRequirement);
2546 }
2547
2548 void Element::webkitRequestFullScreen(unsigned short flags)
2549 {
2550     document().requestFullScreenForElement(this, (flags | LEGACY_MOZILLA_REQUEST), Document::EnforceIFrameAllowFullScreenRequirement);
2551 }
2552
2553 bool Element::containsFullScreenElement() const
2554 {
2555     return hasRareData() && elementRareData()->containsFullScreenElement();
2556 }
2557
2558 void Element::setContainsFullScreenElement(bool flag)
2559 {
2560     ensureElementRareData().setContainsFullScreenElement(flag);
2561     setNeedsStyleRecalc(SyntheticStyleChange);
2562 }
2563
2564 static Element* parentCrossingFrameBoundaries(Element* element)
2565 {
2566     ASSERT(element);
2567     return element->parentElement() ? element->parentElement() : element->document().ownerElement();
2568 }
2569
2570 void Element::setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(bool flag)
2571 {
2572     Element* element = this;
2573     while ((element = parentCrossingFrameBoundaries(element)))
2574         element->setContainsFullScreenElement(flag);
2575 }
2576 #endif
2577
2578 #if ENABLE(POINTER_LOCK)
2579 void Element::webkitRequestPointerLock()
2580 {
2581     if (document().page())
2582         document().page()->pointerLockController()->requestPointerLock(this);
2583 }
2584 #endif
2585
2586 SpellcheckAttributeState Element::spellcheckAttributeState() const
2587 {
2588     const AtomicString& value = getAttribute(HTMLNames::spellcheckAttr);
2589     if (value == nullAtom)
2590         return SpellcheckAttributeDefault;
2591     if (equalIgnoringCase(value, "true") || equalIgnoringCase(value, ""))
2592         return SpellcheckAttributeTrue;
2593     if (equalIgnoringCase(value, "false"))
2594         return SpellcheckAttributeFalse;
2595
2596     return SpellcheckAttributeDefault;
2597 }
2598
2599 bool Element::isSpellCheckingEnabled() const
2600 {
2601     for (const Element* element = this; element; element = element->parentOrShadowHostElement()) {
2602         switch (element->spellcheckAttributeState()) {
2603         case SpellcheckAttributeTrue:
2604             return true;
2605         case SpellcheckAttributeFalse:
2606             return false;
2607         case SpellcheckAttributeDefault:
2608             break;
2609         }
2610     }
2611
2612     return true;
2613 }
2614
2615 RenderRegion* Element::renderRegion() const
2616 {
2617     if (renderer() && renderer()->isRenderRegion())
2618         return toRenderRegion(renderer());
2619
2620     return 0;
2621 }
2622
2623 #if ENABLE(CSS_REGIONS)
2624
2625 bool Element::shouldMoveToFlowThread(const RenderStyle& styleToUse) const
2626 {
2627 #if ENABLE(FULLSCREEN_API)
2628     if (document().webkitIsFullScreen() && document().webkitCurrentFullScreenElement() == this)
2629         return false;
2630 #endif
2631
2632     if (isInShadowTree())
2633         return false;
2634
2635     if (styleToUse.flowThread().isEmpty())
2636         return false;
2637
2638     return !isRegisteredWithNamedFlow();
2639 }
2640
2641 const AtomicString& Element::webkitRegionOverset() const
2642 {
2643     document().updateLayoutIgnorePendingStylesheets();
2644
2645     DEFINE_STATIC_LOCAL(AtomicString, undefinedState, ("undefined", AtomicString::ConstructFromLiteral));
2646     if (!document().cssRegionsEnabled() || !renderRegion())
2647         return undefinedState;
2648
2649     switch (renderRegion()->regionOversetState()) {
2650     case RegionFit: {
2651         DEFINE_STATIC_LOCAL(AtomicString, fitState, ("fit", AtomicString::ConstructFromLiteral));
2652         return fitState;
2653     }
2654     case RegionEmpty: {
2655         DEFINE_STATIC_LOCAL(AtomicString, emptyState, ("empty", AtomicString::ConstructFromLiteral));
2656         return emptyState;
2657     }
2658     case RegionOverset: {
2659         DEFINE_STATIC_LOCAL(AtomicString, overflowState, ("overset", AtomicString::ConstructFromLiteral));
2660         return overflowState;
2661     }
2662     case RegionUndefined:
2663         return undefinedState;
2664     }
2665
2666     ASSERT_NOT_REACHED();
2667     return undefinedState;
2668 }
2669
2670 Vector<RefPtr<Range> > Element::webkitGetRegionFlowRanges() const
2671 {
2672     document().updateLayoutIgnorePendingStylesheets();
2673
2674     Vector<RefPtr<Range> > rangeObjects;
2675     if (document().cssRegionsEnabled() && renderer() && renderer()->isRenderRegion()) {
2676         RenderRegion* region = toRenderRegion(renderer());
2677         if (region->isValid())
2678             region->getRanges(rangeObjects);
2679     }
2680
2681     return rangeObjects;
2682 }
2683
2684 #endif
2685
2686 #ifndef NDEBUG
2687 bool Element::fastAttributeLookupAllowed(const QualifiedName& name) const
2688 {
2689     if (name == HTMLNames::styleAttr)
2690         return false;
2691
2692 #if ENABLE(SVG)
2693     if (isSVGElement())
2694         return !static_cast<const SVGElement*>(this)->isAnimatableAttribute(name);
2695 #endif
2696
2697     return true;
2698 }
2699 #endif
2700
2701 #ifdef DUMP_NODE_STATISTICS
2702 bool Element::hasNamedNodeMap() const
2703 {
2704     return hasRareData() && elementRareData()->attributeMap();
2705 }
2706 #endif
2707
2708 inline void Element::updateName(const AtomicString& oldName, const AtomicString& newName)
2709 {
2710     if (!isInTreeScope())
2711         return;
2712
2713     if (oldName == newName)
2714         return;
2715
2716     updateNameForTreeScope(treeScope(), oldName, newName);
2717
2718     if (!inDocument())
2719         return;
2720     if (!document().isHTMLDocument())
2721         return;
2722     updateNameForDocument(toHTMLDocument(&document()), oldName, newName);
2723 }
2724
2725 void Element::updateNameForTreeScope(TreeScope* scope, const AtomicString& oldName, const AtomicString& newName)
2726 {
2727     ASSERT(isInTreeScope());
2728     ASSERT(oldName != newName);
2729
2730     if (!oldName.isEmpty())
2731         scope->removeElementByName(oldName, this);
2732     if (!newName.isEmpty())
2733         scope->addElementByName(newName, this);
2734 }
2735
2736 void Element::updateNameForDocument(HTMLDocument* document, const AtomicString& oldName, const AtomicString& newName)
2737 {
2738     ASSERT(inDocument());
2739     ASSERT(oldName != newName);
2740
2741     if (WindowNameCollection::nodeMatchesIfNameAttributeMatch(this)) {
2742         const AtomicString& id = WindowNameCollection::nodeMatchesIfIdAttributeMatch(this) ? getIdAttribute() : nullAtom;
2743         if (!oldName.isEmpty() && oldName != id)
2744             document->removeWindowNamedItem(oldName, this);
2745         if (!newName.isEmpty() && newName != id)
2746             document->addWindowNamedItem(newName, this);
2747     }
2748
2749     if (DocumentNameCollection::nodeMatchesIfNameAttributeMatch(this)) {
2750         const AtomicString& id = DocumentNameCollection::nodeMatchesIfIdAttributeMatch(this) ? getIdAttribute() : nullAtom;
2751         if (!oldName.isEmpty() && oldName != id)
2752             document->removeDocumentNamedItem(oldName, this);
2753         if (!newName.isEmpty() && newName != id)
2754             document->addDocumentNamedItem(newName, this);
2755     }
2756 }
2757
2758 inline void Element::updateId(const AtomicString& oldId, const AtomicString& newId)
2759 {
2760     if (!isInTreeScope())
2761         return;
2762
2763     if (oldId == newId)
2764         return;
2765
2766     updateIdForTreeScope(treeScope(), oldId, newId);
2767
2768     if (!inDocument())
2769         return;
2770     if (!document().isHTMLDocument())
2771         return;
2772     updateIdForDocument(toHTMLDocument(&document()), oldId, newId, UpdateHTMLDocumentNamedItemMapsOnlyIfDiffersFromNameAttribute);
2773 }
2774
2775 void Element::updateIdForTreeScope(TreeScope* scope, const AtomicString& oldId, const AtomicString& newId)
2776 {
2777     ASSERT(isInTreeScope());
2778     ASSERT(oldId != newId);
2779
2780     if (!oldId.isEmpty())
2781         scope->removeElementById(oldId, this);
2782     if (!newId.isEmpty())
2783         scope->addElementById(newId, this);
2784 }
2785
2786 void Element::updateIdForDocument(HTMLDocument* document, const AtomicString& oldId, const AtomicString& newId, HTMLDocumentNamedItemMapsUpdatingCondition condition)
2787 {
2788     ASSERT(inDocument());
2789     ASSERT(oldId != newId);
2790
2791     if (WindowNameCollection::nodeMatchesIfIdAttributeMatch(this)) {
2792         const AtomicString& name = condition == UpdateHTMLDocumentNamedItemMapsOnlyIfDiffersFromNameAttribute && WindowNameCollection::nodeMatchesIfNameAttributeMatch(this) ? getNameAttribute() : nullAtom;
2793         if (!oldId.isEmpty() && oldId != name)
2794             document->removeWindowNamedItem(oldId, this);
2795         if (!newId.isEmpty() && newId != name)
2796             document->addWindowNamedItem(newId, this);
2797     }
2798
2799     if (DocumentNameCollection::nodeMatchesIfIdAttributeMatch(this)) {
2800         const AtomicString& name = condition == UpdateHTMLDocumentNamedItemMapsOnlyIfDiffersFromNameAttribute && DocumentNameCollection::nodeMatchesIfNameAttributeMatch(this) ? getNameAttribute() : nullAtom;
2801         if (!oldId.isEmpty() && oldId != name)
2802             document->removeDocumentNamedItem(oldId, this);
2803         if (!newId.isEmpty() && newId != name)
2804             document->addDocumentNamedItem(newId, this);
2805     }
2806 }
2807
2808 void Element::updateLabel(TreeScope* scope, const AtomicString& oldForAttributeValue, const AtomicString& newForAttributeValue)
2809 {
2810     ASSERT(hasTagName(labelTag));
2811
2812     if (!inDocument())
2813         return;
2814
2815     if (oldForAttributeValue == newForAttributeValue)
2816         return;
2817
2818     if (!oldForAttributeValue.isEmpty())
2819         scope->removeLabel(oldForAttributeValue, toHTMLLabelElement(this));
2820     if (!newForAttributeValue.isEmpty())
2821         scope->addLabel(newForAttributeValue, toHTMLLabelElement(this));
2822 }
2823
2824 void Element::willModifyAttribute(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue)
2825 {
2826     if (isIdAttributeName(name))
2827         updateId(oldValue, newValue);
2828     else if (name == HTMLNames::nameAttr)
2829         updateName(oldValue, newValue);
2830     else if (name == HTMLNames::forAttr && hasTagName(labelTag)) {
2831         TreeScope* scope = treeScope();
2832         if (scope->shouldCacheLabelsByForAttribute())
2833             updateLabel(scope, oldValue, newValue);
2834     }
2835
2836     if (oldValue != newValue) {
2837         if (attached() && document().styleResolverIfExists() && document().styleResolverIfExists()->hasSelectorForAttribute(name.localName()))
2838             setNeedsStyleRecalc();
2839     }
2840
2841     if (OwnPtr<MutationObserverInterestGroup> recipients = MutationObserverInterestGroup::createForAttributesMutation(this, name))
2842         recipients->enqueueMutationRecord(MutationRecord::createAttributes(this, name, oldValue));
2843
2844 #if ENABLE(INSPECTOR)
2845     InspectorInstrumentation::willModifyDOMAttr(&document(), this, oldValue, newValue);
2846 #endif
2847 }
2848
2849 void Element::didAddAttribute(const QualifiedName& name, const AtomicString& value)
2850 {
2851     attributeChanged(name, value);
2852     InspectorInstrumentation::didModifyDOMAttr(&document(), this, name.localName(), value);
2853     dispatchSubtreeModifiedEvent();
2854 }
2855
2856 void Element::didModifyAttribute(const QualifiedName& name, const AtomicString& value)
2857 {
2858     attributeChanged(name, value);
2859     InspectorInstrumentation::didModifyDOMAttr(&document(), this, name.localName(), value);
2860     // Do not dispatch a DOMSubtreeModified event here; see bug 81141.
2861 }
2862
2863 void Element::didRemoveAttribute(const QualifiedName& name)
2864 {
2865     attributeChanged(name, nullAtom);
2866     InspectorInstrumentation::didRemoveDOMAttr(&document(), this, name.localName());
2867     dispatchSubtreeModifiedEvent();
2868 }
2869
2870 PassRefPtr<HTMLCollection> Element::ensureCachedHTMLCollection(CollectionType type)
2871 {
2872     if (HTMLCollection* collection = cachedHTMLCollection(type))
2873         return collection;
2874
2875     RefPtr<HTMLCollection> collection;
2876     if (type == TableRows) {
2877         ASSERT(hasTagName(tableTag));
2878         return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLTableRowsCollection>(this, type);
2879     } else if (type == SelectOptions) {
2880         ASSERT(hasTagName(selectTag));
2881         return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLOptionsCollection>(this, type);
2882     } else if (type == FormControls) {
2883         ASSERT(hasTagName(formTag) || hasTagName(fieldsetTag));
2884         return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLFormControlsCollection>(this, type);
2885     }
2886     return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLCollection>(this, type);
2887 }
2888
2889 HTMLCollection* Element::cachedHTMLCollection(CollectionType type)
2890 {
2891     return hasRareData() && rareData()->nodeLists() ? rareData()->nodeLists()->cacheWithAtomicName<HTMLCollection>(type) : 0;
2892 }
2893
2894 IntSize Element::savedLayerScrollOffset() const
2895 {
2896     return hasRareData() ? elementRareData()->savedLayerScrollOffset() : IntSize();
2897 }
2898
2899 void Element::setSavedLayerScrollOffset(const IntSize& size)
2900 {
2901     if (size.isZero() && !hasRareData())
2902         return;
2903     ensureElementRareData().setSavedLayerScrollOffset(size);
2904 }
2905
2906 PassRefPtr<Attr> Element::attrIfExists(const QualifiedName& name)
2907 {
2908     if (AttrNodeList* attrNodeList = attrNodeListForElement(this))
2909         return findAttrNodeInList(*attrNodeList, name);
2910     return 0;
2911 }
2912
2913 PassRefPtr<Attr> Element::ensureAttr(const QualifiedName& name)
2914 {
2915     AttrNodeList& attrNodeList = ensureAttrNodeListForElement(this);
2916     RefPtr<Attr> attrNode = findAttrNodeInList(attrNodeList, name);
2917     if (!attrNode) {
2918         attrNode = Attr::create(this, name);
2919         treeScope()->adoptIfNeeded(attrNode.get());
2920         attrNodeList.append(attrNode);
2921     }
2922     return attrNode.release();
2923 }
2924
2925 void Element::detachAttrNodeFromElementWithValue(Attr* attrNode, const AtomicString& value)
2926 {
2927     ASSERT(hasSyntheticAttrChildNodes());
2928     attrNode->detachFromElementWithValue(value);
2929
2930     AttrNodeList* attrNodeList = attrNodeListForElement(this);
2931     for (unsigned i = 0; i < attrNodeList->size(); ++i) {
2932         if (attrNodeList->at(i)->qualifiedName() == attrNode->qualifiedName()) {
2933             attrNodeList->remove(i);
2934             if (attrNodeList->isEmpty())
2935                 removeAttrNodeListForElement(this);
2936             return;
2937         }
2938     }
2939     ASSERT_NOT_REACHED();
2940 }
2941
2942 void Element::detachAllAttrNodesFromElement()
2943 {
2944     AttrNodeList* attrNodeList = attrNodeListForElement(this);
2945     ASSERT(attrNodeList);
2946
2947     for (unsigned i = 0; i < attributeCount(); ++i) {
2948         const Attribute& attribute = attributeAt(i);
2949         if (RefPtr<Attr> attrNode = findAttrNodeInList(*attrNodeList, attribute.name()))
2950             attrNode->detachFromElementWithValue(attribute.value());
2951     }
2952
2953     removeAttrNodeListForElement(this);
2954 }
2955
2956 void Element::resetComputedStyle()
2957 {
2958     if (!hasRareData())
2959         return;
2960     elementRareData()->resetComputedStyle();
2961 }
2962
2963 void Element::clearStyleDerivedDataBeforeDetachingRenderer()
2964 {
2965     unregisterNamedFlowContentNode();
2966     cancelFocusAppearanceUpdate();
2967     clearBeforePseudoElement();
2968     clearAfterPseudoElement();
2969     if (!hasRareData())
2970         return;
2971     ElementRareData* data = elementRareData();
2972     data->setIsInCanvasSubtree(false);
2973     data->resetComputedStyle();
2974     data->resetDynamicRestyleObservations();
2975     data->setIsInsideRegion(false);
2976 }
2977
2978 void Element::clearHoverAndActiveStatusBeforeDetachingRenderer()
2979 {
2980     if (!isUserActionElement())
2981         return;
2982     if (hovered())
2983         document().hoveredElementDidDetach(this);
2984     if (inActiveChain())
2985         document().elementInActiveChainDidDetach(this);
2986     document().userActionElements().didDetach(this);
2987 }
2988
2989 bool Element::willRecalcStyle(Style::Change)
2990 {
2991     ASSERT(hasCustomStyleResolveCallbacks());
2992     return true;
2993 }
2994
2995 void Element::didRecalcStyle(Style::Change)
2996 {
2997     ASSERT(hasCustomStyleResolveCallbacks());
2998 }
2999
3000 void Element::willAttachRenderers()
3001 {
3002     ASSERT(hasCustomStyleResolveCallbacks());
3003 }
3004
3005 void Element::didAttachRenderers()
3006 {
3007     ASSERT(hasCustomStyleResolveCallbacks());
3008 }
3009
3010 void Element::willDetachRenderers()
3011 {
3012     ASSERT(hasCustomStyleResolveCallbacks());
3013 }
3014
3015 void Element::didDetachRenderers()
3016 {
3017     ASSERT(hasCustomStyleResolveCallbacks());
3018 }
3019
3020 PassRefPtr<RenderStyle> Element::customStyleForRenderer()
3021 {
3022     ASSERT(hasCustomStyleResolveCallbacks());
3023     return 0;
3024 }
3025
3026 void Element::cloneAttributesFromElement(const Element& other)
3027 {
3028     if (hasSyntheticAttrChildNodes())
3029         detachAllAttrNodesFromElement();
3030
3031     other.synchronizeAllAttributes();
3032     if (!other.m_elementData) {
3033         m_elementData.clear();
3034         return;
3035     }
3036
3037     // 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.
3038     // Fortunately, those named item maps are only updated when this element is in the document, which should never be the case.
3039     ASSERT(!inDocument());
3040
3041     const AtomicString& oldID = getIdAttribute();
3042     const AtomicString& newID = other.getIdAttribute();
3043
3044     if (!oldID.isNull() || !newID.isNull())
3045         updateId(oldID, newID);
3046
3047     const AtomicString& oldName = getNameAttribute();
3048     const AtomicString& newName = other.getNameAttribute();
3049
3050     if (!oldName.isNull() || !newName.isNull())
3051         updateName(oldName, newName);
3052
3053     // If 'other' has a mutable ElementData, convert it to an immutable one so we can share it between both elements.
3054     // We can only do this if there is no CSSOM wrapper for other's inline style, and there are no presentation attributes.
3055     if (other.m_elementData->isUnique()
3056         && !other.m_elementData->presentationAttributeStyle()
3057         && (!other.m_elementData->inlineStyle() || !other.m_elementData->inlineStyle()->hasCSSOMWrapper()))
3058         const_cast<Element&>(other).m_elementData = static_cast<const UniqueElementData*>(other.m_elementData.get())->makeShareableCopy();
3059
3060     if (!other.m_elementData->isUnique())
3061         m_elementData = other.m_elementData;
3062     else
3063         m_elementData = other.m_elementData->makeUniqueCopy();
3064
3065     for (unsigned i = 0; i < m_elementData->length(); ++i) {
3066         const Attribute& attribute = const_cast<const ElementData*>(m_elementData.get())->attributeAt(i);
3067         attributeChangedFromParserOrByCloning(attribute.name(), attribute.value(), ModifiedByCloning);
3068     }
3069 }
3070
3071 void Element::cloneDataFromElement(const Element& other)
3072 {
3073     cloneAttributesFromElement(other);
3074     copyNonAttributePropertiesFromElement(other);
3075 }
3076
3077 void Element::createUniqueElementData()
3078 {
3079     if (!m_elementData)
3080         m_elementData = UniqueElementData::create();
3081     else {
3082         ASSERT(!m_elementData->isUnique());
3083         m_elementData = static_cast<ShareableElementData*>(m_elementData.get())->makeUniqueCopy();
3084     }
3085 }
3086
3087 #if ENABLE(SVG)
3088 bool Element::hasPendingResources() const
3089 {
3090     return hasRareData() && elementRareData()->hasPendingResources();
3091 }
3092
3093 void Element::setHasPendingResources()
3094 {
3095     ensureElementRareData().setHasPendingResources(true);
3096 }
3097
3098 void Element::clearHasPendingResources()
3099 {
3100     ensureElementRareData().setHasPendingResources(false);
3101 }
3102 #endif
3103
3104 } // namespace WebCore