feat: v1.13-rc

release candidate for global accessibility awareness day updates
This commit is contained in:
wolfgang101 2025-05-15 14:26:37 +02:00
parent ff15693136
commit 306b873af0
3 changed files with 72 additions and 29 deletions

View File

@ -2,7 +2,7 @@
Plugin that provides an `[include-mastodon-feed]` shortcode to easily integrate mastodon feeds into wordpress pages. Supports personal and tag feeds. Plugin that provides an `[include-mastodon-feed]` shortcode to easily integrate mastodon feeds into wordpress pages. Supports personal and tag feeds.
Account and post images are automatically lazy loaded - post image lazy loading only works with preserveImageAspectRatio set to true. Account and post images are lazy loaded if preserveImageAspectRatio is set to true (default: false).
The plugin is written in PHP and generates native JavaScript to fetch and render the mastodon feed. No special libraries needed. The plugin is written in PHP and generates native JavaScript to fetch and render the mastodon feed. No special libraries needed.

View File

@ -3,7 +3,7 @@
Plugin Name: Include Mastodon Feed Plugin Name: Include Mastodon Feed
Plugin URI: https://wolfgang.lol/code/include-mastodon-feed-wordpress-plugin Plugin URI: https://wolfgang.lol/code/include-mastodon-feed-wordpress-plugin
Description: Plugin providing [include-mastodon-feed] shortcode Description: Plugin providing [include-mastodon-feed] shortcode
Version: 1.12 Version: 1.13
Author: wolfgang.lol Author: wolfgang.lol
Author URI: https://wolfgang.lol Author URI: https://wolfgang.lol
License: MIT License: MIT
@ -86,7 +86,7 @@ $constants = [
], ],
[ [
'key' => 'INCLUDE_MASTODON_FEED_STYLE_ACCENT_COLOR', 'key' => 'INCLUDE_MASTODON_FEED_STYLE_ACCENT_COLOR',
'value' => 'rgb(99, 100, 255)', 'value' => 'rgb(86, 58, 204)',
], ],
[ [
'key' => 'INCLUDE_MASTODON_FEED_STYLE_ACCENT_FONT_COLOR', 'key' => 'INCLUDE_MASTODON_FEED_STYLE_ACCENT_FONT_COLOR',
@ -169,7 +169,12 @@ function init_styles() {
--include-mastodon-feed-border-radius: <?php echo filter_var( INCLUDE_MASTODON_FEED_STYLE_BORDER_RADIUS, FILTER_UNSAFE_RAW ); ?>; --include-mastodon-feed-border-radius: <?php echo filter_var( INCLUDE_MASTODON_FEED_STYLE_BORDER_RADIUS, FILTER_UNSAFE_RAW ); ?>;
} }
.include-mastodon-feed-wrapper .include-mastodon-feed {
list-style: none;
padding-left: 0;
}
.include-mastodon-feed .status { .include-mastodon-feed .status {
display: block;
margin: 0.5rem 0 1.5rem; margin: 0.5rem 0 1.5rem;
border-radius: var(--include-mastodon-feed-border-radius); border-radius: var(--include-mastodon-feed-border-radius);
padding: 0.5rem; padding: 0.5rem;
@ -184,6 +189,7 @@ function init_styles() {
text-decoration: underline; text-decoration: underline;
} }
.include-mastodon-feed .avatar { .include-mastodon-feed .avatar {
display: inline-block;
height: 1.25rem; height: 1.25rem;
border-radius: var(--include-mastodon-feed-border-radius); border-radius: var(--include-mastodon-feed-border-radius);
vertical-align: top; vertical-align: top;
@ -234,13 +240,16 @@ function init_styles() {
} }
.include-mastodon-feed .media { .include-mastodon-feed .media {
display: flex; display: flex;
list-style: none;
padding: 0;
justify-content: space-around; justify-content: space-around;
align-items: center; align-items: center;
flex-wrap: wrap; flex-wrap: wrap;
gap: 0.5rem; gap: 0.5rem;
margin: 1rem; margin: 1rem;
} }
.include-mastodon-feed .media > div { .include-mastodon-feed .media > * {
display: block;
flex-basis: calc(50% - 0.5rem); flex-basis: calc(50% - 0.5rem);
flex-grow: 1; flex-grow: 1;
} }
@ -330,10 +339,12 @@ function init_scripts() {
const mastodonFeedCreateElementAccountLink = function(account) { const mastodonFeedCreateElementAccountLink = function(account) {
let accountLinkElem = mastodonFeedCreateElement('a'); let accountLinkElem = mastodonFeedCreateElement('a');
accountLinkElem.href = account.url; accountLinkElem.href = account.url;
accountLinkElem.setAttribute('aria-label', 'Link to Mastodon account of ' + account.display_name);
let accountImageElem = mastodonFeedCreateElement('img', 'avatar'); let accountImageElem = mastodonFeedCreateElement('img', 'avatar');
accountImageElem.src = account.avatar_static; accountImageElem.src = account.avatar_static;
accountImageElem.loading = 'lazy'; accountImageElem.loading = 'lazy';
accountImageElem.alt = 'Mastodon avatar image of ' + account.display_name;
accountLinkElem.addEventListener('mouseover', (event) => { accountLinkElem.addEventListener('mouseover', (event) => {
accountLinkElem.querySelector('.avatar').src = account.avatar; accountLinkElem.querySelector('.avatar').src = account.avatar;
@ -354,21 +365,23 @@ function init_scripts() {
return accountLinkElem; return accountLinkElem;
} }
const mastodonFeedCreateElementPermalink = function(status, label) { const mastodonFeedCreateElementPermalink = function(status, label, ariaLabel) {
let linkElem = mastodonFeedCreateElement('a'); let linkElem = mastodonFeedCreateElement('a');
linkElem.href = status.url; linkElem.href = status.url;
linkElem.appendChild(document.createTextNode(label)); linkElem.appendChild(document.createTextNode(label));
linkElem.setAttribute('aria-label', ariaLabel);
return linkElem; return linkElem;
} }
const mastodonFeedCreateElementMediaAttachments = function(status, options) { const mastodonFeedCreateElementMediaAttachments = function(status, options) {
let attachments = status.media_attachments; let attachments = status.media_attachments;
let mediaWrapperElem = mastodonFeedCreateElement('div', 'media'); let mediaWrapperElem = mastodonFeedCreateElement('ol', 'media');
for(let mediaIndex = 0; mediaIndex < attachments.length; mediaIndex++) { for(let mediaIndex = 0; mediaIndex < attachments.length; mediaIndex++) {
let media = attachments[mediaIndex]; let media = attachments[mediaIndex];
let mediaElem = mastodonFeedCreateElement('div', media.type); let mediaElem = mastodonFeedCreateElement('li', media.type);
if('image' == media.type) { if('image' == media.type) {
let mediaElemImgLink = mastodonFeedCreateElement('a'); let mediaElemImgLink = mastodonFeedCreateElement('a');
mediaElemImgLink.setAttribute('aria-label', 'Link to Mastodon post');
let imageUrl = media.url; let imageUrl = media.url;
if('full' !== options.images.size && null !== media.preview_url) { if('full' !== options.images.size && null !== media.preview_url) {
imageUrl = media.preview_url; imageUrl = media.preview_url;
@ -376,25 +389,30 @@ function init_scripts() {
mediaElemImgLink.href = status.url; mediaElemImgLink.href = status.url;
if('image' === options.images.link) { if('image' === options.images.link) {
mediaElemImgLink.href = media.remote_url ?? media.url; mediaElemImgLink.href = media.remote_url ?? media.url;
mediaElemImgLink.setAttribute('aria-label', 'Link to Mastodon post image');
} }
if(null !== media.description) {
mediaElem.title = media.description;
mediaElem.alt = media.description;
}
if(options.images.preserveImageAspectRatio) {
let mediaElemImgImage = mastodonFeedCreateElement('img'); let mediaElemImgImage = mastodonFeedCreateElement('img');
mediaElemImgImage.src = imageUrl; mediaElemImgImage.src = imageUrl;
mediaElemImgImage.loading = 'lazy'; mediaElemImgImage.loading = 'lazy';
mediaElemImgLink.appendChild(mediaElemImgImage); if(null === media.description) {
mediaElemImgImage.alt = 'Image attachment of Mastodon post';
} }
else { else {
mediaElemImgLink.style.backgroundImage = 'url("' + imageUrl + '")'; mediaElemImgImage.alt = media.description;
} }
if(!options.images.preserveImageAspectRatio) {
mediaElemImgLink.style.backgroundImage = 'url("' + imageUrl + '")';
mediaElemImgImage.style.width = '100%';
mediaElemImgImage.style.height = '100%';
mediaElemImgImage.style.opacity = 0;
}
mediaElemImgLink.appendChild(mediaElemImgImage);
mediaElem.appendChild(mediaElemImgLink); mediaElem.appendChild(mediaElemImgLink);
} }
else if('gifv' == media.type) { else if('gifv' == media.type) {
let mediaElemGifvLink = mastodonFeedCreateElement('a'); let mediaElemGifvLink = mastodonFeedCreateElement('a');
mediaElemGifvLink.href = status.url; mediaElemGifvLink.href = status.url;
mediaElemGifvLink.setAttribute('aria-label', 'Link to Mastodon post');
let mediaElemGifv = mastodonFeedCreateElement('video', 'requiresInteraction'); let mediaElemGifv = mastodonFeedCreateElement('video', 'requiresInteraction');
if(null === media.remote_url) { if(null === media.remote_url) {
mediaElemGifv.src = media.url; mediaElemGifv.src = media.url;
@ -404,8 +422,10 @@ function init_scripts() {
} }
mediaElemGifv.loop = true; mediaElemGifv.loop = true;
mediaElemGifv.muted = 'muted'; mediaElemGifv.muted = 'muted';
if(null !== media.description) { if(null === media.description) {
mediaElemGifv.title = media.description; mediaElemGifv.alt = 'Video attachment of Mastodon post';
}
else {
mediaElemGifv.alt = media.description; mediaElemGifv.alt = media.description;
} }
mediaElemGifvLink.appendChild(mediaElemGifv); mediaElemGifvLink.appendChild(mediaElemGifv);
@ -424,7 +444,7 @@ function init_scripts() {
// currently only image and gifv support implemented // currently only image and gifv support implemented
mediaElem.innerHTML = 'Stripped ' + media.type + ' - only available on instance<br />'; mediaElem.innerHTML = 'Stripped ' + media.type + ' - only available on instance<br />';
let permalinkElem = mastodonFeedCreateElement('span', 'permalink'); let permalinkElem = mastodonFeedCreateElement('span', 'permalink');
permalinkElem.appendChild(mastodonFeedCreateElementPermalink(status, options.text.viewOnInstance)); permalinkElem.appendChild(mastodonFeedCreateElementPermalink(status, options.text.viewOnInstance, 'Link to Mastodon post'));
mediaElem.appendChild(permalinkElem); mediaElem.appendChild(permalinkElem);
} }
mediaWrapperElem.appendChild(mediaElem); mediaWrapperElem.appendChild(mediaElem);
@ -441,6 +461,12 @@ function init_scripts() {
if(null !== card.image) { if(null !== card.image) {
let cardElemImageWrapper = mastodonFeedCreateElement('div', 'image'); let cardElemImageWrapper = mastodonFeedCreateElement('div', 'image');
let cardElemImage = mastodonFeedCreateElement('img'); let cardElemImage = mastodonFeedCreateElement('img');
if(null === card.image_description) {
cardElemImage.alt = 'Preview image content card';
}
else {
cardElemImage.alt = card.image_description;
}
cardElemImage.src = card.image; cardElemImage.src = card.image;
cardElemImage.loading = 'lazy'; cardElemImage.loading = 'lazy';
cardElemImageWrapper.appendChild(cardElemImage); cardElemImageWrapper.appendChild(cardElemImage);
@ -461,6 +487,7 @@ function init_scripts() {
else { else {
let cardElemLink = mastodonFeedCreateElement('a'); let cardElemLink = mastodonFeedCreateElement('a');
cardElemLink.href = card.url; cardElemLink.href = card.url;
cardElemLink.setAttribute('aria-label', 'Link embedded in Mastodon post');
cardElemLink.appendChild(cardElemMeta); cardElemLink.appendChild(cardElemMeta);
cardElem.appendChild(cardElemLink); cardElem.appendChild(cardElemLink);
} }
@ -478,7 +505,7 @@ function init_scripts() {
createdInfo.innerHTML += new Date(status.created_at).toLocaleString(options.localization.date.locale, options.localization.date.options); createdInfo.innerHTML += new Date(status.created_at).toLocaleString(options.localization.date.locale, options.localization.date.options);
} }
else { else {
createdInfo.appendChild(mastodonFeedCreateElementPermalink(status, new Date(status.created_at).toLocaleString(options.localization.date.locale, options.localization.date.options))); createdInfo.appendChild(mastodonFeedCreateElementPermalink(status, new Date(status.created_at).toLocaleString(options.localization.date.locale, options.localization.date.options), 'Link to Mastodon post'));
} }
createdInfo.innerHTML += ' ' + options.text.permalinkPost; createdInfo.innerHTML += ' ' + options.text.permalinkPost;
return createdInfo; return createdInfo;
@ -498,7 +525,7 @@ function init_scripts() {
let isEdited = (null === status.edited_at ? true : false); let isEdited = (null === status.edited_at ? true : false);
let isReblog = (null === status.reblog ? false : true); let isReblog = (null === status.reblog ? false : true);
let statusElem = mastodonFeedCreateElement('div', 'status'); let statusElem = mastodonFeedCreateElement('li', 'status');
// add account meta info // add account meta info
if(!options.content.hideStatusMeta) { if(!options.content.hideStatusMeta) {
@ -549,6 +576,7 @@ function init_scripts() {
let cwLinkElem = mastodonFeedCreateElement('a'); let cwLinkElem = mastodonFeedCreateElement('a');
cwLinkElem.href = '#'; cwLinkElem.href = '#';
cwLinkElem.setAttribute('aria-label', 'Show content despite warning');
cwLinkElem.onclick = function() { cwLinkElem.onclick = function() {
this.parentElement.style = 'display: none;'; this.parentElement.style = 'display: none;';
this.parentElement.nextSibling.style = 'display: block;'; this.parentElement.nextSibling.style = 'display: block;';
@ -588,11 +616,12 @@ function init_scripts() {
rootElem.appendChild(statusElem); rootElem.appendChild(statusElem);
} }
} }
if('_self' != options.linkTarget) {
rootElem.querySelectorAll('a').forEach(function(e) { rootElem.querySelectorAll('a').forEach(function(e) {
if('_self' != options.linkTarget) {
e.target = options.linkTarget; e.target = options.linkTarget;
});
} }
mediaElemGifvLink.setAttribute('aria-label', 'Link embedded in Mastodon post');
});
} }
const mastodonFeedLoad = function(url, elementId, options) { const mastodonFeedLoad = function(url, elementId, options) {
@ -759,7 +788,7 @@ function display_feed($atts) {
); );
}); });
</script> </script>
<div class="include-mastodon-feed<?php echo (true == $atts['darkmode'] ? ' dark' : ''); ?>" id="<?php echo esc_attr( $elemId ); ?>"><?php echo esc_html( $atts['text-loading'] ); ?></div> <div class="include-mastodon-feed-wrapper"><ol class="include-mastodon-feed<?php echo (true == $atts['darkmode'] ? ' dark' : ''); ?>" id="<?php echo esc_attr( $elemId ); ?>"><li><?php echo esc_html( $atts['text-loading'] ); ?></li></ol></div>
<?php <?php
return ob_get_clean(); return ob_get_clean();
} }

View File

@ -5,7 +5,7 @@ Tags: mastodon, status, feed
Requires at least: 6.0 Requires at least: 6.0
Tested up to: 6.8 Tested up to: 6.8
Requires PHP: 7.4 Requires PHP: 7.4
Stable tag: 1.12 Stable tag: 1.13
License: MIT License: MIT
License URI: https://directory.fsf.org/wiki/License:Expat License URI: https://directory.fsf.org/wiki/License:Expat
@ -14,7 +14,7 @@ Plugin that provides a shortcode to easily integrate mastodon feeds into wordpre
== Description == == Description ==
Plugin that provides an `[include-mastodon-feed]` shortcode to easily integrate mastodon feeds into wordpress pages. Supports personal and tag feeds. Plugin that provides an `[include-mastodon-feed]` shortcode to easily integrate mastodon feeds into wordpress pages. Supports personal and tag feeds.
Account and post images are automatically lazy loaded - post image lazy loading only works with preserveImageAspectRatio set to true. Account and post images are lazy loaded if preserveImageAspectRatio is set to true (default: false).
The plugin is written in PHP and generates native JavaScript to fetch and render the mastodon feed. No special libraries needed. The plugin is written in PHP and generates native JavaScript to fetch and render the mastodon feed. No special libraries needed.
@ -154,6 +154,20 @@ Use the following URL to get your ID:
== Changelog == == Changelog ==
= 1.13 =
Special release for Global Accessibility Awareness Day
in collaboration with @oldrup@mastodon.green
Happy [Accesssibility Day](https://accessibility.day)
* accessibility (fix): image alt attributes - initial implementation was faulty
* accessibility: added alt text to image / video attachments
* accessibility: added alt text to avatar images
* accessibility: added descriptive aria-label to links
* accessibility: added aria-label and alt text to preview cards
* accessibility: increased default text / background color contrast
* accessibility: switched from <DIV> to semantic <OL> / <LI> structure
= 1.12 = = 1.12 =
* accessibility: added image alt attribute (thank you @oldrup@mastodon.green) * accessibility: added image alt attribute (thank you @oldrup@mastodon.green)