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 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 | 176 |
177 request.args = []; | 177 request.args = []; |
178 for (var k = 0; k < argCount; k++) { | 178 for (var k = 0; k < argCount; k++) { |
179 request.args[k] = args[k]; | 179 request.args[k] = args[k]; |
180 } | 180 } |
181 | 181 |
182 return request; | 182 return request; |
183 } | 183 } |
184 | 184 |
185 // Send an API request and optionally register a callback. | 185 // Send an API request and optionally register a callback. |
186 function sendRequest(functionName, args, argSchemas, customCallback) { | 186 // |opt_args| is an object with optional parameters as follows: |
| 187 // - noStringify: true if we should not stringify the request arguments. |
| 188 // - customCallback: a callback that should be called instead of the standard |
| 189 // callback. |
| 190 // - nativeFunction: the v8 native function to handle the request, or |
| 191 // StartRequest if missing. |
| 192 // - forIOThread: true if this function should be handled on the browser IO |
| 193 // thread. |
| 194 function sendRequest(functionName, args, argSchemas, opt_args) { |
| 195 if (!opt_args) |
| 196 opt_args = {}; |
187 var request = prepareRequest(args, argSchemas); | 197 var request = prepareRequest(args, argSchemas); |
188 if (customCallback) { | 198 if (opt_args.customCallback) { |
189 request.customCallback = customCallback; | 199 request.customCallback = opt_args.customCallback; |
190 } | 200 } |
191 // JSON.stringify doesn't support a root object which is undefined. | 201 // JSON.stringify doesn't support a root object which is undefined. |
192 if (request.args === undefined) | 202 if (request.args === undefined) |
193 request.args = null; | 203 request.args = null; |
194 | 204 |
195 var sargs = chromeHidden.JSON.stringify(request.args); | 205 var sargs = opt_args.noStringify ? |
| 206 request.args : chromeHidden.JSON.stringify(request.args); |
| 207 var nativeFunction = opt_args.nativeFunction || StartRequest; |
196 | 208 |
197 var requestId = GetNextRequestId(); | 209 var requestId = GetNextRequestId(); |
198 requests[requestId] = request; | 210 requests[requestId] = request; |
199 var hasCallback = (request.callback || customCallback) ? true : false; | 211 var hasCallback = |
200 return StartRequest(functionName, sargs, requestId, hasCallback); | 212 (request.callback || opt_args.customCallback) ? true : false; |
201 } | 213 return nativeFunction(functionName, sargs, requestId, hasCallback, |
202 | 214 opt_args.forIOThread); |
203 // Send a special API request that is not JSON stringifiable, and optionally | |
204 // register a callback. | |
205 function sendCustomRequest(nativeFunction, functionName, args, argSchemas) { | |
206 var request = prepareRequest(args, argSchemas); | |
207 var requestId = GetNextRequestId(); | |
208 requests[requestId] = request; | |
209 return nativeFunction(functionName, request.args, requestId, | |
210 request.callback ? true : false); | |
211 } | 215 } |
212 | 216 |
213 // Helper function for positioning pop-up windows relative to DOM objects. | 217 // Helper function for positioning pop-up windows relative to DOM objects. |
214 // Returns the absolute position of the given element relative to the hosting | 218 // Returns the absolute position of the given element relative to the hosting |
215 // browser frame. | 219 // browser frame. |
216 function findAbsolutePosition(domElement) { | 220 function findAbsolutePosition(domElement) { |
217 var left = domElement.offsetLeft; | 221 var left = domElement.offsetLeft; |
218 var top = domElement.offsetTop; | 222 var top = domElement.offsetTop; |
219 | 223 |
220 // Ascend through the parent hierarchy, taking into account object nesting | 224 // Ascend through the parent hierarchy, taking into account object nesting |
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
618 chromeHidden.validate(args, this.definition.parameters); | 622 chromeHidden.validate(args, this.definition.parameters); |
619 if (this.updateArgumentsPostValidate) | 623 if (this.updateArgumentsPostValidate) |
620 args = this.updateArgumentsPostValidate.apply(this, args); | 624 args = this.updateArgumentsPostValidate.apply(this, args); |
621 | 625 |
622 var retval; | 626 var retval; |
623 if (this.handleRequest) { | 627 if (this.handleRequest) { |
624 retval = this.handleRequest.apply(this, args); | 628 retval = this.handleRequest.apply(this, args); |
625 } else { | 629 } else { |
626 retval = sendRequest(this.name, args, | 630 retval = sendRequest(this.name, args, |
627 this.definition.parameters, | 631 this.definition.parameters, |
628 this.customCallback); | 632 {customCallback: this.customCallback}); |
629 } | 633 } |
630 | 634 |
631 // Validate return value if defined - only in debug. | 635 // Validate return value if defined - only in debug. |
632 if (chromeHidden.validateCallbacks && | 636 if (chromeHidden.validateCallbacks && |
633 chromeHidden.validate && | 637 chromeHidden.validate && |
634 this.definition.returns) { | 638 this.definition.returns) { |
635 chromeHidden.validate([retval], [this.definition.returns]); | 639 chromeHidden.validate([retval], [this.definition.returns]); |
636 } | 640 } |
637 return retval; | 641 return retval; |
638 }).bind(apiFunction); | 642 }).bind(apiFunction); |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
809 "The imageData property must contain an ImageData object."); | 813 "The imageData property must contain an ImageData object."); |
810 } | 814 } |
811 | 815 |
812 if (details.imageData.width > iconSize || | 816 if (details.imageData.width > iconSize || |
813 details.imageData.height > iconSize) { | 817 details.imageData.height > iconSize) { |
814 throw new Error( | 818 throw new Error( |
815 "The imageData property must contain an ImageData object that " + | 819 "The imageData property must contain an ImageData object that " + |
816 "is no larger than " + iconSize + " pixels square."); | 820 "is no larger than " + iconSize + " pixels square."); |
817 } | 821 } |
818 | 822 |
819 sendCustomRequest(nativeFunction, name, [details], parameters); | 823 sendRequest(name, [details], parameters, |
| 824 {noStringify: true, nativeFunction: nativeFunction}); |
820 } else if ("path" in details) { | 825 } else if ("path" in details) { |
821 var img = new Image(); | 826 var img = new Image(); |
822 img.onerror = function() { | 827 img.onerror = function() { |
823 console.error("Could not load " + actionType + " icon '" + | 828 console.error("Could not load " + actionType + " icon '" + |
824 details.path + "'."); | 829 details.path + "'."); |
825 }; | 830 }; |
826 img.onload = function() { | 831 img.onload = function() { |
827 var canvas = document.createElement("canvas"); | 832 var canvas = document.createElement("canvas"); |
828 canvas.width = img.width > iconSize ? iconSize : img.width; | 833 canvas.width = img.width > iconSize ? iconSize : img.width; |
829 canvas.height = img.height > iconSize ? iconSize : img.height; | 834 canvas.height = img.height > iconSize ? iconSize : img.height; |
830 | 835 |
831 var canvas_context = canvas.getContext('2d'); | 836 var canvas_context = canvas.getContext('2d'); |
832 canvas_context.clearRect(0, 0, canvas.width, canvas.height); | 837 canvas_context.clearRect(0, 0, canvas.width, canvas.height); |
833 canvas_context.drawImage(img, 0, 0, canvas.width, canvas.height); | 838 canvas_context.drawImage(img, 0, 0, canvas.width, canvas.height); |
834 delete details.path; | 839 delete details.path; |
835 details.imageData = canvas_context.getImageData(0, 0, canvas.width, | 840 details.imageData = canvas_context.getImageData(0, 0, canvas.width, |
836 canvas.height); | 841 canvas.height); |
837 sendCustomRequest(nativeFunction, name, [details], parameters); | 842 sendRequest(name, [details], parameters, |
| 843 {noStringify: true, nativeFunction: nativeFunction}); |
838 }; | 844 }; |
839 img.src = details.path; | 845 img.src = details.path; |
840 } else { | 846 } else { |
841 throw new Error( | 847 throw new Error( |
842 "Either the path or imageData property must be specified."); | 848 "Either the path or imageData property must be specified."); |
843 } | 849 } |
844 } | 850 } |
845 | 851 |
846 function setExtensionActionIconCommon(details, name, parameters, | 852 function setExtensionActionIconCommon(details, name, parameters, |
847 actionType) { | 853 actionType) { |
(...skipping 19 matching lines...) Expand all Loading... |
867 details, this.name, this.definition.parameters, "sidebar", | 873 details, this.name, this.definition.parameters, "sidebar", |
868 SIDEBAR_ICON_SIZE, SetIconCommon); | 874 SIDEBAR_ICON_SIZE, SetIconCommon); |
869 }; | 875 }; |
870 | 876 |
871 apiFunctions["contextMenus.create"].handleRequest = | 877 apiFunctions["contextMenus.create"].handleRequest = |
872 function() { | 878 function() { |
873 var args = arguments; | 879 var args = arguments; |
874 var id = GetNextContextMenuId(); | 880 var id = GetNextContextMenuId(); |
875 args[0].generatedId = id; | 881 args[0].generatedId = id; |
876 sendRequest(this.name, args, this.definition.parameters, | 882 sendRequest(this.name, args, this.definition.parameters, |
877 this.customCallback); | 883 {customCallback: this.customCallback}); |
878 return id; | 884 return id; |
879 }; | 885 }; |
880 | 886 |
881 apiFunctions["omnibox.setDefaultSuggestion"].handleRequest = | 887 apiFunctions["omnibox.setDefaultSuggestion"].handleRequest = |
882 function(details) { | 888 function(details) { |
883 var parseResult = parseOmniboxDescription(details.description); | 889 var parseResult = parseOmniboxDescription(details.description); |
884 sendRequest(this.name, [parseResult], this.definition.parameters); | 890 sendRequest(this.name, [parseResult], this.definition.parameters); |
885 }; | 891 }; |
886 | 892 |
| 893 apiFunctions["experimental.webRequest.addEventListener"].handleRequest = |
| 894 function() { |
| 895 var args = Array.prototype.slice.call(arguments); |
| 896 sendRequest(this.name, args, this.definition.parameters, |
| 897 {forIOThread: true}); |
| 898 }; |
| 899 |
| 900 apiFunctions["experimental.webRequest.eventHandled"].handleRequest = |
| 901 function() { |
| 902 var args = Array.prototype.slice.call(arguments); |
| 903 sendRequest(this.name, args, this.definition.parameters, |
| 904 {forIOThread: true}); |
| 905 }; |
| 906 |
887 apiFunctions["contextMenus.create"].customCallback = | 907 apiFunctions["contextMenus.create"].customCallback = |
888 function(name, request, response) { | 908 function(name, request, response) { |
889 if (chrome.extension.lastError) { | 909 if (chrome.extension.lastError) { |
890 return; | 910 return; |
891 } | 911 } |
892 | 912 |
893 var id = request.args[0].generatedId; | 913 var id = request.args[0].generatedId; |
894 | 914 |
895 // Set up the onclick handler if we were passed one in the request. | 915 // Set up the onclick handler if we were passed one in the request. |
896 var onclick = request.args.length ? request.args[0].onclick : null; | 916 var onclick = request.args.length ? request.args[0].onclick : null; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
973 | 993 |
974 if (!chrome.experimental) | 994 if (!chrome.experimental) |
975 chrome.experimental = {}; | 995 chrome.experimental = {}; |
976 | 996 |
977 if (!chrome.experimental.accessibility) | 997 if (!chrome.experimental.accessibility) |
978 chrome.experimental.accessibility = {}; | 998 chrome.experimental.accessibility = {}; |
979 | 999 |
980 if (!chrome.experimental.tts) | 1000 if (!chrome.experimental.tts) |
981 chrome.experimental.tts = {}; | 1001 chrome.experimental.tts = {}; |
982 })(); | 1002 })(); |
OLD | NEW |