- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / common / extensions / docs / examples / extensions / chrome_search / background.js
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
3 // found in the LICENSE file.
4
5 var currentRequest = null;
6
7 chrome.omnibox.onInputChanged.addListener(
8   function(text, suggest) {
9     if (currentRequest != null) {
10       currentRequest.onreadystatechange = null;
11       currentRequest.abort();
12       currentRequest = null;
13     }
14
15     updateDefaultSuggestion(text);
16     if (text == '' || text == 'halp')
17       return;
18
19     currentRequest = search(text, function(xml) {
20       var results = [];
21       var entries = xml.getElementsByTagName("entry");
22
23       for (var i = 0, entry; i < 5 && (entry = entries[i]); i++) {
24         var path = entry.getElementsByTagName("file")[0].getAttribute("name");
25         var line =
26             entry.getElementsByTagName("match")[0].getAttribute("lineNumber");
27         var file = path.split("/").pop();
28
29         var description = '<url>' + file + '</url>';
30         if (/^file:/.test(text)) {
31           description += ' <dim>' + path + '</dim>';
32         } else {
33           var content = entry.getElementsByTagName("content")[0].textContent;
34
35           // There can be multiple lines. Kill all the ones except the one that
36           // contains the first match. We can ocassionally fail to find a single
37           // line that matches, so we still handle multiple lines below.
38           var matches = content.split(/\n/);
39           for (var j = 0, match; match = matches[j]; j++) {
40             if (match.indexOf('<b>') > -1) {
41               content = match;
42               break;
43             }
44           }
45
46           // Replace any extraneous whitespace to make it look nicer.
47           content = content.replace(/[\n\t]/g, ' ');
48           content = content.replace(/ {2,}/g, ' ');
49
50           // Codesearch wraps the result in <pre> tags. Remove those if they're
51           // still there.
52           content = content.replace(/<\/?pre>/g, '');
53
54           // Codesearch highlights the matches with 'b' tags. Replaces those
55           // with 'match'.
56           content = content.replace(/<(\/)?b>/g, '<$1match>');
57
58           description += ' ' + content;
59         }
60
61         results.push({
62           content: path + '@' + line,
63           description: description
64         });
65       }
66
67       suggest(results);
68     });
69   }
70 );
71
72 function resetDefaultSuggestion() {
73   chrome.omnibox.setDefaultSuggestion({
74     description: '<url><match>src:</match></url> Search Chromium source'
75   });
76 }
77
78 resetDefaultSuggestion();
79
80 function updateDefaultSuggestion(text) {
81   var isRegex = /^re:/.test(text);
82   var isFile = /^file:/.test(text);
83   var isHalp = (text == 'halp');
84   var isPlaintext = text.length && !isRegex && !isFile && !isHalp;
85
86   var description = '<match><url>src</url></match><dim> [</dim>';
87   description +=
88       isPlaintext ? ('<match>' + text + '</match>') : 'plaintext-search';
89   description += '<dim> | </dim>';
90   description += isRegex ? ('<match>' + text + '</match>') : 're:regex-search';
91   description += '<dim> | </dim>';
92   description += isFile ? ('<match>' + text + '</match>') : 'file:filename';
93   description += '<dim> | </dim>';
94   description += isHalp ? '<match>halp</match>' : 'halp';
95   description += '<dim> ]</dim>';
96
97   chrome.omnibox.setDefaultSuggestion({
98     description: description
99   });
100 }
101
102 chrome.omnibox.onInputStarted.addListener(function() {
103   updateDefaultSuggestion('');
104 });
105
106 chrome.omnibox.onInputCancelled.addListener(function() {
107   resetDefaultSuggestion();
108 });
109
110 function search(query, callback) {
111   if (query == 'halp')
112     return;
113
114   if (/^re:/.test(query))
115     query = query.substring('re:'.length);
116   else if (/^file:/.test(query))
117     query = 'file:"' + query.substring('file:'.length) + '"';
118   else
119     query = '"' + query + '"';
120
121   var url = "https://code.google.com/p/chromium/codesearch#search/&type=cs&q=" + query +
122       "&exact_package=chromium&type=cs";
123   var req = new XMLHttpRequest();
124   req.open("GET", url, true);
125   req.setRequestHeader("GData-Version", "2");
126   req.onreadystatechange = function() {
127     if (req.readyState == 4) {
128       callback(req.responseXML);
129     }
130   }
131   req.send(null);
132   return req;
133 }
134
135 function getUrl(path, line) {
136   var url = "https://code.google.com/p/chromium/codesearch#" + path
137       "&sq=package:chromium";
138   if (line)
139     url += "&l=" + line;
140   return url;
141 }
142
143 function getEntryUrl(entry) {
144   return getUrl(
145       entry.getElementsByTagName("file")[0].getAttribute("name"),
146       entry.getElementsByTagName("match")[0].getAttribute("lineNumber"));
147   return url;
148 }
149
150 function navigate(url) {
151   chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
152     chrome.tabs.update(tabs[0].id, {url: url});
153   });
154 }
155
156 chrome.omnibox.onInputEntered.addListener(function(text) {
157   // TODO(aa): We need a way to pass arbitrary data through. Maybe that is just
158   // URL?
159   if (/@\d+\b/.test(text)) {
160     var chunks = text.split('@');
161     var path = chunks[0];
162     var line = chunks[1];
163     navigate(getUrl(path, line));
164   } else if (text == 'halp') {
165     // TODO(aa)
166   } else {
167     navigate("https://code.google.com/p/chromium/codesearch#search/&type=cs" +
168              "&q=" + text +
169              "&exact_package=chromium&type=cs");
170   }
171 });