1(function ($) { 2 $(document).ready(function () { 3 if (!$("#side-share").length || typeof blssVars === "undefined") { 4 return false; 5 } 6 7 const generatedShortUrls = {}; 8 9 async function init() { 10 attachListeners(); 11 await addShortUrlsToButtons(); 12 saveGeneratedUrlsToWp(); 13 } 14 15 async function saveGeneratedUrlsToWp() { 16 /** 17 * we want to save any short urls to post meta 18 * so we're not regenerating them with every pageload 19 **/ 20 if ($.isEmptyObject(generatedShortUrls)) { 21 return false; 22 } 23 24 $.post(blssVars.ajax_url, { 25 action: "save_urls_to_post_meta", 26 nonce: blssVars.nonce, 27 data: { 28 _350_share_links: generatedShortUrls, 29 post_id: blssVars.post_id, 30 }, 31 }); 32 } 33 34 async function getShortUrl(longUrl) { 35 const body = { longUrl, crawlable: true }; 36 const url = "https://to.350.org/rest/v3/short-urls"; 37 38 try { 39 const response = await fetch(url, { 40 method: "POST", 41 headers: { 42 accept: "application/json", 43 "X-Api-Key": blssVars.shortKey, 44 "Content-Type": "application/json", 45 }, 46 body: JSON.stringify(body), 47 }); 48 49 const data = await response.json(); 50 return data.shortUrl; 51 } catch (error) { 52 return longUrl; 53 } 54 } 55 56 function replaceWithShortLink($el, longUrl) { 57 const encodedShortUrl = encodeURIComponent($el.attr("data-short-url")); 58 const encodedLongUrl = encodeURIComponent(longUrl); 59 const currentUrl = $el.attr("href"); 60 let newUrl = currentUrl.split(encodedLongUrl).join(encodedShortUrl); 61 if (currentUrl && currentUrl.startsWith("mailto:")) { 62 const paramsString = currentUrl.split("?")[1]; 63 let decodedParams = decodeURIComponent(paramsString); 64 decodedParams = decodedParams.replace( 65 longUrl, 66 $el.attr("data-short-url") 67 ); 68 const subject = decodedParams.split("&")[0].split("=")[1]; 69 const body = decodedParams.split("&")[1].split("=")[1]; 70 newUrl = 71 "mailto:?subject=" + 72 encodeURIComponent(subject) + 73 "&body=" + 74 encodeURIComponent(body); 75 } 76 $el.attr("href", newUrl); 77 } 78 79 function getSourceAndPlatform($el) { 80 const platforms = { 81 "button-share-facebook": "fb", 82 "button-share-whatsapp": "wa", 83 "button-share-bluesky": "bs", 84 "button-share-email": "em", 85 "button-share-copy-link": "copylink", 86 }; 87 88 let platform = ""; 89 for (const className in platforms) { 90 if ($el.hasClass(className)) { 91 platform = platforms[className]; 92 break; 93 } 94 } 95 96 let source = `share-web-floating-${platform}`; 97 const slug = window.location.pathname.replace(/\/$/, "").split("/").pop(); 98 99 if (slug) { 100 source += `-${slug}`; 101 } 102 103 return [source, platform]; 104 } 105 106 async function addShortUrlsToButtons() { 107 const longUrl = $("#side-share").attr("data-long-url"); 108 109 const promises = $("#side-share a[data-short-url]") 110 .map(async function () { 111 const $this = $(this); 112 if ($this.attr("data-short-url") == "") { 113 const [source, platform] = getSourceAndPlatform($this); 114 const shortUrl = await getShortUrl(longUrl + "?source=" + source); 115 $this.attr("data-short-url", shortUrl); 116 generatedShortUrls[platform] = shortUrl; 117 } 118 replaceWithShortLink($this, longUrl); 119 }) 120 .get(); 121 122 await Promise.all(promises); 123 } 124 125 function attachListeners() { 126 const $copyLinkButton = $("#side-share .button-share-copy-link"); 127 $copyLinkButton.on("mouseout", function () { 128 $(this).removeClass("clicked").addClass("copied"); 129 }); 130 131 $copyLinkButton.on("click", function (e) { 132 const longUrl = $(this).attr("data-short-url"); 133 e.preventDefault(); 134 135 navigator.clipboard.writeText(longUrl).then(() => { 136 $(this).removeClass("copied").addClass("clicked"); 137 }); 138 }); 139 } 140 141 init(); 142 }); 143})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.