@miliastry/quasar 1.0.6 → 1.2.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/README.md +1 -1
- package/dist/Visuals/lyne.css +374 -9
- package/dist/Visuals/osu.css +393 -11
- package/dist/index.js +10470 -3336
- package/dist/index.mjs +10336 -3337
- 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 +102 -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 +19 -0
- package/dist/types/Visitors/HTMLRenderer.d.ts +492 -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 +54 -0
- package/dist/types/Visuals/LyneAudio.d.ts +8 -0
- package/dist/types/Visuals/index.d.ts +39 -0
- package/dist/types/index.d.ts +155 -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 +39 -1
- 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 +193 -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 +1845 -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 +365 -32
- package/src/Visitors/BlockPatcher.ts +123 -22
- package/src/Visitors/DOMMorpher.ts +44 -28
- package/src/Visitors/HTMLRenderer.ts +771 -205
- package/src/Visitors/MarkdownExporter.ts +98 -41
- package/src/Visitors/TiptapExporter.ts +1 -0
- package/src/Visitors/index.ts +1 -1
- package/src/Visuals/BoxDrawer.ts +56 -10
- package/src/Visuals/LyneAudio.ts +346 -0
- package/src/Visuals/index.ts +8 -4
- package/src/Visuals/lyne.css +374 -9
- package/src/Visuals/osu.css +393 -11
- package/src/index.ts +178 -8
- 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,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DocumentEngine — BoxDrawer
|
|
3
|
+
*
|
|
4
|
+
* Drawer-style open/close animation for the `<details>` elements that
|
|
5
|
+
* HTMLRenderer emits for `[box]` and `[spoilerbox]`. The box grows downwards
|
|
6
|
+
* and progressively uncovers its content, which stays anchored under the
|
|
7
|
+
* summary instead of popping in all at once.
|
|
8
|
+
*
|
|
9
|
+
* This lives in Quasar rather than in a consumer because Quasar is what emits
|
|
10
|
+
* the `<details>` in the first place — the same reason `morphHTML` lives here.
|
|
11
|
+
* Any host that renders Quasar output gets the behaviour by binding it once.
|
|
12
|
+
*
|
|
13
|
+
* Why not CSS: while a `<details>` is closed its content is not rendered, so
|
|
14
|
+
* there is no height to interpolate between. `::details-content` combined with
|
|
15
|
+
* `interpolate-size: allow-keywords` would solve it, but it is Chromium-only in
|
|
16
|
+
* practice and hosts running on WebKit would silently lose the animation.
|
|
17
|
+
* Measuring the real height and driving it with the Web Animations API works on
|
|
18
|
+
* every engine.
|
|
19
|
+
*
|
|
20
|
+
* Heights are measured, not computed from summary + padding + borders, because
|
|
21
|
+
* that arithmetic breaks as soon as a theme puts margins on the summary or the
|
|
22
|
+
* boxes are nested. Toggling `open` and reading the rect yields the exact
|
|
23
|
+
* height the element will settle at, whatever the stylesheet does.
|
|
24
|
+
*/
|
|
25
|
+
export interface BoxDrawerOptions {
|
|
26
|
+
/** Length of a full open or close, in milliseconds. Partial travel is scaled down. */
|
|
27
|
+
durationMs?: number;
|
|
28
|
+
/** CSS easing function. */
|
|
29
|
+
easing?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Animate one `<details>` to its opposite state. Exported so hosts that toggle
|
|
33
|
+
* boxes programmatically go through the same animation as a click.
|
|
34
|
+
*/
|
|
35
|
+
export declare function toggleBoxWithDrawer(details: HTMLDetailsElement, options?: BoxDrawerOptions): void;
|
|
36
|
+
/**
|
|
37
|
+
* Lo mismo para la caja del dialecto osu, que no es un `<details>`: es
|
|
38
|
+
* `div.js-spoilerbox > a.js-spoilerbox__link + div.js-spoilerbox__body`, y su
|
|
39
|
+
* estado abierto es la clase `js-spoilerbox--open` en el contenedor. Marcado
|
|
40
|
+
* distinto, misma animación — y la misma razón para vivir aquí: Quasar es
|
|
41
|
+
* quien emite el marcado, así que también define cómo se abre.
|
|
42
|
+
*/
|
|
43
|
+
export declare function toggleSpoilerboxWithDrawer(box: HTMLElement, options?: BoxDrawerOptions): void;
|
|
44
|
+
/**
|
|
45
|
+
* Intercept the native toggle of every box inside `root`.
|
|
46
|
+
*
|
|
47
|
+
* The listener is delegated rather than attached per box: hosts typically feed
|
|
48
|
+
* the preview through `morphHTML` on every keystroke, and per-element listeners
|
|
49
|
+
* would be torn down and re-attached continuously.
|
|
50
|
+
*
|
|
51
|
+
* @param root - container holding the rendered BBCode
|
|
52
|
+
* @returns disposer that removes the listener
|
|
53
|
+
*/
|
|
54
|
+
export declare function bindBoxDrawer(root: HTMLElement, options?: BoxDrawerOptions): () => void;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quasar Document Engine — Visuals / LyneAudio.ts
|
|
3
|
+
*
|
|
4
|
+
* Interactive runtime for Quasar's Lyne / SYNE custom audio player (.lx-audio).
|
|
5
|
+
* Supports both scoped root binding (bindLyneAudio) and global document delegation.
|
|
6
|
+
*/
|
|
7
|
+
export declare function bindLyneAudio(root?: HTMLElement): () => void;
|
|
8
|
+
export declare const setupLyneAudioRuntime: typeof bindLyneAudio;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DocumentEngine — Visuals
|
|
3
|
+
*
|
|
4
|
+
* Catálogo de estilos visuales por plataforma para la previsualización
|
|
5
|
+
* de BBCode. Cada plataforma puede tener su propia apariencia sin
|
|
6
|
+
* modificar el renderer HTML.
|
|
7
|
+
*
|
|
8
|
+
* Uso:
|
|
9
|
+
* // Desde la FUENTE, que es como lo consume el monorepo (Next.js, Vite,
|
|
10
|
+
* // Webpack): esta ruta funciona sin haber compilado nada.
|
|
11
|
+
* import '@miliastry/quasar/src/Visuals/osu.css'
|
|
12
|
+
*
|
|
13
|
+
* // Desde el paquete PUBLICADO. Solo resuelve tras `npm run build`, que es
|
|
14
|
+
* // lo que copia los CSS a dist/Visuals (ver scripts/copy-css.mjs).
|
|
15
|
+
* import '@miliastry/quasar/Visuals/osu.css'
|
|
16
|
+
*
|
|
17
|
+
* // Luego en el JSX: <div className="bbcode-preview" ...
|
|
18
|
+
*
|
|
19
|
+
* Para cambiar de tema visual, solo cambia el import del CSS.
|
|
20
|
+
*
|
|
21
|
+
* Temas disponibles:
|
|
22
|
+
* - osu → Estilo visual inspirado en los foros de osu!
|
|
23
|
+
* - miliastry → Estilo por defecto de Miliastry (próximamente)
|
|
24
|
+
*/
|
|
25
|
+
export { bindBoxDrawer, toggleBoxWithDrawer } from './BoxDrawer';
|
|
26
|
+
export type { BoxDrawerOptions } from './BoxDrawer';
|
|
27
|
+
export { setupLyneAudioRuntime, bindLyneAudio } from './LyneAudio';
|
|
28
|
+
export declare const visualThemes: readonly [{
|
|
29
|
+
readonly id: 'osu';
|
|
30
|
+
readonly name: 'osu! Forum Style';
|
|
31
|
+
readonly description: 'Estilo visual inspirado en los foros de osu!';
|
|
32
|
+
readonly cssFile: 'osu.css';
|
|
33
|
+
}, {
|
|
34
|
+
readonly id: 'lyne';
|
|
35
|
+
readonly name: 'Lyne Style';
|
|
36
|
+
readonly description: 'Estilo visual cyberpunk con cortes a 45° inspirado en Lyne';
|
|
37
|
+
readonly cssFile: 'lyne.css';
|
|
38
|
+
}];
|
|
39
|
+
export type VisualThemeId = (typeof visualThemes)[number]['id'];
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MiliastryPlatform / DocumentEngine — Public API
|
|
3
|
+
*
|
|
4
|
+
* Language Platform agnóstica. El BBCode es solo una representación.
|
|
5
|
+
* Todo pasa por el Document Model.
|
|
6
|
+
*
|
|
7
|
+
* @see MILIASTRY_DOCUMENT_ENGINE_ARCHITECTURE.md
|
|
8
|
+
*/
|
|
9
|
+
export { DocumentModel } from './Model/DocumentModel';
|
|
10
|
+
export type { DocumentNode, NodeKind, NodeAttributes, NodeMetadata, DocumentChangeEvent, SourceRange } from './Types/core';
|
|
11
|
+
export { Lexer, type LexerOptions } from './Lexer/Lexer';
|
|
12
|
+
export { BBCODE_RAW_TAGS } from './Lexer/BBCodeLexer';
|
|
13
|
+
export type { Token, TokenKind, Trivia, TriviaKind } from './Types/tokens';
|
|
14
|
+
export { GreenNode, greenNode, greenLeaf } from './Syntax/GreenNode';
|
|
15
|
+
export { RedNode } from './Syntax/RedNode';
|
|
16
|
+
export { RedNodeStore } from './Syntax/RedNodeStore';
|
|
17
|
+
export { TreeBuilder, type BuildResult } from './Syntax/TreeBuilder';
|
|
18
|
+
export { NodeMatcher, type MatchResult } from './Syntax/NodeMatcher';
|
|
19
|
+
export { SemanticAnalyzer, type AnalyzeResult, type SemanticAnalyzerOptions, type CrossedTags, type UnknownTag } from './Semantic/SemanticAnalyzer';
|
|
20
|
+
/**
|
|
21
|
+
* Whether an analysis walked the document or only the edit — see
|
|
22
|
+
* {@link AnalyzeResult.scope}.
|
|
23
|
+
*
|
|
24
|
+
* `'full'` every node was validated afresh; `'window'` only the nodes an edit
|
|
25
|
+
* could have changed were, and every other node kept the verdict it already
|
|
26
|
+
* had. The DIAGNOSTICS ARE THE SAME EITHER WAY: this says how they were
|
|
27
|
+
* arrived at, not what they are.
|
|
28
|
+
*
|
|
29
|
+
* Worth reading if you are timing the engine, deciding whether a slow frame
|
|
30
|
+
* was the analysis, or writing a test that must not silently lose the
|
|
31
|
+
* incremental path. NOT worth branching your rendering on — a consumer that
|
|
32
|
+
* treats `'window'` results as partial and merges them into what it already
|
|
33
|
+
* had will double-report, because `AnalyzeResult.diagnostics` is always the
|
|
34
|
+
* whole document's.
|
|
35
|
+
*
|
|
36
|
+
* `AnalyzeResult.window` carries the span that was re-validated on a
|
|
37
|
+
* `'window'` pass, and is `null` on a full one.
|
|
38
|
+
*/
|
|
39
|
+
export type { AnalyzeScope } from './Semantic/SemanticAnalyzer';
|
|
40
|
+
/**
|
|
41
|
+
* `AnalyzeResult` plus the id→node index — see
|
|
42
|
+
* {@link SemanticAnalyzer.analyze}. `allNodes` is a getter that builds the
|
|
43
|
+
* index on first read, so a caller that never asks never pays for the walk.
|
|
44
|
+
*/
|
|
45
|
+
export type { IndexedAnalyzeResult } from './Semantic/SemanticAnalyzer';
|
|
46
|
+
export type { Diagnostic, DiagnosticSeverity, DiagnosticTag, DiagnosticFix, FixOperation } from './Types/diagnostics';
|
|
47
|
+
export { TagRegistry, type TagDefinition, type TagHandler } from './Model/TagRegistry';
|
|
48
|
+
export { extractTextContent } from './Model/TagRegistry';
|
|
49
|
+
export { NodeFactory } from './Model/NodeFactory';
|
|
50
|
+
export { IncrementalParser, type EditOperation } from './Incremental/IncrementalParser';
|
|
51
|
+
export { ChangeTracker, type TextChange } from './Incremental/ChangeTracker';
|
|
52
|
+
/**
|
|
53
|
+
* A half-open span of the source, `[start, end)`, in the coordinates of the
|
|
54
|
+
* text whose result carries it.
|
|
55
|
+
*
|
|
56
|
+
* The same shape everywhere it appears — {@link ReparseResult.window},
|
|
57
|
+
* `AnalyzeResult.window`, `DocumentModel.lastReparseWindow` — because it
|
|
58
|
+
* always means the same thing: the part of the CURRENT text that the engine
|
|
59
|
+
* actually looked at.
|
|
60
|
+
*/
|
|
61
|
+
export type { SourceSpan } from './Incremental/IncrementalParser';
|
|
62
|
+
/**
|
|
63
|
+
* What a reparse did, including {@link ReparseResult.window} — the span of the
|
|
64
|
+
* new text that went through the parser, or `null` after a full rebuild,
|
|
65
|
+
* where the answer is "all of it".
|
|
66
|
+
*
|
|
67
|
+
* Everything outside that span came across from the previous tree by
|
|
68
|
+
* reference, so a consumer holding per-node state (a rendered block, a
|
|
69
|
+
* measured height, a decoration) can keep it for every node the span does not
|
|
70
|
+
* touch. `DocumentModel.lastReparseWindow` is the same value for the model's
|
|
71
|
+
* last edit, which is usually the easier place to read it.
|
|
72
|
+
*/
|
|
73
|
+
export type { ReparseResult } from './Incremental/IncrementalParser';
|
|
74
|
+
/**
|
|
75
|
+
* Why a reparse rebuilt the whole document instead of splicing a window.
|
|
76
|
+
*
|
|
77
|
+
* Useful when a document is unexpectedly slow to edit: a reason that repeats
|
|
78
|
+
* on every keystroke is a document shape the window guards will not accept —
|
|
79
|
+
* an unclosed `[` before the caret (`open-bracket-before`), a stray closing
|
|
80
|
+
* tag inside the window (`region-not-isolated`), an edit that changes what the
|
|
81
|
+
* parser leaves pending for the text after it (`pending-auto-close`).
|
|
82
|
+
*/
|
|
83
|
+
export type { FallbackReason } from './Incremental/IncrementalParser';
|
|
84
|
+
export { TreeDiffer, type DiffOperation, type DiffKind } from './Diff/TreeDiffer';
|
|
85
|
+
export { Visitor, type VisitorContext } from './Visitors/Visitor';
|
|
86
|
+
export { BBCodeExporter, MILIASTRY_ONLY_TAGS, LYNE_ONLY_TAGS, type ExportTarget, type BBCodeExporterOptions, type BBCodeExportOptions } from './Visitors/BBCodeExporter';
|
|
87
|
+
export { BBBlocksExporter, type UIBBBlock } from './Visitors/BBBlocksExporter';
|
|
88
|
+
export { HTMLRenderer, type HTMLRendererOptions } from './Visitors/HTMLRenderer';
|
|
89
|
+
export { morphHTML, morphElement } from './Visitors/DOMMorpher';
|
|
90
|
+
export { patchBlocksInto, clearPatchCache, type PatchBlocksOptions, type PatchBlocksStats } from './Visitors/BlockPatcher';
|
|
91
|
+
export { SVGRenderer } from './Visitors/SVGRenderer';
|
|
92
|
+
export { MarkdownExporter } from './Visitors/MarkdownExporter';
|
|
93
|
+
export { JSONExporter } from './Visitors/JSONExporter';
|
|
94
|
+
export { TiptapExporter } from './Visitors/TiptapExporter';
|
|
95
|
+
export { Transaction } from './Transactions/Transaction';
|
|
96
|
+
export type { Operation } from './Types/operations';
|
|
97
|
+
export { UndoManager, type UndoEntry } from './Transactions/UndoManager';
|
|
98
|
+
export { CommandRegistry } from './Commands/CommandRegistry';
|
|
99
|
+
export type { Command, CommandContext, CommandResult } from './Commands/Command';
|
|
100
|
+
export { InsertText } from './Commands/InsertText';
|
|
101
|
+
export { DeleteNode } from './Commands/DeleteNode';
|
|
102
|
+
export { WrapInTag } from './Commands/WrapInTag';
|
|
103
|
+
export { SplitNode, MergeNode } from './Commands/SplitMerge';
|
|
104
|
+
export { QueryEngine } from './Queries/QueryEngine';
|
|
105
|
+
export type { Query, QueryMatch, QueryResult } from './Types/queries';
|
|
106
|
+
export { Formatter, type FormatOptions } from './Formatter/Formatter';
|
|
107
|
+
export { Linter, type LintRule, type LintResult } from './Linter/Linter';
|
|
108
|
+
export { SymbolTable } from './Symbols/SymbolTable';
|
|
109
|
+
export type { SymbolInfo, SymbolKind, Reference, SymbolSearchResult } from './Types/symbols';
|
|
110
|
+
export { RenderPipeline } from './RenderPipeline/RenderPipeline';
|
|
111
|
+
export { RenderTree, type RenderNode, type RenderVariant } from './RenderPipeline/RenderTree';
|
|
112
|
+
export { PluginAPI } from './Plugins/PluginAPI';
|
|
113
|
+
export { PluginRegistry, type PluginManifest, type PluginContribution } from './Plugins/PluginRegistry';
|
|
114
|
+
export { repairNesting, type NestingRepair, type OrphanCloser, type UnclosedOpener } from './Repair/NestingRepair';
|
|
115
|
+
export { reconcileVisualDOMToBBCode, computeTextDelta, type SurgicalEdit as QuasarSurgicalEdit, type ReconcileResult } from './Reconciler/SurgicalReconciler';
|
|
116
|
+
export * from './Edits';
|
|
117
|
+
export { BBCodeDocumentModel, renderForumBBCode } from './BBCode/BBCodeDocumentModel';
|
|
118
|
+
export type { BBCodeDocumentModelOptions } from './BBCode/BBCodeDocumentModel';
|
|
119
|
+
export { bbBlocksToRedTree, bbBlocksToGreenTree, bbBlockToGreenNode, greenToRedNode, tagToNodeKind, nodeKindToTag, isBlockKind, BBCODE_TAG_NAMES, getBBCodeTagNames, type BBCodeDialect, } from './BBCode/BBCodeToGreenNode';
|
|
120
|
+
export type { BBBlock } from './BBCode/BBCodeToGreenNode';
|
|
121
|
+
export { DocumentEventBus, type DocumentEvent, type DocumentEventHandler } from './Events/EventBus';
|
|
122
|
+
export { transformOffset, transformRange, type TransformBias } from './Collab/positions';
|
|
123
|
+
export { visualThemes } from './Visuals/index';
|
|
124
|
+
export type { VisualThemeId } from './Visuals/index';
|
|
125
|
+
export { bindBoxDrawer, toggleBoxWithDrawer, toggleSpoilerboxWithDrawer } from './Visuals/BoxDrawer';
|
|
126
|
+
export type { BoxDrawerOptions } from './Visuals/BoxDrawer';
|
|
127
|
+
export { applyGradient, applyGrow, applyRainbow, applyCentralGradient, applyMultiGradient, applyEffect, countTextLength } from './Utils/treeTransformers';
|
|
128
|
+
export type { GradientEffect, GrowEffect, RainbowEffect, CentralGradientEffect, MultiGradientEffect, TreeEffect } from './Utils/treeTransformers';
|
|
129
|
+
export { domToSVG, domToSVGResult } from './Utils/dom-to-svg';
|
|
130
|
+
export type { DomToSVGOptions, DomToSVGResult, SVGLayerInfo } from './Utils/dom-to-svg';
|
|
131
|
+
export type { Transformer } from './Transformers/Transformer';
|
|
132
|
+
export { ASTOptimizer } from './Transformers/ASTOptimizer';
|
|
133
|
+
export { SineWaveTransformer, type SineWaveOptions } from './Transformers/SineWaveTransformer';
|
|
134
|
+
export { RainbowTransformer, type RainbowOptions } from './Transformers/RainbowTransformer';
|
|
135
|
+
export { GradientTransformer, type GradientOptions } from './Transformers/GradientTransformer';
|
|
136
|
+
export { GrowTransformer, type GrowOptions } from './Transformers/GrowTransformer';
|
|
137
|
+
export { MilHibriDocumentModel, type MilHibriDocumentModelOptions } from './MilHibri/MilHibriDocumentModel';
|
|
138
|
+
export { MarkdownDocumentModel } from './Markdown/MarkdownDocumentModel';
|
|
139
|
+
export { markdownAstToGreenTree, markdownAstToRedTree } from './Markdown/MarkdownToGreenNode';
|
|
140
|
+
export { HTMLDocumentModel } from './HTML/HTMLDocumentModel';
|
|
141
|
+
export { htmlStringToGreenTree } from './HTML/HTMLToGreenNode';
|
|
142
|
+
export { ease, solveCubicBezierY, hslToHex, hexToRgb, hexToHsl, hexToOklab, mixHex, mixHexOklab, mixMultiple, mixMultipleStops, perceptualDistance, } from './Utils/ColorMath';
|
|
143
|
+
export type { Easing, ColorStop } from './Utils/ColorMath';
|
|
144
|
+
export { isHexColor } from './Utils/ColorMath';
|
|
145
|
+
export { hashSeed, randAt, valueNoise, fbm, validateExpression, compileExpression, EXPRESSION_VARS, waveform, WAVE_KINDS, DEFAULT_WAVE_OPTIONS, clamp01, blendHex, BLEND_MODES, rgbToHex, adjustHsl, posterizeHex, clampRange, buildSampleTable, buildRangeScope, documentScope, axisValue, expressionVars, AXES, effectiveAxis, mergeStyledSegments, normalizeHex, parseColorStops, stringifyColorStops, parseEffectParams, stringifyEffectParams, EFFECT_PARAM_KEYS, EFFECT_UNITS, evaluateEffect, GRADIENT_DEFAULTS, RAINBOW_DEFAULTS, GROW_DEFAULTS, NEUTRAL_SIZE, PAINT_DEFAULTS, SPATIAL_DEFAULTS, SPATIAL_AXES, DEFAULT_CELL_ASPECT, DEFAULT_SPATIAL, spatialPoint, MASK_SHAPES, DEFAULT_MASK, maskValue, maskDistance, spatialFromParams, maskFromParams, gridFromParams, PAINT_MAX_COLORS, parsePaintGrid, samplePaintGrid, stringifyPaintCells, stringifyPaintPalette, } from './Utils/EffectMath';
|
|
146
|
+
export type { WaveKind, WaveOptions, BlendMode, ExpressionVars, CompiledExpression, CharSample, SampleTable, RangeScope, SampleContext, Axis, EffectParams, EffectUnit, EffectKind, EffectSpan, StyledSegment, SpatialOptions, SpatialPoint, MaskShape, MaskOptions, PaintGrid, } from './Utils/EffectMath';
|
|
147
|
+
export { attributeVocabularyFor, allAttributeVocabularies, EFFECT_TYPES, ANIM_TYPES, CONTAINER_TYPES, SEPARATOR_VARIANTS, TABLE_FLAGS, IMG_MODIFIERS, } from './Utils/TagVocabulary';
|
|
148
|
+
export type { AttributeVocabulary, VocabularySyntax } from './Utils/TagVocabulary';
|
|
149
|
+
export { Pipeline, PipelineBuilder, PipelineStage, ContributionKind, PipelineMode, CharacterCountAnalyzer, MergeableColorAnalyzer, GradientAnalyzer, findCollapsibleGradients, formatGradientTag, RainbowAnalyzer, WaveAnalyzer, SymbolAnalyzer, ColorUsageAnalyzer, DefaultDecision, PaletteRemapDecision, CollapseGradientTransform, RainbowCollapseTransform, WaveCollapseTransform, MergeColorsTransform, } from './Analysis/index';
|
|
150
|
+
export type { CollapsibleGradient, Pass, AnalyzerPass, DecisionPass, TransformPass, TransformationPlan, TransformAction, Contribution, SemanticContribution, DiagnosticContribution, OptimizationContribution, MetricsContribution, AnalysisReport, PipelineContext, PipelineResult, GradientModel, GradientDiagnostics, GradientStop, RainbowModel, RainbowDiagnostics, WaveModel, WaveDiagnostics, SymbolGlyph, SymbolRunModel, ColorUsageModel, Palette, PaletteRemapOptions, RemapAction, } from './Analysis/index';
|
|
151
|
+
export { nodeAttrValue, parseImgAttr, sanitizeColor, sanitizeFontSize, sanitizeFontFamily, } from './Syntax/nodeAttr';
|
|
152
|
+
export type { ImgAttr } from './Syntax/nodeAttr';
|
|
153
|
+
export { toTokenResolver, resolveTokenValue, } from './Tokens/index';
|
|
154
|
+
export type { DocumentTokens, TokenResolverFn, TokenSource, } from './Tokens/index';
|
|
155
|
+
export { setupLyneAudioRuntime, bindLyneAudio } from './Visuals/LyneAudio';
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@miliastry/quasar",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Quasar Document Engine - Advanced BBCode/Markdown/HTML AST Engine",
|
|
5
|
-
"main": "
|
|
6
|
-
"
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/types/index.d.ts",
|
|
7
8
|
"license": "MSL-1.0",
|
|
8
9
|
"sideEffects": [
|
|
9
10
|
"./src/Visuals/*.css",
|
|
@@ -12,11 +13,11 @@
|
|
|
12
13
|
"exports": {
|
|
13
14
|
".": {
|
|
14
15
|
"import": {
|
|
15
|
-
"types": "./dist/index.d.
|
|
16
|
+
"types": "./dist/types/index.d.ts",
|
|
16
17
|
"default": "./dist/index.mjs"
|
|
17
18
|
},
|
|
18
19
|
"require": {
|
|
19
|
-
"types": "./dist/index.d.ts",
|
|
20
|
+
"types": "./dist/types/index.d.ts",
|
|
20
21
|
"default": "./dist/index.js"
|
|
21
22
|
}
|
|
22
23
|
},
|
|
@@ -27,7 +28,7 @@
|
|
|
27
28
|
"./package.json": "./package.json"
|
|
28
29
|
},
|
|
29
30
|
"scripts": {
|
|
30
|
-
"build": "tsup && node scripts/copy-css.mjs",
|
|
31
|
+
"build": "tsup && tsc -p tsconfig.build.json && node scripts/copy-css.mjs",
|
|
31
32
|
"prepublishOnly": "npm run verify && npm run build",
|
|
32
33
|
"test": "vitest run",
|
|
33
34
|
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
@@ -38,12 +39,15 @@
|
|
|
38
39
|
},
|
|
39
40
|
"files": [
|
|
40
41
|
"dist",
|
|
41
|
-
"src"
|
|
42
|
+
"src",
|
|
43
|
+
"!src/Tests",
|
|
44
|
+
"!src/**/__tests__",
|
|
45
|
+
"!src/**/*.test.ts"
|
|
42
46
|
],
|
|
43
|
-
"dependencies": {},
|
|
44
47
|
"devDependencies": {
|
|
45
|
-
"@
|
|
48
|
+
"@types/node": "^22",
|
|
46
49
|
"tsup": "^8.5.1",
|
|
47
|
-
"typescript": "
|
|
50
|
+
"typescript": "^7.0.2",
|
|
51
|
+
"vitest": "^4.1.8"
|
|
48
52
|
}
|
|
49
53
|
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quasar Analysis Framework — Color Usage Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Reports every `[color=#RRGGBB]` in the document, one contribution per tag.
|
|
5
|
+
*
|
|
6
|
+
* ## Why this exists alongside GradientAnalyzer
|
|
7
|
+
*
|
|
8
|
+
* `GradientAnalyzer` recognises that a run of colour tags forms a gradient and
|
|
9
|
+
* describes its *shape* — the stops, the easing, the span. What it does not
|
|
10
|
+
* describe is where each individual tag sits, because a gradient is modelled
|
|
11
|
+
* as one continuous ramp rather than as the tags that spell it out.
|
|
12
|
+
*
|
|
13
|
+
* A consumer that wants to recolour a document needs both: the shape, to know
|
|
14
|
+
* what the gradient is doing, and the tag positions, to know what to edit.
|
|
15
|
+
* This pass supplies the second half. A DecisionPass sees both contributions
|
|
16
|
+
* in the same report and can join them — which is exactly how the framework is
|
|
17
|
+
* meant to compose, since analyzer passes cannot observe each other.
|
|
18
|
+
*
|
|
19
|
+
* ## What gets reported
|
|
20
|
+
*
|
|
21
|
+
* Every colour tag, gradient member or not. Deciding which ones are
|
|
22
|
+
* interesting is a decision, and decisions belong in the decision stage.
|
|
23
|
+
*
|
|
24
|
+
* Only full six-digit hex is recognised, because that is what `extractHex`
|
|
25
|
+
* accepts. `[color=red]` and `[color=#F00]` are parsed as colours by the
|
|
26
|
+
* engine but are invisible here — a deliberate limit, since rewriting them
|
|
27
|
+
* would mean choosing a canonical spelling the author did not use.
|
|
28
|
+
*
|
|
29
|
+
* @see SemanticContribution
|
|
30
|
+
* @see GradientAnalyzer
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import type { AnalyzerPass } from '../../Contracts/Pass'
|
|
34
|
+
import type { PipelineContext } from '../../Contracts/PipelineContext'
|
|
35
|
+
import type { Contribution } from '../../Contracts/Contribution'
|
|
36
|
+
import { ContributionKind } from '../../Contracts/Contribution'
|
|
37
|
+
import type { GreenNode } from '../../../Syntax/GreenNode'
|
|
38
|
+
import { childOffsets } from '../../../Syntax/GreenNode'
|
|
39
|
+
import { extractHex } from '../../Utils/color-utils'
|
|
40
|
+
|
|
41
|
+
// ── Types ─────────────────────────────────────────────────────────
|
|
42
|
+
|
|
43
|
+
export interface ColorUsageModel {
|
|
44
|
+
/** Normalised to uppercase `#RRGGBB` by `extractHex`. */
|
|
45
|
+
readonly hex: string
|
|
46
|
+
/**
|
|
47
|
+
* Source offsets of the opening delimiter alone — `[color=#D194B3]`.
|
|
48
|
+
*
|
|
49
|
+
* Recolouring replaces this span rather than the attribute inside it. The
|
|
50
|
+
* attribute's own position would have to be derived from the delimiter's
|
|
51
|
+
* width and the hex's length, which breaks the moment the author writes
|
|
52
|
+
* `[color = #D194B3]`; the delimiter's bounds are read straight off the
|
|
53
|
+
* node. The cost is that a rewritten tag comes back in canonical spelling,
|
|
54
|
+
* which is acceptable for a tag being edited anyway.
|
|
55
|
+
*/
|
|
56
|
+
readonly openStart: number
|
|
57
|
+
readonly openEnd: number
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// ── Analyzer ──────────────────────────────────────────────────────
|
|
61
|
+
|
|
62
|
+
export class ColorUsageAnalyzer implements AnalyzerPass {
|
|
63
|
+
readonly id = 'color-usage'
|
|
64
|
+
|
|
65
|
+
run(tree: GreenNode, _context: PipelineContext): Contribution[] {
|
|
66
|
+
const contributions: Contribution[] = []
|
|
67
|
+
this.walk(tree, contributions, 0)
|
|
68
|
+
return contributions
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// ── Private ─────────────────────────────────────────────────────
|
|
72
|
+
|
|
73
|
+
private walk(node: GreenNode, sink: Contribution[], start: number): void {
|
|
74
|
+
const hex = extractHex(node)
|
|
75
|
+
|
|
76
|
+
if (hex !== null) {
|
|
77
|
+
const model: ColorUsageModel = {
|
|
78
|
+
hex,
|
|
79
|
+
openStart: start,
|
|
80
|
+
openEnd: start + node.leadingWidth,
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
sink.push({
|
|
84
|
+
kind: ContributionKind.Semantic,
|
|
85
|
+
label: 'Color',
|
|
86
|
+
// A parsed colour tag is a fact, not an inference: unlike a gradient
|
|
87
|
+
// or a decorative glyph, there is nothing here to be unsure about.
|
|
88
|
+
confidence: 1,
|
|
89
|
+
range: { start, end: start + node.width },
|
|
90
|
+
metadata: { model },
|
|
91
|
+
description: `Colour ${hex}`,
|
|
92
|
+
})
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const children = node.children as readonly GreenNode[]
|
|
96
|
+
if (children.length === 0) return
|
|
97
|
+
|
|
98
|
+
const offsets = childOffsets(node, start)
|
|
99
|
+
for (let i = 0; i < children.length; i++) {
|
|
100
|
+
this.walk(children[i], sink, offsets[i])
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|