session.js: correct parenthesization in 2 places
[conkeror/arlinius.git] / modules / webjump.js
blob3a416f81b594cdb4ce0410ba777cf5d95114bbab
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 var webjumps = {};
12 define_keywords("$completer", "$description", "$argument", "$alternative");
13 function define_webjump (key, handler) {
14     keywords(arguments);
15     var argument = arguments.$argument;
16     let alternative = arguments.$alternative;
18     // handler may be a function or a string.  An alternative url may
19     // be passed using the $alternative keyword; it is used in place
20     // of the handler when no arguments are supplied by the user when
21     // invoking the webjump (see get_webjump).  For string webjumps
22     // that contain %s and for which no alternative is provided, an
23     // alternative is autogenerated by trimming the path from the url.
24     // A webjump can thus function both as a way to invoke a search
25     // and as a bookmark.
26     //
27     // The argument property may be false (no arguments will be
28     // accepted for the webjump), true (arguments are required for the
29     // webjump) or 'optional' (arguments are accepted but not
30     // required).  If the property is not specified, a sensible default
31     // is chosen depending on the type of the handler and whether an
32     // alternative is specified.  If the property is false, then
33     // completing on the name of the webjump in the minibuffer will
34     // not result in a space being appended.
35     //
36     if (typeof(handler) == "function") {
37         if (argument == null && alternative == null)
38             argument = true;
39     } else if (typeof(handler) == "string") {
40         if (handler.indexOf('%s') == -1)
41             argument = false;
42         else if (alternative == null)
43             alternative = url_path_trim(handler);
44     }
45     if (alternative && argument == null)
46         argument = 'optional';
48     function make_handler (template) {
49         var b = template.indexOf('%s');
50         return function (arg) {
51             var a = b + 2;
52             // Just return the same string if it doesn't contain a %s
53             if (b == -1)
54                 return template;
55             return template.substr(0,b) + encodeURIComponent(arg) + template.substring(a);
56         };
57     }
59     if (typeof(handler) == "string")
60         handler = make_handler(handler);
62     webjumps[key] = { key: key,
63                       handler: handler,
64                       completer: arguments.$completer,
65                       description: arguments.$description,
66                       argument: argument,
67                       alternative: alternative};
70 function define_delicious_webjumps (username) {
71     define_webjump("delicious", "http://delicious.com/" + username + "/%s",
72                    $alternative = "http://delicious.com/" + username);
73     define_webjump("adelicious", "javascript:location.href='http://delicious.com/"+username+
74                    "?v=2&url='+encodeURIComponent(location.href)+'&title='+"+
75                    "encodeURIComponent(document.title);");
76     define_webjump("sdelicious", "http://delicious.com/search?p=%s&u="+username+
77                    "&chk=&context=userposts&fr=del_icio_us&lc=1");
78     define_webjump("sadelicious", "http://delicious.com/search/all?search=%s");
81 add_delicious_webjumps = define_delicious_webjumps;
83 function define_lastfm_webjumps (username) {
84     if (! username) username = "";
85     define_webjump("lastfm", "http://www.last.fm/user/"+username);
86     define_webjump("lastfm-user", "http://www.last.fm/user/%s");
87     define_webjump("lastfm-music", "http://www.last.fm/search?m=all&q=%s");
88     define_webjump("lastfm-group", "http://www.last.fm/users/groups?s_bio=%s");
89     define_webjump("lastfm-tag", "http://www.last.fm/search?m=tag&q=%s");
90     define_webjump("lastfm-label", "http://www.last.fm/search?m=label&q=%s");
91     define_webjump("lastfm-event", "http://www.last.fm/events?by=artists&q=%s");
94 add_lastfm_webjumps = define_lastfm_webjumps;
96 function clear_webjumps () {
97     webjumps = {};
100 // Some built in web jumps
101 function define_default_webjumps () {
102     define_webjump("conkerorwiki",
103                    "http://conkeror.org/?action=fullsearch&context=60&value=%s&fullsearch=Text");
104     define_webjump("lucky",      "http://www.google.com/search?q=%s&btnI=I'm Feeling Lucky");
105     define_webjump("maps",       "http://maps.google.com/?q=%s");
106     define_webjump("scholar",    "http://scholar.google.com/scholar?q=%s");
107     define_webjump("clusty",     "http://www.clusty.com/search?query=%s");
108     define_webjump("slang",      "http://www.urbandictionary.com/define.php?term=%s");
109     define_webjump("dictionary", "http://dictionary.reference.com/search?q=%s");
110     define_webjump("image",      "http://images.google.com/images?q=%s");
111     define_webjump("clhs",
112                    "http://www.xach.com/clhs?q=%s",
113                    $alternative = "http://www.lispworks.com/documentation/HyperSpec/Front/index.htm");
114     define_webjump("emacswiki",  "http://www.emacswiki.org/cgi-bin/wiki?search=%s");
115     define_webjump("cliki",      "http://www.cliki.net/admin/search?words=%s");
116     define_webjump("ratpoisonwiki", "http://ratpoison.antidesktop.net/?search=%s");
117     define_webjump("stumpwmwiki", "http://stumpwm.antidesktop.net/wiki?search=%s");
118     define_webjump("savannah",
119                    "http://savannah.gnu.org/search/?words=%s&type_of_search=soft&Search=Search&exact=1");
120     define_webjump("sourceforge", "http://sourceforge.net/search/?words=%s");
121     define_webjump("freshmeat", "http://freshmeat.net/search/?q=%s");
122     define_webjump("slashdot", "http://slashdot.org/search.pl?query=%s");
123     define_webjump("kuro5hin", "http://www.kuro5hin.org/?op=search&string=%s");
126 define_variable("webjump_partial_match", true,
127                 "When entering a url, if the input is not a webjump, " +
128                 "but would uniquely complete to a webjump, then accept " +
129                 "that webjump only if this is true.");
131 function match_webjump (str) {
132     var sp = str.indexOf(' ');
134     var key, arg;
135     if (sp == -1) {
136         key = str;
137         arg = null;
138     } else {
139         key = str.substring(0, sp);
140         arg = str.substring(sp + 1);
141         if (/^\s*$/.test(arg))
142             arg = null;
143     }
145     // Look for an exact match
146     var match = webjumps[key];
148     // Look for a partial match
149     if (!match && webjump_partial_match) {
150         for (let [k,v] in Iterator(webjumps)) {
151             if (k.substring(0, key.length) == key) {
152                 if (match) {
153                     // key is not a unique prefix, as there are multiple partial matches
154                     return null;
155                 }
156                 match = v;
157             }
158         }
159     }
161     if (match) {
162         if (arg == null && match.argument == true)
163             throw interactive_error('Webjump '+key+' requires an argument.');
164         return [match, key, arg];
165     }
166     return null;
170 function get_webjump (value) {
171     var res = match_webjump(value);
172     if (!res)
173         return null;
174     let [match,key,arg] = res;
175     if (arg == null && match.alternative)
176         return match.alternative;
177     return match.handler(arg);
180 function get_url_or_webjump (input) {
181     var url = get_webjump(input);
182     if (url != null)
183         return url;
184     else
185         return input;
188 define_default_webjumps();
190 function webjump_completer () {
191     let base_completer = prefix_completer(
192         $completions = [ v for ([k,v] in Iterator(webjumps)) ],
193         $get_string = function (x) { return x.key + (x.argument ? " " : ""); },
194         $get_description = function (x) { return x.description || ""; });
195     return function (input, pos, conservative) {
196         let str = input.substring(0,pos);
197         let res;
198         try { res = match_webjump(str); }
199         catch (e) { res = null; }
200         if (res) {
201             let [match, key, arg] = res;
202             if (arg != null) { // If there is no argument yet, we use the base completer
203                 if (match.completer) {
204                     let c = yield match.completer.call(null, arg, pos - key.length - 1, conservative);
205                     yield co_return(nest_completions(c, match.key + " "));
206                 }
207                 yield co_return(null);
208             }
209         }
210         yield co_return(base_completer(input, pos, conservative));
211     };