ngx-tiptap-editor
Version:
[](https://github.com/HuiiBuh/ngx-tiptap-editor/actions/workflows/publish.yml) [ => {
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