Created
October 21, 2013 11:28
-
-
Save ferronrsmith/7082370 to your computer and use it in GitHub Desktop.
Function to trigger events in phamtomjs. Adapted from ng-scenario
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
(function () { | |
var msie = parseInt((/msie (\d+)/.exec(navigator.userAgent.toLowerCase()) || [])[1], 10); | |
function indexOf(array, obj) { | |
if (array.indexOf) return array.indexOf(obj); | |
for ( var i = 0; i < array.length; i++) { | |
if (obj === array[i]) return i; | |
} | |
return -1; | |
} | |
/** | |
* Triggers a browser event. Attempts to choose the right event if one is | |
* not specified. | |
* | |
* @param {Object} element Either a wrapped jQuery/jqLite node or a DOMElement | |
* @param {string} eventType Optional event type | |
* @param {Object=} eventData An optional object which contains additional event data (such as x,y coordinates, keys, etc...) that | |
* are passed into the event when triggered | |
*/ | |
window.browserTrigger = function browserTrigger(element, eventType, eventData) { | |
if (element && !element.nodeName) element = element[0]; | |
if (!element) return; | |
eventData = eventData || {}; | |
var keys = eventData.keys; | |
var x = eventData.x; | |
var y = eventData.y; | |
var inputType = (element.type) ? element.type.toLowerCase() : null, | |
nodeName = element.nodeName.toLowerCase(); | |
if (!eventType) { | |
eventType = { | |
'text': 'change', | |
'textarea': 'change', | |
'hidden': 'change', | |
'password': 'change', | |
'button': 'click', | |
'submit': 'click', | |
'reset': 'click', | |
'image': 'click', | |
'checkbox': 'click', | |
'radio': 'click', | |
'select-one': 'change', | |
'select-multiple': 'change', | |
'_default_': 'click' | |
}[inputType || '_default_']; | |
} | |
if (nodeName == 'option') { | |
element.parentNode.value = element.value; | |
element = element.parentNode; | |
eventType = 'change'; | |
} | |
keys = keys || []; | |
function pressed(key) { | |
return indexOf(keys, key) !== -1; | |
} | |
if (msie < 9) { | |
if (inputType == 'radio' || inputType == 'checkbox') { | |
element.checked = !element.checked; | |
} | |
// WTF!!! Error: Unspecified error. | |
// Don't know why, but some elements when detached seem to be in inconsistent state and | |
// calling .fireEvent() on them will result in very unhelpful error (Error: Unspecified error) | |
// forcing the browser to compute the element position (by reading its CSS) | |
// puts the element in consistent state. | |
element.style.posLeft; | |
// TODO(vojta): create event objects with pressed keys to get it working on IE<9 | |
var ret = element.fireEvent('on' + eventType); | |
if (inputType == 'submit') { | |
while(element) { | |
if (element.nodeName.toLowerCase() == 'form') { | |
element.fireEvent('onsubmit'); | |
break; | |
} | |
element = element.parentNode; | |
} | |
} | |
return ret; | |
} else { | |
var evnt; | |
if(/transitionend/.test(eventType)) { | |
if(window.WebKitTransitionEvent) { | |
evnt = new WebKitTransitionEvent(eventType, eventData); | |
evnt.initEvent(eventType, false, true); | |
} | |
else { | |
try { | |
evnt = new TransitionEvent(eventType, eventData); | |
} | |
catch(e) { | |
evnt = document.createEvent('TransitionEvent'); | |
evnt.initTransitionEvent(eventType, null, null, null, eventData.elapsedTime || 0); | |
} | |
} | |
} | |
else if(/animationend/.test(eventType)) { | |
if(window.WebKitAnimationEvent) { | |
evnt = new WebKitAnimationEvent(eventType, eventData); | |
evnt.initEvent(eventType, false, true); | |
} | |
else { | |
try { | |
evnt = new AnimationEvent(eventType, eventData); | |
} | |
catch(e) { | |
evnt = document.createEvent('AnimationEvent'); | |
evnt.initAnimationEvent(eventType, null, null, null, eventData.elapsedTime || 0); | |
} | |
} | |
} | |
else { | |
evnt = document.createEvent('MouseEvents'); | |
x = x || 0; | |
y = y || 0; | |
evnt.initMouseEvent(eventType, true, true, window, 0, x, y, x, y, pressed('ctrl'), pressed('alt'), | |
pressed('shift'), pressed('meta'), 0, element); | |
} | |
/* we're unable to change the timeStamp value directly so this | |
* is only here to allow for testing where the timeStamp value is | |
* read */ | |
evnt.$manualTimeStamp = eventData.timeStamp; | |
if(!evnt) return; | |
var originalPreventDefault = evnt.preventDefault, | |
appWindow = element.ownerDocument.defaultView, | |
fakeProcessDefault = true, | |
finalProcessDefault, | |
angular = appWindow.angular || {}; | |
// igor: temporary fix for https://bugzilla.mozilla.org/show_bug.cgi?id=684208 | |
angular['ff-684208-preventDefault'] = false; | |
evnt.preventDefault = function() { | |
fakeProcessDefault = false; | |
return originalPreventDefault.apply(evnt, arguments); | |
}; | |
element.dispatchEvent(evnt); | |
finalProcessDefault = !(angular['ff-684208-preventDefault'] || !fakeProcessDefault); | |
delete angular['ff-684208-preventDefault']; | |
return finalProcessDefault; | |
} | |
} | |
}()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment