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 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 // - rawArgs: true if we should not stringify the request arguments. | |
|
Mihai Parparita -not on Chrome
2011/06/09 18:37:24
noStringify or another boolean-like name seems bet
Matt Perry
2011/06/09 18:50:30
Done.
| |
| 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.rawArgs ? |
| 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 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 560 chromeHidden.validate(args, this.definition.parameters); | 564 chromeHidden.validate(args, this.definition.parameters); |
| 561 if (this.updateArgumentsPostValidate) | 565 if (this.updateArgumentsPostValidate) |
| 562 args = this.updateArgumentsPostValidate.apply(this, args); | 566 args = this.updateArgumentsPostValidate.apply(this, args); |
| 563 | 567 |
| 564 var retval; | 568 var retval; |
| 565 if (this.handleRequest) { | 569 if (this.handleRequest) { |
| 566 retval = this.handleRequest.apply(this, args); | 570 retval = this.handleRequest.apply(this, args); |
| 567 } else { | 571 } else { |
| 568 retval = sendRequest(this.name, args, | 572 retval = sendRequest(this.name, args, |
| 569 this.definition.parameters, | 573 this.definition.parameters, |
| 570 this.customCallback); | 574 {customCallback: this.customCallback}); |
| 571 } | 575 } |
| 572 | 576 |
| 573 // Validate return value if defined - only in debug. | 577 // Validate return value if defined - only in debug. |
| 574 if (chromeHidden.validateCallbacks && | 578 if (chromeHidden.validateCallbacks && |
| 575 chromeHidden.validate && | 579 chromeHidden.validate && |
| 576 this.definition.returns) { | 580 this.definition.returns) { |
| 577 chromeHidden.validate([retval], [this.definition.returns]); | 581 chromeHidden.validate([retval], [this.definition.returns]); |
| 578 } | 582 } |
| 579 return retval; | 583 return retval; |
| 580 }).bind(apiFunction); | 584 }).bind(apiFunction); |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 743 "The imageData property must contain an ImageData object."); | 747 "The imageData property must contain an ImageData object."); |
| 744 } | 748 } |
| 745 | 749 |
| 746 if (details.imageData.width > iconSize || | 750 if (details.imageData.width > iconSize || |
| 747 details.imageData.height > iconSize) { | 751 details.imageData.height > iconSize) { |
| 748 throw new Error( | 752 throw new Error( |
| 749 "The imageData property must contain an ImageData object that " + | 753 "The imageData property must contain an ImageData object that " + |
| 750 "is no larger than " + iconSize + " pixels square."); | 754 "is no larger than " + iconSize + " pixels square."); |
| 751 } | 755 } |
| 752 | 756 |
| 753 sendCustomRequest(nativeFunction, name, [details], parameters); | 757 sendRequest(name, [details], parameters, |
| 758 {rawArgs: true, nativeFunction: nativeFunction}); | |
| 754 } else if ("path" in details) { | 759 } else if ("path" in details) { |
| 755 var img = new Image(); | 760 var img = new Image(); |
| 756 img.onerror = function() { | 761 img.onerror = function() { |
| 757 console.error("Could not load " + actionType + " icon '" + | 762 console.error("Could not load " + actionType + " icon '" + |
| 758 details.path + "'."); | 763 details.path + "'."); |
| 759 }; | 764 }; |
| 760 img.onload = function() { | 765 img.onload = function() { |
| 761 var canvas = document.createElement("canvas"); | 766 var canvas = document.createElement("canvas"); |
| 762 canvas.width = img.width > iconSize ? iconSize : img.width; | 767 canvas.width = img.width > iconSize ? iconSize : img.width; |
| 763 canvas.height = img.height > iconSize ? iconSize : img.height; | 768 canvas.height = img.height > iconSize ? iconSize : img.height; |
| 764 | 769 |
| 765 var canvas_context = canvas.getContext('2d'); | 770 var canvas_context = canvas.getContext('2d'); |
| 766 canvas_context.clearRect(0, 0, canvas.width, canvas.height); | 771 canvas_context.clearRect(0, 0, canvas.width, canvas.height); |
| 767 canvas_context.drawImage(img, 0, 0, canvas.width, canvas.height); | 772 canvas_context.drawImage(img, 0, 0, canvas.width, canvas.height); |
| 768 delete details.path; | 773 delete details.path; |
| 769 details.imageData = canvas_context.getImageData(0, 0, canvas.width, | 774 details.imageData = canvas_context.getImageData(0, 0, canvas.width, |
| 770 canvas.height); | 775 canvas.height); |
| 771 sendCustomRequest(nativeFunction, name, [details], parameters); | 776 sendRequest(name, [details], parameters, |
| 777 {rawArgs: true, nativeFunction: nativeFunction}); | |
| 772 }; | 778 }; |
| 773 img.src = details.path; | 779 img.src = details.path; |
| 774 } else { | 780 } else { |
| 775 throw new Error( | 781 throw new Error( |
| 776 "Either the path or imageData property must be specified."); | 782 "Either the path or imageData property must be specified."); |
| 777 } | 783 } |
| 778 } | 784 } |
| 779 | 785 |
| 780 function setExtensionActionIconCommon(details, name, parameters, | 786 function setExtensionActionIconCommon(details, name, parameters, |
| 781 actionType) { | 787 actionType) { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 801 details, this.name, this.definition.parameters, "sidebar", | 807 details, this.name, this.definition.parameters, "sidebar", |
| 802 SIDEBAR_ICON_SIZE, SetIconCommon); | 808 SIDEBAR_ICON_SIZE, SetIconCommon); |
| 803 }; | 809 }; |
| 804 | 810 |
| 805 apiFunctions["contextMenus.create"].handleRequest = | 811 apiFunctions["contextMenus.create"].handleRequest = |
| 806 function() { | 812 function() { |
| 807 var args = arguments; | 813 var args = arguments; |
| 808 var id = GetNextContextMenuId(); | 814 var id = GetNextContextMenuId(); |
| 809 args[0].generatedId = id; | 815 args[0].generatedId = id; |
| 810 sendRequest(this.name, args, this.definition.parameters, | 816 sendRequest(this.name, args, this.definition.parameters, |
| 811 this.customCallback); | 817 {customCallback: this.customCallback}); |
| 812 return id; | 818 return id; |
| 813 }; | 819 }; |
| 814 | 820 |
| 815 apiFunctions["omnibox.setDefaultSuggestion"].handleRequest = | 821 apiFunctions["omnibox.setDefaultSuggestion"].handleRequest = |
| 816 function(details) { | 822 function(details) { |
| 817 var parseResult = parseOmniboxDescription(details.description); | 823 var parseResult = parseOmniboxDescription(details.description); |
| 818 sendRequest(this.name, [parseResult], this.definition.parameters); | 824 sendRequest(this.name, [parseResult], this.definition.parameters); |
| 819 }; | 825 }; |
| 820 | 826 |
| 827 apiFunctions["experimental.webRequest.addEventListener"].handleRequest = | |
| 828 function() { | |
| 829 var args = Array.prototype.slice.call(arguments); | |
| 830 sendRequest(this.name, args, this.definition.parameters, | |
| 831 {forIOThread: true}); | |
| 832 }; | |
| 833 | |
| 834 apiFunctions["experimental.webRequest.eventHandled"].handleRequest = | |
| 835 function() { | |
| 836 var args = Array.prototype.slice.call(arguments); | |
| 837 sendRequest(this.name, args, this.definition.parameters, | |
| 838 {forIOThread: true}); | |
| 839 }; | |
| 840 | |
| 821 apiFunctions["contextMenus.create"].customCallback = | 841 apiFunctions["contextMenus.create"].customCallback = |
| 822 function(name, request, response) { | 842 function(name, request, response) { |
| 823 if (chrome.extension.lastError) { | 843 if (chrome.extension.lastError) { |
| 824 return; | 844 return; |
| 825 } | 845 } |
| 826 | 846 |
| 827 var id = request.args[0].generatedId; | 847 var id = request.args[0].generatedId; |
| 828 | 848 |
| 829 // Set up the onclick handler if we were passed one in the request. | 849 // Set up the onclick handler if we were passed one in the request. |
| 830 var onclick = request.args.length ? request.args[0].onclick : null; | 850 var onclick = request.args.length ? request.args[0].onclick : null; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 907 | 927 |
| 908 if (!chrome.experimental) | 928 if (!chrome.experimental) |
| 909 chrome.experimental = {}; | 929 chrome.experimental = {}; |
| 910 | 930 |
| 911 if (!chrome.experimental.accessibility) | 931 if (!chrome.experimental.accessibility) |
| 912 chrome.experimental.accessibility = {}; | 932 chrome.experimental.accessibility = {}; |
| 913 | 933 |
| 914 if (!chrome.experimental.tts) | 934 if (!chrome.experimental.tts) |
| 915 chrome.experimental.tts = {}; | 935 chrome.experimental.tts = {}; |
| 916 })(); | 936 })(); |
| OLD | NEW |