mirror of
				https://gitlab.com/idotj/mastodon-embed-timeline.git
				synced 2025-10-30 06:32:24 +00:00 
			
		
		
		
	V4.5.0
This commit is contained in:
		
							parent
							
								
									ec1055e8ec
								
							
						
					
					
						commit
						72751a25cb
					
				| @ -1,3 +1,12 @@ | |||||||
|  | v4.5.0 - 01/03/2025 | ||||||
|  | - Allow to filter posts by language | ||||||
|  | - Update documentation | ||||||
|  | - Improve documentation content/structure | ||||||
|  | - Update Rollup module bundler | ||||||
|  | - Change dateLocale and dateOptions param names | ||||||
|  | - JS refactoring | ||||||
|  | - Improve performance | ||||||
|  | 
 | ||||||
| v4.4.2 - 04/04/2024 | v4.4.2 - 04/04/2024 | ||||||
| - Fix render emojos in warning/spoiler text | - Fix render emojos in warning/spoiler text | ||||||
| - Sanitize post content before rendering | - Sanitize post content before rendering | ||||||
|  | |||||||
							
								
								
									
										338
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										338
									
								
								README.md
									
									
									
									
									
								
							| @ -1,340 +1,46 @@ | |||||||
| # 🐘 Mastodon embed timeline | # 🐘 Mastodon embed timeline | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
| 
 | 
 | ||||||
| Embed a Mastodon timeline in your page, only with a CSS and JS file. | Embed a Mastodon timeline in your page with just a CSS and JS file. | ||||||
| 
 | 
 | ||||||
| Demo running: | Demo:   | ||||||
| <https://codepen.io/ipuntoj/pen/MWppNGL> | <https://codepen.io/ipuntoj/pen/MWppNGL> | ||||||
| 
 | 
 | ||||||
| ## 📋 Table of contents | ## 📋 Table of contents | ||||||
| 
 | 
 | ||||||
| - [Installation](#installation) | - [Installation](#-installation) | ||||||
|   - [Download](#download) | - [Setup](#-setup) | ||||||
|   - [CDN](#cdn) | - [API](#-api) | ||||||
|   - [Package manager](#package-manager) | - [Examples](#-examples) | ||||||
| - [Setup](#setup) | - [Browser support](#-browser-support) | ||||||
|   - [Initialize](#initialize) | - [Improve me](#-improve-me) | ||||||
|     - [Local timeline](#local-timeline) | - [License](#️-license) | ||||||
|     - [Profile timeline](#profile-timeline) | - [FAQ](#-faq) | ||||||
|     - [Hashtag timeline](#hashtag-timeline) | - [Alternatives](#alternatives) | ||||||
|   - [Customize](#customize) |  | ||||||
| - [API](#api) |  | ||||||
| - [Examples](#examples) |  | ||||||
| 
 | 
 | ||||||
| ## Installation | ## 🛠️ Installation | ||||||
| 
 | 
 | ||||||
| You have three different ways to install it in your project, choose the one that best suits your needs: | Steps for installing the timeline in three different ways. [Click here](https://gitlab.com/idotj/mastodon-embed-timeline/-/blob/master/docs/INSTALLATION.md) | ||||||
| 
 | 
 | ||||||
| ### Download | ## ⚙️ Setup | ||||||
| 
 | 
 | ||||||
| Download into your project the following compiled and minified files: | Steps to configure and customize your timeline. [Click here](https://gitlab.com/idotj/mastodon-embed-timeline/-/blob/master/docs/SETUP.md) | ||||||
| 
 | 
 | ||||||
| - `dist/mastodon-timeline.min.css` | ## 🔌 API | ||||||
| - `dist/mastodon-timeline.umd.js` |  | ||||||
| 
 | 
 | ||||||
| Now call the CSS and JS files in your HTML page using the `<link>` and `<script>` tags as follows in this example: | The current version has the following functions that can be performed: | ||||||
| 
 |  | ||||||
| ```html |  | ||||||
| <!DOCTYPE html> |  | ||||||
| 
 |  | ||||||
| <html lang="en"> |  | ||||||
|   <head> |  | ||||||
|     <meta charset="UTF-8" /> |  | ||||||
|     <meta name="viewport" content="width=device-width, initial-scale=1" /> |  | ||||||
|     <title>Your site title</title> |  | ||||||
|     <!-- CSS --> |  | ||||||
|     <link href="path/to/mastodon-timeline.min.css" rel="stylesheet" /> |  | ||||||
|   </head> |  | ||||||
| 
 |  | ||||||
|   <body> |  | ||||||
|     <!-- Your HTML content --> |  | ||||||
| 
 |  | ||||||
|     <!-- JavaScript --> |  | ||||||
|     <script src="path/to/mastodon-timeline.umd.js"></script> |  | ||||||
|     <script> |  | ||||||
|       // You can initialize the script here |  | ||||||
|     </script> |  | ||||||
|   </body> |  | ||||||
| </html> |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| ### CDN |  | ||||||
| 
 |  | ||||||
| This option allows you to start without the need to upload any files on your server.   |  | ||||||
| Copy the following CSS and JS links to include them in your project: |  | ||||||
| 
 |  | ||||||
| ```html |  | ||||||
| <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@idotj/mastodon-embed-timeline@4.4.2/dist/mastodon-timeline.min.css" integrity="sha256-1UGgxsonaMCfOEnVOL89aMKSo3GEAmaRP0ISbsWa6lU=" crossorigin="anonymous"> |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| ```html |  | ||||||
| <script src="https://cdn.jsdelivr.net/npm/@idotj/mastodon-embed-timeline@4.4.2/dist/mastodon-timeline.umd.js" integrity="sha256-E6WPG6iq+qQIzvu3HPJJxoAeRdum5siq13x4ITjyxu8=" crossorigin="anonymous"></script> |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| ### Package manager |  | ||||||
| 
 |  | ||||||
| A quick way to get it installed using **npm** or **yarn**: |  | ||||||
| 
 |  | ||||||
| ```terminal |  | ||||||
| npm install @idotj/mastodon-embed-timeline |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| or |  | ||||||
| 
 |  | ||||||
| ```terminal |  | ||||||
| yarn add @idotj/mastodon-embed-timeline |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| After installation, you can import it as follows: |  | ||||||
| 
 |  | ||||||
| ```js |  | ||||||
| import * as MastodonTimeline from "@idotj/mastodon-embed-timeline"; |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| Make sure to import also the file `mastodon-timeline.min.css` into your project. |  | ||||||
| 
 |  | ||||||
| ## Setup |  | ||||||
| 
 |  | ||||||
| ### Initialize |  | ||||||
| 
 |  | ||||||
| To get your timeline up add the following HTML structure in your page: |  | ||||||
| 
 |  | ||||||
| ```html |  | ||||||
| <div id="mt-container" class="mt-container"> |  | ||||||
|   <div class="mt-body" role="feed"> |  | ||||||
|     <div class="mt-loading-spinner"></div> |  | ||||||
|   </div> |  | ||||||
| </div> |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| Now you can then initialize the script running: |  | ||||||
| 
 |  | ||||||
| ```js |  | ||||||
| const myTimeline = new MastodonTimeline.Init(); |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| By default it will show a timeline with 20 posts from the instance [mastodon.social](https://mastodon.social/public/local) |  | ||||||
| 
 |  | ||||||
| ℹ️ If you are trying to initialize the script before `mastodon-timeline.umd.js` is loaded, you will probably get such an error in the console:   |  | ||||||
| "_MastodonTimeline is not defined_".   |  | ||||||
| To fix that try to initialize the script as follow: |  | ||||||
| 
 |  | ||||||
| ```js |  | ||||||
| window.addEventListener("load", () => { |  | ||||||
|   const myTimeline = new MastodonTimeline.Init(); |  | ||||||
| }); |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| The next step is to configure the options/values of your timeline according to the type you prefer. There are three types, **Local**, **Profile** and **Hashtag**. Here you have an example of each one to see how it works: |  | ||||||
| 
 |  | ||||||
| #### Local timeline |  | ||||||
| 
 |  | ||||||
| To show a timeline with posts from the instance [mastodon.online](https://mastodon.online/public/local) add the following option/value when initializing the timeline: |  | ||||||
| 
 |  | ||||||
| ```js |  | ||||||
| const myTimeline = new MastodonTimeline.Init({ |  | ||||||
|   instanceUrl: "https://mastodon.online", |  | ||||||
| }); |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| #### Profile timeline |  | ||||||
| 
 |  | ||||||
| To show a timeline with posts from my Mastodon profile [@idotj](https://mastodon.online/@idotj) add the following options/values when initializing the timeline: |  | ||||||
| 
 |  | ||||||
| ```js |  | ||||||
| const myTimeline = new MastodonTimeline.Init({ |  | ||||||
|   instanceUrl: "https://mastodon.online", |  | ||||||
|   timelineType: "profile", |  | ||||||
|   userId: "000180745", |  | ||||||
|   profileName: "@idotj", |  | ||||||
| }); |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| ℹ️ If you don't know your `userId` you have two ways to get it: |  | ||||||
| 
 |  | ||||||
| - Copy the url below and paste it in a new tab. Remember to replace the words `INSTANCE` and `USERNAME` with your current values in the url:   |  | ||||||
|   <https://INSTANCE/api/v1/accounts/lookup?acct=USERNAME>   |  | ||||||
|   The first value you see in the list is your `id` number. |  | ||||||
| 
 |  | ||||||
| - Click on the link below and put your `@USERNAME` and `@INSTANCE` in the input field:   |  | ||||||
|   [https://prouser123.me/mastodon-userid-lookup/](https://prouser123.me/mastodon-userid-lookup/) |  | ||||||
| 
 |  | ||||||
| #### Hashtag timeline |  | ||||||
| 
 |  | ||||||
| To show a timeline with posts containing the hashtag [#fediverse](https://mastodon.online/tags/fediverse) add the following options/values when initializing the timeline: |  | ||||||
| 
 |  | ||||||
| ```js |  | ||||||
| const myTimeline = new MastodonTimeline.Init({ |  | ||||||
|   instanceUrl: "https://mastodon.online", |  | ||||||
|   timelineType: "hashtag", |  | ||||||
|   hashtagName: "fediverse", |  | ||||||
| }); |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| ### Customize |  | ||||||
| 
 |  | ||||||
| In the `examples/` folder there is an HTML file `local-timeline-customized.html` where you can see how to customize your timeline by overwriting the CSS styles and using several JS options when initializing the timeline. |  | ||||||
| 
 |  | ||||||
| If you need to change something in the core files (`src/` folder), I recommend you to read the document [CONTRIBUTING.md](https://gitlab.com/idotj/mastodon-embed-timeline/-/blob/master/CONTRIBUTING.md#testing) to see how to compile and test your changes. |  | ||||||
| 
 |  | ||||||
| Here you have all the options available to quickly setup and customize your timeline: |  | ||||||
| 
 |  | ||||||
| ```js |  | ||||||
|   // Id of the <div> containing the timeline |  | ||||||
|   // Default: "mt-container" |  | ||||||
|   mtContainerId: "mt-container", |  | ||||||
| 
 |  | ||||||
|   // Mastodon instance Url including https:// |  | ||||||
|   // Default: "https://mastodon.social" |  | ||||||
|   instanceUrl: "https://mastodon.social", |  | ||||||
| 
 |  | ||||||
|   // Choose type of posts to show in the timeline: 'local', 'profile', 'hashtag' |  | ||||||
|   // Default: "local" |  | ||||||
|   timelineType: "local", |  | ||||||
| 
 |  | ||||||
|   // Your user ID number on Mastodon instance |  | ||||||
|   // Leave it empty if you didn't choose 'profile' as type of timeline |  | ||||||
|   // Default: "" |  | ||||||
|   userId: "", |  | ||||||
| 
 |  | ||||||
|   // Your user name on Mastodon instance (including the @ symbol at the beginning) |  | ||||||
|   // Leave it empty if you didn't choose 'profile' as type of timeline |  | ||||||
|   // Default: "" |  | ||||||
|   profileName: "", |  | ||||||
| 
 |  | ||||||
|   // The name of the hashtag (not including the # symbol) |  | ||||||
|   // Leave it empty if you didn't choose 'hashtag' as type of timeline |  | ||||||
|   // Default: "" |  | ||||||
|   hashtagName: "", |  | ||||||
| 
 |  | ||||||
|   // Class name for the loading spinner (also used in CSS file) |  | ||||||
|   // Default: "mt-loading-spinner" |  | ||||||
|   spinnerClass: "mt-loading-spinner", |  | ||||||
| 
 |  | ||||||
|   // Preferred color theme: "light", "dark" or "auto" |  | ||||||
|   // Default: "auto" |  | ||||||
|   defaultTheme: "auto", |  | ||||||
| 
 |  | ||||||
|   // Maximum number of posts to request to the server |  | ||||||
|   // Default: "20" |  | ||||||
|   maxNbPostFetch: "20", |  | ||||||
| 
 |  | ||||||
|   // Maximum number of posts to show in the timeline |  | ||||||
|   // Default: "20" |  | ||||||
|   maxNbPostShow: "20", |  | ||||||
| 
 |  | ||||||
|   // Specifies the format of the date according to the chosen language/country |  | ||||||
|   // Default: "en-GB" (British English: day-month-year order) |  | ||||||
|   dateLocale: "en-GB", |  | ||||||
| 
 |  | ||||||
|   // Customize the date format using the options for day, month and year |  | ||||||
|   // Default: day: "2-digit", month: "short", year: "numeric" (DD MMM YYYY) |  | ||||||
|   dateOptions: { |  | ||||||
|     day: "2-digit", |  | ||||||
|     month: "short", |  | ||||||
|     year: "numeric", |  | ||||||
|   }, |  | ||||||
| 
 |  | ||||||
|   // Hide unlisted posts |  | ||||||
|   // Default: false (don't hide) |  | ||||||
|   hideUnlisted: false, |  | ||||||
| 
 |  | ||||||
|   // Hide boosted posts |  | ||||||
|   // Default: false (don't hide) |  | ||||||
|   hideReblog: false, |  | ||||||
| 
 |  | ||||||
|   // Hide replies posts |  | ||||||
|   // Default: false (don't hide) |  | ||||||
|   hideReplies: false, |  | ||||||
| 
 |  | ||||||
|   // Hide pinned posts from the profile timeline |  | ||||||
|   // Default: false (don't hide) |  | ||||||
|   hidePinnedPosts: false, |  | ||||||
| 
 |  | ||||||
|   // Hide the user account under the user name |  | ||||||
|   // Default: false (don't hide) |  | ||||||
|   hideUserAccount: false, |  | ||||||
| 
 |  | ||||||
|   // Limit the text content to a maximum number of lines |  | ||||||
|   // Use "0" to show no text |  | ||||||
|   // Default: "" (unlimited) |  | ||||||
|   txtMaxLines: "", |  | ||||||
| 
 |  | ||||||
|   // Customize the text of the button used for showing/hiding sensitive/spoiler text |  | ||||||
|   btnShowMore: "SHOW MORE", |  | ||||||
|   btnShowLess: "SHOW LESS",   |  | ||||||
| 
 |  | ||||||
|   // Converts Markdown symbol ">" at the beginning of a paragraph into a blockquote HTML tag |  | ||||||
|   // Default: false (don't apply) |  | ||||||
|   markdownBlockquote: false,   |  | ||||||
| 
 |  | ||||||
|   // Hide custom emojis available on the server |  | ||||||
|   // Default: false (don't hide) |  | ||||||
|   hideEmojos: false,   |  | ||||||
| 
 |  | ||||||
|   // Customize the text of the button used for showing a sensitive/spoiler media content |  | ||||||
|   btnShowContent: "SHOW CONTENT",   |  | ||||||
| 
 |  | ||||||
|   // Hide video image preview and load the video player instead |  | ||||||
|   // Default: false (don't hide) |  | ||||||
|   hideVideoPreview: false, |  | ||||||
| 
 |  | ||||||
|   // Customize the text of the button used for the image preview to play the video |  | ||||||
|   btnPlayVideoTxt: "Load and play video",   |  | ||||||
| 
 |  | ||||||
|   // Hide preview card if post contains a link, photo or video from a Url |  | ||||||
|   // Default: false (don't hide) |  | ||||||
|   hidePreviewLink: false, |  | ||||||
| 
 |  | ||||||
|   // Limit the preview text description to a maximum number of lines |  | ||||||
|   // Use "0" to show no text |  | ||||||
|   // Default: "" (unlimited) |  | ||||||
|   previewMaxLines: "", |  | ||||||
| 
 |  | ||||||
|   // Hide replies, boosts and favourites posts counter |  | ||||||
|   // Default: false (don't hide) |  | ||||||
|   hideCounterBar: false, |  | ||||||
| 
 |  | ||||||
|   // Disable a carousel/lightbox when the user clicks on a picture in a post |  | ||||||
|   // Default: false (not disabled) |  | ||||||
|   disableCarousel: false, |  | ||||||
| 
 |  | ||||||
|   // Customize the text of the buttons used for the carousel/lightbox |  | ||||||
|   carouselCloseTxt: "Close carousel", |  | ||||||
|   carouselPrevTxt: "Previous media item", |  | ||||||
|   carouselNextTxt: "Next media item",  |  | ||||||
| 
 |  | ||||||
|   // Customize the text of the button pointing to the Mastodon page placed at the end of the timeline |  | ||||||
|   // Leave the value empty to hide it |  | ||||||
|   btnSeeMore: "See more posts at Mastodon", |  | ||||||
| 
 |  | ||||||
|   // Customize the text of the button reloading the list of posts placed at the end of the timeline |  | ||||||
|   // Leave the value empty to hide it |  | ||||||
|   btnReload: "Refresh", |  | ||||||
| 
 |  | ||||||
|   // Keep searching for the main <div> container before building the timeline. Useful in some cases where extra time is needed to render the page |  | ||||||
|   // Default: false (don't apply) |  | ||||||
|   insistSearchContainer: false, |  | ||||||
| 
 |  | ||||||
|   // Defines the maximum time to continue searching for the main <div> container |  | ||||||
|   // Default: "3000" (3 seconds) |  | ||||||
|   insistSearchContainerTime: "3000", |  | ||||||
| 
 |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| ## API |  | ||||||
| 
 | 
 | ||||||
| | Function                  | Description                                                                     | | | Function                  | Description                                                                     | | ||||||
| | ------------------------- | ------------------------------------------------------------------------------- | | | ------------------------- | ------------------------------------------------------------------------------- | | ||||||
| | `mtColorTheme(themeType)` | Apply a theme color. `themeType` accepts only two values: `'light'` or `'dark'` | | | `mtColorTheme(themeType)` | Apply a theme color. `themeType` accepts only two values: `'light'` or `'dark'` | | ||||||
| | `mtUpdate()`              | Reload the timeline by fetching the lastest posts                               | | | `mtUpdate()`              | Reload the timeline by fetching the lastest posts                               | | ||||||
| 
 | 
 | ||||||
| ## Examples | ## 📚 Examples | ||||||
| 
 | 
 | ||||||
| The folder `examples/` contains several demos in HTML to play with. Download the full project and open each HTML file in your favorite browser. | The folder `examples/` contains different demos of timeline types to play with. Download the full project and open each HTML file in your favorite browser.   | ||||||
| 
 | 
 | ||||||
| Also, you have other alternatives to run these examples locally. Consult the document [CONTRIBUTING.md](https://gitlab.com/idotj/mastodon-embed-timeline/-/blob/master/CONTRIBUTING.md#testing) to use options such as Docker or Http-server. | If you have any problems loading the examples in your browser (e.g. CORS error), check the documentation [CONTRIBUTING.md](https://gitlab.com/idotj/mastodon-embed-timeline/-/blob/master/CONTRIBUTING.md#testing) to run the examples using alternatives such as Docker or Http-server. | ||||||
| 
 | 
 | ||||||
| ## 🌐 Browser support | ## 🌐 Browser support | ||||||
| 
 | 
 | ||||||
| @ -350,7 +56,7 @@ Mastodon embed timeline is supported on the latest versions of the following bro | |||||||
| ## 🚀 Improve me | ## 🚀 Improve me | ||||||
| 
 | 
 | ||||||
| Feel free to add your features and improvements.   | Feel free to add your features and improvements.   | ||||||
| Take a look at the [CONTRIBUTING.md](https://gitlab.com/idotj/mastodon-embed-timeline/-/blob/master/CONTRIBUTING.md) document to learn more about how to build and collaborate on the project. | The [CONTRIBUTING.md](https://gitlab.com/idotj/mastodon-embed-timeline/-/blob/master/CONTRIBUTING.md) document to learn more about how to modify, build and collaborate on the project. | ||||||
| 
 | 
 | ||||||
| ## ⚖️ License | ## ⚖️ License | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										4
									
								
								dist/mastodon-timeline.esm.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								dist/mastodon-timeline.esm.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/mastodon-timeline.min.css
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/mastodon-timeline.min.css
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										4
									
								
								dist/mastodon-timeline.umd.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								dist/mastodon-timeline.umd.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										75
									
								
								docs/INSTALLATION.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								docs/INSTALLATION.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,75 @@ | |||||||
|  | # 🐘 Mastodon embed timeline - 🛠️ Installation | ||||||
|  | 
 | ||||||
|  | You have three different ways to install it in your project: | ||||||
|  | - [Download](#download) | ||||||
|  | - [CDN](#cdn) | ||||||
|  | - [Package manager](#package-manager) | ||||||
|  | 
 | ||||||
|  | ## Download | ||||||
|  | 
 | ||||||
|  | Download and copy these two files into your project folder: | ||||||
|  | 
 | ||||||
|  | - `dist/mastodon-timeline.min.css` | ||||||
|  | - `dist/mastodon-timeline.umd.js` | ||||||
|  | 
 | ||||||
|  | Load the CSS and JS files in your HTML page using the `<link>` and `<script>` tags as follows in this example: | ||||||
|  | 
 | ||||||
|  | ```html | ||||||
|  | <!DOCTYPE html> | ||||||
|  | 
 | ||||||
|  | <html lang="en"> | ||||||
|  |   <head> | ||||||
|  |     <meta charset="UTF-8" /> | ||||||
|  |     <meta name="viewport" content="width=device-width, initial-scale=1" /> | ||||||
|  |     <title>Example of site title</title> | ||||||
|  |     <!-- Your CSS --> | ||||||
|  |     <link href="your/path/to/file/mastodon-timeline.min.css" rel="stylesheet" /> | ||||||
|  |   </head> | ||||||
|  | 
 | ||||||
|  |   <body> | ||||||
|  |     <!-- HTML content --> | ||||||
|  |     ... | ||||||
|  | 
 | ||||||
|  |     <!-- Your JavaScript --> | ||||||
|  |     <script src="your/path/to/file/mastodon-timeline.umd.js"></script> | ||||||
|  |     <script> | ||||||
|  |       // You can initialize the script here | ||||||
|  |     </script> | ||||||
|  |   </body> | ||||||
|  | </html> | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## CDN | ||||||
|  | 
 | ||||||
|  | This option allows you to start without the need to upload any files on your server.   | ||||||
|  | Copy the following CSS and JS links to include them in your project: | ||||||
|  | 
 | ||||||
|  | ```html | ||||||
|  | <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@idotj/mastodon-embed-timeline@4.5.0/dist/mastodon-timeline.min.css" crossorigin="anonymous"> | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ```html | ||||||
|  | <script src="https://cdn.jsdelivr.net/npm/@idotj/mastodon-embed-timeline@4.5.0/dist/mastodon-timeline.umd.js" crossorigin="anonymous"></script> | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## Package manager | ||||||
|  | 
 | ||||||
|  | A quick way to get it installed using **npm** or **yarn**: | ||||||
|  | 
 | ||||||
|  | ```terminal | ||||||
|  | npm install @idotj/mastodon-embed-timeline | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | or | ||||||
|  | 
 | ||||||
|  | ```terminal | ||||||
|  | yarn add @idotj/mastodon-embed-timeline | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | After installation, you can import it as follows: | ||||||
|  | 
 | ||||||
|  | ```js | ||||||
|  | import * as MastodonTimeline from "@idotj/mastodon-embed-timeline"; | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Make sure to import also the file `mastodon-timeline.min.css` into your project. | ||||||
							
								
								
									
										239
									
								
								docs/SETUP.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										239
									
								
								docs/SETUP.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,239 @@ | |||||||
|  | # 🐘 Mastodon embed timeline - ⚙️ Setup | ||||||
|  | 
 | ||||||
|  | ## Initialize | ||||||
|  | 
 | ||||||
|  | Add the following HTML structure in your page: | ||||||
|  | 
 | ||||||
|  | ```html | ||||||
|  | <div id="mt-container" class="mt-container"> | ||||||
|  |   <div class="mt-body" role="feed"> | ||||||
|  |     <div class="mt-loading-spinner"></div> | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Now you can then initialize the script running: | ||||||
|  | 
 | ||||||
|  | ```js | ||||||
|  | const myTimeline = new MastodonTimeline.Init(); | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | By default it will show a timeline with 20 posts from the instance [mastodon.social](https://mastodon.social/public/local) | ||||||
|  | 
 | ||||||
|  | ℹ️ If you are trying to initialize the script before `mastodon-timeline.umd.js` is loaded, you will probably get such an error in the console:   | ||||||
|  | "_MastodonTimeline is not defined_".   | ||||||
|  | To fix that try to initialize the script as follow: | ||||||
|  | 
 | ||||||
|  | ```js | ||||||
|  | window.addEventListener("load", () => { | ||||||
|  |   const myTimeline = new MastodonTimeline.Init(); | ||||||
|  | }); | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## Timeline type | ||||||
|  | 
 | ||||||
|  | There are three types, **Local**, **Profile** and **Hashtag**. Here you have an example of each one to see how it works: | ||||||
|  | 
 | ||||||
|  | ### Local timeline | ||||||
|  | 
 | ||||||
|  | To show a timeline with posts from a local instance (e.g. [mastodon.online](https://mastodon.online/public/local)) add the following option/value when initializing the timeline: | ||||||
|  | 
 | ||||||
|  | ```js | ||||||
|  | const myTimeline = new MastodonTimeline.Init({ | ||||||
|  |   instanceUrl: "https://mastodon.online", | ||||||
|  | }); | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Profile timeline | ||||||
|  | 
 | ||||||
|  | To show a timeline with posts from a Mastodon profile (e.g. [@idotj](https://mastodon.online/@idotj)) add the following options/values when initializing the timeline: | ||||||
|  | 
 | ||||||
|  | ```js | ||||||
|  | const myTimeline = new MastodonTimeline.Init({ | ||||||
|  |   instanceUrl: "https://mastodon.online", | ||||||
|  |   timelineType: "profile", | ||||||
|  |   userId: "000180745", | ||||||
|  |   profileName: "@idotj", | ||||||
|  | }); | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ℹ️ If you don't know your `userId` you have two ways to get it: | ||||||
|  | 
 | ||||||
|  | - Copy the url below and paste it in a new tab. Remember to replace the words `INSTANCE` and `USERNAME` with your current values in the url:   | ||||||
|  |   <https://INSTANCE/api/v1/accounts/lookup?acct=USERNAME>   | ||||||
|  |   The first value you see in the list is your `id` number. | ||||||
|  | 
 | ||||||
|  | - Click on the link below and put your `@USERNAME` and `@INSTANCE` in the input field:   | ||||||
|  |   [https://mastodon-userid-lookup.jcxldn.net/](https://mastodon-userid-lookup.jcxldn.net/) | ||||||
|  | 
 | ||||||
|  | ### Hashtag timeline | ||||||
|  | 
 | ||||||
|  | To show a timeline with posts containing a hashtag (e.g. [#fediverse](https://mastodon.online/tags/fediverse)) add the following options/values when initializing the timeline: | ||||||
|  | 
 | ||||||
|  | ```js | ||||||
|  | const myTimeline = new MastodonTimeline.Init({ | ||||||
|  |   instanceUrl: "https://mastodon.online", | ||||||
|  |   timelineType: "hashtag", | ||||||
|  |   hashtagName: "fediverse", | ||||||
|  | }); | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## Customize | ||||||
|  | 
 | ||||||
|  | There is a long list of parameters that allows you to quickly customize your timeline: | ||||||
|  | 
 | ||||||
|  | ```js | ||||||
|  |   // Id of the <div> containing the timeline | ||||||
|  |   // Default: "mt-container" | ||||||
|  |   mtContainerId: "mt-container", | ||||||
|  | 
 | ||||||
|  |   // Mastodon instance Url including https:// | ||||||
|  |   // Default: "https://mastodon.social" | ||||||
|  |   instanceUrl: "https://mastodon.social", | ||||||
|  | 
 | ||||||
|  |   // Choose type of posts to show in the timeline: 'local', 'profile', 'hashtag' | ||||||
|  |   // Default: "local" | ||||||
|  |   timelineType: "local", | ||||||
|  | 
 | ||||||
|  |   // Your user ID number on Mastodon instance | ||||||
|  |   // Leave it empty if you didn't choose 'profile' as type of timeline | ||||||
|  |   // Default: "" | ||||||
|  |   userId: "", | ||||||
|  | 
 | ||||||
|  |   // Your user name on Mastodon instance (including the @ symbol at the beginning) | ||||||
|  |   // Leave it empty if you didn't choose 'profile' as type of timeline | ||||||
|  |   // Default: "" | ||||||
|  |   profileName: "", | ||||||
|  | 
 | ||||||
|  |   // The name of the hashtag (without the # symbol) | ||||||
|  |   // Leave it empty if you didn't choose 'hashtag' as type of timeline | ||||||
|  |   // Default: "" | ||||||
|  |   hashtagName: "", | ||||||
|  | 
 | ||||||
|  |   // Class name for the loading spinner (also used in CSS file) | ||||||
|  |   // Default: "mt-loading-spinner" | ||||||
|  |   spinnerClass: "mt-loading-spinner", | ||||||
|  | 
 | ||||||
|  |   // Preferred color theme: "light", "dark" or "auto" | ||||||
|  |   // Default: "auto" | ||||||
|  |   defaultTheme: "auto", | ||||||
|  | 
 | ||||||
|  |   // Maximum number of posts to request to the server | ||||||
|  |   // Default: "20" | ||||||
|  |   maxNbPostFetch: "20", | ||||||
|  | 
 | ||||||
|  |   // Maximum number of posts to show in the timeline | ||||||
|  |   // Default: "20" | ||||||
|  |   maxNbPostShow: "20", | ||||||
|  | 
 | ||||||
|  |   // Set the format of the date according to the chosen language/country | ||||||
|  |   // Default: "en-GB" (British English: day-month-year order) | ||||||
|  |   dateFormatLocale: "en-GB", | ||||||
|  | 
 | ||||||
|  |   // Customize the date format using the options for day, month and year | ||||||
|  |   // Default: day: "2-digit", month: "short", year: "numeric" (DD MMM YYYY) | ||||||
|  |   dateFormatOptions: { | ||||||
|  |     day: "2-digit", | ||||||
|  |     month: "short", | ||||||
|  |     year: "numeric", | ||||||
|  |   }, | ||||||
|  | 
 | ||||||
|  |   // Hide unlisted posts | ||||||
|  |   // Default: false (don't hide) | ||||||
|  |   hideUnlisted: false, | ||||||
|  | 
 | ||||||
|  |   // Hide boosted posts | ||||||
|  |   // Default: false (don't hide) | ||||||
|  |   hideReblog: false, | ||||||
|  | 
 | ||||||
|  |   // Hide replies posts | ||||||
|  |   // Default: false (don't hide) | ||||||
|  |   hideReplies: false, | ||||||
|  | 
 | ||||||
|  |   // Hide pinned posts from the profile timeline | ||||||
|  |   // Default: false (don't hide) | ||||||
|  |   hidePinnedPosts: false, | ||||||
|  | 
 | ||||||
|  |   // Hide the user account under the user name | ||||||
|  |   // Default: false (don't hide) | ||||||
|  |   hideUserAccount: false, | ||||||
|  | 
 | ||||||
|  |   // Show only posts with the selected language (ISO 639-1) | ||||||
|  |   // Use "en" to show only posts in English | ||||||
|  |   // Default: "" (don't filter by language) | ||||||
|  |   filterByLanguage: "", | ||||||
|  | 
 | ||||||
|  |   // Limit the text content to a maximum number of lines | ||||||
|  |   // Use "0" to show no text | ||||||
|  |   // Default: "" (unlimited) | ||||||
|  |   txtMaxLines: "", | ||||||
|  | 
 | ||||||
|  |   // Customize the text of the button used for showing/hiding sensitive/spoiler text | ||||||
|  |   btnShowMore: "SHOW MORE", | ||||||
|  |   btnShowLess: "SHOW LESS",   | ||||||
|  | 
 | ||||||
|  |   // Convert Markdown symbol ">" at the beginning of a paragraph into a blockquote HTML tag | ||||||
|  |   // Default: false (don't apply) | ||||||
|  |   markdownBlockquote: false,   | ||||||
|  | 
 | ||||||
|  |   // Hide custom emojis available on the server | ||||||
|  |   // Default: false (don't hide) | ||||||
|  |   hideEmojos: false,   | ||||||
|  | 
 | ||||||
|  |   // Customize the text of the button used for showing a sensitive/spoiler media content | ||||||
|  |   btnShowContent: "SHOW CONTENT",   | ||||||
|  | 
 | ||||||
|  |   // Hide video image preview and load the video player instead | ||||||
|  |   // Default: false (don't hide) | ||||||
|  |   hideVideoPreview: false, | ||||||
|  | 
 | ||||||
|  |   // Customize the text of the button used for the image preview to play the video | ||||||
|  |   btnPlayVideoTxt: "Load and play video",   | ||||||
|  | 
 | ||||||
|  |   // Hide preview card if post contains a link, photo or video from a Url | ||||||
|  |   // Default: false (don't hide) | ||||||
|  |   hidePreviewLink: false, | ||||||
|  | 
 | ||||||
|  |   // Limit the preview text description to a maximum number of lines | ||||||
|  |   // Use "0" to show no text | ||||||
|  |   // Default: "" (unlimited) | ||||||
|  |   previewMaxLines: "", | ||||||
|  | 
 | ||||||
|  |   // Hide replies, boosts and favourites posts counter | ||||||
|  |   // Default: false (don't hide) | ||||||
|  |   hideCounterBar: false, | ||||||
|  | 
 | ||||||
|  |   // Disable a carousel/lightbox when the user clicks on a picture in a post | ||||||
|  |   // Default: false (not disabled) | ||||||
|  |   disableCarousel: false, | ||||||
|  | 
 | ||||||
|  |   // Customize the text of the buttons used for the carousel/lightbox | ||||||
|  |   // Default: | ||||||
|  |   carouselCloseTxt: "Close carousel", | ||||||
|  |   carouselPrevTxt: "Previous media item", | ||||||
|  |   carouselNextTxt: "Next media item",  | ||||||
|  | 
 | ||||||
|  |   // Customize the text of the button pointing to the Mastodon page placed at the end of the timeline | ||||||
|  |   // Leave the value empty to hide it | ||||||
|  |   // Default: | ||||||
|  |   btnSeeMore: "See more posts at Mastodon", | ||||||
|  | 
 | ||||||
|  |   // Customize the text of the button reloading the list of posts placed at the end of the timeline | ||||||
|  |   // Leave the value empty to hide it | ||||||
|  |   // Default: | ||||||
|  |   btnReload: "Refresh", | ||||||
|  | 
 | ||||||
|  |   // Keep searching for the main <div> container before building the timeline. Useful in some cases where extra time is needed to render the page | ||||||
|  |   // Default: false (don't apply) | ||||||
|  |   insistSearchContainer: false, | ||||||
|  | 
 | ||||||
|  |   // Define the maximum time to continue searching for the main <div> container | ||||||
|  |   // Default: "3000" (3 seconds) | ||||||
|  |   insistSearchContainerTime: "3000", | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | In the `examples/` folder there is an HTML file `local-timeline-customized.html` that you can use as a referente to see how to customize your timeline by overwriting some CSS styles and using several parameters when initializing the timeline. | ||||||
|  | 
 | ||||||
|  | Also, if you need to change something in the core files (`src/` folder), I recommend you to read the document [CONTRIBUTING.md](https://gitlab.com/idotj/mastodon-embed-timeline/-/blob/master/CONTRIBUTING.md#testing) to see how to compile and test your changes. | ||||||
|  | 
 | ||||||
| Before Width: | Height: | Size: 278 KiB After Width: | Height: | Size: 278 KiB | 
| @ -187,8 +187,8 @@ | |||||||
|       defaultTheme: "light", |       defaultTheme: "light", | ||||||
|       maxNbPostFetch: "42", |       maxNbPostFetch: "42", | ||||||
|       maxNbPostShow: "42", |       maxNbPostShow: "42", | ||||||
|       dateLocale: "en-CA", |       dateFormatLocale: "en-CA", | ||||||
|       dateOptions: { |       dateFormatOptions: { | ||||||
|         day: "2-digit", |         day: "2-digit", | ||||||
|         month: "2-digit", |         month: "2-digit", | ||||||
|         year: "numeric", |         year: "numeric", | ||||||
| @ -225,8 +225,8 @@ | |||||||
|         defaultTheme: "light", |         defaultTheme: "light", | ||||||
|         maxNbPostFetch: "42", |         maxNbPostFetch: "42", | ||||||
|         maxNbPostShow: "42", |         maxNbPostShow: "42", | ||||||
|         dateLocale: "en-CA", |         dateFormatLocale: "en-CA", | ||||||
|         dateOptions: { |         dateFormatOptions: { | ||||||
|           day: "2-digit", |           day: "2-digit", | ||||||
|           month: "2-digit", |           month: "2-digit", | ||||||
|           year: "numeric", |           year: "numeric", | ||||||
|  | |||||||
							
								
								
									
										239
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										239
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -1,17 +1,17 @@ | |||||||
| { | { | ||||||
|   "name": "@idotj/mastodon-embed-timeline", |   "name": "@idotj/mastodon-embed-timeline", | ||||||
|   "version": "4.4.2", |   "version": "4.5.0", | ||||||
|   "lockfileVersion": 3, |   "lockfileVersion": 3, | ||||||
|   "requires": true, |   "requires": true, | ||||||
|   "packages": { |   "packages": { | ||||||
|     "": { |     "": { | ||||||
|       "name": "@idotj/mastodon-embed-timeline", |       "name": "@idotj/mastodon-embed-timeline", | ||||||
|       "version": "4.4.2", |       "version": "4.5.0", | ||||||
|       "license": "GNU", |       "license": "GNU", | ||||||
|       "devDependencies": { |       "devDependencies": { | ||||||
|         "@rollup/plugin-terser": "^0.4.4", |         "@rollup/plugin-terser": "^0.4.4", | ||||||
|         "clean-css-cli": "^5.6.3", |         "clean-css-cli": "^5.6.3", | ||||||
|         "rollup": "^4.14.0" |         "rollup": "^4.34.8" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/@jridgewell/gen-mapping": { |     "node_modules/@jridgewell/gen-mapping": { | ||||||
| @ -95,205 +95,277 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/@rollup/rollup-android-arm-eabi": { |     "node_modules/@rollup/rollup-android-arm-eabi": { | ||||||
|       "version": "4.14.0", |       "version": "4.34.8", | ||||||
|       "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.0.tgz", |       "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz", | ||||||
|       "integrity": "sha512-jwXtxYbRt1V+CdQSy6Z+uZti7JF5irRKF8hlKfEnF/xJpcNGuuiZMBvuoYM+x9sr9iWGnzrlM0+9hvQ1kgkf1w==", |       "integrity": "sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==", | ||||||
|       "cpu": [ |       "cpu": [ | ||||||
|         "arm" |         "arm" | ||||||
|       ], |       ], | ||||||
|       "dev": true, |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|       "optional": true, |       "optional": true, | ||||||
|       "os": [ |       "os": [ | ||||||
|         "android" |         "android" | ||||||
|       ] |       ] | ||||||
|     }, |     }, | ||||||
|     "node_modules/@rollup/rollup-android-arm64": { |     "node_modules/@rollup/rollup-android-arm64": { | ||||||
|       "version": "4.14.0", |       "version": "4.34.8", | ||||||
|       "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.0.tgz", |       "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.8.tgz", | ||||||
|       "integrity": "sha512-fI9nduZhCccjzlsA/OuAwtFGWocxA4gqXGTLvOyiF8d+8o0fZUeSztixkYjcGq1fGZY3Tkq4yRvHPFxU+jdZ9Q==", |       "integrity": "sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==", | ||||||
|       "cpu": [ |       "cpu": [ | ||||||
|         "arm64" |         "arm64" | ||||||
|       ], |       ], | ||||||
|       "dev": true, |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|       "optional": true, |       "optional": true, | ||||||
|       "os": [ |       "os": [ | ||||||
|         "android" |         "android" | ||||||
|       ] |       ] | ||||||
|     }, |     }, | ||||||
|     "node_modules/@rollup/rollup-darwin-arm64": { |     "node_modules/@rollup/rollup-darwin-arm64": { | ||||||
|       "version": "4.14.0", |       "version": "4.34.8", | ||||||
|       "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.0.tgz", |       "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.8.tgz", | ||||||
|       "integrity": "sha512-BcnSPRM76/cD2gQC+rQNGBN6GStBs2pl/FpweW8JYuz5J/IEa0Fr4AtrPv766DB/6b2MZ/AfSIOSGw3nEIP8SA==", |       "integrity": "sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==", | ||||||
|       "cpu": [ |       "cpu": [ | ||||||
|         "arm64" |         "arm64" | ||||||
|       ], |       ], | ||||||
|       "dev": true, |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|       "optional": true, |       "optional": true, | ||||||
|       "os": [ |       "os": [ | ||||||
|         "darwin" |         "darwin" | ||||||
|       ] |       ] | ||||||
|     }, |     }, | ||||||
|     "node_modules/@rollup/rollup-darwin-x64": { |     "node_modules/@rollup/rollup-darwin-x64": { | ||||||
|       "version": "4.14.0", |       "version": "4.34.8", | ||||||
|       "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.0.tgz", |       "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.8.tgz", | ||||||
|       "integrity": "sha512-LDyFB9GRolGN7XI6955aFeI3wCdCUszFWumWU0deHA8VpR3nWRrjG6GtGjBrQxQKFevnUTHKCfPR4IvrW3kCgQ==", |       "integrity": "sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==", | ||||||
|       "cpu": [ |       "cpu": [ | ||||||
|         "x64" |         "x64" | ||||||
|       ], |       ], | ||||||
|       "dev": true, |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|       "optional": true, |       "optional": true, | ||||||
|       "os": [ |       "os": [ | ||||||
|         "darwin" |         "darwin" | ||||||
|       ] |       ] | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/@rollup/rollup-freebsd-arm64": { | ||||||
|  |       "version": "4.34.8", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.8.tgz", | ||||||
|  |       "integrity": "sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==", | ||||||
|  |       "cpu": [ | ||||||
|  |         "arm64" | ||||||
|  |       ], | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "optional": true, | ||||||
|  |       "os": [ | ||||||
|  |         "freebsd" | ||||||
|  |       ] | ||||||
|  |     }, | ||||||
|  |     "node_modules/@rollup/rollup-freebsd-x64": { | ||||||
|  |       "version": "4.34.8", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.8.tgz", | ||||||
|  |       "integrity": "sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==", | ||||||
|  |       "cpu": [ | ||||||
|  |         "x64" | ||||||
|  |       ], | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "optional": true, | ||||||
|  |       "os": [ | ||||||
|  |         "freebsd" | ||||||
|  |       ] | ||||||
|  |     }, | ||||||
|     "node_modules/@rollup/rollup-linux-arm-gnueabihf": { |     "node_modules/@rollup/rollup-linux-arm-gnueabihf": { | ||||||
|       "version": "4.14.0", |       "version": "4.34.8", | ||||||
|       "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.0.tgz", |       "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.8.tgz", | ||||||
|       "integrity": "sha512-ygrGVhQP47mRh0AAD0zl6QqCbNsf0eTo+vgwkY6LunBcg0f2Jv365GXlDUECIyoXp1kKwL5WW6rsO429DBY/bA==", |       "integrity": "sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==", | ||||||
|       "cpu": [ |       "cpu": [ | ||||||
|         "arm" |         "arm" | ||||||
|       ], |       ], | ||||||
|       "dev": true, |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "optional": true, | ||||||
|  |       "os": [ | ||||||
|  |         "linux" | ||||||
|  |       ] | ||||||
|  |     }, | ||||||
|  |     "node_modules/@rollup/rollup-linux-arm-musleabihf": { | ||||||
|  |       "version": "4.34.8", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.8.tgz", | ||||||
|  |       "integrity": "sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==", | ||||||
|  |       "cpu": [ | ||||||
|  |         "arm" | ||||||
|  |       ], | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|       "optional": true, |       "optional": true, | ||||||
|       "os": [ |       "os": [ | ||||||
|         "linux" |         "linux" | ||||||
|       ] |       ] | ||||||
|     }, |     }, | ||||||
|     "node_modules/@rollup/rollup-linux-arm64-gnu": { |     "node_modules/@rollup/rollup-linux-arm64-gnu": { | ||||||
|       "version": "4.14.0", |       "version": "4.34.8", | ||||||
|       "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.0.tgz", |       "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.8.tgz", | ||||||
|       "integrity": "sha512-x+uJ6MAYRlHGe9wi4HQjxpaKHPM3d3JjqqCkeC5gpnnI6OWovLdXTpfa8trjxPLnWKyBsSi5kne+146GAxFt4A==", |       "integrity": "sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==", | ||||||
|       "cpu": [ |       "cpu": [ | ||||||
|         "arm64" |         "arm64" | ||||||
|       ], |       ], | ||||||
|       "dev": true, |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|       "optional": true, |       "optional": true, | ||||||
|       "os": [ |       "os": [ | ||||||
|         "linux" |         "linux" | ||||||
|       ] |       ] | ||||||
|     }, |     }, | ||||||
|     "node_modules/@rollup/rollup-linux-arm64-musl": { |     "node_modules/@rollup/rollup-linux-arm64-musl": { | ||||||
|       "version": "4.14.0", |       "version": "4.34.8", | ||||||
|       "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.0.tgz", |       "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.8.tgz", | ||||||
|       "integrity": "sha512-nrRw8ZTQKg6+Lttwqo6a2VxR9tOroa2m91XbdQ2sUUzHoedXlsyvY1fN4xWdqz8PKmf4orDwejxXHjh7YBGUCA==", |       "integrity": "sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==", | ||||||
|       "cpu": [ |       "cpu": [ | ||||||
|         "arm64" |         "arm64" | ||||||
|       ], |       ], | ||||||
|       "dev": true, |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "optional": true, | ||||||
|  |       "os": [ | ||||||
|  |         "linux" | ||||||
|  |       ] | ||||||
|  |     }, | ||||||
|  |     "node_modules/@rollup/rollup-linux-loongarch64-gnu": { | ||||||
|  |       "version": "4.34.8", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.8.tgz", | ||||||
|  |       "integrity": "sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==", | ||||||
|  |       "cpu": [ | ||||||
|  |         "loong64" | ||||||
|  |       ], | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|       "optional": true, |       "optional": true, | ||||||
|       "os": [ |       "os": [ | ||||||
|         "linux" |         "linux" | ||||||
|       ] |       ] | ||||||
|     }, |     }, | ||||||
|     "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { |     "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { | ||||||
|       "version": "4.14.0", |       "version": "4.34.8", | ||||||
|       "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.0.tgz", |       "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.8.tgz", | ||||||
|       "integrity": "sha512-xV0d5jDb4aFu84XKr+lcUJ9y3qpIWhttO3Qev97z8DKLXR62LC3cXT/bMZXrjLF9X+P5oSmJTzAhqwUbY96PnA==", |       "integrity": "sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==", | ||||||
|       "cpu": [ |       "cpu": [ | ||||||
|         "ppc64le" |         "ppc64" | ||||||
|       ], |       ], | ||||||
|       "dev": true, |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|       "optional": true, |       "optional": true, | ||||||
|       "os": [ |       "os": [ | ||||||
|         "linux" |         "linux" | ||||||
|       ] |       ] | ||||||
|     }, |     }, | ||||||
|     "node_modules/@rollup/rollup-linux-riscv64-gnu": { |     "node_modules/@rollup/rollup-linux-riscv64-gnu": { | ||||||
|       "version": "4.14.0", |       "version": "4.34.8", | ||||||
|       "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.0.tgz", |       "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.8.tgz", | ||||||
|       "integrity": "sha512-SDDhBQwZX6LPRoPYjAZWyL27LbcBo7WdBFWJi5PI9RPCzU8ijzkQn7tt8NXiXRiFMJCVpkuMkBf4OxSxVMizAw==", |       "integrity": "sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==", | ||||||
|       "cpu": [ |       "cpu": [ | ||||||
|         "riscv64" |         "riscv64" | ||||||
|       ], |       ], | ||||||
|       "dev": true, |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|       "optional": true, |       "optional": true, | ||||||
|       "os": [ |       "os": [ | ||||||
|         "linux" |         "linux" | ||||||
|       ] |       ] | ||||||
|     }, |     }, | ||||||
|     "node_modules/@rollup/rollup-linux-s390x-gnu": { |     "node_modules/@rollup/rollup-linux-s390x-gnu": { | ||||||
|       "version": "4.14.0", |       "version": "4.34.8", | ||||||
|       "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.0.tgz", |       "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz", | ||||||
|       "integrity": "sha512-RxB/qez8zIDshNJDufYlTT0ZTVut5eCpAZ3bdXDU9yTxBzui3KhbGjROK2OYTTor7alM7XBhssgoO3CZ0XD3qA==", |       "integrity": "sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==", | ||||||
|       "cpu": [ |       "cpu": [ | ||||||
|         "s390x" |         "s390x" | ||||||
|       ], |       ], | ||||||
|       "dev": true, |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|       "optional": true, |       "optional": true, | ||||||
|       "os": [ |       "os": [ | ||||||
|         "linux" |         "linux" | ||||||
|       ] |       ] | ||||||
|     }, |     }, | ||||||
|     "node_modules/@rollup/rollup-linux-x64-gnu": { |     "node_modules/@rollup/rollup-linux-x64-gnu": { | ||||||
|       "version": "4.14.0", |       "version": "4.34.8", | ||||||
|       "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.0.tgz", |       "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz", | ||||||
|       "integrity": "sha512-C6y6z2eCNCfhZxT9u+jAM2Fup89ZjiG5pIzZIDycs1IwESviLxwkQcFRGLjnDrP+PT+v5i4YFvlcfAs+LnreXg==", |       "integrity": "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==", | ||||||
|       "cpu": [ |       "cpu": [ | ||||||
|         "x64" |         "x64" | ||||||
|       ], |       ], | ||||||
|       "dev": true, |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|       "optional": true, |       "optional": true, | ||||||
|       "os": [ |       "os": [ | ||||||
|         "linux" |         "linux" | ||||||
|       ] |       ] | ||||||
|     }, |     }, | ||||||
|     "node_modules/@rollup/rollup-linux-x64-musl": { |     "node_modules/@rollup/rollup-linux-x64-musl": { | ||||||
|       "version": "4.14.0", |       "version": "4.34.8", | ||||||
|       "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.0.tgz", |       "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.8.tgz", | ||||||
|       "integrity": "sha512-i0QwbHYfnOMYsBEyjxcwGu5SMIi9sImDVjDg087hpzXqhBSosxkE7gyIYFHgfFl4mr7RrXksIBZ4DoLoP4FhJg==", |       "integrity": "sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==", | ||||||
|       "cpu": [ |       "cpu": [ | ||||||
|         "x64" |         "x64" | ||||||
|       ], |       ], | ||||||
|       "dev": true, |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|       "optional": true, |       "optional": true, | ||||||
|       "os": [ |       "os": [ | ||||||
|         "linux" |         "linux" | ||||||
|       ] |       ] | ||||||
|     }, |     }, | ||||||
|     "node_modules/@rollup/rollup-win32-arm64-msvc": { |     "node_modules/@rollup/rollup-win32-arm64-msvc": { | ||||||
|       "version": "4.14.0", |       "version": "4.34.8", | ||||||
|       "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.0.tgz", |       "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.8.tgz", | ||||||
|       "integrity": "sha512-Fq52EYb0riNHLBTAcL0cun+rRwyZ10S9vKzhGKKgeD+XbwunszSY0rVMco5KbOsTlwovP2rTOkiII/fQ4ih/zQ==", |       "integrity": "sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==", | ||||||
|       "cpu": [ |       "cpu": [ | ||||||
|         "arm64" |         "arm64" | ||||||
|       ], |       ], | ||||||
|       "dev": true, |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|       "optional": true, |       "optional": true, | ||||||
|       "os": [ |       "os": [ | ||||||
|         "win32" |         "win32" | ||||||
|       ] |       ] | ||||||
|     }, |     }, | ||||||
|     "node_modules/@rollup/rollup-win32-ia32-msvc": { |     "node_modules/@rollup/rollup-win32-ia32-msvc": { | ||||||
|       "version": "4.14.0", |       "version": "4.34.8", | ||||||
|       "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.0.tgz", |       "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.8.tgz", | ||||||
|       "integrity": "sha512-e/PBHxPdJ00O9p5Ui43+vixSgVf4NlLsmV6QneGERJ3lnjIua/kim6PRFe3iDueT1rQcgSkYP8ZBBXa/h4iPvw==", |       "integrity": "sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==", | ||||||
|       "cpu": [ |       "cpu": [ | ||||||
|         "ia32" |         "ia32" | ||||||
|       ], |       ], | ||||||
|       "dev": true, |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|       "optional": true, |       "optional": true, | ||||||
|       "os": [ |       "os": [ | ||||||
|         "win32" |         "win32" | ||||||
|       ] |       ] | ||||||
|     }, |     }, | ||||||
|     "node_modules/@rollup/rollup-win32-x64-msvc": { |     "node_modules/@rollup/rollup-win32-x64-msvc": { | ||||||
|       "version": "4.14.0", |       "version": "4.34.8", | ||||||
|       "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.0.tgz", |       "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.8.tgz", | ||||||
|       "integrity": "sha512-aGg7iToJjdklmxlUlJh/PaPNa4PmqHfyRMLunbL3eaMO0gp656+q1zOKkpJ/CVe9CryJv6tAN1HDoR8cNGzkag==", |       "integrity": "sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==", | ||||||
|       "cpu": [ |       "cpu": [ | ||||||
|         "x64" |         "x64" | ||||||
|       ], |       ], | ||||||
|       "dev": true, |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|       "optional": true, |       "optional": true, | ||||||
|       "os": [ |       "os": [ | ||||||
|         "win32" |         "win32" | ||||||
|       ] |       ] | ||||||
|     }, |     }, | ||||||
|     "node_modules/@types/estree": { |     "node_modules/@types/estree": { | ||||||
|       "version": "1.0.5", |       "version": "1.0.6", | ||||||
|       "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", |       "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", | ||||||
|       "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", |       "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", | ||||||
|       "dev": true |       "dev": true, | ||||||
|  |       "license": "MIT" | ||||||
|     }, |     }, | ||||||
|     "node_modules/acorn": { |     "node_modules/acorn": { | ||||||
|       "version": "8.11.3", |       "version": "8.11.3", | ||||||
| @ -346,12 +418,13 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/braces": { |     "node_modules/braces": { | ||||||
|       "version": "3.0.2", |       "version": "3.0.3", | ||||||
|       "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", |       "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", | ||||||
|       "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", |       "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "fill-range": "^7.0.1" |         "fill-range": "^7.1.1" | ||||||
|       }, |       }, | ||||||
|       "engines": { |       "engines": { | ||||||
|         "node": ">=8" |         "node": ">=8" | ||||||
| @ -433,10 +506,11 @@ | |||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "node_modules/fill-range": { |     "node_modules/fill-range": { | ||||||
|       "version": "7.0.1", |       "version": "7.1.1", | ||||||
|       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", |       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", | ||||||
|       "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", |       "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "to-regex-range": "^5.0.1" |         "to-regex-range": "^5.0.1" | ||||||
|       }, |       }, | ||||||
| @ -550,6 +624,7 @@ | |||||||
|       "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", |       "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", | ||||||
|       "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", |       "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|       "engines": { |       "engines": { | ||||||
|         "node": ">=0.12.0" |         "node": ">=0.12.0" | ||||||
|       } |       } | ||||||
| @ -627,12 +702,13 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/rollup": { |     "node_modules/rollup": { | ||||||
|       "version": "4.14.0", |       "version": "4.34.8", | ||||||
|       "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.14.0.tgz", |       "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.8.tgz", | ||||||
|       "integrity": "sha512-Qe7w62TyawbDzB4yt32R0+AbIo6m1/sqO7UPzFS8Z/ksL5mrfhA0v4CavfdmFav3D+ub4QeAgsGEe84DoWe/nQ==", |       "integrity": "sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "@types/estree": "1.0.5" |         "@types/estree": "1.0.6" | ||||||
|       }, |       }, | ||||||
|       "bin": { |       "bin": { | ||||||
|         "rollup": "dist/bin/rollup" |         "rollup": "dist/bin/rollup" | ||||||
| @ -642,21 +718,25 @@ | |||||||
|         "npm": ">=8.0.0" |         "npm": ">=8.0.0" | ||||||
|       }, |       }, | ||||||
|       "optionalDependencies": { |       "optionalDependencies": { | ||||||
|         "@rollup/rollup-android-arm-eabi": "4.14.0", |         "@rollup/rollup-android-arm-eabi": "4.34.8", | ||||||
|         "@rollup/rollup-android-arm64": "4.14.0", |         "@rollup/rollup-android-arm64": "4.34.8", | ||||||
|         "@rollup/rollup-darwin-arm64": "4.14.0", |         "@rollup/rollup-darwin-arm64": "4.34.8", | ||||||
|         "@rollup/rollup-darwin-x64": "4.14.0", |         "@rollup/rollup-darwin-x64": "4.34.8", | ||||||
|         "@rollup/rollup-linux-arm-gnueabihf": "4.14.0", |         "@rollup/rollup-freebsd-arm64": "4.34.8", | ||||||
|         "@rollup/rollup-linux-arm64-gnu": "4.14.0", |         "@rollup/rollup-freebsd-x64": "4.34.8", | ||||||
|         "@rollup/rollup-linux-arm64-musl": "4.14.0", |         "@rollup/rollup-linux-arm-gnueabihf": "4.34.8", | ||||||
|         "@rollup/rollup-linux-powerpc64le-gnu": "4.14.0", |         "@rollup/rollup-linux-arm-musleabihf": "4.34.8", | ||||||
|         "@rollup/rollup-linux-riscv64-gnu": "4.14.0", |         "@rollup/rollup-linux-arm64-gnu": "4.34.8", | ||||||
|         "@rollup/rollup-linux-s390x-gnu": "4.14.0", |         "@rollup/rollup-linux-arm64-musl": "4.34.8", | ||||||
|         "@rollup/rollup-linux-x64-gnu": "4.14.0", |         "@rollup/rollup-linux-loongarch64-gnu": "4.34.8", | ||||||
|         "@rollup/rollup-linux-x64-musl": "4.14.0", |         "@rollup/rollup-linux-powerpc64le-gnu": "4.34.8", | ||||||
|         "@rollup/rollup-win32-arm64-msvc": "4.14.0", |         "@rollup/rollup-linux-riscv64-gnu": "4.34.8", | ||||||
|         "@rollup/rollup-win32-ia32-msvc": "4.14.0", |         "@rollup/rollup-linux-s390x-gnu": "4.34.8", | ||||||
|         "@rollup/rollup-win32-x64-msvc": "4.14.0", |         "@rollup/rollup-linux-x64-gnu": "4.34.8", | ||||||
|  |         "@rollup/rollup-linux-x64-musl": "4.34.8", | ||||||
|  |         "@rollup/rollup-win32-arm64-msvc": "4.34.8", | ||||||
|  |         "@rollup/rollup-win32-ia32-msvc": "4.34.8", | ||||||
|  |         "@rollup/rollup-win32-x64-msvc": "4.34.8", | ||||||
|         "fsevents": "~2.3.2" |         "fsevents": "~2.3.2" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
| @ -743,6 +823,7 @@ | |||||||
|       "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", |       "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", | ||||||
|       "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", |       "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "is-number": "^7.0.0" |         "is-number": "^7.0.0" | ||||||
|       }, |       }, | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| { | { | ||||||
|   "name": "@idotj/mastodon-embed-timeline", |   "name": "@idotj/mastodon-embed-timeline", | ||||||
|   "version": "4.4.2", |   "version": "4.5.0", | ||||||
|   "description": "Displays Mastodon timeline with posts embed in your website. Very easy to setup, no dependencies, no trackers, cross-browser, WCAG compliant and fully responsive.", |   "description": "Displays a Mastodon timeline with posts embed in your website. Very easy to setup, no dependencies, no trackers, cross-browser, WCAG compliant and fully responsive.", | ||||||
|   "license": "GNU", |   "license": "GNU", | ||||||
|   "author": { |   "author": { | ||||||
|     "name": "idotj", |     "name": "idotj", | ||||||
| @ -34,7 +34,7 @@ | |||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|     "clean-css-cli": "^5.6.3", |     "clean-css-cli": "^5.6.3", | ||||||
|     "rollup": "^4.14.0", |     "rollup": "^4.34.8", | ||||||
|     "@rollup/plugin-terser": "^0.4.4" |     "@rollup/plugin-terser": "^0.4.4" | ||||||
|   }, |   }, | ||||||
|   "files": [ |   "files": [ | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| /* Mastodon embed timeline v4.4.2 */ | /* Mastodon embed timeline v4.5.0 */ | ||||||
| /* More info at: */ | /* More info at: */ | ||||||
| /* https://gitlab.com/idotj/mastodon-embed-timeline */ | /* https://gitlab.com/idotj/mastodon-embed-timeline */ | ||||||
| 
 | 
 | ||||||
| @ -476,6 +476,7 @@ body:has(dialog.mt-dialog[open]) { | |||||||
|   gap: 0.25rem; |   gap: 0.25rem; | ||||||
|   align-items: center; |   align-items: center; | ||||||
|   opacity: 0.5; |   opacity: 0.5; | ||||||
|  |   cursor: default; | ||||||
| } | } | ||||||
| .mt-post-counter-bar-replies > svg, | .mt-post-counter-bar-replies > svg, | ||||||
| .mt-post-counter-bar-reblog > svg, | .mt-post-counter-bar-reblog > svg, | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| /** | /** | ||||||
|  * Mastodon embed timeline |  * Mastodon embed timeline | ||||||
|  * @author idotj |  * @author idotj | ||||||
|  * @version 4.4.2 |  * @version 4.5.0 | ||||||
|  * @url https://gitlab.com/idotj/mastodon-embed-timeline
 |  * @url https://gitlab.com/idotj/mastodon-embed-timeline
 | ||||||
|  * @license GNU AGPLv3 |  * @license GNU AGPLv3 | ||||||
|  */ |  */ | ||||||
| @ -20,8 +20,8 @@ export class Init { | |||||||
|       defaultTheme: "auto", |       defaultTheme: "auto", | ||||||
|       maxNbPostFetch: "20", |       maxNbPostFetch: "20", | ||||||
|       maxNbPostShow: "20", |       maxNbPostShow: "20", | ||||||
|       dateLocale: "en-GB", |       dateFormatLocale: "en-GB", | ||||||
|       dateOptions: { |       dateFormatOptions: { | ||||||
|         day: "2-digit", |         day: "2-digit", | ||||||
|         month: "short", |         month: "short", | ||||||
|         year: "numeric", |         year: "numeric", | ||||||
| @ -32,6 +32,7 @@ export class Init { | |||||||
|       hidePinnedPosts: false, |       hidePinnedPosts: false, | ||||||
|       hideUserAccount: false, |       hideUserAccount: false, | ||||||
|       txtMaxLines: "", |       txtMaxLines: "", | ||||||
|  |       filterByLanguage: "", | ||||||
|       btnShowMore: "SHOW MORE", |       btnShowMore: "SHOW MORE", | ||||||
|       btnShowLess: "SHOW LESS", |       btnShowLess: "SHOW LESS", | ||||||
|       markdownBlockquote: false, |       markdownBlockquote: false, | ||||||
| @ -100,7 +101,10 @@ export class Init { | |||||||
|    * Find main container in DOM before building the timeline |    * Find main container in DOM before building the timeline | ||||||
|    */ |    */ | ||||||
|   #getContainerNode() { |   #getContainerNode() { | ||||||
|     // console.log("Initializing Mastodon timeline with settings: ", this.mtSettings);
 |     // console.log(
 | ||||||
|  |     //   "Initializing Mastodon timeline with settings: ",
 | ||||||
|  |     //   this.mtSettings
 | ||||||
|  |     // );
 | ||||||
| 
 | 
 | ||||||
|     const assignContainerNode = () => { |     const assignContainerNode = () => { | ||||||
|       this.mtContainerNode = document.getElementById( |       this.mtContainerNode = document.getElementById( | ||||||
| @ -261,39 +265,55 @@ export class Init { | |||||||
|    * @returns {Object} |    * @returns {Object} | ||||||
|    */ |    */ | ||||||
|   #setUrls(i) { |   #setUrls(i) { | ||||||
|     let urls = {}; |     const { | ||||||
|  |       timelineType, | ||||||
|  |       userId, | ||||||
|  |       hashtagName, | ||||||
|  |       maxNbPostFetch, | ||||||
|  |       hidePinnedPosts, | ||||||
|  |       hideEmojos, | ||||||
|  |     } = this.mtSettings; | ||||||
| 
 | 
 | ||||||
|     if (this.mtSettings.timelineType === "profile") { |     const urls = {}; | ||||||
|       if (this.mtSettings.userId) { | 
 | ||||||
|         urls.timeline = `${i}accounts/${this.mtSettings.userId}/statuses?limit=${this.mtSettings.maxNbPostFetch}`; |     switch (timelineType) { | ||||||
|         if (!this.mtSettings.hidePinnedPosts) { |       case "profile": | ||||||
|           urls.pinned = `${i}accounts/${this.mtSettings.userId}/statuses?pinned=true`; |         if (!userId) { | ||||||
|         } |  | ||||||
|       } else { |  | ||||||
|           this.#showError( |           this.#showError( | ||||||
|             "Please check your <strong>userId</strong> value", |             "Please check your <strong>userId</strong> value", | ||||||
|             "⚠️" |             "⚠️" | ||||||
|           ); |           ); | ||||||
|  |           break; | ||||||
|         } |         } | ||||||
|     } else if (this.mtSettings.timelineType === "hashtag") { |         urls.timeline = `${i}accounts/${userId}/statuses?limit=${maxNbPostFetch}`; | ||||||
|       if (this.mtSettings.hashtagName) { |         if (!hidePinnedPosts) { | ||||||
|         urls.timeline = `${i}timelines/tag/${this.mtSettings.hashtagName}?limit=${this.mtSettings.maxNbPostFetch}`; |           urls.pinned = `${i}accounts/${userId}/statuses?pinned=true`; | ||||||
|       } else { |         } | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |       case "hashtag": | ||||||
|  |         if (!hashtagName) { | ||||||
|           this.#showError( |           this.#showError( | ||||||
|             "Please check your <strong>hashtagName</strong> value", |             "Please check your <strong>hashtagName</strong> value", | ||||||
|             "⚠️" |             "⚠️" | ||||||
|           ); |           ); | ||||||
|  |           break; | ||||||
|         } |         } | ||||||
|     } else if (this.mtSettings.timelineType === "local") { |         urls.timeline = `${i}timelines/tag/${hashtagName}?limit=${maxNbPostFetch}`; | ||||||
|       urls.timeline = `${i}timelines/public?local=true&limit=${this.mtSettings.maxNbPostFetch}`; |         break; | ||||||
|     } else { | 
 | ||||||
|  |       case "local": | ||||||
|  |         urls.timeline = `${i}timelines/public?local=true&limit=${maxNbPostFetch}`; | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |       default: | ||||||
|         this.#showError( |         this.#showError( | ||||||
|           "Please check your <strong>timelineType</strong> value", |           "Please check your <strong>timelineType</strong> value", | ||||||
|           "⚠️" |           "⚠️" | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (!this.mtSettings.hideEmojos) { |     if (!hideEmojos) { | ||||||
|       urls.emojos = `${i}custom_emojis`; |       urls.emojos = `${i}custom_emojis`; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -375,27 +395,39 @@ export class Init { | |||||||
| 
 | 
 | ||||||
|     // console.log("Mastodon timeline data fetched: ", this.fetchedData);
 |     // console.log("Mastodon timeline data fetched: ", this.fetchedData);
 | ||||||
| 
 | 
 | ||||||
|  |     const { | ||||||
|  |       hideUnlisted, | ||||||
|  |       hideReblog, | ||||||
|  |       hideReplies, | ||||||
|  |       maxNbPostShow, | ||||||
|  |       filterByLanguage, | ||||||
|  |     } = this.mtSettings; | ||||||
|     const posts = this.fetchedData.timeline; |     const posts = this.fetchedData.timeline; | ||||||
|     let nbPostToShow = 0; |     let nbPostToShow = 0; | ||||||
| 
 |  | ||||||
|     this.mtBodyNode.replaceChildren(); |     this.mtBodyNode.replaceChildren(); | ||||||
| 
 | 
 | ||||||
|     posts.forEach((post) => { |     const filteredPosts = posts.filter((post) => { | ||||||
|       const isPublicOrUnlisted = |       const isPublicOrUnlisted = | ||||||
|         post.visibility === "public" || |         post.visibility === "public" || | ||||||
|         (!this.mtSettings.hideUnlisted && post.visibility === "unlisted"); |         (!hideUnlisted && post.visibility === "unlisted"); | ||||||
|       const shouldHideReblog = this.mtSettings.hideReblog && post.reblog; |       const shouldHideReblog = hideReblog && post.reblog; | ||||||
|       const shouldHideReplies = |       const shouldHideReplies = hideReplies && post.in_reply_to_id; | ||||||
|         this.mtSettings.hideReplies && post.in_reply_to_id; |       const postLanguage = | ||||||
|  |         post.language || (post.reblog ? post.reblog.language : null); | ||||||
|  |       const matchesLanguage = | ||||||
|  |         filterByLanguage === "" || postLanguage === filterByLanguage; | ||||||
| 
 | 
 | ||||||
|       // Filter by (Public / Unlisted)
 |       return ( | ||||||
|       if (isPublicOrUnlisted && !shouldHideReblog && !shouldHideReplies) { |         isPublicOrUnlisted && | ||||||
|         if (nbPostToShow < this.mtSettings.maxNbPostShow) { |         !shouldHideReblog && | ||||||
|           this.#appendPost(post, nbPostToShow); |         !shouldHideReplies && | ||||||
|           nbPostToShow++; |         matchesLanguage | ||||||
|         } else { |       ); | ||||||
|           // Reached the limit of maximum number of posts to show
 |     }); | ||||||
|         } | 
 | ||||||
|  |     filteredPosts.forEach((post, index) => { | ||||||
|  |       if (index < maxNbPostShow) { | ||||||
|  |         this.#appendPost(post, index); | ||||||
|       } |       } | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
| @ -472,312 +504,187 @@ export class Init { | |||||||
|    * @param {Number} i Index of post |    * @param {Number} i Index of post | ||||||
|    */ |    */ | ||||||
|   #assamblePost(c, i) { |   #assamblePost(c, i) { | ||||||
|     let avatar, |     const isReblog = Boolean(c.reblog); | ||||||
|       user, |     const post = isReblog ? c.reblog : c; | ||||||
|       userName, |     const { | ||||||
|       accountName, |  | ||||||
|       url, |       url, | ||||||
|       date, |       created_at: date, | ||||||
|       formattedDate, |       replies_count, | ||||||
|       favoritesCount, |       reblogs_count, | ||||||
|       reblogCount, |       favourites_count, | ||||||
|       repliesCount; |     } = post; | ||||||
| 
 |     const { | ||||||
|     if (c.reblog) { |       avatar, | ||||||
|       // BOOSTED post
 |       url: accountUrl, | ||||||
|       // Post url
 |       username, | ||||||
|       url = c.reblog.url; |       display_name, | ||||||
| 
 |       emojis, | ||||||
|       // Boosted avatar
 |     } = post.account; | ||||||
|       avatar = |  | ||||||
|         '<a href="' + |  | ||||||
|         c.reblog.account.url + |  | ||||||
|         '" class="mt-post-avatar" rel="nofollow noopener noreferrer" target="_blank">' + |  | ||||||
|         '<div class="mt-post-avatar-boosted">' + |  | ||||||
|         '<div class="mt-post-avatar-image-big mt-loading-spinner">' + |  | ||||||
|         '<img src="' + |  | ||||||
|         c.reblog.account.avatar + |  | ||||||
|         '" alt="' + |  | ||||||
|         this.#escapeHTML(c.reblog.account.username) + |  | ||||||
|         ' avatar" loading="lazy" />' + |  | ||||||
|         "</div>" + |  | ||||||
|         '<div class="mt-post-avatar-image-small">' + |  | ||||||
|         '<img src="' + |  | ||||||
|         c.account.avatar + |  | ||||||
|         '" alt="' + |  | ||||||
|         this.#escapeHTML(c.account.username) + |  | ||||||
|         ' avatar" loading="lazy" />' + |  | ||||||
|         "</div>" + |  | ||||||
|         "</div>" + |  | ||||||
|         "</a>"; |  | ||||||
| 
 |  | ||||||
|       // User name and url
 |  | ||||||
|       if (!this.mtSettings.hideEmojos && c.reblog.account.display_name) { |  | ||||||
|         userName = this.#shortcode2Emojos( |  | ||||||
|           c.reblog.account.display_name, |  | ||||||
|           c.reblog.account.emojis |  | ||||||
|         ); |  | ||||||
|       } else { |  | ||||||
|         userName = c.reblog.account.display_name |  | ||||||
|           ? c.reblog.account.display_name |  | ||||||
|           : c.reblog.account.username; |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       if (!this.mtSettings.hideUserAccount) { |  | ||||||
|         accountName = |  | ||||||
|           '<br /><span class="mt-post-header-user-account">@' + |  | ||||||
|           c.reblog.account.username + |  | ||||||
|           "@" + |  | ||||||
|           new URL(c.reblog.account.url).hostname + |  | ||||||
|           "</span>"; |  | ||||||
|       } else { |  | ||||||
|         accountName = ""; |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       user = |  | ||||||
|         '<div class="mt-post-header-user">' + |  | ||||||
|         '<a href="' + |  | ||||||
|         c.reblog.account.url + |  | ||||||
|         '" rel="nofollow noopener noreferrer" target="_blank"><bdi class="mt-post-header-user-name">' + |  | ||||||
|         userName + |  | ||||||
|         "</bdi>" + |  | ||||||
|         accountName + |  | ||||||
|         "</a>" + |  | ||||||
|         "</div>"; |  | ||||||
| 
 |  | ||||||
|       // Date
 |  | ||||||
|       date = c.reblog.created_at; |  | ||||||
| 
 |  | ||||||
|       // Counter bar
 |  | ||||||
|       repliesCount = c.reblog.replies_count; |  | ||||||
|       reblogCount = c.reblog.reblogs_count; |  | ||||||
|       favoritesCount = c.reblog.favourites_count; |  | ||||||
|     } else { |  | ||||||
|       // STANDARD post
 |  | ||||||
|       // Post url
 |  | ||||||
|       url = c.url; |  | ||||||
| 
 | 
 | ||||||
|     // Avatar
 |     // Avatar
 | ||||||
|       avatar = |     const avatarHTML = | ||||||
|       '<a href="' + |       '<a href="' + | ||||||
|         c.account.url + |       accountUrl + | ||||||
|       '" class="mt-post-avatar" rel="nofollow noopener noreferrer" target="_blank">' + |       '" class="mt-post-avatar" rel="nofollow noopener noreferrer" target="_blank">' + | ||||||
|         '<div class="mt-post-avatar-standard">' + |       '<div class="mt-post-avatar-' + | ||||||
|  |       (isReblog ? "boosted" : "standard") + | ||||||
|  |       '">' + | ||||||
|       '<div class="mt-post-avatar-image-big mt-loading-spinner">' + |       '<div class="mt-post-avatar-image-big mt-loading-spinner">' + | ||||||
|  |       '<img src="' + | ||||||
|  |       avatar + | ||||||
|  |       '" alt="' + | ||||||
|  |       this.#escapeHTML(username) + | ||||||
|  |       ' avatar" loading="lazy" />' + | ||||||
|  |       "</div>" + | ||||||
|  |       (isReblog | ||||||
|  |         ? '<div class="mt-post-avatar-image-small">' + | ||||||
|           '<img src="' + |           '<img src="' + | ||||||
|           c.account.avatar + |           c.account.avatar + | ||||||
|           '" alt="' + |           '" alt="' + | ||||||
|           this.#escapeHTML(c.account.username) + |           this.#escapeHTML(c.account.username) + | ||||||
|           ' avatar" loading="lazy" />' + |           ' avatar" loading="lazy" />' + | ||||||
|         "</div>" + |           "</div>" | ||||||
|  |         : "") + | ||||||
|       "</div>" + |       "</div>" + | ||||||
|       "</a>"; |       "</a>"; | ||||||
| 
 | 
 | ||||||
|       // User name and url
 |     // User
 | ||||||
|       if (!this.mtSettings.hideEmojos && c.account.display_name) { |     const userNameFull = | ||||||
|         userName = this.#shortcode2Emojos( |       !this.mtSettings.hideEmojos && display_name | ||||||
|           c.account.display_name, |         ? this.#shortcode2Emojos(display_name, emojis) | ||||||
|           c.account.emojis |         : display_name || username; | ||||||
|         ); |  | ||||||
|       } else { |  | ||||||
|         userName = c.account.display_name |  | ||||||
|           ? c.account.display_name |  | ||||||
|           : c.account.username; |  | ||||||
|       } |  | ||||||
| 
 | 
 | ||||||
|       if (!this.mtSettings.hideUserAccount) { |     const accountName = this.mtSettings.hideUserAccount | ||||||
|         accountName = |       ? "" | ||||||
|           '<br /><span class="mt-post-header-user-account">@' + |       : '<br /><span class="mt-post-header-user-account">@' + | ||||||
|           c.account.username + |         username + | ||||||
|         "@" + |         "@" + | ||||||
|           new URL(c.account.url).hostname + |         new URL(accountUrl).hostname + | ||||||
|         "</span>"; |         "</span>"; | ||||||
|       } else { |  | ||||||
|         accountName = ""; |  | ||||||
|       } |  | ||||||
| 
 | 
 | ||||||
|       user = |     const userHTML = | ||||||
|       '<div class="mt-post-header-user">' + |       '<div class="mt-post-header-user">' + | ||||||
|       '<a href="' + |       '<a href="' + | ||||||
|         c.account.url + |       accountUrl + | ||||||
|         '" rel="nofollow noopener noreferrer" target="_blank"><bdi class="mt-post-header-user-name">' + |       '" rel="nofollow noopener noreferrer" target="_blank">' + | ||||||
|         userName + |       '<bdi class="mt-post-header-user-name">' + | ||||||
|  |       userNameFull + | ||||||
|       "</bdi>" + |       "</bdi>" + | ||||||
|       accountName + |       accountName + | ||||||
|       "</a>" + |       "</a>" + | ||||||
|       "</div>"; |       "</div>"; | ||||||
| 
 | 
 | ||||||
|     // Date
 |     // Date
 | ||||||
|       date = c.created_at; |     const formattedDate = this.#formatDate(date); | ||||||
| 
 |     const dateHTML = | ||||||
|       // Counter bar
 |       '<div class="mt-post-header-date">' + | ||||||
|       repliesCount = c.replies_count; |       (c.pinned ? "<svg>...</svg>" : "") + | ||||||
|       reblogCount = c.reblogs_count; |       '<a href="' + | ||||||
|       favoritesCount = c.favourites_count; |       url + | ||||||
|     } |       '" rel="nofollow noopener noreferrer" target="_blank">' + | ||||||
| 
 |       '<time datetime="' + | ||||||
|     // Date
 |       date + | ||||||
|     formattedDate = this.#formatDate(date); |       '">' + | ||||||
|     const timestamp = ` |       formattedDate + | ||||||
|       <div class="mt-post-header-date"> |       "</time>" + | ||||||
|         ${ |       (c.edited_at ? " *" : "") + | ||||||
|           c.pinned |       "</a>" + | ||||||
|             ? '<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24" class="mt-post-pinned" aria-hidden="true"><path d="m640-480 80 80v80H520v240l-40 40-40-40v-240H240v-80l80-80v-280h-40v-80h400v80h-40v280Zm-286 80h252l-46-46v-314H400v314l-46 46Zm126 0Z"></path></svg>' |  | ||||||
|             : "" |  | ||||||
|         } |  | ||||||
|         <a href="${url}" rel="nofollow noopener noreferrer" target="_blank"> |  | ||||||
|           <time datetime="${date}"> |  | ||||||
|             ${formattedDate} |  | ||||||
|           </time> |  | ||||||
|           ${c.edited_at ? " *" : ""} |  | ||||||
|         </a> |  | ||||||
|       </div>`; |  | ||||||
| 
 |  | ||||||
|     // Main text
 |  | ||||||
|     let content = ""; |  | ||||||
|     if (this.mtSettings.txtMaxLines !== "0") { |  | ||||||
|       const txtCss = |  | ||||||
|         this.mtSettings.txtMaxLines.length !== 0 ? " truncate" : ""; |  | ||||||
| 
 |  | ||||||
|       if (c.spoiler_text !== "") { |  | ||||||
|         content = |  | ||||||
|           '<div class="mt-post-txt">' + |  | ||||||
|           this.#formatPostText(c.spoiler_text) + |  | ||||||
|           ' <button type="button" class="mt-btn-dark mt-btn-spoiler-txt" aria-expanded="false">' + |  | ||||||
|           this.mtSettings.btnShowMore + |  | ||||||
|           "</button>" + |  | ||||||
|           '<div class="spoiler-txt-hidden">' + |  | ||||||
|           this.#formatPostText(c.content) + |  | ||||||
|           "</div>" + |  | ||||||
|       "</div>"; |       "</div>"; | ||||||
|       } else if ( | 
 | ||||||
|         c.reblog && |     // Post text
 | ||||||
|         c.reblog.content !== "" && |     const txtTruncateCss = | ||||||
|         c.reblog.spoiler_text !== "" |       this.mtSettings.txtMaxLines !== "0" ? " truncate" : ""; | ||||||
|       ) { |     let postTxt = ""; | ||||||
|         content = |     const textSource = post.spoiler_text ? post.spoiler_text : post.content; | ||||||
|           '<div class="mt-post-txt">' + | 
 | ||||||
|           this.#formatPostText(c.reblog.spoiler_text) + |     if (textSource) { | ||||||
|           ' <button type="button" class="mt-btn-dark mt-btn-spoiler-txt" aria-expanded="false">' + |       postTxt = | ||||||
|           this.mtSettings.btnShowMore + |  | ||||||
|           "</button>" + |  | ||||||
|           '<div class="spoiler-txt-hidden">' + |  | ||||||
|           this.#formatPostText(c.reblog.content) + |  | ||||||
|           "</div>" + |  | ||||||
|           "</div>"; |  | ||||||
|       } else if ( |  | ||||||
|         c.reblog && |  | ||||||
|         c.reblog.content !== "" && |  | ||||||
|         c.reblog.spoiler_text === "" |  | ||||||
|       ) { |  | ||||||
|         content = |  | ||||||
|         '<div class="mt-post-txt' + |         '<div class="mt-post-txt' + | ||||||
|           txtCss + |         txtTruncateCss + | ||||||
|         '">' + |         '">' + | ||||||
|         '<div class="mt-post-txt-wrapper">' + |         '<div class="mt-post-txt-wrapper">' + | ||||||
|           this.#formatPostText(c.reblog.content) + |         this.#formatPostText(textSource) + | ||||||
|         "</div>" + |         "</div>" + | ||||||
|         "</div>"; |         "</div>"; | ||||||
|       } else { |  | ||||||
|         content = |  | ||||||
|           '<div class="mt-post-txt' + |  | ||||||
|           txtCss + |  | ||||||
|           '">' + |  | ||||||
|           '<div class="mt-post-txt-wrapper">' + |  | ||||||
|           this.#formatPostText(c.content) + |  | ||||||
|           "</div>" + |  | ||||||
|           "</div>"; |  | ||||||
|       } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Media attachments
 |     // Media
 | ||||||
|     let media = []; |     const media = [ | ||||||
|     if (c.media_attachments.length > 0) { |       ...c.media_attachments, | ||||||
|       for (let i in c.media_attachments) { |       ...(c.reblog?.media_attachments || []), | ||||||
|         media.push(this.#createMedia(c.media_attachments[i], c.sensitive)); |     ] | ||||||
|       } |       .map((attachment) => this.#createMedia(attachment, post.sensitive)) | ||||||
|     } |       .join(""); | ||||||
|     if (c.reblog && c.reblog.media_attachments.length > 0) { | 
 | ||||||
|       for (let i in c.reblog.media_attachments) { |     const mediaHTML = media | ||||||
|         media.push( |       ? `<div class="mt-post-media-wrapper">${media}</div>` | ||||||
|           this.#createMedia(c.reblog.media_attachments[i], c.reblog.sensitive) |       : ""; | ||||||
|         ); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     media = `<div class="mt-post-media-wrapper">${media.join("")}</div>`; |  | ||||||
| 
 | 
 | ||||||
|     // Preview link
 |     // Preview link
 | ||||||
|     let previewLink = ""; |     const previewLinkHTML = | ||||||
|     if (!this.mtSettings.hidePreviewLink && c.card) { |       !this.mtSettings.hidePreviewLink && c.card | ||||||
|       previewLink = this.#createPreviewLink(c.card); |         ? this.#createPreviewLink(c.card) | ||||||
|     } |         : ""; | ||||||
| 
 | 
 | ||||||
|     // Poll
 |     // Poll
 | ||||||
|     let poll = ""; |     const pollHTML = c.poll | ||||||
|     if (c.poll) { |       ? '<div class="mt-post-poll ' + | ||||||
|       let pollOption = ""; |  | ||||||
|       for (let i in c.poll.options) { |  | ||||||
|         pollOption += "<li>" + c.poll.options[i].title + "</li>"; |  | ||||||
|       } |  | ||||||
|       poll = |  | ||||||
|         '<div class="mt-post-poll ' + |  | ||||||
|         (c.poll.expired ? "mt-post-poll-expired" : "") + |         (c.poll.expired ? "mt-post-poll-expired" : "") + | ||||||
|         '">' + |         '">' + | ||||||
|         "<ul>" + |         "<ul>" + | ||||||
|         pollOption + |         c.poll.options | ||||||
|  |           .map(function (opt) { | ||||||
|  |             return "<li>" + opt.title + "</li>"; | ||||||
|  |           }) | ||||||
|  |           .join("") + | ||||||
|         "</ul>" + |         "</ul>" + | ||||||
|         "</div>"; |         "</div>" | ||||||
|     } |       : ""; | ||||||
| 
 | 
 | ||||||
|     // Counter bar
 |     // Counter bar
 | ||||||
|     let counterBar = ""; |     const counterBarHTML = !this.mtSettings.hideCounterBar | ||||||
|     if (!this.mtSettings.hideCounterBar) { |       ? '<div class="mt-post-counter-bar">' + | ||||||
|       const repliesTag = |         this.#counteBarItem("replies", replies_count) + | ||||||
|         '<div class="mt-post-counter-bar-replies">' + |         this.#counteBarItem("reblog", reblogs_count) + | ||||||
|         '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 -960 960 960" aria-hidden="true"><path d="M774.913-185.869V-356q0-56.609-35.891-92.5-35.892-35.891-92.5-35.891H258.045L411.435-331l-56 56.566L105.869-524l249.566-249.566 56 56.566-153.39 153.391h388.477q88.957 0 148.566 59.609 59.608 59.609 59.608 148v170.131h-79.783Z"></path></svg>' + |         this.#counteBarItem("favorites", favourites_count) + | ||||||
|         repliesCount + |         "</div>" | ||||||
|         "</div>"; |       : ""; | ||||||
| 
 | 
 | ||||||
|       const reblogTag = |     return ( | ||||||
|         '<div class="mt-post-counter-bar-reblog">' + |  | ||||||
|         '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 -960 960 960" aria-hidden="true"><path d="M276.043-65.304 105.869-236.043l170.174-170.175 52.74 54.175-78.652 78.652h449.304v-160h75.261v235.261H250.131l78.652 78.087-52.74 54.74Zm-90.174-457.348v-235.261h524.565L631.782-836l52.74-54.74L854.696-720 684.522-549.26 631.782-604l78.652-78.652H261.13v160h-75.261Z"></path></svg>' + |  | ||||||
|         reblogCount + |  | ||||||
|         "</div>"; |  | ||||||
| 
 |  | ||||||
|       const favoritesTag = |  | ||||||
|         '<div class="mt-post-counter-bar-favorites">' + |  | ||||||
|         '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 -960 960 960" aria-hidden="true"><path d="m330.955-216.328 149.066-89 149.066 90.023-40.305-168.391 131.217-114.347-172.956-14.87L480-671.869l-67.043 158.521-172.956 14.305 131.427 113.796-40.473 168.919ZM212.086-50.608l70.652-305.305L45.52-561.305l312.645-26.579L480-876.176l121.835 288.292 312.645 26.579-237.218 205.392 71.217 305.306L480-213.173 212.086-50.607ZM480-433.87Z"></path></svg>' + |  | ||||||
|         favoritesCount + |  | ||||||
|         "</div>"; |  | ||||||
| 
 |  | ||||||
|       counterBar = |  | ||||||
|         '<div class="mt-post-counter-bar">' + |  | ||||||
|         repliesTag + |  | ||||||
|         reblogTag + |  | ||||||
|         favoritesTag + |  | ||||||
|         "</div>"; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     // Put all elements together in the post container
 |  | ||||||
|     const post = |  | ||||||
|       '<article class="mt-post" aria-posinset="' + |       '<article class="mt-post" aria-posinset="' + | ||||||
|       (i + 1) + |       (i + 1) + | ||||||
|       '" data-location="' + |       '" data-location="' + | ||||||
|       url + |       url + | ||||||
|       '" tabindex="0">' + |       '" tabindex="0">' + | ||||||
|       '<div class="mt-post-header">' + |       '<div class="mt-post-header">' + | ||||||
|       avatar + |       avatarHTML + | ||||||
|       user + |       userHTML + | ||||||
|       timestamp + |       dateHTML + | ||||||
|       "</div>" + |       "</div>" + | ||||||
|       content + |       postTxt + | ||||||
|       media + |       mediaHTML + | ||||||
|       previewLink + |       previewLinkHTML + | ||||||
|       poll + |       pollHTML + | ||||||
|       counterBar + |       counterBarHTML + | ||||||
|       "</article>"; |       "</article>" | ||||||
|  |     ); | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|     return post; |   /** | ||||||
|  |    * Build counter bar items | ||||||
|  |    * @param {string} t Type of icon | ||||||
|  |    * @param {Number} i Counter | ||||||
|  |    */ | ||||||
|  |   #counteBarItem(t, c) { | ||||||
|  |     const icons = { | ||||||
|  |       replies: | ||||||
|  |         '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 -960 960 960" aria-hidden="true"><path d="M774.913-185.869V-356q0-56.609-35.891-92.5-35.892-35.891-92.5-35.891H258.045L411.435-331l-56 56.566L105.869-524l249.566-249.566 56 56.566-153.39 153.391h388.477q88.957 0 148.566 59.609 59.608 59.609 59.608 148v170.131h-79.783Z"></path></svg>', | ||||||
|  |       reblog: | ||||||
|  |         '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 -960 960 960" aria-hidden="true"><path d="M276.043-65.304 105.869-236.043l170.174-170.175 52.74 54.175-78.652 78.652h449.304v-160h75.261v235.261H250.131l78.652 78.087-52.74 54.74Zm-90.174-457.348v-235.261h524.565L631.782-836l52.74-54.74L854.696-720 684.522-549.26 631.782-604l78.652-78.652H261.13v160h-75.261Z"></path></svg>', | ||||||
|  |       favorites: | ||||||
|  |         '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 -960 960 960" aria-hidden="true"><path d="m330.955-216.328 149.066-89 149.066 90.023-40.305-168.391 131.217-114.347-172.956-14.87L480-671.869l-67.043 158.521-172.956 14.305 131.427 113.796-40.473 168.919ZM212.086-50.608l70.652-305.305L45.52-561.305l312.645-26.579L480-876.176l121.835 288.292 312.645 26.579-237.218 205.392 71.217 305.306L480-213.173 212.086-50.607ZM480-433.87Z"></path></svg>', | ||||||
|  |     }; | ||||||
|  |     return `<div class="mt-post-counter-bar-${t}">${icons[t]}${c}</div>`; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   /** |   /** | ||||||
| @ -983,8 +890,8 @@ export class Init { | |||||||
|     const originalDate = new Date(d); |     const originalDate = new Date(d); | ||||||
| 
 | 
 | ||||||
|     const formattedDate = new Intl.DateTimeFormat( |     const formattedDate = new Intl.DateTimeFormat( | ||||||
|       this.mtSettings.dateLocale, |       this.mtSettings.dateFormatLocale, | ||||||
|       this.mtSettings.dateOptions |       this.mtSettings.dateFormatOptions | ||||||
|     ).format(originalDate); |     ).format(originalDate); | ||||||
| 
 | 
 | ||||||
|     return formattedDate; |     return formattedDate; | ||||||
| @ -1408,12 +1315,12 @@ export class Init { | |||||||
|   #createPreviewLink(c) { |   #createPreviewLink(c) { | ||||||
|     let previewDescription = ""; |     let previewDescription = ""; | ||||||
|     if (this.mtSettings.previewMaxLines !== "0" && c.description) { |     if (this.mtSettings.previewMaxLines !== "0" && c.description) { | ||||||
|       const txtCss = |       const txtTruncateCss = | ||||||
|         this.mtSettings.previewMaxLines.length !== 0 ? " truncate" : ""; |         this.mtSettings.previewMaxLines.length !== 0 ? " truncate" : ""; | ||||||
| 
 | 
 | ||||||
|       previewDescription = |       previewDescription = | ||||||
|         '<span class="mt-post-preview-description' + |         '<span class="mt-post-preview-description' + | ||||||
|         txtCss + |         txtTruncateCss + | ||||||
|         '">' + |         '">' + | ||||||
|         this.#parseHTMLstring(c.description) + |         this.#parseHTMLstring(c.description) + | ||||||
|         "</span>"; |         "</span>"; | ||||||
| @ -1591,25 +1498,38 @@ export class Init { | |||||||
|    * @param {Event} e User interaction trigger |    * @param {Event} e User interaction trigger | ||||||
|    */ |    */ | ||||||
|   #openPostUrl(e) { |   #openPostUrl(e) { | ||||||
|     const urlPost = e.target.closest(".mt-post").dataset.location; |     const urlPost = e.target.closest(".mt-post")?.dataset.location; | ||||||
|  |     if (!urlPost) return; | ||||||
|  | 
 | ||||||
|  |     const tagName = e.target.localName; | ||||||
|     if ( |     if ( | ||||||
|       e.target.localName !== "a" && |       tagName === "a" || | ||||||
|       e.target.localName !== "span" && |       tagName === "span" || | ||||||
|       e.target.localName !== "button" && |       tagName === "button" || | ||||||
|       e.target.localName !== "bdi" && |       tagName === "bdi" || | ||||||
|       e.target.localName !== "time" && |       tagName === "time" | ||||||
|       !e.target.classList.contains("mt-post-media-spoiler") && |     ) | ||||||
|       e.target.className !== "mt-post-preview-noImage" && |       return; | ||||||
|       e.target.parentNode.className !== "mt-post-avatar-image-big" && | 
 | ||||||
|       e.target.parentNode.className !== "mt-post-avatar-image-small" && |     const targetClass = e.target.className; | ||||||
|       e.target.parentNode.className !== "mt-post-header-user-name" && |     if ( | ||||||
|       e.target.parentNode.className !== "mt-post-preview-image" && |       targetClass === "mt-post-media-spoiler" || | ||||||
|       e.target.parentNode.className !== "mt-post-preview" && |       targetClass === "mt-post-preview-noImage" | ||||||
|       urlPost |     ) | ||||||
|     ) { |       return; | ||||||
|  | 
 | ||||||
|  |     const parentClass = e.target.parentNode?.className; | ||||||
|  |     if ( | ||||||
|  |       parentClass === "mt-post-avatar-image-big" || | ||||||
|  |       parentClass === "mt-post-avatar-image-small" || | ||||||
|  |       parentClass === "mt-post-header-user-name" || | ||||||
|  |       parentClass === "mt-post-preview-image" || | ||||||
|  |       parentClass === "mt-post-preview" | ||||||
|  |     ) | ||||||
|  |       return; | ||||||
|  | 
 | ||||||
|     window.open(urlPost, "_blank", "noopener"); |     window.open(urlPost, "_blank", "noopener"); | ||||||
|   } |   } | ||||||
|   } |  | ||||||
| 
 | 
 | ||||||
|   /** |   /** | ||||||
|    * Add/Remove EventListeners for loading spinner |    * Add/Remove EventListeners for loading spinner | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 i.j
						i.j