Chromium Code Reviews| 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 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 610 // Setup the ChromeSetting class so we can use it to construct | 610 // Setup the ChromeSetting class so we can use it to construct |
| 611 // ChromeSetting objects from the API definition. | 611 // ChromeSetting objects from the API definition. |
| 612 setupChromeSetting(); | 612 setupChromeSetting(); |
| 613 | 613 |
| 614 // Ditto ContentSetting. | 614 // Ditto ContentSetting. |
| 615 setupContentSetting(); | 615 setupContentSetting(); |
| 616 | 616 |
| 617 // Ditto StorageNamespace. | 617 // Ditto StorageNamespace. |
| 618 setupStorageNamespace(); | 618 setupStorageNamespace(); |
| 619 | 619 |
| 620 // |apiFunctions| is a hash of name -> object that stores the | 620 // Stores the name and definition of each API function, with methods to |
| 621 // name & definition of the apiFunction. Custom handling of api functions | 621 // modify their behaviour (such as a custom way to handle requests to the |
| 622 // is implemented by adding a "handleRequest" function to the object. | 622 // API, a custom callback, etc). |
| 623 var apiFunctions = {}; | 623 function ApiFunctions() { |
|
Aaron Boodman
2011/12/15 04:37:12
Nit: can you name this "APIFunctions"?
not at google - send to devlin
2011/12/15 05:53:47
Done.
| |
| 624 this.apiFunctions_ = {}; | |
| 625 } | |
| 626 ApiFunctions.prototype.register = function(apiName, apiFunction) { | |
| 627 this.apiFunctions_[apiName] = apiFunction; | |
| 628 }; | |
| 629 ApiFunctions.prototype.setProperty = | |
| 630 function(apiName, propertyName, customizedFunction) { | |
| 631 // TODO(kalman): later, when this is asynchronous and we're only | |
| 632 // customizing exactly what we need, these should be held onto until | |
| 633 // this api function is registered. | |
| 634 if (this.apiFunctions_.hasOwnProperty(apiName)) | |
| 635 this.apiFunctions_[apiName][propertyName] = customizedFunction; | |
| 636 }; | |
| 637 ApiFunctions.prototype.setHandleRequest = | |
| 638 function(apiName, customizedFunction) { | |
| 639 return this.setProperty(apiName, 'handleRequest', customizedFunction); | |
| 640 }; | |
| 641 ApiFunctions.prototype.setUpdateArgumentsPostValidate = | |
| 642 function(apiName, customizedFunction) { | |
| 643 return this.setProperty( | |
| 644 apiName, 'updateArgumentsPostValidate', customizedFunction); | |
| 645 }; | |
| 646 ApiFunctions.prototype.setUpdateArgumentsPreValidate = | |
| 647 function(apiName, customizedFunction) { | |
| 648 return this.setProperty( | |
| 649 apiName, 'updateArgumentsPreValidate', customizedFunction); | |
| 650 }; | |
| 651 ApiFunctions.prototype.setCustomCallback = | |
| 652 function(apiName, customizedFunction) { | |
| 653 return this.setProperty(apiName, 'customCallback', customizedFunction); | |
| 654 }; | |
| 655 | |
| 656 var apiFunctions = new ApiFunctions(); | |
| 624 | 657 |
| 625 // Read api definitions and setup api functions in the chrome namespace. | 658 // Read api definitions and setup api functions in the chrome namespace. |
| 626 // TODO(rafaelw): Consider defining a json schema for an api definition | 659 // TODO(rafaelw): Consider defining a json schema for an api definition |
| 627 // and validating either here, in a unit_test or both. | 660 // and validating either here, in a unit_test or both. |
| 628 // TODO(rafaelw): Handle synchronous functions. | 661 // TODO(rafaelw): Handle synchronous functions. |
| 629 // TODO(rafaelw): Consider providing some convenient override points | 662 // TODO(rafaelw): Consider providing some convenient override points |
| 630 // for api functions that wish to insert themselves into the call. | 663 // for api functions that wish to insert themselves into the call. |
| 631 var apiDefinitions = GetExtensionAPIDefinition(); | 664 var apiDefinitions = GetExtensionAPIDefinition(); |
| 632 var platform = getPlatform(); | 665 var platform = getPlatform(); |
| 633 | 666 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 676 apiDef.functions.forEach(function(functionDef) { | 709 apiDef.functions.forEach(function(functionDef) { |
| 677 if (functionDef.name in module || | 710 if (functionDef.name in module || |
| 678 addUnprivilegedAccessGetter(module, functionDef.name, | 711 addUnprivilegedAccessGetter(module, functionDef.name, |
| 679 functionDef.unprivileged)) { | 712 functionDef.unprivileged)) { |
| 680 return; | 713 return; |
| 681 } | 714 } |
| 682 | 715 |
| 683 var apiFunction = {}; | 716 var apiFunction = {}; |
| 684 apiFunction.definition = functionDef; | 717 apiFunction.definition = functionDef; |
| 685 apiFunction.name = apiDef.namespace + "." + functionDef.name; | 718 apiFunction.name = apiDef.namespace + "." + functionDef.name; |
| 686 apiFunctions[apiFunction.name] = apiFunction; | 719 apiFunctions.register(apiFunction.name, apiFunction); |
| 687 | 720 |
| 688 module[functionDef.name] = (function() { | 721 module[functionDef.name] = (function() { |
| 689 var args = arguments; | 722 var args = arguments; |
| 690 if (this.updateArgumentsPreValidate) | 723 if (this.updateArgumentsPreValidate) |
| 691 args = this.updateArgumentsPreValidate.apply(this, args); | 724 args = this.updateArgumentsPreValidate.apply(this, args); |
| 692 chromeHidden.validate(args, this.definition.parameters); | 725 chromeHidden.validate(args, this.definition.parameters); |
| 693 if (this.updateArgumentsPostValidate) | 726 if (this.updateArgumentsPostValidate) |
| 694 args = this.updateArgumentsPostValidate.apply(this, args); | 727 args = this.updateArgumentsPostValidate.apply(this, args); |
| 695 | 728 |
| 696 var retval; | 729 var retval; |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 785 | 818 |
| 786 // getTabContentses is retained for backwards compatibility | 819 // getTabContentses is retained for backwards compatibility |
| 787 // See http://crbug.com/21433 | 820 // See http://crbug.com/21433 |
| 788 chrome.extension.getTabContentses = chrome.extension.getExtensionTabs; | 821 chrome.extension.getTabContentses = chrome.extension.getExtensionTabs; |
| 789 // TOOD(mihaip): remove this alias once the webstore stops calling | 822 // TOOD(mihaip): remove this alias once the webstore stops calling |
| 790 // beginInstallWithManifest2. | 823 // beginInstallWithManifest2. |
| 791 // See http://crbug.com/100242 | 824 // See http://crbug.com/100242 |
| 792 chrome.webstorePrivate.beginInstallWithManifest2 = | 825 chrome.webstorePrivate.beginInstallWithManifest2 = |
| 793 chrome.webstorePrivate.beginInstallWithManifest3; | 826 chrome.webstorePrivate.beginInstallWithManifest3; |
| 794 | 827 |
| 795 apiFunctions["tabs.connect"].handleRequest = function(tabId, connectInfo) { | 828 apiFunctions.setHandleRequest("tabs.connect", function(tabId, connectInfo) { |
| 796 var name = ""; | 829 var name = ""; |
| 797 if (connectInfo) { | 830 if (connectInfo) { |
| 798 name = connectInfo.name || name; | 831 name = connectInfo.name || name; |
| 799 } | 832 } |
| 800 var portId = OpenChannelToTab(tabId, chromeHidden.extensionId, name); | 833 var portId = OpenChannelToTab(tabId, chromeHidden.extensionId, name); |
| 801 return chromeHidden.Port.createPort(portId, name); | 834 return chromeHidden.Port.createPort(portId, name); |
| 802 }; | 835 }); |
| 803 | 836 |
| 804 apiFunctions["tabs.sendRequest"].handleRequest = | 837 apiFunctions.setHandleRequest("tabs.sendRequest", |
| 805 function(tabId, request, responseCallback) { | 838 function(tabId, request, responseCallback) { |
| 806 var port = chrome.tabs.connect(tabId, | 839 var port = chrome.tabs.connect(tabId, |
| 807 {name: chromeHidden.kRequestChannel}); | 840 {name: chromeHidden.kRequestChannel}); |
| 808 port.postMessage(request); | 841 port.postMessage(request); |
| 809 port.onDisconnect.addListener(function() { | 842 port.onDisconnect.addListener(function() { |
| 810 // For onDisconnects, we only notify the callback if there was an error. | 843 // For onDisconnects, we only notify the callback if there was an error. |
| 811 if (chrome.extension.lastError && responseCallback) | 844 if (chrome.extension.lastError && responseCallback) |
| 812 responseCallback(); | 845 responseCallback(); |
| 813 }); | 846 }); |
| 814 port.onMessage.addListener(function(response) { | 847 port.onMessage.addListener(function(response) { |
| 815 try { | 848 try { |
| 816 if (responseCallback) | 849 if (responseCallback) |
| 817 responseCallback(response); | 850 responseCallback(response); |
| 818 } finally { | 851 } finally { |
| 819 port.disconnect(); | 852 port.disconnect(); |
| 820 port = null; | 853 port = null; |
| 821 } | 854 } |
| 822 }); | 855 }); |
| 823 }; | 856 }); |
| 824 | 857 |
| 825 apiFunctions["pageCapture.saveAsMHTML"].customCallback = | 858 apiFunctions.setCustomCallback("pageCapture.saveAsMHTML", |
| 826 function(name, request, response) { | 859 function(name, request, response) { |
| 827 var params = chromeHidden.JSON.parse(response); | 860 var params = chromeHidden.JSON.parse(response); |
| 828 var path = params.mhtmlFilePath; | 861 var path = params.mhtmlFilePath; |
| 829 var size = params.mhtmlFileLength; | 862 var size = params.mhtmlFileLength; |
| 830 | 863 |
| 831 if (request.callback) | 864 if (request.callback) |
| 832 request.callback(CreateBlob(path, size)); | 865 request.callback(CreateBlob(path, size)); |
| 833 request.callback = null; | 866 request.callback = null; |
| 834 | 867 |
| 835 // Notify the browser. Now that the blob is referenced from JavaScript, | 868 // Notify the browser. Now that the blob is referenced from JavaScript, |
| 836 // the browser can drop its reference to it. | 869 // the browser can drop its reference to it. |
| 837 SendResponseAck(request.id); | 870 SendResponseAck(request.id); |
| 838 }; | 871 }); |
| 839 | 872 |
| 840 apiFunctions["fileBrowserPrivate.requestLocalFileSystem"].customCallback = | 873 apiFunctions.setCustomCallback("fileBrowserPrivate.requestLocalFileSystem", |
| 841 function(name, request, response) { | 874 function(name, request, response) { |
| 842 var resp = response ? [chromeHidden.JSON.parse(response)] : []; | 875 var resp = response ? [chromeHidden.JSON.parse(response)] : []; |
| 843 var fs = null; | 876 var fs = null; |
| 844 if (!resp[0].error) | 877 if (!resp[0].error) |
| 845 fs = GetLocalFileSystem(resp[0].name, resp[0].path); | 878 fs = GetLocalFileSystem(resp[0].name, resp[0].path); |
| 846 if (request.callback) | 879 if (request.callback) |
| 847 request.callback(fs); | 880 request.callback(fs); |
| 848 request.callback = null; | 881 request.callback = null; |
| 849 }; | 882 }); |
| 850 | 883 |
| 851 apiFunctions["chromePrivate.decodeJPEG"].handleRequest = | 884 apiFunctions.setHandleRequest("chromePrivate.decodeJPEG", |
| 852 function(jpeg_image) { | 885 function(jpeg_image) { |
| 853 return DecodeJPEG(jpeg_image); | 886 return DecodeJPEG(jpeg_image); |
| 854 }; | 887 }); |
| 855 | 888 |
| 856 apiFunctions["extension.getViews"].handleRequest = function(properties) { | 889 apiFunctions.setHandleRequest("extension.getViews", function(properties) { |
| 857 var windowId = -1; | 890 var windowId = -1; |
| 858 var type = "ALL"; | 891 var type = "ALL"; |
| 859 if (typeof(properties) != "undefined") { | 892 if (typeof(properties) != "undefined") { |
| 860 if (typeof(properties.type) != "undefined") { | 893 if (typeof(properties.type) != "undefined") { |
| 861 type = properties.type; | 894 type = properties.type; |
| 862 } | 895 } |
| 863 if (typeof(properties.windowId) != "undefined") { | 896 if (typeof(properties.windowId) != "undefined") { |
| 864 windowId = properties.windowId; | 897 windowId = properties.windowId; |
| 865 } | 898 } |
| 866 } | 899 } |
| 867 return GetExtensionViews(windowId, type) || null; | 900 return GetExtensionViews(windowId, type) || null; |
| 868 }; | 901 }); |
| 869 | 902 |
| 870 apiFunctions["extension.getBackgroundPage"].handleRequest = function() { | 903 apiFunctions.setHandleRequest("extension.getBackgroundPage", function() { |
| 871 return GetExtensionViews(-1, "BACKGROUND")[0] || null; | 904 return GetExtensionViews(-1, "BACKGROUND")[0] || null; |
| 872 }; | 905 }); |
| 873 | 906 |
| 874 apiFunctions["extension.getExtensionTabs"].handleRequest = | 907 apiFunctions.setHandleRequest("extension.getExtensionTabs", |
| 875 function(windowId) { | 908 function(windowId) { |
| 876 if (typeof(windowId) == "undefined") | 909 if (typeof(windowId) == "undefined") |
| 877 windowId = -1; | 910 windowId = -1; |
| 878 return GetExtensionViews(windowId, "TAB"); | 911 return GetExtensionViews(windowId, "TAB"); |
| 879 }; | 912 }); |
| 880 | 913 |
| 881 apiFunctions["devtools.getTabEvents"].handleRequest = function(tabId) { | 914 apiFunctions.setHandleRequest("devtools.getTabEvents", function(tabId) { |
| 882 var tabIdProxy = {}; | 915 var tabIdProxy = {}; |
| 883 var functions = ["onPageEvent", "onTabClose"]; | 916 var functions = ["onPageEvent", "onTabClose"]; |
| 884 functions.forEach(function(name) { | 917 functions.forEach(function(name) { |
| 885 // Event disambiguation is handled by name munging. See | 918 // Event disambiguation is handled by name munging. See |
| 886 // chrome/browser/extensions/extension_devtools_events.h for the C++ | 919 // chrome/browser/extensions/extension_devtools_events.h for the C++ |
| 887 // equivalent of this logic. | 920 // equivalent of this logic. |
| 888 tabIdProxy[name] = new chrome.Event("devtools." + tabId + "." + name); | 921 tabIdProxy[name] = new chrome.Event("devtools." + tabId + "." + name); |
| 889 }); | 922 }); |
| 890 return tabIdProxy; | 923 return tabIdProxy; |
| 891 }; | 924 }); |
| 892 | 925 |
| 893 var canvas; | 926 var canvas; |
| 894 function setIconCommon(details, name, parameters, actionType, iconSize, | 927 function setIconCommon(details, name, parameters, actionType, iconSize, |
| 895 nativeFunction) { | 928 nativeFunction) { |
| 896 if ("iconIndex" in details) { | 929 if ("iconIndex" in details) { |
| 897 sendRequest(name, [details], parameters); | 930 sendRequest(name, [details], parameters); |
| 898 } else if ("imageData" in details) { | 931 } else if ("imageData" in details) { |
| 899 // Verify that this at least looks like an ImageData element. | 932 // Verify that this at least looks like an ImageData element. |
| 900 // Unfortunately, we cannot use instanceof because the ImageData | 933 // Unfortunately, we cannot use instanceof because the ImageData |
| 901 // constructor is not public. | 934 // constructor is not public. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 945 } | 978 } |
| 946 } | 979 } |
| 947 | 980 |
| 948 function setExtensionActionIconCommon(details, name, parameters, | 981 function setExtensionActionIconCommon(details, name, parameters, |
| 949 actionType) { | 982 actionType) { |
| 950 var EXTENSION_ACTION_ICON_SIZE = 19; | 983 var EXTENSION_ACTION_ICON_SIZE = 19; |
| 951 setIconCommon(details, name, parameters, actionType, | 984 setIconCommon(details, name, parameters, actionType, |
| 952 EXTENSION_ACTION_ICON_SIZE, SetIconCommon); | 985 EXTENSION_ACTION_ICON_SIZE, SetIconCommon); |
| 953 } | 986 } |
| 954 | 987 |
| 955 apiFunctions["browserAction.setIcon"].handleRequest = function(details) { | 988 apiFunctions.setHandleRequest("browserAction.setIcon", function(details) { |
| 956 setExtensionActionIconCommon( | 989 setExtensionActionIconCommon( |
| 957 details, this.name, this.definition.parameters, "browser action"); | 990 details, this.name, this.definition.parameters, "browser action"); |
| 958 }; | 991 }); |
| 959 | 992 |
| 960 apiFunctions["pageAction.setIcon"].handleRequest = function(details) { | 993 apiFunctions.setHandleRequest("pageAction.setIcon", function(details) { |
| 961 setExtensionActionIconCommon( | 994 setExtensionActionIconCommon( |
| 962 details, this.name, this.definition.parameters, "page action"); | 995 details, this.name, this.definition.parameters, "page action"); |
| 963 }; | 996 }); |
| 964 | 997 |
| 965 apiFunctions["experimental.sidebar.setIcon"].handleRequest = | 998 apiFunctions.setHandleRequest("experimental.sidebar.setIcon", |
| 966 function(details) { | 999 function(details) { |
| 967 var SIDEBAR_ICON_SIZE = 16; | 1000 var SIDEBAR_ICON_SIZE = 16; |
| 968 setIconCommon( | 1001 setIconCommon( |
| 969 details, this.name, this.definition.parameters, "sidebar", | 1002 details, this.name, this.definition.parameters, "sidebar", |
| 970 SIDEBAR_ICON_SIZE, SetIconCommon); | 1003 SIDEBAR_ICON_SIZE, SetIconCommon); |
| 971 }; | 1004 }); |
| 972 | 1005 |
| 973 apiFunctions["contextMenus.create"].handleRequest = | 1006 apiFunctions.setHandleRequest("contextMenus.create", |
| 974 function() { | 1007 function() { |
| 975 var args = arguments; | 1008 var args = arguments; |
| 976 var id = GetNextContextMenuId(); | 1009 var id = GetNextContextMenuId(); |
| 977 args[0].generatedId = id; | 1010 args[0].generatedId = id; |
| 978 sendRequest(this.name, args, this.definition.parameters, | 1011 sendRequest(this.name, args, this.definition.parameters, |
| 979 {customCallback: this.customCallback}); | 1012 {customCallback: this.customCallback}); |
| 980 return id; | 1013 return id; |
| 981 }; | 1014 }); |
| 982 | 1015 |
| 983 apiFunctions["omnibox.setDefaultSuggestion"].handleRequest = | 1016 apiFunctions.setHandleRequest("omnibox.setDefaultSuggestion", |
| 984 function(details) { | 1017 function(details) { |
| 985 var parseResult = parseOmniboxDescription(details.description); | 1018 var parseResult = parseOmniboxDescription(details.description); |
| 986 sendRequest(this.name, [parseResult], this.definition.parameters); | 1019 sendRequest(this.name, [parseResult], this.definition.parameters); |
| 987 }; | 1020 }); |
| 988 | 1021 |
| 989 apiFunctions["webRequest.addEventListener"].handleRequest = | 1022 apiFunctions.setHandleRequest("webRequest.addEventListener", |
| 990 function() { | 1023 function() { |
| 991 var args = Array.prototype.slice.call(arguments); | 1024 var args = Array.prototype.slice.call(arguments); |
| 992 sendRequest(this.name, args, this.definition.parameters, | 1025 sendRequest(this.name, args, this.definition.parameters, |
| 993 {forIOThread: true}); | 1026 {forIOThread: true}); |
| 994 }; | 1027 }); |
| 995 | 1028 |
| 996 apiFunctions["webRequest.eventHandled"].handleRequest = | 1029 apiFunctions.setHandleRequest("webRequest.eventHandled", |
| 997 function() { | 1030 function() { |
| 998 var args = Array.prototype.slice.call(arguments); | 1031 var args = Array.prototype.slice.call(arguments); |
| 999 sendRequest(this.name, args, this.definition.parameters, | 1032 sendRequest(this.name, args, this.definition.parameters, |
| 1000 {forIOThread: true}); | 1033 {forIOThread: true}); |
| 1001 }; | 1034 }); |
| 1002 | 1035 |
| 1003 apiFunctions["webRequest.handlerBehaviorChanged"]. | 1036 apiFunctions.setHandleRequest("webRequest.handlerBehaviorChanged", |
| 1004 handleRequest = function() { | 1037 function() { |
| 1005 var args = Array.prototype.slice.call(arguments); | 1038 var args = Array.prototype.slice.call(arguments); |
| 1006 sendRequest(this.name, args, this.definition.parameters, | 1039 sendRequest(this.name, args, this.definition.parameters, |
| 1007 {forIOThread: true}); | 1040 {forIOThread: true}); |
| 1008 }; | 1041 }); |
| 1009 | 1042 |
| 1010 apiFunctions["contextMenus.create"].customCallback = | 1043 apiFunctions.setCustomCallback("contextMenus.create", |
| 1011 function(name, request, response) { | 1044 function(name, request, response) { |
| 1012 if (chrome.extension.lastError) { | 1045 if (chrome.extension.lastError) { |
| 1013 return; | 1046 return; |
| 1014 } | 1047 } |
| 1015 | 1048 |
| 1016 var id = request.args[0].generatedId; | 1049 var id = request.args[0].generatedId; |
| 1017 | 1050 |
| 1018 // Set up the onclick handler if we were passed one in the request. | 1051 // Set up the onclick handler if we were passed one in the request. |
| 1019 var onclick = request.args.length ? request.args[0].onclick : null; | 1052 var onclick = request.args.length ? request.args[0].onclick : null; |
| 1020 if (onclick) { | 1053 if (onclick) { |
| 1021 chromeHidden.contextMenus.ensureListenerSetup(); | 1054 chromeHidden.contextMenus.ensureListenerSetup(); |
| 1022 chromeHidden.contextMenus.handlers[id] = onclick; | 1055 chromeHidden.contextMenus.handlers[id] = onclick; |
| 1023 } | 1056 } |
| 1024 }; | 1057 }); |
| 1025 | 1058 |
| 1026 apiFunctions["contextMenus.remove"].customCallback = | 1059 apiFunctions.setCustomCallback("contextMenus.remove", |
| 1027 function(name, request, response) { | 1060 function(name, request, response) { |
| 1028 if (chrome.extension.lastError) { | 1061 if (chrome.extension.lastError) { |
| 1029 return; | 1062 return; |
| 1030 } | 1063 } |
| 1031 var id = request.args[0]; | 1064 var id = request.args[0]; |
| 1032 delete chromeHidden.contextMenus.handlers[id]; | 1065 delete chromeHidden.contextMenus.handlers[id]; |
| 1033 }; | 1066 }); |
| 1034 | 1067 |
| 1035 apiFunctions["contextMenus.update"].customCallback = | 1068 apiFunctions.setCustomCallback("contextMenus.update", |
| 1036 function(name, request, response) { | 1069 function(name, request, response) { |
| 1037 if (chrome.extension.lastError) { | 1070 if (chrome.extension.lastError) { |
| 1038 return; | 1071 return; |
| 1039 } | 1072 } |
| 1040 var id = request.args[0]; | 1073 var id = request.args[0]; |
| 1041 if (request.args[1].onclick) { | 1074 if (request.args[1].onclick) { |
| 1042 chromeHidden.contextMenus.handlers[id] = request.args[1].onclick; | 1075 chromeHidden.contextMenus.handlers[id] = request.args[1].onclick; |
| 1043 } | 1076 } |
| 1044 }; | 1077 }); |
| 1045 | 1078 |
| 1046 apiFunctions["contextMenus.removeAll"].customCallback = | 1079 apiFunctions.setCustomCallback("contextMenus.removeAll", |
| 1047 function(name, request, response) { | 1080 function(name, request, response) { |
| 1048 if (chrome.extension.lastError) { | 1081 if (chrome.extension.lastError) { |
| 1049 return; | 1082 return; |
| 1050 } | 1083 } |
| 1051 chromeHidden.contextMenus.handlers = {}; | 1084 chromeHidden.contextMenus.handlers = {}; |
| 1052 }; | 1085 }); |
| 1053 | 1086 |
| 1054 apiFunctions["tabs.captureVisibleTab"].updateArgumentsPreValidate = | 1087 apiFunctions.setUpdateArgumentsPreValidate("tabs.captureVisibleTab", |
| 1055 function() { | 1088 function() { |
| 1056 // Old signature: | 1089 // Old signature: |
| 1057 // captureVisibleTab(int windowId, function callback); | 1090 // captureVisibleTab(int windowId, function callback); |
| 1058 // New signature: | 1091 // New signature: |
| 1059 // captureVisibleTab(int windowId, object details, function callback); | 1092 // captureVisibleTab(int windowId, object details, function callback); |
| 1060 // | 1093 // |
| 1061 // TODO(skerner): The next step to omitting optional arguments is the | 1094 // TODO(skerner): The next step to omitting optional arguments is the |
| 1062 // replacement of this code with code that matches arguments by type. | 1095 // replacement of this code with code that matches arguments by type. |
| 1063 // Once this is working for captureVisibleTab() it can be enabled for | 1096 // Once this is working for captureVisibleTab() it can be enabled for |
| 1064 // the rest of the API. See crbug/29215 . | 1097 // the rest of the API. See crbug/29215 . |
| 1065 if (arguments.length == 2 && typeof(arguments[1]) == "function") { | 1098 if (arguments.length == 2 && typeof(arguments[1]) == "function") { |
| 1066 // If the old signature is used, add a null details object. | 1099 // If the old signature is used, add a null details object. |
| 1067 newArgs = [arguments[0], null, arguments[1]]; | 1100 newArgs = [arguments[0], null, arguments[1]]; |
| 1068 } else { | 1101 } else { |
| 1069 newArgs = arguments; | 1102 newArgs = arguments; |
| 1070 } | 1103 } |
| 1071 return newArgs; | 1104 return newArgs; |
| 1072 }; | 1105 }); |
| 1073 | 1106 |
| 1074 apiFunctions["omnibox.sendSuggestions"].updateArgumentsPostValidate = | 1107 apiFunctions.setUpdateArgumentsPostValidate("omnibox.sendSuggestions", |
| 1075 function(requestId, userSuggestions) { | 1108 function(requestId, userSuggestions) { |
| 1076 var suggestions = []; | 1109 var suggestions = []; |
| 1077 for (var i = 0; i < userSuggestions.length; i++) { | 1110 for (var i = 0; i < userSuggestions.length; i++) { |
| 1078 var parseResult = parseOmniboxDescription( | 1111 var parseResult = parseOmniboxDescription( |
| 1079 userSuggestions[i].description); | 1112 userSuggestions[i].description); |
| 1080 parseResult.content = userSuggestions[i].content; | 1113 parseResult.content = userSuggestions[i].content; |
| 1081 suggestions.push(parseResult); | 1114 suggestions.push(parseResult); |
| 1082 } | 1115 } |
| 1083 return [requestId, suggestions]; | 1116 return [requestId, suggestions]; |
| 1084 }; | 1117 }); |
| 1085 | 1118 |
| 1086 apiFunctions["tts.speak"].handleRequest = function() { | 1119 apiFunctions.setHandleRequest("tts.speak", function() { |
| 1087 var args = arguments; | 1120 var args = arguments; |
| 1088 if (args.length > 1 && args[1] && args[1].onEvent) { | 1121 if (args.length > 1 && args[1] && args[1].onEvent) { |
| 1089 var id = GetNextTtsEventId(); | 1122 var id = GetNextTtsEventId(); |
| 1090 args[1].srcId = id; | 1123 args[1].srcId = id; |
| 1091 chromeHidden.tts.handlers[id] = args[1].onEvent; | 1124 chromeHidden.tts.handlers[id] = args[1].onEvent; |
| 1092 } | 1125 } |
| 1093 sendRequest(this.name, args, this.definition.parameters); | 1126 sendRequest(this.name, args, this.definition.parameters); |
| 1094 return id; | 1127 return id; |
| 1095 }; | 1128 }); |
| 1096 | 1129 |
| 1097 if (chrome.test) { | 1130 if (chrome.test) { |
| 1098 chrome.test.getApiDefinitions = GetExtensionAPIDefinition; | 1131 chrome.test.getApiDefinitions = GetExtensionAPIDefinition; |
| 1099 } | 1132 } |
| 1100 | 1133 |
| 1101 setupPageActionEvents(extensionId); | 1134 setupPageActionEvents(extensionId); |
| 1102 setupHiddenContextMenuEvent(extensionId); | 1135 setupHiddenContextMenuEvent(extensionId); |
| 1103 setupInputEvents(); | 1136 setupInputEvents(); |
| 1104 setupOmniboxEvents(); | 1137 setupOmniboxEvents(); |
| 1105 setupTtsEvents(); | 1138 setupTtsEvents(); |
| 1106 }); | 1139 }); |
| 1107 | 1140 |
| 1141 // TODO(kalman): these should all be unnecessary steps if we design the | |
| 1142 // ApiFunctions class correctly. | |
| 1143 | |
| 1108 if (!chrome.experimental) | 1144 if (!chrome.experimental) |
| 1109 chrome.experimental = {}; | 1145 chrome.experimental = {}; |
| 1110 | 1146 |
| 1111 if (!chrome.experimental.accessibility) | 1147 if (!chrome.experimental.accessibility) |
| 1112 chrome.experimental.accessibility = {}; | 1148 chrome.experimental.accessibility = {}; |
| 1113 | 1149 |
| 1114 if (!chrome.experimental.speechInput) | 1150 if (!chrome.experimental.speechInput) |
| 1115 chrome.experimental.speechInput = {}; | 1151 chrome.experimental.speechInput = {}; |
| 1116 | 1152 |
| 1117 if (!chrome.tts) | 1153 if (!chrome.tts) |
| 1118 chrome.tts = {}; | 1154 chrome.tts = {}; |
| 1119 | 1155 |
| 1120 if (!chrome.ttsEngine) | 1156 if (!chrome.ttsEngine) |
| 1121 chrome.ttsEngine = {}; | 1157 chrome.ttsEngine = {}; |
| 1122 | 1158 |
| 1123 if (!chrome.experimental.downloads) | 1159 if (!chrome.experimental.downloads) |
| 1124 chrome.experimental.downloads = {}; | 1160 chrome.experimental.downloads = {}; |
| 1125 })(); | 1161 })(); |
| OLD | NEW |