2 * (C) Copyright 2004-2007 Shawn Betts
3 * (C) Copyright 2007-2008 John J. Foerch
4 * (C) Copyright 2007-2008 Jeremy Maitin-Shepard
6 * Use, modification, and distribution are subject to the terms specified in the
10 function string_hashset() {}
12 string_hashset.prototype = {
13 constructor : string_hashset,
19 contains : function(s) {
20 return (("-" + s) in this);
23 remove : function (s) {
27 for_each : function (f) {
34 iterator : function () {
42 function string_hashmap() {
45 string_hashmap.prototype = {
46 constructor : string_hashmap,
48 put : function(s,value) {
49 this["-" + s] = value;
52 contains : function(s) {
53 return (("-" + s) in this);
56 get : function(s, default_value) {
62 get_put_default : function(s, default_value) {
65 return (this["-" + s] = default_value);
68 remove : function (s) {
72 for_each : function (f) {
75 f(i.slice(1), this[i]);
79 for_each_value : function (f) {
86 iterator: function (only_keys) {
88 for (let k in Iterator(this, true)) {
93 for (let [k,v] in Iterator(this, false)) {
101 /// Window title formatting
104 * Default tile formatter. The page url is ignored. If there is a
105 * page_title, returns: "Page title - Conkeror". Otherwise, it
106 * returns just: "Conkeror".
108 function default_title_formatter (window)
110 var page_title = window.buffers.current.title;
112 if (page_title && page_title.length > 0)
113 return page_title + " - Conkeror";
118 var title_format_fn = null;
120 function set_window_title (window)
122 window.document.title = title_format_fn(window);
125 function init_window_title ()
127 title_format_fn = default_title_formatter;
129 add_hook("window_initialize_late_hook", set_window_title);
130 add_hook("current_content_buffer_location_change_hook",
132 set_window_title(buffer.window);
134 add_hook("select_buffer_hook", function (buffer) { set_window_title(buffer.window); }, true);
135 add_hook("current_buffer_title_change_hook",
137 set_window_title(buffer.window);
141 init_window_title ();
146 // Put the string on the clipboard
147 function writeToClipboard(str)
149 const gClipboardHelper = Components.classes["@mozilla.org/widget/clipboardhelper;1"]
150 .getService(Components.interfaces.nsIClipboardHelper);
151 gClipboardHelper.copyString(str);
155 function makeURLAbsolute (base, url)
158 var ioService = Components.classes["@mozilla.org/network/io-service;1"]
159 .getService(Components.interfaces.nsIIOService);
160 var baseURI = ioService.newURI(base, null, null);
162 return ioService.newURI (baseURI.resolve (url), null, null).spec;
166 function get_link_location (element)
168 if (element && element.getAttribute("href")) {
169 var loc = element.getAttribute("href");
170 return makeURLAbsolute(element.baseURI, loc);
176 var io_service = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService2);
178 function make_uri(uri, charset, base_uri) {
179 if (uri instanceof Ci.nsIURI)
181 return io_service.newURI(uri, charset, base_uri);
184 var makeURL = make_uri; // until all callers are fixed
186 function makeFileURL(aFile)
188 return io_service.newFileURI(aFile).QueryInterface(Ci.nsIURL);
192 function get_document_content_disposition (document_o)
194 var content_disposition = null;
196 content_disposition =
197 document_o.defaultView
198 .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
199 .getInterface(Components.interfaces.nsIDOMWindowUtils)
200 .getDocumentMetadata("content-disposition");
202 return content_disposition;
206 function set_focus_no_scroll(window, element)
208 window.document.commandDispatcher.suppressFocusScroll = true;
210 window.document.commandDispatcher.suppressFocusScroll = false;
213 function do_repeatedly_positive(func, n) {
214 var args = Array.prototype.slice.call(arguments, 2);
216 func.apply(null, args);
219 function do_repeatedly(func, n, positive_args, negative_args) {
221 do func.apply(null, negative_args); while (++n < 0);
223 while (n-- > 0) func.apply(null, positive_args);
226 // remove whitespace from the beginning and end
227 function trim_whitespace (str)
229 var tmp = new String (str);
230 return tmp.replace (/^\s+/, "").replace (/\s+$/, "");
233 function abs_point (node)
238 pt.x = node.offsetLeft;
239 pt.y = node.offsetTop;
240 // find imagemap's coordinates
241 if (node.tagName == "AREA") {
242 var coords = node.getAttribute("coords").split(",");
243 pt.x += Number(coords[0]);
244 pt.y += Number(coords[1]);
247 node = node.offsetParent;
248 // Sometimes this fails, so just return what we got.
250 while (node.tagName != "BODY") {
251 pt.x += node.offsetLeft;
252 pt.y += node.offsetTop;
253 node = node.offsetParent;
257 // while (node.tagName != "BODY") {
258 // alert("okay: " + node + " " + node.tagName + " " + pt.x + " " + pt.y);
259 // node = node.offsetParent;
265 var xul_app_info = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo);
266 var xul_runtime = Cc['@mozilla.org/xre/app-info;1'].getService(Ci.nsIXULRuntime);
271 // possible return values: 'Darwin', 'Linux', 'WINNT', ...
272 return xul_runtime.OS;
275 var default_directory = null;
277 var env = Cc['@mozilla.org/process/environment;1'].getService(Ci.nsIEnvironment);
278 function getenv (variable) {
279 if (env.exists (variable))
280 return env.get(variable);
284 function set_default_directory(directory_s) {
287 if ( get_os() == "WINNT")
289 directory_s = getenv ('USERPROFILE') ||
290 getenv ('HOMEDRIVE') + getenv ('HOMEPATH');
293 directory_s = getenv ('HOME');
297 default_directory = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
298 default_directory.initWithPath (directory_s);
301 set_default_directory();
303 const XHTML_NS = "http://www.w3.org/1999/xhtml";
304 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
305 const MATHML_NS = "http://www.w3.org/1998/Math/MathML";
306 const XLINK_NS = "http://www.w3.org/1999/xlink";
308 function create_XUL(window, tag_name)
310 return window.document.createElementNS(XUL_NS, tag_name);
314 /* Used in calls to XPath evaluate */
315 function xpath_lookup_namespace(prefix) {
316 if (prefix == "xhtml")
325 function method_caller(obj, func) {
327 func.apply(obj, arguments);
331 function shell_quote(str) {
332 var s = str.replace("\"", "\\\"", "g");
333 s = s.replace("$", "\$", "g");
337 function get_window_from_frame(frame) {
339 var window = frame.QueryInterface(Ci.nsIInterfaceRequestor)
340 .getInterface(Ci.nsIWebNavigation)
341 .QueryInterface(Ci.nsIDocShellTreeItem)
343 .QueryInterface(Ci.nsIInterfaceRequestor)
344 .getInterface(Ci.nsIDOMWindow).wrappedJSObject;
345 /* window is now an XPCSafeJSObjectWrapper */
346 window.escape_wrapper(function (w) { window = w; });
347 /* window is now completely unwrapped */
354 function get_buffer_from_frame(window, frame) {
355 var count = window.buffers.count;
356 for (var i = 0; i < count; ++i) {
357 var b = window.buffers.get_buffer(i);
358 if (b.top_frame == frame)
364 var file_locator = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
366 function get_shortdoc_string(doc) {
369 var idx = doc.indexOf("\n");
371 shortdoc = doc.substring(0,idx);
378 var conkeror_source_code_path = null;
380 function source_code_reference(uri, line_number) {
382 this.line_number = line_number;
384 source_code_reference.prototype = {
386 if (this.uri.indexOf(module_uri_prefix) == 0)
387 return this.uri.substring(module_uri_prefix.length);
392 var file_uri_prefix = "file://";
393 if (this.uri.indexOf(file_uri_prefix) == 0)
394 return this.uri.substring(file_uri_prefix.length);
399 if (conkeror_source_code_path != null) {
400 var module_name = this.module_name;
401 if (module_name != null)
402 return "file://" + conkeror_source_code_path + "/modules/" + module_name;
407 open_in_editor : function() {
408 yield open_with_external_editor(this.best_uri, $line = this.line_number);
412 var get_caller_source_code_reference_ignored_functions = {};
414 function get_caller_source_code_reference(extra_frames_back) {
415 /* Skip at least this function itself and whoever called it (and
416 * more if the caller wants to be skipped). */
417 var frames_to_skip = 2;
418 if (extra_frames_back != null)
419 frames_to_skip += extra_frames_back;
421 for (let f = Components.stack; f != null; f = f.caller) {
422 if (frames_to_skip > 0) {
426 if (get_caller_source_code_reference_ignored_functions[f.name])
428 return new source_code_reference(f.filename, f.lineNumber);
434 function ignore_function_for_get_caller_source_code_reference(func_name) {
435 get_caller_source_code_reference_ignored_functions[func_name] = 1;
438 require_later("external-editor.js");
440 function dom_generator(document, ns) {
441 this.document = document;
444 dom_generator.prototype = {
445 element : function(tag, parent) {
446 var node = this.document.createElementNS(this.ns, tag);
448 if (parent != null && (parent instanceof Ci.nsIDOMNode)) {
449 parent.appendChild(node);
452 for (; i < arguments.length; i += 2)
453 node.setAttribute(arguments[i], arguments[i+1]);
457 text : function(str, parent) {
458 var node = this.document.createTextNode(str);
460 parent.appendChild(node);
465 stylesheet_link : function(href, parent) {
466 var node = this.element("link");
467 node.setAttribute("rel", "stylesheet");
468 node.setAttribute("type", "text/css");
469 node.setAttribute("href", href);
471 parent.appendChild(node);
476 add_stylesheet : function (url) {
477 var head = this.document.documentElement.firstChild;
478 this.stylesheet_link(url, head);
483 * Generates a QueryInterface function suitable for an implemenation
484 * of an XPCOM interface. Unlike XPCOMUtils, this uses the Function
485 * constructor to generate a slightly more efficient version. The
486 * arguments can be either Strings or elements of
487 * Components.interfaces.
489 function generate_QI() {
490 var args = Array.prototype.slice.call(arguments).map(String).concat(["nsISupports"]);
492 Array.prototype.map.call(args,
494 "iid.equals(Components.interfaces." + x + ")")
496 ") return this; throw Components.results.NS_ERROR_NO_INTERFACE;";
497 return new Function("iid", fstr);
500 function set_branch_pref(branch, name, value) {
501 if (typeof(value) == "string") {
502 branch.setCharPref(name, value);
503 } else if (typeof(value) == "number") {
504 branch.setIntPref(name, value);
505 } else if (typeof(value) == "boolean") {
506 branch.setBoolPref(name, value);
510 function default_pref(name, value) {
511 var branch = preferences.getDefaultBranch(null);
512 set_branch_pref(branch, name, value);
515 function user_pref(name, value) {
516 var branch = preferences.getBranch(null);
517 set_branch_pref(branch, name, value);
520 function get_branch_pref(branch, name) {
521 switch (branch.getPrefType(name)) {
522 case branch.PREF_STRING:
523 return branch.getCharPref(name);
524 case branch.PREF_INT:
525 return branch.getIntPref(name);
526 case branch.PREF_BOOL:
527 return branch.getBoolPref(name);
533 function get_localized_pref(name) {
535 return preferences.getBranch(null).getComplexValue(name, Ci.nsIPrefLocalizedString).data;
541 function get_pref(name) {
542 var branch = preferences.getBranch(null);
543 return get_branch_pref(branch, name);
546 function get_default_pref(name) {
547 var branch = preferences.getDefaultBranch(null);
548 return get_branch_pref(branch, name);
551 function clear_pref(name) {
552 var branch = preferences.getBranch(null);
553 return branch.clearUserPref(name);
556 function pref_has_user_value(name) {
557 var branch = preferences.getBranch(null);
558 return branch.prefHasUserValue(name);
561 function pref_has_default_value(name) {
562 var branch = preferences.getDefaultBranch(null);
563 return branch.prefHasUserValue(name);
566 function session_pref (name, value) {
567 try { clear_pref (name); }
569 return default_pref (name, value);
572 const LOCALE_PREF = "general.useragent.locale";
574 function get_locale() {
575 return get_localized_pref(LOCALE_PREF) || get_pref(LOCALE_PREF);
578 const USER_AGENT_OVERRIDE_PREF = "general.useragent.override";
580 function set_user_agent(str) {
581 session_pref(USER_AGENT_OVERRIDE_PREF, str);
584 function define_builtin_commands(prefix, do_command_function, toggle_mark, mark_active_predicate) {
586 // Specify a docstring
587 function D(cmd, docstring) {
588 var o = new String(cmd);
593 // Specify a forward/reverse pair
596 o.is_reverse_pair = true;
600 // Specify a movement/select command pair.
601 function S(command, movement, select) {
602 var o = [movement, select];
604 o.is_move_select_pair = true;
608 var builtin_commands = [
609 S(D("beginning-of-line", "Move or extend the selection to the beginning of the current line."),
610 D("cmd_beginLine", "Move point to the beginning of the current line."),
611 D("cmd_selectBeginLine", "Extend selection to the beginning of the current line.")),
612 S(D("end-of-line", "Move or extend the selection to the end of the current line."),
613 D("cmd_endLine", "Move point to the end of the current line."),
614 D("cmd_selectEndLine", "Extend selection to the end of the current line.")),
615 D("cmd_copy", "Copy the selection into the clipboard."),
617 D("cmd_cut", "Cut the selection into the clipboard."),
619 D("cmd_deleteToBeginningOfLine", "Delete to the beginning of the current line."),
620 D("cmd_deleteToEndOfLine", "Delete to the end of the current line."),
621 S(D("beginning-of-first-line", "Move or extend the selection to the beginning of the first line."),
622 D("cmd_moveTop", "Move point to the beginning of the first line."),
623 D("cmd_selectTop", "Extend selection to the beginning of the first line.")),
624 S(D("end-of-last-line", "Move or extend the selection to the end of the last line."),
625 D("cmd_moveBottom", "Move point to the end of the last line."),
626 D("cmd_selectBottom", "Extend selection to the end of the last line.")),
627 D("cmd_selectAll", "Select all."),
628 "cmd_scrollBeginLine",
630 D("cmd_scrollTop", "Scroll to the top of the buffer."),
631 D("cmd_scrollBottom", "Scroll to the bottom of the buffer.")];
633 var builtin_commands_with_count = [
634 R(S(D("forward-char", "Move or extend the selection forward one character."),
635 D("cmd_charNext", "Move point forward one character."),
636 D("cmd_selectCharNext", "Extend selection forward one character.")),
637 S(D("backward-char", "Move or extend the selection backward one character."),
638 D("cmd_charPrevious", "Move point backward one character."),
639 D("cmd_selectCharPrevious", "Extend selection backward one character."))),
640 R(D("cmd_deleteCharForward", "Delete the following character."),
641 D("cmd_deleteCharBackward", "Delete the previous character.")),
642 R(D("cmd_deleteWordForward", "Delete the following word."),
643 D("cmd_deleteWordBackward", "Delete the previous word.")),
644 R(S(D("forward-line", "Move or extend the selection forward one line."),
645 D("cmd_lineNext", "Move point forward one line."),
646 "cmd_selectLineNext", "Extend selection forward one line."),
647 S(D("backward-line", "Move or extend the selection backward one line."),
648 D("cmd_linePrevious", "Move point backward one line."),
649 D("cmd_selectLinePrevious", "Extend selection backward one line."))),
650 R(S(D("forward-page", "Move or extend the selection forward one page."),
651 D("cmd_movePageDown", "Move point forward one page."),
652 D("cmd_selectPageDown", "Extend selection forward one page.")),
653 S(D("backward-page", "Move or extend the selection backward one page."),
654 D("cmd_movePageUp", "Move point backward one page."),
655 D("cmd_selectPageUp", "Extend selection backward one page."))),
656 R(D("cmd_undo", "Undo last editing action."),
657 D("cmd_redo", "Redo last editing action.")),
658 R(S(D("forward-word", "Move or extend the selection forward one word."),
659 D("cmd_wordNext", "Move point forward one word."),
660 D("cmd_selectWordNext", "Extend selection forward one word.")),
661 S(D("backward-word", "Move or extend the selection backward one word."),
662 D("cmd_wordPrevious", "Move point backward one word."),
663 D("cmd_selectWordPrevious", "Extend selection backward one word."))),
664 R(D("cmd_scrollPageUp", "Scroll up one page."),
665 D("cmd_scrollPageDown", "Scroll down one page.")),
666 R(D("cmd_scrollLineUp", "Scroll up one line."),
667 D("cmd_scrollLineDown", "Scroll down one line.")),
668 R(D("cmd_scrollLeft", "Scroll left."),
669 D("cmd_scrollRight", "Scroll right.")),
670 D("cmd_paste", "Insert the contents of the clipboard.")];
672 interactive(prefix + "set-mark",
673 "Toggle whether the mark is active.\n" +
674 "When the mark is active, movement commands affect the selection.",
677 function doc_for_builtin(c) {
681 return s + "Run the built-in command " + c + ".";
684 function define_simple_command(c) {
685 interactive(prefix + c, doc_for_builtin(c), function (I) { do_command_function(I, c); });
688 function get_move_select_doc_string(c) {
689 return c.command.doc +
690 "\nSpecifically, if the mark is inactive, runs `" + prefix + c[0] + "'. " +
691 "Otherwise, runs `" + prefix + c[1] + "'.\n" +
692 "To toggle whether the mark is active, use `" + prefix + "set-mark'.";
695 for each (let c_temp in builtin_commands) {
697 if (c.is_move_select_pair) {
698 interactive(prefix + c.command, get_move_select_doc_string(c), function (I) {
699 do_command_function(I, mark_active_predicate(I) ? c[1] : c[0]);
701 define_simple_command(c[0]);
702 define_simple_command(c[1]);
705 define_simple_command(c);
708 function get_reverse_pair_doc_string(main_doc, alt_command) {
709 return main_doc + "\n" +
710 "The prefix argument specifies a repeat count for this command. " +
711 "If the count is negative, `" + prefix + alt_command + "' is performed instead with " +
712 "a corresponding positive repeat count.";
715 function define_simple_reverse_pair(a, b) {
716 interactive(prefix + a, get_reverse_pair_doc_string(doc_for_builtin(a), b),
718 do_repeatedly(do_command_function, I.p, [I, a], [I, b]);
720 interactive(prefix + b, get_reverse_pair_doc_string(doc_for_builtin(b), a),
722 do_repeatedly(do_command_function, I.p, [I, b], [I, a]);
726 for each (let c_temp in builtin_commands_with_count)
729 if (c.is_reverse_pair) {
730 if (c[0].is_move_select_pair) {
731 interactive(prefix + c[0].command, get_reverse_pair_doc_string(get_move_select_doc_string(c[0]),
734 var idx = mark_active_predicate(I) ? 1 : 0;
735 do_repeatedly(do_command_function, I.p, [I, c[0][idx]], [I, c[1][idx]]);
737 interactive(prefix + c[1].command, get_reverse_pair_doc_string(get_move_select_doc_string(c[1]),
740 var idx = mark_active_predicate(I) ? 1 : 0;
741 do_repeatedly(do_command_function, I.p, [I, c[1][idx]], [I, c[0][idx]]);
743 define_simple_reverse_pair(c[0][0], c[1][0]);
744 define_simple_reverse_pair(c[0][1], c[1][1]);
746 define_simple_reverse_pair(c[0], c[1]);
748 let doc = doc_for_builtin(c) +
749 "\nThe prefix argument specifies a positive repeat count for this command.";
750 interactive(prefix + c, doc, function (I) {
751 do_repeatedly_positive(do_command_function, I.p, I, c);
757 var observer_service = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
759 function abort(str) {
760 var e = new Error(str);
761 e.__proto__ = abort.prototype;
764 abort.prototype.__proto__ = Error.prototype;
767 function get_temporary_file(name) {
770 var file = file_locator.get("TmpD", Ci.nsIFile);
772 // Create the file now to ensure that no exploits are possible
773 file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0600);
778 /* FIXME: This should be moved somewhere else, perhaps. */
779 function create_info_panel(window, panel_class, row_arr) {
780 /* Show information panel above minibuffer */
782 var g = new dom_generator(window.document, XUL_NS);
784 var p = g.element("vbox", "class", "panel " + panel_class, "flex", "0");
785 var grid = g.element("grid", p);
786 var cols = g.element("columns", grid);
787 g.element("column", cols, "flex", "0");
788 g.element("column", cols, "flex", "1");
790 var rows = g.element("rows", grid);
793 for each (let [row_class, row_label, row_value] in row_arr) {
794 row = g.element("row", rows, "class", row_class);
795 g.element("label", row,
797 "class", "panel-row-label");
798 g.element("label", row,
800 "class", "panel-row-value");
802 window.minibuffer.insert_before(p);
804 p.destroy = function () {
805 this.parentNode.removeChild(this);
812 // read_from_x_primary_selection favors the X PRIMARY SELECTION, when
813 // it exists. The builtin cmd_paste always uses X CLIPBOARD. So this
814 // is an auxiliary utility, in case you need to work with the primary
817 function read_from_x_primary_selection ()
820 var clipboard = Components.classes["@mozilla.org/widget/clipboard;1"]
821 .getService(Components.interfaces.nsIClipboard);
823 // Create tranferable that will transfer the text.
824 var trans = Components.classes["@mozilla.org/widget/transferable;1"]
825 .createInstance(Components.interfaces.nsITransferable);
827 trans.addDataFlavor("text/unicode");
828 // If available, use selection clipboard, otherwise global one
829 if (clipboard.supportsSelectionClipboard())
830 clipboard.getData(trans, clipboard.kSelectionClipboard);
832 clipboard.getData(trans, clipboard.kGlobalClipboard);
836 trans.getTransferData("text/unicode", data, dataLen);
839 data = data.value.QueryInterface(Components.interfaces.nsISupportsString);
840 return data.data.substring(0, dataLen.value / 2);
846 var user_variables = new string_hashmap();
848 function define_variable(name, default_value, doc) {
849 conkeror[name] = default_value;
850 user_variables.put(name, {
851 default_value: default_value,
853 shortdoc: get_shortdoc_string(doc),
854 source_code_reference: get_caller_source_code_reference() });
858 function register_user_stylesheet(url)
860 var uri = makeURL(url);
861 var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
862 sss.loadAndRegisterSheet(uri, sss.USER_SHEET);
865 function unregister_user_stylesheet(url)
867 var uri = makeURL(url);
868 var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
869 if (sss.sheetRegistered(uri, sss.USER_SHEET))
870 ss.unregisterSheet(uri, sss.USER_SHEET);
873 function predicate_alist_match(alist, key) {
874 for each (let i in alist) {
882 function get_meta_title(doc) {
883 var title = doc.evaluate("//meta[@name='title']/@content", doc, xpath_lookup_namespace,
884 Ci.nsIDOMXPathResult.STRING_TYPE , null);
885 if (title && title.stringValue)
886 return title.stringValue;
890 var rdf_service = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService);
892 const PREFIX_ITEM_URI = "urn:mozilla:item:";
893 const PREFIX_NS_EM = "http://www.mozilla.org/2004/em-rdf#";
895 var extension_manager = Cc["@mozilla.org/extensions/manager;1"].getService(Ci.nsIExtensionManager);
897 function get_extension_rdf_property(id, name, type) {
898 var value = extension_manager.datasource.GetTarget(
899 rdf_service.GetResource(PREFIX_ITEM_URI + id),
900 rdf_service.GetResource(PREFIX_NS_EM + name),
904 return value.QueryInterface(type || Ci.nsIRDFLiteral).Value;
907 function get_extension_update_item(id) {
908 return extension_manager.getItemForID(id);
911 function extension_info(id) {
914 extension_info.prototype = {
915 // Returns the nsIUpdateItem object associated with this extension
916 get update_item () { return get_extension_update_item(this.id); },
918 get_rdf_property : function (name, type) {
919 return get_extension_rdf_property(this.id, name, type);
923 get isDisabled () { return this.get_rdf_property("isDisabled"); },
924 get aboutURL () { return this.get_rdf_property("aboutURL"); },
925 get addonID () { return this.get_rdf_property("addonID"); },
926 get availableUpdateURL () { return this.get_rdf_property("availableUpdateURL"); },
927 get availableUpdateVersion () { return this.get_rdf_property("availableUpdateVersion"); },
928 get blocklisted () { return this.get_rdf_property("blocklisted"); },
929 get compatible () { return this.get_rdf_property("compatible"); },
930 get description () { return this.get_rdf_property("description"); },
931 get downloadURL () { return this.get_rdf_property("downloadURL"); },
932 get isDisabled () { return this.get_rdf_property("isDisabled"); },
933 get hidden () { return this.get_rdf_property("hidden"); },
934 get homepageURL () { return this.get_rdf_property("homepageURL"); },
935 get iconURL () { return this.get_rdf_property("iconURL"); },
936 get internalName () { return this.get_rdf_property("internalName"); },
937 get locked () { return this.get_rdf_property("locked"); },
938 get name () { return this.get_rdf_property("name"); },
939 get optionsURL () { return this.get_rdf_property("optionsURL"); },
940 get opType () { return this.get_rdf_property("opType"); },
941 get plugin () { return this.get_rdf_property("plugin"); },
942 get previewImage () { return this.get_rdf_property("previewImage"); },
943 get satisfiesDependencies () { return this.get_rdf_property("satisfiesDependencies"); },
944 get providesUpdatesSecurely () { return this.get_rdf_property("providesUpdatesSecurely"); },
945 get type () { return this.get_rdf_property("type", Ci.nsIRDFInt); },
946 get updateable () { return this.get_rdf_property("updateable"); },
947 get updateURL () { return this.get_rdf_property("updateURL"); },
948 get version () { return this.get_rdf_property("version"); }
951 function extension_is_enabled(id) {
952 var info = new extension_info(id);
953 return info.update_item && (info.isDisabled == "false");
956 function for_each_frame(root_frame, callback, start_with) {
958 callback(start_with);
963 for (let i = 0; i < f.frames.length; ++i) {
970 // Co-routine version of for_each_frame
971 function co_for_each_frame(root_frame, callback, start_with) {
973 yield callback(start_with);
978 for (let i = 0; i < f.frames.length; ++i) {
979 yield helper(f.frames[i]);
982 yield helper(root_frame);
985 function xml_http_request() {
986 return Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest).QueryInterface(Ci.nsIJSXMLHttpRequest).QueryInterface(Ci.nsIDOMEventTarget);
989 var xml_http_request_load_listener = {
990 // nsIBadCertListener2
991 notifyCertProblem: function SSLL_certProblem(socketInfo, status, targetSite) {
995 // nsISSLErrorListener
996 notifySSLError: function SSLL_SSLError(socketInfo, error, targetSite) {
1000 // nsIInterfaceRequestor
1001 getInterface: function SSLL_getInterface(iid) {
1002 return this.QueryInterface(iid);
1007 // FIXME: array comprehension used here to hack around the lack of
1008 // Ci.nsISSLErrorListener in 2007 versions of xulrunner 1.9pre.
1009 // make it a simple generateQI when xulrunner is more stable.
1010 QueryInterface: XPCOMUtils.generateQI (
1011 [i for each (i in [Ci.nsIBadCertListener2,
1012 Ci.nsISSLErrorListener,
1013 Ci.nsIInterfaceRequestor])
1018 define_keywords("$user", "$password", "$override_mime_type", "$headers");
1019 function send_http_request(lspec) {
1020 keywords(arguments, $user = undefined, $password = undefined,
1021 $override_mime_type = undefined, $headers = undefined);
1022 var req = xml_http_request();
1023 var cc = yield CONTINUATION;
1024 var aborting = false;
1025 req.onreadystatechange = function send_http_request__onreadysatechange() {
1026 if (req.readyState != 4)
1033 if (arguments.$override_mime_type)
1034 req.overrideMimeType(arguments.$override_mime_type);
1036 var post_data = load_spec_raw_post_data(lspec);
1038 var method = post_data ? "POST" : "GET";
1040 req.open(method, load_spec_uri_string(lspec), true, arguments.$user, arguments.$password);
1041 req.channel.notificationCallbacks = xml_http_request_load_listener;
1043 for each (let [name,value] in arguments.$headers) {
1044 req.setRequestHeader(name, value);
1048 req.setRequestHeader("Content-Type", load_spec_request_mime_type(lspec));
1049 req.send(post_data);
1061 // Let the caller access the status and reponse data
1062 yield co_return(req);
1066 var JSON = ("@mozilla.org/dom/json;1" in Cc) && Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
1070 var console_service = Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService);
1072 console_service.registerListener(
1073 {observe: function (msg) {
1074 if (msg instanceof Ci.nsIScriptError) {
1075 switch (msg.category) {
1077 case "content javascript":
1080 msg.QueryInterface(Ci.nsIScriptError);
1081 dumpln("Console error: " + msg.message);
1082 dumpln(" Category: " + msg.category);
1087 // ensure_index_is_visible ensures that the given index in the given
1088 // field (an html input field for example) is visible.
1089 function ensure_index_is_visible (window, field, index) {
1090 var start = field.selectionStart;
1091 var end = field.selectionEnd;
1092 field.setSelectionRange (index, index);
1093 send_key_as_event (window, field, "left");
1094 if (field.selectionStart < index) {
1095 send_key_as_event (window, field, "right");
1097 field.setSelectionRange (start, end);