diff -r 322d0feea350 -r 89ef5ed3c48b src/cm/media/js/lib/yui/yui_3.10.3/docs/event/simulate.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cm/media/js/lib/yui/yui_3.10.3/docs/event/simulate.html Tue Jul 16 14:29:46 2013 +0200 @@ -0,0 +1,895 @@ + + + + + Simulating DOM Events + + + + + + + + + + +
+
+

+
+ + Jump to Table of Contents + + +

Simulating DOM Events

+
+
+
+
+

+ When creating automated tests for your application or modules, you need + to be able to mock user events. The DOM supports creating native events + that behave essentially the same as user generated events, though + without the associated browser default behaviors (e.g. following a link + on click). +

+

+ The event-simulate module adds the Y.Event.simulate method for + working with raw DOM nodes, but for most cases, the + node-event-simulate module is the right choice, since it allows you + to call the simulate method directly from the Node. +

+
+ +

Simulating Mouse Events

+ +

+ There are seven mouse events that can be simulated: +

+ +
    +
  • click
  • +
  • dblclick
  • +
  • mousedown
  • +
  • mouseup
  • +
  • mouseover
  • +
  • mouseout
  • +
  • mousemove
  • +
+ +

+ Each event is fired by calling simulate() and passing in two + arguments: the type of event to fire and an optional object specifying + additional information for the event. To simulate a click on the document's + body element, for example, the following code can be used: +

+ +
YUI().use('node-event-simulate', function(Y) {
+
+    Y.one("body").simulate("click");
+});
+ + +

+ This code simulates a click with all of the default properties on the + event object. To specify additional information, such as the + Shift key being down, the second argument must be used and the exact DOM + name for the event property specified (there is browser-normalizing logic + that translates these into browser-specific properties when necessary): +

+ +
Y.one("body").simulate("click", { shiftKey: true });
+ + +

+ In this updated example, a click event is fired on the document's body + while simulating that the Shift key is down. +

+ +

+ The extra properties to specify vary depending on the event being simulated + and are limited to this list: +

+ +
+
detail
+
+ Indicates the number of times a button was clicked (DOM-compliant + browsers only). +
+ +
screenX, screenY
+
+ Coordinates of the mouse event in relation to the entire screen + (DOM-compliant browsers only). +
+ +
clientX, clientY
+
+ Coordinates of the mouse event in relation to the browser client + area. +
+ +
ctrlKey, altKey, shiftKey, metaKey
+
+ The state of the Ctrl, Alt, Shift, and Meta keys, respectively + (true for down, false for up). +
+ +
button
+
+ The button being used for the event, 0 for left (default), 1 for + right, 2 for center. +
+ +
relatedTarget
+
+ the element the mouse moved from (during a mouseover event) or to + (during a mouseout event). +
+
+ +
YUI().use('node-event-simulate', function(Y) {
+
+    var node = Y.one("#myDiv");
+
+    //simulate a click Alt key down
+    node.simulate("click", { altKey: true});
+
+    //simulate a double click with Ctrl key down
+    node.simulate("dblclick", { ctrlKey: true });
+
+    //simulate a mouse over
+    node.simulate("mouseover", { relatedTarget: document.body });
+
+    //simulate a mouse out
+    node.simulate("mouseout", { relatedTarget: document.body });
+
+    //simulate a mouse down at point (100,100) in the client area
+    node.simulate("mousedown", { clientX: 100, clientY: 100 });
+
+    //simulate a mouse up at point (100,100) in the client area
+    node.simulate("mouseup", { clientX: 100, clientY: 100 });
+
+    //simulate a mouse move at point (200, 200) in the client area
+    node.simulate("mousemove", { clientX: 200, clientY: 200 });
+});
+ + +

Simulating Key Events

+ +

There are three key event simulations available:

+ +
    +
  • keyup
  • +
  • keydown
  • +
  • keypress
  • +
+ +

+ As with the mouse events, key events are simulated using + simulate(). For keyup and keydown, + the keyCode property must be specified; for + keypress, the charCode property must be included. + In many cases, keyCode and charCode may be the + same value to represent the same key (97, for instance, represents the + "A" key as well as being the ASCII code for the letter + "a"). For example: +

+ +
YUI().use('node-event-simulate', function(Y) {
+
+    var node = Y.one("#myDiv");
+
+    //simulate a keydown on the A key
+    node.simulate("keydown", { keyCode: 97 });
+
+    //simulate a keyup on the A key
+    node.simulate("keyup", { keyCode: 97 });
+
+    //simulate typing "a"
+    node.simulate("keypress", { charCode: 97 });
+});
+ + +

+ Key events also support the ctrlKey, altKey, + shiftKey, and metaKey event properties. +

+

+ Note: Due to differences in browser implementations, key + events may not be simulated in the same manner across all browsers. For + instance, when simulating a keypress event on a textbox, only Firefox will + update the textbox with the new character of the key that was simulated to + be pressed. For other browsers, the events are still registered and all + event handlers are called, however, the textbox display and + value property are not updated. These differences should go + away as browser support for simulated events improves in the future. +

+ +

Simulating UI Events

+ +

There are several UI event simulations available:

+ +
    +
  • blur
  • +
  • change
  • +
  • focus
  • +
  • resize
  • +
  • scroll
  • +
  • select
  • +
+ +

+ As with the other events, UI events are simulated using + simulate(). There are no properties that are required to + simulate UI events as these events don't carry extra information. Some + examples: +

+ +
YUI().use('node-event-simulate', function(Y) {
+
+    var node = Y.one("#myInput");
+
+    //simulate a change event
+    node.simulate("change");
+
+    //simulate a select event
+    node.simulate("select");
+});
+ + +

Simulating Touch Gestures

+

+There are several high level gesture simulations primarily targeted for +smartphones, tablets, and other touch-enabled devices. Single touch gestures +such as tap and flick are simulated using Mouse Events on desktop or mobile +devices where creating Touch Events are not supported. All gesture simulations +are done by calling the simulateGesture() method against a Node instance. The +method is asynchronous by default so an optional callback function can be +passed. +

+ +
+
tap
+
+ Single finger gesture to simulate a tap. Default is to simulate + one tap but it can be configured to simulate any number of taps. +
+ +
doubletap
+
+ Single finger gesture to simulate double taps. +
+ +
press
+
+ Single finger gesture to simulate a long press. +
+ +
move
+
+ Single finger gesture to simulate a move. It simulates moving + one finger straight in any direction. +
+ +
flick
+
+ Single finger gesture to simulate the flick gesture. It simulates + moving one finger with a certain velocity along either an X or Y + axis. +
+ +
pinch
+
+ Two finger gesture to simulate pinch and spread gestures. +
+ +
rotate
+
+ Two finger gesture to simulate a rotate. +
+
+ +

+Gesture can be simulated by calling simulateGesture() and +passing the following arguments: the name of the gesture to simulate, an +optional object to define gesture properties, and an optional callback function. +The available properties vary per gesture. +

+ +

If the location of the finger is not given, the center of the node element is +used by default. This default behavior can be overridden by passing coordinates +into the optional object. The coordinate values are relative to the top/left +corner of the node element. +

+ +

Single Touch Gestures: Tap, Double Tab and Press

+ +

+The following code simulates tap, double tap and press gestures: +

+ +
YUI().use('node-event-simulate', function(Y) {
+
+    var node = Y.one("#myElement");
+
+    //simulate tap gesture
+    node.simulateGesture("tap");
+
+    //simulate double-tap gesture
+    node.simulateGesture("doubletap");
+
+    //simulate press gesture
+    node.simulateGesture("press", {
+        hold: 3000    // press and hold for 3000ms
+    });
+
+    // simulate tap with options and callback
+    node.simulateGesture("tap", {
+        point: [30, 30], // tap (30, 30) relative to the top/left of the node
+        hold: 3000,      // hold for 3sec in a tap
+        times: 2,        // tap 2 times
+        delay: 500       // delay time before next tap starts
+    }, function() {
+        Y.log("I was called.");
+    });
+});
+ +

Valid Options

+ +

+Optional properties for the tap gesture: +

+ +
+
point
+
+ Indicates the [x,y] coordinates where the tap should be + simulated. Default is the center of the node element. +
+
hold
+
+ The hold time in milliseconds. This is the time between + touchstart and touchend event generation. +
+
times
+
+ Indicates the number of taps. Default is 1. +
+
delay
+
+ The number of milliseconds before the next tap simulation + happens. This is valid only when times is more than 1. +
+
+ +

+Optional properties for the doubletap gesture: +

+ +
+
point
+
+ Indicates the [x, y] coordinates where the doubletap should be + simulated. Default is the center of the node element. +
+
+ +

+The press gesture is essentially a single tap with the hold property +defined. Optional properties for the press gesture: +

+ +
+
point
+
+ Indicates the [x, y] coordinates where the tap should be + simulated. Default is the center of the node element. +
+
hold
+
+ The hold time in milliseconds. This is the time between + touchstart and touchend event generation. +
+
+ +

Single Touch Gestures: Move and Flick

+ +

+The following code can be used To simulate various gestures of moving one +finger: +

+ +
YUI().use('node-event-simulate', function(Y) {
+
+    var node = Y.one("#myElement");
+
+    //simulate moving a finger 200 pixels along the x-axis 
+    //to the right for one second (default)
+    node.simulateGesture("move");
+
+    //simulate moving a finger from the center of the node
+    //to a point 70 pixels to the right and 50 pixels down over 2000ms
+    node.simulateGesture("move", {
+        path: {
+            xdist: 70,
+            ydist: -50
+        } ,
+        duration: 2000
+    });
+
+    //simulate a flick to the right (default)
+    node.simulateGesture("flick");
+
+    //simulate a flick down 100 pixels over 50ms
+    node.simulateGesture("flick", {
+        axis: y
+        distance: -100 
+        duration: 50
+    });
+
+});
+ + +

Valid Options

+ +

+Optional properties for the move gesture: +

+ +
+
path
+
+ Indicates the path of the finger movement. It's an object with three + optional properties: point, xdist and ydist. The point is + the start point and defaults to the center of the node element. + xdist and ydist indicate the distance moved in pixels along the + x- and y-axis. A negative distance value indicates moving to left + for xdist and down for ydist. +
+
duration
+
+ The duration of the gesture in milliseconds. +
+
+ +

+Optional properties for the flick gesture: +

+ +
+
point
+
+ Indicates the [x, y] coordinates where the flick should be + simulated. Default is the center of the node element. +
+
axis
+
+ Valid values are either "x" or "y". Indicates moving axis. The flick + moves in only 4 directions (left, right, up and down). +
+
distance
+
+ Distance to move (in pixels). +
+
duration
+
+ The duration of the gesture in milliseconds. This value may be + adjusted if it is below the minimum velocity to be a flick gesture. +
+
+ +

Two Finger Gestures: Pinch and Rotate

+ +

+The pinch gesture is used to simulate the pinching and spreading of two +fingers. During a pinch simulation, rotation is also possible. Essentially +pinch and rotate simulations share the same base implementation to allow +both pinching and rotation at the same time. The only difference is pinch +requires start and end option properties while rotate requires rotation +option property. +

+ +

+The pinch and rotate gestures can be described as placing 2 fingers along a +circle. Pinching and spreading can be described by start and end circles while +rotation occurs on a single circle. If the radius of the start circle is greater +than the end circle, the gesture becomes a pinch, otherwise it is a spread spread. +

+ +

+The following code can be used to simulate two finger gestures: +

+ +
YUI().use('node-event-simulate', function(Y) {
+
+    var node = Y.one("#myElement");
+
+    //simulate a pinch: "r1" and "r2" are required
+    node.simulateGesture("pinch", {
+        r1: 100, // start circle radius at the center of the node
+        r2: 50   // end circle radius at the center of the node
+    });
+
+    //simulate a spread: same as "pinch" gesture but r2>r1
+    node.simulateGesture("pinch", {
+        r1: 50,
+        r2: 100
+    });
+
+    //simulate rotating a node 75 degrees counter-clockwise 
+    node.simulateGesture("rotate", {
+        rotation: -75
+    });
+
+    //simulate a pinch and a rotation at the same time. 
+    //fingers start on a circle of radius 100 px, placed at top/bottom
+    //fingers end on a circle of radius 50px, placed at right/left 
+    node.simulateGesture("pinch", {
+        r1: 100,
+        r2: 50,
+        start: 0
+        rotation: 90
+    });
+});
+ +

Valid Options

+ +

+The optional properties available for pinch and rotate gestures are the +same: +

+ +
+
center
+
+ The center of the circle where the two fingers are placed. Default + is the center of the node element. +
+
r1
+
+ Required for pinch gestures but optional for rotate. Pixel radius + of the start circle. If omitted in rotate gestures, default is + a fourth of the node element width or height, whichever is smaller. +
+
r2
+
+ Required for pinch gestures but optional for rotate gestures. + Pixel radius of the end circle. If omitted in rotate gestures, + default is a fourth of the node element width or height, whichever + is smaller. +
+
duration
+
+ The duration of the gesture in milliseconds. +
+
start
+
+ Start degree of the first finger for the rotation gesture. Default + is 0 (i.e., 12:00 on a clock). +
+
rotation
+
+ Degrees to rotate from the start degree. Negative value means + rotation of counter-clockwise direction. +
+
+ +

Gesture Simulation on iOS

+

+If the gesture simulation is called in iOS, it generates not only touch events +but also +iOS specific gesture events: gesturestart, gesturechange +and gestureend. +

+ +

Customizing Default Gesture Properties

+ +

+You can define custom default behaviors for gesture simulations by modifying the +following Y.GestureSimulation.defaults object properties: +

+ +
    +
  • HOLD_TAP
  • +
  • DELAY_TAP
  • +
  • HOLD_PRESS
  • +
  • MIN_HOLD_PRESS
  • +
  • MAX_HOLD_PRESS
  • +
  • DISTANCE_MOVE
  • +
  • DURATION_MOVE
  • +
  • MAX_DURATION_MOVE
  • +
  • MIN_VELOCITY_FLICK
  • +
  • DISTANCE_FLICK
  • +
  • DURATION_FLICK
  • +
  • MAX_DURATION_FLICK
  • +
  • DURATION_PINCH
  • +
+ +

+And an example: +

+ +
YUI().use('node-event-simulate', function(Y) {
+
+    var node = Y.one("#myElement");
+    
+    Y.GestureSimulation.defaults = Y.merge(Y.GestureSimulation.defaults, {
+        HOLD_TAP: 3000
+    });
+    
+    //now touchend event will be generated after 3 sec from the touchstart 
+    //event generation.
+    node.simulateGesture("tap");
+});
+ + +

Caveats and Coming Soons

+ +

Don't use simulation in user facing code

+ +

+ Event simulation is for automated testing. Your application should respond + to real user events. For reasons + mentioned below, it can be easy to get + your application into a confused runtime state when some callbacks have + been executed but not others. +

+ +

+ Typically, event simulation is sought to trigger certain callbacks. If a + function needs to respond to user action or be called programmatically, it + should be written accordingly and called directly in the latter case. + Often a better solution is to extract the core logic from the event handler + into a separate function and call that method from the event handler and + from the other part of the application that was going to use simulation. +

+ +

+ In some cases, simulation is wanted because there may be any number of + subscriptions on a node, and all applicable callbacks should be triggered. + If this is the case, investigate using custom events, instead. +

+ +

+ The bottom line is, reliance on event simulation in production code is a + warning sign that the architecture is not scaling. The affected code + should be refactored before it becomes a larger problem. +

+ +

Only what you ask for

+ +

+ In many cases, events happen in groups (mousedown, mouseup, click, or + keydown, keyup, keypress). If you simulate an event that is + typically part of a group or is often followed by other events, the + other events will NOT be generated for free. +

+ +

+ For example, if you simulate a click event on a submit button, you only + simulate the click event. The preceding mousedown and mouseup, as + well as the subsequently expected 'submit' are neither simulated or fired + natively. +

+ +

No synthetic event simulation yet

+ +

+ The Synthetic event system doesn't yet support + defining simulation. In most cases, though, synthetic events are triggered + by other DOM events that can be simulated, so it's often possible to + trigger them by simulating the underlying events. But that ignores the + point that synthetic events are supposed to mask that abstraction for your + benefit. +

+ +

+ Support for synthetic event simulation is on the roadmap. +

+
+
+
+ + +
+
+ + + + + + + + + + +