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

Side by Side Diff: Source/core/svg/animation/SVGSMILElement.cpp

Issue 23823006: [SVG] Handle repeat(n) event for svg animations (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 7 years, 3 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) 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
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 DEFINE_STATIC_LOCAL(SMILEventSender, sender, ("beginEvent")); 56 DEFINE_STATIC_LOCAL(SMILEventSender, sender, ("beginEvent"));
57 return sender; 57 return sender;
58 } 58 }
59 59
60 static SMILEventSender& smilRepeatEventSender() 60 static SMILEventSender& smilRepeatEventSender()
61 { 61 {
62 DEFINE_STATIC_LOCAL(SMILEventSender, sender, ("repeatEvent")); 62 DEFINE_STATIC_LOCAL(SMILEventSender, sender, ("repeatEvent"));
63 return sender; 63 return sender;
64 } 64 }
65 65
66 static SMILEventSender& smilRepeatNEventSender()
67 {
68 DEFINE_STATIC_LOCAL(SMILEventSender, sender, ("repeatn"));
pdr. 2013/09/03 17:48:14 repeatNEvent?
pavane 2013/09/03 19:00:52 yes, i felt this name is the closest to represent
69 return sender;
70 }
71
66 // This is used for duration type time values that can't be negative. 72 // This is used for duration type time values that can't be negative.
67 static const double invalidCachedTime = -1.; 73 static const double invalidCachedTime = -1.;
68 74
69 class ConditionEventListener : public EventListener { 75 class ConditionEventListener : public EventListener {
70 public: 76 public:
71 static PassRefPtr<ConditionEventListener> create(SVGSMILElement* animation, SVGSMILElement::Condition* condition) 77 static PassRefPtr<ConditionEventListener> create(SVGSMILElement* animation, SVGSMILElement::Condition* condition)
72 { 78 {
73 return adoptRef(new ConditionEventListener(animation, condition)); 79 return adoptRef(new ConditionEventListener(animation, condition));
74 } 80 }
75 81
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 return false; 114 return false;
109 } 115 }
110 116
111 void ConditionEventListener::handleEvent(ScriptExecutionContext*, Event* event) 117 void ConditionEventListener::handleEvent(ScriptExecutionContext*, Event* event)
112 { 118 {
113 if (!m_animation) 119 if (!m_animation)
114 return; 120 return;
115 m_animation->handleConditionEvent(event, m_condition); 121 m_animation->handleConditionEvent(event, m_condition);
116 } 122 }
117 123
118 SVGSMILElement::Condition::Condition(Type type, BeginOrEnd beginOrEnd, const Str ing& baseID, const String& name, SMILTime offset, int repeats) 124 SVGSMILElement::Condition::Condition(Type type, BeginOrEnd beginOrEnd, const Str ing& baseID, const String& name, SMILTime offset)
119 : m_type(type) 125 : m_type(type)
120 , m_beginOrEnd(beginOrEnd) 126 , m_beginOrEnd(beginOrEnd)
121 , m_baseID(baseID) 127 , m_baseID(baseID)
122 , m_name(name) 128 , m_name(name)
123 , m_offset(offset) 129 , m_offset(offset)
124 , m_repeats(repeats)
125 { 130 {
126 } 131 }
127 132
128 SVGSMILElement::SVGSMILElement(const QualifiedName& tagName, Document* doc) 133 SVGSMILElement::SVGSMILElement(const QualifiedName& tagName, Document* doc)
129 : SVGElement(tagName, doc) 134 : SVGElement(tagName, doc)
130 , m_attributeName(anyQName()) 135 , m_attributeName(anyQName())
131 , m_targetElement(0) 136 , m_targetElement(0)
132 , m_conditionsConnected(false) 137 , m_conditionsConnected(false)
133 , m_hasEndEventConditions(false) 138 , m_hasEndEventConditions(false)
134 , m_isWaitingForFirstInterval(true) 139 , m_isWaitingForFirstInterval(true)
(...skipping 13 matching lines...) Expand all
148 { 153 {
149 resolveFirstInterval(); 154 resolveFirstInterval();
150 } 155 }
151 156
152 SVGSMILElement::~SVGSMILElement() 157 SVGSMILElement::~SVGSMILElement()
153 { 158 {
154 clearResourceReferences(); 159 clearResourceReferences();
155 smilEndEventSender().cancelEvent(this); 160 smilEndEventSender().cancelEvent(this);
156 smilBeginEventSender().cancelEvent(this); 161 smilBeginEventSender().cancelEvent(this);
157 smilRepeatEventSender().cancelEvent(this); 162 smilRepeatEventSender().cancelEvent(this);
163 smilRepeatNEventSender().cancelEvent(this);
158 disconnectConditions(); 164 disconnectConditions();
159 if (m_timeContainer && m_targetElement && hasValidAttributeName()) 165 if (m_timeContainer && m_targetElement && hasValidAttributeName())
160 m_timeContainer->unschedule(this, m_targetElement, m_attributeName); 166 m_timeContainer->unschedule(this, m_targetElement, m_attributeName);
161 } 167 }
162 168
163 void SVGSMILElement::clearResourceReferences() 169 void SVGSMILElement::clearResourceReferences()
164 { 170 {
165 document().accessSVGExtensions()->removeAllTargetReferencesForElement(this); 171 document().accessSVGExtensions()->removeAllTargetReferencesForElement(this);
166 } 172 }
167 173
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 static void sortTimeList(Vector<SMILTimeWithOrigin>& timeList) 366 static void sortTimeList(Vector<SMILTimeWithOrigin>& timeList)
361 { 367 {
362 std::sort(timeList.begin(), timeList.end()); 368 std::sort(timeList.begin(), timeList.end());
363 } 369 }
364 370
365 bool SVGSMILElement::parseCondition(const String& value, BeginOrEnd beginOrEnd) 371 bool SVGSMILElement::parseCondition(const String& value, BeginOrEnd beginOrEnd)
366 { 372 {
367 String parseString = value.stripWhiteSpace(); 373 String parseString = value.stripWhiteSpace();
368 374
369 double sign = 1.; 375 double sign = 1.;
370 bool ok;
371 size_t pos = parseString.find('+'); 376 size_t pos = parseString.find('+');
372 if (pos == notFound) { 377 if (pos == notFound) {
373 pos = parseString.find('-'); 378 pos = parseString.find('-');
374 if (pos != notFound) 379 if (pos != notFound)
375 sign = -1.; 380 sign = -1.;
376 } 381 }
377 String conditionString; 382 String conditionString;
378 SMILTime offset = 0; 383 SMILTime offset = 0;
379 if (pos == notFound) 384 if (pos == notFound)
380 conditionString = parseString; 385 conditionString = parseString;
(...skipping 14 matching lines...) Expand all
395 if (pos == notFound) 400 if (pos == notFound)
396 nameString = conditionString; 401 nameString = conditionString;
397 else { 402 else {
398 baseID = conditionString.left(pos); 403 baseID = conditionString.left(pos);
399 nameString = conditionString.substring(pos + 1); 404 nameString = conditionString.substring(pos + 1);
400 } 405 }
401 if (nameString.isEmpty()) 406 if (nameString.isEmpty())
402 return false; 407 return false;
403 408
404 Condition::Type type; 409 Condition::Type type;
405 int repeats = -1; 410 if (nameString == "begin" || nameString == "end") {
406 if (nameString.startsWith("repeat(") && nameString.endsWith(')')) {
407 // FIXME: For repeat events we just need to add the data carrying TimeEv ent class and
408 // fire the events at appropiate times.
409 repeats = nameString.substring(7, nameString.length() - 8).toUIntStrict( &ok);
410 if (!ok)
411 return false;
412 nameString = "repeat";
413 type = Condition::EventBase;
414 } else if (nameString == "begin" || nameString == "end") {
415 if (baseID.isEmpty()) 411 if (baseID.isEmpty())
416 return false; 412 return false;
417 type = Condition::Syncbase; 413 type = Condition::Syncbase;
418 } else if (nameString.startsWith("accesskey(")) { 414 } else if (nameString.startsWith("accesskey(")) {
419 // FIXME: accesskey() support. 415 // FIXME: accesskey() support.
420 type = Condition::AccessKey; 416 type = Condition::AccessKey;
421 } else 417 } else
422 type = Condition::EventBase; 418 type = Condition::EventBase;
423 419
424 m_conditions.append(Condition(type, beginOrEnd, baseID, nameString, offset, repeats)); 420 m_conditions.append(Condition(type, beginOrEnd, baseID, nameString, offset)) ;
425 421
426 if (type == Condition::EventBase && beginOrEnd == End) 422 if (type == Condition::EventBase && beginOrEnd == End)
427 m_hasEndEventConditions = true; 423 m_hasEndEventConditions = true;
428 424
429 return true; 425 return true;
430 } 426 }
431 427
432 bool SVGSMILElement::isSMILElement(Node* node) 428 bool SVGSMILElement::isSMILElement(Node* node)
433 { 429 {
434 if (!node) 430 if (!node)
(...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after
1117 // Only reset the animated type to the base value once for the lowest priori ty animation that animates and contributes to a particular element/attribute pai r. 1113 // Only reset the animated type to the base value once for the lowest priori ty animation that animates and contributes to a particular element/attribute pai r.
1118 if (this == resultElement && animationIsContributing) 1114 if (this == resultElement && animationIsContributing)
1119 resetAnimatedType(); 1115 resetAnimatedType();
1120 1116
1121 if (animationIsContributing) { 1117 if (animationIsContributing) {
1122 if (oldActiveState == Inactive) { 1118 if (oldActiveState == Inactive) {
1123 smilBeginEventSender().dispatchEventSoon(this); 1119 smilBeginEventSender().dispatchEventSoon(this);
1124 startedActiveInterval(); 1120 startedActiveInterval();
1125 } 1121 }
1126 1122
1127 if (repeat && repeat != m_lastRepeat) 1123 if (repeat && repeat != m_lastRepeat) {
1128 smilRepeatEventSender().dispatchEventSoon(this); 1124 smilRepeatEventSender().dispatchEventSoon(this);
pdr. 2013/09/03 17:48:14 This code is duplicated 3 times. Can you move it t
pavane 2013/09/03 19:00:52 Done.
1125 m_repeatEventCountList.append(repeat);
1126 smilRepeatNEventSender().dispatchEventSoon(this);
1127 }
1129 1128
1130 updateAnimation(percent, repeat, resultElement); 1129 updateAnimation(percent, repeat, resultElement);
1131 m_lastPercent = percent; 1130 m_lastPercent = percent;
1132 m_lastRepeat = repeat; 1131 m_lastRepeat = repeat;
1133 } 1132 }
1134 1133
1135 if (oldActiveState == Active && m_activeState != Active) { 1134 if (oldActiveState == Active && m_activeState != Active) {
1136 smilEndEventSender().dispatchEventSoon(this); 1135 smilEndEventSender().dispatchEventSoon(this);
1137 endedActiveInterval(); 1136 endedActiveInterval();
1138 if (m_activeState != Frozen && this == resultElement) 1137 if (m_activeState != Frozen && this == resultElement)
1139 clearAnimatedType(m_targetElement); 1138 clearAnimatedType(m_targetElement);
1140 } 1139 }
1141 1140
1142 // Triggering all the pending events if the animation timeline is changed. 1141 // Triggering all the pending events if the animation timeline is changed.
1143 if (seekToTime) { 1142 if (seekToTime) {
1144 if (m_activeState == Inactive) 1143 if (m_activeState == Inactive)
1145 smilBeginEventSender().dispatchEventSoon(this); 1144 smilBeginEventSender().dispatchEventSoon(this);
1146 1145
1147 if (repeat) { 1146 if (repeat) {
1148 for (unsigned repeatEventCount = 1; repeatEventCount < repeat; repea tEventCount++) { 1147 for (unsigned repeatEventCount = 1; repeatEventCount < repeat; repea tEventCount++) {
1149 smilRepeatEventSender().dispatchEventSoon(this); 1148 smilRepeatEventSender().dispatchEventSoon(this);
1149 m_repeatEventCountList.append(repeatEventCount);
1150 smilRepeatNEventSender().dispatchEventSoon(this);
1150 } 1151 }
1151 if (m_activeState == Inactive) 1152 if (m_activeState == Inactive) {
1152 smilRepeatEventSender().dispatchEventSoon(this); 1153 smilRepeatEventSender().dispatchEventSoon(this);
1154 m_repeatEventCountList.append(repeat);
1155 smilRepeatNEventSender().dispatchEventSoon(this);
1156 }
1153 } 1157 }
1154 1158
1155 if (m_activeState == Inactive || m_activeState == Frozen) 1159 if (m_activeState == Inactive || m_activeState == Frozen)
1156 smilEndEventSender().dispatchEventSoon(this); 1160 smilEndEventSender().dispatchEventSoon(this);
1157 } 1161 }
1158 1162
1159 m_nextProgressTime = calculateNextProgressTime(elapsed); 1163 m_nextProgressTime = calculateNextProgressTime(elapsed);
1160 return animationIsContributing; 1164 return animationIsContributing;
1161 } 1165 }
1162 1166
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1227 } 1231 }
1228 1232
1229 void SVGSMILElement::endedActiveInterval() 1233 void SVGSMILElement::endedActiveInterval()
1230 { 1234 {
1231 clearTimesWithDynamicOrigins(m_beginTimes); 1235 clearTimesWithDynamicOrigins(m_beginTimes);
1232 clearTimesWithDynamicOrigins(m_endTimes); 1236 clearTimesWithDynamicOrigins(m_endTimes);
1233 } 1237 }
1234 1238
1235 void SVGSMILElement::dispatchPendingEvent(SMILEventSender* eventSender) 1239 void SVGSMILElement::dispatchPendingEvent(SMILEventSender* eventSender)
1236 { 1240 {
1237 ASSERT(eventSender == &smilEndEventSender() || eventSender == &smilBeginEven tSender() || eventSender == &smilRepeatEventSender()); 1241 ASSERT(eventSender == &smilEndEventSender() || eventSender == &smilBeginEven tSender() || eventSender == &smilRepeatEventSender() || eventSender == &smilRepe atNEventSender());
1238 const AtomicString& eventType = eventSender->eventType(); 1242 const AtomicString& eventType = eventSender->eventType();
1239 dispatchEvent(Event::create(eventType)); 1243 if (eventType == "repeatn") {
1244 unsigned repeatEventCount = m_repeatEventCountList.first();
1245 m_repeatEventCountList.remove(0);
pdr. 2013/09/03 17:48:14 Because this is the only place you remove the even
pavane 2013/09/03 19:00:52 This is not an event list. i am just storing the r
1246 dispatchEvent(Event::create(String("repeat(" + String::number(repeatEven tCount) + ")")));
1247 } else {
1248 dispatchEvent(Event::create(eventType));
1249 }
1240 } 1250 }
1241 1251
1242 } 1252 }
OLDNEW
« LayoutTests/svg/animations/repeatn-event-2a.svg ('K') | « Source/core/svg/animation/SVGSMILElement.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698