summaryrefslogtreecommitdiffhomepage
path: root/packages/ui/src/pierre/commented-lines.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/ui/src/pierre/commented-lines.ts')
-rw-r--r--packages/ui/src/pierre/commented-lines.ts91
1 files changed, 91 insertions, 0 deletions
diff --git a/packages/ui/src/pierre/commented-lines.ts b/packages/ui/src/pierre/commented-lines.ts
new file mode 100644
index 000000000..d2fa64866
--- /dev/null
+++ b/packages/ui/src/pierre/commented-lines.ts
@@ -0,0 +1,91 @@
+import { type SelectedLineRange } from "@pierre/diffs"
+import { diffLineIndex, diffRowIndex, findDiffSide } from "./diff-selection"
+
+export type CommentSide = "additions" | "deletions"
+
+function annotationIndex(node: HTMLElement) {
+ const value = node.dataset.lineAnnotation?.split(",")[1]
+ if (!value) return
+ const line = parseInt(value, 10)
+ if (Number.isNaN(line)) return
+ return line
+}
+
+function clear(root: ShadowRoot) {
+ const marked = Array.from(root.querySelectorAll("[data-comment-selected]"))
+ for (const node of marked) {
+ if (!(node instanceof HTMLElement)) continue
+ node.removeAttribute("data-comment-selected")
+ }
+}
+
+export function markCommentedDiffLines(root: ShadowRoot, ranges: SelectedLineRange[]) {
+ clear(root)
+
+ const diffs = root.querySelector("[data-diff]")
+ if (!(diffs instanceof HTMLElement)) return
+
+ const split = diffs.dataset.diffType === "split"
+ const rows = Array.from(diffs.querySelectorAll("[data-line-index]")).filter(
+ (node): node is HTMLElement => node instanceof HTMLElement,
+ )
+ if (rows.length === 0) return
+
+ const annotations = Array.from(diffs.querySelectorAll("[data-line-annotation]")).filter(
+ (node): node is HTMLElement => node instanceof HTMLElement,
+ )
+
+ for (const range of ranges) {
+ const start = diffRowIndex(root, split, range.start, range.side as CommentSide | undefined)
+ if (start === undefined) continue
+
+ const end = (() => {
+ const same = range.end === range.start && (range.endSide == null || range.endSide === range.side)
+ if (same) return start
+ return diffRowIndex(root, split, range.end, (range.endSide ?? range.side) as CommentSide | undefined)
+ })()
+ if (end === undefined) continue
+
+ const first = Math.min(start, end)
+ const last = Math.max(start, end)
+
+ for (const row of rows) {
+ const idx = diffLineIndex(split, row)
+ if (idx === undefined || idx < first || idx > last) continue
+ row.setAttribute("data-comment-selected", "")
+ }
+
+ for (const annotation of annotations) {
+ const idx = annotationIndex(annotation)
+ if (idx === undefined || idx < first || idx > last) continue
+ annotation.setAttribute("data-comment-selected", "")
+ }
+ }
+}
+
+export function markCommentedFileLines(root: ShadowRoot, ranges: SelectedLineRange[]) {
+ clear(root)
+
+ const annotations = Array.from(root.querySelectorAll("[data-line-annotation]")).filter(
+ (node): node is HTMLElement => node instanceof HTMLElement,
+ )
+
+ for (const range of ranges) {
+ const start = Math.max(1, Math.min(range.start, range.end))
+ const end = Math.max(range.start, range.end)
+
+ for (let line = start; line <= end; line++) {
+ const nodes = Array.from(root.querySelectorAll(`[data-line="${line}"], [data-column-number="${line}"]`))
+ for (const node of nodes) {
+ if (!(node instanceof HTMLElement)) continue
+ node.setAttribute("data-comment-selected", "")
+ }
+ }
+
+ for (const annotation of annotations) {
+ const line = annotationIndex(annotation)
+ if (line === undefined || line < start || line > end) continue
+ annotation.setAttribute("data-comment-selected", "")
+ }
+ }
+}