From 1224ba43327e6dbaf1bf0a06b5354418888f3f78 Mon Sep 17 00:00:00 2001 From: Todd Riley Date: Fri, 5 Sep 2025 14:50:43 -0400 Subject: [PATCH 1/6] Add github-issue add-comment enhancer. --- .../enhancers/github/githubIssueAddComment.ts | 69 +++++++++++++++++++ .../enhancers/github/githubPRAddComment.ts | 21 ++---- .../lib/enhancers/github/githubSpotTypes.ts | 2 +- .../src/lib/enhancers/modifyDOM.ts | 13 ++++ browser-extension/src/lib/registries.ts | 2 + browser-extension/src/overtype/styles.js | 30 ++++---- 6 files changed, 105 insertions(+), 32 deletions(-) create mode 100644 browser-extension/src/lib/enhancers/github/githubIssueAddComment.ts create mode 100644 browser-extension/src/lib/enhancers/modifyDOM.ts diff --git a/browser-extension/src/lib/enhancers/github/githubIssueAddComment.ts b/browser-extension/src/lib/enhancers/github/githubIssueAddComment.ts new file mode 100644 index 0000000..5257722 --- /dev/null +++ b/browser-extension/src/lib/enhancers/github/githubIssueAddComment.ts @@ -0,0 +1,69 @@ +import OverType, { type OverTypeInstance } from '../../../overtype/overtype' +import type { CommentEnhancer, CommentSpot } from '../../enhancer' +import { logger } from '../../logger' +import { modifyDOM } from '../modifyDOM' +import { githubHighlighter } from './githubHighlighter' + +interface GitHubIssueAddCommentSpot extends CommentSpot { + type: 'GH_ISSUE_ADD_COMMENT' + domain: string + slug: string // owner/repo + number: number // issue number, undefined for new issues +} + +export class GitHubIssueAddCommentEnhancer implements CommentEnhancer { + forSpotTypes(): string[] { + return ['GH_ISSUE_ADD_COMMENT'] + } + + tryToEnhance(_textarea: HTMLTextAreaElement): GitHubIssueAddCommentSpot | null { + if (window.location.hostname !== 'github.com') { + return null + } + + // Parse GitHub URL structure: /owner/repo/issues/123 or /owner/repo/pull/456 + logger.debug(`${this.constructor.name} examing url`, window.location.pathname) + + const match = window.location.pathname.match(/^\/([^/]+)\/([^/]+)(?:\/issues\/(\d+))/) + logger.debug(`${this.constructor.name} found match`, window.location.pathname) + if (!match) return null + const [, owner, repo, numberStr] = match + const slug = `${owner}/${repo}` + const number = parseInt(numberStr!, 10) + const unique_key = `github.com:${slug}:${number}` + return { + domain: 'github.com', + number, + slug, + type: 'GH_ISSUE_ADD_COMMENT', + unique_key, + } + } + + prepareForFirstEnhancement(): void { + OverType.setCodeHighlighter(githubHighlighter) + } + + enhance(textArea: HTMLTextAreaElement, _spot: GitHubIssueAddCommentSpot): OverTypeInstance { + const overtypeContainer = modifyDOM(textArea) + return new OverType(overtypeContainer, { + autoResize: true, + minHeight: '100px', + padding: 'var(--base-size-16)', + placeholder: 'Add your comment here...', + })[0]! + } + + tableTitle(spot: GitHubIssueAddCommentSpot): string { + const { slug, number } = spot + return `${slug} Issue #${number}` + } + + tableIcon(_: GitHubIssueAddCommentSpot): string { + return '🔄' // PR icon TODO: icon urls in /public + } + + buildUrl(spot: GitHubIssueAddCommentSpot): string { + return `https://${spot.domain}/${spot.slug}/issue/${spot.number}` + } +} diff --git a/browser-extension/src/lib/enhancers/github/githubPRAddComment.ts b/browser-extension/src/lib/enhancers/github/githubPRAddComment.ts index 13aa81d..1f99e5b 100644 --- a/browser-extension/src/lib/enhancers/github/githubPRAddComment.ts +++ b/browser-extension/src/lib/enhancers/github/githubPRAddComment.ts @@ -1,11 +1,11 @@ import OverType, { type OverTypeInstance } from '../../../overtype/overtype' import type { CommentEnhancer, CommentSpot } from '../../enhancer' import { logger } from '../../logger' +import { modifyDOM } from '../modifyDOM' import { githubHighlighter } from './githubHighlighter' -import { GITHUB_SPOT_TYPES, type GitHubSpotType } from './githubSpotTypes' interface GitHubPRAddCommentSpot extends CommentSpot { - type: GitHubSpotType // Override to narrow from string to specific union + type: 'GH_PR_ADD_COMMENT' // 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 @@ -13,7 +13,7 @@ interface GitHubPRAddCommentSpot extends CommentSpot { export class GitHubPRAddCommentEnhancer implements CommentEnhancer { forSpotTypes(): string[] { - return [...GITHUB_SPOT_TYPES] + return ['GH_PR_ADD_COMMENT'] } tryToEnhance(_textarea: HTMLTextAreaElement): GitHubPRAddCommentSpot | null { @@ -46,7 +46,7 @@ export class GitHubPRAddCommentEnhancer implements CommentEnhancer { @@ -15,6 +16,7 @@ export class EnhancerRegistry { constructor() { // Register all available handlers + this.register(new GitHubIssueAddCommentEnhancer()) this.register(new GitHubPRAddCommentEnhancer()) } diff --git a/browser-extension/src/overtype/styles.js b/browser-extension/src/overtype/styles.js index a3d0ebb..0ebac38 100644 --- a/browser-extension/src/overtype/styles.js +++ b/browser-extension/src/overtype/styles.js @@ -3,7 +3,7 @@ * Embedded in JavaScript to ensure single-file distribution */ -import { themeToCSSVars } from "./themes.js"; +import { themeToCSSVars } from './themes.js' /** * Generate the complete CSS for the editor @@ -12,17 +12,17 @@ import { themeToCSSVars } from "./themes.js"; */ export function generateStyles(options = {}) { let { - fontSize = "14px", + fontSize = '14px', lineHeight = 1.6, /* System-first, guaranteed monospaced; avoids Android 'ui-monospace' pitfalls */ fontFamily = '"SF Mono", SFMono-Regular, Menlo, Monaco, "Cascadia Code", Consolas, "Roboto Mono", "Noto Sans Mono", "Droid Sans Mono", "Ubuntu Mono", "DejaVu Sans Mono", "Liberation Mono", "Courier New", Courier, monospace', - padding = "20px", + padding = '20px', theme = null, mobile = {}, - } = options; + } = options - fontFamily = "inherit"; - fontSize = "var(--text-body-size-medium)"; + fontFamily = 'inherit' + fontSize = 'var(--text-body-size-medium)' // Generate mobile overrides const mobileStyles = @@ -33,17 +33,17 @@ export function generateStyles(options = {}) { .overtype-wrapper .overtype-preview { ${Object.entries(mobile) .map(([prop, val]) => { - const cssProp = prop.replace(/([A-Z])/g, "-$1").toLowerCase(); - return `${cssProp}: ${val} !important;`; + const cssProp = prop.replace(/([A-Z])/g, '-$1').toLowerCase() + return `${cssProp}: ${val} !important;` }) - .join("\n ")} + .join('\n ')} } } ` - : ""; + : '' // Generate theme variables if provided - const themeVars = theme && theme.colors ? themeToCSSVars(theme.colors) : ""; + const themeVars = theme && theme.colors ? themeToCSSVars(theme.colors) : '' return ` /* OverType Editor Styles */ @@ -54,7 +54,9 @@ export function generateStyles(options = {}) { } /* Middle-ground CSS Reset - Prevent parent styles from leaking in */ - .overtype-container * { + .overtype-container .overtype-wrapper, + .overtype-container .overtype-input, + .overtype-container .overtype-preview { /* Box model - these commonly leak */ /* margin: 0 !important; */ padding: 0 !important; @@ -96,7 +98,7 @@ export function generateStyles(options = {}) { ? ` /* Theme Variables */ ${themeVars}` - : "" + : '' } } @@ -820,5 +822,5 @@ export function generateStyles(options = {}) { } ${mobileStyles} - `; + ` } From 1582d5f1d32721e7fd1d9d031ec47a5eccd7ab96 Mon Sep 17 00:00:00 2001 From: Todd Riley Date: Fri, 5 Sep 2025 14:58:58 -0400 Subject: [PATCH 2/6] Only enhance textareas with the correct id. --- .../src/lib/enhancers/github/githubIssueAddComment.ts | 4 ++-- .../src/lib/enhancers/github/githubPRAddComment.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/browser-extension/src/lib/enhancers/github/githubIssueAddComment.ts b/browser-extension/src/lib/enhancers/github/githubIssueAddComment.ts index 5257722..8a81b66 100644 --- a/browser-extension/src/lib/enhancers/github/githubIssueAddComment.ts +++ b/browser-extension/src/lib/enhancers/github/githubIssueAddComment.ts @@ -17,7 +17,7 @@ export class GitHubIssueAddCommentEnhancer implements CommentEnhancer Date: Fri, 5 Sep 2025 22:39:05 -0700 Subject: [PATCH 3/6] reduce `styles.js` diff --- browser-extension/src/overtype/styles.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/browser-extension/src/overtype/styles.js b/browser-extension/src/overtype/styles.js index 0ebac38..6ffb10e 100644 --- a/browser-extension/src/overtype/styles.js +++ b/browser-extension/src/overtype/styles.js @@ -3,7 +3,7 @@ * Embedded in JavaScript to ensure single-file distribution */ -import { themeToCSSVars } from './themes.js' +import { themeToCSSVars } from "./themes.js" /** * Generate the complete CSS for the editor @@ -12,17 +12,17 @@ import { themeToCSSVars } from './themes.js' */ export function generateStyles(options = {}) { let { - fontSize = '14px', + fontSize = "14px", lineHeight = 1.6, /* System-first, guaranteed monospaced; avoids Android 'ui-monospace' pitfalls */ fontFamily = '"SF Mono", SFMono-Regular, Menlo, Monaco, "Cascadia Code", Consolas, "Roboto Mono", "Noto Sans Mono", "Droid Sans Mono", "Ubuntu Mono", "DejaVu Sans Mono", "Liberation Mono", "Courier New", Courier, monospace', - padding = '20px', + padding = "20px", theme = null, mobile = {}, } = options - fontFamily = 'inherit' - fontSize = 'var(--text-body-size-medium)' + fontFamily = "inherit" + fontSize = "var(--text-body-size-medium)" // Generate mobile overrides const mobileStyles = @@ -33,17 +33,17 @@ export function generateStyles(options = {}) { .overtype-wrapper .overtype-preview { ${Object.entries(mobile) .map(([prop, val]) => { - const cssProp = prop.replace(/([A-Z])/g, '-$1').toLowerCase() + const cssProp = prop.replace(/([A-Z])/g, "-$1").toLowerCase() return `${cssProp}: ${val} !important;` }) - .join('\n ')} + .join("\n ")} } } ` - : '' + : "" // Generate theme variables if provided - const themeVars = theme && theme.colors ? themeToCSSVars(theme.colors) : '' + const themeVars = theme && theme.colors ? themeToCSSVars(theme.colors) : "" return ` /* OverType Editor Styles */ From 969c5fc56449dc3cee86a4d4c4121021f681604b Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Fri, 5 Sep 2025 22:40:51 -0700 Subject: [PATCH 4/6] more diff minimization --- browser-extension/src/overtype/styles.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/browser-extension/src/overtype/styles.js b/browser-extension/src/overtype/styles.js index 6ffb10e..df5d303 100644 --- a/browser-extension/src/overtype/styles.js +++ b/browser-extension/src/overtype/styles.js @@ -98,7 +98,7 @@ export function generateStyles(options = {}) { ? ` /* Theme Variables */ ${themeVars}` - : '' + : "" } } @@ -822,5 +822,5 @@ export function generateStyles(options = {}) { } ${mobileStyles} - ` + `; } From e48c94e53ca81b48eb7dc3d8f4f2736c588f7640 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Fri, 5 Sep 2025 22:43:43 -0700 Subject: [PATCH 5/6] more diff minimization --- browser-extension/src/overtype/styles.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/browser-extension/src/overtype/styles.js b/browser-extension/src/overtype/styles.js index df5d303..9c5b861 100644 --- a/browser-extension/src/overtype/styles.js +++ b/browser-extension/src/overtype/styles.js @@ -3,7 +3,7 @@ * Embedded in JavaScript to ensure single-file distribution */ -import { themeToCSSVars } from "./themes.js" +import { themeToCSSVars } from "./themes.js"; /** * Generate the complete CSS for the editor @@ -19,10 +19,10 @@ export function generateStyles(options = {}) { padding = "20px", theme = null, mobile = {}, - } = options + } = options; fontFamily = "inherit" - fontSize = "var(--text-body-size-medium)" + fontSize = "var(--text-body-size-medium)"; // Generate mobile overrides const mobileStyles = @@ -34,16 +34,16 @@ export function generateStyles(options = {}) { ${Object.entries(mobile) .map(([prop, val]) => { const cssProp = prop.replace(/([A-Z])/g, "-$1").toLowerCase() - return `${cssProp}: ${val} !important;` + return `${cssProp}: ${val} !important;`; }) .join("\n ")} } } ` - : "" + : ""; // Generate theme variables if provided - const themeVars = theme && theme.colors ? themeToCSSVars(theme.colors) : "" + const themeVars = theme && theme.colors ? themeToCSSVars(theme.colors) : ""; return ` /* OverType Editor Styles */ From 50daae09e0170f7960bde9d39f78a6b02d4d84f0 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Fri, 5 Sep 2025 22:44:28 -0700 Subject: [PATCH 6/6] more diff minimization --- browser-extension/src/overtype/styles.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/browser-extension/src/overtype/styles.js b/browser-extension/src/overtype/styles.js index 9c5b861..fcdb976 100644 --- a/browser-extension/src/overtype/styles.js +++ b/browser-extension/src/overtype/styles.js @@ -21,7 +21,7 @@ export function generateStyles(options = {}) { mobile = {}, } = options; - fontFamily = "inherit" + fontFamily = "inherit"; fontSize = "var(--text-body-size-medium)"; // Generate mobile overrides @@ -33,7 +33,7 @@ export function generateStyles(options = {}) { .overtype-wrapper .overtype-preview { ${Object.entries(mobile) .map(([prop, val]) => { - const cssProp = prop.replace(/([A-Z])/g, "-$1").toLowerCase() + const cssProp = prop.replace(/([A-Z])/g, "-$1").toLowerCase(); return `${cssProp}: ${val} !important;`; }) .join("\n ")}