Skip to content

Commit aed61f3

Browse files
committed
✨ 新旧テキストとHEAD情報をChangesに変換する関数を作った
1 parent 517fc22 commit aed61f3

File tree

4 files changed

+132
-3
lines changed

4 files changed

+132
-3
lines changed

browser/websocket/makeChanges.ts

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import { diffToChanges } from "./patch.ts";
2+
import type { Line } from "../../deps/scrapbox.ts";
3+
import {
4+
Block,
5+
convertToBlock,
6+
Node,
7+
packRows,
8+
parseToRows,
9+
} from "../../deps/scrapbox.ts";
10+
import type { Change } from "../../deps/socket.ts";
11+
import { HeadData } from "./pull.ts";
12+
import { toTitleLc } from "../../title.ts";
13+
14+
export interface Init {
15+
userId: string;
16+
head: HeadData;
17+
}
18+
export function makeChanges(
19+
left: Pick<Line, "text" | "id">[],
20+
right: string[],
21+
{ userId, head }: Init,
22+
) {
23+
// 本文の差分
24+
const changes: Change[] = [...diffToChanges(left, right, { userId })];
25+
26+
// titleの差分を入れる
27+
// 空ページの場合もタイトル変更commitを入れる
28+
if (left[0].text !== right[0] || !head.persistent) {
29+
changes.push({ title: right[0] });
30+
}
31+
32+
// descriptionsの差分を入れる
33+
const leftDescriptions = left.slice(1, 6).map((line) => line.text);
34+
const rightDescriptions = right.slice(1, 6);
35+
if (leftDescriptions.join("") !== rightDescriptions.join("")) {
36+
changes.push({ descriptions: rightDescriptions });
37+
}
38+
39+
// リンクと画像の差分を入れる
40+
const [linksLc, image] = findLinksAndImage(right.join("\n"));
41+
if (
42+
head.linksLc.length !== linksLc.length ||
43+
!head.linksLc.every((link) => linksLc.includes(link))
44+
) {
45+
changes.push({ links: linksLc });
46+
}
47+
if (head.image !== image) {
48+
changes.push({ image });
49+
}
50+
51+
return changes;
52+
}
53+
54+
/** テキストに含まれる全てのリンクと最初の画像を探す */
55+
function findLinksAndImage(text: string): [string[], string | null] {
56+
const rows = parseToRows(text);
57+
const blocks = packRows(rows, { hasTitle: true }).flatMap((pack) => {
58+
switch (pack.type) {
59+
case "codeBlock":
60+
case "title":
61+
return [];
62+
case "line":
63+
case "table":
64+
return [convertToBlock(pack)];
65+
}
66+
});
67+
68+
const linksLc = [] as string[];
69+
let image: string | null = null;
70+
71+
const lookup = (node: Node) => {
72+
switch (node.type) {
73+
case "hashTag":
74+
linksLc.push(toTitleLc(node.href));
75+
return;
76+
case "link": {
77+
if (node.pathType !== "relative") return;
78+
linksLc.push(toTitleLc(node.href));
79+
return;
80+
}
81+
case "image":
82+
case "strongImage": {
83+
image ??= node.src;
84+
return;
85+
}
86+
case "strong":
87+
case "quote":
88+
case "decoration": {
89+
for (const n of node.nodes) {
90+
lookup(n);
91+
}
92+
return;
93+
}
94+
default:
95+
return;
96+
}
97+
};
98+
for (const node of blocksToNodes(blocks)) {
99+
lookup(node);
100+
}
101+
102+
return [linksLc, image];
103+
}
104+
105+
function* blocksToNodes(blocks: Iterable<Block>) {
106+
for (const block of blocks) {
107+
switch (block.type) {
108+
case "codeBlock":
109+
case "title":
110+
continue;
111+
case "line":
112+
for (const node of block.nodes) {
113+
yield node;
114+
}
115+
continue;
116+
case "table": {
117+
for (const row of block.cells) {
118+
for (const nodes of row) {
119+
for (const node of nodes) {
120+
yield node;
121+
}
122+
}
123+
}
124+
continue;
125+
}
126+
}
127+
}
128+
}

browser/websocket/patch.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ type Options = {
1111
userId: string;
1212
};
1313
export function* diffToChanges(
14-
left: Omit<Line, "userId" | "updated" | "created">[],
14+
left: Pick<Line, "text" | "id">[],
1515
right: string[],
1616
{ userId }: Options,
1717
): Generator<DeleteCommit | InsertCommit | UpdateCommit, void, unknown> {

deps/scrapbox.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ export type {
1414
Scrapbox,
1515
} from "https://raw.githubusercontent.com/scrapbox-jp/types/0.0.8/mod.ts";
1616
import type { Page } from "https://raw.githubusercontent.com/scrapbox-jp/types/0.0.8/mod.ts";
17+
export * from "https://esm.sh/@progfay/scrapbox-parser@7.2.0";
1718
export type Line = Page["lines"][0];

deps/socket.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ export type {
99
ProjectUpdatesStreamCommit,
1010
ProjectUpdatesStreamEvent,
1111
UpdateCommit,
12-
} from "https://raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.1.3/mod.ts";
12+
} from "https://raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.1.4/mod.ts";
1313
export {
1414
socketIO,
1515
wrap,
16-
} from "https://raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.1.3/mod.ts";
16+
} from "https://raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.1.4/mod.ts";

0 commit comments

Comments
 (0)