Fix zoom bindings to use characters rather than keycode names
[conkeror.git] / modules / webjump.js
blobe0db125705e3a03fc7c9abfa5807fef7d9ba5960
1 /**
2  * (C) Copyright 2004-2007 Shawn Betts
3  * (C) Copyright 2007-2008 John J. Foerch
4  * (C) Copyright 2007-2008 Jeremy Maitin-Shepard
5  *
6  * Use, modification, and distribution are subject to the terms specified in the
7  * COPYING file.
8 **/
10 //// web jump stuff
12 var webjumps = new string_hashmap();
14 define_keywords("$completer", "$description", "$no_argument");
15 function define_webjump(key, handler) {
16     keywords(arguments);
18     var no_argument = arguments.$no_argument;
20     if (typeof(handler) == "string") {
21         let template = handler;
22         let b = template.indexOf('%s');
23         if (b == -1)
24             no_argument = true;        
25         handler = function (arg) {
26             var a = b + 2;
27             // Just return the same string if it doesn't contain a %s
28             if (b == -1)
29                 return template;
30             else
31                 return template.substr(0,b) + encodeURIComponent(arg) + template.substring(a);
32         };
33     }
34     webjumps.put(key,
35                  {key: key,
36                   handler: handler, completer: arguments.$completer,
37                   description: arguments.$description,
38                   no_argument: no_argument});
41 // Compatibility
42 var add_webjump = define_webjump;
44 function add_delicious_webjumps (username)
46     add_webjump("delicious", " http://del.icio.us/" + username);
47     add_webjump("adelicious", "javascript:location.href='http://del.icio.us/" + username + "?v=2&url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title);");
48     add_webjump("sdelicious", " http://del.icio.us/search/?search=%s");
49     add_webjump("sadelicious", " http://del.icio.us/search/all?search=%s");
52 function clear_webjumps()
54     webjumps = {};
57 // Some built in web jumps
58 function define_default_webjumps()
60     add_webjump("conkerorwiki",
61                 "http://conkeror.org/?action=fullsearch&context=60&value=%s&fullsearch=Text");
62     add_webjump("lucky",      "http://www.google.com/search?q=%s&btnI=I'm Feeling Lucky");
63     add_webjump("maps",       "http://maps.google.com/?q=%s");
64     add_webjump("scholar",    "http://scholar.google.com/scholar?q=%s");
65     add_webjump("clusty",     "http://www.clusty.com/search?query=%s");
66     add_webjump("slang",      "http://www.urbandictionary.com/define.php?term=%s");
67     add_webjump("dictionary", "http://dictionary.reference.com/search?q=%s");
68     add_webjump("xulplanet",  "http://www.google.com/custom?q=%s&cof=S%3A"+
69                 "http%3A%2F%2Fwww.xulplanet.com%3BAH%3Aleft%3BLH%3A65%3BLC"+
70                 "%3A4682B4%3BL%3Ahttp%3A%2F%2Fwww.xulplanet.com%2Fimages%2F"+
71                 "xulplanet.png%3BALC%3Ablue%3BLW%3A215%3BAWFID%3A0979f384d5"+
72                 "181409%3B&domains=xulplanet.com&sitesearch=xulplanet.com&sa=Go");
73     add_webjump("image",      "http://images.google.com/images?q=%s");
74     add_webjump("clhs",       "http://www.xach.com/clhs?q=%s");
75     add_webjump("emacswiki",  "http://www.emacswiki.org/cgi-bin/wiki?search=%s");
76     add_webjump("cliki",      "http://www.cliki.net/admin/search?words=%s");
77     add_webjump("ratpoisonwiki", "http://ratpoison.antidesktop.net/?search=%s");
78     add_webjump("stumpwmwiki", "http://stumpwm.antidesktop.net/wiki?search=%s");
79     add_webjump("savannah", "http://savannah.gnu.org/search/?words=%s&type_of_search=soft&Search=Search&exact=1");
80     add_webjump("sourceforge", "http://sourceforge.net/search/?words=%s");
81     add_webjump("freshmeat", "http://freshmeat.net/search/?q=%s");
82     add_webjump("slashdot", "http://slashdot.org/search.pl?query=%s");
83     add_webjump("kuro5hin", "http://www.kuro5hin.org/?op=search&string=%s");
84     add_webjump("sheldonbrown",     "http://www.google.com/search?q=site:sheldonbrown.com %s");
85     add_webjump("youtube", "http://www.youtube.com/results?search_query=%s&search=Search");
88 function match_webjump(str) {
89     var sp = str.indexOf(' ');
91     var key, arg;
92     if (sp == -1) {
93         key = str;
94         arg = null;
95     } else {
96         key = str.substring(0, sp);
97         arg = str.substring(sp + 1);
98     }
100     // Look for an exact match
101     var match = webjumps.get(key);
103     // Look for a partial match
104     if (!match) {
105         for (let [k,v] in webjumps.iterator()) {
106             if (k.substring(0, key.length) == key) {
107                 if (match) {
108                     // key is not a unique prefix, as there are multiple partial matches
109                     return null;
110                 }
111                 match = v;
112             }
113         }
114     }
116     if (match) {
117         if (arg == null && !match.no_argument) {
118             throw interactive_error('Webjump '+key+' requires an argument.');
119         }
120         return [match, key, arg];
121     }
122     return null;
126 function getWebJump(value)
128     var res = match_webjump(value);
129     if (!res)
130         return null;
131     let [match,key,arg] = res;
132     return match.handler(arg);
135 function get_url_or_webjump(input)
137     var url = getWebJump(input);
139     if (url != null) {
140         return url;
141     } else {
142         return input;
143     }
146 define_default_webjumps();
148 function webjump_completer()
150     let base_completer = prefix_completer(
151         $completions = [ v for ([k,v] in webjumps.iterator()) ],
152         $get_string = function (x) x.key + (x.no_argument ? "" : " "),
153         $get_description = function (x) x.description || "");
155     return function(input, pos, conservative) {
156         let str = input.substring(0,pos);
157         let res;
158         try { res = match_webjump(str); }
159         catch (e) { res = null; }
160         if (res) {
161             let [match, key, arg] = res;
162             if (arg != null) { // If there is no argument yet, we use the base completer
163                 if (match.completer) {
164                     let c = yield match.completer.call(null, arg, pos - key.length - 1, conservative);
165                     yield co_return(nest_completions(c, match.key + " "));
166                 }
167                 yield co_return(null);
168             }
169         }
170         yield co_return(base_completer(input, pos, conservative));
171     }