1 /**
  2  * 
  3  * All content on this website (including text, images, source
  4  * code and any other original works), unless otherwise noted,
  5  * is licensed under a Creative Commons License.
  6  * 
  7  * http://creativecommons.org/licenses/by-nc-sa/2.5/
  8  * 
  9  * Copyright (C) 2004-2010 Open-Xchange, Inc.
 10  * Mail: info@open-xchange.com 
 11  * 
 12  * @author Viktor Pracht <viktor.pracht@open-xchange.com>
 13  * 
 14  */
 15 
 16 var loadPlugins = function (cont) {
 17     var modules = configGetKey("availableModules");
 18     if (!modules) return;
 19     var join = new Join(function() {
 20         temporary.services.finish();
 21         cont();
 22     });
 23     var lock = join.add();
 24     // turn on/off plugins via url parameter
 25     if (url && url.plugins !== undefined) {
 26         // loop over comma separated list
 27         var i = 0, plugins = url.plugins.split(/,/), $i = plugins.length, plugin, pos;
 28         for (; i < $i; i++) {
 29             plugin = plugins[i];
 30             // on/off?
 31             if (plugin.indexOf("-") === 0) {
 32                 pos = jQuery.inArray(plugin.substr(1), modules);
 33                 // turn off
 34                 if (pos > -1) {
 35                     modules.splice(pos, 1);
 36                 }
 37             } else {
 38                 pos = jQuery.inArray(plugin, modules);
 39                 if (pos === -1) {
 40                     modules.push(plugin);
 41                 }
 42             }
 43         }
 44     }
 45     for (var i in modules) {
 46         loadModule(modules[i], join);
 47     }
 48     lock();
 49 };
 50 
 51   //////////////////////////////////////////
 52  //   Global names defined for plugins   //
 53 //////////////////////////////////////////
 54 
 55 /**
 56  * Translates a string.
 57  * @function
 58  * @name _
 59  * @param {String} text The original English text to translate.
 60  * @type I18nString
 61  * @return The translated text.
 62  */
 63 
 64 /**
 65  * Translates a string.
 66  * @function
 67  * @name gettext
 68  * @param {String} text The original English text to translate.
 69  * @type I18nString
 70  * @return The translated text.
 71  */
 72 
 73 /**
 74  * Translates a string with context
 75  * @function
 76  * @name pgettext
 77  * @param {String} context A context to differentiate multiple identical texts
 78  * with different translations.
 79  * @param {String} text The original English text to translate.
 80  * @type I18nString
 81  * @return The translated text.
 82  */
 83 
 84 /**
 85  * Translates a string containing numbers.
 86  * @function
 87  * @name ngettext
 88  * @param {String} singular The original English text for the singular form.
 89  * @param {String} plural The original English text for the plural form.
 90  * @param {Number} n The number which determines which text form is used.
 91  * @type I18nString
 92  * @return The translated text.
 93  */
 94 
 95 /**
 96  * Translates a string containing numbers with context.
 97  * @function
 98  * @name npgettext
 99  * @param {String} context A context to differentiate multiple identical texts
100  * with different translations.
101  * @param {String} singular The original English text for the singular form.
102  * @param {String} plural The original English text for the plural form.
103  * @param {Number} n The number which determines which text form is used.
104  * @type I18nString
105  * @return The translated text.
106  */
107 
108 /**
109  * Converts a string to I18nString without translation.
110  * @function
111  * @name noI18n
112  * @param {String} text The text to conevrt.
113  * @type I18nString
114  * @return The untranslated text as I18nString.
115  */
116 
117 //////////////////////////////////////////
118 
119 /**
120  * Loads a module at runtime.
121  * Loading a module which is already (being) loaded has no effect. 
122  * The register.js file from the module's directory is converted to the body of
123  * a function and that function is called without parameters.
124  * The file is downloaded asynchronously.
125  * @param {String} name The name of the module to load.
126  * @param {Join} join An optional Join object which is locked until the module
127  * finishes loading.
128  */
129 function loadModule(name, join) {
130     if (name in loadedModules) return;
131     loadedModules[name] = true;
132     if (!join) join = new Join(emptyFunction);
133     // inject version
134     var url = oxProductInfo.build + "/plugins/" + name + "/register.js";
135     // get register.js
136     (new JSON()).get(url, null,
137         join.add(function(js) {
138             if (internalPlugins[name])
139                 name = "";
140             else
141                 bindtextdomain(name, "plugins/" + name + "/lang/%s.po");
142             if (debugPlugins) {
143                 loadModule.params[++loadModule.index] =
144                     [gt, gt, pgt, ngt, npgt, join.add()];
145                 var src =["(function(_,gettext,pgettext,ngettext,npgettext,",
146                           "$done){delete loadModule.params[",
147                           loadModule.index, "];try{(function(){",js,
148                           "})()}finally{$done();}})("];
149                 var params = [];
150                 var prefix = "loadModule.params[" + loadModule.index + "][";
151                 for (var i = 0; i < 6; i++) params.push(prefix + i + "]");
152                 src.push(params.join());
153                 src.push(");");
154                 document.getElementsByTagName("head")[0].appendChild(
155                     newnode("script", 0, {
156                         type: "text/javascript",
157                         src: "data:text/javascript;charset=utf-8," +
158                             encodeURIComponent(src.join(""))
159                     }));
160             } else {
161                 (Function("_", "gettext", "pgettext", "ngettext", "npgettext",
162                     js))(gt, gt, pgt, ngt, npgt);
163             }
164             function gt(text) { return dpgettext(name, "", text); }
165             function pgt(context, text) {
166                 return dpgettext(name, context, text);
167             }
168             function ngt(singular, plural, n) {
169                 return dnpgettext(name, "", singular, plural, n);
170             }
171             function npgt(context, singular, plural, n) {
172                 return dnpgettext(name, context, singular, plural, n);
173             }
174         }),
175         join.alt(function(result, status) {
176             delete loadedModules[name];
177             return status == 404;
178         }), true);
179 };
180 
181 loadModule.params = {};
182 loadModule.index = 0;
183 
184 var internalPlugins = {
185     "com.openexchange.settings.folder": true,
186     "com.openexchange.toolbar": true,
187     "com.openexchange.group": true,
188     "com.openexchange.mail.filter": true,
189     "com.openexchange.oxupdater": true,
190     "com.openexchange.publish": true,
191     "com.openexchange.resource": true,
192     "com.openexchange.secret.recovery": true,
193     "com.openexchange.subscribe": true,
194     "com.openexchange.user.passwordchange": true,
195     "com.openexchange.user.personaldata": true
196 };
197 
198 // TODO: fill during initialization of modules.
199 var loadedModules = {
200     calendar: true,
201     contacts: true,
202     folder: true,
203     infostore: true,
204     interfaces: true,
205     mail: true,
206     mailaccount: true,
207     messaging: true,
208     portal: true,
209     tasks: true,
210     themes: true,
211     folderstorage: true
212 };
213