Skip to content

Commit 126233a

Browse files
authored
feat: keep html previews live and fix bare autolinks (#5)
* ci: fix auto release workflow permissions * fix: bound bare autolinks and keep html preview live
1 parent a6699a0 commit 126233a

6 files changed

Lines changed: 63 additions & 4 deletions

File tree

.github/workflows/auto-release.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ on:
77

88
permissions:
99
contents: read
10-
actions: write
1110

1211
concurrency:
1312
group: auto-release-main

specs/features/autolink.specs.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,18 @@ export const autolinkSpecs: FeatureSpecs = {
5959
},
6060
],
6161
},
62+
{
63+
id: "bare-url-cjk-punctuation-boundary",
64+
label: "bare URL stops before CJK punctuation and keeps following text plain",
65+
seed: "裸 URL https://spec.commonmark.org/0.31.2/,以及邮箱 <hello@example.com>。",
66+
events: [],
67+
checkpoints: [
68+
{
69+
at: 0,
70+
expect: "裸 URL <a:https://spec.commonmark.org/0.31.2/>https://spec.commonmark.org/0.31.2/</a>,以及邮箱 <a:mailto:hello@example.com>hello@example.com</a>。|",
71+
},
72+
],
73+
},
6274
{
6375
id: "non-url-not-touched",
6476
label: "<not a url!> — no scheme/email or HTML shape, stays plain text",

src/features/autolink.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ const URI_PART = "[a-zA-Z][a-zA-Z0-9+.-]*:[^\\s<>]+";
2121
const EMAIL_PART =
2222
"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}";
2323
const AUTOLINK_RE = new RegExp(`<((?:${URI_PART})|(?:${EMAIL_PART}))>`, "g");
24-
const BARE_URL_RE = /\bhttps?:\/\/[^\s<>\]]+/g;
24+
const BARE_URL_RE =
25+
/\bhttps?:\/\/[^\s<>\]\u3000-\u303F\uFF01-\uFF0F\uFF1A-\uFF20\uFF3B-\uFF40\uFF5B-\uFF65]+/g;
2526

2627
function rangeConsumed(consumed: Uint8Array, from: number, to: number): boolean {
2728
for (let i = from; i < to; i++) if (consumed[i]) return true;

src/features/html-block.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class HtmlBlockView implements NodeView {
4949
this.preview.addEventListener("click", this.onPreviewClick);
5050
this.source.addEventListener("mousedown", this.onSourceMouseDown);
5151
document.addEventListener("mousedown", this.onDocumentMouseDown);
52-
this.dom.append(this.preview, this.source);
52+
this.dom.append(this.source, this.preview);
5353
this.sourceEditor = createEmbeddedCodeMirrorEditor({
5454
parent: this.source,
5555
doc: rawHtml(node),

src/styles/widgets.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@
277277
outline: none;
278278
}
279279
.ProseMirror html-block .html-block-source[hidden] { display: none; }
280-
.ProseMirror html-block.html-source-open .html-block-preview { display: none; }
280+
.ProseMirror html-block.html-source-open .html-block-source { margin-bottom: 10px; }
281281
.ProseMirror html-block .html-comment-source {
282282
color: #999;
283283
font-style: italic;

tests/html-block.test.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ describe("CommonMark HTML blocks", () => {
5757
expect(widgetsCss).toMatch(
5858
/\.ProseMirror html-block \.html-block-preview \{\s+display: flow-root;\s+margin: 0;\s+padding: 0;\s+\}/,
5959
);
60+
expect(widgetsCss).toContain(
61+
".ProseMirror html-block.html-source-open .html-block-source { margin-bottom: 10px; }",
62+
);
63+
expect(widgetsCss).not.toContain(
64+
".ProseMirror html-block.html-source-open .html-block-preview { display: none; }",
65+
);
6066
expect(widgetsCss).not.toContain("min-height: 4.5em;");
6167
expect(widgetsCss).not.toContain("margin: 8px 0 0;");
6268
expect(widgetsCss).not.toContain("padding: 10px 12px;");
@@ -144,9 +150,11 @@ describe("CommonMark HTML blocks", () => {
144150

145151
expect(block.classList.contains("html-source-open")).toBe(true);
146152
expect(source?.hidden).toBe(false);
153+
expect(source?.nextElementSibling).toBe(block.querySelector(".html-block-preview"));
147154
expect(source?.querySelector(".cm-editor.typora-web-html-source")).not.toBeNull();
148155
expect(source?.textContent).toContain("<details>");
149156
expect(source?.querySelector("details")).toBeNull();
157+
expect(block.querySelector(".html-block-preview strong")?.textContent).toBe("safe");
150158
} finally {
151159
cleanup();
152160
}
@@ -223,4 +231,43 @@ describe("CommonMark HTML blocks", () => {
223231
cleanup();
224232
}
225233
});
234+
235+
test("HTML image source edits keep a live preview with updated dimensions", () => {
236+
const { block, view, cleanup } = mountHtmlBlock(
237+
'<img src="favicon.svg" alt="Typora-Web logo" width="180" />',
238+
);
239+
240+
try {
241+
const preview = block.querySelector<HTMLElement>(".html-block-preview");
242+
preview?.dispatchEvent(new MouseEvent("mousedown", { bubbles: true, cancelable: true }));
243+
244+
const source = block.querySelector<HTMLElement>("div.html-block-source");
245+
expect(source?.hidden).toBe(false);
246+
expect(source?.nextElementSibling).toBe(preview);
247+
expect(preview?.querySelector("img")?.getAttribute("width")).toBe("180");
248+
249+
const editorView = htmlSourceEditor(block);
250+
const current = editorView.state.doc.toString();
251+
editorView.dispatch({
252+
changes: {
253+
from: 0,
254+
to: current.length,
255+
insert: '<img src="favicon.svg" alt="Typora-Web logo" width="96" />',
256+
},
257+
});
258+
259+
const image = preview?.querySelector("img");
260+
expect(image?.getAttribute("src")).toBe("favicon.svg");
261+
expect(image?.getAttribute("alt")).toBe("Typora-Web logo");
262+
expect(image?.getAttribute("width")).toBe("96");
263+
expect(block.dataset.raw).toBe(
264+
'<img src="favicon.svg" alt="Typora-Web logo" width="96" />',
265+
);
266+
expect(serialize(view.state.doc)).toBe(
267+
'<img src="favicon.svg" alt="Typora-Web logo" width="96" />',
268+
);
269+
} finally {
270+
cleanup();
271+
}
272+
});
226273
});

0 commit comments

Comments
 (0)