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

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

Issue 216463003: Allow <use> inside author shadow roots (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Remove loop in isInUserAgentShadowTree, add a title test Created 6 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « 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 <zimmermann@kde .org> 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde .org>
3 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> 3 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
4 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. 4 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
5 * Copyright (C) 2011 Torch Mobile (Beijing) Co. Ltd. All rights reserved. 5 * Copyright (C) 2011 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
6 * Copyright (C) 2012 University of Szeged 6 * Copyright (C) 2012 University of Szeged
7 * Copyright (C) 2012 Renata Hodovan <reni@webkit.org> 7 * Copyright (C) 2012 Renata Hodovan <reni@webkit.org>
8 * 8 *
9 * This library is free software; you can redistribute it and/or 9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public 10 * modify it under the terms of the GNU Library General Public
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 ScriptWrappable::init(this); 67 ScriptWrappable::init(this);
68 68
69 addToPropertyMap(m_x); 69 addToPropertyMap(m_x);
70 addToPropertyMap(m_y); 70 addToPropertyMap(m_y);
71 addToPropertyMap(m_width); 71 addToPropertyMap(m_width);
72 addToPropertyMap(m_height); 72 addToPropertyMap(m_height);
73 } 73 }
74 74
75 PassRefPtr<SVGUseElement> SVGUseElement::create(Document& document, bool wasInse rtedByParser) 75 PassRefPtr<SVGUseElement> SVGUseElement::create(Document& document, bool wasInse rtedByParser)
76 { 76 {
77 // Always build a #shadow-root for SVGUseElement. 77 // Always build a user agent #shadow-root for SVGUseElement.
78 RefPtr<SVGUseElement> use = adoptRef(new SVGUseElement(document, wasInserted ByParser)); 78 RefPtr<SVGUseElement> use = adoptRef(new SVGUseElement(document, wasInserted ByParser));
79 use->ensureUserAgentShadowRoot(); 79 use->ensureUserAgentShadowRoot();
80 return use.release(); 80 return use.release();
81 } 81 }
82 82
83 SVGUseElement::~SVGUseElement() 83 SVGUseElement::~SVGUseElement()
84 { 84 {
85 setDocumentResource(0); 85 setDocumentResource(0);
86 86
87 clearResourceReferences(); 87 clearResourceReferences();
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 for (Node* cur = start->firstChild(); cur; cur = cur->nextSibling()) { 338 for (Node* cur = start->firstChild(); cur; cur = cur->nextSibling()) {
339 if (subtreeContainsDisallowedElement(cur)) 339 if (subtreeContainsDisallowedElement(cur))
340 return true; 340 return true;
341 } 341 }
342 342
343 return false; 343 return false;
344 } 344 }
345 345
346 void SVGUseElement::scheduleShadowTreeRecreation() 346 void SVGUseElement::scheduleShadowTreeRecreation()
347 { 347 {
348 if (!referencedDocument() || isInShadowTree()) 348 if (!referencedDocument() || isInUserAgentShadowTree())
349 return; 349 return;
350 m_needsShadowTreeRecreation = true; 350 m_needsShadowTreeRecreation = true;
351 document().scheduleUseShadowTreeUpdate(*this); 351 document().scheduleUseShadowTreeUpdate(*this);
352 } 352 }
353 353
354 void SVGUseElement::clearResourceReferences() 354 void SVGUseElement::clearResourceReferences()
355 { 355 {
356 // FIXME: We should try to optimize this, to at least allow partial reclones . 356 // FIXME: We should try to optimize this, to at least allow partial reclones .
357 if (ShadowRoot* shadowTreeRootElement = userAgentShadowRoot()) 357 if (ShadowRoot* shadowTreeRootElement = userAgentShadowRoot())
358 shadowTreeRootElement->removeChildren(); 358 shadowTreeRootElement->removeChildren();
359 359
360 if (m_targetElementInstance) { 360 if (m_targetElementInstance) {
361 m_targetElementInstance->detach(); 361 m_targetElementInstance->detach();
362 m_targetElementInstance = nullptr; 362 m_targetElementInstance = nullptr;
363 } 363 }
364 364
365 m_needsShadowTreeRecreation = false; 365 m_needsShadowTreeRecreation = false;
366 document().unscheduleUseShadowTreeUpdate(*this); 366 document().unscheduleUseShadowTreeUpdate(*this);
367 367
368 document().accessSVGExtensions().removeAllTargetReferencesForElement(this); 368 document().accessSVGExtensions().removeAllTargetReferencesForElement(this);
369 } 369 }
370 370
371 void SVGUseElement::buildPendingResource() 371 void SVGUseElement::buildPendingResource()
372 { 372 {
373 if (!referencedDocument() || isInShadowTree()) 373 if (!referencedDocument() || isInUserAgentShadowTree())
374 return; 374 return;
375 clearResourceReferences(); 375 clearResourceReferences();
376 if (!inDocument()) 376 if (!inDocument())
377 return; 377 return;
378 378
379 AtomicString id; 379 AtomicString id;
380 Element* target = SVGURIReference::targetElementFromIRIString(hrefString(), document(), &id, externalDocument()); 380 Element* target = SVGURIReference::targetElementFromIRIString(hrefString(), document(), &id, externalDocument());
381 if (!target || !target->inDocument()) { 381 if (!target || !target->inDocument()) {
382 // If we can't find the target of an external element, just give up. 382 // If we can't find the target of an external element, just give up.
383 // We can't observe if the target somewhen enters the external document, nor should we do it. 383 // We can't observe if the target somewhen enters the external document, nor should we do it.
(...skipping 12 matching lines...) Expand all
396 invalidateDependentShadowTrees(); 396 invalidateDependentShadowTrees();
397 } 397 }
398 398
399 ASSERT(!m_needsShadowTreeRecreation); 399 ASSERT(!m_needsShadowTreeRecreation);
400 } 400 }
401 401
402 void SVGUseElement::buildShadowAndInstanceTree(SVGElement* target) 402 void SVGUseElement::buildShadowAndInstanceTree(SVGElement* target)
403 { 403 {
404 ASSERT(!m_targetElementInstance); 404 ASSERT(!m_targetElementInstance);
405 405
406 // Do not build the shadow/instance tree for <use> elements living in a shad ow tree. 406 // <use> creates a "user agent" shadow root. Do not build the shadow/instanc e tree for <use>
407 // The will be expanded soon anyway - see expandUseElementsInShadowTree(). 407 // elements living in a user agent shadow tree because they will get expande d in a second
408 if (isInShadowTree()) 408 // pass -- see expandUseElementsInShadowTree().
409 if (isInUserAgentShadowTree())
409 return; 410 return;
410 411
411 // Do not allow self-referencing. 412 // Do not allow self-referencing.
412 // 'target' may be null, if it's a non SVG namespaced element. 413 // 'target' may be null, if it's a non SVG namespaced element.
413 if (!target || target == this) 414 if (!target || target == this)
414 return; 415 return;
415 416
416 // Why a seperated instance/shadow tree? SVG demands it: 417 // Why a seperated instance/shadow tree? SVG demands it:
417 // The instance tree is accesable from JavaScript, and has to 418 // The instance tree is accesable from JavaScript, and has to
418 // expose a 1:1 copy of the referenced tree, whereas internally we need 419 // expose a 1:1 copy of the referenced tree, whereas internally we need
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 668
668 userAgentShadowRoot()->appendChild(newChild.release()); 669 userAgentShadowRoot()->appendChild(newChild.release());
669 } 670 }
670 671
671 void SVGUseElement::expandUseElementsInShadowTree(Node* element) 672 void SVGUseElement::expandUseElementsInShadowTree(Node* element)
672 { 673 {
673 ASSERT(element); 674 ASSERT(element);
674 // Why expand the <use> elements in the shadow tree here, and not just 675 // Why expand the <use> elements in the shadow tree here, and not just
675 // do this directly in buildShadowTree, if we encounter a <use> element? 676 // do this directly in buildShadowTree, if we encounter a <use> element?
676 // 677 //
677 // Short answer: Because we may miss to expand some elements. Ie. if a <symb ol> 678 // Short answer: Because we may miss to expand some elements. For example, i f a <symbol>
678 // contains <use> tags, we'd miss them. So once we're done with settin' up t he 679 // contains <use> tags, we'd miss them. So once we're done with setting up t he
679 // actual shadow tree (after the special case modification for svg/symbol) w e have 680 // actual shadow tree (after the special case modification for svg/symbol) w e have
680 // to walk it completely and expand all <use> elements. 681 // to walk it completely and expand all <use> elements.
681 if (isSVGUseElement(*element)) { 682 if (isSVGUseElement(*element)) {
682 SVGUseElement* use = toSVGUseElement(element); 683 SVGUseElement* use = toSVGUseElement(element);
683 ASSERT(!use->resourceIsStillLoading()); 684 ASSERT(!use->resourceIsStillLoading());
684 685
685 ASSERT(referencedDocument()); 686 ASSERT(referencedDocument());
686 Element* targetElement = SVGURIReference::targetElementFromIRIString(use ->hrefString(), *referencedDocument()); 687 Element* targetElement = SVGURIReference::targetElementFromIRIString(use ->hrefString(), *referencedDocument());
687 SVGElement* target = 0; 688 SVGElement* target = 0;
688 if (targetElement && targetElement->isSVGElement()) 689 if (targetElement && targetElement->isSVGElement())
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
882 883
883 to->cloneDataFromElement(*from); 884 to->cloneDataFromElement(*from);
884 885
885 to->removeAttribute(SVGNames::xAttr); 886 to->removeAttribute(SVGNames::xAttr);
886 to->removeAttribute(SVGNames::yAttr); 887 to->removeAttribute(SVGNames::yAttr);
887 to->removeAttribute(SVGNames::widthAttr); 888 to->removeAttribute(SVGNames::widthAttr);
888 to->removeAttribute(SVGNames::heightAttr); 889 to->removeAttribute(SVGNames::heightAttr);
889 to->removeAttribute(XLinkNames::hrefAttr); 890 to->removeAttribute(XLinkNames::hrefAttr);
890 } 891 }
891 892
893 bool SVGUseElement::isInUserAgentShadowTree() const
894 {
895 if (ShadowRoot* shadowRoot = containingShadowRoot())
896 return shadowRoot->type() == ShadowRoot::UserAgentShadowRoot;
897 return false;
898 }
899
892 bool SVGUseElement::selfHasRelativeLengths() const 900 bool SVGUseElement::selfHasRelativeLengths() const
893 { 901 {
894 if (m_x->currentValue()->isRelative() 902 if (m_x->currentValue()->isRelative()
895 || m_y->currentValue()->isRelative() 903 || m_y->currentValue()->isRelative()
896 || m_width->currentValue()->isRelative() 904 || m_width->currentValue()->isRelative()
897 || m_height->currentValue()->isRelative()) 905 || m_height->currentValue()->isRelative())
898 return true; 906 return true;
899 907
900 if (!m_targetElementInstance) 908 if (!m_targetElementInstance)
901 return false; 909 return false;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
963 971
964 if (m_resource) 972 if (m_resource)
965 m_resource->removeClient(this); 973 m_resource->removeClient(this);
966 974
967 m_resource = resource; 975 m_resource = resource;
968 if (m_resource) 976 if (m_resource)
969 m_resource->addClient(this); 977 m_resource->addClient(this);
970 } 978 }
971 979
972 } 980 }
OLDNEW
« no previous file with comments | « Source/core/svg/SVGUseElement.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698