1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2026-02-13 21:49:50 +00:00

Compare commits

..

19 Commits

Author SHA1 Message Date
jeremy@jermolene.com
5f213567dd Add a cascade for dynamically choosing tiddler icons 2021-11-10 14:27:14 +00:00
jeremy@jermolene.com
a1ab220df6 Avoid unwanted whitespace 2021-11-10 10:42:25 +00:00
jeremy@jermolene.com
88d8057b38 Add a cascade for the view template title 2021-11-08 20:55:35 +00:00
jeremy@jermolene.com
a4e0cf31b0 Add a cascade for the editor template body 2021-11-08 17:52:36 +00:00
jeremy@jermolene.com
4bb12379eb Standardise "Story Tiddler Template" nomenclature 2021-11-08 17:50:06 +00:00
jeremy@jermolene.com
4697718e7b Tweak control panel wording 2021-11-08 09:29:05 +00:00
jeremy@jermolene.com
a624ed24e2 Add demo of custom story tiddler template 2021-11-06 14:48:30 +00:00
jeremy@jermolene.com
2059464276 Fix typo in previous commit 2021-11-05 17:59:53 +00:00
jeremy@jermolene.com
2a3a6dd558 Refer to $:/core/ui/{View|Edit}Template via their associated config tiddlers 2021-11-05 17:56:52 +00:00
jeremy@jermolene.com
e0b7dcded1 Refactor import listing and plugin listing as alternate body templates
As suggested by @pmario
2021-11-05 16:42:57 +00:00
jeremy@jermolene.com
478d90acec Add control panel UI for inspecting the template cascades 2021-11-05 14:45:02 +00:00
jeremy@jermolene.com
3aacf0fe72 Simplify cascade filter
Thanks @saqimtiaz
2021-11-05 14:44:26 +00:00
jeremy@jermolene.com
72c77f42da Use the cascade mechanism to choose between the edit and view templates 2021-11-05 09:20:46 +00:00
jeremy@jermolene.com
52907b98f9 Merge branch 'master' into cascade-filter-run-prefix 2021-11-05 08:29:08 +00:00
jeremy@jermolene.com
b1cb211f21 Use the cascade filter run prefix to choose the view template body template 2021-11-04 20:40:59 +00:00
jeremy@jermolene.com
ee32eb909f Add explicit test for empty result when no filter passes 2021-11-04 17:36:02 +00:00
jeremy@jermolene.com
b47a3ab585 Precompile the filters for performance 2021-11-04 16:43:06 +00:00
jeremy@jermolene.com
9e41d410ee Set currentTiddler and ..currentTiddler for filter evaulation 2021-11-04 16:20:37 +00:00
jeremy@jermolene.com
fc3a764199 Initial Commit 2021-11-04 15:51:13 +00:00
828 changed files with 2946 additions and 12707 deletions

View File

@@ -1,8 +1,15 @@
# Ignore "third party" code whose style we will not change.
# Known minified files
/boot/sjcl.js
/core/modules/utils/base64-utf8/base64-utf8.module.js
/core/modules/utils/base64-utf8/base64-utf8.module.min.js
/core/modules/utils/diff-match-patch/diff_match_patch.js
/core/modules/utils/diff-match-patch/diff_match_patch_uncompressed.js
/core/modules/utils/dom/csscolorparser.js
/plugins/tiddlywiki/*/files/
/plugins/tiddlywiki/async/files/async.min.v1.5.0.js
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/anyword-hint.js
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/css-hint.js
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/html-hint.js
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/javascript-hint.js
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/show-hint.js
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/xml-hint.js
/plugins/tiddlywiki/codemirror-closebrackets/files/addon/edit/closebrackets.js
/plugins/tiddlywiki/codemirror-closebrackets/files/addon/edit/matchbrackets.js
/plugins/tiddlywiki/codemirror-closetag/files/addon/edit/closetag.js
/plugins/tiddlywiki/codemirror-closetag/files/addon/fold/xml-fold.js

View File

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

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

@@ -0,0 +1,43 @@
---
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.

View File

@@ -1,67 +0,0 @@
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.

View File

@@ -1,8 +0,0 @@
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

View File

@@ -20,11 +20,3 @@ 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)

View File

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

View File

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

View File

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

View File

@@ -68,26 +68,6 @@ $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)
@@ -429,19 +409,6 @@ $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
@@ -1114,7 +1081,7 @@ $tw.Wiki = function(options) {
tiddlerTitles = null, // Array of tiddler titles
getTiddlerTitles = function() {
if(!tiddlerTitles) {
tiddlerTitles = Object.keys(tiddlers).sort(function(a,b) {return a.localeCompare(b);});
tiddlerTitles = Object.keys(tiddlers);
}
return tiddlerTitles;
},
@@ -1167,8 +1134,10 @@ $tw.Wiki = function(options) {
}
// Save the new tiddler
tiddlers[title] = tiddler;
// Check we've got the title
tiddlerTitles = $tw.utils.insertSortedArray(tiddlerTitles || [],title);
// Check we've got it's title
if(tiddlerTitles && tiddlerTitles.indexOf(title) === -1) {
tiddlerTitles.push(title);
}
// Record the new tiddler state
updateDescriptor["new"] = {
tiddler: tiddler,
@@ -1353,7 +1322,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] = $tw.utils.parseJSONSafe(tiddler.fields.text);
pluginInfo[tiddler.fields.title] = JSON.parse(tiddler.fields.text);
results.modifiedPlugins.push(tiddler.fields.title);
}
} else {
@@ -1486,7 +1455,7 @@ $tw.Wiki.prototype.defineTiddlerModules = function() {
}
break;
case "application/json":
$tw.modules.define(tiddler.fields.title,tiddler.fields["module-type"],$tw.utils.parseJSONSafe(tiddler.fields.text));
$tw.modules.define(tiddler.fields.title,tiddler.fields["module-type"],JSON.parse(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));
@@ -1675,7 +1644,12 @@ $tw.modules.define("$:/boot/tiddlerdeserializer/json","tiddlerdeserializer",{
}
return true;
},
data = $tw.utils.parseJSONSafe(text);
data = {};
try {
data = JSON.parse(text);
} catch(e) {
// Ignore JSON parse errors
}
if($tw.utils.isArray(data) && isTiddlerArrayValid(data)) {
return data;
} else if(isTiddlerValid(data)) {
@@ -1715,7 +1689,7 @@ $tw.boot.decryptEncryptedTiddlers = function(callback) {
$tw.crypto.setPassword(data.password);
var decryptedText = $tw.crypto.decrypt(encryptedText);
if(decryptedText) {
var json = $tw.utils.parseJSONSafe(decryptedText);
var json = JSON.parse(decryptedText);
for(var title in json) {
$tw.preloadTiddler(json[title]);
}
@@ -1915,7 +1889,7 @@ filepath: pathname of the directory containing the specification file
$tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
var tiddlers = [];
// Read the specification
var filesInfo = $tw.utils.parseJSONSafe(fs.readFileSync(filepath + path.sep + "tiddlywiki.files","utf8"));
var filesInfo = JSON.parse(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)],
@@ -2045,7 +2019,7 @@ $tw.loadPluginFolder = function(filepath,excludeRegExp) {
console.log("Warning: missing plugin.info file in " + filepath);
return null;
}
var pluginInfo = $tw.utils.parseJSONSafe(fs.readFileSync(infoPath,"utf8"));
var pluginInfo = JSON.parse(fs.readFileSync(infoPath,"utf8"));
// Read the plugin files
var pluginFiles = $tw.loadTiddlersFromPath(filepath,excludeRegExp);
// Save the plugin tiddlers into the plugin info
@@ -2162,7 +2136,7 @@ $tw.loadWikiTiddlers = function(wikiPath,options) {
pluginFields;
// Bail if we don't have a wiki info file
if(fs.existsSync(wikiInfoPath)) {
wikiInfo = $tw.utils.parseJSONSafe(fs.readFileSync(wikiInfoPath,"utf8"));
wikiInfo = JSON.parse(fs.readFileSync(wikiInfoPath,"utf8"));
} else {
return null;
}
@@ -2596,7 +2570,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(task.name) === -1)) {
if($tw.boot.doesTaskMatchPlatform(task) || (task.name && $tw.boot.disabledStartupModules.indexOf(name) !== -1)) {
return false;
}
}
@@ -2675,4 +2649,3 @@ if(typeof(exports) !== "undefined") {
} else {
_boot(window.$tw);
}
//# sourceURL=$:/boot/boot.js

View File

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

File diff suppressed because one or more lines are too long

View File

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

View File

@@ -36,8 +36,6 @@ 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
@@ -210,8 +208,6 @@ Theme/Caption: Theme
Theme/Prompt: Current theme:
TiddlerFields/Caption: Tiddler Fields
TiddlerFields/Hint: This is the full set of TiddlerFields in use in this wiki (including system tiddlers but excluding shadow tiddlers).
TiddlerColour/Caption: Tiddler Colour
TiddlerColour/Hint: This rules cascade is used to dynamically choose the colour for a tiddler (used for the icon and the associated tag pill).
TiddlerIcon/Caption: Tiddler Icon
TiddlerIcon/Hint: This rules cascade is used to dynamically choose the icon for a tiddler.
Toolbars/Caption: Toolbars
@@ -228,4 +224,4 @@ Tools/Download/Full/Caption: Download full wiki
ViewTemplateBody/Caption: View Template Body
ViewTemplateBody/Hint: This rule cascade is used by the default view template to dynamically choose the template for displaying the body of a tiddler.
ViewTemplateTitle/Caption: View Template Title
ViewTemplateTitle/Hint: This rule cascade is used by the default view template to dynamically choose the template for displaying the title of a tiddler.
ViewTemplateTitle/Hint: This rule cascade is used by the default view template to dynamically choose the template for displaying the title of a tiddler.

View File

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

View File

@@ -3,7 +3,6 @@ title: $:/language/Help/default
\define commandTitle()
$:/language/Help/$(command)$
\end
\whitespace trim
```
usage: tiddlywiki [<wikifolder>] [--<command> [<args>...]...]
```
@@ -12,9 +11,7 @@ Available commands:
<ul>
<$list filter="[commands[]sort[title]]" variable="command">
<li><$link to=<<commandTitle>>><$macrocall $name="command" $type="text/plain" $output="text/plain"/></$link>:
&#32;
<$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>

View File

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

View File

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

View File

@@ -8,60 +8,46 @@ 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";
/*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 + "\"");
}
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;
})();
$tw.utils.createFileDirectories(filepath);
fs.writeFileSync(filepath,tiddler.fields.text,contentTypeInfo.encoding);
});
return null;
};
exports.Command = Command;
})();

View File

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

View File

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

View File

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

View File

@@ -34,10 +34,8 @@ 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["color-scheme"] || "light";
this.iframeDoc.open();
this.iframeDoc.write("<meta name='color-scheme' content='" + colorScheme + "'>");
this.iframeDoc.write("");
this.iframeDoc.close();
// Style the iframe
this.iframeNode.className = this.dummyTextArea.className;

View File

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

View File

@@ -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($tw.utils.startsWith(line,event.paramObject.character)) {
line = line.substring(event.paramObject.character.length);
while(line.charAt(0) === event.paramObject.character) {
line = line.substring(1);
count++;
}
// Remove any whitespace

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,167 +0,0 @@
/*\
title: $:/core/modules/filters/json-ops.js
type: application/javascript
module-type: filteroperator
Filter operators for JSON operations
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
exports["jsonget"] = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
var data = options.wiki.getTiddlerDataCached(title);
if(data) {
var item = getDataItemValueAsStrings(data,operator.operands);
if(item !== undefined) {
results.push.apply(results,item);
}
}
});
return results;
};
exports["jsonindexes"] = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
var data = options.wiki.getTiddlerDataCached(title);
if(data) {
var item = getDataItemKeysAsStrings(data,operator.operands);
if(item !== undefined) {
results.push.apply(results,item);
}
}
});
return results;
};
exports["jsontype"] = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
var data = options.wiki.getTiddlerDataCached(title);
if(data) {
var item = getDataItemType(data,operator.operands);
if(item !== undefined) {
results.push(item);
}
}
});
return results;
};
/*
Given a JSON data structure and an array of index strings, return an array of the string representation of the values at the end of the index chain, or "undefined" if any of the index strings are invalid
*/
function getDataItemValueAsStrings(data,indexes) {
// Get the item
var item = getDataItem(data,indexes);
// Return the item as a string
return convertDataItemValueToStrings(item);
}
/*
Given a JSON data structure and an array of index strings, return an array of the string representation of the keys of the item at the end of the index chain, or "undefined" if any of the index strings are invalid
*/
function getDataItemKeysAsStrings(data,indexes) {
// Get the item
var item = getDataItem(data,indexes);
// Return the item keys as a string
return convertDataItemKeysToStrings(item);
}
/*
Return an array of the string representation of the values of a data item, or "undefined" if the item is undefined
*/
function convertDataItemValueToStrings(item) {
// Return the item as a string
if(item === undefined) {
return item;
}
if(typeof item === "object") {
if(item === null) {
return ["null"];
}
var results = [];
if($tw.utils.isArray(item)) {
$tw.utils.each(item,function(value) {
results.push.apply(results,convertDataItemValueToStrings(value));
});
return results;
} else {
$tw.utils.each(Object.keys(item).sort(),function(key) {
results.push.apply(results,convertDataItemValueToStrings(item[key]));
});
return results;
}
}
return [item.toString()];
}
/*
Return an array of the string representation of the keys of a data item, or "undefined" if the item is undefined
*/
function convertDataItemKeysToStrings(item) {
// Return the item as a string
if(item === undefined) {
return item;
} else if(typeof item === "object") {
if(item === null) {
return [];
}
var results = [];
if($tw.utils.isArray(item)) {
for(var i=0; i<item.length; i++) {
results.push(i.toString());
}
return results;
} else {
$tw.utils.each(Object.keys(item).sort(),function(key) {
results.push(key);
});
return results;
}
}
return [];
}
function getDataItemType(data,indexes) {
// Get the item
var item = getDataItem(data,indexes);
// Return the item type
if(item === undefined) {
return item;
} else if(item === null) {
return "null";
} else if($tw.utils.isArray(item)) {
return "array";
} else if(typeof item === "object") {
return "object";
} else {
return typeof item;
}
}
/*
Given a JSON data structure and an array of index strings, return the value at the end of the index chain, or "undefined" if any of the index strings are invalid
*/
function getDataItem(data,indexes) {
if(indexes.length === 0 || (indexes.length === 1 && indexes[0] === "")) {
return data;
}
// Get the item
var item = data;
for(var i=0; i<indexes.length; i++) {
if(item !== undefined) {
item = item[indexes[i]];
}
}
return item;
}
})();

View File

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

View File

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

View File

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

View File

@@ -16,22 +16,12 @@ 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 = [],
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));
}
});
}
var results = [];
source(function(tiddler,title) {
if(title.substr(0,operator.operand.length) === operator.operand) {
results.push(title.substr(operator.operand.length));
}
});
return results;
};

View File

@@ -16,26 +16,12 @@ 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 = [],
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));
}
});
}
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));
}
});
return results;
};

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -61,7 +61,7 @@ GiteaSaver.prototype.save = function(text,method,callback) {
}
var use_put = true;
if(xhr.status !== 404) {
getResponseData = $tw.utils.parseJSONSafe(getResponseDataJson);
getResponseData = JSON.parse(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 = $tw.utils.parseJSONSafe(putResponseDataJson);
var putResponseData = JSON.parse(putResponseDataJson);
callback(null);
}
});

View File

@@ -61,7 +61,7 @@ GitHubSaver.prototype.save = function(text,method,callback) {
return callback(err);
}
if(xhr.status !== 404) {
getResponseData = $tw.utils.parseJSONSafe(getResponseDataJson);
getResponseData = JSON.parse(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 = $tw.utils.parseJSONSafe(putResponseDataJson);
var putResponseData = JSON.parse(putResponseDataJson);
callback(null);
}
});

View File

@@ -58,7 +58,7 @@ GitLabSaver.prototype.save = function(text,method,callback) {
}
var requestType = "POST";
if(xhr.status !== 404) {
getResponseData = $tw.utils.parseJSONSafe(getResponseDataJson);
getResponseData = JSON.parse(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 = $tw.utils.parseJSONSafe(putResponseDataJson);
var putResponseData = JSON.parse(putResponseDataJson);
callback(null);
}
});

View File

@@ -80,7 +80,6 @@ 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",
@@ -88,20 +87,17 @@ PutSaver.prototype.save = function(text,method,callback) {
data: text,
callback: function(err,data,xhr) {
if(err) {
var status = xhr.status,
errorMsg = err;
// response is textual: "XMLHttpRequest error code: 412"
var status = Number(err.substring(err.indexOf(':') + 2, err.length))
if(status === 412) { // file changed on server
errorMsg = $tw.language.getString("Error/PutEditConflict");
callback($tw.language.getString("Error/PutEditConflict"));
} else if(status === 401) { // authentication required
errorMsg = $tw.language.getString("Error/PutUnauthorized");
callback($tw.language.getString("Error/PutUnauthorized"));
} else if(status === 403) { // permission denied
errorMsg = $tw.language.getString("Error/PutForbidden");
callback($tw.language.getString("Error/PutForbidden"));
} else {
callback(err); // fail
}
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) {

View File

@@ -64,7 +64,6 @@ 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);
@@ -82,6 +81,7 @@ 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;
};

View File

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

View File

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

View File

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

View File

@@ -42,17 +42,12 @@ 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.styleWidgetNode.assignedStyles;
$tw.styleElement.innerHTML = $tw.styleContainer.textContent;
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)) {
var newStyles = $tw.styleContainer.textContent;
if(newStyles !== $tw.styleWidgetNode.assignedStyles) {
$tw.styleWidgetNode.assignedStyles = newStyles;
$tw.styleElement.innerHTML = $tw.styleWidgetNode.assignedStyles;
}
$tw.styleElement.innerHTML = $tw.styleContainer.textContent;
}
}));
// Display the $:/core/ui/PageTemplate tiddler to kick off the display

View File

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

View File

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

View File

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

View File

@@ -41,7 +41,7 @@ exports.upgrade = function(wiki,titles,tiddlers) {
// Check if we're dealing with a plugin
if(incomingTiddler && incomingTiddler["plugin-type"]) {
// Check whether the plugin contains JS modules
var requiresReload = wiki.doesPluginInfoRequireReload($tw.utils.parseJSONSafe(incomingTiddler.text)) ? (wiki.getTiddlerText("$:/language/ControlPanel/Plugins/PluginWillRequireReload") + " ") : "";
var requiresReload = wiki.doesPluginInfoRequireReload(JSON.parse(incomingTiddler.text)) ? (wiki.getTiddlerText("$:/language/ControlPanel/Plugins/PluginWillRequireReload") + " ") : "";
messages[title] = requiresReload;
if(incomingTiddler.version) {
// Upgrade the incoming plugin if it is in the upgrade library

View File

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

View File

@@ -281,56 +281,5 @@ 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;
};
})();

View File

@@ -16,23 +16,21 @@ 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 context for the filter
widget: widget to use as the contect for the filter
*/
exports.makeDraggable = function(options) {
var dragImageType = options.dragImageType || "dom",
dragImage,
domNode = options.domNode,
dragHandle = options.selector && domNode.querySelector(options.selector) || domNode;
domNode = options.domNode;
// Make the dom node draggable (not necessary for anchor tags)
if((domNode.tagName || "").toLowerCase() !== "a") {
dragHandle.setAttribute("draggable","true");
domNode.setAttribute("draggable","true");
}
// Add event handlers
$tw.utils.addEventListeners(dragHandle,[
$tw.utils.addEventListeners(domNode,[
{name: "dragstart", handlerFunction: function(event) {
if(event.dataTransfer === undefined) {
return false;
@@ -41,26 +39,20 @@ exports.makeDraggable = function(options) {
var dragTiddler = options.dragTiddlerFn && options.dragTiddlerFn(),
dragFilter = options.dragFilterFn && options.dragFilterFn(),
titles = dragTiddler ? [dragTiddler] : [],
startActions = options.startActions,
variables,
domNodeRect;
startActions = options.startActions;
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 === dragHandle) {
if(titles.length > 0 && 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");
// Invoke drag-start actions if given
if(startActions !== undefined) {
// 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);
options.widget.invokeActionString(startActions,options.widget,event,{actionTiddler: titleString});
}
// Create the drag image elements
dragImage = options.widget.document.createElement("div");
@@ -120,8 +112,7 @@ exports.makeDraggable = function(options) {
var dragTiddler = options.dragTiddlerFn && options.dragTiddlerFn(),
dragFilter = options.dragFilterFn && options.dragFilterFn(),
titles = dragTiddler ? [dragTiddler] : [],
endActions = options.endActions,
variables;
endActions = options.endActions;
if(dragFilter) {
titles.push.apply(titles,options.widget.wiki.filterTiddlers(dragFilter,options.widget));
}
@@ -129,10 +120,7 @@ exports.makeDraggable = function(options) {
$tw.dragInProgress = null;
// Invoke drag-end actions if given
if(endActions !== undefined) {
variables = $tw.utils.collectDOMVariables(domNode,null,event);
variables.modifier = $tw.keyboardManager.getEventModifierKeyDescriptor(event);
variables["actionTiddler"] = titleString;
options.widget.invokeActionString(endActions,options.widget,event,variables);
options.widget.invokeActionString(endActions,options.widget,event,{actionTiddler: titleString});
}
// Remove the dragging class on the element being dragged
$tw.utils.removeClass(event.target,"tc-dragging");
@@ -210,7 +198,7 @@ var importDataTypes = [
];
function parseJSONTiddlers(json,fallbackTitle) {
var data = $tw.utils.parseJSONSafe(json);
var data = JSON.parse(json);
if(!$tw.utils.isArray(data)) {
data = [data];
}
@@ -220,10 +208,10 @@ function parseJSONTiddlers(json,fallbackTitle) {
return data;
};
function dragEventContainsType(event,targetType) {
exports.dragEventContainsFiles = function(event) {
if(event.dataTransfer.types) {
for(var i=0; i<event.dataTransfer.types.length; i++) {
if(event.dataTransfer.types[i] === targetType) {
if(event.dataTransfer.types[i] === "Files") {
return true;
break;
}
@@ -232,10 +220,4 @@ function dragEventContainsType(event,targetType) {
return false;
};
exports.dragEventContainsFiles = function(event) {
return (dragEventContainsType(event,"Files") && !dragEventContainsType(event,"text/plain"));
};
exports.dragEventContainsType = dragEventContainsType;
})();

View File

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

View File

@@ -30,7 +30,11 @@ 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 = $tw.utils.parseJSONSafe(fs.readFileSync(path.resolve(editionPath,entry,"tiddlywiki.info"),"utf8"),null);
var info;
try {
info = JSON.parse(fs.readFileSync(path.resolve(editionPath,entry,"tiddlywiki.info"),"utf8"));
} catch(ex) {
}
if(info) {
editionInfo[entry] = info;
}

View File

@@ -13,26 +13,8 @@ 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] = 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);
});
}
node.attributes[name] = {type: "string", value: value};
};
exports.getAttributeValueFromParseTreeNode = function(node,name,defaultValue) {
@@ -43,45 +25,26 @@ exports.getAttributeValueFromParseTreeNode = function(node,name,defaultValue) {
};
exports.addClassToParseTreeNode = function(node,classString) {
var classes = [],
attribute;
var classes = [];
node.attributes = node.attributes || {};
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(" ");
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(" ");
}
if(classString !== "") {
$tw.utils.pushTop(classes,classString.split(" "));
}
attribute.value = classes.join(" ");
node.attributes["class"].value = classes.join(" ");
}
};
exports.addStyleToParseTreeNode = function(node,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);
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 + ";";
}
}
if(attribute.type === "string") {
attribute.value += name + ":" + value + ";";
}
};
exports.findParseTreeNode = function(nodeArray,search) {

View File

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

View File

@@ -95,20 +95,6 @@ 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
@@ -462,7 +448,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(date || new Date());
return $tw.utils.stringifyDate(new Date());
var offset = date.getTimezoneOffset() ; // in minutes
date = new Date(date.getTime()+offset*60*1000) ;
t = t.substr(5) ;

View File

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

View File

@@ -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.hasParseTreeNodeAttribute("$tiddler") && this.getVariable("currentTiddler"));
this.actionTiddler = this.getAttribute("$tiddler",this.getVariable("currentTiddler"));
this.actionField = this.getAttribute("$field");
this.actionIndex = this.getAttribute("$index");
this.actionValue = this.getAttribute("$value");
@@ -46,7 +46,11 @@ SetFieldWidget.prototype.execute = function() {
Refresh the widget by ensuring our attributes are up to date
*/
SetFieldWidget.prototype.refresh = function(changedTiddlers) {
// Nothing to refresh
var changedAttributes = this.computeAttributes();
if(changedAttributes["$tiddler"] || changedAttributes["$field"] || changedAttributes["$index"] || changedAttributes["$value"]) {
this.refreshSelf();
return true;
}
return this.refreshChildren(changedTiddlers);
};
@@ -56,17 +60,15 @@ Invoke the action associated with this widget
SetFieldWidget.prototype.invokeAction = function(triggeringWidget,event) {
var self = this,
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);
}
});
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
};

View File

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

View File

@@ -27,7 +27,6 @@ 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
@@ -36,16 +35,11 @@ CheckboxWidget.prototype.render = function(parent,nextSibling) {
this.execute();
// Create our elements
this.labelDomNode = this.document.createElement("label");
this.labelDomNode.setAttribute("class","tc-checkbox " + this.checkboxClass);
this.labelDomNode.setAttribute("class",this.checkboxClass);
this.inputDomNode = this.document.createElement("input");
this.inputDomNode.setAttribute("type","checkbox");
isChecked = this.getValue();
if(isChecked) {
if(this.getValue()) {
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);
@@ -65,25 +59,20 @@ CheckboxWidget.prototype.render = function(parent,nextSibling) {
CheckboxWidget.prototype.getValue = function() {
var tiddler = this.wiki.getTiddler(this.checkboxTitle);
if(tiddler || this.checkboxFilter) {
if(tiddler) {
if(this.checkboxTag) {
if(this.checkboxInvertTag === "yes") {
if(this.checkboxInvertTag) {
return !tiddler.hasTag(this.checkboxTag);
} else {
return tiddler.hasTag(this.checkboxTag);
}
}
if(this.checkboxField || this.checkboxIndex) {
// Same logic applies to fields and indexes
if(this.checkboxField) {
var value;
if(this.checkboxField) {
if($tw.utils.hop(tiddler.fields,this.checkboxField)) {
value = tiddler.fields[this.checkboxField] || "";
} else {
value = this.checkboxDefault || "";
}
if($tw.utils.hop(tiddler.fields,this.checkboxField)) {
value = tiddler.fields[this.checkboxField] || "";
} else {
value = this.wiki.extractTiddlerDataItem(tiddler,this.checkboxIndex,this.checkboxDefault || "");
value = this.checkboxDefault || "";
}
if(value === this.checkboxChecked) {
return true;
@@ -91,59 +80,15 @@ 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.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) {
if(this.checkboxIndex) {
var value = this.wiki.extractTiddlerDataItem(tiddler,this.checkboxIndex,this.checkboxDefault || "");
if(value === this.checkboxChecked) {
return true;
}
if(list.indexOf(this.checkboxUnchecked) !== -1) {
if(value === this.checkboxUnchecked) {
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) {
@@ -169,8 +114,7 @@ CheckboxWidget.prototype.handleChangeEvent = function(event) {
hasChanged = false,
tagCheck = false,
hasTag = tiddler && tiddler.hasTag(this.checkboxTag),
value = checked ? this.checkboxChecked : this.checkboxUnchecked,
notValue = checked ? this.checkboxUnchecked : this.checkboxChecked;
value = checked ? this.checkboxChecked : this.checkboxUnchecked;
if(this.checkboxTag && this.checkboxInvertTag === "yes") {
tagCheck = hasTag === checked;
} else {
@@ -204,51 +148,9 @@ 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()));
}
@@ -277,13 +179,9 @@ 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");
@@ -296,21 +194,14 @@ 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.listField || changedAttributes.listIndex || changedAttributes.filter || changedAttributes.checked || changedAttributes.unchecked || changedAttributes["default"] || changedAttributes.indeterminate || changedAttributes["class"] || changedAttributes.disabled) {
if(changedAttributes.tiddler || changedAttributes.tag || changedAttributes.invertTag || changedAttributes.field || changedAttributes.index || changedAttributes.checked || changedAttributes.unchecked || changedAttributes["default"] || changedAttributes["class"] || changedAttributes.disabled) {
this.refreshSelf();
return true;
} else {
var refreshed = false;
if(changedTiddlers[this.checkboxTitle]) {
var isChecked = this.getValue();
this.inputDomNode.checked = !!isChecked;
this.inputDomNode.indeterminate = (isChecked === undefined);
this.inputDomNode.checked = this.getValue();
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;
}

View File

@@ -27,10 +27,7 @@ DraggableWidget.prototype = new Widget();
Render this widget into the DOM
*/
DraggableWidget.prototype.render = function(parent,nextSibling) {
var self = this,
tag,
domNode,
classes = [];
var self = this;
// Save the parent dom node
this.parentDomNode = parent;
// Compute our attributes
@@ -38,36 +35,31 @@ DraggableWidget.prototype.render = function(parent,nextSibling) {
// Execute our logic
this.execute();
// Sanitise the specified tag
tag = this.draggableTag;
var tag = this.draggableTag;
if($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {
tag = "div";
}
// Create our element
domNode = this.document.createElement(tag);
var 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(" "));
// Insert the node into the DOM and render any children
// 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
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);
};
@@ -80,9 +72,7 @@ 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.dragHandleSelector = this.getAttribute("selector");
this.dragEnable = this.getAttribute("enable","yes") === "yes";
this.dragImageType = this.getAttribute("dragimagetype");
// Make the child widgets
this.makeChildWidgets();
};
@@ -92,7 +82,7 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
*/
DraggableWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if($tw.utils.count(changedAttributes) > 0) {
if(changedAttributes.tag || changedAttributes["class"]) {
this.refreshSelf();
return true;
}

View File

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

View File

@@ -46,7 +46,6 @@ 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,
@@ -57,23 +56,46 @@ 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;
}
// Exit if we didn't find one
if(selectedNode === domNode) {
// 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 {
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) {

View File

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

View File

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

View File

@@ -48,7 +48,7 @@ LetWidget.prototype.computeAttributes = function() {
var changedAttributes = {},
self = this;
this.currentValueFor = Object.create(null);
$tw.utils.each($tw.utils.getOrderedAttributesFromParseTreeNode(this.parseTreeNode),function(attribute) {
$tw.utils.each(this.parseTreeNode.orderedAttributes,function(attribute,index) {
var value = self.computeAttribute(attribute),
name = attribute.name;
if(name.charAt(0) !== "$") {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -11,7 +11,7 @@ alert-highlight: #FFD60A
alert-muted-foreground: <<colour muted-foreground>>
background: #282828
blockquote-bar: <<colour page-background>>
button-foreground: <<colour foreground>>
button-foreground: <<colour background>>
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 foreground>>
sidebar-button-foreground: <<colour background>>
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: <<colour background>>
tiddler-editor-background: transparent
tiddler-editor-border-image:
tiddler-editor-border: rgba(255, 255, 255, 0.08)
tiddler-editor-fields-even: rgba(255, 255, 255, 0.1)

View File

@@ -12,7 +12,7 @@ alert-highlight: #d79921
alert-muted-foreground: #504945
background: #3c3836
blockquote-bar: <<colour muted-foreground>>
button-foreground: <<colour foreground>>
button-foreground: <<colour page-background>>
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 foreground>>
sidebar-button-foreground: <<colour page-background>>
sidebar-controls-foreground-hover: #7c6f64
sidebar-controls-foreground: #504945
sidebar-foreground-shadow: transparent

View File

@@ -12,7 +12,7 @@ alert-highlight: #B48EAD
alert-muted-foreground: #4C566A
background: #3b4252
blockquote-bar: <<colour muted-foreground>>
button-foreground: <<colour foreground>>
button-foreground: <<colour page-background>>
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 foreground>>
sidebar-button-foreground: <<colour page-background>>
sidebar-controls-foreground-hover: #D8DEE9
sidebar-controls-foreground: #4C566A
sidebar-foreground-shadow: transparent

View File

@@ -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]] [is[tiddler]type[application/javascript]] +[sort[title]]
[is[system]] -[prefix[$:/state/popup/]] -[[$:/HistoryList]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]]
\end
\define skinnySaveTiddlerFilter()
[!is[system]] -[type[application/javascript]]
[!is[system]]
\end
{{$:/core/templates/tiddlywiki5.html}}

View File

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

View File

@@ -6,7 +6,6 @@ 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>

View File

@@ -3,9 +3,8 @@ 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>

View File

@@ -3,7 +3,6 @@ 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>

View File

@@ -2,7 +2,6 @@ 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>

View File

@@ -3,71 +3,31 @@ 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>>/>"/>
\end
\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 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 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 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-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()
\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
\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 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>
&#32;
<$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}}>

View File

@@ -1,7 +1,6 @@
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>>

View File

@@ -1,7 +1,6 @@
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}}

View File

@@ -1,8 +1,6 @@
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}}
@@ -11,11 +9,10 @@ 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>

View File

@@ -1,7 +1,6 @@
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>

View File

@@ -5,68 +5,26 @@ 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>>/>"/>
\end
\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 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 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()
\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-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()
\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
\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>
<<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>
&#32;
<$reveal state="$:/temp/advancedsearch" type="nomatch" text="">
<$button class="tc-btn-invisible">
<<cancel-search-actions>>
@@ -77,9 +35,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">

View File

@@ -3,17 +3,15 @@ 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>
\whitespace trim
\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>
<<lingo Standard/Hint>>
@@ -22,19 +20,12 @@ 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>
@@ -48,22 +39,14 @@ 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>

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