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

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: rebaselined 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
« no previous file with comments | « Source/core/svg/animation/SVGSMILElement.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"));
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 683 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 dispatchRepeatEvents(repeat);
1129 1125
1130 updateAnimation(percent, repeat, resultElement); 1126 updateAnimation(percent, repeat, resultElement);
1131 m_lastPercent = percent; 1127 m_lastPercent = percent;
1132 m_lastRepeat = repeat; 1128 m_lastRepeat = repeat;
1133 } 1129 }
1134 1130
1135 if (oldActiveState == Active && m_activeState != Active) { 1131 if (oldActiveState == Active && m_activeState != Active) {
1136 smilEndEventSender().dispatchEventSoon(this); 1132 smilEndEventSender().dispatchEventSoon(this);
1137 endedActiveInterval(); 1133 endedActiveInterval();
1138 if (m_activeState != Frozen && this == resultElement) 1134 if (m_activeState != Frozen && this == resultElement)
1139 clearAnimatedType(m_targetElement); 1135 clearAnimatedType(m_targetElement);
1140 } 1136 }
1141 1137
1142 // Triggering all the pending events if the animation timeline is changed. 1138 // Triggering all the pending events if the animation timeline is changed.
1143 if (seekToTime) { 1139 if (seekToTime) {
1144 if (m_activeState == Inactive) 1140 if (m_activeState == Inactive)
1145 smilBeginEventSender().dispatchEventSoon(this); 1141 smilBeginEventSender().dispatchEventSoon(this);
1146 1142
1147 if (repeat) { 1143 if (repeat) {
1148 for (unsigned repeatEventCount = 1; repeatEventCount < repeat; repea tEventCount++) { 1144 for (unsigned repeatEventCount = 1; repeatEventCount < repeat; repea tEventCount++)
1149 smilRepeatEventSender().dispatchEventSoon(this); 1145 dispatchRepeatEvents(repeatEventCount);
1150 }
1151 if (m_activeState == Inactive) 1146 if (m_activeState == Inactive)
1152 smilRepeatEventSender().dispatchEventSoon(this); 1147 dispatchRepeatEvents(repeat);
1153 } 1148 }
1154 1149
1155 if (m_activeState == Inactive || m_activeState == Frozen) 1150 if (m_activeState == Inactive || m_activeState == Frozen)
1156 smilEndEventSender().dispatchEventSoon(this); 1151 smilEndEventSender().dispatchEventSoon(this);
1157 } 1152 }
1158 1153
1159 m_nextProgressTime = calculateNextProgressTime(elapsed); 1154 m_nextProgressTime = calculateNextProgressTime(elapsed);
1160 return animationIsContributing; 1155 return animationIsContributing;
1161 } 1156 }
1162 1157
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1225 SMILTime elapsed = this->elapsed(); 1220 SMILTime elapsed = this->elapsed();
1226 addBeginTime(elapsed, elapsed); 1221 addBeginTime(elapsed, elapsed);
1227 } 1222 }
1228 1223
1229 void SVGSMILElement::endedActiveInterval() 1224 void SVGSMILElement::endedActiveInterval()
1230 { 1225 {
1231 clearTimesWithDynamicOrigins(m_beginTimes); 1226 clearTimesWithDynamicOrigins(m_beginTimes);
1232 clearTimesWithDynamicOrigins(m_endTimes); 1227 clearTimesWithDynamicOrigins(m_endTimes);
1233 } 1228 }
1234 1229
1230 void SVGSMILElement::dispatchRepeatEvents(unsigned count)
1231 {
1232 m_repeatEventCountList.append(count);
1233 smilRepeatEventSender().dispatchEventSoon(this);
1234 smilRepeatNEventSender().dispatchEventSoon(this);
1235 }
1236
1235 void SVGSMILElement::dispatchPendingEvent(SMILEventSender* eventSender) 1237 void SVGSMILElement::dispatchPendingEvent(SMILEventSender* eventSender)
1236 { 1238 {
1237 ASSERT(eventSender == &smilEndEventSender() || eventSender == &smilBeginEven tSender() || eventSender == &smilRepeatEventSender()); 1239 ASSERT(eventSender == &smilEndEventSender() || eventSender == &smilBeginEven tSender() || eventSender == &smilRepeatEventSender() || eventSender == &smilRepe atNEventSender());
1238 const AtomicString& eventType = eventSender->eventType(); 1240 const AtomicString& eventType = eventSender->eventType();
1239 dispatchEvent(Event::create(eventType)); 1241 if (eventType == "repeatn") {
1242 unsigned repeatEventCount = m_repeatEventCountList.first();
1243 m_repeatEventCountList.remove(0);
1244 dispatchEvent(Event::create(String("repeat(" + String::number(repeatEven tCount) + ")")));
1245 } else {
1246 dispatchEvent(Event::create(eventType));
1247 }
1240 } 1248 }
1241 1249
1242 } 1250 }
OLDNEW
« no previous file with comments | « Source/core/svg/animation/SVGSMILElement.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698