1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2026-01-25 04:14:40 +00:00

Compare commits

..

3 Commits

Author SHA1 Message Date
buggyj
b9e3550747 added global macro file for tw2 parser 2014-04-15 18:44:25 +01:00
buggyj
3d1a8ee703 added updated tw2 parser 2014-04-15 12:45:23 +01:00
buggyj
17902d1a1e added tw2 original from 3d38d4add3/plugins/tiddlywiki/tw2parser 2014-04-15 12:29:16 +01:00
442 changed files with 2937 additions and 7564 deletions

View File

@@ -19,6 +19,8 @@ Error message and password prompt
left: 50%;
margin-left: -144px; /* - width/2 - paddingHorz/2 - border */
padding: 16px 16px 16px 16px;
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
border-radius: 8px;
}

View File

@@ -32,8 +32,8 @@ if(!$tw) {
$tw = require("./bootprefix.js").bootprefix();
}
$tw.utils = $tw.utils || Object.create(null);
$tw.boot = $tw.boot || Object.create(null);
$tw.utils = $tw.utils || {};
$tw.boot = $tw.boot || {};
/////////////////////////// Standard node.js libraries
@@ -73,11 +73,13 @@ Iterate through all the own properties of an object or array. Callback is invoke
$tw.utils.each = function(object,callback) {
var f;
if(object) {
if(Object.prototype.toString.call(object) == "[object Array]") {
object.forEach(callback);
if($tw.utils.isArray(object)) {
for(f=0; f<object.length; f++) {
callback(object[f],f,object);
}
} else {
for(f in object) {
if(Object.prototype.hasOwnProperty.call(object,f)) {
if($tw.utils.hop(object,f)) {
callback(object[f],f,object);
}
}
@@ -105,7 +107,7 @@ $tw.utils.domMaker = function(tag,options) {
element.className = options["class"];
}
if(options.text) {
element.appendChild(doc.createTextNode(options.text));
element.appendChild(document.createTextNode(options.text));
}
$tw.utils.each(options.children,function(child) {
element.appendChild(child);
@@ -280,7 +282,7 @@ $tw.utils.parseStringArray = function(value) {
// Parse a block of name:value fields. The `fields` object is used as the basis for the return value
$tw.utils.parseFields = function(text,fields) {
fields = fields || Object.create(null);
fields = fields || {};
text.split(/\r?\n/mg).forEach(function(line) {
if(line.charAt(0) !== "#") {
var p = line.indexOf(":");
@@ -352,16 +354,11 @@ $tw.utils.parseVersion = function(version) {
};
/*
Returns true if the version string A is greater than the version string B. Returns true if the versions are the same
Returns true if the version string A is greater than the version string B
*/
$tw.utils.checkVersions = function(versionStringA,versionStringB) {
var defaultVersion = {
major: 0,
minor: 0,
patch: 0
},
versionA = $tw.utils.parseVersion(versionStringA) || defaultVersion,
versionB = $tw.utils.parseVersion(versionStringB) || defaultVersion,
var versionA = $tw.utils.parseVersion(versionStringA),
versionB = $tw.utils.parseVersion(versionStringB),
diff = [
versionA.major - versionB.major,
versionA.minor - versionB.minor,
@@ -369,38 +366,23 @@ $tw.utils.checkVersions = function(versionStringA,versionStringB) {
];
return (diff[0] > 0) ||
(diff[0] === 0 && diff[1] > 0) ||
(diff[0] === 0 && diff[1] === 0 && diff[2] > 0) ||
(diff[0] === 0 && diff[1] === 0 && diff[2] === 0);
(diff[0] === 0 && diff[1] === 0 && diff[2] > 0);
};
/*
Register file type information
options: {flags: flags,deserializerType: deserializerType}
flags:"image" for image types
deserializerType: defaults to type if not specified
flags: "image" for image types
*/
$tw.utils.registerFileType = function(type,encoding,extension,options) {
options = options || {};
$tw.config.fileExtensionInfo[extension] = {type: type};
$tw.config.contentTypeInfo[type] = {encoding: encoding, extension: extension, flags: options.flags || [], deserializerType: options.deserializerType || type};
};
/*
Given an extension, get the correct encoding for that file.
defaults to utf8
*/
$tw.utils.getTypeEncoding = function(ext) {
var extensionInfo = $tw.config.fileExtensionInfo[ext],
type = extensionInfo ? extensionInfo.type : null,
typeInfo = type ? $tw.config.contentTypeInfo[type] : null;
return typeInfo ? typeInfo.encoding : "utf8";
$tw.utils.registerFileType = function(type,encoding,extension,flags) {
$tw.config.fileExtensionInfo[extension] = {type: type};
$tw.config.contentTypeInfo[type] = {encoding: encoding, extension: extension, flags: flags || []};
};
/*
Run code globally with specified context variables in scope
*/
$tw.utils.evalGlobal = function(code,context,filename) {
var contextCopy = $tw.utils.extend(Object.create(null),context);
var contextCopy = $tw.utils.extend({},context);
// Get the context variables as a pair of arrays of names and values
var contextNames = [], contextValues = [];
$tw.utils.each(contextCopy,function(value,name) {
@@ -412,7 +394,7 @@ $tw.utils.evalGlobal = function(code,context,filename) {
// Compile the code into a function
var fn;
if($tw.browser) {
fn = window["eval"](code + "\n\n//# sourceURL=" + filename);
fn = window["eval"](code);
} else {
fn = vm.runInThisContext(code,filename);
}
@@ -424,7 +406,7 @@ $tw.utils.evalGlobal = function(code,context,filename) {
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) {
var sandbox = $tw.utils.extend(Object.create(null),context);
var sandbox = $tw.utils.extend({},context);
vm.runInNewContext(code,sandbox,filename);
return sandbox.exports;
};
@@ -687,7 +669,7 @@ Apply a callback to each module of a particular type
*/
$tw.modules.forEachModuleOfType = function(moduleType,callback) {
var modules = $tw.modules.types[moduleType];
$tw.utils.each(modules,function(element,title) {
$tw.utils.each(modules,function(element,title,object) {
callback(title,$tw.modules.execute(title));
});
};
@@ -697,7 +679,7 @@ Get all the modules of a particular type in a hashmap by their `name` field
*/
$tw.modules.getModulesByTypeAsHashmap = function(moduleType,nameField) {
nameField = nameField || "name";
var results = Object.create(null);
var results = {};
$tw.modules.forEachModuleOfType(moduleType,function(title,module) {
results[module[nameField]] = module;
});
@@ -709,7 +691,7 @@ Apply the exports of the modules of a particular type to a target object
*/
$tw.modules.applyMethods = function(moduleType,targetObject) {
if(!targetObject) {
targetObject = Object.create(null);
targetObject = {};
}
$tw.modules.forEachModuleOfType(moduleType,function(title,module) {
$tw.utils.each(module,function(element,title,object) {
@@ -723,7 +705,7 @@ $tw.modules.applyMethods = function(moduleType,targetObject) {
Return an array of classes created from the modules of a specified type. Each module should export the properties to be added to those of the optional base class
*/
$tw.modules.createClassesFromModules = function(moduleType,subType,baseClass) {
var classes = Object.create(null);
var classes = {};
$tw.modules.forEachModuleOfType(moduleType,function(title,moduleExports) {
if(!subType || moduleExports.types[subType]) {
var newClass = function() {};
@@ -745,34 +727,26 @@ Construct a tiddler object from a hashmap of tiddler fields. If multiple hasmaps
taking precedence to the right
*/
$tw.Tiddler = function(/* [fields,] fields */) {
this.fields = Object.create(null);
this.fields = {};
for(var c=0; c<arguments.length; c++) {
var arg = arguments[c],
src = (arg instanceof $tw.Tiddler) ? arg.fields : arg;
for(var t in src) {
if(src[t] === undefined || src[t] === null) {
if(src[t] === undefined) {
if(t in this.fields) {
delete this.fields[t]; // If we get a field that's undefined, delete any previous field value
}
} else {
// Parse the field with the associated field module (if any)
var fieldModule = $tw.Tiddler.fieldModules[t],
value;
var fieldModule = $tw.Tiddler.fieldModules[t];
if(fieldModule && fieldModule.parse) {
value = fieldModule.parse.call(this,src[t]);
this.fields[t] = fieldModule.parse.call(this,src[t]);
} else {
value = src[t];
this.fields[t] = src[t];
}
// Freeze the field to keep it immutable
if(typeof value === "object") {
Object.freeze(value);
}
this.fields[t] = value;
}
}
}
// Freeze the tiddler against modification
Object.freeze(this.fields);
};
$tw.Tiddler.prototype.hasField = function(field) {
@@ -811,206 +785,115 @@ $tw.modules.define("$:/boot/tiddlerfields/list","tiddlerfield",{
/////////////////////////// Barebones wiki store
/*
Wiki constructor. State is stored in private members that only a small number of privileged accessor methods have direct access. Methods added via the prototype have to use these accessors and cannot access the state data directly.
options include:
shadowTiddlers: Array of shadow tiddlers to be added
Construct a wiki store object
*/
$tw.Wiki = function(options) {
options = options || {};
var self = this,
tiddlers = Object.create(null), // Hashmap of tiddlers
pluginTiddlers = [], // Array of tiddlers containing registered plugins, ordered by priority
pluginInfo = Object.create(null), // Hashmap of parsed plugin content
shadowTiddlers = options.shadowTiddlers || Object.create(null); // Hashmap by title of {source:, tiddler:}
// Add a tiddler to the store
this.addTiddler = function(tiddler) {
if(!(tiddler instanceof $tw.Tiddler)) {
tiddler = new $tw.Tiddler(tiddler);
}
// Save the tiddler
if(tiddler) {
var title = tiddler.fields.title;
if(title) {
tiddlers[title] = tiddler;
this.clearCache(title);
this.clearGlobalCache();
this.enqueueTiddlerEvent(title);
}
}
};
// Delete a tiddler
this.deleteTiddler = function(title) {
delete tiddlers[title];
this.clearCache(title);
this.clearGlobalCache();
this.enqueueTiddlerEvent(title,true);
};
// Get a tiddler from the store
this.getTiddler = function(title) {
var t = tiddlers[title];
if(t instanceof $tw.Tiddler) {
return t;
} else if(title !== undefined && Object.prototype.hasOwnProperty.call(shadowTiddlers,title)) {
return shadowTiddlers[title].tiddler;
} else {
return undefined;
}
};
// Get an array of all tiddler titles
this.allTitles = function() {
return Object.keys(tiddlers);
};
// Iterate through all tiddler titles
this.each = function(callback) {
for(var title in tiddlers) {
callback(tiddlers[title],title);
}
};
// Get an array of all shadow tiddler titles
this.allShadowTitles = function() {
return Object.keys(shadowTiddlers);
};
// Iterate through all shadow tiddler titles
this.eachShadow = function(callback) {
for(var title in shadowTiddlers) {
var shadowInfo = shadowTiddlers[title];
callback(shadowInfo.tiddler,title);
}
};
// Test for the existence of a tiddler
this.tiddlerExists = function(title) {
return !!$tw.utils.hop(tiddlers,title);
};
// Determines if a tiddler is a shadow tiddler, regardless of whether it has been overridden by a real tiddler
this.isShadowTiddler = function(title) {
return $tw.utils.hop(shadowTiddlers,title);
};
this.getShadowSource = function(title) {
if($tw.utils.hop(shadowTiddlers,title)) {
return shadowTiddlers[title].source;
}
return null;
};
// Read plugin info for all plugins
this.readPluginInfo = function() {
for(var title in tiddlers) {
var tiddler = tiddlers[title];
if(tiddler.fields.type === "application/json" && tiddler.hasField("plugin-type")) {
pluginInfo[tiddler.fields.title] = JSON.parse(tiddler.fields.text);
}
}
};
// Get plugin info for a plugin
this.getPluginInfo = function(title) {
return pluginInfo[title];
};
// Register the plugin tiddlers of a particular type, optionally restricting registration to an array of tiddler titles. Return the array of titles affected
this.registerPluginTiddlers = function(pluginType,titles) {
var self = this,
registeredTitles = [],
checkTiddler = function(tiddler) {
if(tiddler && tiddler.fields.type === "application/json" && tiddler.fields["plugin-type"] === pluginType) {
pluginTiddlers.push(tiddler);
registeredTitles.push(tiddler.fields.title);
}
};
if(titles) {
$tw.utils.each(titles,function(title) {
checkTiddler(self.getTiddler(title));
});
} else {
this.each(function(tiddler,title) {
checkTiddler(tiddler);
});
}
return registeredTitles;
};
// Unregister the plugin tiddlers of a particular type, returning an array of the titles affected
this.unregisterPluginTiddlers = function(pluginType) {
var self = this,
titles = [];
// Remove any previous registered plugins of this type
for(var t=pluginTiddlers.length-1; t>=0; t--) {
var tiddler = pluginTiddlers[t];
if(tiddler.fields["plugin-type"] === pluginType) {
titles.push(tiddler.fields.title);
pluginTiddlers.splice(t,1);
}
}
return titles;
};
// Unpack the currently registered plugins, creating shadow tiddlers for their constituent tiddlers
this.unpackPluginTiddlers = function() {
var self = this;
// Sort the plugin titles by the `plugin-priority` field
pluginTiddlers.sort(function(a,b) {
if("plugin-priority" in a.fields && "plugin-priority" in b.fields) {
return a.fields["plugin-priority"] - b.fields["plugin-priority"];
} else if("plugin-priority" in a.fields) {
return -1;
} else if("plugin-priority" in b.fields) {
return +1;
} else if(a.fields.title < b.fields.title) {
return -1;
} else if(a.fields.title === b.fields.title) {
return 0;
} else {
return +1;
}
});
// Now go through the plugins in ascending order and assign the shadows
shadowTiddlers = Object.create(null);
$tw.utils.each(pluginTiddlers,function(tiddler) {
// Extract the constituent tiddlers
if($tw.utils.hop(pluginInfo,tiddler.fields.title)) {
$tw.utils.each(pluginInfo[tiddler.fields.title].tiddlers,function(constituentTiddler,constituentTitle) {
// Save the tiddler object
if(constituentTitle) {
shadowTiddlers[constituentTitle] = {
source: tiddler.fields.title,
tiddler: new $tw.Tiddler(constituentTiddler,{title: constituentTitle})
};
}
});
}
});
};
$tw.Wiki = function() {
this.tiddlers = {};
this.plugins = []; // Array of registered plugins, ordered by priority
this.shadowTiddlers = {}; // Hashmap by title of {source:, tiddler:}
};
// Dummy methods that will be filled in after boot
$tw.Wiki.prototype.clearCache =
$tw.Wiki.prototype.clearGlobalCache =
$tw.Wiki.prototype.enqueueTiddlerEvent = function() {};
$tw.Wiki.prototype.addTiddler = function(tiddler) {
if(!(tiddler instanceof $tw.Tiddler)) {
tiddler = new $tw.Tiddler(tiddler);
}
if(tiddler.fields.title) {
this.tiddlers[tiddler.fields.title] = tiddler;
}
};
// Add an array of tiddlers
$tw.Wiki.prototype.addTiddlers = function(tiddlers) {
for(var t=0; t<tiddlers.length; t++) {
this.addTiddler(tiddlers[t]);
}
};
/*
Register the plugin tiddlers of a particular type, optionally restricting registration to an array of tiddler titles. Return the array of titles affected
*/
$tw.Wiki.prototype.registerPluginTiddlers = function(pluginType,titles) {
var self = this,
registeredTitles = [];
// Go through the provided titles, or the entire tiddler list, looking for plugins of this type
var checkTiddler = function(tiddler) {
if(tiddler && tiddler.fields.type === "application/json" && tiddler.fields["plugin-type"] === pluginType) {
self.plugins.push(tiddler);
registeredTitles.push(tiddler.fields.title);
}
};
if(titles) {
$tw.utils.each(titles,function(title) {
checkTiddler(self.getTiddler(title));
});
} else {
$tw.utils.each(this.tiddlers,function(tiddler,title) {
checkTiddler(tiddler);
});
}
return registeredTitles;
};
/*
Unregister the plugin tiddlers of a particular type, returning an array of the titles affected
*/
$tw.Wiki.prototype.unregisterPluginTiddlers = function(pluginType) {
var self = this,
titles = [];
// Remove any previous registered plugins of this type
for(var t=this.plugins.length-1; t>=0; t--) {
var tiddler = this.plugins[t];
if(tiddler.fields["plugin-type"] === pluginType) {
titles.push(tiddler.fields.title);
this.plugins.splice(t,1);
}
}
return titles;
};
/*
Unpack the currently registered plugins, creating shadow tiddlers for their constituent tiddlers
*/
$tw.Wiki.prototype.unpackPluginTiddlers = function() {
var self = this;
// Sort the plugin titles by the `plugin-priority` field
this.plugins.sort(function(a,b) {
if("plugin-priority" in a.fields && "plugin-priority" in b.fields) {
return a.fields["plugin-priority"] - b.fields["plugin-priority"];
} else if("plugin-priority" in a.fields) {
return -1;
} else if("plugin-priority" in b.fields) {
return +1;
} else if(a.fields.title < b.fields.title) {
return -1;
} else if(a.fields.title === b.fields.title) {
return 0;
} else {
return +1;
}
});
// Now go through the plugins in ascending order and assign the shadows
this.shadowTiddlers = {};
$tw.utils.each(this.plugins,function(tiddler) {
// Get the plugin information
var pluginInfo = JSON.parse(tiddler.fields.text);
// Extract the constituent tiddlers
$tw.utils.each(pluginInfo.tiddlers,function(constituentTiddler,constituentTitle) {
// Save the tiddler object
if(constituentTitle) {
self.shadowTiddlers[constituentTitle] = {
source: tiddler.fields.title,
tiddler: new $tw.Tiddler(constituentTiddler,{title: constituentTitle})
};
}
});
});
};
/*
Define all modules stored in ordinary tiddlers
*/
$tw.Wiki.prototype.defineTiddlerModules = function() {
this.each(function(tiddler,title) {
$tw.utils.each(this.tiddlers,function(tiddler,title,object) {
if(tiddler.hasField("module-type")) {
switch (tiddler.fields.type) {
case "application/javascript":
@@ -1035,63 +918,40 @@ Register all the module tiddlers that have a module type
*/
$tw.Wiki.prototype.defineShadowModules = function() {
var self = this;
this.eachShadow(function(tiddler,title) {
// Don't define the module if it is overidden by an ordinary tiddler
if(!self.tiddlerExists(title) && tiddler.hasField("module-type")) {
// Define the module
$tw.modules.define(tiddler.fields.title,tiddler.fields["module-type"],tiddler.fields.text);
$tw.utils.each(this.shadowTiddlers,function(element,title) {
var tiddler = self.getTiddler(title);
if(!$tw.utils.hop(self.tiddlers,title)) { // Don't define the module if it is overidden by an ordinary tiddler
if(tiddler.hasField("module-type")) {
// Define the module
$tw.modules.define(tiddler.fields.title,tiddler.fields["module-type"],tiddler.fields.text);
}
}
});
};
/*
Enable safe mode by deleting any tiddlers that override a shadow tiddler
*/
$tw.Wiki.prototype.processSafeMode = function() {
var self = this,
overrides = [];
// Find the overriding tiddlers
this.each(function(tiddler,title) {
if(self.isShadowTiddler(title)) {
console.log(title);
overrides.push(title);
}
});
// Assemble a report tiddler
var titleReportTiddler = "TiddlyWiki Safe Mode",
report = [];
report.push("TiddlyWiki has been started in [[safe mode|http://tiddlywiki.com/static/SafeMode.html]]. Most customisations have been disabled by renaming the following tiddlers:")
// Delete the overrides
overrides.forEach(function(title) {
var tiddler = self.getTiddler(title),
newTitle = "SAFE: " + title;
self.deleteTiddler(title);
self.addTiddler(new $tw.Tiddler(tiddler, {title: newTitle}));
report.push("* [[" + title + "|" + newTitle + "]]");
});
report.push()
this.addTiddler(new $tw.Tiddler({title: titleReportTiddler, text: report.join("\n\n")}));
// Set $:/DefaultTiddlers to point to our report
this.addTiddler(new $tw.Tiddler({title: "$:/DefaultTiddlers", text: "[[" + titleReportTiddler + "]]"}));
$tw.Wiki.prototype.getTiddler = function(title) {
var t = this.tiddlers[title];
if(t instanceof $tw.Tiddler) {
return t;
} else if(title !== undefined && $tw.utils.hop(this.shadowTiddlers,title)) {
return this.shadowTiddlers[title].tiddler;
} else {
return undefined;
}
};
/*
Extracts tiddlers from a typed block of text, specifying default field values
*/
$tw.Wiki.prototype.deserializeTiddlers = function(type,text,srcFields) {
srcFields = srcFields || Object.create(null);
srcFields = srcFields || {};
var deserializer = $tw.Wiki.tiddlerDeserializerModules[type],
fields = Object.create(null);
fields = {};
if(!deserializer && $tw.config.fileExtensionInfo[type]) {
// If we didn't find the serializer, try converting it from an extension to a content type
type = $tw.config.fileExtensionInfo[type].type;
deserializer = $tw.Wiki.tiddlerDeserializerModules[type];
}
if(!deserializer && $tw.config.contentTypeInfo[type]) {
// see if this type has a different deserializer registered with it
type = $tw.config.contentTypeInfo[type].deserializerType;
deserializer = $tw.Wiki.tiddlerDeserializerModules[type];
}
if(!deserializer) {
// If we still don't have a deserializer, treat it as plain text
deserializer = $tw.Wiki.tiddlerDeserializerModules["text/plain"];
@@ -1149,7 +1009,7 @@ $tw.modules.define("$:/boot/tiddlerdeserializer/tids","tiddlerdeserializer",{
if(line.charAt(0) !== "#") {
var colonPos= line.indexOf(": ");
if(colonPos !== -1) {
var tiddler = $tw.utils.extend(Object.create(null),fields);
var tiddler = $tw.utils.extend({},fields);
tiddler.title = (tiddler.title || "") + line.substr(0,colonPos);
if(titles.indexOf(tiddler.title) !== -1) {
console.log("Warning: .multids file contains multiple definitions for " + tiddler.title);
@@ -1368,7 +1228,7 @@ $tw.loadTiddlersFromPath = function(filepath,excludeRegExp) {
// Look for a tiddlywiki.files file
if(files.indexOf("tiddlywiki.files") !== -1) {
// If so, process the files it describes
var filesInfo = JSON.parse(fs.readFileSync(filepath + path.sep + "tiddlywiki.files","utf8"));
var filesInfo = JSON.parse(fs.readFileSync(filepath + "/tiddlywiki.files","utf8"));
$tw.utils.each(filesInfo.tiddlers,function(tidInfo) {
var typeInfo = $tw.config.contentTypeInfo[tidInfo.fields.type || "text/plain"],
pathname = path.resolve(filepath,tidInfo.file),
@@ -1386,7 +1246,7 @@ $tw.loadTiddlersFromPath = function(filepath,excludeRegExp) {
// If not, read all the files in the directory
$tw.utils.each(files,function(file) {
if(!excludeRegExp.test(file)) {
tiddlers.push.apply(tiddlers,$tw.loadTiddlersFromPath(filepath + path.sep + file,excludeRegExp));
tiddlers.push.apply(tiddlers,$tw.loadTiddlersFromPath(filepath + "/" + file,excludeRegExp));
}
});
}
@@ -1407,20 +1267,20 @@ $tw.loadPluginFolder = function(filepath,excludeRegExp) {
stat = fs.statSync(filepath);
if(stat.isDirectory()) {
// Read the plugin information
pluginInfo = JSON.parse(fs.readFileSync(filepath + path.sep + "plugin.info","utf8"));
pluginInfo = JSON.parse(fs.readFileSync(filepath + "/plugin.info","utf8"));
// Read the plugin files
files = fs.readdirSync(filepath);
for(f=0; f<files.length; f++) {
file = files[f];
if(!excludeRegExp.test(file) && file !== "plugin.info" && file !== "tiddlywiki.files") {
var tiddlerFiles = $tw.loadTiddlersFromPath(filepath + path.sep + file,excludeRegExp);
var tiddlerFiles = $tw.loadTiddlersFromPath(filepath + "/" + file,excludeRegExp);
$tw.utils.each(tiddlerFiles,function(tiddlerFile) {
pluginTiddlers.push.apply(pluginTiddlers,tiddlerFile.tiddlers);
});
}
}
// Save the plugin tiddlers into the plugin info
pluginInfo.tiddlers = pluginInfo.tiddlers || Object.create(null);
pluginInfo.tiddlers = pluginInfo.tiddlers || {};
for(t=0; t<pluginTiddlers.length; t++) {
if(pluginTiddlers[t].title) {
pluginInfo.tiddlers[pluginTiddlers[t].title] = pluginTiddlers[t];
@@ -1594,12 +1454,10 @@ readBrowserTiddlers: whether to read tiddlers from the HTML file we're executing
*/
$tw.boot.startup = function(options) {
options = options || {};
// Check for safe mode
$tw.safeMode = $tw.browser && location.hash === "#:safe";
// Initialise some more $tw properties
$tw.utils.deepDefaults($tw,{
modules: { // Information about each module
titles: Object.create(null), // hashmap by module title of {fn:, exports:, moduleType:}
titles: {}, // hashmap by module title of {fn:, exports:, moduleType:}
types: {} // hashmap by module type of hashmap of exports
},
config: { // Configuration overridables
@@ -1613,20 +1471,16 @@ $tw.boot.startup = function(options) {
wikiLanguagesSubDir: "./languages",
wikiTiddlersSubDir: "./tiddlers",
jsModuleHeaderRegExpString: "^\\/\\*\\\\(?:\\r?\\n)((?:^[^\\r\\n]*(?:\\r?\\n))+?)(^\\\\\\*\\/$(?:\\r?\\n)?)",
fileExtensionInfo: Object.create(null), // Map file extension to {type:}
contentTypeInfo: Object.create(null) // Map type to {encoding:,extension:}
fileExtensionInfo: {}, // Map file extension to {type:}
contentTypeInfo: {} // Map type to {encoding:,extension:}
}
});
if(!options.readBrowserTiddlers) {
// For writable tiddler files, a hashmap of title to {filepath:,type:,hasMetaFile:}
$tw.boot.files = Object.create(null);
$tw.boot.files = {};
// System paths and filenames
$tw.boot.bootPath = path.dirname(module.filename);
$tw.boot.corePath = path.resolve($tw.boot.bootPath,"../core");
// If there's no arguments then default to `--help`
if($tw.boot.argv.length === 0) {
$tw.boot.argv = ["--help"];
}
// If the first command line argument doesn't start with `--` then we
// interpret it as the path to the wiki folder, which will otherwise default
// to the current folder
@@ -1652,22 +1506,21 @@ $tw.boot.startup = function(options) {
$tw.utils.registerFileType("text/plain","utf8",".txt");
$tw.utils.registerFileType("text/css","utf8",".css");
$tw.utils.registerFileType("text/html","utf8",".html");
$tw.utils.registerFileType("application/hta","utf16le",".hta",{deserializerType:"text/html"});
$tw.utils.registerFileType("application/javascript","utf8",".js");
$tw.utils.registerFileType("application/json","utf8",".json");
$tw.utils.registerFileType("application/pdf","base64",".pdf",{flags:["image"]});
$tw.utils.registerFileType("image/jpeg","base64",".jpg",{flags:["image"]});
$tw.utils.registerFileType("image/png","base64",".png",{flags:["image"]});
$tw.utils.registerFileType("image/gif","base64",".gif",{flags:["image"]});
$tw.utils.registerFileType("image/svg+xml","utf8",".svg",{flags:["image"]});
$tw.utils.registerFileType("image/x-icon","base64",".ico",{flags:["image"]});
$tw.utils.registerFileType("application/pdf","base64",".pdf",["image"]);
$tw.utils.registerFileType("image/jpeg","base64",".jpg",["image"]);
$tw.utils.registerFileType("image/png","base64",".png",["image"]);
$tw.utils.registerFileType("image/gif","base64",".gif",["image"]);
$tw.utils.registerFileType("image/svg+xml","utf8",".svg",["image"]);
$tw.utils.registerFileType("image/x-icon","base64",".ico",["image"]);
$tw.utils.registerFileType("application/font-woff","base64",".woff");
// Create the wiki store for the app
$tw.wiki = new $tw.Wiki();
// Install built in tiddler fields modules
$tw.Tiddler.fieldModules = $tw.modules.getModulesByTypeAsHashmap("tiddlerfield");
// Install the tiddler deserializer modules
$tw.Wiki.tiddlerDeserializerModules = Object.create(null);
$tw.Wiki.tiddlerDeserializerModules = {};
$tw.modules.applyMethods("tiddlerdeserializer",$tw.Wiki.tiddlerDeserializerModules);
// Load tiddlers
if(options.readBrowserTiddlers) {
@@ -1676,13 +1529,8 @@ $tw.boot.startup = function(options) {
$tw.loadTiddlersNode();
}
// Unpack plugin tiddlers
$tw.wiki.readPluginInfo();
$tw.wiki.registerPluginTiddlers("plugin");
$tw.wiki.unpackPluginTiddlers();
// Process "safe mode"
if($tw.safeMode) {
$tw.wiki.processSafeMode();
}
// Register typed modules from the tiddlers we've just loaded
$tw.wiki.defineTiddlerModules();
// And any modules within plugins

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,3 @@
title: $:/core/images/cancel-button
tags: $:/tags/Image
<svg class="tw-image-cancel-button tw-image-button" viewBox="366 150 58 58" width="22pt" height="22pt"><path d="M 414.76236 158.98764 C 403.77887 148.0041 385.97113 148.0041 374.98764 158.98764 C 364.0041 169.97113 364.0041 187.77887 374.98764 198.76236 C 385.97113 209.7459 403.77887 209.7459 414.76236 198.76236 C 425.7459 187.77887 425.7459 169.97113 414.76236 158.98764 M 385.3967 165.32954 L 385.3967 165.32954 L 394.77674 174.7096 L 404.3533 165.13303 C 405.53068 163.95566 407.4396 163.95566 408.61697 165.13303 C 409.79434 166.31041 409.79434 168.21932 408.61697 169.39669 L 399.0404 178.97325 L 408.42046 188.35331 C 409.59783 189.53068 409.59783 191.43959 408.42046 192.61697 L 408.42046 192.61697 C 407.24308 193.79434 405.33417 193.79434 404.1568 192.61697 L 394.77675 183.23692 L 385.5932 192.42046 C 384.41583 193.59783 382.50692 193.59783 381.32954 192.42046 L 381.32954 192.42046 C 380.15217 191.24308 380.15217 189.33417 381.32954 188.1568 C 381.32954 188.1568 381.32954 188.1568 381.32954 188.1568 L 381.32954 188.1568 L 381.32954 188.1568 L 390.51309 178.97326 L 381.13303 169.5932 C 379.95566 168.41583 379.95566 166.50692 381.13303 165.32954 L 381.13303 165.32954 C 382.3104 164.15217 384.21932 164.15217 385.3967 165.32954 C 385.3967 165.32954 385.3967 165.32954 385.3967 165.32954 Z"/></svg>

View File

@@ -1,4 +1,3 @@
title: $:/core/images/close-button
tags: $:/tags/Image
<svg class="tw-image-close-button tw-image-button" viewBox="222 150 56 56" width="22pt" height="22pt"><path d="M 249.56668 185.88827 L 267.06757 203.38916 C 269.26427 205.58586 272.82582 205.58586 275.02252 203.38916 L 275.02252 203.38916 C 277.21922 201.19246 277.21922 197.63091 275.02252 195.43421 L 257.52163 177.93332 L 275.38916 160.06579 C 277.58586 157.86909 277.58586 154.30754 275.38916 152.11084 C 273.19246 149.91414 269.63091 149.91414 267.43421 152.11084 L 249.56668 169.97837 L 232.06579 152.47748 L 232.06579 152.47748 C 232.06579 152.47748 232.06579 152.47748 232.06579 152.47748 C 229.86909 150.28078 226.30754 150.28078 224.11084 152.47748 L 224.11084 152.47748 C 221.91414 154.674175 221.91414 158.23573 224.11084 160.43243 L 241.61173 177.93332 L 224.47748 195.06757 L 224.47748 195.06757 L 224.47748 195.06757 C 224.47748 195.06757 224.47748 195.06757 224.47748 195.06757 C 222.28078 197.26427 222.28078 200.82583 224.47748 203.02252 L 224.47748 203.02252 C 226.67418 205.21922 230.23573 205.21922 232.43243 203.02252 Z"/></svg>

View File

@@ -1,4 +1,3 @@
title: $:/core/images/delete-button
tags: $:/tags/Image
<svg class="tw-image-delete-button tw-image-button" viewBox="303 155 39 50" width="17pt" height="22pt"><path d="M 333 164.25 L 333 157.25 C 333 156.14543 332.10457 155.25 331 155.25 L 314.75 155.25 C 314.75 155.25 314.75 155.25 314.75 155.25 C 313.64543 155.25 312.75 156.14543 312.75 157.25 L 312.75 164.25 L 303.75 164.25 L 303.75 168.75 L 306 168.75 L 306 201.75 L 306 201.75 L 306 201.75 C 306 203.40685 307.34315 204.75 309 204.75 L 336.75 204.75 C 338.40685 204.75 339.75 203.40685 339.75 201.75 L 339.75 168.75 L 342 168.75 L 342 164.25 Z M 317.25 160.75 L 317.25 160.75 C 317.25 160.19772 317.69772 159.75 318.25 159.75 C 318.25 159.75 318.25 159.75 318.25 159.75 L 327.5 159.75 C 328.05228 159.75 328.5 160.19772 328.5 160.75 L 328.5 164.25 L 317.25 164.25 L 317.25 160.75 Z M 310.5 168.75 L 312.75 168.75 L 312.75 200.25 L 310.5 200.25 Z M 317.25 168.75 L 319.5 168.75 L 319.5 200.25 L 317.25 200.25 Z M 324 168.75 L 326.25 168.75 L 326.25 200.25 L 324 200.25 Z M 330.75 168.75 L 333 168.75 L 333 200.25 L 330.75 200.25 Z"/></svg>

View File

@@ -1,4 +1,3 @@
title: $:/core/images/done-button
tags: $:/tags/Image
<svg class="tw-image-done-button tw-image-button" viewBox="434 150 68 55" width="22pt" height="18pt"><path d="M 438.49266 178.00797 L 439.00744 177.49319 C 441.35054 175.15008 445.14946 175.15004 447.49262 177.49309 L 452.50734 182.50757 C 454.8505 184.85063 458.6494 184.85058 460.99252 182.50748 L 488.50747 154.99255 C 490.85058 152.64944 494.6495 152.6494 496.99266 154.99246 L 497.50722 155.506995 C 499.8504 157.85009 499.8505 161.64908 497.5074 163.99228 C 497.50738 163.99229 497.50736 163.99231 497.50734 163.99233 L 460.9926 200.5077 C 458.64947 202.85087 454.85048 202.8509 452.50732 200.50778 C 452.5073 200.50777 452.5073 200.50777 452.5073 200.50776 L 438.49268 186.49327 C 436.14952 184.15013 436.1495 180.35114 438.49264 178.00799 C 438.49265 178.00798 438.49265 178.00797 438.49266 178.00797 Z"/></svg>

View File

@@ -1,4 +1,3 @@
title: $:/core/images/down-arrow
tags: $:/tags/Image
<svg class="tw-image-down-arrow tw-image-button" viewBox="63 152 64 64" width="22pt" height="22pt"><path d="M 98.001786 212.81802 L 123.45763 187.36218 C 125.21499 185.60482 125.21499 182.75557 123.45763 180.99821 C 121.70027 179.24086 118.85103 179.24086 117.09367 180.99821 L 94.819805 203.27208 L 72.54594 180.99821 C 70.788582 179.24086 67.93934 179.24086 66.18198 180.99821 C 64.42462 182.75557 64.42462 185.60482 66.18198 187.36218 L 91.637825 212.81802 C 93.395184 214.57538 96.244426 214.57538 98.001786 212.81802 Z"/></svg>
<svg class="tw-image-down-arrow tw-image-button" viewBox="441 306 59 45" width="24pt" height="22pt"><path d="M 441 306 L 470.25 351 L 499.5 306 Z"/></svg>

View File

@@ -1,4 +1,3 @@
title: $:/core/images/edit-button
tags: $:/tags/Image
<svg class="tw-image-edit-button tw-image-button" viewBox="244 193 20 22" width="20pt" height="22pt"><path d="M 257.33334 196.80951 L 245.90476 207.2857 L 244 212.0476 L 248.7619 210.14284 L 260.19048 199.66665 Z M 259.2381 194.90475 L 258.28566 195.85716 L 261.14284 198.71428 L 262.09522 197.76187 Z M 261.14286 193 L 260.19042 193.95241 L 263.04762 196.80953 L 264 195.85714 Z M 244 213.72882 C 244 213.72882 247.4281 215.43353 250.8572 213.7288 C 254.28599 212.02405 261.14284 214.86531 261.14284 214.86531 L 261.14284 213.72884 C 261.14284 213.72884 254.28577 210.88755 250.8572 212.5923 C 247.42858 214.29712 244 212.59228 244 212.59228 Z"/></svg>

View File

@@ -1,4 +0,0 @@
title: $:/core/images/home-button
tags: $:/tags/Image
<svg class="tw-image-home-button tw-image-button" viewBox="81 513 64 54" width="22pt" height="22pt"><g><path d="M 97.04536 522.62083 L 81.364685 531.49067 L 87.85863 531.49067 L 87.85863 566.9699 L 107.49902 566.9699 L 107.49902 552.99265 L 117.95268 552.99265 L 117.95268 566.9699 L 137.59307 566.9699 L 137.59307 531.49067 L 144.086885 531.49067 L 112.72591 513.751 L 107.49902 516.70758 L 107.49902 513.751 L 97.04536 513.751 Z M 94.669443 534.17844 L 103.222493 534.17844 L 103.222493 545.19854 L 94.669443 545.19854 Z M 108.449266 534.17844 L 117.002435 534.17844 L 117.002435 545.19854 L 108.449266 545.19854 Z M 122.387575 534.17844 L 130.9405 534.17844 L 130.9405 545.19854 L 122.387575 545.19854 Z"/></g></svg>

View File

@@ -1,4 +1,3 @@
title: $:/core/images/info-button
tags: $:/tags/Image
<svg class="tw-image-info-button tw-image-button" viewBox="294 150 58 58" width="22pt" height="22pt"><path d="M 342.76236 158.98764 C 331.77887 148.0041 313.97113 148.0041 302.98764 158.98764 C 292.0041 169.97113 292.0041 187.77887 302.98764 198.76236 C 313.97113 209.7459 331.77887 209.7459 342.76236 198.76236 C 353.7459 187.77887 353.7459 169.97113 342.76236 158.98764 M 326.5425 157.5 L 326.5425 157.5 C 327.72545 157.5 328.72201 157.91022 329.5337 158.73088 C 330.34465 159.55157 330.75 160.54402 330.75 161.7075 C 330.75 162.87172 330.33979 163.86316 329.51911 164.68385 C 328.69842 165.5045 327.70674 165.91501 326.5425 165.91501 C 325.39801 165.91501 324.4153 165.5045 323.5946 164.68385 C 322.77393 163.86316 322.36372 162.87172 322.36372 161.7075 C 322.36372 160.54402 322.76906 159.55157 323.58 158.73088 C 324.39171 157.91022 325.3793 157.5 326.5425 157.5 Z M 327.80211 190.47259 C 324.91945 195.49132 321.85778 198 318.61462 198 C 317.37452 198 316.38691 197.65158 315.65186 196.9555 C 314.9176 196.25866 314.54943 195.37617 314.54943 194.30782 C 314.54943 193.60202 314.71223 192.70572 315.03629 191.61813 L 319.0151 177.93651 C 319.39685 176.61922 319.58735 175.62754 319.58735 174.95991 C 319.58735 174.53996 319.40582 174.16692 319.04356 173.84286 C 318.68052 173.51905 318.18469 173.35701 317.55527 173.35701 C 317.26861 173.35701 316.92506 173.36677 316.5246 173.38548 L 316.89661 172.2407 L 326.59967 170.66627 L 328.31744 170.66627 L 322.44986 191.01638 C 322.12503 192.18064 321.963 192.94337 321.963 193.30666 C 321.963 193.51588 322.04862 193.71121 322.2204 193.89273 C 322.39218 194.07425 322.5737 194.16554 322.7642 194.16477 C 323.08903 194.16554 323.4131 194.02221 323.73792 193.73559 C 324.59605 193.02976 325.6267 191.75142 326.82838 189.90008 Z"/></svg>

View File

@@ -1,4 +0,0 @@
title: $:/core/images/menu-button
tags: $:/tags/Image
<svg class="tw-image-menu-button tw-image-button" viewBox="216 585 63 45" width="22pt" height="22pt"><g><path d="M 274.5 585 L 229.5 585 C 227.01472 585 225 587.01472 225 589.5 L 225 589.5 C 225 591.98528 227.01472 594 229.5 594 L 274.5 594 C 276.98528 594 279 591.98528 279 589.5 L 279 589.5 C 279 587.01472 276.98528 585 274.5 585 Z"/><path d="M 274.5 603 L 229.5 603 C 227.01472 603 225 605.01472 225 607.5 L 225 607.5 C 225 609.98528 227.01472 612 229.5 612 L 274.5 612 C 276.98528 612 279 609.98528 279 607.5 L 279 607.5 C 279 605.01472 276.98528 603 274.5 603 Z"/><path d="M 274.5 621 L 229.5 621 C 227.01472 621 225 623.01472 225 625.5 L 225 625.5 C 225 627.9853 227.01472 630 229.5 630 L 274.5 630 C 276.98528 630 279 627.9853 279 625.5 L 279 625.5 C 279 623.01472 276.98528 621 274.5 621 Z"/></g></svg>

View File

@@ -1,4 +1,3 @@
title: $:/core/images/new-button
tags: $:/tags/Image
<svg class="tw-image-new-button tw-image-button" viewBox="83 81 50 50" width="22pt" height="22pt"><path d="M 101.25 112.5 L 101.25 127.5 C 101.25 127.5 101.25 127.5 101.25 127.5 L 101.25 127.5 C 101.25 129.156855 102.593146 130.5 104.25 130.5 L 111.75 130.5 C 113.406854 130.5 114.75 129.156854 114.75 127.5 L 114.75 112.5 L 129.75 112.5 C 131.406854 112.5 132.75 111.156854 132.75 109.5 L 132.75 102 C 132.75 100.343146 131.406854 99 129.75 99 L 114.75 99 L 114.75 84 C 114.75 82.343146 113.406854 81 111.75 81 L 104.25 81 C 104.25 81 104.25 81 104.25 81 C 102.593146 81 101.25 82.343146 101.25 84 L 101.25 99 L 86.25 99 C 86.25 99 86.25 99 86.25 99 C 84.593146 99 83.25 100.343146 83.25 102 L 83.25 109.5 C 83.25 109.5 83.25 109.5 83.25 109.5 L 83.25 109.5 C 83.25 111.156855 84.593146 112.5 86.25 112.5 Z"/></svg>

View File

@@ -1,4 +1,3 @@
title: $:/core/images/options-button
tags: $:/tags/Image
<svg class="tw-image-options-button tw-image-button" viewBox="434 218 68 68" width="22pt" height="22pt"><path d="M 478.39696 232.53705 L 478.39696 232.53705 C 477.11453 231.85132 475.77877 231.30146 474.4106 230.88735 L 474.4106 218.24993 L 461.58944 218.24993 L 461.58944 230.88735 C 460.22126 231.30146 458.8855 231.85132 457.60308 232.53705 L 448.66825 223.60214 L 439.6022 232.66814 L 448.53716 241.60304 C 447.8515 242.88541 447.30158 244.22116 446.88747 245.58935 L 434.25 245.58935 L 434.25 258.41052 L 446.88747 258.41052 C 447.30158 259.7787 447.8515 261.11446 448.53716 262.39689 L 439.6022 271.33173 L 448.66825 280.39779 L 457.60308 271.46281 C 458.8855 272.14862 460.22126 272.69847 461.58944 273.11251 L 461.58944 285.74986 L 474.4106 285.74986 L 474.4106 273.11251 C 475.77877 272.69847 477.11453 272.14862 478.39696 271.46281 L 487.3318 280.39779 L 496.3977 271.33173 L 487.46287 262.39689 C 488.14854 261.11446 488.6984 259.7787 489.11257 258.41052 L 501.7499 258.41052 L 501.7499 245.58935 L 489.11257 245.58935 C 488.6984 244.22116 488.14854 242.88541 487.46287 241.60304 L 496.3977 232.66814 L 487.3318 223.60214 Z M 475.3328 244.66714 C 479.38253 248.71698 479.38253 255.2829 475.3328 259.33273 C 471.28297 263.3826 464.71706 263.3826 460.66723 259.33273 C 456.61737 255.2829 456.61737 248.71698 460.66723 244.66714 C 464.71706 240.61734 471.28297 240.61734 475.3328 244.66714"/></svg>

View File

@@ -1,4 +1,3 @@
title: $:/core/images/save-button
tags: $:/tags/Image
<svg class="tw-image-save-button tw-image-button" viewBox="4 512 64 60" width="22pt" height="21pt"><path d="M 13.5 537.75 L 11.5 537.75 C 11.5 537.75 11.5 537.75 11.5 537.75 C 7.6340064 537.75 4.4999994 540.884 4.5 544.75 L 4.5 564.5 L 4.5 564.5 C 4.5 564.5 4.5 564.5 4.5 564.5 L 4.5 564.5 C 4.5000006 568.366 7.634007 571.5 11.5 571.5 L 60.5 571.5 C 64.365993 571.5 67.5 568.366 67.5 564.5 L 67.5 544.75 C 67.5 540.884 64.365993 537.75 60.5 537.75 L 58.5 537.75 L 49.5 546.75 L 50 546.75 C 52.20914 546.75 54 548.54086 54 550.75 L 54 556.25 C 54 558.45914 52.20914 560.25 50 560.25 L 36 560.25 L 22 560.25 C 19.790861 560.25 18 558.45914 18 556.25 L 18 556.25 C 18 556.25 18 556.25 18 556.25 L 18 550.75 C 18 548.54086 19.790861 546.75 22 546.75 C 22 546.75 22 546.75 22 546.75 L 22.5 546.75 Z"/><path d="M 16.37132 533.87132 L 33.87868 551.37868 C 35.050253 552.55025 36.949747 552.55025 38.12132 551.37868 L 55.62868 533.87132 C 56.800252 532.69975 56.800252 530.80025 55.62868 529.62868 C 55.06607 529.06607 54.30301 528.75 53.50736 528.75 L 48 528.75 C 46.343146 528.75 45 527.40685 45 525.75 L 45 516 C 45 514.34315 43.656854 513 42 513 L 30 513 C 28.343146 513 27 514.34315 27 516 L 27 525.75 C 27 527.40685 25.656854 528.75 24 528.75 L 18.492641 528.75 C 16.835786 528.75 15.492641 530.09315 15.492641 531.75 C 15.492641 532.54565 15.808711 533.3087 16.37132 533.87132 Z"/></svg>

View File

@@ -14,9 +14,9 @@ Appearance/Palette/Editor/Clone/Prompt: It is recommended that you clone this sh
Appearance/Palette/Editor/Prompt/Modified: This shadow palette has been modified
Appearance/Palette/Editor/Prompt: Editing
Appearance/Palette/Editor/Reset/Caption: reset
Appearance/Palette/ShowEditor/Caption: show editor
Appearance/Palette/HideEditor/Caption: hide editor
Appearance/Palette/Prompt: Current palette:
Appearance/Palette/ShowEditor/Caption: show editor
Appearance/StoryView/Caption: Story View
Appearance/StoryView/Prompt: Current view:
Appearance/Theme/Caption: Theme
@@ -40,9 +40,6 @@ Plugins/Caption: Plugins
Plugins/Fields/Description: Description
Plugins/Fields/Title: Title
Plugins/Fields/Version: Version
Plugins/Language/Prompt: Languages
Plugins/Plugin/Prompt: Plugins
Plugins/Theme/Prompt: Themes
Saving/AutoSave/Disabled/Button: enable
Saving/AutoSave/Disabled/Prompt: Autosave is currently disabled
Saving/AutoSave/Enabled/Button: disable

View File

@@ -1,100 +0,0 @@
title: $:/language/Docs/PaletteColours/
alert-background: Alert background
alert-border: Alert border
alert-highlight: Alert highlight
alert-muted-foreground: Alert muted foreground
background: General background
blockquote-bar: Blockquote bar
code-background: Code background
code-border: Code border
code-foreground: Code foreground
download-background: Download button background
download-foreground: Download button foreground
dragger-background: Dragger background
dragger-foreground: Dragger foreground
dropdown-background: Dropdown background
dropdown-border: Dropdown border
dropdown-tab-background-selected: Dropdown tab background for selected tabs
dropdown-tab-background: Dropdown tab background
dropzone-background: Dropzone background
external-link-background-hover: External link background hover
external-link-background-visited: External link background visited
external-link-background: External link background
external-link-foreground-hover: External link foreground hover
external-link-foreground-visited: External link foreground visited
external-link-foreground: External link foreground
foreground: General foreground
message-background: Message box background
message-border: Message box border
message-foreground: Message box foreground
modal-backdrop: Modal backdrop
modal-background: Modal background
modal-border: Modal border
modal-footer-background: Modal footer background
modal-footer-border: Modal footer border
modal-header-border: Modal header border
muted-foreground: General muted foreground
notification-background: Notification background
notification-border: Notification border
page-background: Page background
pre-background: Preformatted code background
pre-border: Preformatted code border
primary: General primary
sidebar-button-foreground: Sidebar button foreground
sidebar-controls-foreground-hover: Sidebar controls foreground hover
sidebar-controls-foreground: Sidebar controls foreground
sidebar-foreground-shadow: Sidebar foreground shadow
sidebar-foreground: Sidebar foreground
sidebar-muted-foreground-hover: Sidebar muted foreground hover
sidebar-muted-foreground: Sidebar muted foreground
sidebar-tab-background-selected: Sidebar tab background for selected tabs
sidebar-tab-background: Sidebar tab background
sidebar-tab-border-selected: Sidebar tab border for selected tabs
sidebar-tab-border: Sidebar tab border
sidebar-tab-divider: Sidebar tab divider
sidebar-tab-foreground-selected: Sidebar tab foreground for selected tabs
sidebar-tab-foreground: Sidebar tab foreground
sidebar-tiddler-link-foreground-hover: Sidebar tiddler link foreground hover
sidebar-tiddler-link-foreground: Sidebar tiddler link foreground
static-alert-foreground: Static alert foreground
tab-background-selected: Tab background for selected tabs
tab-background: Tab background
tab-border-selected: Tab border for selected tabs
tab-border: Tab border
tab-divider: Tab divider
tab-foreground-selected: Tab foreground for selected tabs
tab-foreground: Tab foreground
table-border: Table border
table-footer-background: Table footer background
table-header-background: Table header background
tag-background: Tag background
tag-foreground: Tag foreground
tiddler-background: Tiddler background
tiddler-border: Tiddler border
tiddler-controls-foreground-hover: Tiddler controls foreground hover
tiddler-controls-foreground-selected: Tiddler controls foreground for selected controls
tiddler-controls-foreground: Tiddler controls foreground
tiddler-editor-background: Tiddler editor background
tiddler-editor-border-image: Tiddler editor border image
tiddler-editor-border: Tiddler editor border
tiddler-editor-fields-even: Tiddler editor background for even fields
tiddler-editor-fields-odd: Tiddler editor background for odd fields
tiddler-info-background: Tiddler info panel background
tiddler-info-border: Tiddler info panel border
tiddler-info-tab-background: Tiddler info panel tab background
tiddler-link-background: Tiddler link background
tiddler-link-foreground: Tiddler link foreground
tiddler-subtitle-foreground: Tiddler subtitle foreground
tiddler-title-foreground: Tiddler title foreground
toolbar-new-button: Toolbar 'new tiddler' button foreground
toolbar-options-button: Toolbar 'options' button foreground
toolbar-save-button: Toolbar 'save' button foreground
toolbar-info-button: Toolbar 'info' button foreground
toolbar-edit-button: Toolbar 'edit' button foreground
toolbar-close-button: Toolbar 'close' button foreground
toolbar-delete-button: Toolbar 'delete' button foreground
toolbar-cancel-button: Toolbar 'cancel' button foreground
toolbar-done-button: Toolbar 'done' button foreground
untagged-background: Untagged pill background
very-muted-foreground: Very muted foreground

View File

@@ -1,6 +1,6 @@
title: $:/language/EditTemplate/
Body/Hint: Use [[wiki text|http://tiddlywiki.com/static/WikiText.html]] to add formatting, images, and dynamic features
Body/Hint: Use WikiText to add formatting, images, and dynamic features
Body/Placeholder: Type the text for this tiddler
Body/Preview/Button/Hide: hide preview
Body/Preview/Button/Show: show preview

View File

@@ -16,8 +16,6 @@ hack-to-give-us-something-to-compare-against: A temporary storage field used in
icon: The title of the tiddler containing the icon associated with a tiddler
library: If set to "yes" indicates that a tiddler should be saved as a JavaScript library
list: An ordered list of tiddler titles associated with a tiddler
list-before: If set, the title of a tiddler before which this tiddler should be added to the ordered list of tiddler titles, or at the start of the list if this field is present but empty
list-after: If set, the title of the tiddler after which this tiddler should be added to the ordered list of tiddler titles
modified: The date and time at which a tiddler was last modified
modifier: The tiddler title associated with the person who last modified a tiddler
name: The human readable name associated with a plugin tiddler
@@ -31,4 +29,4 @@ tags: A list of tags associated with a tiddler
text: The body text of a tiddler
title: The unique name of a tiddler
type: The content type of a tiddler
version: Version information for a plugin
version: Version information for a plugin

View File

@@ -1,12 +0,0 @@
title: $:/language/Filters/
AllTiddlers: All tiddlers except system tiddlers
RecentTiddlers: Recently modified tiddlers
AllTags: All tags except system tags
Missing: Missing tiddlers
Drafts: Draft tiddlers
Orphans: Orphan tiddlers
SystemTiddlers: System tiddlers
ShadowTiddlers: Shadow tiddlers
OverriddenShadowTiddlers: Overridden shadow tiddlers
SystemTags: System tags

View File

@@ -12,5 +12,3 @@ To load tiddlers from an encrypted TiddlyWiki file you should first specify the
```
tiddlywiki ./MyWiki --password pa55w0rd --load my_encrypted_wiki.html
```
Note that TiddlyWiki will not load an older version of an already loaded plugin.

View File

@@ -1,30 +1,4 @@
title: $:/language/
ClassicWarning/Hint: This tiddler is written in TiddlyWiki Classic wiki text format, which is not fully compatible with TiddlyWiki version 5. See http://tiddlywiki.com/static/Upgrading.html for more details.
ClassicWarning/Upgrade/Caption: upgrade
CloseAll/Button: close all
ConfirmCancelTiddler: Do you wish to discard changes to the tiddler "<$text text=<<title>>/>"?
ConfirmDeleteTiddler: Do you wish to delete the tiddler "<$text text=<<title>>/>"?
ConfirmOverwriteTiddler: Do you wish to overwrite the tiddler "<$text text=<<title>>/>"?
InvalidFieldName: Illegal characters in field name "<$text text=<<fieldName>>/>". Fields can only contain lowercase letters and the characters underscore (`_`), hyphen (`-`) and period (`.`)
MissingTiddler/Hint: Missing tiddler "<$text text=<<currentTiddler>>/>" - click {{$:/core/images/edit-button}} to create
RecentChanges/DateFormat: DDth MMM YYYY
RelativeDate/Future/Days: <<period>> days from now
RelativeDate/Future/Hours: <<period>> hours from now
RelativeDate/Future/Minutes: <<period>> minutes from now
RelativeDate/Future/Months: <<period>> months from now
RelativeDate/Future/Second: 1 second from now
RelativeDate/Future/Seconds: <<period>> seconds from now
RelativeDate/Future/Years: <<period>> years from now
RelativeDate/Past/Days: <<period>> days ago
RelativeDate/Past/Hours: <<period>> hours ago
RelativeDate/Past/Minutes: <<period>> minutes ago
RelativeDate/Past/Months: <<period>> months ago
RelativeDate/Past/Second: 1 second ago
RelativeDate/Past/Seconds: <<period>> seconds ago
RelativeDate/Past/Years: <<period>> years ago
SystemTiddler/Tooltip: This is a system tiddler
TagManager/Colour/Heading: Colour
TagManager/Count/Heading: Count
TagManager/Icon/Heading: Icon
TagManager/Tag/Heading: Tag
CloseAll/Button: close all

View File

@@ -1,14 +1,5 @@
title: $:/language/TiddlerInfo/
Advanced/Caption: Advanced
Advanced/PluginInfo/Empty/Hint: none
Advanced/PluginInfo/Heading: Plugin Details
Advanced/PluginInfo/Hint: This plugin contains the following shadow tiddlers:
Advanced/ShadowInfo/Heading: Shadow Status
Advanced/ShadowInfo/NotShadow/Hint: The tiddler <$link to=<<infoTiddler>>><$text text=<<infoTiddler>>/></$link> is not a shadow tiddler
Advanced/ShadowInfo/Shadow/Hint: The tiddler <$link to=<<infoTiddler>>><$text text=<<infoTiddler>>/></$link> is a shadow tiddler
Advanced/ShadowInfo/Shadow/Source: It is defined in the plugin <$link to=<<pluginTiddler>>><$text text=<<pluginTiddler>>/></$link>
Advanced/ShadowInfo/OverriddenShadow/Hint: It is overridden by an ordinary tiddler
Fields/Caption: Fields
List/Caption: List
List/Empty: This tiddler does not have a list

View File

@@ -1,3 +0,0 @@
title: $:/language/Docs/Types/text/html
description: HTML markup
name: text/html

View File

@@ -34,7 +34,7 @@ Command.prototype.execute = function() {
for(var editionIndex=0; editionIndex<editions.length; editionIndex++) {
var editionName = editions[editionIndex];
// Check the edition exists
var editionPath = path.resolve($tw.boot.corePath,$tw.config.editionsPath) + path.sep + editionName;
var editionPath = path.resolve($tw.boot.corePath,$tw.config.editionsPath) + "/" + editionName;
if(!$tw.utils.isDirectory(editionPath)) {
return "Edition '" + editionName + "' not found";
}

View File

@@ -30,9 +30,8 @@ Command.prototype.execute = function() {
if(this.params.length < 1) {
return "Missing filename";
}
var ext = path.extname(self.params[0]);
fs.readFile(this.params[0],$tw.utils.getTypeEncoding(ext),function(err,data) {
if (err) {
fs.readFile(this.params[0],"utf8",function(err,data) {
if(err) {
self.callback(err);
} else {
var fields = {title: self.params[0]},
@@ -42,7 +41,7 @@ Command.prototype.execute = function() {
self.callback("No tiddlers found in file \"" + self.params[0] + "\"");
} else {
for(var t=0; t<tiddlers.length; t++) {
self.commander.wiki.importTiddler(new $tw.Tiddler(tiddlers[t]));
self.commander.wiki.addTiddler(new $tw.Tiddler(tiddlers[t]));
}
self.callback(null);
}

View File

@@ -95,9 +95,8 @@ SimpleServer.prototype.listen = function(port,host) {
if(username && password) {
// Check they match
if(self.checkCredentials(request,username,password) !== "ALLOWED") {
var servername = state.wiki.getTiddlerText("$:/SiteTitle") || "TiddlyWiki5";
response.writeHead(401,"Authentication required",{
"WWW-Authenticate": 'Basic realm="Please provide your username and password to login to ' + servername + '"'
"WWW-Authenticate": 'Basic realm="Please provide your username and password to login to TiddlyWiki5"'
});
response.end();
return;

View File

@@ -37,6 +37,4 @@ exports.htmlVoidElements = "area,base,br,col,command,embed,hr,img,input,keygen,l
exports.htmlBlockElements = "address,article,aside,audio,blockquote,canvas,dd,div,dl,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,hr,li,noscript,ol,output,p,pre,section,table,tfoot,ul,video".split(",");
exports.htmlUnsafeElements = "script".split(",");
})();

View File

@@ -3,7 +3,7 @@ title: $:/core/modules/filters.js
type: application/javascript
module-type: wikimethod
Adds tiddler filtering methods to the $tw.Wiki object.
Adds tiddler filtering to the $tw.Wiki object.
\*/
(function(){
@@ -149,16 +149,11 @@ exports.getFilterOperators = function() {
return this.filterOperators;
};
exports.filterTiddlers = function(filterString,currTiddlerTitle,source) {
exports.filterTiddlers = function(filterString,currTiddlerTitle,tiddlerList) {
var fn = this.compileFilter(filterString);
return fn.call(this,source,currTiddlerTitle);
return fn.call(this,tiddlerList || this.tiddlers,currTiddlerTitle);
};
/*
Compile a filter into a function with the signature fn(source,currTiddlerTitle) where:
source: an iterator function for the source tiddlers, called source(iterator), where iterator is called as iterator(tiddler,title)
currTiddlerTitle: the optional name of the current tiddler
*/
exports.compileFilter = function(filterString) {
var filterParseTree;
try {
@@ -180,15 +175,10 @@ exports.compileFilter = function(filterString) {
var accumulator = source,
results = [];
$tw.utils.each(operation.operators,function(operator) {
var operand = operator.operand,
operatorFunction;
if(!operator.operator) {
operatorFunction = filterOperators.title;
} else if(!filterOperators[operator.operator]) {
operatorFunction = filterOperators.field;
} else {
operatorFunction = filterOperators[operator.operator];
}
var operatorFunction = filterOperators[operator.operator] || filterOperators.field || function(source,operator,operations) {
return ["Filter Error: unknown operator '" + operator.operator + "'"];
},
operand = operator.operand;
if(operator.indirect) {
operand = self.getTextReference(operator.operand,"",currTiddlerTitle);
}
@@ -202,7 +192,7 @@ exports.compileFilter = function(filterString) {
wiki: self,
currTiddlerTitle: currTiddlerTitle
});
accumulator = self.makeTiddlerIterator(results);
accumulator = results;
});
return results;
};
@@ -220,26 +210,22 @@ exports.compileFilter = function(filterString) {
case "+": // This operation is applied to the main results so far
return function(results,source,currTiddlerTitle) {
// This replaces all the elements of the array, but keeps the actual array so that references to it are preserved
source = self.makeTiddlerIterator(results);
source = results.slice(0);
results.splice(0,results.length);
$tw.utils.pushTop(results,operationSubFunction(source,currTiddlerTitle));
};
}
})());
});
// Return a function that applies the operations to a source iterator of tiddler titles
return $tw.perf.measure("filter",function filterFunction(source,currTiddlerTitle) {
if(!source) {
source = self.each;
} else if(typeof source === "object") { // Array or hashmap
source = self.makeTiddlerIterator(source);
}
// Return a function that applies the operations to a source array/hashmap of tiddler titles
return function(source,currTiddlerTitle) {
source = source || self.tiddlers;
var results = [];
$tw.utils.each(operationFunctions,function(operationFunction) {
operationFunction(results,source,currTiddlerTitle);
});
return results;
});
};
};
})();

View File

@@ -1,45 +0,0 @@
/*\
title: $:/core/modules/filters/all.js
type: application/javascript
module-type: filteroperator
Filter operator for selecting tiddlers
[all[shadows+tiddlers]]
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var allFilterOperators;
function getAllFilterOperators() {
if(!allFilterOperators) {
allFilterOperators = {};
$tw.modules.applyMethods("allfilteroperator",allFilterOperators);
}
return allFilterOperators;
}
/*
Export our filter function
*/
exports.all = function(source,operator,options) {
// Get our suboperators
var allFilterOperators = getAllFilterOperators();
// Cycle through the suboperators accumulating their results
var results = [],
subops = operator.operand.split("+");
for(var t=0; t<subops.length; t++) {
var subop = allFilterOperators[subops[t]];
if(subop) {
$tw.utils.pushTop(results,subop(source,operator.prefix,options));
}
}
return results;
};
})();

View File

@@ -1,26 +0,0 @@
/*\
title: $:/core/modules/filters/all/current.js
type: application/javascript
module-type: allfilteroperator
Filter function for [all[current]]
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.current = function(source,prefix,options) {
if(options.currTiddlerTitle) {
return [options.currTiddlerTitle];
} else {
return [];
}
};
})();

View File

@@ -1,22 +0,0 @@
/*\
title: $:/core/modules/filters/all/missing.js
type: application/javascript
module-type: allfilteroperator
Filter function for [all[missing]]
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.missing = function(source,prefix,options) {
return options.wiki.getMissingTitles();
};
})();

View File

@@ -1,22 +0,0 @@
/*\
title: $:/core/modules/filters/all/orphans.js
type: application/javascript
module-type: allfilteroperator
Filter function for [all[orphans]]
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.orphans = function(source,prefix,options) {
return options.wiki.getOrphanTitles();
};
})();

View File

@@ -1,22 +0,0 @@
/*\
title: $:/core/modules/filters/all/shadows.js
type: application/javascript
module-type: allfilteroperator
Filter function for [all[shadows]]
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.shadows = function(source,prefix,options) {
return options.wiki.allShadowTitles();
};
})();

View File

@@ -1,22 +0,0 @@
/*\
title: $:/core/modules/filters/all/tiddlers.js
type: application/javascript
module-type: allfilteroperator
Filter function for [all[tiddlers]]
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.tiddlers = function(source,prefix,options) {
return options.wiki.allTitles();
};
})();

View File

@@ -17,9 +17,20 @@ Export our filter function
*/
exports.backlinks = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
// Function to check an individual title
function checkTiddler(title) {
$tw.utils.pushTop(results,options.wiki.getTiddlerBacklinks(title));
});
}
// Iterate through the source tiddlers
if($tw.utils.isArray(source)) {
$tw.utils.each(source,function(title) {
checkTiddler(title);
});
} else {
$tw.utils.each(source,function(element,title) {
checkTiddler(title);
});
}
return results;
};

View File

@@ -16,9 +16,18 @@ Filter operator that selects one tiddler for each unique value of the specified
Export our filter function
*/
exports.each = function(source,operator,options) {
var results = [],
values = {};
source(function(tiddler,title) {
// Convert the source to an array if necessary
if(!$tw.utils.isArray(source)) {
var copy = [];
$tw.utils.each(source,function(element,title) {
copy.push(title);
});
source = copy;
}
// Collect up the first tiddler with each unique value of the specified field
var results = [],values = {};
$tw.utils.each(source,function(title) {
var tiddler = options.wiki.getTiddler(title);
if(tiddler) {
var value = tiddler.getFieldString(operator.operand);
if(!$tw.utils.hop(values,value)) {

View File

@@ -16,14 +16,23 @@ Filter operator that selects one tiddler for each unique day covered by the spec
Export our filter function
*/
exports.eachday = function(source,operator,options) {
var results = [],
values = [];
// Function to convert a date/time to a date integer
var toDate = function(value) {
value = (new Date(value)).setHours(0,0,0,0);
return value+0;
};
source(function(tiddler,title) {
// Convert the source to an array if necessary
if(!$tw.utils.isArray(source)) {
var copy = [];
$tw.utils.each(source,function(element,title) {
copy.push(title);
});
source = copy;
}
// Collect up the first tiddler with each unique day value of the specified field
var results = [],values = [];
$tw.utils.each(source,function(title) {
var tiddler = options.wiki.getTiddler(title);
if(tiddler && tiddler.fields[operator.operand]) {
var value = toDate(tiddler.fields[operator.operand]);
if(values.indexOf(value) === -1) {

View File

@@ -17,47 +17,36 @@ Export our filter function
*/
exports.field = function(source,operator,options) {
var results = [],
fieldname = (operator.suffix || operator.operator || "title").toLowerCase();
if(operator.prefix === "!") {
if(operator.regexp) {
source(function(tiddler,title) {
if(tiddler) {
var text = tiddler.getFieldString(fieldname);
if(text !== null && !operator.regexp.exec(text)) {
results.push(title);
}
}
});
} else {
source(function(tiddler,title) {
if(tiddler) {
var text = tiddler.getFieldString(fieldname);
if(text !== null && text !== operator.operand) {
results.push(title);
}
}
});
fieldname = (operator.suffix || operator.operator).toLowerCase(),
isTitle = fieldname === "title";
// Function to check an individual title
function checkTiddler(title) {
var tiddler = options.wiki.getTiddler(title),
text = tiddler ? tiddler.getFieldString(fieldname) : (isTitle ? title : null),
match;
if(text !== null) {
if(operator.regexp) {
match = !!operator.regexp.exec(text);
} else {
match = text === operator.operand;
}
if(operator.prefix === "!") {
match = !match;
}
if(match) {
results.push(title);
}
}
}
// Iterate through the source tiddlers
if($tw.utils.isArray(source)) {
$tw.utils.each(source,function(title) {
checkTiddler(title);
});
} else {
if(operator.regexp) {
source(function(tiddler,title) {
if(tiddler) {
var text = tiddler.getFieldString(fieldname);
if(text !== null && !!operator.regexp.exec(text)) {
results.push(title);
}
}
});
} else {
source(function(tiddler,title) {
if(tiddler) {
var text = tiddler.getFieldString(fieldname);
if(text !== null && text === operator.operand) {
results.push(title);
}
}
});
}
$tw.utils.each(source,function(element,title) {
checkTiddler(title);
});
}
return results;
};

View File

@@ -16,14 +16,28 @@ Filter operator for returning the names of the fields on the selected tiddlers
Export our filter function
*/
exports.fields = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
var self = this,
results = [];
// Function to check an individual title
function checkTiddler(title) {
// Return the fields on the specified tiddler
var tiddler = options.wiki.getTiddler(title);
if(tiddler) {
for(var fieldName in tiddler.fields) {
$tw.utils.pushTop(results,fieldName);
}
}
});
}
// Iterate through the source tiddlers
if($tw.utils.isArray(source)) {
$tw.utils.each(source,function(title) {
checkTiddler(title);
});
} else {
$tw.utils.each(source,function(element,title) {
checkTiddler(title);
});
}
return results;
};

View File

@@ -17,17 +17,27 @@ Export our filter function
*/
exports.has = function(source,operator,options) {
var results = [];
if(operator.prefix === "!") {
source(function(tiddler,title) {
if(tiddler && (!$tw.utils.hop(tiddler.fields,operator.operand) || tiddler.fields[operator.operand] === "")) {
// Function to check an individual title
function checkTiddler(title) {
var tiddler = options.wiki.getTiddler(title);
if(tiddler) {
var match = $tw.utils.hop(tiddler.fields,operator.operand) && tiddler.fields[operator.operand] !== "";
if(operator.prefix === "!") {
match = !match;
}
if(match) {
results.push(title);
}
}
}
// Iterate through the source tiddlers
if($tw.utils.isArray(source)) {
$tw.utils.each(source,function(title) {
checkTiddler(title);
});
} else {
source(function(tiddler,title) {
if(tiddler && $tw.utils.hop(tiddler.fields,operator.operand) && tiddler.fields[operator.operand] !== "") {
results.push(title);
}
$tw.utils.each(source,function(element,title) {
checkTiddler(title);
});
}
return results;

View File

@@ -16,13 +16,26 @@ Filter operator for returning the indexes of a data tiddler
Export our filter function
*/
exports.indexes = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
var data = options.wiki.getTiddlerData(title);
var self = this,
results = [];
// Function to check an individual title
function checkTiddler(title) {
// Return the fields on the specified tiddler
var data = options.wiki.getTiddlerData(title,{});
if(data) {
$tw.utils.pushTop(results,Object.keys(data));
}
});
}
// Iterate through the source tiddlers
if($tw.utils.isArray(source)) {
$tw.utils.each(source,function(title) {
checkTiddler(title);
});
} else {
$tw.utils.each(source,function(element,title) {
checkTiddler(title);
});
}
results.sort();
return results;
};

View File

@@ -17,18 +17,31 @@ Export our filter function
*/
exports.current = function(source,prefix,options) {
var results = [];
if(prefix === "!") {
source(function(tiddler,title) {
if(title !== options.currTiddlerTitle) {
results.push(title);
// Function to check a tiddler
function checkTiddler(title) {
if(title !== options.currTiddlerTitle) {
results.push(title);
}
};
// Iterate through the source tiddlers
if($tw.utils.isArray(source)) {
if(prefix === "!") {
$tw.utils.each(source,function(title) {
checkTiddler(title);
});
} else {
if(source.indexOf(options.currTiddlerTitle) !== -1) {
results.push(options.currTiddlerTitle);
}
});
}
} else {
source(function(tiddler,title) {
if(title === options.currTiddlerTitle) {
results.push(title);
}
});
if(prefix === "!") {
$tw.utils.each(source,function(element,title) {
checkTiddler(title);
});
} else {
results.push(options.currTiddlerTitle);
}
}
return results;
};

View File

@@ -17,17 +17,24 @@ Export our filter function
*/
exports.image = function(source,prefix,options) {
var results = [];
if(prefix === "!") {
source(function(tiddler,title) {
if(!options.wiki.isImageTiddler(title)) {
results.push(title);
}
// Function to check a tiddler
function checkTiddler(title) {
var match = options.wiki.isImageTiddler(title);
if(prefix === "!") {
match = !match;
}
if(match) {
results.push(title);
}
};
// Iterate through the source tiddlers
if($tw.utils.isArray(source)) {
$tw.utils.each(source,function(title) {
checkTiddler(title);
});
} else {
source(function(tiddler,title) {
if(options.wiki.isImageTiddler(title)) {
results.push(title);
}
$tw.utils.each(source,function(element,title) {
checkTiddler(title);
});
}
return results;

View File

@@ -16,19 +16,31 @@ Filter function for [is[missing]]
Export our filter function
*/
exports.missing = function(source,prefix,options) {
var results = [];
if(prefix === "!") {
source(function(tiddler,title) {
if(options.wiki.tiddlerExists(title)) {
var results = [],
missingTitles;
// Iterate through the source tiddlers
if($tw.utils.isArray(source)) {
missingTitles = options.wiki.getMissingTitles();
$tw.utils.each(source,function(title) {
var match = missingTitles.indexOf(title) !== -1;
if(prefix === "!") {
match = !match;
}
if(match) {
results.push(title);
}
});
} else {
source(function(tiddler,title) {
if(!options.wiki.tiddlerExists(title)) {
if(prefix !== "!") {
missingTitles = options.wiki.getMissingTitles();
$tw.utils.each(missingTitles,function(title) {
results.push(title);
}
});
});
} else {
$tw.utils.each(source,function(element,title) {
results.push(title);
});
}
}
return results;
};

View File

@@ -18,15 +18,24 @@ Export our filter function
exports.orphan = function(source,prefix,options) {
var results = [],
orphanTitles = options.wiki.getOrphanTitles();
if(prefix === "!") {
source(function(tiddler,title) {
if(orphanTitles.indexOf(title) === -1) {
// Iterate through the source tiddlers
if($tw.utils.isArray(source)) {
$tw.utils.each(source,function(title) {
var match = orphanTitles.indexOf(title) !== -1;
if(prefix === "!") {
match = !match;
}
if(match) {
results.push(title);
}
});
} else {
source(function(tiddler,title) {
if(orphanTitles.indexOf(title) !== -1) {
$tw.utils.each(source,function(element,title) {
var match = orphanTitles.indexOf(title) !== -1;
if(prefix === "!") {
match = !match;
}
if(match) {
results.push(title);
}
});

View File

@@ -17,18 +17,31 @@ Export our filter function
*/
exports.shadow = function(source,prefix,options) {
var results = [];
if(prefix === "!") {
source(function(tiddler,title) {
if(!options.wiki.isShadowTiddler(title)) {
results.push(title);
}
// Function to check a tiddler
function checkTiddler(title) {
var match = options.wiki.isShadowTiddler(title);
if(prefix === "!") {
match = !match;
}
if(match) {
results.push(title);
}
};
// Iterate through the source tiddlers
if($tw.utils.isArray(source)) {
$tw.utils.each(source,function(title) {
checkTiddler(title);
});
} else {
source(function(tiddler,title) {
if(options.wiki.isShadowTiddler(title)) {
if(prefix !== "!") {
$tw.utils.each(options.wiki.shadowTiddlers,function(tiddler,title) {
results.push(title);
}
});
});
} else {
$tw.utils.each(source,function(element,title) {
checkTiddler(title);
});
}
}
return results;
};

View File

@@ -17,17 +17,24 @@ Export our filter function
*/
exports.system = function(source,prefix,options) {
var results = [];
if(prefix === "!") {
source(function(tiddler,title) {
if(!options.wiki.isSystemTiddler(title)) {
results.push(title);
}
// Function to check a tiddler
function checkTiddler(title) {
var match = options.wiki.isSystemTiddler(title);
if(prefix === "!") {
match = !match;
}
if(match) {
results.push(title);
}
};
// Iterate through the source tiddlers
if($tw.utils.isArray(source)) {
$tw.utils.each(source,function(title) {
checkTiddler(title);
});
} else {
source(function(tiddler,title) {
if(options.wiki.isSystemTiddler(title)) {
results.push(title);
}
$tw.utils.each(source,function(element,title) {
checkTiddler(title);
});
}
return results;

View File

@@ -1,37 +0,0 @@
/*\
title: $:/core/modules/filters/is/tag.js
type: application/javascript
module-type: isfilteroperator
Filter function for [is[tag]]
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.tag = function(source,prefix,options) {
var results = [],
tagMap = options.wiki.getTagMap();
if(prefix === "!") {
source(function(tiddler,title) {
if(!$tw.utils.hop(tagMap,title)) {
results.push(title);
}
});
} else {
source(function(tiddler,title) {
if($tw.utils.hop(tagMap,title)) {
results.push(title);
}
});
}
return results;
};
})();

View File

@@ -17,17 +17,24 @@ Export our filter function
*/
exports.tiddler = function(source,prefix,options) {
var results = [];
if(prefix === "!") {
source(function(tiddler,title) {
if(!options.wiki.tiddlerExists(title)) {
results.push(title);
}
// Function to check a tiddler
function checkTiddler(title) {
var match = options.wiki.tiddlerExists(title);
if(prefix === "!") {
match = !match;
}
if(match) {
results.push(title);
}
};
// Iterate through the source tiddlers
if($tw.utils.isArray(source)) {
$tw.utils.each(source,function(title) {
checkTiddler(title);
});
} else {
source(function(tiddler,title) {
if(options.wiki.tiddlerExists(title)) {
results.push(title);
}
$tw.utils.each(source,function(element,title) {
checkTiddler(title);
});
}
return results;

View File

@@ -17,16 +17,20 @@ Export our filter function
*/
exports.limit = function(source,operator,options) {
var results = [];
// Convert to an array
source(function(tiddler,title) {
results.push(title);
});
// Convert to an array if necessary
if(!$tw.utils.isArray(source)) {
var copy = [];
$tw.utils.each(source,function(element,title) {
copy.push(title);
});
source = copy;
}
// Slice the array if necessary
var limit = Math.min(results.length,parseInt(operator.operand,10));
var limit = Math.min(source.length,parseInt(operator.operand,10));
if(operator.prefix === "!") {
results = results.slice(-limit);
results = source.slice(source.length - limit);
} else {
results = results.slice(0,limit);
results = source.slice(0,limit);
}
return results;
};

View File

@@ -17,9 +17,20 @@ Export our filter function
*/
exports.links = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
// Function to check an individual title
function checkTiddler(title) {
$tw.utils.pushTop(results,options.wiki.getTiddlerLinks(title));
});
}
// Iterate through the source tiddlers
if($tw.utils.isArray(source)) {
$tw.utils.each(source,function(title) {
checkTiddler(title);
});
} else {
$tw.utils.each(source,function(element,title) {
checkTiddler(title);
});
}
return results;
};

View File

@@ -19,14 +19,28 @@ exports.list = function(source,operator,options) {
var results = [],
tr = $tw.utils.parseTextReference(operator.operand),
list = options.wiki.getTiddlerList(tr.title || options.currTiddlerTitle,tr.field,tr.index);
if(operator.prefix === "!") {
source(function(tiddler,title) {
if(list.indexOf(title) === -1) {
results.push(title);
}
function checkTiddler(title) {
var match = list.indexOf(title) !== -1;
if(operator.prefix === "!") {
match = !match;
}
if(match) {
results.push(title);
}
}
// Iterate through the source tiddlers
if($tw.utils.isArray(source)) {
$tw.utils.each(source,function(title) {
checkTiddler(title);
});
} else {
results = list;
if(operator.prefix !== "!") {
results = list;
} else {
$tw.utils.each(source,function(element,title) {
checkTiddler(title);
});
}
}
return results;
};

View File

@@ -17,9 +17,20 @@ Export our filter function
*/
exports.listed = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
// Function to check an individual title
function checkTiddler(title) {
$tw.utils.pushTop(results,options.wiki.findListingsOfTiddler(title));
});
}
// Iterate through the source tiddlers
if($tw.utils.isArray(source)) {
$tw.utils.each(source,function(title) {
checkTiddler(title);
});
} else {
$tw.utils.each(source,function(element,title) {
checkTiddler(title);
});
}
return results;
};

View File

@@ -17,7 +17,10 @@ Reverse list
*/
exports.reverse = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
if(!$tw.utils.isArray(source)) {
source = Object.keys(source).sort();
}
$tw.utils.each(source,function(title) {
results.unshift(title);
});
return results;
@@ -27,36 +30,33 @@ exports.reverse = function(source,operator,options) {
First entry/entries in list
*/
exports.first = function(source,operator,options) {
var count = parseInt(operator.operand) || 1,
results = [];
source(function(tiddler,title) {
results.push(title);
});
return results.slice(0,count);
var count = parseInt(operator.operand) || 1;
if(!$tw.utils.isArray(source)) {
source = Object.keys(source).sort();
}
return source.slice(0,Math.min(count,source.length));
};
/*
Last entry/entries in list
*/
exports.last = function(source,operator,options) {
var count = parseInt(operator.operand) || 1,
results = [];
source(function(tiddler,title) {
results.push(title);
});
return results.slice(-count);
var count = parseInt(operator.operand) || 1;
if(!$tw.utils.isArray(source)) {
source = Object.keys(source).sort();
}
return source.slice(-count);
};
/*
All but the first entry/entries of the list
*/
exports.rest = function(source,operator,options) {
var count = parseInt(operator.operand) || 1,
results = [];
source(function(tiddler,title) {
results.push(title);
});
return results.slice(count);
var count = parseInt(operator.operand) || 1;
if(!$tw.utils.isArray(source)) {
source = Object.keys(source).sort();
}
return source.slice(count);
};
exports.butfirst = exports.rest;
exports.bf = exports.rest;
@@ -65,12 +65,11 @@ exports.bf = exports.rest;
All but the last entry/entries of the list
*/
exports.butlast = function(source,operator,options) {
var count = parseInt(operator.operand) || 1,
results = [];
source(function(tiddler,title) {
results.push(title);
});
return results.slice(0,-count);
var count = parseInt(operator.operand) || 1;
if(!$tw.utils.isArray(source)) {
source = Object.keys(source).sort();
}
return source.slice(0,-count);
};
exports.bl = exports.butlast;
@@ -78,12 +77,11 @@ exports.bl = exports.butlast;
The nth member of the list
*/
exports.nth = function(source,operator,options) {
var count = parseInt(operator.operand) || 1,
results = [];
source(function(tiddler,title) {
results.push(title);
});
return results.slice(count - 1,count);
var count = parseInt(operator.operand) || 1;
if(!$tw.utils.isArray(source)) {
source = Object.keys(source).sort();
}
return source.slice(count-1,count);
};
})();

View File

@@ -16,12 +16,22 @@ Filter operator for returning the titles of the modules of a given type in this
Export our filter function
*/
exports.modules = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
$tw.utils.each($tw.modules.types[title],function(moduleInfo,moduleName) {
results.push(moduleName);
var results = [],
pushModules = function(type) {
$tw.utils.each($tw.modules.types[type],function(moduleInfo,moduleName) {
results.push(moduleName);
});
};
// Iterate through the source tiddlers
if($tw.utils.isArray(source)) {
$tw.utils.each(source,function(title) {
pushModules(title);
});
});
} else {
$tw.utils.each(source,function(element,title) {
pushModules(title);
});
}
results.sort();
return results;
};

View File

@@ -18,14 +18,25 @@ Export our filter function
exports.next = function(source,operator,options) {
var results = [],
list = options.wiki.getTiddlerList(operator.operand);
source(function(tiddler,title) {
function checkTiddler(title) {
var match = list.indexOf(title);
// increment match and then test if result is in range
match++;
if(match > 0 && match < list.length) {
results.push(list[match]);
}
});
}
// Iterate through the source tiddlers
if($tw.utils.isArray(source)) {
$tw.utils.each(source,function(title) {
checkTiddler(title);
});
} else {
$tw.utils.each(source,function(element,title) {
checkTiddler(title);
});
}
return results;
};

View File

@@ -1,32 +0,0 @@
/*\
title: $:/core/modules/filters/plugintiddlers.js
type: application/javascript
module-type: filteroperator
Filter operator for returning the titles of the shadow tiddlers within a plugin
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.plugintiddlers = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
var pluginInfo = options.wiki.getPluginInfo(title);
if(pluginInfo) {
$tw.utils.each(pluginInfo.tiddlers,function(fields,title) {
results.push(title);
});
}
});
results.sort();
return results;
};
})();

View File

@@ -17,17 +17,24 @@ Export our filter function
*/
exports.prefix = function(source,operator,options) {
var results = [];
if(operator.prefix === "!") {
source(function(tiddler,title) {
if(title.substr(0,operator.operand.length).toLowerCase() !== operator.operand.toLowerCase()) {
results.push(title);
}
// Function to check an individual title
function checkTiddler(title) {
var match = title.substr(0,operator.operand.length).toLowerCase() === operator.operand.toLowerCase();
if(operator.prefix === "!") {
match = !match;
}
if(match) {
results.push(title);
}
}
// Iterate through the source tiddlers
if($tw.utils.isArray(source)) {
$tw.utils.each(source,function(title) {
checkTiddler(title);
});
} else {
source(function(tiddler,title) {
if(title.substr(0,operator.operand.length).toLowerCase() === operator.operand.toLowerCase()) {
results.push(title);
}
$tw.utils.each(source,function(element,title) {
checkTiddler(title);
});
}
return results;

View File

@@ -18,14 +18,25 @@ Export our filter function
exports.previous = function(source,operator,options) {
var results = [],
list = options.wiki.getTiddlerList(operator.operand);
source(function(tiddler,title) {
function checkTiddler(title) {
var match = list.indexOf(title);
// increment match and then test if result is in range
// decrement match and then test if result is in range
match--;
if(match >= 0) {
if( match >= 0 ) {
results.push(list[match]);
}
});
}
// Iterate through the source tiddlers
if($tw.utils.isArray(source)) {
$tw.utils.each(source,function(title) {
checkTiddler(title);
});
} else {
$tw.utils.each(source,function(element,title) {
checkTiddler(title);
});
}
return results;
};

View File

@@ -1,28 +0,0 @@
/*\
title: $:/core/modules/filters/removeprefix.js
type: application/javascript
module-type: filteroperator
Filter operator for removing a prefix from each title in the list. Titles that do not start with the prefix are removed.
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.removeprefix = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
if(title.substr(0,operator.operand.length).toLowerCase() === operator.operand.toLowerCase()) {
results.push(title.substr(operator.operand.length));
}
});
return results;
};
})();

View File

@@ -17,19 +17,34 @@ Export our filter function
*/
exports.sameday = function(source,operator,options) {
var results = [],
fieldName = operator.suffix || "modified",
targetDate = (new Date($tw.utils.parseDate(operator.operand))).setHours(0,0,0,0);
// Function to convert a date/time to a date integer
var isSameDay = function(dateField) {
return (new Date(dateField)).setHours(0,0,0,0) === targetDate;
isSameDay = function(dateField,dateString) {
var date1 = (new Date(dateField)).setHours(0,0,0,0),
date2 = (new Date($tw.utils.parseDate(dateString))).setHours(0,0,0,0);
return date1 === date2;
};
source(function(tiddler,title) {
if(tiddler && tiddler.fields[fieldName]) {
if(isSameDay(tiddler.fields[fieldName])) {
// Function to check an individual title
function checkTiddler(title) {
var tiddler = options.wiki.getTiddler(title);
if(tiddler) {
var match = isSameDay(tiddler.fields.modified,operator.operand);
if(operator.prefix === "!") {
match = !match;
}
if(match) {
results.push(title);
}
}
});
}
// Iterate through the source tiddlers
if($tw.utils.isArray(source)) {
$tw.utils.each(source,function(title) {
checkTiddler(title);
});
} else {
$tw.utils.each(source,function(element,title) {
checkTiddler(title);
});
}
return results;
};

View File

@@ -18,7 +18,7 @@ Export our filter function
exports.search = function(source,operator,options) {
var invert = operator.prefix === "!";
return options.wiki.search(operator.operand,{
source: source,
titles: source,
invert: invert
});
};

View File

@@ -1,30 +0,0 @@
/*\
title: $:/core/modules/filters/shadowsource.js
type: application/javascript
module-type: filteroperator
Filter operator for returning the source plugins for shadow tiddlers
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.shadowsource = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
var source = options.wiki.getShadowSource(title);
if(source) {
$tw.utils.pushTop(results,source);
}
});
results.sort();
return results;
};
})();

View File

@@ -17,33 +17,38 @@ Export our filter function
*/
exports.sort = function(source,operator,options) {
var results = prepare_results(source);
options.wiki.sortTiddlers(results,operator.operand || "title",operator.prefix === "!",false,false);
options.wiki.sortTiddlers(results,operator.operand,operator.prefix === "!",false,false);
return results;
};
exports.nsort = function(source,operator,options) {
var results = prepare_results(source);
options.wiki.sortTiddlers(results,operator.operand || "title",operator.prefix === "!",false,true);
options.wiki.sortTiddlers(results,operator.operand,operator.prefix === "!",false,true);
return results;
};
exports.sortcs = function(source,operator,options) {
var results = prepare_results(source);
options.wiki.sortTiddlers(results,operator.operand || "title",operator.prefix === "!",true,false);
options.wiki.sortTiddlers(results,operator.operand,operator.prefix === "!",true,false);
return results;
};
exports.nsortcs = function(source,operator,options) {
var results = prepare_results(source);
options.wiki.sortTiddlers(results,operator.operand || "title",operator.prefix === "!",true,true);
options.wiki.sortTiddlers(results,operator.operand,operator.prefix === "!",true,true);
return results;
};
var prepare_results = function (source) {
var results = [];
source(function(tiddler,title) {
results.push(title);
});
var results;
if($tw.utils.isArray(source)) {
results = source;
} else {
results = [];
$tw.utils.each(source,function(element,title) {
results.push(title);
});
}
return results;
}

View File

@@ -17,18 +17,31 @@ Export our filter function
*/
exports.tag = function(source,operator,options) {
var results = [];
if(operator.prefix === "!") {
source(function(tiddler,title) {
if(tiddler && !tiddler.hasTag(operator.operand)) {
// Function to check an individual title
function checkTiddler(title) {
var tiddler = options.wiki.getTiddler(title);
if(tiddler) {
var match = tiddler.hasTag(operator.operand);
if(operator.prefix === "!") {
match = !match;
}
if(match) {
results.push(title);
}
}
}
// Iterate through the source tiddlers
if($tw.utils.isArray(source)) {
$tw.utils.each(source,function(title) {
checkTiddler(title);
});
} else {
source(function(tiddler,title) {
if(tiddler && tiddler.hasTag(operator.operand)) {
results.push(title);
}
$tw.utils.each(source,function(element,title) {
checkTiddler(title);
});
}
// Sort the results if we are matching a tag
if(operator.prefix !== "!") {
results = options.wiki.sortByList(results,operator.operand);
}
return results;

View File

@@ -17,9 +17,20 @@ Export our filter function
*/
exports.tagging = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
// Function to check an individual title
function checkTiddler(title) {
$tw.utils.pushTop(results,options.wiki.getTiddlersWithTag(title));
});
}
// Iterate through the source tiddlers
if($tw.utils.isArray(source)) {
$tw.utils.each(source,function(title) {
checkTiddler(title);
});
} else {
$tw.utils.each(source,function(element,title) {
checkTiddler(title);
});
}
return results;
};

View File

@@ -17,11 +17,23 @@ Export our filter function
*/
exports.tags = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
// Function to check an individual title
function checkTiddler(title) {
var tiddler = options.wiki.getTiddler(title);
if(tiddler && tiddler.fields.tags) {
$tw.utils.pushTop(results,tiddler.fields.tags);
}
});
}
// Iterate through the source tiddlers
if($tw.utils.isArray(source)) {
$tw.utils.each(source,function(title) {
checkTiddler(title);
});
} else {
$tw.utils.each(source,function(element,title) {
checkTiddler(title);
});
}
return results;
};

View File

@@ -17,14 +17,35 @@ Export our filter function
*/
exports.title = function(source,operator,options) {
var results = [];
if(operator.prefix === "!") {
source(function(tiddler,title) {
if(tiddler && tiddler.fields.title !== operator.operand) {
// Function to check an individual title
function checkTiddler(title) {
var tiddler = options.wiki.getTiddler(title);
if(tiddler) {
var match = tiddler.fields[operator.operator] === operator.operand;
if(operator.prefix === "!") {
match = !match;
}
if(match) {
results.push(title);
}
}
}
// Iterate through the source tiddlers
if($tw.utils.isArray(source)) {
$tw.utils.each(source,function(title) {
checkTiddler(title);
});
} else {
results.push(operator.operand);
// If we're filtering a hashmap we change the behaviour to pass through missing tiddlers
if(operator.prefix !== "!") {
results.push(operator.operand);
} else {
$tw.utils.each(source,function(element,title) {
if(title !== operator.operand) {
checkTiddler(title);
}
});
}
}
return results;
};

View File

@@ -17,17 +17,25 @@ Export our filter function
*/
exports.untagged = function(source,operator,options) {
var results = [];
if(operator.prefix === "!") {
source(function(tiddler,title) {
if(tiddler && $tw.utils.isArray(tiddler.fields.tags) && tiddler.fields.tags.length > 0) {
$tw.utils.pushTop(results,title);
}
// Function to check an individual title
function checkTiddler(title) {
var tiddler = options.wiki.getTiddler(title),
match = tiddler && $tw.utils.isArray(tiddler.fields.tags) && tiddler.fields.tags.length > 0;
if(operator.prefix !== "!") {
match = !match;
}
if(match) {
$tw.utils.pushTop(results,title);
}
}
// Iterate through the source tiddlers
if($tw.utils.isArray(source)) {
$tw.utils.each(source,function(title) {
checkTiddler(title);
});
} else {
source(function(tiddler,title) {
if(!tiddler || !tiddler.hasField("tags") || ($tw.utils.isArray(tiddler.fields.tags) && tiddler.fields.tags.length === 0)) {
$tw.utils.pushTop(results,title);
}
$tw.utils.each(source,function(element,title) {
checkTiddler(title);
});
}
return results;

View File

@@ -1,37 +0,0 @@
/*\
title: $:/core/modules/language.js
type: application/javascript
module-type: global
The $tw.Language() manages translateable strings
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Create an instance of the language manager. Options include:
wiki: wiki from which to retrieve translation tiddlers
*/
function Language(options) {
options = options || "";
this.wiki = options.wiki || $tw.wiki;
}
/*
Return a single translateable string. The title is automatically prefixed with "$:/language/"
Options include:
variables: optional hashmap of variables to supply to the language wikification
*/
Language.prototype.getString = function(title,options) {
options = options || {};
title = "$:/language/" + title;
return this.wiki.renderTiddler("text/plain",title,{variables: options.variables});
};
exports.Language = Language;
})();

View File

@@ -1,53 +0,0 @@
/*\
title: $:/core/modules/parsers/csvparser.js
type: application/javascript
module-type: parser
The CSV text parser processes CSV files into a table wrapped in a scrollable widget
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var CsvParser = function(type,text,options) {
// Table framework
this.tree = [{
"type": "element", "tag": "$scrollable", "children": [{
"type": "element", "tag": "table", "children": [{
"type": "element", "tag": "tbody", "children": []
}], "attributes": {
"class": {"type": "string", "value": "tw-csv-table"}
}
}]
}];
// Split the text into lines
var lines = text.split(/\r?\n/mg),
tag = "th";
for(var line=0; line<lines.length; line++) {
var lineText = lines[line];
if(lineText) {
var row = {
"type": "element", "tag": "tr", "children": []
};
var columns = lineText.split(",");
for(var column=0; column<columns.length; column++) {
row.children.push({
"type": "element", "tag": tag, "children": [{
"type": "text",
"text": columns[column]
}]
});
}
tag = "td";
this.tree[0].children[0].children[0].children.push(row);
}
}
};
exports["text/csv"] = CsvParser;
})();

View File

@@ -1,268 +0,0 @@
/*\
title: $:/core/modules/utils/parseutils.js
type: application/javascript
module-type: utils
Utility functions concerned with parsing text into tokens.
Most functions have the following pattern:
* The parameters are:
** `source`: the source string being parsed
** `pos`: the current parse position within the string
** Any further parameters are used to identify the token that is being parsed
* The return value is:
** null if the token was not found at the specified position
** an object representing the token with the following standard fields:
*** `type`: string indicating the type of the token
*** `start`: start position of the token in the source string
*** `end`: end position of the token in the source string
*** Any further fields required to describe the token
The exception is `skipWhiteSpace`, which just returns the position after the whitespace.
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Look for a whitespace token. Returns null if not found, otherwise returns {type: "whitespace", start:, end:,}
*/
exports.parseWhiteSpace = function(source,pos) {
var node = {
type: "whitespace",
start: pos
};
var re = /(\s)+/g;
re.lastIndex = pos;
var match = re.exec(source);
if(match && match.index === pos) {
node.end = pos + match[0].length;
return node;
}
return null;
};
/*
Convenience wrapper for parseWhiteSpace. Returns the position after the whitespace
*/
exports.skipWhiteSpace = function(source,pos) {
var whitespace = $tw.utils.parseWhiteSpace(source,pos);
if(whitespace) {
return whitespace.end;
}
return pos;
};
/*
Look for a given string token. Returns null if not found, otherwise returns {type: "token", value:, start:, end:,}
*/
exports.parseTokenString = function(source,pos,token) {
var match = source.indexOf(token,pos) === pos;
if(match) {
return {
type: "token",
value: token,
start: pos,
end: pos + token.length
};
}
return null;
};
/*
Look for a token matching a regex. Returns null if not found, otherwise returns {type: "regexp", match:, start:, end:,}
*/
exports.parseTokenRegExp = function(source,pos,reToken) {
var node = {
type: "regexp",
start: pos
};
reToken.lastIndex = pos;
node.match = reToken.exec(source);
if(node.match && node.match.index === pos) {
node.end = pos + node.match[0].length;
return node;
} else {
return null;
}
};
/*
Look for a string literal. Returns null if not found, otherwise returns {type: "string", value:, start:, end:,}
*/
exports.parseStringLiteral = function(source,pos) {
var node = {
type: "string",
start: pos
};
var reString = /(?:"([^"]*)")|(?:'([^']*)')/g;
reString.lastIndex = pos;
var match = reString.exec(source);
if(match && match.index === pos) {
node.value = match[1] === undefined ? match[2] : match[1];
node.end = pos + match[0].length;
return node;
} else {
return null;
}
};
/*
Look for a macro invocation parameter. Returns null if not found, or {type: "macro-parameter", name:, value:, start:, end:}
*/
exports.parseMacroParameter = function(source,pos) {
var node = {
type: "macro-parameter",
start: pos
};
// Define our regexp
var reMacroParameter = /(?:([A-Za-z0-9\-_]+)\s*:)?(?:\s*(?:"([^"]*)"|'([^']*)'|\[\[([^\]]*)\]\]|([^\s>"'=]+)))/g;
// Skip whitespace
pos = $tw.utils.skipWhiteSpace(source,pos);
// Look for the parameter
var token = $tw.utils.parseTokenRegExp(source,pos,reMacroParameter);
if(!token) {
return null;
}
pos = token.end;
// Get the parameter details
node.value = token.match[2] !== undefined ? token.match[2] : (
token.match[3] !== undefined ? token.match[3] : (
token.match[4] !== undefined ? token.match[4] : (
token.match[5] !== undefined ? token.match[5] : (
""
)
)
)
);
if(token.match[1]) {
node.name = token.match[1];
}
// Update the end position
node.end = pos;
return node;
};
/*
Look for a macro invocation. Returns null if not found, or {type: "macrocall", name:, parameters:, start:, end:}
*/
exports.parseMacroInvocation = function(source,pos) {
var node = {
type: "macrocall",
start: pos,
params: []
};
// Define our regexps
var reMacroName = /([^\s>"'=]+)/g;
// Skip whitespace
pos = $tw.utils.skipWhiteSpace(source,pos);
// Look for a double less than sign
var token = $tw.utils.parseTokenString(source,pos,"<<");
if(!token) {
return null;
}
pos = token.end;
// Get the macro name
var name = $tw.utils.parseTokenRegExp(source,pos,reMacroName);
if(!name) {
return null;
}
node.name = name.match[1];
pos = name.end;
// Process parameters
var parameter = $tw.utils.parseMacroParameter(source,pos);
while(parameter) {
node.params.push(parameter);
pos = parameter.end;
// Get the next parameter
parameter = $tw.utils.parseMacroParameter(source,pos);
}
// Skip whitespace
pos = $tw.utils.skipWhiteSpace(source,pos);
// Look for a double greater than sign
token = $tw.utils.parseTokenString(source,pos,">>");
if(!token) {
return null;
}
pos = token.end;
// Update the end position
node.end = pos;
return node;
};
/*
Look for an HTML attribute definition. Returns null if not found, otherwise returns {type: "attribute", name:, valueType: "string|indirect|macro", value:, start:, end:,}
*/
exports.parseAttribute = function(source,pos) {
var node = {
start: pos
};
// Define our regexps
var reAttributeName = /([^\/\s>"'=]+)/g,
reUnquotedAttribute = /([^\/\s<>"'=]+)/g,
reIndirectValue = /\{\{([^\}]+)\}\}/g;
// Skip whitespace
pos = $tw.utils.skipWhiteSpace(source,pos);
// Get the attribute name
var name = $tw.utils.parseTokenRegExp(source,pos,reAttributeName);
if(!name) {
return null;
}
node.name = name.match[1];
pos = name.end;
// Skip whitespace
pos = $tw.utils.skipWhiteSpace(source,pos);
// Look for an equals sign
var token = $tw.utils.parseTokenString(source,pos,"=");
if(token) {
pos = token.end;
// Skip whitespace
pos = $tw.utils.skipWhiteSpace(source,pos);
// Look for a string literal
var stringLiteral = $tw.utils.parseStringLiteral(source,pos);
if(stringLiteral) {
pos = stringLiteral.end;
node.type = "string";
node.value = stringLiteral.value;
} else {
// Look for an indirect value
var indirectValue = $tw.utils.parseTokenRegExp(source,pos,reIndirectValue);
if(indirectValue) {
pos = indirectValue.end;
node.type = "indirect";
node.textReference = indirectValue.match[1];
} else {
// Look for a unquoted value
var unquotedValue = $tw.utils.parseTokenRegExp(source,pos,reUnquotedAttribute);
if(unquotedValue) {
pos = unquotedValue.end;
node.type = "string";
node.value = unquotedValue.match[1];
} else {
// Look for a macro invocation value
var macroInvocation = $tw.utils.parseMacroInvocation(source,pos);
if(macroInvocation) {
pos = macroInvocation.end;
node.type = "macro";
node.value = macroInvocation;
} else {
node.type = "string";
node.value = "true";
}
}
}
}
} else {
node.type = "string";
node.value = "true";
}
// Update the end position
node.end = pos;
return node;
};
})();

View File

@@ -26,7 +26,7 @@ exports.types = {inline: true};
exports.init = function(parser) {
this.parser = parser;
// Regexp to match
this.matchRegExp = /~?(?:file|http|https|mailto|ftp|irc|news|data|skype):[^\s<>{}\[\]`|'"\\^~]+(?:\/|\b)/mg;
this.matchRegExp = /~?(?:file|http|https|mailto|ftp|irc|news|data|skype):[^\s'"<>]+(?:\/|\b)/mg;
};
exports.parse = function() {

View File

@@ -36,7 +36,7 @@ exports.parse = function() {
// Return the heading
return [{
type: "element",
tag: "h" + headingLevel,
tag: "h" + this.match[1].length,
attributes: {
"class": {type: "string", value: classes.join(" ")}
},

View File

@@ -48,7 +48,7 @@ exports.parse = function() {
// Advance the parser position to past the tag
this.parser.pos = tag.end;
// Check for an immediately following double linebreak
var hasLineBreak = !tag.isSelfClosing && !!$tw.utils.parseTokenRegExp(this.parser.source,this.parser.pos,/([^\S\n]*\r?\n(?:[^\S\n]*\r?\n|$))/g);
var hasLineBreak = !tag.isSelfClosing && !!this.parseTokenRegExp(this.parser.source,this.parser.pos,/(\r?\n(?:\r?\n|$))/g);
// Set whether we're in block mode
tag.isBlock = this.is.block || hasLineBreak;
// Parse the body if we need to
@@ -71,7 +71,244 @@ exports.parse = function() {
};
/*
Look for an HTML tag. Returns null if not found, otherwise returns {type: "element", name:, attributes: [], isSelfClosing:, start:, end:,}
Look for a whitespace token. Returns null if not found, otherwise returns {type: "whitespace", start:, end:,}
*/
exports.parseWhiteSpace = function(source,pos) {
var node = {
type: "whitespace",
start: pos
};
var re = /(\s)+/g;
re.lastIndex = pos;
var match = re.exec(source);
if(match && match.index === pos) {
node.end = pos + match[0].length;
return node;
}
return null;
};
/*
Convenience wrapper for parseWhiteSpace
*/
exports.skipWhiteSpace = function(source,pos) {
var whitespace = this.parseWhiteSpace(source,pos);
if(whitespace) {
return whitespace.end;
}
return pos;
};
/*
Look for a given string token. Returns null if not found, otherwise returns {type: "token", value:, start:, end:,}
*/
exports.parseTokenString = function(source,pos,token) {
var match = source.indexOf(token,pos) === pos;
if(match) {
return {
type: "token",
value: token,
start: pos,
end: pos + token.length
};
}
return null;
};
/*
Look for a token matching a regex. Returns null if not found, otherwise returns {type: "regexp", match:, start:, end:,}
*/
exports.parseTokenRegExp = function(source,pos,reToken) {
var node = {
type: "regexp",
start: pos
};
reToken.lastIndex = pos;
node.match = reToken.exec(source);
if(node.match && node.match.index === pos) {
node.end = pos + node.match[0].length;
return node;
} else {
return null;
}
};
/*
Look for a string literal. Returns null if not found, otherwise returns {type: "string", value:, start:, end:,}
*/
exports.parseStringLiteral = function(source,pos) {
var node = {
type: "string",
start: pos
};
var reString = /(?:"([^"]*)")|(?:'([^']*)')/g;
reString.lastIndex = pos;
var match = reString.exec(source);
if(match && match.index === pos) {
node.value = match[1] === undefined ? match[2] : match[1];
node.end = pos + match[0].length;
return node;
} else {
return null;
}
};
/*
Look for a macro invocation parameter. Returns null if not found, or {type: "macro-parameter", name:, value:, start:, end:}
*/
exports.parseMacroParameter = function(source,pos) {
var node = {
type: "macro-parameter",
start: pos
};
// Define our regexp
var reMacroParameter = /(?:([A-Za-z0-9\-_]+)\s*:)?(?:\s*(?:"([^"]*)"|'([^']*)'|\[\[([^\]]*)\]\]|([^\s>"'=]+)))/g;
// Skip whitespace
pos = this.skipWhiteSpace(source,pos);
// Look for the parameter
var token = this.parseTokenRegExp(source,pos,reMacroParameter);
if(!token) {
return null;
}
pos = token.end;
// Get the parameter details
node.value = token.match[2] !== undefined ? token.match[2] : (
token.match[3] !== undefined ? token.match[3] : (
token.match[4] !== undefined ? token.match[4] : (
token.match[5] !== undefined ? token.match[5] : (
""
)
)
)
);
if(token.match[1]) {
node.name = token.match[1];
}
// Update the end position
node.end = pos;
return node;
};
/*
Look for a macro invocation. Returns null if not found, or {type: "macrocall", name:, parameters:, start:, end:}
*/
exports.parseMacroInvocation = function(source,pos) {
var node = {
type: "macrocall",
start: pos,
params: []
};
// Define our regexps
var reMacroName = /([^\s>"'=]+)/g;
// Skip whitespace
pos = this.skipWhiteSpace(source,pos);
// Look for a double less than sign
var token = this.parseTokenString(source,pos,"<<");
if(!token) {
return null;
}
pos = token.end;
// Get the macro name
var name = this.parseTokenRegExp(source,pos,reMacroName);
if(!name) {
return null;
}
node.name = name.match[1];
pos = name.end;
// Process parameters
var parameter = this.parseMacroParameter(source,pos);
while(parameter) {
node.params.push(parameter);
pos = parameter.end;
// Get the next parameter
parameter = this.parseMacroParameter(source,pos);
}
// Skip whitespace
pos = this.skipWhiteSpace(source,pos);
// Look for a double greater than sign
token = this.parseTokenString(source,pos,">>");
if(!token) {
return null;
}
pos = token.end;
// Update the end position
node.end = pos;
return node;
};
/*
Look for an HTML attribute definition. Returns null if not found, otherwise returns {type: "attribute", name:, valueType: "string|indirect|macro", value:, start:, end:,}
*/
exports.parseAttribute = function(source,pos) {
var node = {
start: pos
};
// Define our regexps
var reAttributeName = /([^\/\s>"'=]+)/g,
reUnquotedAttribute = /([^\/\s<>"'=]+)/g,
reIndirectValue = /\{\{([^\}]+)\}\}/g;
// Skip whitespace
pos = this.skipWhiteSpace(source,pos);
// Get the attribute name
var name = this.parseTokenRegExp(source,pos,reAttributeName);
if(!name) {
return null;
}
node.name = name.match[1];
pos = name.end;
// Skip whitespace
pos = this.skipWhiteSpace(source,pos);
// Look for an equals sign
var token = this.parseTokenString(source,pos,"=");
if(token) {
pos = token.end;
// Skip whitespace
pos = this.skipWhiteSpace(source,pos);
// Look for a string literal
var stringLiteral = this.parseStringLiteral(source,pos);
if(stringLiteral) {
pos = stringLiteral.end;
node.type = "string";
node.value = stringLiteral.value;
} else {
// Look for an indirect value
var indirectValue = this.parseTokenRegExp(source,pos,reIndirectValue);
if(indirectValue) {
pos = indirectValue.end;
node.type = "indirect";
node.textReference = indirectValue.match[1];
} else {
// Look for a unquoted value
var unquotedValue = this.parseTokenRegExp(source,pos,reUnquotedAttribute);
if(unquotedValue) {
pos = unquotedValue.end;
node.type = "string";
node.value = unquotedValue.match[1];
} else {
// Look for a macro invocation value
var macroInvocation = this.parseMacroInvocation(source,pos);
if(macroInvocation) {
pos = macroInvocation.end;
node.type = "macro";
node.value = macroInvocation;
} else {
node.type = "string";
node.value = "true";
}
}
}
}
} else {
node.type = "string";
node.value = "true";
}
// Update the end position
node.end = pos;
return node;
};
/*
Look for an HTML tag. Returns null if not found, otherwise returns {type: "tag", name:, attributes: [], isSelfClosing:, start:, end:,}
*/
exports.parseTag = function(source,pos,options) {
options = options || {};
@@ -84,45 +321,45 @@ exports.parseTag = function(source,pos,options) {
// Define our regexps
var reTagName = /([a-zA-Z0-9\-\$]+)/g;
// Skip whitespace
pos = $tw.utils.skipWhiteSpace(source,pos);
pos = this.skipWhiteSpace(source,pos);
// Look for a less than sign
token = $tw.utils.parseTokenString(source,pos,"<");
token = this.parseTokenString(source,pos,"<");
if(!token) {
return null;
}
pos = token.end;
// Get the tag name
token = $tw.utils.parseTokenRegExp(source,pos,reTagName);
token = this.parseTokenRegExp(source,pos,reTagName);
if(!token) {
return null;
}
node.tag = token.match[1];
pos = token.end;
// Process attributes
var attribute = $tw.utils.parseAttribute(source,pos);
var attribute = this.parseAttribute(source,pos);
while(attribute) {
node.attributes[attribute.name] = attribute;
pos = attribute.end;
// Get the next attribute
attribute = $tw.utils.parseAttribute(source,pos);
attribute = this.parseAttribute(source,pos);
}
// Skip whitespace
pos = $tw.utils.skipWhiteSpace(source,pos);
pos = this.skipWhiteSpace(source,pos);
// Look for a closing slash
token = $tw.utils.parseTokenString(source,pos,"/");
token = this.parseTokenString(source,pos,"/");
if(token) {
pos = token.end;
node.isSelfClosing = true;
}
// Look for a greater than sign
token = $tw.utils.parseTokenString(source,pos,">");
token = this.parseTokenString(source,pos,">");
if(!token) {
return null;
}
pos = token.end;
// Check for a required line break
if(options.requireLineBreak) {
token = $tw.utils.parseTokenRegExp(source,pos,/([^\S\n]*\r?\n(?:[^\S\n]*\r?\n|$))/g);
token = this.parseTokenRegExp(source,pos,/(\r?\n(?:\r?\n|$))/g);
if(!token) {
return null;
}

View File

@@ -1,137 +0,0 @@
/*\
title: $:/core/modules/parsers/wikiparser/rules/image.js
type: application/javascript
module-type: wikirule
Wiki text inline rule for embedding images. For example:
```
[img[http://tiddlywiki.com/fractalveg.jpg]]
[img width=23 height=24 [http://tiddlywiki.com/fractalveg.jpg]]
[img 23x24 [http://tiddlywiki.com/fractalveg.jpg]]
[img width={{!!width}} height={{!!height}} [http://tiddlywiki.com/fractalveg.jpg]]
[img {{!!width}}x{{!!height}} [http://tiddlywiki.com/fractalveg.jpg]]
[img[Description of image|http://tiddlywiki.com/fractalveg.jpg]]
[img[TiddlerTitle]]
[img[Description of image|TiddlerTitle]]
```
Generates the `<$image>` widget.
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
exports.name = "image";
exports.types = {inline: true};
exports.init = function(parser) {
this.parser = parser;
};
exports.findNextMatch = function(startPos) {
// Find the next tag
this.nextImage = this.findNextImage(this.parser.source,startPos);
return this.nextImage ? this.nextImage.start : undefined;
};
exports.parse = function() {
// Move past the match
this.parser.pos = this.nextImage.end;
var node = {
type: "element",
tag: "$image",
attributes: this.nextImage.attributes
};
return [node];
};
/*
Find the next image from the current position
*/
exports.findNextImage = function(source,pos) {
// A regexp for finding candidate HTML tags
var reLookahead = /(\[img)/g;
// Find the next candidate
reLookahead.lastIndex = pos;
var match = reLookahead.exec(source);
while(match) {
// Try to parse the candidate as a tag
var tag = this.parseImage(source,match.index);
// Return success
if(tag) {
return tag;
}
// Look for the next match
reLookahead.lastIndex = match.index + 1;
match = reLookahead.exec(source);
}
// Failed
return null;
};
/*
Look for an image at the specified position. Returns null if not found, otherwise returns {type: "element", name: "$image", attributes: [], isSelfClosing:, start:, end:,}
*/
exports.parseImage = function(source,pos) {
var token,
node = {
type: "element",
name: "$image",
start: pos,
attributes: {}
};
// Skip whitespace
pos = $tw.utils.skipWhiteSpace(source,pos);
// Look for the `[img`
token = $tw.utils.parseTokenString(source,pos,"[img");
if(!token) {
return null;
}
pos = token.end;
// Skip whitespace
pos = $tw.utils.skipWhiteSpace(source,pos);
// Process attributes
if(source.charAt(pos) !== "[") {
var attribute = $tw.utils.parseAttribute(source,pos);
while(attribute) {
node.attributes[attribute.name] = attribute;
pos = attribute.end;
pos = $tw.utils.skipWhiteSpace(source,pos);
if(source.charAt(pos) !== "[") {
// Get the next attribute
attribute = $tw.utils.parseAttribute(source,pos);
} else {
attribute = null;
}
}
}
// Skip whitespace
pos = $tw.utils.skipWhiteSpace(source,pos);
// Look for the `[` after the attributes
token = $tw.utils.parseTokenString(source,pos,"[");
if(!token) {
return null;
}
pos = token.end;
// Skip whitespace
pos = $tw.utils.skipWhiteSpace(source,pos);
// Get the source up to the terminating `]]`
token = $tw.utils.parseTokenRegExp(source,pos,/(?:([^|\]]*?)\|)?([^\]]+?)\]\]/g);
if(!token) {
return null;
}
pos = token.end;
if(token.match[1]) {
node.attributes.tooltip = {type: "string", value: token.match[1].trim()};
}
node.attributes.source = {type: "string", value: (token.match[2] || "").trim()};
// Update the end position
node.end = pos;
return node;
};
})();

View File

@@ -28,7 +28,7 @@ exports.init = function(parser) {
};
var isLinkExternal = function(to) {
var externalRegExp = /(?:file|http|https|mailto|ftp|irc|news|data|skype):[^\s<>{}\[\]`|'"\\^~]+(?:\/|\b)/i;
var externalRegExp = /(?:file|http|https|mailto|ftp|irc|news|data|skype):[^\s'"]+(?:\/|\b)/i;
return externalRegExp.test(to);
};

View File

@@ -23,17 +23,19 @@ exports.types = {block: true};
exports.init = function(parser) {
this.parser = parser;
// Regexp to match
this.matchRegExp = /\{\{([^\{\}\|]*)(?:\|\|([^\|\{\}]+))?\}\}(?:\r?\n|$)/mg;
this.matchRegExp = /\{\{([^\{\}\|]+)(?:\|\|([^\|\{\}]+))?\}\}(?:\r?\n|$)/mg;
};
exports.parse = function() {
// Move past the match
this.parser.pos = this.matchRegExp.lastIndex;
// Move past the match
this.parser.pos = this.matchRegExp.lastIndex;
// Get the match details
var template = $tw.utils.trim(this.match[2]),
textRef = $tw.utils.trim(this.match[1]);
var textRef = $tw.utils.trim(this.match[1]),
tr = $tw.utils.parseTextReference(textRef),
targetTitle = tr.title,
targetField = tr.field,
targetIndex = tr.index,
template = $tw.utils.trim(this.match[2]);
// Prepare the transclude widget
var transcludeNode = {
type: "element",
@@ -41,43 +43,27 @@ exports.parse = function() {
attributes: {},
isBlock: true
};
// Prepare the tiddler widget
if(textRef) {
var tr = $tw.utils.parseTextReference(textRef),
targetTitle = tr.title,
targetField = tr.field,
targetIndex = tr.index,
tiddlerNode = {
type: "element",
tag: "$tiddler",
attributes: {
tiddler: {type: "string", value: targetTitle}
},
isBlock: true,
children: [transcludeNode]
};
}
var tiddlerNode = {
type: "element",
tag: "$tiddler",
attributes: {
tiddler: {type: "string", value: targetTitle}
},
isBlock: true,
children: [transcludeNode]
};
if(template) {
transcludeNode.attributes.tiddler = {type: "string", value: template};
if(textRef) {
return [tiddlerNode];
} else {
return [transcludeNode];
}
} else {
if(textRef) {
transcludeNode.attributes.tiddler = {type: "string", value: targetTitle};
if(targetField) {
transcludeNode.attributes.field = {type: "string", value: targetField};
}
if(targetIndex) {
transcludeNode.attributes.index = {type: "string", value: targetIndex};
}
return [tiddlerNode];
} else {
return [transcludeNode];
transcludeNode.attributes.tiddler = {type: "string", value: targetTitle};
if(targetField) {
transcludeNode.attributes.field = {type: "string", value: targetField};
}
if(targetIndex) {
transcludeNode.attributes.index = {type: "string", value: targetIndex};
}
}
return [tiddlerNode];
};
})();

View File

@@ -23,57 +23,45 @@ exports.types = {inline: true};
exports.init = function(parser) {
this.parser = parser;
// Regexp to match
this.matchRegExp = /\{\{([^\{\}\|]*)(?:\|\|([^\|\{\}]+))?\}\}/mg;
this.matchRegExp = /\{\{([^\{\}\|]+)(?:\|\|([^\|\{\}]+))?\}\}/mg;
};
exports.parse = function() {
// Move past the match
this.parser.pos = this.matchRegExp.lastIndex;
// Get the match details
var template = $tw.utils.trim(this.match[2]),
textRef = $tw.utils.trim(this.match[1]);
var textRef = $tw.utils.trim(this.match[1]),
tr = $tw.utils.parseTextReference(textRef),
targetTitle = tr.title,
targetField = tr.field,
targetIndex = tr.index,
template = $tw.utils.trim(this.match[2]);
// Prepare the transclude widget
var transcludeNode = {
type: "element",
tag: "$transclude",
attributes: {}
};
// Prepare the tiddler widget
if(textRef) {
var tr = $tw.utils.parseTextReference(textRef),
targetTitle = tr.title,
targetField = tr.field,
targetIndex = tr.index,
tiddlerNode = {
type: "element",
tag: "$tiddler",
attributes: {
tiddler: {type: "string", value: targetTitle}
},
children: [transcludeNode]
};
}
var tiddlerNode = {
type: "element",
tag: "$tiddler",
attributes: {
tiddler: {type: "string", value: targetTitle}
},
children: [transcludeNode]
};
if(template) {
transcludeNode.attributes.tiddler = {type: "string", value: template};
if(textRef) {
return [tiddlerNode];
} else {
return [transcludeNode];
}
} else {
if(textRef) {
transcludeNode.attributes.tiddler = {type: "string", value: targetTitle};
if(targetField) {
transcludeNode.attributes.field = {type: "string", value: targetField};
}
if(targetIndex) {
transcludeNode.attributes.index = {type: "string", value: targetIndex};
}
return [tiddlerNode];
} else {
return [transcludeNode];
transcludeNode.attributes.tiddler = {type: "string", value: targetTitle};
if(targetField) {
transcludeNode.attributes.field = {type: "string", value: targetField};
}
if(targetIndex) {
transcludeNode.attributes.index = {type: "string", value: targetIndex};
}
}
return [tiddlerNode];
};
})();

View File

@@ -62,9 +62,8 @@ PluginSwitcher.prototype.switchPlugins = function() {
var unregisteredTiddlers = $tw.wiki.unregisterPluginTiddlers(this.pluginType);
// Accumulate the titles of shadow tiddlers that have changed as a result of this switch
var changedTiddlers = {};
this.wiki.eachShadow(function(tiddler,title) {
var source = self.wiki.getShadowSource(title);
if(unregisteredTiddlers.indexOf(source) !== -1) {
$tw.utils.each(this.wiki.shadowTiddlers,function(shadowInfo,title) {
if(unregisteredTiddlers.indexOf(shadowInfo.source) !== -1) {
changedTiddlers[title] = true; // isDeleted?
}
});
@@ -73,9 +72,8 @@ PluginSwitcher.prototype.switchPlugins = function() {
// Unpack the current theme tiddlers
$tw.wiki.unpackPluginTiddlers();
// Accumulate the affected shadow tiddlers
this.wiki.eachShadow(function(tiddler,title) {
var source = self.wiki.getShadowSource(title);
if(registeredTiddlers.indexOf(source) !== -1) {
$tw.utils.each(this.wiki.shadowTiddlers,function(shadowInfo,title) {
if(registeredTiddlers.indexOf(shadowInfo.source) !== -1) {
changedTiddlers[title] = false; // isDeleted?
}
});

View File

@@ -19,27 +19,13 @@ TiddlyFoxSaver.prototype.save = function(text,method,callback) {
var messageBox = document.getElementById("tiddlyfox-message-box");
if(messageBox) {
// Get the pathname of this document
var pathname = document.location.toString();
// Replace file://localhost/ with file:///
if(pathname.indexOf("file://localhost/") == 0) {
pathname = "file://" + pathname.substr(16);
}
// Windows path file:///x:/blah/blah --> x:\blah\blah
if(/^file\:\/\/\/[A-Z]\:\//i.test(pathname)) {
// Remove the leading slash and convert slashes to backslashes
pathname = pathname.substr(8).replace(/\//g,"\\");
// Firefox Windows network path file://///server/share/blah/blah --> //server/share/blah/blah
} else if(pathname.indexOf("file://///") === 0) {
pathname = "\\\\" + unescape(pathname.substr(10)).replace(/\//g,"\\");
// Mac/Unix local path file:///path/path --> /path/path
} else if(pathname.indexOf("file:///") == 0) {
pathname = unescape(pathname.substr(7));
// Mac/Unix local path file:/path/path --> /path/path
} else if(pathname.indexOf("file:/") == 0) {
pathname = unescape(pathname.substr(5));
// Otherwise Windows networth path file://server/share/path/path --> \\server\share\path\path
} else {
pathname = "\\\\" + unescape(pathname.substr(7)).replace(new RegExp("/","g"),"\\");
var pathname = document.location.pathname;
// Test for a Windows path of the form /x:/blah/blah
if(/^\/[A-Z]\:\//i.test(pathname)) {
// Remove the leading slash
pathname = pathname.substr(1);
// Convert slashes to backslashes
pathname = pathname.replace(/\//g,"\\");
}
// Create the message element and put it in the message box
var message = document.createElement("div");

View File

@@ -12,12 +12,6 @@ This is the main application logic for both the client and server
/*global $tw: false */
"use strict";
// Set to `true` to enable performance instrumentation
var PERFORMANCE_INSTRUMENTATION = false;
// Time (in ms) that we defer refreshing changes to draft tiddlers
var DRAFT_TIDDLER_TIMEOUT = 400;
var widget = require("$:/core/modules/widgets/widget.js");
exports.startup = function() {
@@ -38,15 +32,14 @@ exports.startup = function() {
$tw.modules.applyMethods("wikimethod",$tw.Wiki.prototype);
$tw.modules.applyMethods("tiddlerdeserializer",$tw.Wiki.tiddlerDeserializerModules);
$tw.macros = $tw.modules.getModulesByTypeAsHashmap("macro");
// Set up the performance framework
$tw.perf = new $tw.Performance(PERFORMANCE_INSTRUMENTATION);
// Set up the parsers
$tw.wiki.initParsers();
// Set up the syncer object
$tw.syncer = new $tw.Syncer({wiki: $tw.wiki});
// Set up the command modules
$tw.Commander.initCommands();
// Kick off the language manager and switcher
$tw.language = new $tw.Language();
$tw.languageSwitcher = new $tw.PluginSwitcher({
// Kick off the language manager
$tw.languageManager = new $tw.PluginSwitcher({
wiki: $tw.wiki,
pluginType: "language",
controllerTitle: "$:/language",
@@ -64,31 +57,25 @@ exports.startup = function() {
"$:/themes/tiddlywiki/vanilla"
]
});
// Display the default tiddlers
var displayDefaultTiddlers = function() {
// Get the default tiddlers
var defaultTiddlersTitle = "$:/DefaultTiddlers",
defaultTiddlersTiddler = $tw.wiki.getTiddler(defaultTiddlersTitle),
defaultTiddlers = [];
if(defaultTiddlersTiddler) {
defaultTiddlers = $tw.wiki.filterTiddlers(defaultTiddlersTiddler.fields.text);
}
// Initialise the story
var storyTitle = "$:/StoryList",
story = [];
for(var t=0; t<defaultTiddlers.length; t++) {
story[t] = defaultTiddlers[t];
}
$tw.wiki.addTiddler({title: storyTitle, text: "", list: story},$tw.wiki.getModificationFields());
};
displayDefaultTiddlers();
// Set up the syncer object
$tw.syncer = new $tw.Syncer({wiki: $tw.wiki});
// Get the default tiddlers
var defaultTiddlersTitle = "$:/DefaultTiddlers",
defaultTiddlersTiddler = $tw.wiki.getTiddler(defaultTiddlersTitle),
defaultTiddlers = [];
if(defaultTiddlersTiddler) {
defaultTiddlers = $tw.wiki.filterTiddlers(defaultTiddlersTiddler.fields.text);
}
// Initialise the story and history
var storyTitle = "$:/StoryList",
story = [];
for(var t=0; t<defaultTiddlers.length; t++) {
story[t] = defaultTiddlers[t];
}
$tw.wiki.addTiddler({title: storyTitle, text: "", list: story},$tw.wiki.getModificationFields());
// Host-specific startup
if($tw.browser) {
// Set up our beforeunload handler
window.addEventListener("beforeunload",function(event) {
var confirmationMessage = undefined;
var confirmationMessage = null;
if($tw.syncer.isDirty()) {
confirmationMessage = "You have unsaved changes in TiddlyWiki";
event.returnValue = confirmationMessage; // Gecko
@@ -124,10 +111,6 @@ exports.startup = function() {
$tw.rootWidget.addEventListener("tw-scroll",function(event) {
$tw.pageScroller.handleEvent(event);
});
// Listen for the tw-home message
$tw.rootWidget.addEventListener("tw-home",function(event) {
displayDefaultTiddlers();
});
// Install the save action handlers
$tw.rootWidget.addEventListener("tw-save-wiki",function(event) {
$tw.syncer.saveWiki({
@@ -207,13 +190,22 @@ exports.startup = function() {
$tw.styleElement = document.createElement("style");
$tw.styleElement.innerHTML = $tw.styleContainer.textContent;
document.head.insertBefore($tw.styleElement,document.head.firstChild);
$tw.wiki.addEventListener("change",$tw.perf.report("styleRefresh",function(changes) {
$tw.wiki.addEventListener("change",function(changes) {
if($tw.styleWidgetNode.refresh(changes,$tw.styleContainer,null)) {
$tw.styleElement.innerHTML = $tw.styleContainer.textContent;
}
}));
// Display the $:/PageMacros tiddler to kick off the display
renderPage();
});
// Display the PageMacros, which includes the PageTemplate
var templateTitle = "$:/core/ui/PageMacros",
parser = $tw.wiki.parseTiddler(templateTitle);
$tw.pageWidgetNode = $tw.wiki.makeWidget(parser,{document: document, parentWidget: $tw.rootWidget});
$tw.pageContainer = document.createElement("div");
$tw.utils.addClass($tw.pageContainer,"tw-page-container");
document.body.insertBefore($tw.pageContainer,document.body.firstChild);
$tw.pageWidgetNode.render($tw.pageContainer,null);
$tw.wiki.addEventListener("change",function(changes) {
$tw.pageWidgetNode.refresh(changes,$tw.pageContainer,null);
});
// Fix up the link between the root widget and the page container
$tw.rootWidget.domNodes = [$tw.pageContainer];
$tw.rootWidget.children = [$tw.pageWidgetNode];
@@ -243,54 +235,7 @@ exports.startup = function() {
);
commander.execute();
}
};
/*
Main render function for PageMacros, which includes the PageTemplate
*/
function renderPage() {
// Parse and render the template
var templateTitle = "$:/core/ui/PageMacros",
parser = $tw.wiki.parseTiddler(templateTitle);
$tw.perf.report("mainRender",function() {
$tw.pageWidgetNode = $tw.wiki.makeWidget(parser,{document: document, parentWidget: $tw.rootWidget});
$tw.pageContainer = document.createElement("div");
$tw.utils.addClass($tw.pageContainer,"tw-page-container-wrapper");
document.body.insertBefore($tw.pageContainer,document.body.firstChild);
$tw.pageWidgetNode.render($tw.pageContainer,null);
})();
// Prepare refresh mechanism
var deferredChanges = Object.create(null),
timerId;
function refresh() {
// Process the refresh
$tw.pageWidgetNode.refresh(deferredChanges,$tw.pageContainer,null);
deferredChanges = Object.create(null);
}
// Add the change event handler
$tw.wiki.addEventListener("change",$tw.perf.report("mainRefresh",function(changes) {
// Check if only drafts have changed
var onlyDraftsHaveChanged = true;
for(var title in changes) {
var tiddler = $tw.wiki.getTiddler(title);
if(!tiddler || !tiddler.hasField("draft.of")) {
onlyDraftsHaveChanged = false;
}
}
// Defer the change if only drafts have changed
if(timerId) {
clearTimeout(timerId);
}
timerId = null;
if(onlyDraftsHaveChanged) {
timerId = setTimeout(refresh,DRAFT_TIDDLER_TIMEOUT);
$tw.utils.extend(deferredChanges,changes);
} else {
$tw.utils.extend(deferredChanges,changes);
refresh();
}
}));
}
})();

View File

@@ -25,7 +25,7 @@ var ZoominListView = function(listWidget) {
}
domNode.style.position = "absolute";
});
};
}
ZoominListView.prototype.navigateTo = function(historyInfo) {
var duration = $tw.utils.getAnimationDuration(),

View File

@@ -267,13 +267,8 @@ Synchronise a set of changes to the server
*/
Syncer.prototype.syncToServer = function(changes) {
var self = this,
now = Date.now(),
filteredChanges = this.filterFn.call(this.wiki,function(callback) {
$tw.utils.each(changes,function(change,title) {
var tiddler = self.wiki.getTiddler(title);
callback(tiddler,title);
});
});
now = new Date(),
filteredChanges = this.filterFn.call(this.wiki,changes);
$tw.utils.each(changes,function(change,title,object) {
// Process the change if it is a deletion of a tiddler we're already syncing, or is on the filtered change list
if((change.deleted && $tw.utils.hop(self.tiddlerInfo,title)) || filteredChanges.indexOf(title) !== -1) {
@@ -371,7 +366,7 @@ Queue up a sync task. If there is already a pending task for the tiddler, just u
*/
Syncer.prototype.enqueueSyncTask = function(task) {
var self = this,
now = Date.now();
now = new Date();
// Set the timestamps on this task
task.queueTime = now;
task.lastModificationTime = now;
@@ -474,7 +469,7 @@ Choose the next applicable task
Syncer.prototype.chooseNextTask = function() {
var self = this,
candidateTask = null,
now = Date.now();
now = new Date();
// Select the best candidate task
$tw.utils.each(this.taskQueue,function(task,title) {
// Exclude the task if there's one of the same name in progress
@@ -519,9 +514,6 @@ Syncer.prototype.dispatchTask = function(task,callback) {
// Invoke the callback
callback(null);
});
} else {
this.logger.log(" Not Dispatching 'save' task:",task.title,"tiddler does not exist");
return callback(null);
}
} else if(task.type === "load") {
// Load the tiddler

View File

@@ -55,20 +55,25 @@ Handle a scroll event hitting the page document
*/
PageScroller.prototype.scrollIntoView = function(element) {
var duration = $tw.utils.getAnimationDuration();
// Get the offset bounds of the element
var bounds = {
left: element.offsetLeft,
top: element.offsetTop,
width: element.offsetWidth,
height: element.offsetHeight
};
// Walk up the tree adjusting the offset bounds by each offsetParent
while(element.offsetParent) {
element = element.offsetParent;
bounds.left += element.offsetLeft;
bounds.top += element.offsetTop;
}
// Now get ready to scroll the body
this.cancelScroll();
this.startTime = Date.now();
var scrollPosition = $tw.utils.getScrollPosition();
// Get the client bounds of the element and adjust by the scroll position
var clientBounds = element.getBoundingClientRect(),
bounds = {
left: clientBounds.left + scrollPosition.x,
top: clientBounds.top + scrollPosition.y,
width: clientBounds.width,
height: clientBounds.height
};
// We'll consider the horizontal and vertical scroll directions separately via this function
var getEndPos = function(targetPos,targetSize,currentPos,currentSize) {
this.startTime = new Date();
var scrollPosition = $tw.utils.getScrollPosition(),
// We'll consider the horizontal and vertical scroll directions separately via this function
getEndPos = function(targetPos,targetSize,currentPos,currentSize) {
// If the target is above/left of the current view, then scroll to it's top/left
if(targetPos <= currentPos) {
return targetPos;
@@ -94,7 +99,7 @@ PageScroller.prototype.scrollIntoView = function(element) {
if(duration <= 0) {
t = 1;
} else {
t = ((Date.now()) - self.startTime) / duration;
t = ((new Date()) - self.startTime) / duration;
}
if(t >= 1) {
self.cancelScroll();

View File

@@ -219,7 +219,6 @@ var document = {
createTextNode: function(text) {
return new TW_TextNode(text);
},
isTiddlyWikiFakeDom: true
};
exports.fakeDocument = document;

View File

@@ -1,62 +0,0 @@
/*\
title: $:/core/modules/utils/performance.js
type: application/javascript
module-type: global
Performance measurement.
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
function Performance(enabled) {
this.enabled = !!enabled;
this.measures = {}; // Hashmap of current values of measurements
this.logger = new $tw.utils.Logger("performance");
}
/*
Wrap performance reporting around a top level function
*/
Performance.prototype.report = function(name,fn) {
var self = this;
if(this.enabled) {
return function() {
self.measures = {};
var startTime = $tw.utils.timer(),
result = fn.apply(this,arguments);
self.logger.log(name + ": " + $tw.utils.timer(startTime) + "ms");
for(var m in self.measures) {
self.logger.log("+" + m + ": " + self.measures[m] + "ms");
}
return result;
};
} else {
return fn;
}
};
/*
Wrap performance measurements around a subfunction
*/
Performance.prototype.measure = function(name,fn) {
var self = this;
if(this.enabled) {
return function() {
var startTime = $tw.utils.timer(),
result = fn.apply(this,arguments),
value = self.measures[name] || 0;
self.measures[name] = value + $tw.utils.timer(startTime);
return result;
};
} else {
return fn;
}
};
exports.Performance = Performance;
})();

View File

@@ -35,34 +35,21 @@ exports.count = function(object) {
/*
Push entries onto an array, removing them first if they already exist in the array
array: array to modify (assumed to be free of duplicates)
array: array to modify
value: a single value to push or an array of values to push
*/
exports.pushTop = function(array,value) {
var t,p;
if($tw.utils.isArray(value)) {
// Remove any array entries that are duplicated in the new values
if(value.length !== 0) {
if(array.length !== 0) {
if(value.length < array.length) {
for(t=0; t<value.length; t++) {
p = array.indexOf(value[t]);
if(p !== -1) {
array.splice(p,1);
}
}
} else {
for(t=array.length-1; t>=0; t--) {
p = value.indexOf(array[t]);
if(p !== -1) {
array.splice(t,1);
}
}
}
for(t=0; t<value.length; t++) {
p = array.indexOf(value[t]);
if(p !== -1) {
array.splice(p,1);
}
// Push the values on top of the main array
array.push.apply(array,value);
}
// Push the values on top of the main array
array.push.apply(array,value);
} else {
p = array.indexOf(value);
if(p !== -1) {
@@ -227,36 +214,32 @@ exports.getRelativeDate = function(delta) {
futurep = true;
}
var units = [
{name: "Years", duration: 365 * 24 * 60 * 60 * 1000},
{name: "Months", duration: (365/12) * 24 * 60 * 60 * 1000},
{name: "Days", duration: 24 * 60 * 60 * 1000},
{name: "Hours", duration: 60 * 60 * 1000},
{name: "Minutes", duration: 60 * 1000},
{name: "Seconds", duration: 1000}
{name: "years", duration: 365 * 24 * 60 * 60 * 1000},
{name: "months", duration: (365/12) * 24 * 60 * 60 * 1000},
{name: "days", duration: 24 * 60 * 60 * 1000},
{name: "hours", duration: 60 * 60 * 1000},
{name: "minutes", duration: 60 * 1000},
{name: "seconds", duration: 1000}
];
for(var t=0; t<units.length; t++) {
var result = Math.floor(delta / units[t].duration);
if(result >= 2) {
var desc = result + " " + units[t].name;
if(futurep) {
desc = desc + " from now";
} else {
desc = desc + " ago";
}
return {
delta: delta,
description: $tw.language.getString(
"RelativeDate/" + (futurep ? "Future" : "Past") + "/" + units[t].name,
{variables:
{period: result.toString()}
}
),
description: desc,
updatePeriod: units[t].duration
};
}
}
return {
delta: delta,
description: $tw.language.getString(
"RelativeDate/" + (futurep ? "Future" : "Past") + "/Second",
{variables:
{period: "1"}
}
),
description: "1 second ago",
updatePeriod: 1000
};
};
@@ -379,7 +362,7 @@ Returns an object with the following fields, all optional:
*/
exports.parseTextReference = function(textRef) {
// Separate out the title, field name and/or JSON indices
var reTextRef = /^\s*([^!#]+)?(?:(?:!!([^\s]+))|(?:##(.+)))?\s*/mg,
var reTextRef = /^\s*([^!#]+)?(?:(?:!!([^\s]+))|(?:##([^\s]+)))?\s*/mg,
match = reTextRef.exec(textRef);
if(match && reTextRef.lastIndex === textRef.length) {
// Return the parts
@@ -464,23 +447,4 @@ exports.makeTiddlerDictionary = function(data) {
return output.join("\n");
};
/*
High resolution microsecond timer for profiling
*/
exports.timer = function(base) {
var m;
if($tw.node) {
var r = process.hrtime();
m = r[0] * 1e3 + (r[1] / 1e6);
} else if(window.performance) {
m = performance.now();
} else {
m = Date.now();
}
if(typeof base !== "undefined") {
m = m - base;
}
return m;
}
})();

View File

@@ -54,7 +54,7 @@ ButtonWidget.prototype.render = function(parent,nextSibling) {
domNode.addEventListener("click",function (event) {
var handled = false;
if(self.to) {
self.navigateTo(event);
self.dispatchEvent({type: "tw-navigate", navigateTo: self.to, tiddlerTitle: self.getVariable("currentTiddler")});
handled = true;
}
if(self.message) {
@@ -92,19 +92,6 @@ ButtonWidget.prototype.isPoppedUp = function() {
return result;
};
ButtonWidget.prototype.navigateTo = function(event) {
var bounds = this.domNodes[0].getBoundingClientRect();
this.dispatchEvent({
type: "tw-navigate",
navigateTo: this.to,
navigateFromTitle: this.getVariable("storyTiddler"),
navigateFromNode: this,
navigateFromClientRect: { top: bounds.top, left: bounds.left, width: bounds.width, right: bounds.right, bottom: bounds.bottom, height: bounds.height
},
navigateSuppressNavigation: event.metaKey || event.ctrlKey || (event.button === 1)
});
};
ButtonWidget.prototype.dispatchMessage = function(event) {
this.dispatchEvent({type: this.message, param: this.param, tiddlerTitle: this.getVariable("currentTiddler")});
};
@@ -118,7 +105,8 @@ ButtonWidget.prototype.triggerPopup = function(event) {
};
ButtonWidget.prototype.setTiddler = function() {
this.wiki.setTextReference(this.set,this.setTo,this.getVariable("currentTiddler"));
var tiddler = this.wiki.getTiddler(this.set);
this.wiki.addTiddler(new $tw.Tiddler(tiddler,{title: this.set, text: this.setTo}));
};
/*

View File

@@ -54,7 +54,6 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
*/
CountWidget.prototype.refresh = function(changedTiddlers) {
// Re-execute the filter to get the count
this.computeAttributes();
var oldCount = this.currentCount;
this.execute();
if(this.currentCount !== oldCount) {

View File

@@ -147,11 +147,6 @@ DropZoneWidget.prototype.importDataTypes = [
};
}
}},
{type: "text/html", IECompatible: false, convertToFields: function(data) {
return {
text: data
};
}},
{type: "text/plain", IECompatible: false, convertToFields: function(data) {
return {
text: data

View File

@@ -30,13 +30,8 @@ ElementWidget.prototype.render = function(parent,nextSibling) {
this.parentDomNode = parent;
this.computeAttributes();
this.execute();
// Neuter blacklisted elements
var tag = this.parseTreeNode.tag;
if($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {
tag = "safe-" + tag;
}
var domNode = this.document.createElementNS(this.namespace,tag);
this.assignAttributes(domNode,{excludeEventAttributes: true});
var domNode = this.document.createElementNS(this.namespace,this.parseTreeNode.tag);
this.assignAttributes(domNode);
parent.insertBefore(domNode,nextSibling);
this.renderChildren(domNode,null);
this.domNodes.push(domNode);
@@ -70,7 +65,7 @@ ElementWidget.prototype.refresh = function(changedTiddlers) {
hasChangedAttributes = $tw.utils.count(changedAttributes) > 0;
if(hasChangedAttributes) {
// Update our attributes
this.assignAttributes(this.domNodes[0],{excludeEventAttributes: true});
this.assignAttributes(this.domNodes[0]);
}
return this.refreshChildren(changedTiddlers) || hasChangedAttributes;
};

View File

@@ -71,20 +71,10 @@ FieldManglerWidget.prototype.handleRemoveFieldEvent = function(event) {
};
FieldManglerWidget.prototype.handleAddFieldEvent = function(event) {
var tiddler = this.wiki.getTiddler(this.mangleTitle),
fieldValidatorRegEx = /^[a-z\-\._]+$/mg;
var tiddler = this.wiki.getTiddler(this.mangleTitle);
if(tiddler && typeof event.param === "string") {
var name = event.param.toLowerCase().trim();
var name = event.param.toLowerCase();
if(name !== "" && !$tw.utils.hop(tiddler.fields,name)) {
if(!fieldValidatorRegEx.test(name)) {
alert($tw.language.getString(
"InvalidFieldName",
{variables:
{fieldName: name}
}
));
return true;
}
var addition = this.wiki.getModificationFields();
addition[name] = "";
this.wiki.addTiddler(new $tw.Tiddler(tiddler,addition));
@@ -112,14 +102,11 @@ FieldManglerWidget.prototype.handleRemoveTagEvent = function(event) {
FieldManglerWidget.prototype.handleAddTagEvent = function(event) {
var tiddler = this.wiki.getTiddler(this.mangleTitle);
if(tiddler && typeof event.param === "string") {
var tag = event.param.trim();
if(tag !== "") {
var modification = this.wiki.getModificationFields();
modification.tags = (tiddler.fields.tags || []).slice(0);
$tw.utils.pushTop(modification.tags,tag);
this.wiki.addTiddler(new $tw.Tiddler(tiddler,modification));
}
if(tiddler && typeof event.param === "string" && event.param !== "") {
var modification = this.wiki.getModificationFields();
modification.tags = (tiddler.fields.tags || []).slice(0);
$tw.utils.pushTop(modification.tags,event.param);
this.wiki.addTiddler(new $tw.Tiddler(tiddler,modification));
}
return true;
};

View File

@@ -1,123 +0,0 @@
/*\
title: $:/core/modules/widgets/image.js
type: application/javascript
module-type: widget
The image widget displays an image referenced with an external URI or with a local tiddler title.
```
<$image src="TiddlerTitle" width="320" height="400" class="classnames">
```
The image source can be the title of an existing tiddler or the URL of an external image.
External images always generate an HTML `<img>` tag.
Tiddlers that have a _canonical_uri field generate an HTML `<img>` tag with the src attribute containing the URI.
Tiddlers that contain image data generate an HTML `<img>` tag with the src attribute containing a base64 representation of the image.
Tiddlers that contain wikitext could be rendered to a DIV of the usual size of a tiddler, and then transformed to the size requested.
The width and height attributes are interpreted as a number of pixels, and do not need to include the "px" suffix.
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var Widget = require("$:/core/modules/widgets/widget.js").widget;
var ImageWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options);
};
/*
Inherit from the base widget class
*/
ImageWidget.prototype = new Widget();
/*
Render this widget into the DOM
*/
ImageWidget.prototype.render = function(parent,nextSibling) {
this.parentDomNode = parent;
this.computeAttributes();
this.execute();
// Create element
// Determine what type of image it is
var tag = "img", src = "",
tiddler = this.wiki.getTiddler(this.imageSource);
if(!tiddler) {
// The source isn't the title of a tiddler, so we'll assume it's a URL
src = this.imageSource;
} else {
// Check if it is an image tiddler
if(this.wiki.isImageTiddler(this.imageSource)) {
// Render the appropriate element for the image type
var type = tiddler.fields.type,
text = tiddler.fields.text;
switch(type) {
case "application/pdf":
tag = "embed";
src = "data:application/pdf;base64," + text;
break;
case "image/svg+xml":
src = "data:image/svg+xml," + encodeURIComponent(text);
break;
default:
src = "data:" + type + ";base64," + text;
break;
}
}
}
// Create the element and assign the attributes
var domNode = this.document.createElement(tag);
domNode.setAttribute("src",src);
if(this.imageClass) {
domNode.setAttribute("class",this.imageClass);
}
if(this.imageWidth) {
domNode.setAttribute("width",parseInt(this.imageWidth,10) + "px");
}
if(this.imageHeight) {
domNode.setAttribute("height",parseInt(this.imageHeight,10) + "px");
}
if(this.imageTooltip) {
domNode.setAttribute("title",this.imageTooltip);
}
// Insert element
parent.insertBefore(domNode,nextSibling);
this.domNodes.push(domNode);
};
/*
Compute the internal state of the widget
*/
ImageWidget.prototype.execute = function() {
// Get our parameters
this.imageSource = this.getAttribute("source");
this.imageWidth = this.getAttribute("width");
this.imageHeight = this.getAttribute("height");
this.imageClass = this.getAttribute("class");
this.imageTooltip = this.getAttribute("tooltip");
};
/*
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/
ImageWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(changedAttributes.source || changedAttributes.width || changedAttributes.height || changedAttributes["class"] || changedAttributes.tooltip || changedTiddlers[this.imageSource]) {
this.refreshSelf();
return true;
} else {
return false;
}
};
exports.image = ImageWidget;
})();

View File

@@ -56,37 +56,23 @@ LinkWidget.prototype.renderLink = function(parent,nextSibling) {
// Create our element
var domNode = this.document.createElement("a");
// Assign classes
var classes = ["tw-tiddlylink"];
$tw.utils.addClass(domNode,"tw-tiddlylink");
if(this.isShadow) {
classes.push("tw-tiddlylink-shadow");
$tw.utils.addClass(domNode,"tw-tiddlylink-shadow");
}
if(this.isMissing && !this.isShadow) {
classes.push("tw-tiddlylink-missing");
$tw.utils.addClass(domNode,"tw-tiddlylink-missing");
} else {
if(!this.isMissing) {
classes.push("tw-tiddlylink-resolves");
$tw.utils.addClass(domNode,"tw-tiddlylink-resolves");
}
}
domNode.setAttribute("class",classes.join(" "));
// Set an href
var wikiLinkTemplateMacro = this.getVariable("tw-wikilink-template"),
wikiLinkTemplate = wikiLinkTemplateMacro ? wikiLinkTemplateMacro.trim() : "#$uri_encoded$",
wikiLinkText = wikiLinkTemplate.replace("$uri_encoded$",encodeURIComponent(this.to));
wikiLinkText = wikiLinkText.replace("$uri_doubleencoded$",encodeURIComponent(encodeURIComponent(this.to)));
domNode.setAttribute("href",wikiLinkText);
// Set the tooltip
// HACK: Performance issues with re-parsing the tooltip prevent us defaulting the tooltip to "<$transclude field='tooltip'><$transclude field='title'/></$transclude>"
var tooltipWikiText = this.tooltip || this.getVariable("tw-wikilink-tooltip");
if(tooltipWikiText) {
var tooltipText = this.wiki.renderText("text/plain","text/vnd.tiddlywiki",tooltipWikiText,{
parseAsInline: true,
variables: {
currentTiddler: this.to
},
parentWidget: this
});
domNode.setAttribute("title",tooltipText);
}
// Add a click event handler
$tw.utils.addEventListeners(domNode,[
{name: "click", handlerObject: this, handlerMethod: "handleClickEvent"},
@@ -109,7 +95,7 @@ LinkWidget.prototype.handleClickEvent = function (event) {
navigateFromNode: this,
navigateFromClientRect: { top: bounds.top, left: bounds.left, width: bounds.width, right: bounds.right, bottom: bounds.bottom, height: bounds.height
},
navigateSuppressNavigation: event.metaKey || event.ctrlKey || (event.button === 1)
navigateSuppressNavigation: event.metaKey || event.ctrlKey
});
event.preventDefault();
event.stopPropagation();
@@ -176,8 +162,6 @@ Compute the internal state of the widget
LinkWidget.prototype.execute = function() {
// Get the target tiddler title
this.to = this.getAttribute("to",this.getVariable("currentTiddler"));
// Get the link title
this.tooltip = this.getAttribute("tooltip");
// Determine the link characteristics
this.isMissing = !this.wiki.tiddlerExists(this.to);
this.isShadow = this.wiki.isShadowTiddler(this.to);
@@ -190,7 +174,7 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
*/
LinkWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(changedAttributes.to || changedTiddlers[this.to] || changedAttributes.tooltip) {
if(changedAttributes.to || changedTiddlers[this.to]) {
this.refreshSelf();
return true;
}

View File

@@ -69,11 +69,10 @@ LinkCatcherWidget.prototype.handleNavigateEvent = function(event) {
if(this.catchTo) {
this.wiki.setTextReference(this.catchTo,event.navigateTo,this.getVariable("currentTiddler"));
}
if(this.catchMessage && this.parentWidget) {
this.parentWidget.dispatchEvent({
if(this.catchMessage) {
this.dispatchEvent({
type: this.catchMessage,
param: event.navigateTo,
navigateTo: event.navigateTo
param: event.navigateTo
});
}
if(this.catchSet) {

View File

@@ -43,11 +43,7 @@ ListWidget.prototype.render = function(parent,nextSibling) {
this.renderChildren(parent,nextSibling);
// Construct the storyview
var StoryView = this.storyViews[this.storyViewName];
if(StoryView && !this.document.isTiddlyWikiFakeDom) {
this.storyview = new StoryView(this)
} else {
this.storyview = null;
}
this.storyview = StoryView ? new StoryView(this) : null;
};
/*

View File

@@ -26,7 +26,7 @@ var NavigatorWidget = function(parseTreeNode,options) {
{type: "tw-close-all-tiddlers", handler: "handleCloseAllTiddlersEvent"},
{type: "tw-close-other-tiddlers", handler: "handleCloseOtherTiddlersEvent"},
{type: "tw-new-tiddler", handler: "handleNewTiddlerEvent"},
{type: "tw-import-tiddlers", handler: "handleImportTiddlersEvent"}
{type: "tw-import-tiddlers", handler: "handleImportTiddlersEvent"},
]);
};
@@ -198,29 +198,15 @@ NavigatorWidget.prototype.handleDeleteTiddlerEvent = function(event) {
// Get the tiddler we're deleting
var title = event.param || event.tiddlerTitle,
tiddler = this.wiki.getTiddler(title),
storyList = this.getStoryList(),
originalTitle, confirmationTitle;
storyList = this.getStoryList();
// Check if the tiddler we're deleting is in draft mode
if(tiddler.hasField("draft.title")) {
// If so, we'll prompt for confirmation referencing the original tiddler
originalTitle = tiddler.fields["draft.of"];
confirmationTitle = originalTitle;
} else {
// If not a draft, then prompt for confirmation referencing the specified tiddler
originalTitle = null;
confirmationTitle = title;
}
// Seek confirmation
if(!confirm($tw.language.getString(
"ConfirmDeleteTiddler",
{variables:
{title: confirmationTitle}
}
))) {
return false;
}
// Delete the original tiddler
if(originalTitle) {
// Delete the original tiddler
var originalTitle = tiddler.fields["draft.of"];
// Ask for confirmation if the tiddler has changed
if(!confirm("Do you wish to delete the tiddler '" + originalTitle + "'")) {
return false;
}
this.wiki.deleteTiddler(originalTitle);
this.removeTitleFromStory(storyList,originalTitle);
}
@@ -291,12 +277,7 @@ NavigatorWidget.prototype.handleSaveTiddlerEvent = function(event) {
var isRename = draftOf !== draftTitle,
isConfirmed = true;
if(isRename && this.wiki.tiddlerExists(draftTitle)) {
isConfirmed = confirm($tw.language.getString(
"ConfirmOverwriteTiddler",
{variables:
{title: draftTitle}
}
));
isConfirmed = confirm("Do you wish to overwrite the tiddler '" + draftTitle + "'?");
}
if(isConfirmed) {
// Save the draft tiddler as the real tiddler
@@ -333,23 +314,11 @@ NavigatorWidget.prototype.handleCancelTiddlerEvent = function(event) {
originalTitle = draftTiddler.fields["draft.of"],
storyList = this.getStoryList();
if(draftTiddler && originalTitle) {
// Ask for confirmation if the tiddler text has changed
var isConfirmed = true;
if(this.wiki.getTiddlerText(draftTitle) !== this.wiki.getTiddlerText(originalTitle)) {
isConfirmed = confirm($tw.language.getString(
"ConfirmCancelTiddler",
{variables:
{title: draftTitle}
}
));
}
// Remove the draft tiddler
if(isConfirmed) {
this.wiki.deleteTiddler(draftTitle);
this.replaceFirstTitleInStory(storyList,draftTitle,originalTitle);
this.addToHistory(originalTitle,event.navigateFromClientRect);
this.saveStoryList(storyList);
}
this.wiki.deleteTiddler(draftTitle);
this.replaceFirstTitleInStory(storyList,draftTitle,originalTitle);
this.addToHistory(originalTitle,event.navigateFromClientRect);
this.saveStoryList(storyList);
}
return false;
};

View File

@@ -1,184 +0,0 @@
/*\
title: $:/core/modules/widgets/scrollable.js
type: application/javascript
module-type: widget
Scrollable widget
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var Widget = require("$:/core/modules/widgets/widget.js").widget;
var ScrollableWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options);
this.scaleFactor = 1;
this.addEventListeners([
{type: "tw-scroll", handler: "handleScrollEvent"}
]);
if($tw.browser) {
this.requestAnimationFrame = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function(callback) {
return window.setTimeout(callback, 1000/60);
};
this.cancelAnimationFrame = window.cancelAnimationFrame ||
window.webkitCancelAnimationFrame ||
window.webkitCancelRequestAnimationFrame ||
window.mozCancelAnimationFrame ||
window.mozCancelRequestAnimationFrame ||
function(id) {
window.clearTimeout(id);
};
}
};
/*
Inherit from the base widget class
*/
ScrollableWidget.prototype = new Widget();
ScrollableWidget.prototype.cancelScroll = function() {
if(this.idRequestFrame) {
this.cancelAnimationFrame.call(window,this.idRequestFrame);
this.idRequestFrame = null;
}
};
/*
Handle a scroll event
*/
ScrollableWidget.prototype.handleScrollEvent = function(event) {
// Pass the scroll event through if our offsetsize is larger than our scrollsize
if(this.outerDomNode.scrollWidth <= this.outerDomNode.offsetWidth && this.outerDomNode.scrollHeight <= this.outerDomNode.offsetHeight && this.fallthrough === "yes") {
return true;
}
this.scrollIntoView(event.target);
return false; // Handled event
};
/*
Scroll an element into view
*/
ScrollableWidget.prototype.scrollIntoView = function(element) {
var duration = $tw.utils.getAnimationDuration();
this.cancelScroll();
this.startTime = Date.now();
var scrollPosition = {
x: this.outerDomNode.scrollLeft,
y: this.outerDomNode.scrollTop
};
// Get the client bounds of the element and adjust by the scroll position
var scrollableBounds = this.outerDomNode.getBoundingClientRect(),
clientTargetBounds = element.getBoundingClientRect(),
bounds = {
left: clientTargetBounds.left + scrollPosition.x - scrollableBounds.left,
top: clientTargetBounds.top + scrollPosition.y - scrollableBounds.top,
width: clientTargetBounds.width,
height: clientTargetBounds.height
};
// We'll consider the horizontal and vertical scroll directions separately via this function
var getEndPos = function(targetPos,targetSize,currentPos,currentSize) {
// If the target is already visible then stay where we are
if(targetPos >= currentPos && (targetPos + targetSize) <= (currentPos + currentSize)) {
return currentPos;
// If the target is above/left of the current view, then scroll to its top/left
} else if(targetPos <= currentPos) {
return targetPos;
// If the target is smaller than the window and the scroll position is too far up, then scroll till the target is at the bottom of the window
} else if(targetSize < currentSize && currentPos < (targetPos + targetSize - currentSize)) {
return targetPos + targetSize - currentSize;
// If the target is big, then just scroll to the top
} else if(currentPos < targetPos) {
return targetPos;
// Otherwise, stay where we are
} else {
return currentPos;
}
},
endX = getEndPos(bounds.left,bounds.width,scrollPosition.x,this.outerDomNode.offsetWidth),
endY = getEndPos(bounds.top,bounds.height,scrollPosition.y,this.outerDomNode.offsetHeight);
// Only scroll if necessary
if(endX !== scrollPosition.x || endY !== scrollPosition.y) {
var self = this,
drawFrame;
drawFrame = function () {
var t;
if(duration <= 0) {
t = 1;
} else {
t = ((Date.now()) - self.startTime) / duration;
}
if(t >= 1) {
self.cancelScroll();
t = 1;
}
t = $tw.utils.slowInSlowOut(t);
self.outerDomNode.scrollLeft = scrollPosition.x + (endX - scrollPosition.x) * t;
self.outerDomNode.scrollTop = scrollPosition.y + (endY - scrollPosition.y) * t;
if(t < 1) {
self.idRequestFrame = self.requestAnimationFrame.call(window,drawFrame);
}
};
drawFrame();
}
};
/*
Render this widget into the DOM
*/
ScrollableWidget.prototype.render = function(parent,nextSibling) {
var self = this;
// Remember parent
this.parentDomNode = parent;
// Compute attributes and execute state
this.computeAttributes();
this.execute();
// Create elements
this.outerDomNode = this.document.createElement("div");
$tw.utils.setStyle(this.outerDomNode,[
{overflowY: "auto"},
{overflowX: "auto"},
{webkitOverflowScrolling: "touch"}
]);
this.innerDomNode = this.document.createElement("div");
this.outerDomNode.appendChild(this.innerDomNode);
// Assign classes
this.outerDomNode.className = this["class"] || "";
// Insert element
parent.insertBefore(this.outerDomNode,nextSibling);
this.renderChildren(this.innerDomNode,null);
this.domNodes.push(this.outerDomNode);
};
/*
Compute the internal state of the widget
*/
ScrollableWidget.prototype.execute = function() {
// Get attributes
this.fallthrough = this.getAttribute("fallthrough","yes");
this["class"] = this.getAttribute("class");
// Make child widgets
this.makeChildWidgets();
};
/*
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/
ScrollableWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(changedAttributes["class"]) {
this.refreshSelf();
return true;
}
return this.refreshChildren(changedTiddlers);
};
exports.scrollable = ScrollableWidget;
})();

Some files were not shown because too many files have changed in this diff Show More