Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(481)

Unified Diff: chrome/browser/resources/access_chromevox/common/extension_bridge.js

Issue 6254007: Adding ChromeVox as a component extensions (enabled only for ChromeOS, for no... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/access_chromevox/common/extension_bridge.js
===================================================================
--- chrome/browser/resources/access_chromevox/common/extension_bridge.js (revision 0)
+++ chrome/browser/resources/access_chromevox/common/extension_bridge.js (revision 0)
@@ -0,0 +1,273 @@
+// Copyright (c) 2011 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 Bridge to aid in communication between a Chrome
+ * background page and scripts injected into a page by a content script.
+ *
+ * This is needed when the extension's content script dynamically loads
+ * most of its code by injecting script tags into the page. To communicate
+ * with the background page, the page script needs to post a message that
+ * the content script can listen to and then forward to the background page.
+ *
+ * To use cvox.ExtensionBridge, this file must be included in all three
+ * contexts:
+ *
+ * 1. From the background page.
+ * 2. From the content script (in the manifest.json after all other scripts).
+ * 3. Inject it into the page from the content script.
+ *
+ * It automatically figures out where it's being run and initializes itself
+ * appropriately. Then just call send() to send a message from the background
+ * to the page or vice versa, and addMessageListener() to provide a message
+ * listener. Messages can be any object that can be serialized using JSON.
+ *
+ * Messages can be sent to the background page from either the page or the
+ * content script, and messages sent from the background page are delivered
+ * to both the content script and the page.
+ */
+
+goog.provide('cvox.ExtensionBridge');
+
+goog.require('cvox.ChromeVoxJSON');
+
+if (BUILD_TYPE == BUILD_TYPE_CHROME) {
+ /**
+ * @constructor
+ */
+ cvox.ExtensionBridge = function() {};
+
+ /**
+ * Initialize the extension bridge. Dynamically figure out whether we're in
+ * the background page, content script, or in a page, and call the
+ * corresponding function for more specific initialization.
+ */
+ cvox.ExtensionBridge.init = function() {
+ var self = cvox.ExtensionBridge;
+ self.listeners = [];
+
+ try {
+ if (chrome && chrome.windows) {
+ // This depends on the fact that chrome.windows is only available
+ // from background pages.
+ self.json = JSON;
+ self.context = self.BACKGROUND;
+ self.initBackground();
+ return;
+ } else {
+ self.json = cvox.ChromeVoxJSON;
+ self.context = self.PAGE;
+ self.initPage();
+ return;
+ }
+ } catch (e) {
+ // Ignore exception that might be raised if we try to access
+ // chrome.windows from a content script.
+ }
+
+ if (chrome && chrome.extension) {
+ self.json = JSON;
+ self.context = self.CONTENT_SCRIPT;
+ self.initContentScript();
+ }
+ };
+
+ /**
+ * Constant indicating we're in a background page.
+ * @type {number}
+ * @const
+ */
+ cvox.ExtensionBridge.BACKGROUND = 0;
+
+ /**
+ * Constant indicating we're in a content script.
+ * @type {number}
+ * @const
+ */
+ cvox.ExtensionBridge.CONTENT_SCRIPT = 1;
+
+ /**
+ * Constant indicating we're in a page.
+ * @type {number}
+ * @const
+ */
+ cvox.ExtensionBridge.PAGE = 2;
+
+ /**
+ * The name of the port between the content script and background page.
+ * @type {string}
+ * @const
+ */
+ cvox.ExtensionBridge.PORT_NAME = 'cvox.ExtensionBridge.Port';
+
+ /**
+ * The name of the message between the page and content script that sets
+ * up the bidirectional port between them.
+ * @type {string}
+ * @const
+ */
+ cvox.ExtensionBridge.PORT_SETUP_MSG = 'cvox.ExtensionBridge.PortSetup';
+
+ /**
+ * Send a message. If the context is a page, sends a message to the
+ * extension background page. If the context is a background page, sends
+ * a message to the current active tab (not all tabs).
+ *
+ * @param {Object} message The message to be sent.
+ */
+ cvox.ExtensionBridge.send = function(message) {
+ var self = cvox.ExtensionBridge;
+ switch (self.context) {
+ case self.BACKGROUND:
+ self.sendBackgroundToContentScript(message);
+ break;
+ case self.CONTENT_SCRIPT:
+ self.sendContentScriptToBackground(message);
+ break;
+ case self.PAGE:
+ self.sendPageToContentScript(message);
+ break;
+ }
+ };
+
+ /**
+ * Provide a function to listen to messages. In page context, this
+ * listens to messages from the background. In background context,
+ * this listens to messages from all pages.
+ *
+ * The function gets called with two parameters: the message, and a
+ * port that can be used to send replies.
+ *
+ * @param {function(Object, Port)} listener The message listener.
+ */
+ cvox.ExtensionBridge.addMessageListener = function(listener) {
+ cvox.ExtensionBridge.listeners.push(listener);
+ };
+
+ /**
+ * Initialize the extension bridge in a background page context by registering
+ * a listener for connections from the content script.
+ */
+ cvox.ExtensionBridge.initBackground = function() {
+ var self = cvox.ExtensionBridge;
+
+ chrome.extension.onConnect.addListener(function(port) {
+ if (port.name != self.PORT_NAME) {
+ return;
+ }
+ port.onMessage.addListener(function(message) {
+ for (var i = 0; i < self.listeners.length; i++) {
+ self.listeners[i](message, port);
+ }
+ });
+ });
+ };
+
+ /**
+ * Initialize the extension bridge in a content script context, listening
+ * for messages from the background page and accepting a bidirectional port
+ * from the page.
+ */
+ cvox.ExtensionBridge.initContentScript = function() {
+ var self = cvox.ExtensionBridge;
+
+ // Listen to requests from the background that don't come from
+ // our connection port.
+ chrome.extension.onRequest.addListener(
+ function(request, sender, sendResponse) {
+ for (var i = 0; i < self.listeners.length; i++) {
+ self.listeners[i](request, self.backgroundPort);
+ }
+ if (self.port) {
+ self.port.postMessage(self.json.stringify(request));
+ }
+ sendResponse({});
+ });
+
+ // Listen to events on the main window and wait for a port setup message
+ // from the page to continue.
+ window.addEventListener('message', function(event) {
+ if (event.data == self.PORT_SETUP_MSG) {
+ // Now that we have a page connection, connect to background too.
+ // (Don't do this earlier, otherwise initial messages from the
+ // background wouldn't make it all the way through to the page.)
+ self.backgroundPort = chrome.extension.connect({name: self.PORT_NAME});
+ self.backgroundPort.onMessage.addListener(
+ function(message) {
+ for (var i = 0; i < self.listeners.length; i++) {
+ self.listeners[i](message, self.backgroundPort);
+ }
+ if (self.port) {
+ self.port.postMessage(self.json.stringify(message));
+ }
+ });
+
+ self.port = event.ports[0];
+ self.port.onmessage = function(event) {
+ self.backgroundPort.postMessage(self.json.parse(event.data));
+ };
+ }
+ }, false);
+ };
+
+ /**
+ * Initialize the extension bridge in a page context, creating a
+ * MessageChannel and sending one of the ports to the content script
+ * and then listening for messages on the other port.
+ */
+ cvox.ExtensionBridge.initPage = function() {
+ var self = cvox.ExtensionBridge;
+ self.channel = new MessageChannel();
+
+ // Note: using postMessage.apply rather than just calling postMessage
+ // directly because the 3-argument form of postMessage is still in the
+ // HTML5 draft.
+ window.postMessage.apply(
+ window, [self.PORT_SETUP_MSG, [self.channel.port2], '*']);
+
+ self.channel.port1.onmessage = function(event) {
+ for (var i = 0; i < self.listeners.length; i++) {
+ self.listeners[i](self.json.parse(event.data), self.channel.port1);
+ }
+ };
+ };
+
+ /**
+ * Send a message from the content script to the background page.
+ *
+ * @param {Object} message The message to send.
+ */
+ cvox.ExtensionBridge.sendContentScriptToBackground = function(message) {
+ cvox.ExtensionBridge.backgroundPort.postMessage(message);
+ };
+
+ /**
+ * Send a message from the background page to the content script of the
+ * current selected tab.
+ *
+ * @param {Object} message The message to send.
+ */
+ cvox.ExtensionBridge.sendBackgroundToContentScript = function(message) {
+ chrome.tabs.getSelected(null, function(tab) {
+ chrome.tabs.sendRequest(tab.id, message, function() {});
+ });
+ };
+
+ /**
+ * Send a message from the current page to its content script.
+ *
+ * @param {Object} message The message to send.
+ */
+ cvox.ExtensionBridge.sendPageToContentScript = function(message) {
+ cvox.ExtensionBridge.channel.port1.postMessage(
+ cvox.ExtensionBridge.json.stringify(message));
+ };
+
+ cvox.ExtensionBridge.init();
+} else {
+ if (goog == undefined) {
+ cvox = {};
+ }
+ cvox.ExtensionBridge = function() {};
+}
Property changes on: chrome/browser/resources/access_chromevox/common/extension_bridge.js
___________________________________________________________________
Added: svn:executable
+ *
Added: svn:eol-style
+ LF

Powered by Google App Engine
This is Rietveld 408576698