//# sourceURL=capacitor-runtime.js (function(win) { win.Capacitor = win.Capacitor || { Plugins: {} }; var capacitor = Capacitor; // Export Cordova if not defined win.cordova = win.cordova || {}; // Add any legacy handlers to keep Cordova compat 100% good addLegacyHandlers(win); capacitor.Plugins = capacitor.Plugins || {}; capacitor.DEBUG = typeof capacitor.DEBUG === 'undefined' ? true : capacitor.DEBUG; // keep a collection of callbacks for native response data var calls = {}; // Counter of callback ids, randomized to avoid // any issues during reloads if a call comes back with // an existing callback id from an old session var callbackIdCount = Math.floor(Math.random() * 134217728); var lastError = null; var errorModal = null; // create the postToNative() fn if needed if (win.androidBridge) { // android platform postToNative = function androidBridge(data) { win.androidBridge.postMessage(JSON.stringify(data)); }; capacitor.isNative = true; capacitor.isAndroid = true; capacitor.platform = 'android'; } else if (win.webkit && win.webkit.messageHandlers && win.webkit.messageHandlers.bridge) { // ios platform postToNative = function iosBridge(data) { data.type = 'message'; win.webkit.messageHandlers.bridge.postMessage(data); }; capacitor.isNative = true; capacitor.isIOS = true; capacitor.platform = 'ios'; } var useFallbackLogging = Object.keys(win.console).length === 0; if(useFallbackLogging) { win.console.warn('Advance console logging disabled.') } // patch window.console on iOS and store original console fns var orgConsole = capacitor.isIOS ? {} : win.console; // list log functions bridged to native log var bridgedLevels = { debug: true, error: true, info: true, log: true, trace: true, warn: true, }; if (capacitor.isIOS) { Object.keys(win.console).forEach(function (level) { if (typeof win.console[level] === 'function') { // loop through all the console functions and keep references to the original orgConsole[level] = win.console[level]; win.console[level] = function capacitorConsole() { var msgs = Array.prototype.slice.call(arguments); // console log to browser orgConsole[level].apply(win.console, msgs); if (capacitor.isNative && bridgedLevels[level]) { // send log to native to print try { // convert all args to strings msgs = msgs.map(function (arg) { if (typeof arg === 'object') { try { arg = JSON.stringify(arg); } catch (e) {} } // convert to string return arg + ''; }); capacitor.toNative('Console', 'log', { level: level, message: msgs.join(' ') }); } catch (e) { // error converting/posting console messages orgConsole.error.apply(win.console, e); } } }; } }); } function addLegacyHandlers(win) { win.navigator.app = { exitApp: function() { capacitor.toNative("App", "exitApp", {}, null); } } var documentAddEventListener = document.addEventListener; document.addEventListener = function() { var name = arguments[0]; var handler = arguments[1]; if (name === 'deviceready') { setTimeout(function() { handler && handler(); }); } else if (name === 'backbutton') { // Add a dummy listener so Capacitor doesn't do the default // back button action Capacitor.Plugins.App && Capacitor.Plugins.App.addListener('backButton', function() {}); } return documentAddEventListener.apply(document, arguments); } } /* * Check if a Plugin is available */ capacitor.isPluginAvailable = function isPluginAvailable(name) { return this.Plugins.hasOwnProperty(name); } capacitor.convertFileSrc = function convertFileSrc(url) { if (!url) { return url; } if (url.startsWith('/')) { return window.WEBVIEW_SERVER_URL + '/_capacitor_file_' + url; } if (url.startsWith('file://')) { return window.WEBVIEW_SERVER_URL + url.replace('file://', '/_capacitor_file_'); } if (url.startsWith('content://')) { return window.WEBVIEW_SERVER_URL + url.replace('content:/', '/_capacitor_content_'); } return url; } /* * Check running platform */ capacitor.getPlatform = function getPlatform() { return this.platform; } /** * Send a plugin method call to the native layer */ capacitor.toNative = function toNative(pluginId, methodName, options, storedCallback) { try { if (capacitor.isNative) { var callbackId = '-1'; if (storedCallback && (typeof storedCallback.callback === 'function' || typeof storedCallback.resolve === 'function')) { // store the call for later lookup callbackId = ++callbackIdCount + ''; calls[callbackId] = storedCallback; } var call = { callbackId: callbackId, pluginId: pluginId, methodName: methodName, options: options || {} }; if (capacitor.DEBUG) { if (pluginId !== 'Console') { capacitor.logToNative(call); } } // post the call data to native postToNative(call); return callbackId; } else { orgConsole.warn.call(win.console, 'browser implementation unavailable for: ' + pluginId); } } catch (e) { orgConsole.error.call(win.console, e); } return null; }; /** * Process a response from the native layer. */ capacitor.fromNative = function fromNative(result) { if (capacitor.DEBUG) { if (result.pluginId !== 'Console') { capacitor.logFromNative(result); } } // get the stored call, if it exists try { var storedCall = calls[result.callbackId]; if (storedCall) { // looks like we've got a stored call if (result.error && typeof result.error === 'object') { // ensure stacktraces by copying error properties to an Error result.error = Object.keys(result.error).reduce(function(err, key) { err[key] = result.error[key]; return err; }, new Error()); } if (typeof storedCall.callback === 'function') { // callback if (result.success) { storedCall.callback(result.data); } else { storedCall.callback(null, result.error); } } else if (typeof storedCall.resolve === 'function') { // promise if (result.success) { storedCall.resolve(result.data); } else { storedCall.reject(result.error); } // no need to keep this stored callback // around for a one time resolve promise delete calls[result.callbackId]; } } else if (!result.success && result.error) { // no stored callback, but if there was an error let's log it orgConsole.warn.call(win.console, result.error); } if (result.save === false) { delete calls[result.callbackId]; } } catch (e) { orgConsole.error.call(win.console, e); } // always delete to prevent memory leaks // overkill but we're not sure what apps will do with this data delete result.data; delete result.error; }; capacitor.logJs = function(message, level) { switch (level) { case 'error': console.error(message); break; case 'warn': console.warn(message); break; case 'info': console.info(message); break; default: console.log(message); } } capacitor.withPlugin = function withPlugin(_pluginId, _fn) { }; capacitor.nativeCallback = function (pluginId, methodName, options, callback) { if(typeof options === 'function') { callback = options; options = null; } return capacitor.toNative(pluginId, methodName, options, { callback: callback }); }; capacitor.nativePromise = function (pluginId, methodName, options) { return new Promise(function (resolve, reject) { capacitor.toNative(pluginId, methodName, options, { resolve: resolve, reject: reject }); }); }; capacitor.addListener = function(pluginId, eventName, callback) { var callbackId = capacitor.nativeCallback(pluginId, 'addListener', { eventName: eventName }, callback); return { remove: function() { console.log('Removing listener', pluginId, eventName); capacitor.removeListener(pluginId, callbackId, eventName, callback); } } }; capacitor.removeListener = function(pluginId, callbackId, eventName, callback) { capacitor.nativeCallback(pluginId, 'removeListener', { callbackId: callbackId, eventName: eventName }, callback); } capacitor.createEvent = function(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; } capacitor.triggerEvent = function(eventName, target, data) { var eventData = data || {}; var event = this.createEvent(eventName, eventData); if (target === "document") { if (cordova.fireDocumentEvent) { cordova.fireDocumentEvent(eventName, eventData); } else { document.dispatchEvent(event); } } else if (target === "window") { window.dispatchEvent(event); } else { var targetEl = document.querySelector(target); targetEl && targetEl.dispatchEvent(event); } } capacitor.handleError = function(error) { console.error(error); } capacitor.handleWindowError = function (msg, url, lineNo, columnNo, error) { var string = msg.toLowerCase(); var substring = "script error"; if (string.indexOf(substring) > -1) { // Some IE issue? } else { var errObj = { type: 'js.error', error: { message: msg, url: url, line: lineNo, col: columnNo, errorObject: JSON.stringify(error) } }; if (error !== null) { win.Capacitor.handleError(error); } if(capacitor.isAndroid) { win.androidBridge.postMessage(JSON.stringify(errObj)); } else if(capacitor.isIOS) { win.webkit.messageHandlers.bridge.postMessage(errObj); } } return false; }; capacitor.logToNative = function(call) { if(!useFallbackLogging) { var c = orgConsole; c.groupCollapsed('%cnative %c' + call.pluginId + '.' + call.methodName + ' (#' + call.callbackId + ')', 'font-weight: lighter; color: gray', 'font-weight: bold; color: #000'); c.dir(call); c.groupEnd(); } else { win.console.log('LOG TO NATIVE: ', call); if (capacitor.isIOS) { try { capacitor.toNative('Console', 'log', {message: JSON.stringify(call)}); } catch (e) { win.console.log('Error converting/posting console messages'); } } } } capacitor.logFromNative = function(result) { if(!useFallbackLogging) { var c = orgConsole; var success = result.success === true; var tagStyles = success ? 'font-style: italic; font-weight: lighter; color: gray' : 'font-style: italic; font-weight: lighter; color: red'; c.groupCollapsed('%cresult %c' + result.pluginId + '.' + result.methodName + ' (#' + result.callbackId + ')', tagStyles, 'font-style: italic; font-weight: bold; color: #444'); if (result.success === false) { c.error(result.error); } else { c.dir(result.data); } c.groupEnd(); } else { if (result.success === false) { win.console.error(result.error); } else { win.console.log(result.data); } } } capacitor.uuidv4 = function() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); } if (Capacitor.DEBUG) { window.onerror = capacitor.handleWindowError; } win.Ionic = win.Ionic || {}; win.Ionic.WebView = win.Ionic.WebView || {}; win.Ionic.WebView.getServerBasePath = function(callback) { Capacitor.Plugins.WebView.getServerBasePath().then(function(result) { callback(result.path); }); } win.Ionic.WebView.setServerBasePath = function (path) { Capacitor.Plugins.WebView.setServerBasePath({"path": path}); } win.Ionic.WebView.persistServerBasePath = function () { Capacitor.Plugins.WebView.persistServerBasePath(); } win.Ionic.WebView.convertFileSrc = function(url) { return Capacitor.convertFileSrc(url); } })(window);