Extends image widget with support for data-attributes and on load actions (#9050)

* feat: support for data-attributes and on load actions

* feat: support for data-attributes and on load actions

* fix: typo

* fix: simplify variable assignment

* docs: added changenote
This commit is contained in:
Saq Imtiaz
2026-02-04 11:12:58 +00:00
committed by GitHub
parent 891e4fcb2b
commit 2e76cc08a1
3 changed files with 60 additions and 6 deletions
+29 -5
View File
@@ -45,7 +45,7 @@ ImageWidget.prototype.render = function(parent,nextSibling) {
this.execute();
// Create element
// Determine what type of image it is
var tag = "img", src = "",
var tag = "img", src = "", self = this,
tiddler = this.wiki.getTiddler(this.imageSource);
if(!tiddler) {
// The source isn't the title of a tiddler, so we'll assume it's a URL
@@ -115,11 +115,21 @@ ImageWidget.prototype.render = function(parent,nextSibling) {
if(this.lazyLoading && tag === "img") {
domNode.setAttribute("loading",this.lazyLoading);
}
this.assignAttributes(domNode,{
sourcePrefix: "data-",
destPrefix: "data-"
});
// Add classes when the image loads or fails
$tw.utils.addClass(domNode,"tc-image-loading");
domNode.addEventListener("load",function() {
domNode.addEventListener("load",function(event) {
$tw.utils.removeClass(domNode,"tc-image-loading");
$tw.utils.addClass(domNode,"tc-image-loaded");
if(self.loadedActions) {
var variables = $tw.utils.collectDOMVariables(domNode,null,event);
variables["img-natural-width"] = domNode.naturalWidth.toString();
variables["img-natural-height"] = domNode.naturalHeight.toString();
self.invokeActionString(self.loadedActions,self,event,variables);
}
},false);
domNode.addEventListener("error",function() {
$tw.utils.removeClass(domNode,"tc-image-loading");
@@ -143,17 +153,31 @@ ImageWidget.prototype.execute = function() {
this.imageTooltip = this.getAttribute("tooltip");
this.imageAlt = this.getAttribute("alt");
this.lazyLoading = this.getAttribute("loading");
this.loadedActions = this.getAttribute("loadActions");
};
/*
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/
ImageWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(changedAttributes.source || changedAttributes.width || changedAttributes.height || changedAttributes["class"] || changedAttributes.usemap || changedAttributes.tooltip || changedTiddlers[this.imageSource]) {
var changedAttributes = this.computeAttributes(),
hasChangedAttributes = $tw.utils.count(changedAttributes) > 0;
if(changedAttributes.source || changedAttributes["class"] || changedAttributes.usemap || changedAttributes.tooltip || changedTiddlers[this.imageSource] ||changedAttributes.loadActions) {
this.refreshSelf();
return true;
} else {
} else if(hasChangedAttributes) {
this.assignAttributes(this.domNodes[0],{
sourcePrefix: "data-",
destPrefix: "data-"
});
if(changedAttributes.width) {
this.domNodes[0].setAttribute("width",this.getAttribute("width"));
}
if(changedAttributes.height) {
this.domNodes[0].setAttribute("height",this.getAttribute("height"));
}
}
else {
return false;
}
};
@@ -0,0 +1,13 @@
change-category: widget
change-type: enhancement
created: 20260126112805413
description: Allow actions to be invoked when an image is loaded
github-contributors: saqimtiaz
github-links: https://github.com/TiddlyWiki/TiddlyWiki5/pull/9050
modified: 20260126113146914
release: 5.4.0
tags: $:/tags/ChangeNote
title: $:/changenotes/5.4.0/#9050
type: text/vnd.tiddlywiki
Adds support to the image widget for optional actions that are invoked when an image has completed loading.
@@ -1,6 +1,6 @@
caption: image
created: 20140416160234142
modified: 20231121114351165
modified: 20260126114209242
tags: Widgets
title: ImageWidget
type: text/vnd.tiddlywiki
@@ -22,9 +22,26 @@ Any content of the `<$image>` widget is ignored.
|class |CSS classes to be assigned to the `<img>` element |
|loading|<<.from-version "5.2.3">>Optional. Set to `lazy` to enable lazy loading of images loaded from an external URI |
|usemap|<<.from-version "5.3.2">>Optional usemap attribute to be assigned to the `<img>` element for use with HTML image maps |
|loadActions|<<.from-version "5.4.0">>Optional actions invoked when the image has completed loading. See below for variables passed to the actions.|
The width and the height can be specified as pixel values (eg "23" or "23px") or percentages (eg "23%"). They are both optional; if not provided the browser will use CSS rules to size the image.
'' The following variables are accessible in the //loadActions//:''
<<.from-version 5.4.0>>
|!Variables |!Description |
|`dom-*` |All DOM attributes of the image are made available as variables, with the prefix `dom-` |
|`tv-popup-coords` |A relative co-ordinate string that can be used with the ActionPopupWidget to trigger a popup at the image|
|`tv-popup-abs-coords` |<<.from-version "5.2.4">> An absolute co-ordinate string that can be used with the ActionPopupWidget to trigger a popup at the image (see [[Coordinate Systems]] for more information) |
|`tv-selectednode-posx` |`x` offset position of the image DOM node |
|`tv-selectednode-posy` |`y` offset position of the image DOM node |
|`tv-selectednode-width` |`offsetWidth` of the image DOM node |
|`tv-selectednode-height` |`offsetHeight` of the image DOM node |
|`img-natural-width` |Original intrinsic width of the image |
|`img-natural-height` |Original intrinsic height of the image |
! Responsive images and `<map>`
[[Image maps area|https://developer.mozilla.org/en-US/docs/Web/HTML/Element/area]] coordinates are numbers of CSS pixels, therefore they do not scale. If you want to use responsive images, you can use a `svg` and `foreignObject`: