Skip to content

Commit b49f29d

Browse files
committed
Merge branch 'main' into feat/testing-take-2
2 parents 1a3f58c + 4d38467 commit b49f29d

File tree

9 files changed

+226
-148
lines changed

9 files changed

+226
-148
lines changed

browser-extension/src/lib/enhancers/github.ts

Lines changed: 0 additions & 111 deletions
This file was deleted.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import hljs from 'highlight.js'
2+
3+
export function githubHighlighter(code: string, language: string) {
4+
try {
5+
if (language && hljs.getLanguage(language)) {
6+
const result = hljs.highlight(code, { language })
7+
return result.value
8+
} else {
9+
const result = hljs.highlightAuto(code)
10+
return result.value
11+
}
12+
} catch (error) {
13+
console.warn('highlight.js highlighting failed:', error)
14+
return code
15+
}
16+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import OverType, { type OverTypeInstance } from '../../../overtype/overtype'
2+
import type { CommentEnhancer, CommentSpot } from '../../enhancer'
3+
import { logger } from '../../logger'
4+
import { modifyDOM } from '../modifyDOM'
5+
import { githubHighlighter } from './githubHighlighter'
6+
7+
interface GitHubIssueAddCommentSpot extends CommentSpot {
8+
type: 'GH_ISSUE_ADD_COMMENT'
9+
domain: string
10+
slug: string // owner/repo
11+
number: number // issue number, undefined for new issues
12+
}
13+
14+
export class GitHubIssueAddCommentEnhancer implements CommentEnhancer<GitHubIssueAddCommentSpot> {
15+
forSpotTypes(): string[] {
16+
return ['GH_ISSUE_ADD_COMMENT']
17+
}
18+
19+
tryToEnhance(textarea: HTMLTextAreaElement): GitHubIssueAddCommentSpot | null {
20+
if (
21+
document.querySelector('meta[name="hostname"]')?.getAttribute('content') !== 'github.com' ||
22+
textarea.id !== ':r2v:'
23+
) {
24+
return null
25+
}
26+
27+
// Parse GitHub URL structure: /owner/repo/issues/123 or /owner/repo/pull/456
28+
logger.debug(`${this.constructor.name} examing url`, window.location.pathname)
29+
30+
const match = window.location.pathname.match(/^\/([^/]+)\/([^/]+)(?:\/issues\/(\d+))/)
31+
logger.debug(`${this.constructor.name} found match`, window.location.pathname)
32+
if (!match) return null
33+
const [, owner, repo, numberStr] = match
34+
const slug = `${owner}/${repo}`
35+
const number = parseInt(numberStr!, 10)
36+
const unique_key = `github.com:${slug}:${number}`
37+
return {
38+
domain: 'github.com',
39+
number,
40+
slug,
41+
type: 'GH_ISSUE_ADD_COMMENT',
42+
unique_key,
43+
}
44+
}
45+
46+
prepareForFirstEnhancement(): void {
47+
OverType.setCodeHighlighter(githubHighlighter)
48+
}
49+
50+
enhance(textArea: HTMLTextAreaElement, _spot: GitHubIssueAddCommentSpot): OverTypeInstance {
51+
const overtypeContainer = modifyDOM(textArea)
52+
return new OverType(overtypeContainer, {
53+
autoResize: true,
54+
minHeight: '100px',
55+
padding: 'var(--base-size-16)',
56+
placeholder: 'Use Markdown to format your comment',
57+
})[0]!
58+
}
59+
60+
tableTitle(spot: GitHubIssueAddCommentSpot): string {
61+
const { slug, number } = spot
62+
return `${slug} Issue #${number}`
63+
}
64+
65+
tableIcon(_: GitHubIssueAddCommentSpot): string {
66+
return '🔄' // PR icon TODO: icon urls in /public
67+
}
68+
69+
buildUrl(spot: GitHubIssueAddCommentSpot): string {
70+
return `https://${spot.domain}/${spot.slug}/issue/${spot.number}`
71+
}
72+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import OverType, { type OverTypeInstance } from '../../../overtype/overtype'
2+
import type { CommentEnhancer, CommentSpot } from '../../enhancer'
3+
import { logger } from '../../logger'
4+
import { modifyDOM } from '../modifyDOM'
5+
import { githubHighlighter } from './githubHighlighter'
6+
7+
interface GitHubPRAddCommentSpot extends CommentSpot {
8+
type: 'GH_PR_ADD_COMMENT' // Override to narrow from string to specific union
9+
domain: string
10+
slug: string // owner/repo
11+
number: number // issue/PR number, undefined for new issues and PRs
12+
}
13+
14+
export class GitHubPRAddCommentEnhancer implements CommentEnhancer<GitHubPRAddCommentSpot> {
15+
forSpotTypes(): string[] {
16+
return ['GH_PR_ADD_COMMENT']
17+
}
18+
19+
tryToEnhance(_textarea: HTMLTextAreaElement): GitHubPRAddCommentSpot | null {
20+
// Only handle github.com domains TODO: identify GitHub Enterprise somehow
21+
if (
22+
document.querySelector('meta[name="hostname"]')?.getAttribute('content') !== 'github.com' ||
23+
_textarea.id !== 'new_comment_field'
24+
) {
25+
return null
26+
}
27+
28+
// Parse GitHub URL structure: /owner/repo/issues/123 or /owner/repo/pull/456
29+
logger.debug(`${this.constructor.name} examing url`, window.location.pathname)
30+
31+
const match = window.location.pathname.match(/^\/([^/]+)\/([^/]+)(?:\/pull\/(\d+))/)
32+
logger.debug(`${this.constructor.name} found match`, window.location.pathname)
33+
if (!match) return null
34+
const [, owner, repo, numberStr] = match
35+
const slug = `${owner}/${repo}`
36+
const number = parseInt(numberStr!, 10)
37+
const unique_key = `github.com:${slug}:${number}`
38+
return {
39+
domain: 'github.com',
40+
number,
41+
slug,
42+
type: 'GH_PR_ADD_COMMENT',
43+
unique_key,
44+
}
45+
}
46+
47+
prepareForFirstEnhancement(): void {
48+
OverType.setCodeHighlighter(githubHighlighter)
49+
}
50+
51+
enhance(textArea: HTMLTextAreaElement, _spot: GitHubPRAddCommentSpot): OverTypeInstance {
52+
const overtypeContainer = modifyDOM(textArea)
53+
return new OverType(overtypeContainer, {
54+
autoResize: true,
55+
minHeight: '102px',
56+
padding: 'var(--base-size-8)',
57+
placeholder: 'Add your comment here...',
58+
})[0]!
59+
}
60+
61+
tableTitle(spot: GitHubPRAddCommentSpot): string {
62+
const { slug, number } = spot
63+
return `${slug} PR #${number}`
64+
}
65+
66+
tableIcon(_: GitHubPRAddCommentSpot): string {
67+
return '🔄' // PR icon TODO: icon urls in /public
68+
}
69+
70+
buildUrl(spot: GitHubPRAddCommentSpot): string {
71+
return `https://${spot.domain}/${spot.slug}/pull/${spot.number}`
72+
}
73+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export const GITHUB_SPOT_TYPES = [
2+
'GH_PR_ADD_COMMENT',
3+
'GH_ISSUE_ADD_COMMENT',
4+
/* TODO
5+
'GH_ISSUE_NEW',
6+
'GH_PR_NEW',
7+
'GH_ISSUE_EDIT_COMMENT',
8+
'GH_PR_EDIT_COMMENT',
9+
'GH_PR_CODE_COMMENT',
10+
*/
11+
] as const
12+
13+
export type GitHubSpotType = (typeof GITHUB_SPOT_TYPES)[number]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Modify the DOM to trick overtype into adopting it instead of recreating it
2+
export function modifyDOM(overtypeInput: HTMLTextAreaElement): HTMLElement {
3+
overtypeInput.classList.add('overtype-input')
4+
const overtypePreview = document.createElement('div')
5+
overtypePreview.classList.add('overtype-preview')
6+
overtypeInput.insertAdjacentElement('afterend', overtypePreview)
7+
const overtypeWrapper = overtypeInput.parentElement!.closest('div')!
8+
overtypeWrapper.classList.add('overtype-wrapper')
9+
overtypeInput.placeholder = 'Add your comment here...'
10+
const overtypeContainer = overtypeWrapper.parentElement!.closest('div')!
11+
overtypeContainer.classList.add('overtype-container')
12+
return overtypeContainer.parentElement!.closest('div')!
13+
}

browser-extension/src/lib/registries.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { OverTypeInstance } from '../overtype/overtype'
22
import type { CommentEnhancer, CommentSpot } from './enhancer'
3-
import { GitHubAddCommentEnhancer } from './enhancers/github'
3+
import { GitHubIssueAddCommentEnhancer } from './enhancers/github/githubIssueAddComment'
4+
import { GitHubPRAddCommentEnhancer } from './enhancers/github/githubPRAddComment'
45

56
export interface EnhancedTextarea<T extends CommentSpot = CommentSpot> {
67
textarea: HTMLTextAreaElement
@@ -15,7 +16,8 @@ export class EnhancerRegistry {
1516

1617
constructor() {
1718
// Register all available handlers
18-
this.register(new GitHubAddCommentEnhancer())
19+
this.register(new GitHubIssueAddCommentEnhancer())
20+
this.register(new GitHubPRAddCommentEnhancer())
1921
}
2022

2123
private register<T extends CommentSpot>(handler: CommentEnhancer<T>): void {

browser-extension/src/overtype/styles.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ export function generateStyles(options = {}) {
5454
}
5555
5656
/* Middle-ground CSS Reset - Prevent parent styles from leaking in */
57-
.overtype-container * {
57+
.overtype-container .overtype-wrapper,
58+
.overtype-container .overtype-input,
59+
.overtype-container .overtype-preview {
5860
/* Box model - these commonly leak */
5961
/* margin: 0 !important; */
6062
padding: 0 !important;

0 commit comments

Comments
 (0)