mnfst 0.5.231 → 0.5.232
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/lib/manifest.appwrite.data.js +1 -1
- package/lib/manifest.components.js +8 -0
- package/lib/manifest.css +341 -424
- package/lib/manifest.d.ts +170 -39
- package/lib/manifest.data.js +1 -1
- package/lib/manifest.defer.js +1 -1
- package/lib/manifest.dropdowns.js +2 -0
- package/lib/manifest.edit.css +87 -150
- package/lib/manifest.edit.js +2324 -1076
- package/lib/manifest.integrity.json +10 -10
- package/lib/manifest.js +119 -25
- package/lib/manifest.min.css +1 -1
- package/lib/manifest.rich.text.css +253 -0
- package/lib/{manifest.text.edit.js → manifest.rich.text.js} +1153 -736
- package/lib/manifest.router.js +8 -0
- package/lib/manifest.sw.js +1 -1
- package/package.json +2 -1
- package/lib/manifest.text.edit.css +0 -273
package/lib/manifest.d.ts
CHANGED
|
@@ -351,80 +351,203 @@ export interface ManifestCamera {
|
|
|
351
351
|
pick(opts?: Record<string, unknown>): Promise<unknown>;
|
|
352
352
|
}
|
|
353
353
|
|
|
354
|
-
/**
|
|
355
|
-
|
|
354
|
+
/** Edit action names for `$edit.can()` and per-action locks. */
|
|
355
|
+
export type ManifestEditAction = 'move' | 'remove' | 'duplicate' | 'text' | 'attrs' | 'size';
|
|
356
|
+
/** `can()` also answers 'class' (the class list; component nodes allow only this) and copy/cut/paste. */
|
|
357
|
+
|
|
358
|
+
/** Class controls on `$edit.classes`. `el` defaults to `$edit.target`. */
|
|
359
|
+
export interface ManifestEditClasses {
|
|
360
|
+
add(cls: string, el?: Element): boolean;
|
|
361
|
+
remove(cls: string, el?: Element): boolean;
|
|
362
|
+
toggle(cls: string, el?: Element, force?: boolean): boolean;
|
|
363
|
+
has(cls: string, el?: Element): boolean;
|
|
364
|
+
/** Replace the static class list. */
|
|
365
|
+
set(value: string, el?: Element): boolean;
|
|
366
|
+
/** The static classes (bound :class classes excluded). */
|
|
367
|
+
list(el?: Element): string[];
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/** Element editor (`x-edit`) — opt-in plugin. Modifiers: `.text` `.move` `.size`
|
|
371
|
+
* `.data` (default text + move), `.lock[.action]`, `.gated`, `.persist`, `.bare`,
|
|
372
|
+
* `.theme`, `.cssvar`. Every edit is logged; actions default to `$edit.target`. */
|
|
356
373
|
export interface ManifestEdit {
|
|
357
|
-
/** True while
|
|
374
|
+
/** True while `.gated` areas are editable. */
|
|
358
375
|
active: boolean;
|
|
359
376
|
canUndo: boolean;
|
|
360
377
|
canRedo: boolean;
|
|
378
|
+
/** Bumps on every change to the log or target; read it to make a binding re-evaluate. */
|
|
379
|
+
version: number;
|
|
361
380
|
/** Set a handler to route patches somewhere other than the dev server. */
|
|
362
381
|
onPublish: ((patches: unknown[], state: { log: unknown[]; cursor: number }) => unknown) | null;
|
|
363
382
|
toggle(): void;
|
|
364
383
|
on(): void;
|
|
365
384
|
off(): void;
|
|
366
|
-
undo(): void
|
|
367
|
-
redo(): void
|
|
368
|
-
/**
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
385
|
+
undo(): Promise<void>;
|
|
386
|
+
redo(): Promise<void>;
|
|
387
|
+
/** Source files that changed since the page loaded, from the last refused publish (also an
|
|
388
|
+
* `edit:stale` event on document, detail `{ files }`), or a reload held back because it
|
|
389
|
+
* would lose unpublished edits. */
|
|
390
|
+
stale: string[];
|
|
391
|
+
/** Edits that could not be applied because the source changed under them (also an
|
|
392
|
+
* `edit:conflict` event on document, detail `{ conflicts }`, and a console warning).
|
|
393
|
+
* `element` names what was edited (tag and opening text, or the region for layout);
|
|
394
|
+
* `value` what the edit held; `reason` says what happened in words.
|
|
395
|
+
* - A text or attribute edit whose element changed: `prop` is the edited property.
|
|
396
|
+
* - Layout (`prop: 'structure'`): kept when only unmoved children changed text in place;
|
|
397
|
+
* dropped when a moved, added or removed child changed, with `value`
|
|
398
|
+
* `{ changed: [{ was, now }], moved: [...], copies: [{ of, html, text }] }` so typed
|
|
399
|
+
* content can be recovered. */
|
|
400
|
+
conflicts: Array<{ region: string; key: string; element: string; prop: string; value: unknown; before: unknown; reason: string }>;
|
|
401
|
+
/** Empty `conflicts`. Those of `.persist` regions are kept across reloads until this is called. */
|
|
402
|
+
clearConflicts(): void;
|
|
403
|
+
/** Send every area's patches; on success the history is cleared (the source now holds it).
|
|
404
|
+
* `rebase: true` takes the current source as the base (writes over external changes). */
|
|
405
|
+
publish(opts?: { rebase?: boolean }): Promise<unknown>;
|
|
406
|
+
/** The resolved source patches for every area, without sending them. */
|
|
374
407
|
patches(): unknown[];
|
|
375
408
|
/** The raw delta log — persist it yourself to move edits between devices. */
|
|
376
409
|
export(): { log: unknown[]; cursor: number };
|
|
377
|
-
/** The
|
|
378
|
-
* assignable. Block operations default to it when called with no element. */
|
|
410
|
+
/** The piece a right-click landed on (set before any menu opens), or assignable. */
|
|
379
411
|
target: Element | null;
|
|
380
|
-
/** Whether an
|
|
381
|
-
can(
|
|
412
|
+
/** Whether an action applies to `el` (default `$edit.target`): capability and locks. */
|
|
413
|
+
can(action: ManifestEditAction | 'class' | 'copy' | 'cut' | 'paste', el?: Element | null): boolean;
|
|
414
|
+
/** Lock `el` and its subtree for one action, or all when omitted. Logged. A component host
|
|
415
|
+
* (see `block`) locks by its host key, for all its roots and what is in them. */
|
|
416
|
+
lock(el?: Element | null, action?: ManifestEditAction): boolean;
|
|
417
|
+
unlock(el?: Element | null, action?: ManifestEditAction): boolean;
|
|
382
418
|
copy(el?: Element): boolean;
|
|
383
419
|
cut(el?: Element): boolean;
|
|
384
420
|
paste(el?: Element): boolean;
|
|
385
421
|
duplicate(el?: Element): boolean;
|
|
386
422
|
remove(el?: Element): boolean;
|
|
387
|
-
/** Move a
|
|
423
|
+
/** Move a piece into a container (element or area key), before `before` or at the end. */
|
|
388
424
|
move(el: Element | null, dest: Element | string, before?: Element | null): boolean;
|
|
389
|
-
/**
|
|
425
|
+
/** Nest a piece into the container before it. */
|
|
426
|
+
nest(el?: Element): boolean;
|
|
427
|
+
/** Move a piece out of its container, after it. */
|
|
428
|
+
unnest(el?: Element): boolean;
|
|
429
|
+
/** The piece containing a node, or null. In a static area a component instance is one
|
|
430
|
+
* piece, its host (its first rendered root; the rest follow it): it moves, duplicates
|
|
431
|
+
* (a new instance) and is removed as one, and its markup is not edited from here. */
|
|
390
432
|
block(node: Element): Element | null;
|
|
433
|
+
/** Set an attribute: a string sets it, `true` sets it empty, `null`/`false` removes it. */
|
|
434
|
+
attr(name: string, value: string | boolean | null, el?: Element): boolean;
|
|
435
|
+
classes: ManifestEditClasses;
|
|
436
|
+
/** Component scope of the target's area: read with no value, set 'instance' or 'main'.
|
|
437
|
+
* Instance overrides apply to an area that wraps exactly one component with no x-edit region
|
|
438
|
+
* of its own; a component among other content is a host piece of a static area instead, and
|
|
439
|
+
* a component's own region is edited in its own file. */
|
|
440
|
+
scope(value?: 'instance' | 'main', el?: Element): 'instance' | 'main' | null | boolean;
|
|
441
|
+
/** Revert a component element's instance overrides (the area element reverts all). */
|
|
442
|
+
revert(el?: Element): boolean;
|
|
391
443
|
}
|
|
392
444
|
|
|
393
|
-
/**
|
|
394
|
-
export interface
|
|
395
|
-
/** The stored value, in the
|
|
396
|
-
* document and resets undo history. */
|
|
445
|
+
/** Rich text editor (`x-rich-text`): the area this element sits in, or the last focused one. */
|
|
446
|
+
export interface ManifestRichText {
|
|
447
|
+
/** The stored value, in the area's format. Assigning replaces the document and resets undo history. */
|
|
397
448
|
value: string;
|
|
398
449
|
focus(): void;
|
|
399
450
|
/** The href at the caret; assign to set it, assign '' to unlink. */
|
|
400
451
|
link: string;
|
|
401
|
-
/**
|
|
402
|
-
*
|
|
403
|
-
|
|
404
|
-
page: Record<string, string>;
|
|
452
|
+
/** Document-wide styles (font, size, leading, align, color, background) as CSS custom
|
|
453
|
+
* properties on the area; not part of the stored value. Assign `{}` to clear. */
|
|
454
|
+
all: Record<string, string>;
|
|
405
455
|
/** Select the whole document. */
|
|
406
456
|
selectAll(): void;
|
|
407
|
-
/** The current selection and its geometry, or null. Also emitted as a
|
|
408
|
-
*
|
|
409
|
-
* on the area, for anchoring a menu to it. */
|
|
457
|
+
/** The current selection and its geometry, or null. Also emitted as a `rich-text:selection`
|
|
458
|
+
* event and as --rich-text-selection-* custom properties. */
|
|
410
459
|
selection: {
|
|
411
460
|
collapsed: boolean; text: string;
|
|
412
461
|
x: number; y: number; width: number; height: number;
|
|
413
462
|
top: number; bottom: number; left: number; right: number;
|
|
414
463
|
} | null;
|
|
415
|
-
/** Apply a command. Commands are
|
|
416
|
-
* '
|
|
417
|
-
*
|
|
418
|
-
*
|
|
419
|
-
run(command: string, arg?:
|
|
464
|
+
/** Apply a command. Commands are HTML tag names ('strong', 'h2', 'ul', 'a', 'table', …) plus
|
|
465
|
+
* 'indent', 'outdent', 'align', 'color', 'background', 'font', 'size', 'leading', 'checklist',
|
|
466
|
+
* 'unlink', 'clear', 'undo', 'redo', 'block' and the table operations. Every command is also
|
|
467
|
+
* a method: `$rich.strong()`, `$rich.table(3, 2)` (columns, rows). */
|
|
468
|
+
run(command: string, arg?: unknown): void;
|
|
420
469
|
/** Whether that command is active at the caret. */
|
|
421
470
|
active(command: string): boolean;
|
|
422
|
-
/** Whether that command is available
|
|
471
|
+
/** Whether that command is available here (format, .inline, caret). */
|
|
423
472
|
can(command: string): boolean;
|
|
424
|
-
/** Read the content as markdown regardless of the storage
|
|
473
|
+
/** Read the content as markdown regardless of the storage format. */
|
|
425
474
|
markdown(): string;
|
|
426
|
-
/** Read the content as sanitized HTML regardless of the storage
|
|
475
|
+
/** Read the content as sanitized HTML regardless of the storage format. */
|
|
427
476
|
html(): string;
|
|
477
|
+
|
|
478
|
+
// Inline tags: toggle on the selection, or arm for the next typed text
|
|
479
|
+
strong(): void; b(): void; em(): void; i(): void; s(): void; del(): void; code(): void;
|
|
480
|
+
bdi(): void; cite(): void; ins(): void; kbd(): void; mark(): void; q(): void; samp(): void;
|
|
481
|
+
small(): void; span(): void; sub(): void; sup(): void; u(): void; var(): void;
|
|
482
|
+
/** `title` attribute (html only). */
|
|
483
|
+
abbr(title?: string): void;
|
|
484
|
+
/** `title` attribute (html only). */
|
|
485
|
+
dfn(title?: string): void;
|
|
486
|
+
/** Direction, default 'rtl' (html only). */
|
|
487
|
+
bdo(dir?: 'ltr' | 'rtl' | 'auto'): void;
|
|
488
|
+
/** Machine-readable `value` (html only). */
|
|
489
|
+
data(value?: string): void;
|
|
490
|
+
/** `datetime` attribute (html only). */
|
|
491
|
+
time(datetime?: string): void;
|
|
492
|
+
/** Link the selection; '' unlinks. */
|
|
493
|
+
a(href?: string): void;
|
|
494
|
+
unlink(): void;
|
|
495
|
+
br(): void;
|
|
496
|
+
/** Break opportunity (html only). */
|
|
497
|
+
wbr(): void;
|
|
498
|
+
img(src: string, alt?: string): void;
|
|
499
|
+
|
|
500
|
+
// Block tags: convert the block (again returns to p)
|
|
501
|
+
p(): void; h1(): void; h2(): void; h3(): void; h4(): void; h5(): void; h6(): void;
|
|
502
|
+
blockquote(): void; pre(): void; address(): void;
|
|
503
|
+
ul(): void; ol(): void; li(): void; checklist(): void; hr(): void;
|
|
504
|
+
figure(): void; figcaption(): void; dl(): void; dt(): void; dd(): void;
|
|
505
|
+
/** Any block tag by name, e.g. block('h2'). */
|
|
506
|
+
block(tag: string): void;
|
|
507
|
+
|
|
508
|
+
/** Insert a columns × rows table (default 3 × 3). */
|
|
509
|
+
table(columns?: number, rows?: number): void;
|
|
510
|
+
'row-before'(): void; 'row-after'(): void; 'row-remove'(): void;
|
|
511
|
+
'column-before'(): void; 'column-after'(): void; 'column-remove'(): void;
|
|
512
|
+
'table-remove'(): void; 'table-header'(): void; merge(): void; split(): void;
|
|
513
|
+
|
|
514
|
+
indent(): void; outdent(): void;
|
|
515
|
+
align(value?: 'start' | 'center' | 'end' | 'justify' | string): void;
|
|
516
|
+
leading(value: string): void;
|
|
517
|
+
color(value: string): void;
|
|
518
|
+
background(value: string): void;
|
|
519
|
+
font(value: string): void;
|
|
520
|
+
size(value: string | number): void;
|
|
521
|
+
clear(): void;
|
|
522
|
+
undo(): void;
|
|
523
|
+
redo(): void;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/** Options for `ManifestRichText.attach()`. */
|
|
527
|
+
export interface ManifestRichTextAttachOptions {
|
|
528
|
+
/** 'block' (default) or 'inline' (single line: no block commands, Enter fires `rich-text:enter`). */
|
|
529
|
+
mode?: 'block' | 'inline';
|
|
530
|
+
/** Inline html only: `<br>` line breaks are kept, Shift+Enter inserts one, pasted blocks become lines. */
|
|
531
|
+
breaks?: boolean;
|
|
532
|
+
/** false: `.all` controls and `$rich.all` are unavailable (no area-wide --rich-text-* styles). Default true. */
|
|
533
|
+
all?: boolean;
|
|
534
|
+
/** Storage format: 'markdown' (default), 'html' or 'plain'. */
|
|
535
|
+
format?: 'markdown' | 'html' | 'plain';
|
|
536
|
+
/** Initial value; omitted, the element's existing markup is the content. */
|
|
537
|
+
value?: string;
|
|
538
|
+
/** No markdown autoformat while typing. */
|
|
539
|
+
literal?: boolean;
|
|
540
|
+
/** Called with the stored value after every change. */
|
|
541
|
+
onChange?(value: string): void;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
/** Returned by `ManifestRichText.attach()`: the `$rich` surface plus detach(). */
|
|
545
|
+
export interface ManifestRichTextHandle extends ManifestRichText {
|
|
546
|
+
el: Element;
|
|
547
|
+
/** Remove editing and restore the element's own contenteditable/role/aria-multiline. */
|
|
548
|
+
detach(): void;
|
|
549
|
+
/** Markup of the newest step in the field's undo history (a pending typing burst is recorded first). */
|
|
550
|
+
newest(): string;
|
|
428
551
|
}
|
|
429
552
|
|
|
430
553
|
/**
|
|
@@ -437,7 +560,7 @@ export type ManifestDirective =
|
|
|
437
560
|
| 'x-toast' | 'x-tooltip' | 'x-carousel' | 'x-virtual' | 'x-computed' | 'x-defer'
|
|
438
561
|
| 'x-chart' | 'x-date' | 'x-color' | 'x-colorpicker' | 'x-combobox'
|
|
439
562
|
| 'x-export' | 'x-import' | 'x-pay' | 'x-files' | 'x-data-files'
|
|
440
|
-
| 'x-edit' | 'x-text
|
|
563
|
+
| 'x-edit' | 'x-rich-text';
|
|
441
564
|
|
|
442
565
|
// ---------------------------------------------------------------------------
|
|
443
566
|
// Global declarations (what Alpine exposes inside `x-data`, `x-show`, etc.)
|
|
@@ -487,8 +610,8 @@ declare global {
|
|
|
487
610
|
const $import: ManifestImport;
|
|
488
611
|
/** Element editor (edit plugin; opt-in). */
|
|
489
612
|
const $edit: ManifestEdit;
|
|
490
|
-
/**
|
|
491
|
-
const $
|
|
613
|
+
/** Rich text editor (rich-text plugin; loaded on use). */
|
|
614
|
+
const $rich: ManifestRichText;
|
|
492
615
|
/** Device/platform info (utilities; enriched by the device plugin). */
|
|
493
616
|
const $device: ManifestDevice;
|
|
494
617
|
/** Native share (device plugin). */
|
|
@@ -523,6 +646,14 @@ declare global {
|
|
|
523
646
|
};
|
|
524
647
|
Alpine?: unknown;
|
|
525
648
|
__manifestLoaded?: unknown;
|
|
649
|
+
/** Rich text engine (rich-text plugin). */
|
|
650
|
+
ManifestRichText?: {
|
|
651
|
+
attach(el: Element, options?: ManifestRichTextAttachOptions): ManifestRichTextHandle | null;
|
|
652
|
+
toMarkdown(root: Element): string;
|
|
653
|
+
fromMarkdown(markdown: string): string;
|
|
654
|
+
sanitize(html: string, allowBlocks?: boolean, keepStyle?: boolean): string;
|
|
655
|
+
commands(): string[];
|
|
656
|
+
};
|
|
526
657
|
}
|
|
527
658
|
|
|
528
659
|
/**
|
package/lib/manifest.data.js
CHANGED
package/lib/manifest.defer.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// Directives that render their own children — never stash under them
|
|
7
7
|
const OWNS_CHILDREN = new Set([
|
|
8
8
|
'x-html', 'x-text', 'x-ignore', 'x-markdown', 'x-icon', 'x-svg', 'x-code', 'x-code-group',
|
|
9
|
-
'x-chart', 'x-carousel', 'x-virtual', 'x-combobox', 'x-colorpicker', 'x-date', 'x-text
|
|
9
|
+
'x-chart', 'x-carousel', 'x-virtual', 'x-combobox', 'x-colorpicker', 'x-date', 'x-rich-text'
|
|
10
10
|
]);
|
|
11
11
|
|
|
12
12
|
// Kill switch: data-defer="off" on the loader script; prerender snapshots keep eager markup
|
|
@@ -359,6 +359,8 @@ function initializeDropdownPlugin() {
|
|
|
359
359
|
pressTimer = null;
|
|
360
360
|
restoreCallout();
|
|
361
361
|
el.__mnfstLongPressOpenedAt = Date.now();
|
|
362
|
+
// No contextmenu event on iOS: announce the press so composing plugins (x-edit) can track the target.
|
|
363
|
+
pressTarget.dispatchEvent(new CustomEvent('dropdown:context', { bubbles: true, detail: { x: startX, y: startY } }));
|
|
362
364
|
openContextMenuAt(pressTarget, startX, startY);
|
|
363
365
|
}, LONG_PRESS_MS);
|
|
364
366
|
});
|