Skip to content

Commit

Permalink
GOTH-498 (#180)
Browse files Browse the repository at this point in the history
* rewrite tweet replacement code, more complex, less destructive

* delete console.log

* remove uneccesary escape characters

* fix regexps, create multiple tweets in parallel

* cleanup

* tweak regexp

* remove old tweet element while we try to create new one

* tweak tweet embed replacer more
  • Loading branch information
walsh9 authored Oct 21, 2022
1 parent 54e8b08 commit 923d070
Showing 1 changed file with 45 additions and 18 deletions.
63 changes: 45 additions & 18 deletions components/Streamfield/StreamfieldEmbedTweet.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,61 @@
import { usePreferredDark } from '@vueuse/core';
import { EmbedBlock } from '~~/composables/types/StreamfieldBlock';
import { computed, ref } from 'vue'
const props = defineProps<{
block: EmbedBlock
}>()
const el = ref(null)
const isDark = usePreferredDark()
const tweetId = computed(() => {
const matches = props.block.value.embed.match(/\/status\/(\d+)/)
if (matches?.length > 1) {
return matches[1]
}
return ''
const tweetRegExp = /<blockquote class="twitter-tweet.*?\/status\/(\d+)\?.*?\/blockquote>/g
const tweetIds = computed(() => {
return [...props.block.value.embed.matchAll(tweetRegExp)].map(matches => matches[1])
})
onMounted(() => {
if (window.twttr) {
window.twttr.widgets.createTweet(tweetId.value, el.value, {theme: isDark.value ? 'dark' : 'light'})
.then((createdTweetEmbed) => {
if (!createdTweetEmbed) {
// fallback to original markup if tweet embed creation fails
el.value.innerHTML = props.block.value.embed
// Remove tweet scripts included with blocks in the cms payload so they can't
// interfere, we're handling this manually
function stripTweetScripts(stringToStrip) {
const tweetScriptMatcher = /<script async(="")? src="https:\/\/platform.twitter.com\/widgets.js" charset="utf-8"><\/script>/g
return stringToStrip.replaceAll(tweetScriptMatcher, '')
}
// find the blockquote element for an unexpanded tweet embed
function findTweetElement(tweetId) {
return [...el.value.querySelectorAll('blockquote.twitter-tweet')].filter(tweet => tweet.outerHTML.includes(tweetId))[0]
}
// replace a tweet blockquote with the expanded embed
function replaceTweet(tweetId) {
return new Promise((resolve) => {
if (window.twttr) {
const originalTweetElement = findTweetElement(tweetId)
if (!originalTweetElement) {
resolve('error finding tweet element')
return;
}
})
} else {
// uh oh, the twitter api script 'window.twttr' hasn't loaded, just
// use the original markup, it's all we can do
el.value.innerHTML = props.block.value.embed
const newTweetDiv = document.createElement('DIV')
originalTweetElement.parentNode.insertBefore(newTweetDiv, originalTweetElement)
originalTweetElement.parentNode.removeChild(originalTweetElement);
window.twttr.widgets.createTweet(tweetId, newTweetDiv, {theme: isDark.value ? 'dark' : 'light'})
.then(createdTweet => {
if (!createdTweet) {
newTweetDiv.parentNode.insertBefore(originalTweetElement, newTweetDiv)
}
})
.catch(e => resolve(e))
.finally(resolve(newTweetDiv))
}
})
}
onMounted(async () => {
el.value.innerHTML = stripTweetScripts(props.block.value.embed)
if (window.twttr) {
await nextTick()
const promises = tweetIds.value.map(id => {return replaceTweet(id)})
Promise.all(promises)
}
})
</script>
Expand Down

0 comments on commit 923d070

Please sign in to comment.