Home | History | Annotate | Download | only in injected
      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 
     11 goog.provide('cvox.ScriptInstaller');
     12 
     13 goog.require('cvox.DomUtil');
     14 
     15 /**
     16  * URL pattern where we do not allow script installation.
     17  * @type {RegExp}
     18  */
     19 cvox.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  */
     32 cvox.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