mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2026-02-07 02:30:22 +00:00
Compare commits
11 Commits
tm-save-do
...
background
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a83855329a | ||
|
|
364e2f2cb5 | ||
|
|
67f13c585d | ||
|
|
6e85d99ed5 | ||
|
|
5791627a50 | ||
|
|
32405c3a71 | ||
|
|
1bbb7fd53b | ||
|
|
599933c34d | ||
|
|
b1ccb82e0a | ||
|
|
ea648c7d15 | ||
|
|
a3a4e91751 |
116
core/modules/background-actions.js
Normal file
116
core/modules/background-actions.js
Normal file
@@ -0,0 +1,116 @@
|
||||
/*\
|
||||
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;
|
||||
106
core/modules/filter-tracker.js
Normal file
106
core/modules/filter-tracker.js
Normal file
@@ -0,0 +1,106 @@
|
||||
/*\
|
||||
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;
|
||||
67
core/modules/info/mediaquerytracker.js
Normal file
67
core/modules/info/mediaquerytracker.js
Normal file
@@ -0,0 +1,67 @@
|
||||
/*\
|
||||
title: $:/core/modules/info/mediaquerytracker.js
|
||||
type: application/javascript
|
||||
module-type: info
|
||||
|
||||
Initialise $:/info/ tiddlers derived from media queries via
|
||||
|
||||
\*/
|
||||
|
||||
"use strict";
|
||||
|
||||
exports.getInfoTiddlerFields = function(updateInfoTiddlersCallback) {
|
||||
if($tw.browser) {
|
||||
// Functions to start and stop tracking a particular media query tracker tiddler
|
||||
function track(title) {
|
||||
var result = {},
|
||||
tiddler = $tw.wiki.getTiddler(title);
|
||||
if(tiddler) {
|
||||
var mediaQuery = tiddler.fields["media-query"],
|
||||
infoTiddler = tiddler.fields["info-tiddler"],
|
||||
infoTiddlerAlt = tiddler.fields["info-tiddler-alt"];
|
||||
if(mediaQuery && infoTiddler) {
|
||||
// Evaluate and track the media query
|
||||
result.mqList = window.matchMedia(mediaQuery);
|
||||
function getResultTiddlers() {
|
||||
var value = result.mqList.matches ? "yes" : "no",
|
||||
tiddlers = [];
|
||||
tiddlers.push({title: infoTiddler, text: value});
|
||||
if(infoTiddlerAlt) {
|
||||
tiddlers.push({title: infoTiddlerAlt, text: value});
|
||||
}
|
||||
return tiddlers;
|
||||
};
|
||||
updateInfoTiddlersCallback(getResultTiddlers());
|
||||
result.handler = function(event) {
|
||||
updateInfoTiddlersCallback(getResultTiddlers());
|
||||
};
|
||||
result.mqList.addEventListener("change",result.handler);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function untrack(enterValue) {
|
||||
if(enterValue.mqList && enterValue.handler) {
|
||||
enterValue.mqList.removeEventListener("change",enterValue.handler);
|
||||
}
|
||||
}
|
||||
// Track media query tracker tiddlers
|
||||
function fnEnter(title) {
|
||||
return track(title);
|
||||
}
|
||||
function fnLeave(title,enterValue) {
|
||||
untrack(enterValue);
|
||||
}
|
||||
function fnChange(title,enterValue) {
|
||||
untrack(enterValue);
|
||||
return track(title);
|
||||
}
|
||||
$tw.filterTracker.track({
|
||||
filterString: "[all[tiddlers+shadows]tag[$:/tags/MediaQueryTracker]!is[draft]]",
|
||||
fnEnter: fnEnter,
|
||||
fnLeave: fnLeave,
|
||||
fnChange: fnChange
|
||||
});
|
||||
}
|
||||
return [];
|
||||
};
|
||||
@@ -33,13 +33,6 @@ 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 || ""});
|
||||
}
|
||||
|
||||
@@ -13,6 +13,11 @@ 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);
|
||||
@@ -31,6 +36,27 @@ 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();
|
||||
}
|
||||
|
||||
@@ -14,11 +14,6 @@ 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) {
|
||||
@@ -54,16 +49,6 @@ 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({
|
||||
|
||||
@@ -86,7 +86,7 @@ LinkWidget.prototype.renderLink = function(parent,nextSibling) {
|
||||
classes.push(this.linkClasses);
|
||||
}
|
||||
} else if(this.overrideClasses !== "") {
|
||||
classes.push(this.overrideClasses)
|
||||
classes.push(this.overrideClasses);
|
||||
}
|
||||
if(classes.length > 0) {
|
||||
domNode.setAttribute("class",classes.join(" "));
|
||||
@@ -97,7 +97,7 @@ LinkWidget.prototype.renderLink = function(parent,nextSibling) {
|
||||
if(wikilinkTransformFilter) {
|
||||
// Use the filter to construct the href
|
||||
wikiLinkText = this.wiki.filterTiddlers(wikilinkTransformFilter,this,function(iterator) {
|
||||
iterator(self.wiki.getTiddler(self.to),self.to)
|
||||
iterator(self.wiki.getTiddler(self.to),self.to);
|
||||
})[0];
|
||||
} else {
|
||||
// Expand the tv-wikilink-template variable to construct the href
|
||||
@@ -121,12 +121,12 @@ LinkWidget.prototype.renderLink = function(parent,nextSibling) {
|
||||
var tooltipWikiText = this.tooltip || this.getVariable("tv-wikilink-tooltip");
|
||||
if(tooltipWikiText) {
|
||||
var tooltipText = this.wiki.renderText("text/plain","text/vnd.tiddlywiki",tooltipWikiText,{
|
||||
parseAsInline: true,
|
||||
variables: {
|
||||
currentTiddler: this.to
|
||||
},
|
||||
parentWidget: this
|
||||
});
|
||||
parseAsInline: true,
|
||||
variables: {
|
||||
currentTiddler: this.to
|
||||
},
|
||||
parentWidget: this
|
||||
});
|
||||
domNode.setAttribute("title",tooltipText);
|
||||
}
|
||||
if(this.role) {
|
||||
@@ -135,7 +135,7 @@ LinkWidget.prototype.renderLink = function(parent,nextSibling) {
|
||||
this.assignAttributes(domNode,{
|
||||
sourcePrefix: "aria-",
|
||||
destPrefix: "aria-"
|
||||
})
|
||||
});
|
||||
// Add a click event handler
|
||||
$tw.utils.addEventListeners(domNode,[
|
||||
{name: "click", handlerObject: this, handlerMethod: "handleClickEvent"},
|
||||
@@ -145,6 +145,8 @@ LinkWidget.prototype.renderLink = function(parent,nextSibling) {
|
||||
$tw.utils.makeDraggable({
|
||||
domNode: domNode,
|
||||
dragTiddlerFn: function() {return self.to;},
|
||||
startActions: self.startActions,
|
||||
endActions: self.endActions,
|
||||
widget: this
|
||||
});
|
||||
} else if(this.draggable === "no") {
|
||||
@@ -203,6 +205,8 @@ LinkWidget.prototype.execute = function() {
|
||||
this.overrideClasses = this.getAttribute("overrideClass");
|
||||
this.tabIndex = this.getAttribute("tabindex");
|
||||
this.draggable = this.getAttribute("draggable","yes");
|
||||
this.startActions = this.getAttribute("startactions");
|
||||
this.endActions = this.getAttribute("endactions");
|
||||
this.linkTag = this.getAttribute("tag","a");
|
||||
// Determine the link characteristics
|
||||
this.isMissing = !this.wiki.tiddlerExists(this.to);
|
||||
|
||||
@@ -103,9 +103,9 @@ title: $:/core/ui/EditTemplate/body/toolbar/button
|
||||
<$set
|
||||
|
||||
name="buttonClasses"
|
||||
value={{!!button-classes}}
|
||||
value={{{ [subfilter{!!button-classes}] :and[join[ ]] }}}
|
||||
|
||||
><<toolbar-button>></$set>
|
||||
\end
|
||||
|
||||
<<toolbar-button-outer>>
|
||||
<<toolbar-button-outer>>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
title: $:/core/Filters/StoryList
|
||||
tags: $:/tags/Filter
|
||||
filter: [list[$:/StoryList]] -$:/AdvancedSearch
|
||||
filter: [<tv-story-list>is[variable]then<tv-story-list>else[$:/StoryList]] =>storylist [list<storylist>] -$:/AdvancedSearch
|
||||
description: {{$:/language/Filters/StoryList}}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -22,7 +22,7 @@ tags: $:/tags/Macro
|
||||
<$action-listops $tiddler=<<targetTiddler>> $field=<<targetField>> $subfilter="+[insertbefore<actionTiddler>,<currentTiddler>]"/>
|
||||
\end
|
||||
|
||||
\define list-links-draggable(tiddler,field:"list",emptyMessage,type:"ul",subtype:"li",class:"",itemTemplate, displayField:"caption")
|
||||
\define list-links-draggable(tiddler,field:"list",emptyMessage,type:"ul",subtype:"li",class:"",itemTemplate,displayField:"caption",startactions,endactions)
|
||||
\whitespace trim
|
||||
<$set name="_tiddler" value="""$tiddler$""" emptyValue=<<currentTiddler>> >
|
||||
<$let field-reference={{{ [<_tiddler>] "!!" [[$field$]] +[join[]] }}}
|
||||
@@ -39,8 +39,11 @@ tags: $:/tags/Macro
|
||||
>
|
||||
<div class="tc-droppable-placeholder"/>
|
||||
<div>
|
||||
<$transclude tiddler="""$itemTemplate$""">
|
||||
<$link to={{!!title}}>
|
||||
<$transclude tiddler=<<__itemTemplate__>>>
|
||||
<$link to={{!!title}}
|
||||
startactions=<<__startactions__>>
|
||||
endactions=<<__endactions__>>
|
||||
>
|
||||
<$let tv-wikilinks="no">
|
||||
<$transclude field=<<__displayField__>>>
|
||||
<$view field="title"/>
|
||||
@@ -92,7 +95,7 @@ tags: $:/tags/Macro
|
||||
</$set>
|
||||
\end
|
||||
|
||||
\define list-tagged-draggable(tag,subFilter,emptyMessage,itemTemplate,elementTag:"div",storyview:"",displayField:"title")
|
||||
\define list-tagged-draggable(tag,subFilter,emptyMessage,itemTemplate,elementTag:"div",storyview:"",displayField:"title",startactions,endactions)
|
||||
\whitespace trim
|
||||
<span class="tc-tagged-draggable-list">
|
||||
<$set name="tag" value=<<__tag__>>>
|
||||
@@ -108,8 +111,11 @@ tags: $:/tags/Macro
|
||||
>
|
||||
<$genesis $type=<<__elementTag__>> class="tc-droppable-placeholder"/>
|
||||
<$genesis $type=<<__elementTag__>>>
|
||||
<$transclude tiddler="""$itemTemplate$""">
|
||||
<$link to={{!!title}}>
|
||||
<$transclude tiddler=<<__itemTemplate__>>>
|
||||
<$link to={{!!title}}
|
||||
startactions=<<__startactions__>>
|
||||
endactions=<<__endactions__>>
|
||||
>
|
||||
<$let tv-wikilinks="no">
|
||||
<$transclude field=<<__displayField__>>>
|
||||
<$view field="title"/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
created: 20201216182347597
|
||||
modified: 20211018102328148
|
||||
modified: 20260206104319886
|
||||
tags:
|
||||
title: How to create dynamic editor toolbar buttons
|
||||
type: text/vnd.tiddlywiki
|
||||
@@ -91,6 +91,9 @@ This tiddler contains all the necessary elements that are important for toolbar
|
||||
; shortcuts
|
||||
: This is the [[Keyboard Shortcut Descriptor]] eg: `((temp-bold))`
|
||||
|
||||
; button-classes <<.from-version "5.4.0">>
|
||||
: Additional CSS classes applied to the created button, definable as a list or filter expression
|
||||
|
||||
<<<
|
||||
|
||||
!! Disabled State
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
caption: list-links-draggable
|
||||
created: 20170328204925306
|
||||
modified: 20211214141650488
|
||||
modified: 20260206131823536
|
||||
tags: Macros [[Core Macros]]
|
||||
title: list-links-draggable Macro
|
||||
type: text/vnd.tiddlywiki
|
||||
@@ -31,9 +31,16 @@ The <<.def list-links-draggable>> [[macro|Macros]] renders the ListField of a ti
|
||||
; itemTemplate
|
||||
: Optional title of a tiddler to use as the template for rendering list items
|
||||
|
||||
;displayField
|
||||
: <<.from-version 5.4.0>> Optional name of the field to display when the list is rendered. Defaults to the "caption" field; if "caption" is not present, the "title" field is used instead
|
||||
; displayField <<.from-version 5.4.0>>
|
||||
: Optional name of the field to display when the list is rendered. Defaults to the "caption" field; if "caption" is not present, the "title" field is used instead
|
||||
|
||||
; startactions <<.from-version "5.4.0">>
|
||||
: Optional action string that gets invoked when link ''dragging starts''
|
||||
: <<.var actionTiddler>> variable is available in this action
|
||||
|
||||
; endactions <<.from-version "5.4.0">>
|
||||
: Optional action string that gets invoked when link ''dragging ends''
|
||||
: <<.var actionTiddler>> variable is available in this action
|
||||
|
||||
If the `itemTemplate` parameter is not provided then the list items are rendered as simple links. Within the `itemTemplate`, the [[currentTiddler Variable]] refers to the current list item.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
caption: list-tagged-draggable
|
||||
created: 20170329092723939
|
||||
modified: 20180109171254045
|
||||
modified: 20260206131803841
|
||||
tags: Macros [[Core Macros]]
|
||||
title: list-tagged-draggable Macro
|
||||
type: text/vnd.tiddlywiki
|
||||
@@ -9,19 +9,30 @@ The <<.def list-tagged-draggable>> [[macro|Macros]] renders the tiddlers with a
|
||||
|
||||
!! Parameters
|
||||
|
||||
;tag
|
||||
; tag
|
||||
: The title of the tag
|
||||
;subFilter
|
||||
|
||||
; subFilter
|
||||
: An optional subfilter to filter out unwanted items (eg `!tag[done]`)
|
||||
;itemTemplate
|
||||
|
||||
; itemTemplate
|
||||
: Optional title of a tiddler to use as the template for rendering list items
|
||||
;emptyMessage
|
||||
|
||||
; emptyMessage
|
||||
: Optional wikitext to display if there are no tiddlers with the specified tag
|
||||
|
||||
;displayField
|
||||
: <<.from-version 5.4.0>> Optional name of the field to display when the list is rendered. Defaults to `title` field.
|
||||
; displayField <<.from-version 5.4.0>>
|
||||
: Optional name of the field to display when the list is rendered. Defaults to `title` field
|
||||
|
||||
Note that the [[ordering|Order of Tagged Tiddlers]] is accomplished by assigning a new list to the `list` field of the tag tiddler. Any `list-before` or `list-after` fields on any of the other tiddlers carrying the tag are also removed to ensure the `list` field is respected.
|
||||
; startactions <<.from-version "5.4.0">>
|
||||
: Optional action string that gets invoked when link ''dragging starts''
|
||||
: <<.var actionTiddler>> variable is available in this action.
|
||||
|
||||
; endactions <<.from-version "5.4.0">>
|
||||
: Optional action string that gets invoked when link ''dragging ends''
|
||||
: <<.var actionTiddler>> variable is available in this action
|
||||
|
||||
Note that the [[ordering|Order of Tagged Tiddlers]] is accomplished by assigning a new list to the `list` field of the tag tiddler. Any `list-before` or `list-after` fields on any of the other tiddlers carrying the tag are also removed to ensure the `list` field is respected
|
||||
|
||||
If the `itemTemplate` parameter is not provided then the list items are rendered as simple links. Within the `itemTemplate`, the [[currentTiddler Variable]] refers to the current list item.
|
||||
|
||||
|
||||
28
editions/tw5.com/tiddlers/mechanisms/Background Actions.tid
Normal file
28
editions/tw5.com/tiddlers/mechanisms/Background Actions.tid
Normal file
@@ -0,0 +1,28 @@
|
||||
title: Background Actions
|
||||
created: 20250212154426403
|
||||
modified: 20250212154426403
|
||||
tags: Mechanisms
|
||||
|
||||
Background actions are performed whenever there are changes to the results of a filter.
|
||||
|
||||
They can be useful for hooking into existing functionality by tracking changes to the tiddler store.
|
||||
|
||||
The following example tracks changes to the story list, reusing itself as the text of a notification at the same time:
|
||||
|
||||
<<.demo-tiddler """
|
||||
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>
|
||||
""">>
|
||||
@@ -4,8 +4,8 @@ tags: Mechanisms
|
||||
title: InfoMechanism
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
\define example(name)
|
||||
<$transclude tiddler="""$:/info/url/$name$""" mode="inline"/>
|
||||
\procedure example(name)
|
||||
<$text text={{{ [[$:/info/url/]addsuffix<name>get[text]] }}} />
|
||||
\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.
|
||||
@@ -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/screen/width]] |Screen width in pixels |
|
||||
|[[$:/info/browser/screen/height]] |Screen height in pixels |
|
||||
|[[$:/info/browser/darkmode]] |<<.from-version "5.4.0">> Is dark mode preferred? ("yes" or "no") |
|
||||
|[[$:/info/darkmode]] |<<.deprecated-since "5.4.0">> Alias for $:/info/browser/darkmode |
|
||||
|`$:/info/browser/window/*` |<<.from-version "5.4.0">> Tiddlers reporting window dimensions, updated when the windows are resized |
|
||||
|[[$:/info/node]] |Running under [[Node.js]]? ("yes" or "no") |
|
||||
|[[$:/info/url/full]] |<<.from-version "5.1.14">> Full URL of wiki (eg, ''<<example full>>'') |
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
title: Media Query Tracker Mechanism
|
||||
tags: Mechanisms
|
||||
created: 20250212154426403
|
||||
modified: 20250212154426403
|
||||
|
||||
|
||||
<<.from-version "5.4.0">> 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.
|
||||
|
||||
The core includes a media query tracker that is used for tracking the operating system dark/light setting. See $:/core/wiki/config/MediaQueryTrackers/DarkLightPreferred for details.
|
||||
@@ -0,0 +1,13 @@
|
||||
title: $:/changenotes/5.4.0/#9585
|
||||
created: 20260106174849522
|
||||
modified: 20260106174849522
|
||||
tags: $:/tags/ChangeNote
|
||||
change-type: enhancement
|
||||
change-category: usability
|
||||
description: The button classes of Editor toolbar buttons can now be evaluated as filter expressions
|
||||
release: 5.4.0
|
||||
github-links: https://github.com/TiddlyWiki/TiddlyWiki5/pull/9585
|
||||
github-contributors: BurningTreeC
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
This change lets you define the button-classes of Editor toolbar buttons as filters for flexible styling
|
||||
@@ -0,0 +1,12 @@
|
||||
change-category: usability
|
||||
change-type: enhancement
|
||||
created: 20260126125300
|
||||
description: Add start- and endactions to link-widget, list-links-draggable and list-tagged-draggable macros
|
||||
github-contributors: pmario
|
||||
github-links: https://github.com/TiddlyWiki/TiddlyWiki5/pull/9621
|
||||
modified: 20260126125300
|
||||
release: 5.4.0
|
||||
tags: $:/tags/ChangeNote
|
||||
title: $:/changenotes/5.4.0/#9621
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
14
editions/tw5.com/tiddlers/releasenotes/5.4.0/#9641.tid
Normal file
14
editions/tw5.com/tiddlers/releasenotes/5.4.0/#9641.tid
Normal file
@@ -0,0 +1,14 @@
|
||||
title: $:/changenotes/5.4.0/#9641
|
||||
description: Background actions and media query tracking
|
||||
tags: $:/tags/ChangeNote
|
||||
release: 5.4.0
|
||||
change-type: enhancement
|
||||
change-category: internal
|
||||
github-links: https://github.com/TiddlyWiki/TiddlyWiki5/pull/9641
|
||||
github-contributors: Jermolene
|
||||
|
||||
Introduces[[Background Actions]] that are triggered whenever there is a change to the results of a specified filter.
|
||||
|
||||
Building on that, it also introduces a new [[Media Query Tracker Mechanism]] that can track the results of any CSS media query (not just dark mode), storing the results in a shadow `$:/info/...` tiddler
|
||||
|
||||
These improvements were cherrypicked from [[#8702 - Colour Handling Improvements|https://github.com/TiddlyWiki/TiddlyWiki5/pull/8702]] when it was deferred until v5.5.0.
|
||||
@@ -1,6 +0,0 @@
|
||||
created: 20230726145210484
|
||||
modified: 20260130210336084
|
||||
title: Behaviour of called variables depends on how the variable was declared
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
See [[Behaviour of called variables depends on how the variable was declared]].
|
||||
@@ -1,6 +1,6 @@
|
||||
caption: link
|
||||
created: 20131024141900000
|
||||
modified: 20250720025154474
|
||||
modified: 20260206131722044
|
||||
tags: Widgets
|
||||
title: LinkWidget
|
||||
type: text/vnd.tiddlywiki
|
||||
@@ -27,6 +27,8 @@ The content of the link widget is rendered within the `<a>` tag representing the
|
||||
|data-* |<<.from-version "5.3.2">> Optional [[data attributes|https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes]] to be assigned to the HTML element |
|
||||
|style.* |<<.from-version "5.3.2">> Optional [[CSS properties|https://developer.mozilla.org/en-US/docs/Web/CSS/Reference]] to be assigned to the HTML element |
|
||||
|aria-* |<<.from-version "5.4.0">> Optional [[ARIA attributes|https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes]] to be assigned to the HTML element |
|
||||
|startactions |<<.from-version "5.4.0">> Optional action string that gets invoked when ''dragging starts''. The <<.var actionTiddler>> variable is available in this action.|
|
||||
|endactions |<<.from-version "5.4.0">> Optional action string that gets invoked when ''dragging ends''. The <<.var actionTiddler>> variable is available in this action. |
|
||||
|
||||
The draggable functionality is equivalent to using the DraggableWidget with the ''tiddler'' attribute set to the link target.
|
||||
|
||||
@@ -67,6 +69,19 @@ A useful convention is to set the tooltip like this:
|
||||
|
||||
This causes the tooltip to be the ''tooltip'' field of the target tiddler. If the field isn't present, then the title is used instead.
|
||||
|
||||
! Action Variables
|
||||
|
||||
<<.from-version "5.4.0">> The <<.var actionTiddler>> variable is available to <<.param startaction>> and <<.param endaction>>.
|
||||
|
||||
To see all variables available to an action you can use this code and see the variables in the browser dev-console (F12)
|
||||
|
||||
<<wikitext-example-without-html """\procedure endActions()
|
||||
<$action-log/>
|
||||
\end
|
||||
|
||||
<$link to=HelloThere endactions=<<endActions>>>drag me!</$link>
|
||||
""">>
|
||||
|
||||
! CSS Classes
|
||||
|
||||
The link widget automatically determines and applies the following classes to links:
|
||||
@@ -95,7 +110,7 @@ The following process is used to generate the `href` attribute of the generated
|
||||
# If <<.vlink tv-wikilink-template>> is defined it is treated as a specialised macro body that can perform limited conversion of the target tiddler title to the `href` value
|
||||
# Otherwise, the target tiddler title is URI encoded to create the `href`
|
||||
|
||||
! Configuration variables
|
||||
! Configuration Variables
|
||||
|
||||
* <<.vlink tv-wikilinks>>
|
||||
* <<.vlink tv-filter-export-link>>
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
"tiddlywiki/browser-sniff",
|
||||
"tiddlywiki/confetti",
|
||||
"tiddlywiki/dynannotate",
|
||||
"tiddlywiki/tour",
|
||||
"tiddlywiki/internals",
|
||||
"tiddlywiki/menubar",
|
||||
"tiddlywiki/railroad",
|
||||
"tiddlywiki/tour"
|
||||
"tiddlywiki/railroad"
|
||||
],
|
||||
"themes": [
|
||||
"tiddlywiki/vanilla",
|
||||
|
||||
66
plugins/tiddlywiki/dom-to-image/docs.tid
Normal file
66
plugins/tiddlywiki/dom-to-image/docs.tid
Normal file
@@ -0,0 +1,66 @@
|
||||
title: $:/plugins/tiddlywiki/dom-to-image/docs
|
||||
caption: tm-save-dom-to-image message
|
||||
|
||||
!! `tm-save-dom-to-image` message
|
||||
|
||||
The `tm-save-dom-to-image` message uses a [[third-party library|https://github.com/1904labs/dom-to-image-more]] to save a DOM node as an image. The image can be saved to a file or to a tiddler.
|
||||
|
||||
Note that there are some limitations to saving content loaded from external domains due to the same-origin policy. See the documentation for more details.
|
||||
|
||||
The following parameters are supported:
|
||||
|
||||
|!Parameters |!Description |
|
||||
|''selector'' |CSS selector identifying the DOM node to be saved as an image (defaults to `body`). If multiple DOM nodes are returned by the selector then the first one is used |
|
||||
|''format'' |Save format: ''png'', ''jpeg'' or ''svg'' (defaults to ''png'') |
|
||||
|''quality'' |Optional quality 0 to 1 for JPEG images (note that the default quality is 1, and this default is applied even if the quality is explicitly specified as `0`. To force a low quality JPEG image it is therefore necessary to specify a small non-zero value such as `0.001`) |
|
||||
|''scale'' |Optional scale factor for the image (defaults to 1) |
|
||||
|''width'' |Optional width of the image in pixels |
|
||||
|''height'' |Optional height of the image in pixels |
|
||||
|''save-file'' |Optional filename to save the image to |
|
||||
|''save-title'' |Optional title of tiddler to save the image to |
|
||||
|''oncompletion'' |Optional action string to be invoked when the save operation has completed |
|
||||
|''var-*'' |Variables to be passed to the completion handler (without the "var-" prefix) |
|
||||
|
||||
!! Examples
|
||||
|
||||
<$button>
|
||||
<$action-sendmessage
|
||||
$message="tm-save-dom-to-image"
|
||||
selector="body.tc-body"
|
||||
scale="2"
|
||||
save-file="screenshot.png"
|
||||
/>
|
||||
Save the screen as an image file in PNG format
|
||||
</$button>
|
||||
|
||||
<$button>
|
||||
<$action-sendmessage
|
||||
$message="tm-save-dom-to-image"
|
||||
selector="body.tc-body"
|
||||
scale="2"
|
||||
save-title="$:/temp/screenshot.png"
|
||||
/>
|
||||
Save the screen as an image tiddler in PNG format
|
||||
</$button> [[$:/temp/screenshot.png]]
|
||||
|
||||
<$button>
|
||||
<$action-sendmessage
|
||||
$message="tm-save-dom-to-image"
|
||||
selector="body.tc-body"
|
||||
format="jpeg"
|
||||
scale="1"
|
||||
quality="0.01"
|
||||
save-title="$:/temp/screenshot.jpeg"
|
||||
/>
|
||||
Save the screen as an image tiddler in low quality JPEG format
|
||||
</$button> [[$:/temp/screenshot.jpeg]]
|
||||
|
||||
<$button>
|
||||
<$action-sendmessage
|
||||
$message="tm-save-dom-to-image"
|
||||
selector="body.tc-body"
|
||||
format="svg"
|
||||
save-title="$:/temp/screenshot.svg"
|
||||
/>
|
||||
Save the screen as an image tiddler in SVG format
|
||||
</$button> [[$:/temp/screenshot.svg]]
|
||||
29
plugins/tiddlywiki/dom-to-image/files/LICENSE
Normal file
29
plugins/tiddlywiki/dom-to-image/files/LICENSE
Normal file
@@ -0,0 +1,29 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright 2018 Marc Brooks
|
||||
https://about.me/idisposable
|
||||
|
||||
Copyright 2015 Anatolii Saienko
|
||||
https://github.com/tsayen
|
||||
|
||||
Copyright 2012 Paul Bakaus
|
||||
http://paulbakaus.com/
|
||||
|
||||
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.
|
||||
3
plugins/tiddlywiki/dom-to-image/files/dom-to-image-more.min.js
vendored
Normal file
3
plugins/tiddlywiki/dom-to-image/files/dom-to-image-more.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
21
plugins/tiddlywiki/dom-to-image/files/tiddlywiki.files
Normal file
21
plugins/tiddlywiki/dom-to-image/files/tiddlywiki.files
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"tiddlers": [
|
||||
{
|
||||
"file": "dom-to-image-more.min.js",
|
||||
"fields": {
|
||||
"type": "application/javascript",
|
||||
"title": "$:/plugins/tiddlywiki/dom-to-image/dom-to-image-more.js",
|
||||
"module-type": "library",
|
||||
"url": "https://github.com/1904labs/dom-to-image-more",
|
||||
"version": "3.5.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"file": "LICENSE",
|
||||
"fields": {
|
||||
"type": "text/plain",
|
||||
"title": "$:/plugins/tiddlywiki/dom-to-image/dom-to-image-more/LICENSE"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
7
plugins/tiddlywiki/dom-to-image/plugin.info
Normal file
7
plugins/tiddlywiki/dom-to-image/plugin.info
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"title": "$:/plugins/tiddlywiki/dom-to-image",
|
||||
"name": "Dom-to-image",
|
||||
"description": "Save DOM nodes as images",
|
||||
"list": "readme docs",
|
||||
"stability": "STABILITY_1_EXPERIMENTAL"
|
||||
}
|
||||
3
plugins/tiddlywiki/dom-to-image/readme.tid
Normal file
3
plugins/tiddlywiki/dom-to-image/readme.tid
Normal file
@@ -0,0 +1,3 @@
|
||||
title: $:/plugins/tiddlywiki/dom-to-image/readme
|
||||
|
||||
* [[dom-to-image-more|https://github.com/1904labs/dom-to-image-more]], an open source library for saving web content as images
|
||||
92
plugins/tiddlywiki/dom-to-image/startup.js
Normal file
92
plugins/tiddlywiki/dom-to-image/startup.js
Normal file
@@ -0,0 +1,92 @@
|
||||
/*\
|
||||
title: $:/plugins/tiddlywiki/dom-to-image/startup.js
|
||||
type: application/javascript
|
||||
module-type: startup
|
||||
|
||||
dom-to-image initialisation
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
// Export name and synchronous status
|
||||
exports.name = "dom-to-image";
|
||||
exports.after = ["rootwidget"];
|
||||
exports.before = ["render"];
|
||||
exports.synchronous = true;
|
||||
|
||||
exports.startup = function() {
|
||||
var getPropertiesWithPrefix = function(properties,prefix) {
|
||||
var result = Object.create(null);
|
||||
$tw.utils.each(properties,function(value,name) {
|
||||
if(name.indexOf(prefix) === 0) {
|
||||
result[name.substring(prefix.length)] = properties[name];
|
||||
}
|
||||
});
|
||||
return result;
|
||||
};
|
||||
$tw.rootWidget.addEventListener("tm-save-dom-to-image",function(event) {
|
||||
var self=this,
|
||||
params = event.paramObject || {},
|
||||
domToImage = require("$:/plugins/tiddlywiki/dom-to-image/dom-to-image-more.js"),
|
||||
domNode = document.querySelector(params.selector || "body.tc-body"),
|
||||
oncompletion = params.oncompletion,
|
||||
variables = getPropertiesWithPrefix(params,"var-");
|
||||
if(domNode) {
|
||||
var method = "toPng";
|
||||
switch(params.format) {
|
||||
case "jpeg":
|
||||
// Intentional fallthrough
|
||||
case "jpg":
|
||||
method = "toJpeg";
|
||||
break;
|
||||
case "svg":
|
||||
method = "toSvg";
|
||||
break;
|
||||
}
|
||||
domToImage[method](domNode,{
|
||||
height: $tw.utils.parseInt(params.height) || domNode.offsetHeight,
|
||||
width: $tw.utils.parseInt(params.width) || domNode.offsetWidth,
|
||||
quality: $tw.utils.parseNumber(params.quality),
|
||||
scale: $tw.utils.parseNumber(params.scale) || 1
|
||||
})
|
||||
.then(function(dataUrl) {
|
||||
// Save the image
|
||||
if(params["save-file"]) {
|
||||
var link = document.createElement("a");
|
||||
link.download = params["save-file"];
|
||||
link.href = dataUrl;
|
||||
link.click();
|
||||
}
|
||||
// Save the tiddler
|
||||
if(params["save-title"]) {
|
||||
if(dataUrl.indexOf("data:image/svg+xml;") === 0) {
|
||||
var commaIndex = dataUrl.indexOf(",");
|
||||
$tw.wiki.addTiddler(new $tw.Tiddler({
|
||||
title: params["save-title"],
|
||||
type: "image/svg+xml",
|
||||
"text": decodeURIComponent(dataUrl.substring(commaIndex + 1))
|
||||
}));
|
||||
} else {
|
||||
var parts = dataUrl.split(";base64,");
|
||||
$tw.wiki.addTiddler(new $tw.Tiddler({
|
||||
title: params["save-title"],
|
||||
type: parts[0].split(":")[1],
|
||||
"text": parts[1]
|
||||
}));
|
||||
}
|
||||
}
|
||||
self.wiki.invokeActionString(oncompletion,self,variables,{parentWidget: $tw.rootWidget});
|
||||
})
|
||||
.catch(function(error) {
|
||||
console.error('oops, something went wrong!', error);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
@@ -25,6 +25,61 @@ exports.startup = function() {
|
||||
require("$:/plugins/tiddlywiki/geospatial/leaflet.markercluster.js");
|
||||
}
|
||||
// Install geolocation message handler
|
||||
$tw.rootWidget.addEventListener("tm-save-dom-to-image",function(event) {
|
||||
var params = event.paramObject || {},
|
||||
domToImage = require("$:/plugins/tiddlywiki/geospatial/dom-to-image-more.js"),
|
||||
domNode = document.querySelector(params.selector || "body.tc-body");
|
||||
if(domNode) {
|
||||
var method = "toPng";
|
||||
switch(params.format) {
|
||||
case "jpeg":
|
||||
// Intentional fallthrough
|
||||
case "jpg":
|
||||
method = "toJpeg";
|
||||
break;
|
||||
case "svg":
|
||||
method = "toSvg";
|
||||
break;
|
||||
}
|
||||
domToImage[method](domNode,{
|
||||
height: $tw.utils.parseInt(params.height) || domNode.offsetHeight,
|
||||
width: $tw.utils.parseInt(params.width) || domNode.offsetWidth,
|
||||
quality: $tw.utils.parseNumber(params.quality),
|
||||
scale: $tw.utils.parseNumber(params.scale) || 1
|
||||
})
|
||||
.then(function(dataUrl) {
|
||||
// Save the image
|
||||
if(params["save-file"]) {
|
||||
var link = document.createElement("a");
|
||||
link.download = params["save-file"];
|
||||
link.href = dataUrl;
|
||||
link.click();
|
||||
}
|
||||
// Save the tiddler
|
||||
if(params["save-title"]) {
|
||||
if(dataUrl.indexOf("data:image/svg+xml;") === 0) {
|
||||
var commaIndex = dataUrl.indexOf(",");
|
||||
$tw.wiki.addTiddler(new $tw.Tiddler({
|
||||
title: params["save-title"],
|
||||
type: "image/svg+xml",
|
||||
"text": decodeURIComponent(dataUrl.substring(commaIndex + 1))
|
||||
}));
|
||||
} else {
|
||||
var parts = dataUrl.split(";base64,");
|
||||
$tw.wiki.addTiddler(new $tw.Tiddler({
|
||||
title: params["save-title"],
|
||||
type: parts[0].split(":")[1],
|
||||
"text": parts[1]
|
||||
}));
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(function(error) {
|
||||
console.error('oops, something went wrong!', error);
|
||||
});
|
||||
}
|
||||
});
|
||||
// Install geolocation message handler
|
||||
$tw.rootWidget.addEventListener("tm-request-geolocation",function(event) {
|
||||
var widget = event.widget,
|
||||
wiki = widget.wiki || $tw.wiki,
|
||||
|
||||
Reference in New Issue
Block a user