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 paste_x_primary_selection (I.buffer.focused_element);
109 function meta_x (window, prefix, command)
111 call_interactively({window: window, prefix_argument: prefix}, command);
113 interactive("execute-extended-command",
114 "Execute a Conkeror command specified in the minibuffer.",
120 else if (typeof prefix == "object")
121 prompt = prefix[0] == 4 ? "C-u " : prefix[0] + " ";
123 prompt = prefix + " ";
124 meta_x(I.window, I.P,
125 (yield I.minibuffer.read_command(
126 $prompt = "M-x" + prompt)));
129 /// built in commands
130 // see: http://www.xulplanet.com/tutorials/xultu/commandupdate.html
132 // Performs a command on a browser buffer content area
135 define_builtin_commands(
137 function (I, command) {
138 var buffer = I.buffer;
140 buffer.do_command(command);
142 /* Ignore exceptions */
146 I.buffer.mark_active = !I.buffer.mark_active;
148 function (I) I.buffer.mark_active
151 function get_link_text()
153 var e = document.commandDispatcher.focusedElement;
154 if (e && e.getAttribute("href")) {
155 return e.getAttribute("href");
162 function copy_email_address (loc)
164 // Copy the comma-separated list of email addresses only.
165 // There are other ways of embedding email addresses in a mailto:
166 // link, but such complex parsing is beyond us.
167 var qmark = loc.indexOf( "?" );
170 if ( qmark > 7 ) { // 7 == length of "mailto:"
171 addresses = loc.substring( 7, qmark );
173 addresses = loc.substr( 7 );
176 //XXX: the original code, which we got from firefox, unescapes the string
177 // using the current character set. To do this in conkeror, we
178 // *should* use an interactive method that gives us the character set,
179 // rather than fetching it by side-effect.
181 // // Let's try to unescape it using a character set
182 // // in case the address is not ASCII.
184 // var characterSet = this.target.ownerDocument.characterSet;
185 // const textToSubURI = Components.classes["@mozilla.org/intl/texttosuburi;1"]
186 // .getService(Components.interfaces.nsITextToSubURI);
187 // addresses = textToSubURI.unEscapeURIForUI(characterSet, addresses);
193 writeToClipboard(addresses);
194 message("Copied '" + addresses + "'");
196 interactive("copy-email-address", copy_email_address, ['focused_link_url']);
199 /* FIXME: fix this command */
201 interactive("source",
202 "Load a JavaScript file.",
203 function (fo) { load_rc (fo.path); }, [['f', function (a) { return "Source File: "; }, null, "source"]]);
205 function reinit (window, fn)
209 window.minibuffer.message ("Loaded: " + fn);
211 window.minibuffer.message ("Failed to load: "+fn);
215 interactive ("reinit",
216 "Reload the Conkeror rc file.",
218 reinit(I.window, get_pref("conkeror.rcfile"));
221 interactive("help-page",
222 "Open the Conkeror help page.",
224 open_in_browser(I.buffer, I.browse_target("open"),
225 "chrome://conkeror/content/help.html");
228 interactive("help-with-tutorial",
229 "Open the Conkeror tutorial.",
231 open_in_browser(I.buffer, I.browse_target("open"),
232 "chrome://conkeror/content/tutorial.html");
235 function univ_arg_to_number(prefix, default_value)
237 if (prefix == null) {
238 if (default_value == null)
241 return default_value;
243 if (typeof prefix == "object")
248 function eval_expression(window, s)
250 // eval in the global scope.
252 // In addition, the following variables are available:
254 var buffer = window.buffers.current;
255 var result = eval(s);
256 if (result !== undefined) {
257 window.minibuffer.message(String(result));
260 interactive("eval-expression",
261 "Evaluate JavaScript statements.",
265 (yield I.minibuffer.read($prompt = "Eval:",
266 $history = "eval-expression",
267 $completer = javascript_completer(I.buffer))));
271 // our little hack. Add a big blank chunk to the bottom of the
273 const scrolly_document_observer = {
277 observe: function(subject, topic, url)
279 // We asume the focused window is the one loading. Not always
280 // the case..tho pretty safe since conkeror is only one window.
282 var win = document.commandDispatcher.focusedWindow;
285 doc = win.content.document;
287 doc = content.document;
289 // Make sure we haven't already added the image
290 if (!doc.__conkeror_scrolly_hack__) {
291 doc.__conkeror_scrolly_hack__ = true;
292 var spc = doc.createElement("img");
293 spc.setAttribute("width", "1");
294 spc.setAttribute("height", getBrowser().mCurrentBrowser.boxObject.height);
295 spc.setAttribute("src", "chrome://conkeror/content/pixel.png");
296 doc.lastChild.appendChild(spc);
298 } catch(e) {alert(e);}
303 function toggle_eod_space()
305 var observerService = Components.classes["@mozilla.org/observer-service;1"]
306 .getService(Components.interfaces.nsIObserverService);
307 if (scrolly_document_observer.enabled) {
308 observerService.removeObserver(scrolly_document_observer, "page-end-load", false);
309 scrolly_document_observer.enabled = false;
311 observerService.addObserver(scrolly_document_observer, "page-end-load", false);
312 scrolly_document_observer.enabled = true;
315 interactive("toggle-eod-space", toggle_eod_space);
318 function show_extension_manager () {
319 return conkeror.window_watcher.openWindow (
321 "chrome://mozapps/content/extensions/extensions.xul?type=extensions",
323 "resizable=yes,dialog=no",
326 interactive("extensions",
327 "Open the extensions manager in a new window.",
328 show_extension_manager);
330 function print_buffer(buffer)
332 buffer.top_frame.print();
334 interactive("print-buffer",
335 "Print the currently loaded page.",
336 function (I) {print_buffer(I.buffer);});
338 function view_partial_source (window, charset, selection) {
339 if (charset) { charset = "charset=" + charset; }
340 window.window.openDialog("chrome://global/content/viewPartialSource.xul",
341 "_blank", "scrollbars,resizable,chrome,dialog=no",
342 null, charset, selection, 'selection');
344 //interactive ('view-partial-source', view_partial_source, I.current_window, I.content_charset, I.content_selection);
347 function view_mathml_source (window, charset, target) {
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, target, 'mathml');
355 function send_key_as_event (window, element, key) {
357 var event = window.document.createEvent ("KeyboardEvent");
363 key.modifiers & MOD_CTRL, // ctrl
364 key.modifiers & MOD_META, // alt
365 key.modifiers & MOD_SHIFT, // shift
366 key.modifiers & MOD_META, // meta
369 // bit of a hack here.. we have to fake a keydown event for conkeror
370 window.keyboard.last_key_down_event = copy_event (event);
372 return element.dispatchEvent (event);
374 return window.dispatchEvent (event);
380 send_key_as_event (I.window, I.buffer.focused_element, "return");