PageRenderTime 104ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

/platform/browser/plugins/supported/appconfig/index.js

https://github.com/c4milo/skywriter
JavaScript | 408 lines | 298 code | 42 blank | 68 comment | 68 complexity | 60e1ba7bc5e7f54942cb75e38d9dfbab MD5 | raw file
  1. require.def(['require', 'exports', 'module',
  2. 'jquery',
  3. 'settings',
  4. 'skywriter/promise',
  5. 'skywriter/console',
  6. 'skywriter/util/stacktrace',
  7. 'skywriter/util/util',
  8. 'skywriter/plugins',
  9. 'environment',
  10. 'theme_manager'
  11. ], function(require, exports, module,
  12. jquery,
  13. settingsMod,
  14. promise,
  15. consoleMod,
  16. stacktrace,
  17. util,
  18. plugins,
  19. environment,
  20. themeManager
  21. ) {
  22. /* ***** BEGIN LICENSE BLOCK *****
  23. * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  24. *
  25. * The contents of this file are subject to the Mozilla Public License Version
  26. * 1.1 (the "License"); you may not use this file except in compliance with
  27. * the License. You may obtain a copy of the License at
  28. * http://www.mozilla.org/MPL/
  29. *
  30. * Software distributed under the License is distributed on an "AS IS" basis,
  31. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  32. * for the specific language governing rights and limitations under the
  33. * License.
  34. *
  35. * The Original Code is Skywriter.
  36. *
  37. * The Initial Developer of the Original Code is
  38. * Mozilla.
  39. * Portions created by the Initial Developer are Copyright (C) 2009
  40. * the Initial Developer. All Rights Reserved.
  41. *
  42. * Contributor(s):
  43. * Skywriter Team (skywriter@mozilla.com)
  44. *
  45. * Alternatively, the contents of this file may be used under the terms of
  46. * either the GNU General Public License Version 2 or later (the "GPL"), or
  47. * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  48. * in which case the provisions of the GPL or the LGPL are applicable instead
  49. * of those above. If you wish to allow use of your version of this file only
  50. * under the terms of either the GPL or the LGPL, and not to allow others to
  51. * use your version of this file under the terms of the MPL, indicate your
  52. * decision by deleting the provisions above and replace them with the notice
  53. * and other provisions required by the GPL or the LGPL. If you do not delete
  54. * the provisions above, a recipient may use your version of this file under
  55. * the terms of any one of the MPL, the GPL or the LGPL.
  56. *
  57. * ***** END LICENSE BLOCK ***** */
  58. var $ = jquery.$; //SYNC_REQ: var $ = require('jquery').$;
  59. var settings = settingsMod.settings; //SYNC_REQ: var settings = require('settings').settings;
  60. var group = promise.group; //SYNC_REQ: var group = require("skywriter:promise").group;
  61. var Promise = promise.Promise; //SYNC_REQ: var Promise = require("skywriter:promise").Promise;
  62. var console = consoleMod.console; //SYNC_REQ: var console = require("skywriter:console").console;
  63. var Trace = stacktrace.Trace; //SYNC_REQ: var Trace = require("skywriter:util/stacktrace").Trace;
  64. //SYNC_REQ: var util = require('skywriter:util/util');
  65. var firstSkywriter = true;
  66. /*
  67. * launch Skywriter with the configuration provided. The configuration is
  68. * an object with the following properties:
  69. * - theme: an object with the basePlugin as string and the standardTheme as
  70. * string. Both are optional. If no basePlugin is given, screen_theme
  71. * is used if this exists.
  72. * - objects: an object with a collection of named objects that will be
  73. * registered with the plugin catalog (see PluginCatalog.registerObject)
  74. * This will automatically be augmented with sane defaults (for
  75. * example, most Skywriter users want a text editor!)
  76. * - gui: instructions on how to build a GUI. Specifically, the current border
  77. * layout positions will be filled in. Again this provides sane defaults.
  78. * - container: node to attach to (optional). If not provided a node will be
  79. * created. and added to the body.
  80. * - settings: settings to preconfigure
  81. */
  82. exports.launch = function(config) {
  83. var launchPromise = new Promise();
  84. // Remove the "Loading..." hint.
  85. $('#_skywriter_loading').remove();
  86. // This will hold the require function to get the catalog.
  87. var require;
  88. // Is this the fist Skywriter?
  89. if (firstSkywriter) {
  90. // Use the global require.
  91. require = skywriter.tiki.require;
  92. firstSkywriter = false;
  93. } else {
  94. // Otherwise create a new tiki-skywriter sandbox and a new require function.
  95. var sandbox = new (skywriter.tiki.require('skywriter:sandbox').Sandbox);
  96. require = sandbox.createRequire({
  97. id: 'index',
  98. ownerPackage: skywriter.tiki.loader.anonymousPackage
  99. });
  100. }
  101. // Here we go: Require the catalog that is used for this Skywriter instance.
  102. var catalog = plugins.catalog; //SYNC_REQ: var catalog = require('skywriter:plugins').catalog;
  103. // Launch Skywriter!
  104. config = config || {};
  105. exports.normalizeConfig(catalog, config);
  106. var objects = config.objects;
  107. for (var key in objects) {
  108. catalog.registerObject(key, objects[key]);
  109. }
  110. for (var setting in config.settings) {
  111. settings.set(setting, config.settings[setting]);
  112. }
  113. // Resolve the launchPromise and pass the env variable along.
  114. var resolveLaunchPromise = function() {
  115. var env = environment.env; //SYNC_REQ: var env = require("environment").env;
  116. var editor = env.editor;
  117. if (editor) {
  118. if (config.lineNumber) {
  119. editor.setLineNumber(config.lineNumber);
  120. }
  121. if (config.stealFocus) {
  122. editor.focus = true;
  123. }
  124. if (config.readOnly) {
  125. editor.readOnly = config.readOnly;
  126. }
  127. if (config.syntax) {
  128. editor.syntax = config.syntax;
  129. }
  130. }
  131. var commandLine = catalog.getObject('commandLine');
  132. if (commandLine) {
  133. env.commandLine = commandLine;
  134. }
  135. catalog.publish(this, 'appLaunched');
  136. launchPromise.resolve(env);
  137. }.bind(this);
  138. var themeLoadingPromise = new Promise();
  139. themeLoadingPromise.then(function() {
  140. if (objects.loginController) {
  141. catalog.createObject("loginController").then(
  142. function(loginController) {
  143. var pr = loginController.showLogin();
  144. pr.then(function(username) {
  145. // Add the username as constructor argument.
  146. config.objects.session.arguments.push(username);
  147. exports.launchEditor(catalog, config).then(resolveLaunchPromise,
  148. launchPromise.reject.bind(launchPromise));
  149. });
  150. });
  151. } else {
  152. exports.launchEditor(catalog, config).then(resolveLaunchPromise,
  153. launchPromise.reject.bind(launchPromise));
  154. }
  155. }, function(error) {
  156. launchPromise.reject(error);
  157. });
  158. // If the themeManager plugin is there, then check for theme configuration.
  159. if (catalog.plugins.theme_manager) {
  160. skywriter.tiki.require.ensurePackage('::theme_manager', function() {
  161. //SYNC_REQ: var themeManager = require('theme_manager');
  162. if (config.theme.basePlugin) {
  163. themeManager.setBasePlugin(config.theme.basePlugin);
  164. }
  165. if (config.theme.standard) {
  166. themeManager.setStandardTheme(config.theme.standard);
  167. }
  168. themeManager.startParsing().then(function() {
  169. themeLoadingPromise.resolve();
  170. }, function(error) {
  171. themeLoadingPromise.reject(error);
  172. });
  173. });
  174. } else {
  175. themeLoadingPromise.resolve();
  176. }
  177. return launchPromise;
  178. };
  179. exports.normalizeConfig = function(catalog, config) {
  180. if (config.objects === undefined) {
  181. config.objects = {};
  182. }
  183. if (config.autoload === undefined) {
  184. config.autoload = [];
  185. }
  186. if (config.theme === undefined) {
  187. config.theme = {};
  188. }
  189. if (!config.theme.basePlugin && catalog.plugins.screen_theme) {
  190. config.theme.basePlugin = 'screen_theme';
  191. }
  192. if (!config.initialContent) {
  193. config.initialContent = '';
  194. }
  195. if (!config.settings) {
  196. config.settings = {};
  197. }
  198. if (!config.objects.notifier && catalog.plugins.notifier) {
  199. config.objects.notifier = {
  200. };
  201. }
  202. if (!config.objects.loginController && catalog.plugins.userident) {
  203. config.objects.loginController = {
  204. };
  205. }
  206. if (!config.objects.fileHistory && catalog.plugins.file_history) {
  207. config.objects.fileHistory = {
  208. factory: 'file_history',
  209. arguments: [
  210. "session"
  211. ],
  212. objects: {
  213. "0": "session"
  214. }
  215. };
  216. }
  217. if (!config.objects.server && catalog.plugins.skywriter_server) {
  218. config.objects.server = {
  219. factory: "skywriter_server"
  220. };
  221. config.objects.filesource = {
  222. factory: "skywriter_filesource",
  223. arguments: [
  224. "server"
  225. ],
  226. objects: {
  227. "0": "server"
  228. }
  229. };
  230. }
  231. if (!config.objects.files && catalog.plugins.filesystem &&
  232. config.objects.filesource) {
  233. config.objects.files = {
  234. arguments: [
  235. "filesource"
  236. ],
  237. "objects": {
  238. "0": "filesource"
  239. }
  240. };
  241. }
  242. if (!config.objects.editor) {
  243. config.objects.editor = {
  244. factory: "text_editor",
  245. arguments: [
  246. config.initialContent
  247. ]
  248. };
  249. }
  250. if (!config.objects.session) {
  251. config.objects.session = {
  252. arguments: [
  253. "editor"
  254. ],
  255. "objects": {
  256. "0": "editor"
  257. }
  258. };
  259. }
  260. if (!config.objects.commandLine && catalog.plugins.command_line) {
  261. config.objects.commandLine = {
  262. };
  263. }
  264. if (!config.objects.toolbar && catalog.plugins.toolbar) {
  265. config.objects.toolbar = {};
  266. }
  267. if (config.gui === undefined) {
  268. config.gui = {};
  269. }
  270. var alreadyRegistered = {};
  271. for (var key in config.gui) {
  272. var desc = config.gui[key];
  273. if (desc.component) {
  274. alreadyRegistered[desc.component] = true;
  275. }
  276. }
  277. if (!config.gui.north && config.objects.toolbar
  278. && !alreadyRegistered.toolbar) {
  279. config.gui.north = { component: "toolbar" };
  280. }
  281. if (!config.gui.center && config.objects.editor
  282. && !alreadyRegistered.editor) {
  283. config.gui.center = { component: "editor" };
  284. }
  285. if (!config.gui.south && config.objects.commandLine
  286. && !alreadyRegistered.commandLine) {
  287. config.gui.south = { component: "commandLine" };
  288. }
  289. };
  290. exports.launchEditor = function(catalog, config) {
  291. var retPr = new Promise();
  292. if (config === null) {
  293. var message = 'Cannot start editor without a configuration!';
  294. console.error(message);
  295. retPr.reject(message);
  296. return retPr;
  297. }
  298. var pr = createAllObjects(catalog, config);
  299. pr.then(function() {
  300. generateGUI(catalog, config, retPr);
  301. }, function(error) {
  302. console.error('Error while creating objects');
  303. new Trace(error).log();
  304. retPr.reject(error);
  305. });
  306. return retPr;
  307. };
  308. var createAllObjects = function(catalog, config) {
  309. var promises = [];
  310. for (var objectName in config.objects) {
  311. promises.push(catalog.createObject(objectName));
  312. }
  313. return group(promises);
  314. };
  315. var generateGUI = function(catalog, config, pr) {
  316. var error;
  317. var container = document.createElement('div');
  318. container.setAttribute('class', 'container');
  319. var centerContainer = document.createElement('div');
  320. centerContainer.setAttribute('class', 'center-container');
  321. var centerAdded = false;
  322. var element = config.element || document.body;
  323. // Add the 'skywriter' class to the element in case it doesn't have this already.
  324. util.addClass(element, 'skywriter');
  325. element.appendChild(container);
  326. // this shouldn't be necessary, but it looks like Firefox has an issue
  327. // with the box-ordinal-group CSS property
  328. ['north', 'west', 'center', 'east', 'south'].forEach(function(place) {
  329. var descriptor = config.gui[place];
  330. if (!descriptor) {
  331. return;
  332. }
  333. var component = catalog.getObject(descriptor.component);
  334. if (!component) {
  335. error = 'Cannot find object ' + descriptor.component +
  336. ' to attach to the Skywriter UI';
  337. console.error(error);
  338. pr.reject(error);
  339. return;
  340. }
  341. element = component.element;
  342. if (!element) {
  343. error = 'Component ' + descriptor.component + ' does not have' +
  344. ' an "element" attribute to attach to the Skywriter UI';
  345. console.error(error);
  346. pr.reject(error);
  347. return;
  348. }
  349. $(element).addClass(place);
  350. if (place == 'west' || place == 'east' || place == 'center') {
  351. if (!centerAdded) {
  352. container.appendChild(centerContainer);
  353. centerAdded = true;
  354. }
  355. centerContainer.appendChild(element);
  356. } else {
  357. container.appendChild(element);
  358. }
  359. // Call the elementAppended event if there is one.
  360. if (component.elementAppended) {
  361. component.elementAppended();
  362. }
  363. });
  364. pr.resolve();
  365. };
  366. });