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

Side by Side Diff: chrome/common/extensions/docs/examples/api/omnibox/extension-docs/background.html

Issue 5638002: Updating omnibox sample to use new XML formatting method. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Regen docs before submit Created 10 years 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 <!DOCTYPE html> 1 <!DOCTYPE html>
2 <!-- 2 <!--
3 * Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this 3 * Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this
4 * source code is governed by a BSD-style license that can be found in the 4 * source code is governed by a BSD-style license that can be found in the
5 * LICENSE file. 5 * LICENSE file.
6 --> 6 -->
7 <html> 7 <html>
8 <head> 8 <head>
9 </head> 9 </head>
10 <body> 10 <body>
(...skipping 24 matching lines...) Expand all
35 * Adds an entry to the index. 35 * Adds an entry to the index.
36 * @param {String} name Name of the function (e.g. chrome.tabs.get). 36 * @param {String} name Name of the function (e.g. chrome.tabs.get).
37 * @param {String} url Url to the documentation. 37 * @param {String} url Url to the documentation.
38 * @param {String} desc Description (optional). 38 * @param {String} desc Description (optional).
39 * @param {String} type The type of entry (e.g. method, event). 39 * @param {String} type The type of entry (e.g. method, event).
40 */ 40 */
41 APISearchCorpus.prototype.addEntry = function(name, url, desc, type) { 41 APISearchCorpus.prototype.addEntry = function(name, url, desc, type) {
42 this.corpus_.push({ 42 this.corpus_.push({
43 'name' : name, 43 'name' : name,
44 'url' : url, 44 'url' : url,
45 'ranges' : [], 45 'style' : name,
46 'description' : desc, 46 'description' : desc,
47 'type' : type 47 'type' : type
48 }); 48 });
49 }; 49 };
50 50
51 /** 51 /**
52 * Locates a match from the supplied keywords against text. 52 * Locates a match from the supplied keywords against text.
53 * 53 *
54 * Keywords are matched in the order supplied, and a non-overlapping 54 * Keywords are matched in the order supplied, and a non-overlapping
55 * search is used. The ranges are returned in a way that is easily 55 * search is used. The matches are returned in a styled string that
56 * converted to the style array required by the omnibox API. 56 * can be passed directly to the omnibox API.
57 * 57 *
58 * @param {Array.<String>} keywords A list of keywords to check. 58 * @param {Array.<String>} keywords A list of keywords to check.
59 * @param {String} name The name to search against. 59 * @param {String} name The name to search against.
60 * @returns {Array.<Array.<number>>|null} A list of indexes corresponding 60 * @returns {String|null} A string containing &lt;match&gt; markup
61 * to matches, or null if no match was found. 61 * corresponding to the matched text, or null if no match was found.
62 */ 62 */
63 APISearchCorpus.prototype.findMatch_ = function(keywords, name) { 63 APISearchCorpus.prototype.findMatch_ = function(keywords, name) {
64 var ranges = []; 64 var style = [];
65 var indexFrom = 0; 65 var indexFrom = 0;
66 var lowerName = name.toLowerCase();
66 for (var i = 0; i < keywords.length; i++) { 67 for (var i = 0; i < keywords.length; i++) {
67 var keyword = keywords[i].toLowerCase(); 68 var keyword = keywords[i].toLowerCase();
68 var start = name.indexOf(keyword, indexFrom); 69 var start = lowerName.indexOf(keyword, indexFrom);
69 if (start == -1) { 70 if (start == -1) {
70 return null; 71 return null;
71 } 72 }
72 var end = start + keyword.length; 73 var end = start + keyword.length + 1;
73 ranges.push([start, end]); 74
74 indexFrom = end + 1; 75 style.push(name.substring(indexFrom, start))
76 style.push('<match>');
77 style.push(name.substring(start, end));
78 style.push('</match>');
79
80 indexFrom = end;
75 } 81 }
76 return ranges; 82 style.push(name.substring(indexFrom));
83 return style.join('');
77 }; 84 };
78 85
79 /** 86 /**
80 * Searches this corpus for the supplied text. 87 * Searches this corpus for the supplied text.
81 * @param {String} text Query text. 88 * @param {String} text Query text.
82 * @param {Number} limit Max results to return. 89 * @param {Number} limit Max results to return.
83 * @returns {Array.<Object>} A list of entries corresponding with 90 * @returns {Array.<Object>} A list of entries corresponding with
84 * matches (@see APISearchCorpus.findMatch_ for keyword search 91 * matches (@see APISearchCorpus.findMatch_ for keyword search
85 * algorithm. Results are returned in a sorted order, first by 92 * algorithm. Results are returned in a sorted order, first by
86 * length, then alphabetically by name. An exact match will be 93 * length, then alphabetically by name. An exact match will be
87 * returned first. 94 * returned first.
88 */ 95 */
89 APISearchCorpus.prototype.search = function(text, limit) { 96 APISearchCorpus.prototype.search = function(text, limit) {
90 var results = []; 97 var results = [];
91 var match = null; 98 var match = null;
92 if (!text || text.length == 0) { 99 if (!text || text.length == 0) {
93 return this.corpus_.slice(0, limit); // No text, start listing APIs. 100 return this.corpus_.slice(0, limit); // No text, start listing APIs.
94 } 101 }
95 var searchText = text.toLowerCase(); 102 var searchText = text.toLowerCase();
96 var keywords = searchText.split(' '); 103 var keywords = searchText.split(' ');
97 for (var i = 0; i < this.corpus_.length; i++) { 104 for (var i = 0; i < this.corpus_.length; i++) {
98 var name = this.corpus_[i]['name'].toLowerCase(); 105 var name = this.corpus_[i]['name'];
99 if (results.length < limit) { 106 if (results.length < limit) {
100 var result = this.findMatch_(keywords, name); 107 var result = this.findMatch_(keywords, name);
101 if (result) { 108 if (result) {
102 this.corpus_[i]['ranges'] = result; 109 this.corpus_[i]['style'] = result;
103 results.push(this.corpus_[i]); 110 results.push(this.corpus_[i]);
104 } 111 }
105 } 112 }
106 if (!match && searchText == name) { 113 if (!match && searchText == name) {
107 match = this.corpus_[i]; // An exact match. 114 match = this.corpus_[i]; // An exact match.
108 } 115 }
109 if (match && results.length >= limit) { 116 if (match && results.length >= limit) {
110 break; // Have an exact match and have reached the search limit. 117 break; // Have an exact match and have reached the search limit.
111 } 118 }
112 } 119 }
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 this.onChanged_.bind(this)); 312 this.onChanged_.bind(this));
306 chrome.omnibox.onInputEntered.addListener( 313 chrome.omnibox.onInputEntered.addListener(
307 this.onEntered_.bind(this)); 314 this.onEntered_.bind(this));
308 }; 315 };
309 316
310 /** 317 /**
311 * Converts a corpus match to an object suitable for the omnibox API. 318 * Converts a corpus match to an object suitable for the omnibox API.
312 * @param {Object} match The match to convert. 319 * @param {Object} match The match to convert.
313 * @returns {Object} A suggestion object formatted for the omnibox API. 320 * @returns {Object} A suggestion object formatted for the omnibox API.
314 */ 321 */
315 OmniboxManager.prototype.matchToSuggestion_ = function(match) { 322 OmniboxManager.prototype.convertMatchToSuggestion_ = function(match) {
316 var styles = [ ]; 323 var suggestion = [ match['style'] ];
317 var ranges = match['ranges'];
318 var desc = match['name'];
319 var name = match['name'];
320 var lastIndex = 0;
321 for (var i = 0; i < ranges.length; i++) {
322 styles.push(chrome.omnibox.styleMatch(ranges[i][0]));
323 styles.push(chrome.omnibox.styleNone(ranges[i][1]));
324 lastIndex = ranges[i][1];
325 }
326
327 if (match['type']) { 324 if (match['type']) {
328 // Abusing the URL style a little, but want this to stand out. 325 // Abusing the URL style a little, but want this to stand out.
329 desc = this.pushStyle_(styles, 'Url', desc, match['type']); 326 suggestion.push(['<url>', match['type'], '</url>'].join(''));
330 lastIndex = desc.length;
331 } 327 }
332 if (match['description']) { 328 if (match['description']) {
333 desc = this.pushStyle_(styles, 'Dim', desc, match['description']); 329 suggestion.push(['<dim>', match['description'], '</dim>'].join(''));
334 lastIndex = desc.length;
335 } 330 }
336
337 if (lastIndex == desc.length) styles.pop();
338
339 return { 331 return {
340 'content' : name, 332 'content' : match['name'],
341 'description' : desc, 333 'description' : suggestion.join(' - ')
342 'descriptionStyles' : styles 334 }
343 };
344 }; 335 };
345 336
346 /** 337 /**
347 * Suggests a list of possible matches when omnibox text changes. 338 * Suggests a list of possible matches when omnibox text changes.
348 * @param {String} text Text input from the omnibox. 339 * @param {String} text Text input from the omnibox.
349 * @param {Function} suggest Callback to execute with a list of 340 * @param {Function} suggest Callback to execute with a list of
350 * suggestion objects, if any matches were found. 341 * suggestion objects, if any matches were found.
351 */ 342 */
352 OmniboxManager.prototype.onChanged_ = function(text, suggest) { 343 OmniboxManager.prototype.onChanged_ = function(text, suggest) {
353 var matches = this.corpus_.search(text, 10); 344 var matches = this.corpus_.search(text, 10);
354 var suggestions = []; 345 var suggestions = [];
355 for (var i = 0; i < matches.length; i++) { 346 for (var i = 0; i < matches.length; i++) {
356 var suggestion = this.matchToSuggestion_(matches[i]); 347 var suggestion = this.convertMatchToSuggestion_(matches[i]);
357 suggestions.push(suggestion); 348 suggestions.push(suggestion);
358 } 349 }
359 suggest(suggestions); 350 suggest(suggestions);
360 }; 351 };
361 352
362 /** 353 /**
363 * Opens the most appropriate URL when enter is pressed in the omnibox. 354 * Opens the most appropriate URL when enter is pressed in the omnibox.
364 * 355 *
365 * Note that the entered text does not have to be exact - the first 356 * Note that the entered text does not have to be exact - the first
366 * search result is automatically opened when enter is pressed. 357 * search result is automatically opened when enter is pressed.
367 * 358 *
368 * @param {String} text The text entered. 359 * @param {String} text The text entered.
369 */ 360 */
370 OmniboxManager.prototype.onEntered_ = function(text) { 361 OmniboxManager.prototype.onEntered_ = function(text) {
371 var matches = this.corpus_.search(text, 1); 362 var matches = this.corpus_.search(text, 1);
372 if (matches.length > 0) { 363 if (matches.length > 0) {
373 this.tabManager_.open(matches[0]['url']); 364 this.tabManager_.open(matches[0]['url']);
374 } 365 }
375 }; 366 };
376 367
377 /**
378 * Helper function for constructing a suggestion style list.
379 *
380 * Adds a separator and text to a description, and modifies an array
381 * of styles so that the separator is not styled and the additional text
382 * obtains the requested style type.
383 *
384 * This method expects the list of styles to end with a styleNone style.
385 * It will modify the list so that the last element is a styleNone style.
386 * The last element will always be at the end of the returned string,
387 * which will throw an error unless it is removed before being passed
388 * to the API (this method is intended to be called a few times in a row).
389 * @see OmniboxManager.matchToSuggestion_ for code that removes this last
390 * entry.
391 *
392 * @param {Array.<Object>} styles An array of styles, in the format
393 * expected by the omnibox API.
394 * @param {String} type The style type to apply - must be one of
395 * "Dim", "Match", "None", and "Url".
396 * @param {String} desc The description text to append to and style.
397 * @param {String} text The text to append to the description.
398 * @returns {String} The description plus a separator and the supplied
399 * text, intended to overwrite the variable which was passed into
400 * this function as "desc".
401 */
402 OmniboxManager.prototype.pushStyle_ = function(styles, type, desc, text) {
403 desc += this.SEPARATOR;
404 styles.push(chrome.omnibox['style' + type](desc.length));
405 desc += text;
406 styles.push(chrome.omnibox.styleNone(desc.length));
407 return desc;
408 };
409
410 ////////////////////////////////////////////////////////////////////////// 368 //////////////////////////////////////////////////////////////////////////
411 369
412 /** 370 /**
413 * Manages opening urls in tabs. 371 * Manages opening urls in tabs.
414 * @constructor 372 * @constructor
415 */ 373 */
416 function TabManager() { 374 function TabManager() {
417 this.tab_ = null; 375 this.tab_ = null;
418 chrome.tabs.onRemoved.addListener(this.onRemoved_.bind(this)); 376 chrome.tabs.onRemoved.addListener(this.onRemoved_.bind(this));
419 }; 377 };
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 ////////////////////////////////////////////////////////////////////////// 415 //////////////////////////////////////////////////////////////////////////
458 416
459 var corpus = new APISearchCorpus(); 417 var corpus = new APISearchCorpus();
460 var docsManager = new DocsManager(corpus); 418 var docsManager = new DocsManager(corpus);
461 docsManager.fetch(); 419 docsManager.fetch();
462 var tabManager = new TabManager(); 420 var tabManager = new TabManager();
463 var omnibox = new OmniboxManager(corpus, tabManager); 421 var omnibox = new OmniboxManager(corpus, tabManager);
464 </script> 422 </script>
465 </body> 423 </body>
466 </html> 424 </html>
OLDNEW
« no previous file with comments | « chrome/common/extensions/docs/examples/api/omnibox/extension-docs.zip ('k') | chrome/common/extensions/docs/samples.json » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698