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

Compare commits

..

204 Commits

Author SHA1 Message Date
jeremy@jermolene.com
3bab996acd Version number update for 5.2.5 2022-12-19 18:47:55 +00:00
jeremy@jermolene.com
7e8380a8df Update readme.tid for github 2022-12-19 18:47:05 +00:00
jeremy@jermolene.com
44de7918ab Preparing for release of v5.2.5 2022-12-19 18:46:10 +00:00
jeremy@jermolene.com
5ee6af0632 Merge branch 'tiddlywiki-com' 2022-12-19 18:41:28 +00:00
jeremy@jermolene.com
ccf444c834 Release note updates 2022-12-19 17:25:52 +00:00
Wincent Balin
ecaa288fc5 Docs typo (#7137) 2022-12-19 15:49:05 +00:00
jeremy@jermolene.com
ceb6999dd6 Update release note 2022-12-19 08:56:18 +00:00
jeremy@jermolene.com
e51dd406b1 Revert global CSS changes from v5.2.4
Changes to style definitions for unclassed elements are being reverted because of backwards compatibility issues in the field. See #7126.
2022-12-19 08:46:26 +00:00
Wincent Balin
6ea61ac94f Signing the CLA (#7134) 2022-12-19 08:18:02 +00:00
Joe Bordes
caf01f10d6 i18n(ES) update with latest changes in master (#7127) 2022-12-17 14:00:57 +00:00
Mario Pietsch
1bd7924e1b Docs: "Saving with the HTML5 saver" improvements (#7109)
* "Saving with the HTML5 saver" improvements

* fix typos add platform tags

* reset modified date and fix minor typos
2022-12-17 08:22:27 +00:00
jeremy@jermolene.com
25b8f26073 Banner for v5.2.5
Daria has kindly reworked their v5.2.4 artwork for v5.2.5.
2022-12-16 17:41:59 +00:00
jeremy@jermolene.com
9160d81cc6 BibTex plugin: Fix obsolete comments 2022-12-16 17:41:05 +00:00
jeremy@jermolene.com
0b1a4f3a4d Fix release note typo 2022-12-13 17:30:52 +00:00
jeremy@jermolene.com
8d48964aca Preparing for v5.2.5 2022-12-13 16:42:40 +00:00
jeremy@jermolene.com
6cd2fc029d Version number update for 5.2.4 2022-12-13 16:35:26 +00:00
jeremy@jermolene.com
6235f29749 Preparing for release of v5.2.4 2022-12-13 16:34:14 +00:00
jeremy@jermolene.com
6385534638 Release note tweaks 2022-12-13 16:26:09 +00:00
jeremy@jermolene.com
ba3cba6170 Merge branch 'tiddlywiki-com' 2022-12-13 16:20:11 +00:00
Simon Baird
34c9e83bec Remove "Saving" tag from "Saving on TiddlySpot" (#7115)
The content is still there since there are links to it from various
places, but let's not have its card appear in the list of savers
shown in the "Saving" tiddler any more.

Removing just the "Saving" tag would have been sufficient, but I
think it makes sense to remove the other tags as well.
2022-12-13 12:26:14 +00:00
jeremy@jermolene.com
ed9cc84fb2 Remove erroneous references to en-GB language plugin
en-GB is built into the core, and so does not have a separate language plugin
2022-12-13 09:36:10 +00:00
jeremy@jermolene.com
22bc826247 Merge branch 'tiddlywiki-com' 2022-12-12 08:51:52 +00:00
jeremy@jermolene.com
6e6efcafc9 Reword Grok TiddlyWiki card 2022-12-12 08:45:38 +00:00
jeremy@jermolene.com
3c81558d74 Add introduction message to "Saving" tiddler
Fixes #7095
2022-12-10 14:23:28 +00:00
Mario Pietsch
cc47bb0330 Improve readability for: Using the external JavaScript template (#7097)
* Improve readability for: Using the external JavaScript template

* remove the extra button
2022-12-10 14:10:54 +00:00
Jeremy Ruston
0ce5788747 Fixes for JSON operators (#7105) 2022-12-09 18:31:23 +00:00
jeremy@jermolene.com
1118de319e Update prerelease warning 2022-12-09 10:43:13 +00:00
jeremy@jermolene.com
c2d82ccb32 Update release note 2022-12-09 10:17:31 +00:00
Maurycy Zarzycki
a899aac92c Change first letter in two plugin-related buttons to be uppercase to be consistent with the button that appears earlier (#7103) 2022-12-08 13:48:45 +00:00
jeremy@jermolene.com
bef11fe6a2 Allow overriding the coreURL for the external JS builds
Fixes #7096
2022-12-07 22:02:58 +00:00
Mario Pietsch
17a1ae23eb Fix truncated search results on small screens (#7099) 2022-12-07 17:14:12 +00:00
jeremy@jermolene.com
9f867ad51e Dynannotate: Fix undefined class 2022-12-07 17:10:45 +00:00
jeremy@jermolene.com
28c1e6bfc3 Docs update for nested macro definitions
Suggested by @kookma in bcb3b06d60 (commitcomment-91922651) and bcb3b06d60 (commitcomment-91922974)
2022-12-07 09:43:39 +00:00
Mario Pietsch
2db886793e Fix table overflow for small screens (#7010)
* fix table overflow for small screens

* add PRE word-break for Chrome and Safari on mobile

* remove comment, since it looks better for all browsers now

* add 1 space to trigger the new automatic build

* change small screen settings only for tiddler frame
2022-12-06 16:36:26 +00:00
jeremy@jermolene.com
8d050e0e69 Merge branch 'tiddlywiki-com' 2022-12-06 15:36:04 +00:00
jeremy@jermolene.com
e77006de63 Update links to Open Collective 2022-12-05 22:44:35 +00:00
FlashSystems
80442b7f7f Fix for bug #7054 (#7092)
* Fix Bug #7054: Reuse of $:/core/ui/EditTemplate/fields broken

This fixes Bug #7054 by creating a new variable
`safeNewFieldValueTiddlerPrefix` that is always set to a valid,
temporary prefix. This variable is used within `$action-deletetiddler`.
If the passed `newFieldValueTiddlerPrefix` variable is empty a new
prefix will be generated by the same logic that creates the original
`newFieldValueTiddlerPrefix` variable.

To be even more defensive, the prefix-filter was prepended with another
prefix filter that limits matches to `$:/temp/NewFieldValue`. This
prevents a bogus but non empty value in `newFieldValueTiddlerPrefix`
to delete arbitrary tiddlers.

* Add a default for `newFieldValueTiddlerPrefix`

This fixes a problem that was identified while fixing bug #7054. If the
tiddler `$:/core/ui/EditTemplate/fields` is transcluded directly and
`newFieldValueTiddlerPrefix` is not set, it will be generated. This
makes sure that this value is defined. It can not be redefined
unconditionally because if this tiddler is transcluded from
`EditTemplate.tid` these two tiddlers must agree on the same prefix
because the clean-up is duplicated between `EditTemplate.tid` and
`fields.tid`.

This would make `safeNewFieldValueTiddlerPrefix` obsolete, but I leave
it in there to make the macros safe and prevent any problems if the
`newFieldValueTiddlerPrefix` is unset by a later change.
2022-12-05 22:05:20 +00:00
Mario Pietsch
10bb3ba09d German Translation Update (#7093) 2022-12-05 22:04:52 +00:00
Maurycy Zarzycki
58013ba435 Another bundle of Polish translations (#7090)
* add Polish transaltions introduced in 272ba6a4b7

* Polish translations to changes introduced in a93a499684 and 0db987da60
2022-12-05 16:30:40 +00:00
Bram Chen
ee7bde58a2 Add chinese translations for the new layout switcher page control button (#7089) 2022-12-05 07:38:59 +00:00
Télumire
229159fea7 Correction of zindex for tc-card-ribbon-wrapper (new ribbon) (#7088) 2022-12-04 23:29:36 +00:00
Télumire
a311e5ebac correction of the z-index for the card ribbon wrapper (#7087) 2022-12-04 22:09:06 +00:00
jeremy@jermolene.com
9ff479ce87 Merge branch 'tiddlywiki-com' 2022-12-04 21:23:08 +00:00
jeremy@jermolene.com
77053cfe13 Update release note 2022-12-04 21:20:14 +00:00
jeremy@jermolene.com
1bd58db944 Add missing docs for commands command 2022-12-04 21:14:30 +00:00
jeremy@jermolene.com
4be0c17dd0 Fix HelloThere thumbnail for latest version to work in prerelease 2022-12-04 21:00:31 +00:00
jeremy@jermolene.com
595da5f9f6 Page control button for page layout should be hidden by default 2022-12-04 20:01:17 +00:00
jeremy@jermolene.com
ff674b9117 Merge branch 'tiddlywiki-com' 2022-12-04 19:57:22 +00:00
jeremy@jermolene.com
38dce175d6 Add Funding and Marketplace material, and refresh HelloThere 2022-12-04 17:58:16 +00:00
jeremy@jermolene.com
1ab9f457b4 Fix description of emergency tiddler expert
Confusing that it was using the same wording as the HTML5 fallback saver
2022-12-04 17:57:18 +00:00
jeremy@jermolene.com
1eddb52de5 Remove obsolete HelloThere badges 2022-12-04 17:55:52 +00:00
jeremy@jermolene.com
52fd6ce9c2 Remove creator field from docs tiddlers
By convention we don't attribute authors to tiddlers on tiddlywiki.com
2022-12-04 17:55:00 +00:00
jeremy@jermolene.com
62308792c8 Layout switcher page control button should be hidden by default 2022-12-04 16:26:52 +00:00
lin onetwo
272ba6a4b7 Add layout switcher page control button (#7076)
* feat: add layout switcher page control button

* feat: use icon from https://morosanuae.github.io/tw-icons/

$:/images/tabler-icons/layout

* fix: trigger switcher

* feat: beautify button icon

* fix: caption

* feat: group palette theme and layout buttons together

* fix: review

* fix: style issue
2022-12-04 16:25:13 +00:00
jeremy@jermolene.com
90449c9458 Fix modified data for "Installing TiddlyWiki on Node.js" 2022-12-04 16:06:37 +00:00
Bram Chen
5b8f36a594 Add chinese help texts for commands command (#7085) 2022-12-04 12:44:31 +00:00
jeremy@jermolene.com
acc7224758 Ensure unfold indicator is always visible
Fixes #7084
2022-12-04 11:19:54 +00:00
jeremy@jermolene.com
0db987da60 Minor tweaks for #7073 2022-12-04 11:03:51 +00:00
Carlo Colombo
a93a499684 Add commands command to run commands returned from a filter (#7073) 2022-12-04 10:59:59 +00:00
jeremy@jermolene.com
2c33502a4a Exclude drafts from the advanced search filter dropdown
Fixes #7083
2022-12-03 17:53:42 +00:00
lin onetwo
451a3454b5 Optionally allow click outside to close modals (#7072)
* feat: option to allow click on modalBackdrop to close modal

* feat: allow switcher modals closable

* feat: allow use caption field as modal title

* refactor: make maskClosable a variable

* fix: use "true"

* fix: code style

* docs: add description about maskClosable

* fix: convention is to have double quotes for strings in the TW core

* refactor: using a "mask-closable" field on the modal tiddlers instead of as a message parameter

* docs: move to modal tid

* Update WidgetMessage_ tm-modal.tid
2022-12-03 17:26:44 +00:00
Mohammad Rahmani
45a7eb1c03 Add new focus attribute to $select widget (#7081)
* Add focus attribute to $select widget

This address https://github.com/Jermolene/TiddlyWiki5/issues/7070

* Update SelectWidget.tid

Update the documentation for $select widget to include the new attribute: focus
2022-12-03 08:22:21 +00:00
jeremy@jermolene.com
d03da6085b Merge branch 'tiddlywiki-com' 2022-12-02 09:58:32 +00:00
Carlo Colombo
fa4dc2a4e9 Signing the CLA (#7074) 2022-12-01 21:26:08 +00:00
FlashSystems
3918e59cc1 Fixed PR to fix popup position if popup is triggered from within an offsetParent element (#7013)
* Fix popup location for tables

This commit introduces the `popupAbsCoords` option to the $button widget
and implements an absolut coordinate format.

Coordinates for popups are stored in the format `(x,y,w,h)`. These
coordinates are relative to the offset parent of the element that
defines the popup.

This commits adds a second format `@(x,y,w,h)`. Coordinates specified in
this format a relative to the pages root element.

The `popupAbsCoords` option of the $button widget enables the use of
this coordinates.

* Unify the declaration of the RegEx for parsing the popup-position

The regular expression was declared in three locations with the same
content. This commit supplies a new function `parseCoordinates` in
`popup.js`. This function returns the parsed coordinates and understands
the classic/absolute coordinates.

This function is used in `reveal.js` and `action-popup.js` to parse the
coordinates.

* Add documentation for coordinate systems

* Consolidate creating coordinate strings

The Popup object now contains a `buildCoordinates` method that can be
used to build coordinate strings. It takes an "enum" for the coordinate-
system to use. This makes everything easily extensible and prevents the
use of magic values.

* Add tests for `parseCoordinates` and `buildCoordinates`

* Add `tv-popup-abs-coords` to `collectDOMVariables`

This will make the absolute coordinates available for the
`DraggableWidget` and the `EventCatcherWidget`.

* Add documentation for the `tv-popup-abs-coords`

... to the `DraggableWidget` and the `EventCatcherWidget`.

* Fix crash when generating a static version of the TW

The Popup class is not initialized in `startup.js` if `$tw.browser` is
not true. After having consolidated the facilities for parsing
coordinate strings into `popup.js` this breaks because the static build
needs to parse coordinate stings even if no Popup module is initialized.
This commit solves this problem by making `readPopupState`,
`parseCoordinates` and `buildCoordinates` static methods of `popup.js`.
It also adds a comment to these functions to show that these can be called
safely even if the Popup-Class is not initialized.
2022-12-01 21:16:44 +00:00
lin onetwo
f7ccba4c25 Add "code" and "key" to propogateKeydownEvent's cloneEvent (#7071)
* feat: add key

* feat: add code
2022-11-30 10:17:10 +00:00
Mario Pietsch
319d7fbe9c Add hidden option to make "More" sidebar tabs be horizontal (#7063)
* make more sidebar tabs configurable vertical or horizontal

* more sidebar tabs orientation German translation

* remove language specific texts for more-horizontal setting

* Add More -> tabs horizontal setting to Hidden Settings
2022-11-30 09:57:14 +00:00
Guang Li
67c8f29160 more localized translation (#7069) 2022-11-29 22:57:13 +00:00
Cameron Fischer
856aca2f92 Linked-List refactor (#6056)
* Added failing linked-list test for #7059

* Fixed linked-list remove bug #7059

* Added failing linked-list test for #7059

* Switched LinkedList to use Map

* Removed this.last from LinkedList

* Removed this.first from LinkedList

* Switching to deleting old LinkedList entries

* LinkedList rewritten to be better

* Using null as LinkList ends to reduce hashing

* Using adhoc map... cause it's better than ECMA6 Map

* compliance with TiddlyWiki coding conventions

* Made link-list tests confirm the prev links

Co-authored-by: btheado <brian.theado@gmail.com>
2022-11-27 17:48:08 +00:00
jeremy@jermolene.com
34a20463c7 Update release note 2022-11-27 13:55:22 +00:00
jeremy@jermolene.com
56f13133d8 Missed off preparation for v5.2.4 2022-11-27 13:35:56 +00:00
Marxsal
684673cbff TiddlyBucket - Save to AWS or Google Storage (#7066) 2022-11-27 08:48:41 +00:00
btheado
bea1a6b14f Fix issue with linked list remove (#7065)
* Added failing linked-list test for #7059

* Fixed linked-list remove bug #7059
2022-11-26 15:05:10 +00:00
jeremy@jermolene.com
32a033bb50 Fix advanced search keyboard shortcut navigation
Fixes #7008
2022-11-26 11:22:24 +00:00
Mario Pietsch
97f7db169a Allow the big download button to be defined using the colour palette values (#7064) 2022-11-26 11:15:47 +00:00
jeremy@jermolene.com
850a4dd351 Correct colour for Mastodon icon 2022-11-25 17:59:11 +00:00
jeremy@jermolene.com
d707e6f825 Add Mastodon icon 2022-11-25 15:28:12 +00:00
jeremy@jermolene.com
5c378855ab Merge branch 'tiddlywiki-com' 2022-11-25 15:27:42 +00:00
jeremy@jermolene.com
ebc1f7e4ce Add link to official Mastodon account 2022-11-25 15:14:15 +00:00
Maurycy Zarzycki
2fcbf3b521 Update documentation to fix a mistake with format used by created and modified (#7060) 2022-11-24 18:43:51 +00:00
jeremy@jermolene.com
00927d2e13 Add parsermode pragma
Fixes #7058
2022-11-23 22:35:32 +00:00
Mario Pietsch
882e040e62 Refactor import preview to not use a hidden table row (#7057) 2022-11-23 21:53:21 +00:00
jeremy@jermolene.com
026739e2e0 Revert "Revert "add table utility classes and some docs how to use them. fix problem with control-panel basics tab shown in story river (#7039)""
See https://github.com/Jermolene/TiddlyWiki5/pull/7057#issue-1461608206

This reverts commit fba9efcf4a.
2022-11-23 21:52:36 +00:00
jeremy@jermolene.com
fba9efcf4a Revert "add table utility classes and some docs how to use them. fix problem with control-panel basics tab shown in story river (#7039)"
See #7056

This reverts commit b8a30091ee.
2022-11-23 08:28:06 +00:00
jeremy@jermolene.com
acfea3a212 New release banner credits 2022-11-22 21:10:36 +00:00
jeremy@jermolene.com
0dc30086e9 Update new release banner 2022-11-22 21:08:41 +00:00
Jeremy Ruston
cb0d0cfa6d Support nested macro definitions (#7004)
* First commit

* Switched to \end <name> instead of all those repeated backslashes

Thanks @kookma. See https://github.com/Jermolene/TiddlyWiki5/pull/7004#issuecomment-1286429236

* Docs update
2022-11-22 17:10:37 +00:00
Maurycy Zarzycki
d32d559f93 Add Timestamp to DateFormat (#7043)
* add Timestamp to DateFormat

* improve TIMESTAMP documentation
2022-11-21 16:13:34 +00:00
Cameron Fischer
8ead7e0624 Jasmine command (#6944) 2022-11-20 17:54:18 +00:00
Maurycy Zarzycki
4f7b10e055 CSV parser improvements (#7042) 2022-11-20 17:51:01 +00:00
Mario Pietsch
b8a30091ee add table utility classes and some docs how to use them. fix problem with control-panel basics tab shown in story river (#7039) 2022-11-20 17:48:10 +00:00
Maurycy Zarzycki
6955f14c3c add a hidden config to disable Syncer logging to the console (#7049) 2022-11-20 17:26:14 +00:00
Maurycy Zarzycki
994c5a2970 fix incorrect quote characters used in a code example (#7035) 2022-11-19 22:23:36 +00:00
Maurycy Zarzycki
ea150029f5 add a lot of small language tweaks and fixes to Polish translation (#7045) 2022-11-19 22:13:35 +00:00
Talha Mansoor
c663d2ba00 Sort completed tasks by 'modified' instead of 'created' field (#7047) 2022-11-19 22:13:02 +00:00
Talha Mansoor
39e8c8b125 Fix modified timestamp (#7046) 2022-11-19 22:11:46 +00:00
jeremy@jermolene.com
3713ee4fa9 Update release note 2022-11-16 17:27:10 +00:00
jeremy@jermolene.com
a99f934371 Fix build-site.sh hang with #6588 2022-11-16 08:26:35 +00:00
jeremy@jermolene.com
63803fd99d Merge branch 'tiddlywiki-com' 2022-11-15 19:50:44 +00:00
jeremy@jermolene.com
79ec96cb59 Remove old link 2022-11-15 17:58:50 +00:00
jeremy@jermolene.com
419b3b3534 Twitter Archivist: Update todo list 2022-11-15 17:12:54 +00:00
jeremy@jermolene.com
368963def0 Revert "Allow $:/core/ui/ControlPanel/Basics to work in the story river + some docs about utility classes (#6912)"
This reverts commit 10cb585dae.
2022-11-15 11:41:55 +00:00
jeremy@jermolene.com
830ffe64de Twitter Archivist: Add note about browser import only working on Chrome 2022-11-15 11:13:02 +00:00
jeremy@jermolene.com
1483195cd5 Merge branch 'tiddlywiki-com' 2022-11-15 10:39:05 +00:00
Mario Pietsch
9b9ff1e843 Extend pluginlibrary edition with a minimal test server (#6588)
* pluginlibrary - minimal test server

* changes suggested by Jeremy

* use tmp instead of the files directory

* new tmp-route

* rename edition to test-pluginlibrary

* fix .gitignore

* remove StoryList tiddler

* improve GettingStarted text

* rename edtion test-pluginlibrary back to pluginlibrary

* remove 2 tiddlers that shouldn't be there
2022-11-15 08:18:58 +00:00
Mario Pietsch
ea3503e30c Allow users to overwrite TOC default icons (#6913)
* Allow users to overwrite TOC default icons

* Fix docs as requested
2022-11-14 22:04:30 +00:00
Mario Pietsch
5e116d2a57 Add data-tags and data-tiddler-title attributes to preview area (#6939) 2022-11-14 17:48:00 +00:00
Mario Pietsch
aa5183a08e Add indentation to $:/TagManager (#6923) 2022-11-14 17:42:17 +00:00
Mario Pietsch
10cb585dae Allow $:/core/ui/ControlPanel/Basics to work in the story river + some docs about utility classes (#6912)
* allow $:/core/ui/ControlPanel/Basics to work in the story river + some docs about utility classes

* apply changes suggested by twMat

* fix some typos and change the base padding for tables

* fix a typo and remove whitespace

* remove TODO in base CSS
2022-11-14 17:36:01 +00:00
Mario Pietsch
029203dbc0 Move the version number to the top of the upgrader (#6881)
* Move the version number to the top of the upgrader

* change header to be clearer

* Move Upgrade Wizard to the top
2022-11-14 17:31:30 +00:00
Mario Pietsch
832868ecae Allow user defined setting for retain-story-order button in ControlPanel (#6863)
* allow user defined setting for retain-story-order button in ControlPanel

* improve hidden setting wording

* adjust all languages with new "ControlPanel DefaultTiddlers BottomHint

* fix typos and snippet filename
2022-11-14 17:30:13 +00:00
Mario Pietsch
7f48b6c6ce Make timeline macro more customisable (#5947)
* make the timeline-macro more customizable

* changed comment as requested
2022-11-14 17:11:26 +00:00
TonyM
b263ee3c80 Update SystemTag_ $__tags_Filter.tid (#7019)
said seach not search in two places description and body
2022-11-14 17:05:16 +00:00
Jeremy Ruston
b097d2ec48 Fix typo in SystemTag_ $__tags_ClassFilters_TiddlerTemplate.tid
Thanks @twMat
2022-11-14 16:58:50 +00:00
Jeremy Ruston
ef779c11e8 Fix Node.js installation instructions for Arch Linux
Fixes #7027
2022-11-14 11:52:38 +00:00
jeremy@jermolene.com
06520c8994 Wikify hashtags 2022-11-14 08:51:18 +00:00
jeremy@jermolene.com
710e51fe04 Twitter Archivist: Fix off by one error in af6c017086 2022-11-13 19:11:56 +00:00
jeremy@jermolene.com
af6c017086 Twitter Archivist: Expand t.co URLs in tweets 2022-11-13 19:05:09 +00:00
jeremy@jermolene.com
34353f4065 Twitter Archivist: Fix display of tweet author
Also:

* Cleaner user interface
* Added data model spec
* Added todo list
* Icons for archives
2022-11-13 11:18:47 +00:00
Jeremy Ruston
fedc23d73c Introduce Twitter Archivist Plugin 2022-11-12 17:09:31 +00:00
jeremy@jermolene.com
344110e289 Rearrange ordering of MP4 extension so that it defaults to video not audio
Previously using the --load command to import an MP4 file would cause it to be recognised as autio/mp4 instead of video/mp4
2022-11-09 13:56:28 +00:00
Xavier Cazin
72f06581b6 More consistency in fr-FR captions for cascade examples in ControlPanel (#7025) 2022-11-08 18:09:42 +00:00
tw-FRed
ae12e8fb69 Help Plugin: Update links to community resources (#7023)
* Promote Talk TiddlyWiki
* Change link to GG to https
2022-11-05 17:44:41 +00:00
jeremy@jermolene.com
e8148ff978 Missed off 965bd090a9
Thanks @pmario @saqimtiaz
2022-11-05 09:41:43 +00:00
jeremy@jermolene.com
965bd090a9 list-links macro: add "field" parameter
See https://talk.tiddlywiki.org/t/choosing-what-field-to-show-with-list-links/5039?u=jeremyruston
2022-11-05 09:10:31 +00:00
Cameron Fischer
3be9b13814 Fix for #4767: lazy-loading deletes tiddler bodies (#7014) 2022-11-02 17:26:08 +00:00
jeremy@jermolene.com
62f26d6630 Improve genesis widget examples 2022-11-01 10:07:54 +00:00
jeremy@jermolene.com
8fe2f6086d Update release notes credits 2022-11-01 09:48:08 +00:00
jeremy@jermolene.com
30af537b91 Update release note 2022-11-01 09:45:08 +00:00
jeremy@jermolene.com
f54ecc23f3 Fix wikification of tiddler titles in advanced search filter dropdown
Closes #7017

Thanks @ericshulman
2022-10-31 12:03:47 +00:00
jeremy@jermolene.com
67dd3f06bf Merge branch 'tiddlywiki-com' 2022-10-30 21:21:40 +00:00
btheado
6af3eb539b Adds a javascript widget tutorial to the dev tiddlywiki edition (#7016)
* Initial widget tutorials extracted from https://btheado.github.io/tw-widget-tutorial/

* Fixes for refresh behavior change
2022-10-30 16:10:12 +00:00
Saq Imtiaz
3f55f827a6 Extend page template with filter assigned classes (#6976)
* Extend page template with filter assigned classes

* feat: added dynamic class support for tiddler templates and documentation
2022-10-28 12:58:58 +01:00
jeremy@jermolene.com
b9d27e9fd5 Revert "Fix popup position if popup is triggered from within an offsetParent element (#6887)"
This reverts commit 5b85786f73.
2022-10-22 13:22:15 +01:00
FlashSystems
5b85786f73 Fix popup position if popup is triggered from within an offsetParent element (#6887)
* Fix popup location for tables

This commit introduces the `popupAbsCoords` option to the $button widget
and implements an absolut coordinate format.

Coordinates for popups are stored in the format `(x,y,w,h)`. These
coordinates are relative to the offset parent of the element that
defines the popup.

This commits adds a second format `@(x,y,w,h)`. Coordinates specified in
this format a relative to the pages root element.

The `popupAbsCoords` option of the $button widget enables the use of
this coordinates.

* Unify the declaration of the RegEx for parsing the popup-position

The regular expression was declared in three locations with the same
content. This commit supplies a new function `parseCoordinates` in
`popup.js`. This function returns the parsed coordinates and understands
the classic/absolute coordinates.

This function is used in `reveal.js` and `action-popup.js` to parse the
coordinates.

* Add documentation for coordinate systems

* Consolidate creating coordinate strings

The Popup object now contains a `buildCoordinates` method that can be
used to build coordinate strings. It takes an "enum" for the coordinate-
system to use. This makes everything easily extensible and prevents the
use of magic values.

* Add tests for `parseCoordinates` and `buildCoordinates`

* Add `tv-popup-abs-coords` to `collectDOMVariables`

This will make the absolute coordinates available for the
`DraggableWidget` and the `EventCatcherWidget`.

* Add documentation for the `tv-popup-abs-coords`

... to the `DraggableWidget` and the `EventCatcherWidget`.
2022-10-22 13:13:39 +01:00
Rob Hoelz
24dbf69180 Fix [is[variable]] operator doesn't work for "fake" variables #6303 (#6996)
* Add tests for [is[variable]] and "faked" variables

See GH #6303

* Make is[variable] and variables[] operators resilient to fake widgets

Co-authored-by: jeremy@jermolene.com <jeremy@jermolene.com>
2022-10-18 17:08:04 +01:00
jeremy@jermolene.com
7b408c7adf Update release note 2022-10-17 16:50:54 +01:00
jeremy@jermolene.com
c19d6d6328 Merge branch 'tiddlywiki-com' 2022-10-17 12:22:06 +01:00
jeremy@jermolene.com
941c09fae2 ScrollableWidget example shouldn't iterate through all tiddlers 2022-10-17 12:21:34 +01:00
jeremy@jermolene.com
b531984f50 Restore "Add default settings for styled inline SPANs (#6877)"
This reverts commit 6f98edd6bd.
2022-10-16 17:28:36 +01:00
jeremy@jermolene.com
8f079e2d45 Fix handling of orderedattributes when adding classes/styles
Fixes issue referred to in https://github.com/Jermolene/TiddlyWiki5/pull/6877#issuecomment-1277590200
2022-10-16 17:27:46 +01:00
Maurycy Zarzycki
cfd894e6fb allow select widget class to update if it uses a filter and is output changes (#6987)
* allow select widget class to update if it uses a filter and the filter output changes

* rewrite code to be more idiomatic + updates local property
2022-10-15 12:26:21 +01:00
Rob Hoelz
91327c1af0 Use deprecated macro for deprecated commands (#6973)
This just brings the documentation for these commands more inline with
other deprecations, plus offers a link to the recommended alternative
as well as the explanation for deprecation
2022-10-10 16:49:20 +01:00
jeremy@jermolene.com
6f98edd6bd Revert "Add default settings for styled inline SPANs (#6877)" because of failed tests
This reverts commit 23e0eeb556.
2022-10-07 18:43:09 +01:00
Mario Pietsch
23e0eeb556 Add default settings for styled inline SPANs (#6877)
* add default settings for styled inline SPANs

* change color names in palettes and vanilla-base

* change parser behaviour if custom class is used

* tc-inline-style will only be set if no other custom setting is appliead

* Add tests for inline-styles

* add one more test

* remove space after if
2022-10-07 18:05:49 +01:00
Maurycy Zarzycki
f33c7e2aef Allow global keyboard shortcuts to override all other shortcuts by providing a special field (#6735)
* allow global keyboard shortcuts to override all other shortcuts by providing a special field

* rework the global shortcuts taking priority

* replace bool option with options object in KeyboardManager's keydown handler

* update keyboard shortcut documentation to add information about the new priority setting

* add support for priority global keyboard shortcuts to code mirror

* update the feature's docs to point out it was/will be introduced in 5.2.4

* rollback unnecessary change
2022-10-07 17:31:04 +01:00
jeremy@jermolene.com
fc586481a9 Merge branch 'tiddlywiki-com' 2022-10-07 16:57:34 +01:00
jeremy@jermolene.com
09179d2f62 Deprecated macro: update text 2022-10-07 16:57:19 +01:00
jeremy@jermolene.com
d6ff38095b Docs: Fix typo 2022-10-06 10:25:14 +01:00
Maurycy Zarzycki
3bbbe77471 Update Polish translations (#6975)
* add polish translations to changes introduced in two commits:

 * ca762ab7a6
 * a453121e96

* add polish translations to changes introduced in d7b9e6fb02

* add polish translations to changes introduced in 0b1fc8e574
2022-10-05 15:40:23 +01:00
Maurycy Zarzycki
5657dfec0e Add VScode user settings directory to git ignore (#6974) 2022-10-05 14:51:11 +01:00
Bram Chen
31ab6dce77 Update chinese language files (#6972)
* Revise the footer and subtitle texts in Fields.multids
2022-10-03 09:45:30 +01:00
jeremy@jermolene.com
4007610d52 Prefer "modal" over "wizard" in the core
See https://github.com/Jermolene/TiddlyWiki5/discussions/6965#discussioncomment-3754315
2022-10-02 18:59:05 +01:00
jeremy@jermolene.com
fb34df84ed New image shortcut should not add journal tags
Fixes #6968
2022-10-02 18:55:26 +01:00
twMat
79e2e317cf Update Styles and Classes in WikiText.tid (#6969)
Add tag to include this tiddler in the list in the tiddler

https://tiddlywiki.com/prerelease/#How%20to%20apply%20custom%20styles
2022-10-02 17:37:03 +01:00
jeremy@jermolene.com
36896c3db8 Use view template body when opening tiddler in new window 2022-10-02 17:22:48 +01:00
Joe Bordes
82de7c9b1a i18n(ES) update translation with latest master (#6971) 2022-10-02 14:19:26 +01:00
jeremy@jermolene.com
1841b0fa4f Fix tests 2022-10-01 14:05:13 +01:00
jeremy@jermolene.com
47f80339b2 Update transclude widget to use error widget
Missed off #6970
2022-10-01 10:15:14 +01:00
Jeremy Ruston
db6abb9703 Improve recursion detection for transclusion and filters (#6970) 2022-10-01 10:13:40 +01:00
jeremy@jermolene.com
8d1e6b5d23 Test plugin should run tests in shadow tiddlers
Missed off #6961, preventing the tests introduced there from running
2022-10-01 10:03:50 +01:00
jeremy@jermolene.com
1df4c29d73 Relax the restriction on the let widget being unable to create variables starting with a dollar 2022-10-01 09:47:26 +01:00
jeremy@jermolene.com
81e4745c56 Update release note contributors list 2022-09-24 14:23:36 +01:00
jeremy@jermolene.com
87597ea273 Update release note 2022-09-24 14:20:30 +01:00
Jeremy Ruston
4e9267ea58 Introduce genesis widget (#6961)
* Initial Commit

* Fix version number

* Fix docs date
2022-09-24 14:07:42 +01:00
jeremy@jermolene.com
dd66fcc759 Merge branch 'tiddlywiki-com' 2022-09-24 11:06:39 +01:00
jeremy@jermolene.com
8ebb9ef442 Typo from a981f8ccfe
Fixes #6955
2022-09-24 10:55:22 +01:00
jeremy@jermolene.com
81ac987484 Optimise variable prototype chain handling
With this improvement and 53d229592d I'm measuring a 10-15% performance improvement between v5.2.3 and master using https://github.com/Jermolene/tiddlywiki-performance-test-rig
2022-09-24 08:28:16 +01:00
jeremy@jermolene.com
0a00da6db9 Optimise fake dom
Object.setPrototypeOf() appears to be significantly faster
2022-09-23 18:09:45 +01:00
jeremy@jermolene.com
53d229592d Optimise wiki.getTiddler() 2022-09-23 18:09:16 +01:00
jeremy@jermolene.com
166a156584 Fix typo: Safe mode should prevent globally disabling parser rules 2022-09-23 18:08:28 +01:00
jeremy@jermolene.com
c5d3d4c26e Disable wiki indexers in safe mode 2022-09-23 18:07:46 +01:00
Robin Munn
51bdf60ee8 Fix bug when using built-in list field as listField parameter to checkbox widget (#6897)
* Fix bug with checkbox widget and `list` field

The `list` field is stored as a list and frozen against modifications,
and getFieldList() returns it directly without creating a copy. So
before we modify it, we need to make a copy so we're not modifying a
frozen list. This bug doesn't manifest with custom fields, which are
stored as strings, only with the built-in `list` field.

* Fix checkboxes referencing non-existent tiddlers

This fixes the "tiddler is undefined" error when a checkbox's listField
property references a tiddler that doesn't (yet) exist.

* Better logic for checkbox listField handling

If the field contains an array, then it's almost certainly referenced
elsewhere and needs a defensive copy made. If it contained a string,
then it's safe to modify without making a defensive copy.
2022-09-22 18:52:55 +01:00
jeremy@jermolene.com
50f54ba6ca Merge branch 'tiddlywiki-com' 2022-09-22 10:34:41 +01:00
jeremy@jermolene.com
1a0ab68dec Complete fix for a981f8ccfe 2022-09-22 10:34:27 +01:00
jeremy@jermolene.com
bb67f96562 Merge branch 'tiddlywiki-com' 2022-09-21 09:32:33 +01:00
jeremy@jermolene.com
a981f8ccfe Partial fix for wikitext example macros
They don't work when the src text contains variable substitution syntax.
2022-09-21 09:32:18 +01:00
白宦成
859d15a446 Signing the CLA (#6951) 2022-09-17 16:52:05 +01:00
Cameron Fischer
debfd42d51 Log message not to have spaces and <empty string> (#6947) 2022-09-15 12:10:33 +01:00
twMat
fe365354d0 [doc] Update WidgetMessage: tm-new-tiddler (#6945)
...
2022-09-13 17:20:28 +01:00
jeremy@jermolene.com
d825f1c875 Use view template body cascade for the default preview 2022-09-10 11:01:29 +01:00
jeremy@jermolene.com
fe74a776e9 Docs: Add note for retrieving system tiddlers via HTTP under Node.js
See #6866
2022-09-09 10:02:26 +01:00
Roma Hicks
93e1a632b8 Updated URL to new public site. (#6496) 2022-09-05 18:04:47 +01:00
jeremy@jermolene.com
9b7edfc1a7 Revert changes to parse tree preview
This implementation requires #6666
2022-09-03 10:55:15 +01:00
jeremy@jermolene.com
3b2c64a85b Update release note 2022-09-02 21:28:32 +01:00
Jeremy Ruston
35b9faaa89 JSON Filter Operators (Revised Attempt) (#6936)
* First commit

Cherry-picked from #6666

* Adjust release version number

Just in case we decide to make a release before we merge #6666
2022-09-02 18:15:45 +01:00
tw-FRed
11b258a14b Fix tag pills style (#6934) 2022-09-01 08:38:26 +01:00
Bram Chen
7652aa5fed Update chinese translations (#6935)
* Add Hint and Caption of the delete button in the AdvancedSearch filter results
* Add confirm messages for the above deleting action
2022-09-01 08:03:37 +01:00
jeremy@jermolene.com
d62a16ee46 iPhone/iPad: Prevent long presses on tiddlylinks from triggering a preview 2022-08-31 17:44:31 +01:00
Xavier Cazin
0b1fc8e574 Make dialogs over deleting AdvancedSearch filter results translatable (#6933)
* Add fr-FR strings over deleting AvancedSearch filter results

* Add default strings over deleting AvancedSearch filter results

* Make dialogs over deleting results from AdvancedSearch filters translatable
2022-08-31 17:32:55 +01:00
jeremy@jermolene.com
127f660c91 Edit widget: remove default text "Type the text for the tiddler 'foo'"
Fixes #6152
2022-08-28 15:12:51 +01:00
Jeremy Ruston
668f443fc2 Fix prerelease version string 2022-08-19 13:14:11 +00:00
Jeremy Ruston
c8ad385947 Docs: Update code of conduct 2022-08-19 11:15:57 +00:00
Marxsal
c1f6e02d14 Fix missing links in Getting Started. (#6900)
* Fix empty links in Getting Started.

* Remove standalone TH reference and combine lines.
2022-08-19 08:14:04 +01:00
jeremy@jermolene.com
f0423c20b9 Merge branch 'tiddlywiki-com' 2022-08-17 18:11:12 +01:00
Mario Pietsch
953b89fd6b CSS: Make input and button elements consistent for all browsers (#6910) 2022-08-17 14:54:15 +01:00
Bram Chen
f87ab06414 Update chinese language files (#6895)
* Change core GettingStarted tiddler table layout
* Revise wording
2022-08-10 10:06:57 +02:00
Mario Pietsch
2ff5bd5a0f Fix removing a field with empty name (#6888)
* allow us to remove a field with empty key

* fix typo in if clause
2022-08-09 18:44:45 +02:00
Mario Pietsch
d7b9e6fb02 Getting started new table layout (#6894)
* change core GettingStarted tiddler table layout

* rename tc-table-no-grid to tc-table-no-border
2022-08-09 18:42:01 +02:00
BALLOON | FU-SEN
8420f8430f Minor adjustments to Japanese language files (#6884)
Since there was a mixture of "Desumasu-style"(ですます調) and "Dearu-style"(である調), the unification (that is unique to Japanese)
2022-08-06 11:07:47 +02:00
Mario Pietsch
a572979cc4 Add global option to show default text below the edit textarea (#6882) 2022-08-05 17:16:39 +02:00
Guang Li
90d6a0f1a6 Update readme.tid (#6883) 2022-08-05 16:59:53 +02:00
twMat
406dbd0883 Update Releases.tid (#6880) 2022-08-04 19:18:06 +01:00
jeremy@jermolene.com
3fd2cfc339 Preparing for v5.2.4
Note that we currently only plan to release v5.2.4 if there's an issue with v5.2.3, and that the next release version will be v5.3.0
2022-08-02 17:31:20 +01:00
413 changed files with 6780 additions and 1153 deletions

2
.gitignore vendored
View File

@@ -1,5 +1,7 @@
.DS_Store
.c9/
.vscode/
tmp/
output/
node_modules/

View File

@@ -5,7 +5,7 @@
# Default to the current version number for building the plugin library
if [ -z "$TW5_BUILD_VERSION" ]; then
TW5_BUILD_VERSION=v5.2.3
TW5_BUILD_VERSION=v5.2.5
fi
echo "Using TW5_BUILD_VERSION as [$TW5_BUILD_VERSION]"
@@ -233,6 +233,15 @@ node $TW5_BUILD_TIDDLYWIKI \
--build index \
|| exit 1
# /editions/twitter-archivist/index.html Twitter Archivist edition
node $TW5_BUILD_TIDDLYWIKI \
./editions/twitter-archivist \
--verbose \
--load $TW5_BUILD_OUTPUT/build.tid \
--output $TW5_BUILD_OUTPUT/editions/twitter-archivist/ \
--build index \
|| exit 1
######################################################
#
# Plugin demos
@@ -450,7 +459,7 @@ node $TW5_BUILD_TIDDLYWIKI \
--verbose \
--load $TW5_BUILD_OUTPUT/build.tid \
--output $TW5_BUILD_OUTPUT/library/$TW5_BUILD_VERSION \
--build \
--build library\
|| exit 1
# Delete the temporary build tiddler

View File

@@ -9,6 +9,7 @@ node ./tiddlywiki.js \
--verbose \
--version \
--rendertiddler $:/core/save/all test.html text/plain \
--test \
|| exit 1
echo To run the tests in a browser, open "editions/test/output/test.html"

View File

@@ -1230,13 +1230,16 @@ $tw.Wiki = function(options) {
this.getTiddler = function(title) {
if(title) {
var t = tiddlers[title];
if(t instanceof $tw.Tiddler) {
if(t !== undefined) {
return t;
} else if(title !== undefined && shadowTiddlers[title]) {
return shadowTiddlers[title].tiddler;
} else {
var s = shadowTiddlers[title];
if(s !== undefined) {
return s.tiddler;
}
}
return undefined;
}
return undefined;
};
// Get an array of all tiddler titles
@@ -2400,11 +2403,11 @@ $tw.boot.initStartup = function(options) {
$tw.utils.registerFileType("application/x-font-ttf","base64",".woff");
$tw.utils.registerFileType("application/font-woff2","base64",".woff2");
$tw.utils.registerFileType("audio/ogg","base64",".ogg");
$tw.utils.registerFileType("audio/mp4","base64",[".mp4",".m4a"]);
$tw.utils.registerFileType("video/ogg","base64",[".ogm",".ogv",".ogg"]);
$tw.utils.registerFileType("video/webm","base64",".webm");
$tw.utils.registerFileType("video/mp4","base64",".mp4");
$tw.utils.registerFileType("audio/mp3","base64",".mp3");
$tw.utils.registerFileType("audio/mp4","base64",[".mp4",".m4a"]);
$tw.utils.registerFileType("text/markdown","utf8",[".md",".markdown"],{deserializerType:"text/x-markdown"});
$tw.utils.registerFileType("text/x-markdown","utf8",[".md",".markdown"]);
$tw.utils.registerFileType("application/enex+xml","utf8",".enex");
@@ -2416,7 +2419,7 @@ $tw.boot.initStartup = function(options) {
$tw.utils.registerFileType("application/epub+zip","base64",".epub");
$tw.utils.registerFileType("application/octet-stream","base64",".octet-stream");
// Create the wiki store for the app
$tw.wiki = new $tw.Wiki();
$tw.wiki = new $tw.Wiki($tw.safeMode && {enableIndexers: []});
// Install built in tiddler fields modules
$tw.Tiddler.fieldModules = $tw.modules.getModulesByTypeAsHashmap("tiddlerfield");
// Install the tiddler deserializer modules

4
core/images/layout-button.tid Executable file
View File

@@ -0,0 +1,4 @@
title: $:/core/images/layout-button
tags: $:/tags/Image
<svg width="22pt" height="22pt" class="tc-image-layout-button tc-image-button" viewBox="0 0 24 24" stroke-width="1" stroke="none"><path d="M0 0h24v24H0z" fill="none"/><rect x="2" y="2" width="7" height="7" rx="2"/><rect x="2" y="13" width="7" height="9" rx="2"/><rect x="12" y="2" width="10" height="20" rx="2"/></svg>

6
core/images/mastodon.tid Normal file
View File

@@ -0,0 +1,6 @@
title: $:/core/images/mastodon
tags: $:/tags/Image
<svg width="22pt" height="22pt" class="tc-image-mastodon tc-image-button" viewBox="0 0 128 128">
<path d="M112.716,76.735C111.231,85.764 99.411,95.646 85.836,97.561C78.757,98.559 71.787,99.476 64.355,99.073C52.201,98.415 42.61,95.646 42.61,95.646C42.61,97.044 42.683,98.374 42.829,99.619C44.409,113.79 54.723,114.639 64.493,115.035C74.354,115.434 83.134,112.163 83.134,112.163L83.539,122.695C83.539,122.695 76.642,127.071 64.355,127.875C57.58,128.315 49.167,127.674 39.369,124.61C18.118,117.965 14.463,91.202 13.904,64.048C13.733,55.985 13.839,48.383 13.839,42.024C13.839,14.257 29.238,6.118 29.238,6.118C37.002,1.905 50.326,0.134 64.177,-0L64.517,-0C78.369,0.134 91.701,1.905 99.465,6.118C99.465,6.118 114.864,14.257 114.864,42.024C114.864,42.024 115.057,62.511 112.716,76.735ZM96.7,44.179C96.7,37.307 95.219,31.847 92.245,27.807C89.177,23.767 85.16,21.696 80.174,21.696C74.403,21.696 70.034,24.316 67.146,29.556L64.337,35.118L61.529,29.556C58.64,24.316 54.271,21.696 48.501,21.696C43.514,21.696 39.497,23.767 36.43,27.807C33.455,31.847 31.974,37.307 31.974,44.179L31.974,77.8L43.249,77.8L43.249,45.167C43.249,38.288 45.699,34.796 50.599,34.796C56.017,34.796 58.733,38.938 58.733,47.128L58.733,64.99L69.941,64.99L69.941,47.128C69.941,38.938 72.657,34.796 78.075,34.796C82.975,34.796 85.425,38.288 85.425,45.167L85.425,77.8L96.7,77.8L96.7,44.179Z"/>
</svg>

View File

@@ -18,6 +18,8 @@ CopyToClipboard/Caption: copy to clipboard
CopyToClipboard/Hint: Copy this text to the clipboard
Delete/Caption: delete
Delete/Hint: Delete this tiddler
DeleteTiddlers/Caption: delete tiddlers
DeleteTiddlers/Hint: Delete tiddlers
Edit/Caption: edit
Edit/Hint: Edit this tiddler
Encryption/Caption: encryption
@@ -57,6 +59,8 @@ Home/Caption: home
Home/Hint: Open the default tiddlers
Language/Caption: language
Language/Hint: Choose the user interface language
LayoutSwitcher/Hint: Open layout switcher
LayoutSwitcher/Caption: layout
Manager/Caption: tiddler manager
Manager/Hint: Open tiddler manager
More/Caption: more

View File

@@ -7,7 +7,7 @@ Appearance/Hint: Ways to customise the appearance of your TiddlyWiki.
Basics/AnimDuration/Prompt: Animation duration
Basics/AutoFocus/Prompt: Default focus field for new tiddlers
Basics/Caption: Basics
Basics/DefaultTiddlers/BottomHint: Use &#91;&#91;double square brackets&#93;&#93; for titles with spaces. Or you can choose to <$button set="$:/DefaultTiddlers" setTo="[list[$:/StoryList]]">retain story ordering</$button>
Basics/DefaultTiddlers/BottomHint: Use &#91;&#91;double square brackets&#93;&#93; for titles with spaces. Or you can choose to {{retain story ordering||$:/snippets/retain-story-ordering-button}}
Basics/DefaultTiddlers/Prompt: Default tiddlers
Basics/DefaultTiddlers/TopHint: Choose which tiddlers are displayed at startup
Basics/Language/Prompt: Hello! Current language:
@@ -90,8 +90,8 @@ Plugins/Languages/Caption: Languages
Plugins/Languages/Hint: Language pack plugins
Plugins/NoInfoFound/Hint: No ''"<$text text=<<currentTab>>/>"'' found
Plugins/NotInstalled/Hint: This plugin is not currently installed
Plugins/OpenPluginLibrary: open plugin library
Plugins/ClosePluginLibrary: close plugin library
Plugins/OpenPluginLibrary: Open plugin library
Plugins/ClosePluginLibrary: Close plugin library
Plugins/PluginWillRequireReload: (requires reload)
Plugins/Plugins/Caption: Plugins
Plugins/Plugins/Hint: Plugins

View File

@@ -13,7 +13,7 @@ dependents: For a plugin, lists the dependent plugin titles
description: The descriptive text for a plugin, or a modal dialogue
draft.of: For draft tiddlers, contains the title of the tiddler of which this is a draft
draft.title: For draft tiddlers, contains the proposed new title of the tiddler
footer: The footer text for a wizard
footer: The footer text for a modal
hide-body: The view template will hide bodies of tiddlers if set to ''yes''
icon: The title of the tiddler containing the icon associated with a tiddler
library: Indicates that a tiddler should be saved as a JavaScript library if set to ''yes''
@@ -28,7 +28,7 @@ plugin-type: The type of plugin in a plugin tiddler
revision: The revision of the tiddler held at the server
released: Date of a TiddlyWiki release
source: The source URL associated with a tiddler
subtitle: The subtitle text for a wizard
subtitle: The subtitle text for a modal
tags: A list of tags associated with a tiddler
text: The body text of a tiddler
throttle.refresh: If present, throttles refreshes of this tiddler

View File

@@ -9,9 +9,10 @@ Before you start storing important information in ~TiddlyWiki it is vital to mak
<div class="tc-control-panel">
|<$link to="$:/SiteTitle"><<lingo Title/Prompt>></$link> |<$edit-text tiddler="$:/SiteTitle" default="" tag="input"/> |
|<$link to="$:/SiteSubtitle"><<lingo Subtitle/Prompt>></$link> |<$edit-text tiddler="$:/SiteSubtitle" default="" tag="input"/> |
|<$link to="$:/DefaultTiddlers"><<lingo DefaultTiddlers/Prompt>></$link> |<<lingo DefaultTiddlers/TopHint>><br> <$edit tag="textarea" tiddler="$:/DefaultTiddlers"/><br>//<<lingo DefaultTiddlers/BottomHint>>// |
|tc-table-no-border tc-first-col-min-width tc-first-link-nowrap|k
| <$link to="$:/SiteTitle"><<lingo Title/Prompt>></$link>|<$edit-text tiddler="$:/SiteTitle" default="" tag="input"/> |
| <$link to="$:/SiteSubtitle"><<lingo Subtitle/Prompt>></$link>|<$edit-text tiddler="$:/SiteSubtitle" default="" tag="input"/> |
|^ <$link to="$:/DefaultTiddlers"><<lingo DefaultTiddlers/Prompt>></$link><br><<lingo DefaultTiddlers/TopHint>>|<$edit tag="textarea" tiddler="$:/DefaultTiddlers"/><br>//<<lingo DefaultTiddlers/BottomHint>>// |
</div>
See the [[control panel|$:/ControlPanel]] for more options.

View File

@@ -0,0 +1,18 @@
title: $:/language/Help/commands
description: Run commands returned from a filter
Sequentially run the command tokens returned from a filter
```
--commands <filter>
```
Examples
```
--commands "[enlist{$:/build-commands-as-text}]"
```
```
--commands "[{$:/build-commands-as-json}jsonindexes[]] :map[{$:/build-commands-as-json}jsonget<currentTiddler>]"
```

View File

@@ -8,6 +8,7 @@ CloseAll/Button: close all
ColourPicker/Recent: Recent:
ConfirmCancelTiddler: Do you wish to discard changes to the tiddler "<$text text=<<title>>/>"?
ConfirmDeleteTiddler: Do you wish to delete the tiddler "<$text text=<<title>>/>"?
ConfirmDeleteTiddlers: Are you sure you wish to delete <<resultCount>> tiddler(s)?
ConfirmOverwriteTiddler: Do you wish to overwrite the tiddler "<$text text=<<title>>/>"?
ConfirmEditShadowTiddler: You are about to edit a ShadowTiddler. Any changes will override the default system making future upgrades non-trivial. Are you sure you want to edit "<$text text=<<title>>/>"?
ConfirmAction: Do you wish to proceed?

View File

@@ -0,0 +1,42 @@
/*\
title: $:/core/modules/commands/commands.js
type: application/javascript
module-type: command
Runs the commands returned from a filter
\*/
(function() {
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
exports.info = {
name: "commands",
synchronous: true
};
var Command = function(params, commander) {
this.params = params;
this.commander = commander;
};
Command.prototype.execute = function() {
// Parse the filter
var filter = this.params[0];
if(!filter) {
return "No filter specified";
}
var commands = this.commander.wiki.filterTiddlers(filter)
if(commands.length === 0) {
return "No tiddlers found for filter '" + filter + "'";
}
this.commander.addCommandTokens(commands);
return null;
};
exports.Command = Command;
})();

View File

@@ -87,7 +87,7 @@ function FramedEngine(options) {
$tw.utils.addEventListeners(this.domNode,[
{name: "click",handlerObject: this,handlerMethod: "handleClickEvent"},
{name: "input",handlerObject: this,handlerMethod: "handleInputEvent"},
{name: "keydown",handlerObject: this.widget,handlerMethod: "handleKeydownEvent"},
{name: "keydown",handlerObject: this,handlerMethod: "handleKeydownEvent"},
{name: "focus",handlerObject: this,handlerMethod: "handleFocusEvent"}
]);
// Add drag and drop event listeners if fileDrop is enabled
@@ -192,6 +192,17 @@ FramedEngine.prototype.handleFocusEvent = function(event) {
}
};
/*
Handle a keydown event
*/
FramedEngine.prototype.handleKeydownEvent = function(event) {
if ($tw.keyboardManager.handleKeydownEvent(event, {onlyPriority: true})) {
return true;
}
return this.widget.handleKeydownEvent(event);
};
/*
Handle a click
*/

View File

@@ -115,7 +115,7 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
// Otherwise, we need to construct a default value for the editor
switch(this.editField) {
case "text":
value = "Type the text for the tiddler '" + this.editTitle + "'";
value = "";
type = "text/vnd.tiddlywiki";
break;
case "title":
@@ -298,7 +298,7 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
Propogate keydown events to our container for the keyboard widgets benefit
*/
EditTextWidget.prototype.propogateKeydownEvent = function(event) {
var newEvent = this.cloneEvent(event,["keyCode","which","metaKey","ctrlKey","altKey","shiftKey"]);
var newEvent = this.cloneEvent(event,["keyCode","code","which","key","metaKey","ctrlKey","altKey","shiftKey"]);
return !this.parentDomNode.dispatchEvent(newEvent);
};

View File

@@ -12,6 +12,9 @@ Adds tiddler filtering methods to the $tw.Wiki object.
/*global $tw: false */
"use strict";
/* Maximum permitted filter recursion depth */
var MAX_FILTER_DEPTH = 300;
/*
Parses an operation (i.e. a run) within a filter string
operators: Array of array of operator nodes into which results should be inserted
@@ -328,7 +331,7 @@ exports.compileFilter = function(filterString) {
})());
});
// Return a function that applies the operations to a source iterator of tiddler titles
var compiled = $tw.perf.measure("filter: " + filterString,function filterFunction(source,widget) {
var fnMeasured = $tw.perf.measure("filter: " + filterString,function filterFunction(source,widget) {
if(!source) {
source = self.each;
} else if(typeof source === "object") { // Array or hashmap
@@ -338,9 +341,15 @@ exports.compileFilter = function(filterString) {
widget = $tw.rootWidget;
}
var results = new $tw.utils.LinkedList();
$tw.utils.each(operationFunctions,function(operationFunction) {
operationFunction(results,source,widget);
});
self.filterRecursionCount = (self.filterRecursionCount || 0) + 1;
if(self.filterRecursionCount < MAX_FILTER_DEPTH) {
$tw.utils.each(operationFunctions,function(operationFunction) {
operationFunction(results,source,widget);
});
} else {
results.push("/**-- Excessive filter recursion --**/");
}
self.filterRecursionCount = self.filterRecursionCount - 1;
return results.toArray();
});
if(this.filterCacheCount >= 2000) {
@@ -350,9 +359,9 @@ exports.compileFilter = function(filterString) {
this.filterCache = Object.create(null);
this.filterCacheCount = 0;
}
this.filterCache[filterString] = compiled;
this.filterCache[filterString] = fnMeasured;
this.filterCacheCount++;
return compiled;
return fnMeasured;
};
})();

View File

@@ -0,0 +1,35 @@
/*\
title: $:/core/modules/filters/format/json.js
type: application/javascript
module-type: formatfilteroperator
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.json = function(source,operand,options) {
var results = [],
spaces = null;
if(operand) {
spaces = /^\d+$/.test(operand) ? parseInt(operand,10) : operand;
}
source(function(tiddler,title) {
var data = $tw.utils.parseJSONSafe(title);
try {
data = JSON.parse(title);
} catch(e) {
data = undefined;
}
if(data !== undefined) {
results.push(JSON.stringify(data,null,spaces));
}
});
return results;
};
})();

View File

@@ -19,13 +19,13 @@ exports.variable = function(source,prefix,options) {
var results = [];
if(prefix === "!") {
source(function(tiddler,title) {
if(!(title in options.widget.variables)) {
if(options.widget.getVariable(title) === undefined) {
results.push(title);
}
});
} else {
source(function(tiddler,title) {
if(title in options.widget.variables) {
if(options.widget.getVariable(title) !== undefined) {
results.push(title);
}
});

View File

@@ -0,0 +1,186 @@
/*\
title: $:/core/modules/filters/json-ops.js
type: application/javascript
module-type: filteroperator
Filter operators for JSON operations
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
exports["jsonget"] = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
var data = $tw.utils.parseJSONSafe(title,title);
if(data) {
var items = getDataItemValueAsStrings(data,operator.operands);
if(items !== undefined) {
results.push.apply(results,items);
}
}
});
return results;
};
exports["jsonextract"] = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
var data = $tw.utils.parseJSONSafe(title,title);
if(data) {
var item = getDataItem(data,operator.operands);
if(item !== undefined) {
results.push(JSON.stringify(item));
}
}
});
return results;
};
exports["jsonindexes"] = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
var data = $tw.utils.parseJSONSafe(title,title);
if(data) {
var items = getDataItemKeysAsStrings(data,operator.operands);
if(items !== undefined) {
results.push.apply(results,items);
}
}
});
return results;
};
exports["jsontype"] = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
var data = $tw.utils.parseJSONSafe(title,title);
if(data) {
var item = getDataItemType(data,operator.operands);
if(item !== undefined) {
results.push(item);
}
}
});
return results;
};
/*
Given a JSON data structure and an array of index strings, return an array of the string representation of the values at the end of the index chain, or "undefined" if any of the index strings are invalid
*/
function getDataItemValueAsStrings(data,indexes) {
// Get the item
var item = getDataItem(data,indexes);
// Return the item as a string list
return convertDataItemValueToStrings(item);
}
/*
Given a JSON data structure and an array of index strings, return an array of the string representation of the keys of the item at the end of the index chain, or "undefined" if any of the index strings are invalid
*/
function getDataItemKeysAsStrings(data,indexes) {
// Get the item
var item = getDataItem(data,indexes);
// Return the item keys as a string
return convertDataItemKeysToStrings(item);
}
/*
Return an array of the string representation of the values of a data item, or "undefined" if the item is undefined
*/
function convertDataItemValueToStrings(item) {
// Return the item as a string
if(item === undefined) {
return undefined;
} else if(item === null) {
return ["null"]
} else if(typeof item === "object") {
var results = [],i,t;
if($tw.utils.isArray(item)) {
// Return all the items in arrays recursively
for(i=0; i<item.length; i++) {
t = convertDataItemValueToStrings(item[i])
if(t !== undefined) {
results.push.apply(results,t);
}
}
} else {
// Return all the values in objects recursively
$tw.utils.each(Object.keys(item).sort(),function(key) {
t = convertDataItemValueToStrings(item[key]);
if(t !== undefined) {
results.push.apply(results,t);
}
});
}
return results;
}
return [item.toString()];
}
/*
Return an array of the string representation of the keys of a data item, or "undefined" if the item is undefined
*/
function convertDataItemKeysToStrings(item) {
// Return the item as a string
if(item === undefined) {
return item;
} else if(typeof item === "object") {
if(item === null) {
return [];
}
var results = [];
if($tw.utils.isArray(item)) {
for(var i=0; i<item.length; i++) {
results.push(i.toString());
}
return results;
} else {
$tw.utils.each(Object.keys(item).sort(),function(key) {
results.push(key);
});
return results;
}
}
return [];
}
function getDataItemType(data,indexes) {
// Get the item
var item = getDataItem(data,indexes);
// Return the item type
if(item === undefined) {
return item;
} else if(item === null) {
return "null";
} else if($tw.utils.isArray(item)) {
return "array";
} else if(typeof item === "object") {
return "object";
} else {
return typeof item;
}
}
/*
Given a JSON data structure and an array of index strings, return the value at the end of the index chain, or "undefined" if any of the index strings are invalid
*/
function getDataItem(data,indexes) {
if(indexes.length === 0 || (indexes.length === 1 && indexes[0] === "")) {
return data;
}
// Get the item
var item = data;
for(var i=0; i<indexes.length; i++) {
if(item !== undefined) {
item = item[indexes[i]];
}
}
return item;
}
})();

View File

@@ -16,9 +16,15 @@ Filter operator for returning the names of the active variables
Export our filter function
*/
exports.variables = function(source,operator,options) {
var names = [];
for(var variable in options.widget.variables) {
names.push(variable);
var names = [],
widget = options.widget;
while(widget && !widget.hasOwnProperty("variables")) {
widget = widget.parentWidget;
}
if(widget && widget.variables) {
for(var variable in widget.variables) {
names.push(variable);
}
}
return names.sort();
};

View File

@@ -141,6 +141,7 @@ function KeyboardManager(options) {
this.shortcutKeysList = [], // Stores the shortcut-key descriptors
this.shortcutActionList = [], // Stores the corresponding action strings
this.shortcutParsedList = []; // Stores the parsed key descriptors
this.shortcutPriorityList = []; // Stores the parsed shortcut priority
this.lookupNames = ["shortcuts"];
this.lookupNames.push($tw.platform.isMac ? "shortcuts-mac" : "shortcuts-not-mac")
this.lookupNames.push($tw.platform.isWindows ? "shortcuts-windows" : "shortcuts-not-windows");
@@ -318,12 +319,23 @@ KeyboardManager.prototype.updateShortcutLists = function(tiddlerList) {
this.shortcutKeysList[i] = tiddlerFields.key !== undefined ? tiddlerFields.key : undefined;
this.shortcutActionList[i] = tiddlerFields.text;
this.shortcutParsedList[i] = this.shortcutKeysList[i] !== undefined ? this.parseKeyDescriptors(this.shortcutKeysList[i]) : undefined;
this.shortcutPriorityList[i] = tiddlerFields.priority === "yes" ? true : false;
}
};
KeyboardManager.prototype.handleKeydownEvent = function(event) {
/*
event: the keyboard event object
options:
onlyPriority: true if only priority global shortcuts should be invoked
*/
KeyboardManager.prototype.handleKeydownEvent = function(event, options) {
options = options || {};
var key, action;
for(var i=0; i<this.shortcutTiddlers.length; i++) {
if(options.onlyPriority && this.shortcutPriorityList[i] !== true) {
continue;
}
if(this.shortcutParsedList[i] !== undefined && this.checkKeyDescriptors(event,this.shortcutParsedList[i])) {
key = this.shortcutParsedList[i];
action = this.shortcutActionList[i];

View File

@@ -13,6 +13,11 @@ The CSV text parser processes CSV files into a table wrapped in a scrollable wid
"use strict";
var CsvParser = function(type,text,options) {
// Special handler for tab-delimited files
if (type === 'text/tab-delimited-values' && !options.separator) {
options.separator = "\t";
}
// Table framework
this.tree = [{
"type": "scrollable", "children": [{
@@ -24,30 +29,33 @@ var CsvParser = function(type,text,options) {
}]
}];
// Split the text into lines
var lines = text.split(/\r?\n/mg),
var lines = $tw.utils.parseCsvString(text, options),
tag = "th";
var maxColumns = 0;
$tw.utils.each(lines, function(columns) {
maxColumns = Math.max(columns.length, maxColumns);
});
for(var line=0; line<lines.length; line++) {
var lineText = lines[line];
if(lineText) {
var row = {
"type": "element", "tag": "tr", "children": []
};
var columns = lineText.split(",");
for(var column=0; column<columns.length; column++) {
row.children.push({
"type": "element", "tag": tag, "children": [{
"type": "text",
"text": columns[column]
}]
});
}
tag = "td";
this.tree[0].children[0].children[0].children.push(row);
var columns = lines[line];
var row = {
"type": "element", "tag": "tr", "children": []
};
for(var column=0; column<maxColumns; column++) {
row.children.push({
"type": "element", "tag": tag, "children": [{
"type": "text",
"text": columns[column] || ''
}]
});
}
tag = "td";
this.tree[0].children[0].children[0].children.push(row);
}
};
exports["text/csv"] = CsvParser;
exports["text/tab-delimited-values"] = CsvParser;
})();

View File

@@ -58,7 +58,7 @@ exports.parse = function() {
var reEnd;
if(this.match[3]) {
// If so, the end of the body is marked with \end
reEnd = /(\r?\n\\end[^\S\n\r]*(?:$|\r?\n))/mg;
reEnd = new RegExp("(\\r?\\n\\\\end[^\\S\\n\\r]*(?:" + $tw.utils.escapeRegExp(this.match[1]) + ")?(?:$|\\r?\\n))","mg");
} else {
// Otherwise, the end of the definition is marked by the end of the line
reEnd = /($|\r?\n)/mg;

View File

@@ -0,0 +1,68 @@
/*\
title: $:/core/modules/parsers/wikiparser/rules/parsermode.js
type: application/javascript
module-type: wikirule
Wiki pragma rule for parser mode specifications
```
\parsermode block
\parsermode inline
```
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
exports.name = "parsermode";
exports.types = {pragma: true};
/*
Instantiate parse rule
*/
exports.init = function(parser) {
this.parser = parser;
// Regexp to match
this.matchRegExp = /^\\parsermode[^\S\n]/mg;
};
/*
Parse the most recent match
*/
exports.parse = function() {
// Move past the pragma invocation
this.parser.pos = this.matchRegExp.lastIndex;
// Parse whitespace delimited tokens terminated by a line break
var reMatch = /[^\S\n]*(\S+)|(\r?\n)/mg,
parserMode = undefined;
reMatch.lastIndex = this.parser.pos;
var match = reMatch.exec(this.parser.source);
while(match && match.index === this.parser.pos) {
this.parser.pos = reMatch.lastIndex;
// Exit if we've got the line break
if(match[2]) {
break;
}
// Process the token
if(match[1]) {
parserMode = match[1];
}
// Match the next token
match = reMatch.exec(this.parser.source);
}
// Process the tokens
if(parserMode !== undefined) {
if(parserMode === "block") {
this.parser.parseAsInline = false;
} else if(parserMode === "inline") {
this.parser.parseAsInline = true;
}
}
// No parse tree nodes to return
return [];
};
})();

View File

@@ -41,9 +41,6 @@ exports.parse = function() {
var node = {
type: "element",
tag: "span",
attributes: {
"class": {type: "string", value: "tc-inline-style"}
},
children: tree
};
if(classString) {
@@ -52,6 +49,9 @@ exports.parse = function() {
if(stylesString) {
$tw.utils.addAttributeToParseTreeNode(node,"style",stylesString);
}
if(!classString && !stylesString) {
$tw.utils.addClassToParseTreeNode(node,"tc-inline-style");
}
return [node];
};

View File

@@ -47,6 +47,8 @@ var WikiParser = function(type,text,options) {
this.sourceLength = this.source.length;
// Flag for ignoring whitespace
this.configTrimWhiteSpace = false;
// Parser mode
this.parseAsInline = options.parseAsInline;
// Set current parse position
this.pos = 0;
// Start with empty output
@@ -83,7 +85,7 @@ var WikiParser = function(type,text,options) {
// Parse any pragmas
var topBranch = this.parsePragmas();
// Parse the text into inline runs or blocks
if(options.parseAsInline) {
if(this.parseAsInline) {
topBranch.push.apply(topBranch,this.parseInlineRun());
} else {
topBranch.push.apply(topBranch,this.parseBlocks());
@@ -116,7 +118,7 @@ WikiParser.prototype.loadRemoteTiddler = function(url) {
*/
WikiParser.prototype.setupRules = function(proto,configPrefix) {
var self = this;
if(!$tw.safemode) {
if(!$tw.safeMode) {
$tw.utils.each(proto,function(object,name) {
if(self.wiki.getTiddlerText(configPrefix + name,"enable") !== "enable") {
delete proto[name];

View File

@@ -30,6 +30,16 @@ exports.handler = function(request,response,state) {
if(fields.revision) {
delete fields.revision;
}
// If this is a skinny tiddler, it means the client never got the full
// version of the tiddler to edit. So we must preserve whatever text
// already exists on the server, or else we'll inadvertently delete it.
if(fields._is_skinny !== undefined) {
var tiddler = state.wiki.getTiddler(title);
if(tiddler) {
fields.text = tiddler.fields.text;
}
delete fields._is_skinny;
}
state.wiki.addTiddler(new $tw.Tiddler(fields,{title: title}));
var changeCount = state.wiki.getChangeCount(title).toString();
response.writeHead(204, "OK",{

View File

@@ -121,7 +121,11 @@ exports.startup = function() {
});
// Set up the syncer object if we've got a syncadaptor
if($tw.syncadaptor) {
$tw.syncer = new $tw.Syncer({wiki: $tw.wiki, syncadaptor: $tw.syncadaptor});
$tw.syncer = new $tw.Syncer({
wiki: $tw.wiki,
syncadaptor: $tw.syncadaptor,
logging: $tw.wiki.getTiddlerText('$:/config/SyncLogging', "yes") === "yes"
});
}
// Setup the saver handler
$tw.saverHandler = new $tw.SaverHandler({

View File

@@ -12,35 +12,113 @@ A barebones CSV parser
/*global $tw: false */
"use strict";
var QUOTE = '"';
var getCellInfo = function(text, start, length, SEPARATOR) {
var isCellQuoted = text.charAt(start) === QUOTE;
var cellStart = isCellQuoted ? start + 1 : start;
if (text.charAt(i) === SEPARATOR) {
return [cellStart, cellStart, false];
}
for (var i = cellStart; i < length; i++) {
var cellCharacter = text.charAt(i);
var isEOL = cellCharacter === "\n" || cellCharacter === "\r";
if (isEOL && !isCellQuoted) {
return [cellStart, i, false];
} else if (cellCharacter === SEPARATOR && !isCellQuoted) {
return [cellStart, i, false];
} else if (cellCharacter === QUOTE && isCellQuoted) {
var nextCharacter = i + 1 < length ? text.charAt(i + 1) : '';
if (nextCharacter !== QUOTE) {
return [cellStart, i, true];
} else {
i++;
}
}
}
return [cellStart, i, isCellQuoted];
}
exports.parseCsvString = function(text, options) {
if (!text) {
return [];
}
options = options || {};
var SEPARATOR = options.separator || ",",
length = text.length,
rows = [],
nextRow = [];
for (var i = 0; i < length; i++) {
var cellInfo = getCellInfo(text, i, length, SEPARATOR);
var cellText = text.substring(cellInfo[0], cellInfo[1]);
if (cellInfo[2]) {
cellText = cellText.replace(/""/g, '"');
cellInfo[1]++;
}
nextRow.push(cellText);
i = cellInfo[1];
var character = text.charAt(i);
var nextCharacter = i + 1 < length ? text.charAt(i + 1) : '';
if (character === "\r" || character === "\n") {
// Edge case for empty rows
if (nextRow.length === 1 && nextRow[0] === '') {
nextRow.length = 0;
}
rows.push(nextRow);
nextRow = [];
if (character === "\r") {
var nextCharacter = i + 1 < length ? text.charAt(i + 1) : '';
if (nextCharacter === "\n") {
i++;
}
}
}
}
// Special case if last cell in last row is an empty cell
if (text.charAt(length - 1) === SEPARATOR) {
nextRow.push("");
}
rows.push(nextRow);
return rows;
}
/*
Parse a CSV string with a header row and return an array of hashmaps.
*/
exports.parseCsvStringWithHeader = function(text,options) {
options = options || {};
var separator = options.separator || ",",
rows = text.split(/\r?\n/mg).map(function(row) {
return $tw.utils.trim(row);
}).filter(function(row) {
return row !== "";
});
if(rows.length < 1) {
return "Missing header row";
}
var headings = rows[0].split(separator),
results = [];
for(var row=1; row<rows.length; row++) {
var columns = rows[row].split(separator),
columnResult = Object.create(null);
if(columns.length !== headings.length) {
return "Malformed CSV row '" + rows[row] + "'";
var csv = $tw.utils.parseCsvString(text, options);
var headers = csv[0];
csv = csv.slice(1);
for (var i = 0; i < csv.length; i++) {
var row = csv[i];
var rowObject = Object.create(null);
for(var columnIndex=0; columnIndex<headers.length; columnIndex++) {
var columnName = headers[columnIndex];
if (columnName) {
rowObject[columnName] = $tw.utils.trim(row[columnIndex] || "");
}
}
for(var column=0; column<columns.length; column++) {
var columnName = headings[column];
columnResult[columnName] = $tw.utils.trim(columns[column] || "");
}
results.push(columnResult);
csv[i] = rowObject;
}
return results;
return csv;
}
})();

View File

@@ -12,6 +12,8 @@ Various static DOM-related utility functions.
/*global $tw: false */
"use strict";
var Popup = require("$:/core/modules/utils/dom/popup.js");
/*
Determines whether element 'a' contains element 'b'
Code thanks to John Resig, http://ejohn.org/blog/comparing-document-position/
@@ -294,8 +296,21 @@ exports.collectDOMVariables = function(selectedNode,domNode,event) {
});
if(selectedNode.offsetLeft) {
// Add a variable with a popup coordinate string for the selected node
variables["tv-popup-coords"] = "(" + selectedNode.offsetLeft + "," + selectedNode.offsetTop +"," + selectedNode.offsetWidth + "," + selectedNode.offsetHeight + ")";
// Add variables with a (relative and absolute) popup coordinate string for the selected node
var nodeRect = {
left: selectedNode.offsetLeft,
top: selectedNode.offsetTop,
width: selectedNode.offsetWidth,
height: selectedNode.offsetHeight
};
variables["tv-popup-coords"] = Popup.buildCoordinates(Popup.coordinatePrefix.csOffsetParent,nodeRect);
var absRect = $tw.utils.extend({}, nodeRect);
for (var currentNode = selectedNode.offsetParent; currentNode; currentNode = currentNode.offsetParent) {
absRect.left += currentNode.offsetLeft;
absRect.top += currentNode.offsetTop;
}
variables["tv-popup-abs-coords"] = Popup.buildCoordinates(Popup.coordinatePrefix.csAbsolute,absRect);
// Add variables for offset of selected node
variables["tv-selectednode-posx"] = selectedNode.offsetLeft.toString();

View File

@@ -26,6 +26,8 @@ Display a modal dialogue
options: see below
Options include:
downloadLink: Text of a big download link to include
event: widget event
variables: from event.paramObject
*/
Modal.prototype.display = function(title,options) {
options = options || {};
@@ -209,6 +211,10 @@ Modal.prototype.display = function(title,options) {
headerWidgetNode.addEventListener("tm-close-tiddler",closeHandler,false);
bodyWidgetNode.addEventListener("tm-close-tiddler",closeHandler,false);
footerWidgetNode.addEventListener("tm-close-tiddler",closeHandler,false);
// Whether to close the modal dialog when the mask (area outside the modal) is clicked
if(tiddler.fields && (tiddler.fields["mask-closable"] === "yes" || tiddler.fields["mask-closable"] === "true")) {
modalBackdrop.addEventListener("click",closeHandler,false);
}
// Set the initial styles for the message
$tw.utils.setStyle(modalBackdrop,[
{opacity: "0"}

View File

@@ -22,6 +22,19 @@ var Popup = function(options) {
this.popups = []; // Array of {title:,wiki:,domNode:} objects
};
/*
Global regular expression for parsing the location of a popup.
This is also used by the Reveal widget.
*/
exports.popupLocationRegExp = /^(@?)\((-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+)\)$/
/*
Objekt containing the available prefixes for coordinates build with the `buildCoordinates` function:
- csOffsetParent: Uses a coordinate system based on the offset parent (no prefix).
- csAbsolute: Use an absolute coordinate system (prefix "@").
*/
exports.coordinatePrefix = { csOffsetParent: "", csAbsolute: "@" }
/*
Trigger a popup open or closed. Parameters are in a hashmap:
title: title of the tiddler where the popup details are stored
@@ -136,8 +149,17 @@ Popup.prototype.show = function(options) {
height: options.domNode.offsetHeight
};
}
var popupRect = "(" + rect.left + "," + rect.top + "," +
rect.width + "," + rect.height + ")";
if(options.absolute && options.domNode) {
// Walk the offsetParent chain and add the position of the offsetParents to make
// the position absolute to the root node of the page.
var currentNode = options.domNode.offsetParent;
while(currentNode) {
rect.left += currentNode.offsetLeft;
rect.top += currentNode.offsetTop;
currentNode = currentNode.offsetParent;
}
}
var popupRect = exports.buildCoordinates(options.absolute?exports.coordinatePrefix.csAbsolute:exports.coordinatePrefix.csOffsetParent,rect);
if(options.noStateReference) {
options.wiki.setText(options.title,"text",undefined,popupRect);
} else {
@@ -172,13 +194,54 @@ Popup.prototype.cancel = function(level) {
};
/*
Returns true if the specified title and text identifies an active popup
Returns true if the specified title and text identifies an active popup.
This function is safe to call, even if the popup class was not initialized.
*/
Popup.prototype.readPopupState = function(text) {
var popupLocationRegExp = /^\((-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+)\)$/;
return popupLocationRegExp.test(text);
exports.readPopupState = function(text) {
return exports.popupLocationRegExp.test(text);
};
/*
Parses a coordinate string in the format `(x,y,w,h)` or `@(x,y,z,h)` and returns
an object containing the position, width and height. The absolute-Mark is boolean
value that indicates the coordinate system of the coordinates. If they start with
an `@`, `absolute` is set to true and the coordinates are relative to the root
element. If the initial `@` is missing, they are relative to the offset parent
element and `absoute` is false.
This function is safe to call, even if the popup class was not initialized.
*/
exports.parseCoordinates = function(coordinates) {
var match = exports.popupLocationRegExp.exec(coordinates);
if(match) {
return {
absolute: (match[1] === "@"),
left: parseFloat(match[2]),
top: parseFloat(match[3]),
width: parseFloat(match[4]),
height: parseFloat(match[5])
};
} else {
return false;
}
}
/*
Builds a coordinate string from a coordinate system identifier and an object
containing the left, top, width and height values.
Use constants defined in coordinatePrefix to specify a coordinate system.
If one of the parameters is invalid for building a coordinate string `(0,0,0,0)`
will be returned.
This function is safe to call, even if the popup class was not initialized.
*/
exports.buildCoordinates = function(prefix,position) {
var coord = prefix + "(" + position.left + "," + position.top + "," + position.width + "," + position.height + ")";
if (exports.popupLocationRegExp.test(coord)) {
return coord;
} else {
return "(0,0,0,0)";
}
}
exports.Popup = Popup;
})();

View File

@@ -42,7 +42,7 @@ var TW_TextNode = function(text) {
this.textContent = text + "";
};
TW_TextNode.prototype = Object.create(TW_Node.prototype);
Object.setPrototypeOf(TW_TextNode,TW_Node.prototype);
Object.defineProperty(TW_TextNode.prototype, "nodeType", {
get: function() {
@@ -67,7 +67,7 @@ var TW_Element = function(tag,namespace) {
this.namespaceURI = namespace || "http://www.w3.org/1999/xhtml";
};
TW_Element.prototype = Object.create(TW_Node.prototype);
Object.setPrototypeOf(TW_Element,TW_Node.prototype);
Object.defineProperty(TW_Element.prototype, "style", {
get: function() {

View File

@@ -15,10 +15,11 @@ function LinkedList() {
LinkedList.prototype.clear = function() {
// LinkedList performs the duty of both the head and tail node
this.next = Object.create(null);
this.prev = Object.create(null);
this.first = undefined;
this.last = undefined;
this.next = new LLMap();
this.prev = new LLMap();
// Linked list head initially points to itself
this.next.set(null, null);
this.prev.set(null, null);
this.length = 0;
};
@@ -41,28 +42,29 @@ Push behaves like array.push and accepts multiple string arguments. But it also
accepts a single array argument too, to be consistent with its other methods.
*/
LinkedList.prototype.push = function(/* values */) {
var values = arguments;
var i, values = arguments;
if($tw.utils.isArray(values[0])) {
values = values[0];
}
for(var i = 0; i < values.length; i++) {
for(i = 0; i < values.length; i++) {
_assertString(values[i]);
}
for(var i = 0; i < values.length; i++) {
for(i = 0; i < values.length; i++) {
_linkToEnd(this,values[i]);
}
return this.length;
};
LinkedList.prototype.pushTop = function(value) {
var t;
if($tw.utils.isArray(value)) {
for (var t=0; t<value.length; t++) {
for (t=0; t<value.length; t++) {
_assertString(value[t]);
}
for(var t=0; t<value.length; t++) {
for(t=0; t<value.length; t++) {
_removeOne(this,value[t]);
}
for(var t=0; t<value.length; t++) {
for(t=0; t<value.length; t++) {
_linkToEnd(this,value[t]);
}
} else {
@@ -74,11 +76,11 @@ LinkedList.prototype.pushTop = function(value) {
LinkedList.prototype.each = function(callback) {
var visits = Object.create(null),
value = this.first;
while(value !== undefined) {
value = this.next.get(null);
while(value !== null) {
callback(value);
var next = this.next[value];
if(typeof next === "object") {
var next = this.next.get(value);
if(Array.isArray(next)) {
var i = visits[value] || 0;
visits[value] = i+1;
value = next[i];
@@ -105,91 +107,79 @@ LinkedList.prototype.makeTiddlerIterator = function(wiki) {
};
function _removeOne(list,value) {
var prevEntry = list.prev[value],
nextEntry = list.next[value],
var nextEntry = list.next.get(value);
if(nextEntry === undefined) {
return;
}
var prevEntry = list.prev.get(value),
prev = prevEntry,
next = nextEntry;
if(typeof nextEntry === "object") {
next = nextEntry,
ref;
if(Array.isArray(nextEntry)) {
next = nextEntry[0];
prev = prevEntry[0];
}
// Relink preceding element.
if(list.first === value) {
list.first = next
} else if(prev !== undefined) {
if(typeof list.next[prev] === "object") {
if(next === undefined) {
// Must have been last, and 'i' would be last element.
list.next[prev].pop();
} else {
var i = list.next[prev].indexOf(value);
list.next[prev][i] = next;
}
} else {
list.next[prev] = next;
}
ref = list.next.get(prev);
if(Array.isArray(ref)) {
var i = ref.indexOf(value);
ref[i] = next;
} else {
return;
list.next.set(prev,next);
}
// Now relink following element
// Check "next !== undefined" rather than "list.last === value" because
// we need to know if the FIRST value is the last in the list, not the last.
if(next !== undefined) {
if(typeof list.prev[next] === "object") {
if(prev === undefined) {
// Must have been first, and 'i' would be 0.
list.prev[next].shift();
} else {
var i = list.prev[next].indexOf(value);
list.prev[next][i] = prev;
}
} else {
list.prev[next] = prev;
}
ref = list.prev.get(next);
if(Array.isArray(ref)) {
var i = ref.indexOf(value);
ref[i] = prev;
} else {
list.last = prev;
list.prev.set(next,prev);
}
// Delink actual value. If it uses arrays, just remove first entries.
if(typeof nextEntry === "object") {
if(Array.isArray(nextEntry) && nextEntry.length > 1) {
nextEntry.shift();
prevEntry.shift();
} else {
list.next[value] = undefined;
list.prev[value] = undefined;
list.next.set(value,undefined);
list.prev.set(value,undefined);
}
list.length -= 1;
};
// Sticks the given node onto the end of the list.
function _linkToEnd(list,value) {
if(list.first === undefined) {
list.first = value;
var old = list.next.get(value);
var last = list.prev.get(null);
// Does it already exists?
if(old !== undefined) {
if(!Array.isArray(old)) {
old = [old];
list.next.set(value,old);
list.prev.set(value,[list.prev.get(value)]);
}
old.push(null);
list.prev.get(value).push(last);
} else {
// Does it already exists?
if(list.first === value || list.prev[value] !== undefined) {
if(typeof list.next[value] === "string") {
list.next[value] = [list.next[value]];
list.prev[value] = [list.prev[value]];
} else if(typeof list.next[value] === "undefined") {
// list.next[value] must be undefined.
// Special case. List already has 1 value. It's at the end.
list.next[value] = [];
list.prev[value] = [list.prev[value]];
}
list.prev[value].push(list.last);
// We do NOT append a new value onto "next" list. Iteration will
// figure out it must point to End-of-List on its own.
} else {
list.prev[value] = list.last;
}
// Make the old last point to this new one.
if(typeof list.next[list.last] === "object") {
list.next[list.last].push(value);
} else {
list.next[list.last] = value;
}
list.next.set(value,null);
list.prev.set(value,last);
}
// Make the old last point to this new one.
if(value !== last) {
var array = list.next.get(last);
if(Array.isArray(array)) {
array[array.length-1] = value;
} else {
list.next.set(last,value);
}
list.prev.set(null,value);
} else {
// Edge case, the pushed value was already the last value.
// The second-to-last nextPtr for that value must point to itself now.
var array = list.next.get(last);
array[array.length-2] = value;
}
list.last = value;
list.length += 1;
};
@@ -199,6 +189,20 @@ function _assertString(value) {
}
};
var LLMap = function() {
this.map = Object.create(null);
};
// Just a wrapper so our object map can also accept null.
LLMap.prototype = {
set: function(key,val) {
(key === null) ? (this.null = val) : (this.map[key] = val);
},
get: function(key) {
return (key === null) ? this.null : this.map[key];
}
};
exports.LinkedList = LinkedList;
})();

View File

@@ -48,7 +48,9 @@ Logger.prototype.log = function(/* args */) {
this.saveBufferLogger.buffer = this.saveBufferLogger.buffer.slice(-this.saveBufferLogger.saveLimit);
}
if(console !== undefined && console.log !== undefined) {
return Function.apply.call(console.log, console, [$tw.utils.terminalColour(this.colour),this.componentName + ":"].concat(Array.prototype.slice.call(arguments,0)).concat($tw.utils.terminalColour()));
var logMessage = [$tw.utils.terminalColour(this.colour) + this.componentName + ":"].concat(Array.prototype.slice.call(arguments,0));
logMessage[logMessage.length-1] += $tw.utils.terminalColour();
return Function.apply.call(console.log, console, logMessage);
}
}
};

View File

@@ -12,12 +12,26 @@ Parse tree utility functions.
/*global $tw: false */
"use strict";
/*
Add attribute to parse tree node
Can be invoked as (node,name,value) or (node,attr)
*/
exports.addAttributeToParseTreeNode = function(node,name,value) {
var attribute = {name: name, type: "string", value: value};
var attribute = typeof name === "object" ? name : {name: name, type: "string", value: value};
name = attribute.name;
node.attributes = node.attributes || {};
node.orderedAttributes = node.orderedAttributes || [];
node.attributes[name] = attribute;
if(node.orderedAttributes) {
var foundIndex = -1;
$tw.utils.each(node.orderedAttributes,function(attr,index) {
if(attr.name === name) {
foundIndex = index;
}
});
if(foundIndex === -1) {
node.orderedAttributes.push(attribute);
} else {
node.orderedAttributes[foundIndex] = attribute;
}
};
@@ -51,10 +65,8 @@ exports.addClassToParseTreeNode = function(node,classString) {
// If the class attribute does not exist, we must create it first.
attribute = {name: "class", type: "string", value: ""};
node.attributes["class"] = attribute;
if(node.orderedAttributes) {
// If there are orderedAttributes, we've got to add them there too.
node.orderedAttributes.push(attribute);
}
node.orderedAttributes = node.orderedAttributes || [];
node.orderedAttributes.push(attribute);
}
if(attribute.type === "string") {
if(attribute.value !== "") {
@@ -74,10 +86,8 @@ exports.addStyleToParseTreeNode = function(node,name,value) {
if(!attribute) {
attribute = {name: "style", type: "string", value: ""};
node.attributes.style = attribute;
if(node.orderedAttributes) {
// If there are orderedAttributes, we've got to add them there too.
node.orderedAttributes.push(attribute);
}
node.orderedAttributes = node.orderedAttributes || [];
node.orderedAttributes.push(attribute);
}
if(attribute.type === "string") {
attribute.value += name + ":" + value + ";";

View File

@@ -354,6 +354,9 @@ exports.formatDateString = function(date,template) {
var result = "",
t = template,
matches = [
[/^TIMESTAMP/, function() {
return date.getTime();
}],
[/^0hh12/, function() {
return $tw.utils.pad($tw.utils.getHours12(date));
}],

View File

@@ -36,7 +36,7 @@ Compute the internal state of the widget
*/
DeleteFieldWidget.prototype.execute = function() {
this.actionTiddler = this.getAttribute("$tiddler",this.getVariable("currentTiddler"));
this.actionField = this.getAttribute("$field");
this.actionField = this.getAttribute("$field",null);
};
/*
@@ -59,7 +59,7 @@ DeleteFieldWidget.prototype.invokeAction = function(triggeringWidget,event) {
tiddler = this.wiki.getTiddler(self.actionTiddler),
removeFields = {},
hasChanged = false;
if(this.actionField && tiddler) {
if((this.actionField !== null) && tiddler) {
removeFields[this.actionField] = undefined;
if(this.actionField in tiddler.fields) {
hasChanged = true;

View File

@@ -14,6 +14,8 @@ Action widget to trigger a popup.
var Widget = require("$:/core/modules/widgets/widget.js").widget;
var Popup = require("$:/core/modules/utils/dom/popup.js");
var ActionPopupWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options);
};
@@ -57,20 +59,20 @@ Invoke the action associated with this widget
*/
ActionPopupWidget.prototype.invokeAction = function(triggeringWidget,event) {
// Trigger the popup
var popupLocationRegExp = /^\((-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+)\)$/,
match = popupLocationRegExp.exec(this.actionCoords || "");
if(match) {
var coordinates = Popup.parseCoordinates(this.actionCoords || "");
if(coordinates) {
$tw.popup.triggerPopup({
domNode: null,
domNodeRect: {
left: parseFloat(match[1]),
top: parseFloat(match[2]),
width: parseFloat(match[3]),
height: parseFloat(match[4])
left: coordinates.left,
top: coordinates.top,
width: coordinates.width,
height: coordinates.height
},
title: this.actionState,
wiki: this.wiki,
floating: this.floating
floating: this.floating,
absolute: coordinates.absolute
});
} else {
$tw.popup.cancel(0);

View File

@@ -14,6 +14,8 @@ Button widget
var Widget = require("$:/core/modules/widgets/widget.js").widget;
var Popup = require("$:/core/modules/utils/dom/popup.js");
var ButtonWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options);
};
@@ -147,7 +149,7 @@ ButtonWidget.prototype.isSelected = function() {
ButtonWidget.prototype.isPoppedUp = function() {
var tiddler = this.popupTitle ? this.wiki.getTiddler(this.popupTitle) : this.wiki.getTiddler(this.popup);
var result = tiddler && tiddler.fields.text ? $tw.popup.readPopupState(tiddler.fields.text) : false;
var result = tiddler && tiddler.fields.text ? Popup.readPopupState(tiddler.fields.text) : false;
return result;
};
@@ -173,6 +175,7 @@ ButtonWidget.prototype.triggerPopup = function(event) {
if(this.popupTitle) {
$tw.popup.triggerPopup({
domNode: this.domNodes[0],
absolute: (this.popupAbsCoords === "yes"),
title: this.popupTitle,
wiki: this.wiki,
noStateReference: true
@@ -180,6 +183,7 @@ ButtonWidget.prototype.triggerPopup = function(event) {
} else {
$tw.popup.triggerPopup({
domNode: this.domNodes[0],
absolute: (this.popupAbsCoords === "yes"),
title: this.popup,
wiki: this.wiki
});
@@ -223,6 +227,7 @@ ButtonWidget.prototype.execute = function() {
this.setField = this.getAttribute("setField");
this.setIndex = this.getAttribute("setIndex");
this.popupTitle = this.getAttribute("popupTitle");
this.popupAbsCoords = this.getAttribute("popupAbsCoords", "no");
this.tabIndex = this.getAttribute("tabindex");
this.isDisabled = this.getAttribute("disabled","no");
// Make child widgets
@@ -252,7 +257,7 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
*/
ButtonWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(changedAttributes.actions || changedAttributes.to || changedAttributes.message || changedAttributes.param || changedAttributes.set || changedAttributes.setTo || changedAttributes.popup || changedAttributes.hover || changedAttributes.selectedClass || changedAttributes.style || changedAttributes.dragFilter || changedAttributes.dragTiddler || (this.set && changedTiddlers[this.set]) || (this.popup && changedTiddlers[this.popup]) || (this.popupTitle && changedTiddlers[this.popupTitle]) || changedAttributes.setTitle || changedAttributes.setField || changedAttributes.setIndex || changedAttributes.popupTitle || changedAttributes.disabled || changedAttributes["default"]) {
if(changedAttributes.actions || changedAttributes.to || changedAttributes.message || changedAttributes.param || changedAttributes.set || changedAttributes.setTo || changedAttributes.popup || changedAttributes.hover || changedAttributes.selectedClass || changedAttributes.style || changedAttributes.dragFilter || changedAttributes.dragTiddler || (this.set && changedTiddlers[this.set]) || (this.popup && changedTiddlers[this.popup]) || (this.popupTitle && changedTiddlers[this.popupTitle]) || changedAttributes.popupAbsCoords || changedAttributes.setTitle || changedAttributes.setField || changedAttributes.setIndex || changedAttributes.popupTitle || changedAttributes.disabled || changedAttributes["default"]) {
this.refreshSelf();
return true;
} else if(changedAttributes["class"]) {

View File

@@ -66,14 +66,14 @@ CheckboxWidget.prototype.render = function(parent,nextSibling) {
CheckboxWidget.prototype.getValue = function() {
var tiddler = this.wiki.getTiddler(this.checkboxTitle);
if(tiddler || this.checkboxFilter) {
if(this.checkboxTag) {
if(tiddler && this.checkboxTag) {
if(this.checkboxInvertTag === "yes") {
return !tiddler.hasTag(this.checkboxTag);
} else {
return tiddler.hasTag(this.checkboxTag);
}
}
if(this.checkboxField || this.checkboxIndex) {
if(tiddler && (this.checkboxField || this.checkboxIndex)) {
// Same logic applies to fields and indexes
var value;
if(this.checkboxField) {
@@ -206,11 +206,18 @@ CheckboxWidget.prototype.handleChangeEvent = function(event) {
}
// Set the list field (or index) if specified
if(this.checkboxListField || this.checkboxListIndex) {
var listContents, oldPos, newPos;
var fieldContents, listContents, oldPos, newPos;
if(this.checkboxListField) {
listContents = tiddler.getFieldList(this.checkboxListField);
fieldContents = tiddler ? tiddler.fields[this.checkboxListField] : undefined;
} else {
listContents = $tw.utils.parseStringArray(this.wiki.extractTiddlerDataItem(this.checkboxTitle,this.checkboxListIndex) || "") || [];
fieldContents = this.wiki.extractTiddlerDataItem(this.checkboxTitle,this.checkboxListIndex);
}
if($tw.utils.isArray(fieldContents)) {
// Make a copy so we can modify it without changing original that's refrenced elsewhere
listContents = fieldContents.slice(0);
} else {
listContents = $tw.utils.parseStringArray(fieldContents) || [];
// No need to copy since parseStringArray returns a fresh array, not refrenced elsewhere
}
oldPos = notValue ? listContents.indexOf(notValue) : -1;
newPos = value ? listContents.indexOf(value) : -1;

View File

@@ -0,0 +1,63 @@
/*\
title: $:/core/modules/widgets/error.js
type: application/javascript
module-type: widget
Error widget
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var Widget = require("$:/core/modules/widgets/widget.js").widget;
var ErrorWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options);
};
/*
Inherit from the base widget class
*/
ErrorWidget.prototype = new Widget();
/*
Render this widget into the DOM
*/
ErrorWidget.prototype.render = function(parent,nextSibling) {
this.parentDomNode = parent;
this.computeAttributes();
this.execute();
var message = this.getAttribute("$message","Unknown error"),
domNode = this.document.createElement("span");
domNode.appendChild(this.document.createTextNode(message));
domNode.className = "tc-error";
parent.insertBefore(domNode,nextSibling);
this.domNodes.push(domNode);
};
/*
Compute the internal state of the widget
*/
ErrorWidget.prototype.execute = function() {
// Nothing to do for a text node
};
/*
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/
ErrorWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(changedAttributes["$message"]) {
this.refreshSelf();
return true;
} else {
return false;
}
};
exports.error = ErrorWidget;
})();

View File

@@ -0,0 +1,108 @@
/*\
title: $:/core/modules/widgets/genesis.js
type: application/javascript
module-type: widget
Genesis widget for dynamically creating widgets
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var Widget = require("$:/core/modules/widgets/widget.js").widget;
var GenesisWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options);
};
/*
Inherit from the base widget class
*/
GenesisWidget.prototype = new Widget();
/*
Render this widget into the DOM
*/
GenesisWidget.prototype.render = function(parent,nextSibling) {
this.parentDomNode = parent;
this.computeAttributes({filterFn: function(name) {
// Only compute our own attributes which start with a single dollar
return name.charAt(0) === "$" && name.charAt(1) !== "$";
}});
this.execute();
this.renderChildren(parent,nextSibling);
};
/*
Compute the internal state of the widget
*/
GenesisWidget.prototype.execute = function() {
var self = this;
// Collect attributes
this.genesisType = this.getAttribute("$type","element");
this.genesisRemappable = this.getAttribute("$remappable","yes") === "yes";
this.genesisNames = this.getAttribute("$names","");
this.genesisValues = this.getAttribute("$values","");
// Construct parse tree
var isElementWidget = this.genesisType.charAt(0) !== "$",
nodeType = isElementWidget ? "element" : this.genesisType.substr(1),
nodeTag = isElementWidget ? this.genesisType : undefined;
var parseTreeNodes = [{
type: nodeType,
tag: nodeTag,
attributes: {},
orderedAttributes: [],
children: this.parseTreeNode.children || [],
isNotRemappable: !this.genesisRemappable
}];
// Apply explicit attributes
$tw.utils.each($tw.utils.getOrderedAttributesFromParseTreeNode(this.parseTreeNode),function(attribute) {
var name = attribute.name;
if(name.charAt(0) === "$") {
if(name.charAt(1) === "$") {
// Double $$ is changed to a single $
name = name.substr(1);
} else {
// Single dollar is ignored
return;
}
}
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],$tw.utils.extend({},attribute,{name: name}));
});
// Apply attributes in $names/$values
this.attributeNames = [];
this.attributeValues = [];
if(this.genesisNames && this.genesisValues) {
this.attributeNames = this.wiki.filterTiddlers(self.genesisNames,this);
this.attributeValues = this.wiki.filterTiddlers(self.genesisValues,this);
$tw.utils.each(this.attributeNames,function(varname,index) {
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],varname,self.attributeValues[index] || "");
});
}
// Construct the child widgets
this.makeChildWidgets(parseTreeNodes);
};
/*
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/
GenesisWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes(),
filterNames = this.getAttribute("$names",""),
filterValues = this.getAttribute("$values",""),
attributeNames = this.wiki.filterTiddlers(filterNames,this),
attributeValues = this.wiki.filterTiddlers(filterValues,this);
if($tw.utils.count(changedAttributes) > 0 || !$tw.utils.isArrayEqual(this.attributeNames,attributeNames) || !$tw.utils.isArrayEqual(this.attributeValues,attributeValues)) {
this.refreshSelf();
return true;
} else {
return this.refreshChildren(changedTiddlers);
}
};
exports.genesis = GenesisWidget;
})();

View File

@@ -39,7 +39,10 @@ Compute the internal state of the widget
ImportVariablesWidget.prototype.execute = function(tiddlerList) {
var widgetPointer = this;
// Got to flush all the accumulated variables
this.variables = new this.variablesConstructor();
this.variables = Object.create(null);
if(this.parentWidget) {
Object.setPrototypeOf(this.variables,this.parentWidget.variables);
}
// Get our parameters
this.filter = this.getAttribute("filter");
// Compute the filter

View File

@@ -53,6 +53,10 @@ KeyboardWidget.prototype.render = function(parent,nextSibling) {
};
KeyboardWidget.prototype.handleChangeEvent = function(event) {
if ($tw.keyboardManager.handleKeydownEvent(event, {onlyPriority: true})) {
return true;
}
var keyInfo = $tw.keyboardManager.getMatchingKeyDescriptor(event,this.keyInfoArray);
if(keyInfo) {
var handled = this.invokeActions(this,event);

View File

@@ -51,11 +51,9 @@ LetWidget.prototype.computeAttributes = function() {
$tw.utils.each($tw.utils.getOrderedAttributesFromParseTreeNode(this.parseTreeNode),function(attribute) {
var value = self.computeAttribute(attribute),
name = attribute.name;
if(name.charAt(0) !== "$") {
// Now that it's prepped, we're allowed to look this variable up
// when defining later variables
self.currentValueFor[name] = value;
}
// Now that it's prepped, we're allowed to look this variable up
// when defining later variables
self.currentValueFor[name] = value;
});
// Run through again, setting variables and looking for differences
$tw.utils.each(this.currentValueFor,function(value,name) {

View File

@@ -14,6 +14,8 @@ Reveal widget
var Widget = require("$:/core/modules/widgets/widget.js").widget;
var Popup = require("$:/core/modules/utils/dom/popup.js");
var RevealWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options);
};
@@ -94,6 +96,13 @@ RevealWidget.prototype.positionPopup = function(domNode) {
left = Math.max(0,left);
top = Math.max(0,top);
}
if (this.popup.absolute) {
// Traverse the offsetParent chain and correct the offset to make it relative to the parent node.
for (var offsetParentDomNode = domNode.offsetParent; offsetParentDomNode; offsetParentDomNode = offsetParentDomNode.offsetParent) {
left -= offsetParentDomNode.offsetLeft;
top -= offsetParentDomNode.offsetTop;
}
}
domNode.style.left = left + "px";
domNode.style.top = top + "px";
};
@@ -183,19 +192,11 @@ RevealWidget.prototype.compareStateText = function(state) {
};
RevealWidget.prototype.readPopupState = function(state) {
var popupLocationRegExp = /^\((-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+)\)$/,
match = popupLocationRegExp.exec(state);
this.popup = Popup.parseCoordinates(state);
// Check if the state matches the location regexp
if(match) {
if(this.popup) {
// If so, we're open
this.isOpen = true;
// Get the location
this.popup = {
left: parseFloat(match[1]),
top: parseFloat(match[2]),
width: parseFloat(match[3]),
height: parseFloat(match[4])
};
} else {
// If not, we're closed
this.isOpen = false;

View File

@@ -42,6 +42,9 @@ SelectWidget.prototype.render = function(parent,nextSibling) {
this.execute();
this.renderChildren(parent,nextSibling);
this.setSelectValue();
if(this.selectFocus == "yes") {
this.getSelectDomNode().focus();
}
$tw.utils.addEventListeners(this.getSelectDomNode(),[
{name: "change", handlerObject: this, handlerMethod: "handleChangeEvent"}
]);
@@ -143,6 +146,7 @@ SelectWidget.prototype.execute = function() {
this.selectMultiple = this.getAttribute("multiple", false);
this.selectSize = this.getAttribute("size");
this.selectTooltip = this.getAttribute("tooltip");
this.selectFocus = this.getAttribute("focus");
// Make the child widgets
var selectNode = {
type: "element",
@@ -175,6 +179,11 @@ SelectWidget.prototype.refresh = function(changedTiddlers) {
return true;
// If the target tiddler value has changed, just update setting and refresh the children
} else {
if(changedAttributes.class) {
this.selectClass = this.getAttribute("class");
this.getSelectDomNode().setAttribute("class",this.selectClass);
}
var childrenRefreshed = this.refreshChildren(changedTiddlers);
if(changedTiddlers[this.selectTitle] || childrenRefreshed) {
this.setSelectValue();

View File

@@ -70,11 +70,9 @@ TranscludeWidget.prototype.execute = function() {
// Check for recursion
if(parser) {
if(this.parentWidget && this.parentWidget.hasVariable("transclusion",recursionMarker)) {
parseTreeNodes = [{type: "element", tag: "span", attributes: {
"class": {type: "string", value: "tc-error"}
}, children: [
{type: "text", text: $tw.language.getString("Error/RecursiveTransclusion")}
]}];
parseTreeNodes = [{type: "error", attributes: {
"$message": {type: "string", value: $tw.language.getString("Error/RecursiveTransclusion")}
}}];
}
}
// Construct the child widgets

View File

@@ -12,6 +12,9 @@ Widget base class
/*global $tw: false */
"use strict";
/* Maximum permitted depth of the widget tree for recursion detection */
var MAX_WIDGET_TREE_DEPTH = 1000;
/*
Create a widget object for a parse tree node
parseTreeNode: reference to the parse tree node to be rendered
@@ -38,9 +41,10 @@ Widget.prototype.initialise = function(parseTreeNode,options) {
this.parseTreeNode = parseTreeNode;
this.wiki = options.wiki;
this.parentWidget = options.parentWidget;
this.variablesConstructor = function() {};
this.variablesConstructor.prototype = this.parentWidget ? this.parentWidget.variables : {};
this.variables = new this.variablesConstructor();
this.variables = Object.create(null);
if(this.parentWidget) {
Object.setPrototypeOf(this.variables,this.parentWidget.variables);
}
this.document = options.document;
this.attributes = {};
this.children = [];
@@ -357,6 +361,20 @@ Widget.prototype.assignAttributes = function(domNode,options) {
}
};
/*
Get the number of ancestor widgets for this widget
*/
Widget.prototype.getAncestorCount = function() {
if(this.ancestorCount === undefined) {
if(this.parentWidget) {
this.ancestorCount = this.parentWidget.getAncestorCount() + 1;
} else {
this.ancestorCount = 0;
}
}
return this.ancestorCount;
};
/*
Make child widgets correspondng to specified parseTreeNodes
*/
@@ -364,21 +382,29 @@ Widget.prototype.makeChildWidgets = function(parseTreeNodes,options) {
options = options || {};
this.children = [];
var self = this;
// Create set variable widgets for each variable
$tw.utils.each(options.variables,function(value,name) {
var setVariableWidget = {
type: "set",
attributes: {
name: {type: "string", value: name},
value: {type: "string", value: value}
},
children: parseTreeNodes
};
parseTreeNodes = [setVariableWidget];
});
$tw.utils.each(parseTreeNodes || (this.parseTreeNode && this.parseTreeNode.children),function(childNode) {
self.children.push(self.makeChildWidget(childNode));
});
// Check for too much recursion
if(this.getAncestorCount() > MAX_WIDGET_TREE_DEPTH) {
this.children.push(this.makeChildWidget({type: "error", attributes: {
"$message": {type: "string", value: $tw.language.getString("Error/RecursiveTransclusion")}
}}));
} else {
// Create set variable widgets for each variable
$tw.utils.each(options.variables,function(value,name) {
var setVariableWidget = {
type: "set",
attributes: {
name: {type: "string", value: name},
value: {type: "string", value: value}
},
children: parseTreeNodes
};
parseTreeNodes = [setVariableWidget];
});
// Create the child widgets
$tw.utils.each(parseTreeNodes || (this.parseTreeNode && this.parseTreeNode.children),function(childNode) {
self.children.push(self.makeChildWidget(childNode));
});
}
};
/*

View File

@@ -34,6 +34,8 @@ external-link-foreground-hover: inherit
external-link-foreground-visited: #0000aa
external-link-foreground: #0000ee
foreground: #333333
highlight-background: #ffff00
highlight-foreground: #000000
message-background: #ecf2ff
message-border: #cfd6e6
message-foreground: #547599

View File

@@ -34,6 +34,8 @@ external-link-foreground-hover: inherit
external-link-foreground-visited: #0000aa
external-link-foreground: #0000ee
foreground: #333353
highlight-background: #ffff00
highlight-foreground: #000000
message-background: #ecf2ff
message-border: #cfd6e6
message-foreground: #547599

View File

@@ -34,6 +34,8 @@ external-link-foreground-hover: inherit
external-link-foreground-visited: #0000aa
external-link-foreground: #0000ee
foreground: #333333
highlight-background: #ffff00
highlight-foreground: #000000
message-background: #ecf2ff
message-border: #cfd6e6
message-foreground: #547599

View File

@@ -34,6 +34,8 @@ external-link-foreground-hover: inherit
external-link-foreground-visited: #00a
external-link-foreground: #00e
foreground: #000
highlight-background: #ffff00
highlight-foreground: #000000
message-background: <<colour foreground>>
message-border: <<colour background>>
message-foreground: <<colour background>>

View File

@@ -34,6 +34,8 @@ external-link-foreground-hover: inherit
external-link-foreground-visited: #00a
external-link-foreground: #00e
foreground: #fff
highlight-background: #ffff00
highlight-foreground: #000000
message-background: <<colour foreground>>
message-border: <<colour background>>
message-foreground: <<colour background>>

View File

@@ -32,6 +32,8 @@ external-link-foreground-hover:
external-link-foreground-visited: #BF5AF2
external-link-foreground: #32D74B
foreground: #FFFFFF
highlight-background: #ffff78
highlight-foreground: #000000
menubar-background: #464646
menubar-foreground: #ffffff
message-background: <<colour background>>

View File

@@ -36,6 +36,8 @@ external-link-foreground-hover: inherit
external-link-foreground-visited: #0000aa
external-link-foreground: #0000ee
foreground: #333333
highlight-background: #ffff00
highlight-foreground: #000000
message-background: #ecf2ff
message-border: #cfd6e6
message-foreground: #547599

View File

@@ -40,6 +40,8 @@ external-link-foreground-hover: inherit
external-link-foreground-visited: #313163
external-link-foreground: #555592
foreground: #2D2A23
highlight-background: #ffff00
highlight-foreground: #000000
menubar-background: #CDC2A6
menubar-foreground: #5A5446
message-background: #ECE5CF

View File

@@ -41,6 +41,8 @@ external-link-foreground-hover: inherit
external-link-foreground-visited: #d3869b
external-link-foreground: #8ec07c
foreground: #fbf1c7
highlight-background: #ffff79
highlight-foreground: #000000
menubar-background: #504945
menubar-foreground: <<colour foreground>>
message-background: #83a598

View File

@@ -41,6 +41,8 @@ external-link-foreground-hover: inherit
external-link-foreground-visited: #5E81AC
external-link-foreground: #8FBCBB
foreground: #d8dee9
highlight-background: #ffff78
highlight-foreground: #000000
menubar-background: #2E3440
menubar-foreground: #d8dee9
message-background: #2E3440

View File

@@ -34,6 +34,8 @@ external-link-foreground-hover: inherit
external-link-foreground-visited: #0000aa
external-link-foreground: #0000ee
foreground: #333333
highlight-background: #ffff00
highlight-foreground: #000000
message-background: #ecf2ff
message-border: #cfd6e6
message-foreground: #547599

View File

@@ -131,6 +131,8 @@ external-link-background-hover: inherit
external-link-background-visited: inherit
external-link-background: inherit
external-link-foreground-hover: inherit
highlight-background: #ffff00
highlight-foreground: #000000
message-border: #cfd6e6
modal-border: #999999
select-tag-background:

View File

@@ -35,6 +35,8 @@ external-link-foreground: #268bd2
external-link-foreground-hover:
external-link-foreground-visited: #268bd2
foreground: #839496
highlight-background: #ffff78
highlight-foreground: #000000
message-background: #002b36
message-border: #586e75
message-foreground: #839496

View File

@@ -35,6 +35,8 @@ external-link-foreground: #268bd2
external-link-foreground-hover: inherit
external-link-foreground-visited: #268bd2
foreground: #657b83
highlight-background: #ffff00
highlight-foreground: #000000
message-background: #fdf6e3
message-border: #93a1a1
message-foreground: #657b83

View File

@@ -34,6 +34,8 @@ external-link-foreground-hover:
external-link-foreground-visited:
external-link-foreground:
foreground: rgba(0, 0, 0, 0.87)
highlight-background: #ffff00
highlight-foreground: #000000
message-background: <<colour background>>
message-border: <<colour very-muted-foreground>>
message-foreground: rgba(0, 0, 0, 0.54)

View File

@@ -34,6 +34,8 @@ external-link-foreground-hover:
external-link-foreground-visited: #7c318c
external-link-foreground: #9e3eb3
foreground: rgba(255, 255, 255, 0.7)
highlight-background: #ffff78
highlight-foreground: #000000
message-background: <<colour background>>
message-border: <<colour very-muted-foreground>>
message-foreground: rgba(255, 255, 255, 0.54)

View File

@@ -43,6 +43,8 @@ external-link-foreground: rgb(179, 179, 255)
external-link-foreground-hover: inherit
external-link-foreground-visited: rgb(153, 153, 255)
foreground: rgb(179, 179, 179)
highlight-background: #ffff78
highlight-foreground: #000000
message-background: <<colour tag-foreground>>
message-border: #96ccff
message-foreground: <<colour tag-background>>

View File

@@ -42,6 +42,8 @@ external-link-foreground-hover: inherit
external-link-foreground-visited: #0000aa
external-link-foreground: #0000ee
foreground: #333333
highlight-background: #ffff00
highlight-foreground: #000000
message-background: #ecf2ff
message-border: #cfd6e6
message-foreground: #547599

View File

@@ -4,5 +4,7 @@ title: $:/core/save/all-external-js
\define saveTiddlerFilter()
[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$
\end
\define coreURL() %24%3A%2Fcore%2Ftemplates%2Ftiddlywiki5.js
{{$:/core/templates/tiddlywiki5-external-js.html}}
\define defaultCoreURL() %24%3A%2Fcore%2Ftemplates%2Ftiddlywiki5.js
<$let coreURL={{{ [[coreURL]is[variable]then<coreURL>else<defaultCoreURL>] }}}>
{{$:/core/templates/tiddlywiki5-external-js.html}}
</$let>

View File

@@ -4,5 +4,7 @@ title: $:/core/save/offline-external-js
\define saveTiddlerFilter()
[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/plugins/tiddlywiki/filesystem]] -[[$:/plugins/tiddlywiki/tiddlyweb]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$
\end
\define coreURL() tiddlywikicore-$(version)$.js
{{$:/core/templates/tiddlywiki5-external-js.html}}
\define defaultCoreURL() tiddlywikicore-$(version)$.js
<$let coreURL={{{ [[coreURL]is[variable]then<coreURL>else<defaultCoreURL>] }}}>
{{$:/core/templates/tiddlywiki5-external-js.html}}
</$let>

View File

@@ -18,7 +18,7 @@ tc-page-container tc-page-view-$(storyviewTitle)$ tc-language-$(languageTitle)$
<$navigator story="$:/StoryList" history="$:/HistoryList">
<$transclude mode="block"/>
<$transclude tiddler="$:/core/ui/ViewTemplate/body" mode="block"/>
</$navigator>

View File

@@ -2,11 +2,5 @@ title: $:/core/ui/Actions/new-image
tags: $:/tags/Actions
description: create a new image tiddler
\define get-type()
image/$(imageType)$
\end
\define get-tags() $(textFieldTags)$ $(tagsFieldTags)$
\whitespace trim
<$vars imageType={{$:/config/NewImageType}} textFieldTags={{$:/config/NewJournal/Tags}} tagsFieldTags={{$:/config/NewJournal/Tags!!tags}}>
<$action-sendmessage $message="tm-new-tiddler" type=<<get-type>> tags=<<get-tags>>/>
</$vars>
<$action-sendmessage $message="tm-new-tiddler" type={{{ [{$:/config/NewImageType}addprefix[image/]] }}}/>

View File

@@ -3,7 +3,7 @@ tags: $:/tags/AdvancedSearch/FilterButton
\whitespace trim
<$reveal state="$:/temp/advancedsearch" type="nomatch" text="">
<$button popup=<<qualify "$:/state/filterDeleteDropdown">> class="tc-btn-invisible">
<$button tooltip={{$:/language/Buttons/DeleteTiddlers/Hint}} popup=<<qualify "$:/state/filterDeleteDropdown">> class="tc-btn-invisible">
{{$:/core/images/delete-button}}
</$button>
</$reveal>
@@ -13,13 +13,13 @@ tags: $:/tags/AdvancedSearch/FilterButton
<div class="tc-block-dropdown tc-edit-type-dropdown">
<div class="tc-dropdown-item-plain">
<$set name="resultCount" value="""<$count filter={{$:/temp/advancedsearch}}/>""">
Are you sure you wish to delete <<resultCount>> tiddler(s)?
{{$:/language/ConfirmDeleteTiddlers}}
</$set>
</div>
<div class="tc-dropdown-item-plain">
<$button class="tc-btn">
<$action-deletetiddler $filter={{$:/temp/advancedsearch}}/>
Delete these tiddlers
{{$:/language/Buttons/DeleteTiddlers/Hint}}
</$button>
</div>
</div>

View File

@@ -14,8 +14,8 @@ tags: $:/tags/AdvancedSearch/FilterButton
<$linkcatcher actions="<$action-setfield $tiddler='$:/temp/advancedsearch' text=<<navigateTo>>/><$action-setfield $tiddler='$:/temp/advancedsearch/input' text=<<navigateTo>>/><$action-setfield $tiddler='$:/temp/advancedsearch/refresh' text='yes'/><$action-sendmessage $message='tm-focus-selector' $param='.tc-advanced-search input' />">
<div class="tc-block-dropdown-wrapper">
<div class="tc-block-dropdown tc-edit-type-dropdown">
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Filter]]">
<$link to={{!!filter}}><$transclude field="description"/></$link>
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Filter]!is[draft]]">
<$link to={{!!filter}}><$let tv-wikilinks="no"><$transclude field="description"/></$let></$link>
</$list>
</div>
</div>

View File

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

View File

@@ -0,0 +1,3 @@
title: $:/snippets/retain-story-ordering-button
<$button set="$:/DefaultTiddlers" setTo={{$:/config/ControlPanel/Basics/DefaultTiddlers/RetainStory}} ><<currentTiddler>></$button>

View File

@@ -1,7 +1,12 @@
title: $:/core/ui/EditTemplate
\define delete-edittemplate-state-tiddlers() <$action-deletetiddler $filter="[<newFieldNameTiddler>] [prefix<newFieldValueTiddlerPrefix>] [<newFieldNameInputTiddler>] [<newFieldNameSelectionTiddler>] [<newTagNameTiddler>] [<newTagNameInputTiddler>] [<newTagNameSelectionTiddler>] [<typeInputTiddler>] [<typeSelectionTiddler>]"/>
\define delete-edittemplate-state-tiddlers()
<$set name="safeNewFieldValueTiddlerPrefix" value=<<newFieldValueTiddlerPrefix>> emptyValue=<<qualify "$:/temp/NewFieldValue">> >
<$action-deletetiddler $filter="[<newFieldNameTiddler>] [prefix[$:/temp/NewFieldValue]prefix<safeNewFieldValueTiddlerPrefix>] [<newFieldNameInputTiddler>] [<newFieldNameSelectionTiddler>] [<newTagNameTiddler>] [<newTagNameInputTiddler>] [<newTagNameSelectionTiddler>] [<typeInputTiddler>] [<typeSelectionTiddler>]"/>
</$set>
\end
<!-- Beware this is duplicated from fields.tid. For details see bug #7054 -->
\define get-field-value-tiddler-filter() [subfilter<get-field-editor-filter>sha256[16]addprefix[/]addprefix<newFieldValueTiddlerPrefix>]
\define get-field-editor-filter() [<newFieldNameTiddler>get[text]else[]] :cascade[all[shadows+tiddlers]tag[$:/tags/FieldEditorFilter]!is[draft]get[text]] :and[!is[blank]else{$:/core/ui/EditTemplate/fieldEditor/default}]
@@ -23,7 +28,7 @@ title: $:/core/ui/EditTemplate
<div
data-tiddler-title=<<currentTiddler>>
data-tags={{!!tags}}
class={{{ tc-tiddler-frame tc-tiddler-edit-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[system]then[tc-tiddler-system]] [{!!class}] [<currentTiddler>tags[]encodeuricomponent[]addprefix[tc-tagged-]] +[join[ ]] }}}
class={{{ [all[shadows+tiddlers]tag[$:/tags/ClassFilters/TiddlerTemplate]!is[draft]] :map:flat[subfilter{!!text}] tc-tiddler-frame tc-tiddler-edit-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[system]then[tc-tiddler-system]] [{!!class}] [<currentTiddler>tags[]encodeuricomponent[]addprefix[tc-tagged-]] +[join[ ]] }}}
role="region"
aria-label={{$:/language/EditTemplate/Caption}}>
<$fieldmangler>

View File

@@ -5,6 +5,6 @@ caption: {{$:/language/EditTemplate/Body/Preview/Type/Output}}
\import [all[shadows+tiddlers]tag[$:/tags/Macro/View]!has[draft.of]] [all[shadows+tiddlers]tag[$:/tags/Macro/View/Body]!has[draft.of]]
<$set name="tv-tiddler-preview" value="yes">
<$transclude />
<$transclude tiddler={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/ViewTemplateBodyFilter]!is[draft]get[text]] :and[!is[blank]else[$:/core/ui/ViewTemplate/body/default]] }}} />
</$set>

View File

@@ -19,7 +19,7 @@ $:/config/EditorToolbarButtons/Visibility/$(currentTiddler)$
<$transclude tiddler="$:/core/ui/EditTemplate/body/editor" mode="inline"/>
<div class="tc-tiddler-preview-preview">
<div class="tc-tiddler-preview-preview" data-tiddler-title={{!!draft.title}} data-tags={{!!tags}}>
<$transclude tiddler={{$:/state/editpreviewtype}} mode="inline">

View File

@@ -10,6 +10,10 @@ $:/config/EditTemplateFields/Visibility/$(currentField)$
[[hide]] -[title{$(config-title)$}]
\end
<!-- Beware this is duplicated from EditTemplate.tid. For details see bug #7054 -->
\define get-field-value-tiddler-filter() [subfilter<get-field-editor-filter>sha256[16]addprefix[/]addprefix<newFieldValueTiddlerPrefix>]
\define get-field-editor-filter() [<newFieldNameTiddler>get[text]else[]] :cascade[all[shadows+tiddlers]tag[$:/tags/FieldEditorFilter]!is[draft]get[text]] :and[!is[blank]else{$:/core/ui/EditTemplate/fieldEditor/default}]
\define current-tiddler-new-field-selector()
[data-tiddler-title="$(currentTiddlerCSSescaped)$"] .tc-edit-field-add-name-wrapper input
\end
@@ -17,7 +21,9 @@ $:/config/EditTemplateFields/Visibility/$(currentField)$
\define new-field-actions()
\whitespace trim
<$action-sendmessage $message="tm-add-field" $name={{{ [<newFieldNameTiddler>get[text]] }}} $value={{{ [<newFieldNameTiddler>get[text]] :map[subfilter<get-field-value-tiddler-filter>get[text]] }}}/>
<$action-deletetiddler $filter="[<newFieldNameTiddler>] [prefix<newFieldValueTiddlerPrefix>] [<storeTitle>] [<searchListState>]"/>
<$set name="safeNewFieldValueTiddlerPrefix" value=<<newFieldValueTiddlerPrefix>> emptyValue=<<qualify "$:/temp/NewFieldValue">> >
<$action-deletetiddler $filter="[<newFieldNameTiddler>] [prefix[$:/temp/NewFieldValue]prefix<safeNewFieldValueTiddlerPrefix>] [<storeTitle>] [<searchListState>]"/>
</$set>
<$action-sendmessage $message="tm-focus-selector" $param=<<current-tiddler-new-field-selector>>/>
\end
@@ -52,7 +58,9 @@ $:/config/EditTemplateFields/Visibility/$(currentField)$
<$action-sendmessage $message="tm-add-field"
$name=<<name>>
$value={{{ [subfilter<get-field-value-tiddler-filter>get[text]] }}}/>
<$action-deletetiddler $filter="[<newFieldNameTiddler>] [prefix<newFieldValueTiddlerPrefix>] [<storeTitle>] [<searchListState>]"/>
<$set name="safeNewFieldValueTiddlerPrefix" value=<<newFieldValueTiddlerPrefix>> emptyValue=<<qualify "$:/temp/NewFieldValue">> >
<$action-deletetiddler $filter="[<newFieldNameTiddler>] [prefix[$:/temp/NewFieldValue]prefix<safeNewFieldValueTiddlerPrefix>] [<storeTitle>] [<searchListState>]"/>
</$set>
<<lingo Fields/Add/Button>>
</$button>
</$reveal>
@@ -65,6 +73,7 @@ $value={{{ [subfilter<get-field-value-tiddler-filter>get[text]] }}}/>
\end
\whitespace trim
<$set name="newFieldValueTiddlerPrefix" value=<<newFieldValueTiddlerPrefix>> emptyValue=<<qualify "$:/temp/NewFieldValue">> >
<div class="tc-edit-fields">
<table class={{{ [all[current]fields[]] :filter[lookup[$:/config/EditTemplateFields/Visibility/]!match[hide]] +[count[]!match[0]] +[then[tc-edit-fields]] ~[[tc-edit-fields tc-edit-fields-small]] }}}>
<tbody>
@@ -148,3 +157,4 @@ $value={{{ [subfilter<get-field-value-tiddler-filter>get[text]] }}}/>
</$vars>
</div>
</$fieldmangler>
</$set>

View File

@@ -117,15 +117,15 @@ title: $:/core/ui/ImportListing
</div>
</td>
</$reveal>
<tr>
<$reveal type="match" text="yes" state=<<previewPopupState>> tag="tr">
<td colspan="3">
<$reveal type="match" text="yes" state=<<previewPopupState>> tag="div">
<$list filter="[{$:/state/importpreviewtype}has[text]]" variable="listItem" emptyMessage={{$:/core/ui/ImportPreviews/Text}}>
<$transclude tiddler={{$:/state/importpreviewtype}}/>
<div>
<$transclude tiddler={{$:/state/importpreviewtype}}/>
</div>
</$list>
</$reveal>
</td>
</tr>
</$reveal>
</$list>
</tbody>
</table>

View File

@@ -4,6 +4,6 @@ key: ((advanced-search))
\whitespace trim
<$navigator story="$:/StoryList" history="$:/HistoryList">
<$action-navigate $to="$:/AdvancedSearch"/>
<$action-navigate $to="$:/AdvancedSearch" $scroll="yes"/>
<$action-sendmessage $message="tm-focus-selector" $param="""[data-tiddler-title="$:/AdvancedSearch"] .tc-search input""" preventScroll="true"/>
</$navigator>

View File

@@ -0,0 +1,15 @@
title: $:/core/ui/Buttons/layout
tags: $:/tags/PageControls
caption: {{$:/core/images/layout-button}} {{$:/language/Buttons/LayoutSwitcher/Caption}}
description: {{$:/language/LayoutSwitcher/Description}}
\whitespace trim
<$button tooltip={{$:/language/Buttons/LayoutSwitcher/Hint}} aria-label={{$:/language/Buttons/LayoutSwitcher/Caption}} class=<<tv-config-toolbar-class>>>
<$action-sendmessage $message="tm-show-switcher" switch="layout"/>
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
{{$:/core/images/layout-button}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/LayoutSwitcher/Caption}}/></span>
</$list>
</$button>

View File

@@ -3,9 +3,6 @@ name: {{$:/language/PageTemplate/Name}}
description: {{$:/language/PageTemplate/Description}}
\whitespace trim
\define containerClasses()
tc-page-container tc-page-view-$(storyviewTitle)$ tc-language-$(languageTitle)$
\end
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
<$vars
@@ -17,7 +14,7 @@ tc-page-container tc-page-view-$(storyviewTitle)$ tc-language-$(languageTitle)$
storyviewTitle={{$:/view}}
languageTitle={{{ [{$:/language}get[name]] }}}>
<div class=<<containerClasses>>>
<div class={{{ [all[shadows+tiddlers]tag[$:/tags/ClassFilters/PageTemplate]!is[draft]] :map:flat[subfilter{!!text}] tc-page-container [[tc-page-view-]addsuffix<storyviewTitle>] [[tc-language-]addsuffix<languageTitle>] :and[unique[]join[ ]] }}} >
<$navigator story="$:/StoryList" history="$:/HistoryList" openLinkFromInsideRiver={{$:/config/Navigation/openLinkFromInsideRiver}} openLinkFromOutsideRiver={{$:/config/Navigation/openLinkFromOutsideRiver}} relinkOnRename={{$:/config/RelinkOnRename}}>

View File

@@ -3,6 +3,6 @@ tags: $:/tags/SideBar
caption: {{$:/language/SideBar/More/Caption}}
\whitespace trim
<div class="tc-more-sidebar">
<$macrocall $name="tabs" tabsList="[all[shadows+tiddlers]tag[$:/tags/MoreSideBar]!has[draft.of]]" default={{$:/config/DefaultMoreSidebarTab}} state="$:/state/tab/moresidebar" class="tc-vertical tc-sidebar-tabs-more" explicitState="$:/state/tab/moresidebar-1850697562"/>
<div class={{{ [{$:/config/ui/SideBar/More/horizontal}match[yes]then[tc-sidebar-tabs]else[tc-more-sidebar]] }}}>
<$macrocall $name="tabs" tabsList="[all[shadows+tiddlers]tag[$:/tags/MoreSideBar]!has[draft.of]]" default={{$:/config/DefaultMoreSidebarTab}} state="$:/state/tab/moresidebar" class={{{ [{$:/config/ui/SideBar/More/horizontal}match[yes]then[tc-sidebar-tabs-more]else[tc-vertical tc-sidebar-tabs-more]] }}} explicitState="$:/state/tab/moresidebar-1850697562"/>
</div>

View File

@@ -1,6 +1,7 @@
title: $:/core/ui/SwitcherModal
subtitle: <$text text={{{[<switch>lookup[$:/language/Switcher/Subtitle/]]}}}/>
class: tc-modal-centered
mask-closable: yes
<$tiddler tiddler={{{[<switch>lookup[$:/config/SwitcherTargets/]]}}}>

View File

@@ -3,89 +3,101 @@ icon: $:/core/images/tag-button
color: #bbb
\define lingo-base() $:/language/TagManager/
\define iconEditorTab(type)
\whitespace trim
<$link to=""><<lingo Icons/None>></$link>
<$list filter="[all[shadows+tiddlers]is[image]] [all[shadows+tiddlers]tag[$:/tags/Image]] -[type[application/pdf]] +[sort[title]] +[$type$is[system]]">
<$link to={{!!title}}>
<$transclude/> <$view field="title"/>
</$link>
<$link to={{!!title}}>
<$transclude/> <$view field="title"/>
</$link>
</$list>
\end
\define iconEditor(title)
\whitespace trim
<div class="tc-drop-down-wrapper">
<$button popupTitle={{{ [[$:/state/popup/icon/]addsuffix<__title__>] }}} class="tc-btn-invisible tc-btn-dropdown">{{$:/core/images/down-arrow}}</$button>
<$reveal stateTitle={{{ [[$:/state/popup/icon/]addsuffix<__title__>] }}} type="popup" position="belowleft" text="" default="">
<div class="tc-drop-down">
<$linkcatcher actions="""<$action-setfield $tiddler=<<__title__>> icon=<<navigateTo>>/>""">
<<iconEditorTab type:"!">>
<hr/>
<<iconEditorTab type:"">>
</$linkcatcher>
</div>
</$reveal>
<$button popupTitle={{{ [[$:/state/popup/icon/]addsuffix<__title__>] }}} class="tc-btn-invisible tc-btn-dropdown">
{{$:/core/images/down-arrow}}
</$button>
<$reveal stateTitle={{{ [[$:/state/popup/icon/]addsuffix<__title__>] }}} type="popup" position="belowleft" text="" default="">
<div class="tc-drop-down">
<$linkcatcher actions="""<$action-setfield $tiddler=<<__title__>> icon=<<navigateTo>>/>""">
<<iconEditorTab type:"!">>
<hr/>
<<iconEditorTab type:"">>
</$linkcatcher>
</div>
</$reveal>
</div>
\end
\define toggleButton(state)
\whitespace trim
<$reveal stateTitle=<<__state__>> type="match" text="closed" default="closed">
<$button setTitle=<<__state__>> setTo="open" class="tc-btn-invisible tc-btn-dropdown" selectedClass="tc-selected">
{{$:/core/images/info-button}}
</$button>
<$button setTitle=<<__state__>> setTo="open" class="tc-btn-invisible tc-btn-dropdown" selectedClass="tc-selected">
{{$:/core/images/info-button}}
</$button>
</$reveal>
<$reveal stateTitle=<<__state__>> type="match" text="open" default="closed">
<$button setTitle=<<__state__>> setTo="closed" class="tc-btn-invisible tc-btn-dropdown" selectedClass="tc-selected">
{{$:/core/images/info-button}}
</$button>
<$button setTitle=<<__state__>> setTo="closed" class="tc-btn-invisible tc-btn-dropdown" selectedClass="tc-selected">
{{$:/core/images/info-button}}
</$button>
</$reveal>
\end
\whitespace trim
<table class="tc-tag-manager-table">
<tbody>
<tr>
<th><<lingo Colour/Heading>></th>
<th class="tc-tag-manager-tag"><<lingo Tag/Heading>></th>
<th><<lingo Count/Heading>></th>
<th><<lingo Icon/Heading>></th>
<th><<lingo Info/Heading>></th>
</tr>
<$list filter="[tags[]!is[system]sort[title]]">
<tr>
<td><$edit-text field="color" tag="input" type="color"/></td>
<td>{{||$:/core/ui/TagTemplate}}</td>
<td><$count filter="[all[current]tagging[]]"/></td>
<td>
<$macrocall $name="iconEditor" title={{!!title}}/>
</td>
<td>
<$macrocall $name="toggleButton" state={{{ [[$:/state/tag-manager/]addsuffix<currentTiddler>] }}} />
</td>
</tr>
<tr>
<td></td>
<td colspan="4">
<$reveal stateTitle={{{ [[$:/state/tag-manager/]addsuffix<currentTiddler>] }}} type="match" text="open" default="">
<table>
<tbody>
<tr><td><<lingo Colour/Heading>></td><td><$edit-text field="color" tag="input" type="text" size="9"/></td></tr>
<tr><td><<lingo Icon/Heading>></td><td><$edit-text field="icon" tag="input" size="45"/></td></tr>
</tbody>
</table>
</$reveal>
</td>
</tr>
</$list>
<tr>
<td></td>
<td style="position:relative;">
{{$:/core/ui/UntaggedTemplate}}
</td>
<td>
<small class="tc-menu-list-count"><$count filter="[untagged[]!is[system]] -[tags[]]"/></small>
</td>
<td></td>
<td></td>
</tr>
<tr>
<th><<lingo Colour/Heading>></th>
<th class="tc-tag-manager-tag"><<lingo Tag/Heading>></th>
<th><<lingo Count/Heading>></th>
<th><<lingo Icon/Heading>></th>
<th><<lingo Info/Heading>></th>
</tr>
<$list filter="[tags[]!is[system]sort[title]]">
<tr>
<td><$edit-text field="color" tag="input" type="color"/></td>
<td>{{||$:/core/ui/TagTemplate}}</td>
<td><$count filter="[all[current]tagging[]]"/></td>
<td>
<$macrocall $name="iconEditor" title={{!!title}}/>
</td>
<td>
<$macrocall $name="toggleButton" state={{{ [[$:/state/tag-manager/]addsuffix<currentTiddler>] }}} />
</td>
</tr>
<tr>
<td></td>
<td colspan="4">
<$reveal stateTitle={{{ [[$:/state/tag-manager/]addsuffix<currentTiddler>] }}} type="match" text="open" default="">
<table>
<tbody>
<tr>
<td><<lingo Colour/Heading>></td>
<td><$edit-text field="color" tag="input" type="text" size="9"/></td>
</tr>
<tr>
<td><<lingo Icon/Heading>></td>
<td><$edit-text field="icon" tag="input" size="45"/></td>
</tr>
</tbody>
</table>
</$reveal>
</td>
</tr>
</$list>
<tr>
<td></td>
<td style="position:relative;">
{{$:/core/ui/UntaggedTemplate}}
</td>
<td>
<small class="tc-menu-list-count"><$count filter="[untagged[]!is[system]] -[tags[]]"/></small>
</td>
<td></td>
<td></td>
</tr>
</tbody>
</table>

View File

@@ -7,7 +7,7 @@ $:/state/folded/$(currentTiddler)$
\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[ ]] }}} role="article">
<div data-tiddler-title=<<currentTiddler>> data-tags={{!!tags}} class={{{ [all[shadows+tiddlers]tag[$:/tags/ClassFilters/TiddlerTemplate]!is[draft]] :map:flat[subfilter{!!text}] 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[ ]] }}} role="article">
<$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewTemplate]!has[draft.of]]" variable="listItem">
<$transclude tiddler=<<listItem>>/>
</$list>

View File

@@ -2,17 +2,21 @@ title: $:/core/ui/ViewTemplate/unfold
tags: $:/tags/ViewTemplate
\whitespace trim
<$reveal tag="div" type="nomatch" state="$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold-bar" text="hide">
<div class="tc-reveal">
<$list filter="[{$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold-bar}match[show]]" variable="ignore">
<$reveal tag="div" type="nomatch" stateTitle=<<folded-state>> text="hide" default="show" retain="yes" animate="yes">
<$button tooltip={{$:/language/Buttons/Fold/Hint}} aria-label={{$:/language/Buttons/Fold/Caption}} class="tc-fold-banner">
<$action-sendmessage $message="tm-fold-tiddler" $param=<<currentTiddler>> foldedState=<<folded-state>>/>
{{$:/core/images/chevron-up}}
</$button>
</$reveal>
</$list>
<$list filter="[{$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold-bar}match[show]] :else[<folded-state>get[text]match[hide]]" variable="ignore">
<$reveal tag="div" type="nomatch" stateTitle=<<folded-state>> text="show" default="show" retain="yes" animate="yes">
<$button tooltip={{$:/language/Buttons/Unfold/Hint}} aria-label={{$:/language/Buttons/Unfold/Caption}} class="tc-unfold-banner">
<$action-sendmessage $message="tm-fold-tiddler" $param=<<currentTiddler>> foldedState=<<folded-state>>/>
{{$:/core/images/chevron-down}}
</$button>
</$reveal>
</$reveal>
</$list>
</div>

View File

@@ -0,0 +1,3 @@
title: $:/config/ControlPanel/Basics/DefaultTiddlers/RetainStory
[list[$:/StoryList]]

View File

@@ -1,6 +1,6 @@
title: $:/config/OfficialPluginLibrary
tags: $:/tags/PluginLibrary
url: https://tiddlywiki.com/library/v5.2.3/index.html
url: https://tiddlywiki.com/library/v5.2.5/index.html
caption: {{$:/language/OfficialPluginLibrary}}
{{$:/language/OfficialPluginLibrary/Hint}}

View File

@@ -21,4 +21,5 @@ core/ui/Buttons/print: hide
core/ui/Buttons/storyview: hide
core/ui/Buttons/timestamp: hide
core/ui/Buttons/theme: hide
core/ui/Buttons/layout: hide
core/ui/Buttons/unfold-all: hide

View File

@@ -1,21 +1,21 @@
title: $:/core/macros/list
tags: $:/tags/Macro
\define list-links(filter,type:"ul",subtype:"li",class:"",emptyMessage)
\define list-links(filter,type:"ul",subtype:"li",class:"",emptyMessage,field:"caption")
\whitespace trim
<$type$ class="$class$">
<$list filter="$filter$" emptyMessage=<<__emptyMessage__>>>
<$subtype$>
<$genesis $type=<<__type__>> class=<<__class__>>>
<$list filter=<<__filter__>> emptyMessage=<<__emptyMessage__>>>
<$genesis $type=<<__subtype__>>>
<$link to={{!!title}}>
<$let tv-wikilinks="no">
<$transclude field="caption">
<$transclude field=<<__field__>>>
<$view field="title"/>
</$transclude>
</$let>
</$link>
</$subtype$>
</$genesis>
</$list>
</$type$>
</$genesis>
\end
\define list-links-draggable-drop-actions()

View File

@@ -3,14 +3,11 @@ modified: 20141212110330815
tags: $:/tags/Macro
title: $:/core/macros/timeline
\define timeline-title()
\whitespace trim
<!-- Override this macro with a global macro
of the same name if you need to change
how titles are displayed on the timeline
-->
<$view field="title"/>
\end
<!-- Override one or both of the following two macros with a global or local macro of the same name
if you need to change how titles are displayed on a timeline -->
\define timeline-title() <$view field="title"/>
\define timeline-link() <$link to={{!!title}}><<timeline-title>></$link>
\define timeline(limit:"100",format:"DDth MMM YYYY",subfilter:"",dateField:"modified")
\whitespace trim
<div class="tc-timeline">
@@ -19,7 +16,7 @@ title: $:/core/macros/timeline
<$view field="$dateField$" format="date" template="$format$"/>
<$list filter="[sameday:$dateField${!!$dateField$}!is[system]$subfilter$!sort[$dateField$]]">
<div class="tc-menu-list-subitem">
<$link to={{!!title}}><<timeline-title>></$link>
<<timeline-link>>
</div>
</$list>
</div>

View File

@@ -1,6 +1,10 @@
title: $:/core/macros/toc
tags: $:/tags/Macro
\define toc-open-icon() $:/core/images/down-arrow
\define toc-closed-icon() $:/core/images/right-arrow
\define toc-caption()
\whitespace trim
<span class="tc-toc-caption tc-tiny-gap-left">
@@ -45,12 +49,12 @@ tags: $:/tags/Macro
<$link to={{{ [<currentTiddler>get[target]else<currentTiddler>] }}}>
<$reveal type="nomatch" stateTitle=<<toc-state>> text="open">
<$button setTitle=<<toc-state>> setTo="open" class="tc-btn-invisible tc-popup-keep">
{{$:/core/images/right-arrow}}
<$transclude tiddler=<<toc-closed-icon>> />
</$button>
</$reveal>
<$reveal type="match" stateTitle=<<toc-state>> text="open">
<$button setTitle=<<toc-state>> setTo="close" class="tc-btn-invisible tc-popup-keep">
{{$:/core/images/down-arrow}}
<$transclude tiddler=<<toc-open-icon>> />
</$button>
</$reveal>
<<toc-caption>>
@@ -71,13 +75,13 @@ tags: $:/tags/Macro
<li class=<<toc-item-class>>>
<$reveal type="nomatch" stateTitle=<<toc-state>> text="open">
<$button setTitle=<<toc-state>> setTo="open" class="tc-btn-invisible tc-popup-keep">
{{$:/core/images/right-arrow}}
<$transclude tiddler=<<toc-closed-icon>> />
<<toc-caption>>
</$button>
</$reveal>
<$reveal type="match" stateTitle=<<toc-state>> text="open">
<$button setTitle=<<toc-state>> setTo="close" class="tc-btn-invisible tc-popup-keep">
{{$:/core/images/down-arrow}}
<$transclude tiddler=<<toc-open-icon>> />
<<toc-caption>>
</$button>
</$reveal>
@@ -117,12 +121,12 @@ tags: $:/tags/Macro
<$list filter="[all[current]tagging[]$sort$limit[1]]" variable="ignore" emptyMessage="<$button class='tc-btn-invisible'>{{$:/core/images/blank}}</$button>">
<$reveal type="nomatch" stateTitle=<<toc-state>> text="open">
<$button setTitle=<<toc-state>> setTo="open" class="tc-btn-invisible tc-popup-keep">
{{$:/core/images/right-arrow}}
<$transclude tiddler=<<toc-closed-icon>> />
</$button>
</$reveal>
<$reveal type="match" stateTitle=<<toc-state>> text="open">
<$button setTitle=<<toc-state>> setTo="close" class="tc-btn-invisible tc-popup-keep">
{{$:/core/images/down-arrow}}
<$transclude tiddler=<<toc-open-icon>> />
</$button>
</$reveal>
</$list>
@@ -144,13 +148,13 @@ tags: $:/tags/Macro
<$list filter="[all[current]tagging[]$sort$limit[1]]" variable="ignore" emptyMessage="<$button class='tc-btn-invisible'>{{$:/core/images/blank}}</$button> <$view field='caption'><$view field='title'/></$view>">
<$reveal type="nomatch" stateTitle=<<toc-state>> text="open">
<$button setTitle=<<toc-state>> setTo="open" class="tc-btn-invisible tc-popup-keep">
{{$:/core/images/right-arrow}}
<$transclude tiddler=<<toc-closed-icon>> />
<<toc-caption>>
</$button>
</$reveal>
<$reveal type="match" stateTitle=<<toc-state>> text="open">
<$button setTitle=<<toc-state>> setTo="close" class="tc-btn-invisible tc-popup-keep">
{{$:/core/images/down-arrow}}
<$transclude tiddler=<<toc-open-icon>> />
<<toc-caption>>
</$button>
</$reveal>

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/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/layout]] [[$:/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

@@ -11,7 +11,6 @@
"tiddlywiki/snowwhite"
],
"languages": [
"en-GB",
"de-AT",
"de-DE"
],

View File

@@ -13,7 +13,6 @@
"tiddlywiki/internals"
],
"languages": [
"en-GB",
"de-AT",
"de-DE"
],

View File

@@ -13,7 +13,6 @@
"tiddlywiki/internals"
],
"languages": [
"en-GB",
"de-AT",
"de-DE"
],

View File

@@ -1,5 +1,5 @@
created: 20190115173333457
modified: 20190115173723915
modified: 20221029175754753
tags: TableOfContents
title: HelloThere
type: text/vnd.tiddlywiki
@@ -15,6 +15,7 @@ Welcome to the developer documentation for TiddlyWiki (https://tiddlywiki.com/).
** [[Using ES2016 for Writing Plugins]]
** [[Adding Babel Polyfill to TiddlyWiki]]
** [[TiddlyWiki Drag and Drop Interoperability]]
** [[Javascript Widget Tutorial]]
* The original developer documentation from https://tiddlywiki.com:
** [[TiddlyWiki for Developers]]
** [[TiddlyWiki Coding Style Guidelines]]

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