• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!DOCTYPE html>
2<!--
3Copyright 2015 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<link rel="import" href="/tracing/base/iteration_helpers.html">
8
9<script>
10'use strict';
11
12tr.exportTo('pi', function() {
13
14  var FunctionRegistry = {
15    allFunctions_: [],
16    allFunctionsByName_: {},
17    get allFunctions() { return this.allFunctions_; },
18    get allFunctionsByName() { return this.allFunctionsByName_; }
19  };
20
21  FunctionRegistry.getFunction = function(name) {
22    return this.allFunctionsByName_[name];
23  };
24
25  FunctionRegistry.register = function(func) {
26    if (func.name === '')
27      throw new Error('Registered functions must not be anonymous');
28    if (this.allFunctionsByName[func.name] !== undefined)
29      throw new Error('Function named ' + func.name + 'is already registered.');
30    this.allFunctionsByName[func.name] = func;
31    this.allFunctions.push(func);
32  };
33
34  function ModuleToLoad(href, filename) {
35    if ((href !== undefined) ? (filename !== undefined) :
36        (filename === undefined)) {
37      throw new Error('ModuleToLoad must specify exactly one of href or ' +
38                      'filename');
39    }
40    this.href = href;
41    this.filename = filename;
42  }
43
44  ModuleToLoad.prototype = {
45    asDict: function() {
46      if (this.href !== undefined)
47        return {'href': this.href};
48      return {'filename': this.filename};
49    },
50
51    toString: function() {
52      if (this.href !== undefined)
53        return 'ModuleToLoad(href="' + this.href + '")';
54      return 'ModuleToLoad(filename="' + this.filename + '")';
55    }
56  };
57
58  ModuleToLoad.fromDict = function(moduleDict) {
59    return new ModuleToLoad(moduleDict.href, moduleDict.filename);
60  };
61
62  function FunctionHandle(modulesToLoad, functionName, opt_options) {
63    if (!(modulesToLoad instanceof Array))
64      throw new Error('modulesToLoad in FunctionHandle must be an array');
65    if (typeof(functionName) !== 'string')
66      throw new Error('functionName in FunctionHandle must be a string');
67    this.modulesToLoad = modulesToLoad;
68    this.functionName = functionName;
69    this.options_ = opt_options;
70  };
71
72  FunctionHandle.prototype = {
73    get options() {
74      return this.options_;
75    },
76
77    asDict: function() {
78      return {
79        'modules_to_load': this.modulesToLoad.map(
80            function(m) {return m.asDict();}),
81        'function_name': this.functionName,
82        'options': this.options_
83      };
84    },
85
86    asUserFriendlyString: function() {
87      var parts = this.modulesToLoad.map(function(mtl) {return mtl.filename});
88      parts.push(this.functionName);
89      parts.push(JSON.stringify(this.options_));
90      return parts.join(',');
91    },
92
93    hasHrefs: function() {
94      for (var module in this.modulesToLoad) {
95        if (this.modulesToLoad[module].href !== undefined) {
96          return true;
97        }
98      }
99      return false;
100    },
101
102    load: function() {
103      if (this.hasHrefs()) {
104        var err = new Error(
105            'FunctionHandle named ' + this.functionName +
106            ' specifies hrefs, which cannot be loaded.');
107        err.name = 'FunctionLoadingError';
108        throw err;
109      }
110
111      for (var module in this.modulesToLoad) {
112        var filename = this.modulesToLoad[module].filename;
113        try {
114          HTMLImportsLoader.loadHTMLFile(filename);
115        } catch (err) {
116          err.name = 'FunctionLoadingError';
117          throw err;
118        }
119      }
120
121      var func = FunctionRegistry.getFunction(this.functionName);
122      if (func === undefined) {
123        var err = new Error(
124            'No registered function named ' + this.functionName);
125        err.name = 'FunctionNotDefinedError';
126        throw err;
127      }
128
129      return func;
130    },
131
132    toString: function() {
133      var modulesToLoadStr = this.modulesToLoad.map(function(module) {
134          return module.toString();
135      });
136      return 'FunctionHandle(modulesToLoad=[' + modulesToLoadStr + '], ' +
137          'functionName="' + this.functionName + '", options="' +
138          JSON.stringify(this.options_) + '")';
139    }
140  };
141
142  FunctionHandle.loadFromFilename_ = function(filename) {
143    try {
144      var numFunctionsBefore = FunctionRegistry.allFunctions.length;
145      HTMLImportsLoader.loadHTMLFile(filename);
146    } catch (err) {
147      err.name = 'FunctionLoadingError';
148      throw err;
149    }
150
151    // Verify a new function was registered.
152    var numFunctionsNow = FunctionRegistry.allFunctions.length;
153    if (numFunctionsNow !== (numFunctionsBefore + 1)) {
154      var err = new Error(filename + " didn't call FunctionRegistry.register");
155      err.name = 'FunctionNotDefinedError';
156      throw err;
157    }
158
159    return FunctionRegistry.allFunctions[numFunctionsNow - 1];
160  };
161
162  FunctionHandle.fromDict = function(handleDict) {
163    var options = handleDict.options;
164    if (handleDict.modules_to_load !== undefined) {
165      var modulesToLoad = handleDict.modules_to_load.map(function(module) {
166        return ModuleToLoad.fromDict(module);
167      });
168    }
169    return new FunctionHandle(modulesToLoad, handleDict.function_name, options);
170  };
171
172  return {
173    FunctionHandle: FunctionHandle,
174    ModuleToLoad: ModuleToLoad,
175    FunctionRegistry: FunctionRegistry
176  };
177});
178</script>
179