mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2026-01-23 11:24:40 +00:00
Compare commits
354 Commits
single-tid
...
full-text-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2340b1215b | ||
|
|
d5c4aa250a | ||
|
|
70561bd481 | ||
|
|
2f5f0db00f | ||
|
|
4a6aa865b3 | ||
|
|
f29d24a1f5 | ||
|
|
2818f52f95 | ||
|
|
9453c4d684 | ||
|
|
42b965c9f0 | ||
|
|
e9a635dc81 | ||
|
|
26ade60e93 | ||
|
|
e7245a709c | ||
|
|
a6efc14a7c | ||
|
|
9fbcdeb29e | ||
|
|
ef1b7d619a | ||
|
|
ec70e5c179 | ||
|
|
4de0dc301b | ||
|
|
769ffa19b7 | ||
|
|
635ec65d3f | ||
|
|
da06b64845 | ||
|
|
ecb3c86e7b | ||
|
|
c6cd4d33e6 | ||
|
|
77fe6244a2 | ||
|
|
f6e485b897 | ||
|
|
4b5d287c90 | ||
|
|
c01e9cef12 | ||
|
|
655501140b | ||
|
|
cae32d39a5 | ||
|
|
bc5609820f | ||
|
|
b8fa6f0f0a | ||
|
|
9605d94b6c | ||
|
|
49b11bc493 | ||
|
|
9a4eb1e835 | ||
|
|
e71bf27dae | ||
|
|
c985fd63f9 | ||
|
|
f5ad5010bc | ||
|
|
12be7ac7e9 | ||
|
|
651619076a | ||
|
|
57ba4c8cba | ||
|
|
6a01ab20a0 | ||
|
|
81e3ab0bc5 | ||
|
|
e43ffe860b | ||
|
|
d0081a7247 | ||
|
|
972456ca07 | ||
|
|
c9efa23f02 | ||
|
|
3843c61132 | ||
|
|
f6938d6abb | ||
|
|
aa7a00d080 | ||
|
|
4c6de22711 | ||
|
|
83f976ea54 | ||
|
|
3153c588ec | ||
|
|
0ce1843070 | ||
|
|
f7f55e8eff | ||
|
|
5cc1600072 | ||
|
|
1a91f81976 | ||
|
|
b9234fe238 | ||
|
|
4cdbe6540b | ||
|
|
4877891980 | ||
|
|
a1b486436e | ||
|
|
c3a8cc7eb4 | ||
|
|
707e9d8926 | ||
|
|
adf0c1a12a | ||
|
|
fd4cfaeb02 | ||
|
|
ae8ee5b955 | ||
|
|
84479bc403 | ||
|
|
794dfb96f2 | ||
|
|
d254612826 | ||
|
|
c8721b38fd | ||
|
|
f863acf8ac | ||
|
|
7e7ecbe7a5 | ||
|
|
4ecd885a0c | ||
|
|
dbda09b9fc | ||
|
|
41931082e6 | ||
|
|
5af76c5ea1 | ||
|
|
1446a1e44c | ||
|
|
69c12618d9 | ||
|
|
651fb777ab | ||
|
|
34a51d2e23 | ||
|
|
2fc62c1a52 | ||
|
|
5ebd98779a | ||
|
|
14a28b7779 | ||
|
|
0027b990e4 | ||
|
|
9716c32695 | ||
|
|
f7a626fef2 | ||
|
|
f8961abb8a | ||
|
|
59f233cd46 | ||
|
|
ae13a0fee1 | ||
|
|
543f9107b6 | ||
|
|
5bf810408a | ||
|
|
405c618b6b | ||
|
|
4cd6a24431 | ||
|
|
773dcce713 | ||
|
|
d5cf4112fa | ||
|
|
72c07a3f81 | ||
|
|
bdaf3a4502 | ||
|
|
f7fe47914e | ||
|
|
0338f0fee2 | ||
|
|
843319ebb0 | ||
|
|
2374fb5104 | ||
|
|
31c9c23a18 | ||
|
|
af82a95a29 | ||
|
|
87dc67d0cd | ||
|
|
68b455565b | ||
|
|
c60402b06d | ||
|
|
422eb43e50 | ||
|
|
a78570c99a | ||
|
|
5202441769 | ||
|
|
ef29d05ea4 | ||
|
|
e332bb1728 | ||
|
|
14573d2c2d | ||
|
|
cbf79b8b90 | ||
|
|
ae604cd660 | ||
|
|
a206dccf0a | ||
|
|
c187f4b238 | ||
|
|
4eda601a32 | ||
|
|
4f376fba35 | ||
|
|
8bfd8f3a26 | ||
|
|
ba9de17b87 | ||
|
|
8497e5b95d | ||
|
|
918e52b37b | ||
|
|
b86bbf3fc4 | ||
|
|
7de8e1fc97 | ||
|
|
b16f5592fc | ||
|
|
48c6146ab6 | ||
|
|
485022797f | ||
|
|
7bd719f3f3 | ||
|
|
6645afcd15 | ||
|
|
05de5b4c49 | ||
|
|
259b45065a | ||
|
|
aa08210e44 | ||
|
|
a0509a5170 | ||
|
|
21f1c163d8 | ||
|
|
a2796d89ab | ||
|
|
c23eedd069 | ||
|
|
ccda938248 | ||
|
|
acd2cbf56a | ||
|
|
f74c49f393 | ||
|
|
8cf458d3b3 | ||
|
|
fca9879321 | ||
|
|
7e964e9501 | ||
|
|
89c0c6157b | ||
|
|
981e3bed45 | ||
|
|
17e2b208e8 | ||
|
|
bbdd12cffd | ||
|
|
dd79c096be | ||
|
|
9898e5e2db | ||
|
|
84b6a85293 | ||
|
|
7acb9a255b | ||
|
|
5a6e35b4b0 | ||
|
|
222821804e | ||
|
|
b32eb49d50 | ||
|
|
97d2af7ebd | ||
|
|
a9d79a1a84 | ||
|
|
792d285970 | ||
|
|
4de95a64c1 | ||
|
|
95e30138f0 | ||
|
|
484c9e986f | ||
|
|
00ff0d6fa0 | ||
|
|
a0bd93c596 | ||
|
|
d66725fd31 | ||
|
|
5b2048fad1 | ||
|
|
0d2df34c58 | ||
|
|
d505eeb269 | ||
|
|
a0db3abe99 | ||
|
|
bd2cf5c464 | ||
|
|
8b5a4faa07 | ||
|
|
4c39db1f54 | ||
|
|
c0f0aadf09 | ||
|
|
55109177ee | ||
|
|
2e39b5add5 | ||
|
|
4127ce8e9f | ||
|
|
6f4f38506e | ||
|
|
33ee650fb7 | ||
|
|
7f08025175 | ||
|
|
35a842ade6 | ||
|
|
d46872c061 | ||
|
|
64034f4977 | ||
|
|
4d2d6cc818 | ||
|
|
c57bdc46f4 | ||
|
|
4a84ed0018 | ||
|
|
3de6c95fd6 | ||
|
|
7911007973 | ||
|
|
24ef51df01 | ||
|
|
a689f31978 | ||
|
|
f760a2fa79 | ||
|
|
9a479a95ad | ||
|
|
7e1f5b8471 | ||
|
|
6265be01cd | ||
|
|
fc1877dcce | ||
|
|
5cda5c82e1 | ||
|
|
b8225f6993 | ||
|
|
1e221ddbdb | ||
|
|
09a2db1cff | ||
|
|
881aed879b | ||
|
|
2f55a8808c | ||
|
|
38e329edad | ||
|
|
d832cb93ce | ||
|
|
bbf20f8955 | ||
|
|
17a36726fa | ||
|
|
482f7a92ae | ||
|
|
b191ee9210 | ||
|
|
25f8b3f903 | ||
|
|
e3ad276dd0 | ||
|
|
1f1fd49d0b | ||
|
|
e01b354f7d | ||
|
|
84cd761c8c | ||
|
|
a947a6b6bc | ||
|
|
b0485eef6a | ||
|
|
5b9dbf7b95 | ||
|
|
d31d4621a4 | ||
|
|
d42b7f173b | ||
|
|
ceb2411794 | ||
|
|
cbff2fb692 | ||
|
|
e59f606566 | ||
|
|
042c8d8a69 | ||
|
|
d32fb6f900 | ||
|
|
2c24f30cdd | ||
|
|
954c9944ad | ||
|
|
41a7d98e17 | ||
|
|
75589d78d8 | ||
|
|
b0e40e8641 | ||
|
|
99a07f80f1 | ||
|
|
79ec21346d | ||
|
|
5d91c27980 | ||
|
|
72ff1a26fc | ||
|
|
1812cbbb7c | ||
|
|
3440f0f308 | ||
|
|
6570561d4e | ||
|
|
9c22537b4e | ||
|
|
84a4784dee | ||
|
|
5c0d91c510 | ||
|
|
d1441d29fd | ||
|
|
bf6735420d | ||
|
|
34181230c7 | ||
|
|
2eb11d9a2d | ||
|
|
4966f6ab62 | ||
|
|
33d973fb91 | ||
|
|
81f07cdf85 | ||
|
|
48dfadd85b | ||
|
|
71a827eead | ||
|
|
86640474b5 | ||
|
|
31c4fd586b | ||
|
|
33e9f88c73 | ||
|
|
b9d02b61b1 | ||
|
|
c9692d7a50 | ||
|
|
7ee9003df7 | ||
|
|
75d65d2694 | ||
|
|
6a0ff7db18 | ||
|
|
85fd43a38c | ||
|
|
1f354a972e | ||
|
|
5eee11beed | ||
|
|
9cd5415dfe | ||
|
|
7f01445903 | ||
|
|
13b8281f6b | ||
|
|
ad575efdcc | ||
|
|
685157266d | ||
|
|
619c0752bd | ||
|
|
bed76b9a32 | ||
|
|
2385bd978f | ||
|
|
1cc5c5e7f0 | ||
|
|
2a8f7a9c50 | ||
|
|
5f98e7d7b3 | ||
|
|
a4fb57bf15 | ||
|
|
cae937f107 | ||
|
|
77a929faa3 | ||
|
|
c86a621d5d | ||
|
|
3a20fb1e3a | ||
|
|
d6ee700bca | ||
|
|
c87f4a1e94 | ||
|
|
075321932a | ||
|
|
39d532a4a0 | ||
|
|
86d7564661 | ||
|
|
d579ce942c | ||
|
|
4efcad46f3 | ||
|
|
1546a4a189 | ||
|
|
2649d2f7dc | ||
|
|
154e886873 | ||
|
|
d9387cf4f8 | ||
|
|
5688670da6 | ||
|
|
678e25f510 | ||
|
|
15d7255728 | ||
|
|
05e6c1bf62 | ||
|
|
4ea79cb0c3 | ||
|
|
e71a27ac2d | ||
|
|
d897989965 | ||
|
|
90469679a5 | ||
|
|
00686fc002 | ||
|
|
1a6be5ae09 | ||
|
|
efb121e016 | ||
|
|
8dd13bdb20 | ||
|
|
28fe82feff | ||
|
|
74eb7e8031 | ||
|
|
22802b4be8 | ||
|
|
7cbe766bde | ||
|
|
f21d013241 | ||
|
|
de5b0062b5 | ||
|
|
2b6c87fb4b | ||
|
|
01226fbe90 | ||
|
|
2f3a95a0b8 | ||
|
|
6507397343 | ||
|
|
69e6da9f5c | ||
|
|
161643c5da | ||
|
|
1f313e8555 | ||
|
|
bc3e5cda9e | ||
|
|
7900412fd0 | ||
|
|
65347ae858 | ||
|
|
43fdb553b7 | ||
|
|
4873e9447a | ||
|
|
a8c55781fa | ||
|
|
9313d9427d | ||
|
|
5c3a19f298 | ||
|
|
69c8058b72 | ||
|
|
dc82365956 | ||
|
|
27ab7d81b7 | ||
|
|
0836fb7184 | ||
|
|
4146a04a9e | ||
|
|
84eaee8210 | ||
|
|
4bbc58dd24 | ||
|
|
4529123777 | ||
|
|
0d0698ea6e | ||
|
|
63dee16611 | ||
|
|
bd0b9d5f81 | ||
|
|
8310af068c | ||
|
|
4cc98e361c | ||
|
|
dc98432fa0 | ||
|
|
fd9938f2cc | ||
|
|
86296b67aa | ||
|
|
245dab0c8c | ||
|
|
7b53f5724c | ||
|
|
3733f8b4ae | ||
|
|
308ac8c5b0 | ||
|
|
bc8859b550 | ||
|
|
bdc5ac592f | ||
|
|
c80f580833 | ||
|
|
1ed36adab6 | ||
|
|
5393187f66 | ||
|
|
72159c5118 | ||
|
|
d2f2d7a11b | ||
|
|
de5bb823fa | ||
|
|
322c37d693 | ||
|
|
338cffd8c7 | ||
|
|
e8506813fe | ||
|
|
fa86a90ef8 | ||
|
|
291b1e2d33 | ||
|
|
9d4c05b6ce | ||
|
|
c7d8492842 | ||
|
|
d1b8cce6bf | ||
|
|
c259aea3bc | ||
|
|
59fd557067 | ||
|
|
06639850ba | ||
|
|
21565f635e | ||
|
|
cf46b6b0ff | ||
|
|
bd449a177b | ||
|
|
bbdebb27ce |
15
.eslintignore
Normal file
15
.eslintignore
Normal file
@@ -0,0 +1,15 @@
|
||||
# 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
|
||||
267
.eslintrc.yml
Normal file
267
.eslintrc.yml
Normal file
@@ -0,0 +1,267 @@
|
||||
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"
|
||||
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
---
|
||||
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.
|
||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
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.
|
||||
22
.github/PULL_REQUEST_TEMPLATE/pull_request_template.md
vendored
Normal file
22
.github/PULL_REQUEST_TEMPLATE/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
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.
|
||||
74
.github/workflows/ci.yml
vendored
Normal file
74
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
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
35
.travis.yml
@@ -1,35 +0,0 @@
|
||||
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
|
||||
@@ -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.21
|
||||
TW5_BUILD_VERSION=v5.1.23
|
||||
fi
|
||||
|
||||
echo "Using TW5_BUILD_VERSION as [$TW5_BUILD_VERSION]"
|
||||
|
||||
15
bin/ci-push.sh
Executable file
15
bin/ci-push.sh
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/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 ..
|
||||
@@ -1,20 +0,0 @@
|
||||
#!/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
|
||||
25
bin/update-translation-from-html-file.sh
Executable file
25
bin/update-translation-from-html-file.sh
Executable file
@@ -0,0 +1,25 @@
|
||||
#!/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
|
||||
|
||||
94
boot/boot.js
94
boot/boot.js
@@ -267,8 +267,16 @@ $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 parts = window.location.href.split('#');
|
||||
return "#" + (parts.length > 1 ? parts[1] : "");
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -409,10 +417,10 @@ $tw.utils.resolvePath = function(sourcepath,rootpath) {
|
||||
};
|
||||
|
||||
/*
|
||||
Parse a semantic version string into its constituent parts
|
||||
Parse a semantic version string into its constituent parts -- see https://semver.org
|
||||
*/
|
||||
$tw.utils.parseVersion = function(version) {
|
||||
var match = /^((\d+)\.(\d+)\.(\d+))(?:-([\dA-Za-z\-]+(?:\.[\dA-Za-z\-]+)*))?(?:\+([\dA-Za-z\-]+(?:\.[\dA-Za-z\-]+)*))?$/.exec(version);
|
||||
var match = /^v?((\d+)\.(\d+)\.(\d+))(?:-([\dA-Za-z\-]+(?:\.[\dA-Za-z\-]+)*))?(?:\+([\dA-Za-z\-]+(?:\.[\dA-Za-z\-]+)*))?$/.exec(version);
|
||||
if(match) {
|
||||
return {
|
||||
version: match[1],
|
||||
@@ -427,25 +435,37 @@ $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) {
|
||||
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);
|
||||
return $tw.utils.compareVersions(versionStringA,versionStringB) !== -1;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -640,11 +660,13 @@ $tw.utils.PasswordPrompt.prototype.createPrompt = function(options) {
|
||||
var promptInfo = {
|
||||
serviceName: options.serviceName,
|
||||
callback: options.callback,
|
||||
form: form
|
||||
form: form,
|
||||
owner: this
|
||||
};
|
||||
this.passwordPrompts.push(promptInfo);
|
||||
// Make sure the wrapper is displayed
|
||||
this.setWrapperDisplay();
|
||||
return promptInfo;
|
||||
};
|
||||
|
||||
$tw.utils.PasswordPrompt.prototype.removePrompt = function(promptInfo) {
|
||||
@@ -1258,7 +1280,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")) {
|
||||
if(tiddler.fields.type === "application/json" && tiddler.hasField("plugin-type") && tiddler.fields.text) {
|
||||
pluginInfo[tiddler.fields.title] = JSON.parse(tiddler.fields.text);
|
||||
results.modifiedPlugins.push(tiddler.fields.title);
|
||||
}
|
||||
@@ -1810,7 +1832,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) {
|
||||
var processFile = function(filename,isTiddlerFile,fields,isEditableFile) {
|
||||
var extInfo = $tw.config.fileExtensionInfo[path.extname(filename)],
|
||||
type = (extInfo || {}).type || fields.type || "text/plain",
|
||||
typeInfo = $tw.config.contentTypeInfo[type] || {},
|
||||
@@ -1863,7 +1885,11 @@ $tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
|
||||
}
|
||||
});
|
||||
});
|
||||
tiddlers.push({tiddlers: fileTiddlers});
|
||||
if(isEditableFile) {
|
||||
tiddlers.push({filepath: pathname, hasMetaFile: !!metadata && !isTiddlerFile, tiddlers: fileTiddlers});
|
||||
} else {
|
||||
tiddlers.push({tiddlers: fileTiddlers});
|
||||
}
|
||||
};
|
||||
// Process the listed tiddlers
|
||||
$tw.utils.each(filesInfo.tiddlers,function(tidInfo) {
|
||||
@@ -1893,7 +1919,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);
|
||||
processFile(dirPath + path.sep + filename,dirSpec.isTiddlerFile,dirSpec.fields,dirSpec.isEditableFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2160,8 +2186,7 @@ $tw.loadTiddlersNode = function() {
|
||||
/*
|
||||
Startup TiddlyWiki
|
||||
*/
|
||||
$tw.boot.startup = function(options) {
|
||||
options = options || {};
|
||||
$tw.boot.initStartup = function(options) {
|
||||
// Get the URL hash and check for safe mode
|
||||
$tw.locationHash = "#";
|
||||
if($tw.browser && !$tw.node) {
|
||||
@@ -2247,6 +2272,7 @@ $tw.boot.startup = 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"]});
|
||||
@@ -2256,6 +2282,7 @@ $tw.boot.startup = 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");
|
||||
@@ -2293,6 +2320,9 @@ $tw.boot.startup = function(options) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
};
|
||||
$tw.boot.loadStartup = function(options){
|
||||
|
||||
// Load tiddlers
|
||||
if($tw.boot.tasks.readBrowserTiddlers) {
|
||||
$tw.loadTiddlersBrowser();
|
||||
@@ -2305,6 +2335,8 @@ $tw.boot.startup = 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);
|
||||
@@ -2333,6 +2365,16 @@ $tw.boot.startup = 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);
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
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>
|
||||
@@ -70,6 +70,7 @@ 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
|
||||
@@ -87,6 +88,11 @@ 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
|
||||
@@ -111,6 +117,7 @@ Saving/GitService/Gitea/Caption: Gitea Saver
|
||||
Saving/GitService/Gitea/Password: Personal access token for API (via Gitea’s 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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -13,6 +13,11 @@ 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>>
|
||||
|
||||
@@ -26,7 +26,9 @@ 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
|
||||
@@ -62,6 +64,15 @@ 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
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
title: $:/config/NewJournal/Tags
|
||||
tags: Journal
|
||||
|
||||
Journal
|
||||
|
||||
@@ -4,7 +4,6 @@ All/Caption: All
|
||||
Contents/Caption: Contents
|
||||
Drafts/Caption: Drafts
|
||||
Explorer/Caption: Explorer
|
||||
History/Caption: History
|
||||
Missing/Caption: Missing
|
||||
More/Caption: More
|
||||
Open/Caption: Open
|
||||
|
||||
@@ -71,7 +71,7 @@ Command.prototype.fetchFiles = function(options) {
|
||||
if(options.url) {
|
||||
urls = [options.url]
|
||||
} else if(options.urlFilter) {
|
||||
urls = $tw.wiki.filterTiddlers(options.urlFilter);
|
||||
urls = this.commander.wiki.filterTiddlers(options.urlFilter);
|
||||
} else {
|
||||
return "Missing URL";
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ Command.prototype.execute = function() {
|
||||
tiddlers = {};
|
||||
// Collect up the library plugins
|
||||
var collectPlugins = function(folder) {
|
||||
var pluginFolders = fs.readdirSync(folder);
|
||||
var pluginFolders = $tw.utils.getSubdirectories(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 = fs.readdirSync(folder);
|
||||
var publisherFolders = $tw.utils.getSubdirectories(folder) || [];
|
||||
for(var t=0; t<publisherFolders.length; t++) {
|
||||
if(!$tw.boot.excludeRegExp.test(publisherFolders[t])) {
|
||||
collectPlugins(path.resolve(folder,"./" + publisherFolders[t]));
|
||||
}
|
||||
}
|
||||
};
|
||||
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));
|
||||
$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);
|
||||
// Save the upgrade library tiddler
|
||||
var pluginFields = {
|
||||
title: upgradeLibraryTitle,
|
||||
|
||||
@@ -5,10 +5,12 @@ module-type: command
|
||||
|
||||
Command to save the subtiddlers of a bundle tiddler as a series of JSON files
|
||||
|
||||
--savelibrarytiddlers <tiddler> <pathname> <skinnylisting>
|
||||
--savelibrarytiddlers <tiddler> <tiddler-filter> <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.
|
||||
@@ -69,7 +71,7 @@ Command.prototype.execute = function() {
|
||||
// Collect the skinny list data
|
||||
var pluginTiddlers = JSON.parse(tiddler.text),
|
||||
readmeContent = (pluginTiddlers.tiddlers[title + "/readme"] || {}).text,
|
||||
doesRequireReload = !!$tw.wiki.doesPluginInfoRequireReload(pluginTiddlers),
|
||||
doesRequireReload = !!self.commander.wiki.doesPluginInfoRequireReload(pluginTiddlers),
|
||||
iconTiddler = pluginTiddlers.tiddlers[title + "/icon"] || {},
|
||||
iconType = iconTiddler.type,
|
||||
iconText = iconTiddler.text,
|
||||
|
||||
@@ -80,7 +80,8 @@ 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: "keydown",handlerObject: this.widget,handlerMethod: "handleKeydownEvent"},
|
||||
{name: "focus",handlerObject: this,handlerMethod: "handleFocusEvent"}
|
||||
]);
|
||||
// Insert the element into the DOM
|
||||
this.iframeDoc.body.appendChild(this.domNode);
|
||||
@@ -107,13 +108,20 @@ 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.domNode.value = text;
|
||||
this.updateDomNodeText(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
|
||||
*/
|
||||
@@ -153,6 +161,15 @@ FramedEngine.prototype.focus = function() {
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Handle a focus event
|
||||
*/
|
||||
FramedEngine.prototype.handleFocusEvent = function(event) {
|
||||
if(this.widget.editCancelPopups) {
|
||||
$tw.popup.cancel(0);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Handle a click
|
||||
*/
|
||||
@@ -167,6 +184,9 @@ 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;
|
||||
};
|
||||
|
||||
|
||||
@@ -68,13 +68,20 @@ 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.domNode.value = text;
|
||||
this.updateDomNodeText(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
|
||||
*/
|
||||
@@ -115,6 +122,9 @@ 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;
|
||||
};
|
||||
|
||||
@@ -122,6 +132,9 @@ 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,
|
||||
|
||||
@@ -177,6 +177,9 @@ 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") {
|
||||
@@ -208,9 +211,11 @@ 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 || 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 || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || 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);
|
||||
|
||||
25
core/modules/filterrunprefixes/all.js
Normal file
25
core/modules/filterrunprefixes/all.js
Normal file
@@ -0,0 +1,25 @@
|
||||
/*\
|
||||
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));
|
||||
};
|
||||
};
|
||||
|
||||
})();
|
||||
28
core/modules/filterrunprefixes/and.js
Normal file
28
core/modules/filterrunprefixes/and.js
Normal file
@@ -0,0 +1,28 @@
|
||||
/*\
|
||||
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));
|
||||
};
|
||||
};
|
||||
|
||||
})();
|
||||
27
core/modules/filterrunprefixes/else.js
Normal file
27
core/modules/filterrunprefixes/else.js
Normal file
@@ -0,0 +1,27 @@
|
||||
/*\
|
||||
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));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
})();
|
||||
25
core/modules/filterrunprefixes/except.js
Normal file
25
core/modules/filterrunprefixes/except.js
Normal file
@@ -0,0 +1,25 @@
|
||||
/*\
|
||||
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));
|
||||
};
|
||||
};
|
||||
|
||||
})();
|
||||
31
core/modules/filterrunprefixes/filter.js
Normal file
31
core/modules/filterrunprefixes/filter.js
Normal file
@@ -0,0 +1,31 @@
|
||||
/*\
|
||||
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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
||||
30
core/modules/filterrunprefixes/intersection.js
Normal file
30
core/modules/filterrunprefixes/intersection.js
Normal file
@@ -0,0 +1,30 @@
|
||||
/*\
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
})();
|
||||
24
core/modules/filterrunprefixes/or.js
Normal file
24
core/modules/filterrunprefixes/or.js
Normal file
@@ -0,0 +1,24 @@
|
||||
/*\
|
||||
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));
|
||||
};
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -119,7 +119,7 @@ exports.parseFilter = function(filterString) {
|
||||
p = 0, // Current position in the filter string
|
||||
match;
|
||||
var whitespaceRegExp = /(\s+)/mg,
|
||||
operandRegExp = /((?:\+|\-|~|=)?)(?:(\[)|(?:"([^"]*)")|(?:'([^']*)')|([^\s\[\]]+))/mg;
|
||||
operandRegExp = /((?:\+|\-|~|=|\:(\w+))?)(?:(\[)|(?:"([^"]*)")|(?:'([^']*)')|([^\s\[\]]+))/mg;
|
||||
while(p < filterString.length) {
|
||||
// Skip any whitespace
|
||||
whitespaceRegExp.lastIndex = p;
|
||||
@@ -140,16 +140,19 @@ exports.parseFilter = function(filterString) {
|
||||
};
|
||||
if(match[1]) {
|
||||
operation.prefix = match[1];
|
||||
p++;
|
||||
p = p + operation.prefix.length;
|
||||
if(match[2]) {
|
||||
operation.namedPrefix = match[2];
|
||||
}
|
||||
}
|
||||
if(match[2]) { // Opening square bracket
|
||||
if(match[3]) { // Opening square bracket
|
||||
p = parseFilterOperation(operation.operators,filterString,p);
|
||||
} else {
|
||||
p = match.index + match[0].length;
|
||||
}
|
||||
if(match[3] || match[4] || match[5]) { // Double quoted string, single quoted string or unquoted title
|
||||
if(match[4] || match[5] || match[6]) { // Double quoted string, single quoted string or unquoted title
|
||||
operation.operators.push(
|
||||
{operator: "title", operand: match[3] || match[4] || match[5]}
|
||||
{operator: "title", operand: match[4] || match[5] || match[6]}
|
||||
);
|
||||
}
|
||||
results.push(operation);
|
||||
@@ -166,6 +169,14 @@ 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);
|
||||
@@ -241,35 +252,29 @@ 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 function(results,source,widget) {
|
||||
$tw.utils.pushTop(results,operationSubFunction(source,widget));
|
||||
};
|
||||
return filterRunPrefixes["or"](operationSubFunction);
|
||||
case "=": // The results of the operation are pushed into the result without deduplication
|
||||
return function(results,source,widget) {
|
||||
Array.prototype.push.apply(results,operationSubFunction(source,widget));
|
||||
};
|
||||
return filterRunPrefixes["all"](operationSubFunction);
|
||||
case "-": // The results of this operation are removed from the main result
|
||||
return function(results,source,widget) {
|
||||
$tw.utils.removeArrayEntries(results,operationSubFunction(source,widget));
|
||||
};
|
||||
return filterRunPrefixes["except"](operationSubFunction);
|
||||
case "+": // This operation is applied to the main results so far
|
||||
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));
|
||||
};
|
||||
return filterRunPrefixes["and"](operationSubFunction);
|
||||
case "~": // This operation is unioned into the result only if the main result so far is empty
|
||||
return function(results,source,widget) {
|
||||
if(results.length === 0) {
|
||||
// Main result so far is empty
|
||||
$tw.utils.pushTop(results,operationSubFunction(source,widget));
|
||||
}
|
||||
};
|
||||
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"));
|
||||
};
|
||||
}
|
||||
}
|
||||
})());
|
||||
});
|
||||
|
||||
40
core/modules/filters/compare.js
Normal file
40
core/modules/filters/compare.js
Normal file
@@ -0,0 +1,40 @@
|
||||
/*\
|
||||
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;}
|
||||
}
|
||||
|
||||
})();
|
||||
36
core/modules/filters/duplicateslugs.js
Normal file
36
core/modules/filters/duplicateslugs.js
Normal file
@@ -0,0 +1,36 @@
|
||||
/*\
|
||||
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;
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -16,13 +16,28 @@ 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 = [];
|
||||
var results = [],
|
||||
fieldName,
|
||||
suffixes = (operator.suffixes || [])[0] || [],
|
||||
operand = $tw.utils.parseStringArray(operator.operand);
|
||||
|
||||
source(function(tiddler,title) {
|
||||
if(tiddler) {
|
||||
for(var fieldName in tiddler.fields) {
|
||||
$tw.utils.pushTop(results,fieldName);
|
||||
}
|
||||
}
|
||||
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)
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
31
core/modules/filters/filter.js
Normal file
31
core/modules/filters/filter.js
Normal file
@@ -0,0 +1,31 @@
|
||||
/*\
|
||||
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;
|
||||
};
|
||||
|
||||
})();
|
||||
46
core/modules/filters/format.js
Normal file
46
core/modules/filters/format.js
Normal file
@@ -0,0 +1,46 @@
|
||||
/*\
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
||||
26
core/modules/filters/format/date.js
Normal file
26
core/modules/filters/format/date.js
Normal file
@@ -0,0 +1,26 @@
|
||||
/*\
|
||||
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;
|
||||
};
|
||||
|
||||
})();
|
||||
26
core/modules/filters/format/relativedate.js
Normal file
26
core/modules/filters/format/relativedate.js
Normal file
@@ -0,0 +1,26 @@
|
||||
/*\
|
||||
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;
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -1,38 +0,0 @@
|
||||
/*\
|
||||
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;
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -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
|
||||
Filter operator for checking if a tiddler has the specified field or index
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
@@ -33,16 +33,32 @@ exports.has = function(source,operator,options) {
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else if(operator.suffix === "index") {
|
||||
if(invert) {
|
||||
source(function(tiddler,title) {
|
||||
if(!tiddler || !$tw.utils.hop(tiddler.fields,operator.operand) || (tiddler.fields[operator.operand] === "")) {
|
||||
if(!tiddler || (tiddler && (!$tw.utils.hop(options.wiki.getTiddlerDataCached(tiddler,Object.create(null)),operator.operand)))) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
if(tiddler && $tw.utils.hop(tiddler.fields,operator.operand) && !(tiddler.fields[operator.operand] === "" || tiddler.fields[operator.operand].length === 0)) {
|
||||
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)) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -114,9 +114,9 @@ exports.minall = makeNumericReducingOperator(
|
||||
function makeNumericBinaryOperator(fnCalc) {
|
||||
return function(source,operator,options) {
|
||||
var result = [],
|
||||
numOperand = parseNumber(operator.operand);
|
||||
numOperand = $tw.utils.parseNumber(operator.operand);
|
||||
source(function(tiddler,title) {
|
||||
result.push(stringifyNumber(fnCalc(parseNumber(title),numOperand)));
|
||||
result.push($tw.utils.stringifyNumber(fnCalc($tw.utils.parseNumber(title),numOperand)));
|
||||
});
|
||||
return result;
|
||||
};
|
||||
@@ -129,18 +129,10 @@ function makeNumericReducingOperator(fnCalc,initialValue) {
|
||||
source(function(tiddler,title) {
|
||||
result.push(title);
|
||||
});
|
||||
return [stringifyNumber(result.reduce(function(accumulator,currentValue) {
|
||||
return fnCalc(accumulator,parseNumber(currentValue));
|
||||
return [$tw.utils.stringifyNumber(result.reduce(function(accumulator,currentValue) {
|
||||
return fnCalc(accumulator,$tw.utils.parseNumber(currentValue));
|
||||
},initialValue))];
|
||||
};
|
||||
}
|
||||
|
||||
function parseNumber(str) {
|
||||
return parseFloat(str) || 0;
|
||||
}
|
||||
|
||||
function stringifyNumber(num) {
|
||||
return num + "";
|
||||
}
|
||||
|
||||
})();
|
||||
|
||||
54
core/modules/filters/reduce.js
Normal file
54
core/modules/filters/reduce.js
Normal file
@@ -0,0 +1,54 @@
|
||||
/*\
|
||||
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];
|
||||
};
|
||||
|
||||
})();
|
||||
23
core/modules/filters/slugify.js
Normal file
23
core/modules/filters/slugify.js
Normal file
@@ -0,0 +1,23 @@
|
||||
/*\
|
||||
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;
|
||||
};
|
||||
|
||||
})();
|
||||
57
core/modules/filters/sortsub.js
Normal file
57
core/modules/filters/sortsub.js
Normal file
@@ -0,0 +1,57 @@
|
||||
/*\
|
||||
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;
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -34,14 +34,36 @@ exports.titlecase = makeStringBinaryOperator(
|
||||
function(a) {return [$tw.utils.toTitleCase(a)];}
|
||||
);
|
||||
|
||||
exports.trim = makeStringBinaryOperator(
|
||||
function(a) {return [$tw.utils.trim(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.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) {
|
||||
@@ -68,9 +90,12 @@ 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) || ""];
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ 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) {
|
||||
|
||||
@@ -284,6 +284,16 @@ 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");
|
||||
};
|
||||
|
||||
@@ -27,7 +27,7 @@ exports.params = [
|
||||
Run the macro
|
||||
*/
|
||||
exports.run = function(filter,spaces) {
|
||||
return this.wiki.getTiddlersAsJson(filter,spaces);
|
||||
return this.wiki.getTiddlersAsJson(filter,$tw.utils.parseInt(spaces));
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
@@ -60,7 +60,7 @@ var listTypes = {
|
||||
"#": {listTag: "ol", itemTag: "li"},
|
||||
";": {listTag: "dl", itemTag: "dt"},
|
||||
":": {listTag: "dl", itemTag: "dd"},
|
||||
">": {listTag: "blockquote", itemTag: "p"}
|
||||
">": {listTag: "blockquote", itemTag: "div"}
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -153,7 +153,7 @@ SaverHandler.prototype.saveWiki = function(options) {
|
||||
var self = this,
|
||||
method = options.method || "save";
|
||||
// Ignore autosave if disabled
|
||||
if(method === "autosave" && this.wiki.getTiddlerText(this.titleAutoSave,"yes") !== "yes") {
|
||||
if(method === "autosave" && ($tw.config.disableAutoSave || this.wiki.getTiddlerText(this.titleAutoSave,"yes") !== "yes")) {
|
||||
return false;
|
||||
}
|
||||
var variables = options.variables || {},
|
||||
|
||||
60
core/modules/savers/custom.js
Normal file
60
core/modules/savers/custom.js
Normal file
@@ -0,0 +1,60 @@
|
||||
/*\
|
||||
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);
|
||||
};
|
||||
})();
|
||||
@@ -31,10 +31,10 @@ GiteaSaver.prototype.save = function(text,method,callback) {
|
||||
headers = {
|
||||
"Accept": "application/json",
|
||||
"Content-Type": "application/json;charset=UTF-8",
|
||||
"Authorization": "Basic " + window.btoa(username + ":" + password)
|
||||
"Authorization": "token " + password
|
||||
};
|
||||
// Bail if we don't have everything we need
|
||||
if(!username || !password || !repo || !path || !filename) {
|
||||
if(!username || !password || !repo || !filename) {
|
||||
return false;
|
||||
}
|
||||
// Make sure the path start and ends with a slash
|
||||
|
||||
@@ -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 || !path || !filename) {
|
||||
if(!username || !password || !repo || !filename) {
|
||||
return false;
|
||||
}
|
||||
// Make sure the path start and ends with a slash
|
||||
|
||||
@@ -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 || !path || !filename) {
|
||||
if(!username || !password || !repo || !filename) {
|
||||
return false;
|
||||
}
|
||||
// Make sure the path start and ends with a slash
|
||||
|
||||
64
core/modules/savers/hyperdrive.js
Normal file
64
core/modules/savers/hyperdrive.js
Normal file
@@ -0,0 +1,64 @@
|
||||
/*\
|
||||
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);
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -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($tw.boot.wikiPath,this.credentialsFilepath);
|
||||
var resolveCredentialsFilepath = path.resolve(this.server.boot.wikiPath,this.credentialsFilepath);
|
||||
if(fs.existsSync(resolveCredentialsFilepath) && !fs.statSync(resolveCredentialsFilepath).isDirectory()) {
|
||||
var credentialsText = fs.readFileSync(resolveCredentialsFilepath,"utf8"),
|
||||
credentialsData = $tw.utils.parseCsvStringWithHeader(credentialsText);
|
||||
|
||||
@@ -14,7 +14,7 @@ Authenticator for trusted header authentication
|
||||
|
||||
function HeaderAuthenticator(server) {
|
||||
this.server = server;
|
||||
this.header = server.get("authenticated-user-header");
|
||||
this.header = server.get("authenticated-user-header") ? server.get("authenticated-user-header").toLowerCase() : undefined;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -21,7 +21,7 @@ exports.handler = function(request,response,state) {
|
||||
fs = require("fs"),
|
||||
util = require("util"),
|
||||
suppliedFilename = decodeURIComponent(state.params[0]),
|
||||
filename = path.resolve($tw.boot.wikiPath,"files",suppliedFilename),
|
||||
filename = path.resolve(state.boot.wikiPath,"files",suppliedFilename),
|
||||
extension = path.extname(filename);
|
||||
fs.readFile(filename,function(err,content) {
|
||||
var status,content,type = "text/plain";
|
||||
|
||||
@@ -3,7 +3,7 @@ title: $:/core/modules/server/routes/get-tiddlers-json.js
|
||||
type: application/javascript
|
||||
module-type: route
|
||||
|
||||
GET /recipes/default/tiddlers/tiddlers.json?filter=<filter>
|
||||
GET /recipes/default/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($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);
|
||||
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);
|
||||
response.writeHead(403);
|
||||
response.end();
|
||||
return;
|
||||
|
||||
@@ -31,6 +31,7 @@ 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);
|
||||
@@ -69,8 +70,8 @@ function Server(options) {
|
||||
tlsCertFilepath = this.get("tls-cert");
|
||||
if(tlsCertFilepath && tlsKeyFilepath) {
|
||||
this.listenOptions = {
|
||||
key: fs.readFileSync(path.resolve($tw.boot.wikiPath,tlsKeyFilepath),"utf8"),
|
||||
cert: fs.readFileSync(path.resolve($tw.boot.wikiPath,tlsCertFilepath),"utf8")
|
||||
key: fs.readFileSync(path.resolve(this.boot.wikiPath,tlsKeyFilepath),"utf8"),
|
||||
cert: fs.readFileSync(path.resolve(this.boot.wikiPath,tlsCertFilepath),"utf8")
|
||||
};
|
||||
this.protocol = "https";
|
||||
}
|
||||
@@ -112,15 +113,14 @@ 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(pathprefix) {
|
||||
if(pathname.substr(0,pathprefix.length) === pathprefix) {
|
||||
pathname = pathname.substr(pathprefix.length) || "/";
|
||||
if(state.pathPrefix) {
|
||||
if(pathname.substr(0,state.pathPrefix.length) === state.pathPrefix) {
|
||||
pathname = pathname.substr(state.pathPrefix.length) || "/";
|
||||
match = potentialRoute.path.exec(pathname);
|
||||
} else {
|
||||
match = false;
|
||||
@@ -156,14 +156,17 @@ 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) {
|
||||
Server.prototype.requestHandler = function(request,response,options) {
|
||||
options = options || {};
|
||||
// Compose the state object
|
||||
var self = this;
|
||||
var state = {};
|
||||
state.wiki = self.wiki;
|
||||
state.wiki = options.wiki || self.wiki;
|
||||
state.boot = options.boot || self.boot;
|
||||
state.server = self;
|
||||
state.urlInfo = url.parse(request.url);
|
||||
state.queryParameters = querystring.parse(state.urlInfo.query);
|
||||
state.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
|
||||
@@ -248,7 +251,7 @@ Server.prototype.listen = function(port,host,prefix) {
|
||||
port = process.env[port] || 8080;
|
||||
}
|
||||
// Warn if required plugins are missing
|
||||
if(!$tw.wiki.getTiddler("$:/plugins/tiddlywiki/tiddlyweb") || !$tw.wiki.getTiddler("$:/plugins/tiddlywiki/filesystem")) {
|
||||
if(!this.wiki.getTiddler("$:/plugins/tiddlywiki/tiddlyweb") || !this.wiki.getTiddler("$:/plugins/tiddlywiki/filesystem")) {
|
||||
$tw.utils.warning("Warning: Plugins required for client-server operation (\"tiddlywiki/filesystem\" and \"tiddlywiki/tiddlyweb\") are missing from tiddlywiki.info file");
|
||||
}
|
||||
// Create the server
|
||||
|
||||
@@ -36,7 +36,7 @@ function setFavicon() {
|
||||
var tiddler = $tw.wiki.getTiddler(FAVICON_TITLE);
|
||||
if(tiddler) {
|
||||
var faviconLink = document.getElementById("faviconLink");
|
||||
faviconLink.setAttribute("href","data:" + tiddler.fields.type + ";base64," + tiddler.fields.text);
|
||||
faviconLink.setAttribute("href",$tw.utils.makeDataUri(tiddler.fields.text,tiddler.fields.type,tiddler.fields._canonical_uri));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -106,6 +106,8 @@ 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");
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
@@ -64,17 +64,12 @@ exports.startup = function() {
|
||||
document: $tw.browser ? document : $tw.fakeDocument
|
||||
});
|
||||
// Execute any startup actions
|
||||
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");
|
||||
$tw.rootWidget.executeStartupTiddlers("$:/tags/StartupAction");
|
||||
if($tw.browser) {
|
||||
executeStartupTiddlers("$:/tags/StartupAction/Browser");
|
||||
$tw.rootWidget.executeStartupTiddlers("$:/tags/StartupAction/Browser");
|
||||
}
|
||||
if($tw.node) {
|
||||
executeStartupTiddlers("$:/tags/StartupAction/Node");
|
||||
$tw.rootWidget.executeStartupTiddlers("$:/tags/StartupAction/Node");
|
||||
}
|
||||
// Kick off the language manager and switcher
|
||||
$tw.language = new $tw.Language();
|
||||
|
||||
@@ -150,6 +150,11 @@ 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 !== "") {
|
||||
@@ -157,9 +162,9 @@ function openStartupTiddlers(options) {
|
||||
if(target.indexOf("[[") === 0 && target.substr(-2) === "]]") {
|
||||
target = target.substr(2,target.length - 4);
|
||||
}
|
||||
$tw.wiki.addToHistory(target);
|
||||
story.addToHistory(target);
|
||||
} else if(storyList.length > 0) {
|
||||
$tw.wiki.addToHistory(storyList[0]);
|
||||
story.addToHistory(storyList[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,48 +37,44 @@ Story.prototype.getStoryList = function() {
|
||||
Story.prototype.addToStory = function(navigateTo,navigateFromTitle,options) {
|
||||
options = options || {};
|
||||
var storyList = this.getStoryList();
|
||||
if(options.singleTiddlerMode) {
|
||||
storyList = [navigateTo];
|
||||
} else {
|
||||
// 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);
|
||||
// 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);
|
||||
// Save the story
|
||||
this.saveStoryList(storyList);
|
||||
};
|
||||
@@ -97,20 +93,11 @@ 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,[]),
|
||||
historyTitles = this.wiki.getTiddlerList(this.historyTitle);
|
||||
var historyList = this.wiki.getTiddlerData(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], list: historyTitles});
|
||||
this.wiki.setTiddlerData(this.historyTitle,historyList,{"current-tiddler": titles[titles.length-1]});
|
||||
};
|
||||
|
||||
Story.prototype.storyCloseTiddler = function(targetTitle) {
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
/*\
|
||||
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;
|
||||
|
||||
})();
|
||||
@@ -39,9 +39,6 @@ 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);
|
||||
|
||||
@@ -113,8 +113,16 @@ function Syncer(options) {
|
||||
return confirmationMessage;
|
||||
});
|
||||
// Listen out for login/logout/refresh events in the browser
|
||||
$tw.rootWidget.addEventListener("tm-login",function() {
|
||||
self.handleLoginEvent();
|
||||
$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-logout",function() {
|
||||
self.handleLogoutEvent();
|
||||
@@ -127,7 +135,7 @@ function Syncer(options) {
|
||||
});
|
||||
}
|
||||
// Listen out for lazyLoad events
|
||||
if(!this.disableUI && $tw.wiki.getTiddlerText(this.titleSyncDisableLazyLoading) !== "yes") {
|
||||
if(!this.disableUI && this.wiki.getTiddlerText(this.titleSyncDisableLazyLoading) !== "yes") {
|
||||
this.wiki.addEventListener("lazyLoad",function(title) {
|
||||
self.handleLazyLoadEvent(title);
|
||||
});
|
||||
@@ -180,12 +188,14 @@ Syncer.prototype.readTiddlerInfo = function() {
|
||||
var self = this,
|
||||
tiddlers = this.getSyncedTiddlers();
|
||||
$tw.utils.each(tiddlers,function(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)
|
||||
};
|
||||
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)
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -202,7 +212,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($tw.wiki.getChangeCount(title) > tiddlerInfo.changeCount) {
|
||||
if(this.wiki.getChangeCount(title) > tiddlerInfo.changeCount) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
@@ -398,15 +408,27 @@ Syncer.prototype.handleLoginEvent = function() {
|
||||
var self = this;
|
||||
this.getStatus(function(err,isLoggedIn,username) {
|
||||
if(!err && !isLoggedIn) {
|
||||
$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
|
||||
}
|
||||
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();
|
||||
});
|
||||
return true; // Get rid of the password prompt
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -524,7 +546,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 || $tw.wiki.getChangeCount(title) > tiddlerInfo.changeCount,
|
||||
var hasChanged = !tiddlerInfo || this.wiki.getChangeCount(title) > tiddlerInfo.changeCount,
|
||||
isReadyToSave = !tiddlerInfo || !tiddlerInfo.timestampLastSaved || tiddlerInfo.timestampLastSaved < thresholdLastSaved;
|
||||
if(hasChanged) {
|
||||
if(isReadyToSave) {
|
||||
@@ -581,6 +603,8 @@ 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");
|
||||
|
||||
@@ -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 = $tw.wiki.doesPluginInfoRequireReload(JSON.parse(incomingTiddler.text)) ? ($tw.wiki.getTiddlerText("$:/language/ControlPanel/Plugins/PluginWillRequireReload") + " ") : "";
|
||||
var requiresReload = wiki.doesPluginInfoRequireReload(JSON.parse(incomingTiddler.text)) ? (wiki.getTiddlerText("$:/language/ControlPanel/Plugins/PluginWillRequireReload") + " ") : "";
|
||||
messages[title] = requiresReload;
|
||||
if(incomingTiddler.version) {
|
||||
// Upgrade the incoming plugin if it is in the upgrade library
|
||||
|
||||
@@ -20,15 +20,27 @@
|
||||
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
|
||||
output += String.fromCharCode((charCode >> 12) | 224),
|
||||
output += String.fromCharCode(((charCode >> 6) & 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);
|
||||
output += String.fromCharCode((charCode & 63) | 128);
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
@@ -41,15 +53,21 @@
|
||||
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
|
||||
output += String.fromCharCode(((charCode & 15) << 12) | ((string.charCodeAt(i + 1) & 63) << 6) | (string.charCodeAt(i + 2) & 63)),
|
||||
} else if ((charCode > 223) && (charCode < 240)) {
|
||||
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;
|
||||
|
||||
@@ -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++)(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"]);
|
||||
!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"]);
|
||||
@@ -29,23 +29,23 @@ exports.removeChildren = function(node) {
|
||||
};
|
||||
|
||||
exports.hasClass = function(el,className) {
|
||||
return el && el.className && el.className.toString().split(" ").indexOf(className) !== -1;
|
||||
return el && el.hasAttribute && el.hasAttribute("class") && el.getAttribute("class").split(" ").indexOf(className) !== -1;
|
||||
};
|
||||
|
||||
exports.addClass = function(el,className) {
|
||||
var c = el.className.split(" ");
|
||||
var c = (el.getAttribute("class") || "").split(" ");
|
||||
if(c.indexOf(className) === -1) {
|
||||
c.push(className);
|
||||
el.className = c.join(" ");
|
||||
el.setAttribute("class",c.join(" "));
|
||||
}
|
||||
};
|
||||
|
||||
exports.removeClass = function(el,className) {
|
||||
var c = el.className.split(" "),
|
||||
var c = (el.getAttribute("class") || "").split(" "),
|
||||
p = c.indexOf(className);
|
||||
if(p !== -1) {
|
||||
c.splice(p,1);
|
||||
el.className = c.join(" ");
|
||||
el.setAttribute("class",c.join(" "));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -24,6 +24,16 @@ 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 = "",
|
||||
@@ -63,10 +73,10 @@ exports.httpRequest = function(options) {
|
||||
request.setRequestHeader(headerTitle,header);
|
||||
});
|
||||
}
|
||||
if(data && !$tw.utils.hop(headers,"Content-type")) {
|
||||
request.setRequestHeader("Content-type","application/x-www-form-urlencoded; charset=UTF-8");
|
||||
if(data && !hasHeader("Content-Type")) {
|
||||
request.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
|
||||
}
|
||||
if(!$tw.utils.hop(headers,"X-Requested-With")) {
|
||||
if(!hasHeader("X-Requested-With")) {
|
||||
request.setRequestHeader("X-Requested-With","TiddlyWiki");
|
||||
}
|
||||
try {
|
||||
|
||||
@@ -49,7 +49,12 @@ Handle an event
|
||||
*/
|
||||
PageScroller.prototype.handleEvent = function(event) {
|
||||
if(event.type === "tm-scroll") {
|
||||
return this.scrollIntoView(event.target);
|
||||
if(event.paramObject && event.paramObject.selector) {
|
||||
this.scrollSelectorIntoView(null,event.paramObject.selector);
|
||||
} else {
|
||||
this.scrollIntoView(event.target);
|
||||
}
|
||||
return false; // Event was handled
|
||||
}
|
||||
return true;
|
||||
};
|
||||
@@ -117,6 +122,14 @@ 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;
|
||||
|
||||
})();
|
||||
|
||||
@@ -21,14 +21,32 @@ 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 3;
|
||||
return this.TEXT_NODE;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -49,6 +67,8 @@ 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;
|
||||
@@ -69,7 +89,7 @@ Object.defineProperty(TW_Element.prototype, "style", {
|
||||
|
||||
Object.defineProperty(TW_Element.prototype, "nodeType", {
|
||||
get: function() {
|
||||
return 1;
|
||||
return this.ELEMENT_NODE;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -15,13 +15,33 @@ 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 = $tw.utils.removeTrailingSeparator(srcPath);
|
||||
dstPath = $tw.utils.removeTrailingSeparator(dstPath);
|
||||
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";
|
||||
}
|
||||
// Create the destination directory
|
||||
var err = $tw.utils.createDirectory(dstPath);
|
||||
if(err) {
|
||||
|
||||
@@ -94,6 +94,36 @@ 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)
|
||||
*/
|
||||
@@ -801,4 +831,57 @@ 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);
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
@@ -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 */
|
||||
/*global $tw:false, require:false, exports:false */
|
||||
"use strict";
|
||||
|
||||
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
||||
@@ -36,9 +36,15 @@ 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");
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -57,7 +63,7 @@ CreateTiddlerWidget.prototype.refresh = function(changedTiddlers) {
|
||||
Invoke the action associated with this widget
|
||||
*/
|
||||
CreateTiddlerWidget.prototype.invokeAction = function(triggeringWidget,event) {
|
||||
var title = this.wiki.generateNewTitle(this.actionBaseTitle),
|
||||
var title = this.wiki.getTiddlerText("$:/language/DefaultNewTiddlerTitle"), // Get the initial new-tiddler title
|
||||
fields = {},
|
||||
creationFields,
|
||||
modificationFields;
|
||||
@@ -70,7 +76,22 @@ CreateTiddlerWidget.prototype.invokeAction = function(triggeringWidget,event) {
|
||||
creationFields = this.wiki.getCreationFields();
|
||||
modificationFields = this.wiki.getModificationFields();
|
||||
}
|
||||
var tiddler = this.wiki.addTiddler(new $tw.Tiddler(creationFields,fields,modificationFields,{title: title}));
|
||||
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}));
|
||||
if(this.actionSaveTitle) {
|
||||
this.wiki.setTextReference(this.actionSaveTitle,title,this.getVariable("currentTiddler"));
|
||||
}
|
||||
|
||||
@@ -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,6 +70,8 @@ ActionPopupWidget.prototype.invokeAction = function(triggeringWidget,event) {
|
||||
title: this.actionState,
|
||||
wiki: this.wiki
|
||||
});
|
||||
} else {
|
||||
$tw.popup.cancel(0);
|
||||
}
|
||||
return true; // Action was invoked
|
||||
};
|
||||
|
||||
@@ -46,6 +46,9 @@ 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);
|
||||
@@ -83,6 +86,7 @@ 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");
|
||||
};
|
||||
|
||||
@@ -91,7 +91,8 @@ ButtonWidget.prototype.render = function(parent,nextSibling) {
|
||||
handled = true;
|
||||
}
|
||||
if(self.actions) {
|
||||
self.invokeActionString(self.actions,self,event);
|
||||
var modifierKey = $tw.keyboardManager.getEventModifierKeyDescriptor(event);
|
||||
self.invokeActionString(self.actions,self,event,{modifier: modifierKey});
|
||||
}
|
||||
if(handled) {
|
||||
event.preventDefault();
|
||||
|
||||
@@ -45,7 +45,7 @@ CountWidget.prototype.execute = function() {
|
||||
if(this.filter) {
|
||||
this.currentCount = this.wiki.filterTiddlers(this.filter,this).length;
|
||||
} else {
|
||||
this.currentCount = undefined;
|
||||
this.currentCount = "0";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ DroppableWidget.prototype.render = function(parent,nextSibling) {
|
||||
}
|
||||
// Create element and assign classes
|
||||
var domNode = this.document.createElement(tag),
|
||||
classes = (this["class"] || "").split(" ");
|
||||
classes = (this.droppableClass || "").split(" ");
|
||||
classes.push("tc-droppable");
|
||||
domNode.className = classes.join(" ");
|
||||
// Add event handlers
|
||||
@@ -75,7 +75,9 @@ 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 = [];
|
||||
$tw.utils.removeClass(this.domNodes[0],"tc-dragover");
|
||||
if(this.domNodes[0]) {
|
||||
$tw.utils.removeClass(this.domNodes[0],"tc-dragover");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -130,8 +132,7 @@ DroppableWidget.prototype.handleDropEvent = function(event) {
|
||||
|
||||
DroppableWidget.prototype.performActions = function(title,event) {
|
||||
if(this.droppableActions) {
|
||||
var modifierKey = event.ctrlKey && ! event.shiftKey ? "ctrl" : event.shiftKey && !event.ctrlKey ? "shift" :
|
||||
event.ctrlKey && event.shiftKey ? "ctrl-shift" : "normal" ;
|
||||
var modifierKey = $tw.keyboardManager.getEventModifierKeyDescriptor(event);
|
||||
this.invokeActionString(this.droppableActions,this,event,{actionTiddler: title, modifier: modifierKey});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -35,7 +35,7 @@ DropZoneWidget.prototype.render = function(parent,nextSibling) {
|
||||
this.execute();
|
||||
// Create element
|
||||
var domNode = this.document.createElement("div");
|
||||
domNode.className = "tc-dropzone";
|
||||
domNode.className = this.dropzoneClass || "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)});
|
||||
self.dispatchEvent({type: "tm-import-tiddlers", param: JSON.stringify(tiddlerFieldsArray), autoOpenOnImport: self.autoOpenOnImport, importTitle: self.importTitle});
|
||||
};
|
||||
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)});
|
||||
self.dispatchEvent({type: "tm-import-tiddlers", param: JSON.stringify(tiddlerFieldsArray), autoOpenOnImport: self.autoOpenOnImport, importTitle: self.importTitle});
|
||||
};
|
||||
// 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])});
|
||||
self.dispatchEvent({type: "tm-import-tiddlers", param: JSON.stringify([tiddlerFields]), autoOpenOnImport: self.autoOpenOnImport, importTitle: self.importTitle});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -190,8 +190,11 @@ 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();
|
||||
};
|
||||
@@ -201,7 +204,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) {
|
||||
if(changedAttributes.enable || changedAttributes.autoOpenOnImport || changedAttributes.importTitle || changedAttributes.deserializer || changedAttributes.class) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -48,20 +48,15 @@ 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: {
|
||||
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}
|
||||
},
|
||||
attributes: this.parseTreeNode.attributes,
|
||||
children: this.parseTreeNode.children
|
||||
}]);
|
||||
};
|
||||
@@ -94,7 +89,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 || (changedTiddlers[this.editTitle] && this.getEditorType() !== this.editorType)) {
|
||||
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.tabindex || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || (changedTiddlers[this.editTitle] && this.getEditorType() !== this.editorType)) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
} else {
|
||||
|
||||
@@ -29,45 +29,47 @@ Render this widget into the DOM
|
||||
ElementWidget.prototype.render = function(parent,nextSibling) {
|
||||
this.parentDomNode = parent;
|
||||
this.computeAttributes();
|
||||
this.execute();
|
||||
// Neuter blacklisted elements
|
||||
var tag = this.parseTreeNode.tag;
|
||||
if($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {
|
||||
tag = "safe-" + tag;
|
||||
this.tag = this.parseTreeNode.tag;
|
||||
if($tw.config.htmlUnsafeElements.indexOf(this.tag) !== -1) {
|
||||
this.tag = "safe-" + this.tag;
|
||||
}
|
||||
// Adjust headings by the current base level
|
||||
var headingLevel = ["h1","h2","h3","h4","h5","h6"].indexOf(tag);
|
||||
var headingLevel = ["h1","h2","h3","h4","h5","h6"].indexOf(this.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);
|
||||
tag = "h" + headingLevel;
|
||||
this.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.parseTreeNode.tag];
|
||||
this.namespace = tagNamespaces[this.tag];
|
||||
if(this.namespace) {
|
||||
this.setVariable("namespace",this.namespace);
|
||||
} else {
|
||||
this.namespace = this.getVariable("namespace",{defaultValue: "http://www.w3.org/1999/xhtml"});
|
||||
}
|
||||
// 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);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -77,8 +79,13 @@ ElementWidget.prototype.refresh = function(changedTiddlers) {
|
||||
var changedAttributes = this.computeAttributes(),
|
||||
hasChangedAttributes = $tw.utils.count(changedAttributes) > 0;
|
||||
if(hasChangedAttributes) {
|
||||
// Update our attributes
|
||||
this.assignAttributes(this.domNodes[0],{excludeEventAttributes: true});
|
||||
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();
|
||||
}
|
||||
}
|
||||
return this.refreshChildren(changedTiddlers) || hasChangedAttributes;
|
||||
};
|
||||
|
||||
@@ -28,6 +28,7 @@ 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));
|
||||
|
||||
@@ -42,44 +42,53 @@ 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 exclusion list
|
||||
var exclude;
|
||||
if(this.exclude) {
|
||||
exclude = this.exclude.split(" ");
|
||||
} else {
|
||||
exclude = ["text"];
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
// Compose the template
|
||||
var text = [];
|
||||
if(this.template && tiddler) {
|
||||
var fields = [];
|
||||
for(var fieldName in tiddler.fields) {
|
||||
if(exclude.indexOf(fieldName) === -1) {
|
||||
fields.push(fieldName);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
fields.sort();
|
||||
for(var f=0; f<fields.length; f++) {
|
||||
if (this.sort) fields.sort();
|
||||
if (this.sortReverse) fields.reverse();
|
||||
for(var f=0, fmax=fields.length; f<fmax; f++) {
|
||||
fieldName = fields[f];
|
||||
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];
|
||||
}
|
||||
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("");
|
||||
@@ -90,11 +99,13 @@ 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.stripTitlePrefix || changedTiddlers[this.tiddlerTitle]) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
if( changedAttributes.tiddler || changedAttributes.template || changedAttributes.exclude ||
|
||||
changedAttributes.include || changedAttributes.sort || changedAttributes.sortReverse ||
|
||||
changedTiddlers[this.tiddlerTitle] || changedAttributes.stripTitlePrefix) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@ 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
|
||||
@@ -70,7 +72,14 @@ ImportVariablesWidget.prototype.execute = function(tiddlerList) {
|
||||
widgetPointer.variables[key] = widget.variables[key];
|
||||
});
|
||||
} else {
|
||||
widgetPointer.makeChildWidgets([node]);
|
||||
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 = widgetPointer.children[0];
|
||||
}
|
||||
parseTreeNode = parseTreeNode.children && parseTreeNode.children[0];
|
||||
|
||||
@@ -60,7 +60,8 @@ LinkWidget.prototype.renderLink = function(parent,nextSibling) {
|
||||
tag = "a";
|
||||
}
|
||||
// Create our element
|
||||
var domNode = this.document.createElement(tag);
|
||||
var namespace = this.getVariable("namespace",{defaultValue: "http://www.w3.org/1999/xhtml"}),
|
||||
domNode = this.document.createElementNS(namespace,tag);
|
||||
// Assign classes
|
||||
var classes = [];
|
||||
if(this.overrideClasses === undefined) {
|
||||
@@ -102,7 +103,8 @@ 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") {
|
||||
domNode.setAttribute("href",wikiLinkText);
|
||||
var namespaceHref = (namespace === "http://www.w3.org/2000/svg") ? "http://www.w3.org/1999/xlink" : undefined;
|
||||
domNode.setAttributeNS(namespaceHref,"href",wikiLinkText);
|
||||
}
|
||||
// Set the tabindex
|
||||
if(this.tabIndex) {
|
||||
@@ -156,7 +158,8 @@ LinkWidget.prototype.handleClickEvent = function(event) {
|
||||
metaKey: event.metaKey,
|
||||
ctrlKey: event.ctrlKey,
|
||||
altKey: event.altKey,
|
||||
shiftKey: event.shiftKey
|
||||
shiftKey: event.shiftKey,
|
||||
event: event
|
||||
});
|
||||
if(this.domNodes[0].hasAttribute("href")) {
|
||||
event.preventDefault();
|
||||
|
||||
@@ -87,7 +87,8 @@ LinkCatcherWidget.prototype.handleNavigateEvent = function(event) {
|
||||
}
|
||||
if(this.catchActions) {
|
||||
this.executingActions = true;
|
||||
this.invokeActionString(this.catchActions,this,event,{navigateTo: event.navigateTo});
|
||||
var modifierKey = $tw.keyboardManager.getEventModifierKeyDescriptor(event);
|
||||
this.invokeActionString(this.catchActions,this,event,{navigateTo: event.navigateTo, modifier: modifierKey});
|
||||
this.executingActions = false;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -87,8 +87,14 @@ ListWidget.prototype.getTiddlerList = function() {
|
||||
};
|
||||
|
||||
ListWidget.prototype.getEmptyMessage = function() {
|
||||
var emptyMessage = this.getAttribute("emptyMessage",""),
|
||||
parser = this.wiki.parseText("text/vnd.tiddlywiki",emptyMessage,{parseAsInline: true});
|
||||
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});
|
||||
if(parser) {
|
||||
return parser.tree;
|
||||
} else {
|
||||
|
||||
@@ -73,6 +73,8 @@ 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});
|
||||
|
||||
@@ -60,12 +60,13 @@ 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();
|
||||
};
|
||||
@@ -75,7 +76,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 || changedAttributes.openLinkFromInsideRiver || changedAttributes.openLinkFromOutsideRiver || changedAttributes.singleTiddlerMode || changedAttributes.relinkOnRename) {
|
||||
if(changedAttributes.story || changedAttributes.history) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
} else {
|
||||
@@ -126,17 +127,12 @@ NavigatorWidget.prototype.replaceFirstTitleInStory = function(storyList,oldTitle
|
||||
};
|
||||
|
||||
NavigatorWidget.prototype.addToStory = function(title,fromTitle) {
|
||||
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);
|
||||
if(this.storyTitle) {
|
||||
this.story.addToStory(title,fromTitle,this.storyTitle,{
|
||||
openLinkFromInsideRiver: this.getAttribute("openLinkFromInsideRiver","top"),
|
||||
openLinkFromOutsideRiver: this.getAttribute("openLinkFromOutsideRiver","top")
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -145,7 +141,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.wiki.addToHistory(title,fromPageRect,this.historyTitle);
|
||||
this.story.addToHistory(title,fromPageRect,this.historyTitle);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -164,34 +160,11 @@ NavigatorWidget.prototype.handleNavigateEvent = function(event) {
|
||||
|
||||
// Close a specified tiddler
|
||||
NavigatorWidget.prototype.handleCloseTiddlerEvent = function(event) {
|
||||
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);
|
||||
}
|
||||
var title = event.param || event.tiddlerTitle,
|
||||
storyList = this.getStoryList();
|
||||
// Look for tiddlers with this title to close
|
||||
this.removeTitleFromStory(storyList,title);
|
||||
this.saveStoryList(storyList);
|
||||
return false;
|
||||
};
|
||||
|
||||
@@ -305,7 +278,9 @@ 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(
|
||||
var draftTiddler = new $tw.Tiddler({
|
||||
text: "",
|
||||
},
|
||||
tiddler,
|
||||
{
|
||||
title: draftTitle,
|
||||
@@ -352,11 +327,11 @@ NavigatorWidget.prototype.handleSaveTiddlerEvent = function(event) {
|
||||
"draft.title": undefined,
|
||||
"draft.of": undefined
|
||||
},this.wiki.getModificationFields());
|
||||
newTiddler = $tw.hooks.invokeHook("th-saving-tiddler",newTiddler);
|
||||
newTiddler = $tw.hooks.invokeHook("th-saving-tiddler",newTiddler,tiddler);
|
||||
this.wiki.addTiddler(newTiddler);
|
||||
// If enabled, relink references to renamed tiddler
|
||||
if(isRename && this.relinkOnRename && this.wiki.tiddlerExists(draftOf)) {
|
||||
console.log("Relinking '" + draftOf + "' to '" + draftTitle + "'");
|
||||
var shouldRelink = this.getAttribute("relinkOnRename","no").toLowerCase().trim() === "yes";
|
||||
if(isRename && shouldRelink && this.wiki.tiddlerExists(draftOf)) {
|
||||
this.wiki.relinkTiddler(draftOf,draftTitle);
|
||||
}
|
||||
// Remove the draft tiddler
|
||||
@@ -525,10 +500,11 @@ NavigatorWidget.prototype.handleImportTiddlersEvent = function(event) {
|
||||
} catch(e) {
|
||||
}
|
||||
// Get the current $:/Import tiddler
|
||||
var importTiddler = this.wiki.getTiddler(IMPORT_TITLE),
|
||||
importData = this.wiki.getTiddlerData(IMPORT_TITLE,{}),
|
||||
var importTitle = event.importTitle ? event.importTitle : IMPORT_TITLE,
|
||||
importTiddler = this.wiki.getTiddler(importTitle),
|
||||
importData = this.wiki.getTiddlerData(importTitle,{}),
|
||||
newFields = new Object({
|
||||
title: IMPORT_TITLE,
|
||||
title: importTitle,
|
||||
type: "application/json",
|
||||
"plugin-type": "import",
|
||||
"status": "pending"
|
||||
@@ -559,15 +535,16 @@ 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
|
||||
if(this.getVariable("tv-auto-open-on-import") !== "no") {
|
||||
var autoOpenOnImport = event.autoOpenOnImport ? event.autoOpenOnImport : this.getVariable("tv-auto-open-on-import");
|
||||
if(autoOpenOnImport !== "no") {
|
||||
var storyList = this.getStoryList(),
|
||||
history = [];
|
||||
// Add it to the story
|
||||
if(storyList && storyList.indexOf(IMPORT_TITLE) === -1) {
|
||||
storyList.unshift(IMPORT_TITLE);
|
||||
if(storyList && storyList.indexOf(importTitle) === -1) {
|
||||
storyList.unshift(importTitle);
|
||||
}
|
||||
// And to history
|
||||
history.push(IMPORT_TITLE);
|
||||
history.push(importTitle);
|
||||
// Save the updated story and history
|
||||
this.saveStoryList(storyList);
|
||||
this.addToHistory(history);
|
||||
@@ -586,10 +563,14 @@ NavigatorWidget.prototype.handlePerformImportEvent = function(event) {
|
||||
$tw.utils.each(importData.tiddlers,function(tiddlerFields) {
|
||||
var title = tiddlerFields.title;
|
||||
if(title && importTiddler && importTiddler.fields["selection-" + title] !== "unchecked") {
|
||||
var tiddler = new $tw.Tiddler(tiddlerFields);
|
||||
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);
|
||||
}
|
||||
tiddler = $tw.hooks.invokeHook("th-importing-tiddler",tiddler);
|
||||
self.wiki.addTiddler(tiddler);
|
||||
importReport.push("# [[" + tiddlerFields.title + "]]");
|
||||
importReport.push("# [[" + tiddler.fields.title + "]]");
|
||||
}
|
||||
});
|
||||
// Replace the $:/Import tiddler with an import report
|
||||
@@ -640,10 +621,13 @@ NavigatorWidget.prototype.handleUnfoldAllTiddlersEvent = function(event) {
|
||||
};
|
||||
|
||||
NavigatorWidget.prototype.handleRenameTiddlerEvent = function(event) {
|
||||
var paramObject = event.paramObject || {},
|
||||
var options = {},
|
||||
paramObject = event.paramObject || {},
|
||||
from = paramObject.from || event.tiddlerTitle,
|
||||
to = paramObject.to;
|
||||
this.wiki.renameTiddler(from,to);
|
||||
options.dontRenameInTags = (paramObject.renameInTags === "false" || paramObject.renameInTags === "no") ? true : false;
|
||||
options.dontRenameInLists = (paramObject.renameInLists === "false" || paramObject.renameInLists === "no") ? true : false;
|
||||
this.wiki.renameTiddler(from,to,options);
|
||||
};
|
||||
|
||||
exports.navigator = NavigatorWidget;
|
||||
|
||||
@@ -49,7 +49,8 @@ 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: "input", handlerObject: this, handlerMethod: "handleInputEvent"},
|
||||
{name: "change", handlerObject: this, handlerMethod: "handleInputEvent"}
|
||||
]);
|
||||
// Insert the label into the DOM and render any children
|
||||
parent.insertBefore(this.inputDomNode,nextSibling);
|
||||
@@ -124,4 +125,4 @@ RangeWidget.prototype.refresh = function(changedTiddlers) {
|
||||
|
||||
exports.range = RangeWidget;
|
||||
|
||||
})();
|
||||
})();
|
||||
|
||||
@@ -58,7 +58,11 @@ ScrollableWidget.prototype.handleScrollEvent = function(event) {
|
||||
if(this.outerDomNode.scrollWidth <= this.outerDomNode.offsetWidth && this.outerDomNode.scrollHeight <= this.outerDomNode.offsetHeight && this.fallthrough === "yes") {
|
||||
return true;
|
||||
}
|
||||
this.scrollIntoView(event.target);
|
||||
if(event.paramObject && event.paramObject.selector) {
|
||||
this.scrollSelectorIntoView(null,event.paramObject.selector);
|
||||
} else {
|
||||
this.scrollIntoView(event.target);
|
||||
}
|
||||
return false; // Handled event
|
||||
};
|
||||
|
||||
@@ -66,7 +70,8 @@ ScrollableWidget.prototype.handleScrollEvent = function(event) {
|
||||
Scroll an element into view
|
||||
*/
|
||||
ScrollableWidget.prototype.scrollIntoView = function(element) {
|
||||
var duration = $tw.utils.getAnimationDuration();
|
||||
var duration = $tw.utils.getAnimationDuration(),
|
||||
srcWindow = element ? element.ownerDocument.defaultView : window;
|
||||
this.cancelScroll();
|
||||
this.startTime = Date.now();
|
||||
var scrollPosition = {
|
||||
@@ -122,13 +127,21 @@ 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(window,drawFrame);
|
||||
self.idRequestFrame = self.requestAnimationFrame.call(srcWindow,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
|
||||
*/
|
||||
|
||||
@@ -421,6 +421,7 @@ 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) {
|
||||
@@ -570,6 +571,16 @@ 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
Reference in New Issue
Block a user