From 7be1f70846f47ad3fbd5da69296b001dda490af8 Mon Sep 17 00:00:00 2001 From: Jon Friesen Date: Sun, 25 Aug 2024 07:55:58 -0600 Subject: [PATCH] split site configs (#12) --- src/content/config.js | 304 +-------------------------------- src/content/sites/github.js | 213 +++++++++++++++++++++++ src/content/sites/instagram.js | 18 ++ src/content/sites/linkedin.js | 42 +++++ src/content/sites/trello.js | 30 ++++ 5 files changed, 311 insertions(+), 296 deletions(-) create mode 100644 src/content/sites/github.js create mode 100644 src/content/sites/instagram.js create mode 100644 src/content/sites/linkedin.js create mode 100644 src/content/sites/trello.js diff --git a/src/content/config.js b/src/content/config.js index d490d21..a01e508 100644 --- a/src/content/config.js +++ b/src/content/config.js @@ -1,301 +1,13 @@ -// config.js +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: { - domain: 'github.com', - prefix: '๐Ÿ™', - pages: { - pr: { - urlPattern: /^https:\/\/github\.com\/[^\/]+\/[^\/]+\/pull\/\d+/, - buttonId: 'gh-pr-copy-button', - getInfo: () => { - const prNumber = document.querySelector('h1.gh-header-title > span.f1-light').textContent.trim() - const titleElement = document.querySelector('bdi.js-issue-title.markdown-title') - const prTitle = titleElement ? titleElement.textContent.trim() : document.title - return { number: prNumber, title: prTitle } - }, - buildMarkdown: (info, url) => `[${info.number}: ${info.title}](${url})`, - buildPlaintext: (info, url) => `${info.number}: ${info.title} - ${url}`, - }, - issue: { - urlPattern: /^https:\/\/github\.com\/[^\/]+\/[^\/]+\/issues\/\d+/, - buttonId: 'gh-issue-copy-button', - getInfo: () => { - const issueNumber = document.querySelector('h1.gh-header-title > span.f1-light').textContent.trim() - const titleElement = document.querySelector('bdi.js-issue-title.markdown-title') - const issueTitle = titleElement ? titleElement.textContent.trim() : document.title - return { number: issueNumber, title: issueTitle } - }, - buildMarkdown: (info, url) => `[${info.number}: ${info.title}](${url})`, - buildPlaintext: (info, url) => `${info.number}: ${info.title} - ${url}`, - }, - discussion: { - urlPattern: /^https:\/\/github\.com\/[^\/]+\/[^\/]+\/discussions\/\d+/, - buttonId: 'gh-discussion-copy-button', - getInfo: () => { - const discussionNumber = document.querySelector('h1.gh-header-title > span.f1-light').textContent.trim() - const titleElement = document.querySelector('h1.gh-header-title') - const discussionTitle = titleElement ? titleElement.textContent.trim().replace(discussionNumber, '').trim() : document.title - return { number: discussionNumber, title: discussionTitle } - }, - buildMarkdown: (info, url) => `[${info.number}: ${info.title}](${url})`, - buildPlaintext: (info, url) => `${info.number}: ${info.title} - ${url}`, - }, - repo: { - urlPattern: /^https:\/\/github\.com\/[^\/]+\/[^\/]+\/?$/, - buttonId: 'gh-repo-copy-button', - getInfo: () => { - let repo = document.title.split(':')[0].trim() || document.querySelector('div.AppHeader-context-full').textContent.trim() - // if repo starts with "GitHub - " then remove it - if (repo.startsWith('GitHub - ')) { - repo = repo.substring(9) - } - const repoDescription = document.querySelector('p.f4.my-3').textContent.trim() - return { title: repo, description: repoDescription } - }, - buildMarkdown: (info, url) => `[${info.title}](${url})${info.description ? ` - ${info.description}` : ''}`, - buildPlaintext: (info, url) => `${info.title} - ${url}${info.description ? ` (${info.description})` : ''}`, - }, - user: { - urlPattern: /^https:\/\/github\.com\/[^\/]+\/?$/, - buttonId: 'gh-user-copy-button', - getInfo: () => { - const name = document.title.trim() - let bio = '' - - // Check if it's an organization page - const isOrg = !!document.querySelector('meta[name="hovercard-subject-tag"][content^="organization:"]') - - if (isOrg) { - // For organizations, try to get the description - bio = document.querySelector('header > div > div > div.flex-1.d-flex.flex-column.gap-2 > div.color-fg-muted > div')?.textContent.trim() || '' - } else { - // For users, get the bio - bio = document.querySelector('div[data-bio-text]')?.textContent.trim() || '' - } - - return { name, bio } - }, - buildMarkdown: (info, url) => `[${info.name}](${url})${info.bio ? ` - ${info.bio}` : ''}`, - buildPlaintext: (info, url) => `${info.name} - ${url}${info.bio ? ` (${info.bio})` : ''}`, - }, - release: { - urlPattern: /^https:\/\/github\.com\/[^\/]+\/[^\/]+\/releases\/tag\/[^\/]+/, - buttonId: 'gh-release-copy-button', - getInfo: () => { - const releaseBodyElement = document.querySelector('div.Box-body') - - // Get the release title - const titleElement = releaseBodyElement.querySelector('h1') - const releaseTitle = titleElement ? titleElement.textContent.trim() : '' - - // Get the release tag - const tagSvgElement = releaseBodyElement.querySelector('svg.octicon.octicon-tag') - const spanElement = tagSvgElement ? tagSvgElement.nextElementSibling : null - const releaseTag = spanElement ? spanElement.textContent.trim() : '' - - // Get the release date - const dateElement = releaseBodyElement.querySelector('relative-time') - const releaseDate = dateElement ? dateElement.getAttribute('datetime') : '' - - // Build title - let releaseTitleAndTag = releaseTitle - if (releaseTitle && releaseTag !== releaseTitle) { - releaseTitleAndTag = `${releaseTag}: ${releaseTitle}` - } - - // Get the release description - // Note: I'm not sure if I want to include the release description - // const descriptionElement = document.querySelector('.markdown-body') - // const releaseDescription = descriptionElement ? descriptionElement.textContent.trim() : '' - - return { - title: releaseTitleAndTag, - date: releaseDate, - } - }, - buildMarkdown: (info, url) => { - const formattedDate = info.date ? new Date(info.date).toLocaleDateString() : '' - return `[${info.title}](${url}) - Released on ${formattedDate}` - }, - buildPlaintext: (info, url) => { - const formattedDate = info.date ? new Date(info.date).toLocaleDateString() : '' - return `${info.title} - ${url}\nReleased on ${formattedDate}` - }, - }, - commit: { - urlPattern: /^https:\/\/github\.com\/[^\/]+\/[^\/]+\/commit\/[a-f0-9]{40}$/, - buttonId: 'gh-commit-copy-button', - getInfo: () => { - const commitTitle = document.querySelector('.commit-title').textContent.trim() - const commitHash = document.querySelector('.sha.user-select-contain').textContent.trim() - const authorName = document.querySelector('.commit-author').textContent.trim() - const commitDate = document.querySelector('relative-time').getAttribute('datetime') - - return { - title: commitTitle, - hash: commitHash, - author: authorName, - date: commitDate, - } - }, - buildMarkdown: (info, url) => { - const formattedDate = new Date(info.date).toLocaleString() - return `[(${info.hash.slice(0, 7)}) - ${info.title}](${url})\nBy ${info.author} on ${formattedDate}` - }, - buildPlaintext: (info, url) => { - const formattedDate = new Date(info.date).toLocaleString() - return `(${info.hash.slice(0, 7)}) -${info.title}\nBy ${info.author} on ${formattedDate}\n${url}` - }, - }, - actions: { - urlPattern: /^https:\/\/github\.com\/[^\/]+\/[^\/]+\/actions\/runs\/\d+$/, - buttonId: 'gh-action-run-copy-button', - getInfo: () => { - const getStatus = () => { - const statusLabel = Array.from(document.querySelectorAll('span.mb-1.d-block.text-small.color-fg-muted')).find((el) => el.textContent.trim() === 'Status') - - if (statusLabel) { - // If found, get the next sibling span which contains the status value - const statusValue = statusLabel.nextElementSibling - if (statusValue && statusValue.classList.contains('h4') && statusValue.classList.contains('color-fg-default')) { - return statusValue.textContent.trim() - } - } - return null - } - const getStatusEmoji = (status) => { - const statusMap = { - Queued: 'โณ', - 'In progress': '๐Ÿ”„', - Success: 'โœ…', - Failure: 'โŒ', - Cancelled: '๐Ÿšซ', - Skipped: 'โญ๏ธ', - } - return statusMap[status] || '' - } - const extractRepoInfo = (str) => { - const parts = str.split('ยท').map((part) => part.trim()) - - if (parts.length >= 2) { - const repoInfo = parts[1].split('/') - if (repoInfo.length >= 2) { - const [name, hash] = repoInfo[1].split('@') - return { - owner: repoInfo[0], - name: name, - hash: hash || null, // In case there's no hash - } - } - } - - return null - } - - // Test the function - const repoInfo = extractRepoInfo(document.title) - const workflowName = document.querySelector('h1.PageHeader-title span.markdown-title').textContent.trim() - const runNumber = document.querySelector('h1.PageHeader-title span.color-fg-muted').textContent.trim() - const runStatus = getStatus() - const repoOwner = repoInfo.owner - const repoName = repoInfo.name - const statusEmoji = getStatusEmoji(runStatus) - return { workflowName, runStatus, runNumber, repoName, repoOwner, statusEmoji } - }, - buildMarkdown: (info, url) => { - return `[${info.repoOwner}/${info.repoName}: ${info.workflowName} ${info.runNumber} ${info.statusEmoji} (${info.runStatus})](${url})` - }, - buildPlaintext: (info, url) => { - return `${info.repoOwner}/${info.repoName}: ${info.workflowName} ${info.runNumber} ${info.statusEmoji} (${info.runStatus}) - ${url}` - }, - }, - }, - }, - instagram: { - domain: 'instagram.com', - prefix: '๐Ÿ“ธ', - pages: { - profile: { - urlPattern: /^https:\/\/www\.instagram\.com\/[^\/]+\/?$/, - buttonId: 'instagram-profile-copy-button', - getInfo: () => { - const name = document.title.split('โ€ข')[0].trim() - return { name } - }, - buildMarkdown: (info, url) => `[${info.name}](${url})`, - buildPlaintext: (info, url) => `${info.name} - ${url}`, - }, - }, - }, - linkedin: { - domain: 'linkedin.com', - prefix: '๐Ÿ’ผ', - pages: { - profile: { - urlPattern: /^https:\/\/www\.linkedin\.com\/in\/[^\/]+\/?$/, - buttonId: 'li-profile-copy-button', - getInfo: () => { - const name = document.querySelector('h1.text-heading-xlarge').textContent.trim() - const headline = document.querySelector('div.text-body-medium').textContent.trim() - return { name, headline } - }, - buildMarkdown: (info, url) => `[${info.name}](${url}) - ${info.headline}`, - buildPlaintext: (info, url) => `${info.name} - ${info.headline} - ${url}`, - }, - company: { - urlPattern: /^https:\/\/www\.linkedin\.com\/company\/[^\/]+\/?$/, - buttonId: 'li-company-copy-button', - getInfo: () => { - const name = document.querySelector('h1.org-top-card-summary__title').textContent.trim() - const about = document.querySelector('p.org-top-card-summary__tagline').textContent.trim() - return { name, about } - }, - buildMarkdown: (info, url) => `[${info.name}](${url}) - ${info.about}`, - buildPlaintext: (info, url) => `${info.name} - ${url} - ${info.about}`, - }, - pulse: { - urlPattern: /^https:\/\/www\.linkedin\.com\/pulse\/[^\/]+\/?$/, - buttonId: 'li-pulse-copy-button', - getInfo: () => { - const title = document.querySelector('h1.reader-article-header__title').textContent.trim() - const author = document.querySelector('div.reader-author-info__container h2').textContent.trim() - const date = document.querySelector('div.reader-author-info__container time').textContent.trim() - return { title, author, date } - }, - buildMarkdown: (info, url) => `[${info.title}](${url})\nBy ${info.author} | ${info.date}`, - buildPlaintext: (info, url) => `${info.title}\nBy ${info.author} | ${info.date}\n${url}`, - }, - }, - }, - trello: { - domain: 'trello.com', - prefix: '๐Ÿ“‹', - pages: { - board: { - urlPattern: /^https:\/\/trello\.com\/b\/[a-zA-Z0-9]+(?:\/[^\/]+)?$/, - buttonId: 'trello-board-copy-button', - getInfo: () => { - const boardName = document.querySelector('h1[data-testid="board-name-display"]').textContent.trim() - return { boardName } - }, - buildMarkdown: (info, url) => `[${info.boardName}](${url})`, - buildPlaintext: (info, url) => `${info.boardName} - ${url}`, - }, - // TODO: Add card support - // card: { - // urlPattern: /^https:\/\/trello\.com\/c\/[a-zA-Z0-9]+(?:\/[^\/]+)?$/, - // buttonId: 'trello-card-copy-button', - // getInfo: () => { - // const cardName = document.querySelector('h2#js-dialog-title').textContent.trim() - // const boardName = document.querySelector('h1[data-testid="board-name-display"]').textContent.trim() - // return { cardName, boardName } - // }, - // buildMarkdown: (info, url) => `[${info.cardName}](${url}) (${info.boardName})`, - // buildPlaintext: (info, url) => `${info.cardName} (${info.boardName}) - ${url}`, - // }, - }, - }, + github, + instagram, + linkedin, + trello, } export default siteConfigs diff --git a/src/content/sites/github.js b/src/content/sites/github.js new file mode 100644 index 0000000..0f1a2fd --- /dev/null +++ b/src/content/sites/github.js @@ -0,0 +1,213 @@ +const github = { + domain: 'github.com', + prefix: '๐Ÿ™', + pages: { + pr: { + urlPattern: /^https:\/\/github\.com\/[^\/]+\/[^\/]+\/pull\/\d+/, + buttonId: 'gh-pr-copy-button', + getInfo: () => { + const prNumber = document.querySelector('h1.gh-header-title > span.f1-light').textContent.trim() + const titleElement = document.querySelector('bdi.js-issue-title.markdown-title') + const prTitle = titleElement ? titleElement.textContent.trim() : document.title + return { number: prNumber, title: prTitle } + }, + buildMarkdown: (info, url) => `[${info.number}: ${info.title}](${url})`, + buildPlaintext: (info, url) => `${info.number}: ${info.title} - ${url}`, + }, + issue: { + urlPattern: /^https:\/\/github\.com\/[^\/]+\/[^\/]+\/issues\/\d+/, + buttonId: 'gh-issue-copy-button', + getInfo: () => { + const issueNumber = document.querySelector('h1.gh-header-title > span.f1-light').textContent.trim() + const titleElement = document.querySelector('bdi.js-issue-title.markdown-title') + const issueTitle = titleElement ? titleElement.textContent.trim() : document.title + return { number: issueNumber, title: issueTitle } + }, + buildMarkdown: (info, url) => `[${info.number}: ${info.title}](${url})`, + buildPlaintext: (info, url) => `${info.number}: ${info.title} - ${url}`, + }, + discussion: { + urlPattern: /^https:\/\/github\.com\/[^\/]+\/[^\/]+\/discussions\/\d+/, + buttonId: 'gh-discussion-copy-button', + getInfo: () => { + const discussionNumber = document.querySelector('h1.gh-header-title > span.f1-light').textContent.trim() + const titleElement = document.querySelector('h1.gh-header-title') + const discussionTitle = titleElement ? titleElement.textContent.trim().replace(discussionNumber, '').trim() : document.title + return { number: discussionNumber, title: discussionTitle } + }, + buildMarkdown: (info, url) => `[${info.number}: ${info.title}](${url})`, + buildPlaintext: (info, url) => `${info.number}: ${info.title} - ${url}`, + }, + repo: { + urlPattern: /^https:\/\/github\.com\/[^\/]+\/[^\/]+\/?$/, + buttonId: 'gh-repo-copy-button', + getInfo: () => { + let repo = document.title.split(':')[0].trim() || document.querySelector('div.AppHeader-context-full').textContent.trim() + // if repo starts with "GitHub - " then remove it + if (repo.startsWith('GitHub - ')) { + repo = repo.substring(9) + } + const repoDescription = document.querySelector('p.f4.my-3').textContent.trim() + return { title: repo, description: repoDescription } + }, + buildMarkdown: (info, url) => `[${info.title}](${url})${info.description ? ` - ${info.description}` : ''}`, + buildPlaintext: (info, url) => `${info.title} - ${url}${info.description ? ` (${info.description})` : ''}`, + }, + user: { + urlPattern: /^https:\/\/github\.com\/[^\/]+\/?$/, + buttonId: 'gh-user-copy-button', + getInfo: () => { + const name = document.title.trim() + let bio = '' + + // Check if it's an organization page + const isOrg = !!document.querySelector('meta[name="hovercard-subject-tag"][content^="organization:"]') + + if (isOrg) { + // For organizations, try to get the description + bio = document.querySelector('header > div > div > div.flex-1.d-flex.flex-column.gap-2 > div.color-fg-muted > div')?.textContent.trim() || '' + } else { + // For users, get the bio + bio = document.querySelector('div[data-bio-text]')?.textContent.trim() || '' + } + + return { name, bio } + }, + buildMarkdown: (info, url) => `[${info.name}](${url})${info.bio ? ` - ${info.bio}` : ''}`, + buildPlaintext: (info, url) => `${info.name} - ${url}${info.bio ? ` (${info.bio})` : ''}`, + }, + release: { + urlPattern: /^https:\/\/github\.com\/[^\/]+\/[^\/]+\/releases\/tag\/[^\/]+/, + buttonId: 'gh-release-copy-button', + getInfo: () => { + const releaseBodyElement = document.querySelector('div.Box-body') + + // Get the release title + const titleElement = releaseBodyElement.querySelector('h1') + const releaseTitle = titleElement ? titleElement.textContent.trim() : '' + + // Get the release tag + const tagSvgElement = releaseBodyElement.querySelector('svg.octicon.octicon-tag') + const spanElement = tagSvgElement ? tagSvgElement.nextElementSibling : null + const releaseTag = spanElement ? spanElement.textContent.trim() : '' + + // Get the release date + const dateElement = releaseBodyElement.querySelector('relative-time') + const releaseDate = dateElement ? dateElement.getAttribute('datetime') : '' + + // Build title + let releaseTitleAndTag = releaseTitle + if (releaseTitle && releaseTag !== releaseTitle) { + releaseTitleAndTag = `${releaseTag}: ${releaseTitle}` + } + + // Get the release description + // Note: I'm not sure if I want to include the release description + // const descriptionElement = document.querySelector('.markdown-body') + // const releaseDescription = descriptionElement ? descriptionElement.textContent.trim() : '' + + return { + title: releaseTitleAndTag, + date: releaseDate, + } + }, + buildMarkdown: (info, url) => { + const formattedDate = info.date ? new Date(info.date).toLocaleDateString() : '' + return `[${info.title}](${url}) - Released on ${formattedDate}` + }, + buildPlaintext: (info, url) => { + const formattedDate = info.date ? new Date(info.date).toLocaleDateString() : '' + return `${info.title} - ${url}\nReleased on ${formattedDate}` + }, + }, + commit: { + urlPattern: /^https:\/\/github\.com\/[^\/]+\/[^\/]+\/commit\/[a-f0-9]{40}$/, + buttonId: 'gh-commit-copy-button', + getInfo: () => { + const commitTitle = document.querySelector('.commit-title').textContent.trim() + const commitHash = document.querySelector('.sha.user-select-contain').textContent.trim() + const authorName = document.querySelector('.commit-author').textContent.trim() + const commitDate = document.querySelector('relative-time').getAttribute('datetime') + + return { + title: commitTitle, + hash: commitHash, + author: authorName, + date: commitDate, + } + }, + buildMarkdown: (info, url) => { + const formattedDate = new Date(info.date).toLocaleString() + return `[(${info.hash.slice(0, 7)}) - ${info.title}](${url})\nBy ${info.author} on ${formattedDate}` + }, + buildPlaintext: (info, url) => { + const formattedDate = new Date(info.date).toLocaleString() + return `(${info.hash.slice(0, 7)}) -${info.title}\nBy ${info.author} on ${formattedDate}\n${url}` + }, + }, + actions: { + urlPattern: /^https:\/\/github\.com\/[^\/]+\/[^\/]+\/actions\/runs\/\d+$/, + buttonId: 'gh-action-run-copy-button', + getInfo: () => { + const getStatus = () => { + const statusLabel = Array.from(document.querySelectorAll('span.mb-1.d-block.text-small.color-fg-muted')).find((el) => el.textContent.trim() === 'Status') + + if (statusLabel) { + // If found, get the next sibling span which contains the status value + const statusValue = statusLabel.nextElementSibling + if (statusValue && statusValue.classList.contains('h4') && statusValue.classList.contains('color-fg-default')) { + return statusValue.textContent.trim() + } + } + return null + } + const getStatusEmoji = (status) => { + const statusMap = { + Queued: 'โณ', + 'In progress': '๐Ÿ”„', + Success: 'โœ…', + Failure: 'โŒ', + Cancelled: '๐Ÿšซ', + Skipped: 'โญ๏ธ', + } + return statusMap[status] || '' + } + const extractRepoInfo = (str) => { + const parts = str.split('ยท').map((part) => part.trim()) + + if (parts.length >= 2) { + const repoInfo = parts[1].split('/') + if (repoInfo.length >= 2) { + const [name, hash] = repoInfo[1].split('@') + return { + owner: repoInfo[0], + name: name, + hash: hash || null, // In case there's no hash + } + } + } + + return null + } + + // Test the function + const repoInfo = extractRepoInfo(document.title) + const workflowName = document.querySelector('h1.PageHeader-title span.markdown-title').textContent.trim() + const runNumber = document.querySelector('h1.PageHeader-title span.color-fg-muted').textContent.trim() + const runStatus = getStatus() + const repoOwner = repoInfo.owner + const repoName = repoInfo.name + const statusEmoji = getStatusEmoji(runStatus) + return { workflowName, runStatus, runNumber, repoName, repoOwner, statusEmoji } + }, + buildMarkdown: (info, url) => { + return `[${info.repoOwner}/${info.repoName}: ${info.workflowName} ${info.runNumber} ${info.statusEmoji} (${info.runStatus})](${url})` + }, + buildPlaintext: (info, url) => { + return `${info.repoOwner}/${info.repoName}: ${info.workflowName} ${info.runNumber} ${info.statusEmoji} (${info.runStatus}) - ${url}` + }, + }, + }, +} + +export default github diff --git a/src/content/sites/instagram.js b/src/content/sites/instagram.js new file mode 100644 index 0000000..60126f8 --- /dev/null +++ b/src/content/sites/instagram.js @@ -0,0 +1,18 @@ +const instagram = { + domain: 'instagram.com', + prefix: '๐Ÿ“ธ', + pages: { + profile: { + urlPattern: /^https:\/\/www\.instagram\.com\/[^\/]+\/?$/, + buttonId: 'instagram-profile-copy-button', + getInfo: () => { + const name = document.title.split('โ€ข')[0].trim() + return { name } + }, + buildMarkdown: (info, url) => `[${info.name}](${url})`, + buildPlaintext: (info, url) => `${info.name} - ${url}`, + }, + }, +} + +export default instagram diff --git a/src/content/sites/linkedin.js b/src/content/sites/linkedin.js new file mode 100644 index 0000000..4df2acf --- /dev/null +++ b/src/content/sites/linkedin.js @@ -0,0 +1,42 @@ +const linkedin = { + domain: 'linkedin.com', + prefix: '๐Ÿ’ผ', + pages: { + profile: { + urlPattern: /^https:\/\/www\.linkedin\.com\/in\/[^\/]+\/?$/, + buttonId: 'li-profile-copy-button', + getInfo: () => { + const name = document.querySelector('h1.text-heading-xlarge').textContent.trim() + const headline = document.querySelector('div.text-body-medium').textContent.trim() + return { name, headline } + }, + buildMarkdown: (info, url) => `[${info.name}](${url}) - ${info.headline}`, + buildPlaintext: (info, url) => `${info.name} - ${info.headline} - ${url}`, + }, + company: { + urlPattern: /^https:\/\/www\.linkedin\.com\/company\/[^\/]+\/?$/, + buttonId: 'li-company-copy-button', + getInfo: () => { + const name = document.querySelector('h1.org-top-card-summary__title').textContent.trim() + const about = document.querySelector('p.org-top-card-summary__tagline').textContent.trim() + return { name, about } + }, + buildMarkdown: (info, url) => `[${info.name}](${url}) - ${info.about}`, + buildPlaintext: (info, url) => `${info.name} - ${url} - ${info.about}`, + }, + pulse: { + urlPattern: /^https:\/\/www\.linkedin\.com\/pulse\/[^\/]+\/?$/, + buttonId: 'li-pulse-copy-button', + getInfo: () => { + const title = document.querySelector('h1.reader-article-header__title').textContent.trim() + const author = document.querySelector('div.reader-author-info__container h2').textContent.trim() + const date = document.querySelector('div.reader-author-info__container time').textContent.trim() + return { title, author, date } + }, + buildMarkdown: (info, url) => `[${info.title}](${url})\nBy ${info.author} | ${info.date}`, + buildPlaintext: (info, url) => `${info.title}\nBy ${info.author} | ${info.date}\n${url}`, + }, + }, +} + +export default linkedin diff --git a/src/content/sites/trello.js b/src/content/sites/trello.js new file mode 100644 index 0000000..96a4c2e --- /dev/null +++ b/src/content/sites/trello.js @@ -0,0 +1,30 @@ +const trello = { + domain: 'trello.com', + prefix: '๐Ÿ“‹', + pages: { + board: { + urlPattern: /^https:\/\/trello\.com\/b\/[a-zA-Z0-9]+(?:\/[^\/]+)?$/, + buttonId: 'trello-board-copy-button', + getInfo: () => { + const boardName = document.querySelector('h1[data-testid="board-name-display"]').textContent.trim() + return { boardName } + }, + buildMarkdown: (info, url) => `[${info.boardName}](${url})`, + buildPlaintext: (info, url) => `${info.boardName} - ${url}`, + }, + // TODO: Add card support + // card: { + // urlPattern: /^https:\/\/trello\.com\/c\/[a-zA-Z0-9]+(?:\/[^\/]+)?$/, + // buttonId: 'trello-card-copy-button', + // getInfo: () => { + // const cardName = document.querySelector('h2#js-dialog-title').textContent.trim() + // const boardName = document.querySelector('h1[data-testid="board-name-display"]').textContent.trim() + // return { cardName, boardName } + // }, + // buildMarkdown: (info, url) => `[${info.cardName}](${url}) (${info.boardName})`, + // buildPlaintext: (info, url) => `${info.cardName} (${info.boardName}) - ${url}`, + // }, + }, +} + +export default trello