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

Compare commits

...

261 Commits

Author SHA1 Message Date
jeremy@jermolene.com
ac8f521303 Version number update for 5.1.23 2020-12-24 13:38:24 +00:00
jeremy@jermolene.com
2ab5fd9abb Preparing for release of v5.1.23 2020-12-24 13:37:18 +00:00
jeremy@jermolene.com
f6339d437e Release note: Jazz up the contributor list 2020-12-24 13:21:06 +00:00
jeremy@jermolene.com
8e61e37f2b Release note: More tweaks and reformatting 2020-12-24 13:10:44 +00:00
jeremy@jermolene.com
2632ed0078 Release note: coloured badges for different types of changes 2020-12-24 11:47:36 +00:00
jeremy@jermolene.com
7cb6dc0e4f Override crazy browser defaults for h1 fontsize
Fixes #5311
2020-12-24 10:37:54 +00:00
Bram Chen
8620b77b45 Improve chinese translations for TiddlySpot warning text (#5306) 2020-12-23 13:34:23 +00:00
jeremy@jermolene.com
03ad396db1 Start to rearrange release note into topics
The previous groupings were getting too large to manage
2020-12-22 19:12:12 +00:00
jeremy@jermolene.com
9e70e89a84 Update Release Note 2020-12-22 17:34:24 +00:00
jeremy@jermolene.com
2f8a100bab Clarify TiddlySpot warning text 2020-12-22 15:42:21 +00:00
jeremy@jermolene.com
a9a36b641a Filename for action-confirm widget should be 'action-confirm.js' for consistency 2020-12-22 11:50:26 +00:00
jeremy@jermolene.com
625c3de6f7 Merge branch 'tiddlywiki-com' 2020-12-22 11:49:18 +00:00
jeremy@jermolene.com
ddda9a34ae [Docs] Update links to developer discussions 2020-12-22 11:48:40 +00:00
twMat
c0a56e790d Update title.tid (#5292) 2020-12-18 20:19:02 +00:00
Simon Huber
dc83ee411d Fix problem with tc-btn-invisible not correct fill color (#5288) 2020-12-16 16:20:14 +00:00
jeremy@jermolene.com
3c003364d2 Add the Atrounoush's winning banner design for v5.1.23
The image was received with a transparent background, but I adjusted it to give it a white background to ensure it is readable with all colour schemes.
2020-12-15 11:59:07 +00:00
Saq Imtiaz
1e9cc2b747 Fix refresh for all attributes of droppable widget. Add disabled class (#5280) 2020-12-15 11:09:32 +00:00
Simon Huber
f968130696 Update Customising search results.tid (#5233) 2020-12-15 10:38:16 +00:00
jed
e046d5ad76 Create Hook_th-make-tiddler-path.tid (#5274)
Documentation for the hook
2020-12-14 19:20:29 +00:00
Robin Munn
3c3cd4673e Railroad diagram for filter expression now includes named prefixes (#5278) 2020-12-14 19:18:51 +00:00
Joshua Fontany
d50f6b406e filesystem cleaup around hook (#5276) 2020-12-14 09:50:53 +00:00
jed
c1a1e272cc Add a hook to allow modifying the the behaviour creating tiddler paths (#5267)
* Add a hook to allow modifying the the behaviour creating tiddler paths

This is needed for Bob to use the core to generate tiddler fileInfo 

I don't know if this is the best way to make the hook, but it works for what I need

* update th-make-tiddler-path arguments

the value is the current path, the parameter passed in is the original unmodified path so it is available to subsequent hooks
2020-12-13 23:24:23 +00:00
jeremy@jermolene.com
81947edd5c Dev: Update hook mechanism docs 2020-12-13 20:01:47 +00:00
Xavier Cazin
88e29b4558 tabsState should hold a tiddler name rather than a list singleton (#5263)
* tabsState should hold a tiddler name rather than a list singleton

* tabsState should hold a tiddler name rather than a list singleton
2020-12-13 16:15:16 +00:00
Simon Huber
8798ebadbd Add foreground color to CodeMirror selections and fix #5272 (#5266)
* Add foreground color to CodeMirror selections

* Use default selection background if tiddler-editor-background matches selection-background
2020-12-13 11:40:57 +00:00
Bimba Laszlo
a17fa35c28 Remove menubar from print (#5273)
In the print view, a shadow appeared at the top of each page, and the
first lines were not visible.

I hide the menubar in the print view.
2020-12-13 11:37:07 +00:00
Saq Imtiaz
0911d99813 URGENT: Reveal widget - fixed problem with previous patch of refresh handling (#5260)
* Fixed problem with previous patch of refresh handling

* Update reveal.js
2020-12-11 23:24:27 +00:00
jeremy@jermolene.com
93309b0b7d Sort plugins in control panel by name instead of title
Fixes #5256
2020-12-11 16:13:14 +00:00
Saq Imtiaz
c0dd13d446 Reveal widget should update on changed class and style attributes (#5258) 2020-12-11 15:36:00 +00:00
ento
ae61b08ae5 Fix browser testing (#5254)
* jasmine: specify 'after' only in Node

The commands module is never executed in browsers and the 'after'
constraint caused a regression where tests were never run in the
browser.

* jasmine: give the startup module a name like all others
2020-12-11 10:12:01 +00:00
Robin Munn
f60d0ef109 reduce and :reduce handle empty input identically (#5255)
Fixes #5246. Now the reduce operator and :reduce filter run prefix will
both return empty output when their input is empty, so that both can be
chained together with the else operator or :else prefix.
2020-12-11 10:07:52 +00:00
Cameron Fischer
6ca89304a1 Fix for LinkedLists when using bad filter prefix (#5251) 2020-12-10 18:25:53 +00:00
Simon Huber
78c2beb640 Add fill: <<colour button-foreground>> to html button in vanilla/base (#5250) 2020-12-10 17:33:42 +00:00
Stefano Stoduto
e34a88e3e4 Signing the CLA (#4876)
Co-authored-by: Jeremy Ruston <jeremy@jermolene.com>
2020-12-10 17:27:47 +00:00
Simon Huber
0d2b6cf837 Rename control-panel-button to advanced-search-button in advanced-search button (#5242) 2020-12-10 17:09:28 +00:00
Simon Huber
1af1f6621a cursor:pointer on input[type=file] doesn't work in webkit browsers... (#5244) 2020-12-10 17:09:03 +00:00
jeremy@jermolene.com
50d8325d4c Dynannotate: Fix off-by-one error for end of annotation text 2020-12-09 19:14:43 +00:00
Saq Imtiaz
3016b3d094 Docs update for Set Widget (#5239)
* Update docs for Set Widget

This updates the docs for Set Widget to add a tip regarding a common source of misunderstanding for users, i.e. using Filtered List Variable Assignment and being confused as to why the value of the variable is in double square brackets.

* Corrected typos
2020-12-09 11:12:57 +00:00
Saq Imtiaz
da5d12d6fb Docs for :reduce filter run prefix (#5238) 2020-12-09 11:11:14 +00:00
Cameron Fischer
cd5d9bd5b9 Code cleanup of Linked Lists (#5241)
* made private methods limited to module scope
* moved private methods to file bottom
* changed tests to run comperable array functions in parallel
* added comments
2020-12-09 09:46:35 +00:00
jeremy@jermolene.com
1e1aeefd93 Fix add plugins modal
Fixes #5235
2020-12-09 09:07:48 +00:00
jeremy@jermolene.com
1d7091e637 Hide .tid exporter when more than one tiddler to export
Fixes #5237
2020-12-08 17:48:58 +00:00
Simon Huber
4334de88a0 Make search-matches button discoverable on dark palettes (#5232) 2020-12-07 17:29:42 +00:00
jeremy@jermolene.com
bb6d41f3dd Macrocall widget: ensure we separately cache inline vs block parse trees
Fixes a bug in #5205
2020-12-07 16:05:34 +00:00
Joshua Fontany
a878d82c7a Ignore edition filters if not running on node (#5222) 2020-12-07 15:59:32 +00:00
Joshua Fontany
85ff47366c fix viewtemplate quirks (#5224) 2020-12-07 15:58:28 +00:00
Saq Imtiaz
ce5d20b8fc Logging widgets :Fixed issue on Firefox where logging does not work (#5223)
* Fixed issue on Firefox where logging does not work properly due to column names

* Remove second argument to utils.logTable
2020-12-07 15:53:49 +00:00
Simon Huber
2c76cfa67a Use displayshortcuts macro for keyboard_driven_input_macro tiddler (#5226)
* Update keyboard-driven-input_Macro.tid

* Update keyboard-driven-input_Macro.tid
2020-12-07 14:44:07 +00:00
Simon Huber
90f05295a2 Add missing config options to ControlPanel->Settings->CodeMirror (#5229)
* Create cursorBlinkRate.tid

* Update config-language.multids

* Create indentUnit.tid

* Create indentWithTabs.tid

* Create smartIndent.tid

* Create tabSize.tid
2020-12-07 14:43:44 +00:00
Simon Huber
5df0225356 Update Customising search results.tid (#5225) 2020-12-07 10:22:02 +00:00
Joshua Fontany
c3e34b469c typo (#5221) 2020-12-06 22:59:48 +00:00
Simon Huber
e8815b79ff Update CodeMirror Dialog to always have a background color (#5217) 2020-12-06 17:21:35 +00:00
Simon Huber
958f57f2c0 Make editTiddler in sidebarsegments/search available as variable (#5218) 2020-12-06 17:15:40 +00:00
jeremy@jermolene.com
43a3228200 Update Performance docs for macro parsing optimisation
Replacing #5216
2020-12-06 14:02:06 +00:00
jeremy@jermolene.com
96d4f87e78 Revert "Update documentation on Performance (#5203)"
This reverts commit f798eab33f.
2020-12-06 14:01:03 +00:00
Saq Imtiaz
a8c1e6a3bd Update performance documentation (#5216)
Documents the change to macro parsing from #5205 
This builds on documentation changes made in the tw.com branch and is therefore based on that branch, but should not be merged before 5.1.23 is live.
2020-12-06 13:57:47 +00:00
jeremy@jermolene.com
36fe519eff Merge branch 'tiddlywiki-com' 2020-12-06 13:56:43 +00:00
Simon Huber
b2d270a7e8 CodeMirror: Make colored selections based on palette work in chrome, too (#5215)
* Make colored selections based on palette work in chrome, too

* Update styles.tid
2020-12-06 13:00:19 +00:00
jeremy@jermolene.com
005f7c55b6 Restore accidental commenting in 0b1a05d10 2020-12-06 10:50:59 +00:00
Simon Huber
122306fc24 Update GruvboxDark, CupertinoDark and Nord palettes to work better with TiddlyDesktop (#5214)
* Update CupertinoDark.tid

* Update GruvBoxDark.tid

* Update Nord.tid
2020-12-06 09:58:02 +00:00
Jeremy Ruston
0b1a05d10d Cache result of parsing macro calls which don't use text subsitution (#5205) 2020-12-06 09:43:06 +00:00
Joshua Fontany
b0f6d50b60 fix filesystem bugs (#5213) 2020-12-06 09:41:03 +00:00
Simon Huber
a3a7d6450d CodeMirror: Ensure linenumber-gutter has a right border (#5212)
* Ensure linenumber-gutter has a right border

* Update GruvBoxDark.tid

* Update Nord.tid
2020-12-06 08:56:06 +00:00
Cameron Fischer
a857b4ab9a use a linked list for filter runs. (#5206)
* Changed the filterrunprefixes to use LinkedList

* Testing for Linked List

* Finishing touches to LinkedList

* Minor corrections to link-list coding style

* Corrected for sneaky bug in linkedList
2020-12-06 08:54:57 +00:00
ento
c4dcf510ef Ensure jasmine-plugin startup module is executed in the right order (#5210) 2020-12-06 07:29:34 +00:00
Saq Imtiaz
7fd24de372 Tests for filter prefixes (#5209) 2020-12-05 23:10:51 +00:00
Simon Huber
396703c478 An even faster version of the TagPickerTagTemplate (#5207) 2020-12-05 17:38:39 +00:00
Simon Huber
bfc4b447da Add selection-background/foreground to GruvboxDark and Nord palettes (#5204)
* Update GruvBoxDark.tid

* Update Nord.tid

* Update Nord.tid

* Update Nord.tid

* Update Nord.tid
2020-12-05 16:38:08 +00:00
Simon Huber
d957b3e4e6 Update CodeMirror styles to set selection colors based on foreground contrastcolour (#5200)
* Update styles.tid

* Update styles.tid

* Update styles.tid
2020-12-05 16:37:50 +00:00
Saq Imtiaz
f798eab33f Update documentation on Performance (#5203) 2020-12-05 16:30:49 +00:00
Cameron Fischer
fbe5bb229a Fix for filterrunprefixes using $tw.wiki (#5202)
* Fixed runprefix 'and' to use widget wiki

* Made widget arg of filterTiddlers optional again

* Switched to passing {wiki: wiki} to prefixes
2020-12-05 16:12:40 +00:00
Simon Huber
ae5d78b4dd Update codemirror styles (#5198) 2020-12-04 19:14:59 +00:00
Saq Imtiaz
9825b5b4a0 Ensure new variables are strings (#5197) 2020-12-04 19:02:05 +00:00
Saq Imtiaz
8799911162 Reduce operator: second optional parameter instead of suffix (#5193)
* Tweak reduce operator to use an optional second parameter instead of a suffix

* Updated docs
2020-12-04 18:31:23 +00:00
Simon Huber
813e28e1ea Make the tag-picker tags-dropdown more performant (#5195)
* Replace macrocall for tag-button with transclusion of a TagPickerTagTemplate

* Create TagPickerTagTemplate.tid
2020-12-04 18:28:36 +00:00
Simon Huber
911e23ee6d Make sidebarsegments/search button display the count of ALL search results (de-duplicated) (#5194) 2020-12-04 18:27:40 +00:00
Saq Imtiaz
046746ba20 Add :reduce filter run prefix (#5196) 2020-12-04 18:23:50 +00:00
Robin Munn
8ffe138942 Add rawunicode suffix to (json)stringify operators (#5191)
Default with no suffix is pre-5.1.23 behavior, escaping all Unicode
characters for maximum compatibility (avoids encoding issues). New
"rawunicode" suffix allows passing through Unicode characters U+0080
and up unchanged, for cases where you know your tools are handling
encoding correctly and you want less verbose escaping.
2020-12-04 13:19:59 +00:00
Mohammad Rahmani
15be409c42 Minor issue in example of Import Variables Widget (#5165)
an unbalanced [ was resolved.
2020-12-03 22:27:21 +00:00
Robin Munn
c92f9dd404 Docs for trim operator suffix use from-version (#5161)
Trim suffix was introduced in version 5.1.23; docs should mention that.
2020-12-03 21:20:23 +00:00
Rob Hoelz
2bbcc94b4d Add documentation for shortcuts introduced in 5.1.20 (#4324) 2020-12-03 21:19:25 +00:00
Saq Imtiaz
1f5e1205ec Extend Eventcatcher to handle multiple events (#5185)
* support multiple events

* Add variables for event type and detail. Rename types attribute to events

* Correct typo in refresh handling
2020-12-02 21:15:35 +00:00
Simon Huber
6b03105bed Update CupertinoDark.tid (#5183) 2020-12-02 21:13:42 +00:00
Simon Huber
9d5babc248 Bump CodeMirror plugin version (#5184) 2020-12-02 21:12:56 +00:00
Robin Munn
e620aaed80 Fix a couple typos in "deprecated feature" warning (#5174)
One tiddler had been renamed since the deprecation warning tiddler was
created, and there were also a couple of minor punctuation and/or
spelling errors.
2020-12-02 16:59:04 +00:00
Simon Huber
552843369c Update shortcuts-mac.multids (#5179) 2020-12-02 16:55:55 +00:00
Simon Huber
f0eba7fdc6 Re-add minified codemirror, without minification bug (#5180) 2020-12-02 16:55:37 +00:00
Simon Huber
9871c1a6a9 Small tweak for codemirror selected-linenumber (#5181) 2020-12-02 16:54:36 +00:00
Simon Huber
a1ef66ec6d Better readability for codemirror linenumbers + CupertinoDark muted-foreground better contrast (#5164)
* Update styles.tid

* Update CupertinoDark.tid
2020-12-02 12:21:23 +00:00
Simon Huber
fc797f3722 Fix #5162 - tiddler opening position is incorrect, bug in navigator.js 2020-12-02 12:21:02 +00:00
Joshua Fontany
c6bb783308 Fix filesystem regression (#5176)
* $:/config/OriginalTiddlerPaths if no filters match

* fixed & docs updated

* tested with tiddlywiki.files & tw.com edition

* typos

* originalpath to options, propigate isEditableFile

* syntax cleanup
2020-12-02 09:47:51 +00:00
Simon Huber
c3055f92a9 Don't minify codemirror.js (#5173) 2020-12-01 20:55:22 +00:00
Saq Imtiaz
4079f72310 Fix typo in x-listops.js (#5171) 2020-12-01 18:14:07 +00:00
Simon Huber
cc1f32067f Update CodeMirror to 5.58.3 - fix vim-mode cursor invisible (#5172)
* Update codemirror to v5.58.3

* Update jump-to-line.js

* Update search.js
2020-12-01 18:11:40 +00:00
Mario Pietsch
880930da8b Add actions parameter to range-widget + docs! (#5158)
* add actionsStart, -Stop and actions to range-widgets

* fix indent
2020-12-01 18:11:09 +00:00
Joshua Fontany
68cb08749f Docs for filesystem adaptor update (#5169)
* rebased to master

* cleanup typos

* typo
2020-12-01 17:36:38 +00:00
jeremy@jermolene.com
13b69a9c10 Missing docs for working with negative years 2020-12-01 15:51:07 +00:00
jeremy@jermolene.com
b63049b4df Fix tests to work in other timezones
Oops.
2020-12-01 10:52:24 +00:00
jeremy@jermolene.com
6a91dbfe2f Add support for working with negative dates
See discussion https://groups.google.com/g/tiddlywiki/c/aHlyaHr93Io/m/vGcDa6lxAgAJ
2020-12-01 10:39:27 +00:00
Joshua Fontany
dde4182830 Fix filesystem adaptor (#5113)
* ignore .env

testing new implementation

almost there

closer

bug, desyncing

fixed

final testing

final testing

cleanup

cleanup

* isEditableFile flow fixed

* removed `basepath` logic

* callback to delete title from $tw.boot.files

* comment fix

* have syncer delete from boot.files

* syntax

* bugfix: error on missing directory

* bugifx

* remove !draft check

* fix relative filepaths

* cleanup

* cleanup !draft

* catch undefined filepaths in deleteTiddlerFile()

* typo

* whitelist wiki dir, encodeURIComponent otherwise

* test for wikiPath, not wikiPath/tiddlers

* don't need to .normailze()

* whitelist wiki directory, move cleanup to util

* use cleanup util & fail EPERM & EACCESS gracefully

* comments

* final bugs fixed

* improved sync error
2020-11-30 22:31:48 +00:00
Rob Hoelz
abe9af1369 Add documentation for indexer modules (#4873) 2020-11-30 22:10:07 +00:00
Florian Kohrt
6f09a5ee65 Fix link to TiddlyWikiFolders (#4843)
* Fix link to TiddlyWikiFolders

* Better link to tiddlywiki.info reference tiddler
2020-11-30 21:34:00 +00:00
Florian Kohrt
706fc3e06e Fix typo; closes #4815 (#4844) 2020-11-30 21:33:16 +00:00
Simon Huber
6a319940d3 Make buttons look like buttons in CupertinoDark, GruvboxDark and DesertSand palette (#5159)
* Make buttons look like buttons in CupertinoDark palette

* Update GruvBoxDark.tid

* Update DesertSand.tid
2020-11-30 21:04:14 +00:00
jeremy@jermolene.com
fe8606759e Fix parsing of dates between 0 and 100 AD 2020-11-30 18:56:52 +00:00
Mario Pietsch
1de747b182 add docs for radio-actions (#5156) 2020-11-30 18:48:48 +00:00
jeremy@jermolene.com
3406b98af6 Add "autocomplete" attribute to <$edit> and <$edit-text> widgets 2020-11-30 18:48:04 +00:00
Bram Chen
80191903b6 Update chinese translations (#5145)
* Improve `References/Caption`
* Add `Basics/RemoveTags` and `Basics/RemoveTags/Hint`
2020-11-30 17:58:33 +00:00
Simon Huber
367854c81b Update static.tiddler.html.tid (#5148) 2020-11-30 17:56:19 +00:00
Robin Munn
4f13848ca2 Document using double hashes for anchor links (#5149)
This is based on #3836, updated and revised with the edits made by
Watt on the Google Group.
2020-11-30 17:54:45 +00:00
Robin Munn
fd3e77d38f "dedupe" and "raw" suffixes for enlist-input operator (#5152)
Includes unit tests.
2020-11-30 17:52:46 +00:00
saqimtiaz
8fc6910c03 Added string operator pad[] along with tests and docs (#5146) 2020-11-30 17:43:50 +00:00
Robin Munn
4623c45d29 Tag trim operator as a string operator (#5147)
* Tag trim operator as a string operator

With the new functionality of the trim operator in 5.1.23, it's now a
general-purpose string manipulation tool. So it should be given the
"String operators" tag so that people see it in the same list as
removeprefix and removesuffix, etc.

* Document suffix of trim operator
2020-11-30 17:30:51 +00:00
Mario Pietsch
5cbe4c5317 Add radio actions, th-radio-variables hook and fix label refresh problem (#5154)
* Add actions to radio-widget, pass trhough all attributes and user parameters, fix label refresh

* invoke th-radio-hook instead of hardcoded variables

* simplify code and test it with a plugin hook

* remove hook
2020-11-30 17:28:49 +00:00
Jeremy Ruston
4d9e6831bb Rename "references" to "backlinks" in the tiddler info panel (#5143)
* Rename "references" to "backlinks" in the tiddler info panel

* Change docs references to "references" to "backlinks"
2020-11-29 18:32:22 +00:00
Robin Munn
5887c6621e Create "Filter Run Prefix (Examples)" tiddler (#5144)
Move the `+` vs `:intersection` example into a separate Examples tiddler
which can be expanded on later.
2020-11-29 15:45:39 +00:00
Simon Huber
ce937595d7 Add Button to remove tags from tiddlers $:/config/NewTiddler/Tags and $:/config/NewJournal/Tags (#5140)
* Update Basics.tid

* Update ControlPanel.multids

* Update Basics.tid

* Update ControlPanel.multids

* Update ControlPanel.multids

* Update ControlPanel.multids
2020-11-29 12:52:50 +00:00
jeremy@jermolene.com
cc850d7151 Fix typo in list macro
See discussion https://github.com/Jermolene/TiddlyWiki5/pull/3710#issuecomment-735295319
2020-11-29 12:38:09 +00:00
Bram Chen
a21428a33a Add chinese translations for Saving/TiddlySpot/ReadOnly (#5139) 2020-11-29 12:26:21 +00:00
saqimtiaz
12bb938463 Corrected typo in contributor's name (#5138) 2020-11-28 22:05:54 +00:00
Jeremy Ruston
e54f3368e9 Update contributors list in release note 2020-11-28 21:43:09 +00:00
Simon Huber
eb7f59a855 Make "tc-dirty" update also on external windows (#5129)
* Update windows.js

* Update saver-handler.js

* Update saver-handler.js
2020-11-28 21:24:01 +00:00
Simon Huber
b3cbd7d733 Add TiddlySpot-ReadOnly Message-Box to Tiddlyspot Saving Panel (#5133)
* Add message box to TiddlySpot Saving panel

* add readonly message
2020-11-28 21:22:32 +00:00
Simon Huber
28724138d1 Small update for better readability for CupertinoDark palette (#5134) 2020-11-28 21:21:53 +00:00
Simon Huber
62a2a0e579 Fix typo in vanilla/base (#5135) 2020-11-28 21:13:18 +00:00
jeremy@jermolene.com
98e60758a9 Updated Release Note 2020-11-28 17:32:42 +00:00
Simon Huber
c655ec5469 Remove background-colors from framed engine (#5131) 2020-11-28 14:08:16 +00:00
Simon Huber
7d2703bffb Make tiddler-editor iframe same color as tiddler background (#5132) 2020-11-28 14:07:46 +00:00
Simon Huber
09d7a77f1b Add default "tiddlywiki" styles to CodeMirror and Highlight.js (#5128)
* Update styles.tid

* Update styles.tid

* Update theme.tid

* Delete cm-theme-tiddlywiki.tid
2020-11-28 14:07:12 +00:00
Simon Huber
8005c91e79 Correctly add EventListener 'click' for popup-handling in new windows (#5127) 2020-11-28 07:26:47 +00:00
Simon Huber
86a9f922bf Update LayoutSwitcher.tid (#5125) 2020-11-27 21:52:26 +00:00
saqimtiaz
2175be27b0 Ensure that we always fetch the latest sha bypassing cache. (#5126)
Ensure that we always fetch the latest sha bypassing cache.
2020-11-27 21:37:11 +00:00
jeremy@jermolene.com
9637a29e55 Rename widget.executeStartupTiddlers() to invokeActionsByTag()
This method was introduced earlier in v5.1.23 in  5cc1600072

It is not in fact restricted to startup tiddlers.
2020-11-26 12:41:24 +00:00
Mario Pietsch
8320a55fef fix titlebar line-height for chrome (#5122) 2020-11-25 16:27:31 +00:00
jeremy@jermolene.com
2267e31546 Fix eventcatcher to ensure variable values are strings
I was getting some inconsistencies with filter operators that expect strings.
2020-11-25 15:54:28 +00:00
jeremy@jermolene.com
e3bf1f43cf Missed off previous commit 64ac29adc
Thanks @saqimtiaz
2020-11-25 14:07:01 +00:00
jeremy@jermolene.com
64ac29adca Fix typo preventing filter run prefix modules from being cached
This had a significant impact on performance.
2020-11-25 13:58:54 +00:00
jeremy@jermolene.com
94ffb50e04 Fix dark mode event handling
Previous code worked but this matches the spec, and works on iOS
2020-11-25 12:33:39 +00:00
jeremy@jermolene.com
3e3f185562 Clarify behaviour of self closing tags 2020-11-25 09:44:48 +00:00
saqimtiaz
6c98bb706a Docs for switching layouts (#5109) 2020-11-24 21:38:18 +00:00
Bram Chen
4f88d79d8b Add chinese translations for Switchers (#5111) 2020-11-24 21:27:24 +00:00
saqimtiaz
0e247c991d Update modifier variable docs (#5114)
Listing the potential key combination in a single line is hard to read and also redundant when we have the same information in the table below.
2020-11-24 21:19:37 +00:00
saqimtiaz
ce27492b96 Refactor updating of classes for button widgets to avoid potential edge case failures (#5115) 2020-11-24 21:19:20 +00:00
Simon Huber
a9d583b85e Update CupertinoDark.tid (#5117) 2020-11-24 21:16:24 +00:00
Simon Huber
5769cf9784 Fix #5108 - vanilla/reset overrides system fonts (#5118) 2020-11-24 21:15:37 +00:00
jeremy@jermolene.com
c854e518fa Add support for $:/info/darkmode (and for dynamic info tiddlers) 2020-11-24 19:01:33 +00:00
jeremy@jermolene.com
7327a3fb92 Fixed: Shadow tiddlers don't refresh when their plugin is deleted/modified 2020-11-24 18:57:39 +00:00
Simon Huber
50a3c5526f Update CupertinoDark.tid (#5107) 2020-11-23 20:09:53 +00:00
Simon Huber
77971ff720 Lighter sidebar-controls-foreground for Cupertino Dark Palette (#5106) 2020-11-23 19:41:51 +00:00
Simon Huber
e0f4d82214 Update CupertinoDark.tid (#5105) 2020-11-23 19:32:51 +00:00
Simon Huber
af72fdf245 Add caption to ControlPanel LayoutSwitcher (#5103)
* Update LayoutSwitcher.tid

* Update ControlPanel.multids
2020-11-23 19:15:04 +00:00
Simon Huber
519962b4a9 Update and rename MacOSDark.tid to CupertinoDark.tid (#5101)
* Update and rename MacOSDark.tid to CupertinoDark.tid

* Update CupertinoDark.tid

* Update CupertinoDark.tid

* Update CupertinoDark.tid
2020-11-23 19:14:07 +00:00
Simon Huber
c9a77c5877 Create MacOSDark.tid (#5100) 2020-11-23 18:41:38 +00:00
Simon Huber
3d93790573 Fix StaticRiver exporter width of static tiddlers (#5099)
* Add tc-static-story-river class to StaticRiver exporter

* Update base.tid
2020-11-23 18:06:46 +00:00
saqimtiaz
cb62c8c96d Docs for eventcatcher (#5097) 2020-11-23 17:07:41 +00:00
saqimtiaz
aa6f152d35 Add Switcher modal (#5089)
* Alternative switcher using a parameter via tm-show-switcher

* Add CSS class for centered modals

* Changed keyboardshortcut and removed transition CSS

* Resolved wording issues
2020-11-23 17:06:24 +00:00
Simon Huber
72b32946aa Small adjustments for DesertSand palette (#5098)
* Small adjustments for DesertSand palette

* Update DesertSand.tid
2020-11-23 16:59:48 +00:00
Mario Pietsch
60850ee69b Update German Language (#5096)
* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* Don't override browser selection colours by default

Reverts some of #4590

* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* Update German Language

* some typos

Co-authored-by: jeremy@jermolene.com <jeremy@jermolene.com>
2020-11-23 16:24:37 +00:00
Simon Huber
8c4d67ba2b Add light "DesertSand" palette - a desert-sandy palette (#5092)
* Add light "DesertSand" palette - a desert-sandy palette

* Update DesertSand.tid

* Update DesertSand.tid
2020-11-22 21:18:34 +00:00
saqimtiaz
3c195b05cb Button and Droppable widgets: improve refresh handling for classes (#5091)
* Button and Droppable widgets: improve refesh handling for classes

* Added comment regarding handling of class attribute
2020-11-22 21:13:24 +00:00
Simon Huber
530b4308e3 Make type input field min-width the highest character length of selectable types (#5090)
* Make type input field min-width the highest character length of selectable types

* Update base.tid

* Update base.tid
2020-11-22 21:12:19 +00:00
saqimtiaz
fa63ac5d1e Add: Eventcatcher widget (#5086)
* Jeremy's original version of the event widget

* Renamed to eventcatcher, added modifier key support and mouse button support as variables

* Allow updating classname without re-rendering entire widget

* Handle tag attribute in refresh handler

* Improve handling for mouse button variable

* Fix typo in refresh handler

* Added variables for position of selected node and position of event relative to selected node and catcher node
2020-11-22 20:47:12 +00:00
saqimtiaz
51ca14861e Fixed bug with default value in lookup operator (#5088)
* Fixed bug with default value in lookup operator

* Fixed test for lookup operator with default
2020-11-22 20:43:36 +00:00
saqimtiaz
d2f87d6200 Reveal widget allow re-positioning (#5087)
* Jeremy's original version of the event widget

* Renamed to eventcatcher, added modifier key support and mouse button support as variables

* Reveal widget: update popup position when state tiddler updates
2020-11-21 17:19:52 +00:00
saqimtiaz
a0f145197c Correct error in operator documentation (#5084) 2020-11-20 21:34:43 +00:00
saqimtiaz
c97003238b Doc updates for ActionLog and Log widgets (#5081) 2020-11-20 18:37:48 +00:00
saqimtiaz
4f07539164 Cycle operator improvements plus docs (#5069)
* Tweak cycle operator to support step size parameter and add docs for toggle and cycle

* Mention that title list should have no duplicates
2020-11-20 18:37:23 +00:00
Simon Huber
5945506169 Revert line-height of 3em on tiddler-edit-title (#5083) 2020-11-20 18:21:30 +00:00
saqimtiaz
483fd941f5 Extend action-log and subclass it as log widget (#5078)
* Extended action-log and subclassed it as log widget

* Do not rename LogWidget class

* Removed unneeded variable declaration
2020-11-20 14:08:18 +00:00
Simon Huber
1339c23b3a Adjustments for narrow screens (#5079) 2020-11-20 14:00:56 +00:00
saqimtiaz
89541edcff Added mathematics filter operators power and log (#5080) 2020-11-20 14:00:20 +00:00
Simon Huber
fd14e94610 Add whitespace trims to EditToolbar Buttons (#5076)
* Add whitespace trim to EditToolbar cancel Button

* Add whitespace trim to EditToolbar delete Button

* Add whitespace trim to EditToolbar save Button
2020-11-19 16:37:36 +00:00
Simon Huber
f591a78f37 Fix small typo in syncer-actions-refresh.tid (#5075) 2020-11-19 16:32:43 +00:00
saqimtiaz
e2bea854b6 System tiddler syncing (#4987)
* First pass at a fix for system tiddler sync issues

* Add new filter syncFromServer

* Undo previous attempt at a fix

* Added a flag to control sync of system tiddlers from server
2020-11-19 15:59:02 +00:00
jeremy@jermolene.com
0d434583ec Merge branch 'tiddlywiki-com' 2020-11-19 10:01:23 +00:00
jeremy@jermolene.com
a81b7fc9f4 Remove extraneous modifier/creator fields
Fixes #5068
2020-11-18 18:21:38 +00:00
Simon Huber
da66323dc5 Remove 2em of whitespace from EditTemplate when there are no visible fields (#5063)
* Remove 2em of whitespace from EditTemplate when there are no visible fields

* Update base.tid

* Update fields.tid

* Update fields.tid

* Update base.tid
2020-11-18 18:02:40 +00:00
jeremy@jermolene.com
0be778fc27 Update Dutch translation
Thanks @gernert
2020-11-18 16:56:01 +00:00
Bram Chen
37f4421ed1 Improve chinese status messages in ImportListing (#5064) 2020-11-18 16:39:45 +00:00
jeremy@jermolene.com
f61906501d Fix issue with Arabic translation
See discussion https://groups.google.com/d/msgid/tiddlywikidev/bb2f558e-5daa-4f18-8dca-73abc61d4dbfn%40googlegroups.com

@Kamal-Habash the .multids file does not allow line breaks in items. Does my fix look right?
2020-11-18 16:31:28 +00:00
saqimtiaz
1a8c6fdc4b Docs: Added example of how to remove stop words (#5066)
* Added example of how to remove stop words

* Moved filter operator example tiddlers to correct folder
2020-11-18 15:56:38 +00:00
saqimtiaz
6f8dca956b Colour code ImportListing rows (#5067) 2020-11-18 15:50:40 +00:00
jeremy@jermolene.com
061b75741b Fix GitHub Actions
Copied from 4ecd885a0c which fixes #4885
2020-11-18 13:14:19 +00:00
jeremy@jermolene.com
d181b96518 Wikitext parser: Refactor a poorly written utility function 2020-11-18 12:05:06 +00:00
saqimtiaz
527638d5e6 Improved status messages in ImportListing to remove redundant and irrelevant messages (#5059) 2020-11-17 19:12:41 +00:00
Simon Huber
b95f9e6000 Partial fix for issue #4721 (#5060)
* Update new-tiddler.tid

* Update new-journal.tid

* Update new-image.tid
2020-11-17 19:08:14 +00:00
Mohammad Rahmani
6d5ea90bfd Add resources by Mohammad (#5061)
* Correct for new GitHub default branch

This PR corrects the default branch of GitHub from master to main. This is ne GitHub repository configuration from Oct 1st, 2020

* Update Saving to a Git service.tid

GitLab still uses `master` as default branch.

* Add Kookma plugins as resources

Some of Kookma resources including TW-Scripts, Commander, Trashbin, Todolist has been added.

* Revert "Add Kookma plugins as resources"

This reverts commit 199fce3a08.

* Adding Resources by Mohammad

This PR adds resources created by Mohammad mostly in GitHub
2020-11-17 19:07:32 +00:00
Simon Huber
eae3da0e9d Make sidebarsegments/search-results-count work with all search tabs (#5062) 2020-11-17 19:05:32 +00:00
Bram Chen
684f13fbcb Add chinese translations for ConfirmAction (#5056) 2020-11-17 14:47:31 +00:00
jeremy@jermolene.com
8cd13e2f89 Change default branch for GitHub saver to "main"
To match GitHub's new default

See also #5055 for the accompanying docs change
2020-11-17 14:47:15 +00:00
Mohammad Rahmani
3b75297168 Correct for new GitHub default branch (#5055)
* Correct for new GitHub default branch

This PR corrects the default branch of GitHub from master to main. This is ne GitHub repository configuration from Oct 1st, 2020

* Update Saving to a Git service.tid

GitLab still uses `master` as default branch.

* Add Kookma plugins as resources

Some of Kookma resources including TW-Scripts, Commander, Trashbin, Todolist has been added.

* Revert "Add Kookma plugins as resources"

This reverts commit 199fce3a08.
2020-11-17 14:45:32 +00:00
saqimtiaz
2b60ab1fdc Doc updates for Modals (#5057) 2020-11-17 14:43:46 +00:00
saqimtiaz
d6e055368d Added docs for action-confirm widget, added default message for widget and improved logic for disabling it. (#5047) 2020-11-16 17:02:22 +00:00
saqimtiaz
fc1721709a Cycle operator and refactored toggle operator (#5021)
* Refactored toggle operator and added cycle operator

* Better handling for operand case

* Syntax/whitespace corrections
2020-11-16 17:02:04 +00:00
Simon Huber
43061e64a6 Fix #5039 - Tag input, Type input and Fields inputs don't delete their state tiddlers on tiddler-cancel/delete (#5049)
* Update EditTemplate.tid

* Update EditTemplate.tid

* Update EditTemplate.tid

* Update tag-picker.tid

* Update tag-picker.tid

* Update type.tid

* Update fields.tid

* Update cancel.tid

* Update delete.tid

* Update type.tid

* Update ViewTemplate.tid
2020-11-16 16:54:29 +00:00
Robin Munn
d8d88c67e3 Fix minor mistake in ButtonWidget docs (#5050)
The ButtonWidget documentation refers to a "state" attribute, but this
should probably be "set". The name "state" appears to be an artifact
from when the setTitle, setField, and setIndex attributes were added to
the widget; at one time they were called stateTitle and so on, and then
they were renamed to setTitle instead, but not every instance of "state"
was found and renamed to "set". This is one such instance, now fixed.
2020-11-16 16:50:32 +00:00
Robin Munn
ffd6a8cce7 More documentation for :intersection filter prefix (#5051) 2020-11-16 16:32:28 +00:00
saqimtiaz
a637f7fb60 Modals: add navigator to handle tm-navigate (#5027)
* Wrap modal in a navigator widget to allow tm-navigate to work

* Move all story list handling to Modal

* Make sure any values for story list or history list sent as variables have precedence

* Code clean up
2020-11-16 16:27:46 +00:00
Simon Huber
ca4cdc81dd Remove reduntant fieldmangler widget from tags EditTemplate (#5044) 2020-11-15 16:04:39 +00:00
saqimtiaz
13499557bf Fix whitespace in x-listops.js and tweak toggle operator (#5024)
* Replaced leading spaces with tabs

* Tweak toggle[] to insert new value in same list position
2020-11-15 16:04:03 +00:00
Simon Huber
a2b2e117e3 Delete all state tiddlers after adding a new field (#5045) 2020-11-15 15:49:43 +00:00
Bram Chen
d9b8a800c6 Update chinese translations (#5046)
* add the tooltip and aria-label of clear-tag-input button
2020-11-15 15:49:05 +00:00
Simon Huber
2aa6e761fd Make Tag-Picker Macro work with every field (#5035)
* Make tag-picker work with every field

* Make EditTemplate/tags work with every field

* Make NewTiddlerTags and NewJournalTags selectable through tag-picker

* Update tag-picker Macro Docs
2020-11-15 12:04:50 +00:00
Simon Huber
7078ca2c1e Revert Tag-input behavior to how it was before (#5041) 2020-11-15 11:42:46 +00:00
saqimtiaz
04bf6e0fd8 Action widget: confirm (#5037)
* added action widget: confirm

* Check for all attributes in refresh handler

* Always return a value from invokeActions
2020-11-15 11:40:08 +00:00
Simon Huber
bb6fee4e1c Remove image-buttons from type image/svg+xml and add editor-height and stamp button (#5042)
* Add stamp button to image/svg+xml

* Add editor-height Button to image/svg+xml

* Remove rotate-left button from image/svg+xml

* Remove size Button from image/svg+xml

* Remove paint Button from image/svg+xml

* Remove line-width Button from image/svg+xml

* Remove clear Button from image/svg+xml

* Remove opacity Button from image/svg+xml
2020-11-15 11:37:30 +00:00
Xavier Cazin
f087a62c99 fr-FR translations updates (#5043)
* fr-FR translations for Shortcut hints

* fr-FR translations related to renaming tiddlers during Import

* Correction of NewJournal Tags default config in fr-FR

* fr-FR update for the rendertiddlers command

* fr-FR translations for new Filter errors

* fr-FR update for the savetiddlers command

* fr-FR update for the savetiddler command

* fr-FR update for the rendertiddler command

Co-authored-by: Xavier Cazin <xavier.cazin@gmail.com>
2020-11-15 11:35:17 +00:00
jeremy@jermolene.com
1b31c25ea7 Introduce <$action-log> widget to help debugging action strings 2020-11-14 13:00:00 +00:00
Simon Huber
02a956b1bb Add Pop Storyview to Manager Tags Section (#5034) 2020-11-14 12:32:39 +00:00
jeremy@jermolene.com
cc3462999b When importing don't use file type as content type
Fixes #5028

I've checked that importing other file types still works but would appreciate a sanity check!
2020-11-14 12:05:35 +00:00
Simon Huber
b63c90e401 Add missing tooltip and aria-label to clear-tag-input button (#5033)
* Add tooltip and aria-label to new clear-tags-input button

* Update EditTemplate.multids
2020-11-13 19:19:55 +00:00
Simon Huber
497b334d60 Change tag-picker behavior when there is user-input ... (#5032)
... in the search field
2020-11-13 18:50:50 +00:00
Simon Huber
fa373a1c6f Make keyboard-driven-input Macro reset to typed input ... (#5031)
... on up/down when reaching the top/bottom of the list
2020-11-13 18:01:24 +00:00
jeremy@jermolene.com
1eac5c051f Menu lists should only use white-space: nowrap in the sidebar
Fixes #5030
2020-11-13 18:00:37 +00:00
saqimtiaz
568990409a Fix typo in toggle operator docs (#5020) 2020-11-09 20:43:44 +00:00
saqimtiaz
09f7ad84b2 Added disabled attribute to input widgets (#5014)
* checkbox widget: added disabled attribute

* Range widget: added disabled attribute

* Radio widget: added disabled attribute

* EditText widget: added disabled attribute
2020-11-09 18:28:12 +00:00
saqimtiaz
445c15e719 Extend toggle operator (#5015)
* Extend toggle operator to support optional second operand to toggle a value pair

* Added tests for extended toggle filter

* Updated docs for toggle operator
2020-11-09 18:27:45 +00:00
Simon Huber
27bed615ab Move styles from menubar plugin to vanilla/base (#5019)
* Update styles.tid

* Update base.tid

* Update styles.tid

* Update base.tid
2020-11-09 18:18:30 +00:00
jeremy@jermolene.com
1ec8b7877e Ensure root template contents is parsed in block mode
Embarrassingly, the double blank lines at the end of the tiddler are needed to ensure the transclude widget is recognised in block mode, instead of being wrapped in a paragraph tag.

Fixes #5016
2020-11-09 17:08:34 +00:00
saqimtiaz
59c6f4447e Import UI : Fix issue with size of rename button (#5012)
* Fix issue with size of rename button

* Add css instead of hard coded style attribute
2020-11-08 23:21:01 +00:00
Simon Huber
343207fc35 MenuBar: Add fallback value to breakpoint-plus-one and ... (#5009)
* Add fallback value to breakpoint-plus-one and ...

... sidebarbreakpoint-minus-one in case that widths aren't given in px units

* Update styles.tid
2020-11-08 22:38:08 +00:00
saqimtiaz
519ce3e89d Update Release 5.1.23.tid (#5005)
Updated release notes
2020-11-08 22:37:43 +00:00
saqimtiaz
71194d8767 Added disabled attribute support to ButtonWidget (#5010)
* Added disabled attribute to ButtonWidget

* Update ButtonWidget.tid
2020-11-08 22:32:27 +00:00
Simon Huber
480e4e2ce9 Make fieldvalue-input a bit larger when viewport is narrow (#5007)
* Make field-value input display a bit larger when narrow

* Update base.tid

* Update base.tid

* Update base.tid
2020-11-08 22:30:31 +00:00
Simon Huber
db48ce5f2c Correct breakpoint for no-box-shadow in snowwhite/base stylesheet (#5008) 2020-11-08 22:28:32 +00:00
Simon Huber
4d85d267a1 Make navigating and editing Shadow tiddlers work again (#5004)
* Update search.tid

* Update Filter.tid

* Update Shadows.tid

* Update Standard.tid

* Update System.tid

* Update search.tid
2020-11-08 13:26:02 +00:00
Simon Huber
98f67373b1 Menubar plugin: make sidebar-scrollable top margin adjust ... (#4974)
* Menubar plugin: make sidebar-scrollable top margin adjust ...

... to height of menubar

* Update styles.tid

* Update styles.tid

* Update styles.tid

* Update styles.tid

* Update menu.tid

* Update styles.tid

* Update styles.tid

* Update styles.tid

* Update styles.tid

* Update menu.tid

* Update styles.tid

* Update styles.tid
2020-11-08 11:50:15 +00:00
ento
e574cb4724 Markdown plugin: add rel="noopener noreferrer" to external links (#4771) 2020-11-08 11:47:44 +00:00
Robin Munn
e72d90c227 More examples for enlist-input operator (#4968)
The examples should also show what would happen without the operator, to
give a better feel for why it's useful.
2020-11-08 11:47:15 +00:00
Simon Huber
c729115506 Update modifier Variable.tid with a test-button and... (#5002)
... a tip for meta-key detection on various operating systems
2020-11-08 11:46:13 +00:00
Simon Huber
9854a4fc08 Fix #4998 - Pressing Enter creates Missing Tiddler (#5001)
* Update search.tid

* Update Filter.tid

* Update Shadows.tid

* Update Standard.tid

* Update System.tid

* Update search.tid

* Create Hidden Setting Search-NavigateOnEnter.tid
2020-11-08 11:43:24 +00:00
Simon Huber
9fe4c4889a Add "meta" to getEventModifierKeyDescriptor (#5000)
* Add "meta" to getEventModifierKeyDescriptor

* Update modifier Variable.tid
2020-11-08 10:15:29 +00:00
Simon Huber
750f56a235 Update Basics.tid (#4999) 2020-11-08 09:44:49 +00:00
saqimtiaz
66636d1a86 Docs for new operators (#4994)
* Docs for is[draft]

* Better error handling for suffixes

* Docs for search-replace operator

* Added tests for search-replace operator

* Docs for toggle operator
2020-11-08 09:34:05 +00:00
saqimtiaz
2a7cdb22c0 Documentation for multiple filter operands (#4969) 2020-11-08 09:32:37 +00:00
Simon Huber
b69b84b38e Update core "tabs" macros to use explicitState (#4985)
* Update ControlPanel.tid

* Update Advanced.tid

* Update Appearance.tid

* Update Info.tid

* Update AddPlugins.tid

* Update Plugins.tid

* Update Saving.tid

* Update Toolbars.tid

* Update Plugins.tid

* Update More.tid

* Update TiddlerInfo.tid

* Update tabs.tid

* Update settings.tid

* Update ControlPanel.tid

* Update Advanced.tid

* Update Appearance.tid

* Update Info.tid

* Update AddPlugins.tid

* Update Plugins.tid

* Update Saving.tid

* Update Toolbars.tid

* Update Plugins.tid

* Update More.tid

* Update tabs.tid

* Update settings.tid

* Update TiddlerInfo.tid

* Update AdvancedSearch.tid

* Update Filter.tid

* Update Shadows.tid

* Update Standard.tid

* Update System.tid
2020-11-08 09:31:39 +00:00
saqimtiaz
ee250bf6c9 Updated release notes (#4997) 2020-11-08 09:26:58 +00:00
Simon Huber
de69ab0d0e Update keyboard-driven type-input actions on "Escape" (#4992)
* Delete "type" field when pressing escape in type input

* Update type.tid
2020-11-07 12:21:24 +00:00
saqimtiaz
cf58dcf116 Add is[draft] operator (#4991) 2020-11-07 10:29:15 +00:00
saqimtiaz
53922d3558 search-replace string operator (#4973)
* Added search-replace operator

* Merge with master

* Add try catch around new RegExp

* Better error handling
2020-11-07 10:09:11 +00:00
saqimtiaz
c41e34793d Add x-listops filter toggle (#4990) 2020-11-07 10:00:47 +00:00
saqimtiaz
5aa4e4cb68 Initial support for switching page templates (#4979)
* Add support for switching page templates

* Revert "Add support for switching page templates"

This reverts commit dbf7682d47.

* Adopt Jeremy's approach to page template switching instead

* Fix default value of recursion marker

* Fixed issue with conditional check
2020-11-07 09:51:01 +00:00
saqimtiaz
2b31c7a509 Multiple operands for filter operators (#4964)
* Firt pass at adding multiple operands to filter operators

* Optimized parsing of multiple operands and added more tests. Need more flexibility for interpreting multiple operands as variables/text references

* Add support for parsing text references and variables in multiple operands

* Added string-replace filter for testing multiple filter operands

* Added more tests for variables and text references in operands

* Removed string-replace operator and some whitespace corrections

* Removed string-replace operator and some whitespace corrections

* Added test with comma in operand
2020-11-07 09:47:08 +00:00
Simon Huber
0bd866e2f9 Make type input keyboard-driven (#4989) 2020-11-07 09:46:05 +00:00
jeremy@jermolene.com
93e7380188 Update default body text font to modern-normalize.css default
Fixes #4988
2020-11-07 09:45:03 +00:00
jeremy@jermolene.com
9003c81039 Switch to more modern fork of normalize.css
https://github.com/sindresorhus/modern-normalize
2020-11-07 09:42:37 +00:00
Simon Huber
900a29fbb3 Tag-picker: focus tag-input after clicking a tag from the dropdown (#4986)
* Tag-picker: focus tag-input after clicking a tag from the dropdown

* Update tag-picker.tid
2020-11-06 21:16:14 +00:00
Simon Huber
b3d0303139 Add editor-height button and stamp-button to tiddler types that miss them (#4975)
* Add editor-height button also to application/javascript ...

... application/json and application/x-tiddler-dictionary

* Add stamp button also to application/javascript ...

... application/json and application/x-tiddler-dictionary
2020-11-06 18:34:10 +00:00
Miha Lunar
feefc4cceb Signing the CLA (#4976) 2020-11-06 17:51:53 +00:00
Simon Huber
d51975b183 KeyboardWidget: don't trap keyboard shortcut if actions and message are empty and invokeActions isn't handled (#4971)
* KeyboardWidget: don't trap keyboard shortcut if actions are empty

* Update keyboard.js

* Update keyboard.js
2020-11-06 17:32:26 +00:00
jeremy@jermolene.com
15e8772170 Remove erroneously committed file 2020-11-06 17:01:13 +00:00
Simon Huber
bc5143f190 When accessing the AdvancedSearch from the sidebar, delete sidebar-search state tiddlers (#4981) 2020-11-06 16:53:11 +00:00
Simon Huber
458460354e Add delete-field keyboard shortcut (#4978)
* Add delete-field keyboard-widget

* Update shortcuts.multids

* Update ShortcutInfo.multids

* Update fields.tid

* Update shortcuts.multids
2020-11-06 16:27:41 +00:00
Simon Huber
78c72b85fb Make tag for menubar-contents dropdown configurable (#4983)
* Make tag for menubar-contents dropdown configurable

* Make tag for menubar-contents dropdown configurable

* Make tag for menubar-contents dropdown configurable
2020-11-06 16:26:44 +00:00
jeremy@jermolene.com
22e25c05eb Remove normalize.css's styling of search inputs
As discussed here: https://github.com/Jermolene/TiddlyWiki5/issues/4984#issuecomment-723169753
2020-11-06 16:24:05 +00:00
jeremy@jermolene.com
4394b8e723 Dynannotate: Add example of view template usage 2020-11-06 12:27:46 +00:00
Robin Munn
c0b021f509 Typo fix (#4951) 2020-11-01 11:03:59 +00:00
twMat
4914208011 Update Configuring startup tiddlers.tid (#4009) 2020-10-29 12:57:11 +00:00
jeremy@jermolene.com
9eec6ff915 Update path-prefix docs
Addressing @OblivionSY's comment https://github.com/Jermolene/TiddlyWiki5/issues/4898#issuecomment-717207456
2020-10-27 12:32:06 +00:00
Mario Pietsch
15338e60e8 Get "New Release Banner" from TW5-com edition (#4912)
* Fix state tiddlers for action-create-tiddlers examples

* Get "New Release Banner" from TW5-com edition
2020-10-25 22:03:35 +00:00
Mario Pietsch
7686be7b14 Fix state tiddlers for action-create-tiddlers examples (#4897) 2020-10-23 16:23:17 +01:00
318 changed files with 5491 additions and 1267 deletions

View File

@@ -305,13 +305,21 @@ $tw.utils.stringifyDate = function(value) {
// Parse a date from a UTC YYYYMMDDHHMMSSmmm format string
$tw.utils.parseDate = function(value) {
if(typeof value === "string") {
return new Date(Date.UTC(parseInt(value.substr(0,4),10),
var negative = 1;
if(value.charAt(0) === "-") {
negative = -1;
value = value.substr(1);
}
var year = parseInt(value.substr(0,4),10) * negative,
d = new Date(Date.UTC(year,
parseInt(value.substr(4,2),10)-1,
parseInt(value.substr(6,2),10),
parseInt(value.substr(8,2)||"00",10),
parseInt(value.substr(10,2)||"00",10),
parseInt(value.substr(12,2)||"00",10),
parseInt(value.substr(14,3)||"000",10)));
d.setUTCFullYear(year); // See https://stackoverflow.com/a/5870822
return d;
} else if($tw.utils.isDate(value)) {
return value;
} else {
@@ -1886,7 +1894,7 @@ $tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
});
});
if(isEditableFile) {
tiddlers.push({filepath: pathname, hasMetaFile: !!metadata && !isTiddlerFile, tiddlers: fileTiddlers});
tiddlers.push({filepath: pathname, hasMetaFile: !!metadata && !isTiddlerFile, isEditableFile: true, tiddlers: fileTiddlers});
} else {
tiddlers.push({tiddlers: fileTiddlers});
}
@@ -1912,15 +1920,21 @@ $tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
}
} else {
// Process directory specifier
var dirPath = path.resolve(filepath,dirSpec.path),
files = fs.readdirSync(dirPath),
fileRegExp = new RegExp(dirSpec.filesRegExp || "^.*$"),
metaRegExp = /^.*\.meta$/;
for(var t=0; t<files.length; t++) {
var filename = files[t];
if(filename !== "tiddlywiki.files" && !metaRegExp.test(filename) && fileRegExp.test(filename)) {
processFile(dirPath + path.sep + filename,dirSpec.isTiddlerFile,dirSpec.fields,dirSpec.isEditableFile);
var dirPath = path.resolve(filepath,dirSpec.path);
if(fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory()) {
var files = fs.readdirSync(dirPath),
fileRegExp = new RegExp(dirSpec.filesRegExp || "^.*$"),
metaRegExp = /^.*\.meta$/;
for(var t=0; t<files.length; t++) {
var filename = files[t];
if(filename !== "tiddlywiki.files" && !metaRegExp.test(filename) && fileRegExp.test(filename)) {
processFile(dirPath + path.sep + filename,dirSpec.isTiddlerFile,dirSpec.fields,dirSpec.isEditableFile);
}
}
} else {
console.log("Warning: a directory in a tiddlywiki.files file does not exist.");
console.log("dirPath: " + dirPath);
console.log("tiddlywiki.files location: " + filepath);
}
}
});
@@ -2060,6 +2074,11 @@ $tw.loadWikiTiddlers = function(wikiPath,options) {
} else {
return null;
}
// Save the path to the tiddlers folder for the filesystemadaptor
var config = wikiInfo.config || {};
if($tw.boot.wikiPath == wikiPath) {
$tw.boot.wikiTiddlersPath = path.resolve($tw.boot.wikiPath,config["default-tiddler-location"] || $tw.config.wikiTiddlersSubDir);
}
// Load any parent wikis
if(wikiInfo.includeWikis) {
parentPaths = parentPaths.slice(0);
@@ -2093,27 +2112,30 @@ $tw.loadWikiTiddlers = function(wikiPath,options) {
$tw.boot.files[tiddler.title] = {
filepath: tiddlerFile.filepath,
type: tiddlerFile.type,
hasMetaFile: tiddlerFile.hasMetaFile
hasMetaFile: tiddlerFile.hasMetaFile,
isEditableFile: config["retain-original-tiddler-path"] || tiddlerFile.isEditableFile || tiddlerFile.filepath.indexOf($tw.boot.wikiTiddlersPath) !== 0
};
});
}
$tw.wiki.addTiddlers(tiddlerFile.tiddlers);
});
// Save the original tiddler file locations if requested
var config = wikiInfo.config || {};
if(config["retain-original-tiddler-path"]) {
var output = {}, relativePath;
if ($tw.boot.wikiPath == wikiPath) {
// Save the original tiddler file locations if requested
var output = {}, relativePath, fileInfo;
for(var title in $tw.boot.files) {
relativePath = path.relative(resolvedWikiPath,$tw.boot.files[title].filepath);
output[title] =
path.sep === "/" ?
relativePath :
relativePath.split(path.sep).join("/");
fileInfo = $tw.boot.files[title];
if(fileInfo.isEditableFile) {
relativePath = path.relative($tw.boot.wikiTiddlersPath,fileInfo.filepath);
output[title] =
path.sep === "/" ?
relativePath :
relativePath.split(path.sep).join("/");
}
}
if(Object.keys(output).length > 0){
$tw.wiki.addTiddler({title: "$:/config/OriginalTiddlerPaths", type: "application/json", text: JSON.stringify(output)});
}
$tw.wiki.addTiddler({title: "$:/config/OriginalTiddlerPaths", type: "application/json", text: JSON.stringify(output)});
}
// Save the path to the tiddlers folder for the filesystemadaptor
$tw.boot.wikiTiddlersPath = path.resolve($tw.boot.wikiPath,config["default-tiddler-location"] || $tw.config.wikiTiddlersSubDir);
// Load any plugins within the wiki folder
var wikiPluginsPath = path.resolve(wikiPath,$tw.config.wikiPluginsSubDir);
if(fs.existsSync(wikiPluginsPath)) {
@@ -2160,7 +2182,7 @@ $tw.loadTiddlersNode = function() {
// Load any extra plugins
$tw.utils.each($tw.boot.extraPlugins,function(name) {
if(name.charAt(0) === "+") { // Relative path to plugin
var pluginFields = $tw.loadPluginFolder(name.substring(1));;
var pluginFields = $tw.loadPluginFolder(name.substring(1));
if(pluginFields) {
$tw.wiki.addTiddler(pluginFields);
}

View File

@@ -17,6 +17,8 @@ Basics/NewJournal/Tags/Prompt: Tags for new journal tiddlers
Basics/NewTiddler/Title/Prompt: Title of new tiddlers
Basics/NewTiddler/Tags/Prompt: Tags for new tiddlers
Basics/OverriddenShadowTiddlers/Prompt: Number of overridden shadow tiddlers
Basics/RemoveTags: Update to current format
Basics/RemoveTags/Hint: Update the tags configuration to the latest format
Basics/ShadowTiddlers/Prompt: Number of shadow tiddlers
Basics/Subtitle/Prompt: Subtitle
Basics/SystemTiddlers/Prompt: Number of system tiddlers
@@ -44,6 +46,7 @@ KeyboardShortcuts/Platform/Linux: Linux platform only
KeyboardShortcuts/Platform/NonLinux: Non-Linux platforms only
KeyboardShortcuts/Platform/Windows: Windows platform only
KeyboardShortcuts/Platform/NonWindows: Non-Windows platforms only
LayoutSwitcher/Caption: Layout
LoadedModules/Caption: Loaded Modules
LoadedModules/Hint: These are the currently loaded tiddler modules linked to their source tiddlers. Any italicised modules lack a source tiddler, typically because they were setup during the boot process.
Palette/Caption: Palette
@@ -125,6 +128,7 @@ Saving/TiddlySpot/Filename: Upload Filename
Saving/TiddlySpot/Heading: ~TiddlySpot
Saving/TiddlySpot/Hint: //The server URL defaults to `http://<wikiname>.tiddlyspot.com/store.cgi` and can be changed to use a custom server address, e.g. `http://example.com/store.php`.//
Saving/TiddlySpot/Password: Password
Saving/TiddlySpot/ReadOnly: The ~TiddlySpot service is currently only available in read-only form. Please see http://tiddlyspot.com/ for the latest details. The ~TiddlySpot saver can still be used to save to compatible servers.
Saving/TiddlySpot/ServerURL: Server URL
Saving/TiddlySpot/UploadDir: Upload Directory
Saving/TiddlySpot/UserName: Wiki Name

View File

@@ -19,6 +19,8 @@ Shadow/OverriddenWarning: This is a modified shadow tiddler. You can revert to t
Tags/Add/Button: add
Tags/Add/Button/Hint: add tag
Tags/Add/Placeholder: tag name
Tags/ClearInput/Caption: clear input
Tags/ClearInput/Hint: Clear tag input
Tags/Dropdown/Caption: tag list
Tags/Dropdown/Hint: Show tag list
Title/BadCharacterWarning: Warning: avoid using any of the characters <<bad-chars>> in tiddler titles

View File

@@ -18,11 +18,11 @@ Listing/Rename/Prompt: Rename to:
Listing/Rename/ConfirmRename: Rename tiddler
Listing/Rename/CancelRename: Cancel
Listing/Rename/OverwriteWarning: A tiddler with this title already exists.
Upgrader/Plugins/Suppressed/Incompatible: Blocked incompatible or obsolete plugin
Upgrader/Plugins/Suppressed/Version: Blocked plugin (due to incoming <<incoming>> being older than existing <<existing>>)
Upgrader/Plugins/Upgraded: Upgraded plugin from <<incoming>> to <<upgraded>>
Upgrader/State/Suppressed: Blocked temporary state tiddler
Upgrader/System/Suppressed: Blocked system tiddler
Upgrader/System/Warning: Core module tiddler
Upgrader/System/Alert: You are about to import a tiddler that will overwrite a core module tiddler. This is not recommended as it may make the system unstable
Upgrader/ThemeTweaks/Created: Migrated theme tweak from <$text text=<<from>>/>
Upgrader/Plugins/Suppressed/Incompatible: Blocked incompatible or obsolete plugin.
Upgrader/Plugins/Suppressed/Version: Blocked plugin (due to incoming <<incoming>> not being newer than existing <<existing>>).
Upgrader/Plugins/Upgraded: Upgraded plugin from <<incoming>> to <<upgraded>>.
Upgrader/State/Suppressed: Blocked temporary state tiddler.
Upgrader/System/Suppressed: Blocked system tiddler.
Upgrader/System/Warning: Core module tiddler.
Upgrader/System/Alert: You are about to import a tiddler that will overwrite a core module tiddler. This is not recommended as it may make the system unstable.
Upgrader/ThemeTweaks/Created: Migrated theme tweak from <$text text=<<from>>/>.

View File

@@ -10,6 +10,7 @@ ConfirmCancelTiddler: Do you wish to discard changes to the tiddler "<$text text
ConfirmDeleteTiddler: Do you wish to delete the tiddler "<$text text=<<title>>/>"?
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?
Count: count
DefaultNewTiddlerTitle: New Tiddler
Diffs/CountMessage: <<diff-count>> differences
@@ -39,6 +40,7 @@ Error/XMLHttpRequest: XMLHttpRequest error code
InternalJavaScriptError/Title: Internal JavaScript Error
InternalJavaScriptError/Hint: Well, this is embarrassing. It is recommended that you restart TiddlyWiki by refreshing your browser
InvalidFieldName: Illegal characters in field name "<$text text=<<fieldName>>/>". Fields can only contain lowercase letters, digits and the characters underscore (`_`), hyphen (`-`) and period (`.`)
LayoutSwitcher/Description: Open the layout switcher
LazyLoadingWarning: <p>Trying to load external content from ''<$text text={{!!_canonical_uri}}/>''</p><p>If this message doesn't disappear, either the tiddler content type doesn't match the type of the external content, or you may be using a browser that doesn't support external content for wikis loaded as standalone files. See https://tiddlywiki.com/#ExternalText</p>
LoginToTiddlySpace: Login to TiddlySpace
Manager/Controls/FilterByTag/None: (none)
@@ -62,6 +64,8 @@ MissingTiddler/Hint: Missing tiddler "<$text text=<<currentTiddler>>/>" -- click
No: No
OfficialPluginLibrary: Official ~TiddlyWiki Plugin Library
OfficialPluginLibrary/Hint: The official ~TiddlyWiki plugin library at tiddlywiki.com. Plugins, themes and language packs are maintained by the core team.
PageTemplate/Description: the default ~TiddlyWiki layout
PageTemplate/Name: Default ~PageTemplate
PluginReloadWarning: Please save {{$:/core/ui/Buttons/save-wiki}} and reload {{$:/core/ui/Buttons/refresh}} to allow changes to ~JavaScript plugins to take effect
RecentChanges/DateFormat: DDth MMM YYYY
Shortcuts/Input/AdvancedSearch/Hint: Open the ~AdvancedSearch panel from within the sidebar search field
@@ -73,6 +77,10 @@ Shortcuts/Input/Tab-Left/Hint: Select the previous Tab
Shortcuts/Input/Tab-Right/Hint: Select the next Tab
Shortcuts/Input/Up/Hint: Select the previous item
Shortcuts/SidebarLayout/Hint: Change the sidebar layout
Switcher/Subtitle/theme: Switch Theme
Switcher/Subtitle/layout: Switch Layout
Switcher/Subtitle/language: Switch Language
Switcher/Subtitle/palette: Switch Palette
SystemTiddler/Tooltip: This is a system tiddler
SystemTiddlers/Include/Prompt: Include system tiddlers
TagManager/Colour/Heading: Colour

View File

@@ -14,7 +14,7 @@ List/Caption: List
List/Empty: This tiddler does not have a list
Listed/Caption: Listed
Listed/Empty: This tiddler is not listed by any others
References/Caption: References
References/Caption: Backlinks
References/Empty: No tiddlers link to this one
Tagging/Caption: Tagging
Tagging/Empty: No tiddlers are tagged with this one

View File

@@ -42,7 +42,6 @@ function FramedEngine(options) {
this.iframeNode.style.border = "none";
this.iframeNode.style.padding = "0";
this.iframeNode.style.resize = "none";
this.iframeNode.style["background-color"] = this.widget.wiki.extractTiddlerDataItem(this.widget.wiki.getTiddlerText("$:/palette"),"tiddler-editor-background");
this.iframeDoc.body.style.margin = "0";
this.iframeDoc.body.style.padding = "0";
this.widget.domNodes.push(this.iframeNode);
@@ -74,6 +73,12 @@ function FramedEngine(options) {
if(this.widget.editTabIndex) {
this.iframeNode.setAttribute("tabindex",this.widget.editTabIndex);
}
if(this.widget.editAutoComplete) {
this.domNode.setAttribute("autocomplete",this.widget.editAutoComplete);
}
if(this.widget.isDisabled === "yes") {
this.domNode.setAttribute("disabled",true);
}
// Copy the styles from the dummy textarea
this.copyStyles();
// Add event listeners
@@ -97,7 +102,6 @@ FramedEngine.prototype.copyStyles = function() {
this.domNode.style.display = "block";
this.domNode.style.width = "100%";
this.domNode.style.margin = "0";
this.domNode.style["background-color"] = this.widget.wiki.extractTiddlerDataItem(this.widget.wiki.getTiddlerText("$:/palette"),"tiddler-editor-background");
// In Chrome setting -webkit-text-fill-color overrides the placeholder text colour
this.domNode.style["-webkit-text-fill-color"] = "currentcolor";
};

View File

@@ -52,6 +52,12 @@ function SimpleEngine(options) {
if(this.widget.editTabIndex) {
this.domNode.setAttribute("tabindex",this.widget.editTabIndex);
}
if(this.widget.editAutoComplete) {
this.domNode.setAttribute("autocomplete",this.widget.editAutoComplete);
}
if(this.widget.isDisabled === "yes") {
this.domNode.setAttribute("disabled",true);
}
// Add an input event handler
$tw.utils.addEventListeners(this.domNode,[
{name: "focus", handlerObject: this, handlerMethod: "handleFocusEvent"},

View File

@@ -180,6 +180,8 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
this.editCancelPopups = this.getAttribute("cancelPopups","") === "yes";
this.editInputActions = this.getAttribute("inputActions");
this.editRefreshTitle = this.getAttribute("refreshTitle");
this.editAutoComplete = this.getAttribute("autocomplete");
this.isDisabled = this.getAttribute("disabled","no");
// Get the default editor element tag and type
var tag,type;
if(this.editField === "text") {
@@ -211,7 +213,7 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
EditTextWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
// Completely rerender if any of our attributes have changed
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes["default"] || changedAttributes["class"] || changedAttributes.placeholder || changedAttributes.size || changedAttributes.autoHeight || changedAttributes.minHeight || changedAttributes.focusPopup || changedAttributes.rows || changedAttributes.tabindex || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || changedTiddlers[HEIGHT_MODE_TITLE] || changedTiddlers[ENABLE_TOOLBAR_TITLE]) {
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes["default"] || changedAttributes["class"] || changedAttributes.placeholder || changedAttributes.size || changedAttributes.autoHeight || changedAttributes.minHeight || changedAttributes.focusPopup || changedAttributes.rows || changedAttributes.tabindex || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || changedAttributes.autocomplete || changedTiddlers[HEIGHT_MODE_TITLE] || changedTiddlers[ENABLE_TOOLBAR_TITLE] || changedAttributes.disabled) {
this.refreshSelf();
return true;
} else if (changedTiddlers[this.editRefreshTitle]) {

View File

@@ -18,7 +18,7 @@ Export our filter prefix function
*/
exports.all = function(operationSubFunction) {
return function(results,source,widget) {
Array.prototype.push.apply(results,operationSubFunction(source,widget));
results.push.apply(results, operationSubFunction(source,widget));
};
};

View File

@@ -16,12 +16,12 @@ Equivalent to + filter run prefix.
/*
Export our filter prefix function
*/
exports.and = function(operationSubFunction) {
exports.and = function(operationSubFunction,options) {
return function(results,source,widget) {
// This replaces all the elements of the array, but keeps the actual array so that references to it are preserved
source = $tw.wiki.makeTiddlerIterator(results);
results.splice(0,results.length);
$tw.utils.pushTop(results,operationSubFunction(source,widget));
source = options.wiki.makeTiddlerIterator(results.toArray());
results.clear();
results.pushTop(operationSubFunction(source,widget));
};
};

View File

@@ -19,7 +19,7 @@ exports.else = function(operationSubFunction) {
return function(results,source,widget) {
if(results.length === 0) {
// Main result so far is empty
$tw.utils.pushTop(results,operationSubFunction(source,widget));
results.pushTop(operationSubFunction(source,widget));
}
};
};

View File

@@ -18,7 +18,7 @@ Export our filter prefix function
*/
exports.except = function(operationSubFunction) {
return function(results,source,widget) {
$tw.utils.removeArrayEntries(results,operationSubFunction(source,widget));
results.remove(operationSubFunction(source,widget));
};
};

View File

@@ -13,17 +13,17 @@ module-type: filterrunprefix
/*
Export our filter function
*/
exports.filter = function(operationSubFunction) {
exports.filter = function(operationSubFunction,options) {
return function(results,source,widget) {
if(results.length > 0) {
var resultsToRemove = [];
$tw.utils.each(results,function(result) {
var filtered = operationSubFunction($tw.wiki.makeTiddlerIterator([result]),widget);
results.each(function(result) {
var filtered = operationSubFunction(options.wiki.makeTiddlerIterator([result]),widget);
if(filtered.length === 0) {
resultsToRemove.push(result);
}
});
$tw.utils.removeArrayEntries(results,resultsToRemove);
results.remove(resultsToRemove);
}
}
};

View File

@@ -17,7 +17,8 @@ exports.intersection = function(operationSubFunction) {
return function(results,source,widget) {
if(results.length !== 0) {
var secondRunResults = operationSubFunction(source,widget);
var firstRunResults = results.splice(0);
var firstRunResults = results.toArray();
results.clear();
$tw.utils.each(firstRunResults,function(title) {
if(secondRunResults.indexOf(title) !== -1) {
results.push(title);
@@ -27,4 +28,4 @@ exports.intersection = function(operationSubFunction) {
};
};
})();
})();

View File

@@ -17,7 +17,7 @@ Export our filter prefix function
*/
exports.or = function(operationSubFunction) {
return function(results,source,widget) {
$tw.utils.pushTop(results,operationSubFunction(source,widget));
results.pushTop(operationSubFunction(source,widget));
};
};

View File

@@ -0,0 +1,50 @@
/*\
title: $:/core/modules/filterrunprefixes/reduce.js
type: application/javascript
module-type: filterrunprefix
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter prefix function
*/
exports.reduce = function(operationSubFunction,options) {
return function(results,source,widget) {
if(results.length > 0) {
var accumulator = "";
var index = 0;
results.each(function(title) {
var list = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{
getVariable: function(name) {
switch(name) {
case "currentTiddler":
return "" + title;
case "accumulator":
return "" + accumulator;
case "index":
return "" + index;
case "revIndex":
return "" + (results.length - 1 - index);
case "length":
return "" + results.length;
default:
return widget.getVariable(name);
}
}
});
if(list.length > 0) {
accumulator = "" + list[0];
}
++index;
});
results.clear();
results.push(accumulator);
}
}
};
})();

View File

@@ -62,43 +62,61 @@ function parseFilterOperation(operators,filterString,p) {
else if(operator.operator === "") {
operator.operator = "title";
}
operator.operands = [];
function parseOperand(bracketType) {
var operand = {};
switch (bracketType) {
case "{": // Curly brackets
operand.indirect = true;
nextBracketPos = filterString.indexOf("}",p);
break;
case "[": // Square brackets
nextBracketPos = filterString.indexOf("]",p);
break;
case "<": // Angle brackets
operand.variable = true;
nextBracketPos = filterString.indexOf(">",p);
break;
case "/": // regexp brackets
var rex = /^((?:[^\\\/]*|\\.)*)\/(?:\(([mygi]+)\))?/g,
rexMatch = rex.exec(filterString.substring(p));
if(rexMatch) {
operator.regexp = new RegExp(rexMatch[1], rexMatch[2]);
// DEPRECATION WARNING
console.log("WARNING: Filter",operator.operator,"has a deprecated regexp operand",operator.regexp);
nextBracketPos = p + rex.lastIndex - 1;
}
else {
throw "Unterminated regular expression in filter expression";
}
break;
}
if(nextBracketPos === -1) {
throw "Missing closing bracket in filter expression";
}
if(!operator.regexp) {
operand.text = filterString.substring(p,nextBracketPos);
operator.operands.push(operand);
}
p = nextBracketPos + 1;
}
p = nextBracketPos + 1;
switch (bracket) {
case "{": // Curly brackets
operator.indirect = true;
nextBracketPos = filterString.indexOf("}",p);
break;
case "[": // Square brackets
nextBracketPos = filterString.indexOf("]",p);
break;
case "<": // Angle brackets
operator.variable = true;
nextBracketPos = filterString.indexOf(">",p);
break;
case "/": // regexp brackets
var rex = /^((?:[^\\\/]*|\\.)*)\/(?:\(([mygi]+)\))?/g,
rexMatch = rex.exec(filterString.substring(p));
if(rexMatch) {
operator.regexp = new RegExp(rexMatch[1], rexMatch[2]);
// DEPRECATION WARNING
console.log("WARNING: Filter",operator.operator,"has a deprecated regexp operand",operator.regexp);
nextBracketPos = p + rex.lastIndex - 1;
}
else {
throw "Unterminated regular expression in filter expression";
}
break;
parseOperand(bracket);
// Check for multiple operands
while(filterString.charAt(p) === ",") {
p++;
if(/^[\[\{<\/]/.test(filterString.substring(p))) {
nextBracketPos = p;
p++;
parseOperand(filterString.charAt(nextBracketPos));
} else {
throw "Missing [ in filter expression";
}
}
if(nextBracketPos === -1) {
throw "Missing closing bracket in filter expression";
}
if(!operator.regexp) {
operator.operand = filterString.substring(p,nextBracketPos);
}
p = nextBracketPos + 1;
// Push this operator
operators.push(operator);
} while(filterString.charAt(p) !== "]");
@@ -152,7 +170,7 @@ exports.parseFilter = function(filterString) {
}
if(match[4] || match[5] || match[6]) { // Double quoted string, single quoted string or unquoted title
operation.operators.push(
{operator: "title", operand: match[4] || match[5] || match[6]}
{operator: "title", operands: [{text: match[4] || match[5] || match[6]}]}
);
}
results.push(operation);
@@ -170,7 +188,7 @@ exports.getFilterOperators = function() {
};
exports.getFilterRunPrefixes = function() {
if(!this.filterPrefixes) {
if(!this.filterRunPrefixes) {
$tw.Wiki.prototype.filterRunPrefixes = {};
$tw.modules.applyMethods("filterrunprefix",this.filterRunPrefixes);
}
@@ -209,7 +227,7 @@ exports.compileFilter = function(filterString) {
results = [],
currTiddlerTitle = widget && widget.getVariable("currentTiddler");
$tw.utils.each(operation.operators,function(operator) {
var operand = operator.operand,
var operands = [],
operatorFunction;
if(!operator.operator) {
operatorFunction = filterOperators.title;
@@ -218,16 +236,23 @@ exports.compileFilter = function(filterString) {
} else {
operatorFunction = filterOperators[operator.operator];
}
if(operator.indirect) {
operand = self.getTextReference(operator.operand,"",currTiddlerTitle);
}
if(operator.variable) {
operand = widget.getVariable(operator.operand,{defaultValue: ""});
}
$tw.utils.each(operator.operands,function(operand) {
if(operand.indirect) {
operand.value = self.getTextReference(operand.text,"",currTiddlerTitle);
} else if(operand.variable) {
operand.value = widget.getVariable(operand.text,{defaultValue: ""});
} else {
operand.value = operand.text;
}
operands.push(operand.value);
});
// Invoke the appropriate filteroperator module
results = operatorFunction(accumulator,{
operator: operator.operator,
operand: operand,
operand: operands.length > 0 ? operands[0] : undefined,
operands: operands,
prefix: operator.prefix,
suffix: operator.suffix,
suffixes: operator.suffixes,
@@ -255,23 +280,24 @@ exports.compileFilter = function(filterString) {
var filterRunPrefixes = self.getFilterRunPrefixes();
// Wrap the operator functions in a wrapper function that depends on the prefix
operationFunctions.push((function() {
var options = {wiki: self};
switch(operation.prefix || "") {
case "": // No prefix means that the operation is unioned into the result
return filterRunPrefixes["or"](operationSubFunction);
return filterRunPrefixes["or"](operationSubFunction, options);
case "=": // The results of the operation are pushed into the result without deduplication
return filterRunPrefixes["all"](operationSubFunction);
return filterRunPrefixes["all"](operationSubFunction, options);
case "-": // The results of this operation are removed from the main result
return filterRunPrefixes["except"](operationSubFunction);
return filterRunPrefixes["except"](operationSubFunction, options);
case "+": // This operation is applied to the main results so far
return filterRunPrefixes["and"](operationSubFunction);
return filterRunPrefixes["and"](operationSubFunction, options);
case "~": // This operation is unioned into the result only if the main result so far is empty
return filterRunPrefixes["else"](operationSubFunction);
return filterRunPrefixes["else"](operationSubFunction, options);
default:
if(operation.namedPrefix && filterRunPrefixes[operation.namedPrefix]) {
return filterRunPrefixes[operation.namedPrefix](operationSubFunction);
return filterRunPrefixes[operation.namedPrefix](operationSubFunction, options);
} else {
return function(results,source,widget) {
results.splice(0,results.length);
results.clear();
results.push($tw.language.getString("Error/FilterRunPrefix"));
};
}
@@ -285,11 +311,11 @@ exports.compileFilter = function(filterString) {
} else if(typeof source === "object") { // Array or hashmap
source = self.makeTiddlerIterator(source);
}
var results = [];
var results = new $tw.utils.LinkedList();
$tw.utils.each(operationFunctions,function(operationFunction) {
operationFunction(results,source,widget);
});
return results;
return results.toArray();
});
};

View File

@@ -16,14 +16,16 @@ Filter operator for returning the descriptions of the specified edition names
Export our filter function
*/
exports.editiondescription = function(source,operator,options) {
var results = [],
editionInfo = $tw.utils.getEditionInfo();
if(editionInfo) {
source(function(tiddler,title) {
if($tw.utils.hop(editionInfo,title)) {
results.push(editionInfo[title].description || "");
}
});
var results = [];
if($tw.node) {
var editionInfo = $tw.utils.getEditionInfo();
if(editionInfo) {
source(function(tiddler,title) {
if($tw.utils.hop(editionInfo,title)) {
results.push(editionInfo[title].description || "");
}
});
}
}
return results;
};

View File

@@ -16,14 +16,16 @@ Filter operator for returning the names of the available editions in this wiki
Export our filter function
*/
exports.editions = function(source,operator,options) {
var results = [],
editionInfo = $tw.utils.getEditionInfo();
if(editionInfo) {
$tw.utils.each(editionInfo,function(info,name) {
results.push(name);
});
var results = [];
if($tw.node) {
var editionInfo = $tw.utils.getEditionInfo();
if(editionInfo) {
$tw.utils.each(editionInfo,function(info,name) {
results.push(name);
});
}
results.sort();
}
results.sort();
return results;
};

View File

@@ -77,7 +77,7 @@ exports.encodehtml = function(source,operator,options) {
exports.stringify = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
results.push($tw.utils.stringify(title));
results.push($tw.utils.stringify(title,(operator.suffix === "rawunicode")));
});
return results;
};
@@ -85,7 +85,7 @@ exports.stringify = function(source,operator,options) {
exports.jsonstringify = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
results.push($tw.utils.jsonStringify(title));
results.push($tw.utils.jsonStringify(title,(operator.suffix === "rawunicode")));
});
return results;
};

View File

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

View File

@@ -22,7 +22,7 @@ Export our filter function
exports.lookup = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
results.push(options.wiki.getTiddlerText(operator.operand + title) || options.wiki.getTiddlerText(operator.operand + operator.suffix));
results.push(options.wiki.getTiddlerText(operator.operand + title) || operator.suffix);
});
return results;
};

View File

@@ -91,6 +91,20 @@ exports.exponential = makeNumericBinaryOperator(
function(a,b) {return Number.prototype.toExponential.call(a,Math.min(Math.max(b,0),100));}
);
exports.power = makeNumericBinaryOperator(
function(a,b) {return Math.pow(a,b);}
);
exports.log = makeNumericBinaryOperator(
function(a,b) {
if(b) {
return Math.log(a)/Math.log(b);
} else {
return Math.log(a);
}
}
);
exports.sum = makeNumericReducingOperator(
function(accumulator,value) {return accumulator + value},
0 // Initial value

View File

@@ -23,7 +23,7 @@ exports.reduce = function(source,operator,options) {
});
// Run the filter over each item
var filterFn = options.wiki.compileFilter(operator.operand),
accumulator = operator.suffix || "";
accumulator = operator.operands[1] || "";
for(var index=0; index<results.length; index++) {
var title = results[index],
list = filterFn.call(options.wiki,options.wiki.makeTiddlerIterator([title]),{
@@ -48,7 +48,11 @@ exports.reduce = function(source,operator,options) {
accumulator = "" + list[0];
}
}
return [accumulator];
if(results.length > 0) {
return [accumulator];
} else {
return [];
}
};
})();

View File

@@ -61,7 +61,7 @@ exports.split = makeStringBinaryOperator(
);
exports["enlist-input"] = makeStringBinaryOperator(
function(a) {return $tw.utils.parseStringArray("" + a);}
function(a,o,s) {return $tw.utils.parseStringArray("" + a,(s === "raw"));}
);
exports.join = makeStringReducingOperator(
@@ -78,7 +78,7 @@ function makeStringBinaryOperator(fnCalc) {
return function(source,operator,options) {
var result = [];
source(function(tiddler,title) {
Array.prototype.push.apply(result,fnCalc(title,operator.operand || ""));
Array.prototype.push.apply(result,fnCalc(title,operator.operand || "",operator.suffix || ""));
});
return result;
};
@@ -115,4 +115,61 @@ exports.splitregexp = function(source,operator,options) {
return result;
};
exports["search-replace"] = function(source,operator,options) {
var results = [],
suffixes = operator.suffixes || [],
flagSuffix = (suffixes[0] ? (suffixes[0][0] || "") : ""),
flags = (flagSuffix.indexOf("g") !== -1 ? "g" : "") + (flagSuffix.indexOf("i") !== -1 ? "i" : ""),
isRegExp = (suffixes[1] && suffixes[1][0] === "regexp") ? true : false,
searchTerm,
regExp;
source(function(tiddler,title) {
if(title && (operator.operands.length > 1)) {
//Escape regexp characters if the operand is not a regular expression
searchTerm = isRegExp ? operator.operand : $tw.utils.escapeRegExp(operator.operand);
try {
regExp = new RegExp(searchTerm,flags);
} catch(ex) {
return ["RegExp error: " + ex];
}
results.push(
title.replace(regExp,operator.operands[1])
);
} else {
results.push(title);
}
});
return results;
};
exports.pad = function(source,operator,options) {
var results = [],
targetLength = operator.operand ? parseInt(operator.operand) : 0,
fill = operator.operands[1] || "0";
source(function(tiddler,title) {
if(title && title.length) {
if(title.length >= targetLength) {
results.push(title);
} else {
var padString = "",
padStringLength = targetLength - title.length;
while (padStringLength > padString.length) {
padString += fill;
}
//make sure we do not exceed the specified length
padString = padString.slice(0,padStringLength);
if(operator.suffix && (operator.suffix === "suffix")) {
title = title + padString;
} else {
title = padString + title;
}
results.push(title);
}
}
});
return results;
}
})();

View File

@@ -8,183 +8,228 @@ Extended filter operators to manipulate the current list.
\*/
(function () {
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Fetch titles from the current list
*/
var prepare_results = function (source) {
var results = [];
source(function (tiddler, title) {
results.push(title);
});
return results;
};
/*
Fetch titles from the current list
*/
var prepare_results = function (source) {
var results = [];
source(function (tiddler, title) {
results.push(title);
});
return results;
};
/*
Moves a number of items from the tail of the current list before the item named in the operand
*/
exports.putbefore = function (source, operator) {
var results = prepare_results(source),
index = results.indexOf(operator.operand),
count = $tw.utils.getInt(operator.suffix,1);
return (index === -1) ?
results.slice(0, -1) :
results.slice(0, index).concat(results.slice(-count)).concat(results.slice(index, -count));
};
/*
Moves a number of items from the tail of the current list before the item named in the operand
*/
exports.putbefore = function (source, operator) {
var results = prepare_results(source),
index = results.indexOf(operator.operand),
count = $tw.utils.getInt(operator.suffix,1);
return (index === -1) ?
results.slice(0, -1) :
results.slice(0, index).concat(results.slice(-count)).concat(results.slice(index, -count));
};
/*
Moves a number of items from the tail of the current list after the item named in the operand
*/
exports.putafter = function (source, operator) {
var results = prepare_results(source),
index = results.indexOf(operator.operand),
count = $tw.utils.getInt(operator.suffix,1);
return (index === -1) ?
results.slice(0, -1) :
results.slice(0, index + 1).concat(results.slice(-count)).concat(results.slice(index + 1, -count));
};
/*
Moves a number of items from the tail of the current list after the item named in the operand
*/
exports.putafter = function (source, operator) {
var results = prepare_results(source),
index = results.indexOf(operator.operand),
count = $tw.utils.getInt(operator.suffix,1);
return (index === -1) ?
results.slice(0, -1) :
results.slice(0, index + 1).concat(results.slice(-count)).concat(results.slice(index + 1, -count));
};
/*
Replaces the item named in the operand with a number of items from the tail of the current list
*/
exports.replace = function (source, operator) {
var results = prepare_results(source),
index = results.indexOf(operator.operand),
count = $tw.utils.getInt(operator.suffix,1);
return (index === -1) ?
results.slice(0, -count) :
results.slice(0, index).concat(results.slice(-count)).concat(results.slice(index + 1, -count));
};
/*
Replaces the item named in the operand with a number of items from the tail of the current list
*/
exports.replace = function (source, operator) {
var results = prepare_results(source),
index = results.indexOf(operator.operand),
count = $tw.utils.getInt(operator.suffix,1);
return (index === -1) ?
results.slice(0, -count) :
results.slice(0, index).concat(results.slice(-count)).concat(results.slice(index + 1, -count));
};
/*
Moves a number of items from the tail of the current list to the head of the list
*/
exports.putfirst = function (source, operator) {
var results = prepare_results(source),
count = $tw.utils.getInt(operator.suffix,1);
return results.slice(-count).concat(results.slice(0, -count));
};
/*
Moves a number of items from the tail of the current list to the head of the list
*/
exports.putfirst = function (source, operator) {
var results = prepare_results(source),
count = $tw.utils.getInt(operator.suffix,1);
return results.slice(-count).concat(results.slice(0, -count));
};
/*
Moves a number of items from the head of the current list to the tail of the list
*/
exports.putlast = function (source, operator) {
var results = prepare_results(source),
count = $tw.utils.getInt(operator.suffix,1);
return results.slice(count).concat(results.slice(0, count));
};
/*
Moves a number of items from the head of the current list to the tail of the list
*/
exports.putlast = function (source, operator) {
var results = prepare_results(source),
count = $tw.utils.getInt(operator.suffix,1);
return results.slice(count).concat(results.slice(0, count));
};
/*
Moves the item named in the operand a number of places forward or backward in the list
*/
exports.move = function (source, operator) {
var results = prepare_results(source),
index = results.indexOf(operator.operand),
count = $tw.utils.getInt(operator.suffix,1),
marker = results.splice(index, 1),
offset = (index + count) > 0 ? index + count : 0;
return results.slice(0, offset).concat(marker).concat(results.slice(offset));
};
/*
Moves the item named in the operand a number of places forward or backward in the list
*/
exports.move = function (source, operator) {
var results = prepare_results(source),
index = results.indexOf(operator.operand),
count = $tw.utils.getInt(operator.suffix,1),
marker = results.splice(index, 1),
offset = (index + count) > 0 ? index + count : 0;
return results.slice(0, offset).concat(marker).concat(results.slice(offset));
};
/*
Returns the items from the current list that are after the item named in the operand
*/
exports.allafter = function (source, operator) {
var results = prepare_results(source),
index = results.indexOf(operator.operand);
return (index === -1) ? [] :
(operator.suffix) ? results.slice(index) :
results.slice(index + 1);
};
/*
Returns the items from the current list that are after the item named in the operand
*/
exports.allafter = function (source, operator) {
var results = prepare_results(source),
index = results.indexOf(operator.operand);
return (index === -1) ? [] :
(operator.suffix) ? results.slice(index) :
results.slice(index + 1);
};
/*
Returns the items from the current list that are before the item named in the operand
*/
exports.allbefore = function (source, operator) {
var results = prepare_results(source),
index = results.indexOf(operator.operand);
return (index === -1) ? [] :
(operator.suffix) ? results.slice(0, index + 1) :
results.slice(0, index);
};
/*
Returns the items from the current list that are before the item named in the operand
*/
exports.allbefore = function (source, operator) {
var results = prepare_results(source),
index = results.indexOf(operator.operand);
return (index === -1) ? [] :
(operator.suffix) ? results.slice(0, index + 1) :
results.slice(0, index);
};
/*
Appends the items listed in the operand array to the tail of the current list
*/
exports.append = function (source, operator) {
var append = $tw.utils.parseStringArray(operator.operand, "true"),
results = prepare_results(source),
count = parseInt(operator.suffix) || append.length;
return (append.length === 0) ? results :
(operator.prefix) ? results.concat(append.slice(-count)) :
results.concat(append.slice(0, count));
};
/*
Appends the items listed in the operand array to the tail of the current list
*/
exports.append = function (source, operator) {
var append = $tw.utils.parseStringArray(operator.operand, "true"),
results = prepare_results(source),
count = parseInt(operator.suffix) || append.length;
return (append.length === 0) ? results :
(operator.prefix) ? results.concat(append.slice(-count)) :
results.concat(append.slice(0, count));
};
/*
Prepends the items listed in the operand array to the head of the current list
*/
exports.prepend = function (source, operator) {
var prepend = $tw.utils.parseStringArray(operator.operand, "true"),
results = prepare_results(source),
count = $tw.utils.getInt(operator.suffix,prepend.length);
return (prepend.length === 0) ? results :
(operator.prefix) ? prepend.slice(-count).concat(results) :
prepend.slice(0, count).concat(results);
};
/*
Prepends the items listed in the operand array to the head of the current list
*/
exports.prepend = function (source, operator) {
var prepend = $tw.utils.parseStringArray(operator.operand, "true"),
results = prepare_results(source),
count = $tw.utils.getInt(operator.suffix,prepend.length);
return (prepend.length === 0) ? results :
(operator.prefix) ? prepend.slice(-count).concat(results) :
prepend.slice(0, count).concat(results);
};
/*
Returns all items from the current list except the items listed in the operand array
*/
exports.remove = function (source, operator) {
var array = $tw.utils.parseStringArray(operator.operand, "true"),
results = prepare_results(source),
count = parseInt(operator.suffix) || array.length,
p,
len,
index;
len = array.length - 1;
for (p = 0; p < count; ++p) {
if (operator.prefix) {
index = results.indexOf(array[len - p]);
} else {
index = results.indexOf(array[p]);
}
if (index !== -1) {
results.splice(index, 1);
}
}
return results;
};
/*
Returns all items from the current list except the items listed in the operand array
*/
exports.remove = function (source, operator) {
var array = $tw.utils.parseStringArray(operator.operand, "true"),
results = prepare_results(source),
count = parseInt(operator.suffix) || array.length,
p,
len,
index;
len = array.length - 1;
for (p = 0; p < count; ++p) {
if (operator.prefix) {
index = results.indexOf(array[len - p]);
} else {
index = results.indexOf(array[p]);
}
if (index !== -1) {
results.splice(index, 1);
}
}
return results;
};
/*
Returns all items from the current list sorted in the order of the items in the operand array
*/
exports.sortby = function (source, operator) {
var results = prepare_results(source);
if (!results || results.length < 2) {
return results;
}
var lookup = $tw.utils.parseStringArray(operator.operand, "true");
results.sort(function (a, b) {
return lookup.indexOf(a) - lookup.indexOf(b);
});
return results;
};
/*
Returns all items from the current list sorted in the order of the items in the operand array
*/
exports.sortby = function (source, operator) {
var results = prepare_results(source);
if (!results || results.length < 2) {
return results;
}
var lookup = $tw.utils.parseStringArray(operator.operand, "true");
results.sort(function (a, b) {
return lookup.indexOf(a) - lookup.indexOf(b);
});
return results;
};
/*
Removes all duplicate items from the current list
*/
exports.unique = function (source, operator) {
var results = prepare_results(source);
var set = results.reduce(function (a, b) {
if (a.indexOf(b) < 0) {
a.push(b);
}
return a;
}, []);
return set;
};
/*
Removes all duplicate items from the current list
*/
exports.unique = function (source, operator) {
var results = prepare_results(source);
var set = results.reduce(function (a, b) {
if (a.indexOf(b) < 0) {
a.push(b);
}
return a;
}, []);
return set;
};
var cycleValueInArray = function(results,operands,stepSize) {
var resultsIndex,
step = stepSize || 1,
i = 0,
opLength = operands.length,
nextOperandIndex;
for(i; i < opLength; i++) {
resultsIndex = results.indexOf(operands[i]);
if(resultsIndex !== -1) {
break;
}
}
if(resultsIndex !== -1) {
i = i + step;
nextOperandIndex = (i < opLength ? i : i - opLength);
if(operands.length > 1) {
results.splice(resultsIndex,1,operands[nextOperandIndex]);
} else {
results.splice(resultsIndex,1);
}
} else {
results.push(operands[0]);
}
return results;
}
/*
Toggles an item in the current list.
*/
exports.toggle = function(source,operator) {
return cycleValueInArray(prepare_results(source),operator.operands);
}
exports.cycle = function(source,operator) {
var results = prepare_results(source),
operands = (operator.operand.length ? $tw.utils.parseStringArray(operator.operand, "true") : [""]),
step = $tw.utils.getInt(operator.operands[1]||"",1);
if(step < 0) {
operands.reverse();
step = Math.abs(step);
}
return cycleValueInArray(results,operands,step);
}
})();

View File

@@ -12,7 +12,7 @@ Initialise basic platform $:/info/ tiddlers
/*global $tw: false */
"use strict";
exports.getInfoTiddlerFields = function() {
exports.getInfoTiddlerFields = function(updateInfoTiddlersCallback) {
var mapBoolean = function(value) {return value ? "yes" : "no";},
infoTiddlerFields = [];
// Basics
@@ -36,6 +36,13 @@ exports.getInfoTiddlerFields = function() {
// Screen size
infoTiddlerFields.push({title: "$:/info/browser/screen/width", text: window.screen.width.toString()});
infoTiddlerFields.push({title: "$:/info/browser/screen/height", text: window.screen.height.toString()});
// Dark mode through event listener on MediaQueryList
var mqList = window.matchMedia("(prefers-color-scheme: dark)"),
getDarkModeTiddler = function() {return {title: "$:/info/darkmode", text: mqList.matches ? "yes" : "no"};};
infoTiddlerFields.push(getDarkModeTiddler());
mqList.addListener(function(event) {
updateInfoTiddlersCallback([getDarkModeTiddler()]);
});
// Language
infoTiddlerFields.push({title: "$:/info/browser/language", text: navigator.language || ""});
}

View File

@@ -285,13 +285,17 @@ KeyboardManager.prototype.checkKeyDescriptors = function(event,keyInfoArray) {
};
KeyboardManager.prototype.getEventModifierKeyDescriptor = function(event) {
return event.ctrlKey && !event.shiftKey && !event.altKey ? "ctrl" :
event.shiftKey && !event.ctrlKey && !event.altKey? "shift" :
event.ctrlKey && event.shiftKey && !event.altKey ? "ctrl-shift" :
event.altKey && !event.shiftKey && !event.ctrlKey ? "alt" :
event.altKey && event.shiftKey && !event.ctrlKey ? "alt-shift" :
event.altKey && event.ctrlKey && !event.shiftKey ? "ctrl-alt" :
event.altKey && event.shiftKey && event.ctrlKey ? "ctrl-alt-shift" : "normal";
return event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey ? "ctrl" :
event.shiftKey && !event.ctrlKey && !event.altKey && !event.metaKey ? "shift" :
event.ctrlKey && event.shiftKey && !event.altKey && !event.metaKey ? "ctrl-shift" :
event.altKey && !event.shiftKey && !event.ctrlKey && !event.metaKey ? "alt" :
event.altKey && event.shiftKey && !event.ctrlKey && !event.metaKey ? "alt-shift" :
event.altKey && event.ctrlKey && !event.shiftKey && !event.metaKey ? "ctrl-alt" :
event.altKey && event.shiftKey && event.ctrlKey && !event.metaKey ? "ctrl-alt-shift" :
event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey ? "meta" :
event.metaKey && event.ctrlKey && !event.shiftKey && !event.altKey ? "meta-ctrl" :
event.metaKey && event.ctrlKey && event.shiftKey && !event.altKey ? "meta-ctrl-shift" :
event.metaKey && event.ctrlKey & event.shiftKey && event.altKey ? "meta-ctrl-alt-shift" : "normal";
};
KeyboardManager.prototype.getShortcutTiddlerList = function() {

View File

@@ -386,22 +386,18 @@ Amend the rules used by this instance of the parser
WikiParser.prototype.amendRules = function(type,names) {
names = names || [];
// Define the filter function
var keepFilter;
var target;
if(type === "only") {
keepFilter = function(name) {
return names.indexOf(name) !== -1;
};
target = true;
} else if(type === "except") {
keepFilter = function(name) {
return names.indexOf(name) === -1;
};
target = false;
} else {
return;
}
// Define a function to process each of our rule arrays
var processRuleArray = function(ruleArray) {
for(var t=ruleArray.length-1; t>=0; t--) {
if(!keepFilter(ruleArray[t].rule.name)) {
if((names.indexOf(ruleArray[t].rule.name) === -1) === target) {
ruleArray.splice(t,1);
}
}

View File

@@ -197,8 +197,12 @@ SaverHandler.prototype.isDirty = function() {
Update the document body with the class "tc-dirty" if the wiki has unsaved/unsynced changes
*/
SaverHandler.prototype.updateDirtyStatus = function() {
var self = this;
if($tw.browser) {
$tw.utils.toggleClass(document.body,"tc-dirty",this.isDirty());
$tw.utils.each($tw.windows,function(win) {
$tw.utils.toggleClass(win.document.body,"tc-dirty",self.isDirty());
});
}
};

View File

@@ -26,12 +26,13 @@ GitHubSaver.prototype.save = function(text,method,callback) {
repo = this.wiki.getTiddlerText("$:/GitHub/Repo"),
path = this.wiki.getTiddlerText("$:/GitHub/Path",""),
filename = this.wiki.getTiddlerText("$:/GitHub/Filename"),
branch = this.wiki.getTiddlerText("$:/GitHub/Branch") || "master",
branch = this.wiki.getTiddlerText("$:/GitHub/Branch") || "main",
endpoint = this.wiki.getTiddlerText("$:/GitHub/ServerURL") || "https://api.github.com",
headers = {
"Accept": "application/vnd.github.v3+json",
"Content-Type": "application/json;charset=UTF-8",
"Authorization": "Basic " + window.btoa(username + ":" + password)
"Authorization": "Basic " + window.btoa(username + ":" + password),
"If-None-Match": ""
};
// Bail if we don't have everything we need
if(!username || !password || !repo || !filename) {

View File

@@ -28,6 +28,9 @@ exports.handler = function(request,response,state) {
return;
}
}
if(state.wiki.getTiddlerText("$:/config/SyncSystemTiddlersFromServer") === "no") {
filter += "+[!is[system]]";
}
var excludeFields = (state.queryParameters.exclude || "text").split(","),
titles = state.wiki.filterTiddlers(filter);
response.writeHead(200, {"Content-Type": "application/json"});

View File

@@ -21,29 +21,37 @@ exports.synchronous = true;
var TITLE_INFO_PLUGIN = "$:/temp/info-plugin";
exports.startup = function() {
// Function to bake the info plugin with new tiddlers
var updateInfoPlugin = function(tiddlerFieldsArray) {
// Get the existing tiddlers
var json = $tw.wiki.getTiddlerData(TITLE_INFO_PLUGIN,{tiddlers: {}});
// Add the new ones
$tw.utils.each(tiddlerFieldsArray,function(fields) {
if(fields && fields.title) {
json.tiddlers[fields.title] = fields;
}
});
// Bake the info tiddlers into a plugin. We use the non-standard plugin-type "info" because ordinary plugins are only registered asynchronously after being loaded dynamically
var fields = {
title: TITLE_INFO_PLUGIN,
type: "application/json",
"plugin-type": "info",
text: JSON.stringify(json,null,$tw.config.preferences.jsonSpaces)
};
$tw.wiki.addTiddler(new $tw.Tiddler(fields));
};
// Collect up the info tiddlers
var infoTiddlerFields = {};
// Give each info module a chance to fill in as many info tiddlers as they want
var tiddlerFieldsArray = [];
// Give each info module a chance to provide as many info tiddlers as they want as an array, and give them a callback for dynamically updating them
$tw.modules.forEachModuleOfType("info",function(title,moduleExports) {
if(moduleExports && moduleExports.getInfoTiddlerFields) {
var tiddlerFieldsArray = moduleExports.getInfoTiddlerFields(infoTiddlerFields);
$tw.utils.each(tiddlerFieldsArray,function(fields) {
if(fields) {
infoTiddlerFields[fields.title] = fields;
}
});
Array.prototype.push.apply(tiddlerFieldsArray,moduleExports.getInfoTiddlerFields(updateInfoPlugin));
}
});
// Bake the info tiddlers into a plugin. We use the non-standard plugin-type "info" because ordinary plugins are only registered asynchronously after being loaded dynamically
var fields = {
title: TITLE_INFO_PLUGIN,
type: "application/json",
"plugin-type": "info",
text: JSON.stringify({tiddlers: infoTiddlerFields},null,$tw.config.preferences.jsonSpaces)
};
$tw.wiki.addTiddler(new $tw.Tiddler(fields));
$tw.wiki.readPluginInfo([TITLE_INFO_PLUGIN]);
$tw.wiki.registerPluginTiddlers("info");
updateInfoPlugin(tiddlerFieldsArray);
var changes = $tw.wiki.readPluginInfo([TITLE_INFO_PLUGIN]);
$tw.wiki.registerPluginTiddlers("info",[TITLE_INFO_PLUGIN]);
$tw.wiki.unpackPluginTiddlers();
};

View File

@@ -24,6 +24,7 @@ var PREFIX_CONFIG_REGISTER_PLUGIN_TYPE = "$:/config/RegisterPluginType/";
exports.startup = function() {
$tw.wiki.addTiddler({title: TITLE_REQUIRE_RELOAD_DUE_TO_PLUGIN_CHANGE,text: "no"});
$tw.wiki.addEventListener("change",function(changes) {
// Work out which of the changed tiddlers are plugins that we need to reregister
var changesToProcess = [],
requireReloadDueToPluginChange = false;
$tw.utils.each(Object.keys(changes),function(title) {
@@ -38,6 +39,7 @@ exports.startup = function() {
}
}
});
// Issue warning if any of the tiddlers require a reload
if(requireReloadDueToPluginChange) {
$tw.wiki.addTiddler({title: TITLE_REQUIRE_RELOAD_DUE_TO_PLUGIN_CHANGE,text: "yes"});
}
@@ -45,12 +47,35 @@ exports.startup = function() {
if(changesToProcess.length > 0) {
var changes = $tw.wiki.readPluginInfo(changesToProcess);
if(changes.modifiedPlugins.length > 0 || changes.deletedPlugins.length > 0) {
var changedShadowTiddlers = {};
// Collect the shadow tiddlers of any deleted plugins
$tw.utils.each(changes.deletedPlugins,function(pluginTitle) {
var pluginInfo = $tw.wiki.getPluginInfo(pluginTitle);
if(pluginInfo) {
$tw.utils.each(Object.keys(pluginInfo.tiddlers),function(title) {
changedShadowTiddlers[title] = true;
});
}
});
// Collect the shadow tiddlers of any modified plugins
$tw.utils.each(changes.modifiedPlugins,function(pluginTitle) {
var pluginInfo = $tw.wiki.getPluginInfo(pluginTitle);
if(pluginInfo) {
$tw.utils.each(Object.keys(pluginInfo.tiddlers),function(title) {
changedShadowTiddlers[title] = false;
});
}
});
// (Re-)register any modified plugins
$tw.wiki.registerPluginTiddlers(null,changes.modifiedPlugins);
// Unregister any deleted plugins
$tw.wiki.unregisterPluginTiddlers(null,changes.deletedPlugins);
// Unpack the shadow tiddlers
$tw.wiki.unpackPluginTiddlers();
// Queue change events for the changed shadow tiddlers
$tw.utils.each(Object.keys(changedShadowTiddlers),function(title) {
$tw.wiki.enqueueTiddlerEvent(title,changedShadowTiddlers[title]);
});
}
}
});

View File

@@ -21,7 +21,7 @@ exports.synchronous = true;
// Default story and history lists
var PAGE_TITLE_TITLE = "$:/core/wiki/title";
var PAGE_STYLESHEET_TITLE = "$:/core/ui/PageStylesheet";
var PAGE_TEMPLATE_TITLE = "$:/core/ui/PageTemplate";
var PAGE_TEMPLATE_TITLE = "$:/core/ui/RootTemplate";
// Time (in ms) that we defer refreshing changes to draft tiddlers
var DRAFT_TIDDLER_TIMEOUT_TITLE = "$:/config/Drafts/TypingTimeout";
@@ -52,7 +52,7 @@ exports.startup = function() {
}));
// Display the $:/core/ui/PageTemplate tiddler to kick off the display
$tw.perf.report("mainRender",function() {
$tw.pageWidgetNode = $tw.wiki.makeTranscludeWidget(PAGE_TEMPLATE_TITLE,{document: document, parentWidget: $tw.rootWidget});
$tw.pageWidgetNode = $tw.wiki.makeTranscludeWidget(PAGE_TEMPLATE_TITLE,{document: document, parentWidget: $tw.rootWidget, recursionMarker: "no"});
$tw.pageContainer = document.createElement("div");
$tw.utils.addClass($tw.pageContainer,"tc-page-container-wrapper");
document.body.insertBefore($tw.pageContainer,document.body.firstChild);
@@ -107,7 +107,7 @@ exports.startup = function() {
$tw.rootWidget.domNodes = [$tw.pageContainer];
$tw.rootWidget.children = [$tw.pageWidgetNode];
// Run any post-render startup actions
$tw.rootWidget.executeStartupTiddlers("$:/tags/StartupAction/PostRender");
$tw.rootWidget.invokeActionsByTag("$:/tags/StartupAction/PostRender");
};
})();

View File

@@ -25,6 +25,9 @@ exports.startup = function() {
$tw.rootWidget.addEventListener("tm-modal",function(event) {
$tw.modal.display(event.param,{variables: event.paramObject, event: event});
});
$tw.rootWidget.addEventListener("tm-show-switcher",function(event) {
$tw.modal.display("$:/core/ui/SwitcherModal",{variables: event.paramObject, event: event});
});
// Install the notification mechanism
$tw.notifier = new $tw.utils.Notifier($tw.wiki);
$tw.rootWidget.addEventListener("tm-notify",function(event) {

View File

@@ -64,12 +64,12 @@ exports.startup = function() {
document: $tw.browser ? document : $tw.fakeDocument
});
// Execute any startup actions
$tw.rootWidget.executeStartupTiddlers("$:/tags/StartupAction");
$tw.rootWidget.invokeActionsByTag("$:/tags/StartupAction");
if($tw.browser) {
$tw.rootWidget.executeStartupTiddlers("$:/tags/StartupAction/Browser");
$tw.rootWidget.invokeActionsByTag("$:/tags/StartupAction/Browser");
}
if($tw.node) {
$tw.rootWidget.executeStartupTiddlers("$:/tags/StartupAction/Node");
$tw.rootWidget.invokeActionsByTag("$:/tags/StartupAction/Node");
}
// Kick off the language manager and switcher
$tw.language = new $tw.Language();

View File

@@ -19,7 +19,7 @@ exports.after = ["startup"];
exports.synchronous = true;
// Global to keep track of open windows (hashmap by title)
var windows = {};
$tw.windows = {};
exports.startup = function() {
// Handle open window message
@@ -44,7 +44,7 @@ exports.startup = function() {
catch(e) {
return;
}
windows[title] = srcWindow;
$tw.windows[title] = srcWindow;
// Check for reopening the same window
if(srcWindow.haveInitialisedWindow) {
return;
@@ -54,7 +54,7 @@ exports.startup = function() {
srcDocument.close();
srcDocument.title = windowTitle;
srcWindow.addEventListener("beforeunload",function(event) {
delete windows[title];
delete $tw.windows[title];
$tw.wiki.removeEventListener("change",refreshHandler);
},false);
// Set up the styles
@@ -84,16 +84,13 @@ exports.startup = function() {
name: "keydown",
handlerObject: $tw.keyboardManager,
handlerMethod: "handleKeydownEvent"
},{
name: "click",
handlerObject: $tw.popup,
handlerMethod: "handleEvent"
}]);
srcWindow.document.documentElement.addEventListener("click",$tw.popup,true);
srcWindow.haveInitialisedWindow = true;
});
// Close open windows when unloading main window
$tw.addUnloadTask(function() {
$tw.utils.each(windows,function(win) {
$tw.utils.each($tw.windows,function(win) {
win.close();
});
});

View File

@@ -305,7 +305,8 @@ Syncer.prototype.syncFromServer = function() {
self.pollTimerId = null;
self.syncFromServer.call(self);
},self.pollTimerInterval);
};
},
syncSystemFromServer = (self.wiki.getTiddlerText("$:/config/SyncSystemTiddlersFromServer") === "yes" ? true : false);
if(this.syncadaptor && this.syncadaptor.getUpdatedTiddlers) {
this.logger.log("Retrieving updated tiddler list");
cancelNextSync();
@@ -320,9 +321,11 @@ Syncer.prototype.syncFromServer = function() {
self.titlesToBeLoaded[title] = true;
});
$tw.utils.each(updates.deletions,function(title) {
delete self.tiddlerInfo[title];
self.logger.log("Deleting tiddler missing from server:",title);
self.wiki.deleteTiddler(title);
if(syncSystemFromServer || !self.wiki.isSystemTiddler(title)) {
delete self.tiddlerInfo[title];
self.logger.log("Deleting tiddler missing from server:",title);
self.wiki.deleteTiddler(title);
}
});
if(updates.modifications.length > 0 || updates.deletions.length > 0) {
self.processTaskQueue();
@@ -365,9 +368,11 @@ Syncer.prototype.syncFromServer = function() {
}
// Delete any tiddlers that were previously reported but missing this time
$tw.utils.each(previousTitles,function(title) {
delete self.tiddlerInfo[title];
self.logger.log("Deleting tiddler missing from server:",title);
self.wiki.deleteTiddler(title);
if(syncSystemFromServer || !self.wiki.isSystemTiddler(title)) {
delete self.tiddlerInfo[title];
self.logger.log("Deleting tiddler missing from server:",title);
self.wiki.deleteTiddler(title);
}
});
self.processTaskQueue();
});
@@ -628,6 +633,10 @@ DeleteTiddlerTask.prototype.run = function(callback) {
}
// Remove the info stored about this tiddler
delete self.syncer.tiddlerInfo[self.title];
if($tw.boot.files){
// Remove the tiddler from $tw.boot.files
delete $tw.boot.files[self.title];
}
// Invoke the callback
callback(null);
},{

View File

@@ -57,7 +57,7 @@ exports.upgrade = function(wiki,titles,tiddlers) {
// Reject the incoming plugin by blanking all its fields
if($tw.utils.checkVersions(existingTiddler.fields.version,incomingTiddler.version)) {
tiddlers[title] = Object.create(null);
messages[title] = requiresReload + $tw.language.getString("Import/Upgrader/Plugins/Suppressed/Version",{variables: {incoming: incomingTiddler.version, existing: existingTiddler.fields.version}});
messages[title] = $tw.language.getString("Import/Upgrader/Plugins/Suppressed/Version",{variables: {incoming: incomingTiddler.version, existing: existingTiddler.fields.version}});
return;
}
}

View File

@@ -13,6 +13,7 @@ Modal message mechanism
"use strict";
var widget = require("$:/core/modules/widgets/widget.js");
var navigator = require("$:/core/modules/widgets/navigator.js");
var Modal = function(wiki) {
this.wiki = wiki;
@@ -41,7 +42,12 @@ Modal.prototype.display = function(title,options) {
return;
}
// Create the variables
var variables = $tw.utils.extend({currentTiddler: title},options.variables);
var variables = $tw.utils.extend({
currentTiddler: title,
"tv-story-list": (options.event && options.event.widget ? options.event.widget.getVariable("tv-story-list") : ""),
"tv-history-list": (options.event && options.event.widget ? options.event.widget.getVariable("tv-history-list") : "")
},options.variables);
// Create the wrapper divs
var wrapper = this.srcDocument.createElement("div"),
modalBackdrop = this.srcDocument.createElement("div"),
@@ -75,6 +81,31 @@ Modal.prototype.display = function(title,options) {
modalFooter.appendChild(modalFooterHelp);
modalFooter.appendChild(modalFooterButtons);
modalWrapper.appendChild(modalFooter);
var navigatorTree = {
"type": "navigator",
"attributes": {
"story": {
"name": "story",
"type": "string",
"value": variables["tv-story-list"]
},
"history": {
"name": "history",
"type": "string",
"value": variables["tv-history-list"]
}
},
"tag": "$navigator",
"isBlock": true,
"children": []
};
var navigatorWidgetNode = new navigator.navigator(navigatorTree, {
wiki: this.wiki,
document : this.srcDocument,
parentWidget: $tw.rootWidget
});
navigatorWidgetNode.render(modalBody,null);
// Render the title of the message
var headerWidgetNode = this.wiki.makeTranscludeWidget(title,{
field: "subtitle",
@@ -86,7 +117,7 @@ Modal.prototype.display = function(title,options) {
type: "string",
value: title
}}}],
parentWidget: $tw.rootWidget,
parentWidget: navigatorWidgetNode,
document: this.srcDocument,
variables: variables,
importPageMacros: true
@@ -94,11 +125,12 @@ Modal.prototype.display = function(title,options) {
headerWidgetNode.render(headerTitle,null);
// Render the body of the message
var bodyWidgetNode = this.wiki.makeTranscludeWidget(title,{
parentWidget: $tw.rootWidget,
parentWidget: navigatorWidgetNode,
document: this.srcDocument,
variables: variables,
importPageMacros: true
});
bodyWidgetNode.render(modalBody,null);
// Setup the link if present
if(options.downloadLink) {
@@ -135,7 +167,7 @@ Modal.prototype.display = function(title,options) {
value: $tw.language.getString("Buttons/Close/Caption")
}}}
]}],
parentWidget: $tw.rootWidget,
parentWidget: navigatorWidgetNode,
document: this.srcDocument,
variables: variables,
importPageMacros: true

View File

@@ -204,15 +204,23 @@ exports.deleteEmptyDirs = function(dirpath,callback) {
/*
Create a fileInfo object for saving a tiddler:
filepath: the absolute path to the file containing the tiddler
type: the type of the tiddler file (NOT the type of the tiddler)
type: the type of the tiddler file on disk (NOT the type of the tiddler)
hasMetaFile: true if the file also has a companion .meta file
isEditableFile: true if the tiddler was loaded via non-standard options & marked editable
Options include:
directory: absolute path of root directory to which we are saving
pathFilters: optional array of filters to be used to generate the base path
wiki: optional wiki for evaluating the pathFilters
extFilters: optional array of filters to be used to generate the base path
wiki: optional wiki for evaluating the pathFilters,
fileInfo: an existing fileInfo to check against
originalpath: a preferred filepath if no pathFilters match
*/
exports.generateTiddlerFileInfo = function(tiddler,options) {
var fileInfo = {};
var fileInfo = {}, metaExt;
// Propagate the isEditableFile flag
if(options.fileInfo) {
fileInfo.isEditableFile = options.fileInfo.isEditableFile || false;
}
// Check if the tiddler has any unsafe fields that can't be expressed in a .tid or .meta file: containing control characters, or leading/trailing whitespace
var hasUnsafeFields = false;
$tw.utils.each(tiddler.getFieldStrings(),function(value,fieldName) {
@@ -238,19 +246,69 @@ exports.generateTiddlerFileInfo = function(tiddler,options) {
fileInfo.type = tiddlerType;
fileInfo.hasMetaFile = true;
}
if(options.extFilters) {
// Check for extension override
metaExt = $tw.utils.generateTiddlerExtension(tiddler.fields.title,{
extFilters: options.extFilters,
wiki: options.wiki
});
if(metaExt){
if(metaExt === ".tid") {
// Overriding to the .tid extension needs special handling
fileInfo.type = "application/x-tiddler";
fileInfo.hasMetaFile = false;
} else if (metaExt === ".json") {
// Overriding to the .json extension needs special handling
fileInfo.type = "application/json";
fileInfo.hasMetaFile = false;
} else {
//If the new type matches a known extention, use that MIME type's encoding
var extInfo = $tw.utils.getFileExtensionInfo(metaExt);
fileInfo.type = extInfo ? extInfo.type : null;
fileInfo.encoding = $tw.utils.getTypeEncoding(metaExt);
fileInfo.hasMetaFile = true;
}
}
}
}
// Take the file extension from the tiddler content type
// Take the file extension from the tiddler content type or metaExt
var contentTypeInfo = $tw.config.contentTypeInfo[fileInfo.type] || {extension: ""};
// Generate the filepath
fileInfo.filepath = $tw.utils.generateTiddlerFilepath(tiddler.fields.title,{
extension: contentTypeInfo.extension,
extension: metaExt || contentTypeInfo.extension,
directory: options.directory,
pathFilters: options.pathFilters,
wiki: options.wiki
wiki: options.wiki,
fileInfo: options.fileInfo,
originalpath: options.originalpath
});
return fileInfo;
};
/*
Generate the file extension for saving a tiddler
Options include:
extFilters: optional array of filters to be used to generate the extention
wiki: optional wiki for evaluating the extFilters
*/
exports.generateTiddlerExtension = function(title,options) {
var self = this,
extension;
// Check if any of the extFilters applies
if(options.extFilters && options.wiki) {
$tw.utils.each(options.extFilters,function(filter) {
if(!extension) {
var source = options.wiki.makeTiddlerIterator([title]),
result = options.wiki.filterTiddlers(filter,null,source);
if(result.length > 0) {
extension = result[0];
}
}
});
}
return extension;
};
/*
Generate the filepath for saving a tiddler
Options include:
@@ -258,12 +316,14 @@ Options include:
directory: absolute path of root directory to which we are saving
pathFilters: optional array of filters to be used to generate the base path
wiki: optional wiki for evaluating the pathFilters
fileInfo: an existing fileInfo object to check against
*/
exports.generateTiddlerFilepath = function(title,options) {
var self = this,
directory = options.directory || "",
extension = options.extension || "",
filepath;
originalpath = options.originalpath || "",
filepath;
// Check if any of the pathFilters applies
if(options.pathFilters && options.wiki) {
$tw.utils.each(options.pathFilters,function(filter) {
@@ -276,8 +336,11 @@ exports.generateTiddlerFilepath = function(title,options) {
}
});
}
// If not, generate a base pathname
if(!filepath) {
if(!filepath && originalpath !== "") {
//Use the originalpath without the extension
var ext = path.extname(originalpath);
filepath = originalpath.substring(0,originalpath.length - ext.length);
} else if(!filepath) {
filepath = title;
// If the filepath already ends in the extension then remove it
if(filepath.substring(filepath.length - extension.length) === extension) {
@@ -286,10 +349,13 @@ exports.generateTiddlerFilepath = function(title,options) {
// Remove any forward or backward slashes so we don't create directories
filepath = filepath.replace(/\/|\\/g,"_");
}
// Don't let the filename start with a dot because such files are invisible on *nix
filepath = filepath.replace(/^\./g,"_");
//If the path does not start with "." or ".." and a path seperator, then
if(!/^\.{1,2}[/\\]/g.test(filepath)) {
// Don't let the filename start with any dots because such files are invisible on *nix
filepath = filepath.replace(/^\.+/g,"_");
}
// Remove any characters that can't be used in cross-platform filenames
filepath = $tw.utils.transliterate(filepath.replace(/<|>|\:|\"|\||\?|\*|\^/g,"_"));
filepath = $tw.utils.transliterate(filepath.replace(/<|>|~|\:|\"|\||\?|\*|\^/g,"_"));
// Truncate the filename if it is too long
if(filepath.length > 200) {
filepath = filepath.substr(0,200);
@@ -306,12 +372,30 @@ exports.generateTiddlerFilepath = function(title,options) {
});
}
// Add a uniquifier if the file already exists
var fullPath,
var fullPath, oldPath = (options.fileInfo) ? options.fileInfo.filepath : undefined,
count = 0;
do {
fullPath = path.resolve(directory,filepath + (count ? "_" + count : "") + extension);
if(oldPath && oldPath == fullPath) {
break;
}
count++;
} while(fs.existsSync(fullPath));
// If the last write failed with an error, or if path does not start with:
// the resolved options.directory, the resolved wikiPath directory, or the wikiTiddlersPath directory,
// then encodeURIComponent() and resolve to tiddler directory
var newPath = fullPath,
encode = (options.fileInfo || {writeError: false}).writeError == true;
if(!encode){
encode = !(fullPath.indexOf(path.resolve(directory)) == 0 ||
fullPath.indexOf(path.resolve($tw.boot.wikiPath)) == 0 ||
fullPath.indexOf($tw.boot.wikiTiddlersPath) == 0);
}
if(encode){
fullPath = path.resolve(directory, encodeURIComponent(fullPath));
}
// Call hook to allow plugins to modify the final path
fullPath = $tw.hooks.invokeHook("th-make-tiddler-path", newPath, fullPath);
// Return the full path to the file
return fullPath;
};
@@ -366,4 +450,58 @@ exports.saveTiddlerToFileSync = function(tiddler,fileInfo) {
}
};
/*
Delete a file described by the fileInfo if it exits
*/
exports.deleteTiddlerFile = function(fileInfo, callback) {
//Only attempt to delete files that exist on disk
if(!fileInfo.filepath || !fs.existsSync(fileInfo.filepath)) {
return callback(null);
}
// Delete the file
fs.unlink(fileInfo.filepath,function(err) {
if(err) {
return callback(err);
}
// Delete the metafile if present
if(fileInfo.hasMetaFile && fs.existsSync(fileInfo.filepath + ".meta")) {
fs.unlink(fileInfo.filepath + ".meta",function(err) {
if(err) {
return callback(err);
}
return $tw.utils.deleteEmptyDirs(path.dirname(fileInfo.filepath),callback);
});
} else {
return $tw.utils.deleteEmptyDirs(path.dirname(fileInfo.filepath),callback);
}
});
};
/*
Cleanup old files on disk, by comparing the options values:
adaptorInfo from $tw.syncer.tiddlerInfo
bootInfo from $tw.boot.files
*/
exports.cleanupTiddlerFiles = function(options, callback) {
var adaptorInfo = options.adaptorInfo || {},
bootInfo = options.bootInfo || {},
title = options.title || "undefined";
if(adaptorInfo.filepath && bootInfo.filepath && adaptorInfo.filepath !== bootInfo.filepath) {
return $tw.utils.deleteTiddlerFile(adaptorInfo, function(err){
if(err) {
if ((err.code == "EPERM" || err.code == "EACCES") && err.syscall == "unlink") {
// Error deleting the previous file on disk, should fail gracefully
$tw.syncer.displayError("Server desynchronized. Error cleaning up previous file for tiddler: "+title, err);
return callback(null);
} else {
return callback(err);
}
}
return callback(null);
});
} else {
return callback(null);
}
};
})();

View File

@@ -0,0 +1,118 @@
/*\
module-type: utils
title: $:/core/modules/utils/linkedlist.js
type: application/javascript
This is a doubly-linked indexed list intended for manipulation, particularly
pushTop, which it does with significantly better performance than an array.
\*/
(function(){
function LinkedList() {
this.clear();
};
LinkedList.prototype.clear = function() {
this.index = Object.create(null);
// LinkedList performs the duty of both the head and tail node
this.next = this;
this.prev = this;
this.length = 0;
};
LinkedList.prototype.remove = function(value) {
if($tw.utils.isArray(value)) {
for(var t=0; t<value.length; t++) {
_removeOne(this,value[t]);
}
} else {
_removeOne(this,value);
}
};
LinkedList.prototype.push = function(/* values */) {
for(var i = 0; i < arguments.length; i++) {
var value = arguments[i];
var node = {value: value};
var preexistingNode = this.index[value];
_linkToEnd(this,node);
if(preexistingNode) {
// We want to keep pointing to the first instance, but we want
// to have that instance (or chain of instances) point to the
// new one.
while (preexistingNode.copy) {
preexistingNode = preexistingNode.copy;
}
preexistingNode.copy = node;
} else {
this.index[value] = node;
}
}
};
LinkedList.prototype.pushTop = function(value) {
if($tw.utils.isArray(value)) {
for(var t=0; t<value.length; t++) {
_removeOne(this,value[t]);
}
this.push.apply(this,value);
} else {
var node = _removeOne(this,value);
if(!node) {
node = {value: value};
this.index[value] = node;
} else {
// Put this node at the end of the copy chain.
var preexistingNode = node;
while(preexistingNode.copy) {
preexistingNode = preexistingNode.copy;
}
// The order of these three statements is important,
// because sometimes preexistingNode == node.
preexistingNode.copy = node;
this.index[value] = node.copy;
node.copy = undefined;
}
_linkToEnd(this,node);
}
};
LinkedList.prototype.each = function(callback) {
for(var ptr = this.next; ptr !== this; ptr = ptr.next) {
callback(ptr.value);
}
};
LinkedList.prototype.toArray = function() {
var output = [];
for(var ptr = this.next; ptr !== this; ptr = ptr.next) {
output.push(ptr.value);
}
return output;
};
function _removeOne(list,value) {
var node = list.index[value];
if(node) {
node.prev.next = node.next;
node.next.prev = node.prev;
list.length -= 1;
// Point index to the next instance of the same value, maybe nothing.
list.index[value] = node.copy;
}
return node;
};
function _linkToEnd(list,node) {
// Sticks the given node onto the end of the list.
list.prev.next = node;
node.prev = list.prev;
list.prev = node;
node.next = list;
list.length += 1;
};
exports.LinkedList = LinkedList;
})();

View File

@@ -53,6 +53,19 @@ exports.warning = function(text) {
exports.log(text,"brown/orange");
};
/*
Log a table of name: value pairs
*/
exports.logTable = function(data) {
if(console.table) {
console.table(data);
} else {
$tw.utils.each(data,function(value,name) {
console.log(name + ": " + value);
});
}
}
/*
Return the integer represented by the str (string).
Return the dflt (default) parameter if str is not a base-10 number.
@@ -289,7 +302,7 @@ exports.formatDateString = function(date,template) {
return $tw.utils.pad($tw.utils.getHours12(date));
}],
[/^wYYYY/, function() {
return $tw.utils.getYearForWeekNo(date);
return $tw.utils.pad($tw.utils.getYearForWeekNo(date),4);
}],
[/^hh12/, function() {
return $tw.utils.getHours12(date);
@@ -298,7 +311,14 @@ exports.formatDateString = function(date,template) {
return date.getDate() + $tw.utils.getDaySuffix(date);
}],
[/^YYYY/, function() {
return date.getFullYear();
return $tw.utils.pad(date.getFullYear(),4);
}],
[/^aYYYY/, function() {
return $tw.utils.pad(Math.abs(date.getFullYear()),4);
}],
[/^\{era:([^,\|}]*)\|([^}\|]*)\|([^}]*)\}/, function(match) {
var year = date.getFullYear();
return year === 0 ? match[2] : (year < 0 ? match[1] : match[3]);
}],
[/^0hh/, function() {
return $tw.utils.pad(date.getHours());
@@ -387,7 +407,7 @@ exports.formatDateString = function(date,template) {
$tw.utils.each(matches, function(m) {
var match = m[0].exec(t);
if(match) {
matchString = m[1].call();
matchString = m[1].call(null,match);
t = t.substr(match[0].length);
return false;
}
@@ -544,7 +564,7 @@ exports.escape = function(ch) {
// Turns a string into a legal JavaScript string
// Copied from peg.js, thanks to David Majda
exports.stringify = function(s) {
exports.stringify = function(s, rawUnicode) {
/*
* ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a string
* literal except for the closing quote character, backslash, carriage return,
@@ -553,19 +573,21 @@ exports.stringify = function(s) {
*
* For portability, we also escape all non-ASCII characters.
*/
var regex = rawUnicode ? /[\x00-\x1f]/g : /[\x00-\x1f\x80-\uFFFF]/g;
return (s || "")
.replace(/\\/g, '\\\\') // backslash
.replace(/"/g, '\\"') // double quote character
.replace(/'/g, "\\'") // single quote character
.replace(/\r/g, '\\r') // carriage return
.replace(/\n/g, '\\n') // line feed
.replace(/[\x00-\x1f\x80-\uFFFF]/g, exports.escape); // non-ASCII characters
.replace(regex, exports.escape); // non-ASCII characters
};
// Turns a string into a legal JSON string
// Derived from peg.js, thanks to David Majda
exports.jsonStringify = function(s) {
exports.jsonStringify = function(s, rawUnicode) {
// See http://www.json.org/
var regex = rawUnicode ? /[\x00-\x1f]/g : /[\x00-\x1f\x80-\uFFFF]/g;
return (s || "")
.replace(/\\/g, '\\\\') // backslash
.replace(/"/g, '\\"') // double quote character
@@ -574,7 +596,7 @@ exports.jsonStringify = function(s) {
.replace(/\x08/g, '\\b') // backspace
.replace(/\x0c/g, '\\f') // formfeed
.replace(/\t/g, '\\t') // tab
.replace(/[\x00-\x1f\x80-\uFFFF]/g,function(s) {
.replace(regex,function(s) {
return '\\u' + $tw.utils.pad(s.charCodeAt(0).toString(16).toUpperCase(),4);
}); // non-ASCII characters
};

View File

@@ -0,0 +1,77 @@
/*\
title: $:/core/modules/widgets/action-confirm.js
type: application/javascript
module-type: widget
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var Widget = require("$:/core/modules/widgets/widget.js").widget;
var ConfirmWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options);
};
/*
Inherit from the base widget class
*/
ConfirmWidget.prototype = new Widget();
/*
Render this widget into the DOM
*/
ConfirmWidget.prototype.render = function(parent,nextSibling) {
this.computeAttributes();
this.execute();
this.parentDomNode = parent;
this.renderChildren(parent,nextSibling);
};
/*
Compute the internal state of the widget
*/
ConfirmWidget.prototype.execute = function() {
this.message = this.getAttribute("$message",$tw.language.getString("ConfirmAction"));
this.prompt = (this.getAttribute("$prompt","yes") == "no" ? false : true);
this.makeChildWidgets();
};
/*
Refresh the widget by ensuring our attributes are up to date
*/
ConfirmWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(changedAttributes["$message"] || changedAttributes["$prompt"]) {
this.refreshSelf();
return true;
}
return this.refreshChildren(changedTiddlers);
};
/*
Invoke the action associated with this widget
*/
ConfirmWidget.prototype.invokeAction = function(triggeringWidget,event) {
var invokeActions = true,
handled = true;
if(this.prompt) {
invokeActions = confirm(this.message);
}
if(invokeActions) {
handled = this.invokeActions(triggeringWidget,event);
}
return handled;
};
ConfirmWidget.prototype.allowActionPropagation = function() {
return false;
};
exports["action-confirm"] = ConfirmWidget;
})();

View File

@@ -0,0 +1,93 @@
/*\
title: $:/core/modules/widgets/action-log.js
type: application/javascript
module-type: widget
Action widget to log debug messages
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var Widget = require("$:/core/modules/widgets/widget.js").widget;
var LogWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options);
};
/*
Inherit from the base widget class
*/
LogWidget.prototype = new Widget();
/*
Render this widget into the DOM
*/
LogWidget.prototype.render = function(parent,nextSibling) {
this.computeAttributes();
this.execute();
};
LogWidget.prototype.execute = function(){
this.message = this.getAttribute("$$message","debug");
this.logAll = this.getAttribute("$$all","no") === "yes" ? true : false;
this.filter = this.getAttribute("$$filter");
}
/*
Refresh the widget by ensuring our attributes are up to date
*/
LogWidget.prototype.refresh = function(changedTiddlers) {
this.refreshSelf();
return true;
};
/*
Invoke the action associated with this widget
*/
LogWidget.prototype.invokeAction = function(triggeringWidget,event) {
this.log();
return true; // Action was invoked
};
LogWidget.prototype.log = function() {
var data = {},
dataCount,
allVars = {},
filteredVars;
$tw.utils.each(this.attributes,function(attribute,name) {
if(name.substring(0,2) !== "$$") {
data[name] = attribute;
}
});
for(var v in this.variables) {
allVars[v] = this.getVariable(v,{defaultValue:""});
}
if(this.filter) {
filteredVars = this.wiki.compileFilter(this.filter).call(this.wiki,this.wiki.makeTiddlerIterator(allVars));
$tw.utils.each(filteredVars,function(name) {
data[name] = allVars[name];
});
}
dataCount = $tw.utils.count(data);
console.group(this.message);
if(dataCount > 0) {
$tw.utils.logTable(data);
}
if(this.logAll || !dataCount) {
console.groupCollapsed("All variables");
$tw.utils.logTable(allVars);
console.groupEnd();
}
console.groupEnd();
}
exports["action-log"] = LogWidget;
})();

View File

@@ -27,18 +27,20 @@ ButtonWidget.prototype = new Widget();
Render this widget into the DOM
*/
ButtonWidget.prototype.render = function(parent,nextSibling) {
var self = this;
var self = this,
tag = "button",
domNode;
// Remember parent
this.parentDomNode = parent;
// Compute attributes and execute state
this.computeAttributes();
this.execute();
// Create element
var tag = "button";
if(this.buttonTag && $tw.config.htmlUnsafeElements.indexOf(this.buttonTag) === -1) {
tag = this.buttonTag;
}
var domNode = this.document.createElement(tag);
domNode = this.document.createElement(tag);
this.domNode = domNode;
// Assign classes
var classes = this["class"].split(" ") || [],
isPoppedUp = (this.popup || this.popupTitle) && this.isPoppedUp();
@@ -67,7 +69,10 @@ ButtonWidget.prototype.render = function(parent,nextSibling) {
// Set the tabindex
if(this.tabIndex) {
domNode.setAttribute("tabindex",this.tabIndex);
}
}
if(this.isDisabled === "yes") {
domNode.setAttribute("disabled",true);
}
// Add a click event handler
domNode.addEventListener("click",function (event) {
var handled = false;
@@ -197,10 +202,10 @@ ButtonWidget.prototype.execute = function() {
this.setTo = this.getAttribute("setTo");
this.popup = this.getAttribute("popup");
this.hover = this.getAttribute("hover");
this["class"] = this.getAttribute("class","");
this["aria-label"] = this.getAttribute("aria-label");
this.tooltip = this.getAttribute("tooltip");
this.style = this.getAttribute("style");
this["class"] = this.getAttribute("class","");
this.selectedClass = this.getAttribute("selectedClass");
this.defaultSetValue = this.getAttribute("default","");
this.buttonTag = this.getAttribute("tag");
@@ -211,18 +216,39 @@ ButtonWidget.prototype.execute = function() {
this.setIndex = this.getAttribute("setIndex");
this.popupTitle = this.getAttribute("popupTitle");
this.tabIndex = this.getAttribute("tabindex");
this.isDisabled = this.getAttribute("disabled","no");
// Make child widgets
this.makeChildWidgets();
};
ButtonWidget.prototype.updateDomNodeClasses = function() {
var domNodeClasses = this.domNode.className.split(" "),
oldClasses = this.class.split(" "),
newClasses;
this["class"] = this.getAttribute("class","");
newClasses = this.class.split(" ");
//Remove classes assigned from the old value of class attribute
$tw.utils.each(oldClasses,function(oldClass){
var i = domNodeClasses.indexOf(oldClass);
if(i !== -1) {
domNodeClasses.splice(i,1);
}
});
//Add new classes from updated class attribute.
$tw.utils.pushTop(domNodeClasses,newClasses);
this.domNode.className = domNodeClasses.join(" ");
}
/*
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/
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["class"] || 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) {
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) {
this.refreshSelf();
return true;
} else if(changedAttributes["class"]) {
this.updateDomNodeClasses();
}
return this.refreshChildren(changedTiddlers);
};

View File

@@ -41,6 +41,9 @@ CheckboxWidget.prototype.render = function(parent,nextSibling) {
if(this.getValue()) {
this.inputDomNode.setAttribute("checked","true");
}
if(this.isDisabled === "yes") {
this.inputDomNode.setAttribute("disabled",true);
}
this.labelDomNode.appendChild(this.inputDomNode);
this.spanDomNode = this.document.createElement("span");
this.labelDomNode.appendChild(this.spanDomNode);
@@ -181,6 +184,7 @@ CheckboxWidget.prototype.execute = function() {
this.checkboxDefault = this.getAttribute("default");
this.checkboxClass = this.getAttribute("class","");
this.checkboxInvertTag = this.getAttribute("invertTag","");
this.isDisabled = this.getAttribute("disabled","no");
// Make the child widgets
this.makeChildWidgets();
};
@@ -190,7 +194,7 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
*/
CheckboxWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(changedAttributes.tiddler || changedAttributes.tag || changedAttributes.invertTag || changedAttributes.field || changedAttributes.index || changedAttributes.checked || changedAttributes.unchecked || changedAttributes["default"] || changedAttributes["class"]) {
if(changedAttributes.tiddler || changedAttributes.tag || changedAttributes.invertTag || changedAttributes.field || changedAttributes.index || changedAttributes.checked || changedAttributes.unchecked || changedAttributes["default"] || changedAttributes["class"] || changedAttributes.disabled) {
this.refreshSelf();
return true;
} else {

View File

@@ -27,21 +27,21 @@ DroppableWidget.prototype = new Widget();
Render this widget into the DOM
*/
DroppableWidget.prototype.render = function(parent,nextSibling) {
var self = this;
var self = this,
tag = this.parseTreeNode.isBlock ? "div" : "span",
domNode;
// Remember parent
this.parentDomNode = parent;
// Compute attributes and execute state
this.computeAttributes();
this.execute();
var tag = this.parseTreeNode.isBlock ? "div" : "span";
if(this.droppableTag && $tw.config.htmlUnsafeElements.indexOf(this.droppableTag) === -1) {
tag = this.droppableTag;
}
// Create element and assign classes
var domNode = this.document.createElement(tag),
classes = (this.droppableClass || "").split(" ");
classes.push("tc-droppable");
domNode.className = classes.join(" ");
domNode = this.document.createElement(tag);
this.domNode = domNode;
this.assignDomNodeClasses();
// Add event handlers
if(this.droppableEnable) {
$tw.utils.addEventListeners(domNode,[
@@ -50,6 +50,8 @@ DroppableWidget.prototype.render = function(parent,nextSibling) {
{name: "dragleave", handlerObject: this, handlerMethod: "handleDragLeaveEvent"},
{name: "drop", handlerObject: this, handlerMethod: "handleDropEvent"}
]);
} else {
$tw.utils.addClass(this.domNode,this.disabledClass);
}
// Insert element
parent.insertBefore(domNode,nextSibling);
@@ -144,24 +146,32 @@ DroppableWidget.prototype.execute = function() {
this.droppableActions = this.getAttribute("actions");
this.droppableEffect = this.getAttribute("effect","copy");
this.droppableTag = this.getAttribute("tag");
this.droppableClass = this.getAttribute("class");
this.droppableEnable = (this.getAttribute("enable") || "yes") === "yes";
this.disabledClass = this.getAttribute("disabledClass","");
// Make child widgets
this.makeChildWidgets();
};
DroppableWidget.prototype.assignDomNodeClasses = function() {
var classes = this.getAttribute("class","").split(" ");
classes.push("tc-droppable");
this.domNode.className = classes.join(" ");
};
/*
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/
DroppableWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(changedAttributes["class"] || changedAttributes.tag || changedAttributes.enable) {
if(changedAttributes.tag || changedAttributes.enable || changedAttributes.disabledClass || changedAttributes.actions || changedAttributes.effect) {
this.refreshSelf();
return true;
} else if(changedAttributes["class"]) {
this.assignDomNodeClasses();
}
return this.refreshChildren(changedTiddlers);
};
exports.droppable = DroppableWidget;
})();
})();

View File

@@ -51,6 +51,7 @@ EditWidget.prototype.execute = function() {
this.editCancelPopups = this.getAttribute("cancelPopups","");
this.editInputActions = this.getAttribute("inputActions");
this.editRefreshTitle = this.getAttribute("refreshTitle");
this.editAutoComplete = this.getAttribute("autocomplete");
// Choose the appropriate edit widget
this.editorType = this.getEditorType();
// Make the child widgets
@@ -89,7 +90,7 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
EditWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
// Refresh if an attribute has changed, or the type associated with the target tiddler has changed
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.tabindex || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || (changedTiddlers[this.editTitle] && this.getEditorType() !== this.editorType)) {
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.tabindex || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || changedAttributes.autocomplete || (changedTiddlers[this.editTitle] && this.getEditorType() !== this.editorType)) {
this.refreshSelf();
return true;
} else {

View File

@@ -0,0 +1,156 @@
/*\
title: $:/core/modules/widgets/eventcatcher.js
type: application/javascript
module-type: widget
Event handler widget
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var Widget = require("$:/core/modules/widgets/widget.js").widget;
var EventWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options);
};
/*
Inherit from the base widget class
*/
EventWidget.prototype = new Widget();
/*
Render this widget into the DOM
*/
EventWidget.prototype.render = function(parent,nextSibling) {
var self = this;
// Remember parent
this.parentDomNode = parent;
// Compute attributes and execute state
this.computeAttributes();
this.execute();
// Create element
var tag = this.parseTreeNode.isBlock ? "div" : "span";
if(this.elementTag && $tw.config.htmlUnsafeElements.indexOf(this.elementTag) === -1) {
tag = this.elementTag;
}
var domNode = this.document.createElement(tag);
this.domNode = domNode;
// Assign classes
this.assignDomNodeClasses();
// Add our event handler
$tw.utils.each(this.types,function(type) {
domNode.addEventListener(type,function(event) {
var selector = self.getAttribute("selector"),
actions = self.getAttribute("actions-"+type),
selectedNode = event.target,
selectedNodeRect,
catcherNodeRect,
variables = {};
if(selector) {
// Search ancestors for a node that matches the selector
while(!selectedNode.matches(selector) && selectedNode !== domNode) {
selectedNode = selectedNode.parentNode;
}
// If we found one, copy the attributes as variables, otherwise exit
if(selectedNode.matches(selector)) {
$tw.utils.each(selectedNode.attributes,function(attribute) {
variables["dom-" + attribute.name] = attribute.value.toString();
});
//Add a variable with a popup coordinate string for the selected node
variables["tv-popup-coords"] = "(" + selectedNode.offsetLeft + "," + selectedNode.offsetTop +"," + selectedNode.offsetWidth + "," + selectedNode.offsetHeight + ")";
//Add variables for offset of selected node
variables["tv-selectednode-posx"] = selectedNode.offsetLeft.toString();
variables["tv-selectednode-posy"] = selectedNode.offsetTop.toString();
variables["tv-selectednode-width"] = selectedNode.offsetWidth.toString();
variables["tv-selectednode-height"] = selectedNode.offsetHeight.toString();
//Add variables for event X and Y position relative to selected node
selectedNodeRect = selectedNode.getBoundingClientRect();
variables["event-fromselected-posx"] = (event.clientX - selectedNodeRect.left).toString();
variables["event-fromselected-posy"] = (event.clientY - selectedNodeRect.top).toString();
//Add variables for event X and Y position relative to event catcher node
catcherNodeRect = self.domNode.getBoundingClientRect();
variables["event-fromcatcher-posx"] = (event.clientX - catcherNodeRect.left).toString();
variables["event-fromcatcher-posy"] = (event.clientY - catcherNodeRect.top).toString();
} else {
return false;
}
}
// Execute our actions with the variables
if(actions) {
// Add a variable for the modifier key
variables.modifier = $tw.keyboardManager.getEventModifierKeyDescriptor(event);
// Add a variable for the mouse button
if("button" in event) {
if(event.button === 0) {
variables["event-mousebutton"] = "left";
} else if(event.button === 1) {
variables["event-mousebutton"] = "middle";
} else if(event.button === 2) {
variables["event-mousebutton"] = "right";
}
}
variables["event-type"] = event.type.toString();
if(typeof event.detail === "object" && !!event.detail) {
$tw.utils.each(event.detail,function(detailValue,detail) {
variables["event-detail-" + detail] = detailValue.toString();
});
} else if(!!event.detail) {
variables["event-detail"] = event.detail.toString();
}
self.invokeActionString(actions,self,event,variables);
event.preventDefault();
event.stopPropagation();
return true;
}
return false;
},false);
});
// Insert element
parent.insertBefore(domNode,nextSibling);
this.renderChildren(domNode,null);
this.domNodes.push(domNode);
};
/*
Compute the internal state of the widget
*/
EventWidget.prototype.execute = function() {
var self = this;
// Get attributes that require a refresh on change
this.types = this.getAttribute("events","").split(" ");
this.elementTag = this.getAttribute("tag");
// Make child widgets
this.makeChildWidgets();
};
EventWidget.prototype.assignDomNodeClasses = function() {
var classes = this.getAttribute("class","").split(" ");
classes.push("tc-eventcatcher");
this.domNode.className = classes.join(" ");
};
/*
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/
EventWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(changedAttributes["events"] || changedAttributes["tag"]) {
this.refreshSelf();
return true;
} else if(changedAttributes["class"]) {
this.assignDomNodeClasses();
}
return this.refreshChildren(changedTiddlers);
};
exports.eventcatcher = EventWidget;
})();

View File

@@ -46,13 +46,15 @@ KeyboardWidget.prototype.render = function(parent,nextSibling) {
// Add a keyboard event handler
domNode.addEventListener("keydown",function (event) {
if($tw.keyboardManager.checkKeyDescriptors(event,self.keyInfoArray)) {
self.invokeActions(self,event);
var handled = self.invokeActions(self,event);
if(self.actions) {
self.invokeActionString(self.actions,self,event);
}
self.dispatchMessage(event);
event.preventDefault();
event.stopPropagation();
if(handled || self.actions || self.message) {
event.preventDefault();
event.stopPropagation();
}
return true;
}
return false;

View File

@@ -0,0 +1,30 @@
/*\
title: $:/core/modules/widgets/log.js
type: application/javascript
module-type: widget-subclass
Widget to log debug messages
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
exports.baseClass = "action-log";
exports.name = "log";
exports.constructor = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options);
}
exports.prototype = {};
exports.prototype.render = function(event) {
Object.getPrototypeOf(Object.getPrototypeOf(this)).render.call(this,event);
Object.getPrototypeOf(Object.getPrototypeOf(this)).log.call(this);
}
})();

View File

@@ -55,9 +55,19 @@ MacroCallWidget.prototype.execute = function() {
// Are we rendering to HTML?
if(this.renderOutput === "text/html") {
// If so we'll return the parsed macro
var parser = this.wiki.parseText(this.parseType,text,
{parseAsInline: !this.parseTreeNode.isBlock});
parseTreeNodes = parser ? parser.tree : [];
// Check if we've already cached parsing this macro
var mode = this.parseTreeNode.isBlock ? "blockParser" : "inlineParser",
parser;
if(variableInfo.srcVariable && variableInfo.srcVariable[mode]) {
parser = variableInfo.srcVariable[mode];
} else {
parser = this.wiki.parseText(this.parseType,text,
{parseAsInline: !this.parseTreeNode.isBlock});
if(variableInfo.isCacheable && variableInfo.srcVariable) {
variableInfo.srcVariable[mode] = parser;
}
}
var parseTreeNodes = parser ? parser.tree : [];
// Wrap the parse tree in a vars widget assigning the parameters to variables named "__paramname__"
var attributes = {};
$tw.utils.each(variableInfo.params,function(param) {

View File

@@ -128,7 +128,7 @@ NavigatorWidget.prototype.replaceFirstTitleInStory = function(storyList,oldTitle
NavigatorWidget.prototype.addToStory = function(title,fromTitle) {
if(this.storyTitle) {
this.story.addToStory(title,fromTitle,this.storyTitle,{
this.story.addToStory(title,fromTitle,{
openLinkFromInsideRiver: this.getAttribute("openLinkFromInsideRiver","top"),
openLinkFromOutsideRiver: this.getAttribute("openLinkFromOutsideRiver","top")
});
@@ -529,6 +529,7 @@ NavigatorWidget.prototype.handleImportTiddlersEvent = function(event) {
$tw.utils.each(importData.tiddlers,function(tiddler,title) {
if($tw.utils.count(tiddler) === 0) {
newFields["selection-" + title] = "unchecked";
newFields["suppressed-" + title] = "yes";
}
});
// Save the $:/Import tiddler

View File

@@ -13,7 +13,6 @@ Set a field or index at a given tiddler via radio buttons
"use strict";
var Widget = require("$:/core/modules/widgets/widget.js").widget;
var RadioWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options);
};
@@ -37,13 +36,16 @@ RadioWidget.prototype.render = function(parent,nextSibling) {
// Create our elements
this.labelDomNode = this.document.createElement("label");
this.labelDomNode.setAttribute("class",
"tc-radio " + this.radioClass + (isChecked ? " tc-radio-selected" : "")
);
"tc-radio " + this.radioClass + (isChecked ? " tc-radio-selected" : "")
);
this.inputDomNode = this.document.createElement("input");
this.inputDomNode.setAttribute("type","radio");
if(isChecked) {
this.inputDomNode.setAttribute("checked","true");
}
if(this.isDisabled === "yes") {
this.inputDomNode.setAttribute("disabled",true);
}
this.labelDomNode.appendChild(this.inputDomNode);
this.spanDomNode = this.document.createElement("span");
this.labelDomNode.appendChild(this.spanDomNode);
@@ -83,6 +85,10 @@ RadioWidget.prototype.handleChangeEvent = function(event) {
if(this.inputDomNode.checked) {
this.setValue();
}
// Trigger actions
if(this.radioActions) {
this.invokeActionString(this.radioActions,this,event,{"actionValue": this.radioValue});
}
};
/*
@@ -95,6 +101,8 @@ RadioWidget.prototype.execute = function() {
this.radioIndex = this.getAttribute("index");
this.radioValue = this.getAttribute("value");
this.radioClass = this.getAttribute("class","");
this.isDisabled = this.getAttribute("disabled","no");
this.radioActions = this.getAttribute("actions","");
// Make the child widgets
this.makeChildWidgets();
};
@@ -104,16 +112,11 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
*/
RadioWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.value || changedAttributes["class"]) {
if(($tw.utils.count(changedAttributes) > 0) || changedTiddlers[this.radioTitle]) {
this.refreshSelf();
return true;
} else {
var refreshed = false;
if(changedTiddlers[this.radioTitle]) {
this.inputDomNode.checked = this.getValue() === this.radioValue;
refreshed = true;
}
return this.refreshChildren(changedTiddlers) || refreshed;
return this.refreshChildren(changedTiddlers);
}
};

View File

@@ -46,11 +46,16 @@ RangeWidget.prototype.render = function(parent,nextSibling) {
if(this.increment){
this.inputDomNode.setAttribute("step", this.increment);
}
if(this.isDisabled === "yes") {
this.inputDomNode.setAttribute("disabled",true);
}
this.inputDomNode.value = this.getValue();
// Add a click event handler
$tw.utils.addEventListeners(this.inputDomNode,[
{name: "input", handlerObject: this, handlerMethod: "handleInputEvent"},
{name: "change", handlerObject: this, handlerMethod: "handleInputEvent"}
{name:"mousedown", handlerObject:this, handlerMethod:"handleMouseDownEvent"},
{name:"mouseup", handlerObject:this, handlerMethod:"handleMouseUpEvent"},
{name:"change", handlerObject:this, handlerMethod:"handleChangeEvent"},
{name:"input", handlerObject:this, handlerMethod:"handleInputEvent"},
]);
// Insert the label into the DOM and render any children
parent.insertBefore(this.inputDomNode,nextSibling);
@@ -59,23 +64,77 @@ RangeWidget.prototype.render = function(parent,nextSibling) {
RangeWidget.prototype.getValue = function() {
var tiddler = this.wiki.getTiddler(this.tiddlerTitle),
fieldName = this.tiddlerField || "text",
value = this.defaultValue;
fieldName = this.tiddlerField,
value = this.defaultValue;
if(tiddler) {
if(this.tiddlerIndex) {
value = this.wiki.extractTiddlerDataItem(tiddler,this.tiddlerIndex,this.defaultValue || "");
value = this.wiki.extractTiddlerDataItem(tiddler,this.tiddlerIndex,this.defaultValue);
} else {
if($tw.utils.hop(tiddler.fields,fieldName)) {
value = tiddler.fields[fieldName] || "";
} else {
value = this.defaultValue || "";
value = this.defaultValue;
}
}
}
return value;
};
RangeWidget.prototype.getActionVariables = function(options) {
options = options || {};
var hasChanged = (this.startValue !== this.inputDomNode.value) ? "yes" : "no";
// Trigger actions. Use variables = {key:value, key:value ...}
// the "value" is needed.
return $tw.utils.extend({"actionValue": this.inputDomNode.value, "actionValueHasChanged": hasChanged}, options);
}
// actionsStart
RangeWidget.prototype.handleMouseDownEvent = function(event) {
this.mouseDown = true; // TODO remove once IE is gone.
this.startValue = this.inputDomNode.value; // TODO remove this line once IE is gone!
this.handleEvent(event);
// Trigger actions
if(this.actionsMouseDown) {
var variables = this.getActionVariables() // TODO this line will go into the function call below.
this.invokeActionString(this.actionsMouseDown,this,event,variables);
}
}
// actionsStop
RangeWidget.prototype.handleMouseUpEvent = function(event) {
this.mouseDown = false; // TODO remove once IE is gone.
this.handleEvent(event);
// Trigger actions
if(this.actionsMouseUp) {
var variables = this.getActionVariables()
this.invokeActionString(this.actionsMouseUp,this,event,variables);
}
// TODO remove the following if() once IE is gone!
if ($tw.browser.isIE) {
if (this.startValue !== this.inputDomNode.value) {
this.handleChangeEvent(event);
this.startValue = this.inputDomNode.value;
}
}
}
RangeWidget.prototype.handleChangeEvent = function(event) {
if (this.mouseDown) { // TODO refactor this function once IE is gone.
this.handleInputEvent(event);
}
};
RangeWidget.prototype.handleInputEvent = function(event) {
this.handleEvent(event);
// Trigger actions
if(this.actionsInput) {
// "tiddler" parameter may be missing. See .execute() below
var variables = this.getActionVariables({"actionValueHasChanged": "yes"}) // TODO this line will go into the function call below.
this.invokeActionString(this.actionsInput,this,event,variables);
}
};
RangeWidget.prototype.handleEvent = function(event) {
if(this.getValue() !== this.inputDomNode.value) {
if(this.tiddlerIndex) {
this.wiki.setText(this.tiddlerTitle,"",this.tiddlerIndex,this.inputDomNode.value);
@@ -89,15 +148,24 @@ RangeWidget.prototype.handleInputEvent = function(event) {
Compute the internal state of the widget
*/
RangeWidget.prototype.execute = function() {
// TODO remove the next 1 lines once IE is gone!
this.mouseUp = true; // Needed for IE10
// Get the parameters from the attributes
this.tiddlerTitle = this.getAttribute("tiddler",this.getVariable("currentTiddler"));
this.tiddlerField = this.getAttribute("field");
this.tiddlerField = this.getAttribute("field","text");
this.tiddlerIndex = this.getAttribute("index");
this.minValue = this.getAttribute("min");
this.maxValue = this.getAttribute("max");
this.increment = this.getAttribute("increment");
this.defaultValue = this.getAttribute("default");
this.defaultValue = this.getAttribute("default","");
this.elementClass = this.getAttribute("class","");
this.isDisabled = this.getAttribute("disabled","no");
// Actions since 5.1.23
// Next 2 only fire once!
this.actionsMouseDown = this.getAttribute("actionsStart","");
this.actionsMouseUp = this.getAttribute("actionsStop","");
// Input fires very often!
this.actionsInput = this.getAttribute("actions","");
// Make the child widgets
this.makeChildWidgets();
};
@@ -107,7 +175,7 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
*/
RangeWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes['min'] || changedAttributes['max'] || changedAttributes['increment'] || changedAttributes["default"] || changedAttributes["class"]) {
if($tw.utils.count(changedAttributes) > 0) {
this.refreshSelf();
return true;
} else {
@@ -115,7 +183,7 @@ RangeWidget.prototype.refresh = function(changedTiddlers) {
if(changedTiddlers[this.tiddlerTitle]) {
var value = this.getValue();
if(this.inputDomNode.value !== value) {
this.inputDomNode.value = value;
this.inputDomNode.value = value;
}
refreshed = true;
}

View File

@@ -35,9 +35,8 @@ RevealWidget.prototype.render = function(parent,nextSibling) {
tag = this.revealTag;
}
var domNode = this.document.createElement(tag);
var classes = this["class"].split(" ") || [];
classes.push("tc-reveal");
domNode.className = classes.join(" ");
this.domNode = domNode;
this.assignDomNodeClasses();
if(this.style) {
domNode.setAttribute("style",this.style);
}
@@ -70,6 +69,10 @@ RevealWidget.prototype.positionPopup = function(domNode) {
left = this.popup.left + this.popup.width;
top = this.popup.top + this.popup.height - domNode.offsetHeight;
break;
case "belowright":
left = this.popup.left + this.popup.width;
top = this.popup.top + this.popup.height;
break;
case "right":
left = this.popup.left + this.popup.width;
top = this.popup.top;
@@ -78,6 +81,10 @@ RevealWidget.prototype.positionPopup = function(domNode) {
left = this.popup.left + this.popup.width - domNode.offsetWidth;
top = this.popup.top + this.popup.height;
break;
case "aboveleft":
left = this.popup.left - domNode.offsetWidth;
top = this.popup.top - domNode.offsetHeight;
break;
default: // Below
left = this.popup.left;
top = this.popup.top + this.popup.height;
@@ -102,13 +109,14 @@ RevealWidget.prototype.execute = function() {
this.text = this.getAttribute("text");
this.position = this.getAttribute("position");
this.positionAllowNegative = this.getAttribute("positionAllowNegative") === "yes";
this["class"] = this.getAttribute("class","");
// class attribute handled in assignDomNodeClasses()
this.style = this.getAttribute("style","");
this["default"] = this.getAttribute("default","");
this.animate = this.getAttribute("animate","no");
this.retain = this.getAttribute("retain","no");
this.openAnimation = this.animate === "no" ? undefined : "open";
this.closeAnimation = this.animate === "no" ? undefined : "close";
this.updatePopupPosition = this.getAttribute("updatePopupPosition","no") === "yes";
// Compute the title of the state tiddler and read it
this.stateTiddlerTitle = this.state;
this.stateTitle = this.getAttribute("stateTitle");
@@ -194,6 +202,12 @@ RevealWidget.prototype.readPopupState = function(state) {
}
};
RevealWidget.prototype.assignDomNodeClasses = function() {
var classes = this.getAttribute("class","").split(" ");
classes.push("tc-reveal");
this.domNode.className = classes.join(" ");
};
/*
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/
@@ -212,7 +226,15 @@ RevealWidget.prototype.refresh = function(changedTiddlers) {
this.refreshSelf();
return true;
}
} else if(this.type === "popup" && this.updatePopupPosition && (changedTiddlers[this.state] || changedTiddlers[this.stateTitle])) {
this.positionPopup(this.domNode);
}
if(changedAttributes.style) {
this.domNode.style = this.getAttribute("style","");
}
if(changedAttributes["class"]) {
this.assignDomNodeClasses();
}
return this.refreshChildren(changedTiddlers);
}
};

View File

@@ -43,6 +43,7 @@ TranscludeWidget.prototype.execute = function() {
this.transcludeField = this.getAttribute("field");
this.transcludeIndex = this.getAttribute("index");
this.transcludeMode = this.getAttribute("mode");
this.recursionMarker = this.getAttribute("recursionMarker","yes");
// Parse the text reference
var parseAsInline = !this.parseTreeNode.isBlock;
if(this.transcludeMode === "inline") {
@@ -61,7 +62,9 @@ TranscludeWidget.prototype.execute = function() {
parseTreeNodes = parser ? parser.tree : this.parseTreeNode.children;
// Set context variables for recursion detection
var recursionMarker = this.makeRecursionMarker();
this.setVariable("transclusion",recursionMarker);
if(this.recursionMarker === "yes") {
this.setVariable("transclusion",recursionMarker);
}
// Check for recursion
if(parser) {
if(this.parentWidget && this.parentWidget.hasVariable("transclusion",recursionMarker)) {

View File

@@ -113,7 +113,8 @@ Widget.prototype.getVariableInfo = function(name,options) {
// Check for the variable defined in the parent widget (or an ancestor in the prototype chain)
if(parentWidget && name in parentWidget.variables) {
var variable = parentWidget.variables[name],
value = variable.value,
originalValue = variable.value,
value = originalValue,
params = this.resolveVariableParameters(variable.params,actualParams);
// Substitute any parameters specified in the definition
$tw.utils.each(params,function(param) {
@@ -125,7 +126,9 @@ Widget.prototype.getVariableInfo = function(name,options) {
}
return {
text: value,
params: params
params: params,
srcVariable: variable,
isCacheable: originalValue === value
};
}
// If the variable doesn't exist in the parent widget then look for a macro module
@@ -574,10 +577,10 @@ Widget.prototype.invokeActionString = function(actions,triggeringWidget,event,va
/*
Execute action tiddlers by tag
*/
Widget.prototype.executeStartupTiddlers = function(tag) {
Widget.prototype.invokeActionsByTag = function(tag,event,variables) {
var self = this;
$tw.utils.each(self.wiki.filterTiddlers("[all[shadows+tiddlers]tag[" + tag + "]!has[draft.of]]"),function(title) {
self.invokeActionString(self.wiki.getTiddlerText(title),self);
self.invokeActionString(self.wiki.getTiddlerText(title),self,event,variables);
});
};

View File

@@ -1004,6 +1004,7 @@ title: target tiddler title
options: as for wiki.makeWidget() plus:
options.field: optional field to transclude (defaults to "text")
options.mode: transclusion mode "inline" or "block"
options.recursionMarker : optional flag to set a recursion marker, defaults to "yes"
options.children: optional array of children for the transclude widget
options.importVariables: optional importvariables filter string for macros to be included
options.importPageMacros: optional boolean; if true, equivalent to passing "[[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]" to options.importVariables
@@ -1027,10 +1028,17 @@ exports.makeTranscludeWidget = function(title,options) {
parseTreeTransclude = {
type: "transclude",
attributes: {
recursionMarker: {
name: "recursionMarker",
type: "string",
value: options.recursionMarker || "yes"
},
tiddler: {
name: "tiddler",
type: "string",
value: title}},
value: title
}
},
isBlock: !options.parseAsInline};
if(options.importVariables || options.importPageMacros) {
if(options.importVariables) {
@@ -1362,7 +1370,7 @@ exports.readFileContent = function(file,type,isBinary,deserializer,callback) {
// Onload
reader.onload = function(event) {
var text = event.target.result,
tiddlerFields = {title: file.name || "Untitled", type: type};
tiddlerFields = {title: file.name || "Untitled"};
if(isBinary) {
var commaPos = text.indexOf(",");
if(commaPos !== -1) {

View File

@@ -0,0 +1,129 @@
title: $:/palettes/CupertinoDark
tags: $:/tags/Palette
name: Cupertino Dark
description: A macOS inspired dark palette
type: application/x-tiddler-dictionary
alert-background: #FF453A
alert-border: #FF453A
alert-highlight: #FFD60A
alert-muted-foreground: <<colour muted-foreground>>
background: #282828
blockquote-bar: <<colour page-background>>
button-foreground: <<colour background>>
code-background: <<colour pre-background>>
code-border: <<colour pre-border>>
code-foreground: rgba(255, 255, 255, 0.54)
dirty-indicator: #FF453A
download-background: <<colour primary>>
download-foreground: <<colour foreground>>
dragger-background: <<colour foreground>>
dragger-foreground: <<colour background>>
dropdown-background: <<colour tiddler-info-background>>
dropdown-border: <<colour dropdown-background>>
dropdown-tab-background-selected: #3F638B
dropdown-tab-background: #323232
dropzone-background: #30D158
external-link-background-hover: transparent
external-link-background-visited: transparent
external-link-background: transparent
external-link-foreground-hover:
external-link-foreground-visited: #BF5AF2
external-link-foreground: #32D74B
foreground: #FFFFFF
menubar-background: #464646
menubar-foreground: #ffffff
message-background: <<colour background>>
message-border: <<colour very-muted-foreground>>
message-foreground: rgba(255, 255, 255, 0.54)
modal-backdrop: <<colour page-background>>
modal-background: <<colour background>>
modal-border: <<colour very-muted-foreground>>
modal-footer-background: <<colour background>>
modal-footer-border: <<colour background>>
modal-header-border: <<colour very-muted-foreground>>
muted-foreground: #98989D
notification-background: <<colour dropdown-background>>
notification-border: <<colour dropdown-background>>
page-background: #323232
pre-background: #464646
pre-border: transparent
primary: #0A84FF
select-tag-background: <<colour background>>
select-tag-foreground: <<colour foreground>>
sidebar-button-foreground: <<colour background>>
sidebar-controls-foreground-hover: #FF9F0A
sidebar-controls-foreground: #8E8E93
sidebar-foreground-shadow: transparent
sidebar-foreground: rgba(255, 255, 255, 0.54)
sidebar-muted-foreground-hover: rgba(255, 255, 255, 0.54)
sidebar-muted-foreground: rgba(255, 255, 255, 0.38)
sidebar-tab-background-selected: #3F638B
sidebar-tab-background: <<colour background>>
sidebar-tab-border-selected: <<colour background>>
sidebar-tab-border: <<colour background>>
sidebar-tab-divider: <<colour background>>
sidebar-tab-foreground-selected: rgba(255, 255, 255, 0.87)
sidebar-tab-foreground: rgba(255, 255, 255, 0.54)
sidebar-tiddler-link-foreground-hover: rgba(255, 255, 255, 0.7)
sidebar-tiddler-link-foreground: rgba(255, 255, 255, 0.54)
site-title-foreground: #ffffff
static-alert-foreground: #B4B4B4
tab-background-selected: #3F638B
tab-background: <<colour page-background>>
tab-border-selected: <<colour page-background>>
tab-border: <<colour page-background>>
tab-divider: <<colour page-background>>
tab-foreground-selected: rgba(255, 255, 255, 0.87)
tab-foreground: rgba(255, 255, 255, 0.54)
table-border: #464646
table-footer-background: <<colour tiddler-editor-fields-odd>>
table-header-background: <<colour tiddler-editor-fields-even>>
tag-background: #48484A
tag-foreground: #323232
tiddler-background: <<colour background>>
tiddler-border: transparent
tiddler-controls-foreground-hover: <<colour sidebar-controls-foreground-hover>>
tiddler-controls-foreground-selected: <<colour sidebar-controls-foreground-hover>>
tiddler-controls-foreground: #48484A
tiddler-editor-background: transparent
tiddler-editor-border-image:
tiddler-editor-border: rgba(255, 255, 255, 0.08)
tiddler-editor-fields-even: rgba(255, 255, 255, 0.1)
tiddler-editor-fields-odd: rgba(255, 255, 255, 0.04)
tiddler-info-background: #1E1E1E
tiddler-info-border: #1E1E1E
tiddler-info-tab-background: #3F638B
tiddler-link-background: <<colour background>>
tiddler-link-foreground: <<colour primary>>
tiddler-subtitle-foreground: <<colour muted-foreground>>
tiddler-title-foreground: #FFFFFF
toolbar-new-button:
toolbar-options-button:
toolbar-save-button:
toolbar-info-button:
toolbar-edit-button:
toolbar-close-button:
toolbar-delete-button:
toolbar-cancel-button:
toolbar-done-button:
untagged-background: <<colour very-muted-foreground>>
very-muted-foreground: #464646
selection-background: #3F638B
selection-foreground: #ffffff
wikilist-background: <<colour page-background>>
wikilist-button-background: #3F638B
wikilist-button-foreground: <<colour foreground>>
wikilist-button-open: #32D74B
wikilist-button-open-hover: #32D74B
wikilist-button-reveal: #0A84FF
wikilist-button-reveal-hover: #0A84FF
wikilist-button-remove: #FF453A
wikilist-button-remove-hover: #FF453A
wikilist-droplink-dragover: #32D74B
wikilist-item: <<colour background>>
wikilist-toolbar-background: <<colour background>>
wikilist-title: <<colour foreground>>
wikilist-title-svg: <<colour foreground>>
wikilist-toolbar-foreground: <<colour foreground>>
wikilist-url: <<colour muted-foreground>>

View File

@@ -0,0 +1,138 @@
title: $:/palettes/DesertSand
tags: $:/tags/Palette
name: Desert Sand
description: A desert sand palette
type: application/x-tiddler-dictionary
alert-background: #ffe476
alert-border: #b99e2f
alert-highlight: #881122
alert-muted-foreground: #b99e2f
background: #E9E0C7
blockquote-bar: <<colour muted-foreground>>
button-foreground: <<colour foreground>>
code-background: #F3EDDF
code-border: #C3BAA1
code-foreground: #ab3250
diff-delete-background: #bd8b8b
diff-delete-foreground: <<colour foreground>>
diff-equal-background:
diff-equal-foreground: <<colour foreground>>
diff-insert-background: #91c093
diff-insert-foreground: <<colour foreground>>
diff-invisible-background:
diff-invisible-foreground: <<colour muted-foreground>>
dirty-indicator: #ad3434
download-background: #6ca16c
download-foreground: <<colour background>>
dragger-background: <<colour foreground>>
dragger-foreground: <<colour background>>
dropdown-background: <<colour background>>
dropdown-border: <<colour muted-foreground>>
dropdown-tab-background-selected: #E9E0C7
dropdown-tab-background: #BAB29C
dropzone-background: rgba(0,200,0,0.7)
external-link-background-hover: inherit
external-link-background-visited: inherit
external-link-background: inherit
external-link-foreground-hover: inherit
external-link-foreground-visited: #313163
external-link-foreground: #555592
foreground: #2D2A23
menubar-background: #CDC2A6
menubar-foreground: #5A5446
message-background: #ECE5CF
message-border: #D6CBAA
message-foreground: #5f6e7d
modal-backdrop: <<colour foreground>>
modal-background: <<colour background>>
modal-border: #8A8885
modal-footer-background: #CDC2A6
modal-footer-border: #9D998E
modal-header-border: #9D998E
muted-foreground: #9D998E
notification-background: #F0E9D7
notification-border: #939189
page-background: #e0d3af
pre-background: #D6CBAA
pre-border: #CDC2A6
primary: #5B6F55
selection-background: #9D947B
selection-foreground: <<colour foreground>>
select-tag-background: #F0E9D7
select-tag-foreground: #2D2A23
sidebar-button-foreground: <<colour foreground>>
sidebar-controls-foreground-hover: #2D2A23
sidebar-controls-foreground: #867F69
sidebar-foreground-shadow: transparent
sidebar-foreground: #867F69
sidebar-muted-foreground-hover: #706A58
sidebar-muted-foreground: #B3A98C
sidebar-tab-background-selected: #e0d3af
sidebar-tab-background: #A6A193
sidebar-tab-border-selected: #C3BAA1
sidebar-tab-border: #C3BAA1
sidebar-tab-divider: #CDC2A6
sidebar-tab-foreground-selected:
sidebar-tab-foreground: #2D2A23
sidebar-tiddler-link-foreground-hover: #433F35
sidebar-tiddler-link-foreground: #706A58
site-title-foreground: <<colour tiddler-title-foreground>>
static-alert-foreground: #A6A193
tab-background-selected: #E9E0C7
tab-background: #A6A193
tab-border-selected: #C3BAA1
tab-border: #C3BAA1
tab-divider: #CDC2A6
tab-foreground-selected: <<colour tab-foreground>>
tab-foreground: #2D2A23
table-border: #9D998E
table-footer-background: #8A8885
table-header-background: #B0AA98
tag-background: #706A58
tag-foreground: #E3D7B7
tiddler-background: <<colour background>>
tiddler-border: <<colour background>>
tiddler-controls-foreground-hover: #9D947B
tiddler-controls-foreground-selected: #706A58
tiddler-controls-foreground: #C3BAA1
tiddler-editor-background: #E9E0C7
tiddler-editor-border-image: #A6A193
tiddler-editor-border: #A6A193
tiddler-editor-fields-even: #D6CBAA
tiddler-editor-fields-odd: #C3BAA1
tiddler-info-background: #E3D7B7
tiddler-info-border: #BAB29C
tiddler-info-tab-background: #E9E0C7
tiddler-link-background: <<colour background>>
tiddler-link-foreground: <<colour primary>>
tiddler-subtitle-foreground: #867F69
tiddler-title-foreground: #374464
toolbar-new-button:
toolbar-options-button:
toolbar-save-button:
toolbar-info-button:
toolbar-edit-button:
toolbar-close-button:
toolbar-delete-button:
toolbar-cancel-button:
toolbar-done-button:
untagged-background: #8A8885
very-muted-foreground: #CDC2A6
wikilist-background: <<colour page-background>>
wikilist-item: #CDC2A6
wikilist-info: #161512
wikilist-title: #433F35
wikilist-title-svg: <<colour wikilist-title>>
wikilist-url: #706A58
wikilist-button-open: #7db66a
wikilist-button-open-hover: #56a556
wikilist-button-reveal: #5a6c9e
wikilist-button-reveal-hover: #454591
wikilist-button-remove: #bc5972
wikilist-button-remove-hover: #814040
wikilist-toolbar-background: #CDC2A6
wikilist-toolbar-foreground: #2D2A23
wikilist-droplink-dragover: rgba(255,192,192,0.5)
wikilist-button-background: #A6A193
wikilist-button-foreground: #161512

View File

@@ -11,9 +11,7 @@ alert-highlight: #d79921
alert-muted-foreground: #504945
background: #3c3836
blockquote-bar: <<colour muted-foreground>>
button-background: #504945
button-foreground: #fbf1c7
button-border: transparent
button-foreground: <<colour page-background>>
code-background: #504945
code-border: #504945
code-foreground: #fb4934
@@ -62,7 +60,9 @@ pre-border: #504945
primary: #d79921
select-tag-background: #665c54
select-tag-foreground: <<colour foreground>>
sidebar-button-foreground: <<colour foreground>>
selection-background: #458588
selection-foreground: <<colour foreground>>
sidebar-button-foreground: <<colour page-background>>
sidebar-controls-foreground-hover: #7c6f64
sidebar-controls-foreground: #504945
sidebar-foreground-shadow: transparent
@@ -97,7 +97,7 @@ tiddler-border: <<colour background>>
tiddler-controls-foreground-hover: #7c6f64
tiddler-controls-foreground-selected: <<colour primary>>
tiddler-controls-foreground: #665c54
tiddler-editor-background: #282828
tiddler-editor-background: #32302f
tiddler-editor-border-image: #282828
tiddler-editor-border: #282828
tiddler-editor-fields-even: #504945
@@ -121,7 +121,7 @@ toolbar-done-button:
untagged-background: #504945
very-muted-foreground: #bdae93
wikilist-background: <<colour page-background>>
wikilist-button-background: <<colour button-background>>
wikilist-button-background: #acacac
wikilist-button-foreground: <<colour button-foreground>>
wikilist-item: <<colour background>>
wikilist-toolbar-background: <<colour background>>

View File

@@ -11,9 +11,7 @@ alert-highlight: #B48EAD
alert-muted-foreground: #4C566A
background: #3b4252
blockquote-bar: <<colour muted-foreground>>
button-background: #4C566A
button-foreground: #D8DEE9
button-border: transparent
button-foreground: <<colour page-background>>
code-background: #2E3440
code-border: #2E3440
code-foreground: #BF616A
@@ -62,7 +60,9 @@ pre-border: #2E3440
primary: #5E81AC
select-tag-background: #3b4252
select-tag-foreground: <<colour foreground>>
sidebar-button-foreground: <<colour foreground>>
selection-background: #5E81AC
selection-foreground: <<colour foreground>>
sidebar-button-foreground: <<colour page-background>>
sidebar-controls-foreground-hover: #D8DEE9
sidebar-controls-foreground: #4C566A
sidebar-foreground-shadow: transparent
@@ -99,7 +99,7 @@ tiddler-controls-foreground-selected: #EBCB8B
tiddler-controls-foreground: #4C566A
tiddler-editor-background: #2e3440
tiddler-editor-border-image: #2e3440
tiddler-editor-border: #2e3440
tiddler-editor-border: #3b4252
tiddler-editor-fields-even: #2e3440
tiddler-editor-fields-odd: #2e3440
tiddler-info-background: #2e3440
@@ -120,3 +120,14 @@ toolbar-cancel-button:
toolbar-done-button:
untagged-background: #2d3038
very-muted-foreground: #2d3038
wikilist-background: <<colour page-background>>
wikilist-toolbar-background: <<colour background>>
wikilist-item: <<colour background>>
wikilist-title: <<colour foreground>>
wikilist-info: <<colour muted-foreground>>
wikilist-button-open: #A3BE8C
wikilist-button-open-hover: #A3BE8C
wikilist-button-reveal: #81A1C1
wikilist-button-reveal-hover: #81A1C1
wikilist-button-remove: #B48EAD
wikilist-button-remove-hover: #B48EAD

View File

@@ -26,7 +26,7 @@ extension: .html
</head>
<body class="tc-body">
{{$:/StaticBanner||$:/core/templates/html-tiddler}}
<section class="tc-story-river">
<section class="tc-story-river tc-static-story-river">
{{$:/core/templates/exporters/StaticRiver/Content||$:/core/templates/html-tiddler}}
</section>
</body>

View File

@@ -2,6 +2,7 @@ title: $:/core/templates/exporters/TidFile
tags: $:/tags/Exporter
description: {{$:/language/Exporters/TidFile}}
extension: .tid
condition: [<count>compare:lte[1]]
\define renderContent()
{{{ $(exportFilter)$ +[limit[1]] ||$:/core/templates/tid-tiddler}}}

View File

@@ -22,9 +22,9 @@ title: $:/core/templates/static.tiddler.html
</head>
<body class="tc-body">
`{{$:/StaticBanner||$:/core/templates/html-tiddler}}`
<section class="tc-story-river">
<section class="tc-story-river tc-static-story-river">
`<$view tiddler="$:/core/ui/ViewTemplate" format="htmlwikified"/>`
</section>
</body>
</html>
`
`

View File

@@ -5,6 +5,7 @@ description: create a new image tiddler
\define get-type()
image/$(imageType)$
\end
<$vars imageType={{$:/config/NewImageType}}>
<$action-sendmessage $message="tm-new-tiddler" type=<<get-type>> tags={{$:/config/NewTiddler/Tags}}/>
\define get-tags() $(textFieldTags)$ $(tagsFieldTags)$
<$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>

View File

@@ -2,13 +2,14 @@ title: $:/core/ui/Actions/new-journal
tags: $:/tags/Actions
description: create a new journal tiddler
<$vars journalTitleTemplate={{$:/config/NewJournal/Title}} journalTags={{$:/config/NewJournal/Tags}} journalText={{$:/config/NewJournal/Text}}>
\define get-tags() $(textFieldTags)$ $(tagsFieldTags)$
<$vars journalTitleTemplate={{$:/config/NewJournal/Title}} textFieldTags={{$:/config/NewJournal/Tags}} tagsFieldTags={{$:/config/NewJournal/Tags!!tags}} journalText={{$:/config/NewJournal/Text}}>
<$wikify name="journalTitle" text="""<$macrocall $name="now" format=<<journalTitleTemplate>>/>""">
<$reveal type="nomatch" state=<<journalTitle>> text="">
<$action-sendmessage $message="tm-new-tiddler" title=<<journalTitle>> tags=<<journalTags>> text={{{ [<journalTitle>get[]] }}}/>
<$action-sendmessage $message="tm-new-tiddler" title=<<journalTitle>> tags=<<get-tags>> text={{{ [<journalTitle>get[]] }}}/>
</$reveal>
<$reveal type="match" state=<<journalTitle>> text="">
<$action-sendmessage $message="tm-new-tiddler" title=<<journalTitle>> tags=<<journalTags>> text=<<journalText>>/>
<$action-sendmessage $message="tm-new-tiddler" title=<<journalTitle>> tags=<<get-tags>> text=<<journalText>>/>
</$reveal>
</$wikify>
</$vars>

View File

@@ -2,4 +2,7 @@ title: $:/core/ui/Actions/new-tiddler
tags: $:/tags/Actions
description: create a new empty tiddler
<$action-sendmessage $message="tm-new-tiddler" tags={{$:/config/NewTiddler/Tags}}/>
\define get-tags() $(textFieldTags)$ $(tagsFieldTags)$
<$vars textFieldTags={{$:/config/NewTiddler/Tags}} tagsFieldTags={{$:/config/NewTiddler/Tags!!tags}}>
<$action-sendmessage $message="tm-new-tiddler" tags=<<get-tags>>/>
</$vars>

View File

@@ -3,5 +3,5 @@ icon: $:/core/images/advanced-search-button
color: #bbb
<div class="tc-advanced-search">
<$macrocall $name="tabs" tabsList="[all[shadows+tiddlers]tag[$:/tags/AdvancedSearch]!has[draft.of]]" default="$:/core/ui/AdvancedSearch/System" actions="""<$action-setfield $tiddler="$:/state/advancedsearch/currentTab" text=<<currentTab>>/>""" explicitState="$:/state/tab/advanced-search-results"/>
<$macrocall $name="tabs" tabsList="[all[shadows+tiddlers]tag[$:/tags/AdvancedSearch]!has[draft.of]]" default="$:/core/ui/AdvancedSearch/System" actions="""<$action-setfield $tiddler="$:/state/advancedsearch/currentTab" text=<<currentTab>>/>""" explicitState="$:/state/tab--1498284803"/>
</div>

View File

@@ -3,13 +3,13 @@ tags: $:/tags/AdvancedSearch
caption: {{$:/language/Search/Filter/Caption}}
\define lingo-base() $:/language/Search/
\define set-next-input-tab(beforeafter:"after") <$macrocall $name="change-input-tab" stateTitle="$:/state/tab/advanced-search-results" tag="$:/tags/AdvancedSearch" beforeafter="$beforeafter$" defaultState="$:/core/ui/AdvancedSearch/System" actions="""<$action-setfield $tiddler="$:/state/advancedsearch/currentTab" text=<<nextTab>>/>"""/>
\define set-next-input-tab(beforeafter:"after") <$macrocall $name="change-input-tab" stateTitle="$:/state/tab--1498284803" tag="$:/tags/AdvancedSearch" beforeafter="$beforeafter$" defaultState="$:/core/ui/AdvancedSearch/System" actions="""<$action-setfield $tiddler="$:/state/advancedsearch/currentTab" text=<<nextTab>>/>"""/>
\define cancel-search-actions() <$list filter="[{$:/temp/advancedsearch/input}!match{$:/temp/advancedsearch}]" emptyMessage="""<$action-deletetiddler $filter="[[$:/temp/advancedsearch]] [[$:/temp/advancedsearch/input]] [[$:/temp/advancedsearch/selected-item]]" />"""><$action-setfield $tiddler="$:/temp/advancedsearch/input" text={{$:/temp/advancedsearch}}/><$action-setfield $tiddler="$:/temp/advancedsearch/refresh" text="yes"/></$list>
\define input-accept-actions() <$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/>
\define input-accept-actions() <$list filter="[{$:/config/Search/NavigateOnEnter/enable}match[yes]]" emptyMessage="""<$list filter="[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]"><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>"""><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>
\define input-accept-variant-actions() <$list filter="[<__tiddler__>get[text]minlength[1]]"><$action-sendmessage $message="tm-edit-tiddler" $param={{{ [<__tiddler__>get[text]] }}}/></$list>
\define input-accept-variant-actions() <$list filter="[{$:/config/Search/NavigateOnEnter/enable}match[yes]]" emptyMessage="""<$list filter="[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]"><$list filter="[<__tiddler__>get[text]minlength[1]]"><$action-sendmessage $message="tm-edit-tiddler" $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>"""><$list filter="[<__tiddler__>get[text]minlength[1]]"><$action-sendmessage $message="tm-edit-tiddler" $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>
<<lingo Filter/Hint>>

View File

@@ -5,13 +5,13 @@ first-search-filter: [all[shadows]search<userInput>sort[title]limit[250]] -[[$:/
\define lingo-base() $:/language/Search/
\define set-next-input-tab(beforeafter:"after") <$macrocall $name="change-input-tab" stateTitle="$:/state/tab/advanced-search-results" tag="$:/tags/AdvancedSearch" beforeafter="$beforeafter$" defaultState="$:/core/ui/AdvancedSearch/System" actions="""<$action-setfield $tiddler="$:/state/advancedsearch/currentTab" text=<<nextTab>>/>"""/>
\define set-next-input-tab(beforeafter:"after") <$macrocall $name="change-input-tab" stateTitle="$:/state/tab--1498284803" tag="$:/tags/AdvancedSearch" beforeafter="$beforeafter$" defaultState="$:/core/ui/AdvancedSearch/System" actions="""<$action-setfield $tiddler="$:/state/advancedsearch/currentTab" text=<<nextTab>>/>"""/>
\define cancel-search-actions() <$list filter="[{$:/temp/advancedsearch}!match{$:/temp/advancedsearch/input}]" emptyMessage="""<$action-deletetiddler $filter="[[$:/temp/advancedsearch]] [[$:/temp/advancedsearch/input]] [[$:/temp/advancedsearch/selected-item]]" />"""><$action-setfield $tiddler="$:/temp/advancedsearch/input" text={{$:/temp/advancedsearch}}/><$action-setfield $tiddler="$:/temp/advancedsearch/refresh" text="yes"/></$list><$action-sendmessage $message="tm-focus-selector" $param=""".tc-advanced-search input"""/>
\define input-accept-actions() <$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/>
\define input-accept-actions() <$list filter="[{$:/config/Search/NavigateOnEnter/enable}match[yes]]" emptyMessage="""<$list filter="[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]"><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>"""><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>
\define input-accept-variant-actions() <$list filter="[<__tiddler__>get[text]minlength[1]]"><$action-sendmessage $message="tm-edit-tiddler" $param={{{ [<__tiddler__>get[text]] }}}/></$list>
\define input-accept-variant-actions() <$list filter="[{$:/config/Search/NavigateOnEnter/enable}match[yes]]" emptyMessage="""<$list filter="[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]"><$list filter="[<__tiddler__>get[text]minlength[1]]"><$action-sendmessage $message="tm-edit-tiddler" $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>"""><$list filter="[<__tiddler__>get[text]minlength[1]]"><$action-sendmessage $message="tm-edit-tiddler" $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>
<<lingo Shadows/Hint>>

View File

@@ -3,15 +3,15 @@ tags: $:/tags/AdvancedSearch
caption: {{$:/language/Search/Standard/Caption}}
\define lingo-base() $:/language/Search/
\define set-next-input-tab(beforeafter:"after") <$macrocall $name="change-input-tab" stateTitle="$:/state/tab/advanced-search-results" tag="$:/tags/AdvancedSearch" beforeafter="$beforeafter$" defaultState="$:/core/ui/AdvancedSearch/System" actions="""<$action-setfield $tiddler="$:/state/advancedsearch/currentTab" text=<<nextTab>>/>"""/>
\define set-next-input-tab(beforeafter:"after") <$macrocall $name="change-input-tab" stateTitle="$:/state/tab--1498284803" tag="$:/tags/AdvancedSearch" beforeafter="$beforeafter$" defaultState="$:/core/ui/AdvancedSearch/System" actions="""<$action-setfield $tiddler="$:/state/advancedsearch/currentTab" text=<<nextTab>>/>"""/>
\define next-search-tab(beforeafter:"after") <$macrocall $name="change-input-tab" stateTitle="$:/state/tab/search-results/advancedsearch" tag="$:/tags/SearchResults" beforeafter="$beforeafter$" defaultState={{$:/config/SearchResults/Default}} actions="""<$action-setfield $tiddler="$:/state/advancedsearch/standard/currentTab" text=<<nextTab>>/>"""/>
\define cancel-search-actions() <$list filter="[{$:/temp/advancedsearch}!match{$:/temp/advancedsearch/input}]" emptyMessage="""<$action-deletetiddler $filter="[[$:/temp/advancedsearch]] [[$:/temp/advancedsearch/input]] [[$:/temp/advancedsearch/selected-item]]" />"""><$action-setfield $tiddler="$:/temp/advancedsearch/input" text={{$:/temp/advancedsearch}}/><$action-setfield $tiddler="$:/temp/advancedsearch/refresh" text="yes"/></$list><$action-sendmessage $message="tm-focus-selector" $param=""".tc-advanced-search input"""/>
\define input-accept-actions() <$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/>
\define input-accept-actions() <$list filter="[{$:/config/Search/NavigateOnEnter/enable}match[yes]]" emptyMessage="""<$list filter="[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]"><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>"""><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>
\define input-accept-variant-actions() <$list filter="[<__tiddler__>get[text]minlength[1]]"><$action-sendmessage $message="tm-edit-tiddler" $param={{{ [<__tiddler__>get[text]] }}}/></$list>
\define input-accept-variant-actions() <$list filter="[{$:/config/Search/NavigateOnEnter/enable}match[yes]]" emptyMessage="""<$list filter="[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]"><$list filter="[<__tiddler__>get[text]minlength[1]]"><$action-sendmessage $message="tm-edit-tiddler" $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>"""><$list filter="[<__tiddler__>get[text]minlength[1]]"><$action-sendmessage $message="tm-edit-tiddler" $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>
<<lingo Standard/Hint>>

View File

@@ -4,13 +4,13 @@ caption: {{$:/language/Search/System/Caption}}
first-search-filter: [is[system]search<userInput>sort[title]limit[250]] -[[$:/temp/advancedsearch]] -[[$:/temp/advancedsearch/input]] -[[$:/temp/advancedsearch/selected-item]]
\define lingo-base() $:/language/Search/
\define set-next-input-tab(beforeafter:"after",stateTitle,tag,defaultState,currentTabTiddler) <$macrocall $name="change-input-tab" stateTitle="$:/state/tab/advanced-search-results" tag="$:/tags/AdvancedSearch" beforeafter="$beforeafter$" defaultState="$:/core/ui/AdvancedSearch/System" actions="""<$action-setfield $tiddler="$:/state/advancedsearch/currentTab" text=<<nextTab>>/>"""/>
\define set-next-input-tab(beforeafter:"after",stateTitle,tag,defaultState,currentTabTiddler) <$macrocall $name="change-input-tab" stateTitle="$:/state/tab--1498284803" tag="$:/tags/AdvancedSearch" beforeafter="$beforeafter$" defaultState="$:/core/ui/AdvancedSearch/System" actions="""<$action-setfield $tiddler="$:/state/advancedsearch/currentTab" text=<<nextTab>>/>"""/>
\define cancel-search-actions() <$list filter="[{$:/temp/advancedsearch}!match{$:/temp/advancedsearch/input}]" emptyMessage="""<$action-deletetiddler $filter="[[$:/temp/advancedsearch]] [[$:/temp/advancedsearch/input]] [[$:/temp/advancedsearch/selected-item]]" />"""><$action-setfield $tiddler="$:/temp/advancedsearch/input" text={{$:/temp/advancedsearch}}/><$action-setfield $tiddler="$:/temp/advancedsearch/refresh" text="yes"/></$list><$action-sendmessage $message="tm-focus-selector" $param=""".tc-advanced-search input"""/>
\define input-accept-actions() <$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/>
\define input-accept-actions() <$list filter="[{$:/config/Search/NavigateOnEnter/enable}match[yes]]" emptyMessage="""<$list filter="[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]"><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>"""><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>
\define input-accept-variant-actions() <$list filter="[<__tiddler__>get[text]minlength[1]]"><$action-sendmessage $message="tm-edit-tiddler" $param={{{ [<__tiddler__>get[text]] }}}/></$list>
\define input-accept-variant-actions() <$list filter="[{$:/config/Search/NavigateOnEnter/enable}match[yes]]" emptyMessage="""<$list filter="[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]"><$list filter="[<__tiddler__>get[text]minlength[1]]"><$action-sendmessage $message="tm-edit-tiddler" $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>"""><$list filter="[<__tiddler__>get[text]minlength[1]]"><$action-sendmessage $message="tm-edit-tiddler" $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>
<<lingo System/Hint>>

View File

@@ -3,5 +3,5 @@ icon: $:/core/images/options-button
color: #bbb
<div class="tc-control-panel">
<<tabs "[all[shadows+tiddlers]tag[$:/tags/ControlPanel]!has[draft.of]]" "$:/core/ui/ControlPanel/Info">>
<$macrocall $name="tabs" tabsList="[all[shadows+tiddlers]tag[$:/tags/ControlPanel]!has[draft.of]]" default="$:/core/ui/ControlPanel/Info" explicitState="$:/state/tab-1749438307"/>
</div>

View File

@@ -5,5 +5,5 @@ caption: {{$:/language/ControlPanel/Advanced/Caption}}
{{$:/language/ControlPanel/Advanced/Hint}}
<div class="tc-control-panel">
<<tabs "[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Advanced]!has[draft.of]]" "$:/core/ui/ControlPanel/TiddlerFields">>
<$macrocall $name="tabs" tabsList="[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Advanced]!has[draft.of]]" default="$:/core/ui/ControlPanel/TiddlerFields" explicitState="$:/state/tab--959111941"/>
</div>

View File

@@ -5,5 +5,5 @@ caption: {{$:/language/ControlPanel/Appearance/Caption}}
{{$:/language/ControlPanel/Appearance/Hint}}
<div class="tc-control-panel">
<<tabs "[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Appearance]!has[draft.of]]" "$:/core/ui/ControlPanel/Theme">>
<$macrocall $name="tabs" tabsList="[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Appearance]!has[draft.of]]" default="$:/core/ui/ControlPanel/Theme" explicitState="$:/state/tab--1963855381"/>
</div>

View File

@@ -7,8 +7,11 @@ caption: {{$:/language/ControlPanel/Basics/Caption}}
\define show-filter-count(filter)
<$button class="tc-btn-invisible">
<$action-setfield $tiddler="$:/temp/advancedsearch" $value="""$filter$"""/>
<$action-setfield $tiddler="$:/temp/advancedsearch/input" $value="""$filter$"""/>
<$action-setfield $tiddler="$:/temp/advancedsearch/refresh" text="yes"/>
<$action-setfield $tiddler="$:/state/tab--1498284803" $value="$:/core/ui/AdvancedSearch/Filter"/>
<$action-navigate $to="$:/AdvancedSearch"/>
<$action-sendmessage $message="tm-focus-selector" $param=".tc-advanced-search input"/>
''<$count filter="""$filter$"""/>''
{{$:/core/images/advanced-search-button}}
</$button>
@@ -23,8 +26,8 @@ caption: {{$:/language/ControlPanel/Basics/Caption}}
|<$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/NewTiddler/Tags"><<lingo NewTiddler/Tags/Prompt>></$link> |<$edit-text tiddler="$:/config/NewTiddler/Tags" tag="input" default=""/> |
|<$link to="$:/config/NewJournal/Tags"><<lingo NewJournal/Tags/Prompt>></$link> |<$edit-text tiddler="$:/config/NewJournal/Tags" tag="input" 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}} |
|<<lingo Language/Prompt>> |{{$:/snippets/minilanguageswitcher}} |
|<<lingo Tiddlers/Prompt>> |<<show-filter-count "[!is[system]sort[title]]">> |

View File

@@ -5,5 +5,5 @@ caption: {{$:/language/ControlPanel/Info/Caption}}
{{$:/language/ControlPanel/Info/Hint}}
<div class="tc-control-panel">
<<tabs "[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Info]!has[draft.of]]" "$:/core/ui/ControlPanel/Basics">>
<$macrocall $name="tabs" tabsList="[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Info]!has[draft.of]]" default="$:/core/ui/ControlPanel/Basics" explicitState="$:/state/tab--2112689675"/>
</div>

View File

@@ -5,7 +5,7 @@ subtitle: {{$:/core/images/download-button}} {{$:/language/ControlPanel/Plugins/
<$action-sendmessage $message="tm-load-plugin-from-library" url={{!!url}} title={{$(assetInfo)$!!original-title}}/>
<$set name="url" value={{!!url}}>
<$set name="currentTiddler" value=<<assetInfo>>>
<$list filter="[enlist{!!dependents}] [{!!parent-plugin}] +[sort[title]]" variable="dependency">
<$list filter="[enlist{!!dependents}] [{!!parent-plugin}] +[sort[name]]" variable="dependency">
<$action-sendmessage $message="tm-load-plugin-from-library" url=<<url>> title=<<dependency>>/>
</$list>
</$set>
@@ -84,7 +84,7 @@ $:/state/add-plugin-info/$(connectionTiddler)$/$(assetInfo)$
<$list filter="[enlist{!!dependents}] [<currentTiddler>get[parent-plugin]] +[limit[1]]" variable="ignore">
<div>
{{$:/language/ControlPanel/Plugins/AlsoRequires}}
<$list filter="[enlist{!!dependents}] [{!!parent-plugin}] +[sort[title]]" variable="dependency">
<$list filter="[enlist{!!dependents}] [{!!parent-plugin}] +[sort[name]]" variable="dependency">
<$text text=<<dependency>>/>
</$list>
</div>
@@ -97,7 +97,7 @@ $:/state/add-plugin-info/$(connectionTiddler)$/$(assetInfo)$
</div>
<$list filter="[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[$type$]has[parent-plugin]parent-plugin<original-title>limit[1]]" variable="ignore">
<div class="tc-plugin-info-sub-plugins">
<$list filter="[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[$type$]has[parent-plugin]parent-plugin<original-title>sort[title]]" variable="assetInfo">
<$list filter="[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[$type$]has[parent-plugin]parent-plugin<original-title>sort[name]]" variable="assetInfo">
<<display-plugin-info "$type$">>
</$list>
</div>
@@ -135,7 +135,7 @@ $:/state/add-plugin-info/$(connectionTiddler)$/$(assetInfo)$
</$button>
</$reveal>
<div class="tc-plugin-library-listing">
<$list filter="[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[$type$]search:author,description,original-title,readme,title{$:/temp/RemoteAssetSearch/$(currentTiddler)$}sort[title]]" variable="assetInfo">
<$list filter="[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[$type$]search:author,description,original-title,readme,title{$:/temp/RemoteAssetSearch/$(currentTiddler)$}sort[name]]" variable="assetInfo">
<$list filter="[[$:/temp/RemoteAssetSearch/$(currentTiddler)$]has[text]] ~[<assetInfo>!has[parent-plugin]]" variable="ignore"><!-- Hide sub-plugins if we're not searching -->
<<display-plugin-info "$type$">>
</$list>

View File

@@ -7,7 +7,7 @@ caption: {{$:/language/ControlPanel/Plugins/Caption}}
\define plugin-table(type)
<$set name="plugin-type" value="""$type$""">
<$set name="qualified-state" value=<<qualify "$:/state/plugin-info">>>
<$list filter="[!has[draft.of]plugin-type[$type$]sort[title]]" emptyMessage=<<lingo "Empty/Hint">> template="$:/core/ui/Components/plugin-info"/>
<$list filter="[!has[draft.of]plugin-type[$type$]sort[name]]" emptyMessage=<<lingo "Empty/Hint">> template="$:/core/ui/Components/plugin-info"/>
</$set>
</$set>
\end
@@ -16,4 +16,4 @@ caption: {{$:/language/ControlPanel/Plugins/Caption}}
<<lingo Installed/Hint>>
<<tabs "[[$:/core/ui/ControlPanel/Plugins/Installed/Plugins]] [[$:/core/ui/ControlPanel/Plugins/Installed/Themes]] [[$:/core/ui/ControlPanel/Plugins/Installed/Languages]]" "$:/core/ui/ControlPanel/Plugins/Installed/Plugins">>
<$macrocall $name="tabs" tabsList="[[$:/core/ui/ControlPanel/Plugins/Installed/Plugins]] [[$:/core/ui/ControlPanel/Plugins/Installed/Themes]] [[$:/core/ui/ControlPanel/Plugins/Installed/Languages]]" default="$:/core/ui/ControlPanel/Plugins/Installed/Plugins" explicitState="$:/state/tab--86143343"/>

View File

@@ -5,5 +5,5 @@ caption: {{$:/language/ControlPanel/Saving/Caption}}
{{$:/language/ControlPanel/Saving/Hint}}
<div class="tc-control-panel">
<<tabs "[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Saving]!has[draft.of]]" "$:/core/ui/ControlPanel/Saving/General">>
<$macrocall $name="tabs" tabsList="[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Saving]!has[draft.of]]" default="$:/core/ui/ControlPanel/Saving/General" explicitState="$:/state/tab-2065006209"/>
</div>

View File

@@ -20,6 +20,12 @@ http://$(userName)$.tiddlyspot.com/$path$/
</$reveal>
\end
<div class="tc-message-box">
<<lingo ReadOnly>>
</div>
<<lingo Description>>
|<<lingo UserName>> |<$edit-text tiddler="$:/UploadName" default="" tag="input"/> |
@@ -34,4 +40,4 @@ http://$(userName)$.tiddlyspot.com/$path$/
|<<lingo UploadDir>> |<$edit-text tiddler="$:/UploadDir" default="." tag="input"/> |
|<<lingo BackupDir>> |<$edit-text tiddler="$:/UploadBackupDir" default="." tag="input"/> |
<<lingo TiddlySpot/Hint>>
<<lingo TiddlySpot/Hint>>

View File

@@ -5,5 +5,5 @@ caption: {{$:/language/ControlPanel/Toolbars/Caption}}
{{$:/language/ControlPanel/Toolbars/Hint}}
<div class="tc-control-panel">
<<tabs "[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Toolbars]!has[draft.of]]" "$:/core/ui/ControlPanel/Toolbars/ViewToolbar" "$:/state/tabs/controlpanel/toolbars" "tc-vertical">>
<$macrocall $name="tabs" tabsList="[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Toolbars]!has[draft.of]]" default="$:/core/ui/ControlPanel/Toolbars/ViewToolbar" class="tc-vertical" explicitState="$:/state/tabs/controlpanel/toolbars-1345989671"/>
</div>

View File

@@ -1,17 +1,20 @@
title: $:/core/ui/EditTemplate
\define delete-edittemplate-state-tiddlers() <$action-deletetiddler $filter="[<newFieldNameTiddler>] [<newFieldValueTiddler>] [<newFieldNameInputTiddler>] [<newFieldNameSelectionTiddler>] [<newTagNameTiddler>] [<newTagNameInputTiddler>] [<newTagNameSelectionTiddler>] [<typeInputTiddler>] [<typeSelectionTiddler>]"/>
\define save-tiddler-actions()
<$action-sendmessage $message="tm-add-tag" $param={{{ [<newTagNameTiddler>get[text]] }}}/>
<$action-deletetiddler $tiddler=<<newTagNameTiddler>>/>
<$action-sendmessage $message="tm-add-field" $name={{{ [<newFieldNameTiddler>get[text]] }}} $value={{{ [<newFieldValueTiddler>get[text]] }}}/>
<$action-deletetiddler $tiddler=<<newFieldNameTiddler>>/>
<$action-deletetiddler $tiddler=<<newFieldValueTiddler>>/>
<<delete-edittemplate-state-tiddlers>>
<$action-sendmessage $message="tm-save-tiddler"/>
\end
\define cancel-delete-tiddler-actions(message)
<<delete-edittemplate-state-tiddlers>>
<$action-sendmessage $message="tm-$message$-tiddler"/>
\end
<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[ ]] }}}>
<$fieldmangler>
<$vars storyTiddler=<<currentTiddler>> newTagNameTiddler=<<qualify "$:/temp/NewTagName">> newFieldNameTiddler=<<qualify "$:/temp/NewFieldName">> newFieldValueTiddler=<<qualify "$:/temp/NewFieldValue">>>
<$keyboard key="((cancel-edit-tiddler))" message="tm-cancel-tiddler">
<$vars storyTiddler=<<currentTiddler>> newTagNameTiddler=<<qualify "$:/temp/NewTagName">> newFieldNameTiddler=<<qualify "$:/temp/NewFieldName">> newFieldValueTiddler=<<qualify "$:/temp/NewFieldValue">> newFieldNameInputTiddler=<<qualify "$:/temp/NewFieldName/input">> newFieldNameSelectionTiddler=<<qualify "$:/temp/NewFieldName/selected-item">> newTagNameInputTiddler=<<qualify "$:/temp/NewTagName/input">> newTagNameSelectionTiddler=<<qualify "$:/temp/NewTagName/selected-item">> typeInputTiddler=<<qualify "$:/temp/Type/input">> typeSelectionTiddler=<<qualify "$:/temp/Type/selected-item">>>
<$keyboard key="((cancel-edit-tiddler))" actions=<<cancel-delete-tiddler-actions "cancel">>>
<$keyboard key="((save-tiddler))" actions=<<save-tiddler-actions>>>
<$list filter="[all[shadows+tiddlers]tag[$:/tags/EditTemplate]!has[draft.of]]" variable="listItem">
<$set name="tv-config-toolbar-class" filter="[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]">

View File

@@ -16,15 +16,14 @@ $:/config/EditTemplateFields/Visibility/$(currentField)$
\define new-field-actions()
<$action-sendmessage $message="tm-add-field" $name={{{ [<newFieldNameTiddler>get[text]] }}} $value={{{ [<newFieldValueTiddler>get[text]] }}}/>
<$action-deletetiddler $tiddler=<<newFieldNameTiddler>>/>
<$action-deletetiddler $tiddler=<<newFieldValueTiddler>>/>
<$action-deletetiddler $filter="[<newFieldNameTiddler>] [<newFieldValueTiddler>] [<storeTitle>] [<searchListState>]"/>
<$action-sendmessage $message="tm-focus-selector" $param=<<current-tiddler-new-field-selector>>/>
\end
\define delete-state-tiddlers() <$action-deletetiddler $filter="[<newFieldNameTiddler>] [<storeTitle>] [<searchListState>]"/>
\define cancel-search-actions-inner()
<$list filter="[<storeTitle>has[text]] [<newFieldNameTiddler>has[text]]" variable="ignore" emptyMessage="""<<delete-state-tiddlers>><$action-sendmessage $message="tm-cancel-tiddler"/>""">
<$list filter="[<storeTitle>has[text]] [<newFieldNameTiddler>has[text]]" variable="ignore" emptyMessage="""<<cancel-delete-tiddler-actions "cancel">>""">
<<delete-state-tiddlers>>
</$list>
\end
@@ -44,8 +43,7 @@ $:/config/EditTemplateFields/Visibility/$(currentField)$
<$action-sendmessage $message="tm-add-field"
$name=<<name>>
$value={{{ [<newFieldValueTiddler>get[text]] }}}/>
<$action-deletetiddler $tiddler=<<newFieldNameTiddler>>/>
<$action-deletetiddler $tiddler=<<newFieldValueTiddler>>/>
<$action-deletetiddler $filter="[<newFieldNameTiddler>] [<newFieldValueTiddler>] [<storeTitle>] [<searchListState>]"/>
<<lingo Fields/Add/Button>>
</$button>
</$reveal>
@@ -59,7 +57,7 @@ $value={{{ [<newFieldValueTiddler>get[text]] }}}/>
\whitespace trim
<div class="tc-edit-fields">
<table 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>
<$list filter="[all[current]fields[]] +[sort[title]]" variable="currentField" storyview="pop">
<$list filter=<<config-filter>> variable="temp">
@@ -67,11 +65,13 @@ $value={{{ [<newFieldValueTiddler>get[text]] }}}/>
<td class="tc-edit-field-name">
<$text text=<<currentField>>/>:</td>
<td class="tc-edit-field-value">
<$keyboard key="((delete-field))" actions="""<$action-deletefield $field=<<currentField>>/><$set name="currentTiddlerCSSescaped" value={{{ [<currentTiddler>escapecss[]] }}}><$action-sendmessage $message="tm-focus-selector" $param=<<current-tiddler-new-field-selector>>/></$set>""">
<$edit-text tiddler=<<currentTiddler>> field=<<currentField>> placeholder={{$:/language/EditTemplate/Fields/Add/Value/Placeholder}} tabindex={{$:/config/EditTabIndex}} cancelPopups="yes"/>
</$keyboard>
</td>
<td class="tc-edit-field-remove">
<$button class="tc-btn-invisible" tooltip={{$:/language/EditTemplate/Field/Remove/Hint}} aria-label={{$:/language/EditTemplate/Field/Remove/Caption}}>
<$action-deletefield $field=<<currentField>>/>
<$action-deletefield $field=<<currentField>>/><$set name="currentTiddlerCSSescaped" value={{{ [<currentTiddler>escapecss[]] }}}><$action-sendmessage $message="tm-focus-selector" $param=<<current-tiddler-new-field-selector>>/></$set>
{{$:/core/images/delete-button}}
</$button>
</td>
@@ -87,8 +87,8 @@ $value={{{ [<newFieldValueTiddler>get[text]] }}}/>
<em class="tc-edit tc-big-gap-right">
<<lingo Fields/Add/Prompt>>
</em>
<$vars refreshTitle=<<qualify "$:/temp/fieldname/refresh">> storeTitle=<<newFieldNameInputTiddler>> searchListState=<<newFieldNameSelectionTiddler>>>
<div class="tc-edit-field-add-name-wrapper">
<$vars refreshTitle=<<qualify "$:/temp/fieldname/refresh">> storeTitle=<<qualify "$:/temp/fieldname/input">> searchListState=<<qualify "$:/temp/fieldname/selected-item">>>
<$macrocall $name="keyboard-driven-input" tiddler=<<newFieldNameTiddler>> storeTitle=<<storeTitle>> refreshTitle=<<refreshTitle>>
selectionStateTitle=<<searchListState>> tag="input" default="" placeholder={{$:/language/EditTemplate/Fields/Add/Name/Placeholder}}
focusPopup=<<qualify "$:/state/popup/field-dropdown">> class="tc-edit-texteditor tc-popup-handle" tabindex={{$:/config/EditTabIndex}}
@@ -125,7 +125,6 @@ $value={{{ [<newFieldValueTiddler>get[text]] }}}/>
</$set>
</div>
</$reveal>
</$vars>
</div>
<span class="tc-edit-field-add-value tc-small-gap-right">
<$set name="currentTiddlerCSSescaped" value={{{ [<currentTiddler>escapecss[]] }}}>
@@ -137,5 +136,6 @@ $value={{{ [<newFieldValueTiddler>get[text]] }}}/>
<span class="tc-edit-field-add-button">
<$macrocall $name="new-field"/>
</span>
</$vars>
</div>
</$fieldmangler>

View File

@@ -11,27 +11,31 @@ fill:$(foregroundColor)$;
color:$(foregroundColor)$;
\end
\define tag-body-inner(colour,fallbackTarget,colourA,colourB,icon)
\define tag-body-inner(colour,fallbackTarget,colourA,colourB,icon,tagField:"tags")
\whitespace trim
<$vars foregroundColor=<<contrastcolour target:"""$colour$""" fallbackTarget:"""$fallbackTarget$""" colourA:"""$colourA$""" colourB:"""$colourB$""">> backgroundColor="""$colour$""">
<span style=<<tag-styles>> class="tc-tag-label tc-tag-list-item">
<$transclude tiddler="""$icon$"""/><$view field="title" format="text" />
<$button message="tm-remove-tag" param={{!!title}} class="tc-btn-invisible tc-remove-tag-button">{{$:/core/images/close-button}}</$button>
<$button class="tc-btn-invisible tc-remove-tag-button"><$action-listops $tiddler=<<saveTiddler>> $field=<<__tagField__>> $subfilter="-[{!!title}]"/>{{$:/core/images/close-button}}</$button>
</span>
</$vars>
\end
\define tag-body(colour,palette,icon)
<$macrocall $name="tag-body-inner" colour="""$colour$""" fallbackTarget={{$palette$##tag-background}} colourA={{$palette$##foreground}} colourB={{$palette$##background}} icon="""$icon$"""/>
\define tag-body(colour,palette,icon,tagField:"tags")
<$macrocall $name="tag-body-inner" colour="""$colour$""" fallbackTarget={{$palette$##tag-background}} colourA={{$palette$##foreground}} colourB={{$palette$##background}} icon="""$icon$""" tagField=<<__tagField__>>/>
\end
\define edit-tags-template(tagField:"tags")
\whitespace trim
<div class="tc-edit-tags">
<$fieldmangler>
<$list filter="[all[current]tags[]sort[title]]" storyview="pop">
<$macrocall $name="tag-body" colour={{!!color}} palette={{$:/palette}} icon={{!!icon}}/>
<$list filter="[list[!!$tagField$]sort[title]]" storyview="pop">
<$macrocall $name="tag-body" colour={{!!color}} palette={{$:/palette}} icon={{!!icon}} tagField=<<__tagField__>>/>
</$list>
<$vars tabIndex={{$:/config/EditTabIndex}} cancelPopups="yes">
<$macrocall $name="tag-picker"/>
<$macrocall $name="tag-picker" tagField=<<__tagField__>>/>
</$vars>
</$fieldmangler>
</div>
\end
<$set name="saveTiddler" value=<<currentTiddler>>>
<$macrocall $name="edit-tags-template" tagField=<<tagField>>/>
</$set>

View File

@@ -1,13 +1,16 @@
title: $:/core/ui/EditTemplate/type
tags: $:/tags/EditTemplate
first-search-filter: [all[shadows+tiddlers]prefix[$:/language/Docs/Types/]sort[description]sort[group-sort]removeprefix[$:/language/Docs/Types/]search<userInput>]
\define lingo-base() $:/language/EditTemplate/
\define input-cancel-actions() <$list filter="[<storeTitle>get[text]] [<currentTiddler>get[type]] +[limit[1]]" emptyMessage="""<<cancel-delete-tiddler-actions "cancel">>"""><$action-sendmessage $message="tm-remove-field" $param="type"/><$action-deletetiddler $filter="[<typeInputTiddler>] [<refreshTitle>] [<typeSelectionTiddler>]"/></$list>
\whitespace trim
<$set name="refreshTitle" value=<<qualify "$:/temp/type-search/refresh">>>
<div class="tc-edit-type-selector-wrapper">
<em class="tc-edit tc-big-gap-right"><<lingo Type/Prompt>></em>
<div class="tc-type-selector-dropdown-wrapper">
<div class="tc-type-selector"><$fieldmangler>
<$edit-text field="type" tag="input" default="" placeholder={{$:/language/EditTemplate/Type/Placeholder}} focusPopup=<<qualify "$:/state/popup/type-dropdown">> class="tc-edit-typeeditor tc-edit-texteditor tc-popup-handle" tabindex={{$:/config/EditTabIndex}} focus={{{ [{$:/config/AutoFocus}match[type]then[true]] ~[[false]] }}} cancelPopups="yes"/><$button popup=<<qualify "$:/state/popup/type-dropdown">> class="tc-btn-invisible tc-btn-dropdown tc-small-gap" tooltip={{$:/language/EditTemplate/Type/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Type/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button><$button message="tm-remove-field" param="type" class="tc-btn-invisible tc-btn-icon" tooltip={{$:/language/EditTemplate/Type/Delete/Hint}} aria-label={{$:/language/EditTemplate/Type/Delete/Caption}}>{{$:/core/images/delete-button}}</$button>
<$macrocall $name="keyboard-driven-input" tiddler=<<currentTiddler>> storeTitle=<<typeInputTiddler>> refreshTitle=<<refreshTitle>> selectionStateTitle=<<typeSelectionTiddler>> field="type" tag="input" default="" placeholder={{$:/language/EditTemplate/Type/Placeholder}} focusPopup=<<qualify "$:/state/popup/type-dropdown">> class="tc-edit-typeeditor tc-edit-texteditor tc-popup-handle" tabindex={{$:/config/EditTabIndex}} focus={{{ [{$:/config/AutoFocus}match[type]then[true]] ~[[false]] }}} cancelPopups="yes" configTiddlerFilter="[[$:/core/ui/EditTemplate/type]]" inputCancelActions=<<input-cancel-actions>>/><$button popup=<<qualify "$:/state/popup/type-dropdown">> class="tc-btn-invisible tc-btn-dropdown tc-small-gap" tooltip={{$:/language/EditTemplate/Type/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Type/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button><$button message="tm-remove-field" param="type" class="tc-btn-invisible tc-btn-icon" tooltip={{$:/language/EditTemplate/Type/Delete/Hint}} aria-label={{$:/language/EditTemplate/Type/Delete/Caption}}>{{$:/core/images/delete-button}}<$action-deletetiddler $filter="[<storeTitle>] [<refreshTitle>] [<selectionStateTitle>]"/></$button>
</$fieldmangler></div>
<div class="tc-block-dropdown-wrapper">
@@ -19,8 +22,10 @@ tags: $:/tags/EditTemplate
<div class="tc-dropdown-item">
<$text text={{!!group}}/>
</div>
<$list filter="[all[shadows+tiddlers]prefix[$:/language/Docs/Types/]group{!!group}] +[sort[description]]"><$link to={{!!name}}><$view field="description"/> (<$view field="name"/>)</$link>
<$set name="userInput" value={{{ [<typeInputTiddler>get[text]] }}}>
<$list filter="[all[shadows+tiddlers]prefix[$:/language/Docs/Types/]group{!!group}] +[sort[description]] +[removeprefix[$:/language/Docs/Types/]] +[search<userInput>]"><span class={{{ [<currentTiddler>addsuffix[-primaryList]] -[<typeSelectionTiddler>get[text]] +[then[]else[tc-list-item-selected]] }}}><$link to={{{ [<currentTiddler>addprefix[$:/language/Docs/Types/]get[name]] }}}><$view tiddler={{{ [<currentTiddler>addprefix[$:/language/Docs/Types/]] }}} field="description"/> (<$view tiddler={{{ [<currentTiddler>addprefix[$:/language/Docs/Types/]] }}} field="name"/>)</$link></span>
</$list>
</$set>
</$list>
</$linkcatcher>
</div>
@@ -29,3 +34,4 @@ tags: $:/tags/EditTemplate
</div>
</div>
</div>
</$set>

View File

@@ -3,11 +3,12 @@ tags: $:/tags/EditToolbar
caption: {{$:/core/images/cancel-button}} {{$:/language/Buttons/Cancel/Caption}}
description: {{$:/language/Buttons/Cancel/Hint}}
<$button message="tm-cancel-tiddler" tooltip={{$:/language/Buttons/Cancel/Hint}} aria-label={{$:/language/Buttons/Cancel/Caption}} class=<<tv-config-toolbar-class>>>
\whitespace trim
<$button actions=<<cancel-delete-tiddler-actions "cancel">> tooltip={{$:/language/Buttons/Cancel/Hint}} aria-label={{$:/language/Buttons/Cancel/Caption}} class=<<tv-config-toolbar-class>>>
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
{{$:/core/images/cancel-button}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/Cancel/Caption}}/></span>
</$list>
</$button>
</$button>

View File

@@ -3,11 +3,12 @@ tags: $:/tags/EditToolbar $:/tags/ViewToolbar
caption: {{$:/core/images/delete-button}} {{$:/language/Buttons/Delete/Caption}}
description: {{$:/language/Buttons/Delete/Hint}}
<$button message="tm-delete-tiddler" tooltip={{$:/language/Buttons/Delete/Hint}} aria-label={{$:/language/Buttons/Delete/Caption}} class=<<tv-config-toolbar-class>>>
\whitespace trim
<$button actions=<<cancel-delete-tiddler-actions "delete">> tooltip={{$:/language/Buttons/Delete/Hint}} aria-label={{$:/language/Buttons/Delete/Caption}} class=<<tv-config-toolbar-class>>>
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
{{$:/core/images/delete-button}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/Delete/Caption}}/></span>
</$list>
</$button>
</$button>

View File

@@ -4,6 +4,7 @@ caption: {{$:/core/images/done-button}} {{$:/language/Buttons/Save/Caption}}
description: {{$:/language/Buttons/Save/Hint}}
\define save-tiddler-button()
\whitespace trim
<$fieldmangler><$button tooltip={{$:/language/Buttons/Save/Hint}} aria-label={{$:/language/Buttons/Save/Caption}} class=<<tv-config-toolbar-class>>>
<<save-tiddler-actions>>
<$list filter="[<tv-config-toolbar-icons>match[yes]]">

View File

@@ -3,6 +3,6 @@ tags: $:/tags/EditorToolbar
icon: $:/core/images/erase
caption: {{$:/language/Buttons/Clear/Caption}}
description: {{$:/language/Buttons/Clear/Hint}}
condition: [<targetTiddler>is[image]]
condition: [<targetTiddler>is[image]] -[<targetTiddler>type[image/svg+xml]]
dropdown: $:/core/ui/EditorToolbar/clear-dropdown

View File

@@ -4,7 +4,7 @@ icon: $:/core/images/fixed-height
custom-icon: yes
caption: {{$:/language/Buttons/EditorHeight/Caption}}
description: {{$:/language/Buttons/EditorHeight/Hint}}
condition: [<targetTiddler>type[]] [<targetTiddler>get[type]prefix[text/]] +[first[]]
condition: [<targetTiddler>type[]] [<targetTiddler>get[type]prefix[text/]] [<targetTiddler>get[type]match[application/javascript]] [<targetTiddler>get[type]match[application/json]] [<targetTiddler>get[type]match[application/x-tiddler-dictionary]] [<targetTiddler>get[type]match[image/svg+xml]] +[first[]]
dropdown: $:/core/ui/EditorToolbar/editor-height-dropdown
<$reveal tag="span" state="$:/config/TextEditor/EditorHeight/Mode" type="match" text="fixed">

View File

@@ -3,7 +3,7 @@ tags: $:/tags/EditorToolbar
icon: $:/core/images/line-width
caption: {{$:/language/Buttons/LineWidth/Caption}}
description: {{$:/language/Buttons/LineWidth/Hint}}
condition: [<targetTiddler>is[image]]
condition: [<targetTiddler>is[image]] -[<targetTiddler>type[image/svg+xml]]
dropdown: $:/core/ui/EditorToolbar/line-width-dropdown
<$text text={{$:/config/BitmapEditor/LineWidth}}/>
<$text text={{$:/config/BitmapEditor/LineWidth}}/>

View File

@@ -3,7 +3,7 @@ tags: $:/tags/EditorToolbar
icon: $:/core/images/opacity
caption: {{$:/language/Buttons/Opacity/Caption}}
description: {{$:/language/Buttons/Opacity/Hint}}
condition: [<targetTiddler>is[image]]
condition: [<targetTiddler>is[image]] -[<targetTiddler>type[image/svg+xml]]
dropdown: $:/core/ui/EditorToolbar/opacity-dropdown
<$text text={{$:/config/BitmapEditor/Opacity}}/>

View File

@@ -3,7 +3,7 @@ tags: $:/tags/EditorToolbar
icon: $:/core/images/paint
caption: {{$:/language/Buttons/Paint/Caption}}
description: {{$:/language/Buttons/Paint/Hint}}
condition: [<targetTiddler>is[image]]
condition: [<targetTiddler>is[image]] -[<targetTiddler>type[image/svg+xml]]
dropdown: $:/core/ui/EditorToolbar/paint-dropdown
\define toolbar-paint()

View File

@@ -3,7 +3,7 @@ tags: $:/tags/EditorToolbar
icon: $:/core/images/rotate-left
caption: {{$:/language/Buttons/RotateLeft/Caption}}
description: {{$:/language/Buttons/RotateLeft/Hint}}
condition: [<targetTiddler>is[image]]
condition: [<targetTiddler>is[image]] -[<targetTiddler>type[image/svg+xml]]
<$action-sendmessage
$message="tm-edit-bitmap-operation"

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