mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2026-07-14 15:52:46 +00:00
Compare commits
360 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 65605d7b72 | |||
| b3f9690941 | |||
| 038d9e474e | |||
| f5317dc225 | |||
| c952450c2e | |||
| 1eb7ec4402 | |||
| 869557f7d1 | |||
| c9f1154643 | |||
| 748f04c9e3 | |||
| d391595836 | |||
| 967140a148 | |||
| 95e68b0437 | |||
| 8ddede1611 | |||
| ceb200b08c | |||
| 00e5f48a59 | |||
| ea0e9105bc | |||
| 51459815ba | |||
| 8c62935a01 | |||
| 839fa2417d | |||
| 1b8610e4d8 | |||
| ca063cbe90 | |||
| 7d4328b2fb | |||
| 1ae224ab74 | |||
| c308fc44c4 | |||
| aa3fb85919 | |||
| bd052a33f8 | |||
| bb766c36c3 | |||
| 566a341328 | |||
| 9316234001 | |||
| c1cb93c9df | |||
| e46361fbc0 | |||
| e730836d6f | |||
| d050dd30cc | |||
| 635f6b5e76 | |||
| 40d0d542f7 | |||
| a66d9a596c | |||
| 23063ea9c8 | |||
| 9c1f69e9c1 | |||
| 6abfcb631d | |||
| 14b11575d0 | |||
| c9b1fbbb76 | |||
| 27c568e53e | |||
| 0023d3f6fa | |||
| 76ebe9d8e9 | |||
| 40444eade5 | |||
| fe8723be49 | |||
| 56ea0789e1 | |||
| fff648b959 | |||
| e1cff6068c | |||
| 6721164f15 | |||
| 3c37aa267d | |||
| a603146b3c | |||
| f992f4ffab | |||
| dfedd8594f | |||
| ea84baa5a3 | |||
| a4e4d36bf6 | |||
| 3ed481b2e2 | |||
| 27c60ff58d | |||
| 748ef8aa8d | |||
| 9cfa5a29fb | |||
| 5ea43ce212 | |||
| df6bbbdedf | |||
| 37a461323e | |||
| b29da7baac | |||
| 75b54457ed | |||
| 51f322c3c6 | |||
| 853af2d848 | |||
| 2c1cb33081 | |||
| 2f63abc12a | |||
| 5f80256576 | |||
| aa837300d0 | |||
| 7f2baa17a9 | |||
| 39c6d8fb53 | |||
| 9afe5226f1 | |||
| 94aa37fe7e | |||
| 1e9c1ef82a | |||
| 6cde5e94ff | |||
| fd0d3ccc27 | |||
| 1ad2e66cbc | |||
| 4699db9f89 | |||
| d977b0ac5c | |||
| 7298684951 | |||
| f78d8252af | |||
| 54260b5be8 | |||
| 95f12eb857 | |||
| 207a68cc59 | |||
| b434b9d7ea | |||
| b0013333de | |||
| bcc30e305a | |||
| 34f4dfb903 | |||
| 32a3a3e478 | |||
| c6520c4429 | |||
| 83d242fb2c | |||
| ecafb7a4c0 | |||
| 0640e0abe2 | |||
| a71ac56cc9 | |||
| f518bdf27c | |||
| 0387b1100b | |||
| c3a73fccd1 | |||
| c25659d87c | |||
| 0c26a75472 | |||
| a24dc0e9e8 | |||
| a499ed0906 | |||
| 3cfb6b1202 | |||
| ac769e5dcd | |||
| ed01af8e47 | |||
| 92caa7312e | |||
| 478dce7009 | |||
| f3c9cb2310 | |||
| 85fb634cae | |||
| 280701fbde | |||
| 01d3cde964 | |||
| 2ea3663ea7 | |||
| 78b6f6f442 | |||
| 3a4a8a206f | |||
| aff5be7195 | |||
| c4991a54a0 | |||
| 1d915389d9 | |||
| f5b4b1781e | |||
| 65fcded29f | |||
| 962692c90c | |||
| 533414b1df | |||
| ec27a4bf20 | |||
| e1cf523e2c | |||
| 1ece822d7a | |||
| b7a3418823 | |||
| bb6d88f144 | |||
| 57c72756ef | |||
| dda4c7fb10 | |||
| fd3b96e2dd | |||
| c07396c453 | |||
| 7fc255f90c | |||
| 4cd84a6ba1 | |||
| fdfcd66c9b | |||
| 3983086b96 | |||
| a61331e6ed | |||
| 8773a0433c | |||
| 846deb3039 | |||
| 111a168b0c | |||
| 02b4c04a56 | |||
| 9d5b5111d0 | |||
| 48cff401b2 | |||
| a3acbaa2f1 | |||
| 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 |
@@ -5,17 +5,17 @@ on:
|
||||
- master
|
||||
- tiddlywiki-com
|
||||
env:
|
||||
NODE_VERSION: "22"
|
||||
NODE_VERSION: "22.22"
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: "${{ env.NODE_VERSION }}"
|
||||
- run: "./bin/ci-test.sh"
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v7
|
||||
if: always()
|
||||
with:
|
||||
name: playwright-report
|
||||
@@ -30,8 +30,8 @@ jobs:
|
||||
TW5_BUILD_MAIN_EDITION: "./editions/prerelease"
|
||||
TW5_BUILD_OUTPUT: "./output/prerelease"
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: "${{ env.NODE_VERSION }}"
|
||||
- run: "./bin/ci-pre-build.sh"
|
||||
@@ -62,8 +62,8 @@ jobs:
|
||||
TW5_BUILD_OUTPUT: "./output"
|
||||
TW5_BUILD_ARCHIVE: "./output"
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: "${{ env.NODE_VERSION }}"
|
||||
- run: "./bin/ci-pre-build.sh"
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
steps:
|
||||
- name: build-size-check
|
||||
id: get_sizes
|
||||
uses: TiddlyWiki/cerebrus@v7
|
||||
uses: TiddlyWiki/cerebrus@v8.1
|
||||
with:
|
||||
pr_number: ${{ github.event.pull_request.number }}
|
||||
repo: ${{ github.repository }}
|
||||
@@ -52,4 +52,4 @@ jobs:
|
||||
pr_size: '${{ needs.calculate-build-size.outputs.pr_size }}',
|
||||
base_size: '${{ needs.calculate-build-size.outputs.base_size }}'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Build and check size
|
||||
uses: TiddlyWiki/cerebrus@v7
|
||||
uses: TiddlyWiki/cerebrus@v8.1
|
||||
with:
|
||||
pr_number: ${{ inputs.pr_number }}
|
||||
repo: ${{ github.repository }}
|
||||
|
||||
@@ -15,7 +15,7 @@ jobs:
|
||||
steps:
|
||||
# Step 1: Validate PR paths
|
||||
- name: Validate PR Paths
|
||||
uses: TiddlyWiki/cerebrus@v6
|
||||
uses: TiddlyWiki/cerebrus@v8.1
|
||||
with:
|
||||
pr_number: ${{ github.event.pull_request.number }}
|
||||
repo: ${{ github.repository }}
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
|
||||
# Step 2: Validate change notes
|
||||
- name: Validate Change Notes
|
||||
uses: TiddlyWiki/cerebrus@v7
|
||||
uses: TiddlyWiki/cerebrus@v8.1
|
||||
with:
|
||||
pr_number: ${{ github.event.pull_request.number }}
|
||||
repo: ${{ github.repository }}
|
||||
|
||||
+11
-1
@@ -2,10 +2,20 @@
|
||||
.c9/
|
||||
.vs/
|
||||
.vscode/
|
||||
.claude/
|
||||
# TiddlyWiki
|
||||
tmp/
|
||||
output/
|
||||
node_modules/
|
||||
$__StoryList.tid
|
||||
# Playwright
|
||||
/test-results/
|
||||
/playwright-report/
|
||||
/blob-report/
|
||||
/playwright/.cache/
|
||||
$__StoryList.tid
|
||||
/playwright/.auth/
|
||||
test-screenshots/
|
||||
test-output.txt
|
||||
.playwright-mcp
|
||||
# TiddlyWiki MPC
|
||||
.tw-mcp
|
||||
@@ -3,3 +3,4 @@
|
||||
tmp/
|
||||
output/
|
||||
node_modules/
|
||||
.claude/
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
# Default to the current version number for building the plugin library
|
||||
|
||||
if [ -z "$TW5_BUILD_VERSION" ]; then
|
||||
TW5_BUILD_VERSION=v5.4.0
|
||||
TW5_BUILD_VERSION=v5.5.0.
|
||||
fi
|
||||
|
||||
echo "Using TW5_BUILD_VERSION as [$TW5_BUILD_VERSION]"
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ git clone --depth=1 --branch=main "https://github.com/TiddlyWiki/tiddlywiki.org-
|
||||
|
||||
# Make the CNAME file that GitHub Pages requires
|
||||
|
||||
echo "tiddlywiki.org" > $TWORG_BUILD_OUTPUT/CNAME
|
||||
# echo "tiddlywiki.org" > $TWORG_BUILD_OUTPUT/CNAME
|
||||
|
||||
# Delete any existing static content
|
||||
|
||||
|
||||
+7
-3
@@ -47,6 +47,13 @@ $tw.utils.hop = function(object,property) {
|
||||
/** @deprecated Use Array.isArray instead */
|
||||
$tw.utils.isArray = (value) => Array.isArray(value);
|
||||
|
||||
/*
|
||||
Determine if a value is a date, even across VM boundaries
|
||||
*/
|
||||
$tw.utils.isDate = function(value) {
|
||||
return Object.prototype.toString.call(value) === "[object Date]";
|
||||
};
|
||||
|
||||
/*
|
||||
Check if an array is equal by value and by reference.
|
||||
*/
|
||||
@@ -124,9 +131,6 @@ $tw.utils.pushTop = function(array,value) {
|
||||
return array;
|
||||
};
|
||||
|
||||
/** @deprecated Use instanceof Date instead */
|
||||
$tw.utils.isDate = (value) => value instanceof Date;
|
||||
|
||||
/** @deprecated Use array iterative methods instead */
|
||||
$tw.utils.each = function(object,callback) {
|
||||
if(object) {
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,6 +1,7 @@
|
||||
created: 20250909171928024
|
||||
modified: 20251110133437795
|
||||
tags: Community/Team
|
||||
leader: @kjharcombe
|
||||
team: @MotovunJack
|
||||
title: Infrastructure Team
|
||||
|
||||
@@ -12,4 +13,4 @@ The infrastructure includes:
|
||||
* github.com/TiddlyWiki
|
||||
* tiddlywiki.com DNS
|
||||
* Netlify account for PR previews
|
||||
* edit.tiddlywiki.com
|
||||
* edit.tiddlywiki.com
|
||||
|
||||
@@ -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
|
||||
+1
-1
File diff suppressed because one or more lines are too long
@@ -9,15 +9,14 @@ Serve tiddlers over http
|
||||
|
||||
"use strict";
|
||||
|
||||
let fs, url, path, querystring, crypto, zlib;
|
||||
let fs, path, crypto, zlib, URL;
|
||||
|
||||
if($tw.node) {
|
||||
fs = require("fs"),
|
||||
url = require("url"),
|
||||
path = require("path"),
|
||||
querystring = require("querystring"),
|
||||
crypto = require("crypto"),
|
||||
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.boot = options.boot || self.boot;
|
||||
state.server = self;
|
||||
state.urlInfo = url.parse(request.url);
|
||||
state.queryParameters = querystring.parse(state.urlInfo.query);
|
||||
state.urlInfo = new URL(request.url, "http://localhost");
|
||||
state.queryParameters = Object.fromEntries(state.urlInfo.searchParams);
|
||||
state.pathPrefix = options.pathPrefix || this.get("path-prefix") || "";
|
||||
// Enable CORS
|
||||
if(this.corsEnable) {
|
||||
|
||||
@@ -58,10 +58,11 @@ LayoutSwitcher/Caption: Layout
|
||||
LoadedModules/Caption: Loaded Modules
|
||||
LoadedModules/Hint: These are the currently loaded tiddler modules linked to their source tiddlers. Any italicised modules lack a source tiddler, typically because they were setup during the boot process.
|
||||
Palette/Caption: Palette
|
||||
Palette/CustomSettings/Prompt: Custom settings for current palette: <<palette-link>>
|
||||
Palette/Editor/Clone/Caption: clone
|
||||
Palette/Editor/Clone/Prompt: It is recommended that you clone this shadow palette before editing it
|
||||
Palette/Editor/Delete/Hint: delete this entry from the current palette
|
||||
Palette/Editor/Names/External/Show: Show color names that are not part of the current palette
|
||||
Palette/Editor/Names/External/Show: Show inherited palette entries
|
||||
Palette/Editor/Prompt/Modified: This shadow palette has been modified
|
||||
Palette/Editor/Prompt: Editing
|
||||
Palette/Editor/Reset/Caption: reset
|
||||
|
||||
@@ -30,6 +30,7 @@ Error/DeserializeOperator/MissingOperand: Filter Error: Missing operand for 'des
|
||||
Error/DeserializeOperator/UnknownDeserializer: Filter Error: Unknown deserializer provided as operand for the 'deserialize' operator
|
||||
Error/Filter: Filter error
|
||||
Error/FilterSyntax: Syntax error in filter expression
|
||||
Error/FilterPragma: Filter Error: Unknown filter pragma
|
||||
Error/FilterRunPrefix: Filter Error: Unknown prefix for filter run
|
||||
Error/IsFilterOperator: Filter Error: Unknown parameter for the 'is' filter operator
|
||||
Error/FormatFilterOperator: Filter Error: Unknown suffix for the 'format' filter operator
|
||||
|
||||
@@ -10,7 +10,7 @@ Advanced/ShadowInfo/Shadow/Hint: The tiddler <$link to=<<infoTiddler>>><$text te
|
||||
Advanced/ShadowInfo/Shadow/Source: It is defined in the plugin <$link to=<<pluginTiddler>>><$text text=<<pluginTiddler>>/></$link>
|
||||
Advanced/ShadowInfo/OverriddenShadow/Hint: It is overridden by an ordinary tiddler
|
||||
Advanced/CascadeInfo/Heading: Cascade Details
|
||||
Advanced/CascadeInfo/Hint: These are the view template segments (tagged <<tag "$:/tags/ViewTemplate">>) using a cascade filter and their resulting template for the current tiddler.
|
||||
Advanced/CascadeInfo/Hint: These are the view template segments that are resolved for each of the system view template cascades
|
||||
Advanced/CascadeInfo/Detail/View: View
|
||||
Advanced/CascadeInfo/Detail/ActiveCascadeFilter: Active cascade filter
|
||||
Advanced/CascadeInfo/Detail/Template: Template
|
||||
|
||||
@@ -31,7 +31,7 @@ function FramedEngine(options) {
|
||||
this.parentNode.insertBefore(this.iframeNode,this.nextSibling);
|
||||
this.iframeDoc = this.iframeNode.contentWindow.document;
|
||||
// (Firefox requires us to put some empty content in the iframe)
|
||||
var paletteTitle = this.widget.wiki.getTiddlerText("$:/palette");
|
||||
var paletteTitle = this.widget.wiki.getTiddlerText("$:/palette/palette-colours");
|
||||
var colorScheme = (this.widget.wiki.getTiddler(paletteTitle) || {fields: {}}).fields["color-scheme"] || "light";
|
||||
this.iframeDoc.open();
|
||||
this.iframeDoc.write("<!DOCTYPE html><html><head><meta name='color-scheme' content='" + colorScheme + "'></head><body></body></html>");
|
||||
@@ -156,14 +156,13 @@ Fix the height of textarea to fit content
|
||||
FramedEngine.prototype.fixHeight = function() {
|
||||
// Make sure styles are updated
|
||||
this.copyStyles();
|
||||
// If .editRows is initialised, it takes precedence
|
||||
if(this.widget.editTag === "textarea" && !this.widget.editRows) {
|
||||
if(this.widget.editTag === "textarea") {
|
||||
if(this.widget.editAutoHeight) {
|
||||
if(this.domNode && !this.domNode.isTiddlyWikiFakeDom) {
|
||||
var newHeight = $tw.utils.resizeTextAreaToFit(this.domNode,this.widget.editMinHeight);
|
||||
this.iframeNode.style.height = newHeight + "px";
|
||||
}
|
||||
} else {
|
||||
} else if(!this.widget.editRows) {
|
||||
var fixedHeight = parseInt(this.widget.wiki.getTiddlerText(HEIGHT_VALUE_TITLE,"400px"),10);
|
||||
fixedHeight = Math.max(fixedHeight,20);
|
||||
this.domNode.style.height = fixedHeight + "px";
|
||||
|
||||
@@ -28,7 +28,12 @@ function SimpleEngine(options) {
|
||||
if(this.widget.editTag === "textarea") {
|
||||
this.domNode.appendChild(this.widget.document.createTextNode(this.value));
|
||||
} else {
|
||||
this.domNode.value = this.value;
|
||||
if(this.widget.editType === "color") {
|
||||
// The <input type="color"> element requires a six digit hex value
|
||||
this.domNode.value = $tw.utils.convertCSSColorToRGBString(this.value);
|
||||
} else {
|
||||
this.domNode.value = this.value;
|
||||
}
|
||||
}
|
||||
// Set the attributes
|
||||
if(this.widget.editType && this.widget.editTag !== "textarea") {
|
||||
@@ -83,6 +88,9 @@ Update the DomNode with the new text
|
||||
*/
|
||||
SimpleEngine.prototype.updateDomNodeText = function(text) {
|
||||
try {
|
||||
if(this.widget.editType === "color") {
|
||||
text = $tw.utils.convertCSSColorToRGBString(text);
|
||||
}
|
||||
this.domNode.value = text;
|
||||
} catch(e) {
|
||||
// Ignore
|
||||
@@ -100,13 +108,12 @@ SimpleEngine.prototype.getText = function() {
|
||||
Fix the height of textarea to fit content
|
||||
*/
|
||||
SimpleEngine.prototype.fixHeight = function() {
|
||||
// If .editRows is initialised, it takes precedence
|
||||
if((this.widget.editTag === "textarea") && !this.widget.editRows) {
|
||||
if(this.widget.editTag === "textarea") {
|
||||
if(this.widget.editAutoHeight) {
|
||||
if(this.domNode && !this.domNode.isTiddlyWikiFakeDom) {
|
||||
$tw.utils.resizeTextAreaToFit(this.domNode,this.widget.editMinHeight);
|
||||
}
|
||||
} else {
|
||||
} else if(!this.widget.editRows) {
|
||||
var fixedHeight = parseInt(this.widget.wiki.getTiddlerText(HEIGHT_VALUE_TITLE,"400px"),10);
|
||||
fixedHeight = Math.max(fixedHeight,20);
|
||||
this.domNode.style.height = fixedHeight + "px";
|
||||
|
||||
@@ -217,10 +217,10 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
|
||||
EditTextWidget.prototype.refresh = function(changedTiddlers) {
|
||||
var changedAttributes = this.computeAttributes();
|
||||
// Completely rerender if any of our attributes have changed
|
||||
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes["default"] || changedAttributes["class"] || changedAttributes.placeholder || changedAttributes.size || changedAttributes.autoHeight || changedAttributes.minHeight || changedAttributes.focusPopup || changedAttributes.rows || changedAttributes.tabindex || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || changedAttributes.autocomplete || changedTiddlers[HEIGHT_MODE_TITLE] || changedTiddlers[ENABLE_TOOLBAR_TITLE] || changedTiddlers["$:/palette"] || changedAttributes.disabled || changedAttributes.fileDrop) {
|
||||
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes["class"] || changedAttributes.placeholder || changedAttributes.size || changedAttributes.autoHeight || changedAttributes.minHeight || changedAttributes.focusPopup || changedAttributes.rows || changedAttributes.tabindex || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || changedAttributes.autocomplete || changedTiddlers[HEIGHT_MODE_TITLE] || changedTiddlers[ENABLE_TOOLBAR_TITLE] || changedTiddlers["$:/palette"] || changedAttributes.disabled || changedAttributes.fileDrop) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
} else if(changedTiddlers[this.editRefreshTitle]) {
|
||||
} else if(changedAttributes["default"] || changedTiddlers[this.editRefreshTitle]) {
|
||||
this.engine.updateDomNodeText(this.getEditInfo().value);
|
||||
} else if(changedTiddlers[this.editTitle]) {
|
||||
var editInfo = this.getEditInfo();
|
||||
|
||||
+71
-45
@@ -146,14 +146,16 @@ exports.parseFilter = function(filterString) {
|
||||
match;
|
||||
var whitespaceRegExp = /(\s+)/mg,
|
||||
// Groups:
|
||||
// 1 - entire filter run prefix
|
||||
// 2 - filter run prefix itself
|
||||
// 3 - filter run prefix suffixes
|
||||
// 4 - opening square bracket following filter run prefix
|
||||
// 5 - double quoted string following filter run prefix
|
||||
// 6 - single quoted string following filter run prefix
|
||||
// 7 - anything except for whitespace and square brackets
|
||||
operandRegExp = /((?:\+|\-|~|(?:=>?)|\:(\w+)(?:\:([\w\:, ]*))?)?)(?:(\[)|(?:"([^"]*)")|(?:'([^']*)')|([^\s\[\]]+))/mg;
|
||||
// 1 - pragma
|
||||
// 2 - pragma suffix
|
||||
// 3 - entire filter run prefix
|
||||
// 4 - filter run prefix name
|
||||
// 5 - filter run prefix suffixes
|
||||
// 6 - opening square bracket following filter run prefix
|
||||
// 7 - double quoted string following filter run prefix
|
||||
// 8 - single quoted string following filter run prefix
|
||||
// 9 - anything except for whitespace and square brackets
|
||||
operandRegExp = /(?:::(\w+)(?:\:(\w+))?(?=\s|$)|((?:\+|\-|~|(?:=>?)|:(\w+)(?:\:([\w\:, ]*))?)?)(?:(\[)|(?:"([^"]*)")|(?:'([^']*)')|([^\s\[\]]+)))/mg;
|
||||
while(p < filterString.length) {
|
||||
// Skip any whitespace
|
||||
whitespaceRegExp.lastIndex = p;
|
||||
@@ -170,18 +172,23 @@ exports.parseFilter = function(filterString) {
|
||||
};
|
||||
match = operandRegExp.exec(filterString);
|
||||
if(match && match.index === p) {
|
||||
// If there is a filter run prefix
|
||||
if(match[1]) {
|
||||
operation.prefix = match[1];
|
||||
// If there is a filter pragma
|
||||
operation.pragma = match[1];
|
||||
operation.suffix = match[2];
|
||||
p = match.index + match[0].length;
|
||||
} else if(match[3]) {
|
||||
// If there is a filter run prefix
|
||||
operation.prefix = match[3];
|
||||
p = p + operation.prefix.length;
|
||||
// Name for named prefixes
|
||||
if(match[2]) {
|
||||
operation.namedPrefix = match[2];
|
||||
if(match[4]) {
|
||||
operation.namedPrefix = match[4];
|
||||
}
|
||||
// Suffixes for filter run prefix
|
||||
if(match[3]) {
|
||||
if(match[5]) {
|
||||
operation.suffixes = [];
|
||||
$tw.utils.each(match[3].split(":"),function(subsuffix) {
|
||||
$tw.utils.each(match[5].split(":"),function(subsuffix) {
|
||||
operation.suffixes.push([]);
|
||||
$tw.utils.each(subsuffix.split(","),function(entry) {
|
||||
entry = $tw.utils.trim(entry);
|
||||
@@ -193,7 +200,7 @@ exports.parseFilter = function(filterString) {
|
||||
}
|
||||
}
|
||||
// Opening square bracket
|
||||
if(match[4]) {
|
||||
if(match[6]) {
|
||||
p = parseFilterOperation(operation.operators,filterString,p);
|
||||
} else {
|
||||
p = match.index + match[0].length;
|
||||
@@ -203,9 +210,9 @@ exports.parseFilter = function(filterString) {
|
||||
p = parseFilterOperation(operation.operators,filterString,p);
|
||||
}
|
||||
// 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(
|
||||
{operator: "title", operands: [{text: match[5] || match[6] || match[7]}]}
|
||||
{operator: "title", operands: [{text: match[7] || match[8] || match[9]}]}
|
||||
);
|
||||
}
|
||||
results.push(operation);
|
||||
@@ -230,23 +237,25 @@ exports.getFilterRunPrefixes = function() {
|
||||
return this.filterRunPrefixes;
|
||||
};
|
||||
|
||||
exports.filterTiddlers = function(filterString,widget,source) {
|
||||
var fn = this.compileFilter(filterString);
|
||||
exports.filterTiddlers = function(filterString,widget,source,options) {
|
||||
var fn = this.compileFilter(filterString,options);
|
||||
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)
|
||||
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";
|
||||
var cacheKey = filterString + "|" + defaultFilterRunPrefix;
|
||||
if(!this.filterCache) {
|
||||
this.filterCache = Object.create(null);
|
||||
this.filterCacheCount = 0;
|
||||
}
|
||||
if(this.filterCache[filterString] !== undefined) {
|
||||
return this.filterCache[filterString];
|
||||
if(this.filterCache[cacheKey] !== undefined) {
|
||||
return this.filterCache[cacheKey];
|
||||
}
|
||||
var filterParseTree;
|
||||
try {
|
||||
@@ -325,7 +334,8 @@ exports.compileFilter = function(filterString) {
|
||||
regexp: operator.regexp
|
||||
},{
|
||||
wiki: self,
|
||||
widget: widget
|
||||
widget: widget,
|
||||
defaultFilterRunPrefix: defaultFilterRunPrefix
|
||||
});
|
||||
if($tw.utils.isArray(results)) {
|
||||
accumulator = self.makeTiddlerIterator(results);
|
||||
@@ -346,29 +356,45 @@ exports.compileFilter = function(filterString) {
|
||||
var filterRunPrefixes = self.getFilterRunPrefixes();
|
||||
// Wrap the operator functions in a wrapper function that depends on the prefix
|
||||
operationFunctions.push((function() {
|
||||
var options = {wiki: self, suffixes: operation.suffixes || []};
|
||||
switch(operation.prefix || "") {
|
||||
case "": // No prefix means that the operation is unioned into the result
|
||||
return filterRunPrefixes["or"](operationSubFunction, options);
|
||||
case "=": // The results of the operation are pushed into the result without deduplication
|
||||
return filterRunPrefixes["all"](operationSubFunction, options);
|
||||
case "-": // The results of this operation are removed from the main result
|
||||
return filterRunPrefixes["except"](operationSubFunction, options);
|
||||
case "+": // This operation is applied to the main results so far
|
||||
return filterRunPrefixes["and"](operationSubFunction, options);
|
||||
case "~": // This operation is unioned into the result only if the main result so far is empty
|
||||
return filterRunPrefixes["else"](operationSubFunction, options);
|
||||
case "=>": // This operation is applied to the main results so far, and the results are assigned to a variable
|
||||
return filterRunPrefixes["let"](operationSubFunction, options);
|
||||
default:
|
||||
if(operation.namedPrefix && filterRunPrefixes[operation.namedPrefix]) {
|
||||
return filterRunPrefixes[operation.namedPrefix](operationSubFunction, options);
|
||||
} else {
|
||||
if(operation.pragma) {
|
||||
switch(operation.pragma) {
|
||||
case "defaultprefix":
|
||||
defaultFilterRunPrefix = operation.suffix || "or";
|
||||
break;
|
||||
default:
|
||||
return function(results,source,widget) {
|
||||
results.clear();
|
||||
results.push($tw.language.getString("Error/FilterRunPrefix"));
|
||||
results.push($tw.language.getString("Error/FilterPragma"));
|
||||
};
|
||||
}
|
||||
}
|
||||
return function(results,source,widget) {
|
||||
// Dummy response
|
||||
};
|
||||
} else {
|
||||
var options = {wiki: self, suffixes: operation.suffixes || []};
|
||||
switch(operation.prefix || "") {
|
||||
case "": // Use the default filter run prefix if none is specified
|
||||
return filterRunPrefixes[defaultFilterRunPrefix](operationSubFunction, options);
|
||||
case "=": // The results of the operation are pushed into the result without deduplication
|
||||
return filterRunPrefixes["all"](operationSubFunction, options);
|
||||
case "-": // The results of this operation are removed from the main result
|
||||
return filterRunPrefixes["except"](operationSubFunction, options);
|
||||
case "+": // This operation is applied to the main results so far
|
||||
return filterRunPrefixes["and"](operationSubFunction, options);
|
||||
case "~": // This operation is unioned into the result only if the main result so far is empty
|
||||
return filterRunPrefixes["else"](operationSubFunction, options);
|
||||
case "=>": // This operation is applied to the main results so far, and the results are assigned to a variable
|
||||
return filterRunPrefixes["let"](operationSubFunction, options);
|
||||
default:
|
||||
if(operation.namedPrefix && filterRunPrefixes[operation.namedPrefix]) {
|
||||
return filterRunPrefixes[operation.namedPrefix](operationSubFunction, options);
|
||||
} else {
|
||||
return function(results,source,widget) {
|
||||
results.clear();
|
||||
results.push($tw.language.getString("Error/FilterRunPrefix"));
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
})());
|
||||
});
|
||||
@@ -407,7 +433,7 @@ exports.compileFilter = function(filterString) {
|
||||
this.filterCache = Object.create(null);
|
||||
this.filterCacheCount = 0;
|
||||
}
|
||||
this.filterCache[filterString] = fnMeasured;
|
||||
this.filterCache[cacheKey] = fnMeasured;
|
||||
this.filterCacheCount++;
|
||||
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,140 @@
|
||||
/*\
|
||||
title: $:/core/modules/filters/colour-ops.js
|
||||
type: application/javascript
|
||||
module-type: filteroperator
|
||||
|
||||
Filter operators for colour operations
|
||||
|
||||
\*/
|
||||
|
||||
"use strict";
|
||||
|
||||
var Color = require("$:/core/modules/utils/dom/color.js").Color,
|
||||
colourSpacesList = Object.keys(Color.spaces),
|
||||
hueAdjustersList = ["raw","increasing","decreasing","longer","shorter"];
|
||||
|
||||
exports["colour-lighten"] = makeSerialColourOperator(function (colour, operator, options) {
|
||||
return colour.lighten($tw.utils.parseNumber(operator.operand)).display().toString();
|
||||
});
|
||||
|
||||
exports["colour-darken"] = makeSerialColourOperator(function (colour, operator, options) {
|
||||
return colour.darken($tw.utils.parseNumber(operator.operand)).display().toString();
|
||||
});
|
||||
|
||||
exports["colour-get-oklch"] = makeSerialColourOperator(function (colour, operator, options) {
|
||||
var prop = ((operator.suffixes || [])[0] || ["l"])[0];
|
||||
if(["l","c","h"].indexOf(prop) !== -1) {
|
||||
colour = colour.oklch[prop];
|
||||
}
|
||||
return colour.toString();
|
||||
});
|
||||
|
||||
exports["colour-set-oklch"] = makeSerialColourOperator(function (colour, operator, options) {
|
||||
var prop = ((operator.suffixes || [])[0] || ["l"])[0];
|
||||
if(["l","c","h"].indexOf(prop) !== -1) {
|
||||
colour.oklch[prop] = $tw.utils.parseNumber(operator.operand);
|
||||
}
|
||||
return colour.display().toString();
|
||||
});
|
||||
|
||||
exports["colour-set-alpha"] = makeSerialColourOperator(function (colour, operator, options) {
|
||||
colour.alpha = $tw.utils.parseNumber(operator.operand);
|
||||
return colour.display().toString();
|
||||
});
|
||||
|
||||
exports["colour-contrast"] = makeParallelColourOperator(function (colours, operator, options) {
|
||||
var colourContrasts = [];
|
||||
$tw.utils.each(colours,function(colour,index) {
|
||||
if(!colour) {
|
||||
colour = $tw.utils.parseCSSColorObject("white");
|
||||
colours[index] = colour;
|
||||
}
|
||||
if(index > 0) {
|
||||
colourContrasts.push(colour.contrast(colours[index - 1],"DeltaPhi").toString());
|
||||
}
|
||||
});
|
||||
return colourContrasts;
|
||||
});
|
||||
|
||||
exports["colour-best-contrast"] = makeParallelColourOperator(function (colours, operator, options, originalColours) {
|
||||
var bestContrast = 0,
|
||||
bestColour = null;
|
||||
if(colours.length < 2) {
|
||||
return [];
|
||||
}
|
||||
var targetColour = colours[colours.length - 1];
|
||||
for(var t=0; t<colours.length; t++) {
|
||||
var colour = colours[t];
|
||||
if(colour) {
|
||||
var contrast = colour.contrast(targetColour,"DeltaPhi");
|
||||
if(contrast > bestContrast) {
|
||||
bestContrast = contrast;
|
||||
bestColour = originalColours[t];
|
||||
}
|
||||
}
|
||||
}
|
||||
if(bestColour) {
|
||||
return [bestColour];
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
});
|
||||
|
||||
exports["colour-interpolate"] = function(source,operator,options) {
|
||||
// Get the colour space suffix
|
||||
var space = ((((operator.suffixes || [])[0] || ["srgb"])[0]) || "").toLowerCase();
|
||||
if(colourSpacesList.indexOf(space) === -1) {
|
||||
space = "lch";
|
||||
}
|
||||
// Get the hue adjuster suffix
|
||||
var hueAdjuster = ((((operator.suffixes || [])[1] || ["shorter"])[0]) || "").toLowerCase();
|
||||
if(hueAdjustersList.indexOf(hueAdjuster) === -1) {
|
||||
hueAdjuster = "shorter";
|
||||
}
|
||||
// Get the colours
|
||||
if(operator.operands.length < 2) {
|
||||
return [];
|
||||
}
|
||||
var colourA = $tw.utils.parseCSSColorObject(operator.operands[0]),
|
||||
colourB = $tw.utils.parseCSSColorObject(operator.operands[1]);
|
||||
if(!colourA || !colourB) {
|
||||
return [];
|
||||
}
|
||||
var rangefn = colourA.range(colourB,{space: space, hue: hueAdjuster});
|
||||
// Cycle through the weights
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
var index = $tw.utils.parseNumber(title);
|
||||
var colour = rangefn(index);
|
||||
results.push(colour.display().toString());
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
function makeSerialColourOperator(fn) {
|
||||
return function (source, operator, options) {
|
||||
var results = [];
|
||||
source(function (tiddler, title) {
|
||||
var c = $tw.utils.parseCSSColorObject(title);
|
||||
if(c) {
|
||||
c = fn(c, operator, options);
|
||||
results.push(c);
|
||||
} else {
|
||||
results.push("");
|
||||
}
|
||||
});
|
||||
return results;
|
||||
};
|
||||
}
|
||||
|
||||
function makeParallelColourOperator(fn) {
|
||||
return function (source, operator, options) {
|
||||
var originalColours = [],
|
||||
colours = [];
|
||||
source(function (tiddler, title) {
|
||||
originalColours.push(title);
|
||||
colours.push($tw.utils.parseCSSColorObject(title));
|
||||
});
|
||||
return fn(colours, operator, options, originalColours);
|
||||
};
|
||||
}
|
||||
@@ -13,7 +13,9 @@ Filter operator returning those input titles that pass a subfilter
|
||||
Export our filter function
|
||||
*/
|
||||
exports.filter = function(source,operator,options) {
|
||||
var filterFn = options.wiki.compileFilter(operator.operand),
|
||||
var suffixes = operator.suffixes || [],
|
||||
defaultFilterRunPrefix = (suffixes[0] || [options.defaultFilterRunPrefix] || [])[0] || "or",
|
||||
filterFn = options.wiki.compileFilter(operator.operand,{defaultFilterRunPrefix}),
|
||||
results = [],
|
||||
target = operator.prefix !== "!";
|
||||
source(function(tiddler,title) {
|
||||
|
||||
@@ -14,31 +14,31 @@ Export our filter function
|
||||
*/
|
||||
exports.sort = function(source,operator,options) {
|
||||
var results = prepare_results(source);
|
||||
options.wiki.sortTiddlers(results,operator.operands[0] || "title",operator.prefix === "!",false,false,undefined,operator.operands[1]);
|
||||
options.wiki.sortTiddlers(results,operator.operand || "title",operator.prefix === "!",false,false);
|
||||
return results;
|
||||
};
|
||||
|
||||
exports.nsort = function(source,operator,options) {
|
||||
var results = prepare_results(source);
|
||||
options.wiki.sortTiddlers(results,operator.operands[0] || "title",operator.prefix === "!",false,true,undefined,operator.operands[1]);
|
||||
options.wiki.sortTiddlers(results,operator.operand || "title",operator.prefix === "!",false,true);
|
||||
return results;
|
||||
};
|
||||
|
||||
exports.sortan = function(source, operator, options) {
|
||||
var results = prepare_results(source);
|
||||
options.wiki.sortTiddlers(results, operator.operands[0] || "title", operator.prefix === "!",false,false,true,operator.operands[1]);
|
||||
options.wiki.sortTiddlers(results, operator.operand || "title", operator.prefix === "!",false,false,true);
|
||||
return results;
|
||||
};
|
||||
|
||||
exports.sortcs = function(source,operator,options) {
|
||||
var results = prepare_results(source);
|
||||
options.wiki.sortTiddlers(results,operator.operands[0] || "title",operator.prefix === "!",true,false,undefined,operator.operands[1]);
|
||||
options.wiki.sortTiddlers(results,operator.operand || "title",operator.prefix === "!",true,false);
|
||||
return results;
|
||||
};
|
||||
|
||||
exports.nsortcs = function(source,operator,options) {
|
||||
var results = prepare_results(source);
|
||||
options.wiki.sortTiddlers(results,operator.operands[0] || "title",operator.prefix === "!",true,true,undefined,operator.operands[1]);
|
||||
options.wiki.sortTiddlers(results,operator.operand || "title",operator.prefix === "!",true,true);
|
||||
return results;
|
||||
};
|
||||
|
||||
|
||||
@@ -13,7 +13,9 @@ Filter operator returning its operand evaluated as a filter
|
||||
Export our filter function
|
||||
*/
|
||||
exports.subfilter = function(source,operator,options) {
|
||||
var list = options.wiki.filterTiddlers(operator.operand,options.widget,source);
|
||||
var suffixes = operator.suffixes || [],
|
||||
defaultFilterRunPrefix = (suffixes[0] || [options.defaultFilterRunPrefix] || [])[0] || "or";
|
||||
var list = options.wiki.filterTiddlers(operator.operand,options.widget,source,{defaultFilterRunPrefix});
|
||||
if(operator.prefix === "!") {
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
|
||||
@@ -22,12 +22,11 @@ exports.tag = function(source,operator,options) {
|
||||
});
|
||||
} else {
|
||||
// Old semantics:
|
||||
var tiddlers;
|
||||
if(operator.prefix === "!") {
|
||||
// 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) {
|
||||
if(tiddlers.indexOf(title) === -1) {
|
||||
if(!excludeTagSet.has(title)) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
@@ -39,9 +38,9 @@ exports.tag = function(source,operator,options) {
|
||||
return indexedResults;
|
||||
}
|
||||
} else {
|
||||
tiddlers = options.wiki.getTiddlersWithTag(operator.operand);
|
||||
const includeTagSet = new Set(options.wiki.getTiddlersWithTag(operator.operand));
|
||||
source(function(tiddler,title) {
|
||||
if(tiddlers.indexOf(title) !== -1) {
|
||||
if(includeTagSet.has(title)) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -26,25 +26,26 @@ exports.params = [
|
||||
Run the macro
|
||||
*/
|
||||
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) {
|
||||
return colourA;
|
||||
}
|
||||
var rgbColourA = $tw.utils.parseCSSColor(colourA),
|
||||
rgbColourB = $tw.utils.parseCSSColor(colourB);
|
||||
var rgbColourA = $tw.utils.parseCSSColorObject(colourA),
|
||||
rgbColourB = $tw.utils.parseCSSColorObject(colourB);
|
||||
if(rgbColourA && !rgbColourB) {
|
||||
return rgbColourA;
|
||||
return colourA;
|
||||
}
|
||||
if(rgbColourB && !rgbColourA) {
|
||||
return rgbColourB;
|
||||
return colourB;
|
||||
}
|
||||
if(!rgbColourA && !rgbColourB) {
|
||||
// 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 brightnessTarget = rgbTarget[0] * 0.299 + rgbTarget[1] * 0.587 + rgbTarget[2] * 0.114,
|
||||
brightnessA = rgbColourA[0] * 0.299 + rgbColourA[1] * 0.587 + rgbColourA[2] * 0.114,
|
||||
brightnessB = rgbColourB[0] * 0.299 + rgbColourB[1] * 0.587 + rgbColourB[2] * 0.114;
|
||||
return Math.abs(brightnessTarget - brightnessA) > Math.abs(brightnessTarget - brightnessB) ? colourA : colourB;
|
||||
var aContrast = rgbColourA.contrast(rgbTarget,"DeltaPhi"),
|
||||
bContrast = rgbColourB.contrast(rgbTarget,"DeltaPhi");
|
||||
return aContrast > bContrast ? colourA : colourB;
|
||||
};
|
||||
|
||||
+151
-114
@@ -107,7 +107,7 @@ exports.parseStringLiteral = function(source,pos) {
|
||||
type: "string",
|
||||
start: pos
|
||||
};
|
||||
var reString = /(?:"""([\s\S]*?)"""|"([^"]*)")|(?:'([^']*)')|\[\[((?:[^\]]|\](?!\]))*)\]\]/g;
|
||||
var reString = /(?:"""([\s\S]*?)"""|"([^"]*)")|(?:'([^']*)')|\[\[((?:[^\]]|\](?!\]))*)\]\]/y;
|
||||
reString.lastIndex = pos;
|
||||
var match = reString.exec(source);
|
||||
if(match && match.index === pos) {
|
||||
@@ -221,7 +221,7 @@ exports.parseMacroInvocationAsTransclusion = function(source,pos) {
|
||||
orderedAttributes: []
|
||||
};
|
||||
// Define our regexps
|
||||
var reVarName = /([^\s>"'=:]+)/g;
|
||||
var reVarName = /([^\s>"'=:]+)/y;
|
||||
// Skip whitespace
|
||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||
// Look for a double opening angle bracket
|
||||
@@ -237,9 +237,11 @@ exports.parseMacroInvocationAsTransclusion = function(source,pos) {
|
||||
}
|
||||
$tw.utils.addAttributeToParseTreeNode(node,"$variable",token.match[1]);
|
||||
pos = token.end;
|
||||
// Check that the tag is terminated by a space or >>
|
||||
if(!$tw.utils.parseWhiteSpace(source,pos) && !(source.charAt(pos) === ">" && source.charAt(pos + 1) === ">") ) {
|
||||
return null;
|
||||
// Check that the tag is terminated by a space or >>, and that there is a closing >> somewhere ahead
|
||||
if(!(source.charAt(pos) === ">" && source.charAt(pos + 1) === ">") ) {
|
||||
if(source.indexOf(">>",pos) === -1) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// Process attributes
|
||||
pos = $tw.utils.parseMacroParametersAsAttributes(node,source,pos);
|
||||
@@ -267,7 +269,7 @@ exports.parseMVVReferenceAsTransclusion = function(source,pos) {
|
||||
orderedAttributes: []
|
||||
};
|
||||
// Define our regexps
|
||||
var reVarName = /([^\s>"'=:)]+)/g;
|
||||
var reVarName = /([^\s>"'=:)]+)/y;
|
||||
// Skip whitespace
|
||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||
// Look for a double opening parenthesis
|
||||
@@ -323,18 +325,24 @@ exports.parseMacroParameterAsAttribute = function(source,pos) {
|
||||
start: pos
|
||||
};
|
||||
// Define our regexps
|
||||
var reAttributeName = /([^\/\s>"'`=:]+)/g,
|
||||
reUnquotedAttribute = /((?:(?:>(?!>))|[^\s>"'])+)/g,
|
||||
reFilteredValue = /\{\{\{([\S\s]+?)\}\}\}/g,
|
||||
reIndirectValue = /\{\{([^\}]+)\}\}/g,
|
||||
reSubstitutedValue = /(?:```([\s\S]*?)```|`([^`]|[\S\s]*?)`)/g;
|
||||
var reAttributeName = /([^\/\s>"'`=:]+)/y,
|
||||
reStrictIdentifier = /^[A-Za-z0-9\-_]+$/,
|
||||
reUnquotedAttribute = /(?!<<)((?:(?:>(?!>))|[^\s>"'])+)/y,
|
||||
reFilteredValue = /\{\{\{([\S\s]+?)\}\}\}/y,
|
||||
reIndirectValue = /\{\{([^\}]+)\}\}/y,
|
||||
reSubstitutedValue = /(?:```([\s\S]*?)```|`([^`]|[\S\s]*?)`)/y;
|
||||
// Skip whitespace
|
||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||
// Get the attribute name and the separator token
|
||||
var nameToken = $tw.utils.parseTokenRegExp(source,pos,reAttributeName),
|
||||
namePos = nameToken && $tw.utils.skipWhiteSpace(source,nameToken.end),
|
||||
separatorToken = nameToken && $tw.utils.parseTokenRegExp(source,namePos,/=|:/g),
|
||||
separatorToken = nameToken && $tw.utils.parseTokenRegExp(source,namePos,/=|:/y),
|
||||
isNewStyleSeparator = false; // If there is no separator then we don't allow new style values
|
||||
// Colon separator requires a strict identifier name to avoid mis-parsing values like $:/foo
|
||||
if(nameToken && separatorToken && separatorToken.match[0] === ":" && !reStrictIdentifier.test(nameToken.match[1])) {
|
||||
nameToken = null;
|
||||
separatorToken = null;
|
||||
}
|
||||
// If we have a name and a separator then we have a named attribute
|
||||
if(nameToken && separatorToken) {
|
||||
node.name = nameToken.match[1];
|
||||
@@ -345,64 +353,78 @@ exports.parseMacroParameterAsAttribute = function(source,pos) {
|
||||
}
|
||||
// Skip whitespace
|
||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||
// Look for a string literal
|
||||
var stringLiteral = $tw.utils.parseStringLiteral(source,pos);
|
||||
if(stringLiteral) {
|
||||
pos = stringLiteral.end;
|
||||
node.type = "string";
|
||||
node.value = stringLiteral.value;
|
||||
// Mark the value as having been quoted in the source
|
||||
node.quoted = true;
|
||||
} else {
|
||||
// Look for a filtered value
|
||||
var filteredValue = $tw.utils.parseTokenRegExp(source,pos,reFilteredValue);
|
||||
if(filteredValue && isNewStyleSeparator) {
|
||||
pos = filteredValue.end;
|
||||
node.type = "filtered";
|
||||
node.filter = filteredValue.match[1];
|
||||
} else {
|
||||
|
||||
do {
|
||||
// Look for a string literal
|
||||
var stringLiteral = $tw.utils.parseStringLiteral(source,pos);
|
||||
if(stringLiteral) {
|
||||
pos = stringLiteral.end;
|
||||
node.type = "string";
|
||||
node.value = stringLiteral.value;
|
||||
// Mark the value as having been quoted in the source
|
||||
node.quoted = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if(isNewStyleSeparator) {
|
||||
// Look for a filtered value
|
||||
var filteredValue = $tw.utils.parseTokenRegExp(source,pos,reFilteredValue);
|
||||
if(filteredValue) {
|
||||
pos = filteredValue.end;
|
||||
node.type = "filtered";
|
||||
node.filter = filteredValue.match[1];
|
||||
break;
|
||||
}
|
||||
|
||||
// Look for an indirect value
|
||||
var indirectValue = $tw.utils.parseTokenRegExp(source,pos,reIndirectValue);
|
||||
if(indirectValue && isNewStyleSeparator) {
|
||||
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 && isNewStyleSeparator) {
|
||||
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 && isNewStyleSeparator) {
|
||||
pos = mvvReference.end;
|
||||
node.type = "macro";
|
||||
node.value = mvvReference;
|
||||
node.isMVV = true;
|
||||
} else {
|
||||
var substitutedValue = $tw.utils.parseTokenRegExp(source,pos,reSubstitutedValue);
|
||||
if(substitutedValue && isNewStyleSeparator) {
|
||||
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 {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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; // redundant, but leaving for consistency
|
||||
}
|
||||
|
||||
} while(false);
|
||||
|
||||
// Bail if we don't have a value
|
||||
if(!node.type) {
|
||||
return null;
|
||||
@@ -506,64 +528,79 @@ exports.parseAttribute = function(source,pos) {
|
||||
pos = token.end;
|
||||
// Skip whitespace
|
||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||
// Look for a string literal
|
||||
var stringLiteral = $tw.utils.parseStringLiteral(source,pos);
|
||||
if(stringLiteral) {
|
||||
pos = stringLiteral.end;
|
||||
node.type = "string";
|
||||
node.value = stringLiteral.value;
|
||||
} else {
|
||||
do {
|
||||
// Look for a string literal
|
||||
var stringLiteral = $tw.utils.parseStringLiteral(source,pos);
|
||||
if(stringLiteral) {
|
||||
pos = stringLiteral.end;
|
||||
node.type = "string";
|
||||
node.value = stringLiteral.value;
|
||||
break;
|
||||
}
|
||||
|
||||
// Look for a filtered value
|
||||
var filteredValue = $tw.utils.parseTokenRegExp(source,pos,reFilteredValue);
|
||||
if(filteredValue) {
|
||||
pos = filteredValue.end;
|
||||
node.type = "filtered";
|
||||
node.filter = filteredValue.match[1];
|
||||
} else {
|
||||
// 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 {
|
||||
node.type = "string";
|
||||
node.value = "true";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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];
|
||||
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 {
|
||||
// If there is no equals sign or colon, then this is an attribute with no value, defaulting to "true"
|
||||
node.type = "string";
|
||||
|
||||
@@ -31,13 +31,16 @@ exports.parse = function() {
|
||||
reEnd.lastIndex = this.parser.pos;
|
||||
var match = reEnd.exec(this.parser.source),
|
||||
text,
|
||||
start = this.parser.pos;
|
||||
start = this.parser.pos,
|
||||
textEnd;
|
||||
// Process the text
|
||||
if(match) {
|
||||
text = this.parser.source.substring(this.parser.pos,match.index);
|
||||
textEnd = match.index;
|
||||
this.parser.pos = match.index + match[0].length;
|
||||
} else {
|
||||
text = this.parser.source.substr(this.parser.pos);
|
||||
textEnd = this.parser.sourceLength;
|
||||
this.parser.pos = this.parser.sourceLength;
|
||||
}
|
||||
return [{
|
||||
@@ -47,7 +50,7 @@ exports.parse = function() {
|
||||
type: "text",
|
||||
text: text,
|
||||
start: start,
|
||||
end: this.parser.pos
|
||||
end: textEnd
|
||||
}]
|
||||
}];
|
||||
};
|
||||
|
||||
@@ -32,7 +32,8 @@ exports.parse = function() {
|
||||
this.parser.pos = this.matchRegExp.lastIndex;
|
||||
// Create the link unless it is suppressed
|
||||
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 {
|
||||
return [{
|
||||
type: "element",
|
||||
|
||||
@@ -34,7 +34,7 @@ exports.parse = function() {
|
||||
// Parse the filter terminated by a line break
|
||||
var reMatch = /(.*)(?:$|\r?\n)/mg;
|
||||
reMatch.lastIndex = this.parser.pos;
|
||||
var filterStart = this.parser.source;
|
||||
var filterStart = this.parser.pos;
|
||||
var match = reMatch.exec(this.parser.source);
|
||||
this.parser.pos = reMatch.lastIndex;
|
||||
// Parse tree nodes to return
|
||||
|
||||
@@ -27,9 +27,11 @@ Parse the most recent match
|
||||
*/
|
||||
exports.parse = function() {
|
||||
// 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
|
||||
this.parser.pos = this.matchRegExp.lastIndex;
|
||||
// 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}];
|
||||
};
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*\
|
||||
title: $:/core/modules/relinkers/tiddlers.js
|
||||
type: application/javascript
|
||||
module-type: relinker
|
||||
|
||||
Relinks the tags and list fields of tiddlers.
|
||||
|
||||
Calls a tw-relinking-tiddler hook for every altered tiddler.
|
||||
|
||||
\*/
|
||||
|
||||
exports.name = "tiddlers";
|
||||
|
||||
exports.relink = function(wiki,fromTitle,toTitle,options) {
|
||||
wiki.each(function(tiddler,title) {
|
||||
var type = tiddler.fields.type || "";
|
||||
// Don't touch plugins or JavaScript modules
|
||||
if(!tiddler.fields["plugin-type"] && type !== "application/javascript") {
|
||||
var tags = tiddler.fields.tags ? tiddler.fields.tags.slice(0) : undefined,
|
||||
list = tiddler.fields.list ? tiddler.fields.list.slice(0) : undefined,
|
||||
isModified = false,
|
||||
processList = function(listField) {
|
||||
if(listField && listField.indexOf(fromTitle) !== -1) {
|
||||
// Remove any existing instances of the toTitle
|
||||
var p = listField.indexOf(toTitle);
|
||||
while(p !== -1) {
|
||||
listField.splice(p,1);
|
||||
p = listField.indexOf(toTitle);
|
||||
}
|
||||
// Replace the fromTitle with toTitle
|
||||
$tw.utils.each(listField,function (title,index) {
|
||||
if(title === fromTitle) {
|
||||
listField[index] = toTitle;
|
||||
isModified = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
if(!options.dontRenameInTags) {
|
||||
// Rename tags
|
||||
processList(tags);
|
||||
}
|
||||
if(!options.dontRenameInLists) {
|
||||
// Rename lists
|
||||
processList(list);
|
||||
}
|
||||
if(isModified) {
|
||||
var newTiddler = new $tw.Tiddler(tiddler,{tags: tags, list: list},wiki.getModificationFields());
|
||||
newTiddler = $tw.hooks.invokeHook("th-relinking-tiddler",newTiddler,tiddler);
|
||||
wiki.addTiddler(newTiddler);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -40,6 +40,8 @@ exports.startup = function() {
|
||||
// The rest of the startup process here is not strictly to do with loading modules, but are needed before other startup
|
||||
// modules are executed. It is easier to put them here than to introduce a new startup module
|
||||
// --------------------------
|
||||
// Set up the performance framework
|
||||
$tw.perf = new $tw.Performance($tw.wiki.getTiddlerText(PERFORMANCE_INSTRUMENTATION_CONFIG_TITLE,"no") === "yes");
|
||||
// Create a root widget for attaching event handlers. By using it as the parentWidget for another widget tree, one can reuse the event handlers
|
||||
$tw.rootWidget = new widget.widget({
|
||||
type: "widget",
|
||||
|
||||
@@ -3,18 +3,43 @@ title: $:/core/modules/utils/deprecated.js
|
||||
type: application/javascript
|
||||
module-type: utils
|
||||
|
||||
Deprecated util functions
|
||||
Deprecated util functions. These preserve the pre-5.4.0 signatures and
|
||||
behaviour for backwards compatibility with plugins and external scripts.
|
||||
Prefer modern alternatives in new code (Array.prototype methods, classList,
|
||||
Math.sign, String.prototype.repeat, etc.).
|
||||
|
||||
\*/
|
||||
|
||||
exports.logTable = (data) => console.table(data);
|
||||
|
||||
exports.repeat = (str,count) => str.repeat(count);
|
||||
/*
|
||||
Repeats a string
|
||||
*/
|
||||
exports.repeat = function(str,count) {
|
||||
var result = "";
|
||||
for(var t=0;t<count;t++) {
|
||||
result += str;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
exports.startsWith = (str,search) => str.startsWith(search);
|
||||
/*
|
||||
Check if a string starts with another string
|
||||
*/
|
||||
exports.startsWith = function(str,search) {
|
||||
return str.substring(0, search.length) === search;
|
||||
};
|
||||
|
||||
exports.endsWith = (str,search) => str.endsWith(search);
|
||||
/*
|
||||
Check if a string ends with another string
|
||||
*/
|
||||
exports.endsWith = function(str,search) {
|
||||
return str.substring(str.length - search.length) === search;
|
||||
};
|
||||
|
||||
/*
|
||||
Trim whitespace from the start and end of a string
|
||||
*/
|
||||
exports.trim = function(str) {
|
||||
if(typeof str === "string") {
|
||||
return str.trim();
|
||||
@@ -29,30 +54,54 @@ exports.sign = Math.sign;
|
||||
|
||||
exports.strEndsWith = (str,ending,position) => str.endsWith(ending,position);
|
||||
|
||||
exports.stringifyNumber = (num) => num.toString();
|
||||
exports.stringifyNumber = function(num) {
|
||||
return num + "";
|
||||
};
|
||||
|
||||
// Returns the fully escaped CSS selector for a tag, e.g.
|
||||
// "$:/tags/Stylesheet" -> "tc-tagged-\%24\%3A\%2Ftags\%2FStylesheet"
|
||||
exports.tagToCssSelector = function(tagName) {
|
||||
return "tc-tagged-" + encodeURIComponent(tagName).replace(/[!"#$%&'()*+,\-./:;<=>?@[\\\]^`{\|}~,]/mg,function(c) {
|
||||
return "\\" + c;
|
||||
});
|
||||
};
|
||||
|
||||
exports.domContains = (a,b) => a.compareDocumentPosition(b) & 16;
|
||||
/*
|
||||
Determines whether element 'a' contains element 'b'.
|
||||
Returns false when a === b (matches the original John Resig semantics).
|
||||
*/
|
||||
exports.domContains = function(a,b) {
|
||||
return a !== b && a.contains(b);
|
||||
};
|
||||
|
||||
exports.domMatchesSelector = (node,selector) => node.matches(selector);
|
||||
|
||||
exports.hasClass = (el,className) => el.classList && el.classList.contains(className);
|
||||
exports.hasClass = function(el,className) {
|
||||
return !!(el && el.classList && el.classList.contains(className));
|
||||
};
|
||||
|
||||
// addClass/removeClass/toggleClass split on whitespace to preserve the
|
||||
// original setAttribute("class", ...) acceptance of "foo bar" as two
|
||||
// classes. Regressed in #9251.
|
||||
function splitClasses(className) {
|
||||
return (typeof className === "string" && className.match(/\S+/g)) || [];
|
||||
}
|
||||
|
||||
exports.addClass = function(el,className) {
|
||||
el.classList && className && el.classList.add(className);
|
||||
if(!el.classList) return;
|
||||
splitClasses(className).forEach(function(c) { el.classList.add(c); });
|
||||
};
|
||||
|
||||
exports.removeClass = function(el,className) {
|
||||
el.classList && className && el.classList.remove(className);
|
||||
if(!el.classList) return;
|
||||
splitClasses(className).forEach(function(c) { el.classList.remove(c); });
|
||||
};
|
||||
|
||||
exports.toggleClass = function(el,className,status) {
|
||||
el.classList && className && el.classList.toggle(className, status);
|
||||
if(!el.classList) return;
|
||||
splitClasses(className).forEach(function(c) { el.classList.toggle(c,status); });
|
||||
};
|
||||
|
||||
exports.getLocationPath = () => window.location.origin + window.location.pathname;
|
||||
exports.getLocationPath = function() {
|
||||
return window.location.toString().split("#")[0];
|
||||
};
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*\
|
||||
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 [rgb[0],rgb[1],rgb[2],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) {
|
||||
var c = exports.parseCSSColorObject(colourString);
|
||||
if(c) {
|
||||
var hex = c.toString({format: "hex"});
|
||||
if(hex.length === 4) {
|
||||
hex = "#" + hex[1] + hex[1] + hex[2] + hex[2] + hex[3] + hex[3];
|
||||
}
|
||||
return hex;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
@@ -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
|
||||
@@ -77,10 +77,23 @@ exports.resizeTextAreaToFit = function(domNode,minHeight) {
|
||||
// Measure the specified minimum height
|
||||
domNode.style.height = minHeight;
|
||||
var measuredHeight = domNode.offsetHeight || parseInt(minHeight,10);
|
||||
// Temporarily force rows=1 during auto-measurement so the intrinsic floor
|
||||
// is one row rather than the HTML default of two; restore afterwards
|
||||
var hadRowsAttr = domNode.hasAttribute("rows"),
|
||||
savedRows = hadRowsAttr ? domNode.getAttribute("rows") : null;
|
||||
if(!hadRowsAttr) {
|
||||
domNode.setAttribute("rows","1");
|
||||
}
|
||||
// Set its height to auto so that it snaps to the correct height
|
||||
domNode.style.height = "auto";
|
||||
// Calculate the revised height
|
||||
var newHeight = Math.max(domNode.scrollHeight + domNode.offsetHeight - domNode.clientHeight,measuredHeight);
|
||||
// Restore the original rows attribute state
|
||||
if(!hadRowsAttr) {
|
||||
domNode.removeAttribute("rows");
|
||||
} else {
|
||||
domNode.setAttribute("rows",savedRows);
|
||||
}
|
||||
// Only try to change the height if it has changed
|
||||
if(newHeight !== domNode.offsetHeight) {
|
||||
domNode.style.height = newHeight + "px";
|
||||
|
||||
@@ -82,6 +82,11 @@ var TW_Style = function(el) {
|
||||
// Return a Proxy to handle direct access to individual style properties
|
||||
return new Proxy(styleObject, {
|
||||
get: function(target, property) {
|
||||
// Real CSSStyleDeclaration returns undefined for non-string keys.
|
||||
// Guards against crashes when consumers probe Symbol.toPrimitive etc.
|
||||
if(typeof property !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
// If the property exists on styleObject, return it (get, set, setProperty methods)
|
||||
if(property in target) {
|
||||
return target[property];
|
||||
@@ -90,6 +95,10 @@ var TW_Style = function(el) {
|
||||
return el._style[$tw.utils.convertStyleNameToPropertyName(property)] || "";
|
||||
},
|
||||
set: function(target, property, value) {
|
||||
// Mirror the get trap: ignore non-string keys instead of crashing.
|
||||
if(typeof property !== "string") {
|
||||
return true;
|
||||
}
|
||||
// Set the property in _style
|
||||
el._style[$tw.utils.convertStyleNameToPropertyName(property)] = value;
|
||||
return true;
|
||||
|
||||
@@ -243,8 +243,28 @@ exports.slowInSlowOut = function(t) {
|
||||
};
|
||||
|
||||
exports.copyObjectPropertiesSafe = function(object) {
|
||||
const seen = new Set(),
|
||||
isDOMElement = (value) => value instanceof Node || value instanceof Window;
|
||||
const seen = new Set();
|
||||
|
||||
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) {
|
||||
// skip circular references
|
||||
@@ -255,10 +275,6 @@ exports.copyObjectPropertiesSafe = function(object) {
|
||||
if(typeof obj !== "object" || obj === null) {
|
||||
return obj;
|
||||
}
|
||||
// skip DOM elements
|
||||
if(isDOMElement(obj)) {
|
||||
return undefined;
|
||||
}
|
||||
// copy arrays, preserving positions
|
||||
if(Array.isArray(obj)) {
|
||||
return obj.map((item) => {
|
||||
@@ -266,7 +282,11 @@ exports.copyObjectPropertiesSafe = function(object) {
|
||||
return value === undefined ? null : value;
|
||||
});
|
||||
}
|
||||
|
||||
// skip DOM elements
|
||||
if(isDOMElement(obj)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
seen.add(obj);
|
||||
const copy = {};
|
||||
let key,
|
||||
|
||||
@@ -61,7 +61,7 @@ LogWidget.prototype.log = function() {
|
||||
$tw.utils.each(this.parseTreeNode.attributes,function(attribute,name) {
|
||||
if(name.substring(0,2) !== "$$") {
|
||||
var resultList = self.computeAttribute(attribute,{asList: true});
|
||||
if(resultList.length <= 1) {
|
||||
if(resultList && resultList.length <= 1) {
|
||||
data[name] = resultList[0] || "";
|
||||
} else {
|
||||
data[name] = resultList;
|
||||
@@ -75,7 +75,7 @@ LogWidget.prototype.log = function() {
|
||||
allVars[v] = variable.value;
|
||||
} else {
|
||||
var variableInfo = this.getVariableInfo(v);
|
||||
allVars[v] = variableInfo.resultList.length > 1 ? variableInfo.resultList : variableInfo.text;
|
||||
allVars[v] = variableInfo && variableInfo.resultList && variableInfo.resultList.length > 1 ? variableInfo.resultList : variableInfo.text;
|
||||
}
|
||||
}
|
||||
if(this.filter) {
|
||||
|
||||
@@ -62,8 +62,8 @@ SendMessageWidget.prototype.invokeAction = function(triggeringWidget,event) {
|
||||
var paramObject = Object.create(null);
|
||||
// Add names/values pairs if present
|
||||
if(this.actionNames && this.actionValues) {
|
||||
var names = this.wiki.filterTiddlers(this.actionNames,this),
|
||||
values = this.wiki.filterTiddlers(this.actionValues,this);
|
||||
var names = this.wiki.filterTiddlers(this.actionNames,this,{defaultFilterRunPrefix: "all"}),
|
||||
values = this.wiki.filterTiddlers(this.actionValues,this,{defaultFilterRunPrefix: "all"});
|
||||
$tw.utils.each(names,function(name,index) {
|
||||
paramObject[name] = values[index] || "";
|
||||
});
|
||||
|
||||
@@ -56,10 +56,10 @@ Invoke the action associated with this widget
|
||||
*/
|
||||
SetMultipleFieldsWidget.prototype.invokeAction = function(triggeringWidget,event) {
|
||||
var tiddler = this.wiki.getTiddler(this.actionTiddler),
|
||||
names, values = this.wiki.filterTiddlers(this.actionValues,this);
|
||||
names, values = this.wiki.filterTiddlers(this.actionValues,this,{defaultFilterRunPrefix: "all"});
|
||||
if(this.actionFields) {
|
||||
var additions = {};
|
||||
names = this.wiki.filterTiddlers(this.actionFields,this);
|
||||
names = this.wiki.filterTiddlers(this.actionFields,this,{defaultFilterRunPrefix: "all"});
|
||||
$tw.utils.each(names,function(fieldname,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));
|
||||
} else if(this.actionIndexes) {
|
||||
var data = this.wiki.getTiddlerData(this.actionTiddler,Object.create(null));
|
||||
names = this.wiki.filterTiddlers(this.actionIndexes,this);
|
||||
names = this.wiki.filterTiddlers(this.actionIndexes,this,{defaultFilterRunPrefix: "all"});
|
||||
$tw.utils.each(names,function(name,index) {
|
||||
data[name] = values[index] || "";
|
||||
});
|
||||
|
||||
@@ -72,8 +72,8 @@ GenesisWidget.prototype.execute = function() {
|
||||
this.attributeNames = [];
|
||||
this.attributeValues = [];
|
||||
if(this.genesisNames && this.genesisValues) {
|
||||
this.attributeNames = this.wiki.filterTiddlers(self.genesisNames,this);
|
||||
this.attributeValues = this.wiki.filterTiddlers(self.genesisValues,this);
|
||||
this.attributeNames = this.wiki.filterTiddlers(self.genesisNames,this,{defaultFilterRunPrefix: "all"});
|
||||
this.attributeValues = this.wiki.filterTiddlers(self.genesisValues,this,{defaultFilterRunPrefix: "all"});
|
||||
$tw.utils.each(this.attributeNames,function(varname,index) {
|
||||
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],varname,self.attributeValues[index] || "");
|
||||
});
|
||||
@@ -103,8 +103,8 @@ GenesisWidget.prototype.refresh = function(changedTiddlers) {
|
||||
var changedAttributes = this.computeAttributes(),
|
||||
filterNames = this.getAttribute("$names",""),
|
||||
filterValues = this.getAttribute("$values",""),
|
||||
attributeNames = this.wiki.filterTiddlers(filterNames,this),
|
||||
attributeValues = this.wiki.filterTiddlers(filterValues,this);
|
||||
attributeNames = this.wiki.filterTiddlers(filterNames,this,{defaultFilterRunPrefix: "all"}),
|
||||
attributeValues = this.wiki.filterTiddlers(filterValues,this,{defaultFilterRunPrefix: "all"});
|
||||
if($tw.utils.count(changedAttributes) > 0 || !$tw.utils.isArrayEqual(this.attributeNames,attributeNames) || !$tw.utils.isArrayEqual(this.attributeValues,attributeValues)) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
|
||||
@@ -125,13 +125,12 @@ SelectWidget.prototype.setSelectValue = function() {
|
||||
values = Array.isArray(value) ? value : $tw.utils.parseStringArray(value);
|
||||
for(var i=0; i < select.children.length; i++){
|
||||
child=select.children[i];
|
||||
if(child.children.length === 0){
|
||||
child.selected = values.indexOf(child.value) !== -1;
|
||||
} else {
|
||||
// grouped options
|
||||
if(child.tagName && child.tagName.toUpperCase() === "OPTGROUP"){
|
||||
for(var y=0; y < child.children.length; y++){
|
||||
child.children[y].selected = values.indexOf(child.children[y].value) !== -1;
|
||||
}
|
||||
} else {
|
||||
child.selected = values.indexOf(child.value) !== -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -49,8 +49,8 @@ SetMultipleVariablesWidget.prototype.setVariables = function() {
|
||||
this.variableNames = [];
|
||||
this.variableValues = [];
|
||||
if(filterNames && filterValues) {
|
||||
this.variableNames = this.wiki.filterTiddlers(filterNames,this);
|
||||
this.variableValues = this.wiki.filterTiddlers(filterValues,this);
|
||||
this.variableNames = this.wiki.filterTiddlers(filterNames,this,{defaultFilterRunPrefix: "all"});
|
||||
this.variableValues = this.wiki.filterTiddlers(filterValues,this,{defaultFilterRunPrefix: "all"});
|
||||
$tw.utils.each(this.variableNames,function(varname,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) {
|
||||
var filterNames = this.getAttribute("$names",""),
|
||||
filterValues = this.getAttribute("$values",""),
|
||||
variableNames = this.wiki.filterTiddlers(filterNames,this),
|
||||
variableValues = this.wiki.filterTiddlers(filterValues,this);
|
||||
variableNames = this.wiki.filterTiddlers(filterNames,this,{defaultFilterRunPrefix: "all"}),
|
||||
variableValues = this.wiki.filterTiddlers(filterValues,this,{defaultFilterRunPrefix: "all"});
|
||||
if(!$tw.utils.isArrayEqual(this.variableNames,variableNames) || !$tw.utils.isArrayEqual(this.variableValues,variableValues)) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
|
||||
@@ -189,7 +189,7 @@ Widget.prototype.getVariableInfo = function(name,options) {
|
||||
}
|
||||
return {
|
||||
text: text,
|
||||
resultList: [text]
|
||||
resultList: text === undefined ? text : [text]
|
||||
};
|
||||
};
|
||||
|
||||
@@ -338,7 +338,7 @@ Widget.prototype.makeFakeWidgetWithVariables = function(vars = {}) {
|
||||
const value = vars[name];
|
||||
return Array.isArray(value)
|
||||
? { text: value[0], resultList: value }
|
||||
: { text: value, resultList: [value] };
|
||||
: { text: value, resultList: value === undefined ? value : [value] };
|
||||
}
|
||||
opts = opts || {};
|
||||
opts.variables = Object.assign({}, vars, opts.variables || {});
|
||||
|
||||
@@ -9,6 +9,7 @@ Bulk tiddler operations such as rename.
|
||||
|
||||
"use strict";
|
||||
|
||||
var relinkers = $tw.modules.getModulesByTypeAsHashmap("relinker");
|
||||
/*
|
||||
Rename a tiddler, and relink any tags or lists that reference it.
|
||||
*/
|
||||
@@ -32,50 +33,13 @@ function renameTiddler(fromTitle,toTitle,options) {
|
||||
Relink any tags or lists that reference a given tiddler
|
||||
*/
|
||||
function relinkTiddler(fromTitle,toTitle,options) {
|
||||
var self = this;
|
||||
fromTitle = (fromTitle || "").trim();
|
||||
toTitle = (toTitle || "").trim();
|
||||
options = options || {};
|
||||
if(fromTitle && toTitle && fromTitle !== toTitle) {
|
||||
this.each(function(tiddler,title) {
|
||||
var type = tiddler.fields.type || "";
|
||||
// Don't touch plugins or JavaScript modules
|
||||
if(!tiddler.fields["plugin-type"] && type !== "application/javascript") {
|
||||
var tags = tiddler.fields.tags ? tiddler.fields.tags.slice(0) : undefined,
|
||||
list = tiddler.fields.list ? tiddler.fields.list.slice(0) : undefined,
|
||||
isModified = false,
|
||||
processList = function(listField) {
|
||||
if(listField && listField.indexOf(fromTitle) !== -1) {
|
||||
// Remove any existing instances of the toTitle
|
||||
var p = listField.indexOf(toTitle);
|
||||
while(p !== -1) {
|
||||
listField.splice(p,1);
|
||||
p = listField.indexOf(toTitle);
|
||||
}
|
||||
// Replace the fromTitle with toTitle
|
||||
$tw.utils.each(listField,function (title,index) {
|
||||
if(title === fromTitle) {
|
||||
listField[index] = toTitle;
|
||||
isModified = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
if(!options.dontRenameInTags) {
|
||||
// Rename tags
|
||||
processList(tags);
|
||||
}
|
||||
if(!options.dontRenameInLists) {
|
||||
// Rename lists
|
||||
processList(list);
|
||||
}
|
||||
if(isModified) {
|
||||
var newTiddler = new $tw.Tiddler(tiddler,{tags: tags, list: list},self.getModificationFields());
|
||||
newTiddler = $tw.hooks.invokeHook("th-relinking-tiddler",newTiddler,tiddler);
|
||||
self.addTiddler(newTiddler);
|
||||
}
|
||||
}
|
||||
});
|
||||
for(var name in relinkers) {
|
||||
relinkers[name].relink(this,fromTitle,toTitle,options);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+37
-10
@@ -369,16 +369,31 @@ Sort an array of tiddler titles by a specified field
|
||||
isDescending: true if the sort should be descending
|
||||
isCaseSensitive: true if the sort should consider upper and lower case letters to be different
|
||||
*/
|
||||
exports.sortTiddlers = function(titles,sortField,isDescending,isCaseSensitive,isNumeric,isAlphaNumeric,locale) {
|
||||
exports.sortTiddlers = function(titles,sortField,isDescending,isCaseSensitive,isNumeric,isAlphaNumeric) {
|
||||
var self = this;
|
||||
if(sortField === "title") {
|
||||
if(!isNumeric && !isAlphaNumeric) {
|
||||
const sorter = new Intl.Collator(locale, { sensitivity: isCaseSensitive ? "variant" : "accent" });
|
||||
if(isDescending) {
|
||||
titles.sort((a,b) => sorter.compare(b, a));
|
||||
if(isCaseSensitive) {
|
||||
if(isDescending) {
|
||||
titles.sort(function(a,b) {
|
||||
return b.localeCompare(a);
|
||||
});
|
||||
} else {
|
||||
titles.sort(function(a,b) {
|
||||
return a.localeCompare(b);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
titles.sort((a,b) => sorter.compare(a, b));
|
||||
}
|
||||
if(isDescending) {
|
||||
titles.sort(function(a,b) {
|
||||
return b.toLowerCase().localeCompare(a.toLowerCase());
|
||||
});
|
||||
} else {
|
||||
titles.sort(function(a,b) {
|
||||
return a.toLowerCase().localeCompare(b.toLowerCase());
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
titles.sort(function(a,b) {
|
||||
var x,y;
|
||||
@@ -399,8 +414,14 @@ exports.sortTiddlers = function(titles,sortField,isDescending,isCaseSensitive,is
|
||||
}
|
||||
}
|
||||
}
|
||||
const sorter = new Intl.Collator(locale, { numeric: isAlphaNumeric, sensitivity: isAlphaNumeric ? "base" : isCaseSensitive ? "variant" : "accent" });
|
||||
return isDescending ? sorter.compare(b, a) : sorter.compare(a, b);
|
||||
if(isAlphaNumeric) {
|
||||
return isDescending ? b.localeCompare(a,undefined,{numeric: true,sensitivity: "base"}) : a.localeCompare(b,undefined,{numeric: true,sensitivity: "base"});
|
||||
}
|
||||
if(!isCaseSensitive) {
|
||||
a = a.toLowerCase();
|
||||
b = b.toLowerCase();
|
||||
}
|
||||
return isDescending ? b.localeCompare(a) : a.localeCompare(b);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
@@ -442,8 +463,14 @@ exports.sortTiddlers = function(titles,sortField,isDescending,isCaseSensitive,is
|
||||
}
|
||||
a = String(a);
|
||||
b = String(b);
|
||||
const sorter = new Intl.Collator(locale, { numeric: isAlphaNumeric, sensitivity: isAlphaNumeric ? "base" : isCaseSensitive ? "variant" : "accent" });
|
||||
return isDescending ? sorter.compare(b, a) : sorter.compare(a, b);
|
||||
if(isAlphaNumeric) {
|
||||
return isDescending ? b.localeCompare(a,undefined,{numeric: true,sensitivity: "base"}) : a.localeCompare(b,undefined,{numeric: true,sensitivity: "base"});
|
||||
}
|
||||
if(!isCaseSensitive) {
|
||||
a = a.toLowerCase();
|
||||
b = b.toLowerCase();
|
||||
}
|
||||
return isDescending ? b.localeCompare(a) : a.localeCompare(b);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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]]
|
||||
settings: $:/palettes/AutoToggle/Settings
|
||||
palette-import@light: $:/palettes/TwentyTwenties
|
||||
palette-import@dark: $:/palettes/TwentyTwentiesDark
|
||||
category: 2026
|
||||
@@ -0,0 +1,19 @@
|
||||
title: $:/palettes/AutoToggle/Settings
|
||||
|
||||
\procedure set-imported-palette(field)
|
||||
<$select field=<<field>>>
|
||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Palette]sort[name]] -[<currentTiddler>]">
|
||||
<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.
|
||||
|
||||
<$tiddler tiddler={{$:/palette}}>
|
||||
|
||||
Light palette: <<set-imported-palette field:"palette-import@light">>
|
||||
|
||||
Dark palette: <<set-imported-palette field:"palette-import@dark">>
|
||||
|
||||
</$tiddler>
|
||||
@@ -0,0 +1,226 @@
|
||||
title: $:/palettes/TwentyTwenties
|
||||
name: TwentyTwenties
|
||||
description: Modern and flexible
|
||||
tags: $:/tags/Palette
|
||||
type: application/x-tiddler-dictionary
|
||||
color-scheme: light
|
||||
settings: $:/palettes/TwentyTwenties/Settings
|
||||
palette-import: $:/palettes/Vanilla
|
||||
category: 2026
|
||||
|
||||
# Background and foreground colours, which are interpolated as required
|
||||
base-paper: #FFFCF0
|
||||
base-background: #edcec1
|
||||
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:DeltaPhi[]]
|
||||
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:DeltaPhi[]]
|
||||
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,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)
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
title: $:/palettes/TwentyTwenties/Settings
|
||||
|
||||
\procedure entry(name,description)
|
||||
<$text text=<<description>>/>: <$edit-text tiddler={{$:/palette}} index=<<name>> type="color" tag="input" default={{{ [function[colour],<name>] }}}/>
|
||||
\end entry
|
||||
|
||||
<<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">>
|
||||
@@ -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]]
|
||||
@@ -6,5 +6,5 @@ caption: {{$:/language/ControlPanel/Appearance/Caption}}
|
||||
{{$:/language/ControlPanel/Appearance/Hint}}
|
||||
|
||||
<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>
|
||||
|
||||
@@ -2,20 +2,4 @@ title: $:/core/ui/ControlPanel/Palette
|
||||
tags: $:/tags/ControlPanel/Appearance
|
||||
caption: {{$:/language/ControlPanel/Palette/Caption}}
|
||||
|
||||
\define lingo-base() $:/language/ControlPanel/Palette/
|
||||
|
||||
{{$:/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>
|
||||
|
||||
{{$:/PaletteManager}}
|
||||
@@ -1,5 +1,7 @@
|
||||
title: $:/core/ui/EditTemplate/body/toolbar/button
|
||||
|
||||
\whitespace trim
|
||||
|
||||
\define toolbar-button-icon()
|
||||
<$list
|
||||
|
||||
|
||||
@@ -17,11 +17,13 @@ tags: $:/tags/EditTemplate
|
||||
<$let backgroundColor=<<colour>> >
|
||||
<span class="tc-tag-label tc-tag-list-item tc-small-gap-right"
|
||||
data-tag-title=<<currentTiddler>>
|
||||
style=`color:$(foregroundColor)$; background-color:$(backgroundColor)$; --tp-remove-tag-button-color:$(foregroundColor)$`
|
||||
style=`color:$(foregroundColor)$; fill:$(foregroundColor)$; background-color:$(backgroundColor)$;`
|
||||
>
|
||||
<$transclude tiddler=<<icon>>/>
|
||||
<$view field="title" format="text"/>
|
||||
<$button class="tc-btn-invisible tc-remove-tag-button">
|
||||
<$button class="tc-btn-invisible tc-remove-tag-button"
|
||||
style.fill=<<foregroundColor>>
|
||||
>
|
||||
<$action-listops $tiddler=<<saveTiddler>> $field=<<tagField>> $subfilter="-[{!!title}]"/>
|
||||
{{$:/core/images/close-button}}
|
||||
</$button>
|
||||
@@ -46,7 +48,6 @@ tags: $:/tags/EditTemplate
|
||||
<$list filter="[<currentTiddler>get<tagField>enlist-input[]sort[title]]" storyview="pop">
|
||||
<$macrocall $name="tag-body"
|
||||
colour={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}
|
||||
palette={{$:/palette}}
|
||||
icon={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]!is[draft]get[text]] }}}
|
||||
tagField=<<tagField>>
|
||||
/>
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
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"/>
|
||||
</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>>
|
||||
+36
-87
@@ -1,94 +1,43 @@
|
||||
title: $:/PaletteManager
|
||||
|
||||
\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 lingo-base() $:/language/ControlPanel/Palette/
|
||||
|
||||
\define resolve-colour(macrocall)
|
||||
\import $:/core/macros/utils
|
||||
\whitespace trim
|
||||
<$wikify name="name" text="""$macrocall$""">
|
||||
<<name>>
|
||||
</$wikify>
|
||||
\end
|
||||
<!-- Used by the language string CustomSettings/Prompt -->
|
||||
\procedure palette-link()
|
||||
<$tiddler tiddler={{$:/palette}}>
|
||||
<$link to={{!!title}}>
|
||||
<$view field="name" format="text">
|
||||
<$view field="title" format="text"/>
|
||||
</$view>
|
||||
</$link>
|
||||
</$tiddler>
|
||||
\end palette-link
|
||||
|
||||
<$transclude $tiddler="$:/snippets/paletteswitcher" thumbnails="yes"/>
|
||||
|
||||
{{$:/snippets/palettetests}}
|
||||
|
||||
<$let
|
||||
paletteSettings={{{ [[$:/temp/palette-consolidated]get[settings]] }}}
|
||||
>
|
||||
<%if [<paletteSettings>!match[]] %>
|
||||
<div>
|
||||
<<lingo CustomSettings/Prompt>>
|
||||
<$transclude $tiddler=<<paletteSettings>> $mode="block"/>
|
||||
</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 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 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"/>
|
||||
@@ -7,7 +7,6 @@ title: $:/core/ui/TagTemplate
|
||||
tag=<<currentTiddler>>
|
||||
icon={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]!is[draft]get[text]] }}}
|
||||
colour={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}
|
||||
palette={{$:/palette}}
|
||||
element-tag="$button"
|
||||
element-attributes="""popup=<<qualify "$:/state/popup/tag">> dragFilter="[subfilter{$:/core/config/TagPillDragFilter}]" tag='span'"""
|
||||
/>
|
||||
|
||||
@@ -2,7 +2,7 @@ title: $:/core/ui/ViewTemplate/title
|
||||
tags: $:/tags/ViewTemplate
|
||||
|
||||
\whitespace trim
|
||||
\define title-styles() color:$(foregroundColor)$;
|
||||
\define title-styles() fill:$(foregroundColor)$;
|
||||
|
||||
<div class="tc-tiddler-title tc-clearfix">
|
||||
<div class="tc-titlebar">
|
||||
|
||||
@@ -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[]]
|
||||
|
||||
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
||||
<<actions-recompile-current-palette>>
|
||||
@@ -1,6 +1,6 @@
|
||||
title: $:/config/OfficialPluginLibrary
|
||||
tags: $:/tags/PluginLibrary
|
||||
url: https://tiddlywiki.com/library/v5.4.0/index.html
|
||||
url: https://tiddlywiki.com/library/v5.5.0/index.html
|
||||
caption: {{$:/language/OfficialPluginLibrary}}
|
||||
|
||||
{{$:/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]]
|
||||
plugin: [has[plugin-type]then[$:/core/ui/ViewTemplate/body/plugin]]
|
||||
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]]
|
||||
|
||||
@@ -1,52 +1,12 @@
|
||||
title: $:/snippets/currpalettepreview
|
||||
|
||||
\define resolve-colour(macrocall)
|
||||
\import $:/core/macros/utils
|
||||
\whitespace trim
|
||||
<$wikify name="name" text="""$macrocall$""">
|
||||
<<name>>
|
||||
</$wikify>
|
||||
\end
|
||||
\define swatchStyle()
|
||||
background-color: $(swatchColour)$;
|
||||
\end
|
||||
\define swatch-inner()
|
||||
\whitespace trim
|
||||
<$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>
|
||||
|
||||
\import [all[shadows+tiddlers]tag[$:/tags/Preview/Helpers]!is[draft]sort[title]]
|
||||
|
||||
<!-- currentTiddler is the palette to use -->
|
||||
<$palette.preview paletteTitle=<<currentTiddler>>>
|
||||
<div class="tc-palette-preview-thumbnail" style.background-color=<<colour page-background>>>
|
||||
<<palette-preview-component-list tag:"$:/tags/Preview/Page">>
|
||||
</div>
|
||||
</$palette.preview>
|
||||
|
||||
+150
-10
@@ -1,17 +1,157 @@
|
||||
title: $:/core/macros/CSS
|
||||
tags: $:/tags/Macro
|
||||
|
||||
<!-- Needs to stay that way for backwards compatibility. See GH issue: #8326 -->
|
||||
\define colour(name)
|
||||
\whitespace trim
|
||||
<$transclude tiddler={{$:/palette}} index="$name$">
|
||||
<$transclude tiddler="$:/palettes/Vanilla" index="$name$">
|
||||
<$transclude tiddler="$:/config/DefaultColourMappings/$name$"/>
|
||||
</$transclude>
|
||||
</$transclude>
|
||||
\end
|
||||
\procedure actions-compile-palette-filtered(consolidatedPalette,outputPalette)
|
||||
<!-- Note the join, needed to cope with palette entries containing spaces -->
|
||||
\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[ ]]
|
||||
\function colour(name) [tf.colour<name>]
|
||||
\function color(name) [tf.colour<name>]
|
||||
<!-- Make the colour function use the input palette -->
|
||||
<$list filter="[<consolidatedPalette>indexes[]sort[]]" variable="colour-name">
|
||||
<$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 suffixed palette entries with the suffix stripped -->
|
||||
<%if [<scheme>!is[blank]] %>
|
||||
<$let
|
||||
prefixed-scheme={{{ [<scheme>addprefix[@]] }}}
|
||||
>
|
||||
<$action-setmultiplefields $tiddler=<<outputPalette>> $indexes="[<inputPalette>indexes[]suffix<prefixed-scheme>removesuffix<prefixed-scheme>sort[]]" $values="[<inputPalette>indexes[]suffix<prefixed-scheme>sort[]] :map[<inputPalette>getindex<currentTiddler>]"/>
|
||||
</$let>
|
||||
<%endif%
|
||||
<!-- 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 fields from the palette -->
|
||||
<$action-setmultiplefields $tiddler=<<outputPalette>> $fields="[<inputPalette>fields[]sort[]] -title -tags -text" $values="[<inputPalette>fields[]sort[]] -title -tags -text :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[[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>>/>
|
||||
</$let>
|
||||
</$let>
|
||||
\end actions-compile-palette
|
||||
|
||||
\procedure actions-recompile-current-palette()
|
||||
\procedure tv-action-refresh-policy() always
|
||||
<$transclude $variable="actions-compile-palette" inputPalette={{$:/palette}} outputPalette="$:/temp/palette-colours"/>
|
||||
\end actions-recompile-current-palette
|
||||
|
||||
\procedure actions-switch-colour-palette(paletteTitle)
|
||||
\procedure tv-action-refresh-policy() always
|
||||
<$action-deletetiddler $tiddler="$:/temp/palette-colours"/>
|
||||
<<actions-recompile-current-palette>>
|
||||
\end actions-switch-colour-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
|
||||
\function colour-inner-get-imported-palette(name,paletteTitle)
|
||||
[[palette-import@]addsuffix<scheme>] :map[<paletteTitle>get<currentTiddler>has[title]] +[!match[]] :else[<paletteTitle>get[palette-import]has[title]] :map[function[colour-inner-get-palette-entry],<name>,<currentTiddler>] +[!match[]]
|
||||
\end colour-inner-get-imported-palette
|
||||
|
||||
\function colour-inner-get-palette-entry(name,paletteTitle)
|
||||
[<name>addprefix[@]addprefix<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>]
|
||||
\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[[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
|
||||
|
||||
\function tf.check-colour-contrast-subfunction()
|
||||
[function[colour],<paletteEntryA>] [function[colour],<paletteEntryB>] +[colour-contrast:DeltaPhi[]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)
|
||||
<$macrocall $name="makedatauri" type={{{ [<title>get[type]] }}} text={{{ [<title>get[text]] }}} _canonical_uri={{{ [<title>get[_canonical_uri]] }}}/>
|
||||
|
||||
@@ -6,5 +6,5 @@ $:/language/
|
||||
\end
|
||||
|
||||
\define lingo(title)
|
||||
{{$(lingo-base)$$title$}}
|
||||
{{||$(lingo-base)$$title$}}
|
||||
\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 -->
|
||||
<!-- "nonSystemTagsFilter", "systemTagsFilter" __need to be the same__ as fields: "first-search-filter", "second-search-filter" -->
|
||||
<$let
|
||||
palette={{$:/palette}}
|
||||
palette="$:/temp/palette-colours"
|
||||
colourA={{{ [<palette>getindex[foreground]] }}}
|
||||
colourB={{{ [<palette>getindex[background]] }}}
|
||||
fallbackTarget={{{ [<palette>getindex[tag-background]] }}}
|
||||
|
||||
@@ -3,6 +3,7 @@ tags: $:/tags/Macro
|
||||
|
||||
\define tag-pill-styles()
|
||||
background-color:$(backgroundColor)$;
|
||||
fill:$(foregroundColor)$;
|
||||
color:$(foregroundColor)$;
|
||||
\end
|
||||
|
||||
@@ -27,15 +28,16 @@ color:$(foregroundColor)$;
|
||||
</$let>
|
||||
\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)
|
||||
\whitespace trim
|
||||
<$macrocall $name="tag-pill-inner"
|
||||
tag=<<__tag__>>
|
||||
icon=<<__icon__>>
|
||||
colour=<<__colour__>>
|
||||
fallbackTarget={{$palette$##tag-background}}
|
||||
colourA={{$palette$##foreground}}
|
||||
colourB={{$palette$##background}}
|
||||
fallbackTarget=<<colour tag-background>>
|
||||
colourA=<<colour foreground>>
|
||||
colourB=<<colour background>>
|
||||
element-tag=<<__element-tag__>>
|
||||
element-attributes=<<__element-attributes__>>
|
||||
actions=<<__actions__>>
|
||||
@@ -50,7 +52,6 @@ color:$(foregroundColor)$;
|
||||
tag=<<__tag__>>
|
||||
icon={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]!is[draft]get[text]] }}}
|
||||
colour={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}
|
||||
palette={{$:/palette}}
|
||||
element-tag=<<__element-tag__>>
|
||||
element-attributes=<<__element-attributes__>>
|
||||
actions=<<__actions__>>/>
|
||||
|
||||
@@ -21,7 +21,7 @@ tags: $:/tags/Macro
|
||||
style="width:$width$px;height:$height$px;background-color:$background-color$;"
|
||||
></$reveal></div><div
|
||||
class="tc-thumbnail-icon"
|
||||
style="color:$color$;"
|
||||
style="fill:$color$;color:$color$;"
|
||||
>$icon$</div><div class="tc-thumbnail-caption">$caption$</div></div></$link>
|
||||
\end
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
title: $:/palette
|
||||
|
||||
$:/palettes/Vanilla
|
||||
$:/palettes/AutoToggle
|
||||
@@ -1,19 +1,30 @@
|
||||
title: $:/snippets/paletteswitcher
|
||||
|
||||
\parameters (thumbnails)
|
||||
|
||||
\whitespace trim
|
||||
<$linkcatcher to="$:/palette">
|
||||
<div class="tc-chooser">
|
||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Palette]!is[draft]sort[name]]">
|
||||
<$set name="cls" filter="[all[current]prefix{$:/palette}]" value="tc-chooser-item tc-chosen" emptyValue="tc-chooser-item">
|
||||
<div class=<<cls>>>
|
||||
<$link to={{!!title}}>
|
||||
''<$view field="name" format="text"/>''
|
||||
 - 
|
||||
<$view field="description" format="text"/>
|
||||
{{||$:/snippets/currpalettepreview}}
|
||||
</$link>
|
||||
</div>
|
||||
</$set>
|
||||
</$list>
|
||||
\procedure actions()
|
||||
<$action-setfield $tiddler="$:/palette" text=<<navigateTo>>/>
|
||||
\end actions
|
||||
|
||||
<!-- Display palette in currentTiddler with selection logic -->
|
||||
\procedure palette-entry(thumbnails)
|
||||
<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]]}$`>
|
||||
<%if [<thumbnails>match[yes]] %>
|
||||
{{||$:/snippets/currpalettepreview}}
|
||||
<%endif%>
|
||||
''<$view field="name" format="text"/>''
|
||||
<br>
|
||||
<$view field="description" format="text"/>
|
||||
</$link>
|
||||
</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>
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
title: $:/snippets/palettetests
|
||||
|
||||
<$let failureCount={{{ [[$:/temp/palette-colours]indexes[]prefix[?]] :filter[[$:/temp/palette-colours]getindex<currentTiddler>!match[ok]] +[count[]] }}}>
|
||||
|
||||
<%if [<failureCount>compare:number:gt[0]] %>
|
||||
|
||||
Palette test failures: <$text text=<<failureCount>>/>
|
||||
|
||||
<$list filter="[[$:/temp/palette-colours]indexes[]prefix[?]sort[]]" variable="name">
|
||||
<%if [[$:/temp/palette-colours]getindex<name>!match[ok]] %>
|
||||
<div>
|
||||
''<$text text={{{ [<name>removeprefix[?]] }}}/>'': <$text text={{{ [[$:/temp/palette-colours]getindex<name>] }}}/>
|
||||
</div>
|
||||
<%endif%>
|
||||
</$list>
|
||||
|
||||
<%endif%>
|
||||
|
||||
</$let>
|
||||
@@ -0,0 +1,2 @@
|
||||
title: $:/tags/ControlPanel/Appearance
|
||||
text: $:/core/ui/ControlPanel/Palette $:/core/ui/ControlPanel/StoryView $:/core/ui/ControlPanel/Theme $:/core/ui/ControlPanel/Toolbars
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user