| <!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. |
| --> |
| |
| <link rel="import" href="/tracing/base/base.html"> |
| |
| <script> |
| 'use strict'; |
| |
| tr.exportTo('tr.b', function() { |
| /** |
| * Adds a {@code getInstance} static method that always return the same |
| * instance object. |
| * @param {!Function} ctor The constructor for the class to add the static |
| * method to. |
| */ |
| function addSingletonGetter(ctor) { |
| ctor.getInstance = function() { |
| return ctor.instance_ || (ctor.instance_ = new ctor()); |
| }; |
| } |
| |
| function deepCopy(value) { |
| if (!(value instanceof Object)) { |
| if (value === undefined || value === null) |
| return value; |
| if (typeof value == 'string') |
| return value.substring(); |
| if (typeof value == 'boolean') |
| return value; |
| if (typeof value == 'number') |
| return value; |
| throw new Error('Unrecognized: ' + typeof value); |
| } |
| |
| var object = value; |
| if (object instanceof Array) { |
| var res = new Array(object.length); |
| for (var i = 0; i < object.length; i++) |
| res[i] = deepCopy(object[i]); |
| return res; |
| } |
| |
| if (object.__proto__ != Object.prototype) |
| throw new Error('Can only clone simple types'); |
| var res = {}; |
| for (var key in object) { |
| res[key] = deepCopy(object[key]); |
| } |
| return res; |
| } |
| |
| function normalizeException(e) { |
| if (e === undefined || e === null) { |
| return { |
| typeName: 'UndefinedError', |
| message: 'Unknown: null or undefined exception', |
| stack: 'Unknown' |
| }; |
| } |
| |
| if (typeof(e) == 'string') { |
| return { |
| typeName: 'StringError', |
| message: e, |
| stack: [e] |
| }; |
| } |
| |
| var typeName; |
| if (e.name) { |
| typeName = e.name; |
| } else if (e.constructor) { |
| if (e.constructor.name) { |
| typeName = e.constructor.name; |
| } else { |
| typeName = 'AnonymousError'; |
| } |
| } else { |
| typeName = 'ErrorWithNoConstructor'; |
| } |
| |
| var msg = e.message ? e.message : 'Unknown'; |
| return { |
| typeName: typeName, |
| message: msg, |
| stack: e.stack ? e.stack : [msg] |
| }; |
| } |
| |
| function stackTraceAsString() { |
| return new Error().stack + ''; |
| } |
| function stackTrace() { |
| var stack = stackTraceAsString(); |
| stack = stack.split('\n'); |
| return stack.slice(2); |
| } |
| |
| function getUsingPath(path, from_dict) { |
| var parts = path.split('.'); |
| var cur = from_dict; |
| |
| for (var part; parts.length && (part = parts.shift());) { |
| if (!parts.length) { |
| return cur[part]; |
| } else if (part in cur) { |
| cur = cur[part]; |
| } else { |
| return undefined; |
| } |
| } |
| return undefined; |
| } |
| |
| /** |
| * Format date as a string "YYYY-MM-DD HH:mm:ss". The timezone is implicitly |
| * UTC. This format is based on the ISO format, but without milliseconds and |
| * the 'T' is replaced with a space for legibility. |
| * |
| * @param {!Date} date |
| * @return {string} |
| */ |
| function formatDate(date) { |
| return date.toISOString().replace('T', ' ').slice(0, 19); |
| } |
| |
| return { |
| addSingletonGetter: addSingletonGetter, |
| |
| deepCopy: deepCopy, |
| |
| normalizeException: normalizeException, |
| stackTrace: stackTrace, |
| stackTraceAsString: stackTraceAsString, |
| formatDate: formatDate, |
| |
| getUsingPath: getUsingPath |
| }; |
| }); |
| </script> |