@ascribed/review 0.2.0 → 0.2.1-next.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/github/requests.d.ts +4 -0
- package/dist/github/requests.js +5 -1
- package/dist/github/requests.js.map +1 -1
- package/dist/marks/index.d.ts +4 -24
- package/dist/marks/index.js +73 -89
- package/dist/marks/index.js.map +1 -1
- package/dist/marks/title.d.ts +8 -0
- package/dist/marks/title.js +17 -0
- package/dist/marks/title.js.map +1 -0
- package/dist/names.d.ts +95 -0
- package/dist/names.js +99 -0
- package/dist/names.js.map +1 -0
- package/dist/overlay/index.d.ts +1 -1
- package/dist/overlay/index.js.map +1 -1
- package/dist/overlay/overlay.js +32 -22
- package/dist/overlay/overlay.js.map +1 -1
- package/dist/overlay/style.d.ts +1 -1
- package/dist/overlay/style.js +24 -16
- package/dist/overlay/style.js.map +1 -1
- package/dist/overlay/text.js +3 -2
- package/dist/overlay/text.js.map +1 -1
- package/dist/overlay/types.d.ts +8 -2
- package/dist/overlay/types.js.map +1 -1
- package/dist/place/anchor.d.ts +3 -7
- package/dist/place/anchor.js.map +1 -1
- package/dist/shapes.d.ts +271 -0
- package/dist/shapes.js +9 -0
- package/dist/shapes.js.map +1 -0
- package/package.json +3 -2
- package/src/marks/marks.css +54 -49
package/dist/overlay/overlay.js
CHANGED
|
@@ -16,11 +16,12 @@
|
|
|
16
16
|
// root, so they sit in the page's reading and tab order.
|
|
17
17
|
//
|
|
18
18
|
// Comment bodies are rendered by `markdown.ts`, as DOM nodes.
|
|
19
|
-
import { findBlock, goTo, reveal, tabButton } from "../marks/index.js";
|
|
19
|
+
import { findBlock, goTo, reveal, tabButton, titleNodes } from "../marks/index.js";
|
|
20
20
|
import { anchorKey, formatSource } from "../place/anchor.js";
|
|
21
21
|
import { renderMarkdown } from "./markdown.js";
|
|
22
22
|
import { OVERLAY_CSS } from "./style.js";
|
|
23
23
|
import { authorName, blockText, hasUnsent, initials, linesLabel, listLabel, onRemovedText, plural, relativeTime, whereLabel, } from "./text.js";
|
|
24
|
+
import { DATA_CHANGE, DATA_OVERLAY, DATA_SHOW, DATA_SOURCE, DATA_UI, DATA_VIA, DATA_WAS_SOURCE, ELEMENT_TAB, } from "../names.js";
|
|
24
25
|
const COLUMN_WIDTH = 250;
|
|
25
26
|
const COLUMN_GAP = 12;
|
|
26
27
|
const MARKER_ROOM = "44px";
|
|
@@ -255,8 +256,8 @@ class ReviewOverlay {
|
|
|
255
256
|
}
|
|
256
257
|
uiHost(tag) {
|
|
257
258
|
const host = this.doc.createElement(tag);
|
|
258
|
-
host.setAttribute(
|
|
259
|
-
host.setAttribute(
|
|
259
|
+
host.setAttribute(DATA_UI, "");
|
|
260
|
+
host.setAttribute(DATA_OVERLAY, "");
|
|
260
261
|
return host;
|
|
261
262
|
}
|
|
262
263
|
shadow(host) {
|
|
@@ -325,29 +326,29 @@ class ReviewOverlay {
|
|
|
325
326
|
return this.container().clientWidth >= this.columnAt;
|
|
326
327
|
}
|
|
327
328
|
anchorOf(element) {
|
|
328
|
-
const source = element.getAttribute(
|
|
329
|
+
const source = element.getAttribute(DATA_SOURCE);
|
|
329
330
|
if (source === null)
|
|
330
331
|
return undefined;
|
|
331
|
-
const via = (element.getAttribute(
|
|
332
|
+
const via = (element.getAttribute(DATA_VIA) ?? "").split(" ").filter(Boolean);
|
|
332
333
|
return { source, via };
|
|
333
334
|
}
|
|
334
335
|
/** The block an event's target is in: the innermost anchored element. */
|
|
335
336
|
blockOf(target) {
|
|
336
337
|
if (!(target instanceof Element))
|
|
337
338
|
return undefined;
|
|
338
|
-
if (target.closest(
|
|
339
|
+
if (target.closest(`[${DATA_OVERLAY}]`) && target !== this.toolsHost) {
|
|
339
340
|
// A marker: the block it's on.
|
|
340
|
-
const marker = this.markers.find((m) => m.host === target.closest(
|
|
341
|
+
const marker = this.markers.find((m) => m.host === target.closest(`[${DATA_OVERLAY}]`));
|
|
341
342
|
if (marker)
|
|
342
343
|
return marker.block;
|
|
343
344
|
}
|
|
344
|
-
const block = target.closest(
|
|
345
|
+
const block = target.closest(`[${DATA_SOURCE}]`);
|
|
345
346
|
return block && this.root.contains(block) ? block : undefined;
|
|
346
347
|
}
|
|
347
348
|
/** The block's text as the page shows it, for a comment to quote. */
|
|
348
349
|
shownText(anchor) {
|
|
349
350
|
const key = anchorKey(anchor);
|
|
350
|
-
for (const el of Array.from(this.root.querySelectorAll(
|
|
351
|
+
for (const el of Array.from(this.root.querySelectorAll(`[${DATA_SOURCE}]`))) {
|
|
351
352
|
const at = this.anchorOf(el);
|
|
352
353
|
if (at && anchorKey(at) === key)
|
|
353
354
|
return blockText(el) || undefined;
|
|
@@ -355,8 +356,8 @@ class ReviewOverlay {
|
|
|
355
356
|
return undefined;
|
|
356
357
|
}
|
|
357
358
|
removedElement(anchor) {
|
|
358
|
-
for (const el of Array.from(this.root.querySelectorAll(
|
|
359
|
-
if (el.getAttribute(
|
|
359
|
+
for (const el of Array.from(this.root.querySelectorAll(`[${DATA_WAS_SOURCE}]`))) {
|
|
360
|
+
if (el.getAttribute(DATA_WAS_SOURCE) === anchor.source)
|
|
360
361
|
return el;
|
|
361
362
|
}
|
|
362
363
|
return null;
|
|
@@ -411,8 +412,8 @@ class ReviewOverlay {
|
|
|
411
412
|
}
|
|
412
413
|
/** Whether what the page shows hides a block: removed text in "as it will be", new text in "as it was". */
|
|
413
414
|
hiddenByShow(element) {
|
|
414
|
-
const show = this.root.getAttribute(
|
|
415
|
-
const kind = element.closest(
|
|
415
|
+
const show = this.root.getAttribute(DATA_SHOW);
|
|
416
|
+
const kind = element.closest(`[${DATA_CHANGE}]`)?.getAttribute(DATA_CHANGE);
|
|
416
417
|
if (show === "will")
|
|
417
418
|
return kind === "removed" || kind === "moved-from";
|
|
418
419
|
if (show === "was")
|
|
@@ -422,7 +423,7 @@ class ReviewOverlay {
|
|
|
422
423
|
/** Where a block is hidden in the page: an unselected tab or a closed `<details>`. */
|
|
423
424
|
hiddenIn(element) {
|
|
424
425
|
for (let node = element.parentElement; node !== null && node !== this.root.parentElement; node = node.parentElement) {
|
|
425
|
-
if (node.localName ===
|
|
426
|
+
if (node.localName === ELEMENT_TAB && node.hidden) {
|
|
426
427
|
return `In the ${node.getAttribute("label") ?? ""} tab, which isn't showing.`;
|
|
427
428
|
}
|
|
428
429
|
if (node.localName === "details" && !node.open) {
|
|
@@ -446,7 +447,7 @@ class ReviewOverlay {
|
|
|
446
447
|
visibleFor(element) {
|
|
447
448
|
let shown = element;
|
|
448
449
|
for (let node = element?.parentElement ?? null; node !== null && node !== this.root; node = node.parentElement) {
|
|
449
|
-
if (node.localName ===
|
|
450
|
+
if (node.localName === ELEMENT_TAB && node.hidden)
|
|
450
451
|
shown = node.parentElement;
|
|
451
452
|
if (node.localName === "details" && !node.open) {
|
|
452
453
|
const summary = node.querySelector(":scope > summary");
|
|
@@ -502,7 +503,7 @@ class ReviewOverlay {
|
|
|
502
503
|
this.root.style.setProperty("margin-inline-end", `${COLUMN_WIDTH + COLUMN_GAP}px`);
|
|
503
504
|
else
|
|
504
505
|
this.root.style.removeProperty("margin-inline-end");
|
|
505
|
-
for (const el of Array.from(this.root.querySelectorAll(
|
|
506
|
+
for (const el of Array.from(this.root.querySelectorAll(`[${DATA_SOURCE}]`))) {
|
|
506
507
|
if (el.hasAttribute("tabindex"))
|
|
507
508
|
continue;
|
|
508
509
|
el.tabIndex = 0;
|
|
@@ -550,7 +551,7 @@ class ReviewOverlay {
|
|
|
550
551
|
continue;
|
|
551
552
|
for (let node = element.parentElement; node !== null && node !== this.root; node = node.parentElement) {
|
|
552
553
|
let on = null;
|
|
553
|
-
if (node.localName ===
|
|
554
|
+
if (node.localName === ELEMENT_TAB)
|
|
554
555
|
on = tabButton(node);
|
|
555
556
|
if (node.localName === "details") {
|
|
556
557
|
const summary = node.querySelector(":scope > summary");
|
|
@@ -950,16 +951,25 @@ class ReviewOverlay {
|
|
|
950
951
|
for (const summary of groups[this.filter]) {
|
|
951
952
|
const { thread, pages } = summary;
|
|
952
953
|
const first = thread.comments[0];
|
|
953
|
-
const
|
|
954
|
+
const only = pages.length === 1 ? pages[0] : undefined;
|
|
955
|
+
const page = only
|
|
956
|
+
? titleNodes(only.formatted_title, only.title ?? only.path, this.doc)
|
|
957
|
+
: pages.length > 1
|
|
958
|
+
? [`on ${pages.length} pages`]
|
|
959
|
+
: [];
|
|
954
960
|
// As on its card: a thread with no block is detached, not outdated.
|
|
955
961
|
const outdated = thread.outdated && thread.detached === undefined;
|
|
956
|
-
const where =
|
|
957
|
-
|
|
958
|
-
|
|
962
|
+
const where = this.el("span", "where");
|
|
963
|
+
where.append([listLabel(thread), outdated ? "outdated" : ""].filter(Boolean).join(" · "));
|
|
964
|
+
if (page.length > 0) {
|
|
965
|
+
if (where.textContent)
|
|
966
|
+
where.append(" · ");
|
|
967
|
+
where.append(...page);
|
|
968
|
+
}
|
|
959
969
|
const more = thread.comments.length > 1 ? ` (+${thread.comments.length - 1})` : "";
|
|
960
970
|
const item = this.el("li", "");
|
|
961
971
|
const jump = this.button("", "", () => this.jump(summary), `jump:${thread.id}`);
|
|
962
|
-
jump.append(
|
|
972
|
+
jump.append(where, this.el("span", "first", first ? `${authorName(first.author, data.viewer)}: ${oneLine(first.body)}${more}` : ""));
|
|
963
973
|
item.append(jump);
|
|
964
974
|
list.append(item);
|
|
965
975
|
}
|