| 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 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 567 for (var i = 0; i < platforms.length; i++) { | 567 for (var i = 0; i < platforms.length; i++) { |
| 568 if (platforms[i][0].test(navigator.appVersion)) { | 568 if (platforms[i][0].test(navigator.appVersion)) { |
| 569 return platforms[i][1]; | 569 return platforms[i][1]; |
| 570 } | 570 } |
| 571 } | 571 } |
| 572 return "unknown"; | 572 return "unknown"; |
| 573 } | 573 } |
| 574 | 574 |
| 575 chromeHidden.onLoad.addListener(function(extensionId, isExtensionProcess, | 575 chromeHidden.onLoad.addListener(function(extensionId, isExtensionProcess, |
| 576 isIncognitoProcess) { | 576 isIncognitoProcess) { |
| 577 if (!isExtensionProcess) | |
| 578 return; | |
| 579 | |
| 580 // Setup the ChromeSetting class so we can use it to construct | 577 // Setup the ChromeSetting class so we can use it to construct |
| 581 // ChromeSetting objects from the API definition. | 578 // ChromeSetting objects from the API definition. |
| 582 setupChromeSetting(); | 579 setupChromeSetting(); |
| 583 | 580 |
| 584 // Setup the ContentSetting class so we can use it to construct | 581 // Setup the ContentSetting class so we can use it to construct |
| 585 // ContentSetting objects from the API definition. | 582 // ContentSetting objects from the API definition. |
| 586 setupContentSetting(); | 583 setupContentSetting(); |
| 587 | 584 |
| 588 // |apiFunctions| is a hash of name -> object that stores the | 585 // |apiFunctions| is a hash of name -> object that stores the |
| 589 // name & definition of the apiFunction. Custom handling of api functions | 586 // name & definition of the apiFunction. Custom handling of api functions |
| 590 // is implemented by adding a "handleRequest" function to the object. | 587 // is implemented by adding a "handleRequest" function to the object. |
| 591 var apiFunctions = {}; | 588 var apiFunctions = {}; |
| 592 | 589 |
| 593 // Read api definitions and setup api functions in the chrome namespace. | 590 // Read api definitions and setup api functions in the chrome namespace. |
| 594 // TODO(rafaelw): Consider defining a json schema for an api definition | 591 // TODO(rafaelw): Consider defining a json schema for an api definition |
| 595 // and validating either here, in a unit_test or both. | 592 // and validating either here, in a unit_test or both. |
| 596 // TODO(rafaelw): Handle synchronous functions. | 593 // TODO(rafaelw): Handle synchronous functions. |
| 597 // TOOD(rafaelw): Consider providing some convenient override points | 594 // TOOD(rafaelw): Consider providing some convenient override points |
| 598 // for api functions that wish to insert themselves into the call. | 595 // for api functions that wish to insert themselves into the call. |
| 599 var apiDefinitions = chromeHidden.JSON.parse(GetExtensionAPIDefinition()); | 596 var apiDefinitions = GetExtensionAPIDefinition(); |
| 600 var platform = getPlatform(); | 597 var platform = getPlatform(); |
| 601 | 598 |
| 602 apiDefinitions.forEach(function(apiDef) { | 599 apiDefinitions.forEach(function(apiDef) { |
| 603 // Check platform, if apiDef has platforms key. | 600 // Check platform, if apiDef has platforms key. |
| 604 if (apiDef.platforms && apiDef.platforms.indexOf(platform) == -1) { | 601 if (apiDef.platforms && apiDef.platforms.indexOf(platform) == -1) { |
| 605 return; | 602 return; |
| 606 } | 603 } |
| 607 | 604 |
| 608 var module = chrome; | 605 var module = chrome; |
| 609 var namespaces = apiDef.namespace.split('.'); | 606 var namespaces = apiDef.namespace.split('.'); |
| 610 for (var index = 0, name; name = namespaces[index]; index++) { | 607 for (var index = 0, name; name = namespaces[index]; index++) { |
| 611 module[name] = module[name] || {}; | 608 module[name] = module[name] || {}; |
| 612 module = module[name]; | 609 module = module[name]; |
| 613 } | 610 } |
| 614 | 611 |
| 615 // Add types to global validationTypes | 612 // Add types to global validationTypes |
| 616 if (apiDef.types) { | 613 if (apiDef.types) { |
| 617 apiDef.types.forEach(function(t) { | 614 apiDef.types.forEach(function(t) { |
| 618 chromeHidden.validationTypes.push(t); | 615 chromeHidden.validationTypes.push(t); |
| 619 if (t.type == 'object' && customBindings[t.id]) { | 616 if (t.type == 'object' && customBindings[t.id]) { |
| 620 customBindings[t.id].prototype.setSchema(t); | 617 customBindings[t.id].prototype.setSchema(t); |
| 621 } | 618 } |
| 622 }); | 619 }); |
| 623 } | 620 } |
| 624 | 621 |
| 622 // Adds a getter that throws an access denied error to object |module| |
| 623 // for property |name| described by |schemaNode| if necessary. |
| 624 // |
| 625 // Returns true if the getter was necessary (access is disallowed), or |
| 626 // false otherwise. |
| 627 function addUnprivilegedAccessGetter(module, name, allowUnprivileged) { |
| 628 if (allowUnprivileged || isExtensionProcess) |
| 629 return false; |
| 630 |
| 631 module.__defineGetter__(name, function() { |
| 632 throw new Error( |
| 633 '"' + name + '" can only be used in extension processes. See ' + |
| 634 'the content scripts documentation for more details.'); |
| 635 }); |
| 636 return true; |
| 637 } |
| 638 |
| 625 // Setup Functions. | 639 // Setup Functions. |
| 626 if (apiDef.functions) { | 640 if (apiDef.functions) { |
| 627 apiDef.functions.forEach(function(functionDef) { | 641 apiDef.functions.forEach(function(functionDef) { |
| 628 // Module functions may have been defined earlier by hand. Don't | 642 if (functionDef.name in module || |
| 629 // clobber them. | 643 addUnprivilegedAccessGetter(module, functionDef.name, |
| 630 if (module[functionDef.name]) | 644 functionDef.unprivileged)) { |
| 631 return; | 645 return; |
| 646 } |
| 632 | 647 |
| 633 var apiFunction = {}; | 648 var apiFunction = {}; |
| 634 apiFunction.definition = functionDef; | 649 apiFunction.definition = functionDef; |
| 635 apiFunction.name = apiDef.namespace + "." + functionDef.name; | 650 apiFunction.name = apiDef.namespace + "." + functionDef.name; |
| 636 apiFunctions[apiFunction.name] = apiFunction; | 651 apiFunctions[apiFunction.name] = apiFunction; |
| 637 | 652 |
| 638 module[functionDef.name] = (function() { | 653 module[functionDef.name] = (function() { |
| 639 var args = arguments; | 654 var args = arguments; |
| 640 if (this.updateArgumentsPreValidate) | 655 if (this.updateArgumentsPreValidate) |
| 641 args = this.updateArgumentsPreValidate.apply(this, args); | 656 args = this.updateArgumentsPreValidate.apply(this, args); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 659 chromeHidden.validate([retval], [this.definition.returns]); | 674 chromeHidden.validate([retval], [this.definition.returns]); |
| 660 } | 675 } |
| 661 return retval; | 676 return retval; |
| 662 }).bind(apiFunction); | 677 }).bind(apiFunction); |
| 663 }); | 678 }); |
| 664 } | 679 } |
| 665 | 680 |
| 666 // Setup Events | 681 // Setup Events |
| 667 if (apiDef.events) { | 682 if (apiDef.events) { |
| 668 apiDef.events.forEach(function(eventDef) { | 683 apiDef.events.forEach(function(eventDef) { |
| 669 // Module events may have been defined earlier by hand. Don't clobber | 684 if (eventDef.name in module || |
| 670 // them. | 685 addUnprivilegedAccessGetter(module, eventDef.name, |
| 671 if (module[eventDef.name]) | 686 eventDef.unprivileged)) { |
| 672 return; | 687 return; |
| 688 } |
| 673 | 689 |
| 674 var eventName = apiDef.namespace + "." + eventDef.name; | 690 var eventName = apiDef.namespace + "." + eventDef.name; |
| 675 if (apiDef.namespace == "experimental.webRequest") { | 691 if (apiDef.namespace == "experimental.webRequest") { |
| 676 module[eventDef.name] = new chrome.WebRequestEvent(eventName, | 692 module[eventDef.name] = new chrome.WebRequestEvent(eventName, |
| 677 eventDef.parameters, eventDef.extraParameters); | 693 eventDef.parameters, eventDef.extraParameters); |
| 678 } else { | 694 } else { |
| 679 module[eventDef.name] = new chrome.Event(eventName, | 695 module[eventDef.name] = new chrome.Event(eventName, |
| 680 eventDef.parameters); | 696 eventDef.parameters); |
| 681 } | 697 } |
| 682 }); | 698 }); |
| 683 } | 699 } |
| 684 | 700 |
| 685 function addProperties(m, def) { | 701 function addProperties(m, def) { |
| 686 // Parse any values defined for properties. | 702 // Parse any values defined for properties. |
| 687 if (def.properties) { | 703 if (def.properties) { |
| 688 forEach(def.properties, function(prop, property) { | 704 forEach(def.properties, function(prop, property) { |
| 705 if (prop in m || |
| 706 addUnprivilegedAccessGetter(m, prop, property.unprivileged)) { |
| 707 return; |
| 708 } |
| 709 |
| 689 var value = property.value; | 710 var value = property.value; |
| 690 if (value) { | 711 if (value) { |
| 691 if (property.type === 'integer') { | 712 if (property.type === 'integer') { |
| 692 value = parseInt(value); | 713 value = parseInt(value); |
| 693 } else if (property.type === 'boolean') { | 714 } else if (property.type === 'boolean') { |
| 694 value = value === "true"; | 715 value = value === "true"; |
| 695 } else if (property["$ref"]) { | 716 } else if (property["$ref"]) { |
| 696 var constructor = customBindings[property["$ref"]]; | 717 var constructor = customBindings[property["$ref"]]; |
| 697 var args = value; | 718 var args = value; |
| 698 // For an object property, |value| is an array of constructor | 719 // For an object property, |value| is an array of constructor |
| (...skipping 13 matching lines...) Expand all Loading... |
| 712 if (value) { | 733 if (value) { |
| 713 m[prop] = value; | 734 m[prop] = value; |
| 714 } | 735 } |
| 715 }); | 736 }); |
| 716 } | 737 } |
| 717 } | 738 } |
| 718 | 739 |
| 719 addProperties(module, apiDef); | 740 addProperties(module, apiDef); |
| 720 }); | 741 }); |
| 721 | 742 |
| 743 // TODO(aa): The rest of the crap below this really needs to be factored out |
| 744 // with a clean API boundary. Right now it is too soupy for me to feel |
| 745 // comfortable running in content scripts. What if people are just |
| 746 // overwriting random APIs? That would bypass our content script access |
| 747 // checks. |
| 748 if (!isExtensionProcess) |
| 749 return; |
| 750 |
| 722 // getTabContentses is retained for backwards compatibility | 751 // getTabContentses is retained for backwards compatibility |
| 723 // See http://crbug.com/21433 | 752 // See http://crbug.com/21433 |
| 724 chrome.extension.getTabContentses = chrome.extension.getExtensionTabs; | 753 chrome.extension.getTabContentses = chrome.extension.getExtensionTabs; |
| 725 // TOOD(mihaip): remove this alias once the webstore stops calling | 754 // TOOD(mihaip): remove this alias once the webstore stops calling |
| 726 // beginInstallWithManifest2. | 755 // beginInstallWithManifest2. |
| 727 // See http://crbug.com/100242 | 756 // See http://crbug.com/100242 |
| 728 chrome.webstorePrivate.beginInstallWithManifest2 = | 757 chrome.webstorePrivate.beginInstallWithManifest2 = |
| 729 chrome.webstorePrivate.beginInstallWithManifest3; | 758 chrome.webstorePrivate.beginInstallWithManifest3; |
| 730 | 759 |
| 731 apiFunctions["tabs.connect"].handleRequest = function(tabId, connectInfo) { | 760 apiFunctions["tabs.connect"].handleRequest = function(tabId, connectInfo) { |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1049 | 1078 |
| 1050 if (!chrome.tts) | 1079 if (!chrome.tts) |
| 1051 chrome.tts = {}; | 1080 chrome.tts = {}; |
| 1052 | 1081 |
| 1053 if (!chrome.ttsEngine) | 1082 if (!chrome.ttsEngine) |
| 1054 chrome.ttsEngine = {}; | 1083 chrome.ttsEngine = {}; |
| 1055 | 1084 |
| 1056 if (!chrome.experimental.downloads) | 1085 if (!chrome.experimental.downloads) |
| 1057 chrome.experimental.downloads = {}; | 1086 chrome.experimental.downloads = {}; |
| 1058 })(); | 1087 })(); |
| OLD | NEW |