1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2026-07-08 21:02:45 +00:00

Compare commits

..

33 Commits

Author SHA1 Message Date
Jeremy Ruston e1625afab5 Docs updates 2026-01-31 13:10:02 +00:00
Jeremy Ruston 2e89771129 Merge branch 'master' into dynamic-macro-calls 2026-01-30 20:58:05 +00:00
Jeremy Ruston a1ef2ef6d4 Merge branch 'tiddlywiki-com' 2026-01-29 14:27:59 +00:00
Saq Imtiaz 75edd9b488 Reverts change to getLocationHash utils method (#9622)
* fix: reverted change to getLocationHash utils method

* docs: update changenote
2026-01-26 16:03:50 +01:00
Jeremy Ruston b6a91521d6 Docs updates 2026-01-25 21:31:53 +00:00
Jeremy Ruston 8ebf052e25 On reflection, new style values should not be allowed for anonymous parameters
Backwards compatibility
2026-01-25 20:27:01 +00:00
Jeremy Ruston a29ae908e2 Only allow new style parameter values if the separator is an equals sign 2026-01-25 20:21:39 +00:00
Jeremy Ruston ff352d63da Allow single closing square brackets within double square brackets quoted strings 2026-01-25 19:56:53 +00:00
Jeremy Ruston 4729e15925 Add change note 2026-01-25 19:35:23 +00:00
Jeremy Ruston 7ec985f8e6 Remove debug logging 2026-01-25 19:26:42 +00:00
Jeremy Ruston cadddc13dc Genuflecting to the linter 2026-01-25 19:23:44 +00:00
Jeremy Ruston a2f38ef51d Merge branch 'master' into dynamic-macro-calls 2026-01-25 19:19:15 +00:00
Mario Pietsch cde9c931c8 Select widget handle default parameter refresh (#9617)
* select widget handle default parameter refresh

* Add change note
2026-01-25 19:58:52 +01:00
Saq Imtiaz d07fe25cdb feat: extend fakedom implementation (#9616)
* feat: extend fakedom implementation

* docs: updated changenote
2026-01-25 19:05:46 +01:00
KiXaM_刻む a40ce29451 Add an option to enable CORS (#9277)
* Add an option to disable CORS

* change 'disable' with 'enable' CORS, because that is what this option actually does

* add a change note

* typo
2026-01-25 17:04:16 +01:00
buggyj 75647eb623 Fixes #8092 SelectWidget does not work with multiple options organise… (#8093)
* Fixes #8092 SelectWidget does not work with multiple options organised into group

* Consolidate variables

* Apply suggestion from @saqimtiaz

* Update core/modules/widgets/select.js

Co-authored-by: Mario Pietsch <pmariojo@gmail.com>

* added release note

* chore: lint fixes

---------

Co-authored-by: Saq Imtiaz <saq.imtiaz@gmail.com>
Co-authored-by: Mario Pietsch <pmariojo@gmail.com>
2026-01-25 17:02:18 +01:00
Mario Pietsch 70b4557738 [DOCS] Add link to "TiddlyWiki Archive" tiddler to the TiddlyWiki Releases info (#9613) 2026-01-25 16:59:54 +01:00
Mario Pietsch efe58e41bc [DOCS] Fix some typos in "days Operator (Examples)" (#9479)
* [DOCS] Fix some typos in "days Operator (Examples)"

* Remove created and modified fields from days.tid

Remove created and modified fields from days.tid
2026-01-21 09:09:14 +01:00
Mario Pietsch 79e3d14698 [DOCS] Make TaskManagementExamples more "hackable" (#9482)
* [DOCS] Make TaskManagementExamples more "hackable"

* Update modified date in TaskManagementExample.tid

* Fix modified date in TaskManagementExampleDraggable
2026-01-20 13:23:17 +01:00
superuser-does 763d717a13 Improvements to DateFormat tiddler (#9583) 2026-01-20 13:18:24 +01:00
Jeremy Ruston 54ebf60a05 Merge branch 'master' into dynamic-macro-calls 2025-12-18 21:09:07 +00:00
Jeremy Ruston 5d72fb0608 Minor docs update 2025-12-18 21:08:54 +00:00
Jeremy Ruston 30e6092819 Fix unneeded diff 2025-11-24 11:11:33 +00:00
lin onetwo 4305a0bb92 Fix/dynamic macro calls test (#9459)
* Revert "Temporarily disable a broken serializer test"

This reverts commit b3144300ee.

* restore synamic parameter parse result

* lint

* lint

* remove duplicate

* Update core/modules/parsers/parseutils.js

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update editions/test/tiddlers/tests/data/serialize/DynamicWidgetAttribute.tid

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update editions/test/tiddlers/tests/data/serialize/DynamicWidgetAttribute.tid

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix: mixed qouted and unquoted

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-24 11:10:42 +00:00
Jeremy Ruston b3144300ee Temporarily disable a broken serializer test 2025-11-23 21:04:04 +00:00
Jeremy Ruston 205e8cf9c9 Fix test 2025-11-23 21:03:32 +00:00
Jeremy Ruston ad4c1ca5a1 Merge branch 'master' into dynamic-macro-calls 2025-11-23 20:59:41 +00:00
Jeremy Ruston 5136e33f07 Tweak examples 2025-05-15 15:09:05 +01:00
Jeremy Ruston 744f6e7a3b Add some examples 2025-05-12 17:43:45 +01:00
Jeremy Ruston 1ded43f6ea Test for attribute macros 2025-05-12 17:32:30 +01:00
Jeremy Ruston 48e6863a89 Parse attribute macros with the new parser
This fixes the tests
2025-05-12 17:16:08 +01:00
Jeremy Ruston f5d5a23aff Test for standalone macro calls with dynamic parameters 2025-05-12 14:26:21 +01:00
Jeremy Ruston 2d6b6b5011 Initial commit
The idea is to extend the macro call syntax to accept dynamic parameter values (ie thing:{{more}} etc). Eventually, this will work in all the contexts in which the double angle bracket syntax is valid.

This initial commit gets the tests passing, but doesn't yet activate the new functionality.
2025-05-12 14:03:29 +01:00
215 changed files with 1563 additions and 6661 deletions
+19 -2
View File
@@ -316,8 +316,25 @@ $tw.utils.htmlDecode = function(s) {
return s.toString().replace(/&lt;/mg,"<").replace(/&nbsp;/mg,"\xA0").replace(/&gt;/mg,">").replace(/&quot;/mg,"\"").replace(/&amp;/mg,"&");
};
/** @deprecated Use window.location.hash instead. */
$tw.utils.getLocationHash = () => window.location.hash;
/*
Get the browser location.hash. We don't use location.hash because of the way that Firefox auto-urldecodes it (see http://stackoverflow.com/questions/1703552/encoding-of-window-location-hash)
*/
$tw.utils.getLocationHash = function() {
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 */
$tw.utils.pad = function(value,length = 2) {
+15
View File
@@ -42,6 +42,8 @@ function Server(options) {
}
// Setup the default required plugins
this.requiredPlugins = this.get("required-plugins").split(',');
// Initialise CORS
this.corsEnable = this.get("cors-enable") === "yes";
// Initialise CSRF
this.csrfDisable = this.get("csrf-disable") === "yes";
// Initialize Gzip compression
@@ -261,6 +263,13 @@ Server.prototype.requestHandler = function(request,response,options) {
state.urlInfo = url.parse(request.url);
state.queryParameters = querystring.parse(state.urlInfo.query);
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);
// Get the principals authorized to access this resource
state.authorizationType = options.authorizationType || this.methodMappings[request.method] || "readers";
@@ -285,6 +294,12 @@ Server.prototype.requestHandler = function(request,response,options) {
response.end();
return;
}
// Reply to OPTIONS
if(this.corsEnable && request.method === "OPTIONS") {
response.writeHead(204);
response.end();
return;
}
// Find the route that matches this path
var route = self.findMatchingRoute(request,state);
// Optionally output debug info
+1 -2
View File
@@ -57,11 +57,10 @@ LayoutSwitcher/Caption: Layout
LoadedModules/Caption: Loaded Modules
LoadedModules/Hint: These are the currently loaded tiddler modules linked to their source tiddlers. Any italicised modules lack a source tiddler, typically because they were setup during the boot process.
Palette/Caption: Palette
Palette/CustomSettings/Prompt: Custom settings for current palette: <<palette-link>>
Palette/Editor/Clone/Caption: clone
Palette/Editor/Clone/Prompt: It is recommended that you clone this shadow palette before editing it
Palette/Editor/Delete/Hint: delete this entry from the current palette
Palette/Editor/Names/External/Show: Show inherited palette entries
Palette/Editor/Names/External/Show: Show color names that are not part of the current palette
Palette/Editor/Prompt/Modified: This shadow palette has been modified
Palette/Editor/Prompt: Editing
Palette/Editor/Reset/Caption: reset
-1
View File
@@ -30,7 +30,6 @@ Error/DeserializeOperator/MissingOperand: Filter Error: Missing operand for 'des
Error/DeserializeOperator/UnknownDeserializer: Filter Error: Unknown deserializer provided as operand for the 'deserialize' operator
Error/Filter: Filter error
Error/FilterSyntax: Syntax error in filter expression
Error/FilterPragma: Filter Error: Unknown filter pragma
Error/FilterRunPrefix: Filter Error: Unknown prefix for filter run
Error/IsFilterOperator: Filter Error: Unknown parameter for the 'is' filter operator
Error/FormatFilterOperator: Filter Error: Unknown suffix for the 'format' filter operator
-116
View File
@@ -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;
+1 -1
View File
@@ -31,7 +31,7 @@ function FramedEngine(options) {
this.parentNode.insertBefore(this.iframeNode,this.nextSibling);
this.iframeDoc = this.iframeNode.contentWindow.document;
// (Firefox requires us to put some empty content in the iframe)
var paletteTitle = this.widget.wiki.getTiddlerText("$:/palette/palette-colours");
var paletteTitle = this.widget.wiki.getTiddlerText("$:/palette");
var colorScheme = (this.widget.wiki.getTiddler(paletteTitle) || {fields: {}}).fields["color-scheme"] || "light";
this.iframeDoc.open();
this.iframeDoc.write("<!DOCTYPE html><html><head><meta name='color-scheme' content='" + colorScheme + "'></head><body></body></html>");
+1 -9
View File
@@ -28,12 +28,7 @@ function SimpleEngine(options) {
if(this.widget.editTag === "textarea") {
this.domNode.appendChild(this.widget.document.createTextNode(this.value));
} else {
if(this.widget.editType === "color") {
// The <input type="color"> element requires a six digit hex value
this.domNode.value = $tw.utils.convertCSSColorToRGBString(this.value);
} else {
this.domNode.value = this.value;
}
this.domNode.value = this.value;
}
// Set the attributes
if(this.widget.editType && this.widget.editTag !== "textarea") {
@@ -88,9 +83,6 @@ Update the DomNode with the new text
*/
SimpleEngine.prototype.updateDomNodeText = function(text) {
try {
if(this.widget.editType === "color") {
text = $tw.utils.convertCSSColorToRGBString(text);
}
this.domNode.value = text;
} catch(e) {
// Ignore
+4 -2
View File
@@ -217,10 +217,12 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
EditTextWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
// Completely rerender if any of our attributes have changed
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes["class"] || changedAttributes.placeholder || changedAttributes.size || changedAttributes.autoHeight || changedAttributes.minHeight || changedAttributes.focusPopup || changedAttributes.rows || changedAttributes.tabindex || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || changedAttributes.autocomplete || changedTiddlers[HEIGHT_MODE_TITLE] || changedTiddlers[ENABLE_TOOLBAR_TITLE] || changedTiddlers["$:/palette"] || changedAttributes.disabled || changedAttributes.fileDrop) {
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes["default"] || changedAttributes["class"] || changedAttributes.placeholder || changedAttributes.size || changedAttributes.autoHeight || changedAttributes.minHeight || changedAttributes.focusPopup || changedAttributes.rows || changedAttributes.tabindex || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || changedAttributes.autocomplete || changedTiddlers[HEIGHT_MODE_TITLE] || changedTiddlers[ENABLE_TOOLBAR_TITLE] || changedTiddlers["$:/palette"] || changedAttributes.disabled || changedAttributes.fileDrop) {
this.refreshSelf();
return true;
} else if(changedAttributes["default"] || changedTiddlers[this.editRefreshTitle] || changedTiddlers[this.editTitle]) {
} else if (changedTiddlers[this.editRefreshTitle]) {
this.engine.updateDomNodeText(this.getEditInfo().value);
} else if(changedTiddlers[this.editTitle]) {
var editInfo = this.getEditInfo();
this.updateEditor(editInfo.value,editInfo.type);
}
-106
View File
@@ -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;
+45 -71
View File
@@ -146,16 +146,14 @@ exports.parseFilter = function(filterString) {
match;
var whitespaceRegExp = /(\s+)/mg,
// Groups:
// 1 - pragma
// 2 - pragma suffix
// 3 - entire filter run prefix
// 4 - filter run prefix name
// 5 - filter run prefix suffixes
// 6 - opening square bracket following filter run prefix
// 7 - double quoted string following filter run prefix
// 8 - single quoted string following filter run prefix
// 9 - anything except for whitespace and square brackets
operandRegExp = /(?:::(\w+)(?:\:(\w+))?(?=\s|$)|((?:\+|\-|~|(?:=>?)|:(\w+)(?:\:([\w\:, ]*))?)?)(?:(\[)|(?:"([^"]*)")|(?:'([^']*)')|([^\s\[\]]+)))/mg;
// 1 - entire filter run prefix
// 2 - filter run prefix itself
// 3 - filter run prefix suffixes
// 4 - opening square bracket following filter run prefix
// 5 - double quoted string following filter run prefix
// 6 - single quoted string following filter run prefix
// 7 - anything except for whitespace and square brackets
operandRegExp = /((?:\+|\-|~|(?:=>?)|\:(\w+)(?:\:([\w\:, ]*))?)?)(?:(\[)|(?:"([^"]*)")|(?:'([^']*)')|([^\s\[\]]+))/mg;
while(p < filterString.length) {
// Skip any whitespace
whitespaceRegExp.lastIndex = p;
@@ -172,23 +170,18 @@ exports.parseFilter = function(filterString) {
};
match = operandRegExp.exec(filterString);
if(match && match.index === p) {
// If there is a filter run prefix
if(match[1]) {
// If there is a filter pragma
operation.pragma = match[1];
operation.suffix = match[2];
p = match.index + match[0].length;
} else if(match[3]) {
// If there is a filter run prefix
operation.prefix = match[3];
operation.prefix = match[1];
p = p + operation.prefix.length;
// Name for named prefixes
if(match[4]) {
operation.namedPrefix = match[4];
if(match[2]) {
operation.namedPrefix = match[2];
}
// Suffixes for filter run prefix
if(match[5]) {
if(match[3]) {
operation.suffixes = [];
$tw.utils.each(match[5].split(":"),function(subsuffix) {
$tw.utils.each(match[3].split(":"),function(subsuffix) {
operation.suffixes.push([]);
$tw.utils.each(subsuffix.split(","),function(entry) {
entry = $tw.utils.trim(entry);
@@ -200,7 +193,7 @@ exports.parseFilter = function(filterString) {
}
}
// Opening square bracket
if(match[6]) {
if(match[4]) {
p = parseFilterOperation(operation.operators,filterString,p);
} else {
p = match.index + match[0].length;
@@ -210,9 +203,9 @@ exports.parseFilter = function(filterString) {
p = parseFilterOperation(operation.operators,filterString,p);
}
// Quoted strings and unquoted title
if(match[7] || match[8] || match[9]) { // Double quoted string, single quoted string or unquoted title
if(match[5] || match[6] || match[7]) { // Double quoted string, single quoted string or unquoted title
operation.operators.push(
{operator: "title", operands: [{text: match[7] || match[8] || match[9]}]}
{operator: "title", operands: [{text: match[5] || match[6] || match[7]}]}
);
}
results.push(operation);
@@ -237,8 +230,8 @@ exports.getFilterRunPrefixes = function() {
return this.filterRunPrefixes;
}
exports.filterTiddlers = function(filterString,widget,source,options) {
var fn = this.compileFilter(filterString,options);
exports.filterTiddlers = function(filterString,widget,source) {
var fn = this.compileFilter(filterString);
try {
const fnResult = fn.call(this,source,widget);
return fnResult;
@@ -248,19 +241,17 @@ exports.filterTiddlers = function(filterString,widget,source,options) {
};
/*
Compile a filter into a function with the signature fn(source,widget,options) where:
Compile a filter into a function with the signature fn(source,widget) where:
source: an iterator function for the source tiddlers, called source(iterator), where iterator is called as iterator(tiddler,title)
widget: an optional widget node for retrieving the current tiddler etc.
*/
exports.compileFilter = function(filterString,options) {
var defaultFilterRunPrefix = (options || {}).defaultFilterRunPrefix || "or";
var cacheKey = filterString + "|" + defaultFilterRunPrefix;
exports.compileFilter = function(filterString) {
if(!this.filterCache) {
this.filterCache = Object.create(null);
this.filterCacheCount = 0;
}
if(this.filterCache[cacheKey] !== undefined) {
return this.filterCache[cacheKey];
if(this.filterCache[filterString] !== undefined) {
return this.filterCache[filterString];
}
var filterParseTree;
try {
@@ -339,8 +330,7 @@ exports.compileFilter = function(filterString,options) {
regexp: operator.regexp
},{
wiki: self,
widget: widget,
defaultFilterRunPrefix: defaultFilterRunPrefix
widget: widget
});
if($tw.utils.isArray(results)) {
accumulator = self.makeTiddlerIterator(results);
@@ -361,45 +351,29 @@ exports.compileFilter = function(filterString,options) {
var filterRunPrefixes = self.getFilterRunPrefixes();
// Wrap the operator functions in a wrapper function that depends on the prefix
operationFunctions.push((function() {
if(operation.pragma) {
switch(operation.pragma) {
case "defaultprefix":
defaultFilterRunPrefix = operation.suffix || "or";
break;
default:
var options = {wiki: self, suffixes: operation.suffixes || []};
switch(operation.prefix || "") {
case "": // No prefix means that the operation is unioned into the result
return filterRunPrefixes["or"](operationSubFunction, options);
case "=": // The results of the operation are pushed into the result without deduplication
return filterRunPrefixes["all"](operationSubFunction, options);
case "-": // The results of this operation are removed from the main result
return filterRunPrefixes["except"](operationSubFunction, options);
case "+": // This operation is applied to the main results so far
return filterRunPrefixes["and"](operationSubFunction, options);
case "~": // This operation is unioned into the result only if the main result so far is empty
return filterRunPrefixes["else"](operationSubFunction, options);
case "=>": // This operation is applied to the main results so far, and the results are assigned to a variable
return filterRunPrefixes["let"](operationSubFunction, options);
default:
if(operation.namedPrefix && filterRunPrefixes[operation.namedPrefix]) {
return filterRunPrefixes[operation.namedPrefix](operationSubFunction, options);
} else {
return function(results,source,widget) {
results.clear();
results.push($tw.language.getString("Error/FilterPragma"));
results.push($tw.language.getString("Error/FilterRunPrefix"));
};
}
return function(results,source,widget) {
// Dummy response
};
} else {
var options = {wiki: self, suffixes: operation.suffixes || []};
switch(operation.prefix || "") {
case "": // Use the default filter run prefix if none is specified
return filterRunPrefixes[defaultFilterRunPrefix](operationSubFunction, options);
case "=": // The results of the operation are pushed into the result without deduplication
return filterRunPrefixes["all"](operationSubFunction, options);
case "-": // The results of this operation are removed from the main result
return filterRunPrefixes["except"](operationSubFunction, options);
case "+": // This operation is applied to the main results so far
return filterRunPrefixes["and"](operationSubFunction, options);
case "~": // This operation is unioned into the result only if the main result so far is empty
return filterRunPrefixes["else"](operationSubFunction, options);
case "=>": // This operation is applied to the main results so far, and the results are assigned to a variable
return filterRunPrefixes["let"](operationSubFunction, options);
default:
if(operation.namedPrefix && filterRunPrefixes[operation.namedPrefix]) {
return filterRunPrefixes[operation.namedPrefix](operationSubFunction, options);
} else {
return function(results,source,widget) {
results.clear();
results.push($tw.language.getString("Error/FilterRunPrefix"));
};
}
}
}
}
})());
});
@@ -438,7 +412,7 @@ exports.compileFilter = function(filterString,options) {
this.filterCache = Object.create(null);
this.filterCacheCount = 0;
}
this.filterCache[cacheKey] = fnMeasured;
this.filterCache[filterString] = fnMeasured;
this.filterCacheCount++;
return fnMeasured;
};
-21
View File
@@ -1,21 +0,0 @@
/*\
title: $:/core/modules/filters/changecount.js
type: application/javascript
module-type: filteroperator
Filter operator for retrieving the changecount for each title in the list.
\*/
"use strict";
/*
Export our filter function
*/
exports.changecount = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
results.push(options.wiki.getChangeCount(title) + "");
});
return results;
};
-140
View File
@@ -1,140 +0,0 @@
/*\
title: $:/core/modules/filters/colour-ops.js
type: application/javascript
module-type: filteroperator
Filter operators for colour operations
\*/
"use strict";
var Color = require("$:/core/modules/utils/dom/color.js").Color,
colourSpacesList = Object.keys(Color.spaces),
hueAdjustersList = ["raw","increasing","decreasing","longer","shorter"];
exports["colour-lighten"] = makeSerialColourOperator(function (colour, operator, options) {
return colour.lighten($tw.utils.parseNumber(operator.operand)).display().toString();
});
exports["colour-darken"] = makeSerialColourOperator(function (colour, operator, options) {
return colour.darken($tw.utils.parseNumber(operator.operand)).display().toString();
});
exports["colour-get-oklch"] = makeSerialColourOperator(function (colour, operator, options) {
var prop = ((operator.suffixes || [])[0] || ["l"])[0];
if(["l","c","h"].indexOf(prop) !== -1) {
colour = colour.oklch[prop];
}
return colour.toString();
});
exports["colour-set-oklch"] = makeSerialColourOperator(function (colour, operator, options) {
var prop = ((operator.suffixes || [])[0] || ["l"])[0];
if(["l","c","h"].indexOf(prop) !== -1) {
colour.oklch[prop] = $tw.utils.parseNumber(operator.operand);
}
return colour.display().toString();
});
exports["colour-set-alpha"] = makeSerialColourOperator(function (colour, operator, options) {
colour.alpha = $tw.utils.parseNumber(operator.operand);
return colour.display().toString();
});
exports["colour-contrast"] = makeParallelColourOperator(function (colours, operator, options) {
var colourContrasts = [];
$tw.utils.each(colours,function(colour,index) {
if(!colour) {
colour = $tw.utils.parseCSSColorObject("white");
colours[index] = colour;
}
if(index > 0) {
colourContrasts.push(colour.contrast(colours[index - 1],"DeltaPhi").toString());
}
});
return colourContrasts;
});
exports["colour-best-contrast"] = makeParallelColourOperator(function (colours, operator, options, originalColours) {
var bestContrast = 0,
bestColour = null;
if(colours.length < 2) {
return [];
}
var targetColour = colours[colours.length - 1];
for(var t=0; t<colours.length; t++) {
var colour = colours[t];
if(colour) {
var contrast = colour.contrast(targetColour,"DeltaPhi");
if(contrast > bestContrast) {
bestContrast = contrast;
bestColour = originalColours[t];
}
}
}
if(bestColour) {
return [bestColour];
} else {
return [];
}
});
exports["colour-interpolate"] = function(source,operator,options) {
// Get the colour space suffix
var space = ((((operator.suffixes || [])[0] || ["srgb"])[0]) || "").toLowerCase();
if(colourSpacesList.indexOf(space) === -1) {
space = "lch";
}
// Get the hue adjuster suffix
var hueAdjuster = ((((operator.suffixes || [])[1] || ["shorter"])[0]) || "").toLowerCase();
if(hueAdjustersList.indexOf(hueAdjuster) === -1) {
hueAdjuster = "shorter";
}
// Get the colours
if(operator.operands.length < 2) {
return [];
}
var colourA = $tw.utils.parseCSSColorObject(operator.operands[0]),
colourB = $tw.utils.parseCSSColorObject(operator.operands[1]);
if(!colourA || !colourB) {
return [];
}
var rangefn = colourA.range(colourB,{space: space, hue: hueAdjuster});
// Cycle through the weights
var results = [];
source(function(tiddler,title) {
var index = $tw.utils.parseNumber(title);
var colour = rangefn(index);
results.push(colour.display().toString());
});
return results;
};
function makeSerialColourOperator(fn) {
return function (source, operator, options) {
var results = [];
source(function (tiddler, title) {
var c = $tw.utils.parseCSSColorObject(title);
if (c) {
c = fn(c, operator, options);
results.push(c);
} else {
results.push("");
}
});
return results;
};
}
function makeParallelColourOperator(fn) {
return function (source, operator, options) {
var originalColours = [],
colours = [];
source(function (tiddler, title) {
originalColours.push(title);
colours.push($tw.utils.parseCSSColorObject(title));
});
return fn(colours, operator, options, originalColours);
};
}
+1 -3
View File
@@ -13,9 +13,7 @@ Filter operator returning those input titles that pass a subfilter
Export our filter function
*/
exports.filter = function(source,operator,options) {
var suffixes = operator.suffixes || [],
defaultFilterRunPrefix = (suffixes[0] || [options.defaultFilterRunPrefix] || [])[0] || "or",
filterFn = options.wiki.compileFilter(operator.operand,{defaultFilterRunPrefix}),
var filterFn = options.wiki.compileFilter(operator.operand),
results = [],
target = operator.prefix !== "!";
source(function(tiddler,title) {
+1 -3
View File
@@ -13,9 +13,7 @@ Filter operator returning its operand evaluated as a filter
Export our filter function
*/
exports.subfilter = function(source,operator,options) {
var suffixes = operator.suffixes || [],
defaultFilterRunPrefix = (suffixes[0] || [options.defaultFilterRunPrefix] || [])[0] || "or";
var list = options.wiki.filterTiddlers(operator.operand,options.widget,source,{defaultFilterRunPrefix});
var list = options.wiki.filterTiddlers(operator.operand,options.widget,source);
if(operator.prefix === "!") {
var results = [];
source(function(tiddler,title) {
-67
View File
@@ -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 [];
};
+7
View File
@@ -33,6 +33,13 @@ exports.getInfoTiddlerFields = function(updateInfoTiddlersCallback) {
// Screen size
infoTiddlerFields.push({title: "$:/info/browser/screen/width", text: window.screen.width.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
infoTiddlerFields.push({title: "$:/info/browser/language", text: navigator.language || ""});
}
+11 -12
View File
@@ -26,26 +26,25 @@ exports.params = [
Run the macro
*/
exports.run = function(target,fallbackTarget,colourA,colourB) {
var rgbTarget = $tw.utils.parseCSSColorObject(target) || $tw.utils.parseCSSColorObject(fallbackTarget);
var rgbTarget = $tw.utils.parseCSSColor(target) || $tw.utils.parseCSSColor(fallbackTarget);
if(!rgbTarget) {
return colourA;
}
var rgbColourA = $tw.utils.parseCSSColorObject(colourA),
rgbColourB = $tw.utils.parseCSSColorObject(colourB);
var rgbColourA = $tw.utils.parseCSSColor(colourA),
rgbColourB = $tw.utils.parseCSSColor(colourB);
if(rgbColourA && !rgbColourB) {
return colourA;
return rgbColourA;
}
if(rgbColourB && !rgbColourA) {
return colourB;
return rgbColourB;
}
if(!rgbColourA && !rgbColourB) {
// If neither colour is readable, return a crude inverse of the target
rgbTarget.srgb.r = 1 - rgbTarget.srgb.r;
rgbTarget.srgb.g = 1 - rgbTarget.srgb.g;
rgbTarget.srgb.b = 1 - rgbTarget.srgb.b;
return rgbTarget.display();
return [255 - rgbTarget[0],255 - rgbTarget[1],255 - rgbTarget[2],rgbTarget[3]];
}
var aContrast = rgbColourA.contrast(rgbTarget,"DeltaPhi"),
bContrast = rgbColourB.contrast(rgbTarget,"DeltaPhi");
return aContrast > bContrast ? colourA : colourB;
// Colour brightness formula derived from http://www.w3.org/WAI/ER/WD-AERT/#color-contrast
var brightnessTarget = rgbTarget[0] * 0.299 + rgbTarget[1] * 0.587 + rgbTarget[2] * 0.114,
brightnessA = rgbColourA[0] * 0.299 + rgbColourA[1] * 0.587 + rgbColourA[2] * 0.114,
brightnessB = rgbColourB[0] * 0.299 + rgbColourB[1] * 0.587 + rgbColourB[2] * 0.114;
return Math.abs(brightnessTarget - brightnessA) > Math.abs(brightnessTarget - brightnessB) ? colourA : colourB;
};
+153 -27
View File
@@ -107,13 +107,14 @@ exports.parseStringLiteral = function(source,pos) {
type: "string",
start: pos
};
var reString = /(?:"""([\s\S]*?)"""|"([^"]*)")|(?:'([^']*)')/g;
var reString = /(?:"""([\s\S]*?)"""|"([^"]*)")|(?:'([^']*)')|\[\[((?:[^\]]|\](?!\]))*)\]\]/g;
reString.lastIndex = pos;
var match = reString.exec(source);
if(match && match.index === pos) {
node.value = match[1] !== undefined ? match[1] :(
match[2] !== undefined ? match[2] : match[3]
);
match[2] !== undefined ? match[2] : (
match[3] !== undefined ? match[3] : match[4]
));
node.end = pos + match[0].length;
return node;
} else {
@@ -173,7 +174,7 @@ exports.parseMacroParameter = function(source,pos) {
start: pos
};
// 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
pos = $tw.utils.skipWhiteSpace(source,pos);
// Look for the parameter
@@ -206,28 +207,152 @@ exports.parseMacroParameter = function(source,pos) {
Look for a macro invocation. Returns null if not found, or {type: "transclude", attributes:, start:, end:}
*/
exports.parseMacroInvocationAsTransclusion = function(source,pos) {
var node = $tw.utils.parseMacroInvocation(source,pos);
if(node) {
var positionalName = 0,
transclusion = {
type: "transclude",
start: node.start,
end: node.end
};
$tw.utils.addAttributeToParseTreeNode(transclusion,"$variable",node.name);
$tw.utils.each(node.params,function(param) {
var name = param.name;
if(name) {
if(name.charAt(0) === "$") {
name = "$" + name;
}
$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;
var node = {
type: "transclude",
start: pos,
attributes: {},
orderedAttributes: []
};
// Define our regexps
var reVarName = /([^\s>"'=:]+)/g;
// Skip whitespace
pos = $tw.utils.skipWhiteSpace(source,pos);
// Look for a double opening angle bracket
var token = $tw.utils.parseTokenString(source,pos,"<<");
if(!token) {
return null;
}
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;
};
/*
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 unquoted value
var unquotedValue = $tw.utils.parseTokenRegExp(source,pos,reUnquotedAttribute);
if(unquotedValue) {
pos = unquotedValue.end;
node.type = "string";
node.value = unquotedValue.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 {
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 {
}
}
}
}
}
}
// Bail if we don't have a value
if(!node.type) {
return null;
}
// Update the end position
node.end = pos;
return node;
};
@@ -296,7 +421,7 @@ exports.parseFilterVariable = function(source) {
};
/*
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:,}
Look for an HTML attribute definition. Returns null if not found, otherwise returns {name:, type: "filtered|string|indirect|macro", value|filter|textReference:, start:, end:,}
*/
exports.parseAttribute = function(source,pos) {
var node = {
@@ -354,7 +479,7 @@ exports.parseAttribute = function(source,pos) {
node.value = unquotedValue.match[1];
} else {
// Look for a macro invocation value
var macroInvocation = $tw.utils.parseMacroInvocation(source,pos);
var macroInvocation = $tw.utils.parseMacroInvocationAsTransclusion(source,pos);
if(macroInvocation) {
pos = macroInvocation.end;
node.type = "macro";
@@ -375,6 +500,7 @@ exports.parseAttribute = function(source,pos) {
}
}
} else {
// If there is no equals sign or colon, then this is an attribute with no value, defaulting to "true"
node.type = "string";
node.value = "true";
}
@@ -37,7 +37,7 @@ exports.parse = function() {
var paramString = this.match[2],
params = [];
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);
while(paramMatch) {
// Save the parameter details
-26
View File
@@ -13,11 +13,6 @@ Load core modules
exports.name = "load-modules";
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() {
// Load modules
$tw.modules.applyMethods("utils",$tw.utils);
@@ -36,27 +31,6 @@ exports.startup = function() {
$tw.modules.applyMethods("tiddlerdeserializer",$tw.Wiki.tiddlerDeserializerModules);
$tw.macros = $tw.modules.getModulesByTypeAsHashmap("macro");
$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) {
$tw.Commander.initCommands();
}
+15
View File
@@ -14,6 +14,11 @@ exports.name = "startup";
exports.after = ["load-modules"];
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() {
// Minimal browser detection
if($tw.browser) {
@@ -49,6 +54,16 @@ exports.startup = function() {
}
// Initialise version
$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
$tw.language = new $tw.Language();
$tw.languageSwitcher = new $tw.PluginSwitcher({
-55
View File
@@ -1,55 +0,0 @@
/*\
title: $:/core/modules/utils/color-utils.js
type: application/javascript
module-type: utils
Color.js related utilities
\*/
"use strict";
var Color = require("$:/core/modules/utils/dom/color.js").Color;
/*
For backwards compatibility
*/
exports.parseCSSColor = function(colourString) {
var c = exports.parseCSSColorObject(colourString);
if(c) {
var rgb = c.srgb;
return [rgb[0],rgb[1],rgb[2],c.alpha];
} else {
return null;
}
};
/*
Preferred way to parse a Color.js colour
*/
exports.parseCSSColorObject = function(colourString) {
var c = null;
try {
c = new Color(colourString);
} catch(e) {
// Return null if there is an error
}
return c;
};
/*
Convert a CSS colour to an RGB string suitable for use with the <input type="color"> element
*/
exports.convertCSSColorToRGBString = function(colourString) {
var c = exports.parseCSSColorObject(colourString);
if(c) {
var hex = c.toString({format: "hex"});
if(hex.length === 4) {
hex = "#" + hex[1] + hex[1] + hex[2] + hex[2] + hex[3] + hex[3];
}
return hex;
} else {
return null;
}
};
-21
View File
@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2021 Lea Verou, Chris Lilley
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
File diff suppressed because one or more lines are too long
@@ -1,21 +0,0 @@
{
"tiddlers": [
{
"file": "color.global.min.v0.6.1.js",
"fields": {
"type": "application/javascript",
"title": "$:/core/modules/utils/dom/color.js",
"module-type": "library"
},
"prefix": "",
"suffix": ";\nexports.Color = Color;"
},
{
"file": "LICENSE",
"fields": {
"type": "text/plain",
"title": "$:/core/modules/utils/dom/color.js/license"
}
}
]
}
+200
View File
@@ -0,0 +1,200 @@
// (c) Dean McNamee <dean@gmail.com>, 2012.
//
// https://github.com/deanm/css-color-parser-js
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
// http://www.w3.org/TR/css3-color/
var kCSSColorTable = {
"transparent": [0,0,0,0], "aliceblue": [240,248,255,1],
"antiquewhite": [250,235,215,1], "aqua": [0,255,255,1],
"aquamarine": [127,255,212,1], "azure": [240,255,255,1],
"beige": [245,245,220,1], "bisque": [255,228,196,1],
"black": [0,0,0,1], "blanchedalmond": [255,235,205,1],
"blue": [0,0,255,1], "blueviolet": [138,43,226,1],
"brown": [165,42,42,1], "burlywood": [222,184,135,1],
"cadetblue": [95,158,160,1], "chartreuse": [127,255,0,1],
"chocolate": [210,105,30,1], "coral": [255,127,80,1],
"cornflowerblue": [100,149,237,1], "cornsilk": [255,248,220,1],
"crimson": [220,20,60,1], "cyan": [0,255,255,1],
"darkblue": [0,0,139,1], "darkcyan": [0,139,139,1],
"darkgoldenrod": [184,134,11,1], "darkgray": [169,169,169,1],
"darkgreen": [0,100,0,1], "darkgrey": [169,169,169,1],
"darkkhaki": [189,183,107,1], "darkmagenta": [139,0,139,1],
"darkolivegreen": [85,107,47,1], "darkorange": [255,140,0,1],
"darkorchid": [153,50,204,1], "darkred": [139,0,0,1],
"darksalmon": [233,150,122,1], "darkseagreen": [143,188,143,1],
"darkslateblue": [72,61,139,1], "darkslategray": [47,79,79,1],
"darkslategrey": [47,79,79,1], "darkturquoise": [0,206,209,1],
"darkviolet": [148,0,211,1], "deeppink": [255,20,147,1],
"deepskyblue": [0,191,255,1], "dimgray": [105,105,105,1],
"dimgrey": [105,105,105,1], "dodgerblue": [30,144,255,1],
"firebrick": [178,34,34,1], "floralwhite": [255,250,240,1],
"forestgreen": [34,139,34,1], "fuchsia": [255,0,255,1],
"gainsboro": [220,220,220,1], "ghostwhite": [248,248,255,1],
"gold": [255,215,0,1], "goldenrod": [218,165,32,1],
"gray": [128,128,128,1], "green": [0,128,0,1],
"greenyellow": [173,255,47,1], "grey": [128,128,128,1],
"honeydew": [240,255,240,1], "hotpink": [255,105,180,1],
"indianred": [205,92,92,1], "indigo": [75,0,130,1],
"ivory": [255,255,240,1], "khaki": [240,230,140,1],
"lavender": [230,230,250,1], "lavenderblush": [255,240,245,1],
"lawngreen": [124,252,0,1], "lemonchiffon": [255,250,205,1],
"lightblue": [173,216,230,1], "lightcoral": [240,128,128,1],
"lightcyan": [224,255,255,1], "lightgoldenrodyellow": [250,250,210,1],
"lightgray": [211,211,211,1], "lightgreen": [144,238,144,1],
"lightgrey": [211,211,211,1], "lightpink": [255,182,193,1],
"lightsalmon": [255,160,122,1], "lightseagreen": [32,178,170,1],
"lightskyblue": [135,206,250,1], "lightslategray": [119,136,153,1],
"lightslategrey": [119,136,153,1], "lightsteelblue": [176,196,222,1],
"lightyellow": [255,255,224,1], "lime": [0,255,0,1],
"limegreen": [50,205,50,1], "linen": [250,240,230,1],
"magenta": [255,0,255,1], "maroon": [128,0,0,1],
"mediumaquamarine": [102,205,170,1], "mediumblue": [0,0,205,1],
"mediumorchid": [186,85,211,1], "mediumpurple": [147,112,219,1],
"mediumseagreen": [60,179,113,1], "mediumslateblue": [123,104,238,1],
"mediumspringgreen": [0,250,154,1], "mediumturquoise": [72,209,204,1],
"mediumvioletred": [199,21,133,1], "midnightblue": [25,25,112,1],
"mintcream": [245,255,250,1], "mistyrose": [255,228,225,1],
"moccasin": [255,228,181,1], "navajowhite": [255,222,173,1],
"navy": [0,0,128,1], "oldlace": [253,245,230,1],
"olive": [128,128,0,1], "olivedrab": [107,142,35,1],
"orange": [255,165,0,1], "orangered": [255,69,0,1],
"orchid": [218,112,214,1], "palegoldenrod": [238,232,170,1],
"palegreen": [152,251,152,1], "paleturquoise": [175,238,238,1],
"palevioletred": [219,112,147,1], "papayawhip": [255,239,213,1],
"peachpuff": [255,218,185,1], "peru": [205,133,63,1],
"pink": [255,192,203,1], "plum": [221,160,221,1],
"powderblue": [176,224,230,1], "purple": [128,0,128,1],
"red": [255,0,0,1], "rosybrown": [188,143,143,1],
"royalblue": [65,105,225,1], "saddlebrown": [139,69,19,1],
"salmon": [250,128,114,1], "sandybrown": [244,164,96,1],
"seagreen": [46,139,87,1], "seashell": [255,245,238,1],
"sienna": [160,82,45,1], "silver": [192,192,192,1],
"skyblue": [135,206,235,1], "slateblue": [106,90,205,1],
"slategray": [112,128,144,1], "slategrey": [112,128,144,1],
"snow": [255,250,250,1], "springgreen": [0,255,127,1],
"steelblue": [70,130,180,1], "tan": [210,180,140,1],
"teal": [0,128,128,1], "thistle": [216,191,216,1],
"tomato": [255,99,71,1], "turquoise": [64,224,208,1],
"violet": [238,130,238,1], "wheat": [245,222,179,1],
"white": [255,255,255,1], "whitesmoke": [245,245,245,1],
"yellow": [255,255,0,1], "yellowgreen": [154,205,50,1]}
function clamp_css_byte(i) { // Clamp to integer 0 .. 255.
i = Math.round(i); // Seems to be what Chrome does (vs truncation).
return i < 0 ? 0 : i > 255 ? 255 : i;
}
function clamp_css_float(f) { // Clamp to float 0.0 .. 1.0.
return f < 0 ? 0 : f > 1 ? 1 : f;
}
function parse_css_int(str) { // int or percentage.
if (str[str.length - 1] === '%')
return clamp_css_byte(parseFloat(str) / 100 * 255);
return clamp_css_byte(parseInt(str));
}
function parse_css_float(str) { // float or percentage.
if (str[str.length - 1] === '%')
return clamp_css_float(parseFloat(str) / 100);
return clamp_css_float(parseFloat(str));
}
function css_hue_to_rgb(m1, m2, h) {
if (h < 0) h += 1;
else if (h > 1) h -= 1;
if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
if (h * 2 < 1) return m2;
if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
return m1;
}
function parseCSSColor(css_str) {
// Remove all whitespace, not compliant, but should just be more accepting.
var str = css_str.replace(/ /g, '').toLowerCase();
// Color keywords (and transparent) lookup.
if (str in kCSSColorTable) return kCSSColorTable[str].slice(); // dup.
// #abc and #abc123 syntax.
if (str[0] === '#') {
if (str.length === 4) {
var iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing.
if (!(iv >= 0 && iv <= 0xfff)) return null; // Covers NaN.
return [((iv & 0xf00) >> 4) | ((iv & 0xf00) >> 8),
(iv & 0xf0) | ((iv & 0xf0) >> 4),
(iv & 0xf) | ((iv & 0xf) << 4),
1];
} else if (str.length === 7) {
var iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing.
if (!(iv >= 0 && iv <= 0xffffff)) return null; // Covers NaN.
return [(iv & 0xff0000) >> 16,
(iv & 0xff00) >> 8,
iv & 0xff,
1];
}
return null;
}
var op = str.indexOf('('), ep = str.indexOf(')');
if (op !== -1 && ep + 1 === str.length) {
var fname = str.substr(0, op);
var params = str.substr(op+1, ep-(op+1)).split(',');
var alpha = 1; // To allow case fallthrough.
switch (fname) {
case 'rgba':
if (params.length !== 4) return null;
alpha = parse_css_float(params.pop());
// Fall through.
case 'rgb':
if (params.length !== 3) return null;
return [parse_css_int(params[0]),
parse_css_int(params[1]),
parse_css_int(params[2]),
alpha];
case 'hsla':
if (params.length !== 4) return null;
alpha = parse_css_float(params.pop());
// Fall through.
case 'hsl':
if (params.length !== 3) return null;
var h = (((parseFloat(params[0]) % 360) + 360) % 360) / 360; // 0 .. 1
// NOTE(deanm): According to the CSS spec s/l should only be
// percentages, but we don't bother and let float or percentage.
var s = parse_css_float(params[1]);
var l = parse_css_float(params[2]);
var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
var m1 = l * 2 - m2;
return [clamp_css_byte(css_hue_to_rgb(m1, m2, h+1/3) * 255),
clamp_css_byte(css_hue_to_rgb(m1, m2, h) * 255),
clamp_css_byte(css_hue_to_rgb(m1, m2, h-1/3) * 255),
alpha];
default:
return null;
}
}
return null;
}
try { exports.parseCSSColor = parseCSSColor } catch(e) { }
@@ -0,0 +1,3 @@
title: $:/core/modules/utils/dom/csscolorparser.js
type: application/javascript
module-type: utils
+1
View File
@@ -37,6 +37,7 @@ Object.defineProperty(TW_Node.prototype, 'TEXT_NODE', {
var TW_TextNode = function(text) {
bumpSequenceNumber(this);
this.textContent = text + "";
this.children = [];
};
Object.setPrototypeOf(TW_TextNode.prototype,TW_Node.prototype);
+2 -2
View File
@@ -62,8 +62,8 @@ SendMessageWidget.prototype.invokeAction = function(triggeringWidget,event) {
var paramObject = Object.create(null);
// Add names/values pairs if present
if(this.actionNames && this.actionValues) {
var names = this.wiki.filterTiddlers(this.actionNames,this,{defaultFilterRunPrefix: "all"}),
values = this.wiki.filterTiddlers(this.actionValues,this,{defaultFilterRunPrefix: "all"});
var names = this.wiki.filterTiddlers(this.actionNames,this),
values = this.wiki.filterTiddlers(this.actionValues,this);
$tw.utils.each(names,function(name,index) {
paramObject[name] = values[index] || "";
});
@@ -56,10 +56,10 @@ Invoke the action associated with this widget
*/
SetMultipleFieldsWidget.prototype.invokeAction = function(triggeringWidget,event) {
var tiddler = this.wiki.getTiddler(this.actionTiddler),
names, values = this.wiki.filterTiddlers(this.actionValues,this,{defaultFilterRunPrefix: "all"});
names, values = this.wiki.filterTiddlers(this.actionValues,this);
if(this.actionFields) {
var additions = {};
names = this.wiki.filterTiddlers(this.actionFields,this,{defaultFilterRunPrefix: "all"});
names = this.wiki.filterTiddlers(this.actionFields,this);
$tw.utils.each(names,function(fieldname,index) {
additions[fieldname] = values[index] || "";
});
@@ -68,7 +68,7 @@ SetMultipleFieldsWidget.prototype.invokeAction = function(triggeringWidget,event
this.wiki.addTiddler(new $tw.Tiddler(creationFields,tiddler,{title: this.actionTiddler},modificationFields,additions));
} else if(this.actionIndexes) {
var data = this.wiki.getTiddlerData(this.actionTiddler,Object.create(null));
names = this.wiki.filterTiddlers(this.actionIndexes,this,{defaultFilterRunPrefix: "all"});
names = this.wiki.filterTiddlers(this.actionIndexes,this);
$tw.utils.each(names,function(name,index) {
data[name] = values[index] || "";
});
+4 -4
View File
@@ -72,8 +72,8 @@ GenesisWidget.prototype.execute = function() {
this.attributeNames = [];
this.attributeValues = [];
if(this.genesisNames && this.genesisValues) {
this.attributeNames = this.wiki.filterTiddlers(self.genesisNames,this,{defaultFilterRunPrefix: "all"});
this.attributeValues = this.wiki.filterTiddlers(self.genesisValues,this,{defaultFilterRunPrefix: "all"});
this.attributeNames = this.wiki.filterTiddlers(self.genesisNames,this);
this.attributeValues = this.wiki.filterTiddlers(self.genesisValues,this);
$tw.utils.each(this.attributeNames,function(varname,index) {
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],varname,self.attributeValues[index] || "");
});
@@ -103,8 +103,8 @@ GenesisWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes(),
filterNames = this.getAttribute("$names",""),
filterValues = this.getAttribute("$values",""),
attributeNames = this.wiki.filterTiddlers(filterNames,this,{defaultFilterRunPrefix: "all"}),
attributeValues = this.wiki.filterTiddlers(filterValues,this,{defaultFilterRunPrefix: "all"});
attributeNames = this.wiki.filterTiddlers(filterNames,this),
attributeValues = this.wiki.filterTiddlers(filterValues,this);
if($tw.utils.count(changedAttributes) > 0 || !$tw.utils.isArrayEqual(this.attributeNames,attributeNames) || !$tw.utils.isArrayEqual(this.attributeValues,attributeValues)) {
this.refreshSelf();
return true;
+18 -9
View File
@@ -82,8 +82,8 @@ SelectWidget.prototype.handleChangeEvent = function(event) {
if(this.selectMultiple == false) {
var value = this.getSelectDomNode().value;
} else {
var value = this.getSelectValues()
value = $tw.utils.stringifyList(value);
var value = this.getSelectValues();
value = $tw.utils.stringifyList(value);
}
this.wiki.setText(this.selectTitle,this.selectField,this.selectIndex,value);
// Trigger actions
@@ -118,12 +118,21 @@ SelectWidget.prototype.setSelectValue = function() {
}
}
// Assign it to the select element if it's different than the current value
if (this.selectMultiple) {
if(this.selectMultiple) {
value = value === undefined ? "" : value;
var select = this.getSelectDomNode();
var values = Array.isArray(value) ? value : $tw.utils.parseStringArray(value);
var child,
values = Array.isArray(value) ? value : $tw.utils.parseStringArray(value);
for(var i=0; i < select.children.length; i++){
select.children[i].selected = values.indexOf(select.children[i].value) !== -1
child=select.children[i];
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 {
var domNode = this.getSelectDomNode();
@@ -147,14 +156,14 @@ SelectWidget.prototype.getSelectValues = function() {
select = this.getSelectDomNode();
result = [];
options = select && select.options;
for (var i=0; i<options.length; i++) {
for(var i=0; i<options.length; i++) {
opt = options[i];
if (opt.selected) {
if(opt.selected) {
result.push(opt.value || opt.text);
}
}
return result;
}
};
/*
Compute the internal state of the widget
@@ -183,7 +192,7 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
SelectWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
// If we're using a different tiddler/field/index then completely refresh ourselves
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.tooltip || changedAttributes.tabindex || changedAttributes.disabled) {
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.tooltip || changedAttributes.default || changedAttributes.tabindex || changedAttributes.disabled) {
this.refreshSelf();
return true;
} else {
+31 -31
View File
@@ -12,7 +12,7 @@ Widget to set multiple variables at once from a list of names and a list of valu
var Widget = require("$:/core/modules/widgets/widget.js").widget;
var SetMultipleVariablesWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options);
this.initialise(parseTreeNode,options);
};
/*
@@ -24,52 +24,52 @@ SetMultipleVariablesWidget.prototype = new Widget();
Render this widget into the DOM
*/
SetMultipleVariablesWidget.prototype.render = function(parent,nextSibling) {
this.parentDomNode = parent;
this.computeAttributes();
this.execute();
this.renderChildren(parent,nextSibling);
this.parentDomNode = parent;
this.computeAttributes();
this.execute();
this.renderChildren(parent,nextSibling);
};
/*
Compute the internal state of the widget
*/
SetMultipleVariablesWidget.prototype.execute = function() {
// Setup our variables
this.setVariables();
// Construct the child widgets
this.makeChildWidgets();
// Setup our variables
this.setVariables();
// Construct the child widgets
this.makeChildWidgets();
};
SetMultipleVariablesWidget.prototype.setVariables = function() {
// Set the variables
var self = this,
filterNames = this.getAttribute("$names",""),
filterValues = this.getAttribute("$values","");
this.variableNames = [];
this.variableValues = [];
if(filterNames && filterValues) {
this.variableNames = this.wiki.filterTiddlers(filterNames,this,{defaultFilterRunPrefix: "all"});
this.variableValues = this.wiki.filterTiddlers(filterValues,this,{defaultFilterRunPrefix: "all"});
$tw.utils.each(this.variableNames,function(varname,index) {
self.setVariable(varname,self.variableValues[index]);
});
}
// Set the variables
var self = this,
filterNames = this.getAttribute("$names",""),
filterValues = this.getAttribute("$values","");
this.variableNames = [];
this.variableValues = [];
if(filterNames && filterValues) {
this.variableNames = this.wiki.filterTiddlers(filterNames,this);
this.variableValues = this.wiki.filterTiddlers(filterValues,this);
$tw.utils.each(this.variableNames,function(varname,index) {
self.setVariable(varname,self.variableValues[index]);
});
}
};
/*
Refresh the widget by ensuring our attributes are up to date
*/
SetMultipleVariablesWidget.prototype.refresh = function(changedTiddlers) {
var filterNames = this.getAttribute("$names",""),
filterValues = this.getAttribute("$values",""),
variableNames = this.wiki.filterTiddlers(filterNames,this,{defaultFilterRunPrefix: "all"}),
variableValues = this.wiki.filterTiddlers(filterValues,this,{defaultFilterRunPrefix: "all"});
if(!$tw.utils.isArrayEqual(this.variableNames,variableNames) || !$tw.utils.isArrayEqual(this.variableValues,variableValues)) {
this.refreshSelf();
return true;
}
return this.refreshChildren(changedTiddlers);
var filterNames = this.getAttribute("$names",""),
filterValues = this.getAttribute("$values",""),
variableNames = this.wiki.filterTiddlers(filterNames,this),
variableValues = this.wiki.filterTiddlers(filterValues,this);
if(!$tw.utils.isArrayEqual(this.variableNames,variableNames) || !$tw.utils.isArrayEqual(this.variableValues,variableValues)) {
this.refreshSelf();
return true;
}
return this.refreshChildren(changedTiddlers);
};
exports["setmultiplevariables"] = SetMultipleVariablesWidget;
+15 -1
View File
@@ -414,7 +414,21 @@ Widget.prototype.computeAttribute = function(attribute,options) {
value = [value];
}
} else if(attribute.type === "macro") {
var variableInfo = this.getVariableInfo(attribute.value.name,{params: attribute.value.params});
// Get the macro name
var macroName = attribute.value.attributes["$variable"].value;
// 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) {
value = variableInfo.resultList;
} else {
-10
View File
@@ -1,10 +0,0 @@
title: $:/palettes/AutoToggle
name: AutoToggle
description: Automatically switch between dark and light modes
tags: $:/tags/Palette
type: application/x-tiddler-dictionary
color-scheme: [{$:/info/browser/darkmode}!match[yes]then[light]else[dark]]
settings: $:/palettes/AutoToggle/Settings
palette-import@light: $:/palettes/TwentyTwenties
palette-import@dark: $:/palettes/TwentyTwentiesDark
category: 2026
-19
View File
@@ -1,19 +0,0 @@
title: $:/palettes/AutoToggle/Settings
\procedure set-imported-palette(field)
<$select field=<<field>>>
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Palette]sort[name]] -[<currentTiddler>]">
<option value=<<currentTiddler>>><$view field="name"><$view field="title"/></$view></option>
</$list>
</$select>
\end set-imported-palette
This palette can be used to automatically switch between two palettes based on the browser's dark mode setting.
<$tiddler tiddler={{$:/palette}}>
Light palette: <<set-imported-palette field:"palette-import@light">>
Dark palette: <<set-imported-palette field:"palette-import@dark">>
</$tiddler>
@@ -1,6 +1,5 @@
title: $:/palettes/Blanca
name: Blanca
category: Legacy
color-scheme: light
description: A clean white palette to let you focus
tags: $:/tags/Palette
@@ -1,6 +1,5 @@
title: $:/palettes/Blue
name: Blue
category: Legacy
color-scheme: light
description: A blue theme
tags: $:/tags/Palette
@@ -1,6 +1,5 @@
title: $:/palettes/Muted
name: Muted
category: Legacy
color-scheme: light
description: Bright tiddlers on a muted background
tags: $:/tags/Palette
@@ -1,6 +1,5 @@
title: $:/palettes/ContrastDark
name: Contrast (Dark)
category: Legacy
color-scheme: dark
description: High contrast and unambiguous (dark version)
tags: $:/tags/Palette
@@ -1,6 +1,5 @@
title: $:/palettes/ContrastLight
name: Contrast (Light)
category: Legacy
color-scheme: light
description: High contrast and unambiguous (light version)
tags: $:/tags/Palette
@@ -2,7 +2,6 @@ title: $:/palettes/CupertinoDark
tags: $:/tags/Palette
color-scheme: dark
name: Cupertino Dark
category: Legacy
description: A macOS inspired dark palette
type: application/x-tiddler-dictionary
@@ -2,7 +2,6 @@ created: 20150402111612188
description: Good with dark photo backgrounds
modified: 20150402112344080
name: DarkPhotos
category: Legacy
tags: $:/tags/Palette
title: $:/palettes/DarkPhotos
type: application/x-tiddler-dictionary
@@ -2,7 +2,6 @@ title: $:/palettes/DesertSand
tags: $:/tags/Palette
color-scheme: light
name: Desert Sand
category: Legacy
description: A desert sand palette
type: application/x-tiddler-dictionary
@@ -1,7 +1,6 @@
color-scheme: dark
description: An inky color scheme for prose and code
name: FlexokiDark
category: Legacy
tags: $:/tags/Palette
title: $:/palettes/FlexokiDark
type: application/x-tiddler-dictionary
@@ -1,6 +1,5 @@
title: $:/palettes/FlexokiLight
name: FlexokiLight
category: Legacy
description: An inky color scheme for prose and code
tags: $:/tags/Palette
type: application/x-tiddler-dictionary
@@ -1,6 +1,5 @@
title: $:/palettes/GruvboxDark
name: Gruvbox Dark
category: Legacy
color-scheme: dark
description: Retro groove color scheme
tags: $:/tags/Palette
@@ -1,6 +1,5 @@
title: $:/palettes/Nord
name: Nord
category: Legacy
color-scheme: dark
description: An arctic, north-bluish color palette.
tags: $:/tags/Palette
@@ -1,6 +1,5 @@
title: $:/palettes/Rocker
name: Rocker
category: Legacy
color-scheme: dark
description: A dark theme
tags: $:/tags/Palette
@@ -1,6 +1,5 @@
title: $:/palettes/SolarFlare
name: Solar Flare
category: Legacy
color-scheme: light
description: Warm, relaxing earth colours
tags: $:/tags/Palette
@@ -1,6 +1,5 @@
title: $:/palettes/SolarizedDark
tags: $:/tags/Palette
category: Legacy
type: application/x-tiddler-dictionary
description: Precision dark colors for machines and people
license: MIT, Ethan Schoonover, https://github.com/altercation/solarized/blob/master/LICENSE
@@ -4,7 +4,6 @@ type: application/x-tiddler-dictionary
description: Precision colors for machines and people
license: MIT, Ethan Schoonover, https://github.com/altercation/solarized/blob/master/LICENSE
name: SolarizedLight
category: Legacy
color-scheme: light
alert-background: #eee8d5
@@ -4,7 +4,6 @@ type: application/x-tiddler-dictionary
description: Cold, spartan day colors
name: Spartan Day
color-scheme: light
category: Legacy
alert-background: <<colour background>>
alert-border: <<colour very-muted-foreground>>
@@ -4,7 +4,6 @@ type: application/x-tiddler-dictionary
description: Dark spartan colors
name: Spartan Night
color-scheme: dark
category: Legacy
alert-background: <<colour background>>
alert-border: <<colour very-muted-foreground>>
-226
View File
@@ -1,226 +0,0 @@
title: $:/palettes/TwentyTwenties
name: TwentyTwenties
description: Modern and flexible
tags: $:/tags/Palette
type: application/x-tiddler-dictionary
color-scheme: light
settings: $:/palettes/TwentyTwenties/Settings
palette-import: $:/palettes/Vanilla
category: 2026
# Background and foreground colours, which are interpolated as required
base-paper: #FFFCF0
base-background: #edcec1
base-ink: #333344
?base-paper-ink: [tf.check-colour-contrast[base-paper],[base-ink],[45]]
?base-background-ink: [tf.check-colour-contrast[base-background],[base-ink],[45]]
# Primary colour, used for links and other accented elements
base-primary: #5778d8
?base-paper-primary: [tf.check-colour-contrast[base-paper],[base-primary],[45]]
?base-background-primary: [tf.check-colour-contrast[base-background],[base-primary],[45]]
# Secondary colour, used for alerts and other secondary elements
base-secondary: #f0e48a
?base-ink-secondary: [tf.check-colour-contrast[base-ink],[base-secondary],[45]]
# Tertiary base colour, used for monospaced text and other tertiary elements
base-tertiary: rgb(183, 95, 95)
?base-paper-tertiary: [tf.check-colour-contrast[base-paper],[base-tertiary],[45]]
# Basic spectrum colours
base-black: #100F0F
base-red: #D14D41
base-orange: #DA702C
base-yellow: #D0A215
base-green: #879A39
base-cyan: #3AA99F
base-blue: #4385BE
base-purple: #8B7EC8
base-magenta: #CE5D97
base-white: #FFFCF0
# Darker variants
# base-red: #AF3029
# base-orange: #BC5215
# base-yellow: #AD8301
# base-green: #66800B
# base-cyan: #24837B
# base-blue: #205EA6
# base-purple: #5E409D
# base-magenta: #A02F6F
# Palette definitions
alert-background: [tf.colour[base-secondary]]
alert-border: [tf.interpolate-colours[base-ink],[alert-background],[0.6]]
alert-highlight: [tf.interpolate-colours[base-ink],[base-primary],[0.3]]
alert-muted-foreground: [tf.interpolate-colours[base-ink],[alert-background],[0.4]]
background: [tf.colour[base-paper]]
blockquote-bar: [tf.colour[muted-foreground]]
button-background:
button-border:
button-foreground:
code-background: [tf.interpolate-colours[base-paper],[base-tertiary],[0.1]]
code-border: [tf.interpolate-colours[base-paper],[base-tertiary],[0.6]]
code-foreground: [tf.colour[base-tertiary]]
diff-delete-background: [tf.colour[base-red]]
diff-delete-foreground: [tf.colour[foreground]]
diff-equal-background:
diff-equal-foreground: [tf.colour[foreground]]
diff-insert-background: [tf.colour[base-green]]
diff-insert-foreground: [tf.colour[foreground]]
diff-invisible-background:
diff-invisible-foreground: [tf.colour[muted-foreground]]
dirty-indicator: [tf.colour[base-tertiary]]
download-background: [tf.interpolate-colours[base-paper],[base-green],[0.6]]
download-foreground: [tf.interpolate-colours[base-ink],[base-green],[0.1]]
dragger-background: [tf.colour[foreground]]
dragger-foreground: [tf.colour[background]]
dropdown-background: [tf.colour[background]]
dropdown-border: [tf.colour[muted-foreground]]
dropdown-tab-background-selected: [tf.colour[background]]
dropdown-tab-background: [tf.interpolate-colours[base-paper],[base-ink],[0.9]]
dropzone-background: [tf.colour[base-secondary]colour-set-alpha[0.7]]
external-link-background-hover: inherit
external-link-background-visited: inherit
external-link-background: inherit
external-link-foreground-hover: inherit
external-link-foreground-visited: [tf.colour[primary]]
external-link-foreground: [tf.colour[primary]]
footnote-target-background: [tf.interpolate-colours[base-paper],[base-ink],[0.2]]
foreground: [tf.colour[base-ink]]
highlight-background: [tf.interpolate-colours[base-paper],[base-yellow],[0.5]]
highlight-foreground: [tf.interpolate-colours[base-yellow],[base-ink],[0.8]]
menubar-background: #5778d8
menubar-foreground: #fff
message-background: [tf.interpolate-colours[base-paper],[base-blue],[0.2]]
message-border: [tf.interpolate-colours[base-blue],[base-ink],[0.5]]
message-foreground: [tf.interpolate-colours[base-blue],[base-ink],[0.8]]
modal-backdrop: [tf.colour[foreground]]
modal-background: [tf.colour[background]]
modal-border: #999999
modal-footer-background: #f5f5f5
modal-footer-border: #dddddd
modal-header-border: #eeeeee
muted-foreground: [tf.interpolate-colours[base-paper],[base-ink],[0.3]]
network-activity-foreground: #448844
notification-background: [tf.colour[base-tertiary]colour-set-oklch:l[0.9]]
notification-border: [tf.colour[base-tertiary]colour-set-oklch:l[0.2]]
page-background: [tf.colour[base-background]]
pre-background: [tf.interpolate-colours[base-paper],[base-tertiary],[0.1]]
pre-border: [tf.interpolate-colours[base-paper],[base-tertiary],[0.6]]
primary: [tf.colour[base-primary]]
select-tag-background:
select-tag-foreground:
selection-background:
selection-foreground:
sidebar-button-foreground: [tf.colour[sidebar-controls-foreground]]
sidebar-controls-foreground-hover: [tf.interpolate-colours[base-ink],[base-background],[0.2]]
sidebar-controls-foreground: [tf.interpolate-colours[base-ink],[base-background],[0.8]]
sidebar-foreground-shadow: inherit
sidebar-foreground: =[tf.colour[base-ink]] =[tf.colour[base-paper]] =[tf.colour[base-background]] +[colour-best-contrast:DeltaPhi[]]
sidebar-muted-foreground-hover: [tf.colour[sidebar-muted-foreground]colour-set-oklch:l[0.3]]
sidebar-muted-foreground: [tf.interpolate-colours[foreground],[page-background],[0.6]]
sidebar-tab-background-selected: [tf.colour[tab-background-selected]]
sidebar-tab-background: [tf.colour[tab-background]]
sidebar-tab-border-selected: [tf.colour[tab-border-selected]]
sidebar-tab-border: [tf.colour[tab-border]]
sidebar-tab-divider: [tf.colour[tab-divider]]
sidebar-tab-foreground-selected: [tf.colour[tab-foreground-selected]]
sidebar-tab-foreground: [tf.colour[tab-foreground]]
sidebar-tiddler-link-foreground-hover: [tf.colour[sidebar-tiddler-link-foreground]colour-set-oklch:l[0.5]]
sidebar-tiddler-link-foreground: =[tf.colour[base-primary]] =[tf.colour[base-secondary]] =[tf.colour[base-tertiary]] =[tf.colour[base-background]] +[colour-best-contrast:DeltaPhi[]]
site-title-foreground: [tf.colour[tiddler-title-foreground]]
stability-deprecated: #ff0000
stability-experimental: #c07c00
stability-legacy: #0000ff
stability-stable: #008000
static-alert-foreground: #aaaaaa
tab-background-selected: [tf.colour[background]]
tab-background: [tf.interpolate-colours[base-paper],[base-ink],[0.2]]
tab-border-selected: [tf.colour[muted-foreground]]
tab-border: [tf.colour[muted-foreground]]
tab-divider: [tf.colour[muted-foreground]]
tab-foreground-selected: [tf.colour[tab-foreground]]
tab-foreground: [tf.colour[foreground]]
table-border: [tf.colour[foreground]]
table-footer-background: [tf.interpolate-colours[background],[foreground],[0.2]]
table-header-background: [tf.interpolate-colours[background],[foreground],[0.1]]
tag-background: [tf.interpolate-colours[base-paper],[base-yellow],[0.9]]
tag-foreground: [tf.interpolate-colours[base-yellow],[base-ink],[0.8]]
testcase-accent-level-1: #c1eaff
testcase-accent-level-2: #E3B740
testcase-accent-level-3: #5FD564
tiddler-background: [tf.colour[background]]
tiddler-border: [tf.interpolate-colours[base-paper],[base-background],[0.5]]
tiddler-controls-foreground-hover: [tf.interpolate-colours[background],[foreground],[0.7]]
tiddler-controls-foreground-selected: [tf.interpolate-colours[background],[foreground],[0.9]]
tiddler-controls-foreground: [tf.interpolate-colours[background],[foreground],[0.5]]
tiddler-editor-background: #f8f8f8
tiddler-editor-border-image: #ffffff
tiddler-editor-border: #cccccc
tiddler-editor-fields-even: #e0e8e0
tiddler-editor-fields-odd: #f0f4f0
tiddler-info-background: #f8f8f8
tiddler-info-border: #dddddd
tiddler-info-tab-background: #f8f8f8
tiddler-link-background: [tf.colour[background]]
tiddler-link-foreground: [tf.colour[primary]]
tiddler-subtitle-foreground: [tf.interpolate-colours[background],[foreground],[0.6]]
tiddler-title-foreground: [tf.interpolate-colours[background],[foreground],[0.9]]
toolbar-cancel-button:
toolbar-close-button:
toolbar-delete-button:
toolbar-done-button:
toolbar-edit-button:
toolbar-info-button:
toolbar-new-button:
toolbar-options-button:
toolbar-save-button:
tour-chooser-button-foreground: <<colour very-muted-foreground>>
tour-chooser-button-hover-background: <<colour muted-foreground>>
tour-chooser-button-hover-foreground: : <<colour background>>
tour-chooser-button-selected-background: <<colour primary>>
tour-chooser-button-selected-foreground: <<colour background>>
tour-chooser-dropdown-foreground: <<colour very-muted-foreground>>
tour-chooser-item-background: <<colour background>>
tour-chooser-item-border: <<colour muted-foreground>>
tour-chooser-item-foreground: <<colour foreground>>
tour-chooser-item-shadow: <<colour muted-foreground>>
tour-chooser-item-start-background: <<colour download-background>>
tour-chooser-item-start-foreground: <<colour background>>
tour-chooser-item-start-hover-background: <<colour primary>>
tour-chooser-item-start-hover-foreground: <<colour background>>
tour-fullscreen-background: <<colour page-background>>
tour-fullscreen-controls-foreground: <<colour muted-foreground>>
tour-navigation-buttons-back-background: red
tour-navigation-buttons-back-foreground: white
tour-navigation-buttons-hint-background: purple
tour-navigation-buttons-hint-foreground: white
tour-navigation-buttons-hover-background: <<colour foreground>>
tour-navigation-buttons-hover-foreground: <<colour background>>
tour-navigation-buttons-next-background: purple
tour-navigation-buttons-next-foreground: white
tour-overlay-background: #cbfff8
tour-overlay-border: #228877
tour-step-heading-background: none
tour-step-task-background: <<colour download-background>>
tour-step-task-foreground: <<colour download-foreground>>
untagged-background: #999999
very-muted-foreground: #888888
wikilist-background: #e5e5e5
wikilist-button-background: #acacac
wikilist-button-foreground: #000000
wikilist-button-open-hover: green
wikilist-button-open: #4fb82b
wikilist-button-remove-hover: red
wikilist-button-remove: #d85778
wikilist-button-reveal-hover: blue
wikilist-button-reveal: #5778d8
wikilist-droplink-dragover: [tf.colour[base-secondary]colour-set-alpha[0.7]]
wikilist-info: #000000
wikilist-item: #ffffff
wikilist-title-svg: [tf.colour[wikilist-title]]
wikilist-title: #666666
wikilist-toolbar-background: #d3d3d3
wikilist-toolbar-foreground: #888888
wikilist-url: #aaaaaa
-12
View File
@@ -1,12 +0,0 @@
title: $:/palettes/TwentyTwenties/Dark
name: TwentyTwenties Dark
description: Modern and flexible, Darkish
tags: $:/tags/Palette
type: application/x-tiddler-dictionary
color-scheme: dark
palette-import: $:/palettes/TwentyTwenties
category: 2026
base-paper: #111122
base-background: #f5f0f9
base-ink: #8C8F80
-12
View File
@@ -1,12 +0,0 @@
title: $:/palettes/TwentyTwenties/Green
name: TwentyTwenties (Green)
description: Modern and flexible, Greenish
tags: $:/tags/Palette
type: application/x-tiddler-dictionary
color-scheme: light
palette-import: $:/palettes/TwentyTwenties
category: 2026
base-paper: rgb(188, 255, 161)
base-background: rgb(94, 192, 145)
base-primary: #6e803c
-13
View File
@@ -1,13 +0,0 @@
title: $:/palettes/TwentyTwenties/GreenP3
name: TwentyTwenties (Green P3)
description: Modern and flexible, Greenish and super bright
tags: $:/tags/Palette
type: application/x-tiddler-dictionary
color-scheme: light
palette-import: $:/palettes/TwentyTwenties
category: 2026
base-paper: color(display-p3 0.281 1 0.584 / 1)
base-background: color(display-p3 1 1 0 / 1)
base-primary: color(display-p3 1 0.563 1 / 1)
-17
View File
@@ -1,17 +0,0 @@
title: $:/palettes/TwentyTwenties/Settings
\procedure entry(name,description)
<$text text=<<description>>/>: <$edit-text tiddler={{$:/palette}} index=<<name>> type="color" tag="input" default={{{ [function[colour],<name>] }}}/>
\end entry
<<entry name:"base-paper" description:"Paper">>
<<entry name:"base-background" description:"Page background">>
<<entry name:"base-ink" description:"Ink">>
<<entry name:"base-primary" description:"Primary">>
<<entry name:"base-secondary" description:"Secondary">>
<<entry name:"base-tertiary" description:"Tertiary">>
@@ -5,7 +5,6 @@ type: application/x-tiddler-dictionary
name: Twilight
description: Delightful, soft darkness.
color-scheme: dark
category: Legacy
alert-background: rgb(255, 255, 102)
alert-border: rgb(232, 232, 125)
@@ -4,7 +4,6 @@ description: Pale and unobtrusive
tags: $:/tags/Palette
type: application/x-tiddler-dictionary
color-scheme: light
category: Legacy
alert-background: #ffe476
alert-border: #b99e2f
-12
View File
@@ -1,12 +0,0 @@
title: $:/palettes/VanillaCherry
name: Vanilla Cherry
category: 2026
description: Pale and unobtrusive with a cherry on top
tags: $:/tags/Palette
type: application/x-tiddler-dictionary
color-scheme: light
palette-import: $:/palettes/Vanilla
primary:rgb(224, 32, 86);
menubar-foreground: #fff
menubar-background: <<colour primary>>
@@ -1,7 +0,0 @@
title: $:/palettes/background/contrast-tests
type: application/x-tiddler-dictionary
tags: $:/tags/BackgroundPalette
?background-foreground-contrast: [tf.check-colour-contrast[background],[foreground],[45]]
?alert-contrast: [tf.check-colour-contrast[alert-background],[foreground],[45]]
?code-contrast: [tf.check-colour-contrast[code-background],[code-foreground],[45]]
+1 -1
View File
@@ -6,5 +6,5 @@ caption: {{$:/language/ControlPanel/Appearance/Caption}}
{{$:/language/ControlPanel/Appearance/Hint}}
<div class="tc-control-panel">
<$macrocall $name="tabs" tabsList="[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Appearance]!has[draft.of]]" default="$:/core/ui/ControlPanel/Palette" explicitState="$:/state/tab--1963855381"/>
<$macrocall $name="tabs" tabsList="[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Appearance]!has[draft.of]]" default="$:/core/ui/ControlPanel/Theme" explicitState="$:/state/tab--1963855381"/>
</div>
+17 -1
View File
@@ -2,4 +2,20 @@ title: $:/core/ui/ControlPanel/Palette
tags: $:/tags/ControlPanel/Appearance
caption: {{$:/language/ControlPanel/Palette/Caption}}
{{$:/PaletteManager}}
\define lingo-base() $:/language/ControlPanel/Palette/
{{$:/snippets/paletteswitcher}}
<$reveal type="nomatch" state="$:/state/ShowPaletteEditor" text="yes">
<$button set="$:/state/ShowPaletteEditor" setTo="yes"><<lingo ShowEditor/Caption>></$button>
</$reveal>
<$reveal type="match" state="$:/state/ShowPaletteEditor" text="yes">
<$button set="$:/state/ShowPaletteEditor" setTo="no"><<lingo HideEditor/Caption>></$button>
{{$:/PaletteManager}}
</$reveal>
+1
View File
@@ -46,6 +46,7 @@ tags: $:/tags/EditTemplate
<$list filter="[<currentTiddler>get<tagField>enlist-input[]sort[title]]" storyview="pop">
<$macrocall $name="tag-body"
colour={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}
palette={{$:/palette}}
icon={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]!is[draft]get[text]] }}}
tagField=<<tagField>>
/>
-94
View File
@@ -1,94 +0,0 @@
title: $:/PaletteEditor
\define lingo-base() $:/language/ControlPanel/Palette/Editor/
\define describePaletteColour(colour)
<$transclude tiddler="$:/language/Docs/PaletteColours/$colour$"><$text text="$colour$"/></$transclude>
\end
\define edit-colour-placeholder()
edit $(colourName)$
\end
\define colour-tooltip(showhide) $showhide$ editor for $(newColourName)$
\define resolve-colour(macrocall)
\import $:/core/macros/utils
\whitespace trim
<$wikify name="name" text="""$macrocall$""">
<<name>>
</$wikify>
\end
\define delete-colour-index-actions() <$action-setfield $index=<<colourName>>/>
\define palette-manager-colour-row-segment()
\whitespace trim
<$edit-text index=<<colourName>> tag="input" placeholder=<<edit-colour-placeholder>> default=""/>
<br>
<$edit-text index=<<colourName>> type="color" tag="input" class="tc-palette-manager-colour-input"/>
<$list filter="[<currentTiddler>getindex<colourName>removeprefix[<<]removesuffix[>>]] [<currentTiddler>getindex<colourName>removeprefix[<$]removesuffix[/>]]" variable="ignore">
<$set name="state" value={{{ [[$:/state/palettemanager/]addsuffix<currentTiddler>addsuffix[/]addsuffix<colourName>] }}}>
<$wikify name="newColourName" text="""<$macrocall $name="resolve-colour" macrocall={{{ [<currentTiddler>getindex<colourName>] }}}/>""">
<$reveal state=<<state>> type="nomatch" text="show">
<$button tooltip=<<colour-tooltip show>> aria-label=<<colour-tooltip show>> class="tc-btn-invisible" set=<<state>> setTo="show">{{$:/core/images/down-arrow}}<$text text=<<newColourName>> class="tc-small-gap-left"/></$button><br>
</$reveal>
<$reveal state=<<state>> type="match" text="show">
<$button tooltip=<<colour-tooltip hide>> aria-label=<<colour-tooltip show>> class="tc-btn-invisible" actions="""<$action-deletetiddler $tiddler=<<state>>/>""">{{$:/core/images/up-arrow}}<$text text=<<newColourName>> class="tc-small-gap-left"/></$button><br>
</$reveal>
<$reveal state=<<state>> type="match" text="show">
<$set name="colourName" value=<<newColourName>>>
<br>
<<palette-manager-colour-row-segment>>
<br><br>
</$set>
</$reveal>
</$wikify>
</$set>
</$list>
\end
\define palette-manager-colour-row()
\whitespace trim
<tr>
<td>
<span style="float:right;">
<$button tooltip={{$:/language/ControlPanel/Palette/Editor/Delete/Hint}} aria-label={{$:/language/ControlPanel/Palette/Editor/Delete/Hint}} class="tc-btn-invisible" actions=<<delete-colour-index-actions>>>
{{$:/core/images/delete-button}}</$button>
</span>
''<$macrocall $name="describePaletteColour" colour=<<colourName>>/>''<br/>
<$macrocall $name="colourName" $output="text/plain"/>
</td>
<td>
<<palette-manager-colour-row-segment>>
</td>
</tr>
\end
\define palette-manager-table()
\whitespace trim
<table>
<tbody>
<$set name="colorList" filter="[{$:/state/palettemanager/showexternal}match[yes]]"
value="[all[shadows+tiddlers]tag[$:/tags/Palette]indexes[]]" emptyValue="[<currentTiddler>indexes[]]">
<$list filter=<<colorList>> variable="colourName"> <<palette-manager-colour-row>> </$list>
</$set>
</tbody>
</table>
\end
\whitespace trim
<$set name="currentTiddler" value={{$:/palette}}>
<<lingo Prompt>>&#32;<$link to={{$:/palette}}><$macrocall $name="currentTiddler" $output="text/plain"/></$link>
<$list filter="[all[current]is[shadow]is[tiddler]]" variable="listItem">
<<lingo Prompt/Modified>>
&#32;
<$button message="tm-delete-tiddler" param={{$:/palette}}><<lingo Reset/Caption>></$button>
</$list>
<$list filter="[all[current]is[shadow]!is[tiddler]]" variable="listItem">
<<lingo Clone/Prompt>>
</$list>
<$button message="tm-new-tiddler" param={{$:/palette}}><<lingo Clone/Caption>></$button>
<$checkbox tiddler="$:/state/palettemanager/showexternal" field="text" checked="yes" unchecked="no"><span class="tc-small-gap-left"><<lingo Names/External/Show>></span></$checkbox>
<<palette-manager-table>>
+87 -36
View File
@@ -1,43 +1,94 @@
title: $:/PaletteManager
\define lingo-base() $:/language/ControlPanel/Palette/
\define lingo-base() $:/language/ControlPanel/Palette/Editor/
\define describePaletteColour(colour)
<$transclude tiddler="$:/language/Docs/PaletteColours/$colour$"><$text text="$colour$"/></$transclude>
\end
\define edit-colour-placeholder()
edit $(colourName)$
\end
\define colour-tooltip(showhide) $showhide$ editor for $(newColourName)$
<!-- Used by the language string CustomSettings/Prompt -->
\procedure palette-link()
<$tiddler tiddler={{$:/palette}}>
<$link to={{!!title}}>
<$view field="name" format="text">
<$view field="title" format="text"/>
</$view>
</$link>
</$tiddler>
\end palette-link
<$transclude $tiddler="$:/snippets/paletteswitcher" thumbnails="yes"/>
{{$:/snippets/palettetests}}
<$let
paletteSettings={{{ [[$:/temp/palette-consolidated]get[settings]] }}}
>
<%if [<paletteSettings>!match[]] %>
<div>
<<lingo CustomSettings/Prompt>>
<$transclude $tiddler=<<paletteSettings>> $mode="block"/>
</div>
<%endif%>
</$let>
<$reveal type="nomatch" state="$:/state/ShowPaletteEditor" text="yes">
<$button set="$:/state/ShowPaletteEditor" setTo="yes"><<lingo ShowEditor/Caption>></$button>
\define resolve-colour(macrocall)
\import $:/core/macros/utils
\whitespace trim
<$wikify name="name" text="""$macrocall$""">
<<name>>
</$wikify>
\end
\define delete-colour-index-actions() <$action-setfield $index=<<colourName>>/>
\define palette-manager-colour-row-segment()
\whitespace trim
<$edit-text index=<<colourName>> tag="input" placeholder=<<edit-colour-placeholder>> default=""/>
<br>
<$edit-text index=<<colourName>> type="color" tag="input" class="tc-palette-manager-colour-input"/>
<$list filter="[<currentTiddler>getindex<colourName>removeprefix[<<]removesuffix[>>]] [<currentTiddler>getindex<colourName>removeprefix[<$]removesuffix[/>]]" variable="ignore">
<$set name="state" value={{{ [[$:/state/palettemanager/]addsuffix<currentTiddler>addsuffix[/]addsuffix<colourName>] }}}>
<$wikify name="newColourName" text="""<$macrocall $name="resolve-colour" macrocall={{{ [<currentTiddler>getindex<colourName>] }}}/>""">
<$reveal state=<<state>> type="nomatch" text="show">
<$button tooltip=<<colour-tooltip show>> aria-label=<<colour-tooltip show>> class="tc-btn-invisible" set=<<state>> setTo="show">{{$:/core/images/down-arrow}}<$text text=<<newColourName>> class="tc-small-gap-left"/></$button><br>
</$reveal>
<$reveal type="match" state="$:/state/ShowPaletteEditor" text="yes">
<$button set="$:/state/ShowPaletteEditor" setTo="no"><<lingo HideEditor/Caption>></$button>
{{$:/PaletteEditor}}
<$reveal state=<<state>> type="match" text="show">
<$button tooltip=<<colour-tooltip hide>> aria-label=<<colour-tooltip show>> class="tc-btn-invisible" actions="""<$action-deletetiddler $tiddler=<<state>>/>""">{{$:/core/images/up-arrow}}<$text text=<<newColourName>> class="tc-small-gap-left"/></$button><br>
</$reveal>
<$reveal state=<<state>> type="match" text="show">
<$set name="colourName" value=<<newColourName>>>
<br>
<<palette-manager-colour-row-segment>>
<br><br>
</$set>
</$reveal>
</$wikify>
</$set>
</$list>
\end
\define palette-manager-colour-row()
\whitespace trim
<tr>
<td>
<span style="float:right;">
<$button tooltip={{$:/language/ControlPanel/Palette/Editor/Delete/Hint}} aria-label={{$:/language/ControlPanel/Palette/Editor/Delete/Hint}} class="tc-btn-invisible" actions=<<delete-colour-index-actions>>>
{{$:/core/images/delete-button}}</$button>
</span>
''<$macrocall $name="describePaletteColour" colour=<<colourName>>/>''<br/>
<$macrocall $name="colourName" $output="text/plain"/>
</td>
<td>
<<palette-manager-colour-row-segment>>
</td>
</tr>
\end
\define palette-manager-table()
\whitespace trim
<table>
<tbody>
<$set name="colorList" filter="[{$:/state/palettemanager/showexternal}match[yes]]"
value="[all[shadows+tiddlers]tag[$:/tags/Palette]indexes[]]" emptyValue="[<currentTiddler>indexes[]]">
<$list filter=<<colorList>> variable="colourName"> <<palette-manager-colour-row>> </$list>
</$set>
</tbody>
</table>
\end
\whitespace trim
<$set name="currentTiddler" value={{$:/palette}}>
<<lingo Prompt>>&#32;<$link to={{$:/palette}}><$macrocall $name="currentTiddler" $output="text/plain"/></$link>
<$list filter="[all[current]is[shadow]is[tiddler]]" variable="listItem">
<<lingo Prompt/Modified>>
&#32;
<$button message="tm-delete-tiddler" param={{$:/palette}}><<lingo Reset/Caption>></$button>
</$list>
<$list filter="[all[current]is[shadow]!is[tiddler]]" variable="listItem">
<<lingo Clone/Prompt>>
</$list>
<$button message="tm-new-tiddler" param={{$:/palette}}><<lingo Clone/Caption>></$button>
<$checkbox tiddler="$:/state/palettemanager/showexternal" field="text" checked="yes" unchecked="no"><span class="tc-small-gap-left"><<lingo Names/External/Show>></span></$checkbox>
<<palette-manager-table>>
-19
View File
@@ -1,19 +0,0 @@
title: $:/core/ui/Palettes/Preview/Alert
tags: $:/tags/Preview/Page
\whitespace trim
<div class="tc-palette-preview-thumbnail-alert" style.background-color=<<colour alert-background>>>
<div class="tc-palette-preview-thumbnail-alert-border" style.border-color=<<colour alert-border>>>
<div style.color=<<colour foreground>>>
<div class="tc-palette-preview-thumbnail-alert-subtitle" style.color=<<colour alert-muted-foreground>>>
Lorem Ipsum
<div class="tc-palette-preview-thumbnail-alert-highlight" style.color=<<colour alert-highlight>>>
(Count: 1)
</div>
</div>
<div class="tc-palette-preview-thumbnail-alert-body">
Lorem Ipsum Dolor Sit Amet Consectetur Adipiscing Elit Sed Do Eiusmod Tempor Incididunt.
</div>
</div>
</div>
</div>
-55
View File
@@ -1,55 +0,0 @@
title: $:/core/ui/Palettes/Preview/Helpers
tags: $:/tags/Preview/Helpers
\whitespace trim
\procedure palette-preview-component-list(tag)
<$list filter="[all[shadows+tiddlers]tag<tag>!has[draft.of]]" variable="componentTitle">
<$transclude $tiddler=<<componentTitle>> title=<<title>>/>
</$list>
\end palette-preview-component-list
\procedure tab-set(tabTitles,colourPrefix:"")
<div class="tc-palette-preview-thumbnail-tab-set">
<div class="tc-palette-preview-thumbnail-tab-buttons">
<$list filter="[enlist<tabTitles>]" variable="tabTitle" counter="tabIndex">
<%if [<tabIndex>match[1]] %>
<span
class="tc-palette-preview-thumbnail-tab-button"
style.border-color={{{ [<colourPrefix>addsuffix[tab-border-selected]] :map[function[colour],<currentTiddler>] }}}
style.color={{{ [<colourPrefix>addsuffix[tab-foreground-selected]] :map[function[colour],<currentTiddler>] }}}
style.background-color={{{ [<colourPrefix>addsuffix[tab-background-selected]] :map[function[colour],<currentTiddler>] }}}
>
<$text text=<<tabTitle>>/>
</span>
<%else%>
<span
class="tc-palette-preview-thumbnail-tab-button"
style.border-color={{{ [<colourPrefix>addsuffix[tab-border]] :map[function[colour],<currentTiddler>] }}}
style.color={{{ [<colourPrefix>addsuffix[tab-foreground]] :map[function[colour],<currentTiddler>] }}}
style.background-color={{{ [<colourPrefix>addsuffix[tab-background]] :map[function[colour],<currentTiddler>] }}}
>
<$text text=<<tabTitle>>/>
</span>
<%endif%>
</$list>
</div>
<div
class="tc-palette-preview-thumbnail-tab-divider"
style.border-color={{{ [<colourPrefix>addsuffix[tab-divider]] :map[function[colour],<currentTiddler>] }}}
>
</div>
</div>
\end tab-set
\procedure link(text)
<span class="tc-palette-preview-thumbnail-tiddler-link" style.color=<<colour primary>>>
<$text text=<<text>>/>
</span>
\end link
\procedure sidebar-link(text)
<span class="tc-palette-preview-thumbnail-tiddler-link" style.color=<<colour sidebar-tiddler-link-foreground>>>
<$text text=<<text>>/>
</span>
\end sidebar-link
-11
View File
@@ -1,11 +0,0 @@
title: $:/core/ui/Palettes/Preview/Notification
tags: $:/tags/Preview/PageOptional
\whitespace trim
<div class="tc-palette-preview-thumbnail-notification" style.background-color=<<colour notification-background>>>
<div class="tc-palette-preview-thumbnail-notification-border" style.border-color=<<colour notification-border>>>
<div class="tc-palette-preview-thumbnail-notification-body" style.color=<<colour foreground>>>
Lorem Ipsum Dolor Sit Amet Consectetur
</div>
</div>
</div>
@@ -1,8 +0,0 @@
title: $:/core/ui/Palettes/Preview/Sidebar/Search
tags: $:/tags/Preview/SideBar
\whitespace trim
<div class="tc-palette-preview-thumbnail-sidebar-search" style.background-color=<<colour background>>>
<div class="tc-palette-preview-thumbnail-sidebar-search-box">
</div>
</div>
@@ -1,7 +0,0 @@
title: $:/core/ui/Palettes/Preview/Sidebar/Subtitle
tags: $:/tags/Preview/SideBar
\whitespace trim
<div class="tc-palette-preview-thumbnail-sidebar-subtitle">
a non-linear personal web notebook
</div>
-18
View File
@@ -1,18 +0,0 @@
title: $:/core/ui/Palettes/Preview/Sidebar/Tabs
tags: $:/tags/Preview/SideBar
\whitespace trim
\procedure recent-links()
HelloThere Community Portal GettingStarted Development Download Filters Palettes Plugins Macros Templates Themes Stylesheets SystemTiddlers
\end recent-links
<<tab-set "Magna Placerat Ligula Imperdiet" "sidebar-">>
<div class="tc-palette-preview-thumbnail-sidebar-list">
<$list filter="[enlist<recent-links>]">
<div>
<$transclude $variable="sidebar-link" text=<<currentTiddler>>/>
</div>
</$list>
</div>
@@ -1,7 +0,0 @@
title: $:/core/ui/Palettes/Preview/Sidebar/Title
tags: $:/tags/Preview/SideBar
\whitespace trim
<div class="tc-palette-preview-thumbnail-sidebar-title" style.color=<<colour site-title-foreground>>>
~TiddlyWiki
</div>
-7
View File
@@ -1,7 +0,0 @@
title: $:/core/ui/Palettes/Preview/SideBar
tags: $:/tags/Preview/Page
\whitespace trim
<div class="tc-palette-preview-thumbnail-sidebar" style.color=<<colour sidebar-foreground>>>
<<palette-preview-component-list "$:/tags/Preview/SideBar">>
</div>
-9
View File
@@ -1,9 +0,0 @@
title: $:/core/ui/Palettes/Preview/Story
tags: $:/tags/Preview/Page
\whitespace trim
<div class="tc-palette-preview-thumbnail-story">
<$list filter="HelloThere GettingStarted" variable="title">
<<palette-preview-component-list "$:/tags/Preview/Story">>
</$list>
</div>
-10
View File
@@ -1,10 +0,0 @@
title: $:/core/ui/Palettes/Preview/Tiddler
tags: $:/tags/Preview/Story
\parameters (title)
\whitespace trim
<div class="tc-palette-preview-thumbnail-tiddler-border" style.border-color=<<colour tiddler-border>>>
<div class="tc-palette-preview-thumbnail-tiddler" style.background-color=<<colour tiddler-background>>>
<<palette-preview-component-list "$:/tags/Preview/Tiddler">>
</div>
</div>
-15
View File
@@ -1,15 +0,0 @@
title: $:/core/ui/Palettes/Preview/Tiddler/Body
tags: $:/tags/Preview/Tiddler
\whitespace trim
<div class="tc-palette-preview-thumbnail-tiddler-body" style.color=<<colour foreground>>>
<%if [<title>match[HelloThere]] %>
Lorem ipsum dolor sit amet, <<link "consectetur adipiscing elit">>. Cras non arcu ultricies, egestas odio tempus, vestibulum ipsum. Praesent diam lorem, elementum in venenatis eget, tincidunt quis lacus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam efficitur velit tortor, sit amet tristique felis viverra sit amet. <<link "Nullam posuere facilisis purus sed">> consectetur. Integer vel elit euismod, posuere ligula et, dictum tellus. Donec in odio diam. Sed metus magna, placerat at ligula et, imperdiet sagittis ex.
<%else%>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<<tab-set "Sed Metus Magna Placerat Ligula Imperdiet">>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras non arcu ultricies, egestas odio tempus, vestibulum ipsum. Praesent diam lorem, elementum in venenatis eget, tincidunt quis lacus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.
<%endif%>
</div>
@@ -1,14 +0,0 @@
title: $:/core/ui/Palettes/Preview/Tiddler/Header
tags: $:/tags/Preview/Tiddler
\whitespace trim
<div class="tc-palette-preview-thumbnail-tiddler-header">
<div class="tc-palette-preview-thumbnail-tiddler-title" style.color=<<colour tiddler-title-foreground>>>
<$text text=<<title>>/>
</div>
<div class="tc-palette-preview-thumbnail-tiddler-toolbar" style.fill=<<colour tiddler-controls-foreground>>>
{{$:/core/images/down-arrow}}
{{$:/core/images/edit-button}}
{{$:/core/images/close-button}}
</div>
</div>
@@ -1,7 +0,0 @@
title: $:/core/ui/Palettes/Preview/Tiddler/Subtitle
tags: $:/tags/Preview/Tiddler
\whitespace trim
<div class="tc-palette-preview-thumbnail-tiddler-subtitle" style.color=<<colour tiddler-subtitle-foreground>>>
Motovun Jack
</div>
@@ -1,11 +0,0 @@
title: $:/core/ui/Palettes/ViewTemplateBody
<div style.width="220px">
{{||$:/snippets/currpalettepreview}}
</div>
''<$view field="name" format="text"/>''
<br>
<$view field="description" format="text"/>
+1
View File
@@ -7,6 +7,7 @@ title: $:/core/ui/TagTemplate
tag=<<currentTiddler>>
icon={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]!is[draft]get[text]] }}}
colour={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}
palette={{$:/palette}}
element-tag="$button"
element-attributes="""popup=<<qualify "$:/state/popup/tag">> dragFilter="[subfilter{$:/core/config/TagPillDragFilter}]" tag='span'"""
/>
@@ -1,7 +0,0 @@
title: $:/core/background-actions/AutoCompilePalette
tags: $:/tags/BackgroundAction $:/tags/StartupAction
platforms: browser
track-filter: [{$:/palette}get[color-scheme]] :map[subfilter<currentTiddler>] [{$:/palette}changecount[]addprefix{$:/palette}] [[$:/palette]changecount[]]
\import [subfilter{$:/core/config/GlobalImportFilter}]
<<actions-recompile-current-palette>>
@@ -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
@@ -10,5 +10,4 @@ code-body: [field:code-body[yes]then[$:/core/ui/ViewTemplate/body/code]]
import: [field:plugin-type[import]then[$:/core/ui/ViewTemplate/body/import]]
plugin: [has[plugin-type]then[$:/core/ui/ViewTemplate/body/plugin]]
hide-body: [field:hide-body[yes]then[$:/core/ui/ViewTemplate/body/blank]]
palette: [tag[$:/tags/Palette]then[$:/core/ui/Palettes/ViewTemplateBody]]
default: [[$:/core/ui/ViewTemplate/body/default]]
+49 -9
View File
@@ -1,12 +1,52 @@
title: $:/snippets/currpalettepreview
\define resolve-colour(macrocall)
\import $:/core/macros/utils
\whitespace trim
\import [all[shadows+tiddlers]tag[$:/tags/Preview/Helpers]!is[draft]sort[title]]
<!-- currentTiddler is the palette to use -->
<$palette.preview paletteTitle=<<currentTiddler>>>
<div class="tc-palette-preview-thumbnail" style.background-color=<<colour page-background>>>
<<palette-preview-component-list tag:"$:/tags/Preview/Page">>
</div>
</$palette.preview>
<$wikify name="name" text="""$macrocall$""">
<<name>>
</$wikify>
\end
\define swatchStyle()
background-color: $(swatchColour)$;
\end
\define swatch-inner()
\whitespace trim
<$set name="swatchColour" value={{##$(colourResolved)$}}>
<$list filter="[<swatchColour>!prefix[<<colour ]!suffix[>>]]" variable="ignore">
<div class="tc-swatch" style=<<swatchStyle>> title=<<swatchTitle>>/>
&#32;
</$list>
<$list filter="[<swatchColour>prefix[<<colour ]suffix[>>]]" variable="ignore">
<$wikify name="colourResolved" text="<$macrocall $name='resolve-colour' macrocall=<<swatchColour>>/>">
<<swatch-inner>>
</$wikify>
</$list>
</$set>
\end
\define swatch()
\whitespace trim
<$set name="swatchColour" value={{##$(colour)$}}>
<$set name="swatchTitle" value=<<colour>>>
<$list filter="[<swatchColour>!prefix[<<colour ]!suffix[>>]]" variable="ignore">
<div class="tc-swatch" style=<<swatchStyle>> title=<<swatchTitle>>/>
&#32;
</$list>
<$list filter="[<swatchColour>prefix[<<colour ]suffix[>>]]" variable="ignore">
<$wikify name="colourResolved" text="<$macrocall $name='resolve-colour' macrocall=<<swatchColour>>/>">
<<swatch-inner>>
</$wikify>
</$list>
</$set>
</$set>
\end
\whitespace trim
<div class="tc-swatches-horiz"><$list filter="
foreground
background
muted-foreground
primary
page-background
tab-background
tiddler-info-background
" variable="colour"><<swatch>></$list></div>
+10 -150
View File
@@ -1,157 +1,17 @@
title: $:/core/macros/CSS
tags: $:/tags/Macro
\procedure actions-compile-palette-filtered(consolidatedPalette,outputPalette)
<!-- Note the join, needed to cope with palette entries containing spaces -->
\function tf.colour(name) [<consolidatedPalette>getindex<name>] :else[[$:/config/DefaultColourMappings/]addsuffix<name>get[text]] :map[tf.colour-inner-transform-classic-palette-entry<currentTiddler>] :map[subfilter:all<currentTiddler>join[ ]]
\function colour(name) [tf.colour<name>]
\function color(name) [tf.colour<name>]
<!-- Make the colour function use the input palette -->
<$list filter="[<consolidatedPalette>indexes[]sort[]]" variable="colour-name">
<$let filter-text={{{ [<consolidatedPalette>getindex<colour-name>] :else[[$:/config/DefaultColourMappings/]addsuffix<colour-name>get[text]] :map[tf.colour-inner-transform-classic-palette-entry<currentTiddler>] }}}>
<!-- Note the join, needed to cope with palette entries containing spaces -->
<$action-setfield $tiddler=<<outputPalette>> $index=<<colour-name>> $value={{{ [subfilter:all<filter-text>join[ ]] +[join[ ]] }}}/>
</$let>
</$list>
\end actions-compile-palette-filtered
<!-- Needs to stay that way for backwards compatibility. See GH issue: #8326 -->
\define colour(name)
\whitespace trim
<$transclude tiddler={{$:/palette}} index="$name$">
<$transclude tiddler="$:/palettes/Vanilla" index="$name$">
<$transclude tiddler="$:/config/DefaultColourMappings/$name$"/>
</$transclude>
</$transclude>
\end
\procedure actions-compile-palette-import(inputPalette,outputPalette,exclusions:"",scheme)
<%if [enlist<exclusions>!match<inputPalette>count[]] :map[enlist<exclusions>count[]compare:number:eq<currentTiddler>] +[!match[]] %>
<$set name="exclusions" filter="[enlist<exclusions>] [<inputPalette>]">
<!-- Recursively import any imported palette -->
<$let
prefixed-palette-import={{{ [[palette-import@]addsuffix<scheme>] }}}
inputPalette={{{ [<inputPalette>get<prefixed-palette-import>has[title]] :else[<inputPalette>get[palette-import]] }}}
>
<%if [<inputPalette>has[title]] %>
<$transclude $variable="actions-compile-palette-import" inputPalette=<<inputPalette>> outputPalette=<<outputPalette>> exclusions=<<exclusions>> scheme=<<scheme>>/>
<%endif%>
</$let>
<!-- Copy the suffixed palette entries with the suffix stripped -->
<%if [<scheme>!is[blank]] %>
<$let
prefixed-scheme={{{ [<scheme>addprefix[@]] }}}
>
<$action-setmultiplefields $tiddler=<<outputPalette>> $indexes="[<inputPalette>indexes[]suffix<prefixed-scheme>removesuffix<prefixed-scheme>sort[]]" $values="[<inputPalette>indexes[]suffix<prefixed-scheme>sort[]] :map[<inputPalette>getindex<currentTiddler>]"/>
</$let>
<%endif%
<!-- Copy the unsuffixed palette entries -->
<$action-setmultiplefields $tiddler=<<outputPalette>> $indexes="[<inputPalette>indexes[]!regexp[@]sort[]]" $values="[<inputPalette>indexes[]!regexp[@]sort[]] :map[<inputPalette>getindex<currentTiddler>]"/>
<!-- Copy the fields from the palette -->
<$action-setmultiplefields $tiddler=<<outputPalette>> $fields="[<inputPalette>fields[]sort[]] -title -tags -text" $values="[<inputPalette>fields[]sort[]] -title -tags -text :map[<inputPalette>get<currentTiddler>]"/>
</$set>
<%endif%>
\end actions-compile-palette-import
\procedure actions-compile-palette(inputPalette,outputPalette)
\procedure tv-action-refresh-policy() always
<$let
consolidatedPalette="$:/temp/palette-consolidated"
>
<!-- Compute the current scheme -->
<$let
color-scheme-filter={{{ [<inputPalette>get[color-scheme]] :else[[light]] }}}
scheme={{{ [subfilter:all<color-scheme-filter>] }}}
>
<!-- Clear the consolidated palette that stores the result of flattening the chain of imported input palettes -->
<$action-deletetiddler $tiddler=<<consolidatedPalette>>/>
<$action-setfield $tiddler=<<consolidatedPalette>> type="application/x-tiddler-dictionary"/>
<!-- Clear the output palette that stores the plain CSS values of palette entries -->
<$action-deletetiddler $tiddler=<<outputPalette>>/>
<$action-setfield $tiddler=<<outputPalette>> type="application/x-tiddler-dictionary"/>
<!-- Import the background palettes -->
<$list filter="[all[shadows+tiddlers]tag[$:/tags/BackgroundPalette]sort[]]" variable="palette-name">
<$transclude $variable="actions-compile-palette-import" inputPalette=<<palette-name>> outputPalette=<<consolidatedPalette>> scheme=<<scheme>>/>
</$list>
<!-- Consolidate the chain of palettes -->
<$transclude $variable="actions-compile-palette-import" inputPalette=<<inputPalette>> outputPalette=<<consolidatedPalette>> scheme=<<scheme>>/>
<!-- Save the current scheme in the output tiddler -->
<$action-setfield $tiddler=<<outputPalette>> $field="color-scheme" $value=<<scheme>>/>
<!-- Compile the temporary palette to the output palette -->
<$transclude $variable="actions-compile-palette-filtered" consolidatedPalette=<<consolidatedPalette>> outputPalette=<<outputPalette>>/>
</$let>
</$let>
\end actions-compile-palette
\procedure actions-recompile-current-palette()
\procedure tv-action-refresh-policy() always
<$transclude $variable="actions-compile-palette" inputPalette={{$:/palette}} outputPalette="$:/temp/palette-colours"/>
\end actions-recompile-current-palette
\procedure actions-switch-colour-palette(paletteTitle)
\procedure tv-action-refresh-policy() always
<$action-deletetiddler $tiddler="$:/temp/palette-colours"/>
<<actions-recompile-current-palette>>
\end actions-switch-colour-palette
\procedure tv-palette-name() $:/temp/palette-colours
\function tf.colour(name)
[<tv-palette-name>getindex<name>] :else[[$:/config/DefaultColourMappings/]addsuffix<name>get[text]]
\end tf.colour
\function colour(name)
[tf.colour<name>]
\end colour
\function color(name)
[tf.colour<name>]
\end color
\procedure colour-function-prefix()
[tf.colour[
\end colour-function-prefix
\procedure colour-function-suffix()
]]
\end colour-function-suffix
\widget $palette.preview(paletteTitle)
\whitespace trim
\function colour-inner-get-imported-palette(name,paletteTitle)
[[palette-import@]addsuffix<scheme>] :map[<paletteTitle>get<currentTiddler>has[title]] +[!match[]] :else[<paletteTitle>get[palette-import]has[title]] :map[function[colour-inner-get-palette-entry],<name>,<currentTiddler>] +[!match[]]
\end colour-inner-get-imported-palette
\function colour-inner-get-palette-entry(name,paletteTitle)
[<name>addprefix[@]addprefix<scheme>] :map[<paletteTitle>getindex<currentTiddler>] +[!match[]] :else[<paletteTitle>getindex<name>] :map[tf.colour-inner-transform-classic-palette-entry<currentTiddler>] :else[function[colour-inner-get-imported-palette],<name>,<paletteTitle>]
\end colour-inner-get-palette-entry
<!-- Note the join, needed to cope with palette entries containing spaces -->
\function tf.colour(name)
[function[colour-inner-get-palette-entry],<name>,<paletteTitle>] :else[[$:/config/DefaultColourMappings/]addsuffix<name>get[text]] :map[subfilter:all<currentTiddler>join[ ]]
\end tf.colour
\function colour(name)
[tf.colour<name>]
\end colour
\function color(name)
[tf.colour<name>]
\end color
<$let
color-scheme-filter={{{ [<paletteTitle>get[color-scheme]] :else[[light]] }}}
scheme={{{ [subfilter:all<color-scheme-filter>] }}}
>
<$slot $name="ts-raw"/>
</$let>
\end $palette.preview
\function tf.colour-inner-transform-classic-palette-entry(colour-result)
[<colour-result>prefix[<<colour ]suffix[>>]removeprefix[<<colour ]removesuffix[>>]addprefix<colour-function-prefix>addsuffix<colour-function-suffix>] :else[<colour-result>]
\end tf.colour-inner-transform-classic-palette-entry
\function tf.check-colour-contrast-subfunction()
[function[colour],<paletteEntryA>] [function[colour],<paletteEntryB>] +[colour-contrast:DeltaPhi[]fixed[3]]
\end tf.check-colour-contrast-subfunction
\function tf.check-colour-contrast(paletteEntryA,paletteEntryB,threshold)
[function[tf.check-colour-contrast-subfunction]compare:number:gt<threshold>then[ok]] :else[function[tf.check-colour-contrast-subfunction]addsuffix[: ]addsuffix<paletteEntryA>addsuffix[/]addsuffix<paletteEntryB>addsuffix[ contrast is too low]]
\end tf.check-colour-contrast
\function tf.interpolate-colours(paletteEntryA,paletteEntryB,weight)
[function[colour],<paletteEntryA>] =>colourA [function[colour],<paletteEntryB>] =>colourB [<weight>colour-interpolate:oklch<colourA>,<colourB>]
\end tf.interpolate-colours
\define color(name) <<colour $name$>>
\procedure datauri(title)
<$macrocall $name="makedatauri" type={{{ [<title>get[type]] }}} text={{{ [<title>get[text]] }}} _canonical_uri={{{ [<title>get[_canonical_uri]] }}}/>
+1 -1
View File
@@ -6,5 +6,5 @@ $:/language/
\end
\define lingo(title)
{{||$(lingo-base)$$title$}}
{{$(lingo-base)$$title$}}
\end
+1 -1
View File
@@ -167,7 +167,7 @@ The second ESC tries to close the "draft tiddler"
<!-- keep those variables because they may "bleed" into macros using old syntax -->
<!-- "nonSystemTagsFilter", "systemTagsFilter" __need to be the same__ as fields: "first-search-filter", "second-search-filter" -->
<$let
palette="$:/temp/palette-colours"
palette={{$:/palette}}
colourA={{{ [<palette>getindex[foreground]] }}}
colourB={{{ [<palette>getindex[background]] }}}
fallbackTarget={{{ [<palette>getindex[tag-background]] }}}
+4 -4
View File
@@ -27,16 +27,15 @@ color:$(foregroundColor)$;
</$let>
\end
<!-- Note that the 'palette' parameter is unused and is only retained for backwards compatibility -->
\define tag-pill-body(tag,icon,colour,palette,element-tag,element-attributes,actions)
\whitespace trim
<$macrocall $name="tag-pill-inner"
tag=<<__tag__>>
icon=<<__icon__>>
colour=<<__colour__>>
fallbackTarget=<<colour tag-background>>
colourA=<<colour foreground>>
colourB=<<colour background>>
fallbackTarget={{$palette$##tag-background}}
colourA={{$palette$##foreground}}
colourB={{$palette$##background}}
element-tag=<<__element-tag__>>
element-attributes=<<__element-attributes__>>
actions=<<__actions__>>
@@ -51,6 +50,7 @@ color:$(foregroundColor)$;
tag=<<__tag__>>
icon={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]!is[draft]get[text]] }}}
colour={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}
palette={{$:/palette}}
element-tag=<<__element-tag__>>
element-attributes=<<__element-attributes__>>
actions=<<__actions__>>/>
+1 -1
View File
@@ -1,3 +1,3 @@
title: $:/palette
$:/palettes/AutoToggle
$:/palettes/Vanilla
+14 -25
View File
@@ -1,30 +1,19 @@
title: $:/snippets/paletteswitcher
\parameters (thumbnails)
\whitespace trim
\procedure actions()
<$action-setfield $tiddler="$:/palette" text=<<navigateTo>>/>
\end actions
<!-- Display palette in currentTiddler with selection logic -->
\procedure palette-entry(thumbnails)
<div class={{{ [<currentTiddler>match{$:/palette}then[tc-chosen]] tc-chooser-item +[join[ ]] }}}>
<$link to={{!!title}} aria-label=`${[[$:/language/ControlPanel/Palette/Caption]get[text]]}$ - ${[all[current]get[name]]}$. ${[all[current]get[description]]}$`>
<%if [<thumbnails>match[yes]] %>
{{||$:/snippets/currpalettepreview}}
<%endif%>
''<$view field="name" format="text"/>''
<br>
<$view field="description" format="text"/>
</$link>
<$linkcatcher to="$:/palette">
<div class="tc-chooser">
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Palette]!is[draft]sort[name]]">
<$set name="cls" filter="[all[current]prefix{$:/palette}]" value="tc-chooser-item tc-chosen" emptyValue="tc-chooser-item">
<div class=<<cls>>>
<$link to={{!!title}}>
''<$view field="name" format="text"/>''
&#32;-&#32;
<$view field="description" format="text"/>
{{||$:/snippets/currpalettepreview}}
</$link>
</div>
</$set>
</$list>
</div>
\end palette-entry
<$linkcatcher actions=<<actions>>>
<div class={{{ tc-chooser [<thumbnails>match[yes]then[tc-chooser-cards]] +[join[ ]] }}}>
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Palette]!is[draft]sort[name]]">
<$transclude $variable="palette-entry" thumbnails=<<thumbnails>>/>
</$list>
</div>
</$linkcatcher>
-19
View File
@@ -1,19 +0,0 @@
title: $:/snippets/palettetests
<$let failureCount={{{ [[$:/temp/palette-colours]indexes[]prefix[?]] :filter[[$:/temp/palette-colours]getindex<currentTiddler>!match[ok]] +[count[]] }}}>
<%if [<failureCount>compare:number:gt[0]] %>
Palette test failures: <$text text=<<failureCount>>/>
<$list filter="[[$:/temp/palette-colours]indexes[]prefix[?]sort[]]" variable="name">
<%if [[$:/temp/palette-colours]getindex<name>!match[ok]] %>
<div>
''<$text text={{{ [<name>removeprefix[?]] }}}/>'': <$text text={{{ [[$:/temp/palette-colours]getindex<name>] }}}/>
</div>
<%endif%>
</$list>
<%endif%>
</$let>
@@ -1,2 +0,0 @@
title: $:/tags/ControlPanel/Appearance
text: $:/core/ui/ControlPanel/Palette $:/core/ui/ControlPanel/StoryView $:/core/ui/ControlPanel/Theme $:/core/ui/ControlPanel/Toolbars
-2
View File
@@ -1,2 +0,0 @@
title: $:/tags/Preview/Page
list: $:/core/ui/Palettes/Preview/Alert $:/core/ui/Palettes/Preview/Notification $:/core/ui/Palettes/Preview/Story $:/core/ui/Palettes/Preview/Sidebar
-2
View File
@@ -1,2 +0,0 @@
title: $:/tags/Preview/SideBar
list: $:/core/ui/Palettes/Preview/Sidebar/Title $:/core/ui/Palettes/Preview/Sidebar/Subtitle $:/core/ui/Palettes/Preview/Sidebar/Search $:/core/ui/Palettes/Preview/Sidebar/Tabs
-2
View File
@@ -1,2 +0,0 @@
title: $:/tags/Preview/Tiddler
list: $:/core/ui/Palettes/Preview/Tiddler/Header $:/core/ui/Palettes/Preview/Tiddler/Subtitle $:/core/ui/Palettes/Preview/Tiddler/Body
+1 -1
View File
@@ -1,2 +1,2 @@
title: $:/tags/ViewTemplateBodyFilter
list: $:/config/ViewTemplateBodyFilters/testcase $:/config/ViewTemplateBodyFilters/hide-body $:/config/ViewTemplateBodyFilters/code-body $:/config/ViewTemplateBodyFilters/stylesheet $:/config/ViewTemplateBodyFilters/core-ui-advanced-search $:/config/ViewTemplateBodyFilters/core-ui-tags $:/config/ViewTemplateBodyFilters/import $:/config/ViewTemplateBodyFilters/plugin $:/config/ViewTemplateBodyFilters/html $:/config/ViewTemplateBodyFilters/system $:/config/ViewTemplateBodyFilters/palette $:/config/ViewTemplateBodyFilters/default
list: $:/config/ViewTemplateBodyFilters/testcase $:/config/ViewTemplateBodyFilters/hide-body $:/config/ViewTemplateBodyFilters/code-body $:/config/ViewTemplateBodyFilters/stylesheet $:/config/ViewTemplateBodyFilters/core-ui-advanced-search $:/config/ViewTemplateBodyFilters/core-ui-tags $:/config/ViewTemplateBodyFilters/import $:/config/ViewTemplateBodyFilters/plugin $:/config/ViewTemplateBodyFilters/html $:/config/ViewTemplateBodyFilters/system $:/config/ViewTemplateBodyFilters/default
@@ -1,11 +1,13 @@
created: 20150220191009000
modified: 20150602092431500
title: $:/editions/tw5.com/railroad/macro-parameter-value
title: $:/editions/tw5.com/railroad/call-parameter-value
type: text/vnd.tiddlywiki.railroad
( '"""' [:{/'tout sauf """'/}] '"""'
| '"' [:{/'tout sauf "'/}] '"'
| "'" [:{/"tout sauf '"/}] "'"
| "[[" [:{/"tout sauf ]"/}] "]]"
| "`" [:{/"tout sauf `"/}] "`"
| "```" [:{/"tout sauf ```"/}] "```"
| {/"""tout sauf ' " ou espacevierge"""/}
)

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