@flogeez/angular-tiptap-editor 2.2.3 → 2.4.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/CHANGELOG.md +24 -0
- package/README.md +132 -93
- package/fesm2022/flogeez-angular-tiptap-editor.mjs +565 -40
- package/fesm2022/flogeez-angular-tiptap-editor.mjs.map +1 -1
- package/index.d.ts +417 -5
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, output, ChangeDetectionStrategy, Component, signal, computed, Injectable, inject, viewChild, effect, Directive, DestroyRef, untracked } from '@angular/core';
|
|
2
|
+
import { input, output, ChangeDetectionStrategy, Component, signal, computed, Injectable, inject, viewChild, effect, Directive, ApplicationRef, EnvironmentInjector, createComponent, InjectionToken, DestroyRef, Injector, untracked, makeEnvironmentProviders, provideEnvironmentInitializer } from '@angular/core';
|
|
3
3
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
4
4
|
import { Node as Node$1, nodeInputRule, mergeAttributes, Extension, getAttributes, Editor } from '@tiptap/core';
|
|
5
5
|
import StarterKit from '@tiptap/starter-kit';
|
|
@@ -20,7 +20,7 @@ import Table from '@tiptap/extension-table';
|
|
|
20
20
|
import TableRow from '@tiptap/extension-table-row';
|
|
21
21
|
import TableCell from '@tiptap/extension-table-cell';
|
|
22
22
|
import TableHeader from '@tiptap/extension-table-header';
|
|
23
|
-
import { isObservable, firstValueFrom, concat, defer, of, tap } from 'rxjs';
|
|
23
|
+
import { isObservable, firstValueFrom, Subscription, concat, defer, of, tap } from 'rxjs';
|
|
24
24
|
import { CommonModule } from '@angular/common';
|
|
25
25
|
import tippy, { sticky } from 'tippy.js';
|
|
26
26
|
import * as i1 from '@angular/forms';
|
|
@@ -5391,6 +5391,442 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
5391
5391
|
}]
|
|
5392
5392
|
}] });
|
|
5393
5393
|
|
|
5394
|
+
/**
|
|
5395
|
+
* Base abstract class for custom 'Angular Nodes'.
|
|
5396
|
+
*
|
|
5397
|
+
* Extend this class in your custom components to automatically receive TipTap editor
|
|
5398
|
+
* properties (node attributes, selection state, etc.) as reactive Signals.
|
|
5399
|
+
*
|
|
5400
|
+
* @example
|
|
5401
|
+
* ```typescript
|
|
5402
|
+
* @Component({
|
|
5403
|
+
* selector: 'app-counter',
|
|
5404
|
+
* template: `
|
|
5405
|
+
* <div>
|
|
5406
|
+
* <button (click)="increment()">Count: {{ node().attrs['count'] }}</button>
|
|
5407
|
+
* </div>
|
|
5408
|
+
* `
|
|
5409
|
+
* })
|
|
5410
|
+
* export class CounterComponent extends AteAngularNodeView {
|
|
5411
|
+
* increment() {
|
|
5412
|
+
* const count = this.node().attrs['count'] || 0;
|
|
5413
|
+
* this.updateAttributes({ count: count + 1 });
|
|
5414
|
+
* }
|
|
5415
|
+
* }
|
|
5416
|
+
* ```
|
|
5417
|
+
*/
|
|
5418
|
+
class AteAngularNodeView {
|
|
5419
|
+
/**
|
|
5420
|
+
* Internal method to initialize the component with NodeView props.
|
|
5421
|
+
* This is called by the AngularNodeViewRenderer.
|
|
5422
|
+
*
|
|
5423
|
+
* @internal
|
|
5424
|
+
*/
|
|
5425
|
+
_initNodeView(props) {
|
|
5426
|
+
// Create signals from the props
|
|
5427
|
+
const editorSignal = signal(props.editor, ...(ngDevMode ? [{ debugName: "editorSignal" }] : []));
|
|
5428
|
+
const nodeSignal = signal(props.node, ...(ngDevMode ? [{ debugName: "nodeSignal" }] : []));
|
|
5429
|
+
const decorationsSignal = signal(props.decorations, ...(ngDevMode ? [{ debugName: "decorationsSignal" }] : []));
|
|
5430
|
+
const selectedSignal = signal(props.selected, ...(ngDevMode ? [{ debugName: "selectedSignal" }] : []));
|
|
5431
|
+
const extensionSignal = signal(props.extension, ...(ngDevMode ? [{ debugName: "extensionSignal" }] : []));
|
|
5432
|
+
// Assign to the component
|
|
5433
|
+
this.editor = editorSignal.asReadonly();
|
|
5434
|
+
this.node = nodeSignal.asReadonly();
|
|
5435
|
+
this.decorations = decorationsSignal.asReadonly();
|
|
5436
|
+
this.selected = selectedSignal.asReadonly();
|
|
5437
|
+
this.extension = extensionSignal.asReadonly();
|
|
5438
|
+
this.getPos = props.getPos;
|
|
5439
|
+
this.updateAttributes = props.updateAttributes;
|
|
5440
|
+
this.deleteNode = props.deleteNode;
|
|
5441
|
+
// Store writable signals for updates
|
|
5442
|
+
this._writableSignals = {
|
|
5443
|
+
node: nodeSignal,
|
|
5444
|
+
decorations: decorationsSignal,
|
|
5445
|
+
selected: selectedSignal,
|
|
5446
|
+
};
|
|
5447
|
+
}
|
|
5448
|
+
/**
|
|
5449
|
+
* Internal method to update the component when the node changes.
|
|
5450
|
+
* This is called by the AngularNodeViewRenderer.
|
|
5451
|
+
*
|
|
5452
|
+
* @internal
|
|
5453
|
+
*/
|
|
5454
|
+
_updateNodeView(node, decorations) {
|
|
5455
|
+
if (this._writableSignals) {
|
|
5456
|
+
this._writableSignals.node.set(node);
|
|
5457
|
+
this._writableSignals.decorations.set(decorations);
|
|
5458
|
+
}
|
|
5459
|
+
}
|
|
5460
|
+
/**
|
|
5461
|
+
* Internal method to update the selection state.
|
|
5462
|
+
* This is called by the AngularNodeViewRenderer.
|
|
5463
|
+
*
|
|
5464
|
+
* @internal
|
|
5465
|
+
*/
|
|
5466
|
+
_selectNodeView() {
|
|
5467
|
+
if (this._writableSignals) {
|
|
5468
|
+
this._writableSignals.selected.set(true);
|
|
5469
|
+
}
|
|
5470
|
+
}
|
|
5471
|
+
/**
|
|
5472
|
+
* Internal method to update the deselection state.
|
|
5473
|
+
* This is called by the AngularNodeViewRenderer.
|
|
5474
|
+
*
|
|
5475
|
+
* @internal
|
|
5476
|
+
*/
|
|
5477
|
+
_deselectNodeView() {
|
|
5478
|
+
if (this._writableSignals) {
|
|
5479
|
+
this._writableSignals.selected.set(false);
|
|
5480
|
+
}
|
|
5481
|
+
}
|
|
5482
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AteAngularNodeView, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
5483
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.16", type: AteAngularNodeView, isStandalone: true, ngImport: i0 }); }
|
|
5484
|
+
}
|
|
5485
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AteAngularNodeView, decorators: [{
|
|
5486
|
+
type: Directive
|
|
5487
|
+
}] });
|
|
5488
|
+
|
|
5489
|
+
/**
|
|
5490
|
+
* Universal Renderer for Angular Components as TipTap NodeViews.
|
|
5491
|
+
*
|
|
5492
|
+
* Supports:
|
|
5493
|
+
* - TipTap-Aware components (extending AteAngularNodeView)
|
|
5494
|
+
* - Standard library components (automatic @Input() sync)
|
|
5495
|
+
* - Signal-based inputs and outputs (Angular 18+)
|
|
5496
|
+
* - Content projection (editableContent)
|
|
5497
|
+
* - Unified lifecycle and event management
|
|
5498
|
+
*/
|
|
5499
|
+
function AteNodeViewRenderer(component, options) {
|
|
5500
|
+
return props => {
|
|
5501
|
+
const { node, view: _view, getPos, decorations, editor, extension } = props;
|
|
5502
|
+
const { injector, inputs = {}, wrapperTag = "div", wrapperClass, editableContent = false, contentSelector, onOutput, ignoreMutation = true, } = options;
|
|
5503
|
+
const dom = document.createElement(wrapperTag);
|
|
5504
|
+
if (wrapperClass) {
|
|
5505
|
+
dom.className = wrapperClass;
|
|
5506
|
+
}
|
|
5507
|
+
const applicationRef = injector.get(ApplicationRef);
|
|
5508
|
+
const environmentInjector = injector.get(EnvironmentInjector);
|
|
5509
|
+
// 1. Setup Content Projection (ng-content)
|
|
5510
|
+
let initialNodes = [];
|
|
5511
|
+
let contentDOM = null;
|
|
5512
|
+
if (editableContent && !contentSelector) {
|
|
5513
|
+
contentDOM = document.createElement("div");
|
|
5514
|
+
contentDOM.setAttribute("data-node-view-content", "");
|
|
5515
|
+
initialNodes = [[contentDOM]];
|
|
5516
|
+
}
|
|
5517
|
+
// 2. Create the Angular Component
|
|
5518
|
+
const componentRef = createComponent(component, {
|
|
5519
|
+
environmentInjector,
|
|
5520
|
+
elementInjector: injector,
|
|
5521
|
+
projectableNodes: initialNodes,
|
|
5522
|
+
});
|
|
5523
|
+
const instance = componentRef.instance;
|
|
5524
|
+
const subscriptions = [];
|
|
5525
|
+
// 3. Initialize TipTap-Aware instances
|
|
5526
|
+
if (instance instanceof AteAngularNodeView) {
|
|
5527
|
+
instance._initNodeView({
|
|
5528
|
+
editor,
|
|
5529
|
+
node,
|
|
5530
|
+
decorations,
|
|
5531
|
+
selected: false,
|
|
5532
|
+
extension,
|
|
5533
|
+
getPos,
|
|
5534
|
+
updateAttributes: attrs => editor.commands.updateAttributes(node.type.name, attrs),
|
|
5535
|
+
deleteNode: () => {
|
|
5536
|
+
const pos = getPos();
|
|
5537
|
+
if (pos !== undefined) {
|
|
5538
|
+
editor.commands.deleteRange({ from: pos, to: pos + node.nodeSize });
|
|
5539
|
+
}
|
|
5540
|
+
},
|
|
5541
|
+
});
|
|
5542
|
+
}
|
|
5543
|
+
// 4. Synchronize Inputs (Handles standard @Input and Signal-based inputs)
|
|
5544
|
+
const syncInputs = (nodeToSync) => {
|
|
5545
|
+
// Combine base inputs from options with dynamic node attributes
|
|
5546
|
+
const mergedInputs = { ...inputs, ...nodeToSync.attrs };
|
|
5547
|
+
Object.entries(mergedInputs).forEach(([key, value]) => {
|
|
5548
|
+
if (key !== "id" && value !== null && value !== undefined) {
|
|
5549
|
+
try {
|
|
5550
|
+
componentRef.setInput(key, value);
|
|
5551
|
+
}
|
|
5552
|
+
catch {
|
|
5553
|
+
// Silently ignore inputs that don't exist on the component
|
|
5554
|
+
}
|
|
5555
|
+
}
|
|
5556
|
+
});
|
|
5557
|
+
};
|
|
5558
|
+
syncInputs(node);
|
|
5559
|
+
// 5. Setup Outputs (Handles EventEmitter and OutputRef)
|
|
5560
|
+
if (onOutput) {
|
|
5561
|
+
Object.entries(instance).forEach(([key, potentialOutput]) => {
|
|
5562
|
+
if (potentialOutput &&
|
|
5563
|
+
typeof potentialOutput
|
|
5564
|
+
.subscribe === "function") {
|
|
5565
|
+
const sub = potentialOutput.subscribe((value) => {
|
|
5566
|
+
onOutput(key, value);
|
|
5567
|
+
});
|
|
5568
|
+
if (sub instanceof Subscription) {
|
|
5569
|
+
subscriptions.push(sub);
|
|
5570
|
+
}
|
|
5571
|
+
}
|
|
5572
|
+
});
|
|
5573
|
+
}
|
|
5574
|
+
// 6. Attach to DOM and ApplicationRef
|
|
5575
|
+
applicationRef.attachView(componentRef.hostView);
|
|
5576
|
+
const componentElement = componentRef.location.nativeElement;
|
|
5577
|
+
// Target specific element for content if selector provided
|
|
5578
|
+
if (editableContent && contentSelector) {
|
|
5579
|
+
contentDOM = componentElement.querySelector(contentSelector);
|
|
5580
|
+
}
|
|
5581
|
+
dom.appendChild(componentElement);
|
|
5582
|
+
// Initial detection to ensure the component is rendered
|
|
5583
|
+
componentRef.changeDetectorRef.detectChanges();
|
|
5584
|
+
// 7. Return the TipTap NodeView Interface
|
|
5585
|
+
return {
|
|
5586
|
+
dom,
|
|
5587
|
+
contentDOM,
|
|
5588
|
+
update: (updatedNode, updatedDecorations) => {
|
|
5589
|
+
if (updatedNode.type !== node.type) {
|
|
5590
|
+
return false;
|
|
5591
|
+
}
|
|
5592
|
+
// Update Aware component signals
|
|
5593
|
+
if (instance instanceof AteAngularNodeView) {
|
|
5594
|
+
instance._updateNodeView(updatedNode, updatedDecorations);
|
|
5595
|
+
}
|
|
5596
|
+
// Update inputs
|
|
5597
|
+
syncInputs(updatedNode);
|
|
5598
|
+
// Notify and Detect changes
|
|
5599
|
+
componentRef.changeDetectorRef.detectChanges();
|
|
5600
|
+
if (options.onUpdate) {
|
|
5601
|
+
options.onUpdate(updatedNode);
|
|
5602
|
+
}
|
|
5603
|
+
return true;
|
|
5604
|
+
},
|
|
5605
|
+
selectNode: () => {
|
|
5606
|
+
if (instance instanceof AteAngularNodeView) {
|
|
5607
|
+
instance._selectNodeView();
|
|
5608
|
+
}
|
|
5609
|
+
dom.classList.add("ProseMirror-selectednode");
|
|
5610
|
+
},
|
|
5611
|
+
deselectNode: () => {
|
|
5612
|
+
if (instance instanceof AteAngularNodeView) {
|
|
5613
|
+
instance._deselectNodeView();
|
|
5614
|
+
}
|
|
5615
|
+
dom.classList.remove("ProseMirror-selectednode");
|
|
5616
|
+
},
|
|
5617
|
+
destroy: () => {
|
|
5618
|
+
if (options.onDestroy) {
|
|
5619
|
+
options.onDestroy();
|
|
5620
|
+
}
|
|
5621
|
+
subscriptions.forEach(s => s.unsubscribe());
|
|
5622
|
+
applicationRef.detachView(componentRef.hostView);
|
|
5623
|
+
componentRef.destroy();
|
|
5624
|
+
},
|
|
5625
|
+
stopEvent: event => {
|
|
5626
|
+
const target = event.target;
|
|
5627
|
+
const isEditable = target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.isContentEditable;
|
|
5628
|
+
return isEditable;
|
|
5629
|
+
},
|
|
5630
|
+
ignoreMutation: mutation => {
|
|
5631
|
+
if (typeof ignoreMutation === "function") {
|
|
5632
|
+
return ignoreMutation(mutation);
|
|
5633
|
+
}
|
|
5634
|
+
return ignoreMutation;
|
|
5635
|
+
},
|
|
5636
|
+
};
|
|
5637
|
+
};
|
|
5638
|
+
}
|
|
5639
|
+
|
|
5640
|
+
const RESERVED_NAMES = [
|
|
5641
|
+
"doc",
|
|
5642
|
+
"paragraph",
|
|
5643
|
+
"text",
|
|
5644
|
+
"hardBreak",
|
|
5645
|
+
"bulletList",
|
|
5646
|
+
"orderedList",
|
|
5647
|
+
"listItem",
|
|
5648
|
+
"blockquote",
|
|
5649
|
+
"codeBlock",
|
|
5650
|
+
"heading",
|
|
5651
|
+
"horizontalRule",
|
|
5652
|
+
];
|
|
5653
|
+
/**
|
|
5654
|
+
* Derives the TipTap node name and HTML tag from a component class.
|
|
5655
|
+
*/
|
|
5656
|
+
function deriveMetadata(component, customName) {
|
|
5657
|
+
let nodeName = customName;
|
|
5658
|
+
if (!nodeName) {
|
|
5659
|
+
nodeName = component.name
|
|
5660
|
+
.replace(/Component$/, "")
|
|
5661
|
+
.replace(/Node$/, "")
|
|
5662
|
+
.replace(/^([A-Z])/, m => m.toLowerCase());
|
|
5663
|
+
console.warn(`[ATE] Auto-deriving node name '${nodeName}' for component ${component.name}. ` +
|
|
5664
|
+
`Provide an explicit 'name' in options to avoid potential naming collisions.`);
|
|
5665
|
+
}
|
|
5666
|
+
if (RESERVED_NAMES.includes(nodeName)) {
|
|
5667
|
+
throw new Error(`[ATE] The name '${nodeName}' is a reserved TipTap node name. ` +
|
|
5668
|
+
`Please provide a unique name for your custom component.`);
|
|
5669
|
+
}
|
|
5670
|
+
const tag = nodeName.toLowerCase().replace(/([A-Z])/g, "-$1");
|
|
5671
|
+
return { nodeName, tag };
|
|
5672
|
+
}
|
|
5673
|
+
/**
|
|
5674
|
+
* Creates TipTap attributes from component inputs (Standard Mode).
|
|
5675
|
+
*/
|
|
5676
|
+
function createStandardAttributes(defaultInputs = {}) {
|
|
5677
|
+
const tiptapAttributes = {};
|
|
5678
|
+
Object.entries(defaultInputs).forEach(([key, defaultValue]) => {
|
|
5679
|
+
tiptapAttributes[key] = {
|
|
5680
|
+
default: defaultValue,
|
|
5681
|
+
parseHTML: (element) => {
|
|
5682
|
+
const attr = element.getAttribute(`data-${key}`);
|
|
5683
|
+
if (attr === null) {
|
|
5684
|
+
return defaultValue;
|
|
5685
|
+
}
|
|
5686
|
+
try {
|
|
5687
|
+
return JSON.parse(attr);
|
|
5688
|
+
}
|
|
5689
|
+
catch {
|
|
5690
|
+
return attr;
|
|
5691
|
+
}
|
|
5692
|
+
},
|
|
5693
|
+
renderHTML: (attrs) => {
|
|
5694
|
+
const value = attrs[key];
|
|
5695
|
+
if (value === undefined || value === null) {
|
|
5696
|
+
return {};
|
|
5697
|
+
}
|
|
5698
|
+
const serialized = typeof value === "object" ? JSON.stringify(value) : String(value);
|
|
5699
|
+
return { [`data-${key}`]: serialized };
|
|
5700
|
+
},
|
|
5701
|
+
};
|
|
5702
|
+
});
|
|
5703
|
+
return tiptapAttributes;
|
|
5704
|
+
}
|
|
5705
|
+
/**
|
|
5706
|
+
* Factory to transform an Angular component into a TipTap Node extension.
|
|
5707
|
+
* Supports both "TipTap-Aware" and "Standard" modes.
|
|
5708
|
+
*
|
|
5709
|
+
* @internal
|
|
5710
|
+
*/
|
|
5711
|
+
function createAngularComponentExtension(injector, options) {
|
|
5712
|
+
const { component, name: customName, attributes, defaultInputs, contentSelector, contentMode = "block", editableContent = false, group = "block", draggable = true, ignoreMutation = true, onOutput, HTMLAttributes = {}, parseHTML: customParseHTML, renderHTML: customRenderHTML, } = options;
|
|
5713
|
+
const { nodeName, tag } = deriveMetadata(component, customName);
|
|
5714
|
+
const isTipTapAware = Object.prototype.isPrototypeOf.call(AteAngularNodeView, component);
|
|
5715
|
+
const atom = !editableContent;
|
|
5716
|
+
// 1. Prepare Attributes
|
|
5717
|
+
const tiptapAttributes = isTipTapAware
|
|
5718
|
+
? attributes || {}
|
|
5719
|
+
: createStandardAttributes(defaultInputs);
|
|
5720
|
+
// 2. Create Node Extension
|
|
5721
|
+
return Node$1.create({
|
|
5722
|
+
name: nodeName,
|
|
5723
|
+
group,
|
|
5724
|
+
inline: group === "inline",
|
|
5725
|
+
atom,
|
|
5726
|
+
draggable,
|
|
5727
|
+
content: editableContent ? (contentMode === "inline" ? "inline*" : "block*") : undefined,
|
|
5728
|
+
addAttributes() {
|
|
5729
|
+
return tiptapAttributes;
|
|
5730
|
+
},
|
|
5731
|
+
parseHTML() {
|
|
5732
|
+
if (customParseHTML) {
|
|
5733
|
+
return customParseHTML.call(this);
|
|
5734
|
+
}
|
|
5735
|
+
return [{ tag }, { tag: `div[data-component="${nodeName}"]` }];
|
|
5736
|
+
},
|
|
5737
|
+
renderHTML({ node, HTMLAttributes: attrs }) {
|
|
5738
|
+
if (customRenderHTML) {
|
|
5739
|
+
return customRenderHTML.call(this, { node, HTMLAttributes: attrs });
|
|
5740
|
+
}
|
|
5741
|
+
return [tag, mergeAttributes(HTMLAttributes, attrs, { "data-component": nodeName })];
|
|
5742
|
+
},
|
|
5743
|
+
addNodeView() {
|
|
5744
|
+
return AteNodeViewRenderer(component, {
|
|
5745
|
+
injector,
|
|
5746
|
+
inputs: defaultInputs,
|
|
5747
|
+
wrapperTag: group === "inline" ? "span" : "div",
|
|
5748
|
+
wrapperClass: isTipTapAware
|
|
5749
|
+
? `ate-node-${nodeName}`
|
|
5750
|
+
: `embedded-component embedded-${nodeName}`,
|
|
5751
|
+
atom,
|
|
5752
|
+
editableContent,
|
|
5753
|
+
contentSelector,
|
|
5754
|
+
contentMode,
|
|
5755
|
+
onOutput,
|
|
5756
|
+
ignoreMutation,
|
|
5757
|
+
});
|
|
5758
|
+
},
|
|
5759
|
+
});
|
|
5760
|
+
}
|
|
5761
|
+
|
|
5762
|
+
/**
|
|
5763
|
+
* Internal registry to store the root injector for the editor.
|
|
5764
|
+
* This allows registerAngularComponent to work without explicitly passing the injector.
|
|
5765
|
+
* @internal
|
|
5766
|
+
*/
|
|
5767
|
+
let globalInjector = null;
|
|
5768
|
+
function setGlobalInjector(injector) {
|
|
5769
|
+
globalInjector = injector;
|
|
5770
|
+
}
|
|
5771
|
+
function getGlobalInjector() {
|
|
5772
|
+
if (!globalInjector) {
|
|
5773
|
+
throw new Error("[ATE] Global Injector not found. Make sure to call provideAteEditor() in your app.config.ts or main.ts.");
|
|
5774
|
+
}
|
|
5775
|
+
return globalInjector;
|
|
5776
|
+
}
|
|
5777
|
+
|
|
5778
|
+
/**
|
|
5779
|
+
* Registers ANY Angular component as a TipTap node extension.
|
|
5780
|
+
*
|
|
5781
|
+
* This function is the single public entry point for adding custom components.
|
|
5782
|
+
* It supports two distinct modes:
|
|
5783
|
+
*
|
|
5784
|
+
* 1. **TipTap-Aware Mode** (the component extends `AteAngularNodeView`):
|
|
5785
|
+
* Grants direct access to the TipTap API (`editor`, `node`, `updateAttributes`, etc.) within the component.
|
|
5786
|
+
*
|
|
5787
|
+
* 2. **Standard Mode** (library or legacy components):
|
|
5788
|
+
* Allows using any existing Angular component. Its `@Input()` properties are automatically
|
|
5789
|
+
* synchronized with TipTap node attributes.
|
|
5790
|
+
*
|
|
5791
|
+
* @param injectorOrOptions - The Angular Injector OR the configuration options
|
|
5792
|
+
* @param maybeOptions - Configuration options (if the first param was an injector)
|
|
5793
|
+
* @returns A TipTap Node extension ready to be used
|
|
5794
|
+
*
|
|
5795
|
+
* @example
|
|
5796
|
+
* ```typescript
|
|
5797
|
+
* // Modern way (requires provideAteEditor())
|
|
5798
|
+
* registerAngularComponent({
|
|
5799
|
+
* component: MyComponent,
|
|
5800
|
+
* name: 'myComponent'
|
|
5801
|
+
* });
|
|
5802
|
+
*
|
|
5803
|
+
* // Classic way
|
|
5804
|
+
* registerAngularComponent(injector, {
|
|
5805
|
+
* component: MyComponent
|
|
5806
|
+
* });
|
|
5807
|
+
* ```
|
|
5808
|
+
*/
|
|
5809
|
+
function registerAngularComponent(injectorOrOptions, maybeOptions) {
|
|
5810
|
+
let injector;
|
|
5811
|
+
let options;
|
|
5812
|
+
// Duck-typing check: Injectors have a 'get' method
|
|
5813
|
+
const isInjector = (obj) => obj !== null && typeof obj === "object" && typeof obj.get === "function";
|
|
5814
|
+
if (isInjector(injectorOrOptions)) {
|
|
5815
|
+
injector = injectorOrOptions;
|
|
5816
|
+
options = maybeOptions;
|
|
5817
|
+
}
|
|
5818
|
+
else {
|
|
5819
|
+
injector = getGlobalInjector();
|
|
5820
|
+
options = injectorOrOptions;
|
|
5821
|
+
}
|
|
5822
|
+
return createAngularComponentExtension(injector, options);
|
|
5823
|
+
}
|
|
5824
|
+
|
|
5825
|
+
/**
|
|
5826
|
+
* Injection Token for global editor configuration.
|
|
5827
|
+
*/
|
|
5828
|
+
const ATE_GLOBAL_CONFIG = new InjectionToken("ATE_GLOBAL_CONFIG");
|
|
5829
|
+
|
|
5394
5830
|
const AteSelectionCalculator = editor => {
|
|
5395
5831
|
const { selection } = editor.state;
|
|
5396
5832
|
const { from, to } = selection;
|
|
@@ -5746,6 +6182,14 @@ const ATE_DEFAULT_CELL_MENU_CONFIG = {
|
|
|
5746
6182
|
};
|
|
5747
6183
|
|
|
5748
6184
|
// Slash commands configuration is handled dynamically via slashCommandsConfigComputed
|
|
6185
|
+
/**
|
|
6186
|
+
* The main rich-text editor component for Angular.
|
|
6187
|
+
*
|
|
6188
|
+
* Powered by Tiptap and built with a native Signal-based architecture, it provides
|
|
6189
|
+
* a seamless, high-performance editing experience. Supports automatic registration
|
|
6190
|
+
* of Angular components as interactive nodes ('Angular Nodes'), full Reactive Forms
|
|
6191
|
+
* integration, and extensive customization via the AteEditorConfig.
|
|
6192
|
+
*/
|
|
5749
6193
|
class AngularTiptapEditorComponent {
|
|
5750
6194
|
// ============================================
|
|
5751
6195
|
// Toolbar / Bubble Menu Coordination
|
|
@@ -5848,7 +6292,7 @@ class AngularTiptapEditorComponent {
|
|
|
5848
6292
|
this._isFormControlDisabled = signal(false, ...(ngDevMode ? [{ debugName: "_isFormControlDisabled" }] : []));
|
|
5849
6293
|
this.isFormControlDisabled = this._isFormControlDisabled.asReadonly();
|
|
5850
6294
|
// Combined disabled state (Input + FormControl)
|
|
5851
|
-
this.mergedDisabled = computed(() => (this.
|
|
6295
|
+
this.mergedDisabled = computed(() => (this.effectiveConfig().disabled ?? this.disabled()) || this.isFormControlDisabled(), ...(ngDevMode ? [{ debugName: "mergedDisabled" }] : []));
|
|
5852
6296
|
// Computed for editor states
|
|
5853
6297
|
this.isEditorReady = computed(() => this.editor() !== null, ...(ngDevMode ? [{ debugName: "isEditorReady" }] : []));
|
|
5854
6298
|
// ============================================
|
|
@@ -5856,27 +6300,27 @@ class AngularTiptapEditorComponent {
|
|
|
5856
6300
|
// ============================================
|
|
5857
6301
|
// Appearance & Fundamentals
|
|
5858
6302
|
this.finalSeamless = computed(() => {
|
|
5859
|
-
const fromConfig = this.
|
|
6303
|
+
const fromConfig = this.effectiveConfig().mode;
|
|
5860
6304
|
if (fromConfig !== undefined) {
|
|
5861
6305
|
return fromConfig === "seamless";
|
|
5862
6306
|
}
|
|
5863
6307
|
return this.seamless();
|
|
5864
6308
|
}, ...(ngDevMode ? [{ debugName: "finalSeamless" }] : []));
|
|
5865
|
-
this.finalEditable = computed(() => this.
|
|
5866
|
-
this.finalPlaceholder = computed(() => this.
|
|
6309
|
+
this.finalEditable = computed(() => this.effectiveConfig().editable ?? this.editable(), ...(ngDevMode ? [{ debugName: "finalEditable" }] : []));
|
|
6310
|
+
this.finalPlaceholder = computed(() => this.effectiveConfig().placeholder ??
|
|
5867
6311
|
(this.placeholder() || this.currentTranslations().editor.placeholder), ...(ngDevMode ? [{ debugName: "finalPlaceholder" }] : []));
|
|
5868
|
-
this.finalFillContainer = computed(() => this.
|
|
5869
|
-
this.finalShowFooter = computed(() => this.
|
|
5870
|
-
this.finalShowEditToggle = computed(() => this.
|
|
5871
|
-
this.finalHeight = computed(() => this.
|
|
5872
|
-
this.finalMinHeight = computed(() => this.
|
|
5873
|
-
this.finalMaxHeight = computed(() => this.
|
|
5874
|
-
this.finalSpellcheck = computed(() => this.
|
|
5875
|
-
this.finalEnableOfficePaste = computed(() => this.
|
|
6312
|
+
this.finalFillContainer = computed(() => this.effectiveConfig().fillContainer ?? this.fillContainer(), ...(ngDevMode ? [{ debugName: "finalFillContainer" }] : []));
|
|
6313
|
+
this.finalShowFooter = computed(() => this.effectiveConfig().showFooter ?? this.showFooter(), ...(ngDevMode ? [{ debugName: "finalShowFooter" }] : []));
|
|
6314
|
+
this.finalShowEditToggle = computed(() => this.effectiveConfig().showEditToggle ?? this.showEditToggle(), ...(ngDevMode ? [{ debugName: "finalShowEditToggle" }] : []));
|
|
6315
|
+
this.finalHeight = computed(() => this.effectiveConfig().height ?? (this.height() ? `${this.height()}px` : undefined), ...(ngDevMode ? [{ debugName: "finalHeight" }] : []));
|
|
6316
|
+
this.finalMinHeight = computed(() => this.effectiveConfig().minHeight ?? (this.minHeight() ? `${this.minHeight()}px` : undefined), ...(ngDevMode ? [{ debugName: "finalMinHeight" }] : []));
|
|
6317
|
+
this.finalMaxHeight = computed(() => this.effectiveConfig().maxHeight ?? (this.maxHeight() ? `${this.maxHeight()}px` : undefined), ...(ngDevMode ? [{ debugName: "finalMaxHeight" }] : []));
|
|
6318
|
+
this.finalSpellcheck = computed(() => this.effectiveConfig().spellcheck ?? this.spellcheck(), ...(ngDevMode ? [{ debugName: "finalSpellcheck" }] : []));
|
|
6319
|
+
this.finalEnableOfficePaste = computed(() => this.effectiveConfig().enableOfficePaste ?? this.enableOfficePaste(), ...(ngDevMode ? [{ debugName: "finalEnableOfficePaste" }] : []));
|
|
5876
6320
|
// Features
|
|
5877
|
-
this.finalShowToolbar = computed(() => this.
|
|
6321
|
+
this.finalShowToolbar = computed(() => this.effectiveConfig().showToolbar ?? this.showToolbar(), ...(ngDevMode ? [{ debugName: "finalShowToolbar" }] : []));
|
|
5878
6322
|
this.finalToolbarConfig = computed(() => {
|
|
5879
|
-
const fromConfig = this.
|
|
6323
|
+
const fromConfig = this.effectiveConfig().toolbar;
|
|
5880
6324
|
const base = ATE_DEFAULT_TOOLBAR_CONFIG;
|
|
5881
6325
|
if (fromConfig) {
|
|
5882
6326
|
return { ...base, ...fromConfig };
|
|
@@ -5884,19 +6328,19 @@ class AngularTiptapEditorComponent {
|
|
|
5884
6328
|
const fromInput = this.toolbar();
|
|
5885
6329
|
return Object.keys(fromInput).length === 0 ? base : { ...base, ...fromInput };
|
|
5886
6330
|
}, ...(ngDevMode ? [{ debugName: "finalToolbarConfig" }] : []));
|
|
5887
|
-
this.finalFloatingToolbar = computed(() => this.
|
|
5888
|
-
this.finalShowBubbleMenu = computed(() => this.
|
|
6331
|
+
this.finalFloatingToolbar = computed(() => this.effectiveConfig().floatingToolbar ?? this.floatingToolbar(), ...(ngDevMode ? [{ debugName: "finalFloatingToolbar" }] : []));
|
|
6332
|
+
this.finalShowBubbleMenu = computed(() => this.effectiveConfig().showBubbleMenu ?? this.showBubbleMenu(), ...(ngDevMode ? [{ debugName: "finalShowBubbleMenu" }] : []));
|
|
5889
6333
|
this.finalBubbleMenuConfig = computed(() => {
|
|
5890
|
-
const fromConfig = this.
|
|
6334
|
+
const fromConfig = this.effectiveConfig().bubbleMenu;
|
|
5891
6335
|
const base = ATE_DEFAULT_BUBBLE_MENU_CONFIG;
|
|
5892
6336
|
if (fromConfig) {
|
|
5893
6337
|
return { ...base, ...fromConfig };
|
|
5894
6338
|
}
|
|
5895
6339
|
return Object.keys(this.bubbleMenu()).length === 0 ? base : { ...base, ...this.bubbleMenu() };
|
|
5896
6340
|
}, ...(ngDevMode ? [{ debugName: "finalBubbleMenuConfig" }] : []));
|
|
5897
|
-
this.finalShowImageBubbleMenu = computed(() => this.
|
|
6341
|
+
this.finalShowImageBubbleMenu = computed(() => this.effectiveConfig().showImageBubbleMenu ?? this.showImageBubbleMenu(), ...(ngDevMode ? [{ debugName: "finalShowImageBubbleMenu" }] : []));
|
|
5898
6342
|
this.finalImageBubbleMenuConfig = computed(() => {
|
|
5899
|
-
const fromConfig = this.
|
|
6343
|
+
const fromConfig = this.effectiveConfig().imageBubbleMenu;
|
|
5900
6344
|
const base = ATE_DEFAULT_IMAGE_BUBBLE_MENU_CONFIG;
|
|
5901
6345
|
if (fromConfig) {
|
|
5902
6346
|
return { ...base, ...fromConfig };
|
|
@@ -5905,9 +6349,9 @@ class AngularTiptapEditorComponent {
|
|
|
5905
6349
|
? base
|
|
5906
6350
|
: { ...base, ...this.imageBubbleMenu() };
|
|
5907
6351
|
}, ...(ngDevMode ? [{ debugName: "finalImageBubbleMenuConfig" }] : []));
|
|
5908
|
-
this.finalShowTableBubbleMenu = computed(() => this.
|
|
6352
|
+
this.finalShowTableBubbleMenu = computed(() => this.effectiveConfig().showTableMenu ?? this.showTableBubbleMenu(), ...(ngDevMode ? [{ debugName: "finalShowTableBubbleMenu" }] : []));
|
|
5909
6353
|
this.finalTableBubbleMenuConfig = computed(() => {
|
|
5910
|
-
const fromConfig = this.
|
|
6354
|
+
const fromConfig = this.effectiveConfig().tableBubbleMenu;
|
|
5911
6355
|
const base = ATE_DEFAULT_TABLE_MENU_CONFIG;
|
|
5912
6356
|
if (fromConfig) {
|
|
5913
6357
|
return { ...base, ...fromConfig };
|
|
@@ -5916,9 +6360,9 @@ class AngularTiptapEditorComponent {
|
|
|
5916
6360
|
? base
|
|
5917
6361
|
: { ...base, ...this.tableBubbleMenu() };
|
|
5918
6362
|
}, ...(ngDevMode ? [{ debugName: "finalTableBubbleMenuConfig" }] : []));
|
|
5919
|
-
this.finalShowCellBubbleMenu = computed(() => this.
|
|
6363
|
+
this.finalShowCellBubbleMenu = computed(() => this.effectiveConfig().showCellMenu ?? this.showCellBubbleMenu(), ...(ngDevMode ? [{ debugName: "finalShowCellBubbleMenu" }] : []));
|
|
5920
6364
|
this.finalCellBubbleMenuConfig = computed(() => {
|
|
5921
|
-
const fromConfig = this.
|
|
6365
|
+
const fromConfig = this.effectiveConfig().cellBubbleMenu;
|
|
5922
6366
|
const base = ATE_DEFAULT_CELL_MENU_CONFIG;
|
|
5923
6367
|
if (fromConfig) {
|
|
5924
6368
|
return { ...base, ...fromConfig };
|
|
@@ -5927,10 +6371,12 @@ class AngularTiptapEditorComponent {
|
|
|
5927
6371
|
? base
|
|
5928
6372
|
: { ...base, ...this.cellBubbleMenu() };
|
|
5929
6373
|
}, ...(ngDevMode ? [{ debugName: "finalCellBubbleMenuConfig" }] : []));
|
|
5930
|
-
this.finalEnableSlashCommands = computed(() => this.
|
|
6374
|
+
this.finalEnableSlashCommands = computed(() => this.effectiveConfig().enableSlashCommands ?? this.enableSlashCommands(), ...(ngDevMode ? [{ debugName: "finalEnableSlashCommands" }] : []));
|
|
5931
6375
|
this.finalSlashCommandsConfig = computed(() => {
|
|
5932
|
-
const fromConfig = this.
|
|
5933
|
-
const
|
|
6376
|
+
const fromConfig = this.effectiveConfig().slashCommands;
|
|
6377
|
+
const fromGlobalCustom = this.effectiveConfig().customSlashCommands;
|
|
6378
|
+
const fromInputCustom = this.customSlashCommands();
|
|
6379
|
+
const customConfig = fromInputCustom ?? fromGlobalCustom;
|
|
5934
6380
|
if (customConfig) {
|
|
5935
6381
|
return customConfig;
|
|
5936
6382
|
}
|
|
@@ -5943,14 +6389,19 @@ class AngularTiptapEditorComponent {
|
|
|
5943
6389
|
};
|
|
5944
6390
|
}, ...(ngDevMode ? [{ debugName: "finalSlashCommandsConfig" }] : []));
|
|
5945
6391
|
// Behavior
|
|
5946
|
-
this.finalAutofocus = computed(() => this.
|
|
5947
|
-
this.finalMaxCharacters = computed(() => this.
|
|
5948
|
-
this.finalShowCharacterCount = computed(() => this.
|
|
5949
|
-
this.finalShowWordCount = computed(() => this.
|
|
5950
|
-
this.finalLocale = computed(() => this.
|
|
6392
|
+
this.finalAutofocus = computed(() => this.effectiveConfig().autofocus ?? this.autofocus(), ...(ngDevMode ? [{ debugName: "finalAutofocus" }] : []));
|
|
6393
|
+
this.finalMaxCharacters = computed(() => this.effectiveConfig().maxCharacters ?? this.maxCharacters(), ...(ngDevMode ? [{ debugName: "finalMaxCharacters" }] : []));
|
|
6394
|
+
this.finalShowCharacterCount = computed(() => this.effectiveConfig().showCharacterCount ?? this.showCharacterCount(), ...(ngDevMode ? [{ debugName: "finalShowCharacterCount" }] : []));
|
|
6395
|
+
this.finalShowWordCount = computed(() => this.effectiveConfig().showWordCount ?? this.showWordCount(), ...(ngDevMode ? [{ debugName: "finalShowWordCount" }] : []));
|
|
6396
|
+
this.finalLocale = computed(() => this.effectiveConfig().locale ?? this.locale(), ...(ngDevMode ? [{ debugName: "finalLocale" }] : []));
|
|
6397
|
+
// Extensions & Options
|
|
6398
|
+
this.finalTiptapExtensions = computed(() => this.effectiveConfig().tiptapExtensions ?? this.tiptapExtensions() ?? [], ...(ngDevMode ? [{ debugName: "finalTiptapExtensions" }] : []));
|
|
6399
|
+
this.finalTiptapOptions = computed(() => this.effectiveConfig().tiptapOptions ?? this.tiptapOptions() ?? {}, ...(ngDevMode ? [{ debugName: "finalTiptapOptions" }] : []));
|
|
6400
|
+
this.finalStateCalculators = computed(() => this.effectiveConfig().stateCalculators ?? this.stateCalculators() ?? [], ...(ngDevMode ? [{ debugName: "finalStateCalculators" }] : []));
|
|
6401
|
+
this.finalAngularNodesConfig = computed(() => this.effectiveConfig().angularNodes ?? [], ...(ngDevMode ? [{ debugName: "finalAngularNodesConfig" }] : []));
|
|
5951
6402
|
// Image Upload
|
|
5952
6403
|
this.finalImageUploadConfig = computed(() => {
|
|
5953
|
-
const fromConfig = this.
|
|
6404
|
+
const fromConfig = this.effectiveConfig().imageUpload;
|
|
5954
6405
|
const fromInput = this.imageUpload();
|
|
5955
6406
|
const merged = {
|
|
5956
6407
|
maxSize: 5, // Default 5MB
|
|
@@ -5970,7 +6421,7 @@ class AngularTiptapEditorComponent {
|
|
|
5970
6421
|
maxSize: merged.maxSize * 1024 * 1024, // Convert MB to bytes for internal service
|
|
5971
6422
|
};
|
|
5972
6423
|
}, ...(ngDevMode ? [{ debugName: "finalImageUploadConfig" }] : []));
|
|
5973
|
-
this.finalImageUploadHandler = computed(() => this.
|
|
6424
|
+
this.finalImageUploadHandler = computed(() => this.effectiveConfig().imageUpload?.handler ?? this.imageUploadHandler(), ...(ngDevMode ? [{ debugName: "finalImageUploadHandler" }] : []));
|
|
5974
6425
|
// Computed for current translations (allows per-instance override via config or input)
|
|
5975
6426
|
this.currentTranslations = computed(() => {
|
|
5976
6427
|
const localeOverride = this.finalLocale();
|
|
@@ -5987,6 +6438,17 @@ class AngularTiptapEditorComponent {
|
|
|
5987
6438
|
this.editorCommandsService = inject(AteEditorCommandsService);
|
|
5988
6439
|
// Access editor state via service
|
|
5989
6440
|
this.editorState = this.editorCommandsService.editorState;
|
|
6441
|
+
this.injector = inject(Injector);
|
|
6442
|
+
this.globalConfig = inject(ATE_GLOBAL_CONFIG, { optional: true });
|
|
6443
|
+
/**
|
|
6444
|
+
* Final merged configuration.
|
|
6445
|
+
* Priority: Input [config] > Global config via provideAteEditor()
|
|
6446
|
+
*/
|
|
6447
|
+
this.effectiveConfig = computed(() => {
|
|
6448
|
+
const fromInput = this.config();
|
|
6449
|
+
const fromGlobal = this.globalConfig || {};
|
|
6450
|
+
return { ...fromGlobal, ...fromInput };
|
|
6451
|
+
}, ...(ngDevMode ? [{ debugName: "effectiveConfig" }] : []));
|
|
5990
6452
|
// Effect to update editor content (with anti-echo)
|
|
5991
6453
|
effect(() => {
|
|
5992
6454
|
const content = this.content(); // Sole reactive dependency
|
|
@@ -6053,6 +6515,24 @@ class AngularTiptapEditorComponent {
|
|
|
6053
6515
|
}
|
|
6054
6516
|
}
|
|
6055
6517
|
});
|
|
6518
|
+
// Effect to re-initialize editor when technical configuration changes
|
|
6519
|
+
effect(() => {
|
|
6520
|
+
// Monitor technical dependencies
|
|
6521
|
+
this.finalTiptapExtensions();
|
|
6522
|
+
this.finalTiptapOptions();
|
|
6523
|
+
this.finalAngularNodesConfig();
|
|
6524
|
+
untracked(() => {
|
|
6525
|
+
// Only if already initialized (post AfterViewInit)
|
|
6526
|
+
if (this.editorFullyInitialized()) {
|
|
6527
|
+
const currentEditor = this.editor();
|
|
6528
|
+
if (currentEditor) {
|
|
6529
|
+
currentEditor.destroy();
|
|
6530
|
+
this._editorFullyInitialized.set(false);
|
|
6531
|
+
this.initEditor();
|
|
6532
|
+
}
|
|
6533
|
+
}
|
|
6534
|
+
});
|
|
6535
|
+
});
|
|
6056
6536
|
}
|
|
6057
6537
|
ngAfterViewInit() {
|
|
6058
6538
|
// La vue est déjà complètement initialisée dans ngAfterViewInit
|
|
@@ -6119,7 +6599,7 @@ class AngularTiptapEditorComponent {
|
|
|
6119
6599
|
AteImageCalculator,
|
|
6120
6600
|
AteStructureCalculator,
|
|
6121
6601
|
AteDiscoveryCalculator,
|
|
6122
|
-
...this.
|
|
6602
|
+
...this.finalStateCalculators(),
|
|
6123
6603
|
],
|
|
6124
6604
|
}),
|
|
6125
6605
|
];
|
|
@@ -6136,8 +6616,22 @@ class AngularTiptapEditorComponent {
|
|
|
6136
6616
|
limit: this.finalMaxCharacters(),
|
|
6137
6617
|
}));
|
|
6138
6618
|
}
|
|
6619
|
+
// Register automatic node views from config
|
|
6620
|
+
const autoNodeViews = this.finalAngularNodesConfig();
|
|
6621
|
+
autoNodeViews.forEach(reg => {
|
|
6622
|
+
const options = typeof reg === "function"
|
|
6623
|
+
? { component: reg }
|
|
6624
|
+
: reg;
|
|
6625
|
+
try {
|
|
6626
|
+
const extension = registerAngularComponent(this.injector, options);
|
|
6627
|
+
extensions.push(extension);
|
|
6628
|
+
}
|
|
6629
|
+
catch (e) {
|
|
6630
|
+
console.error("[ATE] Failed to auto-register node view:", e);
|
|
6631
|
+
}
|
|
6632
|
+
});
|
|
6139
6633
|
// Allow addition of custom extensions, but avoid duplicates by filtering by name
|
|
6140
|
-
const customExtensions = this.
|
|
6634
|
+
const customExtensions = this.finalTiptapExtensions();
|
|
6141
6635
|
if (customExtensions.length > 0) {
|
|
6142
6636
|
const existingNames = new Set(extensions
|
|
6143
6637
|
.map(ext => ext?.name)
|
|
@@ -6149,7 +6643,7 @@ class AngularTiptapEditorComponent {
|
|
|
6149
6643
|
extensions.push(...toAdd);
|
|
6150
6644
|
}
|
|
6151
6645
|
// Also allow any tiptap user options
|
|
6152
|
-
const userOptions = this.
|
|
6646
|
+
const userOptions = this.finalTiptapOptions();
|
|
6153
6647
|
const newEditor = new Editor({
|
|
6154
6648
|
...userOptions,
|
|
6155
6649
|
element: this.editorElement().nativeElement,
|
|
@@ -6590,6 +7084,37 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
6590
7084
|
`, styles: [":host{--ate-primary: #2563eb;--ate-primary-contrast: #ffffff;--ate-primary-light: color-mix(in srgb, var(--ate-primary), transparent 90%);--ate-primary-lighter: color-mix(in srgb, var(--ate-primary), transparent 95%);--ate-primary-light-alpha: color-mix(in srgb, var(--ate-primary), transparent 85%);--ate-surface: #ffffff;--ate-surface-secondary: #f8f9fa;--ate-surface-tertiary: #f1f5f9;--ate-text: #2d3748;--ate-text-secondary: #64748b;--ate-text-muted: #a0aec0;--ate-border: #e2e8f0;--ate-highlight-bg: #fef08a;--ate-highlight-color: #854d0e;--ate-button-hover: #f1f5f9;--ate-button-active: #e2e8f0;--ate-error-color: #c53030;--ate-error-bg: #fed7d7;--ate-error-border: #feb2b2;--ate-border-color: var(--ate-border);--ate-border-width: 2px;--ate-border-radius: 12px;--ate-focus-color: var(--ate-primary);--ate-background: var(--ate-surface);--ate-sub-border-radius: 8px;--ate-text-color: var(--ate-text);--ate-placeholder-color: var(--ate-text-muted);--ate-line-height: 1.6;--ate-content-padding: 16px;--ate-menu-bg: var(--ate-surface);--ate-menu-border-radius: var(--ate-border-radius);--ate-menu-border: var(--ate-border);--ate-menu-shadow: 0 10px 15px -3px rgba(0, 0, 0, .1), 0 4px 6px -2px rgba(0, 0, 0, .05);--ate-menu-padding: 6px;--ate-toolbar-padding: var(--ate-menu-padding);--ate-toolbar-background: var(--ate-surface-secondary);--ate-toolbar-border-color: var(--ate-border);--ate-toolbar-button-color: var(--ate-text-secondary);--ate-toolbar-button-hover-background: transparent;--ate-toolbar-button-active-background: var(--ate-primary-light);--ate-toolbar-button-active-color: var(--ate-primary);--ate-counter-color: var(--ate-text-secondary);--ate-counter-background: var(--ate-surface-secondary);--ate-counter-border-color: var(--ate-border);--ate-drag-background: #f0f8ff;--ate-drag-border-color: var(--ate-primary);--ate-blockquote-border-color: var(--ate-border);--ate-blockquote-background: var(--ate-surface-secondary);--ate-code-background: var(--ate-surface-secondary);--ate-code-color: var(--ate-code-color);--ate-code-border-color: var(--ate-border);--ate-code-block-background: #0f172a;--ate-code-block-color: #e2e8f0;--ate-code-block-border-color: var(--ate-border);--ate-image-border-radius: 16px;--ate-image-selected-color: var(--ate-primary);--ate-scrollbar-width: 10px;--ate-scrollbar-thumb: var(--ate-border);--ate-scrollbar-thumb-hover: var(--ate-text-muted);--ate-scrollbar-track: transparent;--ate-table-border-color: var(--ate-border);--ate-table-header-background: var(--ate-surface-secondary);--ate-table-header-color: var(--ate-text);--ate-table-cell-background: var(--ate-surface);--ate-table-cell-selected-background: var(--ate-primary-light);--ate-table-resize-handle-color: var(--ate-primary);--ate-table-row-hover-background: var(--ate-primary-lighter)}:host(.dark),:host([data-theme=\"dark\"]){--ate-primary: #3b82f6;--ate-primary-contrast: #ffffff;--ate-primary-light: color-mix(in srgb, var(--ate-primary), transparent 85%);--ate-primary-lighter: color-mix(in srgb, var(--ate-primary), transparent 92%);--ate-primary-light-alpha: color-mix(in srgb, var(--ate-primary), transparent 80%);--ate-surface: #020617;--ate-surface-secondary: #0f172a;--ate-surface-tertiary: #1e293b;--ate-text: #f8fafc;--ate-text-secondary: #94a3b8;--ate-text-muted: #64748b;--ate-border: #1e293b;--ate-highlight-bg: #854d0e;--ate-highlight-color: #fef08a;--ate-button-hover: #1e293b;--ate-button-active: #0f172a;--ate-menu-border: rgba(255, 255, 255, .1);--ate-menu-shadow: 0 20px 25px -5px rgba(0, 0, 0, .3), 0 10px 10px -5px rgba(0, 0, 0, .2);--ate-error-color: #f87171;--ate-error-bg: #450a0a;--ate-error-border: #7f1d1d;--ate-drag-background: var(--ate-surface-tertiary);--ate-drag-border-color: var(--ate-primary);--ate-blockquote-border-color: var(--ate-primary);--ate-toolbar-button-active-background: var(--ate-primary-light);--ate-toolbar-button-active-color: var(--ate-primary);--ate-button-hover: var(--ate-surface-tertiary);--ate-button-active: var(--ate-surface-secondary);--ate-scrollbar-thumb: var(--ate-surface-tertiary);--ate-scrollbar-thumb-hover: var(--ate-text-muted)}:host(.fill-container){display:block;height:100%}.ate-editor{border:var(--ate-border-width) solid var(--ate-border-color);border-radius:var(--ate-border-radius);background:var(--ate-background);overflow:visible;transition:border-color .2s ease;position:relative}:host(.floating-toolbar) .ate-editor{overflow:visible}:host(.fill-container) .ate-editor{display:flex;flex-direction:column;height:100%}:host(.fill-container) .ate-content-wrapper{flex:1;min-height:0}:host(.fill-container) .ate-content{flex:1;min-height:0;overflow-y:auto}.ate-editor:focus-within{border-color:var(--ate-focus-color)}.ate-content{min-height:var(--editor-min-height, 200px);height:var(--editor-height, auto);max-height:var(--editor-max-height, none);overflow-y:var(--editor-overflow, visible);outline:none;position:relative;scrollbar-width:thin;scrollbar-color:var(--ate-scrollbar-thumb) var(--ate-scrollbar-track)}:host(.is-disabled) .ate-content{cursor:not-allowed;opacity:.7;-webkit-user-select:none;user-select:none;pointer-events:none;background-color:var(--ate-surface-tertiary)}:host(.is-readonly) .ate-content{cursor:default;-webkit-user-select:text;user-select:text}:host(.is-readonly) .ate-content ::ng-deep .ate-link{cursor:pointer;pointer-events:auto}.ate-content::-webkit-scrollbar{width:var(--ate-scrollbar-width)}.ate-content-wrapper{position:relative;display:flex;flex-direction:column;min-height:0}.ate-content-wrapper .ate-content{flex:1}.ate-content::-webkit-scrollbar-track{background:var(--ate-scrollbar-track)}.ate-content::-webkit-scrollbar-thumb{background:var(--ate-scrollbar-thumb);border:3px solid transparent;background-clip:content-box;border-radius:10px}.ate-content::-webkit-scrollbar-thumb:hover{background:var(--ate-scrollbar-thumb-hover);background-clip:content-box}.ate-content.drag-over{background:var(--ate-drag-background);border:2px dashed var(--ate-drag-border-color)}.character-count{padding:6px 8px;font-size:12px;color:var(--ate-counter-color);text-align:right;border-top:1px solid var(--ate-counter-border-color);background:var(--ate-counter-background);transition:color .2s ease;border-bottom-left-radius:calc(var(--ate-border-radius) - var(--ate-border-width));border-bottom-right-radius:calc(var(--ate-border-radius) - var(--ate-border-width))}.character-count.limit-reached{color:var(--ate-error-color, #ef4444);font-weight:600}:host ::ng-deep .ProseMirror{padding:var(--ate-content-padding);outline:none;line-height:var(--ate-line-height);color:var(--ate-text-color);min-height:100%;height:100%;word-wrap:break-word;overflow-wrap:break-word}:host ::ng-deep .ProseMirror h1{font-size:2em;font-weight:700;margin-top:0;margin-bottom:.5em}:host ::ng-deep .ProseMirror h2{font-size:1.5em;font-weight:700;margin-top:1em;margin-bottom:.5em}:host ::ng-deep .ProseMirror h3{font-size:1.25em;font-weight:700;margin-top:1em;margin-bottom:.5em}:host ::ng-deep .ProseMirror p{margin:.5em 0}:host ::ng-deep .ProseMirror ul,:host ::ng-deep .ProseMirror ol{padding-left:2em;margin:.5em 0}:host ::ng-deep .ProseMirror blockquote{border-left:4px solid var(--ate-blockquote-border-color);margin:1em 0;background:var(--ate-blockquote-background);padding:.5em 1em;border-radius:0 4px 4px 0}:host ::ng-deep .ProseMirror code{background:var(--ate-code-background);color:var(--ate-code-color);border:1px solid var(--ate-code-border-color);padding:.15em .4em;border-radius:4px;font-family:JetBrains Mono,Fira Code,Monaco,Consolas,monospace;font-size:.85em;font-weight:500}:host ::ng-deep .ProseMirror pre{background:var(--ate-code-block-background);color:var(--ate-code-block-color);border:1px solid var(--ate-code-block-border-color);padding:1em;border-radius:var(--ate-border-radius);overflow-x:auto;margin:1em 0}:host ::ng-deep .ProseMirror pre code{background:none;color:inherit;border:none;padding:0}:host ::ng-deep .ProseMirror p.is-editor-empty:first-child:before{content:attr(data-placeholder);color:var(--ate-placeholder-color);pointer-events:none;float:left;height:0}:host ::ng-deep .ProseMirror[contenteditable=false]{pointer-events:none}:host ::ng-deep .ProseMirror[contenteditable=false] img{cursor:default;pointer-events:none}:host ::ng-deep .ProseMirror[contenteditable=false] img:hover{transform:none;box-shadow:0 2px 8px #0000001a}:host ::ng-deep .ProseMirror[contenteditable=false] img.ProseMirror-selectednode{outline:none}:host ::ng-deep .ProseMirror img{position:relative;display:inline-block;max-width:100%;height:auto;cursor:pointer;transition:all .2s ease;border:2px solid transparent;border-radius:var(--ate-image-border-radius)}:host ::ng-deep .ProseMirror img:hover{border-color:var(--ate-border-color);box-shadow:0 2px 4px #0000001a}:host ::ng-deep .ProseMirror img.ProseMirror-selectednode{border-color:var(--ate-image-selected-color);box-shadow:0 0 0 3px var(--ate-primary-light-alpha);transition:all .2s ease}:host ::ng-deep .ProseMirror .tiptap-image{max-width:100%;height:auto;border-radius:var(--ate-image-border-radius);box-shadow:0 4px 20px #00000014;margin:.5em 0;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);display:block;filter:brightness(1) contrast(1)}:host ::ng-deep .ProseMirror .tiptap-image:hover{box-shadow:0 8px 30px #0000001f;filter:brightness(1.02) contrast(1.02)}:host ::ng-deep .ProseMirror .tiptap-image.ProseMirror-selectednode{outline:2px solid var(--ate-primary);outline-offset:2px;border-radius:var(--ate-image-border-radius);box-shadow:0 0 0 4px var(--ate-primary-light-alpha)}:host ::ng-deep .image-container{margin:.5em 0;text-align:center;border-radius:16px;overflow:hidden;transition:all .3s cubic-bezier(.4,0,.2,1)}:host ::ng-deep .image-container.image-align-left{text-align:left}:host ::ng-deep .image-container.image-align-center{text-align:center}:host ::ng-deep .image-container.image-align-right{text-align:right}:host ::ng-deep .image-container img{display:inline-block;max-width:100%;height:auto;border-radius:16px}:host ::ng-deep .resizable-image-container{position:relative;display:inline-block;margin:.5em 0}:host ::ng-deep .resize-controls{position:absolute;inset:0;pointer-events:none;z-index:1000}:host ::ng-deep .resize-handle{position:absolute;width:12px;height:12px;background:var(--ate-primary);border:2px solid var(--ate-surface);border-radius:50%;pointer-events:all;cursor:pointer;z-index:1001;transition:all .15s ease;box-shadow:0 2px 6px #0003}:host ::ng-deep .resize-handle:hover{background:var(--ate-primary);box-shadow:0 3px 8px #0000004d}:host ::ng-deep .resize-handle:active{background:var(--ate-primary)}:host ::ng-deep .resize-handle-n:hover,:host ::ng-deep .resize-handle-s:hover{transform:translate(-50%) scale(1.2)}:host ::ng-deep .resize-handle-w:hover,:host ::ng-deep .resize-handle-e:hover{transform:translateY(-50%) scale(1.2)}:host ::ng-deep .resize-handle-n:active,:host ::ng-deep .resize-handle-s:active{transform:translate(-50%) scale(.9)}:host ::ng-deep .resize-handle-w:active,:host ::ng-deep .resize-handle-e:active{transform:translateY(-50%) scale(.9)}:host ::ng-deep .resize-handle-nw:hover,:host ::ng-deep .resize-handle-ne:hover,:host ::ng-deep .resize-handle-sw:hover,:host ::ng-deep .resize-handle-se:hover{transform:scale(1.2)}:host ::ng-deep .resize-handle-nw:active,:host ::ng-deep .resize-handle-ne:active,:host ::ng-deep .resize-handle-sw:active,:host ::ng-deep .resize-handle-se:active{transform:scale(.9)}:host ::ng-deep .resize-handle-nw{top:0;left:-6px;cursor:nw-resize}:host ::ng-deep .resize-handle-n{top:0;left:50%;transform:translate(-50%);cursor:n-resize}:host ::ng-deep .resize-handle-ne{top:0;right:-6px;cursor:ne-resize}:host ::ng-deep .resize-handle-w{top:50%;left:-6px;transform:translateY(-50%);cursor:w-resize}:host ::ng-deep .resize-handle-e{top:50%;right:-6px;transform:translateY(-50%);cursor:e-resize}:host ::ng-deep .resize-handle-sw{bottom:0;left:-6px;cursor:sw-resize}:host ::ng-deep .resize-handle-s{bottom:0;left:50%;transform:translate(-50%);cursor:s-resize}:host ::ng-deep .resize-handle-se{bottom:0;right:-6px;cursor:se-resize}:host ::ng-deep body.resizing{-webkit-user-select:none;user-select:none;cursor:crosshair}:host ::ng-deep body.resizing .ProseMirror{pointer-events:none}:host ::ng-deep body.resizing .ProseMirror .tiptap-image{pointer-events:none}:host ::ng-deep .image-size-info{position:absolute;bottom:-20px;left:50%;transform:translate(-50%);background:#000c;color:#fff;padding:2px 6px;border-radius:3px;font-size:11px;white-space:nowrap;opacity:0;transition:opacity .2s ease}:host ::ng-deep .image-container:hover .image-size-info{opacity:1}:host ::ng-deep .ProseMirror table{border-collapse:separate;border-spacing:0;margin:0;table-layout:fixed;width:100%;border-radius:8px;overflow:hidden}:host ::ng-deep .ProseMirror table td,:host ::ng-deep .ProseMirror table th{border:none;border-right:1px solid var(--ate-table-border-color);border-bottom:1px solid var(--ate-table-border-color);box-sizing:border-box;min-width:1em;padding:8px 12px;position:relative;vertical-align:top;text-align:left}:host ::ng-deep .ProseMirror table td{background:var(--ate-table-cell-background)}:host ::ng-deep .ProseMirror table td:first-child,:host ::ng-deep .ProseMirror table th:first-child{border-left:1px solid var(--ate-table-border-color)}:host ::ng-deep .ProseMirror table tr:first-child td,:host ::ng-deep .ProseMirror table tr:first-child th{border-top:1px solid var(--ate-table-border-color)}:host ::ng-deep .ProseMirror table tr:first-child th:first-child{border-top-left-radius:8px}:host ::ng-deep .ProseMirror table tr:first-child th:last-child{border-top-right-radius:8px}:host ::ng-deep .ProseMirror table tr:last-child td:first-child{border-bottom-left-radius:8px}:host ::ng-deep .ProseMirror table tr:last-child td:last-child{border-bottom-right-radius:8px}:host ::ng-deep .ProseMirror table th{background:var(--ate-table-header-background);font-weight:600;color:var(--ate-table-header-color)}:host ::ng-deep .ProseMirror table .selectedCell:after{background:var(--ate-table-cell-selected-background);content:\"\";inset:0;pointer-events:none;position:absolute;z-index:2}:host ::ng-deep .ProseMirror table .column-resize-handle{position:absolute;right:-2px;top:0;bottom:0;width:4px;background-color:var(--ate-table-resize-handle-color);opacity:0;transition:opacity .2s ease}:host ::ng-deep .ProseMirror table:hover .column-resize-handle{opacity:1}:host ::ng-deep .ProseMirror table .column-resize-handle:hover{background-color:var(--ate-focus-color)}:host ::ng-deep .ProseMirror .tableWrapper{overflow-x:auto;margin:1em 0;border-radius:8px}:host ::ng-deep .ProseMirror .tableWrapper table{margin:0;border-radius:8px;min-width:600px;overflow:hidden}:host ::ng-deep .ProseMirror table p{margin:0}:host ::ng-deep .ProseMirror table tbody tr:hover td{background-color:var(--ate-table-row-hover-background)}\n"] }]
|
|
6591
7085
|
}], ctorParameters: () => [], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], content: [{ type: i0.Input, args: [{ isSignal: true, alias: "content", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], editable: [{ type: i0.Input, args: [{ isSignal: true, alias: "editable", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], minHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "minHeight", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], maxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxHeight", required: false }] }], fillContainer: [{ type: i0.Input, args: [{ isSignal: true, alias: "fillContainer", required: false }] }], showToolbar: [{ type: i0.Input, args: [{ isSignal: true, alias: "showToolbar", required: false }] }], showFooter: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFooter", required: false }] }], showCharacterCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCharacterCount", required: false }] }], showWordCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "showWordCount", required: false }] }], maxCharacters: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxCharacters", required: false }] }], enableOfficePaste: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableOfficePaste", required: false }] }], enableSlashCommands: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableSlashCommands", required: false }] }], slashCommands: [{ type: i0.Input, args: [{ isSignal: true, alias: "slashCommands", required: false }] }], customSlashCommands: [{ type: i0.Input, args: [{ isSignal: true, alias: "customSlashCommands", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], autofocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "autofocus", required: false }] }], seamless: [{ type: i0.Input, args: [{ isSignal: true, alias: "seamless", required: false }] }], floatingToolbar: [{ type: i0.Input, args: [{ isSignal: true, alias: "floatingToolbar", required: false }] }], showEditToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "showEditToggle", required: false }] }], spellcheck: [{ type: i0.Input, args: [{ isSignal: true, alias: "spellcheck", required: false }] }], tiptapExtensions: [{ type: i0.Input, args: [{ isSignal: true, alias: "tiptapExtensions", required: false }] }], tiptapOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "tiptapOptions", required: false }] }], showBubbleMenu: [{ type: i0.Input, args: [{ isSignal: true, alias: "showBubbleMenu", required: false }] }], bubbleMenu: [{ type: i0.Input, args: [{ isSignal: true, alias: "bubbleMenu", required: false }] }], showImageBubbleMenu: [{ type: i0.Input, args: [{ isSignal: true, alias: "showImageBubbleMenu", required: false }] }], imageBubbleMenu: [{ type: i0.Input, args: [{ isSignal: true, alias: "imageBubbleMenu", required: false }] }], toolbar: [{ type: i0.Input, args: [{ isSignal: true, alias: "toolbar", required: false }] }], showTableBubbleMenu: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTableBubbleMenu", required: false }] }], tableBubbleMenu: [{ type: i0.Input, args: [{ isSignal: true, alias: "tableBubbleMenu", required: false }] }], showCellBubbleMenu: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCellBubbleMenu", required: false }] }], cellBubbleMenu: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellBubbleMenu", required: false }] }], stateCalculators: [{ type: i0.Input, args: [{ isSignal: true, alias: "stateCalculators", required: false }] }], imageUpload: [{ type: i0.Input, args: [{ isSignal: true, alias: "imageUpload", required: false }] }], imageUploadHandler: [{ type: i0.Input, args: [{ isSignal: true, alias: "imageUploadHandler", required: false }] }], contentChange: [{ type: i0.Output, args: ["contentChange"] }], editorCreated: [{ type: i0.Output, args: ["editorCreated"] }], editorUpdate: [{ type: i0.Output, args: ["editorUpdate"] }], editorFocus: [{ type: i0.Output, args: ["editorFocus"] }], editorBlur: [{ type: i0.Output, args: ["editorBlur"] }], editableChange: [{ type: i0.Output, args: ["editableChange"] }], editorElement: [{ type: i0.ViewChild, args: ["editorElement", { isSignal: true }] }] } });
|
|
6592
7086
|
|
|
7087
|
+
/**
|
|
7088
|
+
* Provides the necessary configuration and initialization for the Angular TipTap Editor.
|
|
7089
|
+
* This should be called in your app.config.ts (for standalone) or main.ts.
|
|
7090
|
+
*
|
|
7091
|
+
* This provider is essential for 'Angular Nodes' to work correctly, as it captures the
|
|
7092
|
+
* root Injector required to instantiate custom Angular components within the editor.
|
|
7093
|
+
* @example
|
|
7094
|
+
* ```ts
|
|
7095
|
+
* bootstrapApplication(AppComponent, {
|
|
7096
|
+
* providers: [
|
|
7097
|
+
* provideAteEditor({
|
|
7098
|
+
* theme: 'dark',
|
|
7099
|
+
* mode: 'seamless'
|
|
7100
|
+
* })
|
|
7101
|
+
* ]
|
|
7102
|
+
* });
|
|
7103
|
+
* ```
|
|
7104
|
+
*/
|
|
7105
|
+
function provideAteEditor(config) {
|
|
7106
|
+
return makeEnvironmentProviders([
|
|
7107
|
+
{
|
|
7108
|
+
provide: ATE_GLOBAL_CONFIG,
|
|
7109
|
+
useValue: config || {},
|
|
7110
|
+
},
|
|
7111
|
+
provideEnvironmentInitializer(() => {
|
|
7112
|
+
const injector = inject(Injector);
|
|
7113
|
+
setGlobalInjector(injector);
|
|
7114
|
+
}),
|
|
7115
|
+
]);
|
|
7116
|
+
}
|
|
7117
|
+
|
|
6593
7118
|
/**
|
|
6594
7119
|
* Clés des boutons de la barre d'outils native
|
|
6595
7120
|
*/
|
|
@@ -6677,7 +7202,7 @@ const ATE_CELL_BUBBLE_MENU_KEYS = ["mergeCells", "splitCell"];
|
|
|
6677
7202
|
/*
|
|
6678
7203
|
* Public API Surface of tiptap-editor
|
|
6679
7204
|
*/
|
|
6680
|
-
// Main component
|
|
7205
|
+
// Main component & Provider
|
|
6681
7206
|
/** @deprecated Renamed to `ATE_INITIAL_EDITOR_STATE`. This alias will be removed in v3.0.0. */
|
|
6682
7207
|
const INITIAL_EDITOR_STATE = ATE_INITIAL_EDITOR_STATE;
|
|
6683
7208
|
/** @deprecated Renamed to `ATE_SLASH_COMMAND_KEYS`. This alias will be removed in v3.0.0. */
|
|
@@ -6711,5 +7236,5 @@ const DEFAULT_CELL_MENU_CONFIG = ATE_DEFAULT_CELL_MENU_CONFIG;
|
|
|
6711
7236
|
* Generated bundle index. Do not edit.
|
|
6712
7237
|
*/
|
|
6713
7238
|
|
|
6714
|
-
export { ATE_BUBBLE_MENU_KEYS, ATE_CELL_BUBBLE_MENU_KEYS, ATE_DEFAULT_BUBBLE_MENU_CONFIG, ATE_DEFAULT_CELL_MENU_CONFIG, ATE_DEFAULT_IMAGE_BUBBLE_MENU_CONFIG, ATE_DEFAULT_SLASH_COMMANDS_CONFIG, ATE_DEFAULT_TABLE_MENU_CONFIG, ATE_DEFAULT_TOOLBAR_CONFIG, ATE_IMAGE_BUBBLE_MENU_KEYS, ATE_INITIAL_EDITOR_STATE, ATE_SLASH_COMMAND_KEYS, ATE_TABLE_BUBBLE_MENU_KEYS, ATE_TOOLBAR_KEYS, AngularTiptapEditorComponent, AteColorPickerService, AteDiscoveryCalculator, AteEditorCommandsService, AteI18nService, AteImageCalculator, AteImageService, AteLinkService, AteMarksCalculator, AteNoopValueAccessorDirective, AteSelectionCalculator, AteStructureCalculator, AteTableCalculator, AteColorPickerService as ColorPickerService, DEFAULT_BUBBLE_MENU_CONFIG, DEFAULT_CELL_MENU_CONFIG, DEFAULT_IMAGE_BUBBLE_MENU_CONFIG, DEFAULT_SLASH_COMMANDS_CONFIG, DEFAULT_TABLE_MENU_CONFIG, DEFAULT_TOOLBAR_CONFIG, DiscoveryCalculator, AteEditorCommandsService as EditorCommandsService, INITIAL_EDITOR_STATE, ImageCalculator, AteImageService as ImageService, AteLinkService as LinkService, MarksCalculator, SLASH_COMMAND_KEYS, SelectionCalculator, StructureCalculator, TableCalculator, AteI18nService as TiptapI18nService, createDefaultSlashCommands, filterSlashCommands };
|
|
7239
|
+
export { ATE_BUBBLE_MENU_KEYS, ATE_CELL_BUBBLE_MENU_KEYS, ATE_DEFAULT_BUBBLE_MENU_CONFIG, ATE_DEFAULT_CELL_MENU_CONFIG, ATE_DEFAULT_IMAGE_BUBBLE_MENU_CONFIG, ATE_DEFAULT_SLASH_COMMANDS_CONFIG, ATE_DEFAULT_TABLE_MENU_CONFIG, ATE_DEFAULT_TOOLBAR_CONFIG, ATE_GLOBAL_CONFIG, ATE_IMAGE_BUBBLE_MENU_KEYS, ATE_INITIAL_EDITOR_STATE, ATE_SLASH_COMMAND_KEYS, ATE_TABLE_BUBBLE_MENU_KEYS, ATE_TOOLBAR_KEYS, AngularTiptapEditorComponent, AteAngularNodeView, AteColorPickerService, AteDiscoveryCalculator, AteEditorCommandsService, AteI18nService, AteImageCalculator, AteImageService, AteLinkService, AteMarksCalculator, AteNodeViewRenderer, AteNoopValueAccessorDirective, AteSelectionCalculator, AteStructureCalculator, AteTableCalculator, AteColorPickerService as ColorPickerService, DEFAULT_BUBBLE_MENU_CONFIG, DEFAULT_CELL_MENU_CONFIG, DEFAULT_IMAGE_BUBBLE_MENU_CONFIG, DEFAULT_SLASH_COMMANDS_CONFIG, DEFAULT_TABLE_MENU_CONFIG, DEFAULT_TOOLBAR_CONFIG, DiscoveryCalculator, AteEditorCommandsService as EditorCommandsService, INITIAL_EDITOR_STATE, ImageCalculator, AteImageService as ImageService, AteLinkService as LinkService, MarksCalculator, SLASH_COMMAND_KEYS, SelectionCalculator, StructureCalculator, TableCalculator, AteI18nService as TiptapI18nService, createAngularComponentExtension, createDefaultSlashCommands, filterSlashCommands, provideAteEditor, registerAngularComponent };
|
|
6715
7240
|
//# sourceMappingURL=flogeez-angular-tiptap-editor.mjs.map
|