]>
Commit | Line | Data |
---|---|---|
6527f429 DM |
1 | \r |
2 | /**\r | |
3 | * @class Ext.ux.event.Driver\r | |
4 | * This is the base class for {@link Recorder} and {@link Player}.\r | |
5 | */\r | |
6 | Ext.define('Ext.ux.event.Driver', {\r | |
7 | active: null,\r | |
8 | mixins: {\r | |
9 | observable: 'Ext.util.Observable'\r | |
10 | },\r | |
11 | \r | |
12 | /**\r | |
13 | * @event start\r | |
14 | * Fires when this object is started.\r | |
15 | * @param {Ext.ux.event.Driver} this\r | |
16 | */\r | |
17 | \r | |
18 | /**\r | |
19 | * @event stop\r | |
20 | * Fires when this object is stopped.\r | |
21 | * @param {Ext.ux.event.Driver} this\r | |
22 | */\r | |
23 | \r | |
24 | constructor: function (config) {\r | |
25 | var me = this;\r | |
26 | \r | |
27 | me.mixins.observable.constructor.apply(this, arguments);\r | |
28 | },\r | |
29 | \r | |
30 | /**\r | |
31 | * Returns the number of milliseconds since start was called.\r | |
32 | */\r | |
33 | getTimestamp: function () {\r | |
34 | var d = new Date();\r | |
35 | return d.getTime() - this.startTime;\r | |
36 | },\r | |
37 | \r | |
38 | onStart: function () {},\r | |
39 | \r | |
40 | onStop: function () {},\r | |
41 | \r | |
42 | /**\r | |
43 | * Starts this object. If this object is already started, nothing happens.\r | |
44 | */\r | |
45 | start: function () {\r | |
46 | var me = this;\r | |
47 | \r | |
48 | if (!me.active) {\r | |
49 | me.active = new Date();\r | |
50 | me.startTime = me.active.getTime();\r | |
51 | me.onStart();\r | |
52 | me.fireEvent('start', me);\r | |
53 | }\r | |
54 | },\r | |
55 | \r | |
56 | /**\r | |
57 | * Stops this object. If this object is not started, nothing happens.\r | |
58 | */\r | |
59 | stop: function () {\r | |
60 | var me = this;\r | |
61 | \r | |
62 | if (me.active) {\r | |
63 | me.active = null;\r | |
64 | me.onStop();\r | |
65 | me.fireEvent('stop', me);\r | |
66 | }\r | |
67 | }\r | |
68 | });\r | |
69 | \r | |
70 | /**\r | |
71 | * @class Ext.ux.event.Player\r | |
72 | * @extends Ext.ux.event.Driver\r | |
73 | *\r | |
74 | * This class manages the playback of an array of "event descriptors". For details on the\r | |
75 | * contents of an "event descriptor", see {@link Recorder}. The events recorded by the\r | |
76 | * {@link Recorder} class are designed to serve as input for this class.\r | |
77 | * \r | |
78 | * The simplest use of this class is to instantiate it with an {@link #eventQueue} and call\r | |
79 | * {@link #start}. Like so:\r | |
80 | *\r | |
81 | * var player = Ext.create('Ext.ux.event.Player', {\r | |
82 | * eventQueue: [ ... ],\r | |
83 | * speed: 2, // play at 2x speed\r | |
84 | * listeners: {\r | |
85 | * stop: function () {\r | |
86 | * player = null; // all done\r | |
87 | * }\r | |
88 | * }\r | |
89 | * });\r | |
90 | *\r | |
91 | * player.start();\r | |
92 | *\r | |
93 | * A more complex use would be to incorporate keyframe generation after playing certain\r | |
94 | * events.\r | |
95 | *\r | |
96 | * var player = Ext.create('Ext.ux.event.Player', {\r | |
97 | * eventQueue: [ ... ],\r | |
98 | * keyFrameEvents: {\r | |
99 | * click: true\r | |
100 | * },\r | |
101 | * listeners: {\r | |
102 | * stop: function () {\r | |
103 | * // play has completed... probably time for another keyframe...\r | |
104 | * player = null;\r | |
105 | * },\r | |
106 | * keyframe: onKeyFrame\r | |
107 | * }\r | |
108 | * });\r | |
109 | *\r | |
110 | * player.start();\r | |
111 | *\r | |
112 | * If a keyframe can be handled immediately (synchronously), the listener would be:\r | |
113 | *\r | |
114 | * function onKeyFrame () {\r | |
115 | * handleKeyFrame();\r | |
116 | * }\r | |
117 | *\r | |
118 | * If the keyframe event is always handled asynchronously, then the event listener is only\r | |
119 | * a bit more:\r | |
120 | *\r | |
121 | * function onKeyFrame (p, eventDescriptor) {\r | |
122 | * eventDescriptor.defer(); // pause event playback...\r | |
123 | *\r | |
124 | * handleKeyFrame(function () {\r | |
125 | * eventDescriptor.finish(); // ...resume event playback\r | |
126 | * });\r | |
127 | * }\r | |
128 | *\r | |
129 | * Finally, if the keyframe could be either handled synchronously or asynchronously (perhaps\r | |
130 | * differently by browser), a slightly more complex listener is required.\r | |
131 | *\r | |
132 | * function onKeyFrame (p, eventDescriptor) {\r | |
133 | * var async;\r | |
134 | *\r | |
135 | * handleKeyFrame(function () {\r | |
136 | * // either this callback is being called immediately by handleKeyFrame (in\r | |
137 | * // which case async is undefined) or it is being called later (in which case\r | |
138 | * // async will be true).\r | |
139 | *\r | |
140 | * if (async) {\r | |
141 | * eventDescriptor.finish();\r | |
142 | * } else {\r | |
143 | * async = false;\r | |
144 | * }\r | |
145 | * });\r | |
146 | *\r | |
147 | * // either the callback was called (and async is now false) or it was not\r | |
148 | * // called (and async remains undefined).\r | |
149 | *\r | |
150 | * if (async !== false) {\r | |
151 | * eventDescriptor.defer();\r | |
152 | * async = true; // let the callback know that we have gone async\r | |
153 | * }\r | |
154 | * }\r | |
155 | */\r | |
156 | Ext.define('Ext.ux.event.Player', {\r | |
157 | extend: 'Ext.ux.event.Driver',\r | |
158 | \r | |
159 | /**\r | |
160 | * @cfg {Array} eventQueue The event queue to playback. This must be provided before\r | |
161 | * the {@link #start} method is called.\r | |
162 | */\r | |
163 | \r | |
164 | /**\r | |
165 | * @cfg {Object} keyFrameEvents An object that describes the events that should generate\r | |
166 | * keyframe events. For example, `{ click: true }` would generate keyframe events after\r | |
167 | * each `click` event.\r | |
168 | */\r | |
169 | keyFrameEvents: {\r | |
170 | click: true\r | |
171 | },\r | |
172 | \r | |
173 | /**\r | |
174 | * @cfg {Boolean} pauseForAnimations True to pause event playback during animations, false\r | |
175 | * to ignore animations. Default is true.\r | |
176 | */\r | |
177 | pauseForAnimations: true,\r | |
178 | \r | |
179 | /**\r | |
180 | * @cfg {Number} speed The playback speed multiplier. Default is 1.0 (to playback at the\r | |
181 | * recorded speed). A value of 2 would playback at 2x speed.\r | |
182 | */\r | |
183 | speed: 1.0,\r | |
184 | \r | |
185 | tagPathRegEx: /(\w+)(?:\[(\d+)\])?/,\r | |
186 | \r | |
187 | \r | |
188 | screenshotTimeout: 500,\r | |
189 | \r | |
190 | /**\r | |
191 | * @event beforeplay\r | |
192 | * Fires before an event is played.\r | |
193 | * @param {Ext.ux.event.Player} this\r | |
194 | * @param {Object} eventDescriptor The event descriptor about to be played.\r | |
195 | */\r | |
196 | \r | |
197 | /**\r | |
198 | * @event keyframe\r | |
199 | * Fires when this player reaches a keyframe. Typically, this is after events\r | |
200 | * like `click` are injected and any resulting animations have been completed.\r | |
201 | * @param {Ext.ux.event.Player} this\r | |
202 | * @param {Object} eventDescriptor The keyframe event descriptor.\r | |
203 | */\r | |
204 | \r | |
205 | constructor: function (config) {\r | |
206 | var me = this;\r | |
207 | \r | |
208 | me.callParent(arguments);\r | |
209 | \r | |
210 | me.eventObject = new Ext.EventObjectImpl();\r | |
211 | \r | |
212 | me.timerFn = function () {\r | |
213 | me.onTick();\r | |
214 | };\r | |
215 | me.attachTo = me.attachTo || window;\r | |
216 | },\r | |
217 | \r | |
218 | /**\r | |
219 | * Returns the element given is XPath-like description.\r | |
220 | * @param {String} xpath The XPath-like description of the element.\r | |
221 | * @return {HTMLElement}\r | |
222 | */\r | |
223 | getElementFromXPath: function (xpath) {\r | |
224 | var me = this,\r | |
225 | parts = xpath.split('/'),\r | |
226 | regex = me.tagPathRegEx,\r | |
227 | i, n, m, count, tag, child,\r | |
228 | el = me.attachTo.document;\r | |
229 | \r | |
230 | el = (parts[0] == '~') ? el.body\r | |
231 | : el.getElementById(parts[0].substring(1)); // remove '#'\r | |
232 | \r | |
233 | for (i = 1, n = parts.length; el && i < n; ++i) {\r | |
234 | m = regex.exec(parts[i]);\r | |
235 | count = m[2] ? parseInt(m[2], 10) : 1;\r | |
236 | tag = m[1].toUpperCase();\r | |
237 | \r | |
238 | for (child = el.firstChild; child; child = child.nextSibling) {\r | |
239 | if (child.tagName == tag) {\r | |
240 | if (count == 1) {\r | |
241 | break;\r | |
242 | }\r | |
243 | --count;\r | |
244 | }\r | |
245 | }\r | |
246 | \r | |
247 | el = child;\r | |
248 | }\r | |
249 | \r | |
250 | return el;\r | |
251 | },\r | |
252 | \r | |
253 | /**\r | |
254 | * This method is called after an event has been played to prepare for the next event.\r | |
255 | * @param {Object} eventDescriptor The descriptor of the event just played.\r | |
256 | */\r | |
257 | nextEvent: function (eventDescriptor) {\r | |
258 | var me = this, index;\r | |
259 | \r | |
260 | if (eventDescriptor.screenshot) { \r | |
261 | eventDescriptor.played = true;\r | |
262 | return;\r | |
263 | }\r | |
264 | \r | |
265 | if (eventDescriptor.after) {\r | |
266 | eventDescriptor.after();\r | |
267 | delete eventDescriptor.after;\r | |
268 | return;\r | |
269 | }\r | |
270 | \r | |
271 | index = ++me.queueIndex;\r | |
272 | // keyframe events are inserted after a keyFrameEvent is played.\r | |
273 | if (me.keyFrameEvents[eventDescriptor.type]) {\r | |
274 | Ext.Array.insert(me.eventQueue, index, [\r | |
275 | { keyframe: true, ts: eventDescriptor.ts }\r | |
276 | ]);\r | |
277 | }\r | |
278 | },\r | |
279 | \r | |
280 | /**\r | |
281 | * This method returns the event descriptor at the front of the queue. This does not\r | |
282 | * dequeue the event. Repeated calls return the same object (until {@link #nextEvent}\r | |
283 | * is called).\r | |
284 | */\r | |
285 | peekEvent: function () {\r | |
286 | var me = this,\r | |
287 | queue = me.eventQueue,\r | |
288 | index = me.queueIndex,\r | |
289 | eventDescriptor = queue[index],\r | |
290 | type = eventDescriptor && eventDescriptor.type,\r | |
291 | tmp;\r | |
292 | \r | |
293 | if (type == 'mduclick') {\r | |
294 | tmp = [\r | |
295 | Ext.applyIf({ type: 'mousedown' }, eventDescriptor),\r | |
296 | Ext.applyIf({ type: 'mouseup' }, eventDescriptor),\r | |
297 | Ext.applyIf({ type: 'click' }, eventDescriptor)\r | |
298 | ];\r | |
299 | delete tmp[0].screenshot;\r | |
300 | delete tmp[0].after;\r | |
301 | delete tmp[1].screenshot;\r | |
302 | delete tmp[1].after;\r | |
303 | Ext.Array.replace(queue, index, 1, tmp);\r | |
304 | }\r | |
305 | \r | |
306 | // if (type == 'drag') {\r | |
307 | //\r | |
308 | // Ext.Array.replace(queue, index, 1, me.createDrag(eventDescriptor));\r | |
309 | // return queue[index];\r | |
310 | // }\r | |
311 | return queue[index] || null;\r | |
312 | },\r | |
313 | \r | |
314 | // TODO\r | |
315 | // dragStep: 5,\r | |
316 | // \r | |
317 | // createDrag: function(eventDescriptor) {\r | |
318 | // var me = this,\r | |
319 | // tmp = [\r | |
320 | // Ext.applyIf({ type: 'mousedown' }, eventDescriptor)\r | |
321 | // ],\r | |
322 | // \r | |
323 | // from = me.getTarget(eventDescriptor).xy,\r | |
324 | // to = me.getTarget(eventDescriptor.dropTo).xy,\r | |
325 | // i = 0,\r | |
326 | // xinc, yinc, x, y;\r | |
327 | // \r | |
328 | //\r | |
329 | // \r | |
330 | // xinc = (to[0] - from[0]) / me.dragStep;\r | |
331 | // \r | |
332 | // yinc = (to[1] - from[1]) / me.dragStep;\r | |
333 | // \r | |
334 | // x = from[0] + xinc;\r | |
335 | // y = from[1] + yinc;\r | |
336 | // \r | |
337 | // \r | |
338 | // for (i = 0; i < me.dragStep; i++) {\r | |
339 | // tmp.push(Ext.applyIf({ type: 'mousemove', xy: [x,y]}, eventDescriptor));\r | |
340 | // x += xinc;\r | |
341 | // y += yinc;\r | |
342 | // }\r | |
343 | // \r | |
344 | // tmp.push(Ext.applyIf({ type: 'mouseup' }, eventDescriptor.dropTo));\r | |
345 | // \r | |
346 | // return tmp;\r | |
347 | // },\r | |
348 | /**\r | |
349 | * This method dequeues and injects events until it has arrived at the time index. If\r | |
350 | * no events are ready (based on the time index), this method does nothing.\r | |
351 | * @return {Boolean} True if there is more to do; false if not (at least for now).\r | |
352 | */\r | |
353 | processEvents: function () {\r | |
354 | var me = this,\r | |
355 | animations = me.pauseForAnimations && me.attachTo.Ext.fx.Manager.items,\r | |
356 | eventDescriptor;\r | |
357 | while ((eventDescriptor = me.peekEvent()) !== null) {\r | |
358 | \r | |
359 | if (animations && animations.getCount()) {\r | |
360 | return true;\r | |
361 | }\r | |
362 | \r | |
363 | if (eventDescriptor.screenshot && eventDescriptor.played) {\r | |
364 | delete eventDescriptor.screenshot;\r | |
365 | delete eventDescriptor.played;\r | |
366 | me.snap();\r | |
367 | me.nextEvent(eventDescriptor);\r | |
368 | continue;\r | |
369 | }\r | |
370 | if (eventDescriptor.keyframe) {\r | |
371 | if (!me.processKeyFrame(eventDescriptor)) {\r | |
372 | return false;\r | |
373 | }\r | |
374 | me.nextEvent(eventDescriptor);\r | |
375 | } else if (eventDescriptor.ts <= me.timeIndex || !eventDescriptor.ts &&\r | |
376 | me.fireEvent('beforeplay', me, eventDescriptor) !== false &&\r | |
377 | me.playEvent(eventDescriptor)) {\r | |
378 | me.nextEvent(eventDescriptor);\r | |
379 | if (eventDescriptor.played) {\r | |
380 | return true;\r | |
381 | }\r | |
382 | } else {\r | |
383 | return true;\r | |
384 | }\r | |
385 | }\r | |
386 | me.stop();\r | |
387 | return false;\r | |
388 | },\r | |
389 | \r | |
390 | snap: function() {\r | |
391 | if (window.__x && __x.poll) { \r | |
392 | __x.poll.sendSyncRequest({cmd: 'screenshot'});\r | |
393 | } else {\r | |
394 | alert('sreenshot');\r | |
395 | }\r | |
396 | },\r | |
397 | \r | |
398 | /**\r | |
399 | * This method is called when a keyframe is reached. This will fire the keyframe event.\r | |
400 | * If the keyframe has been handled, true is returned. Otherwise, false is returned.\r | |
401 | * @param {Object} The event descriptor of the keyframe.\r | |
402 | * @return {Boolean} True if the keyframe was handled, false if not.\r | |
403 | */\r | |
404 | processKeyFrame: function (eventDescriptor) {\r | |
405 | var me = this;\r | |
406 | \r | |
407 | // only fire keyframe event (and setup the eventDescriptor) once...\r | |
408 | if (!eventDescriptor.defer) {\r | |
409 | eventDescriptor.done = true;\r | |
410 | \r | |
411 | eventDescriptor.defer = function () {\r | |
412 | eventDescriptor.done = false;\r | |
413 | };\r | |
414 | \r | |
415 | eventDescriptor.finish = function () {\r | |
416 | eventDescriptor.done = true;\r | |
417 | me.schedule();\r | |
418 | };\r | |
419 | \r | |
420 | me.fireEvent('keyframe', me, eventDescriptor);\r | |
421 | }\r | |
422 | \r | |
423 | return eventDescriptor.done;\r | |
424 | },\r | |
425 | \r | |
426 | /**\r | |
427 | * Called to inject the given event on the specified target.\r | |
428 | * @param {HTMLElement} target The target of the event.\r | |
429 | * @param {Ext.EventObject} The event to inject.\r | |
430 | */\r | |
431 | injectEvent: function (target, event) {\r | |
432 | event.injectEvent(target);\r | |
433 | },\r | |
434 | \r | |
435 | playEvent: function (eventDescriptor) {\r | |
436 | var me = this,\r | |
437 | target,\r | |
438 | event;\r | |
439 | \r | |
440 | if (eventDescriptor.cmpQuery || eventDescriptor.domQuery) {\r | |
441 | me.getTarget(eventDescriptor);\r | |
442 | }\r | |
443 | \r | |
444 | if (eventDescriptor.target) {\r | |
445 | target = me.getElementFromXPath(eventDescriptor.target);\r | |
446 | }\r | |
447 | \r | |
448 | if (!target) {\r | |
449 | // not present (yet)... wait for element present...\r | |
450 | // TODO - need a timeout here\r | |
451 | return false;\r | |
452 | }\r | |
453 | \r | |
454 | event = me.translateEvent(eventDescriptor, target);\r | |
455 | me.injectEvent(target, event);\r | |
456 | return true;\r | |
457 | },\r | |
458 | \r | |
459 | schedule: function () {\r | |
460 | var me = this;\r | |
461 | if (!me.timer) {\r | |
462 | me.timer = setTimeout(me.timerFn, 250);\r | |
463 | }\r | |
464 | },\r | |
465 | \r | |
466 | translateEvent: function (eventDescriptor, target) {\r | |
467 | var me = this,\r | |
468 | event = me.eventObject,\r | |
469 | modKeys = eventDescriptor.modKeys || '',\r | |
470 | xy;\r | |
471 | \r | |
472 | if ('xy' in eventDescriptor) {\r | |
473 | event.xy = xy = Ext.fly(target).getXY();\r | |
474 | xy[0] += eventDescriptor.xy[0];\r | |
475 | xy[1] += eventDescriptor.xy[1];\r | |
476 | }\r | |
477 | \r | |
478 | \r | |
479 | if ('wheel' in eventDescriptor) {\r | |
480 | // see getWheelDelta\r | |
481 | }\r | |
482 | \r | |
483 | event.type = eventDescriptor.type;\r | |
484 | event.button = eventDescriptor.button;\r | |
485 | event.altKey = modKeys.indexOf('A') > 0;\r | |
486 | event.ctrlKey = modKeys.indexOf('C') > 0;\r | |
487 | event.metaKey = modKeys.indexOf('M') > 0;\r | |
488 | event.shiftKey = modKeys.indexOf('S') > 0;\r | |
489 | \r | |
490 | \r | |
491 | return event;\r | |
492 | },\r | |
493 | \r | |
494 | getTarget: function(eventDescriptor) {\r | |
495 | var me = this;\r | |
496 | eventDescriptor.el = eventDescriptor.el || 'el';\r | |
497 | if (eventDescriptor.cmpQuery) {\r | |
498 | me.findTarget(eventDescriptor, Ext.ComponentQuery.query(eventDescriptor.cmpQuery)[0]);\r | |
499 | } else {\r | |
500 | me.findTarget(eventDescriptor);\r | |
501 | }\r | |
502 | \r | |
503 | return eventDescriptor;\r | |
504 | },\r | |
505 | \r | |
506 | findTarget: function(eventDescriptor, cmp) {\r | |
507 | var me = this,\r | |
508 | x, y, el, offsetX, offsetY;\r | |
509 | if (cmp) {\r | |
510 | if (!eventDescriptor.domQuery) {\r | |
511 | el = cmp[eventDescriptor.el];\r | |
512 | } else {\r | |
513 | el = cmp.el.down(eventDescriptor.domQuery);\r | |
514 | }\r | |
515 | } else {\r | |
516 | \r | |
517 | el = Ext.get(Ext.DomQuery.selectNode(eventDescriptor.domQuery));\r | |
518 | }\r | |
519 | try {\r | |
520 | eventDescriptor.target = '#' + el.dom.id;\r | |
521 | if (!eventDescriptor.xy) {\r | |
522 | if (eventDescriptor.offset) {\r | |
523 | offsetX = eventDescriptor.offset[0];\r | |
524 | offsetY = eventDescriptor.offset[1];\r | |
525 | if (offsetX > 0) {\r | |
526 | x = offsetX;\r | |
527 | } else {\r | |
528 | x = el.getWidth() - offsetX;\r | |
529 | }\r | |
530 | if (offsetY > 0) {\r | |
531 | y = offsetY;\r | |
532 | } else {\r | |
533 | y = el.getHeight() - offsetY;\r | |
534 | }\r | |
535 | // default centering\r | |
536 | } else {\r | |
537 | x = (el.getWidth() / 2);\r | |
538 | y = (el.getHeight() / 2);\r | |
539 | }\r | |
540 | eventDescriptor.xy = [x,y];\r | |
541 | }\r | |
542 | \r | |
543 | \r | |
544 | } catch(e) {}\r | |
545 | \r | |
546 | return eventDescriptor;\r | |
547 | },\r | |
548 | \r | |
549 | //---------------------------------\r | |
550 | // Driver overrides\r | |
551 | \r | |
552 | onStart: function () {\r | |
553 | var me = this;\r | |
554 | \r | |
555 | me.queueIndex = 0;\r | |
556 | me.schedule();\r | |
557 | },\r | |
558 | \r | |
559 | onStop: function () {\r | |
560 | var me = this;\r | |
561 | \r | |
562 | if (me.timer) {\r | |
563 | clearTimeout(me.timer);\r | |
564 | me.timer = null;\r | |
565 | }\r | |
566 | if (window.__x && __x.poll) {\r | |
567 | __x.poll.sendSyncRequest({cmd: 'finish'});\r | |
568 | }\r | |
569 | },\r | |
570 | \r | |
571 | //---------------------------------\r | |
572 | \r | |
573 | onTick: function () {\r | |
574 | var me = this;\r | |
575 | \r | |
576 | me.timer = null;\r | |
577 | me.timeIndex = me.getTimestamp() * me.speed;\r | |
578 | \r | |
579 | if (me.processEvents()) {\r | |
580 | me.schedule();\r | |
581 | }\r | |
582 | }\r | |
583 | });\r | |
584 | \r | |
585 | Ext.define('Ext.ux.event.Maker', {\r | |
586 | \r | |
587 | eventQueue: [],\r | |
588 | \r | |
589 | startAfter: 0,\r | |
590 | \r | |
591 | timerIncrement: 2000,\r | |
592 | \r | |
593 | currentTiming: 0,\r | |
594 | \r | |
595 | constructor: function(config) {\r | |
596 | var me = this;\r | |
597 | \r | |
598 | me.currentTiming = me.startAfter;\r | |
599 | \r | |
600 | if(!Ext.isArray(config)) {\r | |
601 | config = [config];\r | |
602 | }\r | |
603 | \r | |
604 | Ext.Array.each(config, function(item) {\r | |
605 | item.el = item.el || 'el';\r | |
606 | if (item.cmpQuery) {\r | |
607 | Ext.Array.each(Ext.ComponentQuery.query(item.cmpQuery), function(cmp) {\r | |
608 | me.generateEvent(item, cmp);\r | |
609 | });\r | |
610 | } else {\r | |
611 | me.generateEvent(item);\r | |
612 | }\r | |
613 | if (item.endingScreenshot) {\r | |
614 | me.eventQueue[me.eventQueue.length - 1].screenshot = true;\r | |
615 | }\r | |
616 | });\r | |
617 | \r | |
618 | return me.eventQueue;\r | |
619 | },\r | |
620 | \r | |
621 | generateEvent: function(item, cmp) {\r | |
622 | var me = this,\r | |
623 | event = {}, x, y, el;\r | |
624 | if (cmp) {\r | |
625 | if (!item.domQuery) {\r | |
626 | el = cmp[item.el];\r | |
627 | } else {\r | |
628 | el = cmp.el.down(item.domQuery);\r | |
629 | \r | |
630 | }\r | |
631 | } else {\r | |
632 | el = Ext.get(Ext.DomQuery.selectNode(item.domQuery));\r | |
633 | }\r | |
634 | event.target = '#' + el.dom.id;\r | |
635 | \r | |
636 | // event.type = item.type;\r | |
637 | \r | |
638 | // event.key = item.key;\r | |
639 | // event.button = item.button || 0;\r | |
640 | \r | |
641 | x = el.getX() + (el.getWidth() / 2);\r | |
642 | y = el.getY() + (el.getHeight() / 2);\r | |
643 | \r | |
644 | event.xy = [x,y];\r | |
645 | \r | |
646 | event.ts = me.currentTiming;\r | |
647 | \r | |
648 | event.screenshot = item.screenshot;\r | |
649 | me.currentTiming += me.timerIncrement;\r | |
650 | \r | |
651 | me.eventQueue.push(event);\r | |
652 | }\r | |
653 | });\r | |
654 | \r | |
655 | Ext.onReady(function() {\r | |
656 | if (!window.__x) {\r | |
657 | __x = {};\r | |
658 | } else {\r | |
659 | __x.poll.interval = 50;\r | |
660 | __x.poll.connect(); \r | |
661 | }\r | |
662 | \r | |
663 | // \r | |
664 | // \r | |
665 | __x.player = Ext.create('Ext.ux.event.Player', {\r | |
666 | eventQueue: [{\r | |
667 | cmpQuery: 'panel[title="Collapsed Panel"] > header > tool[type=expand-bottom]',\r | |
668 | \r | |
669 | domQuery: 'img',\r | |
670 | \r | |
671 | type: 'mduclick',\r | |
672 | \r | |
673 | screenshot: true\r | |
674 | },{\r | |
675 | cmpQuery: 'panel[title="Collapsed Panel"] > header > tool[type=collapse-top]',\r | |
676 | \r | |
677 | domQuery: 'img',\r | |
678 | \r | |
679 | type: 'mduclick',\r | |
680 | \r | |
681 | screenshot: true\r | |
682 | },{\r | |
683 | \r | |
684 | cmpQuery: 'panel[title="Masked Panel"] > header > tool[type=collapse-top]',\r | |
685 | \r | |
686 | domQuery: 'img',\r | |
687 | \r | |
688 | type: 'mduclick',\r | |
689 | \r | |
690 | screenshot: true\r | |
691 | },{\r | |
692 | cmpQuery: 'panel[title="Masked Panel"] > header > tool[type=collapse-bottom]',\r | |
693 | \r | |
694 | domQuery: 'img',\r | |
695 | \r | |
696 | type: 'mduclick',\r | |
697 | \r | |
698 | screenshot: true\r | |
699 | },{\r | |
700 | cmpQuery: 'panel[title="Collapsed Framed Panel"] > header > tool[type=expand-bottom]',\r | |
701 | \r | |
702 | domQuery: 'img',\r | |
703 | \r | |
704 | type: 'mduclick',\r | |
705 | \r | |
706 | screenshot: true\r | |
707 | },{\r | |
708 | cmpQuery: 'panel[title="Collapsed Framed Panel"] > header > tool[type=collapse-top]',\r | |
709 | \r | |
710 | domQuery: 'img',\r | |
711 | \r | |
712 | type: 'mduclick',\r | |
713 | \r | |
714 | screenshot: true\r | |
715 | },{\r | |
716 | cmpQuery: 'window[title=Window] > toolbar > button[text=Submit]',\r | |
717 | \r | |
718 | type: 'mduclick',\r | |
719 | \r | |
720 | screenshot: true\r | |
721 | },{\r | |
722 | cmpQuery: 'button[text=Yes]',\r | |
723 | \r | |
724 | type: 'mduclick',\r | |
725 | \r | |
726 | screenshot: true\r | |
727 | },{\r | |
728 | cmpQuery: 'window[title=Window] > header > tool[type=collapse-top]',\r | |
729 | \r | |
730 | domQuery: 'img',\r | |
731 | \r | |
732 | type: 'mduclick',\r | |
733 | \r | |
734 | screenshot: true\r | |
735 | },{\r | |
736 | cmpQuery: 'window[title=Window] > header > tool[type=collapse-bottom]',\r | |
737 | \r | |
738 | domQuery: 'img',\r | |
739 | \r | |
740 | type: 'mduclick',\r | |
741 | \r | |
742 | screenshot: true\r | |
743 | },{ \r | |
744 | cmpQuery: 'panel[title=Basic Panel With Toolbars] > toolbar[dock=top] > buttongroup > button[text=Menu Button]',\r | |
745 | \r | |
746 | offset: [-2, -2],\r | |
747 | \r | |
748 | type: 'mouseover'\r | |
749 | },{\r | |
750 | cmpQuery: 'panel[title=Basic Panel With Toolbars] > toolbar[dock=top] > buttongroup > button[text=Menu Button]',\r | |
751 | \r | |
752 | offset: [-2, -3],\r | |
753 | \r | |
754 | type: 'mousemove'\r | |
755 | },{\r | |
756 | cmpQuery: 'panel[title=Basic Panel With Toolbars] > toolbar[dock=top] > buttongroup > button[text=Menu Button]',\r | |
757 | \r | |
758 | offset: [-2, -2],\r | |
759 | \r | |
760 | type: 'mduclick',\r | |
761 | \r | |
762 | screenshot: true\r | |
763 | },{\r | |
764 | cmpQuery: 'panel[title=Basic Panel With Toolbars] > toolbar[dock=top] > buttongroup > button[text=Menu Button]',\r | |
765 | \r | |
766 | offset: [-2, -2],\r | |
767 | \r | |
768 | type: 'mduclick',\r | |
769 | \r | |
770 | screenshot: true\r | |
771 | \r | |
772 | },{ \r | |
773 | cmpQuery: 'panel[title=Basic Panel With Toolbars] > toolbar[dock=top] > buttongroup > button[text=Menu Button]',\r | |
774 | \r | |
775 | offset: [-2, -2],\r | |
776 | \r | |
777 | type: 'mouseout',\r | |
778 | \r | |
779 | screenshot: true\r | |
780 | },{\r | |
781 | cmpQuery: 'panel[title=Basic Panel With Toolbars] > toolbar[dock=top] > buttongroup > button[text=Cut]',\r | |
782 | \r | |
783 | offset: [-2, -2],\r | |
784 | \r | |
785 | type: 'mouseover'\r | |
786 | },{\r | |
787 | cmpQuery: 'panel[title=Basic Panel With Toolbars] > toolbar[dock=top] > buttongroup > button[text=Cut]',\r | |
788 | \r | |
789 | offset: [-2, -3],\r | |
790 | \r | |
791 | type: 'mousemove'\r | |
792 | },{\r | |
793 | cmpQuery: 'panel[title=Basic Panel With Toolbars] > toolbar[dock=top] > buttongroup > button[text=Cut]',\r | |
794 | \r | |
795 | offset: [-2, -2],\r | |
796 | \r | |
797 | type: 'mduclick',\r | |
798 | \r | |
799 | screenshot: true\r | |
800 | },{\r | |
801 | cmpQuery: 'panel[title=Basic Panel With Toolbars] > toolbar[dock=top] > buttongroup > button[text=Cut]',\r | |
802 | \r | |
803 | offset: [-2, -2],\r | |
804 | \r | |
805 | type: 'mduclick',\r | |
806 | \r | |
807 | screenshot: true\r | |
808 | \r | |
809 | },{ \r | |
810 | cmpQuery: 'panel[title=Basic Panel With Toolbars] > toolbar[dock=top] > buttongroup > button[text=Cut]',\r | |
811 | \r | |
812 | offset: [-2, -2],\r | |
813 | \r | |
814 | type: 'mouseout',\r | |
815 | \r | |
816 | screenshot: true\r | |
817 | },{\r | |
818 | \r | |
819 | cmpQuery: 'panel[title=Basic Panel With Toolbars] > toolbar[dock=bottom] > button[text=Menu Button]',\r | |
820 | \r | |
821 | offset: [-2, -2],\r | |
822 | \r | |
823 | type: 'mouseover'\r | |
824 | },{\r | |
825 | cmpQuery: 'panel[title=Basic Panel With Toolbars] > toolbar[dock=bottom] > button[text=Menu Button]',\r | |
826 | \r | |
827 | offset: [-2, -3],\r | |
828 | \r | |
829 | type: 'mousemove'\r | |
830 | },{\r | |
831 | cmpQuery: 'panel[title=Basic Panel With Toolbars] > toolbar[dock=bottom] > button[text=Menu Button]',\r | |
832 | \r | |
833 | offset: [-2, -2],\r | |
834 | \r | |
835 | type: 'mduclick',\r | |
836 | \r | |
837 | screenshot: true\r | |
838 | },{\r | |
839 | cmpQuery: 'panel[title=Basic Panel With Toolbars] > toolbar[dock=bottom] > button[text=Menu Button]',\r | |
840 | \r | |
841 | offset: [-2, -2],\r | |
842 | \r | |
843 | type: 'mduclick',\r | |
844 | \r | |
845 | screenshot: true\r | |
846 | \r | |
847 | },{ \r | |
848 | cmpQuery: 'panel[title=Basic Panel With Toolbars] > toolbar[dock=bottom] > button[text=Menu Button]',\r | |
849 | \r | |
850 | offset: [-2, -2],\r | |
851 | \r | |
852 | type: 'mouseout',\r | |
853 | \r | |
854 | screenshot: true\r | |
855 | },{\r | |
856 | \r | |
857 | cmpQuery: 'panel[title=Basic Panel With Toolbars] > toolbar[dock=bottom] > button[text=Split Button]',\r | |
858 | \r | |
859 | offset: [-2, -2],\r | |
860 | \r | |
861 | type: 'mouseover'\r | |
862 | },{\r | |
863 | cmpQuery: 'panel[title=Basic Panel With Toolbars] > toolbar[dock=bottom] > button[text=Split Button]',\r | |
864 | \r | |
865 | offset: [-2, -3],\r | |
866 | \r | |
867 | type: 'mousemove'\r | |
868 | },{\r | |
869 | cmpQuery: 'panel[title=Basic Panel With Toolbars] > toolbar[dock=bottom] > button[text=Split Button]',\r | |
870 | \r | |
871 | offset: [-2, -2],\r | |
872 | \r | |
873 | type: 'mduclick',\r | |
874 | \r | |
875 | screenshot: true\r | |
876 | },{\r | |
877 | cmpQuery: 'panel[title=Basic Panel With Toolbars] > toolbar[dock=bottom] > button[text=Split Button]',\r | |
878 | \r | |
879 | offset: [-2, -2],\r | |
880 | \r | |
881 | type: 'mduclick',\r | |
882 | \r | |
883 | screenshot: true\r | |
884 | },{\r | |
885 | cmpQuery: 'panel[title=Basic Panel With Toolbars] > toolbar[dock=bottom] > button[text=Split Button]',\r | |
886 | \r | |
887 | offset: [-2, -2],\r | |
888 | \r | |
889 | type: 'mouseout',\r | |
890 | \r | |
891 | screenshot: true\r | |
892 | },{ \r | |
893 | cmpQuery: 'panel[title=Basic Panel With Toolbars] > toolbar[dock=bottom] > button[text=Toggle Button]',\r | |
894 | \r | |
895 | type: 'mduclick',\r | |
896 | \r | |
897 | screenshot: true\r | |
898 | },{\r | |
899 | cmpQuery: 'panel[title=Basic Panel With Toolbars] > toolbar[dock=bottom] > button[text=Toggle Button]',\r | |
900 | \r | |
901 | type: 'mduclick',\r | |
902 | \r | |
903 | screenshot: true \r | |
904 | \r | |
905 | // },{ \r | |
906 | // cmpQuery: 'panel[title=Basic Panel With Toolbars] > toolbar[dock=bottom] > button[text=Menu Button]',\r | |
907 | // \r | |
908 | // domQuery: '.x-btn-split',\r | |
909 | // \r | |
910 | // type: 'mduclick',\r | |
911 | // \r | |
912 | // screenshot: true\r | |
913 | // },{\r | |
914 | // cmpQuery: 'panel[title=Basic Panel With Toolbars] > toolbar[dock=bottom] > button[text=Menu Button]',\r | |
915 | // \r | |
916 | // domQuery: '.x-btn-split',\r | |
917 | // \r | |
918 | // type: 'mduclick',\r | |
919 | // \r | |
920 | // screenshot: true\r | |
921 | // },{ \r | |
922 | // cmpQuery: 'panel[title=Basic Panel With Toolbars] > toolbar[dock=bottom] > button[text=Split Button]',\r | |
923 | // \r | |
924 | // domQuery: '.x-btn-split',\r | |
925 | // \r | |
926 | // type: 'mduclick',\r | |
927 | // \r | |
928 | // screenshot: true\r | |
929 | // },{\r | |
930 | // cmpQuery: 'panel[title=Basic Panel With Toolbars] > toolbar[dock=bottom] > button[text=Split Button]',\r | |
931 | // \r | |
932 | // domQuery: '.x-btn-split',\r | |
933 | // \r | |
934 | // type: 'mduclick',\r | |
935 | // \r | |
936 | // screenshot: true\r | |
937 | // },{ \r | |
938 | // cmpQuery: 'panel[title=Basic Panel With Toolbars] > toolbar[dock=bottom] > button[text=Toggle Button]',\r | |
939 | // \r | |
940 | // type: 'mduclick',\r | |
941 | // \r | |
942 | // screenshot: true\r | |
943 | // },{\r | |
944 | // cmpQuery: 'panel[title=Basic Panel With Toolbars] > toolbar[dock=bottom] > button[text=Toggle Button]',\r | |
945 | // \r | |
946 | // type: 'mduclick',\r | |
947 | // \r | |
948 | // screenshot: true\r | |
949 | // },{ \r | |
950 | // cmpQuery: 'combo',\r | |
951 | // \r | |
952 | // domQuery: '.x-form-trigger',\r | |
953 | // \r | |
954 | // type: 'mduclick',\r | |
955 | // \r | |
956 | // screenshot: true\r | |
957 | // }, {\r | |
958 | // cmpQuery: 'boundlist',\r | |
959 | // \r | |
960 | // domQuery: '.x-boundlist-item',\r | |
961 | // \r | |
962 | // type: 'mduclick',\r | |
963 | // \r | |
964 | // screenshot: true\r | |
965 | \r | |
966 | // }, {\r | |
967 | // cmpQuery: 'grid[title=Array Grid] > headercontainer > gridcolumn[text=Company]',\r | |
968 | // \r | |
969 | // domQuery: '.x-column-header-text',\r | |
970 | // \r | |
971 | // type: 'drag',\r | |
972 | // \r | |
973 | // dropTo: {\r | |
974 | // cmpQuery: 'grid[title=Array Grid] > headercontainer > gridcolumn[text=Price]',\r | |
975 | // \r | |
976 | // domQuery: '.x-column-header-text'\r | |
977 | // },\r | |
978 | // \r | |
979 | // screenshot: true\r | |
980 | \r | |
981 | }]\r | |
982 | });\r | |
983 | if (!window.__x.poll) {\r | |
984 | __x.player.start();\r | |
985 | }\r | |
986 | \r | |
987 | }); |