mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2026-02-15 22:49:51 +00:00
Compare commits
4 Commits
master
...
element-ma
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f29de0cb44 | ||
|
|
a14cd291ac | ||
|
|
b27d102d55 | ||
|
|
9aaab87b87 |
@@ -120,6 +120,7 @@ node $TW5_BUILD_TIDDLYWIKI \
|
|||||||
|| exit 1
|
|| exit 1
|
||||||
|
|
||||||
# /empty.html Empty
|
# /empty.html Empty
|
||||||
|
# /empty.hta For Internet Explorer
|
||||||
# /empty-external-core.html External core empty
|
# /empty-external-core.html External core empty
|
||||||
# /tiddlywikicore-<version>.js Core plugin javascript
|
# /tiddlywikicore-<version>.js Core plugin javascript
|
||||||
node $TW5_BUILD_TIDDLYWIKI \
|
node $TW5_BUILD_TIDDLYWIKI \
|
||||||
|
|||||||
23
boot/boot.js
23
boot/boot.js
@@ -316,25 +316,8 @@ $tw.utils.htmlDecode = function(s) {
|
|||||||
return s.toString().replace(/</mg,"<").replace(/ /mg,"\xA0").replace(/>/mg,">").replace(/"/mg,"\"").replace(/&/mg,"&");
|
return s.toString().replace(/</mg,"<").replace(/ /mg,"\xA0").replace(/>/mg,">").replace(/"/mg,"\"").replace(/&/mg,"&");
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/** @deprecated Use window.location.hash instead. */
|
||||||
Get the browser location.hash. We don't use location.hash because of the way that Firefox auto-urldecodes it (see http://stackoverflow.com/questions/1703552/encoding-of-window-location-hash)
|
$tw.utils.getLocationHash = () => window.location.hash;
|
||||||
*/
|
|
||||||
$tw.utils.getLocationHash = function() {
|
|
||||||
const href = window.location.href,
|
|
||||||
idx = href.indexOf("#");
|
|
||||||
|
|
||||||
if(idx === -1) {
|
|
||||||
return "#";
|
|
||||||
}
|
|
||||||
|
|
||||||
const afterHash = href.substring(idx + 1);
|
|
||||||
if(afterHash.startsWith("#") || afterHash.startsWith("%23")) {
|
|
||||||
// Special case: ignore location hash if it itself starts with a #
|
|
||||||
return "#";
|
|
||||||
}
|
|
||||||
return href.substring(idx);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/** @deprecated Pad a string to a given length with "0"s. Length defaults to 2 */
|
/** @deprecated Pad a string to a given length with "0"s. Length defaults to 2 */
|
||||||
$tw.utils.pad = function(value,length = 2) {
|
$tw.utils.pad = function(value,length = 2) {
|
||||||
@@ -613,7 +596,7 @@ $tw.utils.evalGlobal = function(code,context,filename,sandbox,allowGlobals) {
|
|||||||
// Compile the code into a function
|
// Compile the code into a function
|
||||||
var fn;
|
var fn;
|
||||||
if($tw.browser) {
|
if($tw.browser) {
|
||||||
fn = Function("return " + code + "\n\n//# sourceURL=" + filename)(); // See https://github.com/TiddlyWiki/TiddlyWiki5/issues/6839
|
fn = window["eval"](code + "\n\n//# sourceURL=" + filename); // eslint-disable-line no-eval -- See https://github.com/TiddlyWiki/TiddlyWiki5/issues/6839
|
||||||
} else {
|
} else {
|
||||||
if(sandbox){
|
if(sandbox){
|
||||||
fn = vm.runInContext(code,sandbox,filename)
|
fn = vm.runInContext(code,sandbox,filename)
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ exports.handler = function(request,response,state) {
|
|||||||
}
|
}
|
||||||
var text = state.wiki.renderTiddler(renderType,renderTemplate,{parseAsInline: true, variables: {currentTiddler: title}});
|
var text = state.wiki.renderTiddler(renderType,renderTemplate,{parseAsInline: true, variables: {currentTiddler: title}});
|
||||||
|
|
||||||
var headers = {"Content-Type": renderType};
|
// Naughty not to set a content-type, but it's the easiest way to ensure the browser will see HTML pages as HTML, and accept plain text tiddlers as CSS or JS
|
||||||
state.sendResponse(200,headers,text,"utf8");
|
state.sendResponse(200,{},text,"utf8");
|
||||||
} else {
|
} else {
|
||||||
response.writeHead(404);
|
response.writeHead(404);
|
||||||
response.end();
|
response.end();
|
||||||
|
|||||||
@@ -42,8 +42,6 @@ function Server(options) {
|
|||||||
}
|
}
|
||||||
// Setup the default required plugins
|
// Setup the default required plugins
|
||||||
this.requiredPlugins = this.get("required-plugins").split(',');
|
this.requiredPlugins = this.get("required-plugins").split(',');
|
||||||
// Initialise CORS
|
|
||||||
this.corsEnable = this.get("cors-enable") === "yes";
|
|
||||||
// Initialise CSRF
|
// Initialise CSRF
|
||||||
this.csrfDisable = this.get("csrf-disable") === "yes";
|
this.csrfDisable = this.get("csrf-disable") === "yes";
|
||||||
// Initialize Gzip compression
|
// Initialize Gzip compression
|
||||||
@@ -263,13 +261,6 @@ Server.prototype.requestHandler = function(request,response,options) {
|
|||||||
state.urlInfo = url.parse(request.url);
|
state.urlInfo = url.parse(request.url);
|
||||||
state.queryParameters = querystring.parse(state.urlInfo.query);
|
state.queryParameters = querystring.parse(state.urlInfo.query);
|
||||||
state.pathPrefix = options.pathPrefix || this.get("path-prefix") || "";
|
state.pathPrefix = options.pathPrefix || this.get("path-prefix") || "";
|
||||||
// Enable CORS
|
|
||||||
if(this.corsEnable) {
|
|
||||||
response.setHeader("Access-Control-Allow-Origin", "*");
|
|
||||||
response.setHeader("Access-Control-Allow-Headers", "*");
|
|
||||||
response.setHeader("Access-Control-Allow-Methods", "*");
|
|
||||||
response.setHeader("Access-Control-Expose-Headers", "*");
|
|
||||||
}
|
|
||||||
state.sendResponse = sendResponse.bind(self,request,response);
|
state.sendResponse = sendResponse.bind(self,request,response);
|
||||||
// Get the principals authorized to access this resource
|
// Get the principals authorized to access this resource
|
||||||
state.authorizationType = options.authorizationType || this.methodMappings[request.method] || "readers";
|
state.authorizationType = options.authorizationType || this.methodMappings[request.method] || "readers";
|
||||||
@@ -294,12 +285,6 @@ Server.prototype.requestHandler = function(request,response,options) {
|
|||||||
response.end();
|
response.end();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Reply to OPTIONS
|
|
||||||
if(this.corsEnable && request.method === "OPTIONS") {
|
|
||||||
response.writeHead(204);
|
|
||||||
response.end();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Find the route that matches this path
|
// Find the route that matches this path
|
||||||
var route = self.findMatchingRoute(request,state);
|
var route = self.findMatchingRoute(request,state);
|
||||||
// Optionally output debug info
|
// Optionally output debug info
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ Appearance/Caption: Appearance
|
|||||||
Appearance/Hint: Ways to customise the appearance of your TiddlyWiki.
|
Appearance/Hint: Ways to customise the appearance of your TiddlyWiki.
|
||||||
Basics/AnimDuration/Prompt: Animation duration
|
Basics/AnimDuration/Prompt: Animation duration
|
||||||
Basics/AutoFocus/Prompt: Default focus field for new tiddlers
|
Basics/AutoFocus/Prompt: Default focus field for new tiddlers
|
||||||
Basics/AutoFocusEdit/Prompt: Default focus field for existing tiddlers
|
|
||||||
Basics/Caption: Basics
|
Basics/Caption: Basics
|
||||||
Basics/DefaultTiddlers/BottomHint: Use [[double square brackets]] for titles with spaces. Or you can choose to {{retain story ordering||$:/snippets/retain-story-ordering-button}}
|
Basics/DefaultTiddlers/BottomHint: Use [[double square brackets]] for titles with spaces. Or you can choose to {{retain story ordering||$:/snippets/retain-story-ordering-button}}
|
||||||
Basics/DefaultTiddlers/Prompt: Default tiddlers
|
Basics/DefaultTiddlers/Prompt: Default tiddlers
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
title: $:/language/Draft/
|
|
||||||
|
|
||||||
Attribution: Draft of '<<draft-title>>' by {{$:/status/UserName}}
|
|
||||||
Title: Draft of '<<draft-title>>'
|
|
||||||
@@ -9,11 +9,6 @@ Advanced/ShadowInfo/NotShadow/Hint: The tiddler <$link to=<<infoTiddler>>><$text
|
|||||||
Advanced/ShadowInfo/Shadow/Hint: The tiddler <$link to=<<infoTiddler>>><$text text=<<infoTiddler>>/></$link> is a shadow tiddler
|
Advanced/ShadowInfo/Shadow/Hint: The tiddler <$link to=<<infoTiddler>>><$text text=<<infoTiddler>>/></$link> is a shadow tiddler
|
||||||
Advanced/ShadowInfo/Shadow/Source: It is defined in the plugin <$link to=<<pluginTiddler>>><$text text=<<pluginTiddler>>/></$link>
|
Advanced/ShadowInfo/Shadow/Source: It is defined in the plugin <$link to=<<pluginTiddler>>><$text text=<<pluginTiddler>>/></$link>
|
||||||
Advanced/ShadowInfo/OverriddenShadow/Hint: It is overridden by an ordinary tiddler
|
Advanced/ShadowInfo/OverriddenShadow/Hint: It is overridden by an ordinary tiddler
|
||||||
Advanced/CascadeInfo/Heading: Cascade Details
|
|
||||||
Advanced/CascadeInfo/Hint: These are the view template segments (tagged <<tag "$:/tags/ViewTemplate">>) using a cascade filter and their resulting template for the current tiddler.
|
|
||||||
Advanced/CascadeInfo/Detail/View: View
|
|
||||||
Advanced/CascadeInfo/Detail/ActiveCascadeFilter: Active cascade filter
|
|
||||||
Advanced/CascadeInfo/Detail/Template: Template
|
|
||||||
Fields/Caption: Fields
|
Fields/Caption: Fields
|
||||||
List/Caption: List
|
List/Caption: List
|
||||||
List/Empty: This tiddler does not have a list
|
List/Empty: This tiddler does not have a list
|
||||||
|
|||||||
@@ -1,116 +0,0 @@
|
|||||||
/*\
|
|
||||||
title: $:/core/modules/background-actions.js
|
|
||||||
type: application/javascript
|
|
||||||
module-type: global
|
|
||||||
|
|
||||||
Class to dispatch actions when filters change
|
|
||||||
|
|
||||||
\*/
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
class BackgroundActionDispatcher {
|
|
||||||
constructor(filterTracker, wiki) {
|
|
||||||
this.filterTracker = filterTracker;
|
|
||||||
this.wiki = wiki;
|
|
||||||
this.nextTrackedFilterId = 1;
|
|
||||||
this.trackedFilters = new Map(); // Use Map for better key management
|
|
||||||
// Track the filter for the background actions
|
|
||||||
this.filterTracker.track({
|
|
||||||
filterString: "[all[tiddlers+shadows]tag[$:/tags/BackgroundAction]!is[draft]]",
|
|
||||||
fnEnter: title => this.trackFilter(title),
|
|
||||||
fnLeave: (title, enterValue) => this.untrackFilter(enterValue),
|
|
||||||
fnChange: (title, enterValue) => {
|
|
||||||
this.untrackFilter(enterValue);
|
|
||||||
return this.trackFilter(title);
|
|
||||||
},
|
|
||||||
fnProcess: changes => this.process(changes)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
trackFilter(title) {
|
|
||||||
const tiddler = this.wiki.getTiddler(title);
|
|
||||||
const id = this.nextTrackedFilterId++;
|
|
||||||
const tracker = new BackgroundActionTracker({
|
|
||||||
wiki: this.wiki,
|
|
||||||
title,
|
|
||||||
trackFilter: tiddler.fields["track-filter"],
|
|
||||||
actions: tiddler.fields.text
|
|
||||||
});
|
|
||||||
this.trackedFilters.set(id, tracker);
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
untrackFilter(enterValue) {
|
|
||||||
const tracker = this.trackedFilters.get(enterValue);
|
|
||||||
if(tracker) {
|
|
||||||
tracker.destroy();
|
|
||||||
}
|
|
||||||
this.trackedFilters.delete(enterValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
process(changes) {
|
|
||||||
for(const tracker of this.trackedFilters.values()) {
|
|
||||||
tracker.process(changes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Represents an individual tracked filter. Options include:
|
|
||||||
wiki: wiki to use
|
|
||||||
title: title of the tiddler being tracked
|
|
||||||
trackFilter: filter string to track changes
|
|
||||||
actions: actions to be executed when the filter changes
|
|
||||||
*/
|
|
||||||
class BackgroundActionTracker {
|
|
||||||
constructor({wiki, title, trackFilter, actions}) {
|
|
||||||
this.wiki = wiki;
|
|
||||||
this.title = title;
|
|
||||||
this.trackFilter = trackFilter;
|
|
||||||
this.actions = actions;
|
|
||||||
this.filterTracker = new $tw.FilterTracker(this.wiki);
|
|
||||||
this.hasChanged = false;
|
|
||||||
this.trackerID = this.filterTracker.track({
|
|
||||||
filterString: this.trackFilter,
|
|
||||||
fnEnter: () => { this.hasChanged = true; },
|
|
||||||
fnLeave: () => { this.hasChanged = true; },
|
|
||||||
fnProcess: changes => {
|
|
||||||
if(this.hasChanged) {
|
|
||||||
this.hasChanged = false;
|
|
||||||
console.log("Processing background action", this.title);
|
|
||||||
const tiddler = this.wiki.getTiddler(this.title);
|
|
||||||
let doActions = true;
|
|
||||||
if(tiddler && tiddler.fields.platforms) {
|
|
||||||
doActions = false;
|
|
||||||
const platforms = $tw.utils.parseStringArray(tiddler.fields.platforms);
|
|
||||||
if(($tw.browser && platforms.includes("browser")) || ($tw.node && platforms.includes("node"))) {
|
|
||||||
doActions = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(doActions) {
|
|
||||||
this.wiki.invokeActionString(
|
|
||||||
this.actions,
|
|
||||||
null,
|
|
||||||
{
|
|
||||||
currentTiddler: this.title
|
|
||||||
},{
|
|
||||||
parentWidget: $tw.rootWidget
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
process(changes) {
|
|
||||||
this.filterTracker.handleChangeEvent(changes);
|
|
||||||
}
|
|
||||||
|
|
||||||
destroy() {
|
|
||||||
this.filterTracker.untrack(this.trackerID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.BackgroundActionDispatcher = BackgroundActionDispatcher;
|
|
||||||
@@ -48,8 +48,8 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
|
|||||||
this.toolbarNode = this.document.createElement("div");
|
this.toolbarNode = this.document.createElement("div");
|
||||||
this.toolbarNode.className = "tc-editor-toolbar";
|
this.toolbarNode.className = "tc-editor-toolbar";
|
||||||
parent.insertBefore(this.toolbarNode,nextSibling);
|
parent.insertBefore(this.toolbarNode,nextSibling);
|
||||||
this.domNodes.push(this.toolbarNode);
|
|
||||||
this.renderChildren(this.toolbarNode,null);
|
this.renderChildren(this.toolbarNode,null);
|
||||||
|
this.domNodes.push(this.toolbarNode);
|
||||||
}
|
}
|
||||||
// Create our element
|
// Create our element
|
||||||
var editInfo = this.getEditInfo(),
|
var editInfo = this.getEditInfo(),
|
||||||
|
|||||||
@@ -1,106 +0,0 @@
|
|||||||
/*\
|
|
||||||
title: $:/core/modules/filter-tracker.js
|
|
||||||
type: application/javascript
|
|
||||||
module-type: global
|
|
||||||
|
|
||||||
Class to track the results of a filter string
|
|
||||||
|
|
||||||
\*/
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
class FilterTracker {
|
|
||||||
constructor(wiki) {
|
|
||||||
this.wiki = wiki;
|
|
||||||
this.trackers = new Map();
|
|
||||||
this.nextTrackerId = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
handleChangeEvent(changes) {
|
|
||||||
this.processTrackers();
|
|
||||||
this.processChanges(changes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Add a tracker to the filter tracker. Returns null if any of the parameters are invalid, or a tracker id if the tracker was added successfully. Options include:
|
|
||||||
filterString: the filter string to track
|
|
||||||
fnEnter: function to call when a title enters the filter results. Called even if the tiddler does not actually exist. Called as (title), and should return a truthy value that is stored in the tracker as the "enterValue"
|
|
||||||
fnLeave: function to call when a title leaves the filter results. Called as (title,enterValue)
|
|
||||||
fnChange: function to call when a tiddler changes in the filter results. Only called for filter results that identify a tiddler or shadow tiddler. Called as (title,enterValue), and may optionally return a replacement enterValue
|
|
||||||
fnProcess: function to call each time the tracker is processed, after any enter, leave or change functions are called. Called as (changes)
|
|
||||||
*/
|
|
||||||
track(options = {}) {
|
|
||||||
const {
|
|
||||||
filterString,
|
|
||||||
fnEnter,
|
|
||||||
fnLeave,
|
|
||||||
fnChange,
|
|
||||||
fnProcess
|
|
||||||
} = options;
|
|
||||||
const id = this.nextTrackerId++;
|
|
||||||
const tracker = {
|
|
||||||
id,
|
|
||||||
filterString,
|
|
||||||
fnEnter,
|
|
||||||
fnLeave,
|
|
||||||
fnChange,
|
|
||||||
fnProcess,
|
|
||||||
previousResults: [],
|
|
||||||
resultValues: {}
|
|
||||||
};
|
|
||||||
this.trackers.set(id, tracker);
|
|
||||||
// Process the tracker
|
|
||||||
this.processTracker(id);
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
untrack(id) {
|
|
||||||
this.trackers.delete(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
processTrackers() {
|
|
||||||
for(const id of this.trackers.keys()) {
|
|
||||||
this.processTracker(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
processTracker(id) {
|
|
||||||
const tracker = this.trackers.get(id);
|
|
||||||
if(!tracker) return;
|
|
||||||
const results = [];
|
|
||||||
// Evaluate the filter and remove duplicate results
|
|
||||||
$tw.utils.each(this.wiki.filterTiddlers(tracker.filterString), title => {
|
|
||||||
$tw.utils.pushTop(results, title);
|
|
||||||
});
|
|
||||||
// Process the newly entered results
|
|
||||||
results.forEach(title => {
|
|
||||||
if(!tracker.previousResults.includes(title) && !tracker.resultValues[title] && tracker.fnEnter) {
|
|
||||||
tracker.resultValues[title] = tracker.fnEnter(title) || true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// Process the results that have just left
|
|
||||||
tracker.previousResults.forEach(title => {
|
|
||||||
if(!results.includes(title) && tracker.resultValues[title] && tracker.fnLeave) {
|
|
||||||
tracker.fnLeave(title, tracker.resultValues[title]);
|
|
||||||
delete tracker.resultValues[title];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// Update the previous results
|
|
||||||
tracker.previousResults = results;
|
|
||||||
}
|
|
||||||
|
|
||||||
processChanges(changes) {
|
|
||||||
for(const tracker of this.trackers.values()) {
|
|
||||||
Object.keys(changes).forEach(title => {
|
|
||||||
if(title && tracker.previousResults.includes(title) && tracker.fnChange) {
|
|
||||||
tracker.resultValues[title] = tracker.fnChange(title, tracker.resultValues[title]) || tracker.resultValues[title];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if(tracker.fnProcess) {
|
|
||||||
tracker.fnProcess(changes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.FilterTracker = FilterTracker;
|
|
||||||
@@ -88,8 +88,8 @@ function parseFilterOperation(operators,filterString,p) {
|
|||||||
rexMatch = rex.exec(filterString.substring(p));
|
rexMatch = rex.exec(filterString.substring(p));
|
||||||
if(rexMatch) {
|
if(rexMatch) {
|
||||||
operator.regexp = new RegExp(rexMatch[1], rexMatch[2]);
|
operator.regexp = new RegExp(rexMatch[1], rexMatch[2]);
|
||||||
// DEPRECATION WARNING
|
// DEPRECATION WARNING
|
||||||
console.log("WARNING: Filter",operator.operator,"has a deprecated regexp operand",operator.regexp);
|
console.log("WARNING: Filter",operator.operator,"has a deprecated regexp operand",operator.regexp);
|
||||||
nextBracketPos = p + rex.lastIndex - 1;
|
nextBracketPos = p + rex.lastIndex - 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -232,7 +232,12 @@ exports.getFilterRunPrefixes = function() {
|
|||||||
|
|
||||||
exports.filterTiddlers = function(filterString,widget,source) {
|
exports.filterTiddlers = function(filterString,widget,source) {
|
||||||
var fn = this.compileFilter(filterString);
|
var fn = this.compileFilter(filterString);
|
||||||
return fn.call(this,source,widget);
|
try {
|
||||||
|
const fnResult = fn.call(this,source,widget);
|
||||||
|
return fnResult;
|
||||||
|
} catch(e) {
|
||||||
|
return [`${$tw.language.getString("Error/Filter")}: ${e}`];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -314,19 +319,19 @@ exports.compileFilter = function(filterString) {
|
|||||||
|
|
||||||
// Invoke the appropriate filteroperator module
|
// Invoke the appropriate filteroperator module
|
||||||
results = operatorFunction(accumulator,{
|
results = operatorFunction(accumulator,{
|
||||||
operator: operator.operator,
|
operator: operator.operator,
|
||||||
operand: operands.length > 0 ? operands[0] : undefined,
|
operand: operands.length > 0 ? operands[0] : undefined,
|
||||||
operands: operands,
|
operands: operands,
|
||||||
multiValueOperands: multiValueOperands,
|
multiValueOperands: multiValueOperands,
|
||||||
isMultiValueOperand: isMultiValueOperand,
|
isMultiValueOperand: isMultiValueOperand,
|
||||||
prefix: operator.prefix,
|
prefix: operator.prefix,
|
||||||
suffix: operator.suffix,
|
suffix: operator.suffix,
|
||||||
suffixes: operator.suffixes,
|
suffixes: operator.suffixes,
|
||||||
regexp: operator.regexp
|
regexp: operator.regexp
|
||||||
},{
|
},{
|
||||||
wiki: self,
|
wiki: self,
|
||||||
widget: widget
|
widget: widget
|
||||||
});
|
});
|
||||||
if($tw.utils.isArray(results)) {
|
if($tw.utils.isArray(results)) {
|
||||||
accumulator = self.makeTiddlerIterator(results);
|
accumulator = self.makeTiddlerIterator(results);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,67 +0,0 @@
|
|||||||
/*\
|
|
||||||
title: $:/core/modules/info/mediaquerytracker.js
|
|
||||||
type: application/javascript
|
|
||||||
module-type: info
|
|
||||||
|
|
||||||
Initialise $:/info/ tiddlers derived from media queries via
|
|
||||||
|
|
||||||
\*/
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
exports.getInfoTiddlerFields = function(updateInfoTiddlersCallback) {
|
|
||||||
if($tw.browser) {
|
|
||||||
// Functions to start and stop tracking a particular media query tracker tiddler
|
|
||||||
function track(title) {
|
|
||||||
var result = {},
|
|
||||||
tiddler = $tw.wiki.getTiddler(title);
|
|
||||||
if(tiddler) {
|
|
||||||
var mediaQuery = tiddler.fields["media-query"],
|
|
||||||
infoTiddler = tiddler.fields["info-tiddler"],
|
|
||||||
infoTiddlerAlt = tiddler.fields["info-tiddler-alt"];
|
|
||||||
if(mediaQuery && infoTiddler) {
|
|
||||||
// Evaluate and track the media query
|
|
||||||
result.mqList = window.matchMedia(mediaQuery);
|
|
||||||
function getResultTiddlers() {
|
|
||||||
var value = result.mqList.matches ? "yes" : "no",
|
|
||||||
tiddlers = [];
|
|
||||||
tiddlers.push({title: infoTiddler, text: value});
|
|
||||||
if(infoTiddlerAlt) {
|
|
||||||
tiddlers.push({title: infoTiddlerAlt, text: value});
|
|
||||||
}
|
|
||||||
return tiddlers;
|
|
||||||
};
|
|
||||||
updateInfoTiddlersCallback(getResultTiddlers());
|
|
||||||
result.handler = function(event) {
|
|
||||||
updateInfoTiddlersCallback(getResultTiddlers());
|
|
||||||
};
|
|
||||||
result.mqList.addEventListener("change",result.handler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
function untrack(enterValue) {
|
|
||||||
if(enterValue.mqList && enterValue.handler) {
|
|
||||||
enterValue.mqList.removeEventListener("change",enterValue.handler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Track media query tracker tiddlers
|
|
||||||
function fnEnter(title) {
|
|
||||||
return track(title);
|
|
||||||
}
|
|
||||||
function fnLeave(title,enterValue) {
|
|
||||||
untrack(enterValue);
|
|
||||||
}
|
|
||||||
function fnChange(title,enterValue) {
|
|
||||||
untrack(enterValue);
|
|
||||||
return track(title);
|
|
||||||
}
|
|
||||||
$tw.filterTracker.track({
|
|
||||||
filterString: "[all[tiddlers+shadows]tag[$:/tags/MediaQueryTracker]!is[draft]]",
|
|
||||||
fnEnter: fnEnter,
|
|
||||||
fnLeave: fnLeave,
|
|
||||||
fnChange: fnChange
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
};
|
|
||||||
@@ -33,6 +33,13 @@ exports.getInfoTiddlerFields = function(updateInfoTiddlersCallback) {
|
|||||||
// Screen size
|
// Screen size
|
||||||
infoTiddlerFields.push({title: "$:/info/browser/screen/width", text: window.screen.width.toString()});
|
infoTiddlerFields.push({title: "$:/info/browser/screen/width", text: window.screen.width.toString()});
|
||||||
infoTiddlerFields.push({title: "$:/info/browser/screen/height", text: window.screen.height.toString()});
|
infoTiddlerFields.push({title: "$:/info/browser/screen/height", text: window.screen.height.toString()});
|
||||||
|
// Dark mode through event listener on MediaQueryList
|
||||||
|
var mqList = window.matchMedia("(prefers-color-scheme: dark)"),
|
||||||
|
getDarkModeTiddler = function() {return {title: "$:/info/darkmode", text: mqList.matches ? "yes" : "no"};};
|
||||||
|
infoTiddlerFields.push(getDarkModeTiddler());
|
||||||
|
mqList.addListener(function(event) {
|
||||||
|
updateInfoTiddlersCallback([getDarkModeTiddler()]);
|
||||||
|
});
|
||||||
// Language
|
// Language
|
||||||
infoTiddlerFields.push({title: "$:/info/browser/language", text: navigator.language || ""});
|
infoTiddlerFields.push({title: "$:/info/browser/language", text: navigator.language || ""});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,14 +107,13 @@ exports.parseStringLiteral = function(source,pos) {
|
|||||||
type: "string",
|
type: "string",
|
||||||
start: pos
|
start: pos
|
||||||
};
|
};
|
||||||
var reString = /(?:"""([\s\S]*?)"""|"([^"]*)")|(?:'([^']*)')|\[\[((?:[^\]]|\](?!\]))*)\]\]/g;
|
var reString = /(?:"""([\s\S]*?)"""|"([^"]*)")|(?:'([^']*)')/g;
|
||||||
reString.lastIndex = pos;
|
reString.lastIndex = pos;
|
||||||
var match = reString.exec(source);
|
var match = reString.exec(source);
|
||||||
if(match && match.index === pos) {
|
if(match && match.index === pos) {
|
||||||
node.value = match[1] !== undefined ? match[1] :(
|
node.value = match[1] !== undefined ? match[1] :(
|
||||||
match[2] !== undefined ? match[2] : (
|
match[2] !== undefined ? match[2] : match[3]
|
||||||
match[3] !== undefined ? match[3] : match[4]
|
);
|
||||||
));
|
|
||||||
node.end = pos + match[0].length;
|
node.end = pos + match[0].length;
|
||||||
return node;
|
return node;
|
||||||
} else {
|
} else {
|
||||||
@@ -143,14 +142,7 @@ exports.parseParameterDefinition = function(paramString,options) {
|
|||||||
var paramInfo = {name: paramMatch[1]},
|
var paramInfo = {name: paramMatch[1]},
|
||||||
defaultValue = paramMatch[2] || paramMatch[3] || paramMatch[4] || paramMatch[5];
|
defaultValue = paramMatch[2] || paramMatch[3] || paramMatch[4] || paramMatch[5];
|
||||||
if(defaultValue !== undefined) {
|
if(defaultValue !== undefined) {
|
||||||
// Check for an MVV reference ((varname))
|
paramInfo["default"] = defaultValue;
|
||||||
var mvvDefaultMatch = /^\(\(([^)|]+)\)\)$/.exec(defaultValue);
|
|
||||||
if(mvvDefaultMatch) {
|
|
||||||
paramInfo.defaultType = "multivalue-variable";
|
|
||||||
paramInfo.defaultVariable = mvvDefaultMatch[1];
|
|
||||||
} else {
|
|
||||||
paramInfo["default"] = defaultValue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
params.push(paramInfo);
|
params.push(paramInfo);
|
||||||
// Look for the next parameter
|
// Look for the next parameter
|
||||||
@@ -181,7 +173,7 @@ exports.parseMacroParameter = function(source,pos) {
|
|||||||
start: pos
|
start: pos
|
||||||
};
|
};
|
||||||
// Define our regexp
|
// Define our regexp
|
||||||
const reMacroParameter = /(?:([A-Za-z0-9\-_]+)\s*:)?(?:\s*(?:"""([\s\S]*?)"""|"([^"]*)"|'([^']*)'|\[\[((?:[^\]]|\](?!\]))*)\]\]|((?:(?:>(?!>))|[^\s>"'])+)))/y;
|
const reMacroParameter = /(?:([A-Za-z0-9\-_]+)\s*:)?(?:\s*(?:"""([\s\S]*?)"""|"([^"]*)"|'([^']*)'|\[\[([^\]]*)\]\]|((?:(?:>(?!>))|[^\s>"'])+)))/y;
|
||||||
// Skip whitespace
|
// Skip whitespace
|
||||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||||
// Look for the parameter
|
// Look for the parameter
|
||||||
@@ -214,201 +206,28 @@ exports.parseMacroParameter = function(source,pos) {
|
|||||||
Look for a macro invocation. Returns null if not found, or {type: "transclude", attributes:, start:, end:}
|
Look for a macro invocation. Returns null if not found, or {type: "transclude", attributes:, start:, end:}
|
||||||
*/
|
*/
|
||||||
exports.parseMacroInvocationAsTransclusion = function(source,pos) {
|
exports.parseMacroInvocationAsTransclusion = function(source,pos) {
|
||||||
var node = {
|
var node = $tw.utils.parseMacroInvocation(source,pos);
|
||||||
type: "transclude",
|
if(node) {
|
||||||
start: pos,
|
var positionalName = 0,
|
||||||
attributes: {},
|
transclusion = {
|
||||||
orderedAttributes: []
|
type: "transclude",
|
||||||
};
|
start: node.start,
|
||||||
// Define our regexps
|
end: node.end
|
||||||
var reVarName = /([^\s>"'=:]+)/g;
|
};
|
||||||
// Skip whitespace
|
$tw.utils.addAttributeToParseTreeNode(transclusion,"$variable",node.name);
|
||||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
$tw.utils.each(node.params,function(param) {
|
||||||
// Look for a double opening angle bracket
|
var name = param.name;
|
||||||
var token = $tw.utils.parseTokenString(source,pos,"<<");
|
if(name) {
|
||||||
if(!token) {
|
if(name.charAt(0) === "$") {
|
||||||
return null;
|
name = "$" + name;
|
||||||
}
|
|
||||||
pos = token.end;
|
|
||||||
// Get the variable name for the macro
|
|
||||||
token = $tw.utils.parseTokenRegExp(source,pos,reVarName);
|
|
||||||
if(!token) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
$tw.utils.addAttributeToParseTreeNode(node,"$variable",token.match[1]);
|
|
||||||
pos = token.end;
|
|
||||||
// Check that the tag is terminated by a space or >>
|
|
||||||
if(!$tw.utils.parseWhiteSpace(source,pos) && !(source.charAt(pos) === ">" && source.charAt(pos + 1) === ">") ) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// Process attributes
|
|
||||||
pos = $tw.utils.parseMacroParametersAsAttributes(node,source,pos);
|
|
||||||
// Skip whitespace
|
|
||||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
|
||||||
// Look for a double closing angle bracket
|
|
||||||
token = $tw.utils.parseTokenString(source,pos,">>");
|
|
||||||
if(!token) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
node.end = token.end;
|
|
||||||
return node;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Look for an MVV (multi-valued variable) reference as a transclusion, i.e. ((varname)) or ((varname params))
|
|
||||||
Returns null if not found, or a parse tree node of type "transclude" with isMVV: true
|
|
||||||
*/
|
|
||||||
exports.parseMVVReferenceAsTransclusion = function(source,pos) {
|
|
||||||
var node = {
|
|
||||||
type: "transclude",
|
|
||||||
isMVV: true,
|
|
||||||
start: pos,
|
|
||||||
attributes: {},
|
|
||||||
orderedAttributes: []
|
|
||||||
};
|
|
||||||
// Define our regexps
|
|
||||||
var reVarName = /([^\s>"'=:)]+)/g;
|
|
||||||
// Skip whitespace
|
|
||||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
|
||||||
// Look for a double opening parenthesis
|
|
||||||
var token = $tw.utils.parseTokenString(source,pos,"((");
|
|
||||||
if(!token) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
pos = token.end;
|
|
||||||
// Get the variable name
|
|
||||||
token = $tw.utils.parseTokenRegExp(source,pos,reVarName);
|
|
||||||
if(!token) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
$tw.utils.addAttributeToParseTreeNode(node,"$variable",token.match[1]);
|
|
||||||
pos = token.end;
|
|
||||||
// Skip whitespace
|
|
||||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
|
||||||
// Look for a double closing parenthesis
|
|
||||||
token = $tw.utils.parseTokenString(source,pos,"))");
|
|
||||||
if(!token) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
node.end = token.end;
|
|
||||||
return node;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Parse macro parameters as attributes. Returns the position after the last attribute
|
|
||||||
*/
|
|
||||||
exports.parseMacroParametersAsAttributes = function(node,source,pos) {
|
|
||||||
var position = 0,
|
|
||||||
attribute = $tw.utils.parseMacroParameterAsAttribute(source,pos);
|
|
||||||
while(attribute) {
|
|
||||||
if(!attribute.name) {
|
|
||||||
attribute.name = (position++) + "";
|
|
||||||
attribute.isPositional = true;
|
|
||||||
}
|
|
||||||
node.orderedAttributes.push(attribute);
|
|
||||||
node.attributes[attribute.name] = attribute;
|
|
||||||
pos = attribute.end;
|
|
||||||
// Get the next attribute
|
|
||||||
attribute = $tw.utils.parseMacroParameterAsAttribute(source,pos);
|
|
||||||
}
|
|
||||||
node.end = pos;
|
|
||||||
return pos;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Parse a macro parameter as an attribute. Returns null if not found, otherwise returns {name:, type: "filtered|string|indirect|macro", value|filter|textReference:, start:, end:,}, with the name being optional
|
|
||||||
*/
|
|
||||||
exports.parseMacroParameterAsAttribute = function(source,pos) {
|
|
||||||
var node = {
|
|
||||||
start: pos
|
|
||||||
};
|
|
||||||
// Define our regexps
|
|
||||||
var reAttributeName = /([^\/\s>"'`=:]+)/g,
|
|
||||||
reUnquotedAttribute = /((?:(?:>(?!>))|[^\s>"'])+)/g,
|
|
||||||
reFilteredValue = /\{\{\{([\S\s]+?)\}\}\}/g,
|
|
||||||
reIndirectValue = /\{\{([^\}]+)\}\}/g,
|
|
||||||
reSubstitutedValue = /(?:```([\s\S]*?)```|`([^`]|[\S\s]*?)`)/g;
|
|
||||||
// Skip whitespace
|
|
||||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
|
||||||
// Get the attribute name and the separator token
|
|
||||||
var nameToken = $tw.utils.parseTokenRegExp(source,pos,reAttributeName),
|
|
||||||
namePos = nameToken && $tw.utils.skipWhiteSpace(source,nameToken.end),
|
|
||||||
separatorToken = nameToken && $tw.utils.parseTokenRegExp(source,namePos,/=|:/g),
|
|
||||||
isNewStyleSeparator = false; // If there is no separator then we don't allow new style values
|
|
||||||
// If we have a name and a separator then we have a named attribute
|
|
||||||
if(nameToken && separatorToken) {
|
|
||||||
node.name = nameToken.match[1];
|
|
||||||
// key value separator is `=` or `:`
|
|
||||||
node.assignmentOperator = separatorToken.match[0];
|
|
||||||
pos = separatorToken.end;
|
|
||||||
isNewStyleSeparator = (node.assignmentOperator === "=");
|
|
||||||
}
|
|
||||||
// Skip whitespace
|
|
||||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
|
||||||
// Look for a string literal
|
|
||||||
var stringLiteral = $tw.utils.parseStringLiteral(source,pos);
|
|
||||||
if(stringLiteral) {
|
|
||||||
pos = stringLiteral.end;
|
|
||||||
node.type = "string";
|
|
||||||
node.value = stringLiteral.value;
|
|
||||||
// Mark the value as having been quoted in the source
|
|
||||||
node.quoted = true;
|
|
||||||
} else {
|
|
||||||
// Look for a filtered value
|
|
||||||
var filteredValue = $tw.utils.parseTokenRegExp(source,pos,reFilteredValue);
|
|
||||||
if(filteredValue && isNewStyleSeparator) {
|
|
||||||
pos = filteredValue.end;
|
|
||||||
node.type = "filtered";
|
|
||||||
node.filter = filteredValue.match[1];
|
|
||||||
} else {
|
|
||||||
// Look for an indirect value
|
|
||||||
var indirectValue = $tw.utils.parseTokenRegExp(source,pos,reIndirectValue);
|
|
||||||
if(indirectValue && isNewStyleSeparator) {
|
|
||||||
pos = indirectValue.end;
|
|
||||||
node.type = "indirect";
|
|
||||||
node.textReference = indirectValue.match[1];
|
|
||||||
} else {
|
|
||||||
// Look for a macro invocation value
|
|
||||||
var macroInvocation = $tw.utils.parseMacroInvocationAsTransclusion(source,pos);
|
|
||||||
if(macroInvocation && isNewStyleSeparator) {
|
|
||||||
pos = macroInvocation.end;
|
|
||||||
node.type = "macro";
|
|
||||||
node.value = macroInvocation;
|
|
||||||
} else {
|
|
||||||
// Look for an MVV reference value
|
|
||||||
var mvvReference = $tw.utils.parseMVVReferenceAsTransclusion(source,pos);
|
|
||||||
if(mvvReference && isNewStyleSeparator) {
|
|
||||||
pos = mvvReference.end;
|
|
||||||
node.type = "macro";
|
|
||||||
node.value = mvvReference;
|
|
||||||
node.isMVV = true;
|
|
||||||
} else {
|
|
||||||
var substitutedValue = $tw.utils.parseTokenRegExp(source,pos,reSubstitutedValue);
|
|
||||||
if(substitutedValue && isNewStyleSeparator) {
|
|
||||||
pos = substitutedValue.end;
|
|
||||||
node.type = "substituted";
|
|
||||||
node.rawValue = substitutedValue.match[1] || substitutedValue.match[2];
|
|
||||||
} else {
|
|
||||||
// Look for a unquoted value
|
|
||||||
var unquotedValue = $tw.utils.parseTokenRegExp(source,pos,reUnquotedAttribute);
|
|
||||||
if(unquotedValue) {
|
|
||||||
pos = unquotedValue.end;
|
|
||||||
node.type = "string";
|
|
||||||
node.value = unquotedValue.match[1];
|
|
||||||
} else {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
$tw.utils.addAttributeToParseTreeNode(transclusion,{name: name,type: "string", value: param.value, start: param.start, end: param.end});
|
||||||
|
} else {
|
||||||
|
$tw.utils.addAttributeToParseTreeNode(transclusion,{name: (positionalName++) + "",type: "string", value: param.value, start: param.start, end: param.end});
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
return transclusion;
|
||||||
}
|
}
|
||||||
// Bail if we don't have a value
|
|
||||||
if(!node.type) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// Update the end position
|
|
||||||
node.end = pos;
|
|
||||||
return node;
|
return node;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -477,7 +296,7 @@ exports.parseFilterVariable = function(source) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Look for an HTML attribute definition. Returns null if not found, otherwise returns {name:, type: "filtered|string|indirect|macro", value|filter|textReference:, start:, end:,}
|
Look for an HTML attribute definition. Returns null if not found, otherwise returns {type: "attribute", name:, type: "filtered|string|indirect|macro", value|filter|textReference:, start:, end:,}
|
||||||
*/
|
*/
|
||||||
exports.parseAttribute = function(source,pos) {
|
exports.parseAttribute = function(source,pos) {
|
||||||
var node = {
|
var node = {
|
||||||
@@ -527,20 +346,19 @@ exports.parseAttribute = function(source,pos) {
|
|||||||
node.type = "indirect";
|
node.type = "indirect";
|
||||||
node.textReference = indirectValue.match[1];
|
node.textReference = indirectValue.match[1];
|
||||||
} else {
|
} else {
|
||||||
// Look for a macro invocation value
|
// Look for a unquoted value
|
||||||
var macroInvocation = $tw.utils.parseMacroInvocationAsTransclusion(source,pos);
|
var unquotedValue = $tw.utils.parseTokenRegExp(source,pos,reUnquotedAttribute);
|
||||||
if(macroInvocation) {
|
if(unquotedValue) {
|
||||||
pos = macroInvocation.end;
|
pos = unquotedValue.end;
|
||||||
node.type = "macro";
|
node.type = "string";
|
||||||
node.value = macroInvocation;
|
node.value = unquotedValue.match[1];
|
||||||
} else {
|
} else {
|
||||||
// Look for an MVV reference value
|
// Look for a macro invocation value
|
||||||
var mvvReference = $tw.utils.parseMVVReferenceAsTransclusion(source,pos);
|
var macroInvocation = $tw.utils.parseMacroInvocation(source,pos);
|
||||||
if(mvvReference) {
|
if(macroInvocation) {
|
||||||
pos = mvvReference.end;
|
pos = macroInvocation.end;
|
||||||
node.type = "macro";
|
node.type = "macro";
|
||||||
node.value = mvvReference;
|
node.value = macroInvocation;
|
||||||
node.isMVV = true;
|
|
||||||
} else {
|
} else {
|
||||||
var substitutedValue = $tw.utils.parseTokenRegExp(source,pos,reSubstitutedValue);
|
var substitutedValue = $tw.utils.parseTokenRegExp(source,pos,reSubstitutedValue);
|
||||||
if(substitutedValue) {
|
if(substitutedValue) {
|
||||||
@@ -548,16 +366,8 @@ exports.parseAttribute = function(source,pos) {
|
|||||||
node.type = "substituted";
|
node.type = "substituted";
|
||||||
node.rawValue = substitutedValue.match[1] || substitutedValue.match[2];
|
node.rawValue = substitutedValue.match[1] || substitutedValue.match[2];
|
||||||
} else {
|
} else {
|
||||||
// Look for a unquoted value
|
node.type = "string";
|
||||||
var unquotedValue = $tw.utils.parseTokenRegExp(source,pos,reUnquotedAttribute);
|
node.value = "true";
|
||||||
if(unquotedValue) {
|
|
||||||
pos = unquotedValue.end;
|
|
||||||
node.type = "string";
|
|
||||||
node.value = unquotedValue.match[1];
|
|
||||||
} else {
|
|
||||||
node.type = "string";
|
|
||||||
node.value = "true";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -565,7 +375,6 @@ exports.parseAttribute = function(source,pos) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If there is no equals sign or colon, then this is an attribute with no value, defaulting to "true"
|
|
||||||
node.type = "string";
|
node.type = "string";
|
||||||
node.value = "true";
|
node.value = "true";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ Instantiate parse rule
|
|||||||
exports.init = function(parser) {
|
exports.init = function(parser) {
|
||||||
this.parser = parser;
|
this.parser = parser;
|
||||||
// Regexp to match
|
// Regexp to match
|
||||||
this.matchRegExp = /\\(function|procedure|widget)\s+([^(\s]+)\((\s*([^)]*(?:\)\)[^)]*)*))?\)(\s*\r?\n)?/mg;
|
this.matchRegExp = /\\(function|procedure|widget)\s+([^(\s]+)\((\s*([^)]*))?\)(\s*\r?\n)?/mg;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ exports.parse = function() {
|
|||||||
var paramString = this.match[2],
|
var paramString = this.match[2],
|
||||||
params = [];
|
params = [];
|
||||||
if(paramString !== "") {
|
if(paramString !== "") {
|
||||||
var reParam = /\s*([A-Za-z0-9\-_]+)(?:\s*:\s*(?:"""([\s\S]*?)"""|"([^"]*)"|'([^']*)'|\[\[((?:[^\]]|\](?!\]))*)\]\]|([^"'\s]+)))?/mg,
|
var reParam = /\s*([A-Za-z0-9\-_]+)(?:\s*:\s*(?:"""([\s\S]*?)"""|"([^"]*)"|'([^']*)'|\[\[([^\]]*)\]\]|([^"'\s]+)))?/mg,
|
||||||
paramMatch = reParam.exec(paramString);
|
paramMatch = reParam.exec(paramString);
|
||||||
while(paramMatch) {
|
while(paramMatch) {
|
||||||
// Save the parameter details
|
// Save the parameter details
|
||||||
|
|||||||
@@ -1,95 +0,0 @@
|
|||||||
/*\
|
|
||||||
title: $:/core/modules/parsers/wikiparser/rules/mvvdisplayinline.js
|
|
||||||
type: application/javascript
|
|
||||||
module-type: wikirule
|
|
||||||
|
|
||||||
Wiki rule for inline display of multi-valued variables and filter results.
|
|
||||||
|
|
||||||
Variable display: ((varname)) or ((varname||separator))
|
|
||||||
Filter display: (((filter))) or (((filter||separator)))
|
|
||||||
|
|
||||||
The default separator is ", " (comma space).
|
|
||||||
|
|
||||||
\*/
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
exports.name = "mvvdisplayinline";
|
|
||||||
exports.types = {inline: true};
|
|
||||||
|
|
||||||
exports.init = function(parser) {
|
|
||||||
this.parser = parser;
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.findNextMatch = function(startPos) {
|
|
||||||
var source = this.parser.source;
|
|
||||||
var nextStart = startPos;
|
|
||||||
while((nextStart = source.indexOf("((",nextStart)) >= 0) {
|
|
||||||
if(source.charAt(nextStart + 2) === "(") {
|
|
||||||
// Filter mode: (((filter))) or (((filter||sep)))
|
|
||||||
var match = /^\(\(\(([\s\S]+?)\)\)\)/.exec(source.substring(nextStart));
|
|
||||||
if(match) {
|
|
||||||
// Check for separator: split on last || before )))
|
|
||||||
var inner = match[1];
|
|
||||||
var sepIndex = inner.lastIndexOf("||");
|
|
||||||
if(sepIndex >= 0) {
|
|
||||||
this.nextMatch = {
|
|
||||||
type: "filter",
|
|
||||||
filter: inner.substring(0,sepIndex),
|
|
||||||
separator: inner.substring(sepIndex + 2),
|
|
||||||
start: nextStart,
|
|
||||||
end: nextStart + match[0].length
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
this.nextMatch = {
|
|
||||||
type: "filter",
|
|
||||||
filter: inner,
|
|
||||||
separator: ", ",
|
|
||||||
start: nextStart,
|
|
||||||
end: nextStart + match[0].length
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return nextStart;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Variable mode: ((varname)) or ((varname||sep))
|
|
||||||
var match = /^\(\(([^()|]+?)(?:\|\|([^)]*))?\)\)/.exec(source.substring(nextStart));
|
|
||||||
if(match) {
|
|
||||||
this.nextMatch = {
|
|
||||||
type: "variable",
|
|
||||||
varName: match[1],
|
|
||||||
separator: match[2] !== undefined ? match[2] : ", ",
|
|
||||||
start: nextStart,
|
|
||||||
end: nextStart + match[0].length
|
|
||||||
};
|
|
||||||
return nextStart;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nextStart += 2;
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Parse the most recent match
|
|
||||||
*/
|
|
||||||
exports.parse = function() {
|
|
||||||
var match = this.nextMatch;
|
|
||||||
this.nextMatch = null;
|
|
||||||
this.parser.pos = match.end;
|
|
||||||
var filter, sep = match.separator;
|
|
||||||
if(match.type === "variable") {
|
|
||||||
filter = "[(" + match.varName + ")join[" + sep + "]]";
|
|
||||||
} else {
|
|
||||||
filter = match.filter + " +[join[" + sep + "]]";
|
|
||||||
}
|
|
||||||
return [{
|
|
||||||
type: "text",
|
|
||||||
attributes: {
|
|
||||||
text: {name: "text", type: "filtered", filter: filter}
|
|
||||||
},
|
|
||||||
orderedAttributes: [
|
|
||||||
{name: "text", type: "filtered", filter: filter}
|
|
||||||
]
|
|
||||||
}];
|
|
||||||
};
|
|
||||||
@@ -23,6 +23,27 @@ exports.init = function(parser) {
|
|||||||
this.matchRegExp = /\{\{([^\{\}\|]*)(?:\|\|([^\|\{\}]+))?(?:\|([^\{\}]+))?\}\}(?:\r?\n|$)/mg;
|
this.matchRegExp = /\{\{([^\{\}\|]*)(?:\|\|([^\|\{\}]+))?(?:\|([^\{\}]+))?\}\}(?:\r?\n|$)/mg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Reject the match if we don't have a template or text reference
|
||||||
|
*/
|
||||||
|
exports.findNextMatch = function(startPos) {
|
||||||
|
this.matchRegExp.lastIndex = startPos;
|
||||||
|
this.match = this.matchRegExp.exec(this.parser.source);
|
||||||
|
if(this.match) {
|
||||||
|
var template = $tw.utils.trim(this.match[2]),
|
||||||
|
textRef = $tw.utils.trim(this.match[1]);
|
||||||
|
// Bail if we don't have a template or text reference
|
||||||
|
if(!template && !textRef) {
|
||||||
|
return undefined;
|
||||||
|
} else {
|
||||||
|
return this.match.index;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return this.match ? this.match.index : undefined;
|
||||||
|
};
|
||||||
|
|
||||||
exports.parse = function() {
|
exports.parse = function() {
|
||||||
// Move past the match
|
// Move past the match
|
||||||
this.parser.pos = this.matchRegExp.lastIndex;
|
this.parser.pos = this.matchRegExp.lastIndex;
|
||||||
|
|||||||
@@ -23,6 +23,27 @@ exports.init = function(parser) {
|
|||||||
this.matchRegExp = /\{\{([^\{\}\|]*)(?:\|\|([^\|\{\}]+))?(?:\|([^\{\}]+))?\}\}/mg;
|
this.matchRegExp = /\{\{([^\{\}\|]*)(?:\|\|([^\|\{\}]+))?(?:\|([^\{\}]+))?\}\}/mg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Reject the match if we don't have a template or text reference
|
||||||
|
*/
|
||||||
|
exports.findNextMatch = function(startPos) {
|
||||||
|
this.matchRegExp.lastIndex = startPos;
|
||||||
|
this.match = this.matchRegExp.exec(this.parser.source);
|
||||||
|
if(this.match) {
|
||||||
|
var template = $tw.utils.trim(this.match[2]),
|
||||||
|
textRef = $tw.utils.trim(this.match[1]);
|
||||||
|
// Bail if we don't have a template or text reference
|
||||||
|
if(!template && !textRef) {
|
||||||
|
return undefined;
|
||||||
|
} else {
|
||||||
|
return this.match.index;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return this.match ? this.match.index : undefined;
|
||||||
|
};
|
||||||
|
|
||||||
exports.parse = function() {
|
exports.parse = function() {
|
||||||
// Move past the match
|
// Move past the match
|
||||||
this.parser.pos = this.matchRegExp.lastIndex;
|
this.parser.pos = this.matchRegExp.lastIndex;
|
||||||
|
|||||||
@@ -6,7 +6,10 @@ module-type: saver
|
|||||||
Handles saving changes via window.postMessage() to the window.parent
|
Handles saving changes via window.postMessage() to the window.parent
|
||||||
|
|
||||||
\*/
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -60,3 +63,4 @@ exports.create = function(wiki) {
|
|||||||
return new PostMessageSaver(wiki);
|
return new PostMessageSaver(wiki);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
})();
|
||||||
|
|||||||
@@ -13,11 +13,6 @@ Load core modules
|
|||||||
exports.name = "load-modules";
|
exports.name = "load-modules";
|
||||||
exports.synchronous = true;
|
exports.synchronous = true;
|
||||||
|
|
||||||
// Set to `true` to enable performance instrumentation
|
|
||||||
var PERFORMANCE_INSTRUMENTATION_CONFIG_TITLE = "$:/config/Performance/Instrumentation";
|
|
||||||
|
|
||||||
var widget = require("$:/core/modules/widgets/widget.js");
|
|
||||||
|
|
||||||
exports.startup = function() {
|
exports.startup = function() {
|
||||||
// Load modules
|
// Load modules
|
||||||
$tw.modules.applyMethods("utils",$tw.utils);
|
$tw.modules.applyMethods("utils",$tw.utils);
|
||||||
@@ -36,27 +31,6 @@ exports.startup = function() {
|
|||||||
$tw.modules.applyMethods("tiddlerdeserializer",$tw.Wiki.tiddlerDeserializerModules);
|
$tw.modules.applyMethods("tiddlerdeserializer",$tw.Wiki.tiddlerDeserializerModules);
|
||||||
$tw.macros = $tw.modules.getModulesByTypeAsHashmap("macro");
|
$tw.macros = $tw.modules.getModulesByTypeAsHashmap("macro");
|
||||||
$tw.wiki.initParsers();
|
$tw.wiki.initParsers();
|
||||||
// --------------------------
|
|
||||||
// The rest of the startup process here is not strictly to do with loading modules, but are needed before other startup
|
|
||||||
// modules are executed. It is easier to put them here than to introduce a new startup module
|
|
||||||
// --------------------------
|
|
||||||
// Create a root widget for attaching event handlers. By using it as the parentWidget for another widget tree, one can reuse the event handlers
|
|
||||||
$tw.rootWidget = new widget.widget({
|
|
||||||
type: "widget",
|
|
||||||
children: []
|
|
||||||
},{
|
|
||||||
wiki: $tw.wiki,
|
|
||||||
document: $tw.browser ? document : $tw.fakeDocument
|
|
||||||
});
|
|
||||||
// Set up the performance framework
|
|
||||||
$tw.perf = new $tw.Performance($tw.wiki.getTiddlerText(PERFORMANCE_INSTRUMENTATION_CONFIG_TITLE,"no") === "yes");
|
|
||||||
// Kick off the filter tracker
|
|
||||||
$tw.filterTracker = new $tw.FilterTracker($tw.wiki);
|
|
||||||
$tw.wiki.addEventListener("change",function(changes) {
|
|
||||||
$tw.filterTracker.handleChangeEvent(changes);
|
|
||||||
});
|
|
||||||
// Kick off the background action dispatcher
|
|
||||||
$tw.backgroundActionDispatcher = new $tw.BackgroundActionDispatcher($tw.filterTracker,$tw.wiki);
|
|
||||||
if($tw.node) {
|
if($tw.node) {
|
||||||
$tw.Commander.initCommands();
|
$tw.Commander.initCommands();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,11 @@ exports.name = "startup";
|
|||||||
exports.after = ["load-modules"];
|
exports.after = ["load-modules"];
|
||||||
exports.synchronous = true;
|
exports.synchronous = true;
|
||||||
|
|
||||||
|
// Set to `true` to enable performance instrumentation
|
||||||
|
var PERFORMANCE_INSTRUMENTATION_CONFIG_TITLE = "$:/config/Performance/Instrumentation";
|
||||||
|
|
||||||
|
var widget = require("$:/core/modules/widgets/widget.js");
|
||||||
|
|
||||||
exports.startup = function() {
|
exports.startup = function() {
|
||||||
// Minimal browser detection
|
// Minimal browser detection
|
||||||
if($tw.browser) {
|
if($tw.browser) {
|
||||||
@@ -49,6 +54,16 @@ exports.startup = function() {
|
|||||||
}
|
}
|
||||||
// Initialise version
|
// Initialise version
|
||||||
$tw.version = $tw.utils.extractVersionInfo();
|
$tw.version = $tw.utils.extractVersionInfo();
|
||||||
|
// Set up the performance framework
|
||||||
|
$tw.perf = new $tw.Performance($tw.wiki.getTiddlerText(PERFORMANCE_INSTRUMENTATION_CONFIG_TITLE,"no") === "yes");
|
||||||
|
// Create a root widget for attaching event handlers. By using it as the parentWidget for another widget tree, one can reuse the event handlers
|
||||||
|
$tw.rootWidget = new widget.widget({
|
||||||
|
type: "widget",
|
||||||
|
children: []
|
||||||
|
},{
|
||||||
|
wiki: $tw.wiki,
|
||||||
|
document: $tw.browser ? document : $tw.fakeDocument
|
||||||
|
});
|
||||||
// Kick off the language manager and switcher
|
// Kick off the language manager and switcher
|
||||||
$tw.language = new $tw.Language();
|
$tw.language = new $tw.Language();
|
||||||
$tw.languageSwitcher = new $tw.PluginSwitcher({
|
$tw.languageSwitcher = new $tw.PluginSwitcher({
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ module-type: utils
|
|||||||
Custom errors for TiddlyWiki.
|
Custom errors for TiddlyWiki.
|
||||||
|
|
||||||
\*/
|
\*/
|
||||||
|
|
||||||
function TranscludeRecursionError() {
|
function TranscludeRecursionError() {
|
||||||
Error.apply(this,arguments);
|
Error.apply(this,arguments);
|
||||||
this.signatures = Object.create(null);
|
this.signatures = Object.create(null);
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ Object.defineProperty(TW_Node.prototype, 'TEXT_NODE', {
|
|||||||
var TW_TextNode = function(text) {
|
var TW_TextNode = function(text) {
|
||||||
bumpSequenceNumber(this);
|
bumpSequenceNumber(this);
|
||||||
this.textContent = text + "";
|
this.textContent = text + "";
|
||||||
this.children = [];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.setPrototypeOf(TW_TextNode.prototype,TW_Node.prototype);
|
Object.setPrototypeOf(TW_TextNode.prototype,TW_Node.prototype);
|
||||||
|
|||||||
@@ -8,7 +8,10 @@ Messaging utilities for use with window.postMessage() etc.
|
|||||||
This module intentionally has no dependencies so that it can be included in non-TiddlyWiki projects
|
This module intentionally has no dependencies so that it can be included in non-TiddlyWiki projects
|
||||||
|
|
||||||
\*/
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var RESPONSE_TIMEOUT = 2 * 1000;
|
var RESPONSE_TIMEOUT = 2 * 1000;
|
||||||
@@ -119,3 +122,5 @@ BrowserMessagingPublisher.prototype.close = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
exports.BrowserMessagingPublisher = BrowserMessagingPublisher;
|
exports.BrowserMessagingPublisher = BrowserMessagingPublisher;
|
||||||
|
|
||||||
|
})();
|
||||||
|
|||||||
@@ -242,53 +242,6 @@ exports.slowInSlowOut = function(t) {
|
|||||||
return (1 - ((Math.cos(t * Math.PI) + 1) / 2));
|
return (1 - ((Math.cos(t * Math.PI) + 1) / 2));
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.copyObjectPropertiesSafe = function(object) {
|
|
||||||
const seen = new Set(),
|
|
||||||
isDOMElement = value => value instanceof Node || value instanceof Window;
|
|
||||||
|
|
||||||
function safeCopy(obj) {
|
|
||||||
// skip circular references
|
|
||||||
if(seen.has(obj)) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
// primitives and null are safe
|
|
||||||
if(typeof obj !== "object" || obj === null) {
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
// skip DOM elements
|
|
||||||
if(isDOMElement(obj)) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
// copy arrays, preserving positions
|
|
||||||
if(Array.isArray(obj)) {
|
|
||||||
return obj.map(item => {
|
|
||||||
const value = safeCopy(item);
|
|
||||||
return value === undefined ? null : value;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
seen.add(obj);
|
|
||||||
const copy = {};
|
|
||||||
let key,
|
|
||||||
value;
|
|
||||||
for(key in obj) {
|
|
||||||
try {
|
|
||||||
value = safeCopy(obj[key]);
|
|
||||||
if(value !== undefined) {
|
|
||||||
copy[key] = value;
|
|
||||||
}
|
|
||||||
} catch(e) {
|
|
||||||
// silently skip unserializable properties
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = safeCopy(object);
|
|
||||||
seen.clear();
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.formatTitleString = function(template,options) {
|
exports.formatTitleString = function(template,options) {
|
||||||
var base = options.base || "",
|
var base = options.base || "",
|
||||||
separator = options.separator || "",
|
separator = options.separator || "",
|
||||||
|
|||||||
@@ -80,8 +80,8 @@ BrowseWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
});
|
});
|
||||||
// Insert element
|
// Insert element
|
||||||
parent.insertBefore(domNode,nextSibling);
|
parent.insertBefore(domNode,nextSibling);
|
||||||
this.domNodes.push(domNode);
|
|
||||||
this.renderChildren(domNode,null);
|
this.renderChildren(domNode,null);
|
||||||
|
this.domNodes.push(domNode);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -135,8 +135,8 @@ ButtonWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
}
|
}
|
||||||
// Insert element
|
// Insert element
|
||||||
parent.insertBefore(domNode,nextSibling);
|
parent.insertBefore(domNode,nextSibling);
|
||||||
this.domNodes.push(domNode);
|
|
||||||
this.renderChildren(domNode,null);
|
this.renderChildren(domNode,null);
|
||||||
|
this.domNodes.push(domNode);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -64,8 +64,8 @@ CheckboxWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
]);
|
]);
|
||||||
// Insert the label into the DOM and render any children
|
// Insert the label into the DOM and render any children
|
||||||
parent.insertBefore(this.labelDomNode,nextSibling);
|
parent.insertBefore(this.labelDomNode,nextSibling);
|
||||||
this.domNodes.push(this.labelDomNode);
|
|
||||||
this.renderChildren(this.spanDomNode,null);
|
this.renderChildren(this.spanDomNode,null);
|
||||||
|
this.domNodes.push(this.labelDomNode);
|
||||||
};
|
};
|
||||||
|
|
||||||
CheckboxWidget.prototype.getValue = function() {
|
CheckboxWidget.prototype.getValue = function() {
|
||||||
|
|||||||
@@ -59,8 +59,6 @@ DiffTextWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
var domContainer = this.document.createElement("div"),
|
var domContainer = this.document.createElement("div"),
|
||||||
domDiff = this.createDiffDom(diffs);
|
domDiff = this.createDiffDom(diffs);
|
||||||
parent.insertBefore(domContainer,nextSibling);
|
parent.insertBefore(domContainer,nextSibling);
|
||||||
// Save our container
|
|
||||||
this.domNodes.push(domContainer);
|
|
||||||
// Set variables
|
// Set variables
|
||||||
this.setVariable("diff-count",diffs.reduce(function(acc,diff) {
|
this.setVariable("diff-count",diffs.reduce(function(acc,diff) {
|
||||||
if(diff[0] !== dmp.DIFF_EQUAL) {
|
if(diff[0] !== dmp.DIFF_EQUAL) {
|
||||||
@@ -72,6 +70,8 @@ DiffTextWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
this.renderChildren(domContainer,null);
|
this.renderChildren(domContainer,null);
|
||||||
// Render the diff
|
// Render the diff
|
||||||
domContainer.appendChild(domDiff);
|
domContainer.appendChild(domDiff);
|
||||||
|
// Save our container
|
||||||
|
this.domNodes.push(domContainer);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ DraggableWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
});
|
});
|
||||||
// Insert the node into the DOM and render any children
|
// Insert the node into the DOM and render any children
|
||||||
parent.insertBefore(domNode,nextSibling);
|
parent.insertBefore(domNode,nextSibling);
|
||||||
this.domNodes.push(domNode);
|
|
||||||
this.renderChildren(domNode,null);
|
this.renderChildren(domNode,null);
|
||||||
// Add event handlers
|
// Add event handlers
|
||||||
if(this.dragEnable) {
|
if(this.dragEnable) {
|
||||||
@@ -71,6 +70,7 @@ DraggableWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
selector: self.dragHandleSelector
|
selector: self.dragHandleSelector
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
this.domNodes.push(domNode);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -57,8 +57,8 @@ DroppableWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
}
|
}
|
||||||
// Insert element
|
// Insert element
|
||||||
parent.insertBefore(domNode,nextSibling);
|
parent.insertBefore(domNode,nextSibling);
|
||||||
this.domNodes.push(domNode);
|
|
||||||
this.renderChildren(domNode,null);
|
this.renderChildren(domNode,null);
|
||||||
|
this.domNodes.push(domNode);
|
||||||
// Stack of outstanding enter/leave events
|
// Stack of outstanding enter/leave events
|
||||||
this.currentlyEntered = [];
|
this.currentlyEntered = [];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ Render this widget into the DOM
|
|||||||
*/
|
*/
|
||||||
ElementWidget.prototype.render = function(parent,nextSibling) {
|
ElementWidget.prototype.render = function(parent,nextSibling) {
|
||||||
this.parentDomNode = parent;
|
this.parentDomNode = parent;
|
||||||
this.computeAttributes();
|
|
||||||
// Neuter blacklisted elements
|
// Neuter blacklisted elements
|
||||||
this.tag = this.parseTreeNode.tag;
|
this.tag = this.parseTreeNode.tag;
|
||||||
if($tw.config.htmlUnsafeElements.indexOf(this.tag) !== -1) {
|
if($tw.config.htmlUnsafeElements.indexOf(this.tag) !== -1) {
|
||||||
@@ -42,6 +41,8 @@ ElementWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
headingLevel = Math.min(Math.max(headingLevel + 1 + baseLevel,1),6);
|
headingLevel = Math.min(Math.max(headingLevel + 1 + baseLevel,1),6);
|
||||||
this.tag = "h" + headingLevel;
|
this.tag = "h" + headingLevel;
|
||||||
}
|
}
|
||||||
|
// Compute the attributes, mapping the element tag if needed
|
||||||
|
this.computeAttributes();
|
||||||
// Select the namespace for the tag
|
// Select the namespace for the tag
|
||||||
var XHTML_NAMESPACE = "http://www.w3.org/1999/xhtml",
|
var XHTML_NAMESPACE = "http://www.w3.org/1999/xhtml",
|
||||||
tagNamespaces = {
|
tagNamespaces = {
|
||||||
@@ -77,8 +78,8 @@ ElementWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
// Allow hooks to manipulate the DOM node. Eg: Add debug info
|
// Allow hooks to manipulate the DOM node. Eg: Add debug info
|
||||||
$tw.hooks.invokeHook("th-dom-rendering-element", domNode, this);
|
$tw.hooks.invokeHook("th-dom-rendering-element", domNode, this);
|
||||||
parent.insertBefore(domNode,nextSibling);
|
parent.insertBefore(domNode,nextSibling);
|
||||||
this.domNodes.push(domNode);
|
|
||||||
this.renderChildren(domNode,null);
|
this.renderChildren(domNode,null);
|
||||||
|
this.domNodes.push(domNode);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -99,4 +100,25 @@ ElementWidget.prototype.refresh = function(changedTiddlers) {
|
|||||||
return this.refreshChildren(changedTiddlers) || hasChangedAttributes;
|
return this.refreshChildren(changedTiddlers) || hasChangedAttributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Override the base computeAttributes method
|
||||||
|
*/
|
||||||
|
ElementWidget.prototype.computeAttributes = function() {
|
||||||
|
// Call the base class to compute the initial values of the attributes
|
||||||
|
var changedAttributes = Widget.prototype.computeAttributes.call(this);
|
||||||
|
// Check for element mapping
|
||||||
|
var mappedTag = this.getVariable("tv-map-" + this.tag),
|
||||||
|
mappedClass = this.getVariable("tv-map-" + this.tag + "-class");
|
||||||
|
if(mappedTag) {
|
||||||
|
this.tag = mappedTag.trim();
|
||||||
|
// Add an attribute to indicate the original tag
|
||||||
|
this.attributes["data-element-mapping-from"] = this.parseTreeNode.tag;
|
||||||
|
// Check for a mapped class
|
||||||
|
if(mappedClass) {
|
||||||
|
this.attributes["class"] = mappedClass.trim() + (this.attributes["class"] ? " " + this.attributes["class"] : "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return changedAttributes;
|
||||||
|
};
|
||||||
|
|
||||||
exports.element = ElementWidget;
|
exports.element = ElementWidget;
|
||||||
|
|||||||
@@ -39,12 +39,75 @@ EventWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
this.domNode = domNode;
|
this.domNode = domNode;
|
||||||
// Assign classes
|
// Assign classes
|
||||||
this.assignDomNodeClasses();
|
this.assignDomNodeClasses();
|
||||||
// Add our event handlers
|
// Add our event handler
|
||||||
this.toggleListeners();
|
$tw.utils.each(this.types,function(type) {
|
||||||
|
domNode.addEventListener(type,function(event) {
|
||||||
|
var selector = self.getAttribute("selector"),
|
||||||
|
matchSelector = self.getAttribute("matchSelector"),
|
||||||
|
actions = self.getAttribute("$"+type),
|
||||||
|
stopPropagation = self.getAttribute("stopPropagation","onaction"),
|
||||||
|
selectedNode = event.target,
|
||||||
|
selectedNodeRect,
|
||||||
|
catcherNodeRect,
|
||||||
|
variables = {};
|
||||||
|
// Firefox can fire dragover and dragenter events on text nodes instead of their parents
|
||||||
|
if(selectedNode.nodeType === 3) {
|
||||||
|
selectedNode = selectedNode.parentNode;
|
||||||
|
}
|
||||||
|
// Check that the selected node matches any matchSelector
|
||||||
|
if(matchSelector && !$tw.utils.domMatchesSelector(selectedNode,matchSelector)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(selector) {
|
||||||
|
// Search ancestors for a node that matches the selector
|
||||||
|
while(!$tw.utils.domMatchesSelector(selectedNode,selector) && selectedNode !== domNode) {
|
||||||
|
selectedNode = selectedNode.parentNode;
|
||||||
|
}
|
||||||
|
// Exit if we didn't find one
|
||||||
|
if(selectedNode === domNode) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Only set up variables if we have actions to invoke
|
||||||
|
if(actions) {
|
||||||
|
variables = $tw.utils.collectDOMVariables(selectedNode,self.domNode,event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Execute our actions with the variables
|
||||||
|
if(actions) {
|
||||||
|
// Add a variable for the modifier key
|
||||||
|
variables.modifier = $tw.keyboardManager.getEventModifierKeyDescriptor(event);
|
||||||
|
// Add a variable for the mouse button
|
||||||
|
if("button" in event) {
|
||||||
|
if(event.button === 0) {
|
||||||
|
variables["event-mousebutton"] = "left";
|
||||||
|
} else if(event.button === 1) {
|
||||||
|
variables["event-mousebutton"] = "middle";
|
||||||
|
} else if(event.button === 2) {
|
||||||
|
variables["event-mousebutton"] = "right";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
variables["event-type"] = event.type.toString();
|
||||||
|
if(typeof event.detail === "object" && !!event.detail) {
|
||||||
|
$tw.utils.each(event.detail,function(detailValue,detail) {
|
||||||
|
variables["event-detail-" + detail] = detailValue.toString();
|
||||||
|
});
|
||||||
|
} else if(!!event.detail) {
|
||||||
|
variables["event-detail"] = event.detail.toString();
|
||||||
|
}
|
||||||
|
self.invokeActionString(actions,self,event,variables);
|
||||||
|
}
|
||||||
|
if((actions && stopPropagation === "onaction") || stopPropagation === "always") {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},false);
|
||||||
|
});
|
||||||
// Insert element
|
// Insert element
|
||||||
parent.insertBefore(domNode,nextSibling);
|
parent.insertBefore(domNode,nextSibling);
|
||||||
this.domNodes.push(domNode);
|
|
||||||
this.renderChildren(domNode,null);
|
this.renderChildren(domNode,null);
|
||||||
|
this.domNodes.push(domNode);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -59,232 +122,11 @@ EventWidget.prototype.execute = function() {
|
|||||||
self.types.push(key.slice(1));
|
self.types.push(key.slice(1));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.pointerCaptureMode = this.getAttribute("pointerCapture","no");
|
|
||||||
this.elementTag = this.getAttribute("tag");
|
this.elementTag = this.getAttribute("tag");
|
||||||
// Make child widgets
|
// Make child widgets
|
||||||
this.makeChildWidgets();
|
this.makeChildWidgets();
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
Cache and pre-create all event listeners, called when first needed
|
|
||||||
*/
|
|
||||||
EventWidget.prototype.cacheEventListeners = function() {
|
|
||||||
if(this._eventListeners) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this._eventListeners = Object.create(null);
|
|
||||||
this._captureActiveListeners = Object.create(null);
|
|
||||||
this._dynamicOnlyEvents = ["pointerup","pointercancel","pointermove"];
|
|
||||||
|
|
||||||
const clearPointerCapture = event => {
|
|
||||||
if(Number.isInteger(this._capturePointerId)) {
|
|
||||||
this.stopPointerCapture(this._capturePointerId);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const attachDynamicOnlyListeners = () => {
|
|
||||||
this._dynamicOnlyEvents.forEach(dt => {
|
|
||||||
const listener = this._eventListeners[dt];
|
|
||||||
if(listener) {
|
|
||||||
this._captureActiveListeners[dt] = listener;
|
|
||||||
this.domNode.addEventListener(dt, listener, false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// Dynamic pointer capture listeners
|
|
||||||
if(this.pointerCaptureMode === "dynamic") {
|
|
||||||
["pointerup","pointercancel"].forEach(type => {
|
|
||||||
this._eventListeners[type] = event => {
|
|
||||||
const selectedNode = this.checkEvent(event, type);
|
|
||||||
if(selectedNode) {
|
|
||||||
clearPointerCapture(event);
|
|
||||||
}
|
|
||||||
// Remove dynamic-only listeners
|
|
||||||
this.cleanupDynamicListeners();
|
|
||||||
return this.handleEvent(event, type, selectedNode);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
if(!this.types.includes("pointerdown")) {
|
|
||||||
this.types.push("pointerdown");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create any listeners not already defined above
|
|
||||||
this.types.forEach(type => {
|
|
||||||
if(!this._eventListeners[type]) {
|
|
||||||
this._eventListeners[type] = event => {
|
|
||||||
const selectedNode = this.checkEvent(event, type);
|
|
||||||
if(!selectedNode) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Handle pointer capture for pointerdown
|
|
||||||
if(type === "pointerdown") {
|
|
||||||
if(this.pointerCaptureMode !== "no") {
|
|
||||||
this.startPointerCapture(event.pointerId, event.target);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this.pointerCaptureMode === "dynamic") {
|
|
||||||
attachDynamicOnlyListeners();
|
|
||||||
}
|
|
||||||
} else if(type === "pointerup" || type === "pointercancel") {
|
|
||||||
clearPointerCapture(event);
|
|
||||||
}
|
|
||||||
return this.handleEvent(event, type, selectedNode);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Check if an event qualifies and return the matching selected node
|
|
||||||
*/
|
|
||||||
EventWidget.prototype.checkEvent = function(event, type) {
|
|
||||||
const domNode = this.domNode;
|
|
||||||
let node = event.target;
|
|
||||||
|
|
||||||
// Use capture target if valid
|
|
||||||
if(this._captureTarget && event.pointerId !== undefined) {
|
|
||||||
if(document.contains(this._captureTarget)) {
|
|
||||||
node = this._captureTarget;
|
|
||||||
} else {
|
|
||||||
// Clear stale reference
|
|
||||||
this.stopPointerCapture(this._capturePointerId);
|
|
||||||
node = event.target;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(node && node.nodeType === 3) {
|
|
||||||
node = node.parentNode;
|
|
||||||
}
|
|
||||||
if(!node || node.nodeType !== 1) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const selector = this.getAttribute("selector"),
|
|
||||||
matchSelector = this.getAttribute("matchSelector");
|
|
||||||
|
|
||||||
if(matchSelector && !node.matches(matchSelector)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if(selector) {
|
|
||||||
const match = node.closest(selector);
|
|
||||||
if(!match || match === domNode || !domNode.contains(match)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return match;
|
|
||||||
}
|
|
||||||
return node;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Handle the event and execute actions
|
|
||||||
*/
|
|
||||||
EventWidget.prototype.handleEvent = function(event, type, selectedNode) {
|
|
||||||
if(!selectedNode) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
let actions = this.getAttribute("$"+type),
|
|
||||||
stopPropagation = this.getAttribute("stopPropagation","onaction");
|
|
||||||
|
|
||||||
if(actions) {
|
|
||||||
let variables = $tw.utils.extend(
|
|
||||||
{},
|
|
||||||
$tw.utils.collectDOMVariables(selectedNode, this.domNode, event),
|
|
||||||
{
|
|
||||||
"eventJSON": JSON.stringify($tw.utils.copyObjectPropertiesSafe(event)),
|
|
||||||
"modifier": $tw.keyboardManager.getEventModifierKeyDescriptor(event),
|
|
||||||
"event-type": event.type.toString()
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if("button" in event) {
|
|
||||||
const mouseButtonMap = {0:"left",1:"middle",2:"right"};
|
|
||||||
variables["event-mousebutton"] = mouseButtonMap[event.button];
|
|
||||||
}
|
|
||||||
this.invokeActionString(actions, this, event, variables);
|
|
||||||
}
|
|
||||||
|
|
||||||
if((actions && stopPropagation === "onaction") || stopPropagation === "always") {
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
EventWidget.prototype.startPointerCapture = function(pointerId, captureTarget) {
|
|
||||||
// Start capture only if none active; pointerId can be 0
|
|
||||||
if(!Number.isInteger(this._capturePointerId) && this.domNode && this.domNode.setPointerCapture) {
|
|
||||||
this.domNode.setPointerCapture(pointerId);
|
|
||||||
this._capturePointerId = pointerId;
|
|
||||||
this._captureTarget = captureTarget;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
EventWidget.prototype.stopPointerCapture = function(pointerId) {
|
|
||||||
if(this.domNode && this.domNode.hasPointerCapture && this.domNode.hasPointerCapture(pointerId)) {
|
|
||||||
this.domNode.releasePointerCapture(pointerId);
|
|
||||||
}
|
|
||||||
this._capturePointerId = undefined;
|
|
||||||
this._captureTarget = undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Attach all relevant listeners
|
|
||||||
*/
|
|
||||||
EventWidget.prototype.attachListeners = function() {
|
|
||||||
this.cacheEventListeners();
|
|
||||||
const domNode = this.domNode;
|
|
||||||
Object.keys(this._eventListeners).forEach(type => {
|
|
||||||
if(this.pointerCaptureMode === "dynamic" && this._dynamicOnlyEvents.includes(type)) {
|
|
||||||
return; //skip dynamic-only events
|
|
||||||
}
|
|
||||||
domNode.addEventListener(type, this._eventListeners[type], false);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Remove dynamic active listeners
|
|
||||||
*/
|
|
||||||
EventWidget.prototype.cleanupDynamicListeners = function() {
|
|
||||||
const domNode = this.domNode;
|
|
||||||
Object.keys(this._captureActiveListeners || {}).forEach(type => {
|
|
||||||
domNode.removeEventListener(type, this._captureActiveListeners[type], false);
|
|
||||||
});
|
|
||||||
this._captureActiveListeners = Object.create(null);
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Remove all listeners
|
|
||||||
*/
|
|
||||||
EventWidget.prototype.removeAllListeners = function() {
|
|
||||||
if(Number.isInteger(this._capturePointerId)) {
|
|
||||||
this.stopPointerCapture(this._capturePointerId);
|
|
||||||
}
|
|
||||||
const domNode = this.domNode;
|
|
||||||
Object.keys(this._eventListeners || {}).forEach(type => {
|
|
||||||
domNode.removeEventListener(type, this._eventListeners[type], false);
|
|
||||||
});
|
|
||||||
this.cleanupDynamicListeners();
|
|
||||||
this._captureTarget = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Enable or disable listeners
|
|
||||||
*/
|
|
||||||
EventWidget.prototype.toggleListeners = function() {
|
|
||||||
let disabled = this.getAttribute("disabled","no") === "yes";
|
|
||||||
if(disabled) {
|
|
||||||
this.removeAllListeners();
|
|
||||||
} else {
|
|
||||||
this.attachListeners();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Assign DOM node classes
|
|
||||||
*/
|
|
||||||
EventWidget.prototype.assignDomNodeClasses = function() {
|
EventWidget.prototype.assignDomNodeClasses = function() {
|
||||||
var classes = this.getAttribute("class","").split(" ");
|
var classes = this.getAttribute("class","").split(" ");
|
||||||
classes.push("tc-eventcatcher");
|
classes.push("tc-eventcatcher");
|
||||||
@@ -292,23 +134,18 @@ EventWidget.prototype.assignDomNodeClasses = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Refresh widget
|
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
|
||||||
*/
|
*/
|
||||||
EventWidget.prototype.refresh = function(changedTiddlers) {
|
EventWidget.prototype.refresh = function(changedTiddlers) {
|
||||||
const changedAttributes = this.computeAttributes(),
|
var changedAttributes = this.computeAttributes(),
|
||||||
changedKeys = Object.keys(changedAttributes),
|
changedAttributesCount = $tw.utils.count(changedAttributes);
|
||||||
canUpdateAttributes = changedKeys.every(key => key === "class" || key === "disabled");
|
if(changedAttributesCount === 1 && changedAttributes["class"]) {
|
||||||
if(canUpdateAttributes) {
|
this.assignDomNodeClasses();
|
||||||
if(changedAttributes["class"]) {
|
} else if(changedAttributesCount > 0) {
|
||||||
this.assignDomNodeClasses();
|
this.refreshSelf();
|
||||||
}
|
return true;
|
||||||
if(changedAttributes["disabled"]) {
|
|
||||||
this.toggleListeners();
|
|
||||||
}
|
|
||||||
return this.refreshChildren(changedTiddlers);
|
|
||||||
}
|
}
|
||||||
this.refreshSelf();
|
return this.refreshChildren(changedTiddlers);
|
||||||
return true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.eventcatcher = EventWidget;
|
exports.eventcatcher = EventWidget;
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ ImageWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
this.execute();
|
this.execute();
|
||||||
// Create element
|
// Create element
|
||||||
// Determine what type of image it is
|
// Determine what type of image it is
|
||||||
var tag = "img", src = "", self = this,
|
var tag = "img", src = "",
|
||||||
tiddler = this.wiki.getTiddler(this.imageSource);
|
tiddler = this.wiki.getTiddler(this.imageSource);
|
||||||
if(!tiddler) {
|
if(!tiddler) {
|
||||||
// The source isn't the title of a tiddler, so we'll assume it's a URL
|
// The source isn't the title of a tiddler, so we'll assume it's a URL
|
||||||
@@ -115,21 +115,11 @@ ImageWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
if(this.lazyLoading && tag === "img") {
|
if(this.lazyLoading && tag === "img") {
|
||||||
domNode.setAttribute("loading",this.lazyLoading);
|
domNode.setAttribute("loading",this.lazyLoading);
|
||||||
}
|
}
|
||||||
this.assignAttributes(domNode,{
|
|
||||||
sourcePrefix: "data-",
|
|
||||||
destPrefix: "data-"
|
|
||||||
});
|
|
||||||
// Add classes when the image loads or fails
|
// Add classes when the image loads or fails
|
||||||
$tw.utils.addClass(domNode,"tc-image-loading");
|
$tw.utils.addClass(domNode,"tc-image-loading");
|
||||||
domNode.addEventListener("load",function(event) {
|
domNode.addEventListener("load",function() {
|
||||||
$tw.utils.removeClass(domNode,"tc-image-loading");
|
$tw.utils.removeClass(domNode,"tc-image-loading");
|
||||||
$tw.utils.addClass(domNode,"tc-image-loaded");
|
$tw.utils.addClass(domNode,"tc-image-loaded");
|
||||||
if(self.loadedActions) {
|
|
||||||
var variables = $tw.utils.collectDOMVariables(domNode,null,event);
|
|
||||||
variables["img-natural-width"] = domNode.naturalWidth.toString();
|
|
||||||
variables["img-natural-height"] = domNode.naturalHeight.toString();
|
|
||||||
self.invokeActionString(self.loadedActions,self,event,variables);
|
|
||||||
}
|
|
||||||
},false);
|
},false);
|
||||||
domNode.addEventListener("error",function() {
|
domNode.addEventListener("error",function() {
|
||||||
$tw.utils.removeClass(domNode,"tc-image-loading");
|
$tw.utils.removeClass(domNode,"tc-image-loading");
|
||||||
@@ -153,31 +143,17 @@ ImageWidget.prototype.execute = function() {
|
|||||||
this.imageTooltip = this.getAttribute("tooltip");
|
this.imageTooltip = this.getAttribute("tooltip");
|
||||||
this.imageAlt = this.getAttribute("alt");
|
this.imageAlt = this.getAttribute("alt");
|
||||||
this.lazyLoading = this.getAttribute("loading");
|
this.lazyLoading = this.getAttribute("loading");
|
||||||
this.loadedActions = this.getAttribute("loadActions");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
|
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
|
||||||
*/
|
*/
|
||||||
ImageWidget.prototype.refresh = function(changedTiddlers) {
|
ImageWidget.prototype.refresh = function(changedTiddlers) {
|
||||||
var changedAttributes = this.computeAttributes(),
|
var changedAttributes = this.computeAttributes();
|
||||||
hasChangedAttributes = $tw.utils.count(changedAttributes) > 0;
|
if(changedAttributes.source || changedAttributes.width || changedAttributes.height || changedAttributes["class"] || changedAttributes.usemap || changedAttributes.tooltip || changedTiddlers[this.imageSource]) {
|
||||||
if(changedAttributes.source || changedAttributes["class"] || changedAttributes.usemap || changedAttributes.tooltip || changedTiddlers[this.imageSource] ||changedAttributes.loadActions) {
|
|
||||||
this.refreshSelf();
|
this.refreshSelf();
|
||||||
return true;
|
return true;
|
||||||
} else if(hasChangedAttributes) {
|
} else {
|
||||||
this.assignAttributes(this.domNodes[0],{
|
|
||||||
sourcePrefix: "data-",
|
|
||||||
destPrefix: "data-"
|
|
||||||
});
|
|
||||||
if(changedAttributes.width) {
|
|
||||||
this.domNodes[0].setAttribute("width",this.getAttribute("width"));
|
|
||||||
}
|
|
||||||
if(changedAttributes.height) {
|
|
||||||
this.domNodes[0].setAttribute("height",this.getAttribute("height"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -45,8 +45,8 @@ KeyboardWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
]);
|
]);
|
||||||
// Insert element
|
// Insert element
|
||||||
parent.insertBefore(domNode,nextSibling);
|
parent.insertBefore(domNode,nextSibling);
|
||||||
this.domNodes.push(domNode);
|
|
||||||
this.renderChildren(domNode,null);
|
this.renderChildren(domNode,null);
|
||||||
|
this.domNodes.push(domNode);
|
||||||
};
|
};
|
||||||
|
|
||||||
KeyboardWidget.prototype.handleChangeEvent = function(event) {
|
KeyboardWidget.prototype.handleChangeEvent = function(event) {
|
||||||
|
|||||||
@@ -50,8 +50,8 @@ LinkWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
destPrefix: "aria-"
|
destPrefix: "aria-"
|
||||||
});
|
});
|
||||||
parent.insertBefore(domNode,nextSibling);
|
parent.insertBefore(domNode,nextSibling);
|
||||||
this.domNodes.push(domNode);
|
|
||||||
this.renderChildren(domNode,null);
|
this.renderChildren(domNode,null);
|
||||||
|
this.domNodes.push(domNode);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ LinkWidget.prototype.renderLink = function(parent,nextSibling) {
|
|||||||
classes.push(this.linkClasses);
|
classes.push(this.linkClasses);
|
||||||
}
|
}
|
||||||
} else if(this.overrideClasses !== "") {
|
} else if(this.overrideClasses !== "") {
|
||||||
classes.push(this.overrideClasses);
|
classes.push(this.overrideClasses)
|
||||||
}
|
}
|
||||||
if(classes.length > 0) {
|
if(classes.length > 0) {
|
||||||
domNode.setAttribute("class",classes.join(" "));
|
domNode.setAttribute("class",classes.join(" "));
|
||||||
@@ -97,7 +97,7 @@ LinkWidget.prototype.renderLink = function(parent,nextSibling) {
|
|||||||
if(wikilinkTransformFilter) {
|
if(wikilinkTransformFilter) {
|
||||||
// Use the filter to construct the href
|
// Use the filter to construct the href
|
||||||
wikiLinkText = this.wiki.filterTiddlers(wikilinkTransformFilter,this,function(iterator) {
|
wikiLinkText = this.wiki.filterTiddlers(wikilinkTransformFilter,this,function(iterator) {
|
||||||
iterator(self.wiki.getTiddler(self.to),self.to);
|
iterator(self.wiki.getTiddler(self.to),self.to)
|
||||||
})[0];
|
})[0];
|
||||||
} else {
|
} else {
|
||||||
// Expand the tv-wikilink-template variable to construct the href
|
// Expand the tv-wikilink-template variable to construct the href
|
||||||
@@ -121,12 +121,12 @@ LinkWidget.prototype.renderLink = function(parent,nextSibling) {
|
|||||||
var tooltipWikiText = this.tooltip || this.getVariable("tv-wikilink-tooltip");
|
var tooltipWikiText = this.tooltip || this.getVariable("tv-wikilink-tooltip");
|
||||||
if(tooltipWikiText) {
|
if(tooltipWikiText) {
|
||||||
var tooltipText = this.wiki.renderText("text/plain","text/vnd.tiddlywiki",tooltipWikiText,{
|
var tooltipText = this.wiki.renderText("text/plain","text/vnd.tiddlywiki",tooltipWikiText,{
|
||||||
parseAsInline: true,
|
parseAsInline: true,
|
||||||
variables: {
|
variables: {
|
||||||
currentTiddler: this.to
|
currentTiddler: this.to
|
||||||
},
|
},
|
||||||
parentWidget: this
|
parentWidget: this
|
||||||
});
|
});
|
||||||
domNode.setAttribute("title",tooltipText);
|
domNode.setAttribute("title",tooltipText);
|
||||||
}
|
}
|
||||||
if(this.role) {
|
if(this.role) {
|
||||||
@@ -135,7 +135,7 @@ LinkWidget.prototype.renderLink = function(parent,nextSibling) {
|
|||||||
this.assignAttributes(domNode,{
|
this.assignAttributes(domNode,{
|
||||||
sourcePrefix: "aria-",
|
sourcePrefix: "aria-",
|
||||||
destPrefix: "aria-"
|
destPrefix: "aria-"
|
||||||
});
|
})
|
||||||
// Add a click event handler
|
// Add a click event handler
|
||||||
$tw.utils.addEventListeners(domNode,[
|
$tw.utils.addEventListeners(domNode,[
|
||||||
{name: "click", handlerObject: this, handlerMethod: "handleClickEvent"},
|
{name: "click", handlerObject: this, handlerMethod: "handleClickEvent"},
|
||||||
@@ -145,8 +145,6 @@ LinkWidget.prototype.renderLink = function(parent,nextSibling) {
|
|||||||
$tw.utils.makeDraggable({
|
$tw.utils.makeDraggable({
|
||||||
domNode: domNode,
|
domNode: domNode,
|
||||||
dragTiddlerFn: function() {return self.to;},
|
dragTiddlerFn: function() {return self.to;},
|
||||||
startActions: self.startActions,
|
|
||||||
endActions: self.endActions,
|
|
||||||
widget: this
|
widget: this
|
||||||
});
|
});
|
||||||
} else if(this.draggable === "no") {
|
} else if(this.draggable === "no") {
|
||||||
@@ -159,8 +157,8 @@ LinkWidget.prototype.renderLink = function(parent,nextSibling) {
|
|||||||
});
|
});
|
||||||
// Insert the link into the DOM and render any children
|
// Insert the link into the DOM and render any children
|
||||||
parent.insertBefore(domNode,nextSibling);
|
parent.insertBefore(domNode,nextSibling);
|
||||||
this.domNodes.push(domNode);
|
|
||||||
this.renderChildren(domNode,null);
|
this.renderChildren(domNode,null);
|
||||||
|
this.domNodes.push(domNode);
|
||||||
};
|
};
|
||||||
|
|
||||||
LinkWidget.prototype.handleClickEvent = function(event) {
|
LinkWidget.prototype.handleClickEvent = function(event) {
|
||||||
@@ -205,8 +203,6 @@ LinkWidget.prototype.execute = function() {
|
|||||||
this.overrideClasses = this.getAttribute("overrideClass");
|
this.overrideClasses = this.getAttribute("overrideClass");
|
||||||
this.tabIndex = this.getAttribute("tabindex");
|
this.tabIndex = this.getAttribute("tabindex");
|
||||||
this.draggable = this.getAttribute("draggable","yes");
|
this.draggable = this.getAttribute("draggable","yes");
|
||||||
this.startActions = this.getAttribute("startactions");
|
|
||||||
this.endActions = this.getAttribute("endactions");
|
|
||||||
this.linkTag = this.getAttribute("tag","a");
|
this.linkTag = this.getAttribute("tag","a");
|
||||||
// Determine the link characteristics
|
// Determine the link characteristics
|
||||||
this.isMissing = !this.wiki.tiddlerExists(this.to);
|
this.isMissing = !this.wiki.tiddlerExists(this.to);
|
||||||
|
|||||||
@@ -61,9 +61,7 @@ ParametersWidget.prototype.execute = function() {
|
|||||||
if(name.substr(0,2) === "$$") {
|
if(name.substr(0,2) === "$$") {
|
||||||
name = name.substr(1);
|
name = name.substr(1);
|
||||||
}
|
}
|
||||||
var defaultValue = (self.multiValuedAttributes && self.multiValuedAttributes[attr.name])
|
var value = pointer.getTransclusionParameter(name,index,self.getAttribute(attr.name,""));
|
||||||
|| self.getAttribute(attr.name,"");
|
|
||||||
var value = pointer.getTransclusionParameter(name,index,defaultValue);
|
|
||||||
self.setVariable(name,value);
|
self.setVariable(name,value);
|
||||||
});
|
});
|
||||||
// Assign any metaparameters
|
// Assign any metaparameters
|
||||||
@@ -82,8 +80,7 @@ ParametersWidget.prototype.execute = function() {
|
|||||||
if(name.substr(0,2) === "$$") {
|
if(name.substr(0,2) === "$$") {
|
||||||
name = name.substr(1);
|
name = name.substr(1);
|
||||||
}
|
}
|
||||||
var value = (self.multiValuedAttributes && self.multiValuedAttributes[attr.name])
|
var value = self.getAttribute(attr.name,"");
|
||||||
|| self.getAttribute(attr.name,"");
|
|
||||||
self.setVariable(name,value);
|
self.setVariable(name,value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ PasswordWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
]);
|
]);
|
||||||
// Insert the label into the DOM and render any children
|
// Insert the label into the DOM and render any children
|
||||||
parent.insertBefore(domNode,nextSibling);
|
parent.insertBefore(domNode,nextSibling);
|
||||||
this.domNodes.push(domNode);
|
|
||||||
this.renderChildren(domNode,null);
|
this.renderChildren(domNode,null);
|
||||||
|
this.domNodes.push(domNode);
|
||||||
};
|
};
|
||||||
|
|
||||||
PasswordWidget.prototype.handleChangeEvent = function(event) {
|
PasswordWidget.prototype.handleChangeEvent = function(event) {
|
||||||
|
|||||||
@@ -59,8 +59,8 @@ RadioWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
]);
|
]);
|
||||||
// Insert the label into the DOM and render any children
|
// Insert the label into the DOM and render any children
|
||||||
parent.insertBefore(this.labelDomNode,nextSibling);
|
parent.insertBefore(this.labelDomNode,nextSibling);
|
||||||
this.domNodes.push(this.labelDomNode);
|
|
||||||
this.renderChildren(this.spanDomNode,null);
|
this.renderChildren(this.spanDomNode,null);
|
||||||
|
this.domNodes.push(this.labelDomNode);
|
||||||
};
|
};
|
||||||
|
|
||||||
RadioWidget.prototype.getValue = function() {
|
RadioWidget.prototype.getValue = function() {
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ RevealWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
domNode.setAttribute("style",this.style);
|
domNode.setAttribute("style",this.style);
|
||||||
}
|
}
|
||||||
parent.insertBefore(domNode,nextSibling);
|
parent.insertBefore(domNode,nextSibling);
|
||||||
this.domNodes.push(domNode);
|
|
||||||
this.renderChildren(domNode,null);
|
this.renderChildren(domNode,null);
|
||||||
if(!domNode.isTiddlyWikiFakeDom && this.type === "popup" && this.isOpen) {
|
if(!domNode.isTiddlyWikiFakeDom && this.type === "popup" && this.isOpen) {
|
||||||
this.positionPopup(domNode);
|
this.positionPopup(domNode);
|
||||||
@@ -49,6 +48,7 @@ RevealWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
if(!this.isOpen) {
|
if(!this.isOpen) {
|
||||||
domNode.setAttribute("hidden","true");
|
domNode.setAttribute("hidden","true");
|
||||||
}
|
}
|
||||||
|
this.domNodes.push(domNode);
|
||||||
};
|
};
|
||||||
|
|
||||||
RevealWidget.prototype.positionPopup = function(domNode) {
|
RevealWidget.prototype.positionPopup = function(domNode) {
|
||||||
|
|||||||
@@ -168,8 +168,8 @@ ScrollableWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
this.outerDomNode.className = this["class"] || "";
|
this.outerDomNode.className = this["class"] || "";
|
||||||
// Insert element
|
// Insert element
|
||||||
parent.insertBefore(this.outerDomNode,nextSibling);
|
parent.insertBefore(this.outerDomNode,nextSibling);
|
||||||
this.domNodes.push(this.outerDomNode);
|
|
||||||
this.renderChildren(this.innerDomNode,null);
|
this.renderChildren(this.innerDomNode,null);
|
||||||
|
this.domNodes.push(this.outerDomNode);
|
||||||
// If the scroll position is bound to a tiddler
|
// If the scroll position is bound to a tiddler
|
||||||
if(this.scrollableBind) {
|
if(this.scrollableBind) {
|
||||||
// After a delay for rendering, scroll to the bound position
|
// After a delay for rendering, scroll to the bound position
|
||||||
|
|||||||
@@ -63,8 +63,8 @@ SelectWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
domNode.setAttribute("title",this.selectTooltip);
|
domNode.setAttribute("title",this.selectTooltip);
|
||||||
}
|
}
|
||||||
this.parentDomNode.insertBefore(domNode,nextSibling);
|
this.parentDomNode.insertBefore(domNode,nextSibling);
|
||||||
this.domNodes.push(domNode);
|
|
||||||
this.renderChildren(domNode,null);
|
this.renderChildren(domNode,null);
|
||||||
|
this.domNodes.push(domNode);
|
||||||
this.setSelectValue();
|
this.setSelectValue();
|
||||||
if(this.selectFocus == "yes") {
|
if(this.selectFocus == "yes") {
|
||||||
this.getSelectDomNode().focus();
|
this.getSelectDomNode().focus();
|
||||||
@@ -82,8 +82,8 @@ SelectWidget.prototype.handleChangeEvent = function(event) {
|
|||||||
if(this.selectMultiple == false) {
|
if(this.selectMultiple == false) {
|
||||||
var value = this.getSelectDomNode().value;
|
var value = this.getSelectDomNode().value;
|
||||||
} else {
|
} else {
|
||||||
var value = this.getSelectValues();
|
var value = this.getSelectValues()
|
||||||
value = $tw.utils.stringifyList(value);
|
value = $tw.utils.stringifyList(value);
|
||||||
}
|
}
|
||||||
this.wiki.setText(this.selectTitle,this.selectField,this.selectIndex,value);
|
this.wiki.setText(this.selectTitle,this.selectField,this.selectIndex,value);
|
||||||
// Trigger actions
|
// Trigger actions
|
||||||
@@ -118,21 +118,12 @@ SelectWidget.prototype.setSelectValue = function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Assign it to the select element if it's different than the current value
|
// Assign it to the select element if it's different than the current value
|
||||||
if(this.selectMultiple) {
|
if (this.selectMultiple) {
|
||||||
value = value === undefined ? "" : value;
|
value = value === undefined ? "" : value;
|
||||||
var select = this.getSelectDomNode();
|
var select = this.getSelectDomNode();
|
||||||
var child,
|
var values = Array.isArray(value) ? value : $tw.utils.parseStringArray(value);
|
||||||
values = Array.isArray(value) ? value : $tw.utils.parseStringArray(value);
|
|
||||||
for(var i=0; i < select.children.length; i++){
|
for(var i=0; i < select.children.length; i++){
|
||||||
child=select.children[i];
|
select.children[i].selected = values.indexOf(select.children[i].value) !== -1
|
||||||
if(child.children.length === 0){
|
|
||||||
child.selected = values.indexOf(child.value) !== -1;
|
|
||||||
} else {
|
|
||||||
// grouped options
|
|
||||||
for(var y=0; y < child.children.length; y++){
|
|
||||||
child.children[y].selected = values.indexOf(child.children[y].value) !== -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var domNode = this.getSelectDomNode();
|
var domNode = this.getSelectDomNode();
|
||||||
@@ -156,14 +147,14 @@ SelectWidget.prototype.getSelectValues = function() {
|
|||||||
select = this.getSelectDomNode();
|
select = this.getSelectDomNode();
|
||||||
result = [];
|
result = [];
|
||||||
options = select && select.options;
|
options = select && select.options;
|
||||||
for(var i=0; i<options.length; i++) {
|
for (var i=0; i<options.length; i++) {
|
||||||
opt = options[i];
|
opt = options[i];
|
||||||
if(opt.selected) {
|
if (opt.selected) {
|
||||||
result.push(opt.value || opt.text);
|
result.push(opt.value || opt.text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Compute the internal state of the widget
|
Compute the internal state of the widget
|
||||||
@@ -192,7 +183,7 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
|
|||||||
SelectWidget.prototype.refresh = function(changedTiddlers) {
|
SelectWidget.prototype.refresh = function(changedTiddlers) {
|
||||||
var changedAttributes = this.computeAttributes();
|
var changedAttributes = this.computeAttributes();
|
||||||
// If we're using a different tiddler/field/index then completely refresh ourselves
|
// If we're using a different tiddler/field/index then completely refresh ourselves
|
||||||
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.tooltip || changedAttributes.default || changedAttributes.tabindex || changedAttributes.disabled) {
|
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.tooltip || changedAttributes.tabindex || changedAttributes.disabled) {
|
||||||
this.refreshSelf();
|
this.refreshSelf();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -32,26 +32,16 @@ TranscludeWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
} catch(error) {
|
} catch(error) {
|
||||||
if(error instanceof $tw.utils.TranscludeRecursionError) {
|
if(error instanceof $tw.utils.TranscludeRecursionError) {
|
||||||
// We were infinite looping.
|
// We were infinite looping.
|
||||||
// We need to try and abort as much of the loop as we
|
// We need to try and abort as much of the loop as we can, so we will keep "throwing" upward until we find a transclusion that has a different signature.
|
||||||
// can, so we will keep "throwing" upward until we find
|
// Hopefully that will land us just outside where the loop began. That's where we want to issue an error.
|
||||||
// a transclusion that has a different signature.
|
// Rendering widgets beneath this point may result in a freezing browser if they explode exponentially.
|
||||||
// Hopefully that will land us just outside where the
|
|
||||||
// loop began. That's where we want to issue an error.
|
|
||||||
// Rendering widgets beneath this point may result in a
|
|
||||||
// freezing browser if they explode exponentially.
|
|
||||||
var transcludeSignature = this.getVariable("transclusion");
|
var transcludeSignature = this.getVariable("transclusion");
|
||||||
if(this.getAncestorCount() > $tw.utils.TranscludeRecursionError.MAX_WIDGET_TREE_DEPTH - 50) {
|
if(this.getAncestorCount() > $tw.utils.TranscludeRecursionError.MAX_WIDGET_TREE_DEPTH - 50) {
|
||||||
// For the first fifty transcludes we climb up,
|
// For the first fifty transcludes we climb up, we simply collect signatures.
|
||||||
// we simply collect signatures.
|
// We're assuming that those first 50 will likely include all transcludes involved in the loop.
|
||||||
// We're assuming those first 50 will likely
|
|
||||||
// include all transcludes involved in the loop.
|
|
||||||
error.signatures[transcludeSignature] = true;
|
error.signatures[transcludeSignature] = true;
|
||||||
} else if(!error.signatures[transcludeSignature]) {
|
} else if(!error.signatures[transcludeSignature]) {
|
||||||
// Now that we're past the first 50, look for
|
// Now that we're past the first 50, let's look for the first signature that wasn't in the loop. That'll be where we print the error and resume rendering.
|
||||||
// the first signature that wasn't in that loop.
|
|
||||||
// That's where we print the error and resume
|
|
||||||
// rendering.
|
|
||||||
this.removeChildDomNodes();
|
|
||||||
this.children = [this.makeChildWidget({type: "error", attributes: {
|
this.children = [this.makeChildWidget({type: "error", attributes: {
|
||||||
"$message": {type: "string", value: $tw.language.getString("Error/RecursiveTransclusion")}
|
"$message": {type: "string", value: $tw.language.getString("Error/RecursiveTransclusion")}
|
||||||
}})];
|
}})];
|
||||||
@@ -158,10 +148,8 @@ Collect string parameters
|
|||||||
TranscludeWidget.prototype.collectStringParameters = function() {
|
TranscludeWidget.prototype.collectStringParameters = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
this.stringParametersByName = Object.create(null);
|
this.stringParametersByName = Object.create(null);
|
||||||
this.multiValuedParametersByName = Object.create(null);
|
|
||||||
if(!this.legacyMode) {
|
if(!this.legacyMode) {
|
||||||
$tw.utils.each(this.attributes,function(value,name) {
|
$tw.utils.each(this.attributes,function(value,name) {
|
||||||
var attrName = name; // Save original attribute name for MVV lookup
|
|
||||||
if(name.charAt(0) === "$") {
|
if(name.charAt(0) === "$") {
|
||||||
if(name.charAt(1) === "$") {
|
if(name.charAt(1) === "$") {
|
||||||
// Attributes starting $$ represent parameters starting with a single $
|
// Attributes starting $$ represent parameters starting with a single $
|
||||||
@@ -172,9 +160,6 @@ TranscludeWidget.prototype.collectStringParameters = function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.stringParametersByName[name] = value;
|
self.stringParametersByName[name] = value;
|
||||||
if(self.multiValuedAttributes && self.multiValuedAttributes[attrName]) {
|
|
||||||
self.multiValuedParametersByName[name] = self.multiValuedAttributes[attrName];
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -318,16 +303,7 @@ TranscludeWidget.prototype.parseTransclusionTarget = function(parseAsInline) {
|
|||||||
if(name.charAt(0) === "$") {
|
if(name.charAt(0) === "$") {
|
||||||
name = "$" + name;
|
name = "$" + name;
|
||||||
}
|
}
|
||||||
if(param.defaultType === "multivalue-variable") {
|
$tw.utils.addAttributeToParseTreeNode(parser.tree[0],name,param["default"])
|
||||||
// Construct MVV attribute for the default
|
|
||||||
var mvvNode = {type: "transclude", isMVV: true, attributes: {}, orderedAttributes: []};
|
|
||||||
$tw.utils.addAttributeToParseTreeNode(mvvNode,"$variable",param.defaultVariable);
|
|
||||||
$tw.utils.addAttributeToParseTreeNode(parser.tree[0],{
|
|
||||||
name: name, type: "macro", isMVV: true, value: mvvNode
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
$tw.utils.addAttributeToParseTreeNode(parser.tree[0],name,param["default"]);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} else if(srcVariable && !srcVariable.isFunctionDefinition) {
|
} else if(srcVariable && !srcVariable.isFunctionDefinition) {
|
||||||
// For macros and ordinary variables, wrap the parse tree in a vars widget assigning the parameters to variables named "__paramname__"
|
// For macros and ordinary variables, wrap the parse tree in a vars widget assigning the parameters to variables named "__paramname__"
|
||||||
@@ -378,11 +354,7 @@ TranscludeWidget.prototype.getOrderedTransclusionParameters = function() {
|
|||||||
// Collect the parameters
|
// Collect the parameters
|
||||||
for(var name in this.stringParametersByName) {
|
for(var name in this.stringParametersByName) {
|
||||||
var value = this.stringParametersByName[name];
|
var value = this.stringParametersByName[name];
|
||||||
var param = {name: name, value: value};
|
result.push({name: name, value: value});
|
||||||
if(this.multiValuedParametersByName[name]) {
|
|
||||||
param.multiValue = this.multiValuedParametersByName[name];
|
|
||||||
}
|
|
||||||
result.push(param);
|
|
||||||
}
|
}
|
||||||
// Sort numerical parameter names first
|
// Sort numerical parameter names first
|
||||||
result.sort(function(a,b) {
|
result.sort(function(a,b) {
|
||||||
@@ -412,16 +384,10 @@ Fetch the value of a parameter
|
|||||||
*/
|
*/
|
||||||
TranscludeWidget.prototype.getTransclusionParameter = function(name,index,defaultValue) {
|
TranscludeWidget.prototype.getTransclusionParameter = function(name,index,defaultValue) {
|
||||||
if(name in this.stringParametersByName) {
|
if(name in this.stringParametersByName) {
|
||||||
if(this.multiValuedParametersByName[name]) {
|
|
||||||
return this.multiValuedParametersByName[name];
|
|
||||||
}
|
|
||||||
return this.stringParametersByName[name];
|
return this.stringParametersByName[name];
|
||||||
} else {
|
} else {
|
||||||
var name = "" + index;
|
var name = "" + index;
|
||||||
if(name in this.stringParametersByName) {
|
if(name in this.stringParametersByName) {
|
||||||
if(this.multiValuedParametersByName[name]) {
|
|
||||||
return this.multiValuedParametersByName[name];
|
|
||||||
}
|
|
||||||
return this.stringParametersByName[name];
|
return this.stringParametersByName[name];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ Widget.prototype.getVariableInfo = function(name,options) {
|
|||||||
} else if(variable.isFunctionDefinition) {
|
} else if(variable.isFunctionDefinition) {
|
||||||
// Function evaluations
|
// Function evaluations
|
||||||
params = self.resolveVariableParameters(variable.params,actualParams);
|
params = self.resolveVariableParameters(variable.params,actualParams);
|
||||||
var variables = $tw.utils.extend({},options.variables);
|
var variables = options.variables || Object.create(null);
|
||||||
// Apply default parameter values
|
// Apply default parameter values
|
||||||
$tw.utils.each(variable.params,function(param,index) {
|
$tw.utils.each(variable.params,function(param,index) {
|
||||||
if(param["default"]) {
|
if(param["default"]) {
|
||||||
@@ -160,7 +160,7 @@ Widget.prototype.getVariableInfo = function(name,options) {
|
|||||||
});
|
});
|
||||||
// Parameters are an array of {name:, value:, multivalue:} pairs (name and multivalue are optional)
|
// Parameters are an array of {name:, value:, multivalue:} pairs (name and multivalue are optional)
|
||||||
$tw.utils.each(params,function(param) {
|
$tw.utils.each(params,function(param) {
|
||||||
if(param.multiValue && param.multiValue.length) {
|
if(param.multiValue) {
|
||||||
variables[param.name] = param.multiValue;
|
variables[param.name] = param.multiValue;
|
||||||
} else {
|
} else {
|
||||||
variables[param.name] = param.value || "";
|
variables[param.name] = param.value || "";
|
||||||
@@ -233,10 +233,8 @@ Widget.prototype.resolveVariableParameters = function(formalParams,actualParams)
|
|||||||
paramMultiValue = typeof param === "string" ? [param] : (param.multiValue || [paramValue]);
|
paramMultiValue = typeof param === "string" ? [param] : (param.multiValue || [paramValue]);
|
||||||
}
|
}
|
||||||
// If we've still not got a value, use the default, if any
|
// If we've still not got a value, use the default, if any
|
||||||
if(!paramValue) {
|
paramValue = paramValue || paramInfo["default"] || "";
|
||||||
paramValue = paramInfo["default"] || "";
|
paramMultiValue = paramMultiValue || [paramValue];
|
||||||
paramMultiValue = [paramValue];
|
|
||||||
}
|
|
||||||
// Store the parameter name and value
|
// Store the parameter name and value
|
||||||
results.push({name: paramInfo.name, value: paramValue, multiValue: paramMultiValue});
|
results.push({name: paramInfo.name, value: paramValue, multiValue: paramMultiValue});
|
||||||
}
|
}
|
||||||
@@ -343,7 +341,7 @@ Widget.prototype.makeFakeWidgetWithVariables = function(variables) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
opts.variables = $tw.utils.extend({},variables,opts.variables);
|
opts.variables = variables;
|
||||||
return self.getVariable(name,opts);
|
return self.getVariable(name,opts);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -381,31 +379,19 @@ filterFn: only include attributes where filterFn(name) returns true
|
|||||||
Widget.prototype.computeAttributes = function(options) {
|
Widget.prototype.computeAttributes = function(options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var changedAttributes = {},
|
var changedAttributes = {},
|
||||||
self = this,
|
self = this;
|
||||||
newMultiValuedAttributes = Object.create(null);
|
|
||||||
$tw.utils.each(this.parseTreeNode.attributes,function(attribute,name) {
|
$tw.utils.each(this.parseTreeNode.attributes,function(attribute,name) {
|
||||||
if(options.filterFn) {
|
if(options.filterFn) {
|
||||||
if(!options.filterFn(name)) {
|
if(!options.filterFn(name)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var value = self.computeAttribute(attribute),
|
var value = self.computeAttribute(attribute);
|
||||||
multiValue = null;
|
if(self.attributes[name] !== value) {
|
||||||
if($tw.utils.isArray(value)) {
|
|
||||||
multiValue = value;
|
|
||||||
newMultiValuedAttributes[name] = multiValue;
|
|
||||||
value = value[0] || "";
|
|
||||||
}
|
|
||||||
var changed = (self.attributes[name] !== value);
|
|
||||||
if(!changed && multiValue && self.multiValuedAttributes) {
|
|
||||||
changed = !$tw.utils.isArrayEqual(self.multiValuedAttributes[name] || [], multiValue);
|
|
||||||
}
|
|
||||||
if(changed) {
|
|
||||||
self.attributes[name] = value;
|
self.attributes[name] = value;
|
||||||
changedAttributes[name] = true;
|
changedAttributes[name] = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.multiValuedAttributes = newMultiValuedAttributes;
|
|
||||||
return changedAttributes;
|
return changedAttributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -428,22 +414,8 @@ Widget.prototype.computeAttribute = function(attribute,options) {
|
|||||||
value = [value];
|
value = [value];
|
||||||
}
|
}
|
||||||
} else if(attribute.type === "macro") {
|
} else if(attribute.type === "macro") {
|
||||||
// Get the macro name
|
var variableInfo = this.getVariableInfo(attribute.value.name,{params: attribute.value.params});
|
||||||
var macroName = attribute.value.attributes["$variable"].value;
|
if(options.asList) {
|
||||||
// Collect macro parameters
|
|
||||||
var params = [];
|
|
||||||
$tw.utils.each(attribute.value.orderedAttributes,function(attr) {
|
|
||||||
var param = {
|
|
||||||
value: self.computeAttribute(attr)
|
|
||||||
};
|
|
||||||
if(attr.name && !attr.isPositional) {
|
|
||||||
param.name = attr.name;
|
|
||||||
}
|
|
||||||
params.push(param);
|
|
||||||
});
|
|
||||||
// Invoke the macro
|
|
||||||
var variableInfo = this.getVariableInfo(macroName,{params: params});
|
|
||||||
if(options.asList || attribute.isMVV) {
|
|
||||||
value = variableInfo.resultList;
|
value = variableInfo.resultList;
|
||||||
} else {
|
} else {
|
||||||
value = variableInfo.text;
|
value = variableInfo.text;
|
||||||
@@ -799,9 +771,9 @@ Widget.prototype.findNextSiblingDomNode = function(startIndex) {
|
|||||||
// Refer to this widget by its index within its parents children
|
// Refer to this widget by its index within its parents children
|
||||||
var parent = this.parentWidget,
|
var parent = this.parentWidget,
|
||||||
index = startIndex !== undefined ? startIndex : parent.children.indexOf(this);
|
index = startIndex !== undefined ? startIndex : parent.children.indexOf(this);
|
||||||
if(index === -1) {
|
if(index === -1) {
|
||||||
throw "node not found in parents children";
|
throw "node not found in parents children";
|
||||||
}
|
}
|
||||||
// Look for a DOM node in the later siblings
|
// Look for a DOM node in the later siblings
|
||||||
while(++index < parent.children.length) {
|
while(++index < parent.children.length) {
|
||||||
var domNode = parent.children[index].findFirstDomNode();
|
var domNode = parent.children[index].findFirstDomNode();
|
||||||
@@ -839,60 +811,21 @@ Widget.prototype.findFirstDomNode = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Entry into destroy procedure
|
Remove any DOM nodes created by this widget or its children
|
||||||
options include:
|
|
||||||
removeDOMNodes: boolean (default true)
|
|
||||||
*/
|
|
||||||
Widget.prototype.destroyChildren = function(options) {
|
|
||||||
$tw.utils.each(this.children,function(childWidget) {
|
|
||||||
childWidget.destroy(options);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Legacy entry into destroy procedure
|
|
||||||
*/
|
*/
|
||||||
Widget.prototype.removeChildDomNodes = function() {
|
Widget.prototype.removeChildDomNodes = function() {
|
||||||
this.destroy({removeDOMNodes: true});
|
// If this widget has directly created DOM nodes, delete them and exit. This assumes that any child widgets are contained within the created DOM nodes, which would normally be the case
|
||||||
};
|
if(this.domNodes.length > 0) {
|
||||||
|
$tw.utils.each(this.domNodes,function(domNode) {
|
||||||
/*
|
|
||||||
Default destroy
|
|
||||||
options include:
|
|
||||||
- removeDOMNodes: boolean (default true)
|
|
||||||
*/
|
|
||||||
Widget.prototype.destroy = function(options) {
|
|
||||||
const { removeDOMNodes = true } = options || {};
|
|
||||||
let removeChildDOMNodes = removeDOMNodes;
|
|
||||||
if(removeDOMNodes && this.domNodes.length > 0) {
|
|
||||||
// If this widget will remove its own DOM nodes, children should not remove theirs
|
|
||||||
removeChildDOMNodes = false;
|
|
||||||
}
|
|
||||||
// Destroy children first
|
|
||||||
this.destroyChildren({removeDOMNodes: removeChildDOMNodes});
|
|
||||||
this.children = [];
|
|
||||||
|
|
||||||
// Call custom cleanup method if implemented
|
|
||||||
if(typeof this.onDestroy === "function") {
|
|
||||||
this.onDestroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove our DOM nodes if needed
|
|
||||||
if(removeDOMNodes) {
|
|
||||||
this.removeLocalDomNodes();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Remove any DOM nodes created by this widget
|
|
||||||
*/
|
|
||||||
Widget.prototype.removeLocalDomNodes = function() {
|
|
||||||
for(const domNode of this.domNodes) {
|
|
||||||
if(domNode.parentNode) {
|
|
||||||
domNode.parentNode.removeChild(domNode);
|
domNode.parentNode.removeChild(domNode);
|
||||||
}
|
});
|
||||||
|
this.domNodes = [];
|
||||||
|
} else {
|
||||||
|
// Otherwise, ask the child widgets to delete their DOM nodes
|
||||||
|
$tw.utils.each(this.children,function(childWidget) {
|
||||||
|
childWidget.removeChildDomNodes();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
this.domNodes = [];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -1122,16 +1122,15 @@ Parse a block of text of a specified MIME type
|
|||||||
Options include:
|
Options include:
|
||||||
substitutions: an optional array of substitutions
|
substitutions: an optional array of substitutions
|
||||||
*/
|
*/
|
||||||
exports.getSubstitutedText = function(text,thisWidget,options) {
|
exports.getSubstitutedText = function(text,widget,options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
text = text || "";
|
text = text || "";
|
||||||
var self = this,
|
var self = this,
|
||||||
widgetClass = widget.widget,
|
|
||||||
substitutions = options.substitutions || [],
|
substitutions = options.substitutions || [],
|
||||||
output;
|
output;
|
||||||
// Evaluate embedded filters and substitute with first result
|
// Evaluate embedded filters and substitute with first result
|
||||||
output = text.replace(/\$\{([\S\s]+?)\}\$/g, function(match,filter) {
|
output = text.replace(/\$\{([\S\s]+?)\}\$/g, function(match,filter) {
|
||||||
return self.filterTiddlers(filter,thisWidget)[0] || "";
|
return self.filterTiddlers(filter,widget)[0] || "";
|
||||||
});
|
});
|
||||||
// Process any substitutions provided in options
|
// Process any substitutions provided in options
|
||||||
$tw.utils.each(substitutions,function(substitute) {
|
$tw.utils.each(substitutions,function(substitute) {
|
||||||
@@ -1139,7 +1138,7 @@ exports.getSubstitutedText = function(text,thisWidget,options) {
|
|||||||
});
|
});
|
||||||
// Substitute any variable references with their values
|
// Substitute any variable references with their values
|
||||||
return output.replace(/\$\((.+?)\)\$/g, function(match,varname) {
|
return output.replace(/\$\((.+?)\)\$/g, function(match,varname) {
|
||||||
return widgetClass.evaluateVariable(thisWidget,varname, {defaultValue: ""})[0];
|
return widget.getVariable(varname,{defaultValue: ""});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1664,14 +1663,12 @@ exports.addToStory = function(title,fromTitle,storyTitle,options) {
|
|||||||
Generate a title for the draft of a given tiddler
|
Generate a title for the draft of a given tiddler
|
||||||
*/
|
*/
|
||||||
exports.generateDraftTitle = function(title) {
|
exports.generateDraftTitle = function(title) {
|
||||||
let c = 0,
|
var c = 0,
|
||||||
draftTitle;
|
draftTitle,
|
||||||
const username = this.getTiddlerText("$:/status/UserName");
|
username = this.getTiddlerText("$:/status/UserName"),
|
||||||
|
attribution = username ? " by " + username : "";
|
||||||
do {
|
do {
|
||||||
draftTitle = username ? $tw.language.getString("Draft/Attribution", {variables: {"draft-title": title}}) : $tw.language.getString("Draft/Title", {variables: {"draft-title": title}});
|
draftTitle = "Draft " + (c ? (c + 1) + " " : "") + "of '" + title + "'" + attribution;
|
||||||
if(c) {
|
|
||||||
draftTitle = draftTitle.concat(" ", (c + 1).toString());
|
|
||||||
}
|
|
||||||
c++;
|
c++;
|
||||||
} while(this.tiddlerExists(draftTitle));
|
} while(this.tiddlerExists(draftTitle));
|
||||||
return draftTitle;
|
return draftTitle;
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
title: $:/core/stylesheets/custom-properties
|
|
||||||
|
|
||||||
\rules only transcludeinline macrocallinline html transcludeblock
|
|
||||||
|
|
||||||
/* Tiddlywiki's CSS properties */
|
|
||||||
|
|
||||||
:root {
|
|
||||||
<$list filter="[[$:/palettes/Vanilla]indexes[]]">
|
|
||||||
--tpc-<<currentTiddler>>: <$transclude $variable="colour" $mode="inline" name=<<currentTiddler>>/>;
|
|
||||||
</$list>
|
|
||||||
|
|
||||||
/* CSS settings */
|
|
||||||
--tp-code-wrapping: {{$:/themes/tiddlywiki/vanilla/options/codewrapping}};
|
|
||||||
--tp-font-family: {{$:/themes/tiddlywiki/vanilla/settings/fontfamily}};
|
|
||||||
--tp-code-font-family: {{$:/themes/tiddlywiki/vanilla/settings/codefontfamily}};
|
|
||||||
--tp-editor-font-family: {{$:/themes/tiddlywiki/vanilla/settings/editorfontfamily}};
|
|
||||||
--tp-font-size: {{$:/themes/tiddlywiki/vanilla/metrics/fontsize}};
|
|
||||||
--tp-line-height: {{$:/themes/tiddlywiki/vanilla/metrics/lineheight}};
|
|
||||||
--tp-body-font-size: {{$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize}};
|
|
||||||
--tp-body-line-height: {{$:/themes/tiddlywiki/vanilla/metrics/bodylineheight}};
|
|
||||||
--tp-story-left: {{$:/themes/tiddlywiki/vanilla/metrics/storyleft}};
|
|
||||||
--tp-story-top: {{$:/themes/tiddlywiki/vanilla/metrics/storytop}};
|
|
||||||
--tp-story-right: {{$:/themes/tiddlywiki/vanilla/metrics/storyright}};
|
|
||||||
--tp-story-width: {{$:/themes/tiddlywiki/vanilla/metrics/storyrwidth}};
|
|
||||||
--tp-tiddler-width: {{$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth}};
|
|
||||||
--tp-sidebar-breakpoint: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}};
|
|
||||||
--tp-sidebar-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth}};
|
|
||||||
|
|
||||||
--tp-animation-duration: {{{ [{$:/config/AnimationDuration}addsuffix[ms]] }}};
|
|
||||||
}
|
|
||||||
@@ -18,7 +18,6 @@ caption: {{$:/language/ControlPanel/Basics/Caption}}
|
|||||||
|<$link to="$:/config/NewTiddler/Tags"><<lingo NewTiddler/Tags/Prompt>></$link> |<$vars currentTiddler="$:/config/NewTiddler/Tags" tagField="text">{{||$:/core/ui/EditTemplate/tags}}<$list filter="[<currentTiddler>tags[]] +[limit[1]]" variable="ignore"><$button tooltip={{$:/language/ControlPanel/Basics/RemoveTags/Hint}}><<lingo RemoveTags>><$action-listops $tiddler=<<currentTiddler>> $field="text" $subfilter={{{ [<currentTiddler>get[tags]] }}}/><$action-setfield $tiddler=<<currentTiddler>> tags=""/></$button></$list></$vars> |
|
|<$link to="$:/config/NewTiddler/Tags"><<lingo NewTiddler/Tags/Prompt>></$link> |<$vars currentTiddler="$:/config/NewTiddler/Tags" tagField="text">{{||$:/core/ui/EditTemplate/tags}}<$list filter="[<currentTiddler>tags[]] +[limit[1]]" variable="ignore"><$button tooltip={{$:/language/ControlPanel/Basics/RemoveTags/Hint}}><<lingo RemoveTags>><$action-listops $tiddler=<<currentTiddler>> $field="text" $subfilter={{{ [<currentTiddler>get[tags]] }}}/><$action-setfield $tiddler=<<currentTiddler>> tags=""/></$button></$list></$vars> |
|
||||||
|<$link to="$:/config/NewJournal/Tags"><<lingo NewJournal/Tags/Prompt>></$link> |<$vars currentTiddler="$:/config/NewJournal/Tags" tagField="text">{{||$:/core/ui/EditTemplate/tags}}<$list filter="[<currentTiddler>tags[]] +[limit[1]]" variable="ignore"><$button tooltip={{$:/language/ControlPanel/Basics/RemoveTags/Hint}}><<lingo RemoveTags>><$action-listops $tiddler=<<currentTiddler>> $field="text" $subfilter={{{ [<currentTiddler>get[tags]] }}}/><$action-setfield $tiddler=<<currentTiddler>> tags=""/></$button></$list></$vars> |
|
|<$link to="$:/config/NewJournal/Tags"><<lingo NewJournal/Tags/Prompt>></$link> |<$vars currentTiddler="$:/config/NewJournal/Tags" tagField="text">{{||$:/core/ui/EditTemplate/tags}}<$list filter="[<currentTiddler>tags[]] +[limit[1]]" variable="ignore"><$button tooltip={{$:/language/ControlPanel/Basics/RemoveTags/Hint}}><<lingo RemoveTags>><$action-listops $tiddler=<<currentTiddler>> $field="text" $subfilter={{{ [<currentTiddler>get[tags]] }}}/><$action-setfield $tiddler=<<currentTiddler>> tags=""/></$button></$list></$vars> |
|
||||||
|<$link to="$:/config/AutoFocus"><<lingo AutoFocus/Prompt>></$link> |{{$:/snippets/minifocusswitcher}} |
|
|<$link to="$:/config/AutoFocus"><<lingo AutoFocus/Prompt>></$link> |{{$:/snippets/minifocusswitcher}} |
|
||||||
|<$link to="$:/config/AutoFocusEdit"><<lingo AutoFocusEdit/Prompt>></$link> |{{$:/snippets/minifocuseditswitcher}} |
|
|
||||||
|<<lingo Language/Prompt>> |{{$:/snippets/minilanguageswitcher}} |
|
|<<lingo Language/Prompt>> |{{$:/snippets/minilanguageswitcher}} |
|
||||||
|<<lingo Tiddlers/Prompt>> |<<show-filter-count "[!is[system]sort[title]]">> |
|
|<<lingo Tiddlers/Prompt>> |<<show-filter-count "[!is[system]sort[title]]">> |
|
||||||
|<<lingo Tags/Prompt>> |<<show-filter-count "[tags[]sort[title]]">> |
|
|<<lingo Tags/Prompt>> |<<show-filter-count "[tags[]sort[title]]">> |
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ title: $:/core/ui/EditTemplate/body/editor
|
|||||||
class="tc-edit-texteditor tc-edit-texteditor-body"
|
class="tc-edit-texteditor tc-edit-texteditor-body"
|
||||||
placeholder={{$:/language/EditTemplate/Body/Placeholder}}
|
placeholder={{$:/language/EditTemplate/Body/Placeholder}}
|
||||||
tabindex={{$:/config/EditTabIndex}}
|
tabindex={{$:/config/EditTabIndex}}
|
||||||
focus={{{ [{!!draft.of}is[tiddler]then{$:/config/AutoFocusEdit}match[text]then[true]] ~[{$:/config/AutoFocus}match[text]then[true]] ~[[false]] }}}
|
focus={{{ [{$:/config/AutoFocus}match[text]then[true]] ~[[false]] }}}
|
||||||
cancelPopups="yes"
|
cancelPopups="yes"
|
||||||
fileDrop={{{ [{$:/config/DragAndDrop/Enable}match[no]] :else[subfilter{$:/config/Editor/EnableImportFilter}then[yes]else[no]] }}}
|
fileDrop={{{ [{$:/config/DragAndDrop/Enable}match[no]] :else[subfilter{$:/config/Editor/EnableImportFilter}then[yes]else[no]] }}}
|
||||||
|
|
||||||
|
|||||||
@@ -103,9 +103,9 @@ title: $:/core/ui/EditTemplate/body/toolbar/button
|
|||||||
<$set
|
<$set
|
||||||
|
|
||||||
name="buttonClasses"
|
name="buttonClasses"
|
||||||
value={{{ [subfilter{!!button-classes}] :and[join[ ]] }}}
|
value={{!!button-classes}}
|
||||||
|
|
||||||
><<toolbar-button>></$set>
|
><<toolbar-button>></$set>
|
||||||
\end
|
\end
|
||||||
|
|
||||||
<<toolbar-button-outer>>
|
<<toolbar-button-outer>>
|
||||||
@@ -1,181 +1,157 @@
|
|||||||
title: $:/core/ui/EditTemplate/fields
|
title: $:/core/ui/EditTemplate/fields
|
||||||
tags: $:/tags/EditTemplate
|
tags: $:/tags/EditTemplate
|
||||||
|
|
||||||
\whitespace trim
|
|
||||||
|
|
||||||
\procedure lingo-base() $:/language/EditTemplate/
|
\procedure lingo-base() $:/language/EditTemplate/
|
||||||
|
\function tf.config-title() [[$:/config/EditTemplateFields/Visibility/]addsuffix[$(currentField)$]substitute[]get[text]]
|
||||||
|
|
||||||
|
\function tf.config-filter() [[hide]] :except[title<tf.config-title>]
|
||||||
|
|
||||||
|
<!-- Beware this is duplicated from EditTemplate.tid. For details see bug #7054 -->
|
||||||
|
\procedure get-field-value-tiddler-filter() [subfilter<get-field-editor-filter>sha256[16]addprefix[/]addprefix<newFieldValueTiddlerPrefix>]
|
||||||
|
\procedure get-field-editor-filter() [<newFieldNameTiddler>get[text]else[]] :cascade[all[shadows+tiddlers]tag[$:/tags/FieldEditorFilter]!is[draft]get[text]] :and[!is[blank]else{$:/core/ui/EditTemplate/fieldEditor/default}]
|
||||||
|
|
||||||
|
\procedure prefix.bracket() [
|
||||||
|
\procedure suffix.bracket() ]
|
||||||
|
|
||||||
|
\function tf.current-tiddler-new-field-selector() [[data-tiddler-title=]addprefix[$(prefix.bracket)$]substitute[]addsuffix<currentTiddlerCSSescaped>addsuffix[$(suffix.bracket)$]substitute[]] .tc-edit-field-add-name-wrapper input :and[join[ ]]
|
||||||
|
|
||||||
|
\procedure new-field-actions()
|
||||||
|
\whitespace trim
|
||||||
|
<$action-sendmessage $message="tm-add-field" $name={{{ [<newFieldNameTiddler>get[text]] }}} $value={{{ [<newFieldNameTiddler>get[text]] :map[subfilter<get-field-value-tiddler-filter>get[text]] }}}/>
|
||||||
|
<$set name="safeNewFieldValueTiddlerPrefix" value=<<newFieldValueTiddlerPrefix>> emptyValue=<<qualify "$:/temp/NewFieldValue">> >
|
||||||
|
<$action-deletetiddler $filter="[<newFieldNameTiddler>] [prefix[$:/temp/NewFieldValue]prefix<safeNewFieldValueTiddlerPrefix>] [<storeTitle>] [<searchListState>]"/>
|
||||||
|
</$set>
|
||||||
|
<$action-sendmessage $message="tm-focus-selector" $param=<<tf.current-tiddler-new-field-selector>>/>
|
||||||
|
\end
|
||||||
|
|
||||||
\procedure delete-state-tiddlers() <$action-deletetiddler $filter="[<newFieldNameTiddler>] [<storeTitle>] [<searchListState>]"/>
|
\procedure delete-state-tiddlers() <$action-deletetiddler $filter="[<newFieldNameTiddler>] [<storeTitle>] [<searchListState>]"/>
|
||||||
|
|
||||||
\procedure focus-new-field-input() <$action-sendmessage $message="tm-focus-selector" $param=`[data-tiddler-title="$(storyTiddler)$"] .tc-edit-field-add-name-wrapper input` />
|
\procedure cancel-search-actions-inner()
|
||||||
|
\whitespace trim
|
||||||
\procedure new-field-actions()
|
<$list
|
||||||
<$action-setfield $tiddler=<<storyTiddler>> $field={{{ [<newFieldNameTiddler>get[text]] }}} $value={{{ [<newFieldValueTiddler>get[text]] }}} />
|
filter="[<storeTitle>has[text]] [<newFieldNameTiddler>has[text]]"
|
||||||
<$action-deletetiddler $filter="[prefix[$:/temp/NewFieldValue]prefix<newFieldValueTiddlerPrefix>]"/>
|
variable="ignore"
|
||||||
<<delete-state-tiddlers>>
|
emptyMessage="<<cancel-delete-tiddler-actions 'cancel'>>">
|
||||||
<<focus-new-field-input>>
|
<<delete-state-tiddlers>>
|
||||||
\end
|
</$list>
|
||||||
|
|
||||||
\procedure delete-field-actions()
|
|
||||||
<$action-deletefield $field=<<currentField>>/>
|
|
||||||
<<focus-new-field-input>>
|
|
||||||
\end
|
\end
|
||||||
|
|
||||||
\procedure cancel-search-actions()
|
\procedure cancel-search-actions()
|
||||||
<$let userInput={{{ [<storeTitle>get[text]] }}}>
|
\whitespace trim
|
||||||
<%if [<newFieldNameTiddler>get[text]!match<userInput>] %>
|
<$set name="userInput" value={{{ [<storeTitle>get[text]] }}}>
|
||||||
<$action-setfield $tiddler=<<newFieldNameTiddler>> text=<<userInput>>/>
|
<$list
|
||||||
<$action-setfield $tiddler=<<refreshTitle>> text="yes"/>
|
filter="[<newFieldNameTiddler>get[text]!match<userInput>]"
|
||||||
<%else%>
|
emptyMessage="<<cancel-search-actions-inner>>">
|
||||||
<%if [<storeTitle>has[text]] [<newFieldNameTiddler>has[text]] %>
|
<$action-setfield $tiddler=<<newFieldNameTiddler>> text=<<userInput>>/><$action-setfield $tiddler=<<refreshTitle>> text="yes"/>
|
||||||
<<delete-state-tiddlers>>
|
</$list>
|
||||||
<%else%>
|
</$set>
|
||||||
<<cancel-delete-tiddler-actions 'cancel'>>
|
|
||||||
<%endif%>
|
|
||||||
<%endif%>
|
|
||||||
</$let>
|
|
||||||
\end
|
\end
|
||||||
|
|
||||||
\procedure new-field()
|
\procedure new-field()
|
||||||
<%if [<newFieldNameTiddler>get[text]!is[blank]] %>
|
\whitespace trim
|
||||||
<$button actions="<<new-field-actions>>" tooltip={{$:/language/EditTemplate/Fields/Add/Button/Hint}}>
|
<$vars name={{{ [<newFieldNameTiddler>get[text]] }}}>
|
||||||
<<lingo Fields/Add/Button>>
|
<$reveal type="nomatch" text="" default=<<name>>>
|
||||||
</$button>
|
<$button tooltip={{$:/language/EditTemplate/Fields/Add/Button/Hint}}>
|
||||||
<%else%>
|
<$action-sendmessage $message="tm-add-field"
|
||||||
<$button>
|
$name=<<name>>
|
||||||
<<lingo Fields/Add/Button>>
|
$value={{{ [subfilter<get-field-value-tiddler-filter>get[text]] }}}/>
|
||||||
</$button>
|
<$set name="safeNewFieldValueTiddlerPrefix" value=<<newFieldValueTiddlerPrefix>> emptyValue=<<qualify "$:/temp/NewFieldValue">> >
|
||||||
<%endif%>
|
<$action-deletetiddler $filter="[<newFieldNameTiddler>] [prefix[$:/temp/NewFieldValue]prefix<safeNewFieldValueTiddlerPrefix>] [<storeTitle>] [<searchListState>]"/>
|
||||||
|
</$set>
|
||||||
|
<<lingo Fields/Add/Button>>
|
||||||
|
</$button>
|
||||||
|
</$reveal>
|
||||||
|
<$reveal type="match" text="" default=<<name>>>
|
||||||
|
<$button>
|
||||||
|
<<lingo Fields/Add/Button>>
|
||||||
|
</$button>
|
||||||
|
</$reveal>
|
||||||
|
</$vars>
|
||||||
\end
|
\end
|
||||||
|
\whitespace trim
|
||||||
|
|
||||||
\function tf.config-filter() [lookup:show[$:/config/EditTemplateFields/Visibility/]!match[hide]]
|
<$set name="newFieldValueTiddlerPrefix" value=<<newFieldValueTiddlerPrefix>> emptyValue=<<qualify "$:/temp/NewFieldValue">> >
|
||||||
|
<div class="tc-edit-fields">
|
||||||
|
<table class={{{ [all[current]fields[]] :filter[lookup[$:/config/EditTemplateFields/Visibility/]!match[hide]] :and[count[]!match[0]] :and[then[tc-edit-fields]] :else[[tc-edit-fields tc-edit-fields-small]] }}}>
|
||||||
|
<tbody>
|
||||||
|
<$list filter="[all[current]fields[]] :and[sort[title]]" variable="currentField" storyview="pop">
|
||||||
|
<$list filter=<<tf.config-filter>> variable="temp">
|
||||||
|
<tr class="tc-edit-field">
|
||||||
|
<td class="tc-edit-field-name">
|
||||||
|
<$text text=<<currentField>>/>:</td>
|
||||||
|
<td class="tc-edit-field-value">
|
||||||
|
<$keyboard key="((delete-field))" actions="""<$action-deletefield $field=<<currentField>>/><$set name="currentTiddlerCSSescaped" value={{{ [<currentTiddler>escapecss[]] }}}><$action-sendmessage $message="tm-focus-selector" $param=<<tf.current-tiddler-new-field-selector>>/></$set>""">
|
||||||
|
<$transclude tiddler={{{ [<currentField>] :cascade[all[shadows+tiddlers]tag[$:/tags/FieldEditorFilter]!is[draft]get[text]] :and[!is[blank]else{$:/core/ui/EditTemplate/fieldEditor/default}] }}} />
|
||||||
|
</$keyboard>
|
||||||
|
</td>
|
||||||
|
<td class="tc-edit-field-remove">
|
||||||
|
<$button class="tc-btn-invisible" tooltip={{$:/language/EditTemplate/Field/Remove/Hint}} aria-label={{$:/language/EditTemplate/Field/Remove/Caption}}>
|
||||||
|
<$action-deletefield $field=<<currentField>>/>
|
||||||
|
{{$:/core/images/delete-button}}
|
||||||
|
</$button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</$list>
|
||||||
|
</$list>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
\function tf.field-cascade()
|
<$fieldmangler>
|
||||||
[<currentField>]
|
<div class="tc-edit-field-add">
|
||||||
:cascade[all[shadows+tiddlers]tag[$:/tags/FieldEditorFilter]!is[draft]get[text]]
|
<em class="tc-edit tc-small-gap-right">
|
||||||
:and[!is[blank]else{$:/core/ui/EditTemplate/fieldEditor/default}]
|
<<lingo Fields/Add/Prompt>>
|
||||||
\end
|
</em>
|
||||||
|
<$vars refreshTitle=<<qualify "$:/temp/fieldname/refresh">> storeTitle=<<newFieldNameInputTiddler>> searchListState=<<newFieldNameSelectionTiddler>>>
|
||||||
\function tf.get-field-editor()
|
<div class="tc-edit-field-add-name-wrapper">
|
||||||
[<newFieldNameTiddler>get[text]else[]]
|
<$transclude $variable="keyboard-driven-input" tiddler=<<newFieldNameTiddler>> storeTitle=<<storeTitle>> refreshTitle=<<refreshTitle>>
|
||||||
:cascade[all[shadows+tiddlers]tag[$:/tags/FieldEditorFilter]!is[draft]get[text]]
|
selectionStateTitle=<<searchListState>> tag="input" default="" placeholder={{$:/language/EditTemplate/Fields/Add/Name/Placeholder}}
|
||||||
:and[!is[blank]else{$:/core/ui/EditTemplate/fieldEditor/default}]
|
focusPopup=<<qualify "$:/state/popup/field-dropdown">> class="tc-edit-texteditor tc-popup-handle" tabindex={{$:/config/EditTabIndex}}
|
||||||
\end
|
focus={{{ [{$:/config/AutoFocus}match[fields]then[true]] :else[[false]] }}} cancelPopups="yes"
|
||||||
|
configTiddlerFilter="[[$:/config/EditMode/fieldname-filter]]" inputCancelActions=<<cancel-search-actions>> />
|
||||||
\function tf.primary-list-exceptions() created creator draft.of draft.title modified modifier tags text title type
|
<$button popup=<<qualify "$:/state/popup/field-dropdown">> class="tc-btn-invisible tc-btn-dropdown tc-small-gap" tooltip={{$:/language/EditTemplate/Field/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Field/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button>
|
||||||
|
<$reveal state=<<qualify "$:/state/popup/field-dropdown">> type="nomatch" text="" default="">
|
||||||
\function tf.list-selection-class(listSuffix) [<searchListState>get[text]removesuffix<listSuffix>match<currentField>then[tc-list-item-selected]]
|
<div class="tc-block-dropdown tc-edit-type-dropdown">
|
||||||
|
<$set name="tv-show-missing-links" value="yes">
|
||||||
|
<$linkcatcher to=<<newFieldNameTiddler>>>
|
||||||
<$let newFieldValueTiddlerPrefix={{{ [<newFieldValueTiddlerPrefix>!is[blank]else<qualify "$:/temp/NewFieldValue">] }}} >
|
<div class="tc-dropdown-item">
|
||||||
<div class="tc-edit-fields">
|
<<lingo Fields/Add/Dropdown/User>>
|
||||||
<!-- table of user fields of the current tiddler -->
|
</div>
|
||||||
<table class=`tc-edit-fields ${ [all[current]fields[]] :filter[tf.config-filter[]] :and[count[]match[0]then[tc-edit-fields-small]] }$`>
|
<$set name="newFieldName" value={{{ [<storeTitle>get[text]] }}}>
|
||||||
<tbody>
|
<$list filter="[!is[shadow]!is[system]fields[]search:title<newFieldName>sort[]] :except[[created]] :except[[creator]] :except[[draft.of]] :except[[draft.title]] :except[[modified]] :except[[modifier]] :except[[tags]] :except[[text]] :except[[title]] :except[[type]]" variable="currentField">
|
||||||
<$list filter="[all[current]fields[]] :and[sort[title]]" variable="currentField" storyview="pop">
|
<$list filter="[<currentField>addsuffix[-primaryList]] :except[<searchListState>get[text]]" emptyMessage="""<$link to=<<currentField>> class="tc-list-item-selected"><$text text=<<currentField>>/></$link>""">
|
||||||
<%if [<currentField>tf.config-filter[]] %>
|
<$link to=<<currentField>>>
|
||||||
<tr class="tc-edit-field">
|
<$text text=<<currentField>>/>
|
||||||
<td class="tc-edit-field-name">
|
</$link>
|
||||||
<$text text=<<currentField>>/>:
|
</$list>
|
||||||
</td>
|
</$list>
|
||||||
<td class="tc-edit-field-value">
|
<div class="tc-dropdown-item">
|
||||||
<$keyboard key="((delete-field))" actions="<<delete-field-actions>>">
|
<<lingo Fields/Add/Dropdown/System>>
|
||||||
<$transclude tiddler=<<tf.field-cascade>> />
|
</div>
|
||||||
</$keyboard>
|
<$list filter="[fields[]search:title<newFieldName>sort[]] :except[!is[shadow]!is[system]fields[]]" variable="currentField">
|
||||||
</td>
|
<$list filter="[<currentField>addsuffix[-secondaryList]] :except[<searchListState>get[text]]" emptyMessage="""<$link to=<<currentField>> class="tc-list-item-selected"><$text text=<<currentField>>/></$link>""">
|
||||||
<td class="tc-edit-field-remove">
|
<$link to=<<currentField>>>
|
||||||
<$button actions="<<delete-field-actions>>"
|
<$text text=<<currentField>>/>
|
||||||
aria-label={{$:/language/EditTemplate/Field/Remove/Caption}}
|
</$link>
|
||||||
class="tc-btn-invisible"
|
</$list>
|
||||||
tooltip={{$:/language/EditTemplate/Field/Remove/Hint}}
|
</$list>
|
||||||
>
|
</$set>
|
||||||
{{$:/core/images/delete-button}}
|
</$linkcatcher>
|
||||||
</$button>
|
</$set>
|
||||||
</td>
|
</div>
|
||||||
</tr>
|
</$reveal>
|
||||||
<%endif%>
|
</div>
|
||||||
</$list>
|
<$let currentTiddlerCSSescaped={{{ [<currentTiddler>escapecss[]] }}} currentTiddler={{{ [subfilter<get-field-value-tiddler-filter>] }}} currentField="text" currentFieldName={{{ [<newFieldNameTiddler>get[text]] }}}>
|
||||||
</tbody>
|
<span class="tc-edit-field-add-value tc-small-gap-right">
|
||||||
</table>
|
<$keyboard key="((add-field))" actions=<<new-field-actions>>>
|
||||||
</div>
|
<$transclude tiddler={{{ [subfilter<get-field-editor-filter>] }}} />
|
||||||
|
</$keyboard>
|
||||||
<!-- input control for new field name with selection dropdown -->
|
</span>
|
||||||
<div class="tc-edit-field-add">
|
<span class="tc-edit-field-add-button">
|
||||||
<em class="tc-edit tc-small-gap-right">
|
<$transclude $variable="new-field"/>
|
||||||
<<lingo Fields/Add/Prompt>>
|
</span>
|
||||||
</em>
|
</$let>
|
||||||
<$let refreshTitle=<<qualify "$:/temp/fieldname/refresh">>
|
</$vars>
|
||||||
storeTitle=<<newFieldNameInputTiddler>>
|
</div>
|
||||||
searchListState=<<newFieldNameSelectionTiddler>>
|
</$fieldmangler>
|
||||||
>
|
</$set>
|
||||||
<div class="tc-edit-field-add-name-wrapper">
|
|
||||||
<$transclude $variable="keyboard-driven-input"
|
|
||||||
cancelPopups="yes"
|
|
||||||
class=`tc-edit-texteditor tc-popup-handle ${ [<newFieldNameTiddler>get[text]] :intersection[<storyTiddler>fields[]] :then[[tc-edit-field-exists]] }$`
|
|
||||||
configTiddlerFilter="[[$:/config/EditMode/fieldname-filter]]"
|
|
||||||
default=""
|
|
||||||
focus={{{ [{!!draft.of}is[tiddler]then{$:/config/AutoFocusEdit}match[fields]then[true]] :else[{$:/config/AutoFocus}match[fields]then[true]] :else[[false]] }}}
|
|
||||||
focusPopup=<<qualify "$:/state/popup/field-dropdown">>
|
|
||||||
inputAcceptVariantActions=<<save-tiddler-actions>>
|
|
||||||
inputCancelActions=<<cancel-search-actions>>
|
|
||||||
placeholder={{$:/language/EditTemplate/Fields/Add/Name/Placeholder}}
|
|
||||||
refreshTitle=<<refreshTitle>>
|
|
||||||
selectionStateTitle=<<searchListState>>
|
|
||||||
storeTitle=<<storeTitle>>
|
|
||||||
tag="input"
|
|
||||||
tabindex={{$:/config/EditTabIndex}}
|
|
||||||
tiddler=<<newFieldNameTiddler>>
|
|
||||||
/>
|
|
||||||
<$button aria-label={{$:/language/EditTemplate/Field/Dropdown/Caption}}
|
|
||||||
class="tc-btn-invisible tc-btn-dropdown tc-small-gap"
|
|
||||||
popup=<<qualify "$:/state/popup/field-dropdown">>
|
|
||||||
tooltip={{$:/language/EditTemplate/Field/Dropdown/Hint}}
|
|
||||||
>
|
|
||||||
{{$:/core/images/down-arrow}}
|
|
||||||
</$button>
|
|
||||||
<$reveal state=<<qualify "$:/state/popup/field-dropdown">> type="nomatch" text="" default="" tag="div" class="tc-block-dropdown tc-edit-type-dropdown">
|
|
||||||
<$let tv-show-missing-links="yes">
|
|
||||||
<$linkcatcher to=<<newFieldNameTiddler>>>
|
|
||||||
<div class="tc-dropdown-item">
|
|
||||||
<<lingo Fields/Add/Dropdown/User>>
|
|
||||||
</div>
|
|
||||||
<$let newFieldName={{{ [<storeTitle>get[text]] }}}
|
|
||||||
primaryListFields={{{ [!is[shadow]!is[system]fields[]format:titlelist[]join[ ]] }}}
|
|
||||||
>
|
|
||||||
<$list filter="[enlist<primaryListFields>search:title<newFieldName>sort[]] :except[tf.primary-list-exceptions[]]" variable="currentField">
|
|
||||||
<$link to=<<currentField>> class=<<tf.list-selection-class "-primaryList">> >
|
|
||||||
<$text text=<<currentField>>/>
|
|
||||||
</$link>
|
|
||||||
</$list>
|
|
||||||
<div class="tc-dropdown-item">
|
|
||||||
<<lingo Fields/Add/Dropdown/System>>
|
|
||||||
</div>
|
|
||||||
<$list filter="[fields[]search:title<newFieldName>!enlist<primaryListFields>sort[]]" variable="currentField">
|
|
||||||
<$link to=<<currentField>> class=<<tf.list-selection-class "-secondaryList">>>
|
|
||||||
<$text text=<<currentField>>/>
|
|
||||||
</$link>
|
|
||||||
</$list>
|
|
||||||
</$let>
|
|
||||||
</$linkcatcher>
|
|
||||||
</$let>
|
|
||||||
</$reveal>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- input control for new field content -->
|
|
||||||
<$let currentFieldName={{{ [<newFieldNameTiddler>get[text]] }}}
|
|
||||||
fieldEditor=<<tf.get-field-editor>>
|
|
||||||
newFieldValueTiddler={{{ [<newFieldValueTiddlerPrefix>] [[/]] [<fieldEditor>sha256[16]] :and[join[]] }}}
|
|
||||||
currentTiddler=<<newFieldValueTiddler>>
|
|
||||||
>
|
|
||||||
<span class="tc-edit-field-add-value tc-small-gap-right">
|
|
||||||
<$keyboard key="((add-field))" actions="<<new-field-actions>>">
|
|
||||||
<$transclude $tiddler=<<fieldEditor>> />
|
|
||||||
</$keyboard>
|
|
||||||
</span>
|
|
||||||
<span class="tc-edit-field-add-button">
|
|
||||||
<$transclude $variable="new-field"/>
|
|
||||||
</span>
|
|
||||||
</$let>
|
|
||||||
</$let>
|
|
||||||
</div>
|
|
||||||
</$let>
|
|
||||||
@@ -17,7 +17,7 @@ tags: $:/tags/EditTemplate
|
|||||||
<$let backgroundColor=<<colour>> >
|
<$let backgroundColor=<<colour>> >
|
||||||
<span class="tc-tag-label tc-tag-list-item tc-small-gap-right"
|
<span class="tc-tag-label tc-tag-list-item tc-small-gap-right"
|
||||||
data-tag-title=<<currentTiddler>>
|
data-tag-title=<<currentTiddler>>
|
||||||
style=`color:$(foregroundColor)$; background-color:$(backgroundColor)$; --tp-remove-tag-button-color:$(foregroundColor)$`
|
style=`color:$(foregroundColor)$; background-color:$(backgroundColor)$;`
|
||||||
>
|
>
|
||||||
<$transclude tiddler=<<icon>>/>
|
<$transclude tiddler=<<icon>>/>
|
||||||
<$view field="title" format="text"/>
|
<$view field="title" format="text"/>
|
||||||
|
|||||||
@@ -2,11 +2,7 @@ title: $:/core/ui/EditTemplate/title
|
|||||||
tags: $:/tags/EditTemplate
|
tags: $:/tags/EditTemplate
|
||||||
|
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<$edit-text field="draft.title" class="tc-titlebar tc-edit-texteditor"
|
<$edit-text field="draft.title" class="tc-titlebar tc-edit-texteditor" focus={{{ [{$:/config/AutoFocus}match[title]then[true]] ~[[false]] }}} tabindex={{$:/config/EditTabIndex}} cancelPopups="yes"/>
|
||||||
focus={{{ [{!!draft.of}is[tiddler]then{$:/config/AutoFocusEdit}match[title]then[true]] ~[{$:/config/AutoFocus}match[title]then[true]] ~[[false]] }}}
|
|
||||||
tabindex={{$:/config/EditTabIndex}}
|
|
||||||
cancelPopups="yes"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<$vars pattern="""[\|\[\]{}]""" bad-chars="""`| [ ] { }`""">
|
<$vars pattern="""[\|\[\]{}]""" bad-chars="""`| [ ] { }`""">
|
||||||
|
|
||||||
|
|||||||
@@ -4,28 +4,13 @@ first-search-filter: [all[shadows+tiddlers]prefix[$:/language/Docs/Types/]sort[d
|
|||||||
|
|
||||||
\procedure lingo-base() $:/language/EditTemplate/
|
\procedure lingo-base() $:/language/EditTemplate/
|
||||||
\procedure input-cancel-actions() <$list filter="[<storeTitle>get[text]] [<currentTiddler>get[type]] :and[limit[1]]" emptyMessage="""<<cancel-delete-tiddler-actions "cancel">>"""><$action-sendmessage $message="tm-remove-field" $param="type"/><$action-deletetiddler $filter="[<typeInputTiddler>] [<refreshTitle>] [<typeSelectionTiddler>]"/></$list>
|
\procedure input-cancel-actions() <$list filter="[<storeTitle>get[text]] [<currentTiddler>get[type]] :and[limit[1]]" emptyMessage="""<<cancel-delete-tiddler-actions "cancel">>"""><$action-sendmessage $message="tm-remove-field" $param="type"/><$action-deletetiddler $filter="[<typeInputTiddler>] [<refreshTitle>] [<typeSelectionTiddler>]"/></$list>
|
||||||
|
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<$set name="refreshTitle" value=<<qualify "$:/temp/type-search/refresh">>>
|
<$set name="refreshTitle" value=<<qualify "$:/temp/type-search/refresh">>>
|
||||||
<div class="tc-edit-type-selector-wrapper">
|
<div class="tc-edit-type-selector-wrapper">
|
||||||
<em class="tc-edit tc-small-gap-right"><<lingo Type/Prompt>></em>
|
<em class="tc-edit tc-small-gap-right"><<lingo Type/Prompt>></em>
|
||||||
<div class="tc-type-selector-dropdown-wrapper">
|
<div class="tc-type-selector-dropdown-wrapper">
|
||||||
<div class="tc-type-selector">
|
<div class="tc-type-selector"><$fieldmangler>
|
||||||
<$fieldmangler>
|
<$transclude $variable="keyboard-driven-input" tiddler=<<currentTiddler>> storeTitle=<<typeInputTiddler>> refreshTitle=<<refreshTitle>> selectionStateTitle=<<typeSelectionTiddler>> field="type" tag="input" default="" placeholder={{$:/language/EditTemplate/Type/Placeholder}} focusPopup=<<qualify "$:/state/popup/type-dropdown">> class="tc-edit-typeeditor tc-edit-texteditor tc-popup-handle tc-keep-focus" tabindex={{$:/config/EditTabIndex}} focus={{{ [{$:/config/AutoFocus}match[type]then[true]] :else[[false]] }}} cancelPopups="yes" configTiddlerFilter="[[$:/core/ui/EditTemplate/type]]" inputCancelActions=<<input-cancel-actions>>/><$button popup=<<qualify "$:/state/popup/type-dropdown">> class="tc-btn-invisible tc-btn-dropdown tc-small-gap" tooltip={{$:/language/EditTemplate/Type/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Type/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button><$button message="tm-remove-field" param="type" class="tc-btn-invisible tc-btn-icon" tooltip={{$:/language/EditTemplate/Type/Delete/Hint}} aria-label={{$:/language/EditTemplate/Type/Delete/Caption}}>{{$:/core/images/delete-button}}<$action-deletetiddler $filter="[<typeInputTiddler>] [<storeTitle>] [<refreshTitle>] [<selectionStateTitle>]"/></$button>
|
||||||
<$transclude $variable="keyboard-driven-input" tiddler=<<currentTiddler>> storeTitle=<<typeInputTiddler>> refreshTitle=<<refreshTitle>>
|
|
||||||
selectionStateTitle=<<typeSelectionTiddler>> field="type" tag="input" default="" placeholder={{$:/language/EditTemplate/Type/Placeholder}}
|
|
||||||
focusPopup=<<qualify "$:/state/popup/type-dropdown">> class="tc-edit-typeeditor tc-edit-texteditor tc-popup-handle tc-keep-focus"
|
|
||||||
tabindex={{$:/config/EditTabIndex}}
|
|
||||||
focus={{{ [{!!draft.of}is[tiddler]then{$:/config/AutoFocusEdit}match[type]then[true]] :else[{$:/config/AutoFocus}match[type]then[true]] :else[[false]] }}}
|
|
||||||
cancelPopups="yes" configTiddlerFilter="[[$:/core/ui/EditTemplate/type]]"
|
|
||||||
inputCancelActions=<<input-cancel-actions>>
|
|
||||||
/>
|
|
||||||
<$button popup=<<qualify "$:/state/popup/type-dropdown">> class="tc-btn-invisible tc-btn-dropdown tc-small-gap" tooltip={{$:/language/EditTemplate/Type/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Type/Dropdown/Caption}}>
|
|
||||||
{{$:/core/images/down-arrow}}
|
|
||||||
</$button>
|
|
||||||
<$button message="tm-remove-field" param="type" class="tc-btn-invisible tc-btn-icon" tooltip={{$:/language/EditTemplate/Type/Delete/Hint}} aria-label={{$:/language/EditTemplate/Type/Delete/Caption}}>
|
|
||||||
{{$:/core/images/delete-button}}<$action-deletetiddler $filter="[<typeInputTiddler>] [<storeTitle>] [<refreshTitle>] [<selectionStateTitle>]"/>
|
|
||||||
</$button>
|
|
||||||
</$fieldmangler></div>
|
</$fieldmangler></div>
|
||||||
|
|
||||||
<div class="tc-block-dropdown-wrapper">
|
<div class="tc-block-dropdown-wrapper">
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
title: $:/core/Filters/StoryList
|
title: $:/core/Filters/StoryList
|
||||||
tags: $:/tags/Filter
|
tags: $:/tags/Filter
|
||||||
filter: [<tv-story-list>is[variable]then<tv-story-list>else[$:/StoryList]] =>storylist [list<storylist>] -$:/AdvancedSearch
|
filter: [list[$:/StoryList]] -$:/AdvancedSearch
|
||||||
description: {{$:/language/Filters/StoryList}}
|
description: {{$:/language/Filters/StoryList}}
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ code-body: yes
|
|||||||
|
|
||||||
<$set name="languageTitle" value={{!!name}}>
|
<$set name="languageTitle" value={{!!name}}>
|
||||||
|
|
||||||
<$transclude $tiddler="$:/core/stylesheets/custom-properties" $mode="block"/>
|
|
||||||
|
|
||||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Stylesheet]!has[draft.of]]">
|
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Stylesheet]!has[draft.of]]">
|
||||||
<$transclude mode="block"/>
|
<$transclude mode="block"/>
|
||||||
</$list>
|
</$list>
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
title: $:/core/ui/TiddlerInfo/Advanced/CascadeInfo
|
|
||||||
tags: $:/tags/TiddlerInfo/Advanced
|
|
||||||
|
|
||||||
\define lingo-base() $:/language/TiddlerInfo/Advanced/CascadeInfo/
|
|
||||||
|
|
||||||
<$let infoTiddler=<<currentTiddler>>>
|
|
||||||
|
|
||||||
''<<lingo Heading>>''
|
|
||||||
|
|
||||||
<<lingo Hint>>
|
|
||||||
|
|
||||||
<table class="tc-max-width">
|
|
||||||
<thead>
|
|
||||||
<$list filter="[[View]] [[ActiveCascadeFilter]] [[Template]]" variable="th">
|
|
||||||
<th><$transclude $variable="lingo" title=`Detail/$(th)$`/></th>
|
|
||||||
</$list>
|
|
||||||
</thead>
|
|
||||||
<$list filter="[[$:/tags/ViewTemplate]tagging[]]" variable="ViewTemplate">
|
|
||||||
<tr>
|
|
||||||
<$let
|
|
||||||
view={{{ [<ViewTemplate>]+[split[/]last[]] }}}
|
|
||||||
tagFilter=`$:/tags/ViewTemplate${ [<view>titlecase[]] }$Filter`
|
|
||||||
activeCascadeFilterTiddler={{{ [all[shadows+tiddlers]tag<tagFilter>!is[draft]]:filter[<storyTiddler>subfilter{!!text}]+[first[]] }}}
|
|
||||||
activeCascadeFilter={{{ [<activeCascadeFilterTiddler>get[text]] }}}
|
|
||||||
activeTemplateTiddler={{{ [<currentTiddler>]:cascade[all[shadows+tiddlers]tag<tagFilter>!is[draft]get[text]] }}}
|
|
||||||
>
|
|
||||||
<%if [<activeCascadeFilterTiddler>!is[blank]]%>
|
|
||||||
<td>
|
|
||||||
<$link to=<<ViewTemplate>> ><<view>></$link>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<$link to=<<activeCascadeFilterTiddler>> />
|
|
||||||
</td>
|
|
||||||
<td style="text-align:center;">
|
|
||||||
<$link class="tc-btn-invisible" to=<<activeTemplateTiddler>>>
|
|
||||||
<$button class="tc-btn-invisible">{{$:/core/images/file}}</$button>
|
|
||||||
</$link>
|
|
||||||
</td>
|
|
||||||
<%endif%>
|
|
||||||
</$let>
|
|
||||||
</tr>
|
|
||||||
</$list>
|
|
||||||
</table>
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
title: $:/core/wiki/config/MediaQueryTrackers/DarkLightPreferred
|
|
||||||
tags: $:/tags/MediaQueryTracker
|
|
||||||
media-query: (prefers-color-scheme: dark)
|
|
||||||
info-tiddler: $:/info/browser/darkmode
|
|
||||||
info-tiddler-alt: $:/info/darkmode
|
|
||||||
@@ -122,15 +122,15 @@ tags: $:/tags/Macro
|
|||||||
\whitespace trim
|
\whitespace trim
|
||||||
\procedure keyboard-driven-input-actions()
|
\procedure keyboard-driven-input-actions()
|
||||||
<%if [<event-key-descriptor>match[((input-accept))]] %>
|
<%if [<event-key-descriptor>match[((input-accept))]] %>
|
||||||
<$transclude $variable=inputAcceptActions $fillignore=yes />
|
<<inputAcceptActions>>
|
||||||
<%elseif [<event-key-descriptor>match[((input-accept-variant))]] %>
|
<%elseif [<event-key-descriptor>match[((input-accept-variant))]] %>
|
||||||
<$transclude $variable=inputAcceptVariantActions $fillignore=yes />
|
<<inputAcceptVariantActions>>
|
||||||
<%elseif [<event-key-descriptor>match[((input-up))]] %>
|
<%elseif [<event-key-descriptor>match[((input-up))]] %>
|
||||||
<$transclude $variable=input-next-actions-before $fillignore=yes />
|
<<input-next-actions-before>>
|
||||||
<%elseif [<event-key-descriptor>match[((input-down))]] %>
|
<%elseif [<event-key-descriptor>match[((input-down))]] %>
|
||||||
<$transclude $variable=input-next-actions-after $fillignore=yes />
|
<<input-next-actions-after>>
|
||||||
<%elseif [<event-key-descriptor>match[((input-cancel))]] %>
|
<%elseif [<event-key-descriptor>match[((input-cancel))]] %>
|
||||||
<$transclude $variable=inputCancelActions $fillignore=yes />
|
<<inputCancelActions>>
|
||||||
<%endif%>
|
<%endif%>
|
||||||
\end keyboard-driven-input-actions
|
\end keyboard-driven-input-actions
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ tags: $:/tags/Macro
|
|||||||
<$action-listops $tiddler=<<targetTiddler>> $field=<<targetField>> $subfilter="+[insertbefore<actionTiddler>,<currentTiddler>]"/>
|
<$action-listops $tiddler=<<targetTiddler>> $field=<<targetField>> $subfilter="+[insertbefore<actionTiddler>,<currentTiddler>]"/>
|
||||||
\end
|
\end
|
||||||
|
|
||||||
\define list-links-draggable(tiddler,field:"list",emptyMessage,type:"ul",subtype:"li",class:"",itemTemplate,displayField:"caption",startactions,endactions)
|
\define list-links-draggable(tiddler,field:"list",emptyMessage,type:"ul",subtype:"li",class:"",itemTemplate, displayField:"caption")
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<$set name="_tiddler" value="""$tiddler$""" emptyValue=<<currentTiddler>> >
|
<$set name="_tiddler" value="""$tiddler$""" emptyValue=<<currentTiddler>> >
|
||||||
<$let field-reference={{{ [<_tiddler>] "!!" [[$field$]] +[join[]] }}}
|
<$let field-reference={{{ [<_tiddler>] "!!" [[$field$]] +[join[]] }}}
|
||||||
@@ -39,11 +39,8 @@ tags: $:/tags/Macro
|
|||||||
>
|
>
|
||||||
<div class="tc-droppable-placeholder"/>
|
<div class="tc-droppable-placeholder"/>
|
||||||
<div>
|
<div>
|
||||||
<$transclude tiddler=<<__itemTemplate__>>>
|
<$transclude tiddler="""$itemTemplate$""">
|
||||||
<$link to={{!!title}}
|
<$link to={{!!title}}>
|
||||||
startactions=<<__startactions__>>
|
|
||||||
endactions=<<__endactions__>>
|
|
||||||
>
|
|
||||||
<$let tv-wikilinks="no">
|
<$let tv-wikilinks="no">
|
||||||
<$transclude field=<<__displayField__>>>
|
<$transclude field=<<__displayField__>>>
|
||||||
<$view field="title"/>
|
<$view field="title"/>
|
||||||
@@ -95,7 +92,7 @@ tags: $:/tags/Macro
|
|||||||
</$set>
|
</$set>
|
||||||
\end
|
\end
|
||||||
|
|
||||||
\define list-tagged-draggable(tag,subFilter,emptyMessage,itemTemplate,elementTag:"div",storyview:"",displayField:"title",startactions,endactions)
|
\define list-tagged-draggable(tag,subFilter,emptyMessage,itemTemplate,elementTag:"div",storyview:"",displayField:"title")
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<span class="tc-tagged-draggable-list">
|
<span class="tc-tagged-draggable-list">
|
||||||
<$set name="tag" value=<<__tag__>>>
|
<$set name="tag" value=<<__tag__>>>
|
||||||
@@ -111,11 +108,8 @@ tags: $:/tags/Macro
|
|||||||
>
|
>
|
||||||
<$genesis $type=<<__elementTag__>> class="tc-droppable-placeholder"/>
|
<$genesis $type=<<__elementTag__>> class="tc-droppable-placeholder"/>
|
||||||
<$genesis $type=<<__elementTag__>>>
|
<$genesis $type=<<__elementTag__>>>
|
||||||
<$transclude tiddler=<<__itemTemplate__>>>
|
<$transclude tiddler="""$itemTemplate$""">
|
||||||
<$link to={{!!title}}
|
<$link to={{!!title}}>
|
||||||
startactions=<<__startactions__>>
|
|
||||||
endactions=<<__endactions__>>
|
|
||||||
>
|
|
||||||
<$let tv-wikilinks="no">
|
<$let tv-wikilinks="no">
|
||||||
<$transclude field=<<__displayField__>>>
|
<$transclude field=<<__displayField__>>>
|
||||||
<$view field="title"/>
|
<$view field="title"/>
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ The second ESC tries to close the "draft tiddler"
|
|||||||
focusPopup=<<tf.tagpicker-dropdown-id>>
|
focusPopup=<<tf.tagpicker-dropdown-id>>
|
||||||
class="tc-edit-texteditor tc-popup-handle"
|
class="tc-edit-texteditor tc-popup-handle"
|
||||||
tabindex=<<tabIndex>>
|
tabindex=<<tabIndex>>
|
||||||
focus={{{ [{!!draft.of}is[tiddler]then{$:/config/AutoFocusEdit}match[tags]then[true]] :else[{$:/config/AutoFocus}match[tags]then[true]] :else[[false]] }}}
|
focus={{{ [{$:/config/AutoFocus}match[tags]then[true]] :else[[false]] }}}
|
||||||
filterMinLength={{$:/config/Tags/MinLength}}
|
filterMinLength={{$:/config/Tags/MinLength}}
|
||||||
cancelPopups=<<cancelPopups>>
|
cancelPopups=<<cancelPopups>>
|
||||||
configTiddlerFilter="[[$:/core/macros/tag-picker]]"
|
configTiddlerFilter="[[$:/core/macros/tag-picker]]"
|
||||||
|
|||||||
@@ -15,18 +15,7 @@ tags: $:/tags/Macro
|
|||||||
</span>
|
</span>
|
||||||
\end
|
\end
|
||||||
|
|
||||||
\define toc-level-indicator()
|
\define toc-body(tag,sort:"",itemClassFilter,exclude,path)
|
||||||
\whitespace trim
|
|
||||||
<%if [<__level__>compare:number:gt[0]]%>
|
|
||||||
<%if [<currentTiddler>tagging[]] %>
|
|
||||||
<span class="tc-tiny-gap-left">{{$:/core/images/new-button}}</span>
|
|
||||||
<%else%>
|
|
||||||
<span class="tc-tiny-gap-left">{{$:/core/images/blank}}</span>
|
|
||||||
<%endif%>
|
|
||||||
<% endif %>
|
|
||||||
\end
|
|
||||||
|
|
||||||
\define toc-body(tag,sort:"",itemClassFilter,exclude,path,level)
|
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<ol class="tc-toc">
|
<ol class="tc-toc">
|
||||||
<$list filter="""[all[shadows+tiddlers]tag<__tag__>!has[draft.of]$sort$] -[<__tag__>] -[subfilter<__exclude__>]""">
|
<$list filter="""[all[shadows+tiddlers]tag<__tag__>!has[draft.of]$sort$] -[<__tag__>] -[subfilter<__exclude__>]""">
|
||||||
@@ -34,26 +23,10 @@ tags: $:/tags/Macro
|
|||||||
<$set name="excluded" filter="[subfilter<__exclude__>] [<__tag__>]">
|
<$set name="excluded" filter="[subfilter<__exclude__>] [<__tag__>]">
|
||||||
<$set name="toc-item-class" filter=<<__itemClassFilter__>> emptyValue="toc-item-selected" value="toc-item">
|
<$set name="toc-item-class" filter=<<__itemClassFilter__>> emptyValue="toc-item-selected" value="toc-item">
|
||||||
<li class=<<toc-item-class>>>
|
<li class=<<toc-item-class>>>
|
||||||
<$list filter="[all[current]toc-link[no]]" >
|
<$list filter="[all[current]toc-link[no]]" emptyMessage="<$link to={{{ [<currentTiddler>get[target]else<currentTiddler>] }}}><<toc-caption>></$link>">
|
||||||
<$list-empty>
|
|
||||||
<!-- link to target-field or currentTiddler -->
|
|
||||||
<$link to={{{ [<currentTiddler>get[target]else<currentTiddler>] }}}>
|
|
||||||
<<toc-level-indicator>>
|
|
||||||
<<toc-caption>>
|
|
||||||
</$link>
|
|
||||||
</$list-empty>
|
|
||||||
<!-- toc-link = no -->
|
|
||||||
<<toc-level-indicator>>
|
|
||||||
<<toc-caption>>
|
<<toc-caption>>
|
||||||
</$list>
|
</$list>
|
||||||
<$let _level={{{ [<__level__>subtract[1]] }}}>
|
<$macrocall $name="toc-body" tag=<<item>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<excluded>> path=<<path>>/>
|
||||||
<%if [<_level>compare:number:gt[0]]%>
|
|
||||||
<$macrocall $name="toc-body" tag=<<item>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<excluded>> path=<<path>> level=<<_level>>/>
|
|
||||||
<%elseif [<_level>match[-1]]%>
|
|
||||||
<!-- show full toc, no level defined -->
|
|
||||||
<$macrocall $name="toc-body" tag=<<item>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<excluded>> path=<<path>>/>
|
|
||||||
<%endif%>
|
|
||||||
</$let>
|
|
||||||
</li>
|
</li>
|
||||||
</$set>
|
</$set>
|
||||||
</$set>
|
</$set>
|
||||||
@@ -62,10 +35,10 @@ tags: $:/tags/Macro
|
|||||||
</ol>
|
</ol>
|
||||||
\end
|
\end
|
||||||
|
|
||||||
\define toc(tag,sort:"",itemClassFilter:"",exclude,level)
|
\define toc(tag,sort:"",itemClassFilter:"", exclude)
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<$let __tag__={{{ [<__tag__>is[blank]then<currentTiddler>else<__tag__>] }}} >
|
<$let __tag__={{{ [<__tag__>is[blank]then<currentTiddler>else<__tag__>] }}} >
|
||||||
<$macrocall $name="toc-body" tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<__exclude__>> level=<<__level__>>/>
|
<$macrocall $name="toc-body" tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<__exclude__>>/>
|
||||||
</$let>
|
</$let>
|
||||||
\end
|
\end
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
title: $:/snippets/minifocuseditswitcher
|
|
||||||
|
|
||||||
\whitespace trim
|
|
||||||
<$select tiddler="$:/config/AutoFocusEdit" default={{$:/config/AutoFocus}}>
|
|
||||||
<$list filter="title tags text">
|
|
||||||
<option><<currentTiddler>></option>
|
|
||||||
</$list>
|
|
||||||
</$select>
|
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
title: $:/tags/TiddlerInfo/Advanced
|
title: $:/tags/TiddlerInfo/Advanced
|
||||||
list: [[$:/core/ui/TiddlerInfo/Advanced/ShadowInfo]] [[$:/core/ui/TiddlerInfo/Advanced/PluginInfo]] [[$:/core/ui/TiddlerInfo/Advanced/CascadeInfo]]
|
list: [[$:/core/ui/TiddlerInfo/Advanced/ShadowInfo]] [[$:/core/ui/TiddlerInfo/Advanced/PluginInfo]]
|
||||||
@@ -20,7 +20,8 @@
|
|||||||
"index": [
|
"index": [
|
||||||
"--rendertiddler","$:/core/save/all","index.html","text/plain"],
|
"--rendertiddler","$:/core/save/all","index.html","text/plain"],
|
||||||
"empty": [
|
"empty": [
|
||||||
"--rendertiddler","$:/editions/de-AT-DE/download-empty","empty.html","text/plain"],
|
"--rendertiddler","$:/editions/de-AT-DE/download-empty","empty.html","text/plain",
|
||||||
|
"--rendertiddler","$:/editions/de-AT-DE/download-empty","empty.hta","text/plain"],
|
||||||
"favicon": [
|
"favicon": [
|
||||||
"--savetiddler","$:/favicon.ico","favicon.ico"],
|
"--savetiddler","$:/favicon.ico","favicon.ico"],
|
||||||
"static": [
|
"static": [
|
||||||
|
|||||||
@@ -24,7 +24,8 @@
|
|||||||
"index": [
|
"index": [
|
||||||
"--rendertiddler","$:/core/save/all","index.html","text/plain"],
|
"--rendertiddler","$:/core/save/all","index.html","text/plain"],
|
||||||
"empty": [
|
"empty": [
|
||||||
"--rendertiddler","$:/editions/de-AT-DE/download-empty","empty.html","text/plain"],
|
"--rendertiddler","$:/editions/de-AT-DE/download-empty","empty.html","text/plain",
|
||||||
|
"--rendertiddler","$:/editions/de-AT-DE/download-empty","empty.hta","text/plain"],
|
||||||
"favicon": [
|
"favicon": [
|
||||||
"--savetiddler","$:/favicon.ico","favicon.ico"],
|
"--savetiddler","$:/favicon.ico","favicon.ico"],
|
||||||
"static": [
|
"static": [
|
||||||
|
|||||||
@@ -10,7 +10,8 @@
|
|||||||
"index": [
|
"index": [
|
||||||
"--render","$:/core/save/all","index.html","text/plain"],
|
"--render","$:/core/save/all","index.html","text/plain"],
|
||||||
"empty": [
|
"empty": [
|
||||||
"--render","$:/core/save/all","empty.html","text/plain"],
|
"--render","$:/core/save/all","empty.html","text/plain",
|
||||||
|
"--render","$:/core/save/all","empty.hta","text/plain"],
|
||||||
"emptyexternalcore": [
|
"emptyexternalcore": [
|
||||||
"--render","$:/core/save/offline-external-js","empty-external-core.html","text/plain",
|
"--render","$:/core/save/offline-external-js","empty-external-core.html","text/plain",
|
||||||
"--render","$:/core/templates/tiddlywiki5.js","[[tiddlywikicore-]addsuffix<version>addsuffix[.js]]","text/plain"],
|
"--render","$:/core/templates/tiddlywiki5.js","[[tiddlywikicore-]addsuffix<version>addsuffix[.js]]","text/plain"],
|
||||||
|
|||||||
@@ -27,7 +27,8 @@
|
|||||||
"--setfield","[tag[external-image]] [tag[external-text]]","text","","text/plain",
|
"--setfield","[tag[external-image]] [tag[external-text]]","text","","text/plain",
|
||||||
"--rendertiddler","$:/core/save/all","index.html","text/plain"],
|
"--rendertiddler","$:/core/save/all","index.html","text/plain"],
|
||||||
"empty": [
|
"empty": [
|
||||||
"--rendertiddler","$:/editions/es-ES/download-empty","empty.html","text/plain"],
|
"--rendertiddler","$:/editions/es-ES/download-empty","empty.html","text/plain",
|
||||||
|
"--rendertiddler","$:/editions/es-ES/download-empty","empty.hta","text/plain"],
|
||||||
"favicon": [
|
"favicon": [
|
||||||
"--savetiddler","$:/favicon.ico","favicon.ico",
|
"--savetiddler","$:/favicon.ico","favicon.ico",
|
||||||
"--savetiddler","$:/green_favicon.ico","static/favicon.ico"],
|
"--savetiddler","$:/green_favicon.ico","static/favicon.ico"],
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
created: 20150220191009000
|
created: 20150220191009000
|
||||||
modified: 20150602092431500
|
modified: 20150602092431500
|
||||||
title: $:/editions/tw5.com/railroad/call-parameter-value
|
title: $:/editions/tw5.com/railroad/macro-parameter-value
|
||||||
type: text/vnd.tiddlywiki.railroad
|
type: text/vnd.tiddlywiki.railroad
|
||||||
|
|
||||||
( '"""' [:{/'tout sauf """'/}] '"""'
|
( '"""' [:{/'tout sauf """'/}] '"""'
|
||||||
| '"' [:{/'tout sauf "'/}] '"'
|
| '"' [:{/'tout sauf "'/}] '"'
|
||||||
| "'" [:{/"tout sauf '"/}] "'"
|
| "'" [:{/"tout sauf '"/}] "'"
|
||||||
| "[[" [:{/"tout sauf ]"/}] "]]"
|
| "[[" [:{/"tout sauf ]"/}] "]]"
|
||||||
| "`" [:{/"tout sauf `"/}] "`"
|
|
||||||
| "```" [:{/"tout sauf ```"/}] "```"
|
|
||||||
| {/"""tout sauf ' " ou espacevierge"""/}
|
| {/"""tout sauf ' " ou espacevierge"""/}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -25,4 +25,4 @@ The <<.place param-nom>> is a sequence of letters (`A`--`Z`, `a`--`z`), digits (
|
|||||||
|
|
||||||
The <<.place valeur>> is specified as follows<<dp>>
|
The <<.place valeur>> is specified as follows<<dp>>
|
||||||
|
|
||||||
<$railroad text={{$:/editions/tw5.com/railroad/call-parameter-value}}/>
|
<$railroad text={{$:/editions/tw5.com/railroad/macro-parameter-value}}/>
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ parametre.nom [: [:espace] ":" [:espace] defaut ]
|
|||||||
|
|
||||||
La valeur par <<.place défaut>> d'un paramètre est spécifiée comme suit<<:>>
|
La valeur par <<.place défaut>> d'un paramètre est spécifiée comme suit<<:>>
|
||||||
|
|
||||||
<$railroad text={{$:/editions/tw5.com/railroad/call-parameter-value}}/>
|
<$railroad text={{$:/editions/tw5.com/railroad/macro-parameter-value}}/>
|
||||||
|
|
||||||
La définition de la <<.place suite>> se fait comme suit<<:>>
|
La définition de la <<.place suite>> se fait comme suit<<:>>
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,8 @@
|
|||||||
"--setfield","[tag[external-image]] [tag[external-text]]","text","","text/plain",
|
"--setfield","[tag[external-image]] [tag[external-text]]","text","","text/plain",
|
||||||
"--rendertiddler","$:/core/save/all","index.html","text/plain"],
|
"--rendertiddler","$:/core/save/all","index.html","text/plain"],
|
||||||
"empty": [
|
"empty": [
|
||||||
"--rendertiddler","$:/editions/fr-FR/download-empty","empty.html","text/plain"],
|
"--rendertiddler","$:/editions/fr-FR/download-empty","empty.html","text/plain",
|
||||||
|
"--rendertiddler","$:/editions/fr-FR/download-empty","empty.hta","text/plain"],
|
||||||
"favicon": [
|
"favicon": [
|
||||||
"--savetiddler","$:/favicon.ico","favicon.ico",
|
"--savetiddler","$:/favicon.ico","favicon.ico",
|
||||||
"--savetiddler","$:/green_favicon.ico","static/favicon.ico"],
|
"--savetiddler","$:/green_favicon.ico","static/favicon.ico"],
|
||||||
|
|||||||
@@ -27,7 +27,8 @@
|
|||||||
"--setfield","[tag[external-image]] [tag[external-text]]","text","","text/plain",
|
"--setfield","[tag[external-image]] [tag[external-text]]","text","","text/plain",
|
||||||
"--rendertiddler","$:/core/save/all","index.html","text/plain"],
|
"--rendertiddler","$:/core/save/all","index.html","text/plain"],
|
||||||
"empty": [
|
"empty": [
|
||||||
"--rendertiddler","$:/editions/ja-JP/download-empty","empty.html","text/plain"],
|
"--rendertiddler","$:/editions/ja-JP/download-empty","empty.html","text/plain",
|
||||||
|
"--rendertiddler","$:/editions/ja-JP/download-empty","empty.hta","text/plain"],
|
||||||
"favicon": [
|
"favicon": [
|
||||||
"--savetiddler","$:/favicon.ico","favicon.ico",
|
"--savetiddler","$:/favicon.ico","favicon.ico",
|
||||||
"--savetiddler","$:/green_favicon.ico","static/favicon.ico"],
|
"--savetiddler","$:/green_favicon.ico","static/favicon.ico"],
|
||||||
|
|||||||
@@ -27,7 +27,8 @@
|
|||||||
"--setfield","[tag[external-image]] [tag[external-text]]","text","","text/plain",
|
"--setfield","[tag[external-image]] [tag[external-text]]","text","","text/plain",
|
||||||
"--rendertiddler","$:/core/save/all","index.html","text/plain"],
|
"--rendertiddler","$:/core/save/all","index.html","text/plain"],
|
||||||
"empty": [
|
"empty": [
|
||||||
"--rendertiddler","$:/editions/ko-KR/download-empty","empty.html","text/plain"],
|
"--rendertiddler","$:/editions/ko-KR/download-empty","empty.html","text/plain",
|
||||||
|
"--rendertiddler","$:/editions/ko-KR/download-empty","empty.hta","text/plain"],
|
||||||
"favicon": [
|
"favicon": [
|
||||||
"--savetiddler","$:/favicon.ico","favicon.ico",
|
"--savetiddler","$:/favicon.ico","favicon.ico",
|
||||||
"--savetiddler","$:/green_favicon.ico","static/favicon.ico"],
|
"--savetiddler","$:/green_favicon.ico","static/favicon.ico"],
|
||||||
|
|||||||
18
editions/test/tiddlers/tests/data/element-mapping/Basic.tid
Normal file
18
editions/test/tiddlers/tests/data/element-mapping/Basic.tid
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
title: ElementMapping/Basic
|
||||||
|
description: Mapping one element to another
|
||||||
|
type: text/vnd.tiddlywiki-multiple
|
||||||
|
tags: [[$:/tags/wiki-test-spec]]
|
||||||
|
|
||||||
|
title: Output
|
||||||
|
|
||||||
|
\whitespace trim
|
||||||
|
|
||||||
|
<!-- Map <p> to <div>, adding the class my-class -->
|
||||||
|
\define tv-map-p() div
|
||||||
|
|
||||||
|
This is a paragraph
|
||||||
|
|
||||||
|
+
|
||||||
|
title: ExpectedResult
|
||||||
|
|
||||||
|
<div data-element-mapping-from="p">This is a paragraph</div>
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
title: ElementMapping/BasicWithClass
|
||||||
|
description: Mapping one element to another with an added class
|
||||||
|
type: text/vnd.tiddlywiki-multiple
|
||||||
|
tags: [[$:/tags/wiki-test-spec]]
|
||||||
|
|
||||||
|
title: Output
|
||||||
|
|
||||||
|
\whitespace trim
|
||||||
|
|
||||||
|
<!-- Map <p> to <div>, adding the class my-class -->
|
||||||
|
\define tv-map-p() div
|
||||||
|
\define tv-map-p-class() my-class
|
||||||
|
|
||||||
|
This is a paragraph
|
||||||
|
|
||||||
|
+
|
||||||
|
title: ExpectedResult
|
||||||
|
|
||||||
|
<div class="my-class" data-element-mapping-from="p">This is a paragraph</div>
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
title: Functions/FunctionDefaultValues
|
|
||||||
description: Use defaults for missing parameters in functions in filters
|
|
||||||
type: text/vnd.tiddlywiki-multiple
|
|
||||||
tags: [[$:/tags/wiki-test-spec]]
|
|
||||||
|
|
||||||
title: Output
|
|
||||||
|
|
||||||
\whitespace trim
|
|
||||||
\function .test(prefix:Default) [[ Content]addprefix<prefix>]
|
|
||||||
|
|
||||||
<$text text={{{ [.test[Special]] }}}/>,<$text text={{{ [.test[]] }}}/>
|
|
||||||
|
|
||||||
+
|
|
||||||
title: ExpectedResult
|
|
||||||
|
|
||||||
<p>Special Content,Default Content</p>
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
title: Functions/FunctionResolutionInSubstitute
|
|
||||||
description: Functions should resolve correctly in the substitute operator
|
|
||||||
type: text/vnd.tiddlywiki-multiple
|
|
||||||
tags: [[$:/tags/wiki-test-spec]]
|
|
||||||
|
|
||||||
title: Output
|
|
||||||
|
|
||||||
\whitespace trim
|
|
||||||
|
|
||||||
\function getIndex() [<index>add[1]]
|
|
||||||
|
|
||||||
\procedure template-with-var() $(getIndex)$
|
|
||||||
|
|
||||||
\procedure template-with-filteredexpression() ${ [<getIndex>] }$
|
|
||||||
|
|
||||||
\function test-with-substitute-variable()
|
|
||||||
[[abc]split[]] :map[<template-with-var>substitute[]] :and[join[ / ]]
|
|
||||||
\end
|
|
||||||
|
|
||||||
\function test-with-substitute-filteredexpression()
|
|
||||||
[[abc]split[]] :map[<template-with-filteredexpression>substitute[]] :and[join[ / ]]
|
|
||||||
\end
|
|
||||||
|
|
||||||
\function test-with-function()
|
|
||||||
[[abc]split[]] :map[function[getIndex]substitute[]] :and[join[ / ]]
|
|
||||||
\end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<<test-with-substitute-variable>>|
|
|
||||||
<<test-with-substitute-filteredexpression>>|
|
|
||||||
<<test-with-function>>
|
|
||||||
|
|
||||||
|
|
||||||
+
|
|
||||||
title: ExpectedResult
|
|
||||||
|
|
||||||
<p>1 / 2 / 3|1 / 2 / 3|1 / 2 / 3</p>
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
title: Macros/Dynamic/Attribute
|
|
||||||
description: Attribute macrocall with dynamic paramters
|
|
||||||
type: text/vnd.tiddlywiki-multiple
|
|
||||||
tags: [[$:/tags/wiki-test-spec]]
|
|
||||||
|
|
||||||
title: Output
|
|
||||||
|
|
||||||
\define mamacromamacro(param:"red")
|
|
||||||
It is $param$
|
|
||||||
\end
|
|
||||||
|
|
||||||
<$text text=<<mamacromamacro>>/>
|
|
||||||
-
|
|
||||||
<$text text=<<mamacromamacro param={{{ [[a]addprefix[b]] }}}>>/>
|
|
||||||
-
|
|
||||||
<$text text=<<mamacromamacro param>>/>
|
|
||||||
|
|
||||||
+
|
|
||||||
title: ExpectedResult
|
|
||||||
|
|
||||||
<p>It is red
|
|
||||||
-
|
|
||||||
It is ba
|
|
||||||
-
|
|
||||||
It is param
|
|
||||||
</p>
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
title: Macros/Dynamic/Standalone
|
|
||||||
description: Standalone macrocall with dynamic paramters
|
|
||||||
type: text/vnd.tiddlywiki-multiple
|
|
||||||
tags: [[$:/tags/wiki-test-spec]]
|
|
||||||
|
|
||||||
title: Output
|
|
||||||
|
|
||||||
\whitespace trim
|
|
||||||
|
|
||||||
\define mamacro(one:"red",two:"green")
|
|
||||||
It is $one$ and $two$ or <<__one__>> and <<__two__>>.
|
|
||||||
\end
|
|
||||||
|
|
||||||
<<mamacro>>
|
|
||||||
|
|
||||||
<<mamacro one={{{ [[b]addprefix[a]] }}}>>
|
|
||||||
|
|
||||||
|
|
||||||
<<mamacro one>>
|
|
||||||
+
|
|
||||||
title: ExpectedResult
|
|
||||||
|
|
||||||
<p>It is red and green or red and green.</p><p>It is ab and green or ab and green.</p><p>It is one and green or one and green.</p>
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
title: MultiValuedVariables/AttributeFirstValue
|
|
||||||
description: ((var)) on non-MVV-aware widget attribute returns first value only
|
|
||||||
type: text/vnd.tiddlywiki-multiple
|
|
||||||
tags: [[$:/tags/wiki-test-spec]]
|
|
||||||
|
|
||||||
title: Output
|
|
||||||
|
|
||||||
\whitespace trim
|
|
||||||
<$let items={{{ [all[tiddlers]sort[]] }}}>
|
|
||||||
<$text text=((items))/>
|
|
||||||
</$let>
|
|
||||||
+
|
|
||||||
title: ExpectedResult
|
|
||||||
|
|
||||||
<p>$:/core</p>
|
|
||||||
+
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
title: MultiValuedVariables/DefaultParameterMVV
|
|
||||||
description: Procedure default parameter value using ((var)) syntax to provide MVV default
|
|
||||||
type: text/vnd.tiddlywiki-multiple
|
|
||||||
tags: [[$:/tags/wiki-test-spec]]
|
|
||||||
|
|
||||||
title: Output
|
|
||||||
|
|
||||||
\whitespace trim
|
|
||||||
\procedure showItems(itemList:((defaults)))
|
|
||||||
<$text text={{{ [(itemList)join[-]] }}}/>
|
|
||||||
\end
|
|
||||||
<$let defaults={{{ [all[tiddlers]sort[]] }}}>
|
|
||||||
<<showItems>>
|
|
||||||
</$let>
|
|
||||||
+
|
|
||||||
title: ExpectedResult
|
|
||||||
|
|
||||||
<p>$:/core-ExpectedResult-Output</p>
|
|
||||||
+
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
title: MultiValuedVariables/InlineDisplay
|
|
||||||
description: ((var)) in inline wikitext displays MVV with default comma-space separator
|
|
||||||
type: text/vnd.tiddlywiki-multiple
|
|
||||||
tags: [[$:/tags/wiki-test-spec]]
|
|
||||||
|
|
||||||
title: Output
|
|
||||||
|
|
||||||
\whitespace trim
|
|
||||||
<$let items={{{ [all[tiddlers]sort[]] }}}>
|
|
||||||
((items))
|
|
||||||
</$let>
|
|
||||||
+
|
|
||||||
title: ExpectedResult
|
|
||||||
|
|
||||||
<p>$:/core, ExpectedResult, Output</p>
|
|
||||||
+
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
title: MultiValuedVariables/InlineDisplaySeparator
|
|
||||||
description: ((var||separator)) in inline wikitext displays MVV with custom separator
|
|
||||||
type: text/vnd.tiddlywiki-multiple
|
|
||||||
tags: [[$:/tags/wiki-test-spec]]
|
|
||||||
|
|
||||||
title: Output
|
|
||||||
|
|
||||||
\whitespace trim
|
|
||||||
<$let items={{{ [all[tiddlers]sort[]] }}}>
|
|
||||||
((items||:))
|
|
||||||
</$let>
|
|
||||||
+
|
|
||||||
title: ExpectedResult
|
|
||||||
|
|
||||||
<p>$:/core:ExpectedResult:Output</p>
|
|
||||||
+
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
title: MultiValuedVariables/InlineFilterDisplay
|
|
||||||
description: (((filter))) in inline wikitext displays filter results with default comma-space separator
|
|
||||||
type: text/vnd.tiddlywiki-multiple
|
|
||||||
tags: [[$:/tags/wiki-test-spec]]
|
|
||||||
|
|
||||||
title: Output
|
|
||||||
|
|
||||||
\whitespace trim
|
|
||||||
((([all[tiddlers]sort[]])))
|
|
||||||
+
|
|
||||||
title: ExpectedResult
|
|
||||||
|
|
||||||
<p>$:/core, ExpectedResult, Output</p>
|
|
||||||
+
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
title: MultiValuedVariables/InlineFilterDisplaySeparator
|
|
||||||
description: (((filter||separator))) in inline wikitext displays filter results with custom separator
|
|
||||||
type: text/vnd.tiddlywiki-multiple
|
|
||||||
tags: [[$:/tags/wiki-test-spec]]
|
|
||||||
|
|
||||||
title: Output
|
|
||||||
|
|
||||||
\whitespace trim
|
|
||||||
((([all[tiddlers]sort[]]||:)))
|
|
||||||
+
|
|
||||||
title: ExpectedResult
|
|
||||||
|
|
||||||
<p>$:/core:ExpectedResult:Output</p>
|
|
||||||
+
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
title: MultiValuedVariables/TranscludeParameter
|
|
||||||
description: Multi-valued variable passed as procedure parameter via ((var)) syntax
|
|
||||||
type: text/vnd.tiddlywiki-multiple
|
|
||||||
tags: [[$:/tags/wiki-test-spec]]
|
|
||||||
|
|
||||||
title: Output
|
|
||||||
|
|
||||||
\whitespace trim
|
|
||||||
\procedure showItems(itemList)
|
|
||||||
<$text text={{{ [(itemList)join[-]] }}}/>
|
|
||||||
\end
|
|
||||||
<$let items={{{ [all[tiddlers]sort[]] }}}>
|
|
||||||
<$transclude $variable="showItems" itemList=((items))/>
|
|
||||||
</$let>
|
|
||||||
+
|
|
||||||
title: ExpectedResult
|
|
||||||
|
|
||||||
<p>$:/core-ExpectedResult-Output</p>
|
|
||||||
+
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
title: MultiValuedVariables/TranscludeParameterFunction
|
|
||||||
description: Multi-valued variable passed as function parameter via ((var)) in $transclude
|
|
||||||
type: text/vnd.tiddlywiki-multiple
|
|
||||||
tags: [[$:/tags/wiki-test-spec]]
|
|
||||||
|
|
||||||
title: Output
|
|
||||||
|
|
||||||
\whitespace trim
|
|
||||||
\function showItems(itemList) [(itemList)sort[]join[-]]
|
|
||||||
<$let items={{{ [all[tiddlers]] }}}>
|
|
||||||
<$transclude $variable="showItems" itemList=((items))/>
|
|
||||||
</$let>
|
|
||||||
+
|
|
||||||
title: ExpectedResult
|
|
||||||
|
|
||||||
<p>$:/core-ExpectedResult-Output</p>
|
|
||||||
+
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
tags: $:/tags/wikitext-serialize-test-spec
|
|
||||||
title: Serialize/DynamicMacroMixed
|
|
||||||
type: text/vnd.tiddlywiki
|
|
||||||
|
|
||||||
<<mymacro static:"value" dynamic={{reference}} filter={{{ [tag[test]] }}}>>
|
|
||||||
|
|
||||||
<$macrocall $name="mymacro" static="value" dynamic=<<inner>>/>
|
|
||||||
|
|
||||||
<<mymacro `substituted $(var)$`>>
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
tags: $:/tags/wikitext-serialize-test-spec
|
|
||||||
title: Serialize/DynamicMacroParams
|
|
||||||
type: text/vnd.tiddlywiki
|
|
||||||
|
|
||||||
<<mymacro param={{Something}}>>
|
|
||||||
|
|
||||||
<<mymacro param={{{ [<myvar>addprefix[https:]] }}}>>
|
|
||||||
|
|
||||||
<$macrocall $name="outermacro" inner=<<innermacro arg="value">>/>
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
tags: $:/tags/wikitext-serialize-test-spec
|
|
||||||
title: Serialize/DynamicWidgetAttribute
|
|
||||||
type: text/vnd.tiddlywiki
|
|
||||||
|
|
||||||
<div class=<<mymacro param={{Something}}>>>content</div>
|
|
||||||
|
|
||||||
<$button actions=<<myactions target={{!!title}}>>/>
|
|
||||||
@@ -7,7 +7,3 @@ type: text/vnd.tiddlywiki
|
|||||||
<<.def "macro calls">>
|
<<.def "macro calls">>
|
||||||
|
|
||||||
<<alert "primary" "primary alert" width:"60%">>
|
<<alert "primary" "primary alert" width:"60%">>
|
||||||
|
|
||||||
<<john one:val1 two:val2 three:"quoted value">>
|
|
||||||
|
|
||||||
<<test unquoted:value quoted:"value" number:123>>
|
|
||||||
|
|||||||
@@ -3,5 +3,3 @@ title: Serialize/MacroCallInline
|
|||||||
type: text/vnd.tiddlywiki
|
type: text/vnd.tiddlywiki
|
||||||
|
|
||||||
These are macro calls in a line: <<name "value" "value2">> and <<.def "macro calls">> <<alert "primary" "primary alert" width:"60%">>
|
These are macro calls in a line: <<name "value" "value2">> and <<.def "macro calls">> <<alert "primary" "primary alert" width:"60%">>
|
||||||
|
|
||||||
Testing unquoted parameters: <<john one:val1 two:val2>> and <<test param:value other:"quoted">>.
|
|
||||||
|
|||||||
@@ -235,307 +235,11 @@ describe("HTML tag new parser tests", function() {
|
|||||||
expect(parser.parseTag("< $mytag attrib1='something' attrib2=else thing>",0)).toEqual(
|
expect(parser.parseTag("< $mytag attrib1='something' attrib2=else thing>",0)).toEqual(
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
expect(parser.parseTag("<$mytag attrib3=<<myMacro one:two three:'four and five'>>>", 0)).toEqual(
|
expect(parser.parseTag("<$mytag attrib3=<<myMacro one:two three:'four and five'>>>",0)).toEqual(
|
||||||
{
|
{ type : "mytag", start : 0, attributes : { attrib3 : { type : "macro", start : 7, name : "attrib3", value : { type : "macrocall", start : 16, params : [ { type : "macro-parameter", start : 25, value : "two", name : "one", end : 33 }, { type : "macro-parameter", start : 33, value : "four and five", name : "three", end : 55 } ], name : "myMacro", end : 57 }, end : 57 } }, orderedAttributes: [ { type : "macro", start : 7, name : "attrib3", value : { type : "macrocall", start : 16, params : [ { type : "macro-parameter", start : 25, value : "two", name : "one", end : 33 }, { type : "macro-parameter", start : 33, value : "four and five", name : "three", end : 55 } ], name : "myMacro", end : 57 }, end : 57 } ], tag : "$mytag", end : 58 }
|
||||||
"type": "mytag",
|
|
||||||
"start": 0,
|
|
||||||
"attributes": {
|
|
||||||
"attrib3": {
|
|
||||||
"start": 7,
|
|
||||||
"name": "attrib3",
|
|
||||||
"type": "macro",
|
|
||||||
"value": {
|
|
||||||
"type": "transclude",
|
|
||||||
"start": 16,
|
|
||||||
"attributes": {
|
|
||||||
"$variable": {
|
|
||||||
"name": "$variable",
|
|
||||||
"type": "string",
|
|
||||||
"value": "myMacro"
|
|
||||||
},
|
|
||||||
"one": {
|
|
||||||
"start": 25,
|
|
||||||
"name": "one",
|
|
||||||
"assignmentOperator": ":",
|
|
||||||
"type": "string",
|
|
||||||
"value": "two",
|
|
||||||
"end": 33
|
|
||||||
},
|
|
||||||
"three": {
|
|
||||||
"start": 33,
|
|
||||||
"name": "three",
|
|
||||||
"assignmentOperator": ":",
|
|
||||||
"type": "string",
|
|
||||||
"value": "four and five",
|
|
||||||
"quoted": true,
|
|
||||||
"end": 55
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"orderedAttributes": [
|
|
||||||
{
|
|
||||||
"name": "$variable",
|
|
||||||
"type": "string",
|
|
||||||
"value": "myMacro"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"start": 25,
|
|
||||||
"name": "one",
|
|
||||||
"assignmentOperator": ":",
|
|
||||||
"type": "string",
|
|
||||||
"value": "two",
|
|
||||||
"end": 33
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"start": 33,
|
|
||||||
"name": "three",
|
|
||||||
"assignmentOperator": ":",
|
|
||||||
"type": "string",
|
|
||||||
"value": "four and five",
|
|
||||||
"quoted": true,
|
|
||||||
"end": 55
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"end": 57
|
|
||||||
},
|
|
||||||
"end": 57
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"orderedAttributes": [
|
|
||||||
{
|
|
||||||
"start": 7,
|
|
||||||
"name": "attrib3",
|
|
||||||
"type": "macro",
|
|
||||||
"value": {
|
|
||||||
"type": "transclude",
|
|
||||||
"start": 16,
|
|
||||||
"attributes": {
|
|
||||||
"$variable": {
|
|
||||||
"name": "$variable",
|
|
||||||
"type": "string",
|
|
||||||
"value": "myMacro"
|
|
||||||
},
|
|
||||||
"one": {
|
|
||||||
"start": 25,
|
|
||||||
"name": "one",
|
|
||||||
"assignmentOperator": ":",
|
|
||||||
"type": "string",
|
|
||||||
"value": "two",
|
|
||||||
"end": 33
|
|
||||||
},
|
|
||||||
"three": {
|
|
||||||
"start": 33,
|
|
||||||
"name": "three",
|
|
||||||
"assignmentOperator": ":",
|
|
||||||
"type": "string",
|
|
||||||
"value": "four and five",
|
|
||||||
"quoted": true,
|
|
||||||
"end": 55
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"orderedAttributes": [
|
|
||||||
{
|
|
||||||
"name": "$variable",
|
|
||||||
"type": "string",
|
|
||||||
"value": "myMacro"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"start": 25,
|
|
||||||
"name": "one",
|
|
||||||
"assignmentOperator": ":",
|
|
||||||
"type": "string",
|
|
||||||
"value": "two",
|
|
||||||
"end": 33
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"start": 33,
|
|
||||||
"name": "three",
|
|
||||||
"assignmentOperator": ":",
|
|
||||||
"type": "string",
|
|
||||||
"value": "four and five",
|
|
||||||
"quoted": true,
|
|
||||||
"end": 55
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"end": 57
|
|
||||||
},
|
|
||||||
"end": 57
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"tag": "$mytag",
|
|
||||||
"end": 58
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
expect(parser.parseTag("<$mytag attrib1='something' attrib2=else thing attrib3=<<myMacro one:two three:'four and five'>>>",0)).toEqual(
|
expect(parser.parseTag("<$mytag attrib1='something' attrib2=else thing attrib3=<<myMacro one:two three:'four and five'>>>",0)).toEqual(
|
||||||
{
|
{ type : "mytag", start : 0, attributes : { attrib1 : { type : "string", start : 7, name : "attrib1", value : "something", end : 27 }, attrib2 : { type : "string", start : 27, name : "attrib2", value : "else", end : 40 }, thing : { type : "string", start : 40, name : "thing", value : "true", end : 47 }, attrib3 : { type : "macro", start : 47, name : "attrib3", value : { type : "macrocall", start : 55, params : [ { type : "macro-parameter", start : 64, value : "two", name : "one", end : 72 }, { type : "macro-parameter", start : 72, value : "four and five", name : "three", end : 94 } ], name : "myMacro", end : 96 }, end : 96 } }, orderedAttributes: [ { type : "string", start : 7, name : "attrib1", value : "something", end : 27 }, { type : "string", start : 27, name : "attrib2", value : "else", end : 40 }, { type : "string", start : 40, name : "thing", value : "true", end : 47 }, { type : "macro", start : 47, name : "attrib3", value : { type : "macrocall", start : 55, params : [ { type : "macro-parameter", start : 64, value : "two", name : "one", end : 72 }, { type : "macro-parameter", start : 72, value : "four and five", name : "three", end : 94 } ], name : "myMacro", end : 96 }, end : 96 } ], tag : "$mytag", end : 97 }
|
||||||
"type": "mytag",
|
|
||||||
"start": 0,
|
|
||||||
"attributes": {
|
|
||||||
"attrib1": {
|
|
||||||
"start": 7,
|
|
||||||
"name": "attrib1",
|
|
||||||
"type": "string",
|
|
||||||
"value": "something",
|
|
||||||
"end": 27
|
|
||||||
},
|
|
||||||
"attrib2": {
|
|
||||||
"start": 27,
|
|
||||||
"name": "attrib2",
|
|
||||||
"type": "string",
|
|
||||||
"value": "else",
|
|
||||||
"end": 40
|
|
||||||
},
|
|
||||||
"thing": {
|
|
||||||
"start": 40,
|
|
||||||
"name": "thing",
|
|
||||||
"type": "string",
|
|
||||||
"value": "true",
|
|
||||||
"end": 47
|
|
||||||
},
|
|
||||||
"attrib3": {
|
|
||||||
"start": 47,
|
|
||||||
"name": "attrib3",
|
|
||||||
"type": "macro",
|
|
||||||
"value": {
|
|
||||||
"type": "transclude",
|
|
||||||
"start": 55,
|
|
||||||
"attributes": {
|
|
||||||
"$variable": {
|
|
||||||
"name": "$variable",
|
|
||||||
"type": "string",
|
|
||||||
"value": "myMacro"
|
|
||||||
},
|
|
||||||
"one": {
|
|
||||||
"start": 64,
|
|
||||||
"name": "one",
|
|
||||||
"assignmentOperator": ":",
|
|
||||||
"type": "string",
|
|
||||||
"value": "two",
|
|
||||||
"end": 72
|
|
||||||
},
|
|
||||||
"three": {
|
|
||||||
"start": 72,
|
|
||||||
"name": "three",
|
|
||||||
"assignmentOperator": ":",
|
|
||||||
"type": "string",
|
|
||||||
"value": "four and five",
|
|
||||||
"quoted": true,
|
|
||||||
"end": 94
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"orderedAttributes": [
|
|
||||||
{
|
|
||||||
"name": "$variable",
|
|
||||||
"type": "string",
|
|
||||||
"value": "myMacro"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"start": 64,
|
|
||||||
"name": "one",
|
|
||||||
"assignmentOperator": ":",
|
|
||||||
"type": "string",
|
|
||||||
"value": "two",
|
|
||||||
"end": 72
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"start": 72,
|
|
||||||
"name": "three",
|
|
||||||
"assignmentOperator": ":",
|
|
||||||
"type": "string",
|
|
||||||
"value": "four and five",
|
|
||||||
"quoted": true,
|
|
||||||
"end": 94
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"end": 96
|
|
||||||
},
|
|
||||||
"end": 96
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"orderedAttributes": [
|
|
||||||
{
|
|
||||||
"start": 7,
|
|
||||||
"name": "attrib1",
|
|
||||||
"type": "string",
|
|
||||||
"value": "something",
|
|
||||||
"end": 27
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"start": 27,
|
|
||||||
"name": "attrib2",
|
|
||||||
"type": "string",
|
|
||||||
"value": "else",
|
|
||||||
"end": 40
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"start": 40,
|
|
||||||
"name": "thing",
|
|
||||||
"type": "string",
|
|
||||||
"value": "true",
|
|
||||||
"end": 47
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"start": 47,
|
|
||||||
"name": "attrib3",
|
|
||||||
"type": "macro",
|
|
||||||
"value": {
|
|
||||||
"type": "transclude",
|
|
||||||
"start": 55,
|
|
||||||
"attributes": {
|
|
||||||
"$variable": {
|
|
||||||
"name": "$variable",
|
|
||||||
"type": "string",
|
|
||||||
"value": "myMacro"
|
|
||||||
},
|
|
||||||
"one": {
|
|
||||||
"start": 64,
|
|
||||||
"name": "one",
|
|
||||||
"assignmentOperator": ":",
|
|
||||||
"type": "string",
|
|
||||||
"value": "two",
|
|
||||||
"end": 72
|
|
||||||
},
|
|
||||||
"three": {
|
|
||||||
"start": 72,
|
|
||||||
"name": "three",
|
|
||||||
"assignmentOperator": ":",
|
|
||||||
"type": "string",
|
|
||||||
"value": "four and five",
|
|
||||||
"quoted": true,
|
|
||||||
"end": 94
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"orderedAttributes": [
|
|
||||||
{
|
|
||||||
"name": "$variable",
|
|
||||||
"type": "string",
|
|
||||||
"value": "myMacro"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"start": 64,
|
|
||||||
"name": "one",
|
|
||||||
"assignmentOperator": ":",
|
|
||||||
"type": "string",
|
|
||||||
"value": "two",
|
|
||||||
"end": 72
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"start": 72,
|
|
||||||
"name": "three",
|
|
||||||
"assignmentOperator": ":",
|
|
||||||
"type": "string",
|
|
||||||
"value": "four and five",
|
|
||||||
"quoted": true,
|
|
||||||
"end": 94
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"end": 96
|
|
||||||
},
|
|
||||||
"end": 96
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"tag": "$mytag",
|
|
||||||
"end": 97
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -177,32 +177,6 @@ describe("Widget module", function() {
|
|||||||
expect(wrapper.innerHTML).toBe("<span class=\"tc-error\">Recursive transclusion error in transclude widget</span> <span class=\"tc-error\">Recursive transclusion error in transclude widget</span>");
|
expect(wrapper.innerHTML).toBe("<span class=\"tc-error\">Recursive transclusion error in transclude widget</span> <span class=\"tc-error\">Recursive transclusion error in transclude widget</span>");
|
||||||
});
|
});
|
||||||
|
|
||||||
// Do NOT use a for-of or for-in here. Each jasmine test must be
|
|
||||||
// defined in its own function context, or the `tag` variable will
|
|
||||||
// end up being the same value for all iterations of the test.
|
|
||||||
$tw.utils.each(["div","$button","$checkbox","$diff-text","$draggable","$droppable","dropzone","$eventcatcher","$keyboard","$link","$list filter=x variable=x","$radio","$reveal type=nomatch","$scrollable","$select","$view field=x"],function(tag) {
|
|
||||||
it(`${tag} cleans itself up if children rendering fails`, function() {
|
|
||||||
var wiki = new $tw.Wiki();
|
|
||||||
wiki.addTiddler({title: "TiddlerOne", text: `<$tiddler tiddler='TiddlerOne'><${tag}><$transclude />`});
|
|
||||||
var parseTreeNode = {type: "widget", children: [
|
|
||||||
{type: "transclude", attributes: {
|
|
||||||
"tiddler": {type: "string", value: "TiddlerOne"}
|
|
||||||
}}
|
|
||||||
]};
|
|
||||||
// Construct the widget node
|
|
||||||
var widgetNode = createWidgetNode(parseTreeNode,wiki);
|
|
||||||
// Render the widget node to the DOM
|
|
||||||
var wrapper = renderWidgetNode(widgetNode);
|
|
||||||
// We don't actually care exactly what the HTML contains,
|
|
||||||
// only that it's reasonably sized. If it's super large,
|
|
||||||
// that means the widget containing the bad transclusion
|
|
||||||
// didn't figure out how to clean itself up, and it cloned a bunch.
|
|
||||||
var html = wrapper.innerHTML;
|
|
||||||
expect(html).toContain("Recursive transclusion error in transclude widget");
|
|
||||||
expect(html.length).toBeLessThan(256, "CONTENTS: " + html);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should handle many-tiddler recursion with branching nodes", function() {
|
it("should handle many-tiddler recursion with branching nodes", function() {
|
||||||
var wiki = new $tw.Wiki();
|
var wiki = new $tw.Wiki();
|
||||||
// Add a tiddler
|
// Add a tiddler
|
||||||
|
|||||||
@@ -261,7 +261,7 @@ describe("WikiText parser tests", function() {
|
|||||||
);
|
);
|
||||||
expect(parse("text <<john one:val1 two: 'val \"2\"' three: \"val '3'\" four: \"\"\"val 4\"5'\"\"\" five: [[val 5]] >>")).toEqual(
|
expect(parse("text <<john one:val1 two: 'val \"2\"' three: \"val '3'\" four: \"\"\"val 4\"5'\"\"\" five: [[val 5]] >>")).toEqual(
|
||||||
|
|
||||||
[{"type":"element","tag":"p",rule:"parseblock","children":[{"type":"text","text":"text ","start":0,"end":5},{"type":"transclude","start":5,"end":92,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"john"},"one":{"name":"one","assignmentOperator":":","type":"string","value":"val1","start":11,"end":20},"two":{"name":"two","assignmentOperator":":","type":"string","value":"val \"2\"","quoted":true,"start":20,"end":35},"three":{"name":"three","assignmentOperator":":","type":"string","value":"val '3'","quoted":true,"start":35,"end":52},"four":{"name":"four","assignmentOperator":":","type":"string","value":"val 4\"5'","quoted":true,"start":52,"end":73},"five":{"name":"five","assignmentOperator":":","type":"string","value":"val 5","quoted":true,"start":73,"end":89}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"one","assignmentOperator":":","type":"string","value":"val1","start":11,"end":20},{"name":"two","assignmentOperator":":","type":"string","value":"val \"2\"","quoted":true,"start":20,"end":35},{"name":"three","assignmentOperator":":","type":"string","value":"val '3'","quoted":true,"start":35,"end":52},{"name":"four","assignmentOperator":":","type":"string","value":"val 4\"5'","quoted":true,"start":52,"end":73},{"name":"five","assignmentOperator":":","type":"string","value":"val 5","quoted":true,"start":73,"end":89}]}],"start":0,"end":92}]
|
[{"type":"element","tag":"p",rule:"parseblock","children":[{"type":"text","text":"text ","start":0,"end":5},{"type":"transclude","start":5,"end":92,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"john"},"one":{"name":"one","type":"string","value":"val1","start":11,"end":20},"two":{"name":"two","type":"string","value":"val \"2\"","start":20,"end":35},"three":{"name":"three","type":"string","value":"val '3'","start":35,"end":52},"four":{"name":"four","type":"string","value":"val 4\"5'","start":52,"end":73},"five":{"name":"five","type":"string","value":"val 5","start":73,"end":89}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"one","type":"string","value":"val1","start":11,"end":20},{"name":"two","type":"string","value":"val \"2\"","start":20,"end":35},{"name":"three","type":"string","value":"val '3'","start":35,"end":52},{"name":"four","type":"string","value":"val 4\"5'","start":52,"end":73},{"name":"five","type":"string","value":"val 5","start":73,"end":89}]}],"start":0,"end":92}]
|
||||||
|
|
||||||
);
|
);
|
||||||
expect(parse("ignored << carrots <<john>>")).toEqual(
|
expect(parse("ignored << carrots <<john>>")).toEqual(
|
||||||
@@ -287,7 +287,7 @@ describe("WikiText parser tests", function() {
|
|||||||
);
|
);
|
||||||
expect(parse("text <<outie one:'my <<innie>>' >>")).toEqual(
|
expect(parse("text <<outie one:'my <<innie>>' >>")).toEqual(
|
||||||
|
|
||||||
[{"type":"element","tag":"p",rule:"parseblock","children":[{"type":"text","text":"text ","start":0,"end":5},{"type":"transclude","start":5,"end":34,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"outie"},"one":{"name":"one","assignmentOperator":":","type":"string","value":"my <<innie>>","quoted":true,"start":12,"end":31}},"orderedAttributes":[{"name":"$variable","type":"string","value":"outie"},{"name":"one","assignmentOperator":":","type":"string","value":"my <<innie>>","quoted":true,"start":12,"end":31}]}],"start":0,"end":34}]
|
[{"type":"element","tag":"p",rule:"parseblock","children":[{"type":"text","text":"text ","start":0,"end":5},{"type":"transclude","start":5,"end":34,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"outie"},"one":{"name":"one","type":"string","value":"my <<innie>>","start":12,"end":31}},"orderedAttributes":[{"name":"$variable","type":"string","value":"outie"},{"name":"one","type":"string","value":"my <<innie>>","start":12,"end":31}]}],"start":0,"end":34}]
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -301,7 +301,7 @@ describe("WikiText parser tests", function() {
|
|||||||
);
|
);
|
||||||
expect(parse("<<john one:val1 two: 'val \"2\"' three: \"val '3'\" four: \"\"\"val 4\"5'\"\"\" five: [[val 5]] >>")).toEqual(
|
expect(parse("<<john one:val1 two: 'val \"2\"' three: \"val '3'\" four: \"\"\"val 4\"5'\"\"\" five: [[val 5]] >>")).toEqual(
|
||||||
|
|
||||||
[{"type":"transclude","start":0,"end":87,"rule":"macrocallblock","attributes":{"$variable":{"name":"$variable","type":"string","value":"john"},"one":{"name":"one","assignmentOperator":":","type":"string","value":"val1","start":6,"end":15},"two":{"name":"two","assignmentOperator":":","type":"string","value":"val \"2\"","quoted":true,"start":15,"end":30},"three":{"name":"three","assignmentOperator":":","type":"string","value":"val '3'","quoted":true,"start":30,"end":47},"four":{"name":"four","assignmentOperator":":","type":"string","value":"val 4\"5'","quoted":true,"start":47,"end":68},"five":{"name":"five","assignmentOperator":":","type":"string","value":"val 5","quoted":true,"start":68,"end":84}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"one","assignmentOperator":":","type":"string","value":"val1","start":6,"end":15},{"name":"two","assignmentOperator":":","type":"string","value":"val \"2\"","quoted":true,"start":15,"end":30},{"name":"three","assignmentOperator":":","type":"string","value":"val '3'","quoted":true,"start":30,"end":47},{"name":"four","assignmentOperator":":","type":"string","value":"val 4\"5'","quoted":true,"start":47,"end":68},{"name":"five","assignmentOperator":":","type":"string","value":"val 5","quoted":true,"start":68,"end":84}],"isBlock":true}]
|
[{"type":"transclude","start":0,"end":87,"rule":"macrocallblock","attributes":{"$variable":{"name":"$variable","type":"string","value":"john"},"one":{"name":"one","type":"string","value":"val1","start":6,"end":15},"two":{"name":"two","type":"string","value":"val \"2\"","start":15,"end":30},"three":{"name":"three","type":"string","value":"val '3'","start":30,"end":47},"four":{"name":"four","type":"string","value":"val 4\"5'","start":47,"end":68},"five":{"name":"five","type":"string","value":"val 5","start":68,"end":84}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"one","type":"string","value":"val1","start":6,"end":15},{"name":"two","type":"string","value":"val \"2\"","start":15,"end":30},{"name":"three","type":"string","value":"val '3'","start":30,"end":47},{"name":"four","type":"string","value":"val 4\"5'","start":47,"end":68},{"name":"five","type":"string","value":"val 5","start":68,"end":84}],"isBlock":true}]
|
||||||
|
|
||||||
);
|
);
|
||||||
expect(parse("<< carrots\n\n<<john>>")).toEqual(
|
expect(parse("<< carrots\n\n<<john>>")).toEqual(
|
||||||
@@ -321,12 +321,12 @@ describe("WikiText parser tests", function() {
|
|||||||
);
|
);
|
||||||
expect(parse("<<multiline arg:\"\"\"\n\nwikitext\n\"\"\" >>")).toEqual(
|
expect(parse("<<multiline arg:\"\"\"\n\nwikitext\n\"\"\" >>")).toEqual(
|
||||||
|
|
||||||
[{"type":"transclude","start":0,"end":36,"rule":"macrocallblock","attributes":{"$variable":{"name":"$variable","type":"string","value":"multiline"},"arg":{"name":"arg","assignmentOperator":":","type":"string","value":"\n\nwikitext\n","quoted":true,"start":11,"end":33}},"orderedAttributes":[{"name":"$variable","type":"string","value":"multiline"},{"name":"arg","assignmentOperator":":","type":"string","value":"\n\nwikitext\n","quoted":true,"start":11,"end":33}],"isBlock":true}]
|
[{"type":"transclude","start":0,"end":36,"rule":"macrocallblock","attributes":{"$variable":{"name":"$variable","type":"string","value":"multiline"},"arg":{"name":"arg","type":"string","value":"\n\nwikitext\n","start":11,"end":33}},"orderedAttributes":[{"name":"$variable","type":"string","value":"multiline"},{"name":"arg","type":"string","value":"\n\nwikitext\n","start":11,"end":33}],"isBlock":true}]
|
||||||
|
|
||||||
);
|
);
|
||||||
expect(parse("<<outie one:'my <<innie>>' >>")).toEqual(
|
expect(parse("<<outie one:'my <<innie>>' >>")).toEqual(
|
||||||
|
|
||||||
[ { type: "transclude", start: 0, rule: "macrocallblock", attributes: { $variable: {name: "$variable", type:"string", value: "outie"}, one: {name: "one", assignmentOperator: ":", type:"string", value: "my <<innie>>", quoted: true, start: 7, end: 26} }, orderedAttributes: [ {name: "$variable", type:"string", value: "outie"}, {name: "one", assignmentOperator: ":", type:"string", value: "my <<innie>>", quoted: true, start: 7, end: 26} ], end: 29, isBlock: true } ]
|
[ { type: "transclude", start: 0, rule: "macrocallblock", attributes: { $variable: {name: "$variable", type:"string", value: "outie"}, one: {name: "one", type:"string", value: "my <<innie>>", start: 7, end: 26} }, orderedAttributes: [ {name: "$variable", type:"string", value: "outie"}, {name: "one", type:"string", value: "my <<innie>>", start: 7, end: 26} ], end: 29, isBlock: true } ]
|
||||||
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -334,23 +334,23 @@ describe("WikiText parser tests", function() {
|
|||||||
it("should parse tricky macrocall parameters", function() {
|
it("should parse tricky macrocall parameters", function() {
|
||||||
expect(parse("<<john pa>am>>")).toEqual(
|
expect(parse("<<john pa>am>>")).toEqual(
|
||||||
|
|
||||||
[{"type":"transclude","start":0,"end":14,"attributes":{"0":{"name":"0","type":"string","value":"pa>am","start":6,"end":12,"isPositional":true},"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"0","type":"string","value":"pa>am","start":6,"end":12,"isPositional":true}],"isBlock":true,"rule":"macrocallblock"}]
|
[{"type":"transclude","start":0,"end":14,"attributes":{"0":{"name":"0","type":"string","value":"pa>am","start":6,"end":12},"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"0","type":"string","value":"pa>am","start":6,"end":12}],"isBlock":true,"rule":"macrocallblock"}]
|
||||||
|
|
||||||
);
|
);
|
||||||
expect(parse("<<john param> >>")).toEqual(
|
expect(parse("<<john param> >>")).toEqual(
|
||||||
|
|
||||||
[{"type":"transclude","start":0,"end":16,"attributes":{"0":{"name":"0","type":"string","value":"param>","start":6,"end":13,"isPositional":true},"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"0","type":"string","value":"param>","start":6,"end":13,"isPositional":true}],"isBlock":true,"rule":"macrocallblock"}]
|
[{"type":"transclude","start":0,"end":16,"attributes":{"0":{"name":"0","type":"string","value":"param>","start":6,"end":13},"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"0","type":"string","value":"param>","start":6,"end":13}],"isBlock":true,"rule":"macrocallblock"}]
|
||||||
|
|
||||||
);
|
);
|
||||||
expect(parse("<<john param>>>")).toEqual(
|
expect(parse("<<john param>>>")).toEqual(
|
||||||
|
|
||||||
[{"type":"element","rule":"parseblock","tag":"p","children":[{"type":"transclude","start":0,"end":14,"rule":"macrocallinline","attributes":{"0":{"name":"0","type":"string","value":"param","start":6,"end":12,"isPositional":true},"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"0","type":"string","value":"param","start":6,"end":12,"isPositional":true}]},{"type":"text","text":">","start":14,"end":15}],"start":0,"end":15}]
|
[{"type":"element","tag":"p",rule:"parseblock","children":[{"type":"transclude","start":0,"end":14,"rule":"macrocallinline","attributes":{"0":{"name":"0","type":"string","value":"param","start":6,"end":12},"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"0","type":"string","value":"param","start":6,"end":12}]},{"type":"text","text":">","start":14,"end":15}],"start":0,"end":15}]
|
||||||
|
|
||||||
);
|
);
|
||||||
// equals signs should be allowed
|
// equals signs should be allowed
|
||||||
expect(parse("<<john var>=4 >>")).toEqual(
|
expect(parse("<<john var>=4 >>")).toEqual(
|
||||||
|
|
||||||
[{"type":"transclude","start":0,"end":16,"attributes":{"0":{"name":"0","type":"string","value":"var>=4","start":6,"end":13,"isPositional":true},"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"0","type":"string","value":"var>=4","start":6,"end":13,"isPositional":true}],"isBlock":true,"rule":"macrocallblock"}]
|
[{"type":"transclude","start":0,"end":16,"attributes":{"0":{"name":"0","type":"string","value":"var>=4","start":6,"end":13},"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"0","type":"string","value":"var>=4","start":6,"end":13}],"isBlock":true,"rule":"macrocallblock"}]
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ Prioritise the groups to translate first. A translation can be useful without be
|
|||||||
* Buttons
|
* Buttons
|
||||||
* Control Panel
|
* Control Panel
|
||||||
* Date
|
* Date
|
||||||
* Draft
|
|
||||||
* Edit Template
|
* Edit Template
|
||||||
* Getting Started
|
* Getting Started
|
||||||
* Import
|
* Import
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
title: $:/status/UserName
|
|
||||||
|
|
||||||
Jermolene
|
|
||||||
@@ -51,7 +51,6 @@
|
|||||||
"--render","$:/plugins/tiddlywiki/translators/templates/ControlPanel.multids","language/ControlPanel.multids","text/plain",
|
"--render","$:/plugins/tiddlywiki/translators/templates/ControlPanel.multids","language/ControlPanel.multids","text/plain",
|
||||||
"--render","$:/plugins/tiddlywiki/translators/templates/CoreReadMe.tid","language/CoreReadMe.tid","text/plain",
|
"--render","$:/plugins/tiddlywiki/translators/templates/CoreReadMe.tid","language/CoreReadMe.tid","text/plain",
|
||||||
"--render","$:/plugins/tiddlywiki/translators/templates/Dates.multids","language/Dates.multids","text/plain",
|
"--render","$:/plugins/tiddlywiki/translators/templates/Dates.multids","language/Dates.multids","text/plain",
|
||||||
"--render","$:/plugins/tiddlywiki/translators/templates/Draft.multids","language/Draft.multids","text/plain",
|
|
||||||
"--render","$:/plugins/tiddlywiki/translators/templates/EditTemplate.multids","language/EditTemplate.multids","text/plain",
|
"--render","$:/plugins/tiddlywiki/translators/templates/EditTemplate.multids","language/EditTemplate.multids","text/plain",
|
||||||
"--render","$:/plugins/tiddlywiki/translators/templates/Exporters.multids","language/Exporters.multids","text/plain",
|
"--render","$:/plugins/tiddlywiki/translators/templates/Exporters.multids","language/Exporters.multids","text/plain",
|
||||||
"--render","$:/plugins/tiddlywiki/translators/templates/Fields.multids","language/Fields.multids","text/plain",
|
"--render","$:/plugins/tiddlywiki/translators/templates/Fields.multids","language/Fields.multids","text/plain",
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
created: 20251108075028089
|
|
||||||
modified: 20260130070027124
|
|
||||||
tags: Reference
|
|
||||||
title: Core CSS Variables
|
|
||||||
type: text/vnd.tiddlywiki
|
|
||||||
|
|
||||||
<<.from-version 5.4.0>> Tiddlywiki CSS variable definitions starts with `--tp-*` and `--tpc-*`. They are mainly used to [[Write stylesheets in vanilla CSS|Writing stylesheets in vanilla CSS]]. These prefixes ''are reserved'' for Tiddlywiki, so it should not be used for user defined CSS variables. It is also not recommended to override these core CSS variables.
|
|
||||||
|
|
||||||
Core CSS variables are defined in [[$:/core/stylesheets/custom-properties]].
|
|
||||||
|
|
||||||
<<list-links "[tag[Core CSS Variables]]" class:"multi-columns">>
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user