Skip to content

Instantly share code, notes, and snippets.

@ferronrsmith
Created October 21, 2013 11:28
Show Gist options
  • Save ferronrsmith/7082370 to your computer and use it in GitHub Desktop.
Save ferronrsmith/7082370 to your computer and use it in GitHub Desktop.
Function to trigger events in phamtomjs. Adapted from ng-scenario
'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