@k2b/ui 0.13.0 → 0.14.0
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/dist/browser/content/MarkdownView.js +13 -5
- package/dist/browser/content/MarkdownView.js.map +1 -1
- package/dist/browser/content/index.js +1 -0
- package/dist/browser/content/index.js.map +1 -1
- package/dist/browser/content/markdown-info-blocks.js +363 -0
- package/dist/browser/content/markdown-info-blocks.js.map +1 -0
- package/dist/browser/feedback/dialog-core.js +6 -1
- package/dist/browser/feedback/dialog-core.js.map +1 -1
- package/dist/browser/intl/messages.js +10 -0
- package/dist/browser/intl/messages.js.map +1 -1
- package/dist/browser/layout/MobileShell.js +48 -6
- package/dist/browser/layout/MobileShell.js.map +1 -1
- package/dist/browser/layout/TabBar.js +8 -4
- package/dist/browser/layout/TabBar.js.map +1 -1
- package/dist/ssr/content/MarkdownView.js +13 -5
- package/dist/ssr/content/MarkdownView.js.map +1 -1
- package/dist/ssr/content/index.js +1 -0
- package/dist/ssr/content/index.js.map +1 -1
- package/dist/ssr/content/markdown-info-blocks.js +363 -0
- package/dist/ssr/content/markdown-info-blocks.js.map +1 -0
- package/dist/ssr/feedback/dialog-core.js +6 -1
- package/dist/ssr/feedback/dialog-core.js.map +1 -1
- package/dist/ssr/intl/messages.js +10 -0
- package/dist/ssr/intl/messages.js.map +1 -1
- package/dist/ssr/layout/MobileShell.js +48 -6
- package/dist/ssr/layout/MobileShell.js.map +1 -1
- package/dist/ssr/layout/TabBar.js +3 -2
- package/dist/ssr/layout/TabBar.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/content/MarkdownView.d.ts +6 -2
- package/dist/types/content/index.d.ts +1 -0
- package/dist/types/content/markdown-info-blocks.d.ts +67 -0
- package/dist/types/intl/messages.d.ts +5 -0
- package/dist/types/layout/TabBar.d.ts +4 -1
- package/package.json +1 -1
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
import { Lexer, Tokenizer } from "marked";
|
|
2
|
+
import { resolveUiMessages } from "../intl/messages";
|
|
3
|
+
import { NOTICE_CARD_CLASSES } from "../surfaces/NoticeCard";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Markdown info blocks: one grammar and one look for every Markdown surface.
|
|
7
|
+
*
|
|
8
|
+
* ```markdown
|
|
9
|
+
* :::warning Before deleting
|
|
10
|
+
* Deleting an item cannot be undone.
|
|
11
|
+
* :::
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* The opening line holds `:::`, a type in any letter case, and an optional
|
|
15
|
+
* plain-text title. The block ends at a line holding only `:::`, indented no
|
|
16
|
+
* deeper than the opener; code, lists, quotes, and HTML inside the body cannot
|
|
17
|
+
* end it. The body is ordinary Markdown. A block that is never closed stays
|
|
18
|
+
* ordinary text.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
const TONES = {
|
|
22
|
+
note: "neutral",
|
|
23
|
+
info: "info",
|
|
24
|
+
success: "success",
|
|
25
|
+
warning: "warning",
|
|
26
|
+
danger: "danger"
|
|
27
|
+
};
|
|
28
|
+
const OPENER = /^( {0,3}):::(note|info|success|warning|danger)(?:[ \t]+(.*?))?[ \t]*$/i;
|
|
29
|
+
const START = /^ {0,3}:::(?:note|info|success|warning|danger)(?=[ \t\n]|$)/i;
|
|
30
|
+
const OPENERS = /(?<=^|\n) {0,3}:::(?:note|info|success|warning|danger)(?=[ \t\n]|$)/gi;
|
|
31
|
+
const CLOSING = /^( {0,3}):::[ \t]*$/;
|
|
32
|
+
const FENCE = /^( *)(`{3,}|~{3,})(.*)$/;
|
|
33
|
+
const LABELS = {
|
|
34
|
+
note: t => t.infoBlockNote,
|
|
35
|
+
info: t => t.infoBlockInfo,
|
|
36
|
+
success: t => t.infoBlockSuccess,
|
|
37
|
+
warning: t => t.infoBlockWarning,
|
|
38
|
+
danger: t => t.infoBlockDanger
|
|
39
|
+
};
|
|
40
|
+
const escapeHtml = value => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
41
|
+
const lineEnd = (source, from) => {
|
|
42
|
+
const end = source.indexOf("\n", from);
|
|
43
|
+
return end < 0 ? source.length : end;
|
|
44
|
+
};
|
|
45
|
+
const closes = (line, indent) => {
|
|
46
|
+
const closing = CLOSING.exec(line);
|
|
47
|
+
return !!closing && closing[1].length <= indent;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/** Column where a list item's text starts, as CommonMark counts it. */
|
|
51
|
+
const itemTextIndent = raw => {
|
|
52
|
+
const [, bullet = "", gap = ""] = /^( {0,3}(?:[-+*]|\d{1,9}[.)]))( *)/.exec(raw) ?? [];
|
|
53
|
+
return bullet.length + (gap.length >= 1 && gap.length <= 4 && raw[bullet.length + gap.length] !== "\n" ? gap.length : 1);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Offset of the block's closing line inside a list or quote, or -1. Lazy
|
|
58
|
+
* paragraph lines may hold it; a list item's own fenced code cannot.
|
|
59
|
+
*/
|
|
60
|
+
const closingLineIn = (token, indent) => {
|
|
61
|
+
if (token.type !== "list" && token.type !== "blockquote") return -1;
|
|
62
|
+
const items = token.type === "list" ? token.items : [];
|
|
63
|
+
let item = -1;
|
|
64
|
+
let itemStart = 0;
|
|
65
|
+
let itemEnd = 0;
|
|
66
|
+
let text = 0;
|
|
67
|
+
let fence = "";
|
|
68
|
+
for (let from = 0; from < token.raw.length;) {
|
|
69
|
+
while (item + 1 < items.length && from >= itemEnd) {
|
|
70
|
+
item++;
|
|
71
|
+
itemStart = itemEnd;
|
|
72
|
+
itemEnd += items[item].raw.length;
|
|
73
|
+
text = itemTextIndent(items[item].raw);
|
|
74
|
+
fence = "";
|
|
75
|
+
}
|
|
76
|
+
const end = lineEnd(token.raw, from);
|
|
77
|
+
const line = token.raw.slice(from, end);
|
|
78
|
+
// A line indented less than the item's text has left the item and its fence.
|
|
79
|
+
if (fence && line.trim() && line.length - line.trimStart().length < text) fence = "";
|
|
80
|
+
// The first line of an item carries its bullet where the text would be indented.
|
|
81
|
+
const marker = items.length ? FENCE.exec(from === itemStart ? " ".repeat(text) + line.slice(text) : line) : null;
|
|
82
|
+
if (fence) {
|
|
83
|
+
if (marker && marker[2][0] === fence[0] && marker[2].length >= fence.length && !marker[3].trim()) fence = "";
|
|
84
|
+
} else if (marker && marker[1].length >= text && marker[1].length <= text + 3 && !(marker[2][0] === "`" && marker[3].includes("`"))) {
|
|
85
|
+
fence = marker[2];
|
|
86
|
+
} else if (closes(line, indent)) {
|
|
87
|
+
return from;
|
|
88
|
+
}
|
|
89
|
+
from = end + 1;
|
|
90
|
+
}
|
|
91
|
+
return -1;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
/** Whether `line` starts a block of its own after a paragraph line instead of continuing the paragraph, as marked decides. */
|
|
95
|
+
const interruptsParagraph = line => Lexer.rules.block.gfm.paragraph.exec(`x\n${line}\n`)?.[0] === "x";
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Reads info blocks in one `\n`-separated source. The opening line reads like
|
|
99
|
+
* a paragraph line, so the body continues it: only a block that may interrupt
|
|
100
|
+
* a paragraph, such as a fence, a list, a quote, or block HTML, hides its
|
|
101
|
+
* lines from the closing line. A scan's only state is its line and whether a
|
|
102
|
+
* paragraph is open there, so a later scan that reaches a line an earlier one
|
|
103
|
+
* passed ends the same way; `outcomes` remembers that, which keeps reading
|
|
104
|
+
* many openers of one document linear.
|
|
105
|
+
*/
|
|
106
|
+
const infoBlockReader = source => {
|
|
107
|
+
const outcomes = new Map();
|
|
108
|
+
let tokenizer;
|
|
109
|
+
|
|
110
|
+
/** Code, lists, quotes, and HTML whose lines belong to the body even when one of them reads `:::`. */
|
|
111
|
+
const container = (offset, line, paragraph) => {
|
|
112
|
+
const kind = /^(?: {4}| {0,3}\t)/.test(line) ? "code" : /^ {0,3}(?:`{3,}|~{3,})/.test(line) ? "fences" : /^ {0,3}(?:[-+*][ \t]|\d{1,9}[.)][ \t])/.test(line) ? "list" : /^ {0,3}>/.test(line) ? "blockquote" : /^ {0,3}</.test(line) ? "html" : undefined;
|
|
113
|
+
if (!kind || paragraph && !interruptsParagraph(line)) return undefined;
|
|
114
|
+
if (!tokenizer) {
|
|
115
|
+
// One tokenizer per document: its lexer queues inline work that nothing drains.
|
|
116
|
+
tokenizer = new Tokenizer({
|
|
117
|
+
gfm: true
|
|
118
|
+
});
|
|
119
|
+
new Lexer({
|
|
120
|
+
gfm: true,
|
|
121
|
+
tokenizer
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
return tokenizer[kind](source.slice(offset));
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
/** Offset of the closing line for a body that starts at `start`, or -1 when the block never closes. */
|
|
128
|
+
const closingLine = (start, indent) => {
|
|
129
|
+
const passed = [];
|
|
130
|
+
let offset = start;
|
|
131
|
+
let paragraph = true;
|
|
132
|
+
let result = -1;
|
|
133
|
+
while (offset < source.length) {
|
|
134
|
+
const key = offset * 8 + indent * 2 + (paragraph ? 1 : 0);
|
|
135
|
+
const known = outcomes.get(key);
|
|
136
|
+
if (known !== undefined) {
|
|
137
|
+
result = known;
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
passed.push(key);
|
|
141
|
+
const end = lineEnd(source, offset);
|
|
142
|
+
const line = source.slice(offset, end);
|
|
143
|
+
if (closes(line, indent)) {
|
|
144
|
+
result = offset;
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
const token = container(offset, line, paragraph);
|
|
148
|
+
if (token) {
|
|
149
|
+
const closing = closingLineIn(token, indent);
|
|
150
|
+
const length = closing < 0 ? token.raw.length : closing;
|
|
151
|
+
if (length > 0) {
|
|
152
|
+
offset += length;
|
|
153
|
+
paragraph = false;
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// A blank line ends a paragraph; any other line continues or starts one.
|
|
158
|
+
paragraph = line.trim() !== "";
|
|
159
|
+
offset = Math.min(end + 1, source.length);
|
|
160
|
+
}
|
|
161
|
+
for (const key of passed) outcomes.set(key, result);
|
|
162
|
+
return result;
|
|
163
|
+
};
|
|
164
|
+
return offset => {
|
|
165
|
+
const firstEnd = lineEnd(source, offset);
|
|
166
|
+
const opener = OPENER.exec(source.slice(offset, firstEnd));
|
|
167
|
+
if (!opener) return null;
|
|
168
|
+
const indent = opener[1].length;
|
|
169
|
+
const type = opener[2].toLowerCase();
|
|
170
|
+
const title = opener[3]?.trim() || undefined;
|
|
171
|
+
const bodyStart = Math.min(firstEnd + 1, source.length);
|
|
172
|
+
const closing = closingLine(bodyStart, indent);
|
|
173
|
+
if (closing < 0) return {
|
|
174
|
+
type,
|
|
175
|
+
title,
|
|
176
|
+
body: source.slice(bodyStart),
|
|
177
|
+
length: source.length - offset,
|
|
178
|
+
closed: false
|
|
179
|
+
};
|
|
180
|
+
const body = source.slice(bodyStart, closing).replace(/\n$/, "");
|
|
181
|
+
return {
|
|
182
|
+
type,
|
|
183
|
+
title,
|
|
184
|
+
body,
|
|
185
|
+
length: Math.min(lineEnd(source, closing) + 1, source.length) - offset,
|
|
186
|
+
closed: true
|
|
187
|
+
};
|
|
188
|
+
};
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Reads the info block that starts `source`. Returns `null` when the first
|
|
193
|
+
* line is not an info-block opener. Applications with their own Markdown
|
|
194
|
+
* pipeline use this to recognize exactly the blocks `MarkdownView` renders.
|
|
195
|
+
* Any line endings are accepted; `length` counts `source` as given.
|
|
196
|
+
*/
|
|
197
|
+
export const scanMarkdownInfoBlock = source => {
|
|
198
|
+
const normalized = source.replace(/\r\n?/g, "\n");
|
|
199
|
+
const block = infoBlockReader(normalized)(0);
|
|
200
|
+
if (!block || normalized.length === source.length) return block;
|
|
201
|
+
// Only `\r\n` shortens the source; count each one twice up to the block's end.
|
|
202
|
+
let length = 0;
|
|
203
|
+
for (let index = 0; index < block.length; index++) length += source[length] === "\r" && source[length + 1] === "\n" ? 2 : 1;
|
|
204
|
+
return {
|
|
205
|
+
...block,
|
|
206
|
+
length
|
|
207
|
+
};
|
|
208
|
+
};
|
|
209
|
+
const renderBlock = (input, messages) => {
|
|
210
|
+
const name = input.title ? `<p class="${NOTICE_CARD_CLASSES.title}">${escapeHtml(input.title)}</p>` : `<span class="k2b-sr-only">${escapeHtml(LABELS[input.type](messages))}: </span>`;
|
|
211
|
+
return `<aside class="${NOTICE_CARD_CLASSES.root}" data-tone="${TONES[input.type]}" role="note">${name}<div class="${NOTICE_CARD_CLASSES.body}">${input.bodyHtml}</div></aside>`;
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Renders an info block as the calm `NoticeCard`: the tone tints the surface,
|
|
216
|
+
* the text stays neutral, and there is no icon. A title is the visible heading
|
|
217
|
+
* and names the block; without one, the localized type name is announced to
|
|
218
|
+
* screen readers only.
|
|
219
|
+
*/
|
|
220
|
+
export const renderMarkdownInfoBlock = input => renderBlock(input, resolveUiMessages(input.locale));
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* What one `marked` lexer run knows about its document: the opening lines, the
|
|
224
|
+
* blocks read so far, the length of the last top-level source, and the extent
|
|
225
|
+
* of the last top-level paragraph `start` measured.
|
|
226
|
+
*/
|
|
227
|
+
|
|
228
|
+
const documents = new WeakMap();
|
|
229
|
+
|
|
230
|
+
/** The closed block that starts at `offset`, read once per document. */
|
|
231
|
+
const closedBlockAt = (document, offset) => {
|
|
232
|
+
let block = document.blocks.get(offset);
|
|
233
|
+
if (block === undefined) {
|
|
234
|
+
const read = document.read(offset);
|
|
235
|
+
block = read?.closed ? read : null;
|
|
236
|
+
document.blocks.set(offset, block);
|
|
237
|
+
}
|
|
238
|
+
return block;
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
/** Index of the first of the ascending `offsets` at or after `from`. */
|
|
242
|
+
const firstAtOrAfter = (offsets, from) => {
|
|
243
|
+
let low = 0;
|
|
244
|
+
let high = offsets.length;
|
|
245
|
+
while (low < high) {
|
|
246
|
+
const middle = low + high >> 1;
|
|
247
|
+
if (offsets[middle] < from) low = middle + 1;else high = middle;
|
|
248
|
+
}
|
|
249
|
+
return low;
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* The first closed block after the top-level `position` inside the paragraph
|
|
254
|
+
* that would start there. Openers further away cannot end that paragraph, and
|
|
255
|
+
* a paragraph that starts inside the last measured one ends where it ends.
|
|
256
|
+
*/
|
|
257
|
+
const nextBlockStart = (document, position, rules) => {
|
|
258
|
+
if (position < document.paragraph.start || position >= document.paragraph.end) {
|
|
259
|
+
const extent = rules.exec(document.source.slice(position))?.[0].length ?? 0;
|
|
260
|
+
document.paragraph = {
|
|
261
|
+
start: position,
|
|
262
|
+
end: position + extent
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
for (let index = firstAtOrAfter(document.openers, position + 1); index < document.openers.length; index++) {
|
|
266
|
+
const offset = document.openers[index];
|
|
267
|
+
if (offset >= document.paragraph.end) return undefined;
|
|
268
|
+
if (closedBlockAt(document, offset)) return offset;
|
|
269
|
+
}
|
|
270
|
+
return undefined;
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
/** The paragraph rule of the lexer's own flavour. */
|
|
274
|
+
const paragraphRule = lexer => Lexer.rules.block[lexer.options.pedantic ? "pedantic" : lexer.options.gfm ? "gfm" : "normal"].paragraph;
|
|
275
|
+
const createExtension = messages => {
|
|
276
|
+
const extension = {
|
|
277
|
+
name: "markdownInfoBlock",
|
|
278
|
+
level: "block",
|
|
279
|
+
// marked ends a top-level paragraph where `start` points. Only a block
|
|
280
|
+
// that closes renders, so `start` points at the first one inside the
|
|
281
|
+
// paragraph; a split anywhere else would only make marked lex the rest of
|
|
282
|
+
// the document again.
|
|
283
|
+
start(source) {
|
|
284
|
+
const document = documents.get(this.lexer);
|
|
285
|
+
// marked asks right after the tokenizer below ran at the same top-level position.
|
|
286
|
+
if (!document || source.length + 1 !== document.top) return undefined;
|
|
287
|
+
const position = document.source.length - source.length - 1;
|
|
288
|
+
const next = nextBlockStart(document, position, paragraphRule(this.lexer));
|
|
289
|
+
return next === undefined ? undefined : next - position - 1;
|
|
290
|
+
},
|
|
291
|
+
tokenizer(source, tokens) {
|
|
292
|
+
let document = documents.get(this.lexer);
|
|
293
|
+
if (tokens !== this.lexer.tokens) {
|
|
294
|
+
// Nested sources are rewritten text, not the rest of the document.
|
|
295
|
+
if (document) document.top = -1;
|
|
296
|
+
return undefined;
|
|
297
|
+
}
|
|
298
|
+
// The first top-level call sees the whole document; later ones see what is left of it.
|
|
299
|
+
if (!document) {
|
|
300
|
+
document = {
|
|
301
|
+
source,
|
|
302
|
+
read: infoBlockReader(source),
|
|
303
|
+
openers: Array.from(source.matchAll(OPENERS), opener => opener.index),
|
|
304
|
+
blocks: new Map(),
|
|
305
|
+
top: source.length,
|
|
306
|
+
paragraph: {
|
|
307
|
+
start: -1,
|
|
308
|
+
end: -1
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
documents.set(this.lexer, document);
|
|
312
|
+
}
|
|
313
|
+
document.top = source.length;
|
|
314
|
+
if (!START.test(source)) return undefined;
|
|
315
|
+
const block = closedBlockAt(document, document.source.length - source.length);
|
|
316
|
+
if (!block) return undefined;
|
|
317
|
+
return {
|
|
318
|
+
type: "markdownInfoBlock",
|
|
319
|
+
raw: source.slice(0, block.length),
|
|
320
|
+
blockType: block.type,
|
|
321
|
+
title: block.title,
|
|
322
|
+
tokens: this.lexer.blockTokens(block.body, [])
|
|
323
|
+
};
|
|
324
|
+
},
|
|
325
|
+
renderer(token) {
|
|
326
|
+
return renderBlock({
|
|
327
|
+
type: token.blockType,
|
|
328
|
+
title: token.title,
|
|
329
|
+
bodyHtml: this.parser.parse(token.tokens ?? [])
|
|
330
|
+
}, messages);
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
return {
|
|
334
|
+
extensions: [extension],
|
|
335
|
+
tokenizer: {
|
|
336
|
+
// A setext heading's text is a paragraph, so it ends before a block as
|
|
337
|
+
// well; marked does not clip it at `start` itself.
|
|
338
|
+
lheading(source) {
|
|
339
|
+
const document = documents.get(this.lexer);
|
|
340
|
+
if (!document || source.length !== document.top) return false;
|
|
341
|
+
const position = document.source.length - source.length;
|
|
342
|
+
const next = nextBlockStart(document, position, paragraphRule(this.lexer));
|
|
343
|
+
return next === undefined ? false : Tokenizer.prototype.lheading.call(this, source.slice(0, next - position));
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
};
|
|
348
|
+
const extensions = new WeakMap();
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* `marked` extension for info blocks at the top level of a document. Blocks
|
|
352
|
+
* inside lists, quotes, or another block stay ordinary text. The body goes
|
|
353
|
+
* through the host's own Markdown renderer, so its escaping and link rules
|
|
354
|
+
* apply unchanged. Locales that share a UI message catalog get the same
|
|
355
|
+
* extension, so a host may cache one `marked` instance per extension.
|
|
356
|
+
*/
|
|
357
|
+
export const markdownInfoBlocks = (options = {}) => {
|
|
358
|
+
const messages = resolveUiMessages(options.locale);
|
|
359
|
+
const extension = extensions.get(messages) ?? createExtension(messages);
|
|
360
|
+
extensions.set(messages, extension);
|
|
361
|
+
return extension;
|
|
362
|
+
};
|
|
363
|
+
//# sourceMappingURL=markdown-info-blocks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["content/markdown-info-blocks.ts"],"sourcesContent":["import { Lexer, type MarkedExtension, Tokenizer, type TokenizerAndRendererExtension } from \"marked\";\nimport { resolveUiMessages, type UiMessages } from \"../intl/messages\";\nimport { NOTICE_CARD_CLASSES, type NoticeTone } from \"../surfaces/NoticeCard\";\n\n/**\n * Markdown info blocks: one grammar and one look for every Markdown surface.\n *\n * ```markdown\n * :::warning Before deleting\n * Deleting an item cannot be undone.\n * :::\n * ```\n *\n * The opening line holds `:::`, a type in any letter case, and an optional\n * plain-text title. The block ends at a line holding only `:::`, indented no\n * deeper than the opener; code, lists, quotes, and HTML inside the body cannot\n * end it. The body is ordinary Markdown. A block that is never closed stays\n * ordinary text.\n */\n\nconst TONES = {\n note: \"neutral\",\n info: \"info\",\n success: \"success\",\n warning: \"warning\",\n danger: \"danger\",\n} as const satisfies Record<string, NoticeTone>;\n\nexport type MarkdownInfoBlockType = keyof typeof TONES;\n\nexport type MarkdownInfoBlock = {\n type: MarkdownInfoBlockType;\n /** Plain-text title from the opening line. */\n title?: string;\n /** Raw Markdown between the opening and closing lines, with `\\n` line breaks. */\n body: string;\n /** Source length through the closing line, or the whole source when the block is not closed. */\n length: number;\n closed: boolean;\n};\n\nexport type MarkdownInfoBlockRenderInput = {\n type: MarkdownInfoBlockType;\n title?: string;\n /** Already rendered body HTML. The caller owns its sanitization. */\n bodyHtml: string;\n /** Locale for the screen-reader name of an untitled block. */\n locale?: string;\n};\n\nconst OPENER = /^( {0,3}):::(note|info|success|warning|danger)(?:[ \\t]+(.*?))?[ \\t]*$/i;\nconst START = /^ {0,3}:::(?:note|info|success|warning|danger)(?=[ \\t\\n]|$)/i;\nconst OPENERS = /(?<=^|\\n) {0,3}:::(?:note|info|success|warning|danger)(?=[ \\t\\n]|$)/gi;\nconst CLOSING = /^( {0,3}):::[ \\t]*$/;\nconst FENCE = /^( *)(`{3,}|~{3,})(.*)$/;\n\ntype ContainerKind = \"code\" | \"fences\" | \"list\" | \"blockquote\" | \"html\";\ntype ContainerToken = NonNullable<ReturnType<Tokenizer[ContainerKind]>>;\n\nconst LABELS: Record<MarkdownInfoBlockType, (t: UiMessages) => string> = {\n note: (t) => t.infoBlockNote,\n info: (t) => t.infoBlockInfo,\n success: (t) => t.infoBlockSuccess,\n warning: (t) => t.infoBlockWarning,\n danger: (t) => t.infoBlockDanger,\n};\n\nconst escapeHtml = (value: string): string =>\n value.replaceAll(\"&\", \"&\").replaceAll(\"<\", \"<\").replaceAll(\">\", \">\").replaceAll('\"', \""\").replaceAll(\"'\", \"'\");\n\nconst lineEnd = (source: string, from: number): number => {\n const end = source.indexOf(\"\\n\", from);\n return end < 0 ? source.length : end;\n};\n\nconst closes = (line: string, indent: number): boolean => {\n const closing = CLOSING.exec(line);\n return !!closing && closing[1]!.length <= indent;\n};\n\n/** Column where a list item's text starts, as CommonMark counts it. */\nconst itemTextIndent = (raw: string): number => {\n const [, bullet = \"\", gap = \"\"] = /^( {0,3}(?:[-+*]|\\d{1,9}[.)]))( *)/.exec(raw) ?? [];\n return bullet.length + (gap.length >= 1 && gap.length <= 4 && raw[bullet.length + gap.length] !== \"\\n\" ? gap.length : 1);\n};\n\n/**\n * Offset of the block's closing line inside a list or quote, or -1. Lazy\n * paragraph lines may hold it; a list item's own fenced code cannot.\n */\nconst closingLineIn = (token: ContainerToken, indent: number): number => {\n if (token.type !== \"list\" && token.type !== \"blockquote\") return -1;\n const items = token.type === \"list\" ? token.items : [];\n let item = -1;\n let itemStart = 0;\n let itemEnd = 0;\n let text = 0;\n let fence = \"\";\n for (let from = 0; from < token.raw.length; ) {\n while (item + 1 < items.length && from >= itemEnd) {\n item++;\n itemStart = itemEnd;\n itemEnd += items[item]!.raw.length;\n text = itemTextIndent(items[item]!.raw);\n fence = \"\";\n }\n const end = lineEnd(token.raw, from);\n const line = token.raw.slice(from, end);\n // A line indented less than the item's text has left the item and its fence.\n if (fence && line.trim() && line.length - line.trimStart().length < text) fence = \"\";\n // The first line of an item carries its bullet where the text would be indented.\n const marker = items.length ? FENCE.exec(from === itemStart ? \" \".repeat(text) + line.slice(text) : line) : null;\n if (fence) {\n if (marker && marker[2]![0] === fence[0] && marker[2]!.length >= fence.length && !marker[3]!.trim()) fence = \"\";\n } else if (\n marker &&\n marker[1]!.length >= text &&\n marker[1]!.length <= text + 3 &&\n !(marker[2]![0] === \"`\" && marker[3]!.includes(\"`\"))\n ) {\n fence = marker[2]!;\n } else if (closes(line, indent)) {\n return from;\n }\n from = end + 1;\n }\n return -1;\n};\n\n/** Whether `line` starts a block of its own after a paragraph line instead of continuing the paragraph, as marked decides. */\nconst interruptsParagraph = (line: string): boolean => Lexer.rules.block.gfm.paragraph.exec(`x\\n${line}\\n`)?.[0] === \"x\";\n\n/**\n * Reads info blocks in one `\\n`-separated source. The opening line reads like\n * a paragraph line, so the body continues it: only a block that may interrupt\n * a paragraph, such as a fence, a list, a quote, or block HTML, hides its\n * lines from the closing line. A scan's only state is its line and whether a\n * paragraph is open there, so a later scan that reaches a line an earlier one\n * passed ends the same way; `outcomes` remembers that, which keeps reading\n * many openers of one document linear.\n */\nconst infoBlockReader = (source: string) => {\n const outcomes = new Map<number, number>();\n let tokenizer: Tokenizer | undefined;\n\n /** Code, lists, quotes, and HTML whose lines belong to the body even when one of them reads `:::`. */\n const container = (offset: number, line: string, paragraph: boolean): ContainerToken | undefined => {\n const kind: ContainerKind | undefined = /^(?: {4}| {0,3}\\t)/.test(line)\n ? \"code\"\n : /^ {0,3}(?:`{3,}|~{3,})/.test(line)\n ? \"fences\"\n : /^ {0,3}(?:[-+*][ \\t]|\\d{1,9}[.)][ \\t])/.test(line)\n ? \"list\"\n : /^ {0,3}>/.test(line)\n ? \"blockquote\"\n : /^ {0,3}</.test(line)\n ? \"html\"\n : undefined;\n if (!kind || (paragraph && !interruptsParagraph(line))) return undefined;\n if (!tokenizer) {\n // One tokenizer per document: its lexer queues inline work that nothing drains.\n tokenizer = new Tokenizer({ gfm: true });\n new Lexer({ gfm: true, tokenizer });\n }\n return tokenizer[kind](source.slice(offset));\n };\n\n /** Offset of the closing line for a body that starts at `start`, or -1 when the block never closes. */\n const closingLine = (start: number, indent: number): number => {\n const passed: number[] = [];\n let offset = start;\n let paragraph = true;\n let result = -1;\n while (offset < source.length) {\n const key = offset * 8 + indent * 2 + (paragraph ? 1 : 0);\n const known = outcomes.get(key);\n if (known !== undefined) {\n result = known;\n break;\n }\n passed.push(key);\n const end = lineEnd(source, offset);\n const line = source.slice(offset, end);\n if (closes(line, indent)) {\n result = offset;\n break;\n }\n const token = container(offset, line, paragraph);\n if (token) {\n const closing = closingLineIn(token, indent);\n const length = closing < 0 ? token.raw.length : closing;\n if (length > 0) {\n offset += length;\n paragraph = false;\n continue;\n }\n }\n // A blank line ends a paragraph; any other line continues or starts one.\n paragraph = line.trim() !== \"\";\n offset = Math.min(end + 1, source.length);\n }\n for (const key of passed) outcomes.set(key, result);\n return result;\n };\n\n return (offset: number): MarkdownInfoBlock | null => {\n const firstEnd = lineEnd(source, offset);\n const opener = OPENER.exec(source.slice(offset, firstEnd));\n if (!opener) return null;\n const indent = opener[1]!.length;\n const type = opener[2]!.toLowerCase() as MarkdownInfoBlockType;\n const title = opener[3]?.trim() || undefined;\n const bodyStart = Math.min(firstEnd + 1, source.length);\n const closing = closingLine(bodyStart, indent);\n if (closing < 0) return { type, title, body: source.slice(bodyStart), length: source.length - offset, closed: false };\n const body = source.slice(bodyStart, closing).replace(/\\n$/, \"\");\n return { type, title, body, length: Math.min(lineEnd(source, closing) + 1, source.length) - offset, closed: true };\n };\n};\n\n/**\n * Reads the info block that starts `source`. Returns `null` when the first\n * line is not an info-block opener. Applications with their own Markdown\n * pipeline use this to recognize exactly the blocks `MarkdownView` renders.\n * Any line endings are accepted; `length` counts `source` as given.\n */\nexport const scanMarkdownInfoBlock = (source: string): MarkdownInfoBlock | null => {\n const normalized = source.replace(/\\r\\n?/g, \"\\n\");\n const block = infoBlockReader(normalized)(0);\n if (!block || normalized.length === source.length) return block;\n // Only `\\r\\n` shortens the source; count each one twice up to the block's end.\n let length = 0;\n for (let index = 0; index < block.length; index++) length += source[length] === \"\\r\" && source[length + 1] === \"\\n\" ? 2 : 1;\n return { ...block, length };\n};\n\nconst renderBlock = (input: Omit<MarkdownInfoBlockRenderInput, \"locale\">, messages: UiMessages): string => {\n const name = input.title\n ? `<p class=\"${NOTICE_CARD_CLASSES.title}\">${escapeHtml(input.title)}</p>`\n : `<span class=\"k2b-sr-only\">${escapeHtml(LABELS[input.type](messages))}: </span>`;\n return `<aside class=\"${NOTICE_CARD_CLASSES.root}\" data-tone=\"${TONES[input.type]}\" role=\"note\">${name}<div class=\"${NOTICE_CARD_CLASSES.body}\">${input.bodyHtml}</div></aside>`;\n};\n\n/**\n * Renders an info block as the calm `NoticeCard`: the tone tints the surface,\n * the text stays neutral, and there is no icon. A title is the visible heading\n * and names the block; without one, the localized type name is announced to\n * screen readers only.\n */\nexport const renderMarkdownInfoBlock = (input: MarkdownInfoBlockRenderInput): string => renderBlock(input, resolveUiMessages(input.locale));\n\n/**\n * What one `marked` lexer run knows about its document: the opening lines, the\n * blocks read so far, the length of the last top-level source, and the extent\n * of the last top-level paragraph `start` measured.\n */\ntype DocumentState = {\n source: string;\n read: (offset: number) => MarkdownInfoBlock | null;\n openers: number[];\n blocks: Map<number, MarkdownInfoBlock | null>;\n top: number;\n paragraph: { start: number; end: number };\n};\n\nconst documents = new WeakMap<object, DocumentState>();\n\n/** The closed block that starts at `offset`, read once per document. */\nconst closedBlockAt = (document: DocumentState, offset: number): MarkdownInfoBlock | null => {\n let block = document.blocks.get(offset);\n if (block === undefined) {\n const read = document.read(offset);\n block = read?.closed ? read : null;\n document.blocks.set(offset, block);\n }\n return block;\n};\n\n/** Index of the first of the ascending `offsets` at or after `from`. */\nconst firstAtOrAfter = (offsets: readonly number[], from: number): number => {\n let low = 0;\n let high = offsets.length;\n while (low < high) {\n const middle = (low + high) >> 1;\n if (offsets[middle]! < from) low = middle + 1;\n else high = middle;\n }\n return low;\n};\n\n/**\n * The first closed block after the top-level `position` inside the paragraph\n * that would start there. Openers further away cannot end that paragraph, and\n * a paragraph that starts inside the last measured one ends where it ends.\n */\nconst nextBlockStart = (document: DocumentState, position: number, rules: RegExp): number | undefined => {\n if (position < document.paragraph.start || position >= document.paragraph.end) {\n const extent = rules.exec(document.source.slice(position))?.[0].length ?? 0;\n document.paragraph = { start: position, end: position + extent };\n }\n for (let index = firstAtOrAfter(document.openers, position + 1); index < document.openers.length; index++) {\n const offset = document.openers[index]!;\n if (offset >= document.paragraph.end) return undefined;\n if (closedBlockAt(document, offset)) return offset;\n }\n return undefined;\n};\n\n/** The paragraph rule of the lexer's own flavour. */\nconst paragraphRule = (lexer: Lexer): RegExp =>\n Lexer.rules.block[lexer.options.pedantic ? \"pedantic\" : lexer.options.gfm ? \"gfm\" : \"normal\"].paragraph;\n\nconst createExtension = (messages: UiMessages): MarkedExtension => {\n const extension: TokenizerAndRendererExtension = {\n name: \"markdownInfoBlock\",\n level: \"block\",\n // marked ends a top-level paragraph where `start` points. Only a block\n // that closes renders, so `start` points at the first one inside the\n // paragraph; a split anywhere else would only make marked lex the rest of\n // the document again.\n start(source) {\n const document = documents.get(this.lexer);\n // marked asks right after the tokenizer below ran at the same top-level position.\n if (!document || source.length + 1 !== document.top) return undefined;\n const position = document.source.length - source.length - 1;\n const next = nextBlockStart(document, position, paragraphRule(this.lexer));\n return next === undefined ? undefined : next - position - 1;\n },\n tokenizer(source, tokens) {\n let document = documents.get(this.lexer);\n if (tokens !== this.lexer.tokens) {\n // Nested sources are rewritten text, not the rest of the document.\n if (document) document.top = -1;\n return undefined;\n }\n // The first top-level call sees the whole document; later ones see what is left of it.\n if (!document) {\n document = {\n source,\n read: infoBlockReader(source),\n openers: Array.from(source.matchAll(OPENERS), (opener) => opener.index),\n blocks: new Map(),\n top: source.length,\n paragraph: { start: -1, end: -1 },\n };\n documents.set(this.lexer, document);\n }\n document.top = source.length;\n if (!START.test(source)) return undefined;\n const block = closedBlockAt(document, document.source.length - source.length);\n if (!block) return undefined;\n return {\n type: \"markdownInfoBlock\",\n raw: source.slice(0, block.length),\n blockType: block.type,\n title: block.title,\n tokens: this.lexer.blockTokens(block.body, []),\n };\n },\n renderer(token) {\n return renderBlock(\n {\n type: token.blockType as MarkdownInfoBlockType,\n title: token.title as string | undefined,\n bodyHtml: this.parser.parse(token.tokens ?? []),\n },\n messages,\n );\n },\n };\n return {\n extensions: [extension],\n tokenizer: {\n // A setext heading's text is a paragraph, so it ends before a block as\n // well; marked does not clip it at `start` itself.\n lheading(source) {\n const document = documents.get(this.lexer);\n if (!document || source.length !== document.top) return false;\n const position = document.source.length - source.length;\n const next = nextBlockStart(document, position, paragraphRule(this.lexer));\n return next === undefined ? false : Tokenizer.prototype.lheading.call(this, source.slice(0, next - position));\n },\n },\n };\n};\n\nconst extensions = new WeakMap<UiMessages, MarkedExtension>();\n\n/**\n * `marked` extension for info blocks at the top level of a document. Blocks\n * inside lists, quotes, or another block stay ordinary text. The body goes\n * through the host's own Markdown renderer, so its escaping and link rules\n * apply unchanged. Locales that share a UI message catalog get the same\n * extension, so a host may cache one `marked` instance per extension.\n */\nexport const markdownInfoBlocks = (options: { locale?: string } = {}): MarkedExtension => {\n const messages = resolveUiMessages(options.locale);\n const extension = extensions.get(messages) ?? createExtension(messages);\n extensions.set(messages, extension);\n return extension;\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -373,8 +373,13 @@ export const createDialogCore = () => {
|
|
|
373
373
|
once: true
|
|
374
374
|
});
|
|
375
375
|
if (options.signal?.aborted) abort();
|
|
376
|
+
// Where opening left focus, the native dialog's own pick included. Focus that the content or a person moved
|
|
377
|
+
// before the next frame stays: a browser can hold that frame back while keys already arrive.
|
|
378
|
+
const opened = document.activeElement;
|
|
376
379
|
schedule(() => {
|
|
377
|
-
if (state.stack[state.stack.length - 1]
|
|
380
|
+
if (state.stack[state.stack.length - 1] !== entry) return;
|
|
381
|
+
if (document.activeElement !== opened && !focusUnclaimed(dialog)) return;
|
|
382
|
+
resolveInitialFocusTarget(entry, dialog)?.focus();
|
|
378
383
|
});
|
|
379
384
|
} catch (error) {
|
|
380
385
|
entry.resolve = undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["feedback/dialog-core.ts"],"sourcesContent":["import type { JSX } from \"solid-js\";\nimport { render } from \"solid-js/web\";\nimport { returnFocus, ringOnReturn } from \"../internal/focus-return\";\nimport { getK2bPortalRoot } from \"../internal/portal\";\nimport { resolveUiMessages } from \"../intl/messages\";\nimport { isPointInsideToast } from \"./toast\";\n\nexport type DialogClose<T> = (result?: T) => void;\n\nexport type OpenDialogOptions = {\n /** Close only this dialog when its owning operation is cancelled. */\n signal?: AbortSignal;\n panelClassName?: string;\n contentClassName?: string;\n initialFocus?: \"first-input\" | \"none\" | ((dialog: HTMLDialogElement) => HTMLElement | null);\n cancelBehavior?: \"resolve-undefined\" | \"ignore\";\n ariaLabel?: string;\n /**\n * Add a same-URL history entry while the dialog is open, so the browser's or the phone's Back closes the dialog\n * instead of leaving the page. Closing the dialog removes the entry again; the returned promise settles after that.\n */\n history?: boolean;\n};\n\nexport type DialogRender<T> = (\n close: DialogClose<T>,\n context: {\n dialog: HTMLDialogElement;\n /** Switch this entry between a modal and a modeless window without remounting. */\n setModal: (modal: boolean) => void;\n /** Set viewport coordinates, or restore the panel stylesheet position with null. */\n setPosition: (position: { x: number; y: number } | null) => void;\n /** Route Escape/backdrop through the same guarded handler as Cancel and X. */\n setDismissHandler: (handler: () => void | Promise<void>) => void;\n /** Request dismissal through this entry's cancellation policy and guard. */\n requestDismiss: () => Promise<void>;\n },\n) => JSX.Element;\n\nexport type DialogCore = {\n open: <T>(view: DialogRender<T>, options?: OpenDialogOptions) => Promise<T | undefined>;\n close: (result?: unknown) => void;\n isOpen: () => boolean;\n};\n\ntype DialogStackEntry = {\n container: HTMLDivElement;\n dispose?: () => void;\n resolve?: (value: unknown) => void;\n panelClassName: string;\n cancelBehavior: NonNullable<OpenDialogOptions[\"cancelBehavior\"]>;\n initialFocus: NonNullable<OpenDialogOptions[\"initialFocus\"]>;\n opener?: HTMLElement;\n openerRing: boolean;\n ariaLabel?: string;\n dismissHandler?: () => void | Promise<void>;\n dismissPending?: boolean;\n modal: boolean;\n position?: { x: number; y: number } | null;\n /** The marker of this dialog's history entry, for dialogs opened with `history`. */\n historyId?: number;\n};\n\ntype DialogState = {\n element?: HTMLDialogElement;\n modal?: boolean;\n stack: DialogStackEntry[];\n scrollLocked?: boolean;\n previousBodyOverflow?: string;\n previousHtmlOverflow?: string;\n mouseDownOnDialog?: boolean;\n connectionObserver?: MutationObserver;\n};\n\nconst DEFAULT_PANEL_CLASS = \"k2b-dialog\";\nconst DEFAULT_CONTENT_CLASS = \"k2b-dialog__viewport\";\nlet nextDialogTitleId = 0;\n/** The history state key that marks a dialog's same-URL entry. */\nconst HISTORY_MARKER = \"k2bDialog\";\n\nconst historyRecord = (): Record<string, unknown> =>\n typeof history.state === \"object\" && history.state !== null ? { ...history.state } : {};\nconst historyMarker = (): unknown => historyRecord()[HISTORY_MARKER];\n\nconst resolveInitialFocusTarget = (entry: DialogStackEntry, dialog: HTMLDialogElement): HTMLElement | null => {\n const { initialFocus } = entry;\n if (initialFocus === \"none\") return null;\n if (typeof initialFocus === \"function\") return initialFocus(dialog);\n const input = entry.container.querySelector<HTMLElement>(\n \"input:not([type='hidden']):not([disabled]), textarea:not([disabled]), select:not([disabled]), [role='combobox']:not([disabled]):not([aria-disabled='true'])\",\n );\n return (\n input ??\n entry.container.querySelector<HTMLElement>(\n \"input:not([type='hidden']):not([disabled]), textarea:not([disabled]), select:not([disabled]), button:not([disabled]), a[href], [tabindex]:not([tabindex='-1'])\",\n )\n );\n};\n\nconst applyAccessibleName = (dialog: HTMLDialogElement, entry: DialogStackEntry): void => {\n dialog.removeAttribute(\"aria-label\");\n dialog.removeAttribute(\"aria-labelledby\");\n if (entry.ariaLabel) {\n dialog.setAttribute(\"aria-label\", entry.ariaLabel);\n return;\n }\n const heading = entry.container.querySelector<HTMLElement>(\"h1, h2, h3\");\n if (!heading) {\n dialog.setAttribute(\"aria-label\", resolveUiMessages().dialog);\n return;\n }\n heading.id ||= `k2b-dialog-title-${++nextDialogTitleId}`;\n dialog.setAttribute(\"aria-labelledby\", heading.id);\n};\n\nconst schedule = (callback: () => void): void => {\n if (typeof requestAnimationFrame === \"function\") requestAnimationFrame(callback);\n else queueMicrotask(callback);\n};\n\n/**\n * Whether focus is still where closing a level left it, on the page or the\n * dialog: nothing took it before the next frame, neither a close handler nor a\n * Tab pressed right after Escape.\n */\nconst focusUnclaimed = (dialog: HTMLDialogElement): boolean => {\n const active = document.activeElement;\n return !active || active === document.body || active === dialog;\n};\n\nexport const createDialogCore = (): DialogCore => {\n const state: DialogState = { stack: [] };\n /** Markers of this core's entries in the browser history, oldest first. */\n let historyIds: number[] = [];\n let nextHistoryId = 0;\n let historySyncScheduled = false;\n let listeningToHistory = false;\n /** Settles when the synthetic Back that removes closed dialogs' entries has arrived. */\n let returning: Promise<void> | undefined;\n\n /** Closed dialogs leave the history with one Back to the newest dialog that is still open, or to the page. */\n const syncHistory = () => {\n historySyncScheduled = false;\n const openIds = new Set(state.stack.map((entry) => entry.historyId));\n const current = historyIds.at(-1);\n let steps = 0;\n while (historyIds.length > 0 && !openIds.has(historyIds.at(-1))) {\n historyIds.pop();\n steps++;\n }\n // Someone else moved the history meanwhile; leave it alone.\n if (steps === 0 || historyMarker() !== current) return;\n const back = new Promise<void>((resolve) => window.addEventListener(\"popstate\", () => resolve(), { once: true }));\n returning = back;\n void back.then(() => {\n if (returning === back) returning = undefined;\n });\n history.go(-steps);\n };\n\n const releaseHistory = (entry: DialogStackEntry) => {\n if (entry.historyId === undefined || historySyncScheduled) return;\n historySyncScheduled = true;\n queueMicrotask(syncHistory);\n };\n\n /** Back or Forward moved to another entry: close every dialog opened after the one it shows. */\n const onPopState = () => {\n const marker = historyMarker();\n const index = typeof marker === \"number\" ? historyIds.indexOf(marker) : -1;\n historyIds = historyIds.slice(0, index + 1);\n const gone = (entry: DialogStackEntry) => entry.historyId !== undefined && !historyIds.includes(entry.historyId);\n while (state.stack.some(gone)) popTop(undefined);\n };\n\n const pushHistory = (entry: DialogStackEntry) => {\n if (!listeningToHistory) {\n window.addEventListener(\"popstate\", onPopState);\n listeningToHistory = true;\n }\n const previous = historyRecord();\n // A reload or Forward never brings back a dialog or its sensitive transient state.\n if (historyIds.length === 0 && previous[HISTORY_MARKER] !== undefined) {\n delete previous[HISTORY_MARKER];\n history.replaceState(previous, \"\");\n }\n entry.historyId = ++nextHistoryId;\n historyIds.push(entry.historyId);\n history.pushState({ ...previous, [HISTORY_MARKER]: entry.historyId }, \"\");\n };\n\n const ensureDialogElement = () => {\n if (typeof document === \"undefined\") throw new Error(\"@k2b/ui dialogs can only be opened in the browser\");\n // Reuse the shared element whenever it is still in the document. Resolving\n // the portal root first would create a second <dialog> when focus has moved\n // into another `.k2b-ui` scope, orphaning the levels already on the stack.\n if (state.element?.isConnected) return state.element;\n\n const element = document.createElement(\"dialog\");\n element.onclose = () => {\n // Repeated Escape can force a non-cancelable native close. A retained\n // entry (ignore, an async guard, or a parent) still owns the modal.\n const top = state.stack[state.stack.length - 1];\n if (state.element !== element || element.open || !top) return;\n if (top.modal) element.showModal();\n else element.show();\n resolveInitialFocusTarget(top, element)?.focus();\n };\n getK2bPortalRoot().appendChild(element);\n state.element = element;\n return element;\n };\n\n const lockPageScroll = () => {\n if (typeof document === \"undefined\" || state.scrollLocked) return;\n state.previousBodyOverflow = document.body.style.overflow;\n state.previousHtmlOverflow = document.documentElement.style.overflow;\n document.body.style.overflow = \"hidden\";\n document.documentElement.style.overflow = \"hidden\";\n state.scrollLocked = true;\n };\n\n const unlockPageScroll = () => {\n if (typeof document === \"undefined\" || !state.scrollLocked) return;\n document.body.style.overflow = state.previousBodyOverflow ?? \"\";\n document.documentElement.style.overflow = state.previousHtmlOverflow ?? \"\";\n state.scrollLocked = false;\n state.previousBodyOverflow = undefined;\n state.previousHtmlOverflow = undefined;\n };\n\n const applyPresentation = (entry: DialogStackEntry) => {\n const dialog = state.element;\n if (!dialog || state.stack[state.stack.length - 1] !== entry) return;\n const position = entry.position;\n dialog.style.position = position ? \"fixed\" : \"\";\n dialog.style.inset = position ? `${position.y}px auto auto ${position.x}px` : \"\";\n dialog.style.margin = position ? \"0\" : \"\";\n dialog.style.transform = position ? \"none\" : \"\";\n dialog.dataset.modeless = String(!entry.modal);\n dialog.setAttribute(\"aria-modal\", String(entry.modal));\n if (dialog.open && state.modal !== entry.modal) {\n const active = document.activeElement;\n dialog.close();\n if (entry.modal) dialog.showModal();\n else dialog.show();\n if (active instanceof HTMLElement && active.isConnected && (!entry.modal || dialog.contains(active))) {\n active.focus({ preventScroll: true });\n } else resolveInitialFocusTarget(entry, dialog)?.focus({ preventScroll: true });\n }\n state.modal = entry.modal;\n if (entry.modal) lockPageScroll();\n else unlockPageScroll();\n };\n\n const modelessEscape = (event: KeyboardEvent) => {\n const top = state.stack[state.stack.length - 1];\n if (!top || top.modal || event.key !== \"Escape\" || event.defaultPrevented || event.isComposing) return;\n event.preventDefault();\n void requestDismiss(top);\n };\n\n const stopConnectionObserver = () => {\n document.removeEventListener(\"keydown\", modelessEscape);\n state.connectionObserver?.disconnect();\n state.connectionObserver = undefined;\n };\n\n const applyCancelBehavior = (\n dialog: HTMLDialogElement,\n close: () => void,\n behavior: NonNullable<OpenDialogOptions[\"cancelBehavior\"]>,\n ) => {\n dialog.oncancel = (event) => {\n if (behavior === \"ignore\") {\n event.preventDefault();\n return;\n }\n event.preventDefault();\n close();\n };\n dialog.onmousedown = (event) => {\n state.mouseDownOnDialog = event.target === dialog;\n };\n dialog.onclick = (event) => {\n const realBackdropClick = state.mouseDownOnDialog === true;\n state.mouseDownOnDialog = false;\n if (event.target !== dialog || !state.modal) return;\n if (!realBackdropClick) return;\n if (behavior === \"ignore\") return;\n if (isPointInsideToast(event.clientX, event.clientY)) return;\n close();\n };\n };\n\n const requestDismiss = async (entry: DialogStackEntry) => {\n if (state.stack[state.stack.length - 1] !== entry || entry.dismissPending || entry.cancelBehavior === \"ignore\") return;\n if (!entry.dismissHandler) {\n popTop(undefined);\n return;\n }\n entry.dismissPending = true;\n try {\n await entry.dismissHandler();\n } catch (error) {\n // A failed guard must never discard the dialog's state.\n console.error(\"Dialog dismissal failed\", error);\n } finally {\n entry.dismissPending = false;\n }\n };\n\n const popTop = (result?: unknown) => {\n const top = state.stack.pop();\n if (!top) return;\n releaseHistory(top);\n top.dispose?.();\n top.container.remove();\n\n const dialog = state.element;\n const previous = state.stack[state.stack.length - 1];\n if (previous && dialog) {\n previous.container.style.display = \"\";\n dialog.className = previous.panelClassName;\n applyPresentation(previous);\n applyAccessibleName(dialog, previous);\n applyCancelBehavior(dialog, () => void requestDismiss(previous), previous.cancelBehavior);\n schedule(() => {\n if (!focusUnclaimed(dialog)) return;\n if (top.opener?.isConnected) returnFocus(top.opener, top.openerRing);\n else resolveInitialFocusTarget(previous, dialog)?.focus();\n });\n } else if (dialog) {\n dialog.oncancel = null;\n dialog.onmousedown = null;\n dialog.onclick = null;\n dialog.removeAttribute(\"aria-label\");\n dialog.removeAttribute(\"aria-labelledby\");\n if (dialog.open && typeof dialog.close === \"function\") dialog.close();\n else dialog.removeAttribute(\"open\");\n dialog.remove();\n state.element = undefined;\n stopConnectionObserver();\n unlockPageScroll();\n // After the Escape that closed it: WebKit lights the ring of whatever\n // that key press leaves focused.\n schedule(() => {\n if (top.opener?.isConnected && focusUnclaimed(dialog)) returnFocus(top.opener, top.openerRing);\n });\n }\n\n top.resolve?.(result);\n };\n\n const resetDisconnectedDialog = () => {\n if (state.stack.length === 0 || state.element?.isConnected) return;\n const entries = state.stack.splice(0);\n const dialog = state.element;\n state.element = undefined;\n stopConnectionObserver();\n dialog?.remove();\n unlockPageScroll();\n for (const entry of entries.reverse()) {\n releaseHistory(entry);\n entry.dispose?.();\n entry.container.remove();\n entry.resolve?.(undefined);\n }\n };\n\n const observeConnection = () => {\n if (state.connectionObserver || typeof MutationObserver === \"undefined\") return;\n document.addEventListener(\"keydown\", modelessEscape);\n state.connectionObserver = new MutationObserver(resetDisconnectedDialog);\n state.connectionObserver.observe(document.documentElement, { childList: true, subtree: true });\n };\n\n const open = <T>(view: DialogRender<T>, options: OpenDialogOptions = {}): Promise<T | undefined> => {\n if (options.signal?.aborted) return Promise.resolve(undefined);\n if (options.history) {\n // Dialogs closed just now leave the history first, or this dialog's entry would be the one removed.\n if (historySyncScheduled) syncHistory();\n if (returning) return returning.then(() => open(view, options));\n }\n const dialog = ensureDialogElement();\n const previousTop = state.stack[state.stack.length - 1];\n if (previousTop) previousTop.container.style.display = \"none\";\n const activeElement = document.activeElement;\n\n const panelClassName = options.panelClassName ?? DEFAULT_PANEL_CLASS;\n const cancelBehavior = options.cancelBehavior ?? \"resolve-undefined\";\n const initialFocus = options.initialFocus ?? \"first-input\";\n dialog.className = panelClassName;\n\n const container = document.createElement(\"div\");\n container.className = options.contentClassName ?? DEFAULT_CONTENT_CLASS;\n dialog.appendChild(container);\n\n const entry: DialogStackEntry = {\n container,\n panelClassName,\n cancelBehavior,\n initialFocus,\n opener: activeElement instanceof HTMLElement ? activeElement : undefined,\n openerRing: ringOnReturn(activeElement),\n ariaLabel: options.ariaLabel,\n modal: true,\n };\n\n return new Promise((resolve, reject) => {\n const abort = () => {\n const index = state.stack.indexOf(entry);\n if (index < 0) return;\n if (index === state.stack.length - 1) popTop(undefined);\n else {\n state.stack.splice(index, 1);\n releaseHistory(entry);\n entry.dispose?.();\n entry.container.remove();\n entry.resolve?.(undefined);\n }\n };\n entry.resolve = (value) => {\n options.signal?.removeEventListener(\"abort\", abort);\n if (entry.historyId === undefined) {\n resolve(value as T | undefined);\n return;\n }\n // After the history sync, so a caller that navigates or opens the next dialog finds the history settled.\n queueMicrotask(() => void (returning ?? Promise.resolve()).then(() => resolve(value as T | undefined)));\n };\n const closeTyped: DialogClose<T> = (result) => {\n if (state.stack[state.stack.length - 1] !== entry) return;\n popTop(result);\n };\n\n if (options.history) pushHistory(entry);\n state.stack.push(entry);\n try {\n entry.dispose = render(\n () =>\n view(closeTyped, {\n dialog,\n setModal: (modal) => {\n entry.modal = modal;\n applyPresentation(entry);\n },\n setPosition: (position) => {\n if (position && (!Number.isFinite(position.x) || !Number.isFinite(position.y))) return;\n entry.position = position;\n applyPresentation(entry);\n },\n requestDismiss: () => requestDismiss(entry),\n setDismissHandler: (handler) => {\n entry.dismissHandler = handler;\n },\n }),\n container,\n );\n applyPresentation(entry);\n applyAccessibleName(dialog, entry);\n applyCancelBehavior(dialog, () => void requestDismiss(entry), cancelBehavior);\n\n if (state.stack.length === 1) {\n // The native dialog returns focus to the element focused when it\n // opened, with a ring of the browser's choosing. Opening from a\n // blurred document leaves the return to popTop and its opener ring.\n if (activeElement instanceof HTMLElement) activeElement.blur();\n if (typeof dialog.showModal === \"function\") {\n if (entry.modal) dialog.showModal();\n else dialog.show();\n } else dialog.setAttribute(\"open\", \"\");\n observeConnection();\n }\n options.signal?.addEventListener(\"abort\", abort, { once: true });\n if (options.signal?.aborted) abort();\n schedule(() => {\n if (state.stack[state.stack.length - 1] === entry) resolveInitialFocusTarget(entry, dialog)?.focus();\n });\n } catch (error) {\n entry.resolve = undefined;\n if (state.stack[state.stack.length - 1] === entry) popTop(undefined);\n reject(error);\n }\n });\n };\n\n const close: DialogCore[\"close\"] = (result) => {\n let first = true;\n while (state.stack.length > 0) {\n popTop(first ? result : undefined);\n first = false;\n }\n };\n\n return {\n open,\n close,\n isOpen: () => state.stack.length > 0,\n };\n};\n\nexport const dialogCore = createDialogCore();\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["feedback/dialog-core.ts"],"sourcesContent":["import type { JSX } from \"solid-js\";\nimport { render } from \"solid-js/web\";\nimport { returnFocus, ringOnReturn } from \"../internal/focus-return\";\nimport { getK2bPortalRoot } from \"../internal/portal\";\nimport { resolveUiMessages } from \"../intl/messages\";\nimport { isPointInsideToast } from \"./toast\";\n\nexport type DialogClose<T> = (result?: T) => void;\n\nexport type OpenDialogOptions = {\n /** Close only this dialog when its owning operation is cancelled. */\n signal?: AbortSignal;\n panelClassName?: string;\n contentClassName?: string;\n initialFocus?: \"first-input\" | \"none\" | ((dialog: HTMLDialogElement) => HTMLElement | null);\n cancelBehavior?: \"resolve-undefined\" | \"ignore\";\n ariaLabel?: string;\n /**\n * Add a same-URL history entry while the dialog is open, so the browser's or the phone's Back closes the dialog\n * instead of leaving the page. Closing the dialog removes the entry again; the returned promise settles after that.\n */\n history?: boolean;\n};\n\nexport type DialogRender<T> = (\n close: DialogClose<T>,\n context: {\n dialog: HTMLDialogElement;\n /** Switch this entry between a modal and a modeless window without remounting. */\n setModal: (modal: boolean) => void;\n /** Set viewport coordinates, or restore the panel stylesheet position with null. */\n setPosition: (position: { x: number; y: number } | null) => void;\n /** Route Escape/backdrop through the same guarded handler as Cancel and X. */\n setDismissHandler: (handler: () => void | Promise<void>) => void;\n /** Request dismissal through this entry's cancellation policy and guard. */\n requestDismiss: () => Promise<void>;\n },\n) => JSX.Element;\n\nexport type DialogCore = {\n open: <T>(view: DialogRender<T>, options?: OpenDialogOptions) => Promise<T | undefined>;\n close: (result?: unknown) => void;\n isOpen: () => boolean;\n};\n\ntype DialogStackEntry = {\n container: HTMLDivElement;\n dispose?: () => void;\n resolve?: (value: unknown) => void;\n panelClassName: string;\n cancelBehavior: NonNullable<OpenDialogOptions[\"cancelBehavior\"]>;\n initialFocus: NonNullable<OpenDialogOptions[\"initialFocus\"]>;\n opener?: HTMLElement;\n openerRing: boolean;\n ariaLabel?: string;\n dismissHandler?: () => void | Promise<void>;\n dismissPending?: boolean;\n modal: boolean;\n position?: { x: number; y: number } | null;\n /** The marker of this dialog's history entry, for dialogs opened with `history`. */\n historyId?: number;\n};\n\ntype DialogState = {\n element?: HTMLDialogElement;\n modal?: boolean;\n stack: DialogStackEntry[];\n scrollLocked?: boolean;\n previousBodyOverflow?: string;\n previousHtmlOverflow?: string;\n mouseDownOnDialog?: boolean;\n connectionObserver?: MutationObserver;\n};\n\nconst DEFAULT_PANEL_CLASS = \"k2b-dialog\";\nconst DEFAULT_CONTENT_CLASS = \"k2b-dialog__viewport\";\nlet nextDialogTitleId = 0;\n/** The history state key that marks a dialog's same-URL entry. */\nconst HISTORY_MARKER = \"k2bDialog\";\n\nconst historyRecord = (): Record<string, unknown> =>\n typeof history.state === \"object\" && history.state !== null ? { ...history.state } : {};\nconst historyMarker = (): unknown => historyRecord()[HISTORY_MARKER];\n\nconst resolveInitialFocusTarget = (entry: DialogStackEntry, dialog: HTMLDialogElement): HTMLElement | null => {\n const { initialFocus } = entry;\n if (initialFocus === \"none\") return null;\n if (typeof initialFocus === \"function\") return initialFocus(dialog);\n const input = entry.container.querySelector<HTMLElement>(\n \"input:not([type='hidden']):not([disabled]), textarea:not([disabled]), select:not([disabled]), [role='combobox']:not([disabled]):not([aria-disabled='true'])\",\n );\n return (\n input ??\n entry.container.querySelector<HTMLElement>(\n \"input:not([type='hidden']):not([disabled]), textarea:not([disabled]), select:not([disabled]), button:not([disabled]), a[href], [tabindex]:not([tabindex='-1'])\",\n )\n );\n};\n\nconst applyAccessibleName = (dialog: HTMLDialogElement, entry: DialogStackEntry): void => {\n dialog.removeAttribute(\"aria-label\");\n dialog.removeAttribute(\"aria-labelledby\");\n if (entry.ariaLabel) {\n dialog.setAttribute(\"aria-label\", entry.ariaLabel);\n return;\n }\n const heading = entry.container.querySelector<HTMLElement>(\"h1, h2, h3\");\n if (!heading) {\n dialog.setAttribute(\"aria-label\", resolveUiMessages().dialog);\n return;\n }\n heading.id ||= `k2b-dialog-title-${++nextDialogTitleId}`;\n dialog.setAttribute(\"aria-labelledby\", heading.id);\n};\n\nconst schedule = (callback: () => void): void => {\n if (typeof requestAnimationFrame === \"function\") requestAnimationFrame(callback);\n else queueMicrotask(callback);\n};\n\n/**\n * Whether focus is still where closing a level left it, on the page or the\n * dialog: nothing took it before the next frame, neither a close handler nor a\n * Tab pressed right after Escape.\n */\nconst focusUnclaimed = (dialog: HTMLDialogElement): boolean => {\n const active = document.activeElement;\n return !active || active === document.body || active === dialog;\n};\n\nexport const createDialogCore = (): DialogCore => {\n const state: DialogState = { stack: [] };\n /** Markers of this core's entries in the browser history, oldest first. */\n let historyIds: number[] = [];\n let nextHistoryId = 0;\n let historySyncScheduled = false;\n let listeningToHistory = false;\n /** Settles when the synthetic Back that removes closed dialogs' entries has arrived. */\n let returning: Promise<void> | undefined;\n\n /** Closed dialogs leave the history with one Back to the newest dialog that is still open, or to the page. */\n const syncHistory = () => {\n historySyncScheduled = false;\n const openIds = new Set(state.stack.map((entry) => entry.historyId));\n const current = historyIds.at(-1);\n let steps = 0;\n while (historyIds.length > 0 && !openIds.has(historyIds.at(-1))) {\n historyIds.pop();\n steps++;\n }\n // Someone else moved the history meanwhile; leave it alone.\n if (steps === 0 || historyMarker() !== current) return;\n const back = new Promise<void>((resolve) => window.addEventListener(\"popstate\", () => resolve(), { once: true }));\n returning = back;\n void back.then(() => {\n if (returning === back) returning = undefined;\n });\n history.go(-steps);\n };\n\n const releaseHistory = (entry: DialogStackEntry) => {\n if (entry.historyId === undefined || historySyncScheduled) return;\n historySyncScheduled = true;\n queueMicrotask(syncHistory);\n };\n\n /** Back or Forward moved to another entry: close every dialog opened after the one it shows. */\n const onPopState = () => {\n const marker = historyMarker();\n const index = typeof marker === \"number\" ? historyIds.indexOf(marker) : -1;\n historyIds = historyIds.slice(0, index + 1);\n const gone = (entry: DialogStackEntry) => entry.historyId !== undefined && !historyIds.includes(entry.historyId);\n while (state.stack.some(gone)) popTop(undefined);\n };\n\n const pushHistory = (entry: DialogStackEntry) => {\n if (!listeningToHistory) {\n window.addEventListener(\"popstate\", onPopState);\n listeningToHistory = true;\n }\n const previous = historyRecord();\n // A reload or Forward never brings back a dialog or its sensitive transient state.\n if (historyIds.length === 0 && previous[HISTORY_MARKER] !== undefined) {\n delete previous[HISTORY_MARKER];\n history.replaceState(previous, \"\");\n }\n entry.historyId = ++nextHistoryId;\n historyIds.push(entry.historyId);\n history.pushState({ ...previous, [HISTORY_MARKER]: entry.historyId }, \"\");\n };\n\n const ensureDialogElement = () => {\n if (typeof document === \"undefined\") throw new Error(\"@k2b/ui dialogs can only be opened in the browser\");\n // Reuse the shared element whenever it is still in the document. Resolving\n // the portal root first would create a second <dialog> when focus has moved\n // into another `.k2b-ui` scope, orphaning the levels already on the stack.\n if (state.element?.isConnected) return state.element;\n\n const element = document.createElement(\"dialog\");\n element.onclose = () => {\n // Repeated Escape can force a non-cancelable native close. A retained\n // entry (ignore, an async guard, or a parent) still owns the modal.\n const top = state.stack[state.stack.length - 1];\n if (state.element !== element || element.open || !top) return;\n if (top.modal) element.showModal();\n else element.show();\n resolveInitialFocusTarget(top, element)?.focus();\n };\n getK2bPortalRoot().appendChild(element);\n state.element = element;\n return element;\n };\n\n const lockPageScroll = () => {\n if (typeof document === \"undefined\" || state.scrollLocked) return;\n state.previousBodyOverflow = document.body.style.overflow;\n state.previousHtmlOverflow = document.documentElement.style.overflow;\n document.body.style.overflow = \"hidden\";\n document.documentElement.style.overflow = \"hidden\";\n state.scrollLocked = true;\n };\n\n const unlockPageScroll = () => {\n if (typeof document === \"undefined\" || !state.scrollLocked) return;\n document.body.style.overflow = state.previousBodyOverflow ?? \"\";\n document.documentElement.style.overflow = state.previousHtmlOverflow ?? \"\";\n state.scrollLocked = false;\n state.previousBodyOverflow = undefined;\n state.previousHtmlOverflow = undefined;\n };\n\n const applyPresentation = (entry: DialogStackEntry) => {\n const dialog = state.element;\n if (!dialog || state.stack[state.stack.length - 1] !== entry) return;\n const position = entry.position;\n dialog.style.position = position ? \"fixed\" : \"\";\n dialog.style.inset = position ? `${position.y}px auto auto ${position.x}px` : \"\";\n dialog.style.margin = position ? \"0\" : \"\";\n dialog.style.transform = position ? \"none\" : \"\";\n dialog.dataset.modeless = String(!entry.modal);\n dialog.setAttribute(\"aria-modal\", String(entry.modal));\n if (dialog.open && state.modal !== entry.modal) {\n const active = document.activeElement;\n dialog.close();\n if (entry.modal) dialog.showModal();\n else dialog.show();\n if (active instanceof HTMLElement && active.isConnected && (!entry.modal || dialog.contains(active))) {\n active.focus({ preventScroll: true });\n } else resolveInitialFocusTarget(entry, dialog)?.focus({ preventScroll: true });\n }\n state.modal = entry.modal;\n if (entry.modal) lockPageScroll();\n else unlockPageScroll();\n };\n\n const modelessEscape = (event: KeyboardEvent) => {\n const top = state.stack[state.stack.length - 1];\n if (!top || top.modal || event.key !== \"Escape\" || event.defaultPrevented || event.isComposing) return;\n event.preventDefault();\n void requestDismiss(top);\n };\n\n const stopConnectionObserver = () => {\n document.removeEventListener(\"keydown\", modelessEscape);\n state.connectionObserver?.disconnect();\n state.connectionObserver = undefined;\n };\n\n const applyCancelBehavior = (\n dialog: HTMLDialogElement,\n close: () => void,\n behavior: NonNullable<OpenDialogOptions[\"cancelBehavior\"]>,\n ) => {\n dialog.oncancel = (event) => {\n if (behavior === \"ignore\") {\n event.preventDefault();\n return;\n }\n event.preventDefault();\n close();\n };\n dialog.onmousedown = (event) => {\n state.mouseDownOnDialog = event.target === dialog;\n };\n dialog.onclick = (event) => {\n const realBackdropClick = state.mouseDownOnDialog === true;\n state.mouseDownOnDialog = false;\n if (event.target !== dialog || !state.modal) return;\n if (!realBackdropClick) return;\n if (behavior === \"ignore\") return;\n if (isPointInsideToast(event.clientX, event.clientY)) return;\n close();\n };\n };\n\n const requestDismiss = async (entry: DialogStackEntry) => {\n if (state.stack[state.stack.length - 1] !== entry || entry.dismissPending || entry.cancelBehavior === \"ignore\") return;\n if (!entry.dismissHandler) {\n popTop(undefined);\n return;\n }\n entry.dismissPending = true;\n try {\n await entry.dismissHandler();\n } catch (error) {\n // A failed guard must never discard the dialog's state.\n console.error(\"Dialog dismissal failed\", error);\n } finally {\n entry.dismissPending = false;\n }\n };\n\n const popTop = (result?: unknown) => {\n const top = state.stack.pop();\n if (!top) return;\n releaseHistory(top);\n top.dispose?.();\n top.container.remove();\n\n const dialog = state.element;\n const previous = state.stack[state.stack.length - 1];\n if (previous && dialog) {\n previous.container.style.display = \"\";\n dialog.className = previous.panelClassName;\n applyPresentation(previous);\n applyAccessibleName(dialog, previous);\n applyCancelBehavior(dialog, () => void requestDismiss(previous), previous.cancelBehavior);\n schedule(() => {\n if (!focusUnclaimed(dialog)) return;\n if (top.opener?.isConnected) returnFocus(top.opener, top.openerRing);\n else resolveInitialFocusTarget(previous, dialog)?.focus();\n });\n } else if (dialog) {\n dialog.oncancel = null;\n dialog.onmousedown = null;\n dialog.onclick = null;\n dialog.removeAttribute(\"aria-label\");\n dialog.removeAttribute(\"aria-labelledby\");\n if (dialog.open && typeof dialog.close === \"function\") dialog.close();\n else dialog.removeAttribute(\"open\");\n dialog.remove();\n state.element = undefined;\n stopConnectionObserver();\n unlockPageScroll();\n // After the Escape that closed it: WebKit lights the ring of whatever\n // that key press leaves focused.\n schedule(() => {\n if (top.opener?.isConnected && focusUnclaimed(dialog)) returnFocus(top.opener, top.openerRing);\n });\n }\n\n top.resolve?.(result);\n };\n\n const resetDisconnectedDialog = () => {\n if (state.stack.length === 0 || state.element?.isConnected) return;\n const entries = state.stack.splice(0);\n const dialog = state.element;\n state.element = undefined;\n stopConnectionObserver();\n dialog?.remove();\n unlockPageScroll();\n for (const entry of entries.reverse()) {\n releaseHistory(entry);\n entry.dispose?.();\n entry.container.remove();\n entry.resolve?.(undefined);\n }\n };\n\n const observeConnection = () => {\n if (state.connectionObserver || typeof MutationObserver === \"undefined\") return;\n document.addEventListener(\"keydown\", modelessEscape);\n state.connectionObserver = new MutationObserver(resetDisconnectedDialog);\n state.connectionObserver.observe(document.documentElement, { childList: true, subtree: true });\n };\n\n const open = <T>(view: DialogRender<T>, options: OpenDialogOptions = {}): Promise<T | undefined> => {\n if (options.signal?.aborted) return Promise.resolve(undefined);\n if (options.history) {\n // Dialogs closed just now leave the history first, or this dialog's entry would be the one removed.\n if (historySyncScheduled) syncHistory();\n if (returning) return returning.then(() => open(view, options));\n }\n const dialog = ensureDialogElement();\n const previousTop = state.stack[state.stack.length - 1];\n if (previousTop) previousTop.container.style.display = \"none\";\n const activeElement = document.activeElement;\n\n const panelClassName = options.panelClassName ?? DEFAULT_PANEL_CLASS;\n const cancelBehavior = options.cancelBehavior ?? \"resolve-undefined\";\n const initialFocus = options.initialFocus ?? \"first-input\";\n dialog.className = panelClassName;\n\n const container = document.createElement(\"div\");\n container.className = options.contentClassName ?? DEFAULT_CONTENT_CLASS;\n dialog.appendChild(container);\n\n const entry: DialogStackEntry = {\n container,\n panelClassName,\n cancelBehavior,\n initialFocus,\n opener: activeElement instanceof HTMLElement ? activeElement : undefined,\n openerRing: ringOnReturn(activeElement),\n ariaLabel: options.ariaLabel,\n modal: true,\n };\n\n return new Promise((resolve, reject) => {\n const abort = () => {\n const index = state.stack.indexOf(entry);\n if (index < 0) return;\n if (index === state.stack.length - 1) popTop(undefined);\n else {\n state.stack.splice(index, 1);\n releaseHistory(entry);\n entry.dispose?.();\n entry.container.remove();\n entry.resolve?.(undefined);\n }\n };\n entry.resolve = (value) => {\n options.signal?.removeEventListener(\"abort\", abort);\n if (entry.historyId === undefined) {\n resolve(value as T | undefined);\n return;\n }\n // After the history sync, so a caller that navigates or opens the next dialog finds the history settled.\n queueMicrotask(() => void (returning ?? Promise.resolve()).then(() => resolve(value as T | undefined)));\n };\n const closeTyped: DialogClose<T> = (result) => {\n if (state.stack[state.stack.length - 1] !== entry) return;\n popTop(result);\n };\n\n if (options.history) pushHistory(entry);\n state.stack.push(entry);\n try {\n entry.dispose = render(\n () =>\n view(closeTyped, {\n dialog,\n setModal: (modal) => {\n entry.modal = modal;\n applyPresentation(entry);\n },\n setPosition: (position) => {\n if (position && (!Number.isFinite(position.x) || !Number.isFinite(position.y))) return;\n entry.position = position;\n applyPresentation(entry);\n },\n requestDismiss: () => requestDismiss(entry),\n setDismissHandler: (handler) => {\n entry.dismissHandler = handler;\n },\n }),\n container,\n );\n applyPresentation(entry);\n applyAccessibleName(dialog, entry);\n applyCancelBehavior(dialog, () => void requestDismiss(entry), cancelBehavior);\n\n if (state.stack.length === 1) {\n // The native dialog returns focus to the element focused when it\n // opened, with a ring of the browser's choosing. Opening from a\n // blurred document leaves the return to popTop and its opener ring.\n if (activeElement instanceof HTMLElement) activeElement.blur();\n if (typeof dialog.showModal === \"function\") {\n if (entry.modal) dialog.showModal();\n else dialog.show();\n } else dialog.setAttribute(\"open\", \"\");\n observeConnection();\n }\n options.signal?.addEventListener(\"abort\", abort, { once: true });\n if (options.signal?.aborted) abort();\n // Where opening left focus, the native dialog's own pick included. Focus that the content or a person moved\n // before the next frame stays: a browser can hold that frame back while keys already arrive.\n const opened = document.activeElement;\n schedule(() => {\n if (state.stack[state.stack.length - 1] !== entry) return;\n if (document.activeElement !== opened && !focusUnclaimed(dialog)) return;\n resolveInitialFocusTarget(entry, dialog)?.focus();\n });\n } catch (error) {\n entry.resolve = undefined;\n if (state.stack[state.stack.length - 1] === entry) popTop(undefined);\n reject(error);\n }\n });\n };\n\n const close: DialogCore[\"close\"] = (result) => {\n let first = true;\n while (state.stack.length > 0) {\n popTop(first ? result : undefined);\n first = false;\n }\n };\n\n return {\n open,\n close,\n isOpen: () => state.stack.length > 0,\n };\n};\n\nexport const dialogCore = createDialogCore();\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -38,6 +38,11 @@ const uiMessages = i18n.define({
|
|
|
38
38
|
close: "Close",
|
|
39
39
|
closeDialog: "close dialog",
|
|
40
40
|
copied: "Copied",
|
|
41
|
+
infoBlockNote: "Note",
|
|
42
|
+
infoBlockInfo: "Info",
|
|
43
|
+
infoBlockSuccess: "Success",
|
|
44
|
+
infoBlockWarning: "Warning",
|
|
45
|
+
infoBlockDanger: "Danger",
|
|
41
46
|
copy: "Copy",
|
|
42
47
|
closeLightbox: "Close lightbox",
|
|
43
48
|
couldNotLoadData: "Could not load this data",
|
|
@@ -544,6 +549,11 @@ const uiMessages = i18n.define({
|
|
|
544
549
|
close: "Schließen",
|
|
545
550
|
closeDialog: "Dialog schließen",
|
|
546
551
|
copied: "Kopiert",
|
|
552
|
+
infoBlockNote: "Notiz",
|
|
553
|
+
infoBlockInfo: "Info",
|
|
554
|
+
infoBlockSuccess: "Erfolg",
|
|
555
|
+
infoBlockWarning: "Warnung",
|
|
556
|
+
infoBlockDanger: "Gefahr",
|
|
547
557
|
copy: "Kopieren",
|
|
548
558
|
closeLightbox: "Bildansicht schließen",
|
|
549
559
|
couldNotLoadData: "Diese Daten konnten nicht geladen werden",
|