Skip to content

Instantly share code, notes, and snippets.

@AlperRehaYAZGAN
Created November 12, 2024 12:14
Show Gist options
  • Save AlperRehaYAZGAN/84fff9d68ae5f8a5022fe3df8912ffba to your computer and use it in GitHub Desktop.
Save AlperRehaYAZGAN/84fff9d68ae5f8a5022fe3df8912ffba to your computer and use it in GitHub Desktop.
A simple Twitter Gist Viewer Extension written by js. (chrome extension)
/*
// manifest.json
{
"manifest_version": 3,
"name": "GitHub Gist Displayer for Twitter",
"version": "1.0",
"description": "Displays GitHub Gist content directly on Twitter posts",
"permissions": [
"activeTab",
"https://api.github.com/*",
"https://gist.github.com/*"
],
"content_scripts": [
{
"matches": ["https://twitter.com/*", "https://x.com/*"],
"js": ["highlight.min.js", "content.js"],
"css": ["styles.css"]
}
]
}
*/
/*
*/
const GIST_URL_REGEX = /https:\/\/gist\.github\.com\/([^\/]+\/[^\/]+)/;
const processedLinks = new Set();
function fetchGistContent(gistUrl) {
const apiUrl = gistUrl.replace(
"https://gist.github.com",
"https://api.github.com/gists"
);
return fetch(apiUrl)
.then((response) => response.text())
.then((data) => {
// github api returns whole file content in the response
return data;
});
}
function createGistCard(content, gistUrl) {
const card = document.createElement("div");
card.className = "gist-card";
card.style.border = "1px solid #e1e8ed";
card.style.borderRadius = "12px";
card.style.padding = "20px";
card.style.margin = "15px 0";
card.style.backgroundColor = "#f6f8fa";
card.style.maxHeight = "360px";
card.style.overflowY = "auto";
card.style.display = "flex";
card.style.flexDirection = "column";
const pre = document.createElement("pre");
pre.style.whiteSpace = "pre-wrap";
pre.style.wordWrap = "break-word";
pre.style.color = "#333";
pre.style.backgroundColor = "#f6f8fa";
pre.style.padding = "15px";
pre.style.borderRadius = "5px";
pre.style.overflowX = "auto";
pre.style.flexGrow = "1";
// Just show the code content without highlighting
pre.textContent = content;
const buttonContainer = document.createElement("div");
buttonContainer.style.display = "flex";
buttonContainer.style.justifyContent = "space-between";
buttonContainer.style.marginTop = "15px";
const detailsButton = document.createElement("button");
detailsButton.textContent = "See Details";
detailsButton.style.padding = "10px 15px";
detailsButton.style.border = "none";
detailsButton.style.borderRadius = "5px";
detailsButton.style.backgroundColor = "#0366d6";
detailsButton.style.color = "#fff";
detailsButton.style.cursor = "pointer";
detailsButton.addEventListener("click", () => {
window.open(gistUrl, "_blank");
});
const purchaseButton = document.createElement("button");
purchaseButton.textContent = "Purchase";
purchaseButton.style.padding = "10px 15px";
purchaseButton.style.border = "none";
purchaseButton.style.borderRadius = "5px";
purchaseButton.style.backgroundColor = "#28a745";
purchaseButton.style.color = "#fff";
purchaseButton.style.cursor = "pointer";
const highlightButton = document.createElement("button");
highlightButton.textContent = "Highlight";
highlightButton.style.padding = "10px 15px";
highlightButton.style.border = "none";
highlightButton.style.borderRadius = "5px";
highlightButton.style.backgroundColor = "#ffcc00";
highlightButton.style.color = "#000";
highlightButton.style.cursor = "pointer";
highlightButton.addEventListener("click", () => {
hljs.highlightElement(pre);
});
buttonContainer.appendChild(detailsButton);
buttonContainer.appendChild(purchaseButton);
buttonContainer.appendChild(highlightButton);
card.appendChild(pre);
card.appendChild(buttonContainer);
return card;
}
function processTwitterPosts() {
const tweets = document.querySelectorAll("article");
tweets.forEach((tweet) => {
const links = tweet.querySelectorAll("a[href*='t.co']");
links.forEach((link) => {
// link has 1 span, text, 1 span. Merge them into one string
const linkSpansContents = Array.from(link.childNodes)
.map((node) => node.textContent)
.join("")
// remove three dots "…"
.replace(/…/g, "");
const linkSpansContentsAggregated = linkSpansContents.trim();
if (!linkSpansContentsAggregated.match(GIST_URL_REGEX)) {
return;
}
if (processedLinks.has(linkSpansContentsAggregated)) {
return;
}
processedLinks.add(linkSpansContentsAggregated);
const gistUrl = linkSpansContentsAggregated;
const gistToRawUrl = gistUrl.replace(
"https://gist.github.com",
"https://gist.githubusercontent.com"
);
const gistToRawUrlWithRaw = gistToRawUrl + "/raw";
fetchGistContent(gistToRawUrlWithRaw)
.then((content) => {
const gistCard = createGistCard(content, gistUrl);
link.parentNode.insertBefore(gistCard, link.nextSibling);
})
.catch((error) => {
console.error("Error fetching Gist content:", error);
});
hljs.highlightAll();
});
});
}
// Run the script when the page loads and whenever it's updated
processTwitterPosts();
new MutationObserver(processTwitterPosts).observe(document.body, {
childList: true,
subtree: true,
});
// Add Highlight.js initialization
document.addEventListener("DOMContentLoaded", (event) => {
document.querySelectorAll("pre code").forEach((block) => {
hljs.highlightBlock(block);
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment