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 |