.deb nightly builds: Make contact e-mail address configurable
[conkeror.git] / modules / window.js
blobbee334252bc2cb73e89894e27ed1108f2d3d4cf3
1 /**
2  * (C) Copyright 2007 John J. Foerch
3  * (C) Copyright 2007-2008 Jeremy Maitin-Shepard
4  *
5  * Use, modification, and distribution are subject to the terms specified in the
6  * COPYING file.
7 **/
9 require("mode.js");
11 var define_window_local_hook = simple_local_hook_definer();
14 define_hook("make_window_hook");
16 var window_watcher = Cc["@mozilla.org/embedcomp/window-watcher;1"]
17     .getService(Ci.nsIWindowWatcher);
19 function generate_new_window_tag (tag) {
20     var existing = [];
21     var exact_match = false;
22     var en = window_watcher.getWindowEnumerator();
23     if (tag == '')
24         tag = null;
25     var re;
26     if (tag)
27         re = new RegExp ("^" + tag + "<(\\d+)>$");
28     else
29         re = new RegExp ("^(\\d+)$");
30     while (en.hasMoreElements()) {
31         var w = en.getNext().QueryInterface(Ci.nsIDOMWindow);
32         if ('tag' in w)  {
33             if (tag && w.tag == tag) {
34                 exact_match = true;
35                 continue;
36             }
37             var re_result = re.exec(w.tag);
38             if (re_result)
39                 existing.push(re_result[1]);
40         }
41     }
42     if (tag && ! exact_match)
43         return tag;
45     existing.sort(function (a, b) { return a - b; });
47     var n = 1;
48     for (var i = 0; i < existing.length; i++) {
49         if (existing[i] < n) continue;
50         if (existing[i] == n) { n++; continue; }
51         break;
52     }
53     if (tag)
54         return tag + "<" + n + ">";
55     else
56         return n;
59 function make_chrome_window (chrome_uri, args) {
60     return window_watcher.openWindow(null, chrome_uri, "_blank",
61                                      "chrome,dialog=no,all,resizable", args);
64 var conkeror_chrome_uri = "chrome://conkeror-gui/content/conkeror.xul";
66 function make_window (initial_buffer_creator, tag) {
67     var args = { tag: tag,
68                  initial_buffer_creator: initial_buffer_creator };
69     var result = make_chrome_window(conkeror_chrome_uri, null);
70     result.args = args;
71     make_window_hook.run(result);
72     result._close = result.close;
73     result.close = function () {
74       if (window_before_close_hook.run(result))
75         result._close();
76     };
77     return result;
80 function get_window_by_tag (tag) {
81     var en = window_watcher.getWindowEnumerator();
82     while (en.hasMoreElements()) {
83         var w = en.getNext().QueryInterface(Ci.nsIDOMWindow);
84         if ('tag' in w && w.tag == tag)
85             return w;
86     }
87     return null;
90 /* FIXME: decide if this should include not-fully-initialized windows  */
91 function for_each_window (func) {
92     var en = window_watcher.getWindowEnumerator();
93     while (en.hasMoreElements()) {
94         var w = en.getNext().QueryInterface(Ci.nsIDOMWindow);
95         if ('conkeror' in w)
96             func(w);
97     }
100 function get_recent_conkeror_window () {
101     var window = window_watcher.activeWindow;
102     if (window && ("conkeror" in window))
103         return window;
104     var en = window_watcher.getWindowEnumerator();
105     while (en.hasMoreElements()) {
106         window = en.getNext().QueryInterface(Ci.nsIDOMWindow);
107         if ('conkeror' in window)
108             return window;
109     }
110     return null;
113 define_window_local_hook("window_initialize_early_hook");
114 define_window_local_hook("window_initialize_hook");
115 define_window_local_hook("window_initialize_late_hook");
117 var window_extra_argument_list = [];
119 define_variable("window_extra_argument_max_delay", 100);
121 function window_setup_args (window) {
122     if (window.args != null)
123         return;
125     var cur_time = Date.now();
126     var i;
127     var result = null;
128     for (i = 0; i < window_extra_argument_list.length; ++i) {
129         var a = window_extra_argument_list[i];
130         if (a.time > cur_time - window_extra_argument_max_delay) {
131             delete a.time;
132             result = a;
133             i++;
134             break;
135         }
136     }
137     window_extra_argument_list = window_extra_argument_list.slice(i);
139     if (result == null)
140         window.args = {};
141     else
142         window.args = result;
145 function window_set_extra_arguments (args) {
146     args.time = Date.now();
147     window_extra_argument_list.push(args);
150 function window_get_this_browser () {
151     return this.buffers.current.browser;
154 function window_initialize (window) {
155     window.conkeror = conkeror;
157     // Used by get_window_from_frame to get an unwrapped window reference
158     window.escape_wrapper = function (x) { x(window); };
160     window_setup_args(window);
162     // Set tag
163     var tag = null;
164     if ('tag' in window.args)
165         tag = window.args.tag;
166     window.tag = generate_new_window_tag(tag);
168     // Add a getBrowser() function to help certain extensions designed
169     // for Firefox work with conkeror
170     window.getBrowser = window_get_this_browser;
172     window_initialize_early_hook.run(window);
173     delete window.window_initialize_early_hook; // used only once
175     window_initialize_hook.run(window);
176     delete window.window_initialize_hook; // used only once
178     window.setTimeout(function () {
179             window_initialize_late_hook.run(window);
180             delete window.window_initialize_late_hook; // used only once
181             delete window.args; // get rid of args
182         }, 0);
184     window.addEventListener("close", window_close_maybe, true /* capture */);
187 define_window_local_hook("window_before_close_hook", RUN_HOOK_UNTIL_FAILURE);
188 define_window_local_hook("window_close_hook", RUN_HOOK);
189 function window_close_maybe (event) {
190     var window = this;
192     if (!window_before_close_hook.run(window)) {
193         event.preventDefault();
194         event.stopPropagation();
195         return;
196     }
198     window_close_hook.run(window);
201 function define_global_window_mode (name, hook_name) {
202     function install (window) {
203         if (name in window)
204             throw new Error(name + " already initialized for window");
205         window[name] = new conkeror[name](window);
206     }
207     function uninstall (window) {
208         if (!window[name])
209             throw new Error(name + " not initialized for window");
210         window[name].uninstall();
211         delete window[name];
212     }
213     define_global_mode(name + "_mode",
214                        function () { // enable
215                            add_hook(hook_name, install);
216                            for_each_window(install);
217                        },
218                        function () { // disable
219                            remove_hook(hook_name, install);
220                            for_each_window(uninstall);
221                        });
223 ignore_function_for_get_caller_source_code_reference("define_global_window_mode");
227 /// Window title formatting
230  * Default tile formatter.  The page url is ignored.  If there is a
231  * page_title, returns: "Page title - Conkeror".  Otherwise, it
232  * returns just: "Conkeror".
233  */
234 function default_title_formatter (window) {
235     var page_title = window.buffers.current.title;
237     if (page_title && page_title.length > 0)
238         return page_title + " - Conkeror";
239     else
240         return "Conkeror";
243 var title_format_fn = null;
245 function set_window_title (window) {
246     window.document.title = title_format_fn(window);
249 function init_window_title () {
250     title_format_fn = default_title_formatter;
252     add_hook("window_initialize_late_hook", set_window_title);
253     add_hook("current_content_buffer_location_change_hook",
254              function (buffer) {
255                  set_window_title(buffer.window);
256              });
257     add_hook("select_buffer_hook",
258              function (buffer) {
259                  set_window_title(buffer.window);
260              }, true);
261     add_hook("current_buffer_title_change_hook",
262              function (buffer) {
263                  set_window_title(buffer.window);
264              });
267 init_window_title();