/** * @license * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt * Code distributed by Google as part of the polymer project is also * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt */ (function(global) { 'use strict'; var HAS_NEW_MOUSE = (function() { var has = false; try { has = Boolean(new MouseEvent('x')); } catch (_) {} return has; })(); function middleOfNode(node) { var bcr = node.getBoundingClientRect(); return { y: bcr.top + (bcr.height / 2), x: bcr.left + (bcr.width / 2) }; } function topLeftOfNode(node) { var bcr = node.getBoundingClientRect(); return { y: bcr.top, x: bcr.left }; } function makeEvent(type, xy, node) { var props = { bubbles: true, cancelable: true, clientX: xy.x, clientY: xy.y, // Make this a primary input. buttons: 1 // http://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons }; var e; var mousetype = type === 'tap' ? 'click' : 'mouse' + type; if (HAS_NEW_MOUSE) { e = new MouseEvent(mousetype, props); } else { e = document.createEvent('MouseEvent'); e.initMouseEvent( mousetype, props.bubbles, props.cancelable, null, /* view */ null, /* detail */ 0, /* screenX */ 0, /* screenY */ props.clientX, props.clientY, false, /*ctrlKey */ false, /*altKey */ false, /*shiftKey */ false, /*metaKey */ 0, /*button */ null /*relatedTarget*/); } node.dispatchEvent(e); } function down(node, xy) { xy = xy || middleOfNode(node); makeEvent('down', xy, node); } function move(node, fromXY, toXY, steps) { steps = steps || 5; var dx = Math.round((fromXY.x - toXY.x) / steps); var dy = Math.round((fromXY.y - toXY.y) / steps); var xy = { x: fromXY.x, y: fromXY.y }; for (var i = steps; i > 0; i--) { makeEvent('move', xy, node); xy.x += dx; xy.y += dy; } makeEvent('move', { x: toXY.x, y: toXY.y }, node); } function up(node, xy) { xy = xy || middleOfNode(node); makeEvent('up', xy, node); } function tap(node) { // Respect nodes that are disabled in the UI. if (window.getComputedStyle(node)['pointer-events'] === 'none') return; var xy = middleOfNode(node); down(node, xy); up(node, xy); makeEvent('tap', xy, node); } function focus(target) { Polymer.Base.fire.call(target, 'focus', {}, { bubbles: false }); } function blur(target) { Polymer.Base.fire.call(target, 'blur', {}, { bubbles: false }); } function downAndUp(target, callback) { down(target); Polymer.Base.async(function() { up(target); tap(target); callback && callback(); }); } function track(target, dx, dy, steps) { dx = dx | 0; dy = dy | 0; steps = steps || 5; down(target); var xy = middleOfNode(target); var xy2 = { x: xy.x + dx, y: xy.y + dy }; move(target, xy, xy2, steps); up(target, xy2); } function keyboardEventFor(type, keyCode) { var event = new CustomEvent(type); event.keyCode = keyCode; event.code = keyCode; return event; } function keyEventOn(target, type, keyCode) { target.dispatchEvent(keyboardEventFor(type, keyCode)); } function keyDownOn(target, keyCode) { keyEventOn(target, 'keydown', keyCode); } function keyUpOn(target, keyCode) { keyEventOn(target, 'keyup', keyCode); } function pressAndReleaseKeyOn(target, keyCode) { keyDownOn(target, keyCode); Polymer.Base.async(function() { keyUpOn(target, keyCode); }, 1); } function pressEnter(target) { pressAndReleaseKeyOn(target, 13); } function pressSpace(target) { pressAndReleaseKeyOn(target, 32); } global.MockInteractions = { focus: focus, blur: blur, down: down, up: up, downAndUp: downAndUp, tap: tap, track: track, pressAndReleaseKeyOn: pressAndReleaseKeyOn, pressEnter: pressEnter, pressSpace: pressSpace, keyDownOn: keyDownOn, keyUpOn: keyUpOn, middleOfNode: middleOfNode, topLeftOfNode: topLeftOfNode }; })(this);