2 * (C) Copyright 2007 John J. Foerch
3 * (C) Copyright 2007-2008 Jeremy Maitin-Shepard
5 * Use, modification, and distribution are subject to the terms specified in the
11 var define_window_local_hook = simple_local_hook_definer();
12 var define_window_local_coroutine_hook = simple_local_coroutine_hook_definer();
15 define_hook("make_window_hook");
17 var window_watcher = Cc["@mozilla.org/embedcomp/window-watcher;1"]
18 .getService(Ci.nsIWindowWatcher);
20 function generate_new_window_tag (tag) {
22 var exact_match = false;
23 var en = window_watcher.getWindowEnumerator();
28 re = new RegExp ("^" + tag + "<(\\d+)>$");
30 re = new RegExp ("^(\\d+)$");
31 while (en.hasMoreElements()) {
32 var w = en.getNext().QueryInterface(Ci.nsIDOMWindow);
34 if (tag && w.tag == tag) {
38 var re_result = re.exec(w.tag);
40 existing.push(re_result[1]);
43 if (tag && ! exact_match)
46 existing.sort(function (a, b) { return a - b; });
49 for (var i = 0; i < existing.length; i++) {
50 if (existing[i] < n) continue;
51 if (existing[i] == n) { n++; continue; }
55 return tag + "<" + n + ">";
60 function make_chrome_window (chrome_uri, args) {
61 return window_watcher.openWindow(null, chrome_uri, "_blank",
62 "chrome,dialog=no,all,resizable", args);
65 var conkeror_chrome_uri = "chrome://conkeror-gui/content/conkeror.xul";
67 function make_window (initial_buffer_creator, tag) {
68 var args = { tag: tag,
69 initial_buffer_creator: initial_buffer_creator };
70 var result = make_chrome_window(conkeror_chrome_uri, null);
72 make_window_hook.run(result);
73 var close = result.close;
74 result.close = function () {
75 function attempt_close () {
76 var res = yield window_before_close_hook.run(result);
78 window_close_hook.run(result);
82 co_call(attempt_close());
87 function get_window_by_tag (tag) {
88 var en = window_watcher.getWindowEnumerator();
89 while (en.hasMoreElements()) {
90 var w = en.getNext().QueryInterface(Ci.nsIDOMWindow);
91 if ('tag' in w && w.tag == tag)
97 /* FIXME: decide if this should include not-fully-initialized windows */
98 function for_each_window (func) {
99 var en = window_watcher.getWindowEnumerator();
100 while (en.hasMoreElements()) {
101 var w = en.getNext().QueryInterface(Ci.nsIDOMWindow);
107 function get_recent_conkeror_window () {
108 var window = window_watcher.activeWindow;
109 if (window && ("conkeror" in window))
111 var en = window_watcher.getWindowEnumerator();
112 while (en.hasMoreElements()) {
113 window = en.getNext().QueryInterface(Ci.nsIDOMWindow);
114 if ('conkeror' in window)
120 define_window_local_hook("window_initialize_early_hook");
121 define_window_local_hook("window_initialize_hook");
122 define_window_local_hook("window_initialize_late_hook");
124 var window_extra_argument_list = [];
126 define_variable("window_extra_argument_max_delay", 100);
128 function window_setup_args (window) {
129 if (window.args != null)
132 var cur_time = Date.now();
135 for (i = 0; i < window_extra_argument_list.length; ++i) {
136 var a = window_extra_argument_list[i];
137 if (a.time > cur_time - window_extra_argument_max_delay) {
144 window_extra_argument_list = window_extra_argument_list.slice(i);
149 window.args = result;
152 function window_set_extra_arguments (args) {
153 args.time = Date.now();
154 window_extra_argument_list.push(args);
157 function window_get_this_browser () {
158 return this.buffers.current.browser;
161 function window_initialize (window) {
162 window.conkeror = conkeror;
164 // Used by get_window_from_frame to get an unwrapped window reference
165 window.escape_wrapper = function (x) { x(window); };
167 window_setup_args(window);
171 if ('tag' in window.args)
172 tag = window.args.tag;
173 window.tag = generate_new_window_tag(tag);
175 // Add a getBrowser() function to help certain extensions designed
176 // for Firefox work with conkeror
177 window.getBrowser = window_get_this_browser;
179 window_initialize_early_hook.run(window);
180 delete window.window_initialize_early_hook; // used only once
182 window_initialize_hook.run(window);
183 delete window.window_initialize_hook; // used only once
185 window.setTimeout(function () {
186 window_initialize_late_hook.run(window);
187 delete window.window_initialize_late_hook; // used only once
188 delete window.args; // get rid of args
191 window.addEventListener("close",
193 event.preventDefault();
194 event.stopPropagation();
200 define_window_local_coroutine_hook("window_before_close_hook",
201 RUN_HOOK_UNTIL_FAILURE);
202 define_window_local_hook("window_close_hook", RUN_HOOK);
205 function define_global_window_mode (name, hook_name) {
206 function install (window) {
208 throw new Error(name + " already initialized for window");
209 window[name] = new conkeror[name](window);
211 function uninstall (window) {
213 throw new Error(name + " not initialized for window");
214 window[name].uninstall();
217 define_global_mode(name + "_mode",
218 function () { // enable
219 add_hook(hook_name, install);
220 for_each_window(install);
222 function () { // disable
223 remove_hook(hook_name, install);
224 for_each_window(uninstall);
227 ignore_function_for_get_caller_source_code_reference("define_global_window_mode");
231 /// Window title formatting
234 * Default tile formatter. The page url is ignored. If there is a
235 * page_title, returns: "Page title - Conkeror". Otherwise, it
236 * returns just: "Conkeror".
238 function default_title_formatter (window) {
239 var page_title = window.buffers.current.title;
241 if (page_title && page_title.length > 0)
242 return page_title + " - Conkeror";
247 var title_format_fn = null;
249 function set_window_title (window) {
250 window.document.title = title_format_fn(window);
253 function init_window_title () {
254 title_format_fn = default_title_formatter;
256 add_hook("window_initialize_late_hook", set_window_title);
257 add_hook("current_content_buffer_location_change_hook",
259 set_window_title(buffer.window);
261 add_hook("select_buffer_hook",
263 set_window_title(buffer.window);
265 add_hook("current_buffer_title_change_hook",
267 set_window_title(buffer.window);