diff --git a/core/boot.js b/core/boot.js index 1b3df9aec..fceab0ae6 100644 --- a/core/boot.js +++ b/core/boot.js @@ -29,11 +29,16 @@ In practice, each module is wrapped in a separate script block. /////////////////////////// Setting up $tw // Set up $tw global for the server -if(typeof(window) === "undefined" && !global.$tw) { - global.$tw = {}; // No `browser` member for the server +if(typeof(window) === "undefined") { + global.$tw = global.$tw || {}; // No `browser` member for the server exports.$tw = $tw; // Export $tw for when boot.js is required directly in node.js } +// Include bootprefix if we're on the server +if(!$tw.browser) { + require("./bootprefix.js"); +} + // Crypto helper object // Setup crypto @@ -57,7 +62,6 @@ var Crypto = function() { password = window.prompt("Enter password to decrypt TiddlyWiki"); } }; - this.setPassword = function(newPassword) { password = newPassword; }; @@ -293,19 +297,6 @@ if(!$tw.browser) { /////////////////////////// Module mechanism -/* -Register the exports of a single module in the $tw.modules.types hashmap -*/ -$tw.modules.registerModuleExports = function(name,moduleType,moduleExports) { - if(!$tw.utils.hop($tw.modules.types,moduleType)) { - $tw.modules.types[moduleType] = {}; - } - if($tw.utils.hop($tw.modules.types[moduleType],name)) { - console.log("Warning: Reregistering module - " + name); - } - $tw.modules.types[moduleType][name] = moduleExports; -}; - /* Apply a callback to each module of a particular type moduleType: type of modules to enumerate @@ -316,7 +307,7 @@ $tw.modules.forEachModuleOfType = function(moduleType,callback) { if(modules) { for(var title in modules) { if($tw.utils.hop(modules,title)) { - callback(title,modules[title]); + callback(title,$tw.modules.execute(title)); } } } @@ -379,6 +370,7 @@ $tw.Tiddler = function(/* [fields,] fields */) { $tw.Tiddler.prototype.hasField = function(field) { return $tw.utils.hop(this.fields,field); }; + /* Hashmap of field modules by field name */ @@ -387,17 +379,17 @@ $tw.Tiddler.fieldModules = {}; /* Register and install the built in tiddler field modules */ -$tw.modules.registerModuleExports("$:/boot/tiddlerfields/modified","tiddlerfield",{ +$tw.modules.define("$:/boot/tiddlerfields/modified","tiddlerfield",{ name: "modified", parse: $tw.utils.parseDate, stringify: $tw.utils.stringifyDate }); -$tw.modules.registerModuleExports("$:/boot/tiddlerfields/created","tiddlerfield",{ +$tw.modules.define("$:/boot/tiddlerfields/created","tiddlerfield",{ name: "created", parse: $tw.utils.parseDate, stringify: $tw.utils.stringifyDate }); -$tw.modules.registerModuleExports("$:/boot/tiddlerfields/tags","tiddlerfield",{ +$tw.modules.define("$:/boot/tiddlerfields/tags","tiddlerfield",{ name: "tags", parse: $tw.utils.parseStringArray, stringify: function(value) { @@ -412,8 +404,6 @@ $tw.modules.registerModuleExports("$:/boot/tiddlerfields/tags","tiddlerfield",{ return result.join(" "); } }); -// Install built in tiddler fields module so that they are available immediately -$tw.Tiddler.fieldModules = $tw.modules.getModulesByTypeAsHashmap("tiddlerfield"); /////////////////////////// Barebones wiki store @@ -422,6 +412,8 @@ Construct a wiki store object */ $tw.Wiki = function() { this.tiddlers = {}; + this.bundles = {}; // Hashmap of plugin information by title + this.bundledTiddlers = {}; // Hashmap of constituent tiddlers from plugins by title }; $tw.Wiki.prototype.addTiddler = function(tiddler) { @@ -441,8 +433,6 @@ $tw.Wiki.prototype.addTiddlers = function(tiddlers) { Extract constituent tiddlers from bundle tiddlers so that we can easily access them in getTiddler() */ $tw.Wiki.prototype.unpackBundleTiddlers = function() { - this.bundles = {}; // Hashmap of plugin information by title - this.bundledTiddlers = {}; // Hashmap of constituent tiddlers from plugins by title // Collect up all the plugin tiddlers for(var title in this.tiddlers) { var tiddler = this.tiddlers[title]; @@ -463,52 +453,36 @@ $tw.Wiki.prototype.unpackBundleTiddlers = function() { } }; +/* +Define all modules stored in ordinary tiddlers +*/ +$tw.Wiki.prototype.defineTiddlerModules = function() { + for(var title in this.tiddlers) { + if($tw.utils.hop(this.tiddlers,title)) { + var tiddler = this.getTiddler(title); + if(tiddler.fields.type === "application/javascript" && tiddler.hasField("module-type")) { + // Define the module + $tw.modules.define(tiddler.fields.title,tiddler.fields["module-type"],tiddler.fields.text); + } + } + } +}; + /* Register all the module tiddlers that have a module type */ -$tw.Wiki.prototype.registerModuleTiddlers = function() { - /*jslint evil: true */ - var title, tiddler; - // If in the browser, define any modules from bundles - if($tw.browser) { - for(title in $tw.wiki.bundledTiddlers) { - if($tw.utils.hop($tw.wiki.bundledTiddlers,title)) { - tiddler = $tw.wiki.getTiddler(title); - if(!$tw.utils.hop($tw.wiki.tiddlers,title)) { - if(tiddler.fields.type === "application/javascript" && tiddler.hasField("module-type")) { - // Define the module - var source = [ - "(function(module,exports,require) {", - tiddler.fields.text, - "})" - ]; - $tw.modules.define(tiddler.fields.title,tiddler.fields["module-type"],window["eval"](source.join(""))); - } - } - } - } - } - // Register and execute any modules from bundles - for(title in $tw.wiki.bundledTiddlers) { - if($tw.utils.hop($tw.wiki.bundledTiddlers,title)) { - tiddler = $tw.wiki.getTiddler(title); - if(!$tw.utils.hop($tw.wiki.tiddlers,title)) { +$tw.Wiki.prototype.defineBundledModules = function() { + for(var title in this.bundledTiddlers) { + if($tw.utils.hop(this.bundledTiddlers,title)) { + var tiddler = this.getTiddler(title); + if(!$tw.utils.hop(this.tiddlers,title)) { if(tiddler.fields.type === "application/javascript" && tiddler.hasField("module-type")) { - // Execute and register the module - $tw.modules.registerModuleExports(title,tiddler.fields["module-type"],$tw.modules.execute(title)); + // Define the module + $tw.modules.define(tiddler.fields.title,tiddler.fields["module-type"],tiddler.fields.text); } } } } - // Register and execute any modules in ordinary tiddlers - for(title in $tw.wiki.tiddlers) { - if($tw.utils.hop($tw.wiki.tiddlers,title)) { - tiddler = $tw.wiki.getTiddler(title); - if(tiddler.fields.type === "application/javascript" && tiddler.hasField("module-type")) { - $tw.modules.registerModuleExports(title,tiddler.fields["module-type"],$tw.modules.execute(title)); - } - } - } }; $tw.Wiki.prototype.getTiddler = function(title) { @@ -558,7 +532,7 @@ $tw.Wiki.prototype.deserializeTiddlers = function(type,text,srcFields) { /* Register the built in tiddler deserializer modules */ -$tw.modules.registerModuleExports("$:/boot/tiddlerdeserializer/js","tiddlerdeserializer",{ +$tw.modules.define("$:/boot/tiddlerdeserializer/js","tiddlerdeserializer",{ "application/javascript": function(text,fields) { var headerCommentRegExp = new RegExp($tw.config.jsModuleHeaderRegExpString,"mg"), match = headerCommentRegExp.exec(text); @@ -569,7 +543,7 @@ $tw.modules.registerModuleExports("$:/boot/tiddlerdeserializer/js","tiddlerdeser return [fields]; } }); -$tw.modules.registerModuleExports("$:/boot/tiddlerdeserializer/tid","tiddlerdeserializer",{ +$tw.modules.define("$:/boot/tiddlerdeserializer/tid","tiddlerdeserializer",{ "application/x-tiddler": function(text,fields) { var split = text.split(/\r?\n\r?\n/mg); if(split.length > 1) { @@ -581,30 +555,27 @@ $tw.modules.registerModuleExports("$:/boot/tiddlerdeserializer/tid","tiddlerdese return [fields]; } }); -$tw.modules.registerModuleExports("$:/boot/tiddlerdeserializer/txt","tiddlerdeserializer",{ +$tw.modules.define("$:/boot/tiddlerdeserializer/txt","tiddlerdeserializer",{ "text/plain": function(text,fields) { fields.text = text; fields.type = "text/plain"; return [fields]; } }); -$tw.modules.registerModuleExports("$:/boot/tiddlerdeserializer/html","tiddlerdeserializer",{ +$tw.modules.define("$:/boot/tiddlerdeserializer/html","tiddlerdeserializer",{ "text/html": function(text,fields) { fields.text = text; fields.type = "text/html"; return [fields]; } }); -$tw.modules.registerModuleExports("$:/boot/tiddlerdeserializer/json","tiddlerdeserializer",{ +$tw.modules.define("$:/boot/tiddlerdeserializer/json","tiddlerdeserializer",{ "application/json": function(text,fields) { var tiddlers = JSON.parse(text); return tiddlers; } }); -// Install the tiddler deserializer modules so they are immediately available -$tw.modules.applyMethods("tiddlerdeserializer",$tw.Wiki.tiddlerDeserializerModules); - /////////////////////////// Intermediate initialisation /* @@ -625,23 +596,29 @@ $tw.modules.execute = function(moduleName,moduleRoot) { return $tw.modules.execute(modRequire,name); }, exports = {}, - module = $tw.modules.titles[name]; - if(!module) { + moduleInfo = $tw.modules.titles[name]; + if(!moduleInfo) { throw new Error("Cannot find module named '" + moduleName + "' required by module '" + moduleRoot + "', resolved to " + name); } - if(module.exports) { - return module.exports; - } else { - module.exports = {}; - module.fn(module,module.exports,require); - return module.exports; + if(!moduleInfo.exports) { + if(typeof moduleInfo.definition === "string") { // String + moduleInfo.definition = window["eval"]("(function(module,exports,require) {" + moduleInfo.definition + "})"); + moduleInfo.exports = {}; + moduleInfo.definition(moduleInfo,moduleInfo.exports,require); + } else if(typeof moduleInfo.definition === "function") { // Function + moduleInfo.exports = {}; + moduleInfo.definition(moduleInfo,moduleInfo.exports,require); + } else { // Object + moduleInfo.exports = moduleInfo.definition; + } } + return moduleInfo.exports; }; /* Register a deserializer that can extract tiddlers from the DOM */ -$tw.modules.registerModuleExports("$:/boot/tiddlerdeserializer/dom","tiddlerdeserializer",{ +$tw.modules.define("$:/boot/tiddlerdeserializer/dom","tiddlerdeserializer",{ "(DOM)": function(node) { var extractTextTiddlers = function(node) { var e = node.firstChild; @@ -714,8 +691,26 @@ $tw.modules.registerModuleExports("$:/boot/tiddlerdeserializer/dom","tiddlerdese return result; } }); -// Install the tiddler deserializer modules -$tw.modules.applyMethods("tiddlerdeserializer",$tw.Wiki.tiddlerDeserializerModules); + +$tw.loadTiddlers = function() { + // In the browser, we load tiddlers from certain elements + var containerIds = [ + "libraryModules", + "modules", + "bootKernelPrefix", + "bootKernel", + "styleArea", + "storeArea", + "shadowArea" + ]; + for(var t=0; t