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