blob: ecb393cb6057237c70e63653c68fa27aeb0b6701 [file] [log] [blame]
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @fileoverview Defines the ScriptInstaller functions which install scripts
* into the web page (not a content script)
*
*/
goog.provide('ScriptInstaller');
/**
* URL pattern where we do not allow script installation.
* @type {RegExp}
*/
ScriptInstaller.denylistPattern = /chrome:\/\/|chrome-extension:\/\//;
/**
* Installs a script in the web page.
* @param {string} src A URL for a script.
* @param {string} uid A unique id. This function won't install the same set of
* scripts twice.
* @return {boolean} False if the script already existed and this function
* didn't do anything.
*/
ScriptInstaller.installScript = function(src, uid) {
if (ScriptInstaller.denylistPattern.test(document.URL)) {
return false;
}
if (document.querySelector('script[' + uid + ']')) {
ScriptInstaller.uninstallScript(uid);
}
if (!src) {
return false;
}
ScriptInstaller.installScriptHelper_(src, uid);
return true;
};
/**
* Uninstalls a script.
* @param {string} uid Id of the script node.
*/
ScriptInstaller.uninstallScript = function(uid) {
let scriptNode;
if (scriptNode = document.querySelector('script[' + uid + ']')) {
scriptNode.remove();
}
};
/**
* Helper that installs one script and calls itself recursively when each
* script loads.
* @param {string} src A URL for a script.
* @param {string} uid A unique id. This function won't install the same set of
* scripts twice.
* @private
*/
ScriptInstaller.installScriptHelper_ = function(src, uid) {
if (!src) {
return;
}
const xhr = new XMLHttpRequest();
const url = src + '?' + new Date().getTime();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
const scriptText = xhr.responseText;
const apiScript = document.createElement('script');
apiScript.type = 'text/javascript';
apiScript.setAttribute(uid, '1');
apiScript.textContent = scriptText;
const scriptOwner = document.head || document.body;
scriptOwner.appendChild(apiScript);
}
};
try {
xhr.open('GET', url, true);
xhr.send(null);
} catch (exception) {
console.log(
'Warning: ChromeVox external script loading for ' + document.location +
' stopped after failing to install ' + src);
}
};