summaryrefslogtreecommitdiffstats
path: root/chrome/renderer/resources/renderer_extension_bindings.js
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/renderer/resources/renderer_extension_bindings.js')
-rw-r--r--chrome/renderer/resources/renderer_extension_bindings.js93
1 files changed, 93 insertions, 0 deletions
diff --git a/chrome/renderer/resources/renderer_extension_bindings.js b/chrome/renderer/resources/renderer_extension_bindings.js
new file mode 100644
index 0000000..401f82c
--- /dev/null
+++ b/chrome/renderer/resources/renderer_extension_bindings.js
@@ -0,0 +1,93 @@
+var chromium = chromium || {};
+(function () {
+ native function OpenChannelToExtension(id);
+ native function PostMessage(portId, msg);
+ native function RegisterScriptAPI(private);
+ // chromium: Public API.
+
+ // Represents info we know about a chrome extension.
+ chromium.Extension = function(id) {
+ this.id_ = id;
+ };
+
+ // Opens a channel to the extension for message passing.
+ chromium.Extension.prototype.openChannel = function() {
+ portId = OpenChannelToExtension(this.id_);
+ if (portId == -1)
+ throw new Error('No such extension \"' + this.id_ + '\"');
+ return new Port(portId);
+ };
+
+ // Adds a listener that fires when a renderer opens a channel to talk
+ // to us.
+ chromium.addConnectListener = function(callback) {
+ chromium.addEventListener('channel-connect',
+ function (e) { callback(e.data.port); });
+ };
+
+ // Adds a generic event listener.
+ chromium.addEventListener = function(type, callback) {
+ var listeners = getPrivateData().eventListeners;
+ if (!listeners[type])
+ listeners[type] = [];
+ listeners[type].push(callback);
+ };
+
+ // Dispatches the given event to anyone listening for that event.
+ chromium.dispatchEvent = function(type, data) {
+ var event = {type: type, data: data};
+ var listeners = getPrivateData().eventListeners;
+ for (var i in listeners[type]) {
+ listeners[type][i](event);
+ }
+ };
+
+ // Private API.
+
+ // Always access privateData through this function, to ensure that we
+ // have registered our native API. We do this lazily to avoid registering
+ // on pages that don't use these bindings.
+ function getPrivateData() {
+ if (!scriptAPI.registered_) {
+ RegisterScriptAPI(scriptAPI);
+ scriptAPI.registered_ = true;
+ }
+ return privateData;
+ }
+ var privateData = {
+ eventListeners: {},
+ ports: {}
+ };
+
+ // Represents a port through which we can send messages to another process.
+ var Port = function(portId) {
+ // TODO(mpcomplete): we probably want to hide this portId_ so
+ // it can't be guessed at. One idea is to expose v8's SetHiddenValue
+ // to our extension.
+ this.portId_ = portId;
+ getPrivateData().ports[portId] = this;
+ };
+
+ // Sends a message to the other side of the channel.
+ Port.prototype.postMessage = function(msg) {
+ PostMessage(this.portId_, msg);
+ };
+
+ // Script API: javascript APIs exposed to C++ only.
+ // This object allows our native code to call back to us through a
+ // private interface that isn't exposed to web content.
+ var scriptAPI = {};
+
+ // Called by native code when a channel has been opened to this process.
+ scriptAPI.dispatchOnConnect = function(portId) {
+ chromium.dispatchEvent('channel-connect', {port: new Port(portId)});
+ };
+
+ // Called by native code when a message has been sent over the given
+ // channel.
+ scriptAPI.dispatchOnMessage = function(msg, portId) {
+ var port = getPrivateData().ports[portId];
+ if (port && port.onMessage)
+ port.onMessage(msg, port);
+ };
+})();