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
13 var define_window_local_hook = simple_local_hook_definer();
14 var define_window_local_coroutine_hook = simple_local_coroutine_hook_definer();
17 define_hook("make_window_hook");
19 var window_watcher = Cc["@mozilla.org/embedcomp/window-watcher;1"]
20 .getService(Ci.nsIWindowWatcher);
22 function generate_new_window_tag (tag) {
24 var exact_match = false;
25 var en = window_watcher.getWindowEnumerator();
30 re = new RegExp ("^" + tag + "<(\\d+)>$");
32 re = new RegExp ("^(\\d+)$");
33 while (en.hasMoreElements()) {
34 var w = en.getNext().QueryInterface(Ci.nsIDOMWindow);
36 if (tag && w.tag == tag) {
40 var re_result = re.exec(w.tag);
42 existing.push(re_result[1]);
45 if (tag && ! exact_match)
48 existing.sort(function (a, b) { return a - b; });
51 for (var i = 0; i < existing.length; i++) {
52 if (existing[i] < n) continue;
53 if (existing[i] == n) { n++; continue; }
57 return tag + "<" + n + ">";
62 function make_chrome_window (chrome_uri, args) {
63 return window_watcher.openWindow(null, chrome_uri, "_blank",
64 "chrome,dialog=no,all,resizable", args);
67 var conkeror_chrome_uri = "chrome://conkeror-gui/content/conkeror.xul";
69 function make_window (initial_buffer_creator, tag) {
70 var args = { tag: tag,
71 initial_buffer_creator: initial_buffer_creator };
72 var result = make_chrome_window(conkeror_chrome_uri, null);
74 make_window_hook.run(result);
75 var close = result.close;
76 result.close = function () {
77 function attempt_close () {
78 var res = yield window_before_close_hook.run(result);
80 window_close_hook.run(result);
84 co_call(attempt_close());
89 function get_window_by_tag (tag) {
90 var en = window_watcher.getWindowEnumerator();
91 while (en.hasMoreElements()) {
92 var w = en.getNext().QueryInterface(Ci.nsIDOMWindow);
93 if ('tag' in w && w.tag == tag)
99 /* FIXME: decide if this should include not-fully-initialized windows */
100 function for_each_window (func) {
101 var en = window_watcher.getWindowEnumerator();
102 while (en.hasMoreElements()) {
103 var w = en.getNext().QueryInterface(Ci.nsIDOMWindow);
109 function get_recent_conkeror_window () {
110 var wm = Cc['@mozilla.org/appshell/window-mediator;1']
111 .getService(Ci.nsIWindowMediator);
112 var window = wm.getMostRecentWindow("navigator:browser");
113 if (window && ("conkeror" in window))
115 var en = window_watcher.getWindowEnumerator();
116 while (en.hasMoreElements()) {
117 window = en.getNext().QueryInterface(Ci.nsIDOMWindow);
118 if ('conkeror' in window)
124 define_window_local_hook("window_initialize_early_hook");
125 define_window_local_hook("window_initialize_hook");
126 define_window_local_hook("window_initialize_late_hook");
128 var window_extra_argument_list = [];
130 define_variable("window_extra_argument_max_delay", 100);
132 function window_setup_args (window) {
133 if (window.args != null)
136 var cur_time = Date.now();
139 for (i = 0; i < window_extra_argument_list.length; ++i) {
140 var a = window_extra_argument_list[i];
141 if (a.time > cur_time - window_extra_argument_max_delay) {
148 window_extra_argument_list = window_extra_argument_list.slice(i);
153 window.args = result;
156 function window_set_extra_arguments (args) {
157 args.time = Date.now();
158 window_extra_argument_list.push(args);
161 function window_get_this_browser () {
162 return this.buffers.current.browser;
165 function window_initialize (window) {
166 window.conkeror = conkeror;
168 // Used by get_window_from_frame to get an unwrapped window reference
169 window.escape_wrapper = function (x) { x(window); };
171 window_setup_args(window);
175 if ('tag' in window.args)
176 tag = window.args.tag;
177 window.tag = generate_new_window_tag(tag);
179 // Add a getBrowser() function to help certain extensions designed
180 // for Firefox work with conkeror
181 window.getBrowser = window_get_this_browser;
183 window_initialize_early_hook.run(window);
184 delete window.window_initialize_early_hook; // used only once
186 window_initialize_hook.run(window);
187 delete window.window_initialize_hook; // used only once
189 window.setTimeout(function () {
190 window_initialize_late_hook.run(window);
191 delete window.window_initialize_late_hook; // used only once
192 delete window.args; // get rid of args
195 window.addEventListener("close",
197 event.preventDefault();
198 event.stopPropagation();
204 define_window_local_coroutine_hook("window_before_close_hook",
205 RUN_HOOK_UNTIL_FAILURE);
206 define_window_local_hook("window_close_hook", RUN_HOOK);
212 function define_global_window_mode (name, hook_name) {
213 function install (window) {
215 throw new Error(name + " already initialized for window");
216 window[name] = new conkeror[name](window);
218 function uninstall (window) {
220 throw new Error(name + " not initialized for window");
221 window[name].uninstall();
224 define_global_mode(name + "_mode",
225 function () { // enable
226 add_hook(hook_name, install);
227 for_each_window(install);
229 function () { // disable
230 remove_hook(hook_name, install);
231 for_each_window(uninstall);
234 ignore_function_for_get_caller_source_code_reference("define_global_window_mode");
243 * Default tile formatter. The page url is ignored. If there is a
244 * page_title, returns: "Page title - Conkeror". Otherwise, it
245 * returns just: "Conkeror".
247 function default_title_formatter (window) {
248 var page_title = window.buffers.current.title;
250 if (page_title && page_title.length > 0)
251 return page_title + " - Conkeror";
256 var title_format_fn = null;
258 function set_window_title (window) {
259 window.document.title = title_format_fn(window);
262 function init_window_title () {
263 title_format_fn = default_title_formatter;
265 add_hook("window_initialize_late_hook", set_window_title);
266 add_hook("current_content_buffer_location_change_hook",
268 set_window_title(buffer.window);
270 add_hook("select_buffer_hook",
272 set_window_title(buffer.window);
274 add_hook("current_buffer_title_change_hook",
276 set_window_title(buffer.window);
283 function call_builtin_command (window, command, clear_mark) {
284 var m = window.minibuffer;
285 if (m.active && m._input_mode_enabled) {
286 m._restore_normal_state();
287 var e = m.input_element;
288 var c = e.controllers.getControllerForCommand(command);
290 if (c && c.isCommandEnabled(command))
291 c.doCommand(command);
296 m.current_state.mark_active = false;
298 function attempt_command (element) {
300 if (element.controllers
301 && (c = element.controllers.getControllerForCommand(command)) != null
302 && c.isCommandEnabled(command))
305 c.doCommand(command);
310 window.buffers.current.mark_active = false;
315 var element = window.buffers.current.focused_element;
316 if (element && attempt_command(element, command))
318 var win = window.buffers.current.focused_frame;
320 if (attempt_command(win, command))
322 if (!win.parent || win == win.parent)
331 * window_set_full_screen sets or toggles the fullScreen and hideChrome
332 * properties of the given window. When fullscreen is a boolean, it sets
333 * it to that value. When it is null or not given, it toggles the current
336 function window_set_full_screen (window, fullscreen) {
337 if (fullscreen === true || fullscreen === false) {
338 window.fullScreen = fullscreen;
339 window.hideChrome = fullscreen;
341 window.fullScreen = ! window.fullScreen;
342 window.hideChrome = window.fullScreen;