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