mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2026-01-22 10:54:46 +00:00
Compare commits
297 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f690458792 | ||
|
|
6bc18570f2 | ||
|
|
1f4b12cd0e | ||
|
|
608aa3378a | ||
|
|
bff7dc88e8 | ||
|
|
667da96c97 | ||
|
|
fb037de091 | ||
|
|
75865385a6 | ||
|
|
091a6a9dc1 | ||
|
|
38f0337207 | ||
|
|
a3b294470f | ||
|
|
53c5cc535e | ||
|
|
9e6713d3e0 | ||
|
|
1acad41574 | ||
|
|
9a5f6558fe | ||
|
|
5d9b71771a | ||
|
|
f891eacddc | ||
|
|
178e652a5d | ||
|
|
daf4eec702 | ||
|
|
34b1b8128f | ||
|
|
a453121e96 | ||
|
|
e849aaab4d | ||
|
|
453d91caeb | ||
|
|
0ad0001e29 | ||
|
|
2441819c70 | ||
|
|
ca762ab7a6 | ||
|
|
28070f847c | ||
|
|
8f85fbca33 | ||
|
|
655cf4729a | ||
|
|
55f3ee5eab | ||
|
|
63bba13758 | ||
|
|
c22d52c046 | ||
|
|
8c57cfdf26 | ||
|
|
4f38903c7b | ||
|
|
ab1e85e01e | ||
|
|
065911259b | ||
|
|
6497633859 | ||
|
|
9cc4c3ead7 | ||
|
|
613b3df367 | ||
|
|
39996c7a2f | ||
|
|
0237d9ed94 | ||
|
|
7e9c2a1a10 | ||
|
|
d4fc8f585e | ||
|
|
caa6b888e9 | ||
|
|
a1b240de2f | ||
|
|
7a98ab1677 | ||
|
|
c49d5a3b08 | ||
|
|
93717560dc | ||
|
|
abc3af16c3 | ||
|
|
97eaec88d1 | ||
|
|
2275255c2b | ||
|
|
fe1147c6fd | ||
|
|
eceacc23c8 | ||
|
|
1ca6305acb | ||
|
|
19331cc6f9 | ||
|
|
f6e021d70f | ||
|
|
2da117484c | ||
|
|
1c1dd2a4cf | ||
|
|
f957874d18 | ||
|
|
aa4a284b88 | ||
|
|
338dc11436 | ||
|
|
22d8fdd259 | ||
|
|
c270e3cd6b | ||
|
|
18d8173dcc | ||
|
|
4cd3c065e7 | ||
|
|
45895bd560 | ||
|
|
af86080943 | ||
|
|
94b02ba3a0 | ||
|
|
bbae2ab6da | ||
|
|
3b778c156b | ||
|
|
2f817e4293 | ||
|
|
0112d04033 | ||
|
|
56d8f47710 | ||
|
|
f818fd96cd | ||
|
|
c5821326d0 | ||
|
|
add14ef65a | ||
|
|
f93fe50044 | ||
|
|
ceec7b5737 | ||
|
|
76bc2f7524 | ||
|
|
a59ec3ebf7 | ||
|
|
20df381cf3 | ||
|
|
4185d9a26c | ||
|
|
bf6d5fa767 | ||
|
|
92c4c82005 | ||
|
|
1110fd50cf | ||
|
|
2c607ee8e6 | ||
|
|
dfebd69d8f | ||
|
|
926b7808b3 | ||
|
|
7ac7d26f86 | ||
|
|
f02bd2392f | ||
|
|
2b45bbc4c4 | ||
|
|
bce3ec6e6f | ||
|
|
5e35c8dda6 | ||
|
|
8af7054efa | ||
|
|
10bc84ba6c | ||
|
|
0391e1855c | ||
|
|
a29889a741 | ||
|
|
27609d2619 | ||
|
|
d5030eb87b | ||
|
|
35b0833e0c | ||
|
|
45f5ba7d38 | ||
|
|
8e64e21039 | ||
|
|
bb47cc97f5 | ||
|
|
7e4722f07a | ||
|
|
df7416d16b | ||
|
|
a226975b3e | ||
|
|
2a62da1498 | ||
|
|
696c5c9c7a | ||
|
|
c808764254 | ||
|
|
a9b0c5d7ff | ||
|
|
9e3c233686 | ||
|
|
8fabcabebb | ||
|
|
96cb66a27e | ||
|
|
6eb4fbeead | ||
|
|
7cbe1e1d83 | ||
|
|
5ea315fb98 | ||
|
|
855b6719d6 | ||
|
|
91cfb217d8 | ||
|
|
1a377a485b | ||
|
|
71ee271eac | ||
|
|
95e0fac655 | ||
|
|
084a5cb0f0 | ||
|
|
e9405ac810 | ||
|
|
775c7f0074 | ||
|
|
34f9cd952c | ||
|
|
e37f36f387 | ||
|
|
7a7d3571cc | ||
|
|
bc8c011eb3 | ||
|
|
b4deb7cc45 | ||
|
|
4b8594c4a8 | ||
|
|
9b9e443c73 | ||
|
|
f3bf5b6e85 | ||
|
|
5d55850c73 | ||
|
|
873ce4823f | ||
|
|
03910fce66 | ||
|
|
0bffae2108 | ||
|
|
bdd99edfe8 | ||
|
|
9bcbb9131e | ||
|
|
1410488a23 | ||
|
|
e2ef5c933b | ||
|
|
3cf078faeb | ||
|
|
9bad66f02e | ||
|
|
ed4ccc4290 | ||
|
|
6e3f4c8772 | ||
|
|
400936920a | ||
|
|
c78bff5bb2 | ||
|
|
8b309ecb42 | ||
|
|
e2869e6ede | ||
|
|
8e25f693c6 | ||
|
|
42bf203758 | ||
|
|
f0416964fa | ||
|
|
8dec674121 | ||
|
|
16f56af873 | ||
|
|
e9fa861418 | ||
|
|
5ab2148807 | ||
|
|
396e7e6921 | ||
|
|
3d2663c900 | ||
|
|
d31839d1e8 | ||
|
|
7d404e4ec5 | ||
|
|
5356345f19 | ||
|
|
f3ee7f429c | ||
|
|
59417f0896 | ||
|
|
2ab0f762e0 | ||
|
|
deeef27cff | ||
|
|
7459ccfed5 | ||
|
|
8d5c94e028 | ||
|
|
6d2d3396ac | ||
|
|
dc2c4635c1 | ||
|
|
fd0b985ac5 | ||
|
|
eb0b2a8d8e | ||
|
|
7d6923f3d6 | ||
|
|
05375e093c | ||
|
|
cc25e1f5b4 | ||
|
|
b3b3020d99 | ||
|
|
383c8b5e49 | ||
|
|
2fd17e864c | ||
|
|
030155ec27 | ||
|
|
58dd47d128 | ||
|
|
8a9d48e055 | ||
|
|
6c505ebc49 | ||
|
|
ae9a183a53 | ||
|
|
b9fec0c669 | ||
|
|
73138b79aa | ||
|
|
6624ce3716 | ||
|
|
c5ea6628f5 | ||
|
|
ad512be04e | ||
|
|
39e4e69ae7 | ||
|
|
8990423374 | ||
|
|
e28af8d594 | ||
|
|
2ab4e965b2 | ||
|
|
4b100503da | ||
|
|
1f14969ab8 | ||
|
|
0b6a345208 | ||
|
|
f97b25676e | ||
|
|
b5ad5c3421 | ||
|
|
2391675e9c | ||
|
|
def8e6d354 | ||
|
|
6701683ddf | ||
|
|
4a9cf67a25 | ||
|
|
5e38f1b0b8 | ||
|
|
73a9625b81 | ||
|
|
bc242cf83a | ||
|
|
051b29c5b3 | ||
|
|
e4b2698380 | ||
|
|
6e89ecd13a | ||
|
|
55eb37222a | ||
|
|
ff42a9e4d4 | ||
|
|
778581b4ff | ||
|
|
dafb3f1c4f | ||
|
|
adcef4f803 | ||
|
|
321f417d58 | ||
|
|
08d9c90dc5 | ||
|
|
6dbb3ee36e | ||
|
|
c920960942 | ||
|
|
ad490017f8 | ||
|
|
e84acf97de | ||
|
|
6a5d73dae6 | ||
|
|
98a509dbf3 | ||
|
|
5d69fe7bef | ||
|
|
b9ae6607c0 | ||
|
|
758d590837 | ||
|
|
1c16f12d6f | ||
|
|
9922701304 | ||
|
|
76236f5ebe | ||
|
|
aec2ad2d12 | ||
|
|
bd6ea2d6a9 | ||
|
|
74d63c7003 | ||
|
|
e26a4d8cb5 | ||
|
|
d1bc079138 | ||
|
|
ffd3599369 | ||
|
|
bfa5882175 | ||
|
|
258f4acb10 | ||
|
|
7e85ec35d3 | ||
|
|
a4dcd92f1b | ||
|
|
fe581a83b3 | ||
|
|
25b2e708c9 | ||
|
|
5db5d711d3 | ||
|
|
075b2ab149 | ||
|
|
8301fb8699 | ||
|
|
bc81195b5a | ||
|
|
02f8713012 | ||
|
|
9df88bfda9 | ||
|
|
97901d756e | ||
|
|
ecde2606ad | ||
|
|
938419ba2c | ||
|
|
1cb1e77785 | ||
|
|
a8331f8909 | ||
|
|
7cc100b82d | ||
|
|
681f22b66d | ||
|
|
b0c4886d23 | ||
|
|
c1f123499c | ||
|
|
977ea24e96 | ||
|
|
b529e69289 | ||
|
|
b5edaae1f4 | ||
|
|
22fd1ca630 | ||
|
|
c741978e95 | ||
|
|
28a91aafa7 | ||
|
|
1d8c538e45 | ||
|
|
3f0fb71635 | ||
|
|
347355128b | ||
|
|
2a38b15a29 | ||
|
|
84ad758829 | ||
|
|
f694f5ead7 | ||
|
|
29aef731a3 | ||
|
|
115b20ff7b | ||
|
|
a38b25eff5 | ||
|
|
71df5162ba | ||
|
|
864b5ec05d | ||
|
|
aaf1aa3821 | ||
|
|
8114d5475b | ||
|
|
29599baa3b | ||
|
|
b196cf77e8 | ||
|
|
4d3ebf4bf0 | ||
|
|
b3268546ef | ||
|
|
615d8da64f | ||
|
|
45a1478bc9 | ||
|
|
a071881562 | ||
|
|
2c38c8351b | ||
|
|
a51191d334 | ||
|
|
4054566493 | ||
|
|
5f994f7d46 | ||
|
|
7a7472833f | ||
|
|
9777aa9d13 | ||
|
|
d0b5b2124a | ||
|
|
95bd694a65 | ||
|
|
49de500b5e | ||
|
|
4cf3df0f86 | ||
|
|
1ae1ff3da2 | ||
|
|
4f42df8bef | ||
|
|
36b162a377 | ||
|
|
82c8fe7fa8 | ||
|
|
5378b45c40 | ||
|
|
94ab1e998d | ||
|
|
b12d6c0758 | ||
|
|
a89677ea40 | ||
|
|
6b31d7cae3 | ||
|
|
3e62e8406b |
43
.github/ISSUE_TEMPLATE/bug_report.md
vendored
43
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,43 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve TiddlyWiki 5
|
||||
title: "[BUG]"
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**TiddlyWiki Configuration (please complete the following information):**
|
||||
- Version [e.g. v5.1.24]
|
||||
- Saving mechanism [e.g. Node.js, TiddlyDesktop, TiddlyHost etc]
|
||||
- Plugins installed [e.g. Freelinks, TiddlyMap]
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Smartphone (please complete the following information):**
|
||||
- Device: [e.g. iPhone6]
|
||||
- OS: [e.g. iOS8.1]
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
67
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
67
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
name: Bug report
|
||||
description: Create a report to help us improve TiddlyWiki 5
|
||||
title: "[BUG] "
|
||||
body:
|
||||
- type: textarea
|
||||
id: Describe
|
||||
attributes:
|
||||
label: Describe the bug
|
||||
description: A clear and concise description of what the bug is.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: Expected
|
||||
attributes:
|
||||
label: Expected behavior
|
||||
description: A clear and concise description of what you expected to happen.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: Reproduce
|
||||
attributes:
|
||||
label: To Reproduce
|
||||
description: "Steps to reproduce the behavior:"
|
||||
value: |
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: Screenshots
|
||||
attributes:
|
||||
label: Screenshots
|
||||
description: If applicable, add screenshots to help explain your problem.
|
||||
placeholder: Drag image here to upload screenshot!
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: Configuration
|
||||
attributes:
|
||||
label: TiddlyWiki Configuration
|
||||
description: please complete the following information
|
||||
value: |
|
||||
- Version [e.g. v5.1.24]
|
||||
- Saving mechanism [e.g. Node.js, TiddlyDesktop, TiddlyHost etc]
|
||||
- Plugins installed [e.g. Freelinks, TiddlyMap]
|
||||
|
||||
### Desktop (please complete the following information):
|
||||
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
### Smartphone (please complete the following information):
|
||||
|
||||
- Device: [e.g. iPhone6]
|
||||
- OS: [e.g. iOS8.1]
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Version [e.g. 22]
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: Context
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any other context about the problem here.
|
||||
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Discuss feature request
|
||||
url: https://github.com/Jermolene/TiddlyWiki5/discussions
|
||||
about: Open new discussion about new feature
|
||||
- name: Talk.Tiddlywiki Forum
|
||||
url: https://talk.tiddlywiki.org
|
||||
about: Join the Forum
|
||||
@@ -20,3 +20,11 @@ A clear and concise description of any alternative solutions or features you've
|
||||
Add any other context or screenshots about the feature request here.
|
||||
|
||||
If you link to discussions elsewhere then please copy and paste the important text, and don't expect readers to scan the entire discussion to find the relevant part.
|
||||
|
||||
## Checklist before requesting a review
|
||||
|
||||
- [ ] Illustrate any visual changes (however minor) with before/after screenshots
|
||||
- [ ] Self-review of code
|
||||
- [ ] Documentation updates (for user-visible changes)
|
||||
- [ ] Tests (for core code changes)
|
||||
- [ ] Complies with coding style guidelines (for JavaScript code)
|
||||
|
||||
3
.github/workflows/ci.yml
vendored
3
.github/workflows/ci.yml
vendored
@@ -72,3 +72,6 @@ jobs:
|
||||
- run: "./bin/ci-push.sh"
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUBPUSHTOKEN }}
|
||||
- run: "./bin/build-tw-org.sh"
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUBPUSHTOKEN }}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# Default to the current version number for building the plugin library
|
||||
|
||||
if [ -z "$TW5_BUILD_VERSION" ]; then
|
||||
TW5_BUILD_VERSION=v5.2.2
|
||||
TW5_BUILD_VERSION=v5.2.3
|
||||
fi
|
||||
|
||||
echo "Using TW5_BUILD_VERSION as [$TW5_BUILD_VERSION]"
|
||||
|
||||
97
bin/build-tw-org.sh
Executable file
97
bin/build-tw-org.sh
Executable file
@@ -0,0 +1,97 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Build tiddlywiki.org assets.
|
||||
|
||||
# Default to the version of TiddlyWiki installed in this repo
|
||||
|
||||
if [ -z "$TWORG_BUILD_TIDDLYWIKI" ]; then
|
||||
TWORG_BUILD_TIDDLYWIKI=./tiddlywiki.js
|
||||
fi
|
||||
|
||||
echo "Using TWORG_BUILD_TIDDLYWIKI as [$TWORG_BUILD_TIDDLYWIKI]"
|
||||
|
||||
# Set up the build details
|
||||
|
||||
if [ -z "$TWORG_BUILD_DETAILS" ]; then
|
||||
TWORG_BUILD_DETAILS="$(git symbolic-ref --short HEAD)-$(git rev-parse HEAD) from $(git remote get-url origin)"
|
||||
fi
|
||||
|
||||
echo "Using TWORG_BUILD_DETAILS as [$TWORG_BUILD_DETAILS]"
|
||||
|
||||
if [ -z "$TWORG_BUILD_COMMIT" ]; then
|
||||
TWORG_BUILD_COMMIT="$(git rev-parse HEAD)"
|
||||
fi
|
||||
|
||||
echo "Using TWORG_BUILD_COMMIT as [$TWORG_BUILD_COMMIT]"
|
||||
|
||||
# Set up the build output directory
|
||||
|
||||
if [ -z "$TWORG_BUILD_OUTPUT" ]; then
|
||||
TWORG_BUILD_OUTPUT=$(mktemp -d)
|
||||
fi
|
||||
|
||||
mkdir -p $TWORG_BUILD_OUTPUT
|
||||
|
||||
if [ ! -d "$TWORG_BUILD_OUTPUT" ]; then
|
||||
echo 'A valid TWORG_BUILD_OUTPUT environment variable must be set'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Using TWORG_BUILD_OUTPUT as [$TWORG_BUILD_OUTPUT]"
|
||||
|
||||
# Pull existing GitHub pages content
|
||||
|
||||
git clone --depth=1 --branch=main "https://github.com/TiddlyWiki/tiddlywiki.org-gh-pages.git" $TWORG_BUILD_OUTPUT
|
||||
|
||||
# Make the CNAME file that GitHub Pages requires
|
||||
|
||||
echo "tiddlywiki.org" > $TWORG_BUILD_OUTPUT/CNAME
|
||||
|
||||
# Delete any existing static content
|
||||
|
||||
mkdir -p $TWORG_BUILD_OUTPUT/static
|
||||
rm $TWORG_BUILD_OUTPUT/static/*
|
||||
|
||||
# Put the build details into a .tid file so that it can be included in each build (deleted at the end of this script)
|
||||
|
||||
echo -e -n "title: $:/build\ncommit: $TWORG_BUILD_COMMIT\n\n$TWORG_BUILD_DETAILS\n" > $TWORG_BUILD_OUTPUT/build.tid
|
||||
|
||||
######################################################
|
||||
#
|
||||
# tiddlywiki.org distribution
|
||||
#
|
||||
######################################################
|
||||
|
||||
# /index.html Main site
|
||||
# /favicon.ico Favicon for main site
|
||||
# /static.html Static rendering of default tiddlers
|
||||
# /alltiddlers.html Static rendering of all tiddlers
|
||||
# /static/* Static single tiddlers
|
||||
# /static/static.css Static stylesheet
|
||||
# /static/favicon.ico Favicon for static pages
|
||||
node $TWORG_BUILD_TIDDLYWIKI \
|
||||
editions/tw.org \
|
||||
--verbose \
|
||||
--version \
|
||||
--load $TWORG_BUILD_OUTPUT/build.tid \
|
||||
--output $TWORG_BUILD_OUTPUT \
|
||||
--build favicon static index \
|
||||
|| exit 1
|
||||
|
||||
# Delete the temporary build tiddler
|
||||
|
||||
rm $TWORG_BUILD_OUTPUT/build.tid || exit 1
|
||||
|
||||
# Push output back to GitHub
|
||||
|
||||
# Exit script immediately if any command fails
|
||||
set -e
|
||||
|
||||
pushd $TWORG_BUILD_OUTPUT
|
||||
git config --global user.email "actions@github.com"
|
||||
git config --global user.name "GitHub Actions"
|
||||
git add -A .
|
||||
git commit --message "GitHub build: $GITHUB_RUN_NUMBER of $TW5_BUILD_BRANCH ($(date +'%F %T %Z'))"
|
||||
git remote add deploy "https://$GH_TOKEN@github.com/TiddlyWiki/tiddlywiki.org-gh-pages.git" &>/dev/null
|
||||
git push deploy main &>/dev/null
|
||||
popd
|
||||
62
boot/boot.js
62
boot/boot.js
@@ -68,6 +68,26 @@ $tw.utils.isArrayEqual = function(array1,array2) {
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
Add an entry to a sorted array if it doesn't already exist, while maintaining the sort order
|
||||
*/
|
||||
$tw.utils.insertSortedArray = function(array,value) {
|
||||
var low = 0, high = array.length - 1, mid, cmp;
|
||||
while(low <= high) {
|
||||
mid = (low + high) >> 1;
|
||||
cmp = value.localeCompare(array[mid]);
|
||||
if(cmp > 0) {
|
||||
low = mid + 1;
|
||||
} else if(cmp < 0) {
|
||||
high = mid - 1;
|
||||
} else {
|
||||
return array;
|
||||
}
|
||||
}
|
||||
array.splice(low,0,value);
|
||||
return array;
|
||||
};
|
||||
|
||||
/*
|
||||
Push entries onto an array, removing them first if they already exist in the array
|
||||
array: array to modify (assumed to be free of duplicates)
|
||||
@@ -409,6 +429,19 @@ $tw.utils.parseFields = function(text,fields) {
|
||||
return fields;
|
||||
};
|
||||
|
||||
// Safely parse a string as JSON
|
||||
$tw.utils.parseJSONSafe = function(text,defaultJSON) {
|
||||
try {
|
||||
return JSON.parse(text);
|
||||
} catch(e) {
|
||||
if(typeof defaultJSON === "function") {
|
||||
return defaultJSON(e);
|
||||
} else {
|
||||
return defaultJSON || {};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Resolves a source filepath delimited with `/` relative to a specified absolute root filepath.
|
||||
In relative paths, the special folder name `..` refers to immediate parent directory, and the
|
||||
@@ -1081,7 +1114,7 @@ $tw.Wiki = function(options) {
|
||||
tiddlerTitles = null, // Array of tiddler titles
|
||||
getTiddlerTitles = function() {
|
||||
if(!tiddlerTitles) {
|
||||
tiddlerTitles = Object.keys(tiddlers);
|
||||
tiddlerTitles = Object.keys(tiddlers).sort(function(a,b) {return a.localeCompare(b);});
|
||||
}
|
||||
return tiddlerTitles;
|
||||
},
|
||||
@@ -1134,10 +1167,8 @@ $tw.Wiki = function(options) {
|
||||
}
|
||||
// Save the new tiddler
|
||||
tiddlers[title] = tiddler;
|
||||
// Check we've got it's title
|
||||
if(tiddlerTitles && tiddlerTitles.indexOf(title) === -1) {
|
||||
tiddlerTitles.push(title);
|
||||
}
|
||||
// Check we've got the title
|
||||
tiddlerTitles = $tw.utils.insertSortedArray(tiddlerTitles || [],title);
|
||||
// Record the new tiddler state
|
||||
updateDescriptor["new"] = {
|
||||
tiddler: tiddler,
|
||||
@@ -1322,7 +1353,7 @@ $tw.Wiki = function(options) {
|
||||
var tiddler = tiddlers[title];
|
||||
if(tiddler) {
|
||||
if(tiddler.fields.type === "application/json" && tiddler.hasField("plugin-type") && tiddler.fields.text) {
|
||||
pluginInfo[tiddler.fields.title] = JSON.parse(tiddler.fields.text);
|
||||
pluginInfo[tiddler.fields.title] = $tw.utils.parseJSONSafe(tiddler.fields.text);
|
||||
results.modifiedPlugins.push(tiddler.fields.title);
|
||||
}
|
||||
} else {
|
||||
@@ -1455,7 +1486,7 @@ $tw.Wiki.prototype.defineTiddlerModules = function() {
|
||||
}
|
||||
break;
|
||||
case "application/json":
|
||||
$tw.modules.define(tiddler.fields.title,tiddler.fields["module-type"],JSON.parse(tiddler.fields.text));
|
||||
$tw.modules.define(tiddler.fields.title,tiddler.fields["module-type"],$tw.utils.parseJSONSafe(tiddler.fields.text));
|
||||
break;
|
||||
case "application/x-tiddler-dictionary":
|
||||
$tw.modules.define(tiddler.fields.title,tiddler.fields["module-type"],$tw.utils.parseFields(tiddler.fields.text));
|
||||
@@ -1644,12 +1675,7 @@ $tw.modules.define("$:/boot/tiddlerdeserializer/json","tiddlerdeserializer",{
|
||||
}
|
||||
return true;
|
||||
},
|
||||
data = {};
|
||||
try {
|
||||
data = JSON.parse(text);
|
||||
} catch(e) {
|
||||
// Ignore JSON parse errors
|
||||
}
|
||||
data = $tw.utils.parseJSONSafe(text);
|
||||
if($tw.utils.isArray(data) && isTiddlerArrayValid(data)) {
|
||||
return data;
|
||||
} else if(isTiddlerValid(data)) {
|
||||
@@ -1689,7 +1715,7 @@ $tw.boot.decryptEncryptedTiddlers = function(callback) {
|
||||
$tw.crypto.setPassword(data.password);
|
||||
var decryptedText = $tw.crypto.decrypt(encryptedText);
|
||||
if(decryptedText) {
|
||||
var json = JSON.parse(decryptedText);
|
||||
var json = $tw.utils.parseJSONSafe(decryptedText);
|
||||
for(var title in json) {
|
||||
$tw.preloadTiddler(json[title]);
|
||||
}
|
||||
@@ -1889,7 +1915,7 @@ filepath: pathname of the directory containing the specification file
|
||||
$tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
|
||||
var tiddlers = [];
|
||||
// Read the specification
|
||||
var filesInfo = JSON.parse(fs.readFileSync(filepath + path.sep + "tiddlywiki.files","utf8"));
|
||||
var filesInfo = $tw.utils.parseJSONSafe(fs.readFileSync(filepath + path.sep + "tiddlywiki.files","utf8"));
|
||||
// Helper to process a file
|
||||
var processFile = function(filename,isTiddlerFile,fields,isEditableFile) {
|
||||
var extInfo = $tw.config.fileExtensionInfo[path.extname(filename)],
|
||||
@@ -2019,7 +2045,7 @@ $tw.loadPluginFolder = function(filepath,excludeRegExp) {
|
||||
console.log("Warning: missing plugin.info file in " + filepath);
|
||||
return null;
|
||||
}
|
||||
var pluginInfo = JSON.parse(fs.readFileSync(infoPath,"utf8"));
|
||||
var pluginInfo = $tw.utils.parseJSONSafe(fs.readFileSync(infoPath,"utf8"));
|
||||
// Read the plugin files
|
||||
var pluginFiles = $tw.loadTiddlersFromPath(filepath,excludeRegExp);
|
||||
// Save the plugin tiddlers into the plugin info
|
||||
@@ -2136,7 +2162,7 @@ $tw.loadWikiTiddlers = function(wikiPath,options) {
|
||||
pluginFields;
|
||||
// Bail if we don't have a wiki info file
|
||||
if(fs.existsSync(wikiInfoPath)) {
|
||||
wikiInfo = JSON.parse(fs.readFileSync(wikiInfoPath,"utf8"));
|
||||
wikiInfo = $tw.utils.parseJSONSafe(fs.readFileSync(wikiInfoPath,"utf8"));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@@ -2570,7 +2596,7 @@ $tw.boot.isStartupTaskEligible = function(taskModule) {
|
||||
for(t=0; t<remaining.length; t++) {
|
||||
var task = remaining[t];
|
||||
if(task.before && task.before.indexOf(name) !== -1) {
|
||||
if($tw.boot.doesTaskMatchPlatform(task) || (task.name && $tw.boot.disabledStartupModules.indexOf(name) !== -1)) {
|
||||
if($tw.boot.doesTaskMatchPlatform(task) && (!task.name || $tw.boot.disabledStartupModules.indexOf(task.name) === -1)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -36,6 +36,8 @@ EditorTypes/Hint: These tiddlers determine which editor is used to edit specific
|
||||
EditorTypes/Type/Caption: Type
|
||||
EditTemplateBody/Caption: Edit Template Body
|
||||
EditTemplateBody/Hint: This rule cascade is used by the default edit template to dynamically choose the template for editing the body of a tiddler.
|
||||
FieldEditor/Caption: Field Editor
|
||||
FieldEditor/Hint: This rules cascade is used to dynamically choose the template for rendering a tiddler field based on its name. It is used within the Edit Template.
|
||||
Info/Caption: Info
|
||||
Info/Hint: Information about this TiddlyWiki
|
||||
KeyboardShortcuts/Add/Prompt: Type shortcut here
|
||||
@@ -226,4 +228,4 @@ Tools/Download/Full/Caption: Download full wiki
|
||||
ViewTemplateBody/Caption: View Template Body
|
||||
ViewTemplateBody/Hint: This rule cascade is used by the default view template to dynamically choose the template for displaying the body of a tiddler.
|
||||
ViewTemplateTitle/Caption: View Template Title
|
||||
ViewTemplateTitle/Hint: This rule cascade is used by the default view template to dynamically choose the template for displaying the title of a tiddler.
|
||||
ViewTemplateTitle/Hint: This rule cascade is used by the default view template to dynamically choose the template for displaying the title of a tiddler.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
title: $:/language/EditTemplate/
|
||||
|
||||
Caption: Editor
|
||||
Body/External/Hint: This tiddler shows content stored outside of the main TiddlyWiki file. You can edit the tags and fields but cannot directly edit the content itself
|
||||
Body/Placeholder: Type the text for this tiddler
|
||||
Body/Preview/Type/Output: output
|
||||
|
||||
@@ -3,6 +3,7 @@ title: $:/language/Help/default
|
||||
\define commandTitle()
|
||||
$:/language/Help/$(command)$
|
||||
\end
|
||||
\whitespace trim
|
||||
```
|
||||
usage: tiddlywiki [<wikifolder>] [--<command> [<args>...]...]
|
||||
```
|
||||
@@ -11,7 +12,9 @@ Available commands:
|
||||
|
||||
<ul>
|
||||
<$list filter="[commands[]sort[title]]" variable="command">
|
||||
<li><$link to=<<commandTitle>>><$macrocall $name="command" $type="text/plain" $output="text/plain"/></$link>: <$transclude tiddler=<<commandTitle>> field="description"/></li>
|
||||
<li><$link to=<<commandTitle>>><$macrocall $name="command" $type="text/plain" $output="text/plain"/></$link>:
|
||||
 
|
||||
<$transclude tiddler=<<commandTitle>> field="description"/></li>
|
||||
</$list>
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -31,5 +31,5 @@ Notes:
|
||||
|
||||
Examples:
|
||||
|
||||
* `--render "[!is[system]]" "[encodeuricomponent[]addprefix[tiddlers/]addsuffix[.html]]"` -- renders all non-system tiddlers as files in the subdirectory "tiddlers" with URL-encoded titles and the extension HTML
|
||||
|
||||
* `--render '[!is[system]]' '[encodeuricomponent[]addprefix[tiddlers/]addsuffix[.html]]'` -- renders all non-system tiddlers as files in the subdirectory "tiddlers" with URL-encoded titles and the extension HTML
|
||||
* `--render '.' 'tiddlers.json' 'text/plain' '$:/core/templates/exporters/JsonFile' 'exportFilter' '[tag[HelloThere]]'` -- renders the tiddlers tagged "HelloThere" to a JSON file named "tiddlers.json"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
title: $:/language/SideBar/
|
||||
|
||||
Caption: Sidebar
|
||||
All/Caption: All
|
||||
Contents/Caption: Contents
|
||||
Drafts/Caption: Drafts
|
||||
|
||||
@@ -48,7 +48,7 @@ Command.prototype.execute = function() {
|
||||
}
|
||||
// Tweak the tiddlywiki.info to remove any included wikis
|
||||
var packagePath = $tw.boot.wikiPath + "/tiddlywiki.info",
|
||||
packageJson = JSON.parse(fs.readFileSync(packagePath));
|
||||
packageJson = $tw.utils.parseJSONSafe(fs.readFileSync(packagePath));
|
||||
delete packageJson.includeWikis;
|
||||
fs.writeFileSync(packagePath,JSON.stringify(packageJson,null,$tw.config.preferences.jsonSpaces));
|
||||
return null;
|
||||
|
||||
@@ -50,7 +50,7 @@ Render individual tiddlers and save the results to the specified files
|
||||
console.log("Rendering \"" + title + "\" to \"" + filepath + "\"");
|
||||
}
|
||||
var parser = wiki.parseTiddler(template || title),
|
||||
widgetNode = wiki.makeWidget(parser,{variables: $tw.utils.extend({},variables,{currentTiddler: title})}),
|
||||
widgetNode = wiki.makeWidget(parser,{variables: $tw.utils.extend({},variables,{currentTiddler: title,storyTiddler: title})}),
|
||||
container = $tw.fakeDocument.createElement("div");
|
||||
widgetNode.render(container,null);
|
||||
var text = type === "text/html" ? container.innerHTML : container.textContent;
|
||||
|
||||
@@ -40,6 +40,7 @@ Command.prototype.execute = function() {
|
||||
$tw.utils.createFileDirectories(filename);
|
||||
if(template) {
|
||||
variables.currentTiddler = title;
|
||||
variables.storyTiddler = title;
|
||||
title = template;
|
||||
}
|
||||
if(name && value) {
|
||||
|
||||
@@ -46,7 +46,7 @@ Command.prototype.execute = function() {
|
||||
}
|
||||
$tw.utils.each(tiddlers,function(title) {
|
||||
var parser = wiki.parseTiddler(template),
|
||||
widgetNode = wiki.makeWidget(parser,{variables: {currentTiddler: title}}),
|
||||
widgetNode = wiki.makeWidget(parser,{variables: {currentTiddler: title, storyTiddler: title}}),
|
||||
container = $tw.fakeDocument.createElement("div");
|
||||
widgetNode.render(container,null);
|
||||
var text = type === "text/html" ? container.innerHTML : container.textContent,
|
||||
|
||||
@@ -8,46 +8,60 @@ Saves individual tiddlers in their raw text or binary format to the specified fi
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
exports.info = {
|
||||
name: "save",
|
||||
synchronous: true
|
||||
};
|
||||
|
||||
var Command = function(params,commander,callback) {
|
||||
this.params = params;
|
||||
this.commander = commander;
|
||||
this.callback = callback;
|
||||
};
|
||||
|
||||
Command.prototype.execute = function() {
|
||||
if(this.params.length < 1) {
|
||||
return "Missing filename filter";
|
||||
}
|
||||
var self = this,
|
||||
fs = require("fs"),
|
||||
path = require("path"),
|
||||
wiki = this.commander.wiki,
|
||||
tiddlerFilter = this.params[0],
|
||||
filenameFilter = this.params[1] || "[is[tiddler]]",
|
||||
tiddlers = wiki.filterTiddlers(tiddlerFilter);
|
||||
$tw.utils.each(tiddlers,function(title) {
|
||||
var tiddler = self.commander.wiki.getTiddler(title),
|
||||
type = tiddler.fields.type || "text/vnd.tiddlywiki",
|
||||
contentTypeInfo = $tw.config.contentTypeInfo[type] || {encoding: "utf8"},
|
||||
filepath = path.resolve(self.commander.outputPath,wiki.filterTiddlers(filenameFilter,$tw.rootWidget,wiki.makeTiddlerIterator([title]))[0]);
|
||||
if(self.commander.verbose) {
|
||||
console.log("Saving \"" + title + "\" to \"" + filepath + "\"");
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
exports.info = {
|
||||
name: "save",
|
||||
synchronous: true
|
||||
};
|
||||
|
||||
var Command = function(params,commander,callback) {
|
||||
this.params = params;
|
||||
this.commander = commander;
|
||||
this.callback = callback;
|
||||
};
|
||||
|
||||
Command.prototype.execute = function() {
|
||||
if(this.params.length < 1) {
|
||||
return "Missing filename filter";
|
||||
}
|
||||
$tw.utils.createFileDirectories(filepath);
|
||||
fs.writeFileSync(filepath,tiddler.fields.text,contentTypeInfo.encoding);
|
||||
});
|
||||
return null;
|
||||
};
|
||||
|
||||
exports.Command = Command;
|
||||
|
||||
})();
|
||||
var self = this,
|
||||
fs = require("fs"),
|
||||
path = require("path"),
|
||||
result = null,
|
||||
wiki = this.commander.wiki,
|
||||
tiddlerFilter = this.params[0],
|
||||
filenameFilter = this.params[1] || "[is[tiddler]]",
|
||||
tiddlers = wiki.filterTiddlers(tiddlerFilter);
|
||||
$tw.utils.each(tiddlers,function(title) {
|
||||
if(!result) {
|
||||
var tiddler = self.commander.wiki.getTiddler(title);
|
||||
if(tiddler) {
|
||||
var fileInfo = $tw.utils.generateTiddlerFileInfo(tiddler,{
|
||||
directory: path.resolve(self.commander.outputPath),
|
||||
pathFilters: [filenameFilter],
|
||||
wiki: wiki,
|
||||
fileInfo: {}
|
||||
});
|
||||
if(self.commander.verbose) {
|
||||
console.log("Saving \"" + title + "\" to \"" + fileInfo.filepath + "\"");
|
||||
}
|
||||
try {
|
||||
$tw.utils.saveTiddlerToFileSync(tiddler,fileInfo);
|
||||
} catch (err) {
|
||||
result = "Error saving tiddler \"" + title + "\", to file: \"" + fileInfo.filepath + "\"";
|
||||
}
|
||||
} else {
|
||||
result = "Tiddler '" + title + "' not found";
|
||||
}
|
||||
}
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
exports.Command = Command;
|
||||
|
||||
})();
|
||||
|
||||
@@ -69,7 +69,7 @@ Command.prototype.execute = function() {
|
||||
$tw.utils.createFileDirectories(pathname);
|
||||
fs.writeFileSync(pathname,JSON.stringify(tiddler),"utf8");
|
||||
// Collect the skinny list data
|
||||
var pluginTiddlers = JSON.parse(tiddler.text),
|
||||
var pluginTiddlers = $tw.utils.parseJSONSafe(tiddler.text),
|
||||
readmeContent = (pluginTiddlers.tiddlers[title + "/readme"] || {}).text,
|
||||
doesRequireReload = !!self.commander.wiki.doesPluginInfoRequireReload(pluginTiddlers),
|
||||
iconTiddler = pluginTiddlers.tiddlers[title + "/icon"] || {},
|
||||
|
||||
@@ -151,7 +151,7 @@ WikiFolderMaker.prototype.saveCustomPlugin = function(pluginTiddler) {
|
||||
pluginInfo = pluginTiddler.getFieldStrings({exclude: ["text","type"]});
|
||||
this.saveJSONFile(directory + path.sep + "plugin.info",pluginInfo);
|
||||
self.log("Writing " + directory + path.sep + "plugin.info: " + JSON.stringify(pluginInfo,null,$tw.config.preferences.jsonSpaces));
|
||||
var pluginTiddlers = JSON.parse(pluginTiddler.fields.text).tiddlers; // A hashmap of tiddlers in the plugin
|
||||
var pluginTiddlers = $tw.utils.parseJSONSafe(pluginTiddler.fields.text).tiddlers; // A hashmap of tiddlers in the plugin
|
||||
$tw.utils.each(pluginTiddlers,function(tiddler) {
|
||||
self.saveTiddler(directory,new $tw.Tiddler(tiddler));
|
||||
});
|
||||
|
||||
@@ -17,16 +17,13 @@ exports["application/x-tiddler-html-div"] = function(text,fields) {
|
||||
};
|
||||
|
||||
exports["application/json"] = function(text,fields) {
|
||||
var incoming,
|
||||
results = [];
|
||||
try {
|
||||
incoming = JSON.parse(text);
|
||||
} catch(e) {
|
||||
incoming = [{
|
||||
title: "JSON error: " + e,
|
||||
text: ""
|
||||
}]
|
||||
}
|
||||
var results = [],
|
||||
incoming = $tw.utils.parseJSONSafe(text,function(err) {
|
||||
return [{
|
||||
title: "JSON error: " + err,
|
||||
text: ""
|
||||
}];
|
||||
});
|
||||
if(!$tw.utils.isArray(incoming)) {
|
||||
incoming = [incoming];
|
||||
}
|
||||
|
||||
@@ -34,8 +34,10 @@ 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 colorScheme = (this.widget.wiki.getTiddler(paletteTitle) || {fields: {}}).fields["color-scheme"] || "light";
|
||||
this.iframeDoc.open();
|
||||
this.iframeDoc.write("");
|
||||
this.iframeDoc.write("<meta name='color-scheme' content='" + colorScheme + "'>");
|
||||
this.iframeDoc.close();
|
||||
// Style the iframe
|
||||
this.iframeNode.className = this.dummyTextArea.className;
|
||||
|
||||
@@ -25,8 +25,8 @@ exports["prefix-lines"] = function(event,operation) {
|
||||
$tw.utils.each(lines,function(line,index) {
|
||||
// Remove and count any existing prefix characters
|
||||
var count = 0;
|
||||
while(line.charAt(0) === event.paramObject.character) {
|
||||
line = line.substring(1);
|
||||
while($tw.utils.startsWith(line,event.paramObject.character)) {
|
||||
line = line.substring(event.paramObject.character.length);
|
||||
count++;
|
||||
}
|
||||
// Remove any whitespace
|
||||
|
||||
@@ -15,16 +15,33 @@ Text editor operation to wrap the selected lines with a prefix and suffix
|
||||
exports["wrap-lines"] = function(event,operation) {
|
||||
var prefix = event.paramObject.prefix || "",
|
||||
suffix = event.paramObject.suffix || "";
|
||||
// Cut just past the preceding line break, or the start of the text
|
||||
operation.cutStart = $tw.utils.findPrecedingLineBreak(operation.text,operation.selStart);
|
||||
// Cut to just past the following line break, or to the end of the text
|
||||
operation.cutEnd = $tw.utils.findFollowingLineBreak(operation.text,operation.selEnd);
|
||||
// Add the prefix and suffix
|
||||
operation.replacement = prefix + "\n" +
|
||||
operation.text.substring(operation.cutStart,operation.cutEnd) + "\n" +
|
||||
suffix + "\n";
|
||||
operation.newSelStart = operation.cutStart + prefix.length + 1;
|
||||
operation.newSelEnd = operation.newSelStart + (operation.cutEnd - operation.cutStart);
|
||||
if($tw.utils.endsWith(operation.text.substring(0,operation.selStart), prefix + "\n") &&
|
||||
$tw.utils.startsWith(operation.text.substring(operation.selEnd), "\n" + suffix)) {
|
||||
// Selected text is already surrounded by prefix and suffix: Remove them
|
||||
// Cut selected text plus prefix and suffix
|
||||
operation.cutStart = operation.selStart - (prefix.length + 1);
|
||||
operation.cutEnd = operation.selEnd + suffix.length + 1;
|
||||
// Also cut the following newline (if there is any)
|
||||
if (operation.text[operation.cutEnd] === "\n") {
|
||||
operation.cutEnd++;
|
||||
}
|
||||
// Replace with selection
|
||||
operation.replacement = operation.text.substring(operation.selStart,operation.selEnd);
|
||||
// Select text that was in between prefix and suffix
|
||||
operation.newSelStart = operation.cutStart;
|
||||
operation.newSelEnd = operation.selEnd - (prefix.length + 1);
|
||||
} else {
|
||||
// Cut just past the preceding line break, or the start of the text
|
||||
operation.cutStart = $tw.utils.findPrecedingLineBreak(operation.text,operation.selStart);
|
||||
// Cut to just past the following line break, or to the end of the text
|
||||
operation.cutEnd = $tw.utils.findFollowingLineBreak(operation.text,operation.selEnd);
|
||||
// Add the prefix and suffix
|
||||
operation.replacement = prefix + "\n" +
|
||||
operation.text.substring(operation.cutStart,operation.cutEnd) + "\n" +
|
||||
suffix + "\n";
|
||||
operation.newSelStart = operation.cutStart + prefix.length + 1;
|
||||
operation.newSelEnd = operation.newSelStart + (operation.cutEnd - operation.cutStart);
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
@@ -16,7 +16,9 @@ exports.map = function(operationSubFunction,options) {
|
||||
return function(results,source,widget) {
|
||||
if(results.length > 0) {
|
||||
var inputTitles = results.toArray(),
|
||||
index = 0;
|
||||
index = 0,
|
||||
suffixes = options.suffixes,
|
||||
flatten = (suffixes[0] && suffixes[0][0] === "flat") ? true : false;
|
||||
results.clear();
|
||||
$tw.utils.each(inputTitles,function(title) {
|
||||
var filtered = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{
|
||||
@@ -36,7 +38,13 @@ exports.map = function(operationSubFunction,options) {
|
||||
}
|
||||
}
|
||||
});
|
||||
results.push(filtered[0] || "");
|
||||
if(filtered.length && flatten) {
|
||||
$tw.utils.each(filtered,function(value) {
|
||||
results.push(value);
|
||||
})
|
||||
} else {
|
||||
results.push(filtered[0]||"");
|
||||
}
|
||||
++index;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -220,10 +220,18 @@ source: an iterator function for the source tiddlers, called source(iterator), w
|
||||
widget: an optional widget node for retrieving the current tiddler etc.
|
||||
*/
|
||||
exports.compileFilter = function(filterString) {
|
||||
if(!this.filterCache) {
|
||||
this.filterCache = Object.create(null);
|
||||
this.filterCacheCount = 0;
|
||||
}
|
||||
if(this.filterCache[filterString] !== undefined) {
|
||||
return this.filterCache[filterString];
|
||||
}
|
||||
var filterParseTree;
|
||||
try {
|
||||
filterParseTree = this.parseFilter(filterString);
|
||||
} catch(e) {
|
||||
// We do not cache this result, so it adjusts along with localization changes
|
||||
return function(source,widget) {
|
||||
return [$tw.language.getString("Error/Filter") + ": " + e];
|
||||
};
|
||||
@@ -320,7 +328,7 @@ exports.compileFilter = function(filterString) {
|
||||
})());
|
||||
});
|
||||
// Return a function that applies the operations to a source iterator of tiddler titles
|
||||
return $tw.perf.measure("filter: " + filterString,function filterFunction(source,widget) {
|
||||
var compiled = $tw.perf.measure("filter: " + filterString,function filterFunction(source,widget) {
|
||||
if(!source) {
|
||||
source = self.each;
|
||||
} else if(typeof source === "object") { // Array or hashmap
|
||||
@@ -335,6 +343,16 @@ exports.compileFilter = function(filterString) {
|
||||
});
|
||||
return results.toArray();
|
||||
});
|
||||
if(this.filterCacheCount >= 2000) {
|
||||
// To prevent memory leak, we maintain an upper limit for cache size.
|
||||
// Reset if exceeded. This should give us 95% of the benefit
|
||||
// that no cache limit would give us.
|
||||
this.filterCache = Object.create(null);
|
||||
this.filterCacheCount = 0;
|
||||
}
|
||||
this.filterCache[filterString] = compiled;
|
||||
this.filterCacheCount++;
|
||||
return compiled;
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
46
core/modules/filters/insertafter.js
Normal file
46
core/modules/filters/insertafter.js
Normal file
@@ -0,0 +1,46 @@
|
||||
/*\
|
||||
title: $:/core/modules/filters/insertafter.js
|
||||
type: application/javascript
|
||||
module-type: filteroperator
|
||||
|
||||
Insert an item after another item in a list
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
Order a list
|
||||
*/
|
||||
exports.insertafter = function(source,operator,options) {
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
results.push(title);
|
||||
});
|
||||
var target = operator.operands[1] || (options.widget && options.widget.getVariable(operator.suffix || "currentTiddler"));
|
||||
if(target !== operator.operand) {
|
||||
// Remove the entry from the list if it is present
|
||||
var pos = results.indexOf(operator.operand);
|
||||
if(pos !== -1) {
|
||||
results.splice(pos,1);
|
||||
}
|
||||
// Insert the entry after the target marker
|
||||
pos = results.indexOf(target);
|
||||
if(pos !== -1) {
|
||||
results.splice(pos+1,0,operator.operand);
|
||||
} else {
|
||||
var suffix = operator.operands.length > 1 ? operator.suffix : "";
|
||||
if(suffix === "start") {
|
||||
results.splice(0,0,operator.operand);
|
||||
} else {
|
||||
results.push(operator.operand);
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -20,7 +20,7 @@ exports.insertbefore = function(source,operator,options) {
|
||||
source(function(tiddler,title) {
|
||||
results.push(title);
|
||||
});
|
||||
var target = options.widget && options.widget.getVariable(operator.suffix || "currentTiddler");
|
||||
var target = operator.operands[1] || (options.widget && options.widget.getVariable(operator.suffix || "currentTiddler"));
|
||||
if(target !== operator.operand) {
|
||||
// Remove the entry from the list if it is present
|
||||
var pos = results.indexOf(operator.operand);
|
||||
@@ -32,7 +32,12 @@ exports.insertbefore = function(source,operator,options) {
|
||||
if(pos !== -1) {
|
||||
results.splice(pos,0,operator.operand);
|
||||
} else {
|
||||
results.push(operator.operand);
|
||||
var suffix = operator.operands.length > 1 ? operator.suffix : "";
|
||||
if(suffix == "start") {
|
||||
results.splice(0,0,operator.operand);
|
||||
} else {
|
||||
results.push(operator.operand);
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
|
||||
@@ -19,13 +19,13 @@ exports.draft = function(source,prefix,options) {
|
||||
var results = [];
|
||||
if(prefix === "!") {
|
||||
source(function(tiddler,title) {
|
||||
if(!tiddler || !$tw.utils.hop(tiddler.fields,"draft.of")) {
|
||||
if(!tiddler || !tiddler.isDraft()) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
if(tiddler && $tw.utils.hop(tiddler.fields,"draft.of") && (tiddler.fields["draft.of"].length !== 0)) {
|
||||
if(tiddler && tiddler.isDraft()) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -87,7 +87,8 @@ exports.butlast = function(source,operator,options) {
|
||||
source(function(tiddler,title) {
|
||||
results.push(title);
|
||||
});
|
||||
return results.slice(0,-count);
|
||||
var index = count === 0 ? results.length : -count;
|
||||
return results.slice(0,index);
|
||||
};
|
||||
exports.bl = exports.butlast;
|
||||
|
||||
|
||||
@@ -16,19 +16,37 @@ Filter operator for checking if a title starts with a prefix
|
||||
Export our filter function
|
||||
*/
|
||||
exports.prefix = function(source,operator,options) {
|
||||
var results = [];
|
||||
if(operator.prefix === "!") {
|
||||
source(function(tiddler,title) {
|
||||
if(title.substr(0,operator.operand.length) !== operator.operand) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
var results = [],
|
||||
suffixes = (operator.suffixes || [])[0] || [];
|
||||
if(suffixes.indexOf("caseinsensitive") !== -1) {
|
||||
var operand = operator.operand.toLowerCase();
|
||||
if(operator.prefix === "!") {
|
||||
source(function(tiddler,title) {
|
||||
if(title.toLowerCase().substr(0,operand.length) !== operand) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
if(title.toLowerCase().substr(0,operand.length) === operand) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
if(title.substr(0,operator.operand.length) === operator.operand) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
if(operator.prefix === "!") {
|
||||
source(function(tiddler,title) {
|
||||
if(title.substr(0,operator.operand.length) !== operator.operand) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
if(title.substr(0,operator.operand.length) === operator.operand) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
@@ -16,12 +16,22 @@ Filter operator for removing a prefix from each title in the list. Titles that d
|
||||
Export our filter function
|
||||
*/
|
||||
exports.removeprefix = function(source,operator,options) {
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
if(title.substr(0,operator.operand.length) === operator.operand) {
|
||||
results.push(title.substr(operator.operand.length));
|
||||
}
|
||||
});
|
||||
var results = [],
|
||||
suffixes = (operator.suffixes || [])[0] || [];
|
||||
if(suffixes.indexOf("caseinsensitive") !== -1) {
|
||||
var operand = operator.operand.toLowerCase();
|
||||
source(function(tiddler,title) {
|
||||
if(title.toLowerCase().substr(0,operand.length) === operand) {
|
||||
results.push(title.substr(operand.length));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
if(title.substr(0,operator.operand.length) === operator.operand) {
|
||||
results.push(title.substr(operator.operand.length));
|
||||
}
|
||||
});
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
|
||||
@@ -16,12 +16,26 @@ Filter operator for removing a suffix from each title in the list. Titles that d
|
||||
Export our filter function
|
||||
*/
|
||||
exports.removesuffix = function(source,operator,options) {
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
if(title && title.substr(-operator.operand.length) === operator.operand) {
|
||||
results.push(title.substr(0,title.length - operator.operand.length));
|
||||
}
|
||||
});
|
||||
var results = [],
|
||||
suffixes = (operator.suffixes || [])[0] || [];
|
||||
if (!operator.operand) {
|
||||
source(function(tiddler,title) {
|
||||
results.push(title);
|
||||
});
|
||||
} else if(suffixes.indexOf("caseinsensitive") !== -1) {
|
||||
var operand = operator.operand.toLowerCase();
|
||||
source(function(tiddler,title) {
|
||||
if(title && title.toLowerCase().substr(-operand.length) === operand) {
|
||||
results.push(title.substr(0,title.length - operand.length));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
if(title && title.substr(-operator.operand.length) === operator.operand) {
|
||||
results.push(title.substr(0,title.length - operator.operand.length));
|
||||
}
|
||||
});
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
|
||||
@@ -16,19 +16,41 @@ Filter operator for checking if a title ends with a suffix
|
||||
Export our filter function
|
||||
*/
|
||||
exports.suffix = function(source,operator,options) {
|
||||
var results = [];
|
||||
if(operator.prefix === "!") {
|
||||
var results = [],
|
||||
suffixes = (operator.suffixes || [])[0] || [];
|
||||
if (!operator.operand) {
|
||||
source(function(tiddler,title) {
|
||||
if(title.substr(-operator.operand.length) !== operator.operand) {
|
||||
results.push(title);
|
||||
}
|
||||
results.push(title);
|
||||
});
|
||||
} else if(suffixes.indexOf("caseinsensitive") !== -1) {
|
||||
var operand = operator.operand.toLowerCase();
|
||||
if(operator.prefix === "!") {
|
||||
source(function(tiddler,title) {
|
||||
if(title.toLowerCase().substr(-operand.length) !== operand) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
if(title.toLowerCase().substr(-operand.length) === operand) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
if(title.substr(-operator.operand.length) === operator.operand) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
if(operator.prefix === "!") {
|
||||
source(function(tiddler,title) {
|
||||
if(title.substr(-operator.operand.length) !== operator.operand) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
if(title.substr(-operator.operand.length) === operator.operand) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
@@ -19,7 +19,7 @@ exports.untagged = function(source,operator,options) {
|
||||
var results = [],
|
||||
expected = (operator.prefix === "!");
|
||||
source(function(tiddler,title) {
|
||||
if((tiddler && $tw.utils.isArray(tiddler.fields.tags) && tiddler.fields.tags.length > 0) === expected) {
|
||||
if(((tiddler && $tw.utils.isArray(tiddler.fields.tags) && tiddler.fields.tags.length > 0) === expected) || (!tiddler && !expected)) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -239,7 +239,7 @@ exports.parseFilterVariable = function(source) {
|
||||
};
|
||||
|
||||
/*
|
||||
Look for an HTML attribute definition. Returns null if not found, otherwise returns {type: "attribute", name:, valueType: "string|indirect|macro", value:, start:, end:,}
|
||||
Look for an HTML attribute definition. Returns null if not found, otherwise returns {type: "attribute", name:, type: "filtered|string|indirect|macro", value|filter|textReference:, start:, end:,}
|
||||
*/
|
||||
exports.parseAttribute = function(source,pos) {
|
||||
var node = {
|
||||
@@ -248,7 +248,7 @@ exports.parseAttribute = function(source,pos) {
|
||||
// Define our regexps
|
||||
var reAttributeName = /([^\/\s>"'=]+)/g,
|
||||
reUnquotedAttribute = /([^\/\s<>"'=]+)/g,
|
||||
reFilteredValue = /\{\{\{(.+?)\}\}\}/g,
|
||||
reFilteredValue = /\{\{\{([\S\s]+?)\}\}\}/g,
|
||||
reIndirectValue = /\{\{([^\}]+)\}\}/g;
|
||||
// Skip whitespace
|
||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||
|
||||
@@ -52,7 +52,7 @@ PluginSwitcher.prototype.switchPlugins = function() {
|
||||
var tiddler = self.wiki.getTiddler(title);
|
||||
if(tiddler && tiddler.isPlugin() && plugins.indexOf(title) === -1) {
|
||||
plugins.push(title);
|
||||
var pluginInfo = JSON.parse(self.wiki.getTiddlerText(title)),
|
||||
var pluginInfo = $tw.utils.parseJSONSafe(self.wiki.getTiddlerText(title)),
|
||||
dependents = $tw.utils.parseStringArray(tiddler.fields.dependents || "");
|
||||
$tw.utils.each(dependents,function(title) {
|
||||
accumulatePlugin(title);
|
||||
|
||||
@@ -61,7 +61,7 @@ GiteaSaver.prototype.save = function(text,method,callback) {
|
||||
}
|
||||
var use_put = true;
|
||||
if(xhr.status !== 404) {
|
||||
getResponseData = JSON.parse(getResponseDataJson);
|
||||
getResponseData = $tw.utils.parseJSONSafe(getResponseDataJson);
|
||||
$tw.utils.each(getResponseData,function(details) {
|
||||
if(details.name === filename) {
|
||||
sha = details.sha;
|
||||
@@ -104,7 +104,7 @@ GiteaSaver.prototype.upload = function(uri,method,headers,data,callback) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
var putResponseData = JSON.parse(putResponseDataJson);
|
||||
var putResponseData = $tw.utils.parseJSONSafe(putResponseDataJson);
|
||||
callback(null);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -61,7 +61,7 @@ GitHubSaver.prototype.save = function(text,method,callback) {
|
||||
return callback(err);
|
||||
}
|
||||
if(xhr.status !== 404) {
|
||||
getResponseData = JSON.parse(getResponseDataJson);
|
||||
getResponseData = $tw.utils.parseJSONSafe(getResponseDataJson);
|
||||
$tw.utils.each(getResponseData,function(details) {
|
||||
if(details.name === filename) {
|
||||
sha = details.sha;
|
||||
@@ -84,7 +84,7 @@ GitHubSaver.prototype.save = function(text,method,callback) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
var putResponseData = JSON.parse(putResponseDataJson);
|
||||
var putResponseData = $tw.utils.parseJSONSafe(putResponseDataJson);
|
||||
callback(null);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -58,7 +58,7 @@ GitLabSaver.prototype.save = function(text,method,callback) {
|
||||
}
|
||||
var requestType = "POST";
|
||||
if(xhr.status !== 404) {
|
||||
getResponseData = JSON.parse(getResponseDataJson);
|
||||
getResponseData = $tw.utils.parseJSONSafe(getResponseDataJson);
|
||||
$tw.utils.each(getResponseData,function(details) {
|
||||
if(details.name === filename) {
|
||||
requestType = "PUT";
|
||||
@@ -82,7 +82,7 @@ GitLabSaver.prototype.save = function(text,method,callback) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
var putResponseData = JSON.parse(putResponseDataJson);
|
||||
var putResponseData = $tw.utils.parseJSONSafe(putResponseDataJson);
|
||||
callback(null);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -80,6 +80,7 @@ PutSaver.prototype.save = function(text,method,callback) {
|
||||
if(this.etag) {
|
||||
headers["If-Match"] = this.etag;
|
||||
}
|
||||
$tw.notifier.display("$:/language/Notifications/Save/Starting");
|
||||
$tw.utils.httpRequest({
|
||||
url: this.uri(),
|
||||
type: "PUT",
|
||||
@@ -87,17 +88,20 @@ PutSaver.prototype.save = function(text,method,callback) {
|
||||
data: text,
|
||||
callback: function(err,data,xhr) {
|
||||
if(err) {
|
||||
// response is textual: "XMLHttpRequest error code: 412"
|
||||
var status = Number(err.substring(err.indexOf(':') + 2, err.length))
|
||||
var status = xhr.status,
|
||||
errorMsg = err;
|
||||
if(status === 412) { // file changed on server
|
||||
callback($tw.language.getString("Error/PutEditConflict"));
|
||||
errorMsg = $tw.language.getString("Error/PutEditConflict");
|
||||
} else if(status === 401) { // authentication required
|
||||
callback($tw.language.getString("Error/PutUnauthorized"));
|
||||
errorMsg = $tw.language.getString("Error/PutUnauthorized");
|
||||
} else if(status === 403) { // permission denied
|
||||
callback($tw.language.getString("Error/PutForbidden"));
|
||||
} else {
|
||||
callback(err); // fail
|
||||
errorMsg = $tw.language.getString("Error/PutForbidden");
|
||||
}
|
||||
if (xhr.responseText) {
|
||||
// treat any server response like a plain text error explanation
|
||||
errorMsg = errorMsg + "\n\n" + xhr.responseText;
|
||||
}
|
||||
callback(errorMsg); // fail
|
||||
} else {
|
||||
self.etag = xhr.getResponseHeader("ETag");
|
||||
if(self.etag == null) {
|
||||
|
||||
@@ -64,6 +64,7 @@ UploadSaver.prototype.save = function(text,method,callback) {
|
||||
var tail = "\r\n--" + boundary + "--\r\n",
|
||||
data = head.join("\r\n") + text + tail;
|
||||
// Do the HTTP post
|
||||
$tw.notifier.display("$:/language/Notifications/Save/Starting");
|
||||
var http = new XMLHttpRequest();
|
||||
http.open("POST",url,true,username,password);
|
||||
http.setRequestHeader("Content-Type","multipart/form-data; charset=UTF-8; boundary=" + boundary);
|
||||
@@ -81,7 +82,6 @@ UploadSaver.prototype.save = function(text,method,callback) {
|
||||
} catch(ex) {
|
||||
return callback($tw.language.getString("Error/Caption") + ":" + ex);
|
||||
}
|
||||
$tw.notifier.display("$:/language/Notifications/Save/Starting");
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ exports.path = /^\/recipes\/default\/tiddlers\/(.+)$/;
|
||||
|
||||
exports.handler = function(request,response,state) {
|
||||
var title = $tw.utils.decodeURIComponentSafe(state.params[0]),
|
||||
fields = JSON.parse(state.data);
|
||||
fields = $tw.utils.parseJSONSafe(state.data);
|
||||
// Pull up any subfields in the `fields` object
|
||||
if(fields.fields) {
|
||||
$tw.utils.each(fields.fields,function(field,name) {
|
||||
|
||||
@@ -359,8 +359,9 @@ Server.prototype.listen = function(port,host,prefix) {
|
||||
}
|
||||
// Display the port number after we've started listening (the port number might have been specified as zero, in which case we will get an assigned port)
|
||||
server.on("listening",function() {
|
||||
var address = server.address();
|
||||
$tw.utils.log("Serving on " + self.protocol + "://" + address.address + ":" + address.port + prefix,"brown/orange");
|
||||
var address = server.address(),
|
||||
url = self.protocol + "://" + (address.family === "IPv6" ? "[" + address.address + "]" : address.address) + ":" + address.port + prefix;
|
||||
$tw.utils.log("Serving on " + url,"brown/orange");
|
||||
$tw.utils.log("(press ctrl-C to exit)","red");
|
||||
});
|
||||
// Listen
|
||||
|
||||
@@ -62,12 +62,14 @@ function loadIFrame(url,callback) {
|
||||
Unload library iframe for given url
|
||||
*/
|
||||
function unloadIFrame(url){
|
||||
$tw.utils.each(document.getElementsByTagName('iframe'), function(iframe) {
|
||||
var iframes = document.getElementsByTagName('iframe');
|
||||
for(var t=iframes.length-1; t--; t>=0) {
|
||||
var iframe = iframes[t];
|
||||
if(iframe.getAttribute("library") === "true" &&
|
||||
iframe.getAttribute("src") === url) {
|
||||
iframe.parentNode.removeChild(iframe);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function saveIFrameInfoTiddler(iframeInfo) {
|
||||
@@ -152,7 +154,7 @@ exports.startup = function() {
|
||||
if(event.data.status.charAt(0) === "2") {
|
||||
if(event.data.cookies) {
|
||||
if(event.data.cookies.type === "save-info") {
|
||||
var tiddlers = JSON.parse(event.data.body);
|
||||
var tiddlers = $tw.utils.parseJSONSafe(event.data.body);
|
||||
$tw.utils.each(tiddlers,function(tiddler) {
|
||||
$tw.wiki.addTiddler(new $tw.Tiddler($tw.wiki.getCreationFields(),tiddler,{
|
||||
title: event.data.cookies.infoTitlePrefix + event.data.cookies.url + "/" + tiddler.title,
|
||||
@@ -170,7 +172,7 @@ exports.startup = function() {
|
||||
},$tw.wiki.getModificationFields()));
|
||||
});
|
||||
} else if(event.data.cookies.type === "save-tiddler") {
|
||||
var tiddler = JSON.parse(event.data.body);
|
||||
var tiddler = $tw.utils.parseJSONSafe(event.data.body);
|
||||
$tw.wiki.addTiddler(new $tw.Tiddler(tiddler));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,12 +42,17 @@ exports.startup = function() {
|
||||
$tw.styleWidgetNode = $tw.wiki.makeTranscludeWidget(PAGE_STYLESHEET_TITLE,{document: $tw.fakeDocument});
|
||||
$tw.styleContainer = $tw.fakeDocument.createElement("style");
|
||||
$tw.styleWidgetNode.render($tw.styleContainer,null);
|
||||
$tw.styleWidgetNode.assignedStyles = $tw.styleContainer.textContent;
|
||||
$tw.styleElement = document.createElement("style");
|
||||
$tw.styleElement.innerHTML = $tw.styleContainer.textContent;
|
||||
$tw.styleElement.innerHTML = $tw.styleWidgetNode.assignedStyles;
|
||||
document.head.insertBefore($tw.styleElement,document.head.firstChild);
|
||||
$tw.wiki.addEventListener("change",$tw.perf.report("styleRefresh",function(changes) {
|
||||
if($tw.styleWidgetNode.refresh(changes,$tw.styleContainer,null)) {
|
||||
$tw.styleElement.innerHTML = $tw.styleContainer.textContent;
|
||||
var newStyles = $tw.styleContainer.textContent;
|
||||
if(newStyles !== $tw.styleWidgetNode.assignedStyles) {
|
||||
$tw.styleWidgetNode.assignedStyles = newStyles;
|
||||
$tw.styleElement.innerHTML = $tw.styleWidgetNode.assignedStyles;
|
||||
}
|
||||
}
|
||||
}));
|
||||
// Display the $:/core/ui/PageTemplate tiddler to kick off the display
|
||||
|
||||
@@ -54,7 +54,9 @@ exports.startup = function() {
|
||||
var hash = $tw.utils.getLocationHash();
|
||||
if(hash !== $tw.locationHash) {
|
||||
$tw.locationHash = hash;
|
||||
openStartupTiddlers({defaultToCurrentStory: true});
|
||||
if(hash !== "#") {
|
||||
openStartupTiddlers({defaultToCurrentStory: true});
|
||||
}
|
||||
}
|
||||
},false);
|
||||
// Listen for the tm-browser-refresh message
|
||||
|
||||
@@ -20,6 +20,8 @@ exports.synchronous = true;
|
||||
|
||||
// Global to keep track of open windows (hashmap by title)
|
||||
$tw.windows = {};
|
||||
// Default template to use for new windows
|
||||
var DEFAULT_WINDOW_TEMPLATE = "$:/core/templates/single.tiddler.window";
|
||||
|
||||
exports.startup = function() {
|
||||
// Handle open window message
|
||||
@@ -29,24 +31,25 @@ exports.startup = function() {
|
||||
title = event.param || event.tiddlerTitle,
|
||||
paramObject = event.paramObject || {},
|
||||
windowTitle = paramObject.windowTitle || title,
|
||||
template = paramObject.template || "$:/core/templates/single.tiddler.window",
|
||||
windowID = paramObject.windowID || title,
|
||||
template = paramObject.template || DEFAULT_WINDOW_TEMPLATE,
|
||||
width = paramObject.width || "700",
|
||||
height = paramObject.height || "600",
|
||||
top = paramObject.top,
|
||||
left = paramObject.left,
|
||||
variables = $tw.utils.extend({},paramObject,{currentTiddler: title});
|
||||
variables = $tw.utils.extend({},paramObject,{currentTiddler: title, "tv-window-id": windowID});
|
||||
// Open the window
|
||||
var srcWindow,
|
||||
srcDocument;
|
||||
// In case that popup blockers deny opening a new window
|
||||
try {
|
||||
srcWindow = window.open("","external-" + title,"scrollbars,width=" + width + ",height=" + height + (top ? ",top=" + top : "" ) + (left ? ",left=" + left : "" )),
|
||||
srcWindow = window.open("","external-" + windowID,"scrollbars,width=" + width + ",height=" + height + (top ? ",top=" + top : "" ) + (left ? ",left=" + left : "" )),
|
||||
srcDocument = srcWindow.document;
|
||||
}
|
||||
catch(e) {
|
||||
return;
|
||||
}
|
||||
$tw.windows[title] = srcWindow;
|
||||
$tw.windows[windowID] = srcWindow;
|
||||
// Check for reopening the same window
|
||||
if(srcWindow.haveInitialisedWindow) {
|
||||
return;
|
||||
@@ -56,7 +59,7 @@ exports.startup = function() {
|
||||
srcDocument.close();
|
||||
srcDocument.title = windowTitle;
|
||||
srcWindow.addEventListener("beforeunload",function(event) {
|
||||
delete $tw.windows[title];
|
||||
delete $tw.windows[windowID];
|
||||
$tw.wiki.removeEventListener("change",refreshHandler);
|
||||
},false);
|
||||
// Set up the styles
|
||||
@@ -90,13 +93,21 @@ exports.startup = function() {
|
||||
srcWindow.document.documentElement.addEventListener("click",$tw.popup,true);
|
||||
srcWindow.haveInitialisedWindow = true;
|
||||
});
|
||||
// Close open windows when unloading main window
|
||||
$tw.addUnloadTask(function() {
|
||||
$tw.rootWidget.addEventListener("tm-close-window",function(event) {
|
||||
var windowID = event.param,
|
||||
win = $tw.windows[windowID];
|
||||
if(win) {
|
||||
win.close();
|
||||
}
|
||||
});
|
||||
var closeAllWindows = function() {
|
||||
$tw.utils.each($tw.windows,function(win) {
|
||||
win.close();
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
$tw.rootWidget.addEventListener("tm-close-all-windows",closeAllWindows);
|
||||
// Close open windows when unloading main window
|
||||
$tw.addUnloadTask(closeAllWindows);
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
@@ -41,7 +41,7 @@ exports.upgrade = function(wiki,titles,tiddlers) {
|
||||
// Check if we're dealing with a plugin
|
||||
if(incomingTiddler && incomingTiddler["plugin-type"]) {
|
||||
// Check whether the plugin contains JS modules
|
||||
var requiresReload = wiki.doesPluginInfoRequireReload(JSON.parse(incomingTiddler.text)) ? (wiki.getTiddlerText("$:/language/ControlPanel/Plugins/PluginWillRequireReload") + " ") : "";
|
||||
var requiresReload = wiki.doesPluginInfoRequireReload($tw.utils.parseJSONSafe(incomingTiddler.text)) ? (wiki.getTiddlerText("$:/language/ControlPanel/Plugins/PluginWillRequireReload") + " ") : "";
|
||||
messages[title] = requiresReload;
|
||||
if(incomingTiddler.version) {
|
||||
// Upgrade the incoming plugin if it is in the upgrade library
|
||||
|
||||
@@ -33,7 +33,7 @@ Attempt to extract the tiddlers from an encrypted store area using the current p
|
||||
exports.decryptStoreArea = function(encryptedStoreArea,password) {
|
||||
var decryptedText = $tw.crypto.decrypt(encryptedStoreArea,password);
|
||||
if(decryptedText) {
|
||||
var json = JSON.parse(decryptedText),
|
||||
var json = $tw.utils.parseJSONSafe(decryptedText),
|
||||
tiddlers = [];
|
||||
for(var title in json) {
|
||||
if(title !== "$:/isEncrypted") {
|
||||
|
||||
@@ -281,5 +281,56 @@ exports.getLocationPath = function() {
|
||||
return window.location.toString().split("#")[0];
|
||||
};
|
||||
|
||||
/*
|
||||
Collect DOM variables
|
||||
*/
|
||||
exports.collectDOMVariables = function(selectedNode,domNode,event) {
|
||||
var variables = {},
|
||||
selectedNodeRect,
|
||||
domNodeRect;
|
||||
if(selectedNode) {
|
||||
$tw.utils.each(selectedNode.attributes,function(attribute) {
|
||||
variables["dom-" + attribute.name] = attribute.value.toString();
|
||||
});
|
||||
|
||||
if(selectedNode.offsetLeft) {
|
||||
// Add a variable with a popup coordinate string for the selected node
|
||||
variables["tv-popup-coords"] = "(" + selectedNode.offsetLeft + "," + selectedNode.offsetTop +"," + selectedNode.offsetWidth + "," + selectedNode.offsetHeight + ")";
|
||||
|
||||
// Add variables for offset of selected node
|
||||
variables["tv-selectednode-posx"] = selectedNode.offsetLeft.toString();
|
||||
variables["tv-selectednode-posy"] = selectedNode.offsetTop.toString();
|
||||
variables["tv-selectednode-width"] = selectedNode.offsetWidth.toString();
|
||||
variables["tv-selectednode-height"] = selectedNode.offsetHeight.toString();
|
||||
}
|
||||
}
|
||||
|
||||
if(domNode && domNode.offsetWidth) {
|
||||
variables["tv-widgetnode-width"] = domNode.offsetWidth.toString();
|
||||
variables["tv-widgetnode-height"] = domNode.offsetHeight.toString();
|
||||
}
|
||||
|
||||
if(event && event.clientX && event.clientY) {
|
||||
if(selectedNode) {
|
||||
// Add variables for event X and Y position relative to selected node
|
||||
selectedNodeRect = selectedNode.getBoundingClientRect();
|
||||
variables["event-fromselected-posx"] = (event.clientX - selectedNodeRect.left).toString();
|
||||
variables["event-fromselected-posy"] = (event.clientY - selectedNodeRect.top).toString();
|
||||
}
|
||||
|
||||
if(domNode) {
|
||||
// Add variables for event X and Y position relative to event catcher node
|
||||
domNodeRect = domNode.getBoundingClientRect();
|
||||
variables["event-fromcatcher-posx"] = (event.clientX - domNodeRect.left).toString();
|
||||
variables["event-fromcatcher-posy"] = (event.clientY - domNodeRect.top).toString();
|
||||
}
|
||||
|
||||
// Add variables for event X and Y position relative to the viewport
|
||||
variables["event-fromviewport-posx"] = event.clientX.toString();
|
||||
variables["event-fromviewport-posy"] = event.clientY.toString();
|
||||
}
|
||||
return variables;
|
||||
};
|
||||
|
||||
|
||||
})();
|
||||
|
||||
@@ -16,17 +16,18 @@ Browser data transfer utilities, used with the clipboard and drag and drop
|
||||
Options:
|
||||
|
||||
domNode: dom node to make draggable
|
||||
selector: CSS selector to identify element within domNode to be used as drag handle (optional)
|
||||
dragImageType: "pill", "blank" or "dom" (the default)
|
||||
dragTiddlerFn: optional function to retrieve the title of tiddler to drag
|
||||
dragFilterFn: optional function to retreive the filter defining a list of tiddlers to drag
|
||||
widget: widget to use as the contect for the filter
|
||||
widget: widget to use as the context for the filter
|
||||
*/
|
||||
exports.makeDraggable = function(options) {
|
||||
var dragImageType = options.dragImageType || "dom",
|
||||
dragImage,
|
||||
domNode = options.domNode;
|
||||
// Make the dom node draggable (not necessary for anchor tags)
|
||||
if((domNode.tagName || "").toLowerCase() !== "a") {
|
||||
if(!options.selector && ((domNode.tagName || "").toLowerCase() !== "a")) {
|
||||
domNode.setAttribute("draggable","true");
|
||||
}
|
||||
// Add event handlers
|
||||
@@ -39,20 +40,26 @@ exports.makeDraggable = function(options) {
|
||||
var dragTiddler = options.dragTiddlerFn && options.dragTiddlerFn(),
|
||||
dragFilter = options.dragFilterFn && options.dragFilterFn(),
|
||||
titles = dragTiddler ? [dragTiddler] : [],
|
||||
startActions = options.startActions;
|
||||
startActions = options.startActions,
|
||||
variables,
|
||||
domNodeRect;
|
||||
if(dragFilter) {
|
||||
titles.push.apply(titles,options.widget.wiki.filterTiddlers(dragFilter,options.widget));
|
||||
}
|
||||
var titleString = $tw.utils.stringifyList(titles);
|
||||
// Check that we've something to drag
|
||||
if(titles.length > 0 && event.target === domNode) {
|
||||
if(titles.length > 0 && (options.selector && $tw.utils.domMatchesSelector(event.target,options.selector) || event.target === domNode)) {
|
||||
// Mark the drag in progress
|
||||
$tw.dragInProgress = domNode;
|
||||
// Set the dragging class on the element being dragged
|
||||
$tw.utils.addClass(event.target,"tc-dragging");
|
||||
$tw.utils.addClass(domNode,"tc-dragging");
|
||||
// Invoke drag-start actions if given
|
||||
if(startActions !== undefined) {
|
||||
options.widget.invokeActionString(startActions,options.widget,event,{actionTiddler: titleString});
|
||||
// Collect our variables
|
||||
variables = $tw.utils.collectDOMVariables(domNode,null,event);
|
||||
variables.modifier = $tw.keyboardManager.getEventModifierKeyDescriptor(event);
|
||||
variables["actionTiddler"] = titleString;
|
||||
options.widget.invokeActionString(startActions,options.widget,event,variables);
|
||||
}
|
||||
// Create the drag image elements
|
||||
dragImage = options.widget.document.createElement("div");
|
||||
@@ -99,20 +106,22 @@ exports.makeDraggable = function(options) {
|
||||
dataTransfer.setData("text/vnd.tiddler",jsonData);
|
||||
dataTransfer.setData("text/plain",titleString);
|
||||
dataTransfer.setData("text/x-moz-url","data:text/vnd.tiddler," + encodeURIComponent(jsonData));
|
||||
} else {
|
||||
dataTransfer.setData("URL","data:text/vnd.tiddler," + encodeURIComponent(jsonData));
|
||||
}
|
||||
dataTransfer.setData("URL","data:text/vnd.tiddler," + encodeURIComponent(jsonData));
|
||||
dataTransfer.setData("Text",titleString);
|
||||
event.stopPropagation();
|
||||
}
|
||||
return false;
|
||||
}},
|
||||
{name: "dragend", handlerFunction: function(event) {
|
||||
if(event.target === domNode) {
|
||||
if((options.selector && $tw.utils.domMatchesSelector(event.target,options.selector)) || event.target === domNode) {
|
||||
// Collect the tiddlers being dragged
|
||||
var dragTiddler = options.dragTiddlerFn && options.dragTiddlerFn(),
|
||||
dragFilter = options.dragFilterFn && options.dragFilterFn(),
|
||||
titles = dragTiddler ? [dragTiddler] : [],
|
||||
endActions = options.endActions;
|
||||
endActions = options.endActions,
|
||||
variables;
|
||||
if(dragFilter) {
|
||||
titles.push.apply(titles,options.widget.wiki.filterTiddlers(dragFilter,options.widget));
|
||||
}
|
||||
@@ -120,10 +129,13 @@ exports.makeDraggable = function(options) {
|
||||
$tw.dragInProgress = null;
|
||||
// Invoke drag-end actions if given
|
||||
if(endActions !== undefined) {
|
||||
options.widget.invokeActionString(endActions,options.widget,event,{actionTiddler: titleString});
|
||||
variables = $tw.utils.collectDOMVariables(domNode,null,event);
|
||||
variables.modifier = $tw.keyboardManager.getEventModifierKeyDescriptor(event);
|
||||
variables["actionTiddler"] = titleString;
|
||||
options.widget.invokeActionString(endActions,options.widget,event,variables);
|
||||
}
|
||||
// Remove the dragging class on the element being dragged
|
||||
$tw.utils.removeClass(event.target,"tc-dragging");
|
||||
$tw.utils.removeClass(domNode,"tc-dragging");
|
||||
// Delete the drag image element
|
||||
if(dragImage) {
|
||||
dragImage.parentNode.removeChild(dragImage);
|
||||
@@ -198,7 +210,7 @@ var importDataTypes = [
|
||||
];
|
||||
|
||||
function parseJSONTiddlers(json,fallbackTitle) {
|
||||
var data = JSON.parse(json);
|
||||
var data = $tw.utils.parseJSONSafe(json);
|
||||
if(!$tw.utils.isArray(data)) {
|
||||
data = [data];
|
||||
}
|
||||
|
||||
@@ -36,8 +36,9 @@ Notifier.prototype.display = function(title,options) {
|
||||
if(!tiddler) {
|
||||
return;
|
||||
}
|
||||
// Add classes
|
||||
// Add classes and roles
|
||||
$tw.utils.addClass(notification,"tc-notification");
|
||||
notification.setAttribute("role","alert");
|
||||
// Create the variables
|
||||
var variables = $tw.utils.extend({currentTiddler: title},options.variables);
|
||||
// Render the body of the notification
|
||||
|
||||
@@ -30,11 +30,7 @@ exports.getEditionInfo = function() {
|
||||
var entry = entries[entryIndex];
|
||||
// Check if directories have a valid tiddlywiki.info
|
||||
if(!editionInfo[entry] && $tw.utils.isDirectory(path.resolve(editionPath,entry))) {
|
||||
var info;
|
||||
try {
|
||||
info = JSON.parse(fs.readFileSync(path.resolve(editionPath,entry,"tiddlywiki.info"),"utf8"));
|
||||
} catch(ex) {
|
||||
}
|
||||
var info = $tw.utils.parseJSONSafe(fs.readFileSync(path.resolve(editionPath,entry,"tiddlywiki.info"),"utf8"),null);
|
||||
if(info) {
|
||||
editionInfo[entry] = info;
|
||||
}
|
||||
|
||||
@@ -13,8 +13,26 @@ Parse tree utility functions.
|
||||
"use strict";
|
||||
|
||||
exports.addAttributeToParseTreeNode = function(node,name,value) {
|
||||
var attribute = {name: name, type: "string", value: value};
|
||||
node.attributes = node.attributes || {};
|
||||
node.attributes[name] = {type: "string", value: value};
|
||||
node.attributes[name] = attribute;
|
||||
if(node.orderedAttributes) {
|
||||
node.orderedAttributes.push(attribute);
|
||||
}
|
||||
};
|
||||
|
||||
exports.getOrderedAttributesFromParseTreeNode = function(node) {
|
||||
if(node.orderedAttributes) {
|
||||
return node.orderedAttributes;
|
||||
} else {
|
||||
var attributes = [];
|
||||
$tw.utils.each(node.attributes,function(attribute) {
|
||||
attributes.push(attribute);
|
||||
});
|
||||
return attributes.sort(function(a,b) {
|
||||
return a.name < b.name ? -1 : (a.name > b.name ? 1 : 0);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
exports.getAttributeValueFromParseTreeNode = function(node,name,defaultValue) {
|
||||
@@ -25,26 +43,45 @@ exports.getAttributeValueFromParseTreeNode = function(node,name,defaultValue) {
|
||||
};
|
||||
|
||||
exports.addClassToParseTreeNode = function(node,classString) {
|
||||
var classes = [];
|
||||
var classes = [],
|
||||
attribute;
|
||||
node.attributes = node.attributes || {};
|
||||
node.attributes["class"] = node.attributes["class"] || {type: "string", value: ""};
|
||||
if(node.attributes["class"].type === "string") {
|
||||
if(node.attributes["class"].value !== "") {
|
||||
classes = node.attributes["class"].value.split(" ");
|
||||
attribute = node.attributes["class"];
|
||||
if(!attribute) {
|
||||
// If the class attribute does not exist, we must create it first.
|
||||
attribute = {name: "class", type: "string", value: ""};
|
||||
node.attributes["class"] = attribute;
|
||||
if(node.orderedAttributes) {
|
||||
// If there are orderedAttributes, we've got to add them there too.
|
||||
node.orderedAttributes.push(attribute);
|
||||
}
|
||||
}
|
||||
if(attribute.type === "string") {
|
||||
if(attribute.value !== "") {
|
||||
classes = attribute.value.split(" ");
|
||||
}
|
||||
if(classString !== "") {
|
||||
$tw.utils.pushTop(classes,classString.split(" "));
|
||||
}
|
||||
node.attributes["class"].value = classes.join(" ");
|
||||
attribute.value = classes.join(" ");
|
||||
}
|
||||
};
|
||||
|
||||
exports.addStyleToParseTreeNode = function(node,name,value) {
|
||||
node.attributes = node.attributes || {};
|
||||
node.attributes.style = node.attributes.style || {type: "string", value: ""};
|
||||
if(node.attributes.style.type === "string") {
|
||||
node.attributes.style.value += name + ":" + value + ";";
|
||||
var attribute;
|
||||
node.attributes = node.attributes || {};
|
||||
attribute = node.attributes.style;
|
||||
if(!attribute) {
|
||||
attribute = {name: "style", type: "string", value: ""};
|
||||
node.attributes.style = attribute;
|
||||
if(node.orderedAttributes) {
|
||||
// If there are orderedAttributes, we've got to add them there too.
|
||||
node.orderedAttributes.push(attribute);
|
||||
}
|
||||
}
|
||||
if(attribute.type === "string") {
|
||||
attribute.value += name + ":" + value + ";";
|
||||
}
|
||||
};
|
||||
|
||||
exports.findParseTreeNode = function(nodeArray,search) {
|
||||
|
||||
@@ -24,10 +24,8 @@ exports.repackPlugin = function(title,additionalTiddlers,excludeTiddlers) {
|
||||
throw "No such tiddler as " + title;
|
||||
}
|
||||
// Extract the JSON
|
||||
var jsonPluginTiddler;
|
||||
try {
|
||||
jsonPluginTiddler = JSON.parse(pluginTiddler.fields.text);
|
||||
} catch(e) {
|
||||
var jsonPluginTiddler = $tw.utils.parseJSONSafe(pluginTiddler.fields.text,null);
|
||||
if(!jsonPluginTiddler) {
|
||||
throw "Cannot parse plugin tiddler " + title + "\n" + $tw.language.getString("Error/Caption") + ": " + e;
|
||||
}
|
||||
// Get the list of tiddlers
|
||||
|
||||
@@ -95,6 +95,20 @@ exports.repeat = function(str,count) {
|
||||
return result;
|
||||
};
|
||||
|
||||
/*
|
||||
Check if a string starts with another string
|
||||
*/
|
||||
exports.startsWith = function(str,search) {
|
||||
return str.substring(0, search.length) === 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
|
||||
Thanks to Steven Levithan, http://blog.stevenlevithan.com/archives/faster-trim-javascript
|
||||
@@ -448,7 +462,7 @@ exports.formatDateString = function(date,template) {
|
||||
// 'return raw UTC (tiddlywiki style) date string.'
|
||||
if(t.indexOf("[UTC]") == 0 ) {
|
||||
if(t == "[UTC]YYYY0MM0DD0hh0mm0ssXXX")
|
||||
return $tw.utils.stringifyDate(new Date());
|
||||
return $tw.utils.stringifyDate(date || new Date());
|
||||
var offset = date.getTimezoneOffset() ; // in minutes
|
||||
date = new Date(date.getTime()+offset*60*1000) ;
|
||||
t = t.substr(5) ;
|
||||
|
||||
@@ -71,8 +71,8 @@ ActionListopsWidget.prototype.invokeAction = function(triggeringWidget,
|
||||
}
|
||||
if(this.subfilter) {
|
||||
var inputList = this.wiki.getTiddlerList(this.target,field,index),
|
||||
subfilter = $tw.utils.stringifyList(inputList) + " " + this.subfilter;
|
||||
this.wiki.setText(this.target, field, index, $tw.utils.stringifyList(this.wiki.filterTiddlers(subfilter,this)));
|
||||
subfilter = "[all[]] " + this.subfilter;
|
||||
this.wiki.setText(this.target, field, index, $tw.utils.stringifyList(this.wiki.filterTiddlers(subfilter,this,this.wiki.makeTiddlerIterator(inputList))));
|
||||
}
|
||||
if(this.filtertags) {
|
||||
var tiddler = this.wiki.getTiddler(this.target),
|
||||
|
||||
@@ -35,7 +35,7 @@ SetFieldWidget.prototype.render = function(parent,nextSibling) {
|
||||
Compute the internal state of the widget
|
||||
*/
|
||||
SetFieldWidget.prototype.execute = function() {
|
||||
this.actionTiddler = this.getAttribute("$tiddler",this.getVariable("currentTiddler"));
|
||||
this.actionTiddler = this.getAttribute("$tiddler") || (!this.hasParseTreeNodeAttribute("$tiddler") && this.getVariable("currentTiddler"));
|
||||
this.actionField = this.getAttribute("$field");
|
||||
this.actionIndex = this.getAttribute("$index");
|
||||
this.actionValue = this.getAttribute("$value");
|
||||
@@ -46,11 +46,7 @@ SetFieldWidget.prototype.execute = function() {
|
||||
Refresh the widget by ensuring our attributes are up to date
|
||||
*/
|
||||
SetFieldWidget.prototype.refresh = function(changedTiddlers) {
|
||||
var changedAttributes = this.computeAttributes();
|
||||
if(changedAttributes["$tiddler"] || changedAttributes["$field"] || changedAttributes["$index"] || changedAttributes["$value"]) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
}
|
||||
// Nothing to refresh
|
||||
return this.refreshChildren(changedTiddlers);
|
||||
};
|
||||
|
||||
@@ -60,15 +56,17 @@ Invoke the action associated with this widget
|
||||
SetFieldWidget.prototype.invokeAction = function(triggeringWidget,event) {
|
||||
var self = this,
|
||||
options = {};
|
||||
options.suppressTimestamp = !this.actionTimestamp;
|
||||
if((typeof this.actionField == "string") || (typeof this.actionIndex == "string") || (typeof this.actionValue == "string")) {
|
||||
this.wiki.setText(this.actionTiddler,this.actionField,this.actionIndex,this.actionValue,options);
|
||||
}
|
||||
$tw.utils.each(this.attributes,function(attribute,name) {
|
||||
if(name.charAt(0) !== "$") {
|
||||
self.wiki.setText(self.actionTiddler,name,undefined,attribute,options);
|
||||
if(this.actionTiddler) {
|
||||
options.suppressTimestamp = !this.actionTimestamp;
|
||||
if((typeof this.actionField == "string") || (typeof this.actionIndex == "string") || (typeof this.actionValue == "string")) {
|
||||
this.wiki.setText(this.actionTiddler,this.actionField,this.actionIndex,this.actionValue,options);
|
||||
}
|
||||
});
|
||||
$tw.utils.each(this.attributes,function(attribute,name) {
|
||||
if(name.charAt(0) !== "$") {
|
||||
self.wiki.setText(self.actionTiddler,name,undefined,attribute,options);
|
||||
}
|
||||
});
|
||||
}
|
||||
return true; // Action was invoked
|
||||
};
|
||||
|
||||
|
||||
@@ -46,7 +46,8 @@ ButtonWidget.prototype.render = function(parent,nextSibling) {
|
||||
isPoppedUp = (this.popup || this.popupTitle) && this.isPoppedUp();
|
||||
if(this.selectedClass) {
|
||||
if((this.set || this.setTitle) && this.setTo && this.isSelected()) {
|
||||
$tw.utils.pushTop(classes,this.selectedClass.split(" "));
|
||||
$tw.utils.pushTop(classes, this.selectedClass.split(" "));
|
||||
domNode.setAttribute("aria-checked", "true");
|
||||
}
|
||||
if(isPoppedUp) {
|
||||
$tw.utils.pushTop(classes,this.selectedClass.split(" "));
|
||||
@@ -66,6 +67,9 @@ ButtonWidget.prototype.render = function(parent,nextSibling) {
|
||||
if(this["aria-label"]) {
|
||||
domNode.setAttribute("aria-label",this["aria-label"]);
|
||||
}
|
||||
if (this.role) {
|
||||
domNode.setAttribute("role", this.role);
|
||||
}
|
||||
if(this.popup || this.popupTitle) {
|
||||
domNode.setAttribute("aria-expanded",isPoppedUp ? "true" : "false");
|
||||
}
|
||||
@@ -206,6 +210,7 @@ ButtonWidget.prototype.execute = function() {
|
||||
this.popup = this.getAttribute("popup");
|
||||
this.hover = this.getAttribute("hover");
|
||||
this["aria-label"] = this.getAttribute("aria-label");
|
||||
this.role = this.getAttribute("role");
|
||||
this.tooltip = this.getAttribute("tooltip");
|
||||
this.style = this.getAttribute("style");
|
||||
this["class"] = this.getAttribute("class","");
|
||||
@@ -247,7 +252,7 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
|
||||
*/
|
||||
ButtonWidget.prototype.refresh = function(changedTiddlers) {
|
||||
var changedAttributes = this.computeAttributes();
|
||||
if(changedAttributes.actions || changedAttributes.to || changedAttributes.message || changedAttributes.param || changedAttributes.set || changedAttributes.setTo || changedAttributes.popup || changedAttributes.hover || changedAttributes.selectedClass || changedAttributes.style || changedAttributes.dragFilter || changedAttributes.dragTiddler || (this.set && changedTiddlers[this.set]) || (this.popup && changedTiddlers[this.popup]) || (this.popupTitle && changedTiddlers[this.popupTitle]) || changedAttributes.setTitle || changedAttributes.setField || changedAttributes.setIndex || changedAttributes.popupTitle || changedAttributes.disabled) {
|
||||
if(changedAttributes.actions || changedAttributes.to || changedAttributes.message || changedAttributes.param || changedAttributes.set || changedAttributes.setTo || changedAttributes.popup || changedAttributes.hover || changedAttributes.selectedClass || changedAttributes.style || changedAttributes.dragFilter || changedAttributes.dragTiddler || (this.set && changedTiddlers[this.set]) || (this.popup && changedTiddlers[this.popup]) || (this.popupTitle && changedTiddlers[this.popupTitle]) || changedAttributes.setTitle || changedAttributes.setField || changedAttributes.setIndex || changedAttributes.popupTitle || changedAttributes.disabled || changedAttributes["default"]) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
} else if(changedAttributes["class"]) {
|
||||
|
||||
@@ -27,6 +27,7 @@ CheckboxWidget.prototype = new Widget();
|
||||
Render this widget into the DOM
|
||||
*/
|
||||
CheckboxWidget.prototype.render = function(parent,nextSibling) {
|
||||
var isChecked;
|
||||
// Save the parent dom node
|
||||
this.parentDomNode = parent;
|
||||
// Compute our attributes
|
||||
@@ -35,11 +36,16 @@ CheckboxWidget.prototype.render = function(parent,nextSibling) {
|
||||
this.execute();
|
||||
// Create our elements
|
||||
this.labelDomNode = this.document.createElement("label");
|
||||
this.labelDomNode.setAttribute("class",this.checkboxClass);
|
||||
this.labelDomNode.setAttribute("class","tc-checkbox " + this.checkboxClass);
|
||||
this.inputDomNode = this.document.createElement("input");
|
||||
this.inputDomNode.setAttribute("type","checkbox");
|
||||
if(this.getValue()) {
|
||||
isChecked = this.getValue();
|
||||
if(isChecked) {
|
||||
this.inputDomNode.setAttribute("checked","true");
|
||||
$tw.utils.addClass(this.labelDomNode,"tc-checkbox-checked");
|
||||
}
|
||||
if(isChecked === undefined && this.checkboxIndeterminate === "yes") {
|
||||
this.inputDomNode.indeterminate = true;
|
||||
}
|
||||
if(this.isDisabled === "yes") {
|
||||
this.inputDomNode.setAttribute("disabled",true);
|
||||
@@ -59,20 +65,25 @@ CheckboxWidget.prototype.render = function(parent,nextSibling) {
|
||||
|
||||
CheckboxWidget.prototype.getValue = function() {
|
||||
var tiddler = this.wiki.getTiddler(this.checkboxTitle);
|
||||
if(tiddler) {
|
||||
if(tiddler || this.checkboxFilter) {
|
||||
if(this.checkboxTag) {
|
||||
if(this.checkboxInvertTag) {
|
||||
if(this.checkboxInvertTag === "yes") {
|
||||
return !tiddler.hasTag(this.checkboxTag);
|
||||
} else {
|
||||
return tiddler.hasTag(this.checkboxTag);
|
||||
}
|
||||
}
|
||||
if(this.checkboxField) {
|
||||
if(this.checkboxField || this.checkboxIndex) {
|
||||
// Same logic applies to fields and indexes
|
||||
var value;
|
||||
if($tw.utils.hop(tiddler.fields,this.checkboxField)) {
|
||||
value = tiddler.fields[this.checkboxField] || "";
|
||||
if(this.checkboxField) {
|
||||
if($tw.utils.hop(tiddler.fields,this.checkboxField)) {
|
||||
value = tiddler.fields[this.checkboxField] || "";
|
||||
} else {
|
||||
value = this.checkboxDefault || "";
|
||||
}
|
||||
} else {
|
||||
value = this.checkboxDefault || "";
|
||||
value = this.wiki.extractTiddlerDataItem(tiddler,this.checkboxIndex,this.checkboxDefault || "");
|
||||
}
|
||||
if(value === this.checkboxChecked) {
|
||||
return true;
|
||||
@@ -80,15 +91,59 @@ CheckboxWidget.prototype.getValue = function() {
|
||||
if(value === this.checkboxUnchecked) {
|
||||
return false;
|
||||
}
|
||||
// Neither value found: were both specified?
|
||||
if(this.checkboxChecked && !this.checkboxUnchecked) {
|
||||
return false; // Absence of checked value
|
||||
}
|
||||
if(this.checkboxUnchecked && !this.checkboxChecked) {
|
||||
return true; // Absence of unchecked value
|
||||
}
|
||||
if(this.checkboxChecked && this.checkboxUnchecked) {
|
||||
// Both specified but neither found: indeterminate or false, depending
|
||||
if(this.checkboxIndeterminate === "yes") {
|
||||
return undefined;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(this.checkboxIndex) {
|
||||
var value = this.wiki.extractTiddlerDataItem(tiddler,this.checkboxIndex,this.checkboxDefault || "");
|
||||
if(value === this.checkboxChecked) {
|
||||
if(this.checkboxListField || this.checkboxListIndex || this.checkboxFilter) {
|
||||
// Same logic applies to lists and filters
|
||||
var list;
|
||||
if(this.checkboxListField) {
|
||||
if($tw.utils.hop(tiddler.fields,this.checkboxListField)) {
|
||||
list = tiddler.getFieldList(this.checkboxListField);
|
||||
} else {
|
||||
list = $tw.utils.parseStringArray(this.checkboxDefault || "") || [];
|
||||
}
|
||||
} else if (this.checkboxListIndex) {
|
||||
list = $tw.utils.parseStringArray(this.wiki.extractTiddlerDataItem(tiddler,this.checkboxListIndex,this.checkboxDefault || "")) || [];
|
||||
} else {
|
||||
list = this.wiki.filterTiddlers(this.checkboxFilter,this) || [];
|
||||
}
|
||||
if(list.indexOf(this.checkboxChecked) !== -1) {
|
||||
return true;
|
||||
}
|
||||
if(value === this.checkboxUnchecked) {
|
||||
if(list.indexOf(this.checkboxUnchecked) !== -1) {
|
||||
return false;
|
||||
}
|
||||
// Neither one present
|
||||
if(this.checkboxChecked && !this.checkboxUnchecked) {
|
||||
return false; // Absence of checked value
|
||||
}
|
||||
if(this.checkboxUnchecked && !this.checkboxChecked) {
|
||||
return true; // Absence of unchecked value
|
||||
}
|
||||
if(this.checkboxChecked && this.checkboxUnchecked) {
|
||||
// Both specified but neither found: indeterminate or false, depending
|
||||
if(this.checkboxIndeterminate === "yes") {
|
||||
return undefined;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Neither specified, so empty list is false, non-empty is true
|
||||
return !!list.length;
|
||||
}
|
||||
} else {
|
||||
if(this.checkboxTag) {
|
||||
@@ -114,7 +169,8 @@ CheckboxWidget.prototype.handleChangeEvent = function(event) {
|
||||
hasChanged = false,
|
||||
tagCheck = false,
|
||||
hasTag = tiddler && tiddler.hasTag(this.checkboxTag),
|
||||
value = checked ? this.checkboxChecked : this.checkboxUnchecked;
|
||||
value = checked ? this.checkboxChecked : this.checkboxUnchecked,
|
||||
notValue = checked ? this.checkboxUnchecked : this.checkboxChecked;
|
||||
if(this.checkboxTag && this.checkboxInvertTag === "yes") {
|
||||
tagCheck = hasTag === checked;
|
||||
} else {
|
||||
@@ -148,9 +204,51 @@ CheckboxWidget.prototype.handleChangeEvent = function(event) {
|
||||
hasChanged = true;
|
||||
}
|
||||
}
|
||||
// Set the list field (or index) if specified
|
||||
if(this.checkboxListField || this.checkboxListIndex) {
|
||||
var listContents, oldPos, newPos;
|
||||
if(this.checkboxListField) {
|
||||
listContents = tiddler.getFieldList(this.checkboxListField);
|
||||
} else {
|
||||
listContents = $tw.utils.parseStringArray(this.wiki.extractTiddlerDataItem(this.checkboxTitle,this.checkboxListIndex) || "") || [];
|
||||
}
|
||||
oldPos = notValue ? listContents.indexOf(notValue) : -1;
|
||||
newPos = value ? listContents.indexOf(value) : -1;
|
||||
if(oldPos === -1 && newPos !== -1) {
|
||||
// old value absent, new value present: no change needed
|
||||
} else if(oldPos === -1) {
|
||||
// neither one was present
|
||||
if(value) {
|
||||
listContents.push(value);
|
||||
hasChanged = true;
|
||||
} else {
|
||||
// value unspecified? then leave list unchanged
|
||||
}
|
||||
} else if(newPos === -1) {
|
||||
// old value present, new value absent
|
||||
if(value) {
|
||||
listContents[oldPos] = value;
|
||||
hasChanged = true;
|
||||
} else {
|
||||
listContents.splice(oldPos, 1)
|
||||
hasChanged = true;
|
||||
}
|
||||
} else {
|
||||
// both were present: just remove the old one, leave new alone
|
||||
listContents.splice(oldPos, 1)
|
||||
hasChanged = true;
|
||||
}
|
||||
if(this.checkboxListField) {
|
||||
newFields[this.checkboxListField] = $tw.utils.stringifyList(listContents);
|
||||
}
|
||||
// The listIndex case will be handled in the if(hasChanged) block below
|
||||
}
|
||||
if(hasChanged) {
|
||||
if(this.checkboxIndex) {
|
||||
this.wiki.setText(this.checkboxTitle,"",this.checkboxIndex,value);
|
||||
} else if(this.checkboxListIndex) {
|
||||
var listIndexValue = (listContents && listContents.length) ? $tw.utils.stringifyList(listContents) : undefined;
|
||||
this.wiki.setText(this.checkboxTitle,"",this.checkboxListIndex,listIndexValue);
|
||||
} else {
|
||||
this.wiki.addTiddler(new $tw.Tiddler(this.wiki.getCreationFields(),fallbackFields,tiddler,newFields,this.wiki.getModificationFields()));
|
||||
}
|
||||
@@ -179,9 +277,13 @@ CheckboxWidget.prototype.execute = function() {
|
||||
this.checkboxTag = this.getAttribute("tag");
|
||||
this.checkboxField = this.getAttribute("field");
|
||||
this.checkboxIndex = this.getAttribute("index");
|
||||
this.checkboxListField = this.getAttribute("listField");
|
||||
this.checkboxListIndex = this.getAttribute("listIndex");
|
||||
this.checkboxFilter = this.getAttribute("filter");
|
||||
this.checkboxChecked = this.getAttribute("checked");
|
||||
this.checkboxUnchecked = this.getAttribute("unchecked");
|
||||
this.checkboxDefault = this.getAttribute("default");
|
||||
this.checkboxIndeterminate = this.getAttribute("indeterminate","no");
|
||||
this.checkboxClass = this.getAttribute("class","");
|
||||
this.checkboxInvertTag = this.getAttribute("invertTag","");
|
||||
this.isDisabled = this.getAttribute("disabled","no");
|
||||
@@ -194,14 +296,21 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
|
||||
*/
|
||||
CheckboxWidget.prototype.refresh = function(changedTiddlers) {
|
||||
var changedAttributes = this.computeAttributes();
|
||||
if(changedAttributes.tiddler || changedAttributes.tag || changedAttributes.invertTag || changedAttributes.field || changedAttributes.index || changedAttributes.checked || changedAttributes.unchecked || changedAttributes["default"] || changedAttributes["class"] || changedAttributes.disabled) {
|
||||
if(changedAttributes.tiddler || changedAttributes.tag || changedAttributes.invertTag || changedAttributes.field || changedAttributes.index || changedAttributes.listField || changedAttributes.listIndex || changedAttributes.filter || changedAttributes.checked || changedAttributes.unchecked || changedAttributes["default"] || changedAttributes.indeterminate || changedAttributes["class"] || changedAttributes.disabled) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
} else {
|
||||
var refreshed = false;
|
||||
if(changedTiddlers[this.checkboxTitle]) {
|
||||
this.inputDomNode.checked = this.getValue();
|
||||
var isChecked = this.getValue();
|
||||
this.inputDomNode.checked = !!isChecked;
|
||||
this.inputDomNode.indeterminate = (isChecked === undefined);
|
||||
refreshed = true;
|
||||
if(isChecked) {
|
||||
$tw.utils.addClass(this.labelDomNode,"tc-checkbox-checked");
|
||||
} else {
|
||||
$tw.utils.removeClass(this.labelDomNode,"tc-checkbox-checked");
|
||||
}
|
||||
}
|
||||
return this.refreshChildren(changedTiddlers) || refreshed;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,10 @@ DraggableWidget.prototype = new Widget();
|
||||
Render this widget into the DOM
|
||||
*/
|
||||
DraggableWidget.prototype.render = function(parent,nextSibling) {
|
||||
var self = this;
|
||||
var self = this,
|
||||
tag,
|
||||
domNode,
|
||||
classes = [];
|
||||
// Save the parent dom node
|
||||
this.parentDomNode = parent;
|
||||
// Compute our attributes
|
||||
@@ -35,31 +38,36 @@ DraggableWidget.prototype.render = function(parent,nextSibling) {
|
||||
// Execute our logic
|
||||
this.execute();
|
||||
// Sanitise the specified tag
|
||||
var tag = this.draggableTag;
|
||||
tag = this.draggableTag;
|
||||
if($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {
|
||||
tag = "div";
|
||||
}
|
||||
// Create our element
|
||||
var domNode = this.document.createElement(tag);
|
||||
domNode = this.document.createElement(tag);
|
||||
// Assign classes
|
||||
var classes = ["tc-draggable"];
|
||||
if(this.draggableClasses) {
|
||||
classes.push(this.draggableClasses);
|
||||
}
|
||||
if(!this.dragHandleSelector && this.dragEnable) {
|
||||
classes.push("tc-draggable");
|
||||
}
|
||||
domNode.setAttribute("class",classes.join(" "));
|
||||
// Add event handlers
|
||||
$tw.utils.makeDraggable({
|
||||
domNode: domNode,
|
||||
dragTiddlerFn: function() {return self.getAttribute("tiddler");},
|
||||
dragFilterFn: function() {return self.getAttribute("filter");},
|
||||
startActions: self.startActions,
|
||||
endActions: self.endActions,
|
||||
dragImageType: self.dragImageType,
|
||||
widget: this
|
||||
});
|
||||
// Insert the link into the DOM and render any children
|
||||
// Insert the node into the DOM and render any children
|
||||
parent.insertBefore(domNode,nextSibling);
|
||||
this.renderChildren(domNode,null);
|
||||
// Add event handlers
|
||||
if(this.dragEnable) {
|
||||
$tw.utils.makeDraggable({
|
||||
domNode: domNode,
|
||||
dragTiddlerFn: function() {return self.getAttribute("tiddler");},
|
||||
dragFilterFn: function() {return self.getAttribute("filter");},
|
||||
startActions: self.startActions,
|
||||
endActions: self.endActions,
|
||||
dragImageType: self.dragImageType,
|
||||
widget: this,
|
||||
selector: self.dragHandleSelector
|
||||
});
|
||||
}
|
||||
this.domNodes.push(domNode);
|
||||
};
|
||||
|
||||
@@ -72,17 +80,39 @@ DraggableWidget.prototype.execute = function() {
|
||||
this.draggableClasses = this.getAttribute("class");
|
||||
this.startActions = this.getAttribute("startactions");
|
||||
this.endActions = this.getAttribute("endactions");
|
||||
this.dragImageType = this.getAttribute("dragimagetype");
|
||||
this.dragImageType = this.getAttribute("dragimagetype");
|
||||
this.dragHandleSelector = this.getAttribute("selector");
|
||||
this.dragEnable = this.getAttribute("enable","yes") === "yes";
|
||||
// Make the child widgets
|
||||
this.makeChildWidgets();
|
||||
};
|
||||
|
||||
|
||||
DraggableWidget.prototype.updateDomNodeClasses = function() {
|
||||
var domNodeClasses = this.domNodes[0].className.split(" "),
|
||||
oldClasses = this.draggableClasses.split(" ");
|
||||
this.draggableClasses = this.getAttribute("class");
|
||||
//Remove classes assigned from the old value of class attribute
|
||||
$tw.utils.each(oldClasses,function(oldClass){
|
||||
var i = domNodeClasses.indexOf(oldClass);
|
||||
if(i !== -1) {
|
||||
domNodeClasses.splice(i,1);
|
||||
}
|
||||
});
|
||||
//Add new classes from updated class attribute.
|
||||
$tw.utils.pushTop(domNodeClasses,this.draggableClasses);
|
||||
this.domNodes[0].setAttribute("class",domNodeClasses.join(" "))
|
||||
}
|
||||
|
||||
/*
|
||||
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
|
||||
*/
|
||||
DraggableWidget.prototype.refresh = function(changedTiddlers) {
|
||||
var changedAttributes = this.computeAttributes();
|
||||
if(changedAttributes.tag || changedAttributes["class"]) {
|
||||
var changedAttributes = this.computeAttributes(),
|
||||
changedAttributesCount = $tw.utils.count(changedAttributes);
|
||||
if(changedAttributesCount === 1 && changedAttributes["class"]) {
|
||||
this.updateDomNodeClasses();
|
||||
} else if(changedAttributesCount > 0) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
}
|
||||
@@ -91,4 +121,4 @@ DraggableWidget.prototype.refresh = function(changedTiddlers) {
|
||||
|
||||
exports.draggable = DraggableWidget;
|
||||
|
||||
})();
|
||||
})();
|
||||
@@ -42,16 +42,22 @@ ElementWidget.prototype.render = function(parent,nextSibling) {
|
||||
this.tag = "h" + headingLevel;
|
||||
}
|
||||
// Select the namespace for the tag
|
||||
var tagNamespaces = {
|
||||
var XHTML_NAMESPACE = "http://www.w3.org/1999/xhtml",
|
||||
tagNamespaces = {
|
||||
svg: "http://www.w3.org/2000/svg",
|
||||
math: "http://www.w3.org/1998/Math/MathML",
|
||||
body: "http://www.w3.org/1999/xhtml"
|
||||
body: XHTML_NAMESPACE
|
||||
};
|
||||
this.namespace = tagNamespaces[this.tag];
|
||||
if(this.namespace) {
|
||||
this.setVariable("namespace",this.namespace);
|
||||
} else {
|
||||
this.namespace = this.getVariable("namespace",{defaultValue: "http://www.w3.org/1999/xhtml"});
|
||||
if(this.hasAttribute("xmlns")) {
|
||||
this.namespace = this.getAttribute("xmlns");
|
||||
this.setVariable("namespace",this.namespace);
|
||||
} else {
|
||||
this.namespace = this.getVariable("namespace",{defaultValue: XHTML_NAMESPACE});
|
||||
}
|
||||
}
|
||||
// Invoke the th-rendering-element hook
|
||||
var parseTreeNodes = $tw.hooks.invokeHook("th-rendering-element",null,this);
|
||||
|
||||
@@ -46,6 +46,7 @@ EventWidget.prototype.render = function(parent,nextSibling) {
|
||||
$tw.utils.each(this.types,function(type) {
|
||||
domNode.addEventListener(type,function(event) {
|
||||
var selector = self.getAttribute("selector"),
|
||||
matchSelector = self.getAttribute("matchSelector"),
|
||||
actions = self.getAttribute("$"+type) || self.getAttribute("actions-"+type),
|
||||
stopPropagation = self.getAttribute("stopPropagation","onaction"),
|
||||
selectedNode = event.target,
|
||||
@@ -56,46 +57,23 @@ EventWidget.prototype.render = function(parent,nextSibling) {
|
||||
if(selectedNode.nodeType === 3) {
|
||||
selectedNode = selectedNode.parentNode;
|
||||
}
|
||||
// Check that the selected node matches any matchSelector
|
||||
if(matchSelector && !$tw.utils.domMatchesSelector(selectedNode,matchSelector)) {
|
||||
return false;
|
||||
}
|
||||
if(selector) {
|
||||
// Search ancestors for a node that matches the selector
|
||||
while(!$tw.utils.domMatchesSelector(selectedNode,selector) && selectedNode !== domNode) {
|
||||
selectedNode = selectedNode.parentNode;
|
||||
}
|
||||
// If we found one, copy the attributes as variables, otherwise exit
|
||||
if($tw.utils.domMatchesSelector(selectedNode,selector)) {
|
||||
// Only set up variables if we have actions to invoke
|
||||
if(actions) {
|
||||
$tw.utils.each(selectedNode.attributes,function(attribute) {
|
||||
variables["dom-" + attribute.name] = attribute.value.toString();
|
||||
});
|
||||
//Add a variable with a popup coordinate string for the selected node
|
||||
variables["tv-popup-coords"] = "(" + selectedNode.offsetLeft + "," + selectedNode.offsetTop +"," + selectedNode.offsetWidth + "," + selectedNode.offsetHeight + ")";
|
||||
|
||||
//Add variables for offset of selected node
|
||||
variables["tv-selectednode-posx"] = selectedNode.offsetLeft.toString();
|
||||
variables["tv-selectednode-posy"] = selectedNode.offsetTop.toString();
|
||||
variables["tv-selectednode-width"] = selectedNode.offsetWidth.toString();
|
||||
variables["tv-selectednode-height"] = selectedNode.offsetHeight.toString();
|
||||
|
||||
if(event.clientX && event.clientY) {
|
||||
//Add variables for event X and Y position relative to selected node
|
||||
selectedNodeRect = selectedNode.getBoundingClientRect();
|
||||
variables["event-fromselected-posx"] = (event.clientX - selectedNodeRect.left).toString();
|
||||
variables["event-fromselected-posy"] = (event.clientY - selectedNodeRect.top).toString();
|
||||
|
||||
//Add variables for event X and Y position relative to event catcher node
|
||||
catcherNodeRect = self.domNode.getBoundingClientRect();
|
||||
variables["event-fromcatcher-posx"] = (event.clientX - catcherNodeRect.left).toString();
|
||||
variables["event-fromcatcher-posy"] = (event.clientY - catcherNodeRect.top).toString();
|
||||
|
||||
//Add variables for event X and Y position relative to the viewport
|
||||
variables["event-fromviewport-posx"] = event.clientX.toString();
|
||||
variables["event-fromviewport-posy"] = event.clientY.toString();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Exit if we didn't find one
|
||||
if(selectedNode === domNode) {
|
||||
return false;
|
||||
}
|
||||
// Only set up variables if we have actions to invoke
|
||||
if(actions) {
|
||||
variables = $tw.utils.collectDOMVariables(selectedNode,self.domNode,event);
|
||||
}
|
||||
}
|
||||
// Execute our actions with the variables
|
||||
if(actions) {
|
||||
|
||||
@@ -111,6 +111,9 @@ ImageWidget.prototype.render = function(parent,nextSibling) {
|
||||
if(this.imageAlt) {
|
||||
domNode.setAttribute("alt",this.imageAlt);
|
||||
}
|
||||
if(this.lazyLoading && tag === "img") {
|
||||
domNode.setAttribute("loading",this.lazyLoading);
|
||||
}
|
||||
// Add classes when the image loads or fails
|
||||
$tw.utils.addClass(domNode,"tc-image-loading");
|
||||
domNode.addEventListener("load",function() {
|
||||
@@ -137,6 +140,7 @@ ImageWidget.prototype.execute = function() {
|
||||
this.imageClass = this.getAttribute("class");
|
||||
this.imageTooltip = this.getAttribute("tooltip");
|
||||
this.imageAlt = this.getAttribute("alt");
|
||||
this.lazyLoading = this.getAttribute("loading");
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -48,7 +48,7 @@ LetWidget.prototype.computeAttributes = function() {
|
||||
var changedAttributes = {},
|
||||
self = this;
|
||||
this.currentValueFor = Object.create(null);
|
||||
$tw.utils.each(this.parseTreeNode.orderedAttributes,function(attribute,index) {
|
||||
$tw.utils.each($tw.utils.getOrderedAttributesFromParseTreeNode(this.parseTreeNode),function(attribute) {
|
||||
var value = self.computeAttribute(attribute),
|
||||
name = attribute.name;
|
||||
if(name.charAt(0) !== "$") {
|
||||
|
||||
@@ -498,11 +498,7 @@ NavigatorWidget.prototype.handleNewTiddlerEvent = function(event) {
|
||||
// Import JSON tiddlers into a pending import tiddler
|
||||
NavigatorWidget.prototype.handleImportTiddlersEvent = function(event) {
|
||||
// Get the tiddlers
|
||||
var tiddlers = [];
|
||||
try {
|
||||
tiddlers = JSON.parse(event.param);
|
||||
} catch(e) {
|
||||
}
|
||||
var tiddlers = $tw.utils.parseJSONSafe(event.param,[]);
|
||||
// Get the current $:/Import tiddler
|
||||
var importTitle = event.importTitle ? event.importTitle : IMPORT_TITLE,
|
||||
importTiddler = this.wiki.getTiddler(importTitle),
|
||||
|
||||
@@ -159,6 +159,8 @@ ScrollableWidget.prototype.render = function(parent,nextSibling) {
|
||||
// Create elements
|
||||
this.outerDomNode = this.document.createElement("div");
|
||||
$tw.utils.setStyle(this.outerDomNode,[
|
||||
{overflowY: "auto"},
|
||||
{overflowX: "auto"},
|
||||
{webkitOverflowScrolling: "touch"}
|
||||
]);
|
||||
this.innerDomNode = this.document.createElement("div");
|
||||
|
||||
@@ -289,12 +289,19 @@ Widget.prototype.computeAttribute = function(attribute) {
|
||||
};
|
||||
|
||||
/*
|
||||
Check for the presence of an attribute
|
||||
Check for the presence of an evaluated attribute on the widget. Note that attributes set to a missing variable (ie attr=<<missing>>) will be treated as missing
|
||||
*/
|
||||
Widget.prototype.hasAttribute = function(name) {
|
||||
return $tw.utils.hop(this.attributes,name);
|
||||
};
|
||||
|
||||
/*
|
||||
Check for the presence of a raw attribute on the widget parse tree node. Note that attributes set to a missing variable (ie attr=<<missing>>) will NOT be treated as missing
|
||||
*/
|
||||
Widget.prototype.hasParseTreeNodeAttribute = function(name) {
|
||||
return $tw.utils.hop(this.parseTreeNode.attributes,name);
|
||||
};
|
||||
|
||||
/*
|
||||
Get the value of an attribute
|
||||
*/
|
||||
|
||||
@@ -50,7 +50,7 @@ exports.getTextReference = function(textRef,defaultText,currTiddlerTitle) {
|
||||
if(tr.field) {
|
||||
var tiddler = this.getTiddler(title);
|
||||
if(tr.field === "title") { // Special case so we can return the title of a non-existent tiddler
|
||||
return title;
|
||||
return title || defaultText;
|
||||
} else if(tiddler && $tw.utils.hop(tiddler.fields,tr.field)) {
|
||||
return tiddler.getFieldString(tr.field);
|
||||
} else {
|
||||
@@ -833,12 +833,7 @@ exports.getTiddlerData = function(titleOrTiddler,defaultData) {
|
||||
switch(tiddler.fields.type) {
|
||||
case "application/json":
|
||||
// JSON tiddler
|
||||
try {
|
||||
data = JSON.parse(tiddler.fields.text);
|
||||
} catch(ex) {
|
||||
return defaultData;
|
||||
}
|
||||
return data;
|
||||
return $tw.utils.parseJSONSafe(tiddler.fields.text,defaultData);
|
||||
case "application/x-tiddler-dictionary":
|
||||
return $tw.utils.parseFields(tiddler.fields.text);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ alert-highlight: #FFD60A
|
||||
alert-muted-foreground: <<colour muted-foreground>>
|
||||
background: #282828
|
||||
blockquote-bar: <<colour page-background>>
|
||||
button-foreground: <<colour background>>
|
||||
button-foreground: <<colour foreground>>
|
||||
code-background: <<colour pre-background>>
|
||||
code-border: <<colour pre-border>>
|
||||
code-foreground: rgba(255, 255, 255, 0.54)
|
||||
@@ -52,7 +52,7 @@ pre-border: transparent
|
||||
primary: #0A84FF
|
||||
select-tag-background: <<colour background>>
|
||||
select-tag-foreground: <<colour foreground>>
|
||||
sidebar-button-foreground: <<colour background>>
|
||||
sidebar-button-foreground: <<colour foreground>>
|
||||
sidebar-controls-foreground-hover: #FF9F0A
|
||||
sidebar-controls-foreground: #8E8E93
|
||||
sidebar-foreground-shadow: transparent
|
||||
@@ -87,7 +87,7 @@ tiddler-border: transparent
|
||||
tiddler-controls-foreground-hover: <<colour sidebar-controls-foreground-hover>>
|
||||
tiddler-controls-foreground-selected: <<colour sidebar-controls-foreground-hover>>
|
||||
tiddler-controls-foreground: #48484A
|
||||
tiddler-editor-background: transparent
|
||||
tiddler-editor-background: <<colour background>>
|
||||
tiddler-editor-border-image:
|
||||
tiddler-editor-border: rgba(255, 255, 255, 0.08)
|
||||
tiddler-editor-fields-even: rgba(255, 255, 255, 0.1)
|
||||
|
||||
@@ -12,7 +12,7 @@ alert-highlight: #d79921
|
||||
alert-muted-foreground: #504945
|
||||
background: #3c3836
|
||||
blockquote-bar: <<colour muted-foreground>>
|
||||
button-foreground: <<colour page-background>>
|
||||
button-foreground: <<colour foreground>>
|
||||
code-background: #504945
|
||||
code-border: #504945
|
||||
code-foreground: #fb4934
|
||||
@@ -63,7 +63,7 @@ select-tag-background: #665c54
|
||||
select-tag-foreground: <<colour foreground>>
|
||||
selection-background: #458588
|
||||
selection-foreground: <<colour foreground>>
|
||||
sidebar-button-foreground: <<colour page-background>>
|
||||
sidebar-button-foreground: <<colour foreground>>
|
||||
sidebar-controls-foreground-hover: #7c6f64
|
||||
sidebar-controls-foreground: #504945
|
||||
sidebar-foreground-shadow: transparent
|
||||
|
||||
@@ -12,7 +12,7 @@ alert-highlight: #B48EAD
|
||||
alert-muted-foreground: #4C566A
|
||||
background: #3b4252
|
||||
blockquote-bar: <<colour muted-foreground>>
|
||||
button-foreground: <<colour page-background>>
|
||||
button-foreground: <<colour foreground>>
|
||||
code-background: #2E3440
|
||||
code-border: #2E3440
|
||||
code-foreground: #BF616A
|
||||
@@ -63,7 +63,7 @@ select-tag-background: #3b4252
|
||||
select-tag-foreground: <<colour foreground>>
|
||||
selection-background: #5E81AC
|
||||
selection-foreground: <<colour foreground>>
|
||||
sidebar-button-foreground: <<colour page-background>>
|
||||
sidebar-button-foreground: <<colour foreground>>
|
||||
sidebar-controls-foreground-hover: #D8DEE9
|
||||
sidebar-controls-foreground: #4C566A
|
||||
sidebar-foreground-shadow: transparent
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
title: $:/core/save/lazy-all
|
||||
|
||||
\define saveTiddlerFilter()
|
||||
[is[system]] -[prefix[$:/state/popup/]] -[[$:/HistoryList]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]]
|
||||
[is[system]] -[prefix[$:/state/popup/]] -[[$:/HistoryList]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] [is[tiddler]type[application/javascript]] +[sort[title]]
|
||||
\end
|
||||
\define skinnySaveTiddlerFilter()
|
||||
[!is[system]]
|
||||
[!is[system]] -[type[application/javascript]]
|
||||
\end
|
||||
{{$:/core/templates/tiddlywiki5.html}}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
title: $:/core/templates/server/static.sidebar.wikitext
|
||||
|
||||
\whitespace trim
|
||||
<div class="tc-sidebar-scrollable" style="overflow: auto;">
|
||||
<div class="tc-sidebar-scrollable" style="overflow: auto;" role="region" aria-label={{$:/language/SideBar/Caption}}>
|
||||
<div class="tc-sidebar-header">
|
||||
<h1 class="tc-site-title">
|
||||
<$transclude tiddler="$:/SiteTitle"/>
|
||||
|
||||
@@ -19,8 +19,8 @@ title: $:/core/templates/server/static.tiddler.html
|
||||
</head>
|
||||
<body class="tc-body">
|
||||
<$transclude tiddler="$:/core/templates/server/static.sidebar.wikitext" mode="inline"/>
|
||||
<section class="tc-story-river">
|
||||
<div class="tc-tiddler-frame">
|
||||
<section class="tc-story-river" role="main">
|
||||
<div class="tc-tiddler-frame" role="article">
|
||||
<$transclude tiddler="$:/core/templates/server/static.tiddler.wikitext" mode="inline"/>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -6,6 +6,7 @@ description: create a new image tiddler
|
||||
image/$(imageType)$
|
||||
\end
|
||||
\define get-tags() $(textFieldTags)$ $(tagsFieldTags)$
|
||||
\whitespace trim
|
||||
<$vars imageType={{$:/config/NewImageType}} textFieldTags={{$:/config/NewJournal/Tags}} tagsFieldTags={{$:/config/NewJournal/Tags!!tags}}>
|
||||
<$action-sendmessage $message="tm-new-tiddler" type=<<get-type>> tags=<<get-tags>>/>
|
||||
</$vars>
|
||||
|
||||
@@ -3,8 +3,9 @@ tags: $:/tags/Actions
|
||||
description: create a new journal tiddler
|
||||
|
||||
\define get-tags() $(textFieldTags)$ $(tagsFieldTags)$
|
||||
\whitespace trim
|
||||
<$vars journalTitleTemplate={{$:/config/NewJournal/Title}} textFieldTags={{$:/config/NewJournal/Tags}} tagsFieldTags={{$:/config/NewJournal/Tags!!tags}} journalText={{$:/config/NewJournal/Text}}>
|
||||
<$wikify name="journalTitle" text="""<$macrocall $name="now" format=<<journalTitleTemplate>>/>""">
|
||||
<$wikify name="journalTitle" text="<$macrocall $name='now' format=<<journalTitleTemplate>>/>">
|
||||
<$reveal type="nomatch" state=<<journalTitle>> text="">
|
||||
<$action-sendmessage $message="tm-new-tiddler" title=<<journalTitle>> tags=<<get-tags>> text={{{ [<journalTitle>get[]] }}}/>
|
||||
</$reveal>
|
||||
|
||||
@@ -3,6 +3,7 @@ tags: $:/tags/Actions
|
||||
description: create a new empty tiddler
|
||||
|
||||
\define get-tags() $(textFieldTags)$ $(tagsFieldTags)$
|
||||
\whitespace trim
|
||||
<$vars textFieldTags={{$:/config/NewTiddler/Tags}} tagsFieldTags={{$:/config/NewTiddler/Tags!!tags}}>
|
||||
<$action-sendmessage $message="tm-new-tiddler" tags=<<get-tags>>/>
|
||||
</$vars>
|
||||
|
||||
@@ -2,6 +2,7 @@ title: $:/AdvancedSearch
|
||||
icon: $:/core/images/advanced-search-button
|
||||
color: #bbb
|
||||
|
||||
\whitespace trim
|
||||
<div class="tc-advanced-search">
|
||||
<$macrocall $name="tabs" tabsList="[all[shadows+tiddlers]tag[$:/tags/AdvancedSearch]!has[draft.of]]" default="$:/core/ui/AdvancedSearch/System" actions="""<$action-setfield $tiddler="$:/state/advancedsearch/currentTab" text=<<currentTab>>/>""" explicitState="$:/state/tab--1498284803"/>
|
||||
</div>
|
||||
|
||||
@@ -3,31 +3,71 @@ tags: $:/tags/AdvancedSearch
|
||||
caption: {{$:/language/Search/Filter/Caption}}
|
||||
|
||||
\define lingo-base() $:/language/Search/
|
||||
\define set-next-input-tab(beforeafter:"after") <$macrocall $name="change-input-tab" stateTitle="$:/state/tab--1498284803" tag="$:/tags/AdvancedSearch" beforeafter="$beforeafter$" defaultState="$:/core/ui/AdvancedSearch/System" actions="""<$action-setfield $tiddler="$:/state/advancedsearch/currentTab" text=<<nextTab>>/>"""/>
|
||||
\define set-next-input-tab(beforeafter:"after")
|
||||
<$macrocall $name="change-input-tab"
|
||||
stateTitle="$:/state/tab--1498284803"
|
||||
tag="$:/tags/AdvancedSearch"
|
||||
beforeafter="$beforeafter$"
|
||||
defaultState="$:/core/ui/AdvancedSearch/System"
|
||||
actions="<$action-setfield $tiddler='$:/state/advancedsearch/currentTab' text=<<nextTab>>/>"/>
|
||||
\end
|
||||
|
||||
\define cancel-search-actions() <$list filter="[{$:/temp/advancedsearch/input}!match{$:/temp/advancedsearch}]" emptyMessage="""<$action-deletetiddler $filter="[[$:/temp/advancedsearch]] [[$:/temp/advancedsearch/input]] [[$:/temp/advancedsearch/selected-item]]" />"""><$action-setfield $tiddler="$:/temp/advancedsearch/input" text={{$:/temp/advancedsearch}}/><$action-setfield $tiddler="$:/temp/advancedsearch/refresh" text="yes"/></$list>
|
||||
\define cancel-search-actions()
|
||||
\whitespace trim
|
||||
<$list
|
||||
filter="[{$:/temp/advancedsearch/input}!match{$:/temp/advancedsearch}]"
|
||||
emptyMessage="<$action-deletetiddler $filter='[[$:/temp/advancedsearch]] [[$:/temp/advancedsearch/input]] [[$:/temp/advancedsearch/selected-item]]' />">
|
||||
<$action-setfield $tiddler="$:/temp/advancedsearch/input" text={{$:/temp/advancedsearch}}/>
|
||||
<$action-setfield $tiddler="$:/temp/advancedsearch/refresh" text="yes"/>
|
||||
</$list>
|
||||
\end
|
||||
|
||||
\define input-accept-actions() <$list filter="[{$:/config/Search/NavigateOnEnter/enable}match[yes]]" emptyMessage="""<$list filter="[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]"><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>"""><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>
|
||||
\define input-accept-actions()
|
||||
\whitespace trim
|
||||
<$list
|
||||
filter="[{$:/config/Search/NavigateOnEnter/enable}match[yes]]"
|
||||
emptyMessage="<$list filter='[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]'><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>">
|
||||
<$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/>
|
||||
</$list>
|
||||
\end
|
||||
|
||||
\define input-accept-variant-actions() <$list filter="[{$:/config/Search/NavigateOnEnter/enable}match[yes]]" emptyMessage="""<$list filter="[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]"><$list filter="[<__tiddler__>get[text]minlength[1]]"><$action-sendmessage $message="tm-edit-tiddler" $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>"""><$list filter="[<__tiddler__>get[text]minlength[1]]"><$action-sendmessage $message="tm-edit-tiddler" $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>
|
||||
\define input-accept-variant-actions()
|
||||
\whitespace trim
|
||||
<$list
|
||||
filter="[{$:/config/Search/NavigateOnEnter/enable}match[yes]]"
|
||||
emptyMessage="<$list filter='[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]'><$list filter='[<__tiddler__>get[text]minlength[1]]'><$action-sendmessage $message='tm-edit-tiddler' $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>">
|
||||
<$list filter="[<__tiddler__>get[text]minlength[1]]">
|
||||
<$action-sendmessage $message="tm-edit-tiddler" $param={{{ [<__tiddler__>get[text]] }}}/>
|
||||
</$list></$list>
|
||||
\end
|
||||
|
||||
\whitespace trim
|
||||
<<lingo Filter/Hint>>
|
||||
|
||||
<div class="tc-search tc-advanced-search">
|
||||
<$keyboard key="((input-tab-right))" actions=<<set-next-input-tab>>>
|
||||
<$keyboard key="((input-tab-left))" actions=<<set-next-input-tab "before">>>
|
||||
<$macrocall $name="keyboard-driven-input" tiddler="$:/temp/advancedsearch/input" storeTitle="$:/temp/advancedsearch"
|
||||
refreshTitle="$:/temp/advancedsearch/refresh" selectionStateTitle="$:/temp/advancedsearch/selected-item" type="search"
|
||||
tag="input" focus={{$:/config/Search/AutoFocus}} configTiddlerFilter="[[$:/temp/advancedsearch]]" firstSearchFilterField="text"
|
||||
inputAcceptActions=<<input-accept-actions>> inputAcceptVariantActions=<<input-accept-variant-actions>>
|
||||
inputCancelActions=<<cancel-search-actions>>/>
|
||||
<$macrocall $name="keyboard-driven-input"
|
||||
tiddler="$:/temp/advancedsearch/input"
|
||||
storeTitle="$:/temp/advancedsearch"
|
||||
refreshTitle="$:/temp/advancedsearch/refresh"
|
||||
selectionStateTitle="$:/temp/advancedsearch/selected-item"
|
||||
type="search"
|
||||
tag="input"
|
||||
focus={{$:/config/Search/AutoFocus}}
|
||||
configTiddlerFilter="[[$:/temp/advancedsearch]]"
|
||||
firstSearchFilterField="text"
|
||||
inputAcceptActions=<<input-accept-actions>>
|
||||
inputAcceptVariantActions=<<input-accept-variant-actions>>
|
||||
inputCancelActions=<<cancel-search-actions>>/>
|
||||
</$keyboard>
|
||||
</$keyboard>
|
||||
 
|
||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/AdvancedSearch/FilterButton]!has[draft.of]]"><$transclude/></$list>
|
||||
</div>
|
||||
|
||||
<$reveal state="$:/temp/advancedsearch" type="nomatch" text="">
|
||||
<$set name="resultCount" value="""<$count filter={{$:/temp/advancedsearch}}/>""">
|
||||
<$set name="resultCount" value="<$count filter={{$:/temp/advancedsearch}}/>">
|
||||
<div class="tc-search-results">
|
||||
<<lingo Filter/Matches>>
|
||||
<$list filter={{$:/temp/advancedsearch}}>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
title: $:/core/ui/AdvancedSearch/Filter/FilterButtons/clear
|
||||
tags: $:/tags/AdvancedSearch/FilterButton
|
||||
|
||||
\whitespace trim
|
||||
<$reveal state="$:/temp/advancedsearch" type="nomatch" text="">
|
||||
<$button class="tc-btn-invisible">
|
||||
<<cancel-search-actions>>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
title: $:/core/ui/AdvancedSearch/Filter/FilterButtons/delete
|
||||
tags: $:/tags/AdvancedSearch/FilterButton
|
||||
|
||||
\whitespace trim
|
||||
<$reveal state="$:/temp/advancedsearch" type="nomatch" text="">
|
||||
<$button popup=<<qualify "$:/state/filterDeleteDropdown">> class="tc-btn-invisible">
|
||||
{{$:/core/images/delete-button}}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
title: $:/core/ui/AdvancedSearch/Filter/FilterButtons/dropdown
|
||||
tags: $:/tags/AdvancedSearch/FilterButton
|
||||
|
||||
\whitespace trim
|
||||
|
||||
<span class="tc-popup-keep">
|
||||
<$button popup=<<qualify "$:/state/filterDropdown">> class="tc-btn-invisible">
|
||||
{{$:/core/images/down-arrow}}
|
||||
@@ -9,10 +11,11 @@ tags: $:/tags/AdvancedSearch/FilterButton
|
||||
|
||||
<$reveal state=<<qualify "$:/state/filterDropdown">> type="popup" position="belowleft" animate="yes">
|
||||
<$set name="tv-show-missing-links" value="yes">
|
||||
<$linkcatcher actions="""<$action-setfield $tiddler="$:/temp/advancedsearch" text=<<navigateTo>>/><$action-setfield $tiddler="$:/temp/advancedsearch/input" text=<<navigateTo>>/><$action-setfield $tiddler="$:/temp/advancedsearch/refresh" text="yes"/><$action-sendmessage $message="tm-focus-selector" $param='.tc-advanced-search input' />""">
|
||||
<$linkcatcher actions="<$action-setfield $tiddler='$:/temp/advancedsearch' text=<<navigateTo>>/><$action-setfield $tiddler='$:/temp/advancedsearch/input' text=<<navigateTo>>/><$action-setfield $tiddler='$:/temp/advancedsearch/refresh' text='yes'/><$action-sendmessage $message='tm-focus-selector' $param='.tc-advanced-search input' />">
|
||||
<div class="tc-block-dropdown-wrapper">
|
||||
<div class="tc-block-dropdown tc-edit-type-dropdown">
|
||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Filter]]"><$link to={{!!filter}}><$transclude field="description"/></$link>
|
||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Filter]]">
|
||||
<$link to={{!!filter}}><$transclude field="description"/></$link>
|
||||
</$list>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
title: $:/core/ui/AdvancedSearch/Filter/FilterButtons/export
|
||||
tags: $:/tags/AdvancedSearch/FilterButton
|
||||
|
||||
\whitespace trim
|
||||
<$reveal state="$:/temp/advancedsearch" type="nomatch" text="">
|
||||
<$macrocall $name="exportButton" exportFilter={{$:/temp/advancedsearch}} lingoBase="$:/language/Buttons/ExportTiddlers/"/>
|
||||
</$reveal>
|
||||
|
||||
@@ -5,26 +5,68 @@ first-search-filter: [all[shadows]search<userInput>sort[title]limit[250]] -[[$:/
|
||||
|
||||
\define lingo-base() $:/language/Search/
|
||||
|
||||
\define set-next-input-tab(beforeafter:"after") <$macrocall $name="change-input-tab" stateTitle="$:/state/tab--1498284803" tag="$:/tags/AdvancedSearch" beforeafter="$beforeafter$" defaultState="$:/core/ui/AdvancedSearch/System" actions="""<$action-setfield $tiddler="$:/state/advancedsearch/currentTab" text=<<nextTab>>/>"""/>
|
||||
\define set-next-input-tab(beforeafter:"after")
|
||||
<$macrocall $name="change-input-tab"
|
||||
stateTitle="$:/state/tab--1498284803"
|
||||
tag="$:/tags/AdvancedSearch"
|
||||
beforeafter="$beforeafter$"
|
||||
defaultState="$:/core/ui/AdvancedSearch/System"
|
||||
actions="<$action-setfield $tiddler='$:/state/advancedsearch/currentTab' text=<<nextTab>>/>"/>
|
||||
\end
|
||||
|
||||
\define cancel-search-actions() <$list filter="[{$:/temp/advancedsearch}!match{$:/temp/advancedsearch/input}]" emptyMessage="""<$action-deletetiddler $filter="[[$:/temp/advancedsearch]] [[$:/temp/advancedsearch/input]] [[$:/temp/advancedsearch/selected-item]]" />"""><$action-setfield $tiddler="$:/temp/advancedsearch/input" text={{$:/temp/advancedsearch}}/><$action-setfield $tiddler="$:/temp/advancedsearch/refresh" text="yes"/></$list><$action-sendmessage $message="tm-focus-selector" $param=""".tc-advanced-search input"""/>
|
||||
\define cancel-search-actions()
|
||||
\whitespace trim
|
||||
<$list
|
||||
filter="[{$:/temp/advancedsearch}!match{$:/temp/advancedsearch/input}]"
|
||||
emptyMessage="<$action-deletetiddler $filter='[[$:/temp/advancedsearch]] [[$:/temp/advancedsearch/input]] [[$:/temp/advancedsearch/selected-item]]' />">
|
||||
<$action-setfield $tiddler="$:/temp/advancedsearch/input" text={{$:/temp/advancedsearch}}/>
|
||||
<$action-setfield $tiddler="$:/temp/advancedsearch/refresh" text="yes"/>
|
||||
</$list>
|
||||
<$action-sendmessage $message="tm-focus-selector" $param=".tc-advanced-search input"/>
|
||||
\end
|
||||
|
||||
\define input-accept-actions() <$list filter="[{$:/config/Search/NavigateOnEnter/enable}match[yes]]" emptyMessage="""<$list filter="[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]"><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>"""><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>
|
||||
\define input-accept-actions()
|
||||
\whitespace trim
|
||||
<$list
|
||||
filter="[{$:/config/Search/NavigateOnEnter/enable}match[yes]]"
|
||||
emptyMessage="<$list filter='[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]'><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>">
|
||||
<$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/>
|
||||
</$list>
|
||||
\end
|
||||
|
||||
\define input-accept-variant-actions() <$list filter="[{$:/config/Search/NavigateOnEnter/enable}match[yes]]" emptyMessage="""<$list filter="[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]"><$list filter="[<__tiddler__>get[text]minlength[1]]"><$action-sendmessage $message="tm-edit-tiddler" $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>"""><$list filter="[<__tiddler__>get[text]minlength[1]]"><$action-sendmessage $message="tm-edit-tiddler" $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>
|
||||
\define input-accept-variant-actions()
|
||||
\whitespace trim
|
||||
<$list
|
||||
filter="[{$:/config/Search/NavigateOnEnter/enable}match[yes]]"
|
||||
emptyMessage="<$list filter='[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]'><$list filter='[<__tiddler__>get[text]minlength[1]]'><$action-sendmessage $message='tm-edit-tiddler' $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>">
|
||||
<$list filter="[<__tiddler__>get[text]minlength[1]]">
|
||||
<$action-sendmessage $message="tm-edit-tiddler" $param={{{ [<__tiddler__>get[text]] }}}/>
|
||||
</$list></$list>
|
||||
\end
|
||||
|
||||
\whitespace trim
|
||||
|
||||
<<lingo Shadows/Hint>>
|
||||
|
||||
<div class="tc-search">
|
||||
<$keyboard key="((input-tab-right))" actions=<<set-next-input-tab>>>
|
||||
<$keyboard key="((input-tab-left))" actions=<<set-next-input-tab "before">>>
|
||||
<$macrocall $name="keyboard-driven-input" tiddler="$:/temp/advancedsearch/input" storeTitle="$:/temp/advancedsearch"
|
||||
refreshTitle="$:/temp/advancedsearch/refresh" selectionStateTitle="$:/temp/advancedsearch/selected-item" type="search"
|
||||
tag="input" focus={{$:/config/Search/AutoFocus}} configTiddlerFilter="[[$:/core/ui/AdvancedSearch/Shadows]]"
|
||||
inputCancelActions=<<cancel-search-actions>> inputAcceptActions=<<input-accept-actions>>
|
||||
inputAcceptVariantActions=<<input-accept-variant-actions>> filterMinLength={{$:/config/Search/MinLength}}/>
|
||||
<$macrocall $name="keyboard-driven-input"
|
||||
tiddler="$:/temp/advancedsearch/input"
|
||||
storeTitle="$:/temp/advancedsearch"
|
||||
refreshTitle="$:/temp/advancedsearch/refresh"
|
||||
selectionStateTitle="$:/temp/advancedsearch/selected-item"
|
||||
type="search"
|
||||
tag="input"
|
||||
focus={{$:/config/Search/AutoFocus}}
|
||||
configTiddlerFilter="[[$:/core/ui/AdvancedSearch/Shadows]]"
|
||||
inputCancelActions=<<cancel-search-actions>>
|
||||
inputAcceptActions=<<input-accept-actions>>
|
||||
inputAcceptVariantActions=<<input-accept-variant-actions>>
|
||||
filterMinLength={{$:/config/Search/MinLength}}/>
|
||||
</$keyboard>
|
||||
</$keyboard>
|
||||
 
|
||||
<$reveal state="$:/temp/advancedsearch" type="nomatch" text="">
|
||||
<$button class="tc-btn-invisible">
|
||||
<<cancel-search-actions>>
|
||||
@@ -35,9 +77,9 @@ first-search-filter: [all[shadows]search<userInput>sort[title]limit[250]] -[[$:/
|
||||
|
||||
<$reveal state="$:/temp/advancedsearch" type="nomatch" text="">
|
||||
|
||||
<$list filter="[{$:/temp/advancedsearch}minlength{$:/config/Search/MinLength}limit[1]]" emptyMessage="""<div class="tc-search-results">{{$:/language/Search/Search/TooShort}}</div>""" variable="listItem">
|
||||
<$list filter="[{$:/temp/advancedsearch}minlength{$:/config/Search/MinLength}limit[1]]" emptyMessage="<div class='tc-search-results'>{{$:/language/Search/Search/TooShort}}</div>" variable="listItem">
|
||||
|
||||
<$set name="resultCount" value="""<$count filter="[all[shadows]search{$:/temp/advancedsearch}] -[[$:/temp/advancedsearch]] -[[$:/temp/advancedsearch/input]]"/>""">
|
||||
<$set name="resultCount" value="<$count filter='[all[shadows]search{$:/temp/advancedsearch}] -[[$:/temp/advancedsearch]] -[[$:/temp/advancedsearch/input]]'/>">
|
||||
|
||||
<div class="tc-search-results">
|
||||
|
||||
|
||||
@@ -3,15 +3,17 @@ tags: $:/tags/AdvancedSearch
|
||||
caption: {{$:/language/Search/Standard/Caption}}
|
||||
|
||||
\define lingo-base() $:/language/Search/
|
||||
\define set-next-input-tab(beforeafter:"after") <$macrocall $name="change-input-tab" stateTitle="$:/state/tab--1498284803" tag="$:/tags/AdvancedSearch" beforeafter="$beforeafter$" defaultState="$:/core/ui/AdvancedSearch/System" actions="""<$action-setfield $tiddler="$:/state/advancedsearch/currentTab" text=<<nextTab>>/>"""/>
|
||||
\define set-next-input-tab(beforeafter:"after") <$macrocall $name="change-input-tab" stateTitle="$:/state/tab--1498284803" tag="$:/tags/AdvancedSearch" beforeafter="$beforeafter$" defaultState="$:/core/ui/AdvancedSearch/System" actions="<$action-setfield $tiddler='$:/state/advancedsearch/currentTab' text=<<nextTab>>/>"/>
|
||||
|
||||
\define next-search-tab(beforeafter:"after") <$macrocall $name="change-input-tab" stateTitle="$:/state/tab/search-results/advancedsearch" tag="$:/tags/SearchResults" beforeafter="$beforeafter$" defaultState={{$:/config/SearchResults/Default}} actions="""<$action-setfield $tiddler="$:/state/advancedsearch/standard/currentTab" text=<<nextTab>>/>"""/>
|
||||
\define next-search-tab(beforeafter:"after") <$macrocall $name="change-input-tab" stateTitle="$:/state/tab/search-results/advancedsearch" tag="$:/tags/SearchResults" beforeafter="$beforeafter$" defaultState={{$:/config/SearchResults/Default}} actions="<$action-setfield $tiddler='$:/state/advancedsearch/standard/currentTab' text=<<nextTab>>/>"/>
|
||||
|
||||
\define cancel-search-actions() <$list filter="[{$:/temp/advancedsearch}!match{$:/temp/advancedsearch/input}]" emptyMessage="""<$action-deletetiddler $filter="[[$:/temp/advancedsearch]] [[$:/temp/advancedsearch/input]] [[$:/temp/advancedsearch/selected-item]]" />"""><$action-setfield $tiddler="$:/temp/advancedsearch/input" text={{$:/temp/advancedsearch}}/><$action-setfield $tiddler="$:/temp/advancedsearch/refresh" text="yes"/></$list><$action-sendmessage $message="tm-focus-selector" $param=""".tc-advanced-search input"""/>
|
||||
\define cancel-search-actions() <$list filter="[{$:/temp/advancedsearch}!match{$:/temp/advancedsearch/input}]" emptyMessage="<$action-deletetiddler $filter='[[$:/temp/advancedsearch]] [[$:/temp/advancedsearch/input]] [[$:/temp/advancedsearch/selected-item]]' />"><$action-setfield $tiddler="$:/temp/advancedsearch/input" text={{$:/temp/advancedsearch}}/><$action-setfield $tiddler="$:/temp/advancedsearch/refresh" text="yes"/></$list><$action-sendmessage $message="tm-focus-selector" $param=".tc-advanced-search input"/>
|
||||
|
||||
\define input-accept-actions() <$list filter="[{$:/config/Search/NavigateOnEnter/enable}match[yes]]" emptyMessage="""<$list filter="[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]"><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>"""><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>
|
||||
\define input-accept-actions() <$list filter="[{$:/config/Search/NavigateOnEnter/enable}match[yes]]" emptyMessage="<$list filter='[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]'><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>"><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>
|
||||
|
||||
\define input-accept-variant-actions() <$list filter="[{$:/config/Search/NavigateOnEnter/enable}match[yes]]" emptyMessage="""<$list filter="[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]"><$list filter="[<__tiddler__>get[text]minlength[1]]"><$action-sendmessage $message="tm-edit-tiddler" $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>"""><$list filter="[<__tiddler__>get[text]minlength[1]]"><$action-sendmessage $message="tm-edit-tiddler" $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>
|
||||
\define input-accept-variant-actions() <$list filter="[{$:/config/Search/NavigateOnEnter/enable}match[yes]]" emptyMessage="<$list filter='[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]'><$list filter='[<__tiddler__>get[text]minlength[1]]'><$action-sendmessage $message='tm-edit-tiddler' $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>"><$list filter="[<__tiddler__>get[text]minlength[1]]"><$action-sendmessage $message="tm-edit-tiddler" $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>
|
||||
|
||||
\whitespace trim
|
||||
|
||||
<<lingo Standard/Hint>>
|
||||
|
||||
@@ -20,12 +22,19 @@ caption: {{$:/language/Search/Standard/Caption}}
|
||||
<$keyboard key="((input-tab-left))" actions=<<set-next-input-tab "before">>>
|
||||
<$keyboard key="shift-alt-Right" actions=<<next-search-tab>>>
|
||||
<$keyboard key="shift-alt-Left" actions=<<next-search-tab "before">>>
|
||||
<$macrocall $name="keyboard-driven-input" tiddler="$:/temp/advancedsearch/input" storeTitle="$:/temp/advancedsearch"
|
||||
refreshTitle="$:/temp/advancedsearch/refresh" selectionStateTitle="$:/temp/advancedsearch/selected-item" type="search"
|
||||
tag="input" focus={{$:/config/Search/AutoFocus}} inputCancelActions=<<cancel-search-actions>>
|
||||
inputAcceptActions=<<input-accept-actions>> inputAcceptVariantActions=<<input-accept-variant-actions>>
|
||||
configTiddlerFilter="[[$:/state/search/currentTab]!is[missing]get[text]] ~[{$:/config/SearchResults/Default}]"
|
||||
filterMinLength={{$:/config/Search/MinLength}}/>
|
||||
<$macrocall $name="keyboard-driven-input"
|
||||
tiddler="$:/temp/advancedsearch/input"
|
||||
storeTitle="$:/temp/advancedsearch"
|
||||
refreshTitle="$:/temp/advancedsearch/refresh"
|
||||
selectionStateTitle="$:/temp/advancedsearch/selected-item"
|
||||
type="search"
|
||||
tag="input"
|
||||
focus={{$:/config/Search/AutoFocus}}
|
||||
inputCancelActions=<<cancel-search-actions>>
|
||||
inputAcceptActions=<<input-accept-actions>>
|
||||
inputAcceptVariantActions=<<input-accept-variant-actions>>
|
||||
configTiddlerFilter="[[$:/state/search/currentTab]!is[missing]get[text]] ~[{$:/config/SearchResults/Default}]"
|
||||
filterMinLength={{$:/config/Search/MinLength}}/>
|
||||
</$keyboard>
|
||||
</$keyboard>
|
||||
</$keyboard>
|
||||
@@ -39,14 +48,22 @@ caption: {{$:/language/Search/Standard/Caption}}
|
||||
</div>
|
||||
|
||||
<$reveal state="$:/temp/advancedsearch" type="nomatch" text="">
|
||||
<$list filter="[{$:/temp/advancedsearch}minlength{$:/config/Search/MinLength}limit[1]]" emptyMessage="""<div class="tc-search-results">{{$:/language/Search/Search/TooShort}}</div>""" variable="listItem">
|
||||
<$vars userInput={{{ [[$:/temp/advancedsearch]get[text]] }}} configTiddler={{{ [[$:/state/search/currentTab]!is[missing]get[text]] ~[{$:/config/SearchResults/Default}] }}} searchListState="$:/temp/advancedsearch/selected-item">
|
||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]butfirst[]limit[1]]" emptyMessage="""
|
||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]]">
|
||||
<$transclude/>
|
||||
</$list>
|
||||
""">
|
||||
<$macrocall $name="tabs" tabsList="[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]]" default={{$:/config/SearchResults/Default}} actions="""<$action-setfield $tiddler="$:/state/advancedsearch/standard/currentTab" text=<<currentTab>>/>""" explicitState="$:/state/tab/search-results/advancedsearch" />
|
||||
<$list
|
||||
filter="[{$:/temp/advancedsearch}minlength{$:/config/Search/MinLength}limit[1]]"
|
||||
emptyMessage="<div class='tc-search-results'>{{$:/language/Search/Search/TooShort}}</div>"
|
||||
variable="listItem">
|
||||
<$vars
|
||||
userInput={{{ [[$:/temp/advancedsearch]get[text]] }}}
|
||||
configTiddler={{{ [[$:/state/search/currentTab]!is[missing]get[text]] ~[{$:/config/SearchResults/Default}] }}}
|
||||
searchListState="$:/temp/advancedsearch/selected-item">
|
||||
<$list
|
||||
filter="[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]butfirst[]limit[1]]"
|
||||
emptyMessage="<$list filter='[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]]'><$transclude/></$list>">
|
||||
<$macrocall $name="tabs"
|
||||
tabsList="[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]]"
|
||||
default={{$:/config/SearchResults/Default}}
|
||||
actions="<$action-setfield $tiddler='$:/state/advancedsearch/standard/currentTab' text=<<currentTab>>/>"
|
||||
explicitState="$:/state/tab/search-results/advancedsearch" />
|
||||
</$list>
|
||||
</$vars>
|
||||
</$list>
|
||||
|
||||
@@ -4,26 +4,68 @@ caption: {{$:/language/Search/System/Caption}}
|
||||
first-search-filter: [is[system]search<userInput>sort[title]limit[250]] -[[$:/temp/advancedsearch]] -[[$:/temp/advancedsearch/input]] -[[$:/temp/advancedsearch/selected-item]]
|
||||
|
||||
\define lingo-base() $:/language/Search/
|
||||
\define set-next-input-tab(beforeafter:"after",stateTitle,tag,defaultState,currentTabTiddler) <$macrocall $name="change-input-tab" stateTitle="$:/state/tab--1498284803" tag="$:/tags/AdvancedSearch" beforeafter="$beforeafter$" defaultState="$:/core/ui/AdvancedSearch/System" actions="""<$action-setfield $tiddler="$:/state/advancedsearch/currentTab" text=<<nextTab>>/>"""/>
|
||||
\define set-next-input-tab(beforeafter:"after",stateTitle,tag,defaultState,currentTabTiddler)
|
||||
<$macrocall $name="change-input-tab"
|
||||
stateTitle="$:/state/tab--1498284803"
|
||||
tag="$:/tags/AdvancedSearch"
|
||||
beforeafter="$beforeafter$"
|
||||
defaultState="$:/core/ui/AdvancedSearch/System"
|
||||
actions="<$action-setfield $tiddler='$:/state/advancedsearch/currentTab' text=<<nextTab>>/>"/>
|
||||
\end
|
||||
|
||||
\define cancel-search-actions() <$list filter="[{$:/temp/advancedsearch}!match{$:/temp/advancedsearch/input}]" emptyMessage="""<$action-deletetiddler $filter="[[$:/temp/advancedsearch]] [[$:/temp/advancedsearch/input]] [[$:/temp/advancedsearch/selected-item]]" />"""><$action-setfield $tiddler="$:/temp/advancedsearch/input" text={{$:/temp/advancedsearch}}/><$action-setfield $tiddler="$:/temp/advancedsearch/refresh" text="yes"/></$list><$action-sendmessage $message="tm-focus-selector" $param=""".tc-advanced-search input"""/>
|
||||
\define cancel-search-actions()
|
||||
\whitespace trim
|
||||
<$list
|
||||
filter="[{$:/temp/advancedsearch}!match{$:/temp/advancedsearch/input}]"
|
||||
emptyMessage="<$action-deletetiddler $filter='[[$:/temp/advancedsearch]] [[$:/temp/advancedsearch/input]] [[$:/temp/advancedsearch/selected-item]]' />">
|
||||
<$action-setfield $tiddler="$:/temp/advancedsearch/input" text={{$:/temp/advancedsearch}}/>
|
||||
<$action-setfield $tiddler="$:/temp/advancedsearch/refresh" text="yes"/>
|
||||
</$list>
|
||||
<$action-sendmessage $message="tm-focus-selector" $param=".tc-advanced-search input"/>
|
||||
\end
|
||||
|
||||
\define input-accept-actions() <$list filter="[{$:/config/Search/NavigateOnEnter/enable}match[yes]]" emptyMessage="""<$list filter="[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]"><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>"""><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>
|
||||
\define input-accept-actions()
|
||||
\whitespace trim
|
||||
<$list
|
||||
filter="[{$:/config/Search/NavigateOnEnter/enable}match[yes]]"
|
||||
emptyMessage="<$list filter='[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]'><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>">
|
||||
<$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/>
|
||||
</$list>
|
||||
\end
|
||||
|
||||
\define input-accept-variant-actions() <$list filter="[{$:/config/Search/NavigateOnEnter/enable}match[yes]]" emptyMessage="""<$list filter="[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]"><$list filter="[<__tiddler__>get[text]minlength[1]]"><$action-sendmessage $message="tm-edit-tiddler" $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>"""><$list filter="[<__tiddler__>get[text]minlength[1]]"><$action-sendmessage $message="tm-edit-tiddler" $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>
|
||||
\define input-accept-variant-actions()
|
||||
\whitespace trim
|
||||
<$list
|
||||
filter="[{$:/config/Search/NavigateOnEnter/enable}match[yes]]"
|
||||
emptyMessage="<$list filter='[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]'><$list filter='[<__tiddler__>get[text]minlength[1]]'><$action-sendmessage $message='tm-edit-tiddler' $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>">
|
||||
<$list filter="[<__tiddler__>get[text]minlength[1]]">
|
||||
<$action-sendmessage $message="tm-edit-tiddler" $param={{{ [<__tiddler__>get[text]] }}}/>
|
||||
</$list></$list>
|
||||
\end
|
||||
|
||||
\whitespace trim
|
||||
|
||||
<<lingo System/Hint>>
|
||||
|
||||
<div class="tc-search">
|
||||
<$keyboard key="((input-tab-right))" actions=<<set-next-input-tab>>>
|
||||
<$keyboard key="((input-tab-left))" actions=<<set-next-input-tab "before">>>
|
||||
<$macrocall $name="keyboard-driven-input" tiddler="$:/temp/advancedsearch/input" storeTitle="$:/temp/advancedsearch"
|
||||
refreshTitle="$:/temp/advancedsearch/refresh" selectionStateTitle="$:/temp/advancedsearch/selected-item"
|
||||
type="search" tag="input" focus={{$:/config/Search/AutoFocus}} configTiddlerFilter="[[$:/core/ui/AdvancedSearch/System]]"
|
||||
inputCancelActions=<<cancel-search-actions>> inputAcceptActions=<<input-accept-actions>>
|
||||
inputAcceptVariantActions=<<input-accept-variant-actions>> filterMinLength={{$:/config/Search/MinLength}}/>
|
||||
<$macrocall $name="keyboard-driven-input"
|
||||
tiddler="$:/temp/advancedsearch/input"
|
||||
storeTitle="$:/temp/advancedsearch"
|
||||
refreshTitle="$:/temp/advancedsearch/refresh"
|
||||
selectionStateTitle="$:/temp/advancedsearch/selected-item"
|
||||
type="search"
|
||||
tag="input"
|
||||
focus={{$:/config/Search/AutoFocus}}
|
||||
configTiddlerFilter="[[$:/core/ui/AdvancedSearch/System]]"
|
||||
inputCancelActions=<<cancel-search-actions>>
|
||||
inputAcceptActions=<<input-accept-actions>>
|
||||
inputAcceptVariantActions=<<input-accept-variant-actions>>
|
||||
filterMinLength={{$:/config/Search/MinLength}}/>
|
||||
</$keyboard>
|
||||
</$keyboard>
|
||||
 
|
||||
<$reveal state="$:/temp/advancedsearch" type="nomatch" text="">
|
||||
<$button class="tc-btn-invisible">
|
||||
<<cancel-search-actions>>
|
||||
@@ -34,9 +76,9 @@ first-search-filter: [is[system]search<userInput>sort[title]limit[250]] -[[$:/te
|
||||
|
||||
<$reveal state="$:/temp/advancedsearch" type="nomatch" text="">
|
||||
|
||||
<$list filter="[{$:/temp/advancedsearch}minlength{$:/config/Search/MinLength}limit[1]]" emptyMessage="""<div class="tc-search-results">{{$:/language/Search/Search/TooShort}}</div>""" variable="listItem">
|
||||
<$list filter="[{$:/temp/advancedsearch}minlength{$:/config/Search/MinLength}limit[1]]" emptyMessage="<div class='tc-search-results'>{{$:/language/Search/Search/TooShort}}</div>" variable="listItem">
|
||||
|
||||
<$set name="resultCount" value="""<$count filter="[is[system]search{$:/temp/advancedsearch}] -[[$:/temp/advancedsearch]] -[[$:/temp/advancedsearch/input]] -[[$:/temp/advancedsearch/selected-item]]"/>""">
|
||||
<$set name="resultCount" value="<$count filter='[is[system]search{$:/temp/advancedsearch}] -[[$:/temp/advancedsearch]] -[[$:/temp/advancedsearch/input]] -[[$:/temp/advancedsearch/selected-item]]'/>">
|
||||
|
||||
<div class="tc-search-results">
|
||||
|
||||
|
||||
@@ -1,12 +1,21 @@
|
||||
title: $:/core/ui/AlertTemplate
|
||||
|
||||
\whitespace trim
|
||||
<div class="tc-alert">
|
||||
<div class="tc-alert-toolbar">
|
||||
<$button class="tc-btn-invisible"><$action-deletetiddler $tiddler=<<currentTiddler>>/>{{$:/core/images/cancel-button}}</$button>
|
||||
</div>
|
||||
<div class="tc-alert-subtitle">
|
||||
<$wikify name="format" text=<<lingo Tiddler/DateFormat>>>
|
||||
<$view field="component"/> - <$view field="modified" format="date" template=<<format>>/> <$reveal type="nomatch" state="!!count" text=""><span class="tc-alert-highlight">({{$:/language/Count}}: <$view field="count"/>)</span></$reveal>
|
||||
<$view field="component"/>
|
||||
 - 
|
||||
<$view field="modified" format="date" template=<<format>>/>
|
||||
 
|
||||
<$reveal type="nomatch" state="!!count" text="">
|
||||
<span class="tc-alert-highlight">
|
||||
({{$:/language/Count}}: <$view field="count"/>)
|
||||
</span>
|
||||
</$reveal>
|
||||
</$wikify>
|
||||
</div>
|
||||
<div class="tc-alert-body">
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
title: $:/core/ui/Components/tag-link
|
||||
|
||||
\whitespace trim
|
||||
<$link>
|
||||
<$set name="backgroundColor" value={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}>
|
||||
<span style=<<tag-styles>> class="tc-tag-label">
|
||||
|
||||
@@ -2,6 +2,7 @@ title: $:/ControlPanel
|
||||
icon: $:/core/images/options-button
|
||||
color: #bbb
|
||||
|
||||
\whitespace trim
|
||||
<div class="tc-control-panel">
|
||||
<$macrocall $name="tabs" tabsList="[all[shadows+tiddlers]tag[$:/tags/ControlPanel]!has[draft.of]]" default="$:/core/ui/ControlPanel/Info" explicitState="$:/state/tab-1749438307"/>
|
||||
</div>
|
||||
|
||||
@@ -2,6 +2,7 @@ title: $:/core/ui/ControlPanel/Advanced
|
||||
tags: $:/tags/ControlPanel/Info
|
||||
caption: {{$:/language/ControlPanel/Advanced/Caption}}
|
||||
|
||||
\whitespace trim
|
||||
{{$:/language/ControlPanel/Advanced/Hint}}
|
||||
|
||||
<div class="tc-control-panel">
|
||||
|
||||
@@ -2,6 +2,7 @@ title: $:/core/ui/ControlPanel/Appearance
|
||||
tags: $:/tags/ControlPanel
|
||||
caption: {{$:/language/ControlPanel/Appearance/Caption}}
|
||||
|
||||
\whitespace trim
|
||||
{{$:/language/ControlPanel/Appearance/Hint}}
|
||||
|
||||
<div class="tc-control-panel">
|
||||
|
||||
@@ -5,6 +5,7 @@ caption: {{$:/language/ControlPanel/Basics/Caption}}
|
||||
\define lingo-base() $:/language/ControlPanel/Basics/
|
||||
|
||||
\define show-filter-count(filter)
|
||||
\whitespace trim
|
||||
<$button class="tc-btn-invisible">
|
||||
<$action-setfield $tiddler="$:/temp/advancedsearch" $value="""$filter$"""/>
|
||||
<$action-setfield $tiddler="$:/temp/advancedsearch/input" $value="""$filter$"""/>
|
||||
@@ -13,9 +14,11 @@ caption: {{$:/language/ControlPanel/Basics/Caption}}
|
||||
<$action-navigate $to="$:/AdvancedSearch"/>
|
||||
<$action-sendmessage $message="tm-focus-selector" $param=".tc-advanced-search input"/>
|
||||
''<$count filter="""$filter$"""/>''
|
||||
 
|
||||
{{$:/core/images/advanced-search-button}}
|
||||
</$button>
|
||||
\end
|
||||
\whitespace trim
|
||||
|
||||
|<<lingo Version/Prompt>> |''<<version>>'' |
|
||||
|<$link to="$:/SiteTitle"><<lingo Title/Prompt>></$link> |<$edit-text tiddler="$:/SiteTitle" default="" tag="input"/> |
|
||||
|
||||
@@ -2,6 +2,7 @@ title: $:/core/ui/ControlPanel/Cascades
|
||||
tags: $:/tags/ControlPanel/Advanced
|
||||
caption: {{$:/language/ControlPanel/Cascades/Caption}}
|
||||
|
||||
\whitespace trim
|
||||
{{$:/language/ControlPanel/Cascades/Hint}}
|
||||
|
||||
<div class="tc-control-panel">
|
||||
|
||||
9
core/ui/ControlPanel/Cascades/FieldEditor.tid
Normal file
9
core/ui/ControlPanel/Cascades/FieldEditor.tid
Normal file
@@ -0,0 +1,9 @@
|
||||
title: $:/core/ui/ControlPanel/FieldEditor
|
||||
tags: $:/tags/ControlPanel/Cascades
|
||||
caption: {{$:/language/ControlPanel/FieldEditor/Caption}}
|
||||
|
||||
\define lingo-base() $:/language/ControlPanel/FieldEditor/
|
||||
|
||||
<<lingo Hint>>
|
||||
|
||||
{{$:/tags/FieldEditorFilter||$:/snippets/ListTaggedCascade}}
|
||||
@@ -3,6 +3,7 @@ tags: $:/tags/ControlPanel/Advanced
|
||||
caption: {{$:/language/ControlPanel/EditorTypes/Caption}}
|
||||
|
||||
\define lingo-base() $:/language/ControlPanel/EditorTypes/
|
||||
\whitespace trim
|
||||
|
||||
<<lingo Hint>>
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ title: $:/core/ui/ControlPanel/Info
|
||||
tags: $:/tags/ControlPanel
|
||||
caption: {{$:/language/ControlPanel/Info/Caption}}
|
||||
|
||||
\whitespace trim
|
||||
{{$:/language/ControlPanel/Info/Hint}}
|
||||
|
||||
<div class="tc-control-panel">
|
||||
|
||||
@@ -5,8 +5,11 @@ caption: {{$:/language/ControlPanel/KeyboardShortcuts/Caption}}
|
||||
\define lingo-base() $:/language/ControlPanel/KeyboardShortcuts/
|
||||
|
||||
\define new-shortcut(title)
|
||||
\whitespace trim
|
||||
<div class="tc-dropdown-item-plain">
|
||||
<$edit-shortcut tiddler="$title$" placeholder={{$:/language/ControlPanel/KeyboardShortcuts/Add/Prompt}} focus="true" style="width:auto;"/> <$button>
|
||||
<$edit-shortcut tiddler="$title$" placeholder={{$:/language/ControlPanel/KeyboardShortcuts/Add/Prompt}} focus="true" style="width:auto;"/>
|
||||
 
|
||||
<$button>
|
||||
<<lingo Add/Caption>>
|
||||
<$action-listops
|
||||
$tiddler="$(shortcutTitle)$"
|
||||
@@ -21,6 +24,7 @@ caption: {{$:/language/ControlPanel/KeyboardShortcuts/Caption}}
|
||||
\end
|
||||
|
||||
\define shortcut-list-item(caption)
|
||||
\whitespace trim
|
||||
<td>
|
||||
</td>
|
||||
<td style="text-align:right;font-size:0.7em;">
|
||||
@@ -31,16 +35,16 @@ caption: {{$:/language/ControlPanel/KeyboardShortcuts/Caption}}
|
||||
<$button popup=<<qualify "$:/state/dropdown/$(shortcutTitle)$">> class="tc-btn-invisible">
|
||||
{{$:/core/images/edit-button}}
|
||||
</$button>
|
||||
 
|
||||
<$macrocall $name="displayshortcuts" $output="text/html" shortcuts={{$(shortcutTitle)$}} prefix="<kbd>" separator="</kbd> <kbd>" suffix="</kbd>"/>
|
||||
|
||||
<$reveal state=<<qualify "$:/state/dropdown/$(shortcutTitle)$">> type="popup" position="below" animate="yes">
|
||||
<div class="tc-block-dropdown-wrapper">
|
||||
<div class="tc-block-dropdown tc-edit-type-dropdown tc-popup-keep">
|
||||
<$list filter="[list[$(shortcutTitle)$!!text]sort[title]]" variable="shortcut" emptyMessage="""
|
||||
<div class="tc-dropdown-item-plain">
|
||||
//<<lingo NoShortcuts/Caption>>//
|
||||
</div>
|
||||
""">
|
||||
<$list
|
||||
filter="[list[$(shortcutTitle)$!!text]sort[title]]"
|
||||
variable="shortcut"
|
||||
emptyMessage="<div class='tc-dropdown-item-plain'>//<<lingo NoShortcuts/Caption>>//</div>">
|
||||
<div class="tc-dropdown-item-plain">
|
||||
<$button class="tc-btn-invisible" tooltip={{$:/language/ControlPanel/KeyboardShortcuts/Remove/Hint}}>
|
||||
<$action-listops
|
||||
@@ -50,6 +54,7 @@ caption: {{$:/language/ControlPanel/KeyboardShortcuts/Caption}}
|
||||
/>
|
||||
<small>{{$:/core/images/close-button}}</small>
|
||||
</$button>
|
||||
 
|
||||
<kbd>
|
||||
<$macrocall $name="displayshortcuts" $output="text/html" shortcuts=<<shortcut>>/>
|
||||
</kbd>
|
||||
@@ -65,6 +70,7 @@ caption: {{$:/language/ControlPanel/KeyboardShortcuts/Caption}}
|
||||
\end
|
||||
|
||||
\define shortcut-list(caption,prefix)
|
||||
\whitespace trim
|
||||
<tr>
|
||||
<$list filter="[[$prefix$$(shortcutName)$]]" variable="shortcutTitle">
|
||||
<<shortcut-list-item "$caption$">>
|
||||
@@ -73,7 +79,8 @@ caption: {{$:/language/ControlPanel/KeyboardShortcuts/Caption}}
|
||||
\end
|
||||
|
||||
\define shortcut-editor()
|
||||
<<shortcut-list "All" "$:/config/shortcuts/">>
|
||||
\whitespace trim
|
||||
<<shortcut-list "All" "$:/config/shortcuts/">>
|
||||
<<shortcut-list "Mac" "$:/config/shortcuts-mac/">>
|
||||
<<shortcut-list "NonMac" "$:/config/shortcuts-not-mac/">>
|
||||
<<shortcut-list "Linux" "$:/config/shortcuts-linux/">>
|
||||
@@ -87,6 +94,7 @@ caption: {{$:/language/ControlPanel/KeyboardShortcuts/Caption}}
|
||||
\end
|
||||
|
||||
\define shortcut-item-inner()
|
||||
\whitespace trim
|
||||
<tr>
|
||||
<td>
|
||||
<$reveal type="nomatch" state=<<dropdownStateTitle>> text="open">
|
||||
@@ -107,6 +115,7 @@ caption: {{$:/language/ControlPanel/KeyboardShortcuts/Caption}}
|
||||
{{$:/core/images/down-arrow}}
|
||||
</$button>
|
||||
</$reveal>
|
||||
 
|
||||
''<$text text=<<shortcutName>>/>''
|
||||
</td>
|
||||
<td>
|
||||
@@ -126,10 +135,12 @@ caption: {{$:/language/ControlPanel/KeyboardShortcuts/Caption}}
|
||||
\end
|
||||
|
||||
\define shortcut-item()
|
||||
\whitespace trim
|
||||
<$set name="dropdownStateTitle" value=<<qualify "$:/state/dropdown/keyboardshortcut/$(shortcutName)$">>>
|
||||
<<shortcut-item-inner>>
|
||||
</$set>
|
||||
\end
|
||||
\whitespace trim
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user