Skip to content

Commit 3883abe

Browse files
author
ntwigg
committed
First cut.
1 parent 85ec3b9 commit 3883abe

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
export type CommentType =
2+
| 'GH_ISSUE_NEW'
3+
| 'GH_PR_NEW'
4+
| 'GH_ISSUE_ADD_COMMENT'
5+
| 'GH_ISSUE_EDIT_COMMENT'
6+
| 'GH_PR_ADD_COMMENT'
7+
| 'GH_PR_EDIT_COMMENT'
8+
| 'GH_PR_CODE_COMMENT'
9+
| 'REDDIT_POST_NEW'
10+
| 'REDDIT_COMMENT_NEW'
11+
| 'REDDIT_COMMENT_EDIT'
12+
| 'GL_ISSUE_NEW'
13+
| 'GL_MR_NEW'
14+
| 'GL_ISSUE_ADD_COMMENT'
15+
| 'GL_MR_ADD_COMMENT'
16+
| 'BB_ISSUE_NEW'
17+
| 'BB_PR_NEW'
18+
| 'BB_ISSUE_ADD_COMMENT'
19+
| 'BB_PR_ADD_COMMENT';
20+
21+
export interface CommentContext {
22+
unique_key: string;
23+
}
24+
25+
export interface TextareaInfo<T extends CommentContext = CommentContext> {
26+
element: HTMLTextAreaElement;
27+
type: CommentType;
28+
context: T;
29+
}
30+
31+
export interface TextareaHandler<T extends CommentContext = CommentContext> {
32+
// Content script functionality
33+
identify(): TextareaInfo<T>[];
34+
readContent(textarea: HTMLTextAreaElement): string;
35+
setContent(textarea: HTMLTextAreaElement, content: string): void;
36+
onSubmit(textarea: HTMLTextAreaElement, callback: (success: boolean) => void): void;
37+
38+
// Context extraction
39+
extractContext(textarea: HTMLTextAreaElement): T | null;
40+
determineType(textarea: HTMLTextAreaElement): CommentType | null;
41+
42+
// Popup functionality helpers
43+
generateDisplayTitle(context: T): string;
44+
generateIcon(type: CommentType): string;
45+
buildUrl(context: T, withDraft?: boolean): string;
46+
}
47+
48+
export abstract class BaseTextareaHandler<T extends CommentContext = CommentContext> implements TextareaHandler<T> {
49+
protected domain: string;
50+
51+
constructor(domain: string) {
52+
this.domain = domain;
53+
}
54+
55+
abstract identify(): TextareaInfo<T>[];
56+
abstract extractContext(textarea: HTMLTextAreaElement): T | null;
57+
abstract determineType(textarea: HTMLTextAreaElement): CommentType | null;
58+
abstract generateDisplayTitle(context: T): string;
59+
abstract generateIcon(type: CommentType): string;
60+
abstract buildUrl(context: T, withDraft?: boolean): string;
61+
62+
readContent(textarea: HTMLTextAreaElement): string {
63+
return textarea.value;
64+
}
65+
66+
setContent(textarea: HTMLTextAreaElement, content: string): void {
67+
textarea.value = content;
68+
textarea.dispatchEvent(new Event('input', { bubbles: true }));
69+
textarea.dispatchEvent(new Event('change', { bubbles: true }));
70+
}
71+
72+
onSubmit(textarea: HTMLTextAreaElement, callback: (success: boolean) => void): void {
73+
const form = textarea.closest('form');
74+
if (form) {
75+
form.addEventListener('submit', () => {
76+
setTimeout(() => callback(true), 100);
77+
}, { once: true });
78+
}
79+
}
80+
}

0 commit comments

Comments
 (0)