mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2026-08-10 12:58:53 +00:00
Compare commits
113
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2fab886564 | ||
|
|
f4db2300be | ||
|
|
33d3372229 | ||
|
|
7a304df673 | ||
|
|
a273ed05eb | ||
|
|
a4721ce24a | ||
|
|
3cf71365a5 | ||
|
|
799618d9f5 | ||
|
|
3ab6302353 | ||
|
|
85ed513bef | ||
|
|
1832aff565 | ||
|
|
a07ecb6156 | ||
|
|
19177964c8 | ||
|
|
c8e41bfade | ||
|
|
fb4d417629 | ||
|
|
20d6be1e23 | ||
|
|
7898cb8446 | ||
|
|
9a5f4cc0ef | ||
|
|
cda8d7ca8c | ||
|
|
f38e9f0822 | ||
|
|
5848d66e96 | ||
|
|
485051951e | ||
|
|
135e685811 | ||
|
|
99682c5731 | ||
|
|
d58eec47c0 | ||
|
|
059978ec63 | ||
|
|
b5e20a58a6 | ||
|
|
e8fe6b98bc | ||
|
|
317104774c | ||
|
|
deed8631d8 | ||
|
|
d733b77e2f | ||
|
|
46c26a64b9 | ||
|
|
ec81d6663b | ||
|
|
23f0a9bf79 | ||
|
|
bad87c405e | ||
|
|
6f23a078b7 | ||
|
|
c3706b8a79 | ||
|
|
7ca8fb29af | ||
|
|
d39bb5274e | ||
|
|
81b69783c4 | ||
|
|
40cc62f727 | ||
|
|
b349adde16 | ||
|
|
d63a1896b3 | ||
|
|
b65fa11643 | ||
|
|
4043499633 | ||
|
|
6a39a4e13b | ||
|
|
b5153c0066 | ||
|
|
b061f90f87 | ||
|
|
8be83cf01b | ||
|
|
5b5147dade | ||
|
|
ad6ac480f9 | ||
|
|
8168512e95 | ||
|
|
276fdc8634 | ||
|
|
0b38ced43a | ||
|
|
d7e48207b9 | ||
|
|
2c8fafee48 | ||
|
|
a6383aaaea | ||
|
|
61619c07c8 | ||
|
|
09a42a54c0 | ||
|
|
f4f31c37fc | ||
|
|
61e638c972 | ||
|
|
6bdd51d72a | ||
|
|
ed3405672a | ||
|
|
e3af967cbb | ||
|
|
6b0d3fab5d | ||
|
|
13f1689e7e | ||
|
|
4c09a88272 | ||
|
|
fbf110e209 | ||
|
|
3c1d658fad | ||
|
|
5d738673ac | ||
|
|
91871d2ced | ||
|
|
5143da9cce | ||
|
|
186d1b014a | ||
|
|
58e41ee0ad | ||
|
|
97824cc3a3 | ||
|
|
6e493755be | ||
|
|
64fce62075 | ||
|
|
5a4ff56477 | ||
|
|
3889a2a0d0 | ||
|
|
34737f4e28 | ||
|
|
94673a1028 | ||
|
|
b462aaa9a3 | ||
|
|
4552c117fc | ||
|
|
dc7f2a57bb | ||
|
|
7e91bac6b8 | ||
|
|
15ba415a45 | ||
|
|
2405e65308 | ||
|
|
865f36a6f5 | ||
|
|
a36356a07d | ||
|
|
ee23097816 | ||
|
|
e753851d49 | ||
|
|
cae3d0fa2c | ||
|
|
7c020d0eb6 | ||
|
|
afe2ac45d9 | ||
|
|
6791f0f130 | ||
|
|
a2e5c2cca2 | ||
|
|
87ba87bdd2 | ||
|
|
619bdfcab5 | ||
|
|
5ff4e02a61 | ||
|
|
f8170cd50a | ||
|
|
5389dc0fa7 | ||
|
|
2cc7c96eec | ||
|
|
8cd3d4e22c | ||
|
|
37e09d1c25 | ||
|
|
7a080092d0 | ||
|
|
810ac42810 | ||
|
|
88d3f69a3b | ||
|
|
e956bb32e9 | ||
|
|
dd91ac0b82 | ||
|
|
af63a3b920 | ||
|
|
e4fb47ee76 | ||
|
|
7944f42467 | ||
|
|
578c09e0ce |
@@ -10,7 +10,7 @@ jobs:
|
|||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: "${{ env.NODE_VERSION }}"
|
node-version: "${{ env.NODE_VERSION }}"
|
||||||
@@ -30,7 +30,7 @@ jobs:
|
|||||||
TW5_BUILD_MAIN_EDITION: "./editions/prerelease"
|
TW5_BUILD_MAIN_EDITION: "./editions/prerelease"
|
||||||
TW5_BUILD_OUTPUT: "./output/prerelease"
|
TW5_BUILD_OUTPUT: "./output/prerelease"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: "${{ env.NODE_VERSION }}"
|
node-version: "${{ env.NODE_VERSION }}"
|
||||||
@@ -62,7 +62,7 @@ jobs:
|
|||||||
TW5_BUILD_OUTPUT: "./output"
|
TW5_BUILD_OUTPUT: "./output"
|
||||||
TW5_BUILD_ARCHIVE: "./output"
|
TW5_BUILD_ARCHIVE: "./output"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: "${{ env.NODE_VERSION }}"
|
node-version: "${{ env.NODE_VERSION }}"
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
name: ESLint
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [opened, synchronize, reopened]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: lint-${{ github.event.pull_request.number || github.ref_name }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
# Needed for GitHub Checks API
|
||||||
|
checks: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
eslint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 20
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm install --include=dev
|
||||||
|
|
||||||
|
- name: Run ESLint with reviewdog (GitHub Checks)
|
||||||
|
uses: reviewdog/action-eslint@v1
|
||||||
|
with:
|
||||||
|
eslint_flags: '.'
|
||||||
|
reporter: github-pr-check
|
||||||
|
fail_level: error
|
||||||
|
level: error
|
||||||
|
tool_name: ESLint PR code
|
||||||
@@ -73,10 +73,8 @@ rm $TW5_BUILD_OUTPUT/dev/static/*
|
|||||||
|
|
||||||
echo "<a href='./plugins/tiddlywiki/tw2parser/index.html'>Moved to http://tiddlywiki.com/plugins/tiddlywiki/tw2parser/index.html</a>" > $TW5_BUILD_OUTPUT/classicparserdemo.html
|
echo "<a href='./plugins/tiddlywiki/tw2parser/index.html'>Moved to http://tiddlywiki.com/plugins/tiddlywiki/tw2parser/index.html</a>" > $TW5_BUILD_OUTPUT/classicparserdemo.html
|
||||||
echo "<a href='./plugins/tiddlywiki/codemirror/index.html'>Moved to http://tiddlywiki.com/plugins/tiddlywiki/codemirror/index.html</a>" > $TW5_BUILD_OUTPUT/codemirrordemo.html
|
echo "<a href='./plugins/tiddlywiki/codemirror/index.html'>Moved to http://tiddlywiki.com/plugins/tiddlywiki/codemirror/index.html</a>" > $TW5_BUILD_OUTPUT/codemirrordemo.html
|
||||||
echo "<a href='./plugins/tiddlywiki/d3/index.html'>Moved to http://tiddlywiki.com/plugins/tiddlywiki/d3/index.html</a>" > $TW5_BUILD_OUTPUT/d3demo.html
|
|
||||||
echo "<a href='./plugins/tiddlywiki/highlight/index.html'>Moved to http://tiddlywiki.com/plugins/tiddlywiki/highlight/index.html</a>" > $TW5_BUILD_OUTPUT/highlightdemo.html
|
echo "<a href='./plugins/tiddlywiki/highlight/index.html'>Moved to http://tiddlywiki.com/plugins/tiddlywiki/highlight/index.html</a>" > $TW5_BUILD_OUTPUT/highlightdemo.html
|
||||||
echo "<a href='./plugins/tiddlywiki/markdown/index.html'>Moved to http://tiddlywiki.com/plugins/tiddlywiki/markdown/index.html</a>" > $TW5_BUILD_OUTPUT/markdowndemo.html
|
echo "<a href='./plugins/tiddlywiki/markdown/index.html'>Moved to http://tiddlywiki.com/plugins/tiddlywiki/markdown/index.html</a>" > $TW5_BUILD_OUTPUT/markdowndemo.html
|
||||||
echo "<a href='./plugins/tiddlywiki/tahoelafs/index.html'>Moved to http://tiddlywiki.com/plugins/tiddlywiki/tahoelafs/index.html</a>" > $TW5_BUILD_OUTPUT/tahoelafs.html
|
|
||||||
|
|
||||||
# Put the build details into a .tid file so that it can be included in each build (deleted at the end of this script)
|
# Put the build details into a .tid file so that it can be included in each build (deleted at the end of this script)
|
||||||
|
|
||||||
@@ -301,26 +299,6 @@ node $TW5_BUILD_TIDDLYWIKI \
|
|||||||
--rendertiddler $:/core/save/empty plugins/tiddlywiki/katex/empty.html text/plain \
|
--rendertiddler $:/core/save/empty plugins/tiddlywiki/katex/empty.html text/plain \
|
||||||
|| exit 1
|
|| exit 1
|
||||||
|
|
||||||
# /plugins/tiddlywiki/tahoelafs/index.html Demo wiki with Tahoe-LAFS plugin
|
|
||||||
# /plugins/tiddlywiki/tahoelafs/empty.html Empty wiki with Tahoe-LAFS plugin
|
|
||||||
node $TW5_BUILD_TIDDLYWIKI \
|
|
||||||
./editions/tahoelafs \
|
|
||||||
--load $TW5_BUILD_OUTPUT/build.tid \
|
|
||||||
--output $TW5_BUILD_OUTPUT \
|
|
||||||
--rendertiddler $:/core/save/all plugins/tiddlywiki/tahoelafs/index.html text/plain \
|
|
||||||
--rendertiddler $:/core/save/empty plugins/tiddlywiki/tahoelafs/empty.html text/plain \
|
|
||||||
|| exit 1
|
|
||||||
|
|
||||||
# /plugins/tiddlywiki/d3/index.html Demo wiki with D3 plugin
|
|
||||||
# /plugins/tiddlywiki/d3/empty.html Empty wiki with D3 plugin
|
|
||||||
node $TW5_BUILD_TIDDLYWIKI \
|
|
||||||
./editions/d3demo \
|
|
||||||
--load $TW5_BUILD_OUTPUT/build.tid \
|
|
||||||
--output $TW5_BUILD_OUTPUT \
|
|
||||||
--rendertiddler $:/core/save/all plugins/tiddlywiki/d3/index.html text/plain \
|
|
||||||
--rendertiddler $:/core/save/empty plugins/tiddlywiki/d3/empty.html text/plain \
|
|
||||||
|| exit 1
|
|
||||||
|
|
||||||
# /plugins/tiddlywiki/codemirror/index.html Demo wiki with codemirror plugin
|
# /plugins/tiddlywiki/codemirror/index.html Demo wiki with codemirror plugin
|
||||||
# /plugins/tiddlywiki/codemirror/empty.html Empty wiki with codemirror plugin
|
# /plugins/tiddlywiki/codemirror/empty.html Empty wiki with codemirror plugin
|
||||||
node $TW5_BUILD_TIDDLYWIKI \
|
node $TW5_BUILD_TIDDLYWIKI \
|
||||||
|
|||||||
+46
-15
@@ -799,12 +799,13 @@ the password, and to encrypt/decrypt a block of text
|
|||||||
$tw.utils.Crypto = function() {
|
$tw.utils.Crypto = function() {
|
||||||
var sjcl = $tw.node ? (global.sjcl || require("./sjcl.js")) : window.sjcl,
|
var sjcl = $tw.node ? (global.sjcl || require("./sjcl.js")) : window.sjcl,
|
||||||
currentPassword = null,
|
currentPassword = null,
|
||||||
callSjcl = function(method,inputText,password) {
|
callSjcl = function(method,inputText,password,options) {
|
||||||
|
options = options || {};
|
||||||
password = password || currentPassword;
|
password = password || currentPassword;
|
||||||
var outputText;
|
var outputText;
|
||||||
try {
|
try {
|
||||||
if(password) {
|
if(password) {
|
||||||
outputText = sjcl[method](password,inputText);
|
outputText = sjcl[method](password,inputText,options);
|
||||||
}
|
}
|
||||||
} catch(ex) {
|
} catch(ex) {
|
||||||
console.log("Crypto error:" + ex);
|
console.log("Crypto error:" + ex);
|
||||||
@@ -830,7 +831,8 @@ $tw.utils.Crypto = function() {
|
|||||||
return !!currentPassword;
|
return !!currentPassword;
|
||||||
}
|
}
|
||||||
this.encrypt = function(text,password) {
|
this.encrypt = function(text,password) {
|
||||||
return callSjcl("encrypt",text,password);
|
// set default ks:256 -- see: http://bitwiseshiftleft.github.io/sjcl/doc/convenience.js.html
|
||||||
|
return callSjcl("encrypt",text,password,{v:1,iter:10000,ks:256,ts:64,mode:"ccm",adata:"",cipher:"aes"});
|
||||||
};
|
};
|
||||||
this.decrypt = function(text,password) {
|
this.decrypt = function(text,password) {
|
||||||
return callSjcl("decrypt",text,password);
|
return callSjcl("decrypt",text,password);
|
||||||
@@ -1530,7 +1532,8 @@ Define all modules stored in ordinary tiddlers
|
|||||||
*/
|
*/
|
||||||
$tw.Wiki.prototype.defineTiddlerModules = function() {
|
$tw.Wiki.prototype.defineTiddlerModules = function() {
|
||||||
this.each(function(tiddler,title) {
|
this.each(function(tiddler,title) {
|
||||||
if(tiddler.hasField("module-type")) {
|
// Modules in draft tiddlers are disabled
|
||||||
|
if(tiddler.hasField("module-type") && (!tiddler.hasField("draft.of"))) {
|
||||||
switch(tiddler.fields.type) {
|
switch(tiddler.fields.type) {
|
||||||
case "application/javascript":
|
case "application/javascript":
|
||||||
// We only define modules that haven't already been defined, because in the browser modules in system tiddlers are defined in inline script
|
// We only define modules that haven't already been defined, because in the browser modules in system tiddlers are defined in inline script
|
||||||
@@ -1557,6 +1560,11 @@ $tw.Wiki.prototype.defineShadowModules = function() {
|
|||||||
this.eachShadow(function(tiddler,title) {
|
this.eachShadow(function(tiddler,title) {
|
||||||
// Don't define the module if it is overidden by an ordinary tiddler
|
// Don't define the module if it is overidden by an ordinary tiddler
|
||||||
if(!self.tiddlerExists(title) && tiddler.hasField("module-type")) {
|
if(!self.tiddlerExists(title) && tiddler.hasField("module-type")) {
|
||||||
|
if(tiddler.hasField("draft.of")) {
|
||||||
|
// Report a fundamental problem
|
||||||
|
console.warn(`TiddlyWiki: Plugins should not contain tiddlers with a 'draft.of' field: ${tiddler.fields.title}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Define the module
|
// Define the module
|
||||||
$tw.modules.define(tiddler.fields.title,tiddler.fields["module-type"],tiddler.fields.text);
|
$tw.modules.define(tiddler.fields.title,tiddler.fields["module-type"],tiddler.fields.text);
|
||||||
}
|
}
|
||||||
@@ -1976,22 +1984,41 @@ filepath: pathname of the directory containing the specification file
|
|||||||
$tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
|
$tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
|
||||||
var tiddlers = [];
|
var tiddlers = [];
|
||||||
// Read the specification
|
// Read the specification
|
||||||
var filesInfo = $tw.utils.parseJSONSafe(fs.readFileSync(filepath + path.sep + "tiddlywiki.files","utf8"));
|
var filesInfo = $tw.utils.parseJSONSafe(fs.readFileSync(filepath + path.sep + "tiddlywiki.files","utf8"), function(e) {
|
||||||
|
console.log("Warning: tiddlywiki.files in " + filepath + " invalid: " + e.message);
|
||||||
|
return {};
|
||||||
|
});
|
||||||
|
|
||||||
// Helper to process a file
|
// Helper to process a file
|
||||||
var processFile = function(filename,isTiddlerFile,fields,isEditableFile,rootPath) {
|
var processFile = function(filename,isTiddlerFile,fields,isEditableFile,rootPath) {
|
||||||
var extInfo = $tw.config.fileExtensionInfo[path.extname(filename)],
|
var extInfo = $tw.config.fileExtensionInfo[path.extname(filename)],
|
||||||
type = (extInfo || {}).type || fields.type || "text/plain",
|
type = (extInfo || {}).type || fields.type || "text/plain",
|
||||||
typeInfo = $tw.config.contentTypeInfo[type] || {},
|
typeInfo = $tw.config.contentTypeInfo[type] || {},
|
||||||
pathname = path.resolve(filepath,filename),
|
pathname = path.resolve(filepath,filename),
|
||||||
text = fs.readFileSync(pathname,typeInfo.encoding || "utf8"),
|
|
||||||
metadata = $tw.loadMetadataForFile(pathname) || {},
|
metadata = $tw.loadMetadataForFile(pathname) || {},
|
||||||
fileTiddlers;
|
fileTooLarge = false,
|
||||||
|
text, fileTiddlers;
|
||||||
|
|
||||||
|
if("_canonical_uri" in fields) {
|
||||||
|
text = "";
|
||||||
|
} else if(fs.statSync(pathname).size > $tw.config.maxEditFileSize) {
|
||||||
|
var msg = "File " + pathname + " not loaded because it is too large";
|
||||||
|
console.log("Warning: " + msg);
|
||||||
|
fileTooLarge = true;
|
||||||
|
text = isTiddlerFile ? msg : "";
|
||||||
|
} else {
|
||||||
|
text = fs.readFileSync(pathname,typeInfo.encoding || "utf8");
|
||||||
|
}
|
||||||
|
|
||||||
if(isTiddlerFile) {
|
if(isTiddlerFile) {
|
||||||
fileTiddlers = $tw.wiki.deserializeTiddlers(path.extname(pathname),text,metadata) || [];
|
fileTiddlers = $tw.wiki.deserializeTiddlers(fileTooLarge ? ".txt" : path.extname(pathname),text,metadata) || [];
|
||||||
} else {
|
} else {
|
||||||
fileTiddlers = [$tw.utils.extend({text: text},metadata)];
|
fileTiddlers = [$tw.utils.extend({text: text},metadata)];
|
||||||
}
|
}
|
||||||
var combinedFields = $tw.utils.extend({},fields,metadata);
|
var combinedFields = $tw.utils.extend({},fields,metadata);
|
||||||
|
if(fileTooLarge && isTiddlerFile) {
|
||||||
|
delete combinedFields.type; // type altered
|
||||||
|
}
|
||||||
$tw.utils.each(fileTiddlers,function(tiddler) {
|
$tw.utils.each(fileTiddlers,function(tiddler) {
|
||||||
$tw.utils.each(combinedFields,function(fieldInfo,name) {
|
$tw.utils.each(combinedFields,function(fieldInfo,name) {
|
||||||
if(typeof fieldInfo === "string" || $tw.utils.isArray(fieldInfo)) {
|
if(typeof fieldInfo === "string" || $tw.utils.isArray(fieldInfo)) {
|
||||||
@@ -2066,6 +2093,7 @@ $tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
|
|||||||
} else if(tidInfo.suffix) {
|
} else if(tidInfo.suffix) {
|
||||||
tidInfo.fields.text = {suffix: tidInfo.suffix};
|
tidInfo.fields.text = {suffix: tidInfo.suffix};
|
||||||
}
|
}
|
||||||
|
tidInfo.fields = tidInfo.fields || {};
|
||||||
processFile(tidInfo.file,tidInfo.isTiddlerFile,tidInfo.fields);
|
processFile(tidInfo.file,tidInfo.isTiddlerFile,tidInfo.fields);
|
||||||
});
|
});
|
||||||
// Process any listed directories
|
// Process any listed directories
|
||||||
@@ -2087,6 +2115,7 @@ $tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
|
|||||||
var thisPath = path.relative(filepath, files[t]),
|
var thisPath = path.relative(filepath, files[t]),
|
||||||
filename = path.basename(thisPath);
|
filename = path.basename(thisPath);
|
||||||
if(filename !== "tiddlywiki.files" && !metaRegExp.test(filename) && fileRegExp.test(filename)) {
|
if(filename !== "tiddlywiki.files" && !metaRegExp.test(filename) && fileRegExp.test(filename)) {
|
||||||
|
dirSpec.fields = dirSpec.fields || {};
|
||||||
processFile(thisPath,dirSpec.isTiddlerFile,dirSpec.fields,dirSpec.isEditableFile,dirSpec.path);
|
processFile(thisPath,dirSpec.isTiddlerFile,dirSpec.fields,dirSpec.isEditableFile,dirSpec.path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2549,10 +2578,10 @@ $tw.boot.execStartup = function(options){
|
|||||||
if($tw.safeMode) {
|
if($tw.safeMode) {
|
||||||
$tw.wiki.processSafeMode();
|
$tw.wiki.processSafeMode();
|
||||||
}
|
}
|
||||||
// Register typed modules from the tiddlers we've just loaded
|
// Register typed modules from the tiddlers we've just loaded and any modules within plugins
|
||||||
$tw.wiki.defineTiddlerModules();
|
// Tiddlers should appear last so that they may overwrite shadows during module registration
|
||||||
// And any modules within plugins
|
|
||||||
$tw.wiki.defineShadowModules();
|
$tw.wiki.defineShadowModules();
|
||||||
|
$tw.wiki.defineTiddlerModules();
|
||||||
// Make sure the crypto state tiddler is up to date
|
// Make sure the crypto state tiddler is up to date
|
||||||
if($tw.crypto) {
|
if($tw.crypto) {
|
||||||
$tw.crypto.updateCryptoStateTiddler();
|
$tw.crypto.updateCryptoStateTiddler();
|
||||||
@@ -2621,11 +2650,13 @@ $tw.boot.executeNextStartupTask = function(callback) {
|
|||||||
$tw.boot.log(s.join(" "));
|
$tw.boot.log(s.join(" "));
|
||||||
// Execute task
|
// Execute task
|
||||||
if(!$tw.utils.hop(task,"synchronous") || task.synchronous) {
|
if(!$tw.utils.hop(task,"synchronous") || task.synchronous) {
|
||||||
task.startup();
|
const thenable = task.startup();
|
||||||
if(task.name) {
|
if(thenable && typeof thenable.then === "function"){
|
||||||
$tw.boot.executedStartupModules[task.name] = true;
|
thenable.then(asyncTaskCallback);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return asyncTaskCallback();
|
||||||
}
|
}
|
||||||
return $tw.boot.executeNextStartupTask(callback);
|
|
||||||
} else {
|
} else {
|
||||||
task.startup(asyncTaskCallback);
|
task.startup(asyncTaskCallback);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ talk.tiddlywiki.org: jeremyruston
|
|||||||
github: Jermolene
|
github: Jermolene
|
||||||
linkedin: www.linkedin.com/in/jermy
|
linkedin: www.linkedin.com/in/jermy
|
||||||
flickr: www.flickr.com/photos/jermy/
|
flickr: www.flickr.com/photos/jermy/
|
||||||
|
bluesky: https://bsky.app/profile/jermolene.bsky.social
|
||||||
homepage: jermolene.com
|
homepage: jermolene.com
|
||||||
email: jeremy@jermolene.com
|
email: jeremy@jermolene.com
|
||||||
avatar: /9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAgICAgJCAkKCgkNDgwODRMREBARExwUFhQWFBwrGx8bGx8bKyYuJSMlLiZENS8vNUROQj5CTl9VVV93cXecnNEBCAgICAkICQoKCQ0ODA4NExEQEBETHBQWFBYUHCsbHxsbHxsrJi4lIyUuJkQ1Ly81RE5CPkJOX1VVX3dxd5yc0f/CABEIACAAIAMBIgACEQEDEQH/xAAtAAEBAAMAAAAAAAAAAAAAAAAHBgIEBQEBAQEBAAAAAAAAAAAAAAAAAgQBBf/aAAwDAQACEAMQAAAANF4uTuPRhD2nBLnUiJvKM0DtMKy//8QAKxAAAgIBAwMDAQkAAAAAAAAAAQIDBBEABRITITEiMkFxFEJRUmFicoGR/9oACAEBAAE/AInTA6gUGP4ZOQbW1bPsmyUq1q+gmvFPUzZPDkPamtwqU75ks04JakroVcg5RwRjg66NUx25KbzqJYyMngfqSuq0M3NZYIebJIvZozIvI/iNPcp/aalSdJXsS4VcKeIzlvU3jVTcYLNiaGISrjkhWQYDfQ63pYAzCDBsOiu7Dsx4EHH6r2w2ttimjd2IsNErhhJHKI04/uzqxuCxpBYVVWKSHqwMyMSQ33SB7dUJFmlkMYRgnqZgCMf7rf8AeEt3A9YOhjXAb2k8u7dtT1RZeOtXmYxiOPj4ZWY/lb51skqUNnNW/wBNzC7IpB6gQeeB/jq/fqGOaLbowuYn5MAQOw8LjW5Vmeo0qIsqYLLKjHIZmwv9fB1//8QAHxEAAQMEAwEAAAAAAAAAAAAAEQABAgMSIWExMkFR/9oACAECAQE/AD9iTy2lJmHUB8BVKM4SNSOj46a29saX/8QAHREAAgICAwEAAAAAAAAAAAAAAQIAAwQRITGBkf/aAAgBAwEBPwDHpFpJZtamVSiBWT2Yt7hmCDsb+TKtsKqpGg3M/9k=
|
avatar: /9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAgICAgJCAkKCgkNDgwODRMREBARExwUFhQWFBwrGx8bGx8bKyYuJSMlLiZENS8vNUROQj5CTl9VVV93cXecnNEBCAgICAkICQoKCQ0ODA4NExEQEBETHBQWFBYUHCsbHxsbHxsrJi4lIyUuJkQ1Ly81RE5CPkJOX1VVX3dxd5yc0f/CABEIACAAIAMBIgACEQEDEQH/xAAtAAEBAAMAAAAAAAAAAAAAAAAHBgIEBQEBAQEBAAAAAAAAAAAAAAAAAgQBBf/aAAwDAQACEAMQAAAANF4uTuPRhD2nBLnUiJvKM0DtMKy//8QAKxAAAgIBAwMDAQkAAAAAAAAAAQIDBBEABRITITEiMkFxFEJRUmFicoGR/9oACAEBAAE/AInTA6gUGP4ZOQbW1bPsmyUq1q+gmvFPUzZPDkPamtwqU75ks04JakroVcg5RwRjg66NUx25KbzqJYyMngfqSuq0M3NZYIebJIvZozIvI/iNPcp/aalSdJXsS4VcKeIzlvU3jVTcYLNiaGISrjkhWQYDfQ63pYAzCDBsOiu7Dsx4EHH6r2w2ttimjd2IsNErhhJHKI04/uzqxuCxpBYVVWKSHqwMyMSQ33SB7dUJFmlkMYRgnqZgCMf7rf8AeEt3A9YOhjXAb2k8u7dtT1RZeOtXmYxiOPj4ZWY/lb51skqUNnNW/wBNzC7IpB6gQeeB/jq/fqGOaLbowuYn5MAQOw8LjW5Vmeo0qIsqYLLKjHIZmwv9fB1//8QAHxEAAQMEAwEAAAAAAAAAAAAAEQABAgMSIWExMkFR/9oACAECAQE/AD9iTy2lJmHUB8BVKM4SNSOj46a29saX/8QAHREAAgICAwEAAAAAAAAAAAAAAQIAAwQRITGBkf/aAAgBAwEBPwDHpFpJZtamVSiBWT2Yt7hmCDsb+TKtsKqpGg3M/9k=
|
||||||
|
|||||||
@@ -99,16 +99,18 @@ Commander.prototype.executeNextCommand = function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(command.info.synchronous) {
|
if(command.info.synchronous) {
|
||||||
// Synchronous command
|
// Synchronous command (await thenables)
|
||||||
c = new command.Command(params,this);
|
c = new command.Command(params,this);
|
||||||
err = c.execute();
|
err = c.execute();
|
||||||
if(err) {
|
if(err && typeof err.then === "function") {
|
||||||
|
err.then(e => { e ? this.callback(e) : this.executeNextCommand(); });
|
||||||
|
} else if(err) {
|
||||||
this.callback(err);
|
this.callback(err);
|
||||||
} else {
|
} else {
|
||||||
this.executeNextCommand();
|
this.executeNextCommand();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Asynchronous command
|
// Asynchronous command (await thenables)
|
||||||
c = new command.Command(params,this,function(err) {
|
c = new command.Command(params,this,function(err) {
|
||||||
if(err) {
|
if(err) {
|
||||||
self.callback(err);
|
self.callback(err);
|
||||||
@@ -117,7 +119,9 @@ Commander.prototype.executeNextCommand = function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
err = c.execute();
|
err = c.execute();
|
||||||
if(err) {
|
if(err && typeof err.then === "function") {
|
||||||
|
err.then(e => { if(e) this.callback(e); });
|
||||||
|
} else if(err) {
|
||||||
this.callback(err);
|
this.callback(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,3 +4,4 @@ This plugin contains TiddlyWiki's core components that are only needed on the se
|
|||||||
|
|
||||||
* Commands
|
* Commands
|
||||||
* HTTP server code
|
* HTTP server code
|
||||||
|
* Utility functions for server
|
||||||
|
|||||||
@@ -8,10 +8,14 @@ DELETE /recipes/default/tiddlers/:title
|
|||||||
\*/
|
\*/
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
exports.method = "DELETE";
|
exports.methods = ["DELETE"];
|
||||||
|
|
||||||
exports.path = /^\/bags\/default\/tiddlers\/(.+)$/;
|
exports.path = /^\/bags\/default\/tiddlers\/(.+)$/;
|
||||||
|
|
||||||
|
exports.info = {
|
||||||
|
priority: 100
|
||||||
|
};
|
||||||
|
|
||||||
exports.handler = function(request,response,state) {
|
exports.handler = function(request,response,state) {
|
||||||
var title = $tw.utils.decodeURIComponentSafe(state.params[0]);
|
var title = $tw.utils.decodeURIComponentSafe(state.params[0]);
|
||||||
state.wiki.deleteTiddler(title);
|
state.wiki.deleteTiddler(title);
|
||||||
|
|||||||
@@ -8,10 +8,14 @@ GET /favicon.ico
|
|||||||
\*/
|
\*/
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
exports.method = "GET";
|
exports.methods = ["GET"];
|
||||||
|
|
||||||
exports.path = /^\/favicon.ico$/;
|
exports.path = /^\/favicon.ico$/;
|
||||||
|
|
||||||
|
exports.info = {
|
||||||
|
priority: 100
|
||||||
|
};
|
||||||
|
|
||||||
exports.handler = function(request,response,state) {
|
exports.handler = function(request,response,state) {
|
||||||
var buffer = state.wiki.getTiddlerText("$:/favicon.ico","");
|
var buffer = state.wiki.getTiddlerText("$:/favicon.ico","");
|
||||||
state.sendResponse(200,{"Content-Type": "image/x-icon"},buffer,"base64");
|
state.sendResponse(200,{"Content-Type": "image/x-icon"},buffer,"base64");
|
||||||
|
|||||||
@@ -8,35 +8,66 @@ GET /files/:filepath
|
|||||||
\*/
|
\*/
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
exports.method = "GET";
|
exports.methods = ["GET"];
|
||||||
|
|
||||||
exports.path = /^\/files\/(.+)$/;
|
exports.path = /^\/files\/(.+)$/;
|
||||||
|
|
||||||
|
exports.info = {
|
||||||
|
priority: 100
|
||||||
|
};
|
||||||
|
|
||||||
exports.handler = function(request,response,state) {
|
exports.handler = function(request,response,state) {
|
||||||
var path = require("path"),
|
var path = require("path"),
|
||||||
fs = require("fs"),
|
fs = require("fs"),
|
||||||
util = require("util"),
|
|
||||||
suppliedFilename = $tw.utils.decodeURIComponentSafe(state.params[0]),
|
suppliedFilename = $tw.utils.decodeURIComponentSafe(state.params[0]),
|
||||||
baseFilename = path.resolve(state.boot.wikiPath,"files"),
|
baseFilename = path.resolve(state.boot.wikiPath,"files"),
|
||||||
filename = path.resolve(baseFilename,suppliedFilename),
|
filename = path.resolve(baseFilename,suppliedFilename),
|
||||||
extension = path.extname(filename);
|
extension = path.extname(filename);
|
||||||
// Check that the filename is inside the wiki files folder
|
// Check that the filename is inside the wiki files folder
|
||||||
if(path.relative(baseFilename,filename).indexOf("..") !== 0) {
|
if(path.relative(baseFilename,filename).indexOf("..") === 0) {
|
||||||
// Send the file
|
return state.sendResponse(404,{"Content-Type": "text/plain"},"File '" + suppliedFilename + "' not found");
|
||||||
fs.readFile(filename,function(err,content) {
|
}
|
||||||
var status,content,type = "text/plain";
|
fs.stat(filename, function(err, stats) {
|
||||||
if(err) {
|
if(err) {
|
||||||
console.log("Error accessing file " + filename + ": " + err.toString());
|
return state.sendResponse(404,{"Content-Type": "text/plain"},"File '" + suppliedFilename + "' not found");
|
||||||
status = 404;
|
|
||||||
content = "File '" + suppliedFilename + "' not found";
|
|
||||||
} else {
|
} else {
|
||||||
status = 200;
|
var type = ($tw.config.fileExtensionInfo[extension] ? $tw.config.fileExtensionInfo[extension].type : "application/octet-stream"),
|
||||||
content = content;
|
responseHeaders = {
|
||||||
type = ($tw.config.fileExtensionInfo[extension] ? $tw.config.fileExtensionInfo[extension].type : "application/octet-stream");
|
"Content-Type": type,
|
||||||
|
"Accept-Ranges": "bytes"
|
||||||
|
};
|
||||||
|
var rangeHeader = request.headers.range,
|
||||||
|
stream;
|
||||||
|
if(rangeHeader) {
|
||||||
|
// Handle range requests
|
||||||
|
var parts = rangeHeader.replace(/bytes=/, "").split("-"),
|
||||||
|
start = parseInt(parts[0], 10),
|
||||||
|
end = parts[1] ? parseInt(parts[1], 10) : stats.size - 1;
|
||||||
|
// Validate start and end
|
||||||
|
if(isNaN(start) || isNaN(end) || start < 0 || end < start || end >= stats.size) {
|
||||||
|
responseHeaders["Content-Range"] = "bytes */" + stats.size;
|
||||||
|
return response.writeHead(416, responseHeaders).end();
|
||||||
}
|
}
|
||||||
state.sendResponse(status,{"Content-Type": type},content);
|
var chunksize = (end - start) + 1;
|
||||||
|
responseHeaders["Content-Range"] = "bytes " + start + "-" + end + "/" + stats.size;
|
||||||
|
responseHeaders["Content-Length"] = chunksize;
|
||||||
|
response.writeHead(206, responseHeaders);
|
||||||
|
stream = fs.createReadStream(filename, {start: start, end: end});
|
||||||
|
} else {
|
||||||
|
responseHeaders["Content-Length"] = stats.size;
|
||||||
|
response.writeHead(200, responseHeaders);
|
||||||
|
stream = fs.createReadStream(filename);
|
||||||
|
}
|
||||||
|
// Common stream error handling
|
||||||
|
stream.on("error", function(err) {
|
||||||
|
if(!response.headersSent) {
|
||||||
|
response.writeHead(500, {"Content-Type": "text/plain"});
|
||||||
|
response.end("Read error");
|
||||||
|
} else {
|
||||||
|
response.destroy();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
stream.pipe(response);
|
||||||
state.sendResponse(404,{"Content-Type": "text/plain"},"File '" + suppliedFilename + "' not found");
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,10 +8,14 @@ GET /
|
|||||||
\*/
|
\*/
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
exports.method = "GET";
|
exports.methods = ["GET"];
|
||||||
|
|
||||||
exports.path = /^\/$/;
|
exports.path = /^\/$/;
|
||||||
|
|
||||||
|
exports.info = {
|
||||||
|
priority: 100
|
||||||
|
};
|
||||||
|
|
||||||
exports.handler = function(request,response,state) {
|
exports.handler = function(request,response,state) {
|
||||||
var text = state.wiki.renderTiddler(state.server.get("root-render-type"),state.server.get("root-tiddler")),
|
var text = state.wiki.renderTiddler(state.server.get("root-render-type"),state.server.get("root-tiddler")),
|
||||||
responseHeaders = {
|
responseHeaders = {
|
||||||
|
|||||||
@@ -8,10 +8,14 @@ GET /login-basic -- force a Basic Authentication challenge
|
|||||||
\*/
|
\*/
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
exports.method = "GET";
|
exports.methods = ["GET"];
|
||||||
|
|
||||||
exports.path = /^\/login-basic$/;
|
exports.path = /^\/login-basic$/;
|
||||||
|
|
||||||
|
exports.info = {
|
||||||
|
priority: 100
|
||||||
|
};
|
||||||
|
|
||||||
exports.handler = function(request,response,state) {
|
exports.handler = function(request,response,state) {
|
||||||
if(!state.authenticatedUsername) {
|
if(!state.authenticatedUsername) {
|
||||||
// Challenge if there's no username
|
// Challenge if there's no username
|
||||||
|
|||||||
@@ -8,10 +8,14 @@ GET /status
|
|||||||
\*/
|
\*/
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
exports.method = "GET";
|
exports.methods = ["GET"];
|
||||||
|
|
||||||
exports.path = /^\/status$/;
|
exports.path = /^\/status$/;
|
||||||
|
|
||||||
|
exports.info = {
|
||||||
|
priority: 100
|
||||||
|
};
|
||||||
|
|
||||||
exports.handler = function(request,response,state) {
|
exports.handler = function(request,response,state) {
|
||||||
var text = JSON.stringify({
|
var text = JSON.stringify({
|
||||||
username: state.authenticatedUsername || state.server.get("anon-username") || "",
|
username: state.authenticatedUsername || state.server.get("anon-username") || "",
|
||||||
|
|||||||
@@ -8,10 +8,14 @@ GET /:title
|
|||||||
\*/
|
\*/
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
exports.method = "GET";
|
exports.methods = ["GET"];
|
||||||
|
|
||||||
exports.path = /^\/([^\/]+)$/;
|
exports.path = /^\/([^\/]+)$/;
|
||||||
|
|
||||||
|
exports.info = {
|
||||||
|
priority: 100
|
||||||
|
};
|
||||||
|
|
||||||
exports.handler = function(request,response,state) {
|
exports.handler = function(request,response,state) {
|
||||||
var title = $tw.utils.decodeURIComponentSafe(state.params[0]),
|
var title = $tw.utils.decodeURIComponentSafe(state.params[0]),
|
||||||
tiddler = state.wiki.getTiddler(title);
|
tiddler = state.wiki.getTiddler(title);
|
||||||
|
|||||||
@@ -8,10 +8,14 @@ GET /recipes/default/tiddlers/:title
|
|||||||
\*/
|
\*/
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
exports.method = "GET";
|
exports.methods = ["GET"];
|
||||||
|
|
||||||
exports.path = /^\/recipes\/default\/tiddlers\/(.+)$/;
|
exports.path = /^\/recipes\/default\/tiddlers\/(.+)$/;
|
||||||
|
|
||||||
|
exports.info = {
|
||||||
|
priority: 100
|
||||||
|
};
|
||||||
|
|
||||||
exports.handler = function(request,response,state) {
|
exports.handler = function(request,response,state) {
|
||||||
var title = $tw.utils.decodeURIComponentSafe(state.params[0]),
|
var title = $tw.utils.decodeURIComponentSafe(state.params[0]),
|
||||||
tiddler = state.wiki.getTiddler(title),
|
tiddler = state.wiki.getTiddler(title),
|
||||||
|
|||||||
@@ -10,10 +10,14 @@ GET /recipes/default/tiddlers.json?filter=<filter>
|
|||||||
|
|
||||||
var DEFAULT_FILTER = "[all[tiddlers]!is[system]sort[title]]";
|
var DEFAULT_FILTER = "[all[tiddlers]!is[system]sort[title]]";
|
||||||
|
|
||||||
exports.method = "GET";
|
exports.methods = ["GET"];
|
||||||
|
|
||||||
exports.path = /^\/recipes\/default\/tiddlers.json$/;
|
exports.path = /^\/recipes\/default\/tiddlers.json$/;
|
||||||
|
|
||||||
|
exports.info = {
|
||||||
|
priority: 100
|
||||||
|
};
|
||||||
|
|
||||||
exports.handler = function(request,response,state) {
|
exports.handler = function(request,response,state) {
|
||||||
var filter = state.queryParameters.filter || DEFAULT_FILTER;
|
var filter = state.queryParameters.filter || DEFAULT_FILTER;
|
||||||
if(state.wiki.getTiddlerText("$:/config/Server/AllowAllExternalFilters") !== "yes") {
|
if(state.wiki.getTiddlerText("$:/config/Server/AllowAllExternalFilters") !== "yes") {
|
||||||
|
|||||||
@@ -8,10 +8,14 @@ PUT /recipes/default/tiddlers/:title
|
|||||||
\*/
|
\*/
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
exports.method = "PUT";
|
exports.methods = ["PUT"];
|
||||||
|
|
||||||
exports.path = /^\/recipes\/default\/tiddlers\/(.+)$/;
|
exports.path = /^\/recipes\/default\/tiddlers\/(.+)$/;
|
||||||
|
|
||||||
|
exports.info = {
|
||||||
|
priority: 100
|
||||||
|
};
|
||||||
|
|
||||||
exports.handler = function(request,response,state) {
|
exports.handler = function(request,response,state) {
|
||||||
var title = $tw.utils.decodeURIComponentSafe(state.params[0]),
|
var title = $tw.utils.decodeURIComponentSafe(state.params[0]),
|
||||||
fields = $tw.utils.parseJSONSafe(state.data);
|
fields = $tw.utils.parseJSONSafe(state.data);
|
||||||
|
|||||||
@@ -74,6 +74,11 @@ function Server(options) {
|
|||||||
// console.log("Loading server route " + title);
|
// console.log("Loading server route " + title);
|
||||||
self.addRoute(routeDefinition);
|
self.addRoute(routeDefinition);
|
||||||
});
|
});
|
||||||
|
this.routes.sort((a, b) => {
|
||||||
|
const priorityA = a.info?.priority ?? 100,
|
||||||
|
priorityB = b.info?.priority ?? 100;
|
||||||
|
return priorityB - priorityA;
|
||||||
|
});
|
||||||
// Initialise the http vs https
|
// Initialise the http vs https
|
||||||
this.listenOptions = null;
|
this.listenOptions = null;
|
||||||
this.protocol = "http";
|
this.protocol = "http";
|
||||||
@@ -217,7 +222,7 @@ Server.prototype.findMatchingRoute = function(request,state) {
|
|||||||
} else {
|
} else {
|
||||||
match = potentialRoute.path.exec(pathname);
|
match = potentialRoute.path.exec(pathname);
|
||||||
}
|
}
|
||||||
if(match && request.method === potentialRoute.method) {
|
if(match && (potentialRoute.methods?.includes(request.method) || potentialRoute.method === request.method)) {
|
||||||
state.params = [];
|
state.params = [];
|
||||||
for(var p=1; p<match.length; p++) {
|
for(var p=1; p<match.length; p++) {
|
||||||
state.params.push(match[p]);
|
state.params.push(match[p]);
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ Settings/AutoSave/Disabled/Description: Do not save changes automatically
|
|||||||
Settings/AutoSave/Enabled/Description: Save changes automatically
|
Settings/AutoSave/Enabled/Description: Save changes automatically
|
||||||
Settings/AutoSave/Hint: Attempt to automatically save changes during editing when using a supporting saver
|
Settings/AutoSave/Hint: Attempt to automatically save changes during editing when using a supporting saver
|
||||||
Settings/CamelCase/Caption: Camel Case Wiki Links
|
Settings/CamelCase/Caption: Camel Case Wiki Links
|
||||||
Settings/CamelCase/Hint: You can globally disable automatic linking of ~CamelCase phrases. Requires reload to take effect
|
Settings/CamelCase/Hint: Requires reload to take effect
|
||||||
Settings/CamelCase/Description: Enable automatic ~CamelCase linking
|
Settings/CamelCase/Description: Enable automatic ~CamelCase linking
|
||||||
Settings/Caption: Settings
|
Settings/Caption: Settings
|
||||||
Settings/EditorToolbar/Caption: Editor Toolbar
|
Settings/EditorToolbar/Caption: Editor Toolbar
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ function FramedEngine(options) {
|
|||||||
var paletteTitle = this.widget.wiki.getTiddlerText("$:/palette");
|
var paletteTitle = this.widget.wiki.getTiddlerText("$:/palette");
|
||||||
var colorScheme = (this.widget.wiki.getTiddler(paletteTitle) || {fields: {}}).fields["color-scheme"] || "light";
|
var colorScheme = (this.widget.wiki.getTiddler(paletteTitle) || {fields: {}}).fields["color-scheme"] || "light";
|
||||||
this.iframeDoc.open();
|
this.iframeDoc.open();
|
||||||
this.iframeDoc.write("<meta name='color-scheme' content='" + colorScheme + "'>");
|
this.iframeDoc.write("<!DOCTYPE html><html><head><meta name='color-scheme' content='" + colorScheme + "'></head><body></body></html>");
|
||||||
this.iframeDoc.close();
|
this.iframeDoc.close();
|
||||||
// Style the iframe
|
// Style the iframe
|
||||||
this.iframeNode.className = this.dummyTextArea.className;
|
this.iframeNode.className = this.dummyTextArea.className;
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
|
|||||||
// Fix height
|
// Fix height
|
||||||
this.engine.fixHeight();
|
this.engine.fixHeight();
|
||||||
// Focus if required
|
// Focus if required
|
||||||
if(this.editFocus === "true" || this.editFocus === "yes") {
|
if($tw.browser && (this.editFocus === "true" || this.editFocus === "yes") && !$tw.utils.hasClass(this.parentDomNode.ownerDocument.activeElement,"tc-keep-focus")) {
|
||||||
this.engine.focus();
|
this.engine.focus();
|
||||||
}
|
}
|
||||||
// Add widget message listeners
|
// Add widget message listeners
|
||||||
|
|||||||
@@ -16,12 +16,8 @@ exports.json = function(source,operand,options) {
|
|||||||
spaces = /^\d+$/.test(operand) ? parseInt(operand,10) : operand;
|
spaces = /^\d+$/.test(operand) ? parseInt(operand,10) : operand;
|
||||||
}
|
}
|
||||||
source(function(tiddler,title) {
|
source(function(tiddler,title) {
|
||||||
var data = $tw.utils.parseJSONSafe(title);
|
var data = $tw.utils.parseJSONSafe(title,function(){return undefined;});
|
||||||
try {
|
|
||||||
data = JSON.parse(title);
|
|
||||||
} catch(e) {
|
|
||||||
data = undefined;
|
|
||||||
}
|
|
||||||
if(data !== undefined) {
|
if(data !== undefined) {
|
||||||
results.push(JSON.stringify(data,null,spaces));
|
results.push(JSON.stringify(data,null,spaces));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -217,6 +217,10 @@ function makeNumericReducingOperator(fnCalc,initialValue,fnFinal) {
|
|||||||
source(function(tiddler,title) {
|
source(function(tiddler,title) {
|
||||||
result.push($tw.utils.parseNumber(title));
|
result.push($tw.utils.parseNumber(title));
|
||||||
});
|
});
|
||||||
|
// We return an empty array if there are no input titles
|
||||||
|
if(result.length === 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
var value = result.reduce(function(accumulator,currentValue) {
|
var value = result.reduce(function(accumulator,currentValue) {
|
||||||
return fnCalc(accumulator,currentValue);
|
return fnCalc(accumulator,currentValue);
|
||||||
},initialValue);
|
},initialValue);
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/info/windowdimensions.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: info
|
||||||
|
\*/
|
||||||
|
|
||||||
|
exports.getInfoTiddlerFields = function(updateInfoTiddlersCallback) {
|
||||||
|
if(!$tw.browser) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
class WindowDimensionsTracker {
|
||||||
|
constructor(updateCallback) {
|
||||||
|
this.updateCallback = updateCallback;
|
||||||
|
this.resizeHandlers = new Map();
|
||||||
|
this.dimensionsInfo = [
|
||||||
|
["outer/width", win => win.outerWidth],
|
||||||
|
["outer/height", win => win.outerHeight],
|
||||||
|
["inner/width", win => win.innerWidth],
|
||||||
|
["inner/height", win => win.innerHeight],
|
||||||
|
["client/width", win => win.document.documentElement.clientWidth],
|
||||||
|
["client/height", win => win.document.documentElement.clientHeight]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTiddlers(win,windowId) {
|
||||||
|
const prefix = `$:/info/browser/window/${windowId}/`;
|
||||||
|
return this.dimensionsInfo.map(([suffix, getter]) => ({
|
||||||
|
title: prefix + suffix,
|
||||||
|
text: String(getter(win))
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
clearTiddlers(windowId) {
|
||||||
|
const prefix = `$:/info/browser/window/${windowId}/`,
|
||||||
|
deletions = this.dimensionsInfo.map(([suffix]) => prefix + suffix);
|
||||||
|
this.updateCallback([], deletions);
|
||||||
|
}
|
||||||
|
|
||||||
|
getUpdateHandler(win,windowId) {
|
||||||
|
let scheduled = false;
|
||||||
|
return () => {
|
||||||
|
if(!scheduled) {
|
||||||
|
scheduled = true;
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
this.updateCallback(this.buildTiddlers(win,windowId), []);
|
||||||
|
scheduled = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
trackWindow(win,windowId) {
|
||||||
|
const handler = this.getUpdateHandler(win, windowId);
|
||||||
|
handler(); // initial update
|
||||||
|
win.addEventListener("resize",handler,{passive:true});
|
||||||
|
this.resizeHandlers.set(windowId,{win, handler});
|
||||||
|
}
|
||||||
|
|
||||||
|
untrackWindow(windowId) {
|
||||||
|
const entry = this.resizeHandlers.get(windowId);
|
||||||
|
if(entry) {
|
||||||
|
entry.win.removeEventListener("resize", entry.handler);
|
||||||
|
this.resizeHandlers.delete(windowId);
|
||||||
|
}
|
||||||
|
this.clearTiddlers(windowId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const tracker = new WindowDimensionsTracker(updateInfoTiddlersCallback);
|
||||||
|
|
||||||
|
// Track main window
|
||||||
|
tracker.trackWindow(window,"system/main");
|
||||||
|
|
||||||
|
// Hook into event bus for user windows
|
||||||
|
if($tw.eventBus) {
|
||||||
|
$tw.eventBus.on("window:opened", ({window: win, windowID}) => {
|
||||||
|
tracker.trackWindow(win, "user/" + windowID);
|
||||||
|
});
|
||||||
|
$tw.eventBus.on("window:closed", ({windowID}) => {
|
||||||
|
tracker.untrackWindow("user/" + windowID);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
};
|
||||||
@@ -7,23 +7,34 @@ The audio parser parses an audio tiddler into an embeddable HTML element
|
|||||||
|
|
||||||
\*/
|
\*/
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var AudioParser = function(type,text,options) {
|
var AudioParser = function(type,text,options) {
|
||||||
var element = {
|
var element = {
|
||||||
type: "element",
|
type: "element",
|
||||||
tag: "audio",
|
tag: "$audio", // Using $audio to enable widget interception
|
||||||
attributes: {
|
attributes: {
|
||||||
controls: {type: "string", value: "controls"},
|
controls: {type: "string", value: "controls"},
|
||||||
style: {type: "string", value: "width: 100%; object-fit: contain"}
|
style: {type: "string", value: "width: 100%; object-fit: contain"}
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
src;
|
|
||||||
|
// Pass through source information
|
||||||
if(options._canonical_uri) {
|
if(options._canonical_uri) {
|
||||||
element.attributes.src = {type: "string", value: options._canonical_uri};
|
element.attributes.src = {type: "string", value: options._canonical_uri};
|
||||||
|
element.attributes.type = {type: "string", value: type};
|
||||||
} else if(text) {
|
} else if(text) {
|
||||||
element.attributes.src = {type: "string", value: "data:" + type + ";base64," + text};
|
element.attributes.src = {type: "string", value: "data:" + type + ";base64," + text};
|
||||||
|
element.attributes.type = {type: "string", value: type};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pass through tiddler title if available
|
||||||
|
if(options.title) {
|
||||||
|
element.attributes.tiddler = {type: "string", value: options.title};
|
||||||
|
}
|
||||||
|
|
||||||
this.tree = [element];
|
this.tree = [element];
|
||||||
this.source = text;
|
this.source = text;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
@@ -33,3 +44,4 @@ exports["audio/ogg"] = AudioParser;
|
|||||||
exports["audio/mpeg"] = AudioParser;
|
exports["audio/mpeg"] = AudioParser;
|
||||||
exports["audio/mp3"] = AudioParser;
|
exports["audio/mp3"] = AudioParser;
|
||||||
exports["audio/mp4"] = AudioParser;
|
exports["audio/mp4"] = AudioParser;
|
||||||
|
|
||||||
@@ -82,6 +82,7 @@ exports.parseTokenString = function(source,pos,token) {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Look for a token matching a regex. Returns null if not found, otherwise returns {type: "regexp", match:, start:, end:,}
|
Look for a token matching a regex. Returns null if not found, otherwise returns {type: "regexp", match:, start:, end:,}
|
||||||
|
Use the "Y" (sticky) flag to avoid searching the entire rest of the string
|
||||||
*/
|
*/
|
||||||
exports.parseTokenRegExp = function(source,pos,reToken) {
|
exports.parseTokenRegExp = function(source,pos,reToken) {
|
||||||
var node = {
|
var node = {
|
||||||
@@ -172,7 +173,7 @@ exports.parseMacroParameter = function(source,pos) {
|
|||||||
start: pos
|
start: pos
|
||||||
};
|
};
|
||||||
// Define our regexp
|
// Define our regexp
|
||||||
var reMacroParameter = /(?:([A-Za-z0-9\-_]+)\s*:)?(?:\s*(?:"""([\s\S]*?)"""|"([^"]*)"|'([^']*)'|\[\[([^\]]*)\]\]|((?:(?:>(?!>))|[^\s>"'])+)))/g;
|
const reMacroParameter = /(?:([A-Za-z0-9\-_]+)\s*:)?(?:\s*(?:"""([\s\S]*?)"""|"([^"]*)"|'([^']*)'|\[\[([^\]]*)\]\]|((?:(?:>(?!>))|[^\s>"'])+)))/y;
|
||||||
// Skip whitespace
|
// Skip whitespace
|
||||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||||
// Look for the parameter
|
// Look for the parameter
|
||||||
@@ -240,7 +241,7 @@ exports.parseMacroInvocation = function(source,pos) {
|
|||||||
params: []
|
params: []
|
||||||
};
|
};
|
||||||
// Define our regexps
|
// Define our regexps
|
||||||
var reMacroName = /([^\s>"'=]+)/g;
|
const reMacroName = /([^\s>"'=]+)/y;
|
||||||
// Skip whitespace
|
// Skip whitespace
|
||||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||||
// Look for a double less than sign
|
// Look for a double less than sign
|
||||||
@@ -277,7 +278,7 @@ exports.parseFilterVariable = function(source) {
|
|||||||
params: [],
|
params: [],
|
||||||
},
|
},
|
||||||
pos = 0,
|
pos = 0,
|
||||||
reName = /([^\s"']+)/g;
|
reName = /([^\s"']+)/y;
|
||||||
// If there is no whitespace or it is an empty string then there are no macro parameters
|
// If there is no whitespace or it is an empty string then there are no macro parameters
|
||||||
if(/^\S*$/.test(source)) {
|
if(/^\S*$/.test(source)) {
|
||||||
node.name = source;
|
node.name = source;
|
||||||
@@ -302,11 +303,11 @@ exports.parseAttribute = function(source,pos) {
|
|||||||
start: pos
|
start: pos
|
||||||
};
|
};
|
||||||
// Define our regexps
|
// Define our regexps
|
||||||
var reAttributeName = /([^\/\s>"'`=]+)/g,
|
const reAttributeName = /([^\/\s>"'`=]+)/y,
|
||||||
reUnquotedAttribute = /([^\/\s<>"'`=]+)/g,
|
reUnquotedAttribute = /([^\/\s<>"'`=]+)/y,
|
||||||
reFilteredValue = /\{\{\{([\S\s]+?)\}\}\}/g,
|
reFilteredValue = /\{\{\{([\S\s]+?)\}\}\}/y,
|
||||||
reIndirectValue = /\{\{([^\}]+)\}\}/g,
|
reIndirectValue = /\{\{([^\}]+)\}\}/y,
|
||||||
reSubstitutedValue = /(?:```([\s\S]*?)```|`([^`]|[\S\s]*?)`)/g;
|
reSubstitutedValue = /(?:```([\s\S]*?)```|`([^`]|[\S\s]*?)`)/y;
|
||||||
// Skip whitespace
|
// Skip whitespace
|
||||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||||
// Get the attribute name
|
// Get the attribute name
|
||||||
|
|||||||
@@ -43,9 +43,18 @@ exports.findNextMatch = function(startPos) {
|
|||||||
return undefined;
|
return undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
exports.parse = function() {
|
exports.parse = function() {
|
||||||
// Move past the match
|
// Move past the match
|
||||||
this.parser.pos = this.endMatchRegExp.lastIndex;
|
this.parser.pos = this.endMatchRegExp.lastIndex;
|
||||||
// Don't return any elements
|
// Return a node representing the comment that is not rendered
|
||||||
return [];
|
var commentStart = this.match.index;
|
||||||
|
var commentEnd = this.endMatch.index + this.endMatch[0].length;
|
||||||
|
return [{
|
||||||
|
type: "void",
|
||||||
|
children: [],
|
||||||
|
text: this.parser.source.slice(commentStart, commentEnd),
|
||||||
|
start: commentStart,
|
||||||
|
end: commentEnd
|
||||||
|
}];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -40,6 +40,13 @@ exports.findNextMatch = function(startPos) {
|
|||||||
exports.parse = function() {
|
exports.parse = function() {
|
||||||
// Move past the match
|
// Move past the match
|
||||||
this.parser.pos = this.endMatchRegExp.lastIndex;
|
this.parser.pos = this.endMatchRegExp.lastIndex;
|
||||||
// Don't return any elements
|
// Return a node representing the inline comment
|
||||||
return [];
|
var commentStart = this.match.index;
|
||||||
|
var commentEnd = this.endMatch.index + this.endMatch[0].length;
|
||||||
|
return [{
|
||||||
|
type: "void",
|
||||||
|
text: this.parser.source.slice(commentStart, commentEnd),
|
||||||
|
start: commentStart,
|
||||||
|
end: commentEnd
|
||||||
|
}];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ exports.parse = function() {
|
|||||||
// Return the classed span
|
// Return the classed span
|
||||||
return [{
|
return [{
|
||||||
type: "element",
|
type: "element",
|
||||||
tag: "strike",
|
tag: "s",
|
||||||
children: tree
|
children: tree
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ exports.parse = function() {
|
|||||||
this.parser.pos = this.matchRegExp.lastIndex;
|
this.parser.pos = this.matchRegExp.lastIndex;
|
||||||
// Create the link unless it is suppressed
|
// Create the link unless it is suppressed
|
||||||
if(this.match[0].substr(0,1) === "~") {
|
if(this.match[0].substr(0,1) === "~") {
|
||||||
return [{type: "text", text: this.match[0].substr(1)}];
|
return [{type: "text", text: this.match[0].substr(1), start: start, end: this.parser.pos}];
|
||||||
} else {
|
} else {
|
||||||
return [{
|
return [{
|
||||||
type: "element",
|
type: "element",
|
||||||
|
|||||||
@@ -6,15 +6,15 @@ module-type: wikirule
|
|||||||
Wiki pragma rule for function, procedure and widget definitions
|
Wiki pragma rule for function, procedure and widget definitions
|
||||||
|
|
||||||
```
|
```
|
||||||
\function name(param:defaultvalue,param2:defaultvalue)
|
\function name(param:"defaultvalue", param2:"defaultvalue")
|
||||||
definition text
|
definition text
|
||||||
\end
|
\end
|
||||||
|
|
||||||
\procedure name(param:defaultvalue,param2:defaultvalue)
|
\procedure name(param:"defaultvalue", param2:"defaultvalue")
|
||||||
definition text
|
definition text
|
||||||
\end
|
\end
|
||||||
|
|
||||||
\widget $mywidget(param:defaultvalue,param2:defaultvalue)
|
\widget $mywidget(param:"defaultvalue", param2:"defaultvalue")
|
||||||
definition text
|
definition text
|
||||||
\end
|
\end
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ exports.parse = function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while(match && !match[1]);
|
} while(match && !match[1]);
|
||||||
// Return the nodes
|
// Mark first and last node, and return the nodes
|
||||||
|
if(tree[0]) tree[0].isRuleStart = true;
|
||||||
|
if(tree[tree.length-1]) tree[tree.length-1].isRuleEnd = true;
|
||||||
return tree;
|
return tree;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ exports.parse = function() {
|
|||||||
// Advance the parser position to past the tag
|
// Advance the parser position to past the tag
|
||||||
this.parser.pos = tag.end;
|
this.parser.pos = tag.end;
|
||||||
// Check for an immediately following double linebreak
|
// Check for an immediately following double linebreak
|
||||||
var hasLineBreak = !tag.isSelfClosing && !!$tw.utils.parseTokenRegExp(this.parser.source,this.parser.pos,/([^\S\n\r]*\r?\n(?:[^\S\n\r]*\r?\n|$))/g);
|
var hasLineBreak = !tag.isSelfClosing && !!$tw.utils.parseTokenRegExp(this.parser.source,this.parser.pos,/([^\S\n\r]*\r?\n(?:[^\S\n\r]*\r?\n|$))/y);
|
||||||
// Set whether we're in block mode
|
// Set whether we're in block mode
|
||||||
tag.isBlock = this.is.block || hasLineBreak;
|
tag.isBlock = this.is.block || hasLineBreak;
|
||||||
// Parse the body if we need to
|
// Parse the body if we need to
|
||||||
@@ -63,7 +63,7 @@ exports.parse = function() {
|
|||||||
}
|
}
|
||||||
tag.end = this.parser.pos;
|
tag.end = this.parser.pos;
|
||||||
tag.closeTagEnd = tag.end;
|
tag.closeTagEnd = tag.end;
|
||||||
if (tag.closeTagEnd === tag.openTagEnd || this.parser.source[tag.closeTagEnd - 1] !== '>') {
|
if(tag.closeTagEnd === tag.openTagEnd || this.parser.source[tag.closeTagEnd - 1] !== ">") {
|
||||||
tag.closeTagStart = tag.end;
|
tag.closeTagStart = tag.end;
|
||||||
} else {
|
} else {
|
||||||
tag.closeTagStart = tag.closeTagEnd - 2;
|
tag.closeTagStart = tag.closeTagEnd - 2;
|
||||||
@@ -71,11 +71,11 @@ exports.parse = function() {
|
|||||||
if(!Number.isSafeInteger(closeTagMinPos)) closeTagMinPos = tag.openTagEnd;
|
if(!Number.isSafeInteger(closeTagMinPos)) closeTagMinPos = tag.openTagEnd;
|
||||||
while(tag.closeTagStart >= closeTagMinPos) {
|
while(tag.closeTagStart >= closeTagMinPos) {
|
||||||
var char = this.parser.source[tag.closeTagStart];
|
var char = this.parser.source[tag.closeTagStart];
|
||||||
if (char === '>') {
|
if(char === ">") {
|
||||||
tag.closeTagStart = -1;
|
tag.closeTagStart = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (char === '<') break;
|
if(char === "<") break;
|
||||||
tag.closeTagStart -= 1;
|
tag.closeTagStart -= 1;
|
||||||
}
|
}
|
||||||
if(tag.closeTagStart < closeTagMinPos) {
|
if(tag.closeTagStart < closeTagMinPos) {
|
||||||
@@ -100,7 +100,7 @@ exports.parseTag = function(source,pos,options) {
|
|||||||
orderedAttributes: []
|
orderedAttributes: []
|
||||||
};
|
};
|
||||||
// Define our regexps
|
// Define our regexps
|
||||||
var reTagName = /([a-zA-Z0-9\-\$\.]+)/g;
|
const reTagName = /([a-zA-Z0-9\-\$\.]+)/y;
|
||||||
// Skip whitespace
|
// Skip whitespace
|
||||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||||
// Look for a less than sign
|
// Look for a less than sign
|
||||||
@@ -148,7 +148,7 @@ exports.parseTag = function(source,pos,options) {
|
|||||||
pos = token.end;
|
pos = token.end;
|
||||||
// Check for a required line break
|
// Check for a required line break
|
||||||
if(options.requireLineBreak) {
|
if(options.requireLineBreak) {
|
||||||
token = $tw.utils.parseTokenRegExp(source,pos,/([^\S\n\r]*\r?\n(?:[^\S\n\r]*\r?\n|$))/g);
|
token = $tw.utils.parseTokenRegExp(source,pos,/([^\S\n\r]*\r?\n(?:[^\S\n\r]*\r?\n|$))/y);
|
||||||
if(!token) {
|
if(!token) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ exports.parseImage = function(source,pos) {
|
|||||||
// Skip whitespace
|
// Skip whitespace
|
||||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||||
// Get the source up to the terminating `]]`
|
// Get the source up to the terminating `]]`
|
||||||
token = $tw.utils.parseTokenRegExp(source,pos,/(?:([^|\]]*?)\|)?([^\]]+?)\]\]/g);
|
token = $tw.utils.parseTokenRegExp(source,pos,/(?:([^|\]]*?)\|)?([^\]]+?)\]\]/y);
|
||||||
if(!token) {
|
if(!token) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ var listTypes = {
|
|||||||
":": {listTag: "dl", itemTag: "dd"},
|
":": {listTag: "dl", itemTag: "dd"},
|
||||||
">": {listTag: "blockquote", itemTag: "div"}
|
">": {listTag: "blockquote", itemTag: "div"}
|
||||||
};
|
};
|
||||||
|
exports.listTypes = listTypes;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Parse the most recent match
|
Parse the most recent match
|
||||||
|
|||||||
@@ -42,3 +42,5 @@ exports.parse = function() {
|
|||||||
this.parser.pos = call.end;
|
this.parser.pos = call.end;
|
||||||
return [call];
|
return [call];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -52,9 +52,10 @@ exports.parse = function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Is the remainder of the \define line blank after the parameter close paren?
|
// Is the remainder of the \define line blank after the parameter close paren?
|
||||||
var reEnd;
|
var reEnd,isBlock = true;
|
||||||
if(this.match[3]) {
|
if(this.match[3]) {
|
||||||
// If so, it is a multiline definition and the end of the body is marked with \end
|
// If so, it is a multiline definition and the end of the body is marked with \end
|
||||||
|
isBlock = false;
|
||||||
reEnd = new RegExp("((?:^|\\r?\\n)[^\\S\\n\\r]*\\\\end[^\\S\\n\\r]*(?:" + $tw.utils.escapeRegExp(this.match[1]) + ")?\\s*?(?:$|\\r?\\n))","mg");
|
reEnd = new RegExp("((?:^|\\r?\\n)[^\\S\\n\\r]*\\\\end[^\\S\\n\\r]*(?:" + $tw.utils.escapeRegExp(this.match[1]) + ")?\\s*?(?:$|\\r?\\n))","mg");
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, the end of the definition is marked by the end of the line
|
// Otherwise, the end of the definition is marked by the end of the line
|
||||||
@@ -79,7 +80,8 @@ exports.parse = function() {
|
|||||||
attributes: {},
|
attributes: {},
|
||||||
children: [],
|
children: [],
|
||||||
params: params,
|
params: params,
|
||||||
isMacroDefinition: true
|
isMacroDefinition: true,
|
||||||
|
isBlock: isBlock && !!endMatch
|
||||||
}];
|
}];
|
||||||
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"name",this.match[1]);
|
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"name",this.match[1]);
|
||||||
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"value",text);
|
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],"value",text);
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ Parse the most recent match
|
|||||||
*/
|
*/
|
||||||
exports.parse = function() {
|
exports.parse = function() {
|
||||||
// Move past the pragma invocation
|
// Move past the pragma invocation
|
||||||
|
var start = this.parser.pos;
|
||||||
this.parser.pos = this.matchRegExp.lastIndex;
|
this.parser.pos = this.matchRegExp.lastIndex;
|
||||||
// Parse whitespace delimited tokens terminated by a line break
|
// Parse whitespace delimited tokens terminated by a line break
|
||||||
var reMatch = /[^\S\n]*(\S+)|(\r?\n)/mg,
|
var reMatch = /[^\S\n]*(\S+)|(\r?\n)/mg,
|
||||||
@@ -58,6 +59,11 @@ exports.parse = function() {
|
|||||||
this.parser.parseAsInline = true;
|
this.parser.parseAsInline = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// No parse tree nodes to return
|
return [{
|
||||||
return [];
|
type: "void",
|
||||||
|
children: [],
|
||||||
|
parseAsInline: this.parser.parseAsInline,
|
||||||
|
start: start,
|
||||||
|
end: this.parser.pos
|
||||||
|
}];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -113,3 +113,5 @@ exports.parseLink = function(source,pos) {
|
|||||||
node.end = closePos + 2;
|
node.end = closePos + 2;
|
||||||
return node;
|
return node;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,13 @@ exports.parse = function() {
|
|||||||
if(tokens.length > 0) {
|
if(tokens.length > 0) {
|
||||||
this.parser.amendRules(tokens[0],tokens.slice(1));
|
this.parser.amendRules(tokens[0],tokens.slice(1));
|
||||||
}
|
}
|
||||||
// No parse tree nodes to return
|
// No widget to render, return void node.
|
||||||
return [];
|
return [{
|
||||||
|
type: "void",
|
||||||
|
attributes: {
|
||||||
|
action: {type: "string", value: tokens[0]},
|
||||||
|
rules: {type: "string", value: tokens.slice(1).join(" ")}
|
||||||
|
},
|
||||||
|
children: []
|
||||||
|
}];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -64,5 +64,8 @@ exports.parse = function() {
|
|||||||
$tw.utils.addAttributeToParseTreeNode(tree[t],"style",styles.join(""));
|
$tw.utils.addAttributeToParseTreeNode(tree[t],"style",styles.join(""));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tree;
|
return [{
|
||||||
|
type: "void",
|
||||||
|
children: tree
|
||||||
|
}]
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ exports.types = {inline: true};
|
|||||||
|
|
||||||
exports.init = function(parser) {
|
exports.init = function(parser) {
|
||||||
this.parser = parser;
|
this.parser = parser;
|
||||||
// Regexp to match
|
// Regexp to match /@@(styles)?\s*(\.class\s+)?/
|
||||||
this.matchRegExp = /@@((?:[^\.\r\n\s:]+:[^\r\n;]+;)+)?(\.(?:[^\r\n\s]+)\s+)?/mg;
|
this.matchRegExp = /@@((?:[^\.\r\n\s:]+:[^\r\n;]+;)+)?(\.(?:[^\r\n\s]+)\s+)?/mg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,27 @@ exports.init = function(parser) {
|
|||||||
this.matchRegExp = /\{\{([^\{\}\|]*)(?:\|\|([^\|\{\}]+))?(?:\|([^\{\}]+))?\}\}(?:\r?\n|$)/mg;
|
this.matchRegExp = /\{\{([^\{\}\|]*)(?:\|\|([^\|\{\}]+))?(?:\|([^\{\}]+))?\}\}(?:\r?\n|$)/mg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Reject the match if we don't have a template or text reference
|
||||||
|
*/
|
||||||
|
exports.findNextMatch = function(startPos) {
|
||||||
|
this.matchRegExp.lastIndex = startPos;
|
||||||
|
this.match = this.matchRegExp.exec(this.parser.source);
|
||||||
|
if(this.match) {
|
||||||
|
var template = $tw.utils.trim(this.match[2]),
|
||||||
|
textRef = $tw.utils.trim(this.match[1]);
|
||||||
|
// Bail if we don't have a template or text reference
|
||||||
|
if(!template && !textRef) {
|
||||||
|
return undefined;
|
||||||
|
} else {
|
||||||
|
return this.match.index;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return this.match ? this.match.index : undefined;
|
||||||
|
};
|
||||||
|
|
||||||
exports.parse = function() {
|
exports.parse = function() {
|
||||||
// Move past the match
|
// Move past the match
|
||||||
this.parser.pos = this.matchRegExp.lastIndex;
|
this.parser.pos = this.matchRegExp.lastIndex;
|
||||||
|
|||||||
@@ -23,6 +23,27 @@ exports.init = function(parser) {
|
|||||||
this.matchRegExp = /\{\{([^\{\}\|]*)(?:\|\|([^\|\{\}]+))?(?:\|([^\{\}]+))?\}\}/mg;
|
this.matchRegExp = /\{\{([^\{\}\|]*)(?:\|\|([^\|\{\}]+))?(?:\|([^\{\}]+))?\}\}/mg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Reject the match if we don't have a template or text reference
|
||||||
|
*/
|
||||||
|
exports.findNextMatch = function(startPos) {
|
||||||
|
this.matchRegExp.lastIndex = startPos;
|
||||||
|
this.match = this.matchRegExp.exec(this.parser.source);
|
||||||
|
if(this.match) {
|
||||||
|
var template = $tw.utils.trim(this.match[2]),
|
||||||
|
textRef = $tw.utils.trim(this.match[1]);
|
||||||
|
// Bail if we don't have a template or text reference
|
||||||
|
if(!template && !textRef) {
|
||||||
|
return undefined;
|
||||||
|
} else {
|
||||||
|
return this.match.index;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return this.match ? this.match.index : undefined;
|
||||||
|
};
|
||||||
|
|
||||||
exports.parse = function() {
|
exports.parse = function() {
|
||||||
// Move past the match
|
// Move past the match
|
||||||
this.parser.pos = this.matchRegExp.lastIndex;
|
this.parser.pos = this.matchRegExp.lastIndex;
|
||||||
|
|||||||
@@ -60,22 +60,37 @@ exports.parse = function() {
|
|||||||
var parser = this.parser.wiki.parseText(parseType,text,{defaultType: "text/plain"});
|
var parser = this.parser.wiki.parseText(parseType,text,{defaultType: "text/plain"});
|
||||||
// If there's no render type, just return the parse tree
|
// If there's no render type, just return the parse tree
|
||||||
if(!renderType) {
|
if(!renderType) {
|
||||||
return parser.tree;
|
return [{
|
||||||
|
type: "void",
|
||||||
|
children: $tw.utils.isArray(parser.tree) ? parser.tree : [parser.tree],
|
||||||
|
parseType: parseType,
|
||||||
|
renderType: renderType,
|
||||||
|
text: text,
|
||||||
|
start: start,
|
||||||
|
end: this.parser.pos
|
||||||
|
}];
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, render to the rendertype and return in a <PRE> tag
|
// Otherwise, render to the rendertype and return in a <PRE> tag
|
||||||
var widgetNode = this.parser.wiki.makeWidget(parser),
|
var widgetNode = this.parser.wiki.makeWidget(parser),
|
||||||
container = $tw.fakeDocument.createElement("div");
|
container = $tw.fakeDocument.createElement("div");
|
||||||
widgetNode.render(container,null);
|
widgetNode.render(container,null);
|
||||||
text = renderType === "text/html" ? container.innerHTML : container.textContent;
|
var renderResult = renderType === "text/html" ? container.innerHTML : container.textContent;
|
||||||
|
// Use void node to carry important info for typedblock
|
||||||
return [{
|
return [{
|
||||||
|
type: "void",
|
||||||
|
children: [{
|
||||||
type: "element",
|
type: "element",
|
||||||
tag: "pre",
|
tag: "pre",
|
||||||
children: [{
|
children: [{
|
||||||
type: "text",
|
type: "text",
|
||||||
|
text: renderResult,
|
||||||
|
}]
|
||||||
|
}],
|
||||||
|
parseType: parseType,
|
||||||
|
renderType: renderType,
|
||||||
text: text,
|
text: text,
|
||||||
start: start,
|
start: start,
|
||||||
end: this.parser.pos
|
end: this.parser.pos
|
||||||
}]
|
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -256,7 +256,7 @@ WikiParser.prototype.parseBlock = function(terminatorRegExpString) {
|
|||||||
var start = this.pos;
|
var start = this.pos;
|
||||||
var children = this.parseInlineRun(terminatorRegExp);
|
var children = this.parseInlineRun(terminatorRegExp);
|
||||||
var end = this.pos;
|
var end = this.pos;
|
||||||
return [{type: "element", tag: "p", children: children, start: start, end: end }];
|
return [{type: "element", tag: "p", children: children, start: start, end: end, rule: "parseblock" }];
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -35,7 +35,9 @@ DownloadSaver.prototype.save = function(text,method,callback,options) {
|
|||||||
}
|
}
|
||||||
// Set up the link
|
// Set up the link
|
||||||
var link = document.createElement("a");
|
var link = document.createElement("a");
|
||||||
if(Blob !== undefined) {
|
// We prefer Blobs if they're available, unless we're dealing with a tiddler type declaring itself full of base64 encoded content.
|
||||||
|
// Then we use data urls, because browsers will know to decode the stream and download the actual binary file as intended.
|
||||||
|
if(Blob !== undefined && !type.includes(";base64")) {
|
||||||
var blob = new Blob([text], {type: type});
|
var blob = new Blob([text], {type: type});
|
||||||
link.setAttribute("href", URL.createObjectURL(blob));
|
link.setAttribute("href", URL.createObjectURL(blob));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/savers/postmessage.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: saver
|
||||||
|
|
||||||
|
Handles saving changes via window.postMessage() to the window.parent
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Select the appropriate saver module and set it up
|
||||||
|
*/
|
||||||
|
var PostMessageSaver = function(wiki) {
|
||||||
|
this.publisher = new $tw.utils.BrowserMessagingPublisher({type: "SAVE"});
|
||||||
|
};
|
||||||
|
|
||||||
|
PostMessageSaver.prototype.save = function(text,method,callback,options) {
|
||||||
|
// Fail if the publisher hasn't been fully initialised
|
||||||
|
if(!this.publisher.canSend()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Send the save request
|
||||||
|
this.publisher.send({
|
||||||
|
verb: "SAVE",
|
||||||
|
body: text
|
||||||
|
},function(err) {
|
||||||
|
if(err) {
|
||||||
|
callback("PostMessageSaver Error: " + err);
|
||||||
|
} else {
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Indicate that we handled the save
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Information about this saver
|
||||||
|
*/
|
||||||
|
PostMessageSaver.prototype.info = {
|
||||||
|
name: "postmessage",
|
||||||
|
capabilities: ["save", "autosave"],
|
||||||
|
priority: 100
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Static method that returns true if this saver is capable of working
|
||||||
|
*/
|
||||||
|
exports.canSave = function(wiki) {
|
||||||
|
// Provisionally say that we can save
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Create an instance of this saver
|
||||||
|
*/
|
||||||
|
exports.create = function(wiki) {
|
||||||
|
return new PostMessageSaver(wiki);
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/startup/eventbus.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: startup
|
||||||
|
|
||||||
|
Event bus for cross module communication
|
||||||
|
\*/
|
||||||
|
|
||||||
|
exports.name = "eventbus";
|
||||||
|
exports.platforms = ["browser"];
|
||||||
|
exports.before = ["windows"];
|
||||||
|
exports.synchronous = true;
|
||||||
|
|
||||||
|
$tw.eventBus = {
|
||||||
|
listenersMap: new Map(),
|
||||||
|
|
||||||
|
on(event,handler) {
|
||||||
|
if(!this.listenersMap.has(event)) {
|
||||||
|
this.listenersMap.set(event,new Set());
|
||||||
|
}
|
||||||
|
const listeners = this.listenersMap.get(event);
|
||||||
|
listeners.add(handler);
|
||||||
|
},
|
||||||
|
|
||||||
|
off(event,handler) {
|
||||||
|
const listeners = this.listenersMap.get(event);
|
||||||
|
if(listeners) {
|
||||||
|
listeners.delete(handler);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
once(event,handler) {
|
||||||
|
const wrapper = (...args) => {
|
||||||
|
handler(...args);
|
||||||
|
this.off(event, wrapper);
|
||||||
|
};
|
||||||
|
this.on(event, wrapper);
|
||||||
|
},
|
||||||
|
|
||||||
|
emit(event,data) {
|
||||||
|
const listeners = this.listenersMap.get(event);
|
||||||
|
if(listeners) {
|
||||||
|
listeners.forEach(fn => fn(data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -19,6 +19,16 @@ exports.synchronous = true;
|
|||||||
var FAVICON_TITLE = "$:/favicon.ico";
|
var FAVICON_TITLE = "$:/favicon.ico";
|
||||||
|
|
||||||
exports.startup = function() {
|
exports.startup = function() {
|
||||||
|
var setFavicon = function() {
|
||||||
|
var tiddler = $tw.wiki.getTiddler(FAVICON_TITLE);
|
||||||
|
if(tiddler) {
|
||||||
|
var faviconLink = document.getElementById("faviconLink"),
|
||||||
|
dataURI = $tw.utils.makeDataUri(tiddler.fields.text,tiddler.fields.type,tiddler.fields._canonical_uri);
|
||||||
|
faviconLink.setAttribute("href",dataURI);
|
||||||
|
$tw.faviconPublisher.send({verb: "FAVICON",body: dataURI});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$tw.faviconPublisher = new $tw.utils.BrowserMessagingPublisher({type: "FAVICON", onsubscribe: setFavicon});
|
||||||
// Set up the favicon
|
// Set up the favicon
|
||||||
setFavicon();
|
setFavicon();
|
||||||
// Reset the favicon when the tiddler changes
|
// Reset the favicon when the tiddler changes
|
||||||
@@ -28,11 +38,3 @@ exports.startup = function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function setFavicon() {
|
|
||||||
var tiddler = $tw.wiki.getTiddler(FAVICON_TITLE);
|
|
||||||
if(tiddler) {
|
|
||||||
var faviconLink = document.getElementById("faviconLink");
|
|
||||||
faviconLink.setAttribute("href",$tw.utils.makeDataUri(tiddler.fields.text,tiddler.fields.type,tiddler.fields._canonical_uri));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -19,11 +19,17 @@ var TITLE_INFO_PLUGIN = "$:/temp/info-plugin";
|
|||||||
|
|
||||||
exports.startup = function() {
|
exports.startup = function() {
|
||||||
// Function to bake the info plugin with new tiddlers
|
// Function to bake the info plugin with new tiddlers
|
||||||
var updateInfoPlugin = function(tiddlerFieldsArray) {
|
// additions: array of tiddler field objects
|
||||||
|
// removals: array of titles to remove
|
||||||
|
var updateInfoPlugin = function(additions = [], removals = []) {
|
||||||
// Get the existing tiddlers
|
// Get the existing tiddlers
|
||||||
var json = $tw.wiki.getTiddlerData(TITLE_INFO_PLUGIN,{tiddlers: {}});
|
var json = $tw.wiki.getTiddlerData(TITLE_INFO_PLUGIN,{tiddlers: {}});
|
||||||
// Add the new ones
|
$tw.utils.each(removals,function(title) {
|
||||||
$tw.utils.each(tiddlerFieldsArray,function(fields) {
|
if(json.tiddlers[title]) {
|
||||||
|
delete json.tiddlers[title];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$tw.utils.each(additions,function(fields) {
|
||||||
if(fields && fields.title) {
|
if(fields && fields.title) {
|
||||||
json.tiddlers[fields.title] = fields;
|
json.tiddlers[fields.title] = fields;
|
||||||
}
|
}
|
||||||
@@ -47,7 +53,7 @@ exports.startup = function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
updateInfoPlugin(tiddlerFieldsArray);
|
updateInfoPlugin(tiddlerFieldsArray);
|
||||||
var changes = $tw.wiki.readPluginInfo([TITLE_INFO_PLUGIN]);
|
$tw.wiki.readPluginInfo([TITLE_INFO_PLUGIN]);
|
||||||
$tw.wiki.registerPluginTiddlers("info",[TITLE_INFO_PLUGIN]);
|
$tw.wiki.registerPluginTiddlers("info",[TITLE_INFO_PLUGIN]);
|
||||||
$tw.wiki.unpackPluginTiddlers();
|
$tw.wiki.unpackPluginTiddlers();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -33,10 +33,15 @@ exports.startup = function() {
|
|||||||
});
|
});
|
||||||
$tw.titleContainer = $tw.fakeDocument.createElement("div");
|
$tw.titleContainer = $tw.fakeDocument.createElement("div");
|
||||||
$tw.titleWidgetNode.render($tw.titleContainer,null);
|
$tw.titleWidgetNode.render($tw.titleContainer,null);
|
||||||
|
var publishTitle = function() {
|
||||||
|
$tw.titlePublisher.send({verb: "PAGETITLE",body: document.title});
|
||||||
document.title = $tw.titleContainer.textContent;
|
document.title = $tw.titleContainer.textContent;
|
||||||
|
};
|
||||||
|
$tw.titlePublisher = new $tw.utils.BrowserMessagingPublisher({type: "PAGETITLE", onsubscribe: publishTitle});
|
||||||
|
publishTitle();
|
||||||
$tw.wiki.addEventListener("change",function(changes) {
|
$tw.wiki.addEventListener("change",function(changes) {
|
||||||
if($tw.titleWidgetNode.refresh(changes,$tw.titleContainer,null)) {
|
if($tw.titleWidgetNode.refresh(changes,$tw.titleContainer,null)) {
|
||||||
document.title = $tw.titleContainer.textContent;
|
publishTitle();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Set up the styles
|
// Set up the styles
|
||||||
|
|||||||
@@ -56,9 +56,11 @@ exports.startup = function() {
|
|||||||
srcDocument.write("<!DOCTYPE html><head></head><body class='tc-body tc-single-tiddler-window'></body></html>");
|
srcDocument.write("<!DOCTYPE html><head></head><body class='tc-body tc-single-tiddler-window'></body></html>");
|
||||||
srcDocument.close();
|
srcDocument.close();
|
||||||
srcDocument.title = windowTitle;
|
srcDocument.title = windowTitle;
|
||||||
|
$tw.eventBus.emit("window:opened",{windowID, window: srcWindow});
|
||||||
srcWindow.addEventListener("beforeunload",function(event) {
|
srcWindow.addEventListener("beforeunload",function(event) {
|
||||||
delete $tw.windows[windowID];
|
delete $tw.windows[windowID];
|
||||||
$tw.wiki.removeEventListener("change",refreshHandler);
|
$tw.wiki.removeEventListener("change",refreshHandler);
|
||||||
|
$tw.eventBus.emit("window:closed",{windowID});
|
||||||
},false);
|
},false);
|
||||||
// Set up the styles
|
// Set up the styles
|
||||||
var styleWidgetNode = $tw.wiki.makeTranscludeWidget("$:/core/ui/PageStylesheet",{
|
var styleWidgetNode = $tw.wiki.makeTranscludeWidget("$:/core/ui/PageStylesheet",{
|
||||||
|
|||||||
@@ -47,16 +47,16 @@ ClassicStoryView.prototype.insert = function(widget) {
|
|||||||
// Reset the margin once the transition is over
|
// Reset the margin once the transition is over
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
$tw.utils.setStyle(targetElement,[
|
$tw.utils.setStyle(targetElement,[
|
||||||
{transition: "none"},
|
|
||||||
{marginBottom: ""}
|
{marginBottom: ""}
|
||||||
]);
|
]);
|
||||||
|
$tw.utils.removeStyle(targetElement, "transition");
|
||||||
},duration);
|
},duration);
|
||||||
// Set up the initial position of the element
|
// Set up the initial position of the element
|
||||||
$tw.utils.setStyle(targetElement,[
|
$tw.utils.setStyle(targetElement,[
|
||||||
{transition: "none"},
|
|
||||||
{marginBottom: (-currHeight) + "px"},
|
{marginBottom: (-currHeight) + "px"},
|
||||||
{opacity: "0.0"}
|
{opacity: "0.0"}
|
||||||
]);
|
]);
|
||||||
|
$tw.utils.removeStyle(targetElement, "transition");
|
||||||
$tw.utils.forceLayout(targetElement);
|
$tw.utils.forceLayout(targetElement);
|
||||||
// Transition to the final position
|
// Transition to the final position
|
||||||
$tw.utils.setStyle(targetElement,[
|
$tw.utils.setStyle(targetElement,[
|
||||||
@@ -94,11 +94,9 @@ ClassicStoryView.prototype.remove = function(widget) {
|
|||||||
setTimeout(removeElement,duration);
|
setTimeout(removeElement,duration);
|
||||||
// Animate the closure
|
// Animate the closure
|
||||||
$tw.utils.setStyle(targetElement,[
|
$tw.utils.setStyle(targetElement,[
|
||||||
{transition: "none"},
|
|
||||||
{transform: "translateX(0px)"},
|
|
||||||
{marginBottom: currMarginBottom + "px"},
|
{marginBottom: currMarginBottom + "px"},
|
||||||
{opacity: "1.0"}
|
|
||||||
]);
|
]);
|
||||||
|
$tw.utils.removeStyles(targetElement, ["transition", "transform", "opacity"]);
|
||||||
$tw.utils.forceLayout(targetElement);
|
$tw.utils.forceLayout(targetElement);
|
||||||
$tw.utils.setStyle(targetElement,[
|
$tw.utils.setStyle(targetElement,[
|
||||||
{transition: $tw.utils.roundTripPropertyName("transform") + " " + duration + "ms " + easing + ", " +
|
{transition: $tw.utils.roundTripPropertyName("transform") + " " + duration + "ms " + easing + ", " +
|
||||||
|
|||||||
@@ -37,10 +37,7 @@ PopStoryView.prototype.insert = function(widget) {
|
|||||||
}
|
}
|
||||||
// Reset once the transition is over
|
// Reset once the transition is over
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
$tw.utils.setStyle(targetElement,[
|
$tw.utils.removeStyles(targetElement, ["transition", "transform"]);
|
||||||
{transition: "none"},
|
|
||||||
{transform: "none"}
|
|
||||||
]);
|
|
||||||
$tw.utils.setStyle(widget.document.body,[
|
$tw.utils.setStyle(widget.document.body,[
|
||||||
{"overflow-x": ""}
|
{"overflow-x": ""}
|
||||||
]);
|
]);
|
||||||
@@ -51,10 +48,10 @@ PopStoryView.prototype.insert = function(widget) {
|
|||||||
]);
|
]);
|
||||||
// Set up the initial position of the element
|
// Set up the initial position of the element
|
||||||
$tw.utils.setStyle(targetElement,[
|
$tw.utils.setStyle(targetElement,[
|
||||||
{transition: "none"},
|
|
||||||
{transform: "scale(2)"},
|
{transform: "scale(2)"},
|
||||||
{opacity: "0.0"}
|
{opacity: "0.0"}
|
||||||
]);
|
]);
|
||||||
|
$tw.utils.removeStyle(targetElement, "transition");
|
||||||
$tw.utils.forceLayout(targetElement);
|
$tw.utils.forceLayout(targetElement);
|
||||||
// Transition to the final position
|
// Transition to the final position
|
||||||
$tw.utils.setStyle(targetElement,[
|
$tw.utils.setStyle(targetElement,[
|
||||||
@@ -63,6 +60,9 @@ PopStoryView.prototype.insert = function(widget) {
|
|||||||
{transform: "scale(1)"},
|
{transform: "scale(1)"},
|
||||||
{opacity: "1.0"}
|
{opacity: "1.0"}
|
||||||
]);
|
]);
|
||||||
|
setTimeout(function() {
|
||||||
|
$tw.utils.removeStyles(targetElement, ["transition", "transform", "opactity"]);
|
||||||
|
}, duration)
|
||||||
};
|
};
|
||||||
|
|
||||||
PopStoryView.prototype.remove = function(widget) {
|
PopStoryView.prototype.remove = function(widget) {
|
||||||
@@ -81,11 +81,7 @@ PopStoryView.prototype.remove = function(widget) {
|
|||||||
// Remove the element at the end of the transition
|
// Remove the element at the end of the transition
|
||||||
setTimeout(removeElement,duration);
|
setTimeout(removeElement,duration);
|
||||||
// Animate the closure
|
// Animate the closure
|
||||||
$tw.utils.setStyle(targetElement,[
|
$tw.utils.removeStyles(targetElement, ["transition", "transform", "opacity"]);
|
||||||
{transition: "none"},
|
|
||||||
{transform: "scale(1)"},
|
|
||||||
{opacity: "1.0"}
|
|
||||||
]);
|
|
||||||
$tw.utils.forceLayout(targetElement);
|
$tw.utils.forceLayout(targetElement);
|
||||||
$tw.utils.setStyle(targetElement,[
|
$tw.utils.setStyle(targetElement,[
|
||||||
{transition: $tw.utils.roundTripPropertyName("transform") + " " + duration + "ms ease-in-out, " +
|
{transition: $tw.utils.roundTripPropertyName("transform") + " " + duration + "ms ease-in-out, " +
|
||||||
|
|||||||
@@ -96,6 +96,9 @@ ZoominListView.prototype.navigateTo = function(historyInfo) {
|
|||||||
{transform: "translateX(0px) translateY(0px) scale(1)"},
|
{transform: "translateX(0px) translateY(0px) scale(1)"},
|
||||||
{zIndex: "500"},
|
{zIndex: "500"},
|
||||||
]);
|
]);
|
||||||
|
setTimeout(function() {
|
||||||
|
$tw.utils.removeStyles(targetElement, ["transition", "opacity", "transform", "zIndex"]);
|
||||||
|
}, duration);
|
||||||
// Transform the previous tiddler out of the way and then hide it
|
// Transform the previous tiddler out of the way and then hide it
|
||||||
if(prevCurrentTiddler && prevCurrentTiddler !== targetElement) {
|
if(prevCurrentTiddler && prevCurrentTiddler !== targetElement) {
|
||||||
scale = zoomBounds.width / sourceBounds.width;
|
scale = zoomBounds.width / sourceBounds.width;
|
||||||
@@ -207,6 +210,9 @@ ZoominListView.prototype.remove = function(widget) {
|
|||||||
{opacity: "0"},
|
{opacity: "0"},
|
||||||
{zIndex: "0"}
|
{zIndex: "0"}
|
||||||
]);
|
]);
|
||||||
|
setTimeout(function() {
|
||||||
|
$tw.utils.removeStyles(toWidgetDomNode, ["transformOrigin", "transform", "transition", "opacity", "zIndex"]);
|
||||||
|
}, duration);
|
||||||
setTimeout(removeElement,duration);
|
setTimeout(removeElement,duration);
|
||||||
// Now the tiddler we're going back to
|
// Now the tiddler we're going back to
|
||||||
if(toWidgetDomNode) {
|
if(toWidgetDomNode) {
|
||||||
|
|||||||
@@ -1,142 +0,0 @@
|
|||||||
// From https://gist.github.com/Nijikokun/5192472
|
|
||||||
//
|
|
||||||
// UTF8 Module
|
|
||||||
//
|
|
||||||
// Cleaner and modularized utf-8 encoding and decoding library for javascript.
|
|
||||||
//
|
|
||||||
// copyright: MIT
|
|
||||||
// author: Nijiko Yonskai, @nijikokun, nijikokun@gmail.com
|
|
||||||
(function (name, definition, context, dependencies) {
|
|
||||||
if (typeof context['module'] !== 'undefined' && context['module']['exports']) { if (dependencies && context['require']) { for (var i = 0; i < dependencies.length; i++) context[dependencies[i]] = context['require'](dependencies[i]); } context['module']['exports'] = definition.apply(context); }
|
|
||||||
else if (typeof context['define'] !== 'undefined' && context['define'] === 'function' && context['define']['amd']) { define(name, (dependencies || []), definition); }
|
|
||||||
else { context[name] = definition.apply(context); }
|
|
||||||
})('utf8', function () {
|
|
||||||
return {
|
|
||||||
encode: function (string) {
|
|
||||||
if (typeof string !== 'string') return string;
|
|
||||||
else string = string.replace(/\r\n/g, "\n");
|
|
||||||
var output = "", i = 0, charCode;
|
|
||||||
|
|
||||||
for (i; i < string.length; i++) {
|
|
||||||
charCode = string.charCodeAt(i);
|
|
||||||
|
|
||||||
if (charCode < 128) {
|
|
||||||
output += String.fromCharCode(charCode);
|
|
||||||
} else if ((charCode > 127) && (charCode < 2048)) {
|
|
||||||
output += String.fromCharCode((charCode >> 6) | 192);
|
|
||||||
output += String.fromCharCode((charCode & 63) | 128);
|
|
||||||
} else if ((charCode > 55295) && (charCode < 57344) && string.length > i+1) {
|
|
||||||
// Surrogate pair
|
|
||||||
var hiSurrogate = charCode;
|
|
||||||
var loSurrogate = string.charCodeAt(i+1);
|
|
||||||
i++; // Skip the low surrogate on the next loop pass
|
|
||||||
var codePoint = (((hiSurrogate - 55296) << 10) | (loSurrogate - 56320)) + 65536;
|
|
||||||
output += String.fromCharCode((codePoint >> 18) | 240);
|
|
||||||
output += String.fromCharCode(((codePoint >> 12) & 63) | 128);
|
|
||||||
output += String.fromCharCode(((codePoint >> 6) & 63) | 128);
|
|
||||||
output += String.fromCharCode((codePoint & 63) | 128);
|
|
||||||
} else {
|
|
||||||
// Not a surrogate pair, or a dangling surrogate without its partner that we'll just encode as-is
|
|
||||||
output += String.fromCharCode((charCode >> 12) | 224);
|
|
||||||
output += String.fromCharCode(((charCode >> 6) & 63) | 128);
|
|
||||||
output += String.fromCharCode((charCode & 63) | 128);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
},
|
|
||||||
|
|
||||||
decode: function (string) {
|
|
||||||
if (typeof string !== 'string') return string;
|
|
||||||
var output = "", i = 0, charCode = 0;
|
|
||||||
|
|
||||||
while (i < string.length) {
|
|
||||||
charCode = string.charCodeAt(i);
|
|
||||||
|
|
||||||
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));
|
|
||||||
i += 2;
|
|
||||||
} else if ((charCode > 223) && (charCode < 240)) {
|
|
||||||
output += String.fromCharCode(((charCode & 15) << 12) | ((string.charCodeAt(i + 1) & 63) << 6) | (string.charCodeAt(i + 2) & 63));
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
// Base64 Module
|
|
||||||
//
|
|
||||||
// Cleaner, modularized and properly scoped base64 encoding and decoding module for strings.
|
|
||||||
//
|
|
||||||
// copyright: MIT
|
|
||||||
// author: Nijiko Yonskai, @nijikokun, nijikokun@gmail.com
|
|
||||||
(function (name, definition, context, dependencies) {
|
|
||||||
if (typeof context['module'] !== 'undefined' && context['module']['exports']) { if (dependencies && context['require']) { for (var i = 0; i < dependencies.length; i++) context[dependencies[i]] = context['require'](dependencies[i]); } context['module']['exports'] = definition.apply(context); }
|
|
||||||
else if (typeof context['define'] !== 'undefined' && context['define'] === 'function' && context['define']['amd']) { define(name, (dependencies || []), definition); }
|
|
||||||
else { context[name] = definition.apply(context); }
|
|
||||||
})('base64', function (utf8) {
|
|
||||||
var $this = this;
|
|
||||||
var $utf8 = utf8 || this.utf8;
|
|
||||||
var map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
|
||||||
|
|
||||||
return {
|
|
||||||
encode: function (input) {
|
|
||||||
if (typeof $utf8 === 'undefined') throw { error: "MissingMethod", message: "UTF8 Module is missing." };
|
|
||||||
if (typeof input !== 'string') return input;
|
|
||||||
else input = $utf8.encode(input);
|
|
||||||
var output = "", a, b, c, d, e, f, g, i = 0;
|
|
||||||
|
|
||||||
while (i < input.length) {
|
|
||||||
a = input.charCodeAt(i++);
|
|
||||||
b = input.charCodeAt(i++);
|
|
||||||
c = input.charCodeAt(i++);
|
|
||||||
d = a >> 2;
|
|
||||||
e = ((a & 3) << 4) | (b >> 4);
|
|
||||||
f = ((b & 15) << 2) | (c >> 6);
|
|
||||||
g = c & 63;
|
|
||||||
|
|
||||||
if (isNaN(b)) f = g = 64;
|
|
||||||
else if (isNaN(c)) g = 64;
|
|
||||||
|
|
||||||
output += map.charAt(d) + map.charAt(e) + map.charAt(f) + map.charAt(g);
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
},
|
|
||||||
|
|
||||||
decode: function (input) {
|
|
||||||
if (typeof $utf8 === 'undefined') throw { error: "MissingMethod", message: "UTF8 Module is missing." };
|
|
||||||
if (typeof input !== 'string') return input;
|
|
||||||
else input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
|
|
||||||
var output = "", a, b, c, d, e, f, g, i = 0;
|
|
||||||
|
|
||||||
while (i < input.length) {
|
|
||||||
d = map.indexOf(input.charAt(i++));
|
|
||||||
e = map.indexOf(input.charAt(i++));
|
|
||||||
f = map.indexOf(input.charAt(i++));
|
|
||||||
g = map.indexOf(input.charAt(i++));
|
|
||||||
|
|
||||||
a = (d << 2) | (e >> 4);
|
|
||||||
b = ((e & 15) << 4) | (f >> 2);
|
|
||||||
c = ((f & 3) << 6) | g;
|
|
||||||
|
|
||||||
output += String.fromCharCode(a);
|
|
||||||
if (f != 64) output += String.fromCharCode(b);
|
|
||||||
if (g != 64) output += String.fromCharCode(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $utf8.decode(output);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, this, [ "utf8" ]);
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
// From https://gist.github.com/Nijikokun/5192472
|
|
||||||
//
|
|
||||||
// UTF8 Module
|
|
||||||
//
|
|
||||||
// Cleaner and modularized utf-8 encoding and decoding library for javascript.
|
|
||||||
//
|
|
||||||
// copyright: MIT
|
|
||||||
// author: Nijiko Yonskai, @nijikokun, nijikokun@gmail.com
|
|
||||||
!function(r,e,o,t){void 0!==o.module&&o.module.exports?o.module.exports=e.apply(o):void 0!==o.define&&"function"===o.define&&o.define.amd?define("utf8",[],e):o.utf8=e.apply(o)}(0,function(){return{encode:function(r){if("string"!=typeof r)return r;r=r.replace(/\r\n/g,"\n");for(var e,o="",t=0;t<r.length;t++)if((e=r.charCodeAt(t))<128)o+=String.fromCharCode(e);else if(e>127&&e<2048)o+=String.fromCharCode(e>>6|192),o+=String.fromCharCode(63&e|128);else if(e>55295&&e<57344&&r.length>t+1){var i=e,n=r.charCodeAt(t+1);t++;var d=65536+(i-55296<<10|n-56320);o+=String.fromCharCode(d>>18|240),o+=String.fromCharCode(d>>12&63|128),o+=String.fromCharCode(d>>6&63|128),o+=String.fromCharCode(63&d|128)}else o+=String.fromCharCode(e>>12|224),o+=String.fromCharCode(e>>6&63|128),o+=String.fromCharCode(63&e|128);return o},decode:function(r){if("string"!=typeof r)return r;for(var e="",o=0,t=0;o<r.length;)if((t=r.charCodeAt(o))<128)e+=String.fromCharCode(t),o++;else if(t>191&&t<224)e+=String.fromCharCode((31&t)<<6|63&r.charCodeAt(o+1)),o+=2;else if(t>223&&t<240)e+=String.fromCharCode((15&t)<<12|(63&r.charCodeAt(o+1))<<6|63&r.charCodeAt(o+2)),o+=3;else{var i=(7&t)<<18|(63&r.charCodeAt(o+1))<<12|(63&r.charCodeAt(o+2))<<6|63&r.charCodeAt(o+3);e+=String.fromCharCode(55296+(i-65536>>10))+String.fromCharCode(56320+(i-65536&1023)),o+=4}return e}}},this),function(r,e,o,t){if(void 0!==o.module&&o.module.exports){if(t&&o.require)for(var i=0;i<t.length;i++)o[t[i]]=o.require(t[i]);o.module.exports=e.apply(o)}else void 0!==o.define&&"function"===o.define&&o.define.amd?define("base64",t||[],e):o.base64=e.apply(o)}(0,function(r){var e=r||this.utf8,o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";return{encode:function(r){if(void 0===e)throw{error:"MissingMethod",message:"UTF8 Module is missing."};if("string"!=typeof r)return r;r=e.encode(r);for(var t,i,n,d,f,a,h,C="",c=0;c<r.length;)d=(t=r.charCodeAt(c++))>>2,f=(3&t)<<4|(i=r.charCodeAt(c++))>>4,a=(15&i)<<2|(n=r.charCodeAt(c++))>>6,h=63&n,isNaN(i)?a=h=64:isNaN(n)&&(h=64),C+=o.charAt(d)+o.charAt(f)+o.charAt(a)+o.charAt(h);return C},decode:function(r){if(void 0===e)throw{error:"MissingMethod",message:"UTF8 Module is missing."};if("string"!=typeof r)return r;r=r.replace(/[^A-Za-z0-9\+\/\=]/g,"");for(var t,i,n,d,f,a,h="",C=0;C<r.length;)t=o.indexOf(r.charAt(C++))<<2|(d=o.indexOf(r.charAt(C++)))>>4,i=(15&d)<<4|(f=o.indexOf(r.charAt(C++)))>>2,n=(3&f)<<6|(a=o.indexOf(r.charAt(C++))),h+=String.fromCharCode(t),64!=f&&(h+=String.fromCharCode(i)),64!=a&&(h+=String.fromCharCode(n));return e.decode(h)}}},this,["utf8"]);
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"tiddlers": [
|
|
||||||
{
|
|
||||||
"file": "base64-utf8.module.min.js",
|
|
||||||
"fields": {
|
|
||||||
"type": "application/javascript",
|
|
||||||
"title": "$:/core/modules/utils/base64-utf8/base64-utf8.module.js",
|
|
||||||
"module-type": "library"
|
|
||||||
},
|
|
||||||
"prefix": "(function(){",
|
|
||||||
"suffix": "}).call(exports);"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -24,6 +24,26 @@ exports.setStyle = function(element,styles) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Remove style properties of an element
|
||||||
|
element: dom node
|
||||||
|
styleProperties: ordered array of string property names
|
||||||
|
*/
|
||||||
|
exports.removeStyles = function(element, styleProperties) {
|
||||||
|
for (var i=0; i<styleProperties.length; i++) {
|
||||||
|
element.style.removeProperty($tw.utils.convertStyleNameToPropertyName(styleProperties[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Remove single style property of an element
|
||||||
|
element: dom node
|
||||||
|
styleProperty: string property name
|
||||||
|
*/
|
||||||
|
exports.removeStyle = function(element, styleProperty) {
|
||||||
|
$tw.utils.removeStyles(element, [styleProperty])
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Converts a standard CSS property name into the local browser-specific equivalent. For example:
|
Converts a standard CSS property name into the local browser-specific equivalent. For example:
|
||||||
"background-color" --> "backgroundColor"
|
"background-color" --> "backgroundColor"
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ Modal.prototype.display = function(title,options) {
|
|||||||
bodyWidgetNode.addEventListener("tm-close-tiddler",closeHandler,false);
|
bodyWidgetNode.addEventListener("tm-close-tiddler",closeHandler,false);
|
||||||
footerWidgetNode.addEventListener("tm-close-tiddler",closeHandler,false);
|
footerWidgetNode.addEventListener("tm-close-tiddler",closeHandler,false);
|
||||||
// Whether to close the modal dialog when the mask (area outside the modal) is clicked
|
// Whether to close the modal dialog when the mask (area outside the modal) is clicked
|
||||||
if(tiddler.fields && (tiddler.fields["mask-closable"] === "yes" || tiddler.fields["mask-closable"] === "true")) {
|
if(tiddler.fields && (tiddler.fields["mask-closable"] === "yes" || tiddler.fields["mask-closable"] === "true" || tiddler.fields["mask-closable"] === "" || "mask-closable" in tiddler.fields === false)) {
|
||||||
modalBackdrop.addEventListener("click",closeHandler,false);
|
modalBackdrop.addEventListener("click",closeHandler,false);
|
||||||
}
|
}
|
||||||
// Set the initial styles for the message
|
// Set the initial styles for the message
|
||||||
|
|||||||
@@ -0,0 +1,126 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/utils/messaging.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: utils-browser
|
||||||
|
|
||||||
|
Messaging utilities for use with window.postMessage() etc.
|
||||||
|
|
||||||
|
This module intentionally has no dependencies so that it can be included in non-TiddlyWiki projects
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var RESPONSE_TIMEOUT = 2 * 1000;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Class to handle subscribing to publishers
|
||||||
|
|
||||||
|
target: Target window (eg iframe.contentWindow)
|
||||||
|
type: String indicating type of item for which subscriptions are being provided (eg "SAVING")
|
||||||
|
onsubscribe: Function to be invoked with err parameter when the subscription is established, or there is a timeout
|
||||||
|
onmessage: Function to be invoked when a new message arrives, invoked with (data,callback). The callback is invoked with the argument (response)
|
||||||
|
*/
|
||||||
|
function BrowserMessagingSubscriber(options) {
|
||||||
|
var self = this;
|
||||||
|
this.target = options.target;
|
||||||
|
this.type = options.type;
|
||||||
|
this.onsubscribe = options.onsubscribe || function() {};
|
||||||
|
this.onmessage = options.onmessage;
|
||||||
|
this.hasConfirmed = false;
|
||||||
|
this.channel = new MessageChannel();
|
||||||
|
this.channel.port1.addEventListener("message",function(event) {
|
||||||
|
if(this.timerID) {
|
||||||
|
clearTimeout(this.timerID);
|
||||||
|
this.timerID = null;
|
||||||
|
}
|
||||||
|
if(event.data) {
|
||||||
|
if(event.data.verb === "SUBSCRIBED") {
|
||||||
|
self.hasConfirmed = true;
|
||||||
|
self.onsubscribe(null);
|
||||||
|
} else if(event.data.verb === self.type) {
|
||||||
|
self.onmessage(event.data,function(response) {
|
||||||
|
// Send the response back on the supplied port, and then close it
|
||||||
|
event.ports[0].postMessage(response);
|
||||||
|
event.ports[0].close();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Set a timer so that if we don't hear from the iframe before a timeout we alert the user
|
||||||
|
this.timerID = setTimeout(function() {
|
||||||
|
if(!self.hasConfirmed) {
|
||||||
|
self.onsubscribe("NO_RESPONSE");
|
||||||
|
}
|
||||||
|
},RESPONSE_TIMEOUT);
|
||||||
|
this.channel.port1.start();
|
||||||
|
this.target.postMessage({verb: "SUBSCRIBE",to: self.type},"*",[this.channel.port2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.BrowserMessagingSubscriber = BrowserMessagingSubscriber;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Class to handle publishing subscriptions
|
||||||
|
|
||||||
|
type: String indicating type of item for which subscriptions are being provided (eg "SAVING")
|
||||||
|
onsubscribe: Function to be invoked when a subscription occurs
|
||||||
|
*/
|
||||||
|
function BrowserMessagingPublisher(options) {
|
||||||
|
var self = this;
|
||||||
|
this.type = options.type;
|
||||||
|
this.hostIsListening = false;
|
||||||
|
this.port = null;
|
||||||
|
// Listen to connection requests from the host
|
||||||
|
window.addEventListener("message",function(event) {
|
||||||
|
if(event.data && event.data.verb === "SUBSCRIBE" && event.data.to === self.type) {
|
||||||
|
self.hostIsListening = true;
|
||||||
|
// Acknowledge
|
||||||
|
self.port = event.ports[0];
|
||||||
|
self.port.postMessage({verb: "SUBSCRIBED", to: self.type});
|
||||||
|
if(options.onsubscribe) {
|
||||||
|
options.onsubscribe(event.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
BrowserMessagingPublisher.prototype.canSend = function() {
|
||||||
|
return !!this.hostIsListening && !!this.port;
|
||||||
|
};
|
||||||
|
|
||||||
|
BrowserMessagingPublisher.prototype.send = function(data,callback) {
|
||||||
|
var self = this;
|
||||||
|
callback = callback || function() {};
|
||||||
|
// Check that we've been initialised by the host
|
||||||
|
if(!this.hostIsListening || !this.port) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Create a channel for the confirmation
|
||||||
|
var channel = new MessageChannel();
|
||||||
|
channel.port1.addEventListener("message",function(event) {
|
||||||
|
if(event.data && event.data.verb === "OK") {
|
||||||
|
callback(null);
|
||||||
|
} else {
|
||||||
|
callback("BrowserMessagingPublisher for " + self.type + " error: " + (event.data || {}).verb);
|
||||||
|
}
|
||||||
|
channel.port1.close();
|
||||||
|
});
|
||||||
|
channel.port1.start();
|
||||||
|
// Send the save request with the port for the response
|
||||||
|
this.port.postMessage(data,[channel.port2]);
|
||||||
|
};
|
||||||
|
|
||||||
|
BrowserMessagingPublisher.prototype.close = function() {
|
||||||
|
if(this.port) {
|
||||||
|
this.port.close();
|
||||||
|
this.hostIsListening = false;
|
||||||
|
this.port = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.BrowserMessagingPublisher = BrowserMessagingPublisher;
|
||||||
|
|
||||||
|
})();
|
||||||
@@ -119,3 +119,19 @@ exports.getParseTreeText = function getParseTreeText(tree) {
|
|||||||
}
|
}
|
||||||
return output.join("");
|
return output.join("");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.getParser = function(type,options) {
|
||||||
|
options = options || {};
|
||||||
|
// Select a parser
|
||||||
|
var Parser = $tw.Wiki.parsers[type];
|
||||||
|
if(!Parser && $tw.utils.getFileExtensionInfo(type)) {
|
||||||
|
Parser = $tw.Wiki.parsers[$tw.utils.getFileExtensionInfo(type).type];
|
||||||
|
}
|
||||||
|
if(!Parser) {
|
||||||
|
Parser = $tw.Wiki.parsers[options.defaultType || "text/vnd.tiddlywiki"];
|
||||||
|
}
|
||||||
|
if(!Parser) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return Parser;
|
||||||
|
};
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ Various static utility functions.
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var base64utf8 = require("$:/core/modules/utils/base64-utf8/base64-utf8.module.js");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Display a message, in colour if we're on a terminal
|
Display a message, in colour if we're on a terminal
|
||||||
*/
|
*/
|
||||||
@@ -842,22 +840,50 @@ if(typeof window !== 'undefined') {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.base64ToBytes = function(base64) {
|
||||||
|
const binString = exports.atob(base64);
|
||||||
|
return Uint8Array.from(binString, (m) => m.codePointAt(0));
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.bytesToBase64 = function(bytes) {
|
||||||
|
const binString = Array.from(bytes, (byte) => String.fromCodePoint(byte)).join("");
|
||||||
|
return exports.btoa(binString);
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.base64EncodeUtf8 = function(str) {
|
||||||
|
if ($tw.browser) {
|
||||||
|
return exports.bytesToBase64(new TextEncoder().encode(str));
|
||||||
|
} else {
|
||||||
|
const buff = Buffer.from(str, "utf-8");
|
||||||
|
return buff.toString("base64");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.base64DecodeUtf8 = function(str) {
|
||||||
|
if ($tw.browser) {
|
||||||
|
return new TextDecoder().decode(exports.base64ToBytes(str));
|
||||||
|
} else {
|
||||||
|
const buff = Buffer.from(str, "base64");
|
||||||
|
return buff.toString("utf-8");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Decode a base64 string
|
Decode a base64 string
|
||||||
*/
|
*/
|
||||||
exports.base64Decode = function(string64,binary,urlsafe) {
|
exports.base64Decode = function(string64,binary,urlsafe) {
|
||||||
var encoded = urlsafe ? string64.replace(/_/g,'/').replace(/-/g,'+') : string64;
|
const encoded = urlsafe ? string64.replace(/_/g,'/').replace(/-/g,'+') : string64;
|
||||||
if(binary) return exports.atob(encoded)
|
if(binary) return exports.atob(encoded)
|
||||||
else return base64utf8.base64.decode.call(base64utf8,encoded);
|
else return exports.base64DecodeUtf8(encoded);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Encode a string to base64
|
Encode a string to base64
|
||||||
*/
|
*/
|
||||||
exports.base64Encode = function(string64,binary,urlsafe) {
|
exports.base64Encode = function(string64,binary,urlsafe) {
|
||||||
var encoded;
|
let encoded;
|
||||||
if(binary) encoded = exports.btoa(string64);
|
if(binary) encoded = exports.btoa(string64);
|
||||||
else encoded = base64utf8.base64.encode.call(base64utf8,string64);
|
else encoded = exports.base64EncodeUtf8(string64);
|
||||||
if(urlsafe) {
|
if(urlsafe) {
|
||||||
encoded = encoded.replace(/\+/g,'-').replace(/\//g,'_');
|
encoded = encoded.replace(/\+/g,'-').replace(/\//g,'_');
|
||||||
}
|
}
|
||||||
@@ -1023,7 +1049,7 @@ exports.makeCompareFunction = function(type,options) {
|
|||||||
return compare(dateA,dateB);
|
return compare(dateA,dateB);
|
||||||
},
|
},
|
||||||
"version": function(a,b) {
|
"version": function(a,b) {
|
||||||
return $tw.utils.compareVersions(a,b);
|
return compare($tw.utils.compareVersions(a,b),0);
|
||||||
},
|
},
|
||||||
"alphanumeric": function(a,b) {
|
"alphanumeric": function(a,b) {
|
||||||
if(!isCaseSensitive) {
|
if(!isCaseSensitive) {
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/widgets/audio.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: widget
|
||||||
|
|
||||||
|
Basic Audio widget for displaying audio files.
|
||||||
|
This is a simple implementation that can be overridden by plugins
|
||||||
|
for more advanced functionality.
|
||||||
|
|
||||||
|
\*/
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
||||||
|
|
||||||
|
var AudioWidget = function(parseTreeNode,options) {
|
||||||
|
this.initialise(parseTreeNode,options);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inherit from the base widget class
|
||||||
|
*/
|
||||||
|
AudioWidget.prototype = new Widget();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Render this widget into the DOM
|
||||||
|
*/
|
||||||
|
AudioWidget.prototype.render = function(parent,nextSibling) {
|
||||||
|
this.parentDomNode = parent;
|
||||||
|
this.computeAttributes();
|
||||||
|
this.execute();
|
||||||
|
|
||||||
|
// Create audio element
|
||||||
|
var audioElement = this.document.createElement("audio");
|
||||||
|
audioElement.setAttribute("controls", this.getAttribute("controls", "controls"));
|
||||||
|
audioElement.setAttribute("style", this.getAttribute("style", "width: 100%; object-fit: contain"));
|
||||||
|
audioElement.className = "tw-audio-element";
|
||||||
|
|
||||||
|
// Set source
|
||||||
|
if(this.audioSource) {
|
||||||
|
if (this.audioSource.indexOf("data:") === 0) {
|
||||||
|
audioElement.setAttribute("src", this.audioSource);
|
||||||
|
} else {
|
||||||
|
var sourceElement = this.document.createElement("source");
|
||||||
|
sourceElement.setAttribute("src", this.audioSource);
|
||||||
|
if(this.audioType) {
|
||||||
|
sourceElement.setAttribute("type", this.audioType);
|
||||||
|
}
|
||||||
|
audioElement.appendChild(sourceElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert the audio into the DOM
|
||||||
|
parent.insertBefore(audioElement, nextSibling);
|
||||||
|
this.domNodes.push(audioElement);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Compute the internal state of the widget
|
||||||
|
*/
|
||||||
|
AudioWidget.prototype.execute = function() {
|
||||||
|
// Get the audio source and type
|
||||||
|
this.audioSource = this.getAttribute("src");
|
||||||
|
this.audioType = this.getAttribute("type");
|
||||||
|
this.audioControls = this.getAttribute("controls", "controls");
|
||||||
|
|
||||||
|
// Try to get from tiddler attribute
|
||||||
|
if(!this.audioSource && this.getAttribute("tiddler")) {
|
||||||
|
var tiddlerTitle = this.getAttribute("tiddler");
|
||||||
|
var tiddler = this.wiki.getTiddler(tiddlerTitle);
|
||||||
|
if(tiddler) {
|
||||||
|
if(tiddler.fields._canonical_uri) {
|
||||||
|
this.audioSource = tiddler.fields._canonical_uri;
|
||||||
|
this.audioType = tiddler.fields.type;
|
||||||
|
} else if(tiddler.fields.text) {
|
||||||
|
this.audioSource = "data:" + tiddler.fields.type + ";base64," + tiddler.fields.text;
|
||||||
|
this.audioType = tiddler.fields.type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure we have a tiddler for saving timestamps
|
||||||
|
this.tiddlerTitle = this.getAttribute("tiddler");
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
|
||||||
|
*/
|
||||||
|
AudioWidget.prototype.refresh = function(changedTiddlers) {
|
||||||
|
var changedAttributes = this.computeAttributes();
|
||||||
|
if(changedAttributes.src || changedAttributes.type || changedAttributes.controls || changedAttributes.tiddler) {
|
||||||
|
this.refreshSelf();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.audio = AudioWidget;
|
||||||
|
|
||||||
|
|
||||||
@@ -61,6 +61,10 @@ ButtonWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
sourcePrefix: "data-",
|
sourcePrefix: "data-",
|
||||||
destPrefix: "data-"
|
destPrefix: "data-"
|
||||||
});
|
});
|
||||||
|
this.assignAttributes(domNode,{
|
||||||
|
sourcePrefix: "aria-",
|
||||||
|
destPrefix: "aria-"
|
||||||
|
});
|
||||||
// Assign other attributes
|
// Assign other attributes
|
||||||
if(this.style) {
|
if(this.style) {
|
||||||
domNode.setAttribute("style",this.style);
|
domNode.setAttribute("style",this.style);
|
||||||
@@ -68,9 +72,6 @@ ButtonWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
if(this.tooltip) {
|
if(this.tooltip) {
|
||||||
domNode.setAttribute("title",this.tooltip);
|
domNode.setAttribute("title",this.tooltip);
|
||||||
}
|
}
|
||||||
if(this["aria-label"]) {
|
|
||||||
domNode.setAttribute("aria-label",this["aria-label"]);
|
|
||||||
}
|
|
||||||
if (this.role) {
|
if (this.role) {
|
||||||
domNode.setAttribute("role", this.role);
|
domNode.setAttribute("role", this.role);
|
||||||
}
|
}
|
||||||
@@ -215,7 +216,6 @@ ButtonWidget.prototype.execute = function() {
|
|||||||
this.setTo = this.getAttribute("setTo");
|
this.setTo = this.getAttribute("setTo");
|
||||||
this.popup = this.getAttribute("popup");
|
this.popup = this.getAttribute("popup");
|
||||||
this.hover = this.getAttribute("hover");
|
this.hover = this.getAttribute("hover");
|
||||||
this["aria-label"] = this.getAttribute("aria-label");
|
|
||||||
this.role = this.getAttribute("role");
|
this.role = this.getAttribute("role");
|
||||||
this.tooltip = this.getAttribute("tooltip");
|
this.tooltip = this.getAttribute("tooltip");
|
||||||
this.style = this.getAttribute("style");
|
this.style = this.getAttribute("style");
|
||||||
@@ -271,6 +271,10 @@ ButtonWidget.prototype.refresh = function(changedTiddlers) {
|
|||||||
sourcePrefix: "data-",
|
sourcePrefix: "data-",
|
||||||
destPrefix: "data-"
|
destPrefix: "data-"
|
||||||
});
|
});
|
||||||
|
this.assignAttributes(this.domNodes[0],{
|
||||||
|
sourcePrefix: "aria-",
|
||||||
|
destPrefix: "aria-"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return this.refreshChildren(changedTiddlers);
|
return this.refreshChildren(changedTiddlers);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -74,6 +74,8 @@ ElementWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
// Create the DOM node and render children
|
// Create the DOM node and render children
|
||||||
var domNode = this.document.createElementNS(this.namespace,this.tag);
|
var domNode = this.document.createElementNS(this.namespace,this.tag);
|
||||||
this.assignAttributes(domNode,{excludeEventAttributes: true});
|
this.assignAttributes(domNode,{excludeEventAttributes: true});
|
||||||
|
// Allow hooks to manipulate the DOM node. Eg: Add debug info
|
||||||
|
$tw.hooks.invokeHook("th-dom-rendering-element", domNode, this);
|
||||||
parent.insertBefore(domNode,nextSibling);
|
parent.insertBefore(domNode,nextSibling);
|
||||||
this.renderChildren(domNode,null);
|
this.renderChildren(domNode,null);
|
||||||
this.domNodes.push(domNode);
|
this.domNodes.push(domNode);
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ EventWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
domNode.addEventListener(type,function(event) {
|
domNode.addEventListener(type,function(event) {
|
||||||
var selector = self.getAttribute("selector"),
|
var selector = self.getAttribute("selector"),
|
||||||
matchSelector = self.getAttribute("matchSelector"),
|
matchSelector = self.getAttribute("matchSelector"),
|
||||||
actions = self.getAttribute("$"+type) || self.getAttribute("actions-"+type),
|
actions = self.getAttribute("$"+type),
|
||||||
stopPropagation = self.getAttribute("stopPropagation","onaction"),
|
stopPropagation = self.getAttribute("stopPropagation","onaction"),
|
||||||
selectedNode = event.target,
|
selectedNode = event.target,
|
||||||
selectedNodeRect,
|
selectedNodeRect,
|
||||||
@@ -122,9 +122,6 @@ EventWidget.prototype.execute = function() {
|
|||||||
self.types.push(key.slice(1));
|
self.types.push(key.slice(1));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if(!this.types.length) {
|
|
||||||
this.types = this.getAttribute("events","").split(" ");
|
|
||||||
}
|
|
||||||
this.elementTag = this.getAttribute("tag");
|
this.elementTag = this.getAttribute("tag");
|
||||||
// Make child widgets
|
// Make child widgets
|
||||||
this.makeChildWidgets();
|
this.makeChildWidgets();
|
||||||
|
|||||||
@@ -49,7 +49,8 @@ ImportVariablesWidget.prototype.execute = function(tiddlerList) {
|
|||||||
var parser = widgetPointer.wiki.parseTiddler(title,{parseAsInline:true, configTrimWhiteSpace:false});
|
var parser = widgetPointer.wiki.parseTiddler(title,{parseAsInline:true, configTrimWhiteSpace:false});
|
||||||
if(parser) {
|
if(parser) {
|
||||||
var parseTreeNode = parser.tree[0];
|
var parseTreeNode = parser.tree[0];
|
||||||
while(parseTreeNode && ["setvariable","set","parameters"].indexOf(parseTreeNode.type) !== -1) {
|
// process AST nodes generated by pragma rules.
|
||||||
|
while(parseTreeNode && ["setvariable","set","parameters","void"].indexOf(parseTreeNode.type) !== -1) {
|
||||||
var node = {
|
var node = {
|
||||||
type: "set",
|
type: "set",
|
||||||
attributes: parseTreeNode.attributes,
|
attributes: parseTreeNode.attributes,
|
||||||
|
|||||||
@@ -45,6 +45,10 @@ LinkWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
sourcePrefix: "data-",
|
sourcePrefix: "data-",
|
||||||
destPrefix: "data-"
|
destPrefix: "data-"
|
||||||
});
|
});
|
||||||
|
this.assignAttributes(domNode,{
|
||||||
|
sourcePrefix: "aria-",
|
||||||
|
destPrefix: "aria-"
|
||||||
|
});
|
||||||
parent.insertBefore(domNode,nextSibling);
|
parent.insertBefore(domNode,nextSibling);
|
||||||
this.renderChildren(domNode,null);
|
this.renderChildren(domNode,null);
|
||||||
this.domNodes.push(domNode);
|
this.domNodes.push(domNode);
|
||||||
@@ -125,9 +129,13 @@ LinkWidget.prototype.renderLink = function(parent,nextSibling) {
|
|||||||
});
|
});
|
||||||
domNode.setAttribute("title",tooltipText);
|
domNode.setAttribute("title",tooltipText);
|
||||||
}
|
}
|
||||||
if(this["aria-label"]) {
|
if(this.role) {
|
||||||
domNode.setAttribute("aria-label",this["aria-label"]);
|
domNode.setAttribute("role",this.role);
|
||||||
}
|
}
|
||||||
|
this.assignAttributes(domNode,{
|
||||||
|
sourcePrefix: "aria-",
|
||||||
|
destPrefix: "aria-"
|
||||||
|
})
|
||||||
// Add a click event handler
|
// Add a click event handler
|
||||||
$tw.utils.addEventListeners(domNode,[
|
$tw.utils.addEventListeners(domNode,[
|
||||||
{name: "click", handlerObject: this, handlerMethod: "handleClickEvent"},
|
{name: "click", handlerObject: this, handlerMethod: "handleClickEvent"},
|
||||||
@@ -139,6 +147,8 @@ LinkWidget.prototype.renderLink = function(parent,nextSibling) {
|
|||||||
dragTiddlerFn: function() {return self.to;},
|
dragTiddlerFn: function() {return self.to;},
|
||||||
widget: this
|
widget: this
|
||||||
});
|
});
|
||||||
|
} else if(this.draggable === "no") {
|
||||||
|
domNode.setAttribute("draggable","false");
|
||||||
}
|
}
|
||||||
// Assign data- attributes
|
// Assign data- attributes
|
||||||
this.assignAttributes(domNode,{
|
this.assignAttributes(domNode,{
|
||||||
@@ -188,7 +198,7 @@ LinkWidget.prototype.execute = function() {
|
|||||||
// Pick up our attributes
|
// Pick up our attributes
|
||||||
this.to = this.getAttribute("to",this.getVariable("currentTiddler"));
|
this.to = this.getAttribute("to",this.getVariable("currentTiddler"));
|
||||||
this.tooltip = this.getAttribute("tooltip");
|
this.tooltip = this.getAttribute("tooltip");
|
||||||
this["aria-label"] = this.getAttribute("aria-label");
|
this.role = this.getAttribute("role");
|
||||||
this.linkClasses = this.getAttribute("class");
|
this.linkClasses = this.getAttribute("class");
|
||||||
this.overrideClasses = this.getAttribute("overrideClass");
|
this.overrideClasses = this.getAttribute("overrideClass");
|
||||||
this.tabIndex = this.getAttribute("tabindex");
|
this.tabIndex = this.getAttribute("tabindex");
|
||||||
|
|||||||
@@ -94,8 +94,6 @@ RangeWidget.prototype.getActionVariables = function(options) {
|
|||||||
|
|
||||||
// actionsStart
|
// actionsStart
|
||||||
RangeWidget.prototype.handleMouseDownEvent = function(event) {
|
RangeWidget.prototype.handleMouseDownEvent = function(event) {
|
||||||
this.mouseDown = true; // TODO remove once IE is gone.
|
|
||||||
this.startValue = this.inputDomNode.value; // TODO remove this line once IE is gone!
|
|
||||||
this.handleEvent(event);
|
this.handleEvent(event);
|
||||||
// Trigger actions
|
// Trigger actions
|
||||||
if(this.actionsMouseDown) {
|
if(this.actionsMouseDown) {
|
||||||
@@ -106,26 +104,16 @@ RangeWidget.prototype.handleMouseDownEvent = function(event) {
|
|||||||
|
|
||||||
// actionsStop
|
// actionsStop
|
||||||
RangeWidget.prototype.handleMouseUpEvent = function(event) {
|
RangeWidget.prototype.handleMouseUpEvent = function(event) {
|
||||||
this.mouseDown = false; // TODO remove once IE is gone.
|
|
||||||
this.handleEvent(event);
|
this.handleEvent(event);
|
||||||
// Trigger actions
|
// Trigger actions
|
||||||
if(this.actionsMouseUp) {
|
if(this.actionsMouseUp) {
|
||||||
var variables = this.getActionVariables()
|
var variables = this.getActionVariables()
|
||||||
this.invokeActionString(this.actionsMouseUp,this,event,variables);
|
this.invokeActionString(this.actionsMouseUp,this,event,variables);
|
||||||
}
|
}
|
||||||
// TODO remove the following if() once IE is gone!
|
|
||||||
if ($tw.browser.isIE) {
|
|
||||||
if (this.startValue !== this.inputDomNode.value) {
|
|
||||||
this.handleChangeEvent(event);
|
|
||||||
this.startValue = this.inputDomNode.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RangeWidget.prototype.handleChangeEvent = function(event) {
|
RangeWidget.prototype.handleChangeEvent = function(event) {
|
||||||
if (this.mouseDown) { // TODO refactor this function once IE is gone.
|
|
||||||
this.handleInputEvent(event);
|
this.handleInputEvent(event);
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
RangeWidget.prototype.handleInputEvent = function(event) {
|
RangeWidget.prototype.handleInputEvent = function(event) {
|
||||||
@@ -152,8 +140,6 @@ RangeWidget.prototype.handleEvent = function(event) {
|
|||||||
Compute the internal state of the widget
|
Compute the internal state of the widget
|
||||||
*/
|
*/
|
||||||
RangeWidget.prototype.execute = function() {
|
RangeWidget.prototype.execute = function() {
|
||||||
// TODO remove the next 1 lines once IE is gone!
|
|
||||||
this.mouseUp = true; // Needed for IE10
|
|
||||||
// Get the parameters from the attributes
|
// Get the parameters from the attributes
|
||||||
this.tiddlerTitle = this.getAttribute("tiddler",this.getVariable("currentTiddler"));
|
this.tiddlerTitle = this.getAttribute("tiddler",this.getVariable("currentTiddler"));
|
||||||
this.tiddlerField = this.getAttribute("field","text");
|
this.tiddlerField = this.getAttribute("field","text");
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ ScrollableWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
ScrollableWidget.prototype.listenerFunction = function(event) {
|
ScrollableWidget.prototype.listenerFunction = function(event) {
|
||||||
self = this;
|
var self = this;
|
||||||
clearTimeout(this.timeout);
|
clearTimeout(this.timeout);
|
||||||
this.timeout = setTimeout(function() {
|
this.timeout = setTimeout(function() {
|
||||||
var existingTiddler = self.wiki.getTiddler(self.scrollableBind),
|
var existingTiddler = self.wiki.getTiddler(self.scrollableBind),
|
||||||
|
|||||||
Executable
+23
@@ -0,0 +1,23 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/widgets/void.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: widget
|
||||||
|
|
||||||
|
Void widget that corresponds to pragma and comment AST nodes, etc. It does not render itself but renders all its children.
|
||||||
|
|
||||||
|
\*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
||||||
|
|
||||||
|
var VoidNodeWidget = function(parseTreeNode,options) {
|
||||||
|
this.initialise(parseTreeNode,options);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inherit from the base widget class
|
||||||
|
*/
|
||||||
|
VoidNodeWidget.prototype = new Widget();
|
||||||
|
|
||||||
|
exports.void = VoidNodeWidget;
|
||||||
+3
-13
@@ -1059,17 +1059,7 @@ Options include:
|
|||||||
exports.parseText = function(type,text,options) {
|
exports.parseText = function(type,text,options) {
|
||||||
text = text || "";
|
text = text || "";
|
||||||
options = options || {};
|
options = options || {};
|
||||||
// Select a parser
|
var Parser = $tw.utils.getParser(type,options)
|
||||||
var Parser = $tw.Wiki.parsers[type];
|
|
||||||
if(!Parser && $tw.utils.getFileExtensionInfo(type)) {
|
|
||||||
Parser = $tw.Wiki.parsers[$tw.utils.getFileExtensionInfo(type).type];
|
|
||||||
}
|
|
||||||
if(!Parser) {
|
|
||||||
Parser = $tw.Wiki.parsers[options.defaultType || "text/vnd.tiddlywiki"];
|
|
||||||
}
|
|
||||||
if(!Parser) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// Return the parser instance
|
// Return the parser instance
|
||||||
return new Parser(type,text,{
|
return new Parser(type,text,{
|
||||||
parseAsInline: options.parseAsInline,
|
parseAsInline: options.parseAsInline,
|
||||||
@@ -1083,7 +1073,7 @@ exports.parseText = function(type,text,options) {
|
|||||||
Parse a tiddler according to its MIME type
|
Parse a tiddler according to its MIME type
|
||||||
*/
|
*/
|
||||||
exports.parseTiddler = function(title,options) {
|
exports.parseTiddler = function(title,options) {
|
||||||
options = $tw.utils.extend({},options);
|
options = options || {};
|
||||||
var cacheType = options.parseAsInline ? "inlineParseTree" : "blockParseTree",
|
var cacheType = options.parseAsInline ? "inlineParseTree" : "blockParseTree",
|
||||||
tiddler = this.getTiddler(title),
|
tiddler = this.getTiddler(title),
|
||||||
self = this;
|
self = this;
|
||||||
@@ -1443,7 +1433,7 @@ exports.search = function(text,options) {
|
|||||||
// Don't search the text field if the content type is binary
|
// Don't search the text field if the content type is binary
|
||||||
var fieldName = searchFields[fieldIndex];
|
var fieldName = searchFields[fieldIndex];
|
||||||
if(fieldName === "text" && contentTypeInfo.encoding !== "utf8") {
|
if(fieldName === "text" && contentTypeInfo.encoding !== "utf8") {
|
||||||
break;
|
continue;
|
||||||
}
|
}
|
||||||
var str = tiddler.fields[fieldName],
|
var str = tiddler.fields[fieldName],
|
||||||
t;
|
t;
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ modal-footer-background: #f5f5f5
|
|||||||
modal-footer-border: #dddddd
|
modal-footer-border: #dddddd
|
||||||
modal-header-border: #eeeeee
|
modal-header-border: #eeeeee
|
||||||
muted-foreground: #bbb
|
muted-foreground: #bbb
|
||||||
|
network-activity-foreground: <<colour primary>>
|
||||||
notification-background: #ffffdd
|
notification-background: #ffffdd
|
||||||
notification-border: #999999
|
notification-border: #999999
|
||||||
page-background: #6f6f70
|
page-background: #6f6f70
|
||||||
@@ -56,22 +57,26 @@ primary: #29a6ee
|
|||||||
select-tag-background:
|
select-tag-background:
|
||||||
select-tag-foreground:
|
select-tag-foreground:
|
||||||
sidebar-button-foreground: <<colour foreground>>
|
sidebar-button-foreground: <<colour foreground>>
|
||||||
sidebar-controls-foreground-hover: #000000
|
sidebar-controls-foreground-hover: #222222
|
||||||
sidebar-controls-foreground: #c2c1c2
|
sidebar-controls-foreground: #c2c1c2
|
||||||
sidebar-foreground-shadow: rgba(255,255,255,0)
|
sidebar-foreground-shadow: transparent
|
||||||
sidebar-foreground: #d3d2d4
|
sidebar-foreground: #d3d2d4
|
||||||
sidebar-muted-foreground-hover: #444444
|
sidebar-muted-foreground-hover: #333333
|
||||||
sidebar-muted-foreground: #c0c0c0
|
sidebar-muted-foreground: #c0c0c0
|
||||||
sidebar-tab-background-selected: #6f6f70
|
sidebar-tab-background-selected: #6f6f70
|
||||||
sidebar-tab-background: #666667
|
sidebar-tab-background: #666667
|
||||||
sidebar-tab-border-selected: #999
|
sidebar-tab-border-selected: #999
|
||||||
sidebar-tab-border: #515151
|
sidebar-tab-border: #515151
|
||||||
sidebar-tab-divider: #999
|
sidebar-tab-divider: #999
|
||||||
sidebar-tab-foreground-selected:
|
sidebar-tab-foreground-selected: #bfbfbf
|
||||||
sidebar-tab-foreground: #999
|
sidebar-tab-foreground: #b0b0b0
|
||||||
sidebar-tiddler-link-foreground-hover: #444444
|
sidebar-tiddler-link-foreground-hover: #444444
|
||||||
sidebar-tiddler-link-foreground: #d1d0d2
|
sidebar-tiddler-link-foreground: #aaaaaa
|
||||||
site-title-foreground: <<colour tiddler-title-foreground>>
|
site-title-foreground: <<colour tiddler-title-foreground>>
|
||||||
|
stability-deprecated: #bf616a
|
||||||
|
stability-experimental: #d08770
|
||||||
|
stability-legacy: #88c0d0
|
||||||
|
stability-stable: #a3be8c
|
||||||
static-alert-foreground: #aaaaaa
|
static-alert-foreground: #aaaaaa
|
||||||
tab-background-selected: #ffffff
|
tab-background-selected: #ffffff
|
||||||
tab-background: #d8d8d8
|
tab-background: #d8d8d8
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
title: $:/core/templates/tiddlywiki5-external-js.html
|
title: $:/core/templates/tiddlywiki5-external-js.html
|
||||||
|
|
||||||
<$set name="saveTiddlerAndShadowsFilter" filter="[subfilter<saveTiddlerFilter>] [subfilter<saveTiddlerFilter>plugintiddlers[]]">
|
<$set name="saveTiddlerAndShadowsFilter" filter="[subfilter<saveTiddlerFilter>] [subfilter<saveTiddlerFilter>plugintiddlers[]]">
|
||||||
|
<$set name="rawMarkupFilter" filter="[enlist<saveTiddlerAndShadowsFilter>] +[[$:/core]plugintiddlers[]]">
|
||||||
`<!doctype html>
|
`<!doctype html>
|
||||||
`{{$:/core/templates/MOTW.html}}`<html lang="`<$text text={{{ [{$:/language}get[name]] }}}/>`">
|
`{{$:/core/templates/MOTW.html}}`<html lang="`<$text text={{{ [{$:/language}get[name]] }}}/>`">
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
||||||
<!--~~ Raw markup for the top of the head section ~~-->
|
<!--~~ Raw markup for the top of the head section ~~-->
|
||||||
`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified/TopHead]] ||$:/core/templates/raw-static-tiddler}}}`
|
`{{{ [enlist<rawMarkupFilter>tag[$:/tags/RawMarkupWikified/TopHead]] ||$:/core/templates/raw-static-tiddler}}}`
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
|
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
|
||||||
<meta name="application-name" content="TiddlyWiki" />
|
<meta name="application-name" content="TiddlyWiki" />
|
||||||
<meta name="generator" content="TiddlyWiki" />
|
<meta name="generator" content="TiddlyWiki" />
|
||||||
@@ -22,13 +23,13 @@ title: $:/core/templates/tiddlywiki5-external-js.html
|
|||||||
<!--~~ This is a Tiddlywiki file. The points of interest in the file are marked with this pattern ~~-->
|
<!--~~ This is a Tiddlywiki file. The points of interest in the file are marked with this pattern ~~-->
|
||||||
|
|
||||||
<!--~~ Raw markup ~~-->
|
<!--~~ Raw markup ~~-->
|
||||||
`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/core/wiki/rawmarkup]] ||$:/core/templates/plain-text-tiddler}}}`
|
`{{{ [enlist<rawMarkupFilter>tag[$:/core/wiki/rawmarkup]] ||$:/core/templates/plain-text-tiddler}}}`
|
||||||
`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkup]] ||$:/core/templates/plain-text-tiddler}}}`
|
`{{{ [enlist<rawMarkupFilter>tag[$:/tags/RawMarkup]] ||$:/core/templates/plain-text-tiddler}}}`
|
||||||
`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified]] ||$:/core/templates/raw-static-tiddler}}}`
|
`{{{ [enlist<rawMarkupFilter>tag[$:/tags/RawMarkupWikified]] ||$:/core/templates/raw-static-tiddler}}}`
|
||||||
</head>
|
</head>
|
||||||
<body class="tc-body">
|
<body class="tc-body">
|
||||||
<!--~~ Raw markup for the top of the body section ~~-->
|
<!--~~ Raw markup for the top of the body section ~~-->
|
||||||
`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified/TopBody]] ||$:/core/templates/raw-static-tiddler}}}`
|
`{{{ [enlist<rawMarkupFilter>tag[$:/tags/RawMarkupWikified/TopBody]] ||$:/core/templates/raw-static-tiddler}}}`
|
||||||
<!--~~ Static styles ~~-->
|
<!--~~ Static styles ~~-->
|
||||||
<div id="styleArea">
|
<div id="styleArea">
|
||||||
`{{$:/boot/boot.css||$:/core/templates/css-tiddler}}`
|
`{{$:/boot/boot.css||$:/core/templates/css-tiddler}}`
|
||||||
@@ -42,9 +43,10 @@ title: $:/core/templates/tiddlywiki5-external-js.html
|
|||||||
<!--~~ Ordinary tiddlers ~~-->
|
<!--~~ Ordinary tiddlers ~~-->
|
||||||
`{{$:/core/templates/store.area.template.html}}`
|
`{{$:/core/templates/store.area.template.html}}`
|
||||||
<!--~~ Raw markup for the bottom of the body section ~~-->
|
<!--~~ Raw markup for the bottom of the body section ~~-->
|
||||||
`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified/BottomBody]] ||$:/core/templates/raw-static-tiddler}}}`
|
`{{{ [enlist<rawMarkupFilter>tag[$:/tags/RawMarkupWikified/BottomBody]] ||$:/core/templates/raw-static-tiddler}}}`
|
||||||
<!--~~ Load external JavaScripts ~~-->
|
<!--~~ Load external JavaScripts ~~-->
|
||||||
<script src="`{{{ [<coreURL>] }}}`" onerror="alert('Error: Cannot load `{{{ [<coreURL>] }}}`');"></script>
|
<script src="`{{{ [<coreURL>] }}}`" onerror="alert('Error: Cannot load `{{{ [<coreURL>] }}}`');"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>`
|
</html>`
|
||||||
</$set>
|
</$set>
|
||||||
|
</$set>
|
||||||
@@ -62,13 +62,20 @@ caption: {{$:/language/Search/Filter/Caption}}
|
|||||||
</$list>
|
</$list>
|
||||||
\end
|
\end
|
||||||
|
|
||||||
|
\procedure input-actions()
|
||||||
|
<%if [<event-key-descriptor>match[((input-tab-right))]] %>
|
||||||
|
<<set-next-input-tab>>
|
||||||
|
<%elseif [<event-key-descriptor>match[((input-tab-left))]] %>
|
||||||
|
<<set-previous-input-tab>>
|
||||||
|
<%endif%>
|
||||||
|
\end
|
||||||
|
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
|
|
||||||
<<lingo Filter/Hint>>
|
<<lingo Filter/Hint>>
|
||||||
|
|
||||||
<div class="tc-search tc-advanced-search">
|
<div class="tc-search tc-advanced-search">
|
||||||
<$keyboard key="((input-tab-right))" actions=<<set-next-input-tab>> class="tc-small-gap-right">
|
<$keyboard key="((input-tab-right)) ((input-tab-left))" actions=<<input-actions>> class="tc-small-gap-right">
|
||||||
<$keyboard key="((input-tab-left))" actions=<<set-previous-input-tab>>>
|
|
||||||
<$transclude $variable="keyboard-driven-input"
|
<$transclude $variable="keyboard-driven-input"
|
||||||
tiddler="$:/temp/advancedsearch/input"
|
tiddler="$:/temp/advancedsearch/input"
|
||||||
storeTitle="$:/temp/advancedsearch"
|
storeTitle="$:/temp/advancedsearch"
|
||||||
@@ -84,7 +91,6 @@ caption: {{$:/language/Search/Filter/Caption}}
|
|||||||
inputCancelActions=<<cancel-search-actions>>
|
inputCancelActions=<<cancel-search-actions>>
|
||||||
/>
|
/>
|
||||||
</$keyboard>
|
</$keyboard>
|
||||||
</$keyboard>
|
|
||||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/AdvancedSearch/FilterButton]!has[draft.of]]">
|
<$list filter="[all[shadows+tiddlers]tag[$:/tags/AdvancedSearch/FilterButton]!has[draft.of]]">
|
||||||
<$transclude/>
|
<$transclude/>
|
||||||
</$list>
|
</$list>
|
||||||
|
|||||||
@@ -53,13 +53,20 @@ first-search-filter: [all[shadows]search<userInput>sort[title]limit[250]] -[[$:/
|
|||||||
</$list></$list>
|
</$list></$list>
|
||||||
\end
|
\end
|
||||||
|
|
||||||
|
\procedure input-actions()
|
||||||
|
<%if [<event-key-descriptor>match[((input-tab-right))]] %>
|
||||||
|
<<set-next-input-tab>>
|
||||||
|
<%elseif [<event-key-descriptor>match[((input-tab-left))]] %>
|
||||||
|
<<set-previous-input-tab>>
|
||||||
|
<%endif%>
|
||||||
|
\end
|
||||||
|
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
|
|
||||||
<<lingo Shadows/Hint>>
|
<<lingo Shadows/Hint>>
|
||||||
|
|
||||||
<div class="tc-search">
|
<div class="tc-search">
|
||||||
<$keyboard key="((input-tab-right))" actions=<<set-next-input-tab>>>
|
<$keyboard key="((input-tab-right)) ((input-tab-left))" actions=<<input-actions>>>
|
||||||
<$keyboard key="((input-tab-left))" actions=<<set-previous-input-tab>>>
|
|
||||||
<$transclude $variable="keyboard-driven-input"
|
<$transclude $variable="keyboard-driven-input"
|
||||||
tiddler="$:/temp/advancedsearch/input"
|
tiddler="$:/temp/advancedsearch/input"
|
||||||
storeTitle="$:/temp/advancedsearch"
|
storeTitle="$:/temp/advancedsearch"
|
||||||
@@ -74,7 +81,6 @@ first-search-filter: [all[shadows]search<userInput>sort[title]limit[250]] -[[$:/
|
|||||||
inputAcceptVariantActions=<<input-accept-variant-actions>>
|
inputAcceptVariantActions=<<input-accept-variant-actions>>
|
||||||
filterMinLength={{$:/config/Search/MinLength}}/>
|
filterMinLength={{$:/config/Search/MinLength}}/>
|
||||||
</$keyboard>
|
</$keyboard>
|
||||||
</$keyboard>
|
|
||||||
 
|
 
|
||||||
<$reveal state="$:/temp/advancedsearch" type="nomatch" text="">
|
<$reveal state="$:/temp/advancedsearch" type="nomatch" text="">
|
||||||
<$button class="tc-btn-invisible">
|
<$button class="tc-btn-invisible">
|
||||||
|
|||||||
@@ -17,15 +17,24 @@ caption: {{$:/language/Search/Standard/Caption}}
|
|||||||
|
|
||||||
\procedure input-accept-variant-actions() <$list filter="[{$:/config/Search/NavigateOnEnter/enable}match[yes]]" emptyMessage="<$list filter='[<tiddler>get[text]!is[missing]] :else[<tiddler>get[text]is[shadow]]'><$list filter='[<tiddler>get[text]minlength[1]]'><$action-sendmessage $message='tm-edit-tiddler' $param={{{ [<tiddler>get[text]] }}}/></$list></$list>"><$list filter="[<tiddler>get[text]minlength[1]]"><$action-sendmessage $message="tm-edit-tiddler" $param={{{ [<tiddler>get[text]] }}}/></$list></$list>
|
\procedure input-accept-variant-actions() <$list filter="[{$:/config/Search/NavigateOnEnter/enable}match[yes]]" emptyMessage="<$list filter='[<tiddler>get[text]!is[missing]] :else[<tiddler>get[text]is[shadow]]'><$list filter='[<tiddler>get[text]minlength[1]]'><$action-sendmessage $message='tm-edit-tiddler' $param={{{ [<tiddler>get[text]] }}}/></$list></$list>"><$list filter="[<tiddler>get[text]minlength[1]]"><$action-sendmessage $message="tm-edit-tiddler" $param={{{ [<tiddler>get[text]] }}}/></$list></$list>
|
||||||
|
|
||||||
|
\procedure input-actions()
|
||||||
|
<%if [<event-code>match[ArrowRight]] :and[<modifier>match[alt-shift]] %>
|
||||||
|
<<next-search-tab>>
|
||||||
|
<%elseif [<event-code>match[ArrowLeft]] :and[<modifier>match[alt-shift]] %>
|
||||||
|
<<previous-search-tab>>
|
||||||
|
<%elseif [<event-key-descriptor>match[((input-tab-right))]] %>
|
||||||
|
<<set-next-input-tab>>
|
||||||
|
<%elseif [<event-key-descriptor>match[((input-tab-left))]] %>
|
||||||
|
<<set-previous-input-tab>>
|
||||||
|
<%endif%>
|
||||||
|
\end
|
||||||
|
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
|
|
||||||
<<lingo Standard/Hint>>
|
<<lingo Standard/Hint>>
|
||||||
|
|
||||||
<div class="tc-search">
|
<div class="tc-search">
|
||||||
<$keyboard key="((input-tab-right))" actions=<<set-next-input-tab>>>
|
<$keyboard key="((input-tab-right)) ((input-tab-left)) shift-alt-Right shift-alt-Left" actions=<<input-actions>>>
|
||||||
<$keyboard key="((input-tab-left))" actions=<<set-previous-input-tab>>>
|
|
||||||
<$keyboard key="shift-alt-Right" actions=<<next-search-tab>>>
|
|
||||||
<$keyboard key="shift-alt-Left" actions=<<previous-search-tab>>>
|
|
||||||
<$transclude $variable="keyboard-driven-input"
|
<$transclude $variable="keyboard-driven-input"
|
||||||
tiddler="$:/temp/advancedsearch/input"
|
tiddler="$:/temp/advancedsearch/input"
|
||||||
storeTitle="$:/temp/advancedsearch"
|
storeTitle="$:/temp/advancedsearch"
|
||||||
@@ -40,9 +49,6 @@ caption: {{$:/language/Search/Standard/Caption}}
|
|||||||
configTiddlerFilter="[[$:/state/advancedsearch/standard/currentTab]!is[missing]get[text]] :else[{$:/config/SearchResults/Default}]"
|
configTiddlerFilter="[[$:/state/advancedsearch/standard/currentTab]!is[missing]get[text]] :else[{$:/config/SearchResults/Default}]"
|
||||||
filterMinLength={{$:/config/Search/MinLength}}/>
|
filterMinLength={{$:/config/Search/MinLength}}/>
|
||||||
</$keyboard>
|
</$keyboard>
|
||||||
</$keyboard>
|
|
||||||
</$keyboard>
|
|
||||||
</$keyboard>
|
|
||||||
 
|
 
|
||||||
<$reveal state="$:/temp/advancedsearch" type="nomatch" text="">
|
<$reveal state="$:/temp/advancedsearch" type="nomatch" text="">
|
||||||
<$button class="tc-btn-invisible">
|
<$button class="tc-btn-invisible">
|
||||||
|
|||||||
@@ -52,13 +52,20 @@ first-search-filter: [is[system]search<userInput>sort[title]limit[250]] :except[
|
|||||||
</$list></$list>
|
</$list></$list>
|
||||||
\end
|
\end
|
||||||
|
|
||||||
|
\procedure input-actions()
|
||||||
|
<%if [<event-key-descriptor>match[((input-tab-right))]] %>
|
||||||
|
<<set-next-input-tab>>
|
||||||
|
<%elseif [<event-key-descriptor>match[((input-tab-left))]] %>
|
||||||
|
<<set-previous-input-tab>>
|
||||||
|
<%endif%>
|
||||||
|
\end
|
||||||
|
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
|
|
||||||
<<lingo System/Hint>>
|
<<lingo System/Hint>>
|
||||||
|
|
||||||
<div class="tc-search">
|
<div class="tc-search">
|
||||||
<$keyboard key="((input-tab-right))" actions=<<set-next-input-tab>>>
|
<$keyboard key="((input-tab-right)) ((input-tab-left))" actions=<<input-actions>>>
|
||||||
<$keyboard key="((input-tab-left))" actions=<<set-previous-input-tab>>>
|
|
||||||
<$transclude $variable="keyboard-driven-input"
|
<$transclude $variable="keyboard-driven-input"
|
||||||
tiddler="$:/temp/advancedsearch/input"
|
tiddler="$:/temp/advancedsearch/input"
|
||||||
storeTitle="$:/temp/advancedsearch"
|
storeTitle="$:/temp/advancedsearch"
|
||||||
@@ -73,7 +80,6 @@ first-search-filter: [is[system]search<userInput>sort[title]limit[250]] :except[
|
|||||||
inputAcceptVariantActions=<<input-accept-variant-actions>>
|
inputAcceptVariantActions=<<input-accept-variant-actions>>
|
||||||
filterMinLength={{$:/config/Search/MinLength}}/>
|
filterMinLength={{$:/config/Search/MinLength}}/>
|
||||||
</$keyboard>
|
</$keyboard>
|
||||||
</$keyboard>
|
|
||||||
 
|
 
|
||||||
<$reveal state="$:/temp/advancedsearch" type="nomatch" text="">
|
<$reveal state="$:/temp/advancedsearch" type="nomatch" text="">
|
||||||
<$button class="tc-btn-invisible">
|
<$button class="tc-btn-invisible">
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ code-body: yes
|
|||||||
title: $:/core/ui/AlertTemplate
|
title: $:/core/ui/AlertTemplate
|
||||||
|
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<div class="tc-alert">
|
<div class="tc-alert" role="alertdialog">
|
||||||
<div class="tc-alert-toolbar">
|
<div class="tc-alert-toolbar">
|
||||||
<$button class="tc-btn-invisible"><$action-deletetiddler $tiddler=<<currentTiddler>>/>{{$:/core/images/cancel-button}}</$button>
|
<$button class="tc-btn-invisible" aria-label={{$:/language/Buttons/Close/Caption}}><$action-deletetiddler $tiddler=<<currentTiddler>>/>{{$:/core/images/cancel-button}}</$button>
|
||||||
</div>
|
</div>
|
||||||
<div class="tc-alert-subtitle">
|
<div class="tc-alert-subtitle">
|
||||||
<$wikify name="format" text=<<lingo Tiddler/DateFormat>>>
|
<$wikify name="format" text=<<lingo Tiddler/DateFormat>>>
|
||||||
@@ -19,7 +19,7 @@ title: $:/core/ui/AlertTemplate
|
|||||||
</$reveal>
|
</$reveal>
|
||||||
</$wikify>
|
</$wikify>
|
||||||
</div>
|
</div>
|
||||||
<div class="tc-alert-body">
|
<div class="tc-alert-body" role="alert" aria-atomic="true">
|
||||||
|
|
||||||
<$transclude/>
|
<$transclude/>
|
||||||
|
|
||||||
|
|||||||
@@ -17,13 +17,11 @@ tags: $:/tags/EditTemplate
|
|||||||
<$let backgroundColor=<<colour>> >
|
<$let backgroundColor=<<colour>> >
|
||||||
<span class="tc-tag-label tc-tag-list-item tc-small-gap-right"
|
<span class="tc-tag-label tc-tag-list-item tc-small-gap-right"
|
||||||
data-tag-title=<<currentTiddler>>
|
data-tag-title=<<currentTiddler>>
|
||||||
style=`color:$(foregroundColor)$; fill:$(foregroundColor)$; background-color:$(backgroundColor)$;`
|
style=`color:$(foregroundColor)$; background-color:$(backgroundColor)$;`
|
||||||
>
|
>
|
||||||
<$transclude tiddler=<<icon>>/>
|
<$transclude tiddler=<<icon>>/>
|
||||||
<$view field="title" format="text"/>
|
<$view field="title" format="text"/>
|
||||||
<$button class="tc-btn-invisible tc-remove-tag-button"
|
<$button class="tc-btn-invisible tc-remove-tag-button">
|
||||||
style.fill=<<foregroundColor>>
|
|
||||||
>
|
|
||||||
<$action-listops $tiddler=<<saveTiddler>> $field=<<tagField>> $subfilter="-[{!!title}]"/>
|
<$action-listops $tiddler=<<saveTiddler>> $field=<<tagField>> $subfilter="-[{!!title}]"/>
|
||||||
{{$:/core/images/close-button}}
|
{{$:/core/images/close-button}}
|
||||||
</$button>
|
</$button>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ first-search-filter: [all[shadows+tiddlers]prefix[$:/language/Docs/Types/]sort[d
|
|||||||
<em class="tc-edit tc-small-gap-right"><<lingo Type/Prompt>></em>
|
<em class="tc-edit tc-small-gap-right"><<lingo Type/Prompt>></em>
|
||||||
<div class="tc-type-selector-dropdown-wrapper">
|
<div class="tc-type-selector-dropdown-wrapper">
|
||||||
<div class="tc-type-selector"><$fieldmangler>
|
<div class="tc-type-selector"><$fieldmangler>
|
||||||
<$transclude $variable="keyboard-driven-input" tiddler=<<currentTiddler>> storeTitle=<<typeInputTiddler>> refreshTitle=<<refreshTitle>> selectionStateTitle=<<typeSelectionTiddler>> field="type" tag="input" default="" placeholder={{$:/language/EditTemplate/Type/Placeholder}} focusPopup=<<qualify "$:/state/popup/type-dropdown">> class="tc-edit-typeeditor tc-edit-texteditor tc-popup-handle" tabindex={{$:/config/EditTabIndex}} focus={{{ [{$:/config/AutoFocus}match[type]then[true]] :else[[false]] }}} cancelPopups="yes" configTiddlerFilter="[[$:/core/ui/EditTemplate/type]]" inputCancelActions=<<input-cancel-actions>>/><$button popup=<<qualify "$:/state/popup/type-dropdown">> class="tc-btn-invisible tc-btn-dropdown tc-small-gap" tooltip={{$:/language/EditTemplate/Type/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Type/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button><$button message="tm-remove-field" param="type" class="tc-btn-invisible tc-btn-icon" tooltip={{$:/language/EditTemplate/Type/Delete/Hint}} aria-label={{$:/language/EditTemplate/Type/Delete/Caption}}>{{$:/core/images/delete-button}}<$action-deletetiddler $filter="[<typeInputTiddler>] [<storeTitle>] [<refreshTitle>] [<selectionStateTitle>]"/></$button>
|
<$transclude $variable="keyboard-driven-input" tiddler=<<currentTiddler>> storeTitle=<<typeInputTiddler>> refreshTitle=<<refreshTitle>> selectionStateTitle=<<typeSelectionTiddler>> field="type" tag="input" default="" placeholder={{$:/language/EditTemplate/Type/Placeholder}} focusPopup=<<qualify "$:/state/popup/type-dropdown">> class="tc-edit-typeeditor tc-edit-texteditor tc-popup-handle tc-keep-focus" tabindex={{$:/config/EditTabIndex}} focus={{{ [{$:/config/AutoFocus}match[type]then[true]] :else[[false]] }}} cancelPopups="yes" configTiddlerFilter="[[$:/core/ui/EditTemplate/type]]" inputCancelActions=<<input-cancel-actions>>/><$button popup=<<qualify "$:/state/popup/type-dropdown">> class="tc-btn-invisible tc-btn-dropdown tc-small-gap" tooltip={{$:/language/EditTemplate/Type/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Type/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button><$button message="tm-remove-field" param="type" class="tc-btn-invisible tc-btn-icon" tooltip={{$:/language/EditTemplate/Type/Delete/Hint}} aria-label={{$:/language/EditTemplate/Type/Delete/Caption}}>{{$:/core/images/delete-button}}<$action-deletetiddler $filter="[<typeInputTiddler>] [<storeTitle>] [<refreshTitle>] [<selectionStateTitle>]"/></$button>
|
||||||
</$fieldmangler></div>
|
</$fieldmangler></div>
|
||||||
|
|
||||||
<div class="tc-block-dropdown-wrapper">
|
<div class="tc-block-dropdown-wrapper">
|
||||||
|
|||||||
@@ -37,8 +37,6 @@ title: $:/core/ui/ImportListing
|
|||||||
|
|
||||||
\define suppressedField() suppressed-$(payloadTiddler)$
|
\define suppressedField() suppressed-$(payloadTiddler)$
|
||||||
|
|
||||||
\define newImportTitleTiddler() $:/temp/NewImportTitle-$(payloadTiddler)$
|
|
||||||
|
|
||||||
\define previewPopupState() $(currentTiddler)$!!popup-$(payloadTiddler)$
|
\define previewPopupState() $(currentTiddler)$!!popup-$(payloadTiddler)$
|
||||||
|
|
||||||
\define renameFieldState() $(currentTiddler)$!!state-rename-$(payloadTiddler)$
|
\define renameFieldState() $(currentTiddler)$!!state-rename-$(payloadTiddler)$
|
||||||
@@ -102,19 +100,7 @@ title: $:/core/ui/ImportListing
|
|||||||
<$reveal type="match" state=<<renameFieldState>> text="yes" tag="tr">
|
<$reveal type="match" state=<<renameFieldState>> text="yes" tag="tr">
|
||||||
<td colspan="3">
|
<td colspan="3">
|
||||||
<div class="tc-flex">
|
<div class="tc-flex">
|
||||||
<$edit-text tiddler=<<newImportTitleTiddler>> default={{{[subfilter<payloadTitleFilter>]}}} tag="input" class="tc-import-rename tc-flex-grow-1"/>
|
<$edit-text field=<<renameField>> default={{{[<payloadTiddler>]}}} tag="input" class="tc-import-rename tc-flex-grow-1"/>
|
||||||
<span class="tc-small-gap-left">
|
|
||||||
<$button class="tc-btn-invisible" set=<<renameFieldState>> setTo="no" tooltip={{{[<lingo-base>addsuffix[Listing/Rename/CancelRename]get[text]]}}}>
|
|
||||||
{{$:/core/images/close-button}}
|
|
||||||
<$action-deletetiddler $tiddler=<<newImportTitleTiddler>>/>
|
|
||||||
</$button>
|
|
||||||
<span class="tc-small-gap-right"/>
|
|
||||||
</span>
|
|
||||||
<$button class="tc-btn-invisible" set=<<renameFieldState>> setTo="no" tooltip={{{[<lingo-base>addsuffix[Listing/Rename/ConfirmRename]get[text]]}}}>
|
|
||||||
{{$:/core/images/done-button}}
|
|
||||||
<$action-setfield $field=<<renameField>> $value={{{[<newImportTitleTiddler>get[text]minlength[1]else<payloadTiddler>]}}} />
|
|
||||||
<$action-deletetiddler $tiddler=<<newImportTitleTiddler>>/>
|
|
||||||
</$button>
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</$reveal>
|
</$reveal>
|
||||||
|
|||||||
+13
-14
@@ -3,26 +3,25 @@ tags: $:/tags/ControlPanel/Appearance
|
|||||||
caption: {{$:/language/ControlPanel/LayoutSwitcher/Caption}}
|
caption: {{$:/language/ControlPanel/LayoutSwitcher/Caption}}
|
||||||
|
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
|
\function layout.filter() [all[current]field:title[$:/core/ui/PageTemplate]]
|
||||||
|
\function layout.empty.filter() [all[current]field:title{$:/layout}]
|
||||||
|
|
||||||
<$linkcatcher to="$:/layout">
|
<$linkcatcher to="$:/layout">
|
||||||
<div class="tc-chooser">
|
<div class="tc-chooser" role="listbox">
|
||||||
<$list filter="[all[tiddlers+shadows]tag[$:/tags/Layout]] [[$:/core/ui/PageTemplate]] +[!is[draft]sort[name]]">
|
<$list filter="[all[tiddlers+shadows]tag[$:/tags/Layout]] [[$:/core/ui/PageTemplate]] +[!is[draft]sort[name]]">
|
||||||
<$list
|
<$list filter="[{$:/layout}!has[text]]" variable="ignore">
|
||||||
filter="[{$:/layout}!has[text]]"
|
<$list-empty>
|
||||||
variable="ignore"
|
<div class={{{ [layout.empty.filter[]then[tc-chooser-item tc-chosen]else[tc-chooser-item]] }}}>
|
||||||
emptyMessage="""\whitespace trim
|
<$link to={{!!title}} role="option" aria-selected={{{ [layout.empty.filter[]then[true]else[false]] }}}>
|
||||||
<$set name="cls" filter="[all[current]field:title{$:/layout}]" value="tc-chooser-item tc-chosen" emptyValue="tc-chooser-item">
|
|
||||||
<div class=<<cls>>>
|
|
||||||
<$link to={{!!title}}>
|
|
||||||
''<$transclude tiddler={{{ [<currentTiddler>get[icon]] }}}/><$transclude field="name"/>'' - <$transclude field="description"/>
|
''<$transclude tiddler={{{ [<currentTiddler>get[icon]] }}}/><$transclude field="name"/>'' - <$transclude field="description"/>
|
||||||
</$link></div></$set>
|
</$link>
|
||||||
""">
|
</div>
|
||||||
<$set name="cls" filter="[all[current]field:title[$:/core/ui/PageTemplate]]" value="tc-chooser-item tc-chosen" emptyValue="tc-chooser-item">
|
</$list-empty>
|
||||||
<div class=<<cls>>>
|
<div class={{{ [layout.filter[]then[tc-chooser-item tc-chosen]else[tc-chooser-item]] }}}>
|
||||||
<$link to={{!!title}}>
|
<$link to={{!!title}} role="option" aria-selected={{{ [layout.filter[]then[true]else[false]] }}}>
|
||||||
''<$transclude tiddler={{{ [<currentTiddler>get[icon]] }}}/><$transclude field="name"/>'' - <$transclude field="description"/>
|
''<$transclude tiddler={{{ [<currentTiddler>get[icon]] }}}/><$transclude field="name"/>'' - <$transclude field="description"/>
|
||||||
</$link>
|
</$link>
|
||||||
</div>
|
</div>
|
||||||
</$set>
|
|
||||||
</$list>
|
</$list>
|
||||||
</$list>
|
</$list>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
title: $:/core/ui/PageTemplate/alerts
|
title: $:/core/ui/PageTemplate/alerts
|
||||||
tags: $:/tags/PageTemplate
|
tags: $:/tags/PageTemplate
|
||||||
|
|
||||||
<div class="tc-alerts">
|
<div class="tc-alerts" role="region" aria-label="Alerts">
|
||||||
|
|
||||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Alert]!has[draft.of]]" template="$:/core/ui/AlertTemplate" storyview="pop"/>
|
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Alert]!is[draft]]" template="$:/core/ui/AlertTemplate" storyview="pop"/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -46,13 +46,21 @@ tags: $:/tags/SideBarSegment
|
|||||||
|
|
||||||
\procedure advanced-search-actions() <$action-setfield $tiddler="$:/temp/advancedsearch" text={{$:/temp/search/input}}/><$action-setfield $tiddler="$:/temp/advancedsearch/input" text={{$:/temp/search/input}}/><<delete-state-tiddlers>><$action-navigate $to="$:/AdvancedSearch"/><$action-setfield $tiddler="$:/temp/advancedsearch/refresh" text="yes"/><$action-sendmessage $message="tm-focus-selector" $param="""[data-tiddler-title="$:/AdvancedSearch"] .tc-search input""" preventScroll="true"/><$action-deletetiddler $filter="$:/temp/search $:/temp/search/input $:/temp/search/refresh [<searchListState>]"/>
|
\procedure advanced-search-actions() <$action-setfield $tiddler="$:/temp/advancedsearch" text={{$:/temp/search/input}}/><$action-setfield $tiddler="$:/temp/advancedsearch/input" text={{$:/temp/search/input}}/><<delete-state-tiddlers>><$action-navigate $to="$:/AdvancedSearch"/><$action-setfield $tiddler="$:/temp/advancedsearch/refresh" text="yes"/><$action-sendmessage $message="tm-focus-selector" $param="""[data-tiddler-title="$:/AdvancedSearch"] .tc-search input""" preventScroll="true"/><$action-deletetiddler $filter="$:/temp/search $:/temp/search/input $:/temp/search/refresh [<searchListState>]"/>
|
||||||
|
|
||||||
|
\procedure input-actions()
|
||||||
|
<%if [<event-key-descriptor>match[((input-tab-right))]] %>
|
||||||
|
<<set-next-input-tab>>
|
||||||
|
<%elseif [<event-key-descriptor>match[((input-tab-left))]] %>
|
||||||
|
<<set-previous-input-tab>>
|
||||||
|
<%elseif [<event-key-descriptor>match[((advanced-search-sidebar))]] %>
|
||||||
|
<<advanced-search-actions>>
|
||||||
|
<%endif%>
|
||||||
|
\end
|
||||||
|
|
||||||
<div class="tc-sidebar-lists tc-sidebar-search">
|
<div class="tc-sidebar-lists tc-sidebar-search">
|
||||||
|
|
||||||
<$vars editTiddler="$:/temp/search" searchTiddler="$:/temp/search/input" searchListState=<<qualify "$:/state/search-list/selected-item">>>
|
<$vars editTiddler="$:/temp/search" searchTiddler="$:/temp/search/input" searchListState=<<qualify "$:/state/search-list/selected-item">>>
|
||||||
<div class="tc-search">
|
<div class="tc-search">
|
||||||
<$keyboard key="((input-tab-right))" actions=<<set-next-input-tab>>>
|
<$keyboard key="((input-tab-right)) ((input-tab-left)) ((advanced-search-sidebar))" actions=<<input-actions>>>
|
||||||
<$keyboard key="((input-tab-left))" actions=<<set-previous-input-tab>>>
|
|
||||||
<$keyboard key="((advanced-search-sidebar))" actions=<<advanced-search-actions>>>
|
|
||||||
<form class="tc-form-inline">
|
<form class="tc-form-inline">
|
||||||
<$transclude $variable="keyboard-driven-input" tiddler=<<editTiddler>> storeTitle=<<searchTiddler>>
|
<$transclude $variable="keyboard-driven-input" tiddler=<<editTiddler>> storeTitle=<<searchTiddler>>
|
||||||
selectionStateTitle=<<searchListState>> refreshTitle="$:/temp/search/refresh" type="search"
|
selectionStateTitle=<<searchListState>> refreshTitle="$:/temp/search/refresh" type="search"
|
||||||
@@ -62,8 +70,6 @@ tags: $:/tags/SideBarSegment
|
|||||||
configTiddlerFilter="[[$:/state/search/currentTab]!is[missing]get[text]] :else[{$:/config/SearchResults/Default}]"/>
|
configTiddlerFilter="[[$:/state/search/currentTab]!is[missing]get[text]] :else[{$:/config/SearchResults/Default}]"/>
|
||||||
</form>
|
</form>
|
||||||
</$keyboard>
|
</$keyboard>
|
||||||
</$keyboard>
|
|
||||||
</$keyboard>
|
|
||||||
<$reveal state=<<searchTiddler>> type="nomatch" text="">
|
<$reveal state=<<searchTiddler>> type="nomatch" text="">
|
||||||
<$button tooltip={{$:/language/Buttons/AdvancedSearch/Hint}} aria-label={{$:/language/Buttons/AdvancedSearch/Caption}} class="tc-btn-invisible">
|
<$button tooltip={{$:/language/Buttons/AdvancedSearch/Hint}} aria-label={{$:/language/Buttons/AdvancedSearch/Caption}} class="tc-btn-invisible">
|
||||||
<<advanced-search-actions>>
|
<<advanced-search-actions>>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ title: $:/core/ui/ViewTemplate/title
|
|||||||
tags: $:/tags/ViewTemplate
|
tags: $:/tags/ViewTemplate
|
||||||
|
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
\define title-styles() fill:$(foregroundColor)$;
|
\define title-styles() color:$(foregroundColor)$;
|
||||||
|
|
||||||
<div class="tc-tiddler-title tc-clearfix">
|
<div class="tc-tiddler-title tc-clearfix">
|
||||||
<div class="tc-titlebar">
|
<div class="tc-titlebar">
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
title: $:/config/TiddlerInfo/Mode
|
title: $:/config/TiddlerInfo/Mode
|
||||||
text: popup
|
text: sticky
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
title: $:/snippets/languageswitcher
|
title: $:/snippets/languageswitcher
|
||||||
|
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
|
\function language.filter() [all[current]field:title{$:/language}]
|
||||||
|
|
||||||
<$linkcatcher to="$:/language">
|
<$linkcatcher to="$:/language">
|
||||||
<div class="tc-chooser tc-language-chooser">
|
<div class="tc-chooser tc-language-chooser" role="listbox">
|
||||||
<$list filter="[[$:/languages/en-GB]] [plugin-type[language]sort[description]]">
|
<$list filter="[[$:/languages/en-GB]] [plugin-type[language]sort[description]]">
|
||||||
<$set name="cls" filter="[all[current]field:title{$:/language}]" value="tc-chooser-item tc-chosen" emptyValue="tc-chooser-item">
|
<div class={{{ [language.filter[]then[tc-chooser-item tc-chosen]else[tc-chooser-item]] }}} lang={{!!name}}>
|
||||||
<div class=<<cls>> lang={{!!name}}>
|
<$link role="option" aria-selected={{{ [language.filter[]then[true]else[false]] }}}>
|
||||||
<$link>
|
|
||||||
<$view field="description">
|
<$view field="description">
|
||||||
<$view field="name">
|
<$view field="name">
|
||||||
<$view field="title"/>
|
<$view field="title"/>
|
||||||
@@ -14,7 +15,6 @@ title: $:/snippets/languageswitcher
|
|||||||
</$view>
|
</$view>
|
||||||
</$link>
|
</$link>
|
||||||
</div>
|
</div>
|
||||||
</$set>
|
|
||||||
</$list>
|
</$list>
|
||||||
</div>
|
</div>
|
||||||
</$linkcatcher>
|
</$linkcatcher>
|
||||||
@@ -120,11 +120,21 @@ tags: $:/tags/Macro
|
|||||||
|
|
||||||
\procedure keyboard-driven-input(tiddler,storeTitle,field:"text",index:"",tag:"input",type,focus:"",inputAcceptActions,inputAcceptVariantActions,inputCancelActions,placeholder:"",default:"",class,focusPopup,rows,minHeight,tabindex,size,autoHeight,filterMinLength:"0",refreshTitle,selectionStateTitle,cancelPopups:"",configTiddlerFilter,firstSearchFilterField:"first-search-filter",secondSearchFilterField:"second-search-filter")
|
\procedure keyboard-driven-input(tiddler,storeTitle,field:"text",index:"",tag:"input",type,focus:"",inputAcceptActions,inputAcceptVariantActions,inputCancelActions,placeholder:"",default:"",class,focusPopup,rows,minHeight,tabindex,size,autoHeight,filterMinLength:"0",refreshTitle,selectionStateTitle,cancelPopups:"",configTiddlerFilter,firstSearchFilterField:"first-search-filter",secondSearchFilterField:"second-search-filter")
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<$keyboard key="((input-accept))" actions=<<inputAcceptActions>>>
|
\procedure keyboard-driven-input-actions()
|
||||||
<$keyboard key="((input-accept-variant))" actions=<<inputAcceptVariantActions>>>
|
<%if [<event-key-descriptor>match[((input-accept))]] %>
|
||||||
<$keyboard key="((input-up))" actions=<<input-next-actions-before>>>
|
<<inputAcceptActions>>
|
||||||
<$keyboard key="((input-down))" actions=<<input-next-actions-after>>>
|
<%elseif [<event-key-descriptor>match[((input-accept-variant))]] %>
|
||||||
<$keyboard key="((input-cancel))" actions=<<inputCancelActions>>>
|
<<inputAcceptVariantActions>>
|
||||||
|
<%elseif [<event-key-descriptor>match[((input-up))]] %>
|
||||||
|
<<input-next-actions-before>>
|
||||||
|
<%elseif [<event-key-descriptor>match[((input-down))]] %>
|
||||||
|
<<input-next-actions-after>>
|
||||||
|
<%elseif [<event-key-descriptor>match[((input-cancel))]] %>
|
||||||
|
<<inputCancelActions>>
|
||||||
|
<%endif%>
|
||||||
|
\end keyboard-driven-input-actions
|
||||||
|
|
||||||
|
<$keyboard key="((input-accept)) ((input-accept-variant)) ((input-up)) ((input-down)) ((input-cancel))" actions=<<keyboard-driven-input-actions>>>
|
||||||
<$edit-text
|
<$edit-text
|
||||||
tiddler=<<tiddler>> field=<<field>> index=<<index>>
|
tiddler=<<tiddler>> field=<<field>> index=<<index>>
|
||||||
inputActions=<<keyboard-input-actions>> tag=<<tag>> class=<<class>>
|
inputActions=<<keyboard-input-actions>> tag=<<tag>> class=<<class>>
|
||||||
@@ -134,8 +144,4 @@ tags: $:/tags/Macro
|
|||||||
refreshTitle=<<refreshTitle>> cancelPopups=<<cancelPopups>>
|
refreshTitle=<<refreshTitle>> cancelPopups=<<cancelPopups>>
|
||||||
/>
|
/>
|
||||||
</$keyboard>
|
</$keyboard>
|
||||||
</$keyboard>
|
\end keyboard-driven-input
|
||||||
</$keyboard>
|
|
||||||
</$keyboard>
|
|
||||||
</$keyboard>
|
|
||||||
\end
|
|
||||||
|
|||||||
@@ -24,10 +24,14 @@ tags: $:/tags/Macro
|
|||||||
|
|
||||||
\define list-links-draggable(tiddler,field:"list",emptyMessage,type:"ul",subtype:"li",class:"",itemTemplate)
|
\define list-links-draggable(tiddler,field:"list",emptyMessage,type:"ul",subtype:"li",class:"",itemTemplate)
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
|
<$set name="_tiddler" value="""$tiddler$""" emptyValue=<<currentTiddler>> >
|
||||||
|
<$let field-reference={{{ [<_tiddler>] "!!" [[$field$]] +[join[]] }}}
|
||||||
|
targetTiddler=<<_tiddler>>
|
||||||
|
targetField="""$field$"""
|
||||||
|
>
|
||||||
<span class="tc-links-draggable-list">
|
<span class="tc-links-draggable-list">
|
||||||
<$vars targetTiddler="""$tiddler$""" targetField="""$field$""">
|
|
||||||
<$genesis $type=<<__type__>> class="$class$">
|
<$genesis $type=<<__type__>> class="$class$">
|
||||||
<$list filter="[list[$tiddler$!!$field$]]" emptyMessage=<<__emptyMessage__>>>
|
<$list filter="[list<field-reference>]" emptyMessage=<<__emptyMessage__>>>
|
||||||
<$droppable
|
<$droppable
|
||||||
actions=<<list-links-draggable-drop-actions>>
|
actions=<<list-links-draggable-drop-actions>>
|
||||||
tag="""$subtype$"""
|
tag="""$subtype$"""
|
||||||
@@ -60,8 +64,9 @@ tags: $:/tags/Macro
|
|||||||
</$droppable>
|
</$droppable>
|
||||||
</$tiddler>
|
</$tiddler>
|
||||||
</$genesis>
|
</$genesis>
|
||||||
</$vars>
|
|
||||||
</span>
|
</span>
|
||||||
|
</$let>
|
||||||
|
</$set>
|
||||||
\end
|
\end
|
||||||
|
|
||||||
\define list-tagged-draggable-drop-actions(tag)
|
\define list-tagged-draggable-drop-actions(tag)
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ tags: $:/tags/Macro
|
|||||||
|
|
||||||
\define tag-pill-styles()
|
\define tag-pill-styles()
|
||||||
background-color:$(backgroundColor)$;
|
background-color:$(backgroundColor)$;
|
||||||
fill:$(foregroundColor)$;
|
|
||||||
color:$(foregroundColor)$;
|
color:$(foregroundColor)$;
|
||||||
\end
|
\end
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ tags: $:/tags/Macro
|
|||||||
style="width:$width$px;height:$height$px;background-color:$background-color$;"
|
style="width:$width$px;height:$height$px;background-color:$background-color$;"
|
||||||
></$reveal></div><div
|
></$reveal></div><div
|
||||||
class="tc-thumbnail-icon"
|
class="tc-thumbnail-icon"
|
||||||
style="fill:$color$;color:$color$;"
|
style="color:$color$;"
|
||||||
>$icon$</div><div class="tc-thumbnail-caption">$caption$</div></div></$link>
|
>$icon$</div><div class="tc-thumbnail-caption">$caption$</div></div></$link>
|
||||||
\end
|
\end
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
title: $:/snippets/themeswitcher
|
title: $:/snippets/themeswitcher
|
||||||
|
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
|
\function theme.filter() [all[current]field:title{$:/theme}] [[$:/theme]!has[text]addsuffix[s/tiddlywiki/vanilla]field:title<currentTiddler>] +[limit[1]]
|
||||||
|
|
||||||
<$linkcatcher to="$:/theme">
|
<$linkcatcher to="$:/theme">
|
||||||
<div class="tc-chooser">
|
<div class="tc-chooser" role="listbox">
|
||||||
<$list filter="[plugin-type[theme]sort[title]]">
|
<$list filter="[plugin-type[theme]sort[title]]">
|
||||||
<$set name="cls" filter="[all[current]field:title{$:/theme}] [[$:/theme]!has[text]addsuffix[s/tiddlywiki/vanilla]field:title<currentTiddler>] +[limit[1]]" value="tc-chooser-item tc-chosen" emptyValue="tc-chooser-item">
|
<div class={{{ [theme.filter[]then[tc-chooser-item tc-chosen]else[tc-chooser-item]] }}}>
|
||||||
<div class=<<cls>>><$link to={{!!title}}>
|
<$link to={{!!title}} role="option" aria-selected={{{ [theme.filter[]then[true]else[false]] }}}>
|
||||||
''<$view field="name" format="text"/>''
|
''<$view field="name" format="text"/>''
|
||||||
 
|
 
|
||||||
<$view field="description" format="text"/>
|
<$view field="description" format="text"/>
|
||||||
</$link>
|
</$link>
|
||||||
</div>
|
</div>
|
||||||
</$set>
|
|
||||||
</$list>
|
</$list>
|
||||||
</div>
|
</div>
|
||||||
</$linkcatcher>
|
</$linkcatcher>
|
||||||
@@ -4,13 +4,14 @@ title: $:/snippets/viewswitcher
|
|||||||
$:/core/images/storyview-$(storyview)$
|
$:/core/images/storyview-$(storyview)$
|
||||||
\end
|
\end
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
|
\function view.filter() [<storyview>prefix{$:/view}]
|
||||||
|
|
||||||
<$linkcatcher to="$:/view">
|
<$linkcatcher to="$:/view">
|
||||||
<div class="tc-chooser tc-viewswitcher">
|
<div class="tc-chooser tc-viewswitcher" role="listbox">
|
||||||
<$list filter="[storyviews[]]" variable="storyview">
|
<$list filter="[storyviews[]]" variable="storyview">
|
||||||
<$set name="cls" filter="[<storyview>prefix{$:/view}]" value="tc-chooser-item tc-chosen" emptyValue="tc-chooser-item"><div class=<<cls>>>
|
<div class={{{ [view.filter[]then[tc-chooser-item tc-chosen]else[tc-chooser-item]] }}}>
|
||||||
<$button tag="a" class="tc-tiddlylink tc-btn-invisible" to=<<storyview>>><$transclude tiddler=<<icon>>/><$text text=<<storyview>>/></$button>
|
<$button tag="a" class="tc-tiddlylink tc-btn-invisible" role="option" to=<<storyview>> aria-selected={{{ [view.filter[]then[true]else[false]] }}}><$transclude tiddler=<<icon>>/><$text text=<<storyview>>/></$button>
|
||||||
</div>
|
</div>
|
||||||
</$set>
|
|
||||||
</$list>
|
</$list>
|
||||||
</div>
|
</div>
|
||||||
</$linkcatcher>
|
</$linkcatcher>
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
title: CloudData
|
|
||||||
type: application/json
|
|
||||||
|
|
||||||
[
|
|
||||||
{"text": "Tokyo/Yokohama", "size": 33.200},
|
|
||||||
{"text": "New York Metro", "size": 17.800},
|
|
||||||
{"text": "Sao Paulo", "size": 17.700},
|
|
||||||
{"text": "Seoul/Incheon", "size": 17.500},
|
|
||||||
{"text": "Mexico City", "size": 17.400},
|
|
||||||
{"text": "Osaka/Kobe/Kyoto", "size": 16.425},
|
|
||||||
{"text": "Manila", "size": 14.750},
|
|
||||||
{"text": "Mumbai", "size": 14.350},
|
|
||||||
{"text": "Delhi", "size": 14.300},
|
|
||||||
{"text": "Jakarta", "size": 14.250},
|
|
||||||
{"text": "Lagos", "size": 13.400},
|
|
||||||
{"text": "Kolkata", "size": 12.700},
|
|
||||||
{"text": "Cairo", "size": 12.200},
|
|
||||||
{"text": "Los Angeles", "size": 11.789},
|
|
||||||
{"text": "Buenos Aires", "size": 11.200},
|
|
||||||
{"text": "Rio de Janeiro", "size": 10.800},
|
|
||||||
{"text": "Moscow", "size": 10.500},
|
|
||||||
{"text": "Shanghai", "size": 10.000},
|
|
||||||
{"text": "Karachi", "size": 9.800},
|
|
||||||
{"text": "Paris", "size": 9.645},
|
|
||||||
{"text": "Istanbul", "size": 9.000},
|
|
||||||
{"text": "Nagoya", "size": 9.000},
|
|
||||||
{"text": "Beijing", "size": 8.614},
|
|
||||||
{"text": "Chicago", "size": 8.308},
|
|
||||||
{"text": "London", "size": 8.278},
|
|
||||||
{"text": "Shenzhen", "size": 8.000},
|
|
||||||
{"text": "Essen/Dusseldorf", "size": 7.350},
|
|
||||||
{"text": "Tehran", "size": 7.250},
|
|
||||||
{"text": "Bogota", "size": 7.000},
|
|
||||||
{"text": "Lima", "size": 7.000},
|
|
||||||
{"text": "Bangkok", "size": 6.500},
|
|
||||||
{"text": "Johannesburg/East Rand", "size": 6.000},
|
|
||||||
{"text": "Chennai", "size": 5.950},
|
|
||||||
{"text": "Taipei", "size": 5.700},
|
|
||||||
{"text": "Baghdad", "size": 5.500},
|
|
||||||
{"text": "Santiago", "size": 5.425},
|
|
||||||
{"text": "Bangalore", "size": 5.400},
|
|
||||||
{"text": "Hyderabad", "size": 5.300},
|
|
||||||
{"text": "St Petersburg", "size": 5.300}
|
|
||||||
]
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user