Add initial OpenSearch search engine support
[conkeror.git] / modules / window.js
blob1f83a9cedb65a22a0ea5ccbe4d16d935c1dc7b8c
1 require("mode.js");
3 var define_window_local_hook = simple_local_hook_definer();
6 define_hook("make_window_hook");
8 var window_watcher = Cc["@mozilla.org/embedcomp/window-watcher;1"].getService(Ci.nsIWindowWatcher);
10 function generate_new_window_tag(tag)
12     var existing = [];
13     var exact_match = false;
14     var en = window_watcher.getWindowEnumerator ();
15     if (tag == '') { tag = null; }
16     var re;
17     if (tag) {
18         re = new RegExp ("^" + tag + "<(\\d+)>$");
19     } else {
20         re = new RegExp ("^(\\d+)$");
21     }
22     while (en.hasMoreElements ()) {
23         var w = en.getNext().QueryInterface (Ci.nsIDOMWindow);
24         if ('tag' in w)  {
25             if (tag && w.tag == tag) {
26                 exact_match = true;
27                 continue;
28             }
29             var re_result = re.exec (w.tag);
30             if (re_result)
31                 existing.push (re_result[1]);
32         }
33     }
34     if (tag && ! exact_match)
35         return tag;
37     existing.sort (function (a, b) { return a - b; });
39     var n = 1;
40     for (var i = 0; i < existing.length; i++) {
41         if (existing[i] < n) continue;
42         if (existing[i] == n) { n++; continue; }
43         break;
44     }
45     if (tag) {
46         return tag + "<" + n + ">";
47     } else {
48         return n;
49     }
52 function make_chrome_window(chrome_URI, args)
54     return window_watcher.openWindow(null, chrome_URI, "_blank",
55                                      "chrome,dialog=no,all,resizable", args);
58 var conkeror_chrome_URI = "chrome://conkeror/content/conkeror.xul";
60 function make_window(initial_buffer_creator, tag)
62     var args = { tag: tag,
63                  initial_buffer_creator: initial_buffer_creator };
64     var result = make_chrome_window(conkeror_chrome_URI, null);
65     result.args = args;
66     make_window_hook.run(result);
67     return result;
70 function get_window_by_tag(tag)
72     var en = window_watcher.getWindowEnumerator ();
73     while (en.hasMoreElements ()) {
74         var w = en.getNext().QueryInterface (Ci.nsIDOMWindow);
75         if ('tag' in w && w.tag == tag)
76             return w;
77     }
78     return null;
81 /* FIXME: decide if this should include not-fully-initialized windows  */
82 function for_each_window(func)
84     var en = window_watcher.getWindowEnumerator ();
85     while (en.hasMoreElements ()) {
86         var w = en.getNext().QueryInterface (Ci.nsIDOMWindow);
87         if ('conkeror' in w)
88             func(w);
89     }
92 function get_recent_conkeror_window()
94     var window = window_watcher.activeWindow;
95     if (window && ("conkeror" in window))
96         return window;
97     var en = window_watcher.getWindowEnumerator ();
98     while (en.hasMoreElements ()) {
99         window = en.getNext().QueryInterface (Ci.nsIDOMWindow);
100         if ('conkeror' in window)
101             return window;
102     }
103     return null;
106 define_window_local_hook("window_initialize_early_hook");
107 define_window_local_hook("window_initialize_hook");
108 define_window_local_hook("window_initialize_late_hook");
110 var window_extra_argument_list = [];
112 define_variable("window_extra_argument_max_delay", 100);
114 function window_setup_args(window) {
115     if (window.args != null)
116         return;
118     var cur_time = Date.now();
119     var i;
120     var result = null;
121     for (i = 0; i < window_extra_argument_list.length; ++i) {
122         var a = window_extra_argument_list[i];
123         if (a.time > cur_time - window_extra_argument_max_delay) {
124             delete a.time;
125             result = a;
126             i++;
127             break;
128         }
129     }
130     window_extra_argument_list = window_extra_argument_list.slice(i);
132     if (result == null)
133         window.args = {};
134     else
135         window.args = result;
138 function window_set_extra_arguments(args) {
139     args.time = Date.now();
140     window_extra_argument_list.push(args);
143 function window_get_this_browser() {
144     return this.buffers.current.browser;
147 function window_initialize(window)
149     window.conkeror = conkeror;
151     // Used by get_window_from_frame to get an unwrapped window reference
152     window.escape_wrapper = function (x) { x(window); }
154     window_setup_args(window);
156     // Set tag
157     var tag = null;
158     if ('tag' in window.args)
159         tag = window.args.tag;
160     window.tag = generate_new_window_tag(tag);
162     // Add a getBrowser() function to help certain extensions designed for Firefox work with conkeror
163     window.getBrowser = window_get_this_browser;
165     window_initialize_early_hook.run(window);
166     delete window.initialize_early_hook; // used only once
168     window_initialize_hook.run(window);
169     delete window.initialize_hook; // used only once
171     window.setTimeout(function(){
172             window_initialize_late_hook.run(window);
173             delete window.window_initialize_late_hook; // used only once
174             delete window.args; // get rid of args
175         },0);
177     window.addEventListener("close", window_close_maybe, true /* capture */, false);
180 define_window_local_hook("window_before_close_hook", RUN_HOOK_UNTIL_FAILURE);
181 define_window_local_hook("window_close_hook", RUN_HOOK);
182 function window_close_maybe(event) {
183     var window = this;
185     if (!window_before_close_hook.run(window)) {
186         event.preventDefault();
187         event.stopPropagation();
188         return;
189     }
191     window_close_hook.run(window);
194 function define_global_window_mode(name, hook_name) {
195     function install(window) {
196         if (window[name])
197             throw new Error(name + " already initialized for window");
198         window[name] = new conkeror[name](window);
199     }
200     function uninstall(window) {
201         if (!window[name])
202             throw new Error(name + " not initialized for window");
203         window[name].uninstall();
204         delete window[name];
205     }
206     define_global_mode(name + "_mode",
207                        function () { // enable
208                            add_hook(hook_name, install);
209                            for_each_window(install);
210                        },
211                        function () { // disable
212                            remove_hook(hook_name, install);
213                            for_each_window(uninstall);
214                        });
216 ignore_function_for_get_caller_source_code_reference("define_global_window_mode");