window.IonicDevServerConfig = window.IonicDevServerConfig || {};
window.IonicDevServer = {
start: function() {
this.msgQueue = [];
this.consoleLog = console.log;
this.consoleError = console.error;
this.consoleWarn = console.warn;
IonicDevServerConfig.systemInfo.push('Navigator Platform: ' + window.navigator.platform);
IonicDevServerConfig.systemInfo.push('User Agent: ' + window.navigator.userAgent);
if (IonicDevServerConfig.sendConsoleLogs) {
this.patchConsole();
}
this.openConnection();
this.bindEvents();
var self = this;
document.addEventListener("DOMContentLoaded", function() {
var diagnosticsEle = document.getElementById('ion-diagnostics');
if (diagnosticsEle) {
self.buildStatus('error');
} else {
self.buildStatus('success');
}
});
if (window.cordova && document.documentElement) {
document.documentElement.classList.add('ion-diagnostics-cordova');
var ua = window.navigator.userAgent.toLowerCase();
if ((ua.indexOf('ipad') > -1 || ua.indexOf('iphone') > -1 || ua.indexOf('ipod') > -1) && ua.indexOf('windows phone') === -1) {
document.documentElement.classList.add('ion-diagnostics-cordova-ios');
}
}
window.onerror = function(msg, url, lineNo, columnNo, error) {
self.handleError(error);
};
},
handleError: function(err) {
if (!err) return;
// Ignore HTTP errors
if(err.url || err.headers) return;
// Socket is ready so send this error to the server for prettifying
if (this.socketReady) {
var msg = {
category: 'runtimeError',
type: 'runtimeError',
data: {
message: err.message ? err.message.toString() : null,
stack: err.stack ? err.stack.toString() : null
}
};
this.queueMessageSend(msg);
} else {
var c = [];
c.push('
');
c.push('');
c.push('
');
c.push('
');
c.push(' ');
c.push('
' + this.escapeHtml(err.stack) + '
');
c.push('
');
c.push('
');
this.buildUpdate({
type: 'clientError',
data: {
diagnosticsHtml: c.join('')
}
});
}
},
reloadApp: function() {
window.location.reload(true);
},
openConnection: function() {
var self = this;
this.socket = new WebSocket('ws://' + window.location.hostname + ':' + IonicDevServerConfig.wsPort);
this.socket.onopen = function(ev) {
self.socketReady = true;
self.socket.onmessage = function(ev) {
try {
var msg = JSON.parse(ev.data);
switch (msg.category) {
case 'buildUpdate':
self.buildUpdate(msg);
break;
}
} catch (e) {
self.consoleError('error receiving ws message', e);
}
};
self.socket.onclose = function() {
self.consoleLog('Dev server logger closed');
self.socketReady = false;
};
self.drainMessageQueue();
};
},
queueMessageSend: function(msg) {
this.msgQueue.push(msg);
this.drainMessageQueue();
},
drainMessageQueue: function() {
if (this.socketReady) {
var msg;
while (msg = this.msgQueue.shift()) {
try {
this.socket.send(JSON.stringify(msg));
} catch(e) {
if (e instanceof TypeError) {
} else {
this.consoleError('ws error: ' + e);
}
}
}
}
},
patchConsole: function() {
var self = this;
function patchConsole(consoleType) {
console[consoleType] = (function() {
var orgConsole = console[consoleType];
return function() {
orgConsole.apply(console, arguments);
var msg = {
category: 'console',
type: consoleType,
data: []
};
for (var i = 0; i < arguments.length; i++) {
msg.data.push(arguments[i]);
}
if (msg.data.length) {
self.queueMessageSend(msg);
}
};
})();
}
// https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-console/#supported-methods
var consoleFns = ['log', 'error', 'exception', 'warn', 'info', 'debug', 'assert', 'dir', 'dirxml', 'time', 'timeEnd', 'table'];
for (var i in consoleFns) {
patchConsole(consoleFns[i]);
}
},
/**
* Process a build update message and display something to the friendly user.
*/
buildUpdate: function(msg) {
var status = 'success';
if (msg.type === 'started') {
status = 'active';
this.buildingNotification(true);
} else {
if (msg.data.reloadApp) {
this.reloadApp();
return;
}
status = msg.data.diagnosticsHtml ? 'error' : 'success';
this.buildingNotification(false);
var diagnosticsEle = document.getElementById('ion-diagnostics');
// If we have an element but no html created yet
if (diagnosticsEle && !msg.data.diagnosticsHtml) {
diagnosticsEle.classList.add('ion-diagnostics-fade-out');
this.diagnosticsTimerId = setTimeout(function() {
var diagnosticsEle = document.getElementById('ion-diagnostics');
if (diagnosticsEle) {
diagnosticsEle.parentElement.removeChild(diagnosticsEle);
}
}, 100);
} else if (msg.data.diagnosticsHtml) {
// We don't have an element but we have diagnostics HTML, so create the error
if (!diagnosticsEle) {
diagnosticsEle = document.createElement('div');
diagnosticsEle.id = 'ion-diagnostics';
diagnosticsEle.className = 'ion-diagnostics-fade-out';
document.body.insertBefore(diagnosticsEle, document.body.firstChild);
}
// Show the last error
clearTimeout(this.diagnosticsTimerId);
this.diagnosticsTimerId = setTimeout(function() {
var diagnosticsEle = document.getElementById('ion-diagnostics');
if (diagnosticsEle) {
diagnosticsEle.classList.remove('ion-diagnostics-fade-out');
}
}, 24);
diagnosticsEle.innerHTML = msg.data.diagnosticsHtml
}
}
this.buildStatus(status);
},
buildStatus: function (status) {
var iconLinks = document.querySelectorAll('link[rel="icon"]');
for (var i = 0; i < iconLinks.length; i++) {
iconLinks[i].parentElement.removeChild(iconLinks[i]);
}
var iconLink = document.createElement('link');
iconLink.rel = 'icon';
iconLink.type = 'image/png';
iconLink.href = this[status + 'Icon'];
document.head.appendChild(iconLink);
if (status === 'error') {
var diagnosticsEle = document.getElementById('ion-diagnostics');
if (diagnosticsEle) {
var systemInfoEle = diagnosticsEle.querySelector('#ion-diagnostics-system-info');
if (!systemInfoEle) {
systemInfoEle = document.createElement('div');
systemInfoEle.id = 'ion-diagnostics-system-info';
systemInfoEle.innerHTML = IonicDevServerConfig.systemInfo.join('\n');
diagnosticsEle.querySelector('.ion-diagnostics-content').appendChild(systemInfoEle);
}
}
}
},
buildingNotification: function(showToast) {
clearTimeout(this.toastTimerId);
var toastEle = document.getElementById('ion-diagnostics-toast');
if (showToast) {
if (!toastEle) {
toastEle = document.createElement('div');
toastEle.id = 'ion-diagnostics-toast';
var c = []
c.push('');
c.push('
Building...
');
c.push('
');
c.push(' ');
c.push('
');
c.push('
');
toastEle.innerHTML = c.join('');
document.body.insertBefore(toastEle, document.body.firstChild);
}
this.toastTimerId = setTimeout(function() {
var toastEle = document.getElementById('ion-diagnostics-toast');
if (toastEle) {
toastEle.classList.add('ion-diagnostics-toast-active');
}
}, 16);
} else if (!showToast && toastEle) {
toastEle.classList.remove('ion-diagnostics-toast-active');
}
},
toggleOptionsMenu: function() {
var optsEle = document.getElementById('ion-diagnostics-options');
this.optionsMenu(!optsEle);
},
optionsMenu: function(showMenu) {
clearTimeout(this.optionsMenuTimerId);
var optsEle = document.getElementById('ion-diagnostics-options');
if (showMenu) {
if (!optsEle) {
var c = [];
c.push('