Skip to content

Commit

Permalink
fix: fixed branch type match, likes fix/test
Browse files Browse the repository at this point in the history
  • Loading branch information
axiaoan committed Apr 21, 2022
1 parent 1d12399 commit ff756ae
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 51 deletions.
12 changes: 10 additions & 2 deletions shim.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,20 @@ declare module 'webext-bridge' {
// see https://github.com/antfu/webext-bridge#type-safe-protocols
'tab-prev': { title: string | undefined }
'get-current-tab': ProtocolWithReturn<{ tabId: number }, { title?: string }>
'modify-pages-changed': { source: string; host: string }
'update-element': { status: boolean; source?: string; host?: string }
'modify-pages-changed': { source: string }
'update-element': { status: boolean; source?: string }
'copy-source': { source: string }
'get-source': ProtocolWithReturn<{}, string | undefined>
}
}

export interface Source {
name: string
repo: string
branch?: string
directory?: string
}

export interface BuildCliOptions {
/**
* Target platform
Expand Down
55 changes: 8 additions & 47 deletions src/background/main.ts
Original file line number Diff line number Diff line change
@@ -1,52 +1,34 @@
import { sendMessage } from 'webext-bridge'
import { log } from '~/logic'

const hosts = ['github.com']
const pathRules = [
// Project root
/^\/(?<name>[^\/]*)\/(?<repo>[^\/]*)$/,
// Subdirectory
/^\/(?<name>[^\/]*)\/(?<repo>[^\/]*)\/tree\/(?<branch>[^\/]*)(\/(?<directory>.*))?$/,
]
const getHostName = (hostname: string) => hosts.find(h => h === hostname)
const getRules = (pathname: string) => {
for (const rule of pathRules) {
const match = pathname.match(rule)
if (match)
return match.groups
}
return null
}

browser.runtime.onConnect.addListener(async() => {
const commands = await browser.commands.getAll()
const copyPathShortcut = commands.find(c => c.name === 'copy-path')
if (copyPathShortcut)
await browser.storage.local.set({ shortcut: copyPathShortcut.shortcut })
})

browser.tabs.onUpdated.addListener(async(tabId, changeInfo, { url }) => {
browser.tabs.onUpdated.addListener(async(tabId, changeInfo) => {
const { 'show-element': showElement } = await browser.storage.local.get('show-element')
if (changeInfo.status === 'complete' && showElement) {
const { host, source } = getSource(url as string)
const source = await getSource(tabId)
if (!source)
return
sendMessage('modify-pages-changed', { source, host }, { context: 'content-script', tabId })
sendMessage('modify-pages-changed', { source }, { context: 'content-script', tabId })
}
})

browser.storage.onChanged.addListener(async(changes: Record<string, any>) => {
for (const [key, { newValue }] of Object.entries(changes)) {
if (key === 'show-element') {
const tabs = await getAllTabs()
tabs.forEach((tab) => {
tabs.forEach(async(tab) => {
const data: any = { status: newValue }
if (newValue) {
const { host, source } = getSource(tab.url as string)
const source = await getSource(tab.id as number)
if (!source)
return
data.source = source
data.host = host
}
sendMessage('update-element', data, { context: 'content-script', tabId: tab.id as number })
})
Expand All @@ -61,37 +43,16 @@ browser.commands.onCommand.addListener(async(command) => {
if (!tab.length)
return

const { source } = getSource(tab[0].url as string)
const source = await getSource(tab[0].id as number)
if (!source)
return
log(source)
sendMessage('copy-source', { source }, { context: 'content-script', tabId: tab[0].id as number })
}
})

// Get the current tab source for `degit` command
function getSource(url: string) {
try {
const { hostname, pathname } = new URL(url as string)
const host = getHostName(hostname)
const match = getRules(pathname)
if (!host || !match)
return { host: null, source: null }

const { name, repo, directory, branch } = match
let source = `npx degit ${name}/${repo}`
if (directory)
source += `/${directory}`

if (branch && branch !== 'master')
source += `#${branch}`

return { source, host }
}
catch (e) {
console.error(e)
return { host: null, source: null }
}
async function getSource(tabId: number) {
return await sendMessage('get-source', {}, { context: 'content-script', tabId })
}

// Get all valid tabs
Expand Down
68 changes: 66 additions & 2 deletions src/contentScripts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,28 @@
import { onMessage } from 'webext-bridge'
import { createApp } from 'vue'
import { useClipboard } from '@vueuse/core'
import type { Source } from 'shim'
import { green } from 'kolorist'
import Github from './views/Github.vue'
import { log } from '~/logic'

const hosts = ['github.com']
const allowPathReg = [
// Github repository root
/^\/[^/]*\/[^/]*\/?$/,
// Github repository Subdirectory
/^\/[^/]*\/[^/]*\/tree\/[^/]*(\/.*)?$/,
]

const validHost = () => hosts.includes(location.hostname)
const validPath = () => allowPathReg.some(reg => location.pathname.match(reg))

// Firefox `browser.tabs.executeScript()` requires scripts return a primitive value
(() => {
;(() => {
log('Setup from content script')

onMessage('modify-pages-changed', ({ data }) => {
log(`Modify pages changed: [${data.source}]`)
log(`Modify pages changed: [${green(data.source)}]`)
renderGithubButton(data.source)
})

Expand All @@ -24,11 +37,25 @@ import { log } from '~/logic'
})

onMessage('copy-source', ({ data }) => {
log('copy-source')
log(data)
if (!data.source)
return
const { copy } = useClipboard({ source: data.source })
copy()
})

onMessage('get-source', () => {
log('get-source')
if (!validHost() || !validPath())
return
const source: Source | undefined = getGithubSource()
if (!source)
return
const directoryText: string | undefined = (<HTMLElement>document.querySelector('.flex-self-center')).innerText
const dirMatch = validDirectory(directoryText)
return renderSource(Object.assign(source, dirMatch))
})
})()

function renderGithubButton(source: string) {
Expand Down Expand Up @@ -60,3 +87,40 @@ function removeCopyEl(container = document) {
const el = container.querySelector('.webext-degit')
el && el.remove()
}

function validDirectory(dir: string) {
const match = dir.match(/^[^/]*\/(?<directory>.*\/)$/)
return match?.groups
}

/**
* If this repo path is root, use `pathname` to resolved
* If this repo path is subdirectory, use selector `.js-repo-root a` to resolved
* @returns {Source}
*/
function getGithubSource(): Source | undefined {
const subUrl = (<HTMLAnchorElement>document.querySelector('.js-repo-root a'))?.href
if (subUrl) {
const reg = /^https?:\/\/github\.com\/(?<name>[^/]*)\/(?<repo>[^/]*)(\/tree\/(?<branch>.*))?$/
// @ts-expect-error Fix { [key: string]: string; } | undefined
return subUrl.match(reg)?.groups
}
else {
const reg = /^\/(?<name>[^/]*)\/(?<repo>[^/]*)(\/tree\/(?<branch>.*))?\/?$/
// @ts-expect-error Fix { [key: string]: string; } | undefined
return location.pathname.match(reg)?.groups
}
}

function renderSource(source: Source) {
const { name, repo, directory, branch } = source
let text = `npx degit ${name}/${repo}`

if (directory)
text += `/${directory}`

if (branch && branch !== 'master')
text += `#${branch}`

return text.trim()
}

0 comments on commit ff756ae

Please sign in to comment.