1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2026-01-23 19:34:39 +00:00

Compare commits

..

5 Commits

Author SHA1 Message Date
Jeremy Ruston
66b0e4b643 Restructure syncer to use a single state machine 2023-11-17 14:01:02 +00:00
Jeremy Ruston
afd7155a9d Typo 2023-11-10 12:18:34 +00:00
Jeremy Ruston
ad98853b7e A tiny bit more logging 2023-11-10 10:29:42 +00:00
Jeremy Ruston
646620fc42 Log task choosing 2023-11-09 17:57:22 +00:00
Jeremy Ruston
d77eee291c Initial commit 2023-11-09 17:28:23 +00:00
1414 changed files with 5227 additions and 39441 deletions

View File

@@ -231,10 +231,7 @@ rules:
prefer-spread: 'off' prefer-spread: 'off'
prefer-template: 'off' prefer-template: 'off'
quote-props: 'off' quote-props: 'off'
quotes: quotes: 'off'
- error
- double
- avoidEscape: true
radix: 'off' radix: 'off'
require-atomic-updates: error require-atomic-updates: error
require-await: error require-await: error

View File

@@ -21,7 +21,7 @@ body:
attributes: attributes:
label: To Reproduce label: To Reproduce
description: "Steps to reproduce the behavior:" description: "Steps to reproduce the behavior:"
placeholder: | value: |
1. Go to '...' 1. Go to '...'
2. Click on '....' 2. Click on '....'
3. Scroll down to '....' 3. Scroll down to '....'
@@ -41,7 +41,7 @@ body:
attributes: attributes:
label: TiddlyWiki Configuration label: TiddlyWiki Configuration
description: please complete the following information description: please complete the following information
placeholder: | value: |
- Version [e.g. v5.1.24] - Version [e.g. v5.1.24]
- Saving mechanism [e.g. Node.js, TiddlyDesktop, TiddlyHost etc] - Saving mechanism [e.g. Node.js, TiddlyDesktop, TiddlyHost etc]
- Plugins installed [e.g. Freelinks, TiddlyMap] - Plugins installed [e.g. Freelinks, TiddlyMap]

View File

@@ -1,7 +1,7 @@
blank_issues_enabled: false blank_issues_enabled: false
contact_links: contact_links:
- name: Discuss feature request - name: Discuss feature request
url: https://github.com/TiddlyWiki/TiddlyWiki5/discussions url: https://github.com/Jermolene/TiddlyWiki5/discussions
about: Open new discussion about new feature about: Open new discussion about new feature
- name: Talk.Tiddlywiki Forum - name: Talk.Tiddlywiki Forum
url: https://talk.tiddlywiki.org url: https://talk.tiddlywiki.org

View File

@@ -60,7 +60,6 @@ jobs:
TW5_BUILD_TIDDLYWIKI: "./node_modules/tiddlywiki/tiddlywiki.js" TW5_BUILD_TIDDLYWIKI: "./node_modules/tiddlywiki/tiddlywiki.js"
TW5_BUILD_MAIN_EDITION: "./editions/tw5.com" TW5_BUILD_MAIN_EDITION: "./editions/tw5.com"
TW5_BUILD_OUTPUT: "./output" TW5_BUILD_OUTPUT: "./output"
TW5_BUILD_ARCHIVE: "./output"
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: actions/setup-node@v1 - uses: actions/setup-node@v1

View File

@@ -1,30 +0,0 @@
name: Check CLA Signature
on:
pull_request_target:
types:
- opened
- reopened
paths-ignore:
- 'licenses/cla-individual.md'
jobs:
check_cla:
runs-on: ubuntu-latest
permissions:
pull-requests: write
if: ${{ (github.event.pull_request.user.login != github.repository_owner) }}
steps:
- run: |
if ! curl -s https://raw.githubusercontent.com/Jermolene/TiddlyWiki5/tiddlywiki-com/licenses/cla-individual.md | grep -o "@$USER,"; then
echo "CLA not signed"
gh pr comment "$NUMBER" -b "@$USER It appears that this is your first contribution to the project, welcome.
With apologies for the bureaucracy, please could you prepare a separate PR to the 'tiddlywiki-com' branch with your signature for the Contributor License Agreement (see [contributing.md](https://github.com/TiddlyWiki/TiddlyWiki5/blob/master/contributing.md))."
else
echo "CLA already signed"
gh pr comment "$NUMBER" -b "Confirmed: **$USER** has already signed the Contributor License Agreement (see [contributing.md](https://github.com/TiddlyWiki/TiddlyWiki5/blob/master/contributing.md))"
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
NUMBER: ${{ github.event.pull_request.number }}
USER: ${{ github.actor }}

View File

@@ -1,70 +0,0 @@
name: CLA Signed
on:
pull_request_target:
types:
- opened
- closed
paths:
- 'licenses/cla-individual.md'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
NUMBER: ${{ github.event.pull_request.number }}
AUTHOR: ${{ github.event.pull_request.user.login }}
jobs:
# check if PRs updating the CLA are targetting the tiddlywiki-com branch
check-signature-branch:
if: (github.event.pull_request.merged != true) && (github.event.pull_request.user.login != github.repository_owner)
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- run: |
if ! $BRANCH == "tiddlywiki-com"; then
echo "This CLA signature targets the wrong branch"
gh pr comment "$NUMBER" -b "@$AUTHOR Signatures to the CLA must target the 'tiddlywiki-com' branch."
fi
env:
BRANCH: ${{ github.event.pull_request.base.ref }}
# leave a comment on each open PR by a given author when their signature is added to the CLA
cla-signed:
if: (github.event.pull_request.merged == true) && (github.event.pull_request.user.login != github.repository_owner)
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- name: List open PRs by user
id: list-prs
uses: actions/github-script@v6
with:
result-encoding: string
script: |
const owner = context.repo.owner,
repo = context.repo.repo,
author = context.payload.pull_request.user.login;
const { data: pullRequests } = await github.rest.pulls.list({
owner: owner,
repo: repo,
state: 'open',
sort: 'created',
direction: 'desc',
per_page: 100
});
const userPullRequests = pullRequests.filter(pr => pr.user.login === author),
prNumbers = userPullRequests.map(pr => pr.number).join(',');
console.log(`Open pull requests by ${author}:${prNumbers}`);
return prNumbers;
- name: Comment open PRs by the same author
run: |
prs=($(echo ${{ steps.list-prs.outputs.result }} | tr "," "\n"))
for number in "${prs[@]}"
do
gh pr comment "$number" -b "**$AUTHOR** has signed the Contributor License Agreement (see [contributing.md](https://github.com/TiddlyWiki/TiddlyWiki5/blob/master/contributing.md))"
done

1
.gitignore vendored
View File

@@ -8,4 +8,3 @@ node_modules/
/test-results/ /test-results/
/playwright-report/ /playwright-report/
/playwright/.cache/ /playwright/.cache/
$__StoryList.tid

View File

@@ -5,7 +5,7 @@
# Default to the current version number for building the plugin library # Default to the current version number for building the plugin library
if [ -z "$TW5_BUILD_VERSION" ]; then if [ -z "$TW5_BUILD_VERSION" ]; then
TW5_BUILD_VERSION=v5.3.6 TW5_BUILD_VERSION=v5.3.2
fi fi
echo "Using TW5_BUILD_VERSION as [$TW5_BUILD_VERSION]" echo "Using TW5_BUILD_VERSION as [$TW5_BUILD_VERSION]"
@@ -84,27 +84,10 @@ echo -e -n "title: $:/build\ncommit: $TW5_BUILD_COMMIT\n\n$TW5_BUILD_DETAILS\n"
###################################################### ######################################################
# #
# Core distributions # Core distribution
# #
###################################################### ######################################################
# Conditionally build archive if $TW5_BUILD_ARCHIVE variable is set, otherwise do nothing
#
# /archive/Empty-TiddlyWiki-<version>.html Empty archived version
# /archive/TiddlyWiki-<version>.html Full archived version
if [ -n "$TW5_BUILD_ARCHIVE" ]; then
node $TW5_BUILD_TIDDLYWIKI \
$TW5_BUILD_MAIN_EDITION \
--verbose \
--version \
--load $TW5_BUILD_OUTPUT/build.tid \
--output $TW5_BUILD_ARCHIVE \
--build archive \
|| exit 1
fi
# /index.html Main site # /index.html Main site
# /favicon.ico Favicon for main site # /favicon.ico Favicon for main site
# /static.html Static rendering of default tiddlers # /static.html Static rendering of default tiddlers
@@ -112,7 +95,6 @@ fi
# /static/* Static single tiddlers # /static/* Static single tiddlers
# /static/static.css Static stylesheet # /static/static.css Static stylesheet
# /static/favicon.ico Favicon for static pages # /static/favicon.ico Favicon for static pages
node $TW5_BUILD_TIDDLYWIKI \ node $TW5_BUILD_TIDDLYWIKI \
$TW5_BUILD_MAIN_EDITION \ $TW5_BUILD_MAIN_EDITION \
--verbose \ --verbose \
@@ -156,28 +138,6 @@ node $TW5_BUILD_TIDDLYWIKI \
--build index favicon static \ --build index favicon static \
|| exit 1 || exit 1
# /tour.html tour edition
node $TW5_BUILD_TIDDLYWIKI \
./editions/tour \
--verbose \
--output $TW5_BUILD_OUTPUT \
--rendertiddler $:/core/save/all tour.html text/plain \
|| exit 1
# /dev/index.html Developer docs
# /dev/favicon.ico Favicon for dev site
# /dev/static.html Static rendering of default tiddlers
# /dev/alltiddlers.html Static rendering of all tiddlers
# /dev/static/* Static single tiddlers
# /dev/static/static.css Static stylesheet
node $TW5_BUILD_TIDDLYWIKI \
./editions/dev \
--verbose \
--load $TW5_BUILD_OUTPUT/build.tid \
--output $TW5_BUILD_OUTPUT/dev \
--build index favicon static \
|| exit 1
# /share.html Custom edition for sharing via the URL # /share.html Custom edition for sharing via the URL
node $TW5_BUILD_TIDDLYWIKI \ node $TW5_BUILD_TIDDLYWIKI \
./editions/share \ ./editions/share \
@@ -393,17 +353,6 @@ node $TW5_BUILD_TIDDLYWIKI \
--rendertiddler $:/core/save/empty plugins/tiddlywiki/highlight/empty.html text/plain \ --rendertiddler $:/core/save/empty plugins/tiddlywiki/highlight/empty.html text/plain \
|| exit 1 || exit 1
# /plugins/tiddlywiki/geospatial/index.html Demo wiki with geospatial plugin
# /plugins/tiddlywiki/geospatial/empty.html Empty wiki with geospatial plugin
node $TW5_BUILD_TIDDLYWIKI \
./editions/geospatialdemo \
--verbose \
--load $TW5_BUILD_OUTPUT/build.tid \
--output $TW5_BUILD_OUTPUT \
--rendertiddler $:/core/save/all plugins/tiddlywiki/geospatial/index.html text/plain \
--rendertiddler $:/core/save/empty plugins/tiddlywiki/geospatial/empty.html text/plain \
|| exit 1
###################################################### ######################################################
# #
# Language editions # Language editions

View File

@@ -7,4 +7,4 @@ npm --force install tiddlywiki || exit 1
# Pull existing GitHub pages content # Pull existing GitHub pages content
git clone --depth=1 --branch=master "https://github.com/TiddlyWiki/tiddlywiki.com-gh-pages.git" output git clone --depth=1 --branch=master "https://github.com/Jermolene/jermolene.github.io.git" output

View File

@@ -10,6 +10,6 @@ git config --global user.email "actions@github.com"
git config --global user.name "GitHub Actions" git config --global user.name "GitHub Actions"
git add -A . git add -A .
git commit --message "GitHub build: $GITHUB_RUN_NUMBER of $TW5_BUILD_BRANCH ($(date +'%F %T %Z'))" git commit --message "GitHub build: $GITHUB_RUN_NUMBER of $TW5_BUILD_BRANCH ($(date +'%F %T %Z'))"
git remote add deploy "https://$GH_TOKEN@github.com/TiddlyWiki/tiddlywiki.com-gh-pages.git" &>/dev/null git remote add deploy "https://$GH_TOKEN@github.com/Jermolene/jermolene.github.io.git" &>/dev/null
git push deploy master &>/dev/null git push deploy master &>/dev/null
cd .. cd ..

View File

@@ -15,11 +15,3 @@ node $TW5_BUILD_TIDDLYWIKI \
--output . \ --output . \
--build readmes \ --build readmes \
|| exit 1 || exit 1
# tw.org readmes
node $TW5_BUILD_TIDDLYWIKI \
editions/tw.org \
--verbose \
--output . \
--build readmes \
|| exit 1

View File

@@ -142,15 +142,15 @@ $tw.utils.each = function(object,callback) {
var next,f,length; var next,f,length;
if(object) { if(object) {
if(Object.prototype.toString.call(object) == "[object Array]") { if(Object.prototype.toString.call(object) == "[object Array]") {
for(f=0, length=object.length; f<length; f++) { for (f=0, length=object.length; f<length; f++) {
next = callback(object[f],f,object); next = callback(object[f],f,object);
if(next === false) { if(next === false) {
break; break;
} }
} }
} else { } else {
var keys = Object.keys(object); var keys = Object.keys(object);
for(f=0, length=keys.length; f<length; f++) { for (f=0, length=keys.length; f<length; f++) {
var key = keys[f]; var key = keys[f];
next = callback(object[key],key,object); next = callback(object[key],key,object);
if(next === false) { if(next === false) {
@@ -177,7 +177,6 @@ document: defaults to current document
eventListeners: array of event listeners (this option won't work until $tw.utils.addEventListeners() has been loaded) eventListeners: array of event listeners (this option won't work until $tw.utils.addEventListeners() has been loaded)
*/ */
$tw.utils.domMaker = function(tag,options) { $tw.utils.domMaker = function(tag,options) {
var options = options || {};
var doc = options.document || document; var doc = options.document || document;
var element = doc.createElementNS(options.namespace || "http://www.w3.org/1999/xhtml",tag); var element = doc.createElementNS(options.namespace || "http://www.w3.org/1999/xhtml",tag);
if(options["class"]) { if(options["class"]) {
@@ -219,34 +218,9 @@ $tw.utils.error = function(err) {
heading = dm("h1",{text: errHeading}), heading = dm("h1",{text: errHeading}),
prompt = dm("div",{text: promptMsg, "class": "tc-error-prompt"}), prompt = dm("div",{text: promptMsg, "class": "tc-error-prompt"}),
message = dm("div",{text: err, "class":"tc-error-message"}), message = dm("div",{text: err, "class":"tc-error-message"}),
closeButton = dm("div",{children: [dm("button",{text: ( $tw.language == undefined ? "close" : $tw.language.getString("Buttons/Close/Caption") )})], "class": "tc-error-prompt"}), button = dm("div",{children: [dm("button",{text: ( $tw.language == undefined ? "close" : $tw.language.getString("Buttons/Close/Caption") )})], "class": "tc-error-prompt"}),
downloadButton = dm("div",{children: [dm("button",{text: ( $tw.language == undefined ? "download tiddlers" : $tw.language.getString("Buttons/EmergencyDownload/Caption") )})], "class": "tc-error-prompt"}), form = dm("form",{children: [heading,prompt,message,button], "class": "tc-error-form"});
form = dm("form",{children: [heading,prompt,downloadButton,message,closeButton], "class": "tc-error-form"});
document.body.insertBefore(form,document.body.firstChild); document.body.insertBefore(form,document.body.firstChild);
downloadButton.addEventListener("click",function(event) {
if($tw && $tw.wiki) {
var tiddlers = [];
$tw.wiki.each(function(tiddler,title) {
tiddlers.push(tiddler.fields);
});
var link = dm("a"),
text = JSON.stringify(tiddlers);
if(Blob !== undefined) {
var blob = new Blob([text], {type: "text/html"});
link.setAttribute("href", URL.createObjectURL(blob));
} else {
link.setAttribute("href","data:text/html," + encodeURIComponent(text));
}
link.setAttribute("download","emergency-tiddlers-" + (new Date()) + ".json");
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
} else {
alert("Emergency tiddler download is not available");
}
event.preventDefault();
return false;
},true);
form.addEventListener("submit",function(event) { form.addEventListener("submit",function(event) {
document.body.removeChild(form); document.body.removeChild(form);
event.preventDefault(); event.preventDefault();
@@ -275,7 +249,7 @@ Extend an object with the properties from a list of source objects
$tw.utils.extend = function(object /*, sourceObjectList */) { $tw.utils.extend = function(object /*, sourceObjectList */) {
$tw.utils.each(Array.prototype.slice.call(arguments,1),function(source) { $tw.utils.each(Array.prototype.slice.call(arguments,1),function(source) {
if(source) { if(source) {
for(var p in source) { for (var p in source) {
object[p] = source[p]; object[p] = source[p];
} }
} }
@@ -289,7 +263,7 @@ Fill in any null or undefined properties of an object with the properties from a
$tw.utils.deepDefaults = function(object /*, sourceObjectList */) { $tw.utils.deepDefaults = function(object /*, sourceObjectList */) {
$tw.utils.each(Array.prototype.slice.call(arguments,1),function(source) { $tw.utils.each(Array.prototype.slice.call(arguments,1),function(source) {
if(source) { if(source) {
for(var p in source) { for (var p in source) {
if(object[p] === null || object[p] === undefined) { if(object[p] === null || object[p] === undefined) {
object[p] = source[p]; object[p] = source[p];
} }
@@ -386,8 +360,8 @@ $tw.utils.parseDate = function(value) {
parseInt(value.substr(10,2)||"00",10), parseInt(value.substr(10,2)||"00",10),
parseInt(value.substr(12,2)||"00",10), parseInt(value.substr(12,2)||"00",10),
parseInt(value.substr(14,3)||"000",10))); parseInt(value.substr(14,3)||"000",10)));
d.setUTCFullYear(year); // See https://stackoverflow.com/a/5870822 d.setUTCFullYear(year); // See https://stackoverflow.com/a/5870822
return d; return d;
} else if($tw.utils.isDate(value)) { } else if($tw.utils.isDate(value)) {
return value; return value;
} else { } else {
@@ -812,7 +786,6 @@ $tw.utils.Crypto = function() {
} }
return outputText; return outputText;
}; };
$tw.sjcl = sjcl;
this.setPassword = function(newPassword) { this.setPassword = function(newPassword) {
currentPassword = newPassword; currentPassword = newPassword;
this.updateCryptoStateTiddler(); this.updateCryptoStateTiddler();
@@ -893,8 +866,8 @@ $tw.modules.execute = function(moduleName,moduleRoot) {
} else { } else {
/* /*
CommonJS optional require.main property: CommonJS optional require.main property:
In a browser we offer a fake main module which points back to the boot function In a browser we offer a fake main module which points back to the boot function
(Theoretically, this may allow TW to eventually load itself as a module in the browser) (Theoretically, this may allow TW to eventually load itself as a module in the browser)
*/ */
Object.defineProperty(sandbox.require, "main", { Object.defineProperty(sandbox.require, "main", {
value: (typeof(require) !== "undefined") ? require.main : {TiddlyWiki: _boot}, value: (typeof(require) !== "undefined") ? require.main : {TiddlyWiki: _boot},
@@ -936,9 +909,9 @@ $tw.modules.execute = function(moduleName,moduleRoot) {
moduleInfo.exports = moduleInfo.definition; moduleInfo.exports = moduleInfo.definition;
} }
} catch(e) { } catch(e) {
if(e instanceof SyntaxError) { if (e instanceof SyntaxError) {
var line = e.lineNumber || e.line; // Firefox || Safari var line = e.lineNumber || e.line; // Firefox || Safari
if(typeof(line) != "undefined" && line !== null) { if (typeof(line) != "undefined" && line !== null) {
$tw.utils.error("Syntax error in boot module " + name + ":" + line + ":\n" + e.stack); $tw.utils.error("Syntax error in boot module " + name + ":" + line + ":\n" + e.stack);
} else if(!$tw.browser) { } else if(!$tw.browser) {
// this is the only way to get node.js to display the line at which the syntax error appeared, // this is the only way to get node.js to display the line at which the syntax error appeared,
@@ -1533,7 +1506,7 @@ 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")) { if(tiddler.hasField("module-type")) {
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
if(!$tw.utils.hop($tw.modules.titles,tiddler.fields.title)) { if(!$tw.utils.hop($tw.modules.titles,tiddler.fields.title)) {
@@ -1994,10 +1967,10 @@ $tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
var value = tiddler[name]; var value = tiddler[name];
switch(fieldInfo.source) { switch(fieldInfo.source) {
case "subdirectories": case "subdirectories":
value = path.relative(rootPath, filename).split(path.sep).slice(0, -1); value = path.relative(rootPath, filename).split('/').slice(0, -1);
break; break;
case "filepath": case "filepath":
value = path.relative(rootPath, filename).split(path.sep).join('/'); value = path.relative(rootPath, filename);
break; break;
case "filename": case "filename":
value = path.basename(filename); value = path.basename(filename);
@@ -2043,7 +2016,7 @@ $tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
arrayOfFiles = arrayOfFiles || []; arrayOfFiles = arrayOfFiles || [];
var files = fs.readdirSync(dirPath); var files = fs.readdirSync(dirPath);
files.forEach(function(file) { files.forEach(function(file) {
if(recurse && fs.statSync(dirPath + path.sep + file).isDirectory()) { if (recurse && fs.statSync(dirPath + path.sep + file).isDirectory()) {
arrayOfFiles = getAllFiles(dirPath + path.sep + file, recurse, arrayOfFiles); arrayOfFiles = getAllFiles(dirPath + path.sep + file, recurse, arrayOfFiles);
} else if(fs.statSync(dirPath + path.sep + file).isFile()){ } else if(fs.statSync(dirPath + path.sep + file).isFile()){
arrayOfFiles.push(path.join(dirPath, path.sep, file)); arrayOfFiles.push(path.join(dirPath, path.sep, file));
@@ -2188,16 +2161,13 @@ Returns an array of search paths
*/ */
$tw.getLibraryItemSearchPaths = function(libraryPath,envVar) { $tw.getLibraryItemSearchPaths = function(libraryPath,envVar) {
var pluginPaths = [path.resolve($tw.boot.corePath,libraryPath)], var pluginPaths = [path.resolve($tw.boot.corePath,libraryPath)],
env;
if(envVar) {
env = process.env[envVar]; env = process.env[envVar];
if(env) { if(env) {
env.split(path.delimiter).map(function(item) { env.split(path.delimiter).map(function(item) {
if(item) { if(item) {
pluginPaths.push(item); pluginPaths.push(item);
} }
}); });
}
} }
return pluginPaths; return pluginPaths;
}; };
@@ -2283,7 +2253,7 @@ $tw.loadWikiTiddlers = function(wikiPath,options) {
} }
$tw.wiki.addTiddlers(tiddlerFile.tiddlers); $tw.wiki.addTiddlers(tiddlerFile.tiddlers);
}); });
if($tw.boot.wikiPath == wikiPath) { if ($tw.boot.wikiPath == wikiPath) {
// Save the original tiddler file locations if requested // Save the original tiddler file locations if requested
var output = {}, relativePath, fileInfo; var output = {}, relativePath, fileInfo;
for(var title in $tw.boot.files) { for(var title in $tw.boot.files) {
@@ -2468,7 +2438,6 @@ $tw.boot.initStartup = function(options) {
$tw.utils.registerFileType("image/svg+xml","utf8",".svg",{flags:["image"]}); $tw.utils.registerFileType("image/svg+xml","utf8",".svg",{flags:["image"]});
$tw.utils.registerFileType("image/vnd.microsoft.icon","base64",".ico",{flags:["image"]}); $tw.utils.registerFileType("image/vnd.microsoft.icon","base64",".ico",{flags:["image"]});
$tw.utils.registerFileType("image/x-icon","base64",".ico",{flags:["image"]}); $tw.utils.registerFileType("image/x-icon","base64",".ico",{flags:["image"]});
$tw.utils.registerFileType("application/wasm","base64",".wasm");
$tw.utils.registerFileType("application/font-woff","base64",".woff"); $tw.utils.registerFileType("application/font-woff","base64",".woff");
$tw.utils.registerFileType("application/x-font-ttf","base64",".woff"); $tw.utils.registerFileType("application/x-font-ttf","base64",".woff");
$tw.utils.registerFileType("application/font-woff2","base64",".woff2"); $tw.utils.registerFileType("application/font-woff2","base64",".woff2");
@@ -2483,12 +2452,8 @@ $tw.boot.initStartup = function(options) {
$tw.utils.registerFileType("text/x-markdown","utf8",[".md",".markdown"]); $tw.utils.registerFileType("text/x-markdown","utf8",[".md",".markdown"]);
$tw.utils.registerFileType("application/enex+xml","utf8",".enex"); $tw.utils.registerFileType("application/enex+xml","utf8",".enex");
$tw.utils.registerFileType("application/vnd.openxmlformats-officedocument.wordprocessingml.document","base64",".docx"); $tw.utils.registerFileType("application/vnd.openxmlformats-officedocument.wordprocessingml.document","base64",".docx");
$tw.utils.registerFileType("application/msword","base64",".doc");
$tw.utils.registerFileType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","base64",".xlsx"); $tw.utils.registerFileType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","base64",".xlsx");
$tw.utils.registerFileType("application/excel","base64",".xls");
$tw.utils.registerFileType("application/vnd.ms-excel","base64",".xls");
$tw.utils.registerFileType("application/vnd.openxmlformats-officedocument.presentationml.presentation","base64",".pptx"); $tw.utils.registerFileType("application/vnd.openxmlformats-officedocument.presentationml.presentation","base64",".pptx");
$tw.utils.registerFileType("application/mspowerpoint","base64",".ppt");
$tw.utils.registerFileType("text/x-bibtex","utf8",".bib",{deserializerType:"application/x-bibtex"}); $tw.utils.registerFileType("text/x-bibtex","utf8",".bib",{deserializerType:"application/x-bibtex"});
$tw.utils.registerFileType("application/x-bibtex","utf8",".bib"); $tw.utils.registerFileType("application/x-bibtex","utf8",".bib");
$tw.utils.registerFileType("application/epub+zip","base64",".epub"); $tw.utils.registerFileType("application/epub+zip","base64",".epub");
@@ -2637,14 +2602,14 @@ $tw.boot.doesTaskMatchPlatform = function(taskModule) {
var platforms = taskModule.platforms; var platforms = taskModule.platforms;
if(platforms) { if(platforms) {
for(var t=0; t<platforms.length; t++) { for(var t=0; t<platforms.length; t++) {
switch(platforms[t]) { switch (platforms[t]) {
case "browser": case "browser":
if($tw.browser) { if ($tw.browser) {
return true; return true;
} }
break; break;
case "node": case "node":
if($tw.node) { if ($tw.node) {
return true; return true;
} }
break; break;
@@ -2727,7 +2692,7 @@ Invoke the hook by key
$tw.hooks.invokeHook = function(hookName /*, value,... */) { $tw.hooks.invokeHook = function(hookName /*, value,... */) {
var args = Array.prototype.slice.call(arguments,1); var args = Array.prototype.slice.call(arguments,1);
if($tw.utils.hop($tw.hooks.names,hookName)) { if($tw.utils.hop($tw.hooks.names,hookName)) {
for(var i = 0; i < $tw.hooks.names[hookName].length; i++) { for (var i = 0; i < $tw.hooks.names[hookName].length; i++) {
args[0] = $tw.hooks.names[hookName][i].apply(null,args); args[0] = $tw.hooks.names[hookName][i].apply(null,args);
} }
} }

View File

@@ -21,7 +21,7 @@ $tw.boot = $tw.boot || Object.create(null);
// Detect platforms // Detect platforms
if(!("browser" in $tw)) { if(!("browser" in $tw)) {
$tw.browser = typeof(window) !== "undefined" && typeof(document) !== "undefined" ? {} : null; $tw.browser = typeof(window) !== "undefined" ? {} : null;
} }
if(!("node" in $tw)) { if(!("node" in $tw)) {
$tw.node = typeof(process) === "object" ? {} : null; $tw.node = typeof(process) === "object" ? {} : null;

3
boot/sjcl.js.meta Normal file
View File

@@ -0,0 +1,3 @@
title: $:/library/sjcl.js
type: application/javascript
library: yes

View File

@@ -1,32 +0,0 @@
{
"tiddlers": [
{
"file": "sjcl.js",
"fields": {
"title": "$:/library/sjcl.js",
"type": "application/javascript",
"library": "yes"
},
"prefix": "(function(define) {\n",
"suffix": "\n})(function (_,defined){window.sjcl = defined()})\n"
},
{
"file": "boot.js",
"fields": {
"title": "$:/boot/boot.js",
"type": "application/javascript"
}
},
{
"file": "bootprefix.js",
"fields": {
"title": "$:/boot/bootprefix.js",
"type": "application/javascript"
}
},
{
"file": "boot.css.tid",
"isTiddlerFile": true
}
]
}

View File

@@ -1 +0,0 @@
<p>This community exists because TiddlyWiki is more useful when people share and work together.</p><p>This community is a beautiful but fragile thing: a collection of diverse people from all over the planet, united in their interest in the project, and their commitment to helping one another achieve and learn more.</p><p>We try to make the community as broad and welcoming as possible by remembering some basic principles of culture and behaviour.</p><p>These principles guide technical and non-technical decisions, and help contributors and leaders support our project and community.</p><ul><li>We are optimistic and hopeful</li><li>We aim to foster a learning environment that is collaborative and safe for everyone</li><li>We recognise that the motivation for sharing and helping is usually for appreciation, and not financial gain, and so we take care to acknowledge and <strong>thank the people who enrich the community by sharing what they have created</strong></li><li>While we are united in our interest in TiddlyWiki, we differ in every other conceivable way. We choose to focus on what unites us, and <strong>avoid unnecessarily mixing contentious topics like religion and politics</strong></li><li>We treat each other with respect, and start with the assumption that <strong>others are acting in good faith</strong></li><li>We avoid discriminatory language</li><li>We try to use our strength as a community to help others</li><li>We avoid responding when angry or upset because we try to de-escalate conflict</li><li>We make sure we critique ideas, not people</li><li>When we disagree with others we do so graciously, and treat others with dignity and respoect</li><li>We do not tolerate intolerance towards others</li><li>We seek first to understand others, and then to be understood</li><li>We have fun</li></ul><p>Our discussions are in English. It is not the first language of many people in the community, nor do we all share the same cultural background and reference points. So we take care to use language that is clear and unambigous, and avoid cultural references or jokes that will not be widely understood.</p><p>It is not acceptable to make jokes or other comments that discriminate by race, gender, sexuality, or other protected characteristic.</p><p>As an inclusive community, we are committed to making sure that TiddlyWiki is an accessible tool that understands the needs of people with disabilities.</p>

File diff suppressed because one or more lines are too long

View File

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

View File

@@ -1,5 +0,0 @@
title: $:/core/images/discord
tags: $:/tags/Image
\parameters (size:"22pt")
<svg width=<<size>> height=<<size>> class="tc-image-discord tc-image-button" viewBox="0 -28.5 256 256"><path d="M216.856 16.597A208.502 208.502 0 0 0 164.042 0c-2.275 4.113-4.933 9.645-6.766 14.046-19.692-2.961-39.203-2.961-58.533 0-1.832-4.4-4.55-9.933-6.846-14.046a207.809 207.809 0 0 0-52.855 16.638C5.618 67.147-3.443 116.4 1.087 164.956c22.169 16.555 43.653 26.612 64.775 33.193A161.094 161.094 0 0 0 79.735 175.3a136.413 136.413 0 0 1-21.846-10.632 108.636 108.636 0 0 0 5.356-4.237c42.122 19.702 87.89 19.702 129.51 0a131.66 131.66 0 0 0 5.355 4.237 136.07 136.07 0 0 1-21.886 10.653c4.006 8.02 8.638 15.67 13.873 22.848 21.142-6.58 42.646-16.637 64.815-33.213 5.316-56.288-9.08-105.09-38.056-148.36ZM85.474 135.095c-12.645 0-23.015-11.805-23.015-26.18s10.149-26.2 23.015-26.2c12.867 0 23.236 11.804 23.015 26.2.02 14.375-10.148 26.18-23.015 26.18Zm85.051 0c-12.645 0-23.014-11.805-23.014-26.18s10.148-26.2 23.014-26.2c12.867 0 23.236 11.804 23.015 26.2 0 14.375-10.148 26.18-23.015 26.18Z"/></svg>

View File

@@ -1,5 +0,0 @@
title: $:/core/images/input-button
tags: $:/tags/Image
\parameters (size:"22pt")
<svg width=<<size>> height=<<size>> class="tc-image-input-button tc-image-button" viewBox="0 0 22 22"><path d="M1.375 22h19.249c.365 0 .716-.145.973-.404v.001c.258-.257.404-.607.403-.972v-11a1.376 1.376 0 0 0-2.75 0v9.625H2.75V9.625a1.376 1.376 0 0 0-2.75 0v11C0 21.384.617 22 1.375 22Z"/><path d="m9.732 11.904-1.541-1.541a1.375 1.375 0 1 0-1.944 1.944l3.887 3.888c.258.258.608.402.973.402h-.001c.353 0 .705-.134.974-.402l3.888-3.889a1.376 1.376 0 0 0 .001-1.944 1.377 1.377 0 0 0-1.946 0l-1.541 1.542V1.376a1.375 1.375 0 1 0-2.75 0v10.528Z"/></svg>

View File

@@ -1,7 +0,0 @@
title: $:/core/images/standard-layout
tags: $:/tags/Image
\parameters (size:"22pt")
<svg width=<<size>> height=<<size>> class="tc-image-standard-layout tc-image-button" viewBox="0 0 128 128">
<path d="M71.93 72A8.07 8.07 0 0 1 80 80.07v7.86A8.071 8.071 0 0 1 71.93 96H8.07A8.067 8.067 0 0 1 0 87.93v-7.86A8.072 8.072 0 0 1 8.07 72h63.86Zm0 32a8.07 8.07 0 0 1 8.07 8.07v7.86a8.071 8.071 0 0 1-8.07 8.07H8.07A8.067 8.067 0 0 1 0 119.93v-7.86A8.072 8.072 0 0 1 8.07 104h63.86Zm0-104A8.068 8.068 0 0 1 80 8.07v47.86A8.073 8.073 0 0 1 71.93 64H8.07A8.07 8.07 0 0 1 0 55.93V8.07A8.072 8.072 0 0 1 8.07 0h63.86Zm48 0c2.14 0 4.193.85 5.706 2.364A8.067 8.067 0 0 1 128 8.07v111.86c0 2.14-.85 4.193-2.364 5.706A8.067 8.067 0 0 1 119.93 128H96.07c-2.14 0-4.193-.85-5.706-2.364A8.067 8.067 0 0 1 88 119.93V8.07c0-2.14.85-4.193 2.364-5.706A8.067 8.067 0 0 1 96.07 0h23.86ZM116 24h-16a3.995 3.995 0 0 0-2.828 1.172 3.995 3.995 0 0 0 0 5.656A3.995 3.995 0 0 0 100 32h16a3.995 3.995 0 0 0 2.828-1.172 3.995 3.995 0 0 0 0-5.656A3.995 3.995 0 0 0 116 24Z"/>
</svg>

View File

@@ -28,7 +28,6 @@ Encryption/ClearPassword/Caption: clear password
Encryption/ClearPassword/Hint: Clear the password and save this wiki without encryption Encryption/ClearPassword/Hint: Clear the password and save this wiki without encryption
Encryption/SetPassword/Caption: set password Encryption/SetPassword/Caption: set password
Encryption/SetPassword/Hint: Set a password for saving this wiki with encryption Encryption/SetPassword/Hint: Set a password for saving this wiki with encryption
EmergencyDownload/Caption: download tiddlers as json
ExportPage/Caption: export all ExportPage/Caption: export all
ExportPage/Hint: Export all tiddlers ExportPage/Hint: Export all tiddlers
ExportTiddler/Caption: export tiddler ExportTiddler/Caption: export tiddler
@@ -80,7 +79,6 @@ NewMarkdown/Caption: new Markdown tiddler
NewMarkdown/Hint: Create a new Markdown tiddler NewMarkdown/Hint: Create a new Markdown tiddler
NewTiddler/Caption: new tiddler NewTiddler/Caption: new tiddler
NewTiddler/Hint: Create a new tiddler NewTiddler/Hint: Create a new tiddler
OpenControlPanel/Hint: Open control panel
OpenWindow/Caption: open in new window OpenWindow/Caption: open in new window
OpenWindow/Hint: Open tiddler in new window OpenWindow/Hint: Open tiddler in new window
Palette/Caption: palette Palette/Caption: palette
@@ -105,8 +103,6 @@ ShowSideBar/Caption: show sidebar
ShowSideBar/Hint: Show sidebar ShowSideBar/Hint: Show sidebar
TagManager/Caption: tag manager TagManager/Caption: tag manager
TagManager/Hint: Open tag manager TagManager/Hint: Open tag manager
TestCaseImport/Caption: import tiddlers
TestCaseImport/Hint: Import tiddlers
Timestamp/Caption: timestamps Timestamp/Caption: timestamps
Timestamp/Hint: Choose whether modifications update timestamps Timestamp/Hint: Choose whether modifications update timestamps
Timestamp/On/Caption: timestamps are on Timestamp/On/Caption: timestamps are on
@@ -133,7 +129,6 @@ Excise/Caption/Replace/Link: link
Excise/Caption/Replace/Transclusion: transclusion Excise/Caption/Replace/Transclusion: transclusion
Excise/Caption/Tag: Tag new tiddler with the title of this tiddler Excise/Caption/Tag: Tag new tiddler with the title of this tiddler
Excise/Caption/TiddlerExists: Warning: tiddler already exists Excise/Caption/TiddlerExists: Warning: tiddler already exists
Excise/DefaultTitle: New Excision
Excise/Hint: Excise the selected text into a new tiddler Excise/Hint: Excise the selected text into a new tiddler
Heading1/Caption: heading 1 Heading1/Caption: heading 1
Heading1/Hint: Apply heading level 1 formatting to lines containing selection Heading1/Hint: Apply heading level 1 formatting to lines containing selection

View File

@@ -198,12 +198,6 @@ Settings/TitleLinks/Yes/Description: Display tiddler titles as links
Settings/MissingLinks/Caption: Wiki Links Settings/MissingLinks/Caption: Wiki Links
Settings/MissingLinks/Hint: Choose whether to link to tiddlers that do not exist yet Settings/MissingLinks/Hint: Choose whether to link to tiddlers that do not exist yet
Settings/MissingLinks/Description: Enable links to missing tiddlers Settings/MissingLinks/Description: Enable links to missing tiddlers
SocialCard/Caption: Social Media Card
SocialCard/Domain/Prompt: Domain name to display for the link (for example, ''tiddlywiki.com'')
SocialCard/Hint: This information is used by social and messaging services to display a preview card for links to this TiddlyWiki when hosted online
SocialCard/PreviewUrl/Prompt: Full URL to preview image for this TiddlyWiki
SocialCard/PreviewUrl/Preview: Preview image:
SocialCard/Url/Prompt: Full URL of this TiddlyWiki
StoryTiddler/Caption: Story Tiddler StoryTiddler/Caption: Story Tiddler
StoryTiddler/Hint: This rule cascade is used to dynamically choose the template for displaying a tiddler in the story river. StoryTiddler/Hint: This rule cascade is used to dynamically choose the template for displaying a tiddler in the story river.
StoryView/Caption: Story View StoryView/Caption: Story View
@@ -212,12 +206,6 @@ Stylesheets/Caption: Stylesheets
Stylesheets/Expand/Caption: Expand All Stylesheets/Expand/Caption: Expand All
Stylesheets/Hint: This is the rendered CSS of the current stylesheet tiddlers tagged with <<tag "$:/tags/Stylesheet">> Stylesheets/Hint: This is the rendered CSS of the current stylesheet tiddlers tagged with <<tag "$:/tags/Stylesheet">>
Stylesheets/Restore/Caption: Restore Stylesheets/Restore/Caption: Restore
TestCases/Caption: Test Cases
TestCases/Hint: Test cases are self contained examples for testing and learning
TestCases/All/Caption: All Test Cases
TestCases/All/Hint: All Test Cases
TestCases/Failed/Caption: Failed Test Cases
TestCases/Failed/Hint: Only Failed Test Cases
Theme/Caption: Theme Theme/Caption: Theme
Theme/Prompt: Current theme: Theme/Prompt: Current theme:
TiddlerFields/Caption: Tiddler Fields TiddlerFields/Caption: Tiddler Fields
@@ -241,7 +229,3 @@ ViewTemplateBody/Caption: View Template Body
ViewTemplateBody/Hint: This rule cascade is used by the default view template to dynamically choose the template for displaying the body of a tiddler. ViewTemplateBody/Hint: This rule cascade is used by the default view template to dynamically choose the template for displaying the body of a tiddler.
ViewTemplateTitle/Caption: View Template Title ViewTemplateTitle/Caption: View Template Title
ViewTemplateTitle/Hint: This rule cascade is used by the default view template to dynamically choose the template for displaying the title of a tiddler. ViewTemplateTitle/Hint: This rule cascade is used by the default view template to dynamically choose the template for displaying the title of a tiddler.
ViewTemplateSubtitle/Caption: View Template Subtitle
ViewTemplateSubtitle/Hint: This rule cascade is used by the default view template to dynamically choose the template for displaying the subtitle of a tiddler.
ViewTemplateTags/Caption: View Template Tags
ViewTemplateTags/Hint: This rule cascade is used by the default view template to dynamically choose the template for displaying the tags area of a tiddler.

View File

@@ -9,7 +9,7 @@ config: Data to be inserted into `$tw.config`.
filteroperator: Individual filter operator methods. filteroperator: Individual filter operator methods.
global: Global data to be inserted into `$tw`. global: Global data to be inserted into `$tw`.
info: Publishes system information via the [[$:/temp/info-plugin]] pseudo-plugin. info: Publishes system information via the [[$:/temp/info-plugin]] pseudo-plugin.
isfilteroperator: Parameters for the ''is'' filter operator. isfilteroperator: Operands for the ''is'' filter operator.
library: Generic module type for general purpose JavaScript modules. library: Generic module type for general purpose JavaScript modules.
macro: JavaScript macro definitions. macro: JavaScript macro definitions.
parser: Parsers for different content types. parser: Parsers for different content types.

View File

@@ -65,13 +65,6 @@ sidebar-tab-foreground-selected: Sidebar tab foreground for selected tabs
sidebar-tab-foreground: Sidebar tab foreground sidebar-tab-foreground: Sidebar tab foreground
sidebar-tiddler-link-foreground-hover: Sidebar tiddler link foreground hover sidebar-tiddler-link-foreground-hover: Sidebar tiddler link foreground hover
sidebar-tiddler-link-foreground: Sidebar tiddler link foreground sidebar-tiddler-link-foreground: Sidebar tiddler link foreground
stability-stable: Badge for stability level "stable"
stability-experimental: Badge for stability level "experimental"
stability-deprecated: Badge for stability level "deprecated"
stability-legacy: Badge for stability level "legacy"
testcase-accent-level-1: Test case accent colour with no nesting
testcase-accent-level-2: Test case accent colour with 2nd level nesting
testcase-accent-level-3: Test case accent colour with 3rd level nesting or higher
site-title-foreground: Site title foreground site-title-foreground: Site title foreground
static-alert-foreground: Static alert foreground static-alert-foreground: Static alert foreground
tab-background-selected: Tab background for selected tabs tab-background-selected: Tab background for selected tabs

View File

@@ -4,7 +4,6 @@ _canonical_uri: The full URI of an external image tiddler
author: Name of the author of a plugin author: Name of the author of a plugin
bag: The name of the bag from which a tiddler came bag: The name of the bag from which a tiddler came
caption: The text to be displayed on a tab or button caption: The text to be displayed on a tab or button
class: The CSS class applied to a tiddler when rendering it - see [[Custom styles by user-class]]. Also used for [[Modals]]
code-body: The view template will display the tiddler as code if set to ''yes'' code-body: The view template will display the tiddler as code if set to ''yes''
color: The CSS color value associated with a tiddler color: The CSS color value associated with a tiddler
component: The name of the component responsible for an [[alert tiddler|AlertMechanism]] component: The name of the component responsible for an [[alert tiddler|AlertMechanism]]
@@ -30,7 +29,6 @@ name: The human readable name associated with a plugin tiddler
parent-plugin: For a plugin, specifies which plugin of which it is a sub-plugin parent-plugin: For a plugin, specifies which plugin of which it is a sub-plugin
plugin-priority: A numerical value indicating the priority of a plugin tiddler plugin-priority: A numerical value indicating the priority of a plugin tiddler
plugin-type: The type of plugin in a plugin tiddler plugin-type: The type of plugin in a plugin tiddler
stability: The development status of a plugin: deprecated, experimental, stable, or legacy
revision: The revision of the tiddler held at the server revision: The revision of the tiddler held at the server
released: Date of a TiddlyWiki release released: Date of a TiddlyWiki release
source: The source URL associated with a tiddler source: The source URL associated with a tiddler

View File

@@ -10,7 +10,7 @@ Sequentially run the command tokens returned from a filter
Examples Examples
``` ```
--commands "[enlist:raw{$:/build-commands-as-text}]" --commands "[enlist{$:/build-commands-as-text}]"
``` ```
``` ```

View File

@@ -30,7 +30,7 @@ Error/DeserializeOperator/UnknownDeserializer: Filter Error: Unknown deserialize
Error/Filter: Filter error Error/Filter: Filter error
Error/FilterSyntax: Syntax error in filter expression Error/FilterSyntax: Syntax error in filter expression
Error/FilterRunPrefix: Filter Error: Unknown prefix for filter run Error/FilterRunPrefix: Filter Error: Unknown prefix for filter run
Error/IsFilterOperator: Filter Error: Unknown parameter for the 'is' filter operator Error/IsFilterOperator: Filter Error: Unknown operand for the 'is' filter operator
Error/FormatFilterOperator: Filter Error: Unknown suffix for the 'format' filter operator Error/FormatFilterOperator: Filter Error: Unknown suffix for the 'format' filter operator
Error/LoadingPluginLibrary: Error loading plugin library Error/LoadingPluginLibrary: Error loading plugin library
Error/NetworkErrorAlert: `<h2>''Network Error''</h2>It looks like the connection to the server has been lost. This may indicate a problem with your network connection. Please attempt to restore network connectivity before continuing.<br><br>''Any unsaved changes will be automatically synchronised when connectivity is restored''.` Error/NetworkErrorAlert: `<h2>''Network Error''</h2>It looks like the connection to the server has been lost. This may indicate a problem with your network connection. Please attempt to restore network connectivity before continuing.<br><br>''Any unsaved changes will be automatically synchronised when connectivity is restored''.`
@@ -70,7 +70,7 @@ No: No
OfficialPluginLibrary: Official ~TiddlyWiki Plugin Library OfficialPluginLibrary: Official ~TiddlyWiki Plugin Library
OfficialPluginLibrary/Hint: The official ~TiddlyWiki plugin library at tiddlywiki.com. Plugins, themes and language packs are maintained by the core team. OfficialPluginLibrary/Hint: The official ~TiddlyWiki plugin library at tiddlywiki.com. Plugins, themes and language packs are maintained by the core team.
PageTemplate/Description: the default ~TiddlyWiki layout PageTemplate/Description: the default ~TiddlyWiki layout
PageTemplate/Name: Standard Layout PageTemplate/Name: Default ~PageTemplate
PluginReloadWarning: Please save {{$:/core/ui/Buttons/save-wiki}} and reload {{$:/core/ui/Buttons/refresh}} to allow changes to ~JavaScript plugins to take effect PluginReloadWarning: Please save {{$:/core/ui/Buttons/save-wiki}} and reload {{$:/core/ui/Buttons/refresh}} to allow changes to ~JavaScript plugins to take effect
RecentChanges/DateFormat: DDth MMM YYYY RecentChanges/DateFormat: DDth MMM YYYY
Shortcuts/Input/AdvancedSearch/Hint: Open the ~AdvancedSearch panel from within the sidebar search field Shortcuts/Input/AdvancedSearch/Hint: Open the ~AdvancedSearch panel from within the sidebar search field

View File

@@ -1,7 +0,0 @@
title: $:/language/Snippets/FunctionDefinition
tags: $:/tags/TextEditor/Snippet
caption: Function definition
\function f.name(param1,param2:"default value") [<param1>!is[blank]else<param2>]
<<f.name>>

View File

@@ -1,7 +0,0 @@
title: $:/language/Snippets/ProcedureDefinition
tags: $:/tags/TextEditor/Snippet
caption: Procedure definition
\procedure procName(param1:"default value",param2)
Your text comes here.
\end

View File

@@ -0,0 +1,5 @@
title: $:/language/Docs/Types/image/x-icon
description: ICO icon
name: image/x-icon
group: Image
group-sort: 1

View File

@@ -1,5 +0,0 @@
title: $:/language/Docs/Types/text/vnd.tiddlywiki-multiple
description: Compound tiddler
name: text/vnd.tiddlywiki-multiple
group: Developer
group-sort: 2

View File

@@ -18,7 +18,7 @@ exports.info = {
name: "listen", name: "listen",
synchronous: true, synchronous: true,
namedParameterMode: true, namedParameterMode: true,
mandatoryParameters: [] mandatoryParameters: [],
}; };
var Command = function(params,commander,callback) { var Command = function(params,commander,callback) {

View File

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

View File

@@ -45,22 +45,17 @@ Render individual tiddlers and save the results to the specified files
variableList = variableList.slice(2); variableList = variableList.slice(2);
} }
$tw.utils.each(tiddlers,function(title) { $tw.utils.each(tiddlers,function(title) {
var filenameResults = wiki.filterTiddlers(filenameFilter,$tw.rootWidget,wiki.makeTiddlerIterator([title])); var filepath = path.resolve(self.commander.outputPath,wiki.filterTiddlers(filenameFilter,$tw.rootWidget,wiki.makeTiddlerIterator([title]))[0]);
if(filenameResults.length > 0) { if(self.commander.verbose) {
var filepath = path.resolve(self.commander.outputPath,filenameResults[0]); console.log("Rendering \"" + title + "\" to \"" + filepath + "\"");
if(self.commander.verbose) {
console.log("Rendering \"" + title + "\" to \"" + filepath + "\"");
}
var parser = wiki.parseTiddler(template || title),
widgetNode = wiki.makeWidget(parser,{variables: $tw.utils.extend({},variables,{currentTiddler: title,storyTiddler: title})}),
container = $tw.fakeDocument.createElement("div");
widgetNode.render(container,null);
var text = type === "text/html" ? container.innerHTML : container.textContent;
$tw.utils.createFileDirectories(filepath);
fs.writeFileSync(filepath,text,"utf8");
} else {
console.log("Not rendering \"" + title + "\" because the filename filter returned an empty result");
} }
var parser = wiki.parseTiddler(template || title),
widgetNode = wiki.makeWidget(parser,{variables: $tw.utils.extend({},variables,{currentTiddler: title,storyTiddler: title})}),
container = $tw.fakeDocument.createElement("div");
widgetNode.render(container,null);
var text = type === "text/html" ? container.innerHTML : container.textContent;
$tw.utils.createFileDirectories(filepath);
fs.writeFileSync(filepath,text,"utf8");
}); });
return null; return null;
}; };

View File

@@ -43,9 +43,7 @@ Saves individual tiddlers in their raw text or binary format to the specified fi
directory: path.resolve(self.commander.outputPath), directory: path.resolve(self.commander.outputPath),
pathFilters: [filenameFilter], pathFilters: [filenameFilter],
wiki: wiki, wiki: wiki,
fileInfo: { fileInfo: {}
overwrite: true
}
}); });
if(self.commander.verbose) { if(self.commander.verbose) {
console.log("Saving \"" + title + "\" to \"" + fileInfo.filepath + "\""); console.log("Saving \"" + title + "\" to \"" + fileInfo.filepath + "\"");

View File

@@ -46,7 +46,7 @@ Command.prototype.execute = function() {
type = tiddler.fields.type || "text/vnd.tiddlywiki", type = tiddler.fields.type || "text/vnd.tiddlywiki",
contentTypeInfo = $tw.config.contentTypeInfo[type] || {encoding: "utf8"}, contentTypeInfo = $tw.config.contentTypeInfo[type] || {encoding: "utf8"},
filename = path.resolve(pathname,$tw.utils.encodeURIComponentExtended(title)); filename = path.resolve(pathname,$tw.utils.encodeURIComponentExtended(title));
fs.writeFileSync(filename,tiddler.fields.text || "",contentTypeInfo.encoding); fs.writeFileSync(filename,tiddler.fields.text,contentTypeInfo.encoding);
}); });
return null; return null;
}; };

View File

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

View File

@@ -30,7 +30,7 @@ exports.textPrimitives.wikiLink = exports.textPrimitives.upperLetter + "+" +
exports.textPrimitives.upperLetter + exports.textPrimitives.upperLetter +
exports.textPrimitives.anyLetter + "*"; exports.textPrimitives.anyLetter + "*";
exports.htmlEntities = {quot:34, dollar:36, amp:38, apos:39, lt:60, gt:62, nbsp:160, iexcl:161, cent:162, pound:163, curren:164, yen:165, brvbar:166, sect:167, uml:168, copy:169, ordf:170, laquo:171, not:172, shy:173, reg:174, macr:175, deg:176, plusmn:177, sup2:178, sup3:179, acute:180, micro:181, para:182, middot:183, cedil:184, sup1:185, ordm:186, raquo:187, frac14:188, frac12:189, frac34:190, iquest:191, Agrave:192, Aacute:193, Acirc:194, Atilde:195, Auml:196, Aring:197, AElig:198, Ccedil:199, Egrave:200, Eacute:201, Ecirc:202, Euml:203, Igrave:204, Iacute:205, Icirc:206, Iuml:207, ETH:208, Ntilde:209, Ograve:210, Oacute:211, Ocirc:212, Otilde:213, Ouml:214, times:215, Oslash:216, Ugrave:217, Uacute:218, Ucirc:219, Uuml:220, Yacute:221, THORN:222, szlig:223, agrave:224, aacute:225, acirc:226, atilde:227, auml:228, aring:229, aelig:230, ccedil:231, egrave:232, eacute:233, ecirc:234, euml:235, igrave:236, iacute:237, icirc:238, iuml:239, eth:240, ntilde:241, ograve:242, oacute:243, ocirc:244, otilde:245, ouml:246, divide:247, oslash:248, ugrave:249, uacute:250, ucirc:251, uuml:252, yacute:253, thorn:254, yuml:255, OElig:338, oelig:339, Scaron:352, scaron:353, Yuml:376, fnof:402, circ:710, tilde:732, Alpha:913, Beta:914, Gamma:915, Delta:916, Epsilon:917, Zeta:918, Eta:919, Theta:920, Iota:921, Kappa:922, Lambda:923, Mu:924, Nu:925, Xi:926, Omicron:927, Pi:928, Rho:929, Sigma:931, Tau:932, Upsilon:933, Phi:934, Chi:935, Psi:936, Omega:937, alpha:945, beta:946, gamma:947, delta:948, epsilon:949, zeta:950, eta:951, theta:952, iota:953, kappa:954, lambda:955, mu:956, nu:957, xi:958, omicron:959, pi:960, rho:961, sigmaf:962, sigma:963, tau:964, upsilon:965, phi:966, chi:967, psi:968, omega:969, thetasym:977, upsih:978, piv:982, ensp:8194, emsp:8195, thinsp:8201, zwnj:8204, zwj:8205, lrm:8206, rlm:8207, ndash:8211, mdash:8212, lsquo:8216, rsquo:8217, sbquo:8218, ldquo:8220, rdquo:8221, bdquo:8222, dagger:8224, Dagger:8225, bull:8226, hellip:8230, permil:8240, prime:8242, Prime:8243, lsaquo:8249, rsaquo:8250, oline:8254, frasl:8260, nobreak:8288, NoBreak:8288, euro:8364, image:8465, weierp:8472, real:8476, trade:8482, alefsym:8501, larr:8592, uarr:8593, rarr:8594, darr:8595, harr:8596, crarr:8629, lArr:8656, uArr:8657, rArr:8658, dArr:8659, hArr:8660, forall:8704, part:8706, exist:8707, empty:8709, nabla:8711, isin:8712, notin:8713, ni:8715, prod:8719, sum:8721, minus:8722, lowast:8727, radic:8730, prop:8733, infin:8734, ang:8736, and:8743, or:8744, cap:8745, cup:8746, int:8747, there4:8756, sim:8764, cong:8773, asymp:8776, ne:8800, equiv:8801, le:8804, ge:8805, sub:8834, sup:8835, nsub:8836, sube:8838, supe:8839, oplus:8853, otimes:8855, perp:8869, sdot:8901, lceil:8968, rceil:8969, lfloor:8970, rfloor:8971, lang:9001, rang:9002, loz:9674, spades:9824, clubs:9827, hearts:9829, diams:9830 }; exports.htmlEntities = {quot:34, dollar:36, amp:38, apos:39, lt:60, gt:62, nbsp:160, iexcl:161, cent:162, pound:163, curren:164, yen:165, brvbar:166, sect:167, uml:168, copy:169, ordf:170, laquo:171, not:172, shy:173, reg:174, macr:175, deg:176, plusmn:177, sup2:178, sup3:179, acute:180, micro:181, para:182, middot:183, cedil:184, sup1:185, ordm:186, raquo:187, frac14:188, frac12:189, frac34:190, iquest:191, Agrave:192, Aacute:193, Acirc:194, Atilde:195, Auml:196, Aring:197, AElig:198, Ccedil:199, Egrave:200, Eacute:201, Ecirc:202, Euml:203, Igrave:204, Iacute:205, Icirc:206, Iuml:207, ETH:208, Ntilde:209, Ograve:210, Oacute:211, Ocirc:212, Otilde:213, Ouml:214, times:215, Oslash:216, Ugrave:217, Uacute:218, Ucirc:219, Uuml:220, Yacute:221, THORN:222, szlig:223, agrave:224, aacute:225, acirc:226, atilde:227, auml:228, aring:229, aelig:230, ccedil:231, egrave:232, eacute:233, ecirc:234, euml:235, igrave:236, iacute:237, icirc:238, iuml:239, eth:240, ntilde:241, ograve:242, oacute:243, ocirc:244, otilde:245, ouml:246, divide:247, oslash:248, ugrave:249, uacute:250, ucirc:251, uuml:252, yacute:253, thorn:254, yuml:255, OElig:338, oelig:339, Scaron:352, scaron:353, Yuml:376, fnof:402, circ:710, tilde:732, Alpha:913, Beta:914, Gamma:915, Delta:916, Epsilon:917, Zeta:918, Eta:919, Theta:920, Iota:921, Kappa:922, Lambda:923, Mu:924, Nu:925, Xi:926, Omicron:927, Pi:928, Rho:929, Sigma:931, Tau:932, Upsilon:933, Phi:934, Chi:935, Psi:936, Omega:937, alpha:945, beta:946, gamma:947, delta:948, epsilon:949, zeta:950, eta:951, theta:952, iota:953, kappa:954, lambda:955, mu:956, nu:957, xi:958, omicron:959, pi:960, rho:961, sigmaf:962, sigma:963, tau:964, upsilon:965, phi:966, chi:967, psi:968, omega:969, thetasym:977, upsih:978, piv:982, ensp:8194, emsp:8195, thinsp:8201, zwnj:8204, zwj:8205, lrm:8206, rlm:8207, ndash:8211, mdash:8212, lsquo:8216, rsquo:8217, sbquo:8218, ldquo:8220, rdquo:8221, bdquo:8222, dagger:8224, Dagger:8225, bull:8226, hellip:8230, permil:8240, prime:8242, Prime:8243, lsaquo:8249, rsaquo:8250, oline:8254, frasl:8260, euro:8364, image:8465, weierp:8472, real:8476, trade:8482, alefsym:8501, larr:8592, uarr:8593, rarr:8594, darr:8595, harr:8596, crarr:8629, lArr:8656, uArr:8657, rArr:8658, dArr:8659, hArr:8660, forall:8704, part:8706, exist:8707, empty:8709, nabla:8711, isin:8712, notin:8713, ni:8715, prod:8719, sum:8721, minus:8722, lowast:8727, radic:8730, prop:8733, infin:8734, ang:8736, and:8743, or:8744, cap:8745, cup:8746, int:8747, there4:8756, sim:8764, cong:8773, asymp:8776, ne:8800, equiv:8801, le:8804, ge:8805, sub:8834, sup:8835, nsub:8836, sube:8838, supe:8839, oplus:8853, otimes:8855, perp:8869, sdot:8901, lceil:8968, rceil:8969, lfloor:8970, rfloor:8971, lang:9001, rang:9002, loz:9674, spades:9824, clubs:9827, hearts:9829, diams:9830 };
exports.htmlVoidElements = "area,base,br,col,command,embed,hr,img,input,keygen,link,meta,param,source,track,wbr".split(","); exports.htmlVoidElements = "area,base,br,col,command,embed,hr,img,input,keygen,link,meta,param,source,track,wbr".split(",");

View File

@@ -14,12 +14,11 @@ Text editor operation to excise the selection to a new tiddler
exports["excise"] = function(event,operation) { exports["excise"] = function(event,operation) {
var editTiddler = this.wiki.getTiddler(this.editTitle), var editTiddler = this.wiki.getTiddler(this.editTitle),
editTiddlerTitle = this.editTitle, editTiddlerTitle = this.editTitle;
excisionBaseTitle = $tw.language.getString("Buttons/Excise/DefaultTitle");
if(editTiddler && editTiddler.fields["draft.of"]) { if(editTiddler && editTiddler.fields["draft.of"]) {
editTiddlerTitle = editTiddler.fields["draft.of"]; editTiddlerTitle = editTiddler.fields["draft.of"];
} }
var excisionTitle = event.paramObject.title || this.wiki.generateNewTitle(excisionBaseTitle); var excisionTitle = event.paramObject.title || this.wiki.generateNewTitle("New Excision");
this.wiki.addTiddler(new $tw.Tiddler( this.wiki.addTiddler(new $tw.Tiddler(
this.wiki.getCreationFields(), this.wiki.getCreationFields(),
this.wiki.getModificationFields(), this.wiki.getModificationFields(),

View File

@@ -1,26 +0,0 @@
/*\
title: $:/core/modules/filters/backtranscludes.js
type: application/javascript
module-type: filteroperator
Filter operator for returning all the backtranscludes from a tiddler
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.backtranscludes = function(source,operator,options) {
var results = new $tw.utils.LinkedList();
source(function(tiddler,title) {
results.pushTop(options.wiki.getTiddlerBacktranscludes(title));
});
return results.makeTiddlerIterator(options.wiki);
};
})();

View File

@@ -14,9 +14,12 @@ Filter operators for cryptography, using the Stanford JavaScript library
exports.sha256 = function(source,operator,options) { exports.sha256 = function(source,operator,options) {
var results = [], var results = [],
length = parseInt(operator.operand,10) || 20; length = parseInt(operator.operand,10) || 20,
sha256 = function(text) {
return sjcl.codec.hex.fromBits(sjcl.hash.sha256.hash(text)).substr(0,length);
};
source(function(tiddler,title) { source(function(tiddler,title) {
results.push($tw.utils.sha256(title,{length: length})); results.push(sha256(title));
}); });
return results; return results;
}; };

View File

@@ -213,18 +213,6 @@ function getDataItemType(data,indexes) {
} }
} }
function getItemAtIndex(item,index) {
if($tw.utils.hop(item,index)) {
return item[index];
} else if($tw.utils.isArray(item)) {
index = $tw.utils.parseInt(index);
if(index < 0) { index = index + item.length };
return item[index]; // Will be undefined if index was out-of-bounds
} else {
return undefined;
}
}
/* /*
Given a JSON data structure and an array of index strings, return the value at the end of the index chain, or "undefined" if any of the index strings are invalid Given a JSON data structure and an array of index strings, return the value at the end of the index chain, or "undefined" if any of the index strings are invalid
*/ */
@@ -237,7 +225,7 @@ function getDataItem(data,indexes) {
for(var i=0; i<indexes.length; i++) { for(var i=0; i<indexes.length; i++) {
if(item !== undefined) { if(item !== undefined) {
if(item !== null && ["number","string","boolean"].indexOf(typeof item) === -1) { if(item !== null && ["number","string","boolean"].indexOf(typeof item) === -1) {
item = getItemAtIndex(item,indexes[i]); item = item[indexes[i]];
} else { } else {
item = undefined; item = undefined;
} }
@@ -261,22 +249,17 @@ function setDataItem(data,indexes,value) {
// Traverse the JSON data structure using the index chain // Traverse the JSON data structure using the index chain
var current = data; var current = data;
for(var i = 0; i < indexes.length - 1; i++) { for(var i = 0; i < indexes.length - 1; i++) {
current = getItemAtIndex(current,indexes[i]); var index = indexes[i];
if(current === undefined) { if($tw.utils.hop(current,index)) {
current = current[index];
} else {
// Return the original JSON data structure if any of the index strings are invalid // Return the original JSON data structure if any of the index strings are invalid
return data; return data;
} }
} }
// Add the value to the end of the index chain // Add the value to the end of the index chain
var lastIndex = indexes[indexes.length - 1]; var lastIndex = indexes[indexes.length - 1];
if($tw.utils.isArray(current)) { current[lastIndex] = value;
lastIndex = $tw.utils.parseInt(lastIndex);
if(lastIndex < 0) { lastIndex = lastIndex + current.length };
}
// Only set indexes on objects and arrays
if(typeof current === "object") {
current[lastIndex] = value;
}
return data; return data;
} }

View File

@@ -127,7 +127,7 @@ function diffPartsToChars(text1,text2,mode) {
if(lineHash.hasOwnProperty ? lineHash.hasOwnProperty(line) : (lineHash[line] !== undefined)) { if(lineHash.hasOwnProperty ? lineHash.hasOwnProperty(line) : (lineHash[line] !== undefined)) {
chars += String.fromCharCode(lineHash[line]); chars += String.fromCharCode(lineHash[line]);
} else { } else {
if(lineArrayLength == maxLines) { if (lineArrayLength == maxLines) {
line = text.substring(lineStart); line = text.substring(lineStart);
lineEnd = text.length; lineEnd = text.length;
} }
@@ -217,10 +217,7 @@ exports.splitregexp = function(source,operator,options) {
return ["RegExp error: " + ex]; return ["RegExp error: " + ex];
} }
source(function(tiddler,title) { source(function(tiddler,title) {
var parts = title.split(regExp).map(function(part){ Array.prototype.push.apply(result,title.split(regExp));
return part || ""; // make sure it's a string
});
Array.prototype.push.apply(result,parts);
}); });
return result; return result;
}; };
@@ -267,7 +264,7 @@ exports.pad = function(source,operator,options) {
} else { } else {
var padString = "", var padString = "",
padStringLength = targetLength - title.length; padStringLength = targetLength - title.length;
while(padStringLength > padString.length) { while (padStringLength > padString.length) {
padString += fill; padString += fill;
} }
//make sure we do not exceed the specified length //make sure we do not exceed the specified length

View File

@@ -1,26 +0,0 @@
/*\
title: $:/core/modules/filters/transcludes.js
type: application/javascript
module-type: filteroperator
Filter operator for returning all the transcludes from a tiddler
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.transcludes = function(source,operator,options) {
var results = new $tw.utils.LinkedList();
source(function(tiddler,title) {
results.pushTop(options.wiki.getTiddlerTranscludes(title));
});
return results.makeTiddlerIterator(options.wiki);
};
})();

View File

@@ -202,7 +202,7 @@ Extended filter operators to manipulate the current list.
} }
if(resultsIndex !== -1) { if(resultsIndex !== -1) {
i = i + step; i = i + step;
nextOperandIndex = (i < opLength ? i : i % opLength); nextOperandIndex = (i < opLength ? i : i - opLength);
if(operands.length > 1) { if(operands.length > 1) {
results.splice(resultsIndex,1,operands[nextOperandIndex]); results.splice(resultsIndex,1,operands[nextOperandIndex]);
} else { } else {

View File

@@ -1,122 +0,0 @@
/*\
title: $:/core/modules/indexers/back-indexer.js
type: application/javascript
module-type: indexer
By parsing the tiddler text, indexes the tiddlers' back links, back transclusions, block level back links.
\*/
function BackIndexer(wiki) {
this.wiki = wiki;
}
BackIndexer.prototype.init = function() {
this.subIndexers = {
link: new BackSubIndexer(this,"extractLinks"),
transclude: new BackSubIndexer(this,"extractTranscludes"),
};
};
BackIndexer.prototype.rebuild = function() {
$tw.utils.each(this.subIndexers,function(subIndexer) {
subIndexer.rebuild();
});
};
BackIndexer.prototype.update = function(updateDescriptor) {
$tw.utils.each(this.subIndexers,function(subIndexer) {
subIndexer.update(updateDescriptor);
});
};
function BackSubIndexer(indexer,extractor) {
this.wiki = indexer.wiki;
this.indexer = indexer;
this.extractor = extractor;
/**
* {
* [target title, e.g. tiddler title being linked to]:
* {
* [source title, e.g. tiddler title that has link syntax in its text]: true
* }
* }
*/
this.index = null;
}
BackSubIndexer.prototype.init = function() {
// lazy init until first lookup
this.index = null;
}
BackSubIndexer.prototype._init = function() {
this.index = Object.create(null);
var self = this;
this.wiki.forEachTiddler(function(sourceTitle,tiddler) {
var newTargets = self._getTarget(tiddler);
$tw.utils.each(newTargets, function(target) {
if(!self.index[target]) {
self.index[target] = Object.create(null);
}
self.index[target][sourceTitle] = true;
});
});
}
BackSubIndexer.prototype.rebuild = function() {
this.index = null;
}
/*
* Get things that is being referenced in the text, e.g. tiddler names in the link syntax.
*/
BackSubIndexer.prototype._getTarget = function(tiddler) {
if(this.wiki.isBinaryTiddler(tiddler.fields.text)) {
return [];
}
var parser = this.wiki.parseText(tiddler.fields.type, tiddler.fields.text, {});
if(parser) {
return this.wiki[this.extractor](parser.tree, tiddler.fields.title);
}
return [];
}
BackSubIndexer.prototype.update = function(updateDescriptor) {
// lazy init/update until first lookup
if(!this.index) {
return;
}
var newTargets = [],
oldTargets = [],
self = this;
if(updateDescriptor.old.exists) {
oldTargets = this._getTarget(updateDescriptor.old.tiddler);
}
if(updateDescriptor.new.exists) {
newTargets = this._getTarget(updateDescriptor.new.tiddler);
}
$tw.utils.each(oldTargets,function(target) {
if(self.index[target]) {
delete self.index[target][updateDescriptor.old.tiddler.fields.title];
}
});
$tw.utils.each(newTargets,function(target) {
if(!self.index[target]) {
self.index[target] = Object.create(null);
}
self.index[target][updateDescriptor.new.tiddler.fields.title] = true;
});
}
BackSubIndexer.prototype.lookup = function(title) {
if(!this.index) {
this._init();
}
if(this.index[title]) {
return Object.keys(this.index[title]);
} else {
return [];
}
}
exports.BackIndexer = BackIndexer;

View File

@@ -0,0 +1,86 @@
/*\
title: $:/core/modules/indexers/backlinks-indexer.js
type: application/javascript
module-type: indexer
Indexes the tiddlers' backlinks
\*/
(function(){
/*jslint node: true, browser: true */
/*global modules: false */
"use strict";
function BacklinksIndexer(wiki) {
this.wiki = wiki;
}
BacklinksIndexer.prototype.init = function() {
this.index = null;
}
BacklinksIndexer.prototype.rebuild = function() {
this.index = null;
}
BacklinksIndexer.prototype._getLinks = function(tiddler) {
var parser = this.wiki.parseText(tiddler.fields.type, tiddler.fields.text, {});
if(parser) {
return this.wiki.extractLinks(parser.tree);
}
return [];
}
BacklinksIndexer.prototype.update = function(updateDescriptor) {
if(!this.index) {
return;
}
var newLinks = [],
oldLinks = [],
self = this;
if(updateDescriptor.old.exists) {
oldLinks = this._getLinks(updateDescriptor.old.tiddler);
}
if(updateDescriptor.new.exists) {
newLinks = this._getLinks(updateDescriptor.new.tiddler);
}
$tw.utils.each(oldLinks,function(link) {
if(self.index[link]) {
delete self.index[link][updateDescriptor.old.tiddler.fields.title];
}
});
$tw.utils.each(newLinks,function(link) {
if(!self.index[link]) {
self.index[link] = Object.create(null);
}
self.index[link][updateDescriptor.new.tiddler.fields.title] = true;
});
}
BacklinksIndexer.prototype.lookup = function(title) {
if(!this.index) {
this.index = Object.create(null);
var self = this;
this.wiki.forEachTiddler(function(title,tiddler) {
var links = self._getLinks(tiddler);
$tw.utils.each(links, function(link) {
if(!self.index[link]) {
self.index[link] = Object.create(null);
}
self.index[link][title] = true;
});
});
}
if(this.index[title]) {
return Object.keys(this.index[title]);
} else {
return [];
}
}
exports.BacklinksIndexer = BacklinksIndexer;
})();

View File

@@ -35,11 +35,9 @@ exports.run = function(filter,format) {
// Collect all the fields // Collect all the fields
for(t=0;t<tiddlers.length; t++) { for(t=0;t<tiddlers.length; t++) {
tiddler = this.wiki.getTiddler(tiddlers[t]); tiddler = this.wiki.getTiddler(tiddlers[t]);
if(tiddler) { for(f in tiddler.fields) {
for(f in tiddler.fields) { if(fields.indexOf(f) === -1) {
if(fields.indexOf(f) === -1) { fields.push(f);
fields.push(f);
}
} }
} }
} }
@@ -62,10 +60,8 @@ exports.run = function(filter,format) {
for(var t=0;t<tiddlers.length; t++) { for(var t=0;t<tiddlers.length; t++) {
row = []; row = [];
tiddler = this.wiki.getTiddler(tiddlers[t]); tiddler = this.wiki.getTiddler(tiddlers[t]);
if(tiddler) { for(f=0; f<fields.length; f++) {
for(f=0; f<fields.length; f++) { row.push(quoteAndEscape(tiddler ? tiddler.getFieldString(fields[f]) || "" : ""));
row.push(quoteAndEscape(tiddler ? tiddler.getFieldString(fields[f]) || "" : ""));
}
} }
output.push(row.join(",")); output.push(row.join(","));
} }

View File

@@ -114,7 +114,7 @@ exports.parseStringLiteral = function(source,pos) {
var match = reString.exec(source); var match = reString.exec(source);
if(match && match.index === pos) { if(match && match.index === pos) {
node.value = match[1] !== undefined ? match[1] :( node.value = match[1] !== undefined ? match[1] :(
match[2] !== undefined ? match[2] : match[3] match[2] !== undefined ? match[2] : match[3]
); );
node.end = pos + match[0].length; node.end = pos + match[0].length;
return node; return node;

View File

@@ -14,12 +14,10 @@ The plain text parser processes blocks of source text into a degenerate parse tr
var TextParser = function(type,text,options) { var TextParser = function(type,text,options) {
this.tree = [{ this.tree = [{
type: "genesis", type: "codeblock",
attributes: { attributes: {
$type: {name: "$type", type: "string", value: "$codeblock"}, code: {type: "string", value: text},
code: {name: "code", type: "string", value: text}, language: {type: "string", value: type}
language: {name: "language", type: "string", value: type},
$remappable: {name: "$remappable", type:"string", value: "no"}
} }
}]; }];
this.source = text; this.source = text;
@@ -34,3 +32,4 @@ exports["text/css"] = TextParser;
exports["application/x-tiddler-dictionary"] = TextParser; exports["application/x-tiddler-dictionary"] = TextParser;
})(); })();

View File

@@ -29,16 +29,13 @@ exports.init = function(parser) {
exports.parse = function() { exports.parse = function() {
var reEnd = /(\r?\n```$)/mg; var reEnd = /(\r?\n```$)/mg;
var languageStart = this.parser.pos + 3,
languageEnd = languageStart + this.match[1].length;
// Move past the match // Move past the match
this.parser.pos = this.matchRegExp.lastIndex; this.parser.pos = this.matchRegExp.lastIndex;
// Look for the end of the block // Look for the end of the block
reEnd.lastIndex = this.parser.pos; reEnd.lastIndex = this.parser.pos;
var match = reEnd.exec(this.parser.source), var match = reEnd.exec(this.parser.source),
text, text;
codeStart = this.parser.pos;
// Process the block // Process the block
if(match) { if(match) {
text = this.parser.source.substring(this.parser.pos,match.index); text = this.parser.source.substring(this.parser.pos,match.index);
@@ -51,8 +48,8 @@ exports.parse = function() {
return [{ return [{
type: "codeblock", type: "codeblock",
attributes: { attributes: {
code: {type: "string", value: text, start: codeStart, end: this.parser.pos}, code: {type: "string", value: text},
language: {type: "string", value: this.match[1], start: languageStart, end: languageEnd} language: {type: "string", value: this.match[1]}
} }
}]; }];
}; };

View File

@@ -33,8 +33,7 @@ exports.parse = function() {
// Look for the end marker // Look for the end marker
reEnd.lastIndex = this.parser.pos; reEnd.lastIndex = this.parser.pos;
var match = reEnd.exec(this.parser.source), var match = reEnd.exec(this.parser.source),
text, text;
start = this.parser.pos;
// Process the text // Process the text
if(match) { if(match) {
text = this.parser.source.substring(this.parser.pos,match.index); text = this.parser.source.substring(this.parser.pos,match.index);
@@ -48,9 +47,7 @@ exports.parse = function() {
tag: "code", tag: "code",
children: [{ children: [{
type: "text", type: "text",
text: text, text: text
start: start,
end: this.parser.pos
}] }]
}]; }];
}; };

View File

@@ -31,7 +31,6 @@ exports.init = function(parser) {
exports.parse = function() { exports.parse = function() {
// Move past the match // Move past the match
var start = this.parser.pos;
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) === "~") {
@@ -47,7 +46,7 @@ exports.parse = function() {
rel: {type: "string", value: "noopener noreferrer"} rel: {type: "string", value: "noopener noreferrer"}
}, },
children: [{ children: [{
type: "text", text: this.match[0], start: start, end: this.parser.pos type: "text", text: this.match[0]
}] }]
}]; }];
} }

View File

@@ -31,16 +31,6 @@ exports.init = function(parser) {
exports.parse = function() { exports.parse = function() {
// Move past the match // Move past the match
var filterStart = this.parser.pos + 3;
var filterEnd = filterStart + this.match[1].length;
var toolTipStart = filterEnd + 1;
var toolTipEnd = toolTipStart + (this.match[2] ? this.match[2].length : 0);
var templateStart = toolTipEnd + 2;
var templateEnd = templateStart + (this.match[3] ? this.match[3].length : 0);
var styleStart = templateEnd + 2;
var styleEnd = styleStart + (this.match[4] ? this.match[4].length : 0);
var classesStart = styleEnd + 1;
var classesEnd = classesStart + (this.match[5] ? this.match[5].length : 0);
this.parser.pos = this.matchRegExp.lastIndex; this.parser.pos = this.matchRegExp.lastIndex;
// Get the match details // Get the match details
var filter = this.match[1], var filter = this.match[1],
@@ -52,21 +42,21 @@ exports.parse = function() {
var node = { var node = {
type: "list", type: "list",
attributes: { attributes: {
filter: {type: "string", value: filter, start: filterStart, end: filterEnd}, filter: {type: "string", value: filter}
}, },
isBlock: true isBlock: true
}; };
if(tooltip) { if(tooltip) {
node.attributes.tooltip = {type: "string", value: tooltip, start: toolTipStart, end: toolTipEnd}; node.attributes.tooltip = {type: "string", value: tooltip};
} }
if(template) { if(template) {
node.attributes.template = {type: "string", value: template, start: templateStart, end: templateEnd}; node.attributes.template = {type: "string", value: template};
} }
if(style) { if(style) {
node.attributes.style = {type: "string", value: style, start: styleStart, end: styleEnd}; node.attributes.style = {type: "string", value: style};
} }
if(classes) { if(classes) {
node.attributes.itemClass = {type: "string", value: classes.split(".").join(" "), start: classesStart, end: classesEnd}; node.attributes.itemClass = {type: "string", value: classes.split(".").join(" ")};
} }
return [node]; return [node];
}; };

View File

@@ -30,16 +30,6 @@ exports.init = function(parser) {
}; };
exports.parse = function() { exports.parse = function() {
var filterStart = this.parser.pos + 3;
var filterEnd = filterStart + this.match[1].length;
var toolTipStart = filterEnd + 1;
var toolTipEnd = toolTipStart + (this.match[2] ? this.match[2].length : 0);
var templateStart = toolTipEnd + 2;
var templateEnd = templateStart + (this.match[3] ? this.match[3].length : 0);
var styleStart = templateEnd + 2;
var styleEnd = styleStart + (this.match[4] ? this.match[4].length : 0);
var classesStart = styleEnd + 1;
var classesEnd = classesStart + (this.match[5] ? this.match[5].length : 0);
// Move past the match // Move past the match
this.parser.pos = this.matchRegExp.lastIndex; this.parser.pos = this.matchRegExp.lastIndex;
// Get the match details // Get the match details
@@ -52,20 +42,20 @@ exports.parse = function() {
var node = { var node = {
type: "list", type: "list",
attributes: { attributes: {
filter: {type: "string", value: filter, start: filterStart, end: filterEnd}, filter: {type: "string", value: filter}
} }
}; };
if(tooltip) { if(tooltip) {
node.attributes.tooltip = {type: "string", value: tooltip, start: toolTipStart, end: toolTipEnd}; node.attributes.tooltip = {type: "string", value: tooltip};
} }
if(template) { if(template) {
node.attributes.template = {type: "string", value: template, start: templateStart, end: templateEnd}; node.attributes.template = {type: "string", value: template};
} }
if(style) { if(style) {
node.attributes.style = {type: "string", value: style, start: styleStart, end: styleEnd}; node.attributes.style = {type: "string", value: style};
} }
if(classes) { if(classes) {
node.attributes.itemClass = {type: "string", value: classes.split(".").join(" "), start: classesStart, end: classesEnd}; node.attributes.itemClass = {type: "string", value: classes.split(".").join(" ")};
} }
return [node]; return [node];
}; };

View File

@@ -49,11 +49,11 @@ exports.parse = function() {
if(this.match[3]) { if(this.match[3]) {
params = $tw.utils.parseParameterDefinition(this.match[4]); params = $tw.utils.parseParameterDefinition(this.match[4]);
} }
// Is the remainder of the line blank after the parameter close paren? // Is this a multiline definition?
var reEnd; var reEnd;
if(this.match[5]) { if(this.match[5]) {
// If so, it is a multiline definition and the end of the body is marked with \end // If so, the end of the body is marked with \end
reEnd = new RegExp("((:?^|\\r?\\n)[^\\S\\n\\r]*\\\\end[^\\S\\n\\r]*(?:" + $tw.utils.escapeRegExp(this.match[2]) + ")?(?:$|\\r?\\n))","mg"); reEnd = new RegExp("(\\r?\\n[^\\S\\n\\r]*\\\\end[^\\S\\n\\r]*(?:" + $tw.utils.escapeRegExp(this.match[2]) + ")?(?:$|\\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
reEnd = /($|\r?\n)/mg; reEnd = /($|\r?\n)/mg;

View File

@@ -45,11 +45,10 @@ exports.parse = function() {
reEnd.lastIndex = this.parser.pos; reEnd.lastIndex = this.parser.pos;
match = reEnd.exec(this.parser.source); match = reEnd.exec(this.parser.source);
if(match) { if(match) {
var start = this.parser.pos;
this.parser.pos = reEnd.lastIndex; this.parser.pos = reEnd.lastIndex;
// Add a line break if the terminator was a line break // Add a line break if the terminator was a line break
if(match[2]) { if(match[2]) {
tree.push({type: "element", tag: "br", start: start, end: this.parser.pos}); tree.push({type: "element", tag: "br"});
} }
} }
} while(match && !match[1]); } while(match && !match[1]);

View File

@@ -30,17 +30,15 @@ exports.parse = function() {
// Move past the !s // Move past the !s
this.parser.pos = this.matchRegExp.lastIndex; this.parser.pos = this.matchRegExp.lastIndex;
// Parse any classes, whitespace and then the heading itself // Parse any classes, whitespace and then the heading itself
var classStart = this.parser.pos;
var classes = this.parser.parseClasses(); var classes = this.parser.parseClasses();
var classEnd = this.parser.pos;
this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true}); this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});
var tree = this.parser.parseInlineRun(/(\r?\n)/mg); var tree = this.parser.parseInlineRun(/(\r?\n)/mg);
// Return the heading // Return the heading
return [{ return [{
type: "element", type: "element",
tag: "h" + headingLevel, tag: "h" + headingLevel,
attributes: { attributes: {
"class": {type: "string", value: classes.join(" "), start: classStart, end: classEnd} "class": {type: "string", value: classes.join(" ")}
}, },
children: tree children: tree
}]; }];

View File

@@ -44,10 +44,6 @@ Parse the most recent match
exports.parse = function() { exports.parse = function() {
// Retrieve the most recent match so that recursive calls don't overwrite it // Retrieve the most recent match so that recursive calls don't overwrite it
var tag = this.nextTag; var tag = this.nextTag;
if (!tag.isSelfClosing) {
tag.openTagStart = tag.start;
tag.openTagEnd = tag.end;
}
this.nextTag = null; this.nextTag = null;
// 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;
@@ -64,27 +60,6 @@ exports.parse = function() {
var reEnd = new RegExp("(" + reEndString + ")","mg"); var reEnd = new RegExp("(" + reEndString + ")","mg");
tag.children = this.parser.parseInlineRun(reEnd,{eatTerminator: true}); tag.children = this.parser.parseInlineRun(reEnd,{eatTerminator: true});
} }
tag.end = this.parser.pos;
tag.closeTagEnd = tag.end;
if (tag.closeTagEnd === tag.openTagEnd || this.parser.source[tag.closeTagEnd - 1] !== '>') {
tag.closeTagStart = tag.end;
} else {
tag.closeTagStart = tag.closeTagEnd - 2;
var closeTagMinPos = tag.children.length > 0 ? tag.children[tag.children.length-1].end : tag.openTagEnd;
if (!Number.isSafeInteger(closeTagMinPos)) closeTagMinPos = tag.openTagEnd;
while (tag.closeTagStart >= closeTagMinPos) {
var char = this.parser.source[tag.closeTagStart];
if (char === '>') {
tag.closeTagStart = -1;
break;
}
if (char === '<') break;
tag.closeTagStart -= 1;
}
if (tag.closeTagStart < closeTagMinPos) {
tag.closeTagStart = tag.end;
}
}
} }
// Return the tag // Return the tag
return [tag]; return [tag];

View File

@@ -122,9 +122,9 @@ exports.parseImage = function(source,pos) {
} }
pos = token.end; pos = token.end;
if(token.match[1]) { if(token.match[1]) {
node.attributes.tooltip = {type: "string", value: token.match[1].trim(),start: token.start,end:token.start + token.match[1].length - 1}; node.attributes.tooltip = {type: "string", value: token.match[1].trim()};
} }
node.attributes.source = {type: "string", value: (token.match[2] || "").trim(), start: token.start + (token.match[1] ? token.match[1].length : 0), end: token.end - 2}; node.attributes.source = {type: "string", value: (token.match[2] || "").trim()};
// Update the end position // Update the end position
node.end = pos; node.end = pos;
return node; return node;

View File

@@ -38,14 +38,13 @@ exports.parse = function() {
// Parse the filter terminated by a line break // Parse the filter terminated by a line break
var reMatch = /(.*)(?:$|\r?\n)/mg; var reMatch = /(.*)(?:$|\r?\n)/mg;
reMatch.lastIndex = this.parser.pos; reMatch.lastIndex = this.parser.pos;
var filterStart = this.parser.source;
var match = reMatch.exec(this.parser.source); var match = reMatch.exec(this.parser.source);
this.parser.pos = reMatch.lastIndex; this.parser.pos = reMatch.lastIndex;
// Parse tree nodes to return // Parse tree nodes to return
return [{ return [{
type: "importvariables", type: "importvariables",
attributes: { attributes: {
filter: {type: "string", value: match[1], start: filterStart, end: this.parser.pos} filter: {type: "string", value: match[1]}
}, },
children: [] children: []
}]; }];

View File

@@ -74,7 +74,6 @@ exports.parse = function() {
// Match the list marker // Match the list marker
var reMatch = /([\*#;:>]+)/mg; var reMatch = /([\*#;:>]+)/mg;
reMatch.lastIndex = this.parser.pos; reMatch.lastIndex = this.parser.pos;
var start = this.parser.pos;
var match = reMatch.exec(this.parser.source); var match = reMatch.exec(this.parser.source);
if(!match || match.index !== this.parser.pos) { if(!match || match.index !== this.parser.pos) {
break; break;
@@ -95,21 +94,9 @@ exports.parse = function() {
} }
// Construct the list element or reuse the previous one at this level // Construct the list element or reuse the previous one at this level
if(listStack.length <= t) { if(listStack.length <= t) {
var listElement = { var listElement = {type: "element", tag: listInfo.listTag, children: [
type: "element", {type: "element", tag: listInfo.itemTag, children: []}
tag: listInfo.listTag, ]};
children: [
{
type: "element",
tag: listInfo.itemTag,
children: [],
start: start,
end: this.parser.pos,
}
],
start: start,
end: this.parser.pos,
};
// Link this list element into the last child item of the parent list item // Link this list element into the last child item of the parent list item
if(t) { if(t) {
var prevListItem = listStack[t-1].children[listStack[t-1].children.length-1]; var prevListItem = listStack[t-1].children[listStack[t-1].children.length-1];
@@ -118,33 +105,21 @@ exports.parse = function() {
// Save this element in the stack // Save this element in the stack
listStack[t] = listElement; listStack[t] = listElement;
} else if(t === (match[0].length - 1)) { } else if(t === (match[0].length - 1)) {
listStack[t].children.push({ listStack[t].children.push({type: "element", tag: listInfo.itemTag, children: []});
type: "element",
tag: listInfo.itemTag,
children: [],
start: start,
end: this.parser.pos,
});
} }
} }
if(listStack.length > match[0].length) { if(listStack.length > match[0].length) {
listStack.splice(match[0].length,listStack.length - match[0].length); listStack.splice(match[0].length,listStack.length - match[0].length);
} }
// Process the body of the list item into the last list item // Process the body of the list item into the last list item
var classStart = this.parser.pos;
var lastListChildren = listStack[listStack.length-1].children, var lastListChildren = listStack[listStack.length-1].children,
lastListItem = lastListChildren[lastListChildren.length-1], lastListItem = lastListChildren[lastListChildren.length-1],
classes = this.parser.parseClasses(); classes = this.parser.parseClasses();
var classEnd = this.parser.pos;
this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true}); this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});
var tree = this.parser.parseInlineRun(/(\r?\n)/mg); var tree = this.parser.parseInlineRun(/(\r?\n)/mg);
lastListItem.children.push.apply(lastListItem.children,tree); lastListItem.children.push.apply(lastListItem.children,tree);
lastListItem.end = this.parser.pos;
listStack[listStack.length-1].end = this.parser.pos;
if(classes.length > 0) { if(classes.length > 0) {
$tw.utils.addClassToParseTreeNode(lastListItem,classes.join(" ")); $tw.utils.addClassToParseTreeNode(lastListItem,classes.join(" "));
lastListItem.attributes.class.start = classStart;
lastListItem.attributes.class.end = classEnd;
} }
// Consume any whitespace following the list item // Consume any whitespace following the list item
this.parser.skipWhitespace(); this.parser.skipWhitespace();

View File

@@ -54,11 +54,11 @@ exports.parse = function() {
paramMatch = reParam.exec(paramString); paramMatch = reParam.exec(paramString);
} }
} }
// Is the remainder of the \define line blank after the parameter close paren? // Is this a multiline definition?
var reEnd; var reEnd;
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, the end of the body is marked with \end
reEnd = new RegExp("((?:^|\\r?\\n)[^\\S\\n\\r]*\\\\end[^\\S\\n\\r]*(?:" + $tw.utils.escapeRegExp(this.match[1]) + ")?(?:$|\\r?\\n))","mg"); reEnd = new RegExp("(\\r?\\n[^\\S\\n\\r]*\\\\end[^\\S\\n\\r]*(?:" + $tw.utils.escapeRegExp(this.match[1]) + ")?(?:$|\\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
reEnd = /($|\r?\n)/mg; reEnd = /($|\r?\n)/mg;

View File

@@ -96,20 +96,15 @@ exports.parseLink = function(source,pos) {
splitPos = null; splitPos = null;
} }
// Pull out the tooltip and URL // Pull out the tooltip and URL
var tooltip, URL, urlStart; var tooltip, URL;
textNode.start = pos;
if(splitPos) { if(splitPos) {
urlStart = splitPos + 1;
URL = source.substring(splitPos + 1,closePos).trim(); URL = source.substring(splitPos + 1,closePos).trim();
textNode.text = source.substring(pos,splitPos).trim(); textNode.text = source.substring(pos,splitPos).trim();
textNode.end = splitPos;
} else { } else {
urlStart = pos;
URL = source.substring(pos,closePos).trim(); URL = source.substring(pos,closePos).trim();
textNode.text = URL; textNode.text = URL;
textNode.end = closePos;
} }
node.attributes.href = {type: "string", value: URL, start: urlStart, end: closePos}; node.attributes.href = {type: "string", value: URL};
node.attributes.target = {type: "string", value: "_blank"}; node.attributes.target = {type: "string", value: "_blank"};
node.attributes.rel = {type: "string", value: "noopener noreferrer"}; node.attributes.rel = {type: "string", value: "noopener noreferrer"};
// Update the end position // Update the end position

View File

@@ -29,39 +29,32 @@ exports.init = function(parser) {
exports.parse = function() { exports.parse = function() {
// Move past the match // Move past the match
var start = this.parser.pos + 2;
this.parser.pos = this.matchRegExp.lastIndex; this.parser.pos = this.matchRegExp.lastIndex;
// Process the link // Process the link
var text = this.match[1], var text = this.match[1],
link = this.match[2] || text, link = this.match[2] || text;
textEndPos = this.parser.source.indexOf("|", start);
if (textEndPos < 0 || textEndPos > this.matchRegExp.lastIndex) {
textEndPos = this.matchRegExp.lastIndex - 2;
}
var linkStart = this.match[2] ? (start + this.match[1].length + 1) : start;
var linkEnd = linkStart + link.length;
if($tw.utils.isLinkExternal(link)) { if($tw.utils.isLinkExternal(link)) {
return [{ return [{
type: "element", type: "element",
tag: "a", tag: "a",
attributes: { attributes: {
href: {type: "string", value: link, start: linkStart, end: linkEnd}, href: {type: "string", value: link},
"class": {type: "string", value: "tc-tiddlylink-external"}, "class": {type: "string", value: "tc-tiddlylink-external"},
target: {type: "string", value: "_blank"}, target: {type: "string", value: "_blank"},
rel: {type: "string", value: "noopener noreferrer"} rel: {type: "string", value: "noopener noreferrer"}
}, },
children: [{ children: [{
type: "text", text: text, start: start, end: textEndPos type: "text", text: text
}] }]
}]; }];
} else { } else {
return [{ return [{
type: "link", type: "link",
attributes: { attributes: {
to: {type: "string", value: link, start: linkStart, end: linkEnd} to: {type: "string", value: link}
}, },
children: [{ children: [{
type: "text", text: text, start: start, end: textEndPos type: "text", text: text
}] }]
}]; }];
} }

View File

@@ -3,7 +3,30 @@ title: $:/core/modules/parsers/wikiparser/rules/quoteblock.js
type: application/javascript type: application/javascript
module-type: wikirule module-type: wikirule
Wiki text rule for quote blocks. Wiki text rule for quote blocks. For example:
```
<<<.optionalClass(es) optional cited from
a quote
<<<
<<<.optionalClass(es)
a quote
<<< optional cited from
```
Quotes can be quoted by putting more <s
```
<<<
Quote Level 1
<<<<
QuoteLevel 2
<<<<
<<<
```
\*/ \*/
(function(){ (function(){
@@ -24,42 +47,33 @@ exports.init = function(parser) {
exports.parse = function() { exports.parse = function() {
var classes = ["tc-quote"]; var classes = ["tc-quote"];
// Get all the details of the match // Get all the details of the match
var reEndString = "^\\s*" + this.match[1] + "(?!<)"; var reEndString = "^" + this.match[1] + "(?!<)";
// Move past the <s // Move past the <s
this.parser.pos = this.matchRegExp.lastIndex; this.parser.pos = this.matchRegExp.lastIndex;
// Parse any classes, whitespace and then the optional cite itself // Parse any classes, whitespace and then the optional cite itself
var classStart = this.parser.pos;
classes.push.apply(classes, this.parser.parseClasses()); classes.push.apply(classes, this.parser.parseClasses());
var classEnd = this.parser.pos;
this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true}); this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});
var citeStart = this.parser.pos;
var cite = this.parser.parseInlineRun(/(\r?\n)/mg); var cite = this.parser.parseInlineRun(/(\r?\n)/mg);
var citeEnd = this.parser.pos;
// before handling the cite, parse the body of the quote // before handling the cite, parse the body of the quote
var tree = this.parser.parseBlocks(reEndString); var tree= this.parser.parseBlocks(reEndString);
// If we got a cite, put it before the text // If we got a cite, put it before the text
if(cite.length > 0) { if(cite.length > 0) {
tree.unshift({ tree.unshift({
type: "element", type: "element",
tag: "cite", tag: "cite",
children: cite, children: cite
start: citeStart,
end: citeEnd
}); });
} }
// Parse any optional cite // Parse any optional cite
this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true}); this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});
citeStart = this.parser.pos;
cite = this.parser.parseInlineRun(/(\r?\n)/mg); cite = this.parser.parseInlineRun(/(\r?\n)/mg);
citeEnd = this.parser.pos;
// If we got a cite, push it // If we got a cite, push it
if(cite.length > 0) { if(cite.length > 0) {
tree.push({ tree.push({
type: "element", type: "element",
tag: "cite", tag: "cite",
children: cite, children: cite
start: citeStart,
end: citeEnd
}); });
} }
// Return the blockquote element // Return the blockquote element
@@ -67,7 +81,7 @@ exports.parse = function() {
type: "element", type: "element",
tag: "blockquote", tag: "blockquote",
attributes: { attributes: {
class: { type: "string", value: classes.join(" "), start: classStart, end: classEnd }, class: { type: "string", value: classes.join(" ") },
}, },
children: tree children: tree
}]; }];

View File

@@ -29,11 +29,10 @@ exports.init = function(parser) {
exports.parse = function() { exports.parse = function() {
var match = this.match[0]; var match = this.match[0];
// Move past the match // Move past the match
var start = this.parser.pos;
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(match.substr(0,1) === "~") { if(match.substr(0,1) === "~") {
return [{type: "text", text: match.substr(1), start: start+1, end: this.parser.pos}]; return [{type: "text", text: match.substr(1)}];
} else { } else {
return [{ return [{
type: "link", type: "link",
@@ -42,12 +41,10 @@ exports.parse = function() {
}, },
children: [{ children: [{
type: "text", type: "text",
text: match, text: match
start: start,
end: this.parser.pos
}] }]
}]; }];
} }
}; };
})(); })();

View File

@@ -93,12 +93,11 @@ var processRow = function(prevColumns) {
} }
// Check whether this is a heading cell // Check whether this is a heading cell
var cell; var cell;
var start = this.parser.pos;
if(chr === "!") { if(chr === "!") {
this.parser.pos++; this.parser.pos++;
cell = {type: "element", tag: "th", start: start, children: []}; cell = {type: "element", tag: "th", children: []};
} else { } else {
cell = {type: "element", tag: "td", start: start, children: []}; cell = {type: "element", tag: "td", children: []};
} }
tree.push(cell); tree.push(cell);
// Record information about this cell // Record information about this cell
@@ -122,7 +121,6 @@ var processRow = function(prevColumns) {
} }
// Move back to the closing `|` // Move back to the closing `|`
this.parser.pos--; this.parser.pos--;
cell.end = this.parser.pos;
} }
col++; col++;
cellRegExp.lastIndex = this.parser.pos; cellRegExp.lastIndex = this.parser.pos;
@@ -152,7 +150,7 @@ exports.parse = function() {
} else { } else {
// Otherwise, create a new row if this one is of a different type // Otherwise, create a new row if this one is of a different type
if(rowType !== currRowType) { if(rowType !== currRowType) {
rowContainer = {type: "element", tag: rowContainerTypes[rowType], children: [], start: this.parser.pos, end: this.parser.pos}; rowContainer = {type: "element", tag: rowContainerTypes[rowType], children: []};
table.children.push(rowContainer); table.children.push(rowContainer);
currRowType = rowType; currRowType = rowType;
} }
@@ -171,17 +169,15 @@ exports.parse = function() {
rowContainer.children = this.parser.parseInlineRun(rowTermRegExp,{eatTerminator: true}); rowContainer.children = this.parser.parseInlineRun(rowTermRegExp,{eatTerminator: true});
} else { } else {
// Create the row // Create the row
var theRow = {type: "element", tag: "tr", children: [], start: rowMatch.index}; var theRow = {type: "element", tag: "tr", children: []};
$tw.utils.addClassToParseTreeNode(theRow,rowCount%2 ? "oddRow" : "evenRow"); $tw.utils.addClassToParseTreeNode(theRow,rowCount%2 ? "oddRow" : "evenRow");
rowContainer.children.push(theRow); rowContainer.children.push(theRow);
// Process the row // Process the row
theRow.children = processRow.call(this,prevColumns); theRow.children = processRow.call(this,prevColumns);
this.parser.pos = rowMatch.index + rowMatch[0].length; this.parser.pos = rowMatch.index + rowMatch[0].length;
theRow.end = this.parser.pos;
// Increment the row count // Increment the row count
rowCount++; rowCount++;
} }
rowContainer.end = this.parser.pos;
} }
rowMatch = rowRegExp.exec(this.parser.source); rowMatch = rowRegExp.exec(this.parser.source);
} }

View File

@@ -81,6 +81,9 @@ exports.parse = function() {
} }
return [tiddlerNode]; return [tiddlerNode];
} else { } else {
// No template or text reference is provided, so we'll use a blank target. Otherwise we'll generate
// a transclude widget that transcludes the current tiddler, often leading to recursion errors
transcludeNode.attributes["$tiddler"] = {name: "$tiddler", type: "string", value: ""};
return [transcludeNode]; return [transcludeNode];
} }
} }

View File

@@ -79,6 +79,9 @@ exports.parse = function() {
} }
return [tiddlerNode]; return [tiddlerNode];
} else { } else {
// No template or text reference is provided, so we'll use a blank target. Otherwise we'll generate
// a transclude widget that transcludes the current tiddler, often leading to recursion errors
transcludeNode.attributes["$tiddler"] = {name: "$tiddler", type: "string", value: ""};
return [transcludeNode]; return [transcludeNode];
} }
} }

View File

@@ -46,7 +46,6 @@ exports.parse = function() {
renderType = this.match[2]; renderType = this.match[2];
// Move past the match // Move past the match
this.parser.pos = this.matchRegExp.lastIndex; this.parser.pos = this.matchRegExp.lastIndex;
var start = this.parser.pos;
// Look for the end of the block // Look for the end of the block
reEnd.lastIndex = this.parser.pos; reEnd.lastIndex = this.parser.pos;
var match = reEnd.exec(this.parser.source), var match = reEnd.exec(this.parser.source),
@@ -75,9 +74,7 @@ exports.parse = function() {
tag: "pre", tag: "pre",
children: [{ children: [{
type: "text", type: "text",
text: text, text: text
start: start,
end: this.parser.pos
}] }]
}]; }];
} }

View File

@@ -36,7 +36,6 @@ exports.parse = function() {
// Get the details of the match // Get the details of the match
var linkText = this.match[0]; var linkText = this.match[0];
// Move past the macro call // Move past the macro call
var start = this.parser.pos;
this.parser.pos = this.matchRegExp.lastIndex; this.parser.pos = this.matchRegExp.lastIndex;
// If the link starts with the unwikilink character then just output it as plain text // If the link starts with the unwikilink character then just output it as plain text
if(linkText.substr(0,1) === $tw.config.textPrimitives.unWikiLink) { if(linkText.substr(0,1) === $tw.config.textPrimitives.unWikiLink) {
@@ -58,9 +57,7 @@ exports.parse = function() {
}, },
children: [{ children: [{
type: "text", type: "text",
text: linkText, text: linkText
start: start,
end: this.parser.pos
}] }]
}]; }];
}; };

View File

@@ -91,11 +91,6 @@ var WikiParser = function(type,text,options) {
} else { } else {
topBranch.push.apply(topBranch,this.parseBlocks()); topBranch.push.apply(topBranch,this.parseBlocks());
} }
// Build rules' name map
this.usingRuleMap = {};
$tw.utils.each(this.pragmaRules, function (ruleInfo) { self.usingRuleMap[ruleInfo.rule.name] = Object.getPrototypeOf(ruleInfo.rule); });
$tw.utils.each(this.blockRules, function (ruleInfo) { self.usingRuleMap[ruleInfo.rule.name] = Object.getPrototypeOf(ruleInfo.rule); });
$tw.utils.each(this.inlineRules, function (ruleInfo) { self.usingRuleMap[ruleInfo.rule.name] = Object.getPrototypeOf(ruleInfo.rule); });
// Return the parse tree // Return the parse tree
}; };
@@ -199,7 +194,6 @@ Parse any pragmas at the beginning of a block of parse text
WikiParser.prototype.parsePragmas = function() { WikiParser.prototype.parsePragmas = function() {
var currentTreeBranch = this.tree; var currentTreeBranch = this.tree;
while(true) { while(true) {
var savedPos = this.pos;
// Skip whitespace // Skip whitespace
this.skipWhitespace(); this.skipWhitespace();
// Check for the end of the text // Check for the end of the text
@@ -210,24 +204,16 @@ WikiParser.prototype.parsePragmas = function() {
var nextMatch = this.findNextMatch(this.pragmaRules,this.pos); var nextMatch = this.findNextMatch(this.pragmaRules,this.pos);
// If not, just exit // If not, just exit
if(!nextMatch || nextMatch.matchIndex !== this.pos) { if(!nextMatch || nextMatch.matchIndex !== this.pos) {
this.pos = savedPos;
break; break;
} }
// Process the pragma rule // Process the pragma rule
var start = this.pos;
var subTree = nextMatch.rule.parse(); var subTree = nextMatch.rule.parse();
if(subTree.length > 0) { if(subTree.length > 0) {
// Set the start and end positions of the pragma rule if
if (subTree[0].start === undefined) subTree[0].start = start;
if (subTree[subTree.length - 1].end === undefined) subTree[subTree.length - 1].end = this.pos;
$tw.utils.each(subTree, function (node) { node.rule = nextMatch.rule.name; });
// Quick hack; we only cope with a single parse tree node being returned, which is true at the moment // Quick hack; we only cope with a single parse tree node being returned, which is true at the moment
currentTreeBranch.push.apply(currentTreeBranch,subTree); currentTreeBranch.push.apply(currentTreeBranch,subTree);
subTree[0].children = []; subTree[0].children = [];
currentTreeBranch = subTree[0].children; currentTreeBranch = subTree[0].children;
} }
// Skip whitespace after the pragma
this.skipWhitespace();
} }
return currentTreeBranch; return currentTreeBranch;
}; };
@@ -245,15 +231,7 @@ WikiParser.prototype.parseBlock = function(terminatorRegExpString) {
// Look for a block rule that applies at the current position // Look for a block rule that applies at the current position
var nextMatch = this.findNextMatch(this.blockRules,this.pos); var nextMatch = this.findNextMatch(this.blockRules,this.pos);
if(nextMatch && nextMatch.matchIndex === this.pos) { if(nextMatch && nextMatch.matchIndex === this.pos) {
var start = this.pos; return nextMatch.rule.parse();
var subTree = nextMatch.rule.parse();
// Set the start and end positions of the first and last blocks if they're not already set
if (subTree.length > 0) {
if (subTree[0].start === undefined) subTree[0].start = start;
if (subTree[subTree.length - 1].end === undefined) subTree[subTree.length - 1].end = this.pos;
}
$tw.utils.each(subTree, function (node) { node.rule = nextMatch.rule.name; });
return subTree;
} }
// Treat it as a paragraph if we didn't find a block rule // Treat it as a paragraph if we didn't find a block rule
var start = this.pos; var start = this.pos;
@@ -350,16 +328,7 @@ WikiParser.prototype.parseInlineRunUnterminated = function(options) {
this.pos = nextMatch.matchIndex; this.pos = nextMatch.matchIndex;
} }
// Process the run rule // Process the run rule
var start = this.pos; tree.push.apply(tree,nextMatch.rule.parse());
var subTree = nextMatch.rule.parse();
// Set the start and end positions of the first and last child if they're not already set
if (subTree.length > 0) {
// Set the start and end positions of the first and last child if they're not already set
if (subTree[0].start === undefined) subTree[0].start = start;
if (subTree[subTree.length - 1].end === undefined) subTree[subTree.length - 1].end = this.pos;
}
$tw.utils.each(subTree, function (node) { node.rule = nextMatch.rule.name; });
tree.push.apply(tree,subTree);
// Look for the next run rule // Look for the next run rule
nextMatch = this.findNextMatch(this.inlineRules,this.pos); nextMatch = this.findNextMatch(this.inlineRules,this.pos);
} }
@@ -410,15 +379,7 @@ WikiParser.prototype.parseInlineRunTerminatedExtended = function(terminatorRegEx
this.pos = inlineRuleMatch.matchIndex; this.pos = inlineRuleMatch.matchIndex;
} }
// Process the inline rule // Process the inline rule
var start = this.pos; tree.push.apply(tree,inlineRuleMatch.rule.parse());
var subTree = inlineRuleMatch.rule.parse();
// Set the start and end positions of the first and last child if they're not already set
if (subTree.length > 0) {
if (subTree[0].start === undefined) subTree[0].start = start;
if (subTree[subTree.length - 1].end === undefined) subTree[subTree.length - 1].end = this.pos;
}
$tw.utils.each(subTree, function (node) { node.rule = inlineRuleMatch.rule.name; });
tree.push.apply(tree,subTree);
// Look for the next inline rule // Look for the next inline rule
inlineRuleMatch = this.findNextMatch(this.inlineRules,this.pos); inlineRuleMatch = this.findNextMatch(this.inlineRules,this.pos);
// Look for the next terminator match // Look for the next terminator match
@@ -444,7 +405,7 @@ WikiParser.prototype.pushTextWidget = function(array,text,start,end) {
text = $tw.utils.trim(text); text = $tw.utils.trim(text);
} }
if(text) { if(text) {
array.push({type: "text", text: text, start: start, end: end}); array.push({type: "text", text: text, start: start, end: end});
} }
}; };
@@ -497,3 +458,4 @@ WikiParser.prototype.amendRules = function(type,names) {
exports["text/vnd.tiddlywiki"] = WikiParser; exports["text/vnd.tiddlywiki"] = WikiParser;
})(); })();

View File

@@ -95,7 +95,6 @@ function SaverHandler(options) {
if($tw.browser) { if($tw.browser) {
$tw.rootWidget.addEventListener("tm-save-wiki",function(event) { $tw.rootWidget.addEventListener("tm-save-wiki",function(event) {
self.saveWiki({ self.saveWiki({
wiki: event.widget.wiki,
template: event.param, template: event.param,
downloadType: "text/plain", downloadType: "text/plain",
variables: event.paramObject variables: event.paramObject
@@ -103,7 +102,6 @@ function SaverHandler(options) {
}); });
$tw.rootWidget.addEventListener("tm-download-file",function(event) { $tw.rootWidget.addEventListener("tm-download-file",function(event) {
self.saveWiki({ self.saveWiki({
wiki: event.widget.wiki,
method: "download", method: "download",
template: event.param, template: event.param,
downloadType: "text/plain", downloadType: "text/plain",
@@ -149,22 +147,20 @@ Save the wiki contents. Options are:
method: "save", "autosave" or "download" method: "save", "autosave" or "download"
template: the tiddler containing the template to save template: the tiddler containing the template to save
downloadType: the content type for the saved file downloadType: the content type for the saved file
wiki: optional wiki, overriding the default wiki specified in the constructor
*/ */
SaverHandler.prototype.saveWiki = function(options) { SaverHandler.prototype.saveWiki = function(options) {
options = options || {}; options = options || {};
var self = this, var self = this,
wiki = options.wiki || this.wiki,
method = options.method || "save"; method = options.method || "save";
// Ignore autosave if disabled // Ignore autosave if disabled
if(method === "autosave" && ($tw.config.disableAutoSave || wiki.getTiddlerText(this.titleAutoSave,"yes") !== "yes")) { if(method === "autosave" && ($tw.config.disableAutoSave || this.wiki.getTiddlerText(this.titleAutoSave,"yes") !== "yes")) {
return false; return false;
} }
var variables = options.variables || {}, var variables = options.variables || {},
template = (options.template || template = (options.template ||
wiki.getTiddlerText("$:/config/SaveWikiButton/Template","$:/core/save/all")).trim(), this.wiki.getTiddlerText("$:/config/SaveWikiButton/Template","$:/core/save/all")).trim(),
downloadType = options.downloadType || "text/plain", downloadType = options.downloadType || "text/plain",
text = wiki.renderTiddler(downloadType,template,options), text = this.wiki.renderTiddler(downloadType,template,options),
callback = function(err) { callback = function(err) {
if(err) { if(err) {
alert($tw.language.getString("Error/WhileSaving") + ":\n\n" + err); alert($tw.language.getString("Error/WhileSaving") + ":\n\n" + err);

View File

@@ -48,14 +48,14 @@ var PutSaver = function(wiki) {
var self = this; var self = this;
var uri = this.uri(); var uri = this.uri();
// Async server probe. Until probe finishes, save will fail fast // Async server probe. Until probe finishes, save will fail fast
// See also https://github.com/TiddlyWiki/TiddlyWiki5/issues/2276 // See also https://github.com/Jermolene/TiddlyWiki5/issues/2276
$tw.utils.httpRequest({ $tw.utils.httpRequest({
url: uri, url: uri,
type: "OPTIONS", type: "OPTIONS",
callback: function(err,data,xhr) { callback: function(err,data,xhr) {
// Check DAV header http://www.webdav.org/specs/rfc2518.html#rfc.section.9.1 // Check DAV header http://www.webdav.org/specs/rfc2518.html#rfc.section.9.1
if(!err) { if(!err) {
self.serverAcceptsPuts = xhr.status >= 200 && xhr.status < 300 && !!xhr.getResponseHeader("dav"); self.serverAcceptsPuts = xhr.status === 200 && !!xhr.getResponseHeader("dav");
} }
} }
}); });

View File

@@ -37,9 +37,7 @@ HeaderAuthenticator.prototype.authenticateRequest = function(request,response,st
return false; return false;
} else { } else {
// authenticatedUsername will be undefined for anonymous users // authenticatedUsername will be undefined for anonymous users
if(username) { state.authenticatedUsername = $tw.utils.decodeURIComponentSafe(username);
state.authenticatedUsername = $tw.utils.decodeURIComponentSafe(username);
}
return true; return true;
} }
}; };

View File

@@ -140,11 +140,6 @@ function sendResponse(request,response,statusCode,headers,data,encoding) {
return; return;
} }
} }
} else {
// RFC 7231, 6.1. Overview of Status Codes:
// Browser clients may cache 200, 203, 204, 206, 300, 301,
// 404, 405, 410, 414, and 501 unless given explicit cache controls
headers["Cache-Control"] = headers["Cache-Control"] || "no-store";
} }
/* /*
If the gzip=yes is set, check if the user agent permits compression. If so, If the gzip=yes is set, check if the user agent permits compression. If so,

View File

@@ -61,7 +61,7 @@ exports.startup = function() {
// Collect the shadow tiddlers of any modified plugins // Collect the shadow tiddlers of any modified plugins
$tw.utils.each(changes.modifiedPlugins,function(pluginTitle) { $tw.utils.each(changes.modifiedPlugins,function(pluginTitle) {
var pluginInfo = $tw.wiki.getPluginInfo(pluginTitle); var pluginInfo = $tw.wiki.getPluginInfo(pluginTitle);
if(pluginInfo && pluginInfo.tiddlers) { if(pluginInfo) {
$tw.utils.each(Object.keys(pluginInfo.tiddlers),function(title) { $tw.utils.each(Object.keys(pluginInfo.tiddlers),function(title) {
changedShadowTiddlers[title] = false; changedShadowTiddlers[title] = false;
}); });

View File

@@ -29,11 +29,7 @@ var THROTTLE_REFRESH_TIMEOUT = 400;
exports.startup = function() { exports.startup = function() {
// Set up the title // Set up the title
$tw.titleWidgetNode = $tw.wiki.makeTranscludeWidget(PAGE_TITLE_TITLE, { $tw.titleWidgetNode = $tw.wiki.makeTranscludeWidget(PAGE_TITLE_TITLE,{document: $tw.fakeDocument, parseAsInline: true});
document: $tw.fakeDocument,
parseAsInline: true,
importPageMacros: true,
});
$tw.titleContainer = $tw.fakeDocument.createElement("div"); $tw.titleContainer = $tw.fakeDocument.createElement("div");
$tw.titleWidgetNode.render($tw.titleContainer,null); $tw.titleWidgetNode.render($tw.titleContainer,null);
document.title = $tw.titleContainer.textContent; document.title = $tw.titleContainer.textContent;
@@ -85,8 +81,6 @@ exports.startup = function() {
deferredChanges = Object.create(null); deferredChanges = Object.create(null);
$tw.hooks.invokeHook("th-page-refreshed"); $tw.hooks.invokeHook("th-page-refreshed");
} }
var throttledRefresh = $tw.perf.report("throttledRefresh",refresh);
// Add the change event handler // Add the change event handler
$tw.wiki.addEventListener("change",$tw.perf.report("mainRefresh",function(changes) { $tw.wiki.addEventListener("change",$tw.perf.report("mainRefresh",function(changes) {
// Check if only tiddlers that are throttled have changed // Check if only tiddlers that are throttled have changed
@@ -107,7 +101,7 @@ exports.startup = function() {
if(isNaN(timeout)) { if(isNaN(timeout)) {
timeout = THROTTLE_REFRESH_TIMEOUT; timeout = THROTTLE_REFRESH_TIMEOUT;
} }
timerId = setTimeout(throttledRefresh,timeout); timerId = setTimeout(refresh,timeout);
$tw.utils.extend(deferredChanges,changes); $tw.utils.extend(deferredChanges,changes);
} else { } else {
$tw.utils.extend(deferredChanges,changes); $tw.utils.extend(deferredChanges,changes);

View File

@@ -39,7 +39,6 @@ exports.startup = function() {
method: params.method, method: params.method,
body: params.body, body: params.body,
binary: params.binary, binary: params.binary,
useDefaultHeaders: params.useDefaultHeaders,
oncompletion: params.oncompletion, oncompletion: params.oncompletion,
onprogress: params.onprogress, onprogress: params.onprogress,
bindStatus: params["bind-status"], bindStatus: params["bind-status"],
@@ -48,11 +47,7 @@ exports.startup = function() {
headers: getPropertiesWithPrefix(params,"header-"), headers: getPropertiesWithPrefix(params,"header-"),
passwordHeaders: getPropertiesWithPrefix(params,"password-header-"), passwordHeaders: getPropertiesWithPrefix(params,"password-header-"),
queryStrings: getPropertiesWithPrefix(params,"query-"), queryStrings: getPropertiesWithPrefix(params,"query-"),
passwordQueryStrings: getPropertiesWithPrefix(params,"password-query-"), passwordQueryStrings: getPropertiesWithPrefix(params,"password-query-")
basicAuthUsername: params["basic-auth-username"],
basicAuthUsernameFromStore: params["basic-auth-username-from-store"],
basicAuthPassword: params["basic-auth-password"],
basicAuthPasswordFromStore: params["basic-auth-password-from-store"]
}); });
}); });
$tw.rootWidget.addEventListener("tm-http-cancel-all-requests",function(event) { $tw.rootWidget.addEventListener("tm-http-cancel-all-requests",function(event) {
@@ -73,10 +68,7 @@ exports.startup = function() {
}); });
// Install the copy-to-clipboard mechanism // Install the copy-to-clipboard mechanism
$tw.rootWidget.addEventListener("tm-copy-to-clipboard",function(event) { $tw.rootWidget.addEventListener("tm-copy-to-clipboard",function(event) {
$tw.utils.copyToClipboard(event.param,{ $tw.utils.copyToClipboard(event.param);
successNotification: event.paramObject && event.paramObject.successNotification,
failureNotification: event.paramObject && event.paramObject.failureNotification
});
}); });
// Install the tm-focus-selector message // Install the tm-focus-selector message
$tw.rootWidget.addEventListener("tm-focus-selector",function(event) { $tw.rootWidget.addEventListener("tm-focus-selector",function(event) {

View File

@@ -93,9 +93,7 @@ exports.startup = function() {
updateAddressBar: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_UPDATE_ADDRESS_BAR,"yes").trim() === "yes" ? "permalink" : "none", updateAddressBar: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_UPDATE_ADDRESS_BAR,"yes").trim() === "yes" ? "permalink" : "none",
updateHistory: $tw.wiki.getTiddlerText(CONFIG_UPDATE_HISTORY,"no").trim(), updateHistory: $tw.wiki.getTiddlerText(CONFIG_UPDATE_HISTORY,"no").trim(),
targetTiddler: event.param || event.tiddlerTitle, targetTiddler: event.param || event.tiddlerTitle,
copyToClipboard: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD,"yes").trim() === "yes" ? "permalink" : "none", copyToClipboard: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD,"yes").trim() === "yes" ? "permalink" : "none"
successNotification: event.paramObject && event.paramObject.successNotification,
failureNotification: event.paramObject && event.paramObject.failureNotification
}); });
}); });
// Listen for the tm-permaview message // Listen for the tm-permaview message
@@ -104,9 +102,7 @@ exports.startup = function() {
updateAddressBar: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_UPDATE_ADDRESS_BAR,"yes").trim() === "yes" ? "permaview" : "none", updateAddressBar: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_UPDATE_ADDRESS_BAR,"yes").trim() === "yes" ? "permaview" : "none",
updateHistory: $tw.wiki.getTiddlerText(CONFIG_UPDATE_HISTORY,"no").trim(), updateHistory: $tw.wiki.getTiddlerText(CONFIG_UPDATE_HISTORY,"no").trim(),
targetTiddler: event.param || event.tiddlerTitle, targetTiddler: event.param || event.tiddlerTitle,
copyToClipboard: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD,"yes").trim() === "yes" ? "permaview" : "none", copyToClipboard: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD,"yes").trim() === "yes" ? "permaview" : "none"
successNotification: event.paramObject && event.paramObject.successNotification,
failureNotification: event.paramObject && event.paramObject.failureNotification
}); });
}); });
} }
@@ -181,8 +177,6 @@ options.updateAddressBar: "permalink", "permaview" or "no" (defaults to "permavi
options.updateHistory: "yes" or "no" (defaults to "no") options.updateHistory: "yes" or "no" (defaults to "no")
options.copyToClipboard: "permalink", "permaview" or "no" (defaults to "no") options.copyToClipboard: "permalink", "permaview" or "no" (defaults to "no")
options.targetTiddler: optional title of target tiddler for permalink options.targetTiddler: optional title of target tiddler for permalink
options.successNotification: optional title of tiddler to use as the notification in case of success
options.failureNotification: optional title of tiddler to use as the notification in case of failure
*/ */
function updateLocationHash(options) { function updateLocationHash(options) {
// Get the story and the history stack // Get the story and the history stack
@@ -211,18 +205,14 @@ function updateLocationHash(options) {
break; break;
} }
// Copy URL to the clipboard // Copy URL to the clipboard
var url = "";
switch(options.copyToClipboard) { switch(options.copyToClipboard) {
case "permalink": case "permalink":
url = $tw.utils.getLocationPath() + "#" + encodeURIComponent(targetTiddler); $tw.utils.copyToClipboard($tw.utils.getLocationPath() + "#" + encodeURIComponent(targetTiddler));
break; break;
case "permaview": case "permaview":
url = $tw.utils.getLocationPath() + "#" + encodeURIComponent(targetTiddler) + ":" + encodeURIComponent($tw.utils.stringifyList(storyList)); $tw.utils.copyToClipboard($tw.utils.getLocationPath() + "#" + encodeURIComponent(targetTiddler) + ":" + encodeURIComponent($tw.utils.stringifyList(storyList)));
break; break;
} }
if(url) {
$tw.utils.copyToClipboard(url,{successNotification: options.successNotification, failureNotification: options.failureNotification});
}
// Only change the location hash if we must, thus avoiding unnecessary onhashchange events // Only change the location hash if we must, thus avoiding unnecessary onhashchange events
if($tw.utils.getLocationHash() !== $tw.locationHash) { if($tw.utils.getLocationHash() !== $tw.locationHash) {
if(options.updateHistory === "yes") { if(options.updateHistory === "yes") {

View File

@@ -56,7 +56,7 @@ exports.startup = function() {
return; return;
} }
// Initialise the document // Initialise the document
srcDocument.write("<!DOCTYPE html><head></head><body class='tc-body tc-single-tiddler-window'></body></html>"); srcDocument.write("<html><head></head><body class='tc-body tc-single-tiddler-window'></body></html>");
srcDocument.close(); srcDocument.close();
srcDocument.title = windowTitle; srcDocument.title = windowTitle;
srcWindow.addEventListener("beforeunload",function(event) { srcWindow.addEventListener("beforeunload",function(event) {

View File

@@ -30,8 +30,12 @@ ClassicStoryView.prototype.navigateTo = function(historyInfo) {
if(!targetElement || targetElement.nodeType === Node.TEXT_NODE) { if(!targetElement || targetElement.nodeType === Node.TEXT_NODE) {
return; return;
} }
// Scroll the node into view if(duration) {
this.listWidget.dispatchEvent({type: "tm-scroll", target: targetElement}); // Scroll the node into view
this.listWidget.dispatchEvent({type: "tm-scroll", target: targetElement});
} else {
targetElement.scrollIntoView();
}
}; };
ClassicStoryView.prototype.insert = function(widget) { ClassicStoryView.prototype.insert = function(widget) {
@@ -78,10 +82,6 @@ ClassicStoryView.prototype.remove = function(widget) {
removeElement = function() { removeElement = function() {
widget.removeChildDomNodes(); widget.removeChildDomNodes();
}; };
// Blur the focus if it is within the descendents of the node we are removing
if($tw.utils.domContains(targetElement,targetElement.ownerDocument.activeElement)) {
targetElement.ownerDocument.activeElement.blur();
}
// Abandon if the list entry isn't a DOM element (it might be a text node) // Abandon if the list entry isn't a DOM element (it might be a text node)
if(!targetElement || targetElement.nodeType === Node.TEXT_NODE) { if(!targetElement || targetElement.nodeType === Node.TEXT_NODE) {
removeElement(); removeElement();

View File

@@ -189,6 +189,7 @@ Syncer.prototype.readTiddlerInfo = function() {
// Record information for known tiddlers // Record information for known tiddlers
var self = this, var self = this,
tiddlers = this.getSyncedTiddlers(); tiddlers = this.getSyncedTiddlers();
this.logger.log("Initialising tiddlerInfo for " + tiddlers.length + " tiddlers");
$tw.utils.each(tiddlers,function(title) { $tw.utils.each(tiddlers,function(title) {
var tiddler = self.wiki.getTiddler(title); var tiddler = self.wiki.getTiddler(title);
if(tiddler) { if(tiddler) {
@@ -235,6 +236,7 @@ Syncer.prototype.isDirty = function() {
return false; return false;
} }
var dirtyStatus = checkIsDirty(); var dirtyStatus = checkIsDirty();
this.logger.log("Dirty status was " + dirtyStatus);
return dirtyStatus; return dirtyStatus;
}; };
@@ -264,6 +266,7 @@ Syncer.prototype.storeTiddler = function(tiddlerFields) {
adaptorInfo: this.syncadaptor.getTiddlerInfo(tiddler), adaptorInfo: this.syncadaptor.getTiddlerInfo(tiddler),
changeCount: this.wiki.getChangeCount(tiddlerFields.title) changeCount: this.wiki.getChangeCount(tiddlerFields.title)
}; };
this.logger.log("Updating tiddler info in syncer.storeTiddler for " + tiddlerFields.title + " " + JSON.stringify(this.tiddlerInfo[tiddlerFields.title]));
}; };
Syncer.prototype.getStatus = function(callback) { Syncer.prototype.getStatus = function(callback) {
@@ -299,16 +302,10 @@ Syncer.prototype.getStatus = function(callback) {
Synchronise from the server by reading the skinny tiddler list and queuing up loads for any tiddlers that we don't already have up to date Synchronise from the server by reading the skinny tiddler list and queuing up loads for any tiddlers that we don't already have up to date
*/ */
Syncer.prototype.syncFromServer = function() { Syncer.prototype.syncFromServer = function() {
if(this.canSyncFromServer()) { this.forceSyncFromServer = true;
this.forceSyncFromServer = true; this.processTaskQueue();
this.processTaskQueue();
}
}; };
Syncer.prototype.canSyncFromServer = function() {
return !!this.syncadaptor.getUpdatedTiddlers || !!this.syncadaptor.getSkinnyTiddlers;
}
/* /*
Force load a tiddler from the server Force load a tiddler from the server
*/ */
@@ -428,6 +425,7 @@ Syncer.prototype.processTaskQueue = function() {
if((!this.syncadaptor.isReady || this.syncadaptor.isReady()) && this.numTasksInProgress === 0) { if((!this.syncadaptor.isReady || this.syncadaptor.isReady()) && this.numTasksInProgress === 0) {
// Choose the next task to perform // Choose the next task to perform
var task = this.chooseNextTask(); var task = this.chooseNextTask();
self.logger.log("Chosen next task " + task);
// Perform the task if we had one // Perform the task if we had one
if(typeof task === "object" && task !== null) { if(typeof task === "object" && task !== null) {
this.numTasksInProgress += 1; this.numTasksInProgress += 1;
@@ -449,7 +447,7 @@ Syncer.prototype.processTaskQueue = function() {
// And trigger a timeout if there is a pending task // And trigger a timeout if there is a pending task
if(task === true) { if(task === true) {
this.triggerTimeout(this.taskTimerInterval); this.triggerTimeout(this.taskTimerInterval);
} else if(this.canSyncFromServer()) { } else {
this.triggerTimeout(this.pollTimerInterval); this.triggerTimeout(this.pollTimerInterval);
} }
} }
@@ -553,12 +551,14 @@ SaveTiddlerTask.prototype.run = function(callback) {
revision: revision, revision: revision,
timestampLastSaved: new Date() timestampLastSaved: new Date()
}; };
self.syncer.logger.log("Updating tiddler info in SaveTiddlerTask.run for " + self.title + " " + JSON.stringify(self.syncer.tiddlerInfo[self.title]));
// Invoke the callback // Invoke the callback
callback(null); callback(null);
},{ },{
tiddlerInfo: self.syncer.tiddlerInfo[self.title] tiddlerInfo: self.syncer.tiddlerInfo[self.title]
}); });
} else { } else {
this.syncer.logger.log(" Not Dispatching 'save' task:",this.title,"tiddler does not exist");
$tw.utils.nextTick(callback(null)); $tw.utils.nextTick(callback(null));
} }
}; };
@@ -582,6 +582,7 @@ DeleteTiddlerTask.prototype.run = function(callback) {
return callback(err); return callback(err);
} }
// Remove the info stored about this tiddler // Remove the info stored about this tiddler
self.syncer.logger.log("Deleting tiddler info in DeleteTiddlerTask.run for " + self.title);
delete self.syncer.tiddlerInfo[self.title]; delete self.syncer.tiddlerInfo[self.title];
// Invoke the callback // Invoke the callback
callback(null); callback(null);
@@ -635,7 +636,8 @@ SyncFromServerTask.prototype.run = function(callback) {
callback(null); callback(null);
}; };
if(this.syncer.syncadaptor.getUpdatedTiddlers) { if(this.syncer.syncadaptor.getUpdatedTiddlers) {
this.syncer.syncadaptor.getUpdatedTiddlers(self.syncer,function(err,updates) { self.syncer.logger.log("Retrieving updated tiddler list");
this.syncer.syncadaptor.getUpdatedTiddlers(self,function(err,updates) {
if(err) { if(err) {
self.syncer.displayError($tw.language.getString("Error/RetrievingSkinny"),err); self.syncer.displayError($tw.language.getString("Error/RetrievingSkinny"),err);
return callback(err); return callback(err);
@@ -655,7 +657,9 @@ SyncFromServerTask.prototype.run = function(callback) {
return successCallback(); return successCallback();
}); });
} else if(this.syncer.syncadaptor.getSkinnyTiddlers) { } else if(this.syncer.syncadaptor.getSkinnyTiddlers) {
this.syncer.logger.log("Retrieving skinny tiddler list");
this.syncer.syncadaptor.getSkinnyTiddlers(function(err,tiddlers) { this.syncer.syncadaptor.getSkinnyTiddlers(function(err,tiddlers) {
self.syncer.logger.log("Retrieved skinny tiddler list");
// Check for errors // Check for errors
if(err) { if(err) {
self.syncer.displayError($tw.language.getString("Error/RetrievingSkinny"),err); self.syncer.displayError($tw.language.getString("Error/RetrievingSkinny"),err);

View File

@@ -12,7 +12,7 @@ Upgrader module that suppresses certain system tiddlers that shouldn't be import
/*global $tw: false */ /*global $tw: false */
"use strict"; "use strict";
var DONT_IMPORT_LIST = ["$:/Import", "$:/build"], var DONT_IMPORT_LIST = ["$:/Import"],
UNSELECT_PREFIX_LIST = ["$:/temp/","$:/state/","$:/StoryList","$:/HistoryList"], UNSELECT_PREFIX_LIST = ["$:/temp/","$:/state/","$:/StoryList","$:/HistoryList"],
WARN_IMPORT_PREFIX_LIST = ["$:/core/modules/"]; WARN_IMPORT_PREFIX_LIST = ["$:/core/modules/"];

View File

@@ -270,7 +270,6 @@ Copy plain text to the clipboard on browsers that support it
*/ */
exports.copyToClipboard = function(text,options) { exports.copyToClipboard = function(text,options) {
options = options || {}; options = options || {};
text = text || "";
var textArea = document.createElement("textarea"); var textArea = document.createElement("textarea");
textArea.style.position = "fixed"; textArea.style.position = "fixed";
textArea.style.top = 0; textArea.style.top = 0;
@@ -290,12 +289,10 @@ exports.copyToClipboard = function(text,options) {
var succeeded = false; var succeeded = false;
try { try {
succeeded = document.execCommand("copy"); succeeded = document.execCommand("copy");
} catch(err) { } catch (err) {
} }
if(!options.doNotNotify) { if(!options.doNotNotify) {
var successNotification = options.successNotification || "$:/language/Notifications/CopiedToClipboard/Succeeded", $tw.notifier.display(succeeded ? "$:/language/Notifications/CopiedToClipboard/Succeeded" : "$:/language/Notifications/CopiedToClipboard/Failed");
failureNotification = options.failureNotification || "$:/language/Notifications/CopiedToClipboard/Failed"
$tw.notifier.display(succeeded ? successNotification : failureNotification);
} }
document.body.removeChild(textArea); document.body.removeChild(textArea);
}; };
@@ -316,7 +313,7 @@ exports.collectDOMVariables = function(selectedNode,domNode,event) {
variables["dom-" + attribute.name] = attribute.value.toString(); variables["dom-" + attribute.name] = attribute.value.toString();
}); });
if("offsetLeft" in selectedNode) { if(selectedNode.offsetLeft) {
// Add variables with a (relative and absolute) popup coordinate string for the selected node // Add variables with a (relative and absolute) popup coordinate string for the selected node
var nodeRect = { var nodeRect = {
left: selectedNode.offsetLeft, left: selectedNode.offsetLeft,
@@ -327,7 +324,7 @@ exports.collectDOMVariables = function(selectedNode,domNode,event) {
variables["tv-popup-coords"] = Popup.buildCoordinates(Popup.coordinatePrefix.csOffsetParent,nodeRect); variables["tv-popup-coords"] = Popup.buildCoordinates(Popup.coordinatePrefix.csOffsetParent,nodeRect);
var absRect = $tw.utils.extend({}, nodeRect); var absRect = $tw.utils.extend({}, nodeRect);
for(var currentNode = selectedNode.offsetParent; currentNode; currentNode = currentNode.offsetParent) { for (var currentNode = selectedNode.offsetParent; currentNode; currentNode = currentNode.offsetParent) {
absRect.left += currentNode.offsetLeft; absRect.left += currentNode.offsetLeft;
absRect.top += currentNode.offsetTop; absRect.top += currentNode.offsetTop;
} }
@@ -341,12 +338,12 @@ exports.collectDOMVariables = function(selectedNode,domNode,event) {
} }
} }
if(domNode && ("offsetWidth" in domNode)) { if(domNode && domNode.offsetWidth) {
variables["tv-widgetnode-width"] = domNode.offsetWidth.toString(); variables["tv-widgetnode-width"] = domNode.offsetWidth.toString();
variables["tv-widgetnode-height"] = domNode.offsetHeight.toString(); variables["tv-widgetnode-height"] = domNode.offsetHeight.toString();
} }
if(event && ("clientX" in event) && ("clientY" in event)) { if(event && event.clientX && event.clientY) {
if(selectedNode) { if(selectedNode) {
// Add variables for event X and Y position relative to selected node // Add variables for event X and Y position relative to selected node
selectedNodeRect = selectedNode.getBoundingClientRect(); selectedNodeRect = selectedNode.getBoundingClientRect();

View File

@@ -69,7 +69,7 @@ HttpClient.prototype.cancelAllHttpRequests = function() {
for(var t=this.requests.length - 1; t--; t>=0) { for(var t=this.requests.length - 1; t--; t>=0) {
var requestInfo = this.requests[t]; var requestInfo = this.requests[t];
requestInfo.request.cancel(); requestInfo.request.cancel();
} }
} }
this.requests = []; this.requests = [];
this.updateRequestTracker(); this.updateRequestTracker();
@@ -100,10 +100,6 @@ headers: hashmap of header name to header value to be sent with the request
passwordHeaders: hashmap of header name to password store name to be sent with the request passwordHeaders: hashmap of header name to password store name to be sent with the request
queryStrings: hashmap of query string parameter name to parameter value to be sent with the request queryStrings: hashmap of query string parameter name to parameter value to be sent with the request
passwordQueryStrings: hashmap of query string parameter name to password store name to be sent with the request passwordQueryStrings: hashmap of query string parameter name to password store name to be sent with the request
basicAuthUsername: plain username for basic authentication
basicAuthUsernameFromStore: name of password store entry containing username
basicAuthPassword: plain password for basic authentication
basicAuthPasswordFromStore: name of password store entry containing password
*/ */
function HttpClientRequest(options) { function HttpClientRequest(options) {
var self = this; var self = this;
@@ -116,7 +112,6 @@ function HttpClientRequest(options) {
this.method = options.method || "GET"; this.method = options.method || "GET";
this.body = options.body || ""; this.body = options.body || "";
this.binary = options.binary || ""; this.binary = options.binary || "";
this.useDefaultHeaders = options.useDefaultHeaders !== "false" ? true : false,
this.variables = options.variables; this.variables = options.variables;
var url = options.url; var url = options.url;
$tw.utils.each(options.queryStrings,function(value,name) { $tw.utils.each(options.queryStrings,function(value,name) {
@@ -133,11 +128,6 @@ function HttpClientRequest(options) {
$tw.utils.each(options.passwordHeaders,function(value,name) { $tw.utils.each(options.passwordHeaders,function(value,name) {
self.requestHeaders[name] = $tw.utils.getPassword(value) || ""; self.requestHeaders[name] = $tw.utils.getPassword(value) || "";
}); });
this.basicAuthUsername = options.basicAuthUsername || (options.basicAuthUsernameFromStore && $tw.utils.getPassword(options.basicAuthUsernameFromStore)) || "";
this.basicAuthPassword = options.basicAuthPassword || (options.basicAuthPasswordFromStore && $tw.utils.getPassword(options.basicAuthPasswordFromStore)) || "";
if(this.basicAuthUsername && this.basicAuthPassword) {
this.requestHeaders.Authorization = "Basic " + $tw.utils.base64Encode(this.basicAuthUsername + ":" + this.basicAuthPassword);
}
} }
HttpClientRequest.prototype.send = function(callback) { HttpClientRequest.prototype.send = function(callback) {
@@ -166,7 +156,6 @@ HttpClientRequest.prototype.send = function(callback) {
this.xhr = $tw.utils.httpRequest({ this.xhr = $tw.utils.httpRequest({
url: this.url, url: this.url,
type: this.method, type: this.method,
useDefaultHeaders: this.useDefaultHeaders,
headers: this.requestHeaders, headers: this.requestHeaders,
data: this.body, data: this.body,
returnProp: this.binary === "" ? "responseText" : "response", returnProp: this.binary === "" ? "responseText" : "response",
@@ -242,8 +231,7 @@ Make an HTTP request. Options are:
exports.httpRequest = function(options) { exports.httpRequest = function(options) {
var type = options.type || "GET", var type = options.type || "GET",
url = options.url, url = options.url,
useDefaultHeaders = options.useDefaultHeaders !== false ? true : false, headers = options.headers || {accept: "application/json"},
headers = options.headers || (useDefaultHeaders ? {accept: "application/json"} : {}),
hasHeader = function(targetHeader) { hasHeader = function(targetHeader) {
targetHeader = targetHeader.toLowerCase(); targetHeader = targetHeader.toLowerCase();
var result = false; var result = false;
@@ -269,7 +257,7 @@ exports.httpRequest = function(options) {
if(hasHeader("Content-Type") && ["application/x-www-form-urlencoded","multipart/form-data","text/plain"].indexOf(getHeader["Content-Type"]) === -1) { if(hasHeader("Content-Type") && ["application/x-www-form-urlencoded","multipart/form-data","text/plain"].indexOf(getHeader["Content-Type"]) === -1) {
return false; return false;
} }
return true; return true;
}, },
returnProp = options.returnProp || "responseText", returnProp = options.returnProp || "responseText",
request = new XMLHttpRequest(), request = new XMLHttpRequest(),
@@ -295,13 +283,13 @@ exports.httpRequest = function(options) {
// Set up the state change handler // Set up the state change handler
request.onreadystatechange = function() { request.onreadystatechange = function() {
if(this.readyState === 4) { if(this.readyState === 4) {
if(this.status >= 200 && this.status < 300) { if(this.status === 200 || this.status === 201 || this.status === 204) {
// Success! // Success!
options.callback(null,this[returnProp],this); options.callback(null,this[returnProp],this);
return; return;
} }
// Something went wrong // Something went wrong
options.callback($tw.language.getString("Error/XMLHttpRequest") + ": " + this.status,this[returnProp],this); options.callback($tw.language.getString("Error/XMLHttpRequest") + ": " + this.status,null,this);
} }
}; };
// Handle progress // Handle progress
@@ -319,10 +307,10 @@ exports.httpRequest = function(options) {
request.setRequestHeader(headerTitle,header); request.setRequestHeader(headerTitle,header);
}); });
} }
if(data && !hasHeader("Content-Type") && useDefaultHeaders) { if(data && !hasHeader("Content-Type")) {
request.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"); request.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
} }
if(!hasHeader("X-Requested-With") && !isSimpleRequest(type,headers) && useDefaultHeaders) { if(!hasHeader("X-Requested-With") && !isSimpleRequest(type,headers)) {
request.setRequestHeader("X-Requested-With","TiddlyWiki"); request.setRequestHeader("X-Requested-With","TiddlyWiki");
} }
// Send data // Send data

View File

@@ -29,14 +29,10 @@ exports.getEditionInfo = function() {
for(var entryIndex=0; entryIndex<entries.length; entryIndex++) { for(var entryIndex=0; entryIndex<entries.length; entryIndex++) {
var entry = entries[entryIndex]; var entry = entries[entryIndex];
// Check if directories have a valid tiddlywiki.info // Check if directories have a valid tiddlywiki.info
// Check if the entry is a hidden directory if(!editionInfo[entry] && $tw.utils.isDirectory(path.resolve(editionPath,entry))) {
if((entry.charAt(0) !== ".") && !editionInfo[entry] && $tw.utils.isDirectory(path.resolve(editionPath,entry))) { var info = $tw.utils.parseJSONSafe(fs.readFileSync(path.resolve(editionPath,entry,"tiddlywiki.info"),"utf8"),null);
var file=path.resolve(editionPath,entry,"tiddlywiki.info"); if(info) {
if(fs.existsSync(file)) { editionInfo[entry] = info;
var info = $tw.utils.parseJSONSafe(fs.readFileSync(file,"utf8"),null);
if(info) {
editionInfo[entry] = info;
}
} }
} }
} }
@@ -45,4 +41,4 @@ exports.getEditionInfo = function() {
return editionInfo; return editionInfo;
}; };
})(); })();

View File

@@ -1,23 +0,0 @@
/*\
title: $:/core/modules/utils/errors.js
type: application/javascript
module-type: utils
Custom errors for TiddlyWiki.
\*/
(function(){
function TranscludeRecursionError() {
Error.apply(this,arguments);
this.signatures = Object.create(null);
};
/* Maximum permitted depth of the widget tree for recursion detection */
TranscludeRecursionError.MAX_WIDGET_TREE_DEPTH = 1000;
TranscludeRecursionError.prototype = Object.create(Error);
exports.TranscludeRecursionError = TranscludeRecursionError;
})();

View File

@@ -42,7 +42,7 @@ var TW_TextNode = function(text) {
this.textContent = text + ""; this.textContent = text + "";
}; };
Object.setPrototypeOf(TW_TextNode.prototype,TW_Node.prototype); Object.setPrototypeOf(TW_TextNode,TW_Node.prototype);
Object.defineProperty(TW_TextNode.prototype, "nodeType", { Object.defineProperty(TW_TextNode.prototype, "nodeType", {
get: function() { get: function() {
@@ -67,7 +67,7 @@ var TW_Element = function(tag,namespace) {
this.namespaceURI = namespace || "http://www.w3.org/1999/xhtml"; this.namespaceURI = namespace || "http://www.w3.org/1999/xhtml";
}; };
Object.setPrototypeOf(TW_Element.prototype,TW_Node.prototype); Object.setPrototypeOf(TW_Element,TW_Node.prototype);
Object.defineProperty(TW_Element.prototype, "style", { Object.defineProperty(TW_Element.prototype, "style", {
get: function() { get: function() {
@@ -104,11 +104,7 @@ TW_Element.prototype.setAttribute = function(name,value) {
if(this.isRaw) { if(this.isRaw) {
throw "Cannot setAttribute on a raw TW_Element"; throw "Cannot setAttribute on a raw TW_Element";
} }
if(name === "style") { this.attributes[name] = value + "";
this.style = value;
} else {
this.attributes[name] = value + "";
}
}; };
TW_Element.prototype.setAttributeNS = function(namespace,name,value) { TW_Element.prototype.setAttributeNS = function(namespace,name,value) {

View File

@@ -238,7 +238,7 @@ exports.generateTiddlerFileInfo = function(tiddler,options) {
} else { } else {
// Save as a .tid or a text/binary file plus a .meta file // Save as a .tid or a text/binary file plus a .meta file
var tiddlerType = tiddler.fields.type || "text/vnd.tiddlywiki"; var tiddlerType = tiddler.fields.type || "text/vnd.tiddlywiki";
if(tiddlerType === "text/vnd.tiddlywiki" || tiddlerType === "text/vnd.tiddlywiki-multiple" || tiddler.hasField("_canonical_uri")) { if(tiddlerType === "text/vnd.tiddlywiki" || tiddler.hasField("_canonical_uri")) {
// Save as a .tid file // Save as a .tid file
fileInfo.type = "application/x-tiddler"; fileInfo.type = "application/x-tiddler";
fileInfo.hasMetaFile = false; fileInfo.hasMetaFile = false;
@@ -316,13 +316,11 @@ Options include:
pathFilters: optional array of filters to be used to generate the base path pathFilters: optional array of filters to be used to generate the base path
wiki: optional wiki for evaluating the pathFilters wiki: optional wiki for evaluating the pathFilters
fileInfo: an existing fileInfo object to check against fileInfo: an existing fileInfo object to check against
fileInfo.overwrite: if true, turns off filename clash numbers (defaults to false)
*/ */
exports.generateTiddlerFilepath = function(title,options) { exports.generateTiddlerFilepath = function(title,options) {
var directory = options.directory || "", var directory = options.directory || "",
extension = options.extension || "", extension = options.extension || "",
originalpath = (options.fileInfo && options.fileInfo.originalpath) ? options.fileInfo.originalpath : "", originalpath = (options.fileInfo && options.fileInfo.originalpath) ? options.fileInfo.originalpath : "",
overwrite = options.fileInfo && options.fileInfo.overwrite || false,
filepath; filepath;
// Check if any of the pathFilters applies // Check if any of the pathFilters applies
if(options.pathFilters && options.wiki) { if(options.pathFilters && options.wiki) {
@@ -383,20 +381,19 @@ exports.generateTiddlerFilepath = function(title,options) {
filepath += char.charCodeAt(0).toString(); filepath += char.charCodeAt(0).toString();
}); });
} }
// Add a uniquifier if the file already exists (default) // Add a uniquifier if the file already exists
var fullPath = path.resolve(directory, filepath + extension); var fullPath, oldPath = (options.fileInfo) ? options.fileInfo.filepath : undefined,
if (!overwrite) {
var oldPath = (options.fileInfo) ? options.fileInfo.filepath : undefined,
count = 0; count = 0;
do { do {
fullPath = path.resolve(directory,filepath + (count ? "_" + count : "") + extension); fullPath = path.resolve(directory,filepath + (count ? "_" + count : "") + extension);
if(oldPath && oldPath == fullPath) break; if(oldPath && oldPath == fullPath) {
count++; break;
} while(fs.existsSync(fullPath)); }
} count++;
} while(fs.existsSync(fullPath));
// If the last write failed with an error, or if path does not start with: // If the last write failed with an error, or if path does not start with:
// the resolved options.directory, the resolved wikiPath directory, the wikiTiddlersPath directory, // the resolved options.directory, the resolved wikiPath directory, the wikiTiddlersPath directory,
// or the 'originalpath' directory, then $tw.utils.encodeURIComponentExtended() and resolve to options.directory. // or the 'originalpath' directory, then $tw.utils.encodeURIComponentExtended() and resolve to tiddler directory.
var writePath = $tw.hooks.invokeHook("th-make-tiddler-path",fullPath,fullPath), var writePath = $tw.hooks.invokeHook("th-make-tiddler-path",fullPath,fullPath),
encode = (options.fileInfo || {writeError: false}).writeError == true; encode = (options.fileInfo || {writeError: false}).writeError == true;
if(!encode) { if(!encode) {

View File

@@ -1,52 +0,0 @@
/*\
title: $:/core/modules/utils/repository.js
type: application/javascript
module-type: utils
Utilities for working with the TiddlyWiki repository file structure
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Get an object containing all the plugins as a hashmap by title of the JSON representation of the plugin
Options:
ignoreEnvironmentVariables: defaults to false
*/
exports.getAllPlugins = function(options) {
options = options || {};
var fs = require("fs"),
path = require("path"),
tiddlers = {};
// Collect up the library plugins
var collectPlugins = function(folder) {
var pluginFolders = $tw.utils.getSubdirectories(folder) || [];
for(var p=0; p<pluginFolders.length; p++) {
if(!$tw.boot.excludeRegExp.test(pluginFolders[p])) {
var pluginFields = $tw.loadPluginFolder(path.resolve(folder,"./" + pluginFolders[p]));
if(pluginFields && pluginFields.title) {
tiddlers[pluginFields.title] = pluginFields;
}
}
}
},
collectPublisherPlugins = function(folder) {
var publisherFolders = $tw.utils.getSubdirectories(folder) || [];
for(var t=0; t<publisherFolders.length; t++) {
if(!$tw.boot.excludeRegExp.test(publisherFolders[t])) {
collectPlugins(path.resolve(folder,"./" + publisherFolders[t]));
}
}
};
$tw.utils.each($tw.getLibraryItemSearchPaths($tw.config.pluginsPath,options.ignoreEnvironmentVariables ? undefined : $tw.config.pluginsEnvVar),collectPublisherPlugins);
$tw.utils.each($tw.getLibraryItemSearchPaths($tw.config.themesPath,options.ignoreEnvironmentVariables ? undefined : $tw.config.themesEnvVar),collectPublisherPlugins);
$tw.utils.each($tw.getLibraryItemSearchPaths($tw.config.languagesPath,options.ignoreEnvironmentVariables ? undefined : $tw.config.languagesEnvVar),collectPlugins);
return tiddlers;
};
})();

View File

@@ -924,7 +924,7 @@ exports.transliterate = function(str) {
}; };
exports.transliterateToSafeASCII = function(str) { exports.transliterateToSafeASCII = function(str) {
return str.replace(/[^\x20-\x7F]/g,function(ch) { return str.replace(/[^\x00-\x7F]/g,function(ch) {
return exports.transliterationPairs[ch] || "" return exports.transliterationPairs[ch] || ""
}); });
}; };

View File

@@ -819,15 +819,6 @@ exports.hashString = function(str) {
},0); },0);
}; };
/*
Cryptographic hash function as used by sha256 filter operator
options.length .. number of characters returned defaults to 64
*/
exports.sha256 = function(str, options) {
options = options || {}
return $tw.sjcl.codec.hex.fromBits($tw.sjcl.hash.sha256.hash(str)).substr(0,options.length || 64);
}
/* /*
Base64 utility functions that work in either browser or Node.js Base64 utility functions that work in either browser or Node.js
*/ */
@@ -931,7 +922,7 @@ IE does not have sign function
*/ */
exports.sign = Math.sign || function(x) { exports.sign = Math.sign || function(x) {
x = +x; // convert to a number x = +x; // convert to a number
if(x === 0 || isNaN(x)) { if (x === 0 || isNaN(x)) {
return x; return x;
} }
return x > 0 ? 1 : -1; return x > 0 ? 1 : -1;
@@ -944,7 +935,7 @@ exports.strEndsWith = function(str,ending,position) {
if(str.endsWith) { if(str.endsWith) {
return str.endsWith(ending,position); return str.endsWith(ending,position);
} else { } else {
if(typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > str.length) { if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > str.length) {
position = str.length; position = str.length;
} }
position -= ending.length; position -= ending.length;

View File

@@ -37,7 +37,6 @@ Compute the internal state of the widget
DeleteFieldWidget.prototype.execute = function() { DeleteFieldWidget.prototype.execute = function() {
this.actionTiddler = this.getAttribute("$tiddler",this.getVariable("currentTiddler")); this.actionTiddler = this.getAttribute("$tiddler",this.getVariable("currentTiddler"));
this.actionField = this.getAttribute("$field",null); this.actionField = this.getAttribute("$field",null);
this.actionTimestamp = this.getAttribute("$timestamp","yes") === "yes";
}; };
/* /*
@@ -70,15 +69,11 @@ DeleteFieldWidget.prototype.invokeAction = function(triggeringWidget,event) {
$tw.utils.each(this.attributes,function(attribute,name) { $tw.utils.each(this.attributes,function(attribute,name) {
if(name.charAt(0) !== "$" && name !== "title") { if(name.charAt(0) !== "$" && name !== "title") {
removeFields[name] = undefined; removeFields[name] = undefined;
if(name in tiddler.fields) { hasChanged = true;
hasChanged = true;
}
} }
}); });
if(hasChanged) { if(hasChanged) {
var creationFields = this.actionTimestamp ? this.wiki.getCreationFields() : {}; this.wiki.addTiddler(new $tw.Tiddler(this.wiki.getCreationFields(),tiddler,removeFields,this.wiki.getModificationFields()));
var modificationFields = this.actionTimestamp ? this.wiki.getModificationFields() : {};
this.wiki.addTiddler(new $tw.Tiddler(creationFields,tiddler,removeFields,modificationFields));
} }
} }
return true; // Action was invoked return true; // Action was invoked

View File

@@ -66,12 +66,7 @@ LogWidget.prototype.log = function() {
}); });
for(var v in this.variables) { for(var v in this.variables) {
var variable = this.parentWidget && this.parentWidget.variables[v]; allVars[v] = this.getVariable(v,{defaultValue:""});
if(variable && variable.isFunctionDefinition) {
allVars[v] = variable.value;
} else {
allVars[v] = this.getVariable(v,{defaultValue:""});
}
} }
if(this.filter) { if(this.filter) {
filteredVars = this.wiki.compileFilter(this.filter).call(this.wiki,this.wiki.makeTiddlerIterator(allVars)); filteredVars = this.wiki.compileFilter(this.filter).call(this.wiki,this.wiki.makeTiddlerIterator(allVars));

View File

@@ -70,11 +70,6 @@ BrowseWidget.prototype.render = function(parent,nextSibling) {
} }
return false; return false;
},false); },false);
// Assign data- attributes
this.assignAttributes(domNode,{
sourcePrefix: "data-",
destPrefix: "data-"
});
// Insert element // Insert element
parent.insertBefore(domNode,nextSibling); parent.insertBefore(domNode,nextSibling);
this.renderChildren(domNode,null); this.renderChildren(domNode,null);
@@ -100,11 +95,6 @@ BrowseWidget.prototype.execute = function() {
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/ */
BrowseWidget.prototype.refresh = function(changedTiddlers) { BrowseWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if($tw.utils.count(changedAttributes) > 0) {
this.refreshSelf();
return true;
}
return false; return false;
}; };

View File

@@ -59,11 +59,6 @@ ButtonWidget.prototype.render = function(parent,nextSibling) {
$tw.utils.pushTop(classes,"tc-popup-handle"); $tw.utils.pushTop(classes,"tc-popup-handle");
} }
domNode.className = classes.join(" "); domNode.className = classes.join(" ");
// Assign data- attributes
this.assignAttributes(domNode,{
sourcePrefix: "data-",
destPrefix: "data-"
});
// Assign other attributes // Assign other attributes
if(this.style) { if(this.style) {
domNode.setAttribute("style",this.style); domNode.setAttribute("style",this.style);
@@ -255,25 +250,18 @@ ButtonWidget.prototype.updateDomNodeClasses = function() {
//Add new classes from updated class attribute. //Add new classes from updated class attribute.
$tw.utils.pushTop(domNodeClasses,newClasses); $tw.utils.pushTop(domNodeClasses,newClasses);
this.domNode.className = domNodeClasses.join(" "); this.domNode.className = domNodeClasses.join(" ");
}; }
/* /*
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/ */
ButtonWidget.prototype.refresh = function(changedTiddlers) { ButtonWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes(); var changedAttributes = this.computeAttributes();
if(changedAttributes.tooltip || changedAttributes.actions || changedAttributes.to || changedAttributes.message || changedAttributes.param || changedAttributes.set || changedAttributes.setTo || changedAttributes.popup || changedAttributes.hover || changedAttributes.selectedClass || changedAttributes.style || changedAttributes.dragFilter || changedAttributes.dragTiddler || (this.set && changedTiddlers[this.set]) || (this.popup && changedTiddlers[this.popup]) || (this.popupTitle && changedTiddlers[this.popupTitle]) || changedAttributes.popupAbsCoords || changedAttributes.setTitle || changedAttributes.setField || changedAttributes.setIndex || changedAttributes.popupTitle || changedAttributes.disabled || changedAttributes["default"]) { if(changedAttributes.actions || changedAttributes.to || changedAttributes.message || changedAttributes.param || changedAttributes.set || changedAttributes.setTo || changedAttributes.popup || changedAttributes.hover || changedAttributes.selectedClass || changedAttributes.style || changedAttributes.dragFilter || changedAttributes.dragTiddler || (this.set && changedTiddlers[this.set]) || (this.popup && changedTiddlers[this.popup]) || (this.popupTitle && changedTiddlers[this.popupTitle]) || changedAttributes.popupAbsCoords || changedAttributes.setTitle || changedAttributes.setField || changedAttributes.setIndex || changedAttributes.popupTitle || changedAttributes.disabled || changedAttributes["default"]) {
this.refreshSelf(); this.refreshSelf();
return true; return true;
} else { } else if(changedAttributes["class"]) {
if(changedAttributes["class"]) { this.updateDomNodeClasses();
this.updateDomNodeClasses();
}
this.assignAttributes(this.domNodes[0],{
changedAttributes: changedAttributes,
sourcePrefix: "data-",
destPrefix: "data-"
});
} }
return this.refreshChildren(changedTiddlers); return this.refreshChildren(changedTiddlers);
}; };

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