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

Compare commits

..

614 Commits

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

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

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

* update th-make-tiddler-path arguments

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

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

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

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

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

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

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

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

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

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

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

* Update config-language.multids

* Create indentUnit.tid

* Create indentWithTabs.tid

* Create smartIndent.tid

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

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

* Update GruvBoxDark.tid

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

* Update GruvBoxDark.tid

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

* Testing for Linked List

* Finishing touches to LinkedList

* Minor corrections to link-list coding style

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

* Update Nord.tid

* Update Nord.tid

* Update Nord.tid

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

* Update styles.tid

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

* Made widget arg of filterTiddlers optional again

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

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

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

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

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

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

* fixed & docs updated

* tested with tiddlywiki.files & tw.com edition

* typos

* originalpath to options, propigate isEditableFile

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

* Update jump-to-line.js

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

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

* cleanup typos

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

testing new implementation

almost there

closer

bug, desyncing

fixed

final testing

final testing

cleanup

cleanup

* isEditableFile flow fixed

* removed `basepath` logic

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

* comment fix

* have syncer delete from boot.files

* syntax

* bugfix: error on missing directory

* bugifx

* remove !draft check

* fix relative filepaths

* cleanup

* cleanup !draft

* catch undefined filepaths in deleteTiddlerFile()

* typo

* whitelist wiki dir, encodeURIComponent otherwise

* test for wikiPath, not wikiPath/tiddlers

* don't need to .normailze()

* whitelist wiki directory, move cleanup to util

* use cleanup util & fail EPERM & EACCESS gracefully

* comments

* final bugs fixed

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

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

* Update GruvBoxDark.tid

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

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

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

* invoke th-radio-hook instead of hardcoded variables

* simplify code and test it with a plugin hook

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

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

* Update ControlPanel.multids

* Update Basics.tid

* Update ControlPanel.multids

* Update ControlPanel.multids

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

* Update saver-handler.js

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

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

* Update styles.tid

* Update theme.tid

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

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

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

* Update CupertinoDark.tid

* Update CupertinoDark.tid

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

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

* Add CSS class for centered modals

* Changed keyboardshortcut and removed transition CSS

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

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* Don't override browser selection colours by default

Reverts some of #4590

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* Update German Language

* some typos

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

* Update DesertSand.tid

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

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

* Update base.tid

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

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

* Allow updating classname without re-rendering entire widget

* Handle tag attribute in refresh handler

* Improve handling for mouse button variable

* Fix typo in refresh handler

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

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

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

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

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

* Do not rename LogWidget class

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

* Add whitespace trim to EditToolbar delete Button

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

* Add new filter syncFromServer

* Undo previous attempt at a fix

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

* Update base.tid

* Update fields.tid

* Update fields.tid

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

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

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

* Update new-journal.tid

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

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

* Update Saving to a Git service.tid

GitLab still uses `master` as default branch.

* Add Kookma plugins as resources

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

* Revert "Add Kookma plugins as resources"

This reverts commit 199fce3a08.

* Adding Resources by Mohammad

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

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

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

* Update Saving to a Git service.tid

GitLab still uses `master` as default branch.

* Add Kookma plugins as resources

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

* Revert "Add Kookma plugins as resources"

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

* Better handling for operand case

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

* Update EditTemplate.tid

* Update EditTemplate.tid

* Update tag-picker.tid

* Update tag-picker.tid

* Update type.tid

* Update fields.tid

* Update cancel.tid

* Update delete.tid

* Update type.tid

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

* Move all story list handling to Modal

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

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

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

* Make EditTemplate/tags work with every field

* Make NewTiddlerTags and NewJournalTags selectable through tag-picker

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

* Check for all attributes in refresh handler

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

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

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

* Remove size Button from image/svg+xml

* Remove paint Button from image/svg+xml

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

* Remove clear Button from image/svg+xml

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

* fr-FR translations related to renaming tiddlers during Import

* Correction of NewJournal Tags default config in fr-FR

* fr-FR update for the rendertiddlers command

* fr-FR translations for new Filter errors

* fr-FR update for the savetiddlers command

* fr-FR update for the savetiddler command

* fr-FR update for the rendertiddler command

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

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

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

* Range widget: added disabled attribute

* Radio widget: added disabled attribute

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

* Added tests for extended toggle filter

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

* Update base.tid

* Update styles.tid

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

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

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

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

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

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

* Update base.tid

* Update base.tid

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

* Update Filter.tid

* Update Shadows.tid

* Update Standard.tid

* Update System.tid

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

... to height of menubar

* Update styles.tid

* Update styles.tid

* Update styles.tid

* Update styles.tid

* Update menu.tid

* Update styles.tid

* Update styles.tid

* Update styles.tid

* Update styles.tid

* Update menu.tid

* Update styles.tid

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

* Update Filter.tid

* Update Shadows.tid

* Update Standard.tid

* Update System.tid

* Update search.tid

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

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

* Better error handling for suffixes

* Docs for search-replace operator

* Added tests for search-replace operator

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

* Update Advanced.tid

* Update Appearance.tid

* Update Info.tid

* Update AddPlugins.tid

* Update Plugins.tid

* Update Saving.tid

* Update Toolbars.tid

* Update Plugins.tid

* Update More.tid

* Update TiddlerInfo.tid

* Update tabs.tid

* Update settings.tid

* Update ControlPanel.tid

* Update Advanced.tid

* Update Appearance.tid

* Update Info.tid

* Update AddPlugins.tid

* Update Plugins.tid

* Update Saving.tid

* Update Toolbars.tid

* Update Plugins.tid

* Update More.tid

* Update tabs.tid

* Update settings.tid

* Update TiddlerInfo.tid

* Update AdvancedSearch.tid

* Update Filter.tid

* Update Shadows.tid

* Update Standard.tid

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

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

* Merge with master

* Add try catch around new RegExp

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

* Revert "Add support for switching page templates"

This reverts commit dbf7682d47.

* Adopt Jeremy's approach to page template switching instead

* Fix default value of recursion marker

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

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

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

* Added string-replace filter for testing multiple filter operands

* Added more tests for variables and text references in operands

* Removed string-replace operator and some whitespace corrections

* Removed string-replace operator and some whitespace corrections

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

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

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

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

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

* Update keyboard.js

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

* Update shortcuts.multids

* Update ShortcutInfo.multids

* Update fields.tid

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

* Make tag for menubar-contents dropdown configurable

* Make tag for menubar-contents dropdown configurable
2020-11-06 16:26:44 +00:00
jeremy@jermolene.com
22e25c05eb Remove normalize.css's styling of search inputs
As discussed here: https://github.com/Jermolene/TiddlyWiki5/issues/4984#issuecomment-723169753
2020-11-06 16:24:05 +00:00
jeremy@jermolene.com
4394b8e723 Dynannotate: Add example of view template usage 2020-11-06 12:27:46 +00:00
Simon Huber
d5c4aa250a Remove dependency on wiki.js for story-startup and navigator (#4200)
* Update story.js

* Update wiki.js

* Update navigator.js

* Add deprecation console logs to addToHistory and addToStory
2020-11-02 22:52:02 +00:00
saqimtiaz
70561bd481 Added docs for enlist-input filter operator (#4966) 2020-11-02 22:50:22 +00:00
saqimtiaz
2f5f0db00f Added docs for :intersection filter run prefix (#4967) 2020-11-02 22:49:50 +00:00
Simon Huber
4a6aa865b3 Make Escape in keyboard-driven-inputs behave like in AdvancedSearch/Filter (#4961)
* Create focus-editor.js

* Update search.tid

* Update link-dropdown.tid

* Update search.tid

* Update Standard.tid

* Update Shadows.tid

* Update System.tid

* Update fields.tid

* Update tag-picker.tid

* Update Filter.tid

* Update clear.tid

* Update link-dropdown.tid

* Delete focus-editor.js
2020-11-02 19:08:24 +00:00
Simon Huber
f29d24a1f5 Doc updates for keyboard-driven-input (#4963) 2020-11-02 19:04:25 +00:00
Bram Chen
2818f52f95 Add chinese translations for Shortcuts/SidebarLayout/Hint (#4962) 2020-11-02 09:17:09 +00:00
Bram Chen
9453c4d684 Add chinese translations for Listing/Rename/OverwriteWarning (#4960) 2020-11-01 17:15:27 +00:00
Mario Pietsch
42b965c9f0 Init less parsers (#4954)
* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* Don't override browser selection colours by default

Reverts some of #4590

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* list-widget, init new Parser() only if needed.

* fix braces

Co-authored-by: jeremy@jermolene.com <jeremy@jermolene.com>
2020-11-01 17:14:42 +00:00
saqimtiaz
e9a635dc81 Added intersection filter run prefix (#4959) 2020-11-01 17:13:52 +00:00
Simon Huber
26ade60e93 Make AdvancedSearch/Filter navigatable by keyboard (#4932)
* Make AdvancedSearch/Filter keyboard-driven

* Adapt keyboard-driven-input macro for use with...

... AdvancedSearch/Filter Tab

* Adjust Filter dropdown for kb-driven AdvancedSearch/Filter

* Adjust Clear Button for kb-driven AdvancedSearch/Filter

* Adjust Delete Button for kb-driven AdvancedSearch/Filter

* Adjust Export Button for kb-driven AdvancedSearch/Filter

* Update clear.tid

* Avoid editing the wron tiddler

* Make cancel-search-actions a bit more sophisticated

* Update Filter.tid

* Update Filter.tid

* Update Filter.tid

* Update keyboard-driven-input.tid

* Update dropdown.tid

* Update dropdown.tid

* Update Filter.tid

* Update clear.tid

* Update delete.tid

* Update dropdown.tid

* Update export.tid

* Update clear.tid

* Update Shadows.tid

* Update Standard.tid

* Update Shadows.tid

* Update System.tid

* Update Filter.tid

* Update keyboard-driven-input.tid
2020-11-01 17:12:29 +00:00
saqimtiaz
e7245a709c Add string operator enlist-input[] (#4948)
* Add string operator titlelist[]

* Update strings.js

* Update strings.js

* Add tests
2020-11-01 17:11:46 +00:00
Simon Huber
a6efc14a7c Add keyboard shortcut to change the sidebar layout (#4952)
* Create change-sidebar-layout keyboard shortcut

* Update shortcuts.multids

* Update ShortcutInfo.multids

* Update Misc.multids
2020-11-01 17:10:19 +00:00
saqimtiaz
9fbcdeb29e Import UI: add warning about tiddlers that already exist (#4956)
* Added message when tiddler being imported already exists

* Refactored some filters into a shared subfilter, optimized macro definitions
2020-11-01 11:33:02 +00:00
Simon Huber
ef1b7d619a Make ctrl-Enter in sidebar search also focus the AdvancedSearch input (#4941)
* Update search.tid

* Update Misc.multids

* Update search.tid

* Update search.tid

* Update search.tid

* Update search.tid
2020-11-01 11:23:18 +00:00
Simon Huber
ec70e5c179 AdvancedSearch keyboard shortcut: Let the navigator widget handle scrolling (#4955) 2020-11-01 11:22:34 +00:00
Simon Huber
4de0dc301b Rename $:/core/ui/KeyboardShortcut/toggle-sidebar... (#4953)
... to $:/core/ui/KeyboardShortcuts/toggle-sidebar for consistency
2020-11-01 11:15:53 +00:00
Simon Huber
769ffa19b7 Update CodeMirror plugins to v5.58.2 (#4950)
* Update codemirror.js to 5.58.2

* Update codemirror.css to 5.58.2

* Update activeline.js to 5.58.2

* Update dialog.js to 5.58.2

* Update jump-to-line.js to 5.58.2

* Update search.js to 5.58.2

* Update searchcursor.js to 5.58.2

* Update xml.js to 5.58.2

* Update show-hint.js to 5.58.2

* Update show-hint.css to 5.58.2

* Update javascript-hint.js to 5.58.2

* Update xml-hint.js to 5.58.2

* Update html-hint.js to 5.58.2

* Update css-hint.js to 5.58.2

* Update anyword-hint.js to 5.58.2

* Update closebrackets.js to 5.58.2

* Update matchbrackets.js to 5.58.2

* Update closetag.js to 5.58.2

* Update xml-fold.js to 5.58.2

* Update fullscreen.js to 5.58.2

* Update emacs.js to 5.58.2

* Update sublime.js to 5.58.2

* Update comment.js to 5.58.2

* Update vim.js to 5.58.2

* Update css.js to 5.58.2

* Update multiplex.js to 5.58.2

* Update htmlembedded.js to 5.58.2

* Update htmlmixed.js to 5.58.2

* Update javascript.js to 5.58.2

* Update markdown.js to 5.58.2

* Update markdown.js

* Update readme.tid

* Update markdown.js
2020-11-01 11:10:00 +00:00
Robin Munn
c0b021f509 Typo fix (#4951) 2020-11-01 11:03:59 +00:00
Simon Huber
635ec65d3f Fix alignment of tc-tiddler-edit-title (#4949) 2020-11-01 10:58:27 +00:00
Simon Huber
da06b64845 Fix AdvancedSearch Standard, System and Shadows up/down behavior (#4939)
* add filterMinLength to AdvancedSearch/Shadows

* add filterMinLength to AdvancedSearch/Standard

* add filterMinLength to AdvancedSearch/System

* Update link-dropdown.tid
2020-11-01 10:57:13 +00:00
Robin Munn
ecb3c86e7b Fix bug when location hash contains a # (#4947)
The bug fixed in this commit had an interesting side effect when the
location hash started with #, e.g. it looked like wiki.html##foo.
In that case, TiddlyWiki's navigation processing is not triggered and
the browser's navigation processing is used instead, which allows
anchors to be used within tiddlers for sub-tiddler navigation. To
preserve this unintended but useful side-effect, we check for a location
hash that starts with # and ignore it if it does.
2020-11-01 10:47:50 +00:00
Bram Chen
c6cd4d33e6 Add chinese translations for Listing/Rename/Prompt (#4946) 2020-11-01 10:45:48 +00:00
Robin Munn
77fe6244a2 Fix bug with sortan operator called on date fields (#4839)
* Add failing unit test that shows the bug

* Fix the bug
2020-11-01 10:45:18 +00:00
Simon Huber
f6e485b897 Avoid editing the wrong tiddlers when input fields are empty (#4943)
* Avoid editing the 'undefined' tiddler

* Avoid editing the wrong tiddler

* Avoid editing the wrong tiddler

* Avoid editing the wrong tiddler
2020-10-31 13:22:46 +00:00
Simon Huber
4b5d287c90 Change input-accept-variant actions shortcut from alt-Enter ... (#4942)
... to ctrl-Enter and advanced-search-sidebar shortcut from ctrl-Enter to alt-Enter

the ctrl-Key blocks navigation to the AdvancedSearch tiddler
2020-10-31 13:22:05 +00:00
saqimtiaz
c01e9cef12 Do not save temp tiddlers in single file (#4938)
* Update single file template to exclude temp tiddlers

* Update save-all-external-js.tid
2020-10-31 13:21:28 +00:00
saqimtiaz
655501140b Improvements for Import UI (#4937)
* Fixed bug with old titles used in popup, improved UI for greater rename input size

* Added flexbox utility CSS and use it for import UI
2020-10-29 13:01:17 +00:00
Robin Munn
cae32d39a5 Improve documentation for reduce operator (#4936) 2020-10-29 13:00:49 +00:00
Bram Chen
bc5609820f Update chinese translations (#4935)
* Update chinese language files
* add `Error/FilterRunPrefix` in Misc.multids
* add `Shortcuts/Input/AdvancedSearch/Hint` in Misc.multids

* Add chinese translations for Listing/Rename/*
2020-10-29 12:57:54 +00:00
twMat
4914208011 Update Configuring startup tiddlers.tid (#4009) 2020-10-29 12:57:11 +00:00
Simon Huber
b8fa6f0f0a Fix keyboard-driven fieldname dropdown (#4930)
I've accidentally overwritten the correct file when adding the tc-small-gap classes ... SORRY!
2020-10-28 17:16:20 +00:00
saqimtiaz
9605d94b6c Import rename (#4928)
* Add UI for renaming tiddlers before import in the import listing

* Removed spurious whitespace
2020-10-28 16:03:04 +00:00
Bram Chen
49b11bc493 Update chinese language files (#4929)
* add `Error/FilterRunPrefix` in Misc.multids
* add `Shortcuts/Input/AdvancedSearch/Hint` in Misc.multids
2020-10-28 15:59:02 +00:00
Simon Huber
9a4eb1e835 Add meta-S (mac) / ctrl-S shortcuts to save wiki (#4927)
* Create save-wiki.tid

* Update shortcuts-mac.multids

* Update shortcuts.multids

* Update ShortcutInfo.multids
2020-10-28 14:42:41 +00:00
Simon Huber
e71bf27dae Replace various &nbsp; with tc-small-gap classes (#4926)
* replace &nbsp; by span.tc-small-gap-right

* replace &nbsp;

* replace &nbsp;

* replace &nbsp;

* replace &nbsp;

* replace &nbsp;

* replace &nbsp;

* replace &nbsp;
2020-10-28 13:13:55 +00:00
Simon Huber
c985fd63f9 make link-dropdown navigatable by keyboard (#4919) 2020-10-28 12:01:05 +00:00
saqimtiaz
f5ad5010bc Added documentation for ':filter' prefix for filter runs. (#4920) 2020-10-28 12:00:18 +00:00
Simon Huber
12be7ac7e9 Add ability to navigate fieldname-dropdown by keyboard (#4921)
* make fields EditTemplate navigatable by keyboard

* Add configuration tiddler for fieldname-dropdown filters

* Update base.tid
2020-10-28 11:59:36 +00:00
Ryan Kramer
651619076a add override saver (#4908)
* add override saver

* rename 'override' to 'custom' and use the  global instead of introducing a new one
2020-10-28 11:58:48 +00:00
Simon Huber
57ba4c8cba Add .tc-small-gap (+left / right) and .tc-big-gap... (#4923)
(+left / right) classes that define margins of .5em / 1em
2020-10-28 11:57:08 +00:00
Simon Huber
6a01ab20a0 Fix menubar-plugin search (#4922) 2020-10-28 10:55:16 +00:00
Simon Huber
81e3ab0bc5 Make AdvancedSearch/Standard, AdvancedSearch/System and AdvancedSearch/Shadows navigatable by keyboard (#4925)
* Make AdvancedSearch/Shadows navigatable by keyboard

* Make AdvancedSearch/System navigatable by keyboard

* Make AdvancedSearch/Standard navigatable by keyboard

* Update search.tid
2020-10-28 10:53:41 +00:00
Simon Huber
e43ffe860b Fix #4910 - "Editor link dropdown is broken in pre-release." (#4913)
* fix #4910 in sidebarsegments/search

* fix #4910 in editortoolbar/link-dropdown

* fix #4910 in keyboard-driven-input macro

* Update keyboard-driven-input_Macro.tid

* Fix #4910 in tag-picker macro

* Update tag-picker.tid
2020-10-27 17:33:06 +00:00
saqimtiaz
d0081a7247 Updated Filter docs for named filter run prefixes (#4917) 2020-10-27 16:49:56 +00:00
saqimtiaz
972456ca07 Add new 'filter' prefix for filter runs (#4918) 2020-10-27 16:48:40 +00:00
jeremy@jermolene.com
9eec6ff915 Update path-prefix docs
Addressing @OblivionSY's comment https://github.com/Jermolene/TiddlyWiki5/issues/4898#issuecomment-717207456
2020-10-27 12:32:06 +00:00
saqimtiaz
c9efa23f02 Named filter run prefixes (#4915)
* First pass at refactoring filter code to support named filter run prefixes

* Remove filter prefix for now

* renamed module type and filter run prefixes

* Moved inline handling for no filter run prefix to 'or' filter run prefix.

* Added error handling for undefined filter run prefixes
2020-10-27 12:24:18 +00:00
Simon Huber
3843c61132 Add ability to cycle Advanced-search tabs by keyboard ... (#4909)
* Update AdvancedSearch.tid

* Update System.tid

* Update Standard.tid

* Update Filter.tid

* Update Shadows.tid

* Update search.tid

* Update shortcuts.multids

* Update ShortcutInfo.multids

* Update Misc.multids

* Update ShortcutInfo.multids

* Update search.tid
2020-10-27 09:03:34 +00:00
jeremy@jermolene.com
f6938d6abb Fix external-attachments plugin relative path bug
Fixes #4549
2020-10-26 18:36:46 +00:00
Rob Hoelz
aa7a00d080 Add eslint plus very tolerant starting config (#4872)
* Add eslint plus very tolerant starting config

Addresses GH #1865

This adds eslint as a developer dependency, plus a generated eslint
config that doesn't take a very strong stance on much of anything.  The
goal here to get started using automated style checking, add eslint
checking to the testing flow, and gradually introduce stricter checks
over time.

* eslint: Fix ecmaVersion

See
https://github.com/Jermolene/TiddlyWiki5/pull/4421#issuecomment-587002325,
where @Jermolene declared TiddlyWiki targets EcmaScript 5
2020-10-26 17:52:25 +00:00
jeremy@jermolene.com
4c6de22711 Recognise the image/jpg content type, even though it's not really legal
Browsers also respect it.

Fixes #4571
2020-10-26 17:47:19 +00:00
saqimtiaz
83f976ea54 Extended tiddlywiki.files to allow optionally saving changes to a tiddler back to the original file location (#4914) 2020-10-26 17:36:50 +00:00
jeremy@jermolene.com
3153c588ec Disable autosave in the upgrade wizard
To address @pmario's suggestion here: https://github.com/Jermolene/TiddlyWiki5/issues/4879#issuecomment-704320381
2020-10-26 17:28:57 +00:00
Robin Munn
0ce1843070 Simplify ci-push.sh: end script on any error (#4886)
Use the bash -e option to exit on any error, so || exit 1 is not needed.

As a bonus, this lets us get the actual return code from any failures.
2020-10-26 16:58:21 +00:00
Mario Pietsch
15338e60e8 Get "New Release Banner" from TW5-com edition (#4912)
* Fix state tiddlers for action-create-tiddlers examples

* Get "New Release Banner" from TW5-com edition
2020-10-25 22:03:35 +00:00
jeremy@jermolene.com
f7f55e8eff Add support for username/password parameters for tm-login message 2020-10-25 16:33:44 +00:00
jeremy@jermolene.com
5cc1600072 Introduce post-render startup actions 2020-10-25 16:22:21 +00:00
saqimtiaz
1a91f81976 Update filters for single file to match changes to syncFilter (#4907)
* Update saverFilter to match new changes in syncFilter

* Update save-all.tid

* Update save-all-external-js.tid

* Update save-offline.tid
2020-10-25 15:57:35 +00:00
saqimtiaz
b9234fe238 Update syncFilter to allow excluding multiple storyLists (#4906) 2020-10-25 15:56:41 +00:00
Bram Chen
4cdbe6540b Update chinese translations (#4890)
* Add chinese translations for "Error/FormatFilterOperator"

* Update Misc.multids
2020-10-24 08:22:39 +01:00
Mario Pietsch
4877891980 Fix tiddler title alignment if no icon is acitve (#4859)
* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* don't show the span if no icons are active.

* title lineheight 1.3 needed for eg: gggggg
2020-10-23 19:39:03 +01:00
Simon Huber
a1b486436e update TabsMacro.tid with "actions" and "explicitState" attribute (#4902) 2020-10-23 19:33:46 +01:00
Simon Huber
c3a8cc7eb4 fix error in sidebarsegments / search (#4903) 2020-10-23 19:32:40 +01:00
jeremy@jermolene.com
707e9d8926 Exclude $:/StoryList from syncing
Fixes #4868
2020-10-23 16:27:17 +01:00
saqimtiaz
adf0c1a12a Documentation for format filter operator (#4895)
* Documentation for format operator

* Examples for format operator
2020-10-23 16:25:05 +01:00
saqimtiaz
fd4cfaeb02 Typo in username (#4896) 2020-10-23 16:24:33 +01:00
Simon Huber
ae8ee5b955 Update modifier Variable.tid (#4894)
* Update modifier Variable.tid

This updates the "modifier Variable" tiddler

* Update modifier Variable.tid
2020-10-23 16:23:54 +01:00
Mario Pietsch
7686be7b14 Fix state tiddlers for action-create-tiddlers examples (#4897) 2020-10-23 16:23:17 +01:00
Simon Huber
84479bc403 Fix #4826 - Keyboard-driven-inputs clashes with customized search results. (#4875)
* Update search.tid

* Update DefaultSearchResultList.tid

* Update tabs.tid

* Update SearchResults.tid

* Update tabs.tid

* Update SearchResults.tid

* Update search.tid

* Update keyboard-driven-input.tid

* Update shortcuts.multids

* Update ShortcutInfo.multids

* Update Misc.multids

* Update keyboard-driven-input.tid

* Update search.tid

* Update Misc.multids
2020-10-23 15:58:34 +01:00
jeremy@jermolene.com
794dfb96f2 Don't try to process lazily loaded plugins
Fixes #4900
2020-10-23 15:37:20 +01:00
jeremy@jermolene.com
d254612826 Update and rearrange release note 2020-10-19 09:51:11 +01:00
jeremy@jermolene.com
c8721b38fd JSZip plugin: Fix example formatting 2020-10-19 09:44:55 +01:00
jeremy@jermolene.com
f863acf8ac Update BibTeX parser to use later fork of library
https://github.com/ORCID/bibtexParseJs
2020-10-18 17:05:43 +01:00
jeremy@jermolene.com
7e7ecbe7a5 Google Actions requires spaces instead of tabs 2020-10-18 16:51:36 +01:00
jeremy@jermolene.com
4ecd885a0c Update GitHub Actions to avoid deprecated "set-env" command
Fixes #4885
2020-10-18 16:13:38 +01:00
ento
dbda09b9fc Make test harness exit with a non-zero code when there's test failure (#4889)
* Rename variables to better convey what they're about

* Refactor comments so that they make more sense

* In Node.js, call the wrapper's execute function

The function sets up callbacks necessary for
exiting the process with the appropriate exit code.
https://github.com/jasmine/jasmine-npm/blob/v3.4.0/lib/jasmine.js#L235

* No need to configure the default reporter manually

The .execute() function does it

* Add note on which path comes from which npm package

* Note that other properties of the process object are referenced too
2020-10-18 15:19:52 +01:00
jeremy@jermolene.com
41931082e6 Update release note 2020-10-18 14:42:25 +01:00
jeremy@jermolene.com
5af76c5ea1 Extend TOC macros to allow custom link targets 2020-10-17 13:44:15 +01:00
jeremy@jermolene.com
1446a1e44c Extend tm-scroll to accept CSS selector to identify the target 2020-10-14 15:59:27 +01:00
jeremy@jermolene.com
69c12618d9 Syncer: Allow syncadaptor to customise the login prompt 2020-10-14 12:41:51 +01:00
jeremy@jermolene.com
651fb777ab PasswordPrompt: Return the object so it can be modified 2020-10-14 12:41:33 +01:00
jeremy@jermolene.com
34a51d2e23 Typo in comment
Thanks @saqimtiaz
2020-10-08 17:21:31 +01:00
jeremy@jermolene.com
2fc62c1a52 Merge branch 'tiddlywiki-com' 2020-10-08 16:49:00 +01:00
jeremy@jermolene.com
5ebd98779a Update Quine 2 URL 2020-10-08 16:46:57 +01:00
jeremy@jermolene.com
14a28b7779 Add "reduce" and "filter" operators 2020-10-06 19:20:03 +01:00
jeremy@jermolene.com
0027b990e4 Move tw5.com docs tiddlers to the correct folders 2020-10-04 17:36:08 +01:00
jeremy@jermolene.com
9716c32695 Fix Firefox bug with selection colours
See 543f9107b6 (commitcomment-42849656)
2020-09-30 17:59:39 +01:00
jeremy@jermolene.com
f7a626fef2 Add version tag missed off ae13a0fee1 2020-09-29 16:40:24 +01:00
jeremy@jermolene.com
f8961abb8a Share Plugin: Fix problem with sharing double quoted tiddler titles 2020-09-28 11:31:58 +01:00
jeremy@jermolene.com
59f233cd46 Fix exporting tiddlers with double quoted titles
Fixes #4860
2020-09-28 11:31:33 +01:00
jeremy@jermolene.com
ae13a0fee1 Extend Macro Call Widget to support outputting raw text 2020-09-28 11:30:28 +01:00
jeremy@jermolene.com
543f9107b6 Don't override browser selection colours by default
Reverts some of #4590
2020-09-25 14:06:00 +01:00
Gerald
5bf810408a Fix: add tc-tiddlylink-external to markdown links (#4862) 2020-09-25 13:07:36 +01:00
Gerald
405c618b6b Signing the CLA (#4867) 2020-09-25 13:07:08 +01:00
Florian Kohrt
4cd6a24431 Mention <tiddler-filter> parameter of savelibrarytiddlers command (#4857) 2020-09-24 19:09:06 +01:00
Florian Kohrt
773dcce713 Signing the CLA (#4845) 2020-09-24 19:08:23 +01:00
Robin Munn
d5cf4112fa Joining an empty list should return an empty list (#4853) 2020-09-24 18:37:51 +01:00
saqimtiaz
72c07a3f81 Format filter to create formatted date strings (#4785)
* asdate filter to create formatted date strings

* Added format filter operator
2020-09-24 18:35:10 +01:00
Mario Pietsch
bdaf3a4502 Change description for Filesystem and TiddlyWeb plugins (#4865)
* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* Improve the plugin description field to make the dataflow more obvious
2020-09-24 18:28:22 +01:00
jeremy@jermolene.com
f7fe47914e Dynaview: Fix transclude-when-visible macro 2020-09-23 17:33:00 +01:00
jeremy@jermolene.com
0338f0fee2 AWS Plugin: Add aws-encodeuricomponent filter that also encodes single quotes
Because AWS S3 doesn't allow single quotes in filenames
2020-09-23 17:32:38 +01:00
jeremy@jermolene.com
843319ebb0 Merge branch 'master' of github.com:Jermolene/TiddlyWiki5 2020-09-14 13:20:06 +01:00
jeremy@jermolene.com
2374fb5104 More release note updates 2020-09-14 13:16:10 +01:00
Robin Munn
31c9c23a18 Gitea API wants tokens, not HTTP basic auth (#4854) 2020-09-14 13:14:10 +01:00
jeremy@jermolene.com
af82a95a29 Update release note 2020-09-14 11:34:38 +01:00
jeremy@jermolene.com
87dc67d0cd Update CI scripts 2020-09-08 12:59:37 +01:00
jeremy@jermolene.com
68b455565b Update workflow file 2020-09-08 12:55:07 +01:00
Devin Weaver
c60402b06d Add Reveal.js plugin entry to Resources (#4842) 2020-09-08 11:34:35 +01:00
jeremy@jermolene.com
422eb43e50 CI: Update name of token 2020-09-01 17:08:53 +01:00
jeremy@jermolene.com
a78570c99a Minor change for testing GitHub Actions
See https://github.com/Jermolene/TiddlyWiki5/issues/4834#issuecomment-683447272
2020-08-30 18:27:25 +01:00
Robin Munn
5202441769 Add suffix and parameter to trim operator (#4811)
* Add suffix and parameter to trim operator

Fixes #4809

* Unit tests for new trim operator parameters

* Mention trim operator in 5.1.23 release notes

* Address review comments

* Move regex escaping into utils.js trim functions

This way the trimPrefix and trimSuffix functions from utils.js are safe
to call without regex-escaping their parameters, which should make them
easier to use from other parts of the Javascript code.
2020-08-29 12:27:58 +01:00
ento
ef29d05ea4 Finish migration to GitHub Actions (#4836)
* Fix 'if' condition syntax in Actions workflow

Strings in expressions need to be in single quotes:
https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#literals

* Delete .travis.yml

We moved to GitHub Actions

* Inline git-related environment variables

* Inline the build number variable

* Rename TRAVIS_BRANCH to TW5_BUILD_BRANCH

Since we don't use Travis anymore

* Update developer documentation regardgin which CI service is used

* Document the decision about setting env vars in the workflow file
2020-08-29 11:58:34 +01:00
ento
e332bb1728 Fix 'if' condition syntax in Actions workflow (#4835)
Strings in expressions need to be in single quotes:
https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#literals
2020-08-29 11:57:05 +01:00
jeremy@jermolene.com
14573d2c2d Add Arabic (Palestine) to the "Full Edition" 2020-08-28 17:51:17 +01:00
jeremy@jermolene.com
cbf79b8b90 Add RTL indicator to Arabic (Palestine) translation 2020-08-28 17:50:44 +01:00
Habash
ae604cd660 Add Arabic (Palestine) translation (#4720)
This is  my first contribution to Tiddlywiki , which contains an Arabic translation of 603 strings out of the porposed 941 strings in the translator edition.

I'll be working soon to finish the translator's edition strings, and I'll create a proper cascading for the arabic tiddlers.
2020-08-28 17:47:57 +01:00
ento
a206dccf0a Add GitHub Actions workflow (#4793)
* Parameterize strings that mention Travis

This is so that the script can be shared with
GitHub Actions while we make the transition.

* Add GitHub Actions workflow

More or less a direct translation of .travis.yml

* Rename scripts that mention travis

* Fix typo
2020-08-28 17:31:57 +01:00
Habash
c187f4b238 Signing the CLA (#4833) 2020-08-28 17:30:00 +01:00
jeremy@jermolene.com
4eda601a32 Update "Hidden Setting: Disable Drag and Drop" with version tag
Fixes #4573
2020-08-28 15:46:29 +01:00
Arlen22
4f376fba35 Separate $tw.boot.startup into three functions (#4602)
* Update boot.js

* Update boot.js
2020-08-28 15:43:42 +01:00
jeremy@jermolene.com
8bfd8f3a26 Update $:/tags/TextEditor/Snippet docs
Fixes #4603
2020-08-28 15:41:33 +01:00
gernert
ba9de17b87 Update SystemTag_ $__tags_Macro_View.tid (#4604) 2020-08-28 15:38:47 +01:00
jeremy@jermolene.com
8497e5b95d GitHub/Gitlab/Gitea savers: Handle empty paths correctly
Fixes #4656
2020-08-28 15:28:34 +01:00
jeremy@jermolene.com
918e52b37b Merge branch 'tiddlywiki-com' 2020-08-28 15:25:47 +01:00
Cameron Fischer
b86bbf3fc4 Compressing $set chains into one $vars (#4659) 2020-08-28 14:53:20 +01:00
jeremy@jermolene.com
7de8e1fc97 Remove extraneous CSS property
Fixes #4713
2020-08-28 14:51:11 +01:00
twMat
b16f5592fc Update contains Operator.tid (#4746) 2020-08-28 14:44:40 +01:00
saqimtiaz
48c6146ab6 Link widget: Include original event in tm-navigate (#4724) 2020-08-27 15:52:25 +01:00
John Xia
485022797f Clarifying plugin installation for Node.js (#4728)
All thanks go to @matrixbot on the Gitter for explaining what was going on!
2020-08-27 15:51:48 +01:00
John Xia
7bd719f3f3 Signing the CLA (#4727)
Co-authored-by: Jeremy Ruston <jeremy@jermolene.com>
2020-08-27 15:50:52 +01:00
Mario Pietsch
6645afcd15 Fix #4750 plugin priority for tiddlyweb (#4751)
* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* fix issue #4750 add plugin-priority of 10 to tiddlyweb plugin.
2020-08-27 15:48:30 +01:00
twMat
05de5b4c49 Update fixed Operator (examples).tid (#4763)
To clarify it zero pads.
2020-08-27 15:47:05 +01:00
ento
259b45065a Fix server error when saving a new tiddler created by following a tiddler link (#4770)
* Initialize draft tiddler with empty text

Otherwise, when the tiddler has a meta file,
$tw.utils.saveTiddlerToFile will call fs.writeFile with the content
to write as `undefined`. Depending on the version of Node, this
results in the string "undefined" getting saved or a TypeError.

* Remove what seems to be a leftover debug log
2020-08-27 15:45:34 +01:00
Simon Huber
aa08210e44 Fix #4795 - PaletteManager showing wrong tooltip (#4796) 2020-08-27 15:40:39 +01:00
Mario Pietsch
a0509a5170 Fix 4800 - remove communication to prodcut hunt on display. (#4812)
* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

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

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* fix #4800 - remove network communication to product hunt
2020-08-27 15:37:18 +01:00
Mario Pietsch
21f1c163d8 Update navigator widgets parameter docs (#4828)
Update navigator widgets parameter docs
2020-08-27 15:36:13 +01:00
jeremy@jermolene.com
a2796d89ab Fix httpRequest() header handling
Header names are not case sensitive, so the old code failed if it was called with a "Content-Type" header
2020-08-17 18:44:36 +01:00
Robin Munn
c23eedd069 Fix incorrect base64 encoding of astral-plane text (#4813)
Most astral-plane text is emojis like U+1F4DA BOOKS (📚), but some
languages like Osage have their alphabet entirely in the supplementary
multilingual plane as well. For proper support of languages like Osage,
and newer emojis, the UTF-8 decode and encode functions need to properly
handle codepoints above U+FFFF, which are represented by a surrogate
pair in Javascript strings.
2020-08-17 17:33:46 +01:00
jeremy@jermolene.com
ccda938248 More docs fixes from @fkohrt
See #4815
2020-08-14 15:19:16 +01:00
jeremy@jermolene.com
acd2cbf56a Docs fixes from @fkohrt
See #4815
2020-08-14 15:04:01 +01:00
jeremy@jermolene.com
f74c49f393 Fix syncing issues with external JS template
Fixes #4808
2020-08-14 11:06:08 +01:00
Adithya Badidey
8cf458d3b3 Adding SolarizedDark Palette, updated SolarizedLight and one tiny UI fix (#4799)
* Fixed Overflow svg fill

When hovered, the svg should be the same colour as the text it comes alongside. This fixes that.

* Fixed the Solarized Palettes as per spec

- Added the Solarized Dark palette
- Remade the Solarized Light palette with the right contrast ratios as per Solarized Spec.

* Sidebar Selected Tab UI Change

Changed the selected tab border and foreground from pink to white(base01) because the pink was too distracting and not very readable.

* Fixed Hover css for plugin info listing

The css was not working so I fixed it.

* Fixed the UI for plugin info tiddler (among others)
2020-08-11 18:54:17 +01:00
Mario Pietsch
fca9879321 Rename savewikifolder.tig to savewikifolder.tid (#4804) 2020-08-11 14:08:01 +01:00
jeremy@jermolene.com
7e964e9501 Browser-storage: Fix startup constraints
The use of $tw.perf requires the "startup" startup module to be executed first.
2020-08-11 12:32:39 +01:00
John Duhamel
89c0c6157b Add saver for Hyperdrive protocol used in Beaker 1.x (#4777) 2020-08-10 20:32:28 +01:00
Adithya Badidey
981e3bed45 Signing the CLA (#4801) 2020-08-10 14:56:33 +01:00
Simon Huber
17e2b208e8 Fix #4794 - tc-type-selector-wrapper not containing tc-edit (#4798)
* Update type.tid

* Update base.tid
2020-08-10 09:25:14 +01:00
Simon Huber
bbdd12cffd Add EditTabIndex config (tabindex = 1) (#4791) 2020-08-03 11:09:56 +01:00
saqimtiaz
dd79c096be Fix #4786 (#4787)
* Fix #4786

Fix #4786

* Update header.js
2020-08-03 10:41:23 +01:00
ento
9898e5e2db Don't run build-* stages for PRs against master (#4788) 2020-08-02 12:11:11 +01:00
Simon Huber
84b6a85293 Fix css selector for edit template new field (#4783) 2020-07-31 14:49:09 +01:00
ento
7acb9a255b Fix markdown table to honor alignment directives (#4774)
* Extract withChildren

* Handle table cell alignment

* 🎨 add missing semicolon
2020-07-31 13:01:21 +01:00
Simon Huber
5a6e35b4b0 Update keyboard-driven-input_Macro.tid (#4781) 2020-07-31 12:54:06 +01:00
ento
222821804e Fix Entity widget not rendering its content without a refresh (#4776)
* Expose TEXT_NODE and ELEMENT_NODE constants

* Add failing test for initial rendering of entity widget

* Compute attributes when rendering
2020-07-31 08:25:15 +01:00
Bram Chen
b32eb49d50 Update chinese translations (#4715)
* Update NewJournalTags.tid for zh* languages

* Add chinese shortcut descriptions to Misc.multids

* Add chinese translations for `Saving/TiddlySpot/ControlPanel`
2020-07-31 08:14:01 +01:00
jeremy@jermolene.com
97d2af7ebd TiddlySpot Saver: Add link to control panel
Thanks @twmat

Fixes #4778
2020-07-30 19:14:53 +01:00
Diep Pham
a9d79a1a84 Fix authenticated-user-header is case sensitive in header authenticator (#4780)
From RFC 2616 - "Hypertext Transfer Protocol -- HTTP/1.1", Section 4.2, "Message Headers":

Each header field consists of a name followed by a colon (":") and the field value. Field names are case-insensitive.
2020-07-30 18:24:28 +01:00
Diep Pham
792d285970 Signing the CLA (#4779) 2020-07-30 18:23:36 +01:00
Simon Huber
4de95a64c1 Lower width for field-value input field (#4760) 2020-07-17 08:48:30 +01:00
Simon Huber
95e30138f0 Add modifier variable to linkcatcher actionstring (#4758)
* Add modifier variable to linkcatcher actionstring

* Update LinkCatcherWidget.tid
2020-07-15 12:27:14 +01:00
Simon Huber
484c9e986f Fix #4755 - Indirect colours not shown in palette switcher (#4757)
* Fix #4755 - Indirect colours not shown in palette switcher

* Update currpalettepreview.tid

* Update currpalettepreview.tid
2020-07-15 12:23:13 +01:00
Simon Huber
00ff0d6fa0 Add modifier variable to button actionstring (#4671)
* Add modifier variable to button actionstring

* Update ButtonWidget.tid

* Update droppable.js

* Create getEventModifierKeyDescriptor method in keyboard.js

* Update droppable.js

* Update button.js
2020-07-14 17:04:06 +01:00
Simon Huber
a0bd93c596 Make tags in tags-dropdown change bg-color on hover (#4753) 2020-07-14 12:32:51 +01:00
Simon Huber
d66725fd31 Integrate keyboard-driven-input in menubar-search (#4752) 2020-07-14 12:32:40 +01:00
jeremy@jermolene.com
5b2048fad1 Update release note 2020-07-13 17:49:40 +01:00
Simon Huber
0d2df34c58 Keyboard-driven dropdown inputs (#4725)
* Add shortcut descriptions to Misc.multids

* Update framed.js

* Update simple.js

* Add inputActions and refreshTitle to factory.js

* Add inputActions and refreshTitle to edit.js

* Update DefaultSearchResultList.tid

* Update search.tid

* Update ShortcutInfo.multids

* Update shortcuts.multids

* Create keyboard-driven-input.tid

* Update tag-picker.tid

* Create keyboard-driven-input_Macro.tid

* Update EditTextWidget.tid

* Update EditWidget.tid

* Update engine.js

* Update base.tid

* Use primaryListFilter, secondaryListFilter, primaryList and secondaryList

* Update tag-picker.tid

* Update search.tid

* Update DefaultSearchResultList.tid

* Update keyboard-driven-input_Macro.tid

* Fix typo udpate -> update

* Update framed.js
2020-07-13 17:42:55 +01:00
jeremy@jermolene.com
d505eeb269 Consent widget
Block the raw widget unless consent has been granted. This is helpful because the tw2parser generates <$raw> widgets for content embedded with <html>, and thus this blocks YouTube embeds.
2020-07-13 11:49:21 +01:00
jeremy@jermolene.com
a0db3abe99 Consent banner: Add optional blocking of embedded content until consent granted 2020-07-02 13:14:51 +01:00
jeremy@jermolene.com
bd2cf5c464 Extend the element widget with a hook to intercept DOM node creation
The element widget is used to render HTML elements in wikitext.
2020-07-02 13:13:55 +01:00
twMat
8b5a4faa07 Update Filter Operators.tid (#4739) 2020-06-27 13:13:10 +01:00
twMat
4c39db1f54 Update ActionListopsWidget.tid (#4738) 2020-06-27 13:13:01 +01:00
twMat
c0f0aadf09 Update TaskManagementExampleDraggableTemplate.tid (#4737) 2020-06-27 13:12:52 +01:00
twMat
55109177ee Update TaskManagementExampleDraggable.tid (#4736) 2020-06-27 13:12:24 +01:00
twMat
2e39b5add5 Update TaskManagementExample.tid (#4735) 2020-06-27 13:11:57 +01:00
twMat
4127ce8e9f Update StateMechanism.tid (#4734) 2020-06-27 13:11:50 +01:00
twMat
6f4f38506e Update NavigatorWidget.tid (#4733) 2020-06-27 13:11:41 +01:00
twMat
33ee650fb7 Update How to create keyboard shortcuts.div (#4732) 2020-06-27 13:11:32 +01:00
twMat
7f08025175 Update HistoryMechanism.tid (#4731) 2020-06-27 13:11:20 +01:00
saqimtiaz
35a842ade6 EditWidget: Pass attributes from parseTreeNode to child widgets (#4740) 2020-06-27 12:33:14 +01:00
saqimtiaz
d46872c061 Extend tm-import-tiddlers message (#4741)
* Allow tm-import-tiddlers event to override tv-auto-open-on-import

* Add autoOpenOnImport attribute to dropzone

* Updated DropZone docs

* Updated dropzone to support importTitle attribute

* Updated navigator to support importTitle attribute on tm-import-tiddlers

* Update dropzone docs for importTitle attribute

* Updated docs for tm-import-tiddlers

* Fixed formatting
2020-06-27 12:32:11 +01:00
jeremy@jermolene.com
64034f4977 Consent banner: Reorganise readme 2020-06-22 12:27:58 +01:00
jeremy@jermolene.com
4d2d6cc818 Consent banner: Use palette colours 2020-06-22 12:25:55 +01:00
jeremy@jermolene.com
c57bdc46f4 Update release note 2020-06-22 11:35:31 +01:00
jeremy@jermolene.com
4a84ed0018 Add new "Consent Banner" plugin, and update Google Analytics plugin to use it 2020-06-22 11:31:54 +01:00
jeremy@jermolene.com
3de6c95fd6 Update release note 2020-06-19 19:06:21 +01:00
saqimtiaz
7911007973 Revised: toggling relink in tm-rename-tiddler (#4723)
* switch boolean logic in new parameters

Use renameinTags and renameInLists instead of dontRenameInTags and dontRenameInLists respectively. This avoids users having to think through double negatives, as well as corresponds better to the setting in $:/config/RelinkOnRename

* Updated docs for revised parameters for tm-new-tiddler
2020-06-19 18:20:25 +01:00
saqimtiaz
24ef51df01 Revert "Allow toggling relink in tm-rename-tiddler (#4719)" (#4722)
This reverts commit a689f31978.
2020-06-19 18:05:08 +01:00
saqimtiaz
a689f31978 Allow toggling relink in tm-rename-tiddler (#4719)
* Allow toggling relink in tm-rename-tiddler

* Updated docs for tm-rename-tiddler
2020-06-19 11:07:03 +01:00
jeremy@jermolene.com
f760a2fa79 Add old tiddler to th-saving-tiddler hook
Addresses https://github.com/Jermolene/TiddlyWiki5/pull/4434#issuecomment-645939182
2020-06-18 11:49:59 +01:00
jeremy@jermolene.com
9a479a95ad Catalan updates 2020-06-16 14:58:07 +01:00
jeremy@jermolene.com
7e1f5b8471 Add script for updating language plugins from translators edition 2020-06-16 14:57:58 +01:00
jeremy@jermolene.com
6265be01cd Release note update 2020-06-16 14:40:49 +01:00
jeremy@jermolene.com
fc1877dcce Merge branch 'tiddlywiki-com' 2020-06-16 14:15:10 +01:00
jeremy@jermolene.com
5cda5c82e1 Add docs for list-thumbnails macro
Thanks @Marxsal
2020-06-14 17:26:19 +01:00
jeremy@jermolene.com
b8225f6993 Create Saving with TW Receiver
Fixes #4712

(with 09a2db1cff)
2020-06-14 17:23:28 +01:00
Rizwan
1e221ddbdb Visual changes to Saving Tiddler (#4640)
* Styles and templates for visual changes to Saving methods listing

* Color coding saver methods according to delivery

* Changes to tags and few tiddlers
- The tag InternetExplorer has been changed to [[Internet Explorer]]
- A tag for Edge is added
- Reclassified TiddlyServer as DIY instead of App
The existing criteriion for classification is unclear. Here is my reasoning for the change. An app is something user can simply install and run. Like TiddlyDesktop or Tiddloid. A DIY is something user has to install additional runtimes for. Thus Nodejs is a DIY. In the same vein, TiddlyServer is a DIY

* Adding Twexe

* Reversing accidental changes to StoryList

* Restyling Download button and Card Size

* Removing "Read more" links

Entire card is now clickable
To give visual clues regarding the clickability of card, title will change color to blue on card hover

* Removing margins from elements under link and adding padding instead.

Why this change? Margins are not "clickable". Having margins under <a> tag means there are minute dead areas where the mouse pointer will change shape, is not clickable and degrade user experience. Paddings are "clickable"
2020-06-14 11:48:13 +01:00
Jeremy Ruston
09a2db1cff Update Saving on a PHP Server.tid (#4714)
As suggested by @Marxsal
2020-06-14 11:22:37 +01:00
Simon Huber
881aed879b Fix #4591: Use text field instead of tags field for $:/config/NewJournal/Tags ... (#4600)
* Update Basics.tid

* Update new-tiddler.tid

* Update new-journal.tid

* Update new-image.tid

* Update new-here.tid

* Update new-journal-here.tid

* Update NewJournalTags.tid

* Update NewJournalTags.tid
2020-06-14 09:40:48 +01:00
twMat
2f55a8808c Update KeyboardWidget.tid (#4606)
Add railroad for key strings.
2020-06-13 19:29:38 +01:00
saqimtiaz
38e329edad Fixes use of stateTitle instead of state resulting in artifacts during import (#4711)
* Fixes use of stateTitle instead of state

* Fixed bug with merging
2020-06-13 09:16:33 +01:00
Simon Huber
d832cb93ce Fix (again) error in scrollable.js (#4705) 2020-06-11 13:54:59 +01:00
Simon Huber
bbf20f8955 Scrollable widget: Fix error in variable declaration (#4704) 2020-06-11 12:33:18 +01:00
Simon Huber
17a36726fa Fields EditTemplate: Correct positioning of dropdown (#4687)
* Add wrapper div to fields EditTemplate

* Add classes

* remove obsolete span

* Update base.tid
2020-06-11 12:18:31 +01:00
Simon Huber
482f7a92ae Type EditTemplate: show dropdown at correct position ... (#4686)
* Refactor type edittemplate for correct positioning...

... of type dropdown

* Refactor classes
2020-06-11 12:14:09 +01:00
Simon Huber
b191ee9210 Fix #4673 - Adding tags in $:/Manager does not work (#4674)
* Add fieldmangler to Manager Tags-Sidebar

This makes the tm-add-tag messages in the tag-picker work

* Add actions parameter back to tag-picker macro

* Add div so that tag-dropdown shows below input field

* Add missing tc-btn-dropdown class to dropdown button ...

... for consistency with dropdown buttons in EditTemplate

* Update tag-picker.tid
2020-06-11 12:12:45 +01:00
saqimtiaz
25f8b3f903 Check for DOM node existence before removing class. (#4696)
Can cause issues if dragstart and dragend actions trigger a refresh.
2020-06-11 12:11:56 +01:00
twMat
e3ad276dd0 Update Images in WikiText.tid (#4691) 2020-06-11 12:11:26 +01:00
twMat
1f1fd49d0b Update LinkWidget.tid (#4690)
add image link
2020-06-11 12:11:12 +01:00
Cameron Fischer
e01b354f7d Corrected issue with markdowns softbreaks AND whitespace between md markup (#4684)
* Corrected issue with markdowns softbreaks

It wasn't respecting the $:/config/markdown/breaks setting.
It was effectively always "true".
Also, no more errors when encountering hardbreaks.

* Corrected introduced md bug

Made it so after each md type, accumulated text may be flushed.

* Changed convertNodes to use switch statement

It's faster, less text, easier to read, and now debuggers don't play
duck-duck-goose with every if-else block.

* whitespace text is no longer forgotten

* Fixed issue with text after md pattern and \n
2020-06-11 12:09:10 +01:00
Simon Huber
84cd761c8c Fix alignment of tag-pill icons (#4683) 2020-06-11 12:07:23 +01:00
Simon Huber
a947a6b6bc Fix hover colors of tag dropdown entries in sidebar (#4682) 2020-06-11 12:06:49 +01:00
Cameron Fischer
b0485eef6a Corrected incorrect image source for markdown (#4680) 2020-06-11 12:03:16 +01:00
Simon Huber
5b9dbf7b95 Use srcWindow in scrollable widget (#4677) 2020-06-11 11:49:32 +01:00
saqimtiaz
d31d4621a4 Incorrect modified field glitches timeline macro (#4676) 2020-06-11 11:48:55 +01:00
twMat
d42b7f173b Update TiddlyWiki in the Sky for TiddlyWeb (#4667)
remove refs to TiddlySpace
2020-06-11 11:46:51 +01:00
twMat
ceb2411794 Update How to apply custom styles.tid (#4663) 2020-06-11 11:46:22 +01:00
Simon Huber
cbff2fb692 Fix e.toggleComment being undefined in CM sublime keymap (#4662)
* Create comment.js

* Update tiddlywiki.files
2020-06-11 11:45:47 +01:00
Simon Huber
e59f606566 Cancel popups when clicking within an editor (#4658)
* Add cancelPopups attribute to edit widget

* Add cancelPopups attribute to factory.js

* Cancel popups in editor/simple.js

* Cancel popups on focus in engines/framed.js

* Cancel popups on focus in CodeMirror engine

* Add cancelPopups="yes" to tag-picker

* Add cancelPopups="yes" to sidebar search

* Add cancelPopups="yes" to editor

* Add cancelPopups="yes" to fields EditTemplate

* Update body.tid

* Add cancelPopups="yes" to title EditTemplate

* Add cancelPopups="yes" to type EditTemplate

* Update EditTextWidget.tid

* Update EditWidget.tid

* Add cancelPopups="yes" to menubar plugin search

* Update tag-picker.tid

* Update tags.tid
2020-06-11 11:41:35 +01:00
Bram Chen
042c8d8a69 Update chinese help texts for rendertiddlers command (#4657) 2020-06-11 11:39:57 +01:00
Arlen22
d32fb6f900 Allow setting boot, wiki, and pathPrefix for each request (#4649)
* Add pathPrefix to state, and options to request handler

* use ternary operator instead of default empty object

* Fix styling issues

* Update server.js

* Add boot to server and filesystem adapter
2020-06-11 11:36:41 +01:00
jeremy@jermolene.com
2c24f30cdd Update release note 2020-06-11 11:30:11 +01:00
jeremy@jermolene.com
954c9944ad Fix accidental changes in 41a7d98e17
Put this one down to COVID-19
2020-06-07 10:30:39 +01:00
jeremy@jermolene.com
41a7d98e17 Merge branch 'tiddlywiki-com' 2020-05-16 20:13:38 +01:00
jeremy@jermolene.com
75589d78d8 Update RoadMap tiddler
Fixes #4661
2020-05-16 19:52:54 +01:00
jeremy@jermolene.com
b0e40e8641 Fix dynaview examples 2020-05-16 14:56:08 +01:00
Simon Huber
99a07f80f1 Add missing Linkify ShortcutInfo (#4653) 2020-05-14 14:37:17 +01:00
Mario Pietsch
79ec21346d Fix 4596 - High cpu consume after upgrade to 5.1.22 (#4634)
* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* fix high CPU load
2020-05-14 14:31:57 +01:00
Simon Huber
5d91c27980 Update rendertiddlers.tid (#4635) 2020-05-14 14:31:32 +01:00
Simon Huber
72ff1a26fc Update Generating Static Sites with TiddlyWiki.tid (#4636) 2020-05-14 14:31:16 +01:00
mocsa
1812cbbb7c Clarify Introduction to filter notation.tid (#4639)
I'm reading the documentation for the first time and I'm trying to clarify parts which are hard to understand for first-time users.
2020-05-14 14:30:48 +01:00
jeremy@jermolene.com
3440f0f308 Merge branch 'tiddlywiki-com' 2020-05-14 14:30:07 +01:00
Bimba Laszlo
6570561d4e The !has[tags] filter didn't work because tags field is an array (#4643)
* The `!has[tags]` filter didn't work because "tags" is an array

The negated `has` filter only considered empty strings, but not empty
arrays (such as the `tags` field).

* Add tests for `has` filter operator with array-like fields (tags, list)
2020-05-14 13:57:12 +01:00
Bimba Laszlo
9c22537b4e Fix the class attribute of Droppable widget (#4647)
Even though we passed the `class` attribute, it did not take it into
account. For example try to render this:

  <$droppable class="custom-css-class">
    ... content ...
  </$droppable>

Before applying this patch:

  <span class=" tc-droppable">
    ... content ...
  </span>

After applying:

  <span class="custom-css-class tc-droppable">
    ... content ...
  </span>
2020-05-14 13:55:33 +01:00
Jonas Passerini
84a4784dee Add Transcludify ShortcutInfo (#4651)
* Signing the CLA

* Add Transcludify ShortcutInfo
2020-05-14 12:19:16 +01:00
jeremy@jermolene.com
5c0d91c510 Fix title of slugify.js filter module 2020-05-14 07:53:30 +01:00
jeremy@jermolene.com
d1441d29fd Release note update 2020-05-10 11:59:22 +01:00
jeremy@jermolene.com
bf6735420d Fix SVG favicons 2020-05-10 11:58:40 +01:00
jeremy@jermolene.com
34181230c7 Release note update 2020-05-09 16:08:46 +01:00
jeremy@jermolene.com
2eb11d9a2d Add slugify operator to JSZip static export example 2020-05-09 15:56:48 +01:00
jeremy@jermolene.com
4966f6ab62 Add slugify and duplicateslugs operators
Fixes #3379
2020-05-09 15:54:44 +01:00
jeremy@jermolene.com
33d973fb91 Add originating widget to event objects 2020-05-09 15:53:38 +01:00
Arlen22
81f07cdf85 Use this.wiki where applicable (#4601)
* Use state.wiki

* use local wiki where available

* fix a couple this vs self cases
2020-05-06 11:27:50 +01:00
jeremy@jermolene.com
48dfadd85b InfoMechanism: Add $:/info/startup-timestamp 2020-05-06 11:05:54 +01:00
Nicolas Petton
71a827eead Fix mailto links Forums.tid (#4616)
To avoid users being mislead when trying to subscribe by email to one of the
Google Groups, put only the relevant mailto link in each forum section.

Co-authored-by: Jeremy Ruston <jeremy@jermolene.com>
2020-05-06 09:51:11 +01:00
Simon Huber
86640474b5 Fix search dropdown items text color on hover (#4632) 2020-05-06 09:46:29 +01:00
Rizwan
31c4fd586b Docs updates and fixing broken links (#4628)
* Corecting URL of LuckySushi shop

* Android-Instructions remained for Andtidwiki

* Updating description and feature set of Timimi
Updating URL of Widdly
Resolving minor camelcase issues in TiddlySpot

* Detailed instructions about termux and adding it to save methods

* Correcting the words "open source" and "Unix"

* Changing link protocols of verified domains to https
2020-05-06 09:40:42 +01:00
Nicolas Petton
33e9f88c73 Add Nicolas Petton to the list of contributors (#4617)
Co-authored-by: Jeremy Ruston <jeremy@jermolene.com>
2020-05-06 09:34:13 +01:00
mocsa
b9d02b61b1 Update cla-individual.md (#4607) 2020-05-06 09:33:18 +01:00
jeremy@jermolene.com
c9692d7a50 Fix case-insensitive freelinks 2020-05-05 16:38:29 +01:00
jeremy@jermolene.com
7ee9003df7 Release note update 2020-05-03 19:06:28 +01:00
jeremy@jermolene.com
75d65d2694 JSZip Plugin: Docs update 2020-05-02 21:31:15 +01:00
jeremy@jermolene.com
6a0ff7db18 JSZip Plugin: Add ability to build and download ZIP files 2020-05-02 21:22:44 +01:00
jeremy@jermolene.com
85fd43a38c Update release note 2020-05-02 14:09:47 +01:00
jeremy@jermolene.com
1f354a972e Freelinks plugin: Add support for ignoring case 2020-05-02 14:07:39 +01:00
jeremy@jermolene.com
5eee11beed Update Catalan translation 2020-05-02 13:16:52 +01:00
jeremy@jermolene.com
9cd5415dfe Add new favicon for prerelease
Fixes #4619
2020-04-30 18:00:33 +01:00
jeremy@jermolene.com
7f01445903 Update information about Quine for iOS 2020-04-29 17:02:17 +01:00
jeremy@jermolene.com
13b8281f6b $tw.utils.copyDirectory: Ensure directories don't overlap 2020-04-27 15:00:06 +01:00
jeremy@jermolene.com
ad575efdcc Update sortsub to evaluate the subfilter for each item in the list
See the discussion here https://groups.google.com/d/msg/tiddlywiki/BqUFQ3v-fZw/U0F04CFFBQAJ
2020-04-25 15:22:24 +01:00
jeremy@jermolene.com
685157266d Release note update 2020-04-25 11:27:31 +01:00
jeremy@jermolene.com
619c0752bd Add new sortsub operator 2020-04-25 11:26:19 +01:00
jeremy@jermolene.com
bed76b9a32 Release note: fix typo
Thanks @BramChen
2020-04-23 09:41:38 +01:00
Cameron Fischer
2385bd978f Fix importvariables crash (#4593)
* Fixed issue: multi nonMacro imports broke everything

* Fixed issue: dead variables in import might linger
2020-04-23 09:10:52 +01:00
jeremy@jermolene.com
1cc5c5e7f0 Update release note
And fix the github comparison link so that it works for the prerelease
2020-04-22 17:47:34 +01:00
jeremy@jermolene.com
2a8f7a9c50 Add support for _canonical_uri field of $:/favicon.ico 2020-04-22 16:40:02 +01:00
jeremy@jermolene.com
5f98e7d7b3 Ensure $tw.utils.hasClass/addClass/removeClass work with SVG elements
These docs make clear that .className isn't recommended for SVG elements:

https://developer.mozilla.org/en-US/docs/Web/API/Element/className#Notes
2020-04-22 15:32:20 +01:00
jeremy@jermolene.com
a4fb57bf15 Fix typo in BrowseWidget docs 2020-04-22 12:10:34 +01:00
Simon Huber
cae937f107 Make selections follow palette colors (#4590) 2020-04-22 10:46:36 +01:00
jeremy@jermolene.com
77a929faa3 ActionPopup widget: Add ability to cancel all popups 2020-04-21 22:19:03 +01:00
jeremy@jermolene.com
c86a621d5d BrowseWidget: Add "accepts" attribute
And add docs for the 'message' and 'param' attributes
2020-04-21 22:18:34 +01:00
jeremy@jermolene.com
3a20fb1e3a Twitter Plugin: Add warning if the wiki needs to be saved and reloaded 2020-04-21 21:22:13 +01:00
jeremy@jermolene.com
d6ee700bca Fix $tw.utils.getSubdirectories() 2020-04-21 21:21:38 +01:00
jeremy@jermolene.com
c87f4a1e94 Update prerelease version number
Whoops
2020-04-21 15:12:43 +01:00
Marxsal
075321932a Make commands for static generation more complete (#4588)
* Make commands for static generation more complete

* Added message about installing on node.js
2020-04-21 11:41:50 +01:00
Simon Huber
39d532a4a0 Revert "Make input fields dismiss their popups when the ... (#4579)" (#4586)
This reverts commit 4efcad46f3.
2020-04-20 19:26:54 +01:00
Simon Huber
86d7564661 Update gruvbox dark for better readability of ... (#4585)
... toolbar buttons
2020-04-20 17:13:00 +01:00
jeremy@jermolene.com
d579ce942c Fix broken links in static rendering
Fixes #4577
2020-04-20 15:56:48 +01:00
Simon Huber
4efcad46f3 Make input fields dismiss their popups when the ... (#4579)
* Make input fields dismiss their popups when the ...

... fields loose focus (`blur`)

* Update simple.js
2020-04-20 15:49:30 +01:00
jeremy@jermolene.com
1546a4a189 Client-server: Add message about disabled plugin library
Fixes #4570
2020-04-20 13:28:02 +01:00
jeremy@jermolene.com
2649d2f7dc Syncer: Fix typos
Fixes a bug introduced in #4584
2020-04-20 13:19:27 +01:00
idotobi
154e886873 Fix Comment in Webserver API route tidlers.json (#4557)
This commit fixes the the comment in the route
`recipes/default/tiddlers.json` which was inconsistent with the actually
used regex. Furthermore, the 403 response was adjusted to also agree
with the the new comment and the regex.

Co-authored-by: tobidot <post@tobidot.net>
2020-04-20 13:07:06 +01:00
idotobi
d9387cf4f8 Signing the CLA (#4581) 2020-04-20 13:06:41 +01:00
jeremy@jermolene.com
5688670da6 makelibrary command: Guard against invalid directories 2020-04-20 12:58:27 +01:00
jeremy@jermolene.com
678e25f510 makelibrary command should skip non-directories
Fixes #4583
2020-04-20 11:47:54 +01:00
jeremy@jermolene.com
15d7255728 Syncer: Should not call syncadaptor for missing tiddlers
Fixes #4580
2020-04-20 11:35:11 +01:00
jeremy@jermolene.com
05e6c1bf62 Freelinks Plugin: Don't autolink within HTML <a> links 2020-04-20 11:26:37 +01:00
Daniel Rodríguez Rivero
4ea79cb0c3 fix(syncer): restore tiddlerInfo param to saveTiddler (#4584)
This was added on a159b5baf3 and lost in #4373.
Will be a good idea to introduce tests against this kind of changes
2020-04-20 11:17:27 +01:00
jeremy@jermolene.com
e71a27ac2d Fix link widget to work within SVG elements 2020-04-19 12:57:56 +01:00
jeremy@jermolene.com
d897989965 Add Product Hunt badge 2020-04-19 12:45:35 +01:00
jeremy@jermolene.com
90469679a5 Placeholder banner for v5.1.23
We'll have another competition
2020-04-18 15:52:15 +01:00
Jeremy Ruston
00686fc002 Preparing for v5.1.23-prerelease 2020-04-15 16:23:19 +01:00
Jeremy Ruston
1a6be5ae09 Version number update for 5.1.22 2020-04-15 16:13:55 +01:00
Jeremy Ruston
efb121e016 Update readme for v5.1.22 2020-04-15 16:11:52 +01:00
Jeremy Ruston
8dd13bdb20 Preparing for v5.1.22 release 2020-04-15 16:10:54 +01:00
Jeremy Ruston
28fe82feff Merge branch 'tiddlywiki-com' 2020-04-15 16:03:38 +01:00
Jeremy Ruston
74eb7e8031 Release note update 2020-04-15 15:58:02 +01:00
Mario Pietsch
22802b4be8 Action create tiddler improvements (#4436)
* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* add $template and $overwrite parameter

* documentation for new parameters + 4 new examples

* remove unwanted files
2020-04-15 15:51:21 +01:00
Jeremy Ruston
7cbe766bde Utils: ParseInt should specify a radix
Thanks @pmario
2020-04-15 15:28:03 +01:00
Jeremy Ruston
f21d013241 jsontiddlers macro: parse "spaces" parameter as integer 2020-04-15 15:27:53 +01:00
Mario Pietsch
de5b0062b5 Add new parameters to fields-widget and fields-operator. (#4433)
* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* extend fields-widget with include/exclude/sort/reverse and fields-filter with include and exclude params plus DOCS

* remove new-line

* remove eslint settings

* restore old eslint settings

* remove typo
2020-04-15 12:36:48 +01:00
Mario Pietsch
2b6c87fb4b Remove unwanted whitespace from sidebar links (#4552)
* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* fix 4532. Links should not add unwanted whitespace, since this causes problems with CSS styling

* remove whitespace from tiddler title and add a little bit of margin-right to the tiddler icon.

* use default parameters for link handling, which results in less code

* introduce tc-viewswitcher class to be able to style icon distance to text
2020-04-15 12:35:35 +01:00
Bram Chen
01226fbe90 Fix wrong configurations in tiddlywiki.info for editions zh-Hant and zh-Hans (#4564) 2020-04-15 10:24:46 +01:00
Jeremy Ruston
2f3a95a0b8 Plugin Chooser: Display libraries as separate tabs
Suggested by @kookma
2020-04-15 10:20:17 +01:00
Jeremy Ruston
6507397343 Update release note 2020-04-14 22:02:51 +01:00
Jeremy Ruston
69e6da9f5c Fix link 2020-04-14 22:02:40 +01:00
lin onetwo
161643c5da Fix: z-index for codemirror hint not large enough (#4551)
It is currently covered by other tiddler.
2020-04-14 21:53:18 +01:00
lin onetwo
1f313e8555 Signing the CLA to start contributing (#4562)
My Chinese name is Lin Dongwu, I will use that to sign it.
2020-04-14 21:52:11 +01:00
Mandar Vaze
bc3e5cda9e Add details about special tag in usage for ribbon (#4544)
Resolve #2581
2020-04-14 18:02:50 +01:00
Mandar Vaze
7900412fd0 Add Mandar Vaze to Individual Contrib. Agreement (#4543) 2020-04-14 18:02:28 +01:00
Cameron Fischer
65347ae858 Fixed join filter operator to never returns null (#4396)
If the operator were passed an empty list, it would return null
which could cause some proceeding operators to crash.
2020-04-14 17:49:38 +01:00
Cameron Fischer
43fdb553b7 Reduced indexOf calls in wiki.sortByList (#4275) (#4397)
Examined the tests in test-tag. They already cover all the use cases
I could think of.
2020-04-14 17:49:10 +01:00
scott willeke
4873e9447a fix the example path (#4419) 2020-04-14 17:47:46 +01:00
twMat
a8c55781fa Update ViewWidget.tid (#4441)
ref https://github.com/Jermolene/TiddlyWiki5/issues/4438
2020-04-14 17:16:07 +01:00
twMat
9313d9427d Update RevealWidget.tid (#4451) 2020-04-14 17:15:26 +01:00
twMat
5c3a19f298 Update RangeWidget.tid (#4453) 2020-04-14 17:14:59 +01:00
Joshua Fontany
69c8058b72 Add has:index (#4540)
* has:index

* has:index

* has:index docs

* has op examples

* has op examples

* operator macros typo missing </div>

* possible mistake
2020-04-14 16:52:56 +01:00
Jeremy Ruston
dc82365956 Update copyright date in license 2020-04-14 15:19:03 +01:00
Jeremy Ruston
27ab7d81b7 Merge branch 'tiddlywiki-com' 2020-04-14 15:16:38 +01:00
Jeremy Ruston
0836fb7184 Makelibrary.js: Minor refactoring 2020-04-14 12:08:15 +01:00
jed
4146a04a9e Fix makelibrary.js to use enviroment variable paths (#4559)
This makes makelibrary.js use environment variables to find paths for plugins, themes and languages instead of just using the paths hardcoded in boot.js
2020-04-14 12:03:12 +01:00
Jeremy Ruston
84eaee8210 Control Panel Plugin Listing: Fallback to last component of title if name field is missing 2020-04-14 11:52:01 +01:00
Jeremy Ruston
4bbc58dd24 Plugin Chooser: Ensure official plugin library is shown first 2020-04-13 11:45:06 +01:00
Jeremy Ruston
4529123777 Plugin Chooser: Colour of update all button should match individual update buttons
Fixes the final issue mentioned by @kookma at https://github.com/Jermolene/TiddlyWiki5/issues/4486#issuecomment-612841838
2020-04-13 11:38:53 +01:00
Jeremy Ruston
0d0698ea6e Plugin Chooser: Don't display the "already installed" message twice
Fixing the first issue here https://github.com/Jermolene/TiddlyWiki5/issues/4486#issuecomment-612841838 by @kookma
2020-04-13 11:35:52 +01:00
Jeremy Ruston
63dee16611 Plugin Chooser: Use separate tab state for each plugin library
Fixing the third issue at https://github.com/Jermolene/TiddlyWiki5/issues/4486#issuecomment-612841838 from @kookma
2020-04-13 11:28:24 +01:00
Bram Chen
bd0b9d5f81 Add chinese translations for AddPlugins things (#4546)
* Add chinese translations for AddPlugins things
* "updates" tab
* prompt for plugins that have subplugins

* Improve chinese wording

* Update chinese translations for AddPlugins
* add Plugins/Downgrade/Caption
* add Plugins/Update/Caption
* update Plugins/Updates/UpdateAll/Caption
2020-04-13 11:17:25 +01:00
Xavier Cazin
8310af068c Additional fr-FR translation for Control Panel (#4555)
* fr-FR translation for strings relative to plugin updates

* Missing fr-FR translation for a string in ControlPanel

* Missing fr-FR translation for Copy to Clipboard caption & hint

* Missing fr-FR translations for the Edit Template

* fr-FR translations for updates/upgrades in plugin chooser
2020-04-13 11:15:20 +01:00
Jeremy Ruston
4cc98e361c Release note update 2020-04-13 11:11:24 +01:00
Jeremy Ruston
dc98432fa0 Plugin Chooser: Use existing template for updates tab 2020-04-13 11:11:16 +01:00
Jeremy Ruston
fd9938f2cc Release note update 2020-04-13 10:04:37 +01:00
Jeremy Ruston
86296b67aa Plugin Chooser: Distinguish between install, reinstall, update and downgrade 2020-04-13 10:04:14 +01:00
Jeremy Ruston
245dab0c8c Plugin Chooser: Include currently installed version 2020-04-13 10:03:24 +01:00
Jeremy Ruston
7b53f5724c Add new compare filter operator
Fixes #4554
2020-04-13 10:03:01 +01:00
Jeremy Ruston
3733f8b4ae Release note update 2020-04-12 17:59:31 +01:00
Jeremy Ruston
308ac8c5b0 AddPlugins: Add new "updates" tab 2020-04-09 11:07:13 +01:00
Jeremy Ruston
bc8859b550 AddPlugins: Add a clearer prompt for plugins that have subplugins 2020-04-09 11:06:54 +01:00
Jeremy Ruston
bdc5ac592f Fix count widget to return "0" for an empty filter string instead of undefined 2020-04-09 11:04:50 +01:00
Jeremy Ruston
c80f580833 Remove internal version number info from dynnannotate plugin 2020-04-09 10:58:32 +01:00
Jeremy Ruston
1ed36adab6 New release banner
Congratulations @telmiger
2020-04-08 12:44:35 +01:00
Jeremy Ruston
5393187f66 Fix missing comma in editions/tw5.com/tiddlywiki.info 2020-04-08 11:47:08 +01:00
Rob Hoelz
72159c5118 Enable indexers in tag test (#4355)
Setting enableIndexers to an empty array ends up disabling all indexers
for the wiki
2020-04-07 20:44:26 +01:00
Matt Lauber
d2f2d7a11b Update jsonstringify Operator.tid (#4348) 2020-04-07 20:44:08 +01:00
Nils-Hero Lindemann
de5bb823fa Enable the internals plugin by default in docs (#4335)
* Enable the internals plugin by default in docs

1. Why hide such a useful thing from the users?

2. When playing around with code examples from the docs they may want to know how the resulting html looks.

* Improve doc

* Typo

Co-authored-by: Jeremy Ruston <jeremy@jermolene.com>
2020-04-07 20:41:00 +01:00
Nils-Hero Lindemann
322c37d693 Let chained > blockquotes generate valid HTML (#4332)
* Replace "p" with "div" in itemTag

'>> text' will now be valid html.

* Make the new div's behave like p's
2020-04-07 20:39:13 +01:00
Simon Huber
338cffd8c7 Add dependents to codemirror addons (#4278)
* use dependents in codemirror-autocomplete

* add dependents to codemirror-mode-htmlmixed

* add dependents to sublime keymap

* add dependents to vim keymap

* add dependents to htmlmixed mode

* add dependents to htmlembedded mode

* add dependents to markdown mode

* fix typo in markdown-mode

* fix typo in codemirror-mode-htmlembedded

* fix typo in codemirror-keymap-sublime

* fix typo in codemirror-keymap-vim

* fix typo in codemirror-mode-htmlembedded

* fix typo in codemirror-mode-markdown
2020-04-07 20:33:46 +01:00
Jeremy Ruston
e8506813fe Docs: fix broken link
Fixes #4266
2020-04-07 20:32:40 +01:00
Jeremy Ruston
fa86a90ef8 Add pull request template 2020-04-07 20:26:46 +01:00
Jeremy Ruston
291b1e2d33 Update issue templates 2020-04-07 20:21:49 +01:00
Mohammad Rahmani
9d4c05b6ce Signing the CLA (#4235)
Co-authored-by: Jeremy Ruston <jeremy@jermolene.com>
2020-04-07 17:48:21 +01:00
Jeremy Ruston
c7d8492842 Add support for woff2 files 2020-04-06 17:35:10 +01:00
Mario Pietsch
d1b8cce6bf Update German translations (#4539)
* add a new-line before the log text to increase readability of the test output

* make eslint, jslint happy

* it shouldn't be there

* fremove this file from my PRs

* update German translations
2020-04-06 16:54:13 +01:00
Jeremy Ruston
c259aea3bc Travis-CI: Fix nvm failing to install Node.js v12.4.0
Something must have changed on the travis-ci end to cause things to suddenly fail
2020-04-06 11:05:45 +01:00
Jeremy Ruston
59fd557067 Minor tweaks to plugin library listings
* Adds a name to the core plugin
* Make plugin listings consistently show "name: description"
* Make plugin listings consistently sort by title (thus grouping publishers)
* Add a missing plugin name

See discussion here: https://github.com/Jermolene/TiddlyWiki5/pull/4508#issuecomment-609671970
2020-04-06 10:15:18 +01:00
Xavier Cazin
06639850ba fr-FR translations catch up (#4535)
* fr-FR translated strings for the Gitea saver

* fr-FR translation for the _is_skinny description

* fr-FR translation for the Network Error alert

* fr-FR translation for Menu Bar colors

* fr-FR translation for the hint of the add button in EditTemplate

* fr-FR translation for the default focus field hint

* fr-FR translation for throttle.refresh field description

* fr-FR translation for Icon: None in TagManager

* fr-FR translation for Plugins "Also requires:"

* Add NewJournalTags.tid in fr-FR directory

* fr-FR translations for plugin related strings

* fr-FR translation for Sidebar visibility toggle hint

* fr-FR translation for the sidebar search hint

* fr-FR translation for two Palette Editor hints
2020-04-04 16:55:32 +01:00
saqimtiaz
21565f635e Fix range widget for IE10/11 (#4534)
As detailed in #4519 the range widget currently does not save its value to the state tiddler on IE 10/11 as they do not support the input event, but rather the change event is fired instead of the input event. This has patch has been tested in IE11 and should work in IE10 as well.

Note that on Chrome and Firefox, the change event will fire only once after the user stops dragging the range slider (In addition the input event). However this does lead to an extra refresh as the handleInputEvent method already checks to see if the current value of the slider is different from the saved value before saving to the store.
2020-04-03 13:07:55 +01:00
Jeremy Ruston
cf46b6b0ff Add "class" attribute to dropzone widget 2020-04-03 10:33:39 +01:00
saqimtiaz
bd449a177b Update documentation for Modals (#4495)
Update documentation for modals to include the custom class introduced in #4485, as well as the footer and subtitle fields that don't appear to be documented.
2020-04-02 19:49:41 +01:00
Simon Huber
bbdebb27ce Add TiddlyDesktop's wikilist colours to Gruvbox palette (#4521) 2020-04-02 17:29:24 +01:00
735 changed files with 12649 additions and 2705 deletions

15
.eslintignore Normal file
View File

@@ -0,0 +1,15 @@
# Known minified files
/boot/sjcl.js
/core/modules/utils/base64-utf8/base64-utf8.module.min.js
/core/modules/utils/diff-match-patch/diff_match_patch.js
/plugins/tiddlywiki/async/files/async.min.v1.5.0.js
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/anyword-hint.js
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/css-hint.js
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/html-hint.js
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/javascript-hint.js
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/show-hint.js
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/xml-hint.js
/plugins/tiddlywiki/codemirror-closebrackets/files/addon/edit/closebrackets.js
/plugins/tiddlywiki/codemirror-closebrackets/files/addon/edit/matchbrackets.js
/plugins/tiddlywiki/codemirror-closetag/files/addon/edit/closetag.js
/plugins/tiddlywiki/codemirror-closetag/files/addon/fold/xml-fold.js

267
.eslintrc.yml Normal file
View File

@@ -0,0 +1,267 @@
env:
browser: true
commonjs: true
es2021: true
node: true
extends: 'eslint:recommended'
globals:
"$tw": "writable" # temporary
parserOptions:
ecmaVersion: 5
rules:
array-bracket-newline: 'off'
array-bracket-spacing: 'off'
array-callback-return: 'off'
array-element-newline: 'off'
arrow-body-style: error
arrow-parens:
- error
- as-needed
arrow-spacing:
- error
- after: true
before: true
block-scoped-var: 'off'
block-spacing: 'off'
brace-style: 'off'
callback-return: 'off'
camelcase: 'off'
capitalized-comments: 'off'
class-methods-use-this: error
comma-dangle: 'off'
comma-spacing: 'off'
comma-style: 'off'
complexity: 'off'
computed-property-spacing: 'off'
consistent-return: 'off'
consistent-this: 'off'
curly: 'off'
default-case: 'off'
default-case-last: error
default-param-last: error
dot-location: 'off'
dot-notation: 'off'
eol-last: 'off'
eqeqeq: 'off'
func-call-spacing: 'off'
func-name-matching: 'off'
func-names: 'off'
func-style: 'off'
function-call-argument-newline: 'off'
function-paren-newline: 'off'
generator-star-spacing: error
global-require: 'off'
grouped-accessor-pairs: error
guard-for-in: 'off'
handle-callback-err: 'off'
id-blacklist: error
id-denylist: error
id-length: 'off'
id-match: error
implicit-arrow-linebreak: error
indent: 'off'
indent-legacy: 'off'
init-declarations: 'off'
jsx-quotes: error
key-spacing: 'off'
keyword-spacing: 'off'
line-comment-position: 'off'
linebreak-style: 'off'
lines-around-comment: 'off'
lines-around-directive: 'off'
lines-between-class-members: error
max-classes-per-file: error
max-depth: 'off'
max-len: 'off'
max-lines: 'off'
max-lines-per-function: 'off'
max-nested-callbacks: error
max-params: 'off'
max-statements: 'off'
max-statements-per-line: 'off'
multiline-comment-style: 'off'
multiline-ternary: 'off'
new-parens: 'off'
newline-after-var: 'off'
newline-before-return: 'off'
newline-per-chained-call: 'off'
no-alert: 'off'
no-array-constructor: 'off'
no-await-in-loop: error
no-bitwise: 'off'
no-buffer-constructor: 'off'
no-caller: error
no-catch-shadow: 'off'
no-confusing-arrow: error
no-console: 'off'
no-constant-condition:
- error
- checkLoops: false
no-constructor-return: error
no-continue: 'off'
no-div-regex: 'off'
no-duplicate-imports: error
no-else-return: 'off'
no-empty-function: 'off'
no-eq-null: 'off'
no-eval: 'off'
no-extend-native: 'off'
no-extra-bind: 'off'
no-extra-label: 'off'
no-extra-parens: 'off'
no-floating-decimal: 'off'
no-implicit-coercion:
- error
- boolean: false
number: false
string: false
no-implicit-globals: 'off'
no-implied-eval: error
no-inline-comments: 'off'
no-invalid-this: 'off'
no-iterator: error
no-label-var: 'off'
no-labels: 'off'
no-lone-blocks: 'off'
no-lonely-if: 'off'
no-loop-func: 'off'
no-loss-of-precision: error
no-magic-numbers: 'off'
no-mixed-operators: 'off'
no-mixed-requires: 'off'
no-multi-assign: 'off'
no-multi-spaces: 'off'
no-multi-str: error
no-multiple-empty-lines: 'off'
no-native-reassign: 'off'
no-negated-condition: 'off'
no-negated-in-lhs: error
no-nested-ternary: 'off'
no-new: 'off'
no-new-func: 'off'
no-new-object: 'off'
no-new-require: error
no-new-wrappers: error
no-octal-escape: error
no-param-reassign: 'off'
no-path-concat: error
no-plusplus: 'off'
no-process-env: 'off'
no-process-exit: 'off'
no-promise-executor-return: error
no-proto: 'off'
no-restricted-exports: error
no-restricted-globals: error
no-restricted-imports: error
no-restricted-modules: error
no-restricted-properties: error
no-restricted-syntax: error
no-return-assign: 'off'
no-return-await: error
no-script-url: 'off'
no-self-compare: 'off'
no-sequences: 'off'
no-shadow: 'off'
no-spaced-func: 'off'
no-sync: 'off'
no-tabs: 'off'
no-template-curly-in-string: error
no-ternary: 'off'
no-throw-literal: 'off'
no-trailing-spaces: 'off'
no-undef-init: 'off'
no-undefined: 'off'
no-underscore-dangle: 'off'
no-unmodified-loop-condition: 'off'
no-unneeded-ternary: 'off'
no-unreachable-loop: error
no-unused-expressions: 'off'
no-use-before-define: 'off'
no-useless-backreference: error
no-useless-call: 'off'
no-useless-computed-key: error
no-useless-concat: 'off'
no-useless-constructor: error
no-useless-rename: error
no-useless-return: 'off'
no-var: 'off'
no-void: 'off'
no-warning-comments: 'off'
no-whitespace-before-property: error
nonblock-statement-body-position:
- error
- any
object-curly-newline: 'off'
object-curly-spacing: 'off'
object-property-newline: 'off'
object-shorthand: 'off'
one-var: 'off'
one-var-declaration-per-line: 'off'
operator-assignment: 'off'
operator-linebreak: 'off'
padded-blocks: 'off'
padding-line-between-statements: error
prefer-arrow-callback: 'off'
prefer-const: 'off'
prefer-destructuring: 'off'
prefer-exponentiation-operator: 'off'
prefer-named-capture-group: 'off'
prefer-numeric-literals: error
prefer-object-spread: 'off'
prefer-promise-reject-errors: error
prefer-reflect: 'off'
prefer-regex-literals: 'off'
prefer-rest-params: 'off'
prefer-spread: 'off'
prefer-template: 'off'
quote-props: 'off'
quotes: 'off'
radix: 'off'
require-atomic-updates: error
require-await: error
require-jsdoc: 'off'
require-unicode-regexp: 'off'
rest-spread-spacing: error
semi: 'off'
semi-spacing: 'off'
semi-style: 'off'
sort-imports: error
sort-keys: 'off'
sort-vars: 'off'
space-before-blocks: 'off'
space-before-function-paren: 'off'
space-in-parens: 'off'
space-infix-ops: 'off'
space-unary-ops: 'off'
spaced-comment: 'off'
strict: 'off'
switch-colon-spacing: 'off'
symbol-description: error
template-curly-spacing: error
template-tag-spacing: error
unicode-bom:
- error
- never
valid-jsdoc: 'off'
valid-typeof:
- error
- requireStringLiterals: false
vars-on-top: 'off'
wrap-iife: 'off'
wrap-regex: 'off'
yield-star-spacing: error
yoda: 'off'
# temporary rules
no-useless-escape: 'off'
no-unused-vars: 'off'
no-empty: 'off'
no-extra-semi: 'off'
no-redeclare: 'off'
no-control-regex: "off"
no-mixed-spaces-and-tabs: "off"
no-extra-boolean-cast: "off"
no-prototype-builtins: "off"
no-undef: "off"
no-unreachable: "off"
no-self-assign: "off"

38
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,38 @@
---
name: Bug report
about: Create a report to help us improve TiddlyWiki 5
title: "[BUG]"
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

View File

@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for TiddlyWiki 5
title: "[IDEA]"
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -0,0 +1,22 @@
---
name: Pull Request
about: Propose a change to TiddlyWiki 5
title: ""
labels: ''
assignees: ''
---
**Is your PR related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you are proposing**
A clear and concise description of the changes you are proposing. Include images to show visual changes.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
If you link to discussions elsewhere then please copy and paste the important text, and don't expect readers to scan the entire discussion to find the relevant part.

74
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,74 @@
on:
pull_request:
push:
branches:
- master
- tiddlywiki-com
env:
NODE_VERSION: "12"
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: "${{ env.NODE_VERSION }}"
- run: "./bin/test.sh"
build-prerelease:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/master'
needs: test
env:
TW5_BUILD_TIDDLYWIKI: "./tiddlywiki.js"
TW5_BUILD_MAIN_EDITION: "./editions/prerelease"
TW5_BUILD_OUTPUT: "./output/prerelease"
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: "${{ env.NODE_VERSION }}"
- run: "./bin/ci-pre-build.sh"
# There's another near-duplicate "Set dynamic environment variables" step in
# the `build-tiddlywiki-com` job.
# These _could_ be extracted as a script (or moved into `ci-pre-build.sh`) to do away with the
# duplication, but, the visibility that comes from having these in the workflow file seems
# valuable. Environment variables are global variables and setting them at the top-level
# makes sense.
# Time to reconsider this decision might be when this setup turns out to be mistake-prone.
- name: "Set dynamic environment variables"
run: |
TW5_BUILD_BRANCH=$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }')
echo "TW5_BUILD_BRANCH=${TW5_BUILD_BRANCH}" >> $GITHUB_ENV
echo "TW5_BUILD_VERSION=$(./bin/get-plugin-library-version-number)" >> $GITHUB_ENV
echo "TW5_BUILD_DETAILS=Prerelease built from branch '$TW5_BUILD_BRANCH' at commit $(git rev-parse HEAD) of $(git remote get-url origin) at $(date +'%F %T %Z')" >> $GITHUB_ENV
- run: "./bin/build-site.sh"
- run: "./bin/ci-push.sh"
env:
GH_TOKEN: ${{ secrets.GITHUBPUSHTOKEN }}
build-tiddlywiki-com:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/tiddlywiki-com'
needs: test
env:
TW5_BUILD_TIDDLYWIKI: "./node_modules/tiddlywiki/tiddlywiki.js"
TW5_BUILD_MAIN_EDITION: "./editions/tw5.com"
TW5_BUILD_OUTPUT: "./output"
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: "${{ env.NODE_VERSION }}"
- run: "./bin/ci-pre-build.sh"
# When making a change here, don't forget to see if it also applies to the step
# with the same name in the `build-prerelease` job.
- name: "Set dynamic environment variables"
run: |
TW5_BUILD_BRANCH=$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }')
echo "TW5_BUILD_BRANCH=${TW5_BUILD_BRANCH}" >> $GITHUB_ENV
echo "TW5_BUILD_VERSION=$(./bin/get-plugin-library-version-number)" >> $GITHUB_ENV
echo "TW5_BUILD_DETAILS=Built from branch '$TW5_BUILD_BRANCH' at commit $(git rev-parse HEAD) of $(git remote get-url origin) at $(date +'%F %T %Z')" >> $GITHUB_ENV
- run: "./bin/build-site.sh"
- run: "./bin/ci-push.sh"
env:
GH_TOKEN: ${{ secrets.GITHUBPUSHTOKEN }}

View File

@@ -1,35 +0,0 @@
language: node_js
node_js:
- "12.4.0"
stages:
- name: test
- name: build-prerelease
if: branch = "master"
- name: build-tiddlywiki-com
if: branch = "tiddlywiki-com"
jobs:
include:
- stage: test
script: ./bin/test.sh
- stage: build-prerelease
script:
- ./bin/travis-pre-build.sh
- export TW5_BUILD_TIDDLYWIKI='./tiddlywiki.js'
- export TW5_BUILD_VERSION=$(./bin/get-plugin-library-version-number)
- export TW5_BUILD_DETAILS="Prerelease built from branch '$TRAVIS_BRANCH' at commit $(git rev-parse HEAD) of $(git remote get-url origin) at $(date +'%F %T %Z')"
- export TW5_BUILD_MAIN_EDITION='./editions/prerelease'
- export TW5_BUILD_OUTPUT='./output/prerelease'
- ./bin/build-site.sh || travis_terminate 1
- ./bin/travis-push.sh || travis_terminate 1
- stage: build-tiddlywiki-com
script:
- ./bin/travis-pre-build.sh
- export TW5_BUILD_TIDDLYWIKI='./node_modules/tiddlywiki/tiddlywiki.js'
- export TW5_BUILD_VERSION=$(./bin/get-plugin-library-version-number)
- export TW5_BUILD_DETAILS="Built from branch '$TRAVIS_BRANCH' at commit $(git rev-parse HEAD) of $(git remote get-url origin) at $(date +'%F %T %Z')"
- export TW5_BUILD_MAIN_EDITION='./editions/tw5.com'
- export TW5_BUILD_OUTPUT='./output'
- ./bin/build-site.sh || travis_terminate 1
- ./bin/travis-push.sh || travis_terminate 1

View File

@@ -5,7 +5,7 @@
# Default to the current version number for building the plugin library
if [ -z "$TW5_BUILD_VERSION" ]; then
TW5_BUILD_VERSION=v5.1.21
TW5_BUILD_VERSION=v5.1.23
fi
echo "Using TW5_BUILD_VERSION as [$TW5_BUILD_VERSION]"

15
bin/ci-push.sh Executable file
View File

@@ -0,0 +1,15 @@
#!/bin/bash
# Push output back to GitHub
# Exit script immediately if any command fails
set -e
cd output
git config --global user.email "actions@github.com"
git config --global user.name "GitHub Actions"
git add -A .
git commit --message "GitHub build: $GITHUB_RUN_NUMBER of $TW5_BUILD_BRANCH ($(date +'%F %T %Z'))"
git remote add deploy "https://$GH_TOKEN@github.com/Jermolene/jermolene.github.io.git" &>/dev/null
git push deploy master &>/dev/null
cd ..

View File

@@ -1,20 +0,0 @@
#!/bin/bash
# Push output back to GitHub
cd output || exit 1
git config --global user.email "travis@travis-ci.org" || exit 1
git config --global user.name "Travis CI" || exit 1
git add -A . || exit 1
git commit --message "Travis build: $TRAVIS_BUILD_NUMBER of $TRAVIS_BRANCH ($(date +'%F %T %Z'))" || exit 1
git remote add deploy "https://$GH_TOKEN@github.com/Jermolene/jermolene.github.io.git" &>/dev/null || exit 1
git push deploy master &>/dev/null || exit 1
cd .. || exit 1

View File

@@ -0,0 +1,25 @@
#!/bin/bash
# Process translation updates made via the translators edition
# ./bin/update-translation-from-html-file.sh <language-code> <path-to-html-file>
# Assign and check parameters
LANGUAGE_CODE=$1
HTML_FILE_PATH=$2
if [ -z "$LANGUAGE_CODE" ]; then
echo "Missing parameter: language code"
exit 1
fi
if [ -z "$HTML_FILE_PATH" ]; then
echo "Missing parameter: path to HTML file"
exit 1
fi
./tiddlywiki.js editions/translators/ --verbose --unpackplugin $:/languages/$LANGUAGE_CODE --load $HTML_FILE_PATH --build output-files || exit 1
cp -R ./editions/translators/output/language/. ./languages/$LANGUAGE_CODE/ || exit 1

View File

@@ -267,8 +267,16 @@ $tw.utils.htmlDecode = function(s) {
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() {
var parts = window.location.href.split('#');
return "#" + (parts.length > 1 ? parts[1] : "");
var href = window.location.href;
var idx = href.indexOf('#');
if(idx === -1) {
return "#";
} else if(idx < href.length-1 && href[idx+1] === '#') {
// Special case: ignore location hash if it itself starts with a #
return "#";
} else {
return href.substring(idx);
}
};
/*
@@ -297,13 +305,21 @@ $tw.utils.stringifyDate = function(value) {
// Parse a date from a UTC YYYYMMDDHHMMSSmmm format string
$tw.utils.parseDate = function(value) {
if(typeof value === "string") {
return new Date(Date.UTC(parseInt(value.substr(0,4),10),
var negative = 1;
if(value.charAt(0) === "-") {
negative = -1;
value = value.substr(1);
}
var year = parseInt(value.substr(0,4),10) * negative,
d = new Date(Date.UTC(year,
parseInt(value.substr(4,2),10)-1,
parseInt(value.substr(6,2),10),
parseInt(value.substr(8,2)||"00",10),
parseInt(value.substr(10,2)||"00",10),
parseInt(value.substr(12,2)||"00",10),
parseInt(value.substr(14,3)||"000",10)));
d.setUTCFullYear(year); // See https://stackoverflow.com/a/5870822
return d;
} else if($tw.utils.isDate(value)) {
return value;
} else {
@@ -409,10 +425,10 @@ $tw.utils.resolvePath = function(sourcepath,rootpath) {
};
/*
Parse a semantic version string into its constituent parts
Parse a semantic version string into its constituent parts -- see https://semver.org
*/
$tw.utils.parseVersion = function(version) {
var match = /^((\d+)\.(\d+)\.(\d+))(?:-([\dA-Za-z\-]+(?:\.[\dA-Za-z\-]+)*))?(?:\+([\dA-Za-z\-]+(?:\.[\dA-Za-z\-]+)*))?$/.exec(version);
var match = /^v?((\d+)\.(\d+)\.(\d+))(?:-([\dA-Za-z\-]+(?:\.[\dA-Za-z\-]+)*))?(?:\+([\dA-Za-z\-]+(?:\.[\dA-Za-z\-]+)*))?$/.exec(version);
if(match) {
return {
version: match[1],
@@ -427,25 +443,37 @@ $tw.utils.parseVersion = function(version) {
}
};
/*
Returns +1 if the version string A is greater than the version string B, 0 if they are the same, and +1 if B is greater than A.
Missing or malformed version strings are parsed as 0.0.0
*/
$tw.utils.compareVersions = function(versionStringA,versionStringB) {
var defaultVersion = {
major: 0,
minor: 0,
patch: 0
},
versionA = $tw.utils.parseVersion(versionStringA) || defaultVersion,
versionB = $tw.utils.parseVersion(versionStringB) || defaultVersion,
diff = [
versionA.major - versionB.major,
versionA.minor - versionB.minor,
versionA.patch - versionB.patch
];
if((diff[0] > 0) || (diff[0] === 0 && diff[1] > 0) || (diff[0] === 0 & diff[1] === 0 & diff[2] > 0)) {
return +1;
} else if((diff[0] < 0) || (diff[0] === 0 && diff[1] < 0) || (diff[0] === 0 & diff[1] === 0 & diff[2] < 0)) {
return -1;
} else {
return 0;
}
};
/*
Returns true if the version string A is greater than the version string B. Returns true if the versions are the same
*/
$tw.utils.checkVersions = function(versionStringA,versionStringB) {
var defaultVersion = {
major: 0,
minor: 0,
patch: 0
},
versionA = $tw.utils.parseVersion(versionStringA) || defaultVersion,
versionB = $tw.utils.parseVersion(versionStringB) || defaultVersion,
diff = [
versionA.major - versionB.major,
versionA.minor - versionB.minor,
versionA.patch - versionB.patch
];
return (diff[0] > 0) ||
(diff[0] === 0 && diff[1] > 0) ||
(diff[0] === 0 && diff[1] === 0 && diff[2] >= 0);
return $tw.utils.compareVersions(versionStringA,versionStringB) !== -1;
};
/*
@@ -640,11 +668,13 @@ $tw.utils.PasswordPrompt.prototype.createPrompt = function(options) {
var promptInfo = {
serviceName: options.serviceName,
callback: options.callback,
form: form
form: form,
owner: this
};
this.passwordPrompts.push(promptInfo);
// Make sure the wrapper is displayed
this.setWrapperDisplay();
return promptInfo;
};
$tw.utils.PasswordPrompt.prototype.removePrompt = function(promptInfo) {
@@ -1258,7 +1288,7 @@ $tw.Wiki = function(options) {
$tw.utils.each(titles || getTiddlerTitles(),function(title) {
var tiddler = tiddlers[title];
if(tiddler) {
if(tiddler.fields.type === "application/json" && tiddler.hasField("plugin-type")) {
if(tiddler.fields.type === "application/json" && tiddler.hasField("plugin-type") && tiddler.fields.text) {
pluginInfo[tiddler.fields.title] = JSON.parse(tiddler.fields.text);
results.modifiedPlugins.push(tiddler.fields.title);
}
@@ -1810,7 +1840,7 @@ $tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
// Read the specification
var filesInfo = JSON.parse(fs.readFileSync(filepath + path.sep + "tiddlywiki.files","utf8"));
// Helper to process a file
var processFile = function(filename,isTiddlerFile,fields) {
var processFile = function(filename,isTiddlerFile,fields,isEditableFile) {
var extInfo = $tw.config.fileExtensionInfo[path.extname(filename)],
type = (extInfo || {}).type || fields.type || "text/plain",
typeInfo = $tw.config.contentTypeInfo[type] || {},
@@ -1863,7 +1893,11 @@ $tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
}
});
});
tiddlers.push({tiddlers: fileTiddlers});
if(isEditableFile) {
tiddlers.push({filepath: pathname, hasMetaFile: !!metadata && !isTiddlerFile, isEditableFile: true, tiddlers: fileTiddlers});
} else {
tiddlers.push({tiddlers: fileTiddlers});
}
};
// Process the listed tiddlers
$tw.utils.each(filesInfo.tiddlers,function(tidInfo) {
@@ -1886,15 +1920,21 @@ $tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
}
} else {
// Process directory specifier
var dirPath = path.resolve(filepath,dirSpec.path),
files = fs.readdirSync(dirPath),
fileRegExp = new RegExp(dirSpec.filesRegExp || "^.*$"),
metaRegExp = /^.*\.meta$/;
for(var t=0; t<files.length; t++) {
var filename = files[t];
if(filename !== "tiddlywiki.files" && !metaRegExp.test(filename) && fileRegExp.test(filename)) {
processFile(dirPath + path.sep + filename,dirSpec.isTiddlerFile,dirSpec.fields);
var dirPath = path.resolve(filepath,dirSpec.path);
if(fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory()) {
var files = fs.readdirSync(dirPath),
fileRegExp = new RegExp(dirSpec.filesRegExp || "^.*$"),
metaRegExp = /^.*\.meta$/;
for(var t=0; t<files.length; t++) {
var filename = files[t];
if(filename !== "tiddlywiki.files" && !metaRegExp.test(filename) && fileRegExp.test(filename)) {
processFile(dirPath + path.sep + filename,dirSpec.isTiddlerFile,dirSpec.fields,dirSpec.isEditableFile);
}
}
} else {
console.log("Warning: a directory in a tiddlywiki.files file does not exist.");
console.log("dirPath: " + dirPath);
console.log("tiddlywiki.files location: " + filepath);
}
}
});
@@ -2034,6 +2074,11 @@ $tw.loadWikiTiddlers = function(wikiPath,options) {
} else {
return null;
}
// Save the path to the tiddlers folder for the filesystemadaptor
var config = wikiInfo.config || {};
if($tw.boot.wikiPath == wikiPath) {
$tw.boot.wikiTiddlersPath = path.resolve($tw.boot.wikiPath,config["default-tiddler-location"] || $tw.config.wikiTiddlersSubDir);
}
// Load any parent wikis
if(wikiInfo.includeWikis) {
parentPaths = parentPaths.slice(0);
@@ -2067,27 +2112,30 @@ $tw.loadWikiTiddlers = function(wikiPath,options) {
$tw.boot.files[tiddler.title] = {
filepath: tiddlerFile.filepath,
type: tiddlerFile.type,
hasMetaFile: tiddlerFile.hasMetaFile
hasMetaFile: tiddlerFile.hasMetaFile,
isEditableFile: config["retain-original-tiddler-path"] || tiddlerFile.isEditableFile || tiddlerFile.filepath.indexOf($tw.boot.wikiTiddlersPath) !== 0
};
});
}
$tw.wiki.addTiddlers(tiddlerFile.tiddlers);
});
// Save the original tiddler file locations if requested
var config = wikiInfo.config || {};
if(config["retain-original-tiddler-path"]) {
var output = {}, relativePath;
if ($tw.boot.wikiPath == wikiPath) {
// Save the original tiddler file locations if requested
var output = {}, relativePath, fileInfo;
for(var title in $tw.boot.files) {
relativePath = path.relative(resolvedWikiPath,$tw.boot.files[title].filepath);
output[title] =
path.sep === "/" ?
relativePath :
relativePath.split(path.sep).join("/");
fileInfo = $tw.boot.files[title];
if(fileInfo.isEditableFile) {
relativePath = path.relative($tw.boot.wikiTiddlersPath,fileInfo.filepath);
output[title] =
path.sep === "/" ?
relativePath :
relativePath.split(path.sep).join("/");
}
}
if(Object.keys(output).length > 0){
$tw.wiki.addTiddler({title: "$:/config/OriginalTiddlerPaths", type: "application/json", text: JSON.stringify(output)});
}
$tw.wiki.addTiddler({title: "$:/config/OriginalTiddlerPaths", type: "application/json", text: JSON.stringify(output)});
}
// Save the path to the tiddlers folder for the filesystemadaptor
$tw.boot.wikiTiddlersPath = path.resolve($tw.boot.wikiPath,config["default-tiddler-location"] || $tw.config.wikiTiddlersSubDir);
// Load any plugins within the wiki folder
var wikiPluginsPath = path.resolve(wikiPath,$tw.config.wikiPluginsSubDir);
if(fs.existsSync(wikiPluginsPath)) {
@@ -2134,7 +2182,7 @@ $tw.loadTiddlersNode = function() {
// Load any extra plugins
$tw.utils.each($tw.boot.extraPlugins,function(name) {
if(name.charAt(0) === "+") { // Relative path to plugin
var pluginFields = $tw.loadPluginFolder(name.substring(1));;
var pluginFields = $tw.loadPluginFolder(name.substring(1));
if(pluginFields) {
$tw.wiki.addTiddler(pluginFields);
}
@@ -2160,8 +2208,7 @@ $tw.loadTiddlersNode = function() {
/*
Startup TiddlyWiki
*/
$tw.boot.startup = function(options) {
options = options || {};
$tw.boot.initStartup = function(options) {
// Get the URL hash and check for safe mode
$tw.locationHash = "#";
if($tw.browser && !$tw.node) {
@@ -2247,6 +2294,7 @@ $tw.boot.startup = function(options) {
$tw.utils.registerFileType("application/zip","base64",".zip");
$tw.utils.registerFileType("application/x-zip-compressed","base64",".zip");
$tw.utils.registerFileType("image/jpeg","base64",[".jpg",".jpeg"],{flags:["image"]});
$tw.utils.registerFileType("image/jpg","base64",[".jpg",".jpeg"],{flags:["image"]});
$tw.utils.registerFileType("image/png","base64",".png",{flags:["image"]});
$tw.utils.registerFileType("image/gif","base64",".gif",{flags:["image"]});
$tw.utils.registerFileType("image/webp","base64",".webp",{flags:["image"]});
@@ -2256,6 +2304,7 @@ $tw.boot.startup = function(options) {
$tw.utils.registerFileType("image/x-icon","base64",".ico",{flags:["image"]});
$tw.utils.registerFileType("application/font-woff","base64",".woff");
$tw.utils.registerFileType("application/x-font-ttf","base64",".woff");
$tw.utils.registerFileType("application/font-woff2","base64",".woff2");
$tw.utils.registerFileType("audio/ogg","base64",".ogg");
$tw.utils.registerFileType("video/ogg","base64",[".ogm",".ogv",".ogg"]);
$tw.utils.registerFileType("video/webm","base64",".webm");
@@ -2293,6 +2342,9 @@ $tw.boot.startup = function(options) {
return result;
}
}
};
$tw.boot.loadStartup = function(options){
// Load tiddlers
if($tw.boot.tasks.readBrowserTiddlers) {
$tw.loadTiddlersBrowser();
@@ -2305,6 +2357,8 @@ $tw.boot.startup = function(options) {
}
// Give hooks a chance to modify the store
$tw.hooks.invokeHook("th-boot-tiddlers-loaded");
}
$tw.boot.execStartup = function(options){
// Unpack plugin tiddlers
$tw.wiki.readPluginInfo();
$tw.wiki.registerPluginTiddlers("plugin",$tw.safeMode ? ["$:/core"] : undefined);
@@ -2333,6 +2387,16 @@ $tw.boot.startup = function(options) {
$tw.boot.disabledStartupModules = $tw.boot.disabledStartupModules || [];
// Repeatedly execute the next eligible task
$tw.boot.executeNextStartupTask(options.callback);
}
/*
Startup TiddlyWiki
*/
$tw.boot.startup = function(options) {
options = options || {};
// Get the URL hash and check for safe mode
$tw.boot.initStartup(options);
$tw.boot.loadStartup(options);
$tw.boot.execStartup(options);
};
/*

View File

@@ -1,4 +0,0 @@
title: $:/core/images/storyview-solo
tags: $:/tags/Image
<svg width="22pt" height="22pt" class="tc-image-storyview-single tc-image-button" viewBox="0 0 128 128"><path fill-rule="evenodd" d="M8.007 0A8.01 8.01 0 000 8.007v111.986A8.01 8.01 0 008.007 128h111.986a8.01 8.01 0 008.007-8.007V8.007A8.01 8.01 0 00119.993 0H8.007zm15.992 16A8 8 0 0016 24.009V71.99C16 76.414 19.588 80 24 80h80a8 8 0 008-8.009V24.01c0-4.423-3.588-8.009-8-8.009H24z"/></svg>

View File

@@ -17,6 +17,8 @@ Basics/NewJournal/Tags/Prompt: Tags for new journal tiddlers
Basics/NewTiddler/Title/Prompt: Title of new tiddlers
Basics/NewTiddler/Tags/Prompt: Tags for new tiddlers
Basics/OverriddenShadowTiddlers/Prompt: Number of overridden shadow tiddlers
Basics/RemoveTags: Update to current format
Basics/RemoveTags/Hint: Update the tags configuration to the latest format
Basics/ShadowTiddlers/Prompt: Number of shadow tiddlers
Basics/Subtitle/Prompt: Subtitle
Basics/SystemTiddlers/Prompt: Number of system tiddlers
@@ -44,6 +46,7 @@ KeyboardShortcuts/Platform/Linux: Linux platform only
KeyboardShortcuts/Platform/NonLinux: Non-Linux platforms only
KeyboardShortcuts/Platform/Windows: Windows platform only
KeyboardShortcuts/Platform/NonWindows: Non-Windows platforms only
LayoutSwitcher/Caption: Layout
LoadedModules/Caption: Loaded Modules
LoadedModules/Hint: These are the currently loaded tiddler modules linked to their source tiddlers. Any italicised modules lack a source tiddler, typically because they were setup during the boot process.
Palette/Caption: Palette
@@ -70,6 +73,7 @@ Plugins/Caption: Plugins
Plugins/Disable/Caption: disable
Plugins/Disable/Hint: Disable this plugin when reloading page
Plugins/Disabled/Status: (disabled)
Plugins/Downgrade/Caption: downgrade
Plugins/Empty/Hint: None
Plugins/Enable/Caption: enable
Plugins/Enable/Hint: Enable this plugin when reloading page
@@ -87,6 +91,11 @@ Plugins/Plugins/Hint: Plugins
Plugins/Reinstall/Caption: reinstall
Plugins/Themes/Caption: Themes
Plugins/Themes/Hint: Theme plugins
Plugins/Update/Caption: update
Plugins/Updates/Caption: Updates
Plugins/Updates/Hint: Available updates to installed plugins
Plugins/Updates/UpdateAll/Caption: Update <<update-count>> plugins
Plugins/SubPluginPrompt: With <<count>> sub-plugins available
Saving/Caption: Saving
Saving/DownloadSaver/AutoSave/Description: Permit automatic saving for the download saver
Saving/DownloadSaver/AutoSave/Hint: Enable Autosave for Download Saver
@@ -111,6 +120,7 @@ Saving/GitService/Gitea/Caption: Gitea Saver
Saving/GitService/Gitea/Password: Personal access token for API (via Giteas web interface: `Settings | Applications | Generate New Token`)
Saving/TiddlySpot/Advanced/Heading: Advanced Settings
Saving/TiddlySpot/BackupDir: Backup Directory
Saving/TiddlySpot/ControlPanel: ~TiddlySpot Control Panel
Saving/TiddlySpot/Backups: Backups
Saving/TiddlySpot/Caption: ~TiddlySpot Saver
Saving/TiddlySpot/Description: These settings are only used when saving to http://tiddlyspot.com or a compatible remote server
@@ -118,6 +128,7 @@ Saving/TiddlySpot/Filename: Upload Filename
Saving/TiddlySpot/Heading: ~TiddlySpot
Saving/TiddlySpot/Hint: //The server URL defaults to `http://<wikiname>.tiddlyspot.com/store.cgi` and can be changed to use a custom server address, e.g. `http://example.com/store.php`.//
Saving/TiddlySpot/Password: Password
Saving/TiddlySpot/ReadOnly: The ~TiddlySpot service is currently only available in read-only form. Please see http://tiddlyspot.com/ for the latest details. The ~TiddlySpot saver can still be used to save to compatible servers.
Saving/TiddlySpot/ServerURL: Server URL
Saving/TiddlySpot/UploadDir: Upload Directory
Saving/TiddlySpot/UserName: Wiki Name

View File

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

View File

@@ -6,13 +6,13 @@ description: Render tiddlers matching a filter to a specified ContentType
Render a set of tiddlers matching a filter to separate files of a specified ContentType (defaults to `text/html`) and extension (defaults to `.html`).
```
--rendertiddlers <filter> <template> <pathname> [<type>] [<extension>] ["noclean"]
--rendertiddlers '<filter>' <template> <pathname> [<type>] [<extension>] ["noclean"]
```
For example:
```
--rendertiddlers [!is[system]] $:/core/templates/static.tiddler.html ./static text/plain
--rendertiddlers '[!is[system]]' $:/core/templates/static.tiddler.html ./static text/plain
```
By default, the pathname is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.

View File

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

View File

@@ -10,6 +10,7 @@ ConfirmCancelTiddler: Do you wish to discard changes to the tiddler "<$text text
ConfirmDeleteTiddler: Do you wish to delete the tiddler "<$text text=<<title>>/>"?
ConfirmOverwriteTiddler: Do you wish to overwrite the tiddler "<$text text=<<title>>/>"?
ConfirmEditShadowTiddler: You are about to edit a ShadowTiddler. Any changes will override the default system making future upgrades non-trivial. Are you sure you want to edit "<$text text=<<title>>/>"?
ConfirmAction: Do you wish to proceed?
Count: count
DefaultNewTiddlerTitle: New Tiddler
Diffs/CountMessage: <<diff-count>> differences
@@ -26,7 +27,9 @@ Error/Caption: Error
Error/EditConflict: File changed on server
Error/Filter: Filter error
Error/FilterSyntax: Syntax error in filter expression
Error/FilterRunPrefix: Filter Error: Unknown prefix for filter run
Error/IsFilterOperator: Filter Error: Unknown operand for the 'is' filter operator
Error/FormatFilterOperator: Filter Error: Unknown suffix for the 'format' filter operator
Error/LoadingPluginLibrary: Error loading plugin library
Error/NetworkErrorAlert: `<h2>''Network Error''</h2>It looks like the connection to the server has been lost. This may indicate a problem with your network connection. Please attempt to restore network connectivity before continuing.<br><br>''Any unsaved changes will be automatically synchronised when connectivity is restored''.`
Error/RecursiveTransclusion: Recursive transclusion error in transclude widget
@@ -37,6 +40,7 @@ Error/XMLHttpRequest: XMLHttpRequest error code
InternalJavaScriptError/Title: Internal JavaScript Error
InternalJavaScriptError/Hint: Well, this is embarrassing. It is recommended that you restart TiddlyWiki by refreshing your browser
InvalidFieldName: Illegal characters in field name "<$text text=<<fieldName>>/>". Fields can only contain lowercase letters, digits and the characters underscore (`_`), hyphen (`-`) and period (`.`)
LayoutSwitcher/Description: Open the layout switcher
LazyLoadingWarning: <p>Trying to load external content from ''<$text text={{!!_canonical_uri}}/>''</p><p>If this message doesn't disappear, either the tiddler content type doesn't match the type of the external content, or you may be using a browser that doesn't support external content for wikis loaded as standalone files. See https://tiddlywiki.com/#ExternalText</p>
LoginToTiddlySpace: Login to TiddlySpace
Manager/Controls/FilterByTag/None: (none)
@@ -60,8 +64,23 @@ MissingTiddler/Hint: Missing tiddler "<$text text=<<currentTiddler>>/>" -- click
No: No
OfficialPluginLibrary: Official ~TiddlyWiki Plugin Library
OfficialPluginLibrary/Hint: The official ~TiddlyWiki plugin library at tiddlywiki.com. Plugins, themes and language packs are maintained by the core team.
PageTemplate/Description: the default ~TiddlyWiki layout
PageTemplate/Name: Default ~PageTemplate
PluginReloadWarning: Please save {{$:/core/ui/Buttons/save-wiki}} and reload {{$:/core/ui/Buttons/refresh}} to allow changes to ~JavaScript plugins to take effect
RecentChanges/DateFormat: DDth MMM YYYY
Shortcuts/Input/AdvancedSearch/Hint: Open the ~AdvancedSearch panel from within the sidebar search field
Shortcuts/Input/Accept/Hint: Accept the selected item
Shortcuts/Input/AcceptVariant/Hint: Accept the selected item (variant)
Shortcuts/Input/Cancel/Hint: Clear the input field
Shortcuts/Input/Down/Hint: Select the next item
Shortcuts/Input/Tab-Left/Hint: Select the previous Tab
Shortcuts/Input/Tab-Right/Hint: Select the next Tab
Shortcuts/Input/Up/Hint: Select the previous item
Shortcuts/SidebarLayout/Hint: Change the sidebar layout
Switcher/Subtitle/theme: Switch Theme
Switcher/Subtitle/layout: Switch Layout
Switcher/Subtitle/language: Switch Language
Switcher/Subtitle/palette: Switch Palette
SystemTiddler/Tooltip: This is a system tiddler
SystemTiddlers/Include/Prompt: Include system tiddlers
TagManager/Colour/Heading: Colour

View File

@@ -1,2 +1,3 @@
title: $:/config/NewJournal/Tags
tags: Journal
Journal

View File

@@ -4,7 +4,6 @@ All/Caption: All
Contents/Caption: Contents
Drafts/Caption: Drafts
Explorer/Caption: Explorer
History/Caption: History
Missing/Caption: Missing
More/Caption: More
Open/Caption: Open

View File

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

View File

@@ -71,7 +71,7 @@ Command.prototype.fetchFiles = function(options) {
if(options.url) {
urls = [options.url]
} else if(options.urlFilter) {
urls = $tw.wiki.filterTiddlers(options.urlFilter);
urls = this.commander.wiki.filterTiddlers(options.urlFilter);
} else {
return "Missing URL";
}

View File

@@ -33,7 +33,7 @@ Command.prototype.execute = function() {
tiddlers = {};
// Collect up the library plugins
var collectPlugins = function(folder) {
var pluginFolders = fs.readdirSync(folder);
var pluginFolders = $tw.utils.getSubdirectories(folder) || [];
for(var p=0; p<pluginFolders.length; p++) {
if(!$tw.boot.excludeRegExp.test(pluginFolders[p])) {
pluginFields = $tw.loadPluginFolder(path.resolve(folder,"./" + pluginFolders[p]));
@@ -44,16 +44,16 @@ Command.prototype.execute = function() {
}
},
collectPublisherPlugins = function(folder) {
var publisherFolders = fs.readdirSync(folder);
var publisherFolders = $tw.utils.getSubdirectories(folder) || [];
for(var t=0; t<publisherFolders.length; t++) {
if(!$tw.boot.excludeRegExp.test(publisherFolders[t])) {
collectPlugins(path.resolve(folder,"./" + publisherFolders[t]));
}
}
};
collectPublisherPlugins(path.resolve($tw.boot.corePath,$tw.config.pluginsPath));
collectPublisherPlugins(path.resolve($tw.boot.corePath,$tw.config.themesPath));
collectPlugins(path.resolve($tw.boot.corePath,$tw.config.languagesPath));
$tw.utils.each($tw.getLibraryItemSearchPaths($tw.config.pluginsPath,$tw.config.pluginsEnvVar),collectPublisherPlugins);
$tw.utils.each($tw.getLibraryItemSearchPaths($tw.config.themesPath,$tw.config.themesEnvVar),collectPublisherPlugins);
$tw.utils.each($tw.getLibraryItemSearchPaths($tw.config.languagesPath,$tw.config.languagesEnvVar),collectPlugins);
// Save the upgrade library tiddler
var pluginFields = {
title: upgradeLibraryTitle,

View File

@@ -5,10 +5,12 @@ module-type: command
Command to save the subtiddlers of a bundle tiddler as a series of JSON files
--savelibrarytiddlers <tiddler> <pathname> <skinnylisting>
--savelibrarytiddlers <tiddler> <tiddler-filter> <pathname> <skinnylisting>
The tiddler identifies the bundle tiddler that contains the subtiddlers.
The tiddler filter specifies the plugins to be included.
The pathname specifies the pathname to the folder in which the JSON files should be saved. The filename is the URL encoded title of the subtiddler.
The skinnylisting specifies the title of the tiddler to which a JSON catalogue of the subtiddlers will be saved. The JSON file contains the same data as the bundle tiddler but with the `text` field removed.
@@ -69,7 +71,7 @@ Command.prototype.execute = function() {
// Collect the skinny list data
var pluginTiddlers = JSON.parse(tiddler.text),
readmeContent = (pluginTiddlers.tiddlers[title + "/readme"] || {}).text,
doesRequireReload = !!$tw.wiki.doesPluginInfoRequireReload(pluginTiddlers),
doesRequireReload = !!self.commander.wiki.doesPluginInfoRequireReload(pluginTiddlers),
iconTiddler = pluginTiddlers.tiddlers[title + "/icon"] || {},
iconType = iconTiddler.type,
iconText = iconTiddler.text,

View File

@@ -42,7 +42,6 @@ function FramedEngine(options) {
this.iframeNode.style.border = "none";
this.iframeNode.style.padding = "0";
this.iframeNode.style.resize = "none";
this.iframeNode.style["background-color"] = this.widget.wiki.extractTiddlerDataItem(this.widget.wiki.getTiddlerText("$:/palette"),"tiddler-editor-background");
this.iframeDoc.body.style.margin = "0";
this.iframeDoc.body.style.padding = "0";
this.widget.domNodes.push(this.iframeNode);
@@ -74,13 +73,20 @@ function FramedEngine(options) {
if(this.widget.editTabIndex) {
this.iframeNode.setAttribute("tabindex",this.widget.editTabIndex);
}
if(this.widget.editAutoComplete) {
this.domNode.setAttribute("autocomplete",this.widget.editAutoComplete);
}
if(this.widget.isDisabled === "yes") {
this.domNode.setAttribute("disabled",true);
}
// Copy the styles from the dummy textarea
this.copyStyles();
// Add event listeners
$tw.utils.addEventListeners(this.domNode,[
{name: "click",handlerObject: this,handlerMethod: "handleClickEvent"},
{name: "input",handlerObject: this,handlerMethod: "handleInputEvent"},
{name: "keydown",handlerObject: this.widget,handlerMethod: "handleKeydownEvent"}
{name: "keydown",handlerObject: this.widget,handlerMethod: "handleKeydownEvent"},
{name: "focus",handlerObject: this,handlerMethod: "handleFocusEvent"}
]);
// Insert the element into the DOM
this.iframeDoc.body.appendChild(this.domNode);
@@ -96,7 +102,6 @@ FramedEngine.prototype.copyStyles = function() {
this.domNode.style.display = "block";
this.domNode.style.width = "100%";
this.domNode.style.margin = "0";
this.domNode.style["background-color"] = this.widget.wiki.extractTiddlerDataItem(this.widget.wiki.getTiddlerText("$:/palette"),"tiddler-editor-background");
// In Chrome setting -webkit-text-fill-color overrides the placeholder text colour
this.domNode.style["-webkit-text-fill-color"] = "currentcolor";
};
@@ -107,13 +112,20 @@ Set the text of the engine if it doesn't currently have focus
FramedEngine.prototype.setText = function(text,type) {
if(!this.domNode.isTiddlyWikiFakeDom) {
if(this.domNode.ownerDocument.activeElement !== this.domNode) {
this.domNode.value = text;
this.updateDomNodeText(text);
}
// Fix the height if needed
this.fixHeight();
}
};
/*
Update the DomNode with the new text
*/
FramedEngine.prototype.updateDomNodeText = function(text) {
this.domNode.value = text;
};
/*
Get the text of the engine
*/
@@ -153,6 +165,15 @@ FramedEngine.prototype.focus = function() {
}
};
/*
Handle a focus event
*/
FramedEngine.prototype.handleFocusEvent = function(event) {
if(this.widget.editCancelPopups) {
$tw.popup.cancel(0);
}
};
/*
Handle a click
*/
@@ -167,6 +188,9 @@ Handle a dom "input" event which occurs when the text has changed
FramedEngine.prototype.handleInputEvent = function(event) {
this.widget.saveChanges(this.getText());
this.fixHeight();
if(this.widget.editInputActions) {
this.widget.invokeActionString(this.widget.editInputActions);
}
return true;
};

View File

@@ -52,6 +52,12 @@ function SimpleEngine(options) {
if(this.widget.editTabIndex) {
this.domNode.setAttribute("tabindex",this.widget.editTabIndex);
}
if(this.widget.editAutoComplete) {
this.domNode.setAttribute("autocomplete",this.widget.editAutoComplete);
}
if(this.widget.isDisabled === "yes") {
this.domNode.setAttribute("disabled",true);
}
// Add an input event handler
$tw.utils.addEventListeners(this.domNode,[
{name: "focus", handlerObject: this, handlerMethod: "handleFocusEvent"},
@@ -68,13 +74,20 @@ 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.domNode.value = text;
this.updateDomNodeText(text);
}
// Fix the height if needed
this.fixHeight();
}
};
/*
Update the DomNode with the new text
*/
SimpleEngine.prototype.updateDomNodeText = function(text) {
this.domNode.value = text;
};
/*
Get the text of the engine
*/
@@ -115,6 +128,9 @@ Handle a dom "input" event which occurs when the text has changed
SimpleEngine.prototype.handleInputEvent = function(event) {
this.widget.saveChanges(this.getText());
this.fixHeight();
if(this.widget.editInputActions) {
this.widget.invokeActionString(this.widget.editInputActions);
}
return true;
};
@@ -122,6 +138,9 @@ SimpleEngine.prototype.handleInputEvent = function(event) {
Handle a dom "focus" event
*/
SimpleEngine.prototype.handleFocusEvent = function(event) {
if(this.widget.editCancelPopups) {
$tw.popup.cancel(0);
}
if(this.widget.editFocusPopup) {
$tw.popup.triggerPopup({
domNode: this.domNode,

View File

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

View File

@@ -0,0 +1,25 @@
/*\
title: $:/core/modules/filterrunprefixes/all.js
type: application/javascript
module-type: filterrunprefix
Union of sets without de-duplication.
Equivalent to = filter run prefix.
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter prefix function
*/
exports.all = function(operationSubFunction) {
return function(results,source,widget) {
results.push.apply(results, operationSubFunction(source,widget));
};
};
})();

View File

@@ -0,0 +1,28 @@
/*\
title: $:/core/modules/filterrunprefixes/and.js
type: application/javascript
module-type: filterrunprefix
Intersection of sets.
Equivalent to + filter run prefix.
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"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
source = options.wiki.makeTiddlerIterator(results.toArray());
results.clear();
results.pushTop(operationSubFunction(source,widget));
};
};
})();

View File

@@ -0,0 +1,27 @@
/*\
title: $:/core/modules/filterrunprefixes/else.js
type: application/javascript
module-type: filterrunprefix
Equivalent to ~ filter run prefix.
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter prefix function
*/
exports.else = function(operationSubFunction) {
return function(results,source,widget) {
if(results.length === 0) {
// Main result so far is empty
results.pushTop(operationSubFunction(source,widget));
}
};
};
})();

View File

@@ -0,0 +1,25 @@
/*\
title: $:/core/modules/filterrunprefixes/except.js
type: application/javascript
module-type: filterrunprefix
Difference of sets.
Equivalent to - filter run prefix.
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter prefix function
*/
exports.except = function(operationSubFunction) {
return function(results,source,widget) {
results.remove(operationSubFunction(source,widget));
};
};
})();

View File

@@ -0,0 +1,31 @@
/*\
title: $:/core/modules/filterrunprefixes/filter.js
type: application/javascript
module-type: filterrunprefix
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.filter = function(operationSubFunction,options) {
return function(results,source,widget) {
if(results.length > 0) {
var resultsToRemove = [];
results.each(function(result) {
var filtered = operationSubFunction(options.wiki.makeTiddlerIterator([result]),widget);
if(filtered.length === 0) {
resultsToRemove.push(result);
}
});
results.remove(resultsToRemove);
}
}
};
})();

View File

@@ -0,0 +1,31 @@
/*\
title: $:/core/modules/filterrunprefixes/intersection.js
type: application/javascript
module-type: filterrunprefix
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter prefix function
*/
exports.intersection = function(operationSubFunction) {
return function(results,source,widget) {
if(results.length !== 0) {
var secondRunResults = operationSubFunction(source,widget);
var firstRunResults = results.toArray();
results.clear();
$tw.utils.each(firstRunResults,function(title) {
if(secondRunResults.indexOf(title) !== -1) {
results.push(title);
}
});
}
};
};
})();

View File

@@ -0,0 +1,24 @@
/*\
title: $:/core/modules/filterrunprefixes/or.js
type: application/javascript
module-type: filterrunprefix
Equivalent to a filter run with no prefix.
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter prefix function
*/
exports.or = function(operationSubFunction) {
return function(results,source,widget) {
results.pushTop(operationSubFunction(source,widget));
};
};
})();

View File

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

View File

@@ -62,43 +62,61 @@ function parseFilterOperation(operators,filterString,p) {
else if(operator.operator === "") {
operator.operator = "title";
}
operator.operands = [];
function parseOperand(bracketType) {
var operand = {};
switch (bracketType) {
case "{": // Curly brackets
operand.indirect = true;
nextBracketPos = filterString.indexOf("}",p);
break;
case "[": // Square brackets
nextBracketPos = filterString.indexOf("]",p);
break;
case "<": // Angle brackets
operand.variable = true;
nextBracketPos = filterString.indexOf(">",p);
break;
case "/": // regexp brackets
var rex = /^((?:[^\\\/]*|\\.)*)\/(?:\(([mygi]+)\))?/g,
rexMatch = rex.exec(filterString.substring(p));
if(rexMatch) {
operator.regexp = new RegExp(rexMatch[1], rexMatch[2]);
// DEPRECATION WARNING
console.log("WARNING: Filter",operator.operator,"has a deprecated regexp operand",operator.regexp);
nextBracketPos = p + rex.lastIndex - 1;
}
else {
throw "Unterminated regular expression in filter expression";
}
break;
}
if(nextBracketPos === -1) {
throw "Missing closing bracket in filter expression";
}
if(!operator.regexp) {
operand.text = filterString.substring(p,nextBracketPos);
operator.operands.push(operand);
}
p = nextBracketPos + 1;
}
p = nextBracketPos + 1;
switch (bracket) {
case "{": // Curly brackets
operator.indirect = true;
nextBracketPos = filterString.indexOf("}",p);
break;
case "[": // Square brackets
nextBracketPos = filterString.indexOf("]",p);
break;
case "<": // Angle brackets
operator.variable = true;
nextBracketPos = filterString.indexOf(">",p);
break;
case "/": // regexp brackets
var rex = /^((?:[^\\\/]*|\\.)*)\/(?:\(([mygi]+)\))?/g,
rexMatch = rex.exec(filterString.substring(p));
if(rexMatch) {
operator.regexp = new RegExp(rexMatch[1], rexMatch[2]);
// DEPRECATION WARNING
console.log("WARNING: Filter",operator.operator,"has a deprecated regexp operand",operator.regexp);
nextBracketPos = p + rex.lastIndex - 1;
}
else {
throw "Unterminated regular expression in filter expression";
}
break;
parseOperand(bracket);
// Check for multiple operands
while(filterString.charAt(p) === ",") {
p++;
if(/^[\[\{<\/]/.test(filterString.substring(p))) {
nextBracketPos = p;
p++;
parseOperand(filterString.charAt(nextBracketPos));
} else {
throw "Missing [ in filter expression";
}
}
if(nextBracketPos === -1) {
throw "Missing closing bracket in filter expression";
}
if(!operator.regexp) {
operator.operand = filterString.substring(p,nextBracketPos);
}
p = nextBracketPos + 1;
// Push this operator
operators.push(operator);
} while(filterString.charAt(p) !== "]");
@@ -119,7 +137,7 @@ exports.parseFilter = function(filterString) {
p = 0, // Current position in the filter string
match;
var whitespaceRegExp = /(\s+)/mg,
operandRegExp = /((?:\+|\-|~|=)?)(?:(\[)|(?:"([^"]*)")|(?:'([^']*)')|([^\s\[\]]+))/mg;
operandRegExp = /((?:\+|\-|~|=|\:(\w+))?)(?:(\[)|(?:"([^"]*)")|(?:'([^']*)')|([^\s\[\]]+))/mg;
while(p < filterString.length) {
// Skip any whitespace
whitespaceRegExp.lastIndex = p;
@@ -140,16 +158,19 @@ exports.parseFilter = function(filterString) {
};
if(match[1]) {
operation.prefix = match[1];
p++;
p = p + operation.prefix.length;
if(match[2]) {
operation.namedPrefix = match[2];
}
}
if(match[2]) { // Opening square bracket
if(match[3]) { // Opening square bracket
p = parseFilterOperation(operation.operators,filterString,p);
} else {
p = match.index + match[0].length;
}
if(match[3] || match[4] || match[5]) { // Double quoted string, single quoted string or unquoted title
if(match[4] || match[5] || match[6]) { // Double quoted string, single quoted string or unquoted title
operation.operators.push(
{operator: "title", operand: match[3] || match[4] || match[5]}
{operator: "title", operands: [{text: match[4] || match[5] || match[6]}]}
);
}
results.push(operation);
@@ -166,6 +187,14 @@ exports.getFilterOperators = function() {
return this.filterOperators;
};
exports.getFilterRunPrefixes = function() {
if(!this.filterRunPrefixes) {
$tw.Wiki.prototype.filterRunPrefixes = {};
$tw.modules.applyMethods("filterrunprefix",this.filterRunPrefixes);
}
return this.filterRunPrefixes;
}
exports.filterTiddlers = function(filterString,widget,source) {
var fn = this.compileFilter(filterString);
return fn.call(this,source,widget);
@@ -198,7 +227,7 @@ exports.compileFilter = function(filterString) {
results = [],
currTiddlerTitle = widget && widget.getVariable("currentTiddler");
$tw.utils.each(operation.operators,function(operator) {
var operand = operator.operand,
var operands = [],
operatorFunction;
if(!operator.operator) {
operatorFunction = filterOperators.title;
@@ -207,16 +236,23 @@ exports.compileFilter = function(filterString) {
} else {
operatorFunction = filterOperators[operator.operator];
}
if(operator.indirect) {
operand = self.getTextReference(operator.operand,"",currTiddlerTitle);
}
if(operator.variable) {
operand = widget.getVariable(operator.operand,{defaultValue: ""});
}
$tw.utils.each(operator.operands,function(operand) {
if(operand.indirect) {
operand.value = self.getTextReference(operand.text,"",currTiddlerTitle);
} else if(operand.variable) {
operand.value = widget.getVariable(operand.text,{defaultValue: ""});
} else {
operand.value = operand.text;
}
operands.push(operand.value);
});
// Invoke the appropriate filteroperator module
results = operatorFunction(accumulator,{
operator: operator.operator,
operand: operand,
operand: operands.length > 0 ? operands[0] : undefined,
operands: operands,
prefix: operator.prefix,
suffix: operator.suffix,
suffixes: operator.suffixes,
@@ -241,35 +277,30 @@ exports.compileFilter = function(filterString) {
return resultArray;
}
};
var filterRunPrefixes = self.getFilterRunPrefixes();
// Wrap the operator functions in a wrapper function that depends on the prefix
operationFunctions.push((function() {
var options = {wiki: self};
switch(operation.prefix || "") {
case "": // No prefix means that the operation is unioned into the result
return function(results,source,widget) {
$tw.utils.pushTop(results,operationSubFunction(source,widget));
};
return filterRunPrefixes["or"](operationSubFunction, options);
case "=": // The results of the operation are pushed into the result without deduplication
return function(results,source,widget) {
Array.prototype.push.apply(results,operationSubFunction(source,widget));
};
return filterRunPrefixes["all"](operationSubFunction, options);
case "-": // The results of this operation are removed from the main result
return function(results,source,widget) {
$tw.utils.removeArrayEntries(results,operationSubFunction(source,widget));
};
return filterRunPrefixes["except"](operationSubFunction, options);
case "+": // This operation is applied to the main results so far
return function(results,source,widget) {
// This replaces all the elements of the array, but keeps the actual array so that references to it are preserved
source = self.makeTiddlerIterator(results);
results.splice(0,results.length);
$tw.utils.pushTop(results,operationSubFunction(source,widget));
};
return filterRunPrefixes["and"](operationSubFunction, options);
case "~": // This operation is unioned into the result only if the main result so far is empty
return function(results,source,widget) {
if(results.length === 0) {
// Main result so far is empty
$tw.utils.pushTop(results,operationSubFunction(source,widget));
}
};
return filterRunPrefixes["else"](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"));
};
}
}
})());
});
@@ -280,11 +311,11 @@ exports.compileFilter = function(filterString) {
} else if(typeof source === "object") { // Array or hashmap
source = self.makeTiddlerIterator(source);
}
var results = [];
var results = new $tw.utils.LinkedList();
$tw.utils.each(operationFunctions,function(operationFunction) {
operationFunction(results,source,widget);
});
return results;
return results.toArray();
});
};

View File

@@ -0,0 +1,40 @@
/*\
title: $:/core/modules/filters/compare.js
type: application/javascript
module-type: filteroperator
General purpose comparison operator
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
exports.compare = function(source,operator,options) {
var suffixes = operator.suffixes || [],
type = (suffixes[0] || [])[0],
mode = (suffixes[1] || [])[0],
typeFn = $tw.utils.makeCompareFunction(type,{defaultType: "number"}),
modeFn = modes[mode] || modes.eq,
invert = operator.prefix === "!",
results = [];
source(function(tiddler,title) {
if(modeFn(typeFn(title,operator.operand)) !== invert) {
results.push(title);
}
});
return results;
};
var modes = {
"eq": function(value) {return value === 0;},
"ne": function(value) {return value !== 0;},
"gteq": function(value) {return value >= 0;},
"gt": function(value) {return value > 0;},
"lteq": function(value) {return value <= 0;},
"lt": function(value) {return value < 0;}
}
})();

View File

@@ -0,0 +1,36 @@
/*\
title: $:/core/modules/filters/duplicateslugs.js
type: application/javascript
module-type: filteroperator
Filter function for [duplicateslugs[]]
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"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 = [];
source(function(tiddler,title) {
var slug = options.wiki.slugify(title);
if(slug in slugs) {
if(slugs[slug] !== true) {
results.push(slugs[slug]);
slugs[slug] = true;
}
results.push(title);
} else {
slugs[slug] = title;
}
});
return results;
};
})();

View File

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

View File

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

View File

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

View File

@@ -16,13 +16,28 @@ Filter operator for returning the names of the fields on the selected tiddlers
Export our filter function
*/
exports.fields = function(source,operator,options) {
var results = [];
var results = [],
fieldName,
suffixes = (operator.suffixes || [])[0] || [],
operand = $tw.utils.parseStringArray(operator.operand);
source(function(tiddler,title) {
if(tiddler) {
for(var fieldName in tiddler.fields) {
$tw.utils.pushTop(results,fieldName);
}
}
if(suffixes.indexOf("include") !== -1) {
for(fieldName in tiddler.fields) {
(operand.indexOf(fieldName) !== -1) ? $tw.utils.pushTop(results,fieldName) : "";
}
} else if (suffixes.indexOf("exclude") !== -1) {
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;
};

View File

@@ -0,0 +1,31 @@
/*\
title: $:/core/modules/filters/filter.js
type: application/javascript
module-type: filteroperator
Filter operator returning those input titles that pass a subfilter
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.filter = function(source,operator,options) {
var filterFn = options.wiki.compileFilter(operator.operand),
results = [],
target = operator.prefix !== "!";
source(function(tiddler,title) {
var list = filterFn.call(options.wiki,options.wiki.makeTiddlerIterator([title]));
if((list.length > 0) === target) {
results.push(title);
}
});
return results;
};
})();

View File

@@ -0,0 +1,46 @@
/*\
title: $:/core/modules/filters/format.js
type: application/javascript
module-type: filteroperator
Filter operator for formatting strings
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var formatFilterOperators;
function getFormatFilterOperators() {
if(!formatFilterOperators) {
formatFilterOperators = {};
$tw.modules.applyMethods("formatfilteroperator",formatFilterOperators);
}
return formatFilterOperators;
}
/*
Export our filter function
*/
exports.format = function(source,operator,options) {
// Dispatch to the correct formatfilteroperator
var formatFilterOperators = getFormatFilterOperators();
if(operator.suffix) {
var formatFilterOperator = formatFilterOperators[operator.suffix];
if(formatFilterOperator) {
return formatFilterOperator(source,operator.operand,options);
} else {
return [$tw.language.getString("Error/FormatFilterOperator")];
}
} else {
// Return all unchanged if the suffix is missing
var results = [];
source(function(tiddler,title) {
results.push(title);
});
return results;
}
};
})();

View File

@@ -0,0 +1,26 @@
/*\
title: $:/core/modules/filters/format/date.js
type: application/javascript
module-type: formatfilteroperator
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.date = function(source,operand,options) {
var results = [];
source(function(tiddler,title) {
var value = $tw.utils.parseDate(title);
if(value && $tw.utils.isDate(value) && value.toString() !== "Invalid Date") {
results.push($tw.utils.formatDateString(value,operand || "YYYY MM DD 0hh:0mm"));
}
});
return results;
};
})();

View File

@@ -0,0 +1,26 @@
/*\
title: $:/core/modules/filters/format/relativedate.js
type: application/javascript
module-type: formatfilteroperator
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.relativedate = function(source,operand,options) {
var results = [];
source(function(tiddler,title) {
var value = $tw.utils.parseDate(title);
if(value && $tw.utils.isDate(value) && value.toString() !== "Invalid Date") {
results.push($tw.utils.getRelativeDate((new Date()) - (new Date(value))).description);
}
});
return results;
};
})();

View File

@@ -1,38 +0,0 @@
/*\
title: $:/core/modules/filters/getstoryviewmode.js
type: application/javascript
module-type: filteroperator
Filter operator for retrieving modes from a storyview. Only "singletiddlermode" is implemented at present
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter functions
*/
exports.getstoryviewmode = function(source,operator,options) {
// Initialise the storyviews if they've not been done already
var storyviews = {};
$tw.modules.applyMethods("storyview",storyviews);
if(operator.operand !== "singletiddlermode") {
return [];
}
var results = [];
source(function(tiddler,title) {
var storyview = storyviews[title];
if(storyview && storyview.singleTiddlerMode) {
results.push("yes");
} else {
results.push("no");
}
});
return results;
};
})();

View File

@@ -3,7 +3,7 @@ title: $:/core/modules/filters/has.js
type: application/javascript
module-type: filteroperator
Filter operator for checking if a tiddler has the specified field
Filter operator for checking if a tiddler has the specified field or index
\*/
(function(){
@@ -33,16 +33,32 @@ exports.has = function(source,operator,options) {
}
});
}
} else {
}
else if(operator.suffix === "index") {
if(invert) {
source(function(tiddler,title) {
if(!tiddler || !$tw.utils.hop(tiddler.fields,operator.operand) || (tiddler.fields[operator.operand] === "")) {
if(!tiddler || (tiddler && (!$tw.utils.hop(options.wiki.getTiddlerDataCached(tiddler,Object.create(null)),operator.operand)))) {
results.push(title);
}
});
} else {
source(function(tiddler,title) {
if(tiddler && $tw.utils.hop(tiddler.fields,operator.operand) && !(tiddler.fields[operator.operand] === "" || tiddler.fields[operator.operand].length === 0)) {
if(tiddler && $tw.utils.hop(options.wiki.getTiddlerDataCached(tiddler,Object.create(null)),operator.operand)) {
results.push(title);
}
});
}
}
else {
if(invert) {
source(function(tiddler,title) {
if(!tiddler || !$tw.utils.hop(tiddler.fields,operator.operand) || (tiddler.fields[operator.operand].length === 0)) {
results.push(title);
}
});
} else {
source(function(tiddler,title) {
if(tiddler && $tw.utils.hop(tiddler.fields,operator.operand) && (tiddler.fields[operator.operand].length !== 0)) {
results.push(title);
}
});

View File

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

View File

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

View File

@@ -91,6 +91,20 @@ exports.exponential = makeNumericBinaryOperator(
function(a,b) {return Number.prototype.toExponential.call(a,Math.min(Math.max(b,0),100));}
);
exports.power = makeNumericBinaryOperator(
function(a,b) {return Math.pow(a,b);}
);
exports.log = makeNumericBinaryOperator(
function(a,b) {
if(b) {
return Math.log(a)/Math.log(b);
} else {
return Math.log(a);
}
}
);
exports.sum = makeNumericReducingOperator(
function(accumulator,value) {return accumulator + value},
0 // Initial value
@@ -114,9 +128,9 @@ exports.minall = makeNumericReducingOperator(
function makeNumericBinaryOperator(fnCalc) {
return function(source,operator,options) {
var result = [],
numOperand = parseNumber(operator.operand);
numOperand = $tw.utils.parseNumber(operator.operand);
source(function(tiddler,title) {
result.push(stringifyNumber(fnCalc(parseNumber(title),numOperand)));
result.push($tw.utils.stringifyNumber(fnCalc($tw.utils.parseNumber(title),numOperand)));
});
return result;
};
@@ -129,18 +143,10 @@ function makeNumericReducingOperator(fnCalc,initialValue) {
source(function(tiddler,title) {
result.push(title);
});
return [stringifyNumber(result.reduce(function(accumulator,currentValue) {
return fnCalc(accumulator,parseNumber(currentValue));
return [$tw.utils.stringifyNumber(result.reduce(function(accumulator,currentValue) {
return fnCalc(accumulator,$tw.utils.parseNumber(currentValue));
},initialValue))];
};
}
function parseNumber(str) {
return parseFloat(str) || 0;
}
function stringifyNumber(num) {
return num + "";
}
})();

View File

@@ -0,0 +1,58 @@
/*\
title: $:/core/modules/filters/reduce.js
type: application/javascript
module-type: filteroperator
Filter operator evaluates a subfilter for each item, making the running total available in the variable `accumulator`, and the current index available in the variable `index`
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.reduce = function(source,operator,options) {
// Accumulate the list
var results = [];
source(function(tiddler,title) {
results.push(title);
});
// Run the filter over each item
var filterFn = options.wiki.compileFilter(operator.operand),
accumulator = operator.operands[1] || "";
for(var index=0; index<results.length; index++) {
var title = results[index],
list = filterFn.call(options.wiki,options.wiki.makeTiddlerIterator([title]),{
getVariable: function(name) {
switch(name) {
case "currentTiddler":
return "" + title;
case "accumulator":
return "" + accumulator;
case "index":
return "" + index;
case "revIndex":
return "" + (results.length - 1 - index);
case "length":
return "" + results.length;
default:
return options.widget.getVariable(name);
}
}
});
if(list.length > 0) {
accumulator = "" + list[0];
}
}
if(results.length > 0) {
return [accumulator];
} else {
return [];
}
};
})();

View File

@@ -0,0 +1,23 @@
/*\
title: $:/core/modules/filters/slugify.js
type: application/javascript
module-type: filteroperator
Filter operator for slugifying a tiddler title
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
exports.slugify = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
results.push(options.wiki.slugify(title));
});
return results;
};
})();

View File

@@ -0,0 +1,57 @@
/*\
title: $:/core/modules/filters/sortsub.js
type: application/javascript
module-type: filteroperator
Filter operator for sorting by a subfilter
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.sortsub = function(source,operator,options) {
// Compile the subfilter
var filterFn = options.wiki.compileFilter(operator.operand);
// Collect the input titles and the corresponding sort keys
var inputTitles = [],
sortKeys = [];
source(function(tiddler,title) {
inputTitles.push(title);
var r = filterFn.call(options.wiki,function(iterator) {
iterator(options.wiki.getTiddler(title),title);
},{
getVariable: function(name) {
if(name === "currentTiddler") {
return title;
} else {
return options.widget.getVariable(name);
}
}
});
sortKeys.push(r[0] || "");
});
// Rather than sorting the titles array, we'll sort the indexes so that we can consult both arrays
var indexes = new Array(inputTitles.length);
for(var t=0; t<inputTitles.length; t++) {
indexes[t] = t;
}
// Sort the indexes
var compareFn = $tw.utils.makeCompareFunction(operator.suffix,{defaultType: "string",invert: operator.prefix === "!"});
indexes = indexes.sort(function(a,b) {
return compareFn(sortKeys[a],sortKeys[b]);
});
// Make the results array in order
var results = [];
$tw.utils.each(indexes,function(index) {
results.push(inputTitles[index]);
});
return results;
};
})();

View File

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

View File

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

View File

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

View File

@@ -284,6 +284,20 @@ KeyboardManager.prototype.checkKeyDescriptors = function(event,keyInfoArray) {
return false;
};
KeyboardManager.prototype.getEventModifierKeyDescriptor = function(event) {
return event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey ? "ctrl" :
event.shiftKey && !event.ctrlKey && !event.altKey && !event.metaKey ? "shift" :
event.ctrlKey && event.shiftKey && !event.altKey && !event.metaKey ? "ctrl-shift" :
event.altKey && !event.shiftKey && !event.ctrlKey && !event.metaKey ? "alt" :
event.altKey && event.shiftKey && !event.ctrlKey && !event.metaKey ? "alt-shift" :
event.altKey && event.ctrlKey && !event.shiftKey && !event.metaKey ? "ctrl-alt" :
event.altKey && event.shiftKey && event.ctrlKey && !event.metaKey ? "ctrl-alt-shift" :
event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey ? "meta" :
event.metaKey && event.ctrlKey && !event.shiftKey && !event.altKey ? "meta-ctrl" :
event.metaKey && event.ctrlKey && event.shiftKey && !event.altKey ? "meta-ctrl-shift" :
event.metaKey && event.ctrlKey & event.shiftKey && event.altKey ? "meta-ctrl-alt-shift" : "normal";
};
KeyboardManager.prototype.getShortcutTiddlerList = function() {
return $tw.wiki.getTiddlersWithTag("$:/tags/KeyboardShortcut");
};

View File

@@ -27,7 +27,7 @@ exports.params = [
Run the macro
*/
exports.run = function(filter,spaces) {
return this.wiki.getTiddlersAsJson(filter,spaces);
return this.wiki.getTiddlersAsJson(filter,$tw.utils.parseInt(spaces));
};
})();

View File

@@ -60,7 +60,7 @@ var listTypes = {
"#": {listTag: "ol", itemTag: "li"},
";": {listTag: "dl", itemTag: "dt"},
":": {listTag: "dl", itemTag: "dd"},
">": {listTag: "blockquote", itemTag: "p"}
">": {listTag: "blockquote", itemTag: "div"}
};
/*

View File

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

View File

@@ -153,7 +153,7 @@ SaverHandler.prototype.saveWiki = function(options) {
var self = this,
method = options.method || "save";
// Ignore autosave if disabled
if(method === "autosave" && this.wiki.getTiddlerText(this.titleAutoSave,"yes") !== "yes") {
if(method === "autosave" && ($tw.config.disableAutoSave || this.wiki.getTiddlerText(this.titleAutoSave,"yes") !== "yes")) {
return false;
}
var variables = options.variables || {},
@@ -197,8 +197,12 @@ SaverHandler.prototype.isDirty = function() {
Update the document body with the class "tc-dirty" if the wiki has unsaved/unsynced changes
*/
SaverHandler.prototype.updateDirtyStatus = function() {
var self = this;
if($tw.browser) {
$tw.utils.toggleClass(document.body,"tc-dirty",this.isDirty());
$tw.utils.each($tw.windows,function(win) {
$tw.utils.toggleClass(win.document.body,"tc-dirty",self.isDirty());
});
}
};

View File

@@ -0,0 +1,60 @@
/*\
title: $:/core/modules/savers/custom.js
type: application/javascript
module-type: saver
Looks for `window.$tw.customSaver` first on the current window, then
on the parent window (of an iframe). If present, the saver must define
save: function(text,method,callback) { ... }
and the saver may define
priority: number
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var findSaver = function(window) {
try {
return window && window.$tw && window.$tw.customSaver;
} catch (err) {
// Catching the exception is the most reliable way to detect cross-origin iframe errors.
// For example, instead of saying that `window.parent.$tw` is undefined, Firefox will throw
// Uncaught DOMException: Permission denied to access property "$tw" on cross-origin object
console.log({ msg: "custom saver is disabled", reason: err });
return null;
}
}
var saver = findSaver(window) || findSaver(window.parent) || {};
var CustomSaver = function(wiki) {
};
CustomSaver.prototype.save = function(text,method,callback) {
return saver.save(text, method, callback);
};
/*
Information about this saver
*/
CustomSaver.prototype.info = {
name: "custom",
priority: saver.priority || 4000,
capabilities: ["save","autosave"]
};
/*
Static method that returns true if this saver is capable of working
*/
exports.canSave = function(wiki) {
return !!(saver.save);
};
/*
Create an instance of this saver
*/
exports.create = function(wiki) {
return new CustomSaver(wiki);
};
})();

View File

@@ -31,10 +31,10 @@ GiteaSaver.prototype.save = function(text,method,callback) {
headers = {
"Accept": "application/json",
"Content-Type": "application/json;charset=UTF-8",
"Authorization": "Basic " + window.btoa(username + ":" + password)
"Authorization": "token " + password
};
// Bail if we don't have everything we need
if(!username || !password || !repo || !path || !filename) {
if(!username || !password || !repo || !filename) {
return false;
}
// Make sure the path start and ends with a slash

View File

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

View File

@@ -34,7 +34,7 @@ GitLabSaver.prototype.save = function(text,method,callback) {
"Private-Token": password
};
// Bail if we don't have everything we need
if(!username || !password || !repo || !path || !filename) {
if(!username || !password || !repo || !filename) {
return false;
}
// Make sure the path start and ends with a slash

View File

@@ -0,0 +1,64 @@
/*\
title: $:/core/modules/savers/hyperdrive.js
type: application/javascript
module-type: saver
Saves files using the Hyperdrive Protocol (https://hypercore-protocol.org/#hyperdrive) Beaker browser beta-1.0 and later (https://beakerbrowser.com)
Compatible with beaker >= V1.0.0
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Set up the saver
*/
var HyperdriveSaver = function(wiki) {
this.wiki = wiki;
};
HyperdriveSaver.prototype.save = function(text,method,callback) {
var dat = beaker.hyperdrive.drive("" + window.location),
pathname = ("" + window.location.pathname).split("#")[0];
dat.stat(pathname).then(function(value) {
if(value.isDirectory()) {
pathname = pathname + "/index.html";
}
dat.writeFile(pathname,text,"utf8").then(function(value) {
callback(null);
},function(reason) {
callback("Hyperdrive Saver Write Error: " + reason);
});
},function(reason) {
callback("Hyperdrive Saver Stat Error: " + reason);
});
return true;
};
/*
Information about this saver
*/
HyperdriveSaver.prototype.info = {
name: "beaker-1.x",
priority: 3000,
capabilities: ["save", "autosave"]
};
/*
Static method that returns true if this saver is capable of working
*/
exports.canSave = function(wiki) {
return !!window.beaker && !!beaker.hyperdrive && location.protocol==="hyper:";
};
/*
Create an instance of this saver
*/
exports.create = function(wiki) {
return new HyperdriveSaver(wiki);
};
})();

View File

@@ -31,7 +31,7 @@ BasicAuthenticator.prototype.init = function() {
// Read the credentials data
this.credentialsFilepath = this.server.get("credentials");
if(this.credentialsFilepath) {
var resolveCredentialsFilepath = path.resolve($tw.boot.wikiPath,this.credentialsFilepath);
var resolveCredentialsFilepath = path.resolve(this.server.boot.wikiPath,this.credentialsFilepath);
if(fs.existsSync(resolveCredentialsFilepath) && !fs.statSync(resolveCredentialsFilepath).isDirectory()) {
var credentialsText = fs.readFileSync(resolveCredentialsFilepath,"utf8"),
credentialsData = $tw.utils.parseCsvStringWithHeader(credentialsText);

View File

@@ -14,7 +14,7 @@ Authenticator for trusted header authentication
function HeaderAuthenticator(server) {
this.server = server;
this.header = server.get("authenticated-user-header");
this.header = server.get("authenticated-user-header") ? server.get("authenticated-user-header").toLowerCase() : undefined;
}
/*

View File

@@ -21,7 +21,7 @@ exports.handler = function(request,response,state) {
fs = require("fs"),
util = require("util"),
suppliedFilename = decodeURIComponent(state.params[0]),
filename = path.resolve($tw.boot.wikiPath,"files",suppliedFilename),
filename = path.resolve(state.boot.wikiPath,"files",suppliedFilename),
extension = path.extname(filename);
fs.readFile(filename,function(err,content) {
var status,content,type = "text/plain";

View File

@@ -3,7 +3,7 @@ title: $:/core/modules/server/routes/get-tiddlers-json.js
type: application/javascript
module-type: route
GET /recipes/default/tiddlers/tiddlers.json?filter=<filter>
GET /recipes/default/tiddlers.json?filter=<filter>
\*/
(function() {
@@ -20,14 +20,17 @@ exports.path = /^\/recipes\/default\/tiddlers.json$/;
exports.handler = function(request,response,state) {
var filter = state.queryParameters.filter || DEFAULT_FILTER;
if($tw.wiki.getTiddlerText("$:/config/Server/AllowAllExternalFilters") !== "yes") {
if($tw.wiki.getTiddlerText("$:/config/Server/ExternalFilters/" + filter) !== "yes") {
console.log("Blocked attempt to GET /recipes/default/tiddlers/tiddlers.json with filter: " + filter);
if(state.wiki.getTiddlerText("$:/config/Server/AllowAllExternalFilters") !== "yes") {
if(state.wiki.getTiddlerText("$:/config/Server/ExternalFilters/" + filter) !== "yes") {
console.log("Blocked attempt to GET /recipes/default/tiddlers.json with filter: " + filter);
response.writeHead(403);
response.end();
return;
}
}
if(state.wiki.getTiddlerText("$:/config/SyncSystemTiddlersFromServer") === "no") {
filter += "+[!is[system]]";
}
var excludeFields = (state.queryParameters.exclude || "text").split(","),
titles = state.wiki.filterTiddlers(filter);
response.writeHead(200, {"Content-Type": "application/json"});

View File

@@ -31,6 +31,7 @@ function Server(options) {
this.routes = options.routes || [];
this.authenticators = options.authenticators || [];
this.wiki = options.wiki;
this.boot = options.boot || $tw.boot;
this.servername = $tw.utils.transliterateToSafeASCII(this.wiki.getTiddlerText("$:/SiteTitle") || "TiddlyWiki5");
// Initialise the variables
this.variables = $tw.utils.extend({},this.defaultVariables);
@@ -69,8 +70,8 @@ function Server(options) {
tlsCertFilepath = this.get("tls-cert");
if(tlsCertFilepath && tlsKeyFilepath) {
this.listenOptions = {
key: fs.readFileSync(path.resolve($tw.boot.wikiPath,tlsKeyFilepath),"utf8"),
cert: fs.readFileSync(path.resolve($tw.boot.wikiPath,tlsCertFilepath),"utf8")
key: fs.readFileSync(path.resolve(this.boot.wikiPath,tlsKeyFilepath),"utf8"),
cert: fs.readFileSync(path.resolve(this.boot.wikiPath,tlsCertFilepath),"utf8")
};
this.protocol = "https";
}
@@ -112,15 +113,14 @@ Server.prototype.addAuthenticator = function(AuthenticatorClass) {
};
Server.prototype.findMatchingRoute = function(request,state) {
var pathprefix = this.get("path-prefix") || "";
for(var t=0; t<this.routes.length; t++) {
var potentialRoute = this.routes[t],
pathRegExp = potentialRoute.path,
pathname = state.urlInfo.pathname,
match;
if(pathprefix) {
if(pathname.substr(0,pathprefix.length) === pathprefix) {
pathname = pathname.substr(pathprefix.length) || "/";
if(state.pathPrefix) {
if(pathname.substr(0,state.pathPrefix.length) === state.pathPrefix) {
pathname = pathname.substr(state.pathPrefix.length) || "/";
match = potentialRoute.path.exec(pathname);
} else {
match = false;
@@ -156,14 +156,17 @@ Server.prototype.isAuthorized = function(authorizationType,username) {
return principals.indexOf("(anon)") !== -1 || (username && (principals.indexOf("(authenticated)") !== -1 || principals.indexOf(username) !== -1));
}
Server.prototype.requestHandler = function(request,response) {
Server.prototype.requestHandler = function(request,response,options) {
options = options || {};
// Compose the state object
var self = this;
var state = {};
state.wiki = self.wiki;
state.wiki = options.wiki || self.wiki;
state.boot = options.boot || self.boot;
state.server = self;
state.urlInfo = url.parse(request.url);
state.queryParameters = querystring.parse(state.urlInfo.query);
state.pathPrefix = options.pathPrefix || this.get("path-prefix") || "";
// Get the principals authorized to access this resource
var authorizationType = this.methodMappings[request.method] || "readers";
// Check for the CSRF header if this is a write
@@ -248,7 +251,7 @@ Server.prototype.listen = function(port,host,prefix) {
port = process.env[port] || 8080;
}
// Warn if required plugins are missing
if(!$tw.wiki.getTiddler("$:/plugins/tiddlywiki/tiddlyweb") || !$tw.wiki.getTiddler("$:/plugins/tiddlywiki/filesystem")) {
if(!this.wiki.getTiddler("$:/plugins/tiddlywiki/tiddlyweb") || !this.wiki.getTiddler("$:/plugins/tiddlywiki/filesystem")) {
$tw.utils.warning("Warning: Plugins required for client-server operation (\"tiddlywiki/filesystem\" and \"tiddlywiki/tiddlyweb\") are missing from tiddlywiki.info file");
}
// Create the server

View File

@@ -36,7 +36,7 @@ function setFavicon() {
var tiddler = $tw.wiki.getTiddler(FAVICON_TITLE);
if(tiddler) {
var faviconLink = document.getElementById("faviconLink");
faviconLink.setAttribute("href","data:" + tiddler.fields.type + ";base64," + tiddler.fields.text);
faviconLink.setAttribute("href",$tw.utils.makeDataUri(tiddler.fields.text,tiddler.fields.type,tiddler.fields._canonical_uri));
}
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -64,17 +64,12 @@ exports.startup = function() {
document: $tw.browser ? document : $tw.fakeDocument
});
// Execute any startup actions
var executeStartupTiddlers = function(tag) {
$tw.utils.each($tw.wiki.filterTiddlers("[all[shadows+tiddlers]tag[" + tag + "]!has[draft.of]]"),function(title) {
$tw.rootWidget.invokeActionString($tw.wiki.getTiddlerText(title),$tw.rootWidget);
});
};
executeStartupTiddlers("$:/tags/StartupAction");
$tw.rootWidget.invokeActionsByTag("$:/tags/StartupAction");
if($tw.browser) {
executeStartupTiddlers("$:/tags/StartupAction/Browser");
$tw.rootWidget.invokeActionsByTag("$:/tags/StartupAction/Browser");
}
if($tw.node) {
executeStartupTiddlers("$:/tags/StartupAction/Node");
$tw.rootWidget.invokeActionsByTag("$:/tags/StartupAction/Node");
}
// Kick off the language manager and switcher
$tw.language = new $tw.Language();

View File

@@ -150,6 +150,11 @@ function openStartupTiddlers(options) {
// Save the story list
$tw.wiki.addTiddler({title: DEFAULT_STORY_TITLE, text: "", list: storyList},$tw.wiki.getModificationFields());
// Update history
var story = new $tw.Story({
wiki: $tw.wiki,
storyTitle: DEFAULT_STORY_TITLE,
historyTitle: DEFAULT_HISTORY_TITLE
});
if(!options.disableHistory) {
// If a target tiddler was specified add it to the history stack
if(target && target !== "") {
@@ -157,9 +162,9 @@ function openStartupTiddlers(options) {
if(target.indexOf("[[") === 0 && target.substr(-2) === "]]") {
target = target.substr(2,target.length - 4);
}
$tw.wiki.addToHistory(target);
story.addToHistory(target);
} else if(storyList.length > 0) {
$tw.wiki.addToHistory(storyList[0]);
story.addToHistory(storyList[0]);
}
}
}

View File

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

View File

@@ -37,48 +37,44 @@ Story.prototype.getStoryList = function() {
Story.prototype.addToStory = function(navigateTo,navigateFromTitle,options) {
options = options || {};
var storyList = this.getStoryList();
if(options.singleTiddlerMode) {
storyList = [navigateTo];
} else {
// See if the tiddler is already there
var slot = storyList.indexOf(navigateTo);
// Quit if it already exists in the story river
if(slot >= 0) {
return;
}
// First we try to find the position of the story element we navigated from
var fromIndex = storyList.indexOf(navigateFromTitle);
if(fromIndex >= 0) {
// The tiddler is added from inside the river
// Determine where to insert the tiddler; Fallback is "below"
switch(options.openLinkFromInsideRiver) {
case "top":
slot = 0;
break;
case "bottom":
slot = storyList.length;
break;
case "above":
slot = fromIndex;
break;
case "below": // Intentional fall-through
default:
slot = fromIndex + 1;
break;
}
} else {
// The tiddler is opened from outside the river. Determine where to insert the tiddler; default is "top"
if(options.openLinkFromOutsideRiver === "bottom") {
// Insert at bottom
slot = storyList.length;
} else {
// Insert at top
slot = 0;
}
}
// Add the tiddler
storyList.splice(slot,0,navigateTo);
// See if the tiddler is already there
var slot = storyList.indexOf(navigateTo);
// Quit if it already exists in the story river
if(slot >= 0) {
return;
}
// First we try to find the position of the story element we navigated from
var fromIndex = storyList.indexOf(navigateFromTitle);
if(fromIndex >= 0) {
// The tiddler is added from inside the river
// Determine where to insert the tiddler; Fallback is "below"
switch(options.openLinkFromInsideRiver) {
case "top":
slot = 0;
break;
case "bottom":
slot = storyList.length;
break;
case "above":
slot = fromIndex;
break;
case "below": // Intentional fall-through
default:
slot = fromIndex + 1;
break;
}
} else {
// The tiddler is opened from outside the river. Determine where to insert the tiddler; default is "top"
if(options.openLinkFromOutsideRiver === "bottom") {
// Insert at bottom
slot = storyList.length;
} else {
// Insert at top
slot = 0;
}
}
// Add the tiddler
storyList.splice(slot,0,navigateTo);
// Save the story
this.saveStoryList(storyList);
};
@@ -97,20 +93,11 @@ Story.prototype.saveStoryList = function(storyList) {
Story.prototype.addToHistory = function(navigateTo,navigateFromClientRect) {
var titles = $tw.utils.isArray(navigateTo) ? navigateTo : [navigateTo];
// Add a new record to the top of the history stack
var historyList = this.wiki.getTiddlerData(this.historyTitle,[]),
historyTitles = this.wiki.getTiddlerList(this.historyTitle);
var historyList = this.wiki.getTiddlerData(this.historyTitle,[]);
$tw.utils.each(titles,function(title) {
historyList.push({title: title, fromPageRect: navigateFromClientRect});
var p;
do {
p = historyTitles.indexOf(title);
if(p !== -1) {
historyTitles.splice(p,1);
}
} while(p !== -1);
historyTitles.unshift(title);
});
this.wiki.setTiddlerData(this.historyTitle,historyList,{"current-tiddler": titles[titles.length-1], list: historyTitles});
this.wiki.setTiddlerData(this.historyTitle,historyList,{"current-tiddler": titles[titles.length-1]});
};
Story.prototype.storyCloseTiddler = function(targetTitle) {

View File

@@ -1,23 +0,0 @@
/*\
title: $:/core/modules/storyviews/solo.js
type: application/javascript
module-type: storyview
Flip between individual tiddlers
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var SoloListView = function(listWidget) {
};
// Engage single tiddler mode
SoloListView.singleTiddlerMode = true;
exports.solo = SoloListView;
})();

View File

@@ -39,9 +39,6 @@ var ZoominListView = function(listWidget) {
});
};
// Engage single tiddler mode
ZoominListView.singleTiddlerMode = true;
ZoominListView.prototype.navigateTo = function(historyInfo) {
var duration = $tw.utils.getAnimationDuration(),
listElementIndex = this.listWidget.findListItem(0,historyInfo.title);

View File

@@ -113,8 +113,16 @@ function Syncer(options) {
return confirmationMessage;
});
// Listen out for login/logout/refresh events in the browser
$tw.rootWidget.addEventListener("tm-login",function() {
self.handleLoginEvent();
$tw.rootWidget.addEventListener("tm-login",function(event) {
var username = event && event.paramObject && event.paramObject.username,
password = event && event.paramObject && event.paramObject.password;
if(username && password) {
// Login with username and password
self.login(username,password,function() {});
} else {
// No username and password, so we display a prompt
self.handleLoginEvent();
}
});
$tw.rootWidget.addEventListener("tm-logout",function() {
self.handleLogoutEvent();
@@ -127,7 +135,7 @@ function Syncer(options) {
});
}
// Listen out for lazyLoad events
if(!this.disableUI && $tw.wiki.getTiddlerText(this.titleSyncDisableLazyLoading) !== "yes") {
if(!this.disableUI && this.wiki.getTiddlerText(this.titleSyncDisableLazyLoading) !== "yes") {
this.wiki.addEventListener("lazyLoad",function(title) {
self.handleLazyLoadEvent(title);
});
@@ -180,12 +188,14 @@ Syncer.prototype.readTiddlerInfo = function() {
var self = this,
tiddlers = this.getSyncedTiddlers();
$tw.utils.each(tiddlers,function(title) {
var tiddler = self.wiki.tiddlerExists(title) && self.wiki.getTiddler(title);
self.tiddlerInfo[title] = {
revision: self.getTiddlerRevision(title),
adaptorInfo: self.syncadaptor && self.syncadaptor.getTiddlerInfo(tiddler),
changeCount: self.wiki.getChangeCount(title)
};
var tiddler = self.wiki.getTiddler(title);
if(tiddler) {
self.tiddlerInfo[title] = {
revision: self.getTiddlerRevision(title),
adaptorInfo: self.syncadaptor && self.syncadaptor.getTiddlerInfo(tiddler),
changeCount: self.wiki.getChangeCount(title)
};
}
});
};
@@ -202,7 +212,7 @@ Syncer.prototype.isDirty = function() {
if(this.wiki.tiddlerExists(title)) {
if(tiddlerInfo) {
// If the tiddler is known on the server and has been modified locally then it needs to be saved to the server
if($tw.wiki.getChangeCount(title) > tiddlerInfo.changeCount) {
if(this.wiki.getChangeCount(title) > tiddlerInfo.changeCount) {
return true;
}
} else {
@@ -295,7 +305,8 @@ Syncer.prototype.syncFromServer = function() {
self.pollTimerId = null;
self.syncFromServer.call(self);
},self.pollTimerInterval);
};
},
syncSystemFromServer = (self.wiki.getTiddlerText("$:/config/SyncSystemTiddlersFromServer") === "yes" ? true : false);
if(this.syncadaptor && this.syncadaptor.getUpdatedTiddlers) {
this.logger.log("Retrieving updated tiddler list");
cancelNextSync();
@@ -310,9 +321,11 @@ Syncer.prototype.syncFromServer = function() {
self.titlesToBeLoaded[title] = true;
});
$tw.utils.each(updates.deletions,function(title) {
delete self.tiddlerInfo[title];
self.logger.log("Deleting tiddler missing from server:",title);
self.wiki.deleteTiddler(title);
if(syncSystemFromServer || !self.wiki.isSystemTiddler(title)) {
delete self.tiddlerInfo[title];
self.logger.log("Deleting tiddler missing from server:",title);
self.wiki.deleteTiddler(title);
}
});
if(updates.modifications.length > 0 || updates.deletions.length > 0) {
self.processTaskQueue();
@@ -355,9 +368,11 @@ Syncer.prototype.syncFromServer = function() {
}
// Delete any tiddlers that were previously reported but missing this time
$tw.utils.each(previousTitles,function(title) {
delete self.tiddlerInfo[title];
self.logger.log("Deleting tiddler missing from server:",title);
self.wiki.deleteTiddler(title);
if(syncSystemFromServer || !self.wiki.isSystemTiddler(title)) {
delete self.tiddlerInfo[title];
self.logger.log("Deleting tiddler missing from server:",title);
self.wiki.deleteTiddler(title);
}
});
self.processTaskQueue();
});
@@ -398,15 +413,27 @@ Syncer.prototype.handleLoginEvent = function() {
var self = this;
this.getStatus(function(err,isLoggedIn,username) {
if(!err && !isLoggedIn) {
$tw.passwordPrompt.createPrompt({
serviceName: $tw.language.getString("LoginToTiddlySpace"),
callback: function(data) {
self.login(data.username,data.password,function(err,isLoggedIn) {
self.syncFromServer();
});
return true; // Get rid of the password prompt
}
if(self.syncadaptor && self.syncadaptor.displayLoginPrompt) {
self.syncadaptor.displayLoginPrompt(self);
} else {
self.displayLoginPrompt();
}
}
});
};
/*
Dispay a password prompt
*/
Syncer.prototype.displayLoginPrompt = function() {
var self = this;
var promptInfo = $tw.passwordPrompt.createPrompt({
serviceName: $tw.language.getString("LoginToTiddlySpace"),
callback: function(data) {
self.login(data.username,data.password,function(err,isLoggedIn) {
self.syncFromServer();
});
return true; // Get rid of the password prompt
}
});
};
@@ -524,7 +551,7 @@ Syncer.prototype.chooseNextTask = function() {
tiddlerInfo = this.tiddlerInfo[title];
if(tiddler) {
// If the tiddler is not known on the server, or has been modified locally no more recently than the threshold then it needs to be saved to the server
var hasChanged = !tiddlerInfo || $tw.wiki.getChangeCount(title) > tiddlerInfo.changeCount,
var hasChanged = !tiddlerInfo || this.wiki.getChangeCount(title) > tiddlerInfo.changeCount,
isReadyToSave = !tiddlerInfo || !tiddlerInfo.timestampLastSaved || tiddlerInfo.timestampLastSaved < thresholdLastSaved;
if(hasChanged) {
if(isReadyToSave) {
@@ -581,6 +608,8 @@ SaveTiddlerTask.prototype.run = function(callback) {
};
// Invoke the callback
callback(null);
},{
tiddlerInfo: self.syncer.tiddlerInfo[self.title]
});
} else {
this.syncer.logger.log(" Not Dispatching 'save' task:",this.title,"tiddler does not exist");
@@ -604,6 +633,10 @@ DeleteTiddlerTask.prototype.run = function(callback) {
}
// Remove the info stored about this tiddler
delete self.syncer.tiddlerInfo[self.title];
if($tw.boot.files){
// Remove the tiddler from $tw.boot.files
delete $tw.boot.files[self.title];
}
// Invoke the callback
callback(null);
},{

View File

@@ -41,7 +41,7 @@ exports.upgrade = function(wiki,titles,tiddlers) {
// Check if we're dealing with a plugin
if(incomingTiddler && incomingTiddler["plugin-type"]) {
// Check whether the plugin contains JS modules
var requiresReload = $tw.wiki.doesPluginInfoRequireReload(JSON.parse(incomingTiddler.text)) ? ($tw.wiki.getTiddlerText("$:/language/ControlPanel/Plugins/PluginWillRequireReload") + " ") : "";
var requiresReload = wiki.doesPluginInfoRequireReload(JSON.parse(incomingTiddler.text)) ? (wiki.getTiddlerText("$:/language/ControlPanel/Plugins/PluginWillRequireReload") + " ") : "";
messages[title] = requiresReload;
if(incomingTiddler.version) {
// Upgrade the incoming plugin if it is in the upgrade library
@@ -57,7 +57,7 @@ exports.upgrade = function(wiki,titles,tiddlers) {
// Reject the incoming plugin by blanking all its fields
if($tw.utils.checkVersions(existingTiddler.fields.version,incomingTiddler.version)) {
tiddlers[title] = Object.create(null);
messages[title] = requiresReload + $tw.language.getString("Import/Upgrader/Plugins/Suppressed/Version",{variables: {incoming: incomingTiddler.version, existing: existingTiddler.fields.version}});
messages[title] = $tw.language.getString("Import/Upgrader/Plugins/Suppressed/Version",{variables: {incoming: incomingTiddler.version, existing: existingTiddler.fields.version}});
return;
}
}

View File

@@ -20,15 +20,27 @@
for (i; i < string.length; i++) {
charCode = string.charCodeAt(i);
if (charCode < 128)
if (charCode < 128) {
output += String.fromCharCode(charCode);
else if ((charCode > 127) && (charCode < 2048))
output += String.fromCharCode((charCode >> 6) | 192),
} else if ((charCode > 127) && (charCode < 2048)) {
output += String.fromCharCode((charCode >> 6) | 192);
output += String.fromCharCode((charCode & 63) | 128);
else
output += String.fromCharCode((charCode >> 12) | 224),
output += String.fromCharCode(((charCode >> 6) & 63) | 128),
} else if ((charCode > 55295) && (charCode < 57344) && string.length > i+1) {
// Surrogate pair
var hiSurrogate = charCode;
var loSurrogate = string.charCodeAt(i+1);
i++; // Skip the low surrogate on the next loop pass
var codePoint = (((hiSurrogate - 55296) << 10) | (loSurrogate - 56320)) + 65536;
output += String.fromCharCode((codePoint >> 18) | 240);
output += String.fromCharCode(((codePoint >> 12) & 63) | 128);
output += String.fromCharCode(((codePoint >> 6) & 63) | 128);
output += String.fromCharCode((codePoint & 63) | 128);
} else {
// Not a surrogate pair, or a dangling surrogate without its partner that we'll just encode as-is
output += String.fromCharCode((charCode >> 12) | 224);
output += String.fromCharCode(((charCode >> 6) & 63) | 128);
output += String.fromCharCode((charCode & 63) | 128);
}
}
return output;
@@ -41,15 +53,21 @@
while (i < string.length) {
charCode = string.charCodeAt(i);
if (charCode < 128)
if (charCode < 128) {
output += String.fromCharCode(charCode),
i++;
else if ((charCode > 191) && (charCode < 224))
output += String.fromCharCode(((charCode & 31) << 6) | (string.charCodeAt(i + 1) & 63)),
} else if ((charCode > 191) && (charCode < 224)) {
output += String.fromCharCode(((charCode & 31) << 6) | (string.charCodeAt(i + 1) & 63));
i += 2;
else
output += String.fromCharCode(((charCode & 15) << 12) | ((string.charCodeAt(i + 1) & 63) << 6) | (string.charCodeAt(i + 2) & 63)),
} else if ((charCode > 223) && (charCode < 240)) {
output += String.fromCharCode(((charCode & 15) << 12) | ((string.charCodeAt(i + 1) & 63) << 6) | (string.charCodeAt(i + 2) & 63));
i += 3;
} else {
var codePoint = ((charCode & 7) << 18) | ((string.charCodeAt(i + 1) & 63) << 12) | ((string.charCodeAt(i + 2) & 63) << 6) | (string.charCodeAt(i + 3) & 63);
// output += String.fromCodePoint(codePoint); // Can't do this because Internet Explorer doesn't have String.fromCodePoint
output += String.fromCharCode(((codePoint - 65536) >> 10) + 55296) + String.fromCharCode(((codePoint - 65536) & 1023) + 56320); // So we do this instead
i += 4;
}
}
return output;

View File

@@ -6,4 +6,4 @@
//
// copyright: MIT
// author: Nijiko Yonskai, @nijikokun, nijikokun@gmail.com
!function(r,e,o,t){void 0!==o.module&&o.module.exports?o.module.exports=e.apply(o):void 0!==o.define&&"function"===o.define&&o.define.amd?define("utf8",[],e):o.utf8=e.apply(o)}(0,function(){return{encode:function(r){if("string"!=typeof r)return r;r=r.replace(/\r\n/g,"\n");for(var e,o="",t=0;t<r.length;t++)(e=r.charCodeAt(t))<128?o+=String.fromCharCode(e):e>127&&e<2048?(o+=String.fromCharCode(e>>6|192),o+=String.fromCharCode(63&e|128)):(o+=String.fromCharCode(e>>12|224),o+=String.fromCharCode(e>>6&63|128),o+=String.fromCharCode(63&e|128));return o},decode:function(r){if("string"!=typeof r)return r;for(var e="",o=0,t=0;o<r.length;)(t=r.charCodeAt(o))<128?(e+=String.fromCharCode(t),o++):t>191&&t<224?(e+=String.fromCharCode((31&t)<<6|63&r.charCodeAt(o+1)),o+=2):(e+=String.fromCharCode((15&t)<<12|(63&r.charCodeAt(o+1))<<6|63&r.charCodeAt(o+2)),o+=3);return e}}},this),function(r,e,o,t){if(void 0!==o.module&&o.module.exports){if(t&&o.require)for(var n=0;n<t.length;n++)o[t[n]]=o.require(t[n]);o.module.exports=e.apply(o)}else void 0!==o.define&&"function"===o.define&&o.define.amd?define("base64",t||[],e):o.base64=e.apply(o)}(0,function(r){var e=r||this.utf8,o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";return{encode:function(r){if(void 0===e)throw{error:"MissingMethod",message:"UTF8 Module is missing."};if("string"!=typeof r)return r;r=e.encode(r);for(var t,n,i,d,f,a,h,c="",u=0;u<r.length;)d=(t=r.charCodeAt(u++))>>2,f=(3&t)<<4|(n=r.charCodeAt(u++))>>4,a=(15&n)<<2|(i=r.charCodeAt(u++))>>6,h=63&i,isNaN(n)?a=h=64:isNaN(i)&&(h=64),c+=o.charAt(d)+o.charAt(f)+o.charAt(a)+o.charAt(h);return c},decode:function(r){if(void 0===e)throw{error:"MissingMethod",message:"UTF8 Module is missing."};if("string"!=typeof r)return r;r=r.replace(/[^A-Za-z0-9\+\/\=]/g,"");for(var t,n,i,d,f,a,h="",c=0;c<r.length;)t=o.indexOf(r.charAt(c++))<<2|(d=o.indexOf(r.charAt(c++)))>>4,n=(15&d)<<4|(f=o.indexOf(r.charAt(c++)))>>2,i=(3&f)<<6|(a=o.indexOf(r.charAt(c++))),h+=String.fromCharCode(t),64!=f&&(h+=String.fromCharCode(n)),64!=a&&(h+=String.fromCharCode(i));return e.decode(h)}}},this,["utf8"]);
!function(r,e,o,t){void 0!==o.module&&o.module.exports?o.module.exports=e.apply(o):void 0!==o.define&&"function"===o.define&&o.define.amd?define("utf8",[],e):o.utf8=e.apply(o)}(0,function(){return{encode:function(r){if("string"!=typeof r)return r;r=r.replace(/\r\n/g,"\n");for(var e,o="",t=0;t<r.length;t++)if((e=r.charCodeAt(t))<128)o+=String.fromCharCode(e);else if(e>127&&e<2048)o+=String.fromCharCode(e>>6|192),o+=String.fromCharCode(63&e|128);else if(e>55295&&e<57344&&r.length>t+1){var i=e,n=r.charCodeAt(t+1);t++;var d=65536+(i-55296<<10|n-56320);o+=String.fromCharCode(d>>18|240),o+=String.fromCharCode(d>>12&63|128),o+=String.fromCharCode(d>>6&63|128),o+=String.fromCharCode(63&d|128)}else o+=String.fromCharCode(e>>12|224),o+=String.fromCharCode(e>>6&63|128),o+=String.fromCharCode(63&e|128);return o},decode:function(r){if("string"!=typeof r)return r;for(var e="",o=0,t=0;o<r.length;)if((t=r.charCodeAt(o))<128)e+=String.fromCharCode(t),o++;else if(t>191&&t<224)e+=String.fromCharCode((31&t)<<6|63&r.charCodeAt(o+1)),o+=2;else if(t>223&&t<240)e+=String.fromCharCode((15&t)<<12|(63&r.charCodeAt(o+1))<<6|63&r.charCodeAt(o+2)),o+=3;else{var i=(7&t)<<18|(63&r.charCodeAt(o+1))<<12|(63&r.charCodeAt(o+2))<<6|63&r.charCodeAt(o+3);e+=String.fromCharCode(55296+(i-65536>>10))+String.fromCharCode(56320+(i-65536&1023)),o+=4}return e}}},this),function(r,e,o,t){if(void 0!==o.module&&o.module.exports){if(t&&o.require)for(var i=0;i<t.length;i++)o[t[i]]=o.require(t[i]);o.module.exports=e.apply(o)}else void 0!==o.define&&"function"===o.define&&o.define.amd?define("base64",t||[],e):o.base64=e.apply(o)}(0,function(r){var e=r||this.utf8,o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";return{encode:function(r){if(void 0===e)throw{error:"MissingMethod",message:"UTF8 Module is missing."};if("string"!=typeof r)return r;r=e.encode(r);for(var t,i,n,d,f,a,h,C="",c=0;c<r.length;)d=(t=r.charCodeAt(c++))>>2,f=(3&t)<<4|(i=r.charCodeAt(c++))>>4,a=(15&i)<<2|(n=r.charCodeAt(c++))>>6,h=63&n,isNaN(i)?a=h=64:isNaN(n)&&(h=64),C+=o.charAt(d)+o.charAt(f)+o.charAt(a)+o.charAt(h);return C},decode:function(r){if(void 0===e)throw{error:"MissingMethod",message:"UTF8 Module is missing."};if("string"!=typeof r)return r;r=r.replace(/[^A-Za-z0-9\+\/\=]/g,"");for(var t,i,n,d,f,a,h="",C=0;C<r.length;)t=o.indexOf(r.charAt(C++))<<2|(d=o.indexOf(r.charAt(C++)))>>4,i=(15&d)<<4|(f=o.indexOf(r.charAt(C++)))>>2,n=(3&f)<<6|(a=o.indexOf(r.charAt(C++))),h+=String.fromCharCode(t),64!=f&&(h+=String.fromCharCode(i)),64!=a&&(h+=String.fromCharCode(n));return e.decode(h)}}},this,["utf8"]);

View File

@@ -29,23 +29,23 @@ exports.removeChildren = function(node) {
};
exports.hasClass = function(el,className) {
return el && el.className && el.className.toString().split(" ").indexOf(className) !== -1;
return el && el.hasAttribute && el.hasAttribute("class") && el.getAttribute("class").split(" ").indexOf(className) !== -1;
};
exports.addClass = function(el,className) {
var c = el.className.split(" ");
var c = (el.getAttribute("class") || "").split(" ");
if(c.indexOf(className) === -1) {
c.push(className);
el.className = c.join(" ");
el.setAttribute("class",c.join(" "));
}
};
exports.removeClass = function(el,className) {
var c = el.className.split(" "),
var c = (el.getAttribute("class") || "").split(" "),
p = c.indexOf(className);
if(p !== -1) {
c.splice(p,1);
el.className = c.join(" ");
el.setAttribute("class",c.join(" "));
}
};

View File

@@ -24,6 +24,16 @@ exports.httpRequest = function(options) {
var type = options.type || "GET",
url = options.url,
headers = options.headers || {accept: "application/json"},
hasHeader = function(targetHeader) {
targetHeader = targetHeader.toLowerCase();
var result = false;
$tw.utils.each(headers,function(header,headerTitle,object) {
if(headerTitle.toLowerCase() === targetHeader) {
result = true;
}
});
return result;
},
returnProp = options.returnProp || "responseText",
request = new XMLHttpRequest(),
data = "",
@@ -63,10 +73,10 @@ exports.httpRequest = function(options) {
request.setRequestHeader(headerTitle,header);
});
}
if(data && !$tw.utils.hop(headers,"Content-type")) {
request.setRequestHeader("Content-type","application/x-www-form-urlencoded; charset=UTF-8");
if(data && !hasHeader("Content-Type")) {
request.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
}
if(!$tw.utils.hop(headers,"X-Requested-With")) {
if(!hasHeader("X-Requested-With")) {
request.setRequestHeader("X-Requested-With","TiddlyWiki");
}
try {

View File

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

View File

@@ -49,7 +49,12 @@ Handle an event
*/
PageScroller.prototype.handleEvent = function(event) {
if(event.type === "tm-scroll") {
return this.scrollIntoView(event.target);
if(event.paramObject && event.paramObject.selector) {
this.scrollSelectorIntoView(null,event.paramObject.selector);
} else {
this.scrollIntoView(event.target);
}
return false; // Event was handled
}
return true;
};
@@ -117,6 +122,14 @@ PageScroller.prototype.scrollIntoView = function(element,callback) {
drawFrame();
};
PageScroller.prototype.scrollSelectorIntoView = function(baseElement,selector,callback) {
baseElement = baseElement || document.body;
var element = baseElement.querySelector(selector);
if(element) {
this.scrollIntoView(element,callback);
}
};
exports.PageScroller = PageScroller;
})();

View File

@@ -21,14 +21,32 @@ var bumpSequenceNumber = function(object) {
}
};
var TW_Node = function (){
throw TypeError("Illegal constructor");
};
Object.defineProperty(TW_Node.prototype, 'ELEMENT_NODE', {
get: function() {
return 1;
}
});
Object.defineProperty(TW_Node.prototype, 'TEXT_NODE', {
get: function() {
return 3;
}
});
var TW_TextNode = function(text) {
bumpSequenceNumber(this);
this.textContent = text + "";
};
TW_TextNode.prototype = Object.create(TW_Node.prototype);
Object.defineProperty(TW_TextNode.prototype, "nodeType", {
get: function() {
return 3;
return this.TEXT_NODE;
}
});
@@ -49,6 +67,8 @@ var TW_Element = function(tag,namespace) {
this.namespaceURI = namespace || "http://www.w3.org/1999/xhtml";
};
TW_Element.prototype = Object.create(TW_Node.prototype);
Object.defineProperty(TW_Element.prototype, "style", {
get: function() {
return this._style;
@@ -69,7 +89,7 @@ Object.defineProperty(TW_Element.prototype, "style", {
Object.defineProperty(TW_Element.prototype, "nodeType", {
get: function() {
return 1;
return this.ELEMENT_NODE;
}
});

View File

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

View File

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

View File

@@ -53,6 +53,19 @@ exports.warning = function(text) {
exports.log(text,"brown/orange");
};
/*
Log a table of name: value pairs
*/
exports.logTable = function(data) {
if(console.table) {
console.table(data);
} else {
$tw.utils.each(data,function(value,name) {
console.log(name + ": " + value);
});
}
}
/*
Return the integer represented by the str (string).
Return the dflt (default) parameter if str is not a base-10 number.
@@ -94,6 +107,36 @@ exports.trim = function(str) {
}
};
exports.trimPrefix = function(str,unwanted) {
if(typeof str === "string" && typeof unwanted === "string") {
if(unwanted === "") {
return str.replace(/^\s\s*/, '');
} else {
// Safely regexp-escape the unwanted text
unwanted = unwanted.replace(/[\\^$*+?.()|[\]{}]/g, '\\$&');
var regex = new RegExp('^(' + unwanted + ')+');
return str.replace(regex, '');
}
} else {
return str;
}
};
exports.trimSuffix = function(str,unwanted) {
if(typeof str === "string" && typeof unwanted === "string") {
if(unwanted === "") {
return str.replace(/\s\s*$/, '');
} else {
// Safely regexp-escape the unwanted text
unwanted = unwanted.replace(/[\\^$*+?.()|[\]{}]/g, '\\$&');
var regex = new RegExp('(' + unwanted + ')+$');
return str.replace(regex, '');
}
} else {
return str;
}
};
/*
Convert a string to sentence case (ie capitalise first letter)
*/
@@ -259,7 +302,7 @@ exports.formatDateString = function(date,template) {
return $tw.utils.pad($tw.utils.getHours12(date));
}],
[/^wYYYY/, function() {
return $tw.utils.getYearForWeekNo(date);
return $tw.utils.pad($tw.utils.getYearForWeekNo(date),4);
}],
[/^hh12/, function() {
return $tw.utils.getHours12(date);
@@ -268,7 +311,14 @@ exports.formatDateString = function(date,template) {
return date.getDate() + $tw.utils.getDaySuffix(date);
}],
[/^YYYY/, function() {
return date.getFullYear();
return $tw.utils.pad(date.getFullYear(),4);
}],
[/^aYYYY/, function() {
return $tw.utils.pad(Math.abs(date.getFullYear()),4);
}],
[/^\{era:([^,\|}]*)\|([^}\|]*)\|([^}]*)\}/, function(match) {
var year = date.getFullYear();
return year === 0 ? match[2] : (year < 0 ? match[1] : match[3]);
}],
[/^0hh/, function() {
return $tw.utils.pad(date.getHours());
@@ -357,7 +407,7 @@ exports.formatDateString = function(date,template) {
$tw.utils.each(matches, function(m) {
var match = m[0].exec(t);
if(match) {
matchString = m[1].call();
matchString = m[1].call(null,match);
t = t.substr(match[0].length);
return false;
}
@@ -514,7 +564,7 @@ exports.escape = function(ch) {
// Turns a string into a legal JavaScript string
// Copied from peg.js, thanks to David Majda
exports.stringify = function(s) {
exports.stringify = function(s, rawUnicode) {
/*
* ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a string
* literal except for the closing quote character, backslash, carriage return,
@@ -523,19 +573,21 @@ exports.stringify = function(s) {
*
* For portability, we also escape all non-ASCII characters.
*/
var regex = rawUnicode ? /[\x00-\x1f]/g : /[\x00-\x1f\x80-\uFFFF]/g;
return (s || "")
.replace(/\\/g, '\\\\') // backslash
.replace(/"/g, '\\"') // double quote character
.replace(/'/g, "\\'") // single quote character
.replace(/\r/g, '\\r') // carriage return
.replace(/\n/g, '\\n') // line feed
.replace(/[\x00-\x1f\x80-\uFFFF]/g, exports.escape); // non-ASCII characters
.replace(regex, exports.escape); // non-ASCII characters
};
// Turns a string into a legal JSON string
// Derived from peg.js, thanks to David Majda
exports.jsonStringify = function(s) {
exports.jsonStringify = function(s, rawUnicode) {
// See http://www.json.org/
var regex = rawUnicode ? /[\x00-\x1f]/g : /[\x00-\x1f\x80-\uFFFF]/g;
return (s || "")
.replace(/\\/g, '\\\\') // backslash
.replace(/"/g, '\\"') // double quote character
@@ -544,7 +596,7 @@ exports.jsonStringify = function(s) {
.replace(/\x08/g, '\\b') // backspace
.replace(/\x0c/g, '\\f') // formfeed
.replace(/\t/g, '\\t') // tab
.replace(/[\x00-\x1f\x80-\uFFFF]/g,function(s) {
.replace(regex,function(s) {
return '\\u' + $tw.utils.pad(s.charCodeAt(0).toString(16).toUpperCase(),4);
}); // non-ASCII characters
};
@@ -801,4 +853,57 @@ exports.getSystemInfo = function(str,ending,position) {
return results.join("\n");
};
exports.parseNumber = function(str) {
return parseFloat(str) || 0;
};
exports.parseInt = function(str) {
return parseInt(str,10) || 0;
};
exports.stringifyNumber = function(num) {
return num + "";
};
exports.makeCompareFunction = function(type,options) {
options = options || {};
var gt = options.invert ? -1 : +1,
lt = options.invert ? +1 : -1,
compare = function(a,b) {
if(a > b) {
return gt ;
} else if(a < b) {
return lt;
} else {
return 0;
}
},
types = {
"number": function(a,b) {
return compare($tw.utils.parseNumber(a),$tw.utils.parseNumber(b));
},
"integer": function(a,b) {
return compare($tw.utils.parseInt(a),$tw.utils.parseInt(b));
},
"string": function(a,b) {
return compare("" + a,"" +b);
},
"date": function(a,b) {
var dateA = $tw.utils.parseDate(a),
dateB = $tw.utils.parseDate(b);
if(!isFinite(dateA)) {
dateA = new Date(0);
}
if(!isFinite(dateB)) {
dateB = new Date(0);
}
return compare(dateA,dateB);
},
"version": function(a,b) {
return $tw.utils.compareVersions(a,b);
}
};
return (types[type] || types[options.defaultType] || types.number);
};
})();

View File

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

View File

@@ -9,7 +9,7 @@ Action widget to create a new tiddler with a unique name and specified fields.
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
/*global $tw:false, require:false, exports:false */
"use strict";
var Widget = require("$:/core/modules/widgets/widget.js").widget;
@@ -36,9 +36,15 @@ Compute the internal state of the widget
*/
CreateTiddlerWidget.prototype.execute = function() {
this.actionBaseTitle = this.getAttribute("$basetitle");
this.hasBase = !!this.actionBaseTitle;
this.actionSaveTitle = this.getAttribute("$savetitle");
this.actionSaveDraftTitle = this.getAttribute("$savedrafttitle");
this.actionTimestamp = this.getAttribute("$timestamp","yes") === "yes";
//Following params are new since 5.1.22
this.actionTemplate = this.getAttribute("$template");
this.useTemplate = !!this.actionTemplate;
this.actionOverwrite = this.getAttribute("$overwrite","no");
};
/*
@@ -57,7 +63,7 @@ CreateTiddlerWidget.prototype.refresh = function(changedTiddlers) {
Invoke the action associated with this widget
*/
CreateTiddlerWidget.prototype.invokeAction = function(triggeringWidget,event) {
var title = this.wiki.generateNewTitle(this.actionBaseTitle),
var title = this.wiki.getTiddlerText("$:/language/DefaultNewTiddlerTitle"), // Get the initial new-tiddler title
fields = {},
creationFields,
modificationFields;
@@ -70,7 +76,22 @@ CreateTiddlerWidget.prototype.invokeAction = function(triggeringWidget,event) {
creationFields = this.wiki.getCreationFields();
modificationFields = this.wiki.getModificationFields();
}
var tiddler = this.wiki.addTiddler(new $tw.Tiddler(creationFields,fields,modificationFields,{title: title}));
if(this.hasBase && this.actionOverwrite === "no") {
title = this.wiki.generateNewTitle(this.actionBaseTitle);
} else if (this.hasBase && this.actionOverwrite === "yes") {
title = this.actionBaseTitle
}
// NO $basetitle BUT $template parameter is available
// the title MUST be unique, otherwise the template would be overwritten
if (!this.hasBase && this.useTemplate) {
title = this.wiki.generateNewTitle(this.actionTemplate);
} else if (!this.hasBase && !this.useTemplate) {
// If NO $basetitle AND NO $template use initial title
// DON'T overwrite any stuff
title = this.wiki.generateNewTitle(title);
}
var templateTiddler = this.wiki.getTiddler(this.actionTemplate) || {};
var tiddler = this.wiki.addTiddler(new $tw.Tiddler(templateTiddler.fields,creationFields,fields,modificationFields,{title: title}));
if(this.actionSaveTitle) {
this.wiki.setTextReference(this.actionSaveTitle,title,this.getVariable("currentTiddler"));
}

View File

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

View File

@@ -57,7 +57,7 @@ Invoke the action associated with this widget
ActionPopupWidget.prototype.invokeAction = function(triggeringWidget,event) {
// Trigger the popup
var popupLocationRegExp = /^\((-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+)\)$/,
match = popupLocationRegExp.exec(this.actionCoords);
match = popupLocationRegExp.exec(this.actionCoords || "");
if(match) {
$tw.popup.triggerPopup({
domNode: null,
@@ -70,6 +70,8 @@ ActionPopupWidget.prototype.invokeAction = function(triggeringWidget,event) {
title: this.actionState,
wiki: this.wiki
});
} else {
$tw.popup.cancel(0);
}
return true; // Action was invoked
};

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