1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2026-01-22 10:54:46 +00:00

Compare commits

...

36 Commits

Author SHA1 Message Date
Jermolene
8756d25d78 Version number update for 5.0.10-beta 2014-04-19 14:07:48 +01:00
Jermolene
8a27c2759b Update 5.0.10 release date 2014-04-19 14:06:29 +01:00
Jermolene
beddcd7138 New ribbon colour for 5.0.10 2014-04-19 13:15:24 +01:00
Jermolene
2db90378a2 Release note updates for 5.0.10 2014-04-19 11:34:23 +01:00
Jermolene
7684891285 Move topbar out of the way of scrollbars
In the process getting rid of some extraneous `<p>` tags.

Fixes #566
2014-04-19 11:32:56 +01:00
Jermolene
821f1f1428 Fix hamburger and seamless behaviour
No longer remove the tiddler borders when hiding the sidebar; users can
select Seamless theme to get the same effect.

Fixes #566
2014-04-19 11:24:41 +01:00
Jermolene
4538f081ee Release note updates for 5.0.10 2014-04-19 11:22:59 +01:00
Jermolene
b4122be50c Update release note for 5.0.10 2014-04-19 11:18:08 +01:00
Jermolene
cd76514105 Update roadmap 2014-04-19 09:36:14 +01:00
Jermolene
ba576d9f1b Add support for safe mode 2014-04-19 09:36:08 +01:00
Jermolene
15d0c27e2a Add [is[tag]] filter operator 2014-04-18 17:57:55 +01:00
Jermolene
869cec1ccc Add docs for date format strings 2014-04-18 17:37:13 +01:00
Jermolene
d6054f1039 Fix problem with offline copy of server edition
We were accidentally including all the shadow tiddlers as well as
ordinary ones.
2014-04-18 15:23:00 +01:00
Jermolene
9fbe72a877 Rearrange system tag configuration
By rearranging the `[all[]]` operator we are able to ensure that shadow
tiddlers get processed before ordinary tiddlers. This makes it easier
to create custom stylesheets that override the core.
2014-04-18 09:28:14 +01:00
Jermolene
89165fc51d Fix problem with sorting date fields
Introduced a couple of commits ago when the localeCompare() stuff was
added.
2014-04-17 22:52:57 +01:00
Jermolene
4758874d13 Add path conversions from TiddlyWiki Classic
TiddlyWiki Classic converts local file URIs to various local native
formats. The same conversions are now performed by the TiddlyFox
adaptor for TW5.
2014-04-17 22:30:14 +01:00
Jermolene
0153fd2a30 Correct typos in 5.0.9 release note 2014-04-17 20:26:35 +01:00
Jermolene
bb42c0ab36 Use localCompare for sorting strings
So that accented characters get sorted correctly. Or at least as
correctly as browsers allow.
2014-04-17 20:15:52 +01:00
Jermolene
95d291daac Update print stylesheet to hide topbar 2014-04-17 19:50:12 +01:00
Jermolene
45b0966013 Support the image widget in markdown 2014-04-17 16:50:54 +01:00
Jermolene
de07da3797 Revise warning about backing up before upgrading 2014-04-17 16:26:57 +01:00
Jeremy Ruston
aebc1ea943 Merge pull request #562 from pmario/upgrade-backup-info
add a backup info for the Upgrade tiddler.
2014-04-17 16:24:57 +01:00
Jermolene
73cfd10218 Fix regression with untagged filter operator
Restored previous behaviour of considering a missing tiddler to be
untagged.
2014-04-17 16:10:50 +01:00
Jermolene
d336ffea02 Fix incorrect background colour for sidebar tag pills
Fixes #568.
2014-04-17 15:11:59 +01:00
Jermolene
6da28e7365 Docs update 2014-04-17 14:44:14 +01:00
Jermolene
d08a2d109f Fix html parser tests 2014-04-17 14:43:24 +01:00
Jermolene
f57e047877 Fix issues with tiddlers with null fields
Fixing #567
2014-04-17 14:43:12 +01:00
Jermolene
df5fe10a40 Start release note for 5.0.10 2014-04-17 12:52:52 +01:00
Jermolene
433ac8e96e Typo fix 2014-04-17 12:52:38 +01:00
Jermolene
ad4b03506a Added wikitext image support
We’ve added a parser to recognise the `[img[URL or tiddler title]]`
format, and an associated image widget.
2014-04-17 12:52:32 +01:00
Jermolene
ace57dd205 Refactor utilities out of HTML parser
Some of the functions are useful general purpose parser helpers.
2014-04-17 12:00:32 +01:00
Jermolene
bd4a031df8 Fix problem with version checking logic
Previously, importing a plugin with a semantically identical version
number was not rejected. This meant that attempts to import
5.0.9-prerelease wikis into 5.0.9-beta led to a corrupted wiki, with a
beta core and prerelease plugins.
2014-04-17 11:59:42 +01:00
Jermolene
6db94052c7 Prepare for 5.0.10 release 2014-04-17 11:58:16 +01:00
Mario Pietsch
dd8797223a add a backup info for the Upgrade tiddler. 2014-04-16 01:09:26 +02:00
Jermolene
e54b0d7129 Docs fixes 2014-04-15 21:50:36 +01:00
Jermolene
07ab8c75b8 Docs fixes 2014-04-15 21:48:19 +01:00
55 changed files with 925 additions and 375 deletions

View File

@@ -352,7 +352,7 @@ $tw.utils.parseVersion = function(version) {
};
/*
Returns true if the version string A is greater than the version string B
Returns true if the version string A is greater than the version string B. Returns true if the versions are the same
*/
$tw.utils.checkVersions = function(versionStringA,versionStringB) {
var defaultVersion = {
@@ -369,7 +369,8 @@ $tw.utils.checkVersions = function(versionStringA,versionStringB) {
];
return (diff[0] > 0) ||
(diff[0] === 0 && diff[1] > 0) ||
(diff[0] === 0 && diff[1] === 0 && diff[2] > 0);
(diff[0] === 0 && diff[1] === 0 && diff[2] > 0) ||
(diff[0] === 0 && diff[1] === 0 && diff[2] === 0);
};
/*
@@ -749,7 +750,7 @@ $tw.Tiddler = function(/* [fields,] fields */) {
var arg = arguments[c],
src = (arg instanceof $tw.Tiddler) ? arg.fields : arg;
for(var t in src) {
if(src[t] === undefined) {
if(src[t] === undefined || src[t] === null) {
if(t in this.fields) {
delete this.fields[t]; // If we get a field that's undefined, delete any previous field value
}
@@ -1043,6 +1044,37 @@ $tw.Wiki.prototype.defineShadowModules = function() {
});
};
/*
Enable safe mode by deleting any tiddlers that override a shadow tiddler
*/
$tw.Wiki.prototype.processSafeMode = function() {
var self = this,
overrides = [];
// Find the overriding tiddlers
this.each(function(tiddler,title) {
if(self.isShadowTiddler(title)) {
console.log(title);
overrides.push(title);
}
});
// Assemble a report tiddler
var titleReportTiddler = "TiddlyWiki Safe Mode",
report = [];
report.push("TiddlyWiki has been started in [[safe mode|http://tiddlywiki.com/static/SafeMode.html]]. Most customisations have been disabled by renaming the following tiddlers:")
// Delete the overrides
overrides.forEach(function(title) {
var tiddler = self.getTiddler(title),
newTitle = "SAFE: " + title;
self.deleteTiddler(title);
self.addTiddler(new $tw.Tiddler(tiddler, {title: newTitle}));
report.push("* [[" + title + "|" + newTitle + "]]");
});
report.push()
this.addTiddler(new $tw.Tiddler({title: titleReportTiddler, text: report.join("\n\n")}));
// Set $:/DefaultTiddlers to point to our report
this.addTiddler(new $tw.Tiddler({title: "$:/DefaultTiddlers", text: "[[" + titleReportTiddler + "]]"}));
};
/*
Extracts tiddlers from a typed block of text, specifying default field values
*/
@@ -1562,6 +1594,8 @@ readBrowserTiddlers: whether to read tiddlers from the HTML file we're executing
*/
$tw.boot.startup = function(options) {
options = options || {};
// Check for safe mode
$tw.safeMode = $tw.browser && location.hash === "#:safe";
// Initialise some more $tw properties
$tw.utils.deepDefaults($tw,{
modules: { // Information about each module
@@ -1645,6 +1679,10 @@ $tw.boot.startup = function(options) {
$tw.wiki.readPluginInfo();
$tw.wiki.registerPluginTiddlers("plugin");
$tw.wiki.unpackPluginTiddlers();
// Process "safe mode"
if($tw.safeMode) {
$tw.wiki.processSafeMode();
}
// Register typed modules from the tiddlers we've just loaded
$tw.wiki.defineTiddlerModules();
// And any modules within plugins

View File

@@ -5,7 +5,7 @@ module-type: filteroperator
Filter operator for selecting tiddlers
[all[tiddlers+shadows]]
[all[shadows+tiddlers]]
\*/
(function(){

View File

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

View File

@@ -25,10 +25,8 @@ exports.untagged = function(source,operator,options) {
});
} else {
source(function(tiddler,title) {
if(tiddler) {
if(!tiddler.hasField("tags") || ($tw.utils.isArray(tiddler.fields.tags) && tiddler.fields.tags.length === 0)) {
$tw.utils.pushTop(results,title);
}
if(!tiddler || !tiddler.hasField("tags") || ($tw.utils.isArray(tiddler.fields.tags) && tiddler.fields.tags.length === 0)) {
$tw.utils.pushTop(results,title);
}
});
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -305,28 +305,20 @@ exports.sortTiddlers = function(titles,sortField,isDescending,isCaseSensitive,is
a = self.getTiddler(a).fields[sortField] || "";
b = self.getTiddler(b).fields[sortField] || "";
}
if(!isNumeric || isNaN(a) || isNaN(b)) {
if(!isCaseSensitive) {
if(typeof a === "string") {
a = a.toLowerCase();
}
if(typeof b === "string") {
b = b.toLowerCase();
}
}
}
else {
a-= 0;
b-= 0;
}
if(a < b) {
return isDescending ? +1 : -1;
if(isNumeric) {
a = Number(a);
b = Number(b);
return isDescending ? b - a : a - b;
} else if($tw.utils.isDate(a) && $tw.utils.isDate(b)) {
return isDescending ? b - a : a - b;
} else {
if(a > b) {
return isDescending ? -1 : +1;
} else {
return 0;
a = String(a);
b = String(b);
if(!isCaseSensitive) {
a = a.toLowerCase();
b = b.toLowerCase();
}
return isDescending ? b.localeCompare(a) : a.localeCompare(b);
}
});
};

View File

@@ -1,5 +1,5 @@
title: $:/AdvancedSearch
<div class="tw-advanced-search">
<<tabs "[all[tiddlers+shadows]tag[$:/tags/AdvancedSearch]!has[draft.of]]" "$:/core/ui/AdvancedSearch/System">>
<<tabs "[all[shadows+tiddlers]tag[$:/tags/AdvancedSearch]!has[draft.of]]" "$:/core/ui/AdvancedSearch/System">>
</div>

View File

@@ -12,7 +12,7 @@ caption: {{$:/language/Search/Filter/Caption}}
<div class="tw-block-dropdown-wrapper">
<$reveal state=<<qualify "$:/state/filterDropdown">> type="nomatch" text="" default="">
<div class="tw-block-dropdown tw-edit-type-dropdown">
<$list filter="[all[tiddlers+shadows]tag[$:/tags/Filter]]"><$link to={{!!filter}}><$transclude field="description"/></$link>
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Filter]]"><$link to={{!!filter}}><$transclude field="description"/></$link>
</$list>
</div>
</$reveal>

View File

@@ -1,5 +1,5 @@
title: $:/ControlPanel
<div class="tw-control-panel">
<<tabs "[all[tiddlers+shadows]tag[$:/tags/ControlPanel]!has[draft.of]]" "$:/core/ui/ControlPanel/Basics">>
<<tabs "[all[shadows+tiddlers]tag[$:/tags/ControlPanel]!has[draft.of]]" "$:/core/ui/ControlPanel/Basics">>
</div>

View File

@@ -5,5 +5,5 @@ caption: {{$:/language/ControlPanel/Advanced/Caption}}
{{$:/language/ControlPanel/Advanced/Hint}}
<div class="tw-control-panel">
<<tabs "[all[tiddlers+shadows]tag[$:/tags/ControlPanel/Advanced]!has[draft.of]]" "$:/core/ui/ControlPanel/Advanced/TiddlerFields">>
<<tabs "[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Advanced]!has[draft.of]]" "$:/core/ui/ControlPanel/Advanced/TiddlerFields">>
</div>

View File

@@ -5,5 +5,5 @@ caption: {{$:/language/ControlPanel/Appearance/Caption}}
{{$:/language/ControlPanel/Appearance/Hint}}
<div class="tw-control-panel">
<<tabs "[all[tiddlers+shadows]tag[$:/tags/ControlPanel/Appearance]!has[draft.of]]" "$:/core/ui/ControlPanel/Appearance/Theme">>
<<tabs "[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Appearance]!has[draft.of]]" "$:/core/ui/ControlPanel/Appearance/Theme">>
</div>

View File

@@ -6,7 +6,7 @@ tw-tiddler-frame tw-tiddler-edit-frame $(missingTiddlerClass)$ $(shadowTiddlerCl
<div class=<<frame-classes>>>
<$set name="storyTiddler" value=<<currentTiddler>>>
<$keyboard key="ctrl+enter" message="tw-save-tiddler">
<$list filter="[all[tiddlers+shadows]tag[$:/tags/EditTemplate]!has[draft.of]]" variable="listItem">
<$list filter="[all[shadows+tiddlers]tag[$:/tags/EditTemplate]!has[draft.of]]" variable="listItem">
<$transclude tiddler=<<listItem>>/>
</$list>
</$keyboard>

View File

@@ -1,4 +1,4 @@
title: $:/core/ui/EditTemplate/controls
tags: $:/tags/EditTemplate
<span class="tw-tiddler-controls titlebar"> <$list filter="[all[tiddlers+shadows]tag[$:/tags/EditToolbar]!has[draft.of]]" variable="listItem"><$transclude tiddler=<<listItem>>/></$list> </span>
<span class="tw-tiddler-controls titlebar"> <$list filter="[all[shadows+tiddlers]tag[$:/tags/EditToolbar]!has[draft.of]]" variable="listItem"><$transclude tiddler=<<listItem>>/></$list> </span>

View File

@@ -8,7 +8,7 @@ tags: $:/tags/EditTemplate
<$reveal state=<<qualify "$:/state/typeDropdown">> type="nomatch" text="" default="">
<div class="tw-block-dropdown tw-edit-type-dropdown">
<$linkcatcher to="!!type">
<$list filter="[all[tiddlers+shadows]prefix[$:/language/Docs/Types/]] +[sort[description]]"><$link to={{!!name}}><$view field="description"/> (<$view field="name"/>)</$link>
<$list filter="[all[shadows+tiddlers]prefix[$:/language/Docs/Types/]] +[sort[description]]"><$link to={{!!name}}><$view field="description"/> (<$view field="name"/>)</$link>
</$list>
</$linkcatcher>
</div>

View File

@@ -1,5 +1,5 @@
title: $:/core/Filters/SystemTags
tags: $:/tags/Filter
filter: [all[tiddlers+shadows]tags[]is[system]sort[title]]
filter: [all[shadows+tiddlers]tags[]is[system]sort[title]]
description: {{$:/language/Filters/SystemTags}}

View File

@@ -3,7 +3,7 @@ tags: $:/tags/MoreSideBar
caption: {{$:/language/SideBar/Tags/Caption}}
\define lingo-base() $:/language/SideBar/Tags/
<$button to="$:/TagManager"><<lingo TagManager/Caption>></$button>
<$button to="$:/TagManager" class="btn"><<lingo TagManager/Caption>></$button>
<$list filter="[tags[]!is[system]sort[title]]">

View File

@@ -54,6 +54,6 @@ background-image: -ms-linear-gradient($gradient$);
\end
<$list filter="[all[tiddlers+shadows]tag[$:/tags/stylesheet]]">
<$list filter="[all[shadows+tiddlers]tag[$:/tags/stylesheet]]">
<$transclude/>
</$list>

View File

@@ -16,7 +16,7 @@ tw-page-container tw-page-view-$(themeTitle)$ tw-language-$(languageTitle)$
<$dropzone>
<$list filter="[all[tiddlers+shadows]tag[$:/tags/PageTemplate]!has[draft.of]]" variable="listItem">
<$list filter="[all[shadows+tiddlers]tag[$:/tags/PageTemplate]!has[draft.of]]" variable="listItem">
<$transclude tiddler=<<listItem>>/>

View File

@@ -3,6 +3,6 @@ tags: $:/tags/PageTemplate
<div class="tw-alerts">
<$list filter="[all[tiddlers+shadows]tag[$:/tags/Alert]!has[draft.of]]" template="$:/core/ui/AlertTemplate" storyview="pop"/>
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Alert]!has[draft.of]]" template="$:/core/ui/AlertTemplate" storyview="pop"/>
</div>

View File

@@ -21,7 +21,7 @@ tags: $:/tags/PageTemplate
<div class="tw-page-controls">
<$list filter="[all[tiddlers+shadows]tag[$:/tags/PageControls]!has[draft.of]]" variable="listItem">
<$list filter="[all[shadows+tiddlers]tag[$:/tags/PageControls]!has[draft.of]]" variable="listItem">
<$transclude tiddler=<<listItem>> mode="inline"/>

View File

@@ -3,6 +3,10 @@ tags: $:/tags/PageTemplate
<span class="tw-topbar tw-topbar-left">
<$list filter="[all[tiddlers+shadows]tag[$:/tags/TopLeftBar]!has[draft.of]]" variable="listItem"><$transclude tiddler=<<listItem>>/></$list>
<$list filter="[all[shadows+tiddlers]tag[$:/tags/TopLeftBar]!has[draft.of]]" variable="listItem">
<$transclude tiddler=<<listItem>> mode="inline"/>
</$list>
</span>

View File

@@ -3,6 +3,10 @@ tags: $:/tags/PageTemplate
<span class="tw-topbar tw-topbar-right">
<$list filter="[all[tiddlers+shadows]tag[$:/tags/TopRightBar]!has[draft.of]]" variable="listItem"><$transclude tiddler=<<listItem>>/></$list>
<$list filter="[all[shadows+tiddlers]tag[$:/tags/TopRightBar]!has[draft.of]]" variable="listItem">
<$transclude tiddler=<<listItem>> mode="inline"/>
</$list>
</span>

View File

@@ -3,5 +3,5 @@ tags: $:/tags/SideBar
caption: {{$:/language/SideBar/More/Caption}}
<div class="tw-more-sidebar">
<<tabs "[all[tiddlers+shadows]tag[$:/tags/MoreSideBar]!has[draft.of]]" "$:/core/ui/MoreSideBar/Tags" "$:/state/tab/moresidebar">>
<<tabs "[all[shadows+tiddlers]tag[$:/tags/MoreSideBar]!has[draft.of]]" "$:/core/ui/MoreSideBar/Tags" "$:/state/tab/moresidebar">>
</div>

View File

@@ -18,6 +18,6 @@ title: $:/core/ui/SideBarLists
</div>
</$reveal>
<$reveal state="$:/temp/search" type="match" text="">
<<tabs "[all[tiddlers+shadows]tag[$:/tags/SideBar]!has[draft.of]]" "$:/core/ui/SideBar/Open" "$:/state/tab/sidebar">>
<<tabs "[all[shadows+tiddlers]tag[$:/tags/SideBar]!has[draft.of]]" "$:/core/ui/SideBar/Open" "$:/state/tab/sidebar">>
</$reveal>
</div>

View File

@@ -7,7 +7,7 @@ title: $:/TagManager
<$reveal state=<<qualify "$:/state/iconDropdown/$title$">> type="nomatch" text="" default="">
<$linkcatcher to="$title$!!icon">
<div class="tw-block-dropdown tw-edit-type-dropdown">
<$list filter="[all[tiddlers+shadows]is[image]] [all[tiddlers+shadows]tag[$:/tags/Image]] +[sort[title]]">
<$list filter="[all[shadows+tiddlers]is[image]] [all[shadows+tiddlers]tag[$:/tags/Image]] +[sort[title]]">
<$link to={{!!title}}>
<$view field="title"/>
</$link>

View File

@@ -1,3 +1,3 @@
title: $:/core/ui/TiddlerInfo
<<tabs "[all[tiddlers+shadows]tag[$:/tags/TiddlerInfo]!has[draft.of]]" "$:/core/ui/TiddlerInfo/References">>
<<tabs "[all[shadows+tiddlers]tag[$:/tags/TiddlerInfo]!has[draft.of]]" "$:/core/ui/TiddlerInfo/References">>

View File

@@ -2,7 +2,7 @@ title: $:/core/ui/TiddlerInfo/Advanced
tags: $:/tags/TiddlerInfo
caption: {{$:/language/TiddlerInfo/Advanced/Caption}}
<$list filter="[all[tiddlers+shadows]tag[$:/tags/TiddlerInfo/Advanced]!has[draft.of]]" variable="listItem">
<$list filter="[all[shadows+tiddlers]tag[$:/tags/TiddlerInfo/Advanced]!has[draft.of]]" variable="listItem">
<$transclude tiddler=<<listItem>>/>
</$list>

View File

@@ -3,6 +3,6 @@ title: $:/core/ui/ViewTemplate
\define frame-classes()
tw-tiddler-frame tw-tiddler-view-frame $(missingTiddlerClass)$ $(shadowTiddlerClass)$ $(systemTiddlerClass)$
\end
<$set name="storyTiddler" value=<<currentTiddler>>><$set name="tiddlerInfoState" value=<<qualify "$:/state/tiddlerInfo">>><$tiddler tiddler=<<currentTiddler>>><div class=<<frame-classes>>><$list filter="[all[tiddlers+shadows]tag[$:/tags/ViewTemplate]!has[draft.of]]" variable="listItem"><$transclude tiddler=<<listItem>>/></$list>
<$set name="storyTiddler" value=<<currentTiddler>>><$set name="tiddlerInfoState" value=<<qualify "$:/state/tiddlerInfo">>><$tiddler tiddler=<<currentTiddler>>><div class=<<frame-classes>>><$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewTemplate]!has[draft.of]]" variable="listItem"><$transclude tiddler=<<listItem>>/></$list>
</div>
</$tiddler></$set></$set>

View File

@@ -7,7 +7,7 @@ fill:$(foregroundColor)$;
<div class="tw-tiddler-title">
<div class="titlebar">
<span class="tw-tiddler-controls">
<$list filter="[all[tiddlers+shadows]tag[$:/tags/ViewToolbar]!has[draft.of]]" variable="listItem"><$transclude tiddler=<<listItem>>/></$list>
<$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewToolbar]!has[draft.of]]" variable="listItem"><$transclude tiddler=<<listItem>>/></$list>
</span>
<$set name="foregroundColor" value={{!!color}}>
<span style=<<title-styles>>>

View File

@@ -4,7 +4,7 @@ title: $:/snippets/paletteswitcher
<<lingo Prompt>> <$view tiddler={{$:/palette}} field="name"/>
<$linkcatcher to="$:/palette">
<div class="tw-chooser"><$list filter="[all[tiddlers+shadows]tag[$:/tags/Palette]sort[description]]"><div class="tw-chooser-item"><$link to={{!!title}}><div><$reveal state="$:/palette" type="match" text={{!!title}}>&bull;</$reveal><$reveal state="$:/palette" type="nomatch" text={{!!title}}>&nbsp;</$reveal> ''<$view field="name" format="text"/>'' - <$view field="description" format="text"/></div><$transclude tiddler="$:/snippets/currpalettepreview"/></$link></div>
<div class="tw-chooser"><$list filter="[all[shadows+tiddlers]tag[$:/tags/Palette]sort[description]]"><div class="tw-chooser-item"><$link to={{!!title}}><div><$reveal state="$:/palette" type="match" text={{!!title}}>&bull;</$reveal><$reveal state="$:/palette" type="nomatch" text={{!!title}}>&nbsp;</$reveal> ''<$view field="name" format="text"/>'' - <$view field="description" format="text"/></div><$transclude tiddler="$:/snippets/currpalettepreview"/></$link></div>
</$list>
</div>
</$linkcatcher>

View File

@@ -23,127 +23,127 @@ describe("HTML tag new parser tests", function() {
var parser = new FakeParser();
it("should parse whitespace", function() {
expect(parser.parseWhiteSpace("p ",0)).toEqual(
expect($tw.utils.parseWhiteSpace("p ",0)).toEqual(
null
);
expect(parser.parseWhiteSpace("p ",1)).toEqual(
expect($tw.utils.parseWhiteSpace("p ",1)).toEqual(
{ type : 'whitespace', start : 1, end : 3 }
);
});
it("should parse string tokens", function() {
expect(parser.parseTokenString("p= ",0,"=")).toEqual(
expect($tw.utils.parseTokenString("p= ",0,"=")).toEqual(
null
);
expect(parser.parseTokenString("p= ",1,"=")).toEqual(
expect($tw.utils.parseTokenString("p= ",1,"=")).toEqual(
{ type : 'token', value : '=', start : 1, end : 2 }
);
});
it("should parse regexp tokens", function() {
expect(parser.parseTokenRegExp("p=' ",0,/(=(?:'|"))/)).toEqual(
expect($tw.utils.parseTokenRegExp("p=' ",0,/(=(?:'|"))/)).toEqual(
null
);
expect(parser.parseTokenRegExp("p=' ",1,/(=(?:'|"))/g).match[0]).toEqual(
expect($tw.utils.parseTokenRegExp("p=' ",1,/(=(?:'|"))/g).match[0]).toEqual(
'=\''
);
expect(parser.parseTokenRegExp("p=blah ",2,/([^\s>]+)/g).match[0]).toEqual(
expect($tw.utils.parseTokenRegExp("p=blah ",2,/([^\s>]+)/g).match[0]).toEqual(
'blah'
);
});
it("should parse string literals", function() {
expect(parser.parseStringLiteral("p='blah' ",0)).toEqual(
expect($tw.utils.parseStringLiteral("p='blah' ",0)).toEqual(
null
);
expect(parser.parseStringLiteral("p='blah' ",2)).toEqual(
expect($tw.utils.parseStringLiteral("p='blah' ",2)).toEqual(
{ type : 'string', start : 2, value : 'blah', end : 8 }
);
expect(parser.parseStringLiteral("p='' ",2)).toEqual(
expect($tw.utils.parseStringLiteral("p='' ",2)).toEqual(
{ type : 'string', start : 2, value : '', end : 4 }
);
expect(parser.parseStringLiteral("p=\"blah' ",2)).toEqual(
expect($tw.utils.parseStringLiteral("p=\"blah' ",2)).toEqual(
null
);
expect(parser.parseStringLiteral("p=\"\" ",2)).toEqual(
expect($tw.utils.parseStringLiteral("p=\"\" ",2)).toEqual(
{ type : 'string', start : 2, value : '', end : 4 }
);
});
it("should parse macro parameters", function() {
expect(parser.parseMacroParameter("me",0)).toEqual(
expect($tw.utils.parseMacroParameter("me",0)).toEqual(
{ type : 'macro-parameter', start : 0, value : 'me', end : 2 }
);
expect(parser.parseMacroParameter("me:one",0)).toEqual(
expect($tw.utils.parseMacroParameter("me:one",0)).toEqual(
{ type : 'macro-parameter', start : 0, value : 'one', name : 'me', end : 6 }
);
expect(parser.parseMacroParameter("me:'one two three'",0)).toEqual(
expect($tw.utils.parseMacroParameter("me:'one two three'",0)).toEqual(
{ type : 'macro-parameter', start : 0, value : 'one two three', name : 'me', end : 18 }
);
expect(parser.parseMacroParameter("'one two three'",0)).toEqual(
expect($tw.utils.parseMacroParameter("'one two three'",0)).toEqual(
{ type : 'macro-parameter', start : 0, value : 'one two three', end : 15 }
);
expect(parser.parseMacroParameter("me:[[one two three]]",0)).toEqual(
expect($tw.utils.parseMacroParameter("me:[[one two three]]",0)).toEqual(
{ type : 'macro-parameter', start : 0, value : 'one two three', name : 'me', end : 20 }
);
expect(parser.parseMacroParameter("[[one two three]]",0)).toEqual(
expect($tw.utils.parseMacroParameter("[[one two three]]",0)).toEqual(
{ type : 'macro-parameter', start : 0, value : 'one two three', end : 17 }
);
expect(parser.parseMacroParameter("myparam>",0)).toEqual(
expect($tw.utils.parseMacroParameter("myparam>",0)).toEqual(
{ type : 'macro-parameter', start : 0, value : 'myparam', end : 7 }
);
});
it("should parse macro invocations", function() {
expect(parser.parseMacroInvocation("<<mymacro",0)).toEqual(
expect($tw.utils.parseMacroInvocation("<<mymacro",0)).toEqual(
null
);
expect(parser.parseMacroInvocation("<<mymacro>>",0)).toEqual(
expect($tw.utils.parseMacroInvocation("<<mymacro>>",0)).toEqual(
{ type : 'macrocall', start : 0, params : [ ], name : 'mymacro', end : 11 }
);
expect(parser.parseMacroInvocation("<<mymacro one two three>>",0)).toEqual(
expect($tw.utils.parseMacroInvocation("<<mymacro one two three>>",0)).toEqual(
{ type : 'macrocall', start : 0, params : [ { type : 'macro-parameter', start : 9, value : 'one', end : 13 }, { type : 'macro-parameter', start : 13, value : 'two', end : 17 }, { type : 'macro-parameter', start : 17, value : 'three', end : 23 } ], name : 'mymacro', end : 25 }
);
expect(parser.parseMacroInvocation("<<mymacro p:one q:two three>>",0)).toEqual(
expect($tw.utils.parseMacroInvocation("<<mymacro p:one q:two three>>",0)).toEqual(
{ type : 'macrocall', start : 0, params : [ { type : 'macro-parameter', start : 9, value : 'one', name : 'p', end : 15 }, { type : 'macro-parameter', start : 15, value : 'two', name : 'q', end : 21 }, { type : 'macro-parameter', start : 21, value : 'three', end : 27 } ], name : 'mymacro', end : 29 }
);
expect(parser.parseMacroInvocation("<<mymacro 'one two three'>>",0)).toEqual(
expect($tw.utils.parseMacroInvocation("<<mymacro 'one two three'>>",0)).toEqual(
{ type : 'macrocall', start : 0, params : [ { type : 'macro-parameter', start : 9, value : 'one two three', end : 25 } ], name : 'mymacro', end : 27 }
);
expect(parser.parseMacroInvocation("<<mymacro r:'one two three'>>",0)).toEqual(
expect($tw.utils.parseMacroInvocation("<<mymacro r:'one two three'>>",0)).toEqual(
{ type : 'macrocall', start : 0, params : [ { type : 'macro-parameter', start : 9, value : 'one two three', name : 'r', end : 27 } ], name : 'mymacro', end : 29 }
);
expect(parser.parseMacroInvocation("<<myMacro one:two three:'four and five'>>",0)).toEqual(
expect($tw.utils.parseMacroInvocation("<<myMacro one:two three:'four and five'>>",0)).toEqual(
{ type : 'macrocall', start : 0, params : [ { type : 'macro-parameter', start : 9, value : 'two', name : 'one', end : 17 }, { type : 'macro-parameter', start : 17, value : 'four and five', name : 'three', end : 39 } ], name : 'myMacro', end : 41 }
);
});
it("should parse HTML attributes", function() {
expect(parser.parseAttribute("p='blah' ",1)).toEqual(
expect($tw.utils.parseAttribute("p='blah' ",1)).toEqual(
null
);
expect(parser.parseAttribute("p='blah' ",0)).toEqual(
expect($tw.utils.parseAttribute("p='blah' ",0)).toEqual(
{ type : 'string', start : 0, name : 'p', value : 'blah', end : 8 }
);
expect(parser.parseAttribute("p=\"blah\" ",0)).toEqual(
expect($tw.utils.parseAttribute("p=\"blah\" ",0)).toEqual(
{ type : 'string', start : 0, name : 'p', value : 'blah', end : 8 }
);
expect(parser.parseAttribute("p=blah ",0)).toEqual(
expect($tw.utils.parseAttribute("p=blah ",0)).toEqual(
{ type : 'string', start : 0, name : 'p', value : 'blah', end : 6 }
);
expect(parser.parseAttribute("p =blah ",0)).toEqual(
expect($tw.utils.parseAttribute("p =blah ",0)).toEqual(
{ type : 'string', start : 0, name : 'p', value : 'blah', end : 7 }
);
expect(parser.parseAttribute("p= blah ",0)).toEqual(
expect($tw.utils.parseAttribute("p= blah ",0)).toEqual(
{ type : 'string', start : 0, name : 'p', value : 'blah', end : 7 }
);
expect(parser.parseAttribute("p = blah ",0)).toEqual(
expect($tw.utils.parseAttribute("p = blah ",0)).toEqual(
{ type : 'string', start : 0, name : 'p', value : 'blah', end : 8 }
);
expect(parser.parseAttribute("p = >blah ",0)).toEqual(
expect($tw.utils.parseAttribute("p = >blah ",0)).toEqual(
{ type : 'string', value : 'true', start : 0, name : 'p', end : 4 }
);
expect(parser.parseAttribute(" attrib1>",0)).toEqual(
expect($tw.utils.parseAttribute(" attrib1>",0)).toEqual(
{ type : 'string', value : 'true', start : 0, name : 'attrib1', end : 8 }
);
});

View File

@@ -33,7 +33,7 @@ Previously, it was common to have `[is[shadow]]` at the start of a filter string
In 5.0.9, that filter has been changed to:
```
[all[tiddlers+shadows]tag[$:/tags/AdvancedSearch]!has[draft.of]]
[all[shadows+tiddlers]tag[$:/tags/AdvancedSearch]!has[draft.of]]
```
Note how the ''all'' operator allows operations to be performed on tiddlers from combinations of sources.

View File

@@ -0,0 +1,40 @@
created: 20140416160234142
modified: 20140416160234142
tags: releasenote
title: Release 5.0.10-beta
type: text/vnd.tiddlywiki
released: 201404191305
//[[See GitHub for detailed change history of this release|https://github.com/Jermolene/TiddlyWiki5/compare/v5.0.9-beta...v5.0.10-beta]]//
!! Highlights
* [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/ad4b03506a62d7110cb30aaa3d6f8dbfc712f246]] new syntax for [[Images in WikiText]] and a new ImageWidget
* [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/ba576d9f1b2146cec293447b2968e34f0c594a05]] support for a SafeMode that disables customisations
!! Documentation Improvements
* Added DateFormat documentation
!! Usability Improvements
* [[Refactor|https://github.com/Jermolene/TiddlyWiki5/commit/bb42c0ab360760917ad5bde84f15350186a9471a]] sorting to respect accented characters
* [[Support|https://github.com/Jermolene/TiddlyWiki5/commit/45b0966013c760abab5b3f7faea0e59af2ca5619]] embedded images in Markdown tiddlers
* [[Refactored|https://github.com/Jermolene/TiddlyWiki5/commit/821f1f1428f92160ae8bc4fa71dd3f947243f09e]] sidebar hiding action so that the story river border is maintained
!! Hackability Improvements
* [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/15d0c27e2a82359616ce6c7883557cd2ef1886cd]] `[is[tag]]` to the [[FilterOperator: is]]
* [[Hide|https://github.com/Jermolene/TiddlyWiki5/commit/95d291daac4a26664f0c232175f54780f0fa678f]] the top bars in the print stylesheet
!! Bug Fixes
* [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/4758874d13430338da07727997d0c4df7f328ac1]] support for saving changes on Windows network drives
* [[Refactored|https://github.com/Jermolene/TiddlyWiki5/commit/9fbe72a8778ae94c7d6322ad4b9155c83f753113]] configuration processing so that ordinary tiddlers are processed after shadow tiddlers. This resolves an issue whereby user stylesheets were being overridden by shadow stylesheets
* [[Fixed|https://github.com/Jermolene/TiddlyWiki5/commit/d6054f10392c535ca430f3e73b9b68d0f8c18498]] issue with offline snapshot of server edition erroneously including shadow tiddlers
* [[Fixed|https://github.com/Jermolene/TiddlyWiki5/commit/bd4a031df8a68287475a41ad84b423ad83f735a3]] problem with corrupted upgrades from 5.0.x-prerelease to 5.0.x-beta
* [[Fixed|https://github.com/Jermolene/TiddlyWiki5/commit/73cfd1021809e97906ecfd5dacdf2337da3abae9]] bug with `[untagged[]]` filter operator
* [[Fixed|https://github.com/Jermolene/TiddlyWiki5/commit/d336ffea02621e382f6d7135847d11e49e77bc26]] incorrect background colour for tag pills in the sidebar
* [[Fixed|https://github.com/Jermolene/TiddlyWiki5/commit/f57e04787738ad30fb05ac0e592239075b90507e]] issues with null fields under TiddlyWeb
* [[Fixed|https://github.com/Jermolene/TiddlyWiki5/commit/768489128547cf54e80fc321f3f1f4f5cd191862]] problem with hamburger overlapping scrollbars

View File

@@ -29,7 +29,7 @@ released: 201404152139
* Made the dropdown arrow icon [[skinnier|https://github.com/Jermolene/TiddlyWiki5/commit/ec90ac99cf2767b6ff20902d8b01aa1c36778147]]
* [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/bca1d552803c1839e7385765314f81c5307632b8]] validation of legal characters for fieldnames
* Added blacklisting of unsage HTML [[elements|https://github.com/Jermolene/TiddlyWiki5/commit/ba6edd42c125cb19d955a1cb3f54a2d367cb79dc]] and [[attributes|https://github.com/Jermolene/TiddlyWiki5/commit/ba6edd42c125cb19d955a1cb3f54a2d367cb79dc]]
* Added blacklisting of unsafe HTML [[elements|https://github.com/Jermolene/TiddlyWiki5/commit/ba6edd42c125cb19d955a1cb3f54a2d367cb79dc]] and [[attributes|https://github.com/Jermolene/TiddlyWiki5/commit/d0caf21b2df9fda9800eb30489003a87cafb1277]]
* [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/baa8cf3dd098bab0a7a8c78b24747c69bd40889f]] a warning indicator to tiddlers in TiddlyWikiClassic format
* [[Add|https://github.com/Jermolene/TiddlyWiki5/commit/42c67cfeb732fccb10b8ab574c84090dc2471352]] tiddler info ''Advanced'' panel with information about plugins and shadow tiddlers
* [[Improved|https://github.com/Jermolene/TiddlyWiki5/commit/96457d801159958b897f98e22aa9af53b97f0e35]] layout of [[$:/ControlPanel]] ''Plugins'' tab
@@ -41,8 +41,7 @@ released: 201404152139
!! Hackability Improvements
* [[Updated|https://github.com/Jermolene/TiddlyWiki5/commit/bdbbf94326f70db0f8ef196270ab9e92bfde10fb]] [[Transclusion in WikiText]] syntax to allow translusion of a template without affecting the current tiddler
* [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/8a7d0f53d380e9ca93ee34d8ad05090d511e95c4]] `sourceURL` handling to `eval()` so that tiddler modules can be [[properly debugged|https://chromedevtools.googlecode.com/svn-history/r421/trunk/tutorials/b
reapoints/index.html#regular]] in Chrome
* [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/8a7d0f53d380e9ca93ee34d8ad05090d511e95c4]] `sourceURL` handling to `eval()` so that tiddler modules can be [[properly debugged|https://chromedevtools.googlecode.com/svn-history/r421/trunk/tutorials/breapoints/index.html#regular]] in Chrome
* New ScrollableWidget giving better control over scrollable regions
* [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/d3c0296a87198296cff26aa7ce7bb8274cdcc3f7]] new CSS class `tw-site-title` for the site title
* [[Disable|https://github.com/Jermolene/TiddlyWiki5/commit/e397e4d15951c1395c7752a7563f002ca459206e]] the TiddlyWeb sync adaptor unless the wiki is loaded over HTTP
@@ -54,7 +53,7 @@ reapoints/index.html#regular]] in Chrome
* [[Extend|https://github.com/Jermolene/TiddlyWiki5/commit/f649b5b037bfd2e7c48d1ba65ffa37064456523d]] the ButtonWidget to be able to set text references
* [[Add|https://github.com/Jermolene/TiddlyWiki5/commit/afa677b9a0b1dff1239dc1ea08edd210b9736af9]] a class to tiddler frames in view mode
* [[Added|https://github.com/Jermolene/TiddlyWiki5/commit/50cf9678cb469e443e220b063e2355c844e417e7]] support for [[WidgetMessage: tw-home]]
* [[Hidden|https://github.com/Jermolene/TiddlyWiki5/commit/2608a323ebf3d8a8e925eda6d3a10ebb8f41d383]] system tags from the sidebar ''Tags' tab
* [[Hidden|https://github.com/Jermolene/TiddlyWiki5/commit/2608a323ebf3d8a8e925eda6d3a10ebb8f41d383]] system tags from the sidebar ''Tags'' tab
* [[Allow|https://github.com/Jermolene/TiddlyWiki5/commit/98872bbe7c62faa4aa209fa421c2989aeef3aaf2]] pasting and import of HTML content
* [[Add|https://github.com/Jermolene/TiddlyWiki5/commit/a5a2c718b1d5671652d01e3567dba1c6795b7521]] support for a tooltip on the LinkWidget

View File

@@ -1,11 +1,13 @@
created: 20131202102427114
modified: 20140126135354379
modified: 20140419082835626
tags: howto
title: Upgrading
type: text/vnd.tiddlywiki
There are several methods for upgrading an existing TiddlyWiki version 5 document to a new release. There is a [[different procedure|Upgrading TiddlyWiki on Node.js]] for upgrading [[TiddlyWiki on Node.js]].
Regardless of which method you use it is very important to exercise caution when upgrading existing wikis. In particular, make sure that you keep careful backups of your content -- in some situations problems with the upgrade may not be immediately apparent.
<div class="tw-message-box">
<a class="tw-message-icon" href="http://tiddlywiki.com/" target="_blank">{{TiddlyWiki Classic.png}}</a>
@@ -45,3 +47,7 @@ This will download a file called ''empty.html'' to your computer. This file is t
! Offline upgrading
You can also download http://tiddlywiki.com/empty.html locally and perform the same drag-and-drop procedure to upgrade your files.
! Problems with Upgrades
Particularly during the beta, it is possible for a customisation applied in a previous version to break when upgraded to the latest version. Use SafeMode to investigate and fix these problems.

View File

@@ -22,4 +22,4 @@ System tags are used to give special behaviour to tiddlers:
These are the system tags in use in this wiki:
{{{ [all[tiddlers+shadows]tags[]prefix[$:/]] +[sort[title]] }}}
{{{ [all[shadows+tiddlers]tags[]prefix[$:/]] +[sort[title]] }}}

View File

@@ -0,0 +1,45 @@
created: 20140418142957325
modified: 20140418163615916
tags: features
title: DateFormat
type: text/vnd.tiddlywiki
The ViewWidget accepts a `template` attribute that allows the format of date values to be specified. The format string is processed with the following substitutions:
|!Token |!Substituted Value |
|`DDD` |Day of week in full (eg, "Monday") |
|`ddd` |Short day of week (eg, "Mon") |
|`DD` |Day of month |
|`0DD` |Adds a leading zero |
|`DDth` |Adds a suffix |
|`WW` |~ISO-8601 week number of year |
|`0WW` |Adds a leading zero |
|`MMM` |Month in full (eg, "July") |
|`mmm` |Short month (eg, "Jul") |
|`MM` |Month number |
|`0MM` |Adds leading zero |
|`YYYY` |Full year |
|`YY` |Two digit year |
|`wYYYY` |Full year with respect to week number |
|`wYY` |Two digit year with respect to week number |
|`hh` |Hours |
|`0hh` |Adds a leading zero |
|`hh12` |Hours in 12 hour clock |
|`0hh12` |Hours in 12 hour clock with leading zero |
|`mm` |Minutes |
|`0mm` |Minutes with leading zero |
|`ss` |Seconds |
|`0ss` |Seconds with leading zero |
|`am` or `pm` |Lower case AM/PM indicator |
|`AM` or `PM` |Upper case AM/PM indicator |
|`TZD` |Timezone offset |
|`\x` |Used to escape a character that would otherwise have special meaning |
Note that other text is passed through unchanged, allowing commas, colons or other separators to be used.
! Examples
|!Template |!Output |
|`DDth MMM YYYY` |16th February 2011 |
|`DDth MMM \M\M\M YYYY` |16th February MMM 2011 |
|`DDth mmm hh:mm:ss` |16th Feb 2011 11:38:42 |

View File

@@ -0,0 +1,21 @@
created: 20140419082845576
modified: 20140419083436245
tags: features
title: SafeMode
type: text/vnd.tiddlywiki
! Introduction
Safe mode provides a way to disabling most customisations in TiddlyWiki. This is useful because if TiddlyWiki is customised incorrectly it can be rendered inoperable. A particular issue is that some customisations break when upgrading to a newer core version of TiddlyWiki (especially during the beta).
! Enabling Safe Mode
Safe mode is enabled in the browser by starting TiddlyWiki with the URL hash set to the string `#:safe`. For example:
http://tiddlywiki.com/#:safe
! How Safe Mode Works
In safe mode, any tiddlers that override shadow tiddlers are renamed to give them the prefix `SAFE: `, thus restoring the underlying shadow tiddler.
A report tiddler is displayed that allows you to inspect the tiddlers that were renamed.

View File

@@ -1,5 +1,5 @@
created: 20140410103123179
modified: 20140410103123179
modified: 20140418103123179
tags: filters commonfilters
title: FilterOperator: is
type: text/vnd.tiddlywiki
@@ -13,6 +13,7 @@ The ''is'' filter operator selects tiddlers from the current list according to t
* `[is[shadow]]` - tiddlers that are ShadowTiddlers
* `[is[system]]` - tiddlers that are SystemTiddlers
* `[is[tiddler]]` - tiddlers that are not MissingTiddlers
* `[is[tag]]` - tiddlers that are being used as tags
For example:
@@ -20,6 +21,8 @@ For example:
|`[tag[task]is[shadow]]` |Returns ShadowTiddlers tagged `task` |
|`[tag[task]!is[system]]` |Returns non-SystemTiddlers tagged `task` |
|`[is[shadow]]` |Returns ShadowTiddlers that have been overridden by a 'real' tiddler |
|`[!is[shadow]]` |Returns ordinary tiddlers that are not shadow tiddlers |
|`[!is[tag]]` |Returns all tiddlers that are not being used as tags |
|`[is[missing]]` |Returns an empty list (see note below) |
Note that the ''is'' filter operator strictly filters the current list by choosing whether or not to include each one in the output. It never adds tiddlers to the results that are not already listed. This means that when used at the start of a run of filter operators the ''is'' operator will be choosing from the currently existing tiddlers, and so will never return missing tiddlers, or shadow tiddlers that haven't been overridden.

View File

@@ -11,7 +11,7 @@ For example:
|!Filter String |!Description |
|`[tag[mytag]]` |Returns all tiddlers tagged `mytag` |
|`[all[shadows]tag[mytag]]` |Returns all ShadowTiddlers tagged `mytag` |
|`[all[tiddlers+shadows]tag[mytag]]` |Returns all ShadowTiddlers and non-ShadowTiddlers tagged `mytag` |
|`[all[shadows+tiddlers]tag[mytag]]` |Returns all ShadowTiddlers and non-ShadowTiddlers tagged `mytag` |
|`[!tag[mytag]]` |Returns all tiddlers not tagged `mytag` |
|`[tag[mytag]!tag[exclude]]` |Returns all tiddlers tagged `mytag` that are not tagged `mytag` |

View File

@@ -1,5 +1,5 @@
created: 20130823203800000
modified: 20140415111839328
modified: 20140419081726794
tags: planning
title: RoadMap
type: text/vnd.tiddlywiki
@@ -18,15 +18,12 @@ The following additional features are planned or under consideration for impleme
** Improve upgrade process
** Establish plugin library
** Proper use of ARIA roles
* Features required by ~TiddlyWiki hackers
** Pretty-printed JSON (similar to http://marianoguerra.github.io/json.human.js/)
** A "safe mode" to disable customisations
* Fixing hangovers from TiddlyWikiClassic
** ~TiddlyWiki file format (to avoid illegal attribute names)
** Tiddler object format (to provide true polymorphism of field values)
* Perfecting WikiText
** Global macros
** `[img[url]]` for remote image embedding, and `[ext[url]]` for explicit external links
** ~~`[img[url]]` for remote image embedding~~, and `[ext[url]]` for explicit external links
** Further ~WikiText features
* Productivity features
** Import wizard allowing individual tiddlers to be selected for import

View File

@@ -1,4 +1,4 @@
title: $:/editions/tw5.com/github-fork-ribbon
tags: $:/tags/PageControls
<div class="github-fork-ribbon-wrapper right" style><div class="github-fork-ribbon" style="background-color:#FFBB3D;"><$link to="ReleaseHistory"><<version>></$link></div></div>
<div class="github-fork-ribbon-wrapper right" style><div class="github-fork-ribbon" style="background-color:#FF7685;"><$link to="ReleaseHistory"><<version>></$link></div></div>

View File

@@ -5,7 +5,7 @@ tags: widget
! Introduction
The button widget displays an HTML `<button>` element that can perform a combination optional actions when clicked:
The button widget displays an HTML `<button>` element that can perform a combination of optional actions when clicked:
* Navigate to a specified tiddler
* Dispatch a user defined [[widget message|WidgetMessages]]

View File

@@ -0,0 +1,20 @@
title: ImageWidget
created: 20140416160234142
modified: 20140416160234142
tags: widget
! Introduction
The image widget displays images that can be specified as a remote URL or the title of a local tiddler containing the image.
! Content and Attributes
Any content of the `<$image>` widget is ignored.
|!Attribute |!Description |
|source |The URL of the image, or the title of an image tiddler |
|width |The width of the image as a number |
|height |The height of the image |
|tooltip |The tooltip to be displayed over the image |
|class |CSS classes to be assigned to the `<img>` element |

View File

@@ -1,10 +1,44 @@
created: 20131205160221762
modified: 20131205160234142
modified: 20140416160234142
tags: wikitext
title: Images in WikiText
type: text/vnd.tiddlywiki
To display an image stored in a tiddler just transclude that tiddler:
! Image Formatting
Images can be included in WikiText with the following syntax:
```
[img[Motovun Jack.jpg]]
[img[http://tiddlywiki.com/favicon.ico]]
```
If the image source is the title of an image tiddler then that tiddler is directly displayed. Otherwise it is interpreted as a URL and an HTML `<img>` tag is generated with the `src` attribute containing the URL.
A tooltip can also be specified:
```
[img[An explanatory tooltip|Motovun Jack.jpg]]
```
Attributes can be provided to specify CSS classes and the image width and height:
```
[img width=32 [Motovun Jack.jpg]]
[img width=32 class="tw-image" [Motovun Jack.jpg]]
```
Note that attributes can be specified as transclusions or variable references:
```
[img width={{!!mywidth}} class=<<image-classes>> [Motovun Jack.jpg]]
```
The image syntax is a shorthand for invoking the ImageWidget.
! Displaying Images via Transclusion
You can also display an image stored in a tiddler by transcluding that tiddler. The disadvantage of this approach is that there is no direct way to control the size of the image.
```
{{Motovun Jack.jpg}}
@@ -13,3 +47,4 @@ To display an image stored in a tiddler just transclude that tiddler:
Renders as:
{{Motovun Jack.jpg}}

View File

@@ -1,7 +1,7 @@
{
"name": "tiddlywiki",
"preferGlobal": "true",
"version": "5.0.9-beta",
"version": "5.0.10-beta",
"author": "Jeremy Ruston <jeremy@jermolene.com>",
"description": "a non-linear personal web notebook",
"contributors": [

View File

@@ -33,6 +33,18 @@ function transformNode(node) {
});
}
widget.children = transformNodes(node.slice(p++));
// Massage images into the image widget
if(widget.tag === "img") {
widget.tag = "$image";
if(widget.attributes.alt) {
widget.attributes.tooltip = widget.attributes.alt;
delete widget.attributes.alt;
}
if(widget.attributes.src) {
widget.attributes.source = widget.attributes.src;
delete widget.attributes.src;
}
}
return widget;
} else {
return {type: "text", text: node};

View File

@@ -1,6 +1,6 @@
title: $:/editions/clientserver/download-offline
\define saveTiddlerFilter()
[all[tiddlers+shadows]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] -[[$:/plugins/tiddlywiki/filesystem]] -[[$:/plugins/tiddlywiki/tiddlyweb]] +[sort[title]]
[is[tiddler]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] -[[$:/plugins/tiddlywiki/filesystem]] -[[$:/plugins/tiddlywiki/tiddlyweb]] +[sort[title]]
\end
{{$:/core/templates/tiddlywiki5.html}}

File diff suppressed because one or more lines are too long

View File

@@ -61,15 +61,11 @@ Seamless modifications
@media (min-width: {{$:/themes/tiddlywiki/vanilla/metrics##storywidth}}) {
<<if-sidebar "
/* Drop the tiddler frame padding */
body.tw-body .tw-tiddler-frame {
padding: 0;
}
">>
/* Move the sidebar up so that the title lines up */
body.tw-body .tw-sidebar-scrollable {
padding: 43px 0 28px 42px;

View File

@@ -257,7 +257,7 @@ a.tw-tiddlylink-external:hover {
color: <<colour foreground>>;
}
.tw-sidebar-lists button {
.tw-sidebar-lists button.btn {
color: <<colour sidebar-button-foreground>>;
}
@@ -330,13 +330,13 @@ a.tw-tiddlylink-external:hover {
}
.tw-topbar-left {
left: 0;
top: 0;
left: 29px;
top: 5px;
}
.tw-topbar-right {
top: 0;
right: 0;
top: 5px;
right: 29px;
}
.tw-topbar button {
@@ -472,7 +472,6 @@ a.tw-tiddlylink-external:hover {
.story-river {
width: auto;
padding: 0;
}
">>
@@ -480,7 +479,7 @@ a.tw-tiddlylink-external:hover {
}
@media print {
.sidebar-header {
.sidebar-header, .tw-topbar {
display: none;
}
@@ -544,7 +543,6 @@ a.tw-tiddlylink-external:hover {
.tw-tiddler-frame {
width: 100%;
margin-bottom: 0;
}
">>