Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6381)

Unified Diff: chrome/renderer/resources/extensions/searchbox_api.js

Issue 10809063: Adding Javascript support for the Extended Searchbox API. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Removing clear method. Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/common/render_messages.h ('k') | chrome/renderer/searchbox/searchbox.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/renderer/resources/extensions/searchbox_api.js
diff --git a/chrome/renderer/resources/extensions/searchbox_api.js b/chrome/renderer/resources/extensions/searchbox_api.js
index e7fc4e0f8c24e540ded492d17dbd170e6c95d86f..b3854dd0b929d3253eb573333fa3b30cf23d474b 100644
--- a/chrome/renderer/resources/extensions/searchbox_api.js
+++ b/chrome/renderer/resources/extensions/searchbox_api.js
@@ -7,7 +7,20 @@ if (!chrome)
chrome = {};
if (!chrome.searchBox) {
chrome.searchBox = new function() {
- native function GetValue();
+ // =========================================================================
+ // Constants
+ // =========================================================================
+
+ var MAX_CLIENT_SUGGESTIONS_TO_DEDUPE = 6;
+
+ var HTTP_REGEX = /^https?:\/\//;
+
+ var WWW_REGEX = /^www\./;
+
+ // =========================================================================
+ // Private functions
+ // =========================================================================
+ native function GetQuery();
native function GetVerbatim();
native function GetSelectionStart();
native function GetSelectionEnd();
@@ -15,8 +28,126 @@ if (!chrome.searchBox) {
native function GetY();
native function GetWidth();
native function GetHeight();
+ native function GetAutocompleteResults();
+ native function GetKeyCode();
native function SetSuggestions();
- this.__defineGetter__('value', GetValue);
+ native function SetQuerySuggestion();
+ native function SetQuerySuggestionFromAutocompleteResult();
+ native function SetQuery();
+ native function SetQueryFromAutocompleteResult();
+ native function SetPreviewHeight();
+
+ // Returns the |restrictedText| wrapped in a ShadowDOM.
+ function SafeWrap(restrictedText) {
+ var node = document.createElement('div');
+ var nodeShadow = new WebKitShadowRoot(node);
+ nodeShadow.applyAuthorStyles = true;
+ nodeShadow.innerHTML =
+ '<div style="width:700px!important;' +
+ ' height:22px!important;' +
+ ' font-family:\'Chrome Droid Sans\',\'Arial\'!important;' +
+ ' overflow:hidden!important;' +
+ ' text-overflow:ellipsis!important">' +
+ ' <nobr>' + restrictedText + '</nobr>' +
+ '</div>';
+ return node;
+ }
+
+ // Wraps the AutocompleteResult query and URL into ShadowDOM nodes so that
+ // the JS cannot access them and deletes the raw values.
+ function GetAutocompleteResultsWrapper() {
+ var autocompleteResults = DedupeAutcompleteResults(
+ GetAutocompleteResults());
+ var userInput = GetQuery();
+ for (var i = 0; i < autocompleteResults.length; ++i) {
+ var result = autocompleteResults[i];
+ var title = result.contents;
+ var url = CleanUrl(result.destination_url, userInput);
+ var combinedHtml = '<span class=chrome_url>' + url + '</span>';
+ if (title) {
+ result.titleNode = SafeWrap(title);
+ combinedHtml += '<span class=chrome_separator> &ndash; </span>' +
+ '<span class=chrome_title>' + title + '</span>';
+ }
+ result.urlNode = SafeWrap(url);
+ result.combinedNode = SafeWrap(combinedHtml);
+ delete result.contents;
+ delete result.destination_url;
+ }
+ return autocompleteResults;
+ }
+
+ function CleanUrl(url, userInput) {
+ if (url.indexOf(userInput) == 0) {
+ return url;
+ }
+ url = url.replace(HTTP_REGEX, '');
+ if (url.indexOf(userInput) == 0) {
+ return url;
+ }
+ return url.replace(WWW_REGEX, '');
+ }
+
+ function CanonicalizeUrl(url) {
+ return url.replace(HTTP_REGEX, '').replace(WWW_REGEX, '');
+ }
+
+ // Removes duplicates from AutocompleteResults.
+ // TODO(dcblack): Do this in C++ instead of JS.
+ function DedupeAutcompleteResults(autocompleteResults) {
+ var urlToResultMap = {};
+ for (var i = 0; i < autocompleteResults.length; ++i) {
+ var result = autocompleteResults[i];
+ var url = CanonicalizeUrl(result.destination_url);
+ if (url in urlToResultMap) {
+ var oldRelevance = urlToResultMap[url].rankingData.relevance;
+ var newRelevance = result.rankingData.relevance;
+ if (newRelevance > oldRelevance) {
+ urlToResultMap[url] = result;
+ }
+ } else {
+ urlToResultMap[url] = result;
+ }
+ }
+ var dedupedResults = [];
+ for (url in urlToResultMap) {
+ dedupedResults.push(urlToResultMap[url]);
+ }
+ return dedupedResults;
+ }
+
+ var lastPrefixQueriedForDuplicates = '';
+
+ function DedupeClientSuggestions(clientSuggestions) {
+ var userInput = GetQuery();
+ if (userInput == lastPrefixQueriedForDuplicates) {
+ // Request blocked for privacy reasons.
+ // TODO(dcblack): This check is insufficient. We should have a check
+ // such that it's only callable once per onnativesuggestions, not
+ // once per prefix.
+ return false;
+ }
+ lastPrefixQueriedForDuplicates = userInput;
+ var autocompleteResults = GetAutocompleteResults();
+ var nativeUrls = {};
+ for (var i = 0; i < autocompleteResults.length; ++i) {
+ var nativeUrl = CanonicalizeUrl(autocompleteResults[i].destination_url);
+ nativeUrls[nativeUrl] = autocompleteResults[i].rid;
+ }
+ for (var i = 0; i < clientSuggestions.length &&
+ i < MAX_CLIENT_SUGGESTIONS_TO_DEDUPE; ++i) {
+ var clientUrl = CanonicalizeUrl(clientSuggestions[i].url);
+ if (clientUrl in nativeUrls) {
+ clientSuggestions[i].duplicateOf = nativeUrls[clientUrl];
+ }
+ }
+ return true;
+ }
+
+ // =========================================================================
+ // Exported functions
+ // =========================================================================
+ this.__defineGetter__('value', GetQuery);
this.__defineGetter__('verbatim', GetVerbatim);
this.__defineGetter__('selectionStart', GetSelectionStart);
this.__defineGetter__('selectionEnd', GetSelectionEnd);
@@ -24,12 +155,34 @@ if (!chrome.searchBox) {
this.__defineGetter__('y', GetY);
this.__defineGetter__('width', GetWidth);
this.__defineGetter__('height', GetHeight);
+ this.__defineGetter__('nativeSuggestions', GetAutocompleteResultsWrapper);
+ this.__defineGetter__('keyCode', GetKeyCode);
this.setSuggestions = function(text) {
SetSuggestions(text);
};
+ this.setAutocompleteText = function(text, behavior) {
+ SetQuerySuggestion(text, behavior);
+ };
+ this.setRestrictedAutocompleteText = function(resultId, behavior) {
+ SetQuerySuggestionFromAutocompleteResult(resultId, behavior);
+ };
+ this.setValue = function(text, type) {
+ SetQuery(text, type);
+ };
+ this.setRestrictedValue = function(resultId, behavior) {
+ SetQueryFromAutocompleteResult(resultId, behavior);
+ };
+ this.setNonNativeDropdownHeight = function(height) {
+ SetPreviewHeight(height);
+ };
+ this.markDuplicateSuggestions = function(clientSuggestions) {
+ return DedupeClientSuggestions(clientSuggestions);
+ };
this.onchange = null;
this.onsubmit = null;
this.oncancel = null;
this.onresize = null;
+ this.onautocompleteresults = null;
+ this.onkeypress = null;
};
}
« no previous file with comments | « chrome/common/render_messages.h ('k') | chrome/renderer/searchbox/searchbox.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698