mirror of
				https://gitlab.com/idotj/mastodon-embed-timeline.git
				synced 2025-10-29 22:22:23 +00:00 
			
		
		
		
	Fix/CSP improvements
This commit is contained in:
		
							parent
							
								
									70904484e9
								
							
						
					
					
						commit
						a29d261caf
					
				| @ -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; | ||||||
|  |   const removeSpinner = function () { | ||||||
|  |     this.parentNode.classList.remove(spinnerCSS); | ||||||
|  |     this.removeEventListener("load", removeSpinner); | ||||||
|  |     this.removeEventListener("error", removeSpinner); | ||||||
|  |   }; | ||||||
| 
 | 
 | ||||||
|   // Find closest parent container (1st, 2nd or 3rd level)
 |   // Add listener to images
 | ||||||
|   let spinnerContainer = e.closest("." + spinnerCSS); |   this.mtBodyContainer | ||||||
| 
 |     .querySelectorAll(`.${this.SPINNER_CLASS} > img`) | ||||||
|   if (spinnerContainer) { |     .forEach((e) => { | ||||||
|     spinnerContainer.classList.remove(spinnerCSS); |       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
	 i.j
						i.j