Chromium Code Reviews| 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 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 298 return true; | 298 return true; |
| 299 | 299 |
| 300 for (const Node* cur = start->firstChild(); cur; cur = cur->nextSibling()) { | 300 for (const Node* cur = start->firstChild(); cur; cur = cur->nextSibling()) { |
| 301 if (subtreeContainsDisallowedElement(cur)) | 301 if (subtreeContainsDisallowedElement(cur)) |
| 302 return true; | 302 return true; |
| 303 } | 303 } |
| 304 | 304 |
| 305 return false; | 305 return false; |
| 306 } | 306 } |
| 307 | 307 |
| 308 static inline void removeSymbolElementsFromSubtree(SVGElement& subtreeRoot) | |
| 309 { | |
| 310 Element* element = ElementTraversal::firstWithin(subtreeRoot); | |
| 311 while (element) { | |
| 312 if (isSVGSymbolElement(element)) { | |
| 313 Element* next = ElementTraversal::nextSkippingChildren(*element, &su btreeRoot); | |
| 314 // The subtree is not in document so this won't generate events that could mutate the tree. | |
|
pdr.
2016/02/29 23:45:40
Can you assert this here and/or above--that the su
| |
| 315 element->parentNode()->removeChild(element); | |
| 316 element = next; | |
| 317 } else { | |
| 318 element = ElementTraversal::next(*element, &subtreeRoot); | |
| 319 } | |
| 320 } | |
| 321 } | |
| 322 | |
| 308 void SVGUseElement::scheduleShadowTreeRecreation() | 323 void SVGUseElement::scheduleShadowTreeRecreation() |
| 309 { | 324 { |
| 310 if (inUseShadowTree()) | 325 if (inUseShadowTree()) |
| 311 return; | 326 return; |
| 312 m_needsShadowTreeRecreation = true; | 327 m_needsShadowTreeRecreation = true; |
| 313 document().scheduleUseShadowTreeUpdate(*this); | 328 document().scheduleUseShadowTreeUpdate(*this); |
| 314 } | 329 } |
| 315 | 330 |
| 316 void SVGUseElement::cancelShadowTreeRecreation() | 331 void SVGUseElement::cancelShadowTreeRecreation() |
| 317 { | 332 { |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 396 if (inUseShadowTree()) | 411 if (inUseShadowTree()) |
| 397 return; | 412 return; |
| 398 | 413 |
| 399 // Do not allow self-referencing. | 414 // Do not allow self-referencing. |
| 400 // 'target' may be null, if it's a non SVG namespaced element. | 415 // 'target' may be null, if it's a non SVG namespaced element. |
| 401 if (!target || target == this || isDisallowedElement(target)) | 416 if (!target || target == this || isDisallowedElement(target)) |
| 402 return; | 417 return; |
| 403 | 418 |
| 404 // Set up root SVG element in shadow tree. | 419 // Set up root SVG element in shadow tree. |
| 405 RefPtrWillBeRawPtr<Element> newChild = target->cloneElementWithoutChildren() ; | 420 RefPtrWillBeRawPtr<Element> newChild = target->cloneElementWithoutChildren() ; |
| 406 m_targetElementInstance = toSVGElement(newChild.get()); | 421 ASSERT(newChild->isSVGElement()); |
| 407 ShadowRoot* shadowTreeRootElement = userAgentShadowRoot(); | |
| 408 shadowTreeRootElement->appendChild(newChild.release()); | |
| 409 | 422 |
| 410 // Clone the target subtree into the shadow tree, not handling <use> and <sy mbol> yet. | 423 // Clone the target subtree into the shadow tree, not handling <use> and <sy mbol> yet. |
| 411 | 424 |
| 412 // SVG specification does not say a word about <use> & cycles. My view on th is is: just ignore it! | 425 // SVG specification does not say a word about <use> & cycles. My view on th is is: just ignore it! |
| 413 // Non-appearing <use> content is easier to debug, then half-appearing conte nt. | 426 // Non-appearing <use> content is easier to debug, then half-appearing conte nt. |
| 414 if (!buildShadowTree(target, m_targetElementInstance.get(), false)) { | 427 if (!buildShadowTree(target, toSVGElement(newChild.get()), false)) { |
| 415 clearShadowTree(); | 428 clearShadowTree(); |
| 416 return; | 429 return; |
| 417 } | 430 } |
| 431 // Remove any <symbol> elements from the clone, because if not, they'll be | |
| 432 // replaced by <svg> elements which will appear in the rendered result (and | |
| 433 // <symbol>s that are not a direct target of a <use> should not be | |
| 434 // rendered.) | |
| 435 removeSymbolElementsFromSubtree(toSVGElement(*newChild)); | |
|
pdr.
2016/02/29 23:45:40
expandSymbolElementsInShadowTree is called below a
| |
| 436 | |
| 437 // Attach the new clone to our shadow root. | |
| 438 m_targetElementInstance = toSVGElement(newChild.get()); | |
| 439 ShadowRoot* shadowTreeRootElement = userAgentShadowRoot(); | |
| 440 shadowTreeRootElement->appendChild(newChild.release()); | |
| 418 | 441 |
| 419 if (instanceTreeIsLoading(m_targetElementInstance.get())) | 442 if (instanceTreeIsLoading(m_targetElementInstance.get())) |
| 420 return; | 443 return; |
| 421 | 444 |
| 422 // Assure shadow tree building was successfull | 445 // Assure shadow tree building was successfull |
| 423 ASSERT(m_targetElementInstance); | 446 ASSERT(m_targetElementInstance); |
| 424 ASSERT(m_targetElementInstance->correspondingUseElement() == this); | 447 ASSERT(m_targetElementInstance->correspondingUseElement() == this); |
| 425 ASSERT(m_targetElementInstance->correspondingElement() == target); | 448 ASSERT(m_targetElementInstance->correspondingElement() == target); |
| 426 | 449 |
| 427 // Expand all <use> elements in the shadow tree. | 450 // Expand all <use> elements in the shadow tree. |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 615 child = nextChild.release(); | 638 child = nextChild.release(); |
| 616 } | 639 } |
| 617 | 640 |
| 618 // Spec: In the generated content, the 'use' will be replaced by 'g', wh ere all attributes from the | 641 // Spec: In the generated content, the 'use' will be replaced by 'g', wh ere all attributes from the |
| 619 // 'use' element except for x, y, width, height and xlink:href are trans ferred to the generated 'g' element. | 642 // 'use' element except for x, y, width, height and xlink:href are trans ferred to the generated 'g' element. |
| 620 transferUseAttributesToReplacedElement(use, cloneParent.get()); | 643 transferUseAttributesToReplacedElement(use, cloneParent.get()); |
| 621 | 644 |
| 622 if (target) { | 645 if (target) { |
| 623 RefPtrWillBeRawPtr<Node> newChild = cloneNodeAndAssociate(*target); | 646 RefPtrWillBeRawPtr<Node> newChild = cloneNodeAndAssociate(*target); |
| 624 ASSERT(newChild->isSVGElement()); | 647 ASSERT(newChild->isSVGElement()); |
| 648 // Remove any <symbol> elements from the clone, because if not, | |
|
pdr.
2016/02/29 23:45:40
I like how webkit wraps this complexity into a sin
| |
| 649 // they'll be replaced by <svg> elements which will appear in the | |
| 650 // rendered result (and <symbol>s that are not a direct target of a | |
| 651 // <use> should not be rendered.) | |
| 652 removeSymbolElementsFromSubtree(toSVGElement(*newChild)); | |
| 625 transferUseWidthAndHeightIfNeeded(*use, toSVGElement(newChild.get()) , *target); | 653 transferUseWidthAndHeightIfNeeded(*use, toSVGElement(newChild.get()) , *target); |
| 626 cloneParent->appendChild(newChild.release()); | 654 cloneParent->appendChild(newChild.release()); |
| 627 } | 655 } |
| 628 | 656 |
| 629 // We don't walk the target tree element-by-element, and clone each elem ent, | 657 // We don't walk the target tree element-by-element, and clone each elem ent, |
| 630 // but instead use cloneElementWithChildren(). This is an optimization f or the common | 658 // but instead use cloneElementWithChildren(). This is an optimization f or the common |
| 631 // case where <use> doesn't contain disallowed elements (ie. <foreignObj ect>). | 659 // case where <use> doesn't contain disallowed elements (ie. <foreignObj ect>). |
| 632 // Though if there are disallowed elements in the subtree, we have to re move them. | 660 // Though if there are disallowed elements in the subtree, we have to re move them. |
| 633 // For instance: <use> on <g> containing <foreignObject> (indirect case) . | 661 // For instance: <use> on <g> containing <foreignObject> (indirect case) . |
| 634 if (subtreeContainsDisallowedElement(cloneParent.get())) | 662 if (subtreeContainsDisallowedElement(cloneParent.get())) |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 835 | 863 |
| 836 if (m_resource) | 864 if (m_resource) |
| 837 m_resource->removeClient(this); | 865 m_resource->removeClient(this); |
| 838 | 866 |
| 839 m_resource = resource; | 867 m_resource = resource; |
| 840 if (m_resource) | 868 if (m_resource) |
| 841 m_resource->addClient(this); | 869 m_resource->addClient(this); |
| 842 } | 870 } |
| 843 | 871 |
| 844 } // namespace blink | 872 } // namespace blink |
| OLD | NEW |