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