Remove all uses of PassRefPtr in WebCore/svg
[WebKit-https.git] / Source / WebCore / svg / SVGElement.cpp
1 /*
2  * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
3  * Copyright (C) 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org>
4  * Copyright (C) 2008, 2014 Apple Inc. All rights reserved.
5  * Copyright (C) 2008 Alp Toker <alp@atoker.com>
6  * Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au>
7  * Copyright (C) 2013 Samsung Electronics. All rights reserved.
8  * Copyright (C) 2014 Adobe Systems Incorporated. All rights reserved.
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 "SVGElement.h"
28
29 #include "CSSCursorImageValue.h"
30 #include "CSSParser.h"
31 #include "DOMImplementation.h"
32 #include "Document.h"
33 #include "ElementIterator.h"
34 #include "Event.h"
35 #include "EventNames.h"
36 #include "HTMLElement.h"
37 #include "HTMLNames.h"
38 #include "HTMLParserIdioms.h"
39 #include "RenderObject.h"
40 #include "RenderSVGResource.h"
41 #include "RenderSVGResourceFilter.h"
42 #include "RenderSVGResourceMasker.h"
43 #include "SVGCursorElement.h"
44 #include "SVGDocumentExtensions.h"
45 #include "SVGElementRareData.h"
46 #include "SVGGraphicsElement.h"
47 #include "SVGImageElement.h"
48 #include "SVGNames.h"
49 #include "SVGRenderStyle.h"
50 #include "SVGRenderSupport.h"
51 #include "SVGSVGElement.h"
52 #include "SVGTitleElement.h"
53 #include "SVGUseElement.h"
54 #include "ShadowRoot.h"
55 #include "XLinkNames.h"
56 #include "XMLNames.h"
57 #include <wtf/Assertions.h>
58 #include <wtf/HashMap.h>
59 #include <wtf/NeverDestroyed.h>
60 #include <wtf/StdLibExtras.h>
61 #include <wtf/text/WTFString.h>
62
63
64 namespace WebCore {
65
66 // Animated property definitions
67 DEFINE_ANIMATED_STRING(SVGElement, HTMLNames::classAttr, ClassName, className)
68
69 BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGElement)
70     REGISTER_LOCAL_ANIMATED_PROPERTY(className)
71 END_REGISTER_ANIMATED_PROPERTIES
72
73 static NEVER_INLINE void populateAttributeNameToCSSPropertyIDMap(HashMap<AtomicStringImpl*, CSSPropertyID>& map)
74 {
75     using namespace HTMLNames;
76     using namespace SVGNames;
77
78     // This list should include all base CSS and SVG CSS properties which are exposed as SVG XML attributes.
79     static const QualifiedName* const attributeNames[] = {
80         &alignment_baselineAttr,
81         &baseline_shiftAttr,
82         &buffered_renderingAttr,
83         &clipAttr,
84         &clip_pathAttr,
85         &clip_ruleAttr,
86         &SVGNames::colorAttr,
87         &color_interpolationAttr,
88         &color_interpolation_filtersAttr,
89         &color_profileAttr,
90         &color_renderingAttr,
91         &cursorAttr,
92         &cxAttr,
93         &cyAttr,
94         &SVGNames::directionAttr,
95         &displayAttr,
96         &dominant_baselineAttr,
97         &enable_backgroundAttr,
98         &fillAttr,
99         &fill_opacityAttr,
100         &fill_ruleAttr,
101         &filterAttr,
102         &flood_colorAttr,
103         &flood_opacityAttr,
104         &font_familyAttr,
105         &font_sizeAttr,
106         &font_stretchAttr,
107         &font_styleAttr,
108         &font_variantAttr,
109         &font_weightAttr,
110         &glyph_orientation_horizontalAttr,
111         &glyph_orientation_verticalAttr,
112         &image_renderingAttr,
113         &SVGNames::heightAttr,
114         &kerningAttr,
115         &letter_spacingAttr,
116         &lighting_colorAttr,
117         &marker_endAttr,
118         &marker_midAttr,
119         &marker_startAttr,
120         &maskAttr,
121         &mask_typeAttr,
122         &opacityAttr,
123         &overflowAttr,
124         &paint_orderAttr,
125         &pointer_eventsAttr,
126         &rAttr,
127         &rxAttr,
128         &ryAttr,
129         &shape_renderingAttr,
130         &stop_colorAttr,
131         &stop_opacityAttr,
132         &strokeAttr,
133         &stroke_dasharrayAttr,
134         &stroke_dashoffsetAttr,
135         &stroke_linecapAttr,
136         &stroke_linejoinAttr,
137         &stroke_miterlimitAttr,
138         &stroke_opacityAttr,
139         &stroke_widthAttr,
140         &text_anchorAttr,
141         &text_decorationAttr,
142         &text_renderingAttr,
143         &unicode_bidiAttr,
144         &vector_effectAttr,
145         &visibilityAttr,
146         &SVGNames::widthAttr,
147         &word_spacingAttr,
148         &writing_modeAttr,
149         &xAttr,
150         &yAttr,
151     };
152
153     for (auto& name : attributeNames) {
154         const AtomicString& localName = name->localName();
155         map.add(localName.impl(), cssPropertyID(localName));
156     }
157
158     // FIXME: When CSS supports "transform-origin" this special case can be removed,
159     // and we can add transform_originAttr to the table above instead.
160     map.add(transform_originAttr.localName().impl(), CSSPropertyTransformOrigin);
161 }
162
163 static NEVER_INLINE void populateAttributeNameToAnimatedPropertyTypeMap(HashMap<QualifiedName::QualifiedNameImpl*, AnimatedPropertyType>& map)
164 {
165     using namespace HTMLNames;
166     using namespace SVGNames;
167
168     struct TableEntry {
169         const QualifiedName& attributeName;
170         AnimatedPropertyType type;
171     };
172
173     static const TableEntry table[] = {
174         { alignment_baselineAttr, AnimatedString },
175         { baseline_shiftAttr, AnimatedString },
176         { buffered_renderingAttr, AnimatedString },
177         { clipAttr, AnimatedRect },
178         { clip_pathAttr, AnimatedString },
179         { clip_ruleAttr, AnimatedString },
180         { SVGNames::colorAttr, AnimatedColor },
181         { color_interpolationAttr, AnimatedString },
182         { color_interpolation_filtersAttr, AnimatedString },
183         { color_profileAttr, AnimatedString },
184         { color_renderingAttr, AnimatedString },
185         { cursorAttr, AnimatedString },
186         { displayAttr, AnimatedString },
187         { dominant_baselineAttr, AnimatedString },
188         { fillAttr, AnimatedColor },
189         { fill_opacityAttr, AnimatedNumber },
190         { fill_ruleAttr, AnimatedString },
191         { filterAttr, AnimatedString },
192         { flood_colorAttr, AnimatedColor },
193         { flood_opacityAttr, AnimatedNumber },
194         { font_familyAttr, AnimatedString },
195         { font_sizeAttr, AnimatedLength },
196         { font_stretchAttr, AnimatedString },
197         { font_styleAttr, AnimatedString },
198         { font_variantAttr, AnimatedString },
199         { font_weightAttr, AnimatedString },
200         { image_renderingAttr, AnimatedString },
201         { kerningAttr, AnimatedLength },
202         { letter_spacingAttr, AnimatedLength },
203         { lighting_colorAttr, AnimatedColor },
204         { marker_endAttr, AnimatedString },
205         { marker_midAttr, AnimatedString },
206         { marker_startAttr, AnimatedString },
207         { maskAttr, AnimatedString },
208         { mask_typeAttr, AnimatedString },
209         { opacityAttr, AnimatedNumber },
210         { overflowAttr, AnimatedString },
211         { paint_orderAttr, AnimatedString },
212         { pointer_eventsAttr, AnimatedString },
213         { shape_renderingAttr, AnimatedString },
214         { stop_colorAttr, AnimatedColor },
215         { stop_opacityAttr, AnimatedNumber },
216         { strokeAttr, AnimatedColor },
217         { stroke_dasharrayAttr, AnimatedLengthList },
218         { stroke_dashoffsetAttr, AnimatedLength },
219         { stroke_linecapAttr, AnimatedString },
220         { stroke_linejoinAttr, AnimatedString },
221         { stroke_miterlimitAttr, AnimatedNumber },
222         { stroke_opacityAttr, AnimatedNumber },
223         { stroke_widthAttr, AnimatedLength },
224         { text_anchorAttr, AnimatedString },
225         { text_decorationAttr, AnimatedString },
226         { text_renderingAttr, AnimatedString },
227         { vector_effectAttr, AnimatedString },
228         { visibilityAttr, AnimatedString },
229         { word_spacingAttr, AnimatedLength },
230     };
231
232     for (auto& entry : table)
233         map.add(entry.attributeName.impl(), entry.type);
234 }
235
236 static inline HashMap<QualifiedName::QualifiedNameImpl*, AnimatedPropertyType>& attributeNameToAnimatedPropertyTypeMap()
237 {
238     static NeverDestroyed<HashMap<QualifiedName::QualifiedNameImpl*, AnimatedPropertyType>> map;
239     if (map.get().isEmpty())
240         populateAttributeNameToAnimatedPropertyTypeMap(map);
241     return map;
242 }
243
244 static NEVER_INLINE void populateCSSPropertyWithSVGDOMNameToAnimatedPropertyTypeMap(HashMap<QualifiedName::QualifiedNameImpl*, AnimatedPropertyType>& map)
245 {
246     using namespace HTMLNames;
247     using namespace SVGNames;
248
249     struct TableEntry {
250         const QualifiedName& attributeName;
251         AnimatedPropertyType type;
252     };
253
254     static const TableEntry table[] = {
255         { cxAttr, AnimatedLength },
256         { cyAttr, AnimatedLength },
257         { rAttr, AnimatedLength },
258         { rxAttr, AnimatedLength },
259         { ryAttr, AnimatedLength },
260         { SVGNames::heightAttr, AnimatedLength },
261         { SVGNames::widthAttr, AnimatedLength },
262         { xAttr, AnimatedLength },
263         { yAttr, AnimatedLength },
264     };
265
266     for (auto& entry : table)
267         map.add(entry.attributeName.impl(), entry.type);
268 }
269
270 static inline HashMap<QualifiedName::QualifiedNameImpl*, AnimatedPropertyType>& cssPropertyWithSVGDOMNameToAnimatedPropertyTypeMap()
271 {
272     static NeverDestroyed<HashMap<QualifiedName::QualifiedNameImpl*, AnimatedPropertyType>> map;
273     if (map.get().isEmpty())
274         populateCSSPropertyWithSVGDOMNameToAnimatedPropertyTypeMap(map);
275     return map;
276 }
277
278 SVGElement::SVGElement(const QualifiedName& tagName, Document& document)
279     : StyledElement(tagName, document, CreateSVGElement)
280 {
281     registerAnimatedPropertiesForSVGElement();
282 }
283
284 SVGElement::~SVGElement()
285 {
286     if (m_svgRareData) {
287         for (SVGElement* instance : m_svgRareData->instances())
288             instance->m_svgRareData->setCorrespondingElement(nullptr);
289         if (SVGCursorElement* cursorElement = m_svgRareData->cursorElement())
290             cursorElement->removeClient(this);
291         if (CSSCursorImageValue* cursorImageValue = m_svgRareData->cursorImageValue())
292             cursorImageValue->removeReferencedElement(this);
293         if (SVGElement* correspondingElement = m_svgRareData->correspondingElement())
294             correspondingElement->m_svgRareData->instances().remove(this);
295
296         m_svgRareData = nullptr;
297     }
298     document().accessSVGExtensions().rebuildAllElementReferencesForTarget(*this);
299     document().accessSVGExtensions().removeAllElementReferencesForTarget(this);
300 }
301
302 short SVGElement::tabIndex() const
303 {
304     if (supportsFocus())
305         return Element::tabIndex();
306     return -1;
307 }
308
309 bool SVGElement::willRecalcStyle(Style::Change change)
310 {
311     if (!m_svgRareData || styleChangeType() == SyntheticStyleChange)
312         return true;
313     // If the style changes because of a regular property change (not induced by SMIL animations themselves)
314     // reset the "computed style without SMIL style properties", so the base value change gets reflected.
315     if (change > Style::NoChange || needsStyleRecalc())
316         m_svgRareData->setNeedsOverrideComputedStyleUpdate();
317     return true;
318 }
319
320 SVGElementRareData& SVGElement::ensureSVGRareData()
321 {
322     if (!m_svgRareData)
323         m_svgRareData = std::make_unique<SVGElementRareData>();
324     return *m_svgRareData;
325 }
326
327 bool SVGElement::isOutermostSVGSVGElement() const
328 {
329     if (!is<SVGSVGElement>(*this))
330         return false;
331
332     // If we're living in a shadow tree, we're a <svg> element that got created as replacement
333     // for a <symbol> element or a cloned <svg> element in the referenced tree. In that case
334     // we're always an inner <svg> element.
335     if (isInShadowTree() && parentOrShadowHostElement() && parentOrShadowHostElement()->isSVGElement())
336         return false;
337
338     // Element may not be in the document, pretend we're outermost for viewport(), getCTM(), etc.
339     if (!parentNode())
340         return true;
341
342     // We act like an outermost SVG element, if we're a direct child of a <foreignObject> element.
343     if (parentNode()->hasTagName(SVGNames::foreignObjectTag))
344         return true;
345
346     // This is true whenever this is the outermost SVG, even if there are HTML elements outside it
347     return !parentNode()->isSVGElement();
348 }
349
350 void SVGElement::reportAttributeParsingError(SVGParsingError error, const QualifiedName& name, const AtomicString& value)
351 {
352     if (error == NoError)
353         return;
354
355     String errorString = "<" + tagName() + "> attribute " + name.toString() + "=\"" + value + "\"";
356     SVGDocumentExtensions& extensions = document().accessSVGExtensions();
357
358     if (error == NegativeValueForbiddenError) {
359         extensions.reportError("Invalid negative value for " + errorString);
360         return;
361     }
362
363     if (error == ParsingAttributeFailedError) {
364         extensions.reportError("Invalid value for " + errorString);
365         return;
366     }
367
368     ASSERT_NOT_REACHED();
369 }
370
371 bool SVGElement::isSupported(StringImpl* feature, StringImpl* version) const
372 {
373     return DOMImplementation::hasFeature(feature, version);
374 }
375
376 String SVGElement::xmlbase() const
377 {
378     return fastGetAttribute(XMLNames::baseAttr);
379 }
380
381 void SVGElement::setXmlbase(const String& value, ExceptionCode&)
382 {
383     setAttribute(XMLNames::baseAttr, value);
384 }
385
386 void SVGElement::removedFrom(ContainerNode& rootParent)
387 {
388     bool wasInDocument = rootParent.inDocument();
389     if (wasInDocument)
390         updateRelativeLengthsInformation(false, this);
391
392     StyledElement::removedFrom(rootParent);
393
394     if (wasInDocument) {
395         document().accessSVGExtensions().clearTargetDependencies(*this);
396         document().accessSVGExtensions().removeAllElementReferencesForTarget(this);
397     }
398     invalidateInstances();
399 }
400
401 SVGSVGElement* SVGElement::ownerSVGElement() const
402 {
403     ContainerNode* node = parentOrShadowHostNode();
404     while (node) {
405         if (is<SVGSVGElement>(*node))
406             return downcast<SVGSVGElement>(node);
407
408         node = node->parentOrShadowHostNode();
409     }
410
411     return nullptr;
412 }
413
414 SVGElement* SVGElement::viewportElement() const
415 {
416     // This function needs shadow tree support - as RenderSVGContainer uses this function
417     // to determine the "overflow" property. <use> on <symbol> wouldn't work otherwhise.
418     ContainerNode* node = parentOrShadowHostNode();
419     while (node) {
420         if (is<SVGSVGElement>(*node) || is<SVGImageElement>(*node) || node->hasTagName(SVGNames::symbolTag))
421             return downcast<SVGElement>(node);
422
423         node = node->parentOrShadowHostNode();
424     }
425
426     return nullptr;
427 }
428  
429 const HashSet<SVGElement*>& SVGElement::instances() const
430 {
431     if (!m_svgRareData) {
432         static NeverDestroyed<HashSet<SVGElement*>> emptyInstances;
433         return emptyInstances;
434     }
435     return m_svgRareData->instances();
436 }
437
438 bool SVGElement::getBoundingBox(FloatRect& rect, SVGLocatable::StyleUpdateStrategy styleUpdateStrategy)
439 {
440     if (is<SVGGraphicsElement>(*this)) {
441         rect = downcast<SVGGraphicsElement>(*this).getBBox(styleUpdateStrategy);
442         return true;
443     }
444     return false;
445 }
446
447 void SVGElement::setCursorElement(SVGCursorElement* cursorElement)
448 {
449     SVGElementRareData& rareData = ensureSVGRareData();
450     if (SVGCursorElement* oldCursorElement = rareData.cursorElement()) {
451         if (cursorElement == oldCursorElement)
452             return;
453         oldCursorElement->removeReferencedElement(this);
454     }
455     rareData.setCursorElement(cursorElement);
456 }
457
458 void SVGElement::cursorElementRemoved() 
459 {
460     ASSERT(m_svgRareData);
461     m_svgRareData->setCursorElement(nullptr);
462 }
463
464 void SVGElement::setCursorImageValue(CSSCursorImageValue* cursorImageValue)
465 {
466     SVGElementRareData& rareData = ensureSVGRareData();
467     if (CSSCursorImageValue* oldCursorImageValue = rareData.cursorImageValue()) {
468         if (cursorImageValue == oldCursorImageValue)
469             return;
470         oldCursorImageValue->removeReferencedElement(this);
471     }
472     rareData.setCursorImageValue(cursorImageValue);
473 }
474
475 void SVGElement::cursorImageValueRemoved()
476 {
477     ASSERT(m_svgRareData);
478     m_svgRareData->setCursorImageValue(nullptr);
479 }
480
481 SVGElement* SVGElement::correspondingElement() const
482 {
483     return m_svgRareData ? m_svgRareData->correspondingElement() : nullptr;
484 }
485
486 SVGUseElement* SVGElement::correspondingUseElement() const
487 {
488     auto* root = containingShadowRoot();
489     if (!root)
490         return nullptr;
491     if (root->type() != ShadowRoot::UserAgentShadowRoot)
492         return nullptr;
493     auto* host = root->host();
494     if (!is<SVGUseElement>(host))
495         return nullptr;
496     return &downcast<SVGUseElement>(*host);
497 }
498
499 void SVGElement::setCorrespondingElement(SVGElement* correspondingElement)
500 {
501     if (m_svgRareData) {
502         if (SVGElement* oldCorrespondingElement = m_svgRareData->correspondingElement())
503             oldCorrespondingElement->m_svgRareData->instances().remove(this);
504     }
505     if (m_svgRareData || correspondingElement)
506         ensureSVGRareData().setCorrespondingElement(correspondingElement);
507     if (correspondingElement)
508         correspondingElement->ensureSVGRareData().instances().add(this);
509 }
510
511 void SVGElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
512 {
513     if (name == HTMLNames::classAttr) {
514         setClassNameBaseValue(value);
515         return;
516     }
517
518     if (name == HTMLNames::tabindexAttr) {
519         int tabindex = 0;
520         if (value.isEmpty())
521             clearTabIndexExplicitlyIfNeeded();
522         else if (parseHTMLInteger(value, tabindex)) {
523             // Clamp tabindex to the range of 'short' to match Firefox's behavior.
524             setTabIndexExplicitly(std::max(static_cast<int>(std::numeric_limits<short>::min()), std::min(tabindex, static_cast<int>(std::numeric_limits<short>::max()))));
525         }
526         return;
527     }
528
529     auto& eventName = HTMLElement::eventNameForEventHandlerAttribute(name);
530     if (!eventName.isNull()) {
531         setAttributeEventListener(eventName, name, value);
532         return;
533     }
534
535     SVGLangSpace::parseAttribute(name, value);
536 }
537
538 Vector<AnimatedPropertyType> SVGElement::animatedPropertyTypesForAttribute(const QualifiedName& attributeName)
539 {
540     auto types = localAttributeToPropertyMap().types(attributeName);
541     if (!types.isEmpty())
542         return types;
543
544     {
545         auto& map = attributeNameToAnimatedPropertyTypeMap();
546         auto it = map.find(attributeName.impl());
547         if (it != map.end()) {
548             types.append(it->value);
549             return types;
550         }
551     }
552
553     {
554         auto& map = cssPropertyWithSVGDOMNameToAnimatedPropertyTypeMap();
555         auto it = map.find(attributeName.impl());
556         if (it != map.end()) {
557             types.append(it->value);
558             return types;
559         }
560     }
561
562     return types;
563 }
564
565 bool SVGElement::haveLoadedRequiredResources()
566 {
567     for (auto& child : childrenOfType<SVGElement>(*this)) {
568         if (!child.haveLoadedRequiredResources())
569             return false;
570     }
571     return true;
572 }
573
574 bool SVGElement::addEventListener(const AtomicString& eventType, RefPtr<EventListener>&& listener, bool useCapture)
575 {   
576     // Add event listener to regular DOM element
577     if (!Node::addEventListener(eventType, listener.copyRef(), useCapture))
578         return false;
579
580     if (containingShadowRoot())
581         return true;
582
583     // Add event listener to all shadow tree DOM element instances
584     ASSERT(!instanceUpdatesBlocked());
585     for (auto* instance : instances()) {
586         ASSERT(instance->correspondingElement() == this);
587         bool result = instance->Node::addEventListener(eventType, listener.copyRef(), useCapture);
588         ASSERT_UNUSED(result, result);
589     }
590
591     return true;
592 }
593
594 bool SVGElement::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
595 {
596     if (containingShadowRoot())
597         return Node::removeEventListener(eventType, listener, useCapture);
598
599     // EventTarget::removeEventListener creates a PassRefPtr around the given EventListener
600     // object when creating a temporary RegisteredEventListener object used to look up the
601     // event listener in a cache. If we want to be able to call removeEventListener() multiple
602     // times on different nodes, we have to delay its immediate destruction, which would happen
603     // after the first call below.
604     RefPtr<EventListener> protector(listener);
605
606     // Remove event listener from regular DOM element
607     if (!Node::removeEventListener(eventType, listener, useCapture))
608         return false;
609
610     // Remove event listener from all shadow tree DOM element instances
611     ASSERT(!instanceUpdatesBlocked());
612     for (auto& instance : instances()) {
613         ASSERT(instance->correspondingElement() == this);
614
615         if (instance->Node::removeEventListener(eventType, listener, useCapture))
616             continue;
617
618         // This case can only be hit for event listeners created from markup
619         ASSERT(listener->wasCreatedFromMarkup());
620
621         // If the event listener 'listener' has been created from markup and has been fired before
622         // then JSLazyEventListener::parseCode() has been called and m_jsFunction of that listener
623         // has been created (read: it's not 0 anymore). During shadow tree creation, the event
624         // listener DOM attribute has been cloned, and another event listener has been setup in
625         // the shadow tree. If that event listener has not been used yet, m_jsFunction is still 0,
626         // and tryRemoveEventListener() above will fail. Work around that very rare problem.
627         ASSERT(instance->eventTargetData());
628         instance->eventTargetData()->eventListenerMap.removeFirstEventListenerCreatedFromMarkup(eventType);
629     }
630
631     return true;
632 }
633
634 static bool hasLoadListener(Element* element)
635 {
636     if (element->hasEventListeners(eventNames().loadEvent))
637         return true;
638
639     for (element = element->parentOrShadowHostElement(); element; element = element->parentOrShadowHostElement()) {
640         const EventListenerVector& entry = element->getEventListeners(eventNames().loadEvent);
641         for (auto& listener : entry) {
642             if (listener.useCapture)
643                 return true;
644         }
645     }
646
647     return false;
648 }
649
650 #if ENABLE(CSS_REGIONS)
651 bool SVGElement::shouldMoveToFlowThread(const RenderStyle& styleToUse) const
652 {
653     // Allow only svg root elements to be directly collected by a render flow thread.
654     return parentNode() && !parentNode()->isSVGElement() && hasTagName(SVGNames::svgTag) && Element::shouldMoveToFlowThread(styleToUse);
655 }
656 #endif
657
658 void SVGElement::sendSVGLoadEventIfPossible(bool sendParentLoadEvents)
659 {
660     RefPtr<SVGElement> currentTarget = this;
661     while (currentTarget && currentTarget->haveLoadedRequiredResources()) {
662         RefPtr<Element> parent;
663         if (sendParentLoadEvents)
664             parent = currentTarget->parentOrShadowHostElement(); // save the next parent to dispatch too incase dispatching the event changes the tree
665         if (hasLoadListener(currentTarget.get()))
666             currentTarget->dispatchEvent(Event::create(eventNames().loadEvent, false, false));
667         currentTarget = (parent && parent->isSVGElement()) ? static_pointer_cast<SVGElement>(parent) : RefPtr<SVGElement>();
668         SVGElement* element = currentTarget.get();
669         if (!element || !element->isOutermostSVGSVGElement())
670             continue;
671
672         // Consider <svg onload="foo()"><image xlink:href="foo.png" externalResourcesRequired="true"/></svg>.
673         // If foo.png is not yet loaded, the first SVGLoad event will go to the <svg> element, sent through
674         // Document::implicitClose(). Then the SVGLoad event will fire for <image>, once its loaded.
675         ASSERT(sendParentLoadEvents);
676
677         // If the load event was not sent yet by Document::implicitClose(), but the <image> from the example
678         // above, just appeared, don't send the SVGLoad event to the outermost <svg>, but wait for the document
679         // to be "ready to render", first.
680         if (!document().loadEventFinished())
681             break;
682     }
683 }
684
685 void SVGElement::sendSVGLoadEventIfPossibleAsynchronously()
686 {
687     svgLoadEventTimer()->startOneShot(0);
688 }
689
690 void SVGElement::svgLoadEventTimerFired()
691 {
692     sendSVGLoadEventIfPossible();
693 }
694
695 Timer* SVGElement::svgLoadEventTimer()
696 {
697     ASSERT_NOT_REACHED();
698     return 0;
699 }
700
701 void SVGElement::finishParsingChildren()
702 {
703     StyledElement::finishParsingChildren();
704
705     // The outermost SVGSVGElement SVGLoad event is fired through Document::dispatchWindowLoadEvent.
706     if (isOutermostSVGSVGElement())
707         return;
708
709     // finishParsingChildren() is called when the close tag is reached for an element (e.g. </svg>)
710     // we send SVGLoad events here if we can, otherwise they'll be sent when any required loads finish
711     sendSVGLoadEventIfPossible();
712
713     // Notify all the elements which have references to this element to rebuild their shadow and render
714     // trees, e.g. a <use> element references a target element before this target element is defined.
715     invalidateInstances();
716 }
717
718 bool SVGElement::childShouldCreateRenderer(const Node& child) const
719 {
720     static NeverDestroyed<HashSet<QualifiedName>> invalidTextContent;
721
722     if (invalidTextContent.get().isEmpty()) {
723         invalidTextContent.get().add(SVGNames::textPathTag);
724 #if ENABLE(SVG_FONTS)
725         invalidTextContent.get().add(SVGNames::altGlyphTag);
726 #endif
727         invalidTextContent.get().add(SVGNames::trefTag);
728         invalidTextContent.get().add(SVGNames::tspanTag);
729     }
730     if (child.isSVGElement()) {
731         const SVGElement& svgChild = downcast<SVGElement>(child);
732         if (invalidTextContent.get().contains(svgChild.tagQName()))
733             return false;
734
735         return svgChild.isValid();
736     }
737     return false;
738 }
739
740 void SVGElement::attributeChanged(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue, AttributeModificationReason)
741 {
742     StyledElement::attributeChanged(name, oldValue, newValue);
743
744     if (name == HTMLNames::idAttr)
745         document().accessSVGExtensions().rebuildAllElementReferencesForTarget(*this);
746
747     // Changes to the style attribute are processed lazily (see Element::getAttribute() and related methods),
748     // so we don't want changes to the style attribute to result in extra work here.
749     if (name != HTMLNames::styleAttr)
750         svgAttributeChanged(name);
751 }
752
753 void SVGElement::synchronizeAllAnimatedSVGAttribute(SVGElement* svgElement)
754 {
755     ASSERT(svgElement->elementData());
756     ASSERT(svgElement->elementData()->animatedSVGAttributesAreDirty());
757
758     svgElement->localAttributeToPropertyMap().synchronizeProperties(*svgElement);
759     svgElement->elementData()->setAnimatedSVGAttributesAreDirty(false);
760 }
761
762 void SVGElement::synchronizeAnimatedSVGAttribute(const QualifiedName& name) const
763 {
764     if (!elementData() || !elementData()->animatedSVGAttributesAreDirty())
765         return;
766
767     SVGElement* nonConstThis = const_cast<SVGElement*>(this);
768     if (name == anyQName())
769         synchronizeAllAnimatedSVGAttribute(nonConstThis);
770     else
771         nonConstThis->localAttributeToPropertyMap().synchronizeProperty(*nonConstThis, name);
772 }
773
774 void SVGElement::synchronizeRequiredFeatures(SVGElement* contextElement)
775 {
776     ASSERT(contextElement);
777     contextElement->synchronizeRequiredFeatures();
778 }
779
780 void SVGElement::synchronizeRequiredExtensions(SVGElement* contextElement)
781 {
782     ASSERT(contextElement);
783     contextElement->synchronizeRequiredExtensions();
784 }
785
786 void SVGElement::synchronizeSystemLanguage(SVGElement* contextElement)
787 {
788     ASSERT(contextElement);
789     contextElement->synchronizeSystemLanguage();
790 }
791
792 RefPtr<RenderStyle> SVGElement::customStyleForRenderer(RenderStyle& parentStyle)
793 {
794     if (!correspondingElement())
795         return document().ensureStyleResolver().styleForElement(this, &parentStyle);
796
797     return document().ensureStyleResolver().styleForElement(correspondingElement(), &parentStyle, DisallowStyleSharing);
798 }
799
800 MutableStyleProperties* SVGElement::animatedSMILStyleProperties() const
801 {
802     if (m_svgRareData)
803         return m_svgRareData->animatedSMILStyleProperties();
804     return 0;
805 }
806
807 MutableStyleProperties& SVGElement::ensureAnimatedSMILStyleProperties()
808 {
809     return ensureSVGRareData().ensureAnimatedSMILStyleProperties();
810 }
811
812 void SVGElement::setUseOverrideComputedStyle(bool value)
813 {
814     if (m_svgRareData)
815         m_svgRareData->setUseOverrideComputedStyle(value);
816 }
817
818 RenderStyle* SVGElement::computedStyle(PseudoId pseudoElementSpecifier)
819 {
820     if (!m_svgRareData || !m_svgRareData->useOverrideComputedStyle())
821         return Element::computedStyle(pseudoElementSpecifier);
822
823     RenderStyle* parentStyle = nullptr;
824     if (Element* parent = parentOrShadowHostElement()) {
825         if (auto renderer = parent->renderer())
826             parentStyle = &renderer->style();
827     }
828
829     return m_svgRareData->overrideComputedStyle(this, parentStyle);
830 }
831
832 static void addQualifiedName(HashMap<AtomicString, QualifiedName>& map, const QualifiedName& name)
833 {
834     HashMap<AtomicString, QualifiedName>::AddResult addResult = map.add(name.localName(), name);
835     ASSERT_UNUSED(addResult, addResult.isNewEntry);
836 }
837
838 QualifiedName SVGElement::animatableAttributeForName(const AtomicString& localName)
839 {
840     static NeverDestroyed<HashMap<AtomicString, QualifiedName>> neverDestroyedAnimatableAttributes;
841     HashMap<AtomicString, QualifiedName>& animatableAttributes = neverDestroyedAnimatableAttributes;
842
843     if (animatableAttributes.isEmpty()) {
844         addQualifiedName(animatableAttributes, HTMLNames::classAttr);
845         addQualifiedName(animatableAttributes, SVGNames::amplitudeAttr);
846         addQualifiedName(animatableAttributes, SVGNames::azimuthAttr);
847         addQualifiedName(animatableAttributes, SVGNames::baseFrequencyAttr);
848         addQualifiedName(animatableAttributes, SVGNames::biasAttr);
849         addQualifiedName(animatableAttributes, SVGNames::clipPathUnitsAttr);
850         addQualifiedName(animatableAttributes, SVGNames::cxAttr);
851         addQualifiedName(animatableAttributes, SVGNames::cyAttr);
852         addQualifiedName(animatableAttributes, SVGNames::diffuseConstantAttr);
853         addQualifiedName(animatableAttributes, SVGNames::divisorAttr);
854         addQualifiedName(animatableAttributes, SVGNames::dxAttr);
855         addQualifiedName(animatableAttributes, SVGNames::dyAttr);
856         addQualifiedName(animatableAttributes, SVGNames::edgeModeAttr);
857         addQualifiedName(animatableAttributes, SVGNames::elevationAttr);
858         addQualifiedName(animatableAttributes, SVGNames::exponentAttr);
859         addQualifiedName(animatableAttributes, SVGNames::externalResourcesRequiredAttr);
860         addQualifiedName(animatableAttributes, SVGNames::filterResAttr);
861         addQualifiedName(animatableAttributes, SVGNames::filterUnitsAttr);
862         addQualifiedName(animatableAttributes, SVGNames::fxAttr);
863         addQualifiedName(animatableAttributes, SVGNames::fyAttr);
864         addQualifiedName(animatableAttributes, SVGNames::gradientTransformAttr);
865         addQualifiedName(animatableAttributes, SVGNames::gradientUnitsAttr);
866         addQualifiedName(animatableAttributes, SVGNames::heightAttr);
867         addQualifiedName(animatableAttributes, SVGNames::in2Attr);
868         addQualifiedName(animatableAttributes, SVGNames::inAttr);
869         addQualifiedName(animatableAttributes, SVGNames::interceptAttr);
870         addQualifiedName(animatableAttributes, SVGNames::k1Attr);
871         addQualifiedName(animatableAttributes, SVGNames::k2Attr);
872         addQualifiedName(animatableAttributes, SVGNames::k3Attr);
873         addQualifiedName(animatableAttributes, SVGNames::k4Attr);
874         addQualifiedName(animatableAttributes, SVGNames::kernelMatrixAttr);
875         addQualifiedName(animatableAttributes, SVGNames::kernelUnitLengthAttr);
876         addQualifiedName(animatableAttributes, SVGNames::lengthAdjustAttr);
877         addQualifiedName(animatableAttributes, SVGNames::limitingConeAngleAttr);
878         addQualifiedName(animatableAttributes, SVGNames::markerHeightAttr);
879         addQualifiedName(animatableAttributes, SVGNames::markerUnitsAttr);
880         addQualifiedName(animatableAttributes, SVGNames::markerWidthAttr);
881         addQualifiedName(animatableAttributes, SVGNames::maskContentUnitsAttr);
882         addQualifiedName(animatableAttributes, SVGNames::maskUnitsAttr);
883         addQualifiedName(animatableAttributes, SVGNames::methodAttr);
884         addQualifiedName(animatableAttributes, SVGNames::modeAttr);
885         addQualifiedName(animatableAttributes, SVGNames::numOctavesAttr);
886         addQualifiedName(animatableAttributes, SVGNames::offsetAttr);
887         addQualifiedName(animatableAttributes, SVGNames::operatorAttr);
888         addQualifiedName(animatableAttributes, SVGNames::orderAttr);
889         addQualifiedName(animatableAttributes, SVGNames::orientAttr);
890         addQualifiedName(animatableAttributes, SVGNames::pathLengthAttr);
891         addQualifiedName(animatableAttributes, SVGNames::patternContentUnitsAttr);
892         addQualifiedName(animatableAttributes, SVGNames::patternTransformAttr);
893         addQualifiedName(animatableAttributes, SVGNames::patternUnitsAttr);
894         addQualifiedName(animatableAttributes, SVGNames::pointsAtXAttr);
895         addQualifiedName(animatableAttributes, SVGNames::pointsAtYAttr);
896         addQualifiedName(animatableAttributes, SVGNames::pointsAtZAttr);
897         addQualifiedName(animatableAttributes, SVGNames::preserveAlphaAttr);
898         addQualifiedName(animatableAttributes, SVGNames::preserveAspectRatioAttr);
899         addQualifiedName(animatableAttributes, SVGNames::primitiveUnitsAttr);
900         addQualifiedName(animatableAttributes, SVGNames::radiusAttr);
901         addQualifiedName(animatableAttributes, SVGNames::rAttr);
902         addQualifiedName(animatableAttributes, SVGNames::refXAttr);
903         addQualifiedName(animatableAttributes, SVGNames::refYAttr);
904         addQualifiedName(animatableAttributes, SVGNames::resultAttr);
905         addQualifiedName(animatableAttributes, SVGNames::rotateAttr);
906         addQualifiedName(animatableAttributes, SVGNames::rxAttr);
907         addQualifiedName(animatableAttributes, SVGNames::ryAttr);
908         addQualifiedName(animatableAttributes, SVGNames::scaleAttr);
909         addQualifiedName(animatableAttributes, SVGNames::seedAttr);
910         addQualifiedName(animatableAttributes, SVGNames::slopeAttr);
911         addQualifiedName(animatableAttributes, SVGNames::spacingAttr);
912         addQualifiedName(animatableAttributes, SVGNames::specularConstantAttr);
913         addQualifiedName(animatableAttributes, SVGNames::specularExponentAttr);
914         addQualifiedName(animatableAttributes, SVGNames::spreadMethodAttr);
915         addQualifiedName(animatableAttributes, SVGNames::startOffsetAttr);
916         addQualifiedName(animatableAttributes, SVGNames::stdDeviationAttr);
917         addQualifiedName(animatableAttributes, SVGNames::stitchTilesAttr);
918         addQualifiedName(animatableAttributes, SVGNames::surfaceScaleAttr);
919         addQualifiedName(animatableAttributes, SVGNames::tableValuesAttr);
920         addQualifiedName(animatableAttributes, SVGNames::targetAttr);
921         addQualifiedName(animatableAttributes, SVGNames::targetXAttr);
922         addQualifiedName(animatableAttributes, SVGNames::targetYAttr);
923         addQualifiedName(animatableAttributes, SVGNames::transformAttr);
924         addQualifiedName(animatableAttributes, SVGNames::typeAttr);
925         addQualifiedName(animatableAttributes, SVGNames::valuesAttr);
926         addQualifiedName(animatableAttributes, SVGNames::viewBoxAttr);
927         addQualifiedName(animatableAttributes, SVGNames::widthAttr);
928         addQualifiedName(animatableAttributes, SVGNames::x1Attr);
929         addQualifiedName(animatableAttributes, SVGNames::x2Attr);
930         addQualifiedName(animatableAttributes, SVGNames::xAttr);
931         addQualifiedName(animatableAttributes, SVGNames::xChannelSelectorAttr);
932         addQualifiedName(animatableAttributes, SVGNames::y1Attr);
933         addQualifiedName(animatableAttributes, SVGNames::y2Attr);
934         addQualifiedName(animatableAttributes, SVGNames::yAttr);
935         addQualifiedName(animatableAttributes, SVGNames::yChannelSelectorAttr);
936         addQualifiedName(animatableAttributes, SVGNames::zAttr);
937         addQualifiedName(animatableAttributes, XLinkNames::hrefAttr);
938     }
939     return animatableAttributes.get(localName);
940 }
941
942 #ifndef NDEBUG
943 bool SVGElement::isAnimatableAttribute(const QualifiedName& name) const
944 {
945     if (SVGElement::animatableAttributeForName(name.localName()) == name)
946         return !filterOutAnimatableAttribute(name);
947     return false;
948 }
949
950 bool SVGElement::filterOutAnimatableAttribute(const QualifiedName&) const
951 {
952     return false;
953 }
954 #endif
955
956 String SVGElement::title() const
957 {
958     // According to spec, for stand-alone SVG documents we should not return a title when
959     // hovering over the rootmost SVG element (the first <title> element is the title of
960     // the document, not a tooltip) so we instantly return.
961     if (isOutermostSVGSVGElement() && document().topDocument().isSVGDocument())
962         return String();
963     auto firstTitle = childrenOfType<SVGTitleElement>(*this).first();
964     return firstTitle ? const_cast<SVGTitleElement*>(firstTitle)->innerText() : String();
965 }
966
967 bool SVGElement::rendererIsNeeded(const RenderStyle& style)
968 {
969     // http://www.w3.org/TR/SVG/extend.html#PrivateData
970     // Prevent anything other than SVG renderers from appearing in our render tree
971     // Spec: SVG allows inclusion of elements from foreign namespaces anywhere
972     // with the SVG content. In general, the SVG user agent will include the unknown
973     // elements in the DOM but will otherwise ignore unknown elements.
974     if (!parentOrShadowHostElement() || parentOrShadowHostElement()->isSVGElement())
975         return StyledElement::rendererIsNeeded(style);
976
977     return false;
978 }
979
980 CSSPropertyID SVGElement::cssPropertyIdForSVGAttributeName(const QualifiedName& attrName)
981 {
982     if (!attrName.namespaceURI().isNull())
983         return CSSPropertyInvalid;
984
985     static NeverDestroyed<HashMap<AtomicStringImpl*, CSSPropertyID>> properties;
986     if (properties.get().isEmpty())
987         populateAttributeNameToCSSPropertyIDMap(properties.get());
988
989     return properties.get().get(attrName.localName().impl());
990 }
991
992 bool SVGElement::isAnimatableCSSProperty(const QualifiedName& attributeName)
993 {
994     return attributeNameToAnimatedPropertyTypeMap().contains(attributeName.impl())
995         || cssPropertyWithSVGDOMNameToAnimatedPropertyTypeMap().contains(attributeName.impl());
996 }
997
998 bool SVGElement::isPresentationAttributeWithSVGDOM(const QualifiedName& attributeName)
999 {
1000     return !localAttributeToPropertyMap().types(attributeName).isEmpty();
1001 }
1002
1003 bool SVGElement::isPresentationAttribute(const QualifiedName& name) const
1004 {
1005     if (cssPropertyIdForSVGAttributeName(name) > 0)
1006         return true;
1007     return StyledElement::isPresentationAttribute(name);
1008 }
1009
1010 void SVGElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStyleProperties& style)
1011 {
1012     CSSPropertyID propertyID = cssPropertyIdForSVGAttributeName(name);
1013     if (propertyID > 0)
1014         addPropertyToPresentationAttributeStyle(style, propertyID, value);
1015 }
1016
1017 bool SVGElement::isKnownAttribute(const QualifiedName& attrName)
1018 {
1019     return attrName == HTMLNames::idAttr;
1020 }
1021
1022 void SVGElement::svgAttributeChanged(const QualifiedName& attrName)
1023 {
1024     CSSPropertyID propId = cssPropertyIdForSVGAttributeName(attrName);
1025     if (propId > 0) {
1026         invalidateInstances();
1027         return;
1028     }
1029
1030     if (attrName == HTMLNames::classAttr) {
1031         classAttributeChanged(className());
1032         invalidateInstances();
1033         return;
1034     }
1035
1036     if (attrName == HTMLNames::idAttr) {
1037         auto renderer = this->renderer();
1038         // Notify resources about id changes, this is important as we cache resources by id in SVGDocumentExtensions
1039         if (is<RenderSVGResourceContainer>(renderer))
1040             downcast<RenderSVGResourceContainer>(*renderer).idChanged();
1041         if (inDocument())
1042             buildPendingResourcesIfNeeded();
1043         invalidateInstances();
1044         return;
1045     }
1046 }
1047
1048 Node::InsertionNotificationRequest SVGElement::insertedInto(ContainerNode& rootParent)
1049 {
1050     StyledElement::insertedInto(rootParent);
1051     updateRelativeLengthsInformation();
1052     buildPendingResourcesIfNeeded();
1053     return InsertionDone;
1054 }
1055
1056 void SVGElement::buildPendingResourcesIfNeeded()
1057 {
1058     if (!needsPendingResourceHandling() || !inDocument() || isInShadowTree())
1059         return;
1060
1061     SVGDocumentExtensions& extensions = document().accessSVGExtensions();
1062     String resourceId = getIdAttribute();
1063     if (!extensions.isIdOfPendingResource(resourceId))
1064         return;
1065
1066     // Mark pending resources as pending for removal.
1067     extensions.markPendingResourcesForRemoval(resourceId);
1068
1069     // Rebuild pending resources for each client of a pending resource that is being removed.
1070     while (Element* clientElement = extensions.removeElementFromPendingResourcesForRemovalMap(resourceId)) {
1071         ASSERT(clientElement->hasPendingResources());
1072         if (clientElement->hasPendingResources()) {
1073             clientElement->buildPendingResource();
1074             extensions.clearHasPendingResourcesIfPossible(clientElement);
1075         }
1076     }
1077 }
1078
1079 void SVGElement::childrenChanged(const ChildChange& change)
1080 {
1081     StyledElement::childrenChanged(change);
1082
1083     if (change.source == ChildChangeSourceParser)
1084         return;
1085     invalidateInstances();
1086 }
1087
1088 RefPtr<CSSValue> SVGElement::getPresentationAttribute(const String& name)
1089 {
1090     if (!hasAttributesWithoutUpdate())
1091         return 0;
1092
1093     QualifiedName attributeName(nullAtom, name, nullAtom);
1094     const Attribute* attribute = findAttributeByName(attributeName);
1095     if (!attribute)
1096         return 0;
1097
1098     RefPtr<MutableStyleProperties> style = MutableStyleProperties::create(SVGAttributeMode);
1099     CSSPropertyID propertyID = cssPropertyIdForSVGAttributeName(attribute->name());
1100     style->setProperty(propertyID, attribute->value());
1101     RefPtr<CSSValue> cssValue = style->getPropertyCSSValue(propertyID);
1102     return cssValue ? cssValue->cloneForCSSOM() : nullptr;
1103 }
1104
1105 bool SVGElement::instanceUpdatesBlocked() const
1106 {
1107     return m_svgRareData && m_svgRareData->instanceUpdatesBlocked();
1108 }
1109
1110 void SVGElement::setInstanceUpdatesBlocked(bool value)
1111 {
1112     // Catch any callers that calls setInstanceUpdatesBlocked(true) twice in a row.
1113     // That probably indicates nested use of InstanceUpdateBlocker and a bug.
1114     ASSERT(!value || !instanceUpdatesBlocked());
1115
1116     if (m_svgRareData)
1117         m_svgRareData->setInstanceUpdatesBlocked(value);
1118 }
1119
1120 AffineTransform SVGElement::localCoordinateSpaceTransform(SVGLocatable::CTMScope) const
1121 {
1122     // To be overriden by SVGGraphicsElement (or as special case SVGTextElement and SVGPatternElement)
1123     return AffineTransform();
1124 }
1125
1126 void SVGElement::updateRelativeLengthsInformation(bool hasRelativeLengths, SVGElement* element)
1127 {
1128     // If we're not yet in a document, this function will be called again from insertedInto(). Do nothing now.
1129     if (!inDocument())
1130         return;
1131
1132     // An element wants to notify us that its own relative lengths state changed.
1133     // Register it in the relative length map, and register us in the parent relative length map.
1134     // Register the parent in the grandparents map, etc. Repeat procedure until the root of the SVG tree.
1135
1136     if (hasRelativeLengths)
1137         m_elementsWithRelativeLengths.add(element);
1138     else {
1139         if (!m_elementsWithRelativeLengths.contains(element)) {
1140             // We were never registered. Do nothing.
1141             return;
1142         }
1143
1144         m_elementsWithRelativeLengths.remove(element);
1145     }
1146
1147     if (!element->isSVGGraphicsElement())
1148         return;
1149
1150     // Find first styled parent node, and notify it that we've changed our relative length state.
1151     ContainerNode* node = parentNode();
1152     while (node) {
1153         if (!node->isSVGElement())
1154             break;
1155
1156         // Register us in the parent element map.
1157         downcast<SVGElement>(*node).updateRelativeLengthsInformation(hasRelativeLengths, this);
1158         break;
1159     }
1160 }
1161
1162 bool SVGElement::hasFocusEventListeners() const
1163 {
1164     Element* eventTarget = const_cast<SVGElement*>(this);
1165     return eventTarget->hasEventListeners(eventNames().focusinEvent)
1166         || eventTarget->hasEventListeners(eventNames().focusoutEvent)
1167         || eventTarget->hasEventListeners(eventNames().focusEvent)
1168         || eventTarget->hasEventListeners(eventNames().blurEvent);
1169 }
1170
1171 bool SVGElement::isMouseFocusable() const
1172 {
1173     if (!isFocusable())
1174         return false;
1175     Element* eventTarget = const_cast<SVGElement*>(this);
1176     return hasFocusEventListeners()
1177         || eventTarget->hasEventListeners(eventNames().keydownEvent)
1178         || eventTarget->hasEventListeners(eventNames().keyupEvent)
1179         || eventTarget->hasEventListeners(eventNames().keypressEvent);
1180 }
1181     
1182 void SVGElement::accessKeyAction(bool sendMouseEvents)
1183 {
1184     dispatchSimulatedClick(0, sendMouseEvents ? SendMouseUpDownEvents : SendNoEvents);
1185 }
1186
1187 void SVGElement::invalidateInstances()
1188 {
1189     if (instanceUpdatesBlocked())
1190         return;
1191
1192     auto& instances = this->instances();
1193     while (!instances.isEmpty()) {
1194         SVGElement* instance = *instances.begin();
1195         if (SVGUseElement* useElement = instance->correspondingUseElement())
1196             useElement->invalidateShadowTree();
1197         instance->setCorrespondingElement(nullptr);
1198     } while (!instances.isEmpty());
1199 }
1200
1201 }