| 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 |