Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions browser-extension/src/lib/enhancers/github/githubHighlighter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import hljs from 'highlight.js'

export function githubHighlighter(code: string, language: string) {
try {
if (language && hljs.getLanguage(language)) {
const result = hljs.highlight(code, { language })
return result.value
} else {
const result = hljs.highlightAuto(code)
return result.value
}
} catch (error) {
console.warn('highlight.js highlighting failed:', error)
return code
}
}
Original file line number Diff line number Diff line change
@@ -1,35 +1,22 @@
import hljs from 'highlight.js'
import { logger } from '../../lib/logger'
import OverType, { type OverTypeInstance } from '../../overtype/overtype'
import type { CommentEnhancer, CommentSpot } from '../enhancer'
import OverType, { type OverTypeInstance } from '../../../overtype/overtype'
import type { CommentEnhancer, CommentSpot } from '../../enhancer'
import { logger } from '../../logger'
import { githubHighlighter } from './githubHighlighter'
import { GITHUB_SPOT_TYPES, type GitHubSpotType } from './githubSpotTypes'

const GITHUB_SPOT_TYPES = [
'GH_PR_ADD_COMMENT',
/* TODO
'GH_ISSUE_NEW',
'GH_PR_NEW',
'GH_ISSUE_ADD_COMMENT',
'GH_ISSUE_EDIT_COMMENT',
'GH_PR_EDIT_COMMENT',
'GH_PR_CODE_COMMENT',
*/
] as const

export type GitHubSpotType = (typeof GITHUB_SPOT_TYPES)[number]

export interface GitHubAddCommentSpot extends CommentSpot {
interface GitHubPRAddCommentSpot extends CommentSpot {
type: GitHubSpotType // Override to narrow from string to specific union
domain: string
slug: string // owner/repo
number: number // issue/PR number, undefined for new issues and PRs
}

export class GitHubAddCommentEnhancer implements CommentEnhancer<GitHubAddCommentSpot> {
export class GitHubPRAddCommentEnhancer implements CommentEnhancer<GitHubPRAddCommentSpot> {
forSpotTypes(): string[] {
return [...GITHUB_SPOT_TYPES]
}

tryToEnhance(_textarea: HTMLTextAreaElement): GitHubAddCommentSpot | null {
tryToEnhance(_textarea: HTMLTextAreaElement): GitHubPRAddCommentSpot | null {
// Only handle github.com domains TODO: identify GitHub Enterprise somehow
if (window.location.hostname !== 'github.com') {
return null
Expand All @@ -55,10 +42,10 @@ export class GitHubAddCommentEnhancer implements CommentEnhancer<GitHubAddCommen
}

prepareForFirstEnhancement(): void {
OverType.setCodeHighlighter(hljsHighlighter)
OverType.setCodeHighlighter(githubHighlighter)
}

enhance(textArea: HTMLTextAreaElement, _spot: GitHubAddCommentSpot): OverTypeInstance {
enhance(textArea: HTMLTextAreaElement, _spot: GitHubPRAddCommentSpot): OverTypeInstance {
const overtypeContainer = this.modifyDOM(textArea)
return new OverType(overtypeContainer, {
autoResize: true,
Expand All @@ -81,31 +68,16 @@ export class GitHubAddCommentEnhancer implements CommentEnhancer<GitHubAddCommen
return overtypeContainer.parentElement!.closest('div')!
}

tableTitle(spot: GitHubAddCommentSpot): string {
tableTitle(spot: GitHubPRAddCommentSpot): string {
const { slug, number } = spot
return `${slug} PR #${number}`
}

tableIcon(_: GitHubAddCommentSpot): string {
tableIcon(_: GitHubPRAddCommentSpot): string {
return '🔄' // PR icon TODO: icon urls in /public
}

buildUrl(spot: GitHubAddCommentSpot): string {
buildUrl(spot: GitHubPRAddCommentSpot): string {
return `https://${spot.domain}/${spot.slug}/pull/${spot.number}`
}
}

function hljsHighlighter(code: string, language: string) {
try {
if (language && hljs.getLanguage(language)) {
const result = hljs.highlight(code, { language })
return result.value
} else {
const result = hljs.highlightAuto(code)
return result.value
}
} catch (error) {
console.warn('highlight.js highlighting failed:', error)
return code
}
}
13 changes: 13 additions & 0 deletions browser-extension/src/lib/enhancers/github/githubSpotTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export const GITHUB_SPOT_TYPES = [
'GH_PR_ADD_COMMENT',
/* TODO
'GH_ISSUE_NEW',
'GH_PR_NEW',
'GH_ISSUE_ADD_COMMENT',
'GH_ISSUE_EDIT_COMMENT',
'GH_PR_EDIT_COMMENT',
'GH_PR_CODE_COMMENT',
*/
] as const

export type GitHubSpotType = (typeof GITHUB_SPOT_TYPES)[number]
4 changes: 2 additions & 2 deletions browser-extension/src/lib/registries.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { OverTypeInstance } from '../overtype/overtype'
import type { CommentEnhancer, CommentSpot } from './enhancer'
import { GitHubAddCommentEnhancer } from './enhancers/github'
import { GitHubPRAddCommentEnhancer } from './enhancers/github/githubPRAddComment'

export interface EnhancedTextarea<T extends CommentSpot = CommentSpot> {
textarea: HTMLTextAreaElement
Expand All @@ -15,7 +15,7 @@ export class EnhancerRegistry {

constructor() {
// Register all available handlers
this.register(new GitHubAddCommentEnhancer())
this.register(new GitHubPRAddCommentEnhancer())
}

private register<T extends CommentSpot>(handler: CommentEnhancer<T>): void {
Expand Down
66 changes: 32 additions & 34 deletions browser-extension/src/playgrounds/github-playground.ts
Original file line number Diff line number Diff line change
@@ -1,49 +1,47 @@
import hljs from "highlight.js";
import OverType from "../overtype/overtype";
import hljs from 'highlight.js'
import OverType from '../overtype/overtype'

export function githubPrNewCommentContentScript() {
if (window.location.hostname !== "github.com") {
return;
}
OverType.setCodeHighlighter(hljsHighlighter);
const ghCommentBox = document.getElementById(
"new_comment_field"
) as HTMLTextAreaElement | null;
if (ghCommentBox) {
const overtypeContainer = modifyDOM(ghCommentBox);
new OverType(overtypeContainer, {
placeholder: "Add your comment here...",
autoResize: true,
minHeight: "102px",
padding: "var(--base-size-8)",
});
}
if (window.location.hostname !== 'github.com') {
return
}
OverType.setCodeHighlighter(hljsHighlighter)
const ghCommentBox = document.getElementById('new_comment_field') as HTMLTextAreaElement | null
if (ghCommentBox) {
const overtypeContainer = modifyDOM(ghCommentBox)
new OverType(overtypeContainer, {
autoResize: true,
minHeight: '102px',
padding: 'var(--base-size-8)',
placeholder: 'Add your comment here...',
})
}
}

function modifyDOM(overtypeInput: HTMLTextAreaElement): HTMLElement {
overtypeInput.classList.add("overtype-input");
const overtypePreview = document.createElement("div");
overtypePreview.classList.add("overtype-preview");
overtypeInput.insertAdjacentElement("afterend", overtypePreview);
const overtypeWrapper = overtypeInput.parentElement!.closest("div")!;
overtypeWrapper.classList.add("overtype-wrapper");
overtypeInput.placeholder = "Add your comment here...";
const overtypeContainer = overtypeWrapper.parentElement!.closest("div")!;
overtypeContainer.classList.add("overtype-container");
return overtypeContainer.parentElement!.closest("div")!;
overtypeInput.classList.add('overtype-input')
const overtypePreview = document.createElement('div')
overtypePreview.classList.add('overtype-preview')
overtypeInput.insertAdjacentElement('afterend', overtypePreview)
const overtypeWrapper = overtypeInput.parentElement!.closest('div')!
overtypeWrapper.classList.add('overtype-wrapper')
overtypeInput.placeholder = 'Add your comment here...'
const overtypeContainer = overtypeWrapper.parentElement!.closest('div')!
overtypeContainer.classList.add('overtype-container')
return overtypeContainer.parentElement!.closest('div')!
}

function hljsHighlighter(code: string, language: string) {
try {
if (language && hljs.getLanguage(language)) {
const result = hljs.highlight(code, { language });
return result.value;
const result = hljs.highlight(code, { language })
return result.value
} else {
const result = hljs.highlightAuto(code);
return result.value;
const result = hljs.highlightAuto(code)
return result.value
}
} catch (error) {
console.warn("highlight.js highlighting failed:", error);
return code;
console.warn('highlight.js highlighting failed:', error)
return code
}
}