Pass key binding hook functions the current top keymap
[conkeror.git] / components / application.js
blob035bb0efe1006e43278c2c6a8c7e686aabb8974b
1 /**
2  * (C) Copyright 2007 John J. Foerch
3  * (C) Copyright 2007-2008 Jeremy Maitin-Shepard
4  *
5  * Use, modification, and distribution are subject to the terms specified in the
6  * COPYING file.
7 **/
9 const Cc = Components.classes;
10 const Ci = Components.interfaces;
11 const Cr = Components.results;
12 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
14 function application () {
15     Components.utils.import("resource://gre/modules/XPCOMUtils.jsm", this);
17     this.wrappedJSObject = this;
18     this.conkeror = this;
20     this.loaded_modules = [];
21     this.loading_modules = [];
22     this.module_after_load_functions = new Object();
23     this.pending_loads = [];
25     try {
26         this.require("conkeror.js");
27     } catch (e) {
28         this.dumpln("Error initializing.");
29         this.dump_error(e);
30     }
32 application.prototype = {
33     Cc: Cc,
34     Ci: Ci,
35     Cr: Cr,
36     /* Note: resource://app currently doesn't result in xpcnativewrappers=yes */
37     module_uri_prefix: "chrome://conkeror-modules/content/",
38     subscript_loader: Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader),
39     preferences: Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService),
40     dump_error: function (e) {
41         if (e instanceof Error) {
42             this.dumpln(e.name + ": " + e.message);
43             this.dumpln(e.fileName + ":" + e.lineNumber);
44             dump(e.stack);
45         } else if (e instanceof Ci.nsIException) {
46             this.dumpln(e.name + ": " + e.message);
47             var stack_frame = e.location;
48             while (stack_frame) {
49                 this.dumpln(stack_frame.name + "()@" + stack_frame.filename + ":" + stack_frame.lineNumber);
50                 stack_frame = stack_frame.caller;
51             }
52         } else {
53             this.dumpln("Error: " + e);
54         }
55     },
56     loaded: function (module) {
57         return (this.loaded_modules.indexOf(module) != -1);
58     },
59     provide: function(module) {
60         if (this.loaded_modules.indexOf(module) == -1)
61             this.loaded_modules.push(module);
62     },
63     skip_module_load : {},
64     load_module: function(module_name) {
65         if (this.loading_modules.indexOf(module_name) != -1)
66             throw new Error("Circular module dependency detected: "
67                             + this.loading_modules.join(" -> ") + " -> " + module_name);
68         this.loading_modules.push(module_name);
69         try {
70             this.subscript_loader.loadSubScript(this.module_uri_prefix + module_name,
71                                                 this);
72             this.provide(module_name);
73             var funcs;
74             if ((funcs = this.module_after_load_functions[module_name]) != null)
75             {
76                 for (var i = 0; i < funcs.length; ++i)
77                     funcs[i]();
78                 delete this.module_after_load_functions[module_name];
79             }
80         }
81         catch (e if e == this.skip_module_load) {}
82         catch (e) {
83             if (!(e instanceof Error) && !(e instanceof Ci.nsIException) &&
84                 (String(e) == "ContentLength not available (not a local URL?)" ||
85                  String(e) == "Error creating channel (invalid URL scheme?)"))
86                 throw new Error("Module not found: " + this.module_uri_prefix + module_name + ": " + e);
87             throw e;
88         }
89         finally {
90             this.loading_modules.pop();
91         }
93         if (this.loading_modules.length == 0)
94         {
95             while (this.pending_loads.length > 0)
96             {
97                 this.require(this.pending_loads.pop());
98             }
99         }
100     },
101     require: function (module) {
102         if (!this.loaded(module))
103             this.load_module(module);
104     },
105     require_later: function (module) {
106         if (!this.loaded(module)
107             && this.pending_loads.indexOf(module) == -1)
108             this.pending_loads.push(module);
109     },
110     call_after_load: function (module, func) {
111         if (this.loaded(module))
112             func();
113         else
114         {
115             var funcs;
116             if (!(funcs = this.module_after_load_functions[module]))
117                 funcs = this.module_after_load_functions[module] = [];
118             funcs.push(func);
119         }
120     },
121     dumpln: function (line) {
122         dump(line + "\n");
123     },
125     version: "$CONKEROR_VERSION$", // preprocessor variable
126     homepage: "chrome://conkeror/content/help.html",
128     /* nsISupports */
129     QueryInterface: XPCOMUtils.generateQI([]),
131     /* XPCOM registration */
132     classDescription: "Conkeror global object",
133     classID: Components.ID("{72a7eea7-a894-47ec-93a9-a7bc172cf1ac}"),
134     contractID: "@conkeror.mozdev.org/application;1"
137 function NSGetModule(compMgr, fileSpec)
138     XPCOMUtils.generateModule([application]);