1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-07-02 10:13:16 +00:00

Merge branch 'upgrade-mechanism'

This commit is contained in:
Jermolene 2014-07-19 15:28:26 +01:00
commit 1bef4b8d8d
54 changed files with 955 additions and 190 deletions

View File

@ -40,6 +40,15 @@ node .\tiddlywiki.js ^
--build favicon empty static index ^
|| exit 1
rem upgrade.html: custom edition for handling upgrades
node .\tiddlywiki.js ^
.\editions\upgrade ^
--verbose ^
--output %TW5_BUILD_OUTPUT% ^
--build upgrade ^
|| exit 1
rem encrypted.html: a version of the main file encrypted with the password "password"
node .\tiddlywiki.js ^

9
bld.sh
View File

@ -41,6 +41,15 @@ node ./tiddlywiki.js \
--build favicon empty static index \
|| exit 1
# upgrade.html: custom edition for handling upgrades
node ./tiddlywiki.js \
./editions/upgrade \
--verbose \
--output $TW5_BUILD_OUTPUT \
--build upgrade \
|| exit 1
# encrypted.html: a version of the main file encrypted with the password "password"
node ./tiddlywiki.js \

View File

@ -0,0 +1,4 @@
title: $:/core/images/download-button
tags: $:/tags/Image
<svg class="tw-image-download-button tw-image-button" width="22pt" height="22pt" viewBox="0 0 129 128"><g fill-rule="evenodd"><path class="tw-image-download-button-ring" d="M64,128 C99.346224,128 128,99.346224 128,64 C128,28.653776 99.346224,0 64,0 C28.653776,0 0,28.653776 0,64 C0,99.346224 28.653776,128 64,128 Z M64,112 C90.509668,112 112,90.509668 112,64 C112,37.490332 90.509668,16 64,16 C37.490332,16 16,37.490332 16,64 C16,90.509668 37.490332,112 64,112 Z"/><path d="M34.3496823,66.4308767 L61.2415823,93.634668 C63.0411536,95.4551107 65.9588502,95.4551107 67.7584215,93.634668 L94.6503215,66.4308767 C96.4498928,64.610434 96.4498928,61.6588981 94.6503215,59.8384554 C93.7861334,58.9642445 92.6140473,58.4731195 91.3919019,58.4731195 L82.9324098,58.4731195 C80.3874318,58.4731195 78.3243078,56.3860674 78.3243078,53.8115729 L78.3243078,38.6615466 C78.3243078,36.0870521 76.2611837,34 73.7162058,34 L55.283798,34 C52.7388201,34 50.675696,36.0870521 50.675696,38.6615466 L50.675696,38.6615466 L50.675696,53.8115729 C50.675696,56.3860674 48.612572,58.4731195 46.0675941,58.4731195 L37.608102,58.4731195 C35.063124,58.4731195 33,60.5601716 33,63.134666 C33,64.3709859 33.4854943,65.5566658 34.3496823,66.4308767 L34.3496823,66.4308767 Z"/></g></svg>

View File

@ -0,0 +1,12 @@
title: $:/language/Import/
Listing/Cancel/Caption: Cancel
Listing/Hint: These tiddlers are ready to import:
Listing/Import/Caption: Import
Listing/Select/Caption: Select
Listing/Status/Caption: Status
Listing/Title/Caption: Title
Upgrader/Plugins/Suppressed: Suppressed plugin (due to incoming <<incoming>> being older than existing <<existing>>)
Upgrader/Plugins/Upgraded: Upgraded plugin from <<incoming>> to <<upgraded>>
Upgrader/System/Suppressed: Suppressed system tiddler
Upgrader/ThemeTweaks/Created: Migrated theme tweak from <$text text=<<from>>/>

View File

@ -0,0 +1,70 @@
/*\
title: $:/core/modules/commands/makelibrary.js
type: application/javascript
module-type: command
Command to pack all of the plugins in the library into a plugin tiddler of type "library"
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
exports.info = {
name: "makelibrary",
synchronous: true
};
var UPGRADE_LIBRARY_TITLE = "$:/UpgradeLibrary";
var Command = function(params,commander,callback) {
this.params = params;
this.commander = commander;
this.callback = callback;
};
Command.prototype.execute = function() {
var wiki = this.commander.wiki,
fs = require("fs"),
path = require("path"),
upgradeLibraryTitle = this.params[0] || UPGRADE_LIBRARY_TITLE,
tiddlers = {};
// Collect up the library plugins
var collectPlugins = function(folder) {
var pluginFolders = fs.readdirSync(folder);
for(var p=0; p<pluginFolders.length; p++) {
if(!$tw.boot.excludeRegExp.test(pluginFolders[p])) {
pluginFields = $tw.loadPluginFolder(path.resolve(folder,"./" + pluginFolders[p]));
if(pluginFields && pluginFields.title) {
tiddlers[pluginFields.title] = pluginFields;
}
}
}
},
collectPublisherPlugins = function(folder) {
var publisherFolders = fs.readdirSync(folder);
for(var t=0; t<publisherFolders.length; t++) {
if(!$tw.boot.excludeRegExp.test(publisherFolders[t])) {
collectPlugins(path.resolve(folder,"./" + publisherFolders[t]));
}
}
};
collectPublisherPlugins(path.resolve($tw.boot.corePath,$tw.config.pluginsPath));
collectPublisherPlugins(path.resolve($tw.boot.corePath,$tw.config.themesPath));
collectPlugins(path.resolve($tw.boot.corePath,$tw.config.languagesPath));
// Save the upgrade library tiddler
var pluginFields = {
title: upgradeLibraryTitle,
type: "application/json",
"plugin-type": "library",
"text": JSON.stringify({tiddlers: tiddlers},null,$tw.config.preferences.jsonSpaces)
};
wiki.addTiddler(new $tw.Tiddler(pluginFields));
return null;
};
exports.Command = Command;
})();

View File

@ -18,7 +18,7 @@ Export our filter function
exports.plugintiddlers = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
var pluginInfo = options.wiki.getPluginInfo(title);
var pluginInfo = options.wiki.getPluginInfo(title) || options.wiki.getTiddlerData(title,{tiddlers:[]});
if(pluginInfo) {
$tw.utils.each(pluginInfo.tiddlers,function(fields,title) {
results.push(title);

View File

@ -0,0 +1,58 @@
/*\
title: $:/core/modules/upgraders/plugins.js
type: application/javascript
module-type: upgrader
Upgrader module that checks that plugins are newer than any already installed version
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var UPGRADE_LIBRARY_TITLE = "$:/UpgradeLibrary";
exports.upgrade = function(wiki,titles,tiddlers) {
var self = this,
messages = {},
upgradeLibrary,
getLibraryTiddler = function(title) {
if(!upgradeLibrary) {
upgradeLibrary = wiki.getTiddlerData(UPGRADE_LIBRARY_TITLE,{});
upgradeLibrary.tiddlers = upgradeLibrary.tiddlers || {};
}
return upgradeLibrary.tiddlers[title]
};
// Go through all the incoming tiddlers
$tw.utils.each(titles,function(title) {
var incomingTiddler = tiddlers[title];
// Check if we're dealing with a plugin
if(incomingTiddler && incomingTiddler["plugin-type"] && incomingTiddler["version"]) {
// Upgrade the incoming plugin if we've got a newer version in the upgrade library
var libraryTiddler = getLibraryTiddler(title);
if(libraryTiddler && libraryTiddler["plugin-type"] && libraryTiddler["version"]) {
if($tw.utils.checkVersions(libraryTiddler.version,incomingTiddler.version)) {
tiddlers[title] = libraryTiddler;
messages[title] = $tw.language.getString("Import/Upgrader/Plugins/Upgraded",{variables: {incoming: incomingTiddler.version, upgraded: libraryTiddler.version}});
return;
}
}
// Suppress the incoming plugin if it is older than the currently installed one
var existingTiddler = wiki.getTiddler(title);
if(existingTiddler && existingTiddler.hasField("plugin-type") && existingTiddler.hasField("version")) {
// Reject the incoming plugin by blanking all its fields
if($tw.utils.checkVersions(existingTiddler.fields.version,incomingTiddler.version)) {
tiddlers[title] = Object.create(null);
messages[title] = $tw.language.getString("Import/Upgrader/Plugins/Suppressed",{variables: {incoming: incomingTiddler.version, existing: existingTiddler.fields.version}});
return;
}
}
}
});
return messages;
};
})();

View File

@ -0,0 +1,30 @@
/*\
title: $:/core/modules/upgraders/system.js
type: application/javascript
module-type: upgrader
Upgrader module that suppresses certain system tiddlers that shouldn't be imported
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var DONT_IMPORT_LIST = ["$:/StoryList","$:/HistoryList"];
exports.upgrade = function(wiki,titles,tiddlers) {
var self = this,
messages = {};
// Check for tiddlers on our list
$tw.utils.each(titles,function(title) {
if(DONT_IMPORT_LIST.indexOf(title) !== -1) {
tiddlers[title] = Object.create(null);
messages[title] = $tw.language.getString("Import/Upgrader/System/Suppressed");
}
});
return messages;
};
})();

View File

@ -0,0 +1,65 @@
/*\
title: $:/core/modules/upgraders/themetweaks.js
type: application/javascript
module-type: upgrader
Upgrader module that handles the change in theme tweak storage introduced in 5.0.14-beta.
Previously, theme tweaks were stored in two data tiddlers:
* $:/themes/tiddlywiki/vanilla/metrics
* $:/themes/tiddlywiki/vanilla/settings
Now, each tweak is stored in its own separate tiddler.
This upgrader copies any values from the old format to the new. The old data tiddlers are not deleted in case they have been used to store additional indexes.
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var MAPPINGS = {
"$:/themes/tiddlywiki/vanilla/metrics": {
"fontsize": "$:/themes/tiddlywiki/vanilla/metrics/fontsize",
"lineheight": "$:/themes/tiddlywiki/vanilla/metrics/lineheight",
"storyleft": "$:/themes/tiddlywiki/vanilla/metrics/storyleft",
"storytop": "$:/themes/tiddlywiki/vanilla/metrics/storytop",
"storyright": "$:/themes/tiddlywiki/vanilla/metrics/storyright",
"storywidth": "$:/themes/tiddlywiki/vanilla/metrics/storywidth",
"tiddlerwidth": "$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth"
},
"$:/themes/tiddlywiki/vanilla/settings": {
"fontfamily": "$:/themes/tiddlywiki/vanilla/settings/fontfamily"
}
};
exports.upgrade = function(wiki,titles,tiddlers) {
var self = this,
messages = {};
// Check for tiddlers on our list
$tw.utils.each(titles,function(title) {
var mapping = MAPPINGS[title];
if(mapping) {
var tiddler = new $tw.Tiddler(tiddlers[title]),
tiddlerData = wiki.getTiddlerData(tiddler,{});
for(var index in mapping) {
var mappedTitle = mapping[index];
if(!tiddlers[mappedTitle] || tiddlers[mappedTitle].title !== mappedTitle) {
tiddlers[mappedTitle] = {
title: mappedTitle,
text: tiddlerData[index]
}
messages[mappedTitle] = $tw.language.getString("Import/Upgrader/ThemeTweaks/Created",{variables: {
from: title + "##" + index
}})
}
}
}
});
return messages;
};
})();

View File

@ -46,7 +46,17 @@ exports.decryptStoreArea = function(encryptedStoreArea,password) {
}
};
exports.decryptStoreAreaInteractive = function(encryptedStoreArea,callback) {
/*
Attempt to extract the tiddlers from an encrypted store area using the current password. If that fails, the user is prompted for a password.
encryptedStoreArea: text of the TiddlyWiki encrypted store area
callback: function(tiddlers) called with the array of decrypted tiddlers
The following configuration settings are supported:
$tw.config.usePasswordVault: causes any password entered by the user to also be put into the system password vault
*/
exports.decryptStoreAreaInteractive = function(encryptedStoreArea,callback,options) {
// Try to decrypt with the current password
var tiddlers = $tw.utils.decryptStoreArea(encryptedStoreArea);
if(tiddlers) {
@ -66,6 +76,9 @@ exports.decryptStoreAreaInteractive = function(encryptedStoreArea,callback) {
// Attempt to decrypt the tiddlers
var tiddlers = $tw.utils.decryptStoreArea(encryptedStoreArea,data.password);
if(tiddlers) {
if($tw.config.usePasswordVault) {
$tw.crypto.setPassword(data.password);
}
callback(tiddlers);
// Exit and remove the password prompt
return true;

View File

@ -55,22 +55,52 @@ CheckboxWidget.prototype.render = function(parent,nextSibling) {
CheckboxWidget.prototype.getValue = function() {
var tiddler = this.wiki.getTiddler(this.checkboxTitle);
return tiddler ? tiddler.hasTag(this.checkboxTag) : false;
if(tiddler) {
if(this.checkboxTag) {
return tiddler.hasTag(this.checkboxTag);
}
if(this.checkboxField) {
var value = tiddler.fields[this.checkboxField] || this.checkboxDefault || "";
if(value === this.checkboxChecked) {
return true;
}
if(value === this.checkboxUnchecked) {
return false;
}
}
}
return false;
};
CheckboxWidget.prototype.handleChangeEvent = function(event) {
var checked = this.inputDomNode.checked,
tiddler = this.wiki.getTiddler(this.checkboxTitle);
if(tiddler && tiddler.hasTag(this.checkboxTag) !== checked) {
var newTags = (tiddler.fields.tags || []).slice(0),
pos = newTags.indexOf(this.checkboxTag);
if(pos !== -1) {
newTags.splice(pos,1);
tiddler = this.wiki.getTiddler(this.checkboxTitle),
newFields = {},
hasChanged = false;
if(tiddler) {
// Set the tag if specified
if(this.checkboxTag && tiddler.hasTag(this.checkboxTag) !== checked) {
newFields.tags = (tiddler.fields.tags || []).slice(0);
var pos = newFields.tags.indexOf(this.checkboxTag);
if(pos !== -1) {
newFields.tags.splice(pos,1);
}
if(checked) {
newFields.tags.push(this.checkboxTag);
}
hasChanged = true;
}
if(checked) {
newTags.push(this.checkboxTag);
// Set the field if specified
if(this.checkboxField) {
var value = checked ? this.checkboxChecked : this.checkboxUnchecked;
if(tiddler.fields[this.checkboxField] !== value) {
newFields[this.checkboxField] = value;
hasChanged = true;
}
}
if(hasChanged) {
this.wiki.addTiddler(new $tw.Tiddler(tiddler,newFields,this.wiki.getModificationFields()));
}
this.wiki.addTiddler(new $tw.Tiddler(tiddler,{tags: newTags},this.wiki.getModificationFields()));
}
};
@ -81,6 +111,10 @@ CheckboxWidget.prototype.execute = function() {
// Get the parameters from the attributes
this.checkboxTitle = this.getAttribute("tiddler",this.getVariable("currentTiddler"));
this.checkboxTag = this.getAttribute("tag");
this.checkboxField = this.getAttribute("field");
this.checkboxChecked = this.getAttribute("checked");
this.checkboxUnchecked = this.getAttribute("unchecked");
this.checkboxDefault = this.getAttribute("default");
// Make the child widgets
this.makeChildWidgets();
};
@ -90,7 +124,7 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
*/
CheckboxWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(changedAttributes.tiddler || changedAttributes.tag || changedAttributes["class"]) {
if(changedAttributes.tiddler || changedAttributes.tag || changedAttributes.field || changedAttributes.checked || changedAttributes.unchecked || changedAttributes["default"] || changedAttributes["class"]) {
this.refreshSelf();
return true;
} else {

View File

@ -12,6 +12,8 @@ Navigator widget
/*global $tw: false */
"use strict";
var IMPORT_TITLE = "$:/Import";
var Widget = require("$:/core/modules/widgets/widget.js").widget;
var NavigatorWidget = function(parseTreeNode,options) {
@ -26,7 +28,8 @@ var NavigatorWidget = function(parseTreeNode,options) {
{type: "tw-close-all-tiddlers", handler: "handleCloseAllTiddlersEvent"},
{type: "tw-close-other-tiddlers", handler: "handleCloseOtherTiddlersEvent"},
{type: "tw-new-tiddler", handler: "handleNewTiddlerEvent"},
{type: "tw-import-tiddlers", handler: "handleImportTiddlersEvent"}
{type: "tw-import-tiddlers", handler: "handleImportTiddlersEvent"},
{type: "tw-perform-import", handler: "handlePerformImportEvent"}
]);
};
@ -402,7 +405,7 @@ NavigatorWidget.prototype.handleNewTiddlerEvent = function(event) {
return false;
};
// Import JSON tiddlers
// Import JSON tiddlers into a pending import tiddler
NavigatorWidget.prototype.handleImportTiddlersEvent = function(event) {
var self = this;
// Get the tiddlers
@ -411,54 +414,81 @@ NavigatorWidget.prototype.handleImportTiddlersEvent = function(event) {
tiddlers = JSON.parse(event.param);
} catch(e) {
}
// Get the current $:/Import tiddler
var importTiddler = this.wiki.getTiddler(IMPORT_TITLE),
importData = this.wiki.getTiddlerData(IMPORT_TITLE,{}),
newFields = new Object({
title: IMPORT_TITLE,
type: "application/json",
"plugin-type": "import",
"status": "pending"
}),
incomingTiddlers = [];
// Process each tiddler
var importedTiddlers = [];
importData.tiddlers = importData.tiddlers || {};
$tw.utils.each(tiddlers,function(tiddlerFields) {
var title = tiddlerFields.title;
// Add it to the store
var imported = self.wiki.importTiddler(new $tw.Tiddler(
self.wiki.getCreationFields(),
self.wiki.getModificationFields(),
tiddlerFields
));
if(imported) {
importedTiddlers.push(title);
if(title) {
incomingTiddlers.push(title);
importData.tiddlers[title] = tiddlerFields;
}
});
// Get the story and history details
var storyList = this.getStoryList(),
history = [];
// Create the import report tiddler
if(importedTiddlers.length === 0) {
return false;
// Give the active upgrader modules a chance to process the incoming tiddlers
var messages = this.wiki.invokeUpgraders(incomingTiddlers,importData.tiddlers);
$tw.utils.each(messages,function(message,title) {
newFields["message-" + title] = message;
});
// Deselect any suppressed tiddlers
$tw.utils.each(importData.tiddlers,function(tiddler,title) {
if($tw.utils.count(tiddler) === 0) {
newFields["selection-" + title] = "unchecked";
}
});
// Save the $:/Import tiddler
newFields.text = JSON.stringify(importData,null,$tw.config.preferences.jsonSpaces);
this.wiki.addTiddler(new $tw.Tiddler(importTiddler,newFields));
// Update the story and history details
if(this.getVariable("tw-auto-open-on-import") !== "no") {
var storyList = this.getStoryList(),
history = [];
// Add it to the story
if(storyList.indexOf(IMPORT_TITLE) === -1) {
storyList.unshift(IMPORT_TITLE);
}
// And to history
history.push(IMPORT_TITLE);
// Save the updated story and history
this.saveStoryList(storyList);
this.addToHistory(history);
}
var title;
if(importedTiddlers.length > 1) {
title = this.wiki.generateNewTitle("$:/temp/ImportReport");
var tiddlerFields = {
title: title,
text: "# [[" + importedTiddlers.join("]]\n# [[") + "]]\n"
};
this.wiki.addTiddler(new $tw.Tiddler(
self.wiki.getCreationFields(),
tiddlerFields,
self.wiki.getModificationFields()
));
} else {
title = importedTiddlers[0];
}
// Add it to the story
if(storyList.indexOf(title) === -1) {
storyList.unshift(title);
}
// And to history
history.push(title);
// Save the updated story and history
this.saveStoryList(storyList);
this.addToHistory(history);
return false;
};
//
NavigatorWidget.prototype.handlePerformImportEvent = function(event) {
var self = this,
importTiddler = this.wiki.getTiddler(event.param),
importData = this.wiki.getTiddlerData(event.param,{tiddlers: {}}),
importReport = [];
// Add the tiddlers to the store
importReport.push("The following tiddlers were imported:\n");
$tw.utils.each(importData.tiddlers,function(tiddlerFields) {
var title = tiddlerFields.title;
if(title && importTiddler && importTiddler.fields["selection-" + title] !== "unchecked") {
self.wiki.addTiddler(new $tw.Tiddler(tiddlerFields));
importReport.push("# [[" + tiddlerFields.title + "]]");
}
});
// Replace the $:/Import tiddler with an import report
this.wiki.addTiddler(new $tw.Tiddler({
title: IMPORT_TITLE,
text: importReport.join("\n"),
"status": "complete"
}));
// Navigate to the $:/Import tiddler
this.addToHistory([IMPORT_TITLE]);
};
exports.navigator = NavigatorWidget;
})();

View File

@ -53,7 +53,7 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
*/
TiddlerWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(changedAttributes.tiddler) {
if(changedAttributes.tiddler || changedTiddlers[this.tiddlerTitle]) {
this.refreshSelf();
return true;
} else {

View File

@ -39,17 +39,10 @@ Compute the internal state of the widget
TranscludeWidget.prototype.execute = function() {
// Get our parameters
this.transcludeTitle = this.getAttribute("tiddler",this.getVariable("currentTiddler"));
this.transcludeSubTiddler = this.getAttribute("subtiddler");
this.transcludeField = this.getAttribute("field");
this.transcludeIndex = this.getAttribute("index");
this.transcludeMode = this.getAttribute("mode");
// Check for recursion
var recursionMarker = this.makeRecursionMarker();
if(this.parentWidget && this.parentWidget.hasVariable("transclusion",recursionMarker)) {
this.makeChildWidgets([{type: "text", text: "Recursive transclusion error in transclude widget"}]);
return;
}
// Set context variables for recursion detection
this.setVariable("transclusion",recursionMarker);
// Parse the text reference
var parseAsInline = !this.parseTreeNode.isBlock;
if(this.transcludeMode === "inline") {
@ -61,8 +54,20 @@ TranscludeWidget.prototype.execute = function() {
this.transcludeTitle,
this.transcludeField,
this.transcludeIndex,
{parseAsInline: parseAsInline}),
{
parseAsInline: parseAsInline,
subTiddler: this.transcludeSubTiddler
}),
parseTreeNodes = parser ? parser.tree : this.parseTreeNode.children;
// Set context variables for recursion detection
var recursionMarker = this.makeRecursionMarker();
this.setVariable("transclusion",recursionMarker);
// Check for recursion
if(parser) {
if(this.parentWidget && this.parentWidget.hasVariable("transclusion",recursionMarker)) {
parseTreeNodes = [{type: "text", text: "Recursive transclusion error in transclude widget"}];
}
}
// Construct the child widgets
this.makeChildWidgets(parseTreeNodes);
};

View File

@ -136,7 +136,7 @@ Widget.prototype.substituteVariableParameters = function(text,formalParams,actua
Widget.prototype.substituteVariableReferences = function(text) {
var self = this;
return text.replace(/\$\(([^\)\$]+)\)\$/g,function(match,p1,offset,string) {
return (text || "").replace(/\$\(([^\)\$]+)\)\$/g,function(match,p1,offset,string) {
return self.getVariable(p1,{defaultValue: ""});
});
};

View File

@ -554,6 +554,17 @@ exports.sortByList = function(array,listTitle) {
}
};
exports.getSubTiddler = function(title,subTiddlerTitle) {
var bundleInfo = this.getPluginInfo(title) || this.getTiddlerData(title);
if(bundleInfo) {
var subTiddler = bundleInfo.tiddlers[subTiddlerTitle];
if(subTiddler) {
return new $tw.Tiddler(subTiddler);
}
}
return null;
};
/*
Retrieve a tiddler as a JSON string of the fields
*/
@ -571,16 +582,22 @@ exports.getTiddlerAsJson = function(title) {
};
/*
Get a tiddlers content as a JavaScript object. How this is done depends on the type of the tiddler:
Get the content of a tiddler as a JavaScript object. How this is done depends on the type of the tiddler:
application/json: the tiddler JSON is parsed into an object
application/x-tiddler-dictionary: the tiddler is parsed as sequence of name:value pairs
Other types currently just return null.
titleOrTiddler: string tiddler title or a tiddler object
defaultData: default data to be returned if the tiddler is missing or doesn't contain data
*/
exports.getTiddlerData = function(title,defaultData) {
var tiddler = this.getTiddler(title),
exports.getTiddlerData = function(titleOrTiddler,defaultData) {
var tiddler = titleOrTiddler,
data;
if(!(tiddler instanceof $tw.Tiddler)) {
tiddler = this.getTiddler(tiddler)
}
if(tiddler && tiddler.fields.text) {
switch(tiddler.fields.type) {
case "application/json":
@ -601,8 +618,8 @@ exports.getTiddlerData = function(title,defaultData) {
/*
Extract an indexed field from within a data tiddler
*/
exports.extractTiddlerDataItem = function(title,index,defaultText) {
var data = this.getTiddlerData(title,Object.create(null)),
exports.extractTiddlerDataItem = function(titleOrTiddler,index,defaultText) {
var data = this.getTiddlerData(titleOrTiddler,Object.create(null)),
text;
if(data && $tw.utils.hop(data,index)) {
text = data[index];
@ -786,31 +803,34 @@ exports.parseTiddler = function(title,options) {
};
exports.parseTextReference = function(title,field,index,options) {
if(field === "text" || (!field && !index)) {
// Force the tiddler to be lazily loaded
this.getTiddlerText(title);
// Parse it
return this.parseTiddler(title,options);
var tiddler,text;
if(options.subTiddler) {
tiddler = this.getSubTiddler(title,options.subTiddler);
} else {
var text;
if(field) {
if(field === "title") {
text = title;
} else {
var tiddler = this.getTiddler(title);
if(!tiddler || !tiddler.hasField(field)) {
return null;
}
text = tiddler.fields[field];
}
return this.parseText("text/vnd.tiddlywiki",text.toString(),options);
} else if(index) {
text = this.extractTiddlerDataItem(title,index,"");
if(text === undefined) {
tiddler = this.getTiddler(title);
if(field === "text" || (!field && !index)) {
this.getTiddlerText(title); // Force the tiddler to be lazily loaded
return this.parseTiddler(title,options);
}
}
if(field === "text" || (!field && !index)) {
return this.parseText(tiddler.fields.type || "text/vnd.tiddlywiki",tiddler.fields.text,options);
} else if(field) {
if(field === "title") {
text = title;
} else {
if(!tiddler || !tiddler.hasField(field)) {
return null;
}
return this.parseText("text/vnd.tiddlywiki",text,options);
text = tiddler.fields[field];
}
return this.parseText("text/vnd.tiddlywiki",text.toString(),options);
} else if(index) {
text = this.extractTiddlerDataItem(tiddler,index,"");
if(text === undefined) {
return null;
}
return this.parseText("text/vnd.tiddlywiki",text,options);
}
};
@ -1125,4 +1145,31 @@ exports.addToHistory = function(title,fromPageRect,historyTitle) {
this.setTiddlerData(historyTitle,historyList,{"current-tiddler": titles[titles.length-1]});
};
/*
Invoke the available upgrader modules
titles: array of tiddler titles to be processed
tiddlers: hashmap by title of tiddler fields of pending import tiddlers. These can be modified by the upgraders. An entry with no fields indicates a tiddler that was pending import has been suppressed. When entries are added to the pending import the tiddlers hashmap may have entries that are not present in the titles array
Returns a hashmap of messages keyed by tiddler title.
*/
exports.invokeUpgraders = function(titles,tiddlers) {
// Collect up the available upgrader modules
var self = this;
if(!this.upgraderModules) {
this.upgraderModules = [];
$tw.modules.forEachModuleOfType("upgrader",function(title,module) {
if(module.upgrade) {
self.upgraderModules.push(module);
}
});
}
// Invoke each upgrader in turn
var messages = {};
for(var t=0; t<this.upgraderModules.length; t++) {
var upgrader = this.upgraderModules[t],
upgraderMessages = upgrader.upgrade(this,titles,tiddlers);
$tw.utils.extend(messages,upgraderMessages);
}
return messages;
};
})();

56
core/ui/ImportListing.tid Normal file
View File

@ -0,0 +1,56 @@
title: $:/core/ui/ImportListing
\define lingo-base() $:/language/Import/
\define messageField()
message-$(payloadTiddler)$
\end
\define selectionField()
selection-$(payloadTiddler)$
\end
\define previewPopupState()
!!popup-$(payloadTiddler)$
\end
<table>
<tbody>
<tr>
<th>
<<lingo Listing/Select/Caption>>
</th>
<th>
<<lingo Listing/Title/Caption>>
</th>
<th>
<<lingo Listing/Status/Caption>>
</th>
</tr>
<$list filter="[all[current]plugintiddlers[]sort[title]]" variable="payloadTiddler">
<tr>
<td>
<$checkbox field=<<selectionField>> checked="checked" unchecked="unchecked" default="checked"/>
</td>
<td>
<$reveal type="nomatch" state=<<previewPopupState>> text="yes">
<$button class="btn-invisible btn-dropdown" set=<<previewPopupState>> setTo="yes">
{{$:/core/images/right-arrow}}&nbsp;<$text text=<<payloadTiddler>>/>
</$button>
</$reveal>
<$reveal type="match" state=<<previewPopupState>> text="yes">
<$button class="btn-invisible btn-dropdown" set=<<previewPopupState>> setTo="no">
{{$:/core/images/down-arrow}}&nbsp;<$text text=<<payloadTiddler>>/>
</$button>
</$reveal>
</td>
<td>
<$view field=<<messageField>>/>
</td>
</tr>
<tr>
<td colspan="3">
<$reveal type="match" text="yes" state=<<previewPopupState>>>
<$transclude subtiddler=<<payloadTiddler>> mode="block"/>
</$reveal>
</td>
</tr>
</$list>
</tbody>
</table>

View File

@ -5,7 +5,7 @@ tags: $:/tags/PageTemplate
<section class="story-backdrop">
<$list filter="[all[shadows+tiddlers]tag[$:/tags/StoryBackdrop]!has[draft.of]]">
<$list filter="[all[shadows+tiddlers]tag[$:/tags/AboveStory]!has[draft.of]]">
<$transclude/>
@ -17,7 +17,7 @@ tags: $:/tags/PageTemplate
<section class="story-frontdrop">
<$list filter="[all[shadows+tiddlers]tag[$:/tags/StoryFrontdrop]!has[draft.of]]">
<$list filter="[all[shadows+tiddlers]tag[$:/tags/BelowStory]!has[draft.of]]">
<$transclude/>

View File

@ -3,10 +3,14 @@ tags: $:/tags/ViewTemplate
<div class="body">
<$list filter="[all[current]!has[plugin-type]]">
<$transclude>
<$transclude tiddler="$:/language/MissingTiddler/Hint"/>
</$transclude>
</$list>
</div>

View File

@ -0,0 +1,19 @@
title: $:/core/ui/ViewTemplate/import
tags: $:/tags/ViewTemplate
\define lingo-base() $:/language/Import/
<$list filter="[all[current]field:plugin-type[import]]">
<div class="tw-import">
<<lingo Listing/Hint>>
{{||$:/core/ui/ImportListing}}
<$button message="tw-delete-tiddler" param=<<currentTiddler>>><<lingo Listing/Cancel/Caption>></$button>
<$button message="tw-perform-import" param=<<currentTiddler>>><<lingo Listing/Import/Caption>></$button>
</div>
</$list>

View File

@ -0,0 +1,8 @@
title: $:/core/ui/ViewTemplate/plugin
tags: $:/tags/ViewTemplate
<$list filter="[all[current]has[plugin-type]] -[all[current]field:plugin-type[import]]">
{{||$:/core/ui/TiddlerInfo/Advanced/PluginInfo}}
</$list>

View File

@ -1,2 +1,2 @@
title: $:/config/Navigation/UpdateAddressBar
text: permaview
text: no

View File

@ -16,16 +16,12 @@ tags: $:/tags/Macro
<$reveal type="match" state=<<qualify "$state$">> text=<<currentTab>> default="$default$">
<$tiddler tiddler=<<currentTab>>>
<$transclude tiddler="$template$" mode="block">
<$transclude mode="block"/>
<$transclude tiddler=<<currentTab>> mode="block"/>
</$transclude>
</$tiddler>
</$reveal>
</$list>

View File

@ -11,7 +11,7 @@ If you find TiddlyWiki useful, there are lots of ways you can help assure its fu
OpenSource projects like ~TiddlyWiki thrive on the feedback and engagement of users. ~TiddlyWiki becomes more useful to everyone as more and more people use it. So, if you find ~TiddlyWiki useful, spread the word. The best possible way to assure its future is for it to become a hundred times more popular than before.
* [[Tweet about TiddlyWiki|https://twitter.com/intent/tweet?text=I+love+TiddlyWiki+because...&source=tiddlywiki5]]
* [[Star the TiddlyWiki5 GitHub Repository|https://github.com/Jermolene/TiddlyWiki5/star]]
* [[Star the TiddlyWiki5 GitHub Repository|https://github.com/Jermolene/TiddlyWiki5]]
! Help improve the documentation and code

View File

@ -7,9 +7,19 @@ caption: 5.0.14-beta
//[[See GitHub for detailed change history of this release|https://github.com/Jermolene/TiddlyWiki5/compare/v5.0.13-beta...v5.0.14-beta]]//
!! Incompatible Changes
!! Major Changes
* Theme tweaks (in [[control panel|$:/ControlPanel]] under the ''Appearance'' tab) will not be upgraded from TiddlyWiki versions prior to 5.0.14-beta. You'll need to re-apply any customisations after upgrading
!!! Introduction of Upgrade Mechanism
There are two components:
* A more flexible ImportMechanism that:
** Presents incoming tiddlers as a pending import list that allows the user to inspect them and, if necessary, explicitly deselect them from the actual import
** Provides UpgraderModules with an opportunity to process each incoming tiddler
*** The [[plugin upgrader|$:/core/modules/upgraders/plugins.js]] module handles version checking of plugins and upgrading them from a special UpgradeLibrary plugin tiddler
*** The [[system upgrader|$:/core/modules/upgraders/system.js]] module is responsible for suppressing the importing of certain system tiddlers (currently [[$:/StoryList]] and [[$:/HistoryList]])
*** The [[themetweak upgrader|$:/core/modules/upgraders/themetweaks.js]] module handles migrating theme tweaks from their pre-5.0.14-beta format (see below)
* An UpgradePlugin and associated edition that provides a custom, single-purpose user interface for upgrading standalone TiddlyWiki files
!! Accessibility Improvements
@ -17,18 +27,23 @@ caption: 5.0.14-beta
!! Usability Improvements
*
* [[Refactored|https://github.com/Jermolene/TiddlyWiki5/commit/f43cd5ba9c6e5eda221ec738174e61e34fad2b8d]] (and [[here|https://github.com/Jermolene/TiddlyWiki5/commit/a3de93b4eb8b108239b2e4b496308026e9e9eef8]]) ReleaseHistory to place the releases into vertical tabs
* [[Stopped|https://github.com/Jermolene/TiddlyWiki5/commit/3ff7462afd5414b92680c6b6e67274be79233224]] saving [[$:/HistoryList]], thus avoiding it uncontrollably increasing in size
!! Hackability Improvements
*
* [[Refactored|https://github.com/Jermolene/TiddlyWiki5/commit/21c137a66c37f010b36697bb6bed5321138fbb9f]] [[control panel|$:/ControlPanel]] theme tweaks to be stored in individual tiddlers
* [[Extend|https://github.com/Jermolene/TiddlyWiki5/commit/e18d8a88661a1c2caa1b722841747c75ca6af437]] the TabsMacro to allow tabs to be templated
!! Bug Fixes
*
* [[Fixed|https://github.com/Jermolene/TiddlyWiki5/commit/5b3b62f93da4b7b19e24ccf72d9ce20b9edce6d5]] bug with execution order of BuildCommand targets
* [[Fixed|https://github.com/Jermolene/TiddlyWiki5/commit/d93da81671a704377209fc1871425c3a7c5db35a]] bug with missing hover colours for external links
* [[Fixed|https://github.com/Jermolene/TiddlyWiki5/commit/465f4ac46903070759a572d183c498c5579cb922]] problem with refreshing modal dialogues
* [[Fixed|https://github.com/Jermolene/TiddlyWiki5/commit/3351ae7e29cbf3bed6fc1925ef33664bcc59fef5]] issue with cookies disabled on Firefox
!! Contributors
[[@Jermolene|https://github.com/Jermolene]] would like to thank the contributors to this release who have generously given their time to help improve TiddlyWiki:
*
* [[@BramChen|https://github.com/BramChen]]

View File

@ -1,7 +1,7 @@
title: ReleaseHistoryTemplate
<h2><$link ><$view field="title"/></$link></h2>
<h2><$link to=<<currentTab>>><$view tiddler=<<currentTab>> field="title"/></$link></h2>
^^Released <$view field="released" format="date" template="DDth MMM YYYY at 0hh:0mm">TBA</$view>^^
^^Released <$view tiddler=<<currentTab>> field="released" format="date" template="DDth MMM YYYY at 0hh:0mm">TBA</$view>^^
<$transclude/>
<$transclude tiddler=<<currentTab>> />

View File

@ -1,57 +1,40 @@
created: 20131202102427114
modified: 20140419133900452
modified: 20140716133900452
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]].
The process described here is for upgrading standalone TiddlyWiki files. There is a [[different procedure|Upgrading TiddlyWiki on Node.js]] for upgrading [[TiddlyWiki on Node.js]].
<<<
Regardless of which method you use, remember the [[The First Rule of Using TiddlyWiki]]:
When upgrading, please remember the [[The First Rule of Using TiddlyWiki]]:
//You are responsible for looking after your own data; take care to make backups, especially when upgrading the ~TiddlyWiki core//
<<<
<div class="tw-message-box">
<a class="tw-message-icon" href="http://tiddlywiki.com/" target="_blank">{{TiddlyWiki Classic.png}}</a>
!! Upgrading from TiddlyWikiClassic
Remember that TiddlyWiki version 5 is not fully backwards compatible with the older TiddlyWikiClassic. It is recommended that users of TiddlyWikiClassic should not attempt to upgrade their existing files until the new version is more mature.
</div>
Remember that TiddlyWiki version 5 is not fully backwards compatible with the older TiddlyWikiClassic.
! Online upgrading
This process will work on most desktop browsers. Note that none of your personal data leaves your browser with this process.
# Locate your TiddlyWiki file in the file system (ie using Windows Explorer, the Finder on Mac OS X, or your file manager on Linux)
# Visit http://tiddlywiki.com/empty.html in your browser
# Visit http://tiddlywiki.com/upgrade.html in your browser
# Drag your old TiddlyWiki HTML file into the browser window
#* If the file is encrypted you will be prompted for the password
#* Your tiddlers should be imported
# Set a password if you want to use encryption
# Review the list of tiddlers that will be upgraded
# Click ''Upgrade''
# Save changes to save the new version
This will download a file called ''empty.html'' to your computer. This file is the upgrade of your old file. You may need to open the location where ''empty.html'' was downloaded, rename ''empty.html'' with the name of the old file you are upgrading, and replace the old file by moving the new file in its place.
//For the moment you'll also need to manually update any plugins that are not included in empty.html://
># Open the control panel to the ''Plugins'' tab in your upgraded wiki
># Check the version numbers of the plugins you are using; any plugins with an older version than the version of [[$:/core]] will probably need updating
># Locate a wiki with the plugins you need to update and open the control panel ''Plugins'' tab
>#* http://tiddlywiki.com/d3demo.html for the D3 plugin
>#* http://tiddlywiki.com/codemirrordemo.html for the CodeMirror plugin
>#* http://tiddlywiki.com/markdowndemo.html for the MarkDown plugin
>#* http://tiddlywiki.com/ for most of the others
># Drag the plugin links one by one back to your own wiki. You should see the version numbers update in the control panel
># Save your wiki
This will download a file called ''upgrade.html'' to your computer. This file is the upgrade of your old file. You may need to open the location where ''upgrade.html'' was downloaded, rename ''upgrade.html'' with the name of the old file you are upgrading, and replace the old file by moving the new file in its place.
! Offline upgrading
You can also download http://tiddlywiki.com/empty.html locally and perform the same drag-and-drop procedure to upgrade your files.
You can also download http://tiddlywiki.com/upgrade.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.
Particularly during the beta, it is possible for a customisation applied in a previous version to break when upgraded to the latest version. There are two techniques you can use to help track down issues:
* Try repeating the upgrade having selectively unchecked any tiddlers that may be applying customisations to TiddlyWiki
* Use SafeMode to disable all customisations of shadow tiddlers

View File

@ -17,12 +17,12 @@ System tags are used to give special behaviour to tiddlers:
* [[$:/tags/EditToolbar]] for the edit mode tiddler toolbar
* [[$:/tags/PageControls]] for the page control tools in the sidebar
* [[$:/tags/PageTemplate]] for the main page elements
* [[$:/tags/StoryBackdrop]] for elements to be placed at the top of the story river
* [[$:/tags/StoryFrontdrop]] for elements to be placed at the bottom of the story river
* [[$:/tags/AboveStory]] for elements to be placed at the top of the story river
* [[$:/tags/BelowStory]] for elements to be placed at the bottom of the story river
* [[$:/tags/RawMarkup]] for raw markup to be included in the generated HTML file
! System tags in use
These are the system tags in use in this wiki:
{{{ [all[shadows+tiddlers]tags[]prefix[$:/]] +[sort[title]] }}}
{{{ [all[shadows+tiddlers]tags[]prefix[$:/]sort[title]] }}}

View File

@ -17,6 +17,8 @@ By default the tab control arranges the tabs horizontally with the content under
|4th |class |Additional CSS classes for the three wrappers DIV of the tab | |
|5th |template |Optional template through which to render the tab content | |
Within the template the title of the current tab is available in the widget variable ''currentTab''.
! Examples
Here is an example of the tabs macro:

View File

@ -0,0 +1,38 @@
title: UpgradeMechanism
modified: 20140711090154150
created: 20140711090154150
tags: mechanism
# Open upgrade.html
# Includes a data tiddler called `$:/UpgradeLibrary` that contains the latest compatible versions of all plugins in the library
# Drag in old wiki file
# Place tiddlers into a data tiddler `$:/Import` that is typed as a "pending import"
# Kick off import processing for each tiddler
## Give each "upgrader" module a chance to inspect the incoming tiddlers
## Upgrader modules can trigger actions for each tiddler:
##* Display a warning message
##* Don't import
##* Replace with another tiddler from the upgrade library
##* Disable incompatible plugins
# Display the newly created pending import tiddler through a new view template segment
## Displays the payload tiddlers as a list of titles and checkboxes, with a dropdown showing the full details of the tiddler
## Perhaps we also suppress the usual JSON display for data tiddlers behind a reveal widget
# The user can adjust the selection checkboxes
# Clicking "done" unpacks the selected tiddlers from the pending import tiddler
# The pending import tiddler and the upgrade library tiddler are excluded from the subsequent save operation
! ToDo
* Incoming tiddler preview
* ~~Better display text for plugins~~
* ~~Better handling of encrypted upgrades~~
* Docs
* ~~Add upgrade plugin containing instructions and one-shot UI~~
* ~~Suppressing $:/UpgradeLibrary and upgrade plugin from save~~
* ~~Checkboxes~~
* ~~Visual difference for suppressed tiddlers~~
* Translation of upgrade wizard
! NoToDo
* Grouping plugins - not possible without extending the core

View File

@ -1,14 +1,19 @@
created: 20140226084658099
modified: 20140226195055502
created: 20140716084658099
modified: 20140716195055502
tags: message navigator-message
title: WidgetMessage: tw-import-tiddlers
type: text/vnd.tiddlywiki
The `tw-import-tiddlers` message inserts a list of tiddlers into the store. If multiple tiddlers are imported then a report is displayed; if only one tiddler is imported then it is displayed instead. The import message requires the following properties on the `event` object:
The `tw-import-tiddlers` message inserts a list of tiddlers into the pending import tiddler [[$:/Import]]. It also applies any active ''upgrader'' modules to each tiddler as it arrives (see the UpgradeMechanism for more details).
|!Name |!Description |
|param |JSON text of the array of tiddlers to be imported |
This message is handled by the NavigatorWidget.
The import tiddlers message is usually generated with the DropzoneWidget or the BrowseWidget, and is handled by the NavigatorWidget.
! Configuration Variables
The variable `tw-auto-open-on-import` controls whether the `tw-import-tiddlers` message automatically triggers the display of the pending import tiddler [[$:/Import]]:
* ''no'': The pending import tiddler is not opened in the story
* ''yes'': The pending import tiddler is opened in th story. This is the default

View File

@ -0,0 +1,14 @@
created: 20140716084242809
modified: 20140716084341303
tags: message navigator-message
title: WidgetMessage: tw-perform-import
type: text/vnd.tiddlywiki
The perform import message copies tiddlers from a specified plugin into the main store. See the UpgradeMechanism for an overview of how it is used by the core.
|!Name |!Description |
|param |Title of the pending import tiddler. Defaults to ''$:/Import'' |
To select which tiddlers are to be imported, fields with names formed from `selection-` plus the title of the tiddler are used. The value ''unchecked'' causes the tiddler to be skipped from the import.
The perform import message is usually generated with the ButtonWidget and is handled by the NavigatorWidget.

View File

@ -1,44 +1,30 @@
created: 20130823203800000
modified: 20140621201725471
modified: 20140715081725471
tags: planning
title: RoadMap
type: text/vnd.tiddlywiki
TiddlyWiki is under rapid development at the moment as it moves through beta to a full release.
TiddlyWiki is under rapid development at the moment as it moves through beta to a full release. That is the point at which it is declared stable enough for general use. It will continue to improve and evolve, but constrained to remain backwards compatible so that plugins and content created for version 5.0 will continue to work into the future.
! Beta
The plan is for the full release to take place in September 2014, around the time of TiddlyWiki's tenth anniversary.
During the beta ~TiddlyWiki will be practical for cautious everyday use but as we perfect the product there will occasionally be situations where we have to make changes that are not backwards compatible. These occasions will be clearly marked in the release notes.
! Deferred Tasks
The following additional features are planned or under consideration for implementation during the beta:
Some important features were deferred to be added after the beta:
* Features to improve user data integrity
** Optional defensive backups with TiddlyFox and TiddlyDesktop
* Features required for large scale adoption
** Improve upgrade process
** Establish plugin library
** ~~Proper use of ARIA roles (in progress)~~
* Establish online plugin library
* 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~~
** Further ~WikiText features
* Productivity features
** Import wizard allowing individual tiddlers to be selected for import
** Aliases
** Search and replace
** Tiddler renaming
** Rich link tooltips, incorporating a preview
** Keyboard shortcuts
** Keyboard snippet expansion in the text editor
** List editor with drag and drop
** Selective/weighted searching by title, body and fields
** Maths notation
* ~TiddlyWiki file format (to avoid illegal attribute names)
* Tiddler object format (to provide true polymorphism of field values)
* Aliases
* Search and replace
* Tiddler renaming
* Rich link tooltips, incorporating a preview
* More keyboard shortcuts
* Keyboard snippet expansion in the text editor
* List editor with drag and drop
* Selective/weighted searching by title, body and fields
* Maths notation
Also see the issues list on GitHub: https://github.com/Jermolene/TiddlyWiki5
! General Release
TiddlyWiki will [[leave beta|TiddlyWiki5 Versioning]] and become a full release in the summer of 2014. That is the point at which it is declared stable enough for general use. It will continue to improve and evolve after this point, although constrained to remain backwards compatible so that plugins and content created for version 5.0 will continue to work into the indefinite future.

View File

@ -1,11 +1,14 @@
title: CheckboxWidget
created: 201310241419
modified: 201310300837
modified: 201407110837
tags: widget
! Introduction
The checkbox widget displays an HTML `<input type="checkbox">` element that is dynamically bound to the presence or absence of a specified tag on a specified tiddler.
The checkbox widget displays an HTML `<input type="checkbox">` element that is dynamically bound to either:
* the presence or absence of a specified tag on a specified tiddler
* the value of a specified field of a specified tiddler
! Content and Attributes
@ -14,3 +17,27 @@ The content of the `<$checkbox>` widget is displayed within an HTML `<label>` el
|!Attribute |!Description |
|tiddler |Title of the tiddler to manipulate (defaults to the [[WidgetVariable: currentTiddler]]) |
|tag |The name of the tag to which the checkbox should be bound |
|field |The name of the field to which the checkbox should be bound |
|checked |The value of the field corresponding to the checkbox being checked |
|unchecked |The value of the field corresponding to the checkbox being unchecked |
|default |The default value to use if the field is not defined |
!! Tag Mode
Using the checkbox widget in tag mode requires the ''tag'' attribute to specify the name of the tag. The ''tiddler'' attribute specifies the tiddler to target, defaulting to the current tiddler if not present.
This example creates a checkbox that flips the ''done'' tag on the current tiddler:
```
<$checkbox tag="done">Is it done?</$checkbox>
```
!! Field Mode
Using the checkbox widget in field mode requires the ''field'' attribute to specify the name of the field. The ''checked'' and ''unchecked'' attributes specify the values to be assigned to the field to correspond to its checked and unchecked states respectively. The ''default'' attribute is used as a fallback value if the field is not defined.
This example creates a checkbox that is checked if the field ''status'' is equal to ''open'' and unchecked if the field is equal to ''closed''. If the field is undefined then it defaults to ''closed'', meaning that the checkbox will be unchecked if the ''status'' field is missing.
```
<$checkbox field="status" checked="open" unchecked="closed" default="closed">Is it open?</$checkbox>
```

View File

@ -1,5 +1,5 @@
created: 20130824142500000
modified: 20140526175900970
modified: 20140717175900970
tags: widget
title: TranscludeWidget
type: text/vnd.tiddlywiki
@ -14,6 +14,7 @@ The TranscludeWidget dynamically imports content from another tiddler.
|tiddler |The title of the tiddler to transclude (defaults to the current tiddler) |
|field |The field name of the current tiddler (defaults to "text"; if present takes precedence over the index attribute) |
|index |The index of a property in a [[DataTiddler|DataTiddlers]] |
|subtiddler |Optional SubTiddler title when the target tiddler is a [[plugin|Plugins]] (see below) |
|mode |Override the default parsing mode for the transcluded text to "block" or "inline" |
The TranscludeWidget treats any contained content as a fallback if the target of the transclusion is not defined (ie a missing tiddler or a missing field).
@ -55,3 +56,14 @@ This can be fixed by amending tiddler "A":
#<$transclude tiddler="B" mode="block"/>
# Item two
```
! SubTiddler Access
The transclude widget allows access to the individual tiddlers stored within a [[plugin|Plugins]].
The following example will transclude the core version of the tiddler [[$:/DefaultTiddlers]] even if it has been overridden:
<<wikitext-example-without-html '
<$transclude tiddler="$:/core" subtiddler="$:/DefaultTiddlers"/>
'>>

View File

@ -0,0 +1,14 @@
{
"plugins": [
"tiddlywiki/upgrade"
],
"themes": [
"tiddlywiki/vanilla",
"tiddlywiki/snowwhite"
],
"build": {
"upgrade": [
"--makelibrary",
"--rendertiddler","$:/core/save/all","upgrade.html","text/plain"]
}
}

View File

@ -0,0 +1,15 @@
title: $:/plugins/tiddlywiki/googleanalytics/readme
This plugin enables you to use Google Analytics to track access to your online TiddlyWiki document. These instructions assume you are using TiddlySpot to publish your wiki.
# Go to the Google Analytics website: http://www.google.com/analytics/
# Click the ''Access Google Analytics'' button and follow instructions to set up your account
# Enter the name of your TiddlySpot domain, for example "mysite.tiddlyspot.com"
# You will be given your own Tracking ID for this domain
# Go to http://tiddlywiki.com -- open the More/System tab and drag the links to these three tiddlers across to a local copy of your site:
#* $:/GoogleAnalyticsDomain
#* $:/GoogleAnalyticsAccount
#* $:/plugins/tiddlywiki/googleanalytics
# Edit the first two of these tiddlers to reflect your Domain and Tracking ID
# Upload the new version to TiddlySpot or other web host
# Return to your Google Analytics page to check that your site is being tracked

View File

@ -0,0 +1,6 @@
{
"title": "$:/plugins/tiddlywiki/tw2parser",
"description": "TiddlyWiki Classic-compatible wikitext parser",
"author": "JeremyRuston",
"core-version": ">=5.0.0"
}

View File

@ -0,0 +1 @@
title: $:/DefaultTiddlers

View File

@ -0,0 +1,3 @@
title: $:/SiteSubtitle
upgrade your files to the latest version

View File

@ -0,0 +1,3 @@
title: $:/SiteTitle
~TiddlyWiki Upgrader

View File

@ -0,0 +1,3 @@
title: $:/config/Navigation/UpdateAddressBar
no

View File

@ -0,0 +1,54 @@
title: $:/UpgradeWizard
tags: $:/tags/AboveStory
<div class="tw-upgrade-wizard-wrapper">
<div class="tw-upgrade-wizard">
! ~TiddlyWiki Upgrade Wizard
<$list filter="[[$:/Import]is[missing]]">
{{$:/core/images/download-button}}
Drag a ~TiddlyWiki file here to upgrade it
or click to pick a file <$browse/>
---
//Your data will not leave your browser. [[Download|http://tiddlywiki.com/upgrade.html]] this upgrader to use it offline//
</$list>
<$reveal state="$:/Import!!status" type="match" text="pending">
The following tiddlers will be included in the upgrade <$button message="tw-perform-import" param="$:/Import">Upgrade</$button>
{{$:/Import||$:/core/ui/ImportListing}}
</$reveal>
<$reveal state="$:/Import!!status" type="match" text="complete">
Upgrade completed. Click the button below to save your upgraded ~TiddlyWiki file
Make sure that you keep a safe copy of your previous ~TiddlyWiki file.
<$reveal type="match" state="$:/isEncrypted" text="yes">
''The file will be encrypted with your existing password.''
</$reveal>
{{$:/plugins/tiddlywiki/upgrade/save}}
Close this browser window to prevent others from being able to access your data.
For help and support, visit [[the TiddlyWiki discussion forum|http://groups.google.com/group/TiddlyWiki]].
</$reveal>
</div>
</div>

View File

@ -0,0 +1,25 @@
/*\
title: $:/plugins/tiddlywiki/upgrade/config.js
type: application/javascript
module-type: startup
Startup module for configuring the upgrade plugin
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
// Export name and synchronous status
exports.name = "upgrade-config";
exports.before = ["startup"];
exports.synchronous = true;
exports.startup = function() {
// See $tw.utils.decryptStoreAreaInteractive() in $:/core/modules/utils/crypto.js
$tw.config.usePasswordVault = true;
};
})();

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -0,0 +1,2 @@
title: $:/favicon.ico
type: image/x-icon

View File

@ -0,0 +1,6 @@
{
"title": "$:/plugins/tiddlywiki/upgrade",
"description": "User interface for upgrading TiddlyWiki documents",
"author": "JeremyRuston",
"core-version": ">=5.0.0"
}

View File

@ -0,0 +1,6 @@
title: $:/plugins/tiddlywiki/upgrade/save-tiddler-filter
\define saveTiddlerFilter()
[is[tiddler]] -[[$:/UpgradeLibrary]] -[[$:/plugins/tiddlywiki/upgrade]] -[prefix[$:/state/popup/]] -[[$:/HistoryList]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]]
\end
{{$:/core/templates/tiddlywiki5.html}}

View File

@ -0,0 +1,3 @@
title: $:/plugins/tiddlywiki/upgrade/save
<$button message="tw-download-file" param="$:/plugins/tiddlywiki/upgrade/save-tiddler-filter" class="btn-big-green">Save upgraded ~TiddlyWiki file {{$:/core/images/save-button}}</$button>

View File

@ -0,0 +1,6 @@
title: $:/plugins/tiddlywiki/upgrade/set-auto-open-on-import
tags: $:/tags/Macro
\define tw-auto-open-on-import()
no
\end

View File

@ -0,0 +1,3 @@
title: $:/state/sidebar
no

View File

@ -0,0 +1,60 @@
title: $:/plugins/tiddlywiki/upgrade/styles
tags: $:/tags/stylesheet
.tw-upgrade-wizard-wrapper {
width: 100%;
text-align: center;
margin-bottom: 3em;
}
.tw-upgrade-wizard {
background: <<colour tiddler-background>>;
padding: 2em;
display: inline-block;
position: relative;
border: 1px solid #ddd;
<<box-shadow "inset 1px 2px 4px rgba(0, 0, 0, 0.15)">>;
overflow: hidden;
}
.tw-upgrade-wizard svg.tw-image-download-button {
width: 14em;
height: 14em;
fill: <<colour muted-foreground>>;
}
.tw-upgrade-wizard:hover svg.tw-image-download-button {
fill: <<colour foreground>>;
}
.tw-upgrade-wizard svg .tw-image-download-button-ring {
}
.tw-upgrade-wizard:hover svg .tw-image-download-button-ring {
fill: <<colour primary>>;
}
.tw-upgrade-wizard em {
color: <<colour tiddler-subtitle-foreground>>;
}
.tw-upgrade-wizard table {
text-align: left;
}
.tw-upgrade-wizard input[type=file] {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
font-size: 999px;
max-width: 100%;
max-height: 100%;
filter: alpha(opacity=0);
opacity: 0;
outline: none;
background: white;
cursor: pointer;
display: block;
}

View File

@ -6,15 +6,15 @@ You can tweak certain aspects of the ''Vanilla'' theme.
! Settings
* Font family: <$edit-text tiddler="$:/themes/tiddlywiki/vanilla/settings/fontfamily" default="" tag="input"/>
* [[Font family|$:/themes/tiddlywiki/vanilla/settings/fontfamily]]: <$edit-text tiddler="$:/themes/tiddlywiki/vanilla/settings/fontfamily" default="" tag="input"/>
! Sizes
* Font size: <$edit-text tiddler="$:/themes/tiddlywiki/vanilla/metrics/fontsize" default="" tag="input"/>
* Line height: <$edit-text tiddler="$:/themes/tiddlywiki/vanilla/metrics/lineheight" default="" tag="input"/>
* Story left position //(the distance between the left of the screen and the left margin of the story river or tiddler area)//: <$edit-text tiddler="$:/themes/tiddlywiki/vanilla/metrics/storyleft" default="" tag="input"/>
* Story top position //(the distance between the top of the screen ad the top margin of the story river or tiddler area)//: <$edit-text tiddler="$:/themes/tiddlywiki/vanilla/metrics/storytop" default="" tag="input"/>
* Story right //(the distance between the left side of the screen and the left margin of the sidebar area)//: <$edit-text tiddler="$:/themes/tiddlywiki/vanilla/metrics/storyright" default="" tag="input"/>
* Story width //(the width of the story river or tiddler area)//: <$edit-text tiddler="$:/themes/tiddlywiki/vanilla/metrics/storywidth" default="" tag="input"/>
* Tiddler width //(the width of individual tiddlers -- used for zoomin storyview)//: <$edit-text tiddler="$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth" default="" tag="input"/>
* Sidebar breakpoint //(the minimum width for the sidebar to be displayed above the story river)//: <$edit-text tiddler="$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint" default="" tag="input"/>
* [[Font size|$:/themes/tiddlywiki/vanilla/metrics/fontsize]]: <$edit-text tiddler="$:/themes/tiddlywiki/vanilla/metrics/fontsize" default="" tag="input"/>
* [[Line height|$:/themes/tiddlywiki/vanilla/metrics/lineheight]]: <$edit-text tiddler="$:/themes/tiddlywiki/vanilla/metrics/lineheight" default="" tag="input"/>
* [[Story left position|$:/themes/tiddlywiki/vanilla/metrics/storyleft]] //(the distance between the left of the screen and the left margin of the story river or tiddler area)//: <$edit-text tiddler="$:/themes/tiddlywiki/vanilla/metrics/storyleft" default="" tag="input"/>
* [[Story top position|$:/themes/tiddlywiki/vanilla/metrics/storytop]] //(the distance between the top of the screen ad the top margin of the story river or tiddler area)//: <$edit-text tiddler="$:/themes/tiddlywiki/vanilla/metrics/storytop" default="" tag="input"/>
* [[Story right|$:/themes/tiddlywiki/vanilla/metrics/storyright]] //(the distance between the left side of the screen and the left margin of the sidebar area)//: <$edit-text tiddler="$:/themes/tiddlywiki/vanilla/metrics/storyright" default="" tag="input"/>
* [[Story width|$:/themes/tiddlywiki/vanilla/metrics/storywidth]] //(the width of the story river or tiddler area)//: <$edit-text tiddler="$:/themes/tiddlywiki/vanilla/metrics/storywidth" default="" tag="input"/>
* [[Tiddler width|$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth]] //(the width of individual tiddlers -- used for zoomin storyview)//: <$edit-text tiddler="$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth" default="" tag="input"/>
* [[Sidebar breakpoint|$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint]] //(the minimum width for the sidebar to be displayed alongside the story river)//: <$edit-text tiddler="$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint" default="" tag="input"/>

View File

@ -825,6 +825,10 @@ canvas.tw-edit-bitmapeditor {
** Dropdowns
*/
.btn-dropdown {
text-align: left;
}
.btn-dropdown svg {
height: 1em;
width: 1em;