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

Compare commits

..

33 Commits

Author SHA1 Message Date
Jeremy Ruston
9d9b00bdb5 Merge branch 'master' into single-tiddler-mode 2020-04-02 11:45:01 +01:00
Jeremy Ruston
b88bfda0b4 Merge branch 'master' into single-tiddler-mode 2020-01-20 13:15:39 +00:00
Jeremy Ruston
834610cdb9 Restore single tiddler mode handling for zoomin
Thus avoiding the problem that performance slows after browsing many tiddlers in zoomin mode.
2020-01-20 08:34:18 +00:00
Jeremy Ruston
5272b13af1 Revert zoomin to old behaviour
Otherwise we break the animations
2020-01-18 10:36:33 +00:00
Jeremy Ruston
5f25b21c0d Introduce new "solo" storyview
It's a single tiddler view with no animation, hopefully more suitable for things like @kookma's presentation plugin.
2020-01-18 10:36:10 +00:00
Jeremy Ruston
f256b7791d Merge branch 'master' into single-tiddler-mode 2020-01-17 13:06:07 +00:00
Jeremy Ruston
66fc63ed7f Revert "Merge branch 'master' into single-tiddler-mode"
This reverts commit f703330962.
2020-01-17 13:01:39 +00:00
Jeremy Ruston
f703330962 Merge branch 'master' into single-tiddler-mode 2020-01-17 12:54:51 +00:00
Jermolene
0ea4bfe99f Merge branch 'master' into single-tiddler-mode 2018-10-04 20:40:42 +01:00
Jermolene
7f99b8c32e Merge branch 'master' into single-tiddler-mode 2018-10-02 14:19:22 +01:00
Jermolene
95111db7ee Merge branch 'master' into single-tiddler-mode 2018-09-28 18:32:07 +01:00
Jermolene
5e148c1d26 Merge branch 'master' into single-tiddler-mode 2018-09-27 11:51:56 +01:00
Jermolene
1ff40c6b22 Merge branch 'master' into single-tiddler-mode 2018-09-27 10:12:09 +01:00
Jermolene
a0084eee9a Merge branch 'master' into single-tiddler-mode 2018-09-27 09:48:12 +01:00
Jermolene
55740fbfaf Merge branch 'master' into single-tiddler-mode 2018-09-21 10:56:43 +01:00
Jermolene
226a635c5c Merge branch 'master' into single-tiddler-mode 2018-09-13 20:42:52 +01:00
Jermolene
a5dca25078 Merge branch 'master' into single-tiddler-mode 2018-09-05 09:27:52 +01:00
Jermolene
a15a711d4a Merge branch 'master' into single-tiddler-mode 2018-09-01 13:19:40 +01:00
Jermolene
9bc8cbfe98 Refactor getstoryviewsingletiddlermode operator into getstoryviewmode
Thanks @pmario
2018-08-31 13:00:30 +01:00
Jermolene
f8b81616fb Merge branch 'master' into single-tiddler-mode 2018-08-31 09:59:46 +01:00
Jermolene
b7611e23b4 Improve prerelease notes 2018-08-30 14:06:31 +01:00
Jermolene
eacbb928e9 Merge branch 'master' into single-tiddler-mode 2018-08-30 14:00:59 +01:00
Jermolene
04d6677949 Temporarily default to Zoomin view, and make the switcher more accessible 2018-08-30 12:39:36 +01:00
Jermolene
ee25af758e Make "Open" tab mutate into "History" tab when in STM
Instead of introducing a new "History" tab to the sidebar we make the existing "Open" tab mutate into a "History" tab when in Single Tiddler Mode.
2018-08-30 12:38:13 +01:00
Jermolene
33aa37f7dc Merge branch 'master' into single-tiddler-mode 2018-08-29 19:03:50 +01:00
Jermolene
0d40b691e7 Make "close tiddler" button in STM go back to the previous tiddler in the history stack 2018-08-27 18:12:54 +01:00
Jermolene
81fda40486 Make single tiddler mode status available in tv-storyview-single-tiddler-mode 2018-08-27 12:19:28 +01:00
Jermolene
7a50edb56d Refactor navigator attribute handling
And fix a bug whereby we weren't refreshing when some attributes changed
2018-08-26 23:57:17 +01:00
Jermolene
f76e3f5d41 Update release note 2018-08-26 17:04:42 +01:00
Jermolene
9f2ce65a71 Merge branch 'master' into single-tiddler-mode 2018-08-26 16:49:17 +01:00
Jermolene
9a77ec4591 Docs update 2018-08-26 15:43:40 +01:00
Jermolene
8625d6cd01 Add "History" sidebar tab
Much more useful than the "open" tab when in single tiddler mode
2018-08-26 15:43:32 +01:00
Jermolene
aba835fb74 Basics of single tiddler mode
* Storyviews expose a static "singleTiddlerMode" property to determine if they require single tiddler mode
* Navigator widget adds a "singleTiddlerMode" attribute; when set to "yes", the story list is entirely replaced during navigation
* Navigator widget now updates "list" field of $:/HistoryList with a more accessible version of the history list
* Add a getstoryviewsingletiddlermode[] operator so that we can obtain the story view STM status for passing to the navigator widget
2018-08-26 15:43:06 +01:00
550 changed files with 1792 additions and 7854 deletions

View File

@@ -1,15 +0,0 @@
# Known minified files
/boot/sjcl.js
/core/modules/utils/base64-utf8/base64-utf8.module.min.js
/core/modules/utils/diff-match-patch/diff_match_patch.js
/plugins/tiddlywiki/async/files/async.min.v1.5.0.js
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/anyword-hint.js
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/css-hint.js
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/html-hint.js
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/javascript-hint.js
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/show-hint.js
/plugins/tiddlywiki/codemirror-autocomplete/files/addon/hint/xml-hint.js
/plugins/tiddlywiki/codemirror-closebrackets/files/addon/edit/closebrackets.js
/plugins/tiddlywiki/codemirror-closebrackets/files/addon/edit/matchbrackets.js
/plugins/tiddlywiki/codemirror-closetag/files/addon/edit/closetag.js
/plugins/tiddlywiki/codemirror-closetag/files/addon/fold/xml-fold.js

View File

@@ -1,267 +0,0 @@
env:
browser: true
commonjs: true
es2021: true
node: true
extends: 'eslint:recommended'
globals:
"$tw": "writable" # temporary
parserOptions:
ecmaVersion: 5
rules:
array-bracket-newline: 'off'
array-bracket-spacing: 'off'
array-callback-return: 'off'
array-element-newline: 'off'
arrow-body-style: error
arrow-parens:
- error
- as-needed
arrow-spacing:
- error
- after: true
before: true
block-scoped-var: 'off'
block-spacing: 'off'
brace-style: 'off'
callback-return: 'off'
camelcase: 'off'
capitalized-comments: 'off'
class-methods-use-this: error
comma-dangle: 'off'
comma-spacing: 'off'
comma-style: 'off'
complexity: 'off'
computed-property-spacing: 'off'
consistent-return: 'off'
consistent-this: 'off'
curly: 'off'
default-case: 'off'
default-case-last: error
default-param-last: error
dot-location: 'off'
dot-notation: 'off'
eol-last: 'off'
eqeqeq: 'off'
func-call-spacing: 'off'
func-name-matching: 'off'
func-names: 'off'
func-style: 'off'
function-call-argument-newline: 'off'
function-paren-newline: 'off'
generator-star-spacing: error
global-require: 'off'
grouped-accessor-pairs: error
guard-for-in: 'off'
handle-callback-err: 'off'
id-blacklist: error
id-denylist: error
id-length: 'off'
id-match: error
implicit-arrow-linebreak: error
indent: 'off'
indent-legacy: 'off'
init-declarations: 'off'
jsx-quotes: error
key-spacing: 'off'
keyword-spacing: 'off'
line-comment-position: 'off'
linebreak-style: 'off'
lines-around-comment: 'off'
lines-around-directive: 'off'
lines-between-class-members: error
max-classes-per-file: error
max-depth: 'off'
max-len: 'off'
max-lines: 'off'
max-lines-per-function: 'off'
max-nested-callbacks: error
max-params: 'off'
max-statements: 'off'
max-statements-per-line: 'off'
multiline-comment-style: 'off'
multiline-ternary: 'off'
new-parens: 'off'
newline-after-var: 'off'
newline-before-return: 'off'
newline-per-chained-call: 'off'
no-alert: 'off'
no-array-constructor: 'off'
no-await-in-loop: error
no-bitwise: 'off'
no-buffer-constructor: 'off'
no-caller: error
no-catch-shadow: 'off'
no-confusing-arrow: error
no-console: 'off'
no-constant-condition:
- error
- checkLoops: false
no-constructor-return: error
no-continue: 'off'
no-div-regex: 'off'
no-duplicate-imports: error
no-else-return: 'off'
no-empty-function: 'off'
no-eq-null: 'off'
no-eval: 'off'
no-extend-native: 'off'
no-extra-bind: 'off'
no-extra-label: 'off'
no-extra-parens: 'off'
no-floating-decimal: 'off'
no-implicit-coercion:
- error
- boolean: false
number: false
string: false
no-implicit-globals: 'off'
no-implied-eval: error
no-inline-comments: 'off'
no-invalid-this: 'off'
no-iterator: error
no-label-var: 'off'
no-labels: 'off'
no-lone-blocks: 'off'
no-lonely-if: 'off'
no-loop-func: 'off'
no-loss-of-precision: error
no-magic-numbers: 'off'
no-mixed-operators: 'off'
no-mixed-requires: 'off'
no-multi-assign: 'off'
no-multi-spaces: 'off'
no-multi-str: error
no-multiple-empty-lines: 'off'
no-native-reassign: 'off'
no-negated-condition: 'off'
no-negated-in-lhs: error
no-nested-ternary: 'off'
no-new: 'off'
no-new-func: 'off'
no-new-object: 'off'
no-new-require: error
no-new-wrappers: error
no-octal-escape: error
no-param-reassign: 'off'
no-path-concat: error
no-plusplus: 'off'
no-process-env: 'off'
no-process-exit: 'off'
no-promise-executor-return: error
no-proto: 'off'
no-restricted-exports: error
no-restricted-globals: error
no-restricted-imports: error
no-restricted-modules: error
no-restricted-properties: error
no-restricted-syntax: error
no-return-assign: 'off'
no-return-await: error
no-script-url: 'off'
no-self-compare: 'off'
no-sequences: 'off'
no-shadow: 'off'
no-spaced-func: 'off'
no-sync: 'off'
no-tabs: 'off'
no-template-curly-in-string: error
no-ternary: 'off'
no-throw-literal: 'off'
no-trailing-spaces: 'off'
no-undef-init: 'off'
no-undefined: 'off'
no-underscore-dangle: 'off'
no-unmodified-loop-condition: 'off'
no-unneeded-ternary: 'off'
no-unreachable-loop: error
no-unused-expressions: 'off'
no-use-before-define: 'off'
no-useless-backreference: error
no-useless-call: 'off'
no-useless-computed-key: error
no-useless-concat: 'off'
no-useless-constructor: error
no-useless-rename: error
no-useless-return: 'off'
no-var: 'off'
no-void: 'off'
no-warning-comments: 'off'
no-whitespace-before-property: error
nonblock-statement-body-position:
- error
- any
object-curly-newline: 'off'
object-curly-spacing: 'off'
object-property-newline: 'off'
object-shorthand: 'off'
one-var: 'off'
one-var-declaration-per-line: 'off'
operator-assignment: 'off'
operator-linebreak: 'off'
padded-blocks: 'off'
padding-line-between-statements: error
prefer-arrow-callback: 'off'
prefer-const: 'off'
prefer-destructuring: 'off'
prefer-exponentiation-operator: 'off'
prefer-named-capture-group: 'off'
prefer-numeric-literals: error
prefer-object-spread: 'off'
prefer-promise-reject-errors: error
prefer-reflect: 'off'
prefer-regex-literals: 'off'
prefer-rest-params: 'off'
prefer-spread: 'off'
prefer-template: 'off'
quote-props: 'off'
quotes: 'off'
radix: 'off'
require-atomic-updates: error
require-await: error
require-jsdoc: 'off'
require-unicode-regexp: 'off'
rest-spread-spacing: error
semi: 'off'
semi-spacing: 'off'
semi-style: 'off'
sort-imports: error
sort-keys: 'off'
sort-vars: 'off'
space-before-blocks: 'off'
space-before-function-paren: 'off'
space-in-parens: 'off'
space-infix-ops: 'off'
space-unary-ops: 'off'
spaced-comment: 'off'
strict: 'off'
switch-colon-spacing: 'off'
symbol-description: error
template-curly-spacing: error
template-tag-spacing: error
unicode-bom:
- error
- never
valid-jsdoc: 'off'
valid-typeof:
- error
- requireStringLiterals: false
vars-on-top: 'off'
wrap-iife: 'off'
wrap-regex: 'off'
yield-star-spacing: error
yoda: 'off'
# temporary rules
no-useless-escape: 'off'
no-unused-vars: 'off'
no-empty: 'off'
no-extra-semi: 'off'
no-redeclare: 'off'
no-control-regex: "off"
no-mixed-spaces-and-tabs: "off"
no-extra-boolean-cast: "off"
no-prototype-builtins: "off"
no-undef: "off"
no-unreachable: "off"
no-self-assign: "off"

View File

@@ -1,38 +0,0 @@
---
name: Bug report
about: Create a report to help us improve TiddlyWiki 5
title: "[BUG]"
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**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,20 +0,0 @@
---
name: Feature request
about: Suggest an idea for TiddlyWiki 5
title: "[IDEA]"
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -1,22 +0,0 @@
---
name: Pull Request
about: Propose a change to TiddlyWiki 5
title: ""
labels: ''
assignees: ''
---
**Is your PR related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you are proposing**
A clear and concise description of the changes you are proposing. Include images to show visual changes.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
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.

View File

@@ -1,74 +0,0 @@
on:
pull_request:
push:
branches:
- master
- tiddlywiki-com
env:
NODE_VERSION: "12"
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: "${{ env.NODE_VERSION }}"
- run: "./bin/test.sh"
build-prerelease:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/master'
needs: test
env:
TW5_BUILD_TIDDLYWIKI: "./tiddlywiki.js"
TW5_BUILD_MAIN_EDITION: "./editions/prerelease"
TW5_BUILD_OUTPUT: "./output/prerelease"
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: "${{ env.NODE_VERSION }}"
- run: "./bin/ci-pre-build.sh"
# There's another near-duplicate "Set dynamic environment variables" step in
# the `build-tiddlywiki-com` job.
# These _could_ be extracted as a script (or moved into `ci-pre-build.sh`) to do away with the
# duplication, but, the visibility that comes from having these in the workflow file seems
# valuable. Environment variables are global variables and setting them at the top-level
# makes sense.
# Time to reconsider this decision might be when this setup turns out to be mistake-prone.
- name: "Set dynamic environment variables"
run: |
TW5_BUILD_BRANCH=$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }')
echo "TW5_BUILD_BRANCH=${TW5_BUILD_BRANCH}" >> $GITHUB_ENV
echo "TW5_BUILD_VERSION=$(./bin/get-plugin-library-version-number)" >> $GITHUB_ENV
echo "TW5_BUILD_DETAILS=Prerelease built from branch '$TW5_BUILD_BRANCH' at commit $(git rev-parse HEAD) of $(git remote get-url origin) at $(date +'%F %T %Z')" >> $GITHUB_ENV
- run: "./bin/build-site.sh"
- run: "./bin/ci-push.sh"
env:
GH_TOKEN: ${{ secrets.GITHUBPUSHTOKEN }}
build-tiddlywiki-com:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/tiddlywiki-com'
needs: test
env:
TW5_BUILD_TIDDLYWIKI: "./node_modules/tiddlywiki/tiddlywiki.js"
TW5_BUILD_MAIN_EDITION: "./editions/tw5.com"
TW5_BUILD_OUTPUT: "./output"
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: "${{ env.NODE_VERSION }}"
- run: "./bin/ci-pre-build.sh"
# When making a change here, don't forget to see if it also applies to the step
# with the same name in the `build-prerelease` job.
- name: "Set dynamic environment variables"
run: |
TW5_BUILD_BRANCH=$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }')
echo "TW5_BUILD_BRANCH=${TW5_BUILD_BRANCH}" >> $GITHUB_ENV
echo "TW5_BUILD_VERSION=$(./bin/get-plugin-library-version-number)" >> $GITHUB_ENV
echo "TW5_BUILD_DETAILS=Built from branch '$TW5_BUILD_BRANCH' at commit $(git rev-parse HEAD) of $(git remote get-url origin) at $(date +'%F %T %Z')" >> $GITHUB_ENV
- run: "./bin/build-site.sh"
- run: "./bin/ci-push.sh"
env:
GH_TOKEN: ${{ secrets.GITHUBPUSHTOKEN }}

35
.travis.yml Normal file
View File

@@ -0,0 +1,35 @@
language: node_js
node_js:
- "12.4.0"
stages:
- name: test
- name: build-prerelease
if: branch = "master"
- name: build-tiddlywiki-com
if: branch = "tiddlywiki-com"
jobs:
include:
- stage: test
script: ./bin/test.sh
- stage: build-prerelease
script:
- ./bin/travis-pre-build.sh
- export TW5_BUILD_TIDDLYWIKI='./tiddlywiki.js'
- export TW5_BUILD_VERSION=$(./bin/get-plugin-library-version-number)
- export TW5_BUILD_DETAILS="Prerelease built from branch '$TRAVIS_BRANCH' at commit $(git rev-parse HEAD) of $(git remote get-url origin) at $(date +'%F %T %Z')"
- export TW5_BUILD_MAIN_EDITION='./editions/prerelease'
- export TW5_BUILD_OUTPUT='./output/prerelease'
- ./bin/build-site.sh || travis_terminate 1
- ./bin/travis-push.sh || travis_terminate 1
- stage: build-tiddlywiki-com
script:
- ./bin/travis-pre-build.sh
- export TW5_BUILD_TIDDLYWIKI='./node_modules/tiddlywiki/tiddlywiki.js'
- export TW5_BUILD_VERSION=$(./bin/get-plugin-library-version-number)
- export TW5_BUILD_DETAILS="Built from branch '$TRAVIS_BRANCH' at commit $(git rev-parse HEAD) of $(git remote get-url origin) at $(date +'%F %T %Z')"
- export TW5_BUILD_MAIN_EDITION='./editions/tw5.com'
- export TW5_BUILD_OUTPUT='./output'
- ./bin/build-site.sh || travis_terminate 1
- ./bin/travis-push.sh || travis_terminate 1

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.1.23
TW5_BUILD_VERSION=v5.1.21
fi
echo "Using TW5_BUILD_VERSION as [$TW5_BUILD_VERSION]"

View File

@@ -1,15 +0,0 @@
#!/bin/bash
# Push output back to GitHub
# Exit script immediately if any command fails
set -e
cd 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/Jermolene/jermolene.github.io.git" &>/dev/null
git push deploy master &>/dev/null
cd ..

20
bin/travis-push.sh Executable file
View File

@@ -0,0 +1,20 @@
#!/bin/bash
# Push output back to GitHub
cd output || exit 1
git config --global user.email "travis@travis-ci.org" || exit 1
git config --global user.name "Travis CI" || exit 1
git add -A . || exit 1
git commit --message "Travis build: $TRAVIS_BUILD_NUMBER of $TRAVIS_BRANCH ($(date +'%F %T %Z'))" || exit 1
git remote add deploy "https://$GH_TOKEN@github.com/Jermolene/jermolene.github.io.git" &>/dev/null || exit 1
git push deploy master &>/dev/null || exit 1
cd .. || exit 1

View File

@@ -1,25 +0,0 @@
#!/bin/bash
# Process translation updates made via the translators edition
# ./bin/update-translation-from-html-file.sh <language-code> <path-to-html-file>
# Assign and check parameters
LANGUAGE_CODE=$1
HTML_FILE_PATH=$2
if [ -z "$LANGUAGE_CODE" ]; then
echo "Missing parameter: language code"
exit 1
fi
if [ -z "$HTML_FILE_PATH" ]; then
echo "Missing parameter: path to HTML file"
exit 1
fi
./tiddlywiki.js editions/translators/ --verbose --unpackplugin $:/languages/$LANGUAGE_CODE --load $HTML_FILE_PATH --build output-files || exit 1
cp -R ./editions/translators/output/language/. ./languages/$LANGUAGE_CODE/ || exit 1

View File

@@ -267,16 +267,8 @@ $tw.utils.htmlDecode = function(s) {
Get the browser location.hash. We don't use location.hash because of the way that Firefox auto-urldecodes it (see http://stackoverflow.com/questions/1703552/encoding-of-window-location-hash)
*/
$tw.utils.getLocationHash = function() {
var href = window.location.href;
var idx = href.indexOf('#');
if(idx === -1) {
return "#";
} else if(idx < href.length-1 && href[idx+1] === '#') {
// Special case: ignore location hash if it itself starts with a #
return "#";
} else {
return href.substring(idx);
}
var parts = window.location.href.split('#');
return "#" + (parts.length > 1 ? parts[1] : "");
};
/*
@@ -417,10 +409,10 @@ $tw.utils.resolvePath = function(sourcepath,rootpath) {
};
/*
Parse a semantic version string into its constituent parts -- see https://semver.org
Parse a semantic version string into its constituent parts
*/
$tw.utils.parseVersion = function(version) {
var match = /^v?((\d+)\.(\d+)\.(\d+))(?:-([\dA-Za-z\-]+(?:\.[\dA-Za-z\-]+)*))?(?:\+([\dA-Za-z\-]+(?:\.[\dA-Za-z\-]+)*))?$/.exec(version);
var match = /^((\d+)\.(\d+)\.(\d+))(?:-([\dA-Za-z\-]+(?:\.[\dA-Za-z\-]+)*))?(?:\+([\dA-Za-z\-]+(?:\.[\dA-Za-z\-]+)*))?$/.exec(version);
if(match) {
return {
version: match[1],
@@ -435,37 +427,25 @@ $tw.utils.parseVersion = function(version) {
}
};
/*
Returns +1 if the version string A is greater than the version string B, 0 if they are the same, and +1 if B is greater than A.
Missing or malformed version strings are parsed as 0.0.0
*/
$tw.utils.compareVersions = function(versionStringA,versionStringB) {
var defaultVersion = {
major: 0,
minor: 0,
patch: 0
},
versionA = $tw.utils.parseVersion(versionStringA) || defaultVersion,
versionB = $tw.utils.parseVersion(versionStringB) || defaultVersion,
diff = [
versionA.major - versionB.major,
versionA.minor - versionB.minor,
versionA.patch - versionB.patch
];
if((diff[0] > 0) || (diff[0] === 0 && diff[1] > 0) || (diff[0] === 0 & diff[1] === 0 & diff[2] > 0)) {
return +1;
} else if((diff[0] < 0) || (diff[0] === 0 && diff[1] < 0) || (diff[0] === 0 & diff[1] === 0 & diff[2] < 0)) {
return -1;
} else {
return 0;
}
};
/*
Returns true if the version string A is greater than the version string B. Returns true if the versions are the same
*/
$tw.utils.checkVersions = function(versionStringA,versionStringB) {
return $tw.utils.compareVersions(versionStringA,versionStringB) !== -1;
var defaultVersion = {
major: 0,
minor: 0,
patch: 0
},
versionA = $tw.utils.parseVersion(versionStringA) || defaultVersion,
versionB = $tw.utils.parseVersion(versionStringB) || defaultVersion,
diff = [
versionA.major - versionB.major,
versionA.minor - versionB.minor,
versionA.patch - versionB.patch
];
return (diff[0] > 0) ||
(diff[0] === 0 && diff[1] > 0) ||
(diff[0] === 0 && diff[1] === 0 && diff[2] >= 0);
};
/*
@@ -660,13 +640,11 @@ $tw.utils.PasswordPrompt.prototype.createPrompt = function(options) {
var promptInfo = {
serviceName: options.serviceName,
callback: options.callback,
form: form,
owner: this
form: form
};
this.passwordPrompts.push(promptInfo);
// Make sure the wrapper is displayed
this.setWrapperDisplay();
return promptInfo;
};
$tw.utils.PasswordPrompt.prototype.removePrompt = function(promptInfo) {
@@ -1280,7 +1258,7 @@ $tw.Wiki = function(options) {
$tw.utils.each(titles || getTiddlerTitles(),function(title) {
var tiddler = tiddlers[title];
if(tiddler) {
if(tiddler.fields.type === "application/json" && tiddler.hasField("plugin-type") && tiddler.fields.text) {
if(tiddler.fields.type === "application/json" && tiddler.hasField("plugin-type")) {
pluginInfo[tiddler.fields.title] = JSON.parse(tiddler.fields.text);
results.modifiedPlugins.push(tiddler.fields.title);
}
@@ -1832,7 +1810,7 @@ $tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
// Read the specification
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 processFile = function(filename,isTiddlerFile,fields) {
var extInfo = $tw.config.fileExtensionInfo[path.extname(filename)],
type = (extInfo || {}).type || fields.type || "text/plain",
typeInfo = $tw.config.contentTypeInfo[type] || {},
@@ -1885,11 +1863,7 @@ $tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
}
});
});
if(isEditableFile) {
tiddlers.push({filepath: pathname, hasMetaFile: !!metadata && !isTiddlerFile, tiddlers: fileTiddlers});
} else {
tiddlers.push({tiddlers: fileTiddlers});
}
tiddlers.push({tiddlers: fileTiddlers});
};
// Process the listed tiddlers
$tw.utils.each(filesInfo.tiddlers,function(tidInfo) {
@@ -1919,7 +1893,7 @@ $tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
for(var t=0; t<files.length; t++) {
var filename = files[t];
if(filename !== "tiddlywiki.files" && !metaRegExp.test(filename) && fileRegExp.test(filename)) {
processFile(dirPath + path.sep + filename,dirSpec.isTiddlerFile,dirSpec.fields,dirSpec.isEditableFile);
processFile(dirPath + path.sep + filename,dirSpec.isTiddlerFile,dirSpec.fields);
}
}
}
@@ -2186,7 +2160,8 @@ $tw.loadTiddlersNode = function() {
/*
Startup TiddlyWiki
*/
$tw.boot.initStartup = function(options) {
$tw.boot.startup = function(options) {
options = options || {};
// Get the URL hash and check for safe mode
$tw.locationHash = "#";
if($tw.browser && !$tw.node) {
@@ -2272,7 +2247,6 @@ $tw.boot.initStartup = function(options) {
$tw.utils.registerFileType("application/zip","base64",".zip");
$tw.utils.registerFileType("application/x-zip-compressed","base64",".zip");
$tw.utils.registerFileType("image/jpeg","base64",[".jpg",".jpeg"],{flags:["image"]});
$tw.utils.registerFileType("image/jpg","base64",[".jpg",".jpeg"],{flags:["image"]});
$tw.utils.registerFileType("image/png","base64",".png",{flags:["image"]});
$tw.utils.registerFileType("image/gif","base64",".gif",{flags:["image"]});
$tw.utils.registerFileType("image/webp","base64",".webp",{flags:["image"]});
@@ -2282,7 +2256,6 @@ $tw.boot.initStartup = function(options) {
$tw.utils.registerFileType("image/x-icon","base64",".ico",{flags:["image"]});
$tw.utils.registerFileType("application/font-woff","base64",".woff");
$tw.utils.registerFileType("application/x-font-ttf","base64",".woff");
$tw.utils.registerFileType("application/font-woff2","base64",".woff2");
$tw.utils.registerFileType("audio/ogg","base64",".ogg");
$tw.utils.registerFileType("video/ogg","base64",[".ogm",".ogv",".ogg"]);
$tw.utils.registerFileType("video/webm","base64",".webm");
@@ -2320,9 +2293,6 @@ $tw.boot.initStartup = function(options) {
return result;
}
}
};
$tw.boot.loadStartup = function(options){
// Load tiddlers
if($tw.boot.tasks.readBrowserTiddlers) {
$tw.loadTiddlersBrowser();
@@ -2335,8 +2305,6 @@ $tw.boot.loadStartup = function(options){
}
// Give hooks a chance to modify the store
$tw.hooks.invokeHook("th-boot-tiddlers-loaded");
}
$tw.boot.execStartup = function(options){
// Unpack plugin tiddlers
$tw.wiki.readPluginInfo();
$tw.wiki.registerPluginTiddlers("plugin",$tw.safeMode ? ["$:/core"] : undefined);
@@ -2365,16 +2333,6 @@ $tw.boot.execStartup = function(options){
$tw.boot.disabledStartupModules = $tw.boot.disabledStartupModules || [];
// Repeatedly execute the next eligible task
$tw.boot.executeNextStartupTask(options.callback);
}
/*
Startup TiddlyWiki
*/
$tw.boot.startup = function(options) {
options = options || {};
// Get the URL hash and check for safe mode
$tw.boot.initStartup(options);
$tw.boot.loadStartup(options);
$tw.boot.execStartup(options);
};
/*

View File

@@ -0,0 +1,4 @@
title: $:/core/images/storyview-solo
tags: $:/tags/Image
<svg width="22pt" height="22pt" class="tc-image-storyview-single tc-image-button" viewBox="0 0 128 128"><path fill-rule="evenodd" d="M8.007 0A8.01 8.01 0 000 8.007v111.986A8.01 8.01 0 008.007 128h111.986a8.01 8.01 0 008.007-8.007V8.007A8.01 8.01 0 00119.993 0H8.007zm15.992 16A8 8 0 0016 24.009V71.99C16 76.414 19.588 80 24 80h80a8 8 0 008-8.009V24.01c0-4.423-3.588-8.009-8-8.009H24z"/></svg>

View File

@@ -70,7 +70,6 @@ Plugins/Caption: Plugins
Plugins/Disable/Caption: disable
Plugins/Disable/Hint: Disable this plugin when reloading page
Plugins/Disabled/Status: (disabled)
Plugins/Downgrade/Caption: downgrade
Plugins/Empty/Hint: None
Plugins/Enable/Caption: enable
Plugins/Enable/Hint: Enable this plugin when reloading page
@@ -88,11 +87,6 @@ Plugins/Plugins/Hint: Plugins
Plugins/Reinstall/Caption: reinstall
Plugins/Themes/Caption: Themes
Plugins/Themes/Hint: Theme plugins
Plugins/Update/Caption: update
Plugins/Updates/Caption: Updates
Plugins/Updates/Hint: Available updates to installed plugins
Plugins/Updates/UpdateAll/Caption: Update <<update-count>> plugins
Plugins/SubPluginPrompt: With <<count>> sub-plugins available
Saving/Caption: Saving
Saving/DownloadSaver/AutoSave/Description: Permit automatic saving for the download saver
Saving/DownloadSaver/AutoSave/Hint: Enable Autosave for Download Saver
@@ -117,7 +111,6 @@ Saving/GitService/Gitea/Caption: Gitea Saver
Saving/GitService/Gitea/Password: Personal access token for API (via Giteas web interface: `Settings | Applications | Generate New Token`)
Saving/TiddlySpot/Advanced/Heading: Advanced Settings
Saving/TiddlySpot/BackupDir: Backup Directory
Saving/TiddlySpot/ControlPanel: ~TiddlySpot Control Panel
Saving/TiddlySpot/Backups: Backups
Saving/TiddlySpot/Caption: ~TiddlySpot Saver
Saving/TiddlySpot/Description: These settings are only used when saving to http://tiddlyspot.com or a compatible remote server

View File

@@ -6,13 +6,13 @@ description: Render tiddlers matching a filter to a specified ContentType
Render a set of tiddlers matching a filter to separate files of a specified ContentType (defaults to `text/html`) and extension (defaults to `.html`).
```
--rendertiddlers '<filter>' <template> <pathname> [<type>] [<extension>] ["noclean"]
--rendertiddlers <filter> <template> <pathname> [<type>] [<extension>] ["noclean"]
```
For example:
```
--rendertiddlers '[!is[system]]' $:/core/templates/static.tiddler.html ./static text/plain
--rendertiddlers [!is[system]] $:/core/templates/static.tiddler.html ./static text/plain
```
By default, the pathname is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.

View File

@@ -13,11 +13,6 @@ Listing/Preview/TextRaw: Text (Raw)
Listing/Preview/Fields: Fields
Listing/Preview/Diff: Diff
Listing/Preview/DiffFields: Diff (Fields)
Listing/Rename/Tooltip: Rename tiddler before importing
Listing/Rename/Prompt: Rename to:
Listing/Rename/ConfirmRename: Rename tiddler
Listing/Rename/CancelRename: Cancel
Listing/Rename/OverwriteWarning: A tiddler with this title already exists.
Upgrader/Plugins/Suppressed/Incompatible: Blocked incompatible or obsolete plugin
Upgrader/Plugins/Suppressed/Version: Blocked plugin (due to incoming <<incoming>> being older than existing <<existing>>)
Upgrader/Plugins/Upgraded: Upgraded plugin from <<incoming>> to <<upgraded>>

View File

@@ -26,9 +26,7 @@ Error/Caption: Error
Error/EditConflict: File changed on server
Error/Filter: Filter error
Error/FilterSyntax: Syntax error in filter expression
Error/FilterRunPrefix: Filter Error: Unknown prefix for filter run
Error/IsFilterOperator: Filter Error: Unknown operand for the 'is' filter operator
Error/FormatFilterOperator: Filter Error: Unknown suffix for the 'format' filter operator
Error/LoadingPluginLibrary: Error loading plugin library
Error/NetworkErrorAlert: `<h2>''Network Error''</h2>It looks like the connection to the server has been lost. This may indicate a problem with your network connection. Please attempt to restore network connectivity before continuing.<br><br>''Any unsaved changes will be automatically synchronised when connectivity is restored''.`
Error/RecursiveTransclusion: Recursive transclusion error in transclude widget
@@ -64,15 +62,6 @@ OfficialPluginLibrary: Official ~TiddlyWiki Plugin Library
OfficialPluginLibrary/Hint: The official ~TiddlyWiki plugin library at tiddlywiki.com. Plugins, themes and language packs are maintained by the core team.
PluginReloadWarning: Please save {{$:/core/ui/Buttons/save-wiki}} and reload {{$:/core/ui/Buttons/refresh}} to allow changes to ~JavaScript plugins to take effect
RecentChanges/DateFormat: DDth MMM YYYY
Shortcuts/Input/AdvancedSearch/Hint: Open the ~AdvancedSearch panel from within the sidebar search field
Shortcuts/Input/Accept/Hint: Accept the selected item
Shortcuts/Input/AcceptVariant/Hint: Accept the selected item (variant)
Shortcuts/Input/Cancel/Hint: Clear the input field
Shortcuts/Input/Down/Hint: Select the next item
Shortcuts/Input/Tab-Left/Hint: Select the previous Tab
Shortcuts/Input/Tab-Right/Hint: Select the next Tab
Shortcuts/Input/Up/Hint: Select the previous item
Shortcuts/SidebarLayout/Hint: Change the sidebar layout
SystemTiddler/Tooltip: This is a system tiddler
SystemTiddlers/Include/Prompt: Include system tiddlers
TagManager/Colour/Heading: Colour

View File

@@ -1,3 +1,2 @@
title: $:/config/NewJournal/Tags
Journal
tags: Journal

View File

@@ -4,6 +4,7 @@ All/Caption: All
Contents/Caption: Contents
Drafts/Caption: Drafts
Explorer/Caption: Explorer
History/Caption: History
Missing/Caption: Missing
More/Caption: More
Open/Caption: Open

View File

@@ -71,7 +71,7 @@ Command.prototype.fetchFiles = function(options) {
if(options.url) {
urls = [options.url]
} else if(options.urlFilter) {
urls = this.commander.wiki.filterTiddlers(options.urlFilter);
urls = $tw.wiki.filterTiddlers(options.urlFilter);
} else {
return "Missing URL";
}

View File

@@ -33,7 +33,7 @@ Command.prototype.execute = function() {
tiddlers = {};
// Collect up the library plugins
var collectPlugins = function(folder) {
var pluginFolders = $tw.utils.getSubdirectories(folder) || [];
var pluginFolders = fs.readdirSync(folder);
for(var p=0; p<pluginFolders.length; p++) {
if(!$tw.boot.excludeRegExp.test(pluginFolders[p])) {
pluginFields = $tw.loadPluginFolder(path.resolve(folder,"./" + pluginFolders[p]));
@@ -44,16 +44,16 @@ Command.prototype.execute = function() {
}
},
collectPublisherPlugins = function(folder) {
var publisherFolders = $tw.utils.getSubdirectories(folder) || [];
var publisherFolders = fs.readdirSync(folder);
for(var t=0; t<publisherFolders.length; t++) {
if(!$tw.boot.excludeRegExp.test(publisherFolders[t])) {
collectPlugins(path.resolve(folder,"./" + publisherFolders[t]));
}
}
};
$tw.utils.each($tw.getLibraryItemSearchPaths($tw.config.pluginsPath,$tw.config.pluginsEnvVar),collectPublisherPlugins);
$tw.utils.each($tw.getLibraryItemSearchPaths($tw.config.themesPath,$tw.config.themesEnvVar),collectPublisherPlugins);
$tw.utils.each($tw.getLibraryItemSearchPaths($tw.config.languagesPath,$tw.config.languagesEnvVar),collectPlugins);
collectPublisherPlugins(path.resolve($tw.boot.corePath,$tw.config.pluginsPath));
collectPublisherPlugins(path.resolve($tw.boot.corePath,$tw.config.themesPath));
collectPlugins(path.resolve($tw.boot.corePath,$tw.config.languagesPath));
// Save the upgrade library tiddler
var pluginFields = {
title: upgradeLibraryTitle,

View File

@@ -5,12 +5,10 @@ module-type: command
Command to save the subtiddlers of a bundle tiddler as a series of JSON files
--savelibrarytiddlers <tiddler> <tiddler-filter> <pathname> <skinnylisting>
--savelibrarytiddlers <tiddler> <pathname> <skinnylisting>
The tiddler identifies the bundle tiddler that contains the subtiddlers.
The tiddler filter specifies the plugins to be included.
The pathname specifies the pathname to the folder in which the JSON files should be saved. The filename is the URL encoded title of the subtiddler.
The skinnylisting specifies the title of the tiddler to which a JSON catalogue of the subtiddlers will be saved. The JSON file contains the same data as the bundle tiddler but with the `text` field removed.
@@ -71,7 +69,7 @@ Command.prototype.execute = function() {
// Collect the skinny list data
var pluginTiddlers = JSON.parse(tiddler.text),
readmeContent = (pluginTiddlers.tiddlers[title + "/readme"] || {}).text,
doesRequireReload = !!self.commander.wiki.doesPluginInfoRequireReload(pluginTiddlers),
doesRequireReload = !!$tw.wiki.doesPluginInfoRequireReload(pluginTiddlers),
iconTiddler = pluginTiddlers.tiddlers[title + "/icon"] || {},
iconType = iconTiddler.type,
iconText = iconTiddler.text,

View File

@@ -80,8 +80,7 @@ function FramedEngine(options) {
$tw.utils.addEventListeners(this.domNode,[
{name: "click",handlerObject: this,handlerMethod: "handleClickEvent"},
{name: "input",handlerObject: this,handlerMethod: "handleInputEvent"},
{name: "keydown",handlerObject: this.widget,handlerMethod: "handleKeydownEvent"},
{name: "focus",handlerObject: this,handlerMethod: "handleFocusEvent"}
{name: "keydown",handlerObject: this.widget,handlerMethod: "handleKeydownEvent"}
]);
// Insert the element into the DOM
this.iframeDoc.body.appendChild(this.domNode);
@@ -108,20 +107,13 @@ Set the text of the engine if it doesn't currently have focus
FramedEngine.prototype.setText = function(text,type) {
if(!this.domNode.isTiddlyWikiFakeDom) {
if(this.domNode.ownerDocument.activeElement !== this.domNode) {
this.updateDomNodeText(text);
this.domNode.value = text;
}
// Fix the height if needed
this.fixHeight();
}
};
/*
Update the DomNode with the new text
*/
FramedEngine.prototype.updateDomNodeText = function(text) {
this.domNode.value = text;
};
/*
Get the text of the engine
*/
@@ -161,15 +153,6 @@ FramedEngine.prototype.focus = function() {
}
};
/*
Handle a focus event
*/
FramedEngine.prototype.handleFocusEvent = function(event) {
if(this.widget.editCancelPopups) {
$tw.popup.cancel(0);
}
};
/*
Handle a click
*/
@@ -184,9 +167,6 @@ Handle a dom "input" event which occurs when the text has changed
FramedEngine.prototype.handleInputEvent = function(event) {
this.widget.saveChanges(this.getText());
this.fixHeight();
if(this.widget.editInputActions) {
this.widget.invokeActionString(this.widget.editInputActions);
}
return true;
};

View File

@@ -68,20 +68,13 @@ Set the text of the engine if it doesn't currently have focus
SimpleEngine.prototype.setText = function(text,type) {
if(!this.domNode.isTiddlyWikiFakeDom) {
if(this.domNode.ownerDocument.activeElement !== this.domNode || text === "") {
this.updateDomNodeText(text);
this.domNode.value = text;
}
// Fix the height if needed
this.fixHeight();
}
};
/*
Update the DomNode with the new text
*/
SimpleEngine.prototype.updateDomNodeText = function(text) {
this.domNode.value = text;
};
/*
Get the text of the engine
*/
@@ -122,9 +115,6 @@ Handle a dom "input" event which occurs when the text has changed
SimpleEngine.prototype.handleInputEvent = function(event) {
this.widget.saveChanges(this.getText());
this.fixHeight();
if(this.widget.editInputActions) {
this.widget.invokeActionString(this.widget.editInputActions);
}
return true;
};
@@ -132,9 +122,6 @@ SimpleEngine.prototype.handleInputEvent = function(event) {
Handle a dom "focus" event
*/
SimpleEngine.prototype.handleFocusEvent = function(event) {
if(this.widget.editCancelPopups) {
$tw.popup.cancel(0);
}
if(this.widget.editFocusPopup) {
$tw.popup.triggerPopup({
domNode: this.domNode,

View File

@@ -177,9 +177,6 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
this.editFocusPopup = this.getAttribute("focusPopup");
this.editFocus = this.getAttribute("focus");
this.editTabIndex = this.getAttribute("tabindex");
this.editCancelPopups = this.getAttribute("cancelPopups","") === "yes";
this.editInputActions = this.getAttribute("inputActions");
this.editRefreshTitle = this.getAttribute("refreshTitle");
// Get the default editor element tag and type
var tag,type;
if(this.editField === "text") {
@@ -211,11 +208,9 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
EditTextWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
// Completely rerender if any of our attributes have changed
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes["default"] || changedAttributes["class"] || changedAttributes.placeholder || changedAttributes.size || changedAttributes.autoHeight || changedAttributes.minHeight || changedAttributes.focusPopup || changedAttributes.rows || changedAttributes.tabindex || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || changedTiddlers[HEIGHT_MODE_TITLE] || changedTiddlers[ENABLE_TOOLBAR_TITLE]) {
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes["default"] || changedAttributes["class"] || changedAttributes.placeholder || changedAttributes.size || changedAttributes.autoHeight || changedAttributes.minHeight || changedAttributes.focusPopup || changedAttributes.rows || changedAttributes.tabindex || changedTiddlers[HEIGHT_MODE_TITLE] || changedTiddlers[ENABLE_TOOLBAR_TITLE]) {
this.refreshSelf();
return true;
} else if (changedTiddlers[this.editRefreshTitle]) {
this.engine.updateDomNodeText(this.getEditInfo().value);
} else if(changedTiddlers[this.editTitle]) {
var editInfo = this.getEditInfo();
this.updateEditor(editInfo.value,editInfo.type);

View File

@@ -1,25 +0,0 @@
/*\
title: $:/core/modules/filterrunprefixes/all.js
type: application/javascript
module-type: filterrunprefix
Union of sets without de-duplication.
Equivalent to = filter run prefix.
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter prefix function
*/
exports.all = function(operationSubFunction) {
return function(results,source,widget) {
Array.prototype.push.apply(results,operationSubFunction(source,widget));
};
};
})();

View File

@@ -1,28 +0,0 @@
/*\
title: $:/core/modules/filterrunprefixes/and.js
type: application/javascript
module-type: filterrunprefix
Intersection of sets.
Equivalent to + filter run prefix.
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter prefix function
*/
exports.and = function(operationSubFunction) {
return function(results,source,widget) {
// This replaces all the elements of the array, but keeps the actual array so that references to it are preserved
source = $tw.wiki.makeTiddlerIterator(results);
results.splice(0,results.length);
$tw.utils.pushTop(results,operationSubFunction(source,widget));
};
};
})();

View File

@@ -1,27 +0,0 @@
/*\
title: $:/core/modules/filterrunprefixes/else.js
type: application/javascript
module-type: filterrunprefix
Equivalent to ~ filter run prefix.
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter prefix function
*/
exports.else = function(operationSubFunction) {
return function(results,source,widget) {
if(results.length === 0) {
// Main result so far is empty
$tw.utils.pushTop(results,operationSubFunction(source,widget));
}
};
};
})();

View File

@@ -1,25 +0,0 @@
/*\
title: $:/core/modules/filterrunprefixes/except.js
type: application/javascript
module-type: filterrunprefix
Difference of sets.
Equivalent to - filter run prefix.
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter prefix function
*/
exports.except = function(operationSubFunction) {
return function(results,source,widget) {
$tw.utils.removeArrayEntries(results,operationSubFunction(source,widget));
};
};
})();

View File

@@ -1,31 +0,0 @@
/*\
title: $:/core/modules/filterrunprefixes/filter.js
type: application/javascript
module-type: filterrunprefix
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.filter = function(operationSubFunction) {
return function(results,source,widget) {
if(results.length > 0) {
var resultsToRemove = [];
$tw.utils.each(results,function(result) {
var filtered = operationSubFunction($tw.wiki.makeTiddlerIterator([result]),widget);
if(filtered.length === 0) {
resultsToRemove.push(result);
}
});
$tw.utils.removeArrayEntries(results,resultsToRemove);
}
}
};
})();

View File

@@ -1,30 +0,0 @@
/*\
title: $:/core/modules/filterrunprefixes/intersection.js
type: application/javascript
module-type: filterrunprefix
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter prefix function
*/
exports.intersection = function(operationSubFunction) {
return function(results,source,widget) {
if(results.length !== 0) {
var secondRunResults = operationSubFunction(source,widget);
var firstRunResults = results.splice(0);
$tw.utils.each(firstRunResults,function(title) {
if(secondRunResults.indexOf(title) !== -1) {
results.push(title);
}
});
}
};
};
})();

View File

@@ -1,24 +0,0 @@
/*\
title: $:/core/modules/filterrunprefixes/or.js
type: application/javascript
module-type: filterrunprefix
Equivalent to a filter run with no prefix.
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter prefix function
*/
exports.or = function(operationSubFunction) {
return function(results,source,widget) {
$tw.utils.pushTop(results,operationSubFunction(source,widget));
};
};
})();

View File

@@ -119,7 +119,7 @@ exports.parseFilter = function(filterString) {
p = 0, // Current position in the filter string
match;
var whitespaceRegExp = /(\s+)/mg,
operandRegExp = /((?:\+|\-|~|=|\:(\w+))?)(?:(\[)|(?:"([^"]*)")|(?:'([^']*)')|([^\s\[\]]+))/mg;
operandRegExp = /((?:\+|\-|~|=)?)(?:(\[)|(?:"([^"]*)")|(?:'([^']*)')|([^\s\[\]]+))/mg;
while(p < filterString.length) {
// Skip any whitespace
whitespaceRegExp.lastIndex = p;
@@ -140,19 +140,16 @@ exports.parseFilter = function(filterString) {
};
if(match[1]) {
operation.prefix = match[1];
p = p + operation.prefix.length;
if(match[2]) {
operation.namedPrefix = match[2];
}
p++;
}
if(match[3]) { // Opening square bracket
if(match[2]) { // Opening square bracket
p = parseFilterOperation(operation.operators,filterString,p);
} else {
p = match.index + match[0].length;
}
if(match[4] || match[5] || match[6]) { // Double quoted string, single quoted string or unquoted title
if(match[3] || match[4] || match[5]) { // Double quoted string, single quoted string or unquoted title
operation.operators.push(
{operator: "title", operand: match[4] || match[5] || match[6]}
{operator: "title", operand: match[3] || match[4] || match[5]}
);
}
results.push(operation);
@@ -169,14 +166,6 @@ exports.getFilterOperators = function() {
return this.filterOperators;
};
exports.getFilterRunPrefixes = function() {
if(!this.filterPrefixes) {
$tw.Wiki.prototype.filterRunPrefixes = {};
$tw.modules.applyMethods("filterrunprefix",this.filterRunPrefixes);
}
return this.filterRunPrefixes;
}
exports.filterTiddlers = function(filterString,widget,source) {
var fn = this.compileFilter(filterString);
return fn.call(this,source,widget);
@@ -252,29 +241,35 @@ exports.compileFilter = function(filterString) {
return resultArray;
}
};
var filterRunPrefixes = self.getFilterRunPrefixes();
// Wrap the operator functions in a wrapper function that depends on the prefix
operationFunctions.push((function() {
switch(operation.prefix || "") {
case "": // No prefix means that the operation is unioned into the result
return filterRunPrefixes["or"](operationSubFunction);
return function(results,source,widget) {
$tw.utils.pushTop(results,operationSubFunction(source,widget));
};
case "=": // The results of the operation are pushed into the result without deduplication
return filterRunPrefixes["all"](operationSubFunction);
return function(results,source,widget) {
Array.prototype.push.apply(results,operationSubFunction(source,widget));
};
case "-": // The results of this operation are removed from the main result
return filterRunPrefixes["except"](operationSubFunction);
return function(results,source,widget) {
$tw.utils.removeArrayEntries(results,operationSubFunction(source,widget));
};
case "+": // This operation is applied to the main results so far
return filterRunPrefixes["and"](operationSubFunction);
return function(results,source,widget) {
// This replaces all the elements of the array, but keeps the actual array so that references to it are preserved
source = self.makeTiddlerIterator(results);
results.splice(0,results.length);
$tw.utils.pushTop(results,operationSubFunction(source,widget));
};
case "~": // This operation is unioned into the result only if the main result so far is empty
return filterRunPrefixes["else"](operationSubFunction);
default:
if(operation.namedPrefix && filterRunPrefixes[operation.namedPrefix]) {
return filterRunPrefixes[operation.namedPrefix](operationSubFunction);
} else {
return function(results,source,widget) {
results.splice(0,results.length);
results.push($tw.language.getString("Error/FilterRunPrefix"));
};
}
return function(results,source,widget) {
if(results.length === 0) {
// Main result so far is empty
$tw.utils.pushTop(results,operationSubFunction(source,widget));
}
};
}
})());
});

View File

@@ -1,40 +0,0 @@
/*\
title: $:/core/modules/filters/compare.js
type: application/javascript
module-type: filteroperator
General purpose comparison operator
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
exports.compare = function(source,operator,options) {
var suffixes = operator.suffixes || [],
type = (suffixes[0] || [])[0],
mode = (suffixes[1] || [])[0],
typeFn = $tw.utils.makeCompareFunction(type,{defaultType: "number"}),
modeFn = modes[mode] || modes.eq,
invert = operator.prefix === "!",
results = [];
source(function(tiddler,title) {
if(modeFn(typeFn(title,operator.operand)) !== invert) {
results.push(title);
}
});
return results;
};
var modes = {
"eq": function(value) {return value === 0;},
"ne": function(value) {return value !== 0;},
"gteq": function(value) {return value >= 0;},
"gt": function(value) {return value > 0;},
"lteq": function(value) {return value <= 0;},
"lt": function(value) {return value < 0;}
}
})();

View File

@@ -1,36 +0,0 @@
/*\
title: $:/core/modules/filters/duplicateslugs.js
type: application/javascript
module-type: filteroperator
Filter function for [duplicateslugs[]]
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.duplicateslugs = function(source,operator,options) {
var slugs = Object.create(null), // Hashmap by slug of title, replaced with "true" if the duplicate title has already been output
results = [];
source(function(tiddler,title) {
var slug = options.wiki.slugify(title);
if(slug in slugs) {
if(slugs[slug] !== true) {
results.push(slugs[slug]);
slugs[slug] = true;
}
results.push(title);
} else {
slugs[slug] = title;
}
});
return results;
};
})();

View File

@@ -16,28 +16,13 @@ Filter operator for returning the names of the fields on the selected tiddlers
Export our filter function
*/
exports.fields = function(source,operator,options) {
var results = [],
fieldName,
suffixes = (operator.suffixes || [])[0] || [],
operand = $tw.utils.parseStringArray(operator.operand);
var results = [];
source(function(tiddler,title) {
if(tiddler) {
if(suffixes.indexOf("include") !== -1) {
for(fieldName in tiddler.fields) {
(operand.indexOf(fieldName) !== -1) ? $tw.utils.pushTop(results,fieldName) : "";
}
} else if (suffixes.indexOf("exclude") !== -1) {
for(fieldName in tiddler.fields) {
(operand.indexOf(fieldName) !== -1) ? "" : $tw.utils.pushTop(results,fieldName);
}
} // else if
else {
for(fieldName in tiddler.fields) {
$tw.utils.pushTop(results,fieldName);
}
} // else
} // if (tiddler)
for(var fieldName in tiddler.fields) {
$tw.utils.pushTop(results,fieldName);
}
}
});
return results;
};

View File

@@ -1,31 +0,0 @@
/*\
title: $:/core/modules/filters/filter.js
type: application/javascript
module-type: filteroperator
Filter operator returning those input titles that pass a subfilter
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.filter = function(source,operator,options) {
var filterFn = options.wiki.compileFilter(operator.operand),
results = [],
target = operator.prefix !== "!";
source(function(tiddler,title) {
var list = filterFn.call(options.wiki,options.wiki.makeTiddlerIterator([title]));
if((list.length > 0) === target) {
results.push(title);
}
});
return results;
};
})();

View File

@@ -1,46 +0,0 @@
/*\
title: $:/core/modules/filters/format.js
type: application/javascript
module-type: filteroperator
Filter operator for formatting strings
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var formatFilterOperators;
function getFormatFilterOperators() {
if(!formatFilterOperators) {
formatFilterOperators = {};
$tw.modules.applyMethods("formatfilteroperator",formatFilterOperators);
}
return formatFilterOperators;
}
/*
Export our filter function
*/
exports.format = function(source,operator,options) {
// Dispatch to the correct formatfilteroperator
var formatFilterOperators = getFormatFilterOperators();
if(operator.suffix) {
var formatFilterOperator = formatFilterOperators[operator.suffix];
if(formatFilterOperator) {
return formatFilterOperator(source,operator.operand,options);
} else {
return [$tw.language.getString("Error/FormatFilterOperator")];
}
} else {
// Return all unchanged if the suffix is missing
var results = [];
source(function(tiddler,title) {
results.push(title);
});
return results;
}
};
})();

View File

@@ -1,26 +0,0 @@
/*\
title: $:/core/modules/filters/format/date.js
type: application/javascript
module-type: formatfilteroperator
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.date = function(source,operand,options) {
var results = [];
source(function(tiddler,title) {
var value = $tw.utils.parseDate(title);
if(value && $tw.utils.isDate(value) && value.toString() !== "Invalid Date") {
results.push($tw.utils.formatDateString(value,operand || "YYYY MM DD 0hh:0mm"));
}
});
return results;
};
})();

View File

@@ -1,26 +0,0 @@
/*\
title: $:/core/modules/filters/format/relativedate.js
type: application/javascript
module-type: formatfilteroperator
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.relativedate = function(source,operand,options) {
var results = [];
source(function(tiddler,title) {
var value = $tw.utils.parseDate(title);
if(value && $tw.utils.isDate(value) && value.toString() !== "Invalid Date") {
results.push($tw.utils.getRelativeDate((new Date()) - (new Date(value))).description);
}
});
return results;
};
})();

View File

@@ -0,0 +1,38 @@
/*\
title: $:/core/modules/filters/getstoryviewmode.js
type: application/javascript
module-type: filteroperator
Filter operator for retrieving modes from a storyview. Only "singletiddlermode" is implemented at present
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter functions
*/
exports.getstoryviewmode = function(source,operator,options) {
// Initialise the storyviews if they've not been done already
var storyviews = {};
$tw.modules.applyMethods("storyview",storyviews);
if(operator.operand !== "singletiddlermode") {
return [];
}
var results = [];
source(function(tiddler,title) {
var storyview = storyviews[title];
if(storyview && storyview.singleTiddlerMode) {
results.push("yes");
} else {
results.push("no");
}
});
return results;
};
})();

View File

@@ -3,7 +3,7 @@ title: $:/core/modules/filters/has.js
type: application/javascript
module-type: filteroperator
Filter operator for checking if a tiddler has the specified field or index
Filter operator for checking if a tiddler has the specified field
\*/
(function(){
@@ -33,32 +33,16 @@ exports.has = function(source,operator,options) {
}
});
}
}
else if(operator.suffix === "index") {
} else {
if(invert) {
source(function(tiddler,title) {
if(!tiddler || (tiddler && (!$tw.utils.hop(options.wiki.getTiddlerDataCached(tiddler,Object.create(null)),operator.operand)))) {
if(!tiddler || !$tw.utils.hop(tiddler.fields,operator.operand) || (tiddler.fields[operator.operand] === "")) {
results.push(title);
}
});
} else {
source(function(tiddler,title) {
if(tiddler && $tw.utils.hop(options.wiki.getTiddlerDataCached(tiddler,Object.create(null)),operator.operand)) {
results.push(title);
}
});
}
}
else {
if(invert) {
source(function(tiddler,title) {
if(!tiddler || !$tw.utils.hop(tiddler.fields,operator.operand) || (tiddler.fields[operator.operand].length === 0)) {
results.push(title);
}
});
} else {
source(function(tiddler,title) {
if(tiddler && $tw.utils.hop(tiddler.fields,operator.operand) && (tiddler.fields[operator.operand].length !== 0)) {
if(tiddler && $tw.utils.hop(tiddler.fields,operator.operand) && !(tiddler.fields[operator.operand] === "" || tiddler.fields[operator.operand].length === 0)) {
results.push(title);
}
});

View File

@@ -114,9 +114,9 @@ exports.minall = makeNumericReducingOperator(
function makeNumericBinaryOperator(fnCalc) {
return function(source,operator,options) {
var result = [],
numOperand = $tw.utils.parseNumber(operator.operand);
numOperand = parseNumber(operator.operand);
source(function(tiddler,title) {
result.push($tw.utils.stringifyNumber(fnCalc($tw.utils.parseNumber(title),numOperand)));
result.push(stringifyNumber(fnCalc(parseNumber(title),numOperand)));
});
return result;
};
@@ -129,10 +129,18 @@ function makeNumericReducingOperator(fnCalc,initialValue) {
source(function(tiddler,title) {
result.push(title);
});
return [$tw.utils.stringifyNumber(result.reduce(function(accumulator,currentValue) {
return fnCalc(accumulator,$tw.utils.parseNumber(currentValue));
return [stringifyNumber(result.reduce(function(accumulator,currentValue) {
return fnCalc(accumulator,parseNumber(currentValue));
},initialValue))];
};
}
function parseNumber(str) {
return parseFloat(str) || 0;
}
function stringifyNumber(num) {
return num + "";
}
})();

View File

@@ -1,54 +0,0 @@
/*\
title: $:/core/modules/filters/reduce.js
type: application/javascript
module-type: filteroperator
Filter operator evaluates a subfilter for each item, making the running total available in the variable `accumulator`, and the current index available in the variable `index`
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.reduce = function(source,operator,options) {
// Accumulate the list
var results = [];
source(function(tiddler,title) {
results.push(title);
});
// Run the filter over each item
var filterFn = options.wiki.compileFilter(operator.operand),
accumulator = operator.suffix || "";
for(var index=0; index<results.length; index++) {
var title = results[index],
list = filterFn.call(options.wiki,options.wiki.makeTiddlerIterator([title]),{
getVariable: function(name) {
switch(name) {
case "currentTiddler":
return "" + title;
case "accumulator":
return "" + accumulator;
case "index":
return "" + index;
case "revIndex":
return "" + (results.length - 1 - index);
case "length":
return "" + results.length;
default:
return options.widget.getVariable(name);
}
}
});
if(list.length > 0) {
accumulator = "" + list[0];
}
}
return [accumulator];
};
})();

View File

@@ -1,23 +0,0 @@
/*\
title: $:/core/modules/filters/slugify.js
type: application/javascript
module-type: filteroperator
Filter operator for slugifying a tiddler title
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
exports.slugify = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
results.push(options.wiki.slugify(title));
});
return results;
};
})();

View File

@@ -1,57 +0,0 @@
/*\
title: $:/core/modules/filters/sortsub.js
type: application/javascript
module-type: filteroperator
Filter operator for sorting by a subfilter
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.sortsub = function(source,operator,options) {
// Compile the subfilter
var filterFn = options.wiki.compileFilter(operator.operand);
// Collect the input titles and the corresponding sort keys
var inputTitles = [],
sortKeys = [];
source(function(tiddler,title) {
inputTitles.push(title);
var r = filterFn.call(options.wiki,function(iterator) {
iterator(options.wiki.getTiddler(title),title);
},{
getVariable: function(name) {
if(name === "currentTiddler") {
return title;
} else {
return options.widget.getVariable(name);
}
}
});
sortKeys.push(r[0] || "");
});
// Rather than sorting the titles array, we'll sort the indexes so that we can consult both arrays
var indexes = new Array(inputTitles.length);
for(var t=0; t<inputTitles.length; t++) {
indexes[t] = t;
}
// Sort the indexes
var compareFn = $tw.utils.makeCompareFunction(operator.suffix,{defaultType: "string",invert: operator.prefix === "!"});
indexes = indexes.sort(function(a,b) {
return compareFn(sortKeys[a],sortKeys[b]);
});
// Make the results array in order
var results = [];
$tw.utils.each(indexes,function(index) {
results.push(inputTitles[index]);
});
return results;
};
})();

View File

@@ -34,36 +34,14 @@ exports.titlecase = makeStringBinaryOperator(
function(a) {return [$tw.utils.toTitleCase(a)];}
);
exports.trim = function(source,operator,options) {
var result = [],
suffix = operator.suffix || "",
operand = (operator.operand || ""),
fnCalc;
if(suffix === "prefix") {
fnCalc = function(a,b) {return [$tw.utils.trimPrefix(a,b)];}
} else if(suffix === "suffix") {
fnCalc = function(a,b) {return [$tw.utils.trimSuffix(a,b)];}
} else {
if(operand === "") {
fnCalc = function(a) {return [$tw.utils.trim(a)];}
} else {
fnCalc = function(a,b) {return [$tw.utils.trimSuffix($tw.utils.trimPrefix(a,b),b)];}
}
}
source(function(tiddler,title) {
Array.prototype.push.apply(result,fnCalc(title,operand));
});
return result;
};
exports.trim = makeStringBinaryOperator(
function(a) {return [$tw.utils.trim(a)];}
);
exports.split = makeStringBinaryOperator(
function(a,b) {return ("" + a).split(b);}
);
exports["enlist-input"] = makeStringBinaryOperator(
function(a) {return $tw.utils.parseStringArray("" + a);}
);
exports.join = makeStringReducingOperator(
function(accumulator,value,operand) {
if(accumulator === null) {
@@ -90,12 +68,9 @@ function makeStringReducingOperator(fnCalc,initialValue) {
source(function(tiddler,title) {
result.push(title);
});
if(result.length === 0) {
return [];
}
return [result.reduce(function(accumulator,currentValue) {
return fnCalc(accumulator,currentValue,operator.operand || "");
},initialValue) || ""];
},initialValue)];
};
}

View File

@@ -18,7 +18,6 @@ exports.getInfoTiddlerFields = function() {
// Basics
infoTiddlerFields.push({title: "$:/info/browser", text: mapBoolean(!!$tw.browser)});
infoTiddlerFields.push({title: "$:/info/node", text: mapBoolean(!!$tw.node)});
infoTiddlerFields.push({title: "$:/info/startup-timestamp", text: $tw.utils.stringifyDate(new Date())});
if($tw.browser) {
// Document location
var setLocationProperty = function(name,value) {

View File

@@ -284,16 +284,6 @@ KeyboardManager.prototype.checkKeyDescriptors = function(event,keyInfoArray) {
return false;
};
KeyboardManager.prototype.getEventModifierKeyDescriptor = function(event) {
return event.ctrlKey && !event.shiftKey && !event.altKey ? "ctrl" :
event.shiftKey && !event.ctrlKey && !event.altKey? "shift" :
event.ctrlKey && event.shiftKey && !event.altKey ? "ctrl-shift" :
event.altKey && !event.shiftKey && !event.ctrlKey ? "alt" :
event.altKey && event.shiftKey && !event.ctrlKey ? "alt-shift" :
event.altKey && event.ctrlKey && !event.shiftKey ? "ctrl-alt" :
event.altKey && event.shiftKey && event.ctrlKey ? "ctrl-alt-shift" : "normal";
};
KeyboardManager.prototype.getShortcutTiddlerList = function() {
return $tw.wiki.getTiddlersWithTag("$:/tags/KeyboardShortcut");
};

View File

@@ -27,7 +27,7 @@ exports.params = [
Run the macro
*/
exports.run = function(filter,spaces) {
return this.wiki.getTiddlersAsJson(filter,$tw.utils.parseInt(spaces));
return this.wiki.getTiddlersAsJson(filter,spaces);
};
})();

View File

@@ -60,7 +60,7 @@ var listTypes = {
"#": {listTag: "ol", itemTag: "li"},
";": {listTag: "dl", itemTag: "dt"},
":": {listTag: "dl", itemTag: "dd"},
">": {listTag: "blockquote", itemTag: "div"}
">": {listTag: "blockquote", itemTag: "p"}
};
/*

View File

@@ -153,7 +153,7 @@ SaverHandler.prototype.saveWiki = function(options) {
var self = this,
method = options.method || "save";
// Ignore autosave if disabled
if(method === "autosave" && ($tw.config.disableAutoSave || this.wiki.getTiddlerText(this.titleAutoSave,"yes") !== "yes")) {
if(method === "autosave" && this.wiki.getTiddlerText(this.titleAutoSave,"yes") !== "yes") {
return false;
}
var variables = options.variables || {},

View File

@@ -1,60 +0,0 @@
/*\
title: $:/core/modules/savers/custom.js
type: application/javascript
module-type: saver
Looks for `window.$tw.customSaver` first on the current window, then
on the parent window (of an iframe). If present, the saver must define
save: function(text,method,callback) { ... }
and the saver may define
priority: number
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var findSaver = function(window) {
try {
return window && window.$tw && window.$tw.customSaver;
} catch (err) {
// Catching the exception is the most reliable way to detect cross-origin iframe errors.
// For example, instead of saying that `window.parent.$tw` is undefined, Firefox will throw
// Uncaught DOMException: Permission denied to access property "$tw" on cross-origin object
console.log({ msg: "custom saver is disabled", reason: err });
return null;
}
}
var saver = findSaver(window) || findSaver(window.parent) || {};
var CustomSaver = function(wiki) {
};
CustomSaver.prototype.save = function(text,method,callback) {
return saver.save(text, method, callback);
};
/*
Information about this saver
*/
CustomSaver.prototype.info = {
name: "custom",
priority: saver.priority || 4000,
capabilities: ["save","autosave"]
};
/*
Static method that returns true if this saver is capable of working
*/
exports.canSave = function(wiki) {
return !!(saver.save);
};
/*
Create an instance of this saver
*/
exports.create = function(wiki) {
return new CustomSaver(wiki);
};
})();

View File

@@ -31,10 +31,10 @@ GiteaSaver.prototype.save = function(text,method,callback) {
headers = {
"Accept": "application/json",
"Content-Type": "application/json;charset=UTF-8",
"Authorization": "token " + password
"Authorization": "Basic " + window.btoa(username + ":" + password)
};
// Bail if we don't have everything we need
if(!username || !password || !repo || !filename) {
if(!username || !password || !repo || !path || !filename) {
return false;
}
// Make sure the path start and ends with a slash

View File

@@ -34,7 +34,7 @@ GitHubSaver.prototype.save = function(text,method,callback) {
"Authorization": "Basic " + window.btoa(username + ":" + password)
};
// Bail if we don't have everything we need
if(!username || !password || !repo || !filename) {
if(!username || !password || !repo || !path || !filename) {
return false;
}
// Make sure the path start and ends with a slash

View File

@@ -34,7 +34,7 @@ GitLabSaver.prototype.save = function(text,method,callback) {
"Private-Token": password
};
// Bail if we don't have everything we need
if(!username || !password || !repo || !filename) {
if(!username || !password || !repo || !path || !filename) {
return false;
}
// Make sure the path start and ends with a slash

View File

@@ -1,64 +0,0 @@
/*\
title: $:/core/modules/savers/hyperdrive.js
type: application/javascript
module-type: saver
Saves files using the Hyperdrive Protocol (https://hypercore-protocol.org/#hyperdrive) Beaker browser beta-1.0 and later (https://beakerbrowser.com)
Compatible with beaker >= V1.0.0
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Set up the saver
*/
var HyperdriveSaver = function(wiki) {
this.wiki = wiki;
};
HyperdriveSaver.prototype.save = function(text,method,callback) {
var dat = beaker.hyperdrive.drive("" + window.location),
pathname = ("" + window.location.pathname).split("#")[0];
dat.stat(pathname).then(function(value) {
if(value.isDirectory()) {
pathname = pathname + "/index.html";
}
dat.writeFile(pathname,text,"utf8").then(function(value) {
callback(null);
},function(reason) {
callback("Hyperdrive Saver Write Error: " + reason);
});
},function(reason) {
callback("Hyperdrive Saver Stat Error: " + reason);
});
return true;
};
/*
Information about this saver
*/
HyperdriveSaver.prototype.info = {
name: "beaker-1.x",
priority: 3000,
capabilities: ["save", "autosave"]
};
/*
Static method that returns true if this saver is capable of working
*/
exports.canSave = function(wiki) {
return !!window.beaker && !!beaker.hyperdrive && location.protocol==="hyper:";
};
/*
Create an instance of this saver
*/
exports.create = function(wiki) {
return new HyperdriveSaver(wiki);
};
})();

View File

@@ -31,7 +31,7 @@ BasicAuthenticator.prototype.init = function() {
// Read the credentials data
this.credentialsFilepath = this.server.get("credentials");
if(this.credentialsFilepath) {
var resolveCredentialsFilepath = path.resolve(this.server.boot.wikiPath,this.credentialsFilepath);
var resolveCredentialsFilepath = path.resolve($tw.boot.wikiPath,this.credentialsFilepath);
if(fs.existsSync(resolveCredentialsFilepath) && !fs.statSync(resolveCredentialsFilepath).isDirectory()) {
var credentialsText = fs.readFileSync(resolveCredentialsFilepath,"utf8"),
credentialsData = $tw.utils.parseCsvStringWithHeader(credentialsText);

View File

@@ -14,7 +14,7 @@ Authenticator for trusted header authentication
function HeaderAuthenticator(server) {
this.server = server;
this.header = server.get("authenticated-user-header") ? server.get("authenticated-user-header").toLowerCase() : undefined;
this.header = server.get("authenticated-user-header");
}
/*

View File

@@ -21,7 +21,7 @@ exports.handler = function(request,response,state) {
fs = require("fs"),
util = require("util"),
suppliedFilename = decodeURIComponent(state.params[0]),
filename = path.resolve(state.boot.wikiPath,"files",suppliedFilename),
filename = path.resolve($tw.boot.wikiPath,"files",suppliedFilename),
extension = path.extname(filename);
fs.readFile(filename,function(err,content) {
var status,content,type = "text/plain";

View File

@@ -3,7 +3,7 @@ title: $:/core/modules/server/routes/get-tiddlers-json.js
type: application/javascript
module-type: route
GET /recipes/default/tiddlers.json?filter=<filter>
GET /recipes/default/tiddlers/tiddlers.json?filter=<filter>
\*/
(function() {
@@ -20,9 +20,9 @@ exports.path = /^\/recipes\/default\/tiddlers.json$/;
exports.handler = function(request,response,state) {
var filter = state.queryParameters.filter || DEFAULT_FILTER;
if(state.wiki.getTiddlerText("$:/config/Server/AllowAllExternalFilters") !== "yes") {
if(state.wiki.getTiddlerText("$:/config/Server/ExternalFilters/" + filter) !== "yes") {
console.log("Blocked attempt to GET /recipes/default/tiddlers.json with filter: " + filter);
if($tw.wiki.getTiddlerText("$:/config/Server/AllowAllExternalFilters") !== "yes") {
if($tw.wiki.getTiddlerText("$:/config/Server/ExternalFilters/" + filter) !== "yes") {
console.log("Blocked attempt to GET /recipes/default/tiddlers/tiddlers.json with filter: " + filter);
response.writeHead(403);
response.end();
return;

View File

@@ -31,7 +31,6 @@ function Server(options) {
this.routes = options.routes || [];
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);
@@ -70,8 +69,8 @@ function Server(options) {
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")
key: fs.readFileSync(path.resolve($tw.boot.wikiPath,tlsKeyFilepath),"utf8"),
cert: fs.readFileSync(path.resolve($tw.boot.wikiPath,tlsCertFilepath),"utf8")
};
this.protocol = "https";
}
@@ -113,14 +112,15 @@ Server.prototype.addAuthenticator = function(AuthenticatorClass) {
};
Server.prototype.findMatchingRoute = function(request,state) {
var pathprefix = this.get("path-prefix") || "";
for(var t=0; t<this.routes.length; t++) {
var potentialRoute = this.routes[t],
pathRegExp = potentialRoute.path,
pathname = state.urlInfo.pathname,
match;
if(state.pathPrefix) {
if(pathname.substr(0,state.pathPrefix.length) === state.pathPrefix) {
pathname = pathname.substr(state.pathPrefix.length) || "/";
if(pathprefix) {
if(pathname.substr(0,pathprefix.length) === pathprefix) {
pathname = pathname.substr(pathprefix.length) || "/";
match = potentialRoute.path.exec(pathname);
} else {
match = false;
@@ -156,17 +156,14 @@ Server.prototype.isAuthorized = function(authorizationType,username) {
return principals.indexOf("(anon)") !== -1 || (username && (principals.indexOf("(authenticated)") !== -1 || principals.indexOf(username) !== -1));
}
Server.prototype.requestHandler = function(request,response,options) {
options = options || {};
Server.prototype.requestHandler = function(request,response) {
// Compose the state object
var self = this;
var state = {};
state.wiki = options.wiki || self.wiki;
state.boot = options.boot || self.boot;
state.wiki = self.wiki;
state.server = self;
state.urlInfo = url.parse(request.url);
state.queryParameters = querystring.parse(state.urlInfo.query);
state.pathPrefix = options.pathPrefix || this.get("path-prefix") || "";
// Get the principals authorized to access this resource
var authorizationType = this.methodMappings[request.method] || "readers";
// Check for the CSRF header if this is a write
@@ -251,7 +248,7 @@ Server.prototype.listen = function(port,host,prefix) {
port = process.env[port] || 8080;
}
// Warn if required plugins are missing
if(!this.wiki.getTiddler("$:/plugins/tiddlywiki/tiddlyweb") || !this.wiki.getTiddler("$:/plugins/tiddlywiki/filesystem")) {
if(!$tw.wiki.getTiddler("$:/plugins/tiddlywiki/tiddlyweb") || !$tw.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

View File

@@ -36,7 +36,7 @@ function setFavicon() {
var tiddler = $tw.wiki.getTiddler(FAVICON_TITLE);
if(tiddler) {
var faviconLink = document.getElementById("faviconLink");
faviconLink.setAttribute("href",$tw.utils.makeDataUri(tiddler.fields.text,tiddler.fields.type,tiddler.fields._canonical_uri));
faviconLink.setAttribute("href","data:" + tiddler.fields.type + ";base64," + tiddler.fields.text);
}
}

View File

@@ -106,8 +106,6 @@ exports.startup = function() {
// Fix up the link between the root widget and the page container
$tw.rootWidget.domNodes = [$tw.pageContainer];
$tw.rootWidget.children = [$tw.pageWidgetNode];
// Run any post-render startup actions
$tw.rootWidget.executeStartupTiddlers("$:/tags/StartupAction/PostRender");
};
})();

View File

@@ -64,12 +64,17 @@ exports.startup = function() {
document: $tw.browser ? document : $tw.fakeDocument
});
// Execute any startup actions
$tw.rootWidget.executeStartupTiddlers("$:/tags/StartupAction");
var executeStartupTiddlers = function(tag) {
$tw.utils.each($tw.wiki.filterTiddlers("[all[shadows+tiddlers]tag[" + tag + "]!has[draft.of]]"),function(title) {
$tw.rootWidget.invokeActionString($tw.wiki.getTiddlerText(title),$tw.rootWidget);
});
};
executeStartupTiddlers("$:/tags/StartupAction");
if($tw.browser) {
$tw.rootWidget.executeStartupTiddlers("$:/tags/StartupAction/Browser");
executeStartupTiddlers("$:/tags/StartupAction/Browser");
}
if($tw.node) {
$tw.rootWidget.executeStartupTiddlers("$:/tags/StartupAction/Node");
executeStartupTiddlers("$:/tags/StartupAction/Node");
}
// Kick off the language manager and switcher
$tw.language = new $tw.Language();

View File

@@ -150,11 +150,6 @@ function openStartupTiddlers(options) {
// Save the story list
$tw.wiki.addTiddler({title: DEFAULT_STORY_TITLE, text: "", list: storyList},$tw.wiki.getModificationFields());
// Update history
var story = new $tw.Story({
wiki: $tw.wiki,
storyTitle: DEFAULT_STORY_TITLE,
historyTitle: DEFAULT_HISTORY_TITLE
});
if(!options.disableHistory) {
// If a target tiddler was specified add it to the history stack
if(target && target !== "") {
@@ -162,9 +157,9 @@ function openStartupTiddlers(options) {
if(target.indexOf("[[") === 0 && target.substr(-2) === "]]") {
target = target.substr(2,target.length - 4);
}
story.addToHistory(target);
$tw.wiki.addToHistory(target);
} else if(storyList.length > 0) {
story.addToHistory(storyList[0]);
$tw.wiki.addToHistory(storyList[0]);
}
}
}

View File

@@ -37,44 +37,48 @@ Story.prototype.getStoryList = function() {
Story.prototype.addToStory = function(navigateTo,navigateFromTitle,options) {
options = options || {};
var storyList = this.getStoryList();
// See if the tiddler is already there
var slot = storyList.indexOf(navigateTo);
// Quit if it already exists in the story river
if(slot >= 0) {
return;
}
// First we try to find the position of the story element we navigated from
var fromIndex = storyList.indexOf(navigateFromTitle);
if(fromIndex >= 0) {
// The tiddler is added from inside the river
// Determine where to insert the tiddler; Fallback is "below"
switch(options.openLinkFromInsideRiver) {
case "top":
slot = 0;
break;
case "bottom":
slot = storyList.length;
break;
case "above":
slot = fromIndex;
break;
case "below": // Intentional fall-through
default:
slot = fromIndex + 1;
break;
}
if(options.singleTiddlerMode) {
storyList = [navigateTo];
} else {
// The tiddler is opened from outside the river. Determine where to insert the tiddler; default is "top"
if(options.openLinkFromOutsideRiver === "bottom") {
// Insert at bottom
slot = storyList.length;
} else {
// Insert at top
slot = 0;
// See if the tiddler is already there
var slot = storyList.indexOf(navigateTo);
// Quit if it already exists in the story river
if(slot >= 0) {
return;
}
// First we try to find the position of the story element we navigated from
var fromIndex = storyList.indexOf(navigateFromTitle);
if(fromIndex >= 0) {
// The tiddler is added from inside the river
// Determine where to insert the tiddler; Fallback is "below"
switch(options.openLinkFromInsideRiver) {
case "top":
slot = 0;
break;
case "bottom":
slot = storyList.length;
break;
case "above":
slot = fromIndex;
break;
case "below": // Intentional fall-through
default:
slot = fromIndex + 1;
break;
}
} else {
// The tiddler is opened from outside the river. Determine where to insert the tiddler; default is "top"
if(options.openLinkFromOutsideRiver === "bottom") {
// Insert at bottom
slot = storyList.length;
} else {
// Insert at top
slot = 0;
}
}
// Add the tiddler
storyList.splice(slot,0,navigateTo);
}
// Add the tiddler
storyList.splice(slot,0,navigateTo);
// Save the story
this.saveStoryList(storyList);
};
@@ -93,11 +97,20 @@ Story.prototype.saveStoryList = function(storyList) {
Story.prototype.addToHistory = function(navigateTo,navigateFromClientRect) {
var titles = $tw.utils.isArray(navigateTo) ? navigateTo : [navigateTo];
// Add a new record to the top of the history stack
var historyList = this.wiki.getTiddlerData(this.historyTitle,[]);
var historyList = this.wiki.getTiddlerData(this.historyTitle,[]),
historyTitles = this.wiki.getTiddlerList(this.historyTitle);
$tw.utils.each(titles,function(title) {
historyList.push({title: title, fromPageRect: navigateFromClientRect});
var p;
do {
p = historyTitles.indexOf(title);
if(p !== -1) {
historyTitles.splice(p,1);
}
} while(p !== -1);
historyTitles.unshift(title);
});
this.wiki.setTiddlerData(this.historyTitle,historyList,{"current-tiddler": titles[titles.length-1]});
this.wiki.setTiddlerData(this.historyTitle,historyList,{"current-tiddler": titles[titles.length-1], list: historyTitles});
};
Story.prototype.storyCloseTiddler = function(targetTitle) {

View File

@@ -0,0 +1,23 @@
/*\
title: $:/core/modules/storyviews/solo.js
type: application/javascript
module-type: storyview
Flip between individual tiddlers
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var SoloListView = function(listWidget) {
};
// Engage single tiddler mode
SoloListView.singleTiddlerMode = true;
exports.solo = SoloListView;
})();

View File

@@ -39,6 +39,9 @@ var ZoominListView = function(listWidget) {
});
};
// Engage single tiddler mode
ZoominListView.singleTiddlerMode = true;
ZoominListView.prototype.navigateTo = function(historyInfo) {
var duration = $tw.utils.getAnimationDuration(),
listElementIndex = this.listWidget.findListItem(0,historyInfo.title);

View File

@@ -113,16 +113,8 @@ function Syncer(options) {
return confirmationMessage;
});
// Listen out for login/logout/refresh events in the browser
$tw.rootWidget.addEventListener("tm-login",function(event) {
var username = event && event.paramObject && event.paramObject.username,
password = event && event.paramObject && event.paramObject.password;
if(username && password) {
// Login with username and password
self.login(username,password,function() {});
} else {
// No username and password, so we display a prompt
self.handleLoginEvent();
}
$tw.rootWidget.addEventListener("tm-login",function() {
self.handleLoginEvent();
});
$tw.rootWidget.addEventListener("tm-logout",function() {
self.handleLogoutEvent();
@@ -135,7 +127,7 @@ function Syncer(options) {
});
}
// Listen out for lazyLoad events
if(!this.disableUI && this.wiki.getTiddlerText(this.titleSyncDisableLazyLoading) !== "yes") {
if(!this.disableUI && $tw.wiki.getTiddlerText(this.titleSyncDisableLazyLoading) !== "yes") {
this.wiki.addEventListener("lazyLoad",function(title) {
self.handleLazyLoadEvent(title);
});
@@ -188,14 +180,12 @@ Syncer.prototype.readTiddlerInfo = function() {
var self = this,
tiddlers = this.getSyncedTiddlers();
$tw.utils.each(tiddlers,function(title) {
var tiddler = self.wiki.getTiddler(title);
if(tiddler) {
self.tiddlerInfo[title] = {
revision: self.getTiddlerRevision(title),
adaptorInfo: self.syncadaptor && self.syncadaptor.getTiddlerInfo(tiddler),
changeCount: self.wiki.getChangeCount(title)
};
}
var tiddler = self.wiki.tiddlerExists(title) && self.wiki.getTiddler(title);
self.tiddlerInfo[title] = {
revision: self.getTiddlerRevision(title),
adaptorInfo: self.syncadaptor && self.syncadaptor.getTiddlerInfo(tiddler),
changeCount: self.wiki.getChangeCount(title)
};
});
};
@@ -212,7 +202,7 @@ Syncer.prototype.isDirty = function() {
if(this.wiki.tiddlerExists(title)) {
if(tiddlerInfo) {
// If the tiddler is known on the server and has been modified locally then it needs to be saved to the server
if(this.wiki.getChangeCount(title) > tiddlerInfo.changeCount) {
if($tw.wiki.getChangeCount(title) > tiddlerInfo.changeCount) {
return true;
}
} else {
@@ -408,27 +398,15 @@ Syncer.prototype.handleLoginEvent = function() {
var self = this;
this.getStatus(function(err,isLoggedIn,username) {
if(!err && !isLoggedIn) {
if(self.syncadaptor && self.syncadaptor.displayLoginPrompt) {
self.syncadaptor.displayLoginPrompt(self);
} else {
self.displayLoginPrompt();
}
}
});
};
/*
Dispay a password prompt
*/
Syncer.prototype.displayLoginPrompt = function() {
var self = this;
var promptInfo = $tw.passwordPrompt.createPrompt({
serviceName: $tw.language.getString("LoginToTiddlySpace"),
callback: function(data) {
self.login(data.username,data.password,function(err,isLoggedIn) {
self.syncFromServer();
$tw.passwordPrompt.createPrompt({
serviceName: $tw.language.getString("LoginToTiddlySpace"),
callback: function(data) {
self.login(data.username,data.password,function(err,isLoggedIn) {
self.syncFromServer();
});
return true; // Get rid of the password prompt
}
});
return true; // Get rid of the password prompt
}
});
};
@@ -546,7 +524,7 @@ Syncer.prototype.chooseNextTask = function() {
tiddlerInfo = this.tiddlerInfo[title];
if(tiddler) {
// If the tiddler is not known on the server, or has been modified locally no more recently than the threshold then it needs to be saved to the server
var hasChanged = !tiddlerInfo || this.wiki.getChangeCount(title) > tiddlerInfo.changeCount,
var hasChanged = !tiddlerInfo || $tw.wiki.getChangeCount(title) > tiddlerInfo.changeCount,
isReadyToSave = !tiddlerInfo || !tiddlerInfo.timestampLastSaved || tiddlerInfo.timestampLastSaved < thresholdLastSaved;
if(hasChanged) {
if(isReadyToSave) {
@@ -603,8 +581,6 @@ SaveTiddlerTask.prototype.run = function(callback) {
};
// Invoke the callback
callback(null);
},{
tiddlerInfo: self.syncer.tiddlerInfo[self.title]
});
} else {
this.syncer.logger.log(" Not Dispatching 'save' task:",this.title,"tiddler does not exist");

View File

@@ -41,7 +41,7 @@ exports.upgrade = function(wiki,titles,tiddlers) {
// Check if we're dealing with a plugin
if(incomingTiddler && incomingTiddler["plugin-type"]) {
// Check whether the plugin contains JS modules
var requiresReload = wiki.doesPluginInfoRequireReload(JSON.parse(incomingTiddler.text)) ? (wiki.getTiddlerText("$:/language/ControlPanel/Plugins/PluginWillRequireReload") + " ") : "";
var requiresReload = $tw.wiki.doesPluginInfoRequireReload(JSON.parse(incomingTiddler.text)) ? ($tw.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

@@ -20,27 +20,15 @@
for (i; i < string.length; i++) {
charCode = string.charCodeAt(i);
if (charCode < 128) {
if (charCode < 128)
output += String.fromCharCode(charCode);
} else if ((charCode > 127) && (charCode < 2048)) {
output += String.fromCharCode((charCode >> 6) | 192);
else if ((charCode > 127) && (charCode < 2048))
output += String.fromCharCode((charCode >> 6) | 192),
output += String.fromCharCode((charCode & 63) | 128);
} else if ((charCode > 55295) && (charCode < 57344) && string.length > i+1) {
// Surrogate pair
var hiSurrogate = charCode;
var loSurrogate = string.charCodeAt(i+1);
i++; // Skip the low surrogate on the next loop pass
var codePoint = (((hiSurrogate - 55296) << 10) | (loSurrogate - 56320)) + 65536;
output += String.fromCharCode((codePoint >> 18) | 240);
output += String.fromCharCode(((codePoint >> 12) & 63) | 128);
output += String.fromCharCode(((codePoint >> 6) & 63) | 128);
output += String.fromCharCode((codePoint & 63) | 128);
} else {
// Not a surrogate pair, or a dangling surrogate without its partner that we'll just encode as-is
output += String.fromCharCode((charCode >> 12) | 224);
output += String.fromCharCode(((charCode >> 6) & 63) | 128);
else
output += String.fromCharCode((charCode >> 12) | 224),
output += String.fromCharCode(((charCode >> 6) & 63) | 128),
output += String.fromCharCode((charCode & 63) | 128);
}
}
return output;
@@ -53,21 +41,15 @@
while (i < string.length) {
charCode = string.charCodeAt(i);
if (charCode < 128) {
if (charCode < 128)
output += String.fromCharCode(charCode),
i++;
} else if ((charCode > 191) && (charCode < 224)) {
output += String.fromCharCode(((charCode & 31) << 6) | (string.charCodeAt(i + 1) & 63));
else if ((charCode > 191) && (charCode < 224))
output += String.fromCharCode(((charCode & 31) << 6) | (string.charCodeAt(i + 1) & 63)),
i += 2;
} else if ((charCode > 223) && (charCode < 240)) {
output += String.fromCharCode(((charCode & 15) << 12) | ((string.charCodeAt(i + 1) & 63) << 6) | (string.charCodeAt(i + 2) & 63));
else
output += String.fromCharCode(((charCode & 15) << 12) | ((string.charCodeAt(i + 1) & 63) << 6) | (string.charCodeAt(i + 2) & 63)),
i += 3;
} else {
var codePoint = ((charCode & 7) << 18) | ((string.charCodeAt(i + 1) & 63) << 12) | ((string.charCodeAt(i + 2) & 63) << 6) | (string.charCodeAt(i + 3) & 63);
// output += String.fromCodePoint(codePoint); // Can't do this because Internet Explorer doesn't have String.fromCodePoint
output += String.fromCharCode(((codePoint - 65536) >> 10) + 55296) + String.fromCharCode(((codePoint - 65536) & 1023) + 56320); // So we do this instead
i += 4;
}
}
return output;

View File

@@ -6,4 +6,4 @@
//
// copyright: MIT
// author: Nijiko Yonskai, @nijikokun, nijikokun@gmail.com
!function(r,e,o,t){void 0!==o.module&&o.module.exports?o.module.exports=e.apply(o):void 0!==o.define&&"function"===o.define&&o.define.amd?define("utf8",[],e):o.utf8=e.apply(o)}(0,function(){return{encode:function(r){if("string"!=typeof r)return r;r=r.replace(/\r\n/g,"\n");for(var e,o="",t=0;t<r.length;t++)if((e=r.charCodeAt(t))<128)o+=String.fromCharCode(e);else if(e>127&&e<2048)o+=String.fromCharCode(e>>6|192),o+=String.fromCharCode(63&e|128);else if(e>55295&&e<57344&&r.length>t+1){var i=e,n=r.charCodeAt(t+1);t++;var d=65536+(i-55296<<10|n-56320);o+=String.fromCharCode(d>>18|240),o+=String.fromCharCode(d>>12&63|128),o+=String.fromCharCode(d>>6&63|128),o+=String.fromCharCode(63&d|128)}else o+=String.fromCharCode(e>>12|224),o+=String.fromCharCode(e>>6&63|128),o+=String.fromCharCode(63&e|128);return o},decode:function(r){if("string"!=typeof r)return r;for(var e="",o=0,t=0;o<r.length;)if((t=r.charCodeAt(o))<128)e+=String.fromCharCode(t),o++;else if(t>191&&t<224)e+=String.fromCharCode((31&t)<<6|63&r.charCodeAt(o+1)),o+=2;else if(t>223&&t<240)e+=String.fromCharCode((15&t)<<12|(63&r.charCodeAt(o+1))<<6|63&r.charCodeAt(o+2)),o+=3;else{var i=(7&t)<<18|(63&r.charCodeAt(o+1))<<12|(63&r.charCodeAt(o+2))<<6|63&r.charCodeAt(o+3);e+=String.fromCharCode(55296+(i-65536>>10))+String.fromCharCode(56320+(i-65536&1023)),o+=4}return e}}},this),function(r,e,o,t){if(void 0!==o.module&&o.module.exports){if(t&&o.require)for(var i=0;i<t.length;i++)o[t[i]]=o.require(t[i]);o.module.exports=e.apply(o)}else void 0!==o.define&&"function"===o.define&&o.define.amd?define("base64",t||[],e):o.base64=e.apply(o)}(0,function(r){var e=r||this.utf8,o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";return{encode:function(r){if(void 0===e)throw{error:"MissingMethod",message:"UTF8 Module is missing."};if("string"!=typeof r)return r;r=e.encode(r);for(var t,i,n,d,f,a,h,C="",c=0;c<r.length;)d=(t=r.charCodeAt(c++))>>2,f=(3&t)<<4|(i=r.charCodeAt(c++))>>4,a=(15&i)<<2|(n=r.charCodeAt(c++))>>6,h=63&n,isNaN(i)?a=h=64:isNaN(n)&&(h=64),C+=o.charAt(d)+o.charAt(f)+o.charAt(a)+o.charAt(h);return C},decode:function(r){if(void 0===e)throw{error:"MissingMethod",message:"UTF8 Module is missing."};if("string"!=typeof r)return r;r=r.replace(/[^A-Za-z0-9\+\/\=]/g,"");for(var t,i,n,d,f,a,h="",C=0;C<r.length;)t=o.indexOf(r.charAt(C++))<<2|(d=o.indexOf(r.charAt(C++)))>>4,i=(15&d)<<4|(f=o.indexOf(r.charAt(C++)))>>2,n=(3&f)<<6|(a=o.indexOf(r.charAt(C++))),h+=String.fromCharCode(t),64!=f&&(h+=String.fromCharCode(i)),64!=a&&(h+=String.fromCharCode(n));return e.decode(h)}}},this,["utf8"]);
!function(r,e,o,t){void 0!==o.module&&o.module.exports?o.module.exports=e.apply(o):void 0!==o.define&&"function"===o.define&&o.define.amd?define("utf8",[],e):o.utf8=e.apply(o)}(0,function(){return{encode:function(r){if("string"!=typeof r)return r;r=r.replace(/\r\n/g,"\n");for(var e,o="",t=0;t<r.length;t++)(e=r.charCodeAt(t))<128?o+=String.fromCharCode(e):e>127&&e<2048?(o+=String.fromCharCode(e>>6|192),o+=String.fromCharCode(63&e|128)):(o+=String.fromCharCode(e>>12|224),o+=String.fromCharCode(e>>6&63|128),o+=String.fromCharCode(63&e|128));return o},decode:function(r){if("string"!=typeof r)return r;for(var e="",o=0,t=0;o<r.length;)(t=r.charCodeAt(o))<128?(e+=String.fromCharCode(t),o++):t>191&&t<224?(e+=String.fromCharCode((31&t)<<6|63&r.charCodeAt(o+1)),o+=2):(e+=String.fromCharCode((15&t)<<12|(63&r.charCodeAt(o+1))<<6|63&r.charCodeAt(o+2)),o+=3);return e}}},this),function(r,e,o,t){if(void 0!==o.module&&o.module.exports){if(t&&o.require)for(var n=0;n<t.length;n++)o[t[n]]=o.require(t[n]);o.module.exports=e.apply(o)}else void 0!==o.define&&"function"===o.define&&o.define.amd?define("base64",t||[],e):o.base64=e.apply(o)}(0,function(r){var e=r||this.utf8,o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";return{encode:function(r){if(void 0===e)throw{error:"MissingMethod",message:"UTF8 Module is missing."};if("string"!=typeof r)return r;r=e.encode(r);for(var t,n,i,d,f,a,h,c="",u=0;u<r.length;)d=(t=r.charCodeAt(u++))>>2,f=(3&t)<<4|(n=r.charCodeAt(u++))>>4,a=(15&n)<<2|(i=r.charCodeAt(u++))>>6,h=63&i,isNaN(n)?a=h=64:isNaN(i)&&(h=64),c+=o.charAt(d)+o.charAt(f)+o.charAt(a)+o.charAt(h);return c},decode:function(r){if(void 0===e)throw{error:"MissingMethod",message:"UTF8 Module is missing."};if("string"!=typeof r)return r;r=r.replace(/[^A-Za-z0-9\+\/\=]/g,"");for(var t,n,i,d,f,a,h="",c=0;c<r.length;)t=o.indexOf(r.charAt(c++))<<2|(d=o.indexOf(r.charAt(c++)))>>4,n=(15&d)<<4|(f=o.indexOf(r.charAt(c++)))>>2,i=(3&f)<<6|(a=o.indexOf(r.charAt(c++))),h+=String.fromCharCode(t),64!=f&&(h+=String.fromCharCode(n)),64!=a&&(h+=String.fromCharCode(i));return e.decode(h)}}},this,["utf8"]);

View File

@@ -29,23 +29,23 @@ exports.removeChildren = function(node) {
};
exports.hasClass = function(el,className) {
return el && el.hasAttribute && el.hasAttribute("class") && el.getAttribute("class").split(" ").indexOf(className) !== -1;
return el && el.className && el.className.toString().split(" ").indexOf(className) !== -1;
};
exports.addClass = function(el,className) {
var c = (el.getAttribute("class") || "").split(" ");
var c = el.className.split(" ");
if(c.indexOf(className) === -1) {
c.push(className);
el.setAttribute("class",c.join(" "));
el.className = c.join(" ");
}
};
exports.removeClass = function(el,className) {
var c = (el.getAttribute("class") || "").split(" "),
var c = el.className.split(" "),
p = c.indexOf(className);
if(p !== -1) {
c.splice(p,1);
el.setAttribute("class",c.join(" "));
el.className = c.join(" ");
}
};

View File

@@ -24,16 +24,6 @@ exports.httpRequest = function(options) {
var type = options.type || "GET",
url = options.url,
headers = options.headers || {accept: "application/json"},
hasHeader = function(targetHeader) {
targetHeader = targetHeader.toLowerCase();
var result = false;
$tw.utils.each(headers,function(header,headerTitle,object) {
if(headerTitle.toLowerCase() === targetHeader) {
result = true;
}
});
return result;
},
returnProp = options.returnProp || "responseText",
request = new XMLHttpRequest(),
data = "",
@@ -73,10 +63,10 @@ exports.httpRequest = function(options) {
request.setRequestHeader(headerTitle,header);
});
}
if(data && !hasHeader("Content-Type")) {
request.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
if(data && !$tw.utils.hop(headers,"Content-type")) {
request.setRequestHeader("Content-type","application/x-www-form-urlencoded; charset=UTF-8");
}
if(!hasHeader("X-Requested-With")) {
if(!$tw.utils.hop(headers,"X-Requested-With")) {
request.setRequestHeader("X-Requested-With","TiddlyWiki");
}
try {

View File

@@ -49,12 +49,7 @@ Handle an event
*/
PageScroller.prototype.handleEvent = function(event) {
if(event.type === "tm-scroll") {
if(event.paramObject && event.paramObject.selector) {
this.scrollSelectorIntoView(null,event.paramObject.selector);
} else {
this.scrollIntoView(event.target);
}
return false; // Event was handled
return this.scrollIntoView(event.target);
}
return true;
};
@@ -122,14 +117,6 @@ PageScroller.prototype.scrollIntoView = function(element,callback) {
drawFrame();
};
PageScroller.prototype.scrollSelectorIntoView = function(baseElement,selector,callback) {
baseElement = baseElement || document.body;
var element = baseElement.querySelector(selector);
if(element) {
this.scrollIntoView(element,callback);
}
};
exports.PageScroller = PageScroller;
})();

View File

@@ -21,32 +21,14 @@ var bumpSequenceNumber = function(object) {
}
};
var TW_Node = function (){
throw TypeError("Illegal constructor");
};
Object.defineProperty(TW_Node.prototype, 'ELEMENT_NODE', {
get: function() {
return 1;
}
});
Object.defineProperty(TW_Node.prototype, 'TEXT_NODE', {
get: function() {
return 3;
}
});
var TW_TextNode = function(text) {
bumpSequenceNumber(this);
this.textContent = text + "";
};
TW_TextNode.prototype = Object.create(TW_Node.prototype);
Object.defineProperty(TW_TextNode.prototype, "nodeType", {
get: function() {
return this.TEXT_NODE;
return 3;
}
});
@@ -67,8 +49,6 @@ var TW_Element = function(tag,namespace) {
this.namespaceURI = namespace || "http://www.w3.org/1999/xhtml";
};
TW_Element.prototype = Object.create(TW_Node.prototype);
Object.defineProperty(TW_Element.prototype, "style", {
get: function() {
return this._style;
@@ -89,7 +69,7 @@ Object.defineProperty(TW_Element.prototype, "style", {
Object.defineProperty(TW_Element.prototype, "nodeType", {
get: function() {
return this.ELEMENT_NODE;
return 1;
}
});

View File

@@ -15,33 +15,13 @@ File system utilities
var fs = require("fs"),
path = require("path");
/*
Return the subdirectories of a path
*/
exports.getSubdirectories = function(dirPath) {
if(!$tw.utils.isDirectory(dirPath)) {
return null;
}
var subdirs = [];
$tw.utils.each(fs.readdirSync(dirPath),function(item) {
if($tw.utils.isDirectory(path.resolve(dirPath,item))) {
subdirs.push(item);
}
});
return subdirs;
}
/*
Recursively (and synchronously) copy a directory and all its content
*/
exports.copyDirectory = function(srcPath,dstPath) {
// Remove any trailing path separators
srcPath = path.resolve($tw.utils.removeTrailingSeparator(srcPath));
dstPath = path.resolve($tw.utils.removeTrailingSeparator(dstPath));
// Check that neither director is within the other
if(srcPath.substring(0,dstPath.length) === dstPath || dstPath.substring(0,srcPath.length) === srcPath) {
return "Cannot copy nested directories";
}
srcPath = $tw.utils.removeTrailingSeparator(srcPath);
dstPath = $tw.utils.removeTrailingSeparator(dstPath);
// Create the destination directory
var err = $tw.utils.createDirectory(dstPath);
if(err) {

View File

@@ -94,36 +94,6 @@ exports.trim = function(str) {
}
};
exports.trimPrefix = function(str,unwanted) {
if(typeof str === "string" && typeof unwanted === "string") {
if(unwanted === "") {
return str.replace(/^\s\s*/, '');
} else {
// Safely regexp-escape the unwanted text
unwanted = unwanted.replace(/[\\^$*+?.()|[\]{}]/g, '\\$&');
var regex = new RegExp('^(' + unwanted + ')+');
return str.replace(regex, '');
}
} else {
return str;
}
};
exports.trimSuffix = function(str,unwanted) {
if(typeof str === "string" && typeof unwanted === "string") {
if(unwanted === "") {
return str.replace(/\s\s*$/, '');
} else {
// Safely regexp-escape the unwanted text
unwanted = unwanted.replace(/[\\^$*+?.()|[\]{}]/g, '\\$&');
var regex = new RegExp('(' + unwanted + ')+$');
return str.replace(regex, '');
}
} else {
return str;
}
};
/*
Convert a string to sentence case (ie capitalise first letter)
*/
@@ -831,57 +801,4 @@ exports.getSystemInfo = function(str,ending,position) {
return results.join("\n");
};
exports.parseNumber = function(str) {
return parseFloat(str) || 0;
};
exports.parseInt = function(str) {
return parseInt(str,10) || 0;
};
exports.stringifyNumber = function(num) {
return num + "";
};
exports.makeCompareFunction = function(type,options) {
options = options || {};
var gt = options.invert ? -1 : +1,
lt = options.invert ? +1 : -1,
compare = function(a,b) {
if(a > b) {
return gt ;
} else if(a < b) {
return lt;
} else {
return 0;
}
},
types = {
"number": function(a,b) {
return compare($tw.utils.parseNumber(a),$tw.utils.parseNumber(b));
},
"integer": function(a,b) {
return compare($tw.utils.parseInt(a),$tw.utils.parseInt(b));
},
"string": function(a,b) {
return compare("" + a,"" +b);
},
"date": function(a,b) {
var dateA = $tw.utils.parseDate(a),
dateB = $tw.utils.parseDate(b);
if(!isFinite(dateA)) {
dateA = new Date(0);
}
if(!isFinite(dateB)) {
dateB = new Date(0);
}
return compare(dateA,dateB);
},
"version": function(a,b) {
return $tw.utils.compareVersions(a,b);
}
};
return (types[type] || types[options.defaultType] || types.number);
};
})();

View File

@@ -9,7 +9,7 @@ Action widget to create a new tiddler with a unique name and specified fields.
(function(){
/*jslint node: true, browser: true */
/*global $tw:false, require:false, exports:false */
/*global $tw: false */
"use strict";
var Widget = require("$:/core/modules/widgets/widget.js").widget;
@@ -36,15 +36,9 @@ Compute the internal state of the widget
*/
CreateTiddlerWidget.prototype.execute = function() {
this.actionBaseTitle = this.getAttribute("$basetitle");
this.hasBase = !!this.actionBaseTitle;
this.actionSaveTitle = this.getAttribute("$savetitle");
this.actionSaveDraftTitle = this.getAttribute("$savedrafttitle");
this.actionTimestamp = this.getAttribute("$timestamp","yes") === "yes";
//Following params are new since 5.1.22
this.actionTemplate = this.getAttribute("$template");
this.useTemplate = !!this.actionTemplate;
this.actionOverwrite = this.getAttribute("$overwrite","no");
};
/*
@@ -63,7 +57,7 @@ CreateTiddlerWidget.prototype.refresh = function(changedTiddlers) {
Invoke the action associated with this widget
*/
CreateTiddlerWidget.prototype.invokeAction = function(triggeringWidget,event) {
var title = this.wiki.getTiddlerText("$:/language/DefaultNewTiddlerTitle"), // Get the initial new-tiddler title
var title = this.wiki.generateNewTitle(this.actionBaseTitle),
fields = {},
creationFields,
modificationFields;
@@ -76,22 +70,7 @@ CreateTiddlerWidget.prototype.invokeAction = function(triggeringWidget,event) {
creationFields = this.wiki.getCreationFields();
modificationFields = this.wiki.getModificationFields();
}
if(this.hasBase && this.actionOverwrite === "no") {
title = this.wiki.generateNewTitle(this.actionBaseTitle);
} else if (this.hasBase && this.actionOverwrite === "yes") {
title = this.actionBaseTitle
}
// NO $basetitle BUT $template parameter is available
// the title MUST be unique, otherwise the template would be overwritten
if (!this.hasBase && this.useTemplate) {
title = this.wiki.generateNewTitle(this.actionTemplate);
} else if (!this.hasBase && !this.useTemplate) {
// If NO $basetitle AND NO $template use initial title
// DON'T overwrite any stuff
title = this.wiki.generateNewTitle(title);
}
var templateTiddler = this.wiki.getTiddler(this.actionTemplate) || {};
var tiddler = this.wiki.addTiddler(new $tw.Tiddler(templateTiddler.fields,creationFields,fields,modificationFields,{title: title}));
var tiddler = this.wiki.addTiddler(new $tw.Tiddler(creationFields,fields,modificationFields,{title: title}));
if(this.actionSaveTitle) {
this.wiki.setTextReference(this.actionSaveTitle,title,this.getVariable("currentTiddler"));
}

View File

@@ -57,7 +57,7 @@ Invoke the action associated with this widget
ActionPopupWidget.prototype.invokeAction = function(triggeringWidget,event) {
// Trigger the popup
var popupLocationRegExp = /^\((-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+)\)$/,
match = popupLocationRegExp.exec(this.actionCoords || "");
match = popupLocationRegExp.exec(this.actionCoords);
if(match) {
$tw.popup.triggerPopup({
domNode: null,
@@ -70,8 +70,6 @@ ActionPopupWidget.prototype.invokeAction = function(triggeringWidget,event) {
title: this.actionState,
wiki: this.wiki
});
} else {
$tw.popup.cancel(0);
}
return true; // Action was invoked
};

View File

@@ -46,9 +46,6 @@ BrowseWidget.prototype.render = function(parent,nextSibling) {
if(this.nwsaveas) {
domNode.setAttribute("nwsaveas",this.nwsaveas);
}
if(this.accept) {
domNode.setAttribute("accept",this.accept);
}
// Nw.js supports "webkitdirectory" and "nwdirectory" to allow a directory to be selected
if(this.webkitdirectory) {
domNode.setAttribute("webkitdirectory",this.webkitdirectory);
@@ -86,7 +83,6 @@ BrowseWidget.prototype.execute = function() {
this.param = this.getAttribute("param");
this.tooltip = this.getAttribute("tooltip");
this.nwsaveas = this.getAttribute("nwsaveas");
this.accept = this.getAttribute("accept");
this.webkitdirectory = this.getAttribute("webkitdirectory");
this.nwdirectory = this.getAttribute("nwdirectory");
};

View File

@@ -91,8 +91,7 @@ ButtonWidget.prototype.render = function(parent,nextSibling) {
handled = true;
}
if(self.actions) {
var modifierKey = $tw.keyboardManager.getEventModifierKeyDescriptor(event);
self.invokeActionString(self.actions,self,event,{modifier: modifierKey});
self.invokeActionString(self.actions,self,event);
}
if(handled) {
event.preventDefault();

View File

@@ -45,7 +45,7 @@ CountWidget.prototype.execute = function() {
if(this.filter) {
this.currentCount = this.wiki.filterTiddlers(this.filter,this).length;
} else {
this.currentCount = "0";
this.currentCount = undefined;
}
};

View File

@@ -39,7 +39,7 @@ DroppableWidget.prototype.render = function(parent,nextSibling) {
}
// Create element and assign classes
var domNode = this.document.createElement(tag),
classes = (this.droppableClass || "").split(" ");
classes = (this["class"] || "").split(" ");
classes.push("tc-droppable");
domNode.className = classes.join(" ");
// Add event handlers
@@ -75,9 +75,7 @@ DroppableWidget.prototype.leaveDrag = function(event) {
// Remove highlighting if we're leaving externally. The hacky second condition is to resolve a problem with Firefox whereby there is an erroneous dragenter event if the node being dragged is within the dropzone
if(this.currentlyEntered.length === 0 || (this.currentlyEntered.length === 1 && this.currentlyEntered[0] === $tw.dragInProgress)) {
this.currentlyEntered = [];
if(this.domNodes[0]) {
$tw.utils.removeClass(this.domNodes[0],"tc-dragover");
}
$tw.utils.removeClass(this.domNodes[0],"tc-dragover");
}
};
@@ -132,7 +130,8 @@ DroppableWidget.prototype.handleDropEvent = function(event) {
DroppableWidget.prototype.performActions = function(title,event) {
if(this.droppableActions) {
var modifierKey = $tw.keyboardManager.getEventModifierKeyDescriptor(event);
var modifierKey = event.ctrlKey && ! event.shiftKey ? "ctrl" : event.shiftKey && !event.ctrlKey ? "shift" :
event.ctrlKey && event.shiftKey ? "ctrl-shift" : "normal" ;
this.invokeActionString(this.droppableActions,this,event,{actionTiddler: title, modifier: modifierKey});
}
};

View File

@@ -35,7 +35,7 @@ DropZoneWidget.prototype.render = function(parent,nextSibling) {
this.execute();
// Create element
var domNode = this.document.createElement("div");
domNode.className = this.dropzoneClass || "tc-dropzone";
domNode.className = "tc-dropzone";
// Add event handlers
if(this.dropzoneEnable) {
$tw.utils.addEventListeners(domNode,[
@@ -113,7 +113,7 @@ DropZoneWidget.prototype.handleDragEndEvent = function(event) {
DropZoneWidget.prototype.handleDropEvent = function(event) {
var self = this,
readFileCallback = function(tiddlerFieldsArray) {
self.dispatchEvent({type: "tm-import-tiddlers", param: JSON.stringify(tiddlerFieldsArray), autoOpenOnImport: self.autoOpenOnImport, importTitle: self.importTitle});
self.dispatchEvent({type: "tm-import-tiddlers", param: JSON.stringify(tiddlerFieldsArray)});
};
this.leaveDrag(event);
// Check for being over a TEXTAREA or INPUT
@@ -149,7 +149,7 @@ DropZoneWidget.prototype.handleDropEvent = function(event) {
DropZoneWidget.prototype.handlePasteEvent = function(event) {
var self = this,
readFileCallback = function(tiddlerFieldsArray) {
self.dispatchEvent({type: "tm-import-tiddlers", param: JSON.stringify(tiddlerFieldsArray), autoOpenOnImport: self.autoOpenOnImport, importTitle: self.importTitle});
self.dispatchEvent({type: "tm-import-tiddlers", param: JSON.stringify(tiddlerFieldsArray)});
};
// Let the browser handle it if we're in a textarea or input box
if(["TEXTAREA","INPUT"].indexOf(event.target.tagName) == -1 && !event.target.isContentEditable) {
@@ -176,7 +176,7 @@ DropZoneWidget.prototype.handlePasteEvent = function(event) {
if($tw.log.IMPORT) {
console.log("Importing string '" + str + "', type: '" + type + "'");
}
self.dispatchEvent({type: "tm-import-tiddlers", param: JSON.stringify([tiddlerFields]), autoOpenOnImport: self.autoOpenOnImport, importTitle: self.importTitle});
self.dispatchEvent({type: "tm-import-tiddlers", param: JSON.stringify([tiddlerFields])});
});
}
}
@@ -190,11 +190,8 @@ DropZoneWidget.prototype.handlePasteEvent = function(event) {
Compute the internal state of the widget
*/
DropZoneWidget.prototype.execute = function() {
this.dropzoneClass = this.getAttribute("class");
this.dropzoneDeserializer = this.getAttribute("deserializer");
this.dropzoneEnable = (this.getAttribute("enable") || "yes") === "yes";
this.autoOpenOnImport = this.getAttribute("autoOpenOnImport");
this.importTitle = this.getAttribute("importTitle");
// Make child widgets
this.makeChildWidgets();
};
@@ -204,7 +201,7 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
*/
DropZoneWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(changedAttributes.enable || changedAttributes.autoOpenOnImport || changedAttributes.importTitle || changedAttributes.deserializer || changedAttributes.class) {
if(changedAttributes.enable) {
this.refreshSelf();
return true;
}

View File

@@ -48,15 +48,20 @@ EditWidget.prototype.execute = function() {
this.editPlaceholder = this.getAttribute("placeholder");
this.editTabIndex = this.getAttribute("tabindex");
this.editFocus = this.getAttribute("focus","");
this.editCancelPopups = this.getAttribute("cancelPopups","");
this.editInputActions = this.getAttribute("inputActions");
this.editRefreshTitle = this.getAttribute("refreshTitle");
// Choose the appropriate edit widget
this.editorType = this.getEditorType();
// Make the child widgets
this.makeChildWidgets([{
type: "edit-" + this.editorType,
attributes: this.parseTreeNode.attributes,
attributes: {
tiddler: {type: "string", value: this.editTitle},
field: {type: "string", value: this.editField},
index: {type: "string", value: this.editIndex},
"class": {type: "string", value: this.editClass},
"placeholder": {type: "string", value: this.editPlaceholder},
"tabindex": {type: "string", value: this.editTabIndex},
"focus": {type: "string", value: this.editFocus}
},
children: this.parseTreeNode.children
}]);
};
@@ -89,7 +94,7 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
EditWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
// Refresh if an attribute has changed, or the type associated with the target tiddler has changed
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.tabindex || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || (changedTiddlers[this.editTitle] && this.getEditorType() !== this.editorType)) {
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.tabindex || (changedTiddlers[this.editTitle] && this.getEditorType() !== this.editorType)) {
this.refreshSelf();
return true;
} else {

View File

@@ -29,47 +29,45 @@ Render this widget into the DOM
ElementWidget.prototype.render = function(parent,nextSibling) {
this.parentDomNode = parent;
this.computeAttributes();
this.execute();
// Neuter blacklisted elements
this.tag = this.parseTreeNode.tag;
if($tw.config.htmlUnsafeElements.indexOf(this.tag) !== -1) {
this.tag = "safe-" + this.tag;
var tag = this.parseTreeNode.tag;
if($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {
tag = "safe-" + tag;
}
// Adjust headings by the current base level
var headingLevel = ["h1","h2","h3","h4","h5","h6"].indexOf(this.tag);
var headingLevel = ["h1","h2","h3","h4","h5","h6"].indexOf(tag);
if(headingLevel !== -1) {
var baseLevel = parseInt(this.getVariable("tv-adjust-heading-level","0"),10) || 0;
headingLevel = Math.min(Math.max(headingLevel + 1 + baseLevel,1),6);
this.tag = "h" + headingLevel;
tag = "h" + headingLevel;
}
// Create the DOM node
var domNode = this.document.createElementNS(this.namespace,tag);
this.assignAttributes(domNode,{excludeEventAttributes: true});
parent.insertBefore(domNode,nextSibling);
this.renderChildren(domNode,null);
this.domNodes.push(domNode);
};
/*
Compute the internal state of the widget
*/
ElementWidget.prototype.execute = function() {
// Select the namespace for the tag
var tagNamespaces = {
svg: "http://www.w3.org/2000/svg",
math: "http://www.w3.org/1998/Math/MathML",
body: "http://www.w3.org/1999/xhtml"
};
this.namespace = tagNamespaces[this.tag];
this.namespace = tagNamespaces[this.parseTreeNode.tag];
if(this.namespace) {
this.setVariable("namespace",this.namespace);
} else {
this.namespace = this.getVariable("namespace",{defaultValue: "http://www.w3.org/1999/xhtml"});
}
// Invoke the th-rendering-element hook
var parseTreeNodes = $tw.hooks.invokeHook("th-rendering-element",null,this);
this.isReplaced = !!parseTreeNodes;
if(parseTreeNodes) {
// Use the parse tree nodes provided by the hook
this.makeChildWidgets(parseTreeNodes);
this.renderChildren(this.parentDomNode,null);
return;
}
// Make the child widgets
this.makeChildWidgets();
// Create the DOM node and render children
var domNode = this.document.createElementNS(this.namespace,this.tag);
this.assignAttributes(domNode,{excludeEventAttributes: true});
parent.insertBefore(domNode,nextSibling);
this.renderChildren(domNode,null);
this.domNodes.push(domNode);
};
/*
@@ -79,13 +77,8 @@ ElementWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes(),
hasChangedAttributes = $tw.utils.count(changedAttributes) > 0;
if(hasChangedAttributes) {
if(!this.isReplaced) {
// Update our attributes
this.assignAttributes(this.domNodes[0],{excludeEventAttributes: true});
} else {
// If we were replaced then completely refresh ourselves
return this.refreshSelf();
}
// Update our attributes
this.assignAttributes(this.domNodes[0],{excludeEventAttributes: true});
}
return this.refreshChildren(changedTiddlers) || hasChangedAttributes;
};

View File

@@ -28,7 +28,6 @@ Render this widget into the DOM
*/
EntityWidget.prototype.render = function(parent,nextSibling) {
this.parentDomNode = parent;
this.computeAttributes();
this.execute();
var entityString = this.getAttribute("entity",this.parseTreeNode.entity || ""),
textNode = this.document.createTextNode($tw.utils.entityDecode(entityString));

View File

@@ -42,53 +42,44 @@ FieldsWidget.prototype.execute = function() {
// Get parameters from our attributes
this.tiddlerTitle = this.getAttribute("tiddler",this.getVariable("currentTiddler"));
this.template = this.getAttribute("template");
this.sort = this.getAttribute("sort","yes") === "yes";
this.sortReverse = this.getAttribute("sortReverse","no") === "yes";
this.exclude = this.getAttribute("exclude");
this.include = this.getAttribute("include",null);
this.stripTitlePrefix = this.getAttribute("stripTitlePrefix","no") === "yes";
// Get the value to display
var tiddler = this.wiki.getTiddler(this.tiddlerTitle);
// Get the inclusion and exclusion list
var excludeArr = (this.exclude) ? this.exclude.split(" ") : ["text"];
// Include takes precedence
var includeArr = (this.include) ? this.include.split(" ") : null;
// Get the exclusion list
var exclude;
if(this.exclude) {
exclude = this.exclude.split(" ");
} else {
exclude = ["text"];
}
// Compose the template
var text = [];
if(this.template && tiddler) {
var fields = [];
if (includeArr) { // Include takes precedence
for(var i=0; i<includeArr.length; i++) {
if(tiddler.fields[includeArr[i]]) {
fields.push(includeArr[i]);
}
}
} else {
for(var fieldName in tiddler.fields) {
if(excludeArr.indexOf(fieldName) === -1) {
fields.push(fieldName);
}
for(var fieldName in tiddler.fields) {
if(exclude.indexOf(fieldName) === -1) {
fields.push(fieldName);
}
}
if (this.sort) fields.sort();
if (this.sortReverse) fields.reverse();
for(var f=0, fmax=fields.length; f<fmax; f++) {
fields.sort();
for(var f=0; f<fields.length; f++) {
fieldName = fields[f];
var row = this.template,
value = tiddler.getFieldString(fieldName);
if(this.stripTitlePrefix && fieldName === "title") {
var reStrip = /^\{[^\}]+\}(.+)/mg,
reMatch = reStrip.exec(value);
if(reMatch) {
value = reMatch[1];
if(exclude.indexOf(fieldName) === -1) {
var row = this.template,
value = tiddler.getFieldString(fieldName);
if(this.stripTitlePrefix && fieldName === "title") {
var reStrip = /^\{[^\}]+\}(.+)/mg,
reMatch = reStrip.exec(value);
if(reMatch) {
value = reMatch[1];
}
}
row = $tw.utils.replaceString(row,"$name$",fieldName);
row = $tw.utils.replaceString(row,"$value$",value);
row = $tw.utils.replaceString(row,"$encoded_value$",$tw.utils.htmlEncode(value));
text.push(row);
}
row = $tw.utils.replaceString(row,"$name$",fieldName);
row = $tw.utils.replaceString(row,"$value$",value);
row = $tw.utils.replaceString(row,"$encoded_value$",$tw.utils.htmlEncode(value));
text.push(row);
}
}
this.text = text.join("");
@@ -99,13 +90,11 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
*/
FieldsWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if( changedAttributes.tiddler || changedAttributes.template || changedAttributes.exclude ||
changedAttributes.include || changedAttributes.sort || changedAttributes.sortReverse ||
changedTiddlers[this.tiddlerTitle] || changedAttributes.stripTitlePrefix) {
this.refreshSelf();
return true;
if(changedAttributes.tiddler || changedAttributes.template || changedAttributes.exclude || changedAttributes.stripTitlePrefix || changedTiddlers[this.tiddlerTitle]) {
this.refreshSelf();
return true;
} else {
return false;
return false;
}
};

View File

@@ -38,8 +38,6 @@ Compute the internal state of the widget
*/
ImportVariablesWidget.prototype.execute = function(tiddlerList) {
var widgetPointer = this;
// Got to flush all the accumulated variables
this.variables = new this.variablesConstructor();
// Get our parameters
this.filter = this.getAttribute("filter");
// Compute the filter
@@ -72,14 +70,7 @@ ImportVariablesWidget.prototype.execute = function(tiddlerList) {
widgetPointer.variables[key] = widget.variables[key];
});
} else {
widgetPointer.children = [widgetPointer.makeChildWidget(node)];
// No more regenerating children for
// this widget. If it needs to refresh,
// it'll do so along with the the whole
// importvariable tree.
if (widgetPointer != this) {
widgetPointer.makeChildWidgets = function(){};
}
widgetPointer.makeChildWidgets([node]);
widgetPointer = widgetPointer.children[0];
}
parseTreeNode = parseTreeNode.children && parseTreeNode.children[0];

View File

@@ -60,8 +60,7 @@ LinkWidget.prototype.renderLink = function(parent,nextSibling) {
tag = "a";
}
// Create our element
var namespace = this.getVariable("namespace",{defaultValue: "http://www.w3.org/1999/xhtml"}),
domNode = this.document.createElementNS(namespace,tag);
var domNode = this.document.createElement(tag);
// Assign classes
var classes = [];
if(this.overrideClasses === undefined) {
@@ -103,8 +102,7 @@ LinkWidget.prototype.renderLink = function(parent,nextSibling) {
// Override with the value of tv-get-export-link if defined
wikiLinkText = this.getVariable("tv-get-export-link",{params: [{name: "to",value: this.to}],defaultValue: wikiLinkText});
if(tag === "a") {
var namespaceHref = (namespace === "http://www.w3.org/2000/svg") ? "http://www.w3.org/1999/xlink" : undefined;
domNode.setAttributeNS(namespaceHref,"href",wikiLinkText);
domNode.setAttribute("href",wikiLinkText);
}
// Set the tabindex
if(this.tabIndex) {
@@ -158,8 +156,7 @@ LinkWidget.prototype.handleClickEvent = function(event) {
metaKey: event.metaKey,
ctrlKey: event.ctrlKey,
altKey: event.altKey,
shiftKey: event.shiftKey,
event: event
shiftKey: event.shiftKey
});
if(this.domNodes[0].hasAttribute("href")) {
event.preventDefault();

View File

@@ -87,8 +87,7 @@ LinkCatcherWidget.prototype.handleNavigateEvent = function(event) {
}
if(this.catchActions) {
this.executingActions = true;
var modifierKey = $tw.keyboardManager.getEventModifierKeyDescriptor(event);
this.invokeActionString(this.catchActions,this,event,{navigateTo: event.navigateTo, modifier: modifierKey});
this.invokeActionString(this.catchActions,this,event,{navigateTo: event.navigateTo});
this.executingActions = false;
}
} else {

View File

@@ -87,14 +87,8 @@ ListWidget.prototype.getTiddlerList = function() {
};
ListWidget.prototype.getEmptyMessage = function() {
var parser,
emptyMessage = this.getAttribute("emptyMessage","");
// this.wiki.parseText() calls
// new Parser(..), which should only be done, if needed, because it's heavy!
if (emptyMessage === "") {
return [];
}
parser = this.wiki.parseText("text/vnd.tiddlywiki",emptyMessage,{parseAsInline: true});
var emptyMessage = this.getAttribute("emptyMessage",""),
parser = this.wiki.parseText("text/vnd.tiddlywiki",emptyMessage,{parseAsInline: true});
if(parser) {
return parser.tree;
} else {

View File

@@ -73,8 +73,6 @@ MacroCallWidget.prototype.execute = function() {
attributes: attributes,
children: parseTreeNodes
}];
} else if(this.renderOutput === "text/raw") {
parseTreeNodes = [{type: "text", text: text}];
} else {
// Otherwise, we'll render the text
var plainText = this.wiki.renderText("text/plain",this.parseType,text,{parentWidget: this});

View File

@@ -60,13 +60,12 @@ NavigatorWidget.prototype.execute = function() {
// Get our parameters
this.storyTitle = this.getAttribute("story");
this.historyTitle = this.getAttribute("history");
this.openLinkFromInsideRiver = this.getAttribute("openLinkFromInsideRiver","top");
this.openLinkFromOutsideRiver = this.getAttribute("openLinkFromOutsideRiver","top");
this.singleTiddlerMode = this.getAttribute("singleTiddlerMode","no") === "yes";
this.relinkOnRename = this.getAttribute("relinkOnRename","no").toLowerCase().trim() === "yes";
this.setVariable("tv-story-list",this.storyTitle);
this.setVariable("tv-history-list",this.historyTitle);
this.story = new $tw.Story({
wiki: this.wiki,
storyTitle: this.storyTitle,
historyTitle: this.historyTitle
});
// Construct the child widgets
this.makeChildWidgets();
};
@@ -76,7 +75,7 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
*/
NavigatorWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(changedAttributes.story || changedAttributes.history) {
if(changedAttributes.story || changedAttributes.history || changedAttributes.openLinkFromInsideRiver || changedAttributes.openLinkFromOutsideRiver || changedAttributes.singleTiddlerMode || changedAttributes.relinkOnRename) {
this.refreshSelf();
return true;
} else {
@@ -127,12 +126,17 @@ NavigatorWidget.prototype.replaceFirstTitleInStory = function(storyList,oldTitle
};
NavigatorWidget.prototype.addToStory = function(title,fromTitle) {
if(this.storyTitle) {
this.story.addToStory(title,fromTitle,this.storyTitle,{
openLinkFromInsideRiver: this.getAttribute("openLinkFromInsideRiver","top"),
openLinkFromOutsideRiver: this.getAttribute("openLinkFromOutsideRiver","top")
});
}
this.wiki.addToStory(title,fromTitle,this.storyTitle,{
openLinkFromInsideRiver: this.openLinkFromInsideRiver,
openLinkFromOutsideRiver: this.openLinkFromOutsideRiver,
singleTiddlerMode: this.singleTiddlerMode
});
};
NavigatorWidget.prototype.removeFromStory = function(title) {
var storyList = this.getStoryList();
this.removeTitleFromStory(storyList,title);
this.saveStoryList(storyList);
};
/*
@@ -141,7 +145,7 @@ title: a title string or an array of title strings
fromPageRect: page coordinates of the origin of the navigation
*/
NavigatorWidget.prototype.addToHistory = function(title,fromPageRect) {
this.story.addToHistory(title,fromPageRect,this.historyTitle);
this.wiki.addToHistory(title,fromPageRect,this.historyTitle);
};
/*
@@ -160,11 +164,34 @@ NavigatorWidget.prototype.handleNavigateEvent = function(event) {
// Close a specified tiddler
NavigatorWidget.prototype.handleCloseTiddlerEvent = function(event) {
var title = event.param || event.tiddlerTitle,
storyList = this.getStoryList();
// Look for tiddlers with this title to close
this.removeTitleFromStory(storyList,title);
this.saveStoryList(storyList);
var title = event.param || event.tiddlerTitle;
if(this.singleTiddlerMode) {
// Get the history stack and find the topmost occurance of the current tiddler
var history = this.wiki.getTiddlerDataCached(this.historyTitle,[]),
currPos = history.findIndex(function(historyRecord) {
return historyRecord.title === title;
}),
newTitle;
// Skip over any duplicates
while(currPos > 0 && history[currPos - 1].title === title) {
currPos--;
}
// Get the new title
if(currPos > 0) {
newTitle = history[currPos - 1].title;
}
// Navigate to the new title if we've got one
if(newTitle) {
this.addToStory(newTitle);
this.addToHistory(newTitle);
} else {
// If there's nothing to navigate back to then we really do close the last tiddler
this.removeFromStory(title);
}
} else {
// Look for tiddlers with this title to close
this.removeFromStory(title);
}
return false;
};
@@ -278,9 +305,7 @@ NavigatorWidget.prototype.makeDraftTiddler = function(targetTitle) {
var tiddler = this.wiki.getTiddler(targetTitle);
// Save the initial value of the draft tiddler
draftTitle = this.generateDraftTitle(targetTitle);
var draftTiddler = new $tw.Tiddler({
text: "",
},
var draftTiddler = new $tw.Tiddler(
tiddler,
{
title: draftTitle,
@@ -327,11 +352,11 @@ NavigatorWidget.prototype.handleSaveTiddlerEvent = function(event) {
"draft.title": undefined,
"draft.of": undefined
},this.wiki.getModificationFields());
newTiddler = $tw.hooks.invokeHook("th-saving-tiddler",newTiddler,tiddler);
newTiddler = $tw.hooks.invokeHook("th-saving-tiddler",newTiddler);
this.wiki.addTiddler(newTiddler);
// If enabled, relink references to renamed tiddler
var shouldRelink = this.getAttribute("relinkOnRename","no").toLowerCase().trim() === "yes";
if(isRename && shouldRelink && this.wiki.tiddlerExists(draftOf)) {
if(isRename && this.relinkOnRename && this.wiki.tiddlerExists(draftOf)) {
console.log("Relinking '" + draftOf + "' to '" + draftTitle + "'");
this.wiki.relinkTiddler(draftOf,draftTitle);
}
// Remove the draft tiddler
@@ -500,11 +525,10 @@ NavigatorWidget.prototype.handleImportTiddlersEvent = function(event) {
} catch(e) {
}
// Get the current $:/Import tiddler
var importTitle = event.importTitle ? event.importTitle : IMPORT_TITLE,
importTiddler = this.wiki.getTiddler(importTitle),
importData = this.wiki.getTiddlerData(importTitle,{}),
var importTiddler = this.wiki.getTiddler(IMPORT_TITLE),
importData = this.wiki.getTiddlerData(IMPORT_TITLE,{}),
newFields = new Object({
title: importTitle,
title: IMPORT_TITLE,
type: "application/json",
"plugin-type": "import",
"status": "pending"
@@ -535,16 +559,15 @@ NavigatorWidget.prototype.handleImportTiddlersEvent = function(event) {
newFields.text = JSON.stringify(importData,null,$tw.config.preferences.jsonSpaces);
this.wiki.addTiddler(new $tw.Tiddler(importTiddler,newFields));
// Update the story and history details
var autoOpenOnImport = event.autoOpenOnImport ? event.autoOpenOnImport : this.getVariable("tv-auto-open-on-import");
if(autoOpenOnImport !== "no") {
if(this.getVariable("tv-auto-open-on-import") !== "no") {
var storyList = this.getStoryList(),
history = [];
// Add it to the story
if(storyList && storyList.indexOf(importTitle) === -1) {
storyList.unshift(importTitle);
if(storyList && storyList.indexOf(IMPORT_TITLE) === -1) {
storyList.unshift(IMPORT_TITLE);
}
// And to history
history.push(importTitle);
history.push(IMPORT_TITLE);
// Save the updated story and history
this.saveStoryList(storyList);
this.addToHistory(history);
@@ -563,14 +586,10 @@ NavigatorWidget.prototype.handlePerformImportEvent = function(event) {
$tw.utils.each(importData.tiddlers,function(tiddlerFields) {
var title = tiddlerFields.title;
if(title && importTiddler && importTiddler.fields["selection-" + title] !== "unchecked") {
if($tw.utils.hop(importTiddler.fields,["rename-" + title])) {
var tiddler = new $tw.Tiddler(tiddlerFields,{title : importTiddler.fields["rename-" + title]});
} else {
var tiddler = new $tw.Tiddler(tiddlerFields);
}
var tiddler = new $tw.Tiddler(tiddlerFields);
tiddler = $tw.hooks.invokeHook("th-importing-tiddler",tiddler);
self.wiki.addTiddler(tiddler);
importReport.push("# [[" + tiddler.fields.title + "]]");
importReport.push("# [[" + tiddlerFields.title + "]]");
}
});
// Replace the $:/Import tiddler with an import report
@@ -621,13 +640,10 @@ NavigatorWidget.prototype.handleUnfoldAllTiddlersEvent = function(event) {
};
NavigatorWidget.prototype.handleRenameTiddlerEvent = function(event) {
var options = {},
paramObject = event.paramObject || {},
var 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);
this.wiki.renameTiddler(from,to);
};
exports.navigator = NavigatorWidget;

View File

@@ -49,8 +49,7 @@ RangeWidget.prototype.render = function(parent,nextSibling) {
this.inputDomNode.value = this.getValue();
// Add a click event handler
$tw.utils.addEventListeners(this.inputDomNode,[
{name: "input", handlerObject: this, handlerMethod: "handleInputEvent"},
{name: "change", handlerObject: this, handlerMethod: "handleInputEvent"}
{name: "input", handlerObject: this, handlerMethod: "handleInputEvent"}
]);
// Insert the label into the DOM and render any children
parent.insertBefore(this.inputDomNode,nextSibling);
@@ -125,4 +124,4 @@ RangeWidget.prototype.refresh = function(changedTiddlers) {
exports.range = RangeWidget;
})();
})();

View File

@@ -58,11 +58,7 @@ ScrollableWidget.prototype.handleScrollEvent = function(event) {
if(this.outerDomNode.scrollWidth <= this.outerDomNode.offsetWidth && this.outerDomNode.scrollHeight <= this.outerDomNode.offsetHeight && this.fallthrough === "yes") {
return true;
}
if(event.paramObject && event.paramObject.selector) {
this.scrollSelectorIntoView(null,event.paramObject.selector);
} else {
this.scrollIntoView(event.target);
}
this.scrollIntoView(event.target);
return false; // Handled event
};
@@ -70,8 +66,7 @@ ScrollableWidget.prototype.handleScrollEvent = function(event) {
Scroll an element into view
*/
ScrollableWidget.prototype.scrollIntoView = function(element) {
var duration = $tw.utils.getAnimationDuration(),
srcWindow = element ? element.ownerDocument.defaultView : window;
var duration = $tw.utils.getAnimationDuration();
this.cancelScroll();
this.startTime = Date.now();
var scrollPosition = {
@@ -127,21 +122,13 @@ ScrollableWidget.prototype.scrollIntoView = function(element) {
self.outerDomNode.scrollLeft = scrollPosition.x + (endX - scrollPosition.x) * t;
self.outerDomNode.scrollTop = scrollPosition.y + (endY - scrollPosition.y) * t;
if(t < 1) {
self.idRequestFrame = self.requestAnimationFrame.call(srcWindow,drawFrame);
self.idRequestFrame = self.requestAnimationFrame.call(window,drawFrame);
}
};
drawFrame();
}
};
ScrollableWidget.prototype.scrollSelectorIntoView = function(baseElement,selector,callback) {
baseElement = baseElement || document.body;
var element = baseElement.querySelector(selector);
if(element) {
this.scrollIntoView(element,callback);
}
};
/*
Render this widget into the DOM
*/

View File

@@ -421,7 +421,6 @@ Widget.prototype.addEventListener = function(type,handler) {
Dispatch an event to a widget. If the widget doesn't handle the event then it is also dispatched to the parent widget
*/
Widget.prototype.dispatchEvent = function(event) {
event.widget = event.widget || this;
// Dispatch the event if this widget handles it
var listener = this.eventListeners[event.type];
if(listener) {
@@ -571,16 +570,6 @@ Widget.prototype.invokeActionString = function(actions,triggeringWidget,event,va
return widgetNode.invokeActions(this,event);
};
/*
Execute action tiddlers by tag
*/
Widget.prototype.executeStartupTiddlers = function(tag) {
var self = this;
$tw.utils.each(self.wiki.filterTiddlers("[all[shadows+tiddlers]tag[" + tag + "]!has[draft.of]]"),function(title) {
self.invokeActionString(self.wiki.getTiddlerText(title),self);
});
};
Widget.prototype.allowActionPropagation = function() {
return true;
};

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