script_installer.js revision cedac228d2dd51db4b79ea1e72c7f249408ee061
1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5/**
6 * @fileoverview Defines the ScriptInstaller functions which install scripts
7 * into the web page (not a content script)
8 *
9 */
10
11goog.provide('cvox.ScriptInstaller');
12
13goog.require('cvox.DomUtil');
14
15/**
16 * URL pattern where we do not allow script installation.
17 * @type {RegExp}
18 */
19cvox.ScriptInstaller.blacklistPattern = /chrome:\/\/|chrome-extension:\/\//;
20
21/**
22 * Installs a script in the web page.
23 * @param {Array.<string>} srcs An array of URLs of scripts.
24 * @param {string} uid A unique id.  This function won't install the same set of
25 *      scripts twice.
26 * @param {function()=} opt_onload A function called when the script has loaded.
27 * @param {string=} opt_chromevoxScriptBase An optional chromevoxScriptBase
28 *     attribute to add.
29 * @return {boolean} False if the script already existed and this function
30 * didn't do anything.
31 */
32cvox.ScriptInstaller.installScript = function(srcs, uid, opt_onload,
33    opt_chromevoxScriptBase) {
34  if (cvox.ScriptInstaller.blacklistPattern.test(document.URL)) {
35    return false;
36  }
37  if (document.querySelector('script[' + uid + ']')) {
38    return false;
39  }
40  if (!srcs) {
41    return false;
42  }
43  for (var i = 0, scriptSrc; scriptSrc = srcs[i]; i++) {
44    // Directly write the contents of the script we are trying to inject into
45    // the page.
46    var xhr = new XMLHttpRequest();
47    var url = scriptSrc + '?' + new Date().getTime();
48    xhr.onreadystatechange = function() {
49        if (xhr.readyState == 4) {
50          var scriptText = xhr.responseText;
51          // Add a magic comment to the bottom of the file so that
52          // Chrome knows the name of the script in the JavaScript debugger.
53          scriptText += '\n//# sourceURL=' + scriptSrc + '\n';
54
55          var apiScript = document.createElement('script');
56          apiScript.type = 'text/javascript';
57          apiScript.setAttribute(uid, '1');
58          apiScript.textContent = scriptText;
59          if (opt_chromevoxScriptBase) {
60            apiScript.setAttribute('chromevoxScriptBase',
61                opt_chromevoxScriptBase);
62          }
63          cvox.DomUtil.addNodeToHead(apiScript);
64        }
65      };
66    try {
67      xhr.open('GET', url, false);
68      xhr.send(null);
69    } catch (exception) {
70      window.console.log('Warning: ChromeVox external script loading for ' +
71          document.location + ' stopped after failing to install ' + scriptSrc);
72      return false;
73    }
74  }
75  if (opt_onload) {
76    opt_onload();
77  }
78  return true;
79};
80