(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/common'), require('@wm/components/base'), require('@angular/forms'), require('@wm/core'), require('@wm/components/input'), require('lodash-es')) :
    typeof define === 'function' && define.amd ? define(['exports', '@angular/core', '@angular/common', '@wm/components/base', '@angular/forms', '@wm/core', '@wm/components/input', 'lodash-es'], factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.wm = global.wm || {}, global.wm.components = global.wm.components || {}, global.wm.components.basic = global.wm.components.basic || {}, global.wm.components.basic.richtexteditor = {}), global.ng.core, global.ng.common, global.wm.components.base, global.ng.forms, global.wm.core, global.wm.components.input, global._));
})(this, (function (exports, i0, i2, i1, forms, core, input, lodashEs) { 'use strict';

    function _interopNamespaceDefault(e) {
        var n = Object.create(null);
        if (e) {
            Object.keys(e).forEach(function (k) {
                if (k !== 'default') {
                    var d = Object.getOwnPropertyDescriptor(e, k);
                    Object.defineProperty(n, k, d.get ? d : {
                        enumerable: true,
                        get: function () { return e[k]; }
                    });
                }
            });
        }
        n.default = e;
        return Object.freeze(n);
    }

    var i0__namespace = /*#__PURE__*/_interopNamespaceDefault(i0);
    var i2__namespace = /*#__PURE__*/_interopNamespaceDefault(i2);
    var i1__namespace = /*#__PURE__*/_interopNamespaceDefault(i1);

    const richTextProps = new Map([
        ['class', i1.PROP_STRING],
        ['datavaluesource', i1.PROP_ANY],
        ['datavalue', i1.PROP_STRING],
        ['height', i1.PROP_STRING],
        ['hint', i1.PROP_STRING],
        ['arialabel', i1.PROP_STRING],
        ['name', i1.PROP_STRING],
        ['placeholder', i1.PROP_STRING],
        ['readonly', i1.PROP_BOOLEAN],
        ['show', { value: true, ...i1.PROP_BOOLEAN }],
        ['showpreview', { value: false, ...i1.PROP_BOOLEAN }],
        ['tabindex', { value: 0, ...i1.PROP_NUMBER }]
    ]);
    const registerProps = () => {
        i1.register('wm-richtexteditor', richTextProps);
        i1.registerFormWidget(core.FormWidgetType.RICHTEXT, new Map(richTextProps));
    };

    const _c0 = ["wmRichTextEditor", ""];
    function RichTextEditorComponent_div_1_Template(rf, ctx) { if (rf & 1) {
        i0__namespace.ɵɵelement(0, "div", 3);
    } if (rf & 2) {
        const ctx_r0 = i0__namespace.ɵɵnextContext();
        i0__namespace.ɵɵproperty("innerHTML", ctx_r0.proxyModel, i0__namespace.ɵɵsanitizeHtml);
    } }
    const WIDGET_INFO = { widgetType: 'wm-richtexteditor', hostClass: 'app-richtexteditor clearfix' };
    const getChangeEvt = () => {
        let changeEvt;
        // for IE the event constructor doesn't work so use the createEvent proto
        if (typeof (Event) === 'function') {
            changeEvt = new Event('change');
        }
        else {
            changeEvt = document.createEvent('Event');
            changeEvt.initEvent('change', true, true);
        }
        return changeEvt;
    };
    const overrideSummerNote = () => {
        if (!$.summernote.__overidden) {
            // override summernote methods
            const origFn = $.summernote.ui_template().button.bind($.summernote);
            $.summernote.ui_template.button = (...args) => {
                const retVal = origFn(...args);
                const origCallback = retVal.callback;
                retVal.callback = ($node, options) => {
                    // add bs3 btn class to the buttons
                    $node.addClass('btn');
                    return origCallback($node, options);
                };
                return retVal;
            };
            $.summernote.__overidden = true;
        }
    };
    class RichTextEditorComponent extends input.BaseFormCustomComponent {
        static { this.initializeProps = registerProps(); }
        get htmlcontent() {
            return this.performEditorOperation('code');
        }
        // @ts-ignore
        get datavalue() {
            return this.htmlcontent;
        }
        // @ts-ignore
        set datavalue(nv) {
            if (nv !== undefined && nv !== null) {
                this.$hiddenInputEle.val(nv);
                this.performEditorOperation('reset');
                this.performEditorOperation('code', nv);
            }
        }
        constructor(inj, sanitizePipe, ngZone, explicitContext) {
            super(inj, WIDGET_INFO, explicitContext);
            this.sanitizePipe = sanitizePipe;
            this.ngZone = ngZone;
            this._operationStack = [];
            this.isEditorLoaded = false;
            this.EDITOR_DEFAULT_OPTIONS = {
                toolbar: [
                    // [groupName, [list of button]]
                    ['misc', ['undo', 'redo']],
                    ['style', ['style']],
                    ['fontname', ['fontname']],
                    ['fontsize', ['fontsize']],
                    ['height', ['height']],
                    ['style', ['bold', 'italic', 'underline', 'clear']],
                    ['font', ['strikethrough', 'superscript', 'subscript']],
                    ['color', ['color']],
                    ['insert', ['table', 'picture', 'link', 'video', 'hr']],
                    ['para', ['ul', 'ol', 'paragraph']],
                    ['misc', ['codeview', 'fullscreen', 'help']]
                ],
                callbacks: {
                    onInit: () => {
                        this.isEditorLoaded = true;
                        if (this._operationStack.length) {
                            this._operationStack.forEach(operationParam => {
                                const key = Array.from(operationParam.keys())[0], val = operationParam.get(key);
                                this.performEditorOperation(key, val);
                            });
                            this._operationStack = [];
                        }
                    },
                    onChange: (contents, editable) => {
                        this.proxyModel = this.sanitizePipe.transform(contents, i0.SecurityContext.HTML);
                        this.invokeOnChange(contents, getChangeEvt(), true);
                        this.invokeOnTouched();
                    }
                },
                fontNames: ['Arial', 'Arial Black', 'Comic Sans MS', 'Courier New', 'Merriweather'],
                placeholder: 'write here...',
                minHeight: 100,
                disableResizeEditor: true
            };
            i1.styler(this.nativeElement, this, i1.APPLY_STYLES_TYPE.CONTAINER, ['height']);
            overrideSummerNote();
        }
        ngOnInit() {
            this.$richTextEditor = $(this.nativeElement.querySelector('[richTextEditor]'));
            this.$hiddenInputEle = $(this.nativeElement.querySelector('input.model-holder'));
            super.ngOnInit();
            this.initEditor();
            $('.note-editable').attr('aria-label', 'textbox');
        }
        initEditor() {
            this.ngZone.runOutsideAngular(() => {
                this.invokeEventCallback('beforerender', { '$event': {} });
                this.$richTextEditor.summernote(this.EDITOR_DEFAULT_OPTIONS);
            });
        }
        getDefaultOptions() {
            return this.EDITOR_DEFAULT_OPTIONS;
        }
        getLib() {
            return 'summernote';
        }
        overrideDefaults(options) {
            lodashEs.extend(this.EDITOR_DEFAULT_OPTIONS, options);
        }
        onPropertyChange(key, nv, ov) {
            if (key === 'placeholder') {
                this.performEditorOperation('placeholder', nv);
            }
            else if (key === 'disabled' || key === 'readonly') {
                this.performEditorOperation(nv ? 'disable' : 'enable');
            }
            else {
                super.onPropertyChange(key, nv, ov);
            }
        }
        onStyleChange(key, nv, ov) {
            if (key === 'height') {
                this.performEditorOperation('height', nv);
            }
        }
        performEditorOperation(key, value) {
            if (this.isEditorLoaded) {
                if (key === 'height') {
                    core.setCSS(this.nativeElement.querySelector('div.note-editable'), key, value, true);
                }
                else if (key === 'placeholder') {
                    core.setAttr(this.nativeElement, key, value);
                    core.setHtml(this.nativeElement.querySelector('div.note-placeholder'), value, true);
                }
                else {
                    // if editor content is empty then summernote('code') is returning empty p tags like <p></br></p>. So checking for empty and returning undefined.
                    if (arguments.length === 1 && key === 'code' && this.$richTextEditor.summernote('isEmpty')) {
                        const content = this.$richTextEditor.summernote('code');
                        return content === '' ? content : undefined;
                    }
                    return this.$richTextEditor.summernote(key, value);
                }
            }
            else {
                const op = new Map();
                op.set(key, value);
                this._operationStack.push(op);
                return;
            }
        }
        getCurrentPosition() {
            return this.performEditorOperation('createRange');
        }
        undo() {
            this.performEditorOperation('undo');
        }
        focus() {
            this.performEditorOperation('focus');
        }
        ngOnDestroy() {
            this.performEditorOperation('destroy');
            super.ngOnDestroy();
        }
        static { this.ɵfac = function RichTextEditorComponent_Factory(t) { return new (t || RichTextEditorComponent)(i0__namespace.ɵɵdirectiveInject(i0__namespace.Injector), i0__namespace.ɵɵdirectiveInject(i1__namespace.SanitizePipe), i0__namespace.ɵɵdirectiveInject(i0__namespace.NgZone), i0__namespace.ɵɵdirectiveInject('EXPLICIT_CONTEXT', 8)); }; }
        static { this.ɵcmp = /*@__PURE__*/ i0__namespace.ɵɵdefineComponent({ type: RichTextEditorComponent, selectors: [["div", "wmRichTextEditor", ""]], exportAs: ["wmRichTextEditor"], features: [i0__namespace.ɵɵProvidersFeature([
                    i1.provideAs(RichTextEditorComponent, forms.NG_VALUE_ACCESSOR, true),
                    i1.provideAsWidgetRef(RichTextEditorComponent)
                ]), i0__namespace.ɵɵInheritDefinitionFeature], attrs: _c0, decls: 3, vars: 2, consts: [["richTextEditor", ""], ["class", "ta-preview", 3, "innerHTML", 4, "ngIf"], ["hidden", "", 1, "model-holder", 3, "disabled"], [1, "ta-preview", 3, "innerHTML"]], template: function RichTextEditorComponent_Template(rf, ctx) { if (rf & 1) {
                i0__namespace.ɵɵelement(0, "div", 0);
                i0__namespace.ɵɵtemplate(1, RichTextEditorComponent_div_1_Template, 1, 1, "div", 1);
                i0__namespace.ɵɵelement(2, "input", 2);
            } if (rf & 2) {
                i0__namespace.ɵɵadvance();
                i0__namespace.ɵɵproperty("ngIf", ctx.showpreview);
                i0__namespace.ɵɵadvance();
                i0__namespace.ɵɵproperty("disabled", ctx.disabled);
            } }, dependencies: [i2__namespace.NgIf], encapsulation: 2 }); }
    }
    (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0__namespace.ɵsetClassMetadata(RichTextEditorComponent, [{
            type: i0.Component,
            args: [{ selector: 'div[wmRichTextEditor]', providers: [
                        i1.provideAs(RichTextEditorComponent, forms.NG_VALUE_ACCESSOR, true),
                        i1.provideAsWidgetRef(RichTextEditorComponent)
                    ], exportAs: 'wmRichTextEditor', template: "<div richTextEditor></div>\n<div [innerHTML]=\"proxyModel\" class=\"ta-preview\" *ngIf=\"showpreview\"></div>\n<input class=\"model-holder\" [disabled]=\"disabled\" hidden>\n" }]
        }], () => [{ type: i0__namespace.Injector }, { type: i1__namespace.SanitizePipe }, { type: i0__namespace.NgZone }, { type: undefined, decorators: [{
                    type: i0.Inject,
                    args: ['EXPLICIT_CONTEXT']
                }, {
                    type: i0.Optional
                }] }], null); })();
    (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0__namespace.ɵsetClassDebugInfo(RichTextEditorComponent, { className: "RichTextEditorComponent", filePath: "rich-text-editor.component.ts", lineNumber: 59 }); })();

    const components = [
        RichTextEditorComponent
    ];
    class RichTextEditorModule {
        static { this.ɵfac = function RichTextEditorModule_Factory(t) { return new (t || RichTextEditorModule)(); }; }
        static { this.ɵmod = /*@__PURE__*/ i0__namespace.ɵɵdefineNgModule({ type: RichTextEditorModule }); }
        static { this.ɵinj = /*@__PURE__*/ i0__namespace.ɵɵdefineInjector({ imports: [i2.CommonModule,
                i1.WmComponentsModule] }); }
    }
    (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0__namespace.ɵsetClassMetadata(RichTextEditorModule, [{
            type: i0.NgModule,
            args: [{
                    imports: [
                        i2.CommonModule,
                        i1.WmComponentsModule
                    ],
                    declarations: [...components],
                    exports: [...components]
                }]
        }], null, null); })();
    (function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0__namespace.ɵɵsetNgModuleScope(RichTextEditorModule, { declarations: [RichTextEditorComponent], imports: [i2.CommonModule,
            i1.WmComponentsModule], exports: [RichTextEditorComponent] }); })();

    exports.RichTextEditorComponent = RichTextEditorComponent;
    exports.RichTextEditorModule = RichTextEditorModule;

}));
