1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2026-01-22 19:04:38 +00:00

Compare commits

..

70 Commits

Author SHA1 Message Date
jeremy@jermolene.com
b4dcf9a338 Allow matchSelector to be used even if selector attribute isn't used 2022-03-14 09:30:35 +00:00
jeremy@jermolene.com
a893791f97 Initial Commit 2022-03-11 16:40:11 +00:00
Saq Imtiaz
aaf1aa3821 Improve affordances for new browser windows (#6498)
* feat: extend tm-open-window to allow opening the same tiddler in multiple templates, and introduce tm-close-window to close browser windows

* fix: use a windowID parameter to uniquely identify a window and introduce tm-close-all-tiddlers

* fix: whitespace

* fix: update variable
2022-03-02 17:34:02 +00:00
jeremy@jermolene.com
8114d5475b Update release note 2022-03-01 16:56:52 +00:00
jeremy@jermolene.com
29599baa3b Merge branch 'tiddlywiki-com' 2022-03-01 16:49:36 +00:00
Saq Imtiaz
b196cf77e8 Sort sidebar language, plugin and theme list by name rather than description (#6501) 2022-03-01 09:23:19 +00:00
jeremy@jermolene.com
4d3ebf4bf0 Revert "fr-FR next batch of translation updates (#6489)"
This reverts commit b3268546ef.
2022-02-27 17:23:36 +00:00
tw-FRed
b3268546ef fr-FR next batch of translation updates (#6489)
* Move GettingStarted to the right place

Previous batch of translations changed the wrong file

* Revert #6467 for GettingStarted

* Delete $ _editions_tw5.com_doc-macros.tid

Wrong name for the updated tiddler

* Update $__editions_tw5.com_doc-macros.tid

* Translation updates

* Update of 2 tiddlers referenced on HelloThere

* 5 more tiddlers, referenced in WikiText.tid
2022-02-27 17:21:55 +00:00
Saq Imtiaz
615d8da64f Docs: mention MessageCatcher widget in LinkCatcher tiddler (#6485) 2022-02-26 18:59:45 +00:00
TW Videos
45a1478bc9 Allow TiddlyVee to submitt PRs (#6487)
This is pmario and TiddlyVee will be used to create real PRs shown in videos
2022-02-26 18:48:49 +00:00
TW Videos
a071881562 Links to CLA: change branch from master to tiddlywiki-com (#6488) 2022-02-26 18:45:58 +00:00
Ben Webber
2c38c8351b Make butlast[0] consistent with rest (#6483)
butlast[0] now returns the input list unchanged.

Fixes: #5833
2022-02-26 09:42:24 +00:00
Ben Webber
a51191d334 Support specifying insertbefore position title as parameter (#6477)
* Support specifying insertbefore position title as parameter

Closes: #6133

* Update insertbefore calls with new variable parameter syntax

See-also: 96b52606a (Support specifying insertbefore position title as parameter, 2022-02-21)
2022-02-24 11:08:06 +00:00
Saq Imtiaz
4054566493 Extend $draggable to support an optional drag handle (#6480)
* feat: extend  to support a selector attribute identifying the DOM element to be used as the drag handle

* fix: remove redundant variable declaration

* fix: remove extranneous variable declaration
2022-02-24 11:06:18 +00:00
Marxsal
5f994f7d46 Savers: Polly (#6481)
* Savers: Polly

* Polly, with url
2022-02-23 21:47:21 +00:00
Ben Webber
7a7472833f Consider non-existent tiddlers untagged (#6478)
Fixes regression introduced in 575c23359.

Fixes: #6119
See-also: 575c23359 (Update untagged filter to avoid $tw.utils.pushTop (#6034), 2021-09-18)
2022-02-23 12:46:34 +00:00
Marxsal
9777aa9d13 Webdav - category "paid" hosting (#6476) 2022-02-22 19:56:07 +00:00
Cameron Fischer
d0b5b2124a Is draft (#6442)
* corrected [!is[draft]] to be a proper complement

* Ensuring [is[draft]] and [!is[draft]] are complements

* Made [is[draft]] more analogous to .isDraft()
2022-02-22 16:41:29 +00:00
Ben Webber
95bd694a65 Support case insensitive matching in prefix/suffix operators (#6468)
* Support case insensitive matching in prefix/suffix operators

Support `caseinsensitive`/`caseinsensitive` suffixes in the following
filter operators:

  * prefix
  * suffix
  * removeprefix
  * removesuffix

The suffixes have the same behaviour as in the match operator.

Closes: #6407

* Do not filter titles if suffix/removesuffix operand is empty

Issue: #6407
2022-02-22 16:38:40 +00:00
jeremy@jermolene.com
49de500b5e Add contributors to release note 2022-02-22 09:54:46 +00:00
jeremy@jermolene.com
4cf3df0f86 Merge branch 'tiddlywiki-com' 2022-02-22 09:25:15 +00:00
jeremy@jermolene.com
1ae1ff3da2 Update release note 2022-02-21 17:38:11 +00:00
cdruan
4f42df8bef Update highlight.js to v11.4.0 (#6427)
* Rename v9 highlight.js plugin to highlight-legacy

* Add ES6 version of highlight.js plugin

* highlightblock.js

	- ensure this ES6 plugin will not cause error on legacy browsers
	- update the code to use new highlight.js APIs
	- change class tagging to match more closely with highlight.js
	- allow users to add language definitions as JS "highlight" modules

* styles.tid

	- update to match v11

* howto.tid

	- add instructions on how to add language definitions as JS modules

* highlight.min.js, default.min.css

	- version 11.4.0 common languages only

* Remove extraneous whitespaces

* Update readme.tid

* Update bundled languages

bundled: common + apache + nginx + latex + dockerfile + fortran

* Update highlight-legacy subtiddlers' titles

* Touch up highlight-legacy docs

* Touch up highlight plugin docs

* Fix pre block styling

- add "hljs" class to <pre> so the element can be styled
2022-02-21 15:35:13 +00:00
Jeremy Ruston
36b162a377 Fix for tag ordering issue #6382 (#6383)
* Failing test

* Fix underlying problem

* Less naive fix

Now we make sure we maintain the sort order of the titles array when adding a new tiddler

* Fix failing tests

* Refactor filter tests to repeat them with different store orderings

* Revert "Fix failing tests"

This reverts commit ee03ee57f5.

* Refine fix to retain stylesheet ordering

The order of tiddlers in the HTML file uses localeCompare(), and that determines the insertion order. So if we want to be compatible with older versions we have to use localeCompare() to order tiddlers, not a plain sort()

* Don't sort shadow tiddlers

Instead rely on the existing ordering

* Fix failing tests, take 2

I think that all of these changes are explained by the store no longer retaining insertion order, but now using localecompare ordering

* Fix tests from #6327
2022-02-21 15:34:05 +00:00
Jeremy Ruston
82c8fe7fa8 Introduce JSON parse utility function with error handling (#6401)
* Introduce JSON parse utility function with error handling

Fixes #6400

* Fix typo
2022-02-21 15:29:25 +00:00
Jeremy Ruston
5378b45c40 Allow newlines within filtered transclusions (#6421)
* Allow newlines within filtered transclusions

* Docs
2022-02-21 15:28:21 +00:00
Jeremy Ruston
ab3109d84b Add support for directly setting style.* attributes on HTML elements (#6388)
* Support direct style attributes on the element widget

* Fix tests

Not all parse tree nodes have an "orderedAttributes" member (eg. the error message generated at 5613bcc884/core/modules/widgets/transclude.js (L73-L75))

* Ensure ordering isn't insertion dependent if orderedAttributes is missing

* Add docs
2022-02-21 15:24:06 +00:00
Cameron Fischer
a4ab42da8a findListingsOfTiddler should cache results (#6327)
* findListingsOfTiddler uses FieldIndexer now

* Turns out FieldIndexer can't help listed[]
2022-02-21 15:07:30 +00:00
jeremy@jermolene.com
af87727ffc Adjust version tag for #6293 2022-02-21 15:06:39 +00:00
Mario Pietsch
6b4e5c74ad Add "some" flag to search operator (#6293) 2022-02-21 15:05:34 +00:00
lin onetwo
94ab1e998d Create Saving on TidGi.tid (#6473) 2022-02-21 12:23:50 +00:00
jeremy@jermolene.com
8af99878cc Add version tags for #5899 2022-02-21 09:56:05 +00:00
Joshua Fontany
d6d2bc455c Fix server options (#5899)
* removed illegal cahracter in filename

* fixes required plugin options & updates docs

* Update dev docs

* call self.displayError

* Revert "call self.displayError"

This reverts commit 5d599aa979.

* adds path based auth (backwards compatible)

* refactor per-route auth

* get status bug

* server options

* server options

* server options, new 'server-settings' param

* reflow

* fix boot.origin

* refactor new parameters

* restore sitetitle as servername option

* Soft reset to master

* docs update

* tweak wording

* docs

* cleanup

* remove literal string

* cleanup docs

* formatting

* Remove per-path auth

* revert get-status

* fold in PR 5538

* remove server-options

* remove doc

* required-plugins a server-parameter, not option
2022-02-21 09:53:06 +00:00
jeremy@jermolene.com
d5ff723d4c Update version tag for #5742 2022-02-21 09:49:55 +00:00
Joshua Fontany
1d0af90ba2 Extend lookup operator to work with fields and indexes (#5742)
* extend lookup op flexibility with 2 parameters

* bumped .from macro to .24

* aligned syntax

* lookup fixes

* bugfix

* docs

* messed up the tests somehow

* docs fix

* lookup bugfix

* docs

* docs

* call self.displayError

* Revert "call self.displayError"

This reverts commit 5d599aa979.

* storylist

* tests

* tests pass
2022-02-21 09:48:29 +00:00
tw-FRed
b12d6c0758 Use cascade for FR ViewTemplate title instead of shadow tiddler (#6471)
* Delete $__core_ui_ViewTemplate_title.tid

fr-FR modifications to ViewTemplate/title can now be done through cascades mechanism.

* fr-FR New ViewTemplate title cascade

Replacement for old fr-FR ViewTemplate/title shadow tiddler

* fr-FR Better ViewTemplate title cascade

Updated according to @Jermolene review.
2022-02-20 19:38:13 +00:00
tw-FRed
a89677ea40 [fr_FR] French translation update (#6467)
* [fr_FR] Add utility macro for translated links

* Update Saving.tid

* Add TiddlyFox Apocalypse translation

* Update TiddlyFox.tid

* Translate Community Links Aggregator.tid

* Update Forums.tid

* Update Developers.tid

* Update HelloThere.tid

* Update GettingStarted.tid

* Update Community.tid

* Update tw5.com edition macros from uplink

Some text in these macros must be translated.

* Various translation updates

* Clean utility fields I had left over

* Clean older files too
2022-02-20 17:25:25 +00:00
Saq Imtiaz
59572cd75d Extend tm-open-window to support optional top and left position for new browser window (#6470)
* feat: extend tm-open-window to support optional top and left position for new browser window

* fix: whitespace correction

* Update WidgetMessage_ tm-open-window.tid
2022-02-20 11:23:27 +00:00
jeremy@jermolene.com
1d16206188 Add support for tm-relink-tiddler message 2022-02-19 09:38:48 +00:00
jeremy@jermolene.com
37a6ff8521 Move tm-rename-tiddler handling from navigator widget into startup module
This reverses an August 2015 change in 68e15c10641e2eda1e64cf29954786a07326a920; the original rationale was wrong: there is nothing related to the navigator widget in the implementation of the tm-rename-tiddler message
2022-02-19 09:20:32 +00:00
jeremy@jermolene.com
d3ea98fcef Menubar plugin: fix class handling for dropdowns
Fixes  #6457
2022-02-14 10:44:42 +00:00
Bram Chen
5022516c61 Update chinese language files (#6449)
* Update chinese field descriptions

* Revised chinese translations for `DropMessage`
2022-02-08 16:01:30 +00:00
jeremy@jermolene.com
965d8ee014 Update release note 2022-02-08 15:40:15 +00:00
Marxsal
8e50ad1243 Change 'Drop here' to 'Drop now' in import msg (#6435) 2022-02-07 17:32:06 +00:00
jeremy@jermolene.com
33f40c47c6 Use code-body: yes for more templates
Fixes #6444
2022-02-07 16:53:36 +00:00
Cameron Fischer
1b3c2557b8 Fixed issue: deprecated regexp could cause crash (#6438)
* Fixed issue: deprecated regexp could cause crash

* Different fix which will bother plugins less
2022-02-07 16:39:29 +00:00
Dyllon Gagnier
6b31d7cae3 Add TW5-browser-nativesaver to tw5.com docs (#6447)
* Signing the CLA

* Add TW5-browser-nativesaver to tw5.com docs

Co-authored-by: Jeremy Ruston <jeremy@jermolene.com>
2022-02-06 10:49:48 +00:00
jeremy@jermolene.com
1a4766c5a1 Merge branch 'tiddlywiki-com' 2022-02-05 16:39:35 +00:00
btheado
3e62e8406b Docs: Compare the wikitext concept of inline vs. block to the corresponding HTML concept (#6443) 2022-02-03 19:22:24 +00:00
jeremy@jermolene.com
e49dda3b48 Fix search results cutoff on narrow screens
Fixes #6440
2022-02-01 09:36:30 +00:00
jeremy@jermolene.com
bd447f0716 Add talk.tiddlywiki.org as the official forum for the community 2022-01-31 17:05:55 +00:00
RJ Skerry-Ryan
13faeaa0bd Markdown: Let WikiText parsing handle the creation of LaTeX widgets. (#6428)
* Markdown: Let WikiText parsing handle the creation of LaTeX widgets.

When embedding LaTeX snippets in inline HTML nodes, such as TiddlyRemember
macros or HTML tables, the parsing of latex nodes breaks the WikiText by
splitting it into pieces around the latex node.

This commit fixes the issue by converting the Remarkable katex nodes back to
text, using a newline to indicate a block katex snippet. This is then re-parsed
by the WikiText KaTeX plugin.

TESTED:

Created a test wiki with:
```
$ node tiddlywiki.js test --init markdowndemo
$ node tiddlywiki.js test --listen
```

* Verified markdown + KaTeX support still works as expected.
* Verified that embedding LaTeX snippets in inline HTML works (e.g. `<a
href="https://example.com/">$x^2$</a>`).
* Verified the markdown + KaTeX support works as expected with renderWikiText
set to `false`.

* Style: Remove spaces between if and opening parentheses.
2022-01-30 11:23:00 +00:00
twMat
7f0fb2b610 [doc] Update Importing Tiddlers.tid - attempt 2 (#6432) 2022-01-30 11:17:39 +00:00
Rizwan
7d2994388b Remove 2 whitespaces (#6434)
These whitespaces were messing the list rendering
2022-01-30 11:07:32 +00:00
RJ Skerry-Ryan
edb5dc3fdc Add keyword-spacing rule to .eslintrc.yml to reflect the project code style. (#6431)
- Update .eslintignore to ignore "third party" code.
- Add a "lint" script to package.json so `npm run lint` runs eslint on the repo.
2022-01-29 17:41:09 +00:00
Marxsal
df1b1316c8 One word change to 'Images in WikiText' (#6430) 2022-01-29 15:39:29 +00:00
jeremy@jermolene.com
1a0c831216 Add sha256 operator 2022-01-29 11:02:47 +00:00
jeremy@jermolene.com
f4365e4bb4 Macro: remove confusing advice
See https://talk.tiddlywiki.org/t/wikitext-parsing-and-rendering-in-macros/2218
2022-01-28 11:24:06 +00:00
Saq Imtiaz
75d10a2dc3 Fix: bug with importvariables widget when importing block mode widgets. fixes #6424 (#6426) 2022-01-27 17:35:18 +00:00
Marxsal
da7cf7a4f3 QualifyWidget documentation (#6422) 2022-01-25 17:59:59 +00:00
Saq Imtiaz
6452eb56a9 fix: bug introduced with 88812092fd fixes #6419 (#6420) 2022-01-24 19:17:09 +00:00
Saq Imtiaz
9fce8153df Add support to tm-scroll message for scrolling without animating (#6410)
* feat: add support for animationDuration attribute of paramObject for tm-scroll message

* docs: added docs for animationDuration attribute of tm-scroll message

* fix: use .utils.hop instead of Object.hasOwnProperty()

* fix: do not check if object before calling utils.hop()

* fix: syntax
2022-01-24 09:44:04 +00:00
jeremy@jermolene.com
4cdfa4e3f9 Update tm-download-file docs to mention the filename parameter 2022-01-23 18:35:38 +00:00
btheado
d6384df6fc Add warnings about non-recursive nature of dynamic attribute values (#6417) 2022-01-23 18:24:25 +00:00
btheado
f0bd06b38d Add doc related to WikiText parser modes (#6415)
* Added macros for displaying wikitext examples in a table

* Added documentation for WikiText parsing

* Changed recognize to British spelling

* Add links to the new wikitext parser tiddlers
2022-01-23 09:44:01 +00:00
Saq Imtiaz
d823856082 feat: add support for renderEnd method for storyviews in widget's render() method (#6409) 2022-01-19 19:48:02 +00:00
twMat
b02a82ba0f Update list-links-draggabe Macro.tid (#6405)
The commented problem is, I presume, resolved now that we can directly edit fields in the current tiddler.
2022-01-19 11:13:08 +00:00
twMat
c43b013539 Paragraph on "anchor links" for Linking in WikiText.tid (#6404) 2022-01-18 19:27:54 +00:00
twMat
5548186c93 Update size attribute in EditTextWidget.tid (#6403)
ref: https://github.com/Jermolene/TiddlyWiki5/issues/6165
2022-01-17 10:11:20 +00:00
twMat
def9b553a8 typo in EventCatcherWidget.tid (#6399) 2022-01-15 12:57:51 +00:00
173 changed files with 4208 additions and 707 deletions

View File

@@ -1,15 +1,8 @@
# Known minified files
# Ignore "third party" code whose style we will not change.
/boot/sjcl.js
/core/modules/utils/base64-utf8/base64-utf8.module.js
/core/modules/utils/base64-utf8/base64-utf8.module.min.js
/core/modules/utils/diff-match-patch/diff_match_patch.js
/plugins/tiddlywiki/async/files/async.min.v1.5.0.js
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/anyword-hint.js
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/css-hint.js
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/html-hint.js
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/javascript-hint.js
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/show-hint.js
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/xml-hint.js
/plugins/tiddlywiki/codemirror-closebrackets/files/addon/edit/closebrackets.js
/plugins/tiddlywiki/codemirror-closebrackets/files/addon/edit/matchbrackets.js
/plugins/tiddlywiki/codemirror-closetag/files/addon/edit/closetag.js
/plugins/tiddlywiki/codemirror-closetag/files/addon/fold/xml-fold.js
/core/modules/utils/diff-match-patch/diff_match_patch_uncompressed.js
/core/modules/utils/dom/csscolorparser.js
/plugins/tiddlywiki/*/files/

View File

@@ -64,7 +64,23 @@ rules:
init-declarations: 'off'
jsx-quotes: error
key-spacing: 'off'
keyword-spacing: 'off'
keyword-spacing:
- error
- before: true
after: false
overrides:
'case':
after: true
'do':
'after': true
'else':
after: true
'return':
after: true
'throw':
after: true
'try':
after: true
line-comment-position: 'off'
linebreak-style: 'off'
lines-around-comment: 'off'

View File

@@ -68,6 +68,26 @@ $tw.utils.isArrayEqual = function(array1,array2) {
});
};
/*
Add an entry to a sorted array if it doesn't already exist, while maintaining the sort order
*/
$tw.utils.insertSortedArray = function(array,value) {
var low = 0, high = array.length - 1, mid, cmp;
while(low <= high) {
mid = (low + high) >> 1;
cmp = value.localeCompare(array[mid]);
if(cmp > 0) {
low = mid + 1;
} else if(cmp < 0) {
high = mid - 1;
} else {
return array;
}
}
array.splice(low,0,value);
return array;
};
/*
Push entries onto an array, removing them first if they already exist in the array
array: array to modify (assumed to be free of duplicates)
@@ -1094,7 +1114,7 @@ $tw.Wiki = function(options) {
tiddlerTitles = null, // Array of tiddler titles
getTiddlerTitles = function() {
if(!tiddlerTitles) {
tiddlerTitles = Object.keys(tiddlers);
tiddlerTitles = Object.keys(tiddlers).sort(function(a,b) {return a.localeCompare(b);});
}
return tiddlerTitles;
},
@@ -1147,10 +1167,8 @@ $tw.Wiki = function(options) {
}
// Save the new tiddler
tiddlers[title] = tiddler;
// Check we've got it's title
if(tiddlerTitles && tiddlerTitles.indexOf(title) === -1) {
tiddlerTitles.push(title);
}
// Check we've got the title
tiddlerTitles = $tw.utils.insertSortedArray(tiddlerTitles || [],title);
// Record the new tiddler state
updateDescriptor["new"] = {
tiddler: tiddler,

View File

@@ -14,7 +14,7 @@ ConfirmAction: Do you wish to proceed?
Count: count
DefaultNewTiddlerTitle: New Tiddler
Diffs/CountMessage: <<diff-count>> differences
DropMessage: Drop here (or use the 'Escape' key to cancel)
DropMessage: Drop now (or use the 'Escape' key to cancel)
Encryption/Cancel: Cancel
Encryption/ConfirmClearPassword: Do you wish to clear the password? This will remove the encryption applied when saving this wiki
Encryption/PromptSetPassword: Set a new password for this TiddlyWiki

View File

@@ -13,8 +13,8 @@ Text editor operation to wrap the selected lines with a prefix and suffix
"use strict";
exports["wrap-lines"] = function(event,operation) {
var prefix = operation.paramObject.prefix || "",
suffix = operation.paramObject.suffix || "";
var prefix = event.paramObject.prefix || "",
suffix = event.paramObject.suffix || "";
// Cut just past the preceding line break, or the start of the text
operation.cutStart = $tw.utils.findPrecedingLineBreak(operation.text,operation.selStart);
// Cut to just past the following line break, or to the end of the text

View File

@@ -95,10 +95,12 @@ function parseFilterOperation(operators,filterString,p) {
if(nextBracketPos === -1) {
throw "Missing closing bracket in filter expression";
}
if(!operator.regexp) {
if(operator.regexp) {
operand.text = "";
} else {
operand.text = filterString.substring(p,nextBracketPos);
operator.operands.push(operand);
}
operator.operands.push(operand);
p = nextBracketPos + 1;
}

View File

@@ -0,0 +1,27 @@
/*\
title: $:/core/modules/filters/crypto.js
type: application/javascript
module-type: filteroperator
Filter operators for cryptography, using the Stanford JavaScript library
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
exports.sha256 = function(source,operator,options) {
var results = [],
length = parseInt(operator.operand,10) || 20,
sha256 = function(text) {
return sjcl.codec.hex.fromBits(sjcl.hash.sha256.hash(text)).substr(0,length);
};
source(function(tiddler,title) {
results.push(sha256(title));
});
return results;
};
})();

View File

@@ -20,7 +20,7 @@ exports.insertbefore = function(source,operator,options) {
source(function(tiddler,title) {
results.push(title);
});
var target = options.widget && options.widget.getVariable(operator.suffix || "currentTiddler");
var target = operator.operands[1] || (options.widget && options.widget.getVariable(operator.suffix || "currentTiddler"));
if(target !== operator.operand) {
// Remove the entry from the list if it is present
var pos = results.indexOf(operator.operand);

View File

@@ -19,13 +19,13 @@ exports.draft = function(source,prefix,options) {
var results = [];
if(prefix === "!") {
source(function(tiddler,title) {
if(!tiddler || !$tw.utils.hop(tiddler.fields,"draft.of")) {
if(!tiddler || !tiddler.isDraft()) {
results.push(title);
}
});
} else {
source(function(tiddler,title) {
if(tiddler && $tw.utils.hop(tiddler.fields,"draft.of") && (tiddler.fields["draft.of"].length !== 0)) {
if(tiddler && tiddler.isDraft()) {
results.push(title);
}
});

View File

@@ -87,7 +87,8 @@ exports.butlast = function(source,operator,options) {
source(function(tiddler,title) {
results.push(title);
});
return results.slice(0,-count);
var index = count === 0 ? results.length : -count;
return results.slice(0,index);
};
exports.bl = exports.butlast;

View File

@@ -5,9 +5,11 @@ module-type: filteroperator
Filter operator that looks up values via a title prefix
[lookup:<field>[<prefix>]]
[lookup:<defaultvalue>:<field OR index>[<prefix>],[<field-name OR index-name>]]
Prepends the prefix to the selected items and returns the specified field value
Prepends the prefix to the selected items and returns the specified
field or index value. If the 2nd suffix does not exist, it defaults to field.
If the second operand is missing it defaults to "text" for fields, and "0" for indexes
\*/
(function(){
@@ -20,10 +22,31 @@ Prepends the prefix to the selected items and returns the specified field value
Export our filter function
*/
exports.lookup = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
results.push(options.wiki.getTiddlerText(operator.operand + title) || operator.suffix || '');
});
var results = [],
suffixes = operator.suffixes || [],
defaultSuffix = suffixes[0] ? (suffixes[0][0] || "") : "",
indexSuffix = (suffixes[1] && suffixes[1][0] === "index") ? true : false,
target;
if(operator.operands.length == 2) {
target = operator.operands[1]
} else {
target = indexSuffix ? "0": "text";
}
if(indexSuffix) {
source(function(tiddler,title) {
var data = options.wiki.extractTiddlerDataItem(operator.operands[0]+title,target,defaultSuffix);
results.push(data);
});
} else {
source(function(tiddler,title) {
var value = defaultSuffix;
var targetTiddler = options.wiki.getTiddler(operator.operands[0]+title);
if(targetTiddler && targetTiddler.getFieldString(target)) {
value = targetTiddler.getFieldString(target);
}
results.push(value);
});
}
return results;
};

View File

@@ -16,19 +16,37 @@ Filter operator for checking if a title starts with a prefix
Export our filter function
*/
exports.prefix = function(source,operator,options) {
var results = [];
if(operator.prefix === "!") {
source(function(tiddler,title) {
if(title.substr(0,operator.operand.length) !== operator.operand) {
results.push(title);
}
});
var results = [],
suffixes = (operator.suffixes || [])[0] || [];
if(suffixes.indexOf("caseinsensitive") !== -1) {
var operand = operator.operand.toLowerCase();
if(operator.prefix === "!") {
source(function(tiddler,title) {
if(title.toLowerCase().substr(0,operand.length) !== operand) {
results.push(title);
}
});
} else {
source(function(tiddler,title) {
if(title.toLowerCase().substr(0,operand.length) === operand) {
results.push(title);
}
});
}
} else {
source(function(tiddler,title) {
if(title.substr(0,operator.operand.length) === operator.operand) {
results.push(title);
}
});
if(operator.prefix === "!") {
source(function(tiddler,title) {
if(title.substr(0,operator.operand.length) !== operator.operand) {
results.push(title);
}
});
} else {
source(function(tiddler,title) {
if(title.substr(0,operator.operand.length) === operator.operand) {
results.push(title);
}
});
}
}
return results;
};

View File

@@ -16,12 +16,22 @@ Filter operator for removing a prefix from each title in the list. Titles that d
Export our filter function
*/
exports.removeprefix = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
if(title.substr(0,operator.operand.length) === operator.operand) {
results.push(title.substr(operator.operand.length));
}
});
var results = [],
suffixes = (operator.suffixes || [])[0] || [];
if(suffixes.indexOf("caseinsensitive") !== -1) {
var operand = operator.operand.toLowerCase();
source(function(tiddler,title) {
if(title.toLowerCase().substr(0,operand.length) === operand) {
results.push(title.substr(operand.length));
}
});
} else {
source(function(tiddler,title) {
if(title.substr(0,operator.operand.length) === operator.operand) {
results.push(title.substr(operator.operand.length));
}
});
}
return results;
};

View File

@@ -16,12 +16,26 @@ Filter operator for removing a suffix from each title in the list. Titles that d
Export our filter function
*/
exports.removesuffix = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
if(title && title.substr(-operator.operand.length) === operator.operand) {
results.push(title.substr(0,title.length - operator.operand.length));
}
});
var results = [],
suffixes = (operator.suffixes || [])[0] || [];
if (!operator.operand) {
source(function(tiddler,title) {
results.push(title);
});
} else if(suffixes.indexOf("caseinsensitive") !== -1) {
var operand = operator.operand.toLowerCase();
source(function(tiddler,title) {
if(title && title.toLowerCase().substr(-operand.length) === operand) {
results.push(title.substr(0,title.length - operand.length));
}
});
} else {
source(function(tiddler,title) {
if(title && title.substr(-operator.operand.length) === operator.operand) {
results.push(title.substr(0,title.length - operator.operand.length));
}
});
}
return results;
};

View File

@@ -40,6 +40,7 @@ exports.search = function(source,operator,options) {
invert: invert,
field: fields,
excludeField: excludeFields,
some: hasFlag("some"),
caseSensitive: hasFlag("casesensitive"),
literal: hasFlag("literal"),
whitespace: hasFlag("whitespace"),

View File

@@ -16,19 +16,41 @@ Filter operator for checking if a title ends with a suffix
Export our filter function
*/
exports.suffix = function(source,operator,options) {
var results = [];
if(operator.prefix === "!") {
var results = [],
suffixes = (operator.suffixes || [])[0] || [];
if (!operator.operand) {
source(function(tiddler,title) {
if(title.substr(-operator.operand.length) !== operator.operand) {
results.push(title);
}
results.push(title);
});
} else if(suffixes.indexOf("caseinsensitive") !== -1) {
var operand = operator.operand.toLowerCase();
if(operator.prefix === "!") {
source(function(tiddler,title) {
if(title.toLowerCase().substr(-operand.length) !== operand) {
results.push(title);
}
});
} else {
source(function(tiddler,title) {
if(title.toLowerCase().substr(-operand.length) === operand) {
results.push(title);
}
});
}
} else {
source(function(tiddler,title) {
if(title.substr(-operator.operand.length) === operator.operand) {
results.push(title);
}
});
if(operator.prefix === "!") {
source(function(tiddler,title) {
if(title.substr(-operator.operand.length) !== operator.operand) {
results.push(title);
}
});
} else {
source(function(tiddler,title) {
if(title.substr(-operator.operand.length) === operator.operand) {
results.push(title);
}
});
}
}
return results;
};

View File

@@ -19,7 +19,7 @@ exports.untagged = function(source,operator,options) {
var results = [],
expected = (operator.prefix === "!");
source(function(tiddler,title) {
if((tiddler && $tw.utils.isArray(tiddler.fields.tags) && tiddler.fields.tags.length > 0) === expected) {
if(((tiddler && $tw.utils.isArray(tiddler.fields.tags) && tiddler.fields.tags.length > 0) === expected) || (!tiddler && !expected)) {
results.push(title);
}
});

View File

@@ -239,7 +239,7 @@ exports.parseFilterVariable = function(source) {
};
/*
Look for an HTML attribute definition. Returns null if not found, otherwise returns {type: "attribute", name:, valueType: "string|indirect|macro", value:, start:, end:,}
Look for an HTML attribute definition. Returns null if not found, otherwise returns {type: "attribute", name:, type: "filtered|string|indirect|macro", value|filter|textReference:, start:, end:,}
*/
exports.parseAttribute = function(source,pos) {
var node = {
@@ -248,7 +248,7 @@ exports.parseAttribute = function(source,pos) {
// Define our regexps
var reAttributeName = /([^\/\s>"'=]+)/g,
reUnquotedAttribute = /([^\/\s<>"'=]+)/g,
reFilteredValue = /\{\{\{(.+?)\}\}\}/g,
reFilteredValue = /\{\{\{([\S\s]+?)\}\}\}/g,
reIndirectValue = /\{\{([^\}]+)\}\}/g;
// Skip whitespace
pos = $tw.utils.skipWhiteSpace(source,pos);

View File

@@ -34,7 +34,6 @@ function Server(options) {
this.authenticators = options.authenticators || [];
this.wiki = options.wiki;
this.boot = options.boot || $tw.boot;
this.servername = $tw.utils.transliterateToSafeASCII(this.wiki.getTiddlerText("$:/SiteTitle") || "TiddlyWiki5");
// Initialise the variables
this.variables = $tw.utils.extend({},this.defaultVariables);
if(options.variables) {
@@ -44,7 +43,8 @@ function Server(options) {
}
}
}
$tw.utils.extend({},this.defaultVariables,options.variables);
// Setup the default required plugins
this.requiredPlugins = this.get("required-plugins").split(',');
// Initialise CSRF
this.csrfDisable = this.get("csrf-disable") === "yes";
// Initialize Gzip compression
@@ -52,14 +52,24 @@ function Server(options) {
// Initialize browser-caching
this.enableBrowserCache = this.get("use-browser-cache") === "yes";
// Initialise authorization
var authorizedUserName = (this.get("username") && this.get("password")) ? this.get("username") : "(anon)";
var authorizedUserName;
if(this.get("username") && this.get("password")) {
authorizedUserName = this.get("username");
} else if(this.get("credentials")) {
authorizedUserName = "(authenticated)";
} else {
authorizedUserName = "(anon)";
}
this.authorizationPrincipals = {
readers: (this.get("readers") || authorizedUserName).split(",").map($tw.utils.trim),
writers: (this.get("writers") || authorizedUserName).split(",").map($tw.utils.trim)
}
if(this.get("admin") || authorizedUserName !== "(anon)") {
this.authorizationPrincipals["admin"] = (this.get("admin") || authorizedUserName).split(',').map($tw.utils.trim)
}
// Load and initialise authenticators
$tw.modules.forEachModuleOfType("authenticator", function(title,authenticatorDefinition) {
// console.log("Loading server route " + title);
// console.log("Loading authenticator " + title);
self.addAuthenticator(authenticatorDefinition.AuthenticatorClass);
});
// Load route handlers
@@ -71,15 +81,21 @@ function Server(options) {
this.listenOptions = null;
this.protocol = "http";
var tlsKeyFilepath = this.get("tls-key"),
tlsCertFilepath = this.get("tls-cert");
tlsCertFilepath = this.get("tls-cert"),
tlsPassphrase = this.get("tls-passphrase");
if(tlsCertFilepath && tlsKeyFilepath) {
this.listenOptions = {
key: fs.readFileSync(path.resolve(this.boot.wikiPath,tlsKeyFilepath),"utf8"),
cert: fs.readFileSync(path.resolve(this.boot.wikiPath,tlsCertFilepath),"utf8")
cert: fs.readFileSync(path.resolve(this.boot.wikiPath,tlsCertFilepath),"utf8"),
passphrase: tlsPassphrase || ''
};
this.protocol = "https";
}
this.transport = require(this.protocol);
// Name the server and init the boot state
this.servername = $tw.utils.transliterateToSafeASCII(this.get("server-name") || this.wiki.getTiddlerText("$:/SiteTitle") || "TiddlyWiki5");
this.boot.origin = this.get("origin")? this.get("origin"): this.protocol+"://"+this.get("host")+":"+this.get("port");
this.boot.pathPrefix = this.get("path-prefix") || "";
}
/*
@@ -150,6 +166,7 @@ function sendResponse(request,response,statusCode,headers,data,encoding) {
Server.prototype.defaultVariables = {
port: "8080",
host: "127.0.0.1",
"required-plugins": "$:/plugins/tiddlywiki/filesystem,$:/plugins/tiddlywiki/tiddlyweb",
"root-tiddler": "$:/core/save/all",
"root-render-type": "text/plain",
"root-serve-type": "text/html",
@@ -239,15 +256,15 @@ Server.prototype.requestHandler = function(request,response,options) {
state.pathPrefix = options.pathPrefix || this.get("path-prefix") || "";
state.sendResponse = sendResponse.bind(self,request,response);
// Get the principals authorized to access this resource
var authorizationType = this.methodMappings[request.method] || "readers";
state.authorizationType = options.authorizationType || this.methodMappings[request.method] || "readers";
// Check for the CSRF header if this is a write
if(!this.csrfDisable && authorizationType === "writers" && request.headers["x-requested-with"] !== "TiddlyWiki") {
if(!this.csrfDisable && state.authorizationType === "writers" && request.headers["x-requested-with"] !== "TiddlyWiki") {
response.writeHead(403,"'X-Requested-With' header required to login to '" + this.servername + "'");
response.end();
return;
}
// Check whether anonymous access is granted
state.allowAnon = this.isAuthorized(authorizationType,null);
state.allowAnon = this.isAuthorized(state.authorizationType,null);
// Authenticate with the first active authenticator
if(this.authenticators.length > 0) {
if(!this.authenticators[0].authenticateRequest(request,response,state)) {
@@ -256,7 +273,7 @@ Server.prototype.requestHandler = function(request,response,options) {
}
}
// Authorize with the authenticated username
if(!this.isAuthorized(authorizationType,state.authenticatedUsername)) {
if(!this.isAuthorized(state.authorizationType,state.authenticatedUsername)) {
response.writeHead(401,"'" + state.authenticatedUsername + "' is not authorized to access '" + this.servername + "'");
response.end();
return;
@@ -322,8 +339,16 @@ Server.prototype.listen = function(port,host,prefix) {
port = process.env[port] || 8080;
}
// Warn if required plugins are missing
if(!this.wiki.getTiddler("$:/plugins/tiddlywiki/tiddlyweb") || !this.wiki.getTiddler("$:/plugins/tiddlywiki/filesystem")) {
$tw.utils.warning("Warning: Plugins required for client-server operation (\"tiddlywiki/filesystem\" and \"tiddlywiki/tiddlyweb\") are missing from tiddlywiki.info file");
var missing = [];
for (var index=0; index<this.requiredPlugins.length; index++) {
if (!this.wiki.getTiddler(this.requiredPlugins[index])) {
missing.push(this.requiredPlugins[index]);
}
}
if(missing.length > 0) {
var error = "Warning: Plugin(s) required for client-server operation are missing.\n"+
"\""+ missing.join("\", \"")+"\"";
$tw.utils.warning(error);
}
// Create the server
var server;

View File

@@ -51,6 +51,20 @@ exports.startup = function() {
element.focus(event.paramObject);
}
});
// Install the tm-rename-tiddler and tm-relink-tiddler messages
var makeRenameHandler = function(method) {
return function(event) {
var options = {},
paramObject = event.paramObject || {},
from = paramObject.from || event.tiddlerTitle,
to = paramObject.to;
options.dontRenameInTags = (paramObject.renameInTags === "false" || paramObject.renameInTags === "no") ? true : false;
options.dontRenameInLists = (paramObject.renameInLists === "false" || paramObject.renameInLists === "no") ? true : false;
$tw.wiki[method](from,to,options);
};
};
$tw.rootWidget.addEventListener("tm-rename-tiddler",makeRenameHandler("renameTiddler"));
$tw.rootWidget.addEventListener("tm-relink-tiddler",makeRenameHandler("relinkTiddler"));
// Install the scroller
$tw.pageScroller = new $tw.utils.PageScroller();
$tw.rootWidget.addEventListener("tm-scroll",function(event) {

View File

@@ -20,6 +20,8 @@ exports.synchronous = true;
// Global to keep track of open windows (hashmap by title)
$tw.windows = {};
// Default template to use for new windows
var DEFAULT_WINDOW_TEMPLATE = "$:/core/templates/single.tiddler.window";
exports.startup = function() {
// Handle open window message
@@ -29,22 +31,25 @@ exports.startup = function() {
title = event.param || event.tiddlerTitle,
paramObject = event.paramObject || {},
windowTitle = paramObject.windowTitle || title,
template = paramObject.template || "$:/core/templates/single.tiddler.window",
windowID = paramObject.windowID || title,
template = paramObject.template || DEFAULT_WINDOW_TEMPLATE,
width = paramObject.width || "700",
height = paramObject.height || "600",
variables = $tw.utils.extend({},paramObject,{currentTiddler: title});
top = paramObject.top,
left = paramObject.left,
variables = $tw.utils.extend({},paramObject,{currentTiddler: title, "tv-window-id": windowID});
// Open the window
var srcWindow,
srcDocument;
// In case that popup blockers deny opening a new window
try {
srcWindow = window.open("","external-" + title,"scrollbars,width=" + width + ",height=" + height),
srcWindow = window.open("","external-" + windowID,"scrollbars,width=" + width + ",height=" + height + (top ? ",top=" + top : "" ) + (left ? ",left=" + left : "" )),
srcDocument = srcWindow.document;
}
catch(e) {
return;
}
$tw.windows[title] = srcWindow;
$tw.windows[windowID] = srcWindow;
// Check for reopening the same window
if(srcWindow.haveInitialisedWindow) {
return;
@@ -54,7 +59,7 @@ exports.startup = function() {
srcDocument.close();
srcDocument.title = windowTitle;
srcWindow.addEventListener("beforeunload",function(event) {
delete $tw.windows[title];
delete $tw.windows[windowID];
$tw.wiki.removeEventListener("change",refreshHandler);
},false);
// Set up the styles
@@ -88,13 +93,21 @@ exports.startup = function() {
srcWindow.document.documentElement.addEventListener("click",$tw.popup,true);
srcWindow.haveInitialisedWindow = true;
});
// Close open windows when unloading main window
$tw.addUnloadTask(function() {
$tw.rootWidget.addEventListener("tm-close-window",function(event) {
var windowID = event.param,
win = $tw.windows[windowID];
if(win) {
win.close();
}
});
var closeAllWindows = function() {
$tw.utils.each($tw.windows,function(win) {
win.close();
});
});
}
$tw.rootWidget.addEventListener("tm-close-all-windows",closeAllWindows);
// Close open windows when unloading main window
$tw.addUnloadTask(closeAllWindows);
};
})();

View File

@@ -16,21 +16,23 @@ Browser data transfer utilities, used with the clipboard and drag and drop
Options:
domNode: dom node to make draggable
selector: CSS selector to identify element within domNode to be used as drag handle (optional)
dragImageType: "pill", "blank" or "dom" (the default)
dragTiddlerFn: optional function to retrieve the title of tiddler to drag
dragFilterFn: optional function to retreive the filter defining a list of tiddlers to drag
widget: widget to use as the contect for the filter
widget: widget to use as the context for the filter
*/
exports.makeDraggable = function(options) {
var dragImageType = options.dragImageType || "dom",
dragImage,
domNode = options.domNode;
domNode = options.domNode,
dragHandle = options.selector && domNode.querySelector(options.selector) || domNode;
// Make the dom node draggable (not necessary for anchor tags)
if((domNode.tagName || "").toLowerCase() !== "a") {
domNode.setAttribute("draggable","true");
dragHandle.setAttribute("draggable","true");
}
// Add event handlers
$tw.utils.addEventListeners(domNode,[
$tw.utils.addEventListeners(dragHandle,[
{name: "dragstart", handlerFunction: function(event) {
if(event.dataTransfer === undefined) {
return false;
@@ -45,7 +47,7 @@ exports.makeDraggable = function(options) {
}
var titleString = $tw.utils.stringifyList(titles);
// Check that we've something to drag
if(titles.length > 0 && event.target === domNode) {
if(titles.length > 0 && event.target === dragHandle) {
// Mark the drag in progress
$tw.dragInProgress = domNode;
// Set the dragging class on the element being dragged

View File

@@ -49,10 +49,14 @@ Handle an event
*/
PageScroller.prototype.handleEvent = function(event) {
if(event.type === "tm-scroll") {
var options = {};
if($tw.utils.hop(event.paramObject,"animationDuration")) {
options.animationDuration = event.paramObject.animationDuration;
}
if(event.paramObject && event.paramObject.selector) {
this.scrollSelectorIntoView(null,event.paramObject.selector);
this.scrollSelectorIntoView(null,event.paramObject.selector,null,options);
} else {
this.scrollIntoView(event.target);
this.scrollIntoView(event.target,null,options);
}
return false; // Event was handled
}
@@ -62,10 +66,10 @@ PageScroller.prototype.handleEvent = function(event) {
/*
Handle a scroll event hitting the page document
*/
PageScroller.prototype.scrollIntoView = function(element,callback) {
PageScroller.prototype.scrollIntoView = function(element,callback,options) {
var self = this,
duration = $tw.utils.getAnimationDuration(),
srcWindow = element ? element.ownerDocument.defaultView : window;
duration = $tw.utils.hop(options,"animationDuration") ? parseInt(options.animationDuration) : $tw.utils.getAnimationDuration(),
srcWindow = element ? element.ownerDocument.defaultView : window;
// Now get ready to scroll the body
this.cancelScroll(srcWindow);
this.startTime = Date.now();
@@ -122,11 +126,11 @@ PageScroller.prototype.scrollIntoView = function(element,callback) {
drawFrame();
};
PageScroller.prototype.scrollSelectorIntoView = function(baseElement,selector,callback) {
PageScroller.prototype.scrollSelectorIntoView = function(baseElement,selector,callback,options) {
baseElement = baseElement || document.body;
var element = baseElement.querySelector(selector);
if(element) {
this.scrollIntoView(element,callback);
this.scrollIntoView(element,callback,options);
}
};

View File

@@ -27,7 +27,10 @@ DraggableWidget.prototype = new Widget();
Render this widget into the DOM
*/
DraggableWidget.prototype.render = function(parent,nextSibling) {
var self = this;
var self = this,
tag,
domNode,
classes = [];
// Save the parent dom node
this.parentDomNode = parent;
// Compute our attributes
@@ -35,18 +38,23 @@ DraggableWidget.prototype.render = function(parent,nextSibling) {
// Execute our logic
this.execute();
// Sanitise the specified tag
var tag = this.draggableTag;
tag = this.draggableTag;
if($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {
tag = "div";
}
// Create our element
var domNode = this.document.createElement(tag);
domNode = this.document.createElement(tag);
// Assign classes
var classes = ["tc-draggable"];
if(this.draggableClasses) {
classes.push(this.draggableClasses);
}
if(!this.dragHandleSelector) {
classes.push("tc-draggable");
}
domNode.setAttribute("class",classes.join(" "));
// Insert the node into the DOM and render any children
parent.insertBefore(domNode,nextSibling);
this.renderChildren(domNode,null);
// Add event handlers
$tw.utils.makeDraggable({
domNode: domNode,
@@ -55,11 +63,9 @@ DraggableWidget.prototype.render = function(parent,nextSibling) {
startActions: self.startActions,
endActions: self.endActions,
dragImageType: self.dragImageType,
widget: this
widget: this,
selector: self.dragHandleSelector
});
// Insert the link into the DOM and render any children
parent.insertBefore(domNode,nextSibling);
this.renderChildren(domNode,null);
this.domNodes.push(domNode);
};
@@ -72,7 +78,8 @@ DraggableWidget.prototype.execute = function() {
this.draggableClasses = this.getAttribute("class");
this.startActions = this.getAttribute("startactions");
this.endActions = this.getAttribute("endactions");
this.dragImageType = this.getAttribute("dragimagetype");
this.dragImageType = this.getAttribute("dragimagetype");
this.dragHandleSelector = this.getAttribute("selector");
// Make the child widgets
this.makeChildWidgets();
};

View File

@@ -46,6 +46,7 @@ EventWidget.prototype.render = function(parent,nextSibling) {
$tw.utils.each(this.types,function(type) {
domNode.addEventListener(type,function(event) {
var selector = self.getAttribute("selector"),
matchSelector = self.getAttribute("matchSelector"),
actions = self.getAttribute("$"+type) || self.getAttribute("actions-"+type),
stopPropagation = self.getAttribute("stopPropagation","onaction"),
selectedNode = event.target,
@@ -56,46 +57,49 @@ EventWidget.prototype.render = function(parent,nextSibling) {
if(selectedNode.nodeType === 3) {
selectedNode = selectedNode.parentNode;
}
// Check that the selected node matches any matchSelector
if(matchSelector && !$tw.utils.domMatchesSelector(selectedNode,matchSelector)) {
return false;
}
if(selector) {
// Search ancestors for a node that matches the selector
while(!$tw.utils.domMatchesSelector(selectedNode,selector) && selectedNode !== domNode) {
selectedNode = selectedNode.parentNode;
}
// If we found one, copy the attributes as variables, otherwise exit
if($tw.utils.domMatchesSelector(selectedNode,selector)) {
// Only set up variables if we have actions to invoke
if(actions) {
$tw.utils.each(selectedNode.attributes,function(attribute) {
variables["dom-" + attribute.name] = attribute.value.toString();
});
//Add a variable with a popup coordinate string for the selected node
variables["tv-popup-coords"] = "(" + selectedNode.offsetLeft + "," + selectedNode.offsetTop +"," + selectedNode.offsetWidth + "," + selectedNode.offsetHeight + ")";
//Add variables for offset of selected node
variables["tv-selectednode-posx"] = selectedNode.offsetLeft.toString();
variables["tv-selectednode-posy"] = selectedNode.offsetTop.toString();
variables["tv-selectednode-width"] = selectedNode.offsetWidth.toString();
variables["tv-selectednode-height"] = selectedNode.offsetHeight.toString();
if(event.clientX && event.clientY) {
//Add variables for event X and Y position relative to selected node
selectedNodeRect = selectedNode.getBoundingClientRect();
variables["event-fromselected-posx"] = (event.clientX - selectedNodeRect.left).toString();
variables["event-fromselected-posy"] = (event.clientY - selectedNodeRect.top).toString();
//Add variables for event X and Y position relative to event catcher node
catcherNodeRect = self.domNode.getBoundingClientRect();
variables["event-fromcatcher-posx"] = (event.clientX - catcherNodeRect.left).toString();
variables["event-fromcatcher-posy"] = (event.clientY - catcherNodeRect.top).toString();
//Add variables for event X and Y position relative to the viewport
variables["event-fromviewport-posx"] = event.clientX.toString();
variables["event-fromviewport-posy"] = event.clientY.toString();
}
}
} else {
// Exit if we didn't find one
if(selectedNode === domNode) {
return false;
}
// Only set up variables if we have actions to invoke
if(actions) {
$tw.utils.each(selectedNode.attributes,function(attribute) {
variables["dom-" + attribute.name] = attribute.value.toString();
});
//Add a variable with a popup coordinate string for the selected node
variables["tv-popup-coords"] = "(" + selectedNode.offsetLeft + "," + selectedNode.offsetTop +"," + selectedNode.offsetWidth + "," + selectedNode.offsetHeight + ")";
//Add variables for offset of selected node
variables["tv-selectednode-posx"] = selectedNode.offsetLeft.toString();
variables["tv-selectednode-posy"] = selectedNode.offsetTop.toString();
variables["tv-selectednode-width"] = selectedNode.offsetWidth.toString();
variables["tv-selectednode-height"] = selectedNode.offsetHeight.toString();
if(event.clientX && event.clientY) {
//Add variables for event X and Y position relative to selected node
selectedNodeRect = selectedNode.getBoundingClientRect();
variables["event-fromselected-posx"] = (event.clientX - selectedNodeRect.left).toString();
variables["event-fromselected-posy"] = (event.clientY - selectedNodeRect.top).toString();
//Add variables for event X and Y position relative to event catcher node
catcherNodeRect = self.domNode.getBoundingClientRect();
variables["event-fromcatcher-posx"] = (event.clientX - catcherNodeRect.left).toString();
variables["event-fromcatcher-posy"] = (event.clientY - catcherNodeRect.top).toString();
//Add variables for event X and Y position relative to the viewport
variables["event-fromviewport-posx"] = event.clientX.toString();
variables["event-fromviewport-posy"] = event.clientY.toString();
}
}
}
// Execute our actions with the variables
if(actions) {

View File

@@ -46,7 +46,7 @@ ImportVariablesWidget.prototype.execute = function(tiddlerList) {
this.tiddlerList = tiddlerList || this.wiki.filterTiddlers(this.filter,this);
// Accumulate the <$set> widgets from each tiddler
$tw.utils.each(this.tiddlerList,function(title) {
var parser = widgetPointer.wiki.parseTiddler(title);
var parser = widgetPointer.wiki.parseTiddler(title,{parseAsInline:true});
if(parser) {
var parseTreeNode = parser.tree[0];
while(parseTreeNode && parseTreeNode.type === "set") {

View File

@@ -51,6 +51,9 @@ ListWidget.prototype.render = function(parent,nextSibling) {
} else {
this.storyview = null;
}
if(this.storyview && this.storyview.renderEnd) {
this.storyview.renderEnd();
}
};
/*

View File

@@ -44,8 +44,7 @@ NavigatorWidget.prototype.render = function(parent,nextSibling) {
{type: "tm-fold-tiddler", handler: "handleFoldTiddlerEvent"},
{type: "tm-fold-other-tiddlers", handler: "handleFoldOtherTiddlersEvent"},
{type: "tm-fold-all-tiddlers", handler: "handleFoldAllTiddlersEvent"},
{type: "tm-unfold-all-tiddlers", handler: "handleUnfoldAllTiddlersEvent"},
{type: "tm-rename-tiddler", handler: "handleRenameTiddlerEvent"}
{type: "tm-unfold-all-tiddlers", handler: "handleUnfoldAllTiddlersEvent"}
]);
this.parentDomNode = parent;
this.computeAttributes();
@@ -632,16 +631,6 @@ NavigatorWidget.prototype.handleUnfoldAllTiddlersEvent = function(event) {
});
};
NavigatorWidget.prototype.handleRenameTiddlerEvent = function(event) {
var options = {},
paramObject = event.paramObject || {},
from = paramObject.from || event.tiddlerTitle,
to = paramObject.to;
options.dontRenameInTags = (paramObject.renameInTags === "false" || paramObject.renameInTags === "no") ? true : false;
options.dontRenameInLists = (paramObject.renameInLists === "false" || paramObject.renameInLists === "no") ? true : false;
this.wiki.renameTiddler(from,to,options);
};
exports.navigator = NavigatorWidget;
})();

View File

@@ -38,10 +38,14 @@ ScrollableWidget.prototype.handleScrollEvent = function(event) {
if(this.outerDomNode.scrollWidth <= this.outerDomNode.offsetWidth && this.outerDomNode.scrollHeight <= this.outerDomNode.offsetHeight && this.fallthrough === "yes") {
return true;
}
var options = {};
if($tw.utils.hop(event.paramObject,"animationDuration")) {
options.animationDuration = event.paramObject.animationDuration;
}
if(event.paramObject && event.paramObject.selector) {
this.scrollSelectorIntoView(null,event.paramObject.selector);
this.scrollSelectorIntoView(null,event.paramObject.selector,null,options);
} else {
this.scrollIntoView(event.target);
this.scrollIntoView(event.target,null,options);
}
return false; // Handled event
};
@@ -49,9 +53,9 @@ ScrollableWidget.prototype.handleScrollEvent = function(event) {
/*
Scroll an element into view
*/
ScrollableWidget.prototype.scrollIntoView = function(element) {
var duration = $tw.utils.getAnimationDuration(),
srcWindow = element ? element.ownerDocument.defaultView : window;
ScrollableWidget.prototype.scrollIntoView = function(element,callback,options) {
var duration = $tw.utils.hop(options,"animationDuration") ? parseInt(options.animationDuration) : $tw.utils.getAnimationDuration(),
srcWindow = element ? element.ownerDocument.defaultView : window;
this.cancelScroll();
this.startTime = Date.now();
var scrollPosition = {
@@ -114,11 +118,11 @@ ScrollableWidget.prototype.scrollIntoView = function(element) {
}
};
ScrollableWidget.prototype.scrollSelectorIntoView = function(baseElement,selector,callback) {
ScrollableWidget.prototype.scrollSelectorIntoView = function(baseElement,selector,callback,options) {
baseElement = baseElement || document.body;
var element = baseElement.querySelector(selector);
if(element) {
this.scrollIntoView(element,callback);
this.scrollIntoView(element,callback,options);
}
};
@@ -155,8 +159,6 @@ ScrollableWidget.prototype.render = function(parent,nextSibling) {
// Create elements
this.outerDomNode = this.document.createElement("div");
$tw.utils.setStyle(this.outerDomNode,[
{overflowY: "auto"},
{overflowX: "auto"},
{webkitOverflowScrolling: "touch"}
]);
this.innerDomNode = this.document.createElement("div");

View File

@@ -314,24 +314,40 @@ excludeEventAttributes: ignores attributes whose name begins with "on"
Widget.prototype.assignAttributes = function(domNode,options) {
options = options || {};
var self = this;
$tw.utils.each(this.attributes,function(v,a) {
// Check exclusions
if(options.excludeEventAttributes && a.substr(0,2) === "on") {
v = undefined;
var assignAttribute = function(name,value) {
// Check for excluded attribute names
if(options.excludeEventAttributes && name.substr(0,2) === "on") {
value = undefined;
}
if(v !== undefined) {
var b = a.split(":");
// Setting certain attributes can cause a DOM error (eg xmlns on the svg element)
try {
if (b.length == 2 && b[0] == "xlink"){
domNode.setAttributeNS("http://www.w3.org/1999/xlink",b[1],v);
} else {
domNode.setAttributeNS(null,a,v);
if(value !== undefined) {
// Handle the xlink: namespace
var namespace = null;
if(name.substr(0,6) === "xlink:" && name.length > 6) {
namespace = "http://www.w3.org/1999/xlink";
name = name.substr(6);
}
// Handle styles
if(name.substr(0,6) === "style." && name.length > 6) {
domNode.style[$tw.utils.unHyphenateCss(name.substr(6))] = value;
} else {
// Setting certain attributes can cause a DOM error (eg xmlns on the svg element)
try {
domNode.setAttributeNS(namespace,name,value);
} catch(e) {
}
} catch(e) {
}
}
});
}
// Not all parse tree nodes have the orderedAttributes property
if(this.parseTreeNode.orderedAttributes) {
$tw.utils.each(this.parseTreeNode.orderedAttributes,function(attribute,index) {
assignAttribute(attribute.name,self.attributes[attribute.name]);
});
} else {
$tw.utils.each(Object.keys(self.attributes).sort(),function(name) {
assignAttribute(name,self.attributes[name]);
});
}
};
/*

View File

@@ -639,14 +639,25 @@ Lookup a given tiddler and return a list of all the tiddlers that include it in
*/
exports.findListingsOfTiddler = function(targetTitle,fieldName) {
fieldName = fieldName || "list";
var titles = [];
this.each(function(tiddler,title) {
var list = $tw.utils.parseStringArray(tiddler.fields[fieldName]);
if(list && list.indexOf(targetTitle) !== -1) {
titles.push(title);
}
var wiki = this;
var listings = this.getGlobalCache("listings-" + fieldName,function() {
var listings = Object.create(null);
wiki.each(function(tiddler,title) {
var list = $tw.utils.parseStringArray(tiddler.fields[fieldName]);
if(list) {
for(var i = 0; i < list.length; i++) {
var listItem = list[i],
listing = listings[listItem] || [];
if (listing.indexOf(title) === -1) {
listing.push(title);
}
listings[listItem] = listing;
}
}
});
return listings;
});
return titles;
return listings[targetTitle] || [];
};
/*
@@ -1196,23 +1207,28 @@ Return an array of tiddler titles that match a search string
text: The text string to search for
options: see below
Options available:
source: an iterator function for the source tiddlers, called source(iterator), where iterator is called as iterator(tiddler,title)
source: an iterator function for the source tiddlers, called source(iterator),
where iterator is called as iterator(tiddler,title)
exclude: An array of tiddler titles to exclude from the search
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
whitespace: same as literal except runs of whitespace are treated as a single space
regexp: treats the search term as a regular expression
words: (default) treats search string as a list of tokens, and matches if all tokens are found, regardless of adjacency or ordering
words: (default) treats search string as a list of tokens, and matches if all tokens are found,
regardless of adjacency or ordering
some: treats search string as a list of tokens, and matches if at least ONE token is found
*/
exports.search = function(text,options) {
options = options || {};
var self = this,
t,
regExpStr="",
invert = !!options.invert;
// Convert the search string into a regexp for each term
var terms, searchTermsRegExps,
@@ -1239,7 +1255,18 @@ exports.search = function(text,options) {
searchTermsRegExps = null;
console.log("Regexp error parsing /(" + text + ")/" + flags + ": ",e);
}
} else {
} else if(options.some) {
terms = text.trim().split(/ +/);
if(terms.length === 1 && terms[0] === "") {
searchTermsRegExps = null;
} else {
searchTermsRegExps = [];
for(t=0; t<terms.length; t++) {
regExpStr += (t===0) ? anchor + $tw.utils.escapeRegExp(terms[t]) : "|" + anchor + $tw.utils.escapeRegExp(terms[t]);
}
searchTermsRegExps.push(new RegExp("(" + regExpStr + ")",flags));
}
} else { // default: words
terms = text.split(/ +/);
if(terms.length === 1 && terms[0] === "") {
searchTermsRegExps = null;
@@ -1250,7 +1277,7 @@ exports.search = function(text,options) {
}
}
}
// Accumulate the array of fields to be searched or excluded from the search
// Accumulate the array of fields to be searched or excluded from the search
var fields = [];
if(options.field) {
if($tw.utils.isArray(options.field)) {

View File

@@ -2,4 +2,4 @@ title: $:/core/ui/MoreSideBar/Plugins/Languages
tags: $:/tags/MoreSideBar/Plugins
caption: {{$:/language/ControlPanel/Plugins/Languages/Caption}}
<$list filter="[!has[draft.of]plugin-type[language]sort[description]]" template="$:/core/ui/PluginListItemTemplate" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}/>
<$list filter="[!has[draft.of]plugin-type[language]sort[name]]" template="$:/core/ui/PluginListItemTemplate" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}/>

View File

@@ -2,4 +2,4 @@ title: $:/core/ui/MoreSideBar/Plugins/Plugins
tags: $:/tags/MoreSideBar/Plugins
caption: {{$:/language/ControlPanel/Plugins/Plugins/Caption}}
<$list filter="[!has[draft.of]plugin-type[plugin]sort[description]]" template="$:/core/ui/PluginListItemTemplate" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}>>/>
<$list filter="[!has[draft.of]plugin-type[plugin]sort[name]]" template="$:/core/ui/PluginListItemTemplate" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}>>/>

View File

@@ -2,4 +2,4 @@ title: $:/core/ui/MoreSideBar/Plugins/Theme
tags: $:/tags/MoreSideBar/Plugins
caption: {{$:/language/ControlPanel/Plugins/Themes/Caption}}
<$list filter="[!has[draft.of]plugin-type[theme]sort[description]]" template="$:/core/ui/PluginListItemTemplate" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}/>
<$list filter="[!has[draft.of]plugin-type[theme]sort[name]]" template="$:/core/ui/PluginListItemTemplate" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}/>

View File

@@ -6,7 +6,7 @@ caption: {{$:/language/SideBar/Open/Caption}}
\define lingo-base() $:/language/CloseAll/
\define drop-actions()
<$action-listops $tiddler=<<tv-story-list>> $subfilter="+[insertbefore:currentTiddler<actionTiddler>]"/>
<$action-listops $tiddler=<<tv-story-list>> $subfilter="+[insertbefore<actionTiddler>,<currentTiddler>]"/>
\end
\define placeholder()

View File

@@ -17,7 +17,7 @@ tags: $:/tags/Macro
\end
\define list-links-draggable-drop-actions()
<$action-listops $tiddler=<<targetTiddler>> $field=<<targetField>> $subfilter="+[insertbefore:currentTiddler<actionTiddler>]"/>
<$action-listops $tiddler=<<targetTiddler>> $field=<<targetField>> $subfilter="+[insertbefore<actionTiddler>,<currentTiddler>]"/>
\end
\define list-links-draggable(tiddler,field:"list",type:"ul",subtype:"li",class:"",itemTemplate)
@@ -61,7 +61,7 @@ tags: $:/tags/Macro
<$action-deletefield $field="list-after"/>
</$list>
<!-- Save the new order to the Tag Tiddler -->
<$action-listops $tiddler=<<__tag__>> $field="list" $filter="+[enlist<order>] +[insertbefore:currentTiddler<actionTiddler>]"/>
<$action-listops $tiddler=<<__tag__>> $field="list" $filter="+[enlist<order>] +[insertbefore<actionTiddler>,<currentTiddler>]"/>
<!-- Make sure the newly added item has the right tag -->
<!-- Removing this line makes dragging tags within the dropdown work as intended -->
<!--<$action-listops $tiddler=<<actionTiddler>> $tags=<<__tag__>>/>-->

View File

@@ -1,10 +1,10 @@
chapter.of: Extended Persistence
created: 20140708084850294
modified: 20140717181245449
modified: 20210720193245000
sub.num: 3
tags: doc
title: Syncadaptor
A module with ``module-type: syncadaptor`` provides functionality to get a list of tiddlers (this list is provided as ~SkinnyTiddlers, which are normal tiddlers without the text field) and to load, save and delete single tiddlers. A syncadaptor can also provide functions to login and logout so that syncadaptor modules can be used to synchronize tiddlers with a remote server.
The syncer module only uses one syncadaptor and honours a special [[system tiddler|System Tiddlers]] [[$:/config/SyncFilter]] containing a [[filter string|Tags and Filter Mechanism]]. Tiddlers matching this filter string are not saved to the server with a syncadapter. It uses the [[WebServer API|https://tiddlywiki.com/#WebServer%20API%3A%20Get%20All%20Tiddlers]] to load modified tiddlers from the server, which returns only non-system tiddlers.
The syncer module only uses one syncadaptor and honours a special [[system tiddler|System Tiddlers]] [[$:/config/SyncFilter]] containing a [[filter string|Tags and Filter Mechanism]]. Tiddlers matching this filter string are saved to the server with a syncadapter. It uses the [[WebServer API|https://tiddlywiki.com/#WebServer%20API%3A%20Get%20All%20Tiddlers]] to load modified tiddlers from the server, which returns only non-system tiddlers.

View File

@@ -5,7 +5,7 @@ caption: {{$:/language/SideBar/Open/Caption}}
\define lingo-base() $:/language/CloseAll/
\define drop-actions()
<$action-listops $tiddler="$:/StoryList" $subfilter="+[insertbefore:currentTiddler<actionTiddler>]"/>
<$action-listops $tiddler="$:/StoryList" $subfilter="+[insertbefore<actionTiddler>,<currentTiddler>]"/>
\end
<$list filter="[list[$:/StoryList]]" history="$:/HistoryList" storyview="pop">

View File

@@ -0,0 +1,7 @@
created: 20220219141117559
list-before: $:/config/ViewTemplateTitleFilters/default
modified: 20220220192507247
tags: $:/tags/ViewTemplateTitleFilter
title: $:/config/ViewTemplateTitleFilters/fr-default
[has[fr-title]then[$:/core/ui/ViewTemplate/title/fr-default]]

View File

@@ -0,0 +1,8 @@
created: 20220219134855444
modified: 20220220192530872
title: $:/core/ui/ViewTemplate/title/fr-default
\whitespace trim
<h2 class="tc-title">
<$view field="fr-title"/>
</h2>

View File

@@ -0,0 +1,174 @@
created: 20150117152607000
modified: 20220220000852855
tags: $:/tags/Macro
title: $:/editions/tw5.com/doc-macros
type: text/vnd.tiddlywiki
\define .concat(1,2,3,4,5) $1$$2$$3$$4$$5$
\define .def(_) <dfn class="doc-def">$_$</dfn>
\define .em(_) <em class="doc-em">$_$</em>
\define .strong(_) <strong class="doc-strong">$_$</strong>
\define .place(_) <code class="doc-place">$_$</code>
\define .word(_) "$_$"
\define .preamble(_) :.doc-preamble $_$
\define .note(_)
@@.doc-note
;Note
: $_$
@@
\end
\define .tid(_) <code class="doc-tiddler">$_$</code>
\define .tag(_) <code class="doc-tag">$_$</code>
\define .field(_) <code class="doc-field">$_$</code>
\define .value(_) <code class="doc-value">$_$</code>
\define .op(_) <code class="doc-operator">$_$</code>
\define .var(_) <code class="doc-var">$_$</code>
\define .wid(_) <code class="doc-widget">$$_$</code>
\define .attr(_) <code class="doc-attr">$_$</code>
\define .param(_) <code class="doc-param">$_$</code>
\define .mtitle(_) $_$ Macro
\define .otitle(_) $_$ Operator
\define .vtitle(_) $_$ Variable
\define .link(_,to) <$link to="$to$">$_$</$link>
\define .clink(_,to) <span class="doc-clink"><<.link """$_$""" "$to$">></span>
\define .dlink(_,to) <$macrocall $name=".link" _=<<.def "$_$">> to="$to$">/>
\define .dlink-ex(_,to) <a href="$to$" class="tc-tiddlylink-external" target="_blank" rel="noopener noreferrer"><<.def "$_$">></a>
\define .flink(to) <$macrocall $name=".link" _=<<.field {{$to$!!caption}}>> to="$to$"/>
\define .mlink(_,to) <$macrocall $name=".link" _=<<.var "$_$">> to=<<.mtitle "$_$">>/>
\define .mlink2(_,to) <$macrocall $name=".link" _=<<.var "$_$">> to="$to$"/>
\define .olink(_) <$macrocall $name=".link" _=<<.op "$_$">> to=<<.otitle "$_$">>/>
\define .olink2(_,to) <$macrocall $name=".link" _=<<.op "$_$">> to=<<.otitle "$to$">>/>
\define .vlink(_,to) <$macrocall $name=".link" _=<<.var "$_$">> to=<<.vtitle "$_$">>/>
\define .vlink2(_,to) <$macrocall $name=".link" _=<<.var "$_$">> to="$to$"/>
\define .wlink(to) <$macrocall $name=".link" _=<<.wid {{$to$!!caption}}>> to="$to$"/>
\define .wlink2(_,to) <$macrocall $name=".link" _="$_$" to="$to$"/>
\define .key(_) <span class="doc-key">$_$</span>
\define .combokey(_) <$macrocall $name=".if" cond="$_$" then=<<.key '$_$'>>/>
\define .keycombo(1,2,3,4) <<.combokey "$1$">><<.if "$2$" +>><<.combokey "$2$">><<.if "$3$" +>><<.combokey "$3$">><<.if "$4$" +>><<.combokey "$4$">>
\define .tab(_) <span class="doc-tab">{{$_$!!caption}}</span>
\define .sidebar-tab(_) <<.tab "$:/core/ui/SideBar/$_$">>
\define .more-tab(_) <<.tab "$:/core/ui/MoreSideBar/$_$">>
\define .info-tab(_) <<.tab "$:/core/ui/TiddlerInfo/$_$">>
\define .controlpanel-tab(_) <<.tab "$:/core/ui/ControlPanel/$_$">>
\define .advancedsearch-tab(_) <<.tab "$:/core/ui/AdvancedSearch/$_$">>
\define .toc-tab() <<.tab "TableOfContents">>
\define .example-tab(_) <span class="doc-tab">$_$</span>
\define .button(_) <span class="doc-button">{{$:/core/ui/Buttons/$_$!!caption}}</span>
\define .icon(_) <span class="doc-icon">{{$_$}}</span>
\define .tip(_) <div class="doc-icon-block"><div class="doc-block-icon">{{$:/core/images/tip}}</div> $_$</div>
\define .warning(_) <div class="doc-icon-block"><div class="doc-block-icon">{{$:/core/images/warning}}</div> $_$</div>
\define .state-prefix() $:/state/editions/tw5.com/
\define .lorem()
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
\end
\define .toc-lorem()
C'est un exemple de tiddler. Voir [[Macros Table des matières (Exemples)|Table-of-Contents Macros (Examples)]].
<<.lorem>>
\end
\define .example(n,eg,egvar:NO-SUCH-VAR)
<div class="doc-example">
<$reveal default="$egvar$" type="match" text="NO-SUCH-VAR">
<$macrocall $name="copy-to-clipboard-above-right" src="""$eg$"""/>
<$codeblock code="""$eg$"""/>
</$reveal>
<$reveal default="$egvar$" type="nomatch" text="NO-SUCH-VAR">
<!-- allow an example to contain """ -->
<$macrocall $name="copy-to-clipboard-above-right" src=<<$egvar$>>/>
<$codeblock code=<<$egvar$>>/>
</$reveal>
<$list filter="[title<.state-prefix>addsuffix{!!title}addsuffix[/]addsuffix[$n$]]" variable=".state">
<$reveal state=<<.state>> type="nomatch" text="show">
<dl>
<dd><$button set=<<.state>> setTo="show">Essayez</$button></dd>
</dl>
</$reveal>
<$reveal state=<<.state>> type="match" text="show">
<dl>
<dd><$button set=<<.state>> setTo="">Cachez</$button></dd>
</dl>
<blockquote class="doc-example-result">
<$reveal default="$egvar$" type="match" text="NO-SUCH-VAR">
$eg$
</$reveal>
<$reveal default="$egvar$" type="nomatch" text="NO-SUCH-VAR">
<<$egvar$>>
</$reveal>
</blockquote>
</$reveal>
</$list>
\end
\define .bad-example(eg)
<table class="doc-bad-example">
<tbody>
<tr class="evenRow">
<td><span class="tc-inline-style" style="font-size:1.5em;">&#9888;</span> Warning:<br> Don't do it this way!</td>
<td>
$eg$
</td>
</tr>
</tbody>
</table>
\end
\define .link-badge(text,link,colour)
<a href=<<__link__>> class="doc-link-badge" style="background-color:$colour$;" target="_blank" rel="noopener noreferrer"><$text text=<<__text__>>/></a>
\end
\define .link-badge-added(link,colour:#ffe246) <<.link-badge "added" """$link$""" """$colour$""">>
\define .link-badge-addendum(link,colour:#fcc84a) <<.link-badge "addendum" """$link$""" """$colour$""">>
\define .link-badge-extended(link,colour:#f9a344) <<.link-badge "extended" """$link$""" """$colour$""">>
\define .link-badge-fixed(link,colour:#ffa86d) <<.link-badge "fixed" """$link$""" """$colour$""">>
\define .link-badge-here(link,colour:#d88e63) <<.link-badge "here" """$link$""" """$colour$""">>
\define .link-badge-hide(link,colour:#9d959f) <<.link-badge "hide" """$link$""" """$colour$""">>
\define .link-badge-improved(link,colour:#7593c7) <<.link-badge "improved" """$link$""" """$colour$""">>
\define .link-badge-modified(link,colour:#7f99c9) <<.link-badge "modified" """$link$""" """$colour$""">>
\define .link-badge-removed(link,colour:#a9aabc) <<.link-badge "removed" """$link$""" """$colour$""">>
\define .link-badge-renamed(link,colour:#b4b995) <<.link-badge "renamed" """$link$""" """$colour$""">>
\define .link-badge-updated(link,colour:#91ba66) <<.link-badge "updated" """$link$""" """$colour$""">>
\define .tiddler-fields(tiddler)
<$tiddler tiddler=<<__tiddler__>>>
<div class="doc-tiddler-fields">
<h2>
<$link>
<span class="tc-tiddler-title-icon">{{||$:/core/ui/TiddlerIcon}}</span><$text text=<<currentTiddler>>/>
</$link>
</h2>
<table class="tc-view-field-table">
<tbody>
<$list filter="[all[current]fields[]sort[title]] -title" template="$:/core/ui/TiddlerFieldTemplate" variable="listItem"/>
</tbody>
</table>
</div>
</$tiddler>
\end
\define .banner-credits(credit,url)
<img src=<<__url__>> width="140" style="float:left;margin-right:0.5em;"/>
$credit$
<div style="clear:both;">
</div>
\end
<pre><$view field="text"/></pre>

View File

@@ -1,46 +0,0 @@
created: 20141119191707140
modified: 20141128165607841
tags: $:/tags/ViewTemplate
title: $:/core/ui/ViewTemplate/title
type: text/vnd.tiddlywiki
\define title-styles()
fill:$(foregroundColor)$;
\end
\define config-title()
$:/config/ViewToolbarButtons/Visibility/$(listItem)$
\end
<div class="tc-tiddler-title">
<div class="tc-titlebar">
<span class="tc-tiddler-controls">
<$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewToolbar]!has[draft.of]]" variable="listItem"><$reveal type="nomatch" state=<<config-title>> text="hide"><$transclude tiddler=<<listItem>>/></$reveal></$list>
</span>
<$set name="tv-wikilinks" value={{$:/config/Tiddlers/TitleLinks}}>
<$link>
<$set name="foregroundColor" value={{!!color}}>
<span class="tc-tiddler-title-icon" style=<<title-styles>>>
<$transclude tiddler={{!!icon}}/>
</span>
</$set>
<$list filter="[all[current]removeprefix[$:/]]">
<h2 class="tc-title" title={{$:/language/SystemTiddler/Tooltip}}>
<span class="tc-system-title-prefix">$:/</span><$text text=<<currentTiddler>>/>
</h2>
</$list>
<$list filter="[all[current]!prefix[$:/]]">
<h2 class="tc-title">
<$view field="fr-title">
<$view field="title"/>
</$view>
</h2>
</$list>
</$link>
</$set>
</div>
<$reveal type="nomatch" text="" default="" state=<<tiddlerInfoState>> class="tc-tiddler-info tc-popup-handle" animate="yes" retain="yes">
<$transclude tiddler="$:/core/ui/TiddlerInfo"/>
</$reveal>
</div>

View File

@@ -36,3 +36,4 @@ type: text/vnd.tiddlywiki
<!-- NO-BREAK SPACE Unicode: U+00A0, UTF-8: C2 A0, ISO-8859-1: A0 -->
«&#160;$text$&#160;»
\end
\define fr(cible) <$link to="$cible$"><$view tiddler="$cible$" field="fr-title">{{$cible$!!title}}</$view></$link>

View File

@@ -0,0 +1,11 @@
created: 20210322151848025
fr-title: Agrégateur de liens communautaire
modified: 20220217174626896
tags: Community
title: Community Links Aggregator
L'Agrégateur de liens communautaire est une collection fréquemment mise à jour de liens vers des ressources utiles et intéressantes sur <<tw>>, dénichés par notre équipe d'éditeurs communautaires. Le site agrège les liens soigneusement sélectionnés par les membres de la communauté <<tw>>. Il permet de visualiser les liens les plus récents, et de les explorer par catégorie et chronologiquement.
https://links.tiddlywiki.com/
Plus les contributeurs sont nombreux, et mieux le site fonctionne<<!>> Comme chacun n'est pas tenu de recenser chaque lien qui passe, la pression individuelle sur les contributeurs est réduite. L'agrégation des liens réduit aussi l'impact d'une erreur, par exemple d'une erreur de catégorisation<<:>> si un contributeur catégorise un lien dans la mauvaise rubrique, le site permet de voir qu'une seule personne a utilisé cette rubrique, alors que la majorité utilise la catégorie appropriée. Ainsi, nous espérons qu'une sorte de //intelligence collective// émergera, avec un consensus sur la manière la plus utile de décrire et de catégoriser les liens.

View File

@@ -1,10 +1,12 @@
fr-title: Communauté
created: 20130909151600000
modified: 20141019103047540
fr-title: Communauté
modified: 20220217155910582
tags: TableOfContents
title: Community
type: text/vnd.tiddlywiki
C'est ici que nous rassemblons les dernières productions les plus utiles en provenance de la communauté <<tw>>.
<<.tip "Les liens les plus utiles et les plus récents sont maintenant regroupés dans [[lAgrégateur de liens communautaire|Community Links Aggregator]].">>
<<tabs "Forums Latest Tutorials Resources Examples Articles Meetups" "Latest">>
Lorsque tous les liens pertinents auront été transférés, ces entrées seront retirées du site tiddlywiki.com.
<<tabs "Forums Latest Tutorials [[Community Editions]] [[Community Plugins]] [[Community Themes]] [[Community Palettes]] [[Other Resources]] Examples Articles Meetups" "Latest">>

View File

@@ -1,12 +1,17 @@
created: 20150412191004348
fr-title: Développeurs
modified: 20150621192259510
modified: 20220217174800697
tags: Community
title: Developers
type: text/vnd.tiddlywiki
Les développeurs disposent de plusieurs ressources pour discuter et contribuer au développement de TiddlyWiki.
Plusieurs ressources permettent aux développeurs d'en apprendre plus sur <<tw>>, de collaborer et de discuter de son développement.
* [[tiddlywiki.com/dev|https://tiddlywiki.com/dev]] la documentation officielle de développement
* [[TiddlyWikiDev group|http://groups.google.com/group/TiddlyWikiDev]] pour les discussions au sujet du développement de TiddlyWiki
* https://github.com/Jermolene/TiddlyWiki5 pour le code source et l'activité de développement
* [[tiddlywiki.com/dev|https://tiddlywiki.com/dev]] est la documentation officielle des développeurs
* Vous pouvez vous impliquer dans le développement de <<tw>> sur [[GitHub|https://github.com/Jermolene/TiddlyWiki5]]
** Les [[discussions|https://github.com/Jermolene/TiddlyWiki5/discussions]] sont disponibles pour les questions ouvertes et les questions/réponses.
** Les [[problèmes|https://github.com/Jermolene/TiddlyWiki5/issues]] permettent de signaler les bogues et de proposer de nouvelles idées spécifiques, réalistes et raisonnables
* L'ancien groupe ~TiddlyWikiDev sur Google Group est maintenant fermé, et remplacé par les [[discussions GitHub|https://github.com/Jermolene/TiddlyWiki5/discussions]], mais une archive reste disponible<<:>> https://groups.google.com/group/TiddlyWikiDev
** Une fonctionnalité de recherche étendue du groupe est disponible sur [[mail-archive.com|https://www.mail-archive.com/tiddlywikidev@googlegroups.com/]]
* Pour les dernières nouvelles, suivez [[@TiddlyWiki sur Twitter|http://twitter.com/#!/TiddlyWiki]]
* Tchatchez sur https://gitter.im/TiddlyWiki/public (une salle dédiée au développement arrive bientôt)

View File

@@ -0,0 +1,11 @@
created: 20130825154900000
modified: 20220219164816011
tags: Definitions
title: Federatial
type: text/vnd.tiddlywiki
Federatial Limited est une entreprise de consultants en logiciel fondée par JeremyRuston, le créateur de <<tw>>.
Federatial aide les organisations à explorer de nouveaux concepts d'interaction utilisateur grâce au prototypage rapide d'outils sophistiqués basés sur le web.
Pour plus d'informations, visitez [[https://federatial.com/]] et [[https://twitter.com/federatial]].

View File

@@ -1,25 +1,39 @@
caption: Forum
created: 20140721121924384
fr-title: Forum
modified: 20150614155153966
modified: 20220217174719926
tags: Community
title: Forums
type: text/vnd.tiddlywiki
! Utilisateurs
! Forum en français
Les groupes de discussion ~TiddlyWiki sont des listes de publipostage pour discuter de ~TiddlyWiki<<:>> demandes d'aide, annonces de nouvelles version et plugins, échanges sur les nouvelles fonctionnalités, ou simples partages d'expériences. Vous pouvez participer via le site web associé, ou souscrire par email.
La communauté francophone sur <<tw>> a son forum, venez contribuer<<!>>
* Le groupe principal de ~TiddlyWiki<<:>> http://groups.google.com/group/TiddlyWiki
*> Notez qu'il n'est nul besoin d'avoir un compte Google pour vous joindre aux groupes de discussion. Souscrire par l'envoi d'un email à mailto:tiddlywiki+subscribe@googlegroups.com ou mailto:tiddlywikidev+subscribe@googlegroups.com.
* Visualiser les enregistrements de nos réguliers [[TiddlyWiki Hangouts]]
* Suivre [[@TiddlyWiki sur Twitter|http://twitter.com/TiddlyWiki]] pour les dernières nouvelles.
https://forum.tiddlywiki.fr/
! Développeurs
! Forums officiels
* Le groupe TiddlyWikiDev pour les dévelopeurs<<:>> http://groups.google.com/group/TiddlyWikiDev
*> Notez qu'il n'est nul besoin d'avoir un compte Google pour vous joindre aux groupes de discussion. Souscrire par l'envoi d'un email à mailto:tiddlywiki+subscribe@googlegroups.com ou mailto:tiddlywikidev+subscribe@googlegroups.com.
* Suivre [[@TiddlyWiki sur Twitter|http://twitter.com/TiddlyWiki]] pour les dernières nouvelles.
* Impliquez-vous dans le [[développement sur GitHub|https://github.com/Jermolene/TiddlyWiki5]]
Le nouveau forum officiel pour discuter de <<tw>><<:>> demandes d'aide, annonces de nouvelles version et plugins, échanges sur les nouvelles fonctionnalités, ou simples partages d'expériences. Vous pouvez participer via le site web associé, ou souscrire par email.
Les nouvelles versions de TiddlyWiki, TiddlyDesktop et TiddlyFox sont annoncés par les groupes de discussion et [[Twitter|https://twitter.com/TiddlyWiki]] (vous pouvez aussi souscrire au flux Atom/RSS des [[versions de TiddlyWiki sur GitHub|https://github.com/jermolene/tiddlywiki5/releases.atom]])
https://talk.tiddlywiki.org/
Notez que talk.tiddlywiki.org est un service communautaire que nous hébergeons et maintenons nous-mêmes. Les modestes frais de mise à disposition du site sont couverts par les contributions de la communauté.
Pour le confort de la communauté, l'ancien groupe <<tw>>, hébergé sur Google Groups depuis 2005, reste fonctionnel.
https://groups.google.com/group/TiddlyWiki
! Forums des développeurs
{{Developers}}
! Autres forums
* [[TiddlyWiki Subreddit|https://www.reddit.com/r/TiddlyWiki5/]]
* Tchatchez avec Gitter sur https://gitter.im/TiddlyWiki/public<<!>>
* Tchatchez avec Discord sur https://discord.gg/HFFZVQ8
!! Documentation
Il existe un groupe de discussion spécialement dédié aux initiatives d'amélioration de la documentation<<:>> https://groups.google.com/group/tiddlywikidocs

View File

@@ -2,12 +2,12 @@ caption: Bienvenue !
created: 20130822170200000
fr-title: Bienvenue !
list: [[Discover TiddlyWiki]] [[Some of the things you can do with TiddlyWiki]] [[Ten reasons to switch to TiddlyWiki]] Examples [[History of TiddlyWiki]] [[What happened to the original TiddlyWiki?]]
modified: 20160603043549286
modified: 20220217174842374
tags: TableOfContents
title: HelloThere
type: text/vnd.tiddlywiki
''N'avez-vous jamais eu la sensation que votre tête était trop petite pour contenir tout ce dont vous avez besoin de mémoriser&nbsp;?''
''N'avez-vous jamais eu la sensation que votre tête était trop petite pour contenir tout ce que vous avez besoin de mémoriser<<?>>''
Bienvenue sur TiddlyWiki, un carnet de notes web [[non-linéaire|Philosophy of Tiddlers]] pour [[saisir|Creating and editing tiddlers]], [[organiser|Structuring TiddlyWiki]] et [[partager|Sharing your tiddlers with others]] des informations simples ou complexes.
@@ -17,19 +17,22 @@ Utilisez-le pour gérer votre [[liste de tâches|TaskManagementExample]], faire
<<list-thumbnails filter:"[tag[HelloThumbnail]]" width:"168" height:"95">>
</div>
Contrairement aux services en ligne classiques, TiddlyWiki vous permet de choisir où conserver vos informations , et garantit que, dans les décennies à venir, vous pourrez toujours utiliser les notes que vous prenez aujourd'hui.
Contrairement aux services en ligne classiques, TiddlyWiki vous permet de choisir où conserver vos informations, et garantit que, dans les décennies à venir, vous pourrez toujours utiliser les notes que vous prenez aujourd'hui.
<div style="font-size:0.7em;text-align:center;margin-top:3em;margin-bottom:3em;">
<a href="http://groups.google.com/group/TiddlyWiki" class="tc-btn-big-green" style="background-color:#FF8C19;" target="_blank" rel="noopener noreferrer">
{{$:/core/images/mail}} ~TiddlyWiki Mailing List
<div style="font-size:0.7em;text-align:center;margin:3em auto;">
<a href="https://talk.tiddlywiki.org/" class="tc-btn-big-green" style="border-radius:4px;background-color:#FF8C19;" target="_blank" rel="noopener noreferrer">
{{$:/core/images/help}} ~TalkTW
</a>
<a href="https://www.youtube.com/c/JeremyRuston" class="tc-btn-big-green" style="background-color:#e52d27;" target="_blank" rel="noopener noreferrer">
{{$:/core/images/video}} ~TiddlyWiki sur ~YouTube
<a href="https://www.youtube.com/c/JeremyRuston" class="tc-btn-big-green" style="border-radius:4px;background-color:#e52d27;" target="_blank" rel="noopener noreferrer">
{{$:/core/images/video}} ~YouTube
</a>
<a href="https://twitter.com/TiddlyWiki" class="tc-btn-big-green" style="background-color:#5E9FCA;" target="_blank" rel="noopener noreferrer">
{{$:/core/images/twitter}} @~TiddlyWiki sur Twitter
<a href="https://twitter.com/TiddlyWiki" class="tc-btn-big-green" style="border-radius:4px;background-color:#5E9FCA;" target="_blank" rel="noopener noreferrer">
{{$:/core/images/twitter}} Twitter
</a>
<a href="https://github.com/Jermolene/TiddlyWiki5" class="tc-btn-big-green" style="background-color:#444;" target="_blank" rel="noopener noreferrer">
{{$:/core/images/github}} ~TiddlyWiki sur ~GitHub
<a href="https://github.com/Jermolene/TiddlyWiki5" class="tc-btn-big-green" style="border-radius:4px;background-color:#444;" target="_blank" rel="noopener noreferrer">
{{$:/core/images/github}} ~GitHub
</a>
<a href="https://gitter.im/TiddlyWiki/public" class="tc-btn-big-green" style="border-radius:4px;background-color:#753a88;background-image:linear-gradient(to left,#cc2b5e,#753a88);" target="_blank" rel="noopener noreferrer">
{{$:/core/images/gitter}} Gitter
</a>
</div>

View File

@@ -1,21 +1,21 @@
caption: Jeremy Ruston
created: 20130825162500000
modified: 20150623064203685
modified: 20220219163924300
tags: Definitions
title: JeremyRuston
type: text/vnd.tiddlywiki
Je suis l'inventeur original de TiddlyWiki. Vous pouvez me retrouver sur ces services<<:>>
Je suis l'inventeur original de TiddlyWiki. Vous pouvez m'engager sur [[Federatial]], et me retrouver sur ces services<<:>>
* jeremy (at) jermolene (dot) com
* [[Jermolene on GitHub|https://github.com/Jermolene]]
* [[Jermolene on GitTip|https://www.gittip.com/Jermolene/]], micropaiements
* [[@Jermolene on Twitter|http://twitter.com/#!/jermolene]]
* [[Jermy on LinkedIn|http://www.linkedin.com/in/jermy]]
* [[Jermy on Flickr|http://www.flickr.com/photos/jermy/]]
* [[Jermolene sur GitHub|https://github.com/Jermolene]]
* [[Jermolene sur GitTip|https://www.gittip.com/Jermolene/]], un service de micropaiements
* [[@Jermolene sur Twitter|http://twitter.com/#!/jermolene]]
* [[Jermy sur LinkedIn|http://www.linkedin.com/in/jermy]]
* [[Jermy sur Flickr|http://www.flickr.com/photos/jermy/]]
Encore plus d'infos<<:>>
Informations supplémentaires<<:>>
* Une [[interview de moi sur The Inquirer|http://www.theinquirer.net/inquirer/feature/2105529/bt-software-engineer-tells-telco-source]] par Wendy Grossman
* Une [[interview hilarante avec moi|https://www.youtube.com/watch?v=auyIhw8MTmQ]] de la télévision britanique en 1983
* Ici, un vidéo de présentation que j'ai réalisée en 2007 appelée [["How to Start an Open Source Project"|http://vimeo.com/856110]].
* Ici, une vidéo de présentation que j'ai réalisée en 2007 intitulée [["How to Start an Open Source Project"|http://vimeo.com/856110]].

View File

@@ -1,14 +1,14 @@
caption: list
created: 20130830092500000
fr-title: Champ liste
modified: 20150614082620572
modified: 20220219194303634
tags: Fields
title: ListField
type: text/vnd.tiddlywiki
[[Champ de tiddler|TiddlerFields]], `list` peut aider à structurer son contenu. Sa valeur est une [[liste de titres|Title List]], et peut être maniée de différentes façons<<:>>
Le [[champ de tiddler|TiddlerFields]] `list` est une fonctionnalité optionnelle qui peut vous aider à structurer votre contenu. Sa valeur est une [[liste de titres|Title List]], qui peut être utilisée de différentes façons<<:>>
* Le champ `list` d'un tiddler utilisé comme étiquette détermine l'ordre des tiddlers portant ce tag - voir [[ Étiqueter |Tagging]] pour plus de détails
* Le [[filtre|Filters]] `list` sélectionne les entrées d'une liste
* Le [[filtre|Filters]] `listed` sélectionne les tiddlers listant le(s) tiddler(s) sélectionné(s)
* Le NavigatorWidget manipule un tiddler $:/StoryList contenant un champ `list` des tiddlers affichés dans la colonne principale ''Récents''
* Le champ `list` d'un tiddler utilisé comme tag détermine l'ordre des tiddlers portant ce tag -- voir [[Étiqueter|Tagging]] pour plus de détails
* Le [[filtre|Filters]] `list` sélectionne les entrées d'une liste -- voir <<fr "list Operator">>
* Le [[filtre|Filters]] `listed` sélectionne les tiddlers listant le(s) tiddler(s) sélectionné(s) -- voir <<fr "listed Operator">>
* Le widget <<.wlink NavigatorWidget>> manipule un tiddler $:/StoryList dont le champ `list` contient les tiddlers affichés dans la vue principale

View File

@@ -1,12 +1,12 @@
caption: Macros
created: 20131205160746466
fr-title: Macros dans WikiText
modified: 20150621152601026
fr-title: Macros en WikiTexte
modified: 20220219191257167
tags: WikiText
title: Macros in WikiText
type: text/vnd.tiddlywiki
L'utilisation des [[macros|Macros]] dans [[WikiTexte|WikiText]] a deux aspects distincts<<:>>
L'utilisation des [[macros|Macros]] en [[WikiTexte|WikiText]] recouvre deux aspects distincts<<:>>
* [[Définition des macros|Macro Definitions in WikiText]]
* [[Appel des macros|Macro Calls in WikiText]]
* [[La définition des macros|Macro Definitions in WikiText]]
* [[L'appel des macros|Macro Calls in WikiText]]

View File

@@ -1,19 +1,28 @@
caption: Macros
created: 20140211171341271
modified: 20150622110720298
modified: 20220219192959452
tags: Concepts Reference
title: Macros
type: text/vnd.tiddlywiki
Les macros sont des bouts de texte qui peuvent être insérés à l'aide d'un raccourci concis<<dp>>
Une <<.def macro>> est un //bout de texte// auquel on donne un nom. Le <<fr WikiText>> utilise ce nom comme raccourci pour [[transclure|Transclusion]] le //bout de texte//. Ces [[transclusions|Transclusion]] particulières s'appellent des <<.def "appels de macro">>, et chaque appel peut transmettre un ensemble différent d'arguments, qui se substituent à leur emplacement dans le //bout de texte//.
```
<<maMacro>>
```
Pour une description de la syntaxe, voir <<fr "Macros in WikiText">>.
Vous pouvez écrire vos propres [[macros en WikiText|Macros in WikiText]] ou pour plus de souplesse, vous pouvez écrire des [[macros en Javascript|JavaScript Macros]].
La plupart des macros sont en fait des [[variables|Variables]] paramétrées.
Les macros suivantes sont fournies avec <<tw>><<dp>>
Elles sont définies en utilisant le [[pragma|Pragma]] `\define`. (En coulisses, cette syntaxe est transformé en <<fr SetWidget>>, donc les macros et les variables sont bien les deux faces de la même pièce.)
<<list-links "[tag[Macros]]">>
Le //bout de texte// et ses arguments sont traités comme de simple chaînes de caractères, sans interprétation du <<fr WikiText>>, au moins jusqu'à ce que le dernier emplacement ait été rempli et que l'appel de macro soit terminé. Cela signifie qu'une macro peut assembler et renvoyer la syntaxe complète d'un composant <<fr WikiText>>, comme un [[lien|Linking in WikiText]] par exemple. (Voir <<fr "Transclusion and Substitution">> pour une discussion plus approfondie sur ce sujet.)
A l'intérieur d'un //bout de texte// lui-même, le seul balisage détecté est `$nom$` (un emplacement pour le paramètre `nom` qui sera substitué par l'argument correspondant reçu au moment d'un appel de macro) et `$(nom)$` (un emplacement pour une [[variable|Variables]]).
La macro <<.mlink dumpvariables>> liste toutes les variables (y-compris les macros) qui sont disponibles à cet endroit de l'arborescence des widgets.
Un widget <<.wlink ImportVariablesWidget>> peut être utilisé pour copier une définition de macro vers une autre branche de [[l'arbre des widgets|Widgets]]. <<tw>> utilise cette technique en interne pour implémenter des macros globales -- c'est-à-dire des macros définies dans des tiddlers étiquetés <<.tag $:/tags/Macro>>. (Le tag <<.tag $:/tags/Macro/View>> est quant à lui utilisé pour définir des macros qui ne doivent être disponibles que dans le modèle de vue principal et le panneau de prévisualisation.)
Pour un maximum de flexibilité, les macros peuvent aussi être <<.js-macro-link "écrites en tant que modules JavaScript">>.
Un effet similaire à l'utilisation de macros paramétrées peut être obtenu en encadrant une [[transclusion|Transclusion]] par une définition de [[variables|Variables]].
<<tw>> intègre [[plusieurs macros|Core Macros]] dans son cœur.

View File

@@ -1,6 +1,6 @@
created: 20131128075743966
fr-title: Philosophie des tiddlers
modified: 20141203144108401
modified: 20220220004339779
tags: Learning
title: Philosophy of Tiddlers
type: text/vnd.tiddlywiki
@@ -9,4 +9,4 @@ Lorsqu'on enregistre et organise des informations, on se donne pour objectif de
La philosophie des [[tiddlers|Tiddlers]] consiste à maximiser les possibilités de réutilisation en découpant l'information en unités sémantiques aussi petites que possible, grâce à une [[modélisation riche des relations entre elles|Structuring TiddlyWiki]]. On utilise ensuite l'agrégation et la composition pour tisser les fragments entre eux afin de construire des déroulés cohérents.
TiddlyWiki a pour ambition de proposer une algèbre pour les tiddlers<<dp>> une manière concise d'exprimer et d'explorer les relations entre les diverses pièces d'information.
<<tw>> a pour ambition de proposer une algèbre pour les tiddlers<<dp>> une manière concise d'exprimer et d'explorer les relations entre les diverses bribes d'information.

View File

@@ -1,10 +1,69 @@
fr-title: Sauvegarder les modifications
created: 20140912140651119
modified: 20141116123050408
fr-title: Sauvegarder les modifications
list:
modified: 20220217174230426
saving-browser: Firefox Chrome Edge [[Internet Explorer]] Safari Opera
saving-os: Windows Mac Linux Android iOS
tags: [[Working with TiddlyWiki]]
title: Saving
type: text/vnd.tiddlywiki
Voici les méthodes disponibles pour sauvegarder vos modifications avec TiddlyWiki<<dp>>
\define alltagsfilter()
<$vars tag1="tag[" tag2="]" lb="[" rb="tag[Saving]sort[delivery]]">
<$set filter="[list[]addprefix<tag1>addsuffix<tag2>]+[join[]addprefix<lb>addsuffix<rb>]" name="alltags" select=0>
<$text text=<<alltags>>/>
</$set>
</$vars>
\end
<<list-links "[tag[Saving]]">>
\define saverssidebaritem(item:"Linux")
<$checkbox tiddler=<<qualify $:/temp/$item$>> field="status" checked="selected" checkactions=<<checkactions "$item$">> uncheckactions=<<uncheckactions "$item$">> default="closed"> $item$</$checkbox><br/>
\end
\define saverssidebaritemlist(fieldname:"os")
<$list filter="[enlist{!!$fieldname$}]" variable="currentItem">
<$macrocall $name="saverssidebaritem" item=<<currentItem>>/>
</$list>
\end
\define uncheckactions(item:"Linux")
<$action-listops $subfilter="-[[$item$]]"/>
\end
\define checkactions(item:"Linux")
<$action-listops $subfilter="[[$item$]]"/>
\end
\define uncheckactions(item:"Linux")
<$action-listops $subfilter="-[[$item$]]"/>
\end
Méthodes disponibles pour enregistrer les modifications avec <<tw>><<:>>
<div class="tc-wrapper-flex">
<div class="tc-saving-sidebar">
<div class="tc-saving-sidebar-category">
<div class="tc-saving-sidebar-category-title">Plateforme</div>
<div class="tc-saving-sidebar-category-item">
<<saverssidebaritemlist "saving-os">>
</div>
</div>
<div class="tc-saving-sidebar-category">
<div class="tc-saving-sidebar-category-title">Navigateur internet</div>
<div class="tc-saving-sidebar-category-item">
<<saverssidebaritemlist "saving-browser">>
</div>
</div>
</div>
<!-- Page content -->
<div class="content">
<$wikify text=<<alltagsfilter>> name="alltagsfilterwikified">
<$list filter=<<alltagsfilterwikified>>>
{{||$:/_tw5.com-card-template}}
</$list>
</$wikify>
</div>
</div>

View File

@@ -1,13 +1,13 @@
created: 20131128090536894
fr-title: Structurer TiddlyWiki
modified: 20150620093923918
modified: 20220220003638545
tags: [[Working with TiddlyWiki]]
title: Structuring TiddlyWiki
type: text/vnd.tiddlywiki
TiddlyWiki5 fournit plusieurs fonctionnalités qui vous aideront à structurer les informations sous forme de [[tiddlers|Tiddlers]], et à modéliser les relations entre eux<<dp>>
TiddlyWiki5 fournit plusieurs fonctionnalités qui vous aideront à structurer les informations sous forme de [[tiddlers|Tiddlers]], et à modéliser les relations entre eux<<:>>
* [[Liens dans un tiddler|TiddlerLinks]]
* [[Étiqueter par tag|Tagging]]
* [[Tiddler de listes|ListWidget]]
* [[Tiddlers de données|DataTiddlers]]
* <<fr TiddlerLinks>>
* <<fr Tagging>>
* <<fr "Title List">>
* <<fr DataTiddlers>>

View File

@@ -1,35 +1,41 @@
created: 20140904075400000
fr-title: Étiqueter par tag
modified: 20150624092812640
modified: 20220220002448916
tags: [[Working with TiddlyWiki]] Concepts
title: Tagging
type: text/vnd.tiddlywiki
Étiqueter un tiddler consiste à assigner par un tag à un tiddler une catégorie de votre choix (voir [[Créer et éditer des tiddlers|Creating and editing tiddlers]] pour des instructions sur la manière de taguer). Par exemple, les tiddlers représentant des individus pourraient être étiquetés par les tags ''ami'', ''famille'', ''collègue'', etc. pour indiquer leur relation avec l'auteur. Plusieurs tags peuvent être appliqués au même tiddler.
L'étiquetage des tiddlers permet de les organiser en catégories. Par exemple, les tiddlers représentant des individus pourraient être étiquetés avec les tags ''ami'', ''famille'', ''collègue'', etc. pour indiquer leur relation avec l'auteur.
Un tag est en fait un simple tiddler (ou un tiddler potentiel), qui peut lui-même avoir ses propres tags. Plusieurs tags peuvent être appliqués au même tiddler.
Voir <<fr "Creating and editing tiddlers">> pour des instructions sur la façon d'étiqueter les tiddlers.
Le fait d'étiqueter les tiddlers vous procure de nombreux moyens supplémentaires de visualiser, parcourir, et organiser vos informations<<:>>
* Les pastilles colorées pour chaque tag d'un tiddler vous donnent accès à tous les autres tiddlers de même tag, ainsi qu'au tiddler correspondant au tag lui-même.
* L'onglet //Étiqueté// dans le panneau d'informations du tiddler (accessible en cliquant sur le bouton {{$:/core/images/info-button}}) vous donne les liens vers tous les tiddlers tagués avec le titre du tiddler courant.
* Vous pouvez utiliser l'onglet Tags dans l'onglet Plus de la barre latérale pour visualiser tous vos tags et accéder à vos tiddlers étiquetés.
* Vous pouvez utiliser des [[filtres|Filters]] pour créer des listes de tiddlers selon leurs tags, puis afficher toute combinaison de champs souhaitée. Par exemple, vous pouvez créer une liste qui montre à la fois le titre et le texte de tous les tiddlers étiquetés //Glossaire//. Ces listes peuvent être formatées à votre goût<<:>> avec des puces, des nombres, ou séparées par des virgules, etc.
* Les tags <<gf système>> peuvent servir à personnaliser la mise en forme des tiddlers et de la page ~TiddlyWiki dans son ensemble. Voir les instructions correspondantes dans [[Personnalisation de la mise en forme de la page et des tiddlers|Page and tiddler layout customisation]].
* Les pastilles colorées pour chaque tag d'un tiddler vous donnent accès à tous les autres tiddlers portant le même tag, ainsi qu'au tiddler correspondant au tag lui-même.
* Lorsqu'un tiddler est utilisé pour étiqueter d'autres tiddlers, l'onglet ''Étiquetage'' dans son [[panneau d'informations|InfoPanel]] liste tous les tiddlers tagués avec le titre du tiddler courant.
* L'onglet ''Plus'' de la barre latérale contient un onglet ''Tags'' qui permet de visualiser tous vos tags et d'accéder à vos tiddlers étiquetés.
* Vous pouvez utiliser des [[filtres|Filters]] pour créer des listes de tiddlers selon leurs tags, puis afficher toute combinaison de [[champs|TiddlerFields]] souhaitée. Par exemple, vous pouvez créer un glossaire en listant le titre et le texte de tous les tiddlers étiquetés //Glossaire//. De telles listes peuvent être formatées à votre goût<<:>> avec des puces, des nombres, ou séparées par des virgules, etc.
* Les <<gf "tags système">> contrôlent la mise en forme des tiddlers et de la page <<tw>> dans son ensemble. Voir les instructions correspondantes dans <<fr "Page and tiddler layout customisation">>.
Encore deux choses que les tags permettent de faire<<:>>
! Affecter des couleurs et des icones à un tag
! Affecter des couleurs et des icônes à un tag
Vous pouvez utiliser le [[gestionnaire de tags|$:/TagManager]], présent dans l'onglet Tags de l'onglet Plus de la barre latérale, pour affecter une couleur de fond et/ou une icone à un tag.
Vous pouvez utiliser le <<.icon $:/core/images/tag-button>> [[gestionnaire de tags|$:/TagManager]], présent dans l'onglet ''Tags'' de l'onglet ''Plus'' de la barre latérale, pour affecter une couleur de fond et/ou une icône à un tag.
* Les couleurs peuvent être affectées à un tag soit en spécifiant la valeur CSS de la couleur dans la fenêtre supérieure dans la colonne des couleurs, soit en choisissant une couleur à partir du menu déroulant proposé.
* Les icones peuvent être affectées à un tag en cliquant sur le bouton {{$:/core/images/down-arrow}} dans la colonne des icones et en choisissant une des icones proposées.
* Les couleurs peuvent être affectées à un tag en cliquant sur le bouton de la colonne des couleurs et en sélectionnant une proposition. Sinon, spécifiez la valeur [[CSS]] de la couleur dans la zone de saisie accessible en cliquant sur le bouton <<.icon $:/core/images/info-button>>.
* Les icônes peuvent être affectées à un tag en cliquant sur le bouton <<.icon $:/core/images/down-arrow>> dans la colonne des icônes et en choisissant une des icônes proposées.
! Utiliser des champs `list` pour ajuster l'ordre des listes par tag
! Changer l'ordre dans lequel les tiddlers sont listés
Si vous voulez créer une liste de tiddlers à l'aide d'un [[filtre|Filters]] à partir d'un tag qu'ils ont en commun, en les triant selon un ordre particulier plutôt que selon l'ordre alphabétique par défaut, vous pouvez créer un champ appelé 'list' dans le tiddler du tag lui-même, et y ajouter les titres des tiddlers à ordonner dans l'ordre désiré. ~TiddlyWiki triera les listes de tiddlers tagués dans l'ordre de priorité suivant<<:>>
Par défaut, les tiddlers tagués sont listés dans l'ordre alphabétique.
* Premièrement, les tiddlers placés dans le [[champ list|ListField]] du tiddler de tag seront placés dans une nouvelle liste dans le même ordre
* Deuxièmement, tout tiddler sans place fixe mais disposant d'un champ ''list-before'' sera placé avant le tiddler indiqué dans le champ
** (si le champ ''list-before'' est vide, alors le tiddler sans place prédéfinie sera placé au début de la liste)
* Troisièmement, tout tiddler sans place prédéfinie disposant d'un champ ''list-after'' sera placé juste après le tiddler indiqué dans le champ
* Enfin, tout tiddler n'ayant toujours pas de place prédéfinie sera placé à la fin de la liste
Si vous voulez un ordre différent, ajoutez un champ `list` au tiddler du tag, et affectez lui comme valeur la [[liste de ses tiddlers|Title List]] dans l'ordre choisi.
Le champ `list` n'a pas besoin de contenir tous les tiddlers. <<tw>> utilise des [[règles précises|Order of Tagged Tiddlers]] pour trier les tiddlers tagués.

View File

@@ -1,11 +1,11 @@
created: 20130825202900000
fr-title: Liens dans un Tiddler
modified: 20150624092911695
modified: 20220219170847313
tags: Concepts
title: TiddlerLinks
type: text/vnd.tiddlywiki
Les liens sont des éléments d'un tiddler où cliquer engendre la navigation vers un tiddler différent. Le comportement d'une navigation est déterminé par le StoryView (la vue) en cours&lt;&lt;;&gt;&gt; par défaut, la vue classique de TiddlyWiki montre son déroulé comme une suite linéaire de tiddlers.
Les liens sont des éléments d'un tiddler où cliquer engendre la navigation vers un tiddler différent. Le comportement d'une navigation est déterminé par le StoryView (la vue) en cours<<:>> par défaut, la vue classique de TiddlyWiki montre son déroulé comme une suite linéaire de tiddlers.
Presser la touche ''control'' ou ''command'' en cliquant sur le lien d'un link ouvre le tiddler cible sans s'y déplacer. Cela peut-être un moyen pratique de dresser une suite de tiddlers à lire plus tard.
@@ -13,12 +13,12 @@ Les liens sont utiles pour modéliser des relations organiques entre tiddlers, e
Le [[panneau d'information|InfoPanel]] liste la provenance des liens vers un tiddler dans l'onglet ''References''.
Les [[filtres|Filters]] peuvent inclure les opérateur de filtrage suivant qui fonctionnent avec les liens&lt;&lt;:&gt;&gt;
Les [[filtres|Filters]] peuvent inclure les opérateur de filtrage suivant qui fonctionnent avec les liens<<:>>
* `[links[]]` - renvoie les titres des tiddlers dont les liens proviennent de la sélection des tiddler(s) en cours
* `[backlinks[]]` - renvoie les titres des tiddlers destination des liens des tiddler(s) en cours sélectionnés
TiddlyWiki5 modifie l'apparence des liens des tiddlers pour donner plus d'informations sur la cible du lien&lt;&lt;:&gt;&gt;
TiddlyWiki5 modifie l'apparence des liens des tiddlers pour donner plus d'informations sur la cible du lien<<:>>
|!Description lien |!Affichage lien |
|Vers tiddler existant |[[Ainsi|TiddlerLinks]] |
@@ -26,4 +26,4 @@ TiddlyWiki5 modifie l'apparence des liens des tiddlers pour donner plus d'inform
|Vers tiddler shadow non remplacé |[[Ainsi|$:/core/copyright.txt]] |
|Vers tiddler shadow remplacé par un tiddler ordinaire|[[Ainsi|$:/SiteTitle]] |
Les liens externes sont affichés comme ceci&lt;&lt;:&gt;&gt; https://tiddlywiki.com/ ou [[comme ça|https://tiddlywiki.com/]].
Les liens externes sont affichés comme ceci<<:>> https://tiddlywiki.com/ ou [[comme ça|https://tiddlywiki.com/]].

View File

@@ -0,0 +1,46 @@
created: 20171109170823847
fr-title: L'apocalypse de TiddlyFox
modified: 20220217174448054
tags: TiddlyFox
title: TiddlyFox Apocalypse
type: text/vnd.tiddlywiki
! Résumé
Le 14 novembre 2017 Mozilla [[a publié Firefox 57|https://blog.mozilla.org/blog/2017/09/26/firefox-quantum-beta-developer-edition/]], une nouvelle version majeure comprenant de nombreuses améliorations et correctifs de sécurité. Toutefois, ces améliorations comportaient ''des changements fondamentaux du modèle de sécurité qui ont eu comme effet indésirable d'empêcher ~TiddlyFox de fonctionner''.
TiddlyFox restera disponible pour les [[utilisateurs d'anciennes versions de Firefox|https://groups.google.com/d/topic/tiddlywiki/OJQ0yRq4zog/discussion]], mais ceux qui passeront à une version plus récente devront choisir une autre façon de gérer la sauvegarde des modifications avec TiddlyWiki.
Heureusement, il existe de nouvelles façons de travailler avec TiddlyWiki et les utilisateurs ont de nombreux choix alternatifs (voir les détails dans <<fr GettingStarted>>). La disparition de TiddlyFox a provoqué plusieurs de ces développements récents et pourrait finalement être bénéfique pour la communauté.
Ces développements font l'objet d'une [[discussion|https://groups.google.com/d/topic/tiddlywiki/LcldXzPlTK0/discussion]] sur les forums TiddlyWiki.
! Contexte
Firefox a été initialement publié en novembre 2004, quelques mois après la première version de TiddlyWiki. C'était très comparable au Faucon Millénium pour l'Étoile de la Mort de Microsoft (incarnée par Internet Explorer). IE écrasait depuis 5 ans le marché des navigateurs, provoquant la frustration de nombreux développeurs web face aux extensions au HTML de Microsoft qui étaient devenus des standards //de facto// au détriment d'une innovation qui aurait pu bénéficier à l'ensemble de la communauté web.
Firefox a vite eu du succès car il réussissait à afficher les pages web avec un rendu assez proche d'Internet Explorer tout en offrant une meilleure expérience utilisateur. Ses avantages résidaient en grande partie dans la possibilité offerte à l'utilisateur de modifier chaque aspect du navigateur. Deux innovations étaient à l'origine de cette capacité<<:>>
* L'intégralité de l'interface utilisateur du navigateur était écrite en [[XUL|https://en.wikipedia.org/wiki/XUL]], une extension au HTML qui lui permettait d'afficher des interface utilisateur conventionnelles (à l'époque, le HTML était limité à un simple rendu de documents structurés). Ajuster quelques lignes de code en XUL pouvait radicalement transformer l'interface du navigateur.
* L'architecture d'extensions de Mozilla donnait les pleins pouvoirs aux extensions, leur permettant d'observer et d'interagir profondément avec le moteur du navigateur lui-même, ainsi qu'avec le système de fichiers de l'ordinateur sur lequel il s'exécutait.
Ces deux conditions permirent l'épanouissement d'un large écosystème d'extensions autour de Firefox, pour certaines extrêmement populaires. Dans de nombreux cas, les innovations apportées par des extensions furent ensuite intégrées dans le navigateur, en particulier le débogueur [[Firebug|https://en.wikipedia.org/wiki/Firebug_(software)]] qui fut par la suite cloné par tous les éditeurs de navigateurs.
Firefox resta très populaire jusqu'à ce que Google rejoigne le développement du moteur rival ~WebKit pour développer Chome. Google choisit une approche très différente des compromis au cœur d'un navigateur, se concentrant sur l'amélioration de la sécurité au détriment de toute autre considération. Ils innovèrent avec l'isolation de chaque onglet dans un processus dédié, qui fut rapidement repris par les principaux navigateurs concurrents.
L'orientation de Google les empêcha d'adopter l'approche libertaire de Mozilla pour les extensions. Au lieu d'avoir accès à tout l'environnement du navigateur et au système, les extensions de Chrome ne voient qu'une petite partie de ce qui se passe dans le navigateur, et n'ont qu'un accès minimal aux ressources de l'hôte.
Le ralliement de Mozilla à l'approche de la [[sécurité des extensions de navigateurs|https://support.mozilla.org/en-US/kb/firefox-add-technology-modernizing]] de Google était inévitable. A ce point, Mozilla aurait été irresponsable de publier un navigateur construit sur un modèle de sécurité notoirement inférieur à celui du leader du marché.
! Leçons
Une partie de la fécondité de l'écosystème autour de TiddlyWiki provient de l'adoption des deux principes de Firefox cités précédemment<<:>>
* Construire l'interface utilisateur de l'application avec les mêmes primitives que son contenu
* Permettre aux extensions d'accéder et interagir librement avec la logique interne de l'application.
Ces deux caractéristiques confrontent TiddlyWiki aux mêmes défis de sécurité que Firefox en son temps. Un TiddlyWiki orienté principalement vers la sécurité serait contraint de réduire ces possibilités.
! Le futur
Dans le domaine des interfaces basées sur les navigateurs et des interactions utilisateur, l'innovation a maintenant quitté les extensions pour migrer vers une nouvelle génération d'environnements qui simplifient la créations de navigateurs sur-mesure basés sur des moteurs de rendu HTML libres sur étagère. Ainsi, TiddlyDesktop utilise [[nwjs|https://nwjs.io]], et [[Beaker Browser]] utilise une alternative nommée [[Electron|https://electron.atom.io/]].

View File

@@ -1,17 +1,20 @@
created: 20130825161100000
modified: 20160602060511458
modified: 20220217174534558
tags: Definitions
title: TiddlyFox
type: text/vnd.tiddlywiki
//~TiddlyFox// est une extension pour Firefox qui permet aux fichiers <<tw>> autonomes d'enregistrer leurs modifications directement sur le système de fichiers. //~TiddlyFox// fonctionne aussi bien sur les versions station de travail que mobile de [[Firefox]]. Voir [[Enregistrer avec TiddlyFox|Saving with TiddlyFox]] ou [[Enregistrer avec TiddlyFox pour Android|Saving with TiddlyFox on Android]] pour des instructions détaillées.
//~TiddlyFox// peut être téléchargé depuis le site //Mozilla Addons//<<dp>>
~TiddlyFox est maintenant obsolète car il n'est plus compatible avec les dernières versions de Firefox (voir <<fr "TiddlyFox Apocalypse">>). Il existe de nombreuses alternatives à ~TiddlyFox, mais aucune ne fonctionne exactement de la même façon. Voir <<fr GettingStarted>> pour plus d'informations.
//~TiddlyFox// peut être téléchargé depuis le site //Mozilla Addons//<<:>>
https://addons.mozilla.org/fr/firefox/addon/tiddlyfox/
<<<
Vous pouvez également installer la dernière version de développement de ~TiddlyFox directement depuis GitHub<<dp>>
Vous pouvez également installer la dernière version de développement de ~TiddlyFox directement depuis GitHub<<:>>
https://github.com/TiddlyWiki/TiddlyFox/raw/master/tiddlyfox.xpi
<<<

View File

@@ -1,12 +1,14 @@
caption: TiddlyWiki
created: 20130822170700000
modified: 20150622113210434
modified: 20220219162827424
tags: Concepts
title: TiddlyWiki
type: text/vnd.tiddlywiki
~TiddlyWiki est un outil riche et interactif, capable de manipuler des données structurées complexes. Il est assez éloigné des outils conventionnels comme les traitements de texte ou les feuilles de calcul.
<<tw>> est un outil riche et interactif, capable de manipuler des données complexes dont la structure n'est pas adaptée aux outils conventionnels comme les traitements de texte ou les feuilles de calcul.
~TiddlyWiki est conçu pour s'adapter à votre cerveau, en vous aidant à gérer ce qui s'adapte mal. L'[[idée fondamentale|Philosophy of Tiddlers]] est que les informations sont plus utiles et plus facilement réutilisables quand on les découpe en morceaux sémantiques aussi petits que possible -- [[les tiddlers|Tiddlers]] -- en leur donnant des titres à partir desquels le wiki pourra se [[structurer|Structuring TiddlyWiki]] à l'aide de [[liens|TiddlerLinks]], d'[[étiquettes|Tagging]], de [[listes|ListField]] et de [[macros|Macros]]. Les tiddlers utilisent une notation [[WikiTexte|WikiText]] qui permet de représenter de façon concise une grande panoplie de fonctions hypertexte et de formatage. Le but de ~TiddlyWiki est de fournir une interface de travail fluide, à même de faciliter l'agrégation des tiddlers et leur recomposition en textes plus long.
<<tw>> est conçu pour s'adapter à votre cerveau, en vous aidant à gérer ce qui s'adapte mal. L'[[idée fondamentale|Philosophy of Tiddlers]] est que les informations sont plus utiles et plus facilement réutilisables quand on les découpe en morceaux sémantiques aussi petits que possible -- [[les tiddlers|Tiddlers]] -- en leur donnant des titres à partir desquels le wiki pourra se [[structurer|Structuring TiddlyWiki]] à l'aide de [[liens|TiddlerLinks]], d'[[étiquettes|Tagging]], de [[listes|ListField]] et de [[macros|Macros]]. Les tiddlers utilisent une notation [[WikiTexte|WikiText]] qui permet de représenter de façon concise une grande panoplie de fonctions hypertexte et de formatage. Le but de <<tw>> est de fournir une interface de travail fluide, à même de faciliter l'agrégation des tiddlers et leur recomposition en textes plus long.
Les gens [[adorent utiliser|Raves]] ~TiddlyWiki. Parce qu'on peut l'utiliser en l'absence d'infrastructure de serveurs compliquée, et parce qu'il est [[open source|OpenSource]], il a apporté une liberté inédite à ceux qui veulent garder le contrôle de leurs précieuses informations. ~TiddlyWiki a été créé initialement par JeremyRuston et est maintenant devenu un projet //open source// qui s'épanouit grâce à une [[communauté|Community]] active de développeurs indépendants.
Les gens adorent utiliser <<tw>>. Comme on peut l'utiliser en l'absence d'infrastructure de serveurs compliquée, et qu'il est [[open source|OpenSource]], il a apporté une liberté inédite à ceux qui veulent garder le contrôle de leurs précieuses informations.
<<tw>> a été créé initialement par JeremyRuston et est maintenant devenu un projet //open source// qui s'épanouit grâce à une [[communauté|Community]] active de développeurs indépendants.

View File

@@ -1,6 +1,6 @@
caption: 5.2.2
created: 20211208115905247
modified: 20211208115905247
created: 20220208152620527
modified: 20220208152620527
tags: ReleaseNotes
title: Release 5.2.2
type: text/vnd.tiddlywiki
@@ -13,46 +13,122 @@ type: text/vnd.tiddlywiki
! Highlights
*
!! <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/6421">> support for line breaks within filtered transcluded attributes
! Bug Fixes
To improve readability, it is now possible to use newlines as whitespace within filtered transcluded attributes of HTML elements and widgets. For example:
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/60187dc59e6546d9ca8e6a35418f782a9627cda0">> importing/upgrading encrypted single file wikis
```
<span class={{{
[<currentTiddler>addsuffix[-primaryList]]
:except[<searchListState>get[text]]
:and[then[]else[tc-list-item-selected]]
}}}>
```
! Usability Improvements
!! <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/6383">> inconsistent ordering of tagged tiddlers
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/853a899c77766e47eade1dfa5822640ef9915637">> wrapping and wikification of field names in field viewer
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/0186c6490fbd1d8fd4de7c3fa99ccf4d129fbd80">> missing whitespace between description and MIME type in edit template dropdown for the ''type'' field
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/c7e8c87f85b54f60302ff8e396a7569d996e3f67">> incorrect usage of code view for certain system tiddlers
This was a long standing bug that manifested itself in several ways.
! Widget Improvements
The root cause was that the order in which tiddlers were enumerated depended upon the order in which they had been added to the store.
*
The effect was that lists based on enumerating tiddlers would show different results depending upon whether new tiddlers were added since the wiki was reloaded.
! Filter improvements
For example, adding a new tiddler with a given tag previously caused the new tiddler to appear at the bottom of the tag pill listing for that tag. Saving and reloading the wiki would reorder the list to put the new tiddler in the correct position.
*
The fix ensures that the enumeration order remains consistent.
! Hackability Improvements
!! <<.link-badge-updated "https://github.com/Jermolene/TiddlyWiki5/pull/6427">> [[Highlight Plugin]] to use highlight.js v11.4.0
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/commit/54cfda76ee353190f1cf0210b9071894fb1a5690">> support for ''code-body'' field set to ''yes'' to trigger display of a tiddler in the code view
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/commit/66ae1d6930796a9eb062fdb64a755adab8f39294">> classes to the ImageWidget to indicate whether it is loading, loaded or has encountered an error
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/6381">> sourceURL tags to $:/boot/boot.js and $:/boot/bootprefix.js, enabling them to be accessed in the browser debugger more easily
This is a major upgrade to the latest version of highlight.js. The new version has many improvements, including better support for Fortran.
! Developer Improvements
<<.warning """The new version of the [[Highlight Plugin]] requires a modern browser that fully supports JavaScript ES6 (released in 2015). The older version is still available as the ''highlight-legacy'' plugin for users who need to use an older browser.""">>
*
! Plugin Improvements
! Node.js Improvements
*
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/6428">> issue with ~LaTeX content within Markdown tiddlers
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/6457">> incorrect handling of dropdown classes in the menu bar plugin
! Translation improvements
* Polish
* Chinese
* French
! Usability Improvements
* <<.link-badge-improved "https://github.com/Jermolene/TiddlyWiki5/pull/6435">> wording of drag and drop banner (from "drop here" to "drop now")
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/853a899c77766e47eade1dfa5822640ef9915637">> wrapping and wikification of field names in field viewer
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/0186c6490fbd1d8fd4de7c3fa99ccf4d129fbd80">> missing whitespace between description and MIME type in edit template dropdown for the ''type'' field
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/c7e8c87f85b54f60302ff8e396a7569d996e3f67">> incorrect usage of code view for certain system tiddlers
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/6501">> sidebar plugin listing to be sorted by name rather than description
! Widget Improvements
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/commit/66ae1d6930796a9eb062fdb64a755adab8f39294">> classes to the ImageWidget to indicate whether it is loading, loaded or has encountered an error
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/6389">> RadioWidget not using default value if the field or index is missing
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/6426">> issue with ImportVariablesWidget when importing block mode widgets
* <<.link-badge-extended "https://github.com/Jermolene/TiddlyWiki5/pull/6480">> DraggableWidget to support an optional drag handle
! Filter improvements
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/6468">> support for case insensitive matching for the [[prefix Operator]] and [[suffix Operator]]
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/commit/1a0c831216c397c6fef8e5685e47857193411a1b">> [[sha256 Operator]]
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/6438">> crash when using deprecated regexp operands for filter operators
* <<.link-badge-extended "https://github.com/Jermolene/TiddlyWiki5/pull/5742">> [[lookup Operator]] to support indexes as well as fields
* <<.link-badge-extended "https://github.com/Jermolene/TiddlyWiki5/pull/6293">> [[search Operator]] with new 'some' flag
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/6478">> [[untagged Operator]] to consider non-existent tiddlers to be untagged
* <<.link-badge-extended "https://github.com/Jermolene/TiddlyWiki5/pull/6477">> [[insertbefore Operator]] to accept the position title as a parameter, instead of as a variable name in the suffix
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/pull/6483">> [[butlast Operator]] to be consistent with the [[rest Operator]]
! Hackability Improvements
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/6388">> support for directly specifying style properties on [[HTML elements|HTML in WikiText]] (for example, `<div style.color={{!!color}}>`)
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/commit/54cfda76ee353190f1cf0210b9071894fb1a5690">> support for ''code-body'' field set to ''yes'' to trigger display of a tiddler in the code view
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/6410">> support to [[WidgetMessage: tm-scroll]] for scrolling without animating
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/commit/1d16206188ebd5ca7481a7f565bf5fc4c08239fd">> support for [[WidgetMessage: tm-relink-tiddler]]
* <<.link-badge-extended "https://github.com/Jermolene/TiddlyWiki5/pull/6470">> [[WidgetMessage: tm-open-window]] to support 'top' and 'left' parameters
! Developer Improvements
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/6409">> support for ''renderEnd()'' method for storyviews
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/6381">> sourceURL tags to $:/boot/boot.js and $:/boot/bootprefix.js, enabling them to be accessed in the browser debugger more easily
! Node.js Improvements
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/5899">> several new web server options: [[admin|WebServer Parameter: admin]], [[required-plugins|WebServer Parameter: required-plugins]] and [[tls-passphrase|WebServer Parameter: tls-passphrase]]
! Performance Improvements
* <<.link-badge-added "https://github.com/Jermolene/TiddlyWiki5/pull/6327">> support for caching the [[listed Operator]]
! Bug Fixes
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/commit/60187dc59e6546d9ca8e6a35418f782a9627cda0">> importing/upgrading encrypted single file wikis
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/6376">> [[WidgetMessage: tm-edit-text-operation]] crash with ''wrap-lines'' operation if prefix or suffix is missing
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/6395">> processing of $:/tags/RawMarkupWikified/TopHead tiddlers
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/6398">> issue whereby renaming tags could result in duplicate tags
* <<.link-badge-fixed "https://github.com/Jermolene/TiddlyWiki5/issues/6440">> search results obscured on narrow screens
! Acknowledgements
[[@Jermolene|https://github.com/Jermolene]] would like to thank the contributors to this release who have generously given their time to help improve TiddlyWiki:
* <<contributor Jermolene>>
* <<contributor benwebber>>
* <<contributor BramChen>>
* <<contributor btheado>>
* <<contributor cdruan>>
* <<contributor davout1806>>
* <<contributor EvidentlyCube>>
* <<contributor flibbles>>
* <<contributor ibnishak>>
* <<contributor jc-ose>>
* <<contributor joshuafontany>>
* <<contributor linonetwo>>
* <<contributor Marxsal>>
* <<contributor nilslindemann>>
* <<contributor pmario>>
* <<contributor rryan>>
* <<contributor saqimtiaz>>
* <<contributor slaymaker1907>>
* <<contributor tw-FRed>>
* <<contributor twMat>>

View File

@@ -1,4 +1,5 @@
title: $:/editions/tw5.com/download-empty
code-body: yes
\define saveTiddlerFilter()
[[$:/core]] [[$:/isEncrypted]] [[$:/themes/tiddlywiki/snowwhite]] [[$:/themes/tiddlywiki/vanilla]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] [[$:/config/OfficialPluginLibrary]] +[sort[title]]

View File

@@ -57,8 +57,19 @@ Tests the filtering mechanism.
);
});
describe("With tiddlers in the store unsorted",function() {
testWithAndWithoutIndexers();
});
describe("With tiddlers in the store sorted ascending",function() {
testWithAndWithoutIndexers({sort: "ascending"});
});
describe("With tiddlers in the store sorted descending",function() {
testWithAndWithoutIndexers({sort: "descending"});
});
function testWithAndWithoutIndexers(options) {
describe("With no indexers", function() {
var wiki = setupWiki({enableIndexers: []});
var wiki = setupWiki(Object.assign({},options,{enableIndexers: []}));
it("should not create indexes when requested not to",function() {
expect(wiki.getIndexer("FieldIndexer")).toBe(null);
});
@@ -66,14 +77,16 @@ Tests the filtering mechanism.
});
describe("With all indexers", function() {
var wiki = setupWiki();
var wiki = setupWiki(options);
if(wiki.getIndexer("FieldIndexer")) {
wiki.getIndexer("FieldIndexer").setMaxIndexedValueLength(8); // Note that JoeBloggs is 9, and John is 5
}
runTests(wiki);
});
}
function setupWiki(wikiOptions) {
wikiOptions = wikiOptions || {};
// Create a wiki
var wiki = new $tw.Wiki(wikiOptions);
// Add a plugin containing some shadow tiddlers
@@ -104,13 +117,12 @@ Tests the filtering mechanism.
}
}
};
wiki.addTiddler({
var tiddlers = [{
title: "$:/ShadowPlugin",
text: JSON.stringify(shadowTiddlers),
"plugin-type": "plugin",
type: "application/json"});
// Add a few tiddlers
wiki.addTiddler({
type: "application/json"
},{
title: "TiddlerOne",
text: "The quick brown fox in $:/TiddlerTwo",
tags: ["one"],
@@ -119,8 +131,8 @@ Tests the filtering mechanism.
slug: "tiddler-one",
authors: "Joe Bloggs",
modifier: "JoeBloggs",
modified: "201304152222"});
wiki.addTiddler({
modified: "201304152222"
},{
title: "$:/TiddlerTwo",
text: "The rain in Spain\nfalls mainly on the plain and [[a fourth tiddler]]",
tags: ["two"],
@@ -129,44 +141,75 @@ Tests the filtering mechanism.
slug: "tiddler-two",
authors: "[[John Doe]]",
modifier: "John",
modified: "201304152211"});
wiki.addTiddler({
modified: "201304152211"
},{
title: "Tiddler Three",
text: "The speed of sound in light\n\nThere is no TiddlerZero but TiddlerSix",
tags: ["one","two"],
cost: "56",
value: "80",
modifier: "John",
modified: "201304162202"});
wiki.addTiddler({
modified: "201304162202"
},{
title: "a fourth tiddler",
text: "The quality of mercy is not drained by [[Tiddler Three]]",
tags: [],
cost: "82",
value: "72",
empty: "not",
modifier: "John"});
wiki.addTiddler({
modifier: "John"
},{
title: "one",
text: "This is the text of tiddler [[one]]",
list: "[[Tiddler Three]] [[TiddlerOne]]",
empty: "",
modifier: "John"});
wiki.addTiddler({
modifier: "John"
},{
title: "hasList",
text: "This is the text of tiddler [[hasList]]",
list: "[[Tiddler Three]] [[TiddlerOne]]",
modifier: "PMario"});
wiki.addTiddler({
modifier: "PMario"
},{
title: "has filter",
text: "This is the text of tiddler [[has filter]]",
filter: "[[Tiddler Three]] [[TiddlerOne]] [subfilter{hasList!!list}]",
modifier: "PMario"});
wiki.addTiddler({
modifier: "PMario"
},{
title: "filter regexp test",
text: "Those strings have been used to create the `regexp = /[+|\-|~]?([[](?:[^\]])*\]+)|([+|-|~|\S]\S*)/;`",
filter: "+aaa -bbb ~ccc aaaaaabbbbbbbbaa \"bb'b\" 'cc\"c' [[abc]] [[tiddler with spaces]] [is[test]] [is[te st]] a s df [enlist<hugo>] +[enlist:raw{test with spaces}] [enlist:raw{test with spaces}] [[a a]] [[ ] [ ]] [[ [hugo]] [subfilter{Story/Tower of Hanoi/A-C Sequence}]",
modifier: "PMario"});
modifier: "PMario"
}];
// Load the tiddlers in the required order
var fnCompare;
switch(wikiOptions.sort) {
case "ascending":
fnCompare = function(a,b) {
if(a.title < b.title) {
return -1;
} else if(a.title > b.title) {
return +1;
} else {
return 0;
}
};
break;
case "descending":
fnCompare = function(a,b) {
if(a.title < b.title) {
return +1;
} else if(a.title > b.title) {
return -1;
} else {
return 0;
}
};
break;
}
if(fnCompare) {
tiddlers.sort(fnCompare);
}
wiki.addTiddlers(tiddlers);
// Unpack plugin tiddlers
wiki.readPluginInfo();
wiki.registerPluginTiddlers("plugin");
@@ -197,7 +240,7 @@ Tests the filtering mechanism.
expect(wiki.filterTiddlers("[!modifier[JoeBloggs]then[Susi]]").join(",")).toBe("Susi,Susi,Susi,Susi,Susi,Susi,Susi,Susi");
expect(wiki.filterTiddlers("[modifier[DaveBloggs]then[Susi]]").join(",")).toBe("");
expect(wiki.filterTiddlers("[modifier[JoeBloggs]else[Susi]]").join(",")).toBe("TiddlerOne");
expect(wiki.filterTiddlers("[!modifier[JoeBloggs]else[Susi]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[!modifier[JoeBloggs]else[Susi]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three");
expect(wiki.filterTiddlers("[modifier[DaveBloggs]else[Susi]]").join(",")).toBe("Susi");
});
@@ -211,6 +254,8 @@ Tests the filtering mechanism.
it("should handle the lookup operator", function() {
expect(wiki.filterTiddlers("Six Seventh 8 +[lookup[Tiddler]]").join(",")).toBe("Missing inaction from TiddlerOne,,Tidd");
expect(wiki.filterTiddlers("Six Seventh 8 +[lookup:8[Tiddler]]").join(",")).toBe("Missing inaction from TiddlerOne,8,Tidd");
expect(wiki.filterTiddlers("Six Seventh 8 +[lookup:8[Tiddler],[text]]").join(",")).toBe("Missing inaction from TiddlerOne,8,Tidd");
expect(wiki.filterTiddlers("Six Seventh 8 +[lookup[Tiddler],[tags]]").join(",")).toBe(",one,one");
});
it("should retrieve shadow tiddlers", function() {
@@ -219,31 +264,31 @@ Tests the filtering mechanism.
it("should handle the title operator", function() {
expect(wiki.filterTiddlers("TiddlerOne [title[$:/TiddlerTwo]] [[Tiddler Three]]").join(",")).toBe("TiddlerOne,$:/TiddlerTwo,Tiddler Three");
expect(wiki.filterTiddlers("[!title[Tiddler Three]]").join(",")).toBe("$:/ShadowPlugin,TiddlerOne,$:/TiddlerTwo,a fourth tiddler,one,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[!title[Tiddler Three]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,TiddlerOne");
expect(wiki.filterTiddlers("TiddlerOne [title[$:/TiddlerTwo]] [[Tiddler Three]] [[A Missing Tiddler]]").join(",")).toBe("TiddlerOne,$:/TiddlerTwo,Tiddler Three,A Missing Tiddler");
});
it("should handle the field operator", function() {
expect(wiki.filterTiddlers("[modifier[JoeBloggs]]").join(",")).toBe("TiddlerOne");
expect(wiki.filterTiddlers("[!modifier[JoeBloggs]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[!is[system]!modifier[JoeBloggs]]").join(",")).toBe("Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[!modifier[JoeBloggs]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three");
expect(wiki.filterTiddlers("[!is[system]!modifier[JoeBloggs]]").join(",")).toBe("a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three");
expect(wiki.filterTiddlers("[field:modifier[JoeBloggs]]").join(",")).toBe("TiddlerOne");
expect(wiki.filterTiddlers("[!field:modifier[JoeBloggs]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[!is[system]!field:modifier[JoeBloggs]]").join(",")).toBe("Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[modifier[John]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one");
expect(wiki.filterTiddlers("[!modifier[John]]").join(",")).toBe("$:/ShadowPlugin,TiddlerOne,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[!is[system]!modifier[John]]").join(",")).toBe("TiddlerOne,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[field:modifier[John]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one");
expect(wiki.filterTiddlers("[!field:modifier[John]]").join(",")).toBe("$:/ShadowPlugin,TiddlerOne,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[!is[system]!field:modifier[John]]").join(",")).toBe("TiddlerOne,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[!field:modifier[JoeBloggs]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three");
expect(wiki.filterTiddlers("[!is[system]!field:modifier[JoeBloggs]]").join(",")).toBe("a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three");
expect(wiki.filterTiddlers("[modifier[John]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,one,Tiddler Three");
expect(wiki.filterTiddlers("[!modifier[John]]").join(",")).toBe("$:/ShadowPlugin,filter regexp test,has filter,hasList,TiddlerOne");
expect(wiki.filterTiddlers("[!is[system]!modifier[John]]").join(",")).toBe("filter regexp test,has filter,hasList,TiddlerOne");
expect(wiki.filterTiddlers("[field:modifier[John]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,one,Tiddler Three");
expect(wiki.filterTiddlers("[!field:modifier[John]]").join(",")).toBe("$:/ShadowPlugin,filter regexp test,has filter,hasList,TiddlerOne");
expect(wiki.filterTiddlers("[!is[system]!field:modifier[John]]").join(",")).toBe("filter regexp test,has filter,hasList,TiddlerOne");
});
it("should handle the regexp operator", function() {
expect(wiki.filterTiddlers("[regexp[id]]").join(",")).toBe("TiddlerOne,$:/TiddlerTwo,Tiddler Three,a fourth tiddler");
expect(wiki.filterTiddlers("[!regexp[id]]").join(",")).toBe("$:/ShadowPlugin,one,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[regexp[Tid]]").join(",")).toBe("TiddlerOne,$:/TiddlerTwo,Tiddler Three");
expect(wiki.filterTiddlers("[regexp[(?i)Tid]]").join(",")).toBe("TiddlerOne,$:/TiddlerTwo,Tiddler Three,a fourth tiddler");
expect(wiki.filterTiddlers("[!regexp[Tid(?i)]]").join(",")).toBe("$:/ShadowPlugin,one,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[regexp[id]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[!regexp[id]]").join(",")).toBe("$:/ShadowPlugin,filter regexp test,has filter,hasList,one");
expect(wiki.filterTiddlers("[regexp[Tid]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[regexp[(?i)Tid]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[!regexp[Tid(?i)]]").join(",")).toBe("$:/ShadowPlugin,filter regexp test,has filter,hasList,one");
});
// The following 2 tests should write a log -> WARNING: Filter modifier has a deprecated regexp operand XXXX
@@ -253,20 +298,55 @@ Tests the filtering mechanism.
expect(wiki.filterTiddlers("[modifier/JoeBloggs/]").join(",")).toBe("TiddlerOne");
expect(console.log).toHaveBeenCalledWith("WARNING: Filter", "modifier", "has a deprecated regexp operand", /JoeBloggs/);
console.log.calls.reset();
expect(wiki.filterTiddlers("[modifier/Jo/]").join(",")).toBe("TiddlerOne,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one");
expect(wiki.filterTiddlers("[modifier/Jo/]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,one,Tiddler Three,TiddlerOne");
expect(console.log).toHaveBeenCalledWith("WARNING: Filter", "modifier", "has a deprecated regexp operand", /Jo/);
});
it("should handle regular expression operands without crashing", function() {
spyOn(console, 'log');
// We don't really care about the results. Just don't get RSoD.
expect(() => wiki.filterTiddlers("[all/current/]")).not.toThrow();
expect(() => wiki.filterTiddlers("[prefix/anything/]")).not.toThrow();
expect(() => wiki.filterTiddlers("[title/anything/]")).not.toThrow();
expect(() => wiki.filterTiddlers("[/anything/]")).not.toThrow();
expect(() => wiki.filterTiddlers("[//]")).not.toThrow();
});
it("should handle the prefix operator", function() {
expect(wiki.filterTiddlers("[prefix[Tiddler]]").join(",")).toBe("TiddlerOne,Tiddler Three");
expect(wiki.filterTiddlers("[prefix[Tiddler]]").join(",")).toBe("Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[prefix:casesensitive[tiddler]]").join(",")).toBe("");
expect(wiki.filterTiddlers("[prefix:caseinsensitive[tiddler]]").join(",")).toBe("Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[prefix[nothing]]").join(",")).toBe("");
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]prefix[]]").join(",")).toBe("ABCDE,abcde");
});
it("should handle the suffix operator", function() {
expect(wiki.filterTiddlers("[suffix[One]]").join(",")).toBe("TiddlerOne");
expect(wiki.filterTiddlers("[suffix:casesensitive[one]]").join(",")).toBe("one");
expect(wiki.filterTiddlers("[suffix:caseinsensitive[one]]").join(",")).toBe("one,TiddlerOne");
expect(wiki.filterTiddlers("[suffix[nothing]]").join(",")).toBe("");
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]suffix[]]").join(",")).toBe("ABCDE,abcde");
});
it("should handle the removeprefix operator", function() {
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]removeprefix[ABC]]").join(",")).toBe("DE");
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]removeprefix:casesensitive[ABC]]").join(",")).toBe("DE");
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]removeprefix:caseinsensitive[abc]]").join(",")).toBe("DE,de");
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]removeprefix[]]").join(",")).toBe("ABCDE,abcde");
});
it("should handle the removesuffix operator", function() {
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]removesuffix[DE]]").join(",")).toBe("ABC");
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]removesuffix:casesensitive[DE]]").join(",")).toBe("ABC");
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]removesuffix:caseinsensitive[de]]").join(",")).toBe("ABC,abc")
expect(wiki.filterTiddlers("[enlist[ABCDE abcde]removesuffix[]]").join(",")).toBe("ABCDE,abcde");
});
it("should handle the sort and sortcs operators", function() {
expect(wiki.filterTiddlers("[sort[title]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[!sort[title]]").join(",")).toBe("TiddlerOne,Tiddler Three,one,hasList,has filter,filter regexp test,a fourth tiddler,$:/TiddlerTwo,$:/ShadowPlugin");
expect(wiki.filterTiddlers("[sort[modified]]").join(",")).toBe("$:/ShadowPlugin,a fourth tiddler,one,hasList,has filter,filter regexp test,$:/TiddlerTwo,TiddlerOne,Tiddler Three");
expect(wiki.filterTiddlers("[!sort[modified]]").join(",")).toBe("Tiddler Three,TiddlerOne,$:/TiddlerTwo,$:/ShadowPlugin,a fourth tiddler,one,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[sort[modified]]").join(",")).toBe("$:/ShadowPlugin,a fourth tiddler,filter regexp test,has filter,hasList,one,$:/TiddlerTwo,TiddlerOne,Tiddler Three");
expect(wiki.filterTiddlers("[!sort[modified]]").join(",")).toBe("Tiddler Three,TiddlerOne,$:/TiddlerTwo,$:/ShadowPlugin,a fourth tiddler,filter regexp test,has filter,hasList,one");
// Temporarily commenting out the following two lines because of platform differences for localeCompare between the browser and Node.js
// expect(wiki.filterTiddlers("[sortcs[title]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three,TiddlerOne,a fourth tiddler,one");
// expect(wiki.filterTiddlers("[!sortcs[title]]").join(",")).toBe("one,a fourth tiddler,TiddlerOne,Tiddler Three,$:/TiddlerTwo");
@@ -291,6 +371,7 @@ Tests the filtering mechanism.
expect(wiki.filterTiddlers("[sort[title]reverse[]]").join(",")).toBe("TiddlerOne,Tiddler Three,one,hasList,has filter,filter regexp test,a fourth tiddler,$:/TiddlerTwo,$:/ShadowPlugin");
expect(wiki.filterTiddlers("[sort[title]reverse[x]]").join(",")).toBe("TiddlerOne,Tiddler Three,one,hasList,has filter,filter regexp test,a fourth tiddler,$:/TiddlerTwo,$:/ShadowPlugin");
expect(wiki.filterTiddlers("[sort[title]butlast[]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three");
expect(wiki.filterTiddlers("[sort[title]butlast[0]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[sort[title]butlast[2]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one");
expect(wiki.filterTiddlers("[sort[title]butlast[11]]").join(",")).toBe("");
expect(wiki.filterTiddlers("[sort[title]butlast[x]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three");
@@ -316,10 +397,10 @@ Tests the filtering mechanism.
expect(wiki.filterTiddlers("[all[shadows]tag[two]]").join(",")).toBe("$:/TiddlerFive");
expect(wiki.filterTiddlers("[all[shadows+tiddlers]tag[two]]").join(",")).toBe("$:/TiddlerFive,$:/TiddlerTwo,Tiddler Three");
expect(wiki.filterTiddlers("[all[tiddlers+shadows]tag[two]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three,$:/TiddlerFive");
expect(wiki.filterTiddlers("[all[shadows+tiddlers]]").join(",")).toBe("$:/TiddlerFive,TiddlerSix,TiddlerSeventh,Tiddler8,$:/ShadowPlugin,TiddlerOne,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[all[tiddlers+shadows]]").join(",")).toBe("$:/ShadowPlugin,TiddlerOne,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test,$:/TiddlerFive,TiddlerSix,TiddlerSeventh,Tiddler8");
expect(wiki.filterTiddlers("[all[shadows+tiddlers]]").join(",")).toBe("$:/TiddlerFive,TiddlerSix,TiddlerSeventh,Tiddler8,$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[all[tiddlers+shadows]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three,TiddlerOne,$:/TiddlerFive,TiddlerSix,TiddlerSeventh,Tiddler8");
expect(wiki.filterTiddlers("[all[tiddlers]tag[two]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three");
expect(wiki.filterTiddlers("[all[orphans+tiddlers+tags]]").join(",")).toBe("$:/ShadowPlugin,TiddlerOne,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,hasList,has filter,filter regexp test,two,one");
expect(wiki.filterTiddlers("[all[orphans+tiddlers+tags]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,Tiddler Three,TiddlerOne,two,one");
});
it("should handle the tags operator", function() {
@@ -330,11 +411,11 @@ Tests the filtering mechanism.
it("should handle the match operator", function() {
expect(wiki.filterTiddlers("[match[TiddlerOne]]").join(",")).toBe("TiddlerOne");
expect(wiki.filterTiddlers("TiddlerOne TiddlerOne =[match[TiddlerOne]]").join(",")).toBe("TiddlerOne,TiddlerOne");
expect(wiki.filterTiddlers("[!match[TiddlerOne]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[!match[TiddlerOne]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three");
expect(wiki.filterTiddlers("[match:casesensitive[tiddlerone]]").join(",")).toBe("");
expect(wiki.filterTiddlers("[!match:casesensitive[tiddlerone]]").join(",")).toBe("$:/ShadowPlugin,TiddlerOne,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[!match:casesensitive[tiddlerone]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[match:caseinsensitive[tiddlerone]]").join(",")).toBe("TiddlerOne");
expect(wiki.filterTiddlers("[!match:caseinsensitive[tiddlerone]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[!match:caseinsensitive[tiddlerone]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three");
});
it("should handle the tagging operator", function() {
@@ -348,6 +429,9 @@ Tests the filtering mechanism.
it("should handle the untagged operator", function() {
expect(wiki.filterTiddlers("[untagged[]sort[title]]").join(",")).toBe("$:/ShadowPlugin,a fourth tiddler,filter regexp test,has filter,hasList,one");
expect(wiki.filterTiddlers("[!untagged[]sort[title]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three,TiddlerOne");
// Should consider non-existent tiddlers untagged.
expect(wiki.filterTiddlers("[enlist[a b c]untagged[]]").join(",")).toBe("a,b,c");
expect(wiki.filterTiddlers("[enlist[a b c]!untagged[]]").join(",")).toBe("");
});
it("should handle the links operator", function() {
@@ -383,6 +467,11 @@ Tests the filtering mechanism.
expect(wiki.filterTiddlers("[list[TiddlerSeventh]sort[title]]").join(",")).toBe("a fourth tiddler,MissingTiddler,Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[tag[one]list[TiddlerSeventh]sort[title]]").join(",")).toBe("a fourth tiddler,MissingTiddler,Tiddler Three,TiddlerOne");
});
it("should handle the listed operator", function() {
expect(wiki.filterTiddlers("TiddlerOne MissingTiddler +[listed[]]").join(",")).toBe('hasList,one');
expect(wiki.filterTiddlers("one two +[listed[tags]]").join(",")).toBe('TiddlerOne,$:/TiddlerTwo,Tiddler Three');
});
it("should handle the next operator", function() {
expect(wiki.filterTiddlers("[[Tiddler Three]next[TiddlerSeventh]]").join(",")).toBe("a fourth tiddler");
@@ -404,21 +493,54 @@ Tests the filtering mechanism.
expect(wiki.filterTiddlers("[search:modifier:regexp[(d|bl)o(ggs|e)]sort[title]]").join(",")).toBe("TiddlerOne");
expect(wiki.filterTiddlers("[search:-modifier,authors:[g]sort[title]]").join(",")).toBe("$:/ShadowPlugin,filter regexp test,Tiddler Three");
expect(wiki.filterTiddlers("[search:*:[g]sort[title]]").join(",")).toBe("$:/ShadowPlugin,filter regexp test,Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[search:text:anchored[the]]").join(",")).toBe("TiddlerOne,$:/TiddlerTwo,Tiddler Three,a fourth tiddler");
expect(wiki.filterTiddlers("[search:text:anchored[the]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,Tiddler Three,TiddlerOne");
});
it("should yield search results where 'default' search finds at least 1 token", function() {
expect(wiki.filterTiddlers("[search::some[one two]sort[title]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,one,Tiddler Three,TiddlerOne");
});
it("should yield search results where 'title' finds at least one token", function() {
expect(wiki.filterTiddlers("[search:title:some[tiddler]sort[title]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[search:title:some[tiddler one]sort[title]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,one,Tiddler Three,TiddlerOne");
});
it("should yield search results where 'tags' finds at least one token", function() {
expect(wiki.filterTiddlers("[search:tags:some[one]sort[title]]").join(",")).toBe("Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[search:tags:some[two]sort[title]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three");
expect(wiki.filterTiddlers("[search:tags:some[two one]sort[title]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three,TiddlerOne");
});
it("should yield search results where 'tags' finds at least one token / casesensitive", function() {
expect(wiki.filterTiddlers("[search:tags:some[ONE]sort[title]]").join(",")).toBe("Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[search:tags:some,casesensitive[two ONE]sort[title]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three");
});
it("should yield search results where 'tags' finds at least one token / anchored", function() {
expect(wiki.filterTiddlers("[search:tags:some,anchored[one]sort[title]]").join(",")).toBe("Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[search:tags:some,anchored[two]sort[title]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three");
// search:title
expect(wiki.filterTiddlers("[search:title:some,anchored[tiddler]sort[title]]").join(",")).toBe("Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[search:title:some,anchored[tiddler one]sort[title]]").join(",")).toBe("one,Tiddler Three,TiddlerOne");
});
it("should yield search results where 'tags' finds at least one token / anchored & casesensitive", function() {
expect(wiki.filterTiddlers("[search:title:some,anchored,casesensitive[Tiddler one]sort[title]]").join(",")).toBe("one,Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[search:title:some,anchored,casesensitive[Tiddler ONE]sort[title]]").join(",")).toBe("Tiddler Three,TiddlerOne");
});
it("should yield search results that have search tokens spread across different fields", function() {
expect(wiki.filterTiddlers("[search[fox one]sort[title]]").join(",")).toBe("TiddlerOne");
});
it("should handle the each operator", function() {
expect(wiki.filterTiddlers("[each[modifier]sort[title]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,hasList,TiddlerOne");
expect(wiki.filterTiddlers("[each[modifier]sort[title]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,filter regexp test,TiddlerOne");
expect(wiki.filterTiddlers("[each:list-item[tags]sort[title]]").join(",")).toBe("one,two");
expect(wiki.filterTiddlers("[each:list-item[authors]sort[title]]").join(",")).toBe("Bloggs,Joe,John Doe");
});
it("should handle the eachday operator", function() {
expect(wiki.filterTiddlers("[eachday[modified]sort[title]]").join(",")).toBe("Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[eachday[modified]sort[title]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three");
});
it("should handle the sameday operator", function() {
@@ -446,7 +568,7 @@ Tests the filtering mechanism.
});
it("should handle the '[is[missing]]' operator", function() {
expect(wiki.filterTiddlers("[all[]]").join(",")).toBe("$:/ShadowPlugin,TiddlerOne,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[all[]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[all[missing]]").join(",")).toBe("TiddlerZero");
expect(wiki.filterTiddlers("[!is[missing]sort[title]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[[TiddlerOne]is[missing]]").join(",")).toBe("");
@@ -457,11 +579,39 @@ Tests the filtering mechanism.
it("should handle the '[is[orphan]]' operator", function() {
expect(wiki.filterTiddlers("[is[orphan]sort[title]]").join(",")).toBe("a fourth tiddler,filter regexp test,TiddlerOne");
expect(wiki.filterTiddlers("[!is[orphan]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,one,hasList,has filter");
expect(wiki.filterTiddlers("[!is[orphan]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,has filter,hasList,one,Tiddler Three");
expect(wiki.filterTiddlers("[[TiddlerOne]is[orphan]]").join(",")).toBe("TiddlerOne");
expect(wiki.filterTiddlers("[[TiddlerOne]!is[orphan]]").join(",")).toBe("");
expect(wiki.filterTiddlers("[!title[Tiddler Three]is[orphan]sort[title]]").join(",")).toBe("a fourth tiddler,filter regexp test,TiddlerOne");
expect(wiki.filterTiddlers("[!title[Tiddler Three]!is[orphan]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,one,hasList,has filter");
expect(wiki.filterTiddlers("[!title[Tiddler Three]!is[orphan]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,has filter,hasList,one");
});
it("should handle the '[is[draft]]' operator", function() {
var wiki = new $tw.Wiki();
wiki.addTiddlers([
{title: "A"},
{title: "Draft of 'A'", "draft.of": "A", "draft.title": "A"},
{title: "B"},
{title: "Draft of 'B'", "draft.of": "B"},
{title: "C"},
// Not a true draft. Doesn't have draft.of
{title: "Draft of 'C'", "draft.title": "C"},
{title: "E"},
// Broken. Has draft.of, but it's empty. Still a draft
{title: "Draft of 'E'", "draft.of": "", "draft.title": ""}
// Not a draft. It doesn't exist.
//{title: "F"} // This one is deliberately missing
]);
// is analagous to [has[draft.of]],
// except they handle empty draft.of differently
expect(wiki.filterTiddlers("[all[]] F +[is[draft]]").join(",")).toEqual("Draft of 'A',Draft of 'B',Draft of 'E'");
expect(wiki.filterTiddlers("[all[]] F +[!is[draft]]").join(",")).toEqual("A,B,C,Draft of 'C',E,F");
// [is[draft]] and [!is[draft]] are proper complements
var included = wiki.filterTiddlers("[all[]] F +[is[draft]]")
var excluded = wiki.filterTiddlers("[all[]] F +[!is[draft]]")
var all = [].concat(included, excluded).sort();
// combined, they should have exactly one of everything.
expect(wiki.filterTiddlers("[all[]] F +[sort[]]")).toEqual(all);
});
});
@@ -606,16 +756,27 @@ Tests the filtering mechanism.
rootWidget.setVariable("tidTitle","e");
rootWidget.setVariable("tidList","one tid with spaces");
// Position title specified as suffix.
expect(wiki.filterTiddlers("a b c d e f +[insertbefore:myVar[f]]",anchorWidget).join(",")).toBe("a,b,f,c,d,e");
expect(wiki.filterTiddlers("a b c d e f +[insertbefore:myVar<tidTitle>]",anchorWidget).join(",")).toBe("a,b,e,c,d,f");
expect(wiki.filterTiddlers("a b c d e f +[insertbefore:myVar[gg gg]]",anchorWidget).join(",")).toBe("a,b,gg gg,c,d,e,f");
expect(wiki.filterTiddlers("a b c d e +[insertbefore:myVar<tidList>]",anchorWidget).join(",")).toBe("a,b,one tid with spaces,c,d,e");
expect(wiki.filterTiddlers("a b c d e f +[insertbefore:tidTitle{TiddlerOne!!tags}]",anchorWidget).join(",")).toBe("a,b,c,d,one,e,f");
// Position title specified as parameter.
expect(wiki.filterTiddlers("a b c d e +[insertbefore[f],[a]]",anchorWidget).join(",")).toBe("f,a,b,c,d,e");
expect(wiki.filterTiddlers("a b c d e +[insertbefore[f],<myVar>]",anchorWidget).join(",")).toBe("a,b,f,c,d,e");
// Parameter takes precedence over suffix.
expect(wiki.filterTiddlers("a b c d e +[insertbefore:myVar[f],[a]]",anchorWidget).join(",")).toBe("f,a,b,c,d,e");
// Next 2 tests do weired things, but will pass - there for compatibility reasons
// No position title.
expect(wiki.filterTiddlers("a b c [[with space]] +[insertbefore[b]]").join(",")).toBe("a,c,with space,b");
expect(wiki.filterTiddlers("a b c d e +[insertbefore:2[b]]").join(",")).toBe("a,c,d,e,b");
// Position title does not exist.
expect(wiki.filterTiddlers("a b c d e +[insertbefore:foo[b]]").join(",")).toBe("a,c,d,e,b");
expect(wiki.filterTiddlers("a b c d e +[insertbefore[b],[foo]]").join(",")).toBe("a,c,d,e,b");
expect(wiki.filterTiddlers("a b c d e +[insertbefore[b],<foo>]").join(",")).toBe("a,c,d,e,b");
});
it("should handle the move operator", function() {
@@ -775,10 +936,10 @@ Tests the filtering mechanism.
rootWidget.setVariable("sort2","[get[text]else[]length[]]");
rootWidget.setVariable("sort3","[{!!value}divide{!!cost}]");
rootWidget.setVariable("sort4","[{!!title}]");
expect(wiki.filterTiddlers("[sortsub:number<sort1>]",anchorWidget).join(",")).toBe("one,hasList,TiddlerOne,has filter,$:/TiddlerTwo,Tiddler Three,$:/ShadowPlugin,a fourth tiddler,filter regexp test");
expect(wiki.filterTiddlers("[!sortsub:number<sort1>]",anchorWidget).join(",")).toBe("filter regexp test,a fourth tiddler,$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,TiddlerOne,has filter,hasList,one");
expect(wiki.filterTiddlers("[sortsub:string<sort1>]",anchorWidget).join(",")).toBe("TiddlerOne,has filter,$:/TiddlerTwo,Tiddler Three,$:/ShadowPlugin,a fourth tiddler,filter regexp test,one,hasList");
expect(wiki.filterTiddlers("[!sortsub:string<sort1>]",anchorWidget).join(",")).toBe("hasList,one,filter regexp test,a fourth tiddler,$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,TiddlerOne,has filter");
expect(wiki.filterTiddlers("[sortsub:number<sort1>]",anchorWidget).join(",")).toBe("one,hasList,has filter,TiddlerOne,$:/TiddlerTwo,Tiddler Three,$:/ShadowPlugin,a fourth tiddler,filter regexp test");
expect(wiki.filterTiddlers("[!sortsub:number<sort1>]",anchorWidget).join(",")).toBe("filter regexp test,a fourth tiddler,$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,has filter,TiddlerOne,hasList,one");
expect(wiki.filterTiddlers("[sortsub:string<sort1>]",anchorWidget).join(",")).toBe("has filter,TiddlerOne,$:/TiddlerTwo,Tiddler Three,$:/ShadowPlugin,a fourth tiddler,filter regexp test,one,hasList");
expect(wiki.filterTiddlers("[!sortsub:string<sort1>]",anchorWidget).join(",")).toBe("hasList,one,filter regexp test,a fourth tiddler,$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,has filter,TiddlerOne");
expect(wiki.filterTiddlers("[sortsub:number<sort2>]",anchorWidget).join(",")).toBe("one,TiddlerOne,hasList,has filter,a fourth tiddler,Tiddler Three,$:/TiddlerTwo,filter regexp test,$:/ShadowPlugin");
expect(wiki.filterTiddlers("[!sortsub:number<sort2>]",anchorWidget).join(",")).toBe("$:/ShadowPlugin,filter regexp test,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,has filter,hasList,TiddlerOne,one");
expect(wiki.filterTiddlers("[sortsub:string<sort2>]",anchorWidget).join(",")).toBe("one,TiddlerOne,hasList,has filter,$:/ShadowPlugin,a fourth tiddler,Tiddler Three,$:/TiddlerTwo,filter regexp test");
@@ -899,4 +1060,4 @@ Tests the filtering mechanism.
});
})();

View File

@@ -128,6 +128,21 @@ describe("HTML tag new parser tests", function() {
expect($tw.utils.parseAttribute("p=\"blah\" ",0)).toEqual(
{ type : 'string', start : 0, name : 'p', value : 'blah', end : 8 }
);
expect($tw.utils.parseAttribute("p=\"bl\nah\" ",0)).toEqual(
{ type : 'string', start : 0, name : 'p', value : 'bl\nah', end : 9 }
);
expect($tw.utils.parseAttribute("p={{{blah}}} ",0)).toEqual(
{ type : 'filtered', start : 0, name : 'p', filter : 'blah', end : 12 }
);
expect($tw.utils.parseAttribute("p={{{bl\nah}}} ",0)).toEqual(
{ type : 'filtered', start : 0, name : 'p', filter : 'bl\nah', end : 13 }
);
expect($tw.utils.parseAttribute("p={{{ [{$:/layout}] }}} ",0)).toEqual(
{ type : 'filtered', start : 0, name : 'p', filter : ' [{$:/layout}] ', end : 23 }
);
expect($tw.utils.parseAttribute("p={{blah}} ",0)).toEqual(
{ type : 'indirect', start : 0, name : 'p', textReference : 'blah', end : 10 }
);
expect($tw.utils.parseAttribute("p=blah ",0)).toEqual(
{ type : 'string', start : 0, name : 'p', value : 'blah', end : 6 }
);

View File

@@ -392,10 +392,10 @@ describe("'reduce' and 'intersection' filter prefix tests", function() {
rootWidget.setVariable("larger-than-18","[get[text]length[]compare:integer:gteq[18]]");
rootWidget.setVariable("nr","18");
rootWidget.setVariable("larger-than-18-with-var","[get[text]length[]compare:integer:gteq<nr>]");
expect(wiki.filterTiddlers("[tag[textexample]] :filter[get[text]length[]compare:integer:gteq[18]]",anchorWidget).join(",")).toBe("Red wine,Cheesecake,Chocolate Cake");
expect(wiki.filterTiddlers("[tag[textexample]]",anchorWidget).join(",")).toBe("Sparkling water,Red wine,Cheesecake,Chocolate Cake");
expect(wiki.filterTiddlers("[tag[textexample]filter<larger-than-18>]",anchorWidget).join(",")).toBe("Red wine,Cheesecake,Chocolate Cake");
expect(wiki.filterTiddlers("[tag[textexample]filter<larger-than-18-with-var>]",anchorWidget).join(",")).toBe("Red wine,Cheesecake,Chocolate Cake");
expect(wiki.filterTiddlers("[tag[textexample]] :filter[get[text]length[]compare:integer:gteq[18]]",anchorWidget).join(",")).toBe("Cheesecake,Chocolate Cake,Red wine");
expect(wiki.filterTiddlers("[tag[textexample]]",anchorWidget).join(",")).toBe("Cheesecake,Chocolate Cake,Red wine,Sparkling water");
expect(wiki.filterTiddlers("[tag[textexample]filter<larger-than-18>]",anchorWidget).join(",")).toBe("Cheesecake,Chocolate Cake,Red wine");
expect(wiki.filterTiddlers("[tag[textexample]filter<larger-than-18-with-var>]",anchorWidget).join(",")).toBe("Cheesecake,Chocolate Cake,Red wine");
});
it("should handle the :sort prefix", function() {
@@ -405,7 +405,7 @@ describe("'reduce' and 'intersection' filter prefix tests", function() {
expect(wiki.filterTiddlers("[tag[textexample]] :sort:number:[get[text]length[]]").join(",")).toBe("Sparkling water,Chocolate Cake,Red wine,Cheesecake");
expect(wiki.filterTiddlers("[tag[textexample]] :sort:number:reverse[get[text]length[]]").join(",")).toBe("Cheesecake,Red wine,Chocolate Cake,Sparkling water");
expect(wiki.filterTiddlers("[tag[notatag]] :sort:number[get[price]]").join(",")).toBe("");
expect(wiki.filterTiddlers("[tag[cakes]] :sort:string[{!!title}]").join(",")).toBe("Cheesecake,cheesecake,Chocolate Cake,chocolate cake,Persian love cake,Pound cake");
expect(wiki.filterTiddlers("[tag[cakes]] :sort:string[{!!title}]").join(",")).toBe("cheesecake,Cheesecake,chocolate cake,Chocolate Cake,Persian love cake,Pound cake");
expect(wiki.filterTiddlers("[tag[cakes]] :sort:string:casesensitive[{!!title}]").join(",")).toBe("Cheesecake,Chocolate Cake,Persian love cake,Pound cake,cheesecake,chocolate cake");
expect(wiki.filterTiddlers("[tag[cakes]] :sort:string:casesensitive,reverse[{!!title}]").join(",")).toBe("chocolate cake,cheesecake,Pound cake,Persian love cake,Chocolate Cake,Cheesecake");
});

View File

@@ -102,6 +102,25 @@ function runTests(wiki,wikiOptions) {
expect(wiki.filterTiddlers("[tag[TiddlerSeventh]]").join(",")).toBe("Tiddler10,TiddlerOne,Tiddler Three,Tiddler11,Tiddler9,a fourth tiddler");
});
it("should apply identical tag ordering irrespective of tag creation order", function () {
var wiki;
wiki = new $tw.Wiki(wikiOptions);
wiki.addTiddler({ title: "A", text: "", tags: "sortTag"});
wiki.addTiddler({ title: "B", text: "", tags: "sortTag"});
wiki.addTiddler({ title: "C", text: "", tags: "sortTag"});
expect(wiki.filterTiddlers("[tag[sortTag]]").join(',')).toBe("A,B,C");
wiki = new $tw.Wiki(wikiOptions);
wiki.addTiddler({ title: "A", text: "", tags: "sortTag"});
wiki.addTiddler({ title: "C", text: "", tags: "sortTag"});
wiki.addTiddler({ title: "B", text: "", tags: "sortTag"});
expect(wiki.filterTiddlers("[tag[sortTag]]").join(',')).toBe("A,B,C");
wiki = new $tw.Wiki(wikiOptions);
wiki.addTiddler({ title: "C", text: "", tags: "sortTag"});
wiki.addTiddler({ title: "B", text: "", tags: "sortTag"});
wiki.addTiddler({ title: "A", text: "", tags: "sortTag"});
expect(wiki.filterTiddlers("[tag[sortTag]]").join(',')).toBe("A,B,C");
});
// Tests for issue (#3296)
it("should apply tag ordering in order of dependency", function () {
var wiki = new $tw.Wiki(wikiOptions);

View File

@@ -169,6 +169,16 @@ describe("Utility tests", function() {
expect(cv("1.1.1","1.1.2")).toEqual(-1);
});
it("should insert strings into sorted arrays", function() {
expect($tw.utils.insertSortedArray([],"a").join(",")).toEqual("a");
expect($tw.utils.insertSortedArray(["b","c","d"],"a").join(",")).toEqual("a,b,c,d");
expect($tw.utils.insertSortedArray(["b","c","d"],"d").join(",")).toEqual("b,c,d");
expect($tw.utils.insertSortedArray(["b","c","d"],"f").join(",")).toEqual("b,c,d,f");
expect($tw.utils.insertSortedArray(["b","c","d","e"],"f").join(",")).toEqual("b,c,d,e,f");
expect($tw.utils.insertSortedArray(["b","c","g"],"f").join(",")).toEqual("b,c,f,g");
expect($tw.utils.insertSortedArray(["b","c","d"],"ccc").join(",")).toEqual("b,c,ccc,d");
});
});
})();

View File

@@ -119,7 +119,7 @@ describe("WikiText parser tests", function() {
);
});
it("should parse comment in pragma area. Comment will be INVISIBLE", function() {
it("should parse comment in pragma area. Comment will be invisible", function() {
expect(parse("<!-- comment in pragma area -->\n\\define aMacro()\nnothing\n\\end\n")).toEqual(
[ { type : 'set', attributes : { name : { type : 'string', value : 'aMacro' }, value : { type : 'string', value : 'nothing' } }, children : [ ], params : [ ], isMacroDefinition : true } ]
@@ -127,6 +127,19 @@ describe("WikiText parser tests", function() {
);
});
it("should block mode filtered transclusions", function() {
expect(parse("{{{ filter }}}")).toEqual(
[ { type: 'list', attributes: { filter: { type: 'string', value: ' filter ' } }, isBlock: true } ]
);
expect(parse("{{{ fil\nter }}}")).toEqual(
[ { type: 'list', attributes: { filter: { type: 'string', value: ' fil\nter ' } }, isBlock: true } ]
);
});
it("should parse inline macro calls", function() {
expect(parse("<<john>><<paul>><<george>><<ringo>>")).toEqual(

View File

@@ -1,10 +1,10 @@
created: 20150630205511173
modified: 20150630205632460
modified: 20220226175543038
tags:
title: Contributor License Agreement
type: text/vnd.tiddlywiki
Like other OpenSource projects, TiddlyWiki5 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 UnaMesa Association (the legal entity that owns TiddlyWiki on behalf of the community).
* For individuals use: [[licenses/CLA-individual|https://github.com/Jermolene/TiddlyWiki5/tree/master/licenses/cla-individual.md]]
* For entities use: [[licenses/CLA-entity|https://github.com/Jermolene/TiddlyWiki5/tree/master/licenses/cla-entity.md]]
* For individuals use: [[licenses/CLA-individual|https://github.com/Jermolene/TiddlyWiki5/tree/tiddlywiki-com/licenses/cla-individual.md]]
* For entities use: [[licenses/CLA-entity|https://github.com/Jermolene/TiddlyWiki5/tree/tiddlywiki-com/licenses/cla-entity.md]]

View File

@@ -1,28 +1,31 @@
created: 20140721121924384
modified: 20201222114755959
modified: 20220131165124489
tags: Community
title: Forums
type: text/vnd.tiddlywiki
! Users
! Official Forums
The ~TiddlyWiki discussion groups are mailing lists for talking about ~TiddlyWiki: requests for help, announcements of new releases and plugins, debating new features, or just sharing experiences. You can participate via the associated website, or subscribe via email.
The new official forum for talking about ~TiddlyWiki: requests for help, announcements of new releases and plugins, debating new features, or just sharing experiences. You can participate via the associated website, or subscribe via email.
* The main ~TiddlyWiki group: https://groups.google.com/group/TiddlyWiki
*> Note that you do not need a Google Account to join the discussion groups. Subscribe by sending an email to mailto:tiddlywiki+subscribe@googlegroups.com.
** An enhanced group search facility is available on [[mail-archive.com|https://www.mail-archive.com/tiddlywiki@googlegroups.com/]]
* Watch recordings of our regular [[TiddlyWiki Hangouts]]
* Follow [[@TiddlyWiki on Twitter|http://twitter.com/TiddlyWiki]] for the latest news
* New: Join us on our live chat at https://gitter.im/TiddlyWiki/public !
* There is also a discord available at https://discord.gg/HFFZVQ8
https://talk.tiddlywiki.org/
Note that talk.tiddlywiki.org is a community run service that we host and maintain ourselves. The modest running costs are covered by community contributions.
! Developers
For the convenience of existing users, we also continue to operate the original ~TiddlyWiki group (hosted on Google Groups since 2005):
https://groups.google.com/group/TiddlyWiki
! Developer Forums
{{Developers}}
New releases of TiddlyWiki, TiddlyDesktop and TiddlyFox are announced via the discussion groups and [[Twitter|https://twitter.com/TiddlyWiki]] (you can also subscribe to an Atom/RSS feed of [[TiddlyWiki releases from GitHub|https://github.com/jermolene/tiddlywiki5/releases.atom]])
! Other Forums
! Documentation
* [[TiddlyWiki Subreddit|https://www.reddit.com/r/TiddlyWiki5/]]
* Chat with Gitter at https://gitter.im/TiddlyWiki/public !
* Chat on Discord at https://discord.gg/HFFZVQ8
!! Documentation
There is also a discussion group specifically for discussing TiddlyWiki documentation improvement initiatives: https://groups.google.com/group/tiddlywikidocs

View File

@@ -1,5 +1,5 @@
created: 20150630205653005
modified: 20190115165616599
modified: 20220226175503241
tags:
title: Signing the Contributor License Agreement
type: text/vnd.tiddlywiki
@@ -8,7 +8,7 @@ Create a GitHub pull request to add your name to `cla-individual.md` or `cla-ent
''step by step''
# Navigate to [[licenses/CLA-individual|https://github.com/Jermolene/TiddlyWiki5/tree/master/licenses/cla-individual.md]] or [[licenses/CLA-entity|https://github.com/Jermolene/TiddlyWiki5/tree/master/licenses/cla-entity.md]] according to whether you are signing as an individual or representative of an organisation
# Navigate to [[licenses/CLA-individual|https://github.com/Jermolene/TiddlyWiki5/tree/tiddlywiki-com/licenses/cla-individual.md]] or [[licenses/CLA-entity|https://github.com/Jermolene/TiddlyWiki5/tree/tiddlywiki-com/licenses/cla-entity.md]] according to whether you are signing as an individual or representative of an organisation
# Ensure that the "branch" dropdown at the top left is set to `tiddlywiki-com`
# Click the "edit" button at the top-right corner (clicking this button will fork the project so you can edit the file)
# Add your name at the bottom

View File

@@ -1,5 +1,5 @@
created: 20140211171341271
modified: 20200103092706002
modified: 20220128112317724
tags: Concepts Reference
title: Macros
type: text/vnd.tiddlywiki
@@ -14,8 +14,6 @@ They are created using the `\define` [[pragma|Pragma]]. (Behind the scenes, this
The snippet and its incoming parameter values are treated as simple strings of characters with no WikiText meaning, at least until the placeholders have been filled in and the macro call has returned. This means that a macro can assemble and return the complete syntax of a ~WikiText component, such as a [[link|Linking in WikiText]]. (See [[Transclusion and Substitution]] for further discussion of this.)
The string returned by a macro call is parsed separately from any surrounding ~WikiText components. So a safe way to insert a special character sequence (such as `[[` or `<`) without triggering its normal ~WikiText meaning is to wrap it in a macro.
Within a snippet itself, the only markup detected is `$name$` (a placeholder for a macro parameter) and `$(name)$` (a placeholder for a [[variable|Variables]]).
The <<.mlink dumpvariables>> macro lists all variables (including macros) that are available at that position in the widget tree.

View File

@@ -1,6 +1,6 @@
created: 20150219175930000
modified: 20180928145730028
tags: Concepts
modified: 20220122182842041
tags: Concepts [[WikiText Parser Modes]]
title: Pragma
type: text/vnd.tiddlywiki

View File

@@ -1,5 +1,6 @@
title: $:/_tw5.com/CustomStoryTiddlerTemplateDemo/Styles
tags: $:/tags/Stylesheet
code-body: yes
.tc-custom-tiddler-template {
border: 3px solid <<colour muted-foreground>>;

View File

@@ -1,4 +1,5 @@
title: $:/_tw5.com/CustomStoryTiddlerTemplateDemo/Template
code-body: yes
\define list-item-styles()
transform: translate($(left)$%,$(top)$%) scale(0.3) rotate($(angle)$deg);

View File

@@ -1,5 +1,6 @@
title: $:/_tw5.com/CustomStoryTiddlerTemplateDemo/Filter
tags: $:/tags/StoryTiddlerTemplateFilter
list-before: $:/config/StoryTiddlerTemplateFilters/default
code-body: yes
[tag[$:/tags/TiddlerList]then[$:/_tw5.com/CustomStoryTiddlerTemplateDemo/Template]]

View File

@@ -22,5 +22,5 @@ Most files are imported as individual tiddlers. The exceptions are:
!! Importing content from other ~TiddlyWiki browser windows
Tiddlers can be imported from other ~TiddlyWiki browser windows via [[Drag and Drop]]. Drag a tiddler link or tag from one ~TiddlyWiki browser window to another. Dragging a link will import a single tiddler while dragging a tag pill will import all of the tiddlers that carry that tag.
Tiddlers can be imported from other ~TiddlyWiki browser windows via [[Drag and Drop]]. Drag a TiddlyWiki internal link or a tag from one ~TiddlyWiki browser window to another. Dragging an internal link will import a single tiddler while dragging a tag pill will import all of the tiddlers that carry that tag.

View File

@@ -1,5 +1,5 @@
created: 20140410103123179
modified: 20150203191930000
modified: 20220226043344258
tags: [[Filter Operators]] [[Order Operators]]
title: butlast Operator
type: text/vnd.tiddlywiki
@@ -10,4 +10,6 @@ op-parameter: an integer, defaulting to 1
op-parameter-name: N
op-output: all but the last <<.place N>> input titles
<<.from-version "5.2.2">> The <<.op butlast>> operator returns the input list unchanged if <<.place N>> is 0. This is consistent with the behaviour of the [[rest Operator]].
<<.operator-examples "butlast">>

View File

@@ -1,5 +1,5 @@
created: 20150118134611000
modified: 20150118183143000
modified: 20220226043344258
tags: [[butlast Operator]] [[Operator Examples]]
title: butlast Operator (Examples)
type: text/vnd.tiddlywiki
@@ -7,5 +7,6 @@ type: text/vnd.tiddlywiki
<<.using-days-of-week>>
<<.operator-example 1 "[list[Days of the Week]butlast[]]">>
<<.operator-example 2 "[list[Days of the Week]butlast[2]]">>
<<.operator-example 3 "A B C D E F G H I J K L M +[butlast[7]]">>
<<.operator-example 2 "[list[Days of the Week]butlast[0]]">>
<<.operator-example 3 "[list[Days of the Week]butlast[2]]">>
<<.operator-example 4 "A B C D E F G H I J K L M +[butlast[7]]">>

View File

@@ -0,0 +1,28 @@
created: 20220223004441865
modified: 20220223004441865
tags: [[Operator Examples]] [[insertbefore Operator]]
title: insertbefore Operator (Examples)
type: text/vnd.tiddlywiki
\define before-title() Friday
\define missing-title() Yesterday
\define display-variable(name)
''<$text text=<<__name__>>/>'': <code><$text text={{{ [<__name__>getvariable[]] }}}/></code>
\end
These examples use the following predefined variables:
* <<display-variable before-title>>
* <<display-variable missing-title>>
<<.operator-example 1 """[list[Days of the Week]insertbefore[Today]]""">>
<<.operator-example 2 """[list[Days of the Week]insertbefore[Today],[Tuesday]]""">>
<<.operator-example 3 """[list[Days of the Week]insertbefore[Today],<before-title>]""">>
<<.operator-example 4 """[list[Days of the Week]insertbefore:before-title[Today]]""">>
<<.operator-example 5 """[list[Days of the Week]insertbefore[Today],<missing-title>]""">>
<<.operator-example 6 """[list[Days of the Week]insertbefore:missing-title[Today]]""">>

View File

@@ -6,3 +6,8 @@ type: text/vnd.tiddlywiki
<<.operator-example 1 "[all[shadows+tiddlers]tag[$:/tags/PageControls]lookup[$:/config/PageControlButtons/Visibility/]]" "Retrieve the visibility status of each page control button">>
<<.operator-example 2 "[all[shadows+tiddlers]tag[$:/tags/PageControls]lookup:show[$:/config/PageControlButtons/Visibility/]]" "Retrieve the visibility status of each page control button, this time with a default value">>
<<.operator-example 3 "[all[tiddlers]has[plugin-type]removeprefix[$:/plugins/tiddlywiki/]lookup:missing-description:field[$:/plugins/tiddlywiki/],[description]]" "Retrieve the description of all plugin-tiddlers that are in the `$:/plugins/tiddlywiki/` namespace.">>
<<.operator-example 4 "OriginalTiddlerPaths +[lookup:missing-index:index[$:/config/],[HelloThere]]" "Lookup the original tiddler path on disk for the [[Hello There]] tiddler.">>
<<.operator-example 5 "OriginalTiddlerPaths +[lookup:missing-index:index[$:/config/],[MissingTiddler]]" "Lookup the original tiddler path on disk for the [[MissingTiddler]] tiddler.">>
<<.operator-example 6 "HistoryList MissingHistoryList +[lookup:missing-0:index[$:/]]" "Retrieve index `0` from the `$:/HistoryList` and `$:/MissingHistoryList`.">>
<<.operator-example 7 "OriginalTiddlerPaths MissingTiddlerPaths +[lookup:missing-tiddler:index[$:/config/],[$:/key-test]]" "Retrieve index `$:/key-test` from `$:/config/OriginalTiddlerPaths` and `$:/config/MissingTiddlerPaths`.">>

View File

@@ -1,9 +1,10 @@
created: 20150123223129000
modified: 20150123223321000
modified: 20220218023400000
tags: [[prefix Operator]] [[Operator Examples]]
title: prefix Operator (Examples)
type: text/vnd.tiddlywiki
<<.operator-example 1 "[tag[task]!prefix[Go]]">>
<<.operator-example 2 "[prefix[$:/languages/]]">>
<<.operator-example 3 "[prefix[$:/]]" "same as `[is[system]]`">>
<<.operator-example 2 "[tag[task]!prefix:caseinsensitive[go]]">>
<<.operator-example 3 "[prefix[$:/languages/]]">>
<<.operator-example 4 "[prefix[$:/]]" "same as `[is[system]]`">>

View File

@@ -1,7 +1,8 @@
created: 20150118132851000
modified: 20150123210429000
modified: 20220218023400000
tags: [[removeprefix Operator]] [[Operator Examples]]
title: removeprefix Operator (Examples)
type: text/vnd.tiddlywiki
<<.operator-example 1 "[[My Cat]] [[Your Garden]] [[My Favourite Armchair]] +[removeprefix[My ]]">>
<<.operator-example 2 "[[My Cat]] [[Your Garden]] [[My Favourite Armchair]] +[removeprefix:caseinsensitive[my ]]">>

View File

@@ -1,9 +1,8 @@
created: 20150118132851000
modified: 20150123211000000
modified: 20220218023400000
tags: [[removesuffix Operator]] [[Operator Examples]]
title: removesuffix Operator (Examples)
type: text/vnd.tiddlywiki
<<.operator-example 1 "SIMPLEX Googolplex Complex +[removesuffix[plex]]">>
<<.operator-example 2 "SIMPLEX Googolplex Complex +[removesuffix:caseinsensitive[plex]]">>

View File

@@ -1,5 +1,5 @@
created: 20150118134611000
modified: 20150123211722000
modified: 20220226043344258
tags: [[rest Operator]] [[Operator Examples]]
title: rest Operator (Examples)
type: text/vnd.tiddlywiki
@@ -7,5 +7,6 @@ type: text/vnd.tiddlywiki
<<.using-days-of-week>>
<<.operator-example 1 "[list[Days of the Week]rest[]]">>
<<.operator-example 2 "[list[Days of the Week]rest[3]]">>
<<.operator-example 3 "Z Y X W V U T S R Q P O +[rest[5]]">>
<<.operator-example 2 "[list[Days of the Week]rest[0]]">>
<<.operator-example 3 "[list[Days of the Week]rest[3]]">>
<<.operator-example 4 "Z Y X W V U T S R Q P O +[rest[5]]">>

View File

@@ -1,5 +1,5 @@
created: 20150124104508000
modified: 20181025082022690
modified: 20211129122755444
tags: [[search Operator]] [[Operator Examples]]
title: search Operator (Examples)
type: text/vnd.tiddlywiki
@@ -13,3 +13,8 @@ type: text/vnd.tiddlywiki
<$macrocall $name=".operator-example" n="7" eg="[!is[system]search::literal[the first]]" ie="non-system tiddlers containing a case-insensitive match for the literal phrase <<.word 'the first'>>"/>
<$macrocall $name=".operator-example" n="8" eg="[!is[system]search::literal,casesensitive[The first]]" ie="non-system tiddlers containing a case-sensitive match for the literal phrase <<.word 'The first'>>"/>
<$macrocall $name=".operator-example" n="9" eg="[search:caption,description:casesensitive,words[arch]]" ie="any tiddlers containing a case-sensitive match for the word `arch` in their <<.field caption>> or <<.field description>> fields"/>
<$macrocall $name=".operator-example" n="10" eg="[search:tags:some[how test]]" ie="any tiddlers containing at least 1 of the search terms in the field: <<.field tags>>"/>
<$macrocall $name=".operator-example" n="11" eg="[search:tags:some,casesensitive[how test]]" ie="any tiddlers containing at least 1 of the case-sensitive search terms in the field: <<.field tags>>"/>
<$macrocall $name=".operator-example" n="12" eg="[search:tags,title:some,anchored[how test]]" ie="any tiddlers containing at least 1 of anchored search terms in the fields: <<.field tags>> and <<.field title>>"/>

View File

@@ -1,8 +1,9 @@
created: 20150124113652000
modified: 20150124113925000
modified: 20220218023400000
tags: [[suffix Operator]] [[Operator Examples]]
title: suffix Operator (Examples)
type: text/vnd.tiddlywiki
<<.operator-example 1 "[suffix[.jpg]]">>
<<.operator-example 2 "[tag[task]!suffix[ing]]">>
<<.operator-example 2 "[suffix:caseinsensitive[.JPG]]">>
<<.operator-example 3 "[tag[task]!suffix[ing]]">>

View File

@@ -1,15 +1,31 @@
caption: insertbefore
created: 20170406090122441
modified: 20170406091248994
modified: 20220223004441865
op-input: a [[selection of titles|Title Selection]]
op-output: the input tiddler list with the new entry inserted
op-parameter: the title of the tiddler to insert
op-parameter-name: T
op-parameter: <<.from-version "5.2.2">> the <<.op insertbefore>> operator accepts 1 or 2 parameters, see below for details
op-purpose: insert an item <<.place T>> into a list immediately before an item <<.place B>>
op-suffix: the name of a variable containing the title of the tiddler before which this one should be inserted
op-suffix-name: B
op-suffix: (optional) the name of a variable containing the title of the tiddler before which this one should be inserted
tags: [[Filter Operators]] [[Order Operators]] [[Listops Operators]]
title: insertbefore Operator
type: text/vnd.tiddlywiki
<<.from-version "5.2.2">>
The <<.op insertbefore>> operator requires at least one parameter which specifies the title to insert into the input list. A second parameter can be used to specify the title before which the new title should be inserted.
```
insertbefore:<before-title-variable>[<title>],[<before-title>]
```
* ''title'' : a title <<.place T>> to insert in the input list.
* ''before-title'' : (optional). Insert <<.place T>> before this title <<.place B>> in the input list.
* ''before-title-variable'' : (optional). The name of a variable specifying <<.place B>> instead of the `before-title` parameter.
If the item <<.place B>> isn't present in the input list then the new item is inserted at the end of the list.
<<.tip "Either [[parameter|Filter Parameter]] can be a string, a text reference or a variable">>
<<.tip "If <<.place B>> is specified as both a suffix and a parameter, the parameter takes precedence">>
<<.operator-examples "insertbefore">>

View File

@@ -1,24 +1,42 @@
caption: lookup
created: 20170907103639431
modified: 20170907144703051
modified: 20210116081305739
op-input: a [[selection of titles|Title Selection]]
op-output: the lookup values corresponding to each input title
op-parameter: prefix applied to input titles to yield title of lookup tiddler from which value is retrieved
op-parameter-name: P
op-purpose: applies a prefix to each input title to yield the title of a tiddler from which the final value is retrieved
op-suffix: the default value to be used for missing lookups
op-suffix-name: D
op-output: the lookup values corresponding to each lookup tiddler
op-parameter: prefix applied to input titles to yield title of lookup tiddler from which value is retrieved. Now accepts 1 or 2 parameters, see below for details
op-parameter-name: P, T
op-purpose: applies a prefix to each input title to yield the title of a tiddler from which the final value is retrieved. With a single parameter, the default field is "text" and the default index is "0". If a second parameter is provided, that becomes the target field or index.
op-suffix: the default value to be used for missing lookups. This operator can now accept a second suffix of `:index`, see below for details
op-suffix-name: D, I
tags: [[Filter Operators]]
title: lookup Operator
type: text/vnd.tiddlywiki
<<.from-version "5.1.15">>
The action of this operator is as follows:
The action of this operator is as follows with 1 parameter:
* Apply the specified prefix to each input tiddler title, yielding a new list of tiddler titles
* Transclude the value of each of those tiddlers
** Substitute the default value for missing or empty tiddlers
* Transclude the value of the `text` field each of those tiddlers
** Substitute the default value for missing or empty values
* Return the list of values
<<.from-version "5.2.2">>
The use of the `:index` second suffix changes the default lookup location from field: `text` to index: `0`. This is used if no 2nd parameter is provided.
The action of this operator is as follows with 2 parameters:
If there are two parameters provided, use the second parameter as the target field or index.
<<.note """If there is only one parameter given, the filter checks for a second suffix equal to "index". If this suffix is found, the default target index is "0".
In all other cases, the default target field is "text".""">>
Then:
* Apply the specified prefix to each input tiddler title, yielding a new list of tiddler titles
* Transclude the value of the target field or index
** Substitute the default value for missing or empty values
* Return the list of values
<<.operator-examples "lookup">>

View File

@@ -1,5 +1,5 @@
created: 20140410103123179
modified: 20150203192735000
modified: 20220218023400000
tags: [[Filter Operators]] [[String Operators]] [[Negatable Operators]]
title: prefix Operator
type: text/vnd.tiddlywiki
@@ -10,7 +10,22 @@ op-parameter: a string of characters
op-parameter-name: S
op-output: those input titles that start with <<.place S>>
op-neg-output: those input tiddlers that do <<.em not>> start with <<.place S>>
op-suffix: the <<.op prefix>> operator uses a rich suffix, see below for details
<<.s-matching-is-case-sensitive>>
<<.from-version "5.2.2">>
The <<.op prefix>> operator uses an extended syntax that permits multiple flags to be passed:
```
[prefix:<flag list>[<operand>]]
```
* ''flag list'': a comma delimited list of flags
* ''operand'': filter operand
The available flags are:
* ''casesensitive'': (default), this flag forces a case-sensitive match, where upper and lower case letters are considered different
* ''caseinsensitive'': overrides the default so that upper and lower case letters are considered identical for matching purposes
<<.operator-examples "prefix">>

View File

@@ -1,5 +1,5 @@
created: 20140410103123179
modified: 20150203190709000
modified: 20220218023400000
tags: [[Filter Operators]] [[String Operators]]
title: removeprefix Operator
type: text/vnd.tiddlywiki
@@ -9,9 +9,24 @@ op-input: a [[selection of titles|Title Selection]]
op-parameter: a string of characters
op-parameter-name: S
op-output: those input titles that start with <<.place S>>, but with those characters discarded
<<.s-matching-is-case-sensitive>>
op-suffix: the <<.op removeprefix>> operator uses a rich suffix, see below for details
<<.tip " This filters out input titles that do not start with S. For removing S without filtering out input titles that don't start with S, see [[trim|trim Operator]].">>
<<.from-version "5.2.2">>
The <<.op removeprefix>> operator uses an extended syntax that permits multiple flags to be passed:
```
[removeprefix:<flag list>[<operand>]]
```
* ''flag list'': a comma delimited list of flags
* ''operand'': filter operand
The available flags are:
* ''casesensitive'': (default), this flag forces a case-sensitive match, where upper and lower case letters are considered different
* ''caseinsensitive'': overrides the default so that upper and lower case letters are considered identical for matching purposes
<<.operator-examples "removeprefix">>

View File

@@ -1,5 +1,5 @@
created: 20140828133830424
modified: 20150203190744000
modified: 20220218023400000
tags: [[Filter Operators]] [[String Operators]]
title: removesuffix Operator
type: text/vnd.tiddlywiki
@@ -9,9 +9,24 @@ op-input: a [[selection of titles|Title Selection]]
op-parameter: a string of characters
op-parameter-name: S
op-output: those input titles that end with <<.place S>>, but with those characters discarded
<<.s-matching-is-case-sensitive>>
op-suffix: the <<.op removesuffix>> operator uses a rich suffix, see below for details
<<.tip " This filters out input titles that do not end with S. For removing S without filtering out input titles that don't end with S, see [[trim|trim Operator]].">>
<<.from-version "5.2.2">>
The <<.op removesuffix>> operator uses an extended syntax that permits multiple flags to be passed:
```
[removesuffix:<flag list>[<operand>]]
```
* ''flag list'': a comma delimited list of flags
* ''operand'': filter operand
The available flags are:
* ''casesensitive'': (default), this flag forces a case-sensitive match, where upper and lower case letters are considered different
* ''caseinsensitive'': overrides the default so that upper and lower case letters are considered identical for matching purposes
<<.operator-examples "removesuffix">>

View File

@@ -1,15 +1,15 @@
caption: search
created: 20140410103123179
modified: 20190731212738712
modified: 20211129120739275
op-input: a [[selection of titles|Title Selection]]
op-neg-output: those input tiddlers in which <<.em not>> all of the search terms can be found
op-output: those input tiddlers in which <<.em all>> of the search terms can be found in the value of field <<.place F>>
op-parameter: one or more search terms, separated by spaces, or a literal search string
op-purpose: filter the input by searching tiddler content
op-suffix: the <<.op search>> operator uses a rich suffix, see below for details
tags: [[Filter Operators]] [[Common Operators]] [[Field Operators]] [[Negatable Operators]]
title: search Operator
type: text/vnd.tiddlywiki
caption: search
op-purpose: filter the input by searching tiddler content
op-input: a [[selection of titles|Title Selection]]
op-suffix: the <<.op search>> operator uses a rich suffix, see below for details
op-parameter: one or more search terms, separated by spaces, or a literal search string
op-output: those input tiddlers in which <<.em all>> of the search terms can be found in the value of field <<.place F>>
op-neg-output: those input tiddlers in which <<.em not>> all of the search terms can be found
<<.from-version "5.1.18">> The search filter operator was significantly enhanced in 5.1.18. Earlier versions do not support the extended syntax and therefore do not permit searching multiple fields, or the ''literal'' or ''casesensitive'' options.
@@ -38,7 +38,8 @@ The available flags are:
** ''literal'': considers the search string to be a literal string, and requires an exact match
** ''whitespace'': considers the search string to be a literal string, but will consider all runs of whitespace to be equivalent to a single space. Thus `A B` matches `A B`
** ''regexp'': treats the search string as a regular expression. Note that the ''regexp'' option obviates the need for the older <<.olink regexp>> operator.
** ''words'': (the default) treats the search string as a list of tokens separated by whitespace, and matches if all of the tokens appear in the string (regardless of ordering and whether there is other text in between)
** ''words'': (the default) treats the search string as a list of tokens separated by whitespace, and matches if ''all of the tokens'' appear in the string (regardless of ordering and whether there is other text in between)
** ''some'': <<.from-version "5.2.2">> treats the search string as a list of tokens separated by whitespace, and matches if ''at least one'' of the tokens appear in the string
* ''casesensitive'': if present, this flag forces a case-sensitive match, where upper and lower case letters are considered different. By default, upper and lower case letters are considered identical for matching purposes.
* ''anchored'': <<.from-version "5.1.20">> anchors the search to the start of the string (applies to ''whitespace'', ''literal'' and ''words'' modes)

View File

@@ -0,0 +1,18 @@
caption: sha256
created: 20220129105504961
modified: 20220129105504961
op-input: a [[selection of titles|Title Selection]]
op-output: the base64 encoded sha256 of the input, truncated to the specified length
op-parameter: the number of characters to return, up to a maximum of 64
op-parameter-name: L
op-purpose: apply sha256 hash to a string
tags: [[Filter Operators]] [[String Operators]]
title: sha256 Operator
type: text/vnd.tiddlywiki
from-version: 5.1.14
Hashes are a way of turning strings of arbitrary length into obfuscated strings of fixed length. They are often used in situations where items need to be stored by name but it is inconvenient to allow arbitrary length strings.
See Wikipedia for details of the [[sha256|https://en.wikipedia.org/wiki/SHA-2]] operation.
<<.operator-examples "sha256">>

View File

@@ -1,5 +1,5 @@
created: 20140828133830424
modified: 20150203192738000
modified: 20220218023400000
tags: [[Filter Operators]] [[String Operators]] [[Negatable Operators]]
title: suffix Operator
type: text/vnd.tiddlywiki
@@ -10,7 +10,22 @@ op-parameter: a string of characters
op-parameter-name: S
op-output: those input titles that end with <<.place S>>
op-neg-output: those input tiddlers that do <<.em not>> end with <<.place S>>
op-suffix: the <<.op suffix>> operator uses a rich suffix, see below for details
<<.s-matching-is-case-sensitive>>
<<.from-version "5.2.2">>
The <<.op suffix>> operator uses an extended syntax that permits multiple flags to be passed:
```
[suffix:<flag list>[<operand>]]
```
* ''flag list'': a comma delimited list of flags
* ''operand'': filter operand
The available flags are:
* ''casesensitive'': (default), this flag forces a case-sensitive match, where upper and lower case letters are considered different
* ''caseinsensitive'': overrides the default so that upper and lower case letters are considered identical for matching purposes
<<.operator-examples "suffix">>

View File

@@ -1,6 +1,6 @@
created: 20130822170200000
list: [[A Gentle Guide to TiddlyWiki]] [[Discover TiddlyWiki]] [[Some of the things you can do with TiddlyWiki]] [[Ten reasons to switch to TiddlyWiki]] Examples [[What happened to the original TiddlyWiki?]] [[HelloThumbnail - TWEUM2017]]
modified: 20211208115833846
modified: 20220131164555580
tags: TableOfContents
title: HelloThere
type: text/vnd.tiddlywiki
@@ -18,8 +18,8 @@ Use it to keep your [[to-do list|TaskManagementExample]], to plan an [[essay or
Unlike conventional online services, TiddlyWiki lets you choose where to keep your data, guaranteeing that in the decades to come you will [[still be able to use|Future Proof]] the notes you take today.
<div style="font-size:0.7em;text-align:center;margin:3em auto;">
<a href="https://groups.google.com/group/TiddlyWiki" class="tc-btn-big-green" style="border-radius:4px;background-color:#FF8C19;" target="_blank" rel="noopener noreferrer">
{{$:/core/images/help}} Forum
<a href="https://talk.tiddlywiki.org/" class="tc-btn-big-green" style="border-radius:4px;background-color:#FF8C19;" target="_blank" rel="noopener noreferrer">
{{$:/core/images/help}} ~TalkTW
</a>
<a href="https://www.youtube.com/c/JeremyRuston" class="tc-btn-big-green" style="border-radius:4px;background-color:#e52d27;" target="_blank" rel="noopener noreferrer">
{{$:/core/images/video}} ~YouTube

View File

@@ -7,8 +7,6 @@ type: text/vnd.tiddlywiki
The <<.def list-links-draggable>> [[macro|Macros]] renders the ListField of a tiddler as a list of links that can be reordered via [[drag and drop|Drag and Drop]].
Note: The list must be contained in a different tiddler. I.e. If the list is populated in the list field of the current tiddler, the drag and drop action will have no effect.
!! Parameters
;tiddler

View File

@@ -0,0 +1,20 @@
created: 20220301162305764
modified: 20220301180818011
tags: Messages
title: WidgetMessage: tm-close-all-windows
type: text/vnd.tiddlywiki
<<.from-version 5.2.2>>
The `tm-close-all-windows` [[message|Messages]] closes all additional //browser// window that were opened with [[tm-open-window|WidgetMessage: tm-open-window]].
The `tm-close-window` message is best generated with the ActionSendMessageWidget, which in turn is triggered by a widget such as the ButtonWidget. It is handled by the core itself.
<$macrocall $name='wikitext-example-without-html'
src="""
<$button>Close All Windows
<$action-sendmessage
$message="tm-close-all-windows"
/>
</$button>
""" />

View File

@@ -0,0 +1,39 @@
caption: tm-open-window
created: 20220228140417116
modified: 20220301180905777
tags: Messages
title: WidgetMessage: tm-close-window
type: text/vnd.tiddlywiki
<<.from-version 5.2.2>>
The `tm-close-window` [[message|Messages]] closes an additional //browser// window that was opened with [[tm-open-window|WidgetMessage: tm-open-window]]. Specify which window to close by setting the value of <<.param param>> to the string used as <<.param windowID>> when opening the window.
|!Name |!Description |
|param //{default param}// |String used as <<.param windowID>> when opening the window |
The `tm-close-window` message is best generated with the ActionSendMessageWidget, which in turn is triggered by a widget such as the ButtonWidget. It is handled by the core itself.
<<.tip """When used with the ActionSendMessageWidget, <<.param 'param'>> becomes <<.param '$param'>> """>>
<<.tip """To close all additional browser windows that were opened with [[tm-open-window|WidgetMessage: tm-open-window]] use [[WidgetMessage: tm-close-all-windows]]""">>
<$macrocall $name='wikitext-example-without-html'
src="""
<$button>Open Window
<$action-sendmessage
$message="tm-open-window"
$param="$:/temp/openme"
template="SampleWindowTemplate"
windowTitle="My Window Title"
width="400"
height="500"
windowID="window1"
something="I just in over in a variable, and boy is my Hashmap tired." />
</$button>
<$button>Close Window
<$action-sendmessage
$message="tm-close-window"
$param="window1"
/>
</$button>
""" />

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