| 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 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 } | 238 } |
| 239 | 239 |
| 240 invalidateShadowTree(); | 240 invalidateShadowTree(); |
| 241 | 241 |
| 242 return; | 242 return; |
| 243 } | 243 } |
| 244 | 244 |
| 245 SVGGraphicsElement::svgAttributeChanged(attrName); | 245 SVGGraphicsElement::svgAttributeChanged(attrName); |
| 246 } | 246 } |
| 247 | 247 |
| 248 static bool isDisallowedElement(const Node& node) | 248 static bool isDisallowedElement(const Element& element) |
| 249 { | 249 { |
| 250 // Spec: "Any 'svg', 'symbol', 'g', graphics element or other 'use' is poten
tially a template object that can be re-used | 250 // Spec: "Any 'svg', 'symbol', 'g', graphics element or other 'use' is poten
tially a template object that can be re-used |
| 251 // (i.e., "instanced") in the SVG document via a 'use' element." | 251 // (i.e., "instanced") in the SVG document via a 'use' element." |
| 252 // "Graphics Element" is defined as 'circle', 'ellipse', 'image', 'line', 'p
ath', 'polygon', 'polyline', 'rect', 'text' | 252 // "Graphics Element" is defined as 'circle', 'ellipse', 'image', 'line', 'p
ath', 'polygon', 'polyline', 'rect', 'text' |
| 253 // Excluded are anything that is used by reference or that only make sense t
o appear once in a document. | 253 // Excluded are anything that is used by reference or that only make sense t
o appear once in a document. |
| 254 // We must also allow the shadow roots of other use elements. | 254 if (!element.isSVGElement()) |
| 255 if (node.isShadowRoot() || node.isTextNode()) | |
| 256 return false; | |
| 257 | |
| 258 if (!node.isSVGElement()) | |
| 259 return true; | 255 return true; |
| 260 | 256 |
| 261 const Element& element = toElement(node); | |
| 262 | |
| 263 DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, allowedElementTags, ()); | 257 DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, allowedElementTags, ()); |
| 264 if (allowedElementTags.isEmpty()) { | 258 if (allowedElementTags.isEmpty()) { |
| 265 allowedElementTags.add(SVGNames::aTag); | 259 allowedElementTags.add(SVGNames::aTag); |
| 266 allowedElementTags.add(SVGNames::circleTag); | 260 allowedElementTags.add(SVGNames::circleTag); |
| 267 allowedElementTags.add(SVGNames::descTag); | 261 allowedElementTags.add(SVGNames::descTag); |
| 268 allowedElementTags.add(SVGNames::ellipseTag); | 262 allowedElementTags.add(SVGNames::ellipseTag); |
| 269 allowedElementTags.add(SVGNames::gTag); | 263 allowedElementTags.add(SVGNames::gTag); |
| 270 allowedElementTags.add(SVGNames::imageTag); | 264 allowedElementTags.add(SVGNames::imageTag); |
| 271 allowedElementTags.add(SVGNames::lineTag); | 265 allowedElementTags.add(SVGNames::lineTag); |
| 272 allowedElementTags.add(SVGNames::metadataTag); | 266 allowedElementTags.add(SVGNames::metadataTag); |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 Element* next = ElementTraversal::nextSkippingChildren(*element, &su
btree); | 373 Element* next = ElementTraversal::nextSkippingChildren(*element, &su
btree); |
| 380 // The subtree is not in document so this won't generate events that
could mutate the tree. | 374 // The subtree is not in document so this won't generate events that
could mutate the tree. |
| 381 element->parentNode()->removeChild(element); | 375 element->parentNode()->removeChild(element); |
| 382 element = next; | 376 element = next; |
| 383 } else { | 377 } else { |
| 384 element = ElementTraversal::next(*element, &subtree); | 378 element = ElementTraversal::next(*element, &subtree); |
| 385 } | 379 } |
| 386 } | 380 } |
| 387 } | 381 } |
| 388 | 382 |
| 383 PassRefPtrWillBeRawPtr<Element> SVGUseElement::createInstanceTree(SVGElement& ta
rgetRoot) const |
| 384 { |
| 385 RefPtrWillBeRawPtr<Element> instanceRoot = targetRoot.cloneElementWithChildr
en(); |
| 386 ASSERT(instanceRoot->isSVGElement()); |
| 387 associateCorrespondingElements(targetRoot, toSVGElement(*instanceRoot)); |
| 388 removeDisallowedElementsFromSubtree(toSVGElement(*instanceRoot)); |
| 389 return instanceRoot.release(); |
| 390 } |
| 391 |
| 389 void SVGUseElement::buildShadowAndInstanceTree(SVGElement& target) | 392 void SVGUseElement::buildShadowAndInstanceTree(SVGElement& target) |
| 390 { | 393 { |
| 391 ASSERT(!m_targetElementInstance); | 394 ASSERT(!m_targetElementInstance); |
| 392 ASSERT(!m_needsShadowTreeRecreation); | 395 ASSERT(!m_needsShadowTreeRecreation); |
| 393 | 396 |
| 394 // <use> creates a "user agent" shadow root. Do not build the shadow/instanc
e tree for <use> | 397 // <use> creates a "user agent" shadow root. Do not build the shadow/instanc
e tree for <use> |
| 395 // elements living in a user agent shadow tree because they will get expande
d in a second | 398 // elements living in a user agent shadow tree because they will get expande
d in a second |
| 396 // pass -- see expandUseElementsInShadowTree(). | 399 // pass -- see expandUseElementsInShadowTree(). |
| 397 if (inUseShadowTree()) | 400 if (inUseShadowTree()) |
| 398 return; | 401 return; |
| 399 | 402 |
| 400 // Do not allow self-referencing. | 403 // Do not allow self-referencing. |
| 401 if (&target == this || isDisallowedElement(target)) | 404 if (&target == this || isDisallowedElement(target)) |
| 402 return; | 405 return; |
| 403 | 406 |
| 404 // Set up root SVG element in shadow tree. | 407 // Set up root SVG element in shadow tree. |
| 405 // Clone the target subtree into the shadow tree, not handling <use> and <sy
mbol> yet. | 408 // Clone the target subtree into the shadow tree, not handling <use> and <sy
mbol> yet. |
| 406 RefPtrWillBeRawPtr<Element> instanceRoot = target.cloneElementWithChildren()
; | 409 RefPtrWillBeRawPtr<Element> instanceRoot = createInstanceTree(target); |
| 407 ASSERT(instanceRoot->isSVGElement()); | |
| 408 associateCorrespondingElements(target, toSVGElement(*instanceRoot)); | |
| 409 removeDisallowedElementsFromSubtree(toSVGElement(*instanceRoot)); | |
| 410 | |
| 411 m_targetElementInstance = toSVGElement(instanceRoot.get()); | 410 m_targetElementInstance = toSVGElement(instanceRoot.get()); |
| 412 ShadowRoot* shadowTreeRootElement = userAgentShadowRoot(); | 411 ShadowRoot* shadowTreeRootElement = userAgentShadowRoot(); |
| 413 shadowTreeRootElement->appendChild(instanceRoot.release()); | 412 shadowTreeRootElement->appendChild(instanceRoot.release()); |
| 414 | 413 |
| 415 addReferencesToFirstDegreeNestedUseElements(target); | 414 addReferencesToFirstDegreeNestedUseElements(target); |
| 416 | 415 |
| 417 if (instanceTreeIsLoading()) { | 416 if (instanceTreeIsLoading()) { |
| 418 cloneNonMarkupEventListeners(); | 417 cloneNonMarkupEventListeners(); |
| 419 return; | 418 return; |
| 420 } | 419 } |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 599 // Transfer all data (attributes, etc.) from <use> to the new <g> elemen
t. | 598 // Transfer all data (attributes, etc.) from <use> to the new <g> elemen
t. |
| 600 cloneParent->cloneDataFromElement(*use); | 599 cloneParent->cloneDataFromElement(*use); |
| 601 cloneParent->setCorrespondingElement(&originalUse); | 600 cloneParent->setCorrespondingElement(&originalUse); |
| 602 | 601 |
| 603 removeAttributesFromReplacementElement(*cloneParent); | 602 removeAttributesFromReplacementElement(*cloneParent); |
| 604 | 603 |
| 605 // Move already cloned elements to the new <g> element. | 604 // Move already cloned elements to the new <g> element. |
| 606 moveChildrenToReplacementElement(*use, *cloneParent); | 605 moveChildrenToReplacementElement(*use, *cloneParent); |
| 607 | 606 |
| 608 if (target) { | 607 if (target) { |
| 609 RefPtrWillBeRawPtr<Element> instanceRoot = target->cloneElementWithC
hildren(); | 608 RefPtrWillBeRawPtr<Element> instanceRoot = use->createInstanceTree(*
target); |
| 610 ASSERT(instanceRoot->isSVGElement()); | |
| 611 associateCorrespondingElements(*target, toSVGElement(*instanceRoot))
; | |
| 612 transferUseWidthAndHeightIfNeeded(*use, toSVGElement(*instanceRoot),
*target); | 609 transferUseWidthAndHeightIfNeeded(*use, toSVGElement(*instanceRoot),
*target); |
| 613 removeDisallowedElementsFromSubtree(toSVGElement(*instanceRoot)); | |
| 614 cloneParent->appendChild(instanceRoot.release()); | 610 cloneParent->appendChild(instanceRoot.release()); |
| 615 } | 611 } |
| 616 | 612 |
| 617 RefPtrWillBeRawPtr<SVGElement> replacingElement(cloneParent.get()); | 613 RefPtrWillBeRawPtr<SVGElement> replacingElement(cloneParent.get()); |
| 618 | 614 |
| 619 // Replace <use> with referenced content. | 615 // Replace <use> with referenced content. |
| 620 use->parentNode()->replaceChild(cloneParent.release(), use); | 616 use->parentNode()->replaceChild(cloneParent.release(), use); |
| 621 | 617 |
| 622 use = Traversal<SVGUseElement>::next(*replacingElement, shadowRoot); | 618 use = Traversal<SVGUseElement>::next(*replacingElement, shadowRoot); |
| 623 } | 619 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 636 // 'svg' element will use values of 100% for these attributes. | 632 // 'svg' element will use values of 100% for these attributes. |
| 637 SVGElement& originalSymbol = *symbol->correspondingElement(); | 633 SVGElement& originalSymbol = *symbol->correspondingElement(); |
| 638 RefPtrWillBeRawPtr<SVGSVGElement> svgElement = SVGSVGElement::create(ori
ginalSymbol.document()); | 634 RefPtrWillBeRawPtr<SVGSVGElement> svgElement = SVGSVGElement::create(ori
ginalSymbol.document()); |
| 639 // Transfer all data (attributes, etc.) from <symbol> to the new <svg> e
lement. | 635 // Transfer all data (attributes, etc.) from <symbol> to the new <svg> e
lement. |
| 640 svgElement->cloneDataFromElement(*symbol); | 636 svgElement->cloneDataFromElement(*symbol); |
| 641 svgElement->setCorrespondingElement(&originalSymbol); | 637 svgElement->setCorrespondingElement(&originalSymbol); |
| 642 | 638 |
| 643 // Move already cloned elements to the new <svg> element. | 639 // Move already cloned elements to the new <svg> element. |
| 644 moveChildrenToReplacementElement(*symbol, *svgElement); | 640 moveChildrenToReplacementElement(*symbol, *svgElement); |
| 645 | 641 |
| 646 removeDisallowedElementsFromSubtree(*svgElement); | |
| 647 | |
| 648 RefPtrWillBeRawPtr<SVGElement> replacingElement(svgElement.get()); | 642 RefPtrWillBeRawPtr<SVGElement> replacingElement(svgElement.get()); |
| 649 | 643 |
| 650 // Replace <symbol> with <svg>. | 644 // Replace <symbol> with <svg>. |
| 651 symbol->parentNode()->replaceChild(svgElement.release(), symbol); | 645 symbol->parentNode()->replaceChild(svgElement.release(), symbol); |
| 652 | 646 |
| 653 symbol = Traversal<SVGSymbolElement>::next(*replacingElement, shadowRoot
); | 647 symbol = Traversal<SVGSymbolElement>::next(*replacingElement, shadowRoot
); |
| 654 } | 648 } |
| 655 } | 649 } |
| 656 | 650 |
| 657 void SVGUseElement::invalidateShadowTree() | 651 void SVGUseElement::invalidateShadowTree() |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 770 | 764 |
| 771 if (m_resource) | 765 if (m_resource) |
| 772 m_resource->removeClient(this); | 766 m_resource->removeClient(this); |
| 773 | 767 |
| 774 m_resource = resource; | 768 m_resource = resource; |
| 775 if (m_resource) | 769 if (m_resource) |
| 776 m_resource->addClient(this); | 770 m_resource->addClient(this); |
| 777 } | 771 } |
| 778 | 772 |
| 779 } // namespace blink | 773 } // namespace blink |
| OLD | NEW |