| 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 | 
|  | 3  * <zimmermann@kde.org> | 
| 3  * Copyright (C) 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> | 4  * Copyright (C) 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> | 
| 4  * Copyright (C) 2008 Apple Inc. All rights reserved. | 5  * Copyright (C) 2008 Apple Inc. All rights reserved. | 
| 5  * Copyright (C) 2008 Alp Toker <alp@atoker.com> | 6  * Copyright (C) 2008 Alp Toker <alp@atoker.com> | 
| 6  * Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au> | 7  * Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au> | 
| 7  * | 8  * | 
| 8  * This library is free software; you can redistribute it and/or | 9  * This library is free software; you can redistribute it and/or | 
| 9  * modify it under the terms of the GNU Library General Public | 10  * modify it under the terms of the GNU Library General Public | 
| 10  * License as published by the Free Software Foundation; either | 11  * License as published by the Free Software Foundation; either | 
| 11  * version 2 of the License, or (at your option) any later version. | 12  * version 2 of the License, or (at your option) any later version. | 
| 12  * | 13  * | 
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 93 | 94 | 
| 94 short SVGElement::tabIndex() const { | 95 short SVGElement::tabIndex() const { | 
| 95   if (supportsFocus()) | 96   if (supportsFocus()) | 
| 96     return Element::tabIndex(); | 97     return Element::tabIndex(); | 
| 97   return -1; | 98   return -1; | 
| 98 } | 99 } | 
| 99 | 100 | 
| 100 void SVGElement::willRecalcStyle(StyleRecalcChange change) { | 101 void SVGElement::willRecalcStyle(StyleRecalcChange change) { | 
| 101   if (!hasSVGRareData()) | 102   if (!hasSVGRareData()) | 
| 102     return; | 103     return; | 
| 103   // If the style changes because of a regular property change (not induced by S
      MIL animations themselves) | 104   // If the style changes because of a regular property change (not induced by | 
| 104   // reset the "computed style without SMIL style properties", so the base value
       change gets reflected. | 105   // SMIL animations themselves) reset the "computed style without SMIL style | 
|  | 106   // properties", so the base value change gets reflected. | 
| 105   if (change > NoChange || needsStyleRecalc()) | 107   if (change > NoChange || needsStyleRecalc()) | 
| 106     svgRareData()->setNeedsOverrideComputedStyleUpdate(); | 108     svgRareData()->setNeedsOverrideComputedStyleUpdate(); | 
| 107 } | 109 } | 
| 108 | 110 | 
| 109 void SVGElement::buildPendingResourcesIfNeeded() { | 111 void SVGElement::buildPendingResourcesIfNeeded() { | 
| 110   Document& document = this->document(); | 112   Document& document = this->document(); | 
| 111   if (!needsPendingResourceHandling() || !isConnected() || inUseShadowTree()) | 113   if (!needsPendingResourceHandling() || !isConnected() || inUseShadowTree()) | 
| 112     return; | 114     return; | 
| 113 | 115 | 
| 114   SVGDocumentExtensions& extensions = document.accessSVGExtensions(); | 116   SVGDocumentExtensions& extensions = document.accessSVGExtensions(); | 
| 115   AtomicString resourceId = getIdAttribute(); | 117   AtomicString resourceId = getIdAttribute(); | 
| 116   if (!extensions.hasPendingResource(resourceId)) | 118   if (!extensions.hasPendingResource(resourceId)) | 
| 117     return; | 119     return; | 
| 118 | 120 | 
| 119   // Mark pending resources as pending for removal. | 121   // Mark pending resources as pending for removal. | 
| 120   extensions.markPendingResourcesForRemoval(resourceId); | 122   extensions.markPendingResourcesForRemoval(resourceId); | 
| 121 | 123 | 
| 122   // Rebuild pending resources for each client of a pending resource that is bei
      ng removed. | 124   // Rebuild pending resources for each client of a pending resource that is | 
|  | 125   // being removed. | 
| 123   while ( | 126   while ( | 
| 124       Element* clientElement = | 127       Element* clientElement = | 
| 125           extensions.removeElementFromPendingResourcesForRemoval(resourceId)) { | 128           extensions.removeElementFromPendingResourcesForRemoval(resourceId)) { | 
| 126     ASSERT(clientElement->hasPendingResources()); | 129     ASSERT(clientElement->hasPendingResources()); | 
| 127     if (clientElement->hasPendingResources()) { | 130     if (clientElement->hasPendingResources()) { | 
| 128       // FIXME: Ideally we'd always resolve pending resources async instead of i
      nside | 131       // FIXME: Ideally we'd always resolve pending resources async instead of | 
| 129       // insertedInto and svgAttributeChanged. For now we only do it for <use> s
      ince | 132       // inside insertedInto and svgAttributeChanged. For now we only do it for | 
| 130       // that would stamp out DOM. | 133       // <use> since that would stamp out DOM. | 
| 131       if (isSVGUseElement(clientElement)) | 134       if (isSVGUseElement(clientElement)) | 
| 132         toSVGUseElement(clientElement)->invalidateShadowTree(); | 135         toSVGUseElement(clientElement)->invalidateShadowTree(); | 
| 133       else | 136       else | 
| 134         clientElement->buildPendingResource(); | 137         clientElement->buildPendingResource(); | 
| 135       extensions.clearHasPendingResourcesIfPossible(clientElement); | 138       extensions.clearHasPendingResourcesIfPossible(clientElement); | 
| 136     } | 139     } | 
| 137   } | 140   } | 
| 138 } | 141 } | 
| 139 | 142 | 
| 140 SVGElementRareData* SVGElement::ensureSVGRareData() { | 143 SVGElementRareData* SVGElement::ensureSVGRareData() { | 
| 141   if (hasSVGRareData()) | 144   if (hasSVGRareData()) | 
| 142     return svgRareData(); | 145     return svgRareData(); | 
| 143 | 146 | 
| 144   m_SVGRareData = new SVGElementRareData(this); | 147   m_SVGRareData = new SVGElementRareData(this); | 
| 145   return m_SVGRareData.get(); | 148   return m_SVGRareData.get(); | 
| 146 } | 149 } | 
| 147 | 150 | 
| 148 bool SVGElement::isOutermostSVGSVGElement() const { | 151 bool SVGElement::isOutermostSVGSVGElement() const { | 
| 149   if (!isSVGSVGElement(*this)) | 152   if (!isSVGSVGElement(*this)) | 
| 150     return false; | 153     return false; | 
| 151 | 154 | 
| 152   // Element may not be in the document, pretend we're outermost for viewport(),
       getCTM(), etc. | 155   // Element may not be in the document, pretend we're outermost for viewport(), | 
|  | 156   // getCTM(), etc. | 
| 153   if (!parentNode()) | 157   if (!parentNode()) | 
| 154     return true; | 158     return true; | 
| 155 | 159 | 
| 156   // We act like an outermost SVG element, if we're a direct child of a <foreign
      Object> element. | 160   // We act like an outermost SVG element, if we're a direct child of a | 
|  | 161   // <foreignObject> element. | 
| 157   if (isSVGForeignObjectElement(*parentNode())) | 162   if (isSVGForeignObjectElement(*parentNode())) | 
| 158     return true; | 163     return true; | 
| 159 | 164 | 
| 160   // If we're living in a shadow tree, we're a <svg> element that got created as
       replacement | 165   // If we're living in a shadow tree, we're a <svg> element that got created as | 
| 161   // for a <symbol> element or a cloned <svg> element in the referenced tree. In
       that case | 166   // replacement for a <symbol> element or a cloned <svg> element in the | 
| 162   // we're always an inner <svg> element. | 167   // referenced tree. In that case we're always an inner <svg> element. | 
| 163   if (inUseShadowTree() && parentOrShadowHostElement() && | 168   if (inUseShadowTree() && parentOrShadowHostElement() && | 
| 164       parentOrShadowHostElement()->isSVGElement()) | 169       parentOrShadowHostElement()->isSVGElement()) | 
| 165     return false; | 170     return false; | 
| 166 | 171 | 
| 167   // This is true whenever this is the outermost SVG, even if there are HTML ele
      ments outside it | 172   // This is true whenever this is the outermost SVG, even if there are HTML | 
|  | 173   // elements outside it | 
| 168   return !parentNode()->isSVGElement(); | 174   return !parentNode()->isSVGElement(); | 
| 169 } | 175 } | 
| 170 | 176 | 
| 171 void SVGElement::reportAttributeParsingError(SVGParsingError error, | 177 void SVGElement::reportAttributeParsingError(SVGParsingError error, | 
| 172                                              const QualifiedName& name, | 178                                              const QualifiedName& name, | 
| 173                                              const AtomicString& value) { | 179                                              const AtomicString& value) { | 
| 174   if (error == SVGParseStatus::NoError) | 180   if (error == SVGParseStatus::NoError) | 
| 175     return; | 181     return; | 
| 176   // Don't report any errors on attribute removal. | 182   // Don't report any errors on attribute removal. | 
| 177   if (value.isNull()) | 183   if (value.isNull()) | 
| 178     return; | 184     return; | 
| 179   document().accessSVGExtensions().reportError( | 185   document().accessSVGExtensions().reportError( | 
| 180       error.format(tagName(), name, value)); | 186       error.format(tagName(), name, value)); | 
| 181 } | 187 } | 
| 182 | 188 | 
| 183 String SVGElement::title() const { | 189 String SVGElement::title() const { | 
| 184   // According to spec, we should not return titles when hovering over root <svg
      > elements (those | 190   // According to spec, we should not return titles when hovering over root | 
| 185   // <title> elements are the title of the document, not a tooltip) so we instan
      tly return. | 191   // <svg> elements (those <title> elements are the title of the document, not a | 
|  | 192   // tooltip) so we instantly return. | 
| 186   if (isOutermostSVGSVGElement()) | 193   if (isOutermostSVGSVGElement()) | 
| 187     return String(); | 194     return String(); | 
| 188 | 195 | 
| 189   if (inUseShadowTree()) { | 196   if (inUseShadowTree()) { | 
| 190     String useTitle(ownerShadowHost()->title()); | 197     String useTitle(ownerShadowHost()->title()); | 
| 191     if (!useTitle.isEmpty()) | 198     if (!useTitle.isEmpty()) | 
| 192       return useTitle; | 199       return useTitle; | 
| 193   } | 200   } | 
| 194 | 201 | 
| 195   // If we aren't an instance in a <use> or the <use> title was not found, then 
      find the first | 202   // If we aren't an instance in a <use> or the <use> title was not found, then | 
| 196   // <title> child of this element. | 203   // find the first <title> child of this element. | 
| 197   // If a title child was found, return the text contents. | 204   // If a title child was found, return the text contents. | 
| 198   if (Element* titleElement = Traversal<SVGTitleElement>::firstChild(*this)) | 205   if (Element* titleElement = Traversal<SVGTitleElement>::firstChild(*this)) | 
| 199     return titleElement->innerText(); | 206     return titleElement->innerText(); | 
| 200 | 207 | 
| 201   // Otherwise return a null/empty string. | 208   // Otherwise return a null/empty string. | 
| 202   return String(); | 209   return String(); | 
| 203 } | 210 } | 
| 204 | 211 | 
| 205 bool SVGElement::instanceUpdatesBlocked() const { | 212 bool SVGElement::instanceUpdatesBlocked() const { | 
| 206   return hasSVGRareData() && svgRareData()->instanceUpdatesBlocked(); | 213   return hasSVGRareData() && svgRareData()->instanceUpdatesBlocked(); | 
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 294 | 301 | 
| 295 void SVGElement::clearAnimatedAttribute(const QualifiedName& attribute) { | 302 void SVGElement::clearAnimatedAttribute(const QualifiedName& attribute) { | 
| 296   forSelfAndInstances(this, [&attribute](SVGElement* element) { | 303   forSelfAndInstances(this, [&attribute](SVGElement* element) { | 
| 297     if (SVGAnimatedPropertyBase* animatedProperty = | 304     if (SVGAnimatedPropertyBase* animatedProperty = | 
| 298             element->propertyFromAttribute(attribute)) | 305             element->propertyFromAttribute(attribute)) | 
| 299       animatedProperty->animationEnded(); | 306       animatedProperty->animationEnded(); | 
| 300   }); | 307   }); | 
| 301 } | 308 } | 
| 302 | 309 | 
| 303 AffineTransform SVGElement::localCoordinateSpaceTransform(CTMScope) const { | 310 AffineTransform SVGElement::localCoordinateSpaceTransform(CTMScope) const { | 
| 304   // To be overriden by SVGGraphicsElement (or as special case SVGTextElement an
      d SVGPatternElement) | 311   // To be overriden by SVGGraphicsElement (or as special case SVGTextElement | 
|  | 312   // and SVGPatternElement) | 
| 305   return AffineTransform(); | 313   return AffineTransform(); | 
| 306 } | 314 } | 
| 307 | 315 | 
| 308 Node::InsertionNotificationRequest SVGElement::insertedInto( | 316 Node::InsertionNotificationRequest SVGElement::insertedInto( | 
| 309     ContainerNode* rootParent) { | 317     ContainerNode* rootParent) { | 
| 310   Element::insertedInto(rootParent); | 318   Element::insertedInto(rootParent); | 
| 311   updateRelativeLengthsInformation(); | 319   updateRelativeLengthsInformation(); | 
| 312   buildPendingResourcesIfNeeded(); | 320   buildPendingResourcesIfNeeded(); | 
| 313   return InsertionDone; | 321   return InsertionDone; | 
| 314 } | 322 } | 
| 315 | 323 | 
| 316 void SVGElement::removedFrom(ContainerNode* rootParent) { | 324 void SVGElement::removedFrom(ContainerNode* rootParent) { | 
| 317   bool wasInDocument = rootParent->isConnected(); | 325   bool wasInDocument = rootParent->isConnected(); | 
| 318 | 326 | 
| 319   if (wasInDocument && hasRelativeLengths()) { | 327   if (wasInDocument && hasRelativeLengths()) { | 
| 320     // The root of the subtree being removed should take itself out from its par
      ent's relative | 328     // The root of the subtree being removed should take itself out from its | 
| 321     // length set. For the other nodes in the subtree we don't need to do anythi
      ng: they will | 329     // parent's relative length set. For the other nodes in the subtree we don't | 
| 322     // get their own removedFrom() notification and just clear their sets. | 330     // need to do anything: they will get their own removedFrom() notification | 
|  | 331     // and just clear their sets. | 
| 323     if (rootParent->isSVGElement() && !parentNode()) { | 332     if (rootParent->isSVGElement() && !parentNode()) { | 
| 324       ASSERT(toSVGElement(rootParent) | 333       ASSERT(toSVGElement(rootParent) | 
| 325                  ->m_elementsWithRelativeLengths.contains(this)); | 334                  ->m_elementsWithRelativeLengths.contains(this)); | 
| 326       toSVGElement(rootParent)->updateRelativeLengthsInformation(false, this); | 335       toSVGElement(rootParent)->updateRelativeLengthsInformation(false, this); | 
| 327     } | 336     } | 
| 328 | 337 | 
| 329     m_elementsWithRelativeLengths.clear(); | 338     m_elementsWithRelativeLengths.clear(); | 
| 330   } | 339   } | 
| 331 | 340 | 
| 332   ASSERT_WITH_SECURITY_IMPLICATION( | 341   ASSERT_WITH_SECURITY_IMPLICATION( | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
| 352 } | 361 } | 
| 353 | 362 | 
| 354 CSSPropertyID SVGElement::cssPropertyIdForSVGAttributeName( | 363 CSSPropertyID SVGElement::cssPropertyIdForSVGAttributeName( | 
| 355     const QualifiedName& attrName) { | 364     const QualifiedName& attrName) { | 
| 356   if (!attrName.namespaceURI().isNull()) | 365   if (!attrName.namespaceURI().isNull()) | 
| 357     return CSSPropertyInvalid; | 366     return CSSPropertyInvalid; | 
| 358 | 367 | 
| 359   static HashMap<StringImpl*, CSSPropertyID>* propertyNameToIdMap = 0; | 368   static HashMap<StringImpl*, CSSPropertyID>* propertyNameToIdMap = 0; | 
| 360   if (!propertyNameToIdMap) { | 369   if (!propertyNameToIdMap) { | 
| 361     propertyNameToIdMap = new HashMap<StringImpl*, CSSPropertyID>; | 370     propertyNameToIdMap = new HashMap<StringImpl*, CSSPropertyID>; | 
| 362     // This is a list of all base CSS and SVG CSS properties which are exposed a
      s SVG XML attributes | 371     // This is a list of all base CSS and SVG CSS properties which are exposed | 
|  | 372     // as SVG XML attributes | 
| 363     const QualifiedName* const attrNames[] = { | 373     const QualifiedName* const attrNames[] = { | 
| 364         &alignment_baselineAttr, | 374         &alignment_baselineAttr, | 
| 365         &baseline_shiftAttr, | 375         &baseline_shiftAttr, | 
| 366         &buffered_renderingAttr, | 376         &buffered_renderingAttr, | 
| 367         &clipAttr, | 377         &clipAttr, | 
| 368         &clip_pathAttr, | 378         &clip_pathAttr, | 
| 369         &clip_ruleAttr, | 379         &clip_ruleAttr, | 
| 370         &SVGNames::colorAttr, | 380         &SVGNames::colorAttr, | 
| 371         &color_interpolationAttr, | 381         &color_interpolationAttr, | 
| 372         &color_interpolation_filtersAttr, | 382         &color_interpolation_filtersAttr, | 
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 427     } | 437     } | 
| 428   } | 438   } | 
| 429 | 439 | 
| 430   return propertyNameToIdMap->get(attrName.localName().impl()); | 440   return propertyNameToIdMap->get(attrName.localName().impl()); | 
| 431 } | 441 } | 
| 432 | 442 | 
| 433 void SVGElement::updateRelativeLengthsInformation(bool clientHasRelativeLengths, | 443 void SVGElement::updateRelativeLengthsInformation(bool clientHasRelativeLengths, | 
| 434                                                   SVGElement* clientElement) { | 444                                                   SVGElement* clientElement) { | 
| 435   ASSERT(clientElement); | 445   ASSERT(clientElement); | 
| 436 | 446 | 
| 437   // If we're not yet in a document, this function will be called again from ins
      ertedInto(). Do nothing now. | 447   // If we're not yet in a document, this function will be called again from | 
|  | 448   // insertedInto(). Do nothing now. | 
| 438   if (!isConnected()) | 449   if (!isConnected()) | 
| 439     return; | 450     return; | 
| 440 | 451 | 
| 441   // An element wants to notify us that its own relative lengths state changed. | 452   // An element wants to notify us that its own relative lengths state changed. | 
| 442   // Register it in the relative length map, and register us in the parent relat
      ive length map. | 453   // Register it in the relative length map, and register us in the parent | 
| 443   // Register the parent in the grandparents map, etc. Repeat procedure until th
      e root of the SVG tree. | 454   // relative length map.  Register the parent in the grandparents map, etc. | 
|  | 455   // Repeat procedure until the root of the SVG tree. | 
| 444   for (Node& currentNode : NodeTraversal::inclusiveAncestorsOf(*this)) { | 456   for (Node& currentNode : NodeTraversal::inclusiveAncestorsOf(*this)) { | 
| 445     if (!currentNode.isSVGElement()) | 457     if (!currentNode.isSVGElement()) | 
| 446       break; | 458       break; | 
| 447     SVGElement& currentElement = toSVGElement(currentNode); | 459     SVGElement& currentElement = toSVGElement(currentNode); | 
| 448     ASSERT(!currentElement.m_inRelativeLengthClientsInvalidation); | 460     ASSERT(!currentElement.m_inRelativeLengthClientsInvalidation); | 
| 449 | 461 | 
| 450     bool hadRelativeLengths = currentElement.hasRelativeLengths(); | 462     bool hadRelativeLengths = currentElement.hasRelativeLengths(); | 
| 451     if (clientHasRelativeLengths) | 463     if (clientHasRelativeLengths) | 
| 452       currentElement.m_elementsWithRelativeLengths.add(clientElement); | 464       currentElement.m_elementsWithRelativeLengths.add(clientElement); | 
| 453     else | 465     else | 
| 454       currentElement.m_elementsWithRelativeLengths.remove(clientElement); | 466       currentElement.m_elementsWithRelativeLengths.remove(clientElement); | 
| 455 | 467 | 
| 456     // If the relative length state hasn't changed, we can stop propagating the 
      notification. | 468     // If the relative length state hasn't changed, we can stop propagating the | 
|  | 469     // notification. | 
| 457     if (hadRelativeLengths == currentElement.hasRelativeLengths()) | 470     if (hadRelativeLengths == currentElement.hasRelativeLengths()) | 
| 458       return; | 471       return; | 
| 459 | 472 | 
| 460     clientElement = ¤tElement; | 473     clientElement = ¤tElement; | 
| 461     clientHasRelativeLengths = clientElement->hasRelativeLengths(); | 474     clientHasRelativeLengths = clientElement->hasRelativeLengths(); | 
| 462   } | 475   } | 
| 463 | 476 | 
| 464   // Register root SVG elements for top level viewport change notifications. | 477   // Register root SVG elements for top level viewport change notifications. | 
| 465   if (isSVGSVGElement(*clientElement)) { | 478   if (isSVGSVGElement(*clientElement)) { | 
| 466     SVGDocumentExtensions& svgExtensions = accessDocumentSVGExtensions(); | 479     SVGDocumentExtensions& svgExtensions = accessDocumentSVGExtensions(); | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 505     if (isSVGSVGElement(*n)) | 518     if (isSVGSVGElement(*n)) | 
| 506       return toSVGSVGElement(n); | 519       return toSVGSVGElement(n); | 
| 507 | 520 | 
| 508     n = n->parentOrShadowHostNode(); | 521     n = n->parentOrShadowHostNode(); | 
| 509   } | 522   } | 
| 510 | 523 | 
| 511   return nullptr; | 524   return nullptr; | 
| 512 } | 525 } | 
| 513 | 526 | 
| 514 SVGElement* SVGElement::viewportElement() const { | 527 SVGElement* SVGElement::viewportElement() const { | 
| 515   // This function needs shadow tree support - as LayoutSVGContainer uses this f
      unction | 528   // This function needs shadow tree support - as LayoutSVGContainer uses this | 
| 516   // to determine the "overflow" property. <use> on <symbol> wouldn't work other
      whise. | 529   // function to determine the "overflow" property. <use> on <symbol> wouldn't | 
|  | 530   // work otherwhise. | 
| 517   ContainerNode* n = parentOrShadowHostNode(); | 531   ContainerNode* n = parentOrShadowHostNode(); | 
| 518   while (n) { | 532   while (n) { | 
| 519     if (isSVGSVGElement(*n) || isSVGImageElement(*n) || isSVGSymbolElement(*n)) | 533     if (isSVGSVGElement(*n) || isSVGImageElement(*n) || isSVGSymbolElement(*n)) | 
| 520       return toSVGElement(n); | 534       return toSVGElement(n); | 
| 521 | 535 | 
| 522     n = n->parentOrShadowHostNode(); | 536     n = n->parentOrShadowHostNode(); | 
| 523   } | 537   } | 
| 524 | 538 | 
| 525   return nullptr; | 539   return nullptr; | 
| 526 } | 540 } | 
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 822 bool SVGElement::sendSVGLoadEventIfPossible() { | 836 bool SVGElement::sendSVGLoadEventIfPossible() { | 
| 823   if (!haveLoadedRequiredResources()) | 837   if (!haveLoadedRequiredResources()) | 
| 824     return false; | 838     return false; | 
| 825   if ((isStructurallyExternal() || isSVGSVGElement(*this)) && | 839   if ((isStructurallyExternal() || isSVGSVGElement(*this)) && | 
| 826       hasLoadListener(this)) | 840       hasLoadListener(this)) | 
| 827     dispatchEvent(Event::create(EventTypeNames::load)); | 841     dispatchEvent(Event::create(EventTypeNames::load)); | 
| 828   return true; | 842   return true; | 
| 829 } | 843 } | 
| 830 | 844 | 
| 831 void SVGElement::sendSVGLoadEventToSelfAndAncestorChainIfPossible() { | 845 void SVGElement::sendSVGLoadEventToSelfAndAncestorChainIfPossible() { | 
| 832   // Let Document::implicitClose() dispatch the 'load' to the outermost SVG root
      . | 846   // Let Document::implicitClose() dispatch the 'load' to the outermost SVG | 
|  | 847   // root. | 
| 833   if (isOutermostSVGSVGElement()) | 848   if (isOutermostSVGSVGElement()) | 
| 834     return; | 849     return; | 
| 835 | 850 | 
| 836   // Save the next parent to dispatch to in case dispatching the event mutates t
      he tree. | 851   // Save the next parent to dispatch to in case dispatching the event mutates | 
|  | 852   // the tree. | 
| 837   Element* parent = parentOrShadowHostElement(); | 853   Element* parent = parentOrShadowHostElement(); | 
| 838   if (!sendSVGLoadEventIfPossible()) | 854   if (!sendSVGLoadEventIfPossible()) | 
| 839     return; | 855     return; | 
| 840 | 856 | 
| 841   // If document/window 'load' has been sent already, then only deliver to | 857   // If document/window 'load' has been sent already, then only deliver to | 
| 842   // the element in question. | 858   // the element in question. | 
| 843   if (document().loadEventFinished()) | 859   if (document().loadEventFinished()) | 
| 844     return; | 860     return; | 
| 845 | 861 | 
| 846   if (!parent || !parent->isSVGElement()) | 862   if (!parent || !parent->isSVGElement()) | 
| 847     return; | 863     return; | 
| 848 | 864 | 
| 849   toSVGElement(parent)->sendSVGLoadEventToSelfAndAncestorChainIfPossible(); | 865   toSVGElement(parent)->sendSVGLoadEventToSelfAndAncestorChainIfPossible(); | 
| 850 } | 866 } | 
| 851 | 867 | 
| 852 void SVGElement::attributeChanged(const QualifiedName& name, | 868 void SVGElement::attributeChanged(const QualifiedName& name, | 
| 853                                   const AtomicString& oldValue, | 869                                   const AtomicString& oldValue, | 
| 854                                   const AtomicString& newValue, | 870                                   const AtomicString& newValue, | 
| 855                                   AttributeModificationReason) { | 871                                   AttributeModificationReason) { | 
| 856   Element::attributeChanged(name, oldValue, newValue); | 872   Element::attributeChanged(name, oldValue, newValue); | 
| 857 | 873 | 
| 858   if (name == HTMLNames::idAttr) | 874   if (name == HTMLNames::idAttr) | 
| 859     rebuildAllIncomingReferences(); | 875     rebuildAllIncomingReferences(); | 
| 860 | 876 | 
| 861   // Changes to the style attribute are processed lazily (see Element::getAttrib
      ute() and related methods), | 877   // Changes to the style attribute are processed lazily (see | 
| 862   // so we don't want changes to the style attribute to result in extra work her
      e. | 878   // Element::getAttribute() and related methods), so we don't want changes to | 
|  | 879   // the style attribute to result in extra work here. | 
| 863   if (name == HTMLNames::styleAttr) | 880   if (name == HTMLNames::styleAttr) | 
| 864     return; | 881     return; | 
| 865 | 882 | 
| 866   svgAttributeBaseValChanged(name); | 883   svgAttributeBaseValChanged(name); | 
| 867 } | 884 } | 
| 868 | 885 | 
| 869 void SVGElement::svgAttributeChanged(const QualifiedName& attrName) { | 886 void SVGElement::svgAttributeChanged(const QualifiedName& attrName) { | 
| 870   CSSPropertyID propId = SVGElement::cssPropertyIdForSVGAttributeName(attrName); | 887   CSSPropertyID propId = SVGElement::cssPropertyIdForSVGAttributeName(attrName); | 
| 871   if (propId > 0) { | 888   if (propId > 0) { | 
| 872     invalidateInstances(); | 889     invalidateInstances(); | 
| 873     return; | 890     return; | 
| 874   } | 891   } | 
| 875 | 892 | 
| 876   if (attrName == HTMLNames::classAttr) { | 893   if (attrName == HTMLNames::classAttr) { | 
| 877     classAttributeChanged(AtomicString(m_className->currentValue()->value())); | 894     classAttributeChanged(AtomicString(m_className->currentValue()->value())); | 
| 878     invalidateInstances(); | 895     invalidateInstances(); | 
| 879     return; | 896     return; | 
| 880   } | 897   } | 
| 881 | 898 | 
| 882   if (attrName == HTMLNames::idAttr) { | 899   if (attrName == HTMLNames::idAttr) { | 
| 883     LayoutObject* object = layoutObject(); | 900     LayoutObject* object = layoutObject(); | 
| 884     // Notify resources about id changes, this is important as we cache resource
      s by id in SVGDocumentExtensions | 901     // Notify resources about id changes, this is important as we cache | 
|  | 902     // resources by id in SVGDocumentExtensions | 
| 885     if (object && object->isSVGResourceContainer()) | 903     if (object && object->isSVGResourceContainer()) | 
| 886       toLayoutSVGResourceContainer(object)->idChanged(); | 904       toLayoutSVGResourceContainer(object)->idChanged(); | 
| 887     if (isConnected()) | 905     if (isConnected()) | 
| 888       buildPendingResourcesIfNeeded(); | 906       buildPendingResourcesIfNeeded(); | 
| 889     invalidateInstances(); | 907     invalidateInstances(); | 
| 890     return; | 908     return; | 
| 891   } | 909   } | 
| 892 } | 910 } | 
| 893 | 911 | 
| 894 void SVGElement::svgAttributeBaseValChanged(const QualifiedName& attribute) { | 912 void SVGElement::svgAttributeBaseValChanged(const QualifiedName& attribute) { | 
| 895   svgAttributeChanged(attribute); | 913   svgAttributeChanged(attribute); | 
| 896 | 914 | 
| 897   if (!hasSVGRareData() || svgRareData()->webAnimatedAttributes().isEmpty()) | 915   if (!hasSVGRareData() || svgRareData()->webAnimatedAttributes().isEmpty()) | 
| 898     return; | 916     return; | 
| 899 | 917 | 
| 900   // TODO(alancutter): Only mark attributes as dirty if their animation depends 
      on the underlying value. | 918   // TODO(alancutter): Only mark attributes as dirty if their animation depends | 
|  | 919   // on the underlying value. | 
| 901   svgRareData()->setWebAnimatedAttributesDirty(true); | 920   svgRareData()->setWebAnimatedAttributesDirty(true); | 
| 902   elementData()->m_animatedSVGAttributesAreDirty = true; | 921   elementData()->m_animatedSVGAttributesAreDirty = true; | 
| 903 } | 922 } | 
| 904 | 923 | 
| 905 void SVGElement::ensureAttributeAnimValUpdated() { | 924 void SVGElement::ensureAttributeAnimValUpdated() { | 
| 906   if (!RuntimeEnabledFeatures::webAnimationsSVGEnabled()) | 925   if (!RuntimeEnabledFeatures::webAnimationsSVGEnabled()) | 
| 907     return; | 926     return; | 
| 908 | 927 | 
| 909   if ((hasSVGRareData() && svgRareData()->webAnimatedAttributesDirty()) || | 928   if ((hasSVGRareData() && svgRareData()->webAnimatedAttributesDirty()) || | 
| 910       (elementAnimations() && | 929       (elementAnimations() && | 
| 911        DocumentAnimations::needsAnimationTimingUpdate(document()))) { | 930        DocumentAnimations::needsAnimationTimingUpdate(document()))) { | 
| 912     DocumentAnimations::updateAnimationTimingIfNeeded(document()); | 931     DocumentAnimations::updateAnimationTimingIfNeeded(document()); | 
| 913     applyActiveWebAnimations(); | 932     applyActiveWebAnimations(); | 
| 914   } | 933   } | 
| 915 } | 934 } | 
| 916 | 935 | 
| 917 void SVGElement::synchronizeAnimatedSVGAttribute( | 936 void SVGElement::synchronizeAnimatedSVGAttribute( | 
| 918     const QualifiedName& name) const { | 937     const QualifiedName& name) const { | 
| 919   if (!elementData() || !elementData()->m_animatedSVGAttributesAreDirty) | 938   if (!elementData() || !elementData()->m_animatedSVGAttributesAreDirty) | 
| 920     return; | 939     return; | 
| 921 | 940 | 
| 922   // We const_cast here because we have deferred baseVal mutation animation upda
      tes to this point in time. | 941   // We const_cast here because we have deferred baseVal mutation animation | 
|  | 942   // updates to this point in time. | 
| 923   const_cast<SVGElement*>(this)->ensureAttributeAnimValUpdated(); | 943   const_cast<SVGElement*>(this)->ensureAttributeAnimValUpdated(); | 
| 924 | 944 | 
| 925   if (name == anyQName()) { | 945   if (name == anyQName()) { | 
| 926     AttributeToPropertyMap::const_iterator::ValuesIterator it = | 946     AttributeToPropertyMap::const_iterator::ValuesIterator it = | 
| 927         m_attributeToPropertyMap.values().begin(); | 947         m_attributeToPropertyMap.values().begin(); | 
| 928     AttributeToPropertyMap::const_iterator::ValuesIterator end = | 948     AttributeToPropertyMap::const_iterator::ValuesIterator end = | 
| 929         m_attributeToPropertyMap.values().end(); | 949         m_attributeToPropertyMap.values().end(); | 
| 930     for (; it != end; ++it) { | 950     for (; it != end; ++it) { | 
| 931       if ((*it)->needsSynchronizeAttribute()) | 951       if ((*it)->needsSynchronizeAttribute()) | 
| 932         (*it)->synchronizeAttribute(); | 952         (*it)->synchronizeAttribute(); | 
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1165     return; | 1185     return; | 
| 1166 | 1186 | 
| 1167   const SVGElementSet& incomingReferences = svgRareData()->incomingReferences(); | 1187   const SVGElementSet& incomingReferences = svgRareData()->incomingReferences(); | 
| 1168 | 1188 | 
| 1169   // Iterate on a snapshot as |incomingReferences| may be altered inside loop. | 1189   // Iterate on a snapshot as |incomingReferences| may be altered inside loop. | 
| 1170   HeapVector<Member<SVGElement>> incomingReferencesSnapshot; | 1190   HeapVector<Member<SVGElement>> incomingReferencesSnapshot; | 
| 1171   copyToVector(incomingReferences, incomingReferencesSnapshot); | 1191   copyToVector(incomingReferences, incomingReferencesSnapshot); | 
| 1172 | 1192 | 
| 1173   // Force rebuilding the |sourceElement| so it knows about this change. | 1193   // Force rebuilding the |sourceElement| so it knows about this change. | 
| 1174   for (SVGElement* sourceElement : incomingReferencesSnapshot) { | 1194   for (SVGElement* sourceElement : incomingReferencesSnapshot) { | 
| 1175     // Before rebuilding |sourceElement| ensure it was not removed from under us
      . | 1195     // Before rebuilding |sourceElement| ensure it was not removed from under | 
|  | 1196     // us. | 
| 1176     if (incomingReferences.contains(sourceElement)) | 1197     if (incomingReferences.contains(sourceElement)) | 
| 1177       sourceElement->svgAttributeChanged(SVGNames::hrefAttr); | 1198       sourceElement->svgAttributeChanged(SVGNames::hrefAttr); | 
| 1178   } | 1199   } | 
| 1179 } | 1200 } | 
| 1180 | 1201 | 
| 1181 void SVGElement::removeAllIncomingReferences() { | 1202 void SVGElement::removeAllIncomingReferences() { | 
| 1182   if (!hasSVGRareData()) | 1203   if (!hasSVGRareData()) | 
| 1183     return; | 1204     return; | 
| 1184 | 1205 | 
| 1185   SVGElementSet& incomingReferences = svgRareData()->incomingReferences(); | 1206   SVGElementSet& incomingReferences = svgRareData()->incomingReferences(); | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
| 1209   visitor->trace(m_className); | 1230   visitor->trace(m_className); | 
| 1210   Element::trace(visitor); | 1231   Element::trace(visitor); | 
| 1211 } | 1232 } | 
| 1212 | 1233 | 
| 1213 const AtomicString& SVGElement::eventParameterName() { | 1234 const AtomicString& SVGElement::eventParameterName() { | 
| 1214   DEFINE_STATIC_LOCAL(const AtomicString, evtString, ("evt")); | 1235   DEFINE_STATIC_LOCAL(const AtomicString, evtString, ("evt")); | 
| 1215   return evtString; | 1236   return evtString; | 
| 1216 } | 1237 } | 
| 1217 | 1238 | 
| 1218 }  // namespace blink | 1239 }  // namespace blink | 
| OLD | NEW | 
|---|