Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Side by Side Diff: third_party/WebKit/Source/core/svg/SVGUseElement.cpp

Issue 2744613002: Use IdTargetObserver in SVGUseElement (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/core/svg/SVGUseElement.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann
3 * <zimmermann@kde.org> 3 * <zimmermann@kde.org>
4 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> 4 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
5 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. 5 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
6 * Copyright (C) 2011 Torch Mobile (Beijing) Co. Ltd. All rights reserved. 6 * Copyright (C) 2011 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
7 * Copyright (C) 2012 University of Szeged 7 * Copyright (C) 2012 University of Szeged
8 * Copyright (C) 2012 Renata Hodovan <reni@webkit.org> 8 * Copyright (C) 2012 Renata Hodovan <reni@webkit.org>
9 * 9 *
10 * This library is free software; you can redistribute it and/or 10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Library General Public 11 * modify it under the terms of the GNU Library General Public
12 * License as published by the Free Software Foundation; either 12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version. 13 * version 2 of the License, or (at your option) any later version.
14 * 14 *
15 * This library is distributed in the hope that it will be useful, 15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Library General Public License for more details. 18 * Library General Public License for more details.
19 * 19 *
20 * You should have received a copy of the GNU Library General Public License 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 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, 22 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301, USA. 23 * Boston, MA 02110-1301, USA.
24 */ 24 */
25 25
26 #include "core/svg/SVGUseElement.h" 26 #include "core/svg/SVGUseElement.h"
27 27
28 #include "bindings/core/v8/ExceptionState.h"
29 #include "core/SVGNames.h" 28 #include "core/SVGNames.h"
30 #include "core/XLinkNames.h" 29 #include "core/XLinkNames.h"
31 #include "core/dom/Document.h" 30 #include "core/dom/Document.h"
32 #include "core/dom/ElementTraversal.h" 31 #include "core/dom/ElementTraversal.h"
32 #include "core/dom/IdTargetObserver.h"
33 #include "core/dom/StyleChangeReason.h" 33 #include "core/dom/StyleChangeReason.h"
34 #include "core/dom/TaskRunnerHelper.h" 34 #include "core/dom/TaskRunnerHelper.h"
35 #include "core/dom/shadow/ElementShadow.h"
36 #include "core/dom/shadow/ShadowRoot.h" 35 #include "core/dom/shadow/ShadowRoot.h"
37 #include "core/events/Event.h" 36 #include "core/events/Event.h"
38 #include "core/layout/svg/LayoutSVGTransformableContainer.h" 37 #include "core/layout/svg/LayoutSVGTransformableContainer.h"
39 #include "core/svg/SVGGElement.h" 38 #include "core/svg/SVGGElement.h"
40 #include "core/svg/SVGLengthContext.h" 39 #include "core/svg/SVGLengthContext.h"
41 #include "core/svg/SVGSVGElement.h" 40 #include "core/svg/SVGSVGElement.h"
42 #include "core/svg/SVGSymbolElement.h" 41 #include "core/svg/SVGSymbolElement.h"
43 #include "core/svg/SVGTitleElement.h" 42 #include "core/svg/SVGTitleElement.h"
44 #include "core/svg/SVGTreeScopeResources.h"
45 #include "core/xml/parser/XMLDocumentParser.h" 43 #include "core/xml/parser/XMLDocumentParser.h"
46 #include "platform/loader/fetch/FetchRequest.h" 44 #include "platform/loader/fetch/FetchRequest.h"
47 #include "platform/loader/fetch/ResourceFetcher.h" 45 #include "platform/loader/fetch/ResourceFetcher.h"
48 #include "wtf/Vector.h" 46 #include "wtf/Vector.h"
49 47
50 namespace blink { 48 namespace blink {
51 49
52 inline SVGUseElement::SVGUseElement(Document& document) 50 inline SVGUseElement::SVGUseElement(Document& document)
53 : SVGGraphicsElement(SVGNames::useTag, document), 51 : SVGGraphicsElement(SVGNames::useTag, document),
54 SVGURIReference(this), 52 SVGURIReference(this),
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 void SVGUseElement::dispose() { 89 void SVGUseElement::dispose() {
92 setDocumentResource(nullptr); 90 setDocumentResource(nullptr);
93 } 91 }
94 92
95 DEFINE_TRACE(SVGUseElement) { 93 DEFINE_TRACE(SVGUseElement) {
96 visitor->trace(m_x); 94 visitor->trace(m_x);
97 visitor->trace(m_y); 95 visitor->trace(m_y);
98 visitor->trace(m_width); 96 visitor->trace(m_width);
99 visitor->trace(m_height); 97 visitor->trace(m_height);
100 visitor->trace(m_targetElementInstance); 98 visitor->trace(m_targetElementInstance);
99 visitor->trace(m_targetIdObserver);
101 visitor->trace(m_resource); 100 visitor->trace(m_resource);
102 SVGGraphicsElement::trace(visitor); 101 SVGGraphicsElement::trace(visitor);
103 SVGURIReference::trace(visitor); 102 SVGURIReference::trace(visitor);
104 DocumentResourceClient::trace(visitor); 103 DocumentResourceClient::trace(visitor);
105 } 104 }
106 105
107 #if DCHECK_IS_ON() 106 #if DCHECK_IS_ON()
108 static inline bool isWellFormedDocument(Document* document) { 107 static inline bool isWellFormedDocument(Document* document) {
109 if (document->isXMLDocument()) 108 if (document->isXMLDocument())
110 return static_cast<XMLDocumentParser*>(document->parser())->wellFormed(); 109 return static_cast<XMLDocumentParser*>(document->parser())->wellFormed();
(...skipping 10 matching lines...) Expand all
121 return InsertionDone; 120 return InsertionDone;
122 ASSERT(!m_targetElementInstance || !isWellFormedDocument(&document())); 121 ASSERT(!m_targetElementInstance || !isWellFormedDocument(&document()));
123 ASSERT(!hasPendingResources() || !isWellFormedDocument(&document())); 122 ASSERT(!hasPendingResources() || !isWellFormedDocument(&document()));
124 invalidateShadowTree(); 123 invalidateShadowTree();
125 return InsertionDone; 124 return InsertionDone;
126 } 125 }
127 126
128 void SVGUseElement::removedFrom(ContainerNode* rootParent) { 127 void SVGUseElement::removedFrom(ContainerNode* rootParent) {
129 SVGGraphicsElement::removedFrom(rootParent); 128 SVGGraphicsElement::removedFrom(rootParent);
130 if (rootParent->isConnected()) { 129 if (rootParent->isConnected()) {
131 clearInstanceRoot(); 130 clearResourceReference();
132 removeAllOutgoingReferences();
133 cancelShadowTreeRecreation(); 131 cancelShadowTreeRecreation();
134 } 132 }
135 } 133 }
136 134
137 static void transferUseWidthAndHeightIfNeeded( 135 static void transferUseWidthAndHeightIfNeeded(
138 const SVGUseElement& use, 136 const SVGUseElement& use,
139 SVGElement& shadowElement, 137 SVGElement& shadowElement,
140 const SVGElement& originalElement) { 138 const SVGElement& originalElement) {
141 DEFINE_STATIC_LOCAL(const AtomicString, hundredPercentString, ("100%")); 139 DEFINE_STATIC_LOCAL(const AtomicString, hundredPercentString, ("100%"));
142 // Use |originalElement| for checking the element type, because we will 140 // Use |originalElement| for checking the element type, because we will
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 m_needsShadowTreeRecreation = true; 278 m_needsShadowTreeRecreation = true;
281 document().scheduleUseShadowTreeUpdate(*this); 279 document().scheduleUseShadowTreeUpdate(*this);
282 } 280 }
283 281
284 void SVGUseElement::cancelShadowTreeRecreation() { 282 void SVGUseElement::cancelShadowTreeRecreation() {
285 m_needsShadowTreeRecreation = false; 283 m_needsShadowTreeRecreation = false;
286 document().unscheduleUseShadowTreeUpdate(*this); 284 document().unscheduleUseShadowTreeUpdate(*this);
287 } 285 }
288 286
289 void SVGUseElement::clearInstanceRoot() { 287 void SVGUseElement::clearInstanceRoot() {
290 if (m_targetElementInstance) 288 m_targetElementInstance = nullptr;
291 m_targetElementInstance = nullptr;
292 } 289 }
293 290
294 void SVGUseElement::clearShadowTree() { 291 void SVGUseElement::clearResourceReference() {
292 unobserveTarget(m_targetIdObserver);
295 clearInstanceRoot(); 293 clearInstanceRoot();
296
297 // FIXME: We should try to optimize this, to at least allow partial reclones.
298 if (ShadowRoot* shadowTreeRootElement = userAgentShadowRoot())
299 shadowTreeRootElement->removeChildren(OmitSubtreeModifiedEvent);
300
301 removeAllOutgoingReferences(); 294 removeAllOutgoingReferences();
302 } 295 }
303 296
304 Element* SVGUseElement::resolveTargetElement() { 297 Element* SVGUseElement::resolveTargetElement() {
305 if (m_elementIdentifier.isEmpty()) 298 if (m_elementIdentifier.isEmpty())
306 return nullptr; 299 return nullptr;
307 const TreeScope* lookupScope = nullptr; 300 if (m_elementIdentifierIsLocal) {
308 if (m_elementIdentifierIsLocal) 301 return observeTarget(m_targetIdObserver, treeScope(), m_elementIdentifier,
309 lookupScope = &treeScope(); 302 WTF::bind(&SVGUseElement::invalidateShadowTree,
310 else if (resourceIsValid()) 303 wrapWeakPersistent(this)));
311 lookupScope = m_resource->document(); 304 }
312 else 305 if (!resourceIsValid())
313 return nullptr; 306 return nullptr;
314 Element* target = lookupScope->getElementById(m_elementIdentifier); 307 return m_resource->document()->getElementById(m_elementIdentifier);
315 // TODO(fs): Why would the Element not be "connected" at this point?
316 if (target && target->isConnected())
317 return target;
318 // Don't record any pending references for external resources.
319 if (!m_resource) {
320 treeScope().ensureSVGTreeScopedResources().addPendingResource(
321 m_elementIdentifier, *this);
322 DCHECK(hasPendingResources());
323 }
324 return nullptr;
325 } 308 }
326 309
327 void SVGUseElement::buildPendingResource() { 310 void SVGUseElement::buildPendingResource() {
328 if (inUseShadowTree()) 311 if (inUseShadowTree())
329 return; 312 return;
330 clearShadowTree(); 313 // FIXME: We should try to optimize this, to at least allow partial reclones.
314 userAgentShadowRoot()->removeChildren(OmitSubtreeModifiedEvent);
315 clearResourceReference();
331 cancelShadowTreeRecreation(); 316 cancelShadowTreeRecreation();
332 if (!isConnected()) 317 if (!isConnected())
333 return; 318 return;
334 Element* target = resolveTargetElement(); 319 Element* target = resolveTargetElement();
335 if (target && target->isSVGElement()) { 320 // TODO(fs): Why would the Element not be "connected" at this point?
321 if (target && target->isConnected() && target->isSVGElement()) {
336 buildShadowAndInstanceTree(toSVGElement(*target)); 322 buildShadowAndInstanceTree(toSVGElement(*target));
337 invalidateDependentShadowTrees(); 323 invalidateDependentShadowTrees();
338 } 324 }
339 325
340 ASSERT(!m_needsShadowTreeRecreation); 326 ASSERT(!m_needsShadowTreeRecreation);
341 } 327 }
342 328
343 String SVGUseElement::title() const { 329 String SVGUseElement::title() const {
344 // Find the first <title> child in <use> which doesn't cover shadow tree. 330 // Find the first <title> child in <use> which doesn't cover shadow tree.
345 if (Element* titleElement = Traversal<SVGTitleElement>::firstChild(*this)) 331 if (Element* titleElement = Traversal<SVGTitleElement>::firstChild(*this))
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 return; 442 return;
457 443
458 // Assure shadow tree building was successful. 444 // Assure shadow tree building was successful.
459 ASSERT(m_targetElementInstance); 445 ASSERT(m_targetElementInstance);
460 ASSERT(m_targetElementInstance->correspondingUseElement() == this); 446 ASSERT(m_targetElementInstance->correspondingUseElement() == this);
461 ASSERT(m_targetElementInstance->correspondingElement() == &target); 447 ASSERT(m_targetElementInstance->correspondingElement() == &target);
462 448
463 // Expand all <use> elements in the shadow tree. 449 // Expand all <use> elements in the shadow tree.
464 // Expand means: replace the actual <use> element by what it references. 450 // Expand means: replace the actual <use> element by what it references.
465 if (!expandUseElementsInShadowTree()) { 451 if (!expandUseElementsInShadowTree()) {
466 clearShadowTree(); 452 shadowTreeRootElement->removeChildren(OmitSubtreeModifiedEvent);
453 clearResourceReference();
467 return; 454 return;
468 } 455 }
469 456
470 // If the instance root was a <use>, it could have been replaced now, so 457 // If the instance root was a <use>, it could have been replaced now, so
471 // reset |m_targetElementInstance|. 458 // reset |m_targetElementInstance|.
472 m_targetElementInstance = 459 m_targetElementInstance =
473 toSVGElementOrDie(shadowTreeRootElement->firstChild()); 460 toSVGElementOrDie(shadowTreeRootElement->firstChild());
474 ASSERT(m_targetElementInstance->parentNode() == shadowTreeRootElement); 461 ASSERT(m_targetElementInstance->parentNode() == shadowTreeRootElement);
475 462
476 // Update relative length information. 463 // Update relative length information.
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 728
742 if (m_resource) 729 if (m_resource)
743 m_resource->removeClient(this); 730 m_resource->removeClient(this);
744 731
745 m_resource = resource; 732 m_resource = resource;
746 if (m_resource) 733 if (m_resource)
747 m_resource->addClient(this); 734 m_resource->addClient(this);
748 } 735 }
749 736
750 } // namespace blink 737 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/svg/SVGUseElement.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698