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 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |