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

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

Issue 2738863002: Replace ASSERT with DCHECK in core/svg/ (Closed)
Patch Set: static_cast<unsigned>(1) > 1u Created 3 years, 9 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann
3 * <zimmermann@kde.org> 3 * <zimmermann@kde.org>
4 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> 4 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
5 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. 5 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
6 * Copyright (C) 2011 Torch Mobile (Beijing) Co. Ltd. All rights reserved. 6 * Copyright (C) 2011 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
7 * Copyright (C) 2012 University of Szeged 7 * Copyright (C) 2012 University of Szeged
8 * Copyright (C) 2012 Renata Hodovan <reni@webkit.org> 8 * Copyright (C) 2012 Renata Hodovan <reni@webkit.org>
9 * 9 *
10 * This library is free software; you can redistribute it and/or 10 * This library is free software; you can redistribute it and/or
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 SVGAnimatedLength::create(this, 62 SVGAnimatedLength::create(this,
63 SVGNames::widthAttr, 63 SVGNames::widthAttr,
64 SVGLength::create(SVGLengthMode::Width))), 64 SVGLength::create(SVGLengthMode::Width))),
65 m_height( 65 m_height(
66 SVGAnimatedLength::create(this, 66 SVGAnimatedLength::create(this,
67 SVGNames::heightAttr, 67 SVGNames::heightAttr,
68 SVGLength::create(SVGLengthMode::Height))), 68 SVGLength::create(SVGLengthMode::Height))),
69 m_elementIdentifierIsLocal(true), 69 m_elementIdentifierIsLocal(true),
70 m_haveFiredLoadEvent(false), 70 m_haveFiredLoadEvent(false),
71 m_needsShadowTreeRecreation(false) { 71 m_needsShadowTreeRecreation(false) {
72 ASSERT(hasCustomStyleCallbacks()); 72 DCHECK(hasCustomStyleCallbacks());
73 73
74 addToPropertyMap(m_x); 74 addToPropertyMap(m_x);
75 addToPropertyMap(m_y); 75 addToPropertyMap(m_y);
76 addToPropertyMap(m_width); 76 addToPropertyMap(m_width);
77 addToPropertyMap(m_height); 77 addToPropertyMap(m_height);
78 } 78 }
79 79
80 SVGUseElement* SVGUseElement::create(Document& document) { 80 SVGUseElement* SVGUseElement::create(Document& document) {
81 // Always build a user agent #shadow-root for SVGUseElement. 81 // Always build a user agent #shadow-root for SVGUseElement.
82 SVGUseElement* use = new SVGUseElement(document); 82 SVGUseElement* use = new SVGUseElement(document);
(...skipping 28 matching lines...) Expand all
111 } 111 }
112 #endif 112 #endif
113 113
114 Node::InsertionNotificationRequest SVGUseElement::insertedInto( 114 Node::InsertionNotificationRequest SVGUseElement::insertedInto(
115 ContainerNode* rootParent) { 115 ContainerNode* rootParent) {
116 // This functions exists to assure assumptions made in the code regarding 116 // This functions exists to assure assumptions made in the code regarding
117 // SVGElementInstance creation/destruction are satisfied. 117 // SVGElementInstance creation/destruction are satisfied.
118 SVGGraphicsElement::insertedInto(rootParent); 118 SVGGraphicsElement::insertedInto(rootParent);
119 if (!rootParent->isConnected()) 119 if (!rootParent->isConnected())
120 return InsertionDone; 120 return InsertionDone;
121 ASSERT(!m_targetElementInstance || !isWellFormedDocument(&document())); 121 #if DCHECK_IS_ON()
122 ASSERT(!hasPendingResources() || !isWellFormedDocument(&document())); 122 DCHECK(!m_targetElementInstance || !isWellFormedDocument(&document()));
123 DCHECK(!hasPendingResources() || !isWellFormedDocument(&document()));
124 #endif
123 invalidateShadowTree(); 125 invalidateShadowTree();
124 return InsertionDone; 126 return InsertionDone;
125 } 127 }
126 128
127 void SVGUseElement::removedFrom(ContainerNode* rootParent) { 129 void SVGUseElement::removedFrom(ContainerNode* rootParent) {
128 SVGGraphicsElement::removedFrom(rootParent); 130 SVGGraphicsElement::removedFrom(rootParent);
129 if (rootParent->isConnected()) { 131 if (rootParent->isConnected()) {
130 clearResourceReference(); 132 clearResourceReference();
131 cancelShadowTreeRecreation(); 133 cancelShadowTreeRecreation();
132 } 134 }
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 SVGElement::InvalidationGuard invalidationGuard(this); 220 SVGElement::InvalidationGuard invalidationGuard(this);
219 221
220 if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr) { 222 if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr) {
221 invalidateSVGPresentationAttributeStyle(); 223 invalidateSVGPresentationAttributeStyle();
222 setNeedsStyleRecalc(LocalStyleChange, 224 setNeedsStyleRecalc(LocalStyleChange,
223 StyleChangeReasonForTracing::fromAttribute(attrName)); 225 StyleChangeReasonForTracing::fromAttribute(attrName));
224 } 226 }
225 227
226 updateRelativeLengthsInformation(); 228 updateRelativeLengthsInformation();
227 if (m_targetElementInstance) { 229 if (m_targetElementInstance) {
228 ASSERT(m_targetElementInstance->correspondingElement()); 230 DCHECK(m_targetElementInstance->correspondingElement());
229 transferUseWidthAndHeightIfNeeded( 231 transferUseWidthAndHeightIfNeeded(
230 *this, *m_targetElementInstance, 232 *this, *m_targetElementInstance,
231 *m_targetElementInstance->correspondingElement()); 233 *m_targetElementInstance->correspondingElement());
232 } 234 }
233 235
234 LayoutObject* object = this->layoutObject(); 236 LayoutObject* object = this->layoutObject();
235 if (object) 237 if (object)
236 markForLayoutAndParentResourceInvalidation(object); 238 markForLayoutAndParentResourceInvalidation(object);
237 return; 239 return;
238 } 240 }
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 cancelShadowTreeRecreation(); 318 cancelShadowTreeRecreation();
317 if (!isConnected()) 319 if (!isConnected())
318 return; 320 return;
319 Element* target = resolveTargetElement(); 321 Element* target = resolveTargetElement();
320 // TODO(fs): Why would the Element not be "connected" at this point? 322 // TODO(fs): Why would the Element not be "connected" at this point?
321 if (target && target->isConnected() && target->isSVGElement()) { 323 if (target && target->isConnected() && target->isSVGElement()) {
322 buildShadowAndInstanceTree(toSVGElement(*target)); 324 buildShadowAndInstanceTree(toSVGElement(*target));
323 invalidateDependentShadowTrees(); 325 invalidateDependentShadowTrees();
324 } 326 }
325 327
326 ASSERT(!m_needsShadowTreeRecreation); 328 DCHECK(!m_needsShadowTreeRecreation);
327 } 329 }
328 330
329 String SVGUseElement::title() const { 331 String SVGUseElement::title() const {
330 // Find the first <title> child in <use> which doesn't cover shadow tree. 332 // Find the first <title> child in <use> which doesn't cover shadow tree.
331 if (Element* titleElement = Traversal<SVGTitleElement>::firstChild(*this)) 333 if (Element* titleElement = Traversal<SVGTitleElement>::firstChild(*this))
332 return titleElement->innerText(); 334 return titleElement->innerText();
333 335
334 // If there is no <title> child in <use>, we lookup first <title> child in 336 // If there is no <title> child in <use>, we lookup first <title> child in
335 // shadow tree. 337 // shadow tree.
336 if (m_targetElementInstance) { 338 if (m_targetElementInstance) {
337 if (Element* titleElement = 339 if (Element* titleElement =
338 Traversal<SVGTitleElement>::firstChild(*m_targetElementInstance)) 340 Traversal<SVGTitleElement>::firstChild(*m_targetElementInstance))
339 return titleElement->innerText(); 341 return titleElement->innerText();
340 } 342 }
341 // Otherwise return a null string. 343 // Otherwise return a null string.
342 return String(); 344 return String();
343 } 345 }
344 346
345 static void associateCorrespondingElements(SVGElement& targetRoot, 347 static void associateCorrespondingElements(SVGElement& targetRoot,
346 SVGElement& instanceRoot) { 348 SVGElement& instanceRoot) {
347 auto targetRange = Traversal<SVGElement>::inclusiveDescendantsOf(targetRoot); 349 auto targetRange = Traversal<SVGElement>::inclusiveDescendantsOf(targetRoot);
348 auto targetIterator = targetRange.begin(); 350 auto targetIterator = targetRange.begin();
349 for (SVGElement& instance : 351 for (SVGElement& instance :
350 Traversal<SVGElement>::inclusiveDescendantsOf(instanceRoot)) { 352 Traversal<SVGElement>::inclusiveDescendantsOf(instanceRoot)) {
351 ASSERT(!instance.correspondingElement()); 353 DCHECK(!instance.correspondingElement());
352 instance.setCorrespondingElement(&*targetIterator); 354 instance.setCorrespondingElement(&*targetIterator);
353 ++targetIterator; 355 ++targetIterator;
354 } 356 }
355 ASSERT(!(targetIterator != targetRange.end())); 357 DCHECK(!(targetIterator != targetRange.end()));
tkent 2017/03/14 22:33:14 Use DCHECK_EQ if possible.
mrunal 2017/03/14 23:52:14 It throws an error, ../../base/logging.h:703:26: e
356 } 358 }
357 359
358 // We don't walk the target tree element-by-element, and clone each element, 360 // We don't walk the target tree element-by-element, and clone each element,
359 // but instead use cloneNode(deep=true). This is an optimization for the common 361 // but instead use cloneNode(deep=true). This is an optimization for the common
360 // case where <use> doesn't contain disallowed elements (ie. <foreignObject>). 362 // case where <use> doesn't contain disallowed elements (ie. <foreignObject>).
361 // Though if there are disallowed elements in the subtree, we have to remove 363 // Though if there are disallowed elements in the subtree, we have to remove
362 // them. For instance: <use> on <g> containing <foreignObject> (indirect 364 // them. For instance: <use> on <g> containing <foreignObject> (indirect
363 // case). 365 // case).
364 static inline void removeDisallowedElementsFromSubtree(SVGElement& subtree) { 366 static inline void removeDisallowedElementsFromSubtree(SVGElement& subtree) {
365 ASSERT(!subtree.isConnected()); 367 DCHECK(!subtree.isConnected());
366 Element* element = ElementTraversal::firstWithin(subtree); 368 Element* element = ElementTraversal::firstWithin(subtree);
367 while (element) { 369 while (element) {
368 if (isDisallowedElement(*element)) { 370 if (isDisallowedElement(*element)) {
369 Element* next = 371 Element* next =
370 ElementTraversal::nextSkippingChildren(*element, &subtree); 372 ElementTraversal::nextSkippingChildren(*element, &subtree);
371 // The subtree is not in document so this won't generate events that could 373 // The subtree is not in document so this won't generate events that could
372 // mutate the tree. 374 // mutate the tree.
373 element->parentNode()->removeChild(element); 375 element->parentNode()->removeChild(element);
374 element = next; 376 element = next;
375 } else { 377 } else {
376 element = ElementTraversal::next(*element, &subtree); 378 element = ElementTraversal::next(*element, &subtree);
377 } 379 }
378 } 380 }
379 } 381 }
380 382
381 static void moveChildrenToReplacementElement(ContainerNode& sourceRoot, 383 static void moveChildrenToReplacementElement(ContainerNode& sourceRoot,
382 ContainerNode& destinationRoot) { 384 ContainerNode& destinationRoot) {
383 for (Node* child = sourceRoot.firstChild(); child;) { 385 for (Node* child = sourceRoot.firstChild(); child;) {
384 Node* nextChild = child->nextSibling(); 386 Node* nextChild = child->nextSibling();
385 destinationRoot.appendChild(child); 387 destinationRoot.appendChild(child);
386 child = nextChild; 388 child = nextChild;
387 } 389 }
388 } 390 }
389 391
390 Element* SVGUseElement::createInstanceTree(SVGElement& targetRoot) const { 392 Element* SVGUseElement::createInstanceTree(SVGElement& targetRoot) const {
391 Element* instanceRoot = targetRoot.cloneElementWithChildren(); 393 Element* instanceRoot = targetRoot.cloneElementWithChildren();
392 ASSERT(instanceRoot->isSVGElement()); 394 DCHECK(instanceRoot->isSVGElement());
393 if (isSVGSymbolElement(targetRoot)) { 395 if (isSVGSymbolElement(targetRoot)) {
394 // Spec: The referenced 'symbol' and its contents are deep-cloned into 396 // Spec: The referenced 'symbol' and its contents are deep-cloned into
395 // the generated tree, with the exception that the 'symbol' is replaced 397 // the generated tree, with the exception that the 'symbol' is replaced
396 // by an 'svg'. This generated 'svg' will always have explicit values 398 // by an 'svg'. This generated 'svg' will always have explicit values
397 // for attributes width and height. If attributes width and/or height 399 // for attributes width and height. If attributes width and/or height
398 // are provided on the 'use' element, then these attributes will be 400 // are provided on the 'use' element, then these attributes will be
399 // transferred to the generated 'svg'. If attributes width and/or 401 // transferred to the generated 'svg'. If attributes width and/or
400 // height are not specified, the generated 'svg' element will use 402 // height are not specified, the generated 'svg' element will use
401 // values of 100% for these attributes. 403 // values of 100% for these attributes.
402 SVGSVGElement* svgElement = SVGSVGElement::create(targetRoot.document()); 404 SVGSVGElement* svgElement = SVGSVGElement::create(targetRoot.document());
403 // Transfer all data (attributes, etc.) from the <symbol> to the new 405 // Transfer all data (attributes, etc.) from the <symbol> to the new
404 // <svg> element. 406 // <svg> element.
405 svgElement->cloneDataFromElement(*instanceRoot); 407 svgElement->cloneDataFromElement(*instanceRoot);
406 // Move already cloned elements to the new <svg> element. 408 // Move already cloned elements to the new <svg> element.
407 moveChildrenToReplacementElement(*instanceRoot, *svgElement); 409 moveChildrenToReplacementElement(*instanceRoot, *svgElement);
408 instanceRoot = svgElement; 410 instanceRoot = svgElement;
409 } 411 }
410 transferUseWidthAndHeightIfNeeded(*this, toSVGElement(*instanceRoot), 412 transferUseWidthAndHeightIfNeeded(*this, toSVGElement(*instanceRoot),
411 targetRoot); 413 targetRoot);
412 associateCorrespondingElements(targetRoot, toSVGElement(*instanceRoot)); 414 associateCorrespondingElements(targetRoot, toSVGElement(*instanceRoot));
413 removeDisallowedElementsFromSubtree(toSVGElement(*instanceRoot)); 415 removeDisallowedElementsFromSubtree(toSVGElement(*instanceRoot));
414 return instanceRoot; 416 return instanceRoot;
415 } 417 }
416 418
417 void SVGUseElement::buildShadowAndInstanceTree(SVGElement& target) { 419 void SVGUseElement::buildShadowAndInstanceTree(SVGElement& target) {
418 ASSERT(!m_targetElementInstance); 420 DCHECK(!m_targetElementInstance);
419 ASSERT(!m_needsShadowTreeRecreation); 421 DCHECK(!m_needsShadowTreeRecreation);
420 422
421 // <use> creates a "user agent" shadow root. Do not build the shadow/instance 423 // <use> creates a "user agent" shadow root. Do not build the shadow/instance
422 // tree for <use> elements living in a user agent shadow tree because they 424 // tree for <use> elements living in a user agent shadow tree because they
423 // will get expanded in a second pass -- see expandUseElementsInShadowTree(). 425 // will get expanded in a second pass -- see expandUseElementsInShadowTree().
424 if (inUseShadowTree()) 426 if (inUseShadowTree())
425 return; 427 return;
426 428
427 // Do not allow self-referencing. 429 // Do not allow self-referencing.
428 if (&target == this || isDisallowedElement(target)) 430 if (&target == this || isDisallowedElement(target))
429 return; 431 return;
430 432
431 // Set up root SVG element in shadow tree. 433 // Set up root SVG element in shadow tree.
432 // Clone the target subtree into the shadow tree, not handling <use> and 434 // Clone the target subtree into the shadow tree, not handling <use> and
433 // <symbol> yet. 435 // <symbol> yet.
434 Element* instanceRoot = createInstanceTree(target); 436 Element* instanceRoot = createInstanceTree(target);
435 m_targetElementInstance = toSVGElement(instanceRoot); 437 m_targetElementInstance = toSVGElement(instanceRoot);
436 ShadowRoot* shadowTreeRootElement = userAgentShadowRoot(); 438 ShadowRoot* shadowTreeRootElement = userAgentShadowRoot();
437 shadowTreeRootElement->appendChild(instanceRoot); 439 shadowTreeRootElement->appendChild(instanceRoot);
438 440
439 addReferencesToFirstDegreeNestedUseElements(target); 441 addReferencesToFirstDegreeNestedUseElements(target);
440 442
441 if (instanceTreeIsLoading()) 443 if (instanceTreeIsLoading())
442 return; 444 return;
443 445
444 // Assure shadow tree building was successful. 446 // Assure shadow tree building was successful.
445 ASSERT(m_targetElementInstance); 447 DCHECK(m_targetElementInstance);
446 ASSERT(m_targetElementInstance->correspondingUseElement() == this); 448 DCHECK_EQ(m_targetElementInstance->correspondingUseElement(), this);
447 ASSERT(m_targetElementInstance->correspondingElement() == &target); 449 DCHECK_EQ(m_targetElementInstance->correspondingElement(), &target);
448 450
449 // Expand all <use> elements in the shadow tree. 451 // Expand all <use> elements in the shadow tree.
450 // Expand means: replace the actual <use> element by what it references. 452 // Expand means: replace the actual <use> element by what it references.
451 if (!expandUseElementsInShadowTree()) { 453 if (!expandUseElementsInShadowTree()) {
452 shadowTreeRootElement->removeChildren(OmitSubtreeModifiedEvent); 454 shadowTreeRootElement->removeChildren(OmitSubtreeModifiedEvent);
453 clearResourceReference(); 455 clearResourceReference();
454 return; 456 return;
455 } 457 }
456 458
457 // If the instance root was a <use>, it could have been replaced now, so 459 // If the instance root was a <use>, it could have been replaced now, so
458 // reset |m_targetElementInstance|. 460 // reset |m_targetElementInstance|.
459 m_targetElementInstance = 461 m_targetElementInstance =
460 toSVGElementOrDie(shadowTreeRootElement->firstChild()); 462 toSVGElementOrDie(shadowTreeRootElement->firstChild());
461 ASSERT(m_targetElementInstance->parentNode() == shadowTreeRootElement); 463 DCHECK_EQ(m_targetElementInstance->parentNode(), shadowTreeRootElement);
462 464
463 // Update relative length information. 465 // Update relative length information.
464 updateRelativeLengthsInformation(); 466 updateRelativeLengthsInformation();
465 } 467 }
466 468
467 LayoutObject* SVGUseElement::createLayoutObject(const ComputedStyle&) { 469 LayoutObject* SVGUseElement::createLayoutObject(const ComputedStyle&) {
468 return new LayoutSVGTransformableContainer(this); 470 return new LayoutSVGTransformableContainer(this);
469 } 471 }
470 472
471 static bool isDirectReference(const SVGElement& element) { 473 static bool isDirectReference(const SVGElement& element) {
472 return isSVGPathElement(element) || isSVGRectElement(element) || 474 return isSVGPathElement(element) || isSVGRectElement(element) ||
473 isSVGCircleElement(element) || isSVGEllipseElement(element) || 475 isSVGCircleElement(element) || isSVGEllipseElement(element) ||
474 isSVGPolygonElement(element) || isSVGPolylineElement(element) || 476 isSVGPolygonElement(element) || isSVGPolylineElement(element) ||
475 isSVGTextElement(element); 477 isSVGTextElement(element);
476 } 478 }
477 479
478 void SVGUseElement::toClipPath(Path& path) const { 480 void SVGUseElement::toClipPath(Path& path) const {
479 ASSERT(path.isEmpty()); 481 DCHECK(path.isEmpty());
480 482
481 const SVGGraphicsElement* element = visibleTargetGraphicsElementForClipping(); 483 const SVGGraphicsElement* element = visibleTargetGraphicsElementForClipping();
482 484
483 if (!element) 485 if (!element)
484 return; 486 return;
485 487
486 if (element->isSVGGeometryElement()) { 488 if (element->isSVGGeometryElement()) {
487 toSVGGeometryElement(*element).toClipPath(path); 489 toSVGGeometryElement(*element).toClipPath(path);
488 // FIXME: Avoid manual resolution of x/y here. Its potentially harmful. 490 // FIXME: Avoid manual resolution of x/y here. Its potentially harmful.
489 SVGLengthContext lengthContext(this); 491 SVGLengthContext lengthContext(this);
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 // Why expand the <use> elements in the shadow tree here, and not just 581 // Why expand the <use> elements in the shadow tree here, and not just
580 // do this directly in buildShadowTree, if we encounter a <use> element? 582 // do this directly in buildShadowTree, if we encounter a <use> element?
581 // 583 //
582 // Short answer: Because we may miss to expand some elements. For example, if 584 // Short answer: Because we may miss to expand some elements. For example, if
583 // a <symbol> contains <use> tags, we'd miss them. So once we're done with 585 // a <symbol> contains <use> tags, we'd miss them. So once we're done with
584 // setting up the actual shadow tree (after the special case modification for 586 // setting up the actual shadow tree (after the special case modification for
585 // svg/symbol) we have to walk it completely and expand all <use> elements. 587 // svg/symbol) we have to walk it completely and expand all <use> elements.
586 ShadowRoot* shadowRoot = userAgentShadowRoot(); 588 ShadowRoot* shadowRoot = userAgentShadowRoot();
587 for (SVGUseElement* use = Traversal<SVGUseElement>::firstWithin(*shadowRoot); 589 for (SVGUseElement* use = Traversal<SVGUseElement>::firstWithin(*shadowRoot);
588 use;) { 590 use;) {
589 ASSERT(!use->resourceIsStillLoading()); 591 DCHECK(!use->resourceIsStillLoading());
590 592
591 SVGUseElement& originalUse = toSVGUseElement(*use->correspondingElement()); 593 SVGUseElement& originalUse = toSVGUseElement(*use->correspondingElement());
592 SVGElement* target = nullptr; 594 SVGElement* target = nullptr;
593 if (hasCycleUseReferencing(originalUse, *use, target)) 595 if (hasCycleUseReferencing(originalUse, *use, target))
594 return false; 596 return false;
595 597
596 if (target && isDisallowedElement(*target)) 598 if (target && isDisallowedElement(*target))
597 return false; 599 return false;
598 // Don't ASSERT(target) here, it may be "pending", too. 600 // Don't DCHECK(target) here, it may be "pending", too.
599 // Setup sub-shadow tree root node 601 // Setup sub-shadow tree root node
600 SVGGElement* cloneParent = SVGGElement::create(originalUse.document()); 602 SVGGElement* cloneParent = SVGGElement::create(originalUse.document());
601 // Transfer all data (attributes, etc.) from <use> to the new <g> element. 603 // Transfer all data (attributes, etc.) from <use> to the new <g> element.
602 cloneParent->cloneDataFromElement(*use); 604 cloneParent->cloneDataFromElement(*use);
603 cloneParent->setCorrespondingElement(&originalUse); 605 cloneParent->setCorrespondingElement(&originalUse);
604 606
605 removeAttributesFromReplacementElement(*cloneParent); 607 removeAttributesFromReplacementElement(*cloneParent);
606 608
607 // Move already cloned elements to the new <g> element. 609 // Move already cloned elements to the new <g> element.
608 moveChildrenToReplacementElement(*use, *cloneParent); 610 moveChildrenToReplacementElement(*use, *cloneParent);
(...skipping 20 matching lines...) Expand all
629 } 631 }
630 632
631 void SVGUseElement::invalidateDependentShadowTrees() { 633 void SVGUseElement::invalidateDependentShadowTrees() {
632 // Recursively invalidate dependent <use> shadow trees 634 // Recursively invalidate dependent <use> shadow trees
633 const HeapHashSet<WeakMember<SVGElement>>& rawInstances = 635 const HeapHashSet<WeakMember<SVGElement>>& rawInstances =
634 instancesForElement(); 636 instancesForElement();
635 HeapVector<Member<SVGElement>> instances; 637 HeapVector<Member<SVGElement>> instances;
636 instances.appendRange(rawInstances.begin(), rawInstances.end()); 638 instances.appendRange(rawInstances.begin(), rawInstances.end());
637 for (auto& instance : instances) { 639 for (auto& instance : instances) {
638 if (SVGUseElement* element = instance->correspondingUseElement()) { 640 if (SVGUseElement* element = instance->correspondingUseElement()) {
639 ASSERT(element->isConnected()); 641 DCHECK(element->isConnected());
640 element->invalidateShadowTree(); 642 element->invalidateShadowTree();
641 } 643 }
642 } 644 }
643 } 645 }
644 646
645 bool SVGUseElement::selfHasRelativeLengths() const { 647 bool SVGUseElement::selfHasRelativeLengths() const {
646 if (m_x->currentValue()->isRelative() || m_y->currentValue()->isRelative() || 648 if (m_x->currentValue()->isRelative() || m_y->currentValue()->isRelative() ||
647 m_width->currentValue()->isRelative() || 649 m_width->currentValue()->isRelative() ||
648 m_height->currentValue()->isRelative()) 650 m_height->currentValue()->isRelative())
649 return true; 651 return true;
(...skipping 21 matching lines...) Expand all
671 // correct without additional work. That will not work out ATM without 673 // correct without additional work. That will not work out ATM without
672 // additional quirks. The problem stems from including the additional 674 // additional quirks. The problem stems from including the additional
673 // translation directly on the LayoutObject corresponding to the 675 // translation directly on the LayoutObject corresponding to the
674 // SVGUseElement. 676 // SVGUseElement.
675 FloatRect bbox = transformableContainer.objectBoundingBox(); 677 FloatRect bbox = transformableContainer.objectBoundingBox();
676 bbox.move(transformableContainer.additionalTranslation()); 678 bbox.move(transformableContainer.additionalTranslation());
677 return bbox; 679 return bbox;
678 } 680 }
679 681
680 void SVGUseElement::dispatchPendingEvent() { 682 void SVGUseElement::dispatchPendingEvent() {
681 ASSERT(isStructurallyExternal() && m_haveFiredLoadEvent); 683 DCHECK(isStructurallyExternal() && m_haveFiredLoadEvent);
tkent 2017/03/14 22:33:14 Split it to two DCHECKs DCHECK((isStructurallyEx
mrunal 2017/03/14 23:52:14 Done.
682 dispatchEvent(Event::create(EventTypeNames::load)); 684 dispatchEvent(Event::create(EventTypeNames::load));
683 } 685 }
684 686
685 void SVGUseElement::notifyFinished(Resource* resource) { 687 void SVGUseElement::notifyFinished(Resource* resource) {
686 ASSERT(m_resource == resource); 688 DCHECK_EQ(m_resource, resource);
687 if (!isConnected()) 689 if (!isConnected())
688 return; 690 return;
689 691
690 invalidateShadowTree(); 692 invalidateShadowTree();
691 if (!resourceIsValid()) { 693 if (!resourceIsValid()) {
692 dispatchEvent(Event::create(EventTypeNames::error)); 694 dispatchEvent(Event::create(EventTypeNames::error));
693 } else if (!resource->wasCanceled()) { 695 } else if (!resource->wasCanceled()) {
694 if (m_haveFiredLoadEvent) 696 if (m_haveFiredLoadEvent)
695 return; 697 return;
696 if (!isStructurallyExternal()) 698 if (!isStructurallyExternal())
697 return; 699 return;
698 ASSERT(!m_haveFiredLoadEvent); 700 DCHECK(!m_haveFiredLoadEvent);
699 m_haveFiredLoadEvent = true; 701 m_haveFiredLoadEvent = true;
700 TaskRunnerHelper::get(TaskType::DOMManipulation, &document()) 702 TaskRunnerHelper::get(TaskType::DOMManipulation, &document())
701 ->postTask(BLINK_FROM_HERE, 703 ->postTask(BLINK_FROM_HERE,
702 WTF::bind(&SVGUseElement::dispatchPendingEvent, 704 WTF::bind(&SVGUseElement::dispatchPendingEvent,
703 wrapPersistent(this))); 705 wrapPersistent(this)));
704 } 706 }
705 } 707 }
706 708
707 bool SVGUseElement::resourceIsStillLoading() const { 709 bool SVGUseElement::resourceIsStillLoading() const {
708 return m_resource && m_resource->isLoading(); 710 return m_resource && m_resource->isLoading();
(...skipping 19 matching lines...) Expand all
728 730
729 if (m_resource) 731 if (m_resource)
730 m_resource->removeClient(this); 732 m_resource->removeClient(this);
731 733
732 m_resource = resource; 734 m_resource = resource;
733 if (m_resource) 735 if (m_resource)
734 m_resource->addClient(this); 736 m_resource->addClient(this);
735 } 737 }
736 738
737 } // namespace blink 739 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698