--- a/wp/wp-content/plugins/include-mastodon-feed/plugin.php Fri Sep 05 18:52:52 2025 +0200
+++ b/wp/wp-content/plugins/include-mastodon-feed/plugin.php Mon Sep 08 19:44:41 2025 +0200
@@ -3,9 +3,11 @@
Plugin Name: Include Mastodon Feed
Plugin URI: https://wolfgang.lol/code/include-mastodon-feed-wordpress-plugin
Description: Plugin providing [include-mastodon-feed] shortcode
- Version: 1.9.4
+ Version: 1.13.1
Author: wolfgang.lol
Author URI: https://wolfgang.lol
+ License: MIT
+ License URI: https://directory.fsf.org/wiki/License:Expat
*/
namespace IncludeMastodonFeedPlugin;
@@ -49,6 +51,14 @@
'value' => false,
],
[
+ 'key' => 'INCLUDE_MASTODON_FEED_IMAGE_SIZE',
+ 'value' => 'preview',
+ ],
+ [
+ 'key' => 'INCLUDE_MASTODON_FEED_IMAGE_LINK',
+ 'value' => 'status',
+ ],
+ [
'key' => 'INCLUDE_MASTODON_FEED_TAGGED',
'value' => false,
],
@@ -76,7 +86,7 @@
],
[
'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',
@@ -101,7 +111,7 @@
],
[
'key' => 'INCLUDE_MASTODON_FEED_TEXT_NO_STATUSES',
- 'value' => 'No statuses availablae',
+ 'value' => 'No statuses available',
],
[
'key' => 'INCLUDE_MASTODON_FEED_TEXT_BOOSTED',
@@ -149,7 +159,6 @@
function init_styles() {
- ob_start();
?>
<style>
:root {
@@ -160,7 +169,12 @@
--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 {
+ display: block;
margin: 0.5rem 0 1.5rem;
border-radius: var(--include-mastodon-feed-border-radius);
padding: 0.5rem;
@@ -175,6 +189,7 @@
text-decoration: underline;
}
.include-mastodon-feed .avatar {
+ display: inline-block;
height: 1.25rem;
border-radius: var(--include-mastodon-feed-border-radius);
vertical-align: top;
@@ -225,13 +240,16 @@
}
.include-mastodon-feed .media {
display: flex;
+ list-style: none;
+ padding: 0;
justify-content: space-around;
align-items: center;
flex-wrap: wrap;
gap: 0.5rem;
margin: 1rem;
}
- .include-mastodon-feed .media > div {
+ .include-mastodon-feed .media > * {
+ display: block;
flex-basis: calc(50% - 0.5rem);
flex-grow: 1;
}
@@ -303,12 +321,10 @@
}
</style>
<?php
- echo ob_get_clean();
}
add_action('wp_head', __NAMESPACE__ . '\init_styles', 7);
function init_scripts() {
- ob_start();
?>
<script>
@@ -323,9 +339,12 @@
const mastodonFeedCreateElementAccountLink = function(account) {
let accountLinkElem = mastodonFeedCreateElement('a');
accountLinkElem.href = account.url;
+ accountLinkElem.setAttribute('aria-label', 'Link to Mastodon account of ' + account.display_name);
let accountImageElem = mastodonFeedCreateElement('img', 'avatar');
accountImageElem.src = account.avatar_static;
+ accountImageElem.loading = 'lazy';
+ accountImageElem.alt = 'Mastodon avatar image of ' + account.display_name;
accountLinkElem.addEventListener('mouseover', (event) => {
accountLinkElem.querySelector('.avatar').src = account.avatar;
@@ -346,41 +365,46 @@
return accountLinkElem;
}
- const mastodonFeedCreateElementPermalink = function(status, label) {
+ const mastodonFeedCreateElementPermalink = function(status, label, ariaLabel) {
let linkElem = mastodonFeedCreateElement('a');
linkElem.href = status.url;
linkElem.appendChild(document.createTextNode(label));
+ linkElem.setAttribute('aria-label', ariaLabel);
return linkElem;
}
const mastodonFeedCreateElementMediaAttachments = function(status, options) {
let attachments = status.media_attachments;
- let mediaWrapperElem = mastodonFeedCreateElement('div', 'media');
+ let mediaWrapperElem = mastodonFeedCreateElement('ol', 'media');
for(let mediaIndex = 0; mediaIndex < attachments.length; mediaIndex++) {
let media = attachments[mediaIndex];
- let mediaElem = mastodonFeedCreateElement('div', media.type);
+ let mediaElem = mastodonFeedCreateElement('li', media.type);
if('image' == media.type) {
let mediaElemImgLink = mastodonFeedCreateElement('a');
+ let imageUrl = media.url;
+ if('full' !== options.images.size && null !== media.preview_url) {
+ imageUrl = media.preview_url;
+ }
mediaElemImgLink.href = status.url;
- if(null === media.remote_url) {
- mediaElemImgLink.style.backgroundImage = 'url("' + media.preview_url + '")';
+ if('image' === options.images.link) {
+ mediaElemImgLink.href = media.remote_url ?? media.url;
+ }
+ let mediaElemImgImage = mastodonFeedCreateElement('img');
+ mediaElemImgImage.src = imageUrl;
+ mediaElemImgImage.loading = 'lazy';
+ if(null === media.description) {
+ mediaElemImgImage.alt = 'Image attachment of Mastodon post';
}
else {
- mediaElemImgLink.style.backgroundImage = 'url("' + media.remote_url + '")';
- }
- if(null !== media.description) {
- mediaElem.title = media.description;
+ mediaElemImgImage.alt = media.description;
}
- if(options.preserveImageAspectRatio) {
- let mediaElemImgImage = mastodonFeedCreateElement('img');
- if(null === media.remote_url) {
- mediaElemImgImage.src = media.preview_url;
- }
- else {
- mediaElemImgImage.src = media.remote_url;
- }
- mediaElemImgLink.appendChild(mediaElemImgImage);
+ 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);
}
else if('gifv' == media.type) {
@@ -395,8 +419,11 @@
}
mediaElemGifv.loop = true;
mediaElemGifv.muted = 'muted';
- if(null !== media.description) {
- mediaElemGifv.title = media.description;
+ if(null === media.description) {
+ mediaElemGifv.alt = 'Video attachment of Mastodon post';
+ }
+ else {
+ mediaElemGifv.alt = media.description;
}
mediaElemGifvLink.appendChild(mediaElemGifv);
mediaElem.appendChild(mediaElemGifvLink);
@@ -414,7 +441,7 @@
// currently only image and gifv support implemented
mediaElem.innerHTML = 'Stripped ' + media.type + ' - only available on instance<br />';
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);
}
mediaWrapperElem.appendChild(mediaElem);
@@ -431,7 +458,14 @@
if(null !== card.image) {
let cardElemImageWrapper = mastodonFeedCreateElement('div', 'image');
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.loading = 'lazy';
cardElemImageWrapper.appendChild(cardElemImage);
cardElemMeta.appendChild(cardElemImageWrapper);
}
@@ -450,6 +484,7 @@
else {
let cardElemLink = mastodonFeedCreateElement('a');
cardElemLink.href = card.url;
+ cardElemLink.setAttribute('aria-label', 'Link embedded in Mastodon post');
cardElemLink.appendChild(cardElemMeta);
cardElem.appendChild(cardElemLink);
}
@@ -467,7 +502,7 @@
createdInfo.innerHTML += new Date(status.created_at).toLocaleString(options.localization.date.locale, options.localization.date.options);
}
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;
return createdInfo;
@@ -479,7 +514,6 @@
const mastodonFeedRenderStatuses = function(statuses, rootElem, options) {
if(statuses.length < 1) {
- console.log(options);
rootElem.innerHTML = options.text.noStatuses;
}
else {
@@ -488,7 +522,7 @@
let isEdited = (null === status.edited_at ? true : false);
let isReblog = (null === status.reblog ? false : true);
- let statusElem = mastodonFeedCreateElement('div', 'status');
+ let statusElem = mastodonFeedCreateElement('li', 'status');
// add account meta info
if(!options.content.hideStatusMeta) {
@@ -539,6 +573,7 @@
let cwLinkElem = mastodonFeedCreateElement('a');
cwLinkElem.href = '#';
+ cwLinkElem.setAttribute('aria-label', 'Show content despite warning');
cwLinkElem.onclick = function() {
this.parentElement.style = 'display: none;';
this.parentElement.nextSibling.style = 'display: block;';
@@ -578,11 +613,11 @@
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;
- });
- }
+ }
+ });
}
const mastodonFeedLoad = function(url, elementId, options) {
@@ -594,11 +629,13 @@
const rootElem = document.getElementById(elementId);
rootElem.innerHTML = '';
<?php if(true === INCLUDE_MASTODON_FEED_DEBUG) : ?>
- console.log("<?php echo __NAMESPACE__; ?>", url);
+ console.log("<?php echo __NAMESPACE__; ?>", 'url', url);
+ console.log("<?php echo __NAMESPACE__; ?>", 'elementId', elementId);
+ console.log("<?php echo __NAMESPACE__; ?>", 'options', options);
<?php endif; ?>
if (xhr.status === 200) {
<?php if(true === INCLUDE_MASTODON_FEED_DEBUG) : ?>
- console.log("<?php echo __NAMESPACE__; ?>", xhr.response);
+ console.log("<?php echo __NAMESPACE__; ?>", 'response', xhr.response);
<?php endif; ?>
if(options.excludeConversationStarters && statuses.length > 0) {
const filteredStatuses = [];
@@ -625,7 +662,7 @@
}
else {
<?php if(true === INCLUDE_MASTODON_FEED_DEBUG) : ?>
- console.log("<?php echo __NAMESPACE__; ?>", xhr);
+ console.log("<?php echo __NAMESPACE__; ?>", 'response error', xhr);
<?php endif; ?>
rootElem.appendChild(document.createTextNode(xhr.response.error));
}
@@ -634,7 +671,6 @@
}
</script>
<?php
- echo ob_get_clean();
}
add_action('wp_footer', __NAMESPACE__ . '\init_scripts');
@@ -651,6 +687,8 @@
'onlypinned' => filter_var(esc_html(INCLUDE_MASTODON_FEED_ONLY_PINNED), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE),
'onlymedia' => filter_var(esc_html(INCLUDE_MASTODON_FEED_ONLY_MEDIA), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE),
'preserveimageaspectratio' => filter_var(esc_html(INCLUDE_MASTODON_FEED_PRESERVE_IMAGE_ASPECT_RATIO), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE),
+ 'imagesize' => INCLUDE_MASTODON_FEED_IMAGE_SIZE,
+ 'imagelink' => INCLUDE_MASTODON_FEED_IMAGE_LINK,
'tagged' => INCLUDE_MASTODON_FEED_TAGGED,
'linktarget' => INCLUDE_MASTODON_FEED_LINKTARGET,
'showpreviewcards' => filter_var(esc_html(INCLUDE_MASTODON_FEED_SHOW_PREVIEWCARDS), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE),
@@ -665,7 +703,6 @@
'text-permalinkpost' => INCLUDE_MASTODON_FEED_TEXT_PERMALINK_POST,
'text-edited' => INCLUDE_MASTODON_FEED_TEXT_EDITED,
'date-locale' => INCLUDE_MASTODON_FEED_DATE_LOCALE,
- 'date-options' => INCLUDE_MASTODON_FEED_DATE_OPTIONS,
'darkmode' => filter_var(esc_html(INCLUDE_MASTODON_FEED_DARKMODE), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE),
), array_change_key_case($atts, CASE_LOWER)
);
@@ -713,37 +750,41 @@
<script>
window.addEventListener("load", () => {
mastodonFeedLoad(
- "<?php echo sanitize_url( $apiUrl, ['https'] ); ?>",
+ "<?php echo esc_url( $apiUrl, ['https'], 'apicall' ); ?>",
"<?php echo filter_var( $elemId, FILTER_UNSAFE_RAW ); ?>",
{
- linkTarget: "<?php echo filter_var( $atts['linktarget'], FILTER_UNSAFE_RAW ); ?>",
+ linkTarget: "<?php echo esc_js(filter_var( $atts['linktarget'], FILTER_UNSAFE_RAW )); ?>",
showPreviewCards: <?php echo (filter_var( $atts['showpreviewcards'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) ? "true" : "false"); ?>,
excludeConversationStarters: <?php echo (filter_var( $atts['excludeconversationstarters'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) ? "true" : "false"); ?>,
- preserveImageAspectRatio: <?php echo (filter_var( $atts['preserveimageaspectratio'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) ? "true" : "false"); ?>,
content: {
hideStatusMeta: <?php echo (filter_var( $atts['hidestatusmeta'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) ? "true" : "false"); ?>,
hideDateTime: <?php echo (filter_var( $atts['hidedatetime'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) ? "true" : "false"); ?>
},
+ images: {
+ preserveImageAspectRatio: <?php echo (filter_var( $atts['preserveimageaspectratio'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) ? "true" : "false"); ?>,
+ size: "<?php echo ( "full" === $atts['imagesize'] ? "full" : "preview" ); ?>",
+ link: "<?php echo ( "image" === $atts['imagelink'] ? "image" : "status" ); ?>",
+ },
text: {
- boosted: "<?php echo esc_js( $atts['text-boosted'] ); ?>",
+ boosted: "<?php echo esc_html( $atts['text-boosted'] ); ?>",
noStatuses: "<?php echo esc_html( $atts['text-nostatuses'] ); ?>",
viewOnInstance: "<?php echo esc_js( $atts['text-viewoninstance'] ); ?>",
- showContent: "<?php echo esc_js( $atts['text-showcontent'] ); ?>",
- permalinkPre: "<?php echo esc_js( $atts['text-permalinkpre'] ); ?>",
- permalinkPost: "<?php echo esc_js( $atts['text-permalinkpost'] ); ?>",
- edited: "<?php echo esc_js( $atts['text-edited'] ); ?>",
+ showContent: "<?php echo esc_html( $atts['text-showcontent'] ); ?>",
+ permalinkPre: "<?php echo esc_html( $atts['text-permalinkpre'] ); ?>",
+ permalinkPost: "<?php echo esc_html( $atts['text-permalinkpost'] ); ?>",
+ edited: "<?php echo esc_html( $atts['text-edited'] ); ?>",
},
localization: {
date: {
- locale: "<?php echo filter_var( $atts['date-locale'], FILTER_UNSAFE_RAW ); ?>",
- options: <?php echo filter_var( $atts['date-options'], FILTER_UNSAFE_RAW ); ?>,
+ locale: "<?php echo esc_js( filter_var( $atts['date-locale'], FILTER_UNSAFE_RAW ) ); ?>",
+ options: <?php echo filter_var( INCLUDE_MASTODON_FEED_DATE_OPTIONS, FILTER_UNSAFE_RAW ); ?>,
}
}
}
);
});
</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
return ob_get_clean();
}