mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2026-02-16 06:59:50 +00:00
Compare commits
1 Commits
v5.2.0
...
word-games
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e26d0175eb |
@@ -5,7 +5,7 @@
|
||||
# Default to the current version number for building the plugin library
|
||||
|
||||
if [ -z "$TW5_BUILD_VERSION" ]; then
|
||||
TW5_BUILD_VERSION=v5.2.0
|
||||
TW5_BUILD_VERSION=v5.1.24
|
||||
fi
|
||||
|
||||
echo "Using TW5_BUILD_VERSION as [$TW5_BUILD_VERSION]"
|
||||
|
||||
60
boot/boot.js
60
boot/boot.js
@@ -1212,12 +1212,8 @@ $tw.Wiki = function(options) {
|
||||
index,titlesLength,title;
|
||||
for(index = 0, titlesLength = titles.length; index < titlesLength; index++) {
|
||||
title = titles[index];
|
||||
if(tiddlers[title]) {
|
||||
callback(tiddlers[title],title);
|
||||
} else {
|
||||
var shadowInfo = shadowTiddlers[title];
|
||||
callback(shadowInfo.tiddler,title);
|
||||
}
|
||||
var shadowInfo = shadowTiddlers[title];
|
||||
callback(shadowInfo.tiddler,title);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1606,8 +1602,8 @@ $tw.modules.define("$:/boot/tiddlerdeserializer/json","tiddlerdeserializer",{
|
||||
}
|
||||
for(var f in data) {
|
||||
if($tw.utils.hop(data,f)) {
|
||||
// Check field name doesn't contain control characters
|
||||
if(typeof(data[f]) !== "string" || /[\x00-\x1F]/.test(f)) {
|
||||
// Check field name doesn't contain whitespace or control characters
|
||||
if(typeof(data[f]) !== "string" || /[\x00-\x1F\s]/.test(f)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1622,12 +1618,7 @@ $tw.modules.define("$:/boot/tiddlerdeserializer/json","tiddlerdeserializer",{
|
||||
}
|
||||
return true;
|
||||
},
|
||||
data = {};
|
||||
try {
|
||||
data = JSON.parse(text);
|
||||
} catch(e) {
|
||||
// Ignore JSON parse errors
|
||||
}
|
||||
data = JSON.parse(text);
|
||||
if($tw.utils.isArray(data) && isTiddlerArrayValid(data)) {
|
||||
return data;
|
||||
} else if(isTiddlerValid(data)) {
|
||||
@@ -1733,20 +1724,13 @@ $tw.modules.define("$:/boot/tiddlerdeserializer/dom","tiddlerdeserializer",{
|
||||
},
|
||||
t,result = [];
|
||||
if(node) {
|
||||
var type = (node.getAttribute && node.getAttribute("type")) || null;
|
||||
if(type) {
|
||||
// A new-style container with an explicit deserialization type
|
||||
result = $tw.wiki.deserializeTiddlers(type,node.textContent);
|
||||
} else {
|
||||
// An old-style container of classic DIV-based tiddlers
|
||||
for(t = 0; t < node.childNodes.length; t++) {
|
||||
for(t = 0; t < node.childNodes.length; t++) {
|
||||
var childNode = node.childNodes[t],
|
||||
tiddlers = extractTextTiddlers(childNode);
|
||||
tiddlers = tiddlers || extractModuleTiddlers(childNode);
|
||||
if(tiddlers) {
|
||||
result.push.apply(result,tiddlers);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -1755,23 +1739,17 @@ $tw.modules.define("$:/boot/tiddlerdeserializer/dom","tiddlerdeserializer",{
|
||||
|
||||
$tw.loadTiddlersBrowser = function() {
|
||||
// In the browser, we load tiddlers from certain elements
|
||||
var containerSelectors = [
|
||||
// IDs for old-style v5.1.x tiddler stores
|
||||
"#libraryModules",
|
||||
"#modules",
|
||||
"#bootKernelPrefix",
|
||||
"#bootKernel",
|
||||
"#styleArea",
|
||||
"#storeArea",
|
||||
"#systemArea",
|
||||
// Classes for new-style v5.2.x JSON tiddler stores
|
||||
"script.tiddlywiki-tiddler-store"
|
||||
var containerIds = [
|
||||
"libraryModules",
|
||||
"modules",
|
||||
"bootKernelPrefix",
|
||||
"bootKernel",
|
||||
"styleArea",
|
||||
"storeArea",
|
||||
"systemArea"
|
||||
];
|
||||
for(var t=0; t<containerSelectors.length; t++) {
|
||||
var nodes = document.querySelectorAll(containerSelectors[t]);
|
||||
for(var n=0; n<nodes.length; n++) {
|
||||
$tw.wiki.addTiddlers($tw.wiki.deserializeTiddlers("(DOM)",nodes[n]));
|
||||
}
|
||||
for(var t=0; t<containerIds.length; t++) {
|
||||
$tw.wiki.addTiddlers($tw.wiki.deserializeTiddlers("(DOM)",document.getElementById(containerIds[t])));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1894,13 +1872,13 @@ $tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
|
||||
value = path.basename(filename);
|
||||
break;
|
||||
case "filename-uri-decoded":
|
||||
value = $tw.utils.decodeURIComponentSafe(path.basename(filename));
|
||||
value = decodeURIComponent(path.basename(filename));
|
||||
break;
|
||||
case "basename":
|
||||
value = path.basename(filename,path.extname(filename));
|
||||
break;
|
||||
case "basename-uri-decoded":
|
||||
value = $tw.utils.decodeURIComponentSafe(path.basename(filename,path.extname(filename)));
|
||||
value = decodeURIComponent(path.basename(filename,path.extname(filename)));
|
||||
break;
|
||||
case "extname":
|
||||
value = path.extname(filename);
|
||||
@@ -2007,7 +1985,7 @@ $tw.loadPluginFolder = function(filepath,excludeRegExp) {
|
||||
pluginInfo.dependents = pluginInfo.dependents || [];
|
||||
pluginInfo.type = "application/json";
|
||||
// Set plugin text
|
||||
pluginInfo.text = JSON.stringify({tiddlers: pluginInfo.tiddlers});
|
||||
pluginInfo.text = JSON.stringify({tiddlers: pluginInfo.tiddlers},null,4);
|
||||
delete pluginInfo.tiddlers;
|
||||
// Deserialise array fields (currently required for the dependents field)
|
||||
for(var field in pluginInfo) {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -22,6 +22,7 @@ All parameters are optional with safe defaults, and can be specified in any orde
|
||||
* ''readers'' - comma-separated list of principals allowed to read from this wiki
|
||||
* ''writers'' - comma-separated list of principals allowed to write to this wiki
|
||||
* ''csrf-disable'' - set to "yes" to disable CSRF checks (defaults to "no")
|
||||
* ''sse-enabled'' - set to "yes" to enable Server-sent events (defaults to "no")
|
||||
* ''root-tiddler'' - the tiddler to serve at the root (defaults to "$:/core/save/all")
|
||||
* ''root-render-type'' - the content type to which the root tiddler should be rendered (defaults to "text/plain")
|
||||
* ''root-serve-type'' - the content type with which the root tiddler should be served (defaults to "text/html")
|
||||
|
||||
@@ -3,7 +3,6 @@ title: $:/language/Import/
|
||||
Editor/Import/Heading: Import images and insert them into the editor.
|
||||
Imported/Hint: The following tiddlers were imported:
|
||||
Listing/Cancel/Caption: Cancel
|
||||
Listing/Cancel/Warning: Do you wish to cancel the import?
|
||||
Listing/Hint: These tiddlers are ready to import:
|
||||
Listing/Import/Caption: Import
|
||||
Listing/Select/Caption: Select
|
||||
@@ -30,5 +29,5 @@ Upgrader/System/Warning: Core module tiddler.
|
||||
Upgrader/System/Alert: You are about to import a tiddler that will overwrite a core module tiddler. This is not recommended as it may make the system unstable.
|
||||
Upgrader/ThemeTweaks/Created: Migrated theme tweak from <$text text=<<from>>/>.
|
||||
Upgrader/Tiddler/Disabled: Disabled tiddler.
|
||||
Upgrader/Tiddler/Selected: Selected tiddler.
|
||||
Upgrader/Tiddler/Selected: User selected.
|
||||
Upgrader/Tiddler/Unselected: Unselected tiddler.
|
||||
|
||||
@@ -41,6 +41,7 @@ Error/WhileSaving: Error while saving
|
||||
Error/XMLHttpRequest: XMLHttpRequest error code
|
||||
InternalJavaScriptError/Title: Internal JavaScript Error
|
||||
InternalJavaScriptError/Hint: Well, this is embarrassing. It is recommended that you restart TiddlyWiki by refreshing your browser
|
||||
InvalidFieldName: Illegal characters in field name "<$text text=<<fieldName>>/>". Fields can only contain lowercase letters, digits and the characters underscore (`_`), hyphen (`-`) and period (`.`)
|
||||
LayoutSwitcher/Description: Open the layout switcher
|
||||
LazyLoadingWarning: <p>Trying to load external content from ''<$text text={{!!_canonical_uri}}/>''</p><p>If this message doesn't disappear, either the tiddler content type doesn't match the type of the external content, or you may be using a browser that doesn't support external content for wikis loaded as standalone files. See https://tiddlywiki.com/#ExternalText</p>
|
||||
LoginToTiddlySpace: Login to TiddlySpace
|
||||
|
||||
@@ -8,59 +8,58 @@ Render individual tiddlers and save the results to the specified files
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
var widget = require("$:/core/modules/widgets/widget.js");
|
||||
|
||||
exports.info = {
|
||||
name: "render",
|
||||
synchronous: true
|
||||
};
|
||||
|
||||
var Command = function(params,commander,callback) {
|
||||
this.params = params;
|
||||
this.commander = commander;
|
||||
this.callback = callback;
|
||||
};
|
||||
|
||||
Command.prototype.execute = function() {
|
||||
if(this.params.length < 1) {
|
||||
return "Missing tiddler filter";
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
var widget = require("$:/core/modules/widgets/widget.js");
|
||||
|
||||
exports.info = {
|
||||
name: "render",
|
||||
synchronous: true
|
||||
};
|
||||
|
||||
var Command = function(params,commander,callback) {
|
||||
this.params = params;
|
||||
this.commander = commander;
|
||||
this.callback = callback;
|
||||
};
|
||||
|
||||
Command.prototype.execute = function() {
|
||||
if(this.params.length < 1) {
|
||||
return "Missing tiddler filter";
|
||||
}
|
||||
var self = this,
|
||||
fs = require("fs"),
|
||||
path = require("path"),
|
||||
wiki = this.commander.wiki,
|
||||
tiddlerFilter = this.params[0],
|
||||
filenameFilter = this.params[1] || "[is[tiddler]addsuffix[.html]]",
|
||||
type = this.params[2] || "text/html",
|
||||
template = this.params[3],
|
||||
variableList = this.params.slice(4),
|
||||
tiddlers = wiki.filterTiddlers(tiddlerFilter),
|
||||
variables = Object.create(null);
|
||||
while(variableList.length >= 2) {
|
||||
variables[variableList[0]] = variableList[1];
|
||||
variableList = variableList.slice(2);
|
||||
}
|
||||
var self = this,
|
||||
fs = require("fs"),
|
||||
path = require("path"),
|
||||
wiki = this.commander.wiki,
|
||||
tiddlerFilter = this.params[0],
|
||||
filenameFilter = this.params[1] || "[is[tiddler]addsuffix[.html]]",
|
||||
type = this.params[2] || "text/html",
|
||||
template = this.params[3],
|
||||
variableList = this.params.slice(4),
|
||||
tiddlers = wiki.filterTiddlers(tiddlerFilter),
|
||||
variables = Object.create(null);
|
||||
while(variableList.length >= 2) {
|
||||
variables[variableList[0]] = variableList[1];
|
||||
variableList = variableList.slice(2);
|
||||
}
|
||||
$tw.utils.each(tiddlers,function(title) {
|
||||
var filepath = path.resolve(self.commander.outputPath,wiki.filterTiddlers(filenameFilter,$tw.rootWidget,wiki.makeTiddlerIterator([title]))[0]);
|
||||
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})}),
|
||||
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;
|
||||
};
|
||||
|
||||
exports.Command = Command;
|
||||
|
||||
})();
|
||||
|
||||
$tw.utils.each(tiddlers,function(title) {
|
||||
var parser = wiki.parseTiddler(template || title);
|
||||
var widgetNode = wiki.makeWidget(parser,{variables: $tw.utils.extend({},variables,{currentTiddler: title})}),
|
||||
container = $tw.fakeDocument.createElement("div");
|
||||
widgetNode.render(container,null);
|
||||
var text = type === "text/html" ? container.innerHTML : container.textContent,
|
||||
filepath = path.resolve(self.commander.outputPath,wiki.filterTiddlers(filenameFilter,$tw.rootWidget,wiki.makeTiddlerIterator([title]))[0]);
|
||||
if(self.commander.verbose) {
|
||||
console.log("Rendering \"" + title + "\" to \"" + filepath + "\"");
|
||||
}
|
||||
$tw.utils.createFileDirectories(filepath);
|
||||
fs.writeFileSync(filepath,text,"utf8");
|
||||
});
|
||||
return null;
|
||||
};
|
||||
|
||||
exports.Command = Command;
|
||||
|
||||
})();
|
||||
|
||||
@@ -12,8 +12,63 @@ Functions to deserialise tiddlers from a block of text
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
Utility function to parse an old-style tiddler DIV in a *.tid file. It looks like this:
|
||||
|
||||
<div title="Title" creator="JoeBloggs" modifier="JoeBloggs" created="201102111106" modified="201102111310" tags="myTag [[my long tag]]">
|
||||
<pre>The text of the tiddler (without the expected HTML encoding).
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
Note that the field attributes are HTML encoded, but that the body of the <PRE> tag is not encoded.
|
||||
|
||||
When these tiddler DIVs are encountered within a TiddlyWiki HTML file then the body is encoded in the usual way.
|
||||
*/
|
||||
var parseTiddlerDiv = function(text /* [,fields] */) {
|
||||
// Slot together the default results
|
||||
var result = {};
|
||||
if(arguments.length > 1) {
|
||||
for(var f=1; f<arguments.length; f++) {
|
||||
var fields = arguments[f];
|
||||
for(var t in fields) {
|
||||
result[t] = fields[t];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Parse the DIV body
|
||||
var startRegExp = /^\s*<div\s+([^>]*)>(\s*<pre>)?/gi,
|
||||
endRegExp,
|
||||
match = startRegExp.exec(text);
|
||||
if(match) {
|
||||
// Old-style DIVs don't have the <pre> tag
|
||||
if(match[2]) {
|
||||
endRegExp = /<\/pre>\s*<\/div>\s*$/gi;
|
||||
} else {
|
||||
endRegExp = /<\/div>\s*$/gi;
|
||||
}
|
||||
var endMatch = endRegExp.exec(text);
|
||||
if(endMatch) {
|
||||
// Extract the text
|
||||
result.text = text.substring(match.index + match[0].length,endMatch.index);
|
||||
// Process the attributes
|
||||
var attrRegExp = /\s*([^=\s]+)\s*=\s*(?:"([^"]*)"|'([^']*)')/gi,
|
||||
attrMatch;
|
||||
do {
|
||||
attrMatch = attrRegExp.exec(match[1]);
|
||||
if(attrMatch) {
|
||||
var name = attrMatch[1];
|
||||
var value = attrMatch[2] !== undefined ? attrMatch[2] : attrMatch[3];
|
||||
result[name] = value;
|
||||
}
|
||||
} while(attrMatch);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
exports["application/x-tiddler-html-div"] = function(text,fields) {
|
||||
return [deserializeTiddlerDiv(text,fields)];
|
||||
return [parseTiddlerDiv(text,fields)];
|
||||
};
|
||||
|
||||
exports["application/json"] = function(text,fields) {
|
||||
@@ -50,34 +105,30 @@ Parse an HTML file into tiddlers. There are three possibilities:
|
||||
# An ordinary HTML file
|
||||
*/
|
||||
exports["text/html"] = function(text,fields) {
|
||||
var results = [];
|
||||
// Check if we've got an old-style store area
|
||||
// Check if we've got a store area
|
||||
var storeAreaMarkerRegExp = /<div id=["']?storeArea['"]?( style=["']?display:none;["']?)?>/gi,
|
||||
storeAreaMatch = storeAreaMarkerRegExp.exec(text);
|
||||
if(storeAreaMatch) {
|
||||
// If so, we've got tiddlers in classic TiddlyWiki format or unencrypted old-style TW5 format
|
||||
results.push.apply(results,deserializeStoreArea(text,storeAreaMarkerRegExp.lastIndex,!!storeAreaMatch[1],fields));
|
||||
}
|
||||
// Check for new-style store areas
|
||||
var newStoreAreaMarkerRegExp = /<script class="tiddlywiki-tiddler-store" type="([^"]*)">/gi,
|
||||
newStoreAreaMatch = newStoreAreaMarkerRegExp.exec(text),
|
||||
haveHadNewStoreArea = !!newStoreAreaMatch;
|
||||
while(newStoreAreaMatch) {
|
||||
results.push.apply(results,deserializeNewStoreArea(text,newStoreAreaMarkerRegExp.lastIndex,newStoreAreaMatch[1],fields));
|
||||
newStoreAreaMatch = newStoreAreaMarkerRegExp.exec(text);
|
||||
}
|
||||
// Return if we had either an old-style or a new-style store area
|
||||
if(storeAreaMatch || haveHadNewStoreArea) {
|
||||
match = storeAreaMarkerRegExp.exec(text);
|
||||
if(match) {
|
||||
// If so, it's either a classic TiddlyWiki file or an unencrypted TW5 file
|
||||
// First read the normal tiddlers
|
||||
var results = deserializeTiddlyWikiFile(text,storeAreaMarkerRegExp.lastIndex,!!match[1],fields);
|
||||
// Then any system tiddlers
|
||||
var systemAreaMarkerRegExp = /<div id=["']?systemArea['"]?( style=["']?display:none;["']?)?>/gi,
|
||||
sysMatch = systemAreaMarkerRegExp.exec(text);
|
||||
if(sysMatch) {
|
||||
results.push.apply(results,deserializeTiddlyWikiFile(text,systemAreaMarkerRegExp.lastIndex,!!sysMatch[1],fields));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
// Otherwise, check whether we've got an encrypted file
|
||||
var encryptedStoreArea = $tw.utils.extractEncryptedStoreArea(text);
|
||||
if(encryptedStoreArea) {
|
||||
// If so, attempt to decrypt it using the current password
|
||||
return $tw.utils.decryptStoreArea(encryptedStoreArea);
|
||||
} else {
|
||||
// It's not a TiddlyWiki so we'll return the entire HTML file as a tiddler
|
||||
return deserializeHtmlFile(text,fields);
|
||||
// Check whether we've got an encrypted file
|
||||
var encryptedStoreArea = $tw.utils.extractEncryptedStoreArea(text);
|
||||
if(encryptedStoreArea) {
|
||||
// If so, attempt to decrypt it using the current password
|
||||
return $tw.utils.decryptStoreArea(encryptedStoreArea);
|
||||
} else {
|
||||
// It's not a TiddlyWiki so we'll return the entire HTML file as a tiddler
|
||||
return deserializeHtmlFile(text,fields);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -91,19 +142,7 @@ function deserializeHtmlFile(text,fields) {
|
||||
return [result];
|
||||
}
|
||||
|
||||
function deserializeNewStoreArea(text,storeAreaEnd,type,fields) {
|
||||
var endOfScriptRegExp = /<\/script>/gi;
|
||||
endOfScriptRegExp.lastIndex = storeAreaEnd;
|
||||
var match = endOfScriptRegExp.exec(text);
|
||||
if(match) {
|
||||
var scriptContent = text.substring(storeAreaEnd,match.index);
|
||||
return $tw.wiki.deserializeTiddlers(type,scriptContent);
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
function deserializeStoreArea(text,storeAreaEnd,isTiddlyWiki5,fields) {
|
||||
function deserializeTiddlyWikiFile(text,storeAreaEnd,isTiddlyWiki5,fields) {
|
||||
var results = [],
|
||||
endOfDivRegExp = /(<\/div>\s*)/gi,
|
||||
startPos = storeAreaEnd,
|
||||
@@ -112,7 +151,7 @@ function deserializeStoreArea(text,storeAreaEnd,isTiddlyWiki5,fields) {
|
||||
var match = endOfDivRegExp.exec(text);
|
||||
while(match) {
|
||||
var endPos = endOfDivRegExp.lastIndex,
|
||||
tiddlerFields = deserializeTiddlerDiv(text.substring(startPos,endPos),fields,{type: defaultType});
|
||||
tiddlerFields = parseTiddlerDiv(text.substring(startPos,endPos),fields,{type: defaultType});
|
||||
if(!tiddlerFields) {
|
||||
break;
|
||||
}
|
||||
@@ -130,59 +169,4 @@ function deserializeStoreArea(text,storeAreaEnd,isTiddlyWiki5,fields) {
|
||||
return results;
|
||||
}
|
||||
|
||||
/*
|
||||
Utility function to parse an old-style tiddler DIV in a *.tid file. It looks like this:
|
||||
|
||||
<div title="Title" creator="JoeBloggs" modifier="JoeBloggs" created="201102111106" modified="201102111310" tags="myTag [[my long tag]]">
|
||||
<pre>The text of the tiddler (without the expected HTML encoding).
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
Note that the field attributes are HTML encoded, but that the body of the <PRE> tag is not encoded.
|
||||
|
||||
When these tiddler DIVs are encountered within a TiddlyWiki HTML file then the body is encoded in the usual way.
|
||||
*/
|
||||
var deserializeTiddlerDiv = function(text /* [,fields] */) {
|
||||
// Slot together the default results
|
||||
var result = {};
|
||||
if(arguments.length > 1) {
|
||||
for(var f=1; f<arguments.length; f++) {
|
||||
var fields = arguments[f];
|
||||
for(var t in fields) {
|
||||
result[t] = fields[t];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Parse the DIV body
|
||||
var startRegExp = /^\s*<div\s+([^>]*)>(\s*<pre>)?/gi,
|
||||
endRegExp,
|
||||
match = startRegExp.exec(text);
|
||||
if(match) {
|
||||
// Old-style DIVs don't have the <pre> tag
|
||||
if(match[2]) {
|
||||
endRegExp = /<\/pre>\s*<\/div>\s*$/gi;
|
||||
} else {
|
||||
endRegExp = /<\/div>\s*$/gi;
|
||||
}
|
||||
var endMatch = endRegExp.exec(text);
|
||||
if(endMatch) {
|
||||
// Extract the text
|
||||
result.text = text.substring(match.index + match[0].length,endMatch.index);
|
||||
// Process the attributes
|
||||
var attrRegExp = /\s*([^=\s]+)\s*=\s*(?:"([^"]*)"|'([^']*)')/gi,
|
||||
attrMatch;
|
||||
do {
|
||||
attrMatch = attrRegExp.exec(match[1]);
|
||||
if(attrMatch) {
|
||||
var name = attrMatch[1];
|
||||
var value = attrMatch[2] !== undefined ? attrMatch[2] : attrMatch[3];
|
||||
result[name] = value;
|
||||
}
|
||||
} while(attrMatch);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
@@ -135,11 +135,7 @@ FramedEngine.prototype.setText = function(text,type) {
|
||||
Update the DomNode with the new text
|
||||
*/
|
||||
FramedEngine.prototype.updateDomNodeText = function(text) {
|
||||
try {
|
||||
this.domNode.value = text;
|
||||
} catch(e) {
|
||||
// Ignore
|
||||
}
|
||||
this.domNode.value = text;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -85,11 +85,7 @@ SimpleEngine.prototype.setText = function(text,type) {
|
||||
Update the DomNode with the new text
|
||||
*/
|
||||
SimpleEngine.prototype.updateDomNodeText = function(text) {
|
||||
try {
|
||||
this.domNode.value = text;
|
||||
} catch(e) {
|
||||
// Ignore
|
||||
}
|
||||
this.domNode.value = text;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -332,7 +332,7 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
|
||||
};
|
||||
|
||||
EditTextWidget.prototype.handlePasteEvent = function(event) {
|
||||
if(event.clipboardData && event.clipboardData.files && event.clipboardData.files.length) {
|
||||
if(event.clipboardData.files.length) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.dispatchDOMEvent(this.cloneEvent(event,["clipboardData"]));
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
/*\
|
||||
title: $:/core/modules/filterrunprefixes/map.js
|
||||
type: application/javascript
|
||||
module-type: filterrunprefix
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
Export our filter prefix function
|
||||
*/
|
||||
exports.map = function(operationSubFunction,options) {
|
||||
return function(results,source,widget) {
|
||||
if(results.length > 0) {
|
||||
var inputTitles = results.toArray();
|
||||
results.clear();
|
||||
$tw.utils.each(inputTitles,function(title) {
|
||||
var filtered = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{
|
||||
getVariable: function(name) {
|
||||
switch(name) {
|
||||
case "currentTiddler":
|
||||
return "" + title;
|
||||
case "..currentTiddler":
|
||||
return widget.getVariable("currentTiddler");
|
||||
default:
|
||||
return widget.getVariable(name);
|
||||
}
|
||||
}
|
||||
});
|
||||
results.push(filtered[0] || "");
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -253,8 +253,7 @@ exports.compileFilter = function(filterString) {
|
||||
if(operand.indirect) {
|
||||
operand.value = self.getTextReference(operand.text,"",currTiddlerTitle);
|
||||
} else if(operand.variable) {
|
||||
var varTree = $tw.utils.parseFilterVariable(operand.text);
|
||||
operand.value = widget.getVariable(varTree.name,{params:varTree.params,defaultValue: ""});
|
||||
operand.value = widget.getVariable(operand.text,{defaultValue: ""});
|
||||
} else {
|
||||
operand.value = operand.text;
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ exports.all = function(source,operator,options) {
|
||||
results.pushTop(subop(source,operator.prefix,options));
|
||||
}
|
||||
}
|
||||
return results.makeTiddlerIterator(options.wiki);
|
||||
return results.toArray();
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
@@ -16,11 +16,11 @@ Filter operator for returning all the backlinks from a tiddler
|
||||
Export our filter function
|
||||
*/
|
||||
exports.backlinks = function(source,operator,options) {
|
||||
var results = new $tw.utils.LinkedList();
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
results.pushTop(options.wiki.getTiddlerBacklinks(title));
|
||||
$tw.utils.pushTop(results,options.wiki.getTiddlerBacklinks(title));
|
||||
});
|
||||
return results.makeTiddlerIterator(options.wiki);
|
||||
return results;
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
@@ -17,7 +17,7 @@ Export our filter function
|
||||
*/
|
||||
exports.contains = function(source,operator,options) {
|
||||
var results = [],
|
||||
fieldname = operator.suffix || "list";
|
||||
fieldname = (operator.suffix || "list").toLowerCase();
|
||||
if(operator.prefix === "!") {
|
||||
source(function(tiddler,title) {
|
||||
if(tiddler) {
|
||||
|
||||
@@ -19,7 +19,12 @@ Export our filter functions
|
||||
exports.decodeuricomponent = function(source,operator,options) {
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
results.push($tw.utils.decodeURIComponentSafe(title));
|
||||
var value = title;
|
||||
try {
|
||||
value = decodeURIComponent(title);
|
||||
} catch(e) {
|
||||
}
|
||||
results.push(value);
|
||||
});
|
||||
return results;
|
||||
};
|
||||
@@ -35,7 +40,12 @@ exports.encodeuricomponent = function(source,operator,options) {
|
||||
exports.decodeuri = function(source,operator,options) {
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
results.push($tw.utils.decodeURISafe(title));
|
||||
var value = title;
|
||||
try {
|
||||
value = decodeURI(title);
|
||||
} catch(e) {
|
||||
}
|
||||
results.push(value);
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
@@ -17,7 +17,7 @@ Export our filter function
|
||||
*/
|
||||
exports.field = function(source,operator,options) {
|
||||
var results = [],indexedResults,
|
||||
fieldname = operator.suffix || operator.operator || "title";
|
||||
fieldname = (operator.suffix || operator.operator || "title").toLowerCase();
|
||||
if(operator.prefix === "!") {
|
||||
if(operator.regexp) {
|
||||
source(function(tiddler,title) {
|
||||
|
||||
@@ -20,7 +20,7 @@ exports.links = function(source,operator,options) {
|
||||
source(function(tiddler,title) {
|
||||
results.pushTop(options.wiki.getTiddlerLinks(title));
|
||||
});
|
||||
return results.makeTiddlerIterator(options.wiki);
|
||||
return results.toArray();
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
/*\
|
||||
title: $:/core/modules/filters/moduleproperty.js
|
||||
type: application/javascript
|
||||
module-type: filteroperator
|
||||
|
||||
Filter [[module-name]moduleproperty[name]] retrieve a module property
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
Export our filter function
|
||||
*/
|
||||
exports.moduleproperty = function(source,operator,options) {
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
var value = require(title)[operator.operand || ""];
|
||||
if(value !== undefined) {
|
||||
results.push(value);
|
||||
}
|
||||
});
|
||||
results.sort();
|
||||
return results;
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -17,23 +17,11 @@ Export our filter function
|
||||
*/
|
||||
exports.modules = function(source,operator,options) {
|
||||
var results = [];
|
||||
if(operator.operands.length >= 2) {
|
||||
// Return the modules that have the module property specified in the first operand with the value in the second operand
|
||||
source(function(tiddler,title) {
|
||||
$tw.utils.each($tw.modules.types[title],function(moduleInfo,moduleName) {
|
||||
if(require(moduleName)[operator.operands[0]] === operator.operands[1]) {
|
||||
results.push(moduleName);
|
||||
}
|
||||
});
|
||||
source(function(tiddler,title) {
|
||||
$tw.utils.each($tw.modules.types[title],function(moduleInfo,moduleName) {
|
||||
results.push(moduleName);
|
||||
});
|
||||
} else {
|
||||
// Return all the module names without filtering
|
||||
source(function(tiddler,title) {
|
||||
$tw.utils.each($tw.modules.types[title],function(moduleInfo,moduleName) {
|
||||
results.push(moduleName);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
results.sort();
|
||||
return results;
|
||||
};
|
||||
|
||||
@@ -17,13 +17,9 @@ Export our filter function
|
||||
*/
|
||||
exports.range = function(source,operator,options) {
|
||||
var results = [];
|
||||
// For backwards compatibility, if there is only one operand, try to split it using one of the delimiters
|
||||
var parts = operator.operands || [];
|
||||
if(parts.length === 1) {
|
||||
parts = operator.operand.split(/[,:;]/g);
|
||||
}
|
||||
// Process the parts
|
||||
var beg, end, inc, i, fixed = 0;
|
||||
// Split the operand into numbers delimited by these symbols
|
||||
var parts = operator.operand.split(/[,:;]/g),
|
||||
beg, end, inc, i, fixed = 0;
|
||||
for (i=0; i<parts.length; i++) {
|
||||
// Validate real number
|
||||
if(!/^\s*[+-]?((\d+(\.\d*)?)|(\.\d+))\s*$/.test(parts[i])) {
|
||||
|
||||
@@ -17,7 +17,7 @@ Export our filter function
|
||||
*/
|
||||
exports.regexp = function(source,operator,options) {
|
||||
var results = [],
|
||||
fieldname = operator.suffix || "title",
|
||||
fieldname = (operator.suffix || "title").toLowerCase(),
|
||||
regexpString, regexp, flags = "", match,
|
||||
getFieldString = function(tiddler,title) {
|
||||
if(tiddler) {
|
||||
|
||||
@@ -119,7 +119,7 @@ exports["search-replace"] = function(source,operator,options) {
|
||||
var results = [],
|
||||
suffixes = operator.suffixes || [],
|
||||
flagSuffix = (suffixes[0] ? (suffixes[0][0] || "") : ""),
|
||||
flags = (flagSuffix.indexOf("g") !== -1 ? "g" : "") + (flagSuffix.indexOf("i") !== -1 ? "i" : "") + (flagSuffix.indexOf("m") !== -1 ? "m" : ""),
|
||||
flags = (flagSuffix.indexOf("g") !== -1 ? "g" : "") + (flagSuffix.indexOf("i") !== -1 ? "i" : ""),
|
||||
isRegExp = (suffixes[1] && suffixes[1][0] === "regexp") ? true : false,
|
||||
searchTerm,
|
||||
regExp;
|
||||
@@ -172,14 +172,4 @@ exports.pad = function(source,operator,options) {
|
||||
return results;
|
||||
}
|
||||
|
||||
exports.charcode = function(source,operator,options) {
|
||||
var chars = [];
|
||||
$tw.utils.each(operator.operands,function(operand) {
|
||||
if(operand !== "") {
|
||||
chars.push(String.fromCharCode($tw.utils.parseInt(operand)));
|
||||
}
|
||||
});
|
||||
return [chars.join("")];
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
@@ -16,13 +16,20 @@ Filter operator returning all the selected tiddlers that are untagged
|
||||
Export our filter function
|
||||
*/
|
||||
exports.untagged = function(source,operator,options) {
|
||||
var results = [],
|
||||
expected = (operator.prefix === "!");
|
||||
source(function(tiddler,title) {
|
||||
if((tiddler && $tw.utils.isArray(tiddler.fields.tags) && tiddler.fields.tags.length > 0) === expected) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
var results = [];
|
||||
if(operator.prefix === "!") {
|
||||
source(function(tiddler,title) {
|
||||
if(tiddler && $tw.utils.isArray(tiddler.fields.tags) && tiddler.fields.tags.length > 0) {
|
||||
$tw.utils.pushTop(results,title);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
if(!tiddler || !tiddler.hasField("tags") || ($tw.utils.isArray(tiddler.fields.tags) && tiddler.fields.tags.length === 0)) {
|
||||
$tw.utils.pushTop(results,title);
|
||||
}
|
||||
});
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
|
||||
@@ -179,7 +179,7 @@ Key descriptors have the following format:
|
||||
ctrl+enter
|
||||
ctrl+shift+alt+A
|
||||
*/
|
||||
KeyboardManager.prototype.parseKeyDescriptor = function(keyDescriptor,options) {
|
||||
KeyboardManager.prototype.parseKeyDescriptor = function(keyDescriptor) {
|
||||
var components = keyDescriptor.split(/\+|\-/),
|
||||
info = {
|
||||
keyCode: 0,
|
||||
@@ -206,9 +206,6 @@ KeyboardManager.prototype.parseKeyDescriptor = function(keyDescriptor,options) {
|
||||
info.keyCode = this.namedKeys[s];
|
||||
}
|
||||
}
|
||||
if(options.keyDescriptor) {
|
||||
info.keyDescriptor = options.keyDescriptor;
|
||||
}
|
||||
if(info.keyCode) {
|
||||
return info;
|
||||
} else {
|
||||
@@ -240,7 +237,6 @@ KeyboardManager.prototype.parseKeyDescriptors = function(keyDescriptors,options)
|
||||
lookupName = function(configName) {
|
||||
var keyDescriptors = wiki.getTiddlerText("$:/config/" + configName + "/" + name);
|
||||
if(keyDescriptors) {
|
||||
options.keyDescriptor = keyDescriptor;
|
||||
result.push.apply(result,self.parseKeyDescriptors(keyDescriptors,options));
|
||||
}
|
||||
};
|
||||
@@ -249,7 +245,7 @@ KeyboardManager.prototype.parseKeyDescriptors = function(keyDescriptors,options)
|
||||
});
|
||||
}
|
||||
} else {
|
||||
result.push(self.parseKeyDescriptor(keyDescriptor,options));
|
||||
result.push(self.parseKeyDescriptor(keyDescriptor));
|
||||
}
|
||||
});
|
||||
return result;
|
||||
@@ -280,16 +276,12 @@ KeyboardManager.prototype.checkKeyDescriptor = function(event,keyInfo) {
|
||||
};
|
||||
|
||||
KeyboardManager.prototype.checkKeyDescriptors = function(event,keyInfoArray) {
|
||||
return (this.getMatchingKeyDescriptor(event,keyInfoArray) !== null);
|
||||
};
|
||||
|
||||
KeyboardManager.prototype.getMatchingKeyDescriptor = function(event,keyInfoArray) {
|
||||
for(var t=0; t<keyInfoArray.length; t++) {
|
||||
if(this.checkKeyDescriptor(event,keyInfoArray[t])) {
|
||||
return keyInfoArray[t];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return false;
|
||||
};
|
||||
|
||||
KeyboardManager.prototype.getEventModifierKeyDescriptor = function(event) {
|
||||
@@ -332,7 +324,7 @@ KeyboardManager.prototype.handleKeydownEvent = function(event) {
|
||||
if(key !== undefined) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
$tw.rootWidget.invokeActionString(action,$tw.rootWidget,event);
|
||||
$tw.rootWidget.invokeActionString(action,$tw.rootWidget);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -123,19 +123,6 @@ exports.parseStringLiteral = function(source,pos) {
|
||||
}
|
||||
};
|
||||
|
||||
exports.parseMacroParameters = function(node,source,pos) {
|
||||
// Process parameters
|
||||
var parameter = $tw.utils.parseMacroParameter(source,pos);
|
||||
while(parameter) {
|
||||
node.params.push(parameter);
|
||||
pos = parameter.end;
|
||||
// Get the next parameter
|
||||
parameter = $tw.utils.parseMacroParameter(source,pos);
|
||||
}
|
||||
node.end = pos;
|
||||
return node;
|
||||
}
|
||||
|
||||
/*
|
||||
Look for a macro invocation parameter. Returns null if not found, or {type: "macro-parameter", name:, value:, start:, end:}
|
||||
*/
|
||||
@@ -200,8 +187,14 @@ exports.parseMacroInvocation = function(source,pos) {
|
||||
}
|
||||
node.name = name.match[1];
|
||||
pos = name.end;
|
||||
node = $tw.utils.parseMacroParameters(node,source,pos);
|
||||
pos = node.end;
|
||||
// Process parameters
|
||||
var parameter = $tw.utils.parseMacroParameter(source,pos);
|
||||
while(parameter) {
|
||||
node.params.push(parameter);
|
||||
pos = parameter.end;
|
||||
// Get the next parameter
|
||||
parameter = $tw.utils.parseMacroParameter(source,pos);
|
||||
}
|
||||
// Skip whitespace
|
||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||
// Look for a double greater than sign
|
||||
@@ -215,29 +208,6 @@ exports.parseMacroInvocation = function(source,pos) {
|
||||
return node;
|
||||
};
|
||||
|
||||
exports.parseFilterVariable = function(source) {
|
||||
var node = {
|
||||
name: "",
|
||||
params: [],
|
||||
},
|
||||
pos = 0,
|
||||
reName = /([^\s"']+)/g;
|
||||
// If there is no whitespace or it is an empty string then there are no macro parameters
|
||||
if(/^\S*$/.test(source)) {
|
||||
node.name = source;
|
||||
return node;
|
||||
}
|
||||
// Get the variable name
|
||||
var nameMatch = $tw.utils.parseTokenRegExp(source,pos,reName);
|
||||
if(nameMatch) {
|
||||
node.name = nameMatch.match[1];
|
||||
pos = nameMatch.end;
|
||||
node = $tw.utils.parseMacroParameters(node,source,pos);
|
||||
delete node.end;
|
||||
}
|
||||
return node;
|
||||
};
|
||||
|
||||
/*
|
||||
Look for an HTML attribute definition. Returns null if not found, otherwise returns {type: "attribute", name:, valueType: "string|indirect|macro", value:, start:, end:,}
|
||||
*/
|
||||
|
||||
@@ -7,12 +7,6 @@ Wiki text block rule for HTML comments. For example:
|
||||
|
||||
```
|
||||
<!-- This is a comment -->
|
||||
\define macroX()
|
||||
<!-- This is a comment -->
|
||||
xxxx
|
||||
\end
|
||||
<!-- This is a comment -->
|
||||
|
||||
```
|
||||
|
||||
Note that the syntax for comments is simplified to an opening "<!--" sequence and a closing "-->" sequence -- HTML itself implements a more complex format (see http://ostermiller.org/findhtmlcomment.html)
|
||||
@@ -25,7 +19,7 @@ Note that the syntax for comments is simplified to an opening "<!--" sequence an
|
||||
"use strict";
|
||||
|
||||
exports.name = "commentblock";
|
||||
exports.types = {block:true, pragma:true};
|
||||
exports.types = {block: true};
|
||||
|
||||
exports.init = function(parser) {
|
||||
this.parser = parser;
|
||||
|
||||
@@ -157,8 +157,7 @@ SaverHandler.prototype.saveWiki = function(options) {
|
||||
return false;
|
||||
}
|
||||
var variables = options.variables || {},
|
||||
template = (options.template ||
|
||||
this.wiki.getTiddlerText("$:/config/SaveWikiButton/Template","$:/core/save/all")).trim(),
|
||||
template = options.template || "$:/core/save/all",
|
||||
downloadType = options.downloadType || "text/plain",
|
||||
text = this.wiki.renderTiddler(downloadType,template,options),
|
||||
callback = function(err) {
|
||||
|
||||
@@ -42,7 +42,7 @@ AndTidWiki.prototype.save = function(text,method,callback,options) {
|
||||
window.twi.saveWiki(text);
|
||||
} else {
|
||||
// Get the pathname of this document
|
||||
var pathname = $tw.utils.decodeURIComponentSafe(document.location.toString().split("#")[0]);
|
||||
var pathname = decodeURIComponent(document.location.toString().split("#")[0]);
|
||||
// Strip the file://
|
||||
if(pathname.indexOf("file://") === 0) {
|
||||
pathname = pathname.substr(7);
|
||||
|
||||
@@ -26,7 +26,7 @@ DownloadSaver.prototype.save = function(text,method,callback,options) {
|
||||
var p = document.location.pathname.lastIndexOf("/");
|
||||
if(p !== -1) {
|
||||
// We decode the pathname because document.location is URL encoded by the browser
|
||||
filename = $tw.utils.decodeURIComponentSafe(document.location.pathname.substr(p+1));
|
||||
filename = decodeURIComponent(document.location.pathname.substr(p+1));
|
||||
}
|
||||
}
|
||||
if(!filename) {
|
||||
|
||||
@@ -72,7 +72,7 @@ GiteaSaver.prototype.save = function(text,method,callback) {
|
||||
}
|
||||
}
|
||||
var data = {
|
||||
message: $tw.language.getString("ControlPanel/Saving/GitService/CommitMessage"),
|
||||
message: $tw.language.getRawString("ControlPanel/Saving/GitService/CommitMessage"),
|
||||
content: $tw.utils.base64Encode(text),
|
||||
sha: sha
|
||||
};
|
||||
|
||||
@@ -69,7 +69,7 @@ GitHubSaver.prototype.save = function(text,method,callback) {
|
||||
});
|
||||
}
|
||||
var data = {
|
||||
message: $tw.language.getString("ControlPanel/Saving/GitService/CommitMessage"),
|
||||
message: $tw.language.getRawString("ControlPanel/Saving/GitService/CommitMessage"),
|
||||
content: $tw.utils.base64Encode(text),
|
||||
branch: branch,
|
||||
sha: sha
|
||||
|
||||
@@ -67,7 +67,7 @@ GitLabSaver.prototype.save = function(text,method,callback) {
|
||||
});
|
||||
}
|
||||
var data = {
|
||||
commit_message: $tw.language.getString("ControlPanel/Saving/GitService/CommitMessage"),
|
||||
commit_message: $tw.language.getRawString("ControlPanel/Saving/GitService/CommitMessage"),
|
||||
content: text,
|
||||
branch: branch,
|
||||
sha: sha
|
||||
|
||||
@@ -43,7 +43,7 @@ TiddlyFoxSaver.prototype.save = function(text,method,callback) {
|
||||
}
|
||||
// Create the message element and put it in the message box
|
||||
var message = document.createElement("div");
|
||||
message.setAttribute("data-tiddlyfox-path",$tw.utils.decodeURIComponentSafe(pathname));
|
||||
message.setAttribute("data-tiddlyfox-path",decodeURIComponent(pathname));
|
||||
message.setAttribute("data-tiddlyfox-content",text);
|
||||
messageBox.appendChild(message);
|
||||
// Add an event handler for when the file has been saved
|
||||
|
||||
@@ -21,7 +21,7 @@ TWEditSaver.prototype.save = function(text,method,callback) {
|
||||
return false;
|
||||
}
|
||||
// Get the pathname of this document
|
||||
var pathname = $tw.utils.decodeURIComponentSafe(document.location.pathname);
|
||||
var pathname = decodeURIComponent(document.location.pathname);
|
||||
// Strip any query or location part
|
||||
var p = pathname.indexOf("?");
|
||||
if(p !== -1) {
|
||||
|
||||
@@ -17,7 +17,7 @@ exports.method = "DELETE";
|
||||
exports.path = /^\/bags\/default\/tiddlers\/(.+)$/;
|
||||
|
||||
exports.handler = function(request,response,state) {
|
||||
var title = $tw.utils.decodeURIComponentSafe(state.params[0]);
|
||||
var title = decodeURIComponent(state.params[0]);
|
||||
state.wiki.deleteTiddler(title);
|
||||
response.writeHead(204, "OK", {
|
||||
"Content-Type": "text/plain"
|
||||
|
||||
@@ -20,29 +20,22 @@ exports.handler = function(request,response,state) {
|
||||
var path = require("path"),
|
||||
fs = require("fs"),
|
||||
util = require("util"),
|
||||
suppliedFilename = $tw.utils.decodeURIComponentSafe(state.params[0]),
|
||||
baseFilename = path.resolve(state.boot.wikiPath,"files"),
|
||||
filename = path.resolve(baseFilename,suppliedFilename),
|
||||
suppliedFilename = decodeURIComponent(state.params[0]),
|
||||
filename = path.resolve(state.boot.wikiPath,"files",suppliedFilename),
|
||||
extension = path.extname(filename);
|
||||
// Check that the filename is inside the wiki files folder
|
||||
if(path.relative(baseFilename,filename).indexOf("..") !== 0) {
|
||||
// Send the file
|
||||
fs.readFile(filename,function(err,content) {
|
||||
var status,content,type = "text/plain";
|
||||
if(err) {
|
||||
console.log("Error accessing file " + filename + ": " + err.toString());
|
||||
status = 404;
|
||||
content = "File '" + suppliedFilename + "' not found";
|
||||
} else {
|
||||
status = 200;
|
||||
content = content;
|
||||
type = ($tw.config.fileExtensionInfo[extension] ? $tw.config.fileExtensionInfo[extension].type : "application/octet-stream");
|
||||
}
|
||||
state.sendResponse(status,{"Content-Type": type},content);
|
||||
});
|
||||
} else {
|
||||
state.sendResponse(404,{"Content-Type": "text/plain"},"File '" + suppliedFilename + "' not found");
|
||||
}
|
||||
fs.readFile(filename,function(err,content) {
|
||||
var status,content,type = "text/plain";
|
||||
if(err) {
|
||||
console.log("Error accessing file " + filename + ": " + err.toString());
|
||||
status = 404;
|
||||
content = "File '" + suppliedFilename + "' not found";
|
||||
} else {
|
||||
status = 200;
|
||||
content = content;
|
||||
type = ($tw.config.fileExtensionInfo[extension] ? $tw.config.fileExtensionInfo[extension].type : "application/octet-stream");
|
||||
}
|
||||
state.sendResponse(status,{"Content-Type": type},content);
|
||||
});
|
||||
};
|
||||
|
||||
}());
|
||||
|
||||
@@ -21,6 +21,7 @@ exports.handler = function(request,response,state) {
|
||||
username: state.authenticatedUsername || state.server.get("anon-username") || "",
|
||||
anonymous: !state.authenticatedUsername,
|
||||
read_only: !state.server.isAuthorized("writers",state.authenticatedUsername),
|
||||
sse_enabled: state.server.get("sse-enabled") === "yes",
|
||||
space: {
|
||||
recipe: "default"
|
||||
},
|
||||
|
||||
@@ -17,7 +17,7 @@ exports.method = "GET";
|
||||
exports.path = /^\/([^\/]+)$/;
|
||||
|
||||
exports.handler = function(request,response,state) {
|
||||
var title = $tw.utils.decodeURIComponentSafe(state.params[0]),
|
||||
var title = decodeURIComponent(state.params[0]),
|
||||
tiddler = state.wiki.getTiddler(title);
|
||||
if(tiddler) {
|
||||
var renderType = tiddler.getFieldString("_render_type"),
|
||||
|
||||
@@ -17,7 +17,7 @@ exports.method = "GET";
|
||||
exports.path = /^\/recipes\/default\/tiddlers\/(.+)$/;
|
||||
|
||||
exports.handler = function(request,response,state) {
|
||||
var title = $tw.utils.decodeURIComponentSafe(state.params[0]),
|
||||
var title = decodeURIComponent(state.params[0]),
|
||||
tiddler = state.wiki.getTiddler(title),
|
||||
tiddlerFields = {},
|
||||
knownFields = [
|
||||
|
||||
@@ -17,7 +17,7 @@ exports.method = "PUT";
|
||||
exports.path = /^\/recipes\/default\/tiddlers\/(.+)$/;
|
||||
|
||||
exports.handler = function(request,response,state) {
|
||||
var title = $tw.utils.decodeURIComponentSafe(state.params[0]),
|
||||
var title = decodeURIComponent(state.params[0]),
|
||||
fields = JSON.parse(state.data);
|
||||
// Pull up any subfields in the `fields` object
|
||||
if(fields.fields) {
|
||||
|
||||
70
core/modules/server/server-sent-events.js
Normal file
70
core/modules/server/server-sent-events.js
Normal file
@@ -0,0 +1,70 @@
|
||||
/*\
|
||||
title: $:/core/modules/server/server-sent-events.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
parameters:
|
||||
prefix - usually the plugin path, such as `plugins/tiddlywiki/tiddlyweb`. The
|
||||
route will match `/events/${prefix}` exactly.
|
||||
|
||||
handler - a function that will be called each time a request comes in with the
|
||||
request and state from the route and an emit function to call.
|
||||
*/
|
||||
|
||||
var ServerSentEvents = function ServerSentEvents(prefix, handler) {
|
||||
this.handler = handler;
|
||||
this.prefix = prefix;
|
||||
};
|
||||
|
||||
ServerSentEvents.prototype.getExports = function() {
|
||||
return {
|
||||
bodyFormat: "stream",
|
||||
method: "GET",
|
||||
path: new RegExp("^/events/" + this.prefix + "$"),
|
||||
handler: this.handleEventRequest.bind(this)
|
||||
};
|
||||
};
|
||||
|
||||
ServerSentEvents.prototype.handleEventRequest = function(request,response,state) {
|
||||
if(ServerSentEvents.prototype.isEventStreamRequest(request)) {
|
||||
response.writeHead(200, {
|
||||
"Content-Type": "text/event-stream",
|
||||
"Cache-Control": "no-cache",
|
||||
"Connection": "keep-alive"
|
||||
});
|
||||
this.handler(request,state,this.emit.bind(this,response),this.end.bind(this,response));
|
||||
} else {
|
||||
response.writeHead(406,"Not Acceptable",{});
|
||||
response.end();
|
||||
}
|
||||
};
|
||||
|
||||
ServerSentEvents.prototype.isEventStreamRequest = function(request) {
|
||||
return request.headers.accept &&
|
||||
request.headers.accept.match(/^text\/event-stream/);
|
||||
};
|
||||
|
||||
ServerSentEvents.prototype.emit = function(response,event,data) {
|
||||
if(typeof event !== "string" || event.indexOf("\n") !== -1) {
|
||||
throw new Error("Type must be a single-line string");
|
||||
}
|
||||
if(typeof data !== "string" || data.indexOf("\n") !== -1) {
|
||||
throw new Error("Data must be a single-line string");
|
||||
}
|
||||
response.write("event: " + event + "\ndata: " + data + "\n\n", "utf8");
|
||||
};
|
||||
|
||||
ServerSentEvents.prototype.end = function(response) {
|
||||
response.end();
|
||||
};
|
||||
|
||||
exports.ServerSentEvents = ServerSentEvents;
|
||||
|
||||
})();
|
||||
@@ -40,10 +40,9 @@ exports.startup = function() {
|
||||
// Install the tm-focus-selector message
|
||||
$tw.rootWidget.addEventListener("tm-focus-selector",function(event) {
|
||||
var selector = event.param || "",
|
||||
element,
|
||||
doc = event.event && event.event.target ? event.event.target.ownerDocument : document;
|
||||
element;
|
||||
try {
|
||||
element = doc.querySelector(selector);
|
||||
element = document.querySelector(selector);
|
||||
} catch(e) {
|
||||
console.log("Error in selector: ",selector)
|
||||
}
|
||||
|
||||
@@ -120,10 +120,10 @@ function openStartupTiddlers(options) {
|
||||
var hash = $tw.locationHash.substr(1),
|
||||
split = hash.indexOf(":");
|
||||
if(split === -1) {
|
||||
target = $tw.utils.decodeURIComponentSafe(hash.trim());
|
||||
target = decodeURIComponent(hash.trim());
|
||||
} else {
|
||||
target = $tw.utils.decodeURIComponentSafe(hash.substr(0,split).trim());
|
||||
storyFilter = $tw.utils.decodeURIComponentSafe(hash.substr(split + 1).trim());
|
||||
target = decodeURIComponent(hash.substr(0,split).trim());
|
||||
storyFilter = decodeURIComponent(hash.substr(split + 1).trim());
|
||||
}
|
||||
}
|
||||
// If the story wasn't specified use the current tiddlers or a blank story
|
||||
|
||||
@@ -27,7 +27,7 @@ ClassicStoryView.prototype.navigateTo = function(historyInfo) {
|
||||
var listItemWidget = this.listWidget.children[listElementIndex],
|
||||
targetElement = listItemWidget.findFirstDomNode();
|
||||
// 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 instanceof Element)) {
|
||||
return;
|
||||
}
|
||||
if(duration) {
|
||||
@@ -43,7 +43,7 @@ ClassicStoryView.prototype.insert = function(widget) {
|
||||
if(duration) {
|
||||
var targetElement = widget.findFirstDomNode();
|
||||
// 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 instanceof Element)) {
|
||||
return;
|
||||
}
|
||||
// Get the current height of the tiddler
|
||||
@@ -83,7 +83,7 @@ ClassicStoryView.prototype.remove = function(widget) {
|
||||
widget.removeChildDomNodes();
|
||||
};
|
||||
// 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 instanceof Element)) {
|
||||
removeElement();
|
||||
return;
|
||||
}
|
||||
@@ -118,4 +118,4 @@ ClassicStoryView.prototype.remove = function(widget) {
|
||||
|
||||
exports.classic = ClassicStoryView;
|
||||
|
||||
})();
|
||||
})();
|
||||
@@ -24,7 +24,7 @@ PopStoryView.prototype.navigateTo = function(historyInfo) {
|
||||
var listItemWidget = this.listWidget.children[listElementIndex],
|
||||
targetElement = listItemWidget.findFirstDomNode();
|
||||
// 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 instanceof Element)) {
|
||||
return;
|
||||
}
|
||||
// Scroll the node into view
|
||||
@@ -35,7 +35,7 @@ PopStoryView.prototype.insert = function(widget) {
|
||||
var targetElement = widget.findFirstDomNode(),
|
||||
duration = $tw.utils.getAnimationDuration();
|
||||
// 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 instanceof Element)) {
|
||||
return;
|
||||
}
|
||||
// Reset once the transition is over
|
||||
@@ -77,7 +77,7 @@ PopStoryView.prototype.remove = function(widget) {
|
||||
}
|
||||
};
|
||||
// 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 instanceof Element)) {
|
||||
removeElement();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ ZoominListView.prototype.navigateTo = function(historyInfo) {
|
||||
var listItemWidget = this.listWidget.children[listElementIndex],
|
||||
targetElement = listItemWidget.findFirstDomNode();
|
||||
// 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 instanceof Element)) {
|
||||
return;
|
||||
}
|
||||
// Make the new tiddler be position absolute and visible so that we can measure it
|
||||
@@ -130,7 +130,7 @@ function findTitleDomNode(widget,targetClass) {
|
||||
ZoominListView.prototype.insert = function(widget) {
|
||||
var targetElement = widget.findFirstDomNode();
|
||||
// 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 instanceof Element)) {
|
||||
return;
|
||||
}
|
||||
// Make the newly inserted node position absolute and hidden
|
||||
@@ -147,7 +147,7 @@ ZoominListView.prototype.remove = function(widget) {
|
||||
widget.removeChildDomNodes();
|
||||
};
|
||||
// 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 instanceof Element)) {
|
||||
removeElement();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ Syncer.prototype.titleIsAnonymous = "$:/status/IsAnonymous";
|
||||
Syncer.prototype.titleIsReadOnly = "$:/status/IsReadOnly";
|
||||
Syncer.prototype.titleUserName = "$:/status/UserName";
|
||||
Syncer.prototype.titleSyncFilter = "$:/config/SyncFilter";
|
||||
Syncer.prototype.titleSyncDisablePolling = "$:/config/SyncDisablePolling";
|
||||
Syncer.prototype.titleSyncPollingInterval = "$:/config/SyncPollingInterval";
|
||||
Syncer.prototype.titleSyncDisableLazyLoading = "$:/config/SyncDisableLazyLoading";
|
||||
Syncer.prototype.titleSavedNotification = "$:/language/Notifications/Save/Done";
|
||||
@@ -89,7 +90,7 @@ function Syncer(options) {
|
||||
if(filteredChanges.length > 0) {
|
||||
self.processTaskQueue();
|
||||
} else {
|
||||
// Look for deletions of tiddlers we're already syncing
|
||||
// Look for deletions of tiddlers we're already syncing
|
||||
var outstandingDeletion = false
|
||||
$tw.utils.each(changes,function(change,title,object) {
|
||||
if(change.deleted && $tw.utils.hop(self.tiddlerInfo,title)) {
|
||||
@@ -121,7 +122,7 @@ function Syncer(options) {
|
||||
self.login(username,password,function() {});
|
||||
} else {
|
||||
// No username and password, so we display a prompt
|
||||
self.handleLoginEvent();
|
||||
self.handleLoginEvent();
|
||||
}
|
||||
});
|
||||
$tw.rootWidget.addEventListener("tm-logout",function() {
|
||||
@@ -138,7 +139,7 @@ function Syncer(options) {
|
||||
if(!this.disableUI && this.wiki.getTiddlerText(this.titleSyncDisableLazyLoading) !== "yes") {
|
||||
this.wiki.addEventListener("lazyLoad",function(title) {
|
||||
self.handleLazyLoadEvent(title);
|
||||
});
|
||||
});
|
||||
}
|
||||
// Get the login status
|
||||
this.getStatus(function(err,isLoggedIn) {
|
||||
@@ -173,8 +174,8 @@ Syncer.prototype.getTiddlerRevision = function(title) {
|
||||
if(this.syncadaptor && this.syncadaptor.getTiddlerRevision) {
|
||||
return this.syncadaptor.getTiddlerRevision(title);
|
||||
} else {
|
||||
return this.wiki.getTiddler(title).fields.revision;
|
||||
}
|
||||
return this.wiki.getTiddler(title).fields.revision;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -267,9 +268,9 @@ Syncer.prototype.getStatus = function(callback) {
|
||||
// Mark us as not logged in
|
||||
this.wiki.addTiddler({title: this.titleIsLoggedIn,text: "no"});
|
||||
// Get login status
|
||||
this.syncadaptor.getStatus(function(err,isLoggedIn,username,isReadOnly,isAnonymous) {
|
||||
this.syncadaptor.getStatus(function(err,isLoggedIn,username,isReadOnly,isAnonymous,isPollingDisabled) {
|
||||
if(err) {
|
||||
self.displayError("Get Status Error",err);
|
||||
self.logger.alert(err);
|
||||
} else {
|
||||
// Set the various status tiddlers
|
||||
self.wiki.addTiddler({title: self.titleIsReadOnly,text: isReadOnly ? "yes" : "no"});
|
||||
@@ -278,6 +279,9 @@ Syncer.prototype.getStatus = function(callback) {
|
||||
if(isLoggedIn) {
|
||||
self.wiki.addTiddler({title: self.titleUserName,text: username || ""});
|
||||
}
|
||||
if(isPollingDisabled) {
|
||||
self.wiki.addTiddler({title: self.titleSyncDisablePolling, text: "yes"});
|
||||
}
|
||||
}
|
||||
// Invoke the callback
|
||||
if(callback) {
|
||||
@@ -301,12 +305,15 @@ Syncer.prototype.syncFromServer = function() {
|
||||
}
|
||||
},
|
||||
triggerNextSync = function() {
|
||||
self.pollTimerId = setTimeout(function() {
|
||||
self.pollTimerId = null;
|
||||
self.syncFromServer.call(self);
|
||||
},self.pollTimerInterval);
|
||||
if(pollingEnabled) {
|
||||
self.pollTimerId = setTimeout(function() {
|
||||
self.pollTimerId = null;
|
||||
self.syncFromServer.call(self);
|
||||
},self.pollTimerInterval);
|
||||
}
|
||||
},
|
||||
syncSystemFromServer = (self.wiki.getTiddlerText("$:/config/SyncSystemTiddlersFromServer") === "yes" ? true : false);
|
||||
syncSystemFromServer = (self.wiki.getTiddlerText("$:/config/SyncSystemTiddlersFromServer") === "yes"),
|
||||
pollingEnabled = (self.wiki.getTiddlerText(self.titleSyncDisablePolling) !== "yes");
|
||||
if(this.syncadaptor && this.syncadaptor.getUpdatedTiddlers) {
|
||||
this.logger.log("Retrieving updated tiddler list");
|
||||
cancelNextSync();
|
||||
@@ -329,7 +336,7 @@ Syncer.prototype.syncFromServer = function() {
|
||||
});
|
||||
if(updates.modifications.length > 0 || updates.deletions.length > 0) {
|
||||
self.processTaskQueue();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if(this.syncadaptor && this.syncadaptor.getSkinnyTiddlers) {
|
||||
@@ -472,7 +479,7 @@ Syncer.prototype.handleLogoutEvent = function() {
|
||||
if(this.syncadaptor.logout) {
|
||||
this.syncadaptor.logout(function(err) {
|
||||
if(err) {
|
||||
self.displayError("Logout Error",err);
|
||||
self.logger.alert(err);
|
||||
} else {
|
||||
self.getStatus();
|
||||
}
|
||||
@@ -509,7 +516,7 @@ Syncer.prototype.processTaskQueue = function() {
|
||||
} else {
|
||||
self.updateDirtyStatus();
|
||||
// Process the next task
|
||||
self.processTaskQueue.call(self);
|
||||
self.processTaskQueue.call(self);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@@ -517,11 +524,11 @@ Syncer.prototype.processTaskQueue = function() {
|
||||
this.updateDirtyStatus();
|
||||
// And trigger a timeout if there is a pending task
|
||||
if(task === true) {
|
||||
this.triggerTimeout();
|
||||
this.triggerTimeout();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.updateDirtyStatus();
|
||||
this.updateDirtyStatus();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -555,7 +562,7 @@ Syncer.prototype.chooseNextTask = function() {
|
||||
isReadyToSave = !tiddlerInfo || !tiddlerInfo.timestampLastSaved || tiddlerInfo.timestampLastSaved < thresholdLastSaved;
|
||||
if(hasChanged) {
|
||||
if(isReadyToSave) {
|
||||
return new SaveTiddlerTask(this,title);
|
||||
return new SaveTiddlerTask(this,title);
|
||||
} else {
|
||||
havePending = true;
|
||||
}
|
||||
@@ -594,7 +601,10 @@ SaveTiddlerTask.prototype.run = function(callback) {
|
||||
tiddler = this.syncer.wiki.tiddlerExists(this.title) && this.syncer.wiki.getTiddler(this.title);
|
||||
this.syncer.logger.log("Dispatching 'save' task:",this.title);
|
||||
if(tiddler) {
|
||||
this.syncer.syncadaptor.saveTiddler(tiddler,function(err,adaptorInfo,revision) {
|
||||
this.syncer.syncadaptor.saveTiddler(tiddler,{
|
||||
changeCount: changeCount,
|
||||
tiddlerInfo: self.syncer.tiddlerInfo[self.title]
|
||||
},function(err,adaptorInfo,revision) {
|
||||
// If there's an error, exit without changing any internal state
|
||||
if(err) {
|
||||
return callback(err);
|
||||
@@ -608,8 +618,6 @@ SaveTiddlerTask.prototype.run = function(callback) {
|
||||
};
|
||||
// Invoke the callback
|
||||
callback(null);
|
||||
},{
|
||||
tiddlerInfo: self.syncer.tiddlerInfo[self.title]
|
||||
});
|
||||
} else {
|
||||
this.syncer.logger.log(" Not Dispatching 'save' task:",this.title,"tiddler does not exist");
|
||||
@@ -626,7 +634,9 @@ function DeleteTiddlerTask(syncer,title) {
|
||||
DeleteTiddlerTask.prototype.run = function(callback) {
|
||||
var self = this;
|
||||
this.syncer.logger.log("Dispatching 'delete' task:",this.title);
|
||||
this.syncer.syncadaptor.deleteTiddler(this.title,function(err) {
|
||||
this.syncer.syncadaptor.deleteTiddler(this.title,{
|
||||
tiddlerInfo: self.syncer.tiddlerInfo[this.title]
|
||||
},function(err,adaptorInfo) {
|
||||
// If there's an error, exit without changing any internal state
|
||||
if(err) {
|
||||
return callback(err);
|
||||
@@ -635,8 +645,6 @@ DeleteTiddlerTask.prototype.run = function(callback) {
|
||||
delete self.syncer.tiddlerInfo[self.title];
|
||||
// Invoke the callback
|
||||
callback(null);
|
||||
},{
|
||||
tiddlerInfo: self.syncer.tiddlerInfo[this.title]
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ Browser data transfer utilities, used with the clipboard and drag and drop
|
||||
Options:
|
||||
|
||||
domNode: dom node to make draggable
|
||||
dragImageType: "pill", "blank" or "dom" (the default)
|
||||
dragImageType: "pill" or "dom"
|
||||
dragTiddlerFn: optional function to retrieve the title of tiddler to drag
|
||||
dragFilterFn: optional function to retreive the filter defining a list of tiddlers to drag
|
||||
widget: widget to use as the contect for the filter
|
||||
@@ -73,9 +73,6 @@ exports.makeDraggable = function(options) {
|
||||
if(dataTransfer.setDragImage) {
|
||||
if(dragImageType === "pill") {
|
||||
dataTransfer.setDragImage(dragImage.firstChild,-16,-16);
|
||||
} else if (dragImageType === "blank") {
|
||||
dragImage.removeChild(dragImage.firstChild);
|
||||
dataTransfer.setDragImage(dragImage,0,0);
|
||||
} else {
|
||||
var r = domNode.getBoundingClientRect();
|
||||
dataTransfer.setDragImage(domNode,event.clientX-r.left,event.clientY-r.top);
|
||||
@@ -167,7 +164,7 @@ var importDataTypes = [
|
||||
}},
|
||||
{type: "URL", IECompatible: true, toTiddlerFieldsArray: function(data,fallbackTitle) {
|
||||
// Check for tiddler data URI
|
||||
var match = $tw.utils.decodeURIComponentSafe(data).match(/^data\:text\/vnd\.tiddler,(.*)/i);
|
||||
var match = decodeURIComponent(data).match(/^data\:text\/vnd\.tiddler,(.*)/i);
|
||||
if(match) {
|
||||
return parseJSONTiddlers(match[1],fallbackTitle);
|
||||
} else {
|
||||
@@ -176,7 +173,7 @@ var importDataTypes = [
|
||||
}},
|
||||
{type: "text/x-moz-url", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {
|
||||
// Check for tiddler data URI
|
||||
var match = $tw.utils.decodeURIComponentSafe(data).match(/^data\:text\/vnd\.tiddler,(.*)/i);
|
||||
var match = decodeURIComponent(data).match(/^data\:text\/vnd\.tiddler,(.*)/i);
|
||||
if(match) {
|
||||
return parseJSONTiddlers(match[1],fallbackTitle);
|
||||
} else {
|
||||
|
||||
@@ -34,23 +34,6 @@ exports.httpRequest = function(options) {
|
||||
});
|
||||
return result;
|
||||
},
|
||||
getHeader = function(targetHeader) {
|
||||
return headers[targetHeader] || headers[targetHeader.toLowerCase()];
|
||||
},
|
||||
isSimpleRequest = function(type,headers) {
|
||||
if(["GET","HEAD","POST"].indexOf(type) === -1) {
|
||||
return false;
|
||||
}
|
||||
for(var header in headers) {
|
||||
if(["accept","accept-language","content-language","content-type"].indexOf(header.toLowerCase()) === -1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(hasHeader("Content-Type") && ["application/x-www-form-urlencoded","multipart/form-data","text/plain"].indexOf(getHeader["Content-Type"]) === -1) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
returnProp = options.returnProp || "responseText",
|
||||
request = new XMLHttpRequest(),
|
||||
data = "",
|
||||
@@ -93,7 +76,7 @@ exports.httpRequest = function(options) {
|
||||
if(data && !hasHeader("Content-Type")) {
|
||||
request.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
|
||||
}
|
||||
if(!hasHeader("X-Requested-With") && !isSimpleRequest(type,headers)) {
|
||||
if(!hasHeader("X-Requested-With")) {
|
||||
request.setRequestHeader("X-Requested-With","TiddlyWiki");
|
||||
}
|
||||
try {
|
||||
|
||||
@@ -243,7 +243,6 @@ Modal.prototype.adjustPageClass = function() {
|
||||
if(windowContainer) {
|
||||
$tw.utils.toggleClass(windowContainer,"tc-modal-displayed",this.modalCount > 0);
|
||||
}
|
||||
$tw.utils.toggleClass(this.srcDocument.body,"tc-modal-prevent-scroll",this.modalCount > 0);
|
||||
};
|
||||
|
||||
exports.Modal = Modal;
|
||||
|
||||
@@ -235,7 +235,7 @@ Object.defineProperty(TW_Element.prototype, "innerHTML", {
|
||||
if(node instanceof TW_Element) {
|
||||
b.push(node.outerHTML);
|
||||
} else if(node instanceof TW_TextNode) {
|
||||
b.push($tw.utils.htmlTextEncode(node.textContent));
|
||||
b.push($tw.utils.htmlEncode(node.textContent));
|
||||
}
|
||||
});
|
||||
return b.join("");
|
||||
|
||||
@@ -228,7 +228,6 @@ exports.generateTiddlerFileInfo = function(tiddler,options) {
|
||||
hasUnsafeFields = hasUnsafeFields || /[\x00-\x1F]/mg.test(value);
|
||||
hasUnsafeFields = hasUnsafeFields || ($tw.utils.trim(value) !== value);
|
||||
}
|
||||
hasUnsafeFields = hasUnsafeFields || /:/mg.test(fieldName);
|
||||
});
|
||||
// Check for field values
|
||||
if(hasUnsafeFields) {
|
||||
|
||||
@@ -95,15 +95,6 @@ LinkedList.prototype.toArray = function() {
|
||||
return output;
|
||||
};
|
||||
|
||||
LinkedList.prototype.makeTiddlerIterator = function(wiki) {
|
||||
var self = this;
|
||||
return function(callback) {
|
||||
self.each(function(title) {
|
||||
callback(wiki.getTiddler(title),title);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
function _removeOne(list,value) {
|
||||
var prevEntry = list.prev[value],
|
||||
nextEntry = list.next[value],
|
||||
|
||||
@@ -199,8 +199,6 @@ exports.transliterationPairs = {
|
||||
"Nj":"N",
|
||||
"Ñ":"N",
|
||||
"NJ":"NJ",
|
||||
"ð":"d",
|
||||
"Ð":"D",
|
||||
"Ó":"O",
|
||||
"Ŏ":"O",
|
||||
"Ǒ":"O",
|
||||
@@ -267,8 +265,6 @@ exports.transliterationPairs = {
|
||||
"Ɽ":"R",
|
||||
"Ꜿ":"C",
|
||||
"Ǝ":"E",
|
||||
"ß":"ss",
|
||||
"ẞ":"SS",
|
||||
"Ś":"S",
|
||||
"Ṥ":"S",
|
||||
"Š":"S",
|
||||
@@ -279,8 +275,6 @@ exports.transliterationPairs = {
|
||||
"Ṡ":"S",
|
||||
"Ṣ":"S",
|
||||
"Ṩ":"S",
|
||||
"þ": "th",
|
||||
"Þ": "TH",
|
||||
"Ť":"T",
|
||||
"Ţ":"T",
|
||||
"Ṱ":"T",
|
||||
@@ -913,8 +907,7 @@ exports.transliterationPairs = {
|
||||
"т":"t",
|
||||
"ь":"'",
|
||||
"б":"b",
|
||||
"ю":"yu",
|
||||
"…":"..."
|
||||
"ю":"yu"
|
||||
};
|
||||
|
||||
exports.transliterate = function(str) {
|
||||
|
||||
@@ -223,7 +223,6 @@ exports.removeArrayEntries = function(array,value) {
|
||||
array.splice(p,1);
|
||||
}
|
||||
}
|
||||
return array;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -383,15 +382,6 @@ exports.formatDateString = function(date,template) {
|
||||
[/^0WW/, function() {
|
||||
return $tw.utils.pad($tw.utils.getWeek(date));
|
||||
}],
|
||||
[/^0ddddd/, function() {
|
||||
return $tw.utils.pad(Math.floor((date - new Date(date.getFullYear(), 0, 0)) / 1000 / 60 / 60 / 24),3);
|
||||
}],
|
||||
[/^ddddd/, function() {
|
||||
return Math.floor((date - new Date(date.getFullYear(), 0, 0)) / 1000 / 60 / 60 / 24);
|
||||
}],
|
||||
[/^dddd/, function() {
|
||||
return [7,1,2,3,4,5,6][date.getDay()];
|
||||
}],
|
||||
[/^ddd/, function() {
|
||||
return $tw.language.getString("Date/Short/Day/" + date.getDay());
|
||||
}],
|
||||
@@ -750,8 +740,9 @@ exports.isValidFieldName = function(name) {
|
||||
if(!name || typeof name !== "string") {
|
||||
return false;
|
||||
}
|
||||
// Since v5.2.x, there are no restrictions on characters in field names
|
||||
return name;
|
||||
name = name.toLowerCase().trim();
|
||||
var fieldValidatorRegEx = /^[a-z0-9\-\._]+$/mg;
|
||||
return fieldValidatorRegEx.test(name);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -978,22 +969,4 @@ exports.makeCompareFunction = function(type,options) {
|
||||
return (types[type] || types[options.defaultType] || types.number);
|
||||
};
|
||||
|
||||
exports.decodeURIComponentSafe = function(str) {
|
||||
var value = str;
|
||||
try {
|
||||
value = decodeURIComponent(str);
|
||||
} catch(e) {
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
exports.decodeURISafe = function(str) {
|
||||
var value = str;
|
||||
try {
|
||||
value = decodeURI(str);
|
||||
} catch(e) {
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
@@ -58,10 +58,9 @@ Invoke the action associated with this widget
|
||||
*/
|
||||
ConfirmWidget.prototype.invokeAction = function(triggeringWidget,event) {
|
||||
var invokeActions = true,
|
||||
handled = true,
|
||||
win = event && event.event && event.event.view ? event.event.view : window;
|
||||
handled = true;
|
||||
if(this.prompt) {
|
||||
invokeActions = win.confirm(this.message);
|
||||
invokeActions = confirm(this.message);
|
||||
}
|
||||
if(invokeActions) {
|
||||
handled = this.invokeActions(triggeringWidget,event);
|
||||
@@ -75,4 +74,4 @@ ConfirmWidget.prototype.allowActionPropagation = function() {
|
||||
|
||||
exports["action-confirm"] = ConfirmWidget;
|
||||
|
||||
})();
|
||||
})();
|
||||
@@ -27,11 +27,8 @@ CreateTiddlerWidget.prototype = new Widget();
|
||||
Render this widget into the DOM
|
||||
*/
|
||||
CreateTiddlerWidget.prototype.render = function(parent,nextSibling) {
|
||||
this.parentDomNode = parent;
|
||||
this.computeAttributes();
|
||||
this.execute();
|
||||
// Render children
|
||||
this.renderChildren(parent,nextSibling);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -47,8 +44,7 @@ CreateTiddlerWidget.prototype.execute = function() {
|
||||
this.actionTemplate = this.getAttribute("$template");
|
||||
this.useTemplate = !!this.actionTemplate;
|
||||
this.actionOverwrite = this.getAttribute("$overwrite","no");
|
||||
// Construct the child widgets
|
||||
this.makeChildWidgets();
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -90,21 +86,18 @@ CreateTiddlerWidget.prototype.invokeAction = function(triggeringWidget,event) {
|
||||
if (!this.hasBase && this.useTemplate) {
|
||||
title = this.wiki.generateNewTitle(this.actionTemplate);
|
||||
} else if (!this.hasBase && !this.useTemplate) {
|
||||
// If no $basetitle and no $template then use initial title
|
||||
// If NO $basetitle AND NO $template use initial title
|
||||
// DON'T overwrite any stuff
|
||||
title = this.wiki.generateNewTitle(title);
|
||||
}
|
||||
var templateTiddler = this.wiki.getTiddler(this.actionTemplate) || {};
|
||||
this.wiki.addTiddler(new $tw.Tiddler(templateTiddler.fields,creationFields,fields,modificationFields,{title: title}));
|
||||
var draftTitle = this.wiki.generateDraftTitle(title);
|
||||
var tiddler = this.wiki.addTiddler(new $tw.Tiddler(templateTiddler.fields,creationFields,fields,modificationFields,{title: title}));
|
||||
if(this.actionSaveTitle) {
|
||||
this.wiki.setTextReference(this.actionSaveTitle,title,this.getVariable("currentTiddler"));
|
||||
}
|
||||
if(this.actionSaveDraftTitle) {
|
||||
this.wiki.setTextReference(this.actionSaveDraftTitle,draftTitle,this.getVariable("currentTiddler"));
|
||||
this.wiki.setTextReference(this.actionSaveDraftTitle,this.wiki.generateDraftTitle(title),this.getVariable("currentTiddler"));
|
||||
}
|
||||
this.setVariable("createTiddler-title",title);
|
||||
this.setVariable("createTiddler-draftTitle",draftTitle);
|
||||
this.refreshChildren();
|
||||
return true; // Action was invoked
|
||||
};
|
||||
|
||||
|
||||
@@ -70,18 +70,7 @@ NavigateWidget.prototype.invokeAction = function(triggeringWidget,event) {
|
||||
navigateFromNode: triggeringWidget,
|
||||
navigateFromClientRect: bounds && { top: bounds.top, left: bounds.left, width: bounds.width, right: bounds.right, bottom: bounds.bottom, height: bounds.height
|
||||
},
|
||||
navigateFromClientTop: bounds && bounds.top,
|
||||
navigateFromClientLeft: bounds && bounds.left,
|
||||
navigateFromClientWidth: bounds && bounds.width,
|
||||
navigateFromClientRight: bounds && bounds.right,
|
||||
navigateFromClientBottom: bounds && bounds.bottom,
|
||||
navigateFromClientHeight: bounds && bounds.height,
|
||||
navigateSuppressNavigation: suppressNavigation,
|
||||
metaKey: event.metaKey,
|
||||
ctrlKey: event.ctrlKey,
|
||||
altKey: event.altKey,
|
||||
shiftKey: event.shiftKey,
|
||||
event: event
|
||||
navigateSuppressNavigation: suppressNavigation
|
||||
});
|
||||
return true; // Action was invoked
|
||||
};
|
||||
|
||||
@@ -54,7 +54,6 @@ DraggableWidget.prototype.render = function(parent,nextSibling) {
|
||||
dragFilterFn: function() {return self.getAttribute("filter");},
|
||||
startActions: self.startActions,
|
||||
endActions: self.endActions,
|
||||
dragImageType: self.dragImageType,
|
||||
widget: this
|
||||
});
|
||||
// Insert the link into the DOM and render any children
|
||||
@@ -72,7 +71,6 @@ DraggableWidget.prototype.execute = function() {
|
||||
this.draggableClasses = this.getAttribute("class");
|
||||
this.startActions = this.getAttribute("startactions");
|
||||
this.endActions = this.getAttribute("endactions");
|
||||
this.dragImageType = this.getAttribute("dragimagetype");
|
||||
// Make the child widgets
|
||||
this.makeChildWidgets();
|
||||
};
|
||||
|
||||
@@ -46,7 +46,7 @@ EventWidget.prototype.render = function(parent,nextSibling) {
|
||||
$tw.utils.each(this.types,function(type) {
|
||||
domNode.addEventListener(type,function(event) {
|
||||
var selector = self.getAttribute("selector"),
|
||||
actions = self.getAttribute("$"+type) || self.getAttribute("actions-"+type),
|
||||
actions = self.getAttribute("actions-"+type),
|
||||
stopPropagation = self.getAttribute("stopPropagation","onaction"),
|
||||
selectedNode = event.target,
|
||||
selectedNodeRect,
|
||||
@@ -76,22 +76,16 @@ EventWidget.prototype.render = function(parent,nextSibling) {
|
||||
variables["tv-selectednode-posy"] = selectedNode.offsetTop.toString();
|
||||
variables["tv-selectednode-width"] = selectedNode.offsetWidth.toString();
|
||||
variables["tv-selectednode-height"] = selectedNode.offsetHeight.toString();
|
||||
|
||||
if(event.clientX && event.clientY) {
|
||||
//Add variables for event X and Y position relative to selected node
|
||||
selectedNodeRect = selectedNode.getBoundingClientRect();
|
||||
variables["event-fromselected-posx"] = (event.clientX - selectedNodeRect.left).toString();
|
||||
variables["event-fromselected-posy"] = (event.clientY - selectedNodeRect.top).toString();
|
||||
|
||||
//Add variables for event X and Y position relative to event catcher node
|
||||
catcherNodeRect = self.domNode.getBoundingClientRect();
|
||||
variables["event-fromcatcher-posx"] = (event.clientX - catcherNodeRect.left).toString();
|
||||
variables["event-fromcatcher-posy"] = (event.clientY - catcherNodeRect.top).toString();
|
||||
//Add variables for event X and Y position relative to selected node
|
||||
selectedNodeRect = selectedNode.getBoundingClientRect();
|
||||
variables["event-fromselected-posx"] = (event.clientX - selectedNodeRect.left).toString();
|
||||
variables["event-fromselected-posy"] = (event.clientY - selectedNodeRect.top).toString();
|
||||
|
||||
//Add variables for event X and Y position relative to the viewport
|
||||
variables["event-fromviewport-posx"] = event.clientX.toString();
|
||||
variables["event-fromviewport-posy"] = event.clientY.toString();
|
||||
}
|
||||
//Add variables for event X and Y position relative to event catcher node
|
||||
catcherNodeRect = self.domNode.getBoundingClientRect();
|
||||
variables["event-fromcatcher-posx"] = (event.clientX - catcherNodeRect.left).toString();
|
||||
variables["event-fromcatcher-posy"] = (event.clientY - catcherNodeRect.top).toString();
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
@@ -141,15 +135,7 @@ Compute the internal state of the widget
|
||||
EventWidget.prototype.execute = function() {
|
||||
var self = this;
|
||||
// Get attributes that require a refresh on change
|
||||
this.types = [];
|
||||
$tw.utils.each(this.attributes,function(value,key) {
|
||||
if(key.charAt(0) === "$") {
|
||||
self.types.push(key.slice(1));
|
||||
}
|
||||
});
|
||||
if(!this.types.length) {
|
||||
this.types = this.getAttribute("events","").split(" ");
|
||||
}
|
||||
this.types = this.getAttribute("events","").split(" ");
|
||||
this.elementTag = this.getAttribute("tag");
|
||||
// Make child widgets
|
||||
this.makeChildWidgets();
|
||||
@@ -165,13 +151,12 @@ EventWidget.prototype.assignDomNodeClasses = function() {
|
||||
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
|
||||
*/
|
||||
EventWidget.prototype.refresh = function(changedTiddlers) {
|
||||
var changedAttributes = this.computeAttributes(),
|
||||
changedAttributesCount = $tw.utils.count(changedAttributes);
|
||||
if(changedAttributesCount === 1 && changedAttributes["class"]) {
|
||||
this.assignDomNodeClasses();
|
||||
} else if(changedAttributesCount > 0) {
|
||||
var changedAttributes = this.computeAttributes();
|
||||
if(changedAttributes["events"] || changedAttributes["tag"]) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
} else if(changedAttributes["class"]) {
|
||||
this.assignDomNodeClasses();
|
||||
}
|
||||
return this.refreshChildren(changedTiddlers);
|
||||
};
|
||||
|
||||
@@ -73,12 +73,26 @@ FieldManglerWidget.prototype.handleRemoveFieldEvent = function(event) {
|
||||
FieldManglerWidget.prototype.handleAddFieldEvent = function(event) {
|
||||
var tiddler = this.wiki.getTiddler(this.mangleTitle),
|
||||
addition = this.wiki.getModificationFields(),
|
||||
hadInvalidFieldName = false,
|
||||
addField = function(name,value) {
|
||||
var trimmedName = name.trim();
|
||||
if(!value && tiddler) {
|
||||
value = tiddler.fields[trimmedName];
|
||||
var trimmedName = name.toLowerCase().trim();
|
||||
if(!$tw.utils.isValidFieldName(trimmedName)) {
|
||||
if(!hadInvalidFieldName) {
|
||||
alert($tw.language.getString(
|
||||
"InvalidFieldName",
|
||||
{variables:
|
||||
{fieldName: trimmedName}
|
||||
}
|
||||
));
|
||||
hadInvalidFieldName = true;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if(!value && tiddler) {
|
||||
value = tiddler.fields[trimmedName];
|
||||
}
|
||||
addition[trimmedName] = value || "";
|
||||
}
|
||||
addition[trimmedName] = value || "";
|
||||
return;
|
||||
};
|
||||
addition.title = this.mangleTitle;
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
/*\
|
||||
title: $:/core/modules/widgets/jsontiddler.js
|
||||
type: application/javascript
|
||||
module-type: widget
|
||||
|
||||
Render a tiddler as JSON text
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
||||
|
||||
var JSONTiddlerWidget = function(parseTreeNode,options) {
|
||||
this.initialise(parseTreeNode,options);
|
||||
};
|
||||
|
||||
/*
|
||||
Inherit from the base widget class
|
||||
*/
|
||||
JSONTiddlerWidget.prototype = new Widget();
|
||||
|
||||
/*
|
||||
Render this widget into the DOM
|
||||
*/
|
||||
JSONTiddlerWidget.prototype.render = function(parent,nextSibling) {
|
||||
var self = this;
|
||||
this.parentDomNode = parent;
|
||||
this.computeAttributes();
|
||||
this.execute();
|
||||
// Collect the fields from the optional base tiddler
|
||||
var fields = this.getTiddlerFields();
|
||||
// Add custom fields specified in attributes starting with $
|
||||
$tw.utils.each(this.attributes,function(attribute,name) {
|
||||
if(name.charAt(0) === "$") {
|
||||
fields[name.slice(1)] = attribute;
|
||||
}
|
||||
});
|
||||
// JSONify
|
||||
var json = JSON.stringify(fields);
|
||||
// Escape unsafe script characters
|
||||
if(this.attEscapeUnsafeScriptChars) {
|
||||
json = json.replace(/</g,"\\u003C");
|
||||
}
|
||||
// Update the DOM
|
||||
var textNode = this.document.createTextNode(json);
|
||||
parent.insertBefore(textNode,nextSibling);
|
||||
this.domNodes.push(textNode);
|
||||
};
|
||||
|
||||
/*
|
||||
Compute the internal state of the widget
|
||||
*/
|
||||
JSONTiddlerWidget.prototype.execute = function() {
|
||||
this.attTiddler = this.getAttribute("tiddler");
|
||||
this.attExclude = this.getAttribute("exclude","");
|
||||
this.attEscapeUnsafeScriptChars = this.getAttribute("escapeUnsafeScriptChars","no") === "yes";
|
||||
};
|
||||
|
||||
/*
|
||||
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
|
||||
*/
|
||||
JSONTiddlerWidget.prototype.refresh = function(changedTiddlers) {
|
||||
var changedAttributes = this.computeAttributes();
|
||||
if($tw.utils.count(changedAttributes) > 0 || (this.attTiddler && changedTiddlers[this.attTiddler])) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
JSONTiddlerWidget.prototype.getTiddlerFields = function() {
|
||||
var fields = {};
|
||||
if(this.attTiddler) {
|
||||
var tiddler = this.wiki.getTiddler(this.attTiddler);
|
||||
if(tiddler) {
|
||||
fields = tiddler.getFieldStrings({exclude: this.attExclude.split(" ")});
|
||||
} else {
|
||||
fields = {title: this.attTiddler};
|
||||
}
|
||||
}
|
||||
return fields;
|
||||
};
|
||||
|
||||
exports.jsontiddler = JSONTiddlerWidget;
|
||||
|
||||
})();
|
||||
@@ -40,8 +40,9 @@ KeyboardWidget.prototype.render = function(parent,nextSibling) {
|
||||
// Create element
|
||||
var domNode = this.document.createElement(tag);
|
||||
// Assign classes
|
||||
this.domNode = domNode;
|
||||
this.assignDomNodeClasses();
|
||||
var classes = (this["class"] || "").split(" ");
|
||||
classes.push("tc-keyboard");
|
||||
domNode.className = classes.join(" ");
|
||||
// Add a keyboard event handler
|
||||
$tw.utils.addEventListeners(domNode,[
|
||||
{name: "keydown", handlerObject: this, handlerMethod: "handleChangeEvent"}
|
||||
@@ -53,8 +54,7 @@ KeyboardWidget.prototype.render = function(parent,nextSibling) {
|
||||
};
|
||||
|
||||
KeyboardWidget.prototype.handleChangeEvent = function(event) {
|
||||
var keyInfo = $tw.keyboardManager.getMatchingKeyDescriptor(event,this.keyInfoArray);
|
||||
if(keyInfo) {
|
||||
if($tw.keyboardManager.checkKeyDescriptors(event,this.keyInfoArray)) {
|
||||
var handled = this.invokeActions(this,event);
|
||||
if(this.actions) {
|
||||
var variables = {
|
||||
@@ -62,9 +62,6 @@ KeyboardWidget.prototype.handleChangeEvent = function(event) {
|
||||
"event-code": event.code,
|
||||
"modifier": $tw.keyboardManager.getEventModifierKeyDescriptor(event)
|
||||
};
|
||||
if(keyInfo.keyDescriptor) {
|
||||
variables["event-key-descriptor"] = keyInfo.keyDescriptor;
|
||||
}
|
||||
this.invokeActionString(this.actions,this,event,variables);
|
||||
}
|
||||
this.dispatchMessage(event);
|
||||
@@ -93,6 +90,7 @@ KeyboardWidget.prototype.execute = function() {
|
||||
this.key = this.getAttribute("key","");
|
||||
this.tag = this.getAttribute("tag","");
|
||||
this.keyInfoArray = $tw.keyboardManager.parseKeyDescriptors(this.key);
|
||||
this["class"] = this.getAttribute("class","");
|
||||
if(this.key.substr(0,2) === "((" && this.key.substr(-2,2) === "))") {
|
||||
this.shortcutTiddlers = [];
|
||||
var name = this.key.substring(2,this.key.length -2);
|
||||
@@ -104,22 +102,14 @@ KeyboardWidget.prototype.execute = function() {
|
||||
this.makeChildWidgets();
|
||||
};
|
||||
|
||||
KeyboardWidget.prototype.assignDomNodeClasses = function() {
|
||||
var classes = this.getAttribute("class","").split(" ");
|
||||
classes.push("tc-keyboard");
|
||||
this.domNode.className = classes.join(" ");
|
||||
};
|
||||
|
||||
/*
|
||||
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
|
||||
*/
|
||||
KeyboardWidget.prototype.refresh = function(changedTiddlers) {
|
||||
var changedAttributes = this.computeAttributes();
|
||||
if(changedAttributes.message || changedAttributes.param || changedAttributes.key || changedAttributes.tag) {
|
||||
if(changedAttributes.message || changedAttributes.param || changedAttributes.key || changedAttributes["class"] || changedAttributes.tag) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
} else if(changedAttributes["class"]) {
|
||||
this.assignDomNodeClasses();
|
||||
}
|
||||
// Update the keyInfoArray if one of its shortcut-config-tiddlers has changed
|
||||
if(this.shortcutTiddlers && $tw.utils.hopArray(changedTiddlers,this.shortcutTiddlers)) {
|
||||
|
||||
@@ -154,12 +154,6 @@ LinkWidget.prototype.handleClickEvent = function(event) {
|
||||
navigateFromNode: this,
|
||||
navigateFromClientRect: { top: bounds.top, left: bounds.left, width: bounds.width, right: bounds.right, bottom: bounds.bottom, height: bounds.height
|
||||
},
|
||||
navigateFromClientTop: bounds.top,
|
||||
navigateFromClientLeft: bounds.left,
|
||||
navigateFromClientWidth: bounds.width,
|
||||
navigateFromClientRight: bounds.right,
|
||||
navigateFromClientBottom: bounds.bottom,
|
||||
navigateFromClientHeight: bounds.height,
|
||||
navigateSuppressNavigation: event.metaKey || event.ctrlKey || (event.button === 1),
|
||||
metaKey: event.metaKey,
|
||||
ctrlKey: event.ctrlKey,
|
||||
|
||||
@@ -236,11 +236,6 @@ ListWidget.prototype.handleListChanges = function(changedTiddlers) {
|
||||
hasRefreshed = hasRefreshed || refreshed;
|
||||
}
|
||||
}
|
||||
// If there are items to remove and we have not refreshed then recreate the item that will now be at the last position
|
||||
if(!hasRefreshed && this.children.length > this.list.length) {
|
||||
this.removeListItem(this.list.length-1);
|
||||
this.insertListItem(this.list.length-1,this.list[this.list.length-1]);
|
||||
}
|
||||
} else {
|
||||
// Cycle through the list, inserting and removing list items as needed
|
||||
for(t=0; t<this.list.length; t++) {
|
||||
|
||||
@@ -33,54 +33,12 @@ MessageCatcherWidget.prototype.render = function(parent,nextSibling) {
|
||||
// Compute attributes and execute state
|
||||
this.computeAttributes();
|
||||
this.execute();
|
||||
// Helper to add an event handler
|
||||
var addEventHandler = function(type,actions) {
|
||||
if(type && actions) {
|
||||
var isActionStringExecuting = false;
|
||||
self.addEventListener(
|
||||
type,
|
||||
function(event) {
|
||||
// Don't trap the event if it came from one of our action handlers
|
||||
if(isActionStringExecuting) {
|
||||
return true;
|
||||
}
|
||||
// Collect all the event properties into variables
|
||||
var collectProps = function(obj,prefix) {
|
||||
prefix = prefix || "";
|
||||
var props = {},
|
||||
names = [];
|
||||
$tw.utils.each(obj,function(value,name) {
|
||||
if(["string","boolean","number"].indexOf(typeof value) !== -1) {
|
||||
names.push(name);
|
||||
props[prefix + "-" + name] = value.toString();
|
||||
}
|
||||
});
|
||||
props["list-" + prefix] = $tw.utils.stringifyList(names);
|
||||
return props;
|
||||
};
|
||||
var variables = $tw.utils.extend(
|
||||
{},
|
||||
collectProps(event.paramObject,"event-paramObject"),
|
||||
collectProps(event,"event"),
|
||||
{
|
||||
modifier: $tw.keyboardManager.getEventModifierKeyDescriptor(event)
|
||||
});
|
||||
isActionStringExecuting = true;
|
||||
self.invokeActionString(actions,self,event,variables);
|
||||
isActionStringExecuting = false;
|
||||
return false;
|
||||
}
|
||||
);
|
||||
}
|
||||
// Add our message handler
|
||||
if(this.messageType) {
|
||||
this.addEventListeners([
|
||||
{type: this.messageType, handler: "handleEvent"}
|
||||
]);
|
||||
}
|
||||
// Add the main event handler
|
||||
addEventHandler(this.getAttribute("type"),this.getAttribute("actions"));
|
||||
// Add any other event handlers
|
||||
$tw.utils.each(this.attributes,function(value,key) {
|
||||
if(key.charAt(0) === "$") {
|
||||
addEventHandler(key.slice(1),value);
|
||||
}
|
||||
});
|
||||
// Render children
|
||||
this.renderChildren(parent,null);
|
||||
};
|
||||
@@ -89,16 +47,48 @@ MessageCatcherWidget.prototype.render = function(parent,nextSibling) {
|
||||
Compute the internal state of the widget
|
||||
*/
|
||||
MessageCatcherWidget.prototype.execute = function() {
|
||||
var self = this;
|
||||
// Get attributes that require a refresh on change
|
||||
this.messageType = this.getAttribute("type");
|
||||
this.messageActions = this.getAttribute("actions");
|
||||
// Make child widgets
|
||||
this.makeChildWidgets();
|
||||
};
|
||||
|
||||
/*
|
||||
Handle an event
|
||||
*/
|
||||
MessageCatcherWidget.prototype.handleEvent = function(event) {
|
||||
if(this.messageActions) {
|
||||
// Collect all the event properties into variables
|
||||
var collectProps = function(obj,prefix) {
|
||||
prefix = prefix || "";
|
||||
var props = {};
|
||||
$tw.utils.each(obj,function(value,name) {
|
||||
if(["string","boolean","number"].indexOf(typeof value) !== -1) {
|
||||
props[prefix + name] = value.toString();
|
||||
}
|
||||
});
|
||||
return props;
|
||||
};
|
||||
var variables = $tw.utils.extend(
|
||||
{},
|
||||
collectProps(event.paramObject,"event-paramObject-"),
|
||||
collectProps(event,"event-"),
|
||||
{
|
||||
modifier: $tw.keyboardManager.getEventModifierKeyDescriptor(event)
|
||||
});
|
||||
this.invokeActionString(this.messageActions,this,event,variables);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/*
|
||||
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
|
||||
*/
|
||||
MessageCatcherWidget.prototype.refresh = function(changedTiddlers) {
|
||||
var changedAttributes = this.computeAttributes();
|
||||
if($tw.utils.count(changedAttributes) > 0) {
|
||||
if(changedAttributes["type"]) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -160,7 +160,6 @@ NavigatorWidget.prototype.handleNavigateEvent = function(event) {
|
||||
|
||||
// Close a specified tiddler
|
||||
NavigatorWidget.prototype.handleCloseTiddlerEvent = function(event) {
|
||||
event = $tw.hooks.invokeHook("th-closing-tiddler",event);
|
||||
var title = event.param || event.tiddlerTitle,
|
||||
storyList = this.getStoryList();
|
||||
// Look for tiddlers with this title to close
|
||||
@@ -184,8 +183,7 @@ NavigatorWidget.prototype.handleCloseOtherTiddlersEvent = function(event) {
|
||||
|
||||
// Place a tiddler in edit mode
|
||||
NavigatorWidget.prototype.handleEditTiddlerEvent = function(event) {
|
||||
var editTiddler = $tw.hooks.invokeHook("th-editing-tiddler",event),
|
||||
win = event.event && event.event.view ? event.event.view : window;
|
||||
var editTiddler = $tw.hooks.invokeHook("th-editing-tiddler",event);
|
||||
if(!editTiddler) {
|
||||
return false;
|
||||
}
|
||||
@@ -194,7 +192,7 @@ NavigatorWidget.prototype.handleEditTiddlerEvent = function(event) {
|
||||
return self.wiki.isShadowTiddler(title) && !self.wiki.tiddlerExists(title);
|
||||
}
|
||||
function confirmEditShadow(title) {
|
||||
return win.confirm($tw.language.getString(
|
||||
return confirm($tw.language.getString(
|
||||
"ConfirmEditShadowTiddler",
|
||||
{variables:
|
||||
{title: title}
|
||||
@@ -227,8 +225,7 @@ NavigatorWidget.prototype.handleDeleteTiddlerEvent = function(event) {
|
||||
storyList = this.getStoryList(),
|
||||
originalTitle = tiddler ? tiddler.fields["draft.of"] : "",
|
||||
originalTiddler = originalTitle ? this.wiki.getTiddler(originalTitle) : undefined,
|
||||
confirmationTitle,
|
||||
win = event.event && event.event.view ? event.event.view : window;
|
||||
confirmationTitle;
|
||||
if(!tiddler) {
|
||||
return false;
|
||||
}
|
||||
@@ -241,7 +238,7 @@ NavigatorWidget.prototype.handleDeleteTiddlerEvent = function(event) {
|
||||
confirmationTitle = title;
|
||||
}
|
||||
// Seek confirmation
|
||||
if((this.wiki.getTiddler(originalTitle) || (tiddler.fields.text || "") !== "") && !win.confirm($tw.language.getString(
|
||||
if((this.wiki.getTiddler(originalTitle) || (tiddler.fields.text || "") !== "") && !confirm($tw.language.getString(
|
||||
"ConfirmDeleteTiddler",
|
||||
{variables:
|
||||
{title: confirmationTitle}
|
||||
@@ -307,8 +304,7 @@ NavigatorWidget.prototype.generateDraftTitle = function(title) {
|
||||
NavigatorWidget.prototype.handleSaveTiddlerEvent = function(event) {
|
||||
var title = event.param || event.tiddlerTitle,
|
||||
tiddler = this.wiki.getTiddler(title),
|
||||
storyList = this.getStoryList(),
|
||||
win = event.event && event.event.view ? event.event.view : window;
|
||||
storyList = this.getStoryList();
|
||||
// Replace the original tiddler with the draft
|
||||
if(tiddler) {
|
||||
var draftTitle = (tiddler.fields["draft.title"] || "").trim(),
|
||||
@@ -317,7 +313,7 @@ NavigatorWidget.prototype.handleSaveTiddlerEvent = function(event) {
|
||||
var isRename = draftOf !== draftTitle,
|
||||
isConfirmed = true;
|
||||
if(isRename && this.wiki.tiddlerExists(draftTitle)) {
|
||||
isConfirmed = win.confirm($tw.language.getString(
|
||||
isConfirmed = confirm($tw.language.getString(
|
||||
"ConfirmOverwriteTiddler",
|
||||
{variables:
|
||||
{title: draftTitle}
|
||||
@@ -366,7 +362,6 @@ NavigatorWidget.prototype.handleSaveTiddlerEvent = function(event) {
|
||||
// Take a tiddler out of edit mode without saving the changes
|
||||
NavigatorWidget.prototype.handleCancelTiddlerEvent = function(event) {
|
||||
event = $tw.hooks.invokeHook("th-cancelling-tiddler", event);
|
||||
var win = event.event && event.event.view ? event.event.view : window;
|
||||
// Flip the specified tiddler from draft back to the original
|
||||
var draftTitle = event.param || event.tiddlerTitle,
|
||||
draftTiddler = this.wiki.getTiddler(draftTitle),
|
||||
@@ -377,7 +372,7 @@ NavigatorWidget.prototype.handleCancelTiddlerEvent = function(event) {
|
||||
originalTiddler = this.wiki.getTiddler(originalTitle),
|
||||
storyList = this.getStoryList();
|
||||
if(this.wiki.isDraftModified(draftTitle)) {
|
||||
isConfirmed = win.confirm($tw.language.getString(
|
||||
isConfirmed = confirm($tw.language.getString(
|
||||
"ConfirmCancelTiddler",
|
||||
{variables:
|
||||
{title: draftTitle}
|
||||
|
||||
@@ -122,7 +122,6 @@ RadioWidget.prototype.refresh = function(changedTiddlers) {
|
||||
return true;
|
||||
} else if(changedTiddlers[this.radioTitle]) {
|
||||
this.inputDomNode.checked = this.getValue() === this.radioValue;
|
||||
$tw.utils.toggleClass(this.labelDomNode,"tc-radio-selected",this.inputDomNode.checked);
|
||||
return this.refreshChildren(changedTiddlers);
|
||||
} else {
|
||||
return this.refreshChildren(changedTiddlers);
|
||||
|
||||
@@ -226,7 +226,7 @@ RevealWidget.prototype.refresh = function(changedTiddlers) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
}
|
||||
} else if(this.type === "popup" && this.isOpen && this.updatePopupPosition && (changedTiddlers[this.state] || changedTiddlers[this.stateTitle])) {
|
||||
} else if(this.type === "popup" && this.updatePopupPosition && (changedTiddlers[this.state] || changedTiddlers[this.stateTitle])) {
|
||||
this.positionPopup(this.domNode);
|
||||
}
|
||||
if(changedAttributes.style) {
|
||||
|
||||
@@ -60,8 +60,6 @@ TranscludeWidget.prototype.execute = function() {
|
||||
subTiddler: this.transcludeSubTiddler
|
||||
}),
|
||||
parseTreeNodes = parser ? parser.tree : this.parseTreeNode.children;
|
||||
this.sourceText = parser ? parser.source : null;
|
||||
this.parserType = parser? parser.type : null;
|
||||
// Set context variables for recursion detection
|
||||
var recursionMarker = this.makeRecursionMarker();
|
||||
if(this.recursionMarker === "yes") {
|
||||
@@ -100,17 +98,12 @@ TranscludeWidget.prototype.makeRecursionMarker = function() {
|
||||
return output.join("");
|
||||
};
|
||||
|
||||
TranscludeWidget.prototype.parserNeedsRefresh = function() {
|
||||
var parserInfo = this.wiki.getTextReferenceParserInfo(this.transcludeTitle,this.transcludeField,this.transcludeIndex,{subTiddler:this.transcludeSubTiddler});
|
||||
return (this.sourceText === undefined || parserInfo.sourceText !== this.sourceText || parserInfo.parserType !== this.parserType)
|
||||
};
|
||||
|
||||
/*
|
||||
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
|
||||
*/
|
||||
TranscludeWidget.prototype.refresh = function(changedTiddlers) {
|
||||
var changedAttributes = this.computeAttributes();
|
||||
if(($tw.utils.count(changedAttributes) > 0) || (changedTiddlers[this.transcludeTitle] && this.parserNeedsRefresh())) {
|
||||
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedTiddlers[this.transcludeTitle]) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
} else {
|
||||
|
||||
@@ -568,15 +568,10 @@ Widget.prototype.invokeActions = function(triggeringWidget,event) {
|
||||
var handled = false;
|
||||
// For each child widget
|
||||
for(var t=0; t<this.children.length; t++) {
|
||||
var child = this.children[t],
|
||||
childIsActionWidget = !!child.invokeAction,
|
||||
actionRefreshPolicy = child.getVariable("tv-action-refresh-policy");
|
||||
// Refresh the child if required
|
||||
if(childIsActionWidget || actionRefreshPolicy === "always") {
|
||||
child.refreshSelf();
|
||||
}
|
||||
var child = this.children[t];
|
||||
// Invoke the child if it is an action widget
|
||||
if(childIsActionWidget) {
|
||||
if(child.invokeAction) {
|
||||
child.refreshSelf();
|
||||
if(child.invokeAction(triggeringWidget,event)) {
|
||||
handled = true;
|
||||
}
|
||||
|
||||
@@ -365,108 +365,47 @@ Sort an array of tiddler titles by a specified field
|
||||
*/
|
||||
exports.sortTiddlers = function(titles,sortField,isDescending,isCaseSensitive,isNumeric,isAlphaNumeric) {
|
||||
var self = this;
|
||||
if(sortField === "title") {
|
||||
if(!isNumeric && !isAlphaNumeric) {
|
||||
if(isCaseSensitive) {
|
||||
if(isDescending) {
|
||||
titles.sort(function(a,b) {
|
||||
return b.localeCompare(a);
|
||||
});
|
||||
} else {
|
||||
titles.sort(function(a,b) {
|
||||
return a.localeCompare(b);
|
||||
});
|
||||
}
|
||||
titles.sort(function(a,b) {
|
||||
var x,y,
|
||||
compareNumbers = function(x,y) {
|
||||
var result =
|
||||
isNaN(x) && !isNaN(y) ? (isDescending ? -1 : 1) :
|
||||
!isNaN(x) && isNaN(y) ? (isDescending ? 1 : -1) :
|
||||
(isDescending ? y - x : x - y);
|
||||
return result;
|
||||
};
|
||||
if(sortField !== "title") {
|
||||
var tiddlerA = self.getTiddler(a),
|
||||
tiddlerB = self.getTiddler(b);
|
||||
if(tiddlerA) {
|
||||
a = tiddlerA.getFieldString(sortField) || "";
|
||||
} else {
|
||||
if(isDescending) {
|
||||
titles.sort(function(a,b) {
|
||||
return b.toLowerCase().localeCompare(a.toLowerCase());
|
||||
});
|
||||
} else {
|
||||
titles.sort(function(a,b) {
|
||||
return a.toLowerCase().localeCompare(b.toLowerCase());
|
||||
});
|
||||
}
|
||||
a = "";
|
||||
}
|
||||
if(tiddlerB) {
|
||||
b = tiddlerB.getFieldString(sortField) || "";
|
||||
} else {
|
||||
b = "";
|
||||
}
|
||||
} else {
|
||||
titles.sort(function(a,b) {
|
||||
var x,y;
|
||||
if(isNumeric) {
|
||||
x = Number(a);
|
||||
y = Number(b);
|
||||
if(isNaN(x)) {
|
||||
if(isNaN(y)) {
|
||||
// If neither value is a number then fall through to a textual comparison
|
||||
} else {
|
||||
return isDescending ? -1 : 1;
|
||||
}
|
||||
} else {
|
||||
if(isNaN(y)) {
|
||||
return isDescending ? 1 : -1;
|
||||
} else {
|
||||
return isDescending ? y - x : x - y;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(isAlphaNumeric) {
|
||||
return isDescending ? b.localeCompare(a,undefined,{numeric: true,sensitivity: "base"}) : a.localeCompare(b,undefined,{numeric: true,sensitivity: "base"});
|
||||
}
|
||||
if(!isCaseSensitive) {
|
||||
a = a.toLowerCase();
|
||||
b = b.toLowerCase();
|
||||
}
|
||||
return isDescending ? b.localeCompare(a) : a.localeCompare(b);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
titles.sort(function(a,b) {
|
||||
var x,y;
|
||||
if(sortField !== "title") {
|
||||
var tiddlerA = self.getTiddler(a),
|
||||
tiddlerB = self.getTiddler(b);
|
||||
if(tiddlerA) {
|
||||
a = tiddlerA.fields[sortField] || "";
|
||||
} else {
|
||||
a = "";
|
||||
}
|
||||
if(tiddlerB) {
|
||||
b = tiddlerB.fields[sortField] || "";
|
||||
} else {
|
||||
b = "";
|
||||
}
|
||||
}
|
||||
if(isNumeric) {
|
||||
x = Number(a);
|
||||
y = Number(b);
|
||||
if(isNaN(x)) {
|
||||
if(isNaN(y)) {
|
||||
// If neither value is a number then fall through to a textual comparison
|
||||
} else {
|
||||
return isDescending ? -1 : 1;
|
||||
}
|
||||
} else {
|
||||
if(isNaN(y)) {
|
||||
return isDescending ? 1 : -1;
|
||||
} else {
|
||||
return isDescending ? y - x : x - y;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(Object.prototype.toString.call(a) === "[object Date]" && Object.prototype.toString.call(b) === "[object Date]") {
|
||||
return isDescending ? b - a : a - b;
|
||||
}
|
||||
x = Number(a);
|
||||
y = Number(b);
|
||||
if(isNumeric && (!isNaN(x) || !isNaN(y))) {
|
||||
return compareNumbers(x,y);
|
||||
} else if($tw.utils.isDate(a) && $tw.utils.isDate(b)) {
|
||||
return isDescending ? b - a : a - b;
|
||||
} else if(isAlphaNumeric) {
|
||||
return isDescending ? b.localeCompare(a,undefined,{numeric: true,sensitivity: "base"}) : a.localeCompare(b,undefined,{numeric: true,sensitivity: "base"});
|
||||
} else {
|
||||
a = String(a);
|
||||
b = String(b);
|
||||
if(isAlphaNumeric) {
|
||||
return isDescending ? b.localeCompare(a,undefined,{numeric: true,sensitivity: "base"}) : a.localeCompare(b,undefined,{numeric: true,sensitivity: "base"});
|
||||
}
|
||||
if(!isCaseSensitive) {
|
||||
a = a.toLowerCase();
|
||||
b = b.toLowerCase();
|
||||
}
|
||||
return isDescending ? b.localeCompare(a) : a.localeCompare(b);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -905,7 +844,7 @@ exports.clearGlobalCache = function() {
|
||||
exports.getCacheForTiddler = function(title,cacheName,initializer) {
|
||||
this.caches = this.caches || Object.create(null);
|
||||
var caches = this.caches[title];
|
||||
if(caches && caches[cacheName] !== undefined) {
|
||||
if(caches && caches[cacheName]) {
|
||||
return caches[cacheName];
|
||||
} else {
|
||||
if(!caches) {
|
||||
@@ -998,57 +937,41 @@ exports.parseTiddler = function(title,options) {
|
||||
};
|
||||
|
||||
exports.parseTextReference = function(title,field,index,options) {
|
||||
var tiddler,
|
||||
text,
|
||||
parserInfo;
|
||||
if(!options.subTiddler) {
|
||||
var tiddler,text;
|
||||
if(options.subTiddler) {
|
||||
tiddler = this.getSubTiddler(title,options.subTiddler);
|
||||
} else {
|
||||
tiddler = this.getTiddler(title);
|
||||
if(field === "text" || (!field && !index)) {
|
||||
this.getTiddlerText(title); // Force the tiddler to be lazily loaded
|
||||
return this.parseTiddler(title,options);
|
||||
}
|
||||
}
|
||||
parserInfo = this.getTextReferenceParserInfo(title,field,index,options);
|
||||
if(parserInfo.sourceText !== null) {
|
||||
return this.parseText(parserInfo.parserType,parserInfo.sourceText,options);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
exports.getTextReferenceParserInfo = function(title,field,index,options) {
|
||||
var tiddler,
|
||||
parserInfo = {
|
||||
sourceText : null,
|
||||
parserType : "text/vnd.tiddlywiki"
|
||||
};
|
||||
if(options.subTiddler) {
|
||||
tiddler = this.getSubTiddler(title,options.subTiddler);
|
||||
} else {
|
||||
tiddler = this.getTiddler(title);
|
||||
}
|
||||
if(field === "text" || (!field && !index)) {
|
||||
if(tiddler && tiddler.fields) {
|
||||
parserInfo.sourceText = tiddler.fields.text || "";
|
||||
if(tiddler.fields.type) {
|
||||
parserInfo.parserType = tiddler.fields.type;
|
||||
}
|
||||
return this.parseText(tiddler.fields.type,tiddler.fields.text,options);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else if(field) {
|
||||
if(field === "title") {
|
||||
parserInfo.sourceText = title;
|
||||
} else if(tiddler && tiddler.fields) {
|
||||
parserInfo.sourceText = tiddler.hasField(field) ? tiddler.fields[field].toString() : null;
|
||||
text = title;
|
||||
} else {
|
||||
if(!tiddler || !tiddler.hasField(field)) {
|
||||
return null;
|
||||
}
|
||||
text = tiddler.fields[field];
|
||||
}
|
||||
return this.parseText("text/vnd.tiddlywiki",text.toString(),options);
|
||||
} else if(index) {
|
||||
this.getTiddlerText(title); // Force the tiddler to be lazily loaded
|
||||
parserInfo.sourceText = this.extractTiddlerDataItem(tiddler,index,null);
|
||||
text = this.extractTiddlerDataItem(tiddler,index,undefined);
|
||||
if(text === undefined) {
|
||||
return null;
|
||||
}
|
||||
return this.parseText("text/vnd.tiddlywiki",text,options);
|
||||
}
|
||||
if(parserInfo.sourceText === null) {
|
||||
parserInfo.parserType = null;
|
||||
}
|
||||
return parserInfo;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Make a widget tree for a parse tree
|
||||
|
||||
@@ -4,5 +4,4 @@ title: $:/core/save/all-external-js
|
||||
\define saveTiddlerFilter()
|
||||
[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$
|
||||
\end
|
||||
\define coreURL() %24%3A%2Fcore%2Ftemplates%2Ftiddlywiki5.js
|
||||
{{$:/core/templates/tiddlywiki5-external-js.html}}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
title: $:/core/save/offline-external-js
|
||||
|
||||
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
|
||||
\define saveTiddlerFilter()
|
||||
[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/plugins/tiddlywiki/filesystem]] -[[$:/plugins/tiddlywiki/tiddlyweb]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$
|
||||
\end
|
||||
\define coreURL() tiddlywikicore-$(version)$.js
|
||||
{{$:/core/templates/tiddlywiki5-external-js.html}}
|
||||
@@ -2,8 +2,4 @@ title: $:/core/templates/tiddlywiki5.js/tiddlers
|
||||
|
||||
`
|
||||
$tw.preloadTiddlerArray(`<$text text=<<jsontiddlers "[[$:/core]]">>/>`);
|
||||
$tw.preloadTiddlerArray([{
|
||||
title: "$:/config/SaveWikiButton/Template",
|
||||
text: "$:/core/save/offline-external-js"
|
||||
}]);
|
||||
`
|
||||
|
||||
@@ -2,7 +2,7 @@ title: $:/core/templates/tiddlywiki5-external-js.html
|
||||
|
||||
\rules only filteredtranscludeinline transcludeinline
|
||||
<!doctype html>
|
||||
{{$:/core/templates/MOTW.html}}<html lang="{{{ [{$:/language}get[name]] }}}">
|
||||
{{$:/core/templates/MOTW.html}}<html lang="`<$text text={{{ [{$:/language}get[name]] }}}/>`">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
||||
<!--~~ Raw markup for the top of the head section ~~-->
|
||||
@@ -43,6 +43,5 @@ title: $:/core/templates/tiddlywiki5-external-js.html
|
||||
<!--~~ Raw markup for the bottom of the body section ~~-->
|
||||
{{{ [all[shadows+tiddlers]tag[$:/tags/RawMarkupWikified/BottomBody]] ||$:/core/templates/raw-static-tiddler}}}
|
||||
</body>
|
||||
<!--~~ Load external JS ~~-->
|
||||
<script src="{{{ [<coreURL>] }}}" onerror="alert('Error: Cannot load {{{ [<coreURL>] }}}');"></script>
|
||||
<script src="%24%3A%2Fcore%2Ftemplates%2Ftiddlywiki5.js" onerror="alert('Error: Cannot load tiddlywiki.js');"></script>
|
||||
</html>
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
title: $:/core/templates/html-json-skinny-tiddler
|
||||
|
||||
<$list filter="[<numTiddlers>compare:number:gteq[1]] ~[<counter>!match[1]]">`,`<$text text=<<newline>>/></$list>
|
||||
<$jsontiddler tiddler=<<currentTiddler>> exclude="text" escapeUnsafeScriptChars="yes"/>
|
||||
@@ -1,3 +0,0 @@
|
||||
title: $:/core/templates/html-json-tiddler
|
||||
|
||||
<$list filter="[<counter>!match[1]]">`,`<$text text=<<newline>>/></$list><$jsontiddler tiddler=<<currentTiddler>> escapeUnsafeScriptChars="yes"/>
|
||||
@@ -1,37 +1,14 @@
|
||||
title: $:/core/templates/store.area.template.html
|
||||
|
||||
\whitespace trim
|
||||
<!-- Unencrypted -->
|
||||
<$list filter="[[$:/isEncrypted]get[text]else[no]match[no]]">
|
||||
<$list filter="[[storeAreaFormat]is[variable]getvariable[]else[json]match[json]]">
|
||||
<!-- New-style JSON store area, with an old-style store area for compatibility with v5.1.x tooling -->
|
||||
`<script class="tiddlywiki-tiddler-store" type="application/json">[`
|
||||
<$vars newline={{{ [charcode[10]] }}}>
|
||||
<$text text=<<newline>>/>
|
||||
<$list filter=<<saveTiddlerFilter>> counter="counter" template="$:/core/templates/html-json-tiddler"/>
|
||||
<$vars numTiddlers={{{ [subfilter<saveTiddlerFilter>count[]] }}}>
|
||||
<$list filter={{{ [<skinnySaveTiddlerFilter>] }}} counter="counter" template="$:/core/templates/html-json-skinny-tiddler"/>
|
||||
</$vars>
|
||||
<$text text=<<newline>>/>
|
||||
</$vars>
|
||||
`]</script>`
|
||||
`<div id="storeArea" style="display:none;">`
|
||||
`</div>`
|
||||
</$list>
|
||||
<$list filter="[[storeAreaFormat]is[variable]getvariable[]else[json]match[div]]">
|
||||
<!-- Old-style DIV/PRE-based store area -->
|
||||
<$reveal type="nomatch" state="$:/isEncrypted" text="yes">
|
||||
`<div id="storeArea" style="display:none;">`
|
||||
<$list filter=<<saveTiddlerFilter>> template="$:/core/templates/html-div-tiddler"/>
|
||||
<$list filter={{{ [<skinnySaveTiddlerFilter>] }}} template="$:/core/templates/html-div-skinny-tiddler"/>
|
||||
`</div>`
|
||||
</$reveal>
|
||||
</$list>
|
||||
</$list>
|
||||
<!-- Encrypted -->
|
||||
<$list filter="[[$:/isEncrypted]get[text]else[no]match[yes]]">
|
||||
`<!--~~ Encrypted tiddlers ~~-->`
|
||||
`<pre id="encryptedStoreArea" type="text/plain" style="display:none;">`
|
||||
<$encrypt filter=<<saveTiddlerFilter>>/>
|
||||
`</pre>`
|
||||
</$list>
|
||||
<$reveal type="nomatch" state="$:/isEncrypted" text="yes">
|
||||
`<div id="storeArea" style="display:none;">`
|
||||
<$list filter=<<saveTiddlerFilter>> template="$:/core/templates/html-div-tiddler"/>
|
||||
<$list filter={{{ [<skinnySaveTiddlerFilter>] }}} template="$:/core/templates/html-div-skinny-tiddler"/>
|
||||
`</div>`
|
||||
</$reveal>
|
||||
<$reveal type="match" state="$:/isEncrypted" text="yes">
|
||||
`<!--~~ Encrypted tiddlers ~~-->`
|
||||
`<pre id="encryptedStoreArea" type="text/plain" style="display:none;">`
|
||||
<$encrypt filter=<<saveTiddlerFilter>>/>
|
||||
`</pre>`
|
||||
</$reveal>
|
||||
@@ -19,73 +19,71 @@ $:/config/Plugins/Disabled/$(currentTiddler)$
|
||||
\end
|
||||
|
||||
\define plugin-table-body(type,disabledMessage,default-popup-state)
|
||||
\whitespace trim
|
||||
<div class="tc-plugin-info-chunk tc-plugin-info-toggle">
|
||||
<$reveal type="nomatch" state=<<popup-state>> text="yes" default="""$default-popup-state$""">
|
||||
<$button class="tc-btn-invisible tc-btn-dropdown" set=<<popup-state>> setTo="yes">
|
||||
{{$:/core/images/chevron-right}}
|
||||
</$button>
|
||||
</$reveal>
|
||||
<$reveal type="match" state=<<popup-state>> text="yes" default="""$default-popup-state$""">
|
||||
<$button class="tc-btn-invisible tc-btn-dropdown" set=<<popup-state>> setTo="no">
|
||||
{{$:/core/images/chevron-down}}
|
||||
</$button>
|
||||
</$reveal>
|
||||
<$reveal type="nomatch" state=<<popup-state>> text="yes" default="""$default-popup-state$""">
|
||||
<$button class="tc-btn-invisible tc-btn-dropdown" set=<<popup-state>> setTo="yes">
|
||||
{{$:/core/images/chevron-right}}
|
||||
</$button>
|
||||
</$reveal>
|
||||
<$reveal type="match" state=<<popup-state>> text="yes" default="""$default-popup-state$""">
|
||||
<$button class="tc-btn-invisible tc-btn-dropdown" set=<<popup-state>> setTo="no">
|
||||
{{$:/core/images/chevron-down}}
|
||||
</$button>
|
||||
</$reveal>
|
||||
</div>
|
||||
<div class="tc-plugin-info-chunk tc-plugin-info-icon">
|
||||
<$transclude tiddler=<<currentTiddler>> subtiddler=<<plugin-icon-title>>>
|
||||
<$transclude tiddler="$:/core/images/plugin-generic-$type$"/>
|
||||
</$transclude>
|
||||
<$transclude tiddler=<<currentTiddler>> subtiddler=<<plugin-icon-title>>>
|
||||
<$transclude tiddler="$:/core/images/plugin-generic-$type$"/>
|
||||
</$transclude>
|
||||
</div>
|
||||
<div class="tc-plugin-info-chunk tc-plugin-info-description">
|
||||
<h1>
|
||||
''<$text text={{{ [<currentTiddler>get[name]] ~[<currentTiddler>split[/]last[1]] }}}/>'': <$view field="description"><$view field="title"/></$view> $disabledMessage$
|
||||
</h1>
|
||||
<h2>
|
||||
<$view field="title"/>
|
||||
</h2>
|
||||
<h2>
|
||||
<div><em><$view field="version"/></em></div>
|
||||
</h2>
|
||||
<h1>
|
||||
''<$text text={{{ [<currentTiddler>get[name]] ~[<currentTiddler>split[/]last[1]] }}}/>'': <$view field="description"><$view field="title"/></$view> $disabledMessage$
|
||||
</h1>
|
||||
<h2>
|
||||
<$view field="title"/>
|
||||
</h2>
|
||||
<h2>
|
||||
<div><em><$view field="version"/></em></div>
|
||||
</h2>
|
||||
</div>
|
||||
\end
|
||||
|
||||
\define plugin-info(type,default-popup-state)
|
||||
\whitespace trim
|
||||
<$set name="popup-state" value=<<popup-state-macro>>>
|
||||
<$reveal type="nomatch" state=<<plugin-disable-title>> text="yes">
|
||||
<$link to={{!!title}} class="tc-plugin-info">
|
||||
<<plugin-table-body type:"$type$" default-popup-state:"""$default-popup-state$""">>
|
||||
</$link>
|
||||
</$reveal>
|
||||
<$reveal type="match" state=<<plugin-disable-title>> text="yes">
|
||||
<$link to={{!!title}} class="tc-plugin-info tc-plugin-info-disabled">
|
||||
<<plugin-table-body type:"$type$" default-popup-state:"""$default-popup-state$""" disabledMessage:"<$macrocall $name='lingo' title='Disabled/Status'/>">>
|
||||
</$link>
|
||||
</$reveal>
|
||||
<$reveal type="match" text="yes" state=<<popup-state>> default="""$default-popup-state$""">
|
||||
<div class="tc-plugin-info-dropdown">
|
||||
<div class="tc-plugin-info-dropdown-body">
|
||||
<$list filter="[all[current]] -[[$:/core]]">
|
||||
<div style="float:right;">
|
||||
<$reveal type="nomatch" state=<<plugin-disable-title>> text="yes">
|
||||
<$button set=<<plugin-disable-title>> setTo="yes" tooltip={{$:/language/ControlPanel/Plugins/Disable/Hint}} aria-label={{$:/language/ControlPanel/Plugins/Disable/Caption}}>
|
||||
<<lingo Disable/Caption>>
|
||||
</$button>
|
||||
</$reveal>
|
||||
<$reveal type="match" state=<<plugin-disable-title>> text="yes">
|
||||
<$button set=<<plugin-disable-title>> setTo="no" tooltip={{$:/language/ControlPanel/Plugins/Enable Hint}} aria-label={{$:/language/ControlPanel/Plugins/Enable/Caption}}>
|
||||
<<lingo Enable/Caption>>
|
||||
</$button>
|
||||
</$reveal>
|
||||
</div>
|
||||
</$list>
|
||||
<$set name="tabsList" filter="[<currentTiddler>list[]] contents">
|
||||
<$macrocall $name="tabs" state=<<tabs-state-macro>> tabsList=<<tabsList>> default={{{ [enlist<tabsList>] }}} template="$:/core/ui/PluginInfo"/>
|
||||
</$set>
|
||||
</div>
|
||||
</div>
|
||||
</$reveal>
|
||||
<$reveal type="nomatch" state=<<plugin-disable-title>> text="yes">
|
||||
<$link to={{!!title}} class="tc-plugin-info">
|
||||
<<plugin-table-body type:"$type$" default-popup-state:"""$default-popup-state$""">>
|
||||
</$link>
|
||||
</$reveal>
|
||||
<$reveal type="match" state=<<plugin-disable-title>> text="yes">
|
||||
<$link to={{!!title}} class="tc-plugin-info tc-plugin-info-disabled">
|
||||
<<plugin-table-body type:"$type$" default-popup-state:"""$default-popup-state$""" disabledMessage:"<$macrocall $name='lingo' title='Disabled/Status'/>">>
|
||||
</$link>
|
||||
</$reveal>
|
||||
<$reveal type="match" text="yes" state=<<popup-state>> default="""$default-popup-state$""">
|
||||
<div class="tc-plugin-info-dropdown">
|
||||
<div class="tc-plugin-info-dropdown-body">
|
||||
<$list filter="[all[current]] -[[$:/core]]">
|
||||
<div style="float:right;">
|
||||
<$reveal type="nomatch" state=<<plugin-disable-title>> text="yes">
|
||||
<$button set=<<plugin-disable-title>> setTo="yes" tooltip={{$:/language/ControlPanel/Plugins/Disable/Hint}} aria-label={{$:/language/ControlPanel/Plugins/Disable/Caption}}>
|
||||
<<lingo Disable/Caption>>
|
||||
</$button>
|
||||
</$reveal>
|
||||
<$reveal type="match" state=<<plugin-disable-title>> text="yes">
|
||||
<$button set=<<plugin-disable-title>> setTo="no" tooltip={{$:/language/ControlPanel/Plugins/Enable/Hint}} aria-label={{$:/language/ControlPanel/Plugins/Enable/Caption}}>
|
||||
<<lingo Enable/Caption>>
|
||||
</$button>
|
||||
</$reveal>
|
||||
</div>
|
||||
</$list>
|
||||
<$set name="tabsList" filter="[<currentTiddler>list[]] contents">
|
||||
<$macrocall $name="tabs" state=<<tabs-state-macro>> tabsList=<<tabsList>> default={{{ [enlist<tabsList>] }}} template="$:/core/ui/PluginInfo"/>
|
||||
</$set>
|
||||
</div>
|
||||
</div>
|
||||
</$reveal>
|
||||
</$set>
|
||||
\end
|
||||
|
||||
|
||||
@@ -16,4 +16,4 @@ caption: {{$:/language/ControlPanel/Plugins/Caption}}
|
||||
|
||||
<<lingo Installed/Hint>>
|
||||
|
||||
<$macrocall $name="tabs" tabsList="[all[tiddlers+shadows]tag[$:/tags/ControlPanel/Plugins]!has[draft.of]]" default="$:/core/ui/ControlPanel/Plugins/Installed/Plugins" explicitState="$:/state/tab--86143343"/>
|
||||
<$macrocall $name="tabs" tabsList="[[$:/core/ui/ControlPanel/Plugins/Installed/Plugins]] [[$:/core/ui/ControlPanel/Plugins/Installed/Themes]] [[$:/core/ui/ControlPanel/Plugins/Installed/Languages]]" default="$:/core/ui/ControlPanel/Plugins/Installed/Plugins" explicitState="$:/state/tab--86143343"/>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
title: $:/core/ui/ControlPanel/Plugins/Installed/Languages
|
||||
tags: $:/tags/ControlPanel/Plugins
|
||||
caption: {{$:/language/ControlPanel/Plugins/Languages/Caption}} (<$count filter="[!has[draft.of]plugin-type[language]]"/>)
|
||||
|
||||
<<plugin-table language>>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
title: $:/core/ui/ControlPanel/Plugins/Installed/Plugins
|
||||
tags: $:/tags/ControlPanel/Plugins
|
||||
caption: {{$:/language/ControlPanel/Plugins/Plugins/Caption}} (<$count filter="[!has[draft.of]plugin-type[plugin]]"/>)
|
||||
|
||||
<<plugin-table plugin>>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
title: $:/core/ui/ControlPanel/Plugins/Installed/Themes
|
||||
tags: $:/tags/ControlPanel/Plugins
|
||||
caption: {{$:/language/ControlPanel/Plugins/Themes/Caption}} (<$count filter="[!has[draft.of]plugin-type[theme]]"/>)
|
||||
|
||||
<<plugin-table theme>>
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
title: $:/core/ui/EditorToolbar/StampDropdown/ItemTemplate
|
||||
|
||||
<$linkcatcher actions="""
|
||||
|
||||
<$list filter="[<modifier>!match[ctrl]]" variable="ignore">
|
||||
|
||||
<$list filter="[<currentTiddler>addsuffix[/prefix]!is[tiddler]!is[shadow]removesuffix[/prefix]addsuffix[/suffix]!is[tiddler]!is[shadow]]" variable="ignore">
|
||||
|
||||
<$action-sendmessage
|
||||
$message="tm-edit-text-operation"
|
||||
$param="replace-selection"
|
||||
text={{{ [<currentTiddler>get[text]] }}}
|
||||
/>
|
||||
|
||||
</$list>
|
||||
|
||||
|
||||
<$list filter="[<currentTiddler>addsuffix[/prefix]] [<currentTiddler>addsuffix[/suffix]] +[is[shadow]] :else[is[tiddler]] +[limit[1]]" variable="ignore">
|
||||
|
||||
<$action-sendmessage
|
||||
$message="tm-edit-text-operation"
|
||||
$param="wrap-selection"
|
||||
prefix={{{ [<currentTiddler>addsuffix[/prefix]get[text]] }}}
|
||||
suffix={{{ [<currentTiddler>addsuffix[/suffix]get[text]] }}}
|
||||
/>
|
||||
|
||||
</$list>
|
||||
|
||||
</$list>
|
||||
|
||||
<$list filter="[<modifier>match[ctrl]]" variable="ignore">
|
||||
|
||||
<$action-sendmessage $message="tm-edit-tiddler"/>
|
||||
|
||||
</$list>
|
||||
|
||||
<$action-deletetiddler
|
||||
$tiddler=<<dropdown-state>>
|
||||
/>
|
||||
|
||||
""">
|
||||
|
||||
<$link tooltip={{{ [<currentTiddler>get[description]] }}}>
|
||||
|
||||
<$transclude tiddler=<<currentTiddler>> field="caption" mode="inline">
|
||||
|
||||
<$view tiddler=<<currentTiddler>> field="title" />
|
||||
|
||||
</$transclude>
|
||||
|
||||
</$link>
|
||||
|
||||
</$linkcatcher>
|
||||
@@ -1,6 +1,48 @@
|
||||
title: $:/core/ui/EditorToolbar/stamp-dropdown
|
||||
|
||||
<$macrocall $name="list-tagged-draggable" tag="$:/tags/TextEditor/Snippet" subFilter="!is[draft]" itemTemplate="$:/core/ui/EditorToolbar/StampDropdown/ItemTemplate"/>
|
||||
\define toolbar-button-stamp-inner()
|
||||
<$button tag="a">
|
||||
|
||||
<$list filter="[[$(snippetTitle)$]addsuffix[/prefix]is[missing]removesuffix[/prefix]addsuffix[/suffix]is[missing]]">
|
||||
|
||||
<$action-sendmessage
|
||||
$message="tm-edit-text-operation"
|
||||
$param="replace-selection"
|
||||
text={{$(snippetTitle)$}}
|
||||
/>
|
||||
|
||||
</$list>
|
||||
|
||||
|
||||
<$list filter="[[$(snippetTitle)$]addsuffix[/prefix]is[missing]removesuffix[/prefix]addsuffix[/suffix]!is[missing]] [[$(snippetTitle)$]addsuffix[/prefix]!is[missing]removesuffix[/prefix]addsuffix[/suffix]is[missing]] [[$(snippetTitle)$]addsuffix[/prefix]!is[missing]removesuffix[/prefix]addsuffix[/suffix]!is[missing]]">
|
||||
|
||||
<$action-sendmessage
|
||||
$message="tm-edit-text-operation"
|
||||
$param="wrap-selection"
|
||||
prefix={{{ [[$(snippetTitle)$]addsuffix[/prefix]get[text]] }}}
|
||||
suffix={{{ [[$(snippetTitle)$]addsuffix[/suffix]get[text]] }}}
|
||||
/>
|
||||
|
||||
</$list>
|
||||
|
||||
<$action-deletetiddler
|
||||
$tiddler=<<dropdown-state>>
|
||||
/>
|
||||
|
||||
<$transclude tiddler=<<snippetTitle>> field="caption" mode="inline">
|
||||
|
||||
<$view tiddler=<<snippetTitle>> field="title" />
|
||||
|
||||
</$transclude>
|
||||
|
||||
</$button>
|
||||
\end
|
||||
|
||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/TextEditor/Snippet]!has[draft.of]sort[caption]]" variable="snippetTitle">
|
||||
|
||||
<<toolbar-button-stamp-inner>>
|
||||
|
||||
</$list>
|
||||
|
||||
----
|
||||
|
||||
|
||||
@@ -6,5 +6,4 @@ description: {{$:/language/Buttons/Stamp/Hint}}
|
||||
condition: [<targetTiddler>type[]] [<targetTiddler>get[type]prefix[text/]] [<targetTiddler>get[type]match[application/javascript]] [<targetTiddler>get[type]match[application/json]] [<targetTiddler>get[type]match[application/x-tiddler-dictionary]] [<targetTiddler>get[type]match[image/svg+xml]] +[first[]]
|
||||
shortcuts: ((stamp))
|
||||
dropdown: $:/core/ui/EditorToolbar/stamp-dropdown
|
||||
button-classes: tc-editortoolbar-stamp-button
|
||||
text:
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
title: $:/core/ui/ExportTiddlyWikiCore
|
||||
|
||||
\define jsFileName() tiddlywikicore-$(version)$.js
|
||||
\define noExportMsg()
|
||||
It appears that you have a wiki with an external ~TiddlyWiki core. The export action cannot be performed.
|
||||
<p>You will need to view the page source in your browser. Then go to the very bottom the the source, find the last `<script>`
|
||||
element, and right-click its `src` URI. Save the link as ''$(jsFileName)$''</p>
|
||||
\end
|
||||
|
||||
''For advanced users''
|
||||
|
||||
Export the ~TiddlyWiki core ~JavaScript code for running with external ~JavaScript:
|
||||
|
||||
<$button tooltip="Export the ~TiddlyWiki core code for running with external ~JavaScript" aria-label="export TiddlyWiki core" class="tc-btn-big-green">
|
||||
<$list filter="[[$:/boot/boot.js]is[missing]]" variable="ignore" emptyMessage="""<$action-sendmessage $message="tm-download-file" $param="$:/core/templates/tiddlywiki5.js" filename=<<jsFileName>>/>""" >
|
||||
<$action-setfield $tiddler=<<qualify "$:/temp/alert">> text=<<noExportMsg>> subtitle="Export ~TiddllyWiki Core"/>
|
||||
<$action-sendmessage $message="tm-modal" $param=<<qualify "$:/temp/alert">>/>
|
||||
</$list>
|
||||
{{$:/core/images/download-button}} Download ~TiddlyWiki core
|
||||
</$button>
|
||||
|
||||
[[Further information|https://tiddlywiki.com/#Using%20the%20external%20JavaScript%20template]]
|
||||
@@ -1,22 +0,0 @@
|
||||
title: $:/core/ui/ExportTiddlyWikiCore
|
||||
|
||||
\define jsFileName() tiddlywikicore-$(version)$.js
|
||||
\define noExportMsg()
|
||||
It appears that you have a wiki with an external ~TiddlyWiki core. The export action cannot be performed.
|
||||
<p>You will need to view the page source in your browser. Then go to the very bottom the the source, find the last `<script>`
|
||||
element, and right-click its `src` URI. Save the link as ''$(jsFileName)$''</p>
|
||||
\end
|
||||
|
||||
''For advanced users''
|
||||
|
||||
Export the ~TiddlyWiki core ~JavaScript code for running with external ~JavaScript:
|
||||
|
||||
<$button tooltip="Export the ~TiddlyWiki core code for running with external ~JavaScript" aria-label="export TiddlyWiki core" class="tc-btn-big-green">
|
||||
<$list filter="[[$:/boot/boot.js]is[missing]]" variable="ignore" emptyMessage="""<$action-sendmessage $message="tm-download-file" $param="$:/core/templates/tiddlywiki5.js" filename=<<jsFileName>>/>""" >
|
||||
<$action-setfield $tiddler=<<qualify "$:/temp/alert">> text=<<noExportMsg>> subtitle="Export ~TiddllyWiki Core"/>
|
||||
<$action-sendmessage $message="tm-modal" $param=<<qualify "$:/temp/alert">>/>
|
||||
</$list>
|
||||
{{$:/core/images/download-button}} Download ~TiddlyWiki core
|
||||
</$button>
|
||||
|
||||
[[Further information|https://tiddlywiki.com/#Using%20the%20external%20JavaScript%20template]]
|
||||
@@ -1,15 +1,10 @@
|
||||
title: $:/core/ui/ViewTemplate
|
||||
|
||||
\whitespace trim
|
||||
\define folded-state()
|
||||
$:/state/folded/$(currentTiddler)$
|
||||
\end
|
||||
\define cancel-delete-tiddler-actions(message) <$action-sendmessage $message="tm-$message$-tiddler"/>
|
||||
\import [all[shadows+tiddlers]tag[$:/tags/Macro/View]!has[draft.of]]
|
||||
<$vars storyTiddler=<<currentTiddler>> tiddlerInfoState=<<qualify "$:/state/popup/tiddler-info">>>
|
||||
<div data-tiddler-title=<<currentTiddler>> data-tags={{!!tags}} class={{{ tc-tiddler-frame tc-tiddler-view-frame [<currentTiddler>is[tiddler]then[tc-tiddler-exists]] [<currentTiddler>is[missing]!is[shadow]then[tc-tiddler-missing]] [<currentTiddler>is[shadow]then[tc-tiddler-exists tc-tiddler-shadow]] [<currentTiddler>is[shadow]is[tiddler]then[tc-tiddler-overridden-shadow]] [<currentTiddler>is[system]then[tc-tiddler-system]] [{!!class}] [<currentTiddler>tags[]encodeuricomponent[]addprefix[tc-tagged-]] +[join[ ]] }}}>
|
||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewTemplate]!has[draft.of]]" variable="listItem">
|
||||
<$transclude tiddler=<<listItem>>/>
|
||||
</$list>
|
||||
<$vars storyTiddler=<<currentTiddler>> tiddlerInfoState=<<qualify "$:/state/popup/tiddler-info">>><div data-tiddler-title=<<currentTiddler>> data-tags={{!!tags}} class={{{ tc-tiddler-frame tc-tiddler-view-frame [<currentTiddler>is[tiddler]then[tc-tiddler-exists]] [<currentTiddler>is[missing]!is[shadow]then[tc-tiddler-missing]] [<currentTiddler>is[shadow]then[tc-tiddler-exists tc-tiddler-shadow]] [<currentTiddler>is[shadow]is[tiddler]then[tc-tiddler-overridden-shadow]] [<currentTiddler>is[system]then[tc-tiddler-system]] [{!!class}] [<currentTiddler>tags[]encodeuricomponent[]addprefix[tc-tagged-]] +[join[ ]] }}}><$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewTemplate]!has[draft.of]]" variable="listItem"><$transclude tiddler=<<listItem>>/></$list>
|
||||
</div>
|
||||
</$vars>
|
||||
|
||||
@@ -3,15 +3,8 @@ tags: $:/tags/ViewTemplate
|
||||
|
||||
\define lingo-base() $:/language/Import/
|
||||
|
||||
\define confirmCancel()
|
||||
<$action-confirm $message={{$:/language/Import/Listing/Cancel/Warning}} >
|
||||
<$action-deletetiddler $tiddler=<<currentTiddler>>/>
|
||||
<$action-sendmessage $message="tm-close-tiddler" title=<<currentTiddler>>/>
|
||||
</$action-confirm>
|
||||
\end
|
||||
|
||||
\define buttons()
|
||||
<$button actions=<<confirmCancel>> ><<lingo Listing/Cancel/Caption>></$button>
|
||||
<$button message="tm-delete-tiddler" param=<<currentTiddler>>><<lingo Listing/Cancel/Caption>></$button>
|
||||
<$button message="tm-perform-import" param=<<currentTiddler>>><<lingo Listing/Import/Caption>></$button>
|
||||
<<lingo Listing/Preview>> <$select tiddler="$:/state/importpreviewtype" default="$:/core/ui/ImportPreviews/Text">
|
||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/ImportPreview]!has[draft.of]]">
|
||||
|
||||
@@ -5,10 +5,13 @@ tags: $:/tags/ViewTemplate
|
||||
\define title-styles()
|
||||
fill:$(foregroundColor)$;
|
||||
\end
|
||||
\define config-title()
|
||||
$:/config/ViewToolbarButtons/Visibility/$(listItem)$
|
||||
\end
|
||||
<div class="tc-tiddler-title">
|
||||
<div class="tc-titlebar">
|
||||
<span class="tc-tiddler-controls">
|
||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewToolbar]!has[draft.of]] :filter[lookup[$:/config/ViewToolbarButtons/Visibility/]!match[hide]]" storyview="pop" variable="listItem"><$set name="tv-config-toolbar-class" filter="[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]"><$transclude tiddler=<<listItem>>/></$set></$list>
|
||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewToolbar]!has[draft.of]]" variable="listItem"><$reveal type="nomatch" state=<<config-title>> text="hide"><$set name="tv-config-toolbar-class" filter="[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]"><$transclude tiddler=<<listItem>>/></$set></$reveal></$list>
|
||||
</span>
|
||||
<$set name="tv-wikilinks" value={{$:/config/Tiddlers/TitleLinks}}>
|
||||
<$link>
|
||||
@@ -40,4 +43,4 @@ fill:$(foregroundColor)$;
|
||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/TiddlerInfoSegment]!has[draft.of]] [[$:/core/ui/TiddlerInfo]]" variable="listItem"><$transclude tiddler=<<listItem>> mode="block"/></$list>
|
||||
|
||||
</$reveal>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,2 +1,3 @@
|
||||
title: $:/config/EditTabIndex
|
||||
text: 1
|
||||
|
||||
1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
title: $:/config/OfficialPluginLibrary
|
||||
tags: $:/tags/PluginLibrary
|
||||
url: https://tiddlywiki.com/library/v5.2.0/index.html
|
||||
url: https://tiddlywiki.com/library/v5.1.24/index.html
|
||||
caption: {{$:/language/OfficialPluginLibrary}}
|
||||
|
||||
{{$:/language/OfficialPluginLibrary/Hint}}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
title: $:/config/shortcuts-mac/
|
||||
|
||||
bold: meta-B
|
||||
input-tab-left: ctrl-Left
|
||||
input-tab-right: ctrl-Right
|
||||
italic: meta-I
|
||||
underline: meta-U
|
||||
new-image: ctrl-I
|
||||
|
||||
@@ -18,8 +18,8 @@ input-accept: Enter
|
||||
input-accept-variant: ctrl-Enter
|
||||
input-cancel: Escape
|
||||
input-down: Down
|
||||
input-tab-left: alt-ctrl-Left
|
||||
input-tab-right: alt-ctrl-Right
|
||||
input-tab-left: alt-Left
|
||||
input-tab-right: alt-Right
|
||||
input-up: Up
|
||||
layout-switcher: ctrl-shift-L
|
||||
link: ctrl-L
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
title: $:/tags/ControlPanel/Plugins
|
||||
list: $:/core/ui/ControlPanel/Plugins/Installed/Plugins $:/core/ui/ControlPanel/Plugins/Installed/Themes $:/core/ui/ControlPanel/Plugins/Installed/Languages
|
||||
list: [[$:/core/ui/ControlPanel/Plugins/Installed]] [[$:/core/ui/ControlPanel/Plugins/Add]]
|
||||
|
||||
@@ -8,13 +8,11 @@ Welcome to the developer documentation for TiddlyWiki (https://tiddlywiki.com/).
|
||||
|
||||
* An assignment by Christian Jurke and Christian Heigele, two students working on their Master's degree in Information Technology at the Gießen University of Applied Sciences (Technische Hochschule Mittelhessen). Their work can be seen in the [[Introduction]] and the tiddlers that link from it.
|
||||
* New developer documentation
|
||||
** [[Data Storage in Single File TiddlyWiki]]
|
||||
** [[Continuous Deployment]]
|
||||
** [[GitHub Branches]]
|
||||
** HookMechanism
|
||||
** [[Using ES2016 for Writing Plugins]]
|
||||
** [[Adding Babel Polyfill to TiddlyWiki]]
|
||||
** [[TiddlyWiki Drag and Drop Interoperability]]
|
||||
* The original developer documentation from https://tiddlywiki.com:
|
||||
** [[TiddlyWiki for Developers]]
|
||||
** [[TiddlyWiki Coding Style Guidelines]]
|
||||
@@ -31,4 +29,4 @@ Welcome to the developer documentation for TiddlyWiki (https://tiddlywiki.com/).
|
||||
** [[Scripts for building tiddlywiki.com]]
|
||||
** SyncAdaptorModules
|
||||
** WidgetModules
|
||||
** WikiRuleModules
|
||||
** WikiRuleModules
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user