blob: 10da6c242937f60da706725d68956b11b69e99a4 [file] [log] [blame]
Chris Craikb122baf2015-03-05 13:58:42 -08001<!DOCTYPE html>
2<!--
3Copyright (c) 2014 The Chromium Authors. All rights reserved.
4Use of this source code is governed by a BSD-style license that can be
5found in the LICENSE file.
6-->
7<script>
8'use strict';
9
10
11/**
12 * The global object.
13 * @type {!Object}
14 * @const
15 */
16var global = this;
17
18/** Platform, package, object property, and Event support. */
19this.tv = (function() {
20 if (window.tv) {
21 console.warn('Base was multiply initialized. First init wins.');
22 return window.tv;
23 }
24
25 /**
26 * Builds an object structure for the provided namespace path,
27 * ensuring that names that already exist are not overwritten. For
28 * example:
29 * 'a.b.c' -> a = {};a.b={};a.b.c={};
30 * @param {string} name Name of the object that this file defines.
31 * @param {*=} opt_object The object to expose at the end of the path.
32 * @param {Object=} opt_objectToExportTo The object to add the path to;
33 * default is {@code global}.
34 * @private
35 */
36 function exportPath(name, opt_object, opt_objectToExportTo) {
37 var parts = name.split('.');
38 var cur = opt_objectToExportTo || global;
39
40 for (var part; parts.length && (part = parts.shift());) {
41 if (!parts.length && opt_object !== undefined) {
42 // last part and we have an object; use it
43 cur[part] = opt_object;
44 } else if (part in cur) {
45 cur = cur[part];
46 } else {
47 cur = cur[part] = {};
48 }
49 }
50 return cur;
51 };
52
53 function isDefined(name, opt_globalObject) {
54 var parts = name.split('.');
55
56 var curObject = opt_globalObject || global;
57
58 for (var i = 0; i < parts.length; i++) {
59 var partName = parts[i];
60 var nextObject = curObject[partName];
61 if (nextObject === undefined)
62 return false;
63 curObject = nextObject;
64 }
65 return true;
66 }
67
68 var panicElement = undefined;
69 var rawPanicMessages = [];
70 function showPanicElementIfNeeded() {
71 if (panicElement)
72 return;
73
74 var panicOverlay = document.createElement('div');
75 panicOverlay.style.backgroundColor = 'white';
76 panicOverlay.style.border = '3px solid red';
77 panicOverlay.style.boxSizing = 'border-box';
78 panicOverlay.style.color = 'black';
79 panicOverlay.style.display = '-webkit-flex';
80 panicOverlay.style.height = '100%';
81 panicOverlay.style.left = 0;
82 panicOverlay.style.padding = '8px';
83 panicOverlay.style.position = 'fixed';
84 panicOverlay.style.top = 0;
85 panicOverlay.style.webkitFlexDirection = 'column';
86 panicOverlay.style.width = '100%';
87
88 panicElement = document.createElement('div');
89 panicElement.style.webkitFlex = '1 1 auto';
90 panicElement.style.overflow = 'auto';
91 panicOverlay.appendChild(panicElement);
92
93 if (!document.body) {
94 setTimeout(function() {
95 document.body.appendChild(panicOverlay);
96 }, 150);
97 } else {
98 document.body.appendChild(panicOverlay);
99 }
100 }
101
102 function showPanic(panicTitle, panicDetails) {
103
104 if (panicDetails instanceof Error)
105 panicDetails = panicDetails.stack;
106
107 showPanicElementIfNeeded();
108 var panicMessageEl = document.createElement('div');
109 panicMessageEl.innerHTML =
110 '<h2 id="message"></h2>' +
111 '<pre id="details"></pre>';
112 panicMessageEl.querySelector('#message').textContent = panicTitle;
113 panicMessageEl.querySelector('#details').textContent = panicDetails;
114 panicElement.appendChild(panicMessageEl);
115
116 rawPanicMessages.push({
117 title: panicTitle,
118 details: panicDetails
119 });
120 }
121
122 function hasPanic() {
123 return rawPanicMessages.length !== 0;
124 }
125 function getPanicText() {
126 return rawPanicMessages.map(function(msg) {
127 return msg.title;
128 }).join(', ');
129 }
130
131 function exportTo(namespace, fn) {
132 var obj = exportPath(namespace);
133 var exports = fn();
134
135 for (var propertyName in exports) {
136 // Maybe we should check the prototype chain here? The current usage
137 // pattern is always using an object literal so we only care about own
138 // properties.
139 var propertyDescriptor = Object.getOwnPropertyDescriptor(exports,
140 propertyName);
141 if (propertyDescriptor)
142 Object.defineProperty(obj, propertyName, propertyDescriptor);
143 }
144 };
145
146 /**
147 * Initialization which must be deferred until run-time.
148 */
149 function initialize() {
150 if (!window._TRACE_VIEWER_IS_COMPILED) {
151 var ver = parseInt(
152 window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10);
153 var support_content_shell = window.navigator.appVersion.match('77.34.5');
154 if (ver < 36 && !support_content_shell) {
155 var msg = 'A Chrome version of 36 or higher is required for ' +
156 'trace-viewer development. Please upgrade your version of Chrome ' +
157 'and try again.';
158 showPanic('Invalid Chrome version', msg);
159 }
160 }
161
162 tv.doc = document;
163
164 tv.isMac = /Mac/.test(navigator.platform);
165 tv.isWindows = /Win/.test(navigator.platform);
166 tv.isChromeOS = /CrOS/.test(navigator.userAgent);
167 tv.isLinux = /Linux/.test(navigator.userAgent);
168 }
169
170 return {
171 initialize: initialize,
172
173 exportTo: exportTo,
174 isDefined: isDefined,
175
176 showPanic: showPanic,
177 hasPanic: hasPanic,
178 getPanicText: getPanicText
179 };
180})();
181
182tv.initialize();
183</script>