mirror of
https://gitlab.com/idotj/mastodon-embed-timeline.git
synced 2025-05-24 08:52:46 +00:00
Merge branch 'fix/csp-improvements' into 'master'
Fix/CSP improvements See merge request idotj/mastodon-embed-feed-timeline!20
This commit is contained in:
commit
30e393cb0a
@ -1,4 +1,8 @@
|
|||||||
v3.8.2 - xx/08/2023
|
v3.9.0 - 02/09/2023
|
||||||
|
- Fix Content Security Policy
|
||||||
|
- Fix account name shown
|
||||||
|
|
||||||
|
v3.8.2 - 26/08/2023
|
||||||
- Add support to customized emojis
|
- Add support to customized emojis
|
||||||
- Javascript refactoring to allow multiple requests
|
- Javascript refactoring to allow multiple requests
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Mastodon embed feed timeline v3.8.2 */
|
/* Mastodon embed feed timeline v3.9.0 */
|
||||||
/* More info at: */
|
/* More info at: */
|
||||||
/* https://gitlab.com/idotj/mastodon-embed-feed-timeline */
|
/* https://gitlab.com/idotj/mastodon-embed-feed-timeline */
|
||||||
|
|
||||||
@ -93,28 +93,34 @@ html[data-theme="dark"] {
|
|||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* User icon */
|
/* User avatar and name */
|
||||||
.mt-avatar {
|
.mt-avatar {
|
||||||
|
width: 3rem;
|
||||||
|
height: 3rem;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 1rem;
|
top: 1rem;
|
||||||
left: 0.25rem;
|
left: 0.25rem;
|
||||||
width: 3rem;
|
|
||||||
height: 3rem;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: 50% 50%;
|
|
||||||
background-size: contain;
|
|
||||||
background-color: var(--bg-color);
|
|
||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.mt-avatar-boosted {
|
.mt-avatar-image img {
|
||||||
width: 2.5rem;
|
width: 100%;
|
||||||
height: 2.5rem;
|
height: auto;
|
||||||
}
|
}
|
||||||
.mt-avatar-booster {
|
.mt-avatar-image .mt-avatar-boosted {
|
||||||
|
width: 2.25rem;
|
||||||
|
height: 2.25rem;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.mt-avatar-image .mt-avatar-account {
|
||||||
width: 1.5rem;
|
width: 1.5rem;
|
||||||
height: 1.5rem;
|
height: 1.5rem;
|
||||||
top: 1.5rem;
|
top: 1.5rem;
|
||||||
left: 1.5rem;
|
left: 1.5rem;
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.mt-user {
|
.mt-user {
|
||||||
display: table;
|
display: table;
|
||||||
@ -157,27 +163,6 @@ html[data-theme="dark"] {
|
|||||||
width: auto;
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mt-error {
|
|
||||||
position: absolute;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
height: calc(100% - 3.5rem);
|
|
||||||
width: calc(100% - 4.5rem);
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
color: var(--error-text-color);
|
|
||||||
padding: 0.75rem;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.mt-error-icon {
|
|
||||||
font-size: 2rem;
|
|
||||||
}
|
|
||||||
.mt-error-message {
|
|
||||||
padding: 1rem 0;
|
|
||||||
}
|
|
||||||
.mt-error-message hr {
|
|
||||||
color: var(--line-gray-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Poll */
|
/* Poll */
|
||||||
.toot-poll {
|
.toot-poll {
|
||||||
@ -252,7 +237,6 @@ html[data-theme="dark"] {
|
|||||||
min-height: 4rem;
|
min-height: 4rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|
||||||
border: 1px solid var(--line-gray-color);
|
border: 1px solid var(--line-gray-color);
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
color: var(--link-color);
|
color: var(--link-color);
|
||||||
@ -308,7 +292,30 @@ html[data-theme="dark"] {
|
|||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loading-spinner */
|
/* Error */
|
||||||
|
.mt-error {
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: calc(100% - 3.5rem);
|
||||||
|
width: calc(100% - 4.5rem);
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
color: var(--error-text-color);
|
||||||
|
padding: 0.75rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.mt-error-icon {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
.mt-error-message {
|
||||||
|
padding: 1rem 0;
|
||||||
|
}
|
||||||
|
.mt-error-message hr {
|
||||||
|
color: var(--line-gray-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loading spinner */
|
||||||
.mt-body > .loading-spinner {
|
.mt-body > .loading-spinner {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 3rem;
|
width: 3rem;
|
||||||
@ -332,7 +339,7 @@ html[data-theme="dark"] {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hidden element */
|
/* Hidden elements */
|
||||||
.visually-hidden {
|
.visually-hidden {
|
||||||
position: absolute !important;
|
position: absolute !important;
|
||||||
width: 1px !important;
|
width: 1px !important;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Mastodon embed feed timeline v3.8.2
|
* Mastodon embed feed timeline v3.9.0
|
||||||
* More info at:
|
* More info at:
|
||||||
* https://gitlab.com/idotj/mastodon-embed-feed-timeline
|
* https://gitlab.com/idotj/mastodon-embed-feed-timeline
|
||||||
*/
|
*/
|
||||||
@ -13,6 +13,9 @@ window.addEventListener("load", () => {
|
|||||||
// Id of the <div> containing the timeline
|
// Id of the <div> containing the timeline
|
||||||
container_body_id: "mt-body",
|
container_body_id: "mt-body",
|
||||||
|
|
||||||
|
// Class name for the loading spinner
|
||||||
|
spinner_class: "loading-spinner",
|
||||||
|
|
||||||
// Preferred color theme: 'light', 'dark' or 'auto'. Default: auto
|
// Preferred color theme: 'light', 'dark' or 'auto'. Default: auto
|
||||||
default_theme: "auto",
|
default_theme: "auto",
|
||||||
|
|
||||||
@ -66,6 +69,8 @@ window.addEventListener("load", () => {
|
|||||||
* Trigger main function to build the timeline
|
* Trigger main function to build the timeline
|
||||||
*/
|
*/
|
||||||
const MastodonApi = function (params_) {
|
const MastodonApi = function (params_) {
|
||||||
|
this.CONTAINER_BODY_ID = params_.container_body_id || "mt-body";
|
||||||
|
this.SPINNER_CLASS = params_.spinner_class || "loading-spinner";
|
||||||
this.DEFAULT_THEME = params_.default_theme || "auto";
|
this.DEFAULT_THEME = params_.default_theme || "auto";
|
||||||
this.INSTANCE_URL = params_.instance_url;
|
this.INSTANCE_URL = params_.instance_url;
|
||||||
this.USER_ID = params_.user_id || "";
|
this.USER_ID = params_.user_id || "";
|
||||||
@ -95,7 +100,7 @@ const MastodonApi = function (params_) {
|
|||||||
this.LINK_SEE_MORE = params_.link_see_more;
|
this.LINK_SEE_MORE = params_.link_see_more;
|
||||||
this.FETCHED_DATA = {};
|
this.FETCHED_DATA = {};
|
||||||
|
|
||||||
this.mtBodyContainer = document.getElementById(params_.container_body_id);
|
this.mtBodyContainer = document.getElementById(this.CONTAINER_BODY_ID);
|
||||||
|
|
||||||
this.buildTimeline();
|
this.buildTimeline();
|
||||||
};
|
};
|
||||||
@ -164,6 +169,9 @@ MastodonApi.prototype.buildTimeline = async function () {
|
|||||||
linkSeeMore
|
linkSeeMore
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Control loading spinners
|
||||||
|
this.manageSpinner();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toot interactions
|
// Toot interactions
|
||||||
@ -172,7 +180,9 @@ MastodonApi.prototype.buildTimeline = async function () {
|
|||||||
if (
|
if (
|
||||||
e.target.localName == "article" ||
|
e.target.localName == "article" ||
|
||||||
e.target.offsetParent.localName == "article" ||
|
e.target.offsetParent.localName == "article" ||
|
||||||
e.target.localName == "img"
|
(e.target.localName == "img" &&
|
||||||
|
e.target.offsetParent.className !== "mt-avatar" &&
|
||||||
|
e.target.offsetParent.className !== "mt-avatar-account")
|
||||||
) {
|
) {
|
||||||
openTootURL(e);
|
openTootURL(e);
|
||||||
}
|
}
|
||||||
@ -355,17 +365,23 @@ MastodonApi.prototype.assambleToot = function (c, i) {
|
|||||||
avatar =
|
avatar =
|
||||||
'<a href="' +
|
'<a href="' +
|
||||||
c.reblog.account.url +
|
c.reblog.account.url +
|
||||||
'" class="mt-avatar mt-avatar-boosted" style="background-image:url(' +
|
'" class="mt-avatar" rel="nofollow noopener noreferrer" target="_blank">' +
|
||||||
|
'<div class="mt-avatar-image">' +
|
||||||
|
'<div class="mt-avatar-boosted">' +
|
||||||
|
'<img src="' +
|
||||||
c.reblog.account.avatar +
|
c.reblog.account.avatar +
|
||||||
');" rel="nofollow noopener noreferrer" target="_blank">' +
|
'" alt="' +
|
||||||
'<div class="mt-avatar mt-avatar-booster" style="background-image:url(' +
|
c.reblog.account.username +
|
||||||
c.account.avatar +
|
' avatar" loading="lazy" />' +
|
||||||
');">' +
|
|
||||||
"</div>" +
|
"</div>" +
|
||||||
'<span class="visually-hidden">' +
|
'<div class="mt-avatar-account">' +
|
||||||
|
'<img src="' +
|
||||||
|
c.account.avatar +
|
||||||
|
'" alt="' +
|
||||||
c.account.username +
|
c.account.username +
|
||||||
" avatar" +
|
' avatar" loading="lazy" />' +
|
||||||
"</span>" +
|
"</div>" +
|
||||||
|
"</div>" +
|
||||||
"</a>";
|
"</a>";
|
||||||
|
|
||||||
// User name and url
|
// User name and url
|
||||||
@ -374,8 +390,10 @@ MastodonApi.prototype.assambleToot = function (c, i) {
|
|||||||
'<a href="' +
|
'<a href="' +
|
||||||
c.reblog.account.url +
|
c.reblog.account.url +
|
||||||
'" rel="nofollow noopener noreferrer" target="_blank">' +
|
'" rel="nofollow noopener noreferrer" target="_blank">' +
|
||||||
c.reblog.account.username +
|
(c.reblog.account.display_name
|
||||||
'<span class="visually-hidden"> post</span>' +
|
? c.reblog.account.display_name
|
||||||
|
: c.reblog.account.username) +
|
||||||
|
'<span class="visually-hidden"> account</span>' +
|
||||||
"</a>" +
|
"</a>" +
|
||||||
"</div>";
|
"</div>";
|
||||||
|
|
||||||
@ -390,13 +408,14 @@ MastodonApi.prototype.assambleToot = function (c, i) {
|
|||||||
avatar =
|
avatar =
|
||||||
'<a href="' +
|
'<a href="' +
|
||||||
c.account.url +
|
c.account.url +
|
||||||
'" class="mt-avatar" style="background-image:url(' +
|
'" class="mt-avatar" rel="nofollow noopener noreferrer" target="_blank">' +
|
||||||
|
'<div class="mt-avatar-image">' +
|
||||||
|
'<img src="' +
|
||||||
c.account.avatar +
|
c.account.avatar +
|
||||||
');" rel="nofollow noopener noreferrer" target="_blank">' +
|
'" alt="' +
|
||||||
'<span class="visually-hidden">' +
|
|
||||||
c.account.username +
|
c.account.username +
|
||||||
" avatar" +
|
' avatar" loading="lazy" />' +
|
||||||
"</span>" +
|
"</div>" +
|
||||||
"</a>";
|
"</a>";
|
||||||
|
|
||||||
// User name and url
|
// User name and url
|
||||||
@ -405,8 +424,8 @@ MastodonApi.prototype.assambleToot = function (c, i) {
|
|||||||
'<a href="' +
|
'<a href="' +
|
||||||
c.account.url +
|
c.account.url +
|
||||||
'" rel="nofollow noopener noreferrer" target="_blank">' +
|
'" rel="nofollow noopener noreferrer" target="_blank">' +
|
||||||
c.account.username +
|
(c.account.display_name ? c.account.display_name : c.account.username) +
|
||||||
'<span class="visually-hidden"> post</span>' +
|
'<span class="visually-hidden"> account</span>' +
|
||||||
"</a>" +
|
"</a>" +
|
||||||
"</div>";
|
"</div>";
|
||||||
|
|
||||||
@ -636,9 +655,11 @@ MastodonApi.prototype.placeMedias = function (m, s) {
|
|||||||
const pic =
|
const pic =
|
||||||
'<div class="toot-media ' +
|
'<div class="toot-media ' +
|
||||||
(spoiler ? "toot-media-spoiler" : "") +
|
(spoiler ? "toot-media-spoiler" : "") +
|
||||||
' img-ratio14_7 loading-spinner">' +
|
" img-ratio14_7 " +
|
||||||
|
this.SPINNER_CLASS +
|
||||||
|
'">' +
|
||||||
(spoiler ? '<button class="spoiler-link">Show content</button>' : "") +
|
(spoiler ? '<button class="spoiler-link">Show content</button>' : "") +
|
||||||
'<img onload="removeSpinner(this)" onerror="removeSpinner(this)" src="' +
|
'<img src="' +
|
||||||
m.preview_url +
|
m.preview_url +
|
||||||
'" alt="' +
|
'" alt="' +
|
||||||
(m.description ? m.description : "") +
|
(m.description ? m.description : "") +
|
||||||
@ -659,7 +680,9 @@ MastodonApi.prototype.placePreviewLink = function (c) {
|
|||||||
c.url +
|
c.url +
|
||||||
'" class="toot-preview-link" target="_blank" rel="noopener noreferrer">' +
|
'" class="toot-preview-link" target="_blank" rel="noopener noreferrer">' +
|
||||||
(c.image
|
(c.image
|
||||||
? '<div class="toot-preview-image"><img onload="removeSpinner(this)" onerror="removeSpinner(this)" src="' +
|
? '<div class="toot-preview-image ' +
|
||||||
|
this.SPINNER_CLASS +
|
||||||
|
'"><img src="' +
|
||||||
c.image +
|
c.image +
|
||||||
'" alt="" loading="lazy" /></div>'
|
'" alt="" loading="lazy" /></div>'
|
||||||
: '<div class="toot-preview-noImage">📄</div>') +
|
: '<div class="toot-preview-noImage">📄</div>') +
|
||||||
@ -714,16 +737,22 @@ MastodonApi.prototype.formatDate = function (d) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loading spinner
|
* Add/Remove event listener for loading spinner
|
||||||
* @param {object} e Image containing the spinner
|
|
||||||
*/
|
*/
|
||||||
const removeSpinner = function (e) {
|
MastodonApi.prototype.manageSpinner = function () {
|
||||||
const spinnerCSS = "loading-spinner";
|
// Remove CSS class to container and listener to images
|
||||||
|
const spinnerCSS = this.SPINNER_CLASS;
|
||||||
// Find closest parent container (1st, 2nd or 3rd level)
|
const removeSpinner = function () {
|
||||||
let spinnerContainer = e.closest("." + spinnerCSS);
|
this.parentNode.classList.remove(spinnerCSS);
|
||||||
|
this.removeEventListener("load", removeSpinner);
|
||||||
if (spinnerContainer) {
|
this.removeEventListener("error", removeSpinner);
|
||||||
spinnerContainer.classList.remove(spinnerCSS);
|
};
|
||||||
}
|
|
||||||
|
// Add listener to images
|
||||||
|
this.mtBodyContainer
|
||||||
|
.querySelectorAll(`.${this.SPINNER_CLASS} > img`)
|
||||||
|
.forEach((e) => {
|
||||||
|
e.addEventListener("load", removeSpinner);
|
||||||
|
e.addEventListener("error", removeSpinner);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
2
src/mastodon-timeline.min.css
vendored
2
src/mastodon-timeline.min.css
vendored
File diff suppressed because one or more lines are too long
2
src/mastodon-timeline.min.js
vendored
2
src/mastodon-timeline.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user