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 *****/
32 * Utility functions for application scope.
37 function string_hashset() {
40 string_hashset.prototype = {
41 constructor : string_hashset,
47 contains : function(s) {
48 return (("-" + s) in this);
51 remove : function (s) {
55 for_each : function (f) {
63 function string_hashmap() {
66 string_hashmap.prototype = {
67 constructor : string_hashmap,
69 put : function(s,value) {
70 this["-" + s] = value;
73 contains : function(s) {
74 return (("-" + s) in this);
77 get : function(s, default_value) {
83 get_put_default : function(s, default_value) {
86 return (this["-" + s] = default_value);
89 remove : function (s) {
93 for_each : function (f) {
96 f(i.slice(1), this[i]);
100 for_each_value : function (f) {
101 for (var i in this) {
108 /// Window title formatting
111 * Default tile formatter. The page url is ignored. If there is a
112 * page_title, returns: "Page title - Conkeror". Otherwise, it
113 * returns just: "Conkeror".
115 function default_title_formatter (window)
117 var page_title = window.buffers.current.title;
119 if (page_title && page_title.length > 0)
120 return page_title + " - Conkeror";
125 var title_format_fn = null;
127 function set_window_title (window)
129 window.document.title = title_format_fn(window);
132 function init_window_title ()
134 title_format_fn = default_title_formatter;
136 add_hook("window_initialize_late_hook", set_window_title);
137 add_hook("current_content_buffer_location_change_hook",
139 set_window_title(buffer.window);
141 add_hook("select_buffer_hook", function (buffer) { set_window_title(buffer.window); }, true);
142 add_hook("current_buffer_title_change_hook",
144 set_window_title(buffer.window);
148 init_window_title ();
153 // Put the string on the clipboard
154 function writeToClipboard(str)
156 const gClipboardHelper = Components.classes["@mozilla.org/widget/clipboardhelper;1"]
157 .getService(Components.interfaces.nsIClipboardHelper);
158 gClipboardHelper.copyString(str);
162 function makeURLAbsolute (base, url)
165 var ioService = Components.classes["@mozilla.org/network/io-service;1"]
166 .getService(Components.interfaces.nsIIOService);
167 var baseURI = ioService.newURI(base, null, null);
169 return ioService.newURI (baseURI.resolve (url), null, null).spec;
173 function get_link_location (element)
175 if (element && element.getAttribute("href")) {
176 var loc = element.getAttribute("href");
177 return makeURLAbsolute(element.baseURI, loc);
183 var io_service = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
185 function make_uri(uri, charset, base_uri) {
186 if (uri instanceof Ci.nsIURI)
188 return io_service.newURI(uri, charset, base_uri);
191 var makeURL = make_uri; // until all callers are fixed
193 function makeFileURL(aFile)
195 return io_service.newFileURI(aFile).QueryInterface(Ci.nsIURL);
199 function get_document_content_disposition (document_o)
201 var content_disposition = null;
203 content_disposition =
204 document_o.defaultView
205 .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
206 .getInterface(Components.interfaces.nsIDOMWindowUtils)
207 .getDocumentMetadata("content-disposition");
209 return content_disposition;
213 function set_focus_no_scroll(window, element)
215 window.document.commandDispatcher.suppressFocusScroll = true;
217 window.document.commandDispatcher.suppressFocusScroll = false;
220 function do_repeatedly_positive(func, n) {
221 var args = Array.prototype.slice.call(arguments, 2);
223 func.apply(null, args);
226 function do_repeatedly(func, n, positive_args, negative_args) {
228 do func.apply(null, negative_args); while (++n < 0);
230 while (n-- > 0) func.apply(null, positive_args);
233 // remove whitespace from the beginning and end
234 function trim_whitespace (str)
236 var tmp = new String (str);
237 return tmp.replace (/^\s+/, "").replace (/\s+$/, "");
240 function abs_point (node)
245 pt.x = node.offsetLeft;
246 pt.y = node.offsetTop;
247 // find imagemap's coordinates
248 if (node.tagName == "AREA") {
249 var coords = node.getAttribute("coords").split(",");
250 pt.x += Number(coords[0]);
251 pt.y += Number(coords[1]);
254 node = node.offsetParent;
255 // Sometimes this fails, so just return what we got.
257 while (node.tagName != "BODY") {
258 pt.x += node.offsetLeft;
259 pt.y += node.offsetTop;
260 node = node.offsetParent;
264 // while (node.tagName != "BODY") {
265 // alert("okay: " + node + " " + node.tagName + " " + pt.x + " " + pt.y);
266 // node = node.offsetParent;
272 var xul_app_info = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo);
273 var xul_runtime = Cc['@mozilla.org/xre/app-info;1'].getService(Ci.nsIXULRuntime);
278 // possible return values: 'Darwin', 'Linux', 'WINNT', ...
279 return xul_runtime.OS;
282 var default_directory = null;
284 var env = Cc['@mozilla.org/process/environment;1'].getService(Ci.nsIEnvironment);
285 function getenv (variable) {
286 if (env.exists (variable))
287 return env.get(variable);
291 function set_default_directory(directory_s) {
294 if ( get_os() == "WINNT")
296 directory_s = getenv ('USERPROFILE') ||
297 getenv ('HOMEDRIVE') + getenv ('HOMEPATH');
300 directory_s = getenv ('HOME');
304 default_directory = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
305 default_directory.initWithPath (directory_s);
308 set_default_directory();
310 const XHTML_NS = "http://www.w3.org/1999/xhtml";
311 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
312 const MATHML_NS = "http://www.w3.org/1998/Math/MathML";
313 const XLINK_NS = "http://www.w3.org/1999/xlink";
315 function create_XUL(window, tag_name)
317 return window.document.createElementNS(XUL_NS, tag_name);
321 /* Used in calls to XPath evaluate */
322 function xpath_lookup_namespace(prefix) {
323 if (prefix == "xhtml")
332 function method_caller(obj, func) {
334 func.apply(obj, arguments);
338 function shell_quote(str) {
339 var s = str.replace("\"", "\\\"", "g");
340 s = s.replace("$", "\$", "g");
344 function get_window_from_frame(frame) {
346 var window = frame.QueryInterface(Ci.nsIInterfaceRequestor)
347 .getInterface(Ci.nsIWebNavigation)
348 .QueryInterface(Ci.nsIDocShellTreeItem)
350 .QueryInterface(Ci.nsIInterfaceRequestor)
351 .getInterface(Ci.nsIDOMWindow).wrappedJSObject;
352 /* window is now an XPCSafeJSObjectWrapper */
353 window.escape_wrapper(function (w) { window = w; });
354 /* window is now completely unwrapped */
361 function get_buffer_from_frame(window, frame) {
362 var count = window.buffers.count;
363 for (var i = 0; i < count; ++i) {
364 var b = window.buffers.get_buffer(i);
365 if (b.top_frame == frame)
371 var file_locator = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
373 function get_shortdoc_string(doc) {
376 var idx = doc.indexOf("\n");
378 shortdoc = doc.substring(0,idx);
385 var conkeror_source_code_path = null;
387 function source_code_reference(uri, line_number) {
389 this.line_number = line_number;
391 source_code_reference.prototype = {
393 if (this.uri.indexOf(module_uri_prefix) == 0)
394 return this.uri.substring(module_uri_prefix.length);
399 var file_uri_prefix = "file://";
400 if (this.uri.indexOf(file_uri_prefix) == 0)
401 return this.uri.substring(file_uri_prefix.length);
406 if (conkeror_source_code_path != null) {
407 var module_name = this.module_name;
408 if (module_name != null)
409 return "file://" + conkeror_source_code_path + "/modules/" + module_name;
414 open_in_editor : function() {
415 yield open_with_external_editor(this.best_uri, $line = this.line_number);
419 var get_caller_source_code_reference_ignored_functions = {};
421 function get_caller_source_code_reference(extra_frames_back) {
422 /* Skip at least this function itself and whoever called it (and
423 * more if the caller wants to be skipped). */
424 var frames_to_skip = 2;
425 if (extra_frames_back != null)
426 frames_to_skip += extra_frames_back;
428 for (let f = Components.stack; f != null; f = f.caller) {
429 if (frames_to_skip > 0) {
433 if (get_caller_source_code_reference_ignored_functions[f.name])
435 return new source_code_reference(f.filename, f.lineNumber);
441 function ignore_function_for_get_caller_source_code_reference(func_name) {
442 get_caller_source_code_reference_ignored_functions[func_name] = 1;
445 require_later("external-editor.js");
447 function dom_generator(document, ns) {
448 this.document = document;
451 dom_generator.prototype = {
452 element : function(tag, parent) {
453 var node = this.document.createElementNS(this.ns, tag);
455 if (parent != null && (parent instanceof Ci.nsIDOMNode)) {
456 parent.appendChild(node);
459 for (; i < arguments.length; i += 2)
460 node.setAttribute(arguments[i], arguments[i+1]);
464 text : function(str, parent) {
465 var node = this.document.createTextNode(str);
467 parent.appendChild(node);
472 stylesheet_link : function(href, parent) {
473 var node = this.element("link");
474 node.setAttribute("rel", "stylesheet");
475 node.setAttribute("type", "text/css");
476 node.setAttribute("href", href);
478 parent.appendChild(node);
483 add_stylesheet : function (url) {
484 var head = this.document.documentElement.firstChild;
485 this.stylesheet_link(url, head);
490 * Generates a QueryInterface function suitable for an implemenation
491 * of an XPCOM interface. Unlike XPCOMUtils, this uses the Function
492 * constructor to generate a slightly more efficient version. The
493 * arguments can be either Strings or elements of
494 * Components.interfaces.
496 function generate_QI() {
497 var args = Array.prototype.slice.call(arguments).map(String).concat(["nsISupports"]);
499 Array.prototype.map.call(args,
501 "iid.equals(Components.interfaces." + x + ")")
503 ") return this; throw Components.results.NS_ERROR_NO_INTERFACE;";
504 return new Function("iid", fstr);
507 function set_branch_pref(branch, name, value) {
508 if (typeof(value) == "string") {
509 branch.setCharPref(name, value);
510 } else if (typeof(value) == "number") {
511 branch.setIntPref(name, value);
512 } else if (typeof(value) == "boolean") {
513 branch.setBoolPref(name, value);
517 function default_pref(name, value) {
518 var branch = preferences.getDefaultBranch(null);
519 set_branch_pref(branch, name, value);
522 function user_pref(name, value) {
523 var branch = preferences.getBranch(null);
524 set_branch_pref(branch, name, value);
527 function get_branch_pref(branch, name) {
528 switch (branch.getPrefType(name)) {
529 case branch.PREF_STRING:
530 return branch.getCharPref(name);
531 case branch.PREF_INT:
532 return branch.getIntPref(name);
533 case branch.PREF_BOOL:
534 return branch.getBoolPref(name);
540 function get_localized_pref(name) {
542 return preferences.getBranch(null).getComplexValue(name, Ci.nsIPrefLocalizedString).data;
548 function get_pref(name) {
549 var branch = preferences.getBranch(null);
550 return get_branch_pref(branch, name);
553 function get_default_pref(name) {
554 var branch = preferences.getDefaultBranch(null);
555 return get_branch_pref(branch, name);
558 function clear_pref(name) {
559 var branch = preferences.getBranch(null);
560 return branch.clearUserPref(name);
563 function pref_has_user_value(name) {
564 var branch = preferences.getBranch(null);
565 return branch.prefHasUserValue(name);
568 function pref_has_default_value(name) {
569 var branch = preferences.getDefaultBranch(null);
570 return branch.prefHasUserValue(name);
573 function session_pref (name, value) {
574 try { clear_pref (name); }
576 return default_pref (name, value);
579 const LOCALE_PREF = "general.useragent.locale";
581 function get_locale() {
582 return get_localized_pref(LOCALE_PREF) || get_pref(LOCALE_PREF);
585 const USER_AGENT_OVERRIDE_PREF = "general.useragent.override";
587 function set_user_agent(str) {
588 session_pref(USER_AGENT_OVERRIDE_PREF, str);
591 function define_builtin_commands(prefix, do_command_function, toggle_mark, mark_active_predicate) {
593 // Specify a docstring
594 function D(cmd, docstring) {
595 var o = new String(cmd);
600 // Specify a forward/reverse pair
603 o.is_reverse_pair = true;
607 // Specify a movement/select command pair.
608 function S(command, movement, select) {
609 var o = [movement, select];
611 o.is_move_select_pair = true;
615 var builtin_commands = [
616 S(D("beginning-of-line", "Move or extend the selection to the beginning of the current line."),
617 D("cmd_beginLine", "Move point to the beginning of the current line."),
618 D("cmd_selectBeginLine", "Extend selection to the beginning of the current line.")),
619 S(D("end-of-line", "Move or extend the selection to the end of the current line."),
620 D("cmd_endLine", "Move point to the end of the current line."),
621 D("cmd_selectEndLine", "Extend selection to the end of the current line.")),
622 D("cmd_copy", "Copy the selection into the clipboard."),
624 D("cmd_cut", "Cut the selection into the clipboard."),
626 D("cmd_deleteToBeginningOfLine", "Delete to the beginning of the current line."),
627 D("cmd_deleteToEndOfLine", "Delete to the end of the current line."),
628 S(D("beginning-of-first-line", "Move or extend the selection to the beginning of the first line."),
629 D("cmd_moveTop", "Move point to the beginning of the first line."),
630 D("cmd_selectTop", "Extend selection to the beginning of the first line.")),
631 S(D("end-of-last-line", "Move or extend the selection to the end of the last line."),
632 D("cmd_moveBottom", "Move point to the end of the last line."),
633 D("cmd_selectBottom", "Extend selection to the end of the last line.")),
634 D("cmd_selectAll", "Select all."),
635 "cmd_scrollBeginLine",
637 D("cmd_scrollTop", "Scroll to the top of the buffer."),
638 D("cmd_scrollBottom", "Scroll to the bottom of the buffer.")];
640 var builtin_commands_with_count = [
641 R(S(D("forward-char", "Move or extend the selection forward one character."),
642 D("cmd_charNext", "Move point forward one character."),
643 D("cmd_selectCharNext", "Extend selection forward one character.")),
644 S(D("backward-char", "Move or extend the selection backward one character."),
645 D("cmd_charPrevious", "Move point backward one character."),
646 D("cmd_selectCharPrevious", "Extend selection backward one character."))),
647 R(D("cmd_deleteCharForward", "Delete the following character."),
648 D("cmd_deleteCharBackward", "Delete the previous character.")),
649 R(D("cmd_deleteWordForward", "Delete the following word."),
650 D("cmd_deleteWordBackward", "Delete the previous word.")),
651 R(S(D("forward-line", "Move or extend the selection forward one line."),
652 D("cmd_lineNext", "Move point forward one line."),
653 "cmd_selectLineNext", "Extend selection forward one line."),
654 S(D("backward-line", "Move or extend the selection backward one line."),
655 D("cmd_linePrevious", "Move point backward one line."),
656 D("cmd_selectLinePrevious", "Extend selection backward one line."))),
657 R(S(D("forward-page", "Move or extend the selection forward one page."),
658 D("cmd_movePageDown", "Move point forward one page."),
659 D("cmd_selectPageDown", "Extend selection forward one page.")),
660 S(D("backward-page", "Move or extend the selection backward one page."),
661 D("cmd_movePageUp", "Move point backward one page."),
662 D("cmd_selectPageUp", "Extend selection backward one page."))),
663 R(D("cmd_undo", "Undo last editing action."),
664 D("cmd_redo", "Redo last editing action.")),
665 R(S(D("forward-word", "Move or extend the selection forward one word."),
666 D("cmd_wordNext", "Move point forward one word."),
667 D("cmd_selectWordNext", "Extend selection forward one word.")),
668 S(D("backward-word", "Move or extend the selection backward one word."),
669 D("cmd_wordPrevious", "Move point backward one word."),
670 D("cmd_selectWordPrevious", "Extend selection backward one word."))),
671 R(D("cmd_scrollPageUp", "Scroll up one page."),
672 D("cmd_scrollPageDown", "Scroll down one page.")),
673 R(D("cmd_scrollLineUp", "Scroll up one line."),
674 D("cmd_scrollLineDown", "Scroll down one line.")),
675 R(D("cmd_scrollLeft", "Scroll left."),
676 D("cmd_scrollRight", "Scroll right.")),
677 D("cmd_paste", "Insert the contents of the clipboard.")];
679 interactive(prefix + "set-mark",
680 "Toggle whether the mark is active.\n" +
681 "When the mark is active, movement commands affect the selection.",
684 function doc_for_builtin(c) {
688 return s + "Run the built-in command " + c + ".";
691 function define_simple_command(c) {
692 interactive(prefix + c, doc_for_builtin(c), function (I) { do_command_function(I, c); });
695 function get_move_select_doc_string(c) {
696 return c.command.doc +
697 "\nSpecifically, if the mark is inactive, runs `" + prefix + c[0] + "'. " +
698 "Otherwise, runs `" + prefix + c[1] + "'.\n" +
699 "To toggle whether the mark is active, use `" + prefix + "set-mark'.";
702 for each (let c_temp in builtin_commands) {
704 if (c.is_move_select_pair) {
705 interactive(prefix + c.command, get_move_select_doc_string(c), function (I) {
706 do_command_function(I, mark_active_predicate(I) ? c[1] : c[0]);
708 define_simple_command(c[0]);
709 define_simple_command(c[1]);
712 define_simple_command(c);
715 function get_reverse_pair_doc_string(main_doc, alt_command) {
716 return main_doc + "\n" +
717 "The prefix argument specifies a repeat count for this command. " +
718 "If the count is negative, `" + prefix + alt_command + "' is performed instead with " +
719 "a corresponding positive repeat count.";
722 function define_simple_reverse_pair(a, b) {
723 interactive(prefix + a, get_reverse_pair_doc_string(doc_for_builtin(a), b),
725 do_repeatedly(do_command_function, I.p, [I, a], [I, b]);
727 interactive(prefix + b, get_reverse_pair_doc_string(doc_for_builtin(b), a),
729 do_repeatedly(do_command_function, I.p, [I, b], [I, a]);
733 for each (let c_temp in builtin_commands_with_count)
736 if (c.is_reverse_pair) {
737 if (c[0].is_move_select_pair) {
738 interactive(prefix + c[0].command, get_reverse_pair_doc_string(get_move_select_doc_string(c[0]),
741 var idx = mark_active_predicate(I) ? 1 : 0;
742 do_repeatedly(do_command_function, I.p, [I, c[0][idx]], [I, c[1][idx]]);
744 interactive(prefix + c[1].command, get_reverse_pair_doc_string(get_move_select_doc_string(c[1]),
747 var idx = mark_active_predicate(I) ? 1 : 0;
748 do_repeatedly(do_command_function, I.p, [I, c[1][idx]], [I, c[0][idx]]);
750 define_simple_reverse_pair(c[0][0], c[1][0]);
751 define_simple_reverse_pair(c[0][1], c[1][1]);
753 define_simple_reverse_pair(c[0], c[1]);
755 let doc = doc_for_builtin(c) +
756 "\nThe prefix argument specifies a positive repeat count for this command.";
757 interactive(prefix + c, doc, function (I) {
758 do_repeatedly_positive(do_command_function, I.p, I, c);
764 var observer_service = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
766 function abort(str) {
767 var e = new Error(str);
768 e.__proto__ = abort.prototype;
771 abort.prototype.__proto__ = Error.prototype;
774 function get_temporary_file(name) {
777 var file = file_locator.get("TmpD", Ci.nsIFile);
779 // Create the file now to ensure that no exploits are possible
780 file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0600);
785 /* FIXME: This should be moved somewhere else, perhaps. */
786 function create_info_panel(window, panel_class, row_arr) {
787 /* Show information panel above minibuffer */
789 var g = new dom_generator(window.document, XUL_NS);
791 var p = g.element("vbox", "class", "panel " + panel_class, "flex", "0");
792 var grid = g.element("grid", p);
793 var cols = g.element("columns", grid);
794 g.element("column", cols, "flex", "0");
795 g.element("column", cols, "flex", "1");
797 var rows = g.element("rows", grid);
800 for each (let [row_class, row_label, row_value] in row_arr) {
801 row = g.element("row", rows, "class", row_class);
802 g.element("label", row,
804 "class", "panel-row-label");
805 g.element("label", row,
807 "class", "panel-row-value");
809 window.minibuffer.insert_before(p);
811 p.destroy = function () {
812 this.parentNode.removeChild(this);
819 // read_from_x_primary_selection favors the X PRIMARY SELECTION, when
820 // it exists. The builtin cmd_paste always uses X CLIPBOARD. So this
821 // is an auxiliary utility, in case you need to work with the primary
824 function read_from_x_primary_selection ()
827 var clipboard = Components.classes["@mozilla.org/widget/clipboard;1"]
828 .getService(Components.interfaces.nsIClipboard);
830 // Create tranferable that will transfer the text.
831 var trans = Components.classes["@mozilla.org/widget/transferable;1"]
832 .createInstance(Components.interfaces.nsITransferable);
834 trans.addDataFlavor("text/unicode");
835 // If available, use selection clipboard, otherwise global one
836 if (clipboard.supportsSelectionClipboard())
837 clipboard.getData(trans, clipboard.kSelectionClipboard);
839 clipboard.getData(trans, clipboard.kGlobalClipboard);
843 trans.getTransferData("text/unicode", data, dataLen);
846 data = data.value.QueryInterface(Components.interfaces.nsISupportsString);
847 return data.data.substring(0, dataLen.value / 2);
853 var user_variables = new string_hashmap();
855 function define_variable(name, default_value, doc) {
856 conkeror[name] = default_value;
857 user_variables.put(name, {
858 default_value: default_value,
860 shortdoc: get_shortdoc_string(doc),
861 source_code_reference: get_caller_source_code_reference() });
865 function register_user_stylesheet(url)
867 var uri = makeURL(url);
868 var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
869 sss.loadAndRegisterSheet(uri, sss.USER_SHEET);
872 function unregister_user_stylesheet(url)
874 var uri = makeURL(url);
875 var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
876 if (sss.sheetRegistered(uri, sss.USER_SHEET))
877 ss.unregisterSheet(uri, sss.USER_SHEET);
880 function predicate_alist_match(alist, key) {
881 for each (let i in alist) {
889 function get_meta_title(doc) {
890 var title = doc.evaluate("//meta[@name='title']/@content", doc, xpath_lookup_namespace,
891 Ci.nsIDOMXPathResult.STRING_TYPE , null);
892 if (title && title.stringValue)
893 return title.stringValue;
897 var rdf_service = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService);
899 const PREFIX_ITEM_URI = "urn:mozilla:item:";
900 const PREFIX_NS_EM = "http://www.mozilla.org/2004/em-rdf#";
902 var extension_manager = Cc["@mozilla.org/extensions/manager;1"].getService(Ci.nsIExtensionManager);
904 function get_extension_rdf_property(id, name, type) {
905 var value = extension_manager.datasource.GetTarget(
906 rdf_service.GetResource(PREFIX_ITEM_URI + id),
907 rdf_service.GetResource(PREFIX_NS_EM + name),
911 return value.QueryInterface(type || Ci.nsIRDFLiteral).Value;
914 function get_extension_update_item(id) {
915 return extension_manager.getItemForID(id);
918 function extension_info(id) {
921 extension_info.prototype = {
922 // Returns the nsIUpdateItem object associated with this extension
923 get update_item () { return get_extension_update_item(this.id); },
925 get_rdf_property : function (name, type) {
926 return get_extension_rdf_property(this.id, name, type);
930 get isDisabled () { return this.get_rdf_property("isDisabled"); },
931 get aboutURL () { return this.get_rdf_property("aboutURL"); },
932 get addonID () { return this.get_rdf_property("addonID"); },
933 get availableUpdateURL () { return this.get_rdf_property("availableUpdateURL"); },
934 get availableUpdateVersion () { return this.get_rdf_property("availableUpdateVersion"); },
935 get blocklisted () { return this.get_rdf_property("blocklisted"); },
936 get compatible () { return this.get_rdf_property("compatible"); },
937 get description () { return this.get_rdf_property("description"); },
938 get downloadURL () { return this.get_rdf_property("downloadURL"); },
939 get isDisabled () { return this.get_rdf_property("isDisabled"); },
940 get hidden () { return this.get_rdf_property("hidden"); },
941 get homepageURL () { return this.get_rdf_property("homepageURL"); },
942 get iconURL () { return this.get_rdf_property("iconURL"); },
943 get internalName () { return this.get_rdf_property("internalName"); },
944 get locked () { return this.get_rdf_property("locked"); },
945 get name () { return this.get_rdf_property("name"); },
946 get optionsURL () { return this.get_rdf_property("optionsURL"); },
947 get opType () { return this.get_rdf_property("opType"); },
948 get plugin () { return this.get_rdf_property("plugin"); },
949 get previewImage () { return this.get_rdf_property("previewImage"); },
950 get satisfiesDependencies () { return this.get_rdf_property("satisfiesDependencies"); },
951 get providesUpdatesSecurely () { return this.get_rdf_property("providesUpdatesSecurely"); },
952 get type () { return this.get_rdf_property("type", Ci.nsIRDFInt); },
953 get updateable () { return this.get_rdf_property("updateable"); },
954 get updateURL () { return this.get_rdf_property("updateURL"); },
955 get version () { return this.get_rdf_property("version"); }
958 function extension_is_enabled(id) {
959 var info = new extension_info(id);
960 return info.update_item && (info.isDisabled == "false");
963 function for_each_frame(root_frame, callback, start_with) {
965 callback(start_with);
970 for (let i = 0; i < f.frames.length; ++i) {
977 // Co-routine version of for_each_frame
978 function co_for_each_frame(root_frame, callback, start_with) {
980 yield callback(start_with);
985 for (let i = 0; i < f.frames.length; ++i) {
986 yield helper(f.frames[i]);
989 yield helper(root_frame);
992 function xml_http_request() {
993 return Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest).QueryInterface(Ci.nsIJSXMLHttpRequest).QueryInterface(Ci.nsIDOMEventTarget);
996 var xml_http_request_load_listener = {
997 // nsIBadCertListener2
998 notifyCertProblem: function SSLL_certProblem(socketInfo, status, targetSite) {
1002 // nsISSLErrorListener
1003 notifySSLError: function SSLL_SSLError(socketInfo, error, targetSite) {
1007 // nsIInterfaceRequestor
1008 getInterface: function SSLL_getInterface(iid) {
1009 return this.QueryInterface(iid);
1013 QueryInterface: XPCOMUtils.generateQI([Ci.nsIBadCertListener2,
1014 Ci.nsISSLErrorListener,
1015 Ci.nsIInterfaceRequestor])
1019 define_keywords("$user", "$password", "$override_mime_type", "$headers");
1020 function send_http_request(lspec) {
1021 keywords(arguments);
1022 var req = xml_http_request();
1023 var cc = yield CONTINUATION;
1024 req.onreadystatechange = function () {
1025 if (req.readyState != 4)
1030 if (arguments.$override_mime_type)
1031 req.overrideMimeType(arguments.$override_mime_type);
1033 var post_data = load_spec_raw_post_data(lspec);
1035 var method = post_data ? "POST" : "GET";
1037 req.open(method, load_spec_uri_string(lspec), true, arguments.$user, arguments.$password);
1038 req.channel.notificationCallbacks = xml_http_request_load_listener;
1040 for each (let [name,value] in arguments.$headers) {
1041 req.setRequestHeader(name, value);
1045 req.setRequestHeader("Content-Type", load_spec_request_mime_type(lspec));
1046 req.send(post_data);
1057 // Let the caller access the status and reponse data
1058 yield co_return(req);