mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-08-07 14:23:53 +00:00
Merge background actions and media tracker from #8555
The changes in #8555 are needed in order to be able to offer the desired user experience for dark mode changes.
This commit is contained in:
parent
9681b0deda
commit
0baf395030
117
core/modules/background-actions.js
Normal file
117
core/modules/background-actions.js
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/background-actions.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: global
|
||||||
|
|
||||||
|
Class to dispatch actions when filters change
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function BackgroundActionDispatcher(filterTracker,wiki) {
|
||||||
|
var self = this;
|
||||||
|
this.filterTracker = filterTracker;
|
||||||
|
this.wiki = wiki;
|
||||||
|
this.nextTrackedFilterId = 1;
|
||||||
|
this.trackedFilters = Object.create(null); // Hashmap by id
|
||||||
|
// Track the filter for the background actions
|
||||||
|
this.filterTracker.track({
|
||||||
|
filterString: "[all[tiddlers+shadows]tag[$:/tags/BackgroundAction]!is[draft]]",
|
||||||
|
fnEnter: function fnEnter(title) {
|
||||||
|
return self.trackFilter(title);
|
||||||
|
},
|
||||||
|
fnLeave: function fnLeave(title,enterValue) {
|
||||||
|
self.untrackFilter(enterValue);
|
||||||
|
},
|
||||||
|
fnChange: function fnChange(title,enterValue) {
|
||||||
|
self.untrackFilter(enterValue);
|
||||||
|
return self.trackFilter(title);
|
||||||
|
},
|
||||||
|
fnProcess: function fnProcess(changes) {
|
||||||
|
self.process(changes);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
BackgroundActionDispatcher.prototype.trackFilter = function(title) {
|
||||||
|
var tiddler = this.wiki.getTiddler(title),
|
||||||
|
id = this.nextTrackedFilterId++,
|
||||||
|
tracker = new BackgroundActionTracker({
|
||||||
|
wiki: this.wiki,
|
||||||
|
title: title,
|
||||||
|
trackFilter: tiddler.fields["track-filter"],
|
||||||
|
actions: tiddler.fields.text
|
||||||
|
});
|
||||||
|
this.trackedFilters[id] = tracker;
|
||||||
|
return id;
|
||||||
|
};
|
||||||
|
|
||||||
|
BackgroundActionDispatcher.prototype.untrackFilter = function(enterValue) {
|
||||||
|
var tracker = this.trackedFilters[enterValue];
|
||||||
|
if(tracker) {
|
||||||
|
tracker.destroy();
|
||||||
|
}
|
||||||
|
delete this.trackedFilters[enterValue];
|
||||||
|
};
|
||||||
|
|
||||||
|
BackgroundActionDispatcher.prototype.process = function(changes) {
|
||||||
|
for(var id in this.trackedFilters) {
|
||||||
|
this.trackedFilters[id].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
|
||||||
|
*/
|
||||||
|
function BackgroundActionTracker(options) {
|
||||||
|
var self = this;
|
||||||
|
this.wiki = options.wiki;
|
||||||
|
this.title = options.title;
|
||||||
|
this.trackFilter = options.trackFilter;
|
||||||
|
this.actions = options.actions
|
||||||
|
this.filterTracker = new $tw.FilterTracker(this.wiki);
|
||||||
|
this.hasChanged = false;
|
||||||
|
this.trackerID = this.filterTracker.track({
|
||||||
|
filterString: this.trackFilter,
|
||||||
|
fnEnter: function(title) {
|
||||||
|
self.hasChanged = true;
|
||||||
|
},
|
||||||
|
fnLeave: function(title,enterValue) {
|
||||||
|
self.hasChanged = true;
|
||||||
|
},
|
||||||
|
fnProcess: function(changes) {
|
||||||
|
if(self.hasChanged) {
|
||||||
|
self.hasChanged = false;
|
||||||
|
self.wiki.invokeActionString(
|
||||||
|
self.actions,
|
||||||
|
null,
|
||||||
|
{
|
||||||
|
title: self.title
|
||||||
|
},{
|
||||||
|
parentWidget: $tw.rootWidget
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
BackgroundActionTracker.prototype.process = function(changes) {
|
||||||
|
this.filterTracker.handleChangeEvent(changes);
|
||||||
|
};
|
||||||
|
|
||||||
|
BackgroundActionTracker.prototype.destroy = function() {
|
||||||
|
this.filterTracker.untrack(this.trackerID);
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.BackgroundActionDispatcher = BackgroundActionDispatcher;
|
||||||
|
|
||||||
|
})();
|
108
core/modules/filter-tracker.js
Normal file
108
core/modules/filter-tracker.js
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/filter-tracker.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: global
|
||||||
|
|
||||||
|
Class to track the results of a filter string
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function FilterTracker(wiki) {
|
||||||
|
this.wiki = wiki;
|
||||||
|
this.trackers = [];
|
||||||
|
this.nextTrackerId = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
FilterTracker.prototype.handleChangeEvent = function(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)
|
||||||
|
*/
|
||||||
|
FilterTracker.prototype.track = function(options) {
|
||||||
|
// Add the tracker details
|
||||||
|
var tracker = {
|
||||||
|
id: this.nextTrackerId++,
|
||||||
|
filterString: options.filterString,
|
||||||
|
fnEnter: options.fnEnter,
|
||||||
|
fnLeave: options.fnLeave,
|
||||||
|
fnChange: options.fnChange,
|
||||||
|
fnProcess: options.fnProcess,
|
||||||
|
previousResults: [], // Results from the previous time the tracker was processed
|
||||||
|
resultValues: {} // Map by title to the value returned by fnEnter
|
||||||
|
};
|
||||||
|
this.trackers.push(tracker);
|
||||||
|
// Process the tracker
|
||||||
|
this.processTracker(this.trackers.length - 1);
|
||||||
|
return tracker.id;
|
||||||
|
};
|
||||||
|
|
||||||
|
FilterTracker.prototype.untrack = function(id) {
|
||||||
|
for(var t=0; t<this.trackers.length; t++) {
|
||||||
|
if(this.trackers[t].id === id) {
|
||||||
|
this.trackers.splice(t,1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
FilterTracker.prototype.processTrackers = function() {
|
||||||
|
for(var t=0; t<this.trackers.length; t++) {
|
||||||
|
this.processTracker(t);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
FilterTracker.prototype.processTracker = function(index) {
|
||||||
|
var tracker = this.trackers[index];
|
||||||
|
var results = [];
|
||||||
|
// Evaluate the filter and remove duplicate results
|
||||||
|
$tw.utils.each(this.wiki.filterTiddlers(tracker.filterString),function(title) {
|
||||||
|
$tw.utils.pushTop(results,title);
|
||||||
|
});
|
||||||
|
// Process the newly entered results
|
||||||
|
$tw.utils.each(results,function(title) {
|
||||||
|
if(tracker.previousResults.indexOf(title) === -1 && !tracker.resultValues[title] && tracker.fnEnter) {
|
||||||
|
tracker.resultValues[title] = tracker.fnEnter(title) || true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Process the results that have just left
|
||||||
|
$tw.utils.each(tracker.previousResults,function(title) {
|
||||||
|
if(results.indexOf(title) === -1 && tracker.resultValues[title] && tracker.fnLeave) {
|
||||||
|
tracker.fnLeave(title,tracker.resultValues[title]);
|
||||||
|
delete tracker.resultValues[title];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Update the previous results
|
||||||
|
tracker.previousResults = results;
|
||||||
|
};
|
||||||
|
|
||||||
|
FilterTracker.prototype.processChanges = function(changes) {
|
||||||
|
for(var t=0; t<this.trackers.length; t++) {
|
||||||
|
var tracker = this.trackers[t];
|
||||||
|
$tw.utils.each(changes,function(change,title) {
|
||||||
|
if(title && tracker.previousResults.indexOf(title) !== -1 && tracker.fnChange) {
|
||||||
|
// Call the change function and if it doesn't return a value then keep the old value
|
||||||
|
tracker.resultValues[title] = tracker.fnChange(title,tracker.resultValues[title]) || tracker.resultValues[title];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if(tracker.fnProcess) {
|
||||||
|
tracker.fnProcess(changes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.FilterTracker = FilterTracker;
|
||||||
|
|
||||||
|
})();
|
72
core/modules/info/mediaquerytracker.js
Normal file
72
core/modules/info/mediaquerytracker.js
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/info/mediaquerytracker.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: info
|
||||||
|
|
||||||
|
Initialise $:/info/ tiddlers derived from media queries via
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"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 [];
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
@ -36,13 +36,6 @@ exports.getInfoTiddlerFields = function(updateInfoTiddlersCallback) {
|
|||||||
// Screen size
|
// Screen size
|
||||||
infoTiddlerFields.push({title: "$:/info/browser/screen/width", text: window.screen.width.toString()});
|
infoTiddlerFields.push({title: "$:/info/browser/screen/width", text: window.screen.width.toString()});
|
||||||
infoTiddlerFields.push({title: "$:/info/browser/screen/height", text: window.screen.height.toString()});
|
infoTiddlerFields.push({title: "$:/info/browser/screen/height", text: window.screen.height.toString()});
|
||||||
// Dark mode through event listener on MediaQueryList
|
|
||||||
var mqList = window.matchMedia("(prefers-color-scheme: dark)"),
|
|
||||||
getDarkModeTiddler = function() {return {title: "$:/info/darkmode", text: mqList.matches ? "yes" : "no"};};
|
|
||||||
infoTiddlerFields.push(getDarkModeTiddler());
|
|
||||||
mqList.addListener(function(event) {
|
|
||||||
updateInfoTiddlersCallback([getDarkModeTiddler()]);
|
|
||||||
});
|
|
||||||
// Language
|
// Language
|
||||||
infoTiddlerFields.push({title: "$:/info/browser/language", text: navigator.language || ""});
|
infoTiddlerFields.push({title: "$:/info/browser/language", text: navigator.language || ""});
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,9 @@ Load core modules
|
|||||||
exports.name = "load-modules";
|
exports.name = "load-modules";
|
||||||
exports.synchronous = true;
|
exports.synchronous = true;
|
||||||
|
|
||||||
|
// Set to `true` to enable performance instrumentation
|
||||||
|
var PERFORMANCE_INSTRUMENTATION_CONFIG_TITLE = "$:/config/Performance/Instrumentation";
|
||||||
|
|
||||||
exports.startup = function() {
|
exports.startup = function() {
|
||||||
// Load modules
|
// Load modules
|
||||||
$tw.modules.applyMethods("utils",$tw.utils);
|
$tw.modules.applyMethods("utils",$tw.utils);
|
||||||
@ -35,6 +38,19 @@ exports.startup = function() {
|
|||||||
$tw.macros = $tw.modules.getModulesByTypeAsHashmap("macro");
|
$tw.macros = $tw.modules.getModulesByTypeAsHashmap("macro");
|
||||||
$tw.wiki.initParsers();
|
$tw.wiki.initParsers();
|
||||||
$tw.Commander.initCommands();
|
$tw.Commander.initCommands();
|
||||||
|
// --------------------------
|
||||||
|
// 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
|
||||||
|
// --------------------------
|
||||||
|
// 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);
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
@ -17,9 +17,6 @@ exports.name = "startup";
|
|||||||
exports.after = ["load-modules"];
|
exports.after = ["load-modules"];
|
||||||
exports.synchronous = true;
|
exports.synchronous = true;
|
||||||
|
|
||||||
// Set to `true` to enable performance instrumentation
|
|
||||||
var PERFORMANCE_INSTRUMENTATION_CONFIG_TITLE = "$:/config/Performance/Instrumentation";
|
|
||||||
|
|
||||||
var widget = require("$:/core/modules/widgets/widget.js");
|
var widget = require("$:/core/modules/widgets/widget.js");
|
||||||
|
|
||||||
exports.startup = function() {
|
exports.startup = function() {
|
||||||
@ -57,8 +54,6 @@ exports.startup = function() {
|
|||||||
}
|
}
|
||||||
// Initialise version
|
// Initialise version
|
||||||
$tw.version = $tw.utils.extractVersionInfo();
|
$tw.version = $tw.utils.extractVersionInfo();
|
||||||
// Set up the performance framework
|
|
||||||
$tw.perf = new $tw.Performance($tw.wiki.getTiddlerText(PERFORMANCE_INSTRUMENTATION_CONFIG_TITLE,"no") === "yes");
|
|
||||||
// Create a root widget for attaching event handlers. By using it as the parentWidget for another widget tree, one can reuse the event handlers
|
// 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({
|
$tw.rootWidget = new widget.widget({
|
||||||
type: "widget",
|
type: "widget",
|
||||||
|
9
core/wiki/SampleBackgroundAction Dark Mode.tid
Normal file
9
core/wiki/SampleBackgroundAction Dark Mode.tid
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
title: SampleBackgroundAction: Dark Mode
|
||||||
|
tags: $:/tags/BackgroundAction
|
||||||
|
track-filter: [{$:/info/browser/darkmode}]
|
||||||
|
|
||||||
|
<%if [{$:/info/browser/darkmode}match[no]] %>
|
||||||
|
<$action-setfield $tiddler="$:/palette" text="$:/palettes/TwentyTwenties"/>
|
||||||
|
<%else%>
|
||||||
|
<$action-setfield $tiddler="$:/palette" text="$:/palettes/TwentyTwenties/Dark"/>
|
||||||
|
<%endif%>
|
15
core/wiki/SampleBackgroundAction Story Change.tid
Normal file
15
core/wiki/SampleBackgroundAction Story Change.tid
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
title: SampleBackgroundAction: Story Change
|
||||||
|
tags: $:/tags/BackgroundAction
|
||||||
|
track-filter: [list[$:/StoryList]]
|
||||||
|
|
||||||
|
<$action-sendmessage $message="tm-notify" $param="SampleBackgroundAction: Story Change" list={{$:/StoryList!!list}}/>
|
||||||
|
|
||||||
|
Story List:
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<$list filter="[enlist<list>]">
|
||||||
|
<li>
|
||||||
|
<$text text=<<currentTiddler>>/>
|
||||||
|
</li>
|
||||||
|
</$list>
|
||||||
|
</ol>
|
@ -0,0 +1,5 @@
|
|||||||
|
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
|
@ -4,8 +4,8 @@ tags: Mechanisms
|
|||||||
title: InfoMechanism
|
title: InfoMechanism
|
||||||
type: text/vnd.tiddlywiki
|
type: text/vnd.tiddlywiki
|
||||||
|
|
||||||
\define example(name)
|
\procedure example(name)
|
||||||
<$transclude tiddler="""$:/info/url/$name$""" mode="inline"/>
|
<$text text={{{ [[$:/info/url/]addsuffix<name>get[text]] }}} />
|
||||||
\end
|
\end
|
||||||
|
|
||||||
System tiddlers in the namespace `$:/info/` are used to expose information about the system (including the current browser) so that WikiText applications can adapt themselves to available features.
|
System tiddlers in the namespace `$:/info/` are used to expose information about the system (including the current browser) so that WikiText applications can adapt themselves to available features.
|
||||||
@ -19,6 +19,8 @@ System tiddlers in the namespace `$:/info/` are used to expose information about
|
|||||||
|[[$:/info/browser/language]] |<<.from-version "5.1.20">> Language as reported by browser (note that some browsers report two character codes such as `en` while others report full codes such as `en-GB`) |
|
|[[$:/info/browser/language]] |<<.from-version "5.1.20">> Language as reported by browser (note that some browsers report two character codes such as `en` while others report full codes such as `en-GB`) |
|
||||||
|[[$:/info/browser/screen/width]] |Screen width in pixels |
|
|[[$:/info/browser/screen/width]] |Screen width in pixels |
|
||||||
|[[$:/info/browser/screen/height]] |Screen height in pixels |
|
|[[$:/info/browser/screen/height]] |Screen height in pixels |
|
||||||
|
|[[$:/info/browser/darkmode]] |<<.from-version "5.3.7">> Is dark mode preferred? ("yes" or "no") |
|
||||||
|
|[[$:/info/darkmode]] |<<.deprecated-since "5.3.7">> Alias for $:/info/browser/darkmode |
|
||||||
|[[$:/info/node]] |Running under [[Node.js]]? ("yes" or "no") |
|
|[[$:/info/node]] |Running under [[Node.js]]? ("yes" or "no") |
|
||||||
|[[$:/info/url/full]] |<<.from-version "5.1.14">> Full URL of wiki (eg, ''<<example full>>'') |
|
|[[$:/info/url/full]] |<<.from-version "5.1.14">> Full URL of wiki (eg, ''<<example full>>'') |
|
||||||
|[[$:/info/url/host]] |<<.from-version "5.1.14">> Host portion of URL of wiki (eg, ''<<example host>>'') |
|
|[[$:/info/url/host]] |<<.from-version "5.1.14">> Host portion of URL of wiki (eg, ''<<example host>>'') |
|
||||||
@ -28,4 +30,3 @@ System tiddlers in the namespace `$:/info/` are used to expose information about
|
|||||||
|[[$:/info/url/port]] |<<.from-version "5.1.14">> Port portion of URL of wiki (eg, ''<<example port>>'') |
|
|[[$:/info/url/port]] |<<.from-version "5.1.14">> Port portion of URL of wiki (eg, ''<<example port>>'') |
|
||||||
|[[$:/info/url/protocol]] |<<.from-version "5.1.14">> Protocol portion of URL of wiki (eg, ''<<example protocol>>'') |
|
|[[$:/info/url/protocol]] |<<.from-version "5.1.14">> Protocol portion of URL of wiki (eg, ''<<example protocol>>'') |
|
||||||
|[[$:/info/url/search]] |<<.from-version "5.1.14">> Search portion of URL of wiki (eg, ''<<example search>>'') |
|
|[[$:/info/url/search]] |<<.from-version "5.1.14">> Search portion of URL of wiki (eg, ''<<example search>>'') |
|
||||||
|[[$:/info/darkmode]] |<<.from-version "5.1.23">> Is dark mode enabled? ("yes" or "no") |
|
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
title: MediaQueryTrackerMechanism
|
||||||
|
tags: Mechanisms
|
||||||
|
|
||||||
|
<<.from-version "5.3.7">> The media query tracker mechanism allows you to define [[custom CSS media queries|https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_media_queries/Using_media_queries]] to be bound to a specified [[info|InfoMechanism]] tiddler. The info tiddler will be dynamically update to reflect the current state of the media query.
|
||||||
|
|
||||||
|
Adding or modifying a tiddler tagged $:/tags/MediaQueryTracker takes effect immediately.
|
||||||
|
|
||||||
|
The media queries are always applied against the main window. This is relevant for viewport related media queries such as `min-width` which will always respect the main window and ignore the sizes of any external windows.
|
Loading…
x
Reference in New Issue
Block a user