mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-27 03:57:21 +00:00
Initial commit
This commit is contained in:
commit
f96708a846
15
cook.js
Normal file
15
cook.js
Normal file
@ -0,0 +1,15 @@
|
||||
// Cook a TiddlyWiki recipe and send it to STDOUT
|
||||
//
|
||||
// Usage: node cook.js <recipefile>
|
||||
|
||||
var sys = require("sys"),
|
||||
tiddlywiki = require("./js/TiddlyWiki.js"),
|
||||
recipe = require("./js/Recipe.js");
|
||||
|
||||
var filename = process.argv[2];
|
||||
|
||||
var store = new tiddlywiki.TiddlyWiki();
|
||||
|
||||
var theRecipe = new recipe.Recipe(store,filename);
|
||||
|
||||
console.log(theRecipe.cook());
|
90
js/ArgParser.js
Normal file
90
js/ArgParser.js
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
Parse a space-separated string of name:value parameters
|
||||
The parameters are returned in a structure that can be referenced like this:
|
||||
|
||||
(return).byName["name"][0] - First occurance of parameter with a given name
|
||||
(return).byPos[0].n - Name of parameter in first position
|
||||
(return).byPos[0].v - Value of parameter in first position
|
||||
|
||||
Options and their defaults are:
|
||||
|
||||
defaultName: null,
|
||||
defaultValue: null,
|
||||
noNames: false,
|
||||
cascadeDefaults: false
|
||||
|
||||
*/
|
||||
|
||||
var ArgParser = function(argString,options) {
|
||||
var parseToken = function(match,p) {
|
||||
var n;
|
||||
if(match[p]) // Double quoted
|
||||
n = match[p];
|
||||
else if(match[p+1]) // Single quoted
|
||||
n = match[p+1];
|
||||
else if(match[p+2]) // Double-square-bracket quoted
|
||||
n = match[p+2];
|
||||
else if(match[p+3]) // Double-brace quoted
|
||||
n = match[p+3];
|
||||
else if(match[p+4]) // Unquoted
|
||||
n = match[p+4];
|
||||
else if(match[p+5]) // empty quote
|
||||
n = "";
|
||||
return n;
|
||||
};
|
||||
this.byPos = [];
|
||||
var dblQuote = "(?:\"((?:(?:\\\\\")|[^\"])+)\")";
|
||||
var sngQuote = "(?:'((?:(?:\\\\\')|[^'])+)')";
|
||||
var dblSquare = "(?:\\[\\[((?:\\s|\\S)*?)\\]\\])";
|
||||
var dblBrace = "(?:\\{\\{((?:\\s|\\S)*?)\\}\\})";
|
||||
var unQuoted = options.noNames ? "([^\"'\\s]\\S*)" : "([^\"':\\s][^\\s:]*)";
|
||||
var emptyQuote = "((?:\"\")|(?:''))";
|
||||
var skipSpace = "(?:\\s*)";
|
||||
var token = "(?:" + dblQuote + "|" + sngQuote + "|" + dblSquare + "|" + dblBrace + "|" + unQuoted + "|" + emptyQuote + ")";
|
||||
var re = options.noNames ? new RegExp(token,"mg") : new RegExp(skipSpace + token + skipSpace + "(?:(\\:)" + skipSpace + token + ")?","mg");
|
||||
do {
|
||||
var match = re.exec(argString);
|
||||
if(match) {
|
||||
var n = parseToken(match,1);
|
||||
if(options.noNames) {
|
||||
this.byPos.push({n:"", v:n});
|
||||
} else {
|
||||
var v = parseToken(match,8);
|
||||
if(v === null && options.defaultName) {
|
||||
v = n;
|
||||
n = options.defaultName;
|
||||
} else if(v === null && options.defaultValue) {
|
||||
v = options.defaultValue;
|
||||
}
|
||||
this.byPos.push({n:n, v:v});
|
||||
if(options.cascadeDefaults) {
|
||||
options.defaultName = n;
|
||||
options.defaultValue = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while(match);
|
||||
this.byName = {};
|
||||
for(var t=0; t<this.byPos.length; t++) {
|
||||
var n = this.byPos[t].n;
|
||||
var v = this.byPos[t].v;
|
||||
if(n in this.byName)
|
||||
this.byName[n].push(v);
|
||||
else
|
||||
this.byName[n] = [v];
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve the first occurance of a named parameter, or the default if missing
|
||||
ArgParser.prototype.getValueByName = function(n,defaultValue) {
|
||||
var v = this.byName[n];
|
||||
return v && v.length > 0 ? v[0] : defaultValue;
|
||||
}
|
||||
|
||||
// Retrieve all the values of a named parameter as an array
|
||||
ArgParser.prototype.getValuesByName = function(n,defaultValue) {
|
||||
var v = this.byName[n];
|
||||
return v && v.length > 0 ? v : defaultValue;
|
||||
}
|
||||
|
||||
exports.ArgParser = ArgParser
|
205
js/Recipe.js
Normal file
205
js/Recipe.js
Normal file
@ -0,0 +1,205 @@
|
||||
/*
|
||||
|
||||
Recipe files consist of recipe lines consisting of a marker, a colon and the pathname of an ingredient:
|
||||
|
||||
marker: pathname
|
||||
|
||||
The pathname is interpreted relative to the directory containing the recipe file.
|
||||
|
||||
The special marker "recipe" is used to load a sub-recipe file.
|
||||
|
||||
The special marker "template" is used to identify the HTML template. The HTML template contains
|
||||
markers in two different forms:
|
||||
|
||||
<!--@@marker@@-->
|
||||
<!--@@marker@@-->
|
||||
|
||||
Recipe processing is in two parts. First the recipe file is parsed and the referenced files are loaded into tiddlers.
|
||||
Second, the template is processed by replacing the markers with the text of the tiddlers indicated in the recipe file.
|
||||
|
||||
The recipe is parsed into the 'ingredients' hashmap like this:
|
||||
|
||||
this.ingredients = {
|
||||
"marker1": [Tiddler1,Tiddler2,Tiddler3,...],
|
||||
"marker2": [TiddlerA,TiddlerB,TiddlerC,...],
|
||||
....
|
||||
};
|
||||
|
||||
*/
|
||||
|
||||
var tiddler = require("./Tiddler.js"),
|
||||
tiddlerUtils = require("./TiddlerUtils.js"),
|
||||
tiddlywiki = require("./TiddlyWiki.js"),
|
||||
fs = require("fs"),
|
||||
path = require("path"),
|
||||
util = require("util");
|
||||
|
||||
// Create a new Recipe object from the specified recipe file, storing the tiddlers in a specified TiddlyWiki store
|
||||
var Recipe = function(store,filepath) {
|
||||
this.store = store; // Save a reference to the store
|
||||
this.ingredients = {}; // Hashmap of array of ingredients
|
||||
this.readRecipe(filepath); // Read the recipe file
|
||||
}
|
||||
|
||||
// Specialised configuration and handlers for particular ingredient markers
|
||||
var specialMarkers = {
|
||||
shadow: {
|
||||
readIngredientPostProcess: function(fields) {
|
||||
// Add ".shadow" to the name of shadow tiddlers
|
||||
fields.title = fields.title + ".shadow";
|
||||
return fields;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Process the contents of a recipe file
|
||||
Recipe.prototype.readRecipe = function(filepath) {
|
||||
var dirname = path.dirname(filepath),
|
||||
me = this;
|
||||
fs.readFileSync(filepath,"utf8").split("\n").forEach(function(line) {
|
||||
var p = line.indexOf(":");
|
||||
if(p !== -1) {
|
||||
var marker = line.substr(0, p).trim(),
|
||||
value = line.substr(p+1).trim();
|
||||
if(marker === "recipe") {
|
||||
me.readRecipe(path.resolve(dirname,value));
|
||||
} else {
|
||||
var fields = me.readIngredient(dirname,value),
|
||||
postProcess = me.readIngredientPostProcess[marker];
|
||||
if(postProcess)
|
||||
fields = postProcess(fields);
|
||||
me.addIngredient(marker,fields);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Special post-processing required for certain ingredient types
|
||||
Recipe.prototype.readIngredientPostProcess = {
|
||||
"shadow": function(fields) {
|
||||
// Add ".shadow" to the name of shadow tiddlers
|
||||
fields.title = fields.title + ".shadow";
|
||||
return fields;
|
||||
}
|
||||
};
|
||||
|
||||
Recipe.prototype.addIngredient = function(marker,tiddlerFields) {
|
||||
var ingredientTiddler = new tiddler.Tiddler(tiddlerFields);
|
||||
this.store.addTiddler(ingredientTiddler);
|
||||
if(marker in this.ingredients) {
|
||||
this.ingredients[marker].push(ingredientTiddler);
|
||||
} else {
|
||||
this.ingredients[marker] = [ingredientTiddler];
|
||||
}
|
||||
}
|
||||
|
||||
// Read an ingredient file and return it as a hashmap of tiddler fields. Also read the .meta file, if present
|
||||
Recipe.prototype.readIngredient = function(dirname,filepath) {
|
||||
var fullpath = path.resolve(dirname,filepath),
|
||||
extname = path.extname(filepath),
|
||||
basename = path.basename(filepath,extname),
|
||||
fields = {
|
||||
title: basename
|
||||
};
|
||||
// Read the tiddler file
|
||||
fields = tiddlerUtils.parseTiddler(fs.readFileSync(fullpath,"utf8"),extname,fields);
|
||||
// Check for the .meta file
|
||||
var metafile = fullpath + ".meta";
|
||||
if(path.existsSync(metafile)) {
|
||||
fields = tiddlerUtils.parseMetaDataBlock(fs.readFileSync(metafile,"utf8"),fields);
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
// Return a string of the cooked recipe
|
||||
Recipe.prototype.cook = function() {
|
||||
var template = this.ingredients.template ? this.ingredients.template[0].fields.text : "";
|
||||
var out = [];
|
||||
var me = this;
|
||||
template.split("\n").forEach(function(line) {
|
||||
var templateRegExp = /^(?:<!--@@(.*)@@-->)|(?:<!--@@(.*)@@-->)$/gi;
|
||||
var match = templateRegExp.exec(line);
|
||||
if(match) {
|
||||
var marker = match[1] === undefined ? match[2] : match[1];
|
||||
me.outputIngredient(out,marker);
|
||||
} else {
|
||||
out.push(line);
|
||||
}
|
||||
});
|
||||
// out.push("\nRecipe:\n" + util.inspect(this.ingredients,false,4));
|
||||
return out.join("\n");
|
||||
}
|
||||
|
||||
// Output all the tiddlers in the recipe with a particular marker
|
||||
Recipe.prototype.outputIngredient = function(out,marker) {
|
||||
var ingredient = this.ingredients[marker];
|
||||
var outputType = Recipe.ingredientOutputMapper[marker] || "raw";
|
||||
var outputter = Recipe.ingredientOutputter[outputType];
|
||||
if(outputter && ingredient) {
|
||||
outputter(out,ingredient);
|
||||
}
|
||||
}
|
||||
|
||||
// Allows for specialised processing for certain markers
|
||||
Recipe.ingredientOutputMapper = {
|
||||
tiddler: "div",
|
||||
js: "javascript",
|
||||
jsdeprecated: "javascript",
|
||||
jquery: "javascript",
|
||||
shadow: "shadow"
|
||||
};
|
||||
|
||||
Recipe.ingredientOutputter = {
|
||||
raw: function(out,ingredient) {
|
||||
// The default is just to output the raw text of the tiddler, ignoring any metadata
|
||||
for(var t=0; t<ingredient.length; t++) {
|
||||
var tid = ingredient[t];
|
||||
// For compatibility with cook.rb, remove one trailing \n from tiddler
|
||||
var text = tid.fields.text;
|
||||
text = text.charAt(text.length-1) === "\n" ? text.substr(0,text.length-1) : text;
|
||||
out.push(text);
|
||||
}
|
||||
},
|
||||
div: function(out,ingredient) {
|
||||
// Ordinary tiddlers are output as a <DIV>
|
||||
for(var t=0; t<ingredient.length; t++) {
|
||||
var tid = ingredient[t];
|
||||
tiddlerUtils.outputTiddlerDiv(out,tid);
|
||||
}
|
||||
},
|
||||
javascript: function(out,ingredient) {
|
||||
// Lines starting with //# are removed from javascript tiddlers
|
||||
for(var t=0; t<ingredient.length; t++) {
|
||||
var tid = ingredient[t];
|
||||
var text = tid.fields.text;
|
||||
// For compatibility with cook.rb, remove one trailing \n from tiddler
|
||||
text = text.charAt(text.length-1) === "\n" ? text.substr(0,text.length-1) : text;
|
||||
var lines = text.split("\n");
|
||||
for(var line=0; line<lines.length; line++) {
|
||||
var commentRegExp = /^\s*\/\/#/gi;
|
||||
if(!commentRegExp.test(lines[line])) {
|
||||
out.push(lines[line]);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
shadow: function(out,ingredient) {
|
||||
// Shadows are output as a <DIV> with the the ".shadow" suffix removed from the title
|
||||
for(var t=0; t<ingredient.length; t++) {
|
||||
var tid = ingredient[t];
|
||||
var title = tid.fields.title;
|
||||
var tweakedTiddler;
|
||||
if(title.indexOf(".shadow") === title.length - 7) {
|
||||
tweakedTiddler = new tiddler.Tiddler(tid,{
|
||||
title: title.substr(0, title.length-7)
|
||||
});
|
||||
} else {
|
||||
tweakedTiddler = tid;
|
||||
}
|
||||
tiddlerUtils.outputTiddlerDiv(out,tweakedTiddler,{omitPrecedingLineFeed: true});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports.Recipe = Recipe;
|
||||
|
34
js/Tiddler.js
Normal file
34
js/Tiddler.js
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
|
||||
Tiddlers are an immutable dictionary of name:value pairs called fields. Values can be a string, an array
|
||||
of strings, or a date.
|
||||
|
||||
Hardcoded in the system is the knowledge that the 'tags' field is a string array, and that the 'modified'
|
||||
and 'created' fields are dates. All other fields are strings.
|
||||
|
||||
The Tiddler object exposes the following API
|
||||
|
||||
new Tiddler(fields) - create a Tiddler given a hashmap of field values
|
||||
new Tiddler(tiddler,fields) - create a Tiddler from an existing tiddler with a hashmap of modified field values
|
||||
Tiddler.fields - hashmap of tiddler fields
|
||||
|
||||
*/
|
||||
|
||||
var Tiddler = function(/* tiddler,fields */) {
|
||||
var tiddler, fields, c = 0, t;
|
||||
if(arguments[c] instanceof Tiddler) {
|
||||
tiddler = arguments[c++];
|
||||
}
|
||||
fields = arguments[c++];
|
||||
this.fields = {};
|
||||
if(tiddler instanceof Tiddler) {
|
||||
for(t in tiddler.fields) {
|
||||
this.fields[t] = tiddler.fields[t]; // Should copy arrays by value
|
||||
}
|
||||
}
|
||||
for(t in fields) {
|
||||
this.fields[t] = fields[t]; // Should copy arrays by value
|
||||
}
|
||||
}
|
||||
|
||||
exports.Tiddler = Tiddler;
|
274
js/TiddlerUtils.js
Normal file
274
js/TiddlerUtils.js
Normal file
@ -0,0 +1,274 @@
|
||||
/*
|
||||
Various static utility functions concerned with parsing and generating representations of tiddlers and
|
||||
other objects.
|
||||
|
||||
This file is a bit of a dumping ground; the expectation is that most of these functions will be refactored.
|
||||
*/
|
||||
|
||||
var argParser = require("./ArgParser.js");
|
||||
|
||||
var tiddlerUtils = exports;
|
||||
|
||||
/*
|
||||
Parse a tiddler given its mimetype, and merge the results into a hashmap of tiddler fields.
|
||||
|
||||
A file extension can be passed as a shortcut for the mimetype, as shown in tiddlerUtils.fileExtensionMappings.
|
||||
For example ".txt" file extension is mapped to the "text/plain" mimetype.
|
||||
|
||||
Special processing to extract embedded metadata is applied to some mimetypes.
|
||||
*/
|
||||
|
||||
tiddlerUtils.parseTiddler = function(text,type,fields) {
|
||||
if(fields === undefined) {
|
||||
var fields = {};
|
||||
}
|
||||
// Map extensions to mimetpyes
|
||||
var fileExtensionMapping = tiddlerUtils.fileExtensionMappings[type];
|
||||
if(fileExtensionMapping)
|
||||
type = fileExtensionMapping;
|
||||
// Invoke the parser for the specified mimetype
|
||||
var parser = tiddlerUtils.parseTiddlerByMimeType[type];
|
||||
if(parser) {
|
||||
return parser(text,fields);
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
tiddlerUtils.fileExtensionMappings = {
|
||||
".txt": "text/plain",
|
||||
".html": "text/html",
|
||||
".tiddler": "application/x-tiddler-html-div",
|
||||
".tid": "application/x-tiddler",
|
||||
".js": "application/javascript"
|
||||
}
|
||||
|
||||
tiddlerUtils.parseTiddlerByMimeType = {
|
||||
"text/plain": function(text,fields) {
|
||||
fields.text = text;
|
||||
return fields;
|
||||
},
|
||||
"text/html": function(text,fields) {
|
||||
fields.text = text;
|
||||
return fields;
|
||||
},
|
||||
"application/x-tiddler-html-div": function(text,fields) {
|
||||
fields = tiddlerUtils.parseTiddlerDiv(text,fields);
|
||||
return fields;
|
||||
},
|
||||
"application/x-tiddler": function(text,fields) {
|
||||
var split = text.indexOf("\n\n");
|
||||
if(split === -1) {
|
||||
split = text.length;
|
||||
}
|
||||
fields = tiddlerUtils.parseMetaDataBlock(text.substr(0,split),fields);
|
||||
fields.text = text.substr(split + 2);
|
||||
return fields;
|
||||
},
|
||||
"application/javascript": function(text,fields) {
|
||||
fields.text = text;
|
||||
return fields;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Parse a block of metadata and merge the results into a hashmap of tiddler fields.
|
||||
|
||||
The block consists of newline delimited lines consisting of the field name, a colon, and then the value. For example:
|
||||
|
||||
title: Safari
|
||||
modifier: blaine
|
||||
created: 20110211110700
|
||||
modified: 20110211131020
|
||||
tags: browsers issues
|
||||
creator: psd
|
||||
*/
|
||||
tiddlerUtils.parseMetaDataBlock = function(metaData,fields) {
|
||||
if(fields === undefined) {
|
||||
var fields = {};
|
||||
}
|
||||
metaData.split("\n").forEach(function(line) {
|
||||
var p = line.indexOf(":");
|
||||
if(p !== -1) {
|
||||
var field = line.substr(0, p).trim();
|
||||
var value = line.substr(p+1).trim();
|
||||
fields[field] = tiddlerUtils.parseMetaDataItem(field,value);
|
||||
}
|
||||
});
|
||||
return fields;
|
||||
}
|
||||
|
||||
/*
|
||||
Parse an old-style tiddler DIV. It looks like this:
|
||||
|
||||
<div title="Title" creator="JoeBloggs" modifier="JoeBloggs" created="201102111106" modified="201102111310" tags="myTag [[my long tag]]">
|
||||
<pre>The text of the tiddler (without the expected HTML encoding).
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
Note that the field attributes are HTML encoded, but that the body of the <PRE> tag is not.
|
||||
*/
|
||||
tiddlerUtils.parseTiddlerDiv = function(text,fields) {
|
||||
if(fields === undefined) {
|
||||
var fields = {};
|
||||
}
|
||||
var divRegExp = /^\s*<div\s+([^>]*)>((?:.|\n)*)<\/div>\s*$/gi;
|
||||
var subDivRegExp = /^(?:\s*<pre>)((?:.|\n)*)(?:<\/pre>\s*)$/gi;
|
||||
var attrRegExp = /\s*([^=\s]+)\s*=\s*"([^"]*)"/gi;
|
||||
var match = divRegExp.exec(text);
|
||||
if(match) {
|
||||
var subMatch = subDivRegExp.exec(match[2]); // Body of the <DIV> tag
|
||||
if(subMatch) {
|
||||
fields.text = subMatch[1];
|
||||
} else {
|
||||
fields.text = match[2];
|
||||
}
|
||||
do {
|
||||
var attrMatch = attrRegExp.exec(match[1]);
|
||||
if(attrMatch) {
|
||||
var name = attrMatch[1];
|
||||
var value = attrMatch[2];
|
||||
fields[name] = tiddlerUtils.parseMetaDataItem(name,value);
|
||||
}
|
||||
} while(attrMatch);
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
// Output a tiddler as an HTML <DIV>
|
||||
// out - array to push the output strings
|
||||
// tid - the tiddler to be output
|
||||
// options - options:
|
||||
// omitPrecedingLineFeed - determines if a linefeed is inserted between the <PRE> tag and the text
|
||||
tiddlerUtils.outputTiddlerDiv = function(out,tid,options) {
|
||||
var result = [];
|
||||
var outputAttribute = function(name,value) {
|
||||
result.push(" " + name + "=\"" + value + "\"");
|
||||
};
|
||||
result.push("<div");
|
||||
for(var t in tid.fields) {
|
||||
switch(t) {
|
||||
case "text":
|
||||
// Ignore the text field
|
||||
break;
|
||||
case "tags":
|
||||
// Output tags as a list
|
||||
outputAttribute(t,tiddlerUtils.stringifyTags(tid.fields.tags));
|
||||
break;
|
||||
case "modified":
|
||||
case "created":
|
||||
// Output dates in YYYYMMDDHHMMSS
|
||||
outputAttribute(t,tiddlerUtils.convertToYYYYMMDDHHMM(tid.fields[t]));
|
||||
break;
|
||||
default:
|
||||
// Output other attributes raw
|
||||
outputAttribute(t,tid.fields[t]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
result.push(">\n<pre>");
|
||||
if(!(options && options.omitPrecedingLineFeed))
|
||||
result.push("\n");
|
||||
result.push(tiddlerUtils.htmlEncode(tid.fields.text));
|
||||
result.push("</pre>\n</div>");
|
||||
out.push(result.join(""));
|
||||
}
|
||||
|
||||
tiddlerUtils.stringifyTags = function(tags) {
|
||||
var results = [];
|
||||
for(var t=0; t<tags.length; t++) {
|
||||
if(tags[t].indexOf(" ") !== -1) {
|
||||
results.push("[[" + tags[t] + "]]");
|
||||
} else {
|
||||
results.push(tags[t]);
|
||||
}
|
||||
}
|
||||
return results.join(" ");
|
||||
}
|
||||
|
||||
/*
|
||||
Parse a single metadata field/value pair and return the value as the appropriate data type
|
||||
*/
|
||||
tiddlerUtils.parseMetaDataItem = function(field,value) {
|
||||
var result;
|
||||
switch(field) {
|
||||
case "modified":
|
||||
case "created":
|
||||
result = tiddlerUtils.convertFromYYYYMMDDHHMMSS(value);
|
||||
break;
|
||||
case "tags":
|
||||
var parser = new argParser.ArgParser(value,{noNames: true});
|
||||
result = parser.getValuesByName("","");
|
||||
break;
|
||||
default:
|
||||
result = value;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Pad a string to a certain length with zeros
|
||||
tiddlerUtils.zeroPad = function(n,d)
|
||||
{
|
||||
var s = n.toString();
|
||||
if(s.length < d)
|
||||
s = "000000000000000000000000000".substr(0,d-s.length) + s;
|
||||
return s;
|
||||
};
|
||||
|
||||
// Convert a date to local YYYYMMDDHHMM string format
|
||||
tiddlerUtils.convertToLocalYYYYMMDDHHMM = function(date)
|
||||
{
|
||||
return date.getFullYear() + tiddlerUtils.zeroPad(date.getMonth()+1,2) + tiddlerUtils.zeroPad(date.getDate(),2) + tiddlerUtils.zeroPad(date.getHours(),2) + tiddlerUtils.zeroPad(date.getMinutes(),2);
|
||||
};
|
||||
|
||||
// Convert a date to UTC YYYYMMDDHHMM string format
|
||||
tiddlerUtils.convertToYYYYMMDDHHMM = function(date)
|
||||
{
|
||||
return date.getUTCFullYear() + tiddlerUtils.zeroPad(date.getUTCMonth()+1,2) + tiddlerUtils.zeroPad(date.getUTCDate(),2) + tiddlerUtils.zeroPad(date.getUTCHours(),2) + tiddlerUtils.zeroPad(date.getUTCMinutes(),2);
|
||||
};
|
||||
|
||||
// Convert a date to UTC YYYYMMDD.HHMMSSMMM string format
|
||||
tiddlerUtils.convertToYYYYMMDDHHMMSSMMM = function(date)
|
||||
{
|
||||
return date.getUTCFullYear() + tiddlerUtils.zeroPad(date.getUTCMonth()+1,2) + tiddlerUtils.zeroPad(date.getUTCDate(),2) + "." + tiddlerUtils.zeroPad(date.getUTCHours(),2) + tiddlerUtils.zeroPad(date.getUTCMinutes(),2) + tiddlerUtils.zeroPad(date.getUTCSeconds(),2) + tiddlerUtils.zeroPad(date.getUTCMilliseconds(),3) +"0";
|
||||
};
|
||||
|
||||
// Create a date from a UTC YYYYMMDDHHMM format string
|
||||
tiddlerUtils.convertFromYYYYMMDDHHMM = function(d)
|
||||
{
|
||||
d = d?d.replace(/[^0-9]/g, ""):"";
|
||||
return tiddlerUtils.convertFromYYYYMMDDHHMMSSMMM(d.substr(0,12));
|
||||
};
|
||||
|
||||
// Create a date from a UTC YYYYMMDDHHMMSS format string
|
||||
tiddlerUtils.convertFromYYYYMMDDHHMMSS = function(d)
|
||||
{
|
||||
d = d?d.replace(/[^0-9]/g, ""):"";
|
||||
return tiddlerUtils.convertFromYYYYMMDDHHMMSSMMM(d.substr(0,14));
|
||||
};
|
||||
|
||||
// Create a date from a UTC YYYYMMDDHHMMSSMMM format string
|
||||
tiddlerUtils.convertFromYYYYMMDDHHMMSSMMM = function(d)
|
||||
{
|
||||
d = d ? d.replace(/[^0-9]/g, "") : "";
|
||||
return new Date(Date.UTC(parseInt(d.substr(0,4),10),
|
||||
parseInt(d.substr(4,2),10)-1,
|
||||
parseInt(d.substr(6,2),10),
|
||||
parseInt(d.substr(8,2)||"00",10),
|
||||
parseInt(d.substr(10,2)||"00",10),
|
||||
parseInt(d.substr(12,2)||"00",10),
|
||||
parseInt(d.substr(14,3)||"000",10)));
|
||||
};
|
||||
|
||||
// Convert & to "&", < to "<", > to ">" and " to """
|
||||
tiddlerUtils.htmlEncode = function(s)
|
||||
{
|
||||
return s.replace(/&/mg,"&").replace(/</mg,"<").replace(/>/mg,">").replace(/\"/mg,""");
|
||||
};
|
||||
|
||||
// Convert "&" to &, "<" to <, ">" to > and """ to "
|
||||
tiddlerUtils.htmlDecode = function(s)
|
||||
{
|
||||
return s.replace(/</mg,"<").replace(/>/mg,">").replace(/"/mg,"\"").replace(/&/mg,"&");
|
||||
};
|
||||
|
33
js/TiddlyWiki.js
Normal file
33
js/TiddlyWiki.js
Normal file
@ -0,0 +1,33 @@
|
||||
var tiddler = require("./Tiddler.js");
|
||||
|
||||
var TiddlyWiki = function() {
|
||||
this.tiddlers = {};
|
||||
};
|
||||
|
||||
TiddlyWiki.prototype.clear = function() {
|
||||
this.tiddlers = {};
|
||||
}
|
||||
|
||||
TiddlyWiki.prototype.fetchTiddler = function(title) {
|
||||
var t = this.tiddlers[title];
|
||||
return t instanceof tiddler.Tiddler ? t : null;
|
||||
}
|
||||
|
||||
TiddlyWiki.prototype.deleteTiddler = function(title) {
|
||||
delete this.tiddlers[title];
|
||||
}
|
||||
|
||||
TiddlyWiki.prototype.addTiddler = function(tiddler) {
|
||||
this.tiddlers[tiddler.title] = tiddler;
|
||||
}
|
||||
|
||||
TiddlyWiki.prototype.forEachTiddler = function(callback) {
|
||||
var t;
|
||||
for(t in this.tiddlers) {
|
||||
var tiddler = this.tiddlers[t];
|
||||
if(tiddler instanceof tiddler.Tiddler)
|
||||
callback.call(this,t,tiddler);
|
||||
}
|
||||
}
|
||||
|
||||
exports.TiddlyWiki = TiddlyWiki
|
21
readme.md
Normal file
21
readme.md
Normal file
@ -0,0 +1,21 @@
|
||||
# cook.js
|
||||
|
||||
This is an attempt to modernise TiddlyWiki's build system, which is based on tools written in Ruby called Cook and Ginsu (see https://github.com/TiddlyWiki/cooker for details). This new version is written in JavaScript for node.js, with the intention that it can share code with TiddlyWiki itself.
|
||||
|
||||
## Usage
|
||||
|
||||
node cook.js <recipefile>
|
||||
|
||||
Cooks a recipe file and sends the output to STDOUT
|
||||
|
||||
node server.js <recipefile>
|
||||
|
||||
Cooks a recipe file and serves it over HTTP port 8000
|
||||
|
||||
## Testing
|
||||
|
||||
`test.sh` contains a simple test that cooks the main tiddlywiki.com recipe, first with the old Ruby-based tool, and then the new one. It uses OS X's opendiff to display the differences between the two files.
|
||||
|
||||
## Current status
|
||||
|
||||
As of 22nd November 2011, cook.js can now build a fully functional TiddlyWiki from the existing recipe files. There are still some minor differences in the layout of tiddler attributes, and some whitespace issues that prevent full byte-for-byte compatibility.
|
22
server.js
Normal file
22
server.js
Normal file
@ -0,0 +1,22 @@
|
||||
// Cook a TiddlyWiki recipe and serve the result over HTTP
|
||||
//
|
||||
// Usage: node server.js <recipefile>
|
||||
|
||||
var tiddlywiki = require("./js/TiddlyWiki.js"),
|
||||
recipe = require("./js/Recipe.js"),
|
||||
sys = require("sys"),
|
||||
http = require("http"),
|
||||
fs = require("fs"),
|
||||
url = require("url"),
|
||||
path = require("path");
|
||||
|
||||
var filename = process.argv[2];
|
||||
|
||||
http.createServer(function (request, response) {
|
||||
response.writeHead(200, {"Content-Type": "text/html"});
|
||||
var store = new tiddlywiki.TiddlyWiki();
|
||||
var theRecipe = new recipe.Recipe(store,filename);
|
||||
response.end(theRecipe.cook(), "utf-8");
|
||||
}).listen(8000);
|
||||
|
||||
sys.puts("Server running at http://127.0.0.1:8000/");
|
10
test.sh
Executable file
10
test.sh
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
# cook the recipe with the old cook.rb (assuming you have set it up as described in github.com/TiddlyWiki/cooker)
|
||||
cook $PWD/test/data/tiddlywiki.com/index.html.recipe -d $PWD -o oldcooked.html
|
||||
|
||||
# cook it with cook.js
|
||||
node cook.js $PWD/test/data/tiddlywiki.com/index.html.recipe > newcooked.html
|
||||
|
||||
# compare the two
|
||||
opendiff oldcooked.html newcooked.html
|
BIN
test/data/.DS_Store
vendored
Normal file
BIN
test/data/.DS_Store
vendored
Normal file
Binary file not shown.
3
test/data/samples/tiddlers/Test1.tiddler
Executable file
3
test/data/samples/tiddlers/Test1.tiddler
Executable file
@ -0,0 +1,3 @@
|
||||
<div title="Test1">
|
||||
<pre>This is a testing tiddler.</pre>
|
||||
</div>
|
3
test/data/samples/tiddlers/TestContainsTag.tiddler
Executable file
3
test/data/samples/tiddlers/TestContainsTag.tiddler
Executable file
@ -0,0 +1,3 @@
|
||||
<div title="TestContainsTag">
|
||||
<pre>This is a testing tiddler with </pre></div> in it.</pre>
|
||||
</div>
|
1
test/data/samples/tiddlers/TestNoPreTag.tiddler
Normal file
1
test/data/samples/tiddlers/TestNoPreTag.tiddler
Normal file
@ -0,0 +1 @@
|
||||
<div tiddler="TestNoPreTag" modifier="JeremyRuston" modified="200605111124" created="200511301204" tags="">This is a tiddler that hasn't got a {{{<pre>}}} tag</div>
|
1
test/data/samples/tiddlers/TestWithTags.tiddler
Normal file
1
test/data/samples/tiddlers/TestWithTags.tiddler
Normal file
@ -0,0 +1 @@
|
||||
<div tiddler="TestWithTags" modifier="JeremyRuston" modified="200602241819" created="200602071851" tags="one two [[three and a half]]"><pre>I welcome contributions to the TiddlyWiki core: code, documentation, or anything else that helps to make it a better product.\n\nIn terms of code, I'm happy to accept small snippets inline in emails or group messages. For larger changes, I prefer to receive a modified version of the entire TiddlyWiki HTML file via email; I can then easily analyse the differences.\n\nTo maximise the chances of your work being accepted into the core, you should consider these points:\n* Is the code reasonably short?\n* Is the functionality nearly universally useful?\n* Is the functionality impractical to offer as a plugin?\n* Have you used the same coding conventions as the rest of the core?\n* Have you tested the change on all major browsers?\n</pre></div>
|
5
test/data/samples/tiddlers/test.recipe
Executable file
5
test/data/samples/tiddlers/test.recipe
Executable file
@ -0,0 +1,5 @@
|
||||
recipe: ../../tiddlywiki.com/index.html.recipe
|
||||
tiddler: Test1.tiddler
|
||||
tiddler: TestNoPreTag.tiddler
|
||||
tiddler: TestWithTags.tiddler
|
||||
tiddler: TestContainsTag.tiddler
|
63
test/data/tiddlywiki.com/README.md
Executable file
63
test/data/tiddlywiki.com/README.md
Executable file
@ -0,0 +1,63 @@
|
||||
TiddlyWiki
|
||||
==========
|
||||
|
||||
https://github.com/TiddlyWiki/tiddlywiki.com
|
||||
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
This repository contains the tools required to create the site http://tiddlywiki.com/
|
||||
|
||||
The content for tiddlywiki.com is obtained from a [TiddlySpace](http://tiddlyspace.com/).
|
||||
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
Ensure that you have downloaded and installed TiddlyWiki as described at https://github.com/TiddlyWiki/tiddlywiki
|
||||
|
||||
You need perl to build tiddlywiki.com. If you do not have it installed, it can be downloaded [here](http://www.perl.org/get.html).
|
||||
|
||||
You need to set up `ginsu`. Copy the `ginsu` script file to somewhere that is on your path. Edit this file according to the instructions in the file.
|
||||
|
||||
You need to set up the `tiddler2tid`. Copy the `tiddler2tid` script file to somewhere that is on your path.
|
||||
|
||||
|
||||
Building tiddlywiki.com
|
||||
-----------------------
|
||||
|
||||
After downloading and installing TiddlyWiki checkout the version of TiddlyWiki that you wish to use for tiddlywiki.com. Ongoing development occurs in the tiddlywiki repository, so you need to checkout a tagged release version of TiddlyWiki. Change to the tiddlywiki directory and checkout the required version, eg:
|
||||
|
||||
git checkout tags/v2.6.5
|
||||
|
||||
Change back to the tiddlywiki.com directory.
|
||||
|
||||
Pull down the tiddlywiki.com content form TiddlySpace by invoking the `pull.sh` script:
|
||||
|
||||
./pull.sh
|
||||
|
||||
Edit the build script `bld` setting the correct version number for TiddlyWiki.
|
||||
|
||||
Invoke the build script:
|
||||
|
||||
./bld
|
||||
|
||||
You now need to generate the TiddlyWiki RSS file. To do this open the TiddlyWiki file index.html in Firefox, ensure the AdvancedOption "Generate an RSS feed when saving changes" is set, and then save the TiddlyWiki. Doing this also causes TiddlyWiki to generate some static HTML for display when Javascript is not enabled.
|
||||
|
||||
Edit the upload script `upload` setting the correct version number for TiddlyWiki.
|
||||
|
||||
Finally you need to upload the TiddlyWiki files to tiddlywiki.com. If this is the first time you are uploading, then you will need to create a `tmp` directory on tiddlywiki.com:
|
||||
|
||||
ssh user@tiddlywiki.com
|
||||
[enter your password when prompted]
|
||||
mkdir tmp
|
||||
exit
|
||||
|
||||
You can now upload the TiddlyWiki files, run the upload script:
|
||||
|
||||
./upload
|
||||
|
||||
You will be prompted for your password on several occasions during the upload process. To do this you will of course need an account on tiddlywiki.com. The upload script assumes your remote user name is the same as your local user name, if it is not then you may specify your remote user name as the first parameter to the upload script.
|
||||
|
||||
Migrated from http://svn.tiddlywiki.org on 20110719.
|
17
test/data/tiddlywiki.com/bld
Executable file
17
test/data/tiddlywiki.com/bld
Executable file
@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Usage:
|
||||
# bld [release]
|
||||
|
||||
DEFAULT_RELEASE="2.6.5"
|
||||
RELEASE=${1:-$DEFAULT_RELEASE}
|
||||
DEST=$PWD/cooked/tiddlywiki.com
|
||||
mkdir -p cooked
|
||||
mkdir -p cooked/tiddlywiki.com
|
||||
cook $PWD/index.html.recipe -d $DEST -o index.$RELEASE.html
|
||||
cook $PWD/empty.html.recipe -d $DEST -o empty.$RELEASE.html
|
||||
cp ../tiddlywiki/java/TiddlySaver.jar $DEST/TiddlySaver.jar
|
||||
rm $DEST/empty.$RELEASE.zip
|
||||
cp $DEST/empty.$RELEASE.html tmp/empty.html
|
||||
zip -j $DEST/empty.$RELEASE.zip tmp/empty.html $DEST/TiddlySaver.jar
|
||||
rm tmp/empty.html
|
1
test/data/tiddlywiki.com/empty.html.recipe
Executable file
1
test/data/tiddlywiki.com/empty.html.recipe
Executable file
@ -0,0 +1 @@
|
||||
recipe: ../tiddlywiki/tiddlywiki.html.recipe
|
14
test/data/tiddlywiki.com/ginsu
Executable file
14
test/data/tiddlywiki.com/ginsu
Executable file
@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# This is a sample ginsu script to be used with the tiddlywiki.com scripts
|
||||
# Adjust this script and then install it somewhere on your $PATH, such as ~/bin.
|
||||
#
|
||||
# You will need to adjust COOKER_TRUNK below.
|
||||
#
|
||||
# Change this to where you have the cooker code installed
|
||||
COOKER_TRUNK=$HOME/Documents/Code/GitHub/tiddlywiki/cooker
|
||||
DEFAULT_FILENAME=index
|
||||
FILENAME=${1:-$DEFAULT_FILENAME}
|
||||
DEST=$PWD
|
||||
RECIPE=$PWD/$FILENAME.html
|
||||
ruby -C $COOKER_TRUNK ginsu.rb $RECIPE -d$DEST $2 $3 $4 $5
|
3
test/data/tiddlywiki.com/index.html.recipe
Executable file
3
test/data/tiddlywiki.com/index.html.recipe
Executable file
@ -0,0 +1,3 @@
|
||||
recipe: ../tiddlywiki/tiddlywikinonoscript.html.recipe
|
||||
recipe: tiddlywiki-com-ref/split.recipe
|
||||
recipe: tiddlywiki-com/split.recipe
|
58
test/data/tiddlywiki.com/pull.sh
Executable file
58
test/data/tiddlywiki.com/pull.sh
Executable file
@ -0,0 +1,58 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# this hack pulls down the wikis for each bag, splitting the wiki into tiddlers using ginsu
|
||||
# long term plan is to use the "fat" JSON for a bag
|
||||
#
|
||||
|
||||
set -e
|
||||
export space
|
||||
export dir
|
||||
|
||||
mkdir -p tmp
|
||||
|
||||
for space in tiddlywiki-com-ref tiddlywiki-com
|
||||
do
|
||||
mkdir -p $space
|
||||
|
||||
dir=tmp/${space}.html.0
|
||||
curl -s http://${space}.tiddlyspace.com/bags/${space}_public/tiddlers.wiki > tmp/$space.html
|
||||
|
||||
# clear out the space directory so we can see deleted files when we commit
|
||||
rm -f $space/*
|
||||
|
||||
# backup any existing exploded content
|
||||
mkdir -p backups
|
||||
[ -d $dir ] && mv $dir backups/$$
|
||||
|
||||
# split into tiddlers
|
||||
(
|
||||
cd tmp
|
||||
ginsu $space > /dev/null
|
||||
)
|
||||
|
||||
# convert .tiddler files into .tid files
|
||||
(
|
||||
cd "$dir"
|
||||
|
||||
tiddler2tid *.tiddler
|
||||
find . -name \*.tid -o -name \*.js -o -name \*.meta |
|
||||
while read file
|
||||
do
|
||||
sed -e '/^server.*: /d' -e '/^_hash:/d' < "$file" > "../../$space/$file"
|
||||
done
|
||||
)
|
||||
|
||||
# make recipe based on files in the space directory
|
||||
(
|
||||
cd $space
|
||||
|
||||
find . -name \*.tid -o -name \*.js |
|
||||
grep -v '\.jpg\.' |
|
||||
grep -v 'PageTemplate' |
|
||||
grep -v 'SplashScreen' |
|
||||
grep -v 'SiteSubtitle' |
|
||||
sed 's/^/tiddler: /' > split.recipe
|
||||
)
|
||||
done
|
||||
|
||||
cook $PWD/index.html.recipe
|
53
test/data/tiddlywiki.com/tiddler2tid
Executable file
53
test/data/tiddlywiki.com/tiddler2tid
Executable file
@ -0,0 +1,53 @@
|
||||
#!/usr//bin/env perl
|
||||
|
||||
#
|
||||
# convert .tiddler into .tid files
|
||||
# useful for ginsu a TiddlyWiki, then HTTP PUT them to TiddlyWeb/TiddlySpaces
|
||||
#
|
||||
|
||||
use strict;
|
||||
|
||||
sub read_file {
|
||||
my ($filename) = @_;
|
||||
undef $/;
|
||||
local *FILE;
|
||||
open FILE, "< $filename";
|
||||
binmode(FILE, ":utf8");
|
||||
my $c = <FILE>;
|
||||
close FILE;
|
||||
return $c;
|
||||
}
|
||||
|
||||
foreach my $file (@ARGV) {
|
||||
|
||||
my $tid = $file;
|
||||
my $text = "";
|
||||
|
||||
if ($file =~ /.tiddler$/) {
|
||||
|
||||
$tid =~ s/dler$//;
|
||||
$text = read_file($file, encoding => 'utf8');
|
||||
|
||||
my $attrs = $text;
|
||||
$attrs =~ s/\s*<div([^>]*)>.*$/$1/s;
|
||||
$attrs =~ s/\s*(\w+)\s*=\s*["']([^"']*)["']\s*/$1: $2\n/gs;
|
||||
|
||||
$text =~ s/^\s*<div[^>]*>\s*<\s*pre>\s*(.*)\s*<\/pre\s*>\s*<\/div\s*>\s*$/$1/s;
|
||||
|
||||
$text = $attrs . "\n" . $text;
|
||||
|
||||
} elsif ($file =~ /.js$/) {
|
||||
|
||||
$tid =~ s/.js$/.tid/;
|
||||
$text = read_file($file . ".meta") . "\n" . read_file($file);
|
||||
|
||||
}
|
||||
|
||||
if ($text) {
|
||||
print "$tid\n";
|
||||
open(FILE, "> $tid");
|
||||
binmode(FILE, ":utf8");
|
||||
print FILE $text;
|
||||
close(FILE);
|
||||
}
|
||||
}
|
70
test/data/tiddlywiki.com/upload
Executable file
70
test/data/tiddlywiki.com/upload
Executable file
@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Usage:
|
||||
# upload [user] [release] [cleanup]
|
||||
|
||||
# default values
|
||||
DEFAULT_RELEASE="2.6.5"
|
||||
REMOTE_USER=${1:-$USER}
|
||||
RELEASE=${2:-$DEFAULT_RELEASE}
|
||||
DEST=$PWD/cooked/tiddlywiki.com
|
||||
HOST="tiddlywiki.com"
|
||||
DIR="/var/www/www.tiddlywiki.com/htdocs"
|
||||
ARCHIVE_DIR="$DIR/archive"
|
||||
OWNER="www-data:www-data"
|
||||
PERM="664"
|
||||
|
||||
# setPermissions()
|
||||
# Usage:
|
||||
# setPermissions file
|
||||
function setPermissions() {
|
||||
COMMANDS="$COMMANDS sudo chown $OWNER $1;"
|
||||
COMMANDS="$COMMANDS sudo chmod $PERM $1;"
|
||||
}
|
||||
|
||||
# upload files to temporary folder
|
||||
echo
|
||||
echo "uploading files"
|
||||
echo
|
||||
FILES="$DEST/index.$RELEASE.html $DEST/index.$RELEASE.xml $DEST/empty.$RELEASE.html $DEST/TiddlySaver.jar $DEST/empty.$RELEASE.zip"
|
||||
scp $FILES "$REMOTE_USER@$HOST:./tmp/"
|
||||
|
||||
# transfer files to their respective folders
|
||||
echo
|
||||
echo "transferring files"
|
||||
echo
|
||||
COMMANDS="ssh $REMOTE_USER@$HOST"
|
||||
# Index
|
||||
COMMANDS="$COMMANDS sudo cp ./tmp/index.$RELEASE.html $ARCHIVE_DIR/;"
|
||||
setPermissions "$ARCHIVE_DIR/index.$RELEASE.html"
|
||||
COMMANDS="$COMMANDS sudo mv ./tmp/index.$RELEASE.html $DIR/index.html;"
|
||||
setPermissions "$DIR/index.html"
|
||||
COMMANDS="$COMMANDS sudo mv ./tmp/index.$RELEASE.xml $DIR/index.xml;"
|
||||
setPermissions "$DIR/index.xml"
|
||||
# Empty
|
||||
COMMANDS="$COMMANDS sudo cp ./tmp/empty.$RELEASE.html $ARCHIVE_DIR/;"
|
||||
setPermissions "$ARCHIVE_DIR/empty.$RELEASE.html"
|
||||
COMMANDS="$COMMANDS sudo cp ./tmp/empty.$RELEASE.html $DIR/empty.html;"
|
||||
setPermissions "$DIR/empty.html"
|
||||
# Upgrade
|
||||
COMMANDS="$COMMANDS sudo mv ./tmp/empty.$RELEASE.html $DIR/upgrade/index.html;"
|
||||
setPermissions "$DIR/upgrade/index.html"
|
||||
# TiddlySaver
|
||||
COMMANDS="$COMMANDS sudo mv ./tmp/TiddlySaver.jar $DIR/TiddlySaver.jar;"
|
||||
setPermissions "$DIR/TiddlySaver.jar"
|
||||
# ZIP package
|
||||
COMMANDS="$COMMANDS sudo mv ./tmp/empty.$RELEASE.zip $DIR/empty.zip;"
|
||||
setPermissions "$DIR/empty.zip"
|
||||
# execute
|
||||
$COMMANDS
|
||||
|
||||
# cleanup
|
||||
if [ "$3" = "true" ]; then
|
||||
echo "cleaning up (removing cooked files)"
|
||||
echo "removing index.$RELEASE.html"
|
||||
rm "index.$RELEASE.html"
|
||||
echo "removing empty.$RELEASE.html"
|
||||
rm "empty.$RELEASE.html"
|
||||
echo "removing TiddlySaver.jar"
|
||||
rm "TiddlySaver.jar"
|
||||
fi
|
1
test/data/tiddlywiki/ALPHA
Executable file
1
test/data/tiddlywiki/ALPHA
Executable file
@ -0,0 +1 @@
|
||||
2.6.6.A1
|
23
test/data/tiddlywiki/Makefile
Executable file
23
test/data/tiddlywiki/Makefile
Executable file
@ -0,0 +1,23 @@
|
||||
# Start at a Makefile or managing build activities.
|
||||
# Expects a 'cook' script somewhere on the $PATH.
|
||||
# See 'cook' in this directory for a sample you can use.
|
||||
# For now users the OSX specific "open" to run a test file. This
|
||||
# will need to change.
|
||||
#
|
||||
|
||||
clean:
|
||||
rm cooked/*.html || true
|
||||
rm cooked/*.jar || true
|
||||
rm cooked/*.js || true
|
||||
rmdir cooked || true
|
||||
|
||||
test: clean tests.html
|
||||
ln -sf test/recipes/sample.txt .
|
||||
open cooked/tests.html
|
||||
|
||||
tests.html:
|
||||
mkdir -p cooked
|
||||
cook $(PWD)/test/recipes/tests.html.recipe -d $(PWD)/cooked -o tests.html
|
||||
|
||||
alpha:
|
||||
./bldalpha
|
75
test/data/tiddlywiki/README.md
Executable file
75
test/data/tiddlywiki/README.md
Executable file
@ -0,0 +1,75 @@
|
||||
TiddlyWiki
|
||||
==========
|
||||
|
||||
https://github.com/TiddlyWiki/tiddlywiki
|
||||
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
This is the master repository for the core of TiddlyWiki. It is for the development and maintenance of TiddlyWiki.
|
||||
|
||||
If you simply wish to use TiddlyWiki, it is easiest to download it from: http://tiddlywiki.com/
|
||||
|
||||
This site also gives details about TiddlyWiki.
|
||||
|
||||
TiddlyWiki code and issues used to be stored at http://svn.tiddlywiki.org and http://trac.tiddlywiki.org .
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
Install the [git](http://git-scm.com/download) version control system, if you do not already have it.
|
||||
|
||||
Install the [ruby](http://www.ruby-lang.org/en/downloads/) programming language, if you do not already have it. Ruby is required for some of the TiddlyWiki tools (cook and ginsu).
|
||||
|
||||
TiddlyWiki has 4 important parallel repositories:
|
||||
|
||||
1. [tiddlywiki](https://github.com/TiddlyWiki/tiddlywiki), this includes the source and test code for TiddlyWiki itself.
|
||||
|
||||
2. [cooker](https://github.com/TiddlyWiki/cooker), this includes the tool for building a TiddlyWiki from a set of tiddlers (`cook`) and the tool for splitting a TiddlyWiki into separate tiddlers (`ginsu`). You need to download this repository for any TiddlyWiki development.
|
||||
|
||||
3. [translations](https://github.com/TiddlyWiki/translations), this includes the translations of TiddlyWiki into a number of different languages.
|
||||
|
||||
4. [tiddlywiki.com](https://github.com/TiddlyWiki/tiddlywiki.com), this includes what is required to build and upload the http://tiddlywiki.com website.
|
||||
|
||||
|
||||
To do any serious work on TiddlyWiki you will probably want to download all four of these repositories. They should be downloaded into parallel directories, since some of the build scripts used relative links to the other repositories:
|
||||
|
||||
git clone git@github.com:TiddlyWiki/tiddlywiki.git
|
||||
git clone git@github.com:TiddlyWiki/cooker.git
|
||||
git clone git@github.com:TiddlyWiki/tiddlywiki.com.git
|
||||
git clone git@github.com:TiddlyWiki/translations.git
|
||||
|
||||
|
||||
Next you need to set up `cook`. Copy the `cook` script file to somewhere that is on your path. Edit this file according to the instructions in the file.
|
||||
|
||||
|
||||
Building and testing
|
||||
--------------------
|
||||
|
||||
There is a `Makefile` for managing testing. To build and execute the TiddlyWiki tests, type:
|
||||
|
||||
make test
|
||||
|
||||
Note that, depending on your machine configuration, the tests may take a while to run (perhaps as long as a 30 seconds to a minute).
|
||||
|
||||
To set the version number of the alpha build output files edit the file `ALPHA`. This should normally be set to the same version as in the TiddlyWiki Version.js file.
|
||||
|
||||
To build an alpha version of TiddlyWiki incorporating any changes you have made, run the `bldalpha` script by typing:
|
||||
|
||||
./bldalpha
|
||||
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
Pull requests for feature requests/bug fixes are being accepted for this project. Pull requests should be accompanied by tests. If no tests existed for the given functionality previously, please include these in your contribution to ensure that the TiddlyWiki code base is as reliable as possible going forward. Any pull requests without tests will not generally be folded into the core codebase. See https://github.com/TiddlyWiki/tiddlywiki/wiki for more information.
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
TiddlyWiki is Copyright 2011 UneMesa Assocation
|
||||
|
||||
It is licensed under a BSD License.
|
21
test/data/tiddlywiki/bldalpha
Executable file
21
test/data/tiddlywiki/bldalpha
Executable file
@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Usage:
|
||||
# bldalpha [release]
|
||||
|
||||
# Requires a cook script on $PATH.
|
||||
# See 'cook' in this directory for a sample.
|
||||
|
||||
DEFAULT_RELEASE=`cat ALPHA`
|
||||
OUTPUT_DIR=$PWD/cooked
|
||||
mkdir -p $OUTPUT_DIR
|
||||
RELEASE=${1:-$DEFAULT_RELEASE}
|
||||
RECIPE=$PWD/tiddlywiki.html.recipe
|
||||
RECIPE_EXT_JS=$PWD/tiddlywiki_externaljs.html.recipe
|
||||
RECIPE_EXT_JS_TS=$PWD/tiddlywiki_externaljs_tiddlyspace_alpha.html.recipe
|
||||
cook $RECIPE -d $OUTPUT_DIR -o tiddlywiki.$RELEASE.html
|
||||
cp java/TiddlySaver.jar $OUTPUT_DIR
|
||||
cook $RECIPE -d $OUTPUT_DIR -o tiddlywiki_compressed.$RELEASE.html -cr -Cr -Dr
|
||||
cook $RECIPE -d $OUTPUT_DIR -o twcore.$RELEASE.js -j
|
||||
cook $RECIPE_EXT_JS -d $OUTPUT_DIR -o tiddlywiki_externaljs.$RELEASE.html
|
||||
cook $RECIPE_EXT_JS_TS -d $OUTPUT_DIR -o tiddlywiki_externaljs_tiddlyspace.$RELEASE.html
|
18
test/data/tiddlywiki/bldxjs
Executable file
18
test/data/tiddlywiki/bldxjs
Executable file
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Build version of TiddlyWiki with external javascript
|
||||
# Usage:
|
||||
# bldxjs [release]
|
||||
|
||||
DEFAULT_RELEASE=2.6.3.A2
|
||||
RELEASE=${1:-$DEFAULT_RELEASE}
|
||||
DEST=$PWD
|
||||
RECIPE=$PWD/tiddlywiki.html.recipe
|
||||
RECIPE_EXT_JS=$PWD/tiddlywiki_externaljs.html.recipe
|
||||
RECIPE_EXT_JS_TS=$PWD/tiddlywiki_externaljs_tiddlyspace_alpha.html.recipe
|
||||
ruby -Ku -C ../tools/cooker cook.rb $RECIPE -d$DEST -q -j -o twcore.$RELEASE.js $2 $3 $4 $5
|
||||
cp -f twcore.$RELEASE.js twcore.js
|
||||
cp -f jquery/jquery.js jquery.js
|
||||
cp -f jquery/plugins/jQuery.twStylesheet.js jQuery.twStylesheet.js
|
||||
ruby -Ku -C ../tools/cooker cook.rb $RECIPE_EXT_JS -d$DEST -q -o tiddlywiki_externaljs.$RELEASE.html$2 $3 $4 $5
|
||||
ruby -Ku -C ../tools/cooker cook.rb $RECIPE_EXT_JS_TS -d$DEST -q -o tiddlywiki_externaljs_tiddlyspace.$RELEASE.html$2 $3 $4 $5
|
21
test/data/tiddlywiki/cook
Executable file
21
test/data/tiddlywiki/cook
Executable file
@ -0,0 +1,21 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This is a sample cook script to be used with the build scripts
|
||||
# and Makefile for TiddlyWiki. Adjust this script and then install
|
||||
# it somewhere on your $PATH, such as ~/bin.
|
||||
#
|
||||
# You will need to adjust DEFAULT_TRUNK and COOKER_TRUNK below.
|
||||
|
||||
# change this to where your tiddlywiki repo lives,
|
||||
# unless you have TW_TRUNKDIR set.
|
||||
DEFAULT_TRUNK=$HOME/Documents/Code/Github/tiddlywiki
|
||||
|
||||
# Change this to where you have the cooker code installed
|
||||
COOKER_TRUNK=$HOME/Documents/Code/Github/tiddlywiki/cooker
|
||||
|
||||
if [ -z "$TW_TRUNKDIR" ]
|
||||
then
|
||||
export TW_TRUNKDIR=$DEFAULT_TRUNK
|
||||
fi
|
||||
RECIPE=$1 && shift
|
||||
ruby -Ku -C $COOKER_TRUNK cook.rb $RECIPE "$@"
|
44
test/data/tiddlywiki/deprecated/Crypto.js
Executable file
44
test/data/tiddlywiki/deprecated/Crypto.js
Executable file
@ -0,0 +1,44 @@
|
||||
//--
|
||||
//-- Deprecated Crypto functions and associated conversion routines.
|
||||
//-- Use the jQuery.encoding functions directly instead.
|
||||
//--
|
||||
|
||||
// Crypto 'namespace'
|
||||
function Crypto() {}
|
||||
|
||||
// Convert a string to an array of big-endian 32-bit words
|
||||
Crypto.strToBe32s = function(str)
|
||||
{
|
||||
return jQuery.encoding.strToBe32s(str);
|
||||
};
|
||||
|
||||
// Convert an array of big-endian 32-bit words to a string
|
||||
Crypto.be32sToStr = function(be)
|
||||
{
|
||||
return jQuery.encoding.be32sToStr(be);
|
||||
};
|
||||
|
||||
// Convert an array of big-endian 32-bit words to a hex string
|
||||
Crypto.be32sToHex = function(be)
|
||||
{
|
||||
return jQuery.encoding.be32sToHex(be);
|
||||
};
|
||||
|
||||
// Return, in hex, the SHA-1 hash of a string
|
||||
Crypto.hexSha1Str = function(str)
|
||||
{
|
||||
return jQuery.encoding.digests.hexSha1Str(str);
|
||||
};
|
||||
|
||||
// Return the SHA-1 hash of a string
|
||||
Crypto.sha1Str = function(str)
|
||||
{
|
||||
return jQuery.encoding.digests.sha1Str(str);
|
||||
};
|
||||
|
||||
// Calculate the SHA-1 hash of an array of blen bytes of big-endian 32-bit words
|
||||
Crypto.sha1 = function(x,blen)
|
||||
{
|
||||
return jQuery.encoding.digests.sha1(x,blen);
|
||||
};
|
||||
|
90
test/data/tiddlywiki/deprecated/Deprecated.js
Executable file
90
test/data/tiddlywiki/deprecated/Deprecated.js
Executable file
@ -0,0 +1,90 @@
|
||||
//--
|
||||
//-- Deprecated code
|
||||
//--
|
||||
|
||||
// @Deprecated: Use createElementAndWikify and this.termRegExp instead
|
||||
config.formatterHelpers.charFormatHelper = function(w)
|
||||
{
|
||||
w.subWikify(createTiddlyElement(w.output,this.element),this.terminator);
|
||||
};
|
||||
|
||||
// @Deprecated: Use enclosedTextHelper and this.lookaheadRegExp instead
|
||||
config.formatterHelpers.monospacedByLineHelper = function(w)
|
||||
{
|
||||
var lookaheadRegExp = new RegExp(this.lookahead,"mg");
|
||||
lookaheadRegExp.lastIndex = w.matchStart;
|
||||
var lookaheadMatch = lookaheadRegExp.exec(w.source);
|
||||
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
|
||||
var text = lookaheadMatch[1];
|
||||
if(config.browser.isIE)
|
||||
text = text.replace(/\n/g,"\r");
|
||||
createTiddlyElement(w.output,"pre",null,null,text);
|
||||
w.nextMatch = lookaheadRegExp.lastIndex;
|
||||
}
|
||||
};
|
||||
|
||||
// @Deprecated: Use <br> or <br /> instead of <<br>>
|
||||
config.macros.br = {};
|
||||
config.macros.br.handler = function(place)
|
||||
{
|
||||
createTiddlyElement(place,"br");
|
||||
};
|
||||
|
||||
// Find an entry in an array. Returns the array index or null
|
||||
// @Deprecated: Use indexOf instead
|
||||
Array.prototype.find = function(item)
|
||||
{
|
||||
var i = this.indexOf(item);
|
||||
return i == -1 ? null : i;
|
||||
};
|
||||
|
||||
// Load a tiddler from an HTML DIV. The caller should make sure to later call Tiddler.changed()
|
||||
// @Deprecated: Use store.getLoader().internalizeTiddler instead
|
||||
Tiddler.prototype.loadFromDiv = function(divRef,title)
|
||||
{
|
||||
return store.getLoader().internalizeTiddler(store,this,title,divRef);
|
||||
};
|
||||
|
||||
// Format the text for storage in an HTML DIV
|
||||
// @Deprecated Use store.getSaver().externalizeTiddler instead.
|
||||
Tiddler.prototype.saveToDiv = function()
|
||||
{
|
||||
return store.getSaver().externalizeTiddler(store,this);
|
||||
};
|
||||
|
||||
// @Deprecated: Use store.allTiddlersAsHtml() instead
|
||||
function allTiddlersAsHtml()
|
||||
{
|
||||
return store.allTiddlersAsHtml();
|
||||
}
|
||||
|
||||
// @Deprecated: Use refreshPageTemplate instead
|
||||
function applyPageTemplate(title)
|
||||
{
|
||||
refreshPageTemplate(title);
|
||||
}
|
||||
|
||||
// @Deprecated: Use story.displayTiddlers instead
|
||||
function displayTiddlers(srcElement,titles,template,unused1,unused2,animate,unused3)
|
||||
{
|
||||
story.displayTiddlers(srcElement,titles,template,animate);
|
||||
}
|
||||
|
||||
// @Deprecated: Use story.displayTiddler instead
|
||||
function displayTiddler(srcElement,title,template,unused1,unused2,animate,unused3)
|
||||
{
|
||||
story.displayTiddler(srcElement,title,template,animate);
|
||||
}
|
||||
|
||||
// @Deprecated: Use functions on right hand side directly instead
|
||||
var createTiddlerPopup = Popup.create;
|
||||
var scrollToTiddlerPopup = Popup.show;
|
||||
var hideTiddlerPopup = Popup.remove;
|
||||
|
||||
// @Deprecated: Use right hand side directly instead
|
||||
var regexpBackSlashEn = new RegExp("\\\\n","mg");
|
||||
var regexpBackSlash = new RegExp("\\\\","mg");
|
||||
var regexpBackSlashEss = new RegExp("\\\\s","mg");
|
||||
var regexpNewLine = new RegExp("\n","mg");
|
||||
var regexpCarriageReturn = new RegExp("\r","mg");
|
||||
|
20
test/data/tiddlywiki/deprecated/FileAdaptor.js
Executable file
20
test/data/tiddlywiki/deprecated/FileAdaptor.js
Executable file
@ -0,0 +1,20 @@
|
||||
//--
|
||||
//-- Deprecated FileAdaptor functions
|
||||
//--
|
||||
|
||||
FileAdaptor.loadTiddlyWikiCallback = function(status,context,responseText,url,xhr)
|
||||
{
|
||||
context.status = status;
|
||||
if(!status) {
|
||||
context.statusText = "Error reading file";
|
||||
} else {
|
||||
//# Load the content into a TiddlyWiki() object
|
||||
context.adaptor.store = new TiddlyWiki();
|
||||
if(!context.adaptor.store.importTiddlyWiki(responseText)) {
|
||||
context.statusText = config.messages.invalidFileError.format([url]);
|
||||
context.status = false;
|
||||
}
|
||||
}
|
||||
context.complete(context,context.userParams);
|
||||
};
|
||||
|
26
test/data/tiddlywiki/deprecated/Http.js
Executable file
26
test/data/tiddlywiki/deprecated/Http.js
Executable file
@ -0,0 +1,26 @@
|
||||
//--
|
||||
//-- Deprecated HTTP request code
|
||||
//-- Use the jQuery ajax functions directly instead
|
||||
//--
|
||||
|
||||
//# Load a file over http
|
||||
//# url - the source url
|
||||
//# callback - function to call when there is a response
|
||||
//# params - parameter object that gets passed to the callback for storing it's state
|
||||
//# Return value is the underlying XMLHttpRequest object, or a string if there was an error
|
||||
//# Callback function is called like this:
|
||||
//# callback(status,params,responseText,xhr)
|
||||
//# status - true if OK, false if error
|
||||
//# params - the parameter object provided to loadRemoteFile()
|
||||
//# responseText - the text of the file
|
||||
//# xhr - the underlying XMLHttpRequest object
|
||||
function loadRemoteFile(url,callback,params)
|
||||
{
|
||||
return httpReq("GET",url,callback,params);
|
||||
}
|
||||
|
||||
function doHttp(type,url,data,contentType,username,password,callback,params,headers,allowCache)
|
||||
{
|
||||
return httpReq(type,url,callback,params,headers,data,contentType,username,password,allowCache);
|
||||
}
|
||||
|
16
test/data/tiddlywiki/deprecated/Numbers.js
Executable file
16
test/data/tiddlywiki/deprecated/Numbers.js
Executable file
@ -0,0 +1,16 @@
|
||||
//--
|
||||
//-- Deprecated Number functions
|
||||
//--
|
||||
|
||||
// @Deprecated: no direct replacement, since not used in core code
|
||||
// Clamp a number to a range
|
||||
Number.prototype.clamp = function(min,max)
|
||||
{
|
||||
var c = this;
|
||||
if(c < min)
|
||||
c = min;
|
||||
if(c > max)
|
||||
c = max;
|
||||
return Number(c);
|
||||
};
|
||||
|
29
test/data/tiddlywiki/deprecated/Strings.js
Executable file
29
test/data/tiddlywiki/deprecated/Strings.js
Executable file
@ -0,0 +1,29 @@
|
||||
//--
|
||||
//-- Deprecated String functions
|
||||
//--
|
||||
|
||||
// @Deprecated: no direct replacement, since not used in core code
|
||||
String.prototype.toJSONString = function()
|
||||
{
|
||||
// Convert a string to it's JSON representation by encoding control characters, double quotes and backslash. See json.org
|
||||
var m = {
|
||||
'\b': '\\b',
|
||||
'\f': '\\f',
|
||||
'\n': '\\n',
|
||||
'\r': '\\r',
|
||||
'\t': '\\t',
|
||||
'"' : '\\"',
|
||||
'\\': '\\\\'
|
||||
};
|
||||
var replaceFn = function(a,b) {
|
||||
var c = m[b];
|
||||
if(c)
|
||||
return c;
|
||||
c = b.charCodeAt();
|
||||
return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
|
||||
};
|
||||
if(/["\\\x00-\x1f]/.test(this))
|
||||
return '"' + this.replace(/([\x00-\x1f\\"])/g,replaceFn) + '"';
|
||||
return '"' + this + '"';
|
||||
};
|
||||
|
22
test/data/tiddlywiki/deprecated/Tiddler.js
Executable file
22
test/data/tiddlywiki/deprecated/Tiddler.js
Executable file
@ -0,0 +1,22 @@
|
||||
//--
|
||||
//-- Deprecated Tiddler code
|
||||
//--
|
||||
|
||||
// @Deprecated: Use tiddlerToRssItem(tiddler,uri) instead
|
||||
Tiddler.prototype.toRssItem = function(uri)
|
||||
{
|
||||
return tiddlerToRssItem(this,uri);
|
||||
};
|
||||
|
||||
// @Deprecated: Use "<item>\n" + tiddlerToRssItem(tiddler,uri) + "\n</item>" instead
|
||||
Tiddler.prototype.saveToRss = function(uri)
|
||||
{
|
||||
return "<item>\n" + tiddlerToRssItem(this,uri) + "\n</item>";
|
||||
};
|
||||
|
||||
// @Deprecated: Use jQuery.encoding.digests.hexSha1Str instead
|
||||
Tiddler.prototype.generateFingerprint = function()
|
||||
{
|
||||
return "0x" + Crypto.hexSha1Str(this.text);
|
||||
};
|
||||
|
38
test/data/tiddlywiki/deprecated/Utilities.js
Executable file
38
test/data/tiddlywiki/deprecated/Utilities.js
Executable file
@ -0,0 +1,38 @@
|
||||
//--
|
||||
//-- Deprecated utility functions
|
||||
//-- Use the jQuery functions directly instead
|
||||
//--
|
||||
|
||||
// Remove all children of a node
|
||||
function removeChildren(e)
|
||||
{
|
||||
jQuery(e).empty();
|
||||
}
|
||||
|
||||
// Remove a node and all it's children
|
||||
function removeNode(e)
|
||||
{
|
||||
jQuery(e).remove();
|
||||
}
|
||||
|
||||
// Return the content of an element as plain text with no formatting
|
||||
function getPlainText(e)
|
||||
{
|
||||
return jQuery(e).text();
|
||||
}
|
||||
|
||||
function addClass(e,className)
|
||||
{
|
||||
jQuery(e).addClass(className);
|
||||
}
|
||||
|
||||
function removeClass(e,className)
|
||||
{
|
||||
jQuery(e).removeClass(className);
|
||||
}
|
||||
|
||||
function hasClass(e,className)
|
||||
{
|
||||
return jQuery(e).hasClass(className);
|
||||
}
|
||||
|
16
test/data/tiddlywiki/deprecated/Wikifier.js
Executable file
16
test/data/tiddlywiki/deprecated/Wikifier.js
Executable file
@ -0,0 +1,16 @@
|
||||
//--
|
||||
//-- Deprecated Wikifier code
|
||||
//--
|
||||
|
||||
//# Wikify a named tiddler to plain text
|
||||
function wikifyPlain(title,theStore,limit)
|
||||
{
|
||||
if(!theStore)
|
||||
theStore = store;
|
||||
if(theStore.tiddlerExists(title) || theStore.isShadowTiddler(title)) {
|
||||
return wikifyPlainText(theStore.getTiddlerText(title),limit,tiddler);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
10
test/data/tiddlywiki/deprecated/split.recipe
Executable file
10
test/data/tiddlywiki/deprecated/split.recipe
Executable file
@ -0,0 +1,10 @@
|
||||
jsdeprecated: Crypto.js
|
||||
jsdeprecated: Deprecated.js
|
||||
jsdeprecated: FileAdaptor.js
|
||||
jsdeprecated: Http.js
|
||||
jsdeprecated: Strings.js
|
||||
jsdeprecated: Tiddler.js
|
||||
jsdeprecated: Numbers.js
|
||||
jsdeprecated: Utilities.js
|
||||
jsdeprecated: Wikifier.js
|
||||
|
29
test/data/tiddlywiki/html/copyright.txt
Executable file
29
test/data/tiddlywiki/html/copyright.txt
Executable file
@ -0,0 +1,29 @@
|
||||
TiddlyWiki created by Jeremy Ruston, (jeremy [at] osmosoft [dot] com)
|
||||
|
||||
Copyright (c) Jeremy Ruston 2004-2007
|
||||
Copyright (c) UnaMesa Association 2007-2011
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
Neither the name of the UnaMesa Association nor the names of its contributors may be
|
||||
used to endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGE.
|
3
test/data/tiddlywiki/html/externaljs.txt
Executable file
3
test/data/tiddlywiki/html/externaljs.txt
Executable file
@ -0,0 +1,3 @@
|
||||
<script type="text/javascript" src="jquery.js"></script>
|
||||
<script type="text/javascript" src="jQuery.twStylesheet.js"></script>
|
||||
<script type="text/javascript" src="twcore.js"></script>
|
3
test/data/tiddlywiki/html/externaljs_tiddlyspace.txt
Executable file
3
test/data/tiddlywiki/html/externaljs_tiddlyspace.txt
Executable file
@ -0,0 +1,3 @@
|
||||
<script type="text/javascript" src="/bags/common/tiddlers/jquery.js"></script>
|
||||
<script type="text/javascript" src="/bags/common/tiddlers/jQuery.twStylesheet.js"></script>
|
||||
<script type="text/javascript" src="/bags/common/tiddlers/twcore.js"></script>
|
3
test/data/tiddlywiki/html/externaljs_tiddlyspace_alpha.txt
Executable file
3
test/data/tiddlywiki/html/externaljs_tiddlyspace_alpha.txt
Executable file
@ -0,0 +1,3 @@
|
||||
<script type="text/javascript" src="/bags/common/tiddlers/alpha_jquery.js"></script>
|
||||
<script type="text/javascript" src="/bags/common/tiddlers/alpha_jQuery.twStylesheet.js"></script>
|
||||
<script type="text/javascript" src="/bags/common/tiddlers/alpha_twcore.js"></script>
|
3
test/data/tiddlywiki/html/externaljs_tiddlyspace_beta.txt
Executable file
3
test/data/tiddlywiki/html/externaljs_tiddlyspace_beta.txt
Executable file
@ -0,0 +1,3 @@
|
||||
<script type="text/javascript" src="/bags/common/tiddlers/beta_jquery.js"></script>
|
||||
<script type="text/javascript" src="/bags/common/tiddlers/beta_jQuery.twStylesheet.js"></script>
|
||||
<script type="text/javascript" src="/bags/common/tiddlers/beta_twcore.js"></script>
|
3
test/data/tiddlywiki/html/noscript.txt
Executable file
3
test/data/tiddlywiki/html/noscript.txt
Executable file
@ -0,0 +1,3 @@
|
||||
<div id="javascriptWarning">
|
||||
This page requires JavaScript to function properly.<br /><br />If you are using Microsoft Internet Explorer you may need to click on the yellow bar above and select 'Allow Blocked Content'. You must then click 'Yes' on the following security warning.
|
||||
</div>
|
1
test/data/tiddlywiki/html/rss.link.html
Executable file
1
test/data/tiddlywiki/html/rss.link.html
Executable file
@ -0,0 +1 @@
|
||||
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml'/>
|
5
test/data/tiddlywiki/html/split.recipe
Executable file
5
test/data/tiddlywiki/html/split.recipe
Executable file
@ -0,0 +1,5 @@
|
||||
template: tiddlywiki.template.html
|
||||
copyright: copyright.txt
|
||||
style: style.txt
|
||||
noscript: noscript.txt
|
||||
jsext: tiddlysaver.txt
|
3
test/data/tiddlywiki/html/splitnonoscript.recipe
Executable file
3
test/data/tiddlywiki/html/splitnonoscript.recipe
Executable file
@ -0,0 +1,3 @@
|
||||
template: tiddlywiki.template.html
|
||||
copyright: copyright.txt
|
||||
style: style.txt
|
7
test/data/tiddlywiki/html/style.txt
Executable file
7
test/data/tiddlywiki/html/style.txt
Executable file
@ -0,0 +1,7 @@
|
||||
#saveTest {display:none;}
|
||||
#messageArea {display:none;}
|
||||
#copyright {display:none;}
|
||||
#storeArea {display:none;}
|
||||
#storeArea div {padding:0.5em; margin:1em 0em 0em 0em; border-color:#fff #666 #444 #ddd; border-style:solid; border-width:2px; overflow:auto;}
|
||||
#shadowArea {display:none;}
|
||||
#javascriptWarning {width:100%; text-align:center; font-weight:bold; background-color:#dd1100; color:#fff; padding:1em 0em;}
|
6
test/data/tiddlywiki/html/tiddlysaver.txt
Executable file
6
test/data/tiddlywiki/html/tiddlysaver.txt
Executable file
@ -0,0 +1,6 @@
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
if(useJavaSaver)
|
||||
document.write("<applet style='position:absolute;left:-1px' name='TiddlySaver' code='TiddlySaver.class' archive='TiddlySaver.jar' width='1' height='1'></applet>");
|
||||
//]]>
|
||||
</script>
|
86
test/data/tiddlywiki/html/tiddlywiki.template.html
Executable file
86
test/data/tiddlywiki/html/tiddlywiki.template.html
Executable file
@ -0,0 +1,86 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<script id="versionArea" type="text/javascript">
|
||||
//<![CDATA[
|
||||
<!--@@version@@-->
|
||||
//]]>
|
||||
</script>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
||||
<meta name="copyright" content="
|
||||
<!--@@copyright@@-->
|
||||
" />
|
||||
<!--PRE-HEAD-START-->
|
||||
<!--@@prehead@@-->
|
||||
<!--PRE-HEAD-END-->
|
||||
<title>
|
||||
<!--@@title@@-->
|
||||
</title>
|
||||
<style id="styleArea" type="text/css">
|
||||
<!--@@style@@-->
|
||||
</style>
|
||||
<!--POST-HEAD-START-->
|
||||
<!--@@posthead@@-->
|
||||
<!--POST-HEAD-END-->
|
||||
</head>
|
||||
<body onload="main();" onunload="if(window.unload) unload();">
|
||||
<!--PRE-BODY-START-->
|
||||
<!--@@prebody@@-->
|
||||
<!--PRE-BODY-END-->
|
||||
<div id="copyright">
|
||||
Welcome to TiddlyWiki created by Jeremy Ruston; Copyright © 2004-2007 Jeremy Ruston, Copyright © 2007-2011 UnaMesa Association
|
||||
</div>
|
||||
<noscript>
|
||||
<!--@@noscript@@-->
|
||||
</noscript>
|
||||
<div id="saveTest"></div>
|
||||
<div id="backstageCloak"></div>
|
||||
<div id="backstageButton"></div>
|
||||
<div id="backstageArea"><div id="backstageToolbar"></div></div>
|
||||
<div id="backstage">
|
||||
<div id="backstagePanel"></div>
|
||||
</div>
|
||||
<div id="contentWrapper"></div>
|
||||
<div id="contentStash"></div>
|
||||
<div id="shadowArea">
|
||||
<!--@@shadow@@-->
|
||||
</div>
|
||||
<!--POST-SHADOWAREA-->
|
||||
<div id="storeArea">
|
||||
<!--@@tiddler@@-->
|
||||
<!--@@plugin@@-->
|
||||
<!--@@posttiddlers@@-->
|
||||
</div>
|
||||
<!--POST-STOREAREA-->
|
||||
<!--POST-BODY-START-->
|
||||
<!--@@postbody@@-->
|
||||
<!--POST-BODY-END-->
|
||||
<script id="jsArea" type="text/javascript">
|
||||
//<![CDATA[
|
||||
<!--@@prejs@@-->
|
||||
<!--@@js@@-->
|
||||
<!--@@postjs@@-->
|
||||
//]]>
|
||||
</script>
|
||||
<!--@@jsext@@-->
|
||||
<script id="jsdeprecatedArea" type="text/javascript">
|
||||
//<![CDATA[
|
||||
<!--@@jsdeprecated@@-->
|
||||
//]]>
|
||||
</script>
|
||||
<script id="jslibArea" type="text/javascript">
|
||||
//<![CDATA[
|
||||
<!--@@jslib@@-->
|
||||
|
||||
//]]>
|
||||
</script>
|
||||
<script id="jqueryArea" type="text/javascript">
|
||||
//<![CDATA[
|
||||
<!--@@jquery@@-->
|
||||
//]]>
|
||||
</script>
|
||||
<!--POST-SCRIPT-START-->
|
||||
<!--@@postscript@@-->
|
||||
<!--POST-SCRIPT-END-->
|
||||
</body>
|
||||
</html>
|
BIN
test/data/tiddlywiki/java/TiddlySaver$1.class
Executable file
BIN
test/data/tiddlywiki/java/TiddlySaver$1.class
Executable file
Binary file not shown.
BIN
test/data/tiddlywiki/java/TiddlySaver$2.class
Executable file
BIN
test/data/tiddlywiki/java/TiddlySaver$2.class
Executable file
Binary file not shown.
BIN
test/data/tiddlywiki/java/TiddlySaver.class
Executable file
BIN
test/data/tiddlywiki/java/TiddlySaver.class
Executable file
Binary file not shown.
BIN
test/data/tiddlywiki/java/TiddlySaver.jar
Executable file
BIN
test/data/tiddlywiki/java/TiddlySaver.jar
Executable file
Binary file not shown.
71
test/data/tiddlywiki/java/TiddlySaver.java
Executable file
71
test/data/tiddlywiki/java/TiddlySaver.java
Executable file
@ -0,0 +1,71 @@
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
public class TiddlySaver extends java.applet.Applet {
|
||||
public String loadFile(final String filename, final String charset) {
|
||||
return (String)AccessController.doPrivileged(new PrivilegedAction() {
|
||||
public Object run() {
|
||||
try {
|
||||
if (charset.length() == 0) {
|
||||
StringBuffer data = new StringBuffer();
|
||||
BufferedReader r = new BufferedReader(new FileReader(filename));
|
||||
String line;
|
||||
while ((line = r.readLine()) != null) data.append(line).append("\n");
|
||||
r.close();
|
||||
return data.toString();
|
||||
} else {
|
||||
File f = new File(filename);
|
||||
FileInputStream i = new FileInputStream(f);
|
||||
byte[] b = new byte[(f.length() > Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int)f.length()];
|
||||
int offset = 0;
|
||||
int num = 0;
|
||||
while (offset < b.length && (num = i.read(b, offset, b.length - offset)) >= 0) {
|
||||
offset += num;
|
||||
}
|
||||
i.close();
|
||||
return new String(b, 0, offset, charset);
|
||||
}
|
||||
} catch (Exception x) {
|
||||
x.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
public int saveFile(final String filename, final String charset, final String data) {
|
||||
return ((Integer)AccessController.doPrivileged(new PrivilegedAction() {
|
||||
public Object run() {
|
||||
try {
|
||||
if (charset.length() == 0) {
|
||||
int e, s = 0;
|
||||
BufferedWriter w = new BufferedWriter(new FileWriter(filename));
|
||||
do {
|
||||
e = data.indexOf('\n', s);
|
||||
if (e == -1) e = data.length();
|
||||
w.write(data, s, e - s);
|
||||
w.newLine();
|
||||
s = e + 1;
|
||||
} while (s < data.length());
|
||||
w.close();
|
||||
return new Integer(1);
|
||||
} else {
|
||||
FileOutputStream o = new FileOutputStream(filename);
|
||||
o.write(data.getBytes(charset));
|
||||
o.close();
|
||||
return new Integer(1);
|
||||
}
|
||||
} catch (Exception x) {
|
||||
x.printStackTrace();
|
||||
return new Integer(0);
|
||||
}
|
||||
}
|
||||
})).intValue();
|
||||
}
|
||||
}
|
BIN
test/data/tiddlywiki/java/TiddlySaverVerify.keystore
Executable file
BIN
test/data/tiddlywiki/java/TiddlySaverVerify.keystore
Executable file
Binary file not shown.
38
test/data/tiddlywiki/java/UnaMesa-2.cer
Executable file
38
test/data/tiddlywiki/java/UnaMesa-2.cer
Executable file
@ -0,0 +1,38 @@
|
||||
-----BEGIN PKCS #7 SIGNED DATA-----
|
||||
MIAGCSqGSIb3DQEHAqCAMIACAQExADALBgkqhkiG9w0BBwGggDCCAyIwggKLoAMC
|
||||
AQICEEtycpHmJVBWKTR1fltuZYgwDQYJKoZIhvcNAQEFBQAwVTELMAkGA1UEBhMC
|
||||
WkExJTAjBgNVBAoTHFRoYXd0ZSBDb25zdWx0aW5nIChQdHkpIEx0ZC4xHzAdBgNV
|
||||
BAMTFlRoYXd0ZSBDb2RlIFNpZ25pbmcgQ0EwHhcNMTAwMzA0MDAwMDAwWhcNMTIw
|
||||
MzAzMjM1OTU5WjBvMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTES
|
||||
MBAGA1UEBxMJUGFsbyBBbHRvMRAwDgYDVQQKFAdVbmFNZXNhMRMwEQYDVQQLFApU
|
||||
aWRkbHlXaWtpMRAwDgYDVQQDFAdVbmFNZXNhMIGfMA0GCSqGSIb3DQEBAQUAA4GN
|
||||
ADCBiQKBgQDy7syNTVAWoApezeC5oKYWsS19uO87TgHcwqAG2R6U8pBVuHoKpzL9
|
||||
YpOnwIL3p+l/fHy5T8ghmxdX4d73RtHiHMFIL6ABrSvt/WxUKtyImleBv521pK5P
|
||||
S0sdBJWgWCSIV76YKxHdHTZfU83rNih1IGzxP+96MflXh4wPsVuvcwIDAQABo4HY
|
||||
MIHVMAwGA1UdEwEB/wQCMAAwPgYDVR0fBDcwNTAzoDGgL4YtaHR0cDovL2NybC50
|
||||
aGF3dGUuY29tL1RoYXd0ZUNvZGVTaWduaW5nQ0EuY3JsMB8GA1UdJQQYMBYGCCsG
|
||||
AQUFBwMDBgorBgEEAYI3AgEWMB0GA1UdBAQWMBQwDjAMBgorBgEEAYI3AgEWAwIH
|
||||
gDAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnRoYXd0
|
||||
ZS5jb20wEQYJYIZIAYb4QgEBBAQDAgQQMA0GCSqGSIb3DQEBBQUAA4GBAHgyGc8J
|
||||
hNHrtizy6e4bWDlYBwVJiGPe1h0qTNrL9qGexHfF9Msik9CYCFHHv0NlatkP0g0L
|
||||
ZNkR4pTg7QFPBxfV/fh74SxnzadgyX5vsuohC3n7r7XLZy+vh/jeZR2Qt9QTkyxY
|
||||
AONfQLWpTUvFy6Rqb6KcPmW70s6t7NORkWF1MIIDTjCCAregAwIBAgIBCjANBgkq
|
||||
hkiG9w0BAQUFADCBzjELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2Fw
|
||||
ZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3VsdGlu
|
||||
ZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEh
|
||||
MB8GA1UEAxMYVGhhd3RlIFByZW1pdW0gU2VydmVyIENBMSgwJgYJKoZIhvcNAQkB
|
||||
FhlwcmVtaXVtLXNlcnZlckB0aGF3dGUuY29tMB4XDTAzMDgwNjAwMDAwMFoXDTEz
|
||||
MDgwNTIzNTk1OVowVTELMAkGA1UEBhMCWkExJTAjBgNVBAoTHFRoYXd0ZSBDb25z
|
||||
dWx0aW5nIChQdHkpIEx0ZC4xHzAdBgNVBAMTFlRoYXd0ZSBDb2RlIFNpZ25pbmcg
|
||||
Q0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMa4uSdgrwvjkWll236N7ZHm
|
||||
qvG+1e3+bdQsf9Fwd/smmVe03T8wuNwh6miNgZL8LkuRNYQg8tpKurT85tqI8iDF
|
||||
IZIJR5WgCRymeb6xTB388YpuVNJpofFMkzpB/n3UZHtjRfdgYB0xHaTp0w+L+24m
|
||||
JLOo/+XlkNS0wtxQYK5ZAgMBAAGjgbMwgbAwEgYDVR0TAQH/BAgwBgEB/wIBADBA
|
||||
BgNVHR8EOTA3MDWgM6Axhi9odHRwOi8vY3JsLnRoYXd0ZS5jb20vVGhhd3RlUHJl
|
||||
bWl1bVNlcnZlckNBLmNybDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwMw
|
||||
DgYDVR0PAQH/BAQDAgEGMCkGA1UdEQQiMCCkHjAcMRowGAYDVQQDExFQcml2YXRl
|
||||
TGFiZWwyLTE0NDANBgkqhkiG9w0BAQUFAAOBgQB2spzuE58b9i00kpRFczTcjmsu
|
||||
XPxMfYnrw2jx15kPLh0XyLUWi77NigUG8hlJOgNbBckgjm1S4XaBoMNliiJn5BxT
|
||||
UzdGv7zXL+t7ntAURWxAIQjiXXV2ZjAe9N+Cii+986IMvx3bnxSimnI3TbB3SOhK
|
||||
PwnOVRks7+YHJOGv7AAAMQAAAAAAAAA=
|
||||
-----END PKCS #7 SIGNED DATA-----
|
BIN
test/data/tiddlywiki/java/UnaMesa-3.cer
Executable file
BIN
test/data/tiddlywiki/java/UnaMesa-3.cer
Executable file
Binary file not shown.
BIN
test/data/tiddlywiki/java/UnaMesa.old.cer
Executable file
BIN
test/data/tiddlywiki/java/UnaMesa.old.cer
Executable file
Binary file not shown.
5
test/data/tiddlywiki/java/build
Executable file
5
test/data/tiddlywiki/java/build
Executable file
@ -0,0 +1,5 @@
|
||||
javac -source 1.2 -target 1.2 -g:none TiddlySaver.java
|
||||
jar cf TiddlySaver.jar TiddlySaver*.class
|
||||
# assume you have UnaMesa.keystore in the same directory
|
||||
# and Passphrase for keystore
|
||||
jarsigner -keystore UnaMesa.keystore TiddlySaver.jar BidiX
|
323
test/data/tiddlywiki/java/sign.readme
Executable file
323
test/data/tiddlywiki/java/sign.readme
Executable file
@ -0,0 +1,323 @@
|
||||
|
||||
Readme file for signing TiddlySaver applet
|
||||
|
||||
for verifying see verify.readme file
|
||||
|
||||
1 - HISTORY
|
||||
|
||||
2010 03 06 - BidiX : Signing TiddlySaver.jar with a new Signing Certificate
|
||||
The files were updated with the new process used for signing (sorry my Macbook was configured in French)
|
||||
New signed TiddlySaver.jar was tested with Safari 4.0.4 on MacOS 10.6.2
|
||||
2008 04 06 - BidiX : documentation
|
||||
2008 04 06 - BidiX : create TiddlySaverVerify.keystore
|
||||
2008 03 27 - BidiX : Signing TiddlySaver.jar
|
||||
2008 03 26 - BidiX : obtaining UnaMesa Signing Certificate
|
||||
2008 03 17 - BidiX : Issuing a certificate request to Thawte with a BidiX CSR
|
||||
2003 03 12 - BidiX : Create UnaMesa.keystore with BidiX alias and Private key
|
||||
|
||||
|
||||
2 - UNAMESA.KEYSTORE CREATION
|
||||
|
||||
Using this command:
|
||||
----------------
|
||||
> keytool -genkey -keyalg RSA -alias BidiX -keystore UnaMesa.keystore
|
||||
Tapez le mot de passe du Keystore :
|
||||
Ressaisissez le nouveau mot de passe :
|
||||
Quels sont vos pr?nom et nom ?
|
||||
[Unknown] : BidiX
|
||||
Quel est le nom de votre unit? organisationnelle ?
|
||||
[Unknown] : TiddlyWiki
|
||||
Quelle est le nom de votre organisation ?
|
||||
[Unknown] : UnaMesa
|
||||
Quel est le nom de votre ville de r?sidence ?
|
||||
[Unknown] : Palo Alto
|
||||
Quel est le nom de votre ?tat ou province ?
|
||||
[Unknown] : California
|
||||
Quel est le code de pays ? deux lettres pour cette unit? ?
|
||||
[Unknown] : US
|
||||
Est-ce CN=BidiX, OU=TiddlyWiki, O=UnaMesa, L=Palo Alto, ST=California, C=US ?
|
||||
[non] : OUI
|
||||
|
||||
Sp?cifiez le mot de passe de la cl? pour <BidiX>
|
||||
(appuyez sur Entr?e s'il s'agit du mot de passe du Keystore) :
|
||||
Ressaisissez le nouveau mot de passe :
|
||||
---------------
|
||||
|
||||
For security reasons the Keystore is kept in a safe place in BidiX environment (BidiX @ bidix.info)
|
||||
|
||||
|
||||
3 - CERTICATE REQUEST
|
||||
Using this command :
|
||||
--------------
|
||||
> keytool -certreq -alias BidiX -file certreq -keystore UnaMesa.keystore -storepass "???"
|
||||
> cat certreq
|
||||
-----BEGIN NEW CERTIFICATE REQUEST-----
|
||||
MIIBrTCCARYCAQAwbTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcT
|
||||
...
|
||||
sxoX+IbLVSs4Ye4HDqFodRkmehWBJsdWpQa/yji72pY+eA3fCgTt57VL+san9pPaLcwPfAiL23cD
|
||||
R1j/y2RjQYLpE0PH+vQXn26xNeUDo2OONijyG0RLIX57yA==
|
||||
-----END NEW CERTIFICATE REQUEST-----
|
||||
---------------
|
||||
Certificate received
|
||||
-----BEGIN PKCS #7 SIGNED DATA-----
|
||||
MIAGCSqGSIb3DQEHAqCAMIACAQExADALBgkqhkiG9w0BBwGggDCCAyIwggKLoAMC
|
||||
...
|
||||
PwnOVRks7+YHJOGv7AAAMQAAAAAAAAA=
|
||||
-----END PKCS #7 SIGNED DATA-----
|
||||
copied in UnaMesa-2.cer
|
||||
|
||||
4 - ADDING CERTICATE TO KEYSTORE
|
||||
---------------
|
||||
> keytool -import -alias BidiX -trustcacerts -file UnaMesa-2.cer -keystore UnaMesa.keystore
|
||||
Tapez le mot de passe du Keystore :
|
||||
R?ponse de certificat install?e dans le Keystore
|
||||
---------------
|
||||
List Keystore
|
||||
---------------
|
||||
> keytool -list -v -alias BidiX -keystore UnaMesa.keystore
|
||||
Tapez le mot de passe du Keystore :
|
||||
Nom d'alias : BidiX
|
||||
Date de cr?ation : 6 mars 2010
|
||||
Type dentr?e?: {0}
|
||||
Longueur de cha?ne du certificat : 3
|
||||
Certificat[1]:
|
||||
Propri?taire?: CN=UnaMesa, OU=TiddlyWiki, O=UnaMesa, L=Palo Alto, ST=California, C=US
|
||||
?metteur?: CN=Thawte Code Signing CA, O=Thawte Consulting (Pty) Ltd., C=ZA
|
||||
Num?ro de s?rie?: 4b727291e62550562934757e5b6e6588
|
||||
Valide du?: Thu Mar 04 01:00:00 CET 2010 au?: Sun Mar 04 00:59:59 CET 2012
|
||||
Empreintes du certificat?:
|
||||
MD5?: 1B:79:CE:47:BE:A9:E4:04:2A:DD:04:F5:BA:62:64:AD
|
||||
SHA1?: 42:A9:6F:4D:C3:20:F8:7F:90:1A:1F:A5:66:92:ED:06:38:19:1E:D4
|
||||
Nom de lalgorithme de signature?: {7}
|
||||
Version?: {8}
|
||||
|
||||
Extensions?:
|
||||
|
||||
#1: ObjectId: 2.5.29.19 Criticality=true
|
||||
BasicConstraints:[
|
||||
CA:false
|
||||
PathLen: undefined
|
||||
]
|
||||
|
||||
#2: ObjectId: 1.3.6.1.5.5.7.1.1 Criticality=false
|
||||
AuthorityInfoAccess [
|
||||
[accessMethod: 1.3.6.1.5.5.7.48.1
|
||||
accessLocation: URIName: http://ocsp.thawte.com]
|
||||
]
|
||||
|
||||
#3: ObjectId: 2.5.29.4 Criticality=false
|
||||
|
||||
#4: ObjectId: 2.5.29.31 Criticality=false
|
||||
CRLDistributionPoints [
|
||||
[DistributionPoint:
|
||||
[URIName: http://crl.thawte.com/ThawteCodeSigningCA.crl]
|
||||
]]
|
||||
|
||||
#5: ObjectId: 2.5.29.37 Criticality=false
|
||||
ExtendedKeyUsages [
|
||||
codeSigning
|
||||
1.3.6.1.4.1.311.2.1.22
|
||||
]
|
||||
|
||||
#6: ObjectId: 2.16.840.1.113730.1.1 Criticality=false
|
||||
NetscapeCertType [
|
||||
Object Signing
|
||||
]
|
||||
|
||||
Certificat[2]:
|
||||
Propri?taire?: CN=Thawte Code Signing CA, O=Thawte Consulting (Pty) Ltd., C=ZA
|
||||
?metteur?: EMAILADDRESS=premium-server@thawte.com, CN=Thawte Premium Server CA, OU=Certification Services Division, O=Thawte Consulting cc, L=Cape Town, ST=Western Cape, C=ZA
|
||||
Num?ro de s?rie?: a
|
||||
Valide du?: Wed Aug 06 02:00:00 CEST 2003 au?: Tue Aug 06 01:59:59 CEST 2013
|
||||
Empreintes du certificat?:
|
||||
MD5?: D4:A7:BF:00:7B:6A:0C:20:D9:23:CD:5B:60:7B:7C:12
|
||||
SHA1?: A7:06:BA:1E:CA:B6:A2:AB:18:69:9F:C0:D7:DD:8C:7D:E3:6F:29:0F
|
||||
Nom de lalgorithme de signature?: {7}
|
||||
Version?: {8}
|
||||
|
||||
Extensions?:
|
||||
|
||||
#1: ObjectId: 2.5.29.15 Criticality=true
|
||||
KeyUsage [
|
||||
Key_CertSign
|
||||
Crl_Sign
|
||||
]
|
||||
|
||||
#2: ObjectId: 2.5.29.19 Criticality=true
|
||||
BasicConstraints:[
|
||||
CA:true
|
||||
PathLen:0
|
||||
]
|
||||
|
||||
#3: ObjectId: 2.5.29.31 Criticality=false
|
||||
CRLDistributionPoints [
|
||||
[DistributionPoint:
|
||||
[URIName: http://crl.thawte.com/ThawtePremiumServerCA.crl]
|
||||
]]
|
||||
|
||||
#4: ObjectId: 2.5.29.37 Criticality=false
|
||||
ExtendedKeyUsages [
|
||||
clientAuth
|
||||
codeSigning
|
||||
]
|
||||
|
||||
#5: ObjectId: 2.5.29.17 Criticality=false
|
||||
SubjectAlternativeName [
|
||||
CN=PrivateLabel2-144
|
||||
]
|
||||
|
||||
Certificat[3]:
|
||||
Propri?taire?: EMAILADDRESS=premium-server@thawte.com, CN=Thawte Premium Server CA, OU=Certification Services Division, O=Thawte Consulting cc, L=Cape Town, ST=Western Cape, C=ZA
|
||||
?metteur?: EMAILADDRESS=premium-server@thawte.com, CN=Thawte Premium Server CA, OU=Certification Services Division, O=Thawte Consulting cc, L=Cape Town, ST=Western Cape, C=ZA
|
||||
Num?ro de s?rie?: 1
|
||||
Valide du?: Thu Aug 01 02:00:00 CEST 1996 au?: Fri Jan 01 00:59:59 CET 2021
|
||||
Empreintes du certificat?:
|
||||
MD5?: 06:9F:69:79:16:66:90:02:1B:8C:8C:A2:C3:07:6F:3A
|
||||
SHA1?: 62:7F:8D:78:27:65:63:99:D2:7D:7F:90:44:C9:FE:B3:F3:3E:FA:9A
|
||||
Nom de lalgorithme de signature?: {7}
|
||||
Version?: {8}
|
||||
|
||||
Extensions?:
|
||||
|
||||
#1: ObjectId: 2.5.29.19 Criticality=true
|
||||
BasicConstraints:[
|
||||
CA:true
|
||||
PathLen:2147483647
|
||||
]
|
||||
---------------
|
||||
|
||||
5 - SIGNING TIDDLYSAVER.JAR
|
||||
|
||||
Get TiddlySaver.jar from http://trac.tiddlywiki.org/browser/Trunk/core/java/TiddlySaver.jar.
|
||||
TiddlySaver.jar contained classes compiled on Thu Dec 07 14:48:00 CET 2006
|
||||
|
||||
With UnaMesa.keystore in the current directory Signing jar on Sam 6 mar 2010 15:16:04 CET using this command :
|
||||
---------------
|
||||
> jarsigner -keystore UnaMesa.keystore TiddlySaver.jar BidiX
|
||||
Enter Passphrase for keystore:
|
||||
---------------
|
||||
|
||||
6 - VERIFYING SIGNATURE WITHOUT KEYSTORE
|
||||
---------------
|
||||
> jarsigner -verify -verbose TiddlySaver.jar
|
||||
|
||||
284 Thu Mar 27 07:59:12 CET 2008 META-INF/MANIFEST.MF
|
||||
395 Sat Mar 06 15:16:04 CET 2010 META-INF/BIDIX.SF
|
||||
2798 Sat Mar 06 15:16:04 CET 2010 META-INF/BIDIX.RSA
|
||||
0 Thu Dec 07 14:48:00 CET 2006 META-INF/
|
||||
sm 1271 Thu Dec 07 14:48:00 CET 2006 TiddlySaver$1.class
|
||||
sm 1184 Thu Dec 07 14:48:00 CET 2006 TiddlySaver$2.class
|
||||
sm 775 Thu Dec 07 14:48:00 CET 2006 TiddlySaver.class
|
||||
|
||||
s = signature was verified
|
||||
m = entry is listed in manifest
|
||||
k = at least one certificate was found in keystore
|
||||
i = at least one certificate was found in identity scope
|
||||
|
||||
jar verified.
|
||||
---------------
|
||||
|
||||
7 - CREATE TiddlySaverVerify.keystore KEYSTORE
|
||||
export SigningCertificate
|
||||
---------------
|
||||
> keytool -export -alias BidiX -file UnaMesa-3.cer -keystore UnaMesa.keystore
|
||||
Tapez le mot de passe du Keystore :
|
||||
Certificat enregistr? dans le fichier <UnaMesa-3.cer>
|
||||
---------------
|
||||
create keystore "TiddlySaverVerify.keystore" with "tiddlywiki" as password and import SigningCertificate
|
||||
---------------
|
||||
> keytool -import -alias BidiX -keystore TiddlySaverVerify.keystore -storepass tiddlywiki -file UnaMesa-3.cer
|
||||
Propri?taire?: CN=UnaMesa, OU=TiddlyWiki, O=UnaMesa, L=Palo Alto, ST=California, C=US
|
||||
?metteur?: CN=Thawte Code Signing CA, O=Thawte Consulting (Pty) Ltd., C=ZA
|
||||
Num?ro de s?rie?: 4b727291e62550562934757e5b6e6588
|
||||
Valide du?: Thu Mar 04 01:00:00 CET 2010 au?: Sun Mar 04 00:59:59 CET 2012
|
||||
Empreintes du certificat?:
|
||||
MD5?: 1B:79:CE:47:BE:A9:E4:04:2A:DD:04:F5:BA:62:64:AD
|
||||
SHA1?: 42:A9:6F:4D:C3:20:F8:7F:90:1A:1F:A5:66:92:ED:06:38:19:1E:D4
|
||||
Nom de lalgorithme de signature?: {7}
|
||||
Version?: {8}
|
||||
|
||||
Extensions?:
|
||||
|
||||
#1: ObjectId: 2.5.29.19 Criticality=true
|
||||
BasicConstraints:[
|
||||
CA:false
|
||||
PathLen: undefined
|
||||
]
|
||||
|
||||
#2: ObjectId: 1.3.6.1.5.5.7.1.1 Criticality=false
|
||||
AuthorityInfoAccess [
|
||||
[accessMethod: 1.3.6.1.5.5.7.48.1
|
||||
accessLocation: URIName: http://ocsp.thawte.com]
|
||||
]
|
||||
|
||||
#3: ObjectId: 2.5.29.4 Criticality=false
|
||||
|
||||
#4: ObjectId: 2.5.29.31 Criticality=false
|
||||
CRLDistributionPoints [
|
||||
[DistributionPoint:
|
||||
[URIName: http://crl.thawte.com/ThawteCodeSigningCA.crl]
|
||||
]]
|
||||
|
||||
#5: ObjectId: 2.5.29.37 Criticality=false
|
||||
ExtendedKeyUsages [
|
||||
codeSigning
|
||||
1.3.6.1.4.1.311.2.1.22
|
||||
]
|
||||
|
||||
#6: ObjectId: 2.16.840.1.113730.1.1 Criticality=false
|
||||
NetscapeCertType [
|
||||
Object Signing
|
||||
]
|
||||
|
||||
Faire confiance ? ce certificat ? [non] : Y
|
||||
R?ponse incorrecte, recommencez
|
||||
Faire confiance ? ce certificat ? [non] : oui
|
||||
Certificat ajout? au Keystore
|
||||
---------------
|
||||
|
||||
8 - VERIFYING SIGNATURE WITH TiddlySaverVerify.keystore
|
||||
---------------
|
||||
> jarsigner -verify -verbose -certs -keystore TiddlySaverVerify.keystore TiddlySaver.jar
|
||||
284 Thu Mar 27 07:59:12 CET 2008 META-INF/MANIFEST.MF
|
||||
395 Sat Mar 06 15:16:04 CET 2010 META-INF/BIDIX.SF
|
||||
2798 Sat Mar 06 15:16:04 CET 2010 META-INF/BIDIX.RSA
|
||||
0 Thu Dec 07 14:48:00 CET 2006 META-INF/
|
||||
smk 1271 Thu Dec 07 14:48:00 CET 2006 TiddlySaver$1.class
|
||||
|
||||
X.509, CN=UnaMesa, OU=TiddlyWiki, O=UnaMesa, L=Palo Alto, ST=California, C=US (bidix)
|
||||
[certificate is valid from 04/03/10 01:00 to 04/03/12 00:59]
|
||||
X.509, CN=Thawte Code Signing CA, O=Thawte Consulting (Pty) Ltd., C=ZA
|
||||
[certificate is valid from 06/08/03 02:00 to 06/08/13 01:59]
|
||||
[KeyUsage extension does not support code signing]
|
||||
X.509, EMAILADDRESS=premium-server@thawte.com, CN=Thawte Premium Server CA, OU=Certification Services Division, O=Thawte Consulting cc, L=Cape Town, ST=Western Cape, C=ZA
|
||||
[certificate is valid from 01/08/96 02:00 to 01/01/21 00:59]
|
||||
|
||||
smk 1184 Thu Dec 07 14:48:00 CET 2006 TiddlySaver$2.class
|
||||
|
||||
X.509, CN=UnaMesa, OU=TiddlyWiki, O=UnaMesa, L=Palo Alto, ST=California, C=US (bidix)
|
||||
[certificate is valid from 04/03/10 01:00 to 04/03/12 00:59]
|
||||
X.509, CN=Thawte Code Signing CA, O=Thawte Consulting (Pty) Ltd., C=ZA
|
||||
[certificate is valid from 06/08/03 02:00 to 06/08/13 01:59]
|
||||
[KeyUsage extension does not support code signing]
|
||||
X.509, EMAILADDRESS=premium-server@thawte.com, CN=Thawte Premium Server CA, OU=Certification Services Division, O=Thawte Consulting cc, L=Cape Town, ST=Western Cape, C=ZA
|
||||
[certificate is valid from 01/08/96 02:00 to 01/01/21 00:59]
|
||||
|
||||
smk 775 Thu Dec 07 14:48:00 CET 2006 TiddlySaver.class
|
||||
|
||||
X.509, CN=UnaMesa, OU=TiddlyWiki, O=UnaMesa, L=Palo Alto, ST=California, C=US (bidix)
|
||||
[certificate is valid from 04/03/10 01:00 to 04/03/12 00:59]
|
||||
X.509, CN=Thawte Code Signing CA, O=Thawte Consulting (Pty) Ltd., C=ZA
|
||||
[certificate is valid from 06/08/03 02:00 to 06/08/13 01:59]
|
||||
[KeyUsage extension does not support code signing]
|
||||
X.509, EMAILADDRESS=premium-server@thawte.com, CN=Thawte Premium Server CA, OU=Certification Services Division, O=Thawte Consulting cc, L=Cape Town, ST=Western Cape, C=ZA
|
||||
[certificate is valid from 01/08/96 02:00 to 01/01/21 00:59]
|
||||
|
||||
|
||||
s = signature was verified
|
||||
m = entry is listed in manifest
|
||||
k = at least one certificate was found in keystore
|
||||
i = at least one certificate was found in identity scope
|
||||
|
||||
jar verified.
|
||||
---------------
|
2
test/data/tiddlywiki/java/verify
Executable file
2
test/data/tiddlywiki/java/verify
Executable file
@ -0,0 +1,2 @@
|
||||
# assume TiddlySaverVerify.keystore and TiddlySaver.jar in the current directory
|
||||
jarsigner -verify -verbose -certs -keystore TiddlySaverVerify.keystore -keypass tiddlywiki TiddlySaver.jar
|
46
test/data/tiddlywiki/java/verify.readme
Executable file
46
test/data/tiddlywiki/java/verify.readme
Executable file
@ -0,0 +1,46 @@
|
||||
|
||||
Above the verifying command and the expected return:
|
||||
|
||||
|
||||
> jarsigner -verify -verbose -certs -keystore TiddlySaverVerify.keystore TiddlySaver.jar
|
||||
284 Thu Mar 27 07:59:12 CET 2008 META-INF/MANIFEST.MF
|
||||
395 Sat Mar 06 15:16:04 CET 2010 META-INF/BIDIX.SF
|
||||
2798 Sat Mar 06 15:16:04 CET 2010 META-INF/BIDIX.RSA
|
||||
0 Thu Dec 07 14:48:00 CET 2006 META-INF/
|
||||
smk 1271 Thu Dec 07 14:48:00 CET 2006 TiddlySaver$1.class
|
||||
|
||||
X.509, CN=UnaMesa, OU=TiddlyWiki, O=UnaMesa, L=Palo Alto, ST=California, C=US (bidix)
|
||||
[certificate is valid from 04/03/10 01:00 to 04/03/12 00:59]
|
||||
X.509, CN=Thawte Code Signing CA, O=Thawte Consulting (Pty) Ltd., C=ZA
|
||||
[certificate is valid from 06/08/03 02:00 to 06/08/13 01:59]
|
||||
[KeyUsage extension does not support code signing]
|
||||
X.509, EMAILADDRESS=premium-server@thawte.com, CN=Thawte Premium Server CA, OU=Certification Services Division, O=Thawte Consulting cc, L=Cape Town, ST=Western Cape, C=ZA
|
||||
[certificate is valid from 01/08/96 02:00 to 01/01/21 00:59]
|
||||
|
||||
smk 1184 Thu Dec 07 14:48:00 CET 2006 TiddlySaver$2.class
|
||||
|
||||
X.509, CN=UnaMesa, OU=TiddlyWiki, O=UnaMesa, L=Palo Alto, ST=California, C=US (bidix)
|
||||
[certificate is valid from 04/03/10 01:00 to 04/03/12 00:59]
|
||||
X.509, CN=Thawte Code Signing CA, O=Thawte Consulting (Pty) Ltd., C=ZA
|
||||
[certificate is valid from 06/08/03 02:00 to 06/08/13 01:59]
|
||||
[KeyUsage extension does not support code signing]
|
||||
X.509, EMAILADDRESS=premium-server@thawte.com, CN=Thawte Premium Server CA, OU=Certification Services Division, O=Thawte Consulting cc, L=Cape Town, ST=Western Cape, C=ZA
|
||||
[certificate is valid from 01/08/96 02:00 to 01/01/21 00:59]
|
||||
|
||||
smk 775 Thu Dec 07 14:48:00 CET 2006 TiddlySaver.class
|
||||
|
||||
X.509, CN=UnaMesa, OU=TiddlyWiki, O=UnaMesa, L=Palo Alto, ST=California, C=US (bidix)
|
||||
[certificate is valid from 04/03/10 01:00 to 04/03/12 00:59]
|
||||
X.509, CN=Thawte Code Signing CA, O=Thawte Consulting (Pty) Ltd., C=ZA
|
||||
[certificate is valid from 06/08/03 02:00 to 06/08/13 01:59]
|
||||
[KeyUsage extension does not support code signing]
|
||||
X.509, EMAILADDRESS=premium-server@thawte.com, CN=Thawte Premium Server CA, OU=Certification Services Division, O=Thawte Consulting cc, L=Cape Town, ST=Western Cape, C=ZA
|
||||
[certificate is valid from 01/08/96 02:00 to 01/01/21 00:59]
|
||||
|
||||
|
||||
s = signature was verified
|
||||
m = entry is listed in manifest
|
||||
k = at least one certificate was found in keystore
|
||||
i = at least one certificate was found in identity scope
|
||||
|
||||
jar verified.
|
4
test/data/tiddlywiki/jquery/jquery.js
vendored
Executable file
4
test/data/tiddlywiki/jquery/jquery.js
vendored
Executable file
File diff suppressed because one or more lines are too long
43
test/data/tiddlywiki/jquery/plugins/doc/encoding.digests.sha1.html
Executable file
43
test/data/tiddlywiki/jquery/plugins/doc/encoding.digests.sha1.html
Executable file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>jQuery.encoding.digests.sha1</title>
|
||||
<link rel="stylesheet" type="text/css" href="styles/main.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>jQuery.encoding.digests.sha1</h1>
|
||||
<p>
|
||||
This <a href="http://jquery.com">jQuery</a> plugin implements the SHA-1 cryptographic hash function.
|
||||
</p>
|
||||
|
||||
<h2>Source</h2>
|
||||
<p>
|
||||
The source code is currently hosted in TiddlyWiki's
|
||||
<a href="http://svn.tiddlywiki.org/Trunk/core/jquery/plugins/jQuery.encoding.digests.sha1.js">Subversion repository</a>.
|
||||
</p>
|
||||
<p>
|
||||
<a href="http://groups.google.com/group/TiddlyWikiDev/">Feedback</a> is welcome.
|
||||
</p>
|
||||
|
||||
<h2>API</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<p><code>$.encoding.digests.hexSha1Str(str)</code>: Return, in hex, the SHA-1 hash of a string</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><code>$.encoding.digests.sha1Str(str)</code>: Return the SHA-1 hash of a string</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><code>$.encoding.digests.sha1(x,blen)</code>: Calculate the SHA-1 hash of an array of blen bytes of big-endian 32-bit words</p>
|
||||
</li>
|
||||
</ul>
|
||||
<p>(full documentation in the code comments)</p>
|
||||
|
||||
<h2>Demo</h2>
|
||||
[TBD]
|
||||
</body>
|
||||
|
||||
</html>
|
31
test/data/tiddlywiki/jquery/plugins/doc/index.html
Executable file
31
test/data/tiddlywiki/jquery/plugins/doc/index.html
Executable file
@ -0,0 +1,31 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>TiddlyWiki jQuery plugins</title>
|
||||
<link rel="stylesheet" type="text/css" href="styles/main.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>TiddlyWiki jQuery plugins</h1>
|
||||
<p>
|
||||
With <a href="http://jquery.com">jQuery</a> being integrated into the
|
||||
<a href="http://tiddlywiki.com">TiddlyWiki</a> core, the community has
|
||||
begun extracting TiddlyWiki functionality into generic components in
|
||||
the form of jQuery plugins:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="twFile.html">jQuery.twFile</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="twStylesheet.html">jQuery.twStylesheet</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="encoding.digests.sha1.html">jQuery.encoding.digests.sha1.html</a>
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
|
||||
</html>
|
78
test/data/tiddlywiki/jquery/plugins/doc/styles/main.css
Executable file
78
test/data/tiddlywiki/jquery/plugins/doc/styles/main.css
Executable file
@ -0,0 +1,78 @@
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
html {
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
body {
|
||||
width: 50%;
|
||||
margin: 0 auto;
|
||||
padding: 10px;
|
||||
background-color: #FFF;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
p,
|
||||
ul {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
ul ul {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
li p {
|
||||
margin-bottom: 0.2em;
|
||||
}
|
||||
|
||||
code {
|
||||
color: #0A0;
|
||||
}
|
||||
|
||||
fieldset,
|
||||
legend {
|
||||
border: 1px solid #AAA;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
margin: 30px 10px 10px;
|
||||
padding: 10px 5px 5px 10px;
|
||||
}
|
||||
|
||||
legend,
|
||||
.editor {
|
||||
background-color: #EEE;
|
||||
}
|
||||
|
||||
legend {
|
||||
margin-top: -1em;
|
||||
border-bottom: none;
|
||||
padding: 1px 3px 0;
|
||||
line-height: 1em;
|
||||
}
|
||||
|
||||
fieldset textarea {
|
||||
display: block;
|
||||
width: 98%;
|
||||
}
|
||||
|
||||
fieldset input {
|
||||
width: 5em;
|
||||
margin: 10px 10px 5px 0;
|
||||
font-size: 1.1em;
|
||||
}
|
124
test/data/tiddlywiki/jquery/plugins/doc/twFile.html
Executable file
124
test/data/tiddlywiki/jquery/plugins/doc/twFile.html
Executable file
@ -0,0 +1,124 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>jQuery.twFile</title>
|
||||
<link rel="stylesheet" type="text/css" href="styles/main.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>jQuery.twFile</h1>
|
||||
<p>
|
||||
This <a href="http://jquery.com">jQuery</a> plugin provides access to
|
||||
the local file system (for documents loaded from a <code>file://</code>
|
||||
URI) to load and save file contents from the browser.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The code is based on <a href="http://tiddlywiki.com">TiddlyWiki</a>'s
|
||||
self-saving capabilities.
|
||||
</p>
|
||||
|
||||
<p id="TiddlySaver">
|
||||
Note that the <a href="http://www.tiddlywiki.com/TiddlySaver.jar">TiddlySaver</a>
|
||||
applet is required on Opera and WebKit-based browsers (Safari, Chrome).
|
||||
The applet has to be present in the same folder as the respective HTML document.
|
||||
</p>
|
||||
|
||||
<h2>Source</h2>
|
||||
<p>
|
||||
The source code is currently hosted in TiddlyWiki's
|
||||
<a href="http://svn.tiddlywiki.org/Trunk/core/jquery/plugins/jQuery.twFile.js">Subversion repository</a>.
|
||||
</p>
|
||||
<p>
|
||||
<a href="http://groups.google.com/group/TiddlyWikiDev/">Feedback</a> is welcome.
|
||||
</p>
|
||||
|
||||
<h2>API Summary</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<p><code>$.twFile.load(filePath)</code>: load contents from file</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><code>$.twFile.save(filePath, content)</code>: save contents to file</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><code>$.twFile.copy(dest, source)</code>: duplicate existing file</p>
|
||||
<p><strong>N.B.:</strong> This is not supported on all browsers.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>
|
||||
<code>$.twFile.convertUriToLocalPath(filePath)</code>:
|
||||
normalizes specified absolute file path
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
<strong>N.B.:</strong> All file paths must be absolute (e.g.
|
||||
<code>/tmp/foo.txt</code> or <code>C:\temp\foo.txt</code>).
|
||||
</p>
|
||||
<p>(full documentation in the code comments)</p>
|
||||
|
||||
<h2>Limitations</h2>
|
||||
<ul>
|
||||
<li>
|
||||
plugin unavailable until
|
||||
<a href="http://docs.jquery.com/Events/ready">document.ready</a>
|
||||
handlers have completed
|
||||
<p>
|
||||
Since the TiddlySaver applet cannot be injected synchronously
|
||||
into the document, this is done asynchronously during
|
||||
<code>document.ready</code> processing.
|
||||
</p>
|
||||
<p>
|
||||
This means that the plugin is not guaranteed to work properly
|
||||
until after all these handlers have completed.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
currently unreliable UTF-8 support on Internet Explorer
|
||||
<p>
|
||||
The plugin is designed to work with UTF-8 encoded text files.
|
||||
However, support in Internet Explorer is broken, and can only
|
||||
reliably save files that are encoded with the ANSI subset of
|
||||
UTF-8. In the case of HTML files, this problem can often be
|
||||
avoided by using HTML entity encodings.
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>Internals</h2>
|
||||
<p>
|
||||
Internally, the plugin uses four separate drivers to implement the functionality on different browsers:
|
||||
<ul>
|
||||
<li>
|
||||
<code>activeX</code>: uses the <code>FileSystemObject</code> built into Internet Explorer 5 and above
|
||||
</li>
|
||||
<li>
|
||||
<code>mozilla</code>: uses the XUL libraries built into Firefox
|
||||
</li>
|
||||
<li>
|
||||
<code>tiddlySaver</code>: uses a custom Java applet that works on Safari, Chrome and Opera
|
||||
</li>
|
||||
<li>
|
||||
<code>javaLiveConnect</code>: uses an ancient (and slow) binding technology to call Java runtime library routines directly - only works on Opera
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2>Demo</h2>
|
||||
<p>
|
||||
Download <a href="twFileDemo.html">this document</a> (and
|
||||
<a href="#TiddlySaver">TiddlySaver</a> if necessary) and open it from
|
||||
the local disk.
|
||||
</p>
|
||||
<p>
|
||||
This demo illustrates self-saving capabilities by passing
|
||||
<code>document.location.href</code> to <code>$.twFile.convertUriToLocalPath</code>,
|
||||
using the return value in load and save functions.
|
||||
</p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
435
test/data/tiddlywiki/jquery/plugins/doc/twFileDemo.html
Executable file
435
test/data/tiddlywiki/jquery/plugins/doc/twFileDemo.html
Executable file
File diff suppressed because one or more lines are too long
94
test/data/tiddlywiki/jquery/plugins/doc/twStylesheet.html
Executable file
94
test/data/tiddlywiki/jquery/plugins/doc/twStylesheet.html
Executable file
@ -0,0 +1,94 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>jQuery.twStylesheet</title>
|
||||
<link rel="stylesheet" type="text/css" href="styles/main.css">
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js" type="text/javascript"></script>
|
||||
<script src="http://svn.tiddlywiki.org/Trunk/core/jquery/plugins/jQuery.twStylesheet.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
var applyCSS = function() {
|
||||
var css = $("#css_code").val();
|
||||
$.twStylesheet(css);
|
||||
};
|
||||
|
||||
var resetCSS = function() {
|
||||
$.twStylesheet.remove();
|
||||
};
|
||||
|
||||
$("#css_apply").click(applyCSS);
|
||||
$("#css_reset").click(resetCSS);
|
||||
|
||||
// initialize
|
||||
$("#css_code").val(
|
||||
"html { background-color: #EEE; }\n" +
|
||||
"body { color: #FFF; background-color: #000; }\n" +
|
||||
"h1, h2 { font-variant: small-caps; }\n" +
|
||||
"ul { list-style-type: square; }\n" +
|
||||
"code { padding: 1px 2px; background-color: #EEE; }\n" +
|
||||
"#css_editor, #css_editor legend { background-color: #888; }\n"
|
||||
);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>jQuery.twStylesheet</h1>
|
||||
<p>
|
||||
This <a href="http://jquery.com">jQuery</a> plugin allows the application
|
||||
of CSS rule sets to the document.
|
||||
</p>
|
||||
<p>
|
||||
In contrast to jQuery's <a href="http://docs.jquery.com/CSS">CSS methods</a>,
|
||||
it applies styles to the document rather than to individual elements (just
|
||||
like defining a static style sheet in the document head).
|
||||
</p>
|
||||
<p>
|
||||
The code is based on <a href="http://tiddlywiki.com">TiddlyWiki</a>'s dynamic
|
||||
style-sheet capabilities, where it is used to allow users to customize their
|
||||
documents on the fly.
|
||||
</p>
|
||||
|
||||
<h2>Source</h2>
|
||||
<p>
|
||||
The source code is currently hosted in TiddlyWiki's
|
||||
<a href="http://svn.tiddlywiki.org/Trunk/core/jquery/plugins/jQuery.twStylesheet.js">Subversion repository</a>.
|
||||
</p>
|
||||
<p>
|
||||
<a href="http://groups.google.com/group/TiddlyWikiDev/">Feedback</a> is welcome.
|
||||
</p>
|
||||
|
||||
<h2>API Summary</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<p><code>$.twStylesheet(css[, options])</code>: adds or replaces a style sheet</p>
|
||||
<p>
|
||||
<code>css</code> is a string containing the CSS rule sets, while
|
||||
<code>options.id</code> is an optional name identifying the style sheet, allowing
|
||||
co-existence of multiple style sheets
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>
|
||||
<code>$.twStylesheet.remove([options])</code>: delete an existing style sheet
|
||||
</p>
|
||||
<p>
|
||||
The <code>options</code> argument is identical to <code>$.twStylesheet</code>'s.
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
<p>(full documentation in the code comments)</p>
|
||||
|
||||
<h2>Demo</h2>
|
||||
This will apply the CSS rule sets below to the entire document.
|
||||
<fieldset id="css_editor" class="editor">
|
||||
<legend>CSS</legend>
|
||||
<textarea id="css_code" rows="10" cols="70"></textarea>
|
||||
<input id="css_apply" type="button" value="Apply">
|
||||
<input id="css_reset" type="button" value="Reset">
|
||||
</fieldset>
|
||||
</body>
|
||||
|
||||
</html>
|
13
test/data/tiddlywiki/jquery/plugins/doc/update
Executable file
13
test/data/tiddlywiki/jquery/plugins/doc/update
Executable file
@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Usage:
|
||||
# upload [user]
|
||||
|
||||
REMOTE_USER=${1:-$USER}
|
||||
HOST="jquery.tiddlywiki.org"
|
||||
DIR="/var/www/www.jquery.tiddlywiki.org/htdocs/"
|
||||
|
||||
COMMANDS="ssh $REMOTE_USER@$HOST"
|
||||
COMMANDS="$COMMANDS cd $DIR;"
|
||||
COMMANDS="$COMMANDS sudo svn update;"
|
||||
$COMMANDS
|
155
test/data/tiddlywiki/jquery/plugins/jQuery.encoding.digests.sha1.js
Executable file
155
test/data/tiddlywiki/jquery/plugins/jQuery.encoding.digests.sha1.js
Executable file
@ -0,0 +1,155 @@
|
||||
/*
|
||||
jQuery.encoding.digests.sha1.js
|
||||
|
||||
SHA-1 digest and associated utility functions
|
||||
|
||||
Copyright (c) UnaMesa Association 2009
|
||||
|
||||
Dual licensed under the MIT and GPL licenses:
|
||||
http://www.opensource.org/licenses/mit-license.php
|
||||
http://www.gnu.org/licenses/gpl.html
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
|
||||
if(!$.encoding)
|
||||
$.encoding = {};
|
||||
$.extend($.encoding,{
|
||||
strToBe32s: function(str) {
|
||||
// Convert a string to an array of big-endian 32-bit words
|
||||
var be=[];
|
||||
var len=Math.floor(str.length/4);
|
||||
var i, j;
|
||||
for(i=0, j=0; i<len; i++, j+=4) {
|
||||
be[i]=((str.charCodeAt(j)&0xff) << 24)|((str.charCodeAt(j+1)&0xff) << 16)|((str.charCodeAt(j+2)&0xff) << 8)|(str.charCodeAt(j+3)&0xff);
|
||||
}
|
||||
while(j<str.length) {
|
||||
be[j>>2] |= (str.charCodeAt(j)&0xff)<<(24-(j*8)%32);
|
||||
j++;
|
||||
}
|
||||
return be;
|
||||
},
|
||||
be32sToStr: function(be) {
|
||||
// Convert an array of big-endian 32-bit words to a string
|
||||
var str='';
|
||||
for(var i=0;i<be.length*32;i+=8) {
|
||||
str += String.fromCharCode((be[i>>5]>>>(24-i%32)) & 0xff);
|
||||
}
|
||||
return str;
|
||||
},
|
||||
be32sToHex: function(be) {
|
||||
// Convert an array of big-endian 32-bit words to a hex string
|
||||
var hex='0123456789ABCDEF';
|
||||
var str='';
|
||||
for(var i=0;i<be.length*4;i++) {
|
||||
str += hex.charAt((be[i>>2]>>((3-i%4)*8+4))&0xF) + hex.charAt((be[i>>2]>>((3-i%4)*8))&0xF);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
});
|
||||
})(jQuery);
|
||||
|
||||
|
||||
(function($) {
|
||||
|
||||
if(!$.encoding.digests)
|
||||
$.encoding.digests = {};
|
||||
$.extend($.encoding.digests,{
|
||||
hexSha1Str: function(str) {
|
||||
// Return, in hex, the SHA-1 hash of a string
|
||||
return $.encoding.be32sToHex($.encoding.digests.sha1Str(str));
|
||||
},
|
||||
sha1Str: function(str) {
|
||||
// Return the SHA-1 hash of a string
|
||||
return sha1($.encoding.strToBe32s(str),str.length);
|
||||
},
|
||||
sha1: function(x,blen) {
|
||||
// Calculate the SHA-1 hash of an array of blen bytes of big-endian 32-bit words
|
||||
return sha1($.encoding.strToBe32s(str),str.length);
|
||||
}
|
||||
});
|
||||
|
||||
// Private functions.
|
||||
function sha1(x,blen) {
|
||||
// Calculate the SHA-1 hash of an array of blen bytes of big-endian 32-bit words
|
||||
function add32(a,b) {
|
||||
// Add 32-bit integers, wrapping at 32 bits
|
||||
// Uses 16-bit operations internally to work around bugs in some JavaScript interpreters.
|
||||
var lsw=(a&0xFFFF)+(b&0xFFFF);
|
||||
var msw=(a>>16)+(b>>16)+(lsw>>16);
|
||||
return (msw<<16)|(lsw&0xFFFF);
|
||||
}
|
||||
function AA(a,b,c,d,e) {
|
||||
// Cryptographic round helper function. Add five 32-bit integers, wrapping at 32 bits, second parameter is rotated left 5 bits before the addition
|
||||
// Uses 16-bit operations internally to work around bugs in some JavaScript interpreters.
|
||||
b=(b>>>27)|(b<<5);
|
||||
var lsw=(a&0xFFFF)+(b&0xFFFF)+(c&0xFFFF)+(d&0xFFFF)+(e&0xFFFF);
|
||||
var msw=(a>>16)+(b>>16)+(c>>16)+(d>>16)+(e>>16)+(lsw>>16);
|
||||
return (msw<<16)|(lsw&0xFFFF);
|
||||
}
|
||||
function RR(w,j) {
|
||||
// Cryptographic round helper function.
|
||||
var n=w[j-3]^w[j-8]^w[j-14]^w[j-16];
|
||||
return (n>>>31)|(n<<1);
|
||||
}
|
||||
|
||||
var len=blen*8;
|
||||
//# Append padding so length in bits is 448 mod 512
|
||||
x[len>>5] |= 0x80 << (24-len%32);
|
||||
//# Append length
|
||||
x[((len+64>>9)<<4)+15]=len;
|
||||
var w=new Array(80);
|
||||
|
||||
var k1=0x5A827999;
|
||||
var k2=0x6ED9EBA1;
|
||||
var k3=0x8F1BBCDC;
|
||||
var k4=0xCA62C1D6;
|
||||
|
||||
var h0=0x67452301;
|
||||
var h1=0xEFCDAB89;
|
||||
var h2=0x98BADCFE;
|
||||
var h3=0x10325476;
|
||||
var h4=0xC3D2E1F0;
|
||||
|
||||
for(var i=0;i<x.length;i+=16) {
|
||||
var j=0;
|
||||
var t;
|
||||
var a=h0;
|
||||
var b=h1;
|
||||
var c=h2;
|
||||
var d=h3;
|
||||
var e=h4;
|
||||
while(j<16) {
|
||||
w[j]=x[i+j];
|
||||
t=AA(e,a,d^(b&(c^d)),w[j],k1);
|
||||
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a=t; j++;
|
||||
}
|
||||
while(j<20) {
|
||||
w[j]=RR(w,j);
|
||||
t=AA(e,a,d^(b&(c^d)),w[j],k1);
|
||||
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a=t; j++;
|
||||
}
|
||||
while(j<40) {
|
||||
w[j]=RR(w,j);
|
||||
t=AA(e,a,b^c^d,w[j],k2);
|
||||
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a=t; j++;
|
||||
}
|
||||
while(j<60) {
|
||||
w[j]=RR(w,j);
|
||||
t=AA(e,a,(b&c)|(d&(b|c)),w[j],k3);
|
||||
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a=t; j++;
|
||||
}
|
||||
while(j<80) {
|
||||
w[j]=RR(w,j);
|
||||
t=AA(e,a,b^c^d,w[j],k4);
|
||||
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a=t; j++;
|
||||
}
|
||||
h0=add32(h0,a);
|
||||
h1=add32(h1,b);
|
||||
h2=add32(h2,c);
|
||||
h3=add32(h3,d);
|
||||
h4=add32(h4,e);
|
||||
}
|
||||
return [h0,h1,h2,h3,h4];
|
||||
}
|
||||
})(jQuery);
|
333
test/data/tiddlywiki/jquery/plugins/jQuery.twFile.js
Executable file
333
test/data/tiddlywiki/jquery/plugins/jQuery.twFile.js
Executable file
@ -0,0 +1,333 @@
|
||||
/*
|
||||
jQuery.twFile.js
|
||||
|
||||
jQuery plugin for loading a file and saving data to a file
|
||||
|
||||
Copyright (c) UnaMesa Association 2009
|
||||
|
||||
Triple licensed under the BSD, MIT and GPL licenses:
|
||||
http://www.opensource.org/licenses/bsd-license.php
|
||||
http://www.opensource.org/licenses/mit-license.php
|
||||
http://www.gnu.org/licenses/gpl.html
|
||||
*/
|
||||
|
||||
|
||||
(function($) {
|
||||
if(!$.twFile) {
|
||||
$.twFile = {};
|
||||
}
|
||||
|
||||
$.extend($.twFile,{
|
||||
currentDriver: null,
|
||||
driverList: ["tiddlySaver", "activeX","javaLiveConnect", "mozilla"],
|
||||
|
||||
// Loads the contents of a text file from the local file system
|
||||
// filePath is the path to the file in these formats:
|
||||
// x:\path\path\path\filename - PC local file
|
||||
// \\server\share\path\path\path\filename - PC network file
|
||||
// /path/path/path/filename - Mac/Unix local file
|
||||
// returns the text of the file, or null if the operation cannot be performed or false if there was an error
|
||||
load: function(filePath) {
|
||||
var d = this.getDriver();
|
||||
return d ? d.loadFile(filePath) : null;
|
||||
},
|
||||
// Saves a string to a text file on the local file system
|
||||
// filePath is the path to the file in the format described above
|
||||
// content is the string to save
|
||||
// returns true if the file was saved successfully, or null if the operation cannot be performed or false if there was an error
|
||||
save: function(filePath,content) {
|
||||
var d = this.getDriver();
|
||||
return d ? d.saveFile(filePath,content) : null;
|
||||
},
|
||||
// Copies a file on the local file system
|
||||
// dest is the path to the destination file in the format described above
|
||||
// source is the path to the source file in the format described above
|
||||
// returns true if the file was copied successfully, or null if the operation cannot be performed or false if there was an error
|
||||
copy: function(dest,source) {
|
||||
var d = this.getDriver();
|
||||
if(d && d.copyFile)
|
||||
return d.copyFile(dest,source);
|
||||
else
|
||||
return null;
|
||||
},
|
||||
// Converts a local file path from the format returned by document.location into the format expected by this plugin
|
||||
// url is the original URL of the file
|
||||
// returns the equivalent local file path
|
||||
convertUriToLocalPath: function (url) {
|
||||
// Remove any location or query part of the URL
|
||||
var originalPath = url.split("#")[0].split("?")[0];
|
||||
// Convert file://localhost/ to file:///
|
||||
if(originalPath.indexOf("file://localhost/") == 0)
|
||||
originalPath = "file://" + originalPath.substr(16);
|
||||
// Convert to a native file format
|
||||
//# "file:///x:/path/path/path..." - pc local file --> "x:\path\path\path..."
|
||||
//# "file://///server/share/path/path/path..." - FireFox pc network file --> "\\server\share\path\path\path..."
|
||||
//# "file:///path/path/path..." - mac/unix local file --> "/path/path/path..."
|
||||
//# "file://server/share/path/path/path..." - pc network file --> "\\server\share\path\path\path..."
|
||||
var localPath;
|
||||
if(originalPath.charAt(9) == ":") // PC local file
|
||||
localPath = unescape(originalPath.substr(8)).replace(new RegExp("/","g"),"\\");
|
||||
else if(originalPath.indexOf("file://///") == 0) // Firefox PC network file
|
||||
localPath = "\\\\" + unescape(originalPath.substr(10)).replace(new RegExp("/","g"),"\\");
|
||||
else if(originalPath.indexOf("file:///") == 0) // Mac/UNIX local file
|
||||
localPath = unescape(originalPath.substr(7));
|
||||
else if(originalPath.indexOf("file:/") == 0) // Mac/UNIX local file
|
||||
localPath = unescape(originalPath.substr(5));
|
||||
else if(originalPath.indexOf("//") == 0) // PC network file
|
||||
localPath = "\\\\" + unescape(originalPath.substr(7)).replace(new RegExp("/","g"),"\\");
|
||||
return localPath || originalPath;
|
||||
},
|
||||
|
||||
// Deferred initialization for any drivers that need it
|
||||
// returns a Deferred object so callback that executes as soon
|
||||
// as twFile is ready can be attached
|
||||
initialize: function() {
|
||||
return $.Deferred(function(dfd) {
|
||||
for(var t in drivers) {
|
||||
if(drivers[t].deferredInit)
|
||||
drivers[t].deferredInit();
|
||||
}
|
||||
// Kludge: give the <applet> some time to load
|
||||
setTimeout(dfd.resolve, 0);
|
||||
});
|
||||
},
|
||||
|
||||
// Private functions
|
||||
|
||||
// Returns a reference to the current driver
|
||||
getDriver: function() {
|
||||
if(this.currentDriver === null) {
|
||||
for(var t=0; t<this.driverList.length; t++) {
|
||||
if(this.currentDriver === null && drivers[this.driverList[t]].isAvailable && drivers[this.driverList[t]].isAvailable())
|
||||
this.currentDriver = drivers[this.driverList[t]];
|
||||
}
|
||||
}
|
||||
return this.currentDriver;
|
||||
}
|
||||
});
|
||||
|
||||
// Automatically initialize on document.ready()
|
||||
$(function() {
|
||||
$.twFile.initialize();
|
||||
});
|
||||
|
||||
// Private driver implementations for each browser
|
||||
|
||||
var drivers = {};
|
||||
|
||||
// Internet Explorer driver
|
||||
|
||||
drivers.activeX = {
|
||||
name: "activeX",
|
||||
isAvailable: function() {
|
||||
try {
|
||||
var fso = new ActiveXObject("Scripting.FileSystemObject");
|
||||
} catch(ex) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
loadFile: function(filePath) {
|
||||
// Returns null if it can't do it, false if there's an error, or a string of the content if successful
|
||||
try {
|
||||
var fso = new ActiveXObject("Scripting.FileSystemObject");
|
||||
var file = fso.OpenTextFile(filePath,1);
|
||||
var content = file.ReadAll();
|
||||
file.Close();
|
||||
} catch(ex) {
|
||||
//# alert("Exception while attempting to load\n\n" + ex.toString());
|
||||
return null;
|
||||
}
|
||||
return content;
|
||||
},
|
||||
createPath: function(path) {
|
||||
//# Remove the filename, if present. Use trailing slash (i.e. "foo\bar\") if no filename.
|
||||
var pos = path.lastIndexOf("\\");
|
||||
if(pos!=-1)
|
||||
path = path.substring(0,pos+1);
|
||||
//# Walk up the path until we find a folder that exists
|
||||
var scan = [path];
|
||||
try {
|
||||
var fso = new ActiveXObject("Scripting.FileSystemObject");
|
||||
var parent = fso.GetParentFolderName(path);
|
||||
while(parent && !fso.FolderExists(parent)) {
|
||||
scan.push(parent);
|
||||
parent = fso.GetParentFolderName(parent);
|
||||
}
|
||||
//# Walk back down the path, creating folders
|
||||
for(i=scan.length-1;i>=0;i--) {
|
||||
if(!fso.FolderExists(scan[i])) {
|
||||
fso.CreateFolder(scan[i]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch(ex) {
|
||||
}
|
||||
return false;
|
||||
},
|
||||
copyFile: function(dest,source) {
|
||||
drivers.activeX.createPath(dest);
|
||||
try {
|
||||
var fso = new ActiveXObject("Scripting.FileSystemObject");
|
||||
fso.GetFile(source).Copy(dest);
|
||||
} catch(ex) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
saveFile: function(filePath,content) {
|
||||
// Returns null if it can't do it, false if there's an error, true if it saved OK
|
||||
drivers.activeX.createPath(filePath);
|
||||
try {
|
||||
var fso = new ActiveXObject("Scripting.FileSystemObject");
|
||||
var file = fso.OpenTextFile(filePath,2,-1,0);
|
||||
file.Write(content);
|
||||
file.Close();
|
||||
} catch (ex) {
|
||||
return null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// Mozilla driver
|
||||
|
||||
drivers.mozilla = {
|
||||
name: "mozilla",
|
||||
isAvailable: function() {
|
||||
return !!window.Components;
|
||||
},
|
||||
loadFile: function(filePath) {
|
||||
// Returns null if it can't do it, false if there's an error, or a string of the content if successful
|
||||
if(window.Components) {
|
||||
try {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
|
||||
file.initWithPath(filePath);
|
||||
if(!file.exists())
|
||||
return null;
|
||||
var inputStream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
|
||||
inputStream.init(file,0x01,00004,null);
|
||||
var sInputStream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
|
||||
sInputStream.init(inputStream);
|
||||
var contents = sInputStream.read(sInputStream.available());
|
||||
sInputStream.close();
|
||||
inputStream.close();
|
||||
return contents;
|
||||
} catch(ex) {
|
||||
//# alert("Exception while attempting to load\n\n" + ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
saveFile: function(filePath,content) {
|
||||
// Returns null if it can't do it, false if there's an error, true if it saved OK
|
||||
if(window.Components) {
|
||||
try {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
|
||||
file.initWithPath(filePath);
|
||||
if(!file.exists())
|
||||
file.create(0,0664);
|
||||
var out = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
|
||||
out.init(file,0x20|0x02,00004,null);
|
||||
out.write(content,content.length);
|
||||
out.flush();
|
||||
out.close();
|
||||
return true;
|
||||
} catch(ex) {
|
||||
alert("Exception while attempting to save\n\n" + ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
// TiddlySaver driver
|
||||
|
||||
drivers.tiddlySaver = {
|
||||
name: "tiddlySaver",
|
||||
deferredInit: function() {
|
||||
if(!document.applets["TiddlySaver"] && /* !$.browser.mozilla && !$.browser.msie && */ document.location.toString().substr(0,5) == "file:") {
|
||||
$(document.body).append("<applet style='position:absolute;left:-1px' name='TiddlySaver' code='TiddlySaver.class' archive='TiddlySaver.jar' width='1'height='1'></applet>");
|
||||
}
|
||||
},
|
||||
isAvailable: function() {
|
||||
var isReady = false;
|
||||
try {
|
||||
isReady = !!document.applets["TiddlySaver"] &&
|
||||
($.browser.msie || document.applets["TiddlySaver"].isActive) &&
|
||||
( document.applets["TiddlySaver"].isActive() );
|
||||
} catch (ex) {
|
||||
isReady = false;
|
||||
}
|
||||
return isReady;
|
||||
},
|
||||
loadFile: function(filePath) {
|
||||
var r;
|
||||
try {
|
||||
if(document.applets["TiddlySaver"]) {
|
||||
r = document.applets["TiddlySaver"].loadFile(javaUrlToFilename(filePath),"UTF-8");
|
||||
return (r === undefined || r === null) ? null : String(r);
|
||||
}
|
||||
} catch(ex) {
|
||||
}
|
||||
return null;
|
||||
},
|
||||
saveFile: function(filePath,content) {
|
||||
try {
|
||||
if(document.applets["TiddlySaver"])
|
||||
return document.applets["TiddlySaver"].saveFile(javaUrlToFilename(filePath),"UTF-8",content);
|
||||
} catch(ex) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
// Java LiveConnect driver
|
||||
|
||||
drivers.javaLiveConnect = {
|
||||
name: "javaLiveConnect",
|
||||
isAvailable: function() {
|
||||
return !!window.java && !!window.java.io && !!window.java.io.FileReader;
|
||||
},
|
||||
loadFile: function(filePath) {
|
||||
var r;
|
||||
var content = [];
|
||||
try {
|
||||
r = new java.io.BufferedReader(new java.io.FileReader(javaUrlToFilename(filePath)));
|
||||
var line;
|
||||
while((line = r.readLine()) != null)
|
||||
content.push(new String(line));
|
||||
r.close();
|
||||
} catch(ex) {
|
||||
return null;
|
||||
}
|
||||
return content.join("\n") + "\n";
|
||||
},
|
||||
saveFile: function(filePath,content) {
|
||||
try {
|
||||
var s = new java.io.PrintStream(new java.io.FileOutputStream(javaUrlToFilename(filePath)));
|
||||
s.print(content);
|
||||
s.close();
|
||||
} catch(ex) {
|
||||
return null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// Private utilities
|
||||
|
||||
function javaUrlToFilename(url) {
|
||||
var f = "//localhost";
|
||||
if(url.indexOf(f) == 0)
|
||||
return url.substring(f.length);
|
||||
var i = url.indexOf(":");
|
||||
return i > 0 ? url.substring(i-1) : url;
|
||||
}
|
||||
|
||||
})(jQuery);
|
||||
|
64
test/data/tiddlywiki/jquery/plugins/jQuery.twStylesheet.js
Executable file
64
test/data/tiddlywiki/jquery/plugins/jQuery.twStylesheet.js
Executable file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
jQuery.twStylesheet.js
|
||||
|
||||
jQuery plugin to dynamically insert CSS rules into a document
|
||||
|
||||
Usage:
|
||||
jQuery.twStylesheet applies style definitions
|
||||
jQuery.twStylesheet.remove neutralizes style definitions
|
||||
|
||||
Copyright (c) UnaMesa Association 2009
|
||||
|
||||
Triple licensed under the BSD, MIT and GPL licenses:
|
||||
http://www.opensource.org/licenses/bsd-license.php
|
||||
http://www.opensource.org/licenses/mit-license.php
|
||||
http://www.gnu.org/licenses/gpl.html
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
|
||||
var defaultId = "customStyleSheet"; // XXX: rename to dynamicStyleSheet?
|
||||
|
||||
// Add or replace a style sheet
|
||||
// css argument is a string of CSS rule sets
|
||||
// options.id is an optional name identifying the style sheet
|
||||
// options.doc is an optional document reference
|
||||
// N.B.: Uses DOM methods instead of jQuery to ensure cross-browser comaptibility.
|
||||
$.twStylesheet = function(css, options) {
|
||||
options = options || {};
|
||||
var id = options.id || defaultId;
|
||||
var doc = options.doc || document;
|
||||
var el = doc.getElementById(id);
|
||||
if(doc.createStyleSheet) { // IE-specific handling
|
||||
if(el) {
|
||||
el.parentNode.removeChild(el);
|
||||
}
|
||||
doc.getElementsByTagName("head")[0].insertAdjacentHTML("beforeEnd",
|
||||
' <style id="' + id + '" type="text/css">' + css + '</style>'); // fails without
|
||||
} else { // modern browsers
|
||||
if(el) {
|
||||
el.replaceChild(doc.createTextNode(css), el.firstChild);
|
||||
} else {
|
||||
el = doc.createElement("style");
|
||||
el.type = "text/css";
|
||||
el.id = id;
|
||||
el.appendChild(doc.createTextNode(css));
|
||||
doc.getElementsByTagName("head")[0].appendChild(el);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Remove existing style sheet
|
||||
// options.id is an optional name identifying the style sheet
|
||||
// options.doc is an optional document reference
|
||||
$.twStylesheet.remove = function(options) {
|
||||
options = options || {};
|
||||
var id = options.id || defaultId;
|
||||
var doc = options.doc || document;
|
||||
var el = doc.getElementById(id);
|
||||
if(el) {
|
||||
el.parentNode.removeChild(el);
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
139
test/data/tiddlywiki/jquery/plugins/jquery.gettext-1.0.4.js
Executable file
139
test/data/tiddlywiki/jquery/plugins/jquery.gettext-1.0.4.js
Executable file
@ -0,0 +1,139 @@
|
||||
/**
|
||||
* gettext for jQuery
|
||||
*
|
||||
* Copyright (c) 2008 Sabin Iacob (m0n5t3r) <iacobs@m0n5t3r.info>
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* @license http://www.gnu.org/licenses/gpl.html
|
||||
* @project jquery.gettext
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* This plugin expects its input data to be a JSON object like
|
||||
* {"": header, "string": "translation", ...}
|
||||
*
|
||||
* After getting the server side set up (either as a static file - my choice - or
|
||||
* as a web service), the client side is simple:
|
||||
* * add to the head section of the page something like
|
||||
* <link href="path/to/translation.json" lang="ro" rel="gettext"/>
|
||||
* * in your script, use $.gt.gettext(string) or _(string); for plural forms, use
|
||||
* $.gt.ngettext(sg, pl1[, pl2, ...], count) or n_(sg, pl1[, pl2, ...], count)
|
||||
* * to extract strings to a .po file, you can use standard gettext utilities like
|
||||
* xgettext and msgfmt; to generate the JSON, one could use the following Python
|
||||
* snippet, assuming a domain.mo file exists under path/lang/LC_MESSAGES:
|
||||
*
|
||||
* import simplejson as enc
|
||||
*
|
||||
* def gettext_json(domain, path, lang = [], indent = False):
|
||||
* try:
|
||||
* tr = gettext.translation(domain, path, lang)
|
||||
* return enc.dumps(tr._catalog, ensure_ascii = False, indent = indent)
|
||||
* except IOError:
|
||||
* return None
|
||||
*
|
||||
* why go through the additional hassle of gettext? well, it's a matter of
|
||||
* preference, the main advantags I see are:
|
||||
* * well known editing tools like KBabel, poEdit, gtranslator, Emacs PO mode,
|
||||
* etc.
|
||||
* * translation memory, fuzzy matches and other features that get really
|
||||
* helpful when your application is big and you have hundreds of strings
|
||||
*/
|
||||
(function($) {
|
||||
$.gt = $.gt || {};
|
||||
|
||||
$.extend($.gt, {
|
||||
messages: {},
|
||||
lang: 'C',
|
||||
setLang: function(code) { $.gt.lang = typeof code == 'string' && code != ' ' ? code : 'C'; },
|
||||
pl_re: /^Plural-Forms:\s*nplurals\s*=\s*(\d+);\s*plural\s*=\s*([^a-zA-Z0-9\$]*([a-zA-Z0-9\$]+).+)$/m,
|
||||
plural: function(n) {return n != 1;},
|
||||
load: function() {
|
||||
$('link[rel=gettext]').each(function(){
|
||||
var lang = this.lang;
|
||||
$.get(this.href, function(data){
|
||||
$.gt.messages[lang] = $.gt.messages[lang] || {};
|
||||
try {
|
||||
var messages = eval('(' + data + ')');
|
||||
} catch(e) {
|
||||
return;
|
||||
}
|
||||
|
||||
$.extend($.gt.messages[lang], messages);
|
||||
|
||||
var pl = $.gt.pl_re.exec($.gt.messages[lang]['']);
|
||||
if(pl){
|
||||
var expr = pl[2];
|
||||
var np = pl[1];
|
||||
var v = pl[3];
|
||||
try {
|
||||
var fn = eval('(function(' + v + ') {return ' + expr + ';})');
|
||||
} catch(e) {
|
||||
return;
|
||||
}
|
||||
$.gt.plural = fn;
|
||||
}
|
||||
});
|
||||
});
|
||||
$.gt.setLang($('html').attr('lang'));
|
||||
},
|
||||
gettext: function(msgstr) {
|
||||
var lang = $.gt.lang;
|
||||
|
||||
if(lang == 'C' || typeof $.gt.messages[lang] == 'undefined') {
|
||||
return msgstr;
|
||||
}
|
||||
|
||||
var trans = $.gt.messages[lang][msgstr];
|
||||
|
||||
if(typeof trans == 'string') { // regular action
|
||||
return trans;
|
||||
} else if(typeof trans == 'object' && trans.constructor == Array) { // the translation contains plural(s), yet gettext was called
|
||||
return trans[0];
|
||||
}
|
||||
return msgstr;
|
||||
},
|
||||
ngettext: function() {
|
||||
var lang = $.gt.lang;
|
||||
var argv = Array.apply(null, arguments);
|
||||
var cnt = argv[argv.length - 1];
|
||||
var sg = argv[0];
|
||||
var pls = argv.slice(0, -1);
|
||||
|
||||
var trans = pls;
|
||||
|
||||
if(lang != 'C' && typeof $.gt.messages[lang] != 'undefined') {
|
||||
trans = $.gt.messages[lang][sg];
|
||||
}
|
||||
|
||||
if(typeof trans == 'string') { // called ngettext, but no plural forms available :-?
|
||||
return trans;
|
||||
} else if(typeof trans == 'object' && trans.constructor == Array) {
|
||||
var pl = $.gt.plural(cnt);
|
||||
if(typeof pl == 'boolean' && pls.length == 2) {
|
||||
pl = pl ? 1 : 0;
|
||||
}
|
||||
if(typeof pl == 'number' && pl < trans.length) {
|
||||
return trans[pl];
|
||||
}
|
||||
}
|
||||
return sg;
|
||||
}
|
||||
});
|
||||
|
||||
$('document').ready($.gt.load);
|
||||
})(jQuery);
|
||||
|
||||
if(typeof _ == 'undefined') {
|
||||
var _ = jQuery.gt.gettext;
|
||||
}
|
||||
if(typeof n_ == 'undefined') {
|
||||
var n_ = jQuery.gt.ngettext;
|
||||
}
|
10
test/data/tiddlywiki/jquery/plugins/obsolete/jquery.tw.js
Executable file
10
test/data/tiddlywiki/jquery/plugins/obsolete/jquery.tw.js
Executable file
@ -0,0 +1,10 @@
|
||||
/*
|
||||
jquery.tw.js
|
||||
addition of tw 'namespace'
|
||||
*/
|
||||
(function($) {
|
||||
if(!$.tw) {
|
||||
$.tw = {};
|
||||
$.tw.extend = $.extend;
|
||||
}
|
||||
})(jQuery);
|
58
test/data/tiddlywiki/jquery/plugins/obsolete/jquery.tw.macro.js
Executable file
58
test/data/tiddlywiki/jquery/plugins/obsolete/jquery.tw.macro.js
Executable file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
jquery.tw.macro.js
|
||||
macro parameter expansion
|
||||
*/
|
||||
(function($) {
|
||||
$.tw.extend({
|
||||
expandMacroParams: function(params) {
|
||||
// expand the macro parameters into a name:value hash
|
||||
// all parameters are also given a numeric name, starting at 1
|
||||
var opts = {};
|
||||
var unnamed = 1;
|
||||
var name,val;
|
||||
var t = $.trim(params);
|
||||
var s = 0;
|
||||
var i = findNakedSpace(t,s);
|
||||
var param = i==-1 ? t.substr(s) : t.substring(s,i);
|
||||
while(true) {
|
||||
var ci = param.indexOf(':');
|
||||
if(ci==-1) {
|
||||
// parameter is unnamed
|
||||
name = param ? unnamed++ : null;
|
||||
val = param;
|
||||
} else {
|
||||
name = param.substr(0,ci);
|
||||
val = param.substr(ci+1);
|
||||
}
|
||||
val = $.trim(val);
|
||||
if(val.charAt(0)=='"' && val.charAt(val.length-1)=='"') {
|
||||
val = val.substr(1,val.length-2);
|
||||
}
|
||||
if(name)
|
||||
opts[name] = val;
|
||||
if(i==-1)
|
||||
break;
|
||||
s = i+1;
|
||||
i = findNakedSpace(t,s);
|
||||
param = i==-1 ? t.substr(s) : t.substring(s,i);
|
||||
}
|
||||
return opts;
|
||||
}
|
||||
});
|
||||
|
||||
// Private functions.
|
||||
function findNakedSpace(text,start) {
|
||||
// find the next space not surrounded by quotes
|
||||
var d = text.indexOf(' ',start);
|
||||
if(d==-1)
|
||||
return -1;
|
||||
var qs = text.indexOf('"',start);
|
||||
if(qs==-1 || qs > d)
|
||||
return d;
|
||||
var qe = text.indexOf('"',qs+1);
|
||||
if(qe==-1)
|
||||
return d;
|
||||
return findNakedSpace(text,qe+1);
|
||||
}
|
||||
|
||||
})(jQuery);
|
15
test/data/tiddlywiki/jquery/plugins/obsolete/jquery.tw.macro.today.js
Executable file
15
test/data/tiddlywiki/jquery/plugins/obsolete/jquery.tw.macro.today.js
Executable file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
jquery.tw.macro.today.js
|
||||
jQuery TiddlyWiki <<today>> macro
|
||||
*/
|
||||
(function($) {
|
||||
$.fn.tw_today = function(args) {
|
||||
args.format = args.format || args[1];
|
||||
var opts = $.extend({},$.fn.tw_today.defaults,args);
|
||||
var now = new Date();
|
||||
var text = now.formatString(opts.format.trim());
|
||||
this.append("<span>"+text+"</span>");
|
||||
return this;
|
||||
};
|
||||
$.fn.tw_today.defaults = {format:"ddd mmm 0DD 0hh:0mm:0ss YYYY"};
|
||||
})(jQuery);
|
2
test/data/tiddlywiki/jquery/plugins/split.recipe
Executable file
2
test/data/tiddlywiki/jquery/plugins/split.recipe
Executable file
@ -0,0 +1,2 @@
|
||||
jquery: jQuery.encoding.digests.sha1.js
|
||||
jquery: jQuery.twStylesheet.js
|
BIN
test/data/tiddlywiki/jquery/plugins/test/TiddlySaver.jar
Executable file
BIN
test/data/tiddlywiki/jquery/plugins/test/TiddlySaver.jar
Executable file
Binary file not shown.
25
test/data/tiddlywiki/jquery/plugins/test/jQuery.twFile.html
Executable file
25
test/data/tiddlywiki/jquery/plugins/test/jQuery.twFile.html
Executable file
@ -0,0 +1,25 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Tests</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../../test/qunit/testsuite.css">
|
||||
<script src="../../jquery-1.3.2.min.js" type="text/javascript"></script>
|
||||
<!-- test suite -->
|
||||
<script src="../../../test/qunit/testrunner.js" type="text/javascript"></script>
|
||||
<script src="../../../test/qunit/raiseAssertion.js" type="text/javascript"></script>
|
||||
<!-- plugin -->
|
||||
<script src="../jQuery.twFile.js" type="text/javascript"></script>
|
||||
<!-- test code -->
|
||||
<script src="js/jQuery.twFile.js" type="text/javascript"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2 id="banner"></h2>
|
||||
<h2 id="userAgent"></h2>
|
||||
<ol id="tests"></ol>
|
||||
<div id="main"></div>
|
||||
</body>
|
||||
|
||||
</html>
|
25
test/data/tiddlywiki/jquery/plugins/test/jQuery.twStylesheet.html
Executable file
25
test/data/tiddlywiki/jquery/plugins/test/jQuery.twStylesheet.html
Executable file
@ -0,0 +1,25 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Tests</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../../test/qunit/testsuite.css">
|
||||
<script src="../../jquery-1.3.2.min.js" type="text/javascript"></script>
|
||||
<!-- test suite -->
|
||||
<script src="../../../test/qunit/testrunner.js" type="text/javascript"></script>
|
||||
<script src="../../../test/qunit/raiseAssertion.js" type="text/javascript"></script>
|
||||
<!-- plugin -->
|
||||
<script src="../jQuery.twStylesheet.js" type="text/javascript"></script>
|
||||
<!-- test code -->
|
||||
<script src="js/jQuery.twStylesheet.js" type="text/javascript"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2 id="banner"></h2>
|
||||
<h2 id="userAgent"></h2>
|
||||
<ol id="tests"></ol>
|
||||
<div id="main"></div>
|
||||
</body>
|
||||
|
||||
</html>
|
86
test/data/tiddlywiki/jquery/plugins/test/js/jQuery.twFile.js
Executable file
86
test/data/tiddlywiki/jquery/plugins/test/js/jQuery.twFile.js
Executable file
@ -0,0 +1,86 @@
|
||||
jQuery(document).ready(function() {
|
||||
module("jQuery.twFile");
|
||||
|
||||
test("load", function() {
|
||||
var actual, expected, filepath;
|
||||
|
||||
actual = jQuery.twFile.load();
|
||||
expected = null;
|
||||
same(actual, expected, "returns null if no argument is specified");
|
||||
|
||||
filepath = getDocumentPath() + "/sample.txt";
|
||||
actual = jQuery.twFile.load(filepath);
|
||||
expected = "lorem ipsum\n" +
|
||||
"dolor sit amet\n" +
|
||||
"\n" +
|
||||
" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~\n" +
|
||||
"foo bar baz\n";
|
||||
same(actual, expected, "returns contents of specified file");
|
||||
|
||||
filepath = "/null";
|
||||
actual = jQuery.twFile.load(filepath);
|
||||
expected = null;
|
||||
same(actual, expected, "returns null if the specified file does not exist");
|
||||
|
||||
filepath = "sample.txt";
|
||||
actual = jQuery.twFile.load(filepath);
|
||||
expected = null;
|
||||
same(actual, expected, "returns null if specified file path is not absolute");
|
||||
});
|
||||
|
||||
test("save", function() {
|
||||
var actual, expression, expected, str;
|
||||
var filepath = getDocumentPath() + "/savetest.txt";
|
||||
|
||||
/* disabled as browser-level exceptions cannot be trapped
|
||||
expression = function() { jQuery.twFile.save(); };
|
||||
expected = "ReferenceError";
|
||||
raises(expression, expected, "raises exception if no argument is specified");
|
||||
*/
|
||||
|
||||
/* disabled as browser-level exceptions cannot be trapped
|
||||
expression = function() { jQuery.twFile.save(filepath); };
|
||||
expected = "TypeError";
|
||||
raises(expression, expected, "raises exception if no content argument is specified");
|
||||
*/
|
||||
|
||||
/* disabled as browser-level exceptions cannot be trapped
|
||||
expression = function() { jQuery.twFile.save("foo.txt", "sample content"); };
|
||||
expected = "ReferenceError";
|
||||
raises(expression, expected, "raises exception if specified file path is not absolute");
|
||||
*/
|
||||
|
||||
str = "lorem ipsum\n" +
|
||||
"dolor sit amet\n" +
|
||||
"\n" +
|
||||
" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~\n" +
|
||||
//"\xa9\u010d\u010c\n" +
|
||||
"foo bar baz\n" +
|
||||
(new Date).toString();
|
||||
saveAndLoadString(filepath, str, "writes given ANSI text content to specified file");
|
||||
|
||||
//str = "\xa9\u010d\u010c";
|
||||
//saveAndLoadString(filepath, str, "writes given UTF-8 text content to specified file");
|
||||
|
||||
//jQuery.twFile.save(filepath, ""); // teardown: blank file contents (deletion impossible)
|
||||
});
|
||||
|
||||
// helper function to save and load back a string to a file
|
||||
var saveAndLoadString = function(filepath,str,desc) {
|
||||
jQuery.twFile.save(filepath, str);
|
||||
var actual = jQuery.twFile.load(filepath);
|
||||
same(actual, str, desc);
|
||||
}
|
||||
|
||||
// helper function to retrieve current document's file path
|
||||
var getDocumentPath = function() {
|
||||
var path = document.location.pathname;
|
||||
var startpos = 0;
|
||||
var endpos = path.lastIndexOf("/");
|
||||
if(path.charAt(2) == ":") {
|
||||
startpos = 1;
|
||||
path = path.replace(new RegExp("/","g"),"\\")
|
||||
}
|
||||
return unescape(path.substring(startpos, endpos));
|
||||
};
|
||||
});
|
69
test/data/tiddlywiki/jquery/plugins/test/js/jQuery.twStylesheet.js
Executable file
69
test/data/tiddlywiki/jquery/plugins/test/js/jQuery.twStylesheet.js
Executable file
@ -0,0 +1,69 @@
|
||||
jQuery(document).ready(function() {
|
||||
module("jQuery.twStylesheet");
|
||||
|
||||
test("apply", function() {
|
||||
var actual, expected, el;
|
||||
|
||||
el = jQuery('<div />').appendTo(document.body);
|
||||
jQuery.twStylesheet("div { overflow: hidden; }");
|
||||
actual = jQuery(el).css("overflow");
|
||||
expected = "hidden";
|
||||
same(actual, expected, "applies style definitions to document");
|
||||
// teardown
|
||||
jQuery(el).remove();
|
||||
jQuery.twStylesheet.remove();
|
||||
|
||||
el = jQuery('<div />').appendTo(document.body);
|
||||
jQuery.twStylesheet("div { font-style: italic; }");
|
||||
actual = jQuery(el).css("font-style");
|
||||
expected = "italic";
|
||||
same(actual, expected, "applies style definitions to newly-created elements");
|
||||
// teardown
|
||||
jQuery(el).remove();
|
||||
jQuery.twStylesheet.remove();
|
||||
|
||||
jQuery.twStylesheet("", { id: "dummyStyleSheet" });
|
||||
actual = jQuery("#dummyStyleSheet").length;
|
||||
expected = 1;
|
||||
same(actual, expected, "generates style element using given ID");
|
||||
// teardown
|
||||
jQuery.twStylesheet.remove({ id: "dummyStyleSheet" });
|
||||
|
||||
// TODO: test for options.doc argument
|
||||
|
||||
});
|
||||
|
||||
test("remove", function() {
|
||||
var actual, expected;
|
||||
|
||||
// setup
|
||||
el = jQuery('<div />').appendTo(document.body);
|
||||
jQuery.twStylesheet("div { overflow: hidden; }");
|
||||
// test
|
||||
jQuery.twStylesheet.remove();
|
||||
actual = jQuery(el).css("overflow");
|
||||
expected = "visible";
|
||||
same(actual, expected, "neutralizes style definitions");
|
||||
// teardown
|
||||
jQuery(el).remove();
|
||||
|
||||
// setup
|
||||
jQuery.twStylesheet("");
|
||||
// test
|
||||
jQuery.twStylesheet.remove();
|
||||
actual = jQuery("#customStyleSheet").length;
|
||||
expected = 0;
|
||||
same(actual, expected, "removes default style sheet if no ID is given");
|
||||
|
||||
// setup
|
||||
jQuery.twStylesheet("", { id: "dummyStyleSheet" });
|
||||
// test
|
||||
jQuery.twStylesheet.remove({ id: "dummyStyleSheet" });
|
||||
actual = jQuery("#dummyStyleSheet").length;
|
||||
expected = 0;
|
||||
same(actual, expected, "removes style element using given ID");
|
||||
|
||||
// TODO: test for options.doc argument
|
||||
|
||||
});
|
||||
});
|
5
test/data/tiddlywiki/jquery/plugins/test/sample.txt
Executable file
5
test/data/tiddlywiki/jquery/plugins/test/sample.txt
Executable file
@ -0,0 +1,5 @@
|
||||
lorem ipsum
|
||||
dolor sit amet
|
||||
|
||||
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~
|
||||
foo bar baz
|
2
test/data/tiddlywiki/jquery/split.recipe
Executable file
2
test/data/tiddlywiki/jquery/split.recipe
Executable file
@ -0,0 +1,2 @@
|
||||
jslib: jquery.js
|
||||
recipe: plugins/split.recipe
|
90
test/data/tiddlywiki/js/AdaptorBase.js
Executable file
90
test/data/tiddlywiki/js/AdaptorBase.js
Executable file
@ -0,0 +1,90 @@
|
||||
//--
|
||||
//-- Server adaptor base class
|
||||
//--
|
||||
|
||||
function AdaptorBase()
|
||||
{
|
||||
this.host = null;
|
||||
this.store = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
AdaptorBase.prototype.close = function()
|
||||
{
|
||||
return true;
|
||||
};
|
||||
|
||||
AdaptorBase.prototype.fullHostName = function(host)
|
||||
{
|
||||
if(!host)
|
||||
return '';
|
||||
host = host.trim();
|
||||
if(!host.match(/:\/\//))
|
||||
host = 'http://' + host;
|
||||
if(host.substr(host.length-1) == '/')
|
||||
host = host.substr(0,host.length-1);
|
||||
return host;
|
||||
};
|
||||
|
||||
AdaptorBase.minHostName = function(host)
|
||||
{
|
||||
return host;
|
||||
};
|
||||
|
||||
AdaptorBase.prototype.setContext = function(context,userParams,callback)
|
||||
{
|
||||
if(!context) context = {};
|
||||
context.userParams = userParams;
|
||||
if(callback) context.callback = callback;
|
||||
context.adaptor = this;
|
||||
if(!context.host)
|
||||
context.host = this.host;
|
||||
context.host = this.fullHostName(context.host);
|
||||
if(!context.workspace)
|
||||
context.workspace = this.workspace;
|
||||
return context;
|
||||
};
|
||||
|
||||
// Open the specified host
|
||||
//# host - uri of host (eg, "http://www.tiddlywiki.com/" or "www.tiddlywiki.com")
|
||||
//# context is itself passed on as a parameter to the callback function
|
||||
//# userParams - user settable object object that is passed on unchanged to the callback function
|
||||
//# callback - optional function to be called on completion
|
||||
//# Return value is true if the request was successfully issued, false if this connector doesn't support openHost(),
|
||||
//# or an error description string if there was a problem
|
||||
//# The callback parameters are callback(context)
|
||||
//# context.status - true if OK, string if error
|
||||
//# context.adaptor - reference to this adaptor object
|
||||
//# userParams - parameters as originally passed into the openHost function
|
||||
AdaptorBase.prototype.openHost = function(host,context,userParams,callback)
|
||||
{
|
||||
this.host = host;
|
||||
context = this.setContext(context,userParams,callback);
|
||||
context.status = true;
|
||||
if(callback)
|
||||
window.setTimeout(function() {context.callback(context,userParams);},10);
|
||||
return true;
|
||||
};
|
||||
|
||||
// Open the specified workspace
|
||||
//# workspace - name of workspace to open
|
||||
//# context - passed on as a parameter to the callback function
|
||||
//# userParams - user settable object object that is passed on unchanged to the callback function
|
||||
//# callback - function to be called on completion
|
||||
//# Return value is true if the request was successfully issued
|
||||
//# or an error description string if there was a problem
|
||||
//# The callback parameters are callback(context,userParams)
|
||||
//# context.status - true if OK, false if error
|
||||
//# context.statusText - error message if there was an error
|
||||
//# context.adaptor - reference to this adaptor object
|
||||
//# userParams - parameters as originally passed into the openWorkspace function
|
||||
AdaptorBase.prototype.openWorkspace = function(workspace,context,userParams,callback)
|
||||
{
|
||||
this.workspace = workspace;
|
||||
context = this.setContext(context,userParams,callback);
|
||||
context.status = true;
|
||||
if(callback)
|
||||
window.setTimeout(function() {callback(context,userParams);},10);
|
||||
return true;
|
||||
};
|
||||
|
46
test/data/tiddlywiki/js/Animator.js
Executable file
46
test/data/tiddlywiki/js/Animator.js
Executable file
@ -0,0 +1,46 @@
|
||||
//-
|
||||
//- Animation engine
|
||||
//-
|
||||
|
||||
function Animator()
|
||||
{
|
||||
this.running = 0; // Incremented at start of each animation, decremented afterwards. If zero, the interval timer is disabled
|
||||
this.timerID = 0; // ID of the timer used for animating
|
||||
this.animations = []; // List of animations in progress
|
||||
return this;
|
||||
}
|
||||
|
||||
// Start animation engine
|
||||
Animator.prototype.startAnimating = function() //# Variable number of arguments
|
||||
{
|
||||
var t;
|
||||
for(t=0; t<arguments.length; t++)
|
||||
this.animations.push(arguments[t]);
|
||||
if(this.running == 0) {
|
||||
var me = this;
|
||||
this.timerID = window.setInterval(function() {me.doAnimate(me);},10);
|
||||
}
|
||||
this.running += arguments.length;
|
||||
};
|
||||
|
||||
// Perform an animation engine tick, calling each of the known animation modules
|
||||
Animator.prototype.doAnimate = function(me)
|
||||
{
|
||||
var a = 0;
|
||||
while(a < me.animations.length) {
|
||||
var animation = me.animations[a];
|
||||
if(animation.tick()) {
|
||||
a++;
|
||||
} else {
|
||||
me.animations.splice(a,1);
|
||||
if(--me.running == 0)
|
||||
window.clearInterval(me.timerID);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Animator.slowInSlowOut = function(progress)
|
||||
{
|
||||
return(1-((Math.cos(progress * Math.PI)+1)/2));
|
||||
};
|
||||
|
187
test/data/tiddlywiki/js/Backstage.js
Executable file
187
test/data/tiddlywiki/js/Backstage.js
Executable file
@ -0,0 +1,187 @@
|
||||
//--
|
||||
//-- Backstage
|
||||
//--
|
||||
// Backstage tasks
|
||||
config.tasks.save.action = saveChanges;
|
||||
|
||||
var backstage = {
|
||||
area: null,
|
||||
toolbar: null,
|
||||
button: null,
|
||||
showButton: null,
|
||||
hideButton: null,
|
||||
cloak: null,
|
||||
panel: null,
|
||||
panelBody: null,
|
||||
panelFooter: null,
|
||||
currTabName: null,
|
||||
currTabElem: null,
|
||||
content: null,
|
||||
|
||||
init: function() {
|
||||
var cmb = config.messages.backstage;
|
||||
this.area = document.getElementById("backstageArea");
|
||||
this.toolbar = jQuery("#backstageToolbar").empty()[0];
|
||||
this.button = jQuery("#backstageButton").empty()[0];
|
||||
this.button.style.display = "block";
|
||||
var t = cmb.open.text + " " + glyph("bentArrowLeft");
|
||||
this.showButton = createTiddlyButton(this.button,t,cmb.open.tooltip,
|
||||
function(e) {backstage.show(); return false;},null,"backstageShow");
|
||||
t = glyph("bentArrowRight") + " " + cmb.close.text;
|
||||
this.hideButton = createTiddlyButton(this.button,t,cmb.close.tooltip,
|
||||
function(e) {backstage.hide(); return false;},null,"backstageHide");
|
||||
this.cloak = document.getElementById("backstageCloak");
|
||||
this.panel = document.getElementById("backstagePanel");
|
||||
this.panelFooter = createTiddlyElement(this.panel,"div",null,"backstagePanelFooter");
|
||||
this.panelBody = createTiddlyElement(this.panel,"div",null,"backstagePanelBody");
|
||||
this.cloak.onmousedown = function(e) {backstage.switchTab(null);};
|
||||
createTiddlyText(this.toolbar,cmb.prompt);
|
||||
for(t=0; t<config.backstageTasks.length; t++) {
|
||||
var taskName = config.backstageTasks[t];
|
||||
var task = config.tasks[taskName];
|
||||
var handler = task.action ? this.onClickCommand : this.onClickTab;
|
||||
var text = task.text + (task.action ? "" : glyph("downTriangle"));
|
||||
var btn = createTiddlyButton(this.toolbar,text,task.tooltip,handler,"backstageTab");
|
||||
jQuery(btn).addClass(task.action ? "backstageAction" : "backstageTask");
|
||||
btn.setAttribute("task", taskName);
|
||||
}
|
||||
this.content = document.getElementById("contentWrapper");
|
||||
if(config.options.chkBackstage)
|
||||
this.show();
|
||||
else
|
||||
this.hide();
|
||||
},
|
||||
|
||||
isVisible: function() {
|
||||
return this.area ? this.area.style.display == "block" : false;
|
||||
},
|
||||
|
||||
show: function() {
|
||||
this.area.style.display = "block";
|
||||
if(anim && config.options.chkAnimate) {
|
||||
backstage.toolbar.style.left = findWindowWidth() + "px";
|
||||
var p = [{style: "left", start: findWindowWidth(), end: 0, template: "%0px"}];
|
||||
anim.startAnimating(new Morpher(backstage.toolbar,config.animDuration,p));
|
||||
} else {
|
||||
backstage.area.style.left = "0px";
|
||||
}
|
||||
jQuery(this.showButton).hide();
|
||||
jQuery(this.hideButton).show();
|
||||
config.options.chkBackstage = true;
|
||||
saveOption("chkBackstage");
|
||||
jQuery(this.content).addClass("backstageVisible");
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
if(this.currTabElem) {
|
||||
this.switchTab(null);
|
||||
} else {
|
||||
backstage.toolbar.style.left = "0px";
|
||||
if(anim && config.options.chkAnimate) {
|
||||
var p = [{style: "left", start: 0, end: findWindowWidth(), template: "%0px"}];
|
||||
var c = function(element,properties) {backstage.area.style.display = "none";};
|
||||
anim.startAnimating(new Morpher(backstage.toolbar,config.animDuration,p,c));
|
||||
} else {
|
||||
this.area.style.display = "none";
|
||||
}
|
||||
this.showButton.style.display = "block";
|
||||
this.hideButton.style.display = "none";
|
||||
config.options.chkBackstage = false;
|
||||
saveOption("chkBackstage");
|
||||
jQuery(this.content).removeClass("backstageVisible");
|
||||
}
|
||||
},
|
||||
|
||||
onClickCommand: function(e) {
|
||||
var task = config.tasks[this.getAttribute("task")];
|
||||
if(task.action) {
|
||||
backstage.switchTab(null);
|
||||
task.action();
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
onClickTab: function(e) {
|
||||
backstage.switchTab(this.getAttribute("task"));
|
||||
return false;
|
||||
},
|
||||
|
||||
// Switch to a given tab, or none if null is passed
|
||||
switchTab: function(tabName) {
|
||||
var tabElem = null;
|
||||
var e = this.toolbar.firstChild;
|
||||
while(e) {
|
||||
if(e.getAttribute && e.getAttribute("task") == tabName)
|
||||
tabElem = e;
|
||||
e = e.nextSibling;
|
||||
}
|
||||
if(tabName == backstage.currTabName) {
|
||||
backstage.hidePanel();
|
||||
return;
|
||||
}
|
||||
if(backstage.currTabElem) {
|
||||
jQuery(this.currTabElem).removeClass("backstageSelTab");
|
||||
}
|
||||
if(tabElem && tabName) {
|
||||
backstage.preparePanel();
|
||||
jQuery(tabElem).addClass("backstageSelTab");
|
||||
var task = config.tasks[tabName];
|
||||
wikify(task.content,backstage.panelBody,null,null);
|
||||
backstage.showPanel();
|
||||
} else if(backstage.currTabElem) {
|
||||
backstage.hidePanel();
|
||||
}
|
||||
backstage.currTabName = tabName;
|
||||
backstage.currTabElem = tabElem;
|
||||
},
|
||||
|
||||
isPanelVisible: function() {
|
||||
return backstage.panel ? backstage.panel.style.display == "block" : false;
|
||||
},
|
||||
|
||||
preparePanel: function() {
|
||||
backstage.cloak.style.height = findWindowHeight() + "px";
|
||||
backstage.cloak.style.display = "block";
|
||||
jQuery(backstage.panelBody).empty();
|
||||
return backstage.panelBody;
|
||||
},
|
||||
|
||||
showPanel: function() {
|
||||
backstage.panel.style.display = "block";
|
||||
if(anim && config.options.chkAnimate) {
|
||||
backstage.panel.style.top = (-backstage.panel.offsetHeight) + "px";
|
||||
var p = [{style: "top", start: -backstage.panel.offsetHeight, end: 0, template: "%0px"}];
|
||||
anim.startAnimating(new Morpher(backstage.panel,config.animDuration,p),new Scroller(backstage.panel,false));
|
||||
} else {
|
||||
backstage.panel.style.top = "0px";
|
||||
}
|
||||
return backstage.panelBody;
|
||||
},
|
||||
|
||||
hidePanel: function() {
|
||||
if(backstage.currTabElem)
|
||||
jQuery(backstage.currTabElem).removeClass("backstageSelTab");
|
||||
backstage.currTabElem = null;
|
||||
backstage.currTabName = null;
|
||||
if(anim && config.options.chkAnimate) {
|
||||
var p = [
|
||||
{style: "top", start: 0, end: -(backstage.panel.offsetHeight), template: "%0px"},
|
||||
{style: "display", atEnd: "none"}
|
||||
];
|
||||
var c = function(element,properties) {backstage.cloak.style.display = "none";};
|
||||
anim.startAnimating(new Morpher(backstage.panel,config.animDuration,p,c));
|
||||
} else {
|
||||
jQuery([backstage.panel,backstage.cloak]).hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
config.macros.backstage = {};
|
||||
|
||||
config.macros.backstage.handler = function(place,macroName,params)
|
||||
{
|
||||
var backstageTask = config.tasks[params[0]];
|
||||
if(backstageTask)
|
||||
createTiddlyButton(place,backstageTask.text,backstageTask.tooltip,function(e) {backstage.switchTab(params[0]); return false;});
|
||||
};
|
||||
|
103
test/data/tiddlywiki/js/BasicTypes.js
Executable file
103
test/data/tiddlywiki/js/BasicTypes.js
Executable file
@ -0,0 +1,103 @@
|
||||
//--
|
||||
//-- Augmented methods for the JavaScript Array() object
|
||||
//--
|
||||
|
||||
// Add indexOf function if browser does not support it
|
||||
if(!Array.indexOf) {
|
||||
Array.prototype.indexOf = function(item,from)
|
||||
{
|
||||
if(!from)
|
||||
from = 0;
|
||||
var i;
|
||||
for(i=from; i<this.length; i++) {
|
||||
if(this[i] === item)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
};}
|
||||
|
||||
// Find an entry in a given field of the members of an array
|
||||
Array.prototype.findByField = function(field,value)
|
||||
{
|
||||
var t;
|
||||
for(t=0; t<this.length; t++) {
|
||||
if(this[t][field] === value)
|
||||
return t;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
// Return whether an entry exists in an array
|
||||
Array.prototype.contains = function(item)
|
||||
{
|
||||
return this.indexOf(item) != -1;
|
||||
};
|
||||
|
||||
// Adds, removes or toggles a particular value within an array
|
||||
// value - value to add
|
||||
// mode - +1 to add value, -1 to remove value, 0 to toggle it
|
||||
Array.prototype.setItem = function(value,mode)
|
||||
{
|
||||
var p = this.indexOf(value);
|
||||
if(mode == 0)
|
||||
mode = (p == -1) ? +1 : -1;
|
||||
if(mode == +1) {
|
||||
if(p == -1)
|
||||
this.push(value);
|
||||
} else if(mode == -1) {
|
||||
if(p != -1)
|
||||
this.splice(p,1);
|
||||
}
|
||||
};
|
||||
|
||||
// Return whether one of a list of values exists in an array
|
||||
Array.prototype.containsAny = function(items)
|
||||
{
|
||||
var i;
|
||||
for(i=0; i<items.length; i++) {
|
||||
if(this.indexOf(items[i]) != -1)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// Return whether all of a list of values exists in an array
|
||||
Array.prototype.containsAll = function(items)
|
||||
{
|
||||
var i;
|
||||
for(i = 0; i<items.length; i++) {
|
||||
if(this.indexOf(items[i]) == -1)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
// Push a new value into an array only if it is not already present in the array. If the optional unique parameter is false, it reverts to a normal push
|
||||
Array.prototype.pushUnique = function(item,unique)
|
||||
{
|
||||
if(unique === false) {
|
||||
this.push(item);
|
||||
} else {
|
||||
if(this.indexOf(item) == -1)
|
||||
this.push(item);
|
||||
}
|
||||
};
|
||||
|
||||
Array.prototype.remove = function(item)
|
||||
{
|
||||
var p = this.indexOf(item);
|
||||
if(p != -1)
|
||||
this.splice(p,1);
|
||||
};
|
||||
|
||||
if(!Array.prototype.map) {
|
||||
Array.prototype.map = function(fn,thisObj)
|
||||
{
|
||||
var scope = thisObj || window;
|
||||
var i,j,a = [];
|
||||
for(i=0, j=this.length; i < j; ++i) {
|
||||
a.push(fn.call(scope,this[i],i,this));
|
||||
}
|
||||
return a;
|
||||
};}
|
||||
|
178
test/data/tiddlywiki/js/Commands.js
Executable file
178
test/data/tiddlywiki/js/Commands.js
Executable file
@ -0,0 +1,178 @@
|
||||
//--
|
||||
//-- Menu and toolbar commands
|
||||
//--
|
||||
|
||||
config.commands.closeTiddler.handler = function(event,src,title)
|
||||
{
|
||||
if(story.isDirty(title) && !readOnly) {
|
||||
if(!confirm(config.commands.cancelTiddler.warning.format([title])))
|
||||
return false;
|
||||
}
|
||||
story.setDirty(title,false);
|
||||
story.closeTiddler(title,true);
|
||||
return false;
|
||||
};
|
||||
|
||||
config.commands.closeOthers.handler = function(event,src,title)
|
||||
{
|
||||
story.closeAllTiddlers(title);
|
||||
return false;
|
||||
};
|
||||
|
||||
config.commands.editTiddler.handler = function(event,src,title)
|
||||
{
|
||||
clearMessage();
|
||||
var tiddlerElem = story.getTiddler(title);
|
||||
var fields = tiddlerElem.getAttribute("tiddlyFields");
|
||||
story.displayTiddler(null,title,DEFAULT_EDIT_TEMPLATE,false,null,fields);
|
||||
var e = story.getTiddlerField(title,config.options.txtEditorFocus||"text");
|
||||
if(e) {
|
||||
setCaretPosition(e,0);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
config.commands.saveTiddler.handler = function(event,src,title)
|
||||
{
|
||||
var newTitle = story.saveTiddler(title,event.shiftKey);
|
||||
if(newTitle)
|
||||
story.displayTiddler(null,newTitle);
|
||||
return false;
|
||||
};
|
||||
|
||||
config.commands.cancelTiddler.handler = function(event,src,title)
|
||||
{
|
||||
if(story.hasChanges(title) && !readOnly) {
|
||||
if(!confirm(this.warning.format([title])))
|
||||
return false;
|
||||
}
|
||||
story.setDirty(title,false);
|
||||
story.displayTiddler(null,title);
|
||||
return false;
|
||||
};
|
||||
|
||||
config.commands.deleteTiddler.handler = function(event,src,title)
|
||||
{
|
||||
var deleteIt = true;
|
||||
if(config.options.chkConfirmDelete)
|
||||
deleteIt = confirm(this.warning.format([title]));
|
||||
if(deleteIt) {
|
||||
store.removeTiddler(title);
|
||||
story.closeTiddler(title,true);
|
||||
autoSaveChanges();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
config.commands.permalink.handler = function(event,src,title)
|
||||
{
|
||||
var t = encodeURIComponent(String.encodeTiddlyLink(title));
|
||||
if(window.location.hash != t)
|
||||
window.location.hash = t;
|
||||
return false;
|
||||
};
|
||||
|
||||
config.commands.references.handlePopup = function(popup,title)
|
||||
{
|
||||
var references = store.getReferringTiddlers(title);
|
||||
var c = false;
|
||||
var r;
|
||||
for(r=0; r<references.length; r++) {
|
||||
if(references[r].title != title && !references[r].isTagged("excludeLists")) {
|
||||
createTiddlyLink(createTiddlyElement(popup,"li"),references[r].title,true);
|
||||
c = true;
|
||||
}
|
||||
}
|
||||
if(!c)
|
||||
createTiddlyElement(popup,"li",null,"disabled",this.popupNone);
|
||||
};
|
||||
|
||||
config.commands.jump.handlePopup = function(popup,title)
|
||||
{
|
||||
story.forEachTiddler(function(title,element) {
|
||||
createTiddlyLink(createTiddlyElement(popup,"li"),title,true,null,false,null,true);
|
||||
});
|
||||
};
|
||||
|
||||
config.commands.syncing.handlePopup = function(popup,title)
|
||||
{
|
||||
var me = config.commands.syncing;
|
||||
var tiddler = store.fetchTiddler(title);
|
||||
if(!tiddler)
|
||||
return;
|
||||
var serverType = tiddler.getServerType();
|
||||
var serverHost = tiddler.fields["server.host"];
|
||||
var serverWorkspace = tiddler.fields["server.workspace"];
|
||||
if(!serverWorkspace)
|
||||
serverWorkspace = "";
|
||||
if(serverType) {
|
||||
var e = createTiddlyElement(popup,"li",null,"popupMessage");
|
||||
e.innerHTML = me.currentlySyncing.format([serverType,serverHost,serverWorkspace]);
|
||||
} else {
|
||||
createTiddlyElement(popup,"li",null,"popupMessage",me.notCurrentlySyncing);
|
||||
}
|
||||
if(serverType) {
|
||||
createTiddlyElement(createTiddlyElement(popup,"li",null,"listBreak"),"div");
|
||||
var btn = createTiddlyButton(createTiddlyElement(popup,"li"),this.captionUnSync,null,me.onChooseServer);
|
||||
btn.setAttribute("tiddler",title);
|
||||
btn.setAttribute("server.type","");
|
||||
}
|
||||
createTiddlyElement(createTiddlyElement(popup,"li",null,"listBreak"),"div");
|
||||
createTiddlyElement(popup,"li",null,"popupMessage",me.chooseServer);
|
||||
var feeds = store.getTaggedTiddlers("systemServer","title");
|
||||
var t;
|
||||
for(t=0; t<feeds.length; t++) {
|
||||
var f = feeds[t];
|
||||
var feedServerType = store.getTiddlerSlice(f.title,"Type");
|
||||
if(!feedServerType)
|
||||
feedServerType = "file";
|
||||
var feedServerHost = store.getTiddlerSlice(f.title,"URL");
|
||||
if(!feedServerHost)
|
||||
feedServerHost = "";
|
||||
var feedServerWorkspace = store.getTiddlerSlice(f.title,"Workspace");
|
||||
if(!feedServerWorkspace)
|
||||
feedServerWorkspace = "";
|
||||
var caption = f.title;
|
||||
if(serverType == feedServerType && serverHost == feedServerHost && serverWorkspace == feedServerWorkspace) {
|
||||
caption = me.currServerMarker + caption;
|
||||
} else {
|
||||
caption = me.notCurrServerMarker + caption;
|
||||
}
|
||||
btn = createTiddlyButton(createTiddlyElement(popup,"li"),caption,null,me.onChooseServer);
|
||||
btn.setAttribute("tiddler",title);
|
||||
btn.setAttribute("server.type",feedServerType);
|
||||
btn.setAttribute("server.host",feedServerHost);
|
||||
btn.setAttribute("server.workspace",feedServerWorkspace);
|
||||
}
|
||||
};
|
||||
|
||||
config.commands.syncing.onChooseServer = function(e)
|
||||
{
|
||||
var tiddler = this.getAttribute("tiddler");
|
||||
var serverType = this.getAttribute("server.type");
|
||||
if(serverType) {
|
||||
store.addTiddlerFields(tiddler,{
|
||||
"server.type": serverType,
|
||||
"server.host": this.getAttribute("server.host"),
|
||||
"server.workspace": this.getAttribute("server.workspace")
|
||||
});
|
||||
} else {
|
||||
store.setValue(tiddler,"server",null);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
config.commands.fields.handlePopup = function(popup,title)
|
||||
{
|
||||
var tiddler = store.fetchTiddler(title);
|
||||
if(!tiddler)
|
||||
return;
|
||||
var items = [];
|
||||
store.forEachField(tiddler,function(tiddler,fieldName,value){items.push({field:fieldName,value:value});},true);
|
||||
items.sort(function(a,b) {return a.field < b.field ? -1 : (a.field == b.field ? 0 : +1);});
|
||||
if(items.length > 0)
|
||||
ListView.create(popup,items,this.listViewTemplate);
|
||||
else
|
||||
createTiddlyElement(popup,"div",null,null,this.emptyText);
|
||||
};
|
||||
|
227
test/data/tiddlywiki/js/Config.js
Executable file
227
test/data/tiddlywiki/js/Config.js
Executable file
@ -0,0 +1,227 @@
|
||||
//--
|
||||
//-- Configuration repository
|
||||
//--
|
||||
|
||||
// Miscellaneous options
|
||||
var config = {
|
||||
numRssItems: 20, // Number of items in the RSS feed
|
||||
animDuration: 400, // Duration of UI animations in milliseconds
|
||||
cascadeFast: 20, // Speed for cascade animations (higher == slower)
|
||||
cascadeSlow: 60, // Speed for EasterEgg cascade animations
|
||||
cascadeDepth: 5, // Depth of cascade animation
|
||||
locale: "en" // W3C language tag
|
||||
};
|
||||
|
||||
// Hashmap of alternative parsers for the wikifier
|
||||
config.parsers = {};
|
||||
|
||||
// Adaptors
|
||||
config.adaptors = {};
|
||||
config.defaultAdaptor = null;
|
||||
|
||||
// Backstage tasks
|
||||
config.tasks = {};
|
||||
|
||||
// Annotations
|
||||
config.annotations = {};
|
||||
|
||||
// Custom fields to be automatically added to new tiddlers
|
||||
config.defaultCustomFields = {};
|
||||
|
||||
// Messages
|
||||
config.messages = {
|
||||
messageClose: {},
|
||||
dates: {},
|
||||
tiddlerPopup: {}
|
||||
};
|
||||
|
||||
// Options that can be set in the options panel and/or cookies
|
||||
config.options = {
|
||||
chkRegExpSearch: false,
|
||||
chkCaseSensitiveSearch: false,
|
||||
chkIncrementalSearch: true,
|
||||
chkAnimate: true,
|
||||
chkSaveBackups: true,
|
||||
chkAutoSave: false,
|
||||
chkGenerateAnRssFeed: false,
|
||||
chkSaveEmptyTemplate: false,
|
||||
chkOpenInNewWindow: true,
|
||||
chkToggleLinks: false,
|
||||
chkHttpReadOnly: true,
|
||||
chkForceMinorUpdate: false,
|
||||
chkConfirmDelete: true,
|
||||
chkInsertTabs: false,
|
||||
chkUsePreForStorage: true, // Whether to use <pre> format for storage
|
||||
chkDisplayInstrumentation: false,
|
||||
txtBackupFolder: "",
|
||||
txtEditorFocus: "text",
|
||||
txtMainTab: "tabTimeline",
|
||||
txtMoreTab: "moreTabAll",
|
||||
txtMaxEditRows: "30",
|
||||
txtFileSystemCharSet: "UTF-8",
|
||||
txtTheme: ""
|
||||
};
|
||||
config.optionsDesc = {};
|
||||
|
||||
//# config.optionSource["chkAnimate"] can be:
|
||||
//# cookie: the option gets stored in a cookie, with the default value coming from SystemSettings
|
||||
//# volatile: the option isn't persisted at all, and reverts to the default specified in SystemSettings when the document is reloaded
|
||||
//# setting: the option is stored in the SystemSettings tiddler
|
||||
//# The default is "setting"
|
||||
config.optionsSource = {};
|
||||
|
||||
// Default tiddler templates
|
||||
var DEFAULT_VIEW_TEMPLATE = 1;
|
||||
var DEFAULT_EDIT_TEMPLATE = 2;
|
||||
config.tiddlerTemplates = {
|
||||
1: "ViewTemplate",
|
||||
2: "EditTemplate"
|
||||
};
|
||||
|
||||
// More messages (rather a legacy layout that should not really be like this)
|
||||
config.views = {
|
||||
wikified: {
|
||||
tag: {}
|
||||
},
|
||||
editor: {
|
||||
tagChooser: {}
|
||||
}
|
||||
};
|
||||
|
||||
// Backstage tasks
|
||||
config.backstageTasks = ["save","sync","importTask","tweak","upgrade","plugins"];
|
||||
|
||||
// Extensions
|
||||
config.extensions = {};
|
||||
|
||||
// Macros; each has a 'handler' member that is inserted later
|
||||
config.macros = {
|
||||
today: {},
|
||||
version: {},
|
||||
search: {sizeTextbox: 15},
|
||||
tiddler: {},
|
||||
tag: {},
|
||||
tags: {},
|
||||
tagging: {},
|
||||
timeline: {},
|
||||
allTags: {},
|
||||
list: {
|
||||
all: {},
|
||||
missing: {},
|
||||
orphans: {},
|
||||
shadowed: {},
|
||||
touched: {},
|
||||
filter: {}
|
||||
},
|
||||
closeAll: {},
|
||||
permaview: {},
|
||||
saveChanges: {},
|
||||
slider: {},
|
||||
option: {},
|
||||
options: {},
|
||||
newTiddler: {},
|
||||
newJournal: {},
|
||||
tabs: {},
|
||||
gradient: {},
|
||||
message: {},
|
||||
view: {defaultView: "text"},
|
||||
edit: {},
|
||||
tagChooser: {},
|
||||
toolbar: {},
|
||||
plugins: {},
|
||||
refreshDisplay: {},
|
||||
importTiddlers: {},
|
||||
upgrade: {
|
||||
source: "http://tiddlywiki-releases.tiddlyspace.com/upgrade",
|
||||
backupExtension: "pre.core.upgrade"
|
||||
},
|
||||
sync: {},
|
||||
annotations: {}
|
||||
};
|
||||
|
||||
// Commands supported by the toolbar macro
|
||||
config.commands = {
|
||||
closeTiddler: {},
|
||||
closeOthers: {},
|
||||
editTiddler: {},
|
||||
saveTiddler: {hideReadOnly: true},
|
||||
cancelTiddler: {},
|
||||
deleteTiddler: {hideReadOnly: true},
|
||||
permalink: {},
|
||||
references: {type: "popup"},
|
||||
jump: {type: "popup"},
|
||||
syncing: {type: "popup"},
|
||||
fields: {type: "popup"}
|
||||
};
|
||||
|
||||
// Control of macro parameter evaluation
|
||||
config.evaluateMacroParameters = "all";
|
||||
|
||||
// Basic regular expressions
|
||||
config.textPrimitives = {
|
||||
upperLetter: "[A-Z\u00c0-\u00de\u0150\u0170]",
|
||||
lowerLetter: "[a-z0-9_\\-\u00df-\u00ff\u0151\u0171]",
|
||||
anyLetter: "[A-Za-z0-9_\\-\u00c0-\u00de\u00df-\u00ff\u0150\u0170\u0151\u0171]",
|
||||
anyLetterStrict: "[A-Za-z0-9\u00c0-\u00de\u00df-\u00ff\u0150\u0170\u0151\u0171]"
|
||||
};
|
||||
if(!((new RegExp("[\u0150\u0170]","g")).test("\u0150"))) {
|
||||
config.textPrimitives = {
|
||||
upperLetter: "[A-Z\u00c0-\u00de]",
|
||||
lowerLetter: "[a-z0-9_\\-\u00df-\u00ff]",
|
||||
anyLetter: "[A-Za-z0-9_\\-\u00c0-\u00de\u00df-\u00ff]",
|
||||
anyLetterStrict: "[A-Za-z0-9\u00c0-\u00de\u00df-\u00ff]"
|
||||
};
|
||||
}
|
||||
config.textPrimitives.sliceSeparator = "::";
|
||||
config.textPrimitives.sectionSeparator = "##";
|
||||
config.textPrimitives.urlPattern = "(?:file|http|https|mailto|ftp|irc|news|data):[^\\s'\"]+(?:/|\\b)";
|
||||
config.textPrimitives.unWikiLink = "~";
|
||||
config.textPrimitives.wikiLink = "(?:(?:" + config.textPrimitives.upperLetter + "+" +
|
||||
config.textPrimitives.lowerLetter + "+" +
|
||||
config.textPrimitives.upperLetter +
|
||||
config.textPrimitives.anyLetter + "*)|(?:" +
|
||||
config.textPrimitives.upperLetter + "{2,}" +
|
||||
config.textPrimitives.lowerLetter + "+))";
|
||||
|
||||
config.textPrimitives.cssLookahead = "(?:(" + config.textPrimitives.anyLetter + "+)\\(([^\\)\\|\\n]+)(?:\\):))|(?:(" + config.textPrimitives.anyLetter + "+):([^;\\|\\n]+);)";
|
||||
config.textPrimitives.cssLookaheadRegExp = new RegExp(config.textPrimitives.cssLookahead,"mg");
|
||||
|
||||
config.textPrimitives.brackettedLink = "\\[\\[([^\\]]+)\\]\\]";
|
||||
config.textPrimitives.titledBrackettedLink = "\\[\\[([^\\[\\]\\|]+)\\|([^\\[\\]\\|]+)\\]\\]";
|
||||
config.textPrimitives.tiddlerForcedLinkRegExp = new RegExp("(?:" + config.textPrimitives.titledBrackettedLink + ")|(?:" +
|
||||
config.textPrimitives.brackettedLink + ")|(?:" +
|
||||
config.textPrimitives.urlPattern + ")","mg");
|
||||
config.textPrimitives.tiddlerAnyLinkRegExp = new RegExp("("+ config.textPrimitives.wikiLink + ")|(?:" +
|
||||
config.textPrimitives.titledBrackettedLink + ")|(?:" +
|
||||
config.textPrimitives.brackettedLink + ")|(?:" +
|
||||
config.textPrimitives.urlPattern + ")","mg");
|
||||
|
||||
config.glyphs = {
|
||||
currBrowser: null,
|
||||
browsers: [],
|
||||
codes: {}
|
||||
};
|
||||
|
||||
//--
|
||||
//-- Shadow tiddlers
|
||||
//--
|
||||
|
||||
config.shadowTiddlers = {
|
||||
StyleSheet: "",
|
||||
MarkupPreHead: "",
|
||||
MarkupPostHead: "",
|
||||
MarkupPreBody: "",
|
||||
MarkupPostBody: "",
|
||||
TabTimeline: '<<timeline>>',
|
||||
TabAll: '<<list all>>',
|
||||
TabTags: '<<allTags excludeLists>>',
|
||||
TabMoreMissing: '<<list missing>>',
|
||||
TabMoreOrphans: '<<list orphans>>',
|
||||
TabMoreShadowed: '<<list shadowed>>',
|
||||
AdvancedOptions: '<<options>>',
|
||||
PluginManager: '<<plugins>>',
|
||||
SystemSettings: '',
|
||||
ToolbarCommands: '|~ViewToolbar|closeTiddler closeOthers +editTiddler > fields syncing permalink references jump|\n|~EditToolbar|+saveTiddler -cancelTiddler deleteTiddler|',
|
||||
WindowTitle: '<<tiddler SiteTitle>> - <<tiddler SiteSubtitle>>'
|
||||
};
|
||||
|
30
test/data/tiddlywiki/js/ConfigBrowser.js
Executable file
30
test/data/tiddlywiki/js/ConfigBrowser.js
Executable file
@ -0,0 +1,30 @@
|
||||
// Browser detection... In a very few places, there's nothing else for it but to know what browser we're using.
|
||||
config.userAgent = navigator.userAgent.toLowerCase();
|
||||
config.browser = {
|
||||
isIE: config.userAgent.indexOf("msie") != -1 && config.userAgent.indexOf("opera") == -1,
|
||||
isGecko: navigator.product == "Gecko" && config.userAgent.indexOf("WebKit") == -1,
|
||||
ieVersion: /MSIE (\d.\d)/i.exec(config.userAgent), // config.browser.ieVersion[1], if it exists, will be the IE version string, eg "6.0"
|
||||
isSafari: config.userAgent.indexOf("applewebkit") != -1,
|
||||
isBadSafari: !((new RegExp("[\u0150\u0170]","g")).test("\u0150")),
|
||||
firefoxDate: /gecko\/(\d{8})/i.exec(config.userAgent), // config.browser.firefoxDate[1], if it exists, will be Firefox release date as "YYYYMMDD"
|
||||
isOpera: config.userAgent.indexOf("opera") != -1,
|
||||
isChrome: config.userAgent.indexOf('chrome') > -1,
|
||||
isLinux: config.userAgent.indexOf("linux") != -1,
|
||||
isUnix: config.userAgent.indexOf("x11") != -1,
|
||||
isMac: config.userAgent.indexOf("mac") != -1,
|
||||
isWindows: config.userAgent.indexOf("win") != -1
|
||||
};
|
||||
|
||||
merge(config.glyphs,{
|
||||
browsers: [
|
||||
function() {return config.browser.isIE;},
|
||||
function() {return true;}
|
||||
],
|
||||
codes: {
|
||||
downTriangle: ["\u25BC","\u25BE"],
|
||||
downArrow: ["\u2193","\u2193"],
|
||||
bentArrowLeft: ["\u2190","\u21A9"],
|
||||
bentArrowRight: ["\u2192","\u21AA"]
|
||||
}
|
||||
});
|
||||
|
143
test/data/tiddlywiki/js/Crypto.js
Executable file
143
test/data/tiddlywiki/js/Crypto.js
Executable file
@ -0,0 +1,143 @@
|
||||
//--
|
||||
//-- Crypto functions and associated conversion routines
|
||||
//--
|
||||
|
||||
// Crypto 'namespace'
|
||||
function Crypto() {}
|
||||
|
||||
// Convert a string to an array of big-endian 32-bit words
|
||||
Crypto.strToBe32s = function(str)
|
||||
{
|
||||
var be=[];
|
||||
var len=Math.floor(str.length/4);
|
||||
var i, j;
|
||||
for(i=0, j=0; i<len; i++, j+=4) {
|
||||
be[i]=((str.charCodeAt(j)&0xff) << 24)|((str.charCodeAt(j+1)&0xff) << 16)|((str.charCodeAt(j+2)&0xff) << 8)|(str.charCodeAt(j+3)&0xff);
|
||||
}
|
||||
while(j<str.length) {
|
||||
be[j>>2] |= (str.charCodeAt(j)&0xff)<<(24-(j*8)%32);
|
||||
j++;
|
||||
}
|
||||
return be;
|
||||
};
|
||||
|
||||
// Convert an array of big-endian 32-bit words to a string
|
||||
Crypto.be32sToStr = function(be)
|
||||
{
|
||||
var str='';
|
||||
for(var i=0;i<be.length*32;i+=8) {
|
||||
str += String.fromCharCode((be[i>>5]>>>(24-i%32)) & 0xff);
|
||||
}
|
||||
return str;
|
||||
};
|
||||
|
||||
// Convert an array of big-endian 32-bit words to a hex string
|
||||
Crypto.be32sToHex = function(be)
|
||||
{
|
||||
var hex='0123456789ABCDEF';
|
||||
var str='';
|
||||
for(var i=0;i<be.length*4;i++) {
|
||||
str += hex.charAt((be[i>>2]>>((3-i%4)*8+4))&0xF) + hex.charAt((be[i>>2]>>((3-i%4)*8))&0xF);
|
||||
}
|
||||
return str;
|
||||
};
|
||||
|
||||
// Return, in hex, the SHA-1 hash of a string
|
||||
Crypto.hexSha1Str = function(str)
|
||||
{
|
||||
return Crypto.be32sToHex(Crypto.sha1Str(str));
|
||||
};
|
||||
|
||||
// Return the SHA-1 hash of a string
|
||||
Crypto.sha1Str = function(str)
|
||||
{
|
||||
return Crypto.sha1(Crypto.strToBe32s(str),str.length);
|
||||
};
|
||||
|
||||
// Calculate the SHA-1 hash of an array of blen bytes of big-endian 32-bit words
|
||||
Crypto.sha1 = function(x,blen)
|
||||
{
|
||||
// Add 32-bit integers, wrapping at 32 bits
|
||||
//# Uses 16-bit operations internally to work around bugs in some JavaScript interpreters.
|
||||
function add32(a,b)
|
||||
{
|
||||
var lsw=(a&0xFFFF)+(b&0xFFFF);
|
||||
var msw=(a>>16)+(b>>16)+(lsw>>16);
|
||||
return (msw<<16)|(lsw&0xFFFF);
|
||||
}
|
||||
//# Cryptographic round helper function. Add five 32-bit integers, wrapping at 32 bits, second parameter is rotated left 5 bits before the addition
|
||||
//# Uses 16-bit operations internally to work around bugs in some JavaScript interpreters.
|
||||
function AA(a,b,c,d,e)
|
||||
{
|
||||
b=(b>>>27)|(b<<5);
|
||||
var lsw=(a&0xFFFF)+(b&0xFFFF)+(c&0xFFFF)+(d&0xFFFF)+(e&0xFFFF);
|
||||
var msw=(a>>16)+(b>>16)+(c>>16)+(d>>16)+(e>>16)+(lsw>>16);
|
||||
return (msw<<16)|(lsw&0xFFFF);
|
||||
}
|
||||
//# Cryptographic round helper function.
|
||||
function RR(w,j)
|
||||
{
|
||||
var n=w[j-3]^w[j-8]^w[j-14]^w[j-16];
|
||||
return (n>>>31)|(n<<1);
|
||||
}
|
||||
|
||||
var len=blen*8;
|
||||
//# Append padding so length in bits is 448 mod 512
|
||||
x[len>>5] |= 0x80 << (24-len%32);
|
||||
//# Append length
|
||||
x[((len+64>>9)<<4)+15]=len;
|
||||
var w=new Array(80);
|
||||
|
||||
var k1=0x5A827999;
|
||||
var k2=0x6ED9EBA1;
|
||||
var k3=0x8F1BBCDC;
|
||||
var k4=0xCA62C1D6;
|
||||
|
||||
var h0=0x67452301;
|
||||
var h1=0xEFCDAB89;
|
||||
var h2=0x98BADCFE;
|
||||
var h3=0x10325476;
|
||||
var h4=0xC3D2E1F0;
|
||||
|
||||
for(var i=0;i<x.length;i+=16) {
|
||||
var j=0;
|
||||
var t;
|
||||
var a=h0;
|
||||
var b=h1;
|
||||
var c=h2;
|
||||
var d=h3;
|
||||
var e=h4;
|
||||
while(j<16) {
|
||||
w[j]=x[i+j];
|
||||
t=AA(e,a,d^(b&(c^d)),w[j],k1);
|
||||
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a=t; j++;
|
||||
}
|
||||
while(j<20) {
|
||||
w[j]=RR(w,j);
|
||||
t=AA(e,a,d^(b&(c^d)),w[j],k1);
|
||||
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a=t; j++;
|
||||
}
|
||||
while(j<40) {
|
||||
w[j]=RR(w,j);
|
||||
t=AA(e,a,b^c^d,w[j],k2);
|
||||
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a=t; j++;
|
||||
}
|
||||
while(j<60) {
|
||||
w[j]=RR(w,j);
|
||||
t=AA(e,a,(b&c)|(d&(b|c)),w[j],k3);
|
||||
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a=t; j++;
|
||||
}
|
||||
while(j<80) {
|
||||
w[j]=RR(w,j);
|
||||
t=AA(e,a,b^c^d,w[j],k4);
|
||||
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a=t; j++;
|
||||
}
|
||||
h0=add32(h0,a);
|
||||
h1=add32(h1,b);
|
||||
h2=add32(h2,c);
|
||||
h3=add32(h3,d);
|
||||
h4=add32(h4,e);
|
||||
}
|
||||
return [h0,h1,h2,h3,h4];
|
||||
};
|
||||
|
119
test/data/tiddlywiki/js/Dates.js
Executable file
119
test/data/tiddlywiki/js/Dates.js
Executable file
@ -0,0 +1,119 @@
|
||||
//--
|
||||
//-- Augmented methods for the JavaScript Date() object
|
||||
//--
|
||||
|
||||
// Substitute date components into a string
|
||||
Date.prototype.formatString = function(template)
|
||||
{
|
||||
var t = template.replace(/0hh12/g,String.zeroPad(this.getHours12(),2));
|
||||
t = t.replace(/hh12/g,this.getHours12());
|
||||
t = t.replace(/0hh/g,String.zeroPad(this.getHours(),2));
|
||||
t = t.replace(/hh/g,this.getHours());
|
||||
t = t.replace(/mmm/g,config.messages.dates.shortMonths[this.getMonth()]);
|
||||
t = t.replace(/0mm/g,String.zeroPad(this.getMinutes(),2));
|
||||
t = t.replace(/mm/g,this.getMinutes());
|
||||
t = t.replace(/0ss/g,String.zeroPad(this.getSeconds(),2));
|
||||
t = t.replace(/ss/g,this.getSeconds());
|
||||
t = t.replace(/[ap]m/g,this.getAmPm().toLowerCase());
|
||||
t = t.replace(/[AP]M/g,this.getAmPm().toUpperCase());
|
||||
t = t.replace(/wYYYY/g,this.getYearForWeekNo());
|
||||
t = t.replace(/wYY/g,String.zeroPad(this.getYearForWeekNo()-2000,2));
|
||||
t = t.replace(/YYYY/g,this.getFullYear());
|
||||
t = t.replace(/YY/g,String.zeroPad(this.getFullYear()-2000,2));
|
||||
t = t.replace(/MMM/g,config.messages.dates.months[this.getMonth()]);
|
||||
t = t.replace(/0MM/g,String.zeroPad(this.getMonth()+1,2));
|
||||
t = t.replace(/MM/g,this.getMonth()+1);
|
||||
t = t.replace(/0WW/g,String.zeroPad(this.getWeek(),2));
|
||||
t = t.replace(/WW/g,this.getWeek());
|
||||
t = t.replace(/DDD/g,config.messages.dates.days[this.getDay()]);
|
||||
t = t.replace(/ddd/g,config.messages.dates.shortDays[this.getDay()]);
|
||||
t = t.replace(/0DD/g,String.zeroPad(this.getDate(),2));
|
||||
t = t.replace(/DDth/g,this.getDate()+this.daySuffix());
|
||||
t = t.replace(/DD/g,this.getDate());
|
||||
var tz = this.getTimezoneOffset();
|
||||
var atz = Math.abs(tz);
|
||||
t = t.replace(/TZD/g,(tz < 0 ? '+' : '-') + String.zeroPad(Math.floor(atz / 60),2) + ':' + String.zeroPad(atz % 60,2));
|
||||
t = t.replace(/\\/g,"");
|
||||
return t;
|
||||
};
|
||||
|
||||
Date.prototype.getWeek = function()
|
||||
{
|
||||
var dt = new Date(this.getTime());
|
||||
var d = dt.getDay();
|
||||
if(d==0) d=7;// JavaScript Sun=0, ISO Sun=7
|
||||
dt.setTime(dt.getTime()+(4-d)*86400000);// shift day to Thurs of same week to calculate weekNo
|
||||
var n = Math.floor((dt.getTime()-new Date(dt.getFullYear(),0,1)+3600000)/86400000);
|
||||
return Math.floor(n/7)+1;
|
||||
};
|
||||
|
||||
Date.prototype.getYearForWeekNo = function()
|
||||
{
|
||||
var dt = new Date(this.getTime());
|
||||
var d = dt.getDay();
|
||||
if(d==0) d=7;// JavaScript Sun=0, ISO Sun=7
|
||||
dt.setTime(dt.getTime()+(4-d)*86400000);// shift day to Thurs of same week
|
||||
return dt.getFullYear();
|
||||
};
|
||||
|
||||
Date.prototype.getHours12 = function()
|
||||
{
|
||||
var h = this.getHours();
|
||||
return h > 12 ? h-12 : ( h > 0 ? h : 12 );
|
||||
};
|
||||
|
||||
Date.prototype.getAmPm = function()
|
||||
{
|
||||
return this.getHours() >= 12 ? config.messages.dates.pm : config.messages.dates.am;
|
||||
};
|
||||
|
||||
Date.prototype.daySuffix = function()
|
||||
{
|
||||
return config.messages.dates.daySuffixes[this.getDate()-1];
|
||||
};
|
||||
|
||||
// Convert a date to local YYYYMMDDHHMM string format
|
||||
Date.prototype.convertToLocalYYYYMMDDHHMM = function()
|
||||
{
|
||||
return this.getFullYear() + String.zeroPad(this.getMonth()+1,2) + String.zeroPad(this.getDate(),2) + String.zeroPad(this.getHours(),2) + String.zeroPad(this.getMinutes(),2);
|
||||
};
|
||||
|
||||
// Convert a date to UTC YYYYMMDDHHMM string format
|
||||
Date.prototype.convertToYYYYMMDDHHMM = function()
|
||||
{
|
||||
return this.getUTCFullYear() + String.zeroPad(this.getUTCMonth()+1,2) + String.zeroPad(this.getUTCDate(),2) + String.zeroPad(this.getUTCHours(),2) + String.zeroPad(this.getUTCMinutes(),2);
|
||||
};
|
||||
|
||||
// Convert a date to UTC YYYYMMDD.HHMMSSMMM string format
|
||||
Date.prototype.convertToYYYYMMDDHHMMSSMMM = function()
|
||||
{
|
||||
return this.getUTCFullYear() + String.zeroPad(this.getUTCMonth()+1,2) + String.zeroPad(this.getUTCDate(),2) + "." + String.zeroPad(this.getUTCHours(),2) + String.zeroPad(this.getUTCMinutes(),2) + String.zeroPad(this.getUTCSeconds(),2) + String.zeroPad(this.getUTCMilliseconds(),3) +"0";
|
||||
};
|
||||
|
||||
// Static method to create a date from a UTC YYYYMMDDHHMM format string
|
||||
Date.convertFromYYYYMMDDHHMM = function(d)
|
||||
{
|
||||
d = d?d.replace(/[^0-9]/g, ""):"";
|
||||
return Date.convertFromYYYYMMDDHHMMSSMMM(d.substr(0,12));
|
||||
};
|
||||
|
||||
// Static method to create a date from a UTC YYYYMMDDHHMMSS format string
|
||||
Date.convertFromYYYYMMDDHHMMSS = function(d)
|
||||
{
|
||||
d = d?d.replace(/[^0-9]/g, ""):"";
|
||||
return Date.convertFromYYYYMMDDHHMMSSMMM(d.substr(0,14));
|
||||
};
|
||||
|
||||
// Static method to create a date from a UTC YYYYMMDDHHMMSSMMM format string
|
||||
Date.convertFromYYYYMMDDHHMMSSMMM = function(d)
|
||||
{
|
||||
d = d ? d.replace(/[^0-9]/g, "") : "";
|
||||
return new Date(Date.UTC(parseInt(d.substr(0,4),10),
|
||||
parseInt(d.substr(4,2),10)-1,
|
||||
parseInt(d.substr(6,2),10),
|
||||
parseInt(d.substr(8,2)||"00",10),
|
||||
parseInt(d.substr(10,2)||"00",10),
|
||||
parseInt(d.substr(12,2)||"00",10),
|
||||
parseInt(d.substr(14,3)||"000",10)));
|
||||
};
|
||||
|
264
test/data/tiddlywiki/js/Dom.js
Executable file
264
test/data/tiddlywiki/js/Dom.js
Executable file
@ -0,0 +1,264 @@
|
||||
//--
|
||||
//-- DOM utilities - many derived from www.quirksmode.org
|
||||
//--
|
||||
|
||||
function drawGradient(place,horiz,locolors,hicolors)
|
||||
{
|
||||
if(!hicolors)
|
||||
hicolors = locolors;
|
||||
var t;
|
||||
for(t=0; t<= 100; t+=2) {
|
||||
var bar = document.createElement("div");
|
||||
place.appendChild(bar);
|
||||
bar.style.position = "absolute";
|
||||
bar.style.left = horiz ? t + "%" : 0;
|
||||
bar.style.top = horiz ? 0 : t + "%";
|
||||
bar.style.width = horiz ? (101-t) + "%" : "100%";
|
||||
bar.style.height = horiz ? "100%" : (101-t) + "%";
|
||||
bar.style.zIndex = -1;
|
||||
var p = t/100*(locolors.length-1);
|
||||
var hc = hicolors[Math.floor(p)];
|
||||
if(typeof hc == "string")
|
||||
hc = new RGB(hc);
|
||||
var lc = locolors[Math.ceil(p)];
|
||||
if(typeof lc == "string")
|
||||
lc = new RGB(lc);
|
||||
bar.style.backgroundColor = hc.mix(lc,p-Math.floor(p)).toString();
|
||||
}
|
||||
}
|
||||
|
||||
//# Add an event handler
|
||||
//# Thanks to John Resig, via QuirksMode
|
||||
function addEvent(obj,type,fn)
|
||||
{
|
||||
if(obj.attachEvent) {
|
||||
obj["e"+type+fn] = fn;
|
||||
obj[type+fn] = function(){obj["e"+type+fn](window.event);};
|
||||
obj.attachEvent("on"+type,obj[type+fn]);
|
||||
} else {
|
||||
obj.addEventListener(type,fn,false);
|
||||
}
|
||||
}
|
||||
|
||||
//# Remove an event handler
|
||||
//# Thanks to John Resig, via QuirksMode
|
||||
function removeEvent(obj,type,fn)
|
||||
{
|
||||
if(obj.detachEvent) {
|
||||
obj.detachEvent("on"+type,obj[type+fn]);
|
||||
obj[type+fn] = null;
|
||||
} else {
|
||||
obj.removeEventListener(type,fn,false);
|
||||
}
|
||||
}
|
||||
|
||||
// Find the closest relative with a given property value (property defaults to tagName, relative defaults to parentNode)
|
||||
function findRelated(e,value,name,relative)
|
||||
{
|
||||
name = name || "tagName";
|
||||
relative = relative || "parentNode";
|
||||
if(name == "className") {
|
||||
while(e && !jQuery(e).hasClass(value)) {
|
||||
e = e[relative];
|
||||
}
|
||||
} else {
|
||||
while(e && e[name] != value) {
|
||||
e = e[relative];
|
||||
}
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
// Get the scroll position for window.scrollTo necessary to scroll a given element into view
|
||||
function ensureVisible(e)
|
||||
{
|
||||
var posTop = findPosY(e);
|
||||
var posBot = posTop + e.offsetHeight;
|
||||
var winTop = findScrollY();
|
||||
var winHeight = findWindowHeight();
|
||||
var winBot = winTop + winHeight;
|
||||
if(posTop < winTop) {
|
||||
return posTop;
|
||||
} else if(posBot > winBot) {
|
||||
if(e.offsetHeight < winHeight)
|
||||
return posTop - (winHeight - e.offsetHeight);
|
||||
else
|
||||
return posTop;
|
||||
} else {
|
||||
return winTop;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the current width of the display window
|
||||
function findWindowWidth()
|
||||
{
|
||||
return window.innerWidth || document.documentElement.clientWidth;
|
||||
}
|
||||
|
||||
// Get the current height of the display window
|
||||
function findWindowHeight()
|
||||
{
|
||||
return window.innerHeight || document.documentElement.clientHeight;
|
||||
}
|
||||
|
||||
// Get the current horizontal page scroll position
|
||||
function findScrollX()
|
||||
{
|
||||
return window.scrollX || document.documentElement.scrollLeft;
|
||||
}
|
||||
|
||||
// Get the current vertical page scroll position
|
||||
function findScrollY()
|
||||
{
|
||||
return window.scrollY || document.documentElement.scrollTop;
|
||||
}
|
||||
|
||||
function findPosX(obj)
|
||||
{
|
||||
var curleft = 0;
|
||||
while(obj.offsetParent) {
|
||||
curleft += obj.offsetLeft;
|
||||
obj = obj.offsetParent;
|
||||
}
|
||||
return curleft;
|
||||
}
|
||||
|
||||
function findPosY(obj)
|
||||
{
|
||||
var curtop = 0;
|
||||
while(obj.offsetParent) {
|
||||
curtop += obj.offsetTop;
|
||||
obj = obj.offsetParent;
|
||||
}
|
||||
return curtop;
|
||||
}
|
||||
|
||||
// Blur a particular element
|
||||
function blurElement(e)
|
||||
{
|
||||
if(e && e.focus && e.blur) {
|
||||
e.focus();
|
||||
e.blur();
|
||||
}
|
||||
}
|
||||
|
||||
// Create a non-breaking space
|
||||
function insertSpacer(place)
|
||||
{
|
||||
var e = document.createTextNode(String.fromCharCode(160));
|
||||
if(place)
|
||||
place.appendChild(e);
|
||||
return e;
|
||||
}
|
||||
|
||||
// Replace the current selection of a textarea or text input and scroll it into view
|
||||
function replaceSelection(e,text)
|
||||
{
|
||||
if(e.setSelectionRange) {
|
||||
var oldpos = e.selectionStart;
|
||||
var isRange = e.selectionEnd > e.selectionStart;
|
||||
e.value = e.value.substr(0,e.selectionStart) + text + e.value.substr(e.selectionEnd);
|
||||
e.setSelectionRange(isRange ? oldpos : oldpos + text.length,oldpos + text.length);
|
||||
var linecount = e.value.split("\n").length;
|
||||
var thisline = e.value.substr(0,e.selectionStart).split("\n").length-1;
|
||||
e.scrollTop = Math.floor((thisline - e.rows / 2) * e.scrollHeight / linecount);
|
||||
} else if(document.selection) {
|
||||
var range = document.selection.createRange();
|
||||
if(range.parentElement() == e) {
|
||||
var isCollapsed = range.text == "";
|
||||
range.text = text;
|
||||
if(!isCollapsed) {
|
||||
range.moveStart("character", -text.length);
|
||||
range.select();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set the caret position in a text area
|
||||
function setCaretPosition(e,pos)
|
||||
{
|
||||
if(e.selectionStart || e.selectionStart == '0') {
|
||||
e.selectionStart = pos;
|
||||
e.selectionEnd = pos;
|
||||
e.focus();
|
||||
} else if(document.selection) {
|
||||
// IE support
|
||||
e.focus ();
|
||||
var sel = document.selection.createRange();
|
||||
sel.moveStart('character', -e.value.length);
|
||||
sel.moveStart('character',pos);
|
||||
sel.moveEnd('character',0);
|
||||
sel.select();
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the text of the given (text) node, possibly merging subsequent text nodes
|
||||
function getNodeText(e)
|
||||
{
|
||||
var t = "";
|
||||
while(e && e.nodeName == "#text") {
|
||||
t += e.nodeValue;
|
||||
e = e.nextSibling;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
// Returns true if the element e has a given ancestor element
|
||||
function isDescendant(e,ancestor)
|
||||
{
|
||||
while(e) {
|
||||
if(e === ancestor)
|
||||
return true;
|
||||
e = e.parentNode;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// deprecate the following...
|
||||
|
||||
// Prevent an event from bubbling
|
||||
function stopEvent(e)
|
||||
{
|
||||
var ev = e || window.event;
|
||||
ev.cancelBubble = true;
|
||||
if(ev.stopPropagation) ev.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove any event handlers or non-primitve custom attributes
|
||||
function scrubNode(e)
|
||||
{
|
||||
if(!config.browser.isIE)
|
||||
return;
|
||||
var att = e.attributes;
|
||||
if(att) {
|
||||
var t;
|
||||
for(t=0; t<att.length; t++) {
|
||||
var n = att[t].name;
|
||||
if(n !== "style" && (typeof e[n] === "function" || (typeof e[n] === "object" && e[n] != null))) {
|
||||
try {
|
||||
e[n] = null;
|
||||
} catch(ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var c = e.firstChild;
|
||||
while(c) {
|
||||
scrubNode(c);
|
||||
c = c.nextSibling;
|
||||
}
|
||||
}
|
||||
|
||||
function setStylesheet(s,id,doc)
|
||||
{
|
||||
jQuery.twStylesheet(s,{id:id,doc:doc});
|
||||
}
|
||||
|
||||
function removeStyleSheet(id)
|
||||
{
|
||||
jQuery.twStylesheet.remove({id:id});
|
||||
}
|
||||
|
185
test/data/tiddlywiki/js/FileAdaptor.js
Executable file
185
test/data/tiddlywiki/js/FileAdaptor.js
Executable file
@ -0,0 +1,185 @@
|
||||
//--
|
||||
//-- Server adaptor for talking to static TiddlyWiki files
|
||||
//--
|
||||
|
||||
function FileAdaptor()
|
||||
{
|
||||
}
|
||||
|
||||
FileAdaptor.prototype = new AdaptorBase();
|
||||
|
||||
FileAdaptor.serverType = 'file';
|
||||
FileAdaptor.serverLabel = 'TiddlyWiki';
|
||||
|
||||
FileAdaptor.loadTiddlyWikiSuccess = function(context,jqXHR)
|
||||
{
|
||||
context.status = true;
|
||||
//# Load the content into a TiddlyWiki() object
|
||||
context.adaptor.store = new TiddlyWiki();
|
||||
if(!context.adaptor.store.importTiddlyWiki(jqXHR.responseText)) {
|
||||
context.statusText = config.messages.invalidFileError.format([context.host]);
|
||||
context.status = false;
|
||||
}
|
||||
context.complete(context,context.userParams);
|
||||
};
|
||||
|
||||
FileAdaptor.loadTiddlyWikiError = function(context,jqXHR)
|
||||
{
|
||||
context.status = false;
|
||||
context.statusText = jqXHR.message;
|
||||
context.complete(context,context.userParams);
|
||||
};
|
||||
|
||||
// Get the list of workspaces on a given server
|
||||
//# context - passed on as a parameter to the callback function
|
||||
//# userParams - user settable object object that is passed on unchanged to the callback function
|
||||
//# callback - function to be called on completion
|
||||
//# Return value is true if the request was successfully issued, false if this connector doesn't support getWorkspaceList(),
|
||||
//# or an error description string if there was a problem
|
||||
//# The callback parameters are callback(context,userParams)
|
||||
//# context.status - true if OK, false if error
|
||||
//# context.statusText - error message if there was an error
|
||||
//# context.adaptor - reference to this adaptor object
|
||||
//# userParams - parameters as originally passed into the getWorkspaceList function
|
||||
FileAdaptor.prototype.getWorkspaceList = function(context,userParams,callback)
|
||||
{
|
||||
context = this.setContext(context,userParams,callback);
|
||||
context.workspaces = [{title:"(default)"}];
|
||||
context.status = true;
|
||||
if(callback)
|
||||
window.setTimeout(function() {callback(context,userParams);},10);
|
||||
return true;
|
||||
};
|
||||
|
||||
// Gets the list of tiddlers within a given workspace
|
||||
//# context - passed on as a parameter to the callback function
|
||||
//# userParams - user settable object object that is passed on unchanged to the callback function
|
||||
//# callback - function to be called on completion
|
||||
//# filter - filter expression
|
||||
//# Return value is true if the request was successfully issued,
|
||||
//# or an error description string if there was a problem
|
||||
//# The callback parameters are callback(context,userParams)
|
||||
//# context.status - true if OK, false if error
|
||||
//# context.statusText - error message if there was an error
|
||||
//# context.adaptor - reference to this adaptor object
|
||||
//# context.tiddlers - array of tiddler objects
|
||||
//# userParams - parameters as originally passed into the getTiddlerList function
|
||||
FileAdaptor.prototype.getTiddlerList = function(context,userParams,callback,filter)
|
||||
{
|
||||
context = this.setContext(context,userParams,callback);
|
||||
if(!context.filter)
|
||||
context.filter = filter;
|
||||
context.complete = FileAdaptor.getTiddlerListComplete;
|
||||
if(this.store) {
|
||||
return context.complete(context,context.userParams);
|
||||
}
|
||||
var options = {
|
||||
type:"GET",
|
||||
url:context.host,
|
||||
processData:false,
|
||||
success:function(data,textStatus,jqXHR) {
|
||||
FileAdaptor.loadTiddlyWikiSuccess(context,jqXHR);
|
||||
},
|
||||
error:function(jqXHR,textStatus,errorThrown) {
|
||||
context.xhr = jqXHR;
|
||||
FileAdaptor.loadTiddlyWikiError(context,jqXHR);
|
||||
}
|
||||
};
|
||||
return ajaxReq(options);
|
||||
};
|
||||
|
||||
FileAdaptor.getTiddlerListComplete = function(context,userParams)
|
||||
{
|
||||
if(context.status) {
|
||||
if(context.filter) {
|
||||
context.tiddlers = context.adaptor.store.filterTiddlers(context.filter);
|
||||
} else {
|
||||
context.tiddlers = [];
|
||||
context.adaptor.store.forEachTiddler(function(title,tiddler) {context.tiddlers.push(tiddler);});
|
||||
}
|
||||
var i;
|
||||
for(i=0; i<context.tiddlers.length; i++) {
|
||||
context.tiddlers[i].fields['server.type'] = FileAdaptor.serverType;
|
||||
context.tiddlers[i].fields['server.host'] = AdaptorBase.minHostName(context.host);
|
||||
context.tiddlers[i].fields['server.page.revision'] = context.tiddlers[i].modified.convertToYYYYMMDDHHMM();
|
||||
}
|
||||
context.status = true;
|
||||
}
|
||||
if(context.callback) {
|
||||
window.setTimeout(function() {context.callback(context,userParams);},10);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
FileAdaptor.prototype.generateTiddlerInfo = function(tiddler)
|
||||
{
|
||||
var info = {};
|
||||
info.uri = tiddler.fields['server.host'] + "#" + tiddler.title;
|
||||
return info;
|
||||
};
|
||||
|
||||
// Retrieve a tiddler from a given workspace on a given server
|
||||
//# title - title of the tiddler to get
|
||||
//# context - passed on as a parameter to the callback function
|
||||
//# userParams - user settable object object that is passed on unchanged to the callback function
|
||||
//# callback - function to be called on completion
|
||||
//# Return value is true if the request was successfully issued,
|
||||
//# or an error description string if there was a problem
|
||||
//# The callback parameters are callback(context,userParams)
|
||||
//# context.status - true if OK, false if error
|
||||
//# context.statusText - error message if there was an error
|
||||
//# context.adaptor - reference to this adaptor object
|
||||
//# context.tiddler - the retrieved tiddler, or null if it cannot be found
|
||||
//# userParams - parameters as originally passed into the getTiddler function
|
||||
FileAdaptor.prototype.getTiddler = function(title,context,userParams,callback)
|
||||
{
|
||||
context = this.setContext(context,userParams,callback);
|
||||
context.title = title;
|
||||
context.complete = FileAdaptor.getTiddlerComplete;
|
||||
if(context.adaptor.store) {
|
||||
return context.complete(context,context.userParams);
|
||||
}
|
||||
var options = {
|
||||
type:"GET",
|
||||
url:context.host,
|
||||
processData:false,
|
||||
success:function(data,textStatus,jqXHR) {
|
||||
FileAdaptor.loadTiddlyWikiSuccess(context,jqXHR);
|
||||
},
|
||||
error:function(jqXHR,textStatus,errorThrown) {
|
||||
FileAdaptor.loadTiddlyWikiError(context,jqXHR);
|
||||
}
|
||||
};
|
||||
return ajaxReq(options);
|
||||
};
|
||||
|
||||
FileAdaptor.getTiddlerComplete = function(context,userParams)
|
||||
{
|
||||
var t = context.adaptor.store.fetchTiddler(context.title);
|
||||
if(t) {
|
||||
t.fields['server.type'] = FileAdaptor.serverType;
|
||||
t.fields['server.host'] = AdaptorBase.minHostName(context.host);
|
||||
t.fields['server.page.revision'] = t.modified.convertToYYYYMMDDHHMM();
|
||||
context.tiddler = t;
|
||||
context.status = true;
|
||||
} else { //# tiddler does not exist in document
|
||||
context.status = false;
|
||||
}
|
||||
if(context.allowSynchronous) {
|
||||
context.isSynchronous = true;
|
||||
context.callback(context,userParams);
|
||||
} else {
|
||||
window.setTimeout(function() {context.callback(context,userParams);},10);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
FileAdaptor.prototype.close = function()
|
||||
{
|
||||
this.store = null;
|
||||
};
|
||||
|
||||
config.adaptors[FileAdaptor.serverType] = FileAdaptor;
|
||||
|
||||
config.defaultAdaptor = FileAdaptor.serverType;
|
||||
|
212
test/data/tiddlywiki/js/FileSystem.js
Executable file
212
test/data/tiddlywiki/js/FileSystem.js
Executable file
@ -0,0 +1,212 @@
|
||||
//--
|
||||
//-- Filesystem code
|
||||
//--
|
||||
//#
|
||||
//# This code is designed to be reusable, but please take care,
|
||||
//# there are some intricacies that make it tricky to use these
|
||||
//# functions with full UTF-8 files. For more details, see:
|
||||
//#
|
||||
//# http://trac.tiddlywiki.org/ticket/99
|
||||
//#
|
||||
//#
|
||||
|
||||
function copyFile(dest,source)
|
||||
{
|
||||
return config.browser.isIE ? ieCopyFile(dest,source) : false;
|
||||
}
|
||||
|
||||
function saveFile(fileUrl,content)
|
||||
{
|
||||
var r = mozillaSaveFile(fileUrl,content);
|
||||
if(!r)
|
||||
r = ieSaveFile(fileUrl,content);
|
||||
if(!r)
|
||||
r = javaSaveFile(fileUrl,content);
|
||||
return r;
|
||||
}
|
||||
|
||||
function loadFile(fileUrl)
|
||||
{
|
||||
var r = mozillaLoadFile(fileUrl);
|
||||
if((r == null) || (r == false))
|
||||
r = ieLoadFile(fileUrl);
|
||||
if((r == null) || (r == false))
|
||||
r = javaLoadFile(fileUrl);
|
||||
return r;
|
||||
}
|
||||
|
||||
function ieCreatePath(path)
|
||||
{
|
||||
try {
|
||||
var fso = new ActiveXObject("Scripting.FileSystemObject");
|
||||
} catch(ex) {
|
||||
return null;
|
||||
}
|
||||
|
||||
//# Remove the filename, if present. Use trailing slash (i.e. "foo\bar\") if no filename.
|
||||
var pos = path.lastIndexOf("\\");
|
||||
if(pos==-1)
|
||||
pos = path.lastIndexOf("/");
|
||||
if(pos!=-1)
|
||||
path = path.substring(0,pos+1);
|
||||
|
||||
//# Walk up the path until we find a folder that exists
|
||||
var scan = [path];
|
||||
var parent = fso.GetParentFolderName(path);
|
||||
while(parent && !fso.FolderExists(parent)) {
|
||||
scan.push(parent);
|
||||
parent = fso.GetParentFolderName(parent);
|
||||
}
|
||||
|
||||
//# Walk back down the path, creating folders
|
||||
for(i=scan.length-1;i>=0;i--) {
|
||||
if(!fso.FolderExists(scan[i])) {
|
||||
fso.CreateFolder(scan[i]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns null if it can't do it, false if there's an error, true if it saved OK
|
||||
function ieSaveFile(filePath,content)
|
||||
{
|
||||
ieCreatePath(filePath);
|
||||
try {
|
||||
var fso = new ActiveXObject("Scripting.FileSystemObject");
|
||||
} catch(ex) {
|
||||
//# alert("Exception while attempting to save\n\n" + ex.toString());
|
||||
return null;
|
||||
}
|
||||
var file = fso.OpenTextFile(filePath,2,-1,0);
|
||||
file.Write(content);
|
||||
file.Close();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns null if it can't do it, false if there's an error, or a string of the content if successful
|
||||
function ieLoadFile(filePath)
|
||||
{
|
||||
try {
|
||||
var fso = new ActiveXObject("Scripting.FileSystemObject");
|
||||
var file = fso.OpenTextFile(filePath,1);
|
||||
var content = file.ReadAll();
|
||||
file.Close();
|
||||
} catch(ex) {
|
||||
//# alert("Exception while attempting to load\n\n" + ex.toString());
|
||||
return null;
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
function ieCopyFile(dest,source)
|
||||
{
|
||||
ieCreatePath(dest);
|
||||
try {
|
||||
var fso = new ActiveXObject("Scripting.FileSystemObject");
|
||||
fso.GetFile(source).Copy(dest);
|
||||
} catch(ex) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns null if it can't do it, false if there's an error, true if it saved OK
|
||||
function mozillaSaveFile(filePath,content)
|
||||
{
|
||||
if(window.Components) {
|
||||
try {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
|
||||
file.initWithPath(filePath);
|
||||
if(!file.exists())
|
||||
file.create(0,0x01B4);// 0x01B4 = 0664
|
||||
var out = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
|
||||
out.init(file,0x22,0x04,null);
|
||||
out.write(content,content.length);
|
||||
out.flush();
|
||||
out.close();
|
||||
return true;
|
||||
} catch(ex) {
|
||||
//# alert("Exception while attempting to save\n\n" + ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Returns null if it can't do it, false if there's an error, or a string of the content if successful
|
||||
function mozillaLoadFile(filePath)
|
||||
{
|
||||
if(window.Components) {
|
||||
try {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
|
||||
file.initWithPath(filePath);
|
||||
if(!file.exists())
|
||||
return null;
|
||||
var inputStream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
|
||||
inputStream.init(file,0x01,0x04,null);
|
||||
var sInputStream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
|
||||
sInputStream.init(inputStream);
|
||||
var contents = sInputStream.read(sInputStream.available());
|
||||
sInputStream.close();
|
||||
inputStream.close();
|
||||
return contents;
|
||||
} catch(ex) {
|
||||
//# alert("Exception while attempting to load\n\n" + ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function javaUrlToFilename(url)
|
||||
{
|
||||
var f = "//localhost";
|
||||
if(url.indexOf(f) == 0)
|
||||
return url.substring(f.length);
|
||||
var i = url.indexOf(":");
|
||||
return i > 0 ? url.substring(i-1) : url;
|
||||
}
|
||||
|
||||
function javaSaveFile(filePath,content)
|
||||
{
|
||||
try {
|
||||
if(document.applets["TiddlySaver"])
|
||||
return document.applets["TiddlySaver"].saveFile(javaUrlToFilename(filePath),"UTF-8",content);
|
||||
} catch(ex) {
|
||||
}
|
||||
try {
|
||||
var s = new java.io.PrintStream(new java.io.FileOutputStream(javaUrlToFilename(filePath)));
|
||||
s.print(content);
|
||||
s.close();
|
||||
} catch(ex2) {
|
||||
return null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function javaLoadFile(filePath)
|
||||
{
|
||||
try {
|
||||
if(document.applets["TiddlySaver"]) {
|
||||
var ret = document.applets["TiddlySaver"].loadFile(javaUrlToFilename(filePath),"UTF-8");
|
||||
if(!ret)
|
||||
return null;
|
||||
return String(ret);
|
||||
}
|
||||
} catch(ex) {
|
||||
}
|
||||
var content = [];
|
||||
try {
|
||||
var r = new java.io.BufferedReader(new java.io.FileReader(javaUrlToFilename(filePath)));
|
||||
var line;
|
||||
while((line = r.readLine()) != null)
|
||||
content.push(String(line));
|
||||
r.close();
|
||||
} catch(ex2) {
|
||||
return null;
|
||||
}
|
||||
return content.join("\n");
|
||||
}
|
||||
|
103
test/data/tiddlywiki/js/FileSystemUtils.js
Executable file
103
test/data/tiddlywiki/js/FileSystemUtils.js
Executable file
@ -0,0 +1,103 @@
|
||||
//--
|
||||
//-- Filesystem utilities
|
||||
//--
|
||||
|
||||
function convertUTF8ToUnicode(u)
|
||||
{
|
||||
return config.browser.isOpera || !window.netscape ? manualConvertUTF8ToUnicode(u) : mozConvertUTF8ToUnicode(u);
|
||||
}
|
||||
|
||||
//# UTF-8 encoding rules:
|
||||
//# 0x0000 - 0x007F: 0xxxxxxx
|
||||
//# 0x0080 - 0x07FF: 110xxxxx 10xxxxxx
|
||||
//# 0x0800 - 0xFFFF: 1110xxxx 10xxxxxx 10xxxxxx
|
||||
|
||||
function manualConvertUTF8ToUnicode(utf)
|
||||
{
|
||||
var uni = utf;
|
||||
var src = 0;
|
||||
var dst = 0;
|
||||
var b1, b2, b3;
|
||||
var c;
|
||||
while(src < utf.length) {
|
||||
b1 = utf.charCodeAt(src++);
|
||||
if(b1 < 0x80) {
|
||||
dst++;
|
||||
} else if(b1 < 0xE0) {
|
||||
b2 = utf.charCodeAt(src++);
|
||||
c = String.fromCharCode(((b1 & 0x1F) << 6) | (b2 & 0x3F));
|
||||
uni = uni.substring(0,dst++).concat(c,utf.substr(src));
|
||||
} else {
|
||||
b2 = utf.charCodeAt(src++);
|
||||
b3 = utf.charCodeAt(src++);
|
||||
c = String.fromCharCode(((b1 & 0xF) << 12) | ((b2 & 0x3F) << 6) | (b3 & 0x3F));
|
||||
uni = uni.substring(0,dst++).concat(c,utf.substr(src));
|
||||
}
|
||||
}
|
||||
return uni;
|
||||
}
|
||||
|
||||
function mozConvertUTF8ToUnicode(u)
|
||||
{
|
||||
try {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
|
||||
converter.charset = "UTF-8";
|
||||
} catch(ex) {
|
||||
return manualConvertUTF8ToUnicode(u);
|
||||
} // fallback
|
||||
var s = converter.ConvertToUnicode(u);
|
||||
var fin = converter.Finish();
|
||||
return fin.length > 0 ? s+fin : s;
|
||||
}
|
||||
|
||||
//# convert unicode string to a format suitable for saving to file
|
||||
//# this should be UTF8, unless the browser does not support saving non-ASCII characters
|
||||
function convertUnicodeToFileFormat(s)
|
||||
{
|
||||
return config.browser.isOpera || !window.netscape ? (config.browser.isIE ? convertUnicodeToHtmlEntities(s) : s) : mozConvertUnicodeToUTF8(s);
|
||||
}
|
||||
|
||||
function convertUnicodeToHtmlEntities(s)
|
||||
{
|
||||
var re = /[^\u0000-\u007F]/g;
|
||||
return s.replace(re,function($0) {return "&#" + $0.charCodeAt(0).toString() + ";";});
|
||||
}
|
||||
|
||||
function convertUnicodeToUTF8(s)
|
||||
{
|
||||
// return convertUnicodeToFileFormat to allow plugin migration
|
||||
return convertUnicodeToFileFormat(s);
|
||||
}
|
||||
|
||||
function manualConvertUnicodeToUTF8(s)
|
||||
{
|
||||
return unescape(encodeURIComponent(s));
|
||||
}
|
||||
|
||||
function mozConvertUnicodeToUTF8(s)
|
||||
{
|
||||
try {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
|
||||
converter.charset = "UTF-8";
|
||||
} catch(ex) {
|
||||
return manualConvertUnicodeToUTF8(s);
|
||||
} // fallback
|
||||
var u = converter.ConvertFromUnicode(s);
|
||||
var fin = converter.Finish();
|
||||
return fin.length > 0 ? u + fin : u;
|
||||
}
|
||||
|
||||
function convertUriToUTF8(uri,charSet)
|
||||
{
|
||||
if(window.netscape == undefined || charSet == undefined || charSet == "")
|
||||
return uri;
|
||||
try {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
var converter = Components.classes["@mozilla.org/intl/utf8converterservice;1"].getService(Components.interfaces.nsIUTF8ConverterService);
|
||||
} catch(ex) {
|
||||
return uri;
|
||||
}
|
||||
return converter.convertURISpecToUTF8(uri,charSet);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user