Skip to content

Commit 50536e2

Browse files
authored
Adapt the overtype POC branch to the new playground layout (#7)
2 parents 697194b + a68d742 commit 50536e2

File tree

22 files changed

+548
-129
lines changed

22 files changed

+548
-129
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
on:
2+
pull_request:
3+
push:
4+
branches: [main, release]
5+
workflow_dispatch:
6+
concurrency:
7+
group: ${{ github.workflow }}-${{ github.ref }}
8+
cancel-in-progress: true
9+
jobs:
10+
lint-test-and-build:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v5
14+
- uses: actions/setup-node@v5
15+
with:
16+
node-version-file: '.nvmrc'
17+
cache: 'npm'
18+
cache-dependency-path: browser-extension/package-lock.json
19+
- run: npm ci
20+
working-directory: browser-extension
21+
- run: npm run biome
22+
working-directory: browser-extension
23+
- run: npm test
24+
working-directory: browser-extension
25+
- run: npm run compile
26+
working-directory: browser-extension

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# <img align="left" src="browser-extension/public/icons/icon-48.png"> Gitcasso
22

3-
*Syntax highlighting and autosave for comments on GitHub (and other other markdown-friendly places).*
3+
*Syntax highlighting and autosave for comments on GitHub (and other other markdown-friendly websites).*
44

55
- "Syntax highlighting is the lie that enables us to see the truth."
66
- "The meaning of life is to find your lost comment drafts. The purpose of life is to post them."
@@ -12,6 +12,6 @@ TODO: screenshot of comment draft storage and restoration
1212
If there's something you'd like to add or fix, see [CONTRIBUTING.md](CONTRIBUTING.md).
1313

1414
Special thanks to:
15-
- [overtype](https://github.com/panphora/overtype) for the trick which makes syntax highlighting possible
16-
- [shiki](https://github.com/shikijs/shiki) for the broad library of syntax highlighters
15+
- [overtype](https://overtype.dev/) for doing `textarea` syntax highlighting of `md`
16+
- [highlight.js](https://highlightjs.org/) for the broad library of syntax highlighters
1717
- [Yukai Huang](https://github.com/Yukaii) for [the PRs](https://github.com/panphora/overtype/issues?q=is%3Apr+author%3AYukaii) which made the two work together

browser-extension/README.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
- `npm run biome` - runs `biome check` (lint & formatting)
1818
- `npm run biome:fix` - fixes most of what `biome check` finds
1919
- `npm run compile` - typechecking
20-
- `npm run test` - vitest
20+
- `npm test` - vitest
2121

2222
### Deployment
2323
- `npm run build` - build for mv3 for most browsers
@@ -27,10 +27,18 @@
2727

2828
This is a [WXT](https://wxt.dev/)-based browser extension that
2929

30-
- finds `textarea` components and decorates them with [overtype](https://overtype.dev/) and [shiki](https://github.com/shikijs/shiki).
30+
- finds `textarea` components and decorates them with [overtype](https://overtype.dev/) and [highlight.js](https://highlightjs.org/)
3131
- stores unposted comment drafts, and makes them easy to find via the extension popup
3232

3333
### Entry points
3434

35-
- src/entrypoints/content.ts - injected into every webpage
36-
- src/entrypoints/popup - html/css/ts which opens when the extension's button gets clicked
35+
- `src/entrypoints/content.ts` - injected into every webpage
36+
- `src/entrypoints/popup` - html/css/ts which opens when the extension's button gets clicked
37+
38+
### Architecture
39+
40+
Every time a `textarea` shows up on a page, on initial load or later on, it gets passed to a list of `CommentEnhancer`s. Each one gets a turn to say "I can enhance this box!". They show that they can enhance it by returning a [`CommentSpot`, `Overtype`].
41+
42+
Those values get bundled up with the `HTMLTextAreaElement` itself into an `EnhancedTextarea`, which gets added to the `TextareaRegistry`. At some interval, draft edits will get saved by the browser extension (TODO).
43+
44+
When the `textarea` gets removed from the page, the `TextareaRegistry` is notified so that the `CommentSpot` can be marked as abandoned or submitted as appropriate (TODO).

browser-extension/biome.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
},
1111
"files": {
1212
"ignoreUnknown": false,
13-
"includes": [".*", "src/**", "tests/**"]
13+
"includes": [".*", "src/**", "tests/**", "!src/overtype", "!src/playgrounds"]
1414
},
1515
"formatter": {
1616
"enabled": true,
@@ -41,7 +41,7 @@
4141
"linter": {
4242
"rules": {
4343
"complexity": {
44-
"noExcessiveCognitiveComplexity": "warn"
44+
"noExcessiveCognitiveComplexity": "off"
4545
},
4646
"correctness": {
4747
"noUnusedVariables": "error",
@@ -65,7 +65,7 @@
6565
"allow": ["assert", "error", "info", "warn"]
6666
}
6767
},
68-
"noExplicitAny": "error",
68+
"noExplicitAny": "off",
6969
"noVar": "error"
7070
}
7171
}

browser-extension/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

browser-extension/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"overtype": "^1.2.3",
77
"webextension-polyfill": "^0.12.0"
88
},
9-
"description": "Syntax highlighting and autosave for comments on GitHub (and other other markdown-friendly places).",
9+
"description": "Syntax highlighting and autosave for comments on GitHub (and other other markdown-friendly websites).",
1010
"devDependencies": {
1111
"@biomejs/biome": "^2.1.2",
1212
"@testing-library/jest-dom": "^6.6.4",
@@ -43,5 +43,5 @@
4343
"zip:firefox": "wxt zip -b firefox"
4444
},
4545
"type": "module",
46-
"version": "1.0.0"
46+
"version": "0.0.1"
4747
}
Lines changed: 93 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,103 @@
1-
import hljs from "highlight.js";
2-
import OverType from "../overtype/overtype";
1+
import { CONFIG } from '../lib/config'
2+
import { logger } from '../lib/logger'
3+
import { EnhancerRegistry, TextareaRegistry } from '../lib/registries'
4+
import { githubPrNewCommentContentScript } from '../playgrounds/github-playground'
5+
6+
const enhancers = new EnhancerRegistry()
7+
const enhancedTextareas = new TextareaRegistry()
38

49
export default defineContentScript({
510
main() {
6-
if (window.location.hostname !== "github.com") {
7-
return;
11+
if (CONFIG.MODE === 'PLAYGROUNDS_PR') {
12+
githubPrNewCommentContentScript()
13+
return
814
}
9-
OverType.setCodeHighlighter(hljsHighlighter);
10-
const ghCommentBox = document.getElementById(
11-
"new_comment_field"
12-
) as HTMLTextAreaElement | null;
13-
if (ghCommentBox) {
14-
const overtypeContainer = modifyDOM(ghCommentBox);
15-
new OverType(overtypeContainer, {
16-
placeholder: "Add your comment here...",
17-
autoResize: true,
18-
minHeight: "102px",
19-
padding: "var(--base-size-8)",
20-
});
15+
const textAreasOnPageLoad = document.querySelectorAll<HTMLTextAreaElement>(`textarea`)
16+
for (const textarea of textAreasOnPageLoad) {
17+
enhanceMaybe(textarea)
2118
}
19+
const observer = new MutationObserver(handleMutations)
20+
observer.observe(document.body, {
21+
childList: true,
22+
subtree: true,
23+
})
24+
logger.debug('Extension loaded with', enhancers.getEnhancerCount, 'handlers')
2225
},
23-
matches: ["<all_urls>"],
24-
runAt: "document_end",
25-
});
26-
27-
function modifyDOM(overtypeInput: HTMLTextAreaElement): HTMLElement {
28-
overtypeInput.classList.add("overtype-input");
29-
const overtypePreview = document.createElement("div");
30-
overtypePreview.classList.add("overtype-preview");
31-
overtypeInput.insertAdjacentElement("afterend", overtypePreview);
32-
const overtypeWrapper = overtypeInput.parentElement!.closest("div")!;
33-
overtypeWrapper.classList.add("overtype-wrapper");
34-
overtypeInput.placeholder = "Add your comment here...";
35-
const overtypeContainer = overtypeWrapper.parentElement!.closest("div")!;
36-
overtypeContainer.classList.add("overtype-container");
37-
return overtypeContainer.parentElement!.closest("div")!;
38-
}
26+
matches: ['<all_urls>'],
27+
runAt: 'document_end',
28+
})
29+
30+
function handleMutations(mutations: MutationRecord[]): void {
31+
for (const mutation of mutations) {
32+
for (const node of mutation.addedNodes) {
33+
if (node.nodeType === Node.ELEMENT_NODE) {
34+
const element = node as Element
35+
if (element.tagName === 'TEXTAREA') {
36+
enhanceMaybe(element as HTMLTextAreaElement)
37+
} else {
38+
// Also check for textareas within added subtrees
39+
const textareas = element.querySelectorAll?.('textarea')
40+
if (textareas) {
41+
for (const textarea of textareas) {
42+
enhanceMaybe(textarea)
43+
}
44+
}
45+
}
46+
}
47+
}
3948

40-
function hljsHighlighter(code: string, language: string) {
41-
try {
42-
if (language && hljs.getLanguage(language)) {
43-
const result = hljs.highlight(code, { language });
44-
return result.value;
45-
} else {
46-
const result = hljs.highlightAuto(code);
47-
return result.value;
49+
for (const node of mutation.removedNodes) {
50+
if (node.nodeType === Node.ELEMENT_NODE) {
51+
const element = node as Element
52+
if (element.tagName === 'TEXTAREA') {
53+
enhancedTextareas.unregisterDueToModification(element as HTMLTextAreaElement)
54+
} else {
55+
// Also check for textareas within removed subtrees
56+
const textareas = element.querySelectorAll?.('textarea')
57+
if (textareas) {
58+
for (const textarea of textareas) {
59+
enhancedTextareas.unregisterDueToModification(textarea)
60+
}
61+
}
62+
}
63+
}
4864
}
49-
} catch (error) {
50-
console.warn("highlight.js highlighting failed:", error);
51-
return code;
65+
}
66+
}
67+
68+
function enhanceMaybe(textarea: HTMLTextAreaElement) {
69+
if (enhancedTextareas.get(textarea)) {
70+
logger.debug('textarea already registered {}', textarea)
71+
return
72+
}
73+
74+
logger.debug('activating textarea {}', textarea)
75+
injectStyles()
76+
77+
const enhancedTextarea = enhancers.tryToEnhance(textarea)
78+
if (enhancedTextarea) {
79+
logger.debug(
80+
'Identified textarea:',
81+
enhancedTextarea.spot.type,
82+
enhancedTextarea.spot.unique_key,
83+
)
84+
enhancedTextareas.register(enhancedTextarea)
85+
} else {
86+
logger.debug('No handler found for textarea')
87+
}
88+
}
89+
90+
const STYLES = `
91+
.${CONFIG.ADDED_OVERTYPE_CLASS} {
92+
background: cyan !important;
93+
}
94+
`
95+
96+
function injectStyles(): void {
97+
if (!document.getElementById('gitcasso-styles')) {
98+
const style = document.createElement('style')
99+
style.textContent = STYLES
100+
style.id = 'gitcasso-styles'
101+
document.head.appendChild(style)
52102
}
53103
}

browser-extension/src/entrypoints/content/config.ts

Lines changed: 0 additions & 9 deletions
This file was deleted.

browser-extension/src/entrypoints/content/styles.ts

Lines changed: 0 additions & 16 deletions
This file was deleted.

browser-extension/src/entrypoints/popup/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<div id="app">
1010
<div class="header">
1111
<div class="logo">Gitcasso Markdown Assistant</div>
12-
<div class="subtitle">Syntax highlighting and autosave for comments on GitHub (and other other markdown-friendly places).</div>
12+
<div class="subtitle">Syntax highlighting and autosave for comments on GitHub (and other other markdown-friendly websites).</div>
1313
</div>
1414
<div id="scan-results">
1515
<p>Loading drafts from local storage...</p>

0 commit comments

Comments
 (0)