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 // XXX: side-effect: contents from primary selection will overwrite clipboard
96 function paste_x_primary_selection (field) {
97 var str = read_from_x_primary_selection ();
98 field.value = field.value.substr (0, field.selectionStart) +
99 str + field.value.substr (field.selectionEnd);
102 "paste-x-primary-selection",
104 paste_x_primary_selection (I.buffer.focused_element);
108 function meta_x (window, prefix, command)
110 call_interactively({window: window, prefix_argument: prefix}, command);
112 interactive("execute-extended-command",
113 "Execute a Conkeror command specified in the minibuffer.",
119 else if (typeof prefix == "object")
120 prompt = prefix[0] == 4 ? "C-u " : prefix[0] + " ";
122 prompt = prefix + " ";
123 meta_x(I.window, I.P,
124 (yield I.minibuffer.read_command(
125 $prompt = "M-x" + prompt)));
128 /// built in commands
129 // see: http://www.xulplanet.com/tutorials/xultu/commandupdate.html
131 // Performs a command on a browser buffer content area
134 define_builtin_commands(
136 function (I, command) {
137 var buffer = I.buffer;
139 buffer.do_command(command);
141 /* Ignore exceptions */
145 I.buffer.mark_active = !I.buffer.mark_active;
147 function (I) I.buffer.mark_active
150 function get_link_text()
152 var e = document.commandDispatcher.focusedElement;
153 if (e && e.getAttribute("href")) {
154 return e.getAttribute("href");
161 function copy_email_address (loc)
163 // Copy the comma-separated list of email addresses only.
164 // There are other ways of embedding email addresses in a mailto:
165 // link, but such complex parsing is beyond us.
166 var qmark = loc.indexOf( "?" );
169 if ( qmark > 7 ) { // 7 == length of "mailto:"
170 addresses = loc.substring( 7, qmark );
172 addresses = loc.substr( 7 );
175 //XXX: the original code, which we got from firefox, unescapes the string
176 // using the current character set. To do this in conkeror, we
177 // *should* use an interactive method that gives us the character set,
178 // rather than fetching it by side-effect.
180 // // Let's try to unescape it using a character set
181 // // in case the address is not ASCII.
183 // var characterSet = this.target.ownerDocument.characterSet;
184 // const textToSubURI = Components.classes["@mozilla.org/intl/texttosuburi;1"]
185 // .getService(Components.interfaces.nsITextToSubURI);
186 // addresses = textToSubURI.unEscapeURIForUI(characterSet, addresses);
192 writeToClipboard(addresses);
193 message("Copied '" + addresses + "'");
195 interactive("copy-email-address", copy_email_address, ['focused_link_url']);
198 /* FIXME: fix this command */
200 interactive("source",
201 "Load a JavaScript file.",
202 function (fo) { load_rc (fo.path); }, [['f', function (a) { return "Source File: "; }, null, "source"]]);
204 function reinit (window, fn)
208 window.minibuffer.message ("Loaded: " + fn);
210 window.minibuffer.message ("Failed to load: "+fn);
214 interactive ("reinit",
215 "Reload the Conkeror rc file.",
217 reinit(I.window, get_pref("conkeror.rcfile"));
220 interactive("help-page",
221 "Open the Conkeror help page.",
223 open_in_browser(I.buffer, I.browse_target("open"),
224 "chrome://conkeror/content/help.html");
227 interactive("help-with-tutorial",
228 "Open the Conkeror tutorial.",
230 open_in_browser(I.buffer, I.browse_target("open"),
231 "chrome://conkeror/content/tutorial.html");
234 function univ_arg_to_number(prefix, default_value)
236 if (prefix == null) {
237 if (default_value == null)
240 return default_value;
242 if (typeof prefix == "object")
247 function eval_expression(window, s)
249 // eval in the global scope.
251 // In addition, the following variables are available:
253 var buffer = window.buffers.current;
254 var result = eval(s);
255 if (result !== undefined) {
256 window.minibuffer.message(String(result));
259 interactive("eval-expression",
260 "Evaluate JavaScript statements.",
264 (yield I.minibuffer.read($prompt = "Eval:",
265 $history = "eval-expression",
266 $completer = javascript_completer(I.buffer))));
270 // our little hack. Add a big blank chunk to the bottom of the
272 const scrolly_document_observer = {
276 observe: function(subject, topic, url)
278 // We asume the focused window is the one loading. Not always
279 // the case..tho pretty safe since conkeror is only one window.
281 var win = document.commandDispatcher.focusedWindow;
284 doc = win.content.document;
286 doc = content.document;
288 // Make sure we haven't already added the image
289 if (!doc.__conkeror_scrolly_hack__) {
290 doc.__conkeror_scrolly_hack__ = true;
291 var spc = doc.createElement("img");
292 spc.setAttribute("width", "1");
293 spc.setAttribute("height", getBrowser().mCurrentBrowser.boxObject.height);
294 spc.setAttribute("src", "chrome://conkeror/content/pixel.png");
295 doc.lastChild.appendChild(spc);
297 } catch(e) {alert(e);}
302 function toggle_eod_space()
304 var observerService = Components.classes["@mozilla.org/observer-service;1"]
305 .getService(Components.interfaces.nsIObserverService);
306 if (scrolly_document_observer.enabled) {
307 observerService.removeObserver(scrolly_document_observer, "page-end-load", false);
308 scrolly_document_observer.enabled = false;
310 observerService.addObserver(scrolly_document_observer, "page-end-load", false);
311 scrolly_document_observer.enabled = true;
314 interactive("toggle-eod-space", toggle_eod_space);
317 function show_extension_manager () {
318 return conkeror.window_watcher.openWindow (
320 "chrome://mozapps/content/extensions/extensions.xul?type=extensions",
322 "resizable=yes,dialog=no",
325 interactive("extensions",
326 "Open the extensions manager in a new window.",
327 show_extension_manager);
329 function print_buffer(buffer)
331 buffer.top_frame.print();
333 interactive("print-buffer",
334 "Print the currently loaded page.",
335 function (I) {print_buffer(I.buffer);});
337 function view_partial_source (window, charset, selection) {
338 if (charset) { charset = "charset=" + charset; }
339 window.window.openDialog("chrome://global/content/viewPartialSource.xul",
340 "_blank", "scrollbars,resizable,chrome,dialog=no",
341 null, charset, selection, 'selection');
343 //interactive ('view-partial-source', view_partial_source, I.current_window, I.content_charset, I.content_selection);
346 function view_mathml_source (window, charset, target) {
347 if (charset) { charset = "charset=" + charset; }
348 window.window.openDialog("chrome://global/content/viewPartialSource.xul",
349 "_blank", "scrollbars,resizable,chrome,dialog=no",
350 null, charset, target, 'mathml');
354 function send_key_as_event (window, element, key) {
356 var event = window.document.createEvent ("KeyboardEvent");
362 key.modifiers & MOD_CTRL, // ctrl
363 key.modifiers & MOD_META, // alt
364 key.modifiers & MOD_SHIFT, // shift
365 key.modifiers & MOD_META, // meta
368 // bit of a hack here.. we have to fake a keydown event for conkeror
369 window.keyboard.last_key_down_event = copy_event (event);
371 return element.dispatchEvent (event);
373 return window.dispatchEvent (event);
379 send_key_as_event (I.window, I.buffer.focused_element, "return");