212 | `;
213 |
214 | export class shareOnMastodon extends HTMLElement {
215 | constructor() {
216 | super();
217 |
218 | this.attachShadow({ mode: "open" });
219 | this.shadowRoot.appendChild(template.content.cloneNode(true));
220 |
221 | // Get button text from attribute if available
222 | if (this.dataset.buttonText) {
223 | this.shadowRoot.querySelector("#button-text").innerHTML =
224 | this.dataset.buttonText;
225 | }
226 |
227 | // Get the modal heading from attribute if available
228 | if (this.dataset.modalHeading) {
229 | this.shadowRoot.querySelector("#modal-heading").innerHTML =
230 | this.dataset.modalHeading;
231 | }
232 |
233 | // Get the modal text from attribute if available
234 | if (this.dataset.modalText) {
235 | this.shadowRoot.querySelector("#modal-text").innerHTML =
236 | this.dataset.modalText;
237 | }
238 |
239 | // Get the modal text from attribute if available
240 | if (this.dataset.jargonText) {
241 | this.shadowRoot.querySelector("#instance-jargon").innerHTML =
242 | this.dataset.jargonText;
243 | }
244 |
245 | // Get the default url to use as placeholder text from attribute if available
246 | if (this.dataset.defaultUrl) {
247 | this.shadowRoot.querySelector("#instance-input").placeholder =
248 | this.dataset.defaultUrl;
249 | }
250 |
251 | // Get the share button text from attribute if available
252 | if (this.dataset.shareText) {
253 | this.shadowRoot.querySelector("#share-text").innerHTML =
254 | this.dataset.shareText;
255 | }
256 | }
257 |
258 | openModal() {
259 | // Prefill the form with the user's previously-specified Mastodon instance, if applicable
260 | const storedInstance = localStorage?.getItem("mastodonInstance");
261 | if (storedInstance) {
262 | this.shadowRoot.querySelector("#instance-input").value = storedInstance;
263 | }
264 |
265 | // open Dialog as modal
266 | this.shadowRoot.querySelector("#mastodon-modal").showModal();
267 | }
268 |
269 | urlCheck() {
270 | let val = this.shadowRoot.querySelector("#instance-input").value;
271 | if (!val == "" && !val.startsWith("https://")) {
272 | this.shadowRoot.querySelector("#instance-input").value = "https://" + val;
273 | }
274 | this.shadowRoot.querySelector("#instance-input").checkValidity();
275 | }
276 |
277 | shareOnMastodon() {
278 | // Set instance from the modal text input
279 | let instance = this.shadowRoot.querySelector("#instance-input").value;
280 |
281 | // check, format, and cache instance
282 | if (instance) {
283 | // Handle URL formats
284 | if (!instance.startsWith("https://") && !instance.startsWith("http://"))
285 | instance = "https://" + instance;
286 |
287 | // Handle ending slash
288 | if (!instance.endsWith("/")) instance = instance + "/";
289 |
290 | // Cache the instance/domain for future requests
291 | localStorage?.setItem("mastodonInstance", instance);
292 | }
293 |
294 | // If the share-title attribute is set use it. Otherwise, use the page title
295 | let shareTitle = this.pageTitle;
296 | if (this.dataset.shareTitle) {
297 | shareTitle = this.dataset.shareTitle + "\n";
298 | } else {
299 | shareTitle = docTitle + "\n";
300 | }
301 |
302 | // If the share-description attribute is set use it. Otherwise, only use this for formating
303 | let desc = this.dataset.shareDescription;
304 | if (desc) {
305 | desc = desc + "\n\n";
306 | } else {
307 | desc = "\n";
308 | }
309 |
310 | // If the hashtags attribute is set use it. Otherwise, set it to an empty string
311 | let hashtags = this.dataset.hashtag;
312 | if (hashtags) {
313 | hashtags = "\n\n" + hashtags;
314 | } else {
315 | hashtags = "";
316 | }
317 |
318 | // If the author attribute is set use it. Otherwise, set it to an empty string
319 | let author = this.dataset.author;
320 | if (author) {
321 | author = "\n\n" + author;
322 | } else {
323 | author = "";
324 | }
325 |
326 | // Get the current page's URL
327 | const url = window.location.href;
328 |
329 | // Create the Share URL
330 | const instanceUrl = new URL(`${instance}share?`);
331 | const params = new URLSearchParams({
332 | text: shareTitle + desc + url + hashtags + author,
333 | });
334 | const shareUrl = instanceUrl + params;
335 |
336 | // Open a new tab at the share location
337 | window.open(shareUrl, "_blank");
338 | }
339 |
340 | connectedCallback() {
341 | this.shadowRoot
342 | .querySelector("#mastodon-button")
343 | .addEventListener("click", () => this.openModal());
344 | this.shadowRoot
345 | .querySelector("#share-button")
346 | .addEventListener("click", () => this.shareOnMastodon());
347 | this.shadowRoot
348 | .querySelector("#instance-input")
349 | .addEventListener("blur", () => this.urlCheck());
350 | }
351 |
352 | disconnectedCallback() {
353 | this.shadowRoot.querySelector("#mastodon-button").removeEventListener();
354 | this.shadowRoot.querySelector("#share-button").removeEventListener();
355 | }
356 | }
357 |
358 | window.customElements.define("share-on-mastodon", shareOnMastodon);
359 |
--------------------------------------------------------------------------------