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

Compare commits

..

250 Commits

Author SHA1 Message Date
jeremy@jermolene.com
76236f5ebe Version number update for 5.2.2 2022-03-25 13:59:52 +00:00
jeremy@jermolene.com
aec2ad2d12 Update readme 2022-03-25 13:58:31 +00:00
jeremy@jermolene.com
bd6ea2d6a9 Update release note for v5.2.2 2022-03-25 13:56:57 +00:00
jeremy@jermolene.com
74d63c7003 Fix another inadvertent div-nested-in-span 2022-03-25 13:35:25 +00:00
jeremy@jermolene.com
e26a4d8cb5 Merge branch 'tiddlywiki-com' 2022-03-25 13:03:35 +00:00
jeremy@jermolene.com
d1bc079138 Remove rounded corners from new release banner
The CSS for the splash screen expects the image to be rectangular (the rounded corners get a pointed shadow which looks wrong)
2022-03-25 13:02:49 +00:00
jeremy@jermolene.com
ffd3599369 New Release Banner for v5.2.2
Thanks to Elise Springer: https://groups.google.com/g/tiddlywiki/c/y6OMgyQx2-k/m/laL5MszxAQAJ
2022-03-25 13:00:14 +00:00
Mario Pietsch
bfa5882175 German translation adjustments (#6554) 2022-03-24 10:47:24 +00:00
damscal
258f4acb10 Docs typo (#6556)
At the end of file, filerrunprefix --> filterrunprefix
2022-03-24 07:03:19 +00:00
damscal
7e85ec35d3 Signing the CLA (#6555) 2022-03-24 07:02:33 +00:00
jeremy@jermolene.com
a4dcd92f1b Update release note to include span -> div change 2022-03-23 14:07:29 +00:00
Saq Imtiaz
fe581a83b3 Fix nesting of block elements inside inline elements in the edit template (#6553)
* Fix nesting of block elements inside inline elements in the edit template

* Fix typo in previous commit
2022-03-23 13:30:49 +00:00
Saq Imtiaz
25b2e708c9 Fix typo in CSS for drafts list (#6552)
Fixed typo in CSS for drafts list
2022-03-23 13:06:08 +00:00
jeremy@jermolene.com
5db5d711d3 Fix release note typo 2022-03-23 10:15:54 +00:00
jeremy@jermolene.com
075b2ab149 Release note update 2022-03-23 09:36:10 +00:00
jeremy@jermolene.com
8301fb8699 Merge branch 'tiddlywiki-com' 2022-03-22 21:59:12 +00:00
jeremy@jermolene.com
bc81195b5a tw.org just one more CI fix 2022-03-20 17:31:07 +00:00
jeremy@jermolene.com
02f8713012 tw.org yet more CI fixes 2022-03-20 17:11:40 +00:00
jeremy@jermolene.com
9df88bfda9 tw.org more CI fixes 2022-03-20 17:10:05 +00:00
jeremy@jermolene.com
97901d756e tw.org more fixes 2022-03-20 17:01:05 +00:00
jeremy@jermolene.com
ecde2606ad tw.org more CI fixes 2022-03-20 15:56:02 +00:00
jeremy@jermolene.com
938419ba2c tw.org CI fixes 2022-03-20 15:46:09 +00:00
jeremy@jermolene.com
1cb1e77785 Fix bug in 7cc100b82d
I HATE YAML!
2022-03-20 14:13:01 +00:00
jeremy@jermolene.com
a8331f8909 Triggering a build for testing purposes 2022-03-20 14:00:31 +00:00
jeremy@jermolene.com
7cc100b82d Introduce a tiddlywiki.org edition
Using its own build script so that we can push it to https://github.com/TiddlyWiki/tiddlywiki.org-gh-pages
2022-03-20 13:36:08 +00:00
jeremy@jermolene.com
681f22b66d Remove erroneously included code
See https://github.com/Jermolene/TiddlyWiki5/pull/6540#pullrequestreview-914281218
2022-03-18 12:40:12 +00:00
Jeremy Ruston
b0c4886d23 Fix action-listops unsafe use of $tw.utils.stringifyList() (#6540)
Fixes #6535
2022-03-18 10:10:43 +00:00
Bram Chen
c1f123499c Update chinese language files (#6539)
* Add chinese translations for `FieldEditor/*` in ControlPanel.multids.
2022-03-18 08:26:00 +00:00
Saq Imtiaz
977ea24e96 Fix: only refresh styles if the CSS has changed (#6537) 2022-03-17 21:19:49 +00:00
FlashSystems
b529e69289 Add a cascade for rendering fields within the Edit Template (#6511)
* Allow the rendering of fields to be extended

This commit extends the `$:/core/ui/EditTemplate/fields` tiddler to
use a new cascade (Field Editor Cascade) to allow customizing the
rendering of the field editor.
It provides a default element for the cascade that displays the standard
EditTextWidget as a fallback. That way, the implementation is completely
backwards compatible. The `currentTiddler` and `currentField` variables
are available in the transcluded tiddler. This has the additional
benefit, that not only the `EditTextWidget` can be used. The user can
use a dropdown-list or even something completely crazy. As long as it
can be put into a tiddler that updates the field, it will be fine.

* Make `select` Tags in Fields look like the rest

This patch updates the CSS to make `tc-edit-texteditor` usable on
`select`-tags as well.

I'm not sure what `-webkit-appearance: none;` is for, but it hides the
DropDown-arrow in Chrome and makes the select-tag hard to discover. I've
changed the css to only apply it to the input tag. Maybe it can be
removed altogether.

* Add documentation for the Field Editor Cascade
2022-03-17 17:06:24 +00:00
Mario Pietsch
b5edaae1f4 Fix the Advanced search link. ... (#6534) 2022-03-16 15:30:06 +00:00
Mario Pietsch
22fd1ca630 Improve Filters doc and add "Learn more about how to use Filters" link to every operator reference tiddler (#6533) 2022-03-16 12:38:49 +00:00
Mario Pietsch
c741978e95 Fix the button default fix (#6531) 2022-03-16 11:57:56 +00:00
Mario Pietsch
28a91aafa7 Button Widget: ensure changes to "default" attribute trigger a refresh 2022-03-15 12:35:58 +00:00
Jeremy Ruston
1d8c538e45 Eventcatcher widget: add "matchSelector" attribute (#6523)
* Initial Commit

* Allow matchSelector to be used even if selector attribute isn't used
2022-03-14 09:56:23 +00:00
Guang Li
3f0fb71635 use Cascade to set dynannotate ViewTemplate (#6520) 2022-03-12 17:09:47 +00:00
Guang Li
347355128b Update cla-individual.md (#6526) 2022-03-12 17:09:22 +00:00
Marxsal
2a38b15a29 Add files via upload (#6524)
See GG discussion. There are, of course, many tiddlers that need this treatment.
2022-03-11 19:15:28 +00:00
Mario Pietsch
84ad758829 Prepare tabs macro tests for future readability improvements (#6504)
* prepare tabs macro test for future improvements

* update tests for tabs-macro to check all possible parameters
2022-03-11 16:33:58 +00:00
FSpark
f694f5ead7 Signing the CLA (#6518) 2022-03-08 17:02:34 +00:00
tw-FRed
29aef731a3 [fr] New batch of documentation translations (#6508) 2022-03-05 09:19:22 +00:00
tw-FRed
115b20ff7b FR documentation translations update (#6489 redone) (#6502)
* Translation updates, new translations, tiddlers renaming

* Wrong target tiddler name for tw5.com's doc-macros.tid

* Update GettingStarted
2022-03-02 18:50:29 +00:00
CodaCoder
a38b25eff5 Fix issues in WidgetMessage: tm-open-window (#6497) 2022-03-02 17:59:36 +00:00
TW Videos
71df5162ba Improve the docs for the sortan operator (#6495) 2022-03-02 17:40:23 +00:00
TW Videos
864b5ec05d Improve readability for documentation macros (#6494) 2022-03-02 17:36:53 +00:00
Saq Imtiaz
aaf1aa3821 Improve affordances for new browser windows (#6498)
* feat: extend tm-open-window to allow opening the same tiddler in multiple templates, and introduce tm-close-window to close browser windows

* fix: use a windowID parameter to uniquely identify a window and introduce tm-close-all-tiddlers

* fix: whitespace

* fix: update variable
2022-03-02 17:34:02 +00:00
jeremy@jermolene.com
8114d5475b Update release note 2022-03-01 16:56:52 +00:00
jeremy@jermolene.com
29599baa3b Merge branch 'tiddlywiki-com' 2022-03-01 16:49:36 +00:00
Saq Imtiaz
b196cf77e8 Sort sidebar language, plugin and theme list by name rather than description (#6501) 2022-03-01 09:23:19 +00:00
jeremy@jermolene.com
4d3ebf4bf0 Revert "fr-FR next batch of translation updates (#6489)"
This reverts commit b3268546ef.
2022-02-27 17:23:36 +00:00
tw-FRed
b3268546ef fr-FR next batch of translation updates (#6489)
* Move GettingStarted to the right place

Previous batch of translations changed the wrong file

* Revert #6467 for GettingStarted

* Delete $ _editions_tw5.com_doc-macros.tid

Wrong name for the updated tiddler

* Update $__editions_tw5.com_doc-macros.tid

* Translation updates

* Update of 2 tiddlers referenced on HelloThere

* 5 more tiddlers, referenced in WikiText.tid
2022-02-27 17:21:55 +00:00
Saq Imtiaz
615d8da64f Docs: mention MessageCatcher widget in LinkCatcher tiddler (#6485) 2022-02-26 18:59:45 +00:00
TW Videos
45a1478bc9 Allow TiddlyVee to submitt PRs (#6487)
This is pmario and TiddlyVee will be used to create real PRs shown in videos
2022-02-26 18:48:49 +00:00
TW Videos
a071881562 Links to CLA: change branch from master to tiddlywiki-com (#6488) 2022-02-26 18:45:58 +00:00
Ben Webber
2c38c8351b Make butlast[0] consistent with rest (#6483)
butlast[0] now returns the input list unchanged.

Fixes: #5833
2022-02-26 09:42:24 +00:00
Ben Webber
a51191d334 Support specifying insertbefore position title as parameter (#6477)
* Support specifying insertbefore position title as parameter

Closes: #6133

* Update insertbefore calls with new variable parameter syntax

See-also: 96b52606a (Support specifying insertbefore position title as parameter, 2022-02-21)
2022-02-24 11:08:06 +00:00
Saq Imtiaz
4054566493 Extend $draggable to support an optional drag handle (#6480)
* feat: extend  to support a selector attribute identifying the DOM element to be used as the drag handle

* fix: remove redundant variable declaration

* fix: remove extranneous variable declaration
2022-02-24 11:06:18 +00:00
Marxsal
5f994f7d46 Savers: Polly (#6481)
* Savers: Polly

* Polly, with url
2022-02-23 21:47:21 +00:00
Ben Webber
7a7472833f Consider non-existent tiddlers untagged (#6478)
Fixes regression introduced in 575c23359.

Fixes: #6119
See-also: 575c23359 (Update untagged filter to avoid $tw.utils.pushTop (#6034), 2021-09-18)
2022-02-23 12:46:34 +00:00
Marxsal
9777aa9d13 Webdav - category "paid" hosting (#6476) 2022-02-22 19:56:07 +00:00
Cameron Fischer
d0b5b2124a Is draft (#6442)
* corrected [!is[draft]] to be a proper complement

* Ensuring [is[draft]] and [!is[draft]] are complements

* Made [is[draft]] more analogous to .isDraft()
2022-02-22 16:41:29 +00:00
Ben Webber
95bd694a65 Support case insensitive matching in prefix/suffix operators (#6468)
* Support case insensitive matching in prefix/suffix operators

Support `caseinsensitive`/`caseinsensitive` suffixes in the following
filter operators:

  * prefix
  * suffix
  * removeprefix
  * removesuffix

The suffixes have the same behaviour as in the match operator.

Closes: #6407

* Do not filter titles if suffix/removesuffix operand is empty

Issue: #6407
2022-02-22 16:38:40 +00:00
jeremy@jermolene.com
49de500b5e Add contributors to release note 2022-02-22 09:54:46 +00:00
jeremy@jermolene.com
4cf3df0f86 Merge branch 'tiddlywiki-com' 2022-02-22 09:25:15 +00:00
jeremy@jermolene.com
1ae1ff3da2 Update release note 2022-02-21 17:38:11 +00:00
cdruan
4f42df8bef Update highlight.js to v11.4.0 (#6427)
* Rename v9 highlight.js plugin to highlight-legacy

* Add ES6 version of highlight.js plugin

* highlightblock.js

	- ensure this ES6 plugin will not cause error on legacy browsers
	- update the code to use new highlight.js APIs
	- change class tagging to match more closely with highlight.js
	- allow users to add language definitions as JS "highlight" modules

* styles.tid

	- update to match v11

* howto.tid

	- add instructions on how to add language definitions as JS modules

* highlight.min.js, default.min.css

	- version 11.4.0 common languages only

* Remove extraneous whitespaces

* Update readme.tid

* Update bundled languages

bundled: common + apache + nginx + latex + dockerfile + fortran

* Update highlight-legacy subtiddlers' titles

* Touch up highlight-legacy docs

* Touch up highlight plugin docs

* Fix pre block styling

- add "hljs" class to <pre> so the element can be styled
2022-02-21 15:35:13 +00:00
Jeremy Ruston
36b162a377 Fix for tag ordering issue #6382 (#6383)
* Failing test

* Fix underlying problem

* Less naive fix

Now we make sure we maintain the sort order of the titles array when adding a new tiddler

* Fix failing tests

* Refactor filter tests to repeat them with different store orderings

* Revert "Fix failing tests"

This reverts commit ee03ee57f5.

* Refine fix to retain stylesheet ordering

The order of tiddlers in the HTML file uses localeCompare(), and that determines the insertion order. So if we want to be compatible with older versions we have to use localeCompare() to order tiddlers, not a plain sort()

* Don't sort shadow tiddlers

Instead rely on the existing ordering

* Fix failing tests, take 2

I think that all of these changes are explained by the store no longer retaining insertion order, but now using localecompare ordering

* Fix tests from #6327
2022-02-21 15:34:05 +00:00
Jeremy Ruston
82c8fe7fa8 Introduce JSON parse utility function with error handling (#6401)
* Introduce JSON parse utility function with error handling

Fixes #6400

* Fix typo
2022-02-21 15:29:25 +00:00
Jeremy Ruston
5378b45c40 Allow newlines within filtered transclusions (#6421)
* Allow newlines within filtered transclusions

* Docs
2022-02-21 15:28:21 +00:00
Jeremy Ruston
ab3109d84b Add support for directly setting style.* attributes on HTML elements (#6388)
* Support direct style attributes on the element widget

* Fix tests

Not all parse tree nodes have an "orderedAttributes" member (eg. the error message generated at 5613bcc884/core/modules/widgets/transclude.js (L73-L75))

* Ensure ordering isn't insertion dependent if orderedAttributes is missing

* Add docs
2022-02-21 15:24:06 +00:00
Cameron Fischer
a4ab42da8a findListingsOfTiddler should cache results (#6327)
* findListingsOfTiddler uses FieldIndexer now

* Turns out FieldIndexer can't help listed[]
2022-02-21 15:07:30 +00:00
jeremy@jermolene.com
af87727ffc Adjust version tag for #6293 2022-02-21 15:06:39 +00:00
Mario Pietsch
6b4e5c74ad Add "some" flag to search operator (#6293) 2022-02-21 15:05:34 +00:00
lin onetwo
94ab1e998d Create Saving on TidGi.tid (#6473) 2022-02-21 12:23:50 +00:00
jeremy@jermolene.com
8af99878cc Add version tags for #5899 2022-02-21 09:56:05 +00:00
Joshua Fontany
d6d2bc455c Fix server options (#5899)
* removed illegal cahracter in filename

* fixes required plugin options & updates docs

* Update dev docs

* call self.displayError

* Revert "call self.displayError"

This reverts commit 5d599aa979.

* adds path based auth (backwards compatible)

* refactor per-route auth

* get status bug

* server options

* server options

* server options, new 'server-settings' param

* reflow

* fix boot.origin

* refactor new parameters

* restore sitetitle as servername option

* Soft reset to master

* docs update

* tweak wording

* docs

* cleanup

* remove literal string

* cleanup docs

* formatting

* Remove per-path auth

* revert get-status

* fold in PR 5538

* remove server-options

* remove doc

* required-plugins a server-parameter, not option
2022-02-21 09:53:06 +00:00
jeremy@jermolene.com
d5ff723d4c Update version tag for #5742 2022-02-21 09:49:55 +00:00
Joshua Fontany
1d0af90ba2 Extend lookup operator to work with fields and indexes (#5742)
* extend lookup op flexibility with 2 parameters

* bumped .from macro to .24

* aligned syntax

* lookup fixes

* bugfix

* docs

* messed up the tests somehow

* docs fix

* lookup bugfix

* docs

* docs

* call self.displayError

* Revert "call self.displayError"

This reverts commit 5d599aa979.

* storylist

* tests

* tests pass
2022-02-21 09:48:29 +00:00
tw-FRed
b12d6c0758 Use cascade for FR ViewTemplate title instead of shadow tiddler (#6471)
* Delete $__core_ui_ViewTemplate_title.tid

fr-FR modifications to ViewTemplate/title can now be done through cascades mechanism.

* fr-FR New ViewTemplate title cascade

Replacement for old fr-FR ViewTemplate/title shadow tiddler

* fr-FR Better ViewTemplate title cascade

Updated according to @Jermolene review.
2022-02-20 19:38:13 +00:00
tw-FRed
a89677ea40 [fr_FR] French translation update (#6467)
* [fr_FR] Add utility macro for translated links

* Update Saving.tid

* Add TiddlyFox Apocalypse translation

* Update TiddlyFox.tid

* Translate Community Links Aggregator.tid

* Update Forums.tid

* Update Developers.tid

* Update HelloThere.tid

* Update GettingStarted.tid

* Update Community.tid

* Update tw5.com edition macros from uplink

Some text in these macros must be translated.

* Various translation updates

* Clean utility fields I had left over

* Clean older files too
2022-02-20 17:25:25 +00:00
Saq Imtiaz
59572cd75d Extend tm-open-window to support optional top and left position for new browser window (#6470)
* feat: extend tm-open-window to support optional top and left position for new browser window

* fix: whitespace correction

* Update WidgetMessage_ tm-open-window.tid
2022-02-20 11:23:27 +00:00
jeremy@jermolene.com
1d16206188 Add support for tm-relink-tiddler message 2022-02-19 09:38:48 +00:00
jeremy@jermolene.com
37a6ff8521 Move tm-rename-tiddler handling from navigator widget into startup module
This reverses an August 2015 change in 68e15c10641e2eda1e64cf29954786a07326a920; the original rationale was wrong: there is nothing related to the navigator widget in the implementation of the tm-rename-tiddler message
2022-02-19 09:20:32 +00:00
jeremy@jermolene.com
d3ea98fcef Menubar plugin: fix class handling for dropdowns
Fixes  #6457
2022-02-14 10:44:42 +00:00
Bram Chen
5022516c61 Update chinese language files (#6449)
* Update chinese field descriptions

* Revised chinese translations for `DropMessage`
2022-02-08 16:01:30 +00:00
jeremy@jermolene.com
965d8ee014 Update release note 2022-02-08 15:40:15 +00:00
Marxsal
8e50ad1243 Change 'Drop here' to 'Drop now' in import msg (#6435) 2022-02-07 17:32:06 +00:00
jeremy@jermolene.com
33f40c47c6 Use code-body: yes for more templates
Fixes #6444
2022-02-07 16:53:36 +00:00
Cameron Fischer
1b3c2557b8 Fixed issue: deprecated regexp could cause crash (#6438)
* Fixed issue: deprecated regexp could cause crash

* Different fix which will bother plugins less
2022-02-07 16:39:29 +00:00
Dyllon Gagnier
6b31d7cae3 Add TW5-browser-nativesaver to tw5.com docs (#6447)
* Signing the CLA

* Add TW5-browser-nativesaver to tw5.com docs

Co-authored-by: Jeremy Ruston <jeremy@jermolene.com>
2022-02-06 10:49:48 +00:00
jeremy@jermolene.com
1a4766c5a1 Merge branch 'tiddlywiki-com' 2022-02-05 16:39:35 +00:00
btheado
3e62e8406b Docs: Compare the wikitext concept of inline vs. block to the corresponding HTML concept (#6443) 2022-02-03 19:22:24 +00:00
jeremy@jermolene.com
e49dda3b48 Fix search results cutoff on narrow screens
Fixes #6440
2022-02-01 09:36:30 +00:00
jeremy@jermolene.com
bd447f0716 Add talk.tiddlywiki.org as the official forum for the community 2022-01-31 17:05:55 +00:00
RJ Skerry-Ryan
13faeaa0bd Markdown: Let WikiText parsing handle the creation of LaTeX widgets. (#6428)
* Markdown: Let WikiText parsing handle the creation of LaTeX widgets.

When embedding LaTeX snippets in inline HTML nodes, such as TiddlyRemember
macros or HTML tables, the parsing of latex nodes breaks the WikiText by
splitting it into pieces around the latex node.

This commit fixes the issue by converting the Remarkable katex nodes back to
text, using a newline to indicate a block katex snippet. This is then re-parsed
by the WikiText KaTeX plugin.

TESTED:

Created a test wiki with:
```
$ node tiddlywiki.js test --init markdowndemo
$ node tiddlywiki.js test --listen
```

* Verified markdown + KaTeX support still works as expected.
* Verified that embedding LaTeX snippets in inline HTML works (e.g. `<a
href="https://example.com/">$x^2$</a>`).
* Verified the markdown + KaTeX support works as expected with renderWikiText
set to `false`.

* Style: Remove spaces between if and opening parentheses.
2022-01-30 11:23:00 +00:00
twMat
7f0fb2b610 [doc] Update Importing Tiddlers.tid - attempt 2 (#6432) 2022-01-30 11:17:39 +00:00
Rizwan
7d2994388b Remove 2 whitespaces (#6434)
These whitespaces were messing the list rendering
2022-01-30 11:07:32 +00:00
RJ Skerry-Ryan
edb5dc3fdc Add keyword-spacing rule to .eslintrc.yml to reflect the project code style. (#6431)
- Update .eslintignore to ignore "third party" code.
- Add a "lint" script to package.json so `npm run lint` runs eslint on the repo.
2022-01-29 17:41:09 +00:00
Marxsal
df1b1316c8 One word change to 'Images in WikiText' (#6430) 2022-01-29 15:39:29 +00:00
jeremy@jermolene.com
1a0c831216 Add sha256 operator 2022-01-29 11:02:47 +00:00
jeremy@jermolene.com
f4365e4bb4 Macro: remove confusing advice
See https://talk.tiddlywiki.org/t/wikitext-parsing-and-rendering-in-macros/2218
2022-01-28 11:24:06 +00:00
Saq Imtiaz
75d10a2dc3 Fix: bug with importvariables widget when importing block mode widgets. fixes #6424 (#6426) 2022-01-27 17:35:18 +00:00
Marxsal
da7cf7a4f3 QualifyWidget documentation (#6422) 2022-01-25 17:59:59 +00:00
Saq Imtiaz
6452eb56a9 fix: bug introduced with 88812092fd fixes #6419 (#6420) 2022-01-24 19:17:09 +00:00
Saq Imtiaz
9fce8153df Add support to tm-scroll message for scrolling without animating (#6410)
* feat: add support for animationDuration attribute of paramObject for tm-scroll message

* docs: added docs for animationDuration attribute of tm-scroll message

* fix: use .utils.hop instead of Object.hasOwnProperty()

* fix: do not check if object before calling utils.hop()

* fix: syntax
2022-01-24 09:44:04 +00:00
jeremy@jermolene.com
4cdfa4e3f9 Update tm-download-file docs to mention the filename parameter 2022-01-23 18:35:38 +00:00
btheado
d6384df6fc Add warnings about non-recursive nature of dynamic attribute values (#6417) 2022-01-23 18:24:25 +00:00
btheado
f0bd06b38d Add doc related to WikiText parser modes (#6415)
* Added macros for displaying wikitext examples in a table

* Added documentation for WikiText parsing

* Changed recognize to British spelling

* Add links to the new wikitext parser tiddlers
2022-01-23 09:44:01 +00:00
Saq Imtiaz
d823856082 feat: add support for renderEnd method for storyviews in widget's render() method (#6409) 2022-01-19 19:48:02 +00:00
twMat
b02a82ba0f Update list-links-draggabe Macro.tid (#6405)
The commented problem is, I presume, resolved now that we can directly edit fields in the current tiddler.
2022-01-19 11:13:08 +00:00
twMat
c43b013539 Paragraph on "anchor links" for Linking in WikiText.tid (#6404) 2022-01-18 19:27:54 +00:00
twMat
5548186c93 Update size attribute in EditTextWidget.tid (#6403)
ref: https://github.com/Jermolene/TiddlyWiki5/issues/6165
2022-01-17 10:11:20 +00:00
twMat
def9b553a8 typo in EventCatcherWidget.tid (#6399) 2022-01-15 12:57:51 +00:00
jeremy@jermolene.com
35f7a8ea06 Fix renaming a tiddler can result in duplicate tags
Fixes #6398
2022-01-14 16:57:30 +00:00
jeremy@jermolene.com
54bfb28063 Merge branch 'tiddlywiki-com' 2022-01-11 17:51:32 +00:00
jeremy@jermolene.com
80c63b96cf Fix processing of $:/tags/RawMarkupWikified/TopHead tiddlers
Fixes #6395
2022-01-11 17:16:50 +00:00
Nils Lindemann
2ef9ecbc44 Signing the CLA (#6394)
* Using a different account now (Second try)

* Typo
2022-01-10 09:34:02 +00:00
jeremy@jermolene.com
88812092fd Fix crash with "wrap-lines" text editor operation if prefix or suffix is missing
Fixes #6376
2022-01-09 17:43:34 +00:00
jeremy@jermolene.com
4e01fc1838 Radio widget should use default if field/index is missing
Fixes #6389
2022-01-09 17:17:12 +00:00
Louis Davout
5cab75f4a7 In 'Filter Operators' add column to indicate those operators that construct an entirely new selection. (#6351) 2022-01-09 14:44:19 +00:00
btheado
1345384d39 Add section about dynamic links to 'Linking in WikiText' (#6361)
* Add discussion of dynamic links to 'Linking in WikiText'

* Added macro and styles for displaying a 'bad' example

* Use .bad-example macro in 'Linking in WikiText'

* Convert existing warnings to use .bad-example macro
2022-01-09 14:30:22 +00:00
Bram Chen
927013a57a Update chinese field descriptions (#6393) 2022-01-09 14:26:14 +00:00
jeremy@jermolene.com
0d11fccba2 Update release note 2022-01-09 10:18:19 +00:00
jeremy@jermolene.com
d78ad756db Docs missed off 54cfda76ee 2022-01-09 10:18:11 +00:00
jeremy@jermolene.com
5613bcc884 It's 2022 2022-01-03 20:22:52 +00:00
jeremy@jermolene.com
0729d730f8 Merge branch 'tiddlywiki-com' 2022-01-03 20:22:05 +00:00
jeremy@jermolene.com
f2422efeb8 Fix issue with Alice in Wonderland demo
Thanks @pmario

See https://github.com/Jermolene/TiddlyWiki5/pull/6213#issuecomment-1003628637
2022-01-03 20:20:48 +00:00
Cameron Fischer
cbb002ec4b Added sourceURL tags to boot js (#6381) 2022-01-03 17:25:40 +00:00
jeremy@jermolene.com
c7e8c87f85 Refine criteria for displaying $:/core/ system tiddlers as code
Fixes #6369
2022-01-03 16:42:50 +00:00
jeremy@jermolene.com
66ae1d6930 Image widget: Add classes for loading/loaded/error 2022-01-02 17:28:54 +00:00
jeremy@jermolene.com
8e3885277f Update messagecatcher widget example to use newer syntax 2021-12-22 15:31:35 +00:00
jeremy@jermolene.com
9293dfa477 Add docs for "help" field of modals
Previously undocumented for no good reason
2021-12-21 10:26:58 +00:00
Louis Davout
8a80d89582 Signing the CLA (#6347) 2021-12-20 19:36:51 +00:00
btheado
10ebd93df3 Add ViewWidget cross references and examples (#6355)
* Link ViewWidget formats to similar filter operators

* Merge the ViewWidget columns and use the tip macro instead

* Reference the format filter operator in ViewWidget

* More accurate language in the ViewWidget docs
2021-12-20 10:07:34 +00:00
jc-ose
d414eef773 Clarify list location requirement (#6338) 2021-12-14 22:27:05 +00:00
jc-ose
7d1f0ea8f4 Signing the CLA (#6337) 2021-12-14 22:26:22 +00:00
twMat
f477e90192 Update Cascade Filter Run Prefix.tid (#6340) 2021-12-14 22:21:49 +00:00
Maurycy Zarzycki
b4dec78a72 add polish translations to cascades (#6335) 2021-12-13 17:28:35 +00:00
jeremy@jermolene.com
60187dc59e Fix importing/upgrading encrypted single file wikis
The problem was that v5.2.0 trimmed the whitespace from $:/core/templates/store.area.template.html which we'd previously been relying on during the import.

This change still allows v5.2.2 to import encrypted pre-v5.2.0 wikis

Fixes #6330
2021-12-11 19:46:20 +00:00
twMat
4453aefad8 Typo in Images in WikiText.tid (#6328)
Typo in link
2021-12-11 09:29:26 +00:00
jeremy@jermolene.com
54cfda76ee ViewTemplateBodyCascade: Add support for code-body field
Missed off #6168
2021-12-09 20:47:51 +00:00
Rizwan
1e8c2821d6 Acknowledgements for banner design 5.1.21-5.2.0 (#6326) 2021-12-09 17:40:12 +00:00
jeremy@jermolene.com
cbc030fbe2 Merge branch 'tiddlywiki-com' 2021-12-09 11:57:16 +00:00
jeremy@jermolene.com
b454116163 Add banner image credits for v5.2.1
See https://talk.tiddlywiki.org/t/the-banner-designer-should-be-acknowledged-in-the-whats-new-section/1787

cc @ibnishak
2021-12-09 11:56:31 +00:00
jeremy@jermolene.com
0186c6490f Edit type dropdown: Add whitespace between description and MIME type 2021-12-08 21:25:44 +00:00
jeremy@jermolene.com
853a899c77 Avoid wraping field names in field viewers
Also avoid wikifying field names
2021-12-08 19:29:02 +00:00
jeremy@jermolene.com
95a3d7fde2 Temporary new release banner for v5.2.2 2021-12-08 12:42:08 +00:00
jeremy@jermolene.com
d33e0a05e2 Preparing for v5.2.2-prerelease 2021-12-08 12:22:51 +00:00
jeremy@jermolene.com
cb833b3f65 build-site.sh: Update version number 2021-12-08 12:21:16 +00:00
jeremy@jermolene.com
b73c50adeb Version number update for 5.2.1 2021-12-08 12:17:32 +00:00
jeremy@jermolene.com
fdfa45329a Updating readme and contributing 2021-12-08 12:16:55 +00:00
jeremy@jermolene.com
7b1880404c Preparing for release of v5.2.1 2021-12-08 12:01:56 +00:00
jeremy@jermolene.com
2739b1bafe Merge branch 'tiddlywiki-com' 2021-12-08 11:56:50 +00:00
jeremy@jermolene.com
cc782ff518 Update release note 2021-12-08 11:55:40 +00:00
jeremy@jermolene.com
492bfbebe9 Sidebar plugin listing
Fix text colour in DarkPhotos and Muted palettes

Thanks @kookma

See https://github.com/Jermolene/TiddlyWiki5/discussions/6167#discussioncomment-1768298
2021-12-07 21:30:38 +00:00
jeremy@jermolene.com
c9fbff265a Update release note 2021-12-07 13:19:37 +00:00
jeremy@jermolene.com
b0f72d0690 Improve sidebar plugin listing
Fixes #6167
2021-12-07 13:17:15 +00:00
Marxsal
6070a2c921 Add two cloud services that support webdav (#6292) 2021-12-07 12:48:17 +00:00
jeremy@jermolene.com
cb43b91ab6 Add official v5.2.1 banner
See https://groups.google.com/g/tiddlywiki/c/GU0TPGNMPvw/m/y1SyQk_nAQAJ
2021-12-06 17:26:34 +00:00
jeremy@jermolene.com
804bc9e9c0 Merge branch 'tiddlywiki-com' 2021-12-06 17:05:43 +00:00
jeremy@jermolene.com
4514a67a1f Add user documentation for cascade mechanism 2021-12-06 16:59:13 +00:00
jeremy@jermolene.com
edcba4ee16 Docs Macros: Add new <<.tiddler-fields>> macro 2021-12-06 16:59:07 +00:00
jeremy@jermolene.com
9e28356047 Cascades: Ignore draft configuration tiddlers 2021-12-06 16:25:51 +00:00
btheado
44ad8c770f Added documentation tiddlers for intersection filter run prefix (#6307) 2021-12-05 17:27:35 +00:00
btheado
2dd4fa41a5 Add documentation tiddlers for filter filter run prefix (#6310)
* Added documentation tiddlers for filter filter run prefix

* Added examples to compare :filter filter run prefix to :and prefix
2021-12-04 20:44:04 +00:00
tw-FRed
f5389b3859 [FR_fr] Fix Latest Version image not displaying (#6308)
Image broken link on the welcome screen of French documentation edition.
See "Quoi de neuf dans la version 5.2.0" here: https://tiddlywiki.com/languages/fr-FR/index.html#HelloThere
2021-12-04 18:21:28 +00:00
tw-FRed
65c8d74218 Sign the CLA (#6306) 2021-12-04 17:34:57 +00:00
btheado
f88e3939e1 Add a cascade filter run example (#6302) 2021-12-04 10:25:43 +00:00
jeremy@jermolene.com
769778b05b Fix tag of control panel tab for edit template cascade
Missed off a350a76a00 (diff-902fbf6814c65f26a991299f17ef1698df82d1004af8d10d81a11a14660e805c)
2021-12-02 19:25:33 +00:00
jeremy@jermolene.com
f84ff0d778 Update release note 2021-12-02 19:21:07 +00:00
Boris Mann
ca1aabe21f Signing TW CLA (#6076)
Co-authored-by: Jeremy Ruston <jeremy@jermolene.com>
2021-12-01 14:57:46 +00:00
jeremy@jermolene.com
dd801d1571 Merge branch 'tiddlywiki-com' 2021-12-01 09:08:46 +00:00
Saq Imtiaz
485730483b Docs: reference documentation for :cascade filter run prefix (#6294)
* docs: formal documentation for :cascade filter run prefix

* fix: typos

* fix: typos
2021-11-30 15:07:10 +00:00
jeremy@jermolene.com
8b6733d792 Docs: Add a new overview of customisation techniques 2021-11-29 09:21:50 +00:00
Saq Imtiaz
75aabcce64 Fix for CodeMirror issues with drop events in Chrome 96 (#6278)
* fix: handle drag events ourselves in chrome when it adds pseudo file objects to the event

* fix: corrected typo in comment

* fix: coding style

* fix: formatting and remove comments
2021-11-28 14:46:27 +00:00
jeremy@jermolene.com
5dfa6b2bb4 Remove "Page and tiddler layout customisation" and most of the excised subtiddlers
These tiddlers are poor quality, and the titles are long and clumsy
2021-11-27 08:40:56 +00:00
btheado
3798a3c7d0 Add NavigatorWidget example (#6285)
* Add NavigatorWidget example

* Moved NavigatorWidget example into the 'Creating SubStories' tiddler

* Fixed link: NavigationMechanism => HistoryMechanism
2021-11-27 07:58:29 +00:00
Marxsal
1c4b2243a6 New tag 'KeyboardDrivenInput' on two tiddlers (#6271) 2021-11-26 17:51:39 +00:00
Mario Pietsch
c11493ec37 fix TiddlerColorFilters/default ... to return a color name or value (#6283) 2021-11-26 12:10:18 +00:00
jeremy@jermolene.com
b6c8cdae64 Merge branch 'tiddlywiki-com' 2021-11-26 11:19:28 +00:00
jeremy@jermolene.com
b80d079d71 Move docs tiddlers out of the root folder
Some of which I'd accidentally left from 1348607c8f, but I thought it was worth clearing them all up
2021-11-26 11:18:03 +00:00
btheado
6512b038c5 Added examples to compare :map filter run prefix to + prefix (#6282)
* Added examples to compare :map filter run prefix to + prefix

* Prefer ':and' over '+'
2021-11-25 18:03:30 +00:00
jeremy@jermolene.com
6d1d497a63 Tweak docs for #6268 2021-11-25 18:00:32 +00:00
Telumire
6ea7140e8f Add a snippet to visualise faulty stylesheets (#6268)
* Add a snippet to visualise faulty stylesheets

As discussed in https://github.com/Jermolene/TiddlyWiki5/issues/6176, a faulty stylesheet can propagate and break several other stylesheets. This can be tricky to debug in a wiki with a lot of custom stylesheets.

This wikitext snippet will display a list of the stylesheets created/modified by the user and will display a red cross next to the one causing a parsing error.

* Improve the css code and add a message

This commit add a short message that provide guidance on how to fix the CSS error(s).
2021-11-25 17:49:28 +00:00
btheado
7b311b0e4a Fix duplicate example id for map filter run prefix (#6281) 2021-11-25 15:20:30 +00:00
jeremy@jermolene.com
be3018fe3b Cascade: Improve demo custom story tiddler template
Now the buttons are part of the template, making it easier to manage new tiddlers given the tag $:/tags/TiddlerList

See #6280
2021-11-25 08:55:10 +00:00
jeremy@jermolene.com
68095eb392 Docs: Misc minor edits 2021-11-25 08:38:17 +00:00
jeremy@jermolene.com
4bb34e4801 Merge branch 'tiddlywiki-com' 2021-11-24 21:04:47 +00:00
jeremy@jermolene.com
1348607c8f Refactor some docs preparatory to adding the cascade docs on master branch 2021-11-24 21:04:22 +00:00
btheado
2f86779a27 Add doc tiddlers for reduce filter run prefix functionality (#6277)
* Added documentation tiddlers for reduce filter run prefix

* Make filter text box wider so long filters fit better

* removed some duplicate words

* Restored the :reduce filter run prefix tip
2021-11-24 20:02:40 +00:00
jeremy@jermolene.com
2af632a46d Don't use CodeMirror unless in the browser
Avoids crashes when rendering static tiddlers under Node.js that include edit widgets with CodeMirror.

The tiddler "SampleWindowTemplate" in 05606f72ad was triggering a build error in https://github.com/Jermolene/TiddlyWiki5/runs/4310561088?check_suite_focus=true#step:6:41
2021-11-24 10:41:38 +00:00
jeremy@jermolene.com
05606f72ad Merge branch 'tiddlywiki-com' 2021-11-24 10:07:17 +00:00
jeremy@jermolene.com
6d0701e0fa Update release note
I will add some more details about the filter cascade stuff
2021-11-23 17:31:59 +00:00
Saq Imtiaz
76cdc17f3b Support macro parameters in filter run prefixes (#6164)
* Support macro params in filter run prefixes and support substitution for variables set by filter run prefixes

* feat: add support macro parameters and variable substitution for all filter run prefixes

* fix: rename options argument to opts for disambiguation

* feat: add support for macro params to cascade filterrun prefix
2021-11-23 13:51:42 +00:00
Marxsal
7b076eadfa Tag Definition for tiddler node-webkit (#6255) 2021-11-21 22:20:13 +00:00
Marxsal
c5ce2a0a94 Tag Definition for tiddler ModuleType (#6256) 2021-11-21 22:19:54 +00:00
Saq Imtiaz
7fcc84156e Fix: issues with drag and drop in Chrome 96 (#6261)
* fix: issues with drag and drop (false positives in detection for files being dropped) introduced by Chrome 96

* fix: call dragEventContainsType method more consistently.

* fix: call dragEventContainsType method more consistently.
2021-11-21 20:48:16 +00:00
Marxsal
75bf12db7a Tags related to releases for file path (#6236)
* Tags related to releases for file path

* Tag Releases -> Release Template

Changing "Releases" tag to "Release Template"
2021-11-20 17:28:48 +00:00
Marxsal
07de96459e Tags for file paths (#6250) 2021-11-20 17:27:43 +00:00
Marxsal
be036aa9c8 Tag Demonstrations for Sample Wizard tiddlers (#6251) 2021-11-20 17:26:38 +00:00
Bram Chen
0664895670 Update chinese translations (#6249)
* Add chinese translations for `TiddlerColour/*` in ControlPanel.multids

* Fix typo
2021-11-20 16:16:54 +00:00
jeremy@jermolene.com
dde1e4bc0f Fixed missed icon and colour cascades 2021-11-20 08:55:00 +00:00
jeremy@jermolene.com
122de63b71 Add a cascade for choosing tiddler colour
Following on from #6168
2021-11-19 12:01:32 +00:00
jeremy@jermolene.com
e3ba880e18 Fix tag pill colouring
Fixes #6221
2021-11-19 10:52:13 +00:00
Marxsal
e3be15531f Adding tag 'Saving' to four IIS Examples (#6244) 2021-11-19 08:07:19 +00:00
Marxsal
5a3ff4e3dc Adding tag Definition for Osmosoft (#6247) 2021-11-19 07:55:16 +00:00
Marxsal
f7f32f00a3 Adding tag to ListopsData (#6248) 2021-11-19 07:54:43 +00:00
Marxsal
d7d694b14f tagging product badges as HelloThere Badge (#6243) 2021-11-18 18:43:23 +00:00
Cameron Fischer
a6feb6dd66 Changed vanilla/reset.tid to be a css file (#6242) 2021-11-18 18:01:13 +00:00
Marxsal
ecf10e41c3 Add tag 'Definitions' to 'BT' (#6231) 2021-11-18 09:02:05 +00:00
Marxsal
481edc1cfe Tag additions (#6233) 2021-11-18 08:58:41 +00:00
Marxsal
ff5817ab50 Tag additions - Widget Examples (#6234) 2021-11-18 08:56:36 +00:00
Marxsal
80235bf049 New tag - Message Examples (#6235) 2021-11-18 08:56:03 +00:00
Marxsal
ecddd5a7be Tags related to Mechanisms for file path (#6237) 2021-11-18 08:48:16 +00:00
Marxsal
f22fc788e5 Changing tags for NamedCommandParameters (#6238) 2021-11-18 08:47:52 +00:00
Marxsal
f828a582c3 Adding tags for file paths (#6240) 2021-11-18 08:45:20 +00:00
Cameron Fischer
a94f94f352 Trim whitespace is stylesheet viewer (#6241) 2021-11-18 08:43:15 +00:00
Marxsal
9f34a01577 Add tag 'Operator Examples' days of the week tiddler set (#6224) 2021-11-17 12:18:57 +00:00
Marxsal
9cd49ed485 Add tag 'Widget Examples' to 3 sample tiddlers (#6226) 2021-11-17 12:15:03 +00:00
Marxsal
4ea1a05af6 Add tag 'Variable Examples' to 3 tiddlers (#6227) 2021-11-17 12:14:42 +00:00
Marxsal
b6eb6d477b Message tm-open-window enhancements (#6188)
* Message tm-open-window enhancements

* Add Messages tiddler. Enhance its description.
2021-11-17 12:13:01 +00:00
jeremy@jermolene.com
cce18d8e2e Merge branch 'tiddlywiki-com' 2021-11-17 09:33:55 +00:00
Marxsal
45d469ca5c Fix tag 'Hidden Settings' on 'Hidden Setting: New-Image Type (#6225) 2021-11-16 22:41:24 +00:00
Marxsal
fbee714ffe Add tags to route to widgets file path (#6223) 2021-11-16 22:06:04 +00:00
Bram Chen
2429dcc2e2 Add chinese translations of control panel UI for inspecting template cascades (#6219) 2021-11-16 17:01:57 +00:00
Marxsal
4d84422f22 Add tag 'Macro Examples' to examples of macros (#6220) 2021-11-16 17:01:43 +00:00
jeremy@jermolene.com
d98bfbde58 Partial revert of "Add tag Demonstration to related tiddlers (#6213)"
See #6222

This reverts commit 7e32e2efcf.
2021-11-16 09:24:27 +00:00
Marxsal
983787a8f2 Tag changes to TW5 Magick and TiddlyMap Plugin (#6210) 2021-11-15 21:19:17 +00:00
Marxsal
7b83c22e78 Tag changes to Plugin Types (#6211) 2021-11-15 21:18:47 +00:00
Marxsal
c8c43b2811 Add new tag TaskManagementExample to related tiddlers (#6212) 2021-11-15 21:18:22 +00:00
Marxsal
7e32e2efcf Add tag Demonstration to related tiddlers (#6213) 2021-11-15 21:17:47 +00:00
eiro10
6f8e842105 tw5.com : Fix typo in ActionListopsWidget.tid (#6215)
* tw5.com : Fix typo in ActionListopsWidget.tid

* tw5.com : update modified field of ActionListopsWidget.tid

When editing a tiddler outside TW itself, this doesn't change automatically the modified field.
2021-11-15 21:17:10 +00:00
eiro10
ce99c0aa0f tw5.com : Fix typo in contributing.tid (#6216)
* tw5.com : Fix typo in contributing.tid

* tw5.com : update modified field of Contributing.tid

When editing a tiddler outside TW itself, this doesn't change automatically the modified field.
2021-11-15 21:16:36 +00:00
eiro10
3ff165402c tw5.com : Fix typo in list.tid (#6217)
* tw5.com : Fix typo in list.tid

* tw5.com : update modified field of list.tid

When editing a tiddler outside TW itself, this doesn't change automatically the modified field.
2021-11-15 21:15:59 +00:00
Jeremy Ruston
a350a76a00 Add "cascade" filter run prefix and use it to control view templates (#6168)
* Initial Commit

* Set currentTiddler and ..currentTiddler for filter evaulation

* Precompile the filters for performance

* Add explicit test for empty result when no filter passes

* Use the cascade filter run prefix to choose the view template body template

* Use the cascade mechanism to choose between the edit and view templates

* Simplify cascade filter

Thanks @saqimtiaz

* Add control panel UI for inspecting the template cascades

* Refactor import listing and plugin listing as alternate body templates

As suggested by @pmario

* Refer to $:/core/ui/{View|Edit}Template via their associated config tiddlers

* Fix typo in previous commit

* Add demo of custom story tiddler template

* Tweak control panel wording

* Standardise "Story Tiddler Template" nomenclature

* Add a cascade for the editor template body

* Add a cascade for the view template title

* Avoid unwanted whitespace

* Add a cascade for dynamically choosing tiddler icons
2021-11-15 21:06:47 +00:00
Marxsal
05b9dd1822 Add tag TaskManagementExample to ...Mordor... (#6218) 2021-11-15 18:40:08 +00:00
Saq Imtiaz
5207b1c127 Docs: add node.js related tag to relevant tiddlers (#6205) 2021-11-14 15:47:45 +00:00
Saq Imtiaz
267c351735 Docs: add "Widgets" tag to new docs tiddlers (#6195) 2021-11-14 15:47:19 +00:00
eiro10
f545418e55 Signing the CLA (#6206) 2021-11-14 15:45:10 +00:00
Marxsal
97dd832d2e More tag changes for file routing (#6199) 2021-11-14 09:12:19 +00:00
Marxsal
d7e7d87581 Add Filter tag to The Extended Listops Filters (#6201) 2021-11-14 08:47:53 +00:00
Marxsal
bd2efeaaa3 Add new tag 'Table-of-Contents Demonstrations' (#6202) 2021-11-14 08:47:07 +00:00
Marxsal
a206bf56b9 Add new tag 'GettingStarted' to Getting Started Tiddlers (#6204) 2021-11-14 08:42:43 +00:00
Marxsal
a33e94c4ee Correct tag names. Add missing tags (#6193)
* Correct tag names. Add missing tags

* Update _muritest_ by Simon Huber.tid

Auto PR didn't include this.

* Update _TiddlyServer_ by Matt Lauber.tid

Fixing tag
2021-11-13 08:48:52 +00:00
Saq Imtiaz
e9313b1c9d Update Hidden Setting_ Typin Refresh Delay.tid (#6187) 2021-11-09 19:44:15 +00:00
twMat
8096935d87 Update DateFormat.tid (#6186)
Ref [discussion](https://talk.tiddlywiki.org/t/help-me-improve-the-dateformat-doc)
2021-11-09 19:16:25 +00:00
Marxsal
dcb083abb0 Add example of actions attribute to SelectWidget documentation (#6181) 2021-11-08 16:59:17 +00:00
Telumire
6cc76fe6ab Update the tiddler "Simple ways to write protect tiddlers" to use data-tags (#6175) 2021-11-06 08:14:36 +00:00
Marxsal
4f8de1881c Increase specificity of doc-examples input (#6174) 2021-11-05 18:09:53 +00:00
Marxsal
746a8ca17f Restore some docs re EditTextWidget (#6170) 2021-11-04 20:39:53 +00:00
500 changed files with 7594 additions and 1669 deletions

View File

@@ -1,15 +1,8 @@
# Known minified files
# Ignore "third party" code whose style we will not change.
/boot/sjcl.js
/core/modules/utils/base64-utf8/base64-utf8.module.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
/core/modules/utils/diff-match-patch/diff_match_patch_uncompressed.js
/core/modules/utils/dom/csscolorparser.js
/plugins/tiddlywiki/*/files/

View File

@@ -64,7 +64,23 @@ rules:
init-declarations: 'off'
jsx-quotes: error
key-spacing: 'off'
keyword-spacing: 'off'
keyword-spacing:
- error
- before: true
after: false
overrides:
'case':
after: true
'do':
'after': true
'else':
after: true
'return':
after: true
'throw':
after: true
'try':
after: true
line-comment-position: 'off'
linebreak-style: 'off'
lines-around-comment: 'off'

View File

@@ -72,3 +72,6 @@ jobs:
- run: "./bin/ci-push.sh"
env:
GH_TOKEN: ${{ secrets.GITHUBPUSHTOKEN }}
- run: "./bin/build-tw-org.sh"
env:
GH_TOKEN: ${{ secrets.GITHUBPUSHTOKEN }}

View File

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

97
bin/build-tw-org.sh Executable file
View File

@@ -0,0 +1,97 @@
#!/bin/bash
# Build tiddlywiki.org assets.
# Default to the version of TiddlyWiki installed in this repo
if [ -z "$TWORG_BUILD_TIDDLYWIKI" ]; then
TWORG_BUILD_TIDDLYWIKI=./tiddlywiki.js
fi
echo "Using TWORG_BUILD_TIDDLYWIKI as [$TWORG_BUILD_TIDDLYWIKI]"
# Set up the build details
if [ -z "$TWORG_BUILD_DETAILS" ]; then
TWORG_BUILD_DETAILS="$(git symbolic-ref --short HEAD)-$(git rev-parse HEAD) from $(git remote get-url origin)"
fi
echo "Using TWORG_BUILD_DETAILS as [$TWORG_BUILD_DETAILS]"
if [ -z "$TWORG_BUILD_COMMIT" ]; then
TWORG_BUILD_COMMIT="$(git rev-parse HEAD)"
fi
echo "Using TWORG_BUILD_COMMIT as [$TWORG_BUILD_COMMIT]"
# Set up the build output directory
if [ -z "$TWORG_BUILD_OUTPUT" ]; then
TWORG_BUILD_OUTPUT=$(mktemp -d)
fi
mkdir -p $TWORG_BUILD_OUTPUT
if [ ! -d "$TWORG_BUILD_OUTPUT" ]; then
echo 'A valid TWORG_BUILD_OUTPUT environment variable must be set'
exit 1
fi
echo "Using TWORG_BUILD_OUTPUT as [$TWORG_BUILD_OUTPUT]"
# Pull existing GitHub pages content
git clone --depth=1 --branch=main "https://github.com/TiddlyWiki/tiddlywiki.org-gh-pages.git" $TWORG_BUILD_OUTPUT
# Make the CNAME file that GitHub Pages requires
echo "tiddlywiki.org" > $TWORG_BUILD_OUTPUT/CNAME
# Delete any existing static content
mkdir -p $TWORG_BUILD_OUTPUT/static
rm $TWORG_BUILD_OUTPUT/static/*
# Put the build details into a .tid file so that it can be included in each build (deleted at the end of this script)
echo -e -n "title: $:/build\ncommit: $TWORG_BUILD_COMMIT\n\n$TWORG_BUILD_DETAILS\n" > $TWORG_BUILD_OUTPUT/build.tid
######################################################
#
# tiddlywiki.org distribution
#
######################################################
# /index.html Main site
# /favicon.ico Favicon for main site
# /static.html Static rendering of default tiddlers
# /alltiddlers.html Static rendering of all tiddlers
# /static/* Static single tiddlers
# /static/static.css Static stylesheet
# /static/favicon.ico Favicon for static pages
node $TWORG_BUILD_TIDDLYWIKI \
editions/tw.org \
--verbose \
--version \
--load $TWORG_BUILD_OUTPUT/build.tid \
--output $TWORG_BUILD_OUTPUT \
--build favicon static index \
|| exit 1
# Delete the temporary build tiddler
rm $TWORG_BUILD_OUTPUT/build.tid || exit 1
# Push output back to GitHub
# Exit script immediately if any command fails
set -e
pushd $TWORG_BUILD_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/TiddlyWiki/tiddlywiki.org-gh-pages.git" &>/dev/null
git push deploy main &>/dev/null
popd

View File

@@ -68,6 +68,26 @@ $tw.utils.isArrayEqual = function(array1,array2) {
});
};
/*
Add an entry to a sorted array if it doesn't already exist, while maintaining the sort order
*/
$tw.utils.insertSortedArray = function(array,value) {
var low = 0, high = array.length - 1, mid, cmp;
while(low <= high) {
mid = (low + high) >> 1;
cmp = value.localeCompare(array[mid]);
if(cmp > 0) {
low = mid + 1;
} else if(cmp < 0) {
high = mid - 1;
} else {
return array;
}
}
array.splice(low,0,value);
return array;
};
/*
Push entries onto an array, removing them first if they already exist in the array
array: array to modify (assumed to be free of duplicates)
@@ -409,6 +429,19 @@ $tw.utils.parseFields = function(text,fields) {
return fields;
};
// Safely parse a string as JSON
$tw.utils.parseJSONSafe = function(text,defaultJSON) {
try {
return JSON.parse(text);
} catch(e) {
if(typeof defaultJSON === "function") {
return defaultJSON(e);
} else {
return defaultJSON || {};
}
}
};
/*
Resolves a source filepath delimited with `/` relative to a specified absolute root filepath.
In relative paths, the special folder name `..` refers to immediate parent directory, and the
@@ -1081,7 +1114,7 @@ $tw.Wiki = function(options) {
tiddlerTitles = null, // Array of tiddler titles
getTiddlerTitles = function() {
if(!tiddlerTitles) {
tiddlerTitles = Object.keys(tiddlers);
tiddlerTitles = Object.keys(tiddlers).sort(function(a,b) {return a.localeCompare(b);});
}
return tiddlerTitles;
},
@@ -1134,10 +1167,8 @@ $tw.Wiki = function(options) {
}
// Save the new tiddler
tiddlers[title] = tiddler;
// Check we've got it's title
if(tiddlerTitles && tiddlerTitles.indexOf(title) === -1) {
tiddlerTitles.push(title);
}
// Check we've got the title
tiddlerTitles = $tw.utils.insertSortedArray(tiddlerTitles || [],title);
// Record the new tiddler state
updateDescriptor["new"] = {
tiddler: tiddler,
@@ -1322,7 +1353,7 @@ $tw.Wiki = function(options) {
var tiddler = tiddlers[title];
if(tiddler) {
if(tiddler.fields.type === "application/json" && tiddler.hasField("plugin-type") && tiddler.fields.text) {
pluginInfo[tiddler.fields.title] = JSON.parse(tiddler.fields.text);
pluginInfo[tiddler.fields.title] = $tw.utils.parseJSONSafe(tiddler.fields.text);
results.modifiedPlugins.push(tiddler.fields.title);
}
} else {
@@ -1455,7 +1486,7 @@ $tw.Wiki.prototype.defineTiddlerModules = function() {
}
break;
case "application/json":
$tw.modules.define(tiddler.fields.title,tiddler.fields["module-type"],JSON.parse(tiddler.fields.text));
$tw.modules.define(tiddler.fields.title,tiddler.fields["module-type"],$tw.utils.parseJSONSafe(tiddler.fields.text));
break;
case "application/x-tiddler-dictionary":
$tw.modules.define(tiddler.fields.title,tiddler.fields["module-type"],$tw.utils.parseFields(tiddler.fields.text));
@@ -1644,12 +1675,7 @@ $tw.modules.define("$:/boot/tiddlerdeserializer/json","tiddlerdeserializer",{
}
return true;
},
data = {};
try {
data = JSON.parse(text);
} catch(e) {
// Ignore JSON parse errors
}
data = $tw.utils.parseJSONSafe(text);
if($tw.utils.isArray(data) && isTiddlerArrayValid(data)) {
return data;
} else if(isTiddlerValid(data)) {
@@ -1689,7 +1715,7 @@ $tw.boot.decryptEncryptedTiddlers = function(callback) {
$tw.crypto.setPassword(data.password);
var decryptedText = $tw.crypto.decrypt(encryptedText);
if(decryptedText) {
var json = JSON.parse(decryptedText);
var json = $tw.utils.parseJSONSafe(decryptedText);
for(var title in json) {
$tw.preloadTiddler(json[title]);
}
@@ -1889,7 +1915,7 @@ filepath: pathname of the directory containing the specification file
$tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
var tiddlers = [];
// Read the specification
var filesInfo = JSON.parse(fs.readFileSync(filepath + path.sep + "tiddlywiki.files","utf8"));
var filesInfo = $tw.utils.parseJSONSafe(fs.readFileSync(filepath + path.sep + "tiddlywiki.files","utf8"));
// Helper to process a file
var processFile = function(filename,isTiddlerFile,fields,isEditableFile) {
var extInfo = $tw.config.fileExtensionInfo[path.extname(filename)],
@@ -2019,7 +2045,7 @@ $tw.loadPluginFolder = function(filepath,excludeRegExp) {
console.log("Warning: missing plugin.info file in " + filepath);
return null;
}
var pluginInfo = JSON.parse(fs.readFileSync(infoPath,"utf8"));
var pluginInfo = $tw.utils.parseJSONSafe(fs.readFileSync(infoPath,"utf8"));
// Read the plugin files
var pluginFiles = $tw.loadTiddlersFromPath(filepath,excludeRegExp);
// Save the plugin tiddlers into the plugin info
@@ -2136,7 +2162,7 @@ $tw.loadWikiTiddlers = function(wikiPath,options) {
pluginFields;
// Bail if we don't have a wiki info file
if(fs.existsSync(wikiInfoPath)) {
wikiInfo = JSON.parse(fs.readFileSync(wikiInfoPath,"utf8"));
wikiInfo = $tw.utils.parseJSONSafe(fs.readFileSync(wikiInfoPath,"utf8"));
} else {
return null;
}
@@ -2649,3 +2675,4 @@ if(typeof(exports) !== "undefined") {
} else {
_boot(window.$tw);
}
//# sourceURL=$:/boot/boot.js

View File

@@ -117,3 +117,4 @@ if(typeof(exports) === "undefined") {
// Export functionality as a module
exports.bootprefix = _bootprefix;
}
//# sourceURL=$:/boot/bootprefix.js

File diff suppressed because one or more lines are too long

View File

@@ -4,7 +4,7 @@ type: text/plain
TiddlyWiki created by Jeremy Ruston, (jeremy [at] jermolene [dot] com)
Copyright (c) 2004-2007, Jeremy Ruston
Copyright (c) 2007-2021, UnaMesa Association
Copyright (c) 2007-2022, UnaMesa Association
All rights reserved.
Redistribution and use in source and binary forms, with or without

View File

@@ -36,6 +36,8 @@ EditorTypes/Hint: These tiddlers determine which editor is used to edit specific
EditorTypes/Type/Caption: Type
EditTemplateBody/Caption: Edit Template Body
EditTemplateBody/Hint: This rule cascade is used by the default edit template to dynamically choose the template for editing the body of a tiddler.
FieldEditor/Caption: Field Editor
FieldEditor/Hint: This rules cascade is used to dynamically choose the template for rendering a tiddler field based on its name. It is used within the Edit Template.
Info/Caption: Info
Info/Hint: Information about this TiddlyWiki
KeyboardShortcuts/Add/Prompt: Type shortcut here
@@ -208,6 +210,8 @@ Theme/Caption: Theme
Theme/Prompt: Current theme:
TiddlerFields/Caption: Tiddler Fields
TiddlerFields/Hint: This is the full set of TiddlerFields in use in this wiki (including system tiddlers but excluding shadow tiddlers).
TiddlerColour/Caption: Tiddler Colour
TiddlerColour/Hint: This rules cascade is used to dynamically choose the colour for a tiddler (used for the icon and the associated tag pill).
TiddlerIcon/Caption: Tiddler Icon
TiddlerIcon/Hint: This rules cascade is used to dynamically choose the icon for a tiddler.
Toolbars/Caption: Toolbars
@@ -224,4 +228,4 @@ Tools/Download/Full/Caption: Download full wiki
ViewTemplateBody/Caption: View Template Body
ViewTemplateBody/Hint: This rule cascade is used by the default view template to dynamically choose the template for displaying the body of a tiddler.
ViewTemplateTitle/Caption: View Template Title
ViewTemplateTitle/Hint: This rule cascade is used by the default view template to dynamically choose the template for displaying the title of a tiddler.
ViewTemplateTitle/Hint: This rule cascade is used by the default view template to dynamically choose the template for displaying the title of a tiddler.

View File

@@ -3,6 +3,7 @@ title: $:/language/Docs/Fields/
_canonical_uri: The full URI of an external image tiddler
bag: The name of the bag from which a tiddler came
caption: The text to be displayed on a tab or button
code-body: The view template will display the tiddler as code if set to ''yes''
color: The CSS color value associated with a tiddler
component: The name of the component responsible for an [[alert tiddler|AlertMechanism]]
current-tiddler: Used to cache the top tiddler in a [[history list|HistoryMechanism]]
@@ -13,9 +14,9 @@ description: The descriptive text for a plugin, or a modal dialogue
draft.of: For draft tiddlers, contains the title of the tiddler of which this is a draft
draft.title: For draft tiddlers, contains the proposed new title of the tiddler
footer: The footer text for a wizard
hide-body: The view template will hide bodies of tiddlers if set to: ''yes''
hide-body: The view template will hide bodies of tiddlers if set to ''yes''
icon: The title of the tiddler containing the icon associated with a tiddler
library: Indicates that a tiddler should be saved as a JavaScript library if set to: ''yes''
library: Indicates that a tiddler should be saved as a JavaScript library if set to ''yes''
list: An ordered list of tiddler titles associated with a tiddler
list-before: If set, the title of a tiddler before which this tiddler should be added to the ordered list of tiddler titles, or at the start of the list if this field is present but empty
list-after: If set, the title of the tiddler after which this tiddler should be added to the ordered list of tiddler titles, or at the end of the list if this field is present but empty
@@ -32,7 +33,7 @@ tags: A list of tags associated with a tiddler
text: The body text of a tiddler
throttle.refresh: If present, throttles refreshes of this tiddler
title: The unique name of a tiddler
toc-link: Suppresses the tiddler's link in a Table of Contents tree if set to: ''no''
toc-link: Suppresses the tiddler's link in a Table of Contents tree if set to ''no''
type: The content type of a tiddler
version: Version information for a plugin
_is_skinny: If present, indicates that the tiddler text field must be loaded from the server

View File

@@ -14,7 +14,7 @@ ConfirmAction: Do you wish to proceed?
Count: count
DefaultNewTiddlerTitle: New Tiddler
Diffs/CountMessage: <<diff-count>> differences
DropMessage: Drop here (or use the 'Escape' key to cancel)
DropMessage: Drop now (or use the 'Escape' key to cancel)
Encryption/Cancel: Cancel
Encryption/ConfirmClearPassword: Do you wish to clear the password? This will remove the encryption applied when saving this wiki
Encryption/PromptSetPassword: Set a new password for this TiddlyWiki

View File

@@ -48,7 +48,7 @@ Command.prototype.execute = function() {
}
// Tweak the tiddlywiki.info to remove any included wikis
var packagePath = $tw.boot.wikiPath + "/tiddlywiki.info",
packageJson = JSON.parse(fs.readFileSync(packagePath));
packageJson = $tw.utils.parseJSONSafe(fs.readFileSync(packagePath));
delete packageJson.includeWikis;
fs.writeFileSync(packagePath,JSON.stringify(packageJson,null,$tw.config.preferences.jsonSpaces));
return null;

View File

@@ -69,7 +69,7 @@ Command.prototype.execute = function() {
$tw.utils.createFileDirectories(pathname);
fs.writeFileSync(pathname,JSON.stringify(tiddler),"utf8");
// Collect the skinny list data
var pluginTiddlers = JSON.parse(tiddler.text),
var pluginTiddlers = $tw.utils.parseJSONSafe(tiddler.text),
readmeContent = (pluginTiddlers.tiddlers[title + "/readme"] || {}).text,
doesRequireReload = !!self.commander.wiki.doesPluginInfoRequireReload(pluginTiddlers),
iconTiddler = pluginTiddlers.tiddlers[title + "/icon"] || {},

View File

@@ -151,7 +151,7 @@ WikiFolderMaker.prototype.saveCustomPlugin = function(pluginTiddler) {
pluginInfo = pluginTiddler.getFieldStrings({exclude: ["text","type"]});
this.saveJSONFile(directory + path.sep + "plugin.info",pluginInfo);
self.log("Writing " + directory + path.sep + "plugin.info: " + JSON.stringify(pluginInfo,null,$tw.config.preferences.jsonSpaces));
var pluginTiddlers = JSON.parse(pluginTiddler.fields.text).tiddlers; // A hashmap of tiddlers in the plugin
var pluginTiddlers = $tw.utils.parseJSONSafe(pluginTiddler.fields.text).tiddlers; // A hashmap of tiddlers in the plugin
$tw.utils.each(pluginTiddlers,function(tiddler) {
self.saveTiddler(directory,new $tw.Tiddler(tiddler));
});

View File

@@ -17,16 +17,13 @@ exports["application/x-tiddler-html-div"] = function(text,fields) {
};
exports["application/json"] = function(text,fields) {
var incoming,
results = [];
try {
incoming = JSON.parse(text);
} catch(e) {
incoming = [{
title: "JSON error: " + e,
text: ""
}]
}
var results = [],
incoming = $tw.utils.parseJSONSafe(text,function(err) {
return [{
title: "JSON error: " + err,
text: ""
}];
});
if(!$tw.utils.isArray(incoming)) {
incoming = [incoming];
}

View File

@@ -324,7 +324,7 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
If there are no Files, let the browser handle it.
*/
EditTextWidget.prototype.handleDropEvent = function(event) {
if(event.dataTransfer.files.length) {
if($tw.utils.dragEventContainsFiles(event)) {
event.preventDefault();
event.stopPropagation();
this.dispatchDOMEvent(this.cloneEvent(event,["dataTransfer"]));

View File

@@ -13,15 +13,17 @@ Text editor operation to wrap the selected lines with a prefix and suffix
"use strict";
exports["wrap-lines"] = function(event,operation) {
var prefix = event.paramObject.prefix || "",
suffix = event.paramObject.suffix || "";
// Cut just past the preceding line break, or the start of the text
operation.cutStart = $tw.utils.findPrecedingLineBreak(operation.text,operation.selStart);
// Cut to just past the following line break, or to the end of the text
operation.cutEnd = $tw.utils.findFollowingLineBreak(operation.text,operation.selEnd);
// Add the prefix and suffix
operation.replacement = event.paramObject.prefix + "\n" +
operation.replacement = prefix + "\n" +
operation.text.substring(operation.cutStart,operation.cutEnd) + "\n" +
event.paramObject.suffix + "\n";
operation.newSelStart = operation.cutStart + event.paramObject.prefix.length + 1;
suffix + "\n";
operation.newSelStart = operation.cutStart + prefix.length + 1;
operation.newSelEnd = operation.newSelStart + (operation.cutEnd - operation.cutStart);
};

View File

@@ -26,17 +26,19 @@ exports.cascade = function(operationSubFunction,options) {
filterFnList[index] = options.wiki.compileFilter(filter);
}
var output = filterFnList[index](options.wiki.makeTiddlerIterator([title]),{
getVariable: function(name) {
switch(name) {
case "currentTiddler":
return "" + title;
case "..currentTiddler":
return widget.getVariable("currentTiddler");
default:
return widget.getVariable(name);
}
getVariable: function(name,opts) {
opts = opts || {};
opts.variables = {
"currentTiddler": "" + title,
"..currentTiddler": widget.getVariable("currentTiddler")
};
if(name in opts.variables) {
return opts.variables[name];
} else {
return widget.getVariable(name,opts);
}
});
}
});
if(output.length !== 0) {
result = output[0];
return false;

View File

@@ -16,23 +16,30 @@ Export our filter function
exports.filter = function(operationSubFunction,options) {
return function(results,source,widget) {
if(results.length > 0) {
var resultsToRemove = [];
var resultsToRemove = [],
index = 0;
results.each(function(title) {
var filtered = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{
getVariable: function(name) {
switch(name) {
case "currentTiddler":
return "" + title;
case "..currentTiddler":
return widget.getVariable("currentTiddler");
default:
return widget.getVariable(name);
getVariable: function(name,opts) {
opts = opts || {};
opts.variables = {
"currentTiddler": "" + title,
"..currentTiddler": widget.getVariable("currentTiddler"),
"index": "" + index,
"revIndex": "" + (results.length - 1 - index),
"length": "" + results.length
};
if(name in opts.variables) {
return opts.variables[name];
} else {
return widget.getVariable(name,opts);
}
}
});
if(filtered.length === 0) {
resultsToRemove.push(title);
}
++index;
});
results.remove(resultsToRemove);
}

View File

@@ -20,20 +20,19 @@ exports.map = function(operationSubFunction,options) {
results.clear();
$tw.utils.each(inputTitles,function(title) {
var filtered = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{
getVariable: function(name) {
switch(name) {
case "currentTiddler":
return "" + title;
case "..currentTiddler":
return widget.getVariable("currentTiddler");
case "index":
return "" + index;
case "revIndex":
return "" + (inputTitles.length - 1 - index);
case "length":
return "" + inputTitles.length;
default:
return widget.getVariable(name);
getVariable: function(name,opts) {
opts = opts || {};
opts.variables = {
"currentTiddler": "" + title,
"..currentTiddler": widget.getVariable("currentTiddler"),
"index": "" + index,
"revIndex": "" + (inputTitles.length - 1 - index),
"length": "" + inputTitles.length
};
if(name in opts.variables) {
return opts.variables[name];
} else {
return widget.getVariable(name,opts);
}
}
});

View File

@@ -15,26 +15,24 @@ Export our filter prefix function
exports.reduce = function(operationSubFunction,options) {
return function(results,source,widget) {
if(results.length > 0) {
var accumulator = "";
var index = 0;
var accumulator = "",
index = 0;
results.each(function(title) {
var list = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{
getVariable: function(name) {
switch(name) {
case "currentTiddler":
return "" + title;
case "..currentTiddler":
return widget.getVariable("currentTiddler");
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);
getVariable: function(name,opts) {
opts = opts || {};
opts.variables = {
"currentTiddler": "" + title,
"..currentTiddler": widget.getVariable("currentTiddler"),
"index": "" + index,
"revIndex": "" + (results.length - 1 - index),
"length": "" + results.length,
"accumulator": "" + accumulator
};
if(name in opts.variables) {
return opts.variables[name];
} else {
return widget.getVariable(name,opts);
}
}
});

View File

@@ -26,14 +26,16 @@ exports.sort = function(operationSubFunction,options) {
compareFn;
results.each(function(title) {
var key = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{
getVariable: function(name) {
switch(name) {
case "currentTiddler":
return "" + title;
case "..currentTiddler":
return widget.getVariable("currentTiddler");
default:
return widget.getVariable(name);
getVariable: function(name,opts) {
opts = opts || {};
opts.variables = {
"currentTiddler": "" + title,
"..currentTiddler": widget.getVariable("currentTiddler")
};
if(name in opts.variables) {
return opts.variables[name];
} else {
return widget.getVariable(name,opts);
}
}
});

View File

@@ -95,10 +95,12 @@ function parseFilterOperation(operators,filterString,p) {
if(nextBracketPos === -1) {
throw "Missing closing bracket in filter expression";
}
if(!operator.regexp) {
if(operator.regexp) {
operand.text = "";
} else {
operand.text = filterString.substring(p,nextBracketPos);
operator.operands.push(operand);
}
operator.operands.push(operand);
p = nextBracketPos + 1;
}

View File

@@ -0,0 +1,27 @@
/*\
title: $:/core/modules/filters/crypto.js
type: application/javascript
module-type: filteroperator
Filter operators for cryptography, using the Stanford JavaScript library
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
exports.sha256 = function(source,operator,options) {
var results = [],
length = parseInt(operator.operand,10) || 20,
sha256 = function(text) {
return sjcl.codec.hex.fromBits(sjcl.hash.sha256.hash(text)).substr(0,length);
};
source(function(tiddler,title) {
results.push(sha256(title));
});
return results;
};
})();

View File

@@ -20,7 +20,7 @@ exports.insertbefore = function(source,operator,options) {
source(function(tiddler,title) {
results.push(title);
});
var target = options.widget && options.widget.getVariable(operator.suffix || "currentTiddler");
var target = operator.operands[1] || (options.widget && options.widget.getVariable(operator.suffix || "currentTiddler"));
if(target !== operator.operand) {
// Remove the entry from the list if it is present
var pos = results.indexOf(operator.operand);

View File

@@ -19,13 +19,13 @@ exports.draft = function(source,prefix,options) {
var results = [];
if(prefix === "!") {
source(function(tiddler,title) {
if(!tiddler || !$tw.utils.hop(tiddler.fields,"draft.of")) {
if(!tiddler || !tiddler.isDraft()) {
results.push(title);
}
});
} else {
source(function(tiddler,title) {
if(tiddler && $tw.utils.hop(tiddler.fields,"draft.of") && (tiddler.fields["draft.of"].length !== 0)) {
if(tiddler && tiddler.isDraft()) {
results.push(title);
}
});

View File

@@ -87,7 +87,8 @@ exports.butlast = function(source,operator,options) {
source(function(tiddler,title) {
results.push(title);
});
return results.slice(0,-count);
var index = count === 0 ? results.length : -count;
return results.slice(0,index);
};
exports.bl = exports.butlast;

View File

@@ -5,9 +5,11 @@ module-type: filteroperator
Filter operator that looks up values via a title prefix
[lookup:<field>[<prefix>]]
[lookup:<defaultvalue>:<field OR index>[<prefix>],[<field-name OR index-name>]]
Prepends the prefix to the selected items and returns the specified field value
Prepends the prefix to the selected items and returns the specified
field or index value. If the 2nd suffix does not exist, it defaults to field.
If the second operand is missing it defaults to "text" for fields, and "0" for indexes
\*/
(function(){
@@ -20,10 +22,31 @@ Prepends the prefix to the selected items and returns the specified field value
Export our filter function
*/
exports.lookup = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
results.push(options.wiki.getTiddlerText(operator.operand + title) || operator.suffix || '');
});
var results = [],
suffixes = operator.suffixes || [],
defaultSuffix = suffixes[0] ? (suffixes[0][0] || "") : "",
indexSuffix = (suffixes[1] && suffixes[1][0] === "index") ? true : false,
target;
if(operator.operands.length == 2) {
target = operator.operands[1]
} else {
target = indexSuffix ? "0": "text";
}
if(indexSuffix) {
source(function(tiddler,title) {
var data = options.wiki.extractTiddlerDataItem(operator.operands[0]+title,target,defaultSuffix);
results.push(data);
});
} else {
source(function(tiddler,title) {
var value = defaultSuffix;
var targetTiddler = options.wiki.getTiddler(operator.operands[0]+title);
if(targetTiddler && targetTiddler.getFieldString(target)) {
value = targetTiddler.getFieldString(target);
}
results.push(value);
});
}
return results;
};

View File

@@ -16,19 +16,37 @@ Filter operator for checking if a title starts with a prefix
Export our filter function
*/
exports.prefix = function(source,operator,options) {
var results = [];
if(operator.prefix === "!") {
source(function(tiddler,title) {
if(title.substr(0,operator.operand.length) !== operator.operand) {
results.push(title);
}
});
var results = [],
suffixes = (operator.suffixes || [])[0] || [];
if(suffixes.indexOf("caseinsensitive") !== -1) {
var operand = operator.operand.toLowerCase();
if(operator.prefix === "!") {
source(function(tiddler,title) {
if(title.toLowerCase().substr(0,operand.length) !== operand) {
results.push(title);
}
});
} else {
source(function(tiddler,title) {
if(title.toLowerCase().substr(0,operand.length) === operand) {
results.push(title);
}
});
}
} else {
source(function(tiddler,title) {
if(title.substr(0,operator.operand.length) === operator.operand) {
results.push(title);
}
});
if(operator.prefix === "!") {
source(function(tiddler,title) {
if(title.substr(0,operator.operand.length) !== operator.operand) {
results.push(title);
}
});
} else {
source(function(tiddler,title) {
if(title.substr(0,operator.operand.length) === operator.operand) {
results.push(title);
}
});
}
}
return results;
};

View File

@@ -16,12 +16,22 @@ Filter operator for removing a prefix from each title in the list. Titles that d
Export our filter function
*/
exports.removeprefix = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
if(title.substr(0,operator.operand.length) === operator.operand) {
results.push(title.substr(operator.operand.length));
}
});
var results = [],
suffixes = (operator.suffixes || [])[0] || [];
if(suffixes.indexOf("caseinsensitive") !== -1) {
var operand = operator.operand.toLowerCase();
source(function(tiddler,title) {
if(title.toLowerCase().substr(0,operand.length) === operand) {
results.push(title.substr(operand.length));
}
});
} else {
source(function(tiddler,title) {
if(title.substr(0,operator.operand.length) === operator.operand) {
results.push(title.substr(operator.operand.length));
}
});
}
return results;
};

View File

@@ -16,12 +16,26 @@ Filter operator for removing a suffix from each title in the list. Titles that d
Export our filter function
*/
exports.removesuffix = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
if(title && title.substr(-operator.operand.length) === operator.operand) {
results.push(title.substr(0,title.length - operator.operand.length));
}
});
var results = [],
suffixes = (operator.suffixes || [])[0] || [];
if (!operator.operand) {
source(function(tiddler,title) {
results.push(title);
});
} else if(suffixes.indexOf("caseinsensitive") !== -1) {
var operand = operator.operand.toLowerCase();
source(function(tiddler,title) {
if(title && title.toLowerCase().substr(-operand.length) === operand) {
results.push(title.substr(0,title.length - operand.length));
}
});
} else {
source(function(tiddler,title) {
if(title && title.substr(-operator.operand.length) === operator.operand) {
results.push(title.substr(0,title.length - operator.operand.length));
}
});
}
return results;
};

View File

@@ -40,6 +40,7 @@ exports.search = function(source,operator,options) {
invert: invert,
field: fields,
excludeField: excludeFields,
some: hasFlag("some"),
caseSensitive: hasFlag("casesensitive"),
literal: hasFlag("literal"),
whitespace: hasFlag("whitespace"),

View File

@@ -16,19 +16,41 @@ Filter operator for checking if a title ends with a suffix
Export our filter function
*/
exports.suffix = function(source,operator,options) {
var results = [];
if(operator.prefix === "!") {
var results = [],
suffixes = (operator.suffixes || [])[0] || [];
if (!operator.operand) {
source(function(tiddler,title) {
if(title.substr(-operator.operand.length) !== operator.operand) {
results.push(title);
}
results.push(title);
});
} else if(suffixes.indexOf("caseinsensitive") !== -1) {
var operand = operator.operand.toLowerCase();
if(operator.prefix === "!") {
source(function(tiddler,title) {
if(title.toLowerCase().substr(-operand.length) !== operand) {
results.push(title);
}
});
} else {
source(function(tiddler,title) {
if(title.toLowerCase().substr(-operand.length) === operand) {
results.push(title);
}
});
}
} else {
source(function(tiddler,title) {
if(title.substr(-operator.operand.length) === operator.operand) {
results.push(title);
}
});
if(operator.prefix === "!") {
source(function(tiddler,title) {
if(title.substr(-operator.operand.length) !== operator.operand) {
results.push(title);
}
});
} else {
source(function(tiddler,title) {
if(title.substr(-operator.operand.length) === operator.operand) {
results.push(title);
}
});
}
}
return results;
};

View File

@@ -19,7 +19,7 @@ exports.untagged = function(source,operator,options) {
var results = [],
expected = (operator.prefix === "!");
source(function(tiddler,title) {
if((tiddler && $tw.utils.isArray(tiddler.fields.tags) && tiddler.fields.tags.length > 0) === expected) {
if(((tiddler && $tw.utils.isArray(tiddler.fields.tags) && tiddler.fields.tags.length > 0) === expected) || (!tiddler && !expected)) {
results.push(title);
}
});

View File

@@ -239,7 +239,7 @@ exports.parseFilterVariable = function(source) {
};
/*
Look for an HTML attribute definition. Returns null if not found, otherwise returns {type: "attribute", name:, valueType: "string|indirect|macro", value:, start:, end:,}
Look for an HTML attribute definition. Returns null if not found, otherwise returns {type: "attribute", name:, type: "filtered|string|indirect|macro", value|filter|textReference:, start:, end:,}
*/
exports.parseAttribute = function(source,pos) {
var node = {
@@ -248,7 +248,7 @@ exports.parseAttribute = function(source,pos) {
// Define our regexps
var reAttributeName = /([^\/\s>"'=]+)/g,
reUnquotedAttribute = /([^\/\s<>"'=]+)/g,
reFilteredValue = /\{\{\{(.+?)\}\}\}/g,
reFilteredValue = /\{\{\{([\S\s]+?)\}\}\}/g,
reIndirectValue = /\{\{([^\}]+)\}\}/g;
// Skip whitespace
pos = $tw.utils.skipWhiteSpace(source,pos);

View File

@@ -52,7 +52,7 @@ PluginSwitcher.prototype.switchPlugins = function() {
var tiddler = self.wiki.getTiddler(title);
if(tiddler && tiddler.isPlugin() && plugins.indexOf(title) === -1) {
plugins.push(title);
var pluginInfo = JSON.parse(self.wiki.getTiddlerText(title)),
var pluginInfo = $tw.utils.parseJSONSafe(self.wiki.getTiddlerText(title)),
dependents = $tw.utils.parseStringArray(tiddler.fields.dependents || "");
$tw.utils.each(dependents,function(title) {
accumulatePlugin(title);

View File

@@ -61,7 +61,7 @@ GiteaSaver.prototype.save = function(text,method,callback) {
}
var use_put = true;
if(xhr.status !== 404) {
getResponseData = JSON.parse(getResponseDataJson);
getResponseData = $tw.utils.parseJSONSafe(getResponseDataJson);
$tw.utils.each(getResponseData,function(details) {
if(details.name === filename) {
sha = details.sha;
@@ -104,7 +104,7 @@ GiteaSaver.prototype.upload = function(uri,method,headers,data,callback) {
if(err) {
return callback(err);
}
var putResponseData = JSON.parse(putResponseDataJson);
var putResponseData = $tw.utils.parseJSONSafe(putResponseDataJson);
callback(null);
}
});

View File

@@ -61,7 +61,7 @@ GitHubSaver.prototype.save = function(text,method,callback) {
return callback(err);
}
if(xhr.status !== 404) {
getResponseData = JSON.parse(getResponseDataJson);
getResponseData = $tw.utils.parseJSONSafe(getResponseDataJson);
$tw.utils.each(getResponseData,function(details) {
if(details.name === filename) {
sha = details.sha;
@@ -84,7 +84,7 @@ GitHubSaver.prototype.save = function(text,method,callback) {
if(err) {
return callback(err);
}
var putResponseData = JSON.parse(putResponseDataJson);
var putResponseData = $tw.utils.parseJSONSafe(putResponseDataJson);
callback(null);
}
});

View File

@@ -58,7 +58,7 @@ GitLabSaver.prototype.save = function(text,method,callback) {
}
var requestType = "POST";
if(xhr.status !== 404) {
getResponseData = JSON.parse(getResponseDataJson);
getResponseData = $tw.utils.parseJSONSafe(getResponseDataJson);
$tw.utils.each(getResponseData,function(details) {
if(details.name === filename) {
requestType = "PUT";
@@ -82,7 +82,7 @@ GitLabSaver.prototype.save = function(text,method,callback) {
if(err) {
return callback(err);
}
var putResponseData = JSON.parse(putResponseDataJson);
var putResponseData = $tw.utils.parseJSONSafe(putResponseDataJson);
callback(null);
}
});

View File

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

View File

@@ -34,7 +34,6 @@ function Server(options) {
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);
if(options.variables) {
@@ -44,7 +43,8 @@ function Server(options) {
}
}
}
$tw.utils.extend({},this.defaultVariables,options.variables);
// Setup the default required plugins
this.requiredPlugins = this.get("required-plugins").split(',');
// Initialise CSRF
this.csrfDisable = this.get("csrf-disable") === "yes";
// Initialize Gzip compression
@@ -52,14 +52,24 @@ function Server(options) {
// Initialize browser-caching
this.enableBrowserCache = this.get("use-browser-cache") === "yes";
// Initialise authorization
var authorizedUserName = (this.get("username") && this.get("password")) ? this.get("username") : "(anon)";
var authorizedUserName;
if(this.get("username") && this.get("password")) {
authorizedUserName = this.get("username");
} else if(this.get("credentials")) {
authorizedUserName = "(authenticated)";
} else {
authorizedUserName = "(anon)";
}
this.authorizationPrincipals = {
readers: (this.get("readers") || authorizedUserName).split(",").map($tw.utils.trim),
writers: (this.get("writers") || authorizedUserName).split(",").map($tw.utils.trim)
}
if(this.get("admin") || authorizedUserName !== "(anon)") {
this.authorizationPrincipals["admin"] = (this.get("admin") || authorizedUserName).split(',').map($tw.utils.trim)
}
// Load and initialise authenticators
$tw.modules.forEachModuleOfType("authenticator", function(title,authenticatorDefinition) {
// console.log("Loading server route " + title);
// console.log("Loading authenticator " + title);
self.addAuthenticator(authenticatorDefinition.AuthenticatorClass);
});
// Load route handlers
@@ -71,15 +81,21 @@ function Server(options) {
this.listenOptions = null;
this.protocol = "http";
var tlsKeyFilepath = this.get("tls-key"),
tlsCertFilepath = this.get("tls-cert");
tlsCertFilepath = this.get("tls-cert"),
tlsPassphrase = this.get("tls-passphrase");
if(tlsCertFilepath && tlsKeyFilepath) {
this.listenOptions = {
key: fs.readFileSync(path.resolve(this.boot.wikiPath,tlsKeyFilepath),"utf8"),
cert: fs.readFileSync(path.resolve(this.boot.wikiPath,tlsCertFilepath),"utf8")
cert: fs.readFileSync(path.resolve(this.boot.wikiPath,tlsCertFilepath),"utf8"),
passphrase: tlsPassphrase || ''
};
this.protocol = "https";
}
this.transport = require(this.protocol);
// Name the server and init the boot state
this.servername = $tw.utils.transliterateToSafeASCII(this.get("server-name") || this.wiki.getTiddlerText("$:/SiteTitle") || "TiddlyWiki5");
this.boot.origin = this.get("origin")? this.get("origin"): this.protocol+"://"+this.get("host")+":"+this.get("port");
this.boot.pathPrefix = this.get("path-prefix") || "";
}
/*
@@ -150,6 +166,7 @@ function sendResponse(request,response,statusCode,headers,data,encoding) {
Server.prototype.defaultVariables = {
port: "8080",
host: "127.0.0.1",
"required-plugins": "$:/plugins/tiddlywiki/filesystem,$:/plugins/tiddlywiki/tiddlyweb",
"root-tiddler": "$:/core/save/all",
"root-render-type": "text/plain",
"root-serve-type": "text/html",
@@ -239,15 +256,15 @@ Server.prototype.requestHandler = function(request,response,options) {
state.pathPrefix = options.pathPrefix || this.get("path-prefix") || "";
state.sendResponse = sendResponse.bind(self,request,response);
// Get the principals authorized to access this resource
var authorizationType = this.methodMappings[request.method] || "readers";
state.authorizationType = options.authorizationType || this.methodMappings[request.method] || "readers";
// Check for the CSRF header if this is a write
if(!this.csrfDisable && authorizationType === "writers" && request.headers["x-requested-with"] !== "TiddlyWiki") {
if(!this.csrfDisable && state.authorizationType === "writers" && request.headers["x-requested-with"] !== "TiddlyWiki") {
response.writeHead(403,"'X-Requested-With' header required to login to '" + this.servername + "'");
response.end();
return;
}
// Check whether anonymous access is granted
state.allowAnon = this.isAuthorized(authorizationType,null);
state.allowAnon = this.isAuthorized(state.authorizationType,null);
// Authenticate with the first active authenticator
if(this.authenticators.length > 0) {
if(!this.authenticators[0].authenticateRequest(request,response,state)) {
@@ -256,7 +273,7 @@ Server.prototype.requestHandler = function(request,response,options) {
}
}
// Authorize with the authenticated username
if(!this.isAuthorized(authorizationType,state.authenticatedUsername)) {
if(!this.isAuthorized(state.authorizationType,state.authenticatedUsername)) {
response.writeHead(401,"'" + state.authenticatedUsername + "' is not authorized to access '" + this.servername + "'");
response.end();
return;
@@ -322,8 +339,16 @@ Server.prototype.listen = function(port,host,prefix) {
port = process.env[port] || 8080;
}
// Warn if required plugins are missing
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");
var missing = [];
for (var index=0; index<this.requiredPlugins.length; index++) {
if (!this.wiki.getTiddler(this.requiredPlugins[index])) {
missing.push(this.requiredPlugins[index]);
}
}
if(missing.length > 0) {
var error = "Warning: Plugin(s) required for client-server operation are missing.\n"+
"\""+ missing.join("\", \"")+"\"";
$tw.utils.warning(error);
}
// Create the server
var server;

View File

@@ -152,7 +152,7 @@ exports.startup = function() {
if(event.data.status.charAt(0) === "2") {
if(event.data.cookies) {
if(event.data.cookies.type === "save-info") {
var tiddlers = JSON.parse(event.data.body);
var tiddlers = $tw.utils.parseJSONSafe(event.data.body);
$tw.utils.each(tiddlers,function(tiddler) {
$tw.wiki.addTiddler(new $tw.Tiddler($tw.wiki.getCreationFields(),tiddler,{
title: event.data.cookies.infoTitlePrefix + event.data.cookies.url + "/" + tiddler.title,
@@ -170,7 +170,7 @@ exports.startup = function() {
},$tw.wiki.getModificationFields()));
});
} else if(event.data.cookies.type === "save-tiddler") {
var tiddler = JSON.parse(event.data.body);
var tiddler = $tw.utils.parseJSONSafe(event.data.body);
$tw.wiki.addTiddler(new $tw.Tiddler(tiddler));
}
}

View File

@@ -42,12 +42,17 @@ exports.startup = function() {
$tw.styleWidgetNode = $tw.wiki.makeTranscludeWidget(PAGE_STYLESHEET_TITLE,{document: $tw.fakeDocument});
$tw.styleContainer = $tw.fakeDocument.createElement("style");
$tw.styleWidgetNode.render($tw.styleContainer,null);
$tw.styleWidgetNode.assignedStyles = $tw.styleContainer.textContent;
$tw.styleElement = document.createElement("style");
$tw.styleElement.innerHTML = $tw.styleContainer.textContent;
$tw.styleElement.innerHTML = $tw.styleWidgetNode.assignedStyles;
document.head.insertBefore($tw.styleElement,document.head.firstChild);
$tw.wiki.addEventListener("change",$tw.perf.report("styleRefresh",function(changes) {
if($tw.styleWidgetNode.refresh(changes,$tw.styleContainer,null)) {
$tw.styleElement.innerHTML = $tw.styleContainer.textContent;
var newStyles = $tw.styleContainer.textContent;
if(newStyles !== $tw.styleWidgetNode.assignedStyles) {
$tw.styleWidgetNode.assignedStyles = newStyles;
$tw.styleElement.innerHTML = $tw.styleWidgetNode.assignedStyles;
}
}
}));
// Display the $:/core/ui/PageTemplate tiddler to kick off the display

View File

@@ -51,6 +51,20 @@ exports.startup = function() {
element.focus(event.paramObject);
}
});
// Install the tm-rename-tiddler and tm-relink-tiddler messages
var makeRenameHandler = function(method) {
return function(event) {
var options = {},
paramObject = event.paramObject || {},
from = paramObject.from || event.tiddlerTitle,
to = paramObject.to;
options.dontRenameInTags = (paramObject.renameInTags === "false" || paramObject.renameInTags === "no") ? true : false;
options.dontRenameInLists = (paramObject.renameInLists === "false" || paramObject.renameInLists === "no") ? true : false;
$tw.wiki[method](from,to,options);
};
};
$tw.rootWidget.addEventListener("tm-rename-tiddler",makeRenameHandler("renameTiddler"));
$tw.rootWidget.addEventListener("tm-relink-tiddler",makeRenameHandler("relinkTiddler"));
// Install the scroller
$tw.pageScroller = new $tw.utils.PageScroller();
$tw.rootWidget.addEventListener("tm-scroll",function(event) {

View File

@@ -20,6 +20,8 @@ exports.synchronous = true;
// Global to keep track of open windows (hashmap by title)
$tw.windows = {};
// Default template to use for new windows
var DEFAULT_WINDOW_TEMPLATE = "$:/core/templates/single.tiddler.window";
exports.startup = function() {
// Handle open window message
@@ -29,22 +31,25 @@ exports.startup = function() {
title = event.param || event.tiddlerTitle,
paramObject = event.paramObject || {},
windowTitle = paramObject.windowTitle || title,
template = paramObject.template || "$:/core/templates/single.tiddler.window",
windowID = paramObject.windowID || title,
template = paramObject.template || DEFAULT_WINDOW_TEMPLATE,
width = paramObject.width || "700",
height = paramObject.height || "600",
variables = $tw.utils.extend({},paramObject,{currentTiddler: title});
top = paramObject.top,
left = paramObject.left,
variables = $tw.utils.extend({},paramObject,{currentTiddler: title, "tv-window-id": windowID});
// Open the window
var srcWindow,
srcDocument;
// In case that popup blockers deny opening a new window
try {
srcWindow = window.open("","external-" + title,"scrollbars,width=" + width + ",height=" + height),
srcWindow = window.open("","external-" + windowID,"scrollbars,width=" + width + ",height=" + height + (top ? ",top=" + top : "" ) + (left ? ",left=" + left : "" )),
srcDocument = srcWindow.document;
}
catch(e) {
return;
}
$tw.windows[title] = srcWindow;
$tw.windows[windowID] = srcWindow;
// Check for reopening the same window
if(srcWindow.haveInitialisedWindow) {
return;
@@ -54,7 +59,7 @@ exports.startup = function() {
srcDocument.close();
srcDocument.title = windowTitle;
srcWindow.addEventListener("beforeunload",function(event) {
delete $tw.windows[title];
delete $tw.windows[windowID];
$tw.wiki.removeEventListener("change",refreshHandler);
},false);
// Set up the styles
@@ -88,13 +93,21 @@ exports.startup = function() {
srcWindow.document.documentElement.addEventListener("click",$tw.popup,true);
srcWindow.haveInitialisedWindow = true;
});
// Close open windows when unloading main window
$tw.addUnloadTask(function() {
$tw.rootWidget.addEventListener("tm-close-window",function(event) {
var windowID = event.param,
win = $tw.windows[windowID];
if(win) {
win.close();
}
});
var closeAllWindows = function() {
$tw.utils.each($tw.windows,function(win) {
win.close();
});
});
}
$tw.rootWidget.addEventListener("tm-close-all-windows",closeAllWindows);
// Close open windows when unloading main window
$tw.addUnloadTask(closeAllWindows);
};
})();

View File

@@ -24,13 +24,13 @@ exports.isDraft = function() {
return this.hasField("draft.of");
};
exports.getFieldString = function(field) {
exports.getFieldString = function(field,defaultValue) {
var value = this.fields[field];
// Check for a missing field
if(value === undefined || value === null) {
return "";
return defaultValue || "";
}
// Parse the field with the associated module (if any)
// Stringify the field with the associated tiddler field module (if any)
var fieldModule = $tw.Tiddler.fieldModules[field];
if(fieldModule && fieldModule.stringify) {
return fieldModule.stringify.call(this,value);

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 = wiki.doesPluginInfoRequireReload(JSON.parse(incomingTiddler.text)) ? (wiki.getTiddlerText("$:/language/ControlPanel/Plugins/PluginWillRequireReload") + " ") : "";
var requiresReload = wiki.doesPluginInfoRequireReload($tw.utils.parseJSONSafe(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

View File

@@ -21,7 +21,7 @@ exports.extractEncryptedStoreArea = function(text) {
if(encryptedStoreAreaStart !== -1) {
var encryptedStoreAreaEnd = text.indexOf("</pre>",encryptedStoreAreaStart);
if(encryptedStoreAreaEnd !== -1) {
return $tw.utils.htmlDecode(text.substring(encryptedStoreAreaStart + encryptedStoreAreaStartMarker.length,encryptedStoreAreaEnd-1));
return $tw.utils.htmlDecode(text.substring(encryptedStoreAreaStart + encryptedStoreAreaStartMarker.length,encryptedStoreAreaEnd));
}
}
return null;
@@ -33,7 +33,7 @@ Attempt to extract the tiddlers from an encrypted store area using the current p
exports.decryptStoreArea = function(encryptedStoreArea,password) {
var decryptedText = $tw.crypto.decrypt(encryptedStoreArea,password);
if(decryptedText) {
var json = JSON.parse(decryptedText),
var json = $tw.utils.parseJSONSafe(decryptedText),
tiddlers = [];
for(var title in json) {
if(title !== "$:/isEncrypted") {

View File

@@ -16,21 +16,23 @@ Browser data transfer utilities, used with the clipboard and drag and drop
Options:
domNode: dom node to make draggable
selector: CSS selector to identify element within domNode to be used as drag handle (optional)
dragImageType: "pill", "blank" or "dom" (the default)
dragTiddlerFn: optional function to retrieve the title of tiddler to drag
dragFilterFn: optional function to retreive the filter defining a list of tiddlers to drag
widget: widget to use as the contect for the filter
widget: widget to use as the context for the filter
*/
exports.makeDraggable = function(options) {
var dragImageType = options.dragImageType || "dom",
dragImage,
domNode = options.domNode;
domNode = options.domNode,
dragHandle = options.selector && domNode.querySelector(options.selector) || domNode;
// Make the dom node draggable (not necessary for anchor tags)
if((domNode.tagName || "").toLowerCase() !== "a") {
domNode.setAttribute("draggable","true");
dragHandle.setAttribute("draggable","true");
}
// Add event handlers
$tw.utils.addEventListeners(domNode,[
$tw.utils.addEventListeners(dragHandle,[
{name: "dragstart", handlerFunction: function(event) {
if(event.dataTransfer === undefined) {
return false;
@@ -45,7 +47,7 @@ exports.makeDraggable = function(options) {
}
var titleString = $tw.utils.stringifyList(titles);
// Check that we've something to drag
if(titles.length > 0 && event.target === domNode) {
if(titles.length > 0 && event.target === dragHandle) {
// Mark the drag in progress
$tw.dragInProgress = domNode;
// Set the dragging class on the element being dragged
@@ -198,7 +200,7 @@ var importDataTypes = [
];
function parseJSONTiddlers(json,fallbackTitle) {
var data = JSON.parse(json);
var data = $tw.utils.parseJSONSafe(json);
if(!$tw.utils.isArray(data)) {
data = [data];
}
@@ -208,10 +210,10 @@ function parseJSONTiddlers(json,fallbackTitle) {
return data;
};
exports.dragEventContainsFiles = function(event) {
function dragEventContainsType(event,targetType) {
if(event.dataTransfer.types) {
for(var i=0; i<event.dataTransfer.types.length; i++) {
if(event.dataTransfer.types[i] === "Files") {
if(event.dataTransfer.types[i] === targetType) {
return true;
break;
}
@@ -220,4 +222,10 @@ exports.dragEventContainsFiles = function(event) {
return false;
};
exports.dragEventContainsFiles = function(event) {
return (dragEventContainsType(event,"Files") && !dragEventContainsType(event,"text/plain"));
};
exports.dragEventContainsType = dragEventContainsType;
})();

View File

@@ -49,10 +49,14 @@ Handle an event
*/
PageScroller.prototype.handleEvent = function(event) {
if(event.type === "tm-scroll") {
var options = {};
if($tw.utils.hop(event.paramObject,"animationDuration")) {
options.animationDuration = event.paramObject.animationDuration;
}
if(event.paramObject && event.paramObject.selector) {
this.scrollSelectorIntoView(null,event.paramObject.selector);
this.scrollSelectorIntoView(null,event.paramObject.selector,null,options);
} else {
this.scrollIntoView(event.target);
this.scrollIntoView(event.target,null,options);
}
return false; // Event was handled
}
@@ -62,10 +66,10 @@ PageScroller.prototype.handleEvent = function(event) {
/*
Handle a scroll event hitting the page document
*/
PageScroller.prototype.scrollIntoView = function(element,callback) {
PageScroller.prototype.scrollIntoView = function(element,callback,options) {
var self = this,
duration = $tw.utils.getAnimationDuration(),
srcWindow = element ? element.ownerDocument.defaultView : window;
duration = $tw.utils.hop(options,"animationDuration") ? parseInt(options.animationDuration) : $tw.utils.getAnimationDuration(),
srcWindow = element ? element.ownerDocument.defaultView : window;
// Now get ready to scroll the body
this.cancelScroll(srcWindow);
this.startTime = Date.now();
@@ -122,11 +126,11 @@ PageScroller.prototype.scrollIntoView = function(element,callback) {
drawFrame();
};
PageScroller.prototype.scrollSelectorIntoView = function(baseElement,selector,callback) {
PageScroller.prototype.scrollSelectorIntoView = function(baseElement,selector,callback,options) {
baseElement = baseElement || document.body;
var element = baseElement.querySelector(selector);
if(element) {
this.scrollIntoView(element,callback);
this.scrollIntoView(element,callback,options);
}
};

View File

@@ -30,11 +30,7 @@ exports.getEditionInfo = function() {
var entry = entries[entryIndex];
// Check if directories have a valid tiddlywiki.info
if(!editionInfo[entry] && $tw.utils.isDirectory(path.resolve(editionPath,entry))) {
var info;
try {
info = JSON.parse(fs.readFileSync(path.resolve(editionPath,entry,"tiddlywiki.info"),"utf8"));
} catch(ex) {
}
var info = $tw.utils.parseJSONSafe(fs.readFileSync(path.resolve(editionPath,entry,"tiddlywiki.info"),"utf8"),null);
if(info) {
editionInfo[entry] = info;
}

View File

@@ -24,10 +24,8 @@ exports.repackPlugin = function(title,additionalTiddlers,excludeTiddlers) {
throw "No such tiddler as " + title;
}
// Extract the JSON
var jsonPluginTiddler;
try {
jsonPluginTiddler = JSON.parse(pluginTiddler.fields.text);
} catch(e) {
var jsonPluginTiddler = $tw.utils.parseJSONSafe(pluginTiddler.fields.text,null);
if(!jsonPluginTiddler) {
throw "Cannot parse plugin tiddler " + title + "\n" + $tw.language.getString("Error/Caption") + ": " + e;
}
// Get the list of tiddlers

View File

@@ -71,8 +71,8 @@ ActionListopsWidget.prototype.invokeAction = function(triggeringWidget,
}
if(this.subfilter) {
var inputList = this.wiki.getTiddlerList(this.target,field,index),
subfilter = $tw.utils.stringifyList(inputList) + " " + this.subfilter;
this.wiki.setText(this.target, field, index, $tw.utils.stringifyList(this.wiki.filterTiddlers(subfilter,this)));
subfilter = "[all[]] " + this.subfilter;
this.wiki.setText(this.target, field, index, $tw.utils.stringifyList(this.wiki.filterTiddlers(subfilter,this,this.wiki.makeTiddlerIterator(inputList))));
}
if(this.filtertags) {
var tiddler = this.wiki.getTiddler(this.target),

View File

@@ -247,7 +247,7 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
*/
ButtonWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(changedAttributes.actions || changedAttributes.to || changedAttributes.message || changedAttributes.param || changedAttributes.set || changedAttributes.setTo || changedAttributes.popup || changedAttributes.hover || changedAttributes.selectedClass || changedAttributes.style || changedAttributes.dragFilter || changedAttributes.dragTiddler || (this.set && changedTiddlers[this.set]) || (this.popup && changedTiddlers[this.popup]) || (this.popupTitle && changedTiddlers[this.popupTitle]) || changedAttributes.setTitle || changedAttributes.setField || changedAttributes.setIndex || changedAttributes.popupTitle || changedAttributes.disabled) {
if(changedAttributes.actions || changedAttributes.to || changedAttributes.message || changedAttributes.param || changedAttributes.set || changedAttributes.setTo || changedAttributes.popup || changedAttributes.hover || changedAttributes.selectedClass || changedAttributes.style || changedAttributes.dragFilter || changedAttributes.dragTiddler || (this.set && changedTiddlers[this.set]) || (this.popup && changedTiddlers[this.popup]) || (this.popupTitle && changedTiddlers[this.popupTitle]) || changedAttributes.setTitle || changedAttributes.setField || changedAttributes.setIndex || changedAttributes.popupTitle || changedAttributes.disabled || changedAttributes["default"]) {
this.refreshSelf();
return true;
} else if(changedAttributes["class"]) {

View File

@@ -27,7 +27,10 @@ DraggableWidget.prototype = new Widget();
Render this widget into the DOM
*/
DraggableWidget.prototype.render = function(parent,nextSibling) {
var self = this;
var self = this,
tag,
domNode,
classes = [];
// Save the parent dom node
this.parentDomNode = parent;
// Compute our attributes
@@ -35,18 +38,23 @@ DraggableWidget.prototype.render = function(parent,nextSibling) {
// Execute our logic
this.execute();
// Sanitise the specified tag
var tag = this.draggableTag;
tag = this.draggableTag;
if($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {
tag = "div";
}
// Create our element
var domNode = this.document.createElement(tag);
domNode = this.document.createElement(tag);
// Assign classes
var classes = ["tc-draggable"];
if(this.draggableClasses) {
classes.push(this.draggableClasses);
}
if(!this.dragHandleSelector) {
classes.push("tc-draggable");
}
domNode.setAttribute("class",classes.join(" "));
// Insert the node into the DOM and render any children
parent.insertBefore(domNode,nextSibling);
this.renderChildren(domNode,null);
// Add event handlers
$tw.utils.makeDraggable({
domNode: domNode,
@@ -55,11 +63,9 @@ DraggableWidget.prototype.render = function(parent,nextSibling) {
startActions: self.startActions,
endActions: self.endActions,
dragImageType: self.dragImageType,
widget: this
widget: this,
selector: self.dragHandleSelector
});
// Insert the link into the DOM and render any children
parent.insertBefore(domNode,nextSibling);
this.renderChildren(domNode,null);
this.domNodes.push(domNode);
};
@@ -72,7 +78,8 @@ DraggableWidget.prototype.execute = function() {
this.draggableClasses = this.getAttribute("class");
this.startActions = this.getAttribute("startactions");
this.endActions = this.getAttribute("endactions");
this.dragImageType = this.getAttribute("dragimagetype");
this.dragImageType = this.getAttribute("dragimagetype");
this.dragHandleSelector = this.getAttribute("selector");
// Make the child widgets
this.makeChildWidgets();
};

View File

@@ -198,7 +198,8 @@ DropZoneWidget.prototype.handleDropEvent = function(event) {
this.resetState();
// Import any files in the drop
var numFiles = 0;
if(dataTransfer.files) {
// If we have type text/vnd.tiddlywiki then skip trying to import files
if(dataTransfer.files && !$tw.utils.dragEventContainsType(event,"text/vnd.tiddler")) {
numFiles = this.wiki.readFiles(dataTransfer.files,{
callback: readFileCallback,
deserializer: this.dropzoneDeserializer

View File

@@ -46,6 +46,7 @@ EventWidget.prototype.render = function(parent,nextSibling) {
$tw.utils.each(this.types,function(type) {
domNode.addEventListener(type,function(event) {
var selector = self.getAttribute("selector"),
matchSelector = self.getAttribute("matchSelector"),
actions = self.getAttribute("$"+type) || self.getAttribute("actions-"+type),
stopPropagation = self.getAttribute("stopPropagation","onaction"),
selectedNode = event.target,
@@ -56,46 +57,49 @@ EventWidget.prototype.render = function(parent,nextSibling) {
if(selectedNode.nodeType === 3) {
selectedNode = selectedNode.parentNode;
}
// Check that the selected node matches any matchSelector
if(matchSelector && !$tw.utils.domMatchesSelector(selectedNode,matchSelector)) {
return false;
}
if(selector) {
// Search ancestors for a node that matches the selector
while(!$tw.utils.domMatchesSelector(selectedNode,selector) && selectedNode !== domNode) {
selectedNode = selectedNode.parentNode;
}
// If we found one, copy the attributes as variables, otherwise exit
if($tw.utils.domMatchesSelector(selectedNode,selector)) {
// Only set up variables if we have actions to invoke
if(actions) {
$tw.utils.each(selectedNode.attributes,function(attribute) {
variables["dom-" + attribute.name] = attribute.value.toString();
});
//Add a variable with a popup coordinate string for the selected node
variables["tv-popup-coords"] = "(" + selectedNode.offsetLeft + "," + selectedNode.offsetTop +"," + selectedNode.offsetWidth + "," + selectedNode.offsetHeight + ")";
//Add variables for offset of selected node
variables["tv-selectednode-posx"] = selectedNode.offsetLeft.toString();
variables["tv-selectednode-posy"] = selectedNode.offsetTop.toString();
variables["tv-selectednode-width"] = selectedNode.offsetWidth.toString();
variables["tv-selectednode-height"] = selectedNode.offsetHeight.toString();
if(event.clientX && event.clientY) {
//Add variables for event X and Y position relative to selected node
selectedNodeRect = selectedNode.getBoundingClientRect();
variables["event-fromselected-posx"] = (event.clientX - selectedNodeRect.left).toString();
variables["event-fromselected-posy"] = (event.clientY - selectedNodeRect.top).toString();
//Add variables for event X and Y position relative to event catcher node
catcherNodeRect = self.domNode.getBoundingClientRect();
variables["event-fromcatcher-posx"] = (event.clientX - catcherNodeRect.left).toString();
variables["event-fromcatcher-posy"] = (event.clientY - catcherNodeRect.top).toString();
//Add variables for event X and Y position relative to the viewport
variables["event-fromviewport-posx"] = event.clientX.toString();
variables["event-fromviewport-posy"] = event.clientY.toString();
}
}
} else {
// Exit if we didn't find one
if(selectedNode === domNode) {
return false;
}
// Only set up variables if we have actions to invoke
if(actions) {
$tw.utils.each(selectedNode.attributes,function(attribute) {
variables["dom-" + attribute.name] = attribute.value.toString();
});
//Add a variable with a popup coordinate string for the selected node
variables["tv-popup-coords"] = "(" + selectedNode.offsetLeft + "," + selectedNode.offsetTop +"," + selectedNode.offsetWidth + "," + selectedNode.offsetHeight + ")";
//Add variables for offset of selected node
variables["tv-selectednode-posx"] = selectedNode.offsetLeft.toString();
variables["tv-selectednode-posy"] = selectedNode.offsetTop.toString();
variables["tv-selectednode-width"] = selectedNode.offsetWidth.toString();
variables["tv-selectednode-height"] = selectedNode.offsetHeight.toString();
if(event.clientX && event.clientY) {
//Add variables for event X and Y position relative to selected node
selectedNodeRect = selectedNode.getBoundingClientRect();
variables["event-fromselected-posx"] = (event.clientX - selectedNodeRect.left).toString();
variables["event-fromselected-posy"] = (event.clientY - selectedNodeRect.top).toString();
//Add variables for event X and Y position relative to event catcher node
catcherNodeRect = self.domNode.getBoundingClientRect();
variables["event-fromcatcher-posx"] = (event.clientX - catcherNodeRect.left).toString();
variables["event-fromcatcher-posy"] = (event.clientY - catcherNodeRect.top).toString();
//Add variables for event X and Y position relative to the viewport
variables["event-fromviewport-posx"] = event.clientX.toString();
variables["event-fromviewport-posy"] = event.clientY.toString();
}
}
}
// Execute our actions with the variables
if(actions) {

View File

@@ -111,6 +111,16 @@ ImageWidget.prototype.render = function(parent,nextSibling) {
if(this.imageAlt) {
domNode.setAttribute("alt",this.imageAlt);
}
// Add classes when the image loads or fails
$tw.utils.addClass(domNode,"tc-image-loading");
domNode.addEventListener("load",function() {
$tw.utils.removeClass(domNode,"tc-image-loading");
$tw.utils.addClass(domNode,"tc-image-loaded");
},false);
domNode.addEventListener("error",function() {
$tw.utils.removeClass(domNode,"tc-image-loading");
$tw.utils.addClass(domNode,"tc-image-error");
},false);
// Insert element
parent.insertBefore(domNode,nextSibling);
this.domNodes.push(domNode);

View File

@@ -46,7 +46,7 @@ ImportVariablesWidget.prototype.execute = function(tiddlerList) {
this.tiddlerList = tiddlerList || this.wiki.filterTiddlers(this.filter,this);
// Accumulate the <$set> widgets from each tiddler
$tw.utils.each(this.tiddlerList,function(title) {
var parser = widgetPointer.wiki.parseTiddler(title);
var parser = widgetPointer.wiki.parseTiddler(title,{parseAsInline:true});
if(parser) {
var parseTreeNode = parser.tree[0];
while(parseTreeNode && parseTreeNode.type === "set") {

View File

@@ -51,6 +51,9 @@ ListWidget.prototype.render = function(parent,nextSibling) {
} else {
this.storyview = null;
}
if(this.storyview && this.storyview.renderEnd) {
this.storyview.renderEnd();
}
};
/*

View File

@@ -44,8 +44,7 @@ NavigatorWidget.prototype.render = function(parent,nextSibling) {
{type: "tm-fold-tiddler", handler: "handleFoldTiddlerEvent"},
{type: "tm-fold-other-tiddlers", handler: "handleFoldOtherTiddlersEvent"},
{type: "tm-fold-all-tiddlers", handler: "handleFoldAllTiddlersEvent"},
{type: "tm-unfold-all-tiddlers", handler: "handleUnfoldAllTiddlersEvent"},
{type: "tm-rename-tiddler", handler: "handleRenameTiddlerEvent"}
{type: "tm-unfold-all-tiddlers", handler: "handleUnfoldAllTiddlersEvent"}
]);
this.parentDomNode = parent;
this.computeAttributes();
@@ -499,11 +498,7 @@ NavigatorWidget.prototype.handleNewTiddlerEvent = function(event) {
// Import JSON tiddlers into a pending import tiddler
NavigatorWidget.prototype.handleImportTiddlersEvent = function(event) {
// Get the tiddlers
var tiddlers = [];
try {
tiddlers = JSON.parse(event.param);
} catch(e) {
}
var tiddlers = $tw.utils.parseJSONSafe(event.param,[]);
// Get the current $:/Import tiddler
var importTitle = event.importTitle ? event.importTitle : IMPORT_TITLE,
importTiddler = this.wiki.getTiddler(importTitle),
@@ -636,16 +631,6 @@ NavigatorWidget.prototype.handleUnfoldAllTiddlersEvent = function(event) {
});
};
NavigatorWidget.prototype.handleRenameTiddlerEvent = function(event) {
var options = {},
paramObject = event.paramObject || {},
from = paramObject.from || event.tiddlerTitle,
to = paramObject.to;
options.dontRenameInTags = (paramObject.renameInTags === "false" || paramObject.renameInTags === "no") ? true : false;
options.dontRenameInLists = (paramObject.renameInLists === "false" || paramObject.renameInLists === "no") ? true : false;
this.wiki.renameTiddler(from,to,options);
};
exports.navigator = NavigatorWidget;
})();

View File

@@ -64,9 +64,9 @@ RadioWidget.prototype.getValue = function() {
tiddler = this.wiki.getTiddler(this.radioTitle);
if(tiddler) {
if(this.radioIndex) {
value = this.wiki.extractTiddlerDataItem(this.radioTitle,this.radioIndex);
value = this.wiki.extractTiddlerDataItem(this.radioTitle,this.radioIndex,this.radioDefault);
} else {
value = tiddler.getFieldString(this.radioField);
value = tiddler.getFieldString(this.radioField,this.radioDefault);
}
} else {
value = this.radioDefault;

View File

@@ -38,10 +38,14 @@ ScrollableWidget.prototype.handleScrollEvent = function(event) {
if(this.outerDomNode.scrollWidth <= this.outerDomNode.offsetWidth && this.outerDomNode.scrollHeight <= this.outerDomNode.offsetHeight && this.fallthrough === "yes") {
return true;
}
var options = {};
if($tw.utils.hop(event.paramObject,"animationDuration")) {
options.animationDuration = event.paramObject.animationDuration;
}
if(event.paramObject && event.paramObject.selector) {
this.scrollSelectorIntoView(null,event.paramObject.selector);
this.scrollSelectorIntoView(null,event.paramObject.selector,null,options);
} else {
this.scrollIntoView(event.target);
this.scrollIntoView(event.target,null,options);
}
return false; // Handled event
};
@@ -49,9 +53,9 @@ ScrollableWidget.prototype.handleScrollEvent = function(event) {
/*
Scroll an element into view
*/
ScrollableWidget.prototype.scrollIntoView = function(element) {
var duration = $tw.utils.getAnimationDuration(),
srcWindow = element ? element.ownerDocument.defaultView : window;
ScrollableWidget.prototype.scrollIntoView = function(element,callback,options) {
var duration = $tw.utils.hop(options,"animationDuration") ? parseInt(options.animationDuration) : $tw.utils.getAnimationDuration(),
srcWindow = element ? element.ownerDocument.defaultView : window;
this.cancelScroll();
this.startTime = Date.now();
var scrollPosition = {
@@ -114,11 +118,11 @@ ScrollableWidget.prototype.scrollIntoView = function(element) {
}
};
ScrollableWidget.prototype.scrollSelectorIntoView = function(baseElement,selector,callback) {
ScrollableWidget.prototype.scrollSelectorIntoView = function(baseElement,selector,callback,options) {
baseElement = baseElement || document.body;
var element = baseElement.querySelector(selector);
if(element) {
this.scrollIntoView(element,callback);
this.scrollIntoView(element,callback,options);
}
};
@@ -155,8 +159,6 @@ ScrollableWidget.prototype.render = function(parent,nextSibling) {
// Create elements
this.outerDomNode = this.document.createElement("div");
$tw.utils.setStyle(this.outerDomNode,[
{overflowY: "auto"},
{overflowX: "auto"},
{webkitOverflowScrolling: "touch"}
]);
this.innerDomNode = this.document.createElement("div");

View File

@@ -122,7 +122,7 @@ Widget.prototype.getVariableInfo = function(name,options) {
});
// Only substitute variable references if this variable was defined with the \define pragma
if(variable.isMacroDefinition) {
value = this.substituteVariableReferences(value);
value = this.substituteVariableReferences(value,options);
}
return {
text: value,
@@ -175,10 +175,10 @@ Widget.prototype.resolveVariableParameters = function(formalParams,actualParams)
return results;
};
Widget.prototype.substituteVariableReferences = function(text) {
Widget.prototype.substituteVariableReferences = function(text,options) {
var self = this;
return (text || "").replace(/\$\(([^\)\$]+)\)\$/g,function(match,p1,offset,string) {
return self.getVariable(p1,{defaultValue: ""});
return options.variables && options.variables[p1] || (self.getVariable(p1,{defaultValue: ""}));
});
};
@@ -314,24 +314,40 @@ excludeEventAttributes: ignores attributes whose name begins with "on"
Widget.prototype.assignAttributes = function(domNode,options) {
options = options || {};
var self = this;
$tw.utils.each(this.attributes,function(v,a) {
// Check exclusions
if(options.excludeEventAttributes && a.substr(0,2) === "on") {
v = undefined;
var assignAttribute = function(name,value) {
// Check for excluded attribute names
if(options.excludeEventAttributes && name.substr(0,2) === "on") {
value = undefined;
}
if(v !== undefined) {
var b = a.split(":");
// Setting certain attributes can cause a DOM error (eg xmlns on the svg element)
try {
if (b.length == 2 && b[0] == "xlink"){
domNode.setAttributeNS("http://www.w3.org/1999/xlink",b[1],v);
} else {
domNode.setAttributeNS(null,a,v);
if(value !== undefined) {
// Handle the xlink: namespace
var namespace = null;
if(name.substr(0,6) === "xlink:" && name.length > 6) {
namespace = "http://www.w3.org/1999/xlink";
name = name.substr(6);
}
// Handle styles
if(name.substr(0,6) === "style." && name.length > 6) {
domNode.style[$tw.utils.unHyphenateCss(name.substr(6))] = value;
} else {
// Setting certain attributes can cause a DOM error (eg xmlns on the svg element)
try {
domNode.setAttributeNS(namespace,name,value);
} catch(e) {
}
} catch(e) {
}
}
});
}
// Not all parse tree nodes have the orderedAttributes property
if(this.parseTreeNode.orderedAttributes) {
$tw.utils.each(this.parseTreeNode.orderedAttributes,function(attribute,index) {
assignAttribute(attribute.name,self.attributes[attribute.name]);
});
} else {
$tw.utils.each(Object.keys(self.attributes).sort(),function(name) {
assignAttribute(name,self.attributes[name]);
});
}
};
/*

View File

@@ -46,26 +46,31 @@ function relinkTiddler(fromTitle,toTitle,options) {
if(!tiddler.fields["plugin-type"] && type !== "application/javascript") {
var tags = tiddler.fields.tags ? tiddler.fields.tags.slice(0) : undefined,
list = tiddler.fields.list ? tiddler.fields.list.slice(0) : undefined,
isModified = false;
isModified = false,
processList = function(listField) {
if(listField && listField.indexOf(fromTitle) !== -1) {
// Remove any existing instances of the toTitle
var p = listField.indexOf(toTitle);
while(p !== -1) {
listField.splice(p,1);
p = listField.indexOf(toTitle);
}
// Replace the fromTitle with toTitle
$tw.utils.each(listField,function (title,index) {
if(title === fromTitle) {
listField[index] = toTitle;
isModified = true;
}
});
}
};
if(!options.dontRenameInTags) {
// Rename tags
$tw.utils.each(tags,function (title,index) {
if(title === fromTitle) {
console.log("Renaming tag '" + tags[index] + "' to '" + toTitle + "' of tiddler '" + tiddler.fields.title + "'");
tags[index] = toTitle;
isModified = true;
}
});
processList(tags);
}
if(!options.dontRenameInLists) {
// Rename lists
$tw.utils.each(list,function (title,index) {
if(title === fromTitle) {
console.log("Renaming list item '" + list[index] + "' to '" + toTitle + "' of tiddler '" + tiddler.fields.title + "'");
list[index] = toTitle;
isModified = true;
}
});
processList(list);
}
if(isModified) {
var newTiddler = new $tw.Tiddler(tiddler,{tags: tags, list: list},self.getModificationFields())

View File

@@ -639,14 +639,25 @@ Lookup a given tiddler and return a list of all the tiddlers that include it in
*/
exports.findListingsOfTiddler = function(targetTitle,fieldName) {
fieldName = fieldName || "list";
var titles = [];
this.each(function(tiddler,title) {
var list = $tw.utils.parseStringArray(tiddler.fields[fieldName]);
if(list && list.indexOf(targetTitle) !== -1) {
titles.push(title);
}
var wiki = this;
var listings = this.getGlobalCache("listings-" + fieldName,function() {
var listings = Object.create(null);
wiki.each(function(tiddler,title) {
var list = $tw.utils.parseStringArray(tiddler.fields[fieldName]);
if(list) {
for(var i = 0; i < list.length; i++) {
var listItem = list[i],
listing = listings[listItem] || [];
if (listing.indexOf(title) === -1) {
listing.push(title);
}
listings[listItem] = listing;
}
}
});
return listings;
});
return titles;
return listings[targetTitle] || [];
};
/*
@@ -822,12 +833,7 @@ exports.getTiddlerData = function(titleOrTiddler,defaultData) {
switch(tiddler.fields.type) {
case "application/json":
// JSON tiddler
try {
data = JSON.parse(tiddler.fields.text);
} catch(ex) {
return defaultData;
}
return data;
return $tw.utils.parseJSONSafe(tiddler.fields.text,defaultData);
case "application/x-tiddler-dictionary":
return $tw.utils.parseFields(tiddler.fields.text);
}
@@ -1201,23 +1207,28 @@ Return an array of tiddler titles that match a search string
text: The text string to search for
options: see below
Options available:
source: an iterator function for the source tiddlers, called source(iterator), where iterator is called as iterator(tiddler,title)
source: an iterator function for the source tiddlers, called source(iterator),
where iterator is called as iterator(tiddler,title)
exclude: An array of tiddler titles to exclude from the search
invert: If true returns tiddlers that do not contain the specified string
caseSensitive: If true forces a case sensitive search
field: If specified, restricts the search to the specified field, or an array of field names
anchored: If true, forces all but regexp searches to be anchored to the start of text
excludeField: If true, the field options are inverted to specify the fields that are not to be searched
The search mode is determined by the first of these boolean flags to be true
literal: searches for literal string
whitespace: same as literal except runs of whitespace are treated as a single space
regexp: treats the search term as a regular expression
words: (default) treats search string as a list of tokens, and matches if all tokens are found, regardless of adjacency or ordering
words: (default) treats search string as a list of tokens, and matches if all tokens are found,
regardless of adjacency or ordering
some: treats search string as a list of tokens, and matches if at least ONE token is found
*/
exports.search = function(text,options) {
options = options || {};
var self = this,
t,
regExpStr="",
invert = !!options.invert;
// Convert the search string into a regexp for each term
var terms, searchTermsRegExps,
@@ -1244,7 +1255,18 @@ exports.search = function(text,options) {
searchTermsRegExps = null;
console.log("Regexp error parsing /(" + text + ")/" + flags + ": ",e);
}
} else {
} else if(options.some) {
terms = text.trim().split(/ +/);
if(terms.length === 1 && terms[0] === "") {
searchTermsRegExps = null;
} else {
searchTermsRegExps = [];
for(t=0; t<terms.length; t++) {
regExpStr += (t===0) ? anchor + $tw.utils.escapeRegExp(terms[t]) : "|" + anchor + $tw.utils.escapeRegExp(terms[t]);
}
searchTermsRegExps.push(new RegExp("(" + regExpStr + ")",flags));
}
} else { // default: words
terms = text.split(/ +/);
if(terms.length === 1 && terms[0] === "") {
searchTermsRegExps = null;
@@ -1255,7 +1277,7 @@ exports.search = function(text,options) {
}
}
}
// Accumulate the array of fields to be searched or excluded from the search
// Accumulate the array of fields to be searched or excluded from the search
var fields = [];
if(options.field) {
if($tw.utils.isArray(options.field)) {

View File

@@ -6,7 +6,7 @@ title: $:/core/templates/tiddlywiki5.html
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<!--~~ Raw markup for the top of the head section ~~-->
`{{{ [<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified/TopHead]] ||$:/core/templates/raw-static-tiddler}}}`
`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified/TopHead]] ||$:/core/templates/raw-static-tiddler}}}`
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
<meta name="application-name" content="TiddlyWiki" />
<meta name="generator" content="TiddlyWiki" />

View File

@@ -1,7 +1,7 @@
title: $:/core/ui/Components/tag-link
<$link>
<$set name="backgroundColor" value={{!!color}}>
<$set name="backgroundColor" value={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}>
<span style=<<tag-styles>> class="tc-tag-label">
<$view field="title" format="text"/>
</span>

View File

@@ -1,5 +1,5 @@
title: $:/core/ui/ControlPanel/EditTemplateBody
tags: $:/tags/ControlPanel/Cascade
tags: $:/tags/ControlPanel/Cascades
caption: {{$:/language/ControlPanel/EditTemplateBody/Caption}}
\define lingo-base() $:/language/ControlPanel/EditTemplateBody/

View File

@@ -0,0 +1,9 @@
title: $:/core/ui/ControlPanel/FieldEditor
tags: $:/tags/ControlPanel/Cascades
caption: {{$:/language/ControlPanel/FieldEditor/Caption}}
\define lingo-base() $:/language/ControlPanel/FieldEditor/
<<lingo Hint>>
{{$:/tags/FieldEditorFilter||$:/snippets/ListTaggedCascade}}

View File

@@ -0,0 +1,9 @@
title: $:/core/ui/ControlPanel/TiddlerColour
tags: $:/tags/ControlPanel/Cascades
caption: {{$:/language/ControlPanel/TiddlerColour/Caption}}
\define lingo-base() $:/language/ControlPanel/TiddlerColour/
<<lingo Hint>>
{{$:/tags/TiddlerColourFilter||$:/snippets/ListTaggedCascade}}

View File

@@ -14,8 +14,8 @@ title: $:/core/ui/EditTemplate
<div data-tiddler-title=<<currentTiddler>> data-tags={{!!tags}} class={{{ tc-tiddler-frame tc-tiddler-edit-frame [<currentTiddler>is[tiddler]then[tc-tiddler-exists]] [<currentTiddler>is[missing]!is[shadow]then[tc-tiddler-missing]] [<currentTiddler>is[shadow]then[tc-tiddler-exists tc-tiddler-shadow]] [<currentTiddler>is[system]then[tc-tiddler-system]] [{!!class}] [<currentTiddler>tags[]encodeuricomponent[]addprefix[tc-tagged-]] +[join[ ]] }}}>
<$fieldmangler>
<$vars storyTiddler=<<currentTiddler>> newTagNameTiddler=<<qualify "$:/temp/NewTagName">> newFieldNameTiddler=<<qualify "$:/temp/NewFieldName">> newFieldValueTiddler=<<qualify "$:/temp/NewFieldValue">> newFieldNameInputTiddler=<<qualify "$:/temp/NewFieldName/input">> newFieldNameSelectionTiddler=<<qualify "$:/temp/NewFieldName/selected-item">> newTagNameInputTiddler=<<qualify "$:/temp/NewTagName/input">> newTagNameSelectionTiddler=<<qualify "$:/temp/NewTagName/selected-item">> typeInputTiddler=<<qualify "$:/temp/Type/input">> typeSelectionTiddler=<<qualify "$:/temp/Type/selected-item">>>
<$keyboard key="((cancel-edit-tiddler))" actions=<<cancel-delete-tiddler-actions "cancel">>>
<$keyboard key="((save-tiddler))" actions=<<save-tiddler-actions>>>
<$keyboard key="((cancel-edit-tiddler))" actions=<<cancel-delete-tiddler-actions "cancel">> tag="div">
<$keyboard key="((save-tiddler))" actions=<<save-tiddler-actions>> tag="div">
<$list filter="[all[shadows+tiddlers]tag[$:/tags/EditTemplate]!has[draft.of]]" variable="listItem">
<$set name="tv-config-toolbar-class" filter="[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]">
<$transclude tiddler=<<listItem>>/>

View File

@@ -1,4 +1,4 @@
title: $:/core/ui/EditTemplate/body
tags: $:/tags/EditTemplate
<$transclude tiddler={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/EditTemplateBodyFilter]get[text]] :and[!is[blank]else[$:/core/ui/EditTemplate/body/default]] }}} />
<$transclude tiddler={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/EditTemplateBodyFilter]!is[draft]get[text]] :and[!is[blank]else[$:/core/ui/EditTemplate/body/default]] }}} />

View File

@@ -10,7 +10,7 @@ $:/config/EditorToolbarButtons/Visibility/$(currentTiddler)$
<$set name="edit-preview-state" value={{{ [{$:/config/ShowEditPreview/PerTiddler}!match[yes]then[$:/state/showeditpreview]] :else[<qualify "$:/state/showeditpreview">] }}}>
<$vars importTitle=<<qualify $:/ImportImage>> importState=<<qualify $:/state/ImportImage>> >
<$dropzone importTitle=<<importTitle>> autoOpenOnImport="no" contentTypesFilter={{$:/config/Editor/ImportContentTypesFilter}} class="tc-dropzone-editor" enable={{{ [{$:/config/DragAndDrop/Enable}match[no]] :else[subfilter{$:/config/Editor/EnableImportFilter}then[yes]else[no]] }}} filesOnly="yes" actions=<<importFileActions>> ><$reveal stateTitle=<<edit-preview-state>> type="match" text="yes">
<$dropzone importTitle=<<importTitle>> autoOpenOnImport="no" contentTypesFilter={{$:/config/Editor/ImportContentTypesFilter}} class="tc-dropzone-editor" enable={{{ [{$:/config/DragAndDrop/Enable}match[no]] :else[subfilter{$:/config/Editor/EnableImportFilter}then[yes]else[no]] }}} filesOnly="yes" actions=<<importFileActions>> ><$reveal stateTitle=<<edit-preview-state>> type="match" text="yes" tag="div">
<div class="tc-tiddler-preview">
<$transclude tiddler="$:/core/ui/EditTemplate/body/editor" mode="inline"/>
@@ -28,7 +28,7 @@ $:/config/EditorToolbarButtons/Visibility/$(currentTiddler)$
</div>
</$reveal>
<$reveal stateTitle=<<edit-preview-state>> type="nomatch" text="yes">
<$reveal stateTitle=<<edit-preview-state>> type="nomatch" text="yes" tag="div">
<$transclude tiddler="$:/core/ui/EditTemplate/body/editor" mode="inline"/>

View File

@@ -0,0 +1,3 @@
title: $:/core/ui/EditTemplate/fieldEditor/default
<$edit-text tiddler=<<currentTiddler>> field=<<currentField>> default="" class="tc-edit-texteditor" placeholder={{$:/language/EditTemplate/Fields/Add/Value/Placeholder}} tabindex={{$:/config/EditTabIndex}} cancelPopups="yes"/>

View File

@@ -15,7 +15,7 @@ $:/config/EditTemplateFields/Visibility/$(currentField)$
\end
\define new-field-actions()
<$action-sendmessage $message="tm-add-field" $name={{{ [<newFieldNameTiddler>get[text]] }}} $value={{{ [<newFieldValueTiddler>get[text]] }}}/>
<$action-sendmessage $message="tm-add-field" $name={{{ [<newFieldNameTiddler>get[text]] }}} $value={{{ [<newFieldNameTiddler>get[text]] :map[<newFieldValueTiddler>get<currentTiddler>] }}}/>
<$action-deletetiddler $filter="[<newFieldNameTiddler>] [<newFieldValueTiddler>] [<storeTitle>] [<searchListState>]"/>
<$action-sendmessage $message="tm-focus-selector" $param=<<current-tiddler-new-field-selector>>/>
\end
@@ -42,7 +42,7 @@ $:/config/EditTemplateFields/Visibility/$(currentField)$
<$button tooltip=<<lingo Fields/Add/Button/Hint>>>
<$action-sendmessage $message="tm-add-field"
$name=<<name>>
$value={{{ [<newFieldValueTiddler>get[text]] }}}/>
$value={{{ [<newFieldValueTiddler>get<name>] }}}/>
<$action-deletetiddler $filter="[<newFieldNameTiddler>] [<newFieldValueTiddler>] [<storeTitle>] [<searchListState>]"/>
<<lingo Fields/Add/Button>>
</$button>
@@ -66,7 +66,7 @@ $value={{{ [<newFieldValueTiddler>get[text]] }}}/>
<$text text=<<currentField>>/>:</td>
<td class="tc-edit-field-value">
<$keyboard key="((delete-field))" actions="""<$action-deletefield $field=<<currentField>>/><$set name="currentTiddlerCSSescaped" value={{{ [<currentTiddler>escapecss[]] }}}><$action-sendmessage $message="tm-focus-selector" $param=<<current-tiddler-new-field-selector>>/></$set>""">
<$edit-text tiddler=<<currentTiddler>> field=<<currentField>> placeholder={{$:/language/EditTemplate/Fields/Add/Value/Placeholder}} tabindex={{$:/config/EditTabIndex}} cancelPopups="yes"/>
<$transclude tiddler={{{ [<currentField>] :cascade[all[shadows+tiddlers]tag[$:/tags/FieldEditorFilter]!is[draft]get[text]] :and[!is[blank]else{$:/core/ui/EditTemplate/fieldEditor/default}] }}} />
</$keyboard>
</td>
<td class="tc-edit-field-remove">
@@ -126,16 +126,18 @@ $value={{{ [<newFieldValueTiddler>get[text]] }}}/>
</div>
</$reveal>
</div>
<$let currentTiddler=<<newFieldValueTiddler>> currentField={{{ [<newFieldNameTiddler>get[text]] }}}>
<span class="tc-edit-field-add-value tc-small-gap-right">
<$set name="currentTiddlerCSSescaped" value={{{ [<currentTiddler>escapecss[]] }}}>
<$keyboard key="((add-field))" actions=<<new-field-actions>>>
<$edit-text tiddler=<<newFieldValueTiddler>> tag="input" default="" placeholder={{$:/language/EditTemplate/Fields/Add/Value/Placeholder}} class="tc-edit-texteditor" tabindex={{$:/config/EditTabIndex}} cancelPopups="yes"/>
<$transclude tiddler={{{ [<currentField>] :cascade[all[shadows+tiddlers]tag[$:/tags/FieldEditorFilter]!is[draft]get[text]] :and[!is[blank]else{$:/core/ui/EditTemplate/fieldEditor/default}] }}} />
</$keyboard>
</$set>
</span>
<span class="tc-edit-field-add-button">
<$macrocall $name="new-field"/>
</span>
</$let>
</$vars>
</div>
</$fieldmangler>

View File

@@ -29,7 +29,7 @@ color:$(foregroundColor)$;
\whitespace trim
<div class="tc-edit-tags">
<$list filter="[list[!!$tagField$]sort[title]]" storyview="pop">
<$macrocall $name="tag-body" colour={{!!color}} palette={{$:/palette}} icon={{!!icon}} tagField=<<__tagField__>>/>
<$macrocall $name="tag-body" colour={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}} palette={{$:/palette}} icon={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]!is[draft]get[text]] }}} tagField=<<__tagField__>>/>
</$list>
<$vars tabIndex={{$:/config/EditTabIndex}} cancelPopups="yes">
<$macrocall $name="tag-picker" tagField=<<__tagField__>>/>

View File

@@ -23,7 +23,7 @@ first-search-filter: [all[shadows+tiddlers]prefix[$:/language/Docs/Types/]sort[d
<$text text={{!!group}}/>
</div>
<$set name="userInput" value={{{ [<typeInputTiddler>get[text]] }}}>
<$list filter="[all[shadows+tiddlers]prefix[$:/language/Docs/Types/]group{!!group}] +[sort[description]] +[removeprefix[$:/language/Docs/Types/]] +[search<userInput>]"><span class={{{ [<currentTiddler>addsuffix[-primaryList]] -[<typeSelectionTiddler>get[text]] +[then[]else[tc-list-item-selected]] }}}><$link to={{{ [<currentTiddler>addprefix[$:/language/Docs/Types/]get[name]] }}}><$view tiddler={{{ [<currentTiddler>addprefix[$:/language/Docs/Types/]] }}} field="description"/> (<$view tiddler={{{ [<currentTiddler>addprefix[$:/language/Docs/Types/]] }}} field="name"/>)</$link></span>
<$list filter="[all[shadows+tiddlers]prefix[$:/language/Docs/Types/]group{!!group}] +[sort[description]] +[removeprefix[$:/language/Docs/Types/]] +[search<userInput>]"><span class={{{ [<currentTiddler>addsuffix[-primaryList]] -[<typeSelectionTiddler>get[text]] +[then[]else[tc-list-item-selected]] }}}><$link to={{{ [<currentTiddler>addprefix[$:/language/Docs/Types/]get[name]] }}}><$view tiddler={{{ [<currentTiddler>addprefix[$:/language/Docs/Types/]] }}} field="description"/><$text text=" "/>(<$view tiddler={{{ [<currentTiddler>addprefix[$:/language/Docs/Types/]] }}} field="name"/>)</$link></span>
</$list>
</$set>
</$list>

View File

@@ -2,4 +2,4 @@ title: $:/core/ui/MoreSideBar/Plugins/Languages
tags: $:/tags/MoreSideBar/Plugins
caption: {{$:/language/ControlPanel/Plugins/Languages/Caption}}
<$list filter="[!has[draft.of]plugin-type[language]sort[description]]" template="$:/core/ui/PluginListItemTemplate" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}/>
<$list filter="[!has[draft.of]plugin-type[language]sort[name]]" template="$:/core/ui/PluginListItemTemplate" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}/>

View File

@@ -2,4 +2,4 @@ title: $:/core/ui/MoreSideBar/Plugins/Plugins
tags: $:/tags/MoreSideBar/Plugins
caption: {{$:/language/ControlPanel/Plugins/Plugins/Caption}}
<$list filter="[!has[draft.of]plugin-type[plugin]sort[description]]" template="$:/core/ui/PluginListItemTemplate" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}>>/>
<$list filter="[!has[draft.of]plugin-type[plugin]sort[name]]" template="$:/core/ui/PluginListItemTemplate" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}>>/>

View File

@@ -2,4 +2,4 @@ title: $:/core/ui/MoreSideBar/Plugins/Theme
tags: $:/tags/MoreSideBar/Plugins
caption: {{$:/language/ControlPanel/Plugins/Themes/Caption}}
<$list filter="[!has[draft.of]plugin-type[theme]sort[description]]" template="$:/core/ui/PluginListItemTemplate" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}/>
<$list filter="[!has[draft.of]plugin-type[theme]sort[name]]" template="$:/core/ui/PluginListItemTemplate" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}/>

View File

@@ -1,5 +1,15 @@
title: $:/core/ui/PluginListItemTemplate
<div class="tc-menu-list-item">
<$link to={{!!title}}><$view field="description"><$view field="title"/></$view></$link>
</div>
\whitespace trim
<$link to={{!!title}} class="tc-plugin-info">
<div class="tc-plugin-info-chunk tc-plugin-info-icon">
<$transclude tiddler=<<currentTiddler>> subtiddler={{{ [<currentTiddler>addsuffix[/icon]] }}}>
<$transclude tiddler={{{ [<currentTiddler>get[plugin-type]addprefix[$:/core/images/plugin-generic-]] }}}/>
</$transclude>
</div>
<div class="tc-plugin-info-chunk tc-plugin-info-description">
<h1>
''<$text text={{{ [<currentTiddler>get[name]] ~[<currentTiddler>split[/]last[1]] }}}/>'':&nbsp;<$view field="description"><$view field="title"/></$view>
</h1>
</div>
</$link>

View File

@@ -6,7 +6,7 @@ caption: {{$:/language/SideBar/Open/Caption}}
\define lingo-base() $:/language/CloseAll/
\define drop-actions()
<$action-listops $tiddler=<<tv-story-list>> $subfilter="+[insertbefore:currentTiddler<actionTiddler>]"/>
<$action-listops $tiddler=<<tv-story-list>> $subfilter="+[insertbefore<actionTiddler>,<currentTiddler>]"/>
\end
\define placeholder()
@@ -15,7 +15,7 @@ caption: {{$:/language/SideBar/Open/Caption}}
\define droppable-item(button)
\whitespace trim
<$droppable actions=<<drop-actions>> enable=<<tv-allow-drag-and-drop>>>
<$droppable actions=<<drop-actions>> enable=<<tv-allow-drag-and-drop>> tag="div">
<<placeholder>>
<div>
$button$

View File

@@ -1,3 +1,3 @@
title: $:/core/ui/StoryTiddlerTemplate
<$transclude tiddler={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/StoryTiddlerTemplateFilter]get[text]] :and[!is[blank]else{$:/config/ui/ViewTemplate}] }}} />
<$transclude tiddler={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/StoryTiddlerTemplateFilter]!is[draft]get[text]] :and[!is[blank]else{$:/config/ui/ViewTemplate}] }}} />

View File

@@ -13,8 +13,8 @@ title: $:/core/ui/TagPickerTagTemplate
<$action-setfield $tiddler=<<refreshTitle>> text="yes"/>
</$list>
<<actions>>
<$set name="backgroundColor" value={{!!color}}>
<$wikify name="foregroundColor" text="""<$macrocall $name="contrastcolour" target={{!!color}} fallbackTarget=<<fallbackTarget>> colourA=<<colourA>> colourB=<<colourB>>/>""">
<$set name="backgroundColor" value={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}>
<$wikify name="foregroundColor" text="""<$macrocall $name="contrastcolour" target=<<backgroundColor>> fallbackTarget=<<fallbackTarget>> colourA=<<colourA>> colourB=<<colourB>>/>""">
<span class="tc-tag-label tc-btn-invisible" style=<<tag-pill-styles>>>
{{||$:/core/ui/TiddlerIcon}}<$view field="title" format="text"/>
</span>

View File

@@ -3,7 +3,7 @@ title: $:/core/ui/TagTemplate
\whitespace trim
<span class="tc-tag-list-item" data-tag-title=<<currentTiddler>>>
<$set name="transclusion" value=<<currentTiddler>>>
<$macrocall $name="tag-pill-body" tag=<<currentTiddler>> colour={{!!color}} palette={{$:/palette}} element-tag="""$button""" element-attributes="""popup=<<qualify "$:/state/popup/tag">> dragFilter='[all[current]tagging[]]' tag='span'"""/>
<$macrocall $name="tag-pill-body" tag=<<currentTiddler>> icon={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]!is[draft]get[text]] }}} colour={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}} palette={{$:/palette}} element-tag="""$button""" element-attributes="""popup=<<qualify "$:/state/popup/tag">> dragFilter='[all[current]tagging[]]' tag='span'"""/>
<$reveal state=<<qualify "$:/state/popup/tag">> type="popup" position="below" animate="yes" class="tc-drop-down">
<$set name="tv-show-missing-links" value="yes">
<$transclude tiddler="$:/core/ui/ListItemTemplate"/>

View File

@@ -1,15 +1,8 @@
title: $:/core/ui/TiddlerIcon
\whitespace trim
\define title-styles()
fill:$(foregroundColor)$;
\end
<$let tiddlerIcon={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]get[text]] }}}>
<$let tiddlerIcon={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]!is[draft]get[text]] }}}>
<$list filter="[<tiddlerIcon>!is[blank]]" variable="ignore">
<$let foregroundColor={{!!color}}>
<span class=<<iconSpanClass>> style=<<title-styles>>>
<$transclude tiddler=<<tiddlerIcon>>/>
</span>
</$let>
</$list>
</$let>

View File

@@ -3,6 +3,6 @@ tags: $:/tags/ViewTemplate
<$reveal tag="div" class="tc-tiddler-body" type="nomatch" stateTitle=<<folded-state>> text="hide" retain="yes" animate="yes">
<$transclude tiddler={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/ViewTemplateBodyFilter]get[text]] :and[!is[blank]else[$:/core/ui/ViewTemplate/body/default]] }}} />
<$transclude tiddler={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/ViewTemplateBodyFilter]!is[draft]get[text]] :and[!is[blank]else[$:/core/ui/ViewTemplate/body/default]] }}} />
</$reveal>

View File

@@ -2,6 +2,9 @@ title: $:/core/ui/ViewTemplate/title
tags: $:/tags/ViewTemplate
\whitespace trim
\define title-styles()
fill:$(foregroundColor)$;
\end
<div class="tc-tiddler-title">
<div class="tc-titlebar">
<span class="tc-tiddler-controls">
@@ -9,10 +12,12 @@ tags: $:/tags/ViewTemplate
</span>
<$set name="tv-wikilinks" value={{$:/config/Tiddlers/TitleLinks}}>
<$link>
<$let iconSpanClass="tc-tiddler-title-icon">
<$let foregroundColor={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}>
<span class="tc-tiddler-title-icon" style=<<title-styles>>>
{{||$:/core/ui/TiddlerIcon}}
</span>
</$let>
<$transclude tiddler={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/ViewTemplateTitleFilter]get[text]] :and[!is[blank]else[$:/core/ui/ViewTemplate/title/default]] }}} />
<$transclude tiddler={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/ViewTemplateTitleFilter]!is[draft]get[text]] :and[!is[blank]else[$:/core/ui/ViewTemplate/title/default]] }}} />
</$link>
</$set>
</div>

View File

@@ -1,7 +1,7 @@
title: $:/snippets/allfields
\define renderfield(title)
<tr class="tc-view-field"><td class="tc-view-field-name">''$title$'':</td><td class="tc-view-field-value">//{{$:/language/Docs/Fields/$title$}}//</td></tr>
<tr class="tc-view-field"><td class="tc-view-field-name">''<$text text=<<__title__>>/>'':</td><td class="tc-view-field-value">//{{$:/language/Docs/Fields/$title$}}//</td></tr>
\end
<table class="tc-view-field-table"><tbody><$list filter="[fields[]sort[title]]" variable="listItem"><$macrocall $name="renderfield" title=<<listItem>>/></$list>
</tbody></table>

View File

@@ -0,0 +1,4 @@
title: $:/config/FieldEditorFilters/
tags: $:/tags/FieldEditorFilter
default: [[$:/core/ui/EditTemplate/fieldEditor/default]]

View File

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

View File

@@ -0,0 +1,5 @@
title: $:/config/TiddlerColourFilters/
tags: $:/tags/TiddlerColourFilter
color-field: [has[color]then{!!color}]
default: [[$:/config/DefaultTiddlerColour]has[text]get[text]trim[]]

View File

@@ -1,7 +1,8 @@
title: $:/config/ViewTemplateBodyFilters/
tags: $:/tags/ViewTemplateBodyFilter
system: [prefix[$:/boot/]] [prefix[$:/config/]] [prefix[$:/core/]!field:title[$:/core/readme]!field:title[$:/core/icon]] [prefix[$:/info/]] [prefix[$:/language/]] [prefix[$:/languages/]] [prefix[$:/snippets/]] [prefix[$:/state/]] [prefix[$:/status/]] [prefix[$:/info/]] [prefix[$:/temp/]] +[limit[1]then[$:/core/ui/ViewTemplate/body/code]]
system: [prefix[$:/boot/]] [prefix[$:/config/]] [prefix[$:/core/macros]] [prefix[$:/core/save/]] [prefix[$:/core/templates/]] [prefix[$:/core/ui/]split[/]count[]compare:number:eq[4]] [prefix[$:/info/]] [prefix[$:/language/]] [prefix[$:/languages/]] [prefix[$:/snippets/]] [prefix[$:/state/]] [prefix[$:/status/]] [prefix[$:/info/]] [prefix[$:/temp/]] +[limit[1]then[$:/core/ui/ViewTemplate/body/code]]
code-body: [field:code-body[yes]then[$:/core/ui/ViewTemplate/body/code]]
import: [field:plugin-type[import]then[$:/core/ui/ViewTemplate/body/import]]
plugin: [has[plugin-type]then[$:/core/ui/ViewTemplate/body/plugin]]
hide-body: [field:hide-body[yes]then[$:/core/ui/ViewTemplate/body/blank]]

View File

@@ -0,0 +1,9 @@
title: $:/snippets/DebugStylesheets
<style>[test]{list-style:'❌'}</style>
<ul>
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Stylesheet]has[modified]]" counter="n">
<style>{{!!text}}[test="<<n>>"]{list-style:disc;}</style>
<li test=<<n>>><$link/></li>
</$list>
</ul>

View File

@@ -17,7 +17,7 @@ tags: $:/tags/Macro
\end
\define list-links-draggable-drop-actions()
<$action-listops $tiddler=<<targetTiddler>> $field=<<targetField>> $subfilter="+[insertbefore:currentTiddler<actionTiddler>]"/>
<$action-listops $tiddler=<<targetTiddler>> $field=<<targetField>> $subfilter="+[insertbefore<actionTiddler>,<currentTiddler>]"/>
\end
\define list-links-draggable(tiddler,field:"list",type:"ul",subtype:"li",class:"",itemTemplate)
@@ -61,7 +61,7 @@ tags: $:/tags/Macro
<$action-deletefield $field="list-after"/>
</$list>
<!-- Save the new order to the Tag Tiddler -->
<$action-listops $tiddler=<<__tag__>> $field="list" $filter="+[enlist<order>] +[insertbefore:currentTiddler<actionTiddler>]"/>
<$action-listops $tiddler=<<__tag__>> $field="list" $filter="+[enlist<order>] +[insertbefore<actionTiddler>,<currentTiddler>]"/>
<!-- Make sure the newly added item has the right tag -->
<!-- Removing this line makes dragging tags within the dropdown work as intended -->
<!--<$action-listops $tiddler=<<actionTiddler>> $tags=<<__tag__>>/>-->

View File

@@ -10,18 +10,20 @@ color:$(foregroundColor)$;
\define tag-pill-inner(tag,icon,colour,fallbackTarget,colourA,colourB,element-tag,element-attributes,actions)
<$vars foregroundColor=<<contrastcolour target:"""$colour$""" fallbackTarget:"""$fallbackTarget$""" colourA:"""$colourA$""" colourB:"""$colourB$""">> backgroundColor="""$colour$""">
<$element-tag$ $element-attributes$ class="tc-tag-label tc-btn-invisible" style=<<tag-pill-styles>>>
$actions${{||$:/core/ui/TiddlerIcon}}<$view tiddler=<<__tag__>> field="title" format="text" />
$actions$<$transclude tiddler="""$icon$"""/><$view tiddler=<<__tag__>> field="title" format="text" />
</$element-tag$>
</$vars>
\end
\define tag-pill-body(tag,icon,colour,palette,element-tag,element-attributes,actions)
<$macrocall $name="tag-pill-inner" tag=<<__tag__>> colour="""$colour$""" fallbackTarget={{$palette$##tag-background}} colourA={{$palette$##foreground}} colourB={{$palette$##background}} element-tag="""$element-tag$""" element-attributes="""$element-attributes$""" actions="""$actions$"""/>
<$macrocall $name="tag-pill-inner" tag=<<__tag__>> icon="""$icon$""" colour="""$colour$""" fallbackTarget={{$palette$##tag-background}} colourA={{$palette$##foreground}} colourB={{$palette$##background}} element-tag="""$element-tag$""" element-attributes="""$element-attributes$""" actions="""$actions$"""/>
\end
\define tag-pill(tag,element-tag:"span",element-attributes:"",actions:"")
<span class="tc-tag-list-item" data-tag-title=<<__tag__>>>
<$macrocall $name="tag-pill-body" tag=<<__tag__>> colour={{{ [<__tag__>get[color]] }}} palette={{$:/palette}} element-tag="""$element-tag$""" element-attributes="""$element-attributes$""" actions="""$actions$"""/>
<$let currentTiddler=<<__tag__>>>
<$macrocall $name="tag-pill-body" tag=<<__tag__>> icon={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]!is[draft]get[text]] }}} colour={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}} palette={{$:/palette}} element-tag="""$element-tag$""" element-attributes="""$element-attributes$""" actions="""$actions$"""/>
</$let>
</span>
\end

View File

@@ -1,6 +1,7 @@
title: $:/snippets/peek-stylesheets
\define expandable-stylesheets-list()
\whitespace trim
<ol>
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Stylesheet]!has[draft.of]]">
<$vars state=<<qualify "$:/state/peek-stylesheets/open/">>>
@@ -38,6 +39,7 @@ title: $:/snippets/peek-stylesheets
\end
\define stylesheets-list()
\whitespace trim
<ol>
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Stylesheet]!has[draft.of]]">
<li>
@@ -57,6 +59,7 @@ title: $:/snippets/peek-stylesheets
</$list>
</ol>
\end
\whitespace trim
<$vars modeState=<<qualify "$:/state/peek-stylesheets/mode/">>>

View File

@@ -0,0 +1,3 @@
title: $:/tags/TiddlerColourFilter
list: $:/config/TiddlerColourFilters/color-field $:/config/TiddlerColourFilters/default

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