UNPKG

@joniras/ngx-editor2

Version:
1,090 lines (1,056 loc) 93.3 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/common'), require('@angular/forms'), require('ngx-bootstrap/popover'), require('@angular/common/http'), require('rxjs'), require('@fortawesome/free-solid-svg-icons'), require('@fortawesome/free-regular-svg-icons'), require('@fortawesome/free-brands-svg-icons'), require('@fortawesome/angular-fontawesome')) : typeof define === 'function' && define.amd ? define('@joniras/ngx-editor2', ['exports', '@angular/core', '@angular/common', '@angular/forms', 'ngx-bootstrap/popover', '@angular/common/http', 'rxjs', '@fortawesome/free-solid-svg-icons', '@fortawesome/free-regular-svg-icons', '@fortawesome/free-brands-svg-icons', '@fortawesome/angular-fontawesome'], factory) : (global = global || self, factory((global.joniras = global.joniras || {}, global.joniras['ngx-editor2'] = {}), global.ng.core, global.ng.common, global.ng.forms, global.popover, global.ng.common.http, global.rxjs, global.freeSolidSvgIcons, global.freeRegularSvgIcons, global.freeBrandsSvgIcons, global.angularFontawesome)); }(this, (function (exports, core, common, forms, popover, http, rxjs, freeSolidSvgIcons, freeRegularSvgIcons, freeBrandsSvgIcons, angularFontawesome) { 'use strict'; /*! ***************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ /* global Reflect, Promise */ var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; function __extends(d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } var __assign = function() { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; function __rest(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; } function __decorate(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; } function __param(paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } } function __metadata(metadataKey, metadataValue) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); } function __awaiter(thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } function __generator(thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } } function __exportStar(m, exports) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } function __values(o) { var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; if (m) return m.call(o); return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; } function __read(o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; } function __spread() { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; } function __spreadArrays() { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; }; function __await(v) { return this instanceof __await ? (this.v = v, this) : new __await(v); } function __asyncGenerator(thisArg, _arguments, generator) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), i, q = []; return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } function fulfill(value) { resume("next", value); } function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } } function __asyncDelegator(o) { var i, p; return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } } function __asyncValues(o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator], i; return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } } function __makeTemplateObject(cooked, raw) { if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; }; function __importStar(mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result.default = mod; return result; } function __importDefault(mod) { return (mod && mod.__esModule) ? mod : { default: mod }; } /** * enable or disable toolbar based on configuration * * @param value toolbar item * @param toolbar toolbar configuration object */ function canEnableToolbarOptions(value, toolbar) { if (value) { if (toolbar['length'] === 0) { return true; } else { var found = toolbar.filter(function (array) { return array.indexOf(value) !== -1; }); return !!found.length; } } else { return false; } } /** * set editor configuration * * @param value configuration via [config] propertyify * @param ngxTextEditorConfig default editor configuration * @param input direct configuration inputs via directives */ function getEditorConfiguration(value, ngxTextEditorConfig, input) { for (var i in ngxTextEditorConfig) { if (i) { if (input[i] !== undefined) { value[i] = input[i]; } if (!value.hasOwnProperty(i)) { value[i] = ngxTextEditorConfig[i]; } } } return value; } /** * return vertical if the element is the resizer property is set to basic * * @param resizer type of resizer, either basic or stack */ function canResize(resizer) { if (resizer === 'basic') { return 'vertical'; } return false; } /** * save selection when the editor is focussed out */ function saveSelection() { if (window.getSelection) { var sel = window.getSelection(); if (sel.getRangeAt && sel.rangeCount) { return sel.getRangeAt(0); } } else if (document.getSelection && document.createRange) { return document.createRange(); } return null; } /** * restore selection when the editor is focussed in * * @param range saved selection when the editor is focussed out */ function restoreSelection(range) { if (range) { if (window.getSelection) { var sel = window.getSelection(); sel.removeAllRanges(); sel.addRange(range); return true; } else if (document.getSelection && range.select) { range.select(); return true; } } else { return false; } } var Utils = /*#__PURE__*/Object.freeze({ __proto__: null, canEnableToolbarOptions: canEnableToolbarOptions, getEditorConfiguration: getEditorConfiguration, canResize: canResize, saveSelection: saveSelection, restoreSelection: restoreSelection }); var CommandExecutorService = /** @class */ (function () { /** * * @param _http HTTP Client for making http requests */ function CommandExecutorService(_http) { this._http = _http; /** saves the selection from the editor when focused out */ this.savedSelection = undefined; } /** * executes command from the toolbar * * @param command command to be executed */ CommandExecutorService.prototype.execute = function (command) { if (!this.savedSelection && command !== 'enableObjectResizing') { throw new Error('Range out of Editor'); } if (command === 'enableObjectResizing') { document.execCommand('enableObjectResizing', true); } if (command === 'blockquote') { document.execCommand('formatBlock', false, 'blockquote'); } if (command === 'removeBlockquote') { document.execCommand('formatBlock', false, 'div'); } if (command === 'h1') { document.execCommand('formatBlock', false, 'h1'); } if (command === 'h2') { document.execCommand('formatBlock', false, 'h2'); } if (command === 'h3') { document.execCommand('formatBlock', false, 'h3'); } if (command === 'clear') { document.execCommand('formatBlock', false, 'div'); } document.execCommand(command, false, null); }; /** * inserts image in the editor * * @param imageURI url of the image to be inserted */ CommandExecutorService.prototype.insertImage = function (imageURI) { if (this.savedSelection) { if (imageURI) { var restored = restoreSelection(this.savedSelection); if (restored) { var img = document.createElement('img'); img.src = imageURI; img.style.width = 'auto'; var inserted = this.insertHtml(img.outerHTML); if (!inserted) { throw new Error('Invalid URL'); } } } } else { throw new Error('Range out of the editor'); } }; /** * inserts image in the editor * * @param videParams url of the image to be inserted */ CommandExecutorService.prototype.insertVideo = function (videParams) { if (this.savedSelection) { if (videParams) { var restored = restoreSelection(this.savedSelection); if (restored) { if (this.isYoutubeLink(videParams.videoUrl)) { var youtubeURL = '<iframe width="' + videParams.width + '" height="' + videParams.height + '"' + 'src="' + videParams.videoUrl + '"></iframe>'; this.insertHtml(youtubeURL); } else if (this.checkTagSupportInBrowser('video')) { if (this.isValidURL(videParams.videoUrl)) { var videoSrc = '<video width="' + videParams.width + '" height="' + videParams.height + '"' + ' controls="true"><source src="' + videParams.videoUrl + '"></video>'; this.insertHtml(videoSrc); } else { throw new Error('Invalid video URL'); } } else { throw new Error('Unable to insert video'); } } } } else { throw new Error('Range out of the editor'); } }; /** * checks the input url is a valid youtube URL or not * * @param url Youtue URL */ CommandExecutorService.prototype.isYoutubeLink = function (url) { var ytRegExp = /^(http(s)?:\/\/)?((w){3}.)?youtu(be|.be)?(\.com)?\/.+/; return ytRegExp.test(url); }; /** * check whether the string is a valid url or not * @param url url */ CommandExecutorService.prototype.isValidURL = function (url) { var urlRegExp = /(http|https):\/\/(\w+:{0,1}\w*)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%!\-\/]))?/; return urlRegExp.test(url); }; /** * uploads image to the server * * @param file file that has to be uploaded * @param endPoint enpoint to which the image has to be uploaded */ CommandExecutorService.prototype.uploadImage = function (file, endPoint) { if (!endPoint) { throw new Error('Image Endpoint isn`t provided or invalid'); } var formData = new FormData(); if (file) { formData.append('file', file); var req = new http.HttpRequest('POST', endPoint, formData, { reportProgress: true }); return this._http.request(req); } else { throw new Error('Invalid Image'); } }; /** * inserts link in the editor * * @param params parameters that holds the information for the link */ CommandExecutorService.prototype.createLink = function (params) { if (this.savedSelection) { /** * check whether the saved selection contains a range or plain selection */ if (params.urlNewTab) { var newUrl = '<a href="' + params.urlLink + '" target="_blank">' + params.urlText + '</a>'; if (document.getSelection().type !== 'Range') { var restored = restoreSelection(this.savedSelection); if (restored) { this.insertHtml(newUrl); } } else { throw new Error('Only new links can be inserted. You cannot edit URL`s'); } } else { var restored = restoreSelection(this.savedSelection); if (restored) { document.execCommand('createLink', false, params.urlLink); } } } else { throw new Error('Range out of the editor'); } }; /** * insert color either font or background * * @param color color to be inserted * @param where where the color has to be inserted either text/background */ CommandExecutorService.prototype.insertColor = function (color, where) { if (this.savedSelection) { var restored = restoreSelection(this.savedSelection); if (restored && this.checkSelection()) { if (where === 'textColor') { document.execCommand('foreColor', false, color); } else { document.execCommand('hiliteColor', false, color); } } } else { throw new Error('Range out of the editor'); } }; /** * set font size for text * * @param fontSize font-size to be set */ CommandExecutorService.prototype.setFontSize = function (fontSize) { if (this.savedSelection && this.checkSelection()) { var deletedValue = this.deleteAndGetElement(); if (deletedValue) { var restored = restoreSelection(this.savedSelection); if (restored) { if (this.isNumeric(fontSize)) { var fontPx = '<span style="font-size: ' + fontSize + 'px;">' + deletedValue + '</span>'; this.insertHtml(fontPx); } else { var fontPx = '<span style="font-size: ' + fontSize + ';">' + deletedValue + '</span>'; this.insertHtml(fontPx); } } } } else { throw new Error('Range out of the editor'); } }; /** * set font name/family for text * * @param fontName font-family to be set */ CommandExecutorService.prototype.setFontName = function (fontName) { if (this.savedSelection && this.checkSelection()) { var deletedValue = this.deleteAndGetElement(); if (deletedValue) { var restored = restoreSelection(this.savedSelection); if (restored) { if (this.isNumeric(fontName)) { var fontFamily = '<span style="font-family: ' + fontName + 'px;">' + deletedValue + '</span>'; this.insertHtml(fontFamily); } else { var fontFamily = '<span style="font-family: ' + fontName + ';">' + deletedValue + '</span>'; this.insertHtml(fontFamily); } } } } else { throw new Error('Range out of the editor'); } }; /** insert HTML */ CommandExecutorService.prototype.insertHtml = function (html) { var isHTMLInserted = document.execCommand('insertHTML', false, html); if (!isHTMLInserted) { throw new Error('Unable to perform the operation'); } return isHTMLInserted; }; /** * check whether the value is a number or string * if number return true * else return false */ CommandExecutorService.prototype.isNumeric = function (value) { return /^-{0,1}\d+$/.test(value); }; /** delete the text at selected range and return the value */ CommandExecutorService.prototype.deleteAndGetElement = function () { var slectedText; if (this.savedSelection) { slectedText = this.savedSelection.toString(); this.savedSelection.deleteContents(); return slectedText; } return false; }; /** check any slection is made or not */ CommandExecutorService.prototype.checkSelection = function () { var slectedText = this.savedSelection.toString(); if (slectedText.length === 0) { throw new Error('No Selection Made'); } return true; }; /** * check tag is supported by browser or not * * @param tag HTML tag */ CommandExecutorService.prototype.checkTagSupportInBrowser = function (tag) { return !(document.createElement(tag) instanceof HTMLUnknownElement); }; CommandExecutorService.ctorParameters = function () { return [ { type: http.HttpClient } ]; }; CommandExecutorService = __decorate([ core.Injectable() ], CommandExecutorService); return CommandExecutorService; }()); /** time in which the message has to be cleared */ var DURATION = 7000; var MessageService = /** @class */ (function () { function MessageService() { /** variable to hold the user message */ this.message = new rxjs.Subject(); } /** returns the message sent by the editor */ MessageService.prototype.getMessage = function () { return this.message.asObservable(); }; /** * sends message to the editor * * @param message message to be sent */ MessageService.prototype.sendMessage = function (message) { this.message.next(message); this.clearMessageIn(DURATION); }; /** * a short interval to clear message * * @param milliseconds time in seconds in which the message has to be cleared */ MessageService.prototype.clearMessageIn = function (milliseconds) { var _this = this; setTimeout(function () { _this.message.next(undefined); }, milliseconds); }; MessageService = __decorate([ core.Injectable() ], MessageService); return MessageService; }()); /** * toolbar default configuration */ var ngxTextEditorConfig = { editable: true, spellcheck: true, height: 'auto', minHeight: '0', width: 'auto', minWidth: '0', translate: 'yes', enableToolbar: true, showToolbar: true, placeholder: 'Enter text here...', imageEndPoint: '', toolbar: [ ['h1', 'h2', 'h3', 'bold', 'italic', 'underline', 'strikeThrough', 'superscript', 'subscript'], ['fontName', 'fontSize', 'color'], ['justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull', 'indent', 'outdent'], ['cut', 'copy', 'delete', 'removeFormat', 'undo', 'redo'], ['paragraph', 'blockquote', 'removeBlockquote', 'horizontalLine', 'orderedList', 'unorderedList'], ['link', 'unlink', 'image', 'video'] ], toolbarTitle: { 'bold': 'Bold', 'italic': 'Italic', 'underline': 'Underline', 'strikeThrough': 'strikeThrough', 'superscript': 'Superscript', 'subscript': 'Subscript', 'fontName': 'Font Family', 'fontSize': 'Font Size', 'color': 'Color Picker', 'justifyLeft': 'Justify Left', 'justifyCenter': 'Justify Center', 'justifyRight': 'Justify Right', 'justifyFull': 'Justify Full', 'indent': 'Indent', 'outdent': 'Outdent', 'cut': 'Cut', 'copy': 'Copy', 'delete': 'Delete', 'removeFormat': 'Clear Formatting', 'undo': 'Undo', 'redo': 'Redo', 'paragraph': 'Paragraph', 'blockquote': 'Blockquote', 'removeBlockquote': 'Remove Blockquote', 'horizontalLine': 'Horizontal Line', 'orderedList': 'Ordered List', 'unorderedList': 'Color Picker', 'link': 'Insert Link', 'URLInput': 'URL', 'urlTextInput': 'Text', 'urlNewTab': 'Open in new tab', 'linkSubmit': 'Submit', 'unlink': 'Unlink', 'image': 'Insert Image', 'chooseImage': 'Choose Image', 'uploadingimage': 'Uploading Image', 'imageURLInput': 'URL', 'imageSubmit': 'Submit', 'video': 'Insert Video', 'videoURLInput': 'URL', 'height': 'height (px)', 'width': 'width (px)', 'heightwidth': 'Height/Width', 'videoSubmit': 'Submit', 'textColor': 'Text', 'backgroundColor': 'Background', 'hexInput': 'Hex Color', 'hexSubmit': 'Submit', 'fontSubmit': 'Submit', 'example': 'Ex:' } }; var NgxTextEditorComponent = /** @class */ (function () { /** * @param _messageService service to send message to the editor message component * @param _commandExecutor executes command from the toolbar * @param _renderer access and manipulate the dom element */ function NgxTextEditorComponent(_messageService, _commandExecutor, _renderer) { this._messageService = _messageService; this._commandExecutor = _commandExecutor; this._renderer = _renderer; /** * The editor can be resized vertically. * * `basic` resizer enables the html5 reszier. Check here https://www.w3schools.com/cssref/css3_pr_resize.asp * * `stack` resizer enable a resizer that looks like as if in https://stackoverflow.com */ this.resizer = 'stack'; /** * The config property is a JSON object * * All avaibale inputs inputs can be provided in the configuration as JSON * inputs provided directly are considered as top priority */ this.config = ngxTextEditorConfig; /** emits `blur` event when focused out from the textarea */ this.blur = new core.EventEmitter(); /** emits `focus` event when focused in to the textarea */ this.focus = new core.EventEmitter(); /** emits `uploadImage` event when image is selected */ this.uploadImage = new core.EventEmitter(); this.Utils = Utils; } NgxTextEditorComponent_1 = NgxTextEditorComponent; /** * events */ NgxTextEditorComponent.prototype.onTextAreaFocus = function () { this.focus.emit('focus'); }; /** focus the text area when the editor is focussed */ NgxTextEditorComponent.prototype.onEditorFocus = function () { this.textArea.nativeElement.focus(); }; /** * Executed from the contentEditable section while the input property changes * @param innerHTML html string from contentEditable */ NgxTextEditorComponent.prototype.onContentChange = function (innerHTML) { if (typeof this.onChange === 'function') { this.onChange(innerHTML); this.togglePlaceholder(innerHTML); } }; NgxTextEditorComponent.prototype.onTextAreaBlur = function () { /** save selection if focussed out */ this._commandExecutor.savedSelection = saveSelection(); if (typeof this.onTouched === 'function') { this.onTouched(); } this.blur.emit('blur'); }; /** * Executed when the image from the disc is selected * @param image uploaded file object */ NgxTextEditorComponent.prototype.onUploadImage = function (image) { this.uploadImage.emit(image); }; /** * resizing text area * * @param offsetY vertical height of the eidtable portion of the editor */ NgxTextEditorComponent.prototype.resizeTextArea = function (offsetY) { var newHeight = parseInt(this.height, 10); newHeight += offsetY; this.height = newHeight + 'px'; this.textArea.nativeElement.style.height = this.height; }; /** * editor actions, i.e., executes command from toolbar * * @param commandName name of the command to be executed */ NgxTextEditorComponent.prototype.executeCommand = function (commandName) { try { this._commandExecutor.execute(commandName); } catch (error) { this._messageService.sendMessage(error.message); } }; /** * Write a new value to the element. * * @param value value to be executed when there is a change in contenteditable */ NgxTextEditorComponent.prototype.writeValue = function (value) { this.togglePlaceholder(value); if (value === null || value === undefined || value === '' || value === '<br>') { value = null; } this.refreshView(value); }; /** * Set the function to be called * when the control receives a change event. * * @param fn a function */ NgxTextEditorComponent.prototype.registerOnChange = function (fn) { this.onChange = fn; }; /** * Set the function to be called * when the control receives a touch event. * * @param fn a function */ NgxTextEditorComponent.prototype.registerOnTouched = function (fn) { this.onTouched = fn; }; /** * refresh view/HTML of the editor * * @param value html string from the editor */ NgxTextEditorComponent.prototype.refreshView = function (value) { var normalizedValue = value === null ? '' : value; this._renderer.setProperty(this.textArea.nativeElement, 'innerHTML', normalizedValue); }; /** * toggles placeholder based on input string * * @param value A HTML string from the editor */ NgxTextEditorComponent.prototype.togglePlaceholder = function (value) { if (!value || value === '<br>' || value === '') { this._renderer.addClass(this.ngxWrapper.nativeElement, 'show-placeholder'); } else { this._renderer.removeClass(this.ngxWrapper.nativeElement, 'show-placeholder'); } }; /** * returns a json containing input params */ NgxTextEditorComponent.prototype.getCollectiveParams = function () { return { editable: this.editable, spellcheck: this.spellcheck, placeholder: this.placeholder, translate: this.translate, height: this.height, minHeight: this.minHeight, width: this.width, minWidth: this.minWidth, enableToolbar: this.enableToolbar, showToolbar: this.showToolbar, imageEndPoint: this.imageEndPoint, toolbar: this.toolbar }; }; NgxTextEditorComponent.prototype.ngOnInit = function () { /** * set configuration */ this.config = this.Utils.getEditorConfiguration(this.config, ngxTextEditorConfig, this.getCollectiveParams()); this.height = this.height || this.textArea.nativeElement.offsetHeight; this.executeCommand('enableObjectResizing'); }; var NgxTextEditorComponent_1; NgxTextEditorComponent.ctorParameters = function () { return [ { type: MessageService }, { type: CommandExecutorService }, { type: core.Renderer2 } ]; }; __decorate([ core.Input() ], NgxTextEditorComponent.prototype, "editable", void 0); __decorate([ core.Input() ], NgxTextEditorComponent.prototype, "spellcheck", void 0); __decorate([ core.Input() ], NgxTextEditorComponent.prototype, "placeholder", void 0); __decorate([ core.Input() ], NgxTextEditorComponent.prototype, "translate", void 0); __decorate([ core.Input() ], NgxTextEditorComponent.prototype, "height", void 0); __decorate([ core.Input() ], NgxTextEditorComponent.prototype, "minHeight", void 0); __decorate([ core.Input() ], NgxTextEditorComponent.prototype, "width", void 0); __decorate([ core.Input() ], NgxTextEditorComponent.prototype, "minWidth", void 0); __decorate([ core.Input() ], NgxTextEditorComponent.prototype, "toolbar", void 0); __decorate([ core.Input() ], NgxTextEditorComponent.prototype, "resizer", void 0); __decorate([ core.Input() ], NgxTextEditorComponent.prototype, "config", void 0); __decorate([ core.Input() ], NgxTextEditorComponent.prototype, "showToolbar", void 0); __decorate([ core.Input() ], NgxTextEditorComponent.prototype, "enableToolbar", void 0); __decorate([ core.Input() ], NgxTextEditorComponent.prototype, "imageEndPoint", void 0); __decorate([ core.Output() ], NgxTextEditorComponent.prototype, "blur", void 0); __decorate([ core.Output() ], NgxTextEditorComponent.prototype, "focus", void 0); __decorate([ core.Output() ], NgxTextEditorComponent.prototype, "uploadImage", void 0); __decorate([ core.ViewChild('ngxTextArea', { static: true }) ], NgxTextEditorComponent.prototype, "textArea", void 0); __decorate([ core.ViewChild('ngxWrapper', { static: true }) ], NgxTextEditorComponent.prototype, "ngxWrapper", void 0); NgxTextEditorComponent = NgxTextEditorComponent_1 = __decorate([ core.Component({ selector: 'ngx-text-editor', template: "<div class=\"ngx-text-editor\"\r\n id=\"ngxTextEditor\"\r\n [style.width]=\"config['width']\"\r\n [style.minWidth]=\"config['minWidth']\"\r\n tabindex=\"0\"\r\n (focus)=\"onEditorFocus()\">\r\n\r\n <ngx-text-editor-toolbar [config]=\"config\"\r\n (execute)=\"executeCommand($event)\"\r\n (uploadImage)=\"onUploadImage($event)\"></ngx-text-editor-toolbar>\r\n\r\n <!-- text area -->\r\n <div #ngxWrapper\r\n class=\"ngx-wrapper\">\r\n <div #ngxTextArea\r\n class=\"ngx-text-editor-textarea\"\r\n [attr.contenteditable]=\"config['editable']\"\r\n (input)=\"onContentChange($event.target.innerHTML)\"\r\n [attr.translate]=\"config['translate']\"\r\n [attr.spellcheck]=\"config['spellcheck']\"\r\n [style.height]=\"config['height']\"\r\n [style.minHeight]=\"config['minHeight']\"\r\n [style.resize]=\"Utils?.canResize(resizer)\"\r\n (focus)=\"onTextAreaFocus()\"\r\n (blur)=\"onTextAreaBlur()\"></div>\r\n\r\n <span class=\"ngx-text-editor-placeholder\">\r\n {{ placeholder || config['placeholder'] }}\r\n </span>\r\n </div>\r\n\r\n <ngx-text-editor-message></ngx-text-editor-message>\r\n\r\n <ngx-grippie *ngIf=\"resizer === 'stack'\"></ngx-grippie>\r\n</div>\r\n", providers: [{ provide: forms.NG_VALUE_ACCESSOR, useExisting: core.forwardRef(function () { return NgxTextEditorComponent_1; }), multi: true }], styles: [".ngx-text-editor{position:relative}.ngx-text-editor ::ng-deep [contenteditable=true]:empty:before{content:attr(placeholder);display:block;color:#868e96;opacity:1}.ngx-text-editor .ngx-wrapper{position:relative}.ngx-text-editor .ngx-wrapper .ngx-text-editor-textarea{min-height:5rem;padding:.5rem .8rem 1rem;border:1px solid #ddd;background-color:transparent;overflow-x:hidden;overflow-y:auto;z-index:2;position:relative}.ngx-text-editor .ngx-wrapper .ngx-text-editor-textarea.focus,.ngx-text-editor .ngx-wrapper .ngx-text-editor-textarea:focus{outline:0}.ngx-text-editor .ngx-wrapper .ngx-text-editor-textarea ::ng-deep blockquote{margin-left:1rem;border-left:.2em solid #dfe2e5;padding-left:.5rem}.ngx-text-editor .ngx-wrapper .ngx-text-editor-textarea::before{content:normal!important}.ngx-text-editor .ngx-wrapper ::ng-deep p{margin-bottom:0}.ngx-text-editor .ngx-wrapper .ngx-text-editor-placeholder{display:none;position:absolute;top:0;padding:.5rem .8rem 1rem .9rem;z-index:1;color:#6c757d;opacity:1}.ngx-text-editor .ngx-wrapper.show-placeholder .ngx-text-editor-placeholder{display:block}"] }) ], NgxTextEditorComponent); return NgxTextEditorComponent; }()); var NgxGrippieComponent = /** @class */ (function () { /** * Constructor * * @param _editorComponent Editor component */ function NgxGrippieComponent(_editorComponent) { this._editorComponent = _editorComponent; /** previous value befor resizing the editor */ this.oldY = 0; /** set to true on mousedown event */ this.grabber = false; } /** * * @param event Mouseevent * * Update the height of the editor when the grabber is dragged */ NgxGrippieComponent.prototype.onMouseMove = function (event) { if (!this.grabber) { return; } this._editorComponent.resizeTextArea(event.clientY - this.oldY); this.oldY = event.clientY; }; /** * * @param event Mouseevent * * set the grabber to false on mouse up action */ NgxGrippieComponent.prototype.onMouseUp = function (event) { this.grabber = false; }; NgxGrippieComponent.prototype.onResize = function (event, resizer) { this.grabber = true; this.oldY = event.clientY; event.preventDefault(); }; NgxGrippieComponent.ctorParameters = function () { return [ { type: NgxTextEditorComponent } ]; }; __decorate([ core.HostListener('document:mousemove', ['$event']) ], NgxGrippieComponent.prototype, "onMouseMove", null); __decorate([ core.HostListener('document:mouseup', ['$event']) ], NgxGrippieComponent.prototype, "onMouseUp", null); __decorate([ core.HostListener('mousedown', ['$event']) ], NgxGrippieComponent.prototype, "onResize", null); NgxGrippieComponent = __decorate([ core.Component({ selector: 'ngx-grippie', template: "<div class=\"ngx-text-editor-grippie\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" style=\"isolation:isolate\" viewBox=\"651.6 235 26 5\"\r\n width=\"26\" height=\"5\">\r\n <g id=\"sprites\">\r\n <path d=\" M 651.6 235 L 653.6 235 L 653.6 237 L 651.6 237 M 654.6 238 L 656.6 238 L 656.6 240 L 654.6 240 M 660.6 238 L 662.6 238 L 662.6 240 L 660.6 240 M 666.6 238 L 668.6 238 L 668.6 240 L 666.6 240 M 672.6 238 L 674.6 238 L 674.6 240 L 672.6 240 M 657.6 235 L 659.6 235 L 659.6 237 L 657.6 237 M 663.6 235 L 665.6 235 L 665.6 237 L 663.6 237 M 669.6 235 L 671.6 235 L 671.6 237 L 669.6 237 M 675.6 235 L 677.6 235 L 677.6 237 L 675.6 237\"\r\n fill=\"rgb(147,153,159)\" />\r\n </g>\r\n </svg>\r\n</div>\r\n", styles: [".ngx-text-editor-grippie{height:9px;background-color:#f1f1f1;position:relative;text-align:center;cursor:s-resize;border:1px solid #ddd;border-top:transparent}.ngx-text-editor-grippie svg{position:absolute;top:1.5px;width:50%;right:25%}"] }) ], NgxGrippieComponent); return NgxGrippieComponent; }()); var NgxTextEditorMessageComponent = /** @class */ (function () { /** * @param _messageService service to send message to the editor */ function NgxTextEditorMessageComponent(_messageService) { var _this = this; this._messageService = _messageService; /** property that holds the message to be displayed on the editor */ this.ngxMessage = undefined; this._messageService.getMessage().subscribe(function (message) { return _this.ngxMessage = message; }); } /** * clears editor message */ NgxTextEditorMessageComponent.prototype.clearMessage = function () { this.ngxMessage = undefined; }; NgxTextEditorMessageComponent.ctorParameters = function () { return [ { type: MessageService } ]; }; NgxTextEditorMessageComponent = __decorate([ core.Component({ selector: 'ngx-text-editor-message', template: "<div class=\"ngx-text-editor-message\" *ngIf=\"ngxMessage\" (dblclick)=\"clearMessage()\">\r\n {{ ngxMessage }}\r\n</div>\r\n", styles: [".ngx-text-editor-message{font-size:80%;background-color:#f1f1f1;border:1px solid #ddd;border-top:transparent;padding:0 .5rem .1rem;transition:.5s ease-in}"] }) ], NgxTextEditorMessageComponent); return NgxTextEditorMessageComponent; }()); var NgxTextEditorToolbarComponent = /** @class */ (function () { function NgxTextEditorToolbarComponent(_popOverConfig, _formBuilder, _messageService, _commandExecutorService) { this._popOverConfig = _popOverConfig; this._formBuilder = _formBuilder; this._messageService = _messageService; this._commandExecutorService = _commandExecutorService; /** set to false when image is being uploaded */ this.uploadComplete = true; /** upload percentage */ this.updloadPercentage = 0; /** set to true when the image is being uploaded */ this.isUploading = false; /** which tab to active for color insertion */ this.selectedColorTab = 'textColor'; /** font family name */ this.fontName = ''; /** font size */ this.fontSize = ''; /** hex color code */ this.hexColor = ''; /** show/hide image uploader */ this.isImageUploader = false; this.wasH1Pressed = false; /** Icons for the Toolbar */ this.icons = { heading: freeSolidSvgIcons.faHeading, bold: freeSolidSvgIcons.faBold, italic: freeSolidSvgIcons.faItalic, underline: freeSolidSvgIcons.faUnderline, strikethrough: freeSolidSvgIcons.faStrikethrough, superscript: freeSolidSvgIcons.faSuperscript, subscript: freeSolidSvgIcons.faSubscript,