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 27 matching lines...) Expand all Loading... |
38 #include "core/svg/SVGURIReference.h" | 38 #include "core/svg/SVGURIReference.h" |
39 #include "core/svg/animation/SMILTimeContainer.h" | 39 #include "core/svg/animation/SMILTimeContainer.h" |
40 #include "wtf/MathExtras.h" | 40 #include "wtf/MathExtras.h" |
41 #include "wtf/StdLibExtras.h" | 41 #include "wtf/StdLibExtras.h" |
42 #include "wtf/Vector.h" | 42 #include "wtf/Vector.h" |
43 | 43 |
44 using namespace std; | 44 using namespace std; |
45 | 45 |
46 namespace WebCore { | 46 namespace WebCore { |
47 | 47 |
| 48 class RepeatEvent : public Event { |
| 49 public: |
| 50 static PassRefPtr<RepeatEvent> create(const AtomicString& type, int repeat) |
| 51 { |
| 52 return adoptRef(new RepeatEvent(type, false, false, repeat)); |
| 53 } |
| 54 |
| 55 ~RepeatEvent() { } |
| 56 |
| 57 int repeat() const { return m_repeat; } |
| 58 protected: |
| 59 RepeatEvent(const AtomicString& type, bool canBubble, bool cancelable, int r
epeat = -1) |
| 60 : Event(type, canBubble, cancelable) |
| 61 , m_repeat(repeat) |
| 62 { |
| 63 } |
| 64 private: |
| 65 int m_repeat; |
| 66 }; |
| 67 |
| 68 inline RepeatEvent* toRepeatEvent(Event* event) |
| 69 { |
| 70 ASSERT_WITH_SECURITY_IMPLICATION(!event || event->type() == "repeatn"); |
| 71 return static_cast<RepeatEvent*>(event); |
| 72 } |
| 73 |
48 static SMILEventSender& smilEndEventSender() | 74 static SMILEventSender& smilEndEventSender() |
49 { | 75 { |
50 DEFINE_STATIC_LOCAL(SMILEventSender, sender, ("endEvent")); | 76 DEFINE_STATIC_LOCAL(SMILEventSender, sender, ("endEvent")); |
51 return sender; | 77 return sender; |
52 } | 78 } |
53 | 79 |
54 static SMILEventSender& smilBeginEventSender() | 80 static SMILEventSender& smilBeginEventSender() |
55 { | 81 { |
56 DEFINE_STATIC_LOCAL(SMILEventSender, sender, ("beginEvent")); | 82 DEFINE_STATIC_LOCAL(SMILEventSender, sender, ("beginEvent")); |
57 return sender; | 83 return sender; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 return false; | 140 return false; |
115 } | 141 } |
116 | 142 |
117 void ConditionEventListener::handleEvent(ScriptExecutionContext*, Event* event) | 143 void ConditionEventListener::handleEvent(ScriptExecutionContext*, Event* event) |
118 { | 144 { |
119 if (!m_animation) | 145 if (!m_animation) |
120 return; | 146 return; |
121 m_animation->handleConditionEvent(event, m_condition); | 147 m_animation->handleConditionEvent(event, m_condition); |
122 } | 148 } |
123 | 149 |
124 SVGSMILElement::Condition::Condition(Type type, BeginOrEnd beginOrEnd, const Str
ing& baseID, const String& name, SMILTime offset) | 150 SVGSMILElement::Condition::Condition(Type type, BeginOrEnd beginOrEnd, const Str
ing& baseID, const String& name, SMILTime offset, int repeat) |
125 : m_type(type) | 151 : m_type(type) |
126 , m_beginOrEnd(beginOrEnd) | 152 , m_beginOrEnd(beginOrEnd) |
127 , m_baseID(baseID) | 153 , m_baseID(baseID) |
128 , m_name(name) | 154 , m_name(name) |
129 , m_offset(offset) | 155 , m_offset(offset) |
| 156 , m_repeat(repeat) |
130 { | 157 { |
131 } | 158 } |
132 | 159 |
133 SVGSMILElement::SVGSMILElement(const QualifiedName& tagName, Document& doc) | 160 SVGSMILElement::SVGSMILElement(const QualifiedName& tagName, Document& doc) |
134 : SVGElement(tagName, doc) | 161 : SVGElement(tagName, doc) |
135 , m_attributeName(anyQName()) | 162 , m_attributeName(anyQName()) |
136 , m_targetElement(0) | 163 , m_targetElement(0) |
137 , m_conditionsConnected(false) | 164 , m_conditionsConnected(false) |
138 , m_hasEndEventConditions(false) | 165 , m_hasEndEventConditions(false) |
139 , m_isWaitingForFirstInterval(true) | 166 , m_isWaitingForFirstInterval(true) |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 static void sortTimeList(Vector<SMILTimeWithOrigin>& timeList) | 393 static void sortTimeList(Vector<SMILTimeWithOrigin>& timeList) |
367 { | 394 { |
368 std::sort(timeList.begin(), timeList.end()); | 395 std::sort(timeList.begin(), timeList.end()); |
369 } | 396 } |
370 | 397 |
371 bool SVGSMILElement::parseCondition(const String& value, BeginOrEnd beginOrEnd) | 398 bool SVGSMILElement::parseCondition(const String& value, BeginOrEnd beginOrEnd) |
372 { | 399 { |
373 String parseString = value.stripWhiteSpace(); | 400 String parseString = value.stripWhiteSpace(); |
374 | 401 |
375 double sign = 1.; | 402 double sign = 1.; |
| 403 bool ok; |
376 size_t pos = parseString.find('+'); | 404 size_t pos = parseString.find('+'); |
377 if (pos == notFound) { | 405 if (pos == notFound) { |
378 pos = parseString.find('-'); | 406 pos = parseString.find('-'); |
379 if (pos != notFound) | 407 if (pos != notFound) |
380 sign = -1.; | 408 sign = -1.; |
381 } | 409 } |
382 String conditionString; | 410 String conditionString; |
383 SMILTime offset = 0; | 411 SMILTime offset = 0; |
384 if (pos == notFound) | 412 if (pos == notFound) |
385 conditionString = parseString; | 413 conditionString = parseString; |
(...skipping 14 matching lines...) Expand all Loading... |
400 if (pos == notFound) | 428 if (pos == notFound) |
401 nameString = conditionString; | 429 nameString = conditionString; |
402 else { | 430 else { |
403 baseID = conditionString.left(pos); | 431 baseID = conditionString.left(pos); |
404 nameString = conditionString.substring(pos + 1); | 432 nameString = conditionString.substring(pos + 1); |
405 } | 433 } |
406 if (nameString.isEmpty()) | 434 if (nameString.isEmpty()) |
407 return false; | 435 return false; |
408 | 436 |
409 Condition::Type type; | 437 Condition::Type type; |
410 if (nameString == "begin" || nameString == "end") { | 438 int repeat = -1; |
| 439 if (nameString.startsWith("repeat(") && nameString.endsWith(')')) { |
| 440 repeat = nameString.substring(7, nameString.length() - 8).toUIntStrict(&
ok); |
| 441 if (!ok) |
| 442 return false; |
| 443 nameString = "repeatn"; |
| 444 type = Condition::EventBase; |
| 445 } else if (nameString == "begin" || nameString == "end") { |
411 if (baseID.isEmpty()) | 446 if (baseID.isEmpty()) |
412 return false; | 447 return false; |
413 type = Condition::Syncbase; | 448 type = Condition::Syncbase; |
414 } else if (nameString.startsWith("accesskey(")) { | 449 } else if (nameString.startsWith("accesskey(")) { |
415 // FIXME: accesskey() support. | 450 // FIXME: accesskey() support. |
416 type = Condition::AccessKey; | 451 type = Condition::AccessKey; |
417 } else | 452 } else |
418 type = Condition::EventBase; | 453 type = Condition::EventBase; |
419 | 454 |
420 m_conditions.append(Condition(type, beginOrEnd, baseID, nameString, offset))
; | 455 m_conditions.append(Condition(type, beginOrEnd, baseID, nameString, offset,
repeat)); |
421 | 456 |
422 if (type == Condition::EventBase && beginOrEnd == End) | 457 if (type == Condition::EventBase && beginOrEnd == End) |
423 m_hasEndEventConditions = true; | 458 m_hasEndEventConditions = true; |
424 | 459 |
425 return true; | 460 return true; |
426 } | 461 } |
427 | 462 |
428 bool SVGSMILElement::isSMILElement(Node* node) | 463 bool SVGSMILElement::isSMILElement(Node* node) |
429 { | 464 { |
430 if (!node) | 465 if (!node) |
(...skipping 773 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1204 m_timeDependents.add(animation); | 1239 m_timeDependents.add(animation); |
1205 if (m_intervalBegin.isFinite()) | 1240 if (m_intervalBegin.isFinite()) |
1206 animation->createInstanceTimesFromSyncbase(this, NewInterval); | 1241 animation->createInstanceTimesFromSyncbase(this, NewInterval); |
1207 } | 1242 } |
1208 | 1243 |
1209 void SVGSMILElement::removeTimeDependent(SVGSMILElement* animation) | 1244 void SVGSMILElement::removeTimeDependent(SVGSMILElement* animation) |
1210 { | 1245 { |
1211 m_timeDependents.remove(animation); | 1246 m_timeDependents.remove(animation); |
1212 } | 1247 } |
1213 | 1248 |
1214 void SVGSMILElement::handleConditionEvent(Event*, Condition* condition) | 1249 void SVGSMILElement::handleConditionEvent(Event* event, Condition* condition) |
1215 { | 1250 { |
| 1251 if (event->type() == "repeatn" && toRepeatEvent(event)->repeat() != conditio
n->m_repeat) |
| 1252 return; |
| 1253 |
1216 SMILTime elapsed = this->elapsed(); | 1254 SMILTime elapsed = this->elapsed(); |
1217 if (condition->m_beginOrEnd == Begin) | 1255 if (condition->m_beginOrEnd == Begin) |
1218 addBeginTime(elapsed, elapsed + condition->m_offset); | 1256 addBeginTime(elapsed, elapsed + condition->m_offset); |
1219 else | 1257 else |
1220 addEndTime(elapsed, elapsed + condition->m_offset); | 1258 addEndTime(elapsed, elapsed + condition->m_offset); |
1221 } | 1259 } |
1222 | 1260 |
1223 void SVGSMILElement::beginByLinkActivation() | 1261 void SVGSMILElement::beginByLinkActivation() |
1224 { | 1262 { |
1225 SMILTime elapsed = this->elapsed(); | 1263 SMILTime elapsed = this->elapsed(); |
(...skipping 13 matching lines...) Expand all Loading... |
1239 smilRepeatNEventSender().dispatchEventSoon(this); | 1277 smilRepeatNEventSender().dispatchEventSoon(this); |
1240 } | 1278 } |
1241 | 1279 |
1242 void SVGSMILElement::dispatchPendingEvent(SMILEventSender* eventSender) | 1280 void SVGSMILElement::dispatchPendingEvent(SMILEventSender* eventSender) |
1243 { | 1281 { |
1244 ASSERT(eventSender == &smilEndEventSender() || eventSender == &smilBeginEven
tSender() || eventSender == &smilRepeatEventSender() || eventSender == &smilRepe
atNEventSender()); | 1282 ASSERT(eventSender == &smilEndEventSender() || eventSender == &smilBeginEven
tSender() || eventSender == &smilRepeatEventSender() || eventSender == &smilRepe
atNEventSender()); |
1245 const AtomicString& eventType = eventSender->eventType(); | 1283 const AtomicString& eventType = eventSender->eventType(); |
1246 if (eventType == "repeatn") { | 1284 if (eventType == "repeatn") { |
1247 unsigned repeatEventCount = m_repeatEventCountList.first(); | 1285 unsigned repeatEventCount = m_repeatEventCountList.first(); |
1248 m_repeatEventCountList.remove(0); | 1286 m_repeatEventCountList.remove(0); |
1249 dispatchEvent(Event::create(String("repeat(" + String::number(repeatEven
tCount) + ")"))); | 1287 dispatchEvent(RepeatEvent::create(eventType, repeatEventCount)); |
1250 } else { | 1288 } else { |
1251 dispatchEvent(Event::create(eventType)); | 1289 dispatchEvent(Event::create(eventType)); |
1252 } | 1290 } |
1253 } | 1291 } |
1254 | 1292 |
1255 } | 1293 } |
OLD | NEW |