@miliastry/quasar 1.0.6 → 1.1.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/Visuals/lyne.css +117 -6
- package/dist/Visuals/osu.css +36 -5
- package/dist/index.js +9664 -3282
- package/dist/index.mjs +9535 -3283
- package/dist/types/Analysis/Contracts/AnalysisReport.d.ts +22 -0
- package/dist/types/Analysis/Contracts/Contribution.d.ts +68 -0
- package/dist/types/Analysis/Contracts/Pass.d.ts +59 -0
- package/dist/types/Analysis/Contracts/PipelineContext.d.ts +34 -0
- package/dist/types/Analysis/Passes/Analysis/ColorUsageAnalyzer.d.ts +56 -0
- package/dist/types/Analysis/Passes/Analysis/GradientAnalyzer.d.ts +111 -0
- package/dist/types/Analysis/Passes/Analysis/MergeableColorAnalyzer.d.ts +26 -0
- package/dist/types/Analysis/Passes/Analysis/RainbowAnalyzer.d.ts +47 -0
- package/dist/types/Analysis/Passes/Analysis/SymbolAnalyzer.d.ts +89 -0
- package/dist/types/Analysis/Passes/Analysis/WaveAnalyzer.d.ts +44 -0
- package/dist/types/Analysis/Passes/Analysis/__tests__/GradientAnalyzer.test.d.ts +4 -0
- package/dist/types/Analysis/Passes/Analysis/__tests__/MergeableColorAnalyzer.test.d.ts +4 -0
- package/dist/types/Analysis/Passes/Analysis/__tests__/RainbowAnalyzer.test.d.ts +4 -0
- package/dist/types/Analysis/Passes/Analysis/__tests__/WaveAnalyzer.test.d.ts +4 -0
- package/dist/types/Analysis/Passes/Decision/DefaultDecision.d.ts +30 -0
- package/dist/types/Analysis/Passes/Decision/PaletteRemapDecision.d.ts +169 -0
- package/dist/types/Analysis/Passes/Decision/__tests__/DefaultDecision.test.d.ts +4 -0
- package/dist/types/Analysis/Passes/Transform/CollapseGradientTransform.d.ts +37 -0
- package/dist/types/Analysis/Passes/Transform/MergeColorsTransform.d.ts +28 -0
- package/dist/types/Analysis/Passes/Transform/RainbowCollapseTransform.d.ts +19 -0
- package/dist/types/Analysis/Passes/Transform/WaveCollapseTransform.d.ts +20 -0
- package/dist/types/Analysis/Passes/Utility/CharacterCountAnalyzer.d.ts +19 -0
- package/dist/types/Analysis/Pipeline/Pipeline.d.ts +69 -0
- package/dist/types/Analysis/Pipeline/PipelineBuilder.d.ts +31 -0
- package/dist/types/Analysis/Pipeline/PipelineStage.d.ts +17 -0
- package/dist/types/Analysis/Utils/color-utils.d.ts +60 -0
- package/dist/types/Analysis/__tests__/Integration.test.d.ts +8 -0
- package/dist/types/Analysis/__tests__/PaletteRemap.test.d.ts +14 -0
- package/dist/types/Analysis/__tests__/Pipeline.test.d.ts +10 -0
- package/dist/types/Analysis/__tests__/RoundTrip.test.d.ts +30 -0
- package/dist/types/Analysis/__tests__/SymbolAnalyzer.test.d.ts +11 -0
- package/dist/types/Analysis/index.d.ts +40 -0
- package/dist/types/BBCode/BBCodeDocumentModel.d.ts +92 -0
- package/dist/types/BBCode/BBCodeToGreenNode.d.ts +111 -0
- package/dist/types/BBCode/Parser.d.ts +78 -0
- package/dist/types/BBCode/index.d.ts +4 -0
- package/dist/types/Collab/positions.d.ts +55 -0
- package/dist/types/Commands/Command.d.ts +37 -0
- package/dist/types/Commands/CommandRegistry.d.ts +48 -0
- package/dist/types/Commands/DeleteNode.d.ts +7 -0
- package/dist/types/Commands/InsertText.d.ts +8 -0
- package/dist/types/Commands/SplitMerge.d.ts +9 -0
- package/dist/types/Commands/WrapInTag.d.ts +8 -0
- package/dist/types/Commands/index.d.ts +6 -0
- package/dist/types/Diff/TreeDiffer.d.ts +52 -0
- package/dist/types/Diff/__tests__/TreeDiffer.test.d.ts +1 -0
- package/dist/types/Diff/index.d.ts +2 -0
- package/dist/types/Edits/EditPlan.d.ts +144 -0
- package/dist/types/Edits/Optimizer.d.ts +78 -0
- package/dist/types/Edits/Rules/Rule.d.ts +91 -0
- package/dist/types/Edits/Rules/dropEmptyTags.d.ts +40 -0
- package/dist/types/Edits/Rules/dropRedundantNesting.d.ts +59 -0
- package/dist/types/Edits/Rules/index.d.ts +9 -0
- package/dist/types/Edits/Rules/mergeAdjacent.d.ts +93 -0
- package/dist/types/Edits/Rules/reorderWrappers.d.ts +42 -0
- package/dist/types/Edits/Rules/shortenHex.d.ts +30 -0
- package/dist/types/Edits/Rules/tagValue.d.ts +56 -0
- package/dist/types/Edits/Rules/unwrapInvisibleColor.d.ts +47 -0
- package/dist/types/Edits/applyEdits.d.ts +36 -0
- package/dist/types/Edits/index.d.ts +6 -0
- package/dist/types/Events/EventBus.d.ts +103 -0
- package/dist/types/Events/index.d.ts +2 -0
- package/dist/types/Formatter/Formatter.d.ts +32 -0
- package/dist/types/Formatter/index.d.ts +2 -0
- package/dist/types/HTML/HTMLDocumentModel.d.ts +13 -0
- package/dist/types/HTML/HTMLToGreenNode.d.ts +4 -0
- package/dist/types/Incremental/BracketIndex.d.ts +101 -0
- package/dist/types/Incremental/ChangeTracker.d.ts +69 -0
- package/dist/types/Incremental/IncrementalParser.d.ts +246 -0
- package/dist/types/Incremental/__tests__/BracketIndex.test.d.ts +1 -0
- package/dist/types/Incremental/__tests__/IncrementalParser.test.d.ts +1 -0
- package/dist/types/Incremental/index.d.ts +4 -0
- package/dist/types/Lexer/BBCodeLexer.d.ts +74 -0
- package/dist/types/Lexer/Lexer.d.ts +54 -0
- package/dist/types/Lexer/index.d.ts +4 -0
- package/dist/types/Linter/Linter.d.ts +58 -0
- package/dist/types/Linter/index.d.ts +2 -0
- package/dist/types/Markdown/MarkdownAST.d.ts +122 -0
- package/dist/types/Markdown/MarkdownDocumentModel.d.ts +15 -0
- package/dist/types/Markdown/MarkdownLexer.d.ts +155 -0
- package/dist/types/Markdown/MarkdownParser.d.ts +42 -0
- package/dist/types/Markdown/MarkdownToGreenNode.d.ts +6 -0
- package/dist/types/MilHibri/MilHibriDocumentModel.d.ts +21 -0
- package/dist/types/Model/DocumentModel.d.ts +318 -0
- package/dist/types/Model/NodeFactory.d.ts +29 -0
- package/dist/types/Model/TagRegistry.d.ts +165 -0
- package/dist/types/Model/index.d.ts +5 -0
- package/dist/types/Plugins/PluginAPI.d.ts +44 -0
- package/dist/types/Plugins/PluginRegistry.d.ts +81 -0
- package/dist/types/Plugins/index.d.ts +3 -0
- package/dist/types/Queries/QueryEngine.d.ts +32 -0
- package/dist/types/Queries/index.d.ts +1 -0
- package/dist/types/Reconciler/SurgicalReconciler.d.ts +23 -0
- package/dist/types/RenderPipeline/RenderPipeline.d.ts +46 -0
- package/dist/types/RenderPipeline/RenderTree.d.ts +55 -0
- package/dist/types/RenderPipeline/index.d.ts +4 -0
- package/dist/types/Repair/NestingRepair.d.ts +48 -0
- package/dist/types/Repair/index.d.ts +1 -0
- package/dist/types/Semantic/SemanticAnalyzer.d.ts +321 -0
- package/dist/types/Semantic/index.d.ts +2 -0
- package/dist/types/Symbols/SymbolTable.d.ts +47 -0
- package/dist/types/Symbols/index.d.ts +1 -0
- package/dist/types/Syntax/GreenNode.d.ts +154 -0
- package/dist/types/Syntax/GreenNodePool.d.ts +134 -0
- package/dist/types/Syntax/NodeMatcher.d.ts +75 -0
- package/dist/types/Syntax/RedNode.d.ts +280 -0
- package/dist/types/Syntax/RedNodeStore.d.ts +116 -0
- package/dist/types/Syntax/TreeBuilder.d.ts +54 -0
- package/dist/types/Syntax/__tests__/GreenNode.test.d.ts +1 -0
- package/dist/types/Syntax/__tests__/RedNode.test.d.ts +1 -0
- package/dist/types/Syntax/__tests__/RedNodeStore.test.d.ts +1 -0
- package/dist/types/Syntax/greenEdit.d.ts +64 -0
- package/dist/types/Syntax/hash.d.ts +17 -0
- package/dist/types/Syntax/index.d.ts +8 -0
- package/dist/types/Syntax/nodeAttr.d.ts +63 -0
- package/dist/types/Syntax/partition.d.ts +67 -0
- package/dist/types/Syntax/preserveNodeIds.d.ts +47 -0
- package/dist/types/Tokens/TokenResolver.d.ts +25 -0
- package/dist/types/Tokens/index.d.ts +1 -0
- package/dist/types/Transactions/Transaction.d.ts +36 -0
- package/dist/types/Transactions/UndoManager.d.ts +63 -0
- package/dist/types/Transactions/index.d.ts +3 -0
- package/dist/types/Transformers/ASTOptimizer.d.ts +34 -0
- package/dist/types/Transformers/GradientTransformer.d.ts +18 -0
- package/dist/types/Transformers/GrowTransformer.d.ts +16 -0
- package/dist/types/Transformers/RainbowTransformer.d.ts +17 -0
- package/dist/types/Transformers/SineWaveTransformer.d.ts +17 -0
- package/dist/types/Transformers/Transformer.d.ts +17 -0
- package/dist/types/Types/core.d.ts +104 -0
- package/dist/types/Types/diagnostics.d.ts +85 -0
- package/dist/types/Types/index.d.ts +11 -0
- package/dist/types/Types/operations.d.ts +109 -0
- package/dist/types/Types/queries.d.ts +67 -0
- package/dist/types/Types/symbols.d.ts +42 -0
- package/dist/types/Types/tokens.d.ts +75 -0
- package/dist/types/Utils/BBCodeGenerator.d.ts +21 -0
- package/dist/types/Utils/ColorMath.d.ts +92 -0
- package/dist/types/Utils/EffectMath.d.ts +643 -0
- package/dist/types/Utils/TagVocabulary.d.ts +104 -0
- package/dist/types/Utils/TagVocabulary.test.d.ts +1 -0
- package/dist/types/Utils/color.d.ts +29 -0
- package/dist/types/Utils/dom-to-svg.d.ts +28 -0
- package/dist/types/Utils/dom-to-svg.test.d.ts +1 -0
- package/dist/types/Utils/treeTransformers.d.ts +160 -0
- package/dist/types/Visitors/BBBlocksExporter.d.ts +27 -0
- package/dist/types/Visitors/BBCodeExporter.d.ts +90 -0
- package/dist/types/Visitors/BlockPatcher.d.ts +91 -0
- package/dist/types/Visitors/DOMMorpher.d.ts +13 -0
- package/dist/types/Visitors/HTMLRenderer.d.ts +380 -0
- package/dist/types/Visitors/JSONExporter.d.ts +42 -0
- package/dist/types/Visitors/MarkdownExporter.d.ts +28 -0
- package/dist/types/Visitors/SVGRenderer.d.ts +16 -0
- package/dist/types/Visitors/TiptapExporter.d.ts +40 -0
- package/dist/types/Visitors/Visitor.d.ts +35 -0
- package/dist/types/Visitors/index.d.ts +9 -0
- package/dist/types/Visuals/BoxDrawer.d.ts +49 -0
- package/dist/types/Visuals/index.d.ts +38 -0
- package/dist/types/index.d.ts +154 -0
- package/package.json +14 -10
- package/src/Analysis/Passes/Analysis/ColorUsageAnalyzer.ts +103 -0
- package/src/Analysis/Passes/Analysis/GradientAnalyzer.ts +294 -20
- package/src/Analysis/Passes/Analysis/SymbolAnalyzer.ts +257 -0
- package/src/Analysis/Passes/Decision/PaletteRemapDecision.ts +425 -0
- package/src/Analysis/Pipeline/Pipeline.ts +15 -2
- package/src/Analysis/index.ts +8 -2
- package/src/BBCode/BBCodeDocumentModel.ts +3 -0
- package/src/BBCode/BBCodeToGreenNode.ts +18 -12
- package/src/BBCode/Parser.ts +38 -1
- package/src/Edits/EditPlan.ts +290 -0
- package/src/Edits/Optimizer.ts +185 -0
- package/src/Edits/Rules/Rule.ts +145 -0
- package/src/Edits/Rules/dropEmptyTags.ts +110 -0
- package/src/Edits/Rules/dropRedundantNesting.ts +120 -0
- package/src/Edits/Rules/index.ts +28 -0
- package/src/Edits/Rules/mergeAdjacent.ts +224 -0
- package/src/Edits/Rules/reorderWrappers.ts +154 -0
- package/src/Edits/Rules/shortenHex.ts +79 -0
- package/src/Edits/Rules/tagValue.ts +105 -0
- package/src/Edits/Rules/unwrapInvisibleColor.ts +93 -0
- package/src/Edits/applyEdits.ts +54 -0
- package/src/Edits/index.ts +22 -0
- package/src/Events/EventBus.ts +18 -0
- package/src/HTML/HTMLToGreenNode.ts +185 -37
- package/src/Incremental/BracketIndex.ts +249 -0
- package/src/Incremental/IncrementalParser.ts +464 -41
- package/src/Lexer/BBCodeLexer.ts +25 -3
- package/src/Lexer/index.ts +1 -1
- package/src/Markdown/MarkdownAST.ts +65 -2
- package/src/Markdown/MarkdownLexer.ts +69 -14
- package/src/Markdown/MarkdownParser.ts +749 -62
- package/src/Markdown/MarkdownToGreenNode.ts +148 -27
- package/src/MilHibri/MilHibriDocumentModel.ts +56 -0
- package/src/Model/DocumentModel.ts +138 -5
- package/src/Model/TagRegistry.ts +129 -134
- package/src/Reconciler/SurgicalReconciler.ts +460 -0
- package/src/Repair/NestingRepair.ts +116 -0
- package/src/Repair/index.ts +1 -0
- package/src/Semantic/SemanticAnalyzer.ts +1802 -65
- package/src/Syntax/GreenNodePool.ts +12 -12
- package/src/Syntax/RedNode.ts +17 -3
- package/src/Syntax/RedNodeStore.ts +9 -1
- package/src/Syntax/nodeAttr.ts +172 -0
- package/src/Tokens/TokenResolver.ts +55 -0
- package/src/Tokens/index.ts +1 -0
- package/src/Types/core.ts +15 -0
- package/src/Utils/ColorMath.ts +276 -55
- package/src/Utils/EffectMath.ts +2462 -0
- package/src/Utils/TagVocabulary.ts +141 -0
- package/src/Utils/dom-to-svg.ts +28 -12
- package/src/Visitors/BBBlocksExporter.ts +15 -1
- package/src/Visitors/BBCodeExporter.ts +319 -32
- package/src/Visitors/BlockPatcher.ts +87 -11
- package/src/Visitors/DOMMorpher.ts +15 -5
- package/src/Visitors/HTMLRenderer.ts +374 -151
- package/src/Visitors/MarkdownExporter.ts +98 -41
- package/src/Visitors/TiptapExporter.ts +1 -0
- package/src/Visuals/index.ts +7 -4
- package/src/Visuals/lyne.css +117 -6
- package/src/Visuals/osu.css +36 -5
- package/src/index.ts +172 -5
- package/dist/index.d.mts +0 -4612
- package/dist/index.d.ts +0 -4612
- package/src/Analysis/Passes/Analysis/__tests__/GradientAnalyzer.test.ts +0 -135
- package/src/Analysis/Passes/Analysis/__tests__/MergeableColorAnalyzer.test.ts +0 -84
- package/src/Analysis/Passes/Analysis/__tests__/RainbowAnalyzer.test.ts +0 -99
- package/src/Analysis/Passes/Analysis/__tests__/WaveAnalyzer.test.ts +0 -119
- package/src/Analysis/Passes/Decision/__tests__/DefaultDecision.test.ts +0 -179
- package/src/Analysis/__tests__/Integration.test.ts +0 -162
- package/src/Analysis/__tests__/Pipeline.test.ts +0 -133
- package/src/Diff/__tests__/TreeDiffer.test.ts +0 -65
- package/src/Incremental/__tests__/IncrementalParser.test.ts +0 -164
- package/src/Syntax/__tests__/GreenNode.test.ts +0 -33
- package/src/Syntax/__tests__/RedNode.test.ts +0 -81
- package/src/Syntax/__tests__/RedNodeStore.test.ts +0 -104
- package/src/Tests/ASTOptimizerIdempotence.test.ts +0 -77
- package/src/Tests/BlockPatcher.test.ts +0 -437
- package/src/Tests/BlockPatcherWindowed.test.ts +0 -364
- package/src/Tests/BoxDrawer.test.ts +0 -217
- package/src/Tests/BoxRichTitle.test.ts +0 -105
- package/src/Tests/Chars500kBenchmark.test.ts +0 -151
- package/src/Tests/Chars500kEdits.test.ts +0 -321
- package/src/Tests/CollabPositions.test.ts +0 -146
- package/src/Tests/CompilerPathProfiling.test.ts +0 -186
- package/src/Tests/DOMMorpher.test.ts +0 -142
- package/src/Tests/DomPatchPerf.test.ts +0 -60
- package/src/Tests/EffectSegments.snapshot.json +0 -616
- package/src/Tests/EffectSegments.test.ts +0 -68
- package/src/Tests/FindNodeAtOffset.test.ts +0 -65
- package/src/Tests/Fuzzer.test.ts +0 -166
- package/src/Tests/GreenNodePool.test.ts +0 -153
- package/src/Tests/Lexer.test.ts +0 -238
- package/src/Tests/LyneMode.test.ts +0 -291
- package/src/Tests/ModelCoherence.test.ts +0 -180
- package/src/Tests/Partition.test.ts +0 -238
- package/src/Tests/PluginTags.test.ts +0 -150
- package/src/Tests/ProblematicSection.test.ts +0 -46
- package/src/Tests/ProblematicSectionHTML.test.ts +0 -58
- package/src/Tests/RedReuse.test.ts +0 -134
- package/src/Tests/ReproDelete20k.test.ts +0 -62
- package/src/Tests/SemanticValidators.test.ts +0 -136
- package/src/Tests/StableNodeIds.test.ts +0 -210
- package/src/Tests/StudioColorBloat.test.ts +0 -25
- package/src/Tests/StudioDebugText.test.ts +0 -27
- package/src/Tests/StudioTrailingChar.test.ts +0 -25
- package/src/Tests/StudioValidText.test.ts +0 -25
- package/src/Tests/UrlImgBug.test.ts +0 -23
- package/src/Tests/VisualBuilderFidelity.test.ts +0 -105
- package/src/Tests/referenceDocument.ts +0 -119
- package/src/Utils/dom-to-svg.test.ts +0 -86
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quasar — Enumerated attribute vocabularies
|
|
3
|
+
*
|
|
4
|
+
* Some tags take an attribute that is not free text: `[effect=glow]`,
|
|
5
|
+
* `[anim=glitch]`, `[container=grid]`, `[separator=dots]`. The set of values
|
|
6
|
+
* each one accepts was, until now, knowable only by reading the `switch` in
|
|
7
|
+
* `HTMLRenderer` — so the editor could offer tag names but never values, and
|
|
8
|
+
* an author had to remember thirty-six magic words.
|
|
9
|
+
*
|
|
10
|
+
* ── Why this is a problem worth a module ──
|
|
11
|
+
*
|
|
12
|
+
* Every one of those switches ends in a `default:`, and none of the defaults
|
|
13
|
+
* is an error. A misspelling does not fail; it renders something else:
|
|
14
|
+
*
|
|
15
|
+
* [anim=glich] → `bb-pulse` (a different animation)
|
|
16
|
+
* [container=gird] → `bb-stack` (a different container)
|
|
17
|
+
* [effect=nen] → a bare span (no effect at all)
|
|
18
|
+
* [img=round,shadow]→ ignored (`parseImgAttr` is exclusive, not flags)
|
|
19
|
+
*
|
|
20
|
+
* The author sees a preview that works and never learns the value was wrong.
|
|
21
|
+
* Offering the vocabulary at the point of typing is the cheapest fix, and it
|
|
22
|
+
* needs the vocabulary to exist as data rather than as control flow.
|
|
23
|
+
*
|
|
24
|
+
* ── Why here and not in the editor ──
|
|
25
|
+
*
|
|
26
|
+
* This is the engine's knowledge: the renderer decides what `glow` means, so
|
|
27
|
+
* the renderer's package owns the list of what is spellable. A copy in the
|
|
28
|
+
* editor would be a fourth transcription of an engine fact, which is the
|
|
29
|
+
* exact mistake `TagSyntax` and `EffectMath` were both written to undo.
|
|
30
|
+
*
|
|
31
|
+
* `TagVocabulary.test.ts` pins every value below to the renderer: a value
|
|
32
|
+
* that stops being handled starts rendering as the fallback, and the test
|
|
33
|
+
* fails. The list cannot silently drift away from the behaviour.
|
|
34
|
+
*
|
|
35
|
+
* Human-readable descriptions are deliberately NOT here. Quasar has no
|
|
36
|
+
* locales; the editor names these values through its own i18n.
|
|
37
|
+
*/
|
|
38
|
+
/** How an attribute's value is written. */
|
|
39
|
+
export type VocabularySyntax =
|
|
40
|
+
/** Exactly one of `values`. */
|
|
41
|
+
'enum'
|
|
42
|
+
/** Any subset of `values`, comma- or space-separated. */
|
|
43
|
+
| 'flags';
|
|
44
|
+
export interface AttributeVocabulary {
|
|
45
|
+
/** The tag whose attribute this describes. */
|
|
46
|
+
tag: string;
|
|
47
|
+
/** Every value the engine actually handles, in the renderer's own order. */
|
|
48
|
+
values: readonly string[];
|
|
49
|
+
syntax: VocabularySyntax;
|
|
50
|
+
/**
|
|
51
|
+
* The value an unrecognised attribute behaves as, or `null` when an
|
|
52
|
+
* unrecognised attribute simply does nothing.
|
|
53
|
+
*
|
|
54
|
+
* This is the honest part: it is what the `default:` branch does, not what
|
|
55
|
+
* the documentation wishes it did.
|
|
56
|
+
*/
|
|
57
|
+
fallback: string | null;
|
|
58
|
+
/**
|
|
59
|
+
* Whether a `:<param>` suffix is read after the value.
|
|
60
|
+
*
|
|
61
|
+
* What the suffix MEANS is per value, not per tag, which is why this is
|
|
62
|
+
* only a boolean: `[effect=glow:#2EE6E2]` and `[tables=striped:#hex]` take
|
|
63
|
+
* a colour, but `[container=grid:3]` takes a column count and
|
|
64
|
+
* `[container=flex:12]` a gap in pixels. Completion needs no more than
|
|
65
|
+
* "there is a suffix here, and it is not part of the vocabulary".
|
|
66
|
+
*/
|
|
67
|
+
suffixed: boolean;
|
|
68
|
+
}
|
|
69
|
+
/** `[effect=…]` — `HTMLRenderer.renderEffect`. */
|
|
70
|
+
export declare const EFFECT_TYPES: readonly ['glow', 'neon', 'outline', 'emboss', 'engrave', 'shimmer', 'ghost', 'rainbow', 'fire', 'ice'];
|
|
71
|
+
/** `[anim=…]` — `HTMLRenderer.renderAnim`. */
|
|
72
|
+
export declare const ANIM_TYPES: readonly ['bounce', 'shake', 'pulse', 'fade-in', 'fade-out', 'typewriter', 'wave', 'sparkle', 'glitch', 'levitate'];
|
|
73
|
+
/**
|
|
74
|
+
* `[container=…]` — `HTMLRenderer.renderContainer`.
|
|
75
|
+
*
|
|
76
|
+
* `neonbox` is the unhyphenated spelling of `neon-box` and renders
|
|
77
|
+
* identically; it stays in the list because a document may carry it, but the
|
|
78
|
+
* hyphenated form is the canonical one and comes first.
|
|
79
|
+
*/
|
|
80
|
+
export declare const CONTAINER_TYPES: readonly ['stack', 'flex', 'grid', 'middle', 'square', 'circle', 'card', 'glass', 'neon-box', 'neonbox'];
|
|
81
|
+
/** `[separator=…]` — `HTMLRenderer.renderSeparator`. */
|
|
82
|
+
export declare const SEPARATOR_VARIANTS: readonly ['line', 'dots', 'stars'];
|
|
83
|
+
/** `[tables=…]` — `HTMLRenderer.renderTables`. Combinable. */
|
|
84
|
+
export declare const TABLE_FLAGS: readonly ['striped', 'borders'];
|
|
85
|
+
/**
|
|
86
|
+
* `[img=…]` — `parseImgAttr` in `Syntax/nodeAttr`.
|
|
87
|
+
*
|
|
88
|
+
* Exclusive despite reading like flags: the parser returns on the first
|
|
89
|
+
* match, so `[img=round,shadow]` yields neither. A dimension pair
|
|
90
|
+
* (`[img=200x100]`) is the other accepted form and is not enumerable.
|
|
91
|
+
*/
|
|
92
|
+
export declare const IMG_MODIFIERS: readonly ['round', 'shadow', 'float'];
|
|
93
|
+
/**
|
|
94
|
+
* The vocabulary for a tag's attribute, or `null` when its attribute is free
|
|
95
|
+
* text (`[box=Título]`, `[url=…]`, `[size=200]`).
|
|
96
|
+
*
|
|
97
|
+
* Case-insensitive, because the renderer lowercases before matching.
|
|
98
|
+
*
|
|
99
|
+
* Note this answers only "what can be spelled here"; whether the tag exists
|
|
100
|
+
* at all is a dialect question, and the caller already knows the dialect.
|
|
101
|
+
*/
|
|
102
|
+
export declare function attributeVocabularyFor(tag: string): AttributeVocabulary | null;
|
|
103
|
+
/** Every vocabulary, for tests and for tooling that enumerates them. */
|
|
104
|
+
export declare function allAttributeVocabularies(): readonly AttributeVocabulary[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quasar — Color Utilities
|
|
3
|
+
*
|
|
4
|
+
* Standalone color functions for gradient/grow/exporter interpolation.
|
|
5
|
+
* No external dependencies — pure math.
|
|
6
|
+
*
|
|
7
|
+
* Ported from TextStudio/lib/color.ts (originally backed by culori).
|
|
8
|
+
* These are the minimal subset needed for internal tag export.
|
|
9
|
+
*/
|
|
10
|
+
export type Easing = 'linear' | 'easeIn' | 'easeOut' | 'easeInOut';
|
|
11
|
+
/**
|
|
12
|
+
* Mix two hex colors via linear RGB interpolation.
|
|
13
|
+
* t in [0, 1] — 0 = from, 1 = to.
|
|
14
|
+
*/
|
|
15
|
+
export declare function mixHex(from: string, to: string, t: number): string;
|
|
16
|
+
/**
|
|
17
|
+
* Mix across multiple hex colors.
|
|
18
|
+
* t in [0, 1] maps across the color array linearly.
|
|
19
|
+
*/
|
|
20
|
+
export declare function mixMultiple(colors: string[], t: number): string;
|
|
21
|
+
/**
|
|
22
|
+
* Convert HSL to hex string.
|
|
23
|
+
* @param h hue in [0, 360]
|
|
24
|
+
* @param s saturation in [0, 1]
|
|
25
|
+
* @param l lightness in [0, 1]
|
|
26
|
+
*/
|
|
27
|
+
export declare function hslToHex(h: number, s: number, l: number): string;
|
|
28
|
+
export declare function clamp(n: number, min?: number, max?: number): number;
|
|
29
|
+
export declare function ease(t: number, kind: Easing): number;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface DomToSVGOptions {
|
|
2
|
+
backgroundColor?: string;
|
|
3
|
+
includeBackground?: boolean;
|
|
4
|
+
/** Scale factor applied to all coordinates (default 1) */
|
|
5
|
+
scale?: number;
|
|
6
|
+
/** Maximum unscaled height in pixels to scan and render into the SVG (useful for thumbnails). Elements and lines below this cutoff are omitted. */
|
|
7
|
+
maxHeight?: number;
|
|
8
|
+
}
|
|
9
|
+
export interface SVGLayerInfo {
|
|
10
|
+
id: string;
|
|
11
|
+
tag: string;
|
|
12
|
+
depth: number;
|
|
13
|
+
x: number;
|
|
14
|
+
y: number;
|
|
15
|
+
width: number;
|
|
16
|
+
height: number;
|
|
17
|
+
type: 'image' | 'iframe' | 'audio' | 'background' | 'border' | 'group' | 'text';
|
|
18
|
+
text?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface DomToSVGResult {
|
|
21
|
+
svg: string;
|
|
22
|
+
width: number;
|
|
23
|
+
height: number;
|
|
24
|
+
layerCount: number;
|
|
25
|
+
layers: SVGLayerInfo[];
|
|
26
|
+
}
|
|
27
|
+
export declare function domToSVG(root: HTMLElement, options?: DomToSVGOptions): string;
|
|
28
|
+
export declare function domToSVGResult(root: HTMLElement, options?: DomToSVGOptions): DomToSVGResult;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quasar — Tree Transformers
|
|
3
|
+
*
|
|
4
|
+
* Apply effects (gradient, grow, rainbow, central, multi) across an entire RedNode tree.
|
|
5
|
+
* These functions walk the tree, track global text position,
|
|
6
|
+
* and wrap each text leaf in internal effect nodes
|
|
7
|
+
* with position metadata so the TagRegistry handlers produce
|
|
8
|
+
* correctly interpolated output.
|
|
9
|
+
*
|
|
10
|
+
* DESIGN:
|
|
11
|
+
* Two-pass approach:
|
|
12
|
+
* 1. Collect total text length (for normalization)
|
|
13
|
+
* 2. Walk again, wrapping text nodes with effect nodes
|
|
14
|
+
*
|
|
15
|
+
* Non-text nodes (img, video, audio, code blocks) are preserved unchanged.
|
|
16
|
+
* Structural nodes (box, quote, list) recurse into children.
|
|
17
|
+
* Formatting nodes (b, i, u, color) recurse — effects go INSIDE formatting.
|
|
18
|
+
*
|
|
19
|
+
* Example:
|
|
20
|
+
* Input: [box][b]Hello[/b] World[/box]
|
|
21
|
+
* Output: [box][b][gradient][b]H[/b][gradient][b]e[/b]...[/b]
|
|
22
|
+
* [gradient] W[/gradient]...[/gradient]
|
|
23
|
+
*
|
|
24
|
+
* Actually simpler — each text leaf gets its own gradient node with
|
|
25
|
+
* globalOffset metadata, and the handler does the interpolation.
|
|
26
|
+
*/
|
|
27
|
+
import { RedNode } from '../Syntax/RedNode';
|
|
28
|
+
import type { Easing } from './color';
|
|
29
|
+
export interface GradientEffect {
|
|
30
|
+
kind: 'gradient';
|
|
31
|
+
colors: string[];
|
|
32
|
+
unit?: 'character' | 'word' | 'line';
|
|
33
|
+
easing?: Easing;
|
|
34
|
+
}
|
|
35
|
+
export interface GrowEffect {
|
|
36
|
+
kind: 'grow';
|
|
37
|
+
min?: number;
|
|
38
|
+
max?: number;
|
|
39
|
+
cycles?: number;
|
|
40
|
+
}
|
|
41
|
+
export interface RainbowEffect {
|
|
42
|
+
kind: 'rainbow';
|
|
43
|
+
saturation?: number;
|
|
44
|
+
lightness?: number;
|
|
45
|
+
spread?: number;
|
|
46
|
+
offset?: number;
|
|
47
|
+
}
|
|
48
|
+
export interface CentralGradientEffect {
|
|
49
|
+
kind: 'central_gradient';
|
|
50
|
+
colors: string[];
|
|
51
|
+
unit?: 'character' | 'word' | 'line';
|
|
52
|
+
easing?: Easing;
|
|
53
|
+
}
|
|
54
|
+
export interface MultiGradientEffect {
|
|
55
|
+
kind: 'multi_gradient';
|
|
56
|
+
colors: string[];
|
|
57
|
+
mode?: 'wave' | 'pulse';
|
|
58
|
+
unit?: 'character' | 'word' | 'line';
|
|
59
|
+
easing?: Easing;
|
|
60
|
+
}
|
|
61
|
+
export type TreeEffect = GradientEffect | GrowEffect | RainbowEffect | CentralGradientEffect | MultiGradientEffect;
|
|
62
|
+
/**
|
|
63
|
+
* Count total plain text length across all text leaves in a tree.
|
|
64
|
+
*/
|
|
65
|
+
export declare function countTextLength(node: RedNode): number;
|
|
66
|
+
/**
|
|
67
|
+
* Apply a gradient effect across an entire RedNode tree.
|
|
68
|
+
*
|
|
69
|
+
* The gradient is computed across ALL text content in the tree,
|
|
70
|
+
* so color transitions span across structural boundaries:
|
|
71
|
+
*
|
|
72
|
+
* [b]Hello[/b] World → [b][color=#FF0000]H[/color]...[/b][color=#00FF00]W[/color]...
|
|
73
|
+
*
|
|
74
|
+
* @param root The RedNode tree to transform
|
|
75
|
+
* @param colors Array of hex colors to interpolate across
|
|
76
|
+
* @param options.unit Split unit: 'character' (default), 'word', or 'line'
|
|
77
|
+
* @param options.easing Easing function: 'linear' (default), 'easeIn', 'easeOut', 'easeInOut'
|
|
78
|
+
* @returns A new RedNode tree with gradient applied
|
|
79
|
+
*/
|
|
80
|
+
export declare function applyGradient(root: RedNode, colors: string[], options?: {
|
|
81
|
+
unit?: 'character' | 'word' | 'line';
|
|
82
|
+
easing?: Easing;
|
|
83
|
+
}): RedNode;
|
|
84
|
+
/**
|
|
85
|
+
* Apply a grow (size wave) effect across an entire RedNode tree.
|
|
86
|
+
*
|
|
87
|
+
* Size oscillates via sine wave across ALL text content:
|
|
88
|
+
*
|
|
89
|
+
* [b]Hello[/b] World → [b][size=90]H[/size]...[/b][size=160]W[/size]...
|
|
90
|
+
*
|
|
91
|
+
* @param root The RedNode tree to transform
|
|
92
|
+
* @param options.min Minimum size % (default: 90)
|
|
93
|
+
* @param options.max Maximum size % (default: 160)
|
|
94
|
+
* @param options.cycles Number of sine cycles across text (default: 1)
|
|
95
|
+
* @returns A new RedNode tree with grow applied
|
|
96
|
+
*/
|
|
97
|
+
export declare function applyGrow(root: RedNode, options?: {
|
|
98
|
+
min?: number;
|
|
99
|
+
max?: number;
|
|
100
|
+
cycles?: number;
|
|
101
|
+
}): RedNode;
|
|
102
|
+
/**
|
|
103
|
+
* Apply a rainbow effect across an entire RedNode tree.
|
|
104
|
+
*
|
|
105
|
+
* Hue rotates across ALL text content using HSL color space:
|
|
106
|
+
*
|
|
107
|
+
* [b]Hello[/b] World → [b][color=#FF0000]H[/color]...[/b][color=#00FF00]W[/color]...
|
|
108
|
+
*
|
|
109
|
+
* @param root The RedNode tree to transform
|
|
110
|
+
* @param options.saturation Saturation 0-100 (default: 80)
|
|
111
|
+
* @param options.lightness Lightness 0-100 (default: 60)
|
|
112
|
+
* @param options.spread Hue spread in degrees (default: 300)
|
|
113
|
+
* @param options.offset Starting hue offset in degrees (default: 0)
|
|
114
|
+
* @returns A new RedNode tree with rainbow applied
|
|
115
|
+
*/
|
|
116
|
+
export declare function applyRainbow(root: RedNode, options?: {
|
|
117
|
+
saturation?: number;
|
|
118
|
+
lightness?: number;
|
|
119
|
+
spread?: number;
|
|
120
|
+
offset?: number;
|
|
121
|
+
}): RedNode;
|
|
122
|
+
/**
|
|
123
|
+
* Apply a central gradient across an entire RedNode tree.
|
|
124
|
+
*
|
|
125
|
+
* Gradient radiates from center outward (mirrored):
|
|
126
|
+
*
|
|
127
|
+
* [b]Hello[/b] World → [b][color=#FF0000]H[/color]...[/b][color=#00FF00]W[/color]...
|
|
128
|
+
*
|
|
129
|
+
* @param root The RedNode tree to transform
|
|
130
|
+
* @param colors Array of hex colors to interpolate across
|
|
131
|
+
* @param options.unit Split unit: 'character' (default), 'word', or 'line'
|
|
132
|
+
* @param options.easing Easing function: 'linear' (default), 'easeIn', 'easeOut', 'easeInOut'
|
|
133
|
+
* @returns A new RedNode tree with central gradient applied
|
|
134
|
+
*/
|
|
135
|
+
export declare function applyCentralGradient(root: RedNode, colors: string[], options?: {
|
|
136
|
+
unit?: 'character' | 'word' | 'line';
|
|
137
|
+
easing?: Easing;
|
|
138
|
+
}): RedNode;
|
|
139
|
+
/**
|
|
140
|
+
* Apply a multi gradient (wave or pulse) across an entire RedNode tree.
|
|
141
|
+
*
|
|
142
|
+
* Wave mode: sine wave pattern across colors.
|
|
143
|
+
* Pulse mode: repeating gradient segments.
|
|
144
|
+
*
|
|
145
|
+
* @param root The RedNode tree to transform
|
|
146
|
+
* @param colors Array of hex colors to interpolate across
|
|
147
|
+
* @param options.mode 'wave' (default) or 'pulse'
|
|
148
|
+
* @param options.unit Split unit: 'character' (default), 'word', or 'line'
|
|
149
|
+
* @param options.easing Easing function: 'linear' (default), 'easeIn', 'easeOut', 'easeInOut'
|
|
150
|
+
* @returns A new RedNode tree with multi gradient applied
|
|
151
|
+
*/
|
|
152
|
+
export declare function applyMultiGradient(root: RedNode, colors: string[], options?: {
|
|
153
|
+
mode?: 'wave' | 'pulse';
|
|
154
|
+
unit?: 'character' | 'word' | 'line';
|
|
155
|
+
easing?: Easing;
|
|
156
|
+
}): RedNode;
|
|
157
|
+
/**
|
|
158
|
+
* Apply any supported effect across an entire RedNode tree.
|
|
159
|
+
*/
|
|
160
|
+
export declare function applyEffect(root: RedNode, effect: TreeEffect): RedNode;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Visitor } from './Visitor';
|
|
2
|
+
import type { VisitorContext } from './Visitor';
|
|
3
|
+
import { RedNode } from '../Syntax/RedNode';
|
|
4
|
+
export interface UIBBBlock {
|
|
5
|
+
id: string;
|
|
6
|
+
type: string;
|
|
7
|
+
attributes?: Record<string, string>;
|
|
8
|
+
children: UIBBBlock[];
|
|
9
|
+
content?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare class BBBlocksExporter extends Visitor<UIBBBlock[]> {
|
|
12
|
+
private idCounter;
|
|
13
|
+
/**
|
|
14
|
+
* Un identificador único dentro de ESTA exportación.
|
|
15
|
+
*
|
|
16
|
+
* Llevaba un `Date.now().toString(36)` por nodo. El reloj no aportaba nada
|
|
17
|
+
* —los identificadores solo tienen que distinguirse entre sí dentro del
|
|
18
|
+
* lote— y se leía, y se convertía a base 36, una vez por nodo del árbol.
|
|
19
|
+
* El prefijo se calcula una sola vez por exportador para que dos lotes
|
|
20
|
+
* consecutivos sigan sin colisionar.
|
|
21
|
+
*/
|
|
22
|
+
private readonly idPrefix;
|
|
23
|
+
private generateId;
|
|
24
|
+
visit(node: RedNode, context?: VisitorContext): UIBBBlock[];
|
|
25
|
+
export(root: RedNode): UIBBBlock[];
|
|
26
|
+
private exportNode;
|
|
27
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DocumentEngine — BBCodeExporter
|
|
3
|
+
*
|
|
4
|
+
* Exports the Document Model / Red Tree back to BBCode text.
|
|
5
|
+
* This is how the internal representation becomes editable text.
|
|
6
|
+
*
|
|
7
|
+
* Uses the TagRegistry to determine how each node serializes.
|
|
8
|
+
* Plugins can register custom serializers for custom tags.
|
|
9
|
+
*/
|
|
10
|
+
import { RedNode } from '../Syntax/RedNode';
|
|
11
|
+
import { Visitor } from './Visitor';
|
|
12
|
+
import type { VisitorContext } from './Visitor';
|
|
13
|
+
import { TagRegistry } from '../Model/TagRegistry';
|
|
14
|
+
import { type TokenResolverFn, type TokenSource } from '../Tokens';
|
|
15
|
+
/**
|
|
16
|
+
* Export target for BBCodeExporter.
|
|
17
|
+
* - 'osu': Expands Miliastry/Lyne-native tags into osu!-compatible BBCode.
|
|
18
|
+
* - 'miliastry': Preserves Miliastry-native tags as-is for round-trip editing.
|
|
19
|
+
* - 'lyne': Preserves Lyne-native tags as-is for round-trip editing.
|
|
20
|
+
*/
|
|
21
|
+
export type ExportTarget = 'osu' | 'miliastry' | 'lyne';
|
|
22
|
+
export interface BBCodeExporterOptions {
|
|
23
|
+
registry?: TagRegistry;
|
|
24
|
+
target?: ExportTarget;
|
|
25
|
+
tokens?: TokenSource;
|
|
26
|
+
resolveTokens?: boolean;
|
|
27
|
+
}
|
|
28
|
+
export type BBCodeExportOptions = {
|
|
29
|
+
target?: ExportTarget;
|
|
30
|
+
tokens?: TokenSource;
|
|
31
|
+
resolveTokens?: boolean;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Tags que existen SOLO en Miliastry (registrados en el TagRegistry) y que
|
|
35
|
+
* osu! NO renderiza. Si un usuario pega `[shadow]`/`[zalgo]`/etc. en osu!,
|
|
36
|
+
* el texto sale roto (los corchetes se ven literalmente). Cuando el target
|
|
37
|
+
* es 'osu', estos tags se DEGRADAN a su contenido plano: mejor perder el
|
|
38
|
+
* efecto que romper la userpage. El target 'miliastry' los conserva.
|
|
39
|
+
*/
|
|
40
|
+
export declare const MILIASTRY_ONLY_TAGS: Set<string>;
|
|
41
|
+
export declare const LYNE_ONLY_TAGS: Set<string>;
|
|
42
|
+
export declare class BBCodeExporter extends Visitor<string> {
|
|
43
|
+
private registry;
|
|
44
|
+
private depth;
|
|
45
|
+
private target;
|
|
46
|
+
private tokens?;
|
|
47
|
+
private tokenResolver?;
|
|
48
|
+
private explicitResolveTokens?;
|
|
49
|
+
/**
|
|
50
|
+
* El resolvedor a aplicar en ESTE recorrido, o `null` si no hay expansión.
|
|
51
|
+
*
|
|
52
|
+
* Se decide una vez en `visit`, no por nodo: `shouldResolveTokens()` da la
|
|
53
|
+
* misma respuesta para todo el documento, y se estaba llamando en la rama
|
|
54
|
+
* de nodo texto, la más frecuente que hay.
|
|
55
|
+
*/
|
|
56
|
+
private expandTokens;
|
|
57
|
+
constructor(registryOrOptions?: TagRegistry | BBCodeExporterOptions, target?: ExportTarget, options?: BBCodeExporterOptions | {
|
|
58
|
+
tokens?: TokenSource;
|
|
59
|
+
resolveTokens?: boolean;
|
|
60
|
+
});
|
|
61
|
+
/**
|
|
62
|
+
* Set the export target. Controls how Miliastry-native tags are serialized.
|
|
63
|
+
*/
|
|
64
|
+
setTarget(target: ExportTarget): void;
|
|
65
|
+
setTokens(tokens?: TokenSource): void;
|
|
66
|
+
getTokens(): TokenSource | undefined;
|
|
67
|
+
getTokenResolver(): TokenResolverFn | undefined;
|
|
68
|
+
private shouldResolveTokens;
|
|
69
|
+
/**
|
|
70
|
+
* Export a RedNode tree to BBCode.
|
|
71
|
+
*/
|
|
72
|
+
visit(node: RedNode, context?: VisitorContext): string;
|
|
73
|
+
/**
|
|
74
|
+
* Export the entire document to BBCode.
|
|
75
|
+
* Optionally override the export target or options for this specific call.
|
|
76
|
+
*/
|
|
77
|
+
export(root: RedNode, targetOrOptions?: ExportTarget | BBCodeExportOptions, options?: BBCodeExportOptions): string;
|
|
78
|
+
/**
|
|
79
|
+
* Exporta los hijos directos y los concatena.
|
|
80
|
+
*
|
|
81
|
+
* Reemplaza el `children.map(...).join('')`, que asignaba un cierre y un
|
|
82
|
+
* array intermedio de N cadenas en cada nivel del árbol. `HTMLRenderer`
|
|
83
|
+
* hizo este mismo cambio y dejó la nota; el exportador se quedó atrás, y es
|
|
84
|
+
* el camino que corre bajo un límite de 60.000 caracteres.
|
|
85
|
+
*/
|
|
86
|
+
private exportChildren;
|
|
87
|
+
private exportNode;
|
|
88
|
+
private kindToTagName;
|
|
89
|
+
private getTagAttributes;
|
|
90
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DocumentEngine — BlockPatcher
|
|
3
|
+
*
|
|
4
|
+
* Incremental rendering for the HTML preview.
|
|
5
|
+
*
|
|
6
|
+
* The naive path — `renderToHTML(root)` + `morphHTML(container, html)` on every
|
|
7
|
+
* keystroke — re-serializes the ENTIRE document to a string and, worse, makes
|
|
8
|
+
* the browser re-parse that whole string (`template.innerHTML`) even when only
|
|
9
|
+
* one character changed. Profiled on an 18.5 KB document: `morphHTML` ≈ 29.8 ms
|
|
10
|
+
* per keystroke, of which ~27 ms is the full-HTML parse (morph ≈ baseline
|
|
11
|
+
* `innerHTML=`). The parser itself is ~0.5 ms.
|
|
12
|
+
*
|
|
13
|
+
* This module makes the DOM update O(changed block) instead of O(document):
|
|
14
|
+
*
|
|
15
|
+
* - The document's top-level children are the independent "blocks".
|
|
16
|
+
* - With stable `data-node-id`s (see `preserveNodeIds`) a block that did not
|
|
17
|
+
* change renders to the SAME html string, or is even the SAME RedNode
|
|
18
|
+
* object (red-subtree reuse). Either way we can detect "unchanged" without
|
|
19
|
+
* touching the DOM.
|
|
20
|
+
* - Only changed blocks are re-rendered and re-morphed, in place, keyed by
|
|
21
|
+
* their element.
|
|
22
|
+
* - Structural edits — a block inserted, removed or reordered (Enter,
|
|
23
|
+
* backspace between blocks, moving a block in the visual builder) — are
|
|
24
|
+
* reconciled BY KEY too. The stable ids let us insert/remove/move ONLY the
|
|
25
|
+
* affected elements, so every untouched block keeps its DOM identity and
|
|
26
|
+
* runtime state (an open `<details>`, media playback). When the edit
|
|
27
|
+
* script adds more blocks than the previous document had (a whole new
|
|
28
|
+
* document patched into the same container, ids regenerated en masse) we
|
|
29
|
+
* fall back to a full rebuild: one `innerHTML` parse beats N per-block
|
|
30
|
+
* ones.
|
|
31
|
+
*
|
|
32
|
+
* DOM alignment — "runs": a top-level block may render to an element, to a
|
|
33
|
+
* bare text node (`text`, osu `spacing`/`empty_line` quirks) or to nothing
|
|
34
|
+
* (`''`, an empty text leaf). Two adjacent bare-text blocks are merged into a
|
|
35
|
+
* single text node by the HTML parser, so a block↔node 1:1 pairing would
|
|
36
|
+
* silently misalign after such a merge. The reconciliation therefore works on
|
|
37
|
+
* RUNS: consecutive bare-text blocks form one "text run" that maps to exactly
|
|
38
|
+
* one text node (mirroring the parser), and element blocks are their own runs.
|
|
39
|
+
* The run list is the exact 1:1 mirror of `container.childNodes`.
|
|
40
|
+
*/
|
|
41
|
+
import { RedNode } from '../Syntax/RedNode';
|
|
42
|
+
import { HTMLRenderer } from './HTMLRenderer';
|
|
43
|
+
import type { TextChangeRange } from '../Incremental/ChangeTracker';
|
|
44
|
+
export interface PatchBlocksOptions {
|
|
45
|
+
/** Renderer used to serialize blocks. Defaults to a shared HTMLRenderer. */
|
|
46
|
+
renderer?: HTMLRenderer;
|
|
47
|
+
/** Called when a block fails to morph; the caller can log it. */
|
|
48
|
+
onError?: (err: unknown) => void;
|
|
49
|
+
/**
|
|
50
|
+
* The source range of the edit that produced `rootNode`, if known.
|
|
51
|
+
*
|
|
52
|
+
* Lets the patcher reconcile ONLY the runs overlapping the edit (O(edit))
|
|
53
|
+
* instead of walking the whole document — the difference between ~2ms and
|
|
54
|
+
* ~100ms per keystroke on a 500k-character document. Coordinates are in
|
|
55
|
+
* new-source space with the old end kept separately; see `TextChangeRange`.
|
|
56
|
+
* When omitted, the patcher falls back to the full keyed reconcile — and it
|
|
57
|
+
* also reads the range attached to the root by `DocumentModel`.
|
|
58
|
+
*/
|
|
59
|
+
change?: TextChangeRange;
|
|
60
|
+
/**
|
|
61
|
+
* Minimum top-level blocks for the windowed path to run; below it the full
|
|
62
|
+
* keyed walk is cheaper than the windowed bookkeeping. Defaults to
|
|
63
|
+
* `MIN_WINDOWED_BLOCKS` (200). Tests force `0` to exercise the windowed
|
|
64
|
+
* path on small documents.
|
|
65
|
+
*/
|
|
66
|
+
minWindowedBlocks?: number;
|
|
67
|
+
/** If true, forces a full rebuild of the container instead of incremental patching. */
|
|
68
|
+
forceRebuild?: boolean;
|
|
69
|
+
}
|
|
70
|
+
export interface PatchBlocksStats {
|
|
71
|
+
/** Which path was taken. */
|
|
72
|
+
mode: 'full' | 'blocks';
|
|
73
|
+
/** Number of top-level blocks. */
|
|
74
|
+
total: number;
|
|
75
|
+
/** Blocks whose DOM was actually updated (0 = nothing changed). */
|
|
76
|
+
patched: number;
|
|
77
|
+
/** True when the windowed (O(edit)) reconcile ran, not the full keyed walk. */
|
|
78
|
+
windowed?: boolean;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Evict `container` from the patch cache so the next patch rebuilds afresh.
|
|
82
|
+
*/
|
|
83
|
+
export declare function clearPatchCache(container: HTMLElement): void;
|
|
84
|
+
/**
|
|
85
|
+
* Reconcile `container`'s children against `rootNode`'s top-level blocks.
|
|
86
|
+
*
|
|
87
|
+
* Inline edits morph only the changed block; structural edits (insert, remove,
|
|
88
|
+
* reorder) are reconciled by key so untouched blocks keep their DOM identity.
|
|
89
|
+
* Returns what was done so callers/tests can assert the fast path fired.
|
|
90
|
+
*/
|
|
91
|
+
export declare function patchBlocksInto(container: HTMLElement, rootNode: RedNode | null, options?: PatchBlocksOptions): PatchBlocksStats;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DocumentEngine — DOMMorpher
|
|
3
|
+
*
|
|
4
|
+
* Reconciles and morphs an existing HTML DOM tree in-place to match a new HTML string.
|
|
5
|
+
* Operating on pure HTML string output from HTMLRenderer means ZERO changes to Quasar AST schemas.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - In-place attribute synchronization
|
|
9
|
+
* - In-place text node value updates
|
|
10
|
+
* - Preserves state of unchanged elements (spoilers, audio/video, selections)
|
|
11
|
+
* - Zero extra wrapper <div> elements
|
|
12
|
+
*/
|
|
13
|
+
export declare function morphHTML(container: HTMLElement, newHTML: string): void;
|