1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2026-01-24 03:44:41 +00:00

Compare commits

...

124 Commits

Author SHA1 Message Date
jeremy@jermolene.com
d095aa0182 Version number update for 5.2.0 2021-10-03 15:29:21 +01:00
jeremy@jermolene.com
15bf850280 Update plugin library for prerelease 2021-10-03 15:28:40 +01:00
jeremy@jermolene.com
62b273266e Update readme.md and contributing.md for v5.2.0 2021-10-03 15:26:45 +01:00
jeremy@jermolene.com
1d058177be Move v5.2.0 release note and prepare v5.2.1 release note 2021-10-03 15:25:36 +01:00
jeremy@jermolene.com
14676b345a Update modified dates for release note and hellothere 2021-10-03 15:21:02 +01:00
jeremy@jermolene.com
a50e6eed38 Merge branch 'tiddlywiki-com' 2021-10-03 15:12:55 +01:00
Saq Imtiaz
073a064ae8 Fixed typo in relese notes (#6083) 2021-10-03 15:11:03 +01:00
jeremy@jermolene.com
e00a3d3cb4 Update release note with an "Other Notable Improvements" section 2021-10-03 13:06:08 +01:00
jeremy@jermolene.com
68d9200a6b Breakup the action widgets execution modes documentation 2021-10-03 13:05:48 +01:00
jeremy@jermolene.com
2551bb3e3f Update release note 2021-10-03 11:40:35 +01:00
jeremy@jermolene.com
80b18e6315 Update JSON store area docs 2021-10-03 11:40:27 +01:00
Maurycy Zarzycki
e0561397f1 Added Polish translation (#6079)
* add Polish translation

* tweak Polish translations to make certain things moree readable

primarily changed translation of "story river" to keep using the English
phrase, but also some other phraes that were awkward when I used the
translation

* add polish flag icon

* add polish translation notes

* replace 'ukryte tiddlery' with 'tiddlery-cienie'

Co-authored-by: Maurycy Zarzycki <maurycy@evidentlycube.com>
2021-10-03 09:19:48 +01:00
jeremy@jermolene.com
b9c3c38edc List widget: Clarify performance optimisation impact of counter attribute 2021-10-02 18:27:50 +01:00
lin onetwo
077ced0d1a Fix: add text to QR Code button caption (#6082) 2021-10-02 18:09:11 +01:00
jeremy@jermolene.com
e5ff84035c Minor fixes to introduction edition 2021-10-02 17:31:02 +01:00
jeremy@jermolene.com
e18a983209 Update dynaview demo viewtemplate with latest core changes 2021-10-02 17:22:24 +01:00
jeremy@jermolene.com
6f61fa07fb Update view template to use whitespace trim 2021-10-02 17:22:10 +01:00
jeremy@jermolene.com
d5d73e02e9 Fix bug with innerwiki template
The problem was that the innerwiki template included the tiddler $:/plugins/tiddlywiki/railroad, which was omitted from the wiki. Unexpectedly, missing tiddlers were rendered by the jsontiddler widget as an empty object {}. The fix is to always include the title when the tiddler is missing.

Also cleaned up the template to remove unneeded tiddlers
2021-10-02 16:17:07 +01:00
Maurycy Zarzycki
4ba7454d8d Signing the CLA (#6078) 2021-10-01 13:26:00 +01:00
Mario Pietsch
5192a39830 Update German translations (#6077) 2021-09-30 15:46:33 +01:00
jeremy@jermolene.com
aa5413b942 Fix incomplete sentence in MessageCatcherWidget docs 2021-09-30 10:34:27 +01:00
Xavier Cazin
ef284e9bde Update the Android section in Saving via WebDAV (#6069) 2021-09-28 10:22:35 +01:00
Cameron Fischer
9c41fe1d18 JSONTiddler a little more extensible (#6057)
As per discussion #6043
2021-09-27 14:23:52 +01:00
jeremy@jermolene.com
e577cf7302 Render command: verbose mode should print title before rendering
Fixes #6067
2021-09-24 18:40:34 +01:00
jeremy@jermolene.com
ebf563ac70 Additional transliteration pairs
Fixes #6066
2021-09-24 18:29:40 +01:00
jeremy@jermolene.com
909340c6fe Release note tweaks 2021-09-24 12:15:19 +01:00
jeremy@jermolene.com
df6d38df65 Update release note 2021-09-24 12:00:07 +01:00
jeremy@jermolene.com
59a53e695b Further refine date format tokens for day of year and weekday number
See f223896c26
2021-09-23 10:09:27 +01:00
jeremy@jermolene.com
6d17505f7b Fix typo in DateFormat docs 2021-09-23 07:41:06 +01:00
Jeremy Ruston
36dd8ea1d2 Optimise wiki.sortTiddlers() (#6053)
* Optimise wiki.sortTiddlers()

* Remove local changes to test-filters.js that have now been made on master

Makes the subsequent merge easier

* Fix bug with numeric sorts of textual values
2021-09-22 13:44:35 +01:00
Saq Imtiaz
b965ae926b Fix(action-confirm): check if event is defined before accessing its properties (#6063) 2021-09-22 13:43:02 +01:00
jeremy@jermolene.com
f6eadbd1c9 Fix crash with reading invalid JSON files 2021-09-22 12:56:55 +01:00
jeremy@jermolene.com
bdbb884be0 MessageCatcher: Fix stack overflow when re-issuing a trapped message
This makes it possible to trap a message and then re-issue the same message within the action string without an infinite loop.
2021-09-20 16:46:26 +01:00
jeremy@jermolene.com
0be39cfbc2 More sorting tests to help with #6053 2021-09-20 11:04:37 +01:00
Saq Imtiaz
ef2aeac7de Added modulesproperty filter operator and extended modules operator (#6055)
* Added modulesproperty filter operator and extended modules operator. Docs included

* Removed spurious new line
2021-09-20 08:25:53 +01:00
Cameron Fischer
157afda2fc Change backlinks to use LinkedList (#6050) 2021-09-19 19:58:45 +01:00
jeremy@jermolene.com
fb4d77ef46 Improved fix for #5701
Reverts dbd3f835bf

Fixes #6042
2021-09-19 13:28:58 +01:00
Cameron Fischer
575c233597 Update untagged filter to avoid $tw.utils.pushTop (#6034) 2021-09-18 16:47:46 +01:00
Saq Imtiaz
2e59d770f7 Fix eventcatcher widget: check for event properties before accessing (#6048) 2021-09-18 15:08:15 +01:00
Soren Bjornstad
baf0ee9cde Remove stray characters in example of :map prefix (#5963)
The `get[` here isn't valid and looks like a copy-paste error.
2021-09-18 15:04:50 +01:00
Soren Bjornstad
af89bb591d Sign CLA (#6049) 2021-09-18 15:03:42 +01:00
Mario Pietsch
d0dec741ad katex-plugin: fix #6041 add automatic numbering reset to KaTex style-sheet (#6046)
* katex-plugin: fix #6041 add automatic numbering reset to KaTex style-sheet

* fix typo
2021-09-18 09:45:17 +01:00
jeremy@jermolene.com
33a82e395e Revert tiddlylink font weight to match v5.1.23
Otherwise links to missing tiddlers are too skinny
2021-09-17 15:11:29 +01:00
jeremy@jermolene.com
f223896c26 Refine date format tokens for weekday number, and add support for day of year
See discussion at https://groups.google.com/g/tiddlywiki/c/tf23ByDXzxM/m/5Wx7PV36AwAJ
2021-09-17 14:52:08 +01:00
Saq Imtiaz
de33b365ae Fixed refresh bug with radio widget where the tc-radio-selected class is not correctly updated (#6044) 2021-09-17 12:52:27 +01:00
Cameron Fischer
e9d8547a81 Optimise LinkedList filter ops to return iterator instead of array (#6035)
* filter ops don't LinkedList to array anymore

* LL.tiddlerIterator -> LL.makeTiddlerIterator

LinkedList method name change.
2021-09-16 22:22:44 +01:00
Cameron Fischer
dcff318a98 Fix wiki.eachShadow returns overridden sources (#6036)
It was returning the underlying shadows before, even if overridden, which
was causing some bugs.

Fixes #6033
2021-09-16 20:08:11 +01:00
jeremy@jermolene.com
f725123690 Simplify freelinks regexp
As discussed here: https://github.com/Jermolene/TiddlyWiki5/issues/6029#issuecomment-917612980
2021-09-14 10:22:27 +01:00
jeremy@jermolene.com
e9e5d37ff0 Draggable widget: Add option to hide drag image
Thanks @ericshulman

Fixes #6027
2021-09-12 14:20:03 +01:00
jeremy@jermolene.com
f70cee6907 Add new date format tokens for weekday number
See https://en.wikipedia.org/wiki/ISO_8601#Week_dates
2021-09-12 11:53:46 +01:00
jeremy@jermolene.com
1491339f50 Update KaTeX version number 2021-09-12 10:56:39 +01:00
jeremy@jermolene.com
8a5ed59ff4 Release note update for KaTeX 2021-09-12 10:55:33 +01:00
jeremy@jermolene.com
a2ca5e4d1e Update KaTeX to v0.13.18 2021-09-12 10:54:54 +01:00
jeremy@jermolene.com
fba993502d Revert some of the UI changes for downloading external-js
See https://github.com/Jermolene/TiddlyWiki5/pull/5570#issuecomment-892127428
2021-09-12 10:48:17 +01:00
jeremy@jermolene.com
9fae3a932b Release note: Emphasise more flexible parsing of macros 2021-09-12 09:07:15 +01:00
Jieao Song
62610f0666 Add custom macro editor for KaTeX plugin (#5933)
* Add custom macro editor for KaTeX plugin

* Use list

* Better escape

* Tweaks

* Remove const

* Catch bad macros

* Capitalize tags

* Name KaTeX-macro tiddlers properly

* UI tweaks

* Move input string to temp

* Improve UI; import macros using LaTeX cmd directly
2021-09-10 21:28:13 +01:00
Cameron Fischer
7282ec5286 Fix getCacheForTiddler to cache falsy values (#5413)
* getCacheForTiddler can cache falsy values

* Switch to "!== undefined" for getCacheForTiddler
2021-09-10 21:17:35 +01:00
Simon Huber
9830e0104f Fix the EditTabIndex value applied to DomNodes which was '1\n' (#6022) 2021-09-08 14:50:11 +01:00
jeremy@jermolene.com
e6fd0caf6b Update range operator to use multiple operands
We still also support the old way of packing all three parameters into one operand with a delimiter
2021-09-07 17:16:09 +01:00
jeremy@jermolene.com
137df37bc7 Merge branch 'tiddlywiki-com' 2021-09-07 11:02:03 +01:00
Bram Chen
d895706199 Revise chinese translations in Imports.multids (#6024) 2021-09-06 08:16:14 +01:00
Xavier Cazin
6ed7d418b5 A few updates to the fr-FR translation + a typo correction in core Imports.multids (#6023) 2021-09-05 19:51:48 +01:00
jeremy@jermolene.com
62b8a83741 Avoid MSIE crash
Fixes #6014
2021-09-01 09:56:17 +01:00
Marxsal
e795b501ac Update Saving via WebDAV (#6011) 2021-08-31 09:19:10 +01:00
Marxsal
03228d8d20 Allow compare operator to appear on filter list (#6008) 2021-08-30 08:58:26 +01:00
jeremy@jermolene.com
c9c5d4cf79 Remove new docs from #5648
See https://github.com/Jermolene/TiddlyWiki5/pull/5648#issuecomment-907845331
2021-08-29 19:36:23 +01:00
Simon Huber
f5cc5bc6a1 Make stamp-dropdown items that are suffixed and prefixed ... (#6003)
... work for shadow tiddlers, too
2021-08-29 18:04:32 +01:00
Mario Pietsch
447494ad4d Fix some typos in the ViewTolbar button docs (#5974)
* fix some typos in the ViewTolbar button docs

* add missing fields to shadow. closes #5980
2021-08-29 17:50:28 +01:00
Simon Huber
c9f178ec87 Make Stamp-Dropdown sortable by Drag&Drop (#5981)
* Make stamp-dropdown reorderable by list-tagged-draggable macro

* Add stamp-dropdown ItemTemplate tiddler

* Make stamp-entries editable by ctrl-click

* Update stamp-dropdown-item-template.tid

* Add `tc-editortoolbar-stamp-button` class to stamp button

* Make stamp-dropdown look like before

* Update base.tid
2021-08-29 17:48:32 +01:00
jeremy@jermolene.com
33be326ef6 Add from-version banner to search-replace operator "m" flag 2021-08-29 17:45:59 +01:00
Simon Huber
c13f04d838 Add m flag for multiline matches to search-replace filter operator (#5968)
* add m flag to search-replace operator and add tests

* update documentation

* Update test-filters.js

* Update test-filters.js

* Update search-replace Operator (Examples).tid

* Fix "Hello There" title (HelloThere)
2021-08-29 17:44:34 +01:00
Mohammad Rahmani
737685149c Plugins tab in control panel display tabs using tag filter instead of hardcoded list (#5694)
* Plugins tab in control panel display tabs using filter instead of hard coded list

* Update ControlPanelPlugins.tid

The two entries `[[$:/core/ui/ControlPanel/Plugins/Installed]] [[$:/core/ui/ControlPanel/Plugins/Add]]` were removed from list filed as per @Jermelon confirmation!

* Create SystemTag_ $__tags_ControlPanel_Plugins.tid

Update the SystemTags documentation tiddler
2021-08-29 17:35:18 +01:00
Joshua Fontany
33eef0202d Adds $tw.utils.decodeURISafe and $tw.utils.decodeURIComponentSafe (#5999)
* call self.displayError

* Revert "call self.displayError"

This reverts commit 5d599aa979.

* fixes decodeURI & decodeURIComponent
2021-08-29 13:39:32 +01:00
jeremy@jermolene.com
a67b1b8bb5 Fileserver: Check for valid file paths 2021-08-28 13:16:54 +01:00
jeremy@jermolene.com
124b49456a MessageCatcher: Expose lists of the message property names 2021-08-21 12:50:38 +01:00
Saq Imtiaz
24956087cc Do not add X-Requested-With header for simple requests (#5931) 2021-08-17 09:56:52 +01:00
jeremy@jermolene.com
199ca57f1c Release note tweaks 2021-08-15 18:13:02 +01:00
jeremy@jermolene.com
64d53ac533 Release note: Optimised Refreshing of Transclusions
A first attempt to write up the consequences, including the impact on broken JS macros. The problem is that there's not really a simple fix that we can give.

The best I can think of is not good enough: a $:/config/ tiddler that globally controls whether the transclude widget uses the new selective refreshing.
2021-08-15 13:17:59 +01:00
Cameron Fischer
b3accbf9e0 Fakedom: use text encoder for html text (#5950) 2021-08-12 16:46:11 +01:00
Joshua Fontany
99249a3160 Fix syncer logout alert (#5936)
* call self.displayError

* Revert "call self.displayError"

This reverts commit 5d599aa979.

* fix Syncer logout alert
2021-08-05 14:50:22 +01:00
Jieao Song
f7cd8bad3a Signing the CLA (#5938) 2021-08-05 14:42:28 +01:00
jeremy@jermolene.com
e9613d7f12 eventcatcher widget: Add viewport-relative coordinates
This is useful because we get viewport relative coordinates from the link and action-navigate widgets
2021-08-05 08:35:44 +01:00
jeremy@jermolene.com
97dff042f7 Reveal widget: fix crash when popup tiddler is refreshed but the popup is not displayed 2021-08-04 17:00:42 +01:00
jeremy@jermolene.com
32b36fb2af Update New Release Banner with winning artwork from Frank B 2021-08-04 11:58:04 +01:00
jeremy@jermolene.com
41535150dd Fix docs typos in "Customising Tiddler File Naming" 2021-08-03 20:47:44 +01:00
jeremy@jermolene.com
8e69284e8c Updated Catalan translation from Paco Riviere 2021-08-01 15:19:14 +01:00
jeremy@jermolene.com
61cfac4eeb Fix typo in release note
Thanks @twMat
2021-07-30 16:33:00 +01:00
jeremy@jermolene.com
2720072b23 Text editor: fix crash when assigning new value to file input controls
Fixes #5911
2021-07-30 16:31:42 +01:00
Joshua Fontany
0413c3a38e Fix syncer error handling for getStatus (#5914) 2021-07-30 16:21:02 +01:00
Mario Pietsch
f2b30c1fe0 tabs-macro: improve info about the "default" parameter (#5904) 2021-07-30 16:19:23 +01:00
Simon Huber
3c86cf7d2e Add pop storyview to ViewToolbar buttons (#5910)
* Add pop storyview to ViewToolbar buttons

* Update title.tid
2021-07-30 16:11:27 +01:00
jeremy@jermolene.com
451074f7ed Fix typo in release note
Thanks @twMat
2021-07-29 12:41:26 +01:00
Saq Imtiaz
1e5601ca31 Fix inaccuracies in documentation for duplicateslugs[] (#5918) 2021-07-29 11:39:20 +01:00
jeremy@jermolene.com
75c99cd235 Merge branch 'tiddlywiki-com' 2021-07-27 19:33:36 +01:00
jeremy@jermolene.com
bb2c2be9b6 Remove file erroneously committed in c4a7ae3164 2021-07-27 19:33:20 +01:00
jeremy@jermolene.com
53c247b9a1 Merge branch 'tiddlywiki-com' 2021-07-27 19:30:44 +01:00
Mario Pietsch
82667d9d16 Add indentation to $:/core/ui/Components/plugin-info (#5777)
* Add indentation to plugin-info, to make the macros readable.

* add missing indent
2021-07-26 21:59:02 +01:00
Bram Chen
97ed2757f0 Revise chinese translations (#5915) 2021-07-26 14:31:43 +01:00
jeremy@jermolene.com
19fd5ca5f2 Remove erroneous \s from field name check
Fixes #5905
2021-07-22 16:55:17 +01:00
jeremy@jermolene.com
6ae78a770f Fix erroneous bolding of links
An accident from f97850dd05
2021-07-19 14:03:12 +01:00
jeremy@jermolene.com
04962b4cd6 Update release note 2021-07-19 12:56:18 +01:00
jeremy@jermolene.com
f97850dd05 Update "Snow White" font-family and font-weight
Fixes #5896
2021-07-19 12:54:57 +01:00
jeremy@jermolene.com
2cb3ed3ab9 Change tab switching shortcuts to alt-ctrl-left/right
Fixes #5889
2021-07-16 13:06:49 +01:00
jeremy@jermolene.com
a4421f50c6 Git{hub|ea|lab} saver should wikify commit messages
Proposed in discussion https://github.com/Jermolene/TiddlyWiki5/discussions/5886#discussioncomment-1012593
2021-07-16 12:04:05 +01:00
Saq Imtiaz
cb726f40fa Fix: bug with List Widget where the counter-last variable is not always accurately updated on refresh (#5883) 2021-07-15 21:59:07 +01:00
Arlen22
be026aa308 Revert "Add server sent events (#5279)" (#5880)
This reverts commit 17b4f53ba2 according to Github Desktop.

git checkout that commit
revert commit in GitHub Desktop
git switch -c revert-sse
uncommit in Github Desktop
switch to master, bringing changes
resolve deletions with command line
2021-07-14 17:16:57 +01:00
RJ Skerry-Ryan
b95f6ca084 Signing the CLA (#5847) 2021-07-04 11:57:38 +01:00
twMat
4a7f078abd Update qualify.tid (#5845)
superfluous blockquoting
2021-07-03 17:43:20 +01:00
Tejasvi S. Tomar
54d8b8a373 Correct term usage (#5417) 2021-06-29 12:24:09 +01:00
GHSRobert Ciang
dd6bd58140 Update TiddlyWiki in the Sky for Dropbox.tid (#5832) 2021-06-29 12:09:16 +01:00
Álvaro González Rincón
4c56bd771a Signing the CLA (#5794) 2021-06-14 17:42:26 +01:00
Frank
a70b26cd55 Sign the CLA (#5774) 2021-06-09 21:32:31 +01:00
jeremy@jermolene.com
c4a7ae3164 Add demo of drag and drop from a standalone HTML file 2021-06-03 14:14:11 +01:00
Joe Bordes
8b8f654c9c Signing the CLA (#5730) 2021-05-30 18:47:34 +01:00
Mario Pietsch
f342fdc41d improve setwidget examples and add a link to and from enlist operator (#5666) 2021-05-25 22:19:28 +01:00
Mario Pietsch
ca96f7f62b contain the long list inside a div which is 50% of vertical height (#5385) 2021-05-25 22:19:09 +01:00
Saq Imtiaz
2f31eab8f4 Update docs for tabs macro (#5722) 2021-05-25 22:16:02 +01:00
Saq Imtiaz
c8528fd1f7 Update keyboard-driven-input_Macro.tid (#5712) 2021-05-21 10:02:35 +01:00
Chris Nicoll
07ac85d9fa Add demo for keyboard-driven-input (#5710) 2021-05-21 09:54:11 +01:00
jeremy@jermolene.com
e84f214280 Add link to @sobjornstad's "Grok TiddlyWiki" 2021-05-19 11:08:48 +01:00
ualich
9cd65efad9 Signing the CLA (#5671) 2021-05-06 12:24:08 +01:00
Chris Nicoll
41200ab6d7 Fix #5310: docs for unique[] filter operator (#5651)
Co-authored-by: clutterstack <clutterstack@gmail.com>
2021-04-29 13:14:28 +01:00
Simon Baird
792171c8fc Two typo fixups related to surplus tilde chars (#5627) 2021-04-24 15:42:02 +01:00
Simon Baird
051a468c63 Add info on TiddlyHost saving & revised TiddlySpot (#5622)
I updated the English text only. Will need some help with the
translations.

Summary:
- Mention that TiddlySpot is deprecated and doesn't allow site
  creation any more. Suggest using TiddlyHost instead.
- Remove obsolete intructions about creating TiddlySpot sites.
- Misc editing/rewording/tweaking of existing TiddlySpot info
  for tidiness and clarity.
- Add new information about saving on TiddlyHost.
- Add logos because why not..

Note: I usually prefer the non-camel case versions of Tiddlyspot and
Tiddlyhost, but decided to go with the CamelCase WikiWords here to
fit in with the existing conventions.
2021-04-23 17:45:44 +01:00
311 changed files with 7053 additions and 3837 deletions

View File

@@ -1212,8 +1212,12 @@ $tw.Wiki = function(options) {
index,titlesLength,title;
for(index = 0, titlesLength = titles.length; index < titlesLength; index++) {
title = titles[index];
var shadowInfo = shadowTiddlers[title];
callback(shadowInfo.tiddler,title);
if(tiddlers[title]) {
callback(tiddlers[title],title);
} else {
var shadowInfo = shadowTiddlers[title];
callback(shadowInfo.tiddler,title);
}
}
};
@@ -1602,8 +1606,8 @@ $tw.modules.define("$:/boot/tiddlerdeserializer/json","tiddlerdeserializer",{
}
for(var f in data) {
if($tw.utils.hop(data,f)) {
// Check field name doesn't contain whitespace or control characters
if(typeof(data[f]) !== "string" || /[\x00-\x1F\s]/.test(f)) {
// Check field name doesn't contain control characters
if(typeof(data[f]) !== "string" || /[\x00-\x1F]/.test(f)) {
return false;
}
}
@@ -1618,7 +1622,12 @@ $tw.modules.define("$:/boot/tiddlerdeserializer/json","tiddlerdeserializer",{
}
return true;
},
data = JSON.parse(text);
data = {};
try {
data = JSON.parse(text);
} catch(e) {
// Ignore JSON parse errors
}
if($tw.utils.isArray(data) && isTiddlerArrayValid(data)) {
return data;
} else if(isTiddlerValid(data)) {
@@ -1885,13 +1894,13 @@ $tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
value = path.basename(filename);
break;
case "filename-uri-decoded":
value = decodeURIComponent(path.basename(filename));
value = $tw.utils.decodeURIComponentSafe(path.basename(filename));
break;
case "basename":
value = path.basename(filename,path.extname(filename));
break;
case "basename-uri-decoded":
value = decodeURIComponent(path.basename(filename,path.extname(filename)));
value = $tw.utils.decodeURIComponentSafe(path.basename(filename,path.extname(filename)));
break;
case "extname":
value = path.extname(filename);

File diff suppressed because one or more lines are too long

View File

@@ -32,8 +32,6 @@ ExportTiddler/Caption: export tiddler
ExportTiddler/Hint: Export tiddler
ExportTiddlers/Caption: export tiddlers
ExportTiddlers/Hint: Export tiddlers
ExportTiddlyWikiCore/Caption: export TiddlyWiki core
ExportTiddlyWikiCore/Hint: Export the ~TiddlyWiki core code for running with external ~JavaScript
SidebarSearch/Hint: Select the sidebar search field
Fold/Caption: fold tiddler
Fold/Hint: Fold the body of this tiddler

View File

@@ -22,7 +22,6 @@ All parameters are optional with safe defaults, and can be specified in any orde
* ''readers'' - comma-separated list of principals allowed to read from this wiki
* ''writers'' - comma-separated list of principals allowed to write to this wiki
* ''csrf-disable'' - set to "yes" to disable CSRF checks (defaults to "no")
* ''sse-enabled'' - set to "yes" to enable Server-sent events (defaults to "no")
* ''root-tiddler'' - the tiddler to serve at the root (defaults to "$:/core/save/all")
* ''root-render-type'' - the content type to which the root tiddler should be rendered (defaults to "text/plain")
* ''root-serve-type'' - the content type with which the root tiddler should be served (defaults to "text/html")

View File

@@ -30,5 +30,5 @@ Upgrader/System/Warning: Core module tiddler.
Upgrader/System/Alert: You are about to import a tiddler that will overwrite a core module tiddler. This is not recommended as it may make the system unstable.
Upgrader/ThemeTweaks/Created: Migrated theme tweak from <$text text=<<from>>/>.
Upgrader/Tiddler/Disabled: Disabled tiddler.
Upgrader/Tiddler/Selected: User selected.
Upgrader/Tiddler/Selected: Selected tiddler.
Upgrader/Tiddler/Unselected: Unselected tiddler.

View File

@@ -8,58 +8,59 @@ Render individual tiddlers and save the results to the specified files
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var widget = require("$:/core/modules/widgets/widget.js");
exports.info = {
name: "render",
synchronous: true
};
var Command = function(params,commander,callback) {
this.params = params;
this.commander = commander;
this.callback = callback;
};
Command.prototype.execute = function() {
if(this.params.length < 1) {
return "Missing tiddler filter";
}
var self = this,
fs = require("fs"),
path = require("path"),
wiki = this.commander.wiki,
tiddlerFilter = this.params[0],
filenameFilter = this.params[1] || "[is[tiddler]addsuffix[.html]]",
type = this.params[2] || "text/html",
template = this.params[3],
variableList = this.params.slice(4),
tiddlers = wiki.filterTiddlers(tiddlerFilter),
variables = Object.create(null);
while(variableList.length >= 2) {
variables[variableList[0]] = variableList[1];
variableList = variableList.slice(2);
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var widget = require("$:/core/modules/widgets/widget.js");
exports.info = {
name: "render",
synchronous: true
};
var Command = function(params,commander,callback) {
this.params = params;
this.commander = commander;
this.callback = callback;
};
Command.prototype.execute = function() {
if(this.params.length < 1) {
return "Missing tiddler filter";
}
$tw.utils.each(tiddlers,function(title) {
var parser = wiki.parseTiddler(template || title);
var widgetNode = wiki.makeWidget(parser,{variables: $tw.utils.extend({},variables,{currentTiddler: title})}),
container = $tw.fakeDocument.createElement("div");
widgetNode.render(container,null);
var text = type === "text/html" ? container.innerHTML : container.textContent,
filepath = path.resolve(self.commander.outputPath,wiki.filterTiddlers(filenameFilter,$tw.rootWidget,wiki.makeTiddlerIterator([title]))[0]);
if(self.commander.verbose) {
console.log("Rendering \"" + title + "\" to \"" + filepath + "\"");
}
$tw.utils.createFileDirectories(filepath);
fs.writeFileSync(filepath,text,"utf8");
});
return null;
};
exports.Command = Command;
})();
var self = this,
fs = require("fs"),
path = require("path"),
wiki = this.commander.wiki,
tiddlerFilter = this.params[0],
filenameFilter = this.params[1] || "[is[tiddler]addsuffix[.html]]",
type = this.params[2] || "text/html",
template = this.params[3],
variableList = this.params.slice(4),
tiddlers = wiki.filterTiddlers(tiddlerFilter),
variables = Object.create(null);
while(variableList.length >= 2) {
variables[variableList[0]] = variableList[1];
variableList = variableList.slice(2);
}
$tw.utils.each(tiddlers,function(title) {
var filepath = path.resolve(self.commander.outputPath,wiki.filterTiddlers(filenameFilter,$tw.rootWidget,wiki.makeTiddlerIterator([title]))[0]);
if(self.commander.verbose) {
console.log("Rendering \"" + title + "\" to \"" + filepath + "\"");
}
var parser = wiki.parseTiddler(template || title),
widgetNode = wiki.makeWidget(parser,{variables: $tw.utils.extend({},variables,{currentTiddler: title})}),
container = $tw.fakeDocument.createElement("div");
widgetNode.render(container,null);
var text = type === "text/html" ? container.innerHTML : container.textContent;
$tw.utils.createFileDirectories(filepath);
fs.writeFileSync(filepath,text,"utf8");
});
return null;
};
exports.Command = Command;
})();

View File

@@ -135,7 +135,11 @@ FramedEngine.prototype.setText = function(text,type) {
Update the DomNode with the new text
*/
FramedEngine.prototype.updateDomNodeText = function(text) {
this.domNode.value = text;
try {
this.domNode.value = text;
} catch(e) {
// Ignore
}
};
/*

View File

@@ -85,7 +85,11 @@ SimpleEngine.prototype.setText = function(text,type) {
Update the DomNode with the new text
*/
SimpleEngine.prototype.updateDomNodeText = function(text) {
this.domNode.value = text;
try {
this.domNode.value = text;
} catch(e) {
// Ignore
}
};
/*

View File

@@ -332,7 +332,7 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
};
EditTextWidget.prototype.handlePasteEvent = function(event) {
if(event.clipboardData.files.length) {
if(event.clipboardData && event.clipboardData.files && event.clipboardData.files.length) {
event.preventDefault();
event.stopPropagation();
this.dispatchDOMEvent(this.cloneEvent(event,["clipboardData"]));

View File

@@ -52,7 +52,7 @@ exports.all = function(source,operator,options) {
results.pushTop(subop(source,operator.prefix,options));
}
}
return results.toArray();
return results.makeTiddlerIterator(options.wiki);
};
})();

View File

@@ -16,11 +16,11 @@ Filter operator for returning all the backlinks from a tiddler
Export our filter function
*/
exports.backlinks = function(source,operator,options) {
var results = [];
var results = new $tw.utils.LinkedList();
source(function(tiddler,title) {
$tw.utils.pushTop(results,options.wiki.getTiddlerBacklinks(title));
results.pushTop(options.wiki.getTiddlerBacklinks(title));
});
return results;
return results.makeTiddlerIterator(options.wiki);
};
})();

View File

@@ -19,12 +19,7 @@ Export our filter functions
exports.decodeuricomponent = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
var value = title;
try {
value = decodeURIComponent(title);
} catch(e) {
}
results.push(value);
results.push($tw.utils.decodeURIComponentSafe(title));
});
return results;
};
@@ -40,12 +35,7 @@ exports.encodeuricomponent = function(source,operator,options) {
exports.decodeuri = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
var value = title;
try {
value = decodeURI(title);
} catch(e) {
}
results.push(value);
results.push($tw.utils.decodeURISafe(title));
});
return results;
};

View File

@@ -20,7 +20,7 @@ exports.links = function(source,operator,options) {
source(function(tiddler,title) {
results.pushTop(options.wiki.getTiddlerLinks(title));
});
return results.toArray();
return results.makeTiddlerIterator(options.wiki);
};
})();

View File

@@ -0,0 +1,30 @@
/*\
title: $:/core/modules/filters/moduleproperty.js
type: application/javascript
module-type: filteroperator
Filter [[module-name]moduleproperty[name]] retrieve a module property
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.moduleproperty = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
var value = require(title)[operator.operand || ""];
if(value !== undefined) {
results.push(value);
}
});
results.sort();
return results;
};
})();

View File

@@ -17,11 +17,23 @@ Export our filter function
*/
exports.modules = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
$tw.utils.each($tw.modules.types[title],function(moduleInfo,moduleName) {
results.push(moduleName);
if(operator.operands.length >= 2) {
// Return the modules that have the module property specified in the first operand with the value in the second operand
source(function(tiddler,title) {
$tw.utils.each($tw.modules.types[title],function(moduleInfo,moduleName) {
if(require(moduleName)[operator.operands[0]] === operator.operands[1]) {
results.push(moduleName);
}
});
});
});
} else {
// Return all the module names without filtering
source(function(tiddler,title) {
$tw.utils.each($tw.modules.types[title],function(moduleInfo,moduleName) {
results.push(moduleName);
});
});
}
results.sort();
return results;
};

View File

@@ -17,9 +17,13 @@ Export our filter function
*/
exports.range = function(source,operator,options) {
var results = [];
// Split the operand into numbers delimited by these symbols
var parts = operator.operand.split(/[,:;]/g),
beg, end, inc, i, fixed = 0;
// For backwards compatibility, if there is only one operand, try to split it using one of the delimiters
var parts = operator.operands || [];
if(parts.length === 1) {
parts = operator.operand.split(/[,:;]/g);
}
// Process the parts
var beg, end, inc, i, fixed = 0;
for (i=0; i<parts.length; i++) {
// Validate real number
if(!/^\s*[+-]?((\d+(\.\d*)?)|(\.\d+))\s*$/.test(parts[i])) {

View File

@@ -119,7 +119,7 @@ exports["search-replace"] = function(source,operator,options) {
var results = [],
suffixes = operator.suffixes || [],
flagSuffix = (suffixes[0] ? (suffixes[0][0] || "") : ""),
flags = (flagSuffix.indexOf("g") !== -1 ? "g" : "") + (flagSuffix.indexOf("i") !== -1 ? "i" : ""),
flags = (flagSuffix.indexOf("g") !== -1 ? "g" : "") + (flagSuffix.indexOf("i") !== -1 ? "i" : "") + (flagSuffix.indexOf("m") !== -1 ? "m" : ""),
isRegExp = (suffixes[1] && suffixes[1][0] === "regexp") ? true : false,
searchTerm,
regExp;

View File

@@ -16,20 +16,13 @@ Filter operator returning all the selected tiddlers that are untagged
Export our filter function
*/
exports.untagged = function(source,operator,options) {
var results = [];
if(operator.prefix === "!") {
source(function(tiddler,title) {
if(tiddler && $tw.utils.isArray(tiddler.fields.tags) && tiddler.fields.tags.length > 0) {
$tw.utils.pushTop(results,title);
}
});
} else {
source(function(tiddler,title) {
if(!tiddler || !tiddler.hasField("tags") || ($tw.utils.isArray(tiddler.fields.tags) && tiddler.fields.tags.length === 0)) {
$tw.utils.pushTop(results,title);
}
});
}
var results = [],
expected = (operator.prefix === "!");
source(function(tiddler,title) {
if((tiddler && $tw.utils.isArray(tiddler.fields.tags) && tiddler.fields.tags.length > 0) === expected) {
results.push(title);
}
});
return results;
};

View File

@@ -42,7 +42,7 @@ AndTidWiki.prototype.save = function(text,method,callback,options) {
window.twi.saveWiki(text);
} else {
// Get the pathname of this document
var pathname = decodeURIComponent(document.location.toString().split("#")[0]);
var pathname = $tw.utils.decodeURIComponentSafe(document.location.toString().split("#")[0]);
// Strip the file://
if(pathname.indexOf("file://") === 0) {
pathname = pathname.substr(7);

View File

@@ -26,7 +26,7 @@ DownloadSaver.prototype.save = function(text,method,callback,options) {
var p = document.location.pathname.lastIndexOf("/");
if(p !== -1) {
// We decode the pathname because document.location is URL encoded by the browser
filename = decodeURIComponent(document.location.pathname.substr(p+1));
filename = $tw.utils.decodeURIComponentSafe(document.location.pathname.substr(p+1));
}
}
if(!filename) {

View File

@@ -72,7 +72,7 @@ GiteaSaver.prototype.save = function(text,method,callback) {
}
}
var data = {
message: $tw.language.getRawString("ControlPanel/Saving/GitService/CommitMessage"),
message: $tw.language.getString("ControlPanel/Saving/GitService/CommitMessage"),
content: $tw.utils.base64Encode(text),
sha: sha
};

View File

@@ -69,7 +69,7 @@ GitHubSaver.prototype.save = function(text,method,callback) {
});
}
var data = {
message: $tw.language.getRawString("ControlPanel/Saving/GitService/CommitMessage"),
message: $tw.language.getString("ControlPanel/Saving/GitService/CommitMessage"),
content: $tw.utils.base64Encode(text),
branch: branch,
sha: sha

View File

@@ -67,7 +67,7 @@ GitLabSaver.prototype.save = function(text,method,callback) {
});
}
var data = {
commit_message: $tw.language.getRawString("ControlPanel/Saving/GitService/CommitMessage"),
commit_message: $tw.language.getString("ControlPanel/Saving/GitService/CommitMessage"),
content: text,
branch: branch,
sha: sha

View File

@@ -43,7 +43,7 @@ TiddlyFoxSaver.prototype.save = function(text,method,callback) {
}
// Create the message element and put it in the message box
var message = document.createElement("div");
message.setAttribute("data-tiddlyfox-path",decodeURIComponent(pathname));
message.setAttribute("data-tiddlyfox-path",$tw.utils.decodeURIComponentSafe(pathname));
message.setAttribute("data-tiddlyfox-content",text);
messageBox.appendChild(message);
// Add an event handler for when the file has been saved

View File

@@ -21,7 +21,7 @@ TWEditSaver.prototype.save = function(text,method,callback) {
return false;
}
// Get the pathname of this document
var pathname = decodeURIComponent(document.location.pathname);
var pathname = $tw.utils.decodeURIComponentSafe(document.location.pathname);
// Strip any query or location part
var p = pathname.indexOf("?");
if(p !== -1) {

View File

@@ -17,7 +17,7 @@ exports.method = "DELETE";
exports.path = /^\/bags\/default\/tiddlers\/(.+)$/;
exports.handler = function(request,response,state) {
var title = decodeURIComponent(state.params[0]);
var title = $tw.utils.decodeURIComponentSafe(state.params[0]);
state.wiki.deleteTiddler(title);
response.writeHead(204, "OK", {
"Content-Type": "text/plain"

View File

@@ -20,22 +20,29 @@ exports.handler = function(request,response,state) {
var path = require("path"),
fs = require("fs"),
util = require("util"),
suppliedFilename = decodeURIComponent(state.params[0]),
filename = path.resolve(state.boot.wikiPath,"files",suppliedFilename),
suppliedFilename = $tw.utils.decodeURIComponentSafe(state.params[0]),
baseFilename = path.resolve(state.boot.wikiPath,"files"),
filename = path.resolve(baseFilename,suppliedFilename),
extension = path.extname(filename);
fs.readFile(filename,function(err,content) {
var status,content,type = "text/plain";
if(err) {
console.log("Error accessing file " + filename + ": " + err.toString());
status = 404;
content = "File '" + suppliedFilename + "' not found";
} else {
status = 200;
content = content;
type = ($tw.config.fileExtensionInfo[extension] ? $tw.config.fileExtensionInfo[extension].type : "application/octet-stream");
}
state.sendResponse(status,{"Content-Type": type},content);
});
// Check that the filename is inside the wiki files folder
if(path.relative(baseFilename,filename).indexOf("..") !== 0) {
// Send the file
fs.readFile(filename,function(err,content) {
var status,content,type = "text/plain";
if(err) {
console.log("Error accessing file " + filename + ": " + err.toString());
status = 404;
content = "File '" + suppliedFilename + "' not found";
} else {
status = 200;
content = content;
type = ($tw.config.fileExtensionInfo[extension] ? $tw.config.fileExtensionInfo[extension].type : "application/octet-stream");
}
state.sendResponse(status,{"Content-Type": type},content);
});
} else {
state.sendResponse(404,{"Content-Type": "text/plain"},"File '" + suppliedFilename + "' not found");
}
};
}());

View File

@@ -21,7 +21,6 @@ exports.handler = function(request,response,state) {
username: state.authenticatedUsername || state.server.get("anon-username") || "",
anonymous: !state.authenticatedUsername,
read_only: !state.server.isAuthorized("writers",state.authenticatedUsername),
sse_enabled: state.server.get("sse-enabled") === "yes",
space: {
recipe: "default"
},

View File

@@ -17,7 +17,7 @@ exports.method = "GET";
exports.path = /^\/([^\/]+)$/;
exports.handler = function(request,response,state) {
var title = decodeURIComponent(state.params[0]),
var title = $tw.utils.decodeURIComponentSafe(state.params[0]),
tiddler = state.wiki.getTiddler(title);
if(tiddler) {
var renderType = tiddler.getFieldString("_render_type"),

View File

@@ -17,7 +17,7 @@ exports.method = "GET";
exports.path = /^\/recipes\/default\/tiddlers\/(.+)$/;
exports.handler = function(request,response,state) {
var title = decodeURIComponent(state.params[0]),
var title = $tw.utils.decodeURIComponentSafe(state.params[0]),
tiddler = state.wiki.getTiddler(title),
tiddlerFields = {},
knownFields = [

View File

@@ -17,7 +17,7 @@ exports.method = "PUT";
exports.path = /^\/recipes\/default\/tiddlers\/(.+)$/;
exports.handler = function(request,response,state) {
var title = decodeURIComponent(state.params[0]),
var title = $tw.utils.decodeURIComponentSafe(state.params[0]),
fields = JSON.parse(state.data);
// Pull up any subfields in the `fields` object
if(fields.fields) {

View File

@@ -1,70 +0,0 @@
/*\
title: $:/core/modules/server/server-sent-events.js
type: application/javascript
module-type: library
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
parameters:
prefix - usually the plugin path, such as `plugins/tiddlywiki/tiddlyweb`. The
route will match `/events/${prefix}` exactly.
handler - a function that will be called each time a request comes in with the
request and state from the route and an emit function to call.
*/
var ServerSentEvents = function ServerSentEvents(prefix, handler) {
this.handler = handler;
this.prefix = prefix;
};
ServerSentEvents.prototype.getExports = function() {
return {
bodyFormat: "stream",
method: "GET",
path: new RegExp("^/events/" + this.prefix + "$"),
handler: this.handleEventRequest.bind(this)
};
};
ServerSentEvents.prototype.handleEventRequest = function(request,response,state) {
if(ServerSentEvents.prototype.isEventStreamRequest(request)) {
response.writeHead(200, {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
"Connection": "keep-alive"
});
this.handler(request,state,this.emit.bind(this,response),this.end.bind(this,response));
} else {
response.writeHead(406,"Not Acceptable",{});
response.end();
}
};
ServerSentEvents.prototype.isEventStreamRequest = function(request) {
return request.headers.accept &&
request.headers.accept.match(/^text\/event-stream/);
};
ServerSentEvents.prototype.emit = function(response,event,data) {
if(typeof event !== "string" || event.indexOf("\n") !== -1) {
throw new Error("Type must be a single-line string");
}
if(typeof data !== "string" || data.indexOf("\n") !== -1) {
throw new Error("Data must be a single-line string");
}
response.write("event: " + event + "\ndata: " + data + "\n\n", "utf8");
};
ServerSentEvents.prototype.end = function(response) {
response.end();
};
exports.ServerSentEvents = ServerSentEvents;
})();

View File

@@ -120,10 +120,10 @@ function openStartupTiddlers(options) {
var hash = $tw.locationHash.substr(1),
split = hash.indexOf(":");
if(split === -1) {
target = decodeURIComponent(hash.trim());
target = $tw.utils.decodeURIComponentSafe(hash.trim());
} else {
target = decodeURIComponent(hash.substr(0,split).trim());
storyFilter = decodeURIComponent(hash.substr(split + 1).trim());
target = $tw.utils.decodeURIComponentSafe(hash.substr(0,split).trim());
storyFilter = $tw.utils.decodeURIComponentSafe(hash.substr(split + 1).trim());
}
}
// If the story wasn't specified use the current tiddlers or a blank story

View File

@@ -20,7 +20,6 @@ Syncer.prototype.titleIsAnonymous = "$:/status/IsAnonymous";
Syncer.prototype.titleIsReadOnly = "$:/status/IsReadOnly";
Syncer.prototype.titleUserName = "$:/status/UserName";
Syncer.prototype.titleSyncFilter = "$:/config/SyncFilter";
Syncer.prototype.titleSyncDisablePolling = "$:/config/SyncDisablePolling";
Syncer.prototype.titleSyncPollingInterval = "$:/config/SyncPollingInterval";
Syncer.prototype.titleSyncDisableLazyLoading = "$:/config/SyncDisableLazyLoading";
Syncer.prototype.titleSavedNotification = "$:/language/Notifications/Save/Done";
@@ -90,7 +89,7 @@ function Syncer(options) {
if(filteredChanges.length > 0) {
self.processTaskQueue();
} else {
// Look for deletions of tiddlers we're already syncing
// Look for deletions of tiddlers we're already syncing
var outstandingDeletion = false
$tw.utils.each(changes,function(change,title,object) {
if(change.deleted && $tw.utils.hop(self.tiddlerInfo,title)) {
@@ -122,7 +121,7 @@ function Syncer(options) {
self.login(username,password,function() {});
} else {
// No username and password, so we display a prompt
self.handleLoginEvent();
self.handleLoginEvent();
}
});
$tw.rootWidget.addEventListener("tm-logout",function() {
@@ -139,7 +138,7 @@ function Syncer(options) {
if(!this.disableUI && this.wiki.getTiddlerText(this.titleSyncDisableLazyLoading) !== "yes") {
this.wiki.addEventListener("lazyLoad",function(title) {
self.handleLazyLoadEvent(title);
});
});
}
// Get the login status
this.getStatus(function(err,isLoggedIn) {
@@ -174,8 +173,8 @@ Syncer.prototype.getTiddlerRevision = function(title) {
if(this.syncadaptor && this.syncadaptor.getTiddlerRevision) {
return this.syncadaptor.getTiddlerRevision(title);
} else {
return this.wiki.getTiddler(title).fields.revision;
}
return this.wiki.getTiddler(title).fields.revision;
}
};
/*
@@ -268,9 +267,9 @@ Syncer.prototype.getStatus = function(callback) {
// Mark us as not logged in
this.wiki.addTiddler({title: this.titleIsLoggedIn,text: "no"});
// Get login status
this.syncadaptor.getStatus(function(err,isLoggedIn,username,isReadOnly,isAnonymous,isPollingDisabled) {
this.syncadaptor.getStatus(function(err,isLoggedIn,username,isReadOnly,isAnonymous) {
if(err) {
self.logger.alert(err);
self.displayError("Get Status Error",err);
} else {
// Set the various status tiddlers
self.wiki.addTiddler({title: self.titleIsReadOnly,text: isReadOnly ? "yes" : "no"});
@@ -279,9 +278,6 @@ Syncer.prototype.getStatus = function(callback) {
if(isLoggedIn) {
self.wiki.addTiddler({title: self.titleUserName,text: username || ""});
}
if(isPollingDisabled) {
self.wiki.addTiddler({title: self.titleSyncDisablePolling, text: "yes"});
}
}
// Invoke the callback
if(callback) {
@@ -305,15 +301,12 @@ Syncer.prototype.syncFromServer = function() {
}
},
triggerNextSync = function() {
if(pollingEnabled) {
self.pollTimerId = setTimeout(function() {
self.pollTimerId = null;
self.syncFromServer.call(self);
},self.pollTimerInterval);
}
self.pollTimerId = setTimeout(function() {
self.pollTimerId = null;
self.syncFromServer.call(self);
},self.pollTimerInterval);
},
syncSystemFromServer = (self.wiki.getTiddlerText("$:/config/SyncSystemTiddlersFromServer") === "yes"),
pollingEnabled = (self.wiki.getTiddlerText(self.titleSyncDisablePolling) !== "yes");
syncSystemFromServer = (self.wiki.getTiddlerText("$:/config/SyncSystemTiddlersFromServer") === "yes" ? true : false);
if(this.syncadaptor && this.syncadaptor.getUpdatedTiddlers) {
this.logger.log("Retrieving updated tiddler list");
cancelNextSync();
@@ -336,7 +329,7 @@ Syncer.prototype.syncFromServer = function() {
});
if(updates.modifications.length > 0 || updates.deletions.length > 0) {
self.processTaskQueue();
}
}
}
});
} else if(this.syncadaptor && this.syncadaptor.getSkinnyTiddlers) {
@@ -479,7 +472,7 @@ Syncer.prototype.handleLogoutEvent = function() {
if(this.syncadaptor.logout) {
this.syncadaptor.logout(function(err) {
if(err) {
self.logger.alert(err);
self.displayError("Logout Error",err);
} else {
self.getStatus();
}
@@ -516,7 +509,7 @@ Syncer.prototype.processTaskQueue = function() {
} else {
self.updateDirtyStatus();
// Process the next task
self.processTaskQueue.call(self);
self.processTaskQueue.call(self);
}
});
} else {
@@ -524,11 +517,11 @@ Syncer.prototype.processTaskQueue = function() {
this.updateDirtyStatus();
// And trigger a timeout if there is a pending task
if(task === true) {
this.triggerTimeout();
this.triggerTimeout();
}
}
} else {
this.updateDirtyStatus();
this.updateDirtyStatus();
}
};
@@ -562,7 +555,7 @@ Syncer.prototype.chooseNextTask = function() {
isReadyToSave = !tiddlerInfo || !tiddlerInfo.timestampLastSaved || tiddlerInfo.timestampLastSaved < thresholdLastSaved;
if(hasChanged) {
if(isReadyToSave) {
return new SaveTiddlerTask(this,title);
return new SaveTiddlerTask(this,title);
} else {
havePending = true;
}

View File

@@ -16,7 +16,7 @@ Browser data transfer utilities, used with the clipboard and drag and drop
Options:
domNode: dom node to make draggable
dragImageType: "pill" or "dom"
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
@@ -73,6 +73,9 @@ exports.makeDraggable = function(options) {
if(dataTransfer.setDragImage) {
if(dragImageType === "pill") {
dataTransfer.setDragImage(dragImage.firstChild,-16,-16);
} else if (dragImageType === "blank") {
dragImage.removeChild(dragImage.firstChild);
dataTransfer.setDragImage(dragImage,0,0);
} else {
var r = domNode.getBoundingClientRect();
dataTransfer.setDragImage(domNode,event.clientX-r.left,event.clientY-r.top);
@@ -164,7 +167,7 @@ var importDataTypes = [
}},
{type: "URL", IECompatible: true, toTiddlerFieldsArray: function(data,fallbackTitle) {
// Check for tiddler data URI
var match = decodeURIComponent(data).match(/^data\:text\/vnd\.tiddler,(.*)/i);
var match = $tw.utils.decodeURIComponentSafe(data).match(/^data\:text\/vnd\.tiddler,(.*)/i);
if(match) {
return parseJSONTiddlers(match[1],fallbackTitle);
} else {
@@ -173,7 +176,7 @@ var importDataTypes = [
}},
{type: "text/x-moz-url", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {
// Check for tiddler data URI
var match = decodeURIComponent(data).match(/^data\:text\/vnd\.tiddler,(.*)/i);
var match = $tw.utils.decodeURIComponentSafe(data).match(/^data\:text\/vnd\.tiddler,(.*)/i);
if(match) {
return parseJSONTiddlers(match[1],fallbackTitle);
} else {

View File

@@ -34,6 +34,23 @@ exports.httpRequest = function(options) {
});
return result;
},
getHeader = function(targetHeader) {
return headers[targetHeader] || headers[targetHeader.toLowerCase()];
},
isSimpleRequest = function(type,headers) {
if(["GET","HEAD","POST"].indexOf(type) === -1) {
return false;
}
for(var header in headers) {
if(["accept","accept-language","content-language","content-type"].indexOf(header.toLowerCase()) === -1) {
return false;
}
}
if(hasHeader("Content-Type") && ["application/x-www-form-urlencoded","multipart/form-data","text/plain"].indexOf(getHeader["Content-Type"]) === -1) {
return false;
}
return true;
},
returnProp = options.returnProp || "responseText",
request = new XMLHttpRequest(),
data = "",
@@ -76,7 +93,7 @@ exports.httpRequest = function(options) {
if(data && !hasHeader("Content-Type")) {
request.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
}
if(!hasHeader("X-Requested-With")) {
if(!hasHeader("X-Requested-With") && !isSimpleRequest(type,headers)) {
request.setRequestHeader("X-Requested-With","TiddlyWiki");
}
try {

View File

@@ -235,7 +235,7 @@ Object.defineProperty(TW_Element.prototype, "innerHTML", {
if(node instanceof TW_Element) {
b.push(node.outerHTML);
} else if(node instanceof TW_TextNode) {
b.push($tw.utils.htmlEncode(node.textContent));
b.push($tw.utils.htmlTextEncode(node.textContent));
}
});
return b.join("");

View File

@@ -95,6 +95,15 @@ LinkedList.prototype.toArray = function() {
return output;
};
LinkedList.prototype.makeTiddlerIterator = function(wiki) {
var self = this;
return function(callback) {
self.each(function(title) {
callback(wiki.getTiddler(title),title);
});
};
};
function _removeOne(list,value) {
var prevEntry = list.prev[value],
nextEntry = list.next[value],

View File

@@ -199,6 +199,8 @@ exports.transliterationPairs = {
"Nj":"N",
"Ñ":"N",
"NJ":"NJ",
"ð":"d",
"Ð":"D",
"Ó":"O",
"Ŏ":"O",
"Ǒ":"O",
@@ -265,6 +267,8 @@ exports.transliterationPairs = {
"Ɽ":"R",
"Ꜿ":"C",
"Ǝ":"E",
"ß":"ss",
"ẞ":"SS",
"Ś":"S",
"Ṥ":"S",
"Š":"S",
@@ -275,6 +279,8 @@ exports.transliterationPairs = {
"Ṡ":"S",
"Ṣ":"S",
"Ṩ":"S",
"þ": "th",
"Þ": "TH",
"Ť":"T",
"Ţ":"T",
"Ṱ":"T",
@@ -907,7 +913,8 @@ exports.transliterationPairs = {
"т":"t",
"ь":"'",
"б":"b",
"ю":"yu"
"ю":"yu",
"…":"..."
};
exports.transliterate = function(str) {

View File

@@ -383,6 +383,15 @@ exports.formatDateString = function(date,template) {
[/^0WW/, function() {
return $tw.utils.pad($tw.utils.getWeek(date));
}],
[/^0ddddd/, function() {
return $tw.utils.pad(Math.floor((date - new Date(date.getFullYear(), 0, 0)) / 1000 / 60 / 60 / 24),3);
}],
[/^ddddd/, function() {
return Math.floor((date - new Date(date.getFullYear(), 0, 0)) / 1000 / 60 / 60 / 24);
}],
[/^dddd/, function() {
return [7,1,2,3,4,5,6][date.getDay()];
}],
[/^ddd/, function() {
return $tw.language.getString("Date/Short/Day/" + date.getDay());
}],
@@ -969,4 +978,22 @@ exports.makeCompareFunction = function(type,options) {
return (types[type] || types[options.defaultType] || types.number);
};
exports.decodeURIComponentSafe = function(str) {
var value = str;
try {
value = decodeURIComponent(str);
} catch(e) {
}
return value;
};
exports.decodeURISafe = function(str) {
var value = str;
try {
value = decodeURI(str);
} catch(e) {
}
return value;
};
})();

View File

@@ -59,7 +59,7 @@ Invoke the action associated with this widget
ConfirmWidget.prototype.invokeAction = function(triggeringWidget,event) {
var invokeActions = true,
handled = true,
win = event.event && event.event.view ? event.event.view : window;
win = event && event.event && event.event.view ? event.event.view : window;
if(this.prompt) {
invokeActions = win.confirm(this.message);
}

View File

@@ -54,6 +54,7 @@ DraggableWidget.prototype.render = function(parent,nextSibling) {
dragFilterFn: function() {return self.getAttribute("filter");},
startActions: self.startActions,
endActions: self.endActions,
dragImageType: self.dragImageType,
widget: this
});
// Insert the link into the DOM and render any children
@@ -71,6 +72,7 @@ DraggableWidget.prototype.execute = function() {
this.draggableClasses = this.getAttribute("class");
this.startActions = this.getAttribute("startactions");
this.endActions = this.getAttribute("endactions");
this.dragImageType = this.getAttribute("dragimagetype");
// Make the child widgets
this.makeChildWidgets();
};

View File

@@ -76,16 +76,22 @@ EventWidget.prototype.render = function(parent,nextSibling) {
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 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 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 {
return false;

View File

@@ -32,13 +32,7 @@ JSONTiddlerWidget.prototype.render = function(parent,nextSibling) {
this.computeAttributes();
this.execute();
// Collect the fields from the optional base tiddler
var fields = {};
if(this.attTiddler) {
var tiddler = this.wiki.getTiddler(this.attTiddler);
if(tiddler) {
fields = tiddler.getFieldStrings({exclude: this.attExclude.split(" ")});
}
}
var fields = this.getTiddlerFields();
// Add custom fields specified in attributes starting with $
$tw.utils.each(this.attributes,function(attribute,name) {
if(name.charAt(0) === "$") {
@@ -79,6 +73,19 @@ JSONTiddlerWidget.prototype.refresh = function(changedTiddlers) {
}
};
JSONTiddlerWidget.prototype.getTiddlerFields = function() {
var fields = {};
if(this.attTiddler) {
var tiddler = this.wiki.getTiddler(this.attTiddler);
if(tiddler) {
fields = tiddler.getFieldStrings({exclude: this.attExclude.split(" ")});
} else {
fields = {title: this.attTiddler};
}
}
return fields;
};
exports.jsontiddler = JSONTiddlerWidget;
})();

View File

@@ -236,6 +236,11 @@ ListWidget.prototype.handleListChanges = function(changedTiddlers) {
hasRefreshed = hasRefreshed || refreshed;
}
}
// If there are items to remove and we have not refreshed then recreate the item that will now be at the last position
if(!hasRefreshed && this.children.length > this.list.length) {
this.removeListItem(this.list.length-1);
this.insertListItem(this.list.length-1,this.list[this.list.length-1]);
}
} else {
// Cycle through the list, inserting and removing list items as needed
for(t=0; t<this.list.length; t++) {

View File

@@ -36,28 +36,38 @@ MessageCatcherWidget.prototype.render = function(parent,nextSibling) {
// Helper to add an event handler
var addEventHandler = function(type,actions) {
if(type && actions) {
var isActionStringExecuting = false;
self.addEventListener(
type,
function(event) {
// Don't trap the event if it came from one of our action handlers
if(isActionStringExecuting) {
return true;
}
// Collect all the event properties into variables
var collectProps = function(obj,prefix) {
prefix = prefix || "";
var props = {};
var props = {},
names = [];
$tw.utils.each(obj,function(value,name) {
if(["string","boolean","number"].indexOf(typeof value) !== -1) {
props[prefix + name] = value.toString();
names.push(name);
props[prefix + "-" + name] = value.toString();
}
});
props["list-" + prefix] = $tw.utils.stringifyList(names);
return props;
};
var variables = $tw.utils.extend(
{},
collectProps(event.paramObject,"event-paramObject-"),
collectProps(event,"event-"),
collectProps(event.paramObject,"event-paramObject"),
collectProps(event,"event"),
{
modifier: $tw.keyboardManager.getEventModifierKeyDescriptor(event)
});
isActionStringExecuting = true;
self.invokeActionString(actions,self,event,variables);
isActionStringExecuting = false;
return false;
}
);

View File

@@ -122,6 +122,7 @@ RadioWidget.prototype.refresh = function(changedTiddlers) {
return true;
} else if(changedTiddlers[this.radioTitle]) {
this.inputDomNode.checked = this.getValue() === this.radioValue;
$tw.utils.toggleClass(this.labelDomNode,"tc-radio-selected",this.inputDomNode.checked);
return this.refreshChildren(changedTiddlers);
} else {
return this.refreshChildren(changedTiddlers);

View File

@@ -226,7 +226,7 @@ RevealWidget.prototype.refresh = function(changedTiddlers) {
this.refreshSelf();
return true;
}
} else if(this.type === "popup" && this.updatePopupPosition && (changedTiddlers[this.state] || changedTiddlers[this.stateTitle])) {
} else if(this.type === "popup" && this.isOpen && this.updatePopupPosition && (changedTiddlers[this.state] || changedTiddlers[this.stateTitle])) {
this.positionPopup(this.domNode);
}
if(changedAttributes.style) {

View File

@@ -365,47 +365,108 @@ Sort an array of tiddler titles by a specified field
*/
exports.sortTiddlers = function(titles,sortField,isDescending,isCaseSensitive,isNumeric,isAlphaNumeric) {
var self = this;
titles.sort(function(a,b) {
var x,y,
compareNumbers = function(x,y) {
var result =
isNaN(x) && !isNaN(y) ? (isDescending ? -1 : 1) :
!isNaN(x) && isNaN(y) ? (isDescending ? 1 : -1) :
(isDescending ? y - x : x - y);
return result;
};
if(sortField !== "title") {
var tiddlerA = self.getTiddler(a),
tiddlerB = self.getTiddler(b);
if(tiddlerA) {
a = tiddlerA.getFieldString(sortField) || "";
if(sortField === "title") {
if(!isNumeric && !isAlphaNumeric) {
if(isCaseSensitive) {
if(isDescending) {
titles.sort(function(a,b) {
return b.localeCompare(a);
});
} else {
titles.sort(function(a,b) {
return a.localeCompare(b);
});
}
} else {
a = "";
if(isDescending) {
titles.sort(function(a,b) {
return b.toLowerCase().localeCompare(a.toLowerCase());
});
} else {
titles.sort(function(a,b) {
return a.toLowerCase().localeCompare(b.toLowerCase());
});
}
}
if(tiddlerB) {
b = tiddlerB.getFieldString(sortField) || "";
} else {
b = "";
}
}
x = Number(a);
y = Number(b);
if(isNumeric && (!isNaN(x) || !isNaN(y))) {
return compareNumbers(x,y);
} else if($tw.utils.isDate(a) && $tw.utils.isDate(b)) {
return isDescending ? b - a : a - b;
} else if(isAlphaNumeric) {
return isDescending ? b.localeCompare(a,undefined,{numeric: true,sensitivity: "base"}) : a.localeCompare(b,undefined,{numeric: true,sensitivity: "base"});
} else {
titles.sort(function(a,b) {
var x,y;
if(isNumeric) {
x = Number(a);
y = Number(b);
if(isNaN(x)) {
if(isNaN(y)) {
// If neither value is a number then fall through to a textual comparison
} else {
return isDescending ? -1 : 1;
}
} else {
if(isNaN(y)) {
return isDescending ? 1 : -1;
} else {
return isDescending ? y - x : x - y;
}
}
}
if(isAlphaNumeric) {
return isDescending ? b.localeCompare(a,undefined,{numeric: true,sensitivity: "base"}) : a.localeCompare(b,undefined,{numeric: true,sensitivity: "base"});
}
if(!isCaseSensitive) {
a = a.toLowerCase();
b = b.toLowerCase();
}
return isDescending ? b.localeCompare(a) : a.localeCompare(b);
});
}
} else {
titles.sort(function(a,b) {
var x,y;
if(sortField !== "title") {
var tiddlerA = self.getTiddler(a),
tiddlerB = self.getTiddler(b);
if(tiddlerA) {
a = tiddlerA.fields[sortField] || "";
} else {
a = "";
}
if(tiddlerB) {
b = tiddlerB.fields[sortField] || "";
} else {
b = "";
}
}
if(isNumeric) {
x = Number(a);
y = Number(b);
if(isNaN(x)) {
if(isNaN(y)) {
// If neither value is a number then fall through to a textual comparison
} else {
return isDescending ? -1 : 1;
}
} else {
if(isNaN(y)) {
return isDescending ? 1 : -1;
} else {
return isDescending ? y - x : x - y;
}
}
}
if(Object.prototype.toString.call(a) === "[object Date]" && Object.prototype.toString.call(b) === "[object Date]") {
return isDescending ? b - a : a - b;
}
a = String(a);
b = String(b);
if(isAlphaNumeric) {
return isDescending ? b.localeCompare(a,undefined,{numeric: true,sensitivity: "base"}) : a.localeCompare(b,undefined,{numeric: true,sensitivity: "base"});
}
if(!isCaseSensitive) {
a = a.toLowerCase();
b = b.toLowerCase();
}
return isDescending ? b.localeCompare(a) : a.localeCompare(b);
}
});
});
}
};
/*
@@ -844,7 +905,7 @@ exports.clearGlobalCache = function() {
exports.getCacheForTiddler = function(title,cacheName,initializer) {
this.caches = this.caches || Object.create(null);
var caches = this.caches[title];
if(caches && caches[cacheName]) {
if(caches && caches[cacheName] !== undefined) {
return caches[cacheName];
} else {
if(!caches) {

View File

@@ -19,71 +19,73 @@ $:/config/Plugins/Disabled/$(currentTiddler)$
\end
\define plugin-table-body(type,disabledMessage,default-popup-state)
\whitespace trim
<div class="tc-plugin-info-chunk tc-plugin-info-toggle">
<$reveal type="nomatch" state=<<popup-state>> text="yes" default="""$default-popup-state$""">
<$button class="tc-btn-invisible tc-btn-dropdown" set=<<popup-state>> setTo="yes">
{{$:/core/images/chevron-right}}
</$button>
</$reveal>
<$reveal type="match" state=<<popup-state>> text="yes" default="""$default-popup-state$""">
<$button class="tc-btn-invisible tc-btn-dropdown" set=<<popup-state>> setTo="no">
{{$:/core/images/chevron-down}}
</$button>
</$reveal>
<$reveal type="nomatch" state=<<popup-state>> text="yes" default="""$default-popup-state$""">
<$button class="tc-btn-invisible tc-btn-dropdown" set=<<popup-state>> setTo="yes">
{{$:/core/images/chevron-right}}
</$button>
</$reveal>
<$reveal type="match" state=<<popup-state>> text="yes" default="""$default-popup-state$""">
<$button class="tc-btn-invisible tc-btn-dropdown" set=<<popup-state>> setTo="no">
{{$:/core/images/chevron-down}}
</$button>
</$reveal>
</div>
<div class="tc-plugin-info-chunk tc-plugin-info-icon">
<$transclude tiddler=<<currentTiddler>> subtiddler=<<plugin-icon-title>>>
<$transclude tiddler="$:/core/images/plugin-generic-$type$"/>
</$transclude>
<$transclude tiddler=<<currentTiddler>> subtiddler=<<plugin-icon-title>>>
<$transclude tiddler="$:/core/images/plugin-generic-$type$"/>
</$transclude>
</div>
<div class="tc-plugin-info-chunk tc-plugin-info-description">
<h1>
''<$text text={{{ [<currentTiddler>get[name]] ~[<currentTiddler>split[/]last[1]] }}}/>'': <$view field="description"><$view field="title"/></$view> $disabledMessage$
</h1>
<h2>
<$view field="title"/>
</h2>
<h2>
<div><em><$view field="version"/></em></div>
</h2>
<h1>
''<$text text={{{ [<currentTiddler>get[name]] ~[<currentTiddler>split[/]last[1]] }}}/>'':&nbsp;<$view field="description"><$view field="title"/></$view>&nbsp;$disabledMessage$
</h1>
<h2>
<$view field="title"/>
</h2>
<h2>
<div><em><$view field="version"/></em></div>
</h2>
</div>
\end
\define plugin-info(type,default-popup-state)
\whitespace trim
<$set name="popup-state" value=<<popup-state-macro>>>
<$reveal type="nomatch" state=<<plugin-disable-title>> text="yes">
<$link to={{!!title}} class="tc-plugin-info">
<<plugin-table-body type:"$type$" default-popup-state:"""$default-popup-state$""">>
</$link>
</$reveal>
<$reveal type="match" state=<<plugin-disable-title>> text="yes">
<$link to={{!!title}} class="tc-plugin-info tc-plugin-info-disabled">
<<plugin-table-body type:"$type$" default-popup-state:"""$default-popup-state$""" disabledMessage:"<$macrocall $name='lingo' title='Disabled/Status'/>">>
</$link>
</$reveal>
<$reveal type="match" text="yes" state=<<popup-state>> default="""$default-popup-state$""">
<div class="tc-plugin-info-dropdown">
<div class="tc-plugin-info-dropdown-body">
<$list filter="[all[current]] -[[$:/core]]">
<div style="float:right;">
<$reveal type="nomatch" state=<<plugin-disable-title>> text="yes">
<$button set=<<plugin-disable-title>> setTo="yes" tooltip={{$:/language/ControlPanel/Plugins/Disable/Hint}} aria-label={{$:/language/ControlPanel/Plugins/Disable/Caption}}>
<<lingo Disable/Caption>>
</$button>
</$reveal>
<$reveal type="match" state=<<plugin-disable-title>> text="yes">
<$button set=<<plugin-disable-title>> setTo="no" tooltip={{$:/language/ControlPanel/Plugins/Enable/Hint}} aria-label={{$:/language/ControlPanel/Plugins/Enable/Caption}}>
<<lingo Enable/Caption>>
</$button>
</$reveal>
</div>
</$list>
<$set name="tabsList" filter="[<currentTiddler>list[]] contents">
<$macrocall $name="tabs" state=<<tabs-state-macro>> tabsList=<<tabsList>> default={{{ [enlist<tabsList>] }}} template="$:/core/ui/PluginInfo"/>
</$set>
</div>
</div>
</$reveal>
<$reveal type="nomatch" state=<<plugin-disable-title>> text="yes">
<$link to={{!!title}} class="tc-plugin-info">
<<plugin-table-body type:"$type$" default-popup-state:"""$default-popup-state$""">>
</$link>
</$reveal>
<$reveal type="match" state=<<plugin-disable-title>> text="yes">
<$link to={{!!title}} class="tc-plugin-info tc-plugin-info-disabled">
<<plugin-table-body type:"$type$" default-popup-state:"""$default-popup-state$""" disabledMessage:"<$macrocall $name='lingo' title='Disabled/Status'/>">>
</$link>
</$reveal>
<$reveal type="match" text="yes" state=<<popup-state>> default="""$default-popup-state$""">
<div class="tc-plugin-info-dropdown">
<div class="tc-plugin-info-dropdown-body">
<$list filter="[all[current]] -[[$:/core]]">
<div style="float:right;">
<$reveal type="nomatch" state=<<plugin-disable-title>> text="yes">
<$button set=<<plugin-disable-title>> setTo="yes" tooltip={{$:/language/ControlPanel/Plugins/Disable/Hint}} aria-label={{$:/language/ControlPanel/Plugins/Disable/Caption}}>
<<lingo Disable/Caption>>
</$button>
</$reveal>
<$reveal type="match" state=<<plugin-disable-title>> text="yes">
<$button set=<<plugin-disable-title>> setTo="no" tooltip={{$:/language/ControlPanel/Plugins/Enable Hint}} aria-label={{$:/language/ControlPanel/Plugins/Enable/Caption}}>
<<lingo Enable/Caption>>
</$button>
</$reveal>
</div>
</$list>
<$set name="tabsList" filter="[<currentTiddler>list[]] contents">
<$macrocall $name="tabs" state=<<tabs-state-macro>> tabsList=<<tabsList>> default={{{ [enlist<tabsList>] }}} template="$:/core/ui/PluginInfo"/>
</$set>
</div>
</div>
</$reveal>
</$set>
\end

View File

@@ -16,4 +16,4 @@ caption: {{$:/language/ControlPanel/Plugins/Caption}}
<<lingo Installed/Hint>>
<$macrocall $name="tabs" tabsList="[[$:/core/ui/ControlPanel/Plugins/Installed/Plugins]] [[$:/core/ui/ControlPanel/Plugins/Installed/Themes]] [[$:/core/ui/ControlPanel/Plugins/Installed/Languages]]" default="$:/core/ui/ControlPanel/Plugins/Installed/Plugins" explicitState="$:/state/tab--86143343"/>
<$macrocall $name="tabs" tabsList="[all[tiddlers+shadows]tag[$:/tags/ControlPanel/Plugins]!has[draft.of]]" default="$:/core/ui/ControlPanel/Plugins/Installed/Plugins" explicitState="$:/state/tab--86143343"/>

View File

@@ -1,4 +1,5 @@
title: $:/core/ui/ControlPanel/Plugins/Installed/Languages
tags: $:/tags/ControlPanel/Plugins
caption: {{$:/language/ControlPanel/Plugins/Languages/Caption}} (<$count filter="[!has[draft.of]plugin-type[language]]"/>)
<<plugin-table language>>

View File

@@ -1,4 +1,5 @@
title: $:/core/ui/ControlPanel/Plugins/Installed/Plugins
tags: $:/tags/ControlPanel/Plugins
caption: {{$:/language/ControlPanel/Plugins/Plugins/Caption}} (<$count filter="[!has[draft.of]plugin-type[plugin]]"/>)
<<plugin-table plugin>>

View File

@@ -1,4 +1,5 @@
title: $:/core/ui/ControlPanel/Plugins/Installed/Themes
tags: $:/tags/ControlPanel/Plugins
caption: {{$:/language/ControlPanel/Plugins/Themes/Caption}} (<$count filter="[!has[draft.of]plugin-type[theme]]"/>)
<<plugin-table theme>>

View File

@@ -0,0 +1,53 @@
title: $:/core/ui/EditorToolbar/StampDropdown/ItemTemplate
<$linkcatcher actions="""
<$list filter="[<modifier>!match[ctrl]]" variable="ignore">
<$list filter="[<currentTiddler>addsuffix[/prefix]!is[tiddler]!is[shadow]removesuffix[/prefix]addsuffix[/suffix]!is[tiddler]!is[shadow]]" variable="ignore">
<$action-sendmessage
$message="tm-edit-text-operation"
$param="replace-selection"
text={{{ [<currentTiddler>get[text]] }}}
/>
</$list>
<$list filter="[<currentTiddler>addsuffix[/prefix]] [<currentTiddler>addsuffix[/suffix]] +[is[shadow]] :else[is[tiddler]] +[limit[1]]" variable="ignore">
<$action-sendmessage
$message="tm-edit-text-operation"
$param="wrap-selection"
prefix={{{ [<currentTiddler>addsuffix[/prefix]get[text]] }}}
suffix={{{ [<currentTiddler>addsuffix[/suffix]get[text]] }}}
/>
</$list>
</$list>
<$list filter="[<modifier>match[ctrl]]" variable="ignore">
<$action-sendmessage $message="tm-edit-tiddler"/>
</$list>
<$action-deletetiddler
$tiddler=<<dropdown-state>>
/>
""">
<$link tooltip={{{ [<currentTiddler>get[description]] }}}>
<$transclude tiddler=<<currentTiddler>> field="caption" mode="inline">
<$view tiddler=<<currentTiddler>> field="title" />
</$transclude>
</$link>
</$linkcatcher>

View File

@@ -1,48 +1,6 @@
title: $:/core/ui/EditorToolbar/stamp-dropdown
\define toolbar-button-stamp-inner()
<$button tag="a">
<$list filter="[[$(snippetTitle)$]addsuffix[/prefix]is[missing]removesuffix[/prefix]addsuffix[/suffix]is[missing]]">
<$action-sendmessage
$message="tm-edit-text-operation"
$param="replace-selection"
text={{$(snippetTitle)$}}
/>
</$list>
<$list filter="[[$(snippetTitle)$]addsuffix[/prefix]is[missing]removesuffix[/prefix]addsuffix[/suffix]!is[missing]] [[$(snippetTitle)$]addsuffix[/prefix]!is[missing]removesuffix[/prefix]addsuffix[/suffix]is[missing]] [[$(snippetTitle)$]addsuffix[/prefix]!is[missing]removesuffix[/prefix]addsuffix[/suffix]!is[missing]]">
<$action-sendmessage
$message="tm-edit-text-operation"
$param="wrap-selection"
prefix={{{ [[$(snippetTitle)$]addsuffix[/prefix]get[text]] }}}
suffix={{{ [[$(snippetTitle)$]addsuffix[/suffix]get[text]] }}}
/>
</$list>
<$action-deletetiddler
$tiddler=<<dropdown-state>>
/>
<$transclude tiddler=<<snippetTitle>> field="caption" mode="inline">
<$view tiddler=<<snippetTitle>> field="title" />
</$transclude>
</$button>
\end
<$list filter="[all[shadows+tiddlers]tag[$:/tags/TextEditor/Snippet]!has[draft.of]sort[caption]]" variable="snippetTitle">
<<toolbar-button-stamp-inner>>
</$list>
<$macrocall $name="list-tagged-draggable" tag="$:/tags/TextEditor/Snippet" subFilter="!is[draft]" itemTemplate="$:/core/ui/EditorToolbar/StampDropdown/ItemTemplate"/>
----

View File

@@ -6,4 +6,5 @@ description: {{$:/language/Buttons/Stamp/Hint}}
condition: [<targetTiddler>type[]] [<targetTiddler>get[type]prefix[text/]] [<targetTiddler>get[type]match[application/javascript]] [<targetTiddler>get[type]match[application/json]] [<targetTiddler>get[type]match[application/x-tiddler-dictionary]] [<targetTiddler>get[type]match[image/svg+xml]] +[first[]]
shortcuts: ((stamp))
dropdown: $:/core/ui/EditorToolbar/stamp-dropdown
button-classes: tc-editortoolbar-stamp-button
text:

View File

@@ -0,0 +1,22 @@
title: $:/core/ui/ExportTiddlyWikiCore
\define jsFileName() tiddlywikicore-$(version)$.js
\define noExportMsg()
It appears that you have a wiki with an external ~TiddlyWiki core. The export action cannot be performed.
<p>You will need to view the page source in your browser. Then go to the very bottom the the source, find the last `<script>`
element, and right-click its `src` URI. Save the link as ''$(jsFileName)$''</p>
\end
''For advanced users''
Export the ~TiddlyWiki core ~JavaScript code for running with external ~JavaScript:
<$button tooltip="Export the ~TiddlyWiki core code for running with external ~JavaScript" aria-label="export TiddlyWiki core" class="tc-btn-big-green">
<$list filter="[[$:/boot/boot.js]is[missing]]" variable="ignore" emptyMessage="""<$action-sendmessage $message="tm-download-file" $param="$:/core/templates/tiddlywiki5.js" filename=<<jsFileName>>/>""" >
<$action-setfield $tiddler=<<qualify "$:/temp/alert">> text=<<noExportMsg>> subtitle="Export ~TiddllyWiki Core"/>
<$action-sendmessage $message="tm-modal" $param=<<qualify "$:/temp/alert">>/>
</$list>
{{$:/core/images/download-button}} Download ~TiddlyWiki core
</$button>
[[Further information|https://tiddlywiki.com/#Using%20the%20external%20JavaScript%20template]]

View File

@@ -1,9 +1,5 @@
title: $:/core/ui/Buttons/export-tiddlywikicore
tags: $:/tags/PageControls
caption: {{$:/core/images/star-filled}} {{$:/language/Buttons/ExportTiddlyWikiCore/Caption}}
description: {{$:/language/Buttons/ExportTiddlyWikiCore/Hint}}
title: $:/core/ui/ExportTiddlyWikiCore
\whitespace trim
\define jsFileName() tiddlywikicore-$(version)$.js
\define noExportMsg()
It appears that you have a wiki with an external ~TiddlyWiki core. The export action cannot be performed.
@@ -11,15 +7,16 @@ It appears that you have a wiki with an external ~TiddlyWiki core. The export ac
element, and right-click its `src` URI. Save the link as ''$(jsFileName)$''</p>
\end
<$button tooltip={{$:/language/Buttons/ExportTiddlyWikiCore/Hint}} aria-label={{$:/language/Buttons/ExportTiddlyWikiCore/Caption}} class=<<tv-config-toolbar-class>>>
''For advanced users''
Export the ~TiddlyWiki core ~JavaScript code for running with external ~JavaScript:
<$button tooltip="Export the ~TiddlyWiki core code for running with external ~JavaScript" aria-label="export TiddlyWiki core" class="tc-btn-big-green">
<$list filter="[[$:/boot/boot.js]is[missing]]" variable="ignore" emptyMessage="""<$action-sendmessage $message="tm-download-file" $param="$:/core/templates/tiddlywiki5.js" filename=<<jsFileName>>/>""" >
<$action-setfield $tiddler=<<qualify "$:/temp/alert">> text=<<noExportMsg>> subtitle="Export ~TiddllyWiki Core"/>
<$action-sendmessage $message="tm-modal" $param=<<qualify "$:/temp/alert">>/>
</$list>
<$list filter="[<tv-config-toolbar-icons>match[yes]]" variable="listItem">
{{$:/core/images/star-filled}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/ExportTiddlyWikiCore/Caption}}/></span>
</$list>
{{$:/core/images/download-button}} Download ~TiddlyWiki core
</$button>
[[Further information|https://tiddlywiki.com/#Using%20the%20external%20JavaScript%20template]]

View File

@@ -1,10 +1,15 @@
title: $:/core/ui/ViewTemplate
\whitespace trim
\define folded-state()
$:/state/folded/$(currentTiddler)$
\end
\define cancel-delete-tiddler-actions(message) <$action-sendmessage $message="tm-$message$-tiddler"/>
\import [all[shadows+tiddlers]tag[$:/tags/Macro/View]!has[draft.of]]
<$vars storyTiddler=<<currentTiddler>> tiddlerInfoState=<<qualify "$:/state/popup/tiddler-info">>><div data-tiddler-title=<<currentTiddler>> data-tags={{!!tags}} class={{{ tc-tiddler-frame tc-tiddler-view-frame [<currentTiddler>is[tiddler]then[tc-tiddler-exists]] [<currentTiddler>is[missing]!is[shadow]then[tc-tiddler-missing]] [<currentTiddler>is[shadow]then[tc-tiddler-exists tc-tiddler-shadow]] [<currentTiddler>is[shadow]is[tiddler]then[tc-tiddler-overridden-shadow]] [<currentTiddler>is[system]then[tc-tiddler-system]] [{!!class}] [<currentTiddler>tags[]encodeuricomponent[]addprefix[tc-tagged-]] +[join[ ]] }}}><$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewTemplate]!has[draft.of]]" variable="listItem"><$transclude tiddler=<<listItem>>/></$list>
<$vars storyTiddler=<<currentTiddler>> tiddlerInfoState=<<qualify "$:/state/popup/tiddler-info">>>
<div data-tiddler-title=<<currentTiddler>> data-tags={{!!tags}} class={{{ tc-tiddler-frame tc-tiddler-view-frame [<currentTiddler>is[tiddler]then[tc-tiddler-exists]] [<currentTiddler>is[missing]!is[shadow]then[tc-tiddler-missing]] [<currentTiddler>is[shadow]then[tc-tiddler-exists tc-tiddler-shadow]] [<currentTiddler>is[shadow]is[tiddler]then[tc-tiddler-overridden-shadow]] [<currentTiddler>is[system]then[tc-tiddler-system]] [{!!class}] [<currentTiddler>tags[]encodeuricomponent[]addprefix[tc-tagged-]] +[join[ ]] }}}>
<$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewTemplate]!has[draft.of]]" variable="listItem">
<$transclude tiddler=<<listItem>>/>
</$list>
</div>
</$vars>

View File

@@ -5,13 +5,10 @@ tags: $:/tags/ViewTemplate
\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"><$set name="tv-config-toolbar-class" filter="[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]"><$transclude tiddler=<<listItem>>/></$set></$reveal></$list>
<$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewToolbar]!has[draft.of]] :filter[lookup[$:/config/ViewToolbarButtons/Visibility/]!match[hide]]" storyview="pop" variable="listItem"><$set name="tv-config-toolbar-class" filter="[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]"><$transclude tiddler=<<listItem>>/></$set></$list>
</span>
<$set name="tv-wikilinks" value={{$:/config/Tiddlers/TitleLinks}}>
<$link>
@@ -43,4 +40,4 @@ $:/config/ViewToolbarButtons/Visibility/$(listItem)$
<$list filter="[all[shadows+tiddlers]tag[$:/tags/TiddlerInfoSegment]!has[draft.of]] [[$:/core/ui/TiddlerInfo]]" variable="listItem"><$transclude tiddler=<<listItem>> mode="block"/></$list>
</$reveal>
</div>
</div>

View File

@@ -1,3 +1,2 @@
title: $:/config/EditTabIndex
1
text: 1

View File

@@ -4,7 +4,6 @@ core/ui/Buttons/advanced-search: hide
core/ui/Buttons/close-all: hide
core/ui/Buttons/encryption: hide
core/ui/Buttons/export-page: hide
core/ui/Buttons/export-tiddlywikicore: hide
core/ui/Buttons/fold-all: hide
core/ui/Buttons/full-screen: hide
core/ui/Buttons/home: hide

View File

@@ -1,8 +1,6 @@
title: $:/config/shortcuts-mac/
bold: meta-B
input-tab-left: ctrl-Left
input-tab-right: ctrl-Right
italic: meta-I
underline: meta-U
new-image: ctrl-I

View File

@@ -18,8 +18,8 @@ input-accept: Enter
input-accept-variant: ctrl-Enter
input-cancel: Escape
input-down: Down
input-tab-left: alt-Left
input-tab-right: alt-Right
input-tab-left: alt-ctrl-Left
input-tab-right: alt-ctrl-Right
input-up: Up
layout-switcher: ctrl-shift-L
link: ctrl-L

View File

@@ -1,2 +1,2 @@
title: $:/tags/ControlPanel/Plugins
list: [[$:/core/ui/ControlPanel/Plugins/Installed]] [[$:/core/ui/ControlPanel/Plugins/Add]]
list: $:/core/ui/ControlPanel/Plugins/Installed/Plugins $:/core/ui/ControlPanel/Plugins/Installed/Themes $:/core/ui/ControlPanel/Plugins/Installed/Languages

View File

@@ -1,2 +1,2 @@
title: $:/tags/PageControls
list: [[$:/core/ui/Buttons/home]] [[$:/core/ui/Buttons/close-all]] [[$:/core/ui/Buttons/fold-all]] [[$:/core/ui/Buttons/unfold-all]] [[$:/core/ui/Buttons/permaview]] [[$:/core/ui/Buttons/new-tiddler]] [[$:/core/ui/Buttons/new-journal]] [[$:/core/ui/Buttons/new-image]] [[$:/core/ui/Buttons/import]] [[$:/core/ui/Buttons/export-page]] [[$:/core/ui/Buttons/control-panel]] [[$:/core/ui/Buttons/advanced-search]] [[$:/core/ui/Buttons/manager]] [[$:/core/ui/Buttons/tag-manager]] [[$:/core/ui/Buttons/language]] [[$:/core/ui/Buttons/palette]] [[$:/core/ui/Buttons/theme]] [[$:/core/ui/Buttons/storyview]] [[$:/core/ui/Buttons/encryption]] [[$:/core/ui/Buttons/timestamp]] [[$:/core/ui/Buttons/full-screen]] [[$:/core/ui/Buttons/print]] [[$:/core/ui/Buttons/save-wiki]] [[$:/core/ui/Buttons/refresh]] [[$:/core/ui/Buttons/export-tiddlywikicore]] [[$:/core/ui/Buttons/more-page-actions]]
list: [[$:/core/ui/Buttons/home]] [[$:/core/ui/Buttons/close-all]] [[$:/core/ui/Buttons/fold-all]] [[$:/core/ui/Buttons/unfold-all]] [[$:/core/ui/Buttons/permaview]] [[$:/core/ui/Buttons/new-tiddler]] [[$:/core/ui/Buttons/new-journal]] [[$:/core/ui/Buttons/new-image]] [[$:/core/ui/Buttons/import]] [[$:/core/ui/Buttons/export-page]] [[$:/core/ui/Buttons/control-panel]] [[$:/core/ui/Buttons/advanced-search]] [[$:/core/ui/Buttons/manager]] [[$:/core/ui/Buttons/tag-manager]] [[$:/core/ui/Buttons/language]] [[$:/core/ui/Buttons/palette]] [[$:/core/ui/Buttons/theme]] [[$:/core/ui/Buttons/storyview]] [[$:/core/ui/Buttons/encryption]] [[$:/core/ui/Buttons/timestamp]] [[$:/core/ui/Buttons/full-screen]] [[$:/core/ui/Buttons/print]] [[$:/core/ui/Buttons/save-wiki]] [[$:/core/ui/Buttons/refresh]] [[$:/core/ui/Buttons/more-page-actions]]

View File

@@ -14,6 +14,7 @@ Welcome to the developer documentation for TiddlyWiki (https://tiddlywiki.com/).
** HookMechanism
** [[Using ES2016 for Writing Plugins]]
** [[Adding Babel Polyfill to TiddlyWiki]]
** [[TiddlyWiki Drag and Drop Interoperability]]
* The original developer documentation from https://tiddlywiki.com:
** [[TiddlyWiki for Developers]]
** [[TiddlyWiki Coding Style Guidelines]]

View File

@@ -37,8 +37,6 @@ Example:
</div>
```
!!! With encryption
If the ~TiddlyWiki is configured to encrypt its content, the tiddlers are stored as as an encrypted JSON string in a `<pre>` tag with the `id` attribute "encryptedStoreArea".
@@ -83,15 +81,20 @@ Any tiddlers in the older format `<div>` store area are also loaded before tiddl
Tiddlers from the new `<script>` tag store areas are loaded in the order of their store areas in the HTML file. Therefore if the same tiddler exists in two different `<script>` tag store areas, the tiddler from the later store area takes precedence. Note however that tiddlers from `<script>` tag store areas always take precedence over tiddlers from the older format `<div>` store area. Therefore a tiddler from the older `<div>` store area can never overwrite a tiddler from a `<script>` tag store area.
Note that all `<script>` tags with the `class` attribute "tiddlywiki-tiddler-store" have their content parsed as JSON and loaded as tiddlers. This allows external tools to easily insert tiddlers into an HTML file by appending additional `<script>` tag(s) at the very end of the HTML file:
Note that all `<script>` tags with the `class` attribute "tiddlywiki-tiddler-store" that precede the `$:/boot.js` module in the HTML file will have their content parsed as JSON and loaded as tiddlers.
This allows external tools to easily insert tiddlers into an HTML file by prepending an additional `<script>` tag(s) at the very start of the HTML file:
```html
</html>
<script class="tiddlywiki-tiddler-store" type="application/json">[
{"created":"20210525212411223","text":"This is some test text","tags":"[[test tag]] [[another tag]]","title":"My new tiddler to insert","modified":"20210525212430577"}
]</script>
<!doctype html>
...
```
Although invalid HTML, all known browsers will silently move the script tag to a valid position within the
Additional topics:
* [[Extracting tiddlers from a single file TiddlyWiki]]

View File

@@ -0,0 +1,15 @@
title: TiddlyWiki Drag and Drop Interoperability
It is straightforward to allow any HTML file to interoperate with TiddlyWiki's drag and drop implementation.
This example shows how to attach draggable data to a DOM element. The data is provided in two different forms:
* the string data is used if the element is dragged onto a text editing area
* the tiddler data is used if the element is dragged into TiddlyWiki's import area
<$button>
<$action-sendmessage $message="tm-download-file" $param="$:/dev/save/dragndropinterop" filename="index.html"/>
Download this sample code
</$button>
<$codeblock code={{DragAndDropInterop}} language="text/html"/>

View File

@@ -0,0 +1,35 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Drag and Drop Interoperability with TiddlyWiki Demo</title>
<style>
#draggable {
padding: 1em;
margin: 1em;
background: #ecc;
}
</style>
</head>
<body>
<div id="draggable" draggable="true">
Drag me to a TiddlyWiki window
</div>
</body>
<script>
var titleString = "This is the string that appears when the block is dragged to a text input";
var tiddlerData = [
{title: "Tiddler One", text: "This is one of the payload tiddlers"},
{title: "Tiddler Two", text: "This is another of the payload tiddlers", "custom-field": "A custom field value"}
];
document.getElementById("draggable").addEventListener("dragstart",function(event) {
event.dataTransfer.setData("URL","data:text/vnd.tiddler," + encodeURIComponent(JSON.stringify(tiddlerData)));
event.dataTransfer.setData("Text",titleString);
event.stopPropagation();
return false;
});
</script>
</html>

View File

@@ -0,0 +1,3 @@
title: DragAndDropInterop
type: text/html

View File

@@ -0,0 +1,3 @@
title: $:/dev/save/dragndropinterop
<$view tiddler="DragAndDropInterop" field="text"/>

View File

@@ -1,15 +1,13 @@
title: $:/core/ui/ViewTemplate
\whitespace trim
\define frame-classes()
tc-tiddler-frame tc-tiddler-view-frame $(missingTiddlerClass)$ $(shadowTiddlerClass)$ $(systemTiddlerClass)$ $(tiddlerTagClasses)$ $(userClass)$
\end
\define folded-state()
$:/state/folded/$(currentTiddler)$
\end
<$vars storyTiddler=<<currentTiddler>> tiddlerInfoState=<<qualify "$:/state/popup/tiddler-info">> userClass={{!!class}}>
<$tiddler tiddler=<<currentTiddler>>>
<div data-tiddler-title=<<currentTiddler>> data-tags={{!!tags}} class=<<frame-classes>>>
\define cancel-delete-tiddler-actions(message) <$action-sendmessage $message="tm-$message$-tiddler"/>
\import [all[shadows+tiddlers]tag[$:/tags/Macro/View]!has[draft.of]]
<$vars storyTiddler=<<currentTiddler>> tiddlerInfoState=<<qualify "$:/state/popup/tiddler-info">>>
<div data-tiddler-title=<<currentTiddler>> data-tags={{!!tags}} class={{{ tc-tiddler-frame tc-tiddler-view-frame [<currentTiddler>is[tiddler]then[tc-tiddler-exists]] [<currentTiddler>is[missing]!is[shadow]then[tc-tiddler-missing]] [<currentTiddler>is[shadow]then[tc-tiddler-exists tc-tiddler-shadow]] [<currentTiddler>is[shadow]is[tiddler]then[tc-tiddler-overridden-shadow]] [<currentTiddler>is[system]then[tc-tiddler-system]] [{!!class}] [<currentTiddler>tags[]encodeuricomponent[]addprefix[tc-tagged-]] +[join[ ]] }}}>
<$set name="state" value={{{ [[$:/state/viewtemplate/visibility/]addsuffix<currentTiddler>] }}}>
<$reveal stateTitle=<<state>> type="nomatch" text="" default="" tag="div">
<div class="tc-dynaview-track-tiddler-when-visible" data-dynaview-track-tiddler=<<state>>>
@@ -24,5 +22,4 @@ $:/state/folded/$(currentTiddler)$
</$reveal>
</$set>
</div>
</$tiddler>
</$vars>

View File

@@ -54,7 +54,7 @@ title="New tiddler"
#* Asígnale la etiqueta <<.tag ~$:/tags/ViewToolbar]]>>
# Hay que crear un tiddler que le diga a ~TiddlyWIki si el botón será o no visible en la barra. Llamémosle por ejemplo <<.tid "~$:/config/ViewToolbarButtons/Visibility/Receta"">>. Escribe `reveal` en el cuerpo y guárdalo.
# Hay que crear un tiddler que le diga a ~TiddlyWIki si el botón será o no visible en la barra. Llamémosle por ejemplo <<.tid "~$:/config/ViewToolbarButtons/Visibility/Receta"">>. Escribe `show` en el cuerpo y guárdalo.
# Habrá que posicionar el botón adecuadamente. Abre el tiddler <<.tid ~$:/tags/ViewToolbar>> e inserta el nombre de tu botón en el lugar adecuado del campo <<.field list>>.

View File

@@ -25,7 +25,7 @@ Imaginons que vous ayez un tiddler squelette appelé 'Modèle Recette', et que v
# Pour illustrer votre bouton, si aucune des images du noyau (tiddlers shadow préfixés par $:/core/images/ ) n'est à votre convenance, vous devrez la créer ou en obtenir une au format SVG (par exemple, une de celles de http://flaticon.com), glissez-la dans votre fichier pour la transformer en tiddler, modifiez le tiddler et ajustez sa hauteur et sa largeur à 22px
#Passons au tiddler contenant votre tiddler. Créez-le, titrez-le et ajoutez le code du bouton (voir le code ci-dessous par exemple, en l'adaptant à vos besoins si nécessaire) Étiquetez-le par [[$:/tags/ViewToolbar]]
#Contrôlons la visibilité de votre tiddler dans la barre d'outil par la création d'un tiddler à titrer [[$:/config/ViewToolbarButtons/Visibility/Recette]]. Saisissez `reveal`dans la zone texte et sauvegardez.
#Contrôlons la visibilité de votre tiddler dans la barre d'outil par la création d'un tiddler à titrer [[$:/config/ViewToolbarButtons/Visibility/Recette]]. Saisissez `show`dans la zone texte et sauvegardez.
#Enfin, positionnons le bouton proprement. Ouvrez le tiddler $:/tags/ViewToolbar et insérez le titre de votre tiddler bouton (cf. titre étape précédente) dans le champ field au bon endroit.
```

View File

@@ -1,7 +1,8 @@
{
"description": "Innerwiki Plugin Demo",
"plugins": [
"tiddlywiki/innerwiki"
"tiddlywiki/innerwiki",
"tiddlywiki/railroad"
],
"themes": [
"tiddlywiki/vanilla",

View File

@@ -7,7 +7,7 @@ title: TiddlyWiki
<$scrollable class="tc-cecily-demo">
<div class="tc-cecily-demo-inner">
<$linkcatcher>
<$list filter="[list[$:/StoryList]] -[[TiddlyWiki]]" template="$:/core/ui/ViewTemplate" storyview="cecily" cecily-width="550px" cecily-map="CecilyMap"/>
<$list filter="[{$:/DefaultTiddlers}enlist-input[]] -[[ ]] -[[TiddlyWiki]]" template="$:/core/ui/ViewTemplate" storyview="cecily" cecily-width="550px" cecily-map="CecilyMap"/>
</$linkcatcher>
</div>
</$scrollable>

View File

@@ -16,10 +16,12 @@
"tiddlywiki/readonly"
],
"languages": [
"ar-PS",
"ca-ES",
"cs-CZ",
"da-DK",
"de-AT",
"de-CH",
"de-DE",
"el-GR",
"en-GB",
@@ -27,6 +29,7 @@
"es-ES",
"fa-IR",
"fr-FR",
"he-IL",
"hi-IN",
"ia-IA",
"it-IT",
@@ -34,12 +37,16 @@
"ko-KR",
"nl-NL",
"pa-IN",
"pt-BR",
"pt-PT",
"ru-RU",
"sk-SK",
"sv-SE",
"zh-CN",
"zh-Hans",
"zh-Hant"
"zh-Hant",
"zh-HK",
"zh-TW"
],
"build": {
"index": [

View File

@@ -0,0 +1,62 @@
caption: 5.2.1
created: 20211003152250369
modified: 20211003152250369
tags: ReleaseNotes
title: Release 5.2.1
type: text/vnd.tiddlywiki
\define contributor(username)
<a href="https://github.com/$username$" style="text-decoration:none;font-size:24px;" class="tc-tiddlylink-external" target="_blank" rel="noopener noreferrer"><img src="https://github.com/$username$.png?size=32" width="32" height="32"/> @<$text text=<<__username__>>/></a>
\end
//[[See GitHub for detailed change history of this release|https://github.com/Jermolene/TiddlyWiki5/compare/v5.2.0...master]]//
! Highlights
! Performance Improvements
*
! Usability Improvements
*
! Widget Improvements
*
! Filter improvements
*
! Hackability Improvements
*
! Client-server Improvements
*
! Node.js Improvements
*
! Plugin Improvements
! Developer Experience Improvements
*
! Translation improvements
*
! Other Bug Fixes
*
! 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>>

View File

@@ -1,6 +1,6 @@
title: $:/config/LocalPluginLibrary
tags: $:/tags/PluginLibrary
url: http://127.0.0.1:8080/prerelease/library/v5.1.23/index.html
url: http://127.0.0.1:8080/prerelease/library/v5.2.1/index.html
caption: {{$:/language/OfficialPluginLibrary}} (Prerelease Local)
A locally installed version of the official ~TiddlyWiki plugin library at tiddlywiki.com for testing and debugging. //Requires a local web server to share the library//

View File

@@ -1,6 +1,6 @@
title: $:/config/OfficialPluginLibrary
tags: $:/tags/PluginLibrary
url: https://tiddlywiki.com/prerelease/library/v5.2.0/index.html
url: https://tiddlywiki.com/prerelease/library/v5.2.1/index.html
caption: {{$:/language/OfficialPluginLibrary}} (Prerelease)
The prerelease version of the official ~TiddlyWiki plugin library at tiddlywiki.com. Plugins, themes and language packs are maintained by the core team.

File diff suppressed because it is too large Load Diff

View File

@@ -465,6 +465,31 @@ describe("Widget module", function() {
expect(wrapper.children[0].children[13].sequenceNumber).toBe(43);
expect(wrapper.children[0].children[14].sequenceNumber).toBe(44);
expect(wrapper.children[0].children[15].sequenceNumber).toBe(45);
//Remove last tiddler
wiki.deleteTiddler("TiddlerTwo");
//Refresh
refreshWidgetNode(widgetNode,wrapper,["TiddlerTwo"]);
//Test the refreshing
expect(wrapper.innerHTML).toBe("<p>Jalapeno Peppers1yesnoLemon Squash2nonoJolly Old World3nonoSomething4noyes</p>");
// Test the sequence numbers in the DOM
expect(wrapper.sequenceNumber).toBe(0);
expect(wrapper.children[0].sequenceNumber).toBe(1);
expect(wrapper.children[0].children[0].sequenceNumber).toBe(18);
expect(wrapper.children[0].children[1].sequenceNumber).toBe(19);
expect(wrapper.children[0].children[2].sequenceNumber).toBe(20);
expect(wrapper.children[0].children[3].sequenceNumber).toBe(21);
expect(wrapper.children[0].children[4].sequenceNumber).toBe(22);
expect(wrapper.children[0].children[5].sequenceNumber).toBe(23);
expect(wrapper.children[0].children[6].sequenceNumber).toBe(24);
expect(wrapper.children[0].children[7].sequenceNumber).toBe(25);
expect(wrapper.children[0].children[8].sequenceNumber).toBe(26);
expect(wrapper.children[0].children[9].sequenceNumber).toBe(27);
expect(wrapper.children[0].children[10].sequenceNumber).toBe(28);
expect(wrapper.children[0].children[11].sequenceNumber).toBe(29);
expect(wrapper.children[0].children[12].sequenceNumber).toBe(50);
expect(wrapper.children[0].children[13].sequenceNumber).toBe(51);
expect(wrapper.children[0].children[14].sequenceNumber).toBe(52);
expect(wrapper.children[0].children[15].sequenceNumber).toBe(53);
});
it("should deal with the list widget followed by other widgets", function() {

View File

@@ -1,4 +0,0 @@
created: 20210525102327864
modified: 20210525102327884
title: $:/key-test
type: text/vnd.tiddlywiki

View File

@@ -1,11 +0,0 @@
created: 20210525102659716
modified: 20210525102701077
title: $:/key-test/action
type: text/vnd.tiddlywiki
<$vars tv-wikilinks="no">
* event-key:
* event-code:
* modifier:
</$vars>

View File

@@ -1,66 +0,0 @@
created: 20210427092418146
modified: 20210525130708186
tags: KeyboardWidget
title: Key Codes (Example 1)
type: text/vnd.tiddlywiki
\define key-test() $:/key-test
\import [[Keyboard Codes (Macros)]]
\define keys()
backspace tab clear return enter pause escape space
page_up page_down end home printscreen insert delete
left up right down results in: ArrowLeft ArrowUp ArrowRight ArrowDown
0 1 2 3
shift+0 shift+1 shift+2 shift+3 results in: = ! " with modifierKey: shift
ctrl+0 ctrl+1 ctrl+2 ctrl+3
alt+0 alt+1 alt+2 alt+3
ctrl+alt+0 ctrl+alt+1 ctrl+alt+2 ctrl+alt+3
alt+shift+0 alt+shift+1 alt+shift+2 alt+shift+3
ctrl+shift+0 ctrl+shift+1 ctrl+shift+2 ctrl+shift+3 INFO: ctrl-shift-0 is eaten by windows!!
ctrl+alt+shift+0 ctrl+alt+shift+1 ctrl+alt+shift+2 ctrl+alt+shift+3
a s d
shift+a shift+s shift+d
ctrl+a ctrl+s ctrl+d
alt+a alt+s alt+d
ctrl+shift+a ctrl+shift+s ctrl+shift+d
alt+shift+a alt+shift+s alt+shift+d
ctrl+alt+a ctrl+alt+s ctrl+alt+d
ctrl+alt+shift+a ctrl+alt+shift+s ctrl+alt+shift+d
numpad0 numpad1 numpad2 numpad3
multiply add separator subtract decimal divide
f1 f2 f3
semicolon equals comma dash period slash backquote openbracket backslash closebracket quote
\end
! Key Codes
{{$:/key-test/action}}
! Input Area
Depending on your OS and browser keyboard settings, some combinations may be "eaten" by the OS, or the browser!
--> <$keyboard key={{{ [enlist<keys>join[ ]] }}} actions=<<actionKey>> >
<$edit-text tiddler=<<key-test>> placeholder="- Click here. Try keys from list below -" tag=input focus />
</$keyboard> <--
!! Keys to be used
<pre><code><$vars tv-wikilinks="no"><<keys>></$vars></code></pre>
All possible keys can be found at: [[Keyboard Codes]]
! Example Code
<<showCode>>

View File

@@ -1,43 +0,0 @@
created: 20210427130002905
modified: 20210525130748774
tags: KeyboardWidget
title: Key Codes (Example)
type: text/vnd.tiddlywiki
\define key-test() $:/key-test
\import [[Keyboard Codes (Macros)]]
\define keys()
1 2 3
shift+1 shift+2 shift+3
a s d
f1 f2 f3
\end
! Key Codes
{{$:/key-test/action}}
! Input Area
Depending on your OS and browser keyboard settings, some combinations may be "eaten" by the OS, or the browser
--> <$keyboard key={{{ [enlist<keys>join[ ]] }}} actions=<<actionKey>> >
<$edit-text tiddler=<<key-test>> placeholder="- Click here to try keys -" tag=input />
</$keyboard> <--
!! Keys to be tested
<$list filter="[enlist<keys>]"><kbd><<currentTiddler>></kbd>, </$list>
-----
All usable keys can be found at: [[Keyboard Codes]]
A more advanced example can be found at: [[Key Codes (Example 1)]]
! Code
<<showCode>>

View File

@@ -1,50 +0,0 @@
created: 20210429084127864
modified: 20210525130830934
tags:
title: Keyboard Codes (Macros)
type: text/vnd.tiddlywiki
\define key-test-prefix() $:/key-test
\define codeState() $:/state/code/$(currentTiddler)$
\define getText()
<$vars tv-wikilinks="no">
* event-key: ''$(event-key)$''
* event-code: ''$(event-code)$''
* modifier: ''$(modifier)$''
</$vars>
\end
\define pinDetails()
<$action-setfield $tiddler=<<codeState>> text="open"/>
\end
\define unpinDetails()
<$action-deletetiddler $tiddler=<<codeState>> />
\end
\define toggleDetails(text)
<$list filter="[<codeState>!has[title]]" variable="ignore">
<$button class="tc-btn-invisible" actions=<<pinDetails>> >$text$ {{$:/core/images/unfold-button}}</$button>
</$list>
<$list filter="[<codeState>has[title]]" variable="ignore">
<$button class="tc-btn-invisible" actions=<<unpinDetails>> >$text$ {{$:/core/images/fold-button}}</$button>
</$list>
\end
\define actionKey()
<$action-setfield $tiddler="$:/key-test/action" text=<<getText>> />
\end
\define showCode()
''<<toggleDetails """Toggle this tiddler code""">>''
<$list filter="[<codeState>has[title]]" variable=ignore>
<pre><code><$view /></code></pre>
</$list>
\end
<pre><code><$view /></code></pre>

View File

@@ -4,7 +4,7 @@ tags: KeyboardWidget
title: Keyboard Codes
type: text/vnd.tiddlywiki
! All Key Codes known by the KeyboardWidget
This is a list of all the key codes supported by the KeyboardWidget:
<kbd>cancel</kbd>, <kbd>help</kbd>, <kbd>backspace</kbd>, <kbd>tab</kbd>, <kbd>clear</kbd>, <kbd>return</kbd>, <kbd>enter</kbd>, <kbd>pause</kbd>, <kbd>escape</kbd>, <kbd>space</kbd>,
<kbd>page_up</kbd>, <kbd>page_down</kbd>, <kbd>end</kbd>, <kbd>home</kbd>, <kbd>left</kbd>, <kbd>up</kbd>, <kbd>right</kbd>, <kbd>down</kbd>, <kbd>printscreen</kbd>, <kbd>insert</kbd>, <kbd>delete</kbd>
@@ -25,7 +25,3 @@ type: text/vnd.tiddlywiki
<kbd>semicolon</kbd>, <kbd>equals</kbd>, <kbd>comma</kbd>, <kbd>dash</kbd>, <kbd>period</kbd>, <kbd>slash</kbd>, <kbd>backquote</kbd>, <kbd>openbracket</kbd>, <kbd>backslash</kbd>, <kbd>closebracket</kbd>, <kbd>quote</kbd>
<kbd>shift</kbd>, <kbd>ctrl</kbd>, <kbd>alt</kbd>, <kbd>meta</kbd>
! Examples
<<list-links "[tag[KeyboardWidget]prefix[Key Codes (Example]]">>

View File

@@ -0,0 +1,16 @@
created: 20210519110226889
modified: 20210519110226889
tags: [[Other Resources]]
title: "Grok TiddlyWiki" by Soren Bjornstad
type: text/vnd.tiddlywiki
url: https://groktiddlywiki.com/read/
This new textbook from Soren Bjornstad is highly recommended for learning ~TiddlyWiki. The presentation and design are also a first class example of using ~TiddlyWiki.
From the site:
> Grok ~TiddlyWiki is a textbook that helps you build a deep, lasting understanding of and proficiency with ~TiddlyWiki through a combination of detailed explanations, practical exercises, and spaced-repetition reviews of prompts called takeaways.
{{!!url}}

View File

@@ -1,4 +1,4 @@
caption: ~TW5-firebase
caption: TW5-firebase
color: #FFEB3B
community-author: Peter Neumark
created: 20210115121027582

View File

@@ -1,11 +1,22 @@
title: ShadowTiddlers
tags: Concepts
modified: 201308091623
\define actions()
<$action-setfield $tiddler="$:/state/tab/moresidebar-1850697562" $field="text" $value="$:/core/ui/MoreSideBar/Shadows"/>
<$action-setfield $tiddler="$:/state/tab/sidebar--595412856" $field="text" $value="$:/core/ui/SideBar/More"/>
\end
\define click(text)
<$button actions=<<actions>>>$text$</$button>
\end
ShadowTiddlers are tiddlers that are loaded from within [[Plugins]]. Unlike ordinary tiddlers, they don't appear in most lists.
ShadowTiddlers can be overridden with an ordinary tiddler of the same name. If that tiddler is subsequently deleted then the original shadow tiddler is automatically restored.
The current shadow tiddlers are:
!! Overridden Shadow Tiddlers
<$list filter="[all[shadows]sort[title]]"/>
<<list-links "[is[tiddler]is[shadow]sort[title]]">>
!! Shadow Tiddlers
A full list of shadow tiddlers can be found in the sidebar in the "More" -> "Shadows" tab

View File

@@ -26,7 +26,7 @@ Let's say you have a skeleton tiddler called 'Recipe template', and you want to
# You will want an image for your button. If none of the core images (shadow tiddlers with the prefix $:/core/images/) work for you, then you will need to create or acquire an SVG image (for example, one of the images at http://flaticon.com), drag it into your file so that it becomes a tiddler, edit the tiddler and adjust the height and width to 22px
# You will want to create the tiddler that contains your tiddler. Create it, title it, and add the button code (see the code at the bottom of this tiddler for an example, with hints where you will need to adapt it). Tag it [[$:/tags/ViewToolbar]]
# You will need to create a tiddler that tells TiddlyWiki whether your button should be visible in the toolbar or hidden. Let's title it [[$:/config/ViewToolbarButtons/Visibility/Recipe]]. Type `reveal` into the text area, and save.
# You will need to create a tiddler that tells TiddlyWiki whether your button should be visible in the toolbar or hidden. Let's title it [[$:/config/ViewToolbarButtons/Visibility/Recipe]]. Type `show` into the text area, and save. If you want to hide it, type `hide` into the text area and save. The button will also be accessable from the ''ControlPanel : Appearance : Toolbars : ViewToolbar'' tab
# You will want to position the button properly. Open the tiddler $:/tags/ViewToolbar and insert your button tiddler's title in the appropriate place in the list field.
```

View File

@@ -0,0 +1,121 @@
created: 20210222140234737
modified: 20210520174049056
tags: Learning
title: Demonstration: keyboard-driven-input Macro
type: text/vnd.tiddlywiki
\define allshortcuts(descriptor)
<$wikify name=scutlist text=<<displayshortcuts (($descriptor$)) '' ' ' ''>> >
<$list filter="[<scutlist>split[ ]join[</kbd> or <kbd>]addprefix[<kbd>]addsuffix[</kbd>]]" variable=scts><<scts>></$list>
</$wikify>
\end
\define kdi-demo-textmacrocall()
```
<$macrocall $name=keyboard-driven-input
tiddler="$(tiddler)$"
storeTitle="$(storeTitle)$"
selectionStateTitle="$(selectionStateTitle)$"
configTiddlerFilter="$(configTiddlerFilter)$"
/>
```
\end
<$vars configTiddlerFilter="[[kdi-demo-configtid]]" tiddler="kdi-demo-tiddler" storeTitle="kdi-demo-storeTitle" selectionStateTitle="kdi-demo-selectionStateTitle" >
The [[keyboard-driven-input Macro]] is used to create filtered lists that update as the user types. It also allows navigating the lists, and invoking macros using list items, with the keyboard.
It consists of an ''[[edit-text widget|EditTextWidget]]'' wrapped in [[keyboard widgets|KeyboardWidget]]. There are <<.def keyboard>> widgets to listen for `((input-accept))`, `((input-accept-variant))`, and `((input-cancel))` keyboard shortcuts, but there is no default behaviour in response to these events; macros must be written to suit the use-case. There is also no default visualisation of the filtered options list.
!!Types of keyboard input handled by the <<.var keyboard-driven-input>> macro:
!!!Non-configurable:
The following keyboard events invoke macros defined alongside <<.var keyboard-driven-input>> in [[$:/core/macros/keyboard-driven-input]].
|Input |Purpose |Macro |h
|typing input |composing a string to be used within list filters |<<.var keyboard-input-actions>> |
|`((input-up))` (<<allshortcuts input-up>>) |temporarily selecting the previous item in the filtered list |<<.var input-next-actions>> with parameters <<.param afterOrBefore>>=`"before"`, <<.param reverse>>=`"reverse[]"` |
|`((input-down))` (<<allshortcuts input-down>>) |temporarily selecting the next item in the filtered list |<<.var input-next-actions>> with <<.param afterOrBefore>>=`"after"`, <<.param reverse>>=`""` |
All of the above actions generate or modify data which <<.var keyboard-driven-input>> keeps in tiddlers specified using the macro's parameters. The data can then be accessed not only by the macros invoked by keyboard shortcuts, but also outside of these, e.g. a macro to display the filtered list(s).
!!!Configurable through parameters:
The following keyboard events invoke macros whose names are specified in parameters to <<.var keyboard-driven-input>>. The intended purpose is suggested by the parameter name, but there are no default macros defined within [[$:/core/macros/keyboard-driven-input]].
|[[Keyboard shortcut descriptor |Keyboard Shortcut Descriptor]] |Key combination |Parameter |h
|`((input-accept))` |<<allshortcuts input-accept>> |<<.param inputAcceptActions>> |
|`((input-accept-variant))` |<<allshortcuts input-accept-variant>> |<<.param inputAcceptVariantActions>> |
|`((input-cancel))` |<<allshortcuts input-cancel>> |<<.param inputCancelActions>> |
<<.var keyboard-driven-input>> can be seen in action as part of various core features in TiddlyWiki, e.g.: the [[search feature|Searching in TiddlyWiki]], the [[tag-picker Macro]], and dropdown interfaces in the [[Editor toolbar]] such as [[Insert link]].
!!Minimal ingredients for a demonstration
Keeping in mind that the <<.var keyboard-driven-input>> macro does not, by itself, display list results, or do anything with a selected option, a minimal demonstration of the <<.var keyboard-driven-input>> macro requires:
# ''a tiddler, containing a filter'' whose results depend on the user's text input, to generate the options from which the user can select
# ''several parameters:''
#*''a filter'' to return the title of the tiddler where the filter described in step 1 can be found, and
#*''tiddler titles'' to use for storing state information in response to input events. These tiddlers do not need to exist already. If they do exist, the <<.var keyboard-driven-input>> macro will change their contents.
!!The search filter(s)
By default, <<.var keyboard-driven-input>> will look for filters in the <<.field first-search-filter>> and <<.field second-search-filter>> fields of a tiddler (whose title is specified by a parameter discussed below).
This filter can refer to a variable called <<.var userInput>>, which shows the contents of the <<.def edit-text>> widget, as stored in a state tiddler (discussed below), at the time of the latest <kbd><<displayshortcuts ((input-up))>></kbd> or <kbd><<displayshortcuts ((input-down))>></kbd> event.
''Note:'' If this filter is to be referred to in a context outside the <<.var keyboard-driven-input>> macro (such as in a popup showing the filtered options), the variable <<.var userInput>> has to be defined in those contexts as well (by reading it from a state tiddler).
!!Minimal parameters
|Parameter name |Notes |h
|<<.param configTiddlerFilter>> |This is a filter, rather than a tiddler title, allowing conditional behaviour (e.g. checking for an active tab, or preferring a filter that may not be present, with a fallback).<br>The title returned must belong to an existing tiddler, containing at least one filter with which <<.var keyboard-driven-input>> can generate its results list. |
|<<.param tiddler>> |This tiddler contains either the typed input, or the instantaneous result selection, depending upon the most recent event. It is updated with each keystroke in the ''edit-text'' widget, //and// when the user uses the <kbd><<displayshortcuts ((input-up))>></kbd> or <kbd><<displayshortcuts ((input-down))>></kbd> key to cycle through filtered results. |
|<<.param storeTitle>> |This tiddler always reflects the user input (transcluded from the tiddler <<.param tiddler>> after each keystroke into the ''edit-text'' widget). |
|<<.param selectionStateTitle>> |This tiddler is updated on <kbd><<displayshortcuts ((input-up))>></kbd> or <kbd><<displayshortcuts ((input-down))>></kbd> events and contains either the user input with the suffix `-userInput`, or the instantaneous selection with the suffix `-primaryList` or `-secondaryList`, depending on which of up to two filters generated the list it came from. |
!!Demonstration setup
I have created a tiddler called <$list filter=<<configTiddlerFilter>> /> and put the following filter into its <<.field first-search-filter>> field:
<code><$list filter=<<configTiddlerFilter>> ><$text text={{!!first-search-filter}}/></$list></code>.
This filters for non-system tiddlers whose titles contain the text the user has typed.
To use the above filter with <<.var keyboard-driven-input>>, the value of the parameter <<.param configTiddlerFilter>> should be a filter that returns <$list filter=<<configTiddlerFilter>> />.
I can select <<.param tiddler>>, <<.param storeTitle>>, and <<.param selectionStateTitle>> fairly arbitrarily (just making sure not to use titles of tiddlers that I do not want changed).
This demonstration can now be invoked with the following macro call:
<<kdi-demo-textmacrocall>>
!!Demo
Try typing in here: <$macrocall $name=keyboard-driven-input
tiddler=<<tiddler>>
storeTitle=<<storeTitle>>
selectionStateTitle=<<selectionStateTitle>>
configTiddlerFilter=<<configTiddlerFilter>>
/>
Observe the changes in the various state tiddlers in the below table. Use <kbd><<displayshortcuts ((input-up))>></kbd> and <kbd><<displayshortcuts ((input-down))>></kbd> keys to navigate among filter results. If nothing changes, try a shorter input to widen the filter. If the input has zero length, the list will contain all non-system tiddlers.
@@.tablestyle
|Parameter name |Tiddler title |Contents of <<.field text>> field of the tiddler |h
|<<.param tiddler>> |{{{[<tiddler>]}}} |<pre><$text text={{{[<tiddler>get[text]]}}}/></pre>|
|<<.param storeTitle>> |{{{[<storeTitle>]}}} |<pre><$text text= {{{[<storeTitle>get[text]]}}}/></pre>|
|<<.param selectionStateTitle>> |{{{[<selectionStateTitle>]}}} |<pre><$text text={{{[<selectionStateTitle>get[text]]}}}/></pre>|
@@
The <<.var keyboard-driven-input>> macro has many parameters available, including all the attributes of the enclosed ''edit-text'' widget, which make it very flexible in how it is used and how results can be displayed and interacted with.
See also: [[Customising search results]] and [[$:/core/ui/DefaultSearchResultList]]
<style>
.tablestyle {width:100%;}
.tablestyle td + td + td {width: 50%;}
</style>

View File

@@ -0,0 +1,6 @@
created: 20210131043724146
first-search-filter: [!is[system]search:title<userInput>sort[]]
modified: 20210204012422020
tags:
title: kdi-demo-configtid
type: text/vnd.tiddlywiki

View File

@@ -1,5 +1,5 @@
created: 20140418142957325
modified: 20201201154521138
modified: 20210912115121622
tags: Features
title: DateFormat
type: text/vnd.tiddlywiki
@@ -7,8 +7,11 @@ type: text/vnd.tiddlywiki
When used to display date values (with the `format` attribute set to ''date''), the ViewWidget accepts a `template` attribute that allows the format of the date values to be specified. The format string is processed with the following substitutions:
|!Token |!Substituted Value |
|`ddddd` |<<.from-version "5.2.0">> Day of year (1 to 365, or 366 for leap years) |
|`0ddddd` |<<.from-version "5.2.0">> Zero padded day of year (001 to 365, or 366 for leap years) |
|`DDD` |Day of week in full (eg, "Monday") |
|`ddd` |Short day of week (eg, "Mon") |
|`dddd` |<<.from-version "5.2.0">> Weekday number from 1 through 7, beginning with Monday and ending with Sunday |
|`DD` |Day of month |
|`0DD` |Adds a leading zero |
|`DDth` |Adds a suffix |

View File

@@ -18,7 +18,7 @@ The information above should be interpreted as follows:
* mainRender is the time taken for the initial display of the page template
* styleRefresh is the time taken to refresh the page stylesheet
* mainRender is the time taken to refresh the main page template
* mainRefresh is the time taken to refresh the main page template
As an example, try switching between the sidebar tabs to compare how long they take to render.

View File

@@ -1,5 +1,5 @@
created: 20140410103123179
modified: 20190206140446821
modified: 20210830010231559
tags: Filters
title: Filter Operators
type: text/vnd.tiddlywiki
@@ -36,9 +36,9 @@ The following table lists all core operators, the most common ones marked ✓. T
<<.group-heading "Listops Operators">>
<<.operator-rows "[tag[Filter Operators]tag[Listops Operators]tag[Order Operators]!tag[Mathematics Operators]!tag[String Operators]!tag[Tag Operators]!tag[Special Operators]sort[]]">>
<<.group-heading "String Operators">>
<<.operator-rows "[tag[Filter Operators]!tag[Order Operators]!tag[Mathematics Operators]tag[String Operators]!tag[Tag Operators]!tag[Special Operators]sort[]]">>
<<.operator-rows "[tag[Filter Operators]!tag[Order Operators]tag[String Operators]!tag[Tag Operators]!tag[Special Operators]sort[]]">>
<<.group-heading "Mathematics Operators">>
<<.operator-rows "[tag[Filter Operators]!tag[Order Operators]tag[Mathematics Operators]!tag[String Operators]!tag[Tag Operators]!tag[Special Operators]sort[]]">>
<<.operator-rows "[tag[Filter Operators]!tag[Order Operators]tag[Mathematics Operators]!tag[Tag Operators]!tag[Special Operators]sort[]]">>
<<.group-heading "Tag Operators">>
<<.operator-rows "[tag[Filter Operators]!tag[Order Operators]!tag[Mathematics Operators]!tag[String Operators]tag[Tag Operators]!tag[Special Operators]sort[]]">>
<<.group-heading "Special Operators">>

View File

@@ -2,13 +2,13 @@ caption: duplicateslugs
created: 20200509141702846
modified: 20200509141702846
op-input: a [[selection of titles|Title Selection]]
op-output: the input titles transformed so that they only contain lower case letters, numbers, periods, dashes and underscores
op-purpose: returns each item in the list in a human-readable form for use in URLs or filenames
op-output: input titles that yield duplicate slugs
op-purpose: find titles that yield duplicate slugs
tags: [[Filter Operators]]
title: duplicateslugs Operator
type: text/vnd.tiddlywiki
<<.from-version "5.1.23">> The <<.olink slugify>> can be used to transform arbitrary tiddler titles into human readable strings suitable for use in URLs or filenames. However, itis possible for multiple different titles to slugify to the same string. The <<.olink duplicateslugs>> operator can be used to display a warning. For example:
<<.from-version "5.1.23">> The <<.olink slugify>> operator can be used to transform arbitrary tiddler titles into human readable strings suitable for use in URLs or filenames. However, it is possible for multiple different titles to slugify to the same string. The <<.olink duplicateslugs>> operator can be used to display a warning. For example:
<$macrocall $name='wikitext-example-without-html'
src='<$list filter="[!is[system]duplicateslugs[]limit[1]]" emptyMessage="There are no duplicate slugs">

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