diff --git a/scripts/generateSupportedSites.js b/scripts/generateSupportedSites.js
index d227a91..ceae162 100644
--- a/scripts/generateSupportedSites.js
+++ b/scripts/generateSupportedSites.js
@@ -1,6 +1,6 @@
import fs from 'fs/promises'
import path from 'path'
-import siteConfigs from '../src/content/config.js'
+import siteConfigs from '../src/content/sites/config.js'
async function generateSupportedSitesMarkdown() {
let markdownContent = '\n\n'
diff --git a/src/background/background.js b/src/background/background.js
index f3f99dd..45c8d3e 100644
--- a/src/background/background.js
+++ b/src/background/background.js
@@ -1,4 +1,4 @@
-import siteConfigs from '../content/config.js'
+import siteConfigs from '../content/sites/config.js'
// Function to check if the URL matches any of our configured patterns
function getMatchingConfig(url, userSiteConfigs) {
diff --git a/src/content/button.js b/src/content/button.js
new file mode 100644
index 0000000..1a4754e
--- /dev/null
+++ b/src/content/button.js
@@ -0,0 +1,55 @@
+import clipboardTextSvg from '../assets/clipboard.svg'
+import clipboardMdSvg from '../assets/clipboard2.svg'
+import checkmarkSvg from '../assets/checkmark.svg'
+
+export function injectOrUpdateButton(config, formatPreference, selectedStyle, siteConfigs) {
+ let button = document.getElementById(config.buttonId)
+
+ if (!button) {
+ button = document.createElement('button')
+ button.id = config.buttonId
+ document.body.appendChild(button)
+ }
+
+ let icon = formatPreference === 'markdown' ? clipboardMdSvg : clipboardTextSvg
+
+ button.className = `copy-button ${selectedStyle}`
+ button.innerHTML = ``
+
+ button.addEventListener('click', () => handleButtonClick(config, formatPreference, siteConfigs, button))
+}
+
+function handleButtonClick(config, formatPreference, siteConfigs, button) {
+ const siteConfig = siteConfigs[config.siteKey]
+ const pageConfig = siteConfig.pages[config.pageKey]
+ const info = pageConfig.getInfo()
+ const currentUrl = window.location.href
+
+ let textToCopy =
+ formatPreference === 'markdown' ? `${config.prefix} ${pageConfig.buildMarkdown(info, currentUrl)}` : `${config.prefix} ${pageConfig.buildPlaintext(info, currentUrl)}`
+
+ navigator.clipboard
+ .writeText(textToCopy)
+ .then(() => {
+ console.debug('Copied to clipboard: ' + textToCopy)
+ updateButtonAfterCopy(button)
+ })
+ .catch((err) => {
+ console.error('Failed to copy text: ', err)
+ })
+}
+
+function updateButtonAfterCopy(button) {
+ const originalHTML = button.innerHTML
+ button.innerHTML = ``
+ button.classList.add('success')
+ setTimeout(() => {
+ button.innerHTML = originalHTML
+ button.classList.remove('success')
+ }, 2000)
+}
+
+export function removeButtons() {
+ const buttons = document.querySelectorAll('.copy-button')
+ buttons.forEach((button) => button.remove())
+}
diff --git a/src/content/config.js b/src/content/config.js
deleted file mode 100644
index a01e508..0000000
--- a/src/content/config.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import github from './sites/github.js'
-import instagram from './sites/instagram.js'
-import linkedin from './sites/linkedin.js'
-import trello from './sites/trello.js'
-
-const siteConfigs = {
- github,
- instagram,
- linkedin,
- trello,
-}
-
-export default siteConfigs
diff --git a/src/content/content.js b/src/content/content.js
index 6366dad..a6c86be 100644
--- a/src/content/content.js
+++ b/src/content/content.js
@@ -1,94 +1,15 @@
-import siteConfigs from './config.js'
+import siteConfigs from './sites/config.js'
import '../styles/button.css'
-import clipboardTextSvg from '../assets/clipboard.svg'
-import clipboardMdSvg from '../assets/clipboard2.svg'
-import checkmarkSvg from '../assets/checkmark.svg'
-
-let formatPreference = 'markdown'
-let selectedStyle = 'dark' // Default style
-let userSiteConfigs = {}
-let currentConfig = null
-
-function injectOrUpdateButton(config) {
- let button = document.getElementById(config.buttonId)
-
- if (!button) {
- button = document.createElement('button')
- button.id = config.buttonId
- document.body.appendChild(button)
- }
-
- let icon = formatPreference === 'markdown' ? clipboardMdSvg : clipboardTextSvg
-
- button.className = `copy-button ${selectedStyle}`
- button.innerHTML = ``
-
- button.addEventListener('click', () => {
- const siteConfig = siteConfigs[config.siteKey]
- const pageConfig = siteConfig.pages[config.pageKey]
- const info = pageConfig.getInfo()
- const currentUrl = window.location.href
-
- let textToCopy
- if (formatPreference === 'markdown') {
- textToCopy = `${config.prefix} ${pageConfig.buildMarkdown(info, currentUrl)}`
- } else {
- textToCopy = `${config.prefix} ${pageConfig.buildPlaintext(info, currentUrl)}`
- }
-
- navigator.clipboard
- .writeText(textToCopy)
- .then(() => {
- console.debug('Copied to clipboard: ' + textToCopy)
- const originalHTML = button.innerHTML
- button.innerHTML = ``
- button.classList.add('success')
- setTimeout(() => {
- button.innerHTML = originalHTML
- button.classList.remove('success')
- }, 2000)
- })
- .catch((err) => {
- console.error('Failed to copy text: ', err)
- })
- })
-}
-
-// Function to remove all buttons
-function removeButtons() {
- const buttons = document.querySelectorAll('.copy-button')
- buttons.forEach((button) => button.remove())
+import { setupMessageListener, checkCurrentUrl } from './messageHandler.js'
+
+// Global state
+const state = {
+ formatPreference: 'markdown',
+ selectedStyle: 'dark', // Default style
+ userSiteConfigs: {},
+ currentConfig: null,
}
-// Listen for messages from the background script
-chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
- switch (request.action) {
- case 'updateConfig':
- formatPreference = request.formatPreference
- selectedStyle = request.buttonStyle
- userSiteConfigs = request.siteConfigs
- currentConfig = request.config
- if (currentConfig) {
- injectOrUpdateButton(currentConfig)
- } else {
- removeButtons()
- }
- break
- case 'removeButtons':
- removeButtons()
- break
- case 'updatePreference':
- formatPreference = request.formatPreference
- break
- case 'updateStyle':
- selectedStyle = request.buttonStyle
- if (currentConfig) {
- injectOrUpdateButton(currentConfig)
- }
- break
- }
-})
-
// Enable debug in development
if (!('update_url' in chrome.runtime.getManifest())) {
console.log('QuickCite - verbose logging enabled')
@@ -97,5 +18,8 @@ if (!('update_url' in chrome.runtime.getManifest())) {
console.debug = function () {} // Disable in production
}
+// Set up message listener
+setupMessageListener(state, siteConfigs)
+
// Initial setup
-chrome.runtime.sendMessage({ action: 'checkCurrentUrl' })
+checkCurrentUrl()
diff --git a/src/content/messageHandler.js b/src/content/messageHandler.js
new file mode 100644
index 0000000..e65fab7
--- /dev/null
+++ b/src/content/messageHandler.js
@@ -0,0 +1,35 @@
+import { injectOrUpdateButton, removeButtons } from './button.js'
+
+export function setupMessageListener(state, siteConfigs) {
+ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
+ switch (request.action) {
+ case 'updateConfig':
+ state.formatPreference = request.formatPreference
+ state.selectedStyle = request.buttonStyle
+ state.userSiteConfigs = request.siteConfigs
+ state.currentConfig = request.config
+ if (state.currentConfig) {
+ injectOrUpdateButton(state.currentConfig, state.formatPreference, state.selectedStyle, siteConfigs)
+ } else {
+ removeButtons()
+ }
+ break
+ case 'removeButtons':
+ removeButtons()
+ break
+ case 'updatePreference':
+ state.formatPreference = request.formatPreference
+ break
+ case 'updateStyle':
+ state.selectedStyle = request.buttonStyle
+ if (state.currentConfig) {
+ injectOrUpdateButton(state.currentConfig, state.formatPreference, state.selectedStyle, siteConfigs)
+ }
+ break
+ }
+ })
+}
+
+export function checkCurrentUrl() {
+ chrome.runtime.sendMessage({ action: 'checkCurrentUrl' })
+}
diff --git a/src/content/sites/config.js b/src/content/sites/config.js
new file mode 100644
index 0000000..14628e5
--- /dev/null
+++ b/src/content/sites/config.js
@@ -0,0 +1,13 @@
+import github from './github.js'
+import instagram from './instagram.js'
+import linkedin from './linkedin.js'
+import trello from './trello.js'
+
+const siteConfigs = {
+ github,
+ instagram,
+ linkedin,
+ trello,
+}
+
+export default siteConfigs
diff --git a/src/e2e/config.e2e.js b/src/e2e/config.e2e.js
index a948173..7601564 100644
--- a/src/e2e/config.e2e.js
+++ b/src/e2e/config.e2e.js
@@ -1,6 +1,6 @@
import { test as base, expect } from '@playwright/test'
import { e2eTestUrls } from './targets.js'
-import siteConfigs from '../content/config.js'
+import siteConfigs from '../content/sites/config.js'
// Define a common user agent
const COMMON_USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
diff --git a/src/popup/popup.js b/src/popup/popup.js
index aef93f0..2b19646 100644
--- a/src/popup/popup.js
+++ b/src/popup/popup.js
@@ -1,7 +1,7 @@
import '../styles/main.css'
import '../styles/button.css'
import './popup.css'
-import siteConfigs from '../content/config.js'
+import siteConfigs from '../content/sites/config.js'
document.addEventListener('DOMContentLoaded', () => {
// Load current preferences and site configurations
diff --git a/src/test/testUtils.js b/src/test/testUtils.js
index 407bd0c..987887a 100644
--- a/src/test/testUtils.js
+++ b/src/test/testUtils.js
@@ -1,4 +1,4 @@
-import siteConfigs from '../content/config'
+import siteConfigs from '../content/sites/config'
export function runUrlPatternTests(siteName, testCases) {
describe(`${siteName} URL pattern tests`, () => {