| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2008 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| 11 * documentation and/or other materials provided with the distribution. | 11 * documentation and/or other materials provided with the distribution. |
| 12 * | 12 * |
| 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY | 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
| 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR | 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
| 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 24 */ | 24 */ |
| 25 | 25 |
| 26 #include "core/svg/animation/SVGSMILElement.h" | 26 #include "core/svg/animation/SVGSMILElement.h" |
| 27 | 27 |
| 28 #include "bindings/core/v8/ExceptionStatePlaceholder.h" | |
| 29 #include "bindings/core/v8/ScriptEventListener.h" | 28 #include "bindings/core/v8/ScriptEventListener.h" |
| 30 #include "core/XLinkNames.h" | 29 #include "core/XLinkNames.h" |
| 31 #include "core/dom/Document.h" | 30 #include "core/dom/Document.h" |
| 32 #include "core/dom/TaskRunnerHelper.h" | 31 #include "core/dom/TaskRunnerHelper.h" |
| 33 #include "core/events/Event.h" | 32 #include "core/events/Event.h" |
| 34 #include "core/events/EventListener.h" | 33 #include "core/events/EventListener.h" |
| 35 #include "core/svg/SVGDocumentExtensions.h" | 34 #include "core/svg/SVGDocumentExtensions.h" |
| 36 #include "core/svg/SVGSVGElement.h" | 35 #include "core/svg/SVGSVGElement.h" |
| 37 #include "core/svg/SVGURIReference.h" | 36 #include "core/svg/SVGURIReference.h" |
| 38 #include "core/svg/animation/SMILTimeContainer.h" | 37 #include "core/svg/animation/SMILTimeContainer.h" |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 } | 217 } |
| 219 } else { | 218 } else { |
| 220 // Register us with the target in the dependencies map. Any change of | 219 // Register us with the target in the dependencies map. Any change of |
| 221 // hrefElement that leads to relayout/repainting now informs us, so we can | 220 // hrefElement that leads to relayout/repainting now informs us, so we can |
| 222 // react to it. | 221 // react to it. |
| 223 addReferenceTo(svgTarget); | 222 addReferenceTo(svgTarget); |
| 224 } | 223 } |
| 225 connectEventBaseConditions(); | 224 connectEventBaseConditions(); |
| 226 } | 225 } |
| 227 | 226 |
| 228 static inline QualifiedName constructQualifiedName( | |
| 229 const SVGElement* svgElement, | |
| 230 const AtomicString& attributeName) { | |
| 231 ASSERT(svgElement); | |
| 232 if (attributeName.isEmpty()) | |
| 233 return anyQName(); | |
| 234 if (!attributeName.contains(':')) | |
| 235 return QualifiedName(nullAtom, attributeName, nullAtom); | |
| 236 | |
| 237 AtomicString prefix; | |
| 238 AtomicString localName; | |
| 239 if (!Document::parseQualifiedName(attributeName, prefix, localName, | |
| 240 IGNORE_EXCEPTION)) | |
| 241 return anyQName(); | |
| 242 | |
| 243 const AtomicString& namespaceURI = svgElement->lookupNamespaceURI(prefix); | |
| 244 if (namespaceURI.isEmpty()) | |
| 245 return anyQName(); | |
| 246 | |
| 247 QualifiedName resolvedAttrName(nullAtom, localName, namespaceURI); | |
| 248 // "Animation elements treat attributeName='xlink:href' as being an alias | |
| 249 // for targetting the 'href' attribute." | |
| 250 // https://svgwg.org/svg2-draft/types.html#__svg__SVGURIReference__href | |
| 251 if (resolvedAttrName == XLinkNames::hrefAttr) | |
| 252 return SVGNames::hrefAttr; | |
| 253 return resolvedAttrName; | |
| 254 } | |
| 255 | |
| 256 static inline void clearTimesWithDynamicOrigins( | 227 static inline void clearTimesWithDynamicOrigins( |
| 257 Vector<SMILTimeWithOrigin>& timeList) { | 228 Vector<SMILTimeWithOrigin>& timeList) { |
| 258 for (int i = timeList.size() - 1; i >= 0; --i) { | 229 for (int i = timeList.size() - 1; i >= 0; --i) { |
| 259 if (timeList[i].originIsScript()) | 230 if (timeList[i].originIsScript()) |
| 260 timeList.remove(i); | 231 timeList.remove(i); |
| 261 } | 232 } |
| 262 } | 233 } |
| 263 | 234 |
| 264 void SVGSMILElement::reset() { | 235 void SVGSMILElement::reset() { |
| 265 clearAnimatedType(); | 236 clearAnimatedType(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 279 ContainerNode* rootParent) { | 250 ContainerNode* rootParent) { |
| 280 SVGElement::insertedInto(rootParent); | 251 SVGElement::insertedInto(rootParent); |
| 281 | 252 |
| 282 if (!rootParent->isConnected()) | 253 if (!rootParent->isConnected()) |
| 283 return InsertionDone; | 254 return InsertionDone; |
| 284 | 255 |
| 285 UseCounter::count(document(), UseCounter::SVGSMILElementInDocument); | 256 UseCounter::count(document(), UseCounter::SVGSMILElementInDocument); |
| 286 if (document().isLoadCompleted()) | 257 if (document().isLoadCompleted()) |
| 287 UseCounter::count(&document(), UseCounter::SVGSMILElementInsertedAfterLoad); | 258 UseCounter::count(&document(), UseCounter::SVGSMILElementInsertedAfterLoad); |
| 288 | 259 |
| 289 setAttributeName(constructQualifiedName( | |
| 290 this, fastGetAttribute(SVGNames::attributeNameAttr))); | |
| 291 SVGSVGElement* owner = ownerSVGElement(); | 260 SVGSVGElement* owner = ownerSVGElement(); |
| 292 if (!owner) | 261 if (!owner) |
| 293 return InsertionDone; | 262 return InsertionDone; |
| 294 | 263 |
| 295 m_timeContainer = owner->timeContainer(); | 264 m_timeContainer = owner->timeContainer(); |
| 296 ASSERT(m_timeContainer); | 265 ASSERT(m_timeContainer); |
| 297 m_timeContainer->setDocumentOrderIndexesDirty(); | 266 m_timeContainer->setDocumentOrderIndexesDirty(); |
| 298 | 267 |
| 299 // "If no attribute is present, the default begin value (an offset-value of 0) | 268 // "If no attribute is present, the default begin value (an offset-value of 0) |
| 300 // must be evaluated." | 269 // must be evaluated." |
| 301 if (!fastHasAttribute(SVGNames::beginAttr)) | 270 if (!fastHasAttribute(SVGNames::beginAttr)) |
| 302 m_beginTimes.append(SMILTimeWithOrigin()); | 271 m_beginTimes.append(SMILTimeWithOrigin()); |
| 303 | 272 |
| 304 if (m_isWaitingForFirstInterval) | 273 if (m_isWaitingForFirstInterval) |
| 305 resolveFirstInterval(); | 274 resolveFirstInterval(); |
| 306 | 275 |
| 307 if (m_timeContainer) | 276 if (m_timeContainer) |
| 308 m_timeContainer->notifyIntervalsChanged(); | 277 m_timeContainer->notifyIntervalsChanged(); |
| 309 | 278 |
| 310 buildPendingResource(); | 279 buildPendingResource(); |
| 311 | 280 |
| 312 return InsertionDone; | 281 return InsertionDone; |
| 313 } | 282 } |
| 314 | 283 |
| 315 void SVGSMILElement::removedFrom(ContainerNode* rootParent) { | 284 void SVGSMILElement::removedFrom(ContainerNode* rootParent) { |
| 316 if (rootParent->isConnected()) { | 285 if (rootParent->isConnected()) { |
| 317 clearResourceAndEventBaseReferences(); | 286 clearResourceAndEventBaseReferences(); |
| 318 clearConditions(); | 287 clearConditions(); |
| 319 setTargetElement(nullptr); | 288 setTargetElement(nullptr); |
| 320 setAttributeName(anyQName()); | |
| 321 animationAttributeChanged(); | 289 animationAttributeChanged(); |
| 322 m_timeContainer = nullptr; | 290 m_timeContainer = nullptr; |
| 323 } | 291 } |
| 324 | 292 |
| 325 SVGElement::removedFrom(rootParent); | 293 SVGElement::removedFrom(rootParent); |
| 326 } | 294 } |
| 327 | 295 |
| 328 SMILTime SVGSMILElement::parseOffsetValue(const String& data) { | 296 SMILTime SVGSMILElement::parseOffsetValue(const String& data) { |
| 329 bool ok; | 297 bool ok; |
| 330 double result = 0; | 298 double result = 0; |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 517 if (attrName == SVGNames::durAttr) { | 485 if (attrName == SVGNames::durAttr) { |
| 518 m_cachedDur = invalidCachedTime; | 486 m_cachedDur = invalidCachedTime; |
| 519 } else if (attrName == SVGNames::repeatDurAttr) { | 487 } else if (attrName == SVGNames::repeatDurAttr) { |
| 520 m_cachedRepeatDur = invalidCachedTime; | 488 m_cachedRepeatDur = invalidCachedTime; |
| 521 } else if (attrName == SVGNames::repeatCountAttr) { | 489 } else if (attrName == SVGNames::repeatCountAttr) { |
| 522 m_cachedRepeatCount = invalidCachedTime; | 490 m_cachedRepeatCount = invalidCachedTime; |
| 523 } else if (attrName == SVGNames::minAttr) { | 491 } else if (attrName == SVGNames::minAttr) { |
| 524 m_cachedMin = invalidCachedTime; | 492 m_cachedMin = invalidCachedTime; |
| 525 } else if (attrName == SVGNames::maxAttr) { | 493 } else if (attrName == SVGNames::maxAttr) { |
| 526 m_cachedMax = invalidCachedTime; | 494 m_cachedMax = invalidCachedTime; |
| 527 } else if (attrName == SVGNames::attributeNameAttr) { | |
| 528 setAttributeName(constructQualifiedName( | |
| 529 this, fastGetAttribute(SVGNames::attributeNameAttr))); | |
| 530 } else if (attrName.matches(SVGNames::hrefAttr) || | 495 } else if (attrName.matches(SVGNames::hrefAttr) || |
| 531 attrName.matches(XLinkNames::hrefAttr)) { | 496 attrName.matches(XLinkNames::hrefAttr)) { |
| 532 // TODO(fs): Could be smarter here when 'href' is specified and 'xlink:href' | 497 // TODO(fs): Could be smarter here when 'href' is specified and 'xlink:href' |
| 533 // is changed. | 498 // is changed. |
| 534 SVGElement::InvalidationGuard invalidationGuard(this); | 499 SVGElement::InvalidationGuard invalidationGuard(this); |
| 535 buildPendingResource(); | 500 buildPendingResource(); |
| 536 if (m_targetElement) | 501 if (m_targetElement) |
| 537 clearAnimatedType(); | 502 clearAnimatedType(); |
| 538 } else if (attrName == SVGNames::beginAttr || attrName == SVGNames::endAttr) { | 503 } else if (attrName == SVGNames::beginAttr || attrName == SVGNames::endAttr) { |
| 539 if (isConnected()) { | 504 if (isConnected()) { |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 SVGElement* eventBase = eventBaseFor(*condition); | 601 SVGElement* eventBase = eventBaseFor(*condition); |
| 637 if (eventBase) | 602 if (eventBase) |
| 638 eventBase->removeEventListener(AtomicString(condition->name()), | 603 eventBase->removeEventListener(AtomicString(condition->name()), |
| 639 condition->eventListener(), false); | 604 condition->eventListener(), false); |
| 640 condition->eventListener()->disconnectAnimation(); | 605 condition->eventListener()->disconnectAnimation(); |
| 641 condition->setEventListener(nullptr); | 606 condition->setEventListener(nullptr); |
| 642 } | 607 } |
| 643 } | 608 } |
| 644 } | 609 } |
| 645 | 610 |
| 646 void SVGSMILElement::setAttributeName(const QualifiedName& attributeName) { | |
| 647 unscheduleIfScheduled(); | |
| 648 if (m_targetElement) | |
| 649 clearAnimatedType(); | |
| 650 m_attributeName = attributeName; | |
| 651 schedule(); | |
| 652 } | |
| 653 | |
| 654 void SVGSMILElement::setTargetElement(SVGElement* target) { | 611 void SVGSMILElement::setTargetElement(SVGElement* target) { |
| 655 unscheduleIfScheduled(); | 612 unscheduleIfScheduled(); |
| 656 | 613 |
| 657 if (m_targetElement) { | 614 if (m_targetElement) { |
| 658 // Clear values that may depend on the previous target. | 615 // Clear values that may depend on the previous target. |
| 659 clearAnimatedType(); | 616 clearAnimatedType(); |
| 660 disconnectSyncBaseConditions(); | 617 disconnectSyncBaseConditions(); |
| 661 } | 618 } |
| 662 | 619 |
| 663 // If the animation state is not Inactive, always reset to a clear state | 620 // If the animation state is not Inactive, always reset to a clear state |
| (...skipping 688 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1352 DEFINE_TRACE(SVGSMILElement) { | 1309 DEFINE_TRACE(SVGSMILElement) { |
| 1353 visitor->trace(m_targetElement); | 1310 visitor->trace(m_targetElement); |
| 1354 visitor->trace(m_timeContainer); | 1311 visitor->trace(m_timeContainer); |
| 1355 visitor->trace(m_conditions); | 1312 visitor->trace(m_conditions); |
| 1356 visitor->trace(m_syncBaseDependents); | 1313 visitor->trace(m_syncBaseDependents); |
| 1357 SVGElement::trace(visitor); | 1314 SVGElement::trace(visitor); |
| 1358 SVGTests::trace(visitor); | 1315 SVGTests::trace(visitor); |
| 1359 } | 1316 } |
| 1360 | 1317 |
| 1361 } // namespace blink | 1318 } // namespace blink |
| OLD | NEW |