OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // Custom bindings for the extension API. | 5 // Custom bindings for the extension API. |
6 | 6 |
7 var extensionNatives = requireNative('extension'); | 7 var extensionNatives = requireNative('extension'); |
8 var GetExtensionViews = extensionNatives.GetExtensionViews; | 8 var GetExtensionViews = extensionNatives.GetExtensionViews; |
9 var OpenChannelToExtension = extensionNatives.OpenChannelToExtension; | 9 var OpenChannelToExtension = extensionNatives.OpenChannelToExtension; |
10 | 10 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
45 return GetExtensionViews(windowId, 'TAB'); | 45 return GetExtensionViews(windowId, 'TAB'); |
46 }); | 46 }); |
47 | 47 |
48 apiFunctions.setHandleRequest('getURL', function(path) { | 48 apiFunctions.setHandleRequest('getURL', function(path) { |
49 path = String(path); | 49 path = String(path); |
50 if (!path.length || path[0] != '/') | 50 if (!path.length || path[0] != '/') |
51 path = '/' + path; | 51 path = '/' + path; |
52 return 'chrome-extension://' + extensionId + path; | 52 return 'chrome-extension://' + extensionId + path; |
53 }); | 53 }); |
54 | 54 |
55 apiFunctions.setUpdateArgumentsPreValidate('sendRequest', function() { | 55 function sendMessageUpdateArguments() { |
56 // Align missing (optional) function arguments with the arguments that | 56 // Align missing (optional) function arguments with the arguments that |
57 // schema validation is expecting, e.g. | 57 // schema validation is expecting, e.g. |
58 // extension.sendRequest(req) -> extension.sendRequest(null, req) | 58 // extension.sendRequest(req) -> extension.sendRequest(null, req) |
59 // extension.sendRequest(req, cb) -> extension.sendRequest(null, req, cb) | 59 // extension.sendRequest(req, cb) -> extension.sendRequest(null, req, cb) |
60 var lastArg = arguments.length - 1; | 60 var lastArg = arguments.length - 1; |
61 | 61 |
62 // responseCallback (last argument) is optional. | 62 // responseCallback (last argument) is optional. |
63 var responseCallback = null; | 63 var responseCallback = null; |
64 if (typeof(arguments[lastArg]) == 'function') | 64 if (typeof(arguments[lastArg]) == 'function') |
65 responseCallback = arguments[lastArg--]; | 65 responseCallback = arguments[lastArg--]; |
66 | 66 |
67 // request (second argument) is required. | 67 // request (second argument) is required. |
68 var request = arguments[lastArg--]; | 68 var request = arguments[lastArg--]; |
69 | 69 |
70 // targetId (first argument, extensionId in the manfiest) is optional. | 70 // targetId (first argument, extensionId in the manfiest) is optional. |
71 var targetId = null; | 71 var targetId = null; |
72 if (lastArg >= 0) | 72 if (lastArg >= 0) |
73 targetId = arguments[lastArg--]; | 73 targetId = arguments[lastArg--]; |
74 | 74 |
75 if (lastArg != -1) | 75 if (lastArg != -1) |
76 throw new Error('Invalid arguments to sendRequest.'); | 76 throw new Error('Invalid arguments to sendMessage.'); |
77 return [targetId, request, responseCallback]; | 77 return [targetId, request, responseCallback]; |
78 }); | 78 } |
79 apiFunctions.setUpdateArgumentsPreValidate('sendRequest', | |
80 sendMessageUpdateArguments); | |
81 apiFunctions.setUpdateArgumentsPreValidate('sendMessage', | |
82 sendMessageUpdateArguments); | |
79 | 83 |
80 apiFunctions.setHandleRequest('sendRequest', | 84 function sendMessageImpl(portName, targetId, request, responseCallback) { |
81 function(targetId, request, responseCallback) { | |
82 if (!targetId) | 85 if (!targetId) |
83 targetId = extensionId; | 86 targetId = extensionId; |
87 var port = chrome.extension.connect(targetId, {name: portName}); | |
88 port.postMessage(request); | |
89 | |
90 // TODO(mpcomplete): the rest is duplicated with tabs.sendRequest. See | |
91 // tabs_custom_bindings.js. Find a way to combine them. | |
92 if (portName == chromeHidden.kMessageChannel && !responseCallback) { | |
Matt Perry
2012/03/30 04:34:56
It might be safe to do this for sendRequest as wel
| |
93 // Go ahead and disconnect immediately if the sender is not expecting | |
94 // a response. | |
95 port.disconnect(); | |
96 return; | |
97 } | |
98 | |
84 if (!responseCallback) | 99 if (!responseCallback) |
85 responseCallback = function() {}; | 100 responseCallback = function() {}; |
86 | 101 |
87 var connectInfo = { name: chromeHidden.kRequestChannel }; | |
88 var port = chrome.extension.connect(targetId, connectInfo); | |
89 | |
90 port.postMessage(request); | |
91 port.onDisconnect.addListener(function() { | 102 port.onDisconnect.addListener(function() { |
92 // For onDisconnects, we only notify the callback if there was an error | 103 // For onDisconnects, we only notify the callback if there was an error |
93 try { | 104 try { |
94 if (chrome.extension.lastError) | 105 if (chrome.extension.lastError) |
95 responseCallback(); | 106 responseCallback(); |
96 } finally { | 107 } finally { |
97 port = null; | 108 port = null; |
98 } | 109 } |
99 }); | 110 }); |
100 port.onMessage.addListener(function(response) { | 111 port.onMessage.addListener(function(response) { |
101 try { | 112 try { |
102 responseCallback(response); | 113 responseCallback(response); |
103 } finally { | 114 } finally { |
104 port.disconnect(); | 115 port.disconnect(); |
105 port = null; | 116 port = null; |
106 } | 117 } |
107 }); | 118 }); |
119 } | |
120 | |
121 apiFunctions.setHandleRequest('sendRequest', | |
122 function(targetId, request, responseCallback) { | |
123 sendMessageImpl(chromeHidden.kRequestChannel, | |
124 targetId, request, responseCallback); | |
125 }); | |
126 | |
127 apiFunctions.setHandleRequest('sendMessage', | |
128 function(targetId, message, responseCallback) { | |
129 sendMessageImpl(chromeHidden.kMessageChannel, | |
130 targetId, message, responseCallback); | |
108 }); | 131 }); |
109 | 132 |
110 apiFunctions.setUpdateArgumentsPreValidate('connect', function() { | 133 apiFunctions.setUpdateArgumentsPreValidate('connect', function() { |
111 // Align missing (optional) function arguments with the arguments that | 134 // Align missing (optional) function arguments with the arguments that |
112 // schema validation is expecting, e.g. | 135 // schema validation is expecting, e.g. |
113 // extension.connect() -> extension.connect(null, null) | 136 // extension.connect() -> extension.connect(null, null) |
114 // extension.connect({}) -> extension.connect(null, {}) | 137 // extension.connect({}) -> extension.connect(null, {}) |
115 var nextArg = 0; | 138 var nextArg = 0; |
116 | 139 |
117 // targetId (first argument) is optional. | 140 // targetId (first argument) is optional. |
(...skipping 17 matching lines...) Expand all Loading... | |
135 var name = ''; | 158 var name = ''; |
136 if (connectInfo && connectInfo.name) | 159 if (connectInfo && connectInfo.name) |
137 name = connectInfo.name; | 160 name = connectInfo.name; |
138 | 161 |
139 var portId = OpenChannelToExtension(extensionId, targetId, name); | 162 var portId = OpenChannelToExtension(extensionId, targetId, name); |
140 if (portId >= 0) | 163 if (portId >= 0) |
141 return chromeHidden.Port.createPort(portId, name); | 164 return chromeHidden.Port.createPort(portId, name); |
142 throw new Error('Error connecting to extension ' + targetId); | 165 throw new Error('Error connecting to extension ' + targetId); |
143 }); | 166 }); |
144 }); | 167 }); |
OLD | NEW |