@lapismd/mira 0.0.4 → 0.0.5

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.
Files changed (203) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/extensions/index.d.ts +7 -0
  3. package/dist/extensions/index.d.ts.map +1 -1
  4. package/dist/preview/editable-markdown-preview/editable-markdown-surface.svelte +20 -9
  5. package/dist/preview/editable-markdown-preview/editable-markdown-surface.svelte.d.ts.map +1 -1
  6. package/dist/preview/editable-markdown-preview/editing-session.d.ts +13 -0
  7. package/dist/preview/editable-markdown-preview/editing-session.d.ts.map +1 -0
  8. package/dist/preview/editable-markdown-preview/editing-session.js +50 -0
  9. package/dist/preview/editable-markdown-preview/editor-surface.svelte +13 -4
  10. package/dist/preview/editable-markdown-preview/editor-surface.svelte.d.ts +1 -0
  11. package/dist/preview/editable-markdown-preview/editor-surface.svelte.d.ts.map +1 -1
  12. package/dist/preview/editable-markdown-preview/serialized-writer.d.ts +5 -1
  13. package/dist/preview/editable-markdown-preview/serialized-writer.d.ts.map +1 -1
  14. package/dist/preview/editable-markdown-preview/serialized-writer.js +29 -0
  15. package/dist/preview/editable-markdown-preview.svelte +8 -6
  16. package/dist/preview/editable-markdown-preview.svelte.d.ts.map +1 -1
  17. package/package.json +5 -2
  18. package/dist/core/code-mirror.test.d.ts +0 -2
  19. package/dist/core/code-mirror.test.d.ts.map +0 -1
  20. package/dist/core/code-mirror.test.js +0 -68
  21. package/dist/core/images.test.d.ts +0 -2
  22. package/dist/core/images.test.d.ts.map +0 -1
  23. package/dist/core/images.test.js +0 -109
  24. package/dist/core/index.test.d.ts +0 -2
  25. package/dist/core/index.test.d.ts.map +0 -1
  26. package/dist/core/index.test.js +0 -11
  27. package/dist/core/markdown-actions.test.d.ts +0 -2
  28. package/dist/core/markdown-actions.test.d.ts.map +0 -1
  29. package/dist/core/markdown-actions.test.js +0 -182
  30. package/dist/extensions/doodle-dividers.test.d.ts +0 -2
  31. package/dist/extensions/doodle-dividers.test.d.ts.map +0 -1
  32. package/dist/extensions/doodle-dividers.test.js +0 -296
  33. package/dist/extensions/index.test.d.ts +0 -2
  34. package/dist/extensions/index.test.d.ts.map +0 -1
  35. package/dist/extensions/index.test.js +0 -283
  36. package/dist/index.test.d.ts +0 -2
  37. package/dist/index.test.d.ts.map +0 -1
  38. package/dist/index.test.js +0 -64
  39. package/dist/internal/appearance-context.test.d.ts +0 -2
  40. package/dist/internal/appearance-context.test.d.ts.map +0 -1
  41. package/dist/internal/appearance-context.test.js +0 -31
  42. package/dist/internal/codemirror/base/index.test.d.ts +0 -2
  43. package/dist/internal/codemirror/base/index.test.d.ts.map +0 -1
  44. package/dist/internal/codemirror/base/index.test.js +0 -303
  45. package/dist/internal/codemirror/base/search.test.d.ts +0 -2
  46. package/dist/internal/codemirror/base/search.test.d.ts.map +0 -1
  47. package/dist/internal/codemirror/base/search.test.js +0 -155
  48. package/dist/internal/codemirror/base/selection-toolbar.test.d.ts +0 -2
  49. package/dist/internal/codemirror/base/selection-toolbar.test.d.ts.map +0 -1
  50. package/dist/internal/codemirror/base/selection-toolbar.test.js +0 -149
  51. package/dist/internal/codemirror/markdown/authoring.test.d.ts +0 -2
  52. package/dist/internal/codemirror/markdown/authoring.test.d.ts.map +0 -1
  53. package/dist/internal/codemirror/markdown/authoring.test.js +0 -222
  54. package/dist/internal/codemirror/markdown/index.test.d.ts +0 -2
  55. package/dist/internal/codemirror/markdown/index.test.d.ts.map +0 -1
  56. package/dist/internal/codemirror/markdown/index.test.js +0 -158
  57. package/dist/internal/codemirror/markdown/showcase-fixture.test.d.ts +0 -2
  58. package/dist/internal/codemirror/markdown/showcase-fixture.test.d.ts.map +0 -1
  59. package/dist/internal/codemirror/markdown/showcase-fixture.test.js +0 -50
  60. package/dist/internal/codemirror/rich/block-controls.test.d.ts +0 -2
  61. package/dist/internal/codemirror/rich/block-controls.test.d.ts.map +0 -1
  62. package/dist/internal/codemirror/rich/block-controls.test.js +0 -401
  63. package/dist/internal/codemirror/rich/block-ranges.test.d.ts +0 -2
  64. package/dist/internal/codemirror/rich/block-ranges.test.d.ts.map +0 -1
  65. package/dist/internal/codemirror/rich/block-ranges.test.js +0 -310
  66. package/dist/internal/codemirror/rich/block-toolbar.test.d.ts +0 -2
  67. package/dist/internal/codemirror/rich/block-toolbar.test.d.ts.map +0 -1
  68. package/dist/internal/codemirror/rich/block-toolbar.test.js +0 -178
  69. package/dist/internal/codemirror/rich/decorations/fold-indicators.test.d.ts +0 -2
  70. package/dist/internal/codemirror/rich/decorations/fold-indicators.test.d.ts.map +0 -1
  71. package/dist/internal/codemirror/rich/decorations/fold-indicators.test.js +0 -8
  72. package/dist/internal/codemirror/rich/index.test.d.ts +0 -2
  73. package/dist/internal/codemirror/rich/index.test.d.ts.map +0 -1
  74. package/dist/internal/codemirror/rich/index.test.js +0 -607
  75. package/dist/internal/codemirror/rich/utils/code-block-lines.test.d.ts +0 -2
  76. package/dist/internal/codemirror/rich/utils/code-block-lines.test.d.ts.map +0 -1
  77. package/dist/internal/codemirror/rich/utils/code-block-lines.test.js +0 -82
  78. package/dist/internal/codemirror/rich/utils/fenced-code.test.d.ts +0 -2
  79. package/dist/internal/codemirror/rich/utils/fenced-code.test.d.ts.map +0 -1
  80. package/dist/internal/codemirror/rich/utils/fenced-code.test.js +0 -12
  81. package/dist/internal/codemirror/rich/utils/headings.test.d.ts +0 -2
  82. package/dist/internal/codemirror/rich/utils/headings.test.d.ts.map +0 -1
  83. package/dist/internal/codemirror/rich/utils/headings.test.js +0 -27
  84. package/dist/internal/codemirror/rich/utils/height-estimates.test.d.ts +0 -2
  85. package/dist/internal/codemirror/rich/utils/height-estimates.test.d.ts.map +0 -1
  86. package/dist/internal/codemirror/rich/utils/height-estimates.test.js +0 -10
  87. package/dist/internal/codemirror/rich/utils/images.test.d.ts +0 -2
  88. package/dist/internal/codemirror/rich/utils/images.test.d.ts.map +0 -1
  89. package/dist/internal/codemirror/rich/utils/images.test.js +0 -37
  90. package/dist/internal/codemirror/rich/utils/indent.test.d.ts +0 -2
  91. package/dist/internal/codemirror/rich/utils/indent.test.d.ts.map +0 -1
  92. package/dist/internal/codemirror/rich/utils/indent.test.js +0 -169
  93. package/dist/internal/codemirror/rich/utils/inline-math.test.d.ts +0 -2
  94. package/dist/internal/codemirror/rich/utils/inline-math.test.d.ts.map +0 -1
  95. package/dist/internal/codemirror/rich/utils/inline-math.test.js +0 -15
  96. package/dist/internal/codemirror/rich/utils/links.test.d.ts +0 -2
  97. package/dist/internal/codemirror/rich/utils/links.test.d.ts.map +0 -1
  98. package/dist/internal/codemirror/rich/utils/links.test.js +0 -28
  99. package/dist/internal/codemirror/rich/utils/list-callouts.test.d.ts +0 -2
  100. package/dist/internal/codemirror/rich/utils/list-callouts.test.d.ts.map +0 -1
  101. package/dist/internal/codemirror/rich/utils/list-callouts.test.js +0 -47
  102. package/dist/internal/codemirror/rich/utils/measured-indent.test.d.ts +0 -2
  103. package/dist/internal/codemirror/rich/utils/measured-indent.test.d.ts.map +0 -1
  104. package/dist/internal/codemirror/rich/utils/measured-indent.test.js +0 -102
  105. package/dist/internal/codemirror/rich/utils/ranges.test.d.ts +0 -2
  106. package/dist/internal/codemirror/rich/utils/ranges.test.d.ts.map +0 -1
  107. package/dist/internal/codemirror/rich/utils/ranges.test.js +0 -22
  108. package/dist/internal/codemirror/rich/utils/tasks.test.d.ts +0 -2
  109. package/dist/internal/codemirror/rich/utils/tasks.test.d.ts.map +0 -1
  110. package/dist/internal/codemirror/rich/utils/tasks.test.js +0 -57
  111. package/dist/internal/task-states.test.d.ts +0 -2
  112. package/dist/internal/task-states.test.d.ts.map +0 -1
  113. package/dist/internal/task-states.test.js +0 -36
  114. package/dist/mira-code-editor.test.d.ts +0 -2
  115. package/dist/mira-code-editor.test.d.ts.map +0 -1
  116. package/dist/mira-code-editor.test.js +0 -93
  117. package/dist/mode-position.test.d.ts +0 -2
  118. package/dist/mode-position.test.d.ts.map +0 -1
  119. package/dist/mode-position.test.js +0 -60
  120. package/dist/preview/code-language.test.d.ts +0 -2
  121. package/dist/preview/code-language.test.d.ts.map +0 -1
  122. package/dist/preview/code-language.test.js +0 -12
  123. package/dist/preview/components/icon.test.d.ts +0 -2
  124. package/dist/preview/components/icon.test.d.ts.map +0 -1
  125. package/dist/preview/components/icon.test.js +0 -20
  126. package/dist/preview/editable-markdown-preview/behavior.test.d.ts +0 -2
  127. package/dist/preview/editable-markdown-preview/behavior.test.d.ts.map +0 -1
  128. package/dist/preview/editable-markdown-preview/behavior.test.js +0 -36
  129. package/dist/preview/editable-markdown-preview/serialized-writer.test.d.ts +0 -2
  130. package/dist/preview/editable-markdown-preview/serialized-writer.test.d.ts.map +0 -1
  131. package/dist/preview/editable-markdown-preview/serialized-writer.test.js +0 -59
  132. package/dist/preview/embed-target.test.d.ts +0 -2
  133. package/dist/preview/embed-target.test.d.ts.map +0 -1
  134. package/dist/preview/embed-target.test.js +0 -78
  135. package/dist/preview/frontmatter/frontmatter.test.d.ts +0 -2
  136. package/dist/preview/frontmatter/frontmatter.test.d.ts.map +0 -1
  137. package/dist/preview/frontmatter/frontmatter.test.js +0 -190
  138. package/dist/preview/frontmatter/suggestions.test.d.ts +0 -2
  139. package/dist/preview/frontmatter/suggestions.test.d.ts.map +0 -1
  140. package/dist/preview/frontmatter/suggestions.test.js +0 -45
  141. package/dist/preview/outline.test.d.ts +0 -2
  142. package/dist/preview/outline.test.d.ts.map +0 -1
  143. package/dist/preview/outline.test.js +0 -98
  144. package/dist/preview/portable-surfaces.test.d.ts +0 -2
  145. package/dist/preview/portable-surfaces.test.d.ts.map +0 -1
  146. package/dist/preview/portable-surfaces.test.js +0 -513
  147. package/dist/preview/preview.test.d.ts +0 -2
  148. package/dist/preview/preview.test.d.ts.map +0 -1
  149. package/dist/preview/preview.test.js +0 -154
  150. package/dist/preview/remark/callouts.test.d.ts +0 -2
  151. package/dist/preview/remark/callouts.test.d.ts.map +0 -1
  152. package/dist/preview/remark/callouts.test.js +0 -23
  153. package/dist/preview/remark/custom-checklists.test.d.ts +0 -2
  154. package/dist/preview/remark/custom-checklists.test.d.ts.map +0 -1
  155. package/dist/preview/remark/custom-checklists.test.js +0 -51
  156. package/dist/preview/remark/links.test.d.ts +0 -2
  157. package/dist/preview/remark/links.test.d.ts.map +0 -1
  158. package/dist/preview/remark/links.test.js +0 -62
  159. package/dist/preview/remark/parity.test.d.ts +0 -2
  160. package/dist/preview/remark/parity.test.d.ts.map +0 -1
  161. package/dist/preview/remark/parity.test.js +0 -105
  162. package/dist/preview/styles/frontmatter-properties.test.d.ts +0 -2
  163. package/dist/preview/styles/frontmatter-properties.test.d.ts.map +0 -1
  164. package/dist/preview/styles/frontmatter-properties.test.js +0 -57
  165. package/dist/preview/styles/source-mode.test.d.ts +0 -2
  166. package/dist/preview/styles/source-mode.test.d.ts.map +0 -1
  167. package/dist/preview/styles/source-mode.test.js +0 -28
  168. package/dist/tables/extension.test.d.ts +0 -2
  169. package/dist/tables/extension.test.d.ts.map +0 -1
  170. package/dist/tables/extension.test.js +0 -100
  171. package/dist/tables/grid-editor-column.test.d.ts +0 -2
  172. package/dist/tables/grid-editor-column.test.d.ts.map +0 -1
  173. package/dist/tables/grid-editor-column.test.js +0 -27
  174. package/dist/tables/grid-table.test.d.ts +0 -2
  175. package/dist/tables/grid-table.test.d.ts.map +0 -1
  176. package/dist/tables/grid-table.test.js +0 -140
  177. package/dist/tables/index.test.d.ts +0 -2
  178. package/dist/tables/index.test.d.ts.map +0 -1
  179. package/dist/tables/index.test.js +0 -7
  180. package/dist/tables/inline-editor-extensions.test.d.ts +0 -2
  181. package/dist/tables/inline-editor-extensions.test.d.ts.map +0 -1
  182. package/dist/tables/inline-editor-extensions.test.js +0 -23
  183. package/dist/tables/pipe-table.test.d.ts +0 -2
  184. package/dist/tables/pipe-table.test.d.ts.map +0 -1
  185. package/dist/tables/pipe-table.test.js +0 -13
  186. package/dist/tables/table-node.test.d.ts +0 -2
  187. package/dist/tables/table-node.test.d.ts.map +0 -1
  188. package/dist/tables/table-node.test.js +0 -167
  189. package/dist/tables/widgets/source-button.test.d.ts +0 -2
  190. package/dist/tables/widgets/source-button.test.d.ts.map +0 -1
  191. package/dist/tables/widgets/source-button.test.js +0 -11
  192. package/dist/themes/theme-contract.test.d.ts +0 -2
  193. package/dist/themes/theme-contract.test.d.ts.map +0 -1
  194. package/dist/themes/theme-contract.test.js +0 -88
  195. package/dist/ui/index.test.d.ts +0 -2
  196. package/dist/ui/index.test.d.ts.map +0 -1
  197. package/dist/ui/index.test.js +0 -7
  198. package/dist/ui/styles.test.d.ts +0 -2
  199. package/dist/ui/styles.test.d.ts.map +0 -1
  200. package/dist/ui/styles.test.js +0 -26
  201. package/dist/ui/table-dnd/table-dnd-utils.test.d.ts +0 -2
  202. package/dist/ui/table-dnd/table-dnd-utils.test.d.ts.map +0 -1
  203. package/dist/ui/table-dnd/table-dnd-utils.test.js +0 -46
@@ -1 +0,0 @@
1
- {"version":3,"file":"tasks.test.d.ts","sourceRoot":"","sources":["../../../../../src/internal/codemirror/rich/utils/tasks.test.ts"],"names":[],"mappings":""}
@@ -1,57 +0,0 @@
1
- import { EditorState } from "@codemirror/state";
2
- import { describe, expect, it } from "vitest";
3
- import { getTaskMarkerRange, selectionTouchesTaskMarker } from "./tasks";
4
- describe("task utilities", () => {
5
- it("resolves normal and custom task marker ranges", () => {
6
- expect(getTaskMarkerRange("- [ ] Open task", 0)).toEqual({
7
- markerStart: 0,
8
- checkboxStart: 2,
9
- checkboxEnd: 5,
10
- markerEnd: 6,
11
- taskValue: " ",
12
- });
13
- expect(getTaskMarkerRange(" * [/] Custom task", 10)).toEqual({
14
- markerStart: 12,
15
- checkboxStart: 14,
16
- checkboxEnd: 17,
17
- markerEnd: 18,
18
- taskValue: "/",
19
- });
20
- expect(getTaskMarkerRange("- [?] Question task", 0)?.taskValue).toBe("?");
21
- expect(getTaskMarkerRange("- [-] Cancelled task", 0)?.taskValue).toBe("-");
22
- });
23
- it("resolves task markers after authored blockquote prefixes", () => {
24
- expect(getTaskMarkerRange(" > - [ ] Quoted checklist child", 20)).toEqual({
25
- markerStart: 26,
26
- checkboxStart: 28,
27
- checkboxEnd: 31,
28
- markerEnd: 32,
29
- taskValue: " ",
30
- });
31
- expect(getTaskMarkerRange("> > 1. [x] Nested task", 0)).toEqual({
32
- markerStart: 4,
33
- checkboxStart: 7,
34
- checkboxEnd: 10,
35
- markerEnd: 11,
36
- taskValue: "x",
37
- });
38
- });
39
- it("treats the task marker prefix as active for source reveal", () => {
40
- for (let anchor = 0; anchor <= 6; anchor += 1) {
41
- const state = EditorState.create({
42
- doc: "* [/] Custom task\nParagraph",
43
- selection: { anchor },
44
- });
45
- const taskLine = state.doc.line(1);
46
- const taskRange = getTaskMarkerRange(taskLine.text, taskLine.from);
47
- expect(selectionTouchesTaskMarker(state, taskLine.from, taskRange.markerEnd)).toBe(true);
48
- }
49
- const state = EditorState.create({
50
- doc: "* [/] Custom task\nParagraph",
51
- selection: { anchor: 10 },
52
- });
53
- const taskLine = state.doc.line(1);
54
- const taskRange = getTaskMarkerRange(taskLine.text, taskLine.from);
55
- expect(selectionTouchesTaskMarker(state, taskLine.from, taskRange.markerEnd)).toBe(false);
56
- });
57
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=task-states.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"task-states.test.d.ts","sourceRoot":"","sources":["../../src/internal/task-states.test.ts"],"names":[],"mappings":""}
@@ -1,36 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import { miraTaskStates, normalizeMiraTaskMarker } from "./task-states";
3
- describe("Mira task states", () => {
4
- it("contains every shipped standard and custom checkbox marker once", () => {
5
- const markers = miraTaskStates.map(({ marker }) => marker);
6
- expect(markers).toEqual([
7
- " ",
8
- "x",
9
- "/",
10
- "?",
11
- "-",
12
- "!",
13
- ">",
14
- "<",
15
- "l",
16
- "*",
17
- "i",
18
- "S",
19
- "I",
20
- "f",
21
- "k",
22
- "u",
23
- "d",
24
- "w",
25
- "p",
26
- "c",
27
- "b",
28
- '"',
29
- ]);
30
- expect(new Set(markers).size).toBe(markers.length);
31
- });
32
- it("normalizes the alternate completed marker only", () => {
33
- expect(normalizeMiraTaskMarker("X")).toBe("x");
34
- expect(normalizeMiraTaskMarker("S")).toBe("S");
35
- });
36
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=mira-code-editor.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mira-code-editor.test.d.ts","sourceRoot":"","sources":["../src/mira-code-editor.test.ts"],"names":[],"mappings":""}
@@ -1,93 +0,0 @@
1
- import { undo } from "@codemirror/commands";
2
- import { Transaction } from "@codemirror/state";
3
- import { EditorView } from "@codemirror/view";
4
- import { readFileSync } from "node:fs";
5
- import { resolve } from "node:path";
6
- import { mount, tick, unmount } from "svelte";
7
- import { describe, expect, it, vi } from "vitest";
8
- import MiraCodeEditor from "./mira-code-editor.svelte";
9
- import Mira from "./mira.svelte";
10
- describe("MiraCodeEditor", () => {
11
- it("keeps the gutter and search panel on the editor surface", () => {
12
- const shellCss = readFileSync(resolve(process.cwd(), "src/mira-code-editor.css"), "utf8");
13
- const searchPanel = readFileSync(resolve(process.cwd(), "src/internal/codemirror/base/search-panel.svelte"), "utf8");
14
- expect(shellCss).toMatch(/background:\s*var\(\s*--mira-code-editor-gutter-background,\s*var\(--mira-code-editor-background/);
15
- expect(shellCss).toMatch(/\[data-surface="framed"\]:focus-within\s*\{[\s\S]*?border-color:\s*transparent/);
16
- expect(shellCss).not.toMatch(/^\s*--mira-code-editor-focus-ring:\s*var\(/m);
17
- expect(searchPanel).toMatch(/background:\s*var\(\s*--mira-code-editor-background/);
18
- expect(searchPanel).toContain("--mira-code-editor-search-input-background");
19
- expect(searchPanel).toContain("--mira-code-editor-search-button-hover-background");
20
- expect(searchPanel).toContain("--mira-code-editor-search-focus-ring");
21
- expect(searchPanel).toMatch(/__search-field:focus-within,[\s\S]*?__button:focus-visible\s*\{[\s\S]*?border-color:\s*transparent/);
22
- expect(searchPanel).toMatch(/--mira-code-editor-search-radius,[\s\S]*?999px/);
23
- expect(searchPanel).toMatch(/font-size:\s*var\(--mira-code-editor-search-font-size,\s*0\.875rem\)/);
24
- expect(searchPanel).toMatch(/\.cm-panels-top:has\(\.mira-search-panel-host\)[\s\S]*?background:\s*transparent;[\s\S]*?border-bottom:\s*0/);
25
- });
26
- it("owns a controlled accessible CodeMirror lifecycle", async () => {
27
- const target = document.createElement("div");
28
- document.body.append(target);
29
- const onChange = vi.fn();
30
- const component = mount(MiraCodeEditor, {
31
- target,
32
- props: {
33
- value: "name: Mira",
34
- ariaLabel: "YAML editor",
35
- invalid: true,
36
- minHeight: "12rem",
37
- scrollerTabIndex: 0,
38
- onChange,
39
- },
40
- });
41
- await tick();
42
- const view = component.getView();
43
- expect(view).not.toBeNull();
44
- expect(view?.contentDOM.getAttribute("aria-label")).toBe("YAML editor");
45
- expect(view?.contentDOM.getAttribute("aria-invalid")).toBe("true");
46
- expect(view?.scrollDOM.getAttribute("tabindex")).toBe("0");
47
- expect(target.querySelector(".mira-code-editor")?.getAttribute("data-surface")).toBe("framed");
48
- view?.dispatch({
49
- changes: { from: view.state.doc.length, insert: "\nrole: editor" },
50
- annotations: Transaction.userEvent.of("input"),
51
- });
52
- expect(onChange).toHaveBeenLastCalledWith("name: Mira\nrole: editor");
53
- component.setValue("external: value");
54
- expect(component.getValue()).toBe("external: value");
55
- expect(onChange).toHaveBeenCalledTimes(1);
56
- component.setSelection({
57
- anchor: { line: 0, ch: 0 },
58
- head: { line: 0, ch: 8 },
59
- });
60
- expect(component.getSelection()).toEqual({
61
- anchor: { line: 0, ch: 0 },
62
- head: { line: 0, ch: 8 },
63
- });
64
- await unmount(component);
65
- expect(target.querySelector(".cm-editor")).toBeNull();
66
- target.remove();
67
- });
68
- it("preserves edit history when the Markdown consumer reconfigures", async () => {
69
- const target = document.createElement("div");
70
- document.body.append(target);
71
- const component = mount(Mira, {
72
- target,
73
- props: { value: "alpha", mode: "source" },
74
- });
75
- await tick();
76
- const editorElement = target.querySelector(".cm-editor");
77
- const view = editorElement ? EditorView.findFromDOM(editorElement) : null;
78
- expect(view).not.toBeNull();
79
- view?.dispatch({
80
- changes: { from: 5, insert: " beta" },
81
- annotations: Transaction.userEvent.of("input"),
82
- });
83
- expect(component.getMarkdown()).toBe("alpha beta");
84
- component.setReadonly(true);
85
- await tick();
86
- component.setReadonly(false);
87
- await tick();
88
- expect(view && undo(view)).toBe(true);
89
- expect(component.getMarkdown()).toBe("alpha");
90
- await unmount(component);
91
- target.remove();
92
- });
93
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=mode-position.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mode-position.test.d.ts","sourceRoot":"","sources":["../src/mode-position.test.ts"],"names":[],"mappings":""}
@@ -1,60 +0,0 @@
1
- import { EditorState } from "@codemirror/state";
2
- import { EditorView } from "@codemirror/view";
3
- import { afterEach, describe, expect, it, vi } from "vitest";
4
- import { captureModeSwitchPosition, capturePreviewPosition, restorePreviewPosition, } from "./mode-position";
5
- afterEach(() => {
6
- document.body.replaceChildren();
7
- });
8
- describe("mode position continuity", () => {
9
- it("captures the nearest visible preview source line and restores it", () => {
10
- const scroller = document.createElement("div");
11
- const first = appendAnchor(scroller, 5, -30);
12
- const second = appendAnchor(scroller, 12, 20);
13
- vi.spyOn(scroller, "getBoundingClientRect").mockReturnValue(rect(0, 100));
14
- const scrollTo = vi.fn();
15
- Object.defineProperty(scroller, "scrollTo", {
16
- configurable: true,
17
- value: scrollTo,
18
- });
19
- scroller.scrollTop = 50;
20
- const position = capturePreviewPosition(scroller);
21
- expect(position).toMatchObject({ line: 12, topDelta: 20 });
22
- vi.mocked(first.getBoundingClientRect).mockReturnValue(rect(-20, 20));
23
- vi.mocked(second.getBoundingClientRect).mockReturnValue(rect(40, 80));
24
- restorePreviewPosition(scroller, position);
25
- expect(scrollTo).toHaveBeenLastCalledWith({ top: 70 });
26
- });
27
- it("captures the surface that becomes hidden when entering preview or split", () => {
28
- const host = document.createElement("div");
29
- document.body.append(host);
30
- const view = new EditorView({
31
- parent: host,
32
- state: EditorState.create({ doc: "one\ntwo\nthree" }),
33
- });
34
- const preview = document.createElement("div");
35
- expect(captureModeSwitchPosition("source", "preview", view, preview)?.target).toBe("preview");
36
- expect(captureModeSwitchPosition("preview", "split", view, preview)?.target).toBe("editor");
37
- expect(captureModeSwitchPosition("live-preview", "source", view, preview)).toBeNull();
38
- view.destroy();
39
- });
40
- });
41
- function appendAnchor(root, line, top) {
42
- const anchor = document.createElement("p");
43
- anchor.dataset["line"] = `${line}`;
44
- vi.spyOn(anchor, "getBoundingClientRect").mockReturnValue(rect(top, top + 20));
45
- root.append(anchor);
46
- return anchor;
47
- }
48
- function rect(top, bottom) {
49
- return {
50
- bottom,
51
- height: bottom - top,
52
- left: 0,
53
- right: 100,
54
- top,
55
- width: 100,
56
- x: 0,
57
- y: top,
58
- toJSON: () => ({}),
59
- };
60
- }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=code-language.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"code-language.test.d.ts","sourceRoot":"","sources":["../../src/preview/code-language.test.ts"],"names":[],"mappings":""}
@@ -1,12 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import { codeLanguageLabel } from "./code-language";
3
- describe("code language labels", () => {
4
- it("uses readable labels for common fenced-code aliases", () => {
5
- expect(codeLanguageLabel("hljs language-ts")).toBe("TypeScript");
6
- expect(codeLanguageLabel("language-yml hljs")).toBe("YAML");
7
- });
8
- it("preserves unknown language ids and omits unlabelled blocks", () => {
9
- expect(codeLanguageLabel("hljs language-gleam")).toBe("gleam");
10
- expect(codeLanguageLabel("hljs")).toBe("");
11
- });
12
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=icon.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"icon.test.d.ts","sourceRoot":"","sources":["../../../src/preview/components/icon.test.ts"],"names":[],"mappings":""}
@@ -1,20 +0,0 @@
1
- import { mount, tick, unmount } from "svelte";
2
- import { describe, expect, it } from "vitest";
3
- import Icon from "./icon.svelte";
4
- describe("portable preview icon", () => {
5
- it("renders canonical Lucide hash geometry", async () => {
6
- const target = document.createElement("div");
7
- document.body.append(target);
8
- const component = mount(Icon, {
9
- target,
10
- props: { name: "lucide-hash" },
11
- });
12
- await tick();
13
- expect(target.querySelector('path[d="M4 9h16"]')).not.toBeNull();
14
- expect(target.querySelector('path[d="M4 15h16"]')).not.toBeNull();
15
- expect(target.querySelector('path[d="M10 3 8 21"]')).not.toBeNull();
16
- expect(target.querySelector('path[d="m16 3-2 18"]')).not.toBeNull();
17
- await unmount(component);
18
- target.remove();
19
- });
20
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=behavior.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"behavior.test.d.ts","sourceRoot":"","sources":["../../../src/preview/editable-markdown-preview/behavior.test.ts"],"names":[],"mappings":""}
@@ -1,36 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import { getEditableMarkdownPreviewOffset, isEditableMarkdownPreviewInteractiveTarget, shouldActivateEditableMarkdownPreview, shouldReturnEditableMarkdownPreviewOnBlur, } from "./behavior";
3
- describe("editable Markdown preview behavior", () => {
4
- it("accepts a plain primary click and reads the nearest source offset", () => {
5
- const block = document.createElement("p");
6
- block.dataset.offset = "24";
7
- const text = document.createElement("span");
8
- block.append(text);
9
- const event = new MouseEvent("click", { button: 0, bubbles: true });
10
- text.dispatchEvent(event);
11
- expect(shouldActivateEditableMarkdownPreview(event)).toBe(true);
12
- expect(getEditableMarkdownPreviewOffset(event)).toBe(24);
13
- });
14
- it("ignores interactive descendants, modifiers, and non-primary clicks", () => {
15
- const button = document.createElement("button");
16
- const child = document.createElement("span");
17
- button.append(child);
18
- expect(isEditableMarkdownPreviewInteractiveTarget(child)).toBe(true);
19
- expect(shouldActivateEditableMarkdownPreview(new MouseEvent("click", { button: 0, ctrlKey: true }))).toBe(false);
20
- const interactiveEvent = new MouseEvent("click", {
21
- button: 0,
22
- bubbles: true,
23
- });
24
- child.dispatchEvent(interactiveEvent);
25
- expect(shouldActivateEditableMarkdownPreview(interactiveEvent)).toBe(false);
26
- expect(shouldActivateEditableMarkdownPreview(new MouseEvent("click", { button: 1 }))).toBe(false);
27
- });
28
- it("returns to preview only when focus leaves the editor", () => {
29
- const container = document.createElement("div");
30
- const inside = document.createElement("button");
31
- const outside = document.createElement("button");
32
- container.append(inside);
33
- expect(shouldReturnEditableMarkdownPreviewOnBlur(container, inside, inside)).toBe(false);
34
- expect(shouldReturnEditableMarkdownPreviewOnBlur(container, outside, outside)).toBe(true);
35
- });
36
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=serialized-writer.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"serialized-writer.test.d.ts","sourceRoot":"","sources":["../../../src/preview/editable-markdown-preview/serialized-writer.test.ts"],"names":[],"mappings":""}
@@ -1,59 +0,0 @@
1
- import { describe, expect, it, vi } from "vitest";
2
- import { SerializedMarkdownWriter } from "./serialized-writer";
3
- describe("SerializedMarkdownWriter", () => {
4
- it("debounces writes for 500ms", async () => {
5
- vi.useFakeTimers();
6
- const write = vi.fn();
7
- const writer = new SerializedMarkdownWriter({ value: "old", write });
8
- writer.update("one");
9
- writer.update("two");
10
- await vi.advanceTimersByTimeAsync(499);
11
- expect(write).not.toHaveBeenCalled();
12
- await vi.advanceTimersByTimeAsync(1);
13
- expect(write).toHaveBeenCalledOnce();
14
- expect(write).toHaveBeenCalledWith("two");
15
- vi.useRealTimers();
16
- });
17
- it("serializes writes and flushes the latest value", async () => {
18
- let releaseFirst;
19
- const writes = [];
20
- const write = vi.fn((value) => {
21
- writes.push(value);
22
- if (writes.length === 1) {
23
- return new Promise((resolve) => {
24
- releaseFirst = resolve;
25
- });
26
- }
27
- });
28
- const writer = new SerializedMarkdownWriter({ value: "old", write });
29
- writer.update("one");
30
- const firstFlush = writer.flush();
31
- await Promise.resolve();
32
- writer.update("two");
33
- const secondFlush = writer.flush();
34
- expect(writes).toEqual(["one"]);
35
- releaseFirst?.();
36
- await expect(firstFlush).resolves.toBe(true);
37
- await expect(secondFlush).resolves.toBe(true);
38
- expect(writes).toEqual(["one", "two"]);
39
- expect(writer.state.dirty).toBe(false);
40
- });
41
- it("preserves dirty data and rejects external replacement after failure", async () => {
42
- const writer = new SerializedMarkdownWriter({
43
- value: "old",
44
- write: async () => {
45
- throw new Error("disk full");
46
- },
47
- });
48
- writer.update("unsaved");
49
- await expect(writer.flush()).resolves.toBe(false);
50
- expect(writer.state).toMatchObject({
51
- dirty: true,
52
- saving: false,
53
- value: "unsaved",
54
- });
55
- expect(writer.state.error?.message).toBe("disk full");
56
- expect(writer.replaceExternal("external")).toBe(false);
57
- expect(writer.state.value).toBe("unsaved");
58
- });
59
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=embed-target.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"embed-target.test.d.ts","sourceRoot":"","sources":["../../src/preview/embed-target.test.ts"],"names":[],"mappings":""}
@@ -1,78 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import { parseMiraImageDetails, selectMarkdownEmbedFragment, } from "./embed-target";
3
- describe("portable embed targets", () => {
4
- const markdown = [
5
- "# Project",
6
- "",
7
- "Introduction.",
8
- "",
9
- "## Next Steps",
10
- "",
11
- "Ship the adapter.",
12
- "",
13
- "### Detail",
14
- "",
15
- "Keep this nested section.",
16
- "",
17
- "## Decisions",
18
- "",
19
- "Use target watchers.",
20
- "",
21
- "A portable referenced paragraph. ^decision-1",
22
- ].join("\n");
23
- it("selects heading sections through the next sibling heading", () => {
24
- expect(selectMarkdownEmbedFragment(markdown, {
25
- kind: "heading",
26
- value: "Next Steps",
27
- })).toEqual({
28
- found: true,
29
- markdown: [
30
- "## Next Steps",
31
- "",
32
- "Ship the adapter.",
33
- "",
34
- "### Detail",
35
- "",
36
- "Keep this nested section.",
37
- "",
38
- ].join("\n"),
39
- });
40
- });
41
- it("accepts heading slugs and selects block references without the marker", () => {
42
- expect(selectMarkdownEmbedFragment(markdown, {
43
- kind: "heading",
44
- value: "next-steps",
45
- }).found).toBe(true);
46
- expect(selectMarkdownEmbedFragment(markdown, {
47
- kind: "block",
48
- value: "decision-1",
49
- })).toEqual({
50
- found: true,
51
- markdown: "A portable referenced paragraph.",
52
- });
53
- });
54
- it("reports missing fragments without falling back to the whole note", () => {
55
- expect(selectMarkdownEmbedFragment(markdown, {
56
- kind: "heading",
57
- value: "Missing",
58
- })).toEqual({ found: false, markdown: "" });
59
- });
60
- });
61
- describe("image details", () => {
62
- it("parses Lapis-style width and width-by-height suffixes", () => {
63
- expect(parseMiraImageDetails("Diagram|640x360")).toEqual({
64
- alt: "Diagram",
65
- width: 640,
66
- height: 360,
67
- });
68
- expect(parseMiraImageDetails("320", "diagram.png")).toEqual({
69
- alt: "diagram.png",
70
- width: 320,
71
- });
72
- });
73
- it("preserves ordinary alt text", () => {
74
- expect(parseMiraImageDetails("Architecture diagram")).toEqual({
75
- alt: "Architecture diagram",
76
- });
77
- });
78
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=frontmatter.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"frontmatter.test.d.ts","sourceRoot":"","sources":["../../../src/preview/frontmatter/frontmatter.test.ts"],"names":[],"mappings":""}