blob: ea5f7cdfe48b6f52ecce9bbf4aa7c8961c437b4c [file] [log] [blame]
var channel = require('cordova/channel');
/**
* Listen for DOMContentLoaded and notify our channel subscribers.
*/
document.addEventListener('DOMContentLoaded', function() {
channel.onDOMContentLoaded.fire();
}, false);
if (document.readyState == 'complete' || document.readyState == 'interactive') {
channel.onDOMContentLoaded.fire();
}
/**
* Intercept calls to addEventListener + removeEventListener and handle deviceready,
* resume, and pause events.
*/
var m_document_addEventListener = document.addEventListener;
var m_document_removeEventListener = document.removeEventListener;
var m_window_addEventListener = window.addEventListener;
var m_window_removeEventListener = window.removeEventListener;
/**
* Houses custom event handlers to intercept on document + window event listeners.
*/
var documentEventHandlers = {},
windowEventHandlers = {};
document.addEventListener = function(evt, handler, capture) {
var e = evt.toLowerCase();
if (typeof documentEventHandlers[e] != 'undefined') {
if (evt === 'deviceready') {
documentEventHandlers[e].subscribeOnce(handler);
} else {
documentEventHandlers[e].subscribe(handler);
}
} else {
m_document_addEventListener.call(document, evt, handler, capture);
}
};
window.addEventListener = function(evt, handler, capture) {
var e = evt.toLowerCase();
if (typeof windowEventHandlers[e] != 'undefined') {
windowEventHandlers[e].subscribe(handler);
} else {
m_window_addEventListener.call(window, evt, handler, capture);
}
};
document.removeEventListener = function(evt, handler, capture) {
var e = evt.toLowerCase();
// If unsubcribing from an event that is handled by a plugin
if (typeof documentEventHandlers[e] != "undefined") {
documentEventHandlers[e].unsubscribe(handler);
} else {
m_document_removeEventListener.call(document, evt, handler, capture);
}
};
window.removeEventListener = function(evt, handler, capture) {
var e = evt.toLowerCase();
// If unsubcribing from an event that is handled by a plugin
if (typeof windowEventHandlers[e] != "undefined") {
windowEventHandlers[e].unsubscribe(handler);
} else {
m_window_removeEventListener.call(window, evt, handler, capture);
}
};
function createEvent(type, data) {
var event = document.createEvent('Events');
event.initEvent(type, false, false);
if (data) {
for (var i in data) {
if (data.hasOwnProperty(i)) {
event[i] = data[i];
}
}
}
return event;
}
if(typeof window.console === "undefined") {
window.console = {
log:function(){}
};
}
var cordova = {
define:define,
require:require,
/**
* Methods to add/remove your own addEventListener hijacking on document + window.
*/
addWindowEventHandler:function(event, opts) {
return (windowEventHandlers[event] = channel.create(event, opts));
},
addDocumentEventHandler:function(event, opts) {
return (documentEventHandlers[event] = channel.create(event, opts));
},
removeWindowEventHandler:function(event) {
delete windowEventHandlers[event];
},
removeDocumentEventHandler:function(event) {
delete documentEventHandlers[event];
},
/**
* Retreive original event handlers that were replaced by Cordova
*
* @return object
*/
getOriginalHandlers: function() {
return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},
'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};
},
/**
* Method to fire event from native code
*/
fireDocumentEvent: function(type, data) {
var evt = createEvent(type, data);
if (typeof documentEventHandlers[type] != 'undefined') {
setTimeout(function() {
documentEventHandlers[type].fire(evt);
}, 0);
} else {
document.dispatchEvent(evt);
}
},
fireWindowEvent: function(type, data) {
var evt = createEvent(type,data);
if (typeof windowEventHandlers[type] != 'undefined') {
setTimeout(function() {
windowEventHandlers[type].fire(evt);
}, 0);
} else {
window.dispatchEvent(evt);
}
},
// TODO: iOS only
// This queue holds the currently executing command and all pending
// commands executed with cordova.exec().
commandQueue:[],
// Indicates if we're currently in the middle of flushing the command
// queue on the native side.
commandQueueFlushing:false,
// END TODO
/**
* Plugin callback mechanism.
*/
callbackId: 0,
callbacks: {},
callbackStatus: {
NO_RESULT: 0,
OK: 1,
CLASS_NOT_FOUND_EXCEPTION: 2,
ILLEGAL_ACCESS_EXCEPTION: 3,
INSTANTIATION_EXCEPTION: 4,
MALFORMED_URL_EXCEPTION: 5,
IO_EXCEPTION: 6,
INVALID_ACTION: 7,
JSON_EXCEPTION: 8,
ERROR: 9
},
/**
* Called by native code when returning successful result from an action.
*
* @param callbackId
* @param args
*/
callbackSuccess: function(callbackId, args) {
if (cordova.callbacks[callbackId]) {
// If result is to be sent to callback
if (args.status == cordova.callbackStatus.OK) {
try {
if (cordova.callbacks[callbackId].success) {
cordova.callbacks[callbackId].success(args.message);
}
}
catch (e) {
console.log("Error in success callback: "+callbackId+" = "+e);
}
}
// Clear callback if not expecting any more results
if (!args.keepCallback) {
delete cordova.callbacks[callbackId];
}
}
},
/**
* Called by native code when returning error result from an action.
*
* @param callbackId
* @param args
*/
callbackError: function(callbackId, args) {
if (cordova.callbacks[callbackId]) {
try {
if (cordova.callbacks[callbackId].fail) {
cordova.callbacks[callbackId].fail(args.message);
}
}
catch (e) {
console.log("Error in error callback: "+callbackId+" = "+e);
}
// Clear callback if not expecting any more results
if (!args.keepCallback) {
delete cordova.callbacks[callbackId];
}
}
},
addConstructor: function(func) {
channel.onCordovaReady.subscribeOnce(function() {
try {
func();
} catch(e) {
console.log("Failed to run constructor: " + e);
}
});
}
};
// Register pause, resume and deviceready channels as events on document.
channel.onPause = cordova.addDocumentEventHandler('pause');
channel.onResume = cordova.addDocumentEventHandler('resume');
channel.onDeviceReady = cordova.addDocumentEventHandler('deviceready');
module.exports = cordova;