1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2026-06-17 02:38:51 +00:00

Compare commits

..

217 Commits

Author SHA1 Message Date
Jeremy Ruston 2dd9a2006d Impact note about wikified palettes 2026-01-30 20:57:13 +00:00
Jeremy Ruston ebff5aa3db Make Palette be the default Appearance tab in control panel 2026-01-30 20:56:59 +00:00
Jeremy Ruston 3bc2c5fabc Remove appply filter run prefix 2026-01-30 20:56:38 +00:00
Jeremy Ruston d423aa926e Tweak lingo 2026-01-30 20:56:14 +00:00
Jeremy Ruston fe708eefc6 Merge branch 'master' into colour-improvements 2026-01-23 09:03:47 +00:00
Jeremy Ruston a7525037fd Improve English 2026-01-22 12:11:45 +00:00
Jeremy Ruston 15736bceb9 Add test for invalid pragma 2026-01-21 21:49:16 +00:00
Jeremy Ruston 35b0108da6 Fix parsing bug 2026-01-21 21:45:45 +00:00
Jeremy Ruston 59d23da97c Merge branch 'default-prefix-for-subfilter' into colour-improvements 2026-01-20 16:22:01 +00:00
Jeremy Ruston 3f654bccaa Revert previous merge from #9595
This reverts commit eb8f69dd03.
2026-01-20 16:04:28 +00:00
Jeremy Ruston a45a8723c0 Add a view template body for palettes 2026-01-19 21:20:08 +00:00
Jeremy Ruston ae7d6da35b Add a P3 palette for testing 2026-01-19 12:54:27 +00:00
Jeremy Ruston a8e056c88c Merge branch 'default-prefix-for-subfilter' into colour-improvements 2026-01-19 12:54:01 +00:00
Jeremy Ruston 5b0af905a2 Use the subfilter suffix to suppress deduping palette entries 2026-01-19 12:53:45 +00:00
Jeremy Ruston eb8f69dd03 Merge subfilter fix from #9595 2026-01-19 12:52:58 +00:00
Jeremy Ruston ef49828989 temp 2026-01-19 12:49:08 +00:00
Jeremy Ruston 9b56734451 Extend subfilter operator with suffix for specifying the default filter run prefix 2026-01-19 11:31:09 +00:00
Jeremy Ruston 2f8d53d3f7 Allow default filter run prefix to be specified for filter evaluation 2026-01-19 11:30:50 +00:00
Jeremy Ruston 5b96929f4e Fix tests 2026-01-18 12:03:59 +00:00
Jeremy Ruston 829bb61378 Merge branch 'master' into colour-improvements 2026-01-18 11:48:42 +00:00
Jeremy Ruston 421ecff30f Merge branch 'master' into colour-improvements 2026-01-17 17:52:34 +00:00
Jeremy Ruston c7511fc99f Tweak credits for 2026 palettes 2026-01-17 17:50:27 +00:00
Jeremy Ruston 87f797b1ae Fix use of creaky old technique for setting alpha/opacity from a different base colour 2026-01-17 17:46:25 +00:00
Jeremy Ruston 8cc94d8ea7 Fix year category for new palettes 2026-01-17 17:45:12 +00:00
Jeremy Ruston dcaff6a243 Revert linter fixes for unused function parameters 2026-01-17 17:29:28 +00:00
Jeremy Ruston e98aed6f6e Fix remaining references to palettes-2025 plugin 2026-01-17 17:23:16 +00:00
Jeremy Ruston d35e34b55e Remove debugging code
It was breaking colour assignment as a property, rather than in a stylesheet
2026-01-17 17:22:57 +00:00
Jeremy Ruston bb4d57e170 More linting dancing 2026-01-17 17:00:24 +00:00
Jeremy Ruston fd709afc37 More linting errors 2026-01-17 16:53:52 +00:00
Jeremy Ruston 93388bc3cc Fix lint errors 2026-01-17 16:05:32 +00:00
Jeremy Ruston a8c4437587 Properly credit the new palettes 2026-01-17 15:48:16 +00:00
Jeremy Ruston 6dc83386bd Update new palettes to 2026 category 2026-01-17 15:44:42 +00:00
Jeremy Ruston 9641e6a2d0 Remove docs for apply filter run prefix 2026-01-17 15:43:45 +00:00
Jeremy Ruston 3254544eb2 Update the 2025 palette plugin to 2026 2026-01-17 15:42:09 +00:00
Jeremy Ruston c707b9a432 Enable change note 2026-01-17 15:39:37 +00:00
Jeremy Ruston 3cab1571be Don't lint color.js 2026-01-17 15:39:19 +00:00
Jeremy Ruston 502598bd25 Switch from apply filter run to let filter run 2026-01-17 15:35:27 +00:00
Jeremy Ruston 8a18f92710 Typo 2026-01-17 13:02:54 +00:00
Jeremy Ruston 3353d0e005 Upgrade color.js 2026-01-17 12:53:41 +00:00
Jeremy Ruston fd85842036 Merge branch 'master' into colour-improvements 2026-01-16 22:40:35 +00:00
Jeremy Ruston b0dc46c9e9 Avoid using camel case for new docs tiddlers 2026-01-16 22:40:27 +00:00
Jeremy Ruston 5b0c923a82 Merge branch 'master' into colour-improvements 2026-01-08 11:23:43 +00:00
Jeremy Ruston ae33a4521d Merge branch 'master' into colour-improvements 2025-09-14 17:22:59 +01:00
Jeremy Ruston 4b83e89d40 Move palettes into plugins 2025-08-06 15:13:10 +01:00
Jeremy Ruston da41483172 Prepare to split palettes out into plugins 2025-08-06 15:07:15 +01:00
Jeremy Ruston 39488f118b Use TwentyTwenties palette by default 2025-08-06 14:39:48 +01:00
Jeremy Ruston f9721b029e Merge branch 'master' into colour-improvements 2025-08-06 10:30:30 +01:00
Jeremy Ruston 974904588c Switch to minified version of color.js
See this discussion https://github.com/TiddlyWiki/TiddlyWiki5/pull/8702#issuecomment-3158465038
2025-08-06 10:29:04 +01:00
Jeremy Ruston 38457a4667 Add category field to palettes 2025-06-21 15:14:25 +01:00
Jeremy Ruston 96ef5c8314 Move palettes into category folders 2025-06-21 14:53:49 +01:00
Jeremy Ruston 96d24756ea Add new palettes from https://yatagarasu.tiddlyhost.com 2025-06-21 14:41:49 +01:00
Jeremy Ruston 77c99b418f Change default colour space for interpolation 2025-06-21 11:36:34 +01:00
Jeremy Ruston 7f2a47f303 Adopt more ES2017 features 2025-06-20 17:54:28 +01:00
Jeremy Ruston dcf0f449c4 Adopt class syntax 2025-06-20 17:46:31 +01:00
Jeremy Ruston a4c84d727c Remove function wrappers 2025-06-20 17:33:28 +01:00
Jeremy Ruston 5335ebf044 Merge branch 'master' into colour-improvements 2025-06-20 17:23:43 +01:00
Jeremy Ruston e9d87fb551 Merge branch 'master' into colour-improvements 2025-06-19 17:13:53 +01:00
Jeremy Ruston 54382d6666 Merge branch 'master' into colour-improvements 2025-04-16 14:31:47 +01:00
Jeremy Ruston e86eb28890 Merge branch 'master' into colour-improvements 2025-03-21 17:24:19 +00:00
Jeremy Ruston 5897b82c51 Fix tests 2025-03-07 16:34:09 +00:00
Jeremy Ruston 5e27462acf TwentyTwenties improvements 2025-03-07 16:23:29 +00:00
Jeremy Ruston 4c95ae546f Fix colour-interpolate with missing colours 2025-03-07 16:23:16 +00:00
Jeremy Ruston d42e3d36bc Add colour-set-alpha operator 2025-03-07 16:23:00 +00:00
Jeremy Ruston ee977def52 Include palette entry name in palette entries
Makes debugging easier, and works in CSS and as a style.prop assignment
2025-03-07 16:21:51 +00:00
Jeremy Ruston 30016967b1 Preview: Fix sidebar link colour 2025-03-07 16:21:07 +00:00
Jeremy Ruston 250ee90b07 TwentyTwenties: copy over missing palette entries
These are mostly RGB entries that were previously missing, filled in with values from Vanilla.

The goal is still not to have any direct RGB colours in the palette, just computed colours derived from the base colours
2025-03-06 21:53:45 +00:00
Jeremy Ruston 624cf95197 Fix from mismerging from master 2025-03-06 21:44:16 +00:00
Jeremy Ruston 8467fa333d Merge branch 'master' into colour-improvements 2025-03-06 21:38:49 +00:00
Jeremy Ruston 75ba08556f Merge branch 'master' into colour-improvements 2025-02-18 21:15:13 +00:00
Jeremy Ruston 93f954411b Merge branch 'master' into colour-improvements 2025-02-18 16:54:54 +00:00
Jeremy Ruston 059e439702 Merge branch 'master' into colour-improvements 2025-02-14 16:46:02 +00:00
Jeremy Ruston 2028420e3b Fixes suggested by @pmario 2025-02-14 14:11:08 +00:00
Jeremy Ruston 8b05b725aa Merge branch 'master' into colour-improvements 2025-02-14 12:01:14 +00:00
Jeremy Ruston d7df7eddb1 Introduce tf.colour function to make palette entries more concise 2025-02-13 16:26:22 +00:00
Jeremy Ruston 0037813b39 Background action demos should require explicit enabling 2025-02-13 09:10:30 +00:00
Jeremy Ruston 377856c6a1 Add temporary guide tiddler at the top 2025-02-12 18:43:19 +00:00
Jeremy Ruston 49969a2f1e Docs for apply filter run prefix 2025-02-12 16:41:37 +00:00
Jeremy Ruston 09f8ab9962 Move from v5.3.7 -> v5.4.0 2025-02-12 12:48:35 +00:00
Jeremy Ruston 422b092eb2 Don't need consent banner anymore
Was just for testing
2025-02-12 12:48:02 +00:00
Jeremy Ruston 067a1a22c6 Move sample background item out of the core
It shouldn't be enabled by default, either, but we'll come back to that
2025-02-12 12:47:41 +00:00
Jeremy Ruston 83c6223617 Refactor the interpolate operator so it can be used with the range operator 2025-02-12 10:05:16 +00:00
Jeremy Ruston 611adadaed Add apply filter run prefix
The map filter run prefix is often used as a way to move a computed value in the input list into a variable so that it can be used as a parameter of a filter operator. The apply filter run prefix extends this idea to make the input list available as variables $1, $2 etc. Unlike the map prefix, the apply filter run is only evaluated once.
2025-02-12 10:04:46 +00:00
Jeremy Ruston 28935a5856 Add hue adjuster to colour-interpolate operator 2025-02-11 20:46:11 +00:00
Jeremy Ruston 71a144f6f9 Typo 2025-02-10 17:01:45 +00:00
Jeremy Ruston 92b7819259 Fix Codemirror colour palette fallbacks 2025-02-10 17:01:37 +00:00
Jeremy Ruston d2204ae72e Fill in some missing palette entries 2025-02-10 13:48:02 +00:00
Jeremy Ruston 7da70ecf6a Add tabs and recent list to the sidebar 2025-02-10 13:47:41 +00:00
Jeremy Ruston d8dfc10ea8 Typo 2025-02-09 21:54:31 +00:00
Jeremy Ruston 7df987803d Move generic tests into a background palette
These are the generic tests that should be applied to every palette
2025-02-09 21:40:15 +00:00
Jeremy Ruston 4665bab700 AutoToggle should default to light mode so that static exports are light mode 2025-02-09 14:29:12 +00:00
Jeremy Ruston e87aaff06b Add tabs to the preview 2025-02-06 22:19:10 +00:00
Jeremy Ruston 7c4938293e Refactor the palette preview macros into a generic widget
Takes the opportunity to simplify things now that we don't have to worry about wikified palettes
2025-02-06 21:27:06 +00:00
Jeremy Ruston eba73eebcb Missed off 961b26a984 2025-02-06 17:28:28 +00:00
Jeremy Ruston 1f4f164d5e Take advantage of compiled palettes
More robust because previously we couldn't cope with indirect palette entries in these situations
2025-02-06 12:55:45 +00:00
Jeremy Ruston bfea62b43b The tags macros do not actually need access to the palette 2025-02-06 12:53:40 +00:00
Jeremy Ruston 4c216646a4 Introduce background palettes for plugins 2025-02-06 11:53:07 +00:00
Jeremy Ruston 4fe90a6c73 Add VanillaCherry palette 2025-02-06 11:28:24 +00:00
Jeremy Ruston 961b26a984 Get rid of palette-types...
Instead, we'll special case transforming `<<colour X>>` into `[function[colour],[x]]`

Makes everything much easier and avoids all the kerfuffle of not being able to mix palettes
2025-02-06 11:27:04 +00:00
Jeremy Ruston 0d9ab2e2f6 Remove unneeded scheme processing
Now that we're dealing with the schemes during the import process it is no longer necessary for the compilation process to worry about it.
2025-02-05 18:05:57 +00:00
Jeremy Ruston 796c33bc46 Refactor some variable names 2025-02-05 17:11:51 +00:00
Jeremy Ruston 4d06ecd535 Only allow palettes to import palettes of the same type 2025-02-04 21:18:54 +00:00
Jeremy Ruston f9e4dd8fd3 Rename custom palette editor to custom palette settings
To avoid confusion with existing usage of "palette editor"
2025-02-04 21:08:02 +00:00
Jeremy Ruston 6e4d7aa7f1 Give the AutoToggle palette a custom editor 2025-02-04 21:03:13 +00:00
Jeremy Ruston 998d5c8d8f The lingo macro shouldn't mess with currentTiddler 2025-02-04 21:02:47 +00:00
Jeremy Ruston 38865a40ad Palette should autocompile when the palette tiddler itself changes 2025-02-04 20:00:17 +00:00
Jeremy Ruston a5c4d90154 Refactor palette switcher a little 2025-02-04 19:59:39 +00:00
Jeremy Ruston 2e5a988bb3 Clarify comment 2025-02-04 16:44:07 +00:00
Jeremy Ruston 0ee2f286aa Set colour scheme property of root element 2025-02-04 16:40:48 +00:00
Jeremy Ruston 30a7d61e56 Easier for development if the prerelease uses the tw5.com palette 2025-02-04 16:26:46 +00:00
Jeremy Ruston c7f9dbfc29 Compile colour scheme handling 2025-02-04 16:26:15 +00:00
Jeremy Ruston c6bb2b51e6 Rethink palette manager
The current content of $:/PaletteManager is moved into $:/PaletteEditor, and $:/PaletteManager repurposed as the control panel palette switcher
2025-02-04 16:11:51 +00:00
Jeremy Ruston a053f03818 Remove logging 2025-02-04 16:10:38 +00:00
Jeremy Ruston 6970ac24bf Typo 2025-02-03 18:44:58 +00:00
Jeremy Ruston 431149d20c Introduce dynamic colour scheme mechanism
Also introduces palette inheritance

This finally allows us to have a palette that automatically switches between dark and light variants. The mechanism is more flexible that that, and allows for multiple colour schemes (night, morning, day, evening, for example) with automatic switching between them.
2025-02-03 13:26:25 +00:00
Jeremy Ruston a366d62358 Include tiddler borders in preview
Several of the core palettes have distinctive borders
2025-01-31 17:06:55 +00:00
Jeremy Ruston a6a91d49b7 Restore accidentally deleted field 2025-01-30 18:35:58 +00:00
Jeremy Ruston 22cf3b25bd Remove infinite loop that was added for testing 2025-01-28 21:40:34 +00:00
Jeremy Ruston 139b61fff1 Proper recursion detection for palettes 2025-01-28 19:18:58 +00:00
Jeremy Ruston c1fd82f50f Minor cleanups 2025-01-28 15:44:42 +00:00
Jeremy Ruston effeed7ade Remove extraneous logging 2025-01-27 21:47:03 +00:00
Jeremy Ruston 546e438943 Allow background actions to be scoped by platform 2025-01-27 21:45:17 +00:00
Jeremy Ruston efcd23993e Merge branch 'master' into colour-improvements 2025-01-27 16:55:03 +00:00
Jeremy Ruston 0c8aad49f9 Replace accumulate-palette-entries with new changecount filter
Much more direct and efficient
2025-01-27 11:09:18 +00:00
Jeremy Ruston 317e1245c8 Introduce an improved but temporary cache invalidation method for palettes 2025-01-26 17:54:47 +00:00
Jeremy Ruston d2bbc56c78 Move modern palettes to correct directory 2025-01-25 17:28:06 +00:00
Jeremy Ruston 8957424e55 Start adding tests for palette operations 2025-01-25 17:28:00 +00:00
Jeremy Ruston 0fd5b04b9a Merge branch 'master' into colour-improvements 2025-01-25 11:05:21 +00:00
Jeremy Ruston 3ea7cd3bf7 Palette editors no longer need to manually recompile the palette 2025-01-25 11:05:13 +00:00
Jeremy Ruston 7513e4426c Allow text editor type=color for colours not in hex RGB format
See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/color#value
2025-01-25 11:03:53 +00:00
Jeremy Ruston 0dfde0660a Detect darkmode at startup 2025-01-24 18:34:55 +00:00
Jeremy Ruston 8c619fd86e Compile palette at startup 2025-01-24 18:32:00 +00:00
Jeremy Ruston 407e58f837 Add a basic dark palette
Obviously some things are hardcoded at the moment
2025-01-24 11:17:55 +00:00
Jeremy Ruston 9588b7f1a3 Autocompile palettes when they change 2025-01-24 11:16:31 +00:00
Jeremy Ruston 28c1e77b60 Make sure rootwidget is available before background actions start 2025-01-24 11:15:27 +00:00
Jeremy Ruston 0baf395030 Merge background actions and media tracker from #8555
The changes in #8555 are needed in order to be able to offer the desired user experience for dark mode changes.
2025-01-23 18:16:10 +00:00
Jeremy Ruston 9681b0deda Merge branch 'master' into colour-improvements 2025-01-23 18:15:44 +00:00
Jeremy Ruston 62fb916a68 Merge branch 'master' into colour-improvements 2025-01-23 14:37:23 +00:00
Jeremy Ruston 3614236cfc Paldette and style tweaks 2025-01-21 16:36:00 +00:00
Jeremy Ruston c75f50e99a Fix palette switcher used in the sidebar
by adding a new "thumbnails" parameter to the template
2025-01-09 14:51:48 +00:00
Jeremy Ruston 55d9e92032 Edit text widget shouldn't fully refresh when default attribute changes 2025-01-09 10:51:02 +00:00
Jeremy Ruston 2edcf0f46b Refactor TwentyTwenties editor 2025-01-09 10:50:37 +00:00
Jeremy Ruston 69363bf7ef Palette manager should recompile palette on edits 2025-01-08 21:38:08 +00:00
Jeremy Ruston 2b0c634fb8 Refactor actions for recompiling current palette 2025-01-08 21:37:44 +00:00
Jeremy Ruston 28167adc22 Add a palette that automatically switches between dark and light
Will requires #7999 to work fully; for the moment when you switch between dark and light you will see the preview change, and then next time you select the palette it will be in the correct mode
2025-01-08 16:02:05 +00:00
Jeremy Ruston bd4b3e4107 Fix some old-style palette references 2025-01-08 16:00:29 +00:00
Jeremy Ruston 2cbd1080fa Fix more TwentyTwenties entries 2025-01-08 15:57:39 +00:00
Jeremy Ruston a4293068bf Clarify method name 2025-01-08 14:49:19 +00:00
Jeremy Ruston d1ce54806f Download button should use palette colours 2025-01-08 10:06:56 +00:00
Jeremy Ruston 6b39d6aa43 Fix editing colours that are not in 6 digit hex format
See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/color#value
2025-01-08 09:59:04 +00:00
Jeremy Ruston 5d1cf251b9 Add best contrast operator 2025-01-07 17:40:23 +00:00
Jeremy Ruston c02c82557b Add a primitive custom palette editor 2025-01-02 17:10:51 +00:00
Jeremy Ruston b90b449ceb Use interpolation to derive colours 2025-01-02 17:10:29 +00:00
Jeremy Ruston 6a06df79c4 Fix palette switcher 2024-12-27 12:00:50 +00:00
Jeremy Ruston 2558dc0b10 TwentyTwenties palette: use interpolation 2024-12-22 19:20:05 +00:00
Jeremy Ruston 2eee3bfcd6 Merge branch 'master' into colour-improvements 2024-12-21 09:48:10 +00:00
Jeremy Ruston 2685fa7c4e Improvements to TwentyTwenties palettes
Still a work in progress, but getting more coherent
2024-12-15 18:55:17 +00:00
Jeremy Ruston 3c44532551 Barebones docs for colour spaces 2024-12-15 18:49:04 +00:00
Jeremy Ruston 2640406f5b Include contrast value in contrast errors 2024-12-15 18:48:48 +00:00
Jeremy Ruston c1e36a1e5f Add colour-interpolate operator 2024-12-15 18:48:28 +00:00
Jeremy Ruston ae1d9f5b86 Add colour-get-oklch operator 2024-12-15 13:04:33 +00:00
Jeremy Ruston 1df0ac486b Refactor colour-oklch operator to colour-set-oklch 2024-12-15 11:56:49 +00:00
Jeremy Ruston b1fcb18d9e Refactor for clearer variable names 2024-12-15 11:49:23 +00:00
Jeremy Ruston 5a6eea7fa2 Make the alert and notification previews be optional
Via some future UI
2024-12-14 17:33:02 +00:00
Jeremy Ruston 6fe16bc71a Fix colour for site title 2024-12-14 17:32:43 +00:00
Jeremy Ruston 6a66c49261 Merge branch 'master' into colour-improvements 2024-12-14 17:12:51 +00:00
Jeremy Ruston fc695e7a50 Merge branch 'master' into colour-improvements 2024-12-05 17:38:50 +00:00
Jeremy Ruston 9efcad9360 Display test results at the bottom of the palette switcher 2024-11-19 09:09:11 +00:00
Jeremy Ruston cd5bbcda8d Add contrast checks to TwentyTwenties palette
I think I might be building a programming language for writing palettes...
2024-11-18 18:15:53 +00:00
Jeremy Ruston aa69c3ae91 Add colour-contrast operator 2024-11-18 18:15:20 +00:00
Jeremy Ruston 76f2decf8b Start fixing the TwentyTwenties palettes 2024-11-18 16:40:49 +00:00
Jeremy Ruston 84bef54802 Docs for colour-oklch operator 2024-11-18 16:38:54 +00:00
Jeremy Ruston 3507b0f952 Fix filtered palette previews 2024-11-17 16:11:10 +00:00
Jeremy Ruston b0828cc099 Add notification preview 2024-11-17 16:10:57 +00:00
Jeremy Ruston 32ac67166a Add alert preview 2024-11-17 14:45:52 +00:00
Jeremy Ruston b2d0c22d75 Componentise more preview components 2024-11-17 14:45:41 +00:00
Jeremy Ruston cfabc92945 Update contrastcolour macro to use color.js 2024-11-16 14:37:14 +00:00
Jeremy Ruston 809465b6e2 Merge branch 'master' into colour-improvements 2024-11-16 14:22:19 +00:00
Jeremy Ruston 8b59b6166e Palette tweaks
These filtered palettes are still just experiments with the techniques, and not yet a serious palette
2024-11-14 17:45:10 +00:00
Jeremy Ruston 3faf9bae5c Fix previews of filtered palettes 2024-11-14 17:40:58 +00:00
Jeremy Ruston c2ee0727a5 Merge branch 'master' into colour-improvements 2024-11-12 20:57:46 +00:00
Jeremy Ruston 7de5f40884 Merge branch 'master' into colour-improvements 2024-11-12 20:37:01 +00:00
Jeremy Ruston 21cd3b86ad Merge branch 'master' into colour-improvements 2024-11-12 19:51:52 +00:00
Jeremy Ruston ad1b0fdddd Palette tweaks 2024-11-12 19:26:20 +00:00
Jeremy Ruston 1db8cf7fe5 Merge branch 'master' into colour-improvements 2024-11-12 19:18:54 +00:00
Jeremy Ruston 46da1619af Add aria labels to palette switcher
Co-authored-by: Mario Pietsch <pmariojo@gmail.com>
2024-11-11 15:52:55 +00:00
Jeremy Ruston bad9517153 Another fix for filtered palette previews 2024-11-10 16:52:49 +00:00
Jeremy Ruston 38d5daaf12 Improve chooser chosen item highlight 2024-11-10 16:52:23 +00:00
Jeremy Ruston 297ae7eccb Fix preview of filtered palettes 2024-11-10 09:52:43 +00:00
Jeremy Ruston b54d56ec47 Support for imported palettes
Also consolidate the palette entries into a temporary palette before compiling them

Note that imported palettes is not currently recursive
2024-11-09 19:03:54 +00:00
Jeremy Ruston 4e2f2bebd0 Avoid redefining the colour function by adding a configuration variable 2024-11-09 17:02:00 +00:00
Jeremy Ruston f88915728f Introduce new static palette architecture 2024-11-09 16:15:33 +00:00
Jeremy Ruston 1be89a28bf Make preview templates tag driven and extensible 2024-11-08 09:12:48 +00:00
Jeremy Ruston 250e57cd79 Remove wikify operator and refactor palette preview
The implementation of the palette preview is much less elegant like this, but it does work
2024-11-07 18:30:39 +00:00
Jeremy Ruston a4d930322e Testing CI 2024-11-06 08:32:42 +00:00
Jeremy Ruston c3ce9cafb7 Testing Netlify CI 2024-11-06 08:22:42 +00:00
Jeremy Ruston 348f7177a7 Remove logging 2024-11-05 22:42:46 +00:00
Jeremy Ruston c6074402bb Restore default styling for chosen chooser item
See https://github.com/TiddlyWiki/TiddlyWiki5/pull/8702#discussion_r1816584692
2024-11-05 10:24:01 +00:00
Jeremy Ruston 23eccd1df6 Merge branch 'master' into colour-improvements 2024-11-04 19:26:16 +00:00
Jeremy Ruston ff5c846130 Indentation for palette switcher 2024-11-04 18:12:00 +00:00
Jeremy Ruston 81b7bb4124 Merge branch 'master' into colour-improvements 2024-11-04 10:39:28 +00:00
Jeremy Ruston a8fb07137d Add expertimental colour-oklch operator 2024-11-03 16:13:09 +00:00
Jeremy Ruston 85fa913b1c Merge branch 'master' into colour-improvements 2024-11-03 16:10:47 +00:00
Jeremy Ruston bc0fde6853 Fix palette chooser when displayed in "Tools" dropdown 2024-10-31 18:03:50 +00:00
Jeremy Ruston 4f2754d16c Merge branch 'master' into colour-improvements 2024-10-31 17:46:30 +00:00
Jeremy Ruston 4445111a08 Merge branch 'master' into colour-improvements 2024-10-30 20:38:58 +00:00
Jeremy Ruston 151f61adc0 Palette chooser styling tweaks 2024-10-25 11:03:21 +01:00
Jeremy Ruston fc369415e4 Improve colour palette switcher with previews 2024-10-25 09:28:33 +01:00
Jeremy Ruston b5a22e3e9e Remove obsolete comment 2024-10-25 09:28:17 +01:00
Jeremy Ruston d372729ed0 Add colour-lighten and colour-darken operators 2024-10-24 12:01:50 +01:00
Jeremy Ruston 96b85edfa2 Fix up the tests 2024-10-24 10:46:48 +01:00
Jeremy Ruston 4af573aaf9 Fix nested colour definitions 2024-10-23 09:39:18 +01:00
Jeremy Ruston 1e5c69eb99 Fix typo 2024-10-23 08:25:24 +01:00
Jeremy Ruston e1e73d2aa0 Merge branch 'master' into colour-improvements 2024-10-23 08:22:01 +01:00
Jeremy Ruston a23ee165d8 Rewrite colour macro as a function
Using the new wikify operator.

Currently has a bug whereby redirected colours (like "tiddler-background") do not work. Direct colours like "background" do work.

Note the hacks needed to makeFakeWidgetWithVariables work
2024-10-22 17:26:04 +01:00
Jeremy Ruston 467a1a47cc Introduce wikify operator
Really just syntactic sugar for the wikify widget
2024-10-22 17:24:51 +01:00
Jeremy Ruston 93d1c05ca7 Include colour.js license and mark version number 2024-10-21 17:25:56 +01:00
Jeremy Ruston fb9c0d6a5a Replace 12 year old CSS colour parsing library
The replacement library from https://colorjs.io/ is much, much larger but I think we can develop a custom build that uses treeshaking to whittle the code down to the bits that we need. @linonetwo does that sound feasible?

I intend the explore further improvements but I wanted to start by establishing a library that can do modern P3 and OKLCH colour calculations.
2024-10-21 09:03:39 +01:00
730 changed files with 11558 additions and 4992 deletions
+1
View File
@@ -120,6 +120,7 @@ node $TW5_BUILD_TIDDLYWIKI \
|| exit 1
# /empty.html Empty
# /empty.hta For Internet Explorer
# /empty-external-core.html External core empty
# /tiddlywikicore-<version>.js Core plugin javascript
node $TW5_BUILD_TIDDLYWIKI \
+3 -20
View File
@@ -316,25 +316,8 @@ $tw.utils.htmlDecode = function(s) {
return s.toString().replace(/&lt;/mg,"<").replace(/&nbsp;/mg,"\xA0").replace(/&gt;/mg,">").replace(/&quot;/mg,"\"").replace(/&amp;/mg,"&");
};
/*
Get the browser location.hash. We don't use location.hash because of the way that Firefox auto-urldecodes it (see http://stackoverflow.com/questions/1703552/encoding-of-window-location-hash)
*/
$tw.utils.getLocationHash = function() {
const href = window.location.href,
idx = href.indexOf("#");
if(idx === -1) {
return "#";
}
const afterHash = href.substring(idx + 1);
if(afterHash.startsWith("#") || afterHash.startsWith("%23")) {
// Special case: ignore location hash if it itself starts with a #
return "#";
}
return href.substring(idx);
};
/** @deprecated Use window.location.hash instead. */
$tw.utils.getLocationHash = () => window.location.hash;
/** @deprecated Pad a string to a given length with "0"s. Length defaults to 2 */
$tw.utils.pad = function(value,length = 2) {
@@ -613,7 +596,7 @@ $tw.utils.evalGlobal = function(code,context,filename,sandbox,allowGlobals) {
// Compile the code into a function
var fn;
if($tw.browser) {
fn = Function("return " + code + "\n\n//# sourceURL=" + filename)(); // See https://github.com/TiddlyWiki/TiddlyWiki5/issues/6839
fn = window["eval"](code + "\n\n//# sourceURL=" + filename); // eslint-disable-line no-eval -- See https://github.com/TiddlyWiki/TiddlyWiki5/issues/6839
} else {
if(sandbox){
fn = vm.runInContext(code,sandbox,filename)
@@ -33,8 +33,8 @@ exports.handler = function(request,response,state) {
}
var text = state.wiki.renderTiddler(renderType,renderTemplate,{parseAsInline: true, variables: {currentTiddler: title}});
var headers = {"Content-Type": renderType};
state.sendResponse(200,headers,text,"utf8");
// Naughty not to set a content-type, but it's the easiest way to ensure the browser will see HTML pages as HTML, and accept plain text tiddlers as CSS or JS
state.sendResponse(200,{},text,"utf8");
} else {
response.writeHead(404);
response.end();
-15
View File
@@ -42,8 +42,6 @@ function Server(options) {
}
// Setup the default required plugins
this.requiredPlugins = this.get("required-plugins").split(',');
// Initialise CORS
this.corsEnable = this.get("cors-enable") === "yes";
// Initialise CSRF
this.csrfDisable = this.get("csrf-disable") === "yes";
// Initialize Gzip compression
@@ -263,13 +261,6 @@ Server.prototype.requestHandler = function(request,response,options) {
state.urlInfo = url.parse(request.url);
state.queryParameters = querystring.parse(state.urlInfo.query);
state.pathPrefix = options.pathPrefix || this.get("path-prefix") || "";
// Enable CORS
if(this.corsEnable) {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Headers", "*");
response.setHeader("Access-Control-Allow-Methods", "*");
response.setHeader("Access-Control-Expose-Headers", "*");
}
state.sendResponse = sendResponse.bind(self,request,response);
// Get the principals authorized to access this resource
state.authorizationType = options.authorizationType || this.methodMappings[request.method] || "readers";
@@ -294,12 +285,6 @@ Server.prototype.requestHandler = function(request,response,options) {
response.end();
return;
}
// Reply to OPTIONS
if(this.corsEnable && request.method === "OPTIONS") {
response.writeHead(204);
response.end();
return;
}
// Find the route that matches this path
var route = self.findMatchingRoute(request,state);
// Optionally output debug info
+2 -2
View File
@@ -6,7 +6,6 @@ Appearance/Caption: Appearance
Appearance/Hint: Ways to customise the appearance of your TiddlyWiki.
Basics/AnimDuration/Prompt: Animation duration
Basics/AutoFocus/Prompt: Default focus field for new tiddlers
Basics/AutoFocusEdit/Prompt: Default focus field for existing tiddlers
Basics/Caption: Basics
Basics/DefaultTiddlers/BottomHint: Use &#91;&#91;double square brackets&#93;&#93; for titles with spaces. Or you can choose to {{retain story ordering||$:/snippets/retain-story-ordering-button}}
Basics/DefaultTiddlers/Prompt: Default tiddlers
@@ -58,10 +57,11 @@ 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
Palette/CustomSettings/Prompt: Custom settings for current palette: <<palette-link>>
Palette/Editor/Clone/Caption: clone
Palette/Editor/Clone/Prompt: It is recommended that you clone this shadow palette before editing it
Palette/Editor/Delete/Hint: delete this entry from the current palette
Palette/Editor/Names/External/Show: Show color names that are not part of the current palette
Palette/Editor/Names/External/Show: Show inherited palette entries
Palette/Editor/Prompt/Modified: This shadow palette has been modified
Palette/Editor/Prompt: Editing
Palette/Editor/Reset/Caption: reset
-4
View File
@@ -1,4 +0,0 @@
title: $:/language/Draft/
Attribution: Draft of '<<draft-title>>' by {{$:/status/UserName}}
Title: Draft of '<<draft-title>>'
+1
View File
@@ -30,6 +30,7 @@ Error/DeserializeOperator/MissingOperand: Filter Error: Missing operand for 'des
Error/DeserializeOperator/UnknownDeserializer: Filter Error: Unknown deserializer provided as operand for the 'deserialize' operator
Error/Filter: Filter error
Error/FilterSyntax: Syntax error in filter expression
Error/FilterPragma: Filter Error: Unknown filter pragma
Error/FilterRunPrefix: Filter Error: Unknown prefix for filter run
Error/IsFilterOperator: Filter Error: Unknown parameter for the 'is' filter operator
Error/FormatFilterOperator: Filter Error: Unknown suffix for the 'format' filter operator
-5
View File
@@ -9,11 +9,6 @@ Advanced/ShadowInfo/NotShadow/Hint: The tiddler <$link to=<<infoTiddler>>><$text
Advanced/ShadowInfo/Shadow/Hint: The tiddler <$link to=<<infoTiddler>>><$text text=<<infoTiddler>>/></$link> is a shadow tiddler
Advanced/ShadowInfo/Shadow/Source: It is defined in the plugin <$link to=<<pluginTiddler>>><$text text=<<pluginTiddler>>/></$link>
Advanced/ShadowInfo/OverriddenShadow/Hint: It is overridden by an ordinary tiddler
Advanced/CascadeInfo/Heading: Cascade Details
Advanced/CascadeInfo/Hint: These are the view template segments (tagged <<tag "$:/tags/ViewTemplate">>) using a cascade filter and their resulting template for the current tiddler.
Advanced/CascadeInfo/Detail/View: View
Advanced/CascadeInfo/Detail/ActiveCascadeFilter: Active cascade filter
Advanced/CascadeInfo/Detail/Template: Template
Fields/Caption: Fields
List/Caption: List
List/Empty: This tiddler does not have a list
+11 -1
View File
@@ -2,6 +2,9 @@
title: $:/core/modules/background-actions.js
type: application/javascript
module-type: global
Class to dispatch actions when filters change
\*/
"use strict";
@@ -12,7 +15,7 @@ class BackgroundActionDispatcher {
this.wiki = wiki;
this.nextTrackedFilterId = 1;
this.trackedFilters = new Map(); // Use Map for better key management
// Track the filter for the background actions
this.filterTracker.track({
filterString: "[all[tiddlers+shadows]tag[$:/tags/BackgroundAction]!is[draft]]",
fnEnter: title => this.trackFilter(title),
@@ -53,6 +56,13 @@ class BackgroundActionDispatcher {
}
}
/*
Represents an individual tracked filter. Options include:
wiki: wiki to use
title: title of the tiddler being tracked
trackFilter: filter string to track changes
actions: actions to be executed when the filter changes
*/
class BackgroundActionTracker {
constructor({wiki, title, trackFilter, actions}) {
this.wiki = wiki;
+3
View File
@@ -2,6 +2,9 @@
title: $:/core/modules/config.js
type: application/javascript
module-type: config
Core configuration constants
\*/
"use strict";
+26 -5
View File
@@ -2,6 +2,9 @@
title: $:/core/modules/deserializers.js
type: application/javascript
module-type: tiddlerdeserializer
Functions to deserialise tiddlers from a block of text
\*/
"use strict";
@@ -34,6 +37,12 @@ exports["application/json"] = function(text,fields) {
return results;
};
/*
Parse an HTML file into tiddlers. There are three possibilities:
# A TiddlyWiki classic HTML file containing `text/x-tiddlywiki` tiddlers
# A TiddlyWiki5 HTML file containing `text/vnd.tiddlywiki` tiddlers
# An ordinary HTML file
*/
exports["text/html"] = function(text,fields) {
var results = [];
// Check if we've got an old-style store area
@@ -51,11 +60,11 @@ exports["text/html"] = function(text,fields) {
results.push.apply(results,deserializeNewStoreArea(text,newStoreAreaMarkerRegExp.lastIndex,newStoreAreaMatch[1],fields));
newStoreAreaMatch = newStoreAreaMarkerRegExp.exec(text);
}
// Return if we had either an old-style or a new-style store area
if(storeAreaMatch || haveHadNewStoreArea) {
return results;
}
// Otherwise, check whether we've got an encrypted file
var encryptedStoreArea = $tw.utils.extractEncryptedStoreArea(text);
if(encryptedStoreArea) {
// If so, attempt to decrypt it using the current password
@@ -115,18 +124,30 @@ function deserializeStoreArea(text,storeAreaEnd,isTiddlyWiki5,fields) {
return results;
}
var deserializeTiddlerDiv = function(text) {
/*
Utility function to parse an old-style tiddler DIV in a *.tid file. It looks like this:
<div title="Title" creator="JoeBloggs" modifier="JoeBloggs" created="201102111106" modified="201102111310" tags="myTag [[my long tag]]">
<pre>The text of the tiddler (without the expected HTML encoding).
</pre>
</div>
Note that the field attributes are HTML encoded, but that the body of the <PRE> tag is not encoded.
When these tiddler DIVs are encountered within a TiddlyWiki HTML file then the body is encoded in the usual way.
*/
var deserializeTiddlerDiv = function(text /* [,fields] */) {
// Slot together the default results
var result = {};
if(arguments.length > 1) {
for(var f=1; f<arguments.length; f++) {
var fields = arguments[f];
for(var t in fields) {
result[t] = fields[t];
result[t] = fields[t];
}
}
}
// Parse the DIV body
var startRegExp = /^\s*<div\s+([^>]*)>(\s*<pre>)?/gi,
endRegExp,
match = startRegExp.exec(text);
+41 -5
View File
@@ -2,6 +2,9 @@
title: $:/core/modules/editor/engines/framed.js
type: application/javascript
module-type: library
Text editor engine based on a simple input or textarea within an iframe. This is done so that the selection is preserved even when clicking away from the textarea
\*/
"use strict";
@@ -28,7 +31,7 @@ function FramedEngine(options) {
this.parentNode.insertBefore(this.iframeNode,this.nextSibling);
this.iframeDoc = this.iframeNode.contentWindow.document;
// (Firefox requires us to put some empty content in the iframe)
var paletteTitle = this.widget.wiki.getTiddlerText("$:/palette");
var paletteTitle = this.widget.wiki.getTiddlerText("$:/palette/palette-colours");
var colorScheme = (this.widget.wiki.getTiddler(paletteTitle) || {fields: {}}).fields["color-scheme"] || "light";
this.iframeDoc.open();
this.iframeDoc.write("<!DOCTYPE html><html><head><meta name='color-scheme' content='" + colorScheme + "'></head><body></body></html>");
@@ -53,7 +56,7 @@ function FramedEngine(options) {
} else {
this.domNode.value = this.value;
}
// Set the attributes
if(this.widget.editType && this.widget.editTag !== "textarea") {
this.domNode.setAttribute("type",this.widget.editType);
}
@@ -75,7 +78,7 @@ function FramedEngine(options) {
if(this.widget.isDisabled === "yes") {
this.domNode.setAttribute("disabled",true);
}
// Copy the styles from the dummy textarea
this.copyStyles();
// Add event listeners
$tw.utils.addEventListeners(this.domNode,[
@@ -96,10 +99,13 @@ function FramedEngine(options) {
{name: "click",handlerObject: this.widget,handlerMethod: "handleClickEvent"}
]);
}
// Insert the element into the DOM
this.iframeDoc.body.appendChild(this.domNode);
}
/*
Copy styles from the dummy text area to the textarea in the iframe
*/
FramedEngine.prototype.copyStyles = function() {
// Copy all styles
$tw.utils.copyStyles(this.dummyTextArea,this.domNode);
@@ -121,11 +127,14 @@ FramedEngine.prototype.setText = function(text,type) {
if(this.domNode.ownerDocument.activeElement !== this.domNode) {
this.updateDomNodeText(text);
}
// Fix the height if needed
this.fixHeight();
}
};
/*
Update the DomNode with the new text
*/
FramedEngine.prototype.updateDomNodeText = function(text) {
try {
this.domNode.value = text;
@@ -134,10 +143,16 @@ FramedEngine.prototype.updateDomNodeText = function(text) {
}
};
/*
Get the text of the engine
*/
FramedEngine.prototype.getText = function() {
return this.domNode.value;
};
/*
Fix the height of textarea to fit content
*/
FramedEngine.prototype.fixHeight = function() {
// Make sure styles are updated
this.copyStyles();
@@ -157,6 +172,9 @@ FramedEngine.prototype.fixHeight = function() {
}
};
/*
Focus the engine node
*/
FramedEngine.prototype.focus = function() {
if(this.domNode.focus) {
this.domNode.focus();
@@ -166,12 +184,18 @@ FramedEngine.prototype.focus = function() {
}
};
/*
Handle a focus event
*/
FramedEngine.prototype.handleFocusEvent = function(event) {
if(this.widget.editCancelPopups) {
$tw.popup.cancel(0);
}
};
/*
Handle a keydown event
*/
FramedEngine.prototype.handleKeydownEvent = function(event) {
if ($tw.keyboardManager.handleKeydownEvent(event, {onlyPriority: true})) {
return true;
@@ -180,11 +204,17 @@ FramedEngine.prototype.handleKeydownEvent = function(event) {
return this.widget.handleKeydownEvent(event);
};
/*
Handle a click
*/
FramedEngine.prototype.handleClickEvent = function(event) {
this.fixHeight();
return true;
};
/*
Handle a dom "input" event which occurs when the text has changed
*/
FramedEngine.prototype.handleInputEvent = function(event) {
this.widget.saveChanges(this.getText());
this.fixHeight();
@@ -194,6 +224,9 @@ FramedEngine.prototype.handleInputEvent = function(event) {
return true;
};
/*
Create a blank structure representing a text operation
*/
FramedEngine.prototype.createTextOperation = function() {
var operation = {
text: this.domNode.value,
@@ -209,6 +242,9 @@ FramedEngine.prototype.createTextOperation = function() {
return operation;
};
/*
Execute a text operation
*/
FramedEngine.prototype.executeTextOperation = function(operation) {
// Perform the required changes to the text area and the underlying tiddler
var newText = operation.text;
+42 -4
View File
@@ -2,6 +2,9 @@
title: $:/core/modules/editor/engines/simple.js
type: application/javascript
module-type: library
Text editor engine based on a simple input or textarea tag
\*/
"use strict";
@@ -25,9 +28,14 @@ function SimpleEngine(options) {
if(this.widget.editTag === "textarea") {
this.domNode.appendChild(this.widget.document.createTextNode(this.value));
} else {
this.domNode.value = this.value;
if(this.widget.editType === "color") {
// The <input type="color"> element requires a six digit hex value
this.domNode.value = $tw.utils.convertCSSColorToRGBString(this.value);
} else {
this.domNode.value = this.value;
}
}
// Set the attributes
if(this.widget.editType && this.widget.editTag !== "textarea") {
this.domNode.setAttribute("type",this.widget.editType);
}
@@ -52,7 +60,7 @@ function SimpleEngine(options) {
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"},
{name: "input", handlerObject: this, handlerMethod: "handleInputEvent"}
@@ -62,28 +70,43 @@ function SimpleEngine(options) {
this.widget.domNodes.push(this.domNode);
}
/*
Set the text of the engine if it doesn't currently have focus
*/
SimpleEngine.prototype.setText = function(text,type) {
if(!this.domNode.isTiddlyWikiFakeDom) {
if(this.domNode.ownerDocument.activeElement !== this.domNode || text === "") {
this.updateDomNodeText(text);
}
// Fix the height if needed
this.fixHeight();
}
};
/*
Update the DomNode with the new text
*/
SimpleEngine.prototype.updateDomNodeText = function(text) {
try {
if(this.widget.editType === "color") {
text = $tw.utils.convertCSSColorToRGBString(text);
}
this.domNode.value = text;
} catch(e) {
// Ignore
}
};
/*
Get the text of the engine
*/
SimpleEngine.prototype.getText = function() {
return this.domNode.value;
};
/*
Fix the height of textarea to fit content
*/
SimpleEngine.prototype.fixHeight = function() {
// If .editRows is initialised, it takes precedence
if((this.widget.editTag === "textarea") && !this.widget.editRows) {
@@ -99,6 +122,9 @@ SimpleEngine.prototype.fixHeight = function() {
}
};
/*
Focus the engine node
*/
SimpleEngine.prototype.focus = function() {
if(this.domNode.focus) {
this.domNode.focus();
@@ -108,6 +134,9 @@ SimpleEngine.prototype.focus = function() {
}
};
/*
Handle a dom "input" event which occurs when the text has changed
*/
SimpleEngine.prototype.handleInputEvent = function(event) {
this.widget.saveChanges(this.getText());
this.fixHeight();
@@ -117,6 +146,9 @@ SimpleEngine.prototype.handleInputEvent = function(event) {
return true;
};
/*
Handle a dom "focus" event
*/
SimpleEngine.prototype.handleFocusEvent = function(event) {
if(this.widget.editCancelPopups) {
$tw.popup.cancel(0);
@@ -132,10 +164,16 @@ SimpleEngine.prototype.handleFocusEvent = function(event) {
return true;
};
/*
Create a blank structure representing a text operation
*/
SimpleEngine.prototype.createTextOperation = function() {
return null;
};
/*
Execute a text operation
*/
SimpleEngine.prototype.executeTextOperation = function(operation) {
};
+41 -10
View File
@@ -2,12 +2,16 @@
title: $:/core/modules/editor/factory.js
type: application/javascript
module-type: library
Factory for constructing text editor widgets with specified engines for the toolbar and non-toolbar cases
\*/
"use strict";
var DEFAULT_MIN_TEXT_AREA_HEIGHT = "100px"; // Minimum height of textareas in pixels
// Configuration tiddlers
var HEIGHT_MODE_TITLE = "$:/config/TextEditor/EditorHeight/Mode";
var ENABLE_TOOLBAR_TITLE = "$:/config/TextEditor/EnableToolbar";
@@ -44,8 +48,8 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
this.toolbarNode = this.document.createElement("div");
this.toolbarNode.className = "tc-editor-toolbar";
parent.insertBefore(this.toolbarNode,nextSibling);
this.domNodes.push(this.toolbarNode);
this.renderChildren(this.toolbarNode,null);
this.domNodes.push(this.toolbarNode);
}
// Create our element
var editInfo = this.getEditInfo(),
@@ -137,6 +141,9 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
return {value: value || "", type: type, update: update};
};
/*
Handle an edit text operation message from the toolbar
*/
EditTextWidget.prototype.handleEditTextOperationMessage = function(event) {
// Prepare information about the operation
var operation = this.engine.createTextOperation();
@@ -145,13 +152,16 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
if(handler) {
handler.call(this,event,operation);
}
// Execute the operation via the engine
var newText = this.engine.executeTextOperation(operation);
// Fix the tiddler height and save changes
this.engine.fixHeight();
this.saveChanges(newText);
};
/*
Compute the internal state of the widget
*/
EditTextWidget.prototype.execute = function() {
// Get our parameters
this.editTitle = this.getAttribute("tiddler",this.getVariable("currentTiddler"));
@@ -191,7 +201,7 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
}
type = type || "text";
}
// Get the rest of our parameters
this.editTag = this.getAttribute("tag",tag) || "input";
this.editType = this.getAttribute("type",type);
// Make the child widgets
@@ -201,15 +211,16 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
this.editShowToolbar = (this.editShowToolbar === "yes") && !!(this.children && this.children.length > 0) && (!this.document.isTiddlyWikiFakeDom);
};
/*
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/
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 || changedAttributes.autocomplete || changedTiddlers[HEIGHT_MODE_TITLE] || changedTiddlers[ENABLE_TOOLBAR_TITLE] || changedTiddlers["$:/palette"] || changedAttributes.disabled || changedAttributes.fileDrop) {
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || 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] || changedTiddlers["$:/palette"] || changedAttributes.disabled || changedAttributes.fileDrop) {
this.refreshSelf();
return true;
} else if (changedTiddlers[this.editRefreshTitle]) {
this.engine.updateDomNodeText(this.getEditInfo().value);
} else if(changedTiddlers[this.editTitle]) {
} else if(changedAttributes["default"] || changedTiddlers[this.editRefreshTitle] || changedTiddlers[this.editTitle]) {
var editInfo = this.getEditInfo();
this.updateEditor(editInfo.value,editInfo.type);
}
@@ -221,14 +232,24 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
}
};
/*
Update the editor with new text. This method is separate from updateEditorDomNode()
so that subclasses can override updateEditor() and still use updateEditorDomNode()
*/
EditTextWidget.prototype.updateEditor = function(text,type) {
this.updateEditorDomNode(text,type);
};
/*
Update the editor dom node with new text
*/
EditTextWidget.prototype.updateEditorDomNode = function(text,type) {
this.engine.setText(text,type);
};
/*
Save changes back to the tiddler store
*/
EditTextWidget.prototype.saveChanges = function(text) {
var editInfo = this.getEditInfo();
if(text !== editInfo.value) {
@@ -236,6 +257,9 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
}
};
/*
Handle a dom "keydown" event, which we'll bubble up to our container for the keyboard widgets benefit
*/
EditTextWidget.prototype.handleKeydownEvent = function(event) {
// Check for a keyboard shortcut
if(this.toolbarNode) {
@@ -256,17 +280,20 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
}
}
}
// Propogate the event to the container
if(this.propogateKeydownEvent(event)) {
// Ignore the keydown if it was already handled
event.preventDefault();
event.stopPropagation();
return true;
}
// Otherwise, process the keydown normally
return false;
};
/*
Propogate keydown events to our container for the keyboard widgets benefit
*/
EditTextWidget.prototype.propogateKeydownEvent = function(event) {
var newEvent = this.cloneEvent(event,["keyCode","code","which","key","metaKey","ctrlKey","altKey","shiftKey"]);
return !this.parentDomNode.dispatchEvent(newEvent);
@@ -289,12 +316,16 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
return dispatchNode.dispatchEvent(newEvent);
};
/*
Propogate drag and drop events with File data to our container for the dropzone widgets benefit.
If there are no Files, let the browser handle it.
*/
EditTextWidget.prototype.handleDropEvent = function(event) {
if($tw.utils.dragEventContainsFiles(event)) {
event.preventDefault();
event.stopPropagation();
this.dispatchDOMEvent(this.cloneEvent(event,["dataTransfer"]));
}
}
};
EditTextWidget.prototype.handlePasteEvent = function(event) {
@@ -2,6 +2,9 @@
title: $:/core/modules/editor/operations/bitmap/clear.js
type: application/javascript
module-type: bitmapeditoroperation
Bitmap editor operation to clear the image
\*/
"use strict";
@@ -2,6 +2,9 @@
title: $:/core/modules/editor/operations/bitmap/resize.js
type: application/javascript
module-type: bitmapeditoroperation
Bitmap editor operation to resize the image
\*/
"use strict";
@@ -14,7 +17,7 @@ exports["resize"] = function(event) {
if(newWidth > 0 && newHeight > 0 && !(newWidth === this.currCanvas.width && newHeight === this.currCanvas.height)) {
this.changeCanvasSize(newWidth,newHeight);
}
// Update the input controls
this.refreshToolbar();
// Save the image into the tiddler
this.saveChanges();
@@ -2,6 +2,9 @@
title: $:/core/modules/editor/operations/bitmap/rotate-left.js
type: application/javascript
module-type: bitmapeditoroperation
Bitmap editor operation to rotate the image left by 90 degrees
\*/
"use strict";
@@ -2,6 +2,9 @@
title: $:/core/modules/editor/operations/text/excise.js
type: application/javascript
module-type: texteditoroperation
Text editor operation to excise the selection to a new tiddler
\*/
"use strict";
@@ -2,6 +2,9 @@
title: $:/core/modules/editor/operations/text/insert-text.js
type: application/javascript
module-type: texteditoroperation
Text editor operation insert text at the caret position. If there is a selection it is replaced.
\*/
"use strict";
@@ -2,6 +2,9 @@
title: $:/core/modules/editor/operations/text/make-link.js
type: application/javascript
module-type: texteditoroperation
Text editor operation to make a link
\*/
"use strict";
@@ -2,6 +2,9 @@
title: $:/core/modules/editor/operations/text/prefix-lines.js
type: application/javascript
module-type: texteditoroperation
Text editor operation to add a prefix to the selected lines
\*/
"use strict";
@@ -23,16 +26,16 @@ exports["prefix-lines"] = function(event,operation) {
line = line.substring(event.paramObject.character.length);
count++;
}
// Remove any whitespace
while(line.charAt(0) === " ") {
line = line.substring(1);
}
// We're done if we removed the exact required prefix, otherwise add it
if(count !== targetCount) {
// Apply the prefix
line = prefix + " " + line;
}
// Save the modified line
lines[index] = line;
});
// Stitch the replacement text together and set the selection
@@ -2,6 +2,9 @@
title: $:/core/modules/editor/operations/text/replace-all.js
type: application/javascript
module-type: texteditoroperation
Text editor operation to replace the entire text
\*/
"use strict";
@@ -2,6 +2,9 @@
title: $:/core/modules/editor/operations/text/replace-selection.js
type: application/javascript
module-type: texteditoroperation
Text editor operation to replace the selection
\*/
"use strict";
@@ -2,6 +2,9 @@
title: $:/core/modules/editor/operations/text/save-selection.js
type: application/javascript
module-type: texteditoroperation
Text editor operation to save the current selection in a specified tiddler
\*/
"use strict";
@@ -2,6 +2,9 @@
title: $:/core/modules/editor/operations/text/wrap-lines.js
type: application/javascript
module-type: texteditoroperation
Text editor operation to wrap the selected lines with a prefix and suffix
\*/
"use strict";
@@ -12,14 +15,14 @@ exports["wrap-lines"] = function(event,operation) {
if($tw.utils.endsWith(operation.text.substring(0,operation.selStart), prefix + "\n") &&
$tw.utils.startsWith(operation.text.substring(operation.selEnd), "\n" + suffix)) {
// Selected text is already surrounded by prefix and suffix: Remove them
// Cut selected text plus prefix and suffix
operation.cutStart = operation.selStart - (prefix.length + 1);
operation.cutEnd = operation.selEnd + suffix.length + 1;
// Also cut the following newline (if there is any)
if (operation.text[operation.cutEnd] === "\n") {
operation.cutEnd++;
}
// Replace with selection
operation.replacement = operation.text.substring(operation.selStart,operation.selEnd);
// Select text that was in between prefix and suffix
operation.newSelStart = operation.cutStart;
@@ -2,6 +2,9 @@
title: $:/core/modules/editor/operations/text/wrap-selection.js
type: application/javascript
module-type: texteditoroperation
Text editor operation to wrap the selection with the specified prefix and suffix
\*/
"use strict";
@@ -14,11 +17,11 @@ exports["wrap-selection"] = function(event,operation) {
selLength = o.selEnd - o.selStart;
// This function detects, if trailing spaces are part of the selection __and__ if the user wants to handle them
// Returns "yes", "start", "end", "no" (default)
// yes .. there are trailing spaces at both ends
// start .. there are trailing spaces at the start
// end .. there are trailing spaces at the end
// no .. no trailing spaces are taken into account
var trailingSpaceAt = function(sel) {
var _start,
_end,
@@ -61,6 +64,7 @@ exports["wrap-selection"] = function(event,operation) {
}
}
// options: lenPrefix, lenSuffix
function removePrefixSuffix(options) {
options = options || {};
var _lenPrefix = options.lenPrefix || 0;
+11
View File
@@ -2,6 +2,9 @@
title: $:/core/modules/filter-tracker.js
type: application/javascript
module-type: global
Class to track the results of a filter string
\*/
"use strict";
@@ -18,6 +21,14 @@ class FilterTracker {
this.processChanges(changes);
}
/*
Add a tracker to the filter tracker. Returns null if any of the parameters are invalid, or a tracker id if the tracker was added successfully. Options include:
filterString: the filter string to track
fnEnter: function to call when a title enters the filter results. Called even if the tiddler does not actually exist. Called as (title), and should return a truthy value that is stored in the tracker as the "enterValue"
fnLeave: function to call when a title leaves the filter results. Called as (title,enterValue)
fnChange: function to call when a tiddler changes in the filter results. Only called for filter results that identify a tiddler or shadow tiddler. Called as (title,enterValue), and may optionally return a replacement enterValue
fnProcess: function to call each time the tracker is processed, after any enter, leave or change functions are called. Called as (changes)
*/
track(options = {}) {
const {
filterString,
+7
View File
@@ -2,10 +2,17 @@
title: $:/core/modules/filterrunprefixes/all.js
type: application/javascript
module-type: filterrunprefix
Union of sets without de-duplication.
Equivalent to = filter run prefix.
\*/
"use strict";
/*
Export our filter prefix function
*/
exports.all = function(operationSubFunction) {
return function(results,source,widget) {
results.push.apply(results, operationSubFunction(source,widget));
+7
View File
@@ -2,10 +2,17 @@
title: $:/core/modules/filterrunprefixes/and.js
type: application/javascript
module-type: filterrunprefix
Intersection of sets.
Equivalent to + filter run prefix.
\*/
"use strict";
/*
Export our filter prefix function
*/
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
+4 -1
View File
@@ -6,6 +6,9 @@ module-type: filterrunprefix
"use strict";
/*
Export our filter prefix function
*/
exports.cascade = function(operationSubFunction,options) {
return function(results,source,widget) {
if(results.length !== 0) {
@@ -21,7 +24,7 @@ exports.cascade = function(operationSubFunction,options) {
}
var output = filterFnList[index](options.wiki.makeTiddlerIterator([title]),widget.makeFakeWidgetWithVariables({
"currentTiddler": "" + title,
"..currentTiddler": widget.getVariable("currentTiddler",{defaultValue:""})
"..currentTiddler": widget.getVariable("currentTiddler","")
}));
if(output.length !== 0) {
result = output[0];
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filterrunprefixes/else.js
type: application/javascript
module-type: filterrunprefix
Equivalent to ~ filter run prefix.
\*/
"use strict";
/*
Export our filter prefix function
*/
exports.else = function(operationSubFunction) {
return function(results,source,widget) {
if(results.length === 0) {
+7
View File
@@ -2,10 +2,17 @@
title: $:/core/modules/filterrunprefixes/except.js
type: application/javascript
module-type: filterrunprefix
Difference of sets.
Equivalent to - filter run prefix.
\*/
"use strict";
/*
Export our filter prefix function
*/
exports.except = function(operationSubFunction) {
return function(results,source,widget) {
results.remove(operationSubFunction(source,widget));
+5 -1
View File
@@ -2,10 +2,14 @@
title: $:/core/modules/filterrunprefixes/filter.js
type: application/javascript
module-type: filterrunprefix
\*/
"use strict";
/*
Export our filter function
*/
exports.filter = function(operationSubFunction,options) {
return function(results,source,widget) {
if(results.length > 0) {
@@ -14,7 +18,7 @@ exports.filter = function(operationSubFunction,options) {
results.each(function(title) {
var filtered = operationSubFunction(options.wiki.makeTiddlerIterator([title]),widget.makeFakeWidgetWithVariables({
"currentTiddler": "" + title,
"..currentTiddler": widget.getVariable("currentTiddler",{defaultValue:""}),
"..currentTiddler": widget.getVariable("currentTiddler",""),
"index": "" + index,
"revIndex": "" + (results.length - 1 - index),
"length": "" + results.length
@@ -2,10 +2,14 @@
title: $:/core/modules/filterrunprefixes/intersection.js
type: application/javascript
module-type: filterrunprefix
\*/
"use strict";
/*
Export our filter prefix function
*/
exports.intersection = function(operationSubFunction) {
return function(results,source,widget) {
if(results.length !== 0) {
+9 -1
View File
@@ -2,10 +2,18 @@
title: $:/core/modules/filterrunprefixes/let.js
type: application/javascript
module-type: filterrunprefix
Assign a value to a variable
\*/
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter prefix function
*/
exports.let = function(operationSubFunction,options) {
// Return the filter run prefix function
return function(results,source,widget) {
@@ -22,7 +30,7 @@ exports.let = function(operationSubFunction,options) {
if(typeof name !== "string" || name.length === 0) {
return;
}
// Assign the result of the subfunction to the variable
var variables = {};
variables[name] = resultList;
// Return the variables
+4 -1
View File
@@ -6,6 +6,9 @@ module-type: filterrunprefix
"use strict";
/*
Export our filter prefix function
*/
exports.map = function(operationSubFunction,options) {
return function(results,source,widget) {
if(results.length > 0) {
@@ -17,7 +20,7 @@ exports.map = function(operationSubFunction,options) {
$tw.utils.each(inputTitles,function(title) {
var filtered = operationSubFunction(options.wiki.makeTiddlerIterator([title]),widget.makeFakeWidgetWithVariables({
"currentTiddler": "" + title,
"..currentTiddler": widget.getVariable("currentTiddler",{defaultValue:""}),
"..currentTiddler": widget.getVariable("currentTiddler",""),
"index": "" + index,
"revIndex": "" + (inputTitles.length - 1 - index),
"length": "" + inputTitles.length
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filterrunprefixes/or.js
type: application/javascript
module-type: filterrunprefix
Equivalent to a filter run with no prefix.
\*/
"use strict";
/*
Export our filter prefix function
*/
exports.or = function(operationSubFunction) {
return function(results,source,widget) {
results.pushTop(operationSubFunction(source,widget));
+4 -1
View File
@@ -6,6 +6,9 @@ module-type: filterrunprefix
"use strict";
/*
Export our filter prefix function
*/
exports.reduce = function(operationSubFunction,options) {
return function(results,source,widget) {
if(results.length > 0) {
@@ -14,7 +17,7 @@ exports.reduce = function(operationSubFunction,options) {
results.each(function(title) {
var list = operationSubFunction(options.wiki.makeTiddlerIterator([title]),widget.makeFakeWidgetWithVariables({
"currentTiddler": "" + title,
"..currentTiddler": widget.getVariable("currentTiddler",{defaultValue:""}),
"..currentTiddler": widget.getVariable("currentTiddler"),
"index": "" + index,
"revIndex": "" + (results.length - 1 - index),
"length": "" + results.length,
+6 -2
View File
@@ -2,10 +2,14 @@
title: $:/core/modules/filterrunprefixes/sort.js
type: application/javascript
module-type: filterrunprefix
\*/
"use strict";
/*
Export our filter prefix function
*/
exports.sort = function(operationSubFunction,options) {
return function(results,source,widget) {
if(results.length > 0) {
@@ -20,7 +24,7 @@ exports.sort = function(operationSubFunction,options) {
results.each(function(title) {
var key = operationSubFunction(options.wiki.makeTiddlerIterator([title]),widget.makeFakeWidgetWithVariables({
"currentTiddler": "" + title,
"..currentTiddler": widget.getVariable("currentTiddler",{defaultValue:""})
"..currentTiddler": widget.getVariable("currentTiddler")
}));
sortKeys.push(key[0] || "");
});
@@ -29,7 +33,7 @@ exports.sort = function(operationSubFunction,options) {
for(var t=0; t<inputTitles.length; t++) {
indexes[t] = t;
}
// Sort the indexes
compareFn = $tw.utils.makeCompareFunction(sortType,{defaultType: "string", invert:invert, isCaseSensitive:isCaseSensitive});
indexes = indexes.sort(function(a,b) {
return compareFn(sortKeys[a],sortKeys[b]);
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filterrunprefixes/then.js
type: application/javascript
module-type: filterrunprefix
Replace results of previous runs unless empty
\*/
"use strict";
/*
Export our filter prefix function
*/
exports.then = function(operationSubFunction) {
return function(results,source,widget) {
if(results.length !== 0) {
+122 -71
View File
@@ -2,28 +2,39 @@
title: $:/core/modules/filters.js
type: application/javascript
module-type: wikimethod
Adds tiddler filtering methods to the $tw.Wiki object.
\*/
"use strict";
var widgetClass = require("$:/core/modules/widgets/widget.js").widget;
/* Maximum permitted filter recursion depth */
var MAX_FILTER_DEPTH = 300;
/*
Parses an operation (i.e. a run) within a filter string
operators: Array of array of operator nodes into which results should be inserted
filterString: filter string
p: start position within the string
Returns the new start position, after the parsed operation
*/
function parseFilterOperation(operators,filterString,p) {
var nextBracketPos, operator;
// Skip the starting square bracket
if(filterString.charAt(p++) !== "[") {
throw "Missing [ in filter expression";
}
// Process each operator in turn
do {
operator = {};
// Check for an operator prefix
if(filterString.charAt(p) === "!") {
operator.prefix = filterString.charAt(p++);
}
// Get the operator name
nextBracketPos = filterString.substring(p).search(/[\[\{<\/\(]/);
if(nextBracketPos === -1) {
throw "Missing [ in filter expression";
@@ -44,12 +55,12 @@ function parseFilterOperation(operators,filterString,p) {
$tw.utils.each(subsuffix.split(","),function(entry) {
entry = $tw.utils.trim(entry);
if(entry) {
operator.suffixes[operator.suffixes.length - 1].push(entry);
operator.suffixes[operator.suffixes.length - 1].push(entry);
}
});
});
}
// Empty operator means: title
else if(operator.operator === "") {
operator.operator = "title";
}
@@ -77,8 +88,8 @@ function parseFilterOperation(operators,filterString,p) {
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);
// DEPRECATION WARNING
console.log("WARNING: Filter",operator.operator,"has a deprecated regexp operand",operator.regexp);
nextBracketPos = p + rex.lastIndex - 1;
}
else {
@@ -114,16 +125,20 @@ function parseFilterOperation(operators,filterString,p) {
}
}
// Push this operator
operators.push(operator);
} while(filterString.charAt(p) !== "]");
// Skip the ending square bracket
if(filterString.charAt(p++) !== "]") {
throw "Missing ] in filter expression";
}
// Return the parsing position
return p;
}
/*
Parse a filter string
*/
exports.parseFilter = function(filterString) {
filterString = filterString || "";
var results = [], // Array of arrays of operator nodes {operator:,operand:}
@@ -131,14 +146,16 @@ exports.parseFilter = function(filterString) {
match;
var whitespaceRegExp = /(\s+)/mg,
// Groups:
// 1 - entire filter run prefix
// 3 - filter run prefix suffixes
// 5 - double quoted string following filter run prefix
// 7 - anything except for whitespace and square brackets
operandRegExp = /((?:\+|\-|~|(?:=>?)|\:(\w+)(?:\:([\w\:, ]*))?)?)(?:(\[)|(?:"([^"]*)")|(?:'([^']*)')|([^\s\[\]]+))/mg;
// 1 - pragma
// 2 - pragma suffix
// 3 - entire filter run prefix
// 4 - filter run prefix name
// 5 - filter run prefix suffixes
// 6 - opening square bracket following filter run prefix
// 7 - double quoted string following filter run prefix
// 8 - single quoted string following filter run prefix
// 9 - anything except for whitespace and square brackets
operandRegExp = /(?:::(\w+)(?:\:(\w+))?(?=\s|$)|((?:\+|\-|~|(?:=>?)|:(\w+)(?:\:([\w\:, ]*))?)?)(?:(\[)|(?:"([^"]*)")|(?:'([^']*)')|([^\s\[\]]+)))/mg;
while(p < filterString.length) {
// Skip any whitespace
whitespaceRegExp.lastIndex = p;
@@ -146,7 +163,7 @@ exports.parseFilter = function(filterString) {
if(match && match.index === p) {
p = p + match[0].length;
}
// Match the start of the operation
if(p < filterString.length) {
operandRegExp.lastIndex = p;
var operation = {
@@ -155,18 +172,23 @@ exports.parseFilter = function(filterString) {
};
match = operandRegExp.exec(filterString);
if(match && match.index === p) {
// If there is a filter run prefix
if(match[1]) {
operation.prefix = match[1];
// If there is a filter pragma
operation.pragma = match[1];
operation.suffix = match[2];
p = match.index + match[0].length;
} else if(match[3]) {
// If there is a filter run prefix
operation.prefix = match[3];
p = p + operation.prefix.length;
// Name for named prefixes
if(match[2]) {
operation.namedPrefix = match[2];
if(match[4]) {
operation.namedPrefix = match[4];
}
if(match[3]) {
// Suffixes for filter run prefix
if(match[5]) {
operation.suffixes = [];
$tw.utils.each(match[3].split(":"),function(subsuffix) {
$tw.utils.each(match[5].split(":"),function(subsuffix) {
operation.suffixes.push([]);
$tw.utils.each(subsuffix.split(","),function(entry) {
entry = $tw.utils.trim(entry);
@@ -177,8 +199,8 @@ exports.parseFilter = function(filterString) {
});
}
}
if(match[4]) {
// Opening square bracket
if(match[6]) {
p = parseFilterOperation(operation.operators,filterString,p);
} else {
p = match.index + match[0].length;
@@ -187,10 +209,10 @@ exports.parseFilter = function(filterString) {
// No filter run prefix
p = parseFilterOperation(operation.operators,filterString,p);
}
if(match[5] || match[6] || match[7]) { // Double quoted string, single quoted string or unquoted title
// Quoted strings and unquoted title
if(match[7] || match[8] || match[9]) { // Double quoted string, single quoted string or unquoted title
operation.operators.push(
{operator: "title", operands: [{text: match[5] || match[6] || match[7]}]}
{operator: "title", operands: [{text: match[7] || match[8] || match[9]}]}
);
}
results.push(operation);
@@ -215,18 +237,30 @@ exports.getFilterRunPrefixes = function() {
return this.filterRunPrefixes;
}
exports.filterTiddlers = function(filterString,widget,source) {
var fn = this.compileFilter(filterString);
return fn.call(this,source,widget);
exports.filterTiddlers = function(filterString,widget,source,options) {
var fn = this.compileFilter(filterString,options);
try {
const fnResult = fn.call(this,source,widget);
return fnResult;
} catch(e) {
return [`${$tw.language.getString("Error/Filter")}: ${e}`];
}
};
exports.compileFilter = function(filterString) {
/*
Compile a filter into a function with the signature fn(source,widget,options) where:
source: an iterator function for the source tiddlers, called source(iterator), where iterator is called as iterator(tiddler,title)
widget: an optional widget node for retrieving the current tiddler etc.
*/
exports.compileFilter = function(filterString,options) {
var defaultFilterRunPrefix = (options || {}).defaultFilterRunPrefix || "or";
var cacheKey = filterString + "|" + defaultFilterRunPrefix;
if(!this.filterCache) {
this.filterCache = Object.create(null);
this.filterCacheCount = 0;
}
if(this.filterCache[filterString] !== undefined) {
return this.filterCache[filterString];
if(this.filterCache[cacheKey] !== undefined) {
return this.filterCache[cacheKey];
}
var filterParseTree;
try {
@@ -237,7 +271,7 @@ exports.compileFilter = function(filterString) {
return [$tw.language.getString("Error/Filter") + ": " + e];
};
}
// Get the hashmap of filter operator functions
var filterOperators = this.getFilterOperators();
// Assemble array of functions, one for each operation
var operationFunctions = [];
@@ -282,7 +316,7 @@ exports.compileFilter = function(filterString) {
operand.value = "";
operand.multiValue = [];
}
operand.isMultiValueOperand = true;
operand.isMultiValueOperand = true;
} else {
operand.value = operand.text;
operand.multiValue = [operand.value];
@@ -294,19 +328,20 @@ exports.compileFilter = function(filterString) {
// Invoke the appropriate filteroperator module
results = operatorFunction(accumulator,{
operator: operator.operator,
operand: operands.length > 0 ? operands[0] : undefined,
operands: operands,
multiValueOperands: multiValueOperands,
isMultiValueOperand: isMultiValueOperand,
prefix: operator.prefix,
suffix: operator.suffix,
suffixes: operator.suffixes,
regexp: operator.regexp
},{
wiki: self,
widget: widget
});
operator: operator.operator,
operand: operands.length > 0 ? operands[0] : undefined,
operands: operands,
multiValueOperands: multiValueOperands,
isMultiValueOperand: isMultiValueOperand,
prefix: operator.prefix,
suffix: operator.suffix,
suffixes: operator.suffixes,
regexp: operator.regexp
},{
wiki: self,
widget: widget,
defaultFilterRunPrefix: defaultFilterRunPrefix
});
if($tw.utils.isArray(results)) {
accumulator = self.makeTiddlerIterator(results);
} else {
@@ -326,29 +361,45 @@ 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, suffixes: operation.suffixes || []};
switch(operation.prefix || "") {
case "": // No prefix means that the operation is unioned into the result
return filterRunPrefixes["or"](operationSubFunction, options);
case "=": // The results of the operation are pushed into the result without deduplication
return filterRunPrefixes["all"](operationSubFunction, options);
case "-": // The results of this operation are removed from the main result
return filterRunPrefixes["except"](operationSubFunction, options);
case "+": // This operation is applied to the main results so far
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, options);
case "=>": // This operation is applied to the main results so far, and the results are assigned to a variable
return filterRunPrefixes["let"](operationSubFunction, options);
default:
if(operation.namedPrefix && filterRunPrefixes[operation.namedPrefix]) {
return filterRunPrefixes[operation.namedPrefix](operationSubFunction, options);
} else {
if(operation.pragma) {
switch(operation.pragma) {
case "defaultprefix":
defaultFilterRunPrefix = operation.suffix || "or";
break;
default:
return function(results,source,widget) {
results.clear();
results.push($tw.language.getString("Error/FilterRunPrefix"));
results.push($tw.language.getString("Error/FilterPragma"));
};
}
}
return function(results,source,widget) {
// Dummy response
};
} else {
var options = {wiki: self, suffixes: operation.suffixes || []};
switch(operation.prefix || "") {
case "": // Use the default filter run prefix if none is specified
return filterRunPrefixes[defaultFilterRunPrefix](operationSubFunction, options);
case "=": // The results of the operation are pushed into the result without deduplication
return filterRunPrefixes["all"](operationSubFunction, options);
case "-": // The results of this operation are removed from the main result
return filterRunPrefixes["except"](operationSubFunction, options);
case "+": // This operation is applied to the main results so far
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, options);
case "=>": // This operation is applied to the main results so far, and the results are assigned to a variable
return filterRunPrefixes["let"](operationSubFunction, options);
default:
if(operation.namedPrefix && filterRunPrefixes[operation.namedPrefix]) {
return filterRunPrefixes[operation.namedPrefix](operationSubFunction, options);
} else {
return function(results,source,widget) {
results.clear();
results.push($tw.language.getString("Error/FilterRunPrefix"));
};
}
}
}
})());
});
@@ -382,12 +433,12 @@ exports.compileFilter = function(filterString) {
});
if(this.filterCacheCount >= 2000) {
// To prevent memory leak, we maintain an upper limit for cache size.
// Reset if exceeded. This should give us 95% of the benefit
// that no cache limit would give us.
this.filterCache = Object.create(null);
this.filterCacheCount = 0;
}
this.filterCache[filterString] = fnMeasured;
this.filterCache[cacheKey] = fnMeasured;
this.filterCacheCount++;
return fnMeasured;
};
+8
View File
@@ -2,10 +2,18 @@
title: $:/core/modules/filters/addprefix.js
type: application/javascript
module-type: filteroperator
Filter operator for adding a prefix to each title in the list. This is
especially useful in contexts where only a filter expression is allowed
and macro substitution isn't available.
\*/
"use strict";
/*
Export our filter function
*/
exports.addprefix = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
+8
View File
@@ -2,10 +2,18 @@
title: $:/core/modules/filters/addsuffix.js
type: application/javascript
module-type: filteroperator
Filter operator for adding a suffix to each title in the list. This is
especially useful in contexts where only a filter expression is allowed
and macro substitution isn't available.
\*/
"use strict";
/*
Export our filter function
*/
exports.addsuffix = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/after.js
type: application/javascript
module-type: filteroperator
Filter operator returning the tiddler from the current list that is after the tiddler named in the operand.
\*/
"use strict";
/*
Export our filter function
*/
exports.after = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
+9 -1
View File
@@ -2,6 +2,11 @@
title: $:/core/modules/filters/all.js
type: application/javascript
module-type: filteroperator
Filter operator for selecting tiddlers
[all[shadows+tiddlers]]
\*/
"use strict";
@@ -16,6 +21,9 @@ function getAllFilterOperators() {
return allFilterOperators;
}
/*
Export our filter function
*/
exports.all = function(source,operator,options) {
// Check for common optimisations
var subops = operator.operand.split("+");
@@ -30,7 +38,7 @@ exports.all = function(source,operator,options) {
} else if(subops.length === 2 && subops[0] === "shadows" && subops[1] === "tiddlers") {
return options.wiki.eachShadowPlusTiddlers;
}
// Do it the hard way
// Get our suboperators
var allFilterOperators = getAllFilterOperators();
// Cycle through the suboperators accumulating their results
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/all/current.js
type: application/javascript
module-type: allfilteroperator
Filter function for [all[current]]
\*/
"use strict";
/*
Export our filter function
*/
exports.current = function(source,prefix,options) {
var currTiddlerTitle = options.widget && options.widget.getVariable("currentTiddler");
if(currTiddlerTitle) {
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/all/missing.js
type: application/javascript
module-type: allfilteroperator
Filter function for [all[missing]]
\*/
"use strict";
/*
Export our filter function
*/
exports.missing = function(source,prefix,options) {
return options.wiki.getMissingTitles();
};
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/all/orphans.js
type: application/javascript
module-type: allfilteroperator
Filter function for [all[orphans]]
\*/
"use strict";
/*
Export our filter function
*/
exports.orphans = function(source,prefix,options) {
return options.wiki.getOrphanTitles();
};
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/all/shadows.js
type: application/javascript
module-type: allfilteroperator
Filter function for [all[shadows]]
\*/
"use strict";
/*
Export our filter function
*/
exports.shadows = function(source,prefix,options) {
return options.wiki.allShadowTitles();
};
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/all/tags.js
type: application/javascript
module-type: allfilteroperator
Filter function for [all[tags]]
\*/
"use strict";
/*
Export our filter function
*/
exports.tags = function(source,prefix,options) {
return Object.keys(options.wiki.getTagMap());
};
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/all/tiddlers.js
type: application/javascript
module-type: allfilteroperator
Filter function for [all[tiddlers]]
\*/
"use strict";
/*
Export our filter function
*/
exports.tiddlers = function(source,prefix,options) {
return options.wiki.allTitles();
};
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/backlinks.js
type: application/javascript
module-type: filteroperator
Filter operator for returning all the backlinks from a tiddler
\*/
"use strict";
/*
Export our filter function
*/
exports.backlinks = function(source,operator,options) {
var results = new $tw.utils.LinkedList();
source(function(tiddler,title) {
+6
View File
@@ -2,9 +2,15 @@
title: $:/core/modules/filters/backtranscludes.js
type: application/javascript
module-type: filteroperator
Filter operator for returning all the backtranscludes from a tiddler
\*/
"use strict";
/*
Export our filter function
*/
exports.backtranscludes = function(source,operator,options) {
var results = new $tw.utils.LinkedList();
source(function(tiddler,title) {
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/before.js
type: application/javascript
module-type: filteroperator
Filter operator returning the tiddler from the current list that is before the tiddler named in the operand.
\*/
"use strict";
/*
Export our filter function
*/
exports.before = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
+21
View File
@@ -0,0 +1,21 @@
/*\
title: $:/core/modules/filters/changecount.js
type: application/javascript
module-type: filteroperator
Filter operator for retrieving the changecount for each title in the list.
\*/
"use strict";
/*
Export our filter function
*/
exports.changecount = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
results.push(options.wiki.getChangeCount(title) + "");
});
return results;
};
+140
View File
@@ -0,0 +1,140 @@
/*\
title: $:/core/modules/filters/colour-ops.js
type: application/javascript
module-type: filteroperator
Filter operators for colour operations
\*/
"use strict";
var Color = require("$:/core/modules/utils/dom/color.js").Color,
colourSpacesList = Object.keys(Color.spaces),
hueAdjustersList = ["raw","increasing","decreasing","longer","shorter"];
exports["colour-lighten"] = makeSerialColourOperator(function (colour, operator, options) {
return colour.lighten($tw.utils.parseNumber(operator.operand)).display().toString();
});
exports["colour-darken"] = makeSerialColourOperator(function (colour, operator, options) {
return colour.darken($tw.utils.parseNumber(operator.operand)).display().toString();
});
exports["colour-get-oklch"] = makeSerialColourOperator(function (colour, operator, options) {
var prop = ((operator.suffixes || [])[0] || ["l"])[0];
if(["l","c","h"].indexOf(prop) !== -1) {
colour = colour.oklch[prop];
}
return colour.toString();
});
exports["colour-set-oklch"] = makeSerialColourOperator(function (colour, operator, options) {
var prop = ((operator.suffixes || [])[0] || ["l"])[0];
if(["l","c","h"].indexOf(prop) !== -1) {
colour.oklch[prop] = $tw.utils.parseNumber(operator.operand);
}
return colour.display().toString();
});
exports["colour-set-alpha"] = makeSerialColourOperator(function (colour, operator, options) {
colour.alpha = $tw.utils.parseNumber(operator.operand);
return colour.display().toString();
});
exports["colour-contrast"] = makeParallelColourOperator(function (colours, operator, options) {
var colourContrasts = [];
$tw.utils.each(colours,function(colour,index) {
if(!colour) {
colour = $tw.utils.parseCSSColorObject("white");
colours[index] = colour;
}
if(index > 0) {
colourContrasts.push(colour.contrast(colours[index - 1],"DeltaPhi").toString());
}
});
return colourContrasts;
});
exports["colour-best-contrast"] = makeParallelColourOperator(function (colours, operator, options, originalColours) {
var bestContrast = 0,
bestColour = null;
if(colours.length < 2) {
return [];
}
var targetColour = colours[colours.length - 1];
for(var t=0; t<colours.length; t++) {
var colour = colours[t];
if(colour) {
var contrast = colour.contrast(targetColour,"DeltaPhi");
if(contrast > bestContrast) {
bestContrast = contrast;
bestColour = originalColours[t];
}
}
}
if(bestColour) {
return [bestColour];
} else {
return [];
}
});
exports["colour-interpolate"] = function(source,operator,options) {
// Get the colour space suffix
var space = ((((operator.suffixes || [])[0] || ["srgb"])[0]) || "").toLowerCase();
if(colourSpacesList.indexOf(space) === -1) {
space = "lch";
}
// Get the hue adjuster suffix
var hueAdjuster = ((((operator.suffixes || [])[1] || ["shorter"])[0]) || "").toLowerCase();
if(hueAdjustersList.indexOf(hueAdjuster) === -1) {
hueAdjuster = "shorter";
}
// Get the colours
if(operator.operands.length < 2) {
return [];
}
var colourA = $tw.utils.parseCSSColorObject(operator.operands[0]),
colourB = $tw.utils.parseCSSColorObject(operator.operands[1]);
if(!colourA || !colourB) {
return [];
}
var rangefn = colourA.range(colourB,{space: space, hue: hueAdjuster});
// Cycle through the weights
var results = [];
source(function(tiddler,title) {
var index = $tw.utils.parseNumber(title);
var colour = rangefn(index);
results.push(colour.display().toString());
});
return results;
};
function makeSerialColourOperator(fn) {
return function (source, operator, options) {
var results = [];
source(function (tiddler, title) {
var c = $tw.utils.parseCSSColorObject(title);
if (c) {
c = fn(c, operator, options);
results.push(c);
} else {
results.push("");
}
});
return results;
};
}
function makeParallelColourOperator(fn) {
return function (source, operator, options) {
var originalColours = [],
colours = [];
source(function (tiddler, title) {
originalColours.push(title);
colours.push($tw.utils.parseCSSColorObject(title));
});
return fn(colours, operator, options, originalColours);
};
}
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/commands.js
type: application/javascript
module-type: filteroperator
Filter operator for returning the names of the commands available in this wiki
\*/
"use strict";
/*
Export our filter function
*/
exports.commands = function(source,operator,options) {
var results = [];
$tw.utils.each($tw.commands,function(commandInfo,name) {
+3
View File
@@ -2,6 +2,9 @@
title: $:/core/modules/filters/compare.js
type: application/javascript
module-type: filteroperator
General purpose comparison operator
\*/
"use strict";
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/contains.js
type: application/javascript
module-type: filteroperator
Filter operator for finding values in array fields
\*/
"use strict";
/*
Export our filter function
*/
exports.contains = function(source,operator,options) {
var results = [],
fieldname = operator.suffix || "list";
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/count.js
type: application/javascript
module-type: filteroperator
Filter operator returning the number of entries in the current list.
\*/
"use strict";
/*
Export our filter function
*/
exports.count = function(source,operator,options) {
var count = 0;
source(function(tiddler,title) {
+3
View File
@@ -2,6 +2,9 @@
title: $:/core/modules/filters/crypto.js
type: application/javascript
module-type: filteroperator
Filter operators for cryptography, using the Stanford JavaScript library
\*/
"use strict";
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/days.js
type: application/javascript
module-type: filteroperator
Filter operator that selects tiddlers with a specified date field within a specified date interval.
\*/
"use strict";
/*
Export our filter function
*/
exports.days = function(source,operator,options) {
var results = [],
fieldName = operator.suffix || "modified",
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/deserializers.js
type: application/javascript
module-type: filteroperator
Filter operator for returning the names of the deserializers in this wiki
\*/
"use strict";
/*
Export our filter function
*/
exports.deserializers = function(source,operator,options) {
var results = [];
$tw.utils.each($tw.Wiki.tiddlerDeserializerModules,function(deserializer,type) {
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/duplicateslugs.js
type: application/javascript
module-type: filteroperator
Filter function for [duplicateslugs[]]
\*/
"use strict";
/*
Export our filter function
*/
exports.duplicateslugs = function(source,operator,options) {
var slugs = Object.create(null), // Hashmap by slug of title, replaced with "true" if the duplicate title has already been output
results = [];
+7
View File
@@ -2,10 +2,17 @@
title: $:/core/modules/filters/each.js
type: application/javascript
module-type: filteroperator
Filter operator that selects one tiddler for each unique value of the specified field.
With suffix "list", selects all tiddlers that are values in a specified list field.
\*/
"use strict";
/*
Export our filter function
*/
exports.each = function(source,operator,options) {
var results =[] ,
value,values = {},
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/eachday.js
type: application/javascript
module-type: filteroperator
Filter operator that selects one tiddler for each unique day covered by the specified date field
\*/
"use strict";
/*
Export our filter function
*/
exports.eachday = function(source,operator,options) {
var results = [],
values = [],
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/editiondescription.js
type: application/javascript
module-type: filteroperator
Filter operator for returning the descriptions of the specified edition names
\*/
"use strict";
/*
Export our filter function
*/
exports.editiondescription = function(source,operator,options) {
var results = [];
if($tw.node) {
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/editions.js
type: application/javascript
module-type: filteroperator
Filter operator for returning the names of the available editions in this wiki
\*/
"use strict";
/*
Export our filter function
*/
exports.editions = function(source,operator,options) {
var results = [];
if($tw.node) {
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/else.js
type: application/javascript
module-type: filteroperator
Filter operator for replacing an empty input list with a constant, passing a non-empty input list straight through
\*/
"use strict";
/*
Export our filter function
*/
exports.else = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
+7
View File
@@ -2,10 +2,17 @@
title: $:/core/modules/filters/decodeuricomponent.js
type: application/javascript
module-type: filteroperator
Filter operator for applying decodeURIComponent() to each item.
\*/
"use strict";
/*
Export our filter functions
*/
exports.decodebase64 = function(source,operator,options) {
var results = [];
var binary = operator.suffixes && operator.suffixes[0].indexOf("binary") !== -1;
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/enlist.js
type: application/javascript
module-type: filteroperator
Filter operator returning its operand parsed as a list
\*/
"use strict";
/*
Export our filter function
*/
exports.enlist = function(source,operator,options) {
var allowDuplicates = false;
switch(operator.suffix) {
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/field.js
type: application/javascript
module-type: filteroperator
Filter operator for comparing fields for equality
\*/
"use strict";
/*
Export our filter function
*/
exports.field = function(source,operator,options) {
var results = [],indexedResults,
fieldname = operator.suffix || operator.operator || "title";
+9 -3
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/fields.js
type: application/javascript
module-type: filteroperator
Filter operator for returning the names of the fields on the selected tiddlers
\*/
"use strict";
/*
Export our filter function
*/
exports.fields = function(source,operator,options) {
var results = [],
fieldName,
@@ -22,13 +28,13 @@ exports.fields = function(source,operator,options) {
for(fieldName in tiddler.fields) {
(operand.indexOf(fieldName) !== -1) ? "" : $tw.utils.pushTop(results,fieldName);
}
}
} // else if
else {
for(fieldName in tiddler.fields) {
$tw.utils.pushTop(results,fieldName);
}
}
}
} // else
} // if (tiddler)
});
return results;
};
+10 -2
View File
@@ -2,18 +2,26 @@
title: $:/core/modules/filters/filter.js
type: application/javascript
module-type: filteroperator
Filter operator returning those input titles that pass a subfilter
\*/
"use strict";
/*
Export our filter function
*/
exports.filter = function(source,operator,options) {
var filterFn = options.wiki.compileFilter(operator.operand),
var suffixes = operator.suffixes || [],
defaultFilterRunPrefix = (suffixes[0] || [options.defaultFilterRunPrefix] || [])[0] || "or",
filterFn = options.wiki.compileFilter(operator.operand,{defaultFilterRunPrefix}),
results = [],
target = operator.prefix !== "!";
source(function(tiddler,title) {
var list = filterFn.call(options.wiki,options.wiki.makeTiddlerIterator([title]),options.widget.makeFakeWidgetWithVariables({
"currentTiddler": "" + title,
"..currentTiddler": options.widget.getVariable("currentTiddler",{defaultValue:""})
"..currentTiddler": options.widget.getVariable("currentTiddler","")
}));
if((list.length > 0) === target) {
results.push(title);
+3
View File
@@ -17,6 +17,9 @@ function getFormatFilterOperators() {
return formatFilterOperators;
}
/*
Export our filter function
*/
exports.format = function(source,operator,options) {
// Dispatch to the correct formatfilteroperator
var formatFilterOperators = getFormatFilterOperators();
+3
View File
@@ -6,6 +6,9 @@ module-type: formatfilteroperator
"use strict";
/*
Export our filter function
*/
exports.date = function(source,operand,options) {
var results = [];
source(function(tiddler,title) {
+3
View File
@@ -6,6 +6,9 @@ module-type: formatfilteroperator
"use strict";
/*
Export our filter function
*/
exports.json = function(source,operand,options) {
var results = [],
spaces = null;
@@ -6,6 +6,9 @@ module-type: formatfilteroperator
"use strict";
/*
Export our filter function
*/
exports.relativedate = function(source,operand,options) {
var results = [];
source(function(tiddler,title) {
+3
View File
@@ -6,6 +6,9 @@ module-type: formatfilteroperator
"use strict";
/*
Export our filter function
*/
exports.timestamp = function(source,operand,options) {
var results = [];
source(function(tiddler,title) {
+3
View File
@@ -6,6 +6,9 @@ module-type: formatfilteroperator
"use strict";
/*
Export our filter function
*/
exports.titlelist = function(source,operand,options) {
var results = [];
source(function(tiddler,title) {
+9 -3
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/function.js
type: application/javascript
module-type: filteroperator
Filter operator returning those input titles that are returned from a function
\*/
"use strict";
/*
Export our filter function
*/
exports.function = function(source,operator,options) {
var functionName = operator.operands[0],
params = [],
@@ -18,13 +24,13 @@ exports.function = function(source,operator,options) {
if(variableInfo && variableInfo.srcVariable && variableInfo.srcVariable.isFunctionDefinition) {
results = variableInfo.resultList ? variableInfo.resultList : [variableInfo.text];
}
// Return the input list if the function wasn't found
if(!results) {
results = [];
source(function(tiddler,title) {
results.push(title);
});
});
}
// console.log(`function ${functionName} with params ${JSON.stringify(params)} results: ${JSON.stringify(results)}`);
return results;
};
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/get.js
type: application/javascript
module-type: filteroperator
Filter operator for replacing tiddler titles by the value of the field specified in the operand.
\*/
"use strict";
/*
Export our filter function
*/
exports.get = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/getindex.js
type: application/javascript
module-type: filteroperator
returns the value at a given index of datatiddlers
\*/
"use strict";
/*
Export our filter function
*/
exports.getindex = function(source,operator,options) {
var data,title,results = [];
if(operator.operand){
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/getvariable.js
type: application/javascript
module-type: filteroperator
Filter operator for replacing input values by the value of the variable with the same name, or blank if the variable is missing
\*/
"use strict";
/*
Export our filter function
*/
exports.getvariable = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/has.js
type: application/javascript
module-type: filteroperator
Filter operator for checking if a tiddler has the specified field or index
\*/
"use strict";
/*
Export our filter function
*/
exports.has = function(source,operator,options) {
var results = [],
invert = operator.prefix === "!";
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/haschanged.js
type: application/javascript
module-type: filteroperator
Filter operator returns tiddlers from the list that have a non-zero changecount.
\*/
"use strict";
/*
Export our filter function
*/
exports.haschanged = function(source,operator,options) {
var results = [];
if(operator.prefix === "!") {
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/indexes.js
type: application/javascript
module-type: filteroperator
Filter operator for returning the indexes of a data tiddler
\*/
"use strict";
/*
Export our filter function
*/
exports.indexes = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
+7 -1
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/insertafter.js
type: application/javascript
module-type: filteroperator
Insert an item after another item in a list
\*/
"use strict";
/*
Order a list
*/
exports.insertafter = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
@@ -18,7 +24,7 @@ exports.insertafter = function(source,operator,options) {
if(pos !== -1) {
results.splice(pos,1);
}
// Insert the entry after the target marker
pos = results.indexOf(target);
if(pos !== -1) {
results.splice(pos+1,0,operator.operand);
+7 -1
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/insertbefore.js
type: application/javascript
module-type: filteroperator
Insert an item before another item in a list
\*/
"use strict";
/*
Order a list
*/
exports.insertbefore = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
@@ -18,7 +24,7 @@ exports.insertbefore = function(source,operator,options) {
if(pos !== -1) {
results.splice(pos,1);
}
// Insert the entry before the target marker
pos = results.indexOf(target);
if(pos !== -1) {
results.splice(pos,0,operator.operand);
+6
View File
@@ -2,6 +2,9 @@
title: $:/core/modules/filters/is.js
type: application/javascript
module-type: filteroperator
Filter operator for checking tiddler properties
\*/
"use strict";
@@ -16,6 +19,9 @@ function getIsFilterOperators() {
return isFilterOperators;
}
/*
Export our filter function
*/
exports.is = function(source,operator,options) {
// Dispatch to the correct isfilteroperator
var isFilterOperators = getIsFilterOperators();
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/is/binary.js
type: application/javascript
module-type: isfilteroperator
Filter function for [is[binary]]
\*/
"use strict";
/*
Export our filter function
*/
exports.binary = function(source,prefix,options) {
var results = [];
if(prefix === "!") {
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/is/blank.js
type: application/javascript
module-type: isfilteroperator
Filter function for [is[blank]]
\*/
"use strict";
/*
Export our filter function
*/
exports.blank = function(source,prefix,options) {
var results = [];
if(prefix === "!") {
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/is/current.js
type: application/javascript
module-type: isfilteroperator
Filter function for [is[current]]
\*/
"use strict";
/*
Export our filter function
*/
exports.current = function(source,prefix,options) {
var results = [],
currTiddlerTitle = options.widget && options.widget.getVariable("currentTiddler");
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/is/draft.js
type: application/javascript
module-type: isfilteroperator
Filter function for [is[draft]] analagous to [has[draft.of]]
\*/
"use strict";
/*
Export our filter function
*/
exports.draft = function(source,prefix,options) {
var results = [];
if(prefix === "!") {
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/is/image.js
type: application/javascript
module-type: isfilteroperator
Filter function for [is[image]]
\*/
"use strict";
/*
Export our filter function
*/
exports.image = function(source,prefix,options) {
var results = [];
if(prefix === "!") {
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/is/missing.js
type: application/javascript
module-type: isfilteroperator
Filter function for [is[missing]]
\*/
"use strict";
/*
Export our filter function
*/
exports.missing = function(source,prefix,options) {
var results = [];
if(prefix === "!") {
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/is/orphan.js
type: application/javascript
module-type: isfilteroperator
Filter function for [is[orphan]]
\*/
"use strict";
/*
Export our filter function
*/
exports.orphan = function(source,prefix,options) {
var results = [],
orphanTitles = options.wiki.getOrphanTitles();
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/is/shadow.js
type: application/javascript
module-type: isfilteroperator
Filter function for [is[shadow]]
\*/
"use strict";
/*
Export our filter function
*/
exports.shadow = function(source,prefix,options) {
var results = [];
if(prefix === "!") {
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/is/system.js
type: application/javascript
module-type: isfilteroperator
Filter function for [is[system]]
\*/
"use strict";
/*
Export our filter function
*/
exports.system = function(source,prefix,options) {
var results = [];
if(prefix === "!") {
+6
View File
@@ -2,10 +2,16 @@
title: $:/core/modules/filters/is/tag.js
type: application/javascript
module-type: isfilteroperator
Filter function for [is[tag]]
\*/
"use strict";
/*
Export our filter function
*/
exports.tag = function(source,prefix,options) {
var results = [],
tagMap = options.wiki.getTagMap();

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