1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2026-01-31 07:10:23 +00:00

Compare commits

..

1 Commits

Author SHA1 Message Date
Jermolene
b799d924f0 Trial implementing pretty links via a macro
An experiment for #3883
2019-03-29 22:04:13 +00:00
434 changed files with 16649 additions and 21257 deletions

View File

@@ -5,7 +5,7 @@
# Default to the current version number for building the plugin library
if [ -z "$TW5_BUILD_VERSION" ]; then
TW5_BUILD_VERSION=v5.1.20
TW5_BUILD_VERSION=v5.1.19
fi
echo "Using TW5_BUILD_VERSION as [$TW5_BUILD_VERSION]"
@@ -34,12 +34,6 @@ fi
echo "Using TW5_BUILD_DETAILS as [$TW5_BUILD_DETAILS]"
if [ -z "$TW5_BUILD_COMMIT" ]; then
TW5_BUILD_COMMIT="$(git rev-parse HEAD)"
fi
echo "Using TW5_BUILD_COMMIT as [$TW5_BUILD_COMMIT]"
# Set up the build output directory
if [ -z "$TW5_BUILD_OUTPUT" ]; then
@@ -80,7 +74,7 @@ echo "<a href='./plugins/tiddlywiki/tahoelafs/index.html'>Moved to http://tiddly
# Put the build details into a .tid file so that it can be included in each build (deleted at the end of this script)
echo -e -n "title: $:/build\ncommit: $TW5_BUILD_COMMIT\n\n$TW5_BUILD_DETAILS\n" > $TW5_BUILD_OUTPUT/build.tid
echo -e -n "title: $:/build\n\n$TW5_BUILD_DETAILS\n" > $TW5_BUILD_OUTPUT/build.tid
######################################################
#

View File

@@ -1,7 +0,0 @@
#!/bin/bash
# publish to npm
./bin/clean.sh
npm publish || exit 1

View File

@@ -1,8 +0,0 @@
#!/bin/bash
# Abbreviated build script for building prerelease
tiddlywiki editions/prerelease \
--verbose \
--build favicon index \
|| exit 1

View File

@@ -1,17 +0,0 @@
#!/bin/bash
# Build readmes from corresponding tiddlers
# Default to the version of TiddlyWiki installed in this repo
if [ -z "$TW5_BUILD_TIDDLYWIKI" ]; then
TW5_BUILD_TIDDLYWIKI=./tiddlywiki.js
fi
# tw5.com readmes
node $TW5_BUILD_TIDDLYWIKI \
editions/tw5.com \
--verbose \
--output . \
--build readmes \
|| exit 1

View File

@@ -1,4 +1,3 @@
<h1 class="">Script Files</h1><p>The <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/TiddlyWiki5.html">TiddlyWiki5</a> repository contains several scripts in the <code>bin</code> folder that you can use to automate common tasks, or as a useful starting point for your own scripts. See <a class="tc-tiddlylink tc-tiddlylink-missing" href="https://tiddlywiki.com/static/Scripts%2520for%2520building%2520tiddlywiki.com.html">Scripts for building tiddlywiki.com</a> for details of the scripts used to build and release <a class="tc-tiddlylink-external" href="https://tiddlywiki.com/" rel="noopener noreferrer" target="_blank">https://tiddlywiki.com/</a>.</p><p>All the scripts expect to be run from the root folder of the repository.</p><h2 class=""><code>serve</code>: serves tw5.com</h2><pre><code>./bin/serve.sh -h
./bin/serve.sh [edition dir] [username] [password] [host] [port]</code></pre><p>Or:</p><pre><code>./bin/serve.cmd -h
./bin/serve.cmd [edition dir] [username] [password] [host] [port]</code></pre><p>This script starts <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/TiddlyWiki5.html">TiddlyWiki5</a> running as an HTTP server, defaulting to the content from the <code>tw5.com-server</code> edition. By default, the Node.js serves on port 8080. If the optional <code>username</code> parameter is provided, it is used for signing edits. If the <code>password</code> is provided then HTTP basic authentication is used. Run the script with the <code>-h</code> parameter to see online help.</p><p>To experiment with this configuration, run the script and then visit <code>http://127.0.0.1:8080</code> in a browser.</p><p>Changes made in the browser propagate to the server over HTTP (use the browser developer console to see these requests). The server then syncs changes to the file system (and logs each change to the screen).</p><h2 class=""><code>test</code>: build and run tests</h2><p>This script runs the <code>test</code> edition of <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/TiddlyWiki.html">TiddlyWiki</a> on the server to perform the server-side tests and to build <code>test.html</code> for running the tests in the browser.</p><h2 class=""><code>lazy</code>: serves tw5.com with lazily loaded images</h2><pre><code>./bin/lazy.sh &lt;username&gt; [&lt;password&gt;]</code></pre><p>Or:</p><pre><code>./bin/lazy.cmd &lt;username&gt; [&lt;password&gt;]</code></pre><p>This script serves the <code>tw5.com-server</code> edition content with <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/LazyLoading.html">LazyLoading</a> applied to images.
</p>
./bin/serve.cmd [edition dir] [username] [password] [host] [port]</code></pre><p>This script starts <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/TiddlyWiki5.html">TiddlyWiki5</a> running as an HTTP server, defaulting to the content from the <code>tw5.com-server</code> edition. By default, the Node.js serves on port 8080. If the optional <code>username</code> parameter is provided, it is used for signing edits. If the <code>password</code> is provided then HTTP basic authentication is used. Run the script with the <code>-h</code> parameter to see online help.</p><p>To experiment with this configuration, run the script and then visit <code>http://127.0.0.1:8080</code> in a browser.</p><p>Changes made in the browser propagate to the server over HTTP (use the browser developer console to see these requests). The server then syncs changes to the file system (and logs each change to the screen).</p><h2 class=""><code>test</code>: build and run tests</h2><p>This script runs the <code>test</code> edition of <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/TiddlyWiki.html">TiddlyWiki</a> on the server to perform the server-side tests and to build <code>test.html</code> for running the tests in the browser.</p><h2 class=""><code>lazy</code>: serves tw5.com with lazily loaded images</h2><pre><code>./bin/lazy.sh &lt;username&gt; [&lt;password&gt;]</code></pre><p>Or:</p><pre><code>./bin/lazy.cmd &lt;username&gt; [&lt;password&gt;]</code></pre><p>This script serves the <code>tw5.com-server</code> edition content with <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/LazyLoading.html">LazyLoading</a> applied to images.</p><h2 class=""><code>2bld</code>: builds <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/TiddlyWiki.html">TiddlyWiki</a> 2.6.5</h2><p>This script builds <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/TiddlyWiki.html">TiddlyWiki</a> 2.6.5 from the original source and then displays the differences between them (<code>diff</code> is used for *nix, <code>fc</code> for Windows).</p>

View File

@@ -1,17 +0,0 @@
#!/bin/bash
# Bump to a new version number
if [ -z "$1" ]
then
echo "Missing version (eg '5.1.38-prerelease')"
exit 1
fi
# Set the new version number (will also commit and tag the release)
npm version $1 -m "Version number update for $1" || exit 1
# Make sure our tags are pushed to the origin server
git push origin --tags || exit 1

View File

@@ -314,13 +314,13 @@ $tw.utils.parseDate = function(value) {
// Stringify an array of tiddler titles into a list string
$tw.utils.stringifyList = function(value) {
if($tw.utils.isArray(value)) {
var result = new Array(value.length);
for(var t=0, l=value.length; t<l; t++) {
var result = [];
for(var t=0; t<value.length; t++) {
var entry = value[t] || "";
if(entry.indexOf(" ") !== -1) {
result[t] = "[[" + entry + "]]";
result.push("[[" + entry + "]]");
} else {
result[t] = entry;
result.push(entry);
}
}
return result.join(" ");
@@ -1013,7 +1013,7 @@ $tw.modules.define("$:/boot/tiddlerfields/list","tiddlerfield",{
/*
Wiki constructor. State is stored in private members that only a small number of privileged accessor methods have direct access. Methods added via the prototype have to use these accessors and cannot access the state data directly.
options include:
enableIndexers - Array of indexer names to enable, or null to use all available indexers
shadowTiddlers: Array of shadow tiddlers to be added
*/
$tw.Wiki = function(options) {
options = options || {};
@@ -1028,31 +1028,14 @@ $tw.Wiki = function(options) {
},
pluginTiddlers = [], // Array of tiddlers containing registered plugins, ordered by priority
pluginInfo = Object.create(null), // Hashmap of parsed plugin content
shadowTiddlers = Object.create(null), // Hashmap by title of {source:, tiddler:}
shadowTiddlers = options.shadowTiddlers || Object.create(null), // Hashmap by title of {source:, tiddler:}
shadowTiddlerTitles = null,
getShadowTiddlerTitles = function() {
if(!shadowTiddlerTitles) {
shadowTiddlerTitles = Object.keys(shadowTiddlers);
}
return shadowTiddlerTitles;
},
enableIndexers = options.enableIndexers || null,
indexers = [],
indexersByName = Object.create(null);
this.addIndexer = function(indexer,name) {
// Bail if this indexer is not enabled
if(enableIndexers && enableIndexers.indexOf(name) === -1) {
return;
}
indexers.push(indexer);
indexersByName[name] = indexer;
indexer.init();
};
this.getIndexer = function(name) {
return indexersByName[name] || null;
};
};
// Add a tiddler to the store
this.addTiddler = function(tiddler) {
@@ -1065,33 +1048,12 @@ $tw.Wiki = function(options) {
if(title) {
// Uncomment the following line for detailed logs of all tiddler writes
// console.log("Adding",title,tiddler)
// Record the old tiddler state
var updateDescriptor = {
old: {
tiddler: this.getTiddler(title),
shadow: this.isShadowTiddler(title),
exists: this.tiddlerExists(title)
}
}
// Save the new tiddler
tiddlers[title] = tiddler;
// Check we've got it's title
if(tiddlerTitles && tiddlerTitles.indexOf(title) === -1) {
tiddlerTitles.push(title);
}
// Record the new tiddler state
updateDescriptor["new"] = {
tiddler: tiddler,
shadow: this.isShadowTiddler(title),
exists: this.tiddlerExists(title)
}
// Update indexes
this.clearCache(title);
this.clearGlobalCache();
$tw.utils.each(indexers,function(indexer) {
indexer.update(updateDescriptor);
});
// Queue a change event
this.enqueueTiddlerEvent(title);
}
}
@@ -1102,36 +1064,15 @@ $tw.Wiki = function(options) {
// Uncomment the following line for detailed logs of all tiddler deletions
// console.log("Deleting",title)
if($tw.utils.hop(tiddlers,title)) {
// Record the old tiddler state
var updateDescriptor = {
old: {
tiddler: this.getTiddler(title),
shadow: this.isShadowTiddler(title),
exists: this.tiddlerExists(title)
}
}
// Delete the tiddler
delete tiddlers[title];
// Delete it from the list of titles
if(tiddlerTitles) {
var index = tiddlerTitles.indexOf(title);
if(index !== -1) {
tiddlerTitles.splice(index,1);
}
}
// Record the new tiddler state
updateDescriptor["new"] = {
tiddler: this.getTiddler(title),
shadow: this.isShadowTiddler(title),
exists: this.tiddlerExists(title)
}
// Update indexes
this.clearCache(title);
this.clearGlobalCache();
$tw.utils.each(indexers,function(indexer) {
indexer.update(updateDescriptor);
});
// Queue a change event
this.enqueueTiddlerEvent(title,true);
}
};
@@ -1218,6 +1159,7 @@ $tw.Wiki = function(options) {
callback(tiddlers[title],title);
}
}
};
// Test for the existence of a tiddler (excludes shadow tiddlers)
@@ -1331,14 +1273,8 @@ $tw.Wiki = function(options) {
shadowTiddlerTitles = null;
this.clearCache(null);
this.clearGlobalCache();
$tw.utils.each(indexers,function(indexer) {
indexer.rebuild();
});
};
if(this.addIndexersToWiki) {
this.addIndexersToWiki();
}
};
// Dummy methods that will be filled in after boot
@@ -1533,40 +1469,8 @@ $tw.modules.define("$:/boot/tiddlerdeserializer/html","tiddlerdeserializer",{
});
$tw.modules.define("$:/boot/tiddlerdeserializer/json","tiddlerdeserializer",{
"application/json": function(text,fields) {
var isTiddlerValid = function(data) {
// Not valid if it's not an object with a title property
if(typeof(data) !== "object" || !$tw.utils.hop(data,"title")) {
return false;
}
for(var f in data) {
if($tw.utils.hop(data,f)) {
// Check field name doesn't contain whitespace or control characters
if(typeof(data[f]) !== "string" || /[\x00-\x1F\s]/.test(f)) {
return false;
}
}
}
return true;
},
isTiddlerArrayValid = function(data) {
for(var t=0; t<data.length; t++) {
if(!isTiddlerValid(data[t])) {
return false;
}
}
return true;
},
data = JSON.parse(text);
if($tw.utils.isArray(data) && isTiddlerArrayValid(data)) {
return data;
} else if(isTiddlerValid(data)) {
return [data];
} else {
// Plain JSON file
fields.text = text;
fields.type = "application/json";
return [fields];
}
var data = JSON.parse(text);
return $tw.utils.isArray(data) ? data : [data];
}
});
@@ -1719,11 +1623,9 @@ $tw.loadTiddlersFromFile = function(filepath,fields) {
typeInfo = type ? $tw.config.contentTypeInfo[type] : null,
data = fs.readFileSync(filepath,typeInfo ? typeInfo.encoding : "utf8"),
tiddlers = $tw.wiki.deserializeTiddlers(ext,data,fields),
metadata;
if(ext !== ".json" && tiddlers.length === 1) {
metadata = $tw.loadMetadataForFile(filepath);
if(metadata) {
if(type === "application/json") {
tiddlers = [{text: data, type: "application/json"}];
}
tiddlers = [$tw.utils.extend({},tiddlers[0],metadata)];
}
return {filepath: filepath, type: type, tiddlers: tiddlers, hasMetaFile: !!metadata};
@@ -1953,10 +1855,8 @@ $tw.loadPlugin = function(name,paths) {
var pluginFields = $tw.loadPluginFolder(pluginPath);
if(pluginFields) {
$tw.wiki.addTiddler(pluginFields);
return;
}
}
console.log("Warning: Cannot find plugin '" + name + "'");
};
/*
@@ -1970,7 +1870,7 @@ $tw.getLibraryItemSearchPaths = function(libraryPath,envVar) {
if(env) {
env.split(path.delimiter).map(function(item) {
if(item) {
pluginPaths.push(item);
pluginPaths.push(item)
}
});
}
@@ -2106,21 +2006,6 @@ $tw.loadTiddlersNode = function() {
});
// Load the core tiddlers
$tw.wiki.addTiddler($tw.loadPluginFolder($tw.boot.corePath));
// Load any extra plugins
$tw.utils.each($tw.boot.extraPlugins,function(name) {
if(name.charAt(0) === "+") { // Relative path to plugin
var pluginFields = $tw.loadPluginFolder(name.substring(1));;
if(pluginFields) {
$tw.wiki.addTiddler(pluginFields);
}
} else {
var parts = name.split("/"),
type = parts[0];
if(parts.length === 3 && ["plugins","themes","languages"].indexOf(type) !== -1) {
$tw.loadPlugins([parts[1] + "/" + parts[2]],$tw.config[type + "Path"],$tw.config[type + "EnvVar"]);
}
}
});
// Load the tiddlers from the wiki directory
if($tw.boot.wikiPath) {
$tw.boot.wikiInfo = $tw.loadWikiTiddlers($tw.boot.wikiPath);
@@ -2184,12 +2069,6 @@ $tw.boot.startup = function(options) {
if($tw.boot.argv.length === 0) {
$tw.boot.argv = ["--help"];
}
// Parse any extra plugin references
$tw.boot.extraPlugins = $tw.boot.extraPlugins || [];
while($tw.boot.argv[0] && $tw.boot.argv[0].indexOf("+") === 0) {
$tw.boot.extraPlugins.push($tw.boot.argv[0].substring(1));
$tw.boot.argv.splice(0,1);
}
// If the first command line argument doesn't start with `--` then we
// interpret it as the path to the wiki folder, which will otherwise default
// to the current folder

View File

@@ -1,3 +1,4 @@
<h1 class="">Contributing to <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/TiddlyWiki5.html">TiddlyWiki5</a></h1><p>We welcome contributions to the code and documentation of <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/TiddlyWiki.html">TiddlyWiki</a> in several ways:</p><ul><li><a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/ReportingBugs.html">ReportingBugs</a></li><li>Helping to <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/Improving%2520TiddlyWiki%2520Documentation.html">improve our documentation</a></li><li>Contributing to the code via <a class="tc-tiddlylink-external" href="https://github.com/Jermolene/TiddlyWiki5" rel="noopener noreferrer" target="_blank">GitHub</a><ul><li>See <a class="tc-tiddlylink-external" href="https://tiddlywiki.com/dev" rel="noopener noreferrer" target="_blank">https://tiddlywiki.com/dev</a> for more details</li></ul></li></ul><p>There are other ways to <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/HelpingTiddlyWiki.html">help TiddlyWiki</a> too.</p><h1 class="">Contributor License Agreement</h1><p>Like other <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/OpenSource.html">OpenSource</a> projects, <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/TiddlyWiki5.html">TiddlyWiki5</a> needs a signed contributor license agreement from individual contributors. This is a legal agreement that allows contributors to assert that they own the copyright of their contribution, and that they agree to license it to the <a class="tc-tiddlylink tc-tiddlylink-missing" href="https://tiddlywiki.com/static/UnaMesa.html">UnaMesa</a> Association (the legal entity that owns <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/TiddlyWiki.html">TiddlyWiki</a> on behalf of the community).</p><ul><li>For individuals use: <a class="tc-tiddlylink-external" href="https://github.com/Jermolene/TiddlyWiki5/tree/master/licenses/cla-individual.md" rel="noopener noreferrer" target="_blank">licenses/CLA-individual</a></li><li>For entities use: <a class="tc-tiddlylink-external" href="https://github.com/Jermolene/TiddlyWiki5/tree/master/licenses/cla-entity.md" rel="noopener noreferrer" target="_blank">licenses/CLA-entity</a></li></ul><h1 class="">How to sign the CLA</h1><p>Create a <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/GitHub.html">GitHub</a> pull request to add your name to <code>cla-individual.md</code> or <code>cla-entity.md</code>, with the date in the format (YYYY/MM/DD).</p><p><strong>step by step</strong></p><ol><li>Navigate to <a class="tc-tiddlylink-external" href="https://github.com/Jermolene/TiddlyWiki5/tree/master/licenses/cla-individual.md" rel="noopener noreferrer" target="_blank">licenses/CLA-individual</a> or <a class="tc-tiddlylink-external" href="https://github.com/Jermolene/TiddlyWiki5/tree/master/licenses/cla-entity.md" rel="noopener noreferrer" target="_blank">licenses/CLA-entity</a> according to whether you are signing as an individual or representative of an organisation</li><li>Ensure that the &quot;branch&quot; dropdown at the top left is set to <code>tiddlywiki-com</code></li><li>Click the &quot;edit&quot; button at the top-right corner (clicking this button will fork the project so you can edit the file)</li><li>Add your name at the bottom<ul><li>eg: <code>Jeremy Ruston, @Jermolene, 2011/11/22</code></li></ul></li><li>Below the edit box for the CLA text you should see a box labelled <strong>Propose file change</strong></li><li>Enter a brief title to explain the change (eg, &quot;Signing the CLA&quot;)</li><li>Click the green button labelled <strong>Propose file change</strong></li><li>On the following screen, click the green button labelled <strong>Create pull request</strong></li></ol><hr><p><em>The CLA documents used for this project were created using <a class="tc-tiddlylink-external" href="http://www.harmonyagreements.org" rel="noopener noreferrer" target="_blank">Harmony Project Templates</a>. &quot;HA-CLA-I-LIST Version 1.0&quot; for &quot;CLA-individual&quot; and &quot;HA-CLA-E-LIST Version 1.0&quot; for &quot;CLA-entity&quot;.</em></p><h2 class="">Remarks</h2><p><strong>If you do not own the copyright in the entire work of authorship</strong>:</p><p>In this case, please clearly state so and provide links and any additional information that clarify under which license the rest of the code is distributed.
<h1 class="">Contributing to <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/TiddlyWiki5.html">TiddlyWiki5</a></h1><p>We welcome contributions to the code and documentation of <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/TiddlyWiki.html">TiddlyWiki</a> in several ways:</p><ul><li><a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/ReportingBugs.html">ReportingBugs</a></li><li>Helping to <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/Improving%2520TiddlyWiki%2520Documentation.html">improve our documentation</a></li><li>Contributing to the code via <a class="tc-tiddlylink-external" href="https://github.com/Jermolene/TiddlyWiki5" rel="noopener noreferrer" target="_blank">GitHub</a><ul><li>See <a class="tc-tiddlylink-external" href="https://tiddlywiki.com/dev" rel="noopener noreferrer" target="_blank">https://tiddlywiki.com/dev</a> for more details</li></ul></li></ul><p>There are other ways to <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/HelpingTiddlyWiki.html">help TiddlyWiki</a> too.</p><h1 class="">Contributor License Agreement</h1><p>Like other <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/OpenSource.html">OpenSource</a> projects, <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/TiddlyWiki5.html">TiddlyWiki5</a> needs a signed contributor license agreement from individual contributors. This is a legal agreement that allows contributors to assert that they own the copyright of their contribution, and that they agree to license it to the <a class="tc-tiddlylink tc-tiddlylink-missing" href="https://tiddlywiki.com/static/UnaMesa.html">UnaMesa</a> Association (the legal entity that owns <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/TiddlyWiki.html">TiddlyWiki</a> on behalf of the community).</p><ul><li>For individuals use: <a class="tc-tiddlylink-external" href="https://github.com/Jermolene/TiddlyWiki5/tree/master/licenses/cla-individual.md" rel="noopener noreferrer" target="_blank">licenses/CLA-individual</a></li><li>For entities use: <a class="tc-tiddlylink-external" href="https://github.com/Jermolene/TiddlyWiki5/tree/master/licenses/cla-entity.md" rel="noopener noreferrer" target="_blank">licenses/CLA-entity</a></li></ul><h1 class="">How to sign the CLA</h1><p>Create a <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/GitHub.html">GitHub</a> pull request to add your name to <code>cla-individual.md</code> or <code>cla-entity.md</code>, with the date in the format (YYYY/MM/DD).</p><p><strong>step by step</strong></p><ol><li>Navigate to <a class="tc-tiddlylink-external" href="https://github.com/Jermolene/TiddlyWiki5/tree/master/licenses/cla-individual.md" rel="noopener noreferrer" target="_blank">licenses/CLA-individual</a> or <a class="tc-tiddlylink-external" href="https://github.com/Jermolene/TiddlyWiki5/tree/master/licenses/cla-entity.md" rel="noopener noreferrer" target="_blank">licenses/CLA-entity</a> according to whether you are signing as an individual or representative of an organisation</li><li>Click the &quot;edit&quot; button at the top-right corner (clicking this button will fork the project so you can edit the file)</li><li>Add your name at the bottom<ul><li>eg: <code>Jeremy Ruston, @Jermolene, 2011/11/22</code></li></ul></li><li>Below the edit box for the CLA text you should see a box labelled <strong>Propose file change</strong></li><li>Enter a brief title to explain the change (eg, &quot;Signing the CLA&quot;)</li><li>Click the green button labelled <strong>Propose file change</strong></li><li>On the following screen, click the green button labelled <strong>Create pull request</strong></li></ol><hr><p><em>The CLA documents used for this project were created using <a class="tc-tiddlylink-external" href="http://www.harmonyagreements.org" rel="noopener noreferrer" target="_blank">Harmony Project Templates</a>. &quot;HA-CLA-I-LIST Version 1.0&quot; for &quot;CLA-individual&quot; and &quot;HA-CLA-E-LIST Version 1.0&quot; for &quot;CLA-entity&quot;.</em></p><p>Remarks
----—</p><ul><li><ul><li>When not owning the copyright in the entire work of authorship**</li></ul></li></ul><p>In this case, please clearly state so, since otherwise we assume that you are the legal copyright holder of the contributed work! Please provide links and additional information that clarify under which license the rest of the code is distributed.
</p><p><em>This file was automatically generated by <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/TiddlyWiki5.html">TiddlyWiki5</a></em>
</p>

View File

@@ -32,7 +32,6 @@ ExportTiddler/Caption: export tiddler
ExportTiddler/Hint: Export tiddler
ExportTiddlers/Caption: export tiddlers
ExportTiddlers/Hint: Export tiddlers
SidebarSearch/Hint: Select the sidebar search field
Fold/Caption: fold tiddler
Fold/Hint: Fold the body of this tiddler
Fold/FoldBar/Caption: fold-bar
@@ -182,7 +181,6 @@ Subscript/Caption: subscript
Subscript/Hint: Apply subscript formatting to selection
Superscript/Caption: superscript
Superscript/Hint: Apply superscript formatting to selection
ToggleSidebar/Hint: Toggle the sidebar visibility
Transcludify/Caption: transclusion
Transcludify/Hint: Wrap selection in curly brackets
Underline/Caption: underline

View File

@@ -47,8 +47,6 @@ LoadedModules/Hint: These are the currently loaded tiddler modules linked to the
Palette/Caption: Palette
Palette/Editor/Clone/Caption: clone
Palette/Editor/Clone/Prompt: It is recommended that you clone this shadow palette before editing it
Palette/Editor/Delete/Hint: delete this entry from the current palette
Palette/Editor/Names/External/Show: Show color names that are not part of the current palette
Palette/Editor/Prompt/Modified: This shadow palette has been modified
Palette/Editor/Prompt: Editing
Palette/Editor/Reset/Caption: reset
@@ -91,18 +89,6 @@ Saving/DownloadSaver/Hint: These settings apply to the HTML5-compatible download
Saving/General/Caption: General
Saving/General/Hint: These settings apply to all the loaded savers
Saving/Hint: Settings used for saving the entire TiddlyWiki as a single file via a saver module
Saving/GitService/Branch: Target branch for saving
Saving/GitService/CommitMessage: Saved by TiddlyWiki
Saving/GitService/Description: These settings are only used when saving to <<service-name>>
Saving/GitService/Filename: Filename of target file (e.g. `index.html`)
Saving/GitService/Path: Path to target file (e.g. `/wiki/`)
Saving/GitService/Repo: Target repository (e.g. `Jermolene/TiddlyWiki5`)
Saving/GitService/ServerURL: Server API URL
Saving/GitService/UserName: Username
Saving/GitService/GitHub/Caption: ~GitHub Saver
Saving/GitService/GitHub/Password: Password, OAUTH token, or personal access token (see [[GitHub help page|https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line]] for details)
Saving/GitService/GitLab/Caption: ~GitLab Saver
Saving/GitService/GitLab/Password: Personal access token for API (see [[GitLab help page|https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html]] for details)
Saving/TiddlySpot/Advanced/Heading: Advanced Settings
Saving/TiddlySpot/BackupDir: Backup Directory
Saving/TiddlySpot/Backups: Backups

View File

@@ -1,8 +0,0 @@
title: $:/language/Help/deletetiddlers
description: Deletes a group of tiddlers
<<.from-version "5.1.20">> Deletes a group of tiddlers identified by a filter.
```
--deletetiddlers <filter>
```

View File

@@ -1,19 +0,0 @@
title: $:/language/Help/savewikifolder
description: Saves a wiki to a new wiki folder
<<.from-version "5.1.20">> Saves the current wiki as a wiki folder, including tiddlers, plugins and configuration:
```
--savewikifolder <wikifolderpath> [<filter>]
```
* The target wiki folder must be empty or non-existent
* The filter specifies which tiddlers should be included. It is optional, defaulting to `[all[tiddlers]]`
* Plugins from the official plugin library are replaced with references to those plugins in the `tiddlywiki.info` file
* Custom plugins are unpacked into their own folder
A common usage is to convert a TiddlyWiki HTML file into a wiki folder:
```
tiddlywiki --load ./mywiki.html --savewikifolder ./mywikifolder
```

View File

@@ -1,42 +0,0 @@
/*\
title: $:/core/modules/commands/deletetiddlers.js
type: application/javascript
module-type: command
Command to delete tiddlers
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
exports.info = {
name: "deletetiddlers",
synchronous: true
};
var Command = function(params,commander,callback) {
this.params = params;
this.commander = commander;
this.callback = callback;
};
Command.prototype.execute = function() {
if(this.params.length < 1) {
return "Missing filter";
}
var self = this,
wiki = this.commander.wiki,
filter = this.params[0],
tiddlers = wiki.filterTiddlers(filter);
$tw.utils.each(tiddlers,function(title) {
wiki.deleteTiddler(title);
});
return null;
};
exports.Command = Command;
})();

View File

@@ -1,184 +0,0 @@
/*\
title: $:/core/modules/commands/savewikifolder.js
type: application/javascript
module-type: command
Command to save the current wiki as a wiki folder
--savewikifolder <wikifolderpath> [<filter>]
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
exports.info = {
name: "savewikifolder",
synchronous: true
};
var fs,path;
if($tw.node) {
fs = require("fs");
path = require("path");
}
var Command = function(params,commander,callback) {
this.params = params;
this.commander = commander;
this.callback = callback;
};
Command.prototype.execute = function() {
if(this.params.length < 1) {
return "Missing wiki folder path";
}
var wikifoldermaker = new WikiFolderMaker(this.params[0],this.params[1],this.commander);
return wikifoldermaker.save();
};
function WikiFolderMaker(wikiFolderPath,wikiFilter,commander) {
this.wikiFolderPath = wikiFolderPath;
this.wikiFilter = wikiFilter || "[all[tiddlers]]";
this.commander = commander;
this.wiki = commander.wiki;
this.savedPaths = []; // So that we can detect filename clashes
}
WikiFolderMaker.prototype.log = function(str) {
if(this.commander.verbose) {
console.log(str);
}
};
WikiFolderMaker.prototype.tiddlersToIgnore = [
"$:/boot/boot.css",
"$:/boot/boot.js",
"$:/boot/bootprefix.js",
"$:/core",
"$:/library/sjcl.js",
"$:/temp/info-plugin"
];
/*
Returns null if successful, or an error string if there was an error
*/
WikiFolderMaker.prototype.save = function() {
var self = this;
// Check that the output directory doesn't exist
if(fs.existsSync(this.wikiFolderPath) && !$tw.utils.isDirectoryEmpty(this.wikiFolderPath)) {
return "The unpackwiki command requires that the output wiki folder be empty";
}
// Get the tiddlers from the source wiki
var tiddlerTitles = this.wiki.filterTiddlers(this.wikiFilter);
// Initialise a new tiddlwiki.info file
var newWikiInfo = {};
// Process each incoming tiddler in turn
$tw.utils.each(tiddlerTitles,function(title) {
var tiddler = self.wiki.getTiddler(title);
if(tiddler) {
if(self.tiddlersToIgnore.indexOf(title) !== -1) {
// Ignore the core plugin and the ephemeral info plugin
self.log("Ignoring tiddler: " + title);
} else {
var type = tiddler.fields.type,
pluginType = tiddler.fields["plugin-type"];
if(type === "application/json" && pluginType) {
// Plugin tiddler
var libraryDetails = self.findPluginInLibrary(title);
if(libraryDetails) {
// A plugin from the core library
self.log("Adding built-in plugin: " + libraryDetails.name);
newWikiInfo[libraryDetails.type] = newWikiInfo[libraryDetails.type] || [];
$tw.utils.pushTop(newWikiInfo[libraryDetails.type],libraryDetails.name);
} else {
// A custom plugin
self.log("Processing custom plugin: " + title);
self.saveCustomPlugin(tiddler);
}
} else {
// Ordinary tiddler
self.saveTiddler("tiddlers",tiddler);
}
}
}
});
// Save the tiddlywiki.info file
this.saveJSONFile("tiddlywiki.info",newWikiInfo);
self.log("Writing tiddlywiki.info: " + JSON.stringify(newWikiInfo,null,$tw.config.preferences.jsonSpaces));
return null;
};
/*
Test whether the specified tiddler is a plugin in the plugin library
*/
WikiFolderMaker.prototype.findPluginInLibrary = function(title) {
var parts = title.split("/"),
pluginPath, type, name;
if(parts[0] === "$:") {
if(parts[1] === "languages" && parts.length === 3) {
pluginPath = "languages" + path.sep + parts[2];
type = parts[1];
name = parts[2];
} else if(parts[1] === "plugins" || parts[1] === "themes" && parts.length === 4) {
pluginPath = parts[1] + path.sep + parts[2] + path.sep + parts[3];
type = parts[1];
name = parts[2] + "/" + parts[3];
}
}
if(pluginPath && type && name) {
pluginPath = path.resolve($tw.boot.bootPath,"..",pluginPath);
if(fs.existsSync(pluginPath)) {
return {
pluginPath: pluginPath,
type: type,
name: name
};
}
}
return false;
};
WikiFolderMaker.prototype.saveCustomPlugin = function(pluginTiddler) {
var self = this,
pluginTitle = pluginTiddler.fields.title,
titleParts = pluginTitle.split("/"),
directory = $tw.utils.generateTiddlerFilepath(titleParts[titleParts.length - 1],{
directory: path.resolve(this.wikiFolderPath,pluginTiddler.fields["plugin-type"] + "s")
}),
pluginInfo = pluginTiddler.getFieldStrings({exclude: ["text","type"]});
this.saveJSONFile(directory + path.sep + "plugin.info",pluginInfo);
self.log("Writing " + directory + path.sep + "plugin.info: " + JSON.stringify(pluginInfo,null,$tw.config.preferences.jsonSpaces));
var pluginTiddlers = JSON.parse(pluginTiddler.fields.text).tiddlers; // A hashmap of tiddlers in the plugin
$tw.utils.each(pluginTiddlers,function(tiddler) {
self.saveTiddler(directory,new $tw.Tiddler(tiddler));
});
};
WikiFolderMaker.prototype.saveTiddler = function(directory,tiddler) {
var fileInfo = $tw.utils.generateTiddlerFileInfo(tiddler,{
directory: path.resolve(this.wikiFolderPath,directory),
wiki: this.wiki
});
$tw.utils.saveTiddlerToFileSync(tiddler,fileInfo);
};
WikiFolderMaker.prototype.saveJSONFile = function(filename,json) {
this.saveTextFile(filename,JSON.stringify(json,null,$tw.config.preferences.jsonSpaces));
};
WikiFolderMaker.prototype.saveTextFile = function(filename,data) {
this.saveFile(filename,"utf8",data);
};
WikiFolderMaker.prototype.saveFile = function(filename,encoding,data) {
var filepath = path.resolve(this.wikiFolderPath,filename);
$tw.utils.createFileDirectories(filepath);
fs.writeFileSync(filepath,data,encoding);
};
exports.Command = Command;
})();

View File

@@ -42,7 +42,6 @@ function FramedEngine(options) {
this.iframeNode.style.border = "none";
this.iframeNode.style.padding = "0";
this.iframeNode.style.resize = "none";
this.iframeNode.style["background-color"] = this.widget.wiki.extractTiddlerDataItem(this.widget.wiki.getTiddlerText("$:/palette"),"tiddler-editor-background");
this.iframeDoc.body.style.margin = "0";
this.iframeDoc.body.style.padding = "0";
this.widget.domNodes.push(this.iframeNode);
@@ -79,7 +78,6 @@ function FramedEngine(options) {
// Add event listeners
$tw.utils.addEventListeners(this.domNode,[
{name: "click",handlerObject: this,handlerMethod: "handleClickEvent"},
{name: "focus",handlerObject: this,handlerMethod: "handleFocusEvent"},
{name: "input",handlerObject: this,handlerMethod: "handleInputEvent"},
{name: "keydown",handlerObject: this.widget,handlerMethod: "handleKeydownEvent"}
]);
@@ -97,7 +95,6 @@ FramedEngine.prototype.copyStyles = function() {
this.domNode.style.display = "block";
this.domNode.style.width = "100%";
this.domNode.style.margin = "0";
this.domNode.style["background-color"] = this.widget.wiki.extractTiddlerDataItem(this.widget.wiki.getTiddlerText("$:/palette"),"tiddler-editor-background");
// In Chrome setting -webkit-text-fill-color overrides the placeholder text colour
this.domNode.style["-webkit-text-fill-color"] = "currentcolor";
};
@@ -153,14 +150,6 @@ FramedEngine.prototype.focus = function() {
this.domNode.select();
}
};
/*
Handle the focus event
*/
FramedEngine.prototype.handleFocusEvent = function(event) {
this.widget.cancelPopups();
return true;
};
/*
Handle a click

View File

@@ -122,7 +122,6 @@ SimpleEngine.prototype.handleInputEvent = function(event) {
Handle a dom "focus" event
*/
SimpleEngine.prototype.handleFocusEvent = function(event) {
this.widget.cancelPopups();
if(this.widget.editFocusPopup) {
$tw.popup.triggerPopup({
domNode: this.domNode,

View File

@@ -193,7 +193,7 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
type = type || "text";
}
// Get the rest of our parameters
this.editTag = this.getAttribute("tag",tag) || "input";
this.editTag = this.getAttribute("tag",tag);
this.editType = this.getAttribute("type",type);
// Make the child widgets
this.makeChildWidgets();
@@ -248,13 +248,6 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
}
};
/*
Cancel Popups
*/
EditTextWidget.prototype.cancelPopups = function() {
$tw.popup.cancel(0,this.engine.domNode);
};
/*
Handle a dom "keydown" event, which we'll bubble up to our container for the keyboard widgets benefit
*/

View File

@@ -119,7 +119,7 @@ exports.parseFilter = function(filterString) {
p = 0, // Current position in the filter string
match;
var whitespaceRegExp = /(\s+)/mg,
operandRegExp = /((?:\+|\-|~|=)?)(?:(\[)|(?:"([^"]*)")|(?:'([^']*)')|([^\s\[\]]+))/mg;
operandRegExp = /((?:\+|\-|~)?)(?:(\[)|(?:"([^"]*)")|(?:'([^']*)')|([^\s\[\]]+))/mg;
while(p < filterString.length) {
// Skip any whitespace
whitespaceRegExp.lastIndex = p;
@@ -248,10 +248,6 @@ exports.compileFilter = function(filterString) {
return function(results,source,widget) {
$tw.utils.pushTop(results,operationSubFunction(source,widget));
};
case "=": // The results of the operation are pushed into the result without deduplication
return function(results,source,widget) {
Array.prototype.push.apply(results,operationSubFunction(source,widget));
};
case "-": // The results of this operation are removed from the main result
return function(results,source,widget) {
$tw.utils.removeArrayEntries(results,operationSubFunction(source,widget));
@@ -274,7 +270,7 @@ exports.compileFilter = function(filterString) {
})());
});
// Return a function that applies the operations to a source iterator of tiddler titles
return $tw.perf.measure("filter: " + filterString,function filterFunction(source,widget) {
return $tw.perf.measure("filter",function filterFunction(source,widget) {
if(!source) {
source = self.each;
} else if(typeof source === "object") { // Array or hashmap

View File

@@ -1,30 +0,0 @@
/*\
title: $:/core/modules/filters/else.js
type: application/javascript
module-type: filteroperator
Filter operator for replacing an empty input list with a constant, passing a non-empty input list straight through
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.else = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
results.push(title);
});
if(results.length === 0) {
return [operator.operand];
} else {
return results;
}
};
})();

View File

@@ -98,13 +98,4 @@ exports.escaperegexp = function(source,operator,options) {
return results;
};
exports.escapecss = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
// escape any character with a special meaning in CSS using CSS.escape()
results.push(CSS.escape(title));
});
return results;
};
})();

View File

@@ -16,16 +16,7 @@ Filter operator returning its operand parsed as a list
Export our filter function
*/
exports.enlist = function(source,operator,options) {
var allowDuplicates = false;
switch(operator.suffix) {
case "raw":
allowDuplicates = true;
break;
case "dedupe":
allowDuplicates = false;
break;
}
var list = $tw.utils.parseStringArray(operator.operand,allowDuplicates);
var list = $tw.utils.parseStringArray(operator.operand);
if(operator.prefix === "!") {
var results = [];
source(function(tiddler,title) {

View File

@@ -16,7 +16,7 @@ Filter operator for comparing fields for equality
Export our filter function
*/
exports.field = function(source,operator,options) {
var results = [],indexedResults,
var results = [],
fieldname = (operator.suffix || operator.operator || "title").toLowerCase();
if(operator.prefix === "!") {
if(operator.regexp) {
@@ -53,12 +53,6 @@ exports.field = function(source,operator,options) {
}
});
} else {
if(source.byField && operator.operand) {
indexedResults = source.byField(fieldname,operator.operand);
if(indexedResults) {
return indexedResults
}
}
source(function(tiddler,title) {
if(tiddler) {
var text = tiddler.getFieldString(fieldname);

View File

@@ -1,26 +0,0 @@
/*\
title: $:/core/modules/filters/getvariable.js
type: application/javascript
module-type: filteroperator
Filter operator for replacing input values by the value of the variable with the same name, or blank if the variable is missing
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.getvariable = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
results.push(options.widget.getVariable(title) || "");
});
return results;
};
})();

View File

@@ -45,7 +45,7 @@ exports.has = function(source,operator,options) {
if(tiddler && $tw.utils.hop(tiddler.fields,operator.operand) && !(tiddler.fields[operator.operand] === "" || tiddler.fields[operator.operand].length === 0)) {
results.push(title);
}
});
});
}
}
return results;

View File

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

View File

@@ -1,53 +0,0 @@
/*\
title: $:/core/modules/filters/match.js
type: application/javascript
module-type: filteroperator
Filter operator for checking if a title matches a string
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.match = function(source,operator,options) {
var results = [],
suffixes = (operator.suffixes || [])[0] || [];
if(suffixes.indexOf("caseinsensitive") !== -1) {
if(operator.prefix === "!") {
source(function(tiddler,title) {
if(title.toLowerCase() !== (operator.operand || "").toLowerCase()) {
results.push(title);
}
});
} else {
source(function(tiddler,title) {
if(title.toLowerCase() === (operator.operand || "").toLowerCase()) {
results.push(title);
}
});
}
} else {
if(operator.prefix === "!") {
source(function(tiddler,title) {
if(title !== operator.operand) {
results.push(title);
}
});
} else {
source(function(tiddler,title) {
if(title === operator.operand) {
results.push(title);
}
});
}
}
return results;
};
})();

View File

@@ -43,10 +43,6 @@ exports.trunc = makeNumericBinaryOperator(
function(a) {return Math.trunc(a)}
);
exports.untrunc = makeNumericBinaryOperator(
function(a) {return Math.ceil(Math.abs(a)) * Math.sign(a)}
);
exports.sign = makeNumericBinaryOperator(
function(a) {return Math.sign(a)}
);
@@ -80,33 +76,33 @@ exports.min = makeNumericBinaryOperator(
);
exports.fixed = makeNumericBinaryOperator(
function(a,b) {return Number.prototype.toFixed.call(a,Math.min(Math.max(b,0),100));}
function(a,b) {return Number.prototype.toFixed.call(a,b);}
);
exports.precision = makeNumericBinaryOperator(
function(a,b) {return Number.prototype.toPrecision.call(a,Math.min(Math.max(b,1),100));}
function(a,b) {return Number.prototype.toPrecision.call(a,b);}
);
exports.exponential = makeNumericBinaryOperator(
function(a,b) {return Number.prototype.toExponential.call(a,Math.min(Math.max(b,0),100));}
function(a,b) {return Number.prototype.toExponential.call(a,b);}
);
exports.sum = makeNumericReducingOperator(
exports.sum = makeNumericArrayOperator(
function(accumulator,value) {return accumulator + value},
0 // Initial value
);
exports.product = makeNumericReducingOperator(
exports.product = makeNumericArrayOperator(
function(accumulator,value) {return accumulator * value},
1 // Initial value
);
exports.maxall = makeNumericReducingOperator(
exports.maxall = makeNumericArrayOperator(
function(accumulator,value) {return Math.max(accumulator,value)},
-Infinity // Initial value
);
exports.minall = makeNumericReducingOperator(
exports.minall = makeNumericArrayOperator(
function(accumulator,value) {return Math.min(accumulator,value)},
Infinity // Initial value
);
@@ -122,7 +118,7 @@ function makeNumericBinaryOperator(fnCalc) {
};
}
function makeNumericReducingOperator(fnCalc,initialValue) {
function makeNumericArrayOperator(fnCalc,initialValue) {
initialValue = initialValue || 0;
return function(source,operator,options) {
var result = [];

View File

@@ -43,7 +43,6 @@ exports.search = function(source,operator,options) {
caseSensitive: hasFlag("casesensitive"),
literal: hasFlag("literal"),
whitespace: hasFlag("whitespace"),
anchored: hasFlag("anchored"),
regexp: hasFlag("regexp"),
words: hasFlag("words")
});

View File

@@ -26,30 +26,22 @@ exports.lowercase = makeStringBinaryOperator(
function(a) {return [("" + a).toLowerCase()];}
);
exports.sentencecase = makeStringBinaryOperator(
function(a) {return [$tw.utils.toSentenceCase(a)];}
);
exports.titlecase = makeStringBinaryOperator(
function(a) {return [$tw.utils.toTitleCase(a)];}
);
exports.trim = makeStringBinaryOperator(
function(a) {return [$tw.utils.trim(a)];}
);
exports.split = makeStringBinaryOperator(
function(a,b) {return ("" + a).split(b);}
exports.concat = makeStringBinaryOperator(
function(a,b) {return ["" + a + b];}
);
exports.join = makeStringReducingOperator(
exports.split = makeStringBinaryOperator(
function(a,b) {return ("" + a).split(b).filter(function(str) {return !!str;});}
);
exports.join = makeStringArrayOperator(
function(accumulator,value,operand) {
if(accumulator === null) {
return value;
} else {
return accumulator + operand + value;
}
},null
return "" + (accumulator ? accumulator + (operand || "") + value : value);
}
);
function makeStringBinaryOperator(fnCalc) {
@@ -62,7 +54,8 @@ function makeStringBinaryOperator(fnCalc) {
};
}
function makeStringReducingOperator(fnCalc,initialValue) {
function makeStringArrayOperator(fnCalc,initialValue) {
initialValue = initialValue || "";
return function(source,operator,options) {
var result = [];
source(function(tiddler,title) {
@@ -74,20 +67,4 @@ function makeStringReducingOperator(fnCalc,initialValue) {
};
}
exports.splitregexp = function(source,operator,options) {
var result = [],
suffix = operator.suffix || "",
flags = (suffix.indexOf("m") !== -1 ? "m" : "") + (suffix.indexOf("i") !== -1 ? "i" : ""),
regExp;
try {
regExp = new RegExp(operator.operand || "",flags);
} catch(ex) {
return ["RegExp error: " + ex];
}
source(function(tiddler,title) {
Array.prototype.push.apply(result,title.split(regExp));
});
return result;
};
})();

View File

@@ -16,7 +16,7 @@ Filter operator for checking for the presence of a tag
Export our filter function
*/
exports.tag = function(source,operator,options) {
var results = [],indexedResults;
var results = [];
if((operator.suffix || "").toLowerCase() === "strict" && !operator.operand) {
// New semantics:
// Always return copy of input if operator.operand is missing
@@ -25,10 +25,9 @@ exports.tag = function(source,operator,options) {
});
} else {
// Old semantics:
var tiddlers;
var tiddlers = options.wiki.getTiddlersWithTag(operator.operand);
if(operator.prefix === "!") {
// Returns a copy of the input if operator.operand is missing
tiddlers = options.wiki.getTiddlersWithTag(operator.operand);
source(function(tiddler,title) {
if(tiddlers.indexOf(title) === -1) {
results.push(title);
@@ -36,20 +35,12 @@ exports.tag = function(source,operator,options) {
});
} else {
// Returns empty results if operator.operand is missing
if(source.byTag) {
indexedResults = source.byTag(operator.operand);
if(indexedResults) {
return indexedResults;
source(function(tiddler,title) {
if(tiddlers.indexOf(title) !== -1) {
results.push(title);
}
} else {
tiddlers = options.wiki.getTiddlersWithTag(operator.operand);
source(function(tiddler,title) {
if(tiddlers.indexOf(title) !== -1) {
results.push(title);
}
});
results = options.wiki.sortByList(results,operator.operand);
}
});
results = options.wiki.sortByList(results,operator.operand);
}
}
return results;

View File

@@ -1,26 +0,0 @@
/*\
title: $:/core/modules/filters/then.js
type: application/javascript
module-type: filteroperator
Filter operator for replacing any titles with a constant
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.then = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
results.push(operator.operand);
});
return results;
};
})();

View File

@@ -1,26 +0,0 @@
/*\
title: $:/core/modules/filters/variables.js
type: application/javascript
module-type: filteroperator
Filter operator for returning the names of the active variables
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.variables = function(source,operator,options) {
var names = [];
for(var variable in options.widget.variables) {
names.push(variable);
}
return names.sort();
};
})();

View File

@@ -95,7 +95,7 @@ Extended filter operators to manipulate the current list.
exports.allafter = function (source, operator) {
var results = prepare_results(source),
index = results.indexOf(operator.operand);
return (index === -1) ? [] :
return (index === -1 || index > (results.length - 2)) ? [] :
(operator.suffix) ? results.slice(index) :
results.slice(index + 1);
};
@@ -106,7 +106,7 @@ Extended filter operators to manipulate the current list.
exports.allbefore = function (source, operator) {
var results = prepare_results(source),
index = results.indexOf(operator.operand);
return (index === -1) ? [] :
return (index < 0) ? [] :
(operator.suffix) ? results.slice(0, index + 1) :
results.slice(0, index);
};

View File

@@ -1,143 +0,0 @@
/*\
title: $:/core/modules/indexers/field-indexer.js
type: application/javascript
module-type: indexer
Indexes the tiddlers with each field value
\*/
(function(){
/*jslint node: true, browser: true */
/*global modules: false */
"use strict";
var DEFAULT_MAXIMUM_INDEXED_VALUE_LENGTH = 128;
function FieldIndexer(wiki) {
this.wiki = wiki;
}
FieldIndexer.prototype.init = function() {
this.index = null;
this.maxIndexedValueLength = DEFAULT_MAXIMUM_INDEXED_VALUE_LENGTH;
this.addIndexMethods();
}
// Provided for testing
FieldIndexer.prototype.setMaxIndexedValueLength = function(length) {
this.index = null;
this.maxIndexedValueLength = length;
};
FieldIndexer.prototype.addIndexMethods = function() {
var self = this;
this.wiki.each.byField = function(name,value) {
var titles = self.wiki.allTitles(),
lookup = self.lookup(name,value);
return lookup && lookup.filter(function(title) {
return titles.indexOf(title) !== -1;
});
};
this.wiki.eachShadow.byField = function(name,value) {
var titles = self.wiki.allShadowTitles(),
lookup = self.lookup(name,value);
return lookup && lookup.filter(function(title) {
return titles.indexOf(title) !== -1;
});
};
this.wiki.eachTiddlerPlusShadows.byField = function(name,value) {
var lookup = self.lookup(name,value);
return lookup ? lookup.slice(0) : null;
};
this.wiki.eachShadowPlusTiddlers.byField = function(name,value) {
var lookup = self.lookup(name,value);
return lookup ? lookup.slice(0) : null;
};
};
/*
Tear down and then rebuild the index as if all tiddlers have changed
*/
FieldIndexer.prototype.rebuild = function() {
// Invalidate the index so that it will be rebuilt when it is next used
this.index = null;
};
/*
Build the index for a particular field
*/
FieldIndexer.prototype.buildIndexForField = function(name) {
var self = this;
// Hashmap by field name of hashmap by field value of array of tiddler titles
this.index = this.index || Object.create(null);
this.index[name] = Object.create(null);
var baseIndex = this.index[name];
// Update the index for each tiddler
this.wiki.eachTiddlerPlusShadows(function(tiddler,title) {
if(name in tiddler.fields) {
var value = tiddler.getFieldString(name);
// Skip any values above the maximum length
if(value.length < self.maxIndexedValueLength) {
baseIndex[value] = baseIndex[value] || [];
baseIndex[value].push(title);
}
}
});
};
/*
Update the index in the light of a tiddler value changing; note that the title must be identical. (Renames are handled as a separate delete and create)
updateDescriptor: {old: {tiddler: <tiddler>, shadow: <boolean>, exists: <boolean>},new: {tiddler: <tiddler>, shadow: <boolean>, exists: <boolean>}}
*/
FieldIndexer.prototype.update = function(updateDescriptor) {
var self = this;
// Don't do anything if the index hasn't been built yet
if(this.index === null) {
return;
}
// Remove the old tiddler from the index
if(updateDescriptor.old.tiddler) {
$tw.utils.each(this.index,function(indexEntry,name) {
if(name in updateDescriptor.old.tiddler.fields) {
var value = updateDescriptor.old.tiddler.getFieldString(name),
tiddlerList = indexEntry[value];
if(tiddlerList) {
var index = tiddlerList.indexOf(updateDescriptor.old.tiddler.fields.title);
if(index !== -1) {
tiddlerList.splice(index,1);
}
}
}
});
}
// Add the new tiddler to the index
if(updateDescriptor["new"].tiddler) {
$tw.utils.each(this.index,function(indexEntry,name) {
if(name in updateDescriptor["new"].tiddler.fields) {
var value = updateDescriptor["new"].tiddler.getFieldString(name);
if(value.length < self.maxIndexedValueLength) {
indexEntry[value] = indexEntry[value] || [];
indexEntry[value].push(updateDescriptor["new"].tiddler.fields.title);
}
}
});
}
};
// Lookup the given field returning a list of tiddler titles
FieldIndexer.prototype.lookup = function(name,value) {
// Fail the lookup if the value is too long
if(value.length >= this.maxIndexedValueLength) {
return null;
}
// Update the index if it has yet to be built
if(this.index === null || !this.index[name]) {
this.buildIndexForField(name);
}
return this.index[name][value] || [];
};
exports.FieldIndexer = FieldIndexer;
})();

View File

@@ -1,98 +0,0 @@
/*\
title: $:/core/modules/indexers/tag-indexer.js
type: application/javascript
module-type: indexer
Indexes the tiddlers with each tag
\*/
(function(){
/*jslint node: true, browser: true */
/*global modules: false */
"use strict";
function TagIndexer(wiki) {
this.wiki = wiki;
}
TagIndexer.prototype.init = function() {
this.subIndexers = [
new TagSubIndexer(this,"each"),
new TagSubIndexer(this,"eachShadow"),
new TagSubIndexer(this,"eachTiddlerPlusShadows"),
new TagSubIndexer(this,"eachShadowPlusTiddlers")
];
$tw.utils.each(this.subIndexers,function(subIndexer) {
subIndexer.addIndexMethod();
});
};
TagIndexer.prototype.rebuild = function() {
$tw.utils.each(this.subIndexers,function(subIndexer) {
subIndexer.rebuild();
});
};
TagIndexer.prototype.update = function(updateDescriptor) {
$tw.utils.each(this.subIndexers,function(subIndexer) {
subIndexer.update(updateDescriptor);
});
};
function TagSubIndexer(indexer,iteratorMethod) {
this.indexer = indexer;
this.iteratorMethod = iteratorMethod;
this.index = null; // Hashmap of tag title to {isSorted: bool, titles: [array]} or null if not yet initialised
}
TagSubIndexer.prototype.addIndexMethod = function() {
var self = this;
this.indexer.wiki[this.iteratorMethod].byTag = function(tag) {
return self.lookup(tag).slice(0);
};
};
TagSubIndexer.prototype.rebuild = function() {
var self = this;
// Hashmap by tag of array of {isSorted:, titles:[]}
this.index = Object.create(null);
// Add all the tags
this.indexer.wiki[this.iteratorMethod](function(tiddler,title) {
$tw.utils.each(tiddler.fields.tags,function(tag) {
if(!self.index[tag]) {
self.index[tag] = {isSorted: false, titles: [title]};
} else {
self.index[tag].titles.push(title);
}
});
});
};
TagSubIndexer.prototype.update = function(updateDescriptor) {
this.index = null;
};
TagSubIndexer.prototype.lookup = function(tag) {
// Update the index if it has yet to be built
if(this.index === null) {
this.rebuild();
}
var indexRecord = this.index[tag];
if(indexRecord) {
if(!indexRecord.isSorted) {
if(this.indexer.wiki.sortByList) {
indexRecord.titles = this.indexer.wiki.sortByList(indexRecord.titles,tag);
}
indexRecord.isSorted = true;
}
return indexRecord.titles;
} else {
return [];
}
};
exports.TagIndexer = TagIndexer;
})();

View File

@@ -0,0 +1,41 @@
/*\
title: $:/core/modules/macros/dumpvariables.js
type: application/javascript
module-type: macro
Macro to dump all active variable values
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Information about this macro
*/
exports.name = "dumpvariables";
exports.params = [
];
/*
Run the macro
*/
exports.run = function() {
var output = ["|!Variable |!Value |"],
variables = [], variable;
for(variable in this.variables) {
variables.push(variable);
}
variables.sort();
for(var index=0; index<variables.length; index++) {
var variable = variables[index];
output.push("|" + variable + " |<input size=50 value=<<" + variable + ">>/> |")
}
return output.join("\n");
};
})();

View File

@@ -0,0 +1,13 @@
title: $:/core/macros/shortcuts/prettylink
tags: $:/tags/Macro
\define x-tm-prettylink-internal(to,text)
<$link to=<<__to__>>><$text text=<<__text__>>/></$link>
\end
\define tm-prettylink-internal(to,text)
<$button>
<$action-navigate $to=<<__to__>>/>
<$text text=<<__text__>>/>
</$button>
\end

View File

@@ -49,13 +49,12 @@ exports.parse = function() {
}];
} else {
return [{
type: "link",
attributes: {
to: {type: "string", value: link}
},
children: [{
type: "text", text: text
}]
type: "macrocall",
name: "tm-prettylink-internal",
params: [
{name: "to", value: link},
{name: "text", value: text}
]
}];
}
};

View File

@@ -27,6 +27,8 @@ exports.init = function(parser) {
};
exports.parse = function() {
// Move past the match
this.parser.pos = this.matchRegExp.lastIndex;
// Move past the match
this.parser.pos = this.matchRegExp.lastIndex;
// Get the match details

View File

@@ -1,118 +0,0 @@
/*\
title: $:/core/modules/savers/github.js
type: application/javascript
module-type: saver
Saves wiki by pushing a commit to the GitHub v3 REST API
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Select the appropriate saver module and set it up
*/
var GitHubSaver = function(wiki) {
this.wiki = wiki;
};
GitHubSaver.prototype.save = function(text,method,callback) {
var self = this,
username = this.wiki.getTiddlerText("$:/GitHub/Username"),
password = $tw.utils.getPassword("github"),
repo = this.wiki.getTiddlerText("$:/GitHub/Repo"),
path = this.wiki.getTiddlerText("$:/GitHub/Path"),
filename = this.wiki.getTiddlerText("$:/GitHub/Filename"),
branch = this.wiki.getTiddlerText("$:/GitHub/Branch") || "master",
endpoint = this.wiki.getTiddlerText("$:/GitHub/ServerURL") || "https://api.github.com",
headers = {
"Accept": "application/vnd.github.v3+json",
"Content-Type": "application/json;charset=UTF-8",
"Authorization": "Basic " + window.btoa(username + ":" + password)
};
// Bail if we don't have everything we need
if(!username || !password || !repo || !path || !filename) {
return false;
}
// Make sure the path start and ends with a slash
if(path.substring(0,1) !== "/") {
path = "/" + path;
}
if(path.substring(path.length - 1) !== "/") {
path = path + "/";
}
// Compose the base URI
var uri = endpoint + "/repos/" + repo + "/contents" + path;
// Perform a get request to get the details (inc shas) of files in the same path as our file
$tw.utils.httpRequest({
url: uri,
type: "GET",
headers: headers,
data: {
ref: branch
},
callback: function(err,getResponseDataJson,xhr) {
var getResponseData,sha = "";
if(err && xhr.status !== 404) {
return callback(err);
}
if(xhr.status !== 404) {
getResponseData = JSON.parse(getResponseDataJson);
$tw.utils.each(getResponseData,function(details) {
if(details.name === filename) {
sha = details.sha;
}
});
}
var data = {
message: $tw.language.getRawString("ControlPanel/Saving/GitService/CommitMessage"),
content: $tw.utils.base64Encode(text),
branch: branch,
sha: sha
};
// Perform a PUT request to save the file
$tw.utils.httpRequest({
url: uri + filename,
type: "PUT",
headers: headers,
data: JSON.stringify(data),
callback: function(err,putResponseDataJson,xhr) {
if(err) {
return callback(err);
}
var putResponseData = JSON.parse(putResponseDataJson);
callback(null);
}
});
}
});
return true;
};
/*
Information about this saver
*/
GitHubSaver.prototype.info = {
name: "github",
priority: 2000,
capabilities: ["save", "autosave"]
};
/*
Static method that returns true if this saver is capable of working
*/
exports.canSave = function(wiki) {
return true;
};
/*
Create an instance of this saver
*/
exports.create = function(wiki) {
return new GitHubSaver(wiki);
};
})();

View File

@@ -1,120 +0,0 @@
/*\
title: $:/core/modules/savers/gitlab.js
type: application/javascript
module-type: saver
Saves wiki by pushing a commit to the GitLab REST API
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: true */
"use strict";
/*
Select the appropriate saver module and set it up
*/
var GitLabSaver = function(wiki) {
this.wiki = wiki;
};
GitLabSaver.prototype.save = function(text,method,callback) {
/* See https://docs.gitlab.com/ee/api/repository_files.html */
var self = this,
username = this.wiki.getTiddlerText("$:/GitLab/Username"),
password = $tw.utils.getPassword("gitlab"),
repo = this.wiki.getTiddlerText("$:/GitLab/Repo"),
path = this.wiki.getTiddlerText("$:/GitLab/Path"),
filename = this.wiki.getTiddlerText("$:/GitLab/Filename"),
branch = this.wiki.getTiddlerText("$:/GitLab/Branch") || "master",
endpoint = this.wiki.getTiddlerText("$:/GitLab/ServerURL") || "https://gitlab.com/api/v4",
headers = {
"Content-Type": "application/json;charset=UTF-8",
"Private-Token": password
};
// Bail if we don't have everything we need
if(!username || !password || !repo || !path || !filename) {
return false;
}
// Make sure the path start and ends with a slash
if(path.substring(0,1) !== "/") {
path = "/" + path;
}
if(path.substring(path.length - 1) !== "/") {
path = path + "/";
}
// Compose the base URI
var uri = endpoint + "/projects/" + encodeURIComponent(repo) + "/repository/";
// Perform a get request to get the details (inc shas) of files in the same path as our file
$tw.utils.httpRequest({
url: uri + "tree/" + encodeURIComponent(path.replace(/^\/+|\/$/g, '')),
type: "GET",
headers: headers,
data: {
ref: branch
},
callback: function(err,getResponseDataJson,xhr) {
var getResponseData,sha = "";
if(err && xhr.status !== 404) {
return callback(err);
}
var requestType = "POST";
if(xhr.status !== 404) {
getResponseData = JSON.parse(getResponseDataJson);
$tw.utils.each(getResponseData,function(details) {
if(details.name === filename) {
requestType = "PUT";
sha = details.sha;
}
});
}
var data = {
commit_message: $tw.language.getRawString("ControlPanel/Saving/GitService/CommitMessage"),
content: text,
branch: branch,
sha: sha
};
// Perform a request to save the file
$tw.utils.httpRequest({
url: uri + "files/" + encodeURIComponent(path.replace(/^\/+/, '') + filename),
type: requestType,
headers: headers,
data: JSON.stringify(data),
callback: function(err,putResponseDataJson,xhr) {
if(err) {
return callback(err);
}
var putResponseData = JSON.parse(putResponseDataJson);
callback(null);
}
});
}
});
return true;
};
/*
Information about this saver
*/
GitLabSaver.prototype.info = {
name: "gitlab",
priority: 2000,
capabilities: ["save", "autosave"]
};
/*
Static method that returns true if this saver is capable of working
*/
exports.canSave = function(wiki) {
return true;
};
/*
Create an instance of this saver
*/
exports.create = function(wiki) {
return new GitLabSaver(wiki);
};
})();

View File

@@ -41,7 +41,7 @@ BasicAuthenticator.prototype.init = function() {
this.credentialsData = credentialsData;
}
} else {
return "Error: Unable to load user credentials from '" + resolveCredentialsFilepath + "'";
return "Error: Unable to load user credentials from '" + credentialsFilepath + "'";
}
}
// Add the hardcoded username and password if specified

View File

@@ -12,21 +12,22 @@ GET /
/*global $tw: false */
"use strict";
var zlib = require("zlib");
var zlib = require('zlib');
exports.method = "GET";
exports.path = /^\/$/;
exports.handler = function(request,response,state) {
var acceptEncoding = request.headers["accept-encoding"];
if(!acceptEncoding) {
acceptEncoding = "";
}
var text = state.wiki.renderTiddler(state.server.get("root-render-type"),state.server.get("root-tiddler")),
responseHeaders = {
var acceptEncoding = request.headers['accept-encoding'];
if (!acceptEncoding) { acceptEncoding = ''; }
var text = state.wiki.renderTiddler(state.server.get("root-render-type"),state.server.get("root-tiddler"));
var responseHeaders = {
"Content-Type": state.server.get("root-serve-type")
};
/*
If the gzip=yes flag for `listen` is set, check if the user agent permits
compression. If so, compress our response. Note that we use the synchronous
@@ -35,14 +36,15 @@ exports.handler = function(request,response,state) {
*/
if(state.server.enableGzip) {
if (/\bdeflate\b/.test(acceptEncoding)) {
responseHeaders["Content-Encoding"] = "deflate";
responseHeaders['Content-Encoding'] = 'deflate';
text = zlib.deflateSync(text);
} else if (/\bgzip\b/.test(acceptEncoding)) {
responseHeaders["Content-Encoding"] = "gzip";
responseHeaders['Content-Encoding'] = 'gzip';
text = zlib.gzipSync(text);
}
}
response.writeHead(200,responseHeaders);
response.writeHead(200, responseHeaders);
response.end(text);
};

View File

@@ -144,9 +144,9 @@ exports.startup = function() {
});
// Listen for window messages from other windows
window.addEventListener("message",function listener(event){
// console.log("browser-messaging: ",document.location.toString())
// console.log("browser-messaging: Received message from",event.origin);
// console.log("browser-messaging: Message content",event.data);
console.log("browser-messaging: ",document.location.toString())
console.log("browser-messaging: Received message from",event.origin);
console.log("browser-messaging: Message content",event.data);
switch(event.data.verb) {
case "GET-RESPONSE":
if(event.data.status.charAt(0) === "2") {

View File

@@ -1,114 +0,0 @@
/*\
title: $:/core/modules/startup/CSSescape.js
type: application/javascript
module-type: startup
Polyfill for CSS.escape()
\*/
(function(root,factory){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
// Export name and synchronous status
exports.name = "css-escape";
exports.platforms = ["browser"];
exports.after = ["startup"];
exports.synchronous = true;
/*! https://mths.be/cssescape v1.5.1 by @mathias | MIT license */
// https://github.com/umdjs/umd/blob/master/returnExports.js
exports.startup = factory(root);
}(typeof global != 'undefined' ? global : this, function(root) {
if (root.CSS && root.CSS.escape) {
return;
}
// https://drafts.csswg.org/cssom/#serialize-an-identifier
var cssEscape = function(value) {
if (arguments.length == 0) {
throw new TypeError('`CSS.escape` requires an argument.');
}
var string = String(value);
var length = string.length;
var index = -1;
var codeUnit;
var result = '';
var firstCodeUnit = string.charCodeAt(0);
while (++index < length) {
codeUnit = string.charCodeAt(index);
// Note: theres no need to special-case astral symbols, surrogate
// pairs, or lone surrogates.
// If the character is NULL (U+0000), then the REPLACEMENT CHARACTER
// (U+FFFD).
if (codeUnit == 0x0000) {
result += '\uFFFD';
continue;
}
if (
// If the character is in the range [\1-\1F] (U+0001 to U+001F) or is
// U+007F, […]
(codeUnit >= 0x0001 && codeUnit <= 0x001F) || codeUnit == 0x007F ||
// If the character is the first character and is in the range [0-9]
// (U+0030 to U+0039), […]
(index == 0 && codeUnit >= 0x0030 && codeUnit <= 0x0039) ||
// If the character is the second character and is in the range [0-9]
// (U+0030 to U+0039) and the first character is a `-` (U+002D), […]
(
index == 1 &&
codeUnit >= 0x0030 && codeUnit <= 0x0039 &&
firstCodeUnit == 0x002D
)
) {
// https://drafts.csswg.org/cssom/#escape-a-character-as-code-point
result += '\\' + codeUnit.toString(16) + ' ';
continue;
}
if (
// If the character is the first character and is a `-` (U+002D), and
// there is no second character, […]
index == 0 &&
length == 1 &&
codeUnit == 0x002D
) {
result += '\\' + string.charAt(index);
continue;
}
// If the character is not handled by one of the above rules and is
// greater than or equal to U+0080, is `-` (U+002D) or `_` (U+005F), or
// is in one of the ranges [0-9] (U+0030 to U+0039), [A-Z] (U+0041 to
// U+005A), or [a-z] (U+0061 to U+007A), […]
if (
codeUnit >= 0x0080 ||
codeUnit == 0x002D ||
codeUnit == 0x005F ||
codeUnit >= 0x0030 && codeUnit <= 0x0039 ||
codeUnit >= 0x0041 && codeUnit <= 0x005A ||
codeUnit >= 0x0061 && codeUnit <= 0x007A
) {
// the character itself
result += string.charAt(index);
continue;
}
// Otherwise, the escaped character.
// https://drafts.csswg.org/cssom/#escape-a-character
result += '\\' + string.charAt(index);
}
return result;
};
if (!root.CSS) {
root.CSS = {};
}
root.CSS.escape = cssEscape;
}));

View File

@@ -27,7 +27,6 @@ exports.startup = function() {
$tw.Tiddler.fieldModules = $tw.modules.getModulesByTypeAsHashmap("tiddlerfield");
$tw.modules.applyMethods("tiddlermethod",$tw.Tiddler.prototype);
$tw.modules.applyMethods("wikimethod",$tw.Wiki.prototype);
$tw.wiki.addIndexersToWiki();
$tw.modules.applyMethods("tiddlerdeserializer",$tw.Wiki.tiddlerDeserializerModules);
$tw.macros = $tw.modules.getModulesByTypeAsHashmap("macro");
$tw.wiki.initParsers();

View File

@@ -34,19 +34,6 @@ exports.startup = function() {
$tw.rootWidget.addEventListener("tm-copy-to-clipboard",function(event) {
$tw.utils.copyToClipboard(event.param);
});
// Install the tm-focus-selector message
$tw.rootWidget.addEventListener("tm-focus-selector",function(event) {
var selector = event.param || "",
element;
try {
element = document.querySelector(selector);
} catch(e) {
console.log("Error in selector: ",selector)
}
if(element && element.focus) {
element.focus(event.paramObject);
}
});
// Install the scroller
$tw.pageScroller = new $tw.utils.PageScroller();
$tw.rootWidget.addEventListener("tm-scroll",function(event) {

View File

@@ -28,7 +28,6 @@ exports.startup = function() {
var refreshHandler,
title = event.param || event.tiddlerTitle,
paramObject = event.paramObject || {},
windowTitle = paramObject.windowTitle || title,
template = paramObject.template || "$:/core/templates/single.tiddler.window",
width = paramObject.width || "700",
height = paramObject.height || "600",
@@ -52,7 +51,7 @@ exports.startup = function() {
// Initialise the document
srcDocument.write("<html><head></head><body class='tc-body tc-single-tiddler-window'></body></html>");
srcDocument.close();
srcDocument.title = windowTitle;
srcDocument.title = title;
srcWindow.addEventListener("beforeunload",function(event) {
delete windows[title];
$tw.wiki.removeEventListener("change",refreshHandler);

View File

@@ -19,7 +19,6 @@ var ClassicStoryView = function(listWidget) {
};
ClassicStoryView.prototype.navigateTo = function(historyInfo) {
var duration = $tw.utils.getAnimationDuration()
var listElementIndex = this.listWidget.findListItem(0,historyInfo.title);
if(listElementIndex === undefined) {
return;
@@ -30,90 +29,80 @@ ClassicStoryView.prototype.navigateTo = function(historyInfo) {
if(!(targetElement instanceof Element)) {
return;
}
if(duration) {
// Scroll the node into view
this.listWidget.dispatchEvent({type: "tm-scroll", target: targetElement});
} else {
targetElement.scrollIntoView();
}
// Scroll the node into view
this.listWidget.dispatchEvent({type: "tm-scroll", target: targetElement});
};
ClassicStoryView.prototype.insert = function(widget) {
var duration = $tw.utils.getAnimationDuration();
if(duration) {
var targetElement = widget.findFirstDomNode();
// Abandon if the list entry isn't a DOM element (it might be a text node)
if(!(targetElement instanceof Element)) {
return;
}
// Get the current height of the tiddler
var computedStyle = window.getComputedStyle(targetElement),
currMarginBottom = parseInt(computedStyle.marginBottom,10),
currMarginTop = parseInt(computedStyle.marginTop,10),
currHeight = targetElement.offsetHeight + currMarginTop;
// Reset the margin once the transition is over
setTimeout(function() {
$tw.utils.setStyle(targetElement,[
{transition: "none"},
{marginBottom: ""}
]);
},duration);
// Set up the initial position of the element
var targetElement = widget.findFirstDomNode(),
duration = $tw.utils.getAnimationDuration();
// Abandon if the list entry isn't a DOM element (it might be a text node)
if(!(targetElement instanceof Element)) {
return;
}
// Get the current height of the tiddler
var computedStyle = window.getComputedStyle(targetElement),
currMarginBottom = parseInt(computedStyle.marginBottom,10),
currMarginTop = parseInt(computedStyle.marginTop,10),
currHeight = targetElement.offsetHeight + currMarginTop;
// Reset the margin once the transition is over
setTimeout(function() {
$tw.utils.setStyle(targetElement,[
{transition: "none"},
{marginBottom: (-currHeight) + "px"},
{opacity: "0.0"}
{marginBottom: ""}
]);
$tw.utils.forceLayout(targetElement);
// Transition to the final position
$tw.utils.setStyle(targetElement,[
{transition: "opacity " + duration + "ms " + easing + ", " +
"margin-bottom " + duration + "ms " + easing},
{marginBottom: currMarginBottom + "px"},
{opacity: "1.0"}
},duration);
// Set up the initial position of the element
$tw.utils.setStyle(targetElement,[
{transition: "none"},
{marginBottom: (-currHeight) + "px"},
{opacity: "0.0"}
]);
$tw.utils.forceLayout(targetElement);
// Transition to the final position
$tw.utils.setStyle(targetElement,[
{transition: "opacity " + duration + "ms " + easing + ", " +
"margin-bottom " + duration + "ms " + easing},
{marginBottom: currMarginBottom + "px"},
{opacity: "1.0"}
]);
}
};
ClassicStoryView.prototype.remove = function(widget) {
var duration = $tw.utils.getAnimationDuration();
if(duration) {
var targetElement = widget.findFirstDomNode(),
removeElement = function() {
widget.removeChildDomNodes();
};
// Abandon if the list entry isn't a DOM element (it might be a text node)
if(!(targetElement instanceof Element)) {
removeElement();
return;
}
// Get the current height of the tiddler
var currWidth = targetElement.offsetWidth,
computedStyle = window.getComputedStyle(targetElement),
currMarginBottom = parseInt(computedStyle.marginBottom,10),
currMarginTop = parseInt(computedStyle.marginTop,10),
currHeight = targetElement.offsetHeight + currMarginTop;
// Remove the dom nodes of the widget at the end of the transition
setTimeout(removeElement,duration);
// Animate the closure
$tw.utils.setStyle(targetElement,[
{transition: "none"},
{transform: "translateX(0px)"},
{marginBottom: currMarginBottom + "px"},
{opacity: "1.0"}
]);
$tw.utils.forceLayout(targetElement);
$tw.utils.setStyle(targetElement,[
{transition: $tw.utils.roundTripPropertyName("transform") + " " + duration + "ms " + easing + ", " +
"opacity " + duration + "ms " + easing + ", " +
"margin-bottom " + duration + "ms " + easing},
{transform: "translateX(-" + currWidth + "px)"},
{marginBottom: (-currHeight) + "px"},
{opacity: "0.0"}
]);
} else {
widget.removeChildDomNodes();
var targetElement = widget.findFirstDomNode(),
duration = $tw.utils.getAnimationDuration(),
removeElement = function() {
widget.removeChildDomNodes();
};
// Abandon if the list entry isn't a DOM element (it might be a text node)
if(!(targetElement instanceof Element)) {
removeElement();
return;
}
// Get the current height of the tiddler
var currWidth = targetElement.offsetWidth,
computedStyle = window.getComputedStyle(targetElement),
currMarginBottom = parseInt(computedStyle.marginBottom,10),
currMarginTop = parseInt(computedStyle.marginTop,10),
currHeight = targetElement.offsetHeight + currMarginTop;
// Remove the dom nodes of the widget at the end of the transition
setTimeout(removeElement,duration);
// Animate the closure
$tw.utils.setStyle(targetElement,[
{transition: "none"},
{transform: "translateX(0px)"},
{marginBottom: currMarginBottom + "px"},
{opacity: "1.0"}
]);
$tw.utils.forceLayout(targetElement);
$tw.utils.setStyle(targetElement,[
{transition: $tw.utils.roundTripPropertyName("transform") + " " + duration + "ms " + easing + ", " +
"opacity " + duration + "ms " + easing + ", " +
"margin-bottom " + duration + "ms " + easing},
{transform: "translateX(-" + currWidth + "px)"},
{marginBottom: (-currHeight) + "px"},
{opacity: "0.0"}
]);
};
exports.classic = ClassicStoryView;

View File

@@ -44,14 +44,7 @@ PopStoryView.prototype.insert = function(widget) {
{transition: "none"},
{transform: "none"}
]);
$tw.utils.setStyle(widget.document.body,[
{"overflow-x": ""}
]);
},duration);
// Prevent the page from overscrolling due to the zoom factor
$tw.utils.setStyle(widget.document.body,[
{"overflow-x": "hidden"}
]);
// Set up the initial position of the element
$tw.utils.setStyle(targetElement,[
{transition: "none"},
@@ -72,7 +65,7 @@ PopStoryView.prototype.remove = function(widget) {
var targetElement = widget.findFirstDomNode(),
duration = $tw.utils.getAnimationDuration(),
removeElement = function() {
if(targetElement && targetElement.parentNode) {
if(targetElement.parentNode) {
widget.removeChildDomNodes();
}
};

View File

@@ -75,16 +75,16 @@ Get all the fields as a name:value block. Options:
*/
exports.getFieldStringBlock = function(options) {
options = options || {};
var exclude = options.exclude || [],
fields = Object.keys(this.fields).sort(),
result = [];
for(var t=0; t<fields.length; t++) {
var field = fields[t];
if(exclude.indexOf(field) === -1) {
result.push(field + ": " + this.getFieldString(field));
var exclude = options.exclude || [];
var fields = [];
for(var field in this.fields) {
if($tw.utils.hop(this.fields,field)) {
if(exclude.indexOf(field) === -1) {
fields.push(field + ": " + this.getFieldString(field));
}
}
}
return result.join("\n");
return fields.join("\n");
};
exports.getFieldDay = function(field) {

View File

@@ -35,17 +35,17 @@ exports.upgrade = function(wiki,titles,tiddlers) {
}
for(var t=0; t<WARN_IMPORT_PREFIX_LIST.length; t++) {
var prefix = WARN_IMPORT_PREFIX_LIST[t];
if(title.substr(0,prefix.length) === prefix && wiki.isShadowTiddler(title)) {
if(title.substr(0,prefix.length) === prefix) {
showAlert = true;
messages[title] = $tw.language.getString("Import/Upgrader/System/Warning");
}
}
}
if(showAlert) {
var logger = new $tw.utils.Logger("import");
logger.alert($tw.language.getString("Import/Upgrader/System/Alert"));
}
});
if(showAlert) {
var logger = new $tw.utils.Logger("import");
logger.alert($tw.language.getString("Import/Upgrader/System/Alert"));
}
return messages;
};

View File

@@ -1,124 +0,0 @@
// From https://gist.github.com/Nijikokun/5192472
//
// UTF8 Module
//
// Cleaner and modularized utf-8 encoding and decoding library for javascript.
//
// copyright: MIT
// author: Nijiko Yonskai, @nijikokun, nijikokun@gmail.com
(function (name, definition, context, dependencies) {
if (typeof context['module'] !== 'undefined' && context['module']['exports']) { if (dependencies && context['require']) { for (var i = 0; i < dependencies.length; i++) context[dependencies[i]] = context['require'](dependencies[i]); } context['module']['exports'] = definition.apply(context); }
else if (typeof context['define'] !== 'undefined' && context['define'] === 'function' && context['define']['amd']) { define(name, (dependencies || []), definition); }
else { context[name] = definition.apply(context); }
})('utf8', function () {
return {
encode: function (string) {
if (typeof string !== 'string') return string;
else string = string.replace(/\r\n/g, "\n");
var output = "", i = 0, charCode;
for (i; i < string.length; i++) {
charCode = string.charCodeAt(i);
if (charCode < 128)
output += String.fromCharCode(charCode);
else if ((charCode > 127) && (charCode < 2048))
output += String.fromCharCode((charCode >> 6) | 192),
output += String.fromCharCode((charCode & 63) | 128);
else
output += String.fromCharCode((charCode >> 12) | 224),
output += String.fromCharCode(((charCode >> 6) & 63) | 128),
output += String.fromCharCode((charCode & 63) | 128);
}
return output;
},
decode: function (string) {
if (typeof string !== 'string') return string;
var output = "", i = 0, charCode = 0;
while (i < string.length) {
charCode = string.charCodeAt(i);
if (charCode < 128)
output += String.fromCharCode(charCode),
i++;
else if ((charCode > 191) && (charCode < 224))
output += String.fromCharCode(((charCode & 31) << 6) | (string.charCodeAt(i + 1) & 63)),
i += 2;
else
output += String.fromCharCode(((charCode & 15) << 12) | ((string.charCodeAt(i + 1) & 63) << 6) | (string.charCodeAt(i + 2) & 63)),
i += 3;
}
return output;
}
};
}, this);
// Base64 Module
//
// Cleaner, modularized and properly scoped base64 encoding and decoding module for strings.
//
// copyright: MIT
// author: Nijiko Yonskai, @nijikokun, nijikokun@gmail.com
(function (name, definition, context, dependencies) {
if (typeof context['module'] !== 'undefined' && context['module']['exports']) { if (dependencies && context['require']) { for (var i = 0; i < dependencies.length; i++) context[dependencies[i]] = context['require'](dependencies[i]); } context['module']['exports'] = definition.apply(context); }
else if (typeof context['define'] !== 'undefined' && context['define'] === 'function' && context['define']['amd']) { define(name, (dependencies || []), definition); }
else { context[name] = definition.apply(context); }
})('base64', function (utf8) {
var $this = this;
var $utf8 = utf8 || this.utf8;
var map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
return {
encode: function (input) {
if (typeof $utf8 === 'undefined') throw { error: "MissingMethod", message: "UTF8 Module is missing." };
if (typeof input !== 'string') return input;
else input = $utf8.encode(input);
var output = "", a, b, c, d, e, f, g, i = 0;
while (i < input.length) {
a = input.charCodeAt(i++);
b = input.charCodeAt(i++);
c = input.charCodeAt(i++);
d = a >> 2;
e = ((a & 3) << 4) | (b >> 4);
f = ((b & 15) << 2) | (c >> 6);
g = c & 63;
if (isNaN(b)) f = g = 64;
else if (isNaN(c)) g = 64;
output += map.charAt(d) + map.charAt(e) + map.charAt(f) + map.charAt(g);
}
return output;
},
decode: function (input) {
if (typeof $utf8 === 'undefined') throw { error: "MissingMethod", message: "UTF8 Module is missing." };
if (typeof input !== 'string') return input;
else input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
var output = "", a, b, c, d, e, f, g, i = 0;
while (i < input.length) {
d = map.indexOf(input.charAt(i++));
e = map.indexOf(input.charAt(i++));
f = map.indexOf(input.charAt(i++));
g = map.indexOf(input.charAt(i++));
a = (d << 2) | (e >> 4);
b = ((e & 15) << 4) | (f >> 2);
c = ((f & 3) << 6) | g;
output += String.fromCharCode(a);
if (f != 64) output += String.fromCharCode(b);
if (g != 64) output += String.fromCharCode(c);
}
return $utf8.decode(output);
}
}
}, this, [ "utf8" ]);

View File

@@ -1,9 +0,0 @@
// From https://gist.github.com/Nijikokun/5192472
//
// UTF8 Module
//
// Cleaner and modularized utf-8 encoding and decoding library for javascript.
//
// copyright: MIT
// author: Nijiko Yonskai, @nijikokun, nijikokun@gmail.com
!function(r,e,o,t){void 0!==o.module&&o.module.exports?o.module.exports=e.apply(o):void 0!==o.define&&"function"===o.define&&o.define.amd?define("utf8",[],e):o.utf8=e.apply(o)}(0,function(){return{encode:function(r){if("string"!=typeof r)return r;r=r.replace(/\r\n/g,"\n");for(var e,o="",t=0;t<r.length;t++)(e=r.charCodeAt(t))<128?o+=String.fromCharCode(e):e>127&&e<2048?(o+=String.fromCharCode(e>>6|192),o+=String.fromCharCode(63&e|128)):(o+=String.fromCharCode(e>>12|224),o+=String.fromCharCode(e>>6&63|128),o+=String.fromCharCode(63&e|128));return o},decode:function(r){if("string"!=typeof r)return r;for(var e="",o=0,t=0;o<r.length;)(t=r.charCodeAt(o))<128?(e+=String.fromCharCode(t),o++):t>191&&t<224?(e+=String.fromCharCode((31&t)<<6|63&r.charCodeAt(o+1)),o+=2):(e+=String.fromCharCode((15&t)<<12|(63&r.charCodeAt(o+1))<<6|63&r.charCodeAt(o+2)),o+=3);return e}}},this),function(r,e,o,t){if(void 0!==o.module&&o.module.exports){if(t&&o.require)for(var n=0;n<t.length;n++)o[t[n]]=o.require(t[n]);o.module.exports=e.apply(o)}else void 0!==o.define&&"function"===o.define&&o.define.amd?define("base64",t||[],e):o.base64=e.apply(o)}(0,function(r){var e=r||this.utf8,o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";return{encode:function(r){if(void 0===e)throw{error:"MissingMethod",message:"UTF8 Module is missing."};if("string"!=typeof r)return r;r=e.encode(r);for(var t,n,i,d,f,a,h,c="",u=0;u<r.length;)d=(t=r.charCodeAt(u++))>>2,f=(3&t)<<4|(n=r.charCodeAt(u++))>>4,a=(15&n)<<2|(i=r.charCodeAt(u++))>>6,h=63&i,isNaN(n)?a=h=64:isNaN(i)&&(h=64),c+=o.charAt(d)+o.charAt(f)+o.charAt(a)+o.charAt(h);return c},decode:function(r){if(void 0===e)throw{error:"MissingMethod",message:"UTF8 Module is missing."};if("string"!=typeof r)return r;r=r.replace(/[^A-Za-z0-9\+\/\=]/g,"");for(var t,n,i,d,f,a,h="",c=0;c<r.length;)t=o.indexOf(r.charAt(c++))<<2|(d=o.indexOf(r.charAt(c++)))>>4,n=(15&d)<<4|(f=o.indexOf(r.charAt(c++)))>>2,i=(3&f)<<6|(a=o.indexOf(r.charAt(c++))),h+=String.fromCharCode(t),64!=f&&(h+=String.fromCharCode(n)),64!=a&&(h+=String.fromCharCode(i));return e.decode(h)}}},this,["utf8"]);

View File

@@ -1,14 +0,0 @@
{
"tiddlers": [
{
"file": "base64-utf8.module.min.js",
"fields": {
"type": "application/javascript",
"title": "$:/core/modules/utils/base64-utf8/base64-utf8.module.js",
"module-type": "library"
},
"prefix": "(function(){",
"suffix": "}).call(exports);"
}
]
}

View File

@@ -136,31 +136,22 @@ exports.getBoundingPageRect = function(element) {
Saves a named password in the browser
*/
exports.savePassword = function(name,password) {
var done = false;
try {
window.localStorage.setItem("tw5-password-" + name,password);
done = true;
if(window.localStorage) {
localStorage.setItem("tw5-password-" + name,password);
}
} catch(e) {
}
if(!done) {
$tw.savedPasswords = $tw.savedPasswords || Object.create(null);
$tw.savedPasswords[name] = password;
}
};
/*
Retrieve a named password from the browser
*/
exports.getPassword = function(name) {
var value;
try {
value = window.localStorage.getItem("tw5-password-" + name);
return window.localStorage ? localStorage.getItem("tw5-password-" + name) : "";
} catch(e) {
}
if(value !== undefined) {
return value;
} else {
return ($tw.savedPasswords || Object.create(null))[name] || "";
return "";
}
};

View File

@@ -17,7 +17,7 @@ A quick and dirty HTTP function; to be refactored later. Options are:
url: URL to retrieve
headers: hashmap of headers to send
type: GET, PUT, POST etc
callback: function invoked with (err,data,xhr)
callback: function invoked with (err,data)
returnProp: string name of the property to return as first argument of callback
*/
exports.httpRequest = function(options) {
@@ -48,7 +48,7 @@ exports.httpRequest = function(options) {
return;
}
// Something went wrong
options.callback($tw.language.getString("Error/XMLHttpRequest") + ": " + this.status,null,this);
options.callback($tw.language.getString("Error/XMLHttpRequest") + ": " + this.status);
}
};
// Make the request
@@ -67,7 +67,7 @@ exports.httpRequest = function(options) {
try {
request.send(data);
} catch(e) {
options.callback(e,null,this);
options.callback(e);
}
return request;
};

View File

@@ -120,8 +120,7 @@ Popup.prototype.show = function(options) {
this.popups.push({
title: options.title,
wiki: options.wiki,
domNode: options.domNode,
noStateReference: options.noStateReference
domNode: options.domNode
});
}
// Set the state tiddler
@@ -149,46 +148,17 @@ Popup.prototype.show = function(options) {
}
};
/*
Detect if a Popup contains an input field that has focus
Returns true or false
*/
Popup.prototype.detectInputWithinPopup = function(node) {
var withinPopup = false,
currNode = node;
for(var i=0; i<this.popups.length; i++) {
var popup = (this.popups[i] && this.popups[i].domNode) ? this.popups[i].domNode : null;
while(node && popup) {
if(node === popup || (node.classList && (node.classList.contains("tc-popup-keep") || (node !== currNode && node.classList.contains("tc-popup-handle"))))) {
withinPopup = true;
}
node = node.parentNode;
}
}
return withinPopup;
};
/*
Cancel all popups at or above a specified level or DOM node
level: popup level to cancel (0 cancels all popups)
*/
Popup.prototype.cancel = function(level,focusedInputNode) {
Popup.prototype.cancel = function(level) {
var numPopups = this.popups.length;
level = Math.max(0,Math.min(level,numPopups));
for(var t=level; t<numPopups; t++) {
var inputWithinPopup;
if(focusedInputNode) {
inputWithinPopup = this.detectInputWithinPopup(focusedInputNode);
}
if(!inputWithinPopup) {
var popup = this.popups.pop();
if(popup.title) {
if(popup.noStateReference) {
popup.wiki.deleteTiddler(popup.title);
} else {
popup.wiki.deleteTiddler($tw.utils.parseTextReference(popup.title).title);
}
}
var popup = this.popups.pop();
if(popup.title) {
popup.wiki.deleteTiddler(popup.title);
}
}
if(this.popups.length === 0) {

View File

@@ -181,169 +181,4 @@ exports.deleteEmptyDirs = function(dirpath,callback) {
});
};
/*
Create a fileInfo object for saving a tiddler:
filepath: the absolute path to the file containing the tiddler
type: the type of the tiddler file (NOT the type of the tiddler)
hasMetaFile: true if the file also has a companion .meta file
Options include:
directory: absolute path of root directory to which we are saving
pathFilters: optional array of filters to be used to generate the base path
wiki: optional wiki for evaluating the pathFilters
*/
exports.generateTiddlerFileInfo = function(tiddler,options) {
var fileInfo = {};
// Check if the tiddler has any unsafe fields that can't be expressed in a .tid or .meta file: containing control characters, or leading/trailing whitespace
var hasUnsafeFields = false;
$tw.utils.each(tiddler.getFieldStrings(),function(value,fieldName) {
if(fieldName !== "text") {
hasUnsafeFields = hasUnsafeFields || /[\x00-\x1F]/mg.test(value);
hasUnsafeFields = hasUnsafeFields || ($tw.utils.trim(value) !== value);
}
});
// Check for field values
if(hasUnsafeFields) {
// Save as a JSON file
fileInfo.type = "application/json";
fileInfo.hasMetaFile = false;
} else {
// Save as a .tid or a text/binary file plus a .meta file
var tiddlerType = tiddler.fields.type || "text/vnd.tiddlywiki";
if(tiddlerType === "text/vnd.tiddlywiki") {
// Save as a .tid file
fileInfo.type = "application/x-tiddler";
fileInfo.hasMetaFile = false;
} else {
// Save as a text/binary file and a .meta file
fileInfo.type = tiddlerType;
fileInfo.hasMetaFile = true;
}
}
// Take the file extension from the tiddler content type
var contentTypeInfo = $tw.config.contentTypeInfo[fileInfo.type] || {extension: ""};
// Generate the filepath
fileInfo.filepath = $tw.utils.generateTiddlerFilepath(tiddler.fields.title,{
extension: contentTypeInfo.extension,
directory: options.directory,
pathFilters: options.pathFilters,
wiki: options.wiki
});
return fileInfo;
};
/*
Generate the filepath for saving a tiddler
Options include:
extension: file extension to be added the finished filepath
directory: absolute path of root directory to which we are saving
pathFilters: optional array of filters to be used to generate the base path
wiki: optional wiki for evaluating the pathFilters
*/
exports.generateTiddlerFilepath = function(title,options) {
var self = this,
directory = options.directory || "",
extension = options.extension || "",
filepath;
// Check if any of the pathFilters applies
if(options.pathFilters && options.wiki) {
$tw.utils.each(options.pathFilters,function(filter) {
if(!filepath) {
var source = options.wiki.makeTiddlerIterator([title]),
result = options.wiki.filterTiddlers(filter,null,source);
if(result.length > 0) {
filepath = result[0];
}
}
});
}
// If not, generate a base pathname
if(!filepath) {
filepath = title;
// If the filepath already ends in the extension then remove it
if(filepath.substring(filepath.length - extension.length) === extension) {
filepath = filepath.substring(0,filepath.length - extension.length);
}
// Remove any forward or backward slashes so we don't create directories
filepath = filepath.replace(/\/|\\/g,"_");
}
// Don't let the filename start with a dot because such files are invisible on *nix
filepath = filepath.replace(/^\./g,"_");
// Remove any characters that can't be used in cross-platform filenames
filepath = $tw.utils.transliterate(filepath.replace(/<|>|\:|\"|\||\?|\*|\^/g,"_"));
// Truncate the filename if it is too long
if(filepath.length > 200) {
filepath = filepath.substr(0,200);
}
// If the resulting filename is blank (eg because the title is just punctuation characters)
if(!filepath) {
// ...then just use the character codes of the title
filepath = "";
$tw.utils.each(title.split(""),function(char) {
if(filepath) {
filepath += "-";
}
filepath += char.charCodeAt(0).toString();
});
}
// Add a uniquifier if the file already exists
var fullPath,
count = 0;
do {
fullPath = path.resolve(directory,filepath + (count ? "_" + count : "") + extension);
count++;
} while(fs.existsSync(fullPath));
// Return the full path to the file
return fullPath;
};
/*
Save a tiddler to a file described by the fileInfo:
filepath: the absolute path to the file containing the tiddler
type: the type of the tiddler file (NOT the type of the tiddler)
hasMetaFile: true if the file also has a companion .meta file
*/
exports.saveTiddlerToFile = function(tiddler,fileInfo,callback) {
$tw.utils.createDirectory(path.dirname(fileInfo.filepath));
if(fileInfo.hasMetaFile) {
// Save the tiddler as a separate body and meta file
var typeInfo = $tw.config.contentTypeInfo[tiddler.fields.type || "text/plain"] || {encoding: "utf8"};
fs.writeFile(fileInfo.filepath,tiddler.fields.text,typeInfo.encoding,function(err) {
if(err) {
return callback(err);
}
fs.writeFile(fileInfo.filepath + ".meta",tiddler.getFieldStringBlock({exclude: ["text","bag"]}),"utf8",callback);
});
} else {
// Save the tiddler as a self contained templated file
if(fileInfo.type === "application/x-tiddler") {
fs.writeFile(fileInfo.filepath,tiddler.getFieldStringBlock({exclude: ["text","bag"]}) + (!!tiddler.fields.text ? "\n\n" + tiddler.fields.text : ""),"utf8",callback);
} else {
fs.writeFile(fileInfo.filepath,JSON.stringify([tiddler.getFieldStrings({exclude: ["bag"]})],null,$tw.config.preferences.jsonSpaces),"utf8",callback);
}
}
};
/*
Save a tiddler to a file described by the fileInfo:
filepath: the absolute path to the file containing the tiddler
type: the type of the tiddler file (NOT the type of the tiddler)
hasMetaFile: true if the file also has a companion .meta file
*/
exports.saveTiddlerToFileSync = function(tiddler,fileInfo) {
$tw.utils.createDirectory(path.dirname(fileInfo.filepath));
if(fileInfo.hasMetaFile) {
// Save the tiddler as a separate body and meta file
var typeInfo = $tw.config.contentTypeInfo[tiddler.fields.type || "text/plain"] || {encoding: "utf8"};
fs.writeFileSync(fileInfo.filepath,tiddler.fields.text,typeInfo.encoding);
fs.writeFileSync(fileInfo.filepath + ".meta",tiddler.getFieldStringBlock({exclude: ["text","bag"]}),"utf8");
} else {
// Save the tiddler as a self contained templated file
if(fileInfo.type === "application/x-tiddler") {
fs.writeFileSync(fileInfo.filepath,tiddler.getFieldStringBlock({exclude: ["text","bag"]}) + (!!tiddler.fields.text ? "\n\n" + tiddler.fields.text : ""),"utf8");
} else {
fs.writeFileSync(fileInfo.filepath,JSON.stringify([tiddler.getFieldStrings({exclude: ["bag"]})],null,$tw.config.preferences.jsonSpaces),"utf8");
}
}
};
})();

View File

@@ -33,13 +33,6 @@ Logger.prototype.log = function(/* args */) {
}
};
/*
Log a structure as a table
*/
Logger.prototype.table = function(value) {
(console.table || console.log)(value);
};
/*
Alert a message
*/

View File

@@ -14,17 +14,10 @@ Performance measurement.
function Performance(enabled) {
this.enabled = !!enabled;
this.measures = {}; // Hashmap by measurement name of {time:, invocations:}
this.measures = {}; // Hashmap of current values of measurements
this.logger = new $tw.utils.Logger("performance");
this.showGreeting();
}
Performance.prototype.showGreeting = function() {
if($tw.browser) {
this.logger.log("Execute $tw.perf.log(); to see filter execution timings");
}
};
/*
Wrap performance reporting around a top level function
*/
@@ -32,9 +25,13 @@ Performance.prototype.report = function(name,fn) {
var self = this;
if(this.enabled) {
return function() {
self.measures = {};
var startTime = $tw.utils.timer(),
result = fn.apply(this,arguments);
self.logger.log(name + ": " + $tw.utils.timer(startTime).toFixed(2) + "ms");
for(var m in self.measures) {
self.logger.log("+" + m + ": " + self.measures[m].toFixed(2) + "ms");
}
return result;
};
} else {
@@ -42,29 +39,6 @@ Performance.prototype.report = function(name,fn) {
}
};
Performance.prototype.log = function() {
var self = this,
totalTime = 0,
orderedMeasures = Object.keys(this.measures).sort(function(a,b) {
if(self.measures[a].time > self.measures[b].time) {
return -1;
} else if (self.measures[a].time < self.measures[b].time) {
return + 1;
} else {
return 0;
}
});
$tw.utils.each(orderedMeasures,function(name) {
totalTime += self.measures[name].time;
});
var results = []
$tw.utils.each(orderedMeasures,function(name) {
var measure = self.measures[name];
results.push({name: name,invocations: measure.invocations, avgTime: measure.time / measure.invocations, totalTime: measure.time, percentTime: (measure.time / totalTime) * 100})
});
self.logger.table(results);
};
/*
Wrap performance measurements around a subfunction
*/
@@ -73,12 +47,9 @@ Performance.prototype.measure = function(name,fn) {
if(this.enabled) {
return function() {
var startTime = $tw.utils.timer(),
result = fn.apply(this,arguments);
if(!(name in self.measures)) {
self.measures[name] = {time: 0, invocations: 0};
}
self.measures[name].time += $tw.utils.timer(startTime);
self.measures[name].invocations++;
result = fn.apply(this,arguments),
value = self.measures[name] || 0;
self.measures[name] = value + $tw.utils.timer(startTime);
return result;
};
} else {

View File

@@ -12,8 +12,6 @@ Various static utility functions.
/*global $tw: false */
"use strict";
var base64utf8 = require("$:/core/modules/utils/base64-utf8/base64-utf8.module.js");
/*
Display a message, in colour if we're on a terminal
*/
@@ -94,20 +92,6 @@ exports.trim = function(str) {
}
};
/*
Convert a string to sentence case (ie capitalise first letter)
*/
exports.toSentenceCase = function(str) {
return (str || "").replace(/^\S/, function(c) {return c.toUpperCase();});
}
/*
Convert a string to title case (ie capitalise each initial letter)
*/
exports.toTitleCase = function(str) {
return (str || "").replace(/(^|\s)\S/g, function(c) {return c.toUpperCase();});
}
/*
Find the line break preceding a given position in a string
Returns position immediately after that line break, or the start of the string
@@ -685,14 +669,12 @@ exports.hashString = function(str) {
Decode a base64 string
*/
exports.base64Decode = function(string64) {
return base64utf8.base64.decode.call(base64utf8,string64);
};
/*
Encode a string to base64
*/
exports.base64Encode = function(string64) {
return base64utf8.base64.encode.call(base64utf8,string64);
if($tw.browser) {
// TODO
throw "$tw.utils.base64Decode() doesn't work in the browser";
} else {
return Buffer.from(string64,"base64").toString();
}
};
/*

View File

@@ -37,7 +37,6 @@ Compute the internal state of the widget
CreateTiddlerWidget.prototype.execute = function() {
this.actionBaseTitle = this.getAttribute("$basetitle");
this.actionSaveTitle = this.getAttribute("$savetitle");
this.actionSaveDraftTitle = this.getAttribute("$savedrafttitle");
this.actionTimestamp = this.getAttribute("$timestamp","yes") === "yes";
};
@@ -74,9 +73,6 @@ CreateTiddlerWidget.prototype.invokeAction = function(triggeringWidget,event) {
if(this.actionSaveTitle) {
this.wiki.setTextReference(this.actionSaveTitle,title,this.getVariable("currentTiddler"));
}
if(this.actionSaveDraftTitle) {
this.wiki.setTextReference(this.actionSaveDraftTitle,this.wiki.generateDraftTitle(title),this.getVariable("currentTiddler"));
}
return true; // Action was invoked
};

View File

@@ -59,7 +59,7 @@ DeleteFieldWidget.prototype.invokeAction = function(triggeringWidget,event) {
tiddler = this.wiki.getTiddler(self.actionTiddler),
removeFields = {},
hasChanged = false;
if(this.actionField && tiddler) {
if(this.actionField) {
removeFields[this.actionField] = undefined;
if(this.actionField in tiddler.fields) {
hasChanged = true;

View File

@@ -156,9 +156,6 @@ CheckboxWidget.prototype.handleChangeEvent = function(event) {
if(this.checkboxActions) {
this.invokeActionString(this.checkboxActions,this,event);
}
if(this.checkboxCheckActions && checked) {
this.invokeActionString(this.checkboxCheckActions,this,event);
}
if(this.checkboxUncheckActions && !checked) {
this.invokeActionString(this.checkboxUncheckActions,this,event);
}
@@ -170,7 +167,6 @@ Compute the internal state of the widget
CheckboxWidget.prototype.execute = function() {
// Get the parameters from the attributes
this.checkboxActions = this.getAttribute("actions");
this.checkboxCheckActions = this.getAttribute("checkactions");
this.checkboxUncheckActions = this.getAttribute("uncheckactions");
this.checkboxTitle = this.getAttribute("tiddler",this.getVariable("currentTiddler"));
this.checkboxTag = this.getAttribute("tag");

View File

@@ -14,8 +14,7 @@ Edit-bitmap widget
// Default image sizes
var DEFAULT_IMAGE_WIDTH = 600,
DEFAULT_IMAGE_HEIGHT = 370,
DEFAULT_IMAGE_TYPE = "image/png";
DEFAULT_IMAGE_HEIGHT = 370;
// Configuration tiddlers
var LINE_WIDTH_TITLE = "$:/config/BitmapEditor/LineWidth",
@@ -155,13 +154,7 @@ EditBitmapWidget.prototype.loadCanvas = function() {
self.refreshToolbar();
};
// Get the current bitmap into an image object
if(tiddler && tiddler.fields.type && tiddler.fields.text) {
currImage.src = "data:" + tiddler.fields.type + ";base64," + tiddler.fields.text;
} else {
currImage.width = DEFAULT_IMAGE_WIDTH;
currImage.height = DEFAULT_IMAGE_HEIGHT;
currImage.onerror();
}
currImage.src = "data:" + tiddler.fields.type + ";base64," + tiddler.fields.text;
};
EditBitmapWidget.prototype.initCanvas = function(canvas,width,height,image) {
@@ -326,16 +319,18 @@ EditBitmapWidget.prototype.strokeEnd = function() {
};
EditBitmapWidget.prototype.saveChanges = function() {
var tiddler = this.wiki.getTiddler(this.editTitle) || new $tw.Tiddler({title: this.editTitle,type: DEFAULT_IMAGE_TYPE});
// data URIs look like "data:<type>;base64,<text>"
var dataURL = this.canvasDomNode.toDataURL(tiddler.fields.type),
posColon = dataURL.indexOf(":"),
posSemiColon = dataURL.indexOf(";"),
posComma = dataURL.indexOf(","),
type = dataURL.substring(posColon+1,posSemiColon),
text = dataURL.substring(posComma+1);
var update = {type: type, text: text};
this.wiki.addTiddler(new $tw.Tiddler(this.wiki.getModificationFields(),tiddler,update,this.wiki.getCreationFields()));
var tiddler = this.wiki.getTiddler(this.editTitle);
if(tiddler) {
// data URIs look like "data:<type>;base64,<text>"
var dataURL = this.canvasDomNode.toDataURL(tiddler.fields.type),
posColon = dataURL.indexOf(":"),
posSemiColon = dataURL.indexOf(";"),
posComma = dataURL.indexOf(","),
type = dataURL.substring(posColon+1,posSemiColon),
text = dataURL.substring(posComma+1);
var update = {type: type, text: text};
this.wiki.addTiddler(new $tw.Tiddler(this.wiki.getModificationFields(),tiddler,update,this.wiki.getCreationFields()));
}
};
exports["edit-bitmap"] = EditBitmapWidget;

View File

@@ -73,13 +73,13 @@ Compute the internal state of the widget
KeyboardWidget.prototype.execute = function() {
var self = this;
// Get attributes
this.actions = this.getAttribute("actions","");
this.message = this.getAttribute("message","");
this.param = this.getAttribute("param","");
this.key = this.getAttribute("key","");
this.tag = this.getAttribute("tag","");
this.actions = this.getAttribute("actions");
this.message = this.getAttribute("message");
this.param = this.getAttribute("param");
this.key = this.getAttribute("key");
this.tag = this.getAttribute("tag");
this.keyInfoArray = $tw.keyboardManager.parseKeyDescriptors(this.key);
this["class"] = this.getAttribute("class","");
this["class"] = this.getAttribute("class");
if(this.key.substr(0,2) === "((" && this.key.substr(-2,2) === "))") {
this.shortcutTiddlers = [];
var name = this.key.substring(2,this.key.length -2);

View File

@@ -183,14 +183,7 @@ LinkWidget.prototype.execute = function() {
this.isShadow = this.wiki.isShadowTiddler(this.to);
this.hideMissingLinks = (this.getVariable("tv-show-missing-links") || "yes") === "no";
// Make the child widgets
var templateTree;
if(this.parseTreeNode.children && this.parseTreeNode.children.length > 0) {
templateTree = this.parseTreeNode.children;
} else {
// Default template is a link to the title
templateTree = [{type: "text", text: this.to}];
}
this.makeChildWidgets(templateTree);
this.makeChildWidgets();
};
/*

View File

@@ -84,50 +84,39 @@ NavigatorWidget.prototype.getStoryList = function() {
};
NavigatorWidget.prototype.saveStoryList = function(storyList) {
if(this.storyTitle) {
var storyTiddler = this.wiki.getTiddler(this.storyTitle);
this.wiki.addTiddler(new $tw.Tiddler(
{title: this.storyTitle},
storyTiddler,
{list: storyList}
));
}
var storyTiddler = this.wiki.getTiddler(this.storyTitle);
this.wiki.addTiddler(new $tw.Tiddler(
{title: this.storyTitle},
storyTiddler,
{list: storyList}
));
};
NavigatorWidget.prototype.removeTitleFromStory = function(storyList,title) {
if(storyList) {
var p = storyList.indexOf(title);
while(p !== -1) {
storyList.splice(p,1);
p = storyList.indexOf(title);
}
var p = storyList.indexOf(title);
while(p !== -1) {
storyList.splice(p,1);
p = storyList.indexOf(title);
}
};
NavigatorWidget.prototype.replaceFirstTitleInStory = function(storyList,oldTitle,newTitle) {
if(storyList) {
var pos = storyList.indexOf(oldTitle);
if(pos !== -1) {
storyList[pos] = newTitle;
do {
pos = storyList.indexOf(oldTitle,pos + 1);
if(pos !== -1) {
storyList.splice(pos,1);
}
} while(pos !== -1);
} else {
storyList.splice(0,0,newTitle);
}
var pos = storyList.indexOf(oldTitle);
if(pos !== -1) {
storyList[pos] = newTitle;
do {
pos = storyList.indexOf(oldTitle,pos + 1);
if(pos !== -1) {
storyList.splice(pos,1);
}
} while(pos !== -1);
} else {
storyList.splice(0,0,newTitle);
}
};
NavigatorWidget.prototype.addToStory = function(title,fromTitle) {
if(this.storyTitle) {
this.wiki.addToStory(title,fromTitle,this.storyTitle,{
openLinkFromInsideRiver: this.getAttribute("openLinkFromInsideRiver","top"),
openLinkFromOutsideRiver: this.getAttribute("openLinkFromOutsideRiver","top")
});
}
this.wiki.addToStory(title,fromTitle,this.storyTitle,{openLinkFromInsideRiver: this.getAttribute("openLinkFromInsideRiver","top"),openLinkFromOutsideRiver: this.getAttribute("openLinkFromOutsideRiver","top")});
};
/*
@@ -290,7 +279,15 @@ NavigatorWidget.prototype.makeDraftTiddler = function(targetTitle) {
Generate a title for the draft of a given tiddler
*/
NavigatorWidget.prototype.generateDraftTitle = function(title) {
return this.wiki.generateDraftTitle(title);
var c = 0,
draftTitle,
username = this.wiki.getTiddlerText("$:/status/UserName"),
attribution = username ? " by " + username : "";
do {
draftTitle = "Draft " + (c ? (c + 1) + " " : "") + "of '" + title + "'" + attribution;
c++;
} while(this.wiki.tiddlerExists(draftTitle));
return draftTitle;
};
// Take a tiddler out of edit mode, saving the changes
@@ -469,14 +466,14 @@ NavigatorWidget.prototype.handleNewTiddlerEvent = function(event) {
},this.wiki.getModificationFields());
this.wiki.addTiddler(draftTiddler);
// Update the story to insert the new draft at the top and remove any existing tiddler
if(storyList && storyList.indexOf(draftTitle) === -1) {
if(storyList.indexOf(draftTitle) === -1) {
var slot = storyList.indexOf(event.navigateFromTitle);
if(slot === -1) {
slot = this.getAttribute("openLinkFromOutsideRiver","top") === "bottom" ? storyList.length - 1 : slot;
}
storyList.splice(slot + 1,0,draftTitle);
}
if(storyList && storyList.indexOf(title) !== -1) {
if(storyList.indexOf(title) !== -1) {
storyList.splice(storyList.indexOf(title),1);
}
this.saveStoryList(storyList);
@@ -532,7 +529,7 @@ NavigatorWidget.prototype.handleImportTiddlersEvent = function(event) {
var storyList = this.getStoryList(),
history = [];
// Add it to the story
if(storyList && storyList.indexOf(IMPORT_TITLE) === -1) {
if(storyList.indexOf(IMPORT_TITLE) === -1) {
storyList.unshift(IMPORT_TITLE);
}
// And to history
@@ -609,6 +606,7 @@ NavigatorWidget.prototype.handleUnfoldAllTiddlersEvent = function(event) {
};
NavigatorWidget.prototype.handleRenameTiddlerEvent = function(event) {
event = $tw.hooks.invokeHook("th-renaming-tiddler", event);
var paramObject = event.paramObject || {},
from = paramObject.from || event.tiddlerTitle,
to = paramObject.to;

View File

@@ -56,39 +56,32 @@ RevealWidget.prototype.render = function(parent,nextSibling) {
RevealWidget.prototype.positionPopup = function(domNode) {
domNode.style.position = "absolute";
domNode.style.zIndex = "1000";
var left,top;
switch(this.position) {
case "left":
left = this.popup.left - domNode.offsetWidth;
top = this.popup.top;
domNode.style.left = Math.max(0, this.popup.left - domNode.offsetWidth) + "px";
domNode.style.top = this.popup.top + "px";
break;
case "above":
left = this.popup.left;
top = this.popup.top - domNode.offsetHeight;
domNode.style.left = this.popup.left + "px";
domNode.style.top = Math.max(0, this.popup.top - domNode.offsetHeight) + "px";
break;
case "aboveright":
left = this.popup.left + this.popup.width;
top = this.popup.top + this.popup.height - domNode.offsetHeight;
domNode.style.left = (this.popup.left + this.popup.width) + "px";
domNode.style.top = Math.max(0, this.popup.top + this.popup.height - domNode.offsetHeight) + "px";
break;
case "right":
left = this.popup.left + this.popup.width;
top = this.popup.top;
domNode.style.left = (this.popup.left + this.popup.width) + "px";
domNode.style.top = this.popup.top + "px";
break;
case "belowleft":
left = this.popup.left + this.popup.width - domNode.offsetWidth;
top = this.popup.top + this.popup.height;
domNode.style.left = Math.max(0, this.popup.left + this.popup.width - domNode.offsetWidth) + "px";
domNode.style.top = (this.popup.top + this.popup.height) + "px";
break;
default: // Below
left = this.popup.left;
top = this.popup.top + this.popup.height;
domNode.style.left = this.popup.left + "px";
domNode.style.top = (this.popup.top + this.popup.height) + "px";
break;
}
if(!this.positionAllowNegative) {
left = Math.max(0,left);
top = Math.max(0,top);
}
domNode.style.left = left + "px";
domNode.style.top = top + "px";
};
/*
@@ -101,7 +94,6 @@ RevealWidget.prototype.execute = function() {
this.type = this.getAttribute("type");
this.text = this.getAttribute("text");
this.position = this.getAttribute("position");
this.positionAllowNegative = this.getAttribute("positionAllowNegative") === "yes";
this["class"] = this.getAttribute("class","");
this.style = this.getAttribute("style","");
this["default"] = this.getAttribute("default","");
@@ -150,10 +142,10 @@ RevealWidget.prototype.readState = function() {
this.readPopupState(state);
break;
case "match":
this.isOpen = this.text === state;
this.isOpen = !!(this.compareStateText(state) == 0);
break;
case "nomatch":
this.isOpen = this.text !== state;
this.isOpen = !(this.compareStateText(state) == 0);
break;
case "lt":
this.isOpen = !!(this.compareStateText(state) < 0);
@@ -199,13 +191,13 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
*/
RevealWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(changedAttributes.state || changedAttributes.type || changedAttributes.text || changedAttributes.position || changedAttributes.positionAllowNegative || changedAttributes["default"] || changedAttributes.animate || changedAttributes.stateTitle || changedAttributes.stateField || changedAttributes.stateIndex) {
if(changedAttributes.state || changedAttributes.type || changedAttributes.text || changedAttributes.position || changedAttributes["default"] || changedAttributes.animate || changedAttributes.stateTitle || changedAttributes.stateField || changedAttributes.stateIndex) {
this.refreshSelf();
return true;
} else {
var currentlyOpen = this.isOpen;
this.readState();
if(this.isOpen !== currentlyOpen) {
if(this.isOpen !== currentlyOpen || (this.stateTiddlerTitle && changedTiddlers[this.stateTiddlerTitle])) {
if(this.retain === "yes") {
this.updateState();
} else {

View File

@@ -385,10 +385,9 @@ Widget.prototype.previousSibling = function() {
Render the children of this widget into the DOM
*/
Widget.prototype.renderChildren = function(parent,nextSibling) {
var children = this.children;
for(var i = 0; i < children.length; i++) {
children[i].render(parent,nextSibling);
};
$tw.utils.each(this.children,function(childWidget) {
childWidget.render(parent,nextSibling);
});
};
/*
@@ -456,11 +455,11 @@ Widget.prototype.refreshSelf = function() {
Refresh all the children of a widget
*/
Widget.prototype.refreshChildren = function(changedTiddlers) {
var children = this.children,
var self = this,
refreshed = false;
for (var i = 0; i < children.length; i++) {
refreshed = children[i].refresh(changedTiddlers) || refreshed;
}
$tw.utils.each(this.children,function(childWidget) {
refreshed = childWidget.refresh(changedTiddlers) || refreshed;
});
return refreshed;
};

View File

@@ -44,8 +44,8 @@ function relinkTiddler(fromTitle,toTitle,options) {
var type = tiddler.fields.type || "";
// Don't touch plugins or JavaScript modules
if(!tiddler.fields["plugin-type"] && type !== "application/javascript") {
var tags = tiddler.fields.tags ? tiddler.fields.tags.slice(0) : undefined,
list = tiddler.fields.list ? tiddler.fields.list.slice(0) : undefined,
var tags = (tiddler.fields.tags || []).slice(0),
list = (tiddler.fields.list || []).slice(0),
isModified = false;
if(!options.dontRenameInTags) {
// Rename tags

View File

@@ -27,16 +27,6 @@ var widget = require("$:/core/modules/widgets/widget.js");
var USER_NAME_TITLE = "$:/status/UserName",
TIMESTAMP_DISABLE_TITLE = "$:/config/TimestampDisable";
/*
Add available indexers to this wiki
*/
exports.addIndexersToWiki = function() {
var self = this;
$tw.utils.each($tw.modules.applyMethods("indexer"),function(Indexer,name) {
self.addIndexer(new Indexer(self),name);
});
};
/*
Get the value of a text reference. Text references can have any of these forms:
<tiddlertitle>
@@ -488,18 +478,11 @@ exports.getOrphanTitles = function() {
Retrieves a list of the tiddler titles that are tagged with a given tag
*/
exports.getTiddlersWithTag = function(tag) {
// Try to use the indexer
var self = this,
tagIndexer = this.getIndexer("TagIndexer"),
results = tagIndexer && tagIndexer.subIndexers[3].lookup(tag);
if(!results) {
// If not available, perform a manual scan
results = this.getGlobalCache("taglist-" + tag,function() {
var tagmap = self.getTagMap();
return self.sortByList(tagmap[tag],tag);
});
}
return results;
var self = this;
return this.getGlobalCache("taglist-" + tag,function() {
var tagmap = self.getTagMap();
return self.sortByList(tagmap[tag],tag);
});
};
/*
@@ -1065,7 +1048,6 @@ Options available:
invert: If true returns tiddlers that do not contain the specified string
caseSensitive: If true forces a case sensitive search
field: If specified, restricts the search to the specified field, or an array of field names
anchored: If true, forces all but regexp searches to be anchored to the start of text
excludeField: If true, the field options are inverted to specify the fields that are not to be searched
The search mode is determined by the first of these boolean flags to be true
literal: searches for literal string
@@ -1080,13 +1062,12 @@ exports.search = function(text,options) {
invert = !!options.invert;
// Convert the search string into a regexp for each term
var terms, searchTermsRegExps,
flags = options.caseSensitive ? "" : "i",
anchor = options.anchored ? "^" : "";
flags = options.caseSensitive ? "" : "i";
if(options.literal) {
if(text.length === 0) {
searchTermsRegExps = null;
} else {
searchTermsRegExps = [new RegExp("(" + anchor + $tw.utils.escapeRegExp(text) + ")",flags)];
searchTermsRegExps = [new RegExp("(" + $tw.utils.escapeRegExp(text) + ")",flags)];
}
} else if(options.whitespace) {
terms = [];
@@ -1095,7 +1076,7 @@ exports.search = function(text,options) {
terms.push($tw.utils.escapeRegExp(term));
}
});
searchTermsRegExps = [new RegExp("(" + anchor + terms.join("\\s+") + ")",flags)];
searchTermsRegExps = [new RegExp("(" + terms.join("\\s+") + ")",flags)];
} else if(options.regexp) {
try {
searchTermsRegExps = [new RegExp("(" + text + ")",flags)];
@@ -1110,7 +1091,7 @@ exports.search = function(text,options) {
} else {
searchTermsRegExps = [];
for(t=0; t<terms.length; t++) {
searchTermsRegExps.push(new RegExp("(" + anchor + $tw.utils.escapeRegExp(terms[t]) + ")",flags));
searchTermsRegExps.push(new RegExp("(" + $tw.utils.escapeRegExp(terms[t]) + ")",flags));
}
}
}
@@ -1388,10 +1369,8 @@ fromPageRect: page coordinates of the origin of the navigation
historyTitle: title of history tiddler (defaults to $:/HistoryList)
*/
exports.addToHistory = function(title,fromPageRect,historyTitle) {
if(historyTitle) {
var story = new $tw.Story({wiki: this, historyTitle: historyTitle});
story.addToHistory(title,fromPageRect);
}
var story = new $tw.Story({wiki: this, historyTitle: historyTitle});
story.addToHistory(title,fromPageRect);
};
/*
@@ -1402,25 +1381,8 @@ storyTitle: title of story tiddler (defaults to $:/StoryList)
options: see story.js
*/
exports.addToStory = function(title,fromTitle,storyTitle,options) {
if(storyTitle) {
var story = new $tw.Story({wiki: this, storyTitle: storyTitle});
story.addToStory(title,fromTitle,options);
}
};
/*
Generate a title for the draft of a given tiddler
*/
exports.generateDraftTitle = function(title) {
var c = 0,
draftTitle,
username = this.getTiddlerText("$:/status/UserName"),
attribution = username ? " by " + username : "";
do {
draftTitle = "Draft " + (c ? (c + 1) + " " : "") + "of '" + title + "'" + attribution;
c++;
} while(this.tiddlerExists(draftTitle));
return draftTitle;
var story = new $tw.Story({wiki: this, storyTitle: storyTitle});
story.addToStory(title,fromTitle,options);
};
/*

View File

@@ -52,7 +52,7 @@ modal-footer-background: #3b4252
modal-footer-border: #3b4252
modal-header-border: #3b4252
muted-foreground: #4C566A
notification-background: <<colour primary>>
notification-background: #D08770
notification-border: #EBCB8B
page-background: #2e3440
pre-background: #2E3440

View File

@@ -119,7 +119,7 @@ caption: {{$:/language/ControlPanel/KeyboardShortcuts/Caption}}
</td>
</tr>
<$set name="dropdownState" value={{$(dropdownStateTitle)$}}>
<$list filter="[<dropdownState>match[open]]" variable="listItem">
<$list filter="[<dropdownState>prefix[open]]" variable="listItem">
<<shortcut-editor>>
</$list>
</$set>

View File

@@ -15,7 +15,7 @@ caption: {{$:/language/ControlPanel/Palette/Caption}}
<$reveal type="match" state="$:/state/ShowPaletteEditor" text="yes">
<$button set="$:/state/ShowPaletteEditor" setTo="no"><<lingo HideEditor/Caption>></$button>
{{$:/PaletteManager}}
{{$:/snippets/paletteeditor}}
</$reveal>

View File

@@ -2,6 +2,6 @@ title: $:/core/ui/ControlPanel/Plugins/AddPlugins
\define lingo-base() $:/language/ControlPanel/Plugins/
<$button message="tm-modal" param="$:/core/ui/ControlPanel/Modals/AddPlugins" tooltip={{$:/language/ControlPanel/Plugins/Add/Hint}} class="tc-btn-big-green tc-primary-btn">
<$button message="tm-modal" param="$:/core/ui/ControlPanel/Modals/AddPlugins" tooltip={{$:/language/ControlPanel/Plugins/Add/Hint}} class="tc-btn-big-green" style="background:blue;">
{{$:/core/images/download-button}} <<lingo Add/Caption>>
</$button>

View File

@@ -1,16 +0,0 @@
title: $:/core/ui/ControlPanel/Saving/GitHub
tags: $:/tags/ControlPanel/Saving
caption: {{$:/language/ControlPanel/Saving/GitService/GitHub/Caption}}
\define lingo-base() $:/language/ControlPanel/Saving/GitService/
\define service-name() ~GitHub
<<lingo Description>>
|<<lingo UserName>> |<$edit-text tiddler="$:/GitHub/Username" default="" tag="input"/> |
|<<lingo GitHub/Password>> |<$password name="github"/> |
|<<lingo Repo>> |<$edit-text tiddler="$:/GitHub/Repo" default="" tag="input"/> |
|<<lingo Branch>> |<$edit-text tiddler="$:/GitHub/Branch" default="master" tag="input"/> |
|<<lingo Path>> |<$edit-text tiddler="$:/GitHub/Path" default="" tag="input"/> |
|<<lingo Filename>> |<$edit-text tiddler="$:/GitHub/Filename" default="" tag="input"/> |
|<<lingo ServerURL>> |<$edit-text tiddler="$:/GitHub/ServerURL" default="https://api.github.com" tag="input"/> |

View File

@@ -1,16 +0,0 @@
title: $:/core/ui/ControlPanel/Saving/GitLab
tags: $:/tags/ControlPanel/Saving
caption: {{$:/language/ControlPanel/Saving/GitService/GitLab/Caption}}
\define lingo-base() $:/language/ControlPanel/Saving/GitService/
\define service-name() ~GitLab
<<lingo Description>>
|<<lingo UserName>> |<$edit-text tiddler="$:/GitLab/Username" default="" tag="input"/> |
|<<lingo GitLab/Password>> |<$password name="gitlab"/> |
|<<lingo Repo>> |<$edit-text tiddler="$:/GitLab/Repo" default="" tag="input"/> |
|<<lingo Branch>> |<$edit-text tiddler="$:/GitLab/Branch" default="master" tag="input"/> |
|<<lingo Path>> |<$edit-text tiddler="$:/GitLab/Path" default="" tag="input"/> |
|<<lingo Filename>> |<$edit-text tiddler="$:/GitLab/Filename" default="" tag="input"/> |
|<<lingo ServerURL>> |<$edit-text tiddler="$:/GitLab/ServerURL" default="https://gitlab.com/api/v4" tag="input"/> |

View File

@@ -29,12 +29,11 @@ $value={{$:/temp/newfieldvalue}}/>
</$reveal>
</$vars>
\end
\whitespace trim
<div class="tc-edit-fields">
<table class="tc-edit-fields">
<tbody>
<$list filter="[all[current]fields[]] +[sort[title]]" variable="currentField" storyview="pop">
<$list filter="[all[current]fields[]] +[sort[title]]" variable="currentField">
<$list filter=<<config-filter>> variable="temp">
<tr class="tc-edit-field">
<td class="tc-edit-field-name">
@@ -58,12 +57,12 @@ $value={{$:/temp/newfieldvalue}}/>
<$fieldmangler>
<div class="tc-edit-field-add">
<em class="tc-edit">
<<lingo Fields/Add/Prompt>>&nbsp;
<<lingo Fields/Add/Prompt>>
</em>
<span class="tc-edit-field-add-name">
<$edit-text tiddler="$:/temp/newfieldname" tag="input" default="" placeholder={{$:/language/EditTemplate/Fields/Add/Name/Placeholder}} focusPopup=<<qualify "$:/state/popup/field-dropdown">> class="tc-edit-texteditor tc-popup-handle" tabindex={{$:/config/EditTabIndex}}/>
</span>&nbsp;
<$button popup=<<qualify "$:/state/popup/field-dropdown">> class="tc-btn-invisible tc-btn-dropdown" tooltip={{$:/language/EditTemplate/Field/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Field/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button>&nbsp;
</span>
<$button popup=<<qualify "$:/state/popup/field-dropdown">> class="tc-btn-invisible tc-btn-dropdown" tooltip={{$:/language/EditTemplate/Field/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Field/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button>
<$reveal state=<<qualify "$:/state/popup/field-dropdown">> type="nomatch" text="" default="">
<div class="tc-block-dropdown tc-edit-type-dropdown">
<$set name="tv-show-missing-links" value="yes">
@@ -73,7 +72,7 @@ $value={{$:/temp/newfieldvalue}}/>
</div>
<$list filter="[!is[shadow]!is[system]fields[]search:title{$:/temp/newfieldname}sort[]] -created -creator -draft.of -draft.title -modified -modifier -tags -text -title -type" variable="currentField">
<$link to=<<currentField>>>
<$text text=<<currentField>>/>
<<currentField>>
</$link>
</$list>
<div class="tc-dropdown-item">
@@ -81,7 +80,7 @@ $value={{$:/temp/newfieldvalue}}/>
</div>
<$list filter="[fields[]search:title{$:/temp/newfieldname}sort[]] -[!is[shadow]!is[system]fields[]]" variable="currentField">
<$link to=<<currentField>>>
<$text text=<<currentField>>/>
<<currentField>>
</$link>
</$list>
</$linkcatcher>
@@ -90,7 +89,7 @@ $value={{$:/temp/newfieldvalue}}/>
</$reveal>
<span class="tc-edit-field-add-value">
<$edit-text tiddler="$:/temp/newfieldvalue" tag="input" default="" placeholder={{$:/language/EditTemplate/Fields/Add/Value/Placeholder}} class="tc-edit-texteditor" tabindex={{$:/config/EditTabIndex}}/>
</span>&nbsp;
</span>
<span class="tc-edit-field-add-button">
<$macrocall $name="new-field"/>
</span>

View File

@@ -16,7 +16,7 @@ color:$(foregroundColor)$;
<$vars foregroundColor=<<contrastcolour target:"""$colour$""" fallbackTarget:"""$fallbackTarget$""" colourA:"""$colourA$""" colourB:"""$colourB$""">> backgroundColor="""$colour$""">
<span style=<<tag-styles>> class="tc-tag-label tc-tag-list-item">
<$transclude tiddler="""$icon$"""/>&nbsp;<$view field="title" format="text" />
<$button message="tm-remove-tag" param={{!!title}} class="tc-btn-invisible tc-remove-tag-button">{{$:/core/images/close-button}}</$button>
<$button message="tm-remove-tag" param={{!!title}} class="tc-btn-invisible tc-remove-tag-button">&times;</$button>
</span>
</$vars>
\end

View File

@@ -4,10 +4,10 @@ caption: {{$:/core/images/cancel-button}} {{$:/language/Buttons/Cancel/Caption}}
description: {{$:/language/Buttons/Cancel/Hint}}
<$button message="tm-cancel-tiddler" tooltip={{$:/language/Buttons/Cancel/Hint}} aria-label={{$:/language/Buttons/Cancel/Caption}} class=<<tv-config-toolbar-class>>>
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
<$list filter="[<tv-config-toolbar-icons>prefix[yes]]">
{{$:/core/images/cancel-button}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<$list filter="[<tv-config-toolbar-text>prefix[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/Cancel/Caption}}/></span>
</$list>
</$button>

View File

@@ -4,10 +4,10 @@ caption: {{$:/core/images/delete-button}} {{$:/language/Buttons/Delete/Caption}}
description: {{$:/language/Buttons/Delete/Hint}}
<$button message="tm-delete-tiddler" tooltip={{$:/language/Buttons/Delete/Hint}} aria-label={{$:/language/Buttons/Delete/Caption}} class=<<tv-config-toolbar-class>>>
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
<$list filter="[<tv-config-toolbar-icons>prefix[yes]]">
{{$:/core/images/delete-button}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<$list filter="[<tv-config-toolbar-text>prefix[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/Delete/Caption}}/></span>
</$list>
</$button>

View File

@@ -10,10 +10,10 @@ description: {{$:/language/Buttons/Save/Hint}}
<$action-deletetiddler $tiddler="$:/temp/newfieldname"/>
<$action-deletetiddler $tiddler="$:/temp/newfieldvalue"/>
<$action-sendmessage $message="tm-save-tiddler"/>
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
<$list filter="[<tv-config-toolbar-icons>prefix[yes]]">
{{$:/core/images/done-button}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<$list filter="[<tv-config-toolbar-text>prefix[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/Save/Caption}}/></span>
</$list>
</$button></$fieldmangler>

View File

@@ -3,28 +3,12 @@ title: $:/core/ui/EditorToolbar/stamp-dropdown
\define toolbar-button-stamp-inner()
<$button tag="a">
<$list filter="[[$(snippetTitle)$]addsuffix[/prefix]is[missing]removesuffix[/prefix]addsuffix[/suffix]is[missing]]">
<$action-sendmessage
$message="tm-edit-text-operation"
$param="replace-selection"
text={{$(snippetTitle)$}}
/>
</$list>
<$list filter="[[$(snippetTitle)$]addsuffix[/prefix]is[missing]removesuffix[/prefix]addsuffix[/suffix]!is[missing]] [[$(snippetTitle)$]addsuffix[/prefix]!is[missing]removesuffix[/prefix]addsuffix[/suffix]is[missing]] [[$(snippetTitle)$]addsuffix[/prefix]!is[missing]removesuffix[/prefix]addsuffix[/suffix]!is[missing]]">
<$action-sendmessage
$message="tm-edit-text-operation"
$param="wrap-selection"
prefix={{{ [[$(snippetTitle)$]addsuffix[/prefix]get[text]] }}}
suffix={{{ [[$(snippetTitle)$]addsuffix[/suffix]get[text]] }}}
/>
</$list>
<$action-deletetiddler
$tiddler=<<dropdown-state>>
/>

View File

@@ -1,8 +0,0 @@
title: $:/core/ui/KeyboardShortcuts/advanced-search
tags: $:/tags/KeyboardShortcut
key: ((advanced-search))
<$navigator story="$:/StoryList" history="$:/HistoryList">
<$action-navigate $to="$:/AdvancedSearch"/>
<$action-sendmessage $message="tm-focus-selector" $param="""[data-tiddler-title="$:/AdvancedSearch"] .tc-search input"""/>
</$navigator>

View File

@@ -1,5 +0,0 @@
title: $:/core/ui/KeyboardShortcuts/sidebar-search
tags: $:/tags/KeyboardShortcut
key: ((sidebar-search))
<$action-sendmessage $message="tm-focus-selector" $param=".tc-search input"/>

View File

@@ -1,9 +0,0 @@
title: $:/core/ui/KeyboardShortcut/toggle-sidebar
tags: $:/tags/KeyboardShortcut
key: ((toggle-sidebar))
<$list filter="[[$:/state/sidebar]is[missing]] [{$:/state/sidebar}removeprefix[yes]]" emptyMessage="""
<$action-setfield $tiddler="$:/state/sidebar" text="yes"/>
""">
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
</$list>

View File

@@ -1,17 +1,15 @@
title: $:/core/ui/PageTemplate/pagecontrols
\whitespace trim
\define config-title()
$:/config/PageControlButtons/Visibility/$(listItem)$
\end
<div class="tc-page-controls">
<$list filter="[all[shadows+tiddlers]tag[$:/tags/PageControls]!has[draft.of]]" variable="listItem">
<$set name="hidden" value=<<config-title>>>
<$list filter="[<hidden>!text[hide]]" storyview="pop">
<$reveal type="nomatch" state=<<config-title>> text="hide">
<$set name="tv-config-toolbar-class" filter="[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]">
<$transclude tiddler=<<listItem>> mode="inline"/>
</$set>
</$list>
</$set>
</$reveal>
</$list>
</div>

View File

@@ -5,10 +5,10 @@ description: {{$:/language/Buttons/AdvancedSearch/Hint}}
\define control-panel-button(class)
<$button to="$:/AdvancedSearch" tooltip={{$:/language/Buttons/AdvancedSearch/Hint}} aria-label={{$:/language/Buttons/AdvancedSearch/Caption}} class="""$(tv-config-toolbar-class)$ $class$""">
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
<$list filter="[<tv-config-toolbar-icons>prefix[yes]]">
{{$:/core/images/advanced-search-button}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<$list filter="[<tv-config-toolbar-text>prefix[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/AdvancedSearch/Caption}}/></span>
</$list>
</$button>

View File

@@ -4,10 +4,10 @@ caption: {{$:/core/images/close-all-button}} {{$:/language/Buttons/CloseAll/Capt
description: {{$:/language/Buttons/CloseAll/Hint}}
<$button message="tm-close-all-tiddlers" tooltip={{$:/language/Buttons/CloseAll/Hint}} aria-label={{$:/language/Buttons/CloseAll/Caption}} class=<<tv-config-toolbar-class>>>
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
<$list filter="[<tv-config-toolbar-icons>prefix[yes]]">
{{$:/core/images/close-all-button}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<$list filter="[<tv-config-toolbar-text>prefix[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/CloseAll/Caption}}/></span>
</$list>
</$button>

View File

@@ -5,10 +5,10 @@ description: {{$:/language/Buttons/ControlPanel/Hint}}
\define control-panel-button(class)
<$button to="$:/ControlPanel" tooltip={{$:/language/Buttons/ControlPanel/Hint}} aria-label={{$:/language/Buttons/ControlPanel/Caption}} class="""$(tv-config-toolbar-class)$ $class$""">
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
<$list filter="[<tv-config-toolbar-icons>prefix[yes]]">
{{$:/core/images/options-button}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<$list filter="[<tv-config-toolbar-text>prefix[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/ControlPanel/Caption}}/></span>
</$list>
</$button>

View File

@@ -5,20 +5,20 @@ description: {{$:/language/Buttons/Encryption/Hint}}
<$reveal type="match" state="$:/isEncrypted" text="yes">
<$button message="tm-clear-password" tooltip={{$:/language/Buttons/Encryption/ClearPassword/Hint}} aria-label={{$:/language/Buttons/Encryption/ClearPassword/Caption}} class=<<tv-config-toolbar-class>>>
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
<$list filter="[<tv-config-toolbar-icons>prefix[yes]]">
{{$:/core/images/locked-padlock}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<$list filter="[<tv-config-toolbar-text>prefix[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/Encryption/ClearPassword/Caption}}/></span>
</$list>
</$button>
</$reveal>
<$reveal type="nomatch" state="$:/isEncrypted" text="yes">
<$button message="tm-set-password" tooltip={{$:/language/Buttons/Encryption/SetPassword/Hint}} aria-label={{$:/language/Buttons/Encryption/SetPassword/Caption}} class=<<tv-config-toolbar-class>>>
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
<$list filter="[<tv-config-toolbar-icons>prefix[yes]]">
{{$:/core/images/unlocked-padlock}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<$list filter="[<tv-config-toolbar-text>prefix[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/Encryption/SetPassword/Caption}}/></span>
</$list>
</$button>

View File

@@ -5,10 +5,10 @@ description: {{$:/language/Buttons/FoldAll/Hint}}
<$button tooltip={{$:/language/Buttons/FoldAll/Hint}} aria-label={{$:/language/Buttons/FoldAll/Caption}} class=<<tv-config-toolbar-class>>>
<$action-sendmessage $message="tm-fold-all-tiddlers" $param=<<currentTiddler>> foldedStatePrefix="$:/state/folded/"/>
<$list filter="[<tv-config-toolbar-icons>match[yes]]" variable="listItem">
<$list filter="[<tv-config-toolbar-icons>prefix[yes]]" variable="listItem">
{{$:/core/images/fold-all-button}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<$list filter="[<tv-config-toolbar-text>prefix[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/FoldAll/Caption}}/></span>
</$list>
</$button>

View File

@@ -4,10 +4,10 @@ caption: {{$:/core/images/full-screen-button}} {{$:/language/Buttons/FullScreen/
description: {{$:/language/Buttons/FullScreen/Hint}}
<$button message="tm-full-screen" tooltip={{$:/language/Buttons/FullScreen/Hint}} aria-label={{$:/language/Buttons/FullScreen/Caption}} class=<<tv-config-toolbar-class>>>
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
<$list filter="[<tv-config-toolbar-icons>prefix[yes]]">
{{$:/core/images/full-screen-button}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<$list filter="[<tv-config-toolbar-text>prefix[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/FullScreen/Caption}}/></span>
</$list>
</$button>

View File

@@ -4,10 +4,10 @@ caption: {{$:/core/images/home-button}} {{$:/language/Buttons/Home/Caption}}
description: {{$:/language/Buttons/Home/Hint}}
<$button message="tm-home" tooltip={{$:/language/Buttons/Home/Hint}} aria-label={{$:/language/Buttons/Home/Caption}} class=<<tv-config-toolbar-class>>>
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
<$list filter="[<tv-config-toolbar-icons>prefix[yes]]">
{{$:/core/images/home-button}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<$list filter="[<tv-config-toolbar-text>prefix[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/Home/Caption}}/></span>
</$list>
</$button>

View File

@@ -5,10 +5,10 @@ description: {{$:/language/Buttons/Import/Hint}}
<div class="tc-file-input-wrapper">
<$button tooltip={{$:/language/Buttons/Import/Hint}} aria-label={{$:/language/Buttons/Import/Caption}} class=<<tv-config-toolbar-class>>>
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
<$list filter="[<tv-config-toolbar-icons>prefix[yes]]">
{{$:/core/images/import-button}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<$list filter="[<tv-config-toolbar-text>prefix[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/Import/Caption}}/></span>
</$list>
</$button>

View File

@@ -8,14 +8,14 @@ $(languagePluginTitle)$/icon
\end
<span class="tc-popup-keep">
<$button popup=<<qualify "$:/state/popup/language">> tooltip={{$:/language/Buttons/Language/Hint}} aria-label={{$:/language/Buttons/Language/Caption}} class=<<tv-config-toolbar-class>> selectedClass="tc-selected">
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
<$list filter="[<tv-config-toolbar-icons>prefix[yes]]">
<span class="tc-image-button">
<$set name="languagePluginTitle" value={{$:/language}}>
<$image source=<<flag-title>>/>
</$set>
</span>
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<$list filter="[<tv-config-toolbar-text>prefix[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/Language/Caption}}/></span>
</$list>
</$button>

View File

@@ -5,10 +5,10 @@ description: {{$:/language/Buttons/Manager/Hint}}
\define manager-button(class)
<$button to="$:/Manager" tooltip={{$:/language/Buttons/Manager/Hint}} aria-label={{$:/language/Buttons/Manager/Caption}} class="""$(tv-config-toolbar-class)$ $class$""">
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
<$list filter="[<tv-config-toolbar-icons>prefix[yes]]">
{{$:/core/images/list}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<$list filter="[<tv-config-toolbar-text>prefix[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/Manager/Caption}}/></span>
</$list>
</$button>

View File

@@ -7,10 +7,10 @@ description: {{$:/language/Buttons/More/Hint}}
$:/config/PageControlButtons/Visibility/$(listItem)$
\end
<$button popup=<<qualify "$:/state/popup/more">> tooltip={{$:/language/Buttons/More/Hint}} aria-label={{$:/language/Buttons/More/Caption}} class=<<tv-config-toolbar-class>> selectedClass="tc-selected">
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
<$list filter="[<tv-config-toolbar-icons>prefix[yes]]">
{{$:/core/images/down-arrow}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<$list filter="[<tv-config-toolbar-text>prefix[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/More/Caption}}/></span>
</$list>
</$button><$reveal state=<<qualify "$:/state/popup/more">> type="popup" position="below" animate="yes">

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