OLD | NEW |
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 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 | 148 |
149 Document* SVGUseElement::externalDocument() const | 149 Document* SVGUseElement::externalDocument() const |
150 { | 150 { |
151 // Gracefully handle error condition. | 151 // Gracefully handle error condition. |
152 if (!resourceIsValid()) | 152 if (!resourceIsValid()) |
153 return nullptr; | 153 return nullptr; |
154 ASSERT(m_resource->document()); | 154 ASSERT(m_resource->document()); |
155 return m_resource->document(); | 155 return m_resource->document(); |
156 } | 156 } |
157 | 157 |
158 void transferUseWidthAndHeightIfNeeded(const SVGUseElement& use, SVGElement* sha
dowElement, const SVGElement& originalElement) | 158 static void transferUseWidthAndHeightIfNeeded(const SVGUseElement& use, SVGEleme
nt& shadowElement, const SVGElement& originalElement) |
159 { | 159 { |
160 DEFINE_STATIC_LOCAL(const AtomicString, hundredPercentString, ("100%", Atomi
cString::ConstructFromLiteral)); | 160 DEFINE_STATIC_LOCAL(const AtomicString, hundredPercentString, ("100%", Atomi
cString::ConstructFromLiteral)); |
161 ASSERT(shadowElement); | 161 if (isSVGSymbolElement(shadowElement)) { |
162 if (isSVGSymbolElement(*shadowElement)) { | |
163 // Spec (<use> on <symbol>): This generated 'svg' will always have expli
cit values for attributes width and height. | 162 // Spec (<use> on <symbol>): This generated 'svg' will always have expli
cit values for attributes width and height. |
164 // If attributes width and/or height are provided on the 'use' element,
then these attributes | 163 // If attributes width and/or height are provided on the 'use' element,
then these attributes |
165 // will be transferred to the generated 'svg'. If attributes width and/o
r height are not specified, | 164 // will be transferred to the generated 'svg'. If attributes width and/o
r height are not specified, |
166 // the generated 'svg' element will use values of 100% for these attribu
tes. | 165 // the generated 'svg' element will use values of 100% for these attribu
tes. |
167 shadowElement->setAttribute(SVGNames::widthAttr, use.width()->isSpecifie
d() ? AtomicString(use.width()->currentValue()->valueAsString()) : hundredPercen
tString); | 166 shadowElement.setAttribute(SVGNames::widthAttr, use.width()->isSpecified
() ? AtomicString(use.width()->currentValue()->valueAsString()) : hundredPercent
String); |
168 shadowElement->setAttribute(SVGNames::heightAttr, use.height()->isSpecif
ied() ? AtomicString(use.height()->currentValue()->valueAsString()) : hundredPer
centString); | 167 shadowElement.setAttribute(SVGNames::heightAttr, use.height()->isSpecifi
ed() ? AtomicString(use.height()->currentValue()->valueAsString()) : hundredPerc
entString); |
169 } else if (isSVGSVGElement(*shadowElement)) { | 168 } else if (isSVGSVGElement(shadowElement)) { |
170 // Spec (<use> on <svg>): If attributes width and/or height are provided
on the 'use' element, then these | 169 // Spec (<use> on <svg>): If attributes width and/or height are provided
on the 'use' element, then these |
171 // values will override the corresponding attributes on the 'svg' in the
generated tree. | 170 // values will override the corresponding attributes on the 'svg' in the
generated tree. |
172 if (use.width()->isSpecified()) | 171 if (use.width()->isSpecified()) |
173 shadowElement->setAttribute(SVGNames::widthAttr, AtomicString(use.wi
dth()->currentValue()->valueAsString())); | 172 shadowElement.setAttribute(SVGNames::widthAttr, AtomicString(use.wid
th()->currentValue()->valueAsString())); |
174 else | 173 else |
175 shadowElement->setAttribute(SVGNames::widthAttr, originalElement.get
Attribute(SVGNames::widthAttr)); | 174 shadowElement.setAttribute(SVGNames::widthAttr, originalElement.getA
ttribute(SVGNames::widthAttr)); |
176 if (use.height()->isSpecified()) | 175 if (use.height()->isSpecified()) |
177 shadowElement->setAttribute(SVGNames::heightAttr, AtomicString(use.h
eight()->currentValue()->valueAsString())); | 176 shadowElement.setAttribute(SVGNames::heightAttr, AtomicString(use.he
ight()->currentValue()->valueAsString())); |
178 else | 177 else |
179 shadowElement->setAttribute(SVGNames::heightAttr, originalElement.ge
tAttribute(SVGNames::heightAttr)); | 178 shadowElement.setAttribute(SVGNames::heightAttr, originalElement.get
Attribute(SVGNames::heightAttr)); |
180 } | 179 } |
181 } | 180 } |
182 | 181 |
183 bool SVGUseElement::isPresentationAttribute(const QualifiedName& attrName) const | 182 bool SVGUseElement::isPresentationAttribute(const QualifiedName& attrName) const |
184 { | 183 { |
185 if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr) | 184 if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr) |
186 return true; | 185 return true; |
187 return SVGGraphicsElement::isPresentationAttribute(attrName); | 186 return SVGGraphicsElement::isPresentationAttribute(attrName); |
188 } | 187 } |
189 | 188 |
(...skipping 26 matching lines...) Expand all Loading... |
216 if (attrName == SVGNames::xAttr | 215 if (attrName == SVGNames::xAttr |
217 || attrName == SVGNames::yAttr) { | 216 || attrName == SVGNames::yAttr) { |
218 invalidateSVGPresentationAttributeStyle(); | 217 invalidateSVGPresentationAttributeStyle(); |
219 setNeedsStyleRecalc(LocalStyleChange, | 218 setNeedsStyleRecalc(LocalStyleChange, |
220 StyleChangeReasonForTracing::fromAttribute(attrName)); | 219 StyleChangeReasonForTracing::fromAttribute(attrName)); |
221 } | 220 } |
222 | 221 |
223 updateRelativeLengthsInformation(); | 222 updateRelativeLengthsInformation(); |
224 if (m_targetElementInstance) { | 223 if (m_targetElementInstance) { |
225 ASSERT(m_targetElementInstance->correspondingElement()); | 224 ASSERT(m_targetElementInstance->correspondingElement()); |
226 transferUseWidthAndHeightIfNeeded(*this, m_targetElementInstance.get
(), *m_targetElementInstance->correspondingElement()); | 225 transferUseWidthAndHeightIfNeeded(*this, *m_targetElementInstance, *
m_targetElementInstance->correspondingElement()); |
227 } | 226 } |
228 | 227 |
229 LayoutObject* object = this->layoutObject(); | 228 LayoutObject* object = this->layoutObject(); |
230 if (object) | 229 if (object) |
231 markForLayoutAndParentResourceInvalidation(object); | 230 markForLayoutAndParentResourceInvalidation(object); |
232 return; | 231 return; |
233 } | 232 } |
234 | 233 |
235 if (SVGURIReference::isKnownAttribute(attrName)) { | 234 if (SVGURIReference::isKnownAttribute(attrName)) { |
236 SVGElement::InvalidationGuard invalidationGuard(this); | 235 SVGElement::InvalidationGuard invalidationGuard(this); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 return; | 342 return; |
344 if (id.isEmpty()) | 343 if (id.isEmpty()) |
345 return; | 344 return; |
346 | 345 |
347 referencedScope()->document().accessSVGExtensions().addPendingResource(i
d, this); | 346 referencedScope()->document().accessSVGExtensions().addPendingResource(i
d, this); |
348 ASSERT(hasPendingResources()); | 347 ASSERT(hasPendingResources()); |
349 return; | 348 return; |
350 } | 349 } |
351 | 350 |
352 if (target->isSVGElement()) { | 351 if (target->isSVGElement()) { |
353 buildShadowAndInstanceTree(toSVGElement(target)); | 352 buildShadowAndInstanceTree(toSVGElement(*target)); |
354 invalidateDependentShadowTrees(); | 353 invalidateDependentShadowTrees(); |
355 } | 354 } |
356 | 355 |
357 ASSERT(!m_needsShadowTreeRecreation); | 356 ASSERT(!m_needsShadowTreeRecreation); |
358 } | 357 } |
359 | 358 |
360 static PassRefPtrWillBeRawPtr<Node> cloneNodeAndAssociate(Node& toClone) | 359 static PassRefPtrWillBeRawPtr<Node> cloneNodeAndAssociate(Node& toClone) |
361 { | 360 { |
362 RefPtrWillBeRawPtr<Node> clone = toClone.cloneNode(false); | 361 RefPtrWillBeRawPtr<Node> clone = toClone.cloneNode(false); |
363 if (!clone->isSVGElement()) | 362 if (!clone->isSVGElement()) |
364 return clone.release(); | 363 return clone.release(); |
365 | 364 |
366 SVGElement& svgElement = toSVGElement(toClone); | 365 SVGElement& svgElement = toSVGElement(toClone); |
367 ASSERT(!svgElement.correspondingElement()); | 366 ASSERT(!svgElement.correspondingElement()); |
368 toSVGElement(clone.get())->setCorrespondingElement(&svgElement); | 367 toSVGElement(clone.get())->setCorrespondingElement(&svgElement); |
369 TrackExceptionState exceptionState; | 368 TrackExceptionState exceptionState; |
370 for (RefPtrWillBeRawPtr<Node> node = toClone.firstChild(); node && !exceptio
nState.hadException(); node = node->nextSibling()) | 369 for (RefPtrWillBeRawPtr<Node> node = toClone.firstChild(); node && !exceptio
nState.hadException(); node = node->nextSibling()) |
371 clone->appendChild(cloneNodeAndAssociate(*node), exceptionState); | 370 clone->appendChild(cloneNodeAndAssociate(*node), exceptionState); |
372 return clone.release(); | 371 return clone.release(); |
373 } | 372 } |
374 | 373 |
375 void SVGUseElement::buildShadowAndInstanceTree(SVGElement* target) | 374 void SVGUseElement::buildShadowAndInstanceTree(SVGElement& target) |
376 { | 375 { |
377 ASSERT(!m_targetElementInstance); | 376 ASSERT(!m_targetElementInstance); |
378 ASSERT(!m_needsShadowTreeRecreation); | 377 ASSERT(!m_needsShadowTreeRecreation); |
379 | 378 |
380 // <use> creates a "user agent" shadow root. Do not build the shadow/instanc
e tree for <use> | 379 // <use> creates a "user agent" shadow root. Do not build the shadow/instanc
e tree for <use> |
381 // elements living in a user agent shadow tree because they will get expande
d in a second | 380 // elements living in a user agent shadow tree because they will get expande
d in a second |
382 // pass -- see expandUseElementsInShadowTree(). | 381 // pass -- see expandUseElementsInShadowTree(). |
383 if (inUseShadowTree()) | 382 if (inUseShadowTree()) |
384 return; | 383 return; |
385 | 384 |
386 // Do not allow self-referencing. | 385 // Do not allow self-referencing. |
387 // 'target' may be null, if it's a non SVG namespaced element. | 386 if (&target == this || isDisallowedElement(target)) |
388 if (!target || target == this || isDisallowedElement(*target)) | |
389 return; | 387 return; |
390 | 388 |
391 // Set up root SVG element in shadow tree. | 389 // Set up root SVG element in shadow tree. |
392 RefPtrWillBeRawPtr<Element> newChild = target->cloneElementWithoutChildren()
; | 390 RefPtrWillBeRawPtr<Element> newChild = target.cloneElementWithoutChildren(); |
393 m_targetElementInstance = toSVGElement(newChild.get()); | 391 m_targetElementInstance = toSVGElement(newChild.get()); |
394 ShadowRoot* shadowTreeRootElement = userAgentShadowRoot(); | 392 ShadowRoot* shadowTreeRootElement = userAgentShadowRoot(); |
395 shadowTreeRootElement->appendChild(newChild.release()); | 393 shadowTreeRootElement->appendChild(newChild.release()); |
396 | 394 |
397 // Clone the target subtree into the shadow tree, not handling <use> and <sy
mbol> yet. | 395 // Clone the target subtree into the shadow tree, not handling <use> and <sy
mbol> yet. |
398 | 396 |
399 // SVG specification does not say a word about <use> & cycles. My view on th
is is: just ignore it! | 397 // SVG specification does not say a word about <use> & cycles. My view on th
is is: just ignore it! |
400 // Non-appearing <use> content is easier to debug, then half-appearing conte
nt. | 398 // Non-appearing <use> content is easier to debug, then half-appearing conte
nt. |
401 buildShadowTree(target, m_targetElementInstance.get(), false); | 399 buildShadowTree(target, *m_targetElementInstance, false); |
402 | 400 |
403 if (instanceTreeIsLoading(m_targetElementInstance.get())) { | 401 if (instanceTreeIsLoading(m_targetElementInstance.get())) { |
404 cloneNonMarkupEventListeners(); | 402 cloneNonMarkupEventListeners(); |
405 return; | 403 return; |
406 } | 404 } |
407 | 405 |
408 // Assure shadow tree building was successful. | 406 // Assure shadow tree building was successful. |
409 ASSERT(m_targetElementInstance); | 407 ASSERT(m_targetElementInstance); |
410 ASSERT(m_targetElementInstance->correspondingUseElement() == this); | 408 ASSERT(m_targetElementInstance->correspondingUseElement() == this); |
411 ASSERT(m_targetElementInstance->correspondingElement() == target); | 409 ASSERT(m_targetElementInstance->correspondingElement() == &target); |
412 | 410 |
413 // Expand all <use> elements in the shadow tree. | 411 // Expand all <use> elements in the shadow tree. |
414 // Expand means: replace the actual <use> element by what it references. | 412 // Expand means: replace the actual <use> element by what it references. |
415 if (!expandUseElementsInShadowTree()) { | 413 if (!expandUseElementsInShadowTree()) { |
416 clearShadowTree(); | 414 clearShadowTree(); |
417 return; | 415 return; |
418 } | 416 } |
419 | 417 |
420 // Expand all <symbol> elements in the shadow tree. | 418 // Expand all <symbol> elements in the shadow tree. |
421 // Expand means: replace the actual <symbol> element by the <svg> element. | 419 // Expand means: replace the actual <symbol> element by the <svg> element. |
422 expandSymbolElementsInShadowTree(); | 420 expandSymbolElementsInShadowTree(); |
423 | 421 |
424 m_targetElementInstance = toSVGElement(shadowTreeRootElement->firstChild()); | 422 m_targetElementInstance = toSVGElement(shadowTreeRootElement->firstChild()); |
425 transferUseWidthAndHeightIfNeeded(*this, m_targetElementInstance.get(), *m_t
argetElementInstance->correspondingElement()); | 423 transferUseWidthAndHeightIfNeeded(*this, *m_targetElementInstance, *m_target
ElementInstance->correspondingElement()); |
426 cloneNonMarkupEventListeners(); | 424 cloneNonMarkupEventListeners(); |
427 | 425 |
428 ASSERT(m_targetElementInstance->parentNode() == shadowTreeRootElement); | 426 ASSERT(m_targetElementInstance->parentNode() == shadowTreeRootElement); |
429 | 427 |
430 // Update relative length information. | 428 // Update relative length information. |
431 updateRelativeLengthsInformation(); | 429 updateRelativeLengthsInformation(); |
432 } | 430 } |
433 | 431 |
434 LayoutObject* SVGUseElement::createLayoutObject(const ComputedStyle&) | 432 LayoutObject* SVGUseElement::createLayoutObject(const ComputedStyle&) |
435 { | 433 { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
482 // http://dev.w3.org/fxtf/css-masking-1/#the-clip-path | 480 // http://dev.w3.org/fxtf/css-masking-1/#the-clip-path |
483 if (!isDirectReference(element)) { | 481 if (!isDirectReference(element)) { |
484 // Spec: Indirect references are an error (14.3.5) | 482 // Spec: Indirect references are an error (14.3.5) |
485 document().accessSVGExtensions().reportError("Not allowed to use indirec
t reference in <clip-path>"); | 483 document().accessSVGExtensions().reportError("Not allowed to use indirec
t reference in <clip-path>"); |
486 return nullptr; | 484 return nullptr; |
487 } | 485 } |
488 | 486 |
489 return &toSVGGraphicsElement(element); | 487 return &toSVGGraphicsElement(element); |
490 } | 488 } |
491 | 489 |
492 void SVGUseElement::buildShadowTree(SVGElement* target, SVGElement* targetInstan
ce, bool foundUse) | 490 void SVGUseElement::buildShadowTree(SVGElement& target, SVGElement& targetInstan
ce, bool foundUse) |
493 { | 491 { |
494 ASSERT(target); | 492 ASSERT(!isDisallowedElement(target)); |
495 ASSERT(targetInstance); | |
496 ASSERT(!isDisallowedElement(*target)); | |
497 | 493 |
498 // Spec: If the referenced object is itself a 'use', or if there are 'use' s
ubelements within the referenced | 494 // Spec: If the referenced object is itself a 'use', or if there are 'use' s
ubelements within the referenced |
499 // object, the instance tree will contain recursive expansion of the indirec
t references to form a complete tree. | 495 // object, the instance tree will contain recursive expansion of the indirec
t references to form a complete tree. |
500 if (isSVGUseElement(*target)) { | 496 if (isSVGUseElement(target)) { |
501 // We only need to track first degree <use> dependencies. Indirect refer
ences are handled | 497 // We only need to track first degree <use> dependencies. Indirect refer
ences are handled |
502 // as the invalidation bubbles up the dependency chain. | 498 // as the invalidation bubbles up the dependency chain. |
503 if (!foundUse && !isStructurallyExternal()) { | 499 if (!foundUse && !isStructurallyExternal()) { |
504 addReferenceTo(target); | 500 addReferenceTo(&target); |
505 foundUse = true; | 501 foundUse = true; |
506 } | 502 } |
507 } | 503 } |
508 | 504 |
509 targetInstance->setCorrespondingElement(target); | 505 targetInstance.setCorrespondingElement(&target); |
510 | 506 |
511 for (RefPtrWillBeRawPtr<Node> child = target->firstChild(); child; child = c
hild->nextSibling()) { | 507 for (RefPtrWillBeRawPtr<Node> child = target.firstChild(); child; child = ch
ild->nextSibling()) { |
512 // Skip any disallowed element. | 508 // Skip any disallowed element. |
513 if (isDisallowedElement(*child)) | 509 if (isDisallowedElement(*child)) |
514 continue; | 510 continue; |
515 | 511 |
516 RefPtrWillBeRawPtr<Node> newChild = child->cloneNode(false); | 512 RefPtrWillBeRawPtr<Node> newChild = child->cloneNode(false); |
517 targetInstance->appendChild(newChild.get()); | 513 targetInstance.appendChild(newChild.get()); |
518 if (newChild->isSVGElement()) { | 514 if (newChild->isSVGElement()) { |
519 // Enter recursion, appending new instance tree nodes to the "instan
ce" object. | 515 // Enter recursion, appending new instance tree nodes to the "instan
ce" object. |
520 buildShadowTree(toSVGElement(child), toSVGElement(newChild), foundUs
e); | 516 buildShadowTree(toSVGElement(*child), toSVGElement(*newChild), found
Use); |
521 } | 517 } |
522 } | 518 } |
523 } | 519 } |
524 | 520 |
525 void SVGUseElement::cloneNonMarkupEventListeners() | 521 void SVGUseElement::cloneNonMarkupEventListeners() |
526 { | 522 { |
527 for (SVGElement& element : Traversal<SVGElement>::descendantsOf(*userAgentSh
adowRoot())) { | 523 for (SVGElement& element : Traversal<SVGElement>::descendantsOf(*userAgentSh
adowRoot())) { |
528 if (EventTargetData* data = element.correspondingElement()->eventTargetD
ata()) | 524 if (EventTargetData* data = element.correspondingElement()->eventTargetD
ata()) |
529 data->eventListenerMap.copyEventListenersNotCreatedFromMarkupToTarge
t(&element); | 525 data->eventListenerMap.copyEventListenersNotCreatedFromMarkupToTarge
t(&element); |
530 } | 526 } |
531 } | 527 } |
532 | 528 |
533 bool SVGUseElement::hasCycleUseReferencing(SVGUseElement* use, ContainerNode* ta
rgetInstance, SVGElement*& newTarget) | 529 bool SVGUseElement::hasCycleUseReferencing(const SVGUseElement& use, const Conta
inerNode& targetInstance, SVGElement*& newTarget) const |
534 { | 530 { |
535 ASSERT(referencedScope()); | 531 ASSERT(referencedScope()); |
536 Element* targetElement = SVGURIReference::targetElementFromIRIString(use->hr
efString(), *referencedScope()); | 532 Element* targetElement = SVGURIReference::targetElementFromIRIString(use.hre
fString(), *referencedScope()); |
537 newTarget = 0; | 533 newTarget = 0; |
538 if (targetElement && targetElement->isSVGElement()) | 534 if (targetElement && targetElement->isSVGElement()) |
539 newTarget = toSVGElement(targetElement); | 535 newTarget = toSVGElement(targetElement); |
540 | 536 |
541 if (!newTarget) | 537 if (!newTarget) |
542 return false; | 538 return false; |
543 | 539 |
544 // Shortcut for self-references | 540 // Shortcut for self-references |
545 if (newTarget == this) | 541 if (newTarget == this) |
546 return true; | 542 return true; |
547 | 543 |
548 AtomicString targetId = newTarget->getIdAttribute(); | 544 AtomicString targetId = newTarget->getIdAttribute(); |
549 ContainerNode* instance = targetInstance->parentNode(); | 545 ContainerNode* instance = targetInstance.parentNode(); |
550 while (instance && instance->isSVGElement()) { | 546 while (instance && instance->isSVGElement()) { |
551 SVGElement* element = toSVGElement(instance); | 547 SVGElement* element = toSVGElement(instance); |
552 if (element->hasID() && element->getIdAttribute() == targetId && element
->document() == newTarget->document()) | 548 if (element->hasID() && element->getIdAttribute() == targetId && element
->document() == newTarget->document()) |
553 return true; | 549 return true; |
554 | 550 |
555 instance = instance->parentNode(); | 551 instance = instance->parentNode(); |
556 } | 552 } |
557 return false; | 553 return false; |
558 } | 554 } |
559 | 555 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
608 // | 604 // |
609 // Short answer: Because we may miss to expand some elements. For example, i
f a <symbol> | 605 // Short answer: Because we may miss to expand some elements. For example, i
f a <symbol> |
610 // contains <use> tags, we'd miss them. So once we're done with setting up t
he | 606 // contains <use> tags, we'd miss them. So once we're done with setting up t
he |
611 // actual shadow tree (after the special case modification for svg/symbol) w
e have | 607 // actual shadow tree (after the special case modification for svg/symbol) w
e have |
612 // to walk it completely and expand all <use> elements. | 608 // to walk it completely and expand all <use> elements. |
613 ShadowRoot* shadowRoot = userAgentShadowRoot(); | 609 ShadowRoot* shadowRoot = userAgentShadowRoot(); |
614 for (RefPtrWillBeRawPtr<SVGUseElement> use = Traversal<SVGUseElement>::first
Within(*shadowRoot); use; ) { | 610 for (RefPtrWillBeRawPtr<SVGUseElement> use = Traversal<SVGUseElement>::first
Within(*shadowRoot); use; ) { |
615 ASSERT(!use->resourceIsStillLoading()); | 611 ASSERT(!use->resourceIsStillLoading()); |
616 | 612 |
617 SVGElement* target = 0; | 613 SVGElement* target = 0; |
618 if (hasCycleUseReferencing(toSVGUseElement(use->correspondingElement()),
use.get(), target)) | 614 if (hasCycleUseReferencing(toSVGUseElement(*use->correspondingElement())
, *use, target)) |
619 return false; | 615 return false; |
620 | 616 |
621 if (target && isDisallowedElement(*target)) | 617 if (target && isDisallowedElement(*target)) |
622 return false; | 618 return false; |
623 // Don't ASSERT(target) here, it may be "pending", too. | 619 // Don't ASSERT(target) here, it may be "pending", too. |
624 // Setup sub-shadow tree root node | 620 // Setup sub-shadow tree root node |
625 RefPtrWillBeRawPtr<SVGGElement> cloneParent = SVGGElement::create(refere
ncedScope()->document()); | 621 RefPtrWillBeRawPtr<SVGGElement> cloneParent = SVGGElement::create(refere
ncedScope()->document()); |
626 // Transfer all data (attributes, etc.) from <use> to the new <g> elemen
t. | 622 // Transfer all data (attributes, etc.) from <use> to the new <g> elemen
t. |
627 cloneParent->cloneDataFromElement(*use); | 623 cloneParent->cloneDataFromElement(*use); |
628 cloneParent->setCorrespondingElement(use->correspondingElement()); | 624 cloneParent->setCorrespondingElement(use->correspondingElement()); |
629 | 625 |
630 removeAttributesFromReplacementElement(*cloneParent); | 626 removeAttributesFromReplacementElement(*cloneParent); |
631 | 627 |
632 // Move already cloned elements to the new <g> element. | 628 // Move already cloned elements to the new <g> element. |
633 moveChildrenToReplacementElement(*use, *cloneParent); | 629 moveChildrenToReplacementElement(*use, *cloneParent); |
634 | 630 |
635 if (target) { | 631 if (target) { |
636 RefPtrWillBeRawPtr<Node> newChild = cloneNodeAndAssociate(*target); | 632 RefPtrWillBeRawPtr<Node> newChild = cloneNodeAndAssociate(*target); |
637 ASSERT(newChild->isSVGElement()); | 633 ASSERT(newChild->isSVGElement()); |
638 transferUseWidthAndHeightIfNeeded(*use, toSVGElement(newChild.get())
, *target); | 634 transferUseWidthAndHeightIfNeeded(*use, toSVGElement(*newChild), *ta
rget); |
639 cloneParent->appendChild(newChild.release()); | 635 cloneParent->appendChild(newChild.release()); |
640 } | 636 } |
641 | 637 |
642 removeDisallowedElementsFromSubtree(*cloneParent); | 638 removeDisallowedElementsFromSubtree(*cloneParent); |
643 | 639 |
644 RefPtrWillBeRawPtr<SVGElement> replacingElement(cloneParent.get()); | 640 RefPtrWillBeRawPtr<SVGElement> replacingElement(cloneParent.get()); |
645 | 641 |
646 // Replace <use> with referenced content. | 642 // Replace <use> with referenced content. |
647 use->parentNode()->replaceChild(cloneParent.release(), use); | 643 use->parentNode()->replaceChild(cloneParent.release(), use); |
648 | 644 |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
797 | 793 |
798 if (m_resource) | 794 if (m_resource) |
799 m_resource->removeClient(this); | 795 m_resource->removeClient(this); |
800 | 796 |
801 m_resource = resource; | 797 m_resource = resource; |
802 if (m_resource) | 798 if (m_resource) |
803 m_resource->addClient(this); | 799 m_resource->addClient(this); |
804 } | 800 } |
805 | 801 |
806 } // namespace blink | 802 } // namespace blink |
OLD | NEW |