UNPKG

ngx-tiptap-editor

Version:

[![Build and Publish](https://github.com/HuiiBuh/ngx-tiptap-editor/actions/workflows/publish.yml/badge.svg)](https://github.com/HuiiBuh/ngx-tiptap-editor/actions/workflows/publish.yml) [![Deploy to Github Pages](https://github.com/HuiiBuh/ngx-tiptap-edito

2,958 lines 174 kB
import * as i2 from '@angular/common';
import { DOCUMENT, isPlatformBrowser, CommonModule } from '@angular/common';
import * as i0 from '@angular/core';
import { EventEmitter, Component, ChangeDetectionStrategy, Input, ViewChild, SecurityContext, Inject, Output, ContentChildren, Directive, isDevMode, ViewChildren, Injectable, forwardRef, InjectionToken, HostBinding, PLATFORM_ID, Optional, ContentChild, NgModule, Injector, ApplicationRef, NgZone, ComponentFactoryResolver } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { __awaiter, __rest } from 'tslib';
import { Observable, pipe, from, Subject, fromEvent, merge } from 'rxjs';
import { concatMap, map, filter, takeUntil, startWith, switchMap, delay, tap } from 'rxjs/operators';
import { trigger, transition, style, animate, query } from '@angular/animations';
import * as i1 from '@angular/platform-browser';
import * as i1$1 from '@tiptap/core';
import { generateHTML, Editor, mergeAttributes } from '@tiptap/core';
import { Mention } from '@tiptap/extension-mention';
import { Link } from '@tiptap/extension-link';

const findExtension = (editor, name) => {
    return editor.extensionManager.extensions.find(e => e.name === name);
};
const getHeadingsExtension = (editor) => {
    return findExtension(editor, 'heading');
};
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
const fromEditorEvent = (editor, event, once = false) => {
    return new Observable((observer) => {
        const callback = (...params) => {
            observer.next(...params);
            if (once)
                editor.off(event, callback);
        };
        editor.on(event, callback);
        return () => {
            editor.off(event, callback);
        };
    });
};
const asyncFilter = (predicate) => {
    let count = 0;
    return pipe(
    // Convert the predicate Promise<boolean> to an observable (which resolves the promise,
    // Then combine the boolean result of the promise with the input data to a container object
    concatMap((data) => {
        return from(predicate(data, count++))
            .pipe(map((isValid) => ({ filterResult: isValid, entry: data })));
    }), 
    // Filter the container object synchronously for the value in each data container object
    filter(data => data.filterResult), 
    // remove the data container object from the observable chain
    map(data => data.entry));
};
const getSelectedTextPosition = () => {
    const selection = document.getSelection();
    if (!selection)
        return null;
    const range = selection.getRangeAt(0);
    return range.getBoundingClientRect();
};
const getLinkFromCursorPosition = (editor) => {
    const link = editor.getAttributes('link');
    return link && link.href ? link.href : null;
};
const getLinkDOMFromCursorPosition = ({ state: { selection: { from } }, view }, link = null) => {
    const dom = view.domAtPos(from);
    let selector = 'a';
    if (link)
        selector = `a[href="${link}"]`;
    return dom.node.parentElement.closest(selector);
};
const getSelectedEditorTextPosition = ({ state, view }) => {
    const { from, to } = state.selection;
    const start = view.coordsAtPos(from);
    const end = view.coordsAtPos(to);
    return {
        start, end,
        topCenter: {
            y: start.top,
            x: start.left + (end.left - start.left) / 2
        }
    };
};
const topCenterOfRect = (rect) => {
    return {
        y: rect.y,
        x: rect.x + rect.width / 2
    };
};
const getDuplicates = (list, getKey) => {
    const hashMap = {};
    for (const item of list) {
        const key = getKey(item);
        if (!(key in hashMap))
            hashMap[key] = [];
        hashMap[key].push(item);
    }
    const duplicates = {};
    for (const hashKey of Object.keys(hashMap)) {
        if (hashMap[hashKey].length > 1)
            duplicates[hashKey] = hashMap[hashKey];
    }
    return Object.keys(duplicates).length > 0 ? duplicates : null;
};
const isObject = (o) => typeof o === 'object' && !Array.isArray(o);
const deepMerge = (target, source) => {
    const targetCopy = Object.assign({}, target);
    for (const key of Object.keys(source)) {
        if (isObject(source[key])) {
            const newTarget = isObject(target[key]) ? target[key] : {};
            targetCopy[key] = deepMerge(newTarget, source[key]);
        }
        else {
            targetCopy[key] = source[key];
        }
    }
    return targetCopy;
};

const FadeInAnimation = trigger('fadeIn', [
    transition(':enter', [
        style({ opacity: 0 }),
        animate('150ms cubic-bezier(.13,1.14,1,.92)', style({ opacity: 1 })),
    ]),
    transition(':leave', [
        animate('150ms cubic-bezier(.13,1.14,1,.92)', style({ opacity: 0 }))
    ])
]);

const ExpandHeight = trigger('expandHeight', [
    transition(':enter', [
        style({ height: '0' }),
        animate('100ms cubic-bezier(.13,1.14,1,.92)', style({ height: '*' })),
    ]),
    transition(':leave', animate('100ms cubic-bezier(.13,1.14,1,.92)', style({ height: '0' })))
]);

class OptionComponent {
    constructor(element) {
        this.element = element;
        this.onSelect = new EventEmitter();
        this.enforceHeight = false;
        this.useHtml = false;
        this._disabled = false;
    }
    set disabled(value) {
        if (this.option && value) {
            this.option.nativeElement.setAttribute('disabled', 'true');
        }
        else {
            this.option && this.option.nativeElement.removeAttribute('disabled');
        }
        this._disabled = false;
    }
    setSelected(value) {
        this.addOrRemoveClass(value, 'active');
    }
    emit($event) {
        $event.preventDefault();
        this.onSelect.emit(this);
    }
    getContent() {
        return this.useHtml ? this.element.nativeElement.innerHTML : this.element.nativeElement.textContent;
    }
    addOrRemoveClass(add, className) {
        const operation = add ? 'add' : 'remove';
        this.option && this.option.nativeElement.classList[operation](className);
    }
}
OptionComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: OptionComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
OptionComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: OptionComponent, selector: "tip-option[value]", inputs: { value: "value", enforceHeight: "enforceHeight", useHtml: "useHtml", disabled: "disabled" }, viewQueries: [{ propertyName: "option", first: true, predicate: ["option"], descendants: true }], ngImport: i0, template: `
    <button type="button" (click)="emit($event)" (keydown.enter)="emit($event)"
            class="select-option select-overflow-wrapper" #option>
      <ng-content></ng-content>
    </button>`, isInline: true, styles: [":host-context(tip-select){display:flex}.select-wrapper{position:relative;display:inline-flex;align-items:center;-webkit-user-select:none;user-select:none;outline-offset:-1}.select-preview{display:inline-flex;overflow:hidden;align-items:center;box-sizing:border-box;width:100%;height:var(--tip-select-preview-height);padding:0 .2rem;cursor:pointer;border:solid 1px var(--tip-border-color);border-radius:calc(var(--tip-border-radius) / 2)}.select-preview:focus{color:var(--tip-active-color)}.select-preview.icon-placeholder{padding-right:var(--tip-select-preview-height)}.select-overflow-wrapper{overflow:hidden;box-sizing:border-box;width:100%;white-space:nowrap;display:flex;align-items:center;text-overflow:ellipsis}.select-options-overlay{position:absolute;box-sizing:border-box;z-index:1;top:0;width:100%;margin-top:4px;border-radius:calc(var(--tip-border-radius) / 2);border:solid 1px var(--tip-border-color);cursor:pointer;transform:translateY(var(--tip-select-preview-height));background-color:var(--tip-background-color);overflow-y:hidden}.select-icon{position:absolute;top:50%;right:0;height:var(--tip-select-preview-height);transform:translateY(-50%);transition:.3s rotate;fill:var(--tip-text-color)}.select-icon.rotate180{transform:rotate(180deg) translateY(50%)}::ng-deep tip-select .select-preview-content{height:var(--tip-select-preview-height)}::ng-deep tip-select .select-preview-content>.select-option{height:var(--tip-select-preview-height)}::ng-deep tip-option:last-child .select-option{border-bottom:none}.select-option{padding:.2rem;transition:color .3s;border-bottom:solid 1px var(--tip-border-color);border-left:none;border-top:none;border-right:none;background-color:transparent;color:var(--tip-text-color)}.select-option[disabled]{color:var(--tip-disabled-color)}.select-option:not([disabled]){cursor:pointer}.select-option:not([disabled]):hover,.select-option:not([disabled]).tip-active,.select-option:not([disabled]):focus{color:var(--tip-active-color)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: OptionComponent, decorators: [{
            type: Component,
            args: [{ selector: 'tip-option[value]', template: `
    <button type="button" (click)="emit($event)" (keydown.enter)="emit($event)"
            class="select-option select-overflow-wrapper" #option>
      <ng-content></ng-content>
    </button>`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host-context(tip-select){display:flex}.select-wrapper{position:relative;display:inline-flex;align-items:center;-webkit-user-select:none;user-select:none;outline-offset:-1}.select-preview{display:inline-flex;overflow:hidden;align-items:center;box-sizing:border-box;width:100%;height:var(--tip-select-preview-height);padding:0 .2rem;cursor:pointer;border:solid 1px var(--tip-border-color);border-radius:calc(var(--tip-border-radius) / 2)}.select-preview:focus{color:var(--tip-active-color)}.select-preview.icon-placeholder{padding-right:var(--tip-select-preview-height)}.select-overflow-wrapper{overflow:hidden;box-sizing:border-box;width:100%;white-space:nowrap;display:flex;align-items:center;text-overflow:ellipsis}.select-options-overlay{position:absolute;box-sizing:border-box;z-index:1;top:0;width:100%;margin-top:4px;border-radius:calc(var(--tip-border-radius) / 2);border:solid 1px var(--tip-border-color);cursor:pointer;transform:translateY(var(--tip-select-preview-height));background-color:var(--tip-background-color);overflow-y:hidden}.select-icon{position:absolute;top:50%;right:0;height:var(--tip-select-preview-height);transform:translateY(-50%);transition:.3s rotate;fill:var(--tip-text-color)}.select-icon.rotate180{transform:rotate(180deg) translateY(50%)}::ng-deep tip-select .select-preview-content{height:var(--tip-select-preview-height)}::ng-deep tip-select .select-preview-content>.select-option{height:var(--tip-select-preview-height)}::ng-deep tip-option:last-child .select-option{border-bottom:none}.select-option{padding:.2rem;transition:color .3s;border-bottom:solid 1px var(--tip-border-color);border-left:none;border-top:none;border-right:none;background-color:transparent;color:var(--tip-text-color)}.select-option[disabled]{color:var(--tip-disabled-color)}.select-option:not([disabled]){cursor:pointer}.select-option:not([disabled]):hover,.select-option:not([disabled]).tip-active,.select-option:not([disabled]):focus{color:var(--tip-active-color)}\n"] }]
        }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { value: [{
                type: Input
            }], enforceHeight: [{
                type: Input
            }], useHtml: [{
                type: Input
            }], option: [{
                type: ViewChild,
                args: ['option']
            }], disabled: [{
                type: Input
            }] } });
// @dynamic
class SelectComponent {
    constructor(cd, element, ngZone, renderer2, sanitizer, document) {
        this.cd = cd;
        this.element = element;
        this.ngZone = ngZone;
        this.renderer2 = renderer2;
        this.sanitizer = sanitizer;
        this.document = document;
        this.width = '150px';
        this.placeholder = '';
        this.defaultValue = '';
        this.showIcon = true;
        this.disablePreviewSanitation = false;
        // tslint:disable-next-line:no-output-native
        this.change = new EventEmitter();
        // Is the dropdown visible
        this.visible = false;
        this.destroy$ = new Subject();
    }
    get value() {
        return this._value;
    }
    set value(value) {
        // Nothing changed
        if (value === this._value)
            return;
        this._value = value;
        this.updateComponent(false);
    }
    ngOnInit() {
        this.ngZone.runOutsideAngular(() => {
            fromEvent(this.document, 'keyup').pipe(filter(e => e.key === 'Escape'), filter(() => this.visible), takeUntil(this.destroy$)).subscribe(() => {
                this.ngZone.run(() => {
                    this.visible = false;
                    this.cd.markForCheck();
                });
            });
            fromEvent(this.document, 'click').pipe(filter(e => !this.element.nativeElement.contains(e.target) && this.visible), filter(e => {
                var _a;
                return (
                // Dont trigger close if the event comes from the own toggle button, or its children
                e.target === ((_a = this.toggleElement) === null || _a === void 0 ? void 0 : _a.nativeElement) ||
                    !!this.selectPreview && !this.selectPreview.nativeElement.contains(e.target));
            }), takeUntil(this.destroy$)).subscribe(() => {
                this.ngZone.run(() => {
                    this.visible = false;
                    this.cd.markForCheck();
                });
            });
        });
    }
    ngAfterViewInit() {
        // Subscribe to click events on the options
        const options = this.optionList;
        this.optionList.changes.pipe(startWith(...options), switchMap(() => merge(...options.map(o => o.onSelect))), takeUntil(this.destroy$)).subscribe(component => {
            // Nothing changed
            if (this._value === component.value)
                return;
            this._value = component.value;
            this.visible = false;
            this.updateComponent(true);
        });
        // Update the selected value for the initial select
        this.updateComponent(false);
    }
    ngOnDestroy() {
        this.destroy$.next();
        this.destroy$.complete();
    }
    toggle() {
        this.visible = !this.visible;
    }
    /**
     * Select the current component depending on the selected value
     * @param emitUpdate Should the change be propagated
     */
    updateComponent(emitUpdate) {
        var _a, _b;
        // No options => no update
        if (!this.optionList)
            return;
        // If no value is provided use the default value
        if (!this.value && this.defaultValue) {
            this._value = this.defaultValue;
        }
        // Deselect all
        this.optionList.forEach(o => o.setSelected(false));
        // Select right one
        const selectedComponent = this.optionList.find(o => o.value === this._value);
        let previewText = this.placeholder;
        // A component is selected, so select the component
        if (selectedComponent) {
            selectedComponent.setSelected(true);
            previewText = selectedComponent.getContent();
            emitUpdate && this.change.emit(selectedComponent.value);
        }
        let sanitizedHtml = previewText;
        if (!this.disablePreviewSanitation) {
            sanitizedHtml = this.sanitizer.sanitize(SecurityContext.HTML, previewText);
        }
        // Dont update if ou don't have to updaet
        if (((_a = this.selectPreview) === null || _a === void 0 ? void 0 : _a.nativeElement.innerHTML) === sanitizedHtml)
            return;
        this.selectPreview && this.renderer2.setProperty((_b = this.selectPreview) === null || _b === void 0 ? void 0 : _b.nativeElement, 'innerHTML', sanitizedHtml);
    }
}
SelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: SelectComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i1.DomSanitizer }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component });
SelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: SelectComponent, selector: "tip-select", inputs: { width: "width", placeholder: "placeholder", defaultValue: "defaultValue", showIcon: "showIcon", disablePreviewSanitation: "disablePreviewSanitation", value: "value" }, outputs: { change: "change" }, queries: [{ propertyName: "optionList", predicate: OptionComponent, descendants: true }], viewQueries: [{ propertyName: "selectPreview", first: true, predicate: ["selectPreview"], descendants: true }, { propertyName: "toggleElement", first: true, predicate: ["toggleElement"], descendants: true }], ngImport: i0, template: "<div [ngStyle]=\"{width: width}\" class=\"select-wrapper\">\n  <div (click)=\"toggle()\" (keydown.enter)=\"toggle()\" [class.icon-placeholder]=\"showIcon\"\n       class=\"select-preview\"\n       tabindex=\"0\" #toggleElement>\n    <div #selectPreview\n         class=\"select-overflow-wrapper select-preview-content\">\n    </div>\n    <i *ngIf=\"showIcon\" [class.rotate180]=\"visible\" class=\"select-icon\">\n      <svg focusable=\"false\" height=\"24px\" viewBox=\"0 0 24 24\" width=\"24px\">\n        <path d=\"M7 10l5 5 5-5z\"/>\n      </svg>\n    </i>\n  </div>\n  <div *ngIf=\"visible\" class=\"select-options-overlay\" @expandHeight>\n    <ng-content></ng-content>\n  </div>\n</div>\n\n", styles: [":host-context(tip-select){display:flex}.select-wrapper{position:relative;display:inline-flex;align-items:center;-webkit-user-select:none;user-select:none;outline-offset:-1}.select-preview{display:inline-flex;overflow:hidden;align-items:center;box-sizing:border-box;width:100%;height:var(--tip-select-preview-height);padding:0 .2rem;cursor:pointer;border:solid 1px var(--tip-border-color);border-radius:calc(var(--tip-border-radius) / 2)}.select-preview:focus{color:var(--tip-active-color)}.select-preview.icon-placeholder{padding-right:var(--tip-select-preview-height)}.select-overflow-wrapper{overflow:hidden;box-sizing:border-box;width:100%;white-space:nowrap;display:flex;align-items:center;text-overflow:ellipsis}.select-options-overlay{position:absolute;box-sizing:border-box;z-index:1;top:0;width:100%;margin-top:4px;border-radius:calc(var(--tip-border-radius) / 2);border:solid 1px var(--tip-border-color);cursor:pointer;transform:translateY(var(--tip-select-preview-height));background-color:var(--tip-background-color);overflow-y:hidden}.select-icon{position:absolute;top:50%;right:0;height:var(--tip-select-preview-height);transform:translateY(-50%);transition:.3s rotate;fill:var(--tip-text-color)}.select-icon.rotate180{transform:rotate(180deg) translateY(50%)}::ng-deep tip-select .select-preview-content{height:var(--tip-select-preview-height)}::ng-deep tip-select .select-preview-content>.select-option{height:var(--tip-select-preview-height)}::ng-deep tip-option:last-child .select-option{border-bottom:none}.select-option{padding:.2rem;transition:color .3s;border-bottom:solid 1px var(--tip-border-color);border-left:none;border-top:none;border-right:none;background-color:transparent;color:var(--tip-text-color)}.select-option[disabled]{color:var(--tip-disabled-color)}.select-option:not([disabled]){cursor:pointer}.select-option:not([disabled]):hover,.select-option:not([disabled]).tip-active,.select-option:not([disabled]):focus{color:var(--tip-active-color)}\n"], directives: [{ type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], animations: [FadeInAnimation, ExpandHeight], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: SelectComponent, decorators: [{
            type: Component,
            args: [{ selector: 'tip-select', animations: [FadeInAnimation, ExpandHeight], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngStyle]=\"{width: width}\" class=\"select-wrapper\">\n  <div (click)=\"toggle()\" (keydown.enter)=\"toggle()\" [class.icon-placeholder]=\"showIcon\"\n       class=\"select-preview\"\n       tabindex=\"0\" #toggleElement>\n    <div #selectPreview\n         class=\"select-overflow-wrapper select-preview-content\">\n    </div>\n    <i *ngIf=\"showIcon\" [class.rotate180]=\"visible\" class=\"select-icon\">\n      <svg focusable=\"false\" height=\"24px\" viewBox=\"0 0 24 24\" width=\"24px\">\n        <path d=\"M7 10l5 5 5-5z\"/>\n      </svg>\n    </i>\n  </div>\n  <div *ngIf=\"visible\" class=\"select-options-overlay\" @expandHeight>\n    <ng-content></ng-content>\n  </div>\n</div>\n\n", styles: [":host-context(tip-select){display:flex}.select-wrapper{position:relative;display:inline-flex;align-items:center;-webkit-user-select:none;user-select:none;outline-offset:-1}.select-preview{display:inline-flex;overflow:hidden;align-items:center;box-sizing:border-box;width:100%;height:var(--tip-select-preview-height);padding:0 .2rem;cursor:pointer;border:solid 1px var(--tip-border-color);border-radius:calc(var(--tip-border-radius) / 2)}.select-preview:focus{color:var(--tip-active-color)}.select-preview.icon-placeholder{padding-right:var(--tip-select-preview-height)}.select-overflow-wrapper{overflow:hidden;box-sizing:border-box;width:100%;white-space:nowrap;display:flex;align-items:center;text-overflow:ellipsis}.select-options-overlay{position:absolute;box-sizing:border-box;z-index:1;top:0;width:100%;margin-top:4px;border-radius:calc(var(--tip-border-radius) / 2);border:solid 1px var(--tip-border-color);cursor:pointer;transform:translateY(var(--tip-select-preview-height));background-color:var(--tip-background-color);overflow-y:hidden}.select-icon{position:absolute;top:50%;right:0;height:var(--tip-select-preview-height);transform:translateY(-50%);transition:.3s rotate;fill:var(--tip-text-color)}.select-icon.rotate180{transform:rotate(180deg) translateY(50%)}::ng-deep tip-select .select-preview-content{height:var(--tip-select-preview-height)}::ng-deep tip-select .select-preview-content>.select-option{height:var(--tip-select-preview-height)}::ng-deep tip-option:last-child .select-option{border-bottom:none}.select-option{padding:.2rem;transition:color .3s;border-bottom:solid 1px var(--tip-border-color);border-left:none;border-top:none;border-right:none;background-color:transparent;color:var(--tip-text-color)}.select-option[disabled]{color:var(--tip-disabled-color)}.select-option:not([disabled]){cursor:pointer}.select-option:not([disabled]):hover,.select-option:not([disabled]).tip-active,.select-option:not([disabled]):focus{color:var(--tip-active-color)}\n"] }]
        }], ctorParameters: function () {
        return [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i1.DomSanitizer }, { type: Document, decorators: [{
                        type: Inject,
                        args: [DOCUMENT]
                    }] }];
    }, propDecorators: { width: [{
                type: Input
            }], placeholder: [{
                type: Input
            }], defaultValue: [{
                type: Input
            }], showIcon: [{
                type: Input
            }], disablePreviewSanitation: [{
                type: Input
            }], change: [{
                type: Output
            }], optionList: [{
                type: ContentChildren,
                args: [OptionComponent, { descendants: true }]
            }], selectPreview: [{
                type: ViewChild,
                args: ['selectPreview']
            }], toggleElement: [{
                type: ViewChild,
                args: ['toggleElement']
            }], value: [{
                type: Input
            }] } });

class BaseControl {
    constructor() {
        this._editor = null;
    }
    get editor() {
        return this._editor;
    }
    setEditor(editor) {
        this._editor = editor;
        this.onEditorReady && this.onEditorReady(editor);
    }
}
// tslint:disable-next-line:directive-class-suffix
class ExtendedBaseControl extends BaseControl {
    constructor() {
        super(...arguments);
        this.destroy$ = new Subject();
    }
    ngOnDestroy() {
        this.destroy$.next(true);
        this.destroy$.complete();
    }
    setEditor(editor) {
        super.setEditor(editor);
        fromEditorEvent(editor, 'destroy', true).pipe(takeUntil(this.destroy$))
            .subscribe(() => this.onEditorDestroy && this.onEditorDestroy());
    }
    isEditable() {
        var _a;
        return !!((_a = this.editor) === null || _a === void 0 ? void 0 : _a.isEditable);
    }
}
ExtendedBaseControl.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ExtendedBaseControl, deps: null, target: i0.ɵɵFactoryTarget.Directive });
ExtendedBaseControl.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.1.1", type: ExtendedBaseControl, usesInheritance: true, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ExtendedBaseControl, decorators: [{
            type: Directive
        }] });
// tslint:disable-next-line:directive-class-suffix
class ButtonBaseControl extends ExtendedBaseControl {
    constructor() {
        super(...arguments);
        this.updateEvent = 'transaction';
    }
    ngAfterViewInit() {
        if (!this.button && isDevMode()) {
            console.warn(`The button element in your control could not be found in ${this.constructor.name}\nPlease add #button to your control button element`);
        }
    }
    setEditor(editor) {
        super.setEditor(editor);
        fromEditorEvent(editor, this.updateEvent).pipe(takeUntil(this.destroy$))
            .subscribe(() => this.updateButton());
        this.updateButton();
    }
    updateButton() {
        return __awaiter(this, void 0, void 0, function* () {
            if (!this.button)
                return;
            const activeAction = (yield this.isActive()) ? 'add' : 'remove';
            this.button.nativeElement.classList[activeAction]('tip-active');
            if ((yield this.can()) && this.isEditable()) {
                this.button.nativeElement.removeAttribute('disabled');
            }
            else {
                this.button.nativeElement.setAttribute('disabled', 'true');
            }
        });
    }
}
ButtonBaseControl.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ButtonBaseControl, deps: null, target: i0.ɵɵFactoryTarget.Directive });
ButtonBaseControl.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.1.1", type: ButtonBaseControl, viewQueries: [{ propertyName: "button", first: true, predicate: ["button"], descendants: true }], usesInheritance: true, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ButtonBaseControl, decorators: [{
            type: Directive
        }], propDecorators: { button: [{
                type: ViewChild,
                args: ['button']
            }] } });
// tslint:disable-next-line:directive-class-suffix
class SelectBaseControl extends ExtendedBaseControl {
    ngOnInit() {
        this.eventService.update$.pipe(takeUntil(this.destroy$)).subscribe(() => {
            this.updateSelectValue();
            this.updateDisabledValue();
        });
    }
    ngAfterViewInit() {
        if (!isDevMode() && !this.select) {
            console.warn(`The select element in your control could not be found in ${this.constructor.name}\nPlease make sure you have a tip-select in your component`);
        }
    }
    setEditor(editor) {
        super.setEditor(editor);
        this.updateSelectValue();
        this.updateDisabledValue();
    }
    updateSelectValue() {
        return __awaiter(this, void 0, void 0, function* () {
            this.select.value = yield this.currentActive();
        });
    }
    updateDisabledValue() {
        return __awaiter(this, void 0, void 0, function* () {
            const optionsList = this.options.toArray();
            for (const [index, param] of this.canStyleParams.entries()) {
                const option = optionsList[index];
                if (!option)
                    continue;
                option.disabled = !((yield this.canStyle(param)) && this.isEditable());
            }
        });
    }
}
SelectBaseControl.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: SelectBaseControl, deps: null, target: i0.ɵɵFactoryTarget.Directive });
SelectBaseControl.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.1.1", type: SelectBaseControl, viewQueries: [{ propertyName: "select", first: true, predicate: SelectComponent, descendants: true }, { propertyName: "options", predicate: OptionComponent, descendants: true }], usesInheritance: true, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: SelectBaseControl, decorators: [{
            type: Directive
        }], propDecorators: { select: [{
                type: ViewChild,
                args: [SelectComponent]
            }], options: [{
                type: ViewChildren,
                args: [OptionComponent]
            }] } });

class TiptapEventService {
    /* tslint:enable */
    constructor(ngZone) {
        this.ngZone = ngZone;
        this.clickSubject = new Subject();
        this.keyboardSubject = new Subject();
        this.clickSubscription = null;
        this.keyboardSubscription = null;
        /* tslint:disable */
        this.update$ = merge(this.clickSubject, this.keyboardSubject);
        this.onClick$ = this.clickSubject.asObservable();
        this.onKeyboard$ = this.keyboardSubject.asObservable();
    }
    registerShortcut(shortcut) {
        const parts = shortcut.split('-');
        let key = parts[parts.length - 1];
        if (key === 'Space')
            key = ' ';
        const keyCodeSmall = key.toUpperCase().charCodeAt(0);
        const keyCodeLarge = key.toLowerCase().charCodeAt(0);
        const hasAlt = parts.includes('Alt');
        const hasShift = parts.includes('Shift');
        const hasMod = parts.includes('Mod');
        const hasCtrl = parts.includes('Ctrl');
        const hasCmd = parts.includes('Cmd');
        return this.onKeyboard$.pipe(filter(e => (
        // Check the keycode against the large and small letter (I hate you apple)
        (e.keyCode === keyCodeSmall || e.keyCode === keyCodeLarge) &&
            e.altKey === hasAlt &&
            e.shiftKey === hasShift &&
            // Check if the meta key was pressed, or the combined mod is allowed  (I really, really, hate you apple)
            (
            // Both ctrl and command key
            hasMod && (e.ctrlKey && !e.metaKey || !e.ctrlKey && e.metaKey)
                // Only ctrl or command key
                || e.ctrlKey === hasCtrl && e.metaKey === hasCmd && !hasMod))));
    }
    setElement(element) {
        this.ngZone.runOutsideAngular(() => {
            var _a, _b;
            (_a = this.clickSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
            (_b = this.keyboardSubscription) === null || _b === void 0 ? void 0 : _b.unsubscribe();
            this.clickSubscription = fromEvent(element, 'click').subscribe(e => this.clickSubject.next(e));
            this.keyboardSubscription = fromEvent(element, 'keydown').subscribe(e => this.keyboardSubject.next(e));
        });
    }
}
TiptapEventService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: TiptapEventService, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
TiptapEventService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: TiptapEventService, providedIn: 'root' });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: TiptapEventService, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root'
                }]
        }], ctorParameters: function () { return [{ type: i0.NgZone }]; } });

class ControlBoldComponent extends ButtonBaseControl {
    constructor(eventService) {
        super();
        this.eventService = eventService;
    }
    toggleBold() {
        this.editor && this.editor.chain().focus().toggleBold().run();
    }
    isActive() {
        var _a;
        return !!((_a = this.editor) === null || _a === void 0 ? void 0 : _a.isActive('bold'));
    }
    can() {
        var _a;
        return !!((_a = this.editor) === null || _a === void 0 ? void 0 : _a.can().toggleBold());
    }
}
ControlBoldComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ControlBoldComponent, deps: [{ token: TiptapEventService }], target: i0.ɵɵFactoryTarget.Component });
ControlBoldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: ControlBoldComponent, selector: "tip-control-bold", providers: [{ provide: BaseControl, useExisting: forwardRef(() => ControlBoldComponent) }], usesInheritance: true, ngImport: i0, template: `
    <button class="tip-control-button" type="button" (click)="toggleBold()" #button>
      <div class="content-wrapper" #ref>
        <ng-content></ng-content>
      </div>
      <i *ngIf="ref.childNodes.length === 0" class="material-icons">format_bold</i>
    </button>
  `, isInline: true, styles: [":host-context{display:contents}.tip-control-button{display:inline-flex;align-items:center;justify-content:center;padding:1px calc(var(--tip-header-padding) / 2);cursor:pointer;color:var(--tip-text-color);border:none;background-color:transparent;-webkit-tap-highlight-color:transparent}@media (pointer: fine){.tip-control-button:hover,.tip-control-button:focus{color:var(--tip-active-color)}}.tip-control-button[disabled]{cursor:default;color:var(--tip-disabled-color)}.content-wrapper{display:contents}.tip-active{color:var(--tip-active-color)}\n"], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ControlBoldComponent, decorators: [{
            type: Component,
            args: [{ selector: 'tip-control-bold', template: `
    <button class="tip-control-button" type="button" (click)="toggleBold()" #button>
      <div class="content-wrapper" #ref>
        <ng-content></ng-content>
      </div>
      <i *ngIf="ref.childNodes.length === 0" class="material-icons">format_bold</i>
    </button>
  `, changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: BaseControl, useExisting: forwardRef(() => ControlBoldComponent) }], styles: [":host-context{display:contents}.tip-control-button{display:inline-flex;align-items:center;justify-content:center;padding:1px calc(var(--tip-header-padding) / 2);cursor:pointer;color:var(--tip-text-color);border:none;background-color:transparent;-webkit-tap-highlight-color:transparent}@media (pointer: fine){.tip-control-button:hover,.tip-control-button:focus{color:var(--tip-active-color)}}.tip-control-button[disabled]{cursor:default;color:var(--tip-disabled-color)}.content-wrapper{display:contents}.tip-active{color:var(--tip-active-color)}\n"] }]
        }], ctorParameters: function () { return [{ type: TiptapEventService }]; } });

class ControlBulletListComponent extends ButtonBaseControl {
    constructor(eventService) {
        super();
        this.eventService = eventService;
    }
    toggleList() {
        this.editor && this.editor.chain().focus().toggleBulletList().run();
    }
    can() {
        var _a, _b;
        return !!((_b = (_a = this.editor) === null || _a === void 0 ? void 0 : _a.can()) === null || _b === void 0 ? void 0 : _b.toggleBulletList());
    }
    isActive(...args) {
        var _a;
        return !!((_a = this.editor) === null || _a === void 0 ? void 0 : _a.isActive('bulletList'));
    }
}
ControlBulletListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ControlBulletListComponent, deps: [{ token: TiptapEventService }], target: i0.ɵɵFactoryTarget.Component });
ControlBulletListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: ControlBulletListComponent, selector: "tip-bullet-list-control", providers: [{ provide: BaseControl, useExisting: forwardRef(() => ControlBulletListComponent) }], usesInheritance: true, ngImport: i0, template: `
    <button class="tip-control-button" type="button" (click)="toggleList()" #button>
      <div class="content-wrapper" #ref>
        <ng-content></ng-content>
      </div>
      <i *ngIf="ref.childNodes.length === 0" class="material-icons">format_list_bulleted</i>
    </button>`, isInline: true, styles: [":host-context{display:contents}.tip-control-button{display:inline-flex;align-items:center;justify-content:center;padding:1px calc(var(--tip-header-padding) / 2);cursor:pointer;color:var(--tip-text-color);border:none;background-color:transparent;-webkit-tap-highlight-color:transparent}@media (pointer: fine){.tip-control-button:hover,.tip-control-button:focus{color:var(--tip-active-color)}}.tip-control-button[disabled]{cursor:default;color:var(--tip-disabled-color)}.content-wrapper{display:contents}.tip-active{color:var(--tip-active-color)}\n"], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ControlBulletListComponent, decorators: [{
            type: Component,
            args: [{ selector: '' +
                        'tip-bullet-list-control', template: `
    <button class="tip-control-button" type="button" (click)="toggleList()" #button>
      <div class="content-wrapper" #ref>
        <ng-content></ng-content>
      </div>
      <i *ngIf="ref.childNodes.length === 0" class="material-icons">format_list_bulleted</i>
    </button>`, changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: BaseControl, useExisting: forwardRef(() => ControlBulletListComponent) }], styles: [":host-context{display:contents}.tip-control-button{display:inline-flex;align-items:center;justify-content:center;padding:1px calc(var(--tip-header-padding) / 2);cursor:pointer;color:var(--tip-text-color);border:none;background-color:transparent;-webkit-tap-highlight-color:transparent}@media (pointer: fine){.tip-control-button:hover,.tip-control-button:focus{color:var(--tip-active-color)}}.tip-control-button[disabled]{cursor:default;color:var(--tip-disabled-color)}.content-wrapper{display:contents}.tip-active{color:var(--tip-active-color)}\n"] }]
        }], ctorParameters: function () { return [{ type: TiptapEventService }]; } });

class ControlCodeBlockComponent extends ButtonBaseControl {
    constructor(eventService) {
        super();
        this.eventService = eventService;
    }
    toggleCodeBlock() {
        this.editor && this.editor.chain().focus().toggleCodeBlock().run();
    }
    can() {
        var _a;
        return !!((_a = this.editor) === null || _a === void 0 ? void 0 : _a.can().toggleCodeBlock());
    }
    isActive(...args) {
        var _a;
        return !!((_a = this.editor) === null || _a === void 0 ? void 0 : _a.isActive('codeBlock'));
    }
}
ControlCodeBlockComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ControlCodeBlockComponent, deps: [{ token: TiptapEventService }], target: i0.ɵɵFactoryTarget.Component });
ControlCodeBlockComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: ControlCodeBlockComponent, selector: "tip-code-block-control", providers: [{ provide: BaseControl, useExisting: forwardRef(() => ControlCodeBlockComponent) }], usesInheritance: true, ngImport: i0, template: `
    <button class="tip-control-button" type="button" (click)="toggleCodeBlock()" #button>
      <div class="content-wrapper" #ref>
        <ng-content></ng-content>
      </div>
      <i *ngIf="ref.childNodes.length === 0" class="material-icons">integration_instructions</i>
    </button>`, isInline: true, styles: [":host-context{display:contents}.tip-control-button{display:inline-flex;align-items:center;justify-content:center;padding:1px calc(var(--tip-header-padding) / 2);cursor:pointer;color:var(--tip-text-color);border:none;background-color:transparent;-webkit-tap-highlight-color:transparent}@media (pointer: fine){.tip-control-button:hover,.tip-control-button:focus{color:var(--tip-active-color)}}.tip-control-button[disabled]{cursor:default;color:var(--tip-disabled-color)}.content-wrapper{display:contents}.tip-active{color:var(--tip-active-color)}\n"], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ControlCodeBlockComponent, decorators: [{
            type: Component,
            args: [{ selector: 'tip-code-block-control', template: `
    <button class="tip-control-button" type="button" (click)="toggleCodeBlock()" #button>
      <div class="content-wrapper" #ref>
        <ng-content></ng-content>
      </div>
      <i *ngIf="ref.childNodes.length === 0" class="material-icons">integration_instructions</i>
    </button>`, changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: BaseControl, useExisting: forwardRef(() => ControlCodeBlockComponent) }], styles: [":host-context{display:contents}.tip-control-button{display:inline-flex;align-items:center;justify-content:center;padding:1px calc(var(--tip-header-padding) / 2);cursor:pointer;color:var(--tip-text-color);border:none;background-color:transparent;-webkit-tap-highlight-color:transparent}@media (pointer: fine){.tip-control-button:hover,.tip-control-button:focus{color:var(--tip-active-color)}}.tip-control-button[disabled]{cursor:default;color:var(--tip-disabled-color)}.content-wrapper{display:contents}.tip-active{color:var(--tip-active-color)}\n"] }]
        }], ctorParameters: function () { return [{ type: TiptapEventService }]; } });

class ControlCodeComponent extends ButtonBaseControl {
    constructor(eventService) {
        super();
        this.eventService = eventService;
    }
    toggleCode() {
        this.editor && this.editor.chain().focus().toggleCode().run();
    }
    can() {
        var _a;
        return !!((_a = this.editor) === null || _a === void 0 ? void 0 : _a.can().toggleCode());
    }
    isActive(...args) {
        var _a;
        return !!((_a = this.editor) === null || _a === void 0 ? void 0 : _a.isActive('code'));
    }
}
ControlCodeComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ControlCodeComponent, deps: [{ token: TiptapEventService }], target: i0.ɵɵFactoryTarget.Component });
ControlCodeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: ControlCodeComponent, selector: "tip-control-code", providers: [{ provide: BaseControl, useExisting: forwardRef(() => ControlCodeComponent) }], usesInheritance: true, ngImport: i0, template: `
    <button class="tip-control-button" type="button" (click)="toggleCode()" #button>
      <div class="content-wrapper" #ref>
        <ng-content></ng-content>
      </div>
      <i *ngIf="ref.childNodes.length === 0" class="material-icons">code</i>
    </button>`, isInline: true, styles: [":host-context{display:contents}.tip-control-button{display:inline-flex;align-items:center;justify-content:center;padding:1px calc(var(--tip-header-padding) / 2);cursor:pointer;color:var(--tip-text-color);border:none;background-color:transparent;-webkit-tap-highlight-color:transparent}@media (pointer: fine){.tip-control-button:hover,.tip-control-button:focus{color:var(--tip-active-color)}}.tip-control-button[disabled]{cursor:default;color:var(--tip-disabled-color)}.content-wrapper{display:contents}.tip-active{color:var(--tip-active-color)}\n"], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ControlCodeComponent, decorators: [{
            type: Component,
            args: [{ selector: 'tip-control-code', template: `
    <button class="tip-control-button" type="button" (click)="toggleCode()" #button>
      <div class="content-wrapper" #ref>
        <ng-content></ng-content>
      </div>
      <i *ngIf="ref.childNodes.length === 0" class="material-icons">code</i>
    </button>`, changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: BaseControl, useExisting: forwardRef(() => ControlCodeComponent) }], styles: [":host-context{display:contents}.tip-control-button{display:inline-flex;align-items:center;justify-content:center;padding:1px calc(var(--tip-header-padding) / 2);cursor:pointer;color:var(--tip-text-color);border:none;background-color:transparent;-webkit-tap-highlight-color:transparent}@media (pointer: fine){.tip-control-button:hover,.tip-control-button:focus{color:var(--tip-active-color)}}.tip-control-button[disabled]{cursor:default;color:var(--tip-disabled-color)}.content-wrapper{display:contents}.tip-active{color:var(--tip-active-color)}\n"] }]
        }], ctorParameters: function () { return [{ type: TiptapEventService }]; } });

const isHeading = (level) => typeof level === 'number';
class ControlFormatComponent extends SelectBaseControl {
    constructor(eventService, cd) {
        super();
        this.eventService = eventService;
        this.cd = cd;
        this.disableSanitation = false;
        this.levels = [];
        this.headingHtml = {};
        this.canStyleParams = [];
    }
    setEditor(editor) {
        super.setEditor(editor);
        this.levels = getHeadingsExtension(editor).options.levels;
        this.canStyleParams = [...this.levels, 'paragraph'];
        this.headingHtml = [...this.levels].reduce((previousValue, currentValue) => {
            previousValue[currentValue] = `<h${currentValue} class="no-margin light-font">Heading ${currentValue}</h${currentValue}>`;
            return previousValue;
        }, {});
        this.cd.detectChanges();
    }
    selectTextLevel(format) {
        if (isHeading(format)) {
            this.setHeading(format);
        }
        else {
            this.setParagraph();
        }
    }
    canStyle(format) {
        if (!this.editor)
            return false;
        if (isHeading(format)) {
            return this.editor.can().chain().setHeading({ level: format }).run();
        }
        else {
            return this.editor.can().chain().setParagraph().run();
        }
    }
    currentActive() {
        if (this.editor) {
            const headingAttributes = this.editor.getAttributes('heading');
            if (headingAttributes.level)
                return headingAttributes.level;
            if (this.editor.isActive('paragraph'))
                return 'paragraph';
        }
        return null;
    }
    setParagraph() {
        this.editor && this.editor.chain().setParagraph().run();
    }
    setHeading(headingLevel) {
        this.editor && this.editor.chain().focus().setHeading({ level: headingLevel }).focus().run();
    }
}
ControlFormatComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ControlFormatComponent, deps: [{ token: TiptapEventService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
ControlFormatComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: ControlFormatComponent, selector: "tip-format-control", inputs: { disableSanitation: "disableSanitation" }, providers: [{ provide: BaseControl, useExisting: forwardRef(() => ControlFormatComponent) }], usesInheritance: true, ngImport: i0, template: `
    <tip-select (change)="selectTextLevel($event)" defaultValue="paragraph"
                [disablePreviewSanitation]="disableSanitation">
      <tip-option *ngFor="let level of levels" [value]="level">
        <div [innerHTML]="headingHtml[level]"></div>
      </tip-option>
      <tip-option value="paragraph">
        <div>
          <p class="no-margin light-font">Paragraph</p>
        </div>
      </tip-option>
    </tip-select>
  `, isInline: true, styles: [":host-context{display:contents}.tip-control-button{display:inline-flex;align-items:center;justify-content:center;padding:1px calc(var(--tip-header-padding) / 2);cursor:pointer;color:var(--tip-text-color);border:none;background-color:transparent;-webkit-tap-highlight-color:transparent}@media (pointer: fine){.tip-control-button:hover,.tip-control-button:focus{color:var(--tip-active-color)}}.tip-control-button[disabled]{cursor:default;color:var(--tip-disabled-color)}.content-wrapper{display:contents}.tip-active{color:var(--tip-active-color)}\n"], components: [{ type: SelectComponent, selector: "tip-select", inputs: ["width", "placeholder", "defaultValue", "showIcon", "disablePreviewSanitation", "value"], outputs: ["change"] }, { type: OptionComponent, selector: "tip-option[value]", inputs: ["value", "enforceHeight", "useHtml", "disabled"] }], directives: [{ type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ControlFormatComponent, decorators: [{
            type: Component,
            args: [{ selector: 'tip-format-control', template: `
    <tip-select (change)="selectTextLevel($event)" defaultValue="paragraph"
                [disablePreviewSanitation]="disableSanitation">
      <tip-option *ngFor="let level of levels" [value]="level">
        <div [innerHTML]="headingHtml[level]"></div>
      </tip-option>
      <tip-option value="paragraph">
        <div>
          <p class="no-margin light-font">Paragraph</p>
        </div>
      </tip-option>
    </tip-select>
  `, changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: BaseControl, useExisting: forwardRef(() => ControlFormatComponent) }], styles: [":host-context{display:contents}.tip-control-button{display:inline-flex;align-items:center;justify-content:center;padding:1px calc(var(--tip-header-padding) / 2);cursor:pointer;color:var(--tip-text-color);border:none;background-color:transparent;-webkit-tap-highlight-color:transparent}@media (pointer: fine){.tip-control-button:hover,.tip-control-button:focus{color:var(--tip-active-color)}}.tip-control-button[disabled]{cursor:default;color:var(--tip-disabled-color)}.content-wrapper{display:contents}.tip-active{color:var(--tip-active-color)}\n"] }]
        }], ctorParameters: function () { return [{ type: TiptapEventService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { disableSanitation: [{
                type: Input
            }] } });

class HorizontalRuleControlComponent extends ButtonBaseControl {
    constructor(eventService) {
        super();
        this.eventService = eventService;
    }
    addHorizontalRule() {
        this.editor && this.editor.chain().focus().setHorizontalRule().run();
    }
    can() {
        var _a;
        return !!((_a = this.editor) === null || _a === void 0 ? void 0 : _a.can().setHorizontalRule());
    }
    isActive(...args) {
        return false;
    }
}
HorizontalRuleControlComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: HorizontalRuleControlComponent, deps: [{ token: TiptapEventService }], target: i0.ɵɵFactoryTarget.Component });
HorizontalRuleControlComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: HorizontalRuleControlComponent, selector: "tip-control-hr", providers: [{ provide: BaseControl, useExisting: forwardRef(() => HorizontalRuleControlComponent) }], usesInheritance: true, ngImport: i0, template: `
    <button class="tip-control-button" type="button" (click)="addHorizontalRule()" #button>
      <div class="content-wrapper" #ref>
        <ng-content></ng-content>
      </div>
      <i *ngIf="ref.childNodes.length === 0" class="material-icons">horizontal_rule</i>
    </button>`, isInline: true, styles: [":host-context{display:contents}.tip-control-button{display:inline-flex;align-items:center;justify-content:center;padding:1px calc(var(--tip-header-padding) / 2);cursor:pointer;color:var(--tip-text-color);border:none;background-color:transparent;-webkit-tap-highlight-color:transparent}@media (pointer: fine){.tip-control-button:hover,.tip-control-button:focus{color:var(--tip-active-color)}}.tip-control-button[disabled]{cursor:default;color:var(--tip-disabled-color)}.content-wrapper{display:contents}.tip-active{color:var(--tip-active-color)}\n"], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: HorizontalRuleControlComponent, decorators: [{
            type: Component,
            args: [{ selector: 'tip-control-hr', template: `
    <button class="tip-control-button" type="button" (click)="addHorizontalRule()" #button>
      <div class="content-wrapper" #ref>
        <ng-content></ng-content>
      </div>
      <i *ngIf="ref.childNodes.length === 0" class="material-icons">horizontal_rule</i>
    </button>`, changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: BaseControl, useExisting: forwardRef(() => HorizontalRuleControlComponent) }], styles: [":host-context{display:contents}.tip-control-button{display:inline-flex;align-items:center;justify-content:center;padding:1px calc(var(--tip-header-padding) / 2);cursor:pointer;color:var(--tip-text-color);border:none;background-color:transparent;-webkit-tap-highlight-color:transparent}@media (pointer: fine){.tip-control-button:hover,.tip-control-button:focus{color:var(--tip-active-color)}}.tip-control-button[disabled]{cursor:default;color:var(--tip-disabled-color)}.content-wrapper{display:contents}.tip-active{color:var(--tip-active-color)}\n"] }]
        }], ctorParameters: function () { return [{ type: TiptapEventService }]; } });

class ControlItalicComponent extends ButtonBaseControl {
    constructor(eventService) {
        super();
        this.eventService = eventService;
    }
    toggleItalic() {
        this.editor && this.editor.chain().focus().toggleItalic().run();
    }
    isActive() {
        var _a;
        return !!((_a = this.editor) === null || _a === void 0 ? void 0 : _a.isActive('italic'));
    }
    can() {
        var _a;
        return !!((_a = this.editor) === null || _a === void 0 ? void 0 : _a.can().toggleItalic());
    }
}
ControlItalicComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ControlItalicComponent, deps: [{ token: TiptapEventService }], target: i0.ɵɵFactoryTarget.Component });
ControlItalicComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: ControlItalicComponent, selector: "tip-control-italic", providers: [{ provide: BaseControl, useExisting: forwardRef(() => ControlItalicComponent) }], usesInheritance: true, ngImport: i0, template: `
    <button class="tip-control-button" type="button" (click)="toggleItalic()" #button>
      <div class="content-wrapper" #ref>
        <ng-content></ng-content>
      </div>
      <i *ngIf="ref.childNodes.length === 0" class="material-icons">format_italic</i>
    </button>`, isInline: true, styles: [":host-context{display:contents}.tip-control-button{display:inline-flex;align-items:center;justify-content:center;padding:1px calc(var(--tip-header-padding) / 2);cursor:pointer;color:var(--tip-text-color);border:none;background-color:transparent;-webkit-tap-highlight-color:transparent}@media (pointer: fine){.tip-control-button:hover,.tip-control-button:focus{color:var(--tip-active-color)}}.tip-control-button[disabled]{cursor:default;color:var(--tip-disabled-color)}.content-wrapper{display:contents}.tip-active{color:var(--tip-active-color)}\n"], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ControlItalicComponent, decorators: [{
            type: Component,
            args: [{ selector: 'tip-control-italic', template: `
    <button class="tip-control-button" type="button" (click)="toggleItalic()" #button>
      <div class="content-wrapper" #ref>
        <ng-content></ng-content>
      </div>
      <i *ngIf="ref.childNodes.length === 0" class="material-icons">format_italic</i>
    </button>`, changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: BaseControl, useExisting: forwardRef(() => ControlItalicComponent) }], styles: [":host-context{display:contents}.tip-control-button{display:inline-flex;align-items:center;justify-content:center;padding:1px calc(var(--tip-header-padding) / 2);cursor:pointer;color:var(--tip-text-color);border:none;background-color:transparent;-webkit-tap-highlight-color:transparent}@media (pointer: fine){.tip-control-button:hover,.tip-control-button:focus{color:var(--tip-active-color)}}.tip-control-button[disabled]{cursor:default;color:var(--tip-disabled-color)}.content-wrapper{display:contents}.tip-active{color:var(--tip-active-color)}\n"] }]
        }], ctorParameters: function () { return [{ type: TiptapEventService }]; } });

class TiptapExtensionService {
    constructor() {
        this._nativeExtensions = {};
        this._angularExtensions = {};
    }
    get angularExtensions() {
        return this._angularExtensions;
    }
    setAngularExtensions(value) {
        this._angularExtensions = value.reduce((previousValue, currentValue) => {
            previousValue[currentValue.nativeExtension.name] = currentValue;
            return previousValue;
        }, {});
    }
    get nativeExtensions() {
        return this._nativeExtensions;
    }
    setNativeExtensions(value) {
        this._nativeExtensions = value.reduce((previousValue, currentValue) => {
            previousValue[currentValue.name] = currentValue;
            return previousValue;
        }, {});
    }
    getExtension(extensionName) {
        if (extensionName in this._angularExtensions) {
            return this._angularExtensions[extensionName];
        }
        if (extensionName in this._nativeExtensions) {
            return this._nativeExtensions[extensionName];
        }
        return null;
    }
}
TiptapExtensionService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: TiptapExtensionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
TiptapExtensionService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: TiptapExtensionService, providedIn: 'root' });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: TiptapExtensionService, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root'
                }]
        }] });

// @dynamic
class ControlLinkComponent extends ButtonBaseControl {
    constructor(eventService, extensionService) {
        super();
        this.eventService = eventService;
        this.extensionService = extensionService;
        this.updateEvent = 'selectionUpdate';
    }
    onEditorReady(editor) {
        this.linkExtension = this.extensionService.getExtension('link');
    }
    can() {
        return __awaiter(this, void 0, void 0, function* () {
            return this.linkExtension.can();
        });
    }
    openLinkDialog() {
        return __awaiter(this, void 0, void 0, function* () {
            return this.linkExtension.openCreateLinkDialog();
        });
    }
    isActive() {
        return this.linkExtension.isActive();
    }
}
ControlLinkComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ControlLinkComponent, deps: [{ token: TiptapEventService }, { token: TiptapExtensionService }], target: i0.ɵɵFactoryTarget.Component });
ControlLinkComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: ControlLinkComponent, selector: "tip-control-link", providers: [{ provide: BaseControl, useExisting: forwardRef(() => ControlLinkComponent) }], usesInheritance: true, ngImport: i0, template: `
    <button class="tip-control-button" type="button" (click)="openLinkDialog()" disabled #button>
      <div class="content-wrapper" #ref>
        <ng-content></ng-content>
      </div>
      <i *ngIf="ref.childNodes.length === 0" class="material-icons">link</i>
    </button>`, isInline: true, styles: [":host-context{display:contents}.tip-control-button{display:inline-flex;align-items:center;justify-content:center;padding:1px calc(var(--tip-header-padding) / 2);cursor:pointer;color:var(--tip-text-color);border:none;background-color:transparent;-webkit-tap-highlight-color:transparent}@media (pointer: fine){.tip-control-button:hover,.tip-control-button:focus{color:var(--tip-active-color)}}.tip-control-button[disabled]{cursor:default;color:var(--tip-disabled-color)}.content-wrapper{display:contents}.tip-active{color:var(--tip-active-color)}\n"], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ControlLinkComponent, decorators: [{
            type: Component,
            args: [{ selector: 'tip-control-link', template: `
    <button class="tip-control-button" type="button" (click)="openLinkDialog()" disabled #button>
      <div class="content-wrapper" #ref>
        <ng-content></ng-content>
      </div>
      <i *ngIf="ref.childNodes.length === 0" class="material-icons">link</i>
    </button>`, changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: BaseControl, useExisting: forwardRef(() => ControlLinkComponent) }], styles: [":host-context{display:contents}.tip-control-button{display:inline-flex;align-items:center;justify-content:center;padding:1px calc(var(--tip-header-padding) / 2);cursor:pointer;color:var(--tip-text-color);border:none;background-color:transparent;-webkit-tap-highlight-color:transparent}@media (pointer: fine){.tip-control-button:hover,.tip-control-button:focus{color:var(--tip-active-color)}}.tip-control-button[disabled]{cursor:default;color:var(--tip-disabled-color)}.content-wrapper{display:contents}.tip-active{color:var(--tip-active-color)}\n"] }]
        }], ctorParameters: function () { return [{ type: TiptapEventService }, { type: TiptapExtensionService }]; } });

class ControlMentionComponent extends ButtonBaseControl {
    constructor(eventService, extensionService) {
        super();
        this.eventService = eventService;
        this.extensionService = extensionService;
        this.createMention = new EventEmitter();
        this.mentionClicked = new EventEmitter();
    }
    onEditorReady(editor) {
        this.mentionExtension = this.extensionService.getExtension('mention');
        this.mentionExtension.onClick$.pipe(takeUntil(this.destroy$)).subscribe(e => this.mentionClicked.emit(e));
    }
    updateMention() {
        this.createMention.emit((props) => { var _a; return (_a = this.editor) === null || _a === void 0 ? void 0 : _a.chain().focus().setMention({ props }).run(); });
    }
    isActive() {
        return false;
    }
    can() {
        var _a;
        return !!((_a = this.editor) === null || _a === void 0 ? void 0 : _a.can().setMention({ props: { id: '' } }));
    }
}
ControlMentionComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ControlMentionComponent, deps: [{ token: TiptapEventService }, { token: TiptapExtensionService }], target: i0.ɵɵFactoryTarget.Component });
ControlMentionComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: ControlMentionComponent, selector: "tip-control-mention", outputs: { createMention: "createMention", mentionClicked: "mentionClicked" }, providers: [{ provide: BaseControl, useExisting: forwardRef(() => ControlMentionComponent) }], usesInheritance: true, ngImport: i0, template: `
    <button class="tip-control-button" type="button" (click)="updateMention()" #button>
      <div class="content-wrapper" #ref>
        <ng-content></ng-content>
      </div>
      <i *ngIf="ref.childNodes.length === 0" class="material-icons">person_add</i>
    </button>
  `, isInline: true, styles: [":host-context{display:contents}.tip-control-button{display:inline-flex;align-items:center;justify-content:center;padding:1px calc(var(--tip-header-padding) / 2);cursor:pointer;color:var(--tip-text-color);border:none;background-color:transparent;-webkit-tap-highlight-color:transparent}@media (pointer: fine){.tip-control-button:hover,.tip-control-button:focus{color:var(--tip-active-color)}}.tip-control-button[disabled]{cursor:default;color:var(--tip-disabled-color)}.content-wrapper{display:contents}.tip-active{color:var(--tip-active-color)}\n"], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ControlMentionComponent, decorators: [{
            type: Component,
            args: [{ selector: 'tip-control-mention', template: `
    <button class="tip-control-button" type="button" (click)="updateMention()" #button>
      <div class="content-wrapper" #ref>
        <ng-content></ng-content>
      </div>
      <i *ngIf="ref.childNodes.length === 0" class="material-icons">person_add</i>
    </button>
  `, changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: BaseControl, useExisting: forwardRef(() => ControlMentionComponent) }], styles: [":host-context{display:contents}.tip-control-button{display:inline-flex;align-items:center;justify-content:center;padding:1px calc(var(--tip-header-padding) / 2);cursor:pointer;color:var(--tip-text-color);border:none;background-color:transparent;-webkit-tap-highlight-color:transparent}@media (pointer: fine){.tip-control-button:hover,.tip-control-button:focus{color:var(--tip-active-color)}}.tip-control-button[disabled]{cursor:default;color:var(--tip-disabled-color)}.content-wrapper{display:contents}.tip-active{color:var(--tip-active-color)}\n"] }]
        }], ctorParameters: function () { return [{ type: TiptapEventService }, { type: TiptapExtensionService }]; }, propDecorators: { createMention: [{
                type: Output
            }], mentionClicked: [{
                type: Output
            }] } });

class ControlNumberListComponent extends ButtonBaseControl {
    constructor(eventService) {
        super();
        this.eventService = eventService;
    }
    toggleList() {
        this.editor && this.editor.chain().focus().toggleOrderedList().run();
    }
    can(...args) {
        var _a;
        return !!((_a = this.editor) === null || _a === void 0 ? void 0 : _a.can().toggleOrderedList());
    }
    isActive(...args) {
        var _a;
        return !!((_a = this.editor) === null || _a === void 0 ? void 0 : _a.isActive('orderedList'));
    }
}
ControlNumberListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ControlNumberListComponent, deps: [{ token: TiptapEventService }], target: i0.ɵɵFactoryTarget.Component });
ControlNumberListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: ControlNumberListComponent, selector: "tip-control-number-list", providers: [{ provide: BaseControl, useExisting: forwardRef(() => ControlNumberListComponent) }], usesInheritance: true, ngImport: i0, template: `
    <button class="tip-control-button" type="button" (click)="toggleList()" #button>
      <div class="content-wrapper" #ref>
        <ng-content></ng-content>
      </div>
      <i *ngIf="ref.childNodes.length === 0" class="material-icons">format_list_numbered</i>
    </button>`, isInline: true, styles: [":host-context{display:contents}.tip-control-button{display:inline-flex;align-items:center;justify-content:center;padding:1px calc(var(--tip-header-padding) / 2);cursor:pointer;color:var(--tip-text-color);border:none;background-color:transparent;-webkit-tap-highlight-color:transparent}@media (pointer: fine){.tip-control-button:hover,.tip-control-button:focus{color:var(--tip-active-color)}}.tip-control-button[disabled]{cursor:default;color:var(--tip-disabled-color)}.content-wrapper{display:contents}.tip-active{color:var(--tip-active-color)}\n"], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ControlNumberListComponent, decorators: [{
            type: Component,
            args: [{ selector: 'tip-control-number-list', template: `
    <button class="tip-control-button" type="button" (click)="toggleList()" #button>
      <div class="content-wrapper" #ref>
        <ng-content></ng-content>
      </div>
      <i *ngIf="ref.childNodes.length === 0" class="material-icons">format_list_numbered</i>
    </button>`, changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: BaseControl, useExisting: forwardRef(() => ControlNumberListComponent) }], styles: [":host-context{display:contents}.tip-control-button{display:inline-flex;align-items:center;justify-content:center;padding:1px calc(var(--tip-header-padding) / 2);cursor:pointer;color:var(--tip-text-color);border:none;background-color:transparent;-webkit-tap-highlight-color:transparent}@media (pointer: fine){.tip-control-button:hover,.tip-control-button:focus{color:var(--tip-active-color)}}.tip-control-button[disabled]{cursor:default;color:var(--tip-disabled-color)}.content-wrapper{display:contents}.tip-active{color:var(--tip-active-color)}\n"] }]
        }], ctorParameters: function () { return [{ type: TiptapEventService }]; } });

class ControlStrikeComponent extends ButtonBaseControl {
    constructor(eventService) {
        super();
        this.eventService = eventService;
    }
    toggleList() {
        this.editor && this.editor.chain().focus().toggleStrike().run();
    }
    can() {
        var _a;
        return !!((_a = this.editor) === null || _a === void 0 ? void 0 : _a.can().toggleStrike());
    }
    isActive(...args) {
        var _a;
        return !!((_a = this.editor) === null || _a === void 0 ? void 0 : _a.isActive('strike'));
    }
}
ControlStrikeComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ControlStrikeComponent, deps: [{ token: TiptapEventService }], target: i0.ɵɵFactoryTarget.Component });
ControlStrikeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: ControlStrikeComponent, selector: "tip-control-strike", providers: [{ provide: BaseControl, useExisting: forwardRef(() => ControlStrikeComponent) }], usesInheritance: true, ngImport: i0, template: `
    <button class="tip-control-button" type="button" (click)="toggleList()" #button>
      <div class="content-wrapper" #ref>
        <ng-content></ng-content>
      </div>
      <i *ngIf="ref.childNodes.length === 0" class="material-icons">format_strikethrough</i>
    </button>`, isInline: true, styles: [":host-context{display:contents}.tip-control-button{display:inline-flex;align-items:center;justify-content:center;padding:1px calc(var(--tip-header-padding) / 2);cursor:pointer;color:var(--tip-text-color);border:none;background-color:transparent;-webkit-tap-highlight-color:transparent}@media (pointer: fine){.tip-control-button:hover,.tip-control-button:focus{color:var(--tip-active-color)}}.tip-control-button[disabled]{cursor:default;color:var(--tip-disabled-color)}.content-wrapper{display:contents}.tip-active{color:var(--tip-active-color)}\n"], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ControlStrikeComponent, decorators: [{
            type: Component,
            args: [{ selector: 'tip-control-strike', template: `
    <button class="tip-control-button" type="button" (click)="toggleList()" #button>
      <div class="content-wrapper" #ref>
        <ng-content></ng-content>
      </div>
      <i *ngIf="ref.childNodes.length === 0" class="material-icons">format_strikethrough</i>
    </button>`, changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: BaseControl, useExisting: forwardRef(() => ControlStrikeComponent) }], styles: [":host-context{display:contents}.tip-control-button{display:inline-flex;align-items:center;justify-content:center;padding:1px calc(var(--tip-header-padding) / 2);cursor:pointer;color:var(--tip-text-color);border:none;background-color:transparent;-webkit-tap-highlight-color:transparent}@media (pointer: fine){.tip-control-button:hover,.tip-control-button:focus{color:var(--tip-active-color)}}.tip-control-button[disabled]{cursor:default;color:var(--tip-disabled-color)}.content-wrapper{display:contents}.tip-active{color:var(--tip-active-color)}\n"] }]
        }], ctorParameters: function () { return [{ type: TiptapEventService }]; } });

class ControlTasklistComponent extends ButtonBaseControl {
    constructor(eventService) {
        super();
        this.eventService = eventService;
    }
    toggleTask() {
        this.editor && this.editor.chain().focus().toggleTaskList().run();
    }
    can() {
        var _a;
        return !!((_a = this.editor) === null || _a === void 0 ? void 0 : _a.can().toggleTaskList());
    }
    isActive(...args) {
        var _a;
        return !!((_a = this.editor) === null || _a === void 0 ? void 0 : _a.isActive('taskList'));
    }
}
ControlTasklistComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ControlTasklistComponent, deps: [{ token: TiptapEventService }], target: i0.ɵɵFactoryTarget.Component });
ControlTasklistComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: ControlTasklistComponent, selector: "tip-control-task", providers: [{ provide: BaseControl, useExisting: forwardRef(() => ControlTasklistComponent) }], usesInheritance: true, ngImport: i0, template: `
    <button class="tip-control-button" type="button" (click)="toggleTask()" #button>
      <div class="content-wrapper" #ref>
        <ng-content></ng-content>
      </div>
      <i *ngIf="ref.childNodes.length === 0" class="material-icons">checklist</i>
    </button>`, isInline: true, styles: [":host-context{display:contents}.tip-control-button{display:inline-flex;align-items:center;justify-content:center;padding:1px calc(var(--tip-header-padding) / 2);cursor:pointer;color:var(--tip-text-color);border:none;background-color:transparent;-webkit-tap-highlight-color:transparent}@media (pointer: fine){.tip-control-button:hover,.tip-control-button:focus{color:var(--tip-active-color)}}.tip-control-button[disabled]{cursor:default;color:var(--tip-disabled-color)}.content-wrapper{display:contents}.tip-active{color:var(--tip-active-color)}\n"], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ControlTasklistComponent, decorators: [{
            type: Component,
            args: [{ selector: 'tip-control-task', template: `
    <button class="tip-control-button" type="button" (click)="toggleTask()" #button>
      <div class="content-wrapper" #ref>
        <ng-content></ng-content>
      </div>
      <i *ngIf="ref.childNodes.length === 0" class="material-icons">checklist</i>
    </button>`, changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: BaseControl, useExisting: forwardRef(() => ControlTasklistComponent) }], styles: [":host-context{display:contents}.tip-control-button{display:inline-flex;align-items:center;justify-content:center;padding:1px calc(var(--tip-header-padding) / 2);cursor:pointer;color:var(--tip-text-color);border:none;background-color:transparent;-webkit-tap-highlight-color:transparent}@media (pointer: fine){.tip-control-button:hover,.tip-control-button:focus{color:var(--tip-active-color)}}.tip-control-button[disabled]{cursor:default;color:var(--tip-disabled-color)}.content-wrapper{display:contents}.tip-active{color:var(--tip-active-color)}\n"] }]
        }], ctorParameters: function () { return [{ type: TiptapEventService }]; } });

class ControlTextAlignComponent extends SelectBaseControl {
    constructor(eventService) {
        super();
        this.eventService = eventService;
        this.disableSanitation = false;
        this.canStyleParams = ['left', 'right', 'center', 'justify'];
    }
    setAlign(alignment) {
        this.editor && this.editor.chain().focus().setTextAlign(alignment).run();
    }
    canStyle(alignment) {
        if (!this.editor)
            return false;
        return this.editor.can().setTextAlign(alignment);
    }
    currentActive() {
        if (this.editor) {
            if (this.editor.isActive({ textAlign: 'left' }))
                return 'left';
            if (this.editor.isActive({ textAlign: 'right' }))
                return 'right';
            if (this.editor.isActive({ textAlign: 'center' }))
                return 'center';
            if (this.editor.isActive({ textAlign: 'justify' }))
                return 'justify';
        }
        return null;
    }
}
ControlTextAlignComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ControlTextAlignComponent, deps: [{ token: TiptapEventService }], target: i0.ɵɵFactoryTarget.Component });
ControlTextAlignComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: ControlTextAlignComponent, selector: "tip-control-text-align", inputs: { disableSanitation: "disableSanitation" }, providers: [{ provide: BaseControl, useExisting: forwardRef(() => ControlTextAlignComponent) }], usesInheritance: true, ngImport: i0, template: `
    <tip-select defaultValue="left" width="auto" [showIcon]="false"
                (change)="setAlign($event)" [disablePreviewSanitation]="disableSanitation">
      <tip-option value="left" [useHtml]="true" [enforceHeight]="true">
        <div class="content-wrapper" #left>
          <ng-content select="[data-left]"></ng-content>
        </div>
        <i *ngIf="left.childNodes.length === 0" class="material-icons">format_align_left</i>
      </tip-option>
      <tip-option value="right" [useHtml]="true" [enforceHeight]="true">
        <div class="content-wrapper" #right>
          <ng-content select="[data-right]"></ng-content>
        </div>
        <i *ngIf="right.childNodes.length === 0" class="material-icons">format_align_right</i>
      </tip-option>
      <tip-option value="center" [useHtml]="true" [enforceHeight]="true">
        <div class="content-wrapper" #center>
          <ng-content select="[data-center]"></ng-content>
        </div>
        <i *ngIf="center.childNodes.length === 0" class="material-icons">format_align_center</i>
      </tip-option>
      <tip-option value="justify" [useHtml]="true" [enforceHeight]="true">
        <div class="content-wrapper" #justify>
          <ng-content select="[data-justify]"></ng-content>
        </div>
        <i *ngIf="justify.childNodes.length === 0" class="material-icons">format_align_justify</i>
      </tip-option>
    </tip-select>
  `, isInline: true, styles: [":host-context{display:contents}.tip-control-button{display:inline-flex;align-items:center;justify-content:center;padding:1px calc(var(--tip-header-padding) / 2);cursor:pointer;color:var(--tip-text-color);border:none;background-color:transparent;-webkit-tap-highlight-color:transparent}@media (pointer: fine){.tip-control-button:hover,.tip-control-button:focus{color:var(--tip-active-color)}}.tip-control-button[disabled]{cursor:default;color:var(--tip-disabled-color)}.content-wrapper{display:contents}.tip-active{color:var(--tip-active-color)}\n"], components: [{ type: SelectComponent, selector: "tip-select", inputs: ["width", "placeholder", "defaultValue", "showIcon", "disablePreviewSanitation", "value"], outputs: ["change"] }, { type: OptionComponent, selector: "tip-option[value]", inputs: ["value", "enforceHeight", "useHtml", "disabled"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ControlTextAlignComponent, decorators: [{
            type: Component,
            args: [{ selector: 'tip-control-text-align', template: `
    <tip-select defaultValue="left" width="auto" [showIcon]="false"
                (change)="setAlign($event)" [disablePreviewSanitation]="disableSanitation">
      <tip-option value="left" [useHtml]="true" [enforceHeight]="true">
        <div class="content-wrapper" #left>
          <ng-content select="[data-left]"></ng-content>
        </div>
        <i *ngIf="left.childNodes.length === 0" class="material-icons">format_align_left</i>
      </tip-option>
      <tip-option value="right" [useHtml]="true" [enforceHeight]="true">
        <div class="content-wrapper" #right>
          <ng-content select="[data-right]"></ng-content>
        </div>
        <i *ngIf="right.childNodes.length === 0" class="material-icons">format_align_right</i>
      </tip-option>
      <tip-option value="center" [useHtml]="true" [enforceHeight]="true">
        <div class="content-wrapper" #center>
          <ng-content select="[data-center]"></ng-content>
        </div>
        <i *ngIf="center.childNodes.length === 0" class="material-icons">format_align_center</i>
      </tip-option>
      <tip-option value="justify" [useHtml]="true" [enforceHeight]="true">
        <div class="content-wrapper" #justify>
          <ng-content select="[data-justify]"></ng-content>
        </div>
        <i *ngIf="justify.childNodes.length === 0" class="material-icons">format_align_justify</i>
      </tip-option>
    </tip-select>
  `, changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: BaseControl, useExisting: forwardRef(() => ControlTextAlignComponent) }], styles: [":host-context{display:contents}.tip-control-button{display:inline-flex;align-items:center;justify-content:center;padding:1px calc(var(--tip-header-padding) / 2);cursor:pointer;color:var(--tip-text-color);border:none;background-color:transparent;-webkit-tap-highlight-color:transparent}@media (pointer: fine){.tip-control-button:hover,.tip-control-button:focus{color:var(--tip-active-color)}}.tip-control-button[disabled]{cursor:default;color:var(--tip-disabled-color)}.content-wrapper{display:contents}.tip-active{color:var(--tip-active-color)}\n"] }]
        }], ctorParameters: function () { return [{ type: TiptapEventService }]; }, propDecorators: { disableSanitation: [{
                type: Input
            }] } });

class ControlUnderlineComponent extends ButtonBaseControl {
    constructor(eventService) {
        super();
        this.eventService = eventService;
    }
    toggleUnderline() {
        this.editor && this.editor.chain().focus().toggleUnderline().run();
    }
    can() {
        var _a;
        return !!((_a = this.editor) === null || _a === void 0 ? void 0 : _a.can().toggleUnderline());
    }
    isActive() {
        var _a;
        return !!((_a = this.editor) === null || _a === void 0 ? void 0 : _a.isActive('underline'));
    }
}
ControlUnderlineComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ControlUnderlineComponent, deps: [{ token: TiptapEventService }], target: i0.ɵɵFactoryTarget.Component });
ControlUnderlineComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: ControlUnderlineComponent, selector: "tip-control-underline", providers: [{ provide: BaseControl, useExisting: forwardRef(() => ControlUnderlineComponent) }], usesInheritance: true, ngImport: i0, template: `
    <button class="tip-control-button" type="button" (click)="toggleUnderline()" #button>
      <div class="content-wrapper" #ref>
        <ng-content></ng-content>
      </div>
      <i *ngIf="ref.childNodes.length === 0" class="material-icons">format_underline</i>
    </button>
  `, isInline: true, styles: [":host-context{display:contents}.tip-control-button{display:inline-flex;align-items:center;justify-content:center;padding:1px calc(var(--tip-header-padding) / 2);cursor:pointer;color:var(--tip-text-color);border:none;background-color:transparent;-webkit-tap-highlight-color:transparent}@media (pointer: fine){.tip-control-button:hover,.tip-control-button:focus{color:var(--tip-active-color)}}.tip-control-button[disabled]{cursor:default;color:var(--tip-disabled-color)}.content-wrapper{display:contents}.tip-active{color:var(--tip-active-color)}\n"], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ControlUnderlineComponent, decorators: [{
            type: Component,
            args: [{ selector: 'tip-control-underline', template: `
    <button class="tip-control-button" type="button" (click)="toggleUnderline()" #button>
      <div class="content-wrapper" #ref>
        <ng-content></ng-content>
      </div>
      <i *ngIf="ref.childNodes.length === 0" class="material-icons">format_underline</i>
    </button>
  `, changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: BaseControl, useExisting: forwardRef(() => ControlUnderlineComponent) }], styles: [":host-context{display:contents}.tip-control-button{display:inline-flex;align-items:center;justify-content:center;padding:1px calc(var(--tip-header-padding) / 2);cursor:pointer;color:var(--tip-text-color);border:none;background-color:transparent;-webkit-tap-highlight-color:transparent}@media (pointer: fine){.tip-control-button:hover,.tip-control-button:focus{color:var(--tip-active-color)}}.tip-control-button[disabled]{cursor:default;color:var(--tip-disabled-color)}.content-wrapper{display:contents}.tip-active{color:var(--tip-active-color)}\n"] }]
        }], ctorParameters: function () { return [{ type: TiptapEventService }]; } });

class DisplayCharacterCountComponent extends ExtendedBaseControl {
    constructor(eventService, tiptapExtensionService) {
        super();
        this.eventService = eventService;
        this.tiptapExtensionService = tiptapExtensionService;
        this.displayLimit = true;
        this.displayCharacter = true;
        this.displayWordCount = true;
        this.worldString = 'worlds';
        this.characterString = 'characters';
    }
    ngOnInit() {
        this.eventService.update$.pipe(takeUntil(this.destroy$), delay(100)).subscribe(() => {
            this.updateCharacterCountHtml();
        });
    }
    onEditorReady(editor) {
        this.characterCountExtension = this.tiptapExtensionService.getExtension('characterCount');
        this.updateCharacterCountHtml();
    }
    updateCharacterCountHtml() {
        if (!this.editor)
            return;
        const characters = this.editor.storage.characterCount.characters();
        const words = this.editor.storage.characterCount.words();
        if (this.characterElement) {
            let characterString = `${characters}`;
            if (this.displayLimit && this.characterCountExtension && this.characterCountExtension.options.limit) {
                characterString += `/${this.characterCountExtension.options.limit}`;
            }
            characterString += ` ${this.characterString}`;
            this.characterElement.nativeElement.innerText = characterString;
        }
        if (this.wordCountElement) {
            this.wordCountElement.nativeElement.innerText = `${words} ${this.worldString}`;
        }
    }
}
DisplayCharacterCountComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DisplayCharacterCountComponent, deps: [{ token: TiptapEventService }, { token: TiptapExtensionService }], target: i0.ɵɵFactoryTarget.Component });
DisplayCharacterCountComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: DisplayCharacterCountComponent, selector: "tip-character-count-display", inputs: { displayLimit: "displayLimit", displayCharacter: "displayCharacter", displayWordCount: "displayWordCount", worldString: "worldString", characterString: "characterString" }, providers: [{ provide: BaseControl, useExisting: forwardRef(() => DisplayCharacterCountComponent) }], viewQueries: [{ propertyName: "characterElement", first: true, predicate: ["character"], descendants: true }, { propertyName: "wordCountElement", first: true, predicate: ["worldCount"], descendants: true }], usesInheritance: true, ngImport: i0, template: `
    <span *ngIf="displayCharacter" #character></span><br/>
    <span *ngIf="displayWordCount" #worldCount></span>
  `, isInline: true, styles: [":host-context{color:var(--tip-light-text-color)}\n"], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DisplayCharacterCountComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'tip-character-count-display',
                    styles: [`
    :host-context {
      color: var(--tip-light-text-color)
    }
  `],
                    template: `
    <span *ngIf="displayCharacter" #character></span><br/>
    <span *ngIf="displayWordCount" #worldCount></span>
  `,
                    changeDetection: ChangeDetectionStrategy.OnPush,
                    providers: [{ provide: BaseControl, useExisting: forwardRef(() => DisplayCharacterCountComponent) }],
                }]
        }], ctorParameters: function () { return [{ type: TiptapEventService }, { type: TiptapExtensionService }]; }, propDecorators: { displayLimit: [{
                type: Input
            }], displayCharacter: [{
                type: Input
            }], displayWordCount: [{
                type: Input
            }], worldString: [{
                type: Input
            }], characterString: [{
                type: Input
            }], characterElement: [{
                type: ViewChild,
                args: ['character']
            }], wordCountElement: [{
                type: ViewChild,
                args: ['worldCount']
            }] } });

const PopOverPopUpAnimation = trigger('popUp', [
    transition(':enter', [
        query('.popover-wrapper', [
            style({ opacity: 0, transform: 'translate(-50%, -50%)' }),
            animate('150ms cubic-bezier(.13,1.14,1,.92)', style({ opacity: 1, transform: '*' })),
        ])
    ]),
    transition(':leave', query('.popover-wrapper', [
        animate('150ms cubic-bezier(.13,1.14,1,.92)', style({ opacity: 0, transform: 'translate(-50%, -50%)' })),
    ])),
]);
const OverlayPopUpAnimation = trigger('popUp', [
    transition(':enter', [
        query('.dialog-wrapper', [
            style({ transform: 'translate(-50%, -30%)' }),
            animate('150ms cubic-bezier(.13,1.14,1,.92)', style({ transform: '*' })),
        ])
    ]),
    transition(':leave', query('.dialog-wrapper', [
        animate('150ms cubic-bezier(.13,1.14,1,.92)', style({ transform: 'translate(-50%, -30%)' })),
    ])),
]);

const TIP_DIALOG_DATA = new InjectionToken('DIALOG_DATA');
class DialogRef {
    /* tslint:enable */
    constructor(_component, appRef, dialogWrapperComponentRef, config) {
        this._component = _component;
        this.appRef = appRef;
        this.dialogWrapperComponentRef = dialogWrapperComponentRef;
        this.config = config;
        /* tslint:disable member-ordering*/
        this.subject$ = new Subject();
        this.result$ = this.subject$.asObservable();
        this._done = false;
    }
    get component() {
        return this._component;
    }
    get done() {
        return this._done;
    }
    get dialogConfig() {
        const copy = Object.assign({}, this.config);
        delete copy.data;
        return copy;
    }
    get dialogWrapperComponent() {
        return this.dialogWrapperComponentRef.component;
    }
    submit(data) {
        this.sendResult(data, 'success');
    }
    cancel() {
        this.sendResult(null, 'canceled');
    }
    sendResult(data, status) {
        if (this.done)
            return;
        this.appRef.detachView(this.dialogWrapperComponent.hostView);
        this.dialogWrapperComponent.destroy();
        this._done = true;
        this.subject$.next({ data, status });
        this.subject$.complete();
    }
}
// tslint:disable-next-line:directive-class-suffix
class DialogBaseClass {
    constructor() {
        this.destroy$ = new Subject();
    }
    ngOnInit() {
        this.ngZone.runOutsideAngular(() => {
            fromEvent(this.document, 'keydown').pipe(filter(e => e.key === 'Escape'), takeUntil(this.destroy$)).subscribe(() => this.ngZone.run(() => this.closeDialog()));
        });
    }
    ngOnDestroy() {
        this.destroy$.next(true);
        this.destroy$.complete();
    }
    closeDialog() {
        if (!this.dialogRef.dialogConfig.autoClose)
            return;
        this.dialogRef.cancel();
    }
}
DialogBaseClass.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DialogBaseClass, deps: [], target: i0.ɵɵFactoryTarget.Directive });
DialogBaseClass.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.1.1", type: DialogBaseClass, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DialogBaseClass, decorators: [{
            type: Directive
        }] });

// @dynamic
class DialogComponent extends DialogBaseClass {
    constructor(data, document, dialogRef, ngZone) {
        super();
        this.data = data;
        this.document = document;
        this.dialogRef = dialogRef;
        this.ngZone = ngZone;
        this.position = {};
        this.position = this.calculateStyle();
    }
    calculateStyle() {
        const config = this.dialogRef.dialogConfig;
        return {
            width: config.width,
            maxWidth: config.maxWidth,
            top: config.position === 'top' ? '20%' : '50%',
        };
    }
}
DialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DialogComponent, deps: [{ token: TIP_DIALOG_DATA }, { token: DOCUMENT }, { token: DialogRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
DialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: DialogComponent, selector: "tip-dialog", host: { properties: { "@fadeIn": "this.calculateStyle", "@popUp": "this.calculateStyle" } }, usesInheritance: true, ngImport: i0, template: `
    <div class="overlay" (click)="closeDialog()" [ngStyle]="{backgroundColor: dialogRef.dialogConfig.backdropColor}"></div>
    <div class="dialog-wrapper" [ngStyle]="position">
      <ng-container *ngIf="dialogRef.component" [ngComponentOutlet]="dialogRef.component"></ng-container>
    </div>
  `, isInline: true, styles: [".overlay{position:fixed;top:0;bottom:0;right:0;left:0;z-index:2000}.dialog-wrapper{left:50%;position:absolute;transform:translate(-50%,-50%);border-radius:5px;padding:10px;z-index:2000;background-color:var(--tip-background-color)}\n"], directives: [{ type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModuleFactory"] }], animations: [FadeInAnimation, OverlayPopUpAnimation], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DialogComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'tip-dialog',
                    template: `
    <div class="overlay" (click)="closeDialog()" [ngStyle]="{backgroundColor: dialogRef.dialogConfig.backdropColor}"></div>
    <div class="dialog-wrapper" [ngStyle]="position">
      <ng-container *ngIf="dialogRef.component" [ngComponentOutlet]="dialogRef.component"></ng-container>
    </div>
  `,
                    animations: [FadeInAnimation, OverlayPopUpAnimation],
                    styles: [`
    .overlay {
      position: fixed;
      top: 0;
      bottom: 0;
      right: 0;
      left: 0;
      z-index: 2000;
    }

    .dialog-wrapper {
      left: 50%;
      position: absolute;
      transform: translate(-50%, -50%);
      border-radius: 5px;
      padding: 10px;
      z-index: 2000;
      background-color: var(--tip-background-color);
    }
  `],
                    changeDetection: ChangeDetectionStrategy.OnPush
                }]
        }], ctorParameters: function () {
        return [{ type: undefined, decorators: [{
                        type: Inject,
                        args: [TIP_DIALOG_DATA]
                    }] }, { type: Document, decorators: [{
                        type: Inject,
                        args: [DOCUMENT]
                    }] }, { type: DialogRef }, { type: i0.NgZone }];
    }, propDecorators: { calculateStyle: [{
                type: HostBinding,
                args: ['@fadeIn']
            }, {
                type: HostBinding,
                args: ['@popUp']
            }] } });

// @dynamic
class PopoverComponent extends DialogBaseClass {
    constructor(data, document, dialogRef, ngZone, cd, element) {
        super();
        this.data = data;
        this.document = document;
        this.dialogRef = dialogRef;
        this.ngZone = ngZone;
        this.cd = cd;
        this.element = element;
        this.style = {};
        this.style = this.calculateStyle();
    }
    ngOnInit() {
        super.ngOnInit();
        this.ngZone.runOutsideAngular(() => __awaiter(this, void 0, void 0, function* () {
            yield sleep(1000);
            fromEvent(this.document, 'click')
                .pipe(takeUntil(this.destroy$), filter(e => !this.element.nativeElement.contains(e.target)))
                .subscribe(() => this.ngZone.run(() => this.dialogRef.cancel()));
        }));
    }
    ngAfterViewInit() {
        const position = this.popover.nativeElement.getBoundingClientRect();
        const window = this.document.defaultView;
        if (!window)
            return;
        const windowWidth = window.innerWidth;
        const overflowRight = (position.x + position.width) - windowWidth;
        const updateStyles = {};
        if (position.x < 0) {
            updateStyles.transform = `translate(calc(-50% + ${Math.abs(position.x - 5)}px), -100%)`;
        }
        else if (overflowRight > 0) {
            updateStyles.transform = `translate(calc(-50% - ${overflowRight + 5}px), -100%)`;
        }
        if (Object.keys(updateStyles).length > 0) {
            this.style = Object.assign(Object.assign({}, this.style), updateStyles);
            this.cd.detectChanges();
        }
    }
    calculateStyle() {
        const config = this.dialogRef.dialogConfig;
        return {
            'top.px': config.position.y - 10,
            'left.px': config.position.x,
        };
    }
}
PopoverComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: PopoverComponent, deps: [{ token: TIP_DIALOG_DATA }, { token: DOCUMENT }, { token: DialogRef }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
PopoverComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: PopoverComponent, selector: "tip-popover", host: { properties: { "@popUp": "this.ngAfterViewInit" } }, viewQueries: [{ propertyName: "popover", first: true, predicate: ["popover"], descendants: true }], usesInheritance: true, ngImport: i0, template: `
    <div class="popover-wrapper" [ngStyle]="style" #popover>
      <ng-container *ngIf="dialogRef.component" [ngComponentOutlet]="dialogRef.component"></ng-container>
      <div class="hide-arrow"></div>
      <div class="arrow"></div>
    </div>
  `, isInline: true, styles: [".popover-wrapper{border-radius:5px;background-color:var(--tip-background-color);position:fixed;transform:translate(-50%,-100%);box-shadow:0 1px 3px 1px #3c404326;padding:11px;z-index:2000}.hide-arrow{position:absolute;width:30px;height:10px;transform:translate(-50%,-100%);top:100%;left:50%;background-color:var(--tip-background-color);z-index:1}.arrow{position:absolute;top:100%;left:50%;width:0;height:0;box-shadow:1px 1px 3px 1px #3c404326;border:7px solid var(--tip-background-color);transform:rotate(45deg) translate(-50%,-50%);transform-origin:0 0;z-index:0}\n"], directives: [{ type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModuleFactory"] }], animations: [PopOverPopUpAnimation], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: PopoverComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'tip-popover',
                    template: `
    <div class="popover-wrapper" [ngStyle]="style" #popover>
      <ng-container *ngIf="dialogRef.component" [ngComponentOutlet]="dialogRef.component"></ng-container>
      <div class="hide-arrow"></div>
      <div class="arrow"></div>
    </div>
  `,
                    animations: [PopOverPopUpAnimation],
                    styles: [`
    .popover-wrapper {
      border-radius: 5px;
      background-color: var(--tip-background-color);
      position: fixed;
      transform: translate(-50%, -100%);
      box-shadow: 0 1px 3px 1px rgba(60, 64, 67, .15);
      padding: 11px;
      z-index: 2000;
    }

    .hide-arrow {
      position: absolute;
      width: 30px;
      height: 10px;
      transform: translate(-50%, -100%);
      top: 100%;
      left: 50%;
      background-color: var(--tip-background-color);
      z-index: 1;
    }

    .arrow {
      position: absolute;
      top: 100%;
      left: 50%;
      width: 0;
      height: 0;
      box-shadow: 1px 1px 3px 1px rgba(60, 64, 67, .15);
      border: 7px solid var(--tip-background-color);
      transform: rotate(45deg) translate(-50%, -50%);
      transform-origin: 0 0;
      z-index: 0;
    }

  `],
                    changeDetection: ChangeDetectionStrategy.OnPush,
                }]
        }], ctorParameters: function () {
        return [{ type: undefined, decorators: [{
                        type: Inject,
                        args: [TIP_DIALOG_DATA]
                    }] }, { type: Document, decorators: [{
                        type: Inject,
                        args: [DOCUMENT]
                    }] }, { type: DialogRef }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }];
    }, propDecorators: { popover: [{
                type: ViewChild,
                args: ['popover']
            }], ngAfterViewInit: [{
                type: HostBinding,
                args: ['@popUp']
            }] } });

class EditorBodyComponent {
    constructor() {
        this.minHeight = '';
        this.maxHeight = '';
        this._displayTopCurves = true;
        this._displayBottomCurves = true;
        this.editor = null;
        this._editorElement = null;
        this._bodyWrapper = null;
    }
    set displayTopCurves(value) {
        this._displayTopCurves = value;
        this.applyBorderClasses();
    }
    set displayBottomCurves(value) {
        this._displayBottomCurves = value;
        this.applyBorderClasses();
    }
    get editorElement() {
        return this._editorElement ? this._editorElement.nativeElement : null;
    }
    get height() {
        if (this.minHeight && !this.maxHeight) {
            return this.minHeight;
        }
        if (this.minHeight && !this.maxHeight || this.maxHeight && !this.minHeight) {
            console.warn('You have to set minHeight and maxHeight of the tip-editor-body for it to work properly.\n' +
                'The values however can be the same');
            return '';
        }
        else if (!this.minHeight && !this.maxHeight) {
            return '';
        }
        return '200vh';
    }
    setEditor(tiptapEditor) {
        this.editor = tiptapEditor;
    }
    applyBorderClasses() {
        if (!this._bodyWrapper)
            return;
        const wrapperElement = this._bodyWrapper.nativeElement;
        if (this._displayBottomCurves) {
            wrapperElement.classList.add('curve-bottom');
        }
        else {
            wrapperElement.classList.remove('curve-bottom');
        }
        if (this._displayTopCurves) {
            wrapperElement.classList.add('curve-top');
        }
        else {
            wrapperElement.classList.remove('curve-top');
        }
    }
}
EditorBodyComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: EditorBodyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
EditorBodyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: EditorBodyComponent, selector: "tip-editor-body, tip-editor-body[minHeight][maxHeight]", inputs: { minHeight: "minHeight", maxHeight: "maxHeight" }, viewQueries: [{ propertyName: "_editorElement", first: true, predicate: ["editorBody"], descendants: true }, { propertyName: "_bodyWrapper", first: true, predicate: ["bodyWrapper"], descendants: true }], ngImport: i0, template: `
    <div class="editor-body" [ngStyle]="{minHeight: minHeight, maxHeight: maxHeight}"
         #bodyWrapper
    >
      <div class="tiptap-view" #editorBody></div>
    </div>
  `, isInline: true, styles: [".editor-body{display:flex;overflow:auto;flex-direction:column;height:100%;padding:1rem;border:solid 1px var(--tip-border-color)}.curve-top{border-top-left-radius:var(--tip-border-radius);border-top-right-radius:var(--tip-border-radius)}.curve-bottom{border-bottom-right-radius:var(--tip-border-radius);border-bottom-left-radius:var(--tip-border-radius)}::ng-deep .ProseMirror>*:first-child{margin-top:0}::ng-deep .ProseMirror>*:last-child{margin-bottom:0}.tiptap-view{display:flex;flex-direction:column;flex-grow:1;height:100%}::ng-deep tip-editor-body .ProseMirror{flex-grow:1}\n"], directives: [{ type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: EditorBodyComponent, decorators: [{
            type: Component,
            args: [{ selector: 'tip-editor-body, tip-editor-body[minHeight][maxHeight]', template: `
    <div class="editor-body" [ngStyle]="{minHeight: minHeight, maxHeight: maxHeight}"
         #bodyWrapper
    >
      <div class="tiptap-view" #editorBody></div>
    </div>
  `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".editor-body{display:flex;overflow:auto;flex-direction:column;height:100%;padding:1rem;border:solid 1px var(--tip-border-color)}.curve-top{border-top-left-radius:var(--tip-border-radius);border-top-right-radius:var(--tip-border-radius)}.curve-bottom{border-bottom-right-radius:var(--tip-border-radius);border-bottom-left-radius:var(--tip-border-radius)}::ng-deep .ProseMirror>*:first-child{margin-top:0}::ng-deep .ProseMirror>*:last-child{margin-bottom:0}.tiptap-view{display:flex;flex-direction:column;flex-grow:1;height:100%}::ng-deep tip-editor-body .ProseMirror{flex-grow:1}\n"] }]
        }], propDecorators: { minHeight: [{
                type: Input
            }], maxHeight: [{
                type: Input
            }], _editorElement: [{
                type: ViewChild,
                args: ['editorBody']
            }], _bodyWrapper: [{
                type: ViewChild,
                args: ['bodyWrapper']
            }] } });

class EditorFooterComponent {
    constructor() {
        this.editor = null;
        this.children = null;
    }
    setEditor(tiptapEditor) {
        this.editor = tiptapEditor;
        this.passEditorToControls();
    }
    passEditorToControls() {
        this.children && this.children.forEach(control => this.editor && control.setEditor(this.editor));
    }
}
EditorFooterComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: EditorFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
EditorFooterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: EditorFooterComponent, selector: "tip-editor-footer", queries: [{ propertyName: "children", predicate: BaseControl }], ngImport: i0, template: `
    <div class="controls-row">
      <ng-content></ng-content>
    </div>
  `, isInline: true, styles: [".controls-row{display:flex;align-items:center;flex-wrap:wrap;box-sizing:border-box;min-height:var(--tip-header-height);padding:var(--tip-header-padding);border:solid 1px var(--tip-border-color);border-top:none;border-bottom-right-radius:var(--tip-border-radius);border-bottom-left-radius:var(--tip-border-radius)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: EditorFooterComponent, decorators: [{
            type: Component,
            args: [{ selector: 'tip-editor-footer', template: `
    <div class="controls-row">
      <ng-content></ng-content>
    </div>
  `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".controls-row{display:flex;align-items:center;flex-wrap:wrap;box-sizing:border-box;min-height:var(--tip-header-height);padding:var(--tip-header-padding);border:solid 1px var(--tip-border-color);border-top:none;border-bottom-right-radius:var(--tip-border-radius);border-bottom-left-radius:var(--tip-border-radius)}\n"] }]
        }], propDecorators: { children: [{
                type: ContentChildren,
                args: [BaseControl]
            }] } });

class EditorHeaderComponent {
    constructor() {
        this.editor = null;
        this.children = null;
    }
    setEditor(tiptapEditor) {
        this.editor = tiptapEditor;
        this.passEditorToControls();
    }
    passEditorToControls() {
        this.children && this.children.forEach(control => this.editor && control.setEditor(this.editor));
    }
}
EditorHeaderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: EditorHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
EditorHeaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: EditorHeaderComponent, selector: "tip-editor-header", queries: [{ propertyName: "children", predicate: BaseControl }], ngImport: i0, template: `
    <div class="controls-row">
      <ng-content></ng-content>
    </div>
  `, isInline: true, styles: [".controls-row{border-top-left-radius:var(--tip-border-radius);border-top-right-radius:var(--tip-border-radius);display:flex;align-items:center;flex-wrap:wrap;box-sizing:border-box;min-height:var(--tip-header-height);padding:var(--tip-header-padding);border:solid 1px var(--tip-border-color);border-bottom:none}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: EditorHeaderComponent, decorators: [{
            type: Component,
            args: [{ selector: 'tip-editor-header', template: `
    <div class="controls-row">
      <ng-content></ng-content>
    </div>
  `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".controls-row{border-top-left-radius:var(--tip-border-radius);border-top-right-radius:var(--tip-border-radius);display:flex;align-items:center;flex-wrap:wrap;box-sizing:border-box;min-height:var(--tip-header-height);padding:var(--tip-header-padding);border:solid 1px var(--tip-border-color);border-bottom:none}\n"] }]
        }], propDecorators: { children: [{
                type: ContentChildren,
                args: [BaseControl]
            }] } });

class EditorPreviewComponent {
    constructor(domSanitizer, renderer, injector, ngZone) {
        this.domSanitizer = domSanitizer;
        this.renderer = renderer;
        this.injector = injector;
        this.ngZone = ngZone;
        this.extensions = [];
        this.angularExtensions = [];
        this.sanitizeHtml = true;
        this._content = null;
        this.builtExtensions = [];
    }
    set content(value) {
        this._content = value;
        this.renderOutput();
    }
    ngOnChanges(_) {
        const builtAngularExtensions = this.angularExtensions.map(builder => this.ngZone.run(() => builder.build(this.injector)));
        this.builtExtensions = [
            ...this.extensions,
            ...builtAngularExtensions.map(e => e.nativeExtension)
        ];
    }
    ngAfterViewInit() {
        return this.renderOutput();
    }
    renderOutput(content = this._content) {
        if (!this.contentOutlet)
            return;
        let html = '';
        if (typeof content === 'string') {
            html = content;
        }
        else if (content) {
            // Hopefully fixes the github build, which seems to break for some reason
            html = generateHTML(content, this.builtExtensions);
        }
        if (this.sanitizeHtml) {
            html = this.domSanitizer.sanitize(SecurityContext.HTML, html);
            if (isDevMode()) {
                console.warn('The editor preview is sanetizing your HTML. This may lead to missing HTML.');
            }
        }
        this.renderer.setProperty(this.contentOutlet.nativeElement, 'innerHTML', html);
    }
}
EditorPreviewComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: EditorPreviewComponent, deps: [{ token: i1.DomSanitizer }, { token: i0.Renderer2 }, { token: i0.Injector }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
EditorPreviewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: EditorPreviewComponent, selector: "tip-editor-preview", inputs: { extensions: "extensions", angularExtensions: "angularExtensions", sanitizeHtml: "sanitizeHtml", content: "content" }, viewQueries: [{ propertyName: "contentOutlet", first: true, predicate: ["contentOutlet"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
    <div #contentOutlet></div>
  `, isInline: true, styles: [""], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: EditorPreviewComponent, decorators: [{
            type: Component,
            args: [{ selector: 'tip-editor-preview', template: `
    <div #contentOutlet></div>
  `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [""] }]
        }], ctorParameters: function () { return [{ type: i1.DomSanitizer }, { type: i0.Renderer2 }, { type: i0.Injector }, { type: i0.NgZone }]; }, propDecorators: { extensions: [{
                type: Input
            }], angularExtensions: [{
                type: Input
            }], sanitizeHtml: [{
                type: Input
            }], contentOutlet: [{
                type: ViewChild,
                args: ['contentOutlet']
            }], content: [{
                type: Input
            }] } });

const GLOBAL_EXTENSIONS = new InjectionToken('GLOBAL_EXTENSIONS');
const GLOBAL_ANGULAR_EXTENSIONS = new InjectionToken('GLOBAL_ANGULAR_EXTENSIONS');

// tslint:disable:no-output-native
class EditorComponent {
    constructor(ngZone, injector, cd, tiptapExtensionService, platformId, globalExtensions, globalAngularExtensions, eventService, element) {
        this.ngZone = ngZone;
        this.injector = injector;
        this.cd = cd;
        this.tiptapExtensionService = tiptapExtensionService;
        this.platformId = platformId;
        this.globalExtensions = globalExtensions;
        this.globalAngularExtensions = globalAngularExtensions;
        // Content change
        this.jsonChange = new EventEmitter();
        this.htmlChange = new EventEmitter();
        // Editor set
        this.created = new EventEmitter();
        // Editor events
        this.beforeCreate = new EventEmitter();
        this.create = new EventEmitter();
        this.update = new EventEmitter();
        this.selectionUpdate = new EventEmitter();
        this.transaction = new EventEmitter();
        this.focus = new EventEmitter();
        this.blur = new EventEmitter();
        this.destroy = new EventEmitter();
        // Editor input params
        this.content = null;
        this.injectCSS = true;
        this.autofocus = true;
        this.editable = true;
        this.editorProps = {};
        this.parseOptions = {};
        this.enableInputRules = true;
        this.enablePasteRules = true;
        this.extensions = [];
        this.angularExtensions = [];
        this.runEventsOutsideAngular = true;
        this.destroy$ = new Subject();
        this.builtExtensions = [];
        eventService.setElement(element.nativeElement);
    }
    get editor() {
        return this.tiptap ? this.tiptap : null;
    }
    ngAfterViewInit() {
        return __awaiter(this, void 0, void 0, function* () {
            // On the serve you don't need an editor
            if (!isPlatformBrowser(this.platformId))
                return;
            if (!this.editorComponent) {
                throw new Error('You have to pass the tip-editor-body as a child of the tip-editor. Otherwise you cannot see anything');
            }
            // Attach the editor to the editor element
            this.tiptap = this.ngZone.runOutsideAngular(() => new Editor(Object.assign(Object.assign({}, this.buildEditorOptions()), { element: this.editorComponent.editorElement })));
            this.setEditorInAngularExtension();
            // Emit the event which indicates that the tiptap editor was created
            this.created.emit(this.tiptap);
            // Pass the editor the the editorBody component
            this.editorComponent.setEditor(this.tiptap);
            // Check if the header component was passed and if not disable it
            if (this.headerComponent) {
                this.headerComponent.setEditor(this.tiptap);
                this.editorComponent.displayTopCurves = false;
            }
            else {
                this.editorComponent.displayTopCurves = true;
            }
            if (this.footerComponent) {
                this.footerComponent.setEditor(this.tiptap);
                this.editorComponent.displayBottomCurves = false;
            }
            else {
                this.editorComponent.displayBottomCurves = true;
            }
            this.registerEvents();
        });
    }
    ngOnDestroy() {
        this.tiptap && this.tiptap.destroy();
        this.destroy$.next(true);
        this.destroy.complete();
    }
    registerEvents() {
        if (!this.tiptap)
            return;
        this.pipeTo(fromEditorEvent(this.tiptap, 'update').pipe(map(({ editor }) => editor.getJSON())), this.jsonChange);
        this.pipeTo(fromEditorEvent(this.tiptap, 'update').pipe(map(({ editor }) => editor.getHTML())), this.htmlChange);
        this.pipeTo(fromEditorEvent(this.tiptap, 'beforeCreate'), this.beforeCreate);
        this.pipeTo(fromEditorEvent(this.tiptap, 'create'), this.create);
        this.pipeTo(fromEditorEvent(this.tiptap, 'update'), this.update);
        this.pipeTo(fromEditorEvent(this.tiptap, 'selectionUpdate'), this.selectionUpdate);
        this.pipeTo(fromEditorEvent(this.tiptap, 'transaction'), this.transaction);
        this.pipeTo(fromEditorEvent(this.tiptap, 'focus'), this.focus);
        this.pipeTo(fromEditorEvent(this.tiptap, 'blur'), this.blur);
        this.pipeTo(fromEditorEvent(this.tiptap, 'destroy'), this.destroy);
    }
    buildEditorOptions() {
        return {
            content: this.content,
            autofocus: this.autofocus,
            injectCSS: this.injectCSS,
            editable: this.editable,
            editorProps: this.editorProps,
            parseOptions: this.parseOptions,
            enableInputRules: this.enableInputRules,
            enablePasteRules: this.enablePasteRules,
            extensions: this.mergeNativeAndAngularExtensions()
        };
    }
    mergeNativeAndAngularExtensions() {
        // Set collection of native extensions in the extension service
        const nativeExtensions = [...this.extensions];
        if (this.globalExtensions)
            nativeExtensions.push(...this.globalExtensions);
        const nativeDuplicates = getDuplicates(nativeExtensions, item => item.name);
        if (nativeDuplicates && isDevMode()) {
            throw new Error(`Duplicate tiptap extensions found ${JSON.stringify(Object.keys(nativeDuplicates))}`);
        }
        this.tiptapExtensionService.setNativeExtensions(nativeExtensions);
        // Build the angular extensions and set them in the extension service
        const angularExtensions = [...this.angularExtensions];
        if (this.globalAngularExtensions)
            angularExtensions.push(...this.globalAngularExtensions);
        this.builtExtensions = angularExtensions.map(extension => this.ngZone.run(() => extension.build(this.injector)));
        const ngDuplicates = getDuplicates(this.builtExtensions, item => item.constructor.name);
        if (ngDuplicates && isDevMode()) {
            throw new Error(`Duplicate angular-tiptap extensions found (Key is class name): ${JSON.stringify(Object.keys(ngDuplicates))}`);
        }
        this.tiptapExtensionService.setAngularExtensions(this.builtExtensions);
        return [
            ...this.extensions,
            ...this.builtExtensions.map(e => e.nativeExtension)
        ];
    }
    pipeTo(observable, eventEmitter) {
        observable
            .pipe(takeUntil(this.destroy$))
            .subscribe(e => {
            if (this.runEventsOutsideAngular) {
                this.ngZone.runOutsideAngular(() => eventEmitter.next(e));
            }
            else {
                this.ngZone.run(() => eventEmitter.next(e));
            }
        });
    }
    setEditorInAngularExtension() {
        for (const angularExtension of this.builtExtensions) {
            angularExtension.editor = this.tiptap;
        }
    }
}
EditorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: EditorComponent, deps: [{ token: i0.NgZone }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }, { token: TiptapExtensionService }, { token: PLATFORM_ID }, { token: GLOBAL_EXTENSIONS, optional: true }, { token: GLOBAL_ANGULAR_EXTENSIONS, optional: true }, { token: TiptapEventService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
EditorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: EditorComponent, selector: "tip-editor", inputs: { content: "content", injectCSS: "injectCSS", autofocus: "autofocus", editable: "editable", editorProps: "editorProps", parseOptions: "parseOptions", enableInputRules: "enableInputRules", enablePasteRules: "enablePasteRules", extensions: "extensions", angularExtensions: "angularExtensions", runEventsOutsideAngular: "runEventsOutsideAngular" }, outputs: { jsonChange: "jsonChange", htmlChange: "htmlChange", created: "created", beforeCreate: "beforeCreate", create: "create", update: "update", selectionUpdate: "selectionUpdate", transaction: "transaction", focus: "focus", blur: "blur", destroy: "destroy" }, providers: [TiptapEventService, TiptapExtensionService], queries: [{ propertyName: "editorComponent", first: true, predicate: EditorBodyComponent, descendants: true }, { propertyName: "headerComponent", first: true, predicate: EditorHeaderComponent, descendants: true }, { propertyName: "footerComponent", first: true, predicate: EditorFooterComponent, descendants: true }], ngImport: i0, template: `
    <ng-content select="tip-editor-header"></ng-content>
    <ng-content select="tip-editor-body"></ng-content>
    <ng-content select="tip-editor-footer"></ng-content>
  `, isInline: true, styles: [""], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: EditorComponent, decorators: [{
            type: Component,
            args: [{ selector: 'tip-editor', template: `
    <ng-content select="tip-editor-header"></ng-content>
    <ng-content select="tip-editor-body"></ng-content>
    <ng-content select="tip-editor-footer"></ng-content>
  `, changeDetection: ChangeDetectionStrategy.OnPush, providers: [TiptapEventService, TiptapExtensionService], styles: [""] }]
        }], ctorParameters: function () {
        return [{ type: i0.NgZone }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }, { type: TiptapExtensionService }, { type: undefined, decorators: [{
                        type: Inject,
                        args: [PLATFORM_ID]
                    }] }, { type: undefined, decorators: [{
                        type: Optional
                    }, {
                        type: Inject,
                        args: [GLOBAL_EXTENSIONS]
                    }] }, { type: undefined, decorators: [{
                        type: Optional
                    }, {
                        type: Inject,
                        args: [GLOBAL_ANGULAR_EXTENSIONS]
                    }] }, { type: TiptapEventService }, { type: i0.ElementRef }];
    }, propDecorators: { jsonChange: [{
                type: Output
            }], htmlChange: [{
                type: Output
            }], created: [{
                type: Output
            }], beforeCreate: [{
                type: Output
            }], create: [{
                type: Output
            }], update: [{
                type: Output
            }], selectionUpdate: [{
                type: Output
            }], transaction: [{
                type: Output
            }], focus: [{
                type: Output
            }], blur: [{
                type: Output
            }], destroy: [{
                type: Output
            }], content: [{
                type: Input
            }], injectCSS: [{
                type: Input
            }], autofocus: [{
                type: Input
            }], editable: [{
                type: Input
            }], editorProps: [{
                type: Input
            }], parseOptions: [{
                type: Input
            }], enableInputRules: [{
                type: Input
            }], enablePasteRules: [{
                type: Input
            }], extensions: [{
                type: Input
            }], angularExtensions: [{
                type: Input
            }], runEventsOutsideAngular: [{
                type: Input
            }], editorComponent: [{
                type: ContentChild,
                args: [EditorBodyComponent]
            }], headerComponent: [{
                type: ContentChild,
                args: [EditorHeaderComponent]
            }], footerComponent: [{
                type: ContentChild,
                args: [EditorFooterComponent]
            }] } });

class LinkPreviewComponent {
    constructor(dialogRef, link) {
        this.dialogRef = dialogRef;
        this.link = link;
    }
    deleteLink() {
        this.dialogRef.submit('delete');
    }
    editLink() {
        this.dialogRef.submit('edit');
    }
    copyLink() {
        return __awaiter(this, void 0, void 0, function* () {
            yield navigator.clipboard.writeText(this.link);
            this.dialogRef.cancel();
        });
    }
}
LinkPreviewComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: LinkPreviewComponent, deps: [{ token: DialogRef }, { token: TIP_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
LinkPreviewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: LinkPreviewComponent, selector: "tip-link-preview", ngImport: i0, template: `
    <div class="flex">
      <a class="v-center link-text" target="_blank" [href]="link">
        {{link}}
      </a>
      <i style="padding: 0 .25rem" class="material-icons pointer" tabindex="0" (click)="deleteLink()"
         (keyup.enter)="deleteLink()">link_off</i>
      <i style="padding: 0 .25rem" class="material-icons pointer" tabindex="0" (click)="copyLink()"
         (keyup.enter)="copyLink()">content_copy</i>
      <i style="padding: 0 .25rem" class="material-icons pointer" tabindex="0" (click)="editLink()"
         (keyup.enter)="editLink()">edit</i>
    </div>
  `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: LinkPreviewComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'tip-link-preview',
                    template: `
    <div class="flex">
      <a class="v-center link-text" target="_blank" [href]="link">
        {{link}}
      </a>
      <i style="padding: 0 .25rem" class="material-icons pointer" tabindex="0" (click)="deleteLink()"
         (keyup.enter)="deleteLink()">link_off</i>
      <i style="padding: 0 .25rem" class="material-icons pointer" tabindex="0" (click)="copyLink()"
         (keyup.enter)="copyLink()">content_copy</i>
      <i style="padding: 0 .25rem" class="material-icons pointer" tabindex="0" (click)="editLink()"
         (keyup.enter)="editLink()">edit</i>
    </div>
  `,
                    changeDetection: ChangeDetectionStrategy.OnPush
                }]
        }], ctorParameters: function () {
        return [{ type: DialogRef }, { type: undefined, decorators: [{
                        type: Inject,
                        args: [TIP_DIALOG_DATA]
                    }] }];
    } });

class AutofocusDirective {
    constructor(element, ngZone) {
        this.element = element;
        this.ngZone = ngZone;
        this.enable = true;
    }
    ngAfterViewInit() {
        if (typeof this.enable === 'string' || this.enable) {
            this.ngZone.runOutsideAngular(() => setTimeout(() => this.element.nativeElement.focus()));
        }
    }
}
AutofocusDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: AutofocusDirective, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive });
AutofocusDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.1.1", type: AutofocusDirective, selector: "[tipAutofocus]", inputs: { enable: ["tipAutofocus", "enable"] }, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: AutofocusDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[tipAutofocus]'
                }]
        }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }]; }, propDecorators: { enable: [{
                type: Input,
                args: ['tipAutofocus']
            }] } });

// @dynamic
class LinkSelectComponent {
    constructor(dialogRef, data) {
        this.dialogRef = dialogRef;
        this.data = data;
        this.error = null;
        this.urlRegex = new RegExp('^(https?:\\/\\/)?' + // protocol
            '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name
            '((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address
            '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path
            '(\\?[;&a-z\\d%_.~+=-]*)?' + // query string
            '(\\#[-a-z\\d_]*)?$', 'i');
    }
    submit(value, event) {
        // Stop selected text being replaced by the enter
        event && event.preventDefault();
        if (!/^(https?:\/\/).*/.test(value))
            value = `https://${value}`;
        if (this.urlRegex.test(value)) {
            this.dialogRef.submit(value);
        }
        else {
            this.error = 'Invalid URL';
        }
    }
}
LinkSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: LinkSelectComponent, deps: [{ token: DialogRef }, { token: TIP_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
LinkSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: LinkSelectComponent, selector: "tip-link-select", ngImport: i0, template: `
    <div class="flex">
      <input class="tip-input" [placeholder]="data?.inputPlaceholder" tipAutofocus type="text" #input
             [value]="data.link"
             (keyup.enter)="submit(input.value, $event)">
      <button type="button" (click)="submit(input.value)" (keyup.enter)="submit(input.value)"
              class="tip-button margin-left-s">Apply
      </button>
    </div>
    <small style="color: var(--tip-warn-color)" *ngIf="error">{{error}}</small>
  `, isInline: true, directives: [{ type: AutofocusDirective, selector: "[tipAutofocus]", inputs: ["tipAutofocus"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: LinkSelectComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'tip-link-select',
                    template: `
    <div class="flex">
      <input class="tip-input" [placeholder]="data?.inputPlaceholder" tipAutofocus type="text" #input
             [value]="data.link"
             (keyup.enter)="submit(input.value, $event)">
      <button type="button" (click)="submit(input.value)" (keyup.enter)="submit(input.value)"
              class="tip-button margin-left-s">Apply
      </button>
    </div>
    <small style="color: var(--tip-warn-color)" *ngIf="error">{{error}}</small>
  `,
                    changeDetection: ChangeDetectionStrategy.OnPush,
                }]
        }], ctorParameters: function () {
        return [{ type: DialogRef }, { type: undefined, decorators: [{
                        type: Inject,
                        args: [TIP_DIALOG_DATA]
                    }] }];
    } });

class SideBySideComponent {
    constructor() {
        this.destroy$ = new Subject();
    }
    ngAfterViewInit() {
        this.editor.jsonChange
            .pipe(takeUntil(this.destroy$))
            .subscribe((content) => {
            this.preview.renderOutput(content);
        });
    }
    ngOnDestroy() {
        this.destroy$.next(true);
        this.destroy$.complete();
    }
}
SideBySideComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: SideBySideComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
SideBySideComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: SideBySideComponent, selector: "tip-side-by-side", queries: [{ propertyName: "editor", first: true, predicate: EditorComponent, descendants: true }, { propertyName: "preview", first: true, predicate: EditorPreviewComponent, descendants: true }], ngImport: i0, template: `
    <ng-content select="tip-editor"></ng-content>
    <div class="preview-wrapper">
      <div class="preview-heading v-center h-center">
        <h2 class="no-margin">Preview</h2>
      </div>
      <ng-content select="tip-editor-preview"></ng-content>
    </div>
  `, isInline: true, styles: [":host-context{display:flex;width:100%}.preview-heading{border-bottom:solid 1px var(--tip-border-color);padding:var(--tip-header-padding);height:var(--tip-header-height);box-sizing:border-box}.preview-wrapper{border:solid 1px var(--tip-border-color);border-left:none;width:50%}::ng-deep tip-side-by-side>tip-editor{width:50%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: SideBySideComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'tip-side-by-side',
                    changeDetection: ChangeDetectionStrategy.OnPush,
                    template: `
    <ng-content select="tip-editor"></ng-content>
    <div class="preview-wrapper">
      <div class="preview-heading v-center h-center">
        <h2 class="no-margin">Preview</h2>
      </div>
      <ng-content select="tip-editor-preview"></ng-content>
    </div>
  `,
                    styles: [`
    :host-context {
      display: flex;
      width: 100%;
    }

    .preview-heading {
      border-bottom: solid 1px var(--tip-border-color);
      padding: var(--tip-header-padding);
      height: var(--tip-header-height);
      box-sizing: border-box;
    }

    .preview-wrapper {
      border: solid 1px var(--tip-border-color);
      border-left: none;
      width: 50%;
    }

    ::ng-deep tip-side-by-side > tip-editor {
      width: 50%;
    }
  `]
                }]
        }], propDecorators: { editor: [{
                type: ContentChild,
                args: [EditorComponent]
            }], preview: [{
                type: ContentChild,
                args: [EditorPreviewComponent]
            }] } });

class UtilBreakLineComponent {
}
UtilBreakLineComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: UtilBreakLineComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
UtilBreakLineComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: UtilBreakLineComponent, selector: "tip-util-br", ngImport: i0, template: ``, isInline: true, styles: [":host-context{flex-basis:100%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: UtilBreakLineComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'tip-util-br',
                    template: ``,
                    styles: [`:host-context {
    flex-basis: 100%;
  }`],
                    changeDetection: ChangeDetectionStrategy.OnPush
                }]
        }] });

class UtilHorizontalDividerComponent {
}
UtilHorizontalDividerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: UtilHorizontalDividerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
UtilHorizontalDividerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: UtilHorizontalDividerComponent, selector: "tip-util-hr", ngImport: i0, template: `
    <hr>`, isInline: true, styles: [":host-context{display:contents}hr{flex-basis:calc(100% + var(--tip-header-padding) * 2);margin:var(--tip-header-padding) calc(var(--tip-header-padding) * -1);border:none;border-top:solid 1px var(--tip-border-color)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: UtilHorizontalDividerComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'tip-util-hr',
                    template: `
    <hr>`,
                    styles: [`
    :host-context {
      display: contents;
    }

    hr {
      flex-basis: calc(100% + var(--tip-header-padding) * 2);
      margin: var(--tip-header-padding) calc(var(--tip-header-padding) * -1);
      border: none;
      border-top: solid 1px var(--tip-border-color);
    }`],
                    changeDetection: ChangeDetectionStrategy.OnPush
                }]
        }] });

class UtilPaddingComponent {
}
UtilPaddingComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: UtilPaddingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
UtilPaddingComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: UtilPaddingComponent, selector: "tip-util-padding", ngImport: i0, template: ``, isInline: true, styles: [":host-context{width:calc(var(--tip-header-padding) / 2)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: UtilPaddingComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'tip-util-padding',
                    template: ``,
                    styles: [`:host-context {
    width: calc(var(--tip-header-padding) / 2);
  }`],
                    changeDetection: ChangeDetectionStrategy.OnPush
                }]
        }] });

class UtilSpacerComponent {
}
UtilSpacerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: UtilSpacerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
UtilSpacerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: UtilSpacerComponent, selector: "tip-util-spacer", ngImport: i0, template: ``, isInline: true, styles: [":host-context{flex-grow:1}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: UtilSpacerComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'tip-util-spacer',
                    template: ``,
                    styles: [`:host-context {
    flex-grow: 1;
  }`],
                    changeDetection: ChangeDetectionStrategy.OnPush
                }]
        }] });

class UtilVerticalDividerComponent {
}
UtilVerticalDividerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: UtilVerticalDividerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
UtilVerticalDividerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: UtilVerticalDividerComponent, selector: "tip-util-vr", ngImport: i0, template: ``, isInline: true, styles: [":host-context{width:1px;border-left:solid 1px var(--tip-border-color);height:var(--tip-header-height);margin-top:calc(var(--tip-header-padding) * -1);margin-bottom:calc(var(--tip-header-padding) * -1)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: UtilVerticalDividerComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'tip-util-vr',
                    template: ``,
                    styles: [`:host-context {
    width: 1px;
    border-left: solid 1px var(--tip-border-color);
    height: var(--tip-header-height);
    margin-top: calc(var(--tip-header-padding) * -1);
    margin-bottom: calc(var(--tip-header-padding) * -1);
  }`],
                    changeDetection: ChangeDetectionStrategy.OnPush
                }]
        }] });

const MENTION_FETCH = new InjectionToken('MENTION_FETCH');
// @dynamic
class MentionPreviewComponent {
    constructor(ngZone, cd, editor, fetchFunction) {
        this.ngZone = ngZone;
        this.cd = cd;
        this.editor = editor;
        this.fetchFunction = fetchFunction;
        this.queryResult = [];
    }
    handleKeyPress(event) {
        return false;
    }
    updateProps(props) {
        return __awaiter(this, void 0, void 0, function* () {
            this.mentionProps = props;
            this.queryResult = yield this.fetchFunction(props.query);
            this.cd.detectChanges();
        });
    }
    setMention(mention) {
        this.mentionProps.command(mention);
    }
}
MentionPreviewComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: MentionPreviewComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ChangeDetectorRef }, { token: i1$1.Editor }, { token: MENTION_FETCH }], target: i0.ɵɵFactoryTarget.Component });
MentionPreviewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: MentionPreviewComponent, selector: "tip-mention-select", ngImport: i0, template: `
    <button *ngFor="let item of queryResult" (click)="setMention(item)" (keyup.enter)="setMention(item)">
      {{item.id}}
    </button>
    <div *ngIf="queryResult.length === 0">
      No result was found
    </div>
  `, isInline: true, directives: [{ type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: MentionPreviewComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'tip-mention-select',
                    template: `
    <button *ngFor="let item of queryResult" (click)="setMention(item)" (keyup.enter)="setMention(item)">
      {{item.id}}
    </button>
    <div *ngIf="queryResult.length === 0">
      No result was found
    </div>
  `,
                    changeDetection: ChangeDetectionStrategy.OnPush
                }]
        }], ctorParameters: function () {
        return [{ type: i0.ChangeDetectorRef }, { type: i0.ChangeDetectorRef }, { type: i1$1.Editor }, { type: undefined, decorators: [{
                        type: Inject,
                        args: [MENTION_FETCH]
                    }] }];
    } });

class NgxTipTapEditorModule {
}
NgxTipTapEditorModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: NgxTipTapEditorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
NgxTipTapEditorModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: NgxTipTapEditorModule, declarations: [
        // Editor
        EditorComponent,
        EditorBodyComponent,
        EditorHeaderComponent,
        EditorFooterComponent,
        // Preview
        EditorPreviewComponent,
        SideBySideComponent,
        // Control alignment
        UtilBreakLineComponent,
        UtilHorizontalDividerComponent,
        UtilPaddingComponent,
        UtilSpacerComponent,
        UtilVerticalDividerComponent,
        // Controls
        ControlBoldComponent,
        ControlBulletListComponent,
        ControlCodeBlockComponent,
        ControlCodeComponent,
        ControlFormatComponent,
        HorizontalRuleControlComponent,
        ControlItalicComponent,
        ControlMentionComponent,
        ControlNumberListComponent,
        ControlStrikeComponent,
        ControlTasklistComponent,
        ControlTextAlignComponent,
        ControlUnderlineComponent,
        ControlLinkComponent,
        // Display
        DisplayCharacterCountComponent,
        // Common
        OptionComponent,
        SelectComponent,
        DialogComponent,
        // Private
        LinkSelectComponent,
        AutofocusDirective,
        LinkPreviewComponent,
        PopoverComponent,
        MentionPreviewComponent
    ], imports: [CommonModule,
        BrowserAnimationsModule], exports: [
        // Editor
        EditorComponent,
        EditorBodyComponent,
        EditorHeaderComponent,
        EditorFooterComponent,
        // Preview
        EditorPreviewComponent,
        SideBySideComponent,
        // Control alignment
        UtilBreakLineComponent,
        UtilHorizontalDividerComponent,
        UtilPaddingComponent,
        UtilSpacerComponent,
        UtilVerticalDividerComponent,
        // Controls
        ControlBoldComponent,
        ControlBulletListComponent,
        ControlCodeBlockComponent,
        ControlCodeComponent,
        ControlFormatComponent,
        HorizontalRuleControlComponent,
        ControlItalicComponent,
        ControlMentionComponent,
        ControlNumberListComponent,
        ControlStrikeComponent,
        ControlTasklistComponent,
        ControlTextAlignComponent,
        ControlUnderlineComponent,
        ControlLinkComponent,
        // Display
        DisplayCharacterCountComponent,
        // Common
        OptionComponent,
        SelectComponent
    ] });
NgxTipTapEditorModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: NgxTipTapEditorModule, providers: [], imports: [[
            CommonModule,
            BrowserAnimationsModule,
        ]] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: NgxTipTapEditorModule, decorators: [{
            type: NgModule,
            args: [{
                    declarations: [
                        // Editor
                        EditorComponent,
                        EditorBodyComponent,
                        EditorHeaderComponent,
                        EditorFooterComponent,
                        // Preview
                        EditorPreviewComponent,
                        SideBySideComponent,
                        // Control alignment
                        UtilBreakLineComponent,
                        UtilHorizontalDividerComponent,
                        UtilPaddingComponent,
                        UtilSpacerComponent,
                        UtilVerticalDividerComponent,
                        // Controls
                        ControlBoldComponent,
                        ControlBulletListComponent,
                        ControlCodeBlockComponent,
                        ControlCodeComponent,
                        ControlFormatComponent,
                        HorizontalRuleControlComponent,
                        ControlItalicComponent,
                        ControlMentionComponent,
                        ControlNumberListComponent,
                        ControlStrikeComponent,
                        ControlTasklistComponent,
                        ControlTextAlignComponent,
                        ControlUnderlineComponent,
                        ControlLinkComponent,
                        // Display
                        DisplayCharacterCountComponent,
                        // Common
                        OptionComponent,
                        SelectComponent,
                        DialogComponent,
                        // Private
                        LinkSelectComponent,
                        AutofocusDirective,
                        LinkPreviewComponent,
                        PopoverComponent,
                        MentionPreviewComponent,
                    ],
                    imports: [
                        CommonModule,
                        BrowserAnimationsModule,
                    ],
                    exports: [
                        // Editor
                        EditorComponent,
                        EditorBodyComponent,
                        EditorHeaderComponent,
                        EditorFooterComponent,
                        // Preview
                        EditorPreviewComponent,
                        SideBySideComponent,
                        // Control alignment
                        UtilBreakLineComponent,
                        UtilHorizontalDividerComponent,
                        UtilPaddingComponent,
                        UtilSpacerComponent,
                        UtilVerticalDividerComponent,
                        // Controls
                        ControlBoldComponent,
                        ControlBulletListComponent,
                        ControlCodeBlockComponent,
                        ControlCodeComponent,
                        ControlFormatComponent,
                        HorizontalRuleControlComponent,
                        ControlItalicComponent,
                        ControlMentionComponent,
                        ControlNumberListComponent,
                        ControlStrikeComponent,
                        ControlTasklistComponent,
                        ControlTextAlignComponent,
                        ControlUnderlineComponent,
                        ControlLinkComponent,
                        // Display
                        DisplayCharacterCountComponent,
                        // Common
                        OptionComponent,
                        SelectComponent,
                    ],
                    providers: []
                }]
        }] });

class TipBaseExtension {
    constructor() {
        this.destroy$ = new Subject();
    }
    static create(extension, extensionOptions) {
        return {
            options: extensionOptions,
            angularExtension: extension,
            build(parentInjector) {
                const injector = Injector.create({
                    providers: [{ provide: this.angularExtension }],
                    parent: parentInjector
                });
                const injectedExtension = injector.get(this.angularExtension);
                injectedExtension.options = this.options;
                injectedExtension.nativeExtension = injectedExtension.createExtension(injectedExtension.options);
                return injectedExtension;
            }
        };
    }
    set options(value) {
        if (this._options)
            throw new Error(`${this.constructor.name} already has the options set. Don't try to set it twice.`);
        this._options = this.defaultOptions ? deepMerge(this.defaultOptions, value) : value;
    }
    get options() {
        return this._options;
    }
    set editor(value) {
        if (this._editor)
            throw new Error(`${this.constructor.name} already has the editor set. Don't try to set it twice.`);
        this._editor = value;
        this._editor.on('destroy', () => {
            this.onEditorDestroy && this.onEditorDestroy();
            this.destroy$.next(true);
            this.destroy$.complete();
        });
        this.onEditorReady && this.onEditorReady();
    }
    get editor() {
        return this._editor;
    }
    set nativeExtension(value) {
        if (this._nativeExtension)
            throw new Error(`${this.constructor.name} already has a nativeExtension assigned to it. Don't try to assign it twice`);
        this._nativeExtension = value;
    }
    get nativeExtension() {
        return this._nativeExtension;
    }
}
class AdvancedBaseExtension extends TipBaseExtension {
    /**
     * Inject the provided component at any position in the dom
     * @param component The component which should be injected
     * @param injectionPoint The point you want to inject the component into (this.document.body for example)
     */
    createAndInsertIntoDom(component, injectionPoint) {
        const componentRef = this.createComponent(component);
        return this.insertComponent(componentRef, injectionPoint);
    }
    insertComponent(componentRef, injectionPoint) {
        const appRef = this.injector.get(ApplicationRef);
        appRef.attachView(componentRef.hostView);
        const domElement = componentRef.hostView.rootNodes[0];
        injectionPoint.appendChild(domElement);
        const ngZone = this.injector.get(NgZone);
        return {
            remove: () => {
                ngZone.run(() => {
                    appRef.detachView(componentRef.hostView);
                    componentRef.destroy();
                });
            }
        };
    }
    createComponent(component, additionalProviders = []) {
        const componentFactoryResolver = this.injector.get(ComponentFactoryResolver);
        const componentFactory = componentFactoryResolver.resolveComponentFactory(component);
        const injector = Injector.create({
            providers: additionalProviders,
            parent: this.injector
        });
        return componentFactory.create(injector);
    }
}

// @dynamic
class TipDialogService {
    constructor(componentFactoryResolver, appRef, injector, document) {
        this.componentFactoryResolver = componentFactoryResolver;
        this.appRef = appRef;
        this.injector = injector;
        this.document = document;
    }
    openDialog(component, config = {}) {
        // Fill with default values
        const newConfig = Object.assign({
            type: 'dialog',
            autoClose: true,
            maxWidth: '1000px',
            width: '50%',
            backdropColor: 'var(--tip-overlay-color)',
            position: 'center'
        }, config);
        return this.createAndAttachComponent(component, newConfig, DialogComponent);
    }
    openPopover(component, config) {
        const newConfig = Object.assign({
            type: 'popover',
            autoClose: true,
            maxWidth: 'auto',
            width: 'auto',
            backdropColor: 'transparent',
        }, config);
        return this.createAndAttachComponent(component, newConfig, PopoverComponent);
    }
    /**
     * @param component The component which will be displayed
     * @param config The config of the dialog
     * @param wrapperComponent The wrapper component which will encapsulate the user component
     */
    createAndAttachComponent(component, config, wrapperComponent) {
        const dialogReference = {};
        const dialogRef = new DialogRef(component, this.appRef, dialogReference, config);
        const componentInjector = Injector.create({
            providers: [
                { provide: TIP_DIALOG_DATA, useValue: config.data },
                { provide: DialogRef, useValue: dialogRef }
            ],
            parent: this.injector
        });
        // Create the component wrapper which in turn will attach the user component to the view
        const componentFactory = this.componentFactoryResolver.resolveComponentFactory(wrapperComponent);
        const componentRef = componentFactory.create(componentInjector);
        dialogReference.component = componentRef;
        this.appRef.attachView(componentRef.hostView);
        // Attach the component wrapper
        const domElement = componentRef.hostView.rootNodes[0];
        this.document.body.appendChild(domElement);
        return dialogRef;
    }
}
TipDialogService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: TipDialogService, deps: [{ token: i0.ComponentFactoryResolver }, { token: i0.ApplicationRef }, { token: i0.Injector }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
TipDialogService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: TipDialogService, providedIn: 'root' });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: TipDialogService, decorators: [{
            type: Injectable,
            args: [{ providedIn: 'root' }]
        }], ctorParameters: function () {
        return [{ type: i0.ComponentFactoryResolver }, { type: i0.ApplicationRef }, { type: i0.Injector }, { type: Document, decorators: [{
                        type: Inject,
                        args: [DOCUMENT]
                    }] }];
    } });

// @dynamic
class NgxMention extends AdvancedBaseExtension {
    // tslint:enable:member-ordering
    constructor(injector, ngZone, document, dialogService) {
        super();
        this.injector = injector;
        this.ngZone = ngZone;
        this.document = document;
        this.dialogService = dialogService;
        // tslint:disable:member-ordering
        this._onClick$ = new Subject();
        this.onClick$ = this._onClick$.asObservable();
        this.defaultOptions = {
            HTMLAttributes: { class: 'mention' },
            previewComponent: MentionPreviewComponent
        };
    }
    createExtension(extensionOptions) {
        const extendedMention = this.extendMention();
        const mentionOptions = this.configureMention(extensionOptions);
        return extendedMention.configure(mentionOptions);
    }
    extendMention() {
        const listeners = [];
        const self = this;
        return Mention.extend({
            // Remove listeners
            onDestroy: () => listeners.forEach(l => l.unsubscribe()),
            renderHTML({ node, HTMLAttributes }) {
                const span = document.createElement('span');
                span.textContent = this.options.renderLabel({ options: this.options, node });
                // Subscribe to click events and pass them to the onClick Subject
                const subscription = fromEvent(span, 'click').subscribe(() => self._onClick$.next(node.attrs));
                listeners.push(subscription);
                const attributes = mergeAttributes({ 'data-mention': '' }, this.options.HTMLAttributes, HTMLAttributes);
                Object.keys(attributes).forEach(key => span.setAttribute(key, attributes[key]));
                return span;
            },
            addCommands() {
                return {
                    setMention: ({ range, props }) => ({ commands, state }) => {
                        // If range was not provided just insert at the current position
                        if (!range)
                            range = state.selection;
                        return commands.insertContentAt(range, [
                            {
                                type: 'mention',
                                attrs: props,
                            },
                            {
                                type: 'text',
                                text: ' ',
                            },
                        ]);
                    }
                };
            },
        });
    }
    configureMention(_a) {
        var mentionOptions = __rest(_a, []);
        // Check if the fetch function is provided and if not don't register events for it
        if (mentionOptions.mentionFetchFunction) {
            mentionOptions.suggestion = Object.assign({ render: () => {
                    let component;
                    let remove;
                    return this.ngZone.run(() => ({
                        onStart: props => {
                            component = this.createComponent(mentionOptions.previewComponent, [{
                                    provide: Editor,
                                    useValue: props.editor
                                }, {
                                    provide: MENTION_FETCH,
                                    useValue: mentionOptions.mentionFetchFunction
                                }]);
                            component.instance.updateProps(props);
                            remove = this.insertComponent(component, this.document.body);
                        },
                        onKeyDown: (props) => component.instance.handleKeyPress(props.event),
                        onUpdate: props => component.instance.updateProps(props),
                        onExit: () => remove.remove(),
                    }));
                } }, mentionOptions.suggestion);
        }
        return mentionOptions;
    }
}
NgxMention.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: NgxMention, deps: [{ token: i0.Injector }, { token: i0.NgZone }, { token: DOCUMENT }, { token: TipDialogService }], target: i0.ɵɵFactoryTarget.Injectable });
NgxMention.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: NgxMention });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: NgxMention, decorators: [{
            type: Injectable
        }], ctorParameters: function () {
        return [{ type: i0.Injector }, { type: i0.NgZone }, { type: Document, decorators: [{
                        type: Inject,
                        args: [DOCUMENT]
                    }] }, { type: TipDialogService }];
    } });

// @dynamic
class NgxLink extends TipBaseExtension {
    constructor(dialogService, eventService, ngZone, document) {
        super();
        this.dialogService = dialogService;
        this.eventService = eventService;
        this.ngZone = ngZone;
        this.document = document;
        this.defaultOptions = {
            ng: {
                inputPlaceholder: 'Input a link',
            }
        };
        this.createDialog = null;
        this.previewDialog = null;
        this.linkElement = null;
    }
    onEditorDestroy() {
        var _a;
        this.closeLinkPreview();
        (_a = this.createDialog) === null || _a === void 0 ? void 0 : _a.cancel();
    }
    onEditorReady() {
        this.eventService.registerShortcut('Mod-k')
            .pipe(tap((e) => e.preventDefault()), filter(() => this.can()), takeUntil(this.destroy$)).subscribe(() => this.openCreateLinkDialog());
        fromEditorEvent(this.editor, 'transaction').pipe(takeUntil(this.destroy$), filter(e => !e.transaction.getMeta('blur'))).subscribe(({ editor: e }) => this.toggleLinkPreview(e));
    }
    createExtension(extensionOptions) {
        return Link.configure(extensionOptions.native);
    }
    openCreateLinkDialog() {
        return __awaiter(this, void 0, void 0, function* () {
            if (!this.editor)
                return;
            const link = getLinkFromCursorPosition(this.editor);
            const position = getSelectedEditorTextPosition(this.editor);
            if (!position)
                return;
            this.createDialog = this.ngZone.run(() => this.dialogService.openPopover(LinkSelectComponent, {
                width: 'auto',
                position: position.topCenter,
                autoClose: true,
                data: {
                    link,
                    inputPlaceholder: this.options.ng.inputPlaceholder
                }
            }));
            const result = yield this.createDialog.result$.toPromise();
            this.createDialog = null;
            if (result.status === 'canceled') {
                this.editor.commands.focus();
                return;
            }
            const { from, to } = this.editor.state.selection;
            this.editor.chain().focus()
                .extendMarkRange('link')
                .unsetLink()
                .setLink({ href: result.data })
                .setTextSelection({ from, to })
                .run();
        });
    }
    can() {
        var _a;
        if (!this.editor)
            return false;
        const active = this.isActive();
        const { from, to } = this.editor.state.selection;
        return !!((_a = this.editor) === null || _a === void 0 ? void 0 : _a.can().setLink({ href: '' })) && from !== to || from === to && active;
    }
    isActive() {
        return !!this.editor && 'href' in this.editor.getAttributes('link');
    }
    toggleLinkPreview(editor) {
        return __awaiter(this, void 0, void 0, function* () {
            if (
            // Link creation dialog is open
            this.createDialog ||
                // Not active
                !this.isActive() ||
                // Some text selected
                editor.view.state.selection.from !== editor.view.state.selection.to) {
                return this.closeLinkPreview();
            }
            // Get the link and the anchor element
            const link = getLinkFromCursorPosition(this.editor);
            const linkElement = getLinkDOMFromCursorPosition(this.editor, link);
            // Not a link element
            if (!linkElement) {
                return this.closeLinkPreview();
            }
            // Already open and no different link element selected
            if (this.previewDialog && linkElement === this.linkElement)
                return;
            // Different link element, so close the preview and create a new dialog
            this.closeLinkPreview();
            this.linkElement = linkElement;
            const position = linkElement.getBoundingClientRect();
            const previewDialog = this.ngZone.run(() => this.dialogService.openPopover(LinkPreviewComponent, {
                position: {
                    x: position.x + position.width / 2,
                    y: position.y
                },
                data: link
            }));
            // Prevent race conditions from overwriting the preview dialog
            this.previewDialog = previewDialog;
            // Get result of dialog
            const result = yield previewDialog.result$.toPromise();
            // Fixes race condition
            if (this.previewDialog === previewDialog) {
                this.closeLinkPreview();
            }
            if (result.data === 'delete') {
                this.editor.chain().focus().unsetLink().run();
            }
            else if (result.data === 'edit') {
                this.editor.commands.focus();
                yield this.openCreateLinkDialog();
            }
        });
    }
    closeLinkPreview() {
        this.linkElement = null;
        if (this.previewDialog) {
            this.ngZone.run(() => this.previewDialog.cancel());
            this.previewDialog = null;
        }
    }
}
NgxLink.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: NgxLink, deps: [{ token: TipDialogService }, { token: TiptapEventService }, { token: i0.NgZone }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
NgxLink.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: NgxLink });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: NgxLink, decorators: [{
            type: Injectable
        }], ctorParameters: function () {
        return [{ type: TipDialogService }, { type: TiptapEventService }, { type: i0.NgZone }, { type: Document, decorators: [{
                        type: Inject,
                        args: [DOCUMENT]
                    }] }];
    } });

/*
 * Public API Surface of ngx-tiptap-editor
 */

/**
 * Generated bundle index. Do not edit.
 */

export { AdvancedBaseExtension, BaseControl, ButtonBaseControl, ControlBoldComponent, ControlBulletListComponent, ControlCodeBlockComponent, ControlCodeComponent, ControlFormatComponent, ControlItalicComponent, ControlLinkComponent, ControlMentionComponent, ControlNumberListComponent, ControlStrikeComponent, ControlTasklistComponent, ControlTextAlignComponent, ControlUnderlineComponent, DisplayCharacterCountComponent, EditorBodyComponent, EditorComponent, EditorFooterComponent, EditorHeaderComponent, EditorPreviewComponent, ExtendedBaseControl, GLOBAL_ANGULAR_EXTENSIONS, GLOBAL_EXTENSIONS, HorizontalRuleControlComponent, NgxLink, NgxMention, NgxTipTapEditorModule, OptionComponent, SelectBaseControl, SelectComponent, SideBySideComponent, TipBaseExtension, TiptapEventService, TiptapExtensionService, UtilBreakLineComponent, UtilHorizontalDividerComponent, UtilPaddingComponent, UtilSpacerComponent, UtilVerticalDividerComponent };
//# sourceMappingURL=ngx-tiptap-editor.mjs.map