OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium 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 // This script contains privileged chrome extension related javascript APIs. | 5 // This script contains privileged chrome extension related javascript APIs. |
6 // It is loaded by pages whose URL has the chrome-extension protocol. | 6 // It is loaded by pages whose URL has the chrome-extension protocol. |
7 | 7 |
8 var chrome = chrome || {}; | 8 var chrome = chrome || {}; |
9 (function() { | 9 (function() { |
10 native function GetExtensionAPIDefinition(); | 10 native function GetExtensionAPIDefinition(); |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 } | 118 } |
119 | 119 |
120 if (request.callbackSchema.parameters.length > 1) { | 120 if (request.callbackSchema.parameters.length > 1) { |
121 throw "Callbacks may only define one parameter"; | 121 throw "Callbacks may only define one parameter"; |
122 } | 122 } |
123 | 123 |
124 chromeHidden.validate(callbackArgs, | 124 chromeHidden.validate(callbackArgs, |
125 request.callbackSchema.parameters); | 125 request.callbackSchema.parameters); |
126 } catch (exception) { | 126 } catch (exception) { |
127 return "Callback validation error during " + name + " -- " + | 127 return "Callback validation error during " + name + " -- " + |
128 exception; | 128 exception.stack; |
129 } | 129 } |
130 } | 130 } |
131 | 131 |
132 if (response) { | 132 if (response) { |
133 request.callback(callbackArgs[0]); | 133 request.callback(callbackArgs[0]); |
134 } else { | 134 } else { |
135 request.callback(); | 135 request.callback(); |
136 } | 136 } |
137 } | 137 } |
138 } finally { | 138 } finally { |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
340 | 340 |
341 function extendSchema(schema) { | 341 function extendSchema(schema) { |
342 var extendedSchema = schema.slice(); | 342 var extendedSchema = schema.slice(); |
343 extendedSchema.unshift({'type': 'string'}); | 343 extendedSchema.unshift({'type': 'string'}); |
344 return extendedSchema; | 344 return extendedSchema; |
345 } | 345 } |
346 | 346 |
347 var customBindings = {}; | 347 var customBindings = {}; |
348 | 348 |
349 function setupChromeSetting() { | 349 function setupChromeSetting() { |
350 customBindings['ChromeSetting'] = function(prefKey, valueSchema) { | 350 function ChromeSetting(prefKey, valueSchema) { |
351 this.get = function(details, callback) { | 351 this.get = function(details, callback) { |
352 var getSchema = this.parameters.get; | 352 var getSchema = this.parameters.get; |
353 chromeHidden.validate([details, callback], getSchema); | 353 chromeHidden.validate([details, callback], getSchema); |
354 return sendRequest('types.ChromeSetting.get', | 354 return sendRequest('types.ChromeSetting.get', |
355 [prefKey, details, callback], | 355 [prefKey, details, callback], |
356 extendSchema(getSchema)); | 356 extendSchema(getSchema)); |
357 }; | 357 }; |
358 this.set = function(details, callback) { | 358 this.set = function(details, callback) { |
359 var setSchema = this.parameters.set.slice(); | 359 var setSchema = this.parameters.set.slice(); |
360 setSchema[0].properties.value = valueSchema; | 360 setSchema[0].properties.value = valueSchema; |
361 chromeHidden.validate([details, callback], setSchema); | 361 chromeHidden.validate([details, callback], setSchema); |
362 return sendRequest('types.ChromeSetting.set', | 362 return sendRequest('types.ChromeSetting.set', |
363 [prefKey, details, callback], | 363 [prefKey, details, callback], |
364 extendSchema(setSchema)); | 364 extendSchema(setSchema)); |
365 }; | 365 }; |
366 this.clear = function(details, callback) { | 366 this.clear = function(details, callback) { |
367 var clearSchema = this.parameters.clear; | 367 var clearSchema = this.parameters.clear; |
368 chromeHidden.validate([details, callback], clearSchema); | 368 chromeHidden.validate([details, callback], clearSchema); |
369 return sendRequest('types.ChromeSetting.clear', | 369 return sendRequest('types.ChromeSetting.clear', |
370 [prefKey, details, callback], | 370 [prefKey, details, callback], |
371 extendSchema(clearSchema)); | 371 extendSchema(clearSchema)); |
372 }; | 372 }; |
373 this.onChange = new chrome.Event('types.ChromeSetting.' + prefKey + | 373 this.onChange = new chrome.Event('types.ChromeSetting.' + prefKey + |
374 '.onChange'); | 374 '.onChange'); |
375 }; | 375 }; |
376 customBindings['ChromeSetting'].prototype = new CustomBindingsObject(); | 376 ChromeSetting.prototype = new CustomBindingsObject(); |
| 377 customBindings['ChromeSetting'] = ChromeSetting; |
| 378 } |
| 379 |
| 380 function setupContentSetting() { |
| 381 function ContentSetting(content_type, settingSchema) { |
| 382 this.get = function(details, callback) { |
| 383 var getSchema = this.parameters.get; |
| 384 chromeHidden.validate([details, callback], getSchema); |
| 385 return sendRequest('experimental.contentSettings.get', |
| 386 [content_type, details, callback], |
| 387 extendSchema(getSchema)); |
| 388 }; |
| 389 this.set = function(details, callback) { |
| 390 var setSchema = this.parameters.set.slice(); |
| 391 setSchema[0].properties.setting = settingSchema; |
| 392 chromeHidden.validate([details, callback], setSchema); |
| 393 return sendRequest('experimental.contentSettings.set', |
| 394 [content_type, details, callback], |
| 395 extendSchema(setSchema)); |
| 396 }; |
| 397 this.clear = function(details, callback) { |
| 398 var clearSchema = this.parameters.clear; |
| 399 chromeHidden.validate([details, callback], clearSchema); |
| 400 return sendRequest('experimental.contentSettings.clear', |
| 401 [content_type, details, callback], |
| 402 extendSchema(clearSchema)); |
| 403 }; |
| 404 } |
| 405 ContentSetting.prototype = new CustomBindingsObject(); |
| 406 customBindings['ContentSetting'] = ContentSetting; |
377 } | 407 } |
378 | 408 |
379 // Page action events send (pageActionId, {tabId, tabUrl}). | 409 // Page action events send (pageActionId, {tabId, tabUrl}). |
380 function setupPageActionEvents(extensionId) { | 410 function setupPageActionEvents(extensionId) { |
381 var pageActions = GetCurrentPageActions(extensionId); | 411 var pageActions = GetCurrentPageActions(extensionId); |
382 | 412 |
383 var oldStyleEventName = "pageActions"; | 413 var oldStyleEventName = "pageActions"; |
384 // TODO(EXTENSIONS_DEPRECATED): only one page action | 414 // TODO(EXTENSIONS_DEPRECATED): only one page action |
385 for (var i = 0; i < pageActions.length; ++i) { | 415 for (var i = 0; i < pageActions.length; ++i) { |
386 // Setup events for each extension_id/page_action_id string we find. | 416 // Setup events for each extension_id/page_action_id string we find. |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 chromeHidden.onLoad.addListener(function (extensionId) { | 532 chromeHidden.onLoad.addListener(function (extensionId) { |
503 if (!extensionId) { | 533 if (!extensionId) { |
504 return; | 534 return; |
505 } | 535 } |
506 chrome.initExtension(extensionId, false, IsIncognitoProcess()); | 536 chrome.initExtension(extensionId, false, IsIncognitoProcess()); |
507 | 537 |
508 // Setup the ChromeSetting class so we can use it to construct | 538 // Setup the ChromeSetting class so we can use it to construct |
509 // ChromeSetting objects from the API definition. | 539 // ChromeSetting objects from the API definition. |
510 setupChromeSetting(); | 540 setupChromeSetting(); |
511 | 541 |
| 542 // Setup the ContentSetting class so we can use it to construct |
| 543 // ContentSetting objects from the API definition. |
| 544 setupContentSetting(); |
| 545 |
512 // |apiFunctions| is a hash of name -> object that stores the | 546 // |apiFunctions| is a hash of name -> object that stores the |
513 // name & definition of the apiFunction. Custom handling of api functions | 547 // name & definition of the apiFunction. Custom handling of api functions |
514 // is implemented by adding a "handleRequest" function to the object. | 548 // is implemented by adding a "handleRequest" function to the object. |
515 var apiFunctions = {}; | 549 var apiFunctions = {}; |
516 | 550 |
517 // Read api definitions and setup api functions in the chrome namespace. | 551 // Read api definitions and setup api functions in the chrome namespace. |
518 // TODO(rafaelw): Consider defining a json schema for an api definition | 552 // TODO(rafaelw): Consider defining a json schema for an api definition |
519 // and validating either here, in a unit_test or both. | 553 // and validating either here, in a unit_test or both. |
520 // TODO(rafaelw): Handle synchronous functions. | 554 // TODO(rafaelw): Handle synchronous functions. |
521 // TOOD(rafaelw): Consider providing some convenient override points | 555 // TOOD(rafaelw): Consider providing some convenient override points |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 // WebRequest events have a special structure. | 628 // WebRequest events have a special structure. |
595 module[eventDef.name] = new chrome.WebRequestEvent(eventName, | 629 module[eventDef.name] = new chrome.WebRequestEvent(eventName, |
596 eventDef.parameters, eventDef.extraParameters); | 630 eventDef.parameters, eventDef.extraParameters); |
597 } else { | 631 } else { |
598 module[eventDef.name] = new chrome.Event(eventName, | 632 module[eventDef.name] = new chrome.Event(eventName, |
599 eventDef.parameters); | 633 eventDef.parameters); |
600 } | 634 } |
601 }); | 635 }); |
602 } | 636 } |
603 | 637 |
| 638 function addProperties(m, def) { |
| 639 // Parse any values defined for properties. |
| 640 if (def.properties) { |
| 641 forEach(def.properties, function(prop, property) { |
| 642 var value = property.value; |
| 643 if (value) { |
| 644 if (property.type === 'integer') { |
| 645 value = parseInt(value); |
| 646 } else if (property.type === 'boolean') { |
| 647 value = value === "true"; |
| 648 } else if (property["$ref"]) { |
| 649 var constructor = customBindings[property["$ref"]]; |
| 650 var args = value; |
| 651 // For an object property, |value| is an array of constructor |
| 652 // arguments, but we want to pass the arguments directly |
| 653 // (i.e. not as an array), so we have to fake calling |new| on |
| 654 // the constructor. |
| 655 value = { __proto__: constructor.prototype }; |
| 656 constructor.apply(value, args); |
| 657 } else if (property.type === 'object') { |
| 658 // Recursively add properties. |
| 659 addProperties(value, property); |
| 660 } else if (property.type !== 'string') { |
| 661 throw "NOT IMPLEMENTED (extension_api.json error): Cannot " + |
| 662 "parse values for type \"" + property.type + "\""; |
| 663 } |
| 664 } |
| 665 if (value) { |
| 666 m[prop] = value; |
| 667 } |
| 668 }); |
| 669 } |
| 670 } |
604 | 671 |
605 // Parse any values defined for properties. | 672 addProperties(module, apiDef); |
606 if (apiDef.properties) { | |
607 forEach(apiDef.properties, function(prop, property) { | |
608 if (property.value) { | |
609 var value = property.value; | |
610 if (property.type === 'integer') { | |
611 value = parseInt(value); | |
612 } else if (property.type === 'boolean') { | |
613 value = value === "true"; | |
614 } else if (property["$ref"]) { | |
615 var constructor = customBindings[property["$ref"]]; | |
616 var args = value; | |
617 // For an object property, |value| is an array of constructor | |
618 // arguments, but we want to pass the arguments directly | |
619 // (i.e. not as an array), so we have to fake calling |new| on the | |
620 // constructor. | |
621 value = { __proto__: constructor.prototype }; | |
622 constructor.apply(value, args); | |
623 } else if (property.type !== 'string') { | |
624 throw "NOT IMPLEMENTED (extension_api.json error): Cannot " + | |
625 "parse values for type \"" + property.type + "\""; | |
626 } | |
627 module[prop] = value; | |
628 } | |
629 }); | |
630 } | |
631 | 673 |
632 // getTabContentses is retained for backwards compatibility | 674 // getTabContentses is retained for backwards compatibility |
633 // See http://crbug.com/21433 | 675 // See http://crbug.com/21433 |
634 chrome.extension.getTabContentses = chrome.extension.getExtensionTabs; | 676 chrome.extension.getTabContentses = chrome.extension.getExtensionTabs; |
635 }); | 677 }); |
636 | 678 |
637 apiFunctions["tabs.connect"].handleRequest = function(tabId, connectInfo) { | 679 apiFunctions["tabs.connect"].handleRequest = function(tabId, connectInfo) { |
638 var name = ""; | 680 var name = ""; |
639 if (connectInfo) { | 681 if (connectInfo) { |
640 name = connectInfo.name || name; | 682 name = connectInfo.name || name; |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
907 | 949 |
908 if (!chrome.experimental) | 950 if (!chrome.experimental) |
909 chrome.experimental = {}; | 951 chrome.experimental = {}; |
910 | 952 |
911 if (!chrome.experimental.accessibility) | 953 if (!chrome.experimental.accessibility) |
912 chrome.experimental.accessibility = {}; | 954 chrome.experimental.accessibility = {}; |
913 | 955 |
914 if (!chrome.experimental.tts) | 956 if (!chrome.experimental.tts) |
915 chrome.experimental.tts = {}; | 957 chrome.experimental.tts = {}; |
916 })(); | 958 })(); |
OLD | NEW |