Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 278 // if there is one. | 278 // if there is one. |
| 279 var id = arguments[0].menuItemId; | 279 var id = arguments[0].menuItemId; |
| 280 var onclick = chromeHidden.contextMenus.handlers[id]; | 280 var onclick = chromeHidden.contextMenus.handlers[id]; |
| 281 if (onclick) { | 281 if (onclick) { |
| 282 onclick.apply(null, arguments); | 282 onclick.apply(null, arguments); |
| 283 } | 283 } |
| 284 }); | 284 }); |
| 285 }; | 285 }; |
| 286 } | 286 } |
| 287 | 287 |
| 288 // Parses the xml syntax supported by omnibox suggestion results. Returns an | |
| 289 // object with two properties: 'description', which is just the text content, | |
| 290 // and 'descriptionStyles', which is an array of style objects in a format | |
| 291 // understood by the C++ backend. | |
| 292 function parseOmniboxDescription(input) { | |
| 293 var domParser = new DOMParser(); | |
| 294 | |
| 295 // The XML parser requires a single top-level element, but we want to | |
| 296 // support things like 'hello, <match>world</match>!'. So we wrap the | |
| 297 // provided text in generated root level element. | |
| 298 var root = domParser.parseFromString( | |
| 299 '<fragment>' + input + '</fragment>', 'text/xml'); | |
| 300 | |
| 301 // DOMParser has a terrible error reporting facility. Errors come out nested | |
| 302 // inside the returned document. | |
| 303 var error = root.querySelector('parsererror div'); | |
| 304 if (error) { | |
| 305 throw new Error(error.textContent); | |
| 306 } | |
| 307 | |
| 308 // Otherwise, it's valid, so build up the result. | |
| 309 var result = { | |
| 310 description: '', | |
| 311 descriptionStyles: [] | |
| 312 }; | |
| 313 | |
| 314 // Recursively walk the tree. | |
| 315 (function(node) { | |
| 316 for (var i = 0, child; child = node.childNodes[i]; i++) { | |
| 317 // Append text nodes to our description. | |
| 318 if (child.nodeType == Node.TEXT_NODE) { | |
| 319 result.description += child.nodeValue; | |
| 320 continue; | |
| 321 } | |
| 322 | |
| 323 // Process and descend into a subset of recognized tags. | |
| 324 if (child.nodeType == Node.ELEMENT_NODE && | |
| 325 (child.nodeName == 'dim' || child.nodeName == 'match' || | |
| 326 child.nodeName == 'url')) { | |
| 327 var style = { | |
| 328 'type': child.nodeName, | |
| 329 'offset': result.description.length | |
| 330 }; | |
| 331 result.descriptionStyles.push(style); | |
| 332 arguments.callee(child); | |
| 333 style.length = result.description.length - style.offset; | |
| 334 continue; | |
| 335 } | |
| 336 | |
| 337 // Descend into all other nodes, even if they are unrecognized, for | |
| 338 // forward compat. | |
| 339 arguments.callee(child); | |
| 340 } | |
| 341 })(root); | |
| 342 | |
| 343 return result; | |
| 344 } | |
| 345 | |
| 288 function setupOmniboxEvents(extensionId) { | 346 function setupOmniboxEvents(extensionId) { |
| 289 chrome.omnibox.onInputChanged.dispatch = | 347 chrome.omnibox.onInputChanged.dispatch = |
| 290 function(text, requestId) { | 348 function(text, requestId) { |
| 291 var suggestCallback = function(suggestions) { | 349 var suggestCallback = function(suggestions) { |
| 292 chrome.omnibox.sendSuggestions(requestId, suggestions); | 350 chrome.omnibox.sendSuggestions(requestId, suggestions); |
| 293 }; | 351 }; |
| 294 chrome.Event.prototype.dispatch.apply(this, [text, suggestCallback]); | 352 chrome.Event.prototype.dispatch.apply(this, [text, suggestCallback]); |
| 295 }; | 353 }; |
| 296 } | 354 } |
| 297 | 355 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 338 return; | 396 return; |
| 339 | 397 |
| 340 var apiFunction = {}; | 398 var apiFunction = {}; |
| 341 apiFunction.definition = functionDef; | 399 apiFunction.definition = functionDef; |
| 342 apiFunction.name = apiDef.namespace + "." + functionDef.name; | 400 apiFunction.name = apiDef.namespace + "." + functionDef.name; |
| 343 apiFunctions[apiFunction.name] = apiFunction; | 401 apiFunctions[apiFunction.name] = apiFunction; |
| 344 | 402 |
| 345 module[functionDef.name] = (function() { | 403 module[functionDef.name] = (function() { |
| 346 var args = arguments; | 404 var args = arguments; |
| 347 if (this.updateArguments) { | 405 if (this.updateArguments) { |
| 348 // Functions whose signature has changed can define an | |
| 349 // |updateArguments| function to transform old argument lists | |
| 350 // into the new form, preserving compatibility. | |
| 351 // TODO(skerner): Once optional args can be omitted (crbug/29215), | |
| 352 // this mechanism will become unnecessary. Consider removing it | |
| 353 // when crbug/29215 is fixed. | |
| 354 args = this.updateArguments.apply(this, args); | 406 args = this.updateArguments.apply(this, args); |
| 355 } | 407 } |
| 356 chromeHidden.validate(args, this.definition.parameters); | 408 chromeHidden.validate(args, this.definition.parameters); |
| 357 | 409 |
| 358 var retval; | 410 var retval; |
| 359 if (this.handleRequest) { | 411 if (this.handleRequest) { |
| 360 retval = this.handleRequest.apply(this, args); | 412 retval = this.handleRequest.apply(this, args); |
| 361 } else { | 413 } else { |
| 362 retval = sendRequest(this.name, args, | 414 retval = sendRequest(this.name, args, |
| 363 this.definition.parameters, | 415 this.definition.parameters, |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 633 apiFunctions["contextMenus.create"].handleRequest = | 685 apiFunctions["contextMenus.create"].handleRequest = |
| 634 function() { | 686 function() { |
| 635 var args = arguments; | 687 var args = arguments; |
| 636 var id = chromeHidden.contextMenus.nextId++; | 688 var id = chromeHidden.contextMenus.nextId++; |
| 637 args[0].generatedId = id; | 689 args[0].generatedId = id; |
| 638 sendRequest(this.name, args, this.definition.parameters, | 690 sendRequest(this.name, args, this.definition.parameters, |
| 639 this.customCallback); | 691 this.customCallback); |
| 640 return id; | 692 return id; |
| 641 }; | 693 }; |
| 642 | 694 |
| 695 apiFunctions["omnibox.setDefaultSuggestion"].handleRequest = | |
| 696 function(details) { | |
| 697 var parseResult = parseOmniboxDescription(details.description); | |
| 698 sendRequest(this.name, [parseResult], this.definition.parameters); | |
| 699 }; | |
| 700 | |
| 643 apiFunctions["contextMenus.create"].customCallback = | 701 apiFunctions["contextMenus.create"].customCallback = |
| 644 function(name, request, response) { | 702 function(name, request, response) { |
| 645 if (chrome.extension.lastError) { | 703 if (chrome.extension.lastError) { |
| 646 return; | 704 return; |
| 647 } | 705 } |
| 648 | 706 |
| 649 var id = request.args[0].generatedId; | 707 var id = request.args[0].generatedId; |
| 650 | 708 |
| 651 // Set up the onclick handler if we were passed one in the request. | 709 // Set up the onclick handler if we were passed one in the request. |
| 652 var onclick = request.args.length ? request.args[0].onclick : null; | 710 var onclick = request.args.length ? request.args[0].onclick : null; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 696 // the rest of the API. See crbug/29215 . | 754 // the rest of the API. See crbug/29215 . |
| 697 if (arguments.length == 2 && typeof(arguments[1]) == "function") { | 755 if (arguments.length == 2 && typeof(arguments[1]) == "function") { |
| 698 // If the old signature is used, add a null details object. | 756 // If the old signature is used, add a null details object. |
| 699 newArgs = [arguments[0], null, arguments[1]]; | 757 newArgs = [arguments[0], null, arguments[1]]; |
| 700 } else { | 758 } else { |
| 701 newArgs = arguments; | 759 newArgs = arguments; |
| 702 } | 760 } |
| 703 return newArgs; | 761 return newArgs; |
| 704 }; | 762 }; |
| 705 | 763 |
| 706 apiFunctions["omnibox.styleUrl"].handleRequest = function(offset, length) { | 764 apiFunctions["omnibox.sendSuggestions"].updateArguments = |
|
Matt Perry
2010/11/30 01:17:31
Will this validate against the incoming arguments,
| |
| 707 return {type: "url", offset: offset, length: length}; | 765 function(requestId, userSuggestions) { |
| 708 }; | 766 var suggestions = []; |
| 709 apiFunctions["omnibox.styleMatch"].handleRequest = | 767 for (var i = 0; i < userSuggestions.length; i++) { |
| 710 function(offset, length) { | 768 var parseResult = parseOmniboxDescription( |
| 711 return {type: "match", offset: offset, length: length}; | 769 userSuggestions[i].description); |
| 712 }; | 770 parseResult.content = userSuggestions[i].content; |
| 713 apiFunctions["omnibox.styleDim"].handleRequest = function(offset, length) { | 771 suggestions.push(parseResult); |
| 714 return {type: "dim", offset: offset, length: length}; | 772 } |
| 773 return [requestId, suggestions]; | |
| 715 }; | 774 }; |
| 716 | 775 |
| 717 if (chrome.test) { | 776 if (chrome.test) { |
| 718 chrome.test.getApiDefinitions = GetExtensionAPIDefinition; | 777 chrome.test.getApiDefinitions = GetExtensionAPIDefinition; |
| 719 } | 778 } |
| 720 | 779 |
| 721 setupPageActionEvents(extensionId); | 780 setupPageActionEvents(extensionId); |
| 722 setupToolstripEvents(GetRenderViewId()); | 781 setupToolstripEvents(GetRenderViewId()); |
| 723 setupPopupEvents(GetRenderViewId()); | 782 setupPopupEvents(GetRenderViewId()); |
| 724 setupHiddenContextMenuEvent(extensionId); | 783 setupHiddenContextMenuEvent(extensionId); |
| 725 setupOmniboxEvents(extensionId); | 784 setupOmniboxEvents(extensionId); |
| 726 }); | 785 }); |
| 727 | 786 |
| 728 if (!chrome.experimental) | 787 if (!chrome.experimental) |
| 729 chrome.experimental = {}; | 788 chrome.experimental = {}; |
| 730 | 789 |
| 731 if (!chrome.experimental.accessibility) | 790 if (!chrome.experimental.accessibility) |
| 732 chrome.experimental.accessibility = {}; | 791 chrome.experimental.accessibility = {}; |
| 733 | 792 |
| 734 if (!chrome.experimental.tts) | 793 if (!chrome.experimental.tts) |
| 735 chrome.experimental.tts = {}; | 794 chrome.experimental.tts = {}; |
| 736 })(); | 795 })(); |
| OLD | NEW |