| OLD | NEW |
| 1 // Copyright (c) 2009 The chrome Authors. All rights reserved. | 1 // Copyright (c) 2009 The chrome Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // ----------------------------------------------------------------------------- | 5 // ----------------------------------------------------------------------------- |
| 6 // NOTE: If you change this file you need to touch renderer_resources.grd to | 6 // NOTE: If you change this file you need to touch renderer_resources.grd to |
| 7 // have your change take effect. | 7 // have your change take effect. |
| 8 // ----------------------------------------------------------------------------- | 8 // ----------------------------------------------------------------------------- |
| 9 | 9 |
| 10 // This script contains privileged chrome extension related javascript APIs. | 10 // This script contains privileged chrome extension related javascript APIs. |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 delete chrome.extension.lastError; | 68 delete chrome.extension.lastError; |
| 69 } else { | 69 } else { |
| 70 if (!error) { | 70 if (!error) { |
| 71 error = "Unknown error." | 71 error = "Unknown error." |
| 72 } | 72 } |
| 73 console.error("Error during " + name + ": " + error); | 73 console.error("Error during " + name + ": " + error); |
| 74 chrome.extension.lastError = { | 74 chrome.extension.lastError = { |
| 75 "message": error | 75 "message": error |
| 76 }; | 76 }; |
| 77 } | 77 } |
| 78 | 78 |
| 79 if (request.callback) { | 79 if (request.callback) { |
| 80 // Callbacks currently only support one callback argument. | 80 // Callbacks currently only support one callback argument. |
| 81 var callbackArgs = response ? [JSON.parse(response)] : []; | 81 var callbackArgs = response ? [JSON.parse(response)] : []; |
| 82 | 82 |
| 83 // Validate callback in debug only -- and only when the | 83 // Validate callback in debug only -- and only when the |
| 84 // caller has provided a callback. Implementations of api | 84 // caller has provided a callback. Implementations of api |
| 85 // calls my not return data if they observe the caller | 85 // calls my not return data if they observe the caller |
| 86 // has not provided a callback. | 86 // has not provided a callback. |
| 87 if (chromeHidden.validateCallbacks && !error) { | 87 if (chromeHidden.validateCallbacks && !error) { |
| 88 try { | 88 try { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 110 } | 110 } |
| 111 } finally { | 111 } finally { |
| 112 delete requests[requestId]; | 112 delete requests[requestId]; |
| 113 delete chrome.extension.lastError; | 113 delete chrome.extension.lastError; |
| 114 } | 114 } |
| 115 }; | 115 }; |
| 116 | 116 |
| 117 function prepareRequest(args, argSchemas) { | 117 function prepareRequest(args, argSchemas) { |
| 118 var request = {}; | 118 var request = {}; |
| 119 var argCount = args.length; | 119 var argCount = args.length; |
| 120 | 120 |
| 121 // Look for callback param. | 121 // Look for callback param. |
| 122 if (argSchemas.length > 0 && | 122 if (argSchemas.length > 0 && |
| 123 args.length == argSchemas.length && | 123 args.length == argSchemas.length && |
| 124 argSchemas[argSchemas.length - 1].type == "function") { | 124 argSchemas[argSchemas.length - 1].type == "function") { |
| 125 request.callback = args[argSchemas.length - 1]; | 125 request.callback = args[argSchemas.length - 1]; |
| 126 request.callbackSchema = argSchemas[argSchemas.length - 1]; | 126 request.callbackSchema = argSchemas[argSchemas.length - 1]; |
| 127 --argCount; | 127 --argCount; |
| 128 } | 128 } |
| 129 | 129 |
| 130 // Calls with one argument expect singular argument. Calls with multiple | 130 // Calls with one argument expect singular argument. Calls with multiple |
| 131 // expect a list. | 131 // expect a list. |
| 132 if (argCount == 1) { | 132 if (argCount == 1) { |
| 133 request.args = args[0]; | 133 request.args = args[0]; |
| 134 } | 134 } |
| 135 if (argCount > 1) { | 135 if (argCount > 1) { |
| 136 request.args = []; | 136 request.args = []; |
| 137 for (var k = 0; k < argCount; k++) { | 137 for (var k = 0; k < argCount; k++) { |
| 138 request.args[k] = args[k]; | 138 request.args[k] = args[k]; |
| 139 } | 139 } |
| 140 } | 140 } |
| 141 | 141 |
| 142 return request; | 142 return request; |
| 143 } | 143 } |
| 144 | 144 |
| 145 // Send an API request and optionally register a callback. | 145 // Send an API request and optionally register a callback. |
| 146 function sendRequest(functionName, args, argSchemas) { | 146 function sendRequest(functionName, args, argSchemas) { |
| 147 var request = prepareRequest(args, argSchemas); | 147 var request = prepareRequest(args, argSchemas); |
| 148 // JSON.stringify doesn't support a root object which is undefined. | 148 // JSON.stringify doesn't support a root object which is undefined. |
| 149 if (request.args === undefined) | 149 if (request.args === undefined) |
| 150 request.args = null; | 150 request.args = null; |
| 151 var sargs = JSON.stringify(request.args); | 151 var sargs = JSON.stringify(request.args); |
| 152 var requestId = GetNextRequestId(); | 152 var requestId = GetNextRequestId(); |
| 153 requests[requestId] = request; | 153 requests[requestId] = request; |
| 154 return StartRequest(functionName, sargs, requestId, | 154 return StartRequest(functionName, sargs, requestId, |
| 155 request.callback ? true : false); | 155 request.callback ? true : false); |
| 156 } | 156 } |
| 157 | 157 |
| 158 // Using forEach for convenience, and to bind |module|s & |apiDefs|s via | 158 // Using forEach for convenience, and to bind |module|s & |apiDefs|s via |
| 159 // closures. | 159 // closures. |
| 160 function forEach(a, f) { | 160 function forEach(a, f) { |
| 161 for (var i = 0; i < a.length; i++) { | 161 for (var i = 0; i < a.length; i++) { |
| 162 f(a[i], i); | 162 f(a[i], i); |
| 163 } | 163 } |
| 164 } | 164 } |
| 165 | 165 |
| 166 function bind(obj, func) { | 166 function bind(obj, func) { |
| 167 return function() { | 167 return function() { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 182 } | 182 } |
| 183 } | 183 } |
| 184 | 184 |
| 185 chromeHidden.onLoad.addListener(function (extensionId) { | 185 chromeHidden.onLoad.addListener(function (extensionId) { |
| 186 chrome.extension = new chrome.Extension(extensionId); | 186 chrome.extension = new chrome.Extension(extensionId); |
| 187 | 187 |
| 188 // TODO(mpcomplete): chrome.self is deprecated. Remove it at 1.0. | 188 // TODO(mpcomplete): chrome.self is deprecated. Remove it at 1.0. |
| 189 // http://code.google.com/p/chromium/issues/detail?id=16356 | 189 // http://code.google.com/p/chromium/issues/detail?id=16356 |
| 190 chrome.self = chrome.extension; | 190 chrome.self = chrome.extension; |
| 191 | 191 |
| 192 // |apiFunctions| is a hash of name -> object that stores the | 192 // |apiFunctions| is a hash of name -> object that stores the |
| 193 // name & definition of the apiFunction. Custom handling of api functions | 193 // name & definition of the apiFunction. Custom handling of api functions |
| 194 // is implemented by adding a "handleRequest" function to the object. | 194 // is implemented by adding a "handleRequest" function to the object. |
| 195 var apiFunctions = {}; | 195 var apiFunctions = {}; |
| 196 | 196 |
| 197 // Read api definitions and setup api functions in the chrome namespace. | 197 // Read api definitions and setup api functions in the chrome namespace. |
| 198 // TODO(rafaelw): Consider defining a json schema for an api definition | 198 // TODO(rafaelw): Consider defining a json schema for an api definition |
| 199 // and validating either here, in a unit_test or both. | 199 // and validating either here, in a unit_test or both. |
| 200 // TODO(rafaelw): Handle synchronous functions. | 200 // TODO(rafaelw): Handle synchronous functions. |
| 201 // TOOD(rafaelw): Consider providing some convenient override points | 201 // TOOD(rafaelw): Consider providing some convenient override points |
| 202 // for api functions that wish to insert themselves into the call. | 202 // for api functions that wish to insert themselves into the call. |
| 203 var apiDefinitions = JSON.parse(GetExtensionAPIDefinition()); | 203 var apiDefinitions = JSON.parse(GetExtensionAPIDefinition()); |
| 204 | 204 |
| 205 forEach(apiDefinitions, function(apiDef) { | 205 forEach(apiDefinitions, function(apiDef) { |
| 206 chrome[apiDef.namespace] = chrome[apiDef.namespace] || {}; | 206 chrome[apiDef.namespace] = chrome[apiDef.namespace] || {}; |
| 207 var module = chrome[apiDef.namespace]; | 207 var module = chrome[apiDef.namespace]; |
| 208 | 208 |
| 209 // Add types to global validationTypes | 209 // Add types to global validationTypes |
| 210 if (apiDef.types) { | 210 if (apiDef.types) { |
| 211 forEach(apiDef.types, function(t) { | 211 forEach(apiDef.types, function(t) { |
| 212 chromeHidden.validationTypes.push(t); | 212 chromeHidden.validationTypes.push(t); |
| 213 }); | 213 }); |
| 214 } | 214 } |
| 215 | 215 |
| 216 // Setup Functions. | 216 // Setup Functions. |
| 217 if (apiDef.functions) { | 217 if (apiDef.functions) { |
| 218 forEach(apiDef.functions, function(functionDef) { | 218 forEach(apiDef.functions, function(functionDef) { |
| 219 // Module functions may have been defined earlier by hand. Don't | 219 // Module functions may have been defined earlier by hand. Don't |
| 220 // clobber them. | 220 // clobber them. |
| 221 if (module[functionDef.name]) | 221 if (module[functionDef.name]) |
| 222 return; | 222 return; |
| 223 | 223 |
| 224 var apiFunction = {}; | 224 var apiFunction = {}; |
| 225 apiFunction.definition = functionDef; | 225 apiFunction.definition = functionDef; |
| 226 apiFunction.name = apiDef.namespace + "." + functionDef.name;; | 226 apiFunction.name = apiDef.namespace + "." + functionDef.name;; |
| 227 apiFunctions[apiFunction.name] = apiFunction; | 227 apiFunctions[apiFunction.name] = apiFunction; |
| 228 | 228 |
| 229 module[functionDef.name] = bind(apiFunction, function() { | 229 module[functionDef.name] = bind(apiFunction, function() { |
| 230 chromeHidden.validate(arguments, this.definition.parameters); | 230 chromeHidden.validate(arguments, this.definition.parameters); |
| 231 | 231 |
| 232 if (this.handleRequest) | 232 if (this.handleRequest) |
| 233 return this.handleRequest.apply(this, arguments); | 233 return this.handleRequest.apply(this, arguments); |
| 234 else | 234 else |
| 235 return sendRequest(this.name, arguments, | 235 return sendRequest(this.name, arguments, |
| 236 this.definition.parameters); | 236 this.definition.parameters); |
| 237 }); | 237 }); |
| 238 }); | 238 }); |
| 239 } | 239 } |
| 240 | 240 |
| 241 // Setup Events | 241 // Setup Events |
| 242 if (apiDef.events) { | 242 if (apiDef.events) { |
| 243 forEach(apiDef.events, function(eventDef) { | 243 forEach(apiDef.events, function(eventDef) { |
| 244 // Module events may have been defined earlier by hand. Don't clobber | 244 // Module events may have been defined earlier by hand. Don't clobber |
| 245 // them. | 245 // them. |
| 246 if (module[eventDef.name]) | 246 if (module[eventDef.name]) |
| 247 return; | 247 return; |
| 248 | 248 |
| 249 var eventName = apiDef.namespace + "." + eventDef.name; | 249 var eventName = apiDef.namespace + "." + eventDef.name; |
| 250 module[eventDef.name] = new chrome.Event(eventName, | 250 module[eventDef.name] = new chrome.Event(eventName, |
| 251 eventDef.parameters); | 251 eventDef.parameters); |
| 252 }); | 252 }); |
| 253 } | 253 } |
| 254 }); | 254 }); |
| 255 | 255 |
| 256 apiFunctions["tabs.connect"].handleRequest = function(tabId, opt_name) { | 256 apiFunctions["tabs.connect"].handleRequest = function(tabId, connectInfo) { |
| 257 var name = ""; |
| 258 if (connectInfo) { |
| 259 name = connectInfo.name || name; |
| 260 } |
| 257 var portId = OpenChannelToTab( | 261 var portId = OpenChannelToTab( |
| 258 tabId, chrome.extension.id_, opt_name || ""); | 262 tabId, chrome.extension.id_, name); |
| 259 return chromeHidden.Port.createPort(portId, opt_name); | 263 return chromeHidden.Port.createPort(portId, name); |
| 260 } | 264 } |
| 261 | 265 |
| 262 apiFunctions["extension.getViews"].handleRequest = function() { | 266 apiFunctions["extension.getViews"].handleRequest = function() { |
| 263 return GetExtensionViews(-1, "ALL"); | 267 return GetExtensionViews(-1, "ALL"); |
| 264 } | 268 } |
| 265 | 269 |
| 266 apiFunctions["extension.getBackgroundPage"].handleRequest = function() { | 270 apiFunctions["extension.getBackgroundPage"].handleRequest = function() { |
| 267 return GetExtensionViews(-1, "BACKGROUND")[0] || null; | 271 return GetExtensionViews(-1, "BACKGROUND")[0] || null; |
| 268 } | 272 } |
| 269 | 273 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 289 // chrome/browser/extensions/extension_devtools_events.h for the C++ | 293 // chrome/browser/extensions/extension_devtools_events.h for the C++ |
| 290 // equivalent of this logic. | 294 // equivalent of this logic. |
| 291 tabIdProxy[name] = new chrome.Event("devtools." + tabId + "." + name); | 295 tabIdProxy[name] = new chrome.Event("devtools." + tabId + "." + name); |
| 292 }); | 296 }); |
| 293 return tabIdProxy; | 297 return tabIdProxy; |
| 294 } | 298 } |
| 295 | 299 |
| 296 setupPageActionEvents(extensionId); | 300 setupPageActionEvents(extensionId); |
| 297 }); | 301 }); |
| 298 })(); | 302 })(); |
| OLD | NEW |