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 function makeURL(aURL)
185 var ioService = Cc["@mozilla.org/network/io-service;1"]
186 .getService(Ci.nsIIOService);
187 return ioService.newURI(aURL, null, null);
190 function make_uri(uri) {
191 if (uri instanceof Ci.nsIURI)
193 var io_service = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
194 return io_service.newURI(uri, null, null);
197 function makeFileURL(aFile)
199 var ioService = Cc["@mozilla.org/network/io-service;1"]
200 .getService(Ci.nsIIOService);
201 return ioService.newFileURI(aFile).QueryInterface(Ci.nsIURL);
205 function get_document_content_disposition (document_o)
207 var content_disposition = null;
209 content_disposition =
210 document_o.defaultView
211 .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
212 .getInterface(Components.interfaces.nsIDOMWindowUtils)
213 .getDocumentMetadata("content-disposition");
215 return content_disposition;
219 function set_focus_no_scroll(window, element)
221 window.document.commandDispatcher.suppressFocusScroll = true;
223 window.document.commandDispatcher.suppressFocusScroll = false;
226 function do_repeatedly_positive(func, n) {
227 var args = Array.prototype.slice.call(arguments, 2);
229 func.apply(null, args);
232 function do_repeatedly(func, n, positive_args, negative_args) {
234 do func.apply(null, negative_args); while (++n < 0);
236 while (n-- > 0) func.apply(null, positive_args);
239 // remove whitespace from the beginning and end
240 function trim_whitespace (str)
242 var tmp = new String (str);
243 return tmp.replace (/^\s+/, "").replace (/\s+$/, "");
246 function abs_point (node)
251 pt.x = node.offsetLeft;
252 pt.y = node.offsetTop;
253 // find imagemap's coordinates
254 if (node.tagName == "AREA") {
255 var coords = node.getAttribute("coords").split(",");
256 pt.x += Number(coords[0]);
257 pt.y += Number(coords[1]);
260 node = node.offsetParent;
261 // Sometimes this fails, so just return what we got.
263 while (node.tagName != "BODY") {
264 pt.x += node.offsetLeft;
265 pt.y += node.offsetTop;
266 node = node.offsetParent;
270 // while (node.tagName != "BODY") {
271 // alert("okay: " + node + " " + node.tagName + " " + pt.x + " " + pt.y);
272 // node = node.offsetParent;
278 var xul_app_info = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo);
279 var xul_runtime = Cc['@mozilla.org/xre/app-info;1'].getService(Ci.nsIXULRuntime);
284 // possible return values: 'Darwin', 'Linux', 'WINNT', ...
285 return xul_runtime.OS;
288 var default_directory = null;
290 var env = Cc['@mozilla.org/process/environment;1'].getService(Ci.nsIEnvironment);
291 function getenv (variable) {
292 if (env.exists (variable))
293 return env.get(variable);
297 function set_default_directory(directory_s) {
300 if ( get_os() == "WINNT")
302 directory_s = getenv ('USERPROFILE') ||
303 getenv ('HOMEDRIVE') + getenv ('HOMEPATH');
306 directory_s = getenv ('HOME');
310 default_directory = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
311 default_directory.initWithPath (directory_s);
314 set_default_directory();
316 const XHTML_NS = "http://www.w3.org/1999/xhtml";
317 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
318 const MATHML_NS = "http://www.w3.org/1998/Math/MathML";
319 const XLINK_NS = "http://www.w3.org/1999/xlink";
321 function create_XUL(window, tag_name)
323 return window.document.createElementNS(XUL_NS, tag_name);
327 /* Used in calls to XPath evaluate */
328 function xpath_lookup_namespace(prefix) {
329 if (prefix == "xhtml")
338 function method_caller(obj, func) {
340 func.apply(obj, arguments);
344 function shell_quote(str) {
345 var s = str.replace("\"", "\\\"", "g");
346 s = s.replace("$", "\$", "g");
350 function get_window_from_frame(frame) {
352 var window = frame.QueryInterface(Ci.nsIInterfaceRequestor)
353 .getInterface(Ci.nsIWebNavigation)
354 .QueryInterface(Ci.nsIDocShellTreeItem)
356 .QueryInterface(Ci.nsIInterfaceRequestor)
357 .getInterface(Ci.nsIDOMWindow).wrappedJSObject;
358 /* window is now an XPCSafeJSObjectWrapper */
359 window.escape_wrapper(function (w) { window = w; });
360 /* window is now completely unwrapped */
367 function get_buffer_from_frame(window, frame) {
368 var count = window.buffers.count;
369 for (var i = 0; i < count; ++i) {
370 var b = window.buffers.get_buffer(i);
371 if (b.top_frame == frame)
377 var file_locator = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
379 function get_shortdoc_string(doc) {
382 var idx = doc.indexOf("\n");
384 shortdoc = doc.substring(0,idx);
391 var conkeror_source_code_path = null;
393 function source_code_reference(uri, line_number) {
395 this.line_number = line_number;
397 source_code_reference.prototype = {
399 if (this.uri.indexOf(module_uri_prefix) == 0)
400 return this.uri.substring(module_uri_prefix.length);
405 var file_uri_prefix = "file://";
406 if (this.uri.indexOf(file_uri_prefix) == 0)
407 return this.uri.substring(file_uri_prefix.length);
412 if (conkeror_source_code_path != null) {
413 var module_name = this.module_name;
414 if (module_name != null)
415 return "file://" + conkeror_source_code_path + "/modules/" + module_name;
420 open_in_editor : function() {
421 yield open_with_external_editor(this.best_uri, $line = this.line_number);
425 var get_caller_source_code_reference_ignored_functions = {};
427 function get_caller_source_code_reference(extra_frames_back) {
428 /* Skip at least this function itself and whoever called it (and
429 * more if the caller wants to be skipped). */
430 var frames_to_skip = 2;
431 if (extra_frames_back != null)
432 frames_to_skip += extra_frames_back;
434 for (let f = Components.stack; f != null; f = f.caller) {
435 if (frames_to_skip > 0) {
439 if (get_caller_source_code_reference_ignored_functions[f.name])
441 return new source_code_reference(f.filename, f.lineNumber);
447 function ignore_function_for_get_caller_source_code_reference(func_name) {
448 get_caller_source_code_reference_ignored_functions[func_name] = 1;
451 require_later("external-editor.js");
453 function dom_generator(document, ns) {
454 this.document = document;
457 dom_generator.prototype = {
458 element : function(tag, parent) {
459 var node = this.document.createElementNS(this.ns, tag);
461 if (parent != null && (parent instanceof Ci.nsIDOMNode)) {
462 parent.appendChild(node);
465 for (; i < arguments.length; i += 2)
466 node.setAttribute(arguments[i], arguments[i+1]);
470 text : function(str, parent) {
471 var node = this.document.createTextNode(str);
473 parent.appendChild(node);
478 stylesheet_link : function(href, parent) {
479 var node = this.element("link");
480 node.setAttribute("rel", "stylesheet");
481 node.setAttribute("type", "text/css");
482 node.setAttribute("href", href);
484 parent.appendChild(node);
489 add_stylesheet : function (url) {
490 var head = this.document.documentElement.firstChild;
491 this.stylesheet_link(url, head);
496 * Generates a QueryInterface function suitable for an implemenation
497 * of an XPCOM interface. Unlike XPCOMUtils, this uses the Function
498 * constructor to generate a slightly more efficient version. The
499 * arguments can be either Strings or elements of
500 * Components.interfaces.
502 function generate_QI() {
503 var args = Array.prototype.slice.call(arguments).map(String).concat(["nsISupports"]);
505 Array.prototype.map.call(args,
507 "iid.equals(Components.interfaces." + x + ")")
509 ") return this; throw Components.results.NS_ERROR_NO_INTERFACE;";
510 return new Function("iid", fstr);
513 function set_branch_pref(branch, name, value) {
514 if (typeof(value) == "string") {
515 branch.setCharPref(name, value);
516 } else if (typeof(value) == "number") {
517 branch.setIntPref(name, value);
518 } else if (typeof(value) == "boolean") {
519 branch.setBoolPref(name, value);
523 function default_pref(name, value) {
524 var branch = preferences.getDefaultBranch(null);
525 set_branch_pref(branch, name, value);
528 function user_pref(name, value) {
529 var branch = preferences.getBranch(null);
530 set_branch_pref(branch, name, value);
533 function get_branch_pref(branch, name) {
534 switch (branch.getPrefType(name)) {
535 case branch.PREF_STRING:
536 return branch.getCharPref(name);
537 case branch.PREF_INT:
538 return branch.getIntPref(name);
539 case branch.PREF_BOOL:
540 return branch.getBoolPref(name);
546 function get_localized_pref(name) {
548 return preferences.getBranch(null).getComplexValue(name, Ci.nsIPrefLocalizedString).data;
554 function get_pref(name) {
555 var branch = preferences.getBranch(null);
556 return get_branch_pref(branch, name);
559 function get_default_pref(name) {
560 var branch = preferences.getDefaultBranch(null);
561 return get_branch_pref(branch, name);
564 function clear_pref(name) {
565 var branch = preferences.getBranch(null);
566 return branch.clearUserPref(name);
569 function pref_has_user_value(name) {
570 var branch = preferences.getBranch(null);
571 return branch.prefHasUserValue(name);
574 function pref_has_default_value(name) {
575 var branch = preferences.getDefaultBranch(null);
576 return branch.prefHasUserValue(name);
579 function session_pref (name, value) {
580 try { clear_pref (name); }
582 return default_pref (name, value);
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");