Merge backlog of changes from master branch

This is too easy. I'm worried.
print-window-tiddler
Jeremy Ruston 2013-11-08 08:33:27 +00:00
commit 35adf4269a
38 zmienionych plików z 578 dodań i 53 usunięć

Wyświetl plik

@ -20,23 +20,16 @@ The module definitions on the browser look like this:
In practice, each module is wrapped in a separate script block. In practice, each module is wrapped in a separate script block.
\*/ \*/
(function() {
var _boot = (function($tw) {
/*jslint node: true, browser: true */ /*jslint node: true, browser: true */
/*global modules: false, $tw: false */ /*global modules: false, $tw: false */
"use strict"; "use strict";
/////////////////////////// Setting up $tw // Include bootprefix if we're not given module data
if(!$tw) {
// Set up $tw global for the server (set up for browser is in bootprefix.js) $tw = require("./bootprefix.js").bootprefix();
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");
} }
$tw.utils = $tw.utils || {}; $tw.utils = $tw.utils || {};
@ -318,6 +311,7 @@ name `.` refers to the current directory
*/ */
$tw.utils.resolvePath = function(sourcepath,rootpath) { $tw.utils.resolvePath = function(sourcepath,rootpath) {
// If the source path starts with ./ or ../ then it is relative to the root // If the source path starts with ./ or ../ then it is relative to the root
if(sourcepath.substr(0,2) === "./" || sourcepath.substr(0,3) === "../" ) { if(sourcepath.substr(0,2) === "./" || sourcepath.substr(0,3) === "../" ) {
var src = sourcepath.split("/"), var src = sourcepath.split("/"),
root = rootpath.split("/"); root = rootpath.split("/");
@ -337,7 +331,14 @@ $tw.utils.resolvePath = function(sourcepath,rootpath) {
return root.join("/"); return root.join("/");
} else { } else {
// If it isn't relative, just return the path // If it isn't relative, just return the path
return sourcepath; if(rootpath) {
var root = rootpath.split("/");
// Remove the filename part of the root
root.splice(root.length - 1, 1);
return root.join("/") + "/" + sourcepath;
} else {
return sourcepath;
}
} }
}; };
@ -367,9 +368,7 @@ $tw.utils.registerFileType = function(type,encoding,extension) {
Run code globally with specified context variables in scope Run code globally with specified context variables in scope
*/ */
$tw.utils.evalGlobal = function(code,context,filename) { $tw.utils.evalGlobal = function(code,context,filename) {
var contextCopy = $tw.utils.extend({},context,{ var contextCopy = $tw.utils.extend({},context);
exports: {}
});
// Get the context variables as a pair of arrays of names and values // Get the context variables as a pair of arrays of names and values
var contextNames = [], contextValues = []; var contextNames = [], contextValues = [];
$tw.utils.each(contextCopy,function(value,name) { $tw.utils.each(contextCopy,function(value,name) {
@ -394,9 +393,6 @@ Run code in a sandbox with only the specified context variables in scope
*/ */
$tw.utils.evalSandboxed = $tw.browser ? $tw.utils.evalGlobal : function(code,context,filename) { $tw.utils.evalSandboxed = $tw.browser ? $tw.utils.evalGlobal : function(code,context,filename) {
var sandbox = $tw.utils.extend({},context); var sandbox = $tw.utils.extend({},context);
$tw.utils.extend(sandbox,{
exports: {}
});
vm.runInNewContext(code,sandbox,filename); vm.runInNewContext(code,sandbox,filename);
return sandbox.exports; return sandbox.exports;
}; };
@ -545,12 +541,14 @@ $tw.utils.Crypto = function() {
Execute the module named 'moduleName'. The name can optionally be relative to the module named 'moduleRoot' Execute the module named 'moduleName'. The name can optionally be relative to the module named 'moduleRoot'
*/ */
$tw.modules.execute = function(moduleName,moduleRoot) { $tw.modules.execute = function(moduleName,moduleRoot) {
var name = moduleRoot ? $tw.utils.resolvePath(moduleName,moduleRoot) : moduleName, var name = moduleName[0] === "." ? $tw.utils.resolvePath(moduleName,moduleRoot) : moduleName,
moduleInfo = $tw.modules.titles[name], moduleInfo = $tw.modules.titles[name] || $tw.modules.titles[name + ".js"] || $tw.modules.titles[moduleName] || $tw.modules.titles[moduleName + ".js"] ,
tiddler = $tw.wiki.getTiddler(name), tiddler = $tw.wiki.getTiddler(name) || $tw.wiki.getTiddler(name + ".js") || $tw.wiki.getTiddler(moduleName) || $tw.wiki.getTiddler(moduleName + ".js") ,
_exports = {},
sandbox = { sandbox = {
module: moduleInfo, module: {},
exports: {}, //moduleInfo: moduleInfo,
exports: _exports,
console: console, console: console,
setInterval: setInterval, setInterval: setInterval,
clearInterval: clearInterval, clearInterval: clearInterval,
@ -558,18 +556,45 @@ $tw.modules.execute = function(moduleName,moduleRoot) {
clearTimeout: clearTimeout, clearTimeout: clearTimeout,
$tw: $tw, $tw: $tw,
require: function(title) { require: function(title) {
return $tw.modules.execute(title,name); return $tw.modules.execute(title, name);
} }
}; };
Object.defineProperty(sandbox.module, "id", {
value: name,
writable: false,
enumerable: true,
configurable: false
});
if(!$tw.browser) { if(!$tw.browser) {
$tw.utils.extend(sandbox,{ $tw.utils.extend(sandbox,{
process: process process: process
}); });
} else {
/*
CommonJS optional require.main property:
In a browser we offer a fake main module which points back to the boot function
(Theoretically, this may allow TW to eventually load itself as a module in the browser)
*/
Object.defineProperty(sandbox.require, "main", {
value: (typeof(require) !== "undefined") ? require.main : {TiddlyWiki: _boot},
writable: false,
enumerable: true,
configurable: false
});
} }
if(!moduleInfo) { if(!moduleInfo) {
// We could not find the module on this path
// Try to defer to browserify etc, or node
var deferredModule;
if($tw.browser) { if($tw.browser) {
return $tw.utils.error("Cannot find module named '" + moduleName + "' required by module '" + moduleRoot + "', resolved to " + name); if(window.require) {
try {
return window.require(moduleName);
} catch(e) {}
}
throw "Cannot find module named '" + moduleName + "' required by module '" + moduleRoot + "', resolved to " + name;
} else { } else {
// If we don't have a module with that name, let node.js try to find it // If we don't have a module with that name, let node.js try to find it
return require(moduleName); return require(moduleName);
@ -580,10 +605,11 @@ $tw.modules.execute = function(moduleName,moduleRoot) {
try { try {
// Check the type of the definition // Check the type of the definition
if(typeof moduleInfo.definition === "function") { // Function if(typeof moduleInfo.definition === "function") { // Function
moduleInfo.exports = {}; moduleInfo.exports = _exports;
moduleInfo.definition(moduleInfo,moduleInfo.exports,sandbox.require); moduleInfo.definition(moduleInfo,moduleInfo.exports,sandbox.require);
} else if(typeof moduleInfo.definition === "string") { // String } else if(typeof moduleInfo.definition === "string") { // String
moduleInfo.exports = $tw.utils.evalSandboxed(moduleInfo.definition,sandbox,tiddler.fields.title); moduleInfo.exports = _exports;
$tw.utils.evalSandboxed(moduleInfo.definition,sandbox,tiddler.fields.title);
} else { // Object } else { // Object
moduleInfo.exports = moduleInfo.definition; moduleInfo.exports = moduleInfo.definition;
} }
@ -1411,4 +1437,15 @@ if($tw.browser) {
$tw.boot.boot(); $tw.boot.boot();
} }
})(); return $tw;
});
if(typeof(exports) !== "undefined") {
exports.TiddlyWiki = _boot;
} else {
_boot(window.$tw);
}

Wyświetl plik

@ -12,12 +12,11 @@ See Boot.js for further details of the boot process.
\*/ \*/
// Set up $tw global for the browser var _bootprefix = (function($tw) {
if(typeof(window) === "undefined") {
global.$tw = global.$tw || {}; // No `browser` member for the server "use strict";
} else {
window.$tw = window.$tw || {browser: {}}; $tw = $tw || {browser: typeof(window) !== "undefined" ? {} : null};
}
/* /*
Information about each module is kept in an object with these members: Information about each module is kept in an object with these members:
@ -81,3 +80,18 @@ Convenience function for pushing a tiddler onto the preloading array
$tw.preloadTiddler = function(fields) { $tw.preloadTiddler = function(fields) {
$tw.preloadTiddlers.push(fields); $tw.preloadTiddlers.push(fields);
}; };
return $tw
});
if(typeof(exports) === "undefined") {
// Set up $tw global for the browser
window.$tw = _bootprefix();
} else {
// Export functionality as a module
exports.bootprefix = _bootprefix;
}

Wyświetl plik

@ -379,7 +379,7 @@ exports.findNextTag = function(source,pos,options) {
// Try to parse the candidate as a tag // Try to parse the candidate as a tag
var tag = this.parseTag(source,match.index,options); var tag = this.parseTag(source,match.index,options);
// Return success // Return success
if(tag) { if(tag && this.isLegalTag(tag.tag)) {
return tag; return tag;
} }
// Look for the next match // Look for the next match
@ -390,4 +390,17 @@ exports.findNextTag = function(source,pos,options) {
return null; return null;
}; };
exports.isLegalTag = function(tag) {
// If it starts with a $ then we'll let anything go
if(tag.charAt(0) === "$") {
return true;
// If it starts with a dash then it's not legal
} else if(tag.charAt(0) === "-") {
return false;
} else {
// Otherwise it's OK
return true;
}
};
})(); })();

Wyświetl plik

@ -875,38 +875,40 @@ exports.search = function(text,options) {
// Function to check a given tiddler for the search term // Function to check a given tiddler for the search term
var searchTiddler = function(title) { var searchTiddler = function(title) {
if(!searchTermsRegExps) { if(!searchTermsRegExps) {
return !options.invert; return false;
} }
var tiddler = self.getTiddler(title); var tiddler = self.getTiddler(title);
if(!tiddler) { if(!tiddler) {
tiddler = new $tw.Tiddler({title: title, text: "", type: "text/vnd.tiddlywiki"}); tiddler = new $tw.Tiddler({title: title, text: "", type: "text/vnd.tiddlywiki"});
} }
var contentTypeInfo = $tw.config.contentTypeInfo[tiddler.fields.type]; var contentTypeInfo = $tw.config.contentTypeInfo[tiddler.fields.type] || $tw.config.contentTypeInfo["text/vnd.tiddlywiki"],
if(contentTypeInfo ? contentTypeInfo.encoding === "utf8" : true) { match;
var match = true; for(var t=0; t<searchTermsRegExps.length; t++) {
for(var t=0; t<searchTermsRegExps.length; t++) { // Search title, tags and body
// Search title and body match = false;
if(match) { if(contentTypeInfo.encoding === "utf8") {
var tags = tiddler.fields.tags ? tiddler.fields.tags.join("\0") : ""; match = match || searchTermsRegExps[t].test(tiddler.fields.text);
match = searchTermsRegExps[t].test(tiddler.fields.title) || searchTermsRegExps[t].test(tags) || searchTermsRegExps[t].test(tiddler.fields.text); }
} var tags = tiddler.fields.tags ? tiddler.fields.tags.join("\0") : "";
match = match || searchTermsRegExps[t].test(tags) || searchTermsRegExps[t].test(tiddler.fields.title);
if(!match) {
return false;
} }
return options.invert ? !match : match;
} }
return false; return true;
}; };
// Loop through all the tiddlers doing the search // Loop through all the tiddlers doing the search
var results = []; var results = [];
if($tw.utils.isArray(options.titles)) { if($tw.utils.isArray(options.titles)) {
for(t=0; t<options.titles.length; t++) { for(t=0; t<options.titles.length; t++) {
if(searchTiddler(options.titles[t])) { if(!!searchTiddler(options.titles[t]) === !options.invert) {
results.push(options.titles[t]); results.push(options.titles[t]);
} }
} }
} else { } else {
var source = options.titles || this.tiddlers; var source = options.titles || this.tiddlers;
for(t in source) { for(t in source) {
if(searchTiddler(t)) { if(!!searchTiddler(t) === !options.invert) {
results.push(t); results.push(t);
} }
} }

Wyświetl plik

@ -0,0 +1,7 @@
title: GettingStarted
This wiki instance contains the CommonJS Modules/1.0 unit tests.
To run them, open a console repl and execute "$tw.modules.execute('allTests')" there. You should see no exceptions or output starting with "FAIL" in the console.

Wyświetl plik

@ -0,0 +1,11 @@
/*\
title: absolute/b.js
type: application/javascript
module-type: library
Absolute require test
\*/
exports.foo = function() {};

Wyświetl plik

@ -0,0 +1,16 @@
/*\
title: absolute/program.js
type: application/javascript
module-type: library
Absolute require test
\*/
var test = require('test');
var a = require('./submodule/a');
var b = require('./b');
test.assert(a.foo().foo === b.foo, 'require works with absolute identifiers');
test.print('DONE', 'info');

Wyświetl plik

@ -0,0 +1,14 @@
/*\
title: absolute/submodule/a.js
type: application/javascript
module-type: library
Absolute require test
\*/
exports.foo = function () {
return require('../b');
};

Wyświetl plik

@ -0,0 +1,23 @@
/*\
title: allTests.js
type: application/javascript
module-type: library
Runs all CommonJS Modules tests
\*/
$tw.modules.execute('absolute/program.js');
$tw.modules.execute('cyclic/program.js');
$tw.modules.execute('determinism/program.js');
$tw.modules.execute('exactExports/program.js');
$tw.modules.execute('hasOwnProperty/program.js');
$tw.modules.execute('method/program.js');
$tw.modules.execute('missing/program.js');
$tw.modules.execute('monkeys/program.js');
$tw.modules.execute('nested/program.js');
$tw.modules.execute('relative/program.js');
$tw.modules.execute('transitive/program.js');

Wyświetl plik

@ -0,0 +1,15 @@
/*\
title: cyclic/a.js
type: application/javascript
module-type: library
Cycle require test A
\*/
exports.a = function () {
return b;
};
var b = require('./b');

Wyświetl plik

@ -0,0 +1,16 @@
/*\
title: cyclic/b.js
type: application/javascript
module-type: library
Cycle require test B
\*/
var a = require('./a');
exports.b = function () {
return a;
};

Wyświetl plik

@ -0,0 +1,22 @@
/*\
title: cyclic/program.js
type: application/javascript
module-type: library
Cycle require test
\*/
var test = require('test');
var a = require('./a');
var b = require('./b');
test.assert(a.a, 'a exists');
test.assert(b.b, 'b exists')
test.assert(a.a().b === b.b, 'a gets b');
test.assert(b.b().a === a.a, 'b gets a');
test.print('DONE', 'info');

Wyświetl plik

@ -0,0 +1,14 @@
/*\
title: determinism/program.js
type: application/javascript
module-type: library
Determinism test
\*/
var test = require('test');
require('submodule/a');
test.print('DONE', 'info');

Wyświetl plik

@ -0,0 +1,20 @@
/*\
title: determinism/submodule/a.js
type: application/javascript
module-type: library
Determinism require test A
\*/
var test = require('test');
var pass = false;
var test = require('test');
try {
require('a');
} catch (exception) {
pass = true;
}
test.assert(pass, 'require does not fall back to relative modules when absolutes are not available.')

Wyświetl plik

@ -0,0 +1,15 @@
/*\
title: exactExports/a.js
type: application/javascript
module-type: library
ExactExports test A
\*/
exports.program = function () {
return require('./program');
};

Wyświetl plik

@ -0,0 +1,16 @@
/*\
title: exactExports/program.js
type: application/javascript
module-type: library
ExactExports test
\*/
var test = require('test');
var a = require('./a');
test.assert(a.program() === exports, 'exact exports');
test.print('DONE', 'info');

Wyświetl plik

@ -0,0 +1,8 @@
/*\
title: hasOwnProperty.js
type: application/javascript
module-type: library
OwnProperty test A
\*/

Wyświetl plik

@ -0,0 +1,15 @@
/*\
title: hasOwnProperty/program.js
type: application/javascript
module-type: library
OwnProperty test
\*/
var hasOwnProperty = require('hasOwnProperty');
var toString = require('toString');
var test = require('test');
test.print('DONE', 'info');

Wyświetl plik

@ -0,0 +1,8 @@
/*\
title: toString.js
type: application/javascript
module-type: library
OwnProperty test B
\*/

Wyświetl plik

@ -0,0 +1,23 @@
/*\
title: method/a.js
type: application/javascript
module-type: library
Method test
\*/
exports.foo = function () {
return this;
};
exports.set = function (x) {
this.x = x;
};
exports.get = function () {
return this.x;
};
exports.getClosed = function () {
return exports.x;
};

Wyświetl plik

@ -0,0 +1,19 @@
/*\
title: method/program.js
type: application/javascript
module-type: library
Method test
\*/
var test = require('test');
var a = require('./a');
var foo = a.foo;
test.assert(a.foo() == a, 'calling a module member');
test.assert(foo() == (function (){return this})(), 'members not implicitly bound');
a.set(10);
test.assert(a.get() == 10, 'get and set')
test.print('DONE', 'info');

Wyświetl plik

@ -0,0 +1,19 @@
/*\
title: missing/program.js
type: application/javascript
module-type: library
Missing test
\*/
var test = require('test');
try {
require('bogus');
test.print('FAIL require throws error when module missing', 'fail');
} catch (exception) {
test.print('PASS require throws error when module missing', 'pass');
}
test.print('DONE', 'info');

Wyświetl plik

@ -0,0 +1,12 @@
/*\
title: monkeys/a.js
type: application/javascript
module-type: library
Monkeys test A
\*/
require('./program').monkey = 10;

Wyświetl plik

@ -0,0 +1,15 @@
/*\
title: monkeys/program.js
type: application/javascript
module-type: library
Monkeys test
\*/
var a = require('./a');
var test = require('test');
test.assert(exports.monkey == 10, 'monkeys permitted');
test.print('DONE', 'info');

Wyświetl plik

@ -0,0 +1,14 @@
/*\
title: a/b/c/d.js
type: application/javascript
module-type: library
Nested test
\*/
exports.foo = function () {
return 1;
};

Wyświetl plik

@ -0,0 +1,14 @@
/*\
title: nested/program.js
type: application/javascript
module-type: library
Nested test
\*/
var test = require('test');
test.assert(require('a/b/c/d').foo() == 1, 'nested module identifier');
test.print('DONE', 'info');

Wyświetl plik

@ -0,0 +1,16 @@
/*\
title: relative/program.js
type: application/javascript
module-type: library
Relative test
\*/
var test = require('test');
var a = require('submodule/a');
var b = require('submodule/b');
test.assert(a.foo == b.foo, 'a and b share foo through a relative require');
test.print('DONE', 'info');

Wyświetl plik

@ -0,0 +1,13 @@
/*\
title: submodule/a.js
type: application/javascript
module-type: library
Relative test A
\*/
exports.foo = require('./b').foo;

Wyświetl plik

@ -0,0 +1,12 @@
/*\
title: submodule/b.js
type: application/javascript
module-type: library
Relative test B
\*/
exports.foo = function () {
};

Wyświetl plik

@ -0,0 +1,23 @@
/*\
title: test.js
type: application/javascript
module-type: library
testing lib
\*/
exports.assert = function(cond, msg) {
if(!cond) {
if(msg) {
throw msg
} else {
throw "ASSERT FAILED"
}
}
}
exports.print = function() {
console.log.apply(console, arguments);
}

Wyświetl plik

@ -0,0 +1,11 @@
/*\
title: transitive/a.js
type: application/javascript
module-type: library
Transitive test A
\*/
exports.foo = require('./b').foo;

Wyświetl plik

@ -0,0 +1,12 @@
/*\
title: transitive/b.js
type: application/javascript
module-type: library
Transitive test B
\*/
exports.foo = require('./c').foo;

Wyświetl plik

@ -0,0 +1,14 @@
/*\
title: transitive/c.js
type: application/javascript
module-type: library
Transitive test C
\*/
exports.foo = function () {
return 1;
};

Wyświetl plik

@ -0,0 +1,13 @@
/*\
title: transitive/program.js
type: application/javascript
module-type: library
Transitive test
\*/
var test = require('test');
test.assert(require('./a').foo() == 1, 'transitive');
test.print('DONE', 'info');

Wyświetl plik

@ -0,0 +1,8 @@
{
"plugins": [
"tiddlywiki/fullscreen"
],
"themes": [
"tiddlywiki/snowwhite"
]
}

Wyświetl plik

@ -27,6 +27,7 @@ exports.startup = function() {
clearInterval: clearInterval, clearInterval: clearInterval,
setTimeout: setTimeout, setTimeout: setTimeout,
clearTimeout: clearTimeout, clearTimeout: clearTimeout,
exports: {},
$tw: $tw $tw: $tw
}); });
// Prepare the Jasmine environment // Prepare the Jasmine environment

Wyświetl plik

@ -1,4 +1,4 @@
title: $:/themes/tiddlywiki/centralised/styles.tid title: $:/themes/tiddlywiki/readonly/styles.tid
tags: [[$:/tags/stylesheet]] tags: [[$:/tags/stylesheet]]
\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline \rules only filteredtranscludeinline transcludeinline macrodef macrocallinline

Wyświetl plik

@ -4,7 +4,7 @@
This is invoked as a shell script by NPM when the `tiddlywiki` command is typed This is invoked as a shell script by NPM when the `tiddlywiki` command is typed
*/ */
var $tw = require("./boot/boot.js").$tw; var $tw = require("./boot/boot.js").TiddlyWiki();
// Pass the command line arguments to the boot kernel // Pass the command line arguments to the boot kernel
$tw.boot.argv = Array.prototype.slice.call(process.argv,2); $tw.boot.argv = Array.prototype.slice.call(process.argv,2);