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

Compare commits

..

48 Commits

Author SHA1 Message Date
Jeremy Ruston
dd2df9f80f Move the international section into Quick Start 2023-10-17 11:28:43 +01:00
Jeremy Ruston
2f9eb9071c Update Chinese Community Content 2023-10-17 11:20:13 +01:00
Jeremy Ruston
8eec0d326a Fix Chinese translation
Thanks @linonetwo
2023-10-16 19:09:48 +01:00
Jeremy Ruston
94fd4ff09f Merge branch 'master' into international-communities 2023-10-16 19:08:31 +01:00
Jeremy Ruston
4d548580e6 Merge branch 'tiddlywiki-com' 2023-10-16 18:32:37 +01:00
lin onetwo
9773dff1e3 Chore: Add npm script for new core developers (#7539)
* Update package.json

* lint fix

* chore: use node ./tiddlywiki.js  instead of ./bin/serve.sh

* Update package.json

* Update package.json
2023-10-16 18:29:51 +01:00
Guang Li
c6604c0c56 Add floating popup to Dynannotate (#7790) 2023-10-16 18:21:26 +01:00
Jeremy Ruston
e521ee2133 Update release note 2023-10-16 12:27:56 +01:00
Guang Li
a7bd134c35 Docs: Add FSRS4TW plugin (#7770) 2023-10-16 12:23:22 +01:00
lin onetwo
d3f5695601 Fix: Evernote .enex image import (#7785)
* feat: add modifier info

* feat: replace image and attachment with [img[] and [[]]

* feat: import as wikitext tid

* fix: a few resources don't have title

* fix: use hash as random name for images

* fix: Firefox's DOMParser have problem in some cases

* fix: bad char in title, and useless xmlns

* Update sample-enex-with-image.xml.enex

* Update enex-deserializer.js

* Update readme.tid

* fix: some dont have modified
2023-10-15 12:40:38 +01:00
Simon Huber
efa4f34131 Update Basics.tid to not use fixed height in edit widgets (#7789) 2023-10-15 12:32:17 +01:00
Jeremy Ruston
fffbedd6b9 Updated release note 2023-10-14 10:25:16 +01:00
Jeremy Ruston
ff1437e439 Fix refreshing of transcluded functions (#7698)
* Passing test

* Failing test

* Fix test

It still fails, but now fails correctly

* Fix refreshing transcluded functions (#7755)

We store the previous result of the filter function and recalculate it
when the transclude widget needs to be refreshed, refreshing the widget
if the result is different.

---------

Co-authored-by: Jeremy Ruston <174761+Jermolene@users.noreply.github.com>
Co-authored-by: Robin Munn <rmunn@pobox.com>
2023-10-14 09:44:18 +01:00
Jeremy Ruston
32966c9e91 Introduce jsonset operator (#7742) 2023-10-14 09:43:23 +01:00
Jeremy Ruston
96b0543351 Add barcode reader widget to qrcode plugin (#7746)
* Add barcode reader widget to qrcode plugin

* Don't use a fixed ID
2023-10-14 09:42:34 +01:00
Jeremy Ruston
b7562f0c7b Conditional Shortcut Syntax (#7710)
* Initial Commit

* Update docs

* Add support for elseif blocks

* Another test

* WIP

* Change from `{%if%}` to `<%if%>`

See discussion here - https://talk.tiddlywiki.org/t/proposed-if-widget/7882/64

* Don't use the widget body as the template if a list-empty widget is present

See discussion here - https://github.com/Jermolene/TiddlyWiki5/pull/7710#issuecomment-1717193296

* List widget should search recursively for list-template and list-empty

* Allow block mode content within an if/then/else clause

* Update docs

* Add from-version tag to docs
2023-10-14 09:41:21 +01:00
Jeremy Ruston
4c9c85aec5 Add support for list-template and list-empty widgets for specifying list widget templates (#7784)
Cherry picked from #7710
2023-10-14 09:31:11 +01:00
Jeremy Ruston
8f50630695 Initial Commit 2023-10-12 10:28:53 +01:00
Maurycy Zarzycki
7726982d71 Polish Translations 2023-10-11 (#7779)
* Add translations introduced in 5bb8155422

* Add translations introduced in d17525ec8e
2023-10-11 21:07:49 +01:00
Jeremy Ruston
774058912d Update release note 2023-10-09 17:12:22 +01:00
Jeremy Ruston
106e1c68df Merge branch 'tiddlywiki-com' 2023-10-08 16:23:29 +01:00
Jeremy Ruston
12f42ad62f Add a summary for each release, and include in archive listing 2023-10-08 10:29:42 +01:00
Jeremy Ruston
66a8e2dbf2 Ensure {{}} doesn't generate a transclude widget with no attributes (#7768) 2023-10-07 21:55:39 +01:00
Jeremy Ruston
327ecf8f66 Don't refresh the body editor when switching the preview on and off (#7747)
* Don't refresh the body editor when switching the preview on and off

* Focus editor when switching the preview on or off
2023-10-06 21:49:02 +01:00
Mateusz Wilczek
35e45f3b90 Clean up after #7671 (Change favicon format from ICO to PNG) (#7774)
* Delete editions/tw5.com/tiddlers/_tw_shared/favicons/favicons.svg

* Delete editions/tw5.com/tiddlers/_tw_shared/favicons/favicons.svg.md
2023-10-06 21:39:43 +01:00
Jeremy Ruston
93bc9e4309 Merge branch 'tiddlywiki-com' 2023-10-05 22:29:45 +01:00
Jeremy Ruston
23b75bbc5d Add links to archived versions of TiddlyWiki
@pmario v5.3.0 and v5.3.1 are missing from the archive, would you be able to kindly prepare a PR?
2023-10-05 22:25:07 +01:00
Mateusz Wilczek
68da654eb3 Change favicon format from ICO to PNG, fix #7665 (#7671)
* Change favicon format from ICO to PNG

* Revert renaming `./favicon.ico`

Keep the backwards compatible file name `./favicon.ico` (though they will actually be in PNG format now).

* Add SVG template for creating favicons

Add `favicons.svg`, the template for creating the current PNG favicons, along with some helpful information about it in `favicons.svg.md`.

* Add source Inkscape SVG

Add source Inkscape SVG as an example of image tiddler in tw-com
2023-10-04 22:15:23 +01:00
Bram Chen
1eceb5f47f Update chinese language files (#7765)
* Improve consistency of naming file types and content types in some UI hints.
2023-10-04 18:25:10 +01:00
Timur
def508a220 Fix offline upgrade download link (#6088)
* Fix offline upgrade download link

In Firefox (92.0.1) `href="#"` does not allow to start downloading of `upgrade.html` (Chrome has no such problem). Making href completely empty fixes the issue.

* Update plugins/tiddlywiki/upgrade/UpgradeWizard.tid
2023-10-04 18:24:45 +01:00
Timur
3fb71e2553 Signing the CLA (#7766) 2023-10-04 18:24:14 +01:00
Mateusz Wilczek
d17525ec8e Improve file type names (TID, SVG, ICO) in hints (#7764)
* Make filetype names in hints consistent

* Make ICO content type hint more consistent
2023-10-03 21:37:49 +01:00
Joe Bordes
5bb8155422 i18n(ES) update to latest version changes (#7761) 2023-10-01 09:00:06 +01:00
Robin Munn
bb2973fc29 Make flexbox or grid layouts possible (#7690)
Both flexbox and grid layouts need the container div to be the direct
parent of the children it lays out. To enable that, we need a class that
can select the direct parent of the list widget in PageTemplate.tid so
that that class can have `display: flex` or `display: grid` applied to
it. The `tc-page-container` div is not suitable, because it contains
a `<$dropzone>` inside it, and the dropzone widget creates a div so
tc-page-container is no longer the direct parent of the list. Instead,
a tc-page-container-inner class is added to the dropzone widget in
addition to its existing tc-dropzone class, so that grid or flexbox
layouts can target tc-page-container-inner for setting the appropriate
CSS `display` property.
2023-09-30 16:33:40 +01:00
Jeremy Ruston
bbaa0890b5 Fix broken render commands
Fixes #7759
2023-09-30 13:30:31 +01:00
Mario Pietsch
b4a862c618 Fix #7757 vanilla styles should be first (#7758) 2023-09-28 14:59:50 +01:00
Jeremy Ruston
1be8f0a933 Comments plugin should use palette colours 2023-09-26 17:55:01 +01:00
lin onetwo
773c1f83f2 API for deleting core hooks (#7751)
* feat: Delete hooks from the hashmap

* fix: not using findIndex in the core

* Update HookMechanism.tid
2023-09-24 21:54:52 +01:00
Robin Munn
9ee1ef7e23 Fix a dangling link in filter run prefix docs (#7715)
One example was moved to another tiddler but its link wasn't updated to
follow it. This fixes the link to point to the example again.
2023-09-24 20:20:13 +01:00
Robin Munn
8effb3f218 Fix list widget bug with counter-last when appending items (#7712)
* Add failing test for list widget with counter-last

The failing test appends a value to a list without changing the rest of
the list, and the counter-last value doesn't get updated correctly when
that happens. Also added another test, which passes, testing removing
the last item of the list, just in case of a regression.

* Improve unit tests for counter-last list widget bug

The unit tests were looking very similar to each other, so I factored
out the common code and made them into simple data-driven tests.

* Fix bug where counter-last fails in list widget

The only scenario that was failing was when counter-last was used, but
the list was strictly appended to with no other changes made. The one
unit test that was failing now passes with this fix.

* Improve bugfix to list widget counter-last

Now we only refresh the last item if it was truly necessary.
2023-09-24 20:19:50 +01:00
Robin Munn
780e5d33a4 Slightly speed up [all[shadows+tiddlers]] filters (#7702)
The `all` filter operator has shortcuts to optimise common patterns like
`[all[shadows+tiddlers]]` or `[all[tiddlers]]`. In those cases, the
filter operator function returns early and never uses the `result`
linked list that was created, so it's immediately garbage-collected.
Let's delay creating it until we know it's actually going to be used.
2023-09-24 20:19:04 +01:00
Maurycy Zarzycki
526e997aa4 Add translation changes to Polish from e16635a5ad (#7752) 2023-09-22 19:11:15 +01:00
Jeremy Ruston
e4d8849f22 Merge branch 'tiddlywiki-com' 2023-09-21 18:17:28 +01:00
Jeremy Ruston
bd99cf3385 Docs: Clarify that whitespace trim is inherited by procedure and widget definitions 2023-09-21 18:11:54 +01:00
Simon Huber
711d1658e2 Edittemplate delete button should also delete the typeInputTiddler (#7749)
If we don't delete the typeInputTiddler with the click on the "delete" button then the dropdown stays filtered - but the text input seems to be empty. This PR corrects this behavior
2023-09-21 17:57:53 +01:00
Jeremy Ruston
b82f012c0c Revert "Make preview editor button focus the editor"
This reverts commit f383863654.
2023-09-19 16:08:13 +01:00
Jeremy Ruston
f383863654 Make preview editor button focus the editor 2023-09-19 16:07:52 +01:00
Mateusz Wilczek
697dc8db4c Improve jsonstringify and stringify operators docs (#7650) 2023-09-19 15:52:04 +01:00
226 changed files with 1834 additions and 267 deletions

View File

@@ -2674,6 +2674,18 @@ $tw.hooks.addHook = function(hookName,definition) {
}
};
/*
Delete hooks from the hashmap
*/
$tw.hooks.removeHook = function(hookName,definition) {
if($tw.utils.hop($tw.hooks.names,hookName)) {
var p = $tw.hooks.names[hookName].indexOf(definition);
if(p !== -1) {
$tw.hooks.names[hookName].splice(p, 1);
}
}
};
/*
Invoke the hook by key
*/

View File

@@ -3,4 +3,4 @@ title: $:/language/Exporters/
StaticRiver: Static HTML
JsonFile: JSON file
CsvFile: CSV file
TidFile: ".tid" file
TidFile: TID text file

View File

@@ -19,7 +19,7 @@ The following options are supported:
** ''yes'' will "explode" plugins into separate tiddler files and save them to the plugin directory within the wiki folder
** ''no'' will suppress exploding plugins into their constituent tiddler files. It will save the plugin as a single JSON tiddler in the tiddlers folder
Note that both ''explodePlugins'' options will produce wiki folders that build the same exact same original wiki. The difference lies in how plugins are represented in the wiki folder.
Note that both ''explodePlugins'' options will produce wiki folders that build the exact same original wiki. The difference lies in how plugins are represented in the wiki folder.
A common usage is to convert a TiddlyWiki HTML file into a wiki folder:
@@ -31,4 +31,4 @@ Save the plugin to the tiddlers directory of the target wiki folder:
```
tiddlywiki --load ./mywiki.html --savewikifolder ./mywikifolder explodePlugins=no
```
```

View File

@@ -1,5 +1,5 @@
title: $:/language/Docs/Types/image/svg+xml
description: Structured Vector Graphics image
description: SVG image
name: image/svg+xml
group: Image
group-sort: 1

View File

@@ -1,5 +1,5 @@
title: $:/language/Docs/Types/image/x-icon
description: ICO format icon file
description: ICO icon
name: image/x-icon
group: Image
group-sort: 1

View File

@@ -28,12 +28,8 @@ function getAllFilterOperators() {
Export our filter function
*/
exports.all = function(source,operator,options) {
// Get our suboperators
var allFilterOperators = getAllFilterOperators();
// Cycle through the suboperators accumulating their results
var results = new $tw.utils.LinkedList(),
subops = operator.operand.split("+");
// Check for common optimisations
var subops = operator.operand.split("+");
if(subops.length === 1 && subops[0] === "") {
return source;
} else if(subops.length === 1 && subops[0] === "tiddlers") {
@@ -46,6 +42,10 @@ exports.all = function(source,operator,options) {
return options.wiki.eachShadowPlusTiddlers;
}
// Do it the hard way
// Get our suboperators
var allFilterOperators = getAllFilterOperators();
// Cycle through the suboperators accumulating their results
var results = new $tw.utils.LinkedList();
for(var t=0; t<subops.length; t++) {
var subop = allFilterOperators[subops[t]];
if(subop) {

View File

@@ -68,6 +68,54 @@ exports["jsontype"] = function(source,operator,options) {
return results;
};
exports["jsonset"] = function(source,operator,options) {
var suffixes = operator.suffixes || [],
type = suffixes[0] && suffixes[0][0],
indexes = operator.operands.slice(0,-1),
value = operator.operands[operator.operands.length - 1],
results = [];
if(operator.operands.length === 1 && operator.operands[0] === "") {
value = undefined; // Prevents the value from being assigned
}
switch(type) {
case "string":
// Use value unchanged
break;
case "boolean":
value = (value === "true" ? true : (value === "false" ? false : undefined));
break;
case "number":
value = $tw.utils.parseNumber(value);
break;
case "array":
indexes = operator.operands;
value = [];
break;
case "object":
indexes = operator.operands;
value = {};
break;
case "null":
indexes = operator.operands;
value = null;
break;
case "json":
value = $tw.utils.parseJSONSafe(value,function() {return undefined;});
break;
default:
// Use value unchanged
break;
}
source(function(tiddler,title) {
var data = $tw.utils.parseJSONSafe(title,title);
if(data) {
data = setDataItem(data,indexes,value);
results.push(JSON.stringify(data));
}
});
return results;
};
/*
Given a JSON data structure and an array of index strings, return an array of the string representation of the values at the end of the index chain, or "undefined" if any of the index strings are invalid
*/
@@ -186,5 +234,34 @@ function getDataItem(data,indexes) {
return item;
}
/*
Given a JSON data structure, an array of index strings and a value, return the data structure with the value added at the end of the index chain. If any of the index strings are invalid then the JSON data structure is returned unmodified. If the root item is targetted then a different data object will be returned
*/
function setDataItem(data,indexes,value) {
// Ignore attempts to assign undefined
if(value === undefined) {
return data;
}
// Check for the root item
if(indexes.length === 0 || (indexes.length === 1 && indexes[0] === "")) {
return value;
}
// Traverse the JSON data structure using the index chain
var current = data;
for(var i = 0; i < indexes.length - 1; i++) {
var index = indexes[i];
if($tw.utils.hop(current,index)) {
current = current[index];
} else {
// Return the original JSON data structure if any of the index strings are invalid
return data;
}
}
// Add the value to the end of the index chain
var lastIndex = indexes[indexes.length - 1];
current[lastIndex] = value;
return data;
}
})();

View File

@@ -0,0 +1,120 @@
/*\
title: $:/core/modules/parsers/wikiparser/rules/conditional.js
type: application/javascript
module-type: wikirule
Conditional shortcut syntax
```
This is a <% if [{something}] %>Elephant<% elseif [{else}] %>Pelican<% else %>Crocodile<% endif %>
```
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
exports.name = "conditional";
exports.types = {inline: true, block: true};
exports.init = function(parser) {
this.parser = parser;
// Regexp to match
this.matchRegExp = /\<\%\s*if\s+/mg;
this.terminateIfRegExp = /\%\>/mg;
};
exports.findNextMatch = function(startPos) {
// Look for the next <% if shortcut
this.matchRegExp.lastIndex = startPos;
this.match = this.matchRegExp.exec(this.parser.source);
// If not found then return no match
if(!this.match) {
return undefined;
}
// Check for the next %>
this.terminateIfRegExp.lastIndex = this.match.index;
this.terminateIfMatch = this.terminateIfRegExp.exec(this.parser.source);
// If not found then return no match
if(!this.terminateIfMatch) {
return undefined;
}
// Return the position at which the construction was found
return this.match.index;
};
/*
Parse the most recent match
*/
exports.parse = function() {
// Get the filter condition
var filterCondition = this.parser.source.substring(this.match.index + this.match[0].length,this.terminateIfMatch.index);
// Advance the parser position to past the %>
this.parser.pos = this.terminateIfMatch.index + this.terminateIfMatch[0].length;
// Parse the if clause
return this.parseIfClause(filterCondition);
};
exports.parseIfClause = function(filterCondition) {
// Create the list widget
var listWidget = {
type: "list",
tag: "$list",
isBlock: this.is.block,
children: [
{
type: "list-template",
tag: "$list-template"
},
{
type: "list-empty",
tag: "$list-empty"
}
]
};
$tw.utils.addAttributeToParseTreeNode(listWidget,"filter",filterCondition);
$tw.utils.addAttributeToParseTreeNode(listWidget,"variable","condition");
$tw.utils.addAttributeToParseTreeNode(listWidget,"limit","1");
// Check for an immediately following double linebreak
var hasLineBreak = !!$tw.utils.parseTokenRegExp(this.parser.source,this.parser.pos,/([^\S\n\r]*\r?\n(?:[^\S\n\r]*\r?\n|$))/g);
// Parse the body looking for else or endif
var reEndString = "\\<\\%\\s*(endif)\\s*\\%\\>|\\<\\%\\s*(else)\\s*\\%\\>|\\<\\%\\s*(elseif)\\s+([\\s\\S]+?)\\%\\>",
ex;
if(hasLineBreak) {
ex = this.parser.parseBlocksTerminatedExtended(reEndString);
} else {
var reEnd = new RegExp(reEndString,"mg");
ex = this.parser.parseInlineRunTerminatedExtended(reEnd,{eatTerminator: true});
}
// Put the body into the list template
listWidget.children[0].children = ex.tree;
// Check for an else or elseif
if(ex.match) {
if(ex.match[1] === "endif") {
// Nothing to do if we just found an endif
} else if(ex.match[2] === "else") {
// Check for an immediately following double linebreak
hasLineBreak = !!$tw.utils.parseTokenRegExp(this.parser.source,this.parser.pos,/([^\S\n\r]*\r?\n(?:[^\S\n\r]*\r?\n|$))/g);
// If we found an else then we need to parse the body looking for the endif
var reEndString = "\\<\\%\\s*(endif)\\s*\\%\\>",
ex;
if(hasLineBreak) {
ex = this.parser.parseBlocksTerminatedExtended(reEndString);
} else {
var reEnd = new RegExp(reEndString,"mg");
ex = this.parser.parseInlineRunTerminatedExtended(reEnd,{eatTerminator: true});
}
// Put the parsed content inside the list empty template
listWidget.children[1].children = ex.tree;
} else if(ex.match[3] === "elseif") {
// Parse the elseif clause by reusing this parser, passing the new filter condition
listWidget.children[1].children = this.parseIfClause(ex.match[4]);
}
}
// Return the parse tree node
return [listWidget];
};
})();

View File

@@ -81,6 +81,9 @@ exports.parse = function() {
}
return [tiddlerNode];
} else {
// No template or text reference is provided, so we'll use a blank target. Otherwise we'll generate
// a transclude widget that transcludes the current tiddler, often leading to recursion errors
transcludeNode.attributes["$tiddler"] = {name: "$tiddler", type: "string", value: ""};
return [transcludeNode];
}
}

View File

@@ -79,6 +79,9 @@ exports.parse = function() {
}
return [tiddlerNode];
} else {
// No template or text reference is provided, so we'll use a blank target. Otherwise we'll generate
// a transclude widget that transcludes the current tiddler, often leading to recursion errors
transcludeNode.attributes["$tiddler"] = {name: "$tiddler", type: "string", value: ""};
return [transcludeNode];
}
}

View File

@@ -223,7 +223,7 @@ Parse a block from the current position
terminatorRegExpString: optional regular expression string that identifies the end of plain paragraphs. Must not include capturing parenthesis
*/
WikiParser.prototype.parseBlock = function(terminatorRegExpString) {
var terminatorRegExp = terminatorRegExpString ? new RegExp("(" + terminatorRegExpString + "|\\r?\\n\\r?\\n)","mg") : /(\r?\n\r?\n)/mg;
var terminatorRegExp = terminatorRegExpString ? new RegExp(terminatorRegExpString + "|\\r?\\n\\r?\\n","mg") : /(\r?\n\r?\n)/mg;
this.skipWhitespace();
if(this.pos >= this.sourceLength) {
return [];
@@ -264,11 +264,21 @@ WikiParser.prototype.parseBlocksUnterminated = function() {
};
/*
Parse blocks of text until a terminating regexp is encountered
Parse blocks of text until a terminating regexp is encountered. Wrapper for parseBlocksTerminatedExtended that just returns the parse tree
*/
WikiParser.prototype.parseBlocksTerminated = function(terminatorRegExpString) {
var terminatorRegExp = new RegExp("(" + terminatorRegExpString + ")","mg"),
tree = [];
var ex = this.parseBlocksTerminatedExtended(terminatorRegExpString);
return ex.tree;
};
/*
Parse blocks of text until a terminating regexp is encountered
*/
WikiParser.prototype.parseBlocksTerminatedExtended = function(terminatorRegExpString) {
var terminatorRegExp = new RegExp(terminatorRegExpString,"mg"),
result = {
tree: []
};
// Skip any whitespace
this.skipWhitespace();
// Check if we've got the end marker
@@ -277,7 +287,7 @@ WikiParser.prototype.parseBlocksTerminated = function(terminatorRegExpString) {
// Parse the text into blocks
while(this.pos < this.sourceLength && !(match && match.index === this.pos)) {
var blocks = this.parseBlock(terminatorRegExpString);
tree.push.apply(tree,blocks);
result.tree.push.apply(result.tree,blocks);
// Skip any whitespace
this.skipWhitespace();
// Check if we've got the end marker
@@ -286,8 +296,9 @@ WikiParser.prototype.parseBlocksTerminated = function(terminatorRegExpString) {
}
if(match && match.index === this.pos) {
this.pos = match.index + match[0].length;
result.match = match;
}
return tree;
return result;
};
/*
@@ -330,6 +341,11 @@ WikiParser.prototype.parseInlineRunUnterminated = function(options) {
};
WikiParser.prototype.parseInlineRunTerminated = function(terminatorRegExp,options) {
var ex = this.parseInlineRunTerminatedExtended(terminatorRegExp,options);
return ex.tree;
};
WikiParser.prototype.parseInlineRunTerminatedExtended = function(terminatorRegExp,options) {
options = options || {};
var tree = [];
// Find the next occurrence of the terminator
@@ -349,7 +365,10 @@ WikiParser.prototype.parseInlineRunTerminated = function(terminatorRegExp,option
if(options.eatTerminator) {
this.pos += terminatorMatch[0].length;
}
return tree;
return {
match: terminatorMatch,
tree: tree
};
}
}
// Process any inline rule, along with the text preceding it
@@ -373,7 +392,9 @@ WikiParser.prototype.parseInlineRunTerminated = function(terminatorRegExp,option
this.pushTextWidget(tree,this.source.substr(this.pos),this.pos,this.sourceLength);
}
this.pos = this.sourceLength;
return tree;
return {
tree: tree
};
};
/*

View File

@@ -60,6 +60,7 @@ ListWidget.prototype.render = function(parent,nextSibling) {
Compute the internal state of the widget
*/
ListWidget.prototype.execute = function() {
var self = this;
// Get our attributes
this.template = this.getAttribute("template");
this.editTemplate = this.getAttribute("editTemplate");
@@ -67,6 +68,8 @@ ListWidget.prototype.execute = function() {
this.counterName = this.getAttribute("counter");
this.storyViewName = this.getAttribute("storyview");
this.historyTitle = this.getAttribute("history");
// Look for <$list-template> and <$list-empty> widgets as immediate child widgets
this.findExplicitTemplates();
// Compose the list elements
this.list = this.getTiddlerList();
var members = [],
@@ -85,18 +88,48 @@ ListWidget.prototype.execute = function() {
this.history = [];
};
ListWidget.prototype.findExplicitTemplates = function() {
var self = this;
this.explicitListTemplate = null;
this.explicitEmptyTemplate = null;
var searchChildren = function(childNodes) {
$tw.utils.each(childNodes,function(node) {
if(node.type === "list-template") {
self.explicitListTemplate = node.children;
} else if(node.type === "list-empty") {
self.explicitEmptyTemplate = node.children;
} else if(node.type === "element" && node.tag === "p") {
searchChildren(node.children);
}
});
};
searchChildren(this.parseTreeNode.children);
}
ListWidget.prototype.getTiddlerList = function() {
var limit = $tw.utils.getInt(this.getAttribute("limit",""),undefined);
var defaultFilter = "[!is[system]sort[title]]";
return this.wiki.filterTiddlers(this.getAttribute("filter",defaultFilter),this);
var results = this.wiki.filterTiddlers(this.getAttribute("filter",defaultFilter),this);
if(limit !== undefined) {
if(limit >= 0) {
results = results.slice(0,limit);
} else {
results = results.slice(limit);
}
}
return results;
};
ListWidget.prototype.getEmptyMessage = function() {
var parser,
emptyMessage = this.getAttribute("emptyMessage","");
// this.wiki.parseText() calls
// new Parser(..), which should only be done, if needed, because it's heavy!
if (emptyMessage === "") {
return [];
emptyMessage = this.getAttribute("emptyMessage");
// If emptyMessage attribute is not present or empty then look for an explicit empty template
if(!emptyMessage) {
if(this.explicitEmptyTemplate) {
return this.explicitEmptyTemplate;
} else {
return [];
}
}
parser = this.wiki.parseText("text/vnd.tiddlywiki",emptyMessage,{parseAsInline: true});
if(parser) {
@@ -122,12 +155,19 @@ ListWidget.prototype.makeItemTemplate = function(title,index) {
if(template) {
templateTree = [{type: "transclude", attributes: {tiddler: {type: "string", value: template}}}];
} else {
// Check for child nodes of the list widget
if(this.parseTreeNode.children && this.parseTreeNode.children.length > 0) {
templateTree = this.parseTreeNode.children;
} else {
// Check for a <$list-item> widget
if(this.explicitListTemplate) {
templateTree = this.explicitListTemplate;
} else if (!this.explicitEmptyTemplate) {
templateTree = this.parseTreeNode.children;
}
}
if(!templateTree) {
// Default template is a link to the title
templateTree = [{type: "element", tag: this.parseTreeNode.isBlock ? "div" : "span", children: [{type: "link", attributes: {to: {type: "string", value: title}}, children: [
{type: "text", text: title}
{type: "text", text: title}
]}]}];
}
}
@@ -225,6 +265,8 @@ ListWidget.prototype.handleListChanges = function(changedTiddlers) {
// If we are providing an counter variable then we must refresh the items, otherwise we can rearrange them
var hasRefreshed = false,t;
if(this.counterName) {
var mustRefreshOldLast = false;
var oldLength = this.children.length;
// Cycle through the list and remove and re-insert the first item that has changed, and all the remaining items
for(t=0; t<this.list.length; t++) {
if(hasRefreshed || !this.children[t] || this.children[t].parseTreeNode.itemTitle !== this.list[t]) {
@@ -232,6 +274,9 @@ ListWidget.prototype.handleListChanges = function(changedTiddlers) {
this.removeListItem(t);
}
this.insertListItem(t,this.list[t]);
if(!hasRefreshed && t === oldLength) {
mustRefreshOldLast = true;
}
hasRefreshed = true;
} else {
// Refresh the item we're reusing
@@ -239,6 +284,12 @@ ListWidget.prototype.handleListChanges = function(changedTiddlers) {
hasRefreshed = hasRefreshed || refreshed;
}
}
// If items were inserted then we must recreate the item that used to be at the last position as it is no longer last
if(mustRefreshOldLast && oldLength > 0) {
var oldLastIdx = oldLength-1;
this.removeListItem(oldLastIdx);
this.insertListItem(oldLastIdx,this.list[oldLastIdx]);
}
// If there are items to remove and we have not refreshed then recreate the item that will now be at the last position
if(!hasRefreshed && this.children.length > this.list.length) {
this.removeListItem(this.list.length-1);

View File

@@ -109,6 +109,7 @@ TranscludeWidget.prototype.collectAttributes = function() {
this.recursionMarker = this.getAttribute("recursionMarker","yes");
} else {
this.transcludeVariable = this.getAttribute("$variable");
this.transcludeVariableIsFunction = false;
this.transcludeType = this.getAttribute("$type");
this.transcludeOutput = this.getAttribute("$output","text/html");
this.transcludeTitle = this.getAttribute("$tiddler",this.getVariable("currentTiddler"));
@@ -184,7 +185,9 @@ TranscludeWidget.prototype.getTransclusionTarget = function() {
if(this.transcludeVariable) {
// Transcluding a variable
var variableInfo = this.getVariableInfo(this.transcludeVariable,{params: this.getOrderedTransclusionParameters()});
this.transcludeVariableIsFunction = variableInfo.srcVariable && variableInfo.srcVariable.isFunctionDefinition;
text = variableInfo.text;
this.transcludeFunctionResult = text;
return {
text: variableInfo.text,
type: this.transcludeType
@@ -219,21 +222,24 @@ TranscludeWidget.prototype.parseTransclusionTarget = function(parseAsInline) {
// Transcluding a variable
var variableInfo = this.getVariableInfo(this.transcludeVariable,{params: this.getOrderedTransclusionParameters()}),
srcVariable = variableInfo && variableInfo.srcVariable;
if(srcVariable && srcVariable.isFunctionDefinition) {
this.transcludeVariableIsFunction = true;
this.transcludeFunctionResult = (variableInfo.resultList ? variableInfo.resultList[0] : variableInfo.text) || "";
}
if(variableInfo.text) {
if(srcVariable && srcVariable.isFunctionDefinition) {
var result = (variableInfo.resultList ? variableInfo.resultList[0] : variableInfo.text) || "";
parser = {
tree: [{
type: "text",
text: result
text: this.transcludeFunctionResult
}],
source: result,
source: this.transcludeFunctionResult,
type: "text/vnd.tiddlywiki"
};
if(parseAsInline) {
parser.tree[0] = {
type: "text",
text: result
text: this.transcludeFunctionResult
};
} else {
parser.tree[0] = {
@@ -241,7 +247,7 @@ TranscludeWidget.prototype.parseTransclusionTarget = function(parseAsInline) {
tag: "p",
children: [{
type: "text",
text: result
text: this.transcludeFunctionResult
}]
}
}
@@ -430,12 +436,19 @@ TranscludeWidget.prototype.parserNeedsRefresh = function() {
return (this.sourceText === undefined || parserInfo.sourceText !== this.sourceText || parserInfo.parserType !== this.parserType)
};
TranscludeWidget.prototype.functionNeedsRefresh = function() {
var oldResult = this.transcludeFunctionResult;
var variableInfo = this.getVariableInfo(this.transcludeVariable,{params: this.getOrderedTransclusionParameters()});
var newResult = (variableInfo.resultList ? variableInfo.resultList[0] : variableInfo.text) || "";
return oldResult !== newResult;
}
/*
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/
TranscludeWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(($tw.utils.count(changedAttributes) > 0) || (!this.transcludeVariable && changedTiddlers[this.transcludeTitle] && this.parserNeedsRefresh())) {
if(($tw.utils.count(changedAttributes) > 0) || (this.transcludeVariableIsFunction && this.functionNeedsRefresh()) || (!this.transcludeVariable && changedTiddlers[this.transcludeTitle] && this.parserNeedsRefresh())) {
this.refreshSelf();
return true;
} else {

View File

@@ -26,10 +26,10 @@ caption: {{$:/language/ControlPanel/Basics/Caption}}
|<$link to="$:/SiteSubtitle"><<lingo Subtitle/Prompt>></$link> |<$edit-text tiddler="$:/SiteSubtitle" default="" tag="input"/> |
|<$link to="$:/status/UserName"><<lingo Username/Prompt>></$link> |<$edit-text tiddler="$:/status/UserName" default="" tag="input"/> |
|<$link to="$:/config/AnimationDuration"><<lingo AnimDuration/Prompt>></$link> |<$edit-text tiddler="$:/config/AnimationDuration" default="" tag="input"/> |
|<$link to="$:/DefaultTiddlers"><<lingo DefaultTiddlers/Prompt>></$link> |<<lingo DefaultTiddlers/TopHint>><br> <$edit class="tc-edit-texteditor" tiddler="$:/DefaultTiddlers"/><br>//<<lingo DefaultTiddlers/BottomHint>>// |
|<$link to="$:/DefaultTiddlers"><<lingo DefaultTiddlers/Prompt>></$link> |<<lingo DefaultTiddlers/TopHint>><br> <$edit class="tc-edit-texteditor" tiddler="$:/DefaultTiddlers" autoHeight="yes"/><br>//<<lingo DefaultTiddlers/BottomHint>>// |
|<$link to="$:/language/DefaultNewTiddlerTitle"><<lingo NewTiddler/Title/Prompt>></$link> |<$edit-text tiddler="$:/language/DefaultNewTiddlerTitle" default="" tag="input"/> |
|<$link to="$:/config/NewJournal/Title"><<lingo NewJournal/Title/Prompt>></$link> |<$edit-text tiddler="$:/config/NewJournal/Title" default="" tag="input"/> |
|<$link to="$:/config/NewJournal/Text"><<lingo NewJournal/Text/Prompt>></$link> |<$edit tiddler="$:/config/NewJournal/Text" class="tc-edit-texteditor" default=""/> |
|<$link to="$:/config/NewJournal/Text"><<lingo NewJournal/Text/Prompt>></$link> |<$edit tiddler="$:/config/NewJournal/Text" class="tc-edit-texteditor" default="" autoHeight="yes"/> |
|<$link to="$:/config/NewTiddler/Tags"><<lingo NewTiddler/Tags/Prompt>></$link> |<$vars currentTiddler="$:/config/NewTiddler/Tags" tagField="text">{{||$:/core/ui/EditTemplate/tags}}<$list filter="[<currentTiddler>tags[]] +[limit[1]]" variable="ignore"><$button tooltip={{$:/language/ControlPanel/Basics/RemoveTags/Hint}}><<lingo RemoveTags>><$action-listops $tiddler=<<currentTiddler>> $field="text" $subfilter={{{ [<currentTiddler>get[tags]] }}}/><$action-setfield $tiddler=<<currentTiddler>> tags=""/></$button></$list></$vars> |
|<$link to="$:/config/NewJournal/Tags"><<lingo NewJournal/Tags/Prompt>></$link> |<$vars currentTiddler="$:/config/NewJournal/Tags" tagField="text">{{||$:/core/ui/EditTemplate/tags}}<$list filter="[<currentTiddler>tags[]] +[limit[1]]" variable="ignore"><$button tooltip={{$:/language/ControlPanel/Basics/RemoveTags/Hint}}><<lingo RemoveTags>><$action-listops $tiddler=<<currentTiddler>> $field="text" $subfilter={{{ [<currentTiddler>get[tags]] }}}/><$action-setfield $tiddler=<<currentTiddler>> tags=""/></$button></$list></$vars> |
|<$link to="$:/config/AutoFocus"><<lingo AutoFocus/Prompt>></$link> |{{$:/snippets/minifocusswitcher}} |

View File

@@ -1,5 +1,9 @@
title: $:/core/ui/EditTemplate/body/default
\function edit-preview-state()
[{$:/config/ShowEditPreview/PerTiddler}!match[yes]then[$:/state/showeditpreview]] :else[<qualify "$:/state/showeditpreview">] +[get[text]] :else[[no]]
\end
\define config-visibility-title()
$:/config/EditorToolbarButtons/Visibility/$(currentTiddler)$
\end
@@ -10,15 +14,16 @@ $:/config/EditorToolbarButtons/Visibility/$(currentTiddler)$
\whitespace trim
<$let
edit-preview-state={{{ [{$:/config/ShowEditPreview/PerTiddler}!match[yes]then[$:/state/showeditpreview]] :else[<qualify "$:/state/showeditpreview">] }}}
importTitle=<<qualify $:/ImportImage>>
importState=<<qualify $:/state/ImportImage>> >
<$dropzone importTitle=<<importTitle>> autoOpenOnImport="no" contentTypesFilter={{$:/config/Editor/ImportContentTypesFilter}} class="tc-dropzone-editor" enable={{{ [{$:/config/DragAndDrop/Enable}match[no]] :else[subfilter{$:/config/Editor/EnableImportFilter}then[yes]else[no]] }}} filesOnly="yes" actions=<<importFileActions>> >
<$reveal stateTitle=<<edit-preview-state>> type="match" text="yes" tag="div">
<div class="tc-tiddler-preview">
<div>
<div class={{{ [function[edit-preview-state]match[yes]then[tc-tiddler-preview]] +[join[ ]] }}}>
<$transclude tiddler="$:/core/ui/EditTemplate/body/editor" mode="inline"/>
<$list filter="[function[edit-preview-state]match[yes]]" variable="ignore">
<div class="tc-tiddler-preview-preview" data-tiddler-title={{!!draft.title}} data-tags={{!!tags}}>
<$transclude tiddler={{$:/state/editpreviewtype}} mode="inline">
@@ -29,13 +34,12 @@ $:/config/EditorToolbarButtons/Visibility/$(currentTiddler)$
</div>
</$list>
</div>
</$reveal>
<$reveal stateTitle=<<edit-preview-state>> type="nomatch" text="yes" tag="div">
</div>
<$transclude tiddler="$:/core/ui/EditTemplate/body/editor" mode="inline"/>
</$reveal>
</$dropzone>
</$let>

View File

@@ -10,7 +10,7 @@ first-search-filter: [all[shadows+tiddlers]prefix[$:/language/Docs/Types/]sort[d
<em class="tc-edit tc-small-gap-right"><<lingo Type/Prompt>></em>
<div class="tc-type-selector-dropdown-wrapper">
<div class="tc-type-selector"><$fieldmangler>
<$macrocall $name="keyboard-driven-input" tiddler=<<currentTiddler>> storeTitle=<<typeInputTiddler>> refreshTitle=<<refreshTitle>> selectionStateTitle=<<typeSelectionTiddler>> field="type" tag="input" default="" placeholder={{$:/language/EditTemplate/Type/Placeholder}} focusPopup=<<qualify "$:/state/popup/type-dropdown">> class="tc-edit-typeeditor tc-edit-texteditor tc-popup-handle" tabindex={{$:/config/EditTabIndex}} focus={{{ [{$:/config/AutoFocus}match[type]then[true]] ~[[false]] }}} cancelPopups="yes" configTiddlerFilter="[[$:/core/ui/EditTemplate/type]]" inputCancelActions=<<input-cancel-actions>>/><$button popup=<<qualify "$:/state/popup/type-dropdown">> class="tc-btn-invisible tc-btn-dropdown tc-small-gap" tooltip={{$:/language/EditTemplate/Type/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Type/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button><$button message="tm-remove-field" param="type" class="tc-btn-invisible tc-btn-icon" tooltip={{$:/language/EditTemplate/Type/Delete/Hint}} aria-label={{$:/language/EditTemplate/Type/Delete/Caption}}>{{$:/core/images/delete-button}}<$action-deletetiddler $filter="[<storeTitle>] [<refreshTitle>] [<selectionStateTitle>]"/></$button>
<$macrocall $name="keyboard-driven-input" tiddler=<<currentTiddler>> storeTitle=<<typeInputTiddler>> refreshTitle=<<refreshTitle>> selectionStateTitle=<<typeSelectionTiddler>> field="type" tag="input" default="" placeholder={{$:/language/EditTemplate/Type/Placeholder}} focusPopup=<<qualify "$:/state/popup/type-dropdown">> class="tc-edit-typeeditor tc-edit-texteditor tc-popup-handle" tabindex={{$:/config/EditTabIndex}} focus={{{ [{$:/config/AutoFocus}match[type]then[true]] ~[[false]] }}} cancelPopups="yes" configTiddlerFilter="[[$:/core/ui/EditTemplate/type]]" inputCancelActions=<<input-cancel-actions>>/><$button popup=<<qualify "$:/state/popup/type-dropdown">> class="tc-btn-invisible tc-btn-dropdown tc-small-gap" tooltip={{$:/language/EditTemplate/Type/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Type/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button><$button message="tm-remove-field" param="type" class="tc-btn-invisible tc-btn-icon" tooltip={{$:/language/EditTemplate/Type/Delete/Hint}} aria-label={{$:/language/EditTemplate/Type/Delete/Caption}}>{{$:/core/images/delete-button}}<$action-deletetiddler $filter="[<typeInputTiddler>] [<storeTitle>] [<refreshTitle>] [<selectionStateTitle>]"/></$button>
</$fieldmangler></div>
<div class="tc-block-dropdown-wrapper">

View File

@@ -9,11 +9,17 @@ button-classes: tc-text-editor-toolbar-item-start-group
shortcuts: ((preview))
\whitespace trim
<$let
edit-preview-state={{{ [{$:/config/ShowEditPreview/PerTiddler}!match[yes]then[$:/state/showeditpreview]] :else[<qualify "$:/state/showeditpreview">] }}}
>
<$reveal state=<<edit-preview-state>> type="match" text="yes" tag="span">
{{$:/core/images/preview-open}}
<$action-setfield $tiddler=<<edit-preview-state>> $value="no"/>
<$action-sendmessage $message="tm-edit-text-operation" $param="focus-editor"/>
</$reveal>
<$reveal state=<<edit-preview-state>> type="nomatch" text="yes" tag="span">
{{$:/core/images/preview-closed}}
<$action-setfield $tiddler=<<edit-preview-state>> $value="yes"/>
<$action-sendmessage $message="tm-edit-text-operation" $param="focus-editor"/>
</$reveal>
</$let>

View File

@@ -20,7 +20,7 @@ code-body: yes
<$navigator story="$:/StoryList" history="$:/HistoryList" openLinkFromInsideRiver={{$:/config/Navigation/openLinkFromInsideRiver}} openLinkFromOutsideRiver={{$:/config/Navigation/openLinkFromOutsideRiver}} relinkOnRename={{$:/config/RelinkOnRename}}>
<$dropzone enable=<<tv-enable-drag-and-drop>>>
<$dropzone enable=<<tv-enable-drag-and-drop>> class="tc-dropzone tc-page-container-inner">
<$list filter="[all[shadows+tiddlers]tag[$:/tags/PageTemplate]!has[draft.of]]" variable="listItem">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

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

View File

@@ -1,9 +1,14 @@
created: 20141122200310516
modified: 20201213161842776
modified: 20230923031318421
tags: Mechanisms
title: HookMechanism
type: text/vnd.tiddlywiki
The hook mechanism provides a way for plugins to intercept and modify default functionality. Hooks are added as follows:
The hook mechanism provides a way for plugins to intercept and modify default functionality.
!! Add a hook
Hooks are added as follows:
```js
/*
@@ -13,6 +18,8 @@ handler: function to be called when hook is invoked
$tw.hooks.addHook(name,handler);
```
!!! Params and return
The handler function will be called with parameters that depend on the specific hook in question, but they always follow the pattern `handler(value,params...)`
* ''value'': an optional value that is to be transformed by the hook function
@@ -20,11 +27,29 @@ The handler function will be called with parameters that depend on the specific
If required by the hook in question, the handler function must return the modified ''value''.
!!! Multiple handlers
Multiple handlers can be assigned to the same name using repeated calls. When a hook is invoked by name all registered functions will be called sequentially in their order of addition.
Note that the ''value'' passed to the subsequent hook function will be the return value of the previous hook function.
Though not essential care should be taken to ensure that hooks are added before they are invoked. For example: [[Hook: th-opening-default-tiddlers-list]] should ideally be added before the story startup module is invoked otherwise any hook specified additions to the default tiddlers will not be seen on the initial loading of the page, though will be visible if the user clicks the home button.
Be careful not to `addHook` in widget's `render` method, which will be call several times. You could `addHook` in methods that only called once, e.g. the constructor of widget class. Otherwise you should `removeHook` then add it again.
!!! Timing of registration
Though not essential care should be taken to ensure that hooks are added before they are invoked.
For example: [[Hook: th-opening-default-tiddlers-list]] should ideally be added before the story startup module is invoked. Otherwise any hook specified additions to the default tiddlers will not be seen on the initial loading of the page, though will be visible if the user clicks the home button.
!! Remove a hook
You should clean up the callback when your widget is going to unmount.
```js
$tw.hooks.removeHook(handler)
```
The `handler` should be the same function instance you used in `addHook` (check by `===`). You can save it to `this.xxxHookHandler` on your widget, and call `removeHook` in [[destroy method|Widget `destroy` method examples]].
!! Example

View File

@@ -23,7 +23,7 @@
"static": [
"--render","$:/core/templates/static.template.html","static.html","text/plain",
"--render","$:/core/templates/alltiddlers.template.html","alltiddlers.html","text/plain",
"--render","[!is[system]]","[encodeuricomponent[]addprefix[static/]addsuffix[.html]]","text/plain",
"--render","[!is[system]]","[encodeuricomponent[]addprefix[static/]addsuffix[.html]]","text/plain","$:/core/templates/static.tiddler.html",
"--render","$:/core/templates/static.template.css","static/static.css","text/plain"]
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

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

View File

@@ -15,7 +15,7 @@
"static": [
"--render","$:/core/templates/static.template.html","static.html","text/plain",
"--render","$:/core/templates/alltiddlers.template.html","alltiddlers.html","text/plain",
"--render","[!is[system]]","[encodeuricomponent[]addprefix[static/]addsuffix[.html]]","text/plain",
"--render","[!is[system]]","[encodeuricomponent[]addprefix[static/]addsuffix[.html]]","text/plain","$:/core/templates/static.tiddler.html",
"--render","$:/core/templates/static.template.css","static/static.css","text/plain"]
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

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

View File

@@ -15,7 +15,7 @@
"static": [
"--render","$:/core/templates/static.template.html","static.html","text/plain",
"--render","$:/core/templates/alltiddlers.template.html","alltiddlers.html","text/plain",
"--render","[!is[system]]","[encodeuricomponent[]addprefix[static/]addsuffix[.html]]","text/plain",
"--render","[!is[system]]","[encodeuricomponent[]addprefix[static/]addsuffix[.html]]","text/plain","$:/core/templates/static.tiddler.html",
"--render","$:/core/templates/static.template.css","static/static.css","text/plain"]
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

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

View File

@@ -1,37 +1,105 @@
caption: 5.3.2
created: 20230820114855583
modified: 20230820114855583
created: 20231016122502955
modified: 20231016122502955
tags: ReleaseNotes
title: Release 5.3.2
type: text/vnd.tiddlywiki
description: Under development
//[[See GitHub for detailed change history of this release|https://github.com/Jermolene/TiddlyWiki5/compare/v5.3.1...master]]//
! Major Improvements
!! Conditional Shortcut Syntax
<<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/7710">> a new [[shortcut syntax|Conditional Shortcut Syntax]] for concisely expressing if-then-else logic. For example:
```
<% if [<animal>match[Elephant]] %>
It is an elephant
<% else %>
<% if [<animal>match[Giraffe]] %>
It is a giraffe
<% else %>
It is completely unknown
<% endif %>
<% endif %>
```
!! Explicit Templates for the ListWidget
<<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/7784">> support for `<$list-template>` and `<$list-empty>` as immediate children of the <<.wid "ListWidget">> widget to specify the list item template and/or the empty template. Note that the <<.attr "emptyMessage">> and <<.attr "template">> attributes take precedence if they are present. For example:
```
<$list filter=<<filter>>>
<$list-template>
<$text text=<<currentTiddler>>/>
</$list-template>
<$list-empty>
None!
</$list-empty>
</$list>
```
!! jsonset operator
<<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/7742">> [[jsonset Operator]] for setting values within JSON objects
!! QR Code Reader
<<.link-badge-extended "https://github.com/Jermolene/TiddlyWiki5/pull/7746">> QR Code plugin to be able to read QR codes and a number of other bar code formats
! Translation improvement
Improvements to the following translations:
*
* Chinese
* Polish
* Spanish
! Plugin Improvements
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/1be8f0a9336952d4745d2bd4f2327e353580a272">> Comments Plugin to use predefined palette colours
* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/7785">> Evernote Importer Plugin to support images and other attachments
! Widget Improvements
*
! Usability Improvements
* <<.link-badge-updated "https://github.com/Jermolene/TiddlyWiki5/pull/7747">> editor preview button to automatically focus the editor
* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/7764">> file type names in the export menu
! Hackability Improvements
*
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/7737">> an automatic build of the external core TiddlyWiki at https://tiddlywiki.com/empty-external-core.html
* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/7690">> the default page layout to better support CSS grid and flexbox layouts
! Bug Fixes
*
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/7665">> `{{}}` generating a recursion error
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7758">> ordering of Vanilla stylesheets
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/fa9bfa07a095548eb2f8339b0b1b816d2e6794ef">> missing closing tag in tag-pill-inner macro
* <<.link-badge-removed "https://github.com/Jermolene/TiddlyWiki5/issues/7732">> invalid "type" attribute from textarea elements generated by the EditTextWidget
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7749">> editor "type" dropdown state tiddlers
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7712">> handling of "counter-last" variable when appending items with the ListWidget
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/6088">> upgrade download link in Firefox
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7698">> refreshing of transcluded functions
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/7789">> resizing of height of textareas in control panel
! Node.js Improvements
*
! Performance Improvements
* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/7702">> performance of predefined patterns with [[all Operator]]
* <<.link-badge-updated "https://github.com/Jermolene/TiddlyWiki5/issues/7671">> favicon format to PNG
! Developer Improvements
*
* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/7751">> global hook handling to support removing hooks
! Acknowledgements
@@ -39,22 +107,16 @@ Improvements to the following translations:
<<.contributors """
AnthonyMuscio
btheado
catter-fly
cmo-pomerium
CrossEye
flibbles
hffqyd
lilscribby
BramChen
BuckarooBanzay
BurningTreeC
EvidentlyCube
joebordes
kookma
linonetwo
Marxsal
mateuszwilczek
pille1842
pmario
rmunn
saqimtiaz
stevesunypoly
TiddlyTweeter
twMat
yaisog
simonbaird
T1mL3arn
""">>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

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

View File

@@ -17,7 +17,7 @@
"static": [
"--render","$:/core/templates/static.template.html","static.html","text/plain",
"--render","$:/core/templates/alltiddlers.template.html","alltiddlers.html","text/plain",
"--render","[!is[system]]","[encodeuricomponent[]addprefix[static/]addsuffix[.html]]","text/plain",
"--render","[!is[system]]","[encodeuricomponent[]addprefix[static/]addsuffix[.html]]","text/plain","$:/core/templates/static.tiddler.html",
"--render","$:/core/templates/static.template.css","static/static.css","text/plain"],
"tiddlywikicore": [
"--render","$:/core/templates/tiddlywiki5.js","[[tiddlywikicore-]addsuffix<version>addsuffix[.js]]","text/plain"]

View File

@@ -15,7 +15,7 @@
"static": [
"--render","$:/core/templates/static.template.html","static.html","text/plain",
"--render","$:/core/templates/alltiddlers.template.html","alltiddlers.html","text/plain",
"--render","[!is[system]]","[encodeuricomponent[]addprefix[static/]addsuffix[.html]]","text/plain",
"--render","[!is[system]]","[encodeuricomponent[]addprefix[static/]addsuffix[.html]]","text/plain","$:/core/templates/static.tiddler.html",
"--render","$:/core/templates/static.template.css","static/static.css","text/plain"]
}
}

View File

@@ -0,0 +1,26 @@
title: Conditionals/Basic
description: Basic conditional shortcut syntax
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Text
This is a <% if [<something>match[one]] %>Elephant<% endif %>, I think.
+
title: Output
<$let something="one">
{{Text}}
</$let>
<$let something="two">
{{Text}}
</$let>
+
title: ExpectedResult
<p>
This is a Elephant, I think.
</p><p>
This is a , I think.
</p>

View File

@@ -0,0 +1,37 @@
title: Conditionals/BlockMode
description: Basic conditional shortcut syntax in block mode
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
\procedure test(animal)
<% if [<animal>match[Elephant]] %>
! It is an elephant
<% else %>
<% if [<animal>match[Giraffe]] %>
! It is a giraffe
<% else %>
! It is completely unknown
<% endif %>
<% endif %>
\end
<<test "Giraffe">>
<<test "Elephant">>
<<test "Antelope">>
+
title: ExpectedResult
<h1 class="">It is a giraffe</h1><h1 class="">It is an elephant</h1><h1 class="">It is completely unknown</h1>

View File

@@ -0,0 +1,26 @@
title: Conditionals/Else
description: Else conditional shortcut syntax
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Text
This is a <% if [<something>match[one]] %>Elephant<% else %>Crocodile<% endif %>, I think.
+
title: Output
<$let something="one">
{{Text}}
</$let>
<$let something="two">
{{Text}}
</$let>
+
title: ExpectedResult
<p>
This is a Elephant, I think.
</p><p>
This is a Crocodile, I think.
</p>

View File

@@ -0,0 +1,32 @@
title: Conditionals/Elseif
description: Elseif conditional shortcut syntax
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Text
This is a <% if [<something>match[one]] %>Elephant<% elseif [<something>match[two]] %>Antelope<% else %>Crocodile<% endif %>, I think.
+
title: Output
<$let something="one">
{{Text}}
</$let>
<$let something="two">
{{Text}}
</$let>
<$let something="three">
{{Text}}
</$let>
+
title: ExpectedResult
<p>
This is a Elephant, I think.
</p><p>
This is a Antelope, I think.
</p><p>
This is a Crocodile, I think.
</p>

View File

@@ -0,0 +1,26 @@
title: Conditionals/MissingEndif
description: Conditional shortcut syntax with missing endif
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Text
This is a <% if [<something>match[one]] %>Elephant
+
title: Output
<$let something="one">
{{Text}}
</$let>
<$let something="two">
{{Text}}
</$let>
+
title: ExpectedResult
<p>
This is a Elephant
</p><p>
This is a
</p>

View File

@@ -0,0 +1,12 @@
title: Conditionals/MultipleResults
description: Check that multiple results from the filter are ignored
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
This is a <% if 1 2 3 4 5 6 %>Elephant<% endif %>, I think.
+
title: ExpectedResult
<p>This is a Elephant, I think.</p>

View File

@@ -0,0 +1,38 @@
title: Conditionals/Nested
description: Nested conditional shortcut syntax
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
\procedure test(animal)
<% if [<animal>match[Elephant]] %>
It is an elephant
<% else %>
<% if [<animal>match[Giraffe]] %>
It is a giraffe
<% else %>
It is completely unknown
<% endif %>
<% endif %>
\end
<<test "Giraffe">>
<<test "Elephant">>
<<test "Antelope">>
+
title: ExpectedResult
It is a giraffe
It is an elephant
It is completely unknown

View File

@@ -0,0 +1,60 @@
title: Conditionals/NestedElseif
description: Nested elseif conditional shortcut syntax
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Text
\whitespace trim
This is a&#32;
<% if [<something>match[one]] %>
<% if [<another>match[one]] %>
Indian
<% elseif [<another>match[two]] %>
African
<% else %>
Unknown
<% endif %>
&#32;Elephant
<% elseif [<something>match[two]] %>
Antelope
<% else %>
Crocodile
<% endif %>
, I think.
+
title: Output
<$let something="one" another="one">
{{Text}}
</$let>
<$let something="one" another="two">
{{Text}}
</$let>
<$let something="one" another="three">
{{Text}}
</$let>
<$let something="two">
{{Text}}
</$let>
<$let something="three">
{{Text}}
</$let>
+
title: ExpectedResult
<p>
This is a Indian Elephant, I think.
</p><p>
This is a African Elephant, I think.
</p><p>
This is a Unknown Elephant, I think.
</p><p>
This is a Antelope, I think.
</p><p>
This is a Crocodile, I think.
</p>

View File

@@ -0,0 +1,29 @@
title: ListWidget/WithExplicitTemplates
description: List widget with explicit templates
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
+
title: Output
\whitespace trim
\procedure test(filter)
<$list filter=<<filter>>>
<$list-template>
<$text text=<<currentTiddler>>/>
</$list-template>
<$list-empty>
None!
</$list-empty>
</$list>
\end
<<test "1 2 3">>
<<test "">>
+
title: ExpectedResult
<p>123</p><p>None!</p>

View File

@@ -0,0 +1,32 @@
title: ListWidget/WithExplicitTemplatesInBlockMode
description: List widget with explicit templates in block mode
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
+
title: Output
\whitespace trim
\procedure test(filter)
<$list filter=<<filter>>>
<$list-template>
<$text text=<<currentTiddler>>/>
</$list-template>
<$list-empty>
None!
</$list-empty>
</$list>
\end
<<test "1 2 3">>
<<test "">>
+
title: ExpectedResult
123None!

View File

@@ -0,0 +1,33 @@
title: ListWidget/WithExplicitTemplatesOverriddenByAttributes
description: List widget with explicit templates
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
+
title: Output
\whitespace trim
\procedure test(filter)
<$list filter=<<filter>> emptyMessage="Zero" template="Template">
<$list-template>
<$text text=<<currentTiddler>>/>
</$list-template>
<$list-empty>
None!
</$list-empty>
</$list>
\end
<<test "1 2 3">>
<<test "">>
+
title: Template
<$text text=<<currentTiddler>>/><$text text=<<currentTiddler>>/>
+
title: ExpectedResult
<p>112233</p><p>Zero</p>

View File

@@ -0,0 +1,25 @@
title: ListWidget/WithLimit
description: List widget with limit
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
+
title: Output
Zero: <$list filter="1 2 3 4" limit="0" template="Template"/>
One: <$list filter="1 2 3 4" limit="1" template="Template"/>
Two: <$list filter="1 2 3 4" limit="2" template="Template"/>
Minus Two: <$list filter="1 2 3 4" limit="-2" template="Template"/>
+
title: Template
<$text text=<<currentTiddler>>/>
+
title: ExpectedResult
<p>Zero: </p><p>One: 1</p><p>Two: 12</p><p>Minus Two: 34
</p>

View File

@@ -0,0 +1,26 @@
title: ListWidget/WithMissingTemplate
description: List widget with explicit templates
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
+
title: Output
\whitespace trim
\procedure test(filter)
<$list filter=<<filter>>>
<$list-empty>
None!
</$list-empty>
</$list>
\end
<<test "1 2 3">>
<<test "">>
+
title: ExpectedResult
<p><span><a class="tc-tiddlylink tc-tiddlylink-missing" href="#1">1</a></span><span><a class="tc-tiddlylink tc-tiddlylink-missing" href="#2">2</a></span><span><a class="tc-tiddlylink tc-tiddlylink-missing" href="#3">3</a></span></p><p>None!</p>

View File

@@ -0,0 +1,27 @@
title: Transclude/Variable/Refreshing
description: Transcluding and refreshing a function
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
\function list-join(filter, sep:", ") [subfilter<filter>join<sep>]
<$tiddler tiddler="TestData">
<<list-join "[enlist{!!items}]">>
</$tiddler>
+
title: TestData
+
title: Actions
<$action-setfield $tiddler="TestData" items={{{ [range[10]join[ ]] }}}/>
+
title: ExpectedResult
<p>1, 2, 3, 4, 5, 6, 7, 8, 9, 10</p>

View File

@@ -0,0 +1,15 @@
title: Transclude/Variable/Static
description: Transcluding a function
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
items: 1 2 3 4 5 6 7 8 9 10
\function list-join(filter, sep:", ") [subfilter<filter>join<sep>]
<<list-join "[enlist{!!items}]">>
+
title: ExpectedResult
<p>1, 2, 3, 4, 5, 6, 7, 8, 9, 10</p>

View File

@@ -103,6 +103,24 @@ describe("json filter tests", function() {
expect(wiki.filterTiddlers("[{First}jsontype[d],[f],[4]]")).toEqual(["null"]);
});
it("should support the jsonset operator", function() {
expect(wiki.filterTiddlers("[{First}jsonset[]]")).toEqual(['{"a":"one","b":"","c":1.618,"d":{"e":"four","f":["five","six",true,false,null]}}']);
expect(wiki.filterTiddlers("[{First}jsonset[],[Antelope]]")).toEqual(['"Antelope"']);
expect(wiki.filterTiddlers("[{First}jsonset:number[],[not a number]]")).toEqual(['0']);
expect(wiki.filterTiddlers("[{First}jsonset[id],[Antelope]]")).toEqual(['{"a":"one","b":"","c":1.618,"d":{"e":"four","f":["five","six",true,false,null]},"id":"Antelope"}']);
expect(wiki.filterTiddlers("[{First}jsonset:notatype[id],[Antelope]]")).toEqual(['{"a":"one","b":"","c":1.618,"d":{"e":"four","f":["five","six",true,false,null]},"id":"Antelope"}']);
expect(wiki.filterTiddlers("[{First}jsonset:boolean[id],[false]]")).toEqual(['{"a":"one","b":"","c":1.618,"d":{"e":"four","f":["five","six",true,false,null]},"id":false}']);
expect(wiki.filterTiddlers("[{First}jsonset:boolean[id],[Antelope]]")).toEqual(['{"a":"one","b":"","c":1.618,"d":{"e":"four","f":["five","six",true,false,null]}}']);
expect(wiki.filterTiddlers("[{First}jsonset:number[id],[42]]")).toEqual(['{"a":"one","b":"","c":1.618,"d":{"e":"four","f":["five","six",true,false,null]},"id":42}']);
expect(wiki.filterTiddlers("[{First}jsonset:null[id]]")).toEqual(['{"a":"one","b":"","c":1.618,"d":{"e":"four","f":["five","six",true,false,null]},"id":null}']);
expect(wiki.filterTiddlers("[{First}jsonset:array[d],[f],[5]]")).toEqual(['{"a":"one","b":"","c":1.618,"d":{"e":"four","f":["five","six",true,false,null,[]]}}']);
expect(wiki.filterTiddlers("[{First}jsonset:object[d],[f],[5]]")).toEqual(['{"a":"one","b":"","c":1.618,"d":{"e":"four","f":["five","six",true,false,null,{}]}}']);
expect(wiki.filterTiddlers("[{First}jsonset[missing],[id],[Antelope]]")).toEqual(['{"a":"one","b":"","c":1.618,"d":{"e":"four","f":["five","six",true,false,null]}}']);
expect(wiki.filterTiddlers("[{First}jsonset:json[\"Antelope\"]]")).toEqual(['"Antelope"']);
expect(wiki.filterTiddlers("[{First}jsonset:json[id],[{\"a\":313}]]")).toEqual(['{"a":"one","b":"","c":1.618,"d":{"e":"four","f":["five","six",true,false,null]},"id":{"a":313}}']);
expect(wiki.filterTiddlers("[{First}jsonset:json[notjson]]")).toEqual(['{"a":"one","b":"","c":1.618,"d":{"e":"four","f":["five","six",true,false,null]}}']);
});
it("should support the format:json operator", function() {
expect(wiki.filterTiddlers("[{First}format:json[]]")).toEqual(["{\"a\":\"one\",\"b\":\"\",\"c\":1.618,\"d\":{\"e\":\"four\",\"f\":[\"five\",\"six\",true,false,null]}}"]);
expect(wiki.filterTiddlers("[{First}format:json[4]]")).toEqual(["{\n \"a\": \"one\",\n \"b\": \"\",\n \"c\": 1.618,\n \"d\": {\n \"e\": \"four\",\n \"f\": [\n \"five\",\n \"six\",\n true,\n false,\n null\n ]\n }\n}"]);

View File

@@ -527,6 +527,29 @@ describe("Widget module", function() {
expect(wrapper.children[0].children[15].sequenceNumber).toBe(53);
});
var testCounterLast = function(oldList, newList) {
return function() {
var wiki = new $tw.Wiki();
// Add some tiddlers
wiki.addTiddler({title: "Numbers", text: "", list: oldList});
var text = "<$list filter='[list[Numbers]]' variable='item' counter='c'><<item>><$text text={{{ [<c-last>match[no]then[, ]] }}} /></$list>";
var widgetNode = createWidgetNode(parseText(text,wiki),wiki);
// Render the widget node to the DOM
var wrapper = renderWidgetNode(widgetNode);
// Test the rendering
expect(wrapper.innerHTML).toBe("<p>" + oldList.split(' ').join(', ') + "</p>");
// Append a number
wiki.addTiddler({title: "Numbers", text: "", list: newList});
refreshWidgetNode(widgetNode,wrapper,["Numbers"]);
expect(wrapper.innerHTML).toBe("<p>" + newList.split(' ').join(', ') + "</p>");
}
}
it("the list widget with counter-last should update correctly when list is appended", testCounterLast("1 2 3 4", "1 2 3 4 5"));
it("the list widget with counter-last should update correctly when last item is removed", testCounterLast("1 2 3 4", "1 2 3"));
it("the list widget with counter-last should update correctly when first item is inserted", testCounterLast("1 2 3 4", "0 1 2 3 4"));
it("the list widget with counter-last should update correctly when first item is removed", testCounterLast("1 2 3 4", "2 3 4"));
it("should deal with the list widget followed by other widgets", function() {
var wiki = new $tw.Wiki();
// Add some tiddlers

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 894 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

View File

@@ -1,3 +1,3 @@
title: $:/_tw_shared/favicons/classic.tiddlywiki.com
type: image/x-icon
type: image/png
tags: TiddlyWikiSitesMenu

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

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