1 /***** BEGIN LICENSE BLOCK *****
2 Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 The contents of this file are subject to the Mozilla Public License Version
5 1.1 (the "License"); you may not use this file except in compliance with
6 the License. You may obtain a copy of the License at
7 http://www.mozilla.org/MPL/
9 Software distributed under the License is distributed on an "AS IS" basis,
10 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 for the specific language governing rights and limitations under the
14 The Initial Developer of the Original Code is Shawn Betts.
15 Portions created by the Initial Developer are Copyright (C) 2004,2005
16 by the Initial Developer. All Rights Reserved.
18 Alternatively, the contents of this file may be used under the terms of
19 either the GNU General Public License Version 2 or later (the "GPL"), or
20 the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
21 in which case the provisions of the GPL or the LGPL are applicable instead
22 of those above. If you wish to allow use of your version of this file only
23 under the terms of either the GPL or the LGPL, and not to allow others to
24 use your version of this file under the terms of the MPL, indicate your
25 decision by deleting the provisions above and replace them with the notice
26 and other provisions required by the GPL or the LGPL. If you do not delete
27 the provisions above, a recipient may use your version of this file under
28 the terms of any one of the MPL, the GPL or the LGPL.
29 ***** END LICENSE BLOCK *****/
31 require("content-buffer.js");
33 define_hook("quit_hook");
38 var appStartup = Cc["@mozilla.org/toolkit/app-startup;1"]
39 .getService(Ci.nsIAppStartup);
40 appStartup.quit(appStartup.eAttemptQuit);
47 function show_conkeror_version (window)
49 window.minibuffer.message (conkeror.version);
51 interactive ("conkeror-version",
52 "Show version information for Conkeror.",
53 function (I) {show_conkeror_version(I.window);});
55 /* FIXME: maybe this should be supported for non-browser buffers */
56 function scroll_horiz_complete (buffer, n)
58 var w = buffer.focused_frame;
59 w.scrollTo (n > 0 ? w.scrollMaxX : 0, w.scrollY);
61 interactive("scroll-beginning-of-line",
62 "Scroll the current frame all the way to the left.",
63 function (I) {scroll_horiz_complete(I.buffer, -1);});
65 interactive("scroll-end-of-line",
66 "Scroll the current frame all the way to the right.",
67 function (I) {scroll_horiz_complete(I.buffer, 1);});
69 interactive("make-window",
72 make_window(buffer_creator(content_buffer,
74 $configuration = I.buffer.configuration));
77 function delete_window (window)
79 window.window.close();
81 interactive("delete-window",
82 "Delete the current window.",
83 function (I) {delete_window(I.window);});
85 interactive("jsconsole",
86 "Open the JavaScript console.",
88 open_in_browser(I.buffer,
89 I.browse_target("jsconsole"),
90 "chrome://global/content/console.xul");
92 default_browse_targets["jsconsole"] = "find-url";
95 function paste_x_primary_selection (field) {
96 var str = read_from_x_primary_selection ();
97 var point = field.selectionEnd;
98 field.value = field.value.substr (0, field.selectionStart) +
99 str + field.value.substr (field.selectionEnd);
100 field.setSelectionRange (point, point);
103 "paste-x-primary-selection",
105 var m = I.window.minibuffer;
106 var s = m.current_state;
107 if (m._input_mode_enabled) {
108 m._restore_normal_state();
109 var e = m.input_element;
111 var e = I.buffer.focused_element;
112 paste_x_primary_selection (e);
113 if (s && s.handle_input)
118 function meta_x (window, prefix, command)
120 call_interactively({window: window, prefix_argument: prefix}, command);
122 interactive("execute-extended-command",
123 "Execute a Conkeror command specified in the minibuffer.",
129 else if (typeof prefix == "object")
130 prompt = prefix[0] == 4 ? "C-u " : prefix[0] + " ";
132 prompt = prefix + " ";
133 meta_x(I.window, I.P,
134 (yield I.minibuffer.read_command(
135 $prompt = "M-x" + prompt)));
138 /// built in commands
139 // see: http://www.xulplanet.com/tutorials/xultu/commandupdate.html
141 // Performs a command on a browser buffer content area
144 define_builtin_commands(
146 function (I, command) {
147 var buffer = I.buffer;
149 buffer.do_command(command);
151 /* Ignore exceptions */
155 I.buffer.mark_active = !I.buffer.mark_active;
157 function (I) I.buffer.mark_active
160 function get_link_text()
162 var e = document.commandDispatcher.focusedElement;
163 if (e && e.getAttribute("href")) {
164 return e.getAttribute("href");
171 function copy_email_address (loc)
173 // Copy the comma-separated list of email addresses only.
174 // There are other ways of embedding email addresses in a mailto:
175 // link, but such complex parsing is beyond us.
176 var qmark = loc.indexOf( "?" );
179 if ( qmark > 7 ) { // 7 == length of "mailto:"
180 addresses = loc.substring( 7, qmark );
182 addresses = loc.substr( 7 );
185 //XXX: the original code, which we got from firefox, unescapes the string
186 // using the current character set. To do this in conkeror, we
187 // *should* use an interactive method that gives us the character set,
188 // rather than fetching it by side-effect.
190 // // Let's try to unescape it using a character set
191 // // in case the address is not ASCII.
193 // var characterSet = this.target.ownerDocument.characterSet;
194 // const textToSubURI = Components.classes["@mozilla.org/intl/texttosuburi;1"]
195 // .getService(Components.interfaces.nsITextToSubURI);
196 // addresses = textToSubURI.unEscapeURIForUI(characterSet, addresses);
202 writeToClipboard(addresses);
203 message("Copied '" + addresses + "'");
205 interactive("copy-email-address", copy_email_address, ['focused_link_url']);
208 /* FIXME: fix this command */
210 interactive("source",
211 "Load a JavaScript file.",
212 function (fo) { load_rc (fo.path); }, [['f', function (a) { return "Source File: "; }, null, "source"]]);
214 function reinit (window, fn)
218 window.minibuffer.message ("Loaded: " + fn);
220 window.minibuffer.message ("Failed to load: "+fn);
224 interactive ("reinit",
225 "Reload the Conkeror rc file.",
227 reinit(I.window, get_pref("conkeror.rcfile"));
230 interactive("help-page",
231 "Open the Conkeror help page.",
233 open_in_browser(I.buffer, I.browse_target("open"),
234 "chrome://conkeror/content/help.html");
237 interactive("help-with-tutorial",
238 "Open the Conkeror tutorial.",
240 open_in_browser(I.buffer, I.browse_target("open"),
241 "chrome://conkeror/content/tutorial.html");
244 function univ_arg_to_number(prefix, default_value)
246 if (prefix == null) {
247 if (default_value == null)
250 return default_value;
252 if (typeof prefix == "object")
257 function eval_expression(window, s)
259 // eval in the global scope.
261 // In addition, the following variables are available:
263 var buffer = window.buffers.current;
264 var result = eval(s);
265 if (result !== undefined) {
266 window.minibuffer.message(String(result));
269 interactive("eval-expression",
270 "Evaluate JavaScript statements.",
274 (yield I.minibuffer.read($prompt = "Eval:",
275 $history = "eval-expression",
276 $completer = javascript_completer(I.buffer))));
280 // our little hack. Add a big blank chunk to the bottom of the
282 const scrolly_document_observer = {
286 observe: function(subject, topic, url)
288 // We asume the focused window is the one loading. Not always
289 // the case..tho pretty safe since conkeror is only one window.
291 var win = document.commandDispatcher.focusedWindow;
294 doc = win.content.document;
296 doc = content.document;
298 // Make sure we haven't already added the image
299 if (!doc.__conkeror_scrolly_hack__) {
300 doc.__conkeror_scrolly_hack__ = true;
301 var spc = doc.createElement("img");
302 spc.setAttribute("width", "1");
303 spc.setAttribute("height", getBrowser().mCurrentBrowser.boxObject.height);
304 spc.setAttribute("src", "chrome://conkeror/content/pixel.png");
305 doc.lastChild.appendChild(spc);
307 } catch(e) {alert(e);}
312 function toggle_eod_space()
314 var observerService = Components.classes["@mozilla.org/observer-service;1"]
315 .getService(Components.interfaces.nsIObserverService);
316 if (scrolly_document_observer.enabled) {
317 observerService.removeObserver(scrolly_document_observer, "page-end-load", false);
318 scrolly_document_observer.enabled = false;
320 observerService.addObserver(scrolly_document_observer, "page-end-load", false);
321 scrolly_document_observer.enabled = true;
324 interactive("toggle-eod-space", toggle_eod_space);
327 function show_extension_manager () {
328 return conkeror.window_watcher.openWindow (
330 "chrome://mozapps/content/extensions/extensions.xul?type=extensions",
332 "resizable=yes,dialog=no",
335 interactive("extensions",
336 "Open the extensions manager in a new window.",
337 show_extension_manager);
339 function print_buffer(buffer)
341 buffer.top_frame.print();
343 interactive("print-buffer",
344 "Print the currently loaded page.",
345 function (I) {print_buffer(I.buffer);});
347 function view_partial_source (window, charset, selection) {
348 if (charset) { charset = "charset=" + charset; }
349 window.window.openDialog("chrome://global/content/viewPartialSource.xul",
350 "_blank", "scrollbars,resizable,chrome,dialog=no",
351 null, charset, selection, 'selection');
353 //interactive ('view-partial-source', view_partial_source, I.current_window, I.content_charset, I.content_selection);
356 function view_mathml_source (window, charset, target) {
357 if (charset) { charset = "charset=" + charset; }
358 window.window.openDialog("chrome://global/content/viewPartialSource.xul",
359 "_blank", "scrollbars,resizable,chrome,dialog=no",
360 null, charset, target, 'mathml');
364 function send_key_as_event (window, element, key) {
366 var event = window.document.createEvent ("KeyboardEvent");
372 key.modifiers & MOD_CTRL, // ctrl
373 key.modifiers & MOD_META, // alt
374 key.modifiers & MOD_SHIFT, // shift
375 key.modifiers & MOD_META, // meta
378 // bit of a hack here.. we have to fake a keydown event for conkeror
379 window.keyboard.last_key_down_event = copy_event (event);
381 return element.dispatchEvent (event);
383 return window.dispatchEvent (event);
389 send_key_as_event (I.window, I.buffer.focused_element, "return");
392 function ensure_content_focused(buffer) {
393 var foc = buffer.focused_frame_or_null;
395 buffer.top_frame.focus();
397 interactive("ensure-content-focused", "Ensure that the content document has focus.",
398 function (I) { ensure_content_focused(I.buffer); });