WIP: Plug API document change event (#488)
* add support for basic on doc change event * move change API core into plug-api/lib; add docs * add overlap utility * Maintain modal focus * Federated URL backend handling * Fix small typo in Query.md (#483) * Federation progress * Cleanup and federation prep * Robustness and federation sync * Federation: rewrite page references in federated content * Don't sync service worker and index.json to client on silverbullet.md * Federation listing timeouts * Switching onboarding over to federation links * Reduce amount of sync related log messages a bit * Attribute indexing and code completion * Shift-Enter in the page navigator now takes the input literally * Updated changelog * Completion for handlebar template variables * Make 'pos' a number in tasks * Updated install instructions to include edge builds * WIP: CLI running of plugs * Upgrade deno in Docker to 1.36.0 * Implement CLI store using Deno store * Rerun directives * Fixes #485 * 0.3.8 * 0.3.9 * Changelog * Instantly sync updated pages when ticking off a task in a directive * Sync current open page every 5s * Optimize requests * Make attribute extensible * Debugging sync getting stuck * Misaligning sync cycles (to avoid no-op cycles) * Fixes #500: New apply page template command * Changelog * More sync debugging statements * More sync debugging * Even more debug * Dial down excessive debug logging * Fixes #115: By introducing MQ workers * Use MQ for updating directives in entire space * Work on plug:run * touch up docs * Fix htmlLanguage dependency --------- Co-authored-by: Zef Hemel <zef@zef.me> Co-authored-by: johnl <johnlunney@users.noreply.github.com>
This commit is contained in:
co-authored by
Zef Hemel
johnl
parent
f22b9c4a1f
commit
7d3303251d
@@ -1,5 +1,6 @@
|
||||
import type { ParseTree } from "$sb/lib/tree.ts";
|
||||
import { ParsedQuery } from "$sb/lib/query.ts";
|
||||
import { TextChange } from "$sb/lib/change.ts";
|
||||
|
||||
export type AppEvent =
|
||||
| "page:click"
|
||||
@@ -11,7 +12,8 @@ export type AppEvent =
|
||||
| "editor:pageReloaded"
|
||||
| "editor:pageSaved"
|
||||
| "editor:modeswitch"
|
||||
| "plugs:loaded";
|
||||
| "plugs:loaded"
|
||||
| "editor:pageModified";
|
||||
|
||||
export type QueryProviderEvent = {
|
||||
query: ParsedQuery;
|
||||
@@ -56,3 +58,9 @@ export type WidgetContent = {
|
||||
height?: number;
|
||||
width?: number;
|
||||
};
|
||||
|
||||
/** PageModifiedEvent payload for "editor:pageModified". Fired when the document text changes
|
||||
*/
|
||||
export type PageModifiedEvent = {
|
||||
changes: TextChange[];
|
||||
};
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { rangeLength, rangesOverlap } from "$sb/lib/change.ts";
|
||||
import { assertEquals } from "https://deno.land/std@0.165.0/testing/asserts.ts";
|
||||
|
||||
Deno.test("rangeLength", () => {
|
||||
assertEquals(rangeLength({ from: 4, to: 11 }), 7);
|
||||
});
|
||||
|
||||
Deno.test("rangesOverlap", () => {
|
||||
assertEquals(
|
||||
rangesOverlap({ from: 0, to: 5 }, { from: 3, to: 8 }),
|
||||
true,
|
||||
);
|
||||
assertEquals(
|
||||
rangesOverlap({ from: 0, to: 5 }, { from: 6, to: 8 }),
|
||||
false,
|
||||
);
|
||||
// `to` is exclusive
|
||||
assertEquals(
|
||||
rangesOverlap({ from: 0, to: 6 }, { from: 6, to: 8 }),
|
||||
false,
|
||||
);
|
||||
assertEquals(
|
||||
rangesOverlap({ from: 3, to: 6 }, { from: 0, to: 4 }),
|
||||
true,
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
// API for working with changes to document text
|
||||
|
||||
/** Denotes a region in the document, based on character indicices
|
||||
*/
|
||||
export type Range = {
|
||||
/** The starting index of the span, 0-based, inclusive
|
||||
*/
|
||||
from: number;
|
||||
|
||||
/** The ending index of the span, 0-based, exclusive
|
||||
*/
|
||||
to: number;
|
||||
};
|
||||
|
||||
/** A modification to the document */
|
||||
export type TextChange = {
|
||||
/** The new text */
|
||||
inserted: string;
|
||||
|
||||
/** The modified range **before** this change took effect.
|
||||
*
|
||||
* Example: "aaabbbccc" => "aaaccc", oldRange is [3, 6)
|
||||
*/
|
||||
oldRange: Range;
|
||||
|
||||
/** The modified range **after** this change took effect.
|
||||
*
|
||||
* Example: "aaabbbccc" => "aaaccc", newRange is [3, 3)
|
||||
*/
|
||||
newRange: Range;
|
||||
};
|
||||
|
||||
/** Get this distance between the start and end of a range */
|
||||
export function rangeLength(range: Range): number {
|
||||
return range.to - range.from;
|
||||
}
|
||||
|
||||
export function rangesOverlap(a: Range, b: Range): boolean {
|
||||
// `b.from >= a.to` => "b" starts after "a"
|
||||
// `a.from >= b.to` => "b" ends before "a"
|
||||
// if neither is true these two ranges must overlap
|
||||
return !(b.from >= a.to || a.from >= b.to);
|
||||
}
|
||||
Reference in New Issue
Block a user