mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2026-09-16 23:01:23 +00:00
Compare commits
353
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d0d28ab96 | ||
|
|
2b60da0dcf | ||
|
|
5d3f2685a3 | ||
|
|
685a80dfc6 | ||
|
|
3aec096a07 | ||
|
|
ddc59ee77b | ||
|
|
e0e6ab69b1 | ||
|
|
e4ce6b3433 | ||
|
|
47806feb85 | ||
|
|
5577a3d07b | ||
|
|
d62b75cceb | ||
|
|
30a51be168 | ||
|
|
38fa4486e4 | ||
|
|
d0a0198f49 | ||
|
|
52c60be3a0 | ||
|
|
b3279e348d | ||
|
|
516135e1b2 | ||
|
|
6845f1c47e | ||
|
|
6680967875 | ||
|
|
f9d5ee0ad7 | ||
|
|
68630c939d | ||
|
|
5e5937838b | ||
|
|
6c8ac9b6a7 | ||
|
|
0c60e1fa7a | ||
|
|
b40b6de3ae | ||
|
|
aac08a6252 | ||
|
|
40b353bd0e | ||
|
|
7efbd01801 | ||
|
|
5143138c16 | ||
|
|
251871f9cf | ||
|
|
8e65fdc06a | ||
|
|
ceb0817176 | ||
|
|
2f578589a0 | ||
|
|
916df90cc9 | ||
|
|
ea18c85a4c | ||
|
|
abf134afe4 | ||
|
|
45d2ca948a | ||
|
|
94b046b8cb | ||
|
|
c710a56b21 | ||
|
|
e681096127 | ||
|
|
24b433211d | ||
|
|
a64bbeaf52 | ||
|
|
9fecc7b1d9 | ||
|
|
2bc7826b5e | ||
|
|
d6174f0c46 | ||
|
|
c6c29ec68e | ||
|
|
fd96e5c8cb | ||
|
|
52a36c01ff | ||
|
|
002fd550a8 | ||
|
|
c1d9b07b20 | ||
|
|
187849a6a9 | ||
|
|
d5f8a04230 | ||
|
|
73ad4f633b | ||
|
|
ea549f6e26 | ||
|
|
df80a42d13 | ||
|
|
07d5f55abe | ||
|
|
1dfa09267b | ||
|
|
a0ee17989b | ||
|
|
2578eac294 | ||
|
|
60f0d22777 | ||
|
|
503c60f666 | ||
|
|
abf8ffdbca | ||
|
|
97e27d0dad | ||
|
|
4259ce4979 | ||
|
|
855dc2fbb9 | ||
|
|
e1e34f4907 | ||
|
|
7196b9ee9b | ||
|
|
c0b3403f87 | ||
|
|
7f808bc64f | ||
|
|
be9dc59f73 | ||
|
|
3a2a64b877 | ||
|
|
4c193f5d21 | ||
|
|
7322f0c024 | ||
|
|
9c2a36cefe | ||
|
|
0ce2cba0b1 | ||
|
|
1103b733fe | ||
|
|
81d7283990 | ||
|
|
3dba0f2938 | ||
|
|
ff8b077b0e | ||
|
|
66b5d3f0fd | ||
|
|
ec5d73c3a8 | ||
|
|
b71c3044ce | ||
|
|
f09cc75fb6 | ||
|
|
df9074773c | ||
|
|
6a2670592f | ||
|
|
35ede09e0f | ||
|
|
3862082f64 | ||
|
|
b7d2cb9b78 | ||
|
|
29c3a8d412 | ||
|
|
546f95ad07 | ||
|
|
6d8bfe269c | ||
|
|
ed71c8262a | ||
|
|
2ececf21c7 | ||
|
|
7516d96eed | ||
|
|
4bf7e9d192 | ||
|
|
04cd3081e4 | ||
|
|
d27716c1e0 | ||
|
|
7f7f36d986 | ||
|
|
86a4e18134 | ||
|
|
304858c7c5 | ||
|
|
7ececf9e0f | ||
|
|
521e530e11 | ||
|
|
46ffd7ebf3 | ||
|
|
65605d7b72 | ||
|
|
b3f9690941 | ||
|
|
4c29dae4af | ||
|
|
038d9e474e | ||
|
|
f5317dc225 | ||
|
|
c952450c2e | ||
|
|
1eb7ec4402 | ||
|
|
9a0bbf831b | ||
|
|
a30854a4c7 | ||
|
|
869557f7d1 | ||
|
|
856057be81 | ||
|
|
c9f1154643 | ||
|
|
748f04c9e3 | ||
|
|
d391595836 | ||
|
|
967140a148 | ||
|
|
95e68b0437 | ||
|
|
8ddede1611 | ||
|
|
ceb200b08c | ||
|
|
00e5f48a59 | ||
|
|
ea0e9105bc | ||
|
|
51459815ba | ||
|
|
8c62935a01 | ||
|
|
839fa2417d | ||
|
|
1b8610e4d8 | ||
|
|
ca063cbe90 | ||
|
|
7d4328b2fb | ||
|
|
1ae224ab74 | ||
|
|
c308fc44c4 | ||
|
|
aa3fb85919 | ||
|
|
bd052a33f8 | ||
|
|
bb766c36c3 | ||
|
|
9c1f69e9c1 | ||
|
|
14b11575d0 | ||
|
|
2dd9a2006d | ||
|
|
ebff5aa3db | ||
|
|
3bc2c5fabc | ||
|
|
d423aa926e | ||
|
|
fe708eefc6 | ||
|
|
a7525037fd | ||
|
|
15736bceb9 | ||
|
|
35b0108da6 | ||
|
|
59d23da97c | ||
|
|
3f654bccaa | ||
|
|
a45a8723c0 | ||
|
|
ae7d6da35b | ||
|
|
a8e056c88c | ||
|
|
5b0af905a2 | ||
|
|
eb8f69dd03 | ||
|
|
ef49828989 | ||
|
|
9b56734451 | ||
|
|
2f8d53d3f7 | ||
|
|
5b96929f4e | ||
|
|
829bb61378 | ||
|
|
421ecff30f | ||
|
|
c7511fc99f | ||
|
|
87f797b1ae | ||
|
|
8cc94d8ea7 | ||
|
|
dcaff6a243 | ||
|
|
e98aed6f6e | ||
|
|
d35e34b55e | ||
|
|
bb4d57e170 | ||
|
|
fd709afc37 | ||
|
|
93388bc3cc | ||
|
|
a8c4437587 | ||
|
|
6dc83386bd | ||
|
|
9641e6a2d0 | ||
|
|
3254544eb2 | ||
|
|
c707b9a432 | ||
|
|
3cab1571be | ||
|
|
502598bd25 | ||
|
|
8a18f92710 | ||
|
|
3353d0e005 | ||
|
|
fd85842036 | ||
|
|
b0dc46c9e9 | ||
|
|
5b0c923a82 | ||
|
|
ae33a4521d | ||
|
|
4b83e89d40 | ||
|
|
da41483172 | ||
|
|
39488f118b | ||
|
|
f9721b029e | ||
|
|
974904588c | ||
|
|
38457a4667 | ||
|
|
96ef5c8314 | ||
|
|
96d24756ea | ||
|
|
77c99b418f | ||
|
|
7f2a47f303 | ||
|
|
dcf0f449c4 | ||
|
|
a4c84d727c | ||
|
|
5335ebf044 | ||
|
|
e9d87fb551 | ||
|
|
54382d6666 | ||
|
|
e86eb28890 | ||
|
|
5897b82c51 | ||
|
|
5e27462acf | ||
|
|
4c95ae546f | ||
|
|
d42e3d36bc | ||
|
|
ee977def52 | ||
|
|
30016967b1 | ||
|
|
250ee90b07 | ||
|
|
624cf95197 | ||
|
|
8467fa333d | ||
|
|
75ba08556f | ||
|
|
93f954411b | ||
|
|
059e439702 | ||
|
|
2028420e3b | ||
|
|
8b05b725aa | ||
|
|
d7df7eddb1 | ||
|
|
0037813b39 | ||
|
|
377856c6a1 | ||
|
|
49969a2f1e | ||
|
|
09f8ab9962 | ||
|
|
422b092eb2 | ||
|
|
067a1a22c6 | ||
|
|
83c6223617 | ||
|
|
611adadaed | ||
|
|
28935a5856 | ||
|
|
71a144f6f9 | ||
|
|
92b7819259 | ||
|
|
d2204ae72e | ||
|
|
7da70ecf6a | ||
|
|
d8dfc10ea8 | ||
|
|
7df987803d | ||
|
|
4665bab700 | ||
|
|
e87aaff06b | ||
|
|
7c4938293e | ||
|
|
eba73eebcb | ||
|
|
1f4f164d5e | ||
|
|
bfea62b43b | ||
|
|
4c216646a4 | ||
|
|
4fe90a6c73 | ||
|
|
961b26a984 | ||
|
|
0d9ab2e2f6 | ||
|
|
796c33bc46 | ||
|
|
4d06ecd535 | ||
|
|
f9e4dd8fd3 | ||
|
|
6e4d7aa7f1 | ||
|
|
998d5c8d8f | ||
|
|
38865a40ad | ||
|
|
a5c4d90154 | ||
|
|
2e5a988bb3 | ||
|
|
0ee2f286aa | ||
|
|
30a7d61e56 | ||
|
|
c7f9dbfc29 | ||
|
|
c6bb2b51e6 | ||
|
|
a053f03818 | ||
|
|
6970ac24bf | ||
|
|
431149d20c | ||
|
|
a366d62358 | ||
|
|
a6a91d49b7 | ||
|
|
22cf3b25bd | ||
|
|
139b61fff1 | ||
|
|
c1fd82f50f | ||
|
|
effeed7ade | ||
|
|
546e438943 | ||
|
|
efcd23993e | ||
|
|
0c8aad49f9 | ||
|
|
317e1245c8 | ||
|
|
d2bbc56c78 | ||
|
|
8957424e55 | ||
|
|
0fd5b04b9a | ||
|
|
3ea7cd3bf7 | ||
|
|
7513e4426c | ||
|
|
0dfde0660a | ||
|
|
8c619fd86e | ||
|
|
407e58f837 | ||
|
|
9588b7f1a3 | ||
|
|
28c1e77b60 | ||
|
|
0baf395030 | ||
|
|
9681b0deda | ||
|
|
62fb916a68 | ||
|
|
3614236cfc | ||
|
|
c75f50e99a | ||
|
|
55d9e92032 | ||
|
|
2edcf0f46b | ||
|
|
69363bf7ef | ||
|
|
2b0c634fb8 | ||
|
|
28167adc22 | ||
|
|
bd4b3e4107 | ||
|
|
2cbd1080fa | ||
|
|
a4293068bf | ||
|
|
d1ce54806f | ||
|
|
6b39d6aa43 | ||
|
|
5d1cf251b9 | ||
|
|
c02c82557b | ||
|
|
b90b449ceb | ||
|
|
6a06df79c4 | ||
|
|
2558dc0b10 | ||
|
|
2eee3bfcd6 | ||
|
|
2685fa7c4e | ||
|
|
3c44532551 | ||
|
|
2640406f5b | ||
|
|
c1e36a1e5f | ||
|
|
ae1d9f5b86 | ||
|
|
1df0ac486b | ||
|
|
b1fcb18d9e | ||
|
|
5a6eea7fa2 | ||
|
|
6fe16bc71a | ||
|
|
6a66c49261 | ||
|
|
fc695e7a50 | ||
|
|
9efcad9360 | ||
|
|
cd5bbcda8d | ||
|
|
aa69c3ae91 | ||
|
|
76f2decf8b | ||
|
|
84bef54802 | ||
|
|
3507b0f952 | ||
|
|
b0828cc099 | ||
|
|
32ac67166a | ||
|
|
b2d0c22d75 | ||
|
|
cfabc92945 | ||
|
|
809465b6e2 | ||
|
|
8b59b6166e | ||
|
|
3faf9bae5c | ||
|
|
c2ee0727a5 | ||
|
|
7de5f40884 | ||
|
|
21cd3b86ad | ||
|
|
ad1b0fdddd | ||
|
|
1db8cf7fe5 | ||
|
|
46da1619af | ||
|
|
bad9517153 | ||
|
|
38d5daaf12 | ||
|
|
297ae7eccb | ||
|
|
b54d56ec47 | ||
|
|
4e2f2bebd0 | ||
|
|
f88915728f | ||
|
|
1be89a28bf | ||
|
|
250e57cd79 | ||
|
|
a4d930322e | ||
|
|
c3ce9cafb7 | ||
|
|
348f7177a7 | ||
|
|
c6074402bb | ||
|
|
23eccd1df6 | ||
|
|
ff5c846130 | ||
|
|
81b7bb4124 | ||
|
|
a8fb07137d | ||
|
|
85fa913b1c | ||
|
|
bc0fde6853 | ||
|
|
4f2754d16c | ||
|
|
4445111a08 | ||
|
|
151f61adc0 | ||
|
|
fc369415e4 | ||
|
|
b5a22e3e9e | ||
|
|
d372729ed0 | ||
|
|
96b85edfa2 | ||
|
|
4af573aaf9 | ||
|
|
1e5c69eb99 | ||
|
|
e1e73d2aa0 | ||
|
|
a23ee165d8 | ||
|
|
467a1a47cc | ||
|
|
93d1c05ca7 | ||
|
|
fb9c0d6a5a |
@@ -1,69 +0,0 @@
|
|||||||
# Repository Contribution Guidelines & Automation
|
|
||||||
|
|
||||||
This document establishes the single source of truth for repository contribution guidelines, optimized for AI context consumption, alongside a TiddlyWiki-based automation strategy to prevent source-of-truth drift.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📄 The High-Density Ruleset
|
|
||||||
*Copy the content below into a single master tiddler titled `ProjectContributionRules` with the type `text/x-markdown`.*
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
# CONTRIBUTING
|
|
||||||
|
|
||||||
## AI & Comment Rules
|
|
||||||
* Banned: Conversational filler, verbose explanations of standard APIs, or teaching basic programming logic.
|
|
||||||
* Required: Prune all AI-generated comment blocks down to a single sentence maximum.
|
|
||||||
* Focus: Comments must only state the "why" behind non-obvious engineering decisions, never the "how".
|
|
||||||
* PR Descriptions: Write concise, bulleted summaries of what changed. Do not use AI-generated marketing/polite filler text.
|
|
||||||
|
|
||||||
### Code Comment Examples
|
|
||||||
* BAD: // Use behavior:"instant" so that this animation's per-frame position updates are applied immediately and are NOT re-animated by a CSS `scroll-behavior: smooth` on the scrolling element (which would make the page lag behind and stutter).
|
|
||||||
* GOOD: // Use 'instant' to prevent conflicts with CSS scroll-behavior: smooth.
|
|
||||||
|
|
||||||
## Workflow Rules
|
|
||||||
* Branching: Base all feature branches on `main`. Use `feat/` or `fix/` prefixes.
|
|
||||||
* Scope: Keep pull requests limited to a single logical change. Massive, multi-feature PRs will be rejected.
|
|
||||||
* Testing: Run local tests and formatting checks before pushing.
|
|
||||||
* Merging: All commits are squashed on merge.
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🛠️ TiddlyWiki Build Integration
|
|
||||||
To ensure this file is distributed automatically to all required locations without duplication, use TiddlyWiki's native command-line rendering tool.
|
|
||||||
|
|
||||||
### 1. Update `tiddlywiki.info`
|
|
||||||
Add a dedicated `repo-configs` target to your project's `tiddlywiki.info` JSON file. This instructs TiddlyWiki to compile the master tiddler out to both human-facing and AI-facing configuration endpoints:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"description": "Project build targets",
|
|
||||||
"plugins": [
|
|
||||||
"tiddlywiki/markdown"
|
|
||||||
],
|
|
||||||
"build": {
|
|
||||||
"repo-configs": [
|
|
||||||
"--rendertiddler", "ProjectContributionRules", "./CONTRIBUTING.md", "text/plain",
|
|
||||||
"--rendertiddler", "ProjectContributionRules", "./.claudecode", "text/plain"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Update `package.json`
|
|
||||||
Integrate the rendering command into your existing Node.js project lifecycle scripts so it triggers automatically during development builds or pre-commit checks:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"scripts": {
|
|
||||||
"build:configs": "tiddlywiki --build repo-configs"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 Why This Works
|
|
||||||
* **Zero Duplication:** Edits are made exclusively within `ProjectContributionRules` inside the wiki workspace.
|
|
||||||
* **Human Visibility:** Browsing GitHub automatically surfaces `CONTRIBUTING.md` to human contributors.
|
|
||||||
* **Claude Code Ready:** When **Claude Code** sweeps the project root, it instantly reads the identical, strict engineering boundaries outputted to `.claudecode`.
|
|
||||||
+1
-1
@@ -5,7 +5,7 @@
|
|||||||
# Default to the current version number for building the plugin library
|
# Default to the current version number for building the plugin library
|
||||||
|
|
||||||
if [ -z "$TW5_BUILD_VERSION" ]; then
|
if [ -z "$TW5_BUILD_VERSION" ]; then
|
||||||
TW5_BUILD_VERSION=v5.4.1.
|
TW5_BUILD_VERSION=v5.5.0.
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Using TW5_BUILD_VERSION as [$TW5_BUILD_VERSION]"
|
echo "Using TW5_BUILD_VERSION as [$TW5_BUILD_VERSION]"
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
|
|||||||
|
title: TiddlyWiki Team
|
||||||
|
tags: Community/Team
|
||||||
|
modified: 20260708095630754
|
||||||
|
created: 20260708095630754
|
||||||
|
leader: @BurningTreeC
|
||||||
|
team:
|
||||||
|
|
||||||
|
The TiddlyDesktop development repository is at https://github.com/TiddlyWiki/TiddlyDesktop
|
||||||
@@ -217,6 +217,11 @@ exports.generateTiddlerFileInfo = function(tiddler,options) {
|
|||||||
fileInfo.isEditableFile = true;
|
fileInfo.isEditableFile = true;
|
||||||
fileInfo.originalpath = options.fileInfo.originalpath;
|
fileInfo.originalpath = options.fileInfo.originalpath;
|
||||||
}
|
}
|
||||||
|
// Propagate the pinFilepath flag (so generateTiddlerFilepath can short-circuit
|
||||||
|
// FileSystemPaths and write back to the original location)
|
||||||
|
if(options.fileInfo && !!options.fileInfo.pinFilepath) {
|
||||||
|
fileInfo.pinFilepath = true;
|
||||||
|
}
|
||||||
// Check if the tiddler has any unsafe fields that can't be expressed in a .tid or .meta file: containing control characters, or leading/trailing whitespace
|
// Check if the tiddler has any unsafe fields that can't be expressed in a .tid or .meta file: containing control characters, or leading/trailing whitespace
|
||||||
var hasUnsafeFields = false;
|
var hasUnsafeFields = false;
|
||||||
$tw.utils.each(tiddler.getFieldStrings(),function(value,fieldName) {
|
$tw.utils.each(tiddler.getFieldStrings(),function(value,fieldName) {
|
||||||
@@ -319,9 +324,16 @@ exports.generateTiddlerFilepath = function(title,options) {
|
|||||||
extension = options.extension || "",
|
extension = options.extension || "",
|
||||||
originalpath = (options.fileInfo && options.fileInfo.originalpath) ? options.fileInfo.originalpath : "",
|
originalpath = (options.fileInfo && options.fileInfo.originalpath) ? options.fileInfo.originalpath : "",
|
||||||
overwrite = options.fileInfo && options.fileInfo.overwrite || false,
|
overwrite = options.fileInfo && options.fileInfo.overwrite || false,
|
||||||
|
pinFilepath = !!(options.fileInfo && options.fileInfo.pinFilepath),
|
||||||
filepath;
|
filepath;
|
||||||
|
// If the tiddler's filepath is pinned via tiddlywiki.files, the originalpath
|
||||||
|
// wins and the path filters are skipped entirely.
|
||||||
|
if(pinFilepath && originalpath) {
|
||||||
|
var pinnedExt = path.extname(originalpath);
|
||||||
|
filepath = originalpath.substring(0,originalpath.length - pinnedExt.length);
|
||||||
|
}
|
||||||
// Check if any of the pathFilters applies
|
// Check if any of the pathFilters applies
|
||||||
if(options.pathFilters && options.wiki) {
|
if(!filepath && options.pathFilters && options.wiki) {
|
||||||
$tw.utils.each(options.pathFilters,function(filter) {
|
$tw.utils.each(options.pathFilters,function(filter) {
|
||||||
if(!filepath) {
|
if(!filepath) {
|
||||||
var source = options.wiki.makeTiddlerIterator([title]),
|
var source = options.wiki.makeTiddlerIterator([title]),
|
||||||
@@ -336,13 +348,14 @@ exports.generateTiddlerFilepath = function(title,options) {
|
|||||||
//Use the originalpath without the extension
|
//Use the originalpath without the extension
|
||||||
var ext = path.extname(originalpath);
|
var ext = path.extname(originalpath);
|
||||||
filepath = originalpath.substring(0,originalpath.length - ext.length);
|
filepath = originalpath.substring(0,originalpath.length - ext.length);
|
||||||
|
// normalise "\" to "/" so the sanitiser keeps subdirectories
|
||||||
|
// (it strips "\", not "/") instead of flattening them.
|
||||||
|
filepath = filepath.split(path.sep).join("/");
|
||||||
} else if(!filepath) {
|
} else if(!filepath) {
|
||||||
filepath = title;
|
filepath = title;
|
||||||
// Remove any forward or backward slashes so we don't create directories
|
// Remove any forward or backward slashes so we don't create directories
|
||||||
filepath = filepath.replace(/\/|\\/g,"_");
|
filepath = filepath.replace(/\/|\\/g,"_");
|
||||||
}
|
}
|
||||||
// Replace any Windows control codes
|
|
||||||
filepath = filepath.replace(/^(con|prn|aux|nul|com[0-9]|lpt[0-9])$/i,"_$1_");
|
|
||||||
// Replace any leading spaces with the same number of underscores
|
// Replace any leading spaces with the same number of underscores
|
||||||
filepath = filepath.replace(/^ +/,function (u) { return u.replace(/ /g, "_");});
|
filepath = filepath.replace(/^ +/,function (u) { return u.replace(/ /g, "_");});
|
||||||
//If the path does not start with "." or ".." && a path seperator, then
|
//If the path does not start with "." or ".." && a path seperator, then
|
||||||
@@ -352,8 +365,23 @@ exports.generateTiddlerFilepath = function(title,options) {
|
|||||||
}
|
}
|
||||||
// Replace any Unicode control codes
|
// Replace any Unicode control codes
|
||||||
filepath = filepath.replace(/[\x00-\x1f\x80-\x9f]/g,"_");
|
filepath = filepath.replace(/[\x00-\x1f\x80-\x9f]/g,"_");
|
||||||
// Replace any characters that can't be used in cross-platform filenames
|
// Replace any characters that can't be used in cross-platform filenames.
|
||||||
filepath = $tw.utils.transliterate(filepath.replace(/<|>|~|\:|\"|\||\?|\*|\^/g,"_"));
|
if(!pinFilepath) {
|
||||||
|
filepath = $tw.utils.transliterate(filepath.replace(/<|>|~|\:|\"|\||\?|\*|\^|\\/g,"_"));
|
||||||
|
}
|
||||||
|
// Per segment (catches "sub/CON"), MUST be after transliterate which can create a
|
||||||
|
// reserved name. Reserved names are wrapped on every path incl pinned;
|
||||||
|
// trailing dots/spaces (Windows strips) fixed for generated names, not pinned.
|
||||||
|
filepath = filepath.split("/").map(function(segment) {
|
||||||
|
if(segment === "" || segment === "." || segment === "..") {
|
||||||
|
return segment;
|
||||||
|
}
|
||||||
|
segment = segment.replace(/^(con|prn|aux|nul|com[0-9]|lpt[0-9])$/i,"_$1_");
|
||||||
|
if(!pinFilepath) {
|
||||||
|
segment = segment.replace(/[. ]+$/,function(u) { return u.replace(/[. ]/g,"_"); });
|
||||||
|
}
|
||||||
|
return segment;
|
||||||
|
}).join("/");
|
||||||
// Replace any dots or spaces at the end of the extension with the same number of underscores
|
// Replace any dots or spaces at the end of the extension with the same number of underscores
|
||||||
extension = extension.replace(/[\. ]+$/, function (u) { return u.replace(/[\. ]/g, "_");});
|
extension = extension.replace(/[\. ]+$/, function (u) { return u.replace(/[\. ]/g, "_");});
|
||||||
// Truncate the extension if it is too long
|
// Truncate the extension if it is too long
|
||||||
|
|||||||
@@ -9,15 +9,14 @@ Serve tiddlers over http
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
let fs, url, path, querystring, crypto, zlib;
|
let fs, path, crypto, zlib, URL;
|
||||||
|
|
||||||
if($tw.node) {
|
if($tw.node) {
|
||||||
fs = require("fs"),
|
fs = require("fs"),
|
||||||
url = require("url"),
|
|
||||||
path = require("path"),
|
path = require("path"),
|
||||||
querystring = require("querystring"),
|
|
||||||
crypto = require("crypto"),
|
crypto = require("crypto"),
|
||||||
zlib = require("zlib");
|
zlib = require("zlib");
|
||||||
|
URL = require("url").URL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -260,8 +259,8 @@ Server.prototype.requestHandler = function(request,response,options) {
|
|||||||
state.wiki = options.wiki || self.wiki;
|
state.wiki = options.wiki || self.wiki;
|
||||||
state.boot = options.boot || self.boot;
|
state.boot = options.boot || self.boot;
|
||||||
state.server = self;
|
state.server = self;
|
||||||
state.urlInfo = url.parse(request.url);
|
state.urlInfo = new URL(request.url, "http://localhost");
|
||||||
state.queryParameters = querystring.parse(state.urlInfo.query);
|
state.queryParameters = Object.fromEntries(state.urlInfo.searchParams);
|
||||||
state.pathPrefix = options.pathPrefix || this.get("path-prefix") || "";
|
state.pathPrefix = options.pathPrefix || this.get("path-prefix") || "";
|
||||||
// Enable CORS
|
// Enable CORS
|
||||||
if(this.corsEnable) {
|
if(this.corsEnable) {
|
||||||
|
|||||||
@@ -58,10 +58,14 @@ LayoutSwitcher/Caption: Layout
|
|||||||
LoadedModules/Caption: Loaded Modules
|
LoadedModules/Caption: Loaded Modules
|
||||||
LoadedModules/Hint: These are the currently loaded tiddler modules linked to their source tiddlers. Any italicised modules lack a source tiddler, typically because they were setup during the boot process.
|
LoadedModules/Hint: These are the currently loaded tiddler modules linked to their source tiddlers. Any italicised modules lack a source tiddler, typically because they were setup during the boot process.
|
||||||
Palette/Caption: Palette
|
Palette/Caption: Palette
|
||||||
|
Palette/Customisations/Prompt: Customisations for the current palette: <<palette-link>>
|
||||||
|
Palette/Customisations/Reset/Caption: reset customisations
|
||||||
|
Palette/Editor/Customised/Prompt: This palette has customisations that override the entries marked below
|
||||||
|
Palette/Editor/Customised/Entry: overridden by a customisation
|
||||||
Palette/Editor/Clone/Caption: clone
|
Palette/Editor/Clone/Caption: clone
|
||||||
Palette/Editor/Clone/Prompt: It is recommended that you clone this shadow palette before editing it
|
Palette/Editor/Clone/Prompt: It is recommended that you clone this shadow palette before editing it
|
||||||
Palette/Editor/Delete/Hint: delete this entry from the current palette
|
Palette/Editor/Delete/Hint: delete this entry from the current palette
|
||||||
Palette/Editor/Names/External/Show: Show color names that are not part of the current palette
|
Palette/Editor/Names/External/Show: Show inherited palette entries
|
||||||
Palette/Editor/Prompt/Modified: This shadow palette has been modified
|
Palette/Editor/Prompt/Modified: This shadow palette has been modified
|
||||||
Palette/Editor/Prompt: Editing
|
Palette/Editor/Prompt: Editing
|
||||||
Palette/Editor/Reset/Caption: reset
|
Palette/Editor/Reset/Caption: reset
|
||||||
@@ -255,4 +259,5 @@ ViewTemplateTags/Caption: View Template Tags
|
|||||||
ViewTemplateTags/Hint: This rule cascade is used by the default view template to dynamically choose the template for displaying the tags area of a tiddler.
|
ViewTemplateTags/Hint: This rule cascade is used by the default view template to dynamically choose the template for displaying the tags area of a tiddler.
|
||||||
WikiInformation/Caption: Wiki Information
|
WikiInformation/Caption: Wiki Information
|
||||||
WikiInformation/Hint: This page summarises high level information about the configuration of this ~TiddlyWiki. It is designed to enable users to quickly share relevant aspects of the configuration of their ~TiddlyWiki with others, for example when seeking help in one of the forums. No private or personal information is included, and nothing is shared without being explicitly copied and pasted elsewhere
|
WikiInformation/Hint: This page summarises high level information about the configuration of this ~TiddlyWiki. It is designed to enable users to quickly share relevant aspects of the configuration of their ~TiddlyWiki with others, for example when seeking help in one of the forums. No private or personal information is included, and nothing is shared without being explicitly copied and pasted elsewhere
|
||||||
WikiInformation/Drag/Caption: Drag this link to copy this tool to another wiki
|
WikiInformation/Drag/Caption: Drag this link to copy this tool to another wiki
|
||||||
|
WikiInformation/Generate/Caption: Click to generate wiki information report
|
||||||
@@ -30,6 +30,8 @@ Error/DeserializeOperator/MissingOperand: Filter Error: Missing operand for 'des
|
|||||||
Error/DeserializeOperator/UnknownDeserializer: Filter Error: Unknown deserializer provided as operand for the 'deserialize' operator
|
Error/DeserializeOperator/UnknownDeserializer: Filter Error: Unknown deserializer provided as operand for the 'deserialize' operator
|
||||||
Error/Filter: Filter error
|
Error/Filter: Filter error
|
||||||
Error/FilterSyntax: Syntax error in filter expression
|
Error/FilterSyntax: Syntax error in filter expression
|
||||||
|
Error/FilterPragma: Filter Error: Unknown filter pragma
|
||||||
|
Error/FilterPragmaPosition: Filter Error: Filter pragmas are only allowed at the start of a filter
|
||||||
Error/FilterRunPrefix: Filter Error: Unknown prefix for filter run
|
Error/FilterRunPrefix: Filter Error: Unknown prefix for filter run
|
||||||
Error/IsFilterOperator: Filter Error: Unknown parameter for the 'is' filter operator
|
Error/IsFilterOperator: Filter Error: Unknown parameter for the 'is' filter operator
|
||||||
Error/FormatFilterOperator: Filter Error: Unknown suffix for the 'format' filter operator
|
Error/FormatFilterOperator: Filter Error: Unknown suffix for the 'format' filter operator
|
||||||
|
|||||||
@@ -78,7 +78,6 @@ class BackgroundActionTracker {
|
|||||||
fnProcess: (changes) => {
|
fnProcess: (changes) => {
|
||||||
if(this.hasChanged) {
|
if(this.hasChanged) {
|
||||||
this.hasChanged = false;
|
this.hasChanged = false;
|
||||||
console.log("Processing background action", this.title);
|
|
||||||
const tiddler = this.wiki.getTiddler(this.title);
|
const tiddler = this.wiki.getTiddler(this.title);
|
||||||
let doActions = true;
|
let doActions = true;
|
||||||
if(tiddler && tiddler.fields.platforms) {
|
if(tiddler && tiddler.fields.platforms) {
|
||||||
@@ -89,6 +88,7 @@ class BackgroundActionTracker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(doActions) {
|
if(doActions) {
|
||||||
|
console.log("Processing background action", this.title);
|
||||||
this.wiki.invokeActionString(
|
this.wiki.invokeActionString(
|
||||||
this.actions,
|
this.actions,
|
||||||
null,
|
null,
|
||||||
|
|||||||
@@ -31,8 +31,7 @@ function FramedEngine(options) {
|
|||||||
this.parentNode.insertBefore(this.iframeNode,this.nextSibling);
|
this.parentNode.insertBefore(this.iframeNode,this.nextSibling);
|
||||||
this.iframeDoc = this.iframeNode.contentWindow.document;
|
this.iframeDoc = this.iframeNode.contentWindow.document;
|
||||||
// (Firefox requires us to put some empty content in the iframe)
|
// (Firefox requires us to put some empty content in the iframe)
|
||||||
var paletteTitle = this.widget.wiki.getTiddlerText("$:/palette");
|
var colorScheme = (this.widget.wiki.getTiddler("$:/temp/palette-colours") || {fields: {}}).fields["color-scheme"] || "light";
|
||||||
var colorScheme = (this.widget.wiki.getTiddler(paletteTitle) || {fields: {}}).fields["color-scheme"] || "light";
|
|
||||||
this.iframeDoc.open();
|
this.iframeDoc.open();
|
||||||
this.iframeDoc.write("<!DOCTYPE html><html><head><meta name='color-scheme' content='" + colorScheme + "'></head><body></body></html>");
|
this.iframeDoc.write("<!DOCTYPE html><html><head><meta name='color-scheme' content='" + colorScheme + "'></head><body></body></html>");
|
||||||
this.iframeDoc.close();
|
this.iframeDoc.close();
|
||||||
|
|||||||
@@ -28,7 +28,12 @@ function SimpleEngine(options) {
|
|||||||
if(this.widget.editTag === "textarea") {
|
if(this.widget.editTag === "textarea") {
|
||||||
this.domNode.appendChild(this.widget.document.createTextNode(this.value));
|
this.domNode.appendChild(this.widget.document.createTextNode(this.value));
|
||||||
} else {
|
} else {
|
||||||
this.domNode.value = this.value;
|
if(this.widget.editType === "color") {
|
||||||
|
// The <input type="color"> element requires a six digit hex value
|
||||||
|
this.domNode.value = $tw.utils.convertCSSColorToRGBString(this.value);
|
||||||
|
} else {
|
||||||
|
this.domNode.value = this.value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Set the attributes
|
// Set the attributes
|
||||||
if(this.widget.editType && this.widget.editTag !== "textarea") {
|
if(this.widget.editType && this.widget.editTag !== "textarea") {
|
||||||
@@ -83,6 +88,9 @@ Update the DomNode with the new text
|
|||||||
*/
|
*/
|
||||||
SimpleEngine.prototype.updateDomNodeText = function(text) {
|
SimpleEngine.prototype.updateDomNodeText = function(text) {
|
||||||
try {
|
try {
|
||||||
|
if(this.widget.editType === "color") {
|
||||||
|
text = $tw.utils.convertCSSColorToRGBString(text);
|
||||||
|
}
|
||||||
this.domNode.value = text;
|
this.domNode.value = text;
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
// Ignore
|
// Ignore
|
||||||
|
|||||||
@@ -210,6 +210,29 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
|
|||||||
this.editShowToolbar = this.wiki.getTiddlerText(ENABLE_TOOLBAR_TITLE,"yes");
|
this.editShowToolbar = this.wiki.getTiddlerText(ENABLE_TOOLBAR_TITLE,"yes");
|
||||||
this.editShowToolbar = (this.editShowToolbar === "yes") && !!(this.children && this.children.length > 0) && (!this.document.isTiddlyWikiFakeDom);
|
this.editShowToolbar = (this.editShowToolbar === "yes") && !!(this.children && this.children.length > 0) && (!this.document.isTiddlyWikiFakeDom);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
EditTextWidget.prototype.updateDomNodeClasses = function() {
|
||||||
|
var domNodeClasses = this.engine.domNode.className.split(/\s+/).filter(Boolean),
|
||||||
|
oldClasses = this.editClass.split(/\s+/).filter(Boolean),
|
||||||
|
newClasses;
|
||||||
|
|
||||||
|
this.editClass = this.getAttribute("class","");
|
||||||
|
newClasses = this.editClass.split(/\s+/).filter(Boolean);
|
||||||
|
|
||||||
|
// Remove classes assigned from the old value of the class attribute
|
||||||
|
domNodeClasses = domNodeClasses.filter(function(className) {
|
||||||
|
return !oldClasses.includes(className);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add new classes from the updated class attribute
|
||||||
|
domNodeClasses = domNodeClasses.concat(
|
||||||
|
newClasses.filter(function(className) {
|
||||||
|
return !domNodeClasses.includes(className);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
this.engine.domNode.className = domNodeClasses.join(" ");
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
|
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
|
||||||
@@ -217,15 +240,19 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
|
|||||||
EditTextWidget.prototype.refresh = function(changedTiddlers) {
|
EditTextWidget.prototype.refresh = function(changedTiddlers) {
|
||||||
var changedAttributes = this.computeAttributes();
|
var changedAttributes = this.computeAttributes();
|
||||||
// Completely rerender if any of our attributes have changed
|
// Completely rerender if any of our attributes have changed
|
||||||
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes["default"] || changedAttributes["class"] || changedAttributes.placeholder || changedAttributes.size || changedAttributes.autoHeight || changedAttributes.minHeight || changedAttributes.focusPopup || changedAttributes.rows || changedAttributes.tabindex || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || changedAttributes.autocomplete || changedTiddlers[HEIGHT_MODE_TITLE] || changedTiddlers[ENABLE_TOOLBAR_TITLE] || changedTiddlers["$:/palette"] || changedAttributes.disabled || changedAttributes.fileDrop) {
|
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.placeholder || changedAttributes.size || changedAttributes.autoHeight || changedAttributes.minHeight || changedAttributes.focusPopup || changedAttributes.rows || changedAttributes.tabindex || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || changedAttributes.autocomplete || changedTiddlers[HEIGHT_MODE_TITLE] || changedTiddlers[ENABLE_TOOLBAR_TITLE] || changedTiddlers["$:/palette"] || changedAttributes.disabled || changedAttributes.fileDrop) {
|
||||||
this.refreshSelf();
|
this.refreshSelf();
|
||||||
return true;
|
return true;
|
||||||
} else if(changedTiddlers[this.editRefreshTitle]) {
|
} else if(changedAttributes["default"] || changedTiddlers[this.editRefreshTitle]) {
|
||||||
|
this.editDefault = this.getAttribute("default");
|
||||||
this.engine.updateDomNodeText(this.getEditInfo().value);
|
this.engine.updateDomNodeText(this.getEditInfo().value);
|
||||||
} else if(changedTiddlers[this.editTitle]) {
|
} else if(changedTiddlers[this.editTitle]) {
|
||||||
var editInfo = this.getEditInfo();
|
var editInfo = this.getEditInfo();
|
||||||
this.updateEditor(editInfo.value,editInfo.type);
|
this.updateEditor(editInfo.value,editInfo.type);
|
||||||
}
|
}
|
||||||
|
if(changedAttributes["class"]) {
|
||||||
|
this.updateDomNodeClasses();
|
||||||
|
}
|
||||||
this.engine.fixHeight();
|
this.engine.fixHeight();
|
||||||
if(this.editShowToolbar) {
|
if(this.editShowToolbar) {
|
||||||
return this.refreshChildren(changedTiddlers);
|
return this.refreshChildren(changedTiddlers);
|
||||||
|
|||||||
@@ -13,14 +13,15 @@ Export our filter prefix function
|
|||||||
exports.intersection = function(operationSubFunction) {
|
exports.intersection = function(operationSubFunction) {
|
||||||
return function(results,source,widget) {
|
return function(results,source,widget) {
|
||||||
if(results.length !== 0) {
|
if(results.length !== 0) {
|
||||||
var secondRunResults = operationSubFunction(source,widget);
|
const secondRunResults = operationSubFunction(source,widget),
|
||||||
var firstRunResults = results.toArray();
|
secondRunSet = new Set(secondRunResults),
|
||||||
|
firstRunResults = results.toArray();
|
||||||
results.clear();
|
results.clear();
|
||||||
$tw.utils.each(firstRunResults,function(title) {
|
firstRunResults.forEach((title) => {
|
||||||
if(secondRunResults.indexOf(title) !== -1) {
|
if(secondRunSet.has(title)) {
|
||||||
results.push(title);
|
results.push(title);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -13,33 +13,28 @@ Export our filter prefix function
|
|||||||
exports.sort = function(operationSubFunction,options) {
|
exports.sort = function(operationSubFunction,options) {
|
||||||
return function(results,source,widget) {
|
return function(results,source,widget) {
|
||||||
if(results.length > 0) {
|
if(results.length > 0) {
|
||||||
var suffixes = options.suffixes,
|
const suffixes = options.suffixes,
|
||||||
sortType = (suffixes[0] && suffixes[0][0]) ? suffixes[0][0] : "string",
|
sortType = (suffixes[0] && suffixes[0][0]) ? suffixes[0][0] : "string",
|
||||||
invert = suffixes[1] ? (suffixes[1].indexOf("reverse") !== -1) : false,
|
invert = suffixes[1] ? suffixes[1].includes("reverse") : false,
|
||||||
isCaseSensitive = suffixes[1] ? (suffixes[1].indexOf("casesensitive") !== -1) : false,
|
isCaseSensitive = suffixes[1] ? suffixes[1].includes("casesensitive") : false,
|
||||||
inputTitles = results.toArray(),
|
inputTitles = results.toArray(),
|
||||||
sortKeys = [],
|
sortKeys = [],
|
||||||
indexes = new Array(inputTitles.length),
|
compareFn = $tw.utils.makeCompareFunction(sortType,{defaultType: "string", invert:invert, isCaseSensitive:isCaseSensitive});
|
||||||
compareFn;
|
results.each((title) => {
|
||||||
results.each(function(title) {
|
const key = operationSubFunction(
|
||||||
var key = operationSubFunction(options.wiki.makeTiddlerIterator([title]),widget.makeFakeWidgetWithVariables({
|
options.wiki.makeTiddlerIterator([title]),
|
||||||
"currentTiddler": "" + title,
|
widget.makeFakeWidgetWithVariables({
|
||||||
"..currentTiddler": widget.getVariable("currentTiddler",{defaultValue:""})
|
"currentTiddler": "" + title,
|
||||||
}));
|
"..currentTiddler": widget.getVariable("currentTiddler",{defaultValue:""})
|
||||||
|
})
|
||||||
|
);
|
||||||
sortKeys.push(key[0] || "");
|
sortKeys.push(key[0] || "");
|
||||||
});
|
});
|
||||||
results.clear();
|
results.clear();
|
||||||
// Prepare an array of indexes to sort
|
// Prepare an array of indexes to sort
|
||||||
for(var t=0; t<inputTitles.length; t++) {
|
let indexes = Array.from(inputTitles.keys());
|
||||||
indexes[t] = t;
|
indexes.sort((a,b) => compareFn(sortKeys[a],sortKeys[b]));
|
||||||
}
|
indexes.forEach((index) => {
|
||||||
// Sort the indexes
|
|
||||||
compareFn = $tw.utils.makeCompareFunction(sortType,{defaultType: "string", invert:invert, isCaseSensitive:isCaseSensitive});
|
|
||||||
indexes = indexes.sort(function(a,b) {
|
|
||||||
return compareFn(sortKeys[a],sortKeys[b]);
|
|
||||||
});
|
|
||||||
// Add to results in correct order
|
|
||||||
$tw.utils.each(indexes,function(index) {
|
|
||||||
results.push(inputTitles[index]);
|
results.push(inputTitles[index]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+88
-46
@@ -146,14 +146,16 @@ exports.parseFilter = function(filterString) {
|
|||||||
match;
|
match;
|
||||||
var whitespaceRegExp = /(\s+)/mg,
|
var whitespaceRegExp = /(\s+)/mg,
|
||||||
// Groups:
|
// Groups:
|
||||||
// 1 - entire filter run prefix
|
// 1 - pragma
|
||||||
// 2 - filter run prefix itself
|
// 2 - pragma suffix
|
||||||
// 3 - filter run prefix suffixes
|
// 3 - entire filter run prefix
|
||||||
// 4 - opening square bracket following filter run prefix
|
// 4 - filter run prefix name
|
||||||
// 5 - double quoted string following filter run prefix
|
// 5 - filter run prefix suffixes
|
||||||
// 6 - single quoted string following filter run prefix
|
// 6 - opening square bracket following filter run prefix
|
||||||
// 7 - anything except for whitespace and square brackets
|
// 7 - double quoted string following filter run prefix
|
||||||
operandRegExp = /((?:\+|\-|~|(?:=>?)|\:(\w+)(?:\:([\w\:, ]*))?)?)(?:(\[)|(?:"([^"]*)")|(?:'([^']*)')|([^\s\[\]]+))/mg;
|
// 8 - single quoted string following filter run prefix
|
||||||
|
// 9 - anything except for whitespace and square brackets
|
||||||
|
operandRegExp = /(?:::(\w+)(?:\:(\w+))?(?=\s|$)|((?:\+|\-|~|(?:=>?)|:(\w+)(?:\:([\w\:, ]*))?)?)(?:(\[)|(?:"([^"]*)")|(?:'([^']*)')|([^\s\[\]]+)))/mg;
|
||||||
while(p < filterString.length) {
|
while(p < filterString.length) {
|
||||||
// Skip any whitespace
|
// Skip any whitespace
|
||||||
whitespaceRegExp.lastIndex = p;
|
whitespaceRegExp.lastIndex = p;
|
||||||
@@ -170,18 +172,23 @@ exports.parseFilter = function(filterString) {
|
|||||||
};
|
};
|
||||||
match = operandRegExp.exec(filterString);
|
match = operandRegExp.exec(filterString);
|
||||||
if(match && match.index === p) {
|
if(match && match.index === p) {
|
||||||
// If there is a filter run prefix
|
|
||||||
if(match[1]) {
|
if(match[1]) {
|
||||||
operation.prefix = match[1];
|
// If there is a filter pragma
|
||||||
|
operation.pragma = match[1];
|
||||||
|
operation.suffix = match[2];
|
||||||
|
p = match.index + match[0].length;
|
||||||
|
} else if(match[3]) {
|
||||||
|
// If there is a filter run prefix
|
||||||
|
operation.prefix = match[3];
|
||||||
p = p + operation.prefix.length;
|
p = p + operation.prefix.length;
|
||||||
// Name for named prefixes
|
// Name for named prefixes
|
||||||
if(match[2]) {
|
if(match[4]) {
|
||||||
operation.namedPrefix = match[2];
|
operation.namedPrefix = match[4];
|
||||||
}
|
}
|
||||||
// Suffixes for filter run prefix
|
// Suffixes for filter run prefix
|
||||||
if(match[3]) {
|
if(match[5]) {
|
||||||
operation.suffixes = [];
|
operation.suffixes = [];
|
||||||
$tw.utils.each(match[3].split(":"),function(subsuffix) {
|
$tw.utils.each(match[5].split(":"),function(subsuffix) {
|
||||||
operation.suffixes.push([]);
|
operation.suffixes.push([]);
|
||||||
$tw.utils.each(subsuffix.split(","),function(entry) {
|
$tw.utils.each(subsuffix.split(","),function(entry) {
|
||||||
entry = $tw.utils.trim(entry);
|
entry = $tw.utils.trim(entry);
|
||||||
@@ -193,7 +200,7 @@ exports.parseFilter = function(filterString) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Opening square bracket
|
// Opening square bracket
|
||||||
if(match[4]) {
|
if(match[6]) {
|
||||||
p = parseFilterOperation(operation.operators,filterString,p);
|
p = parseFilterOperation(operation.operators,filterString,p);
|
||||||
} else {
|
} else {
|
||||||
p = match.index + match[0].length;
|
p = match.index + match[0].length;
|
||||||
@@ -203,9 +210,9 @@ exports.parseFilter = function(filterString) {
|
|||||||
p = parseFilterOperation(operation.operators,filterString,p);
|
p = parseFilterOperation(operation.operators,filterString,p);
|
||||||
}
|
}
|
||||||
// Quoted strings and unquoted title
|
// Quoted strings and unquoted title
|
||||||
if(match[5] || match[6] || match[7]) { // Double quoted string, single quoted string or unquoted title
|
if(match[7] || match[8] || match[9]) { // Double quoted string, single quoted string or unquoted title
|
||||||
operation.operators.push(
|
operation.operators.push(
|
||||||
{operator: "title", operands: [{text: match[5] || match[6] || match[7]}]}
|
{operator: "title", operands: [{text: match[7] || match[8] || match[9]}]}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
results.push(operation);
|
results.push(operation);
|
||||||
@@ -230,23 +237,26 @@ exports.getFilterRunPrefixes = function() {
|
|||||||
return this.filterRunPrefixes;
|
return this.filterRunPrefixes;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.filterTiddlers = function(filterString,widget,source) {
|
exports.filterTiddlers = function(filterString,widget,source,options) {
|
||||||
var fn = this.compileFilter(filterString);
|
var fn = this.compileFilter(filterString,options);
|
||||||
return fn.call(this,source,widget);
|
return fn.call(this,source,widget);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Compile a filter into a function with the signature fn(source,widget) where:
|
Compile a filter into a function with the signature fn(source,widget,options) where:
|
||||||
source: an iterator function for the source tiddlers, called source(iterator), where iterator is called as iterator(tiddler,title)
|
source: an iterator function for the source tiddlers, called source(iterator), where iterator is called as iterator(tiddler,title)
|
||||||
widget: an optional widget node for retrieving the current tiddler etc.
|
widget: an optional widget node for retrieving the current tiddler etc.
|
||||||
*/
|
*/
|
||||||
exports.compileFilter = function(filterString) {
|
exports.compileFilter = function(filterString,options) {
|
||||||
|
var defaultFilterRunPrefix = (options || {}).defaultFilterRunPrefix || "or",
|
||||||
|
seenNonPragmaOperation = false;
|
||||||
|
var cacheKey = filterString + "|" + defaultFilterRunPrefix;
|
||||||
if(!this.filterCache) {
|
if(!this.filterCache) {
|
||||||
this.filterCache = Object.create(null);
|
this.filterCache = Object.create(null);
|
||||||
this.filterCacheCount = 0;
|
this.filterCacheCount = 0;
|
||||||
}
|
}
|
||||||
if(this.filterCache[filterString] !== undefined) {
|
if(this.filterCache[cacheKey] !== undefined) {
|
||||||
return this.filterCache[filterString];
|
return this.filterCache[cacheKey];
|
||||||
}
|
}
|
||||||
var filterParseTree;
|
var filterParseTree;
|
||||||
try {
|
try {
|
||||||
@@ -296,7 +306,7 @@ exports.compileFilter = function(filterString) {
|
|||||||
var varTree = $tw.utils.parseFilterVariable(operand.text);
|
var varTree = $tw.utils.parseFilterVariable(operand.text);
|
||||||
var resultList = widgetClass.evaluateVariable(widget,varTree.name,{params: varTree.params, source: source});
|
var resultList = widgetClass.evaluateVariable(widget,varTree.name,{params: varTree.params, source: source});
|
||||||
if((resultList.length > 0 && resultList[0] !== undefined) || resultList.length === 0) {
|
if((resultList.length > 0 && resultList[0] !== undefined) || resultList.length === 0) {
|
||||||
operand.multiValue = widgetClass.evaluateVariable(widget,varTree.name,{params: varTree.params, source: source}) || [];
|
operand.multiValue = resultList || [];
|
||||||
operand.value = operand.multiValue[0] || "";
|
operand.value = operand.multiValue[0] || "";
|
||||||
} else {
|
} else {
|
||||||
operand.value = "";
|
operand.value = "";
|
||||||
@@ -325,7 +335,8 @@ exports.compileFilter = function(filterString) {
|
|||||||
regexp: operator.regexp
|
regexp: operator.regexp
|
||||||
},{
|
},{
|
||||||
wiki: self,
|
wiki: self,
|
||||||
widget: widget
|
widget: widget,
|
||||||
|
defaultFilterRunPrefix: defaultFilterRunPrefix
|
||||||
});
|
});
|
||||||
if($tw.utils.isArray(results)) {
|
if($tw.utils.isArray(results)) {
|
||||||
accumulator = self.makeTiddlerIterator(results);
|
accumulator = self.makeTiddlerIterator(results);
|
||||||
@@ -346,29 +357,60 @@ exports.compileFilter = function(filterString) {
|
|||||||
var filterRunPrefixes = self.getFilterRunPrefixes();
|
var filterRunPrefixes = self.getFilterRunPrefixes();
|
||||||
// Wrap the operator functions in a wrapper function that depends on the prefix
|
// Wrap the operator functions in a wrapper function that depends on the prefix
|
||||||
operationFunctions.push((function() {
|
operationFunctions.push((function() {
|
||||||
var options = {wiki: self, suffixes: operation.suffixes || []};
|
if(operation.pragma) {
|
||||||
switch(operation.prefix || "") {
|
// Pragmas are only allowed at the start of a filter, before any runs
|
||||||
case "": // No prefix means that the operation is unioned into the result
|
if(seenNonPragmaOperation) {
|
||||||
return filterRunPrefixes["or"](operationSubFunction, options);
|
return function(results,source,widget) {
|
||||||
case "=": // The results of the operation are pushed into the result without deduplication
|
results.clear();
|
||||||
return filterRunPrefixes["all"](operationSubFunction, options);
|
results.push($tw.language.getString("Error/FilterPragmaPosition"));
|
||||||
case "-": // The results of this operation are removed from the main result
|
};
|
||||||
return filterRunPrefixes["except"](operationSubFunction, options);
|
}
|
||||||
case "+": // This operation is applied to the main results so far
|
switch(operation.pragma) {
|
||||||
return filterRunPrefixes["and"](operationSubFunction, options);
|
case "defaultprefix":
|
||||||
case "~": // This operation is unioned into the result only if the main result so far is empty
|
defaultFilterRunPrefix = operation.suffix || "or";
|
||||||
return filterRunPrefixes["else"](operationSubFunction, options);
|
break;
|
||||||
case "=>": // This operation is applied to the main results so far, and the results are assigned to a variable
|
default:
|
||||||
return filterRunPrefixes["let"](operationSubFunction, options);
|
|
||||||
default:
|
|
||||||
if(operation.namedPrefix && filterRunPrefixes[operation.namedPrefix]) {
|
|
||||||
return filterRunPrefixes[operation.namedPrefix](operationSubFunction, options);
|
|
||||||
} else {
|
|
||||||
return function(results,source,widget) {
|
return function(results,source,widget) {
|
||||||
results.clear();
|
results.clear();
|
||||||
results.push($tw.language.getString("Error/FilterRunPrefix"));
|
results.push($tw.language.getString("Error/FilterPragma"));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
return function(results,source,widget) {
|
||||||
|
// Dummy response
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
seenNonPragmaOperation = true;
|
||||||
|
var options = {wiki: self, suffixes: operation.suffixes || []};
|
||||||
|
switch(operation.prefix || "") {
|
||||||
|
case "": // Use the default filter run prefix if none is specified
|
||||||
|
if(filterRunPrefixes[defaultFilterRunPrefix]) {
|
||||||
|
return filterRunPrefixes[defaultFilterRunPrefix](operationSubFunction, options);
|
||||||
|
} else {
|
||||||
|
return function(results,source,widget) {
|
||||||
|
results.clear();
|
||||||
|
results.push($tw.language.getString("Error/FilterRunPrefix"));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case "=": // The results of the operation are pushed into the result without deduplication
|
||||||
|
return filterRunPrefixes["all"](operationSubFunction, options);
|
||||||
|
case "-": // The results of this operation are removed from the main result
|
||||||
|
return filterRunPrefixes["except"](operationSubFunction, options);
|
||||||
|
case "+": // This operation is applied to the main results so far
|
||||||
|
return filterRunPrefixes["and"](operationSubFunction, options);
|
||||||
|
case "~": // This operation is unioned into the result only if the main result so far is empty
|
||||||
|
return filterRunPrefixes["else"](operationSubFunction, options);
|
||||||
|
case "=>": // This operation is applied to the main results so far, and the results are assigned to a variable
|
||||||
|
return filterRunPrefixes["let"](operationSubFunction, options);
|
||||||
|
default:
|
||||||
|
if(operation.namedPrefix && filterRunPrefixes[operation.namedPrefix]) {
|
||||||
|
return filterRunPrefixes[operation.namedPrefix](operationSubFunction, options);
|
||||||
|
} else {
|
||||||
|
return function(results,source,widget) {
|
||||||
|
results.clear();
|
||||||
|
results.push($tw.language.getString("Error/FilterRunPrefix"));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})());
|
})());
|
||||||
});
|
});
|
||||||
@@ -407,7 +449,7 @@ exports.compileFilter = function(filterString) {
|
|||||||
this.filterCache = Object.create(null);
|
this.filterCache = Object.create(null);
|
||||||
this.filterCacheCount = 0;
|
this.filterCacheCount = 0;
|
||||||
}
|
}
|
||||||
this.filterCache[filterString] = fnMeasured;
|
this.filterCache[cacheKey] = fnMeasured;
|
||||||
this.filterCacheCount++;
|
this.filterCacheCount++;
|
||||||
return fnMeasured;
|
return fnMeasured;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/filters/changecount.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: filteroperator
|
||||||
|
|
||||||
|
Filter operator for retrieving the changecount for each title in the list.
|
||||||
|
|
||||||
|
\*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Export our filter function
|
||||||
|
*/
|
||||||
|
exports.changecount = function(source,operator,options) {
|
||||||
|
var results = [];
|
||||||
|
source(function(tiddler,title) {
|
||||||
|
results.push(options.wiki.getChangeCount(title) + "");
|
||||||
|
});
|
||||||
|
return results;
|
||||||
|
};
|
||||||
@@ -0,0 +1,158 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/filters/colour-ops.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: filteroperator
|
||||||
|
|
||||||
|
Filter operators for colour operations
|
||||||
|
|
||||||
|
\*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var Color = require("$:/core/modules/utils/dom/color.js").Color,
|
||||||
|
colourSpacesList = Object.keys(Color.spaces),
|
||||||
|
hueAdjustersList = ["raw","increasing","decreasing","longer","shorter"];
|
||||||
|
|
||||||
|
exports["colour-lighten"] = makeSerialColourOperator(function (colour, operator, options) {
|
||||||
|
return colour.lighten($tw.utils.parseNumber(operator.operand)).display().toString();
|
||||||
|
});
|
||||||
|
|
||||||
|
exports["colour-darken"] = makeSerialColourOperator(function (colour, operator, options) {
|
||||||
|
return colour.darken($tw.utils.parseNumber(operator.operand)).display().toString();
|
||||||
|
});
|
||||||
|
|
||||||
|
exports["colour-get-oklch"] = makeSerialColourOperator(function (colour, operator, options) {
|
||||||
|
var prop = ((operator.suffixes || [])[0] || ["l"])[0];
|
||||||
|
if(["l","c","h"].indexOf(prop) !== -1) {
|
||||||
|
colour = colour.oklch[prop];
|
||||||
|
// Hue is null for achromatic colours
|
||||||
|
if(colour === null || colour === undefined || Number.isNaN(colour)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return colour.toString();
|
||||||
|
});
|
||||||
|
|
||||||
|
exports["colour-set-oklch"] = makeSerialColourOperator(function (colour, operator, options) {
|
||||||
|
var prop = ((operator.suffixes || [])[0] || ["l"])[0];
|
||||||
|
if(["l","c","h"].indexOf(prop) !== -1) {
|
||||||
|
colour.oklch[prop] = $tw.utils.parseNumber(operator.operand);
|
||||||
|
}
|
||||||
|
return colour.display().toString();
|
||||||
|
});
|
||||||
|
|
||||||
|
exports["colour-set-alpha"] = makeSerialColourOperator(function (colour, operator, options) {
|
||||||
|
colour.alpha = $tw.utils.parseNumber(operator.operand);
|
||||||
|
return colour.display().toString();
|
||||||
|
});
|
||||||
|
|
||||||
|
exports["colour-composite"] = makeSerialColourOperator(function (colour, operator, options) {
|
||||||
|
// Composite each translucent input colour over the backdrop given in the operand
|
||||||
|
var backdrop = $tw.utils.parseCSSColorObject(operator.operand);
|
||||||
|
if(backdrop && colour.alpha < 1) {
|
||||||
|
var alpha = colour.alpha;
|
||||||
|
colour.alpha = 1;
|
||||||
|
colour = backdrop.mix(colour,alpha,{space: "srgb"});
|
||||||
|
}
|
||||||
|
return colour.display().toString();
|
||||||
|
});
|
||||||
|
|
||||||
|
exports["colour-contrast"] = makeParallelColourOperator(function (colours, operator, options) {
|
||||||
|
var colourContrasts = [];
|
||||||
|
$tw.utils.each(colours,function(colour,index) {
|
||||||
|
if(!colour) {
|
||||||
|
colour = $tw.utils.parseCSSColorObject("white");
|
||||||
|
colours[index] = colour;
|
||||||
|
}
|
||||||
|
if(index > 0) {
|
||||||
|
colourContrasts.push(colour.contrast(colours[index - 1],"DeltaPhi").toString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return colourContrasts;
|
||||||
|
});
|
||||||
|
|
||||||
|
exports["colour-best-contrast"] = makeParallelColourOperator(function (colours, operator, options, originalColours) {
|
||||||
|
var bestContrast = 0,
|
||||||
|
bestColour = null;
|
||||||
|
if(colours.length < 2) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
var targetColour = colours[colours.length - 1];
|
||||||
|
if(!targetColour) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
for(var t=0; t<colours.length; t++) {
|
||||||
|
var colour = colours[t];
|
||||||
|
if(colour) {
|
||||||
|
var contrast = colour.contrast(targetColour,"DeltaPhi");
|
||||||
|
if(contrast > bestContrast) {
|
||||||
|
bestContrast = contrast;
|
||||||
|
bestColour = originalColours[t];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(bestColour) {
|
||||||
|
return [bestColour];
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
exports["colour-interpolate"] = function(source,operator,options) {
|
||||||
|
// Get the colour space suffix
|
||||||
|
var space = ((((operator.suffixes || [])[0] || ["srgb"])[0]) || "").toLowerCase();
|
||||||
|
if(colourSpacesList.indexOf(space) === -1) {
|
||||||
|
space = "lch";
|
||||||
|
}
|
||||||
|
// Get the hue adjuster suffix
|
||||||
|
var hueAdjuster = ((((operator.suffixes || [])[1] || ["shorter"])[0]) || "").toLowerCase();
|
||||||
|
if(hueAdjustersList.indexOf(hueAdjuster) === -1) {
|
||||||
|
hueAdjuster = "shorter";
|
||||||
|
}
|
||||||
|
// Get the colours
|
||||||
|
if(operator.operands.length < 2) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
var colourA = $tw.utils.parseCSSColorObject(operator.operands[0]),
|
||||||
|
colourB = $tw.utils.parseCSSColorObject(operator.operands[1]);
|
||||||
|
if(!colourA || !colourB) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
var rangefn = colourA.range(colourB,{space: space, hue: hueAdjuster});
|
||||||
|
// Cycle through the weights
|
||||||
|
var results = [];
|
||||||
|
source(function(tiddler,title) {
|
||||||
|
var index = $tw.utils.parseNumber(title);
|
||||||
|
var colour = rangefn(index);
|
||||||
|
results.push(colour.display().toString());
|
||||||
|
});
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
function makeSerialColourOperator(fn) {
|
||||||
|
return function (source, operator, options) {
|
||||||
|
var results = [];
|
||||||
|
source(function (tiddler, title) {
|
||||||
|
var c = $tw.utils.parseCSSColorObject(title);
|
||||||
|
if(c) {
|
||||||
|
c = fn(c, operator, options);
|
||||||
|
results.push(c);
|
||||||
|
} else {
|
||||||
|
results.push("");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeParallelColourOperator(fn) {
|
||||||
|
return function (source, operator, options) {
|
||||||
|
var originalColours = [],
|
||||||
|
colours = [];
|
||||||
|
source(function (tiddler, title) {
|
||||||
|
originalColours.push(title);
|
||||||
|
colours.push($tw.utils.parseCSSColorObject(title));
|
||||||
|
});
|
||||||
|
return fn(colours, operator, options, originalColours);
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -13,7 +13,9 @@ Filter operator returning those input titles that pass a subfilter
|
|||||||
Export our filter function
|
Export our filter function
|
||||||
*/
|
*/
|
||||||
exports.filter = function(source,operator,options) {
|
exports.filter = function(source,operator,options) {
|
||||||
var filterFn = options.wiki.compileFilter(operator.operand),
|
var suffixes = operator.suffixes || [],
|
||||||
|
defaultFilterRunPrefix = (suffixes[0] && suffixes[0][0]) || options.defaultFilterRunPrefix || "or",
|
||||||
|
filterFn = options.wiki.compileFilter(operator.operand,{defaultFilterRunPrefix}),
|
||||||
results = [],
|
results = [],
|
||||||
target = operator.prefix !== "!";
|
target = operator.prefix !== "!";
|
||||||
source(function(tiddler,title) {
|
source(function(tiddler,title) {
|
||||||
|
|||||||
@@ -9,69 +9,56 @@ Filter operators for manipulating the current selection list
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Fetch titles from the current list
|
||||||
|
*/
|
||||||
|
const prepare_results = (source) => {
|
||||||
|
const results = [];
|
||||||
|
source((tiddler,title) => results.push(title));
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Order a list
|
Order a list
|
||||||
*/
|
*/
|
||||||
exports.order = function(source,operator,options) {
|
exports.order = function(source,operator,options) {
|
||||||
var results = [];
|
const results = prepare_results(source);
|
||||||
if(operator.operand.toLowerCase() === "reverse") {
|
return operator.operand.toLowerCase() === "reverse" ?
|
||||||
source(function(tiddler,title) {
|
results.reverse() :
|
||||||
results.unshift(title);
|
results;
|
||||||
});
|
|
||||||
} else {
|
|
||||||
source(function(tiddler,title) {
|
|
||||||
results.push(title);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Reverse list
|
Reverse list
|
||||||
*/
|
*/
|
||||||
exports.reverse = function(source,operator,options) {
|
exports.reverse = function(source,operator,options) {
|
||||||
var results = [];
|
return prepare_results(source).reverse();
|
||||||
source(function(tiddler,title) {
|
|
||||||
results.unshift(title);
|
|
||||||
});
|
|
||||||
return results;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
First entry/entries in list
|
First entry/entries in list
|
||||||
*/
|
*/
|
||||||
exports.first = function(source,operator,options) {
|
exports.first = function(source,operator,options) {
|
||||||
var count = $tw.utils.getInt(operator.operand,1),
|
const count = $tw.utils.getInt(operator.operand,1);
|
||||||
results = [];
|
return prepare_results(source).slice(0,count);
|
||||||
source(function(tiddler,title) {
|
|
||||||
results.push(title);
|
|
||||||
});
|
|
||||||
return results.slice(0,count);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Last entry/entries in list
|
Last entry/entries in list
|
||||||
*/
|
*/
|
||||||
exports.last = function(source,operator,options) {
|
exports.last = function(source,operator,options) {
|
||||||
var count = $tw.utils.getInt(operator.operand,1),
|
const count = $tw.utils.getInt(operator.operand,1);
|
||||||
results = [];
|
return count === 0 ?
|
||||||
if(count === 0) return results;
|
[] :
|
||||||
source(function(tiddler,title) {
|
prepare_results(source).slice(-count);
|
||||||
results.push(title);
|
|
||||||
});
|
|
||||||
return results.slice(-count);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
All but the first entry/entries of the list
|
All but the first entry/entries of the list
|
||||||
*/
|
*/
|
||||||
exports.rest = function(source,operator,options) {
|
exports.rest = function(source,operator,options) {
|
||||||
var count = $tw.utils.getInt(operator.operand,1),
|
const count = $tw.utils.getInt(operator.operand,1);
|
||||||
results = [];
|
return prepare_results(source).slice(count);
|
||||||
source(function(tiddler,title) {
|
|
||||||
results.push(title);
|
|
||||||
});
|
|
||||||
return results.slice(count);
|
|
||||||
};
|
};
|
||||||
exports.butfirst = exports.rest;
|
exports.butfirst = exports.rest;
|
||||||
exports.bf = exports.rest;
|
exports.bf = exports.rest;
|
||||||
@@ -80,12 +67,9 @@ exports.bf = exports.rest;
|
|||||||
All but the last entry/entries of the list
|
All but the last entry/entries of the list
|
||||||
*/
|
*/
|
||||||
exports.butlast = function(source,operator,options) {
|
exports.butlast = function(source,operator,options) {
|
||||||
var count = $tw.utils.getInt(operator.operand,1),
|
const count = $tw.utils.getInt(operator.operand,1),
|
||||||
results = [];
|
results = prepare_results(source),
|
||||||
source(function(tiddler,title) {
|
index = count === 0 ? results.length : -count;
|
||||||
results.push(title);
|
|
||||||
});
|
|
||||||
var index = count === 0 ? results.length : -count;
|
|
||||||
return results.slice(0,index);
|
return results.slice(0,index);
|
||||||
};
|
};
|
||||||
exports.bl = exports.butlast;
|
exports.bl = exports.butlast;
|
||||||
@@ -94,22 +78,14 @@ exports.bl = exports.butlast;
|
|||||||
The nth member of the list
|
The nth member of the list
|
||||||
*/
|
*/
|
||||||
exports.nth = function(source,operator,options) {
|
exports.nth = function(source,operator,options) {
|
||||||
var count = $tw.utils.getInt(operator.operand,1),
|
const count = $tw.utils.getInt(operator.operand,1);
|
||||||
results = [];
|
return prepare_results(source).slice(count - 1,count);
|
||||||
source(function(tiddler,title) {
|
|
||||||
results.push(title);
|
|
||||||
});
|
|
||||||
return results.slice(count - 1,count);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The zero based nth member of the list
|
The zero based nth member of the list
|
||||||
*/
|
*/
|
||||||
exports.zth = function(source,operator,options) {
|
exports.zth = function(source,operator,options) {
|
||||||
var count = $tw.utils.getInt(operator.operand,0),
|
const count = $tw.utils.getInt(operator.operand,0);
|
||||||
results = [];
|
return prepare_results(source).slice(count,count + 1);
|
||||||
source(function(tiddler,title) {
|
};
|
||||||
results.push(title);
|
|
||||||
});
|
|
||||||
return results.slice(count,count + 1);
|
|
||||||
};
|
|
||||||
@@ -13,37 +13,22 @@ Filter operator for checking if a title starts with a prefix
|
|||||||
Export our filter function
|
Export our filter function
|
||||||
*/
|
*/
|
||||||
exports.prefix = function(source,operator,options) {
|
exports.prefix = function(source,operator,options) {
|
||||||
var results = [],
|
const results = [],
|
||||||
suffixes = (operator.suffixes || [])[0] || [];
|
suffixes = (operator.suffixes || [])[0] || [],
|
||||||
if(suffixes.indexOf("caseinsensitive") !== -1) {
|
caseInsensitive = suffixes.includes("caseinsensitive"),
|
||||||
var operand = operator.operand.toLowerCase();
|
negate = operator.prefix === "!";
|
||||||
if(operator.prefix === "!") {
|
|
||||||
source(function(tiddler,title) {
|
const operand = caseInsensitive ?
|
||||||
if(title.toLowerCase().substr(0,operand.length) !== operand) {
|
operator.operand.toLowerCase() :
|
||||||
results.push(title);
|
operator.operand;
|
||||||
}
|
|
||||||
});
|
source((tiddler,title) => {
|
||||||
} else {
|
const value = caseInsensitive ? title.toLowerCase() : title,
|
||||||
source(function(tiddler,title) {
|
matches = value.startsWith(operand);
|
||||||
if(title.toLowerCase().substr(0,operand.length) === operand) {
|
if(negate ? !matches : matches) {
|
||||||
results.push(title);
|
results.push(title);
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} else {
|
});
|
||||||
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;
|
return results;
|
||||||
};
|
};
|
||||||
@@ -14,13 +14,13 @@ Export our filter function
|
|||||||
*/
|
*/
|
||||||
exports.sortsub = function(source,operator,options) {
|
exports.sortsub = function(source,operator,options) {
|
||||||
// Compile the subfilter
|
// Compile the subfilter
|
||||||
var filterFn = options.wiki.compileFilter(operator.operand);
|
let filterFn = options.wiki.compileFilter(operator.operand);
|
||||||
// Collect the input titles and the corresponding sort keys
|
// Collect the input titles and the corresponding sort keys
|
||||||
var inputTitles = [],
|
let inputTitles = [],
|
||||||
sortKeys = [];
|
sortKeys = [];
|
||||||
source(function(tiddler,title) {
|
source(function(tiddler,title) {
|
||||||
inputTitles.push(title);
|
inputTitles.push(title);
|
||||||
var r = filterFn.call(options.wiki,function(iterator) {
|
let r = filterFn.call(options.wiki,function(iterator) {
|
||||||
iterator(options.wiki.getTiddler(title),title);
|
iterator(options.wiki.getTiddler(title),title);
|
||||||
},options.widget.makeFakeWidgetWithVariables({
|
},options.widget.makeFakeWidgetWithVariables({
|
||||||
"currentTiddler": "" + title,
|
"currentTiddler": "" + title,
|
||||||
@@ -29,17 +29,12 @@ exports.sortsub = function(source,operator,options) {
|
|||||||
sortKeys.push(r[0] || "");
|
sortKeys.push(r[0] || "");
|
||||||
});
|
});
|
||||||
// Rather than sorting the titles array, we'll sort the indexes so that we can consult both arrays
|
// Rather than sorting the titles array, we'll sort the indexes so that we can consult both arrays
|
||||||
var indexes = new Array(inputTitles.length);
|
let indexes = Array.from(inputTitles.keys());
|
||||||
for(var t=0; t<inputTitles.length; t++) {
|
|
||||||
indexes[t] = t;
|
|
||||||
}
|
|
||||||
// Sort the indexes
|
// Sort the indexes
|
||||||
var compareFn = $tw.utils.makeCompareFunction(operator.suffix,{defaultType: "string",invert: operator.prefix === "!"});
|
let compareFn = $tw.utils.makeCompareFunction(operator.suffix,{defaultType: "string",invert: operator.prefix === "!"});
|
||||||
indexes = indexes.sort(function(a,b) {
|
indexes = indexes.sort((a,b) => compareFn(sortKeys[a],sortKeys[b]));
|
||||||
return compareFn(sortKeys[a],sortKeys[b]);
|
|
||||||
});
|
|
||||||
// Make the results array in order
|
// Make the results array in order
|
||||||
var results = [];
|
let results = [];
|
||||||
$tw.utils.each(indexes,function(index) {
|
$tw.utils.each(indexes,function(index) {
|
||||||
results.push(inputTitles[index]);
|
results.push(inputTitles[index]);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -91,22 +91,35 @@ function diffLineWordMode(text1,text2,mode) {
|
|||||||
return diffs;
|
return diffs;
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.makepatches = function(source,operator,options) {
|
exports.makepatches = function(source, operator, options) {
|
||||||
var suffix = operator.suffix || "",
|
const suffixes = operator.suffixes || [],
|
||||||
result = [];
|
[modeArg = [], formatArg = []] = suffixes,
|
||||||
|
modeSuffix = modeArg[0] || operator.suffix || "",
|
||||||
source(function(tiddler,title) {
|
mode = ["lines", "words"].includes(modeSuffix) ? modeSuffix : "",
|
||||||
let diffs, patches;
|
isJson = formatArg[0] === "json",
|
||||||
if(suffix === "lines" || suffix === "words") {
|
results = [];
|
||||||
diffs = diffLineWordMode(title,operator.operand,suffix);
|
|
||||||
patches = dmp.patchMake(title,diffs);
|
source((tiddler, title) => {
|
||||||
|
if (isJson) {
|
||||||
|
const diffs = (mode === "lines" || mode === "words")
|
||||||
|
? diffLineWordMode(title, operator.operand, mode)
|
||||||
|
: dmp.diffMain(title, operator.operand);
|
||||||
|
|
||||||
|
const jsonOutput = diffs.map(([typeCode, text]) => ({
|
||||||
|
type: typeCode === 1 ? "insert" : (typeCode === -1 ? "delete" : "equal"),
|
||||||
|
text
|
||||||
|
}));
|
||||||
|
results.push(JSON.stringify(jsonOutput));
|
||||||
} else {
|
} else {
|
||||||
patches = dmp.patchMake(title,operator.operand);
|
const patches = (mode === "lines" || mode === "words")
|
||||||
|
? dmp.patchMake(title, diffLineWordMode(title, operator.operand, mode))
|
||||||
|
: dmp.patchMake(title, operator.operand);
|
||||||
|
|
||||||
|
results.push(dmp.patchToText(patches));
|
||||||
}
|
}
|
||||||
Array.prototype.push.apply(result,[dmp.patchToText(patches)]);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return results;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.applypatches = makeStringBinaryOperator(
|
exports.applypatches = makeStringBinaryOperator(
|
||||||
@@ -235,4 +248,4 @@ exports.charcode = function(source,operator,options) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
return [chars.join("")];
|
return [chars.join("")];
|
||||||
};
|
};
|
||||||
@@ -13,11 +13,14 @@ Filter operator returning its operand evaluated as a filter
|
|||||||
Export our filter function
|
Export our filter function
|
||||||
*/
|
*/
|
||||||
exports.subfilter = function(source,operator,options) {
|
exports.subfilter = function(source,operator,options) {
|
||||||
var list = options.wiki.filterTiddlers(operator.operand,options.widget,source);
|
var suffixes = operator.suffixes || [],
|
||||||
|
defaultFilterRunPrefix = (suffixes[0] && suffixes[0][0]) || options.defaultFilterRunPrefix || "or";
|
||||||
|
var list = options.wiki.filterTiddlers(operator.operand,options.widget,source,{defaultFilterRunPrefix});
|
||||||
if(operator.prefix === "!") {
|
if(operator.prefix === "!") {
|
||||||
var results = [];
|
const results = [],
|
||||||
source(function(tiddler,title) {
|
listSet = new Set(list);
|
||||||
if(list.indexOf(title) === -1) {
|
source((tiddler,title) => {
|
||||||
|
if(!listSet.has(title)) {
|
||||||
results.push(title);
|
results.push(title);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -13,41 +13,27 @@ Filter operator for checking if a title ends with a suffix
|
|||||||
Export our filter function
|
Export our filter function
|
||||||
*/
|
*/
|
||||||
exports.suffix = function(source,operator,options) {
|
exports.suffix = function(source,operator,options) {
|
||||||
var results = [],
|
const results = [],
|
||||||
suffixes = (operator.suffixes || [])[0] || [];
|
suffixes = (operator.suffixes || [])[0] || [];
|
||||||
|
|
||||||
if(!operator.operand) {
|
if(!operator.operand) {
|
||||||
source(function(tiddler,title) {
|
source((tiddler,title) => {
|
||||||
results.push(title);
|
results.push(title);
|
||||||
});
|
});
|
||||||
} else if(suffixes.indexOf("caseinsensitive") !== -1) {
|
return results;
|
||||||
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 {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const caseInsensitive = suffixes.indexOf("caseinsensitive") !== -1,
|
||||||
|
negate = operator.prefix === "!",
|
||||||
|
operand = caseInsensitive ? operator.operand.toLowerCase() : operator.operand;
|
||||||
|
|
||||||
|
source((tiddler,title) => {
|
||||||
|
const value = caseInsensitive ? title.toLowerCase() : title,
|
||||||
|
matches = value.endsWith(operand);
|
||||||
|
if(negate ? !matches : matches) {
|
||||||
|
results.push(title);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,12 +22,11 @@ exports.tag = function(source,operator,options) {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Old semantics:
|
// Old semantics:
|
||||||
var tiddlers;
|
|
||||||
if(operator.prefix === "!") {
|
if(operator.prefix === "!") {
|
||||||
// Returns a copy of the input if operator.operand is missing
|
// Returns a copy of the input if operator.operand is missing
|
||||||
tiddlers = options.wiki.getTiddlersWithTag(operator.operand);
|
const excludeTagSet = new Set(options.wiki.getTiddlersWithTag(operator.operand));
|
||||||
source(function(tiddler,title) {
|
source(function(tiddler,title) {
|
||||||
if(tiddlers.indexOf(title) === -1) {
|
if(!excludeTagSet.has(title)) {
|
||||||
results.push(title);
|
results.push(title);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -39,9 +38,9 @@ exports.tag = function(source,operator,options) {
|
|||||||
return indexedResults;
|
return indexedResults;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tiddlers = options.wiki.getTiddlersWithTag(operator.operand);
|
const includeTagSet = new Set(options.wiki.getTiddlersWithTag(operator.operand));
|
||||||
source(function(tiddler,title) {
|
source(function(tiddler,title) {
|
||||||
if(tiddlers.indexOf(title) !== -1) {
|
if(includeTagSet.has(title)) {
|
||||||
results.push(title);
|
results.push(title);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,20 +11,18 @@ Extended filter operators to manipulate the current list.
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Fetch titles from the current list
|
Fetch titles from the current list
|
||||||
*/
|
*/
|
||||||
var prepare_results = function (source) {
|
const prepare_results = (source) => {
|
||||||
var results = [];
|
const results = [];
|
||||||
source(function (tiddler, title) {
|
source((tiddler,title) => results.push(title));
|
||||||
results.push(title);
|
|
||||||
});
|
|
||||||
return results;
|
return results;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Moves a number of items from the tail of the current list before the item named in the operand
|
Moves a number of items from the tail of the current list before the item named in the operand
|
||||||
*/
|
*/
|
||||||
exports.putbefore = function (source, operator) {
|
exports.putbefore = function(source,operator) {
|
||||||
var results = prepare_results(source),
|
const results = prepare_results(source),
|
||||||
index = results.indexOf(operator.operand),
|
index = results.indexOf(operator.operand),
|
||||||
count = $tw.utils.getInt(operator.suffix,1);
|
count = $tw.utils.getInt(operator.suffix,1);
|
||||||
return (index === -1) ?
|
return (index === -1) ?
|
||||||
@@ -34,9 +32,9 @@ exports.putbefore = function (source, operator) {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Moves a number of items from the tail of the current list after the item named in the operand
|
Moves a number of items from the tail of the current list after the item named in the operand
|
||||||
*/
|
*/
|
||||||
exports.putafter = function (source, operator) {
|
exports.putafter = function(source,operator) {
|
||||||
var results = prepare_results(source),
|
const results = prepare_results(source),
|
||||||
index = results.indexOf(operator.operand),
|
index = results.indexOf(operator.operand),
|
||||||
count = $tw.utils.getInt(operator.suffix,1);
|
count = $tw.utils.getInt(operator.suffix,1);
|
||||||
return (index === -1) ?
|
return (index === -1) ?
|
||||||
@@ -46,9 +44,9 @@ exports.putafter = function (source, operator) {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Replaces the item named in the operand with a number of items from the tail of the current list
|
Replaces the item named in the operand with a number of items from the tail of the current list
|
||||||
*/
|
*/
|
||||||
exports.replace = function (source, operator) {
|
exports.replace = function(source,operator) {
|
||||||
var results = prepare_results(source),
|
const results = prepare_results(source),
|
||||||
index = results.indexOf(operator.operand),
|
index = results.indexOf(operator.operand),
|
||||||
count = $tw.utils.getInt(operator.suffix,1);
|
count = $tw.utils.getInt(operator.suffix,1);
|
||||||
return (index === -1) ?
|
return (index === -1) ?
|
||||||
@@ -58,39 +56,39 @@ exports.replace = function (source, operator) {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Moves a number of items from the tail of the current list to the head of the list
|
Moves a number of items from the tail of the current list to the head of the list
|
||||||
*/
|
*/
|
||||||
exports.putfirst = function (source, operator) {
|
exports.putfirst = function(source,operator) {
|
||||||
var results = prepare_results(source),
|
const results = prepare_results(source),
|
||||||
count = $tw.utils.getInt(operator.suffix,1);
|
count = $tw.utils.getInt(operator.suffix,1);
|
||||||
return results.slice(-count).concat(results.slice(0, -count));
|
return [...results.slice(-count), ...results.slice(0, -count)];
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Moves a number of items from the head of the current list to the tail of the list
|
Moves a number of items from the head of the current list to the tail of the list
|
||||||
*/
|
*/
|
||||||
exports.putlast = function (source, operator) {
|
exports.putlast = function(source,operator) {
|
||||||
var results = prepare_results(source),
|
const results = prepare_results(source),
|
||||||
count = $tw.utils.getInt(operator.suffix,1);
|
count = $tw.utils.getInt(operator.suffix,1);
|
||||||
return results.slice(count).concat(results.slice(0, count));
|
return [...results.slice(count), ...results.slice(0, count)];
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Moves the item named in the operand a number of places forward or backward in the list
|
Moves the item named in the operand a number of places forward or backward in the list
|
||||||
*/
|
*/
|
||||||
exports.move = function (source, operator) {
|
exports.move = function(source,operator) {
|
||||||
var results = prepare_results(source),
|
const results = prepare_results(source),
|
||||||
index = results.indexOf(operator.operand),
|
index = results.indexOf(operator.operand),
|
||||||
count = $tw.utils.getInt(operator.suffix,1),
|
count = $tw.utils.getInt(operator.suffix,1),
|
||||||
marker = results.splice(index, 1),
|
marker = results.splice(index, 1),
|
||||||
offset = (index + count) > 0 ? index + count : 0;
|
offset = (index + count) > 0 ? index + count : 0;
|
||||||
return results.slice(0, offset).concat(marker).concat(results.slice(offset));
|
return results.slice(0, offset).concat(marker).concat(results.slice(offset));
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Returns the items from the current list that are after the item named in the operand
|
Returns the items from the current list that are after the item named in the operand
|
||||||
*/
|
*/
|
||||||
exports.allafter = function (source, operator) {
|
exports.allafter = function(source,operator) {
|
||||||
var results = prepare_results(source),
|
const results = prepare_results(source),
|
||||||
index = results.indexOf(operator.operand);
|
index = results.indexOf(operator.operand);
|
||||||
return (index === -1) ? [] :
|
return (index === -1) ? [] :
|
||||||
(operator.suffix) ? results.slice(index) :
|
(operator.suffix) ? results.slice(index) :
|
||||||
@@ -99,9 +97,9 @@ exports.allafter = function (source, operator) {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Returns the items from the current list that are before the item named in the operand
|
Returns the items from the current list that are before the item named in the operand
|
||||||
*/
|
*/
|
||||||
exports.allbefore = function (source, operator) {
|
exports.allbefore = function(source,operator) {
|
||||||
var results = prepare_results(source),
|
const results = prepare_results(source),
|
||||||
index = results.indexOf(operator.operand);
|
index = results.indexOf(operator.operand);
|
||||||
return (index === -1) ? [] :
|
return (index === -1) ? [] :
|
||||||
(operator.suffix) ? results.slice(0, index + 1) :
|
(operator.suffix) ? results.slice(0, index + 1) :
|
||||||
@@ -110,9 +108,9 @@ exports.allbefore = function (source, operator) {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Appends the items listed in the operand array to the tail of the current list
|
Appends the items listed in the operand array to the tail of the current list
|
||||||
*/
|
*/
|
||||||
exports.append = function (source, operator) {
|
exports.append = function(source,operator) {
|
||||||
var append = $tw.utils.parseStringArray(operator.operand, "true"),
|
const append = $tw.utils.parseStringArray(operator.operand,"true"),
|
||||||
results = prepare_results(source),
|
results = prepare_results(source),
|
||||||
count = parseInt(operator.suffix) || append.length;
|
count = parseInt(operator.suffix) || append.length;
|
||||||
return (append.length === 0) ? results :
|
return (append.length === 0) ? results :
|
||||||
@@ -122,9 +120,9 @@ exports.append = function (source, operator) {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Prepends the items listed in the operand array to the head of the current list
|
Prepends the items listed in the operand array to the head of the current list
|
||||||
*/
|
*/
|
||||||
exports.prepend = function (source, operator) {
|
exports.prepend = function(source,operator) {
|
||||||
var prepend = $tw.utils.parseStringArray(operator.operand, "true"),
|
const prepend = $tw.utils.parseStringArray(operator.operand,"true"),
|
||||||
results = prepare_results(source),
|
results = prepare_results(source),
|
||||||
count = $tw.utils.getInt(operator.suffix,prepend.length);
|
count = $tw.utils.getInt(operator.suffix,prepend.length);
|
||||||
return (prepend.length === 0) ? results :
|
return (prepend.length === 0) ? results :
|
||||||
@@ -134,21 +132,19 @@ exports.prepend = function (source, operator) {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Returns all items from the current list except the items listed in the operand array
|
Returns all items from the current list except the items listed in the operand array
|
||||||
*/
|
*/
|
||||||
exports.remove = function (source, operator) {
|
exports.remove = function(source, operator) {
|
||||||
var array = $tw.utils.parseStringArray(operator.operand, "true"),
|
const array = $tw.utils.parseStringArray(operator.operand, "true"),
|
||||||
results = prepare_results(source),
|
results = prepare_results(source);
|
||||||
count = parseInt(operator.suffix) || array.length,
|
|
||||||
p,
|
if(array.length === 0) {
|
||||||
len,
|
return results;
|
||||||
index;
|
}
|
||||||
len = array.length - 1;
|
const count = parseInt(operator.suffix, 10) || array.length,
|
||||||
for(p = 0; p < count; ++p) {
|
targetItems = operator.prefix ? array.slice(-count).reverse() : array.slice(0, count);
|
||||||
if(operator.prefix) {
|
|
||||||
index = results.indexOf(array[len - p]);
|
for(const item of targetItems) {
|
||||||
} else {
|
const index = results.indexOf(item);
|
||||||
index = results.indexOf(array[p]);
|
|
||||||
}
|
|
||||||
if(index !== -1) {
|
if(index !== -1) {
|
||||||
results.splice(index, 1);
|
results.splice(index, 1);
|
||||||
}
|
}
|
||||||
@@ -158,40 +154,38 @@ exports.remove = function (source, operator) {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Returns all items from the current list sorted in the order of the items in the operand array
|
Returns all items from the current list sorted in the order of the items in the operand array
|
||||||
*/
|
*/
|
||||||
exports.sortby = function (source, operator) {
|
exports.sortby = function(source,operator) {
|
||||||
var results = prepare_results(source);
|
const results = prepare_results(source);
|
||||||
if(!results || results.length < 2) {
|
if(!results || results.length < 2) {
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
var lookup = $tw.utils.parseStringArray(operator.operand, "true");
|
const lookup = $tw.utils.parseStringArray(operator.operand,"true"),
|
||||||
results.sort(function (a, b) {
|
// The "end" suffix places unlisted titles last, the default is first
|
||||||
return lookup.indexOf(a) - lookup.indexOf(b);
|
unlisted = operator.suffix === "end" ? lookup.length : -1,
|
||||||
});
|
position = (title) => {
|
||||||
return results;
|
const index = lookup.indexOf(title);
|
||||||
|
return index === -1 ? unlisted : index;
|
||||||
|
};
|
||||||
|
return results.sort((a,b) => position(a) - position(b));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Removes all duplicate items from the current list
|
Removes all duplicate items from the current list
|
||||||
*/
|
*/
|
||||||
exports.unique = function (source, operator) {
|
exports.unique = function(source, operator) {
|
||||||
var results = prepare_results(source);
|
return Array.from(new Set(prepare_results(source)));
|
||||||
var set = results.reduce(function (a, b) {
|
|
||||||
if(a.indexOf(b) < 0) {
|
|
||||||
a.push(b);
|
|
||||||
}
|
|
||||||
return a;
|
|
||||||
}, []);
|
|
||||||
return set;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var cycleValueInArray = function(results,operands,stepSize) {
|
const cycleValueInArray = function(results,operands,stepSize) {
|
||||||
var resultsIndex,
|
let resultsIndex,
|
||||||
step = stepSize || 1,
|
step = stepSize || 1,
|
||||||
i = 0,
|
i = 0,
|
||||||
opLength = operands.length,
|
|
||||||
nextOperandIndex;
|
nextOperandIndex;
|
||||||
for(i; i < opLength; i++) {
|
const opLength = operands.length;
|
||||||
|
|
||||||
|
for(; i < opLength; i++) {
|
||||||
resultsIndex = results.indexOf(operands[i]);
|
resultsIndex = results.indexOf(operands[i]);
|
||||||
if(resultsIndex !== -1) {
|
if(resultsIndex !== -1) {
|
||||||
break;
|
break;
|
||||||
@@ -213,18 +207,19 @@ var cycleValueInArray = function(results,operands,stepSize) {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Toggles an item in the current list.
|
Toggles an item in the current list.
|
||||||
*/
|
*/
|
||||||
exports.toggle = function(source,operator) {
|
exports.toggle = function(source,operator) {
|
||||||
return cycleValueInArray(prepare_results(source),operator.operands);
|
return cycleValueInArray(prepare_results(source),operator.operands);
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.cycle = function(source,operator) {
|
exports.cycle = function(source,operator) {
|
||||||
var results = prepare_results(source),
|
const results = prepare_results(source),
|
||||||
operands = (operator.operand.length ? $tw.utils.parseStringArray(operator.operand, "true") : [""]),
|
operands = operator.operand.length ? $tw.utils.parseStringArray(operator.operand,"true") : [""];
|
||||||
step = $tw.utils.getInt(operator.operands[1]||"",1);
|
let step = $tw.utils.getInt(operator.operands[1] || "",1);
|
||||||
|
|
||||||
if(step < 0) {
|
if(step < 0) {
|
||||||
operands.reverse();
|
operands.reverse();
|
||||||
step = Math.abs(step);
|
step = Math.abs(step);
|
||||||
}
|
}
|
||||||
return cycleValueInArray(results,operands,step);
|
return cycleValueInArray(results,operands,step);
|
||||||
};
|
};
|
||||||
@@ -88,10 +88,11 @@ BackSubIndexer.prototype.update = function(updateDescriptor) {
|
|||||||
var newTargets = [],
|
var newTargets = [],
|
||||||
oldTargets = [],
|
oldTargets = [],
|
||||||
self = this;
|
self = this;
|
||||||
if(updateDescriptor.old.exists) {
|
// System tiddlers are never indexed as sources, matching the _init() scan
|
||||||
|
if(updateDescriptor.old.exists && !this.wiki.isSystemTiddler(updateDescriptor.old.tiddler.fields.title)) {
|
||||||
oldTargets = this._getTarget(updateDescriptor.old.tiddler);
|
oldTargets = this._getTarget(updateDescriptor.old.tiddler);
|
||||||
}
|
}
|
||||||
if(updateDescriptor.new.exists) {
|
if(updateDescriptor.new.exists && !this.wiki.isSystemTiddler(updateDescriptor.new.tiddler.fields.title)) {
|
||||||
newTargets = this._getTarget(updateDescriptor.new.tiddler);
|
newTargets = this._getTarget(updateDescriptor.new.tiddler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,25 +26,26 @@ exports.params = [
|
|||||||
Run the macro
|
Run the macro
|
||||||
*/
|
*/
|
||||||
exports.run = function(target,fallbackTarget,colourA,colourB) {
|
exports.run = function(target,fallbackTarget,colourA,colourB) {
|
||||||
var rgbTarget = $tw.utils.parseCSSColor(target) || $tw.utils.parseCSSColor(fallbackTarget);
|
var rgbTarget = $tw.utils.parseCSSColorObject(target) || $tw.utils.parseCSSColorObject(fallbackTarget);
|
||||||
if(!rgbTarget) {
|
if(!rgbTarget) {
|
||||||
return colourA;
|
return colourA;
|
||||||
}
|
}
|
||||||
var rgbColourA = $tw.utils.parseCSSColor(colourA),
|
var rgbColourA = $tw.utils.parseCSSColorObject(colourA),
|
||||||
rgbColourB = $tw.utils.parseCSSColor(colourB);
|
rgbColourB = $tw.utils.parseCSSColorObject(colourB);
|
||||||
if(rgbColourA && !rgbColourB) {
|
if(rgbColourA && !rgbColourB) {
|
||||||
return rgbColourA;
|
return colourA;
|
||||||
}
|
}
|
||||||
if(rgbColourB && !rgbColourA) {
|
if(rgbColourB && !rgbColourA) {
|
||||||
return rgbColourB;
|
return colourB;
|
||||||
}
|
}
|
||||||
if(!rgbColourA && !rgbColourB) {
|
if(!rgbColourA && !rgbColourB) {
|
||||||
// If neither colour is readable, return a crude inverse of the target
|
// If neither colour is readable, return a crude inverse of the target
|
||||||
return [255 - rgbTarget[0],255 - rgbTarget[1],255 - rgbTarget[2],rgbTarget[3]];
|
rgbTarget.srgb.r = 1 - rgbTarget.srgb.r;
|
||||||
|
rgbTarget.srgb.g = 1 - rgbTarget.srgb.g;
|
||||||
|
rgbTarget.srgb.b = 1 - rgbTarget.srgb.b;
|
||||||
|
return rgbTarget.display();
|
||||||
}
|
}
|
||||||
// Colour brightness formula derived from http://www.w3.org/WAI/ER/WD-AERT/#color-contrast
|
var aContrast = rgbColourA.contrast(rgbTarget,"DeltaPhi"),
|
||||||
var brightnessTarget = rgbTarget[0] * 0.299 + rgbTarget[1] * 0.587 + rgbTarget[2] * 0.114,
|
bContrast = rgbColourB.contrast(rgbTarget,"DeltaPhi");
|
||||||
brightnessA = rgbColourA[0] * 0.299 + rgbColourA[1] * 0.587 + rgbColourA[2] * 0.114,
|
return aContrast > bContrast ? colourA : colourB;
|
||||||
brightnessB = rgbColourB[0] * 0.299 + rgbColourB[1] * 0.587 + rgbColourB[2] * 0.114;
|
|
||||||
return Math.abs(brightnessTarget - brightnessA) > Math.abs(brightnessTarget - brightnessB) ? colourA : colourB;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ exports.parseMacroInvocationAsTransclusion = function(source,pos) {
|
|||||||
orderedAttributes: []
|
orderedAttributes: []
|
||||||
};
|
};
|
||||||
// Define our regexps
|
// Define our regexps
|
||||||
var reVarName = /([^\s>"'=:]+)/y;
|
var reVarName = /([^\s>"'=]+)/y;
|
||||||
// Skip whitespace
|
// Skip whitespace
|
||||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||||
// Look for a double opening angle bracket
|
// Look for a double opening angle bracket
|
||||||
@@ -269,7 +269,7 @@ exports.parseMVVReferenceAsTransclusion = function(source,pos) {
|
|||||||
orderedAttributes: []
|
orderedAttributes: []
|
||||||
};
|
};
|
||||||
// Define our regexps
|
// Define our regexps
|
||||||
var reVarName = /([^\s>"'=:)]+)/y;
|
var reVarName = /([^\s>"'=)]+)/y;
|
||||||
// Skip whitespace
|
// Skip whitespace
|
||||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||||
// Look for a double opening parenthesis
|
// Look for a double opening parenthesis
|
||||||
@@ -528,67 +528,79 @@ exports.parseAttribute = function(source,pos) {
|
|||||||
pos = token.end;
|
pos = token.end;
|
||||||
// Skip whitespace
|
// Skip whitespace
|
||||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||||
// Look for a string literal
|
do {
|
||||||
var stringLiteral = $tw.utils.parseStringLiteral(source,pos);
|
// Look for a string literal
|
||||||
if(stringLiteral) {
|
var stringLiteral = $tw.utils.parseStringLiteral(source,pos);
|
||||||
pos = stringLiteral.end;
|
if(stringLiteral) {
|
||||||
node.type = "string";
|
pos = stringLiteral.end;
|
||||||
node.value = stringLiteral.value;
|
node.type = "string";
|
||||||
} else {
|
node.value = stringLiteral.value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Look for a filtered value
|
// Look for a filtered value
|
||||||
var filteredValue = $tw.utils.parseTokenRegExp(source,pos,reFilteredValue);
|
var filteredValue = $tw.utils.parseTokenRegExp(source,pos,reFilteredValue);
|
||||||
if(filteredValue) {
|
if(filteredValue) {
|
||||||
pos = filteredValue.end;
|
pos = filteredValue.end;
|
||||||
node.type = "filtered";
|
node.type = "filtered";
|
||||||
node.filter = filteredValue.match[1];
|
node.filter = filteredValue.match[1];
|
||||||
} else {
|
break;
|
||||||
// Look for an indirect value
|
|
||||||
var indirectValue = $tw.utils.parseTokenRegExp(source,pos,reIndirectValue);
|
|
||||||
if(indirectValue) {
|
|
||||||
pos = indirectValue.end;
|
|
||||||
node.type = "indirect";
|
|
||||||
node.textReference = indirectValue.match[1];
|
|
||||||
} else {
|
|
||||||
// Look for a macro invocation value
|
|
||||||
var macroInvocation = $tw.utils.parseMacroInvocationAsTransclusion(source,pos);
|
|
||||||
if(macroInvocation) {
|
|
||||||
pos = macroInvocation.end;
|
|
||||||
node.type = "macro";
|
|
||||||
node.value = macroInvocation;
|
|
||||||
} else {
|
|
||||||
// Look for an MVV reference value
|
|
||||||
var mvvReference = $tw.utils.parseMVVReferenceAsTransclusion(source,pos);
|
|
||||||
if(mvvReference) {
|
|
||||||
pos = mvvReference.end;
|
|
||||||
node.type = "macro";
|
|
||||||
node.value = mvvReference;
|
|
||||||
node.isMVV = true;
|
|
||||||
} else {
|
|
||||||
var substitutedValue = $tw.utils.parseTokenRegExp(source,pos,reSubstitutedValue);
|
|
||||||
if(substitutedValue) {
|
|
||||||
pos = substitutedValue.end;
|
|
||||||
node.type = "substituted";
|
|
||||||
node.rawValue = substitutedValue.match[1] || substitutedValue.match[2];
|
|
||||||
} else {
|
|
||||||
// Look for a unquoted value
|
|
||||||
var unquotedValue = $tw.utils.parseTokenRegExp(source,pos,reUnquotedAttribute);
|
|
||||||
if(unquotedValue) {
|
|
||||||
pos = unquotedValue.end;
|
|
||||||
node.type = "string";
|
|
||||||
node.value = unquotedValue.match[1];
|
|
||||||
} else if(source.charAt(pos) === "<" && source.charAt(pos + 1) === "<" && source.indexOf(">>",pos) !== -1) {
|
|
||||||
// Value looks like a macro invocation (starts with << with a closing >> ahead) but does not parse as one. Return null so the enclosing tag fails to parse rather than silently binding the attribute to "true" and treating the remainder as further attributes (restores v5.3.8 behaviour)
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
node.type = "string";
|
|
||||||
node.value = "true";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// Look for an indirect value
|
||||||
|
var indirectValue = $tw.utils.parseTokenRegExp(source,pos,reIndirectValue);
|
||||||
|
if(indirectValue) {
|
||||||
|
pos = indirectValue.end;
|
||||||
|
node.type = "indirect";
|
||||||
|
node.textReference = indirectValue.match[1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for a macro invocation value
|
||||||
|
var macroInvocation = $tw.utils.parseMacroInvocationAsTransclusion(source,pos);
|
||||||
|
if(macroInvocation) {
|
||||||
|
pos = macroInvocation.end;
|
||||||
|
node.type = "macro";
|
||||||
|
node.value = macroInvocation;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for an MVV reference value
|
||||||
|
var mvvReference = $tw.utils.parseMVVReferenceAsTransclusion(source,pos);
|
||||||
|
if(mvvReference) {
|
||||||
|
pos = mvvReference.end;
|
||||||
|
node.type = "macro";
|
||||||
|
node.value = mvvReference;
|
||||||
|
node.isMVV = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for a substituted value
|
||||||
|
var substitutedValue = $tw.utils.parseTokenRegExp(source,pos,reSubstitutedValue);
|
||||||
|
if(substitutedValue) {
|
||||||
|
pos = substitutedValue.end;
|
||||||
|
node.type = "substituted";
|
||||||
|
node.rawValue = substitutedValue.match[1] || substitutedValue.match[2];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for a unquoted value
|
||||||
|
var unquotedValue = $tw.utils.parseTokenRegExp(source,pos,reUnquotedAttribute);
|
||||||
|
if(unquotedValue) {
|
||||||
|
pos = unquotedValue.end;
|
||||||
|
node.type = "string";
|
||||||
|
node.value = unquotedValue.match[1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(source.charAt(pos) === "<" && source.charAt(pos + 1) === "<" && source.indexOf(">>",pos) !== -1) {
|
||||||
|
// Value looks like a macro invocation (starts with << with a closing >> ahead) but does not parse as one. Return null so the enclosing tag fails to parse rather than silently binding the attribute to "true" and treating the remainder as further attributes (restores v5.3.8 behaviour)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
node.type = "string";
|
||||||
|
node.value = "true";
|
||||||
|
} while(false);
|
||||||
} else {
|
} else {
|
||||||
// If there is no equals sign or colon, then this is an attribute with no value, defaulting to "true"
|
// If there is no equals sign or colon, then this is an attribute with no value, defaulting to "true"
|
||||||
node.type = "string";
|
node.type = "string";
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ exports.init = function(parser) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
exports.parse = function() {
|
exports.parse = function() {
|
||||||
var reEnd = /(\r?\n```$)/mg;
|
var reEnd = /(^|\r?\n)```$/mg;
|
||||||
var languageStart = this.parser.pos + 3,
|
var languageStart = this.parser.pos + 3,
|
||||||
languageEnd = languageStart + this.match[1].length;
|
languageEnd = languageStart + this.match[1].length;
|
||||||
// Move past the match
|
// Move past the match
|
||||||
|
|||||||
@@ -31,13 +31,16 @@ exports.parse = function() {
|
|||||||
reEnd.lastIndex = this.parser.pos;
|
reEnd.lastIndex = this.parser.pos;
|
||||||
var match = reEnd.exec(this.parser.source),
|
var match = reEnd.exec(this.parser.source),
|
||||||
text,
|
text,
|
||||||
start = this.parser.pos;
|
start = this.parser.pos,
|
||||||
|
textEnd;
|
||||||
// Process the text
|
// Process the text
|
||||||
if(match) {
|
if(match) {
|
||||||
text = this.parser.source.substring(this.parser.pos,match.index);
|
text = this.parser.source.substring(this.parser.pos,match.index);
|
||||||
|
textEnd = match.index;
|
||||||
this.parser.pos = match.index + match[0].length;
|
this.parser.pos = match.index + match[0].length;
|
||||||
} else {
|
} else {
|
||||||
text = this.parser.source.substr(this.parser.pos);
|
text = this.parser.source.substr(this.parser.pos);
|
||||||
|
textEnd = this.parser.sourceLength;
|
||||||
this.parser.pos = this.parser.sourceLength;
|
this.parser.pos = this.parser.sourceLength;
|
||||||
}
|
}
|
||||||
return [{
|
return [{
|
||||||
@@ -47,7 +50,7 @@ exports.parse = function() {
|
|||||||
type: "text",
|
type: "text",
|
||||||
text: text,
|
text: text,
|
||||||
start: start,
|
start: start,
|
||||||
end: this.parser.pos
|
end: textEnd
|
||||||
}]
|
}]
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ exports.parse = function() {
|
|||||||
this.parser.pos = this.matchRegExp.lastIndex;
|
this.parser.pos = this.matchRegExp.lastIndex;
|
||||||
// Create the link unless it is suppressed
|
// Create the link unless it is suppressed
|
||||||
if(this.match[0].substr(0,1) === "~") {
|
if(this.match[0].substr(0,1) === "~") {
|
||||||
return [{type: "text", text: this.match[0].substr(1), start: start, end: this.parser.pos}];
|
// Start after the suppressing "~" so the span matches the plain text
|
||||||
|
return [{type: "text", text: this.match[0].substr(1), start: start + 1, end: this.parser.pos}];
|
||||||
} else {
|
} else {
|
||||||
return [{
|
return [{
|
||||||
type: "element",
|
type: "element",
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ exports.parse = function() {
|
|||||||
// Parse the filter terminated by a line break
|
// Parse the filter terminated by a line break
|
||||||
var reMatch = /(.*)(?:$|\r?\n)/mg;
|
var reMatch = /(.*)(?:$|\r?\n)/mg;
|
||||||
reMatch.lastIndex = this.parser.pos;
|
reMatch.lastIndex = this.parser.pos;
|
||||||
var filterStart = this.parser.source;
|
var filterStart = this.parser.pos;
|
||||||
var match = reMatch.exec(this.parser.source);
|
var match = reMatch.exec(this.parser.source);
|
||||||
this.parser.pos = reMatch.lastIndex;
|
this.parser.pos = reMatch.lastIndex;
|
||||||
// Parse tree nodes to return
|
// Parse tree nodes to return
|
||||||
|
|||||||
@@ -27,9 +27,11 @@ Parse the most recent match
|
|||||||
*/
|
*/
|
||||||
exports.parse = function() {
|
exports.parse = function() {
|
||||||
// Get the details of the match
|
// Get the details of the match
|
||||||
var linkText = this.match[0];
|
var linkText = this.match[0],
|
||||||
|
// Start after the suppressing "~" so the span matches the plain text
|
||||||
|
start = this.parser.pos + 1;
|
||||||
// Move past the wikilink
|
// Move past the wikilink
|
||||||
this.parser.pos = this.matchRegExp.lastIndex;
|
this.parser.pos = this.matchRegExp.lastIndex;
|
||||||
// Return the link without unwikilink character as plain text
|
// Return the link without unwikilink character as plain text
|
||||||
return [{type: "text", text: linkText.substr(1)}];
|
return [{type: "text", text: linkText.substr(1), start: start, end: this.parser.pos}];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ type: application/javascript
|
|||||||
module-type: startup
|
module-type: startup
|
||||||
|
|
||||||
Browser message handling
|
Browser message handling
|
||||||
|
|
||||||
\*/
|
\*/
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
@@ -18,6 +17,20 @@ exports.synchronous = true;
|
|||||||
/*
|
/*
|
||||||
Load a specified url as an iframe and call the callback when it is loaded. If the url is already loaded then the existing iframe instance is used
|
Load a specified url as an iframe and call the callback when it is loaded. If the url is already loaded then the existing iframe instance is used
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Ensure the callback fires once, whether by PLUGIN-LIBRARY-READY or onload (legacy)
|
||||||
|
|
||||||
|
function flushCallbacks(iframeInfo, err) {
|
||||||
|
if(iframeInfo.status !== "loaded") {
|
||||||
|
iframeInfo.status = err ? "error" : "loaded";
|
||||||
|
saveIFrameInfoTiddler(iframeInfo);
|
||||||
|
var cb;
|
||||||
|
while((cb = iframeInfo.callbacks.shift())) {
|
||||||
|
cb(err, iframeInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function loadIFrame(url,callback) {
|
function loadIFrame(url,callback) {
|
||||||
// Check if iframe already exists
|
// Check if iframe already exists
|
||||||
var iframeInfo = $tw.browserMessaging.iframeInfoMap[url];
|
var iframeInfo = $tw.browserMessaging.iframeInfoMap[url];
|
||||||
@@ -30,7 +43,8 @@ function loadIFrame(url,callback) {
|
|||||||
iframeInfo = {
|
iframeInfo = {
|
||||||
url: url,
|
url: url,
|
||||||
status: "loading",
|
status: "loading",
|
||||||
domNode: iframe
|
domNode: iframe,
|
||||||
|
callbacks: [callback]
|
||||||
};
|
};
|
||||||
$tw.browserMessaging.iframeInfoMap[url] = iframeInfo;
|
$tw.browserMessaging.iframeInfoMap[url] = iframeInfo;
|
||||||
saveIFrameInfoTiddler(iframeInfo);
|
saveIFrameInfoTiddler(iframeInfo);
|
||||||
@@ -38,19 +52,18 @@ function loadIFrame(url,callback) {
|
|||||||
iframe.style.display = "none";
|
iframe.style.display = "none";
|
||||||
iframe.setAttribute("library","true");
|
iframe.setAttribute("library","true");
|
||||||
document.body.appendChild(iframe);
|
document.body.appendChild(iframe);
|
||||||
// Set up onload
|
|
||||||
|
// Set up onload. Legacy fallback: if PLUGIN-LIBRARY-READY never arrives, onload triggers the flush later
|
||||||
iframe.onload = function() {
|
iframe.onload = function() {
|
||||||
iframeInfo.status = "loaded";
|
flushCallbacks(iframeInfo);
|
||||||
saveIFrameInfoTiddler(iframeInfo);
|
|
||||||
callback(null,iframeInfo);
|
|
||||||
};
|
};
|
||||||
iframe.onerror = function() {
|
iframe.onerror = function() {
|
||||||
callback("Cannot load iframe");
|
flushCallbacks(iframeInfo, "Cannot load iframe");
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
iframe.src = url;
|
iframe.src = url;
|
||||||
} catch(ex) {
|
} catch(ex) {
|
||||||
callback(ex);
|
flushCallbacks(iframeInfo, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -60,7 +73,7 @@ Unload library iframe for given url
|
|||||||
*/
|
*/
|
||||||
function unloadIFrame(url){
|
function unloadIFrame(url){
|
||||||
var iframes = document.getElementsByTagName("iframe");
|
var iframes = document.getElementsByTagName("iframe");
|
||||||
for(var t=iframes.length-1; t--; t>=0) {
|
for(var t = iframes.length - 1; t >= 0; t--) {
|
||||||
var iframe = iframes[t];
|
var iframe = iframes[t];
|
||||||
if(iframe.getAttribute("library") === "true" &&
|
if(iframe.getAttribute("library") === "true" &&
|
||||||
iframe.getAttribute("src") === url) {
|
iframe.getAttribute("src") === url) {
|
||||||
@@ -147,6 +160,13 @@ exports.startup = function() {
|
|||||||
// console.log("browser-messaging: Received message from",event.origin);
|
// console.log("browser-messaging: Received message from",event.origin);
|
||||||
// console.log("browser-messaging: Message content",event.data);
|
// console.log("browser-messaging: Message content",event.data);
|
||||||
switch(event.data.verb) {
|
switch(event.data.verb) {
|
||||||
|
case "PLUGIN-LIBRARY-READY":
|
||||||
|
$tw.utils.each($tw.browserMessaging.iframeInfoMap, function(info) {
|
||||||
|
if(info && info.domNode && info.domNode.contentWindow === event.source) {
|
||||||
|
flushCallbacks(info);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
case "GET-RESPONSE":
|
case "GET-RESPONSE":
|
||||||
if(event.data.status.charAt(0) === "2") {
|
if(event.data.status.charAt(0) === "2") {
|
||||||
if(event.data.cookies) {
|
if(event.data.cookies) {
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ var getCellInfo = function(text, start, length, SEPARATOR) {
|
|||||||
var isCellQuoted = text.charAt(start) === QUOTE;
|
var isCellQuoted = text.charAt(start) === QUOTE;
|
||||||
var cellStart = isCellQuoted ? start + 1 : start;
|
var cellStart = isCellQuoted ? start + 1 : start;
|
||||||
|
|
||||||
if(text.charAt(i) === SEPARATOR) {
|
// A quote licenses a separator inside the cell, so only an unquoted cell reads an immediate separator as empty
|
||||||
|
if(!isCellQuoted && text.charAt(cellStart) === SEPARATOR) {
|
||||||
return [cellStart, cellStart, false];
|
return [cellStart, cellStart, false];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/utils/color-utils.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: utils
|
||||||
|
|
||||||
|
Color.js related utilities
|
||||||
|
|
||||||
|
\*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var Color = require("$:/core/modules/utils/dom/color.js").Color;
|
||||||
|
|
||||||
|
/*
|
||||||
|
For backwards compatibility
|
||||||
|
*/
|
||||||
|
exports.parseCSSColor = function(colourString) {
|
||||||
|
var c = exports.parseCSSColorObject(colourString);
|
||||||
|
if(c) {
|
||||||
|
var rgb = c.srgb;
|
||||||
|
// Return components in the 0-255 range, matching the legacy csscolorparser.
|
||||||
|
// Clamp because Color.js can emit out-of-gamut sRGB components (e.g. from P3 inputs).
|
||||||
|
return [
|
||||||
|
Math.round(Math.max(0,Math.min(255,rgb[0] * 255))),
|
||||||
|
Math.round(Math.max(0,Math.min(255,rgb[1] * 255))),
|
||||||
|
Math.round(Math.max(0,Math.min(255,rgb[2] * 255))),
|
||||||
|
c.alpha
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Preferred way to parse a Color.js colour
|
||||||
|
*/
|
||||||
|
exports.parseCSSColorObject = function(colourString) {
|
||||||
|
var c = null;
|
||||||
|
try {
|
||||||
|
c = new Color(colourString);
|
||||||
|
} catch(e) {
|
||||||
|
// Return null if there is an error
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Convert a CSS colour to an RGB string suitable for use with the <input type="color"> element
|
||||||
|
*/
|
||||||
|
exports.convertCSSColorToRGBString = function(colourString) {
|
||||||
|
// The <input type="color"> element only accepts six digit hex values, so we
|
||||||
|
// discard any alpha channel and fall back to black for unparseable input
|
||||||
|
var rgb = exports.parseCSSColor(colourString);
|
||||||
|
if(rgb) {
|
||||||
|
return "#" + rgb.slice(0,3).map(function(component) {
|
||||||
|
return ("0" + component.toString(16)).slice(-2);
|
||||||
|
}).join("");
|
||||||
|
} else {
|
||||||
|
return "#000000";
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2021 Lea Verou, Chris Lilley
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"tiddlers": [
|
||||||
|
{
|
||||||
|
"file": "color.global.min.v0.6.1.js",
|
||||||
|
"fields": {
|
||||||
|
"type": "application/javascript",
|
||||||
|
"title": "$:/core/modules/utils/dom/color.js",
|
||||||
|
"module-type": "library"
|
||||||
|
},
|
||||||
|
"prefix": "",
|
||||||
|
"suffix": ";\nexports.Color = Color;"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "LICENSE",
|
||||||
|
"fields": {
|
||||||
|
"type": "text/plain",
|
||||||
|
"title": "$:/core/modules/utils/dom/color.js/license"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,200 +0,0 @@
|
|||||||
// (c) Dean McNamee <dean@gmail.com>, 2012.
|
|
||||||
//
|
|
||||||
// https://github.com/deanm/css-color-parser-js
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to
|
|
||||||
// deal in the Software without restriction, including without limitation the
|
|
||||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
||||||
// sell copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
// IN THE SOFTWARE.
|
|
||||||
|
|
||||||
// http://www.w3.org/TR/css3-color/
|
|
||||||
var kCSSColorTable = {
|
|
||||||
"transparent": [0,0,0,0], "aliceblue": [240,248,255,1],
|
|
||||||
"antiquewhite": [250,235,215,1], "aqua": [0,255,255,1],
|
|
||||||
"aquamarine": [127,255,212,1], "azure": [240,255,255,1],
|
|
||||||
"beige": [245,245,220,1], "bisque": [255,228,196,1],
|
|
||||||
"black": [0,0,0,1], "blanchedalmond": [255,235,205,1],
|
|
||||||
"blue": [0,0,255,1], "blueviolet": [138,43,226,1],
|
|
||||||
"brown": [165,42,42,1], "burlywood": [222,184,135,1],
|
|
||||||
"cadetblue": [95,158,160,1], "chartreuse": [127,255,0,1],
|
|
||||||
"chocolate": [210,105,30,1], "coral": [255,127,80,1],
|
|
||||||
"cornflowerblue": [100,149,237,1], "cornsilk": [255,248,220,1],
|
|
||||||
"crimson": [220,20,60,1], "cyan": [0,255,255,1],
|
|
||||||
"darkblue": [0,0,139,1], "darkcyan": [0,139,139,1],
|
|
||||||
"darkgoldenrod": [184,134,11,1], "darkgray": [169,169,169,1],
|
|
||||||
"darkgreen": [0,100,0,1], "darkgrey": [169,169,169,1],
|
|
||||||
"darkkhaki": [189,183,107,1], "darkmagenta": [139,0,139,1],
|
|
||||||
"darkolivegreen": [85,107,47,1], "darkorange": [255,140,0,1],
|
|
||||||
"darkorchid": [153,50,204,1], "darkred": [139,0,0,1],
|
|
||||||
"darksalmon": [233,150,122,1], "darkseagreen": [143,188,143,1],
|
|
||||||
"darkslateblue": [72,61,139,1], "darkslategray": [47,79,79,1],
|
|
||||||
"darkslategrey": [47,79,79,1], "darkturquoise": [0,206,209,1],
|
|
||||||
"darkviolet": [148,0,211,1], "deeppink": [255,20,147,1],
|
|
||||||
"deepskyblue": [0,191,255,1], "dimgray": [105,105,105,1],
|
|
||||||
"dimgrey": [105,105,105,1], "dodgerblue": [30,144,255,1],
|
|
||||||
"firebrick": [178,34,34,1], "floralwhite": [255,250,240,1],
|
|
||||||
"forestgreen": [34,139,34,1], "fuchsia": [255,0,255,1],
|
|
||||||
"gainsboro": [220,220,220,1], "ghostwhite": [248,248,255,1],
|
|
||||||
"gold": [255,215,0,1], "goldenrod": [218,165,32,1],
|
|
||||||
"gray": [128,128,128,1], "green": [0,128,0,1],
|
|
||||||
"greenyellow": [173,255,47,1], "grey": [128,128,128,1],
|
|
||||||
"honeydew": [240,255,240,1], "hotpink": [255,105,180,1],
|
|
||||||
"indianred": [205,92,92,1], "indigo": [75,0,130,1],
|
|
||||||
"ivory": [255,255,240,1], "khaki": [240,230,140,1],
|
|
||||||
"lavender": [230,230,250,1], "lavenderblush": [255,240,245,1],
|
|
||||||
"lawngreen": [124,252,0,1], "lemonchiffon": [255,250,205,1],
|
|
||||||
"lightblue": [173,216,230,1], "lightcoral": [240,128,128,1],
|
|
||||||
"lightcyan": [224,255,255,1], "lightgoldenrodyellow": [250,250,210,1],
|
|
||||||
"lightgray": [211,211,211,1], "lightgreen": [144,238,144,1],
|
|
||||||
"lightgrey": [211,211,211,1], "lightpink": [255,182,193,1],
|
|
||||||
"lightsalmon": [255,160,122,1], "lightseagreen": [32,178,170,1],
|
|
||||||
"lightskyblue": [135,206,250,1], "lightslategray": [119,136,153,1],
|
|
||||||
"lightslategrey": [119,136,153,1], "lightsteelblue": [176,196,222,1],
|
|
||||||
"lightyellow": [255,255,224,1], "lime": [0,255,0,1],
|
|
||||||
"limegreen": [50,205,50,1], "linen": [250,240,230,1],
|
|
||||||
"magenta": [255,0,255,1], "maroon": [128,0,0,1],
|
|
||||||
"mediumaquamarine": [102,205,170,1], "mediumblue": [0,0,205,1],
|
|
||||||
"mediumorchid": [186,85,211,1], "mediumpurple": [147,112,219,1],
|
|
||||||
"mediumseagreen": [60,179,113,1], "mediumslateblue": [123,104,238,1],
|
|
||||||
"mediumspringgreen": [0,250,154,1], "mediumturquoise": [72,209,204,1],
|
|
||||||
"mediumvioletred": [199,21,133,1], "midnightblue": [25,25,112,1],
|
|
||||||
"mintcream": [245,255,250,1], "mistyrose": [255,228,225,1],
|
|
||||||
"moccasin": [255,228,181,1], "navajowhite": [255,222,173,1],
|
|
||||||
"navy": [0,0,128,1], "oldlace": [253,245,230,1],
|
|
||||||
"olive": [128,128,0,1], "olivedrab": [107,142,35,1],
|
|
||||||
"orange": [255,165,0,1], "orangered": [255,69,0,1],
|
|
||||||
"orchid": [218,112,214,1], "palegoldenrod": [238,232,170,1],
|
|
||||||
"palegreen": [152,251,152,1], "paleturquoise": [175,238,238,1],
|
|
||||||
"palevioletred": [219,112,147,1], "papayawhip": [255,239,213,1],
|
|
||||||
"peachpuff": [255,218,185,1], "peru": [205,133,63,1],
|
|
||||||
"pink": [255,192,203,1], "plum": [221,160,221,1],
|
|
||||||
"powderblue": [176,224,230,1], "purple": [128,0,128,1],
|
|
||||||
"red": [255,0,0,1], "rosybrown": [188,143,143,1],
|
|
||||||
"royalblue": [65,105,225,1], "saddlebrown": [139,69,19,1],
|
|
||||||
"salmon": [250,128,114,1], "sandybrown": [244,164,96,1],
|
|
||||||
"seagreen": [46,139,87,1], "seashell": [255,245,238,1],
|
|
||||||
"sienna": [160,82,45,1], "silver": [192,192,192,1],
|
|
||||||
"skyblue": [135,206,235,1], "slateblue": [106,90,205,1],
|
|
||||||
"slategray": [112,128,144,1], "slategrey": [112,128,144,1],
|
|
||||||
"snow": [255,250,250,1], "springgreen": [0,255,127,1],
|
|
||||||
"steelblue": [70,130,180,1], "tan": [210,180,140,1],
|
|
||||||
"teal": [0,128,128,1], "thistle": [216,191,216,1],
|
|
||||||
"tomato": [255,99,71,1], "turquoise": [64,224,208,1],
|
|
||||||
"violet": [238,130,238,1], "wheat": [245,222,179,1],
|
|
||||||
"white": [255,255,255,1], "whitesmoke": [245,245,245,1],
|
|
||||||
"yellow": [255,255,0,1], "yellowgreen": [154,205,50,1]}
|
|
||||||
|
|
||||||
function clamp_css_byte(i) { // Clamp to integer 0 .. 255.
|
|
||||||
i = Math.round(i); // Seems to be what Chrome does (vs truncation).
|
|
||||||
return i < 0 ? 0 : i > 255 ? 255 : i;
|
|
||||||
}
|
|
||||||
|
|
||||||
function clamp_css_float(f) { // Clamp to float 0.0 .. 1.0.
|
|
||||||
return f < 0 ? 0 : f > 1 ? 1 : f;
|
|
||||||
}
|
|
||||||
|
|
||||||
function parse_css_int(str) { // int or percentage.
|
|
||||||
if (str[str.length - 1] === '%')
|
|
||||||
return clamp_css_byte(parseFloat(str) / 100 * 255);
|
|
||||||
return clamp_css_byte(parseInt(str));
|
|
||||||
}
|
|
||||||
|
|
||||||
function parse_css_float(str) { // float or percentage.
|
|
||||||
if (str[str.length - 1] === '%')
|
|
||||||
return clamp_css_float(parseFloat(str) / 100);
|
|
||||||
return clamp_css_float(parseFloat(str));
|
|
||||||
}
|
|
||||||
|
|
||||||
function css_hue_to_rgb(m1, m2, h) {
|
|
||||||
if (h < 0) h += 1;
|
|
||||||
else if (h > 1) h -= 1;
|
|
||||||
|
|
||||||
if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
|
|
||||||
if (h * 2 < 1) return m2;
|
|
||||||
if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
|
|
||||||
return m1;
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseCSSColor(css_str) {
|
|
||||||
// Remove all whitespace, not compliant, but should just be more accepting.
|
|
||||||
var str = css_str.replace(/ /g, '').toLowerCase();
|
|
||||||
|
|
||||||
// Color keywords (and transparent) lookup.
|
|
||||||
if (str in kCSSColorTable) return kCSSColorTable[str].slice(); // dup.
|
|
||||||
|
|
||||||
// #abc and #abc123 syntax.
|
|
||||||
if (str[0] === '#') {
|
|
||||||
if (str.length === 4) {
|
|
||||||
var iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing.
|
|
||||||
if (!(iv >= 0 && iv <= 0xfff)) return null; // Covers NaN.
|
|
||||||
return [((iv & 0xf00) >> 4) | ((iv & 0xf00) >> 8),
|
|
||||||
(iv & 0xf0) | ((iv & 0xf0) >> 4),
|
|
||||||
(iv & 0xf) | ((iv & 0xf) << 4),
|
|
||||||
1];
|
|
||||||
} else if (str.length === 7) {
|
|
||||||
var iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing.
|
|
||||||
if (!(iv >= 0 && iv <= 0xffffff)) return null; // Covers NaN.
|
|
||||||
return [(iv & 0xff0000) >> 16,
|
|
||||||
(iv & 0xff00) >> 8,
|
|
||||||
iv & 0xff,
|
|
||||||
1];
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var op = str.indexOf('('), ep = str.indexOf(')');
|
|
||||||
if (op !== -1 && ep + 1 === str.length) {
|
|
||||||
var fname = str.substr(0, op);
|
|
||||||
var params = str.substr(op+1, ep-(op+1)).split(',');
|
|
||||||
var alpha = 1; // To allow case fallthrough.
|
|
||||||
switch (fname) {
|
|
||||||
case 'rgba':
|
|
||||||
if (params.length !== 4) return null;
|
|
||||||
alpha = parse_css_float(params.pop());
|
|
||||||
// Fall through.
|
|
||||||
case 'rgb':
|
|
||||||
if (params.length !== 3) return null;
|
|
||||||
return [parse_css_int(params[0]),
|
|
||||||
parse_css_int(params[1]),
|
|
||||||
parse_css_int(params[2]),
|
|
||||||
alpha];
|
|
||||||
case 'hsla':
|
|
||||||
if (params.length !== 4) return null;
|
|
||||||
alpha = parse_css_float(params.pop());
|
|
||||||
// Fall through.
|
|
||||||
case 'hsl':
|
|
||||||
if (params.length !== 3) return null;
|
|
||||||
var h = (((parseFloat(params[0]) % 360) + 360) % 360) / 360; // 0 .. 1
|
|
||||||
// NOTE(deanm): According to the CSS spec s/l should only be
|
|
||||||
// percentages, but we don't bother and let float or percentage.
|
|
||||||
var s = parse_css_float(params[1]);
|
|
||||||
var l = parse_css_float(params[2]);
|
|
||||||
var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
|
|
||||||
var m1 = l * 2 - m2;
|
|
||||||
return [clamp_css_byte(css_hue_to_rgb(m1, m2, h+1/3) * 255),
|
|
||||||
clamp_css_byte(css_hue_to_rgb(m1, m2, h) * 255),
|
|
||||||
clamp_css_byte(css_hue_to_rgb(m1, m2, h-1/3) * 255),
|
|
||||||
alpha];
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
try { exports.parseCSSColor = parseCSSColor } catch(e) { }
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
title: $:/core/modules/utils/dom/csscolorparser.js
|
|
||||||
type: application/javascript
|
|
||||||
module-type: utils
|
|
||||||
@@ -164,15 +164,16 @@ exports.forceLayout = function(element) {
|
|||||||
Pulse an element for debugging purposes
|
Pulse an element for debugging purposes
|
||||||
*/
|
*/
|
||||||
exports.pulseElement = function(element) {
|
exports.pulseElement = function(element) {
|
||||||
|
var eventName = $tw.utils.convertEventName("animationEnd");
|
||||||
// Event handler to remove the class at the end
|
// Event handler to remove the class at the end
|
||||||
element.addEventListener($tw.browser.animationEnd,function handler(event) {
|
element.addEventListener(eventName,function handler(event) {
|
||||||
element.removeEventListener($tw.browser.animationEnd,handler,false);
|
element.removeEventListener(eventName,handler,false);
|
||||||
$tw.utils.removeClass(element,"pulse");
|
$tw.utils.removeClass(element,"tc-pulse");
|
||||||
},false);
|
},false);
|
||||||
// Apply the pulse class
|
// Apply the pulse class
|
||||||
$tw.utils.removeClass(element,"pulse");
|
$tw.utils.removeClass(element,"tc-pulse");
|
||||||
$tw.utils.forceLayout(element);
|
$tw.utils.forceLayout(element);
|
||||||
$tw.utils.addClass(element,"pulse");
|
$tw.utils.addClass(element,"tc-pulse");
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -115,7 +115,9 @@ var TW_Element = function(tag, namespace) {
|
|||||||
this.children = [];
|
this.children = [];
|
||||||
this._style = {}; // Internal style object
|
this._style = {}; // Internal style object
|
||||||
this.style = new TW_Style(this); // Proxy for style management
|
this.style = new TW_Style(this); // Proxy for style management
|
||||||
this.namespaceURI = namespace || "http://www.w3.org/1999/xhtml";
|
// createElementNS with empty-string or null normalises to null (no namespace) per spec.
|
||||||
|
// https://dom.spec.whatwg.org/#dom-document-createelementns
|
||||||
|
this.namespaceURI = namespace !== undefined ? (namespace || null) : "http://www.w3.org/1999/xhtml";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -206,7 +208,16 @@ TW_Element.prototype.addEventListener = function(type,listener,useCapture) {
|
|||||||
|
|
||||||
Object.defineProperty(TW_Element.prototype, "tagName", {
|
Object.defineProperty(TW_Element.prototype, "tagName", {
|
||||||
get: function() {
|
get: function() {
|
||||||
return this.tag || "";
|
if(!this.tag) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
// HTML elements report uppercase tagName per DOM spec. Other namespaces
|
||||||
|
// preserve case. Fakedom only models HTML documents.
|
||||||
|
// https://dom.spec.whatwg.org/#dom-element-tagname
|
||||||
|
if(this.namespaceURI === "http://www.w3.org/1999/xhtml") {
|
||||||
|
return this.tag.toUpperCase();
|
||||||
|
}
|
||||||
|
return this.tag;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -243,8 +243,28 @@ exports.slowInSlowOut = function(t) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
exports.copyObjectPropertiesSafe = function(object) {
|
exports.copyObjectPropertiesSafe = function(object) {
|
||||||
const seen = new Set(),
|
const seen = new Set();
|
||||||
isDOMElement = (value) => value instanceof Node || value instanceof Window;
|
|
||||||
|
function isDOMElement(value) {
|
||||||
|
if(!value || typeof value !== "object") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cross-realm DOM nodes
|
||||||
|
if(typeof value.nodeType === "number" &&
|
||||||
|
typeof value.nodeName === "string") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cross-realm Window objects
|
||||||
|
if(value.window === value &&
|
||||||
|
value.document &&
|
||||||
|
value.location) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
function safeCopy(obj) {
|
function safeCopy(obj) {
|
||||||
// skip circular references
|
// skip circular references
|
||||||
@@ -255,10 +275,6 @@ exports.copyObjectPropertiesSafe = function(object) {
|
|||||||
if(typeof obj !== "object" || obj === null) {
|
if(typeof obj !== "object" || obj === null) {
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
// skip DOM elements
|
|
||||||
if(isDOMElement(obj)) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
// copy arrays, preserving positions
|
// copy arrays, preserving positions
|
||||||
if(Array.isArray(obj)) {
|
if(Array.isArray(obj)) {
|
||||||
return obj.map((item) => {
|
return obj.map((item) => {
|
||||||
@@ -266,7 +282,11 @@ exports.copyObjectPropertiesSafe = function(object) {
|
|||||||
return value === undefined ? null : value;
|
return value === undefined ? null : value;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// skip DOM elements
|
||||||
|
if(isDOMElement(obj)) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
seen.add(obj);
|
seen.add(obj);
|
||||||
const copy = {};
|
const copy = {};
|
||||||
let key,
|
let key,
|
||||||
|
|||||||
@@ -62,8 +62,8 @@ SendMessageWidget.prototype.invokeAction = function(triggeringWidget,event) {
|
|||||||
var paramObject = Object.create(null);
|
var paramObject = Object.create(null);
|
||||||
// Add names/values pairs if present
|
// Add names/values pairs if present
|
||||||
if(this.actionNames && this.actionValues) {
|
if(this.actionNames && this.actionValues) {
|
||||||
var names = this.wiki.filterTiddlers(this.actionNames,this),
|
var names = this.wiki.filterTiddlers(this.actionNames,this,null,{defaultFilterRunPrefix: "all"}),
|
||||||
values = this.wiki.filterTiddlers(this.actionValues,this);
|
values = this.wiki.filterTiddlers(this.actionValues,this,null,{defaultFilterRunPrefix: "all"});
|
||||||
$tw.utils.each(names,function(name,index) {
|
$tw.utils.each(names,function(name,index) {
|
||||||
paramObject[name] = values[index] || "";
|
paramObject[name] = values[index] || "";
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -56,10 +56,10 @@ Invoke the action associated with this widget
|
|||||||
*/
|
*/
|
||||||
SetMultipleFieldsWidget.prototype.invokeAction = function(triggeringWidget,event) {
|
SetMultipleFieldsWidget.prototype.invokeAction = function(triggeringWidget,event) {
|
||||||
var tiddler = this.wiki.getTiddler(this.actionTiddler),
|
var tiddler = this.wiki.getTiddler(this.actionTiddler),
|
||||||
names, values = this.wiki.filterTiddlers(this.actionValues,this);
|
names, values = this.wiki.filterTiddlers(this.actionValues,this,null,{defaultFilterRunPrefix: "all"});
|
||||||
if(this.actionFields) {
|
if(this.actionFields) {
|
||||||
var additions = {};
|
var additions = {};
|
||||||
names = this.wiki.filterTiddlers(this.actionFields,this);
|
names = this.wiki.filterTiddlers(this.actionFields,this,null,{defaultFilterRunPrefix: "all"});
|
||||||
$tw.utils.each(names,function(fieldname,index) {
|
$tw.utils.each(names,function(fieldname,index) {
|
||||||
additions[fieldname] = values[index] || "";
|
additions[fieldname] = values[index] || "";
|
||||||
});
|
});
|
||||||
@@ -68,7 +68,7 @@ SetMultipleFieldsWidget.prototype.invokeAction = function(triggeringWidget,event
|
|||||||
this.wiki.addTiddler(new $tw.Tiddler(creationFields,tiddler,{title: this.actionTiddler},modificationFields,additions));
|
this.wiki.addTiddler(new $tw.Tiddler(creationFields,tiddler,{title: this.actionTiddler},modificationFields,additions));
|
||||||
} else if(this.actionIndexes) {
|
} else if(this.actionIndexes) {
|
||||||
var data = this.wiki.getTiddlerData(this.actionTiddler,Object.create(null));
|
var data = this.wiki.getTiddlerData(this.actionTiddler,Object.create(null));
|
||||||
names = this.wiki.filterTiddlers(this.actionIndexes,this);
|
names = this.wiki.filterTiddlers(this.actionIndexes,this,null,{defaultFilterRunPrefix: "all"});
|
||||||
$tw.utils.each(names,function(name,index) {
|
$tw.utils.each(names,function(name,index) {
|
||||||
data[name] = values[index] || "";
|
data[name] = values[index] || "";
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -151,10 +151,24 @@ ButtonWidget.prototype.getBoundingClientRect = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
ButtonWidget.prototype.isSelected = function() {
|
ButtonWidget.prototype.isSelected = function() {
|
||||||
return this.setTitle ? (this.setField ? this.wiki.getTiddler(this.setTitle).getFieldString(this.setField) === this.setTo :
|
var currentValue;
|
||||||
(this.setIndex ? this.wiki.extractTiddlerDataItem(this.setTitle,this.setIndex) === this.setTo :
|
if(this.setTitle) {
|
||||||
this.wiki.getTiddlerText(this.setTitle))) || this.defaultSetValue || this.getVariable("currentTiddler") :
|
if(this.setField) {
|
||||||
this.wiki.getTextReference(this.set,this.defaultSetValue,this.getVariable("currentTiddler")) === this.setTo;
|
// The state tiddler usually does not exist until the button is first clicked
|
||||||
|
var tiddler = this.wiki.getTiddler(this.setTitle);
|
||||||
|
currentValue = tiddler ? tiddler.getFieldString(this.setField) : undefined;
|
||||||
|
} else if(this.setIndex) {
|
||||||
|
currentValue = this.wiki.extractTiddlerDataItem(this.setTitle,this.setIndex);
|
||||||
|
} else {
|
||||||
|
currentValue = this.wiki.getTiddlerText(this.setTitle);
|
||||||
|
}
|
||||||
|
if(!currentValue) {
|
||||||
|
currentValue = this.defaultSetValue || this.getVariable("currentTiddler");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
currentValue = this.wiki.getTextReference(this.set,this.defaultSetValue,this.getVariable("currentTiddler"));
|
||||||
|
}
|
||||||
|
return currentValue === this.setTo;
|
||||||
};
|
};
|
||||||
|
|
||||||
ButtonWidget.prototype.isPoppedUp = function() {
|
ButtonWidget.prototype.isPoppedUp = function() {
|
||||||
@@ -267,7 +281,7 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
|
|||||||
*/
|
*/
|
||||||
ButtonWidget.prototype.refresh = function(changedTiddlers) {
|
ButtonWidget.prototype.refresh = function(changedTiddlers) {
|
||||||
var changedAttributes = this.computeAttributes();
|
var changedAttributes = this.computeAttributes();
|
||||||
if(changedAttributes.tooltip || changedAttributes.actions || changedAttributes.to || changedAttributes.message || changedAttributes.param || changedAttributes.set || changedAttributes.setTo || changedAttributes.popup || changedAttributes.hover || changedAttributes.selectedClass || changedAttributes.style || changedAttributes.dragFilter || changedAttributes.dragTiddler || (this.set && changedTiddlers[this.set]) || (this.popup && changedTiddlers[this.popup]) || (this.popupTitle && changedTiddlers[this.popupTitle]) || changedAttributes.popupAbsCoords || changedAttributes.setTitle || changedAttributes.setField || changedAttributes.setIndex || changedAttributes.popupTitle || changedAttributes.disabled || changedAttributes["default"]) {
|
if(changedAttributes.tooltip || 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.setTitle && changedTiddlers[this.setTitle]) || (this.popup && changedTiddlers[this.popup]) || (this.popupTitle && changedTiddlers[this.popupTitle]) || changedAttributes.popupAbsCoords || changedAttributes.setTitle || changedAttributes.setField || changedAttributes.setIndex || changedAttributes.popupTitle || changedAttributes.disabled || changedAttributes["default"]) {
|
||||||
this.refreshSelf();
|
this.refreshSelf();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ Inherit from the base widget class
|
|||||||
DiffTextWidget.prototype = new Widget();
|
DiffTextWidget.prototype = new Widget();
|
||||||
|
|
||||||
DiffTextWidget.prototype.invisibleCharacters = {
|
DiffTextWidget.prototype.invisibleCharacters = {
|
||||||
"\n": "↩︎\n",
|
"\n": "↲\n",
|
||||||
"\r": "⇠",
|
"\r": "⇠",
|
||||||
"\t": "⇥\t"
|
"\t": "⇥\t"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -72,8 +72,8 @@ GenesisWidget.prototype.execute = function() {
|
|||||||
this.attributeNames = [];
|
this.attributeNames = [];
|
||||||
this.attributeValues = [];
|
this.attributeValues = [];
|
||||||
if(this.genesisNames && this.genesisValues) {
|
if(this.genesisNames && this.genesisValues) {
|
||||||
this.attributeNames = this.wiki.filterTiddlers(self.genesisNames,this);
|
this.attributeNames = this.wiki.filterTiddlers(self.genesisNames,this,null,{defaultFilterRunPrefix: "all"});
|
||||||
this.attributeValues = this.wiki.filterTiddlers(self.genesisValues,this);
|
this.attributeValues = this.wiki.filterTiddlers(self.genesisValues,this,null,{defaultFilterRunPrefix: "all"});
|
||||||
$tw.utils.each(this.attributeNames,function(varname,index) {
|
$tw.utils.each(this.attributeNames,function(varname,index) {
|
||||||
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],varname,self.attributeValues[index] || "");
|
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],varname,self.attributeValues[index] || "");
|
||||||
});
|
});
|
||||||
@@ -103,8 +103,8 @@ GenesisWidget.prototype.refresh = function(changedTiddlers) {
|
|||||||
var changedAttributes = this.computeAttributes(),
|
var changedAttributes = this.computeAttributes(),
|
||||||
filterNames = this.getAttribute("$names",""),
|
filterNames = this.getAttribute("$names",""),
|
||||||
filterValues = this.getAttribute("$values",""),
|
filterValues = this.getAttribute("$values",""),
|
||||||
attributeNames = this.wiki.filterTiddlers(filterNames,this),
|
attributeNames = this.wiki.filterTiddlers(filterNames,this,null,{defaultFilterRunPrefix: "all"}),
|
||||||
attributeValues = this.wiki.filterTiddlers(filterValues,this);
|
attributeValues = this.wiki.filterTiddlers(filterValues,this,null,{defaultFilterRunPrefix: "all"});
|
||||||
if($tw.utils.count(changedAttributes) > 0 || !$tw.utils.isArrayEqual(this.attributeNames,attributeNames) || !$tw.utils.isArrayEqual(this.attributeValues,attributeValues)) {
|
if($tw.utils.count(changedAttributes) > 0 || !$tw.utils.isArrayEqual(this.attributeNames,attributeNames) || !$tw.utils.isArrayEqual(this.attributeValues,attributeValues)) {
|
||||||
this.refreshSelf();
|
this.refreshSelf();
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -99,7 +99,8 @@ LinkWidget.prototype.renderLink = function(parent,nextSibling) {
|
|||||||
wikiLinkText = this.wiki.filterTiddlers(wikilinkTransformFilter,this,function(iterator) {
|
wikiLinkText = this.wiki.filterTiddlers(wikilinkTransformFilter,this,function(iterator) {
|
||||||
iterator(self.wiki.getTiddler(self.to),self.to);
|
iterator(self.wiki.getTiddler(self.to),self.to);
|
||||||
})[0];
|
})[0];
|
||||||
} else {
|
}
|
||||||
|
if(!wikiLinkText) {
|
||||||
// Expand the tv-wikilink-template variable to construct the href
|
// Expand the tv-wikilink-template variable to construct the href
|
||||||
var wikiLinkTemplateMacro = this.getVariable("tv-wikilink-template"),
|
var wikiLinkTemplateMacro = this.getVariable("tv-wikilink-template"),
|
||||||
wikiLinkTemplate = wikiLinkTemplateMacro ? wikiLinkTemplateMacro.trim() : "#$uri_encoded$";
|
wikiLinkTemplate = wikiLinkTemplateMacro ? wikiLinkTemplateMacro.trim() : "#$uri_encoded$";
|
||||||
|
|||||||
@@ -49,8 +49,8 @@ SetMultipleVariablesWidget.prototype.setVariables = function() {
|
|||||||
this.variableNames = [];
|
this.variableNames = [];
|
||||||
this.variableValues = [];
|
this.variableValues = [];
|
||||||
if(filterNames && filterValues) {
|
if(filterNames && filterValues) {
|
||||||
this.variableNames = this.wiki.filterTiddlers(filterNames,this);
|
this.variableNames = this.wiki.filterTiddlers(filterNames,this,null,{defaultFilterRunPrefix: "all"});
|
||||||
this.variableValues = this.wiki.filterTiddlers(filterValues,this);
|
this.variableValues = this.wiki.filterTiddlers(filterValues,this,null,{defaultFilterRunPrefix: "all"});
|
||||||
$tw.utils.each(this.variableNames,function(varname,index) {
|
$tw.utils.each(this.variableNames,function(varname,index) {
|
||||||
self.setVariable(varname,self.variableValues[index]);
|
self.setVariable(varname,self.variableValues[index]);
|
||||||
});
|
});
|
||||||
@@ -63,8 +63,8 @@ Refresh the widget by ensuring our attributes are up to date
|
|||||||
SetMultipleVariablesWidget.prototype.refresh = function(changedTiddlers) {
|
SetMultipleVariablesWidget.prototype.refresh = function(changedTiddlers) {
|
||||||
var filterNames = this.getAttribute("$names",""),
|
var filterNames = this.getAttribute("$names",""),
|
||||||
filterValues = this.getAttribute("$values",""),
|
filterValues = this.getAttribute("$values",""),
|
||||||
variableNames = this.wiki.filterTiddlers(filterNames,this),
|
variableNames = this.wiki.filterTiddlers(filterNames,this,null,{defaultFilterRunPrefix: "all"}),
|
||||||
variableValues = this.wiki.filterTiddlers(filterValues,this);
|
variableValues = this.wiki.filterTiddlers(filterValues,this,null,{defaultFilterRunPrefix: "all"});
|
||||||
if(!$tw.utils.isArrayEqual(this.variableNames,variableNames) || !$tw.utils.isArrayEqual(this.variableValues,variableValues)) {
|
if(!$tw.utils.isArrayEqual(this.variableNames,variableNames) || !$tw.utils.isArrayEqual(this.variableValues,variableValues)) {
|
||||||
this.refreshSelf();
|
this.refreshSelf();
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
title: $:/palettes/AutoToggle
|
||||||
|
name: AutoToggle
|
||||||
|
description: Automatically switch between dark and light modes
|
||||||
|
tags: $:/tags/Palette
|
||||||
|
type: application/x-tiddler-dictionary
|
||||||
|
color-scheme: [{$:/info/browser/darkmode}!match[yes]then[light]else[dark]]
|
||||||
|
customisations: $:/palettes/AutoToggle/Customisations
|
||||||
|
palette-import@light: $:/palettes/TwentyTwenties
|
||||||
|
palette-import@dark: $:/palettes/TwentyTwenties/Dark
|
||||||
|
category: 2026
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
title: $:/palettes/AutoToggle/Customisations
|
||||||
|
|
||||||
|
\procedure layer-input-actions()
|
||||||
|
<$action-setfield $tiddler=<<layerTitle>> palette-import={{$:/palette}}/>
|
||||||
|
\end layer-input-actions
|
||||||
|
|
||||||
|
\procedure set-imported-palette(field)
|
||||||
|
<$select field=<<field>> default={{{ [[$:/temp/palette-consolidated]get<field>] }}} actions=<<layer-input-actions>>>
|
||||||
|
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Palette]sort[name]] -[{$:/palette}]">
|
||||||
|
<option value=<<currentTiddler>>><$view field="name"><$view field="title"/></$view></option>
|
||||||
|
</$list>
|
||||||
|
</$select>
|
||||||
|
\end set-imported-palette
|
||||||
|
|
||||||
|
This palette can be used to automatically switch between two palettes based on the browser's dark mode setting.
|
||||||
|
|
||||||
|
<$let layerTitle={{{ [function[tf.palette-customisations-layer]] }}}>
|
||||||
|
<$tiddler tiddler=<<layerTitle>>>
|
||||||
|
|
||||||
|
Light palette: <<set-imported-palette field:"palette-import@light">>
|
||||||
|
|
||||||
|
Dark palette: <<set-imported-palette field:"palette-import@dark">>
|
||||||
|
|
||||||
|
</$tiddler>
|
||||||
|
</$let>
|
||||||
@@ -0,0 +1,226 @@
|
|||||||
|
title: $:/palettes/TwentyTwenties
|
||||||
|
name: TwentyTwenties
|
||||||
|
description: Modern and flexible
|
||||||
|
tags: $:/tags/Palette
|
||||||
|
type: application/x-tiddler-dictionary
|
||||||
|
color-scheme: light
|
||||||
|
customisations: $:/palettes/TwentyTwenties/Customisations
|
||||||
|
palette-import: $:/palettes/Vanilla
|
||||||
|
category: 2026
|
||||||
|
|
||||||
|
# Background and foreground colours, which are interpolated as required
|
||||||
|
base-paper: #FFFCF0
|
||||||
|
base-background: #f0d5c6
|
||||||
|
base-ink: #333344
|
||||||
|
?base-paper-ink: [tf.check-colour-contrast[base-paper],[base-ink],[45]]
|
||||||
|
?base-background-ink: [tf.check-colour-contrast[base-background],[base-ink],[45]]
|
||||||
|
|
||||||
|
# Primary colour, used for links and other accented elements
|
||||||
|
base-primary: #5778d8
|
||||||
|
?base-paper-primary: [tf.check-colour-contrast[base-paper],[base-primary],[45]]
|
||||||
|
?base-background-primary: [tf.check-colour-contrast[base-background],[base-primary],[45]]
|
||||||
|
|
||||||
|
# Secondary colour, used for alerts and other secondary elements
|
||||||
|
base-secondary: #f0e48a
|
||||||
|
?base-ink-secondary: [tf.check-colour-contrast[base-ink],[base-secondary],[45]]
|
||||||
|
|
||||||
|
# Tertiary base colour, used for monospaced text and other tertiary elements
|
||||||
|
base-tertiary: rgb(183, 95, 95)
|
||||||
|
?base-paper-tertiary: [tf.check-colour-contrast[base-paper],[base-tertiary],[45]]
|
||||||
|
|
||||||
|
# Basic spectrum colours
|
||||||
|
base-black: #100F0F
|
||||||
|
base-red: #D14D41
|
||||||
|
base-orange: #DA702C
|
||||||
|
base-yellow: #D0A215
|
||||||
|
base-green: #879A39
|
||||||
|
base-cyan: #3AA99F
|
||||||
|
base-blue: #4385BE
|
||||||
|
base-purple: #8B7EC8
|
||||||
|
base-magenta: #CE5D97
|
||||||
|
base-white: #FFFCF0
|
||||||
|
# Darker variants
|
||||||
|
# base-red: #AF3029
|
||||||
|
# base-orange: #BC5215
|
||||||
|
# base-yellow: #AD8301
|
||||||
|
# base-green: #66800B
|
||||||
|
# base-cyan: #24837B
|
||||||
|
# base-blue: #205EA6
|
||||||
|
# base-purple: #5E409D
|
||||||
|
# base-magenta: #A02F6F
|
||||||
|
|
||||||
|
# Palette definitions
|
||||||
|
alert-background: [tf.colour[base-secondary]]
|
||||||
|
alert-border: [tf.interpolate-colours[base-ink],[alert-background],[0.6]]
|
||||||
|
alert-highlight: [tf.interpolate-colours[base-ink],[base-primary],[0.3]]
|
||||||
|
alert-muted-foreground: [tf.interpolate-colours[base-ink],[alert-background],[0.4]]
|
||||||
|
background: [tf.colour[base-paper]]
|
||||||
|
blockquote-bar: [tf.colour[muted-foreground]]
|
||||||
|
button-background:
|
||||||
|
button-border:
|
||||||
|
button-foreground:
|
||||||
|
code-background: [tf.interpolate-colours[base-paper],[base-tertiary],[0.1]]
|
||||||
|
code-border: [tf.interpolate-colours[base-paper],[base-tertiary],[0.6]]
|
||||||
|
code-foreground: [tf.colour[base-tertiary]]
|
||||||
|
diff-delete-background: [tf.colour[base-red]]
|
||||||
|
diff-delete-foreground: [tf.colour[foreground]]
|
||||||
|
diff-equal-background:
|
||||||
|
diff-equal-foreground: [tf.colour[foreground]]
|
||||||
|
diff-insert-background: [tf.colour[base-green]]
|
||||||
|
diff-insert-foreground: [tf.colour[foreground]]
|
||||||
|
diff-invisible-background:
|
||||||
|
diff-invisible-foreground: [tf.colour[muted-foreground]]
|
||||||
|
dirty-indicator: [tf.colour[base-tertiary]]
|
||||||
|
download-background: [tf.interpolate-colours[base-paper],[base-green],[0.6]]
|
||||||
|
download-foreground: [tf.interpolate-colours[base-ink],[base-green],[0.1]]
|
||||||
|
dragger-background: [tf.colour[foreground]]
|
||||||
|
dragger-foreground: [tf.colour[background]]
|
||||||
|
dropdown-background: [tf.colour[background]]
|
||||||
|
dropdown-border: [tf.colour[muted-foreground]]
|
||||||
|
dropdown-tab-background-selected: [tf.colour[background]]
|
||||||
|
dropdown-tab-background: [tf.interpolate-colours[base-paper],[base-ink],[0.9]]
|
||||||
|
dropzone-background: [tf.colour[base-secondary]colour-set-alpha[0.7]]
|
||||||
|
external-link-background-hover: inherit
|
||||||
|
external-link-background-visited: inherit
|
||||||
|
external-link-background: inherit
|
||||||
|
external-link-foreground-hover: inherit
|
||||||
|
external-link-foreground-visited: [tf.colour[primary]]
|
||||||
|
external-link-foreground: [tf.colour[primary]]
|
||||||
|
footnote-target-background: [tf.interpolate-colours[base-paper],[base-ink],[0.2]]
|
||||||
|
foreground: [tf.colour[base-ink]]
|
||||||
|
highlight-background: [tf.interpolate-colours[base-paper],[base-yellow],[0.5]]
|
||||||
|
highlight-foreground: [tf.interpolate-colours[base-yellow],[base-ink],[0.8]]
|
||||||
|
menubar-background: #5778d8
|
||||||
|
menubar-foreground: #fff
|
||||||
|
message-background: [tf.interpolate-colours[base-paper],[base-blue],[0.2]]
|
||||||
|
message-border: [tf.interpolate-colours[base-blue],[base-ink],[0.5]]
|
||||||
|
message-foreground: [tf.interpolate-colours[base-blue],[base-ink],[0.8]]
|
||||||
|
modal-backdrop: [tf.colour[foreground]]
|
||||||
|
modal-background: [tf.colour[background]]
|
||||||
|
modal-border: #999999
|
||||||
|
modal-footer-background: #f5f5f5
|
||||||
|
modal-footer-border: #dddddd
|
||||||
|
modal-header-border: #eeeeee
|
||||||
|
muted-foreground: [tf.interpolate-colours[base-paper],[base-ink],[0.3]]
|
||||||
|
network-activity-foreground: #448844
|
||||||
|
notification-background: [tf.colour[base-tertiary]colour-set-oklch:l[0.9]]
|
||||||
|
notification-border: [tf.colour[base-tertiary]colour-set-oklch:l[0.2]]
|
||||||
|
page-background: [tf.colour[base-background]]
|
||||||
|
pre-background: [tf.interpolate-colours[base-paper],[base-tertiary],[0.1]]
|
||||||
|
pre-border: [tf.interpolate-colours[base-paper],[base-tertiary],[0.6]]
|
||||||
|
primary: [tf.colour[base-primary]]
|
||||||
|
select-tag-background:
|
||||||
|
select-tag-foreground:
|
||||||
|
selection-background:
|
||||||
|
selection-foreground:
|
||||||
|
sidebar-button-foreground: [tf.colour[sidebar-controls-foreground]]
|
||||||
|
sidebar-controls-foreground-hover: [tf.interpolate-colours[base-ink],[base-background],[0.2]]
|
||||||
|
sidebar-controls-foreground: [tf.interpolate-colours[base-ink],[base-background],[0.8]]
|
||||||
|
sidebar-foreground-shadow: inherit
|
||||||
|
sidebar-foreground: =[tf.colour[base-ink]] =[tf.colour[base-paper]] =[tf.colour[base-background]] +[colour-best-contrast[]]
|
||||||
|
sidebar-muted-foreground-hover: [tf.colour[sidebar-muted-foreground]colour-set-oklch:l[0.3]]
|
||||||
|
sidebar-muted-foreground: [tf.interpolate-colours[foreground],[page-background],[0.6]]
|
||||||
|
sidebar-tab-background-selected: [tf.colour[tab-background-selected]]
|
||||||
|
sidebar-tab-background: [tf.colour[tab-background]]
|
||||||
|
sidebar-tab-border-selected: [tf.colour[tab-border-selected]]
|
||||||
|
sidebar-tab-border: [tf.colour[tab-border]]
|
||||||
|
sidebar-tab-divider: [tf.colour[tab-divider]]
|
||||||
|
sidebar-tab-foreground-selected: [tf.colour[tab-foreground-selected]]
|
||||||
|
sidebar-tab-foreground: [tf.colour[tab-foreground]]
|
||||||
|
sidebar-tiddler-link-foreground-hover: [tf.colour[sidebar-tiddler-link-foreground]colour-set-oklch:l[0.5]]
|
||||||
|
sidebar-tiddler-link-foreground: =[tf.colour[base-primary]] =[tf.colour[base-secondary]] =[tf.colour[base-tertiary]] =[tf.colour[base-background]] +[colour-best-contrast[]]
|
||||||
|
site-title-foreground: [tf.colour[tiddler-title-foreground]]
|
||||||
|
stability-deprecated: #ff0000
|
||||||
|
stability-experimental: #c07c00
|
||||||
|
stability-legacy: #0000ff
|
||||||
|
stability-stable: #008000
|
||||||
|
static-alert-foreground: #aaaaaa
|
||||||
|
tab-background-selected: [tf.colour[background]]
|
||||||
|
tab-background: [tf.interpolate-colours[base-paper],[base-ink],[0.2]]
|
||||||
|
tab-border-selected: [tf.colour[muted-foreground]]
|
||||||
|
tab-border: [tf.colour[muted-foreground]]
|
||||||
|
tab-divider: [tf.colour[muted-foreground]]
|
||||||
|
tab-foreground-selected: [tf.colour[tab-foreground]]
|
||||||
|
tab-foreground: [tf.colour[foreground]]
|
||||||
|
table-border: [tf.colour[foreground]]
|
||||||
|
table-footer-background: [tf.interpolate-colours[background],[foreground],[0.2]]
|
||||||
|
table-header-background: [tf.interpolate-colours[background],[foreground],[0.1]]
|
||||||
|
tag-background: [tf.interpolate-colours[base-paper],[base-yellow],[0.9]]
|
||||||
|
tag-foreground: [tf.interpolate-colours[base-yellow],[base-ink],[0.8]]
|
||||||
|
testcase-accent-level-1: #c1eaff
|
||||||
|
testcase-accent-level-2: #E3B740
|
||||||
|
testcase-accent-level-3: #5FD564
|
||||||
|
tiddler-background: [tf.colour[background]]
|
||||||
|
tiddler-border: [tf.interpolate-colours[base-paper],[base-background],[0.5]]
|
||||||
|
tiddler-controls-foreground-hover: [tf.interpolate-colours[background],[foreground],[0.7]]
|
||||||
|
tiddler-controls-foreground-selected: [tf.interpolate-colours[background],[foreground],[0.9]]
|
||||||
|
tiddler-controls-foreground: [tf.interpolate-colours[background],[foreground],[0.5]]
|
||||||
|
tiddler-editor-background: #f8f8f8
|
||||||
|
tiddler-editor-border-image: #ffffff
|
||||||
|
tiddler-editor-border: #cccccc
|
||||||
|
tiddler-editor-fields-even: #e0e8e0
|
||||||
|
tiddler-editor-fields-odd: #f0f4f0
|
||||||
|
tiddler-info-background: #f8f8f8
|
||||||
|
tiddler-info-border: #dddddd
|
||||||
|
tiddler-info-tab-background: #f8f8f8
|
||||||
|
tiddler-link-background: [tf.colour[background]]
|
||||||
|
tiddler-link-foreground: [tf.colour[primary]]
|
||||||
|
tiddler-subtitle-foreground: [tf.interpolate-colours[background],[foreground],[0.6]]
|
||||||
|
tiddler-title-foreground: [tf.interpolate-colours[background],[foreground],[0.9]]
|
||||||
|
toolbar-cancel-button:
|
||||||
|
toolbar-close-button:
|
||||||
|
toolbar-delete-button:
|
||||||
|
toolbar-done-button:
|
||||||
|
toolbar-edit-button:
|
||||||
|
toolbar-info-button:
|
||||||
|
toolbar-new-button:
|
||||||
|
toolbar-options-button:
|
||||||
|
toolbar-save-button:
|
||||||
|
tour-chooser-button-foreground: <<colour very-muted-foreground>>
|
||||||
|
tour-chooser-button-hover-background: <<colour muted-foreground>>
|
||||||
|
tour-chooser-button-hover-foreground: <<colour background>>
|
||||||
|
tour-chooser-button-selected-background: <<colour primary>>
|
||||||
|
tour-chooser-button-selected-foreground: <<colour background>>
|
||||||
|
tour-chooser-dropdown-foreground: <<colour very-muted-foreground>>
|
||||||
|
tour-chooser-item-background: <<colour background>>
|
||||||
|
tour-chooser-item-border: <<colour muted-foreground>>
|
||||||
|
tour-chooser-item-foreground: <<colour foreground>>
|
||||||
|
tour-chooser-item-shadow: <<colour muted-foreground>>
|
||||||
|
tour-chooser-item-start-background: <<colour download-background>>
|
||||||
|
tour-chooser-item-start-foreground: <<colour background>>
|
||||||
|
tour-chooser-item-start-hover-background: <<colour primary>>
|
||||||
|
tour-chooser-item-start-hover-foreground: <<colour background>>
|
||||||
|
tour-fullscreen-background: <<colour page-background>>
|
||||||
|
tour-fullscreen-controls-foreground: <<colour muted-foreground>>
|
||||||
|
tour-navigation-buttons-back-background: red
|
||||||
|
tour-navigation-buttons-back-foreground: white
|
||||||
|
tour-navigation-buttons-hint-background: purple
|
||||||
|
tour-navigation-buttons-hint-foreground: white
|
||||||
|
tour-navigation-buttons-hover-background: <<colour foreground>>
|
||||||
|
tour-navigation-buttons-hover-foreground: <<colour background>>
|
||||||
|
tour-navigation-buttons-next-background: purple
|
||||||
|
tour-navigation-buttons-next-foreground: white
|
||||||
|
tour-overlay-background: #cbfff8
|
||||||
|
tour-overlay-border: #228877
|
||||||
|
tour-step-heading-background: none
|
||||||
|
tour-step-task-background: <<colour download-background>>
|
||||||
|
tour-step-task-foreground: <<colour download-foreground>>
|
||||||
|
untagged-background: #999999
|
||||||
|
very-muted-foreground: #888888
|
||||||
|
wikilist-background: #e5e5e5
|
||||||
|
wikilist-button-background: #acacac
|
||||||
|
wikilist-button-foreground: #000000
|
||||||
|
wikilist-button-open-hover: green
|
||||||
|
wikilist-button-open: #4fb82b
|
||||||
|
wikilist-button-remove-hover: red
|
||||||
|
wikilist-button-remove: #d85778
|
||||||
|
wikilist-button-reveal-hover: blue
|
||||||
|
wikilist-button-reveal: #5778d8
|
||||||
|
wikilist-droplink-dragover: [tf.colour[base-secondary]colour-set-alpha[0.7]]
|
||||||
|
wikilist-info: #000000
|
||||||
|
wikilist-item: #ffffff
|
||||||
|
wikilist-title-svg: [tf.colour[wikilist-title]]
|
||||||
|
wikilist-title: #666666
|
||||||
|
wikilist-toolbar-background: #d3d3d3
|
||||||
|
wikilist-toolbar-foreground: #888888
|
||||||
|
wikilist-url: #aaaaaa
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
title: $:/palettes/TwentyTwenties/Customisations
|
||||||
|
|
||||||
|
\procedure layer-input-actions()
|
||||||
|
<$action-setfield $tiddler=<<layerTitle>> palette-import={{$:/palette}}/>
|
||||||
|
\end layer-input-actions
|
||||||
|
|
||||||
|
\procedure entry(name,description)
|
||||||
|
<$text text=<<description>>/>: <$edit-text tiddler=<<layerTitle>> index=<<name>> type="color" tag="input" default={{{ [function[colour],<name>] }}} inputActions=<<layer-input-actions>>/>
|
||||||
|
\end entry
|
||||||
|
|
||||||
|
<$let layerTitle={{{ [function[tf.palette-customisations-layer]] }}}>
|
||||||
|
|
||||||
|
<<entry name:"base-paper" description:"Paper">>
|
||||||
|
|
||||||
|
<<entry name:"base-background" description:"Page background">>
|
||||||
|
|
||||||
|
<<entry name:"base-ink" description:"Ink">>
|
||||||
|
|
||||||
|
<<entry name:"base-primary" description:"Primary">>
|
||||||
|
|
||||||
|
<<entry name:"base-secondary" description:"Secondary">>
|
||||||
|
|
||||||
|
<<entry name:"base-tertiary" description:"Tertiary">>
|
||||||
|
|
||||||
|
</$let>
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
title: $:/palettes/TwentyTwenties/Dark
|
||||||
|
name: TwentyTwenties Dark
|
||||||
|
description: Modern and flexible, Darkish
|
||||||
|
tags: $:/tags/Palette
|
||||||
|
type: application/x-tiddler-dictionary
|
||||||
|
color-scheme: dark
|
||||||
|
palette-import: $:/palettes/TwentyTwenties
|
||||||
|
category: 2026
|
||||||
|
|
||||||
|
base-paper: #111122
|
||||||
|
base-background: #f5f0f9
|
||||||
|
base-ink: #8C8F80
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
title: $:/palettes/TwentyTwenties/Green
|
||||||
|
name: TwentyTwenties (Green)
|
||||||
|
description: Modern and flexible, Greenish
|
||||||
|
tags: $:/tags/Palette
|
||||||
|
type: application/x-tiddler-dictionary
|
||||||
|
color-scheme: light
|
||||||
|
palette-import: $:/palettes/TwentyTwenties
|
||||||
|
category: 2026
|
||||||
|
|
||||||
|
base-paper: rgb(188, 255, 161)
|
||||||
|
base-background: rgb(94, 192, 145)
|
||||||
|
base-primary: #6e803c
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
title: $:/palettes/TwentyTwenties/GreenP3
|
||||||
|
name: TwentyTwenties (Green P3)
|
||||||
|
description: Modern and flexible, Greenish and super bright
|
||||||
|
tags: $:/tags/Palette
|
||||||
|
type: application/x-tiddler-dictionary
|
||||||
|
color-scheme: light
|
||||||
|
palette-import: $:/palettes/TwentyTwenties
|
||||||
|
category: 2026
|
||||||
|
|
||||||
|
base-paper: color(display-p3 0.281 1 0.584 / 1)
|
||||||
|
base-background: color(display-p3 1 1 0 / 1)
|
||||||
|
base-primary: color(display-p3 1 0.563 1 / 1)
|
||||||
|
|
||||||
@@ -4,6 +4,7 @@ description: Pale and unobtrusive
|
|||||||
tags: $:/tags/Palette
|
tags: $:/tags/Palette
|
||||||
type: application/x-tiddler-dictionary
|
type: application/x-tiddler-dictionary
|
||||||
color-scheme: light
|
color-scheme: light
|
||||||
|
category: Legacy
|
||||||
|
|
||||||
alert-background: #ffe476
|
alert-background: #ffe476
|
||||||
alert-border: #b99e2f
|
alert-border: #b99e2f
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
title: $:/palettes/VanillaCherry
|
||||||
|
name: Vanilla Cherry
|
||||||
|
category: 2026
|
||||||
|
description: Pale and unobtrusive with a cherry on top
|
||||||
|
tags: $:/tags/Palette
|
||||||
|
type: application/x-tiddler-dictionary
|
||||||
|
color-scheme: light
|
||||||
|
palette-import: $:/palettes/Vanilla
|
||||||
|
|
||||||
|
primary: rgb(224, 32, 86)
|
||||||
|
menubar-foreground: #fff
|
||||||
|
menubar-background: <<colour primary>>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
title: $:/palettes/background/contrast-tests
|
||||||
|
type: application/x-tiddler-dictionary
|
||||||
|
tags: $:/tags/BackgroundPalette
|
||||||
|
|
||||||
|
?background-foreground-contrast: [tf.check-colour-contrast[background],[foreground],[45]]
|
||||||
|
?alert-contrast: [tf.check-colour-contrast[alert-background],[foreground],[45]]
|
||||||
|
?code-contrast: [tf.check-colour-contrast[code-background],[code-foreground],[45]]
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
title: $:/core/stylesheets/custom-properties
|
title: $:/core/stylesheets/custom-properties
|
||||||
|
|
||||||
\rules only transcludeinline macrocallinline html transcludeblock
|
\rules only transcludeinline macrocallinline html transcludeblock filteredtranscludeinline
|
||||||
|
|
||||||
/* Tiddlywiki's CSS properties */
|
/* Tiddlywiki's CSS properties */
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
<$list filter="[[$:/palettes/Vanilla]indexes[]]">
|
<$list filter="[[$:/temp/palette-colours]indexes[]!prefix[?]]">
|
||||||
--tpc-<<currentTiddler>>: <$transclude $variable="colour" $mode="inline" name=<<currentTiddler>>/>;
|
--tpc-<<currentTiddler>>: <$transclude $variable="colour" $mode="inline" name=<<currentTiddler>>/>;
|
||||||
</$list>
|
</$list>
|
||||||
|
|
||||||
@@ -21,10 +21,10 @@ title: $:/core/stylesheets/custom-properties
|
|||||||
--tp-story-left: {{$:/themes/tiddlywiki/vanilla/metrics/storyleft}};
|
--tp-story-left: {{$:/themes/tiddlywiki/vanilla/metrics/storyleft}};
|
||||||
--tp-story-top: {{$:/themes/tiddlywiki/vanilla/metrics/storytop}};
|
--tp-story-top: {{$:/themes/tiddlywiki/vanilla/metrics/storytop}};
|
||||||
--tp-story-right: {{$:/themes/tiddlywiki/vanilla/metrics/storyright}};
|
--tp-story-right: {{$:/themes/tiddlywiki/vanilla/metrics/storyright}};
|
||||||
--tp-story-width: {{$:/themes/tiddlywiki/vanilla/metrics/storyrwidth}};
|
--tp-story-width: {{$:/themes/tiddlywiki/vanilla/metrics/storywidth}};
|
||||||
--tp-tiddler-width: {{$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth}};
|
--tp-tiddler-width: {{$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth}};
|
||||||
--tp-sidebar-breakpoint: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}};
|
--tp-sidebar-breakpoint: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}};
|
||||||
--tp-sidebar-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth}};
|
--tp-sidebar-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth}};
|
||||||
|
|
||||||
--tp-animation-duration: {{{ [{$:/config/AnimationDuration}addsuffix[ms]] }}};
|
--tp-animation-duration: {{{ [{$:/config/AnimationDuration}addsuffix[ms]] }}};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
title: $:/core/templates/plain-text
|
||||||
|
|
||||||
|
<$text text=<<text>>/>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
title: $:/core/templates/rendered-text
|
||||||
|
|
||||||
|
<<text>>
|
||||||
@@ -4,13 +4,15 @@ description: create a new journal tiddler
|
|||||||
|
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
\function get-tags() [<textFieldTags>] [<tagsFieldTags>] +[join[ ]]
|
\function get-tags() [<textFieldTags>] [<tagsFieldTags>] +[join[ ]]
|
||||||
<$let journalTitleTemplate={{$:/config/NewJournal/Title}} textFieldTags={{$:/config/NewJournal/Tags}} tagsFieldTags={{$:/config/NewJournal/Tags!!tags}} journalText={{$:/config/NewJournal/Text}}>
|
<$let journalTitle=<<now format={{$:/config/NewJournal/Title}}>>
|
||||||
<$wikify name="journalTitle" text="<$transclude $variable='now' format=<<journalTitleTemplate>>/>">
|
textFieldTags={{$:/config/NewJournal/Tags}}
|
||||||
|
tagsFieldTags={{$:/config/NewJournal/Tags!!tags}}
|
||||||
|
journalText={{$:/config/NewJournal/Text}}
|
||||||
|
>
|
||||||
<$reveal type="nomatch" state=<<journalTitle>> text="">
|
<$reveal type="nomatch" state=<<journalTitle>> text="">
|
||||||
<$action-sendmessage $message="tm-new-tiddler" title=<<journalTitle>> tags=<<get-tags>> text={{{ [<journalTitle>get[]] }}}/>
|
<$action-sendmessage $message="tm-new-tiddler" title=<<journalTitle>> tags=<<get-tags>> text={{{ [<journalTitle>get[]] }}}/>
|
||||||
</$reveal>
|
</$reveal>
|
||||||
<$reveal type="match" state=<<journalTitle>> text="">
|
<$reveal type="match" state=<<journalTitle>> text="">
|
||||||
<$action-sendmessage $message="tm-new-tiddler" title=<<journalTitle>> tags=<<get-tags>> text=<<journalText>>/>
|
<$action-sendmessage $message="tm-new-tiddler" title=<<journalTitle>> tags=<<get-tags>> text=<<journalText>>/>
|
||||||
</$reveal>
|
</$reveal>
|
||||||
</$wikify>
|
|
||||||
</$let>
|
</$let>
|
||||||
|
|||||||
@@ -6,5 +6,5 @@ caption: {{$:/language/ControlPanel/Appearance/Caption}}
|
|||||||
{{$:/language/ControlPanel/Appearance/Hint}}
|
{{$:/language/ControlPanel/Appearance/Hint}}
|
||||||
|
|
||||||
<div class="tc-control-panel">
|
<div class="tc-control-panel">
|
||||||
<$macrocall $name="tabs" tabsList="[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Appearance]!has[draft.of]]" default="$:/core/ui/ControlPanel/Theme" explicitState="$:/state/tab--1963855381"/>
|
<$macrocall $name="tabs" tabsList="[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Appearance]!has[draft.of]]" default="$:/core/ui/ControlPanel/Palette" explicitState="$:/state/tab--1963855381"/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,20 +2,4 @@ title: $:/core/ui/ControlPanel/Palette
|
|||||||
tags: $:/tags/ControlPanel/Appearance
|
tags: $:/tags/ControlPanel/Appearance
|
||||||
caption: {{$:/language/ControlPanel/Palette/Caption}}
|
caption: {{$:/language/ControlPanel/Palette/Caption}}
|
||||||
|
|
||||||
\define lingo-base() $:/language/ControlPanel/Palette/
|
{{$:/PaletteManager}}
|
||||||
|
|
||||||
{{$:/snippets/paletteswitcher}}
|
|
||||||
|
|
||||||
<$reveal type="nomatch" state="$:/state/ShowPaletteEditor" text="yes">
|
|
||||||
|
|
||||||
<$button set="$:/state/ShowPaletteEditor" setTo="yes"><<lingo ShowEditor/Caption>></$button>
|
|
||||||
|
|
||||||
</$reveal>
|
|
||||||
|
|
||||||
<$reveal type="match" state="$:/state/ShowPaletteEditor" text="yes">
|
|
||||||
|
|
||||||
<$button set="$:/state/ShowPaletteEditor" setTo="no"><<lingo HideEditor/Caption>></$button>
|
|
||||||
{{$:/PaletteManager}}
|
|
||||||
|
|
||||||
</$reveal>
|
|
||||||
|
|
||||||
@@ -108,10 +108,10 @@ tags: $:/tags/EditTemplate
|
|||||||
storeTitle=<<newFieldNameInputTiddler>>
|
storeTitle=<<newFieldNameInputTiddler>>
|
||||||
searchListState=<<newFieldNameSelectionTiddler>>
|
searchListState=<<newFieldNameSelectionTiddler>>
|
||||||
>
|
>
|
||||||
<div class="tc-edit-field-add-name-wrapper">
|
<div class=`tc-edit-field-add-name-wrapper ${ [<newFieldNameTiddler>get[text]] :intersection[<storyTiddler>fields[]] :then[[tc-edit-field-exists]] }$`>
|
||||||
<$transclude $variable="keyboard-driven-input"
|
<$transclude $variable="keyboard-driven-input"
|
||||||
cancelPopups="yes"
|
cancelPopups="yes"
|
||||||
class=`tc-edit-texteditor tc-popup-handle ${ [<newFieldNameTiddler>get[text]] :intersection[<storyTiddler>fields[]] :then[[tc-edit-field-exists]] }$`
|
class="tc-edit-texteditor tc-popup-handle"
|
||||||
configTiddlerFilter="[[$:/config/EditMode/fieldname-filter]]"
|
configTiddlerFilter="[[$:/config/EditMode/fieldname-filter]]"
|
||||||
default=""
|
default=""
|
||||||
focus={{{ [{!!draft.of}is[tiddler]then{$:/config/AutoFocusEdit}match[fields]then[true]] :else[{$:/config/AutoFocus}match[fields]then[true]] :else[[false]] }}}
|
focus={{{ [{!!draft.of}is[tiddler]then{$:/config/AutoFocusEdit}match[fields]then[true]] :else[{$:/config/AutoFocus}match[fields]then[true]] :else[[false]] }}}
|
||||||
@@ -178,4 +178,4 @@ tags: $:/tags/EditTemplate
|
|||||||
</$let>
|
</$let>
|
||||||
</$let>
|
</$let>
|
||||||
</div>
|
</div>
|
||||||
</$let>
|
</$let>
|
||||||
|
|||||||
@@ -6,30 +6,25 @@ tags: $:/tags/EditTemplate
|
|||||||
\procedure lingo-base() $:/language/EditTemplate/
|
\procedure lingo-base() $:/language/EditTemplate/
|
||||||
|
|
||||||
\procedure tag-body-inner(colour,fallbackTarget,colourA,colourB,icon,tagField:"tags")
|
\procedure tag-body-inner(colour,fallbackTarget,colourA,colourB,icon,tagField:"tags")
|
||||||
<$wikify name="foregroundColor"
|
<$let foregroundColor=<<contrastcolour target=<<colour>> fallbackTarget=<<fallbackTarget>> colourA=<<colourA>> colourB=<<colourB>> >>
|
||||||
text="""<$macrocall $name="contrastcolour"
|
backgroundColor=<<colour>>
|
||||||
target=<<colour>>
|
>
|
||||||
fallbackTarget=<<fallbackTarget>>
|
<span class="tc-tag-label tc-tag-list-item tc-small-gap-right"
|
||||||
colourA=<<colourA>>
|
data-tag-title=<<currentTiddler>>
|
||||||
colourB=<<colourB>>/>
|
style=`color:$(foregroundColor)$; fill:$(foregroundColor)$; background-color:$(backgroundColor)$;`
|
||||||
"""
|
>
|
||||||
>
|
<$transclude tiddler=<<icon>>/>
|
||||||
<$let backgroundColor=<<colour>> >
|
<$view field="title" format="text"/>
|
||||||
<span class="tc-tag-label tc-tag-list-item tc-small-gap-right"
|
<$button class="tc-btn-invisible tc-remove-tag-button"
|
||||||
data-tag-title=<<currentTiddler>>
|
style.fill=<<foregroundColor>>
|
||||||
style=`color:$(foregroundColor)$; fill:$(foregroundColor)$; background-color:$(backgroundColor)$;`
|
|
||||||
>
|
>
|
||||||
<$transclude tiddler=<<icon>>/>
|
<$action-listops $tiddler=<<saveTiddler>> $field=<<tagField>> $subfilter="-[{!!title}]"/>
|
||||||
<$view field="title" format="text"/>
|
<!-- Touch a temp tiddler so that the tag remove animation fires instantly. Otherwise it's delayed by the typing timeout duration -->
|
||||||
<$button class="tc-btn-invisible tc-remove-tag-button"
|
<$action-setfield $tiddler="$:/temp/tags-edit-refresh" text=<<currentTiddler>>/>
|
||||||
style.fill=<<foregroundColor>>
|
{{$:/core/images/close-button}}
|
||||||
>
|
</$button>
|
||||||
<$action-listops $tiddler=<<saveTiddler>> $field=<<tagField>> $subfilter="-[{!!title}]"/>
|
</span>
|
||||||
{{$:/core/images/close-button}}
|
</$let>
|
||||||
</$button>
|
|
||||||
</span>
|
|
||||||
</$let>
|
|
||||||
</$wikify>
|
|
||||||
\end
|
\end
|
||||||
|
|
||||||
\procedure tag-body(colour,palette,icon,tagField:"tags")
|
\procedure tag-body(colour,palette,icon,tagField:"tags")
|
||||||
@@ -48,7 +43,7 @@ tags: $:/tags/EditTemplate
|
|||||||
<$list filter="[<currentTiddler>get<tagField>enlist-input[]sort[title]]" storyview="pop">
|
<$list filter="[<currentTiddler>get<tagField>enlist-input[]sort[title]]" storyview="pop">
|
||||||
<$macrocall $name="tag-body"
|
<$macrocall $name="tag-body"
|
||||||
colour={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}
|
colour={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}
|
||||||
palette={{$:/palette}}
|
palette="$:/temp/palette-colours"
|
||||||
icon={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]!is[draft]get[text]] }}}
|
icon={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]!is[draft]get[text]] }}}
|
||||||
tagField=<<tagField>>
|
tagField=<<tagField>>
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -0,0 +1,105 @@
|
|||||||
|
title: $:/PaletteEditor
|
||||||
|
|
||||||
|
\define lingo-base() $:/language/ControlPanel/Palette/Editor/
|
||||||
|
\define describePaletteColour(colour)
|
||||||
|
<$transclude tiddler="$:/language/Docs/PaletteColours/$colour$"><$text text="$colour$"/></$transclude>
|
||||||
|
\end
|
||||||
|
\define edit-colour-placeholder()
|
||||||
|
edit $(colourName)$
|
||||||
|
\end
|
||||||
|
\define colour-tooltip(showhide) $showhide$ editor for $(newColourName)$
|
||||||
|
|
||||||
|
\define resolve-colour(macrocall)
|
||||||
|
\import $:/core/macros/utils
|
||||||
|
\whitespace trim
|
||||||
|
<$wikify name="name" text="""$macrocall$""">
|
||||||
|
<<name>>
|
||||||
|
</$wikify>
|
||||||
|
\end
|
||||||
|
|
||||||
|
\define delete-colour-index-actions() <$action-setfield $index=<<colourName>>/>
|
||||||
|
\define palette-manager-colour-row-segment()
|
||||||
|
\whitespace trim
|
||||||
|
<$edit-text index=<<colourName>> tag="input" placeholder=<<edit-colour-placeholder>> default=""/>
|
||||||
|
<br>
|
||||||
|
<$edit-text index=<<colourName>> type="color" tag="input" class="tc-palette-manager-colour-input"/>
|
||||||
|
<$list filter="[<currentTiddler>getindex<colourName>removeprefix[<<]removesuffix[>>]] [<currentTiddler>getindex<colourName>removeprefix[<$]removesuffix[/>]]" variable="ignore">
|
||||||
|
<$set name="state" value={{{ [[$:/state/palettemanager/]addsuffix<currentTiddler>addsuffix[/]addsuffix<colourName>] }}}>
|
||||||
|
<$wikify name="newColourName" text="""<$macrocall $name="resolve-colour" macrocall={{{ [<currentTiddler>getindex<colourName>] }}}/>""">
|
||||||
|
<$reveal state=<<state>> type="nomatch" text="show">
|
||||||
|
<$button tooltip=<<colour-tooltip show>> aria-label=<<colour-tooltip show>> class="tc-btn-invisible" set=<<state>> setTo="show">{{$:/core/images/down-arrow}}<$text text=<<newColourName>> class="tc-small-gap-left"/></$button><br>
|
||||||
|
</$reveal>
|
||||||
|
<$reveal state=<<state>> type="match" text="show">
|
||||||
|
<$button tooltip=<<colour-tooltip hide>> aria-label=<<colour-tooltip show>> class="tc-btn-invisible" actions="""<$action-deletetiddler $tiddler=<<state>>/>""">{{$:/core/images/up-arrow}}<$text text=<<newColourName>> class="tc-small-gap-left"/></$button><br>
|
||||||
|
</$reveal>
|
||||||
|
<$reveal state=<<state>> type="match" text="show">
|
||||||
|
<$set name="colourName" value=<<newColourName>>>
|
||||||
|
<br>
|
||||||
|
<<palette-manager-colour-row-segment>>
|
||||||
|
<br><br>
|
||||||
|
</$set>
|
||||||
|
</$reveal>
|
||||||
|
</$wikify>
|
||||||
|
</$set>
|
||||||
|
</$list>
|
||||||
|
\end
|
||||||
|
|
||||||
|
\define palette-manager-colour-row()
|
||||||
|
\whitespace trim
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<span style="float:right;">
|
||||||
|
<$button tooltip={{$:/language/ControlPanel/Palette/Editor/Delete/Hint}} aria-label={{$:/language/ControlPanel/Palette/Editor/Delete/Hint}} class="tc-btn-invisible" actions=<<delete-colour-index-actions>>>
|
||||||
|
{{$:/core/images/delete-button}}</$button>
|
||||||
|
</span>
|
||||||
|
''<$macrocall $name="describePaletteColour" colour=<<colourName>>/>''<br/>
|
||||||
|
<$macrocall $name="colourName" $output="text/plain"/>
|
||||||
|
<%if [<layerTitle>getindex<colourName>] %>
|
||||||
|
<br/><em><<lingo Customised/Entry>></em>
|
||||||
|
<%endif%>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<<palette-manager-colour-row-segment>>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
\end
|
||||||
|
|
||||||
|
\define palette-manager-table()
|
||||||
|
\whitespace trim
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<$set name="colorList" filter="[{$:/state/palettemanager/showexternal}match[yes]]"
|
||||||
|
value="[all[shadows+tiddlers]tag[$:/tags/Palette]indexes[]]" emptyValue="[<currentTiddler>indexes[]]">
|
||||||
|
<$list filter=<<colorList>> variable="colourName"> <<palette-manager-colour-row>> </$list>
|
||||||
|
</$set>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
\end
|
||||||
|
\whitespace trim
|
||||||
|
<$set name="currentTiddler" value={{$:/palette}}>
|
||||||
|
<$let layerTitle={{{ [function[tf.palette-customisations-layer]] }}}>
|
||||||
|
|
||||||
|
<<lingo Prompt>> <$link to={{$:/palette}}><$macrocall $name="currentTiddler" $output="text/plain"/></$link>
|
||||||
|
|
||||||
|
<$list filter="[function[tf.palette-customisations-layer]is[tiddler]]" variable="listItem">
|
||||||
|
<<lingo Customised/Prompt>>
|
||||||
|
 
|
||||||
|
<$button actions="""<$action-deletetiddler $tiddler=<<layerTitle>>/>""">{{$:/language/ControlPanel/Palette/Customisations/Reset/Caption}}</$button>
|
||||||
|
</$list>
|
||||||
|
|
||||||
|
<$list filter="[all[current]is[shadow]is[tiddler]]" variable="listItem">
|
||||||
|
<<lingo Prompt/Modified>>
|
||||||
|
 
|
||||||
|
<$button message="tm-delete-tiddler" param={{$:/palette}}><<lingo Reset/Caption>></$button>
|
||||||
|
</$list>
|
||||||
|
|
||||||
|
<$list filter="[all[current]is[shadow]!is[tiddler]]" variable="listItem">
|
||||||
|
<<lingo Clone/Prompt>>
|
||||||
|
</$list>
|
||||||
|
|
||||||
|
<$button message="tm-new-tiddler" param={{$:/palette}}><<lingo Clone/Caption>></$button>
|
||||||
|
|
||||||
|
<$checkbox tiddler="$:/state/palettemanager/showexternal" field="text" checked="yes" unchecked="no"><span class="tc-small-gap-left"><<lingo Names/External/Show>></span></$checkbox>
|
||||||
|
|
||||||
|
<<palette-manager-table>>
|
||||||
|
</$let>
|
||||||
+43
-87
@@ -1,94 +1,50 @@
|
|||||||
title: $:/PaletteManager
|
title: $:/PaletteManager
|
||||||
|
|
||||||
\define lingo-base() $:/language/ControlPanel/Palette/Editor/
|
\define lingo-base() $:/language/ControlPanel/Palette/
|
||||||
\define describePaletteColour(colour)
|
|
||||||
<$transclude tiddler="$:/language/Docs/PaletteColours/$colour$"><$text text="$colour$"/></$transclude>
|
|
||||||
\end
|
|
||||||
\define edit-colour-placeholder()
|
|
||||||
edit $(colourName)$
|
|
||||||
\end
|
|
||||||
\define colour-tooltip(showhide) $showhide$ editor for $(newColourName)$
|
|
||||||
|
|
||||||
\define resolve-colour(macrocall)
|
<!-- Used by the language string Customisations/Prompt -->
|
||||||
\import $:/core/macros/utils
|
\procedure palette-link()
|
||||||
\whitespace trim
|
<$tiddler tiddler={{$:/palette}}>
|
||||||
<$wikify name="name" text="""$macrocall$""">
|
<$link to={{!!title}}>
|
||||||
<<name>>
|
<$view field="name" format="text">
|
||||||
</$wikify>
|
<$view field="title" format="text"/>
|
||||||
\end
|
</$view>
|
||||||
|
</$link>
|
||||||
|
</$tiddler>
|
||||||
|
\end palette-link
|
||||||
|
|
||||||
|
<$transclude $tiddler="$:/snippets/paletteswitcher" thumbnails="yes"/>
|
||||||
|
|
||||||
|
{{$:/snippets/palettetests}}
|
||||||
|
|
||||||
|
<$let
|
||||||
|
resolvedPalette={{{ [{$:/palette}is[tiddler]] [{$:/palette}is[shadow]] :else[[$:/palettes/Vanilla]] }}}
|
||||||
|
paletteCustomisations={{{ [<resolvedPalette>get[customisations]] :else[[$:/temp/palette-consolidated]get[customisations]] }}}
|
||||||
|
layerTitle={{{ [function[tf.palette-customisations-layer]] }}}
|
||||||
|
>
|
||||||
|
<%if [<paletteCustomisations>!match[]] %>
|
||||||
|
<div>
|
||||||
|
<<lingo Customisations/Prompt>>
|
||||||
|
<$transclude $tiddler=<<paletteCustomisations>> $mode="block"/>
|
||||||
|
</div>
|
||||||
|
<%endif%>
|
||||||
|
<%if [<layerTitle>is[tiddler]] %>
|
||||||
|
<div>
|
||||||
|
<$button actions="""<$action-deletetiddler $tiddler=<<layerTitle>>/>"""><<lingo Customisations/Reset/Caption>></$button>
|
||||||
|
</div>
|
||||||
|
<%endif%>
|
||||||
|
</$let>
|
||||||
|
|
||||||
|
<$reveal type="nomatch" state="$:/state/ShowPaletteEditor" text="yes">
|
||||||
|
|
||||||
|
<$button set="$:/state/ShowPaletteEditor" setTo="yes"><<lingo ShowEditor/Caption>></$button>
|
||||||
|
|
||||||
\define delete-colour-index-actions() <$action-setfield $index=<<colourName>>/>
|
|
||||||
\define palette-manager-colour-row-segment()
|
|
||||||
\whitespace trim
|
|
||||||
<$edit-text index=<<colourName>> tag="input" placeholder=<<edit-colour-placeholder>> default=""/>
|
|
||||||
<br>
|
|
||||||
<$edit-text index=<<colourName>> type="color" tag="input" class="tc-palette-manager-colour-input"/>
|
|
||||||
<$list filter="[<currentTiddler>getindex<colourName>removeprefix[<<]removesuffix[>>]] [<currentTiddler>getindex<colourName>removeprefix[<$]removesuffix[/>]]" variable="ignore">
|
|
||||||
<$set name="state" value={{{ [[$:/state/palettemanager/]addsuffix<currentTiddler>addsuffix[/]addsuffix<colourName>] }}}>
|
|
||||||
<$wikify name="newColourName" text="""<$macrocall $name="resolve-colour" macrocall={{{ [<currentTiddler>getindex<colourName>] }}}/>""">
|
|
||||||
<$reveal state=<<state>> type="nomatch" text="show">
|
|
||||||
<$button tooltip=<<colour-tooltip show>> aria-label=<<colour-tooltip show>> class="tc-btn-invisible" set=<<state>> setTo="show">{{$:/core/images/down-arrow}}<$text text=<<newColourName>> class="tc-small-gap-left"/></$button><br>
|
|
||||||
</$reveal>
|
</$reveal>
|
||||||
<$reveal state=<<state>> type="match" text="show">
|
|
||||||
<$button tooltip=<<colour-tooltip hide>> aria-label=<<colour-tooltip show>> class="tc-btn-invisible" actions="""<$action-deletetiddler $tiddler=<<state>>/>""">{{$:/core/images/up-arrow}}<$text text=<<newColourName>> class="tc-small-gap-left"/></$button><br>
|
<$reveal type="match" state="$:/state/ShowPaletteEditor" text="yes">
|
||||||
|
|
||||||
|
<$button set="$:/state/ShowPaletteEditor" setTo="no"><<lingo HideEditor/Caption>></$button>
|
||||||
|
{{$:/PaletteEditor}}
|
||||||
|
|
||||||
</$reveal>
|
</$reveal>
|
||||||
<$reveal state=<<state>> type="match" text="show">
|
|
||||||
<$set name="colourName" value=<<newColourName>>>
|
|
||||||
<br>
|
|
||||||
<<palette-manager-colour-row-segment>>
|
|
||||||
<br><br>
|
|
||||||
</$set>
|
|
||||||
</$reveal>
|
|
||||||
</$wikify>
|
|
||||||
</$set>
|
|
||||||
</$list>
|
|
||||||
\end
|
|
||||||
|
|
||||||
\define palette-manager-colour-row()
|
|
||||||
\whitespace trim
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<span style="float:right;">
|
|
||||||
<$button tooltip={{$:/language/ControlPanel/Palette/Editor/Delete/Hint}} aria-label={{$:/language/ControlPanel/Palette/Editor/Delete/Hint}} class="tc-btn-invisible" actions=<<delete-colour-index-actions>>>
|
|
||||||
{{$:/core/images/delete-button}}</$button>
|
|
||||||
</span>
|
|
||||||
''<$macrocall $name="describePaletteColour" colour=<<colourName>>/>''<br/>
|
|
||||||
<$macrocall $name="colourName" $output="text/plain"/>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<<palette-manager-colour-row-segment>>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
\end
|
|
||||||
|
|
||||||
\define palette-manager-table()
|
|
||||||
\whitespace trim
|
|
||||||
<table>
|
|
||||||
<tbody>
|
|
||||||
<$set name="colorList" filter="[{$:/state/palettemanager/showexternal}match[yes]]"
|
|
||||||
value="[all[shadows+tiddlers]tag[$:/tags/Palette]indexes[]]" emptyValue="[<currentTiddler>indexes[]]">
|
|
||||||
<$list filter=<<colorList>> variable="colourName"> <<palette-manager-colour-row>> </$list>
|
|
||||||
</$set>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
\end
|
|
||||||
\whitespace trim
|
|
||||||
<$set name="currentTiddler" value={{$:/palette}}>
|
|
||||||
|
|
||||||
<<lingo Prompt>> <$link to={{$:/palette}}><$macrocall $name="currentTiddler" $output="text/plain"/></$link>
|
|
||||||
|
|
||||||
<$list filter="[all[current]is[shadow]is[tiddler]]" variable="listItem">
|
|
||||||
<<lingo Prompt/Modified>>
|
|
||||||
 
|
|
||||||
<$button message="tm-delete-tiddler" param={{$:/palette}}><<lingo Reset/Caption>></$button>
|
|
||||||
</$list>
|
|
||||||
|
|
||||||
<$list filter="[all[current]is[shadow]!is[tiddler]]" variable="listItem">
|
|
||||||
<<lingo Clone/Prompt>>
|
|
||||||
</$list>
|
|
||||||
|
|
||||||
<$button message="tm-new-tiddler" param={{$:/palette}}><<lingo Clone/Caption>></$button>
|
|
||||||
|
|
||||||
<$checkbox tiddler="$:/state/palettemanager/showexternal" field="text" checked="yes" unchecked="no"><span class="tc-small-gap-left"><<lingo Names/External/Show>></span></$checkbox>
|
|
||||||
|
|
||||||
<<palette-manager-table>>
|
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
title: $:/core/ui/Palettes/Preview/Alert
|
||||||
|
tags: $:/tags/Preview/Page
|
||||||
|
|
||||||
|
\whitespace trim
|
||||||
|
<div class="tc-palette-preview-thumbnail-alert" style.background-color=<<colour alert-background>>>
|
||||||
|
<div class="tc-palette-preview-thumbnail-alert-border" style.border-color=<<colour alert-border>>>
|
||||||
|
<div style.color=<<colour foreground>>>
|
||||||
|
<div class="tc-palette-preview-thumbnail-alert-subtitle" style.color=<<colour alert-muted-foreground>>>
|
||||||
|
Lorem Ipsum
|
||||||
|
<div class="tc-palette-preview-thumbnail-alert-highlight" style.color=<<colour alert-highlight>>>
|
||||||
|
(Count: 1)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tc-palette-preview-thumbnail-alert-body">
|
||||||
|
Lorem Ipsum Dolor Sit Amet Consectetur Adipiscing Elit Sed Do Eiusmod Tempor Incididunt.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
title: $:/core/ui/Palettes/Preview/Helpers
|
||||||
|
tags: $:/tags/Preview/Helpers
|
||||||
|
|
||||||
|
\whitespace trim
|
||||||
|
|
||||||
|
\procedure palette-preview-component-list(tag)
|
||||||
|
<$list filter="[all[shadows+tiddlers]tag<tag>!has[draft.of]]" variable="componentTitle">
|
||||||
|
<$transclude $tiddler=<<componentTitle>> title=<<title>>/>
|
||||||
|
</$list>
|
||||||
|
\end palette-preview-component-list
|
||||||
|
|
||||||
|
\procedure tab-set(tabTitles,colourPrefix:"")
|
||||||
|
<div class="tc-palette-preview-thumbnail-tab-set">
|
||||||
|
<div class="tc-palette-preview-thumbnail-tab-buttons">
|
||||||
|
<$list filter="[enlist<tabTitles>]" variable="tabTitle" counter="tabIndex">
|
||||||
|
<%if [<tabIndex>match[1]] %>
|
||||||
|
<span
|
||||||
|
class="tc-palette-preview-thumbnail-tab-button"
|
||||||
|
style.border-color={{{ [<colourPrefix>addsuffix[tab-border-selected]] :map[function[colour],<currentTiddler>] }}}
|
||||||
|
style.color={{{ [<colourPrefix>addsuffix[tab-foreground-selected]] :map[function[colour],<currentTiddler>] }}}
|
||||||
|
style.background-color={{{ [<colourPrefix>addsuffix[tab-background-selected]] :map[function[colour],<currentTiddler>] }}}
|
||||||
|
>
|
||||||
|
<$text text=<<tabTitle>>/>
|
||||||
|
</span>
|
||||||
|
<%else%>
|
||||||
|
<span
|
||||||
|
class="tc-palette-preview-thumbnail-tab-button"
|
||||||
|
style.border-color={{{ [<colourPrefix>addsuffix[tab-border]] :map[function[colour],<currentTiddler>] }}}
|
||||||
|
style.color={{{ [<colourPrefix>addsuffix[tab-foreground]] :map[function[colour],<currentTiddler>] }}}
|
||||||
|
style.background-color={{{ [<colourPrefix>addsuffix[tab-background]] :map[function[colour],<currentTiddler>] }}}
|
||||||
|
>
|
||||||
|
<$text text=<<tabTitle>>/>
|
||||||
|
</span>
|
||||||
|
<%endif%>
|
||||||
|
</$list>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="tc-palette-preview-thumbnail-tab-divider"
|
||||||
|
style.border-color={{{ [<colourPrefix>addsuffix[tab-divider]] :map[function[colour],<currentTiddler>] }}}
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
\end tab-set
|
||||||
|
|
||||||
|
\procedure link(text)
|
||||||
|
<span class="tc-palette-preview-thumbnail-tiddler-link" style.color=<<colour primary>>>
|
||||||
|
<$text text=<<text>>/>
|
||||||
|
</span>
|
||||||
|
\end link
|
||||||
|
|
||||||
|
\procedure sidebar-link(text)
|
||||||
|
<span class="tc-palette-preview-thumbnail-tiddler-link" style.color=<<colour sidebar-tiddler-link-foreground>>>
|
||||||
|
<$text text=<<text>>/>
|
||||||
|
</span>
|
||||||
|
\end sidebar-link
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
title: $:/core/ui/Palettes/Preview/Notification
|
||||||
|
tags: $:/tags/Preview/PageOptional
|
||||||
|
|
||||||
|
\whitespace trim
|
||||||
|
<div class="tc-palette-preview-thumbnail-notification" style.background-color=<<colour notification-background>>>
|
||||||
|
<div class="tc-palette-preview-thumbnail-notification-border" style.border-color=<<colour notification-border>>>
|
||||||
|
<div class="tc-palette-preview-thumbnail-notification-body" style.color=<<colour foreground>>>
|
||||||
|
Lorem Ipsum Dolor Sit Amet Consectetur
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
title: $:/core/ui/Palettes/Preview/Sidebar/Search
|
||||||
|
tags: $:/tags/Preview/SideBar
|
||||||
|
|
||||||
|
\whitespace trim
|
||||||
|
<div class="tc-palette-preview-thumbnail-sidebar-search" style.background-color=<<colour background>>>
|
||||||
|
<div class="tc-palette-preview-thumbnail-sidebar-search-box">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
title: $:/core/ui/Palettes/Preview/Sidebar/Subtitle
|
||||||
|
tags: $:/tags/Preview/SideBar
|
||||||
|
|
||||||
|
\whitespace trim
|
||||||
|
<div class="tc-palette-preview-thumbnail-sidebar-subtitle">
|
||||||
|
a non-linear personal web notebook
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
title: $:/core/ui/Palettes/Preview/Sidebar/Tabs
|
||||||
|
tags: $:/tags/Preview/SideBar
|
||||||
|
|
||||||
|
\whitespace trim
|
||||||
|
|
||||||
|
\procedure recent-links()
|
||||||
|
HelloThere Community Portal GettingStarted Development Download Filters Palettes Plugins Macros Templates Themes Stylesheets SystemTiddlers
|
||||||
|
\end recent-links
|
||||||
|
|
||||||
|
<<tab-set "Magna Placerat Ligula Imperdiet" "sidebar-">>
|
||||||
|
|
||||||
|
<div class="tc-palette-preview-thumbnail-sidebar-list">
|
||||||
|
<$list filter="[enlist<recent-links>]">
|
||||||
|
<div>
|
||||||
|
<$transclude $variable="sidebar-link" text=<<currentTiddler>>/>
|
||||||
|
</div>
|
||||||
|
</$list>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
title: $:/core/ui/Palettes/Preview/Sidebar/Title
|
||||||
|
tags: $:/tags/Preview/SideBar
|
||||||
|
|
||||||
|
\whitespace trim
|
||||||
|
<div class="tc-palette-preview-thumbnail-sidebar-title" style.color=<<colour site-title-foreground>>>
|
||||||
|
~TiddlyWiki
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
title: $:/core/ui/Palettes/Preview/SideBar
|
||||||
|
tags: $:/tags/Preview/Page
|
||||||
|
|
||||||
|
\whitespace trim
|
||||||
|
<div class="tc-palette-preview-thumbnail-sidebar" style.color=<<colour sidebar-foreground>>>
|
||||||
|
<<palette-preview-component-list "$:/tags/Preview/SideBar">>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
title: $:/core/ui/Palettes/Preview/Story
|
||||||
|
tags: $:/tags/Preview/Page
|
||||||
|
|
||||||
|
\whitespace trim
|
||||||
|
<div class="tc-palette-preview-thumbnail-story">
|
||||||
|
<$list filter="HelloThere GettingStarted" variable="title">
|
||||||
|
<<palette-preview-component-list "$:/tags/Preview/Story">>
|
||||||
|
</$list>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
title: $:/core/ui/Palettes/Preview/Tiddler
|
||||||
|
tags: $:/tags/Preview/Story
|
||||||
|
|
||||||
|
\parameters (title)
|
||||||
|
\whitespace trim
|
||||||
|
<div class="tc-palette-preview-thumbnail-tiddler-border" style.border-color=<<colour tiddler-border>>>
|
||||||
|
<div class="tc-palette-preview-thumbnail-tiddler" style.background-color=<<colour tiddler-background>>>
|
||||||
|
<<palette-preview-component-list "$:/tags/Preview/Tiddler">>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
title: $:/core/ui/Palettes/Preview/Tiddler/Body
|
||||||
|
tags: $:/tags/Preview/Tiddler
|
||||||
|
|
||||||
|
\whitespace trim
|
||||||
|
|
||||||
|
<div class="tc-palette-preview-thumbnail-tiddler-body" style.color=<<colour foreground>>>
|
||||||
|
<%if [<title>match[HelloThere]] %>
|
||||||
|
Lorem ipsum dolor sit amet, <<link "consectetur adipiscing elit">>. Cras non arcu ultricies, egestas odio tempus, vestibulum ipsum. Praesent diam lorem, elementum in venenatis eget, tincidunt quis lacus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam efficitur velit tortor, sit amet tristique felis viverra sit amet. <<link "Nullam posuere facilisis purus sed">> consectetur. Integer vel elit euismod, posuere ligula et, dictum tellus. Donec in odio diam. Sed metus magna, placerat at ligula et, imperdiet sagittis ex.
|
||||||
|
<%else%>
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||||
|
<<tab-set "Sed Metus Magna Placerat Ligula Imperdiet">>
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras non arcu ultricies, egestas odio tempus, vestibulum ipsum. Praesent diam lorem, elementum in venenatis eget, tincidunt quis lacus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.
|
||||||
|
<%endif%>
|
||||||
|
</div>
|
||||||
|
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
title: $:/core/ui/Palettes/Preview/Tiddler/Header
|
||||||
|
tags: $:/tags/Preview/Tiddler
|
||||||
|
|
||||||
|
\whitespace trim
|
||||||
|
<div class="tc-palette-preview-thumbnail-tiddler-header">
|
||||||
|
<div class="tc-palette-preview-thumbnail-tiddler-title" style.color=<<colour tiddler-title-foreground>>>
|
||||||
|
<$text text=<<title>>/>
|
||||||
|
</div>
|
||||||
|
<div class="tc-palette-preview-thumbnail-tiddler-toolbar" style.fill=<<colour tiddler-controls-foreground>>>
|
||||||
|
{{$:/core/images/down-arrow}}
|
||||||
|
{{$:/core/images/edit-button}}
|
||||||
|
{{$:/core/images/close-button}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
title: $:/core/ui/Palettes/Preview/Tiddler/Subtitle
|
||||||
|
tags: $:/tags/Preview/Tiddler
|
||||||
|
|
||||||
|
\whitespace trim
|
||||||
|
<div class="tc-palette-preview-thumbnail-tiddler-subtitle" style.color=<<colour tiddler-subtitle-foreground>>>
|
||||||
|
Motovun Jack
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
title: $:/core/ui/Palettes/ViewTemplateBody
|
||||||
|
|
||||||
|
<div style.width="220px">
|
||||||
|
|
||||||
|
{{||$:/snippets/currpalettepreview}}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
''<$view field="name" format="text"/>''
|
||||||
|
<br>
|
||||||
|
<$view field="description" format="text"/>
|
||||||
@@ -16,15 +16,13 @@ title: $:/core/ui/TagPickerTagTemplate
|
|||||||
<$set name="backgroundColor"
|
<$set name="backgroundColor"
|
||||||
value={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}
|
value={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}
|
||||||
>
|
>
|
||||||
<$wikify name="foregroundColor"
|
<$let foregroundColor=<<contrastcolour target=<<backgroundColor>> fallbackTarget=<<fallbackTarget>> colourA=<<colourA>> colourB=<<colourB>> >> >
|
||||||
text="""<$macrocall $name="contrastcolour" target=<<backgroundColor>> fallbackTarget=<<fallbackTarget>> colourA=<<colourA>> colourB=<<colourB>>/>"""
|
|
||||||
>
|
|
||||||
<span class="tc-tag-label tc-btn-invisible"
|
<span class="tc-tag-label tc-btn-invisible"
|
||||||
style=<<tag-pill-styles>>
|
style=<<tag-pill-styles>>
|
||||||
data-tag-title=<<currentTiddler>>
|
data-tag-title=<<currentTiddler>>
|
||||||
>
|
>
|
||||||
{{||$:/core/ui/TiddlerIcon}}<$view field="title" format="text"/>
|
{{||$:/core/ui/TiddlerIcon}}<$view field="title" format="text"/>
|
||||||
</span>
|
</span>
|
||||||
</$wikify>
|
</$let>
|
||||||
</$set>
|
</$set>
|
||||||
</$button>
|
</$button>
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ title: $:/core/ui/TagTemplate
|
|||||||
tag=<<currentTiddler>>
|
tag=<<currentTiddler>>
|
||||||
icon={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]!is[draft]get[text]] }}}
|
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]] }}}
|
colour={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}
|
||||||
palette={{$:/palette}}
|
|
||||||
element-tag="$button"
|
element-tag="$button"
|
||||||
element-attributes="""popup=<<qualify "$:/state/popup/tag">> dragFilter="[subfilter{$:/core/config/TagPillDragFilter}]" tag='span'"""
|
element-attributes="""popup=<<qualify "$:/state/popup/tag">> dragFilter="[subfilter{$:/core/config/TagPillDragFilter}]" tag='span'"""
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ description: {{$:/language/Buttons/NewJournalHere/Hint}}
|
|||||||
\whitespace trim
|
\whitespace trim
|
||||||
\procedure journalButton()
|
\procedure journalButton()
|
||||||
<$button tooltip={{$:/language/Buttons/NewJournalHere/Hint}} aria-label={{$:/language/Buttons/NewJournalHere/Caption}} class=<<tv-config-toolbar-class>>>
|
<$button tooltip={{$:/language/Buttons/NewJournalHere/Hint}} aria-label={{$:/language/Buttons/NewJournalHere/Caption}} class=<<tv-config-toolbar-class>>>
|
||||||
<$wikify name="journalTitle" text="""<$transclude $variable="now" format=<<journalTitleTemplate>>/>""">
|
|
||||||
<$action-sendmessage $message="tm-new-tiddler" title=<<journalTitle>> tags=`[[$(currentTiddlerTag)$]] $(journalTags)$`/>
|
<$action-sendmessage $message="tm-new-tiddler" title=<<journalTitle>> tags=`[[$(currentTiddlerTag)$]] $(journalTags)$`/>
|
||||||
<%if [<tv-config-toolbar-icons>match[yes]] %>
|
<%if [<tv-config-toolbar-icons>match[yes]] %>
|
||||||
{{$:/core/images/new-journal-button}}
|
{{$:/core/images/new-journal-button}}
|
||||||
@@ -16,9 +15,11 @@ description: {{$:/language/Buttons/NewJournalHere/Hint}}
|
|||||||
<$text text={{$:/language/Buttons/NewJournalHere/Caption}}/>
|
<$text text={{$:/language/Buttons/NewJournalHere/Caption}}/>
|
||||||
</span>
|
</span>
|
||||||
<%endif%>
|
<%endif%>
|
||||||
</$wikify>
|
|
||||||
</$button>
|
</$button>
|
||||||
\end
|
\end
|
||||||
<$let journalTitleTemplate={{$:/config/NewJournal/Title}} journalTags={{$:/config/NewJournal/Tags}} currentTiddlerTag=<<currentTiddler>>>
|
<$let journalTitle=<<now format={{$:/config/NewJournal/Title}}>>
|
||||||
|
journalTags={{$:/config/NewJournal/Tags}}
|
||||||
|
currentTiddlerTag=<<currentTiddler>>
|
||||||
|
>
|
||||||
<<journalButton>>
|
<<journalButton>>
|
||||||
</$let>
|
</$let>
|
||||||
|
|||||||
@@ -17,6 +17,10 @@ This page summarises high level information about the configuration of this ~Tid
|
|||||||
Drag this link to copy this tool to another wiki
|
Drag this link to copy this tool to another wiki
|
||||||
\end intrinsic-lingo-Drag/Caption
|
\end intrinsic-lingo-Drag/Caption
|
||||||
|
|
||||||
|
\procedure intrinsic-lingo-Generate/Caption()
|
||||||
|
Click to generate wiki information report
|
||||||
|
\end intrinsic-lingo-Generate/Caption
|
||||||
|
|
||||||
\procedure lingo(title,mode:"inline")
|
\procedure lingo(title,mode:"inline")
|
||||||
<%if [<title>addprefix<lingo-base>is[shadow]] %>
|
<%if [<title>addprefix<lingo-base>is[shadow]] %>
|
||||||
<$transclude $tiddler={{{ [<title>addprefix<lingo-base>] }}} $mode=<<mode>>/>
|
<$transclude $tiddler={{{ [<title>addprefix<lingo-base>] }}} $mode=<<mode>>/>
|
||||||
@@ -105,7 +109,7 @@ Drag this link to copy this tool to another wiki
|
|||||||
|
|
||||||
<$button>
|
<$button>
|
||||||
<<display-wiki-info-modal>>
|
<<display-wiki-info-modal>>
|
||||||
Click to generate wiki information report
|
<<lingo title:"Generate/Caption">>
|
||||||
</$button>
|
</$button>
|
||||||
|
|
||||||
<$link to="$:/core/ui/ControlPanel/WikiInformation">
|
<$link to="$:/core/ui/ControlPanel/WikiInformation">
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
title: $:/core/background-actions/AutoCompilePalette
|
||||||
|
tags: $:/tags/BackgroundAction $:/tags/StartupAction
|
||||||
|
platforms: browser
|
||||||
|
track-filter: [{$:/palette}get[color-scheme]] :map[subfilter<currentTiddler>] [{$:/palette}changecount[]addprefix{$:/palette}] [[$:/palette]changecount[]] =[all[shadows+tiddlers]tag[$:/tags/Palette]changecount[]] =[all[shadows+tiddlers]tag[$:/tags/BackgroundPalette]changecount[]] =[all[tiddlers]prefix[$:/config/PaletteCustomisations/]changecount[]]
|
||||||
|
|
||||||
|
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
||||||
|
<<actions-recompile-current-palette>>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
title: $:/config/OfficialPluginLibrary
|
title: $:/config/OfficialPluginLibrary
|
||||||
tags: $:/tags/PluginLibrary
|
tags: $:/tags/PluginLibrary
|
||||||
url: https://tiddlywiki.com/library/v5.4.1/index.html
|
url: https://tiddlywiki.com/library/v5.5.0/index.html
|
||||||
caption: {{$:/language/OfficialPluginLibrary}}
|
caption: {{$:/language/OfficialPluginLibrary}}
|
||||||
|
|
||||||
{{$:/language/OfficialPluginLibrary/Hint}}
|
{{$:/language/OfficialPluginLibrary/Hint}}
|
||||||
|
|||||||
@@ -10,4 +10,5 @@ code-body: [field:code-body[yes]then[$:/core/ui/ViewTemplate/body/code]]
|
|||||||
import: [field:plugin-type[import]then[$:/core/ui/ViewTemplate/body/import]]
|
import: [field:plugin-type[import]then[$:/core/ui/ViewTemplate/body/import]]
|
||||||
plugin: [has[plugin-type]then[$:/core/ui/ViewTemplate/body/plugin]]
|
plugin: [has[plugin-type]then[$:/core/ui/ViewTemplate/body/plugin]]
|
||||||
hide-body: [field:hide-body[yes]then[$:/core/ui/ViewTemplate/body/blank]]
|
hide-body: [field:hide-body[yes]then[$:/core/ui/ViewTemplate/body/blank]]
|
||||||
|
palette: [tag[$:/tags/Palette]then[$:/core/ui/Palettes/ViewTemplateBody]]
|
||||||
default: [[$:/core/ui/ViewTemplate/body/default]]
|
default: [[$:/core/ui/ViewTemplate/body/default]]
|
||||||
|
|||||||
@@ -1,52 +1,12 @@
|
|||||||
title: $:/snippets/currpalettepreview
|
title: $:/snippets/currpalettepreview
|
||||||
|
|
||||||
\define resolve-colour(macrocall)
|
|
||||||
\import $:/core/macros/utils
|
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<$wikify name="name" text="""$macrocall$""">
|
|
||||||
<<name>>
|
\import [all[shadows+tiddlers]tag[$:/tags/Preview/Helpers]!is[draft]sort[title]]
|
||||||
</$wikify>
|
|
||||||
\end
|
<!-- currentTiddler is the palette to use -->
|
||||||
\define swatchStyle()
|
<$palette.preview paletteTitle=<<currentTiddler>>>
|
||||||
background-color: $(swatchColour)$;
|
<div class="tc-palette-preview-thumbnail" style.background-color=<<colour page-background>>>
|
||||||
\end
|
<<palette-preview-component-list tag:"$:/tags/Preview/Page">>
|
||||||
\define swatch-inner()
|
</div>
|
||||||
\whitespace trim
|
</$palette.preview>
|
||||||
<$set name="swatchColour" value={{##$(colourResolved)$}}>
|
|
||||||
<$list filter="[<swatchColour>!prefix[<<colour ]!suffix[>>]]" variable="ignore">
|
|
||||||
<div class="tc-swatch" style=<<swatchStyle>> title=<<swatchTitle>>/>
|
|
||||||
 
|
|
||||||
</$list>
|
|
||||||
<$list filter="[<swatchColour>prefix[<<colour ]suffix[>>]]" variable="ignore">
|
|
||||||
<$wikify name="colourResolved" text="<$macrocall $name='resolve-colour' macrocall=<<swatchColour>>/>">
|
|
||||||
<<swatch-inner>>
|
|
||||||
</$wikify>
|
|
||||||
</$list>
|
|
||||||
</$set>
|
|
||||||
\end
|
|
||||||
\define swatch()
|
|
||||||
\whitespace trim
|
|
||||||
<$set name="swatchColour" value={{##$(colour)$}}>
|
|
||||||
<$set name="swatchTitle" value=<<colour>>>
|
|
||||||
<$list filter="[<swatchColour>!prefix[<<colour ]!suffix[>>]]" variable="ignore">
|
|
||||||
<div class="tc-swatch" style=<<swatchStyle>> title=<<swatchTitle>>/>
|
|
||||||
 
|
|
||||||
</$list>
|
|
||||||
<$list filter="[<swatchColour>prefix[<<colour ]suffix[>>]]" variable="ignore">
|
|
||||||
<$wikify name="colourResolved" text="<$macrocall $name='resolve-colour' macrocall=<<swatchColour>>/>">
|
|
||||||
<<swatch-inner>>
|
|
||||||
</$wikify>
|
|
||||||
</$list>
|
|
||||||
</$set>
|
|
||||||
</$set>
|
|
||||||
\end
|
|
||||||
\whitespace trim
|
|
||||||
<div class="tc-swatches-horiz"><$list filter="
|
|
||||||
foreground
|
|
||||||
background
|
|
||||||
muted-foreground
|
|
||||||
primary
|
|
||||||
page-background
|
|
||||||
tab-background
|
|
||||||
tiddler-info-background
|
|
||||||
" variable="colour"><<swatch>></$list></div>
|
|
||||||
|
|||||||
+167
-10
@@ -1,17 +1,174 @@
|
|||||||
title: $:/core/macros/CSS
|
title: $:/core/macros/CSS
|
||||||
tags: $:/tags/Macro
|
tags: $:/tags/Macro
|
||||||
|
|
||||||
<!-- Needs to stay that way for backwards compatibility. See GH issue: #8326 -->
|
\procedure actions-compile-palette-filtered(consolidatedPalette,outputPalette)
|
||||||
\define colour(name)
|
<!-- The $:/config/DefaultColourMappings/ fallback used below is unused by the core and is retained for compatibility with third party plugins -->
|
||||||
\whitespace trim
|
<!-- Note the join, needed to cope with palette entries containing spaces -->
|
||||||
<$transclude tiddler={{$:/palette}} index="$name$">
|
\function tf.colour(name) [<consolidatedPalette>getindex<name>] :else[[$:/config/DefaultColourMappings/]addsuffix<name>get[text]] :map[tf.colour-inner-transform-classic-palette-entry<currentTiddler>] :map[subfilter:all<currentTiddler>join[ ]]
|
||||||
<$transclude tiddler="$:/palettes/Vanilla" index="$name$">
|
\function colour(name) [tf.colour<name>]
|
||||||
<$transclude tiddler="$:/config/DefaultColourMappings/$name$"/>
|
\function color(name) [tf.colour<name>]
|
||||||
</$transclude>
|
<!-- Make the colour function use the input palette -->
|
||||||
</$transclude>
|
<$list filter="[<consolidatedPalette>indexes[]sort[]]" variable="colour-name">
|
||||||
\end
|
<$let filter-text={{{ [<consolidatedPalette>getindex<colour-name>] :else[[$:/config/DefaultColourMappings/]addsuffix<colour-name>get[text]] :map[tf.colour-inner-transform-classic-palette-entry<currentTiddler>] }}}>
|
||||||
|
<!-- Note the join, needed to cope with palette entries containing spaces -->
|
||||||
|
<$action-setfield $tiddler=<<outputPalette>> $index=<<colour-name>> $value={{{ [subfilter:all<filter-text>join[ ]] +[join[ ]] }}}/>
|
||||||
|
</$let>
|
||||||
|
</$list>
|
||||||
|
\end actions-compile-palette-filtered
|
||||||
|
|
||||||
\define color(name) <<colour $name$>>
|
\procedure actions-compile-palette-import(inputPalette,outputPalette,exclusions:"",scheme)
|
||||||
|
<%if [enlist<exclusions>!match<inputPalette>count[]] :map[enlist<exclusions>count[]compare:number:eq<currentTiddler>] +[!match[]] %>
|
||||||
|
<$set name="exclusions" filter="[enlist<exclusions>] [<inputPalette>]">
|
||||||
|
<!-- Recursively import any imported palette -->
|
||||||
|
<$let
|
||||||
|
prefixed-palette-import={{{ [[palette-import@]addsuffix<scheme>] }}}
|
||||||
|
inputPalette={{{ [<inputPalette>get<prefixed-palette-import>has[title]] :else[<inputPalette>get[palette-import]] }}}
|
||||||
|
>
|
||||||
|
<%if [<inputPalette>has[title]] %>
|
||||||
|
<$transclude $variable="actions-compile-palette-import" inputPalette=<<inputPalette>> outputPalette=<<outputPalette>> exclusions=<<exclusions>> scheme=<<scheme>>/>
|
||||||
|
<%endif%>
|
||||||
|
</$let>
|
||||||
|
<!-- Copy the unsuffixed palette entries -->
|
||||||
|
<$action-setmultiplefields $tiddler=<<outputPalette>> $indexes="[<inputPalette>indexes[]!regexp[@]sort[]]" $values="[<inputPalette>indexes[]!regexp[@]sort[]] :map[<inputPalette>getindex<currentTiddler>]"/>
|
||||||
|
<!-- Copy the suffixed palette entries with the suffix stripped, overriding any unsuffixed entries of the same name -->
|
||||||
|
<%if [<scheme>!is[blank]] %>
|
||||||
|
<$let
|
||||||
|
prefixed-scheme={{{ [<scheme>addprefix[@]] }}}
|
||||||
|
>
|
||||||
|
<$action-setmultiplefields $tiddler=<<outputPalette>> $indexes="[<inputPalette>indexes[]suffix<prefixed-scheme>sort[]removesuffix<prefixed-scheme>]" $values="[<inputPalette>indexes[]suffix<prefixed-scheme>sort[]] :map[<inputPalette>getindex<currentTiddler>]"/>
|
||||||
|
</$let>
|
||||||
|
<%endif%>
|
||||||
|
<!-- Copy the fields from the palette -->
|
||||||
|
<$action-setmultiplefields $tiddler=<<outputPalette>> $fields="[<inputPalette>fields[]sort[]] -title -tags -text -type" $values="[<inputPalette>fields[]sort[]] -title -tags -text -type :map[<inputPalette>get<currentTiddler>]"/>
|
||||||
|
</$set>
|
||||||
|
<%endif%>
|
||||||
|
\end actions-compile-palette-import
|
||||||
|
|
||||||
|
\procedure actions-compile-palette(inputPalette,outputPalette)
|
||||||
|
\procedure tv-action-refresh-policy() always
|
||||||
|
<$let
|
||||||
|
consolidatedPalette="$:/temp/palette-consolidated"
|
||||||
|
>
|
||||||
|
<!-- Compute the current scheme -->
|
||||||
|
<$let
|
||||||
|
color-scheme-filter={{{ [<inputPalette>get[color-scheme]] :else[<inputPalette>get[palette-import]get[color-scheme]] :else[[light]] }}}
|
||||||
|
scheme={{{ [subfilter:all<color-scheme-filter>] }}}
|
||||||
|
>
|
||||||
|
<!-- Clear the consolidated palette that stores the result of flattening the chain of imported input palettes -->
|
||||||
|
<$action-deletetiddler $tiddler=<<consolidatedPalette>>/>
|
||||||
|
<$action-setfield $tiddler=<<consolidatedPalette>> type="application/x-tiddler-dictionary"/>
|
||||||
|
<!-- Clear the output palette that stores the plain CSS values of palette entries -->
|
||||||
|
<$action-deletetiddler $tiddler=<<outputPalette>>/>
|
||||||
|
<$action-setfield $tiddler=<<outputPalette>> type="application/x-tiddler-dictionary"/>
|
||||||
|
<!-- Import the background palettes -->
|
||||||
|
<$list filter="[all[shadows+tiddlers]tag[$:/tags/BackgroundPalette]sort[]]" variable="palette-name">
|
||||||
|
<$transclude $variable="actions-compile-palette-import" inputPalette=<<palette-name>> outputPalette=<<consolidatedPalette>> scheme=<<scheme>>/>
|
||||||
|
</$list>
|
||||||
|
<!-- Consolidate the chain of palettes -->
|
||||||
|
<$transclude $variable="actions-compile-palette-import" inputPalette=<<inputPalette>> outputPalette=<<consolidatedPalette>> scheme=<<scheme>>/>
|
||||||
|
<!-- Save the current scheme in the output tiddler -->
|
||||||
|
<$action-setfield $tiddler=<<outputPalette>> $field="color-scheme" $value=<<scheme>>/>
|
||||||
|
<!-- Compile the temporary palette to the output palette -->
|
||||||
|
<$transclude $variable="actions-compile-palette-filtered" consolidatedPalette=<<consolidatedPalette>> outputPalette=<<outputPalette>>/>
|
||||||
|
<!-- Blank any entries with recursive definitions, reporting them via the readability test mechanism -->
|
||||||
|
<$list filter="[<outputPalette>indexes[]!prefix[?]] :filter[<outputPalette>getindex<currentTiddler>regexp[Excessive filter recursion]]" variable="entry-name">
|
||||||
|
<$action-setfield $tiddler=<<outputPalette>> $index=<<entry-name>> $value=""/>
|
||||||
|
<$action-setfield $tiddler=<<outputPalette>> $index={{{ [<entry-name>addprefix[?recursion-]] }}} $value={{{ [[the definition of ']addsuffix<entry-name>addsuffix[' is recursive]] }}}/>
|
||||||
|
</$list>
|
||||||
|
</$let>
|
||||||
|
</$let>
|
||||||
|
\end actions-compile-palette
|
||||||
|
|
||||||
|
<!-- Customisations of the current palette are stored in a layer tiddler that imports the palette itself -->
|
||||||
|
\function tf.palette-customisations-layer()
|
||||||
|
[{$:/palette}is[tiddler]] [{$:/palette}is[shadow]] :else[[$:/palettes/Vanilla]] :map[addprefix[$:/config/PaletteCustomisations/]]
|
||||||
|
\end tf.palette-customisations-layer
|
||||||
|
|
||||||
|
\procedure actions-recompile-current-palette()
|
||||||
|
\procedure tv-action-refresh-policy() always
|
||||||
|
<$let
|
||||||
|
resolvedPalette={{{ [{$:/palette}is[tiddler]] [{$:/palette}is[shadow]] :else[[$:/palettes/Vanilla]] }}}
|
||||||
|
inputPalette={{{ [function[tf.palette-customisations-layer]has[palette-import]] :else[<resolvedPalette>] }}}
|
||||||
|
>
|
||||||
|
<$transclude $variable="actions-compile-palette" inputPalette=<<inputPalette>> outputPalette="$:/temp/palette-colours"/>
|
||||||
|
</$let>
|
||||||
|
\end actions-recompile-current-palette
|
||||||
|
|
||||||
|
\procedure tv-palette-name() $:/temp/palette-colours
|
||||||
|
|
||||||
|
\function tf.colour(name)
|
||||||
|
[<tv-palette-name>getindex<name>] :else[[$:/config/DefaultColourMappings/]addsuffix<name>get[text]]
|
||||||
|
\end tf.colour
|
||||||
|
|
||||||
|
\function colour(name)
|
||||||
|
[tf.colour<name>]
|
||||||
|
\end colour
|
||||||
|
|
||||||
|
\function color(name)
|
||||||
|
[tf.colour<name>]
|
||||||
|
\end color
|
||||||
|
|
||||||
|
\procedure colour-function-prefix()
|
||||||
|
[tf.colour[
|
||||||
|
\end colour-function-prefix
|
||||||
|
|
||||||
|
\procedure colour-function-suffix()
|
||||||
|
]]
|
||||||
|
\end colour-function-suffix
|
||||||
|
|
||||||
|
\widget $palette.preview(paletteTitle)
|
||||||
|
\whitespace trim
|
||||||
|
<!-- The exclusions parameter guards against palettes that import each other in a loop -->
|
||||||
|
\function colour-inner-get-imported-palette(name,paletteTitle,exclusions)
|
||||||
|
[[palette-import@]addsuffix<scheme>] :map[<paletteTitle>get<currentTiddler>has[title]] +[!match[]] :else[<paletteTitle>get[palette-import]has[title]] +[!match[]] :filter[enlist<exclusions>match<currentTiddler>count[]compare:number:eq[0]] :map[function[colour-inner-descend-imported-palette],<name>,<currentTiddler>,<exclusions>,<paletteTitle>] +[!match[]]
|
||||||
|
\end colour-inner-get-imported-palette
|
||||||
|
|
||||||
|
<!-- Helper to extend the exclusions list with the parent palette before descending -->
|
||||||
|
\function colour-inner-descend-imported-palette(name,paletteTitle,exclusions,parentTitle)
|
||||||
|
[enlist<exclusions>] [<parentTitle>] +[format:titlelist[]join[ ]] :map[function[colour-inner-get-palette-entry],<name>,<paletteTitle>,<currentTiddler>]
|
||||||
|
\end colour-inner-descend-imported-palette
|
||||||
|
|
||||||
|
\function colour-inner-get-palette-entry(name,paletteTitle,exclusions)
|
||||||
|
[<name>addsuffix[@]addsuffix<scheme>] :map[<paletteTitle>getindex<currentTiddler>] +[!match[]] :else[<paletteTitle>getindex<name>] :map[tf.colour-inner-transform-classic-palette-entry<currentTiddler>] :else[function[colour-inner-get-imported-palette],<name>,<paletteTitle>,<exclusions>]
|
||||||
|
\end colour-inner-get-palette-entry
|
||||||
|
|
||||||
|
<!-- Note the join, needed to cope with palette entries containing spaces -->
|
||||||
|
\function tf.colour(name)
|
||||||
|
[function[colour-inner-get-palette-entry],<name>,<paletteTitle>] :else[[$:/config/DefaultColourMappings/]addsuffix<name>get[text]] :map[subfilter:all<currentTiddler>join[ ]]
|
||||||
|
\end tf.colour
|
||||||
|
|
||||||
|
\function colour(name)
|
||||||
|
[tf.colour<name>]
|
||||||
|
\end colour
|
||||||
|
|
||||||
|
\function color(name)
|
||||||
|
[tf.colour<name>]
|
||||||
|
\end color
|
||||||
|
|
||||||
|
<$let
|
||||||
|
color-scheme-filter={{{ [<paletteTitle>get[color-scheme]] :else[<paletteTitle>get[palette-import]get[color-scheme]] :else[[light]] }}}
|
||||||
|
scheme={{{ [subfilter:all<color-scheme-filter>] }}}
|
||||||
|
>
|
||||||
|
<$slot $name="ts-raw"/>
|
||||||
|
</$let>
|
||||||
|
\end $palette.preview
|
||||||
|
|
||||||
|
\function tf.colour-inner-transform-classic-palette-entry(colour-result)
|
||||||
|
[<colour-result>prefix[<<colour ]suffix[>>]removeprefix[<<colour ]removesuffix[>>]addprefix<colour-function-prefix>addsuffix<colour-function-suffix>] :else[<colour-result>]
|
||||||
|
\end tf.colour-inner-transform-classic-palette-entry
|
||||||
|
|
||||||
|
<!-- Translucent entries are composited over the background entry before their contrast is measured -->
|
||||||
|
\function tf.check-colour-contrast-subfunction()
|
||||||
|
[function[colour],[background]] =>backdrop [function[colour],<paletteEntryA>colour-composite<backdrop>] =>colourA [function[colour],<paletteEntryB>colour-composite<backdrop>] =>colourB [<colourA>] [<colourB>] +[colour-contrast[]fixed[3]]
|
||||||
|
\end tf.check-colour-contrast-subfunction
|
||||||
|
|
||||||
|
\function tf.check-colour-contrast(paletteEntryA,paletteEntryB,threshold)
|
||||||
|
[function[tf.check-colour-contrast-subfunction]compare:number:gt<threshold>then[ok]] :else[function[tf.check-colour-contrast-subfunction]addsuffix[: ]addsuffix<paletteEntryA>addsuffix[/]addsuffix<paletteEntryB>addsuffix[ contrast is too low]]
|
||||||
|
\end tf.check-colour-contrast
|
||||||
|
|
||||||
|
\function tf.interpolate-colours(paletteEntryA,paletteEntryB,weight)
|
||||||
|
[function[colour],<paletteEntryA>] =>colourA [function[colour],<paletteEntryB>] =>colourB [<weight>colour-interpolate:oklch<colourA>,<colourB>]
|
||||||
|
\end tf.interpolate-colours
|
||||||
|
|
||||||
\procedure datauri(title)
|
\procedure datauri(title)
|
||||||
<$macrocall $name="makedatauri" type={{{ [<title>get[type]] }}} text={{{ [<title>get[text]] }}} _canonical_uri={{{ [<title>get[_canonical_uri]] }}}/>
|
<$macrocall $name="makedatauri" type={{{ [<title>get[type]] }}} text={{{ [<title>get[text]] }}} _canonical_uri={{{ [<title>get[_canonical_uri]] }}}/>
|
||||||
|
|||||||
@@ -6,5 +6,5 @@ $:/language/
|
|||||||
\end
|
\end
|
||||||
|
|
||||||
\define lingo(title)
|
\define lingo(title)
|
||||||
{{$(lingo-base)$$title$}}
|
{{||$(lingo-base)$$title$}}
|
||||||
\end
|
\end
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ The second ESC tries to close the "draft tiddler"
|
|||||||
<!-- keep those variables because they may "bleed" into macros using old syntax -->
|
<!-- keep those variables because they may "bleed" into macros using old syntax -->
|
||||||
<!-- "nonSystemTagsFilter", "systemTagsFilter" __need to be the same__ as fields: "first-search-filter", "second-search-filter" -->
|
<!-- "nonSystemTagsFilter", "systemTagsFilter" __need to be the same__ as fields: "first-search-filter", "second-search-filter" -->
|
||||||
<$let
|
<$let
|
||||||
palette={{$:/palette}}
|
palette="$:/temp/palette-colours"
|
||||||
colourA={{{ [<palette>getindex[foreground]] }}}
|
colourA={{{ [<palette>getindex[foreground]] }}}
|
||||||
colourB={{{ [<palette>getindex[background]] }}}
|
colourB={{{ [<palette>getindex[background]] }}}
|
||||||
fallbackTarget={{{ [<palette>getindex[tag-background]] }}}
|
fallbackTarget={{{ [<palette>getindex[tag-background]] }}}
|
||||||
|
|||||||
@@ -28,15 +28,16 @@ color:$(foregroundColor)$;
|
|||||||
</$let>
|
</$let>
|
||||||
\end
|
\end
|
||||||
|
|
||||||
|
<!-- Note that the 'palette' parameter is unused and is only retained for backwards compatibility -->
|
||||||
\define tag-pill-body(tag,icon,colour,palette,element-tag,element-attributes,actions)
|
\define tag-pill-body(tag,icon,colour,palette,element-tag,element-attributes,actions)
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<$macrocall $name="tag-pill-inner"
|
<$macrocall $name="tag-pill-inner"
|
||||||
tag=<<__tag__>>
|
tag=<<__tag__>>
|
||||||
icon=<<__icon__>>
|
icon=<<__icon__>>
|
||||||
colour=<<__colour__>>
|
colour=<<__colour__>>
|
||||||
fallbackTarget={{$palette$##tag-background}}
|
fallbackTarget=<<colour tag-background>>
|
||||||
colourA={{$palette$##foreground}}
|
colourA=<<colour foreground>>
|
||||||
colourB={{$palette$##background}}
|
colourB=<<colour background>>
|
||||||
element-tag=<<__element-tag__>>
|
element-tag=<<__element-tag__>>
|
||||||
element-attributes=<<__element-attributes__>>
|
element-attributes=<<__element-attributes__>>
|
||||||
actions=<<__actions__>>
|
actions=<<__actions__>>
|
||||||
@@ -51,7 +52,6 @@ color:$(foregroundColor)$;
|
|||||||
tag=<<__tag__>>
|
tag=<<__tag__>>
|
||||||
icon={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]!is[draft]get[text]] }}}
|
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]] }}}
|
colour={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}
|
||||||
palette={{$:/palette}}
|
|
||||||
element-tag=<<__element-tag__>>
|
element-tag=<<__element-tag__>>
|
||||||
element-attributes=<<__element-attributes__>>
|
element-attributes=<<__element-attributes__>>
|
||||||
actions=<<__actions__>>/>
|
actions=<<__actions__>>/>
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
title: $:/palette
|
title: $:/palette
|
||||||
|
|
||||||
$:/palettes/Vanilla
|
$:/palettes/AutoToggle
|
||||||
@@ -1,19 +1,30 @@
|
|||||||
title: $:/snippets/paletteswitcher
|
title: $:/snippets/paletteswitcher
|
||||||
|
|
||||||
|
\parameters (thumbnails)
|
||||||
|
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<$linkcatcher to="$:/palette">
|
\procedure actions()
|
||||||
<div class="tc-chooser">
|
<$action-setfield $tiddler="$:/palette" text=<<navigateTo>>/>
|
||||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Palette]!is[draft]sort[name]]">
|
\end actions
|
||||||
<$set name="cls" filter="[all[current]prefix{$:/palette}]" value="tc-chooser-item tc-chosen" emptyValue="tc-chooser-item">
|
|
||||||
<div class=<<cls>>>
|
<!-- Display palette in currentTiddler with selection logic -->
|
||||||
<$link to={{!!title}}>
|
\procedure palette-entry(thumbnails)
|
||||||
''<$view field="name" format="text"/>''
|
<div class={{{ [<currentTiddler>match{$:/palette}then[tc-chosen]] tc-chooser-item +[join[ ]] }}}>
|
||||||
 - 
|
<$link to={{!!title}} aria-label=`${[[$:/language/ControlPanel/Palette/Caption]get[text]]}$ - ${[all[current]get[name]]}$. ${[all[current]get[description]]}$`>
|
||||||
<$view field="description" format="text"/>
|
<%if [<thumbnails>match[yes]] %>
|
||||||
{{||$:/snippets/currpalettepreview}}
|
{{||$:/snippets/currpalettepreview}}
|
||||||
</$link>
|
<%endif%>
|
||||||
</div>
|
''<$view field="name" format="text"/>''
|
||||||
</$set>
|
<br>
|
||||||
</$list>
|
<$view field="description" format="text"/>
|
||||||
|
</$link>
|
||||||
</div>
|
</div>
|
||||||
|
\end palette-entry
|
||||||
|
|
||||||
|
<$linkcatcher actions=<<actions>>>
|
||||||
|
<div class={{{ tc-chooser [<thumbnails>match[yes]then[tc-chooser-cards]] +[join[ ]] }}}>
|
||||||
|
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Palette]!is[draft]sort[name]]">
|
||||||
|
<$transclude $variable="palette-entry" thumbnails=<<thumbnails>>/>
|
||||||
|
</$list>
|
||||||
|
</div>
|
||||||
</$linkcatcher>
|
</$linkcatcher>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user