-
-
Save bertiebaggio/9ffe0e6e54d903c3be82cb2137aa5b3b to your computer and use it in GitHub Desktop.
Element youtube preview fix
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Element YouTube Preview | |
// @namespace http://tampermonkey.net/ | |
// @version 0.3 | |
// @description Fix YouTube embeds in Element client-side to keep description (instead of oembed, which does not) | |
// @author Cinnabar (original script) / bertiebaggio (for images & updates) | |
// @match https://example.com/ | |
// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | |
// @grant GM.xmlHttpRequest | |
// @connect youtube.com | |
// @connect youtu.be | |
// ==/UserScript== | |
/* | |
Change example.com in @match to Element client URL, eg https://element.yourdomain if self-hosting | |
Alternatively, you can reconfigure your homeserver to use oembed data, see link below for details. | |
This script will make requests from your browser to YouTube via xmlHttpRequest. | |
See also: | |
- https://github.com/matrix-org/synapse/issues/9733#issuecomment-819488067 (Cinnarbar's comment on original issue, Apr 2021) | |
- https://github.com/element-hq/synapse/issues/17462 (more recent issue with oembed info, Dec 2024) | |
Note: This userscript has been tested with Greasemonkey on a self-hosted Element & homeserver combo. YMMV | |
*/ | |
(function() { | |
'use strict'; | |
const checkForPreviewsInterval = 2000; // 2s, feel free to increase / decrease | |
const checkTitle = "- YouTube"; | |
const checkDescription = "Enjoy the videos and music that you love, upload original content and share it all with friends, family and the world on YouTube."; | |
function previewEditor() { | |
const allPreviews = document.getElementsByClassName('mx_LinkPreviewWidget'); | |
for (const preview of allPreviews) { | |
const previewImg = preview.getElementsByClassName("mx_LinkPreviewWidget_image")[0]; | |
const caption = preview.getElementsByClassName("mx_LinkPreviewWidget_caption")[0]; | |
if (!caption) { continue; } | |
const linkTitle = caption.getElementsByClassName("mx_LinkPreviewWidget_title")[0]; | |
if (!linkTitle) { continue; } | |
const linkDesc = caption.getElementsByClassName("mx_LinkPreviewWidget_description")[0]; | |
if (!linkDesc) { continue; } | |
if (linkTitle.textContent == checkTitle && linkDesc.textContent == checkDescription) { | |
const linkHref = linkTitle.childNodes[0].href; // first child is <a> | |
console.log("YT Preview: fetching " + linkHref); | |
GM.xmlHttpRequest({ | |
method: "GET", | |
url: linkHref, | |
onload: function(response) { | |
if (response.status == 200) { | |
const title = response.responseText.match(/<title[^>]*>([^<]+)<\/title>/)[1]; | |
const desc = response.responseText.match(/<meta name="description" content="(.*?)">/)[1]; | |
const imgsrc = response.responseText.match(/<meta property="og:image" content="(.*?)">/)[1]; | |
linkTitle.childNodes[0].textContent = title; | |
linkDesc.textContent = desc; | |
previewImg.childNodes[0].src = imgsrc; // first child is <img> | |
} | |
} | |
}); | |
} | |
} | |
} | |
setInterval(previewEditor,checkForPreviewsInterval); | |
})(); |
Great work!
Updated as YT previews stopped working again
.text
was not working so this now uses .textContent
🤷
Further improvements welcome :)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
As noted in the original gist, remember to update the
@match
line with the URL of your Element client -- eg// @match https://app.element.io
-- and refresh the page after saving/enabling the script.