blob: f90bae06c057bd68efd68568d81079908a18d0e0 [file] [log] [blame]
// Copyright 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.
/**
* @fileoverview Implentation of ChromeVox's public API.
*
*/
goog.provide('ApiImplementation');
goog.require('ChromeVox');
goog.require('ExtensionBridge');
goog.require('ScriptInstaller');
ApiImplementation = class {
constructor() {}
/**
* Inject the API into the page and set up communication with it.
* @param {function()=} opt_onload A function called when the script is
* loaded.
*/
static init(opt_onload) {
window.addEventListener('message', ApiImplementation.portSetup, true);
const scripts =
[window.chrome.extension.getURL('chromevox/injected/api.js')];
const didInstall =
ScriptInstaller.installScript(scripts, 'cvoxapi', opt_onload);
if (!didInstall) {
console.error('Unable to install api scripts');
}
ExtensionBridge.addDisconnectListener(function() {
ApiImplementation.port.postMessage(ApiImplementation.DISCONNECT_MSG);
ScriptInstaller.uninstallScript('cvoxapi');
});
}
/**
* This method is called when the content script receives a message from
* the page.
* @param {Event} event The DOM event with the message data.
* @return {boolean} True if default event processing should continue.
*/
static portSetup(event) {
if (event.data === 'cvox.PortSetup') {
ApiImplementation.port = event.ports[0];
ApiImplementation.port.onmessage = function(event) {
ApiImplementation.dispatchApiMessage(JSON.parse(event.data));
};
// Stop propagation since it was our message.
event.stopPropagation();
return false;
}
return true;
}
/**
* Call the appropriate API function given a message from the page.
* @param {*} message The message.
*/
static dispatchApiMessage(message) {
let method;
switch (message['cmd']) {
case 'speak':
method = ApiImplementation.speak;
break;
break;
}
if (!method) {
throw 'Unknown API call: ' + message['cmd'];
}
method.apply(ApiImplementation, message['args']);
}
/**
* Speaks the given string using the specified queueMode and properties.
*
* @param {number} callbackId The callback Id.
* @param {string} textString The string of text to be spoken.
* @param {number=} queueMode Valid modes are 0 for flush; 1 for queue.
* @param {Object=} properties Speech properties to use for this utterance.
*/
static speak(callbackId, textString, queueMode, properties) {
if (!properties) {
properties = {};
}
setupEndCallback_(properties, callbackId);
const message = {
'target': 'TTS',
'action': 'speak',
'text': textString,
queueMode,
properties
};
ExtensionBridge.send(message);
}
};
/**
* The message between content script and the page that indicates the
* connection to the background page has been lost.
* @type {string}
* @const
*/
ApiImplementation.DISCONNECT_MSG = 'Disconnect';
/**
* Sets endCallback in properties to call callbackId's function.
* @param {Object} properties Speech properties to use for this utterance.
* @param {number} callbackId The callback Id.
* @private
*/
function setupEndCallback_(properties, callbackId) {
const endCallback = function() {
ApiImplementation.port.postMessage(JSON.stringify({'id': callbackId}));
};
if (properties) {
properties['endCallback'] = endCallback;
}
}