blob: cb449c7431151112960622280f8ed5366e862c74 [file] [log] [blame]
<!DOCTYPE html>
<!--
Copyright (c) 2014 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<script>
'use strict';
/**
* The global object.
* @type {!Object}
* @const
*/
var global = this;
/** Platform, package, object property, and Event support. */
this.tr = (function() {
if (global.tr) {
console.warn('Base was multiply initialized. First init wins.');
return global.tr;
}
/**
* Builds an object structure for the provided namespace path,
* ensuring that names that already exist are not overwritten. For
* example:
* 'a.b.c' -> a = {};a.b={};a.b.c={};
* @param {string} name Name of the object that this file defines.
* @private
*/
function exportPath(name) {
var parts = name.split('.');
var cur = global;
for (var part; parts.length && (part = parts.shift());) {
if (part in cur) {
cur = cur[part];
} else {
cur = cur[part] = {};
}
}
return cur;
};
function isExported(name) {
var parts = name.split('.');
var cur = global;
for (var part; parts.length && (part = parts.shift());) {
if (part in cur) {
cur = cur[part];
} else {
return false;
}
}
return true;
}
function isDefined(name) {
var parts = name.split('.');
var curObject = global;
for (var i = 0; i < parts.length; i++) {
var partName = parts[i];
var nextObject = curObject[partName];
if (nextObject === undefined)
return false;
curObject = nextObject;
}
return true;
}
var panicElement = undefined;
var rawPanicMessages = [];
function showPanicElementIfNeeded() {
if (panicElement)
return;
var panicOverlay = document.createElement('div');
panicOverlay.style.backgroundColor = 'white';
panicOverlay.style.border = '3px solid red';
panicOverlay.style.boxSizing = 'border-box';
panicOverlay.style.color = 'black';
panicOverlay.style.display = '-webkit-flex';
panicOverlay.style.height = '100%';
panicOverlay.style.left = 0;
panicOverlay.style.padding = '8px';
panicOverlay.style.position = 'fixed';
panicOverlay.style.top = 0;
panicOverlay.style.webkitFlexDirection = 'column';
panicOverlay.style.width = '100%';
panicElement = document.createElement('div');
panicElement.style.webkitFlex = '1 1 auto';
panicElement.style.overflow = 'auto';
panicOverlay.appendChild(panicElement);
if (!document.body) {
setTimeout(function() {
document.body.appendChild(panicOverlay);
}, 150);
} else {
document.body.appendChild(panicOverlay);
}
}
function showPanic(panicTitle, panicDetails) {
if (tr.isHeadless) {
if (panicDetails instanceof Error)
throw panicDetails;
throw new Error('Panic: ' + panicTitle + ':\n' + panicDetails);
}
if (panicDetails instanceof Error)
panicDetails = panicDetails.stack;
showPanicElementIfNeeded();
var panicMessageEl = document.createElement('div');
panicMessageEl.innerHTML =
'<h2 id="message"></h2>' +
'<pre id="details"></pre>';
panicMessageEl.querySelector('#message').textContent = panicTitle;
panicMessageEl.querySelector('#details').textContent = panicDetails;
panicElement.appendChild(panicMessageEl);
rawPanicMessages.push({
title: panicTitle,
details: panicDetails
});
}
function hasPanic() {
return rawPanicMessages.length !== 0;
}
function getPanicText() {
return rawPanicMessages.map(function(msg) {
return msg.title;
}).join(', ');
}
function exportTo(namespace, fn) {
var obj = exportPath(namespace);
var exports = fn();
for (var propertyName in exports) {
// Maybe we should check the prototype chain here? The current usage
// pattern is always using an object literal so we only care about own
// properties.
var propertyDescriptor = Object.getOwnPropertyDescriptor(exports,
propertyName);
if (propertyDescriptor)
Object.defineProperty(obj, propertyName, propertyDescriptor);
}
};
/**
* Initialization which must be deferred until run-time.
*/
function initialize() {
if (global.version && global.version()) {
tr.isD8 = true;
} else if (global.process && global.process.versions.node) {
tr.isNode = true;
} else {
tr.isD8 = false;
tr.isNode = false;
tr.doc = document;
tr.isMac = /Mac/.test(navigator.platform);
tr.isWindows = /Win/.test(navigator.platform);
tr.isChromeOS = /CrOS/.test(navigator.userAgent);
tr.isLinux = /Linux/.test(navigator.userAgent);
}
tr.isHeadless = tr.isD8 || tr.isNode;
}
return {
initialize: initialize,
exportTo: exportTo,
isExported: isExported,
isDefined: isDefined,
showPanic: showPanic,
hasPanic: hasPanic,
getPanicText: getPanicText
};
})();
tr.initialize();
</script>