UNPKG

ng-quill

Version:

Angular component for the Quill Rich Text Editor

2 lines (1 loc) 8.18 kB
(function(root,factory){if(typeof define==="function"&&define.amd){define(["quill"],factory)}else if(typeof module!=="undefined"&&typeof exports==="object"){module.exports=factory(require("quill"))}else{root.Requester=factory(root.Quill)}})(this,function(Quill){"use strict";var app;app=angular.module("ngQuill",["ngSanitize"]);app.provider("ngQuillConfig",function(){var config={modules:{toolbar:[["bold","italic","underline","strike"],["blockquote","code-block"],[{header:1},{header:2}],[{list:"ordered"},{list:"bullet"}],[{script:"sub"},{script:"super"}],[{indent:"-1"},{indent:"+1"}],[{direction:"rtl"}],[{size:["small",false,"large","huge"]}],[{header:[1,2,3,4,5,6,false]}],[{color:[]},{background:[]}],[{font:[]}],[{align:[]}],["clean"],["link","image","video"]]},bounds:document.body,debug:"warn",theme:"snow",scrollingContainer:null,placeholder:"Insert text here ...",readOnly:false,trackChanges:"user",preserveWhitespace:false};this.set=function(customConf){customConf=customConf||{};if(customConf.modules){config.modules=customConf.modules}if(customConf.theme){config.theme=customConf.theme}if(customConf.placeholder!==null&&customConf.placeholder!==undefined){config.placeholder=customConf.placeholder.trim()}if(customConf.readOnly){config.readOnly=customConf.readOnly}if(customConf.formats){config.formats=customConf.formats}if(customConf.bounds){config.bounds=customConf.bounds}if(customConf.scrollingContainer){config.scrollingContainer=customConf.scrollingContainer}if(customConf.debug||customConf.debug===false){config.debug=customConf.debug}if(customConf.trackChanges&&["all","user"].indexOf(customConf.trackChanges)>-1){config.trackChanges=customConf.trackChanges}if(customConf.preserveWhitespace){config.preserveWhitespace=true}};this.$get=function(){return config}});app.component("ngQuillEditor",{bindings:{modules:"<modules",theme:"@?",readOnly:"<?",format:"@?",debug:"@?",formats:"<?",placeholder:"<?",bounds:"<?",scrollingContainer:"<?",strict:"<?",onEditorCreated:"&?",onContentChanged:"&?",onBlur:"&?",onFocus:"&?",onSelectionChanged:"&?",ngModel:"<",maxLength:"<",minLength:"<",customOptions:"<?",styles:"<?",sanitize:"<?",customToolbarPosition:"@?",trackChanges:"@?",preserveWhitespace:"<?"},require:{ngModelCtrl:"ngModel"},transclude:{toolbar:"?ngQuillToolbar"},template:'<div class="ng-hide" ng-show="$ctrl.ready"><ng-transclude ng-transclude-slot="toolbar"></ng-transclude></div>',controller:["$scope","$element","$sanitize","$timeout","$transclude","ngQuillConfig",function($scope,$element,$sanitize,$timeout,$transclude,ngQuillConfig){var config={};var content;var editorElem;var format="html";var editorChanged=false;var editor;var placeholder=ngQuillConfig.placeholder;var textChangeEvent;var selectionChangeEvent;this.setter=function(value){if(format==="html"){return editor.clipboard.convert(this.sanitize?$sanitize(value):value)}else if(this.format==="json"){try{return JSON.parse(value)}catch(e){return[{insert:value}]}}return value};this.validate=function(text){var textLength=text.trim().length;if(this.maxLength){if(textLength>this.maxLength){this.ngModelCtrl.$setValidity("maxlength",false)}else{this.ngModelCtrl.$setValidity("maxlength",true)}}if(this.minLength>0){if(textLength<this.minLength&&textLength){this.ngModelCtrl.$setValidity("minlength",false)}else{this.ngModelCtrl.$setValidity("minlength",true)}}};this.$onChanges=function(changes){if(changes.ngModel){content=changes.ngModel.currentValue;if(editor){if(!editorChanged){if(content){if(changes.ngModel.currentValue!==changes.ngModel.previousValue){if(this.format==="text"){editor.setText(content)}else{editor.setContents(this.setter(content))}}}else{editor.setText("")}}editorChanged=false}}if(editor&&changes.readOnly){editor.enable(!changes.readOnly.currentValue)}if(editor&&changes.placeholder){editor.root.dataset.placeholder=changes.placeholder.currentValue}if(editor&&editorElem&&changes.styles){var currentStyling=changes.styles.currentValue;var previousStyling=changes.styles.previousValue;if(previousStyling){for(var key in previousStyling){editorElem.style[key]=""}}if(currentStyling){for(var activeStyle in currentStyling){if(currentStyling.hasOwnProperty(activeStyle)){editorElem.style[activeStyle]=currentStyling[activeStyle]}}}}};this.$onInit=function(){if(this.placeholder!==null&&this.placeholder!==undefined){placeholder=this.placeholder.trim()}if(this.format&&["object","html","text","json"].indexOf(this.format)>-1){format=this.format}config={theme:this.theme||ngQuillConfig.theme,readOnly:this.readOnly||ngQuillConfig.readOnly,modules:this.modules||ngQuillConfig.modules,formats:this.formats||ngQuillConfig.formats,placeholder:placeholder,bounds:this.bounds||ngQuillConfig.bounds,strict:this.strict,scrollingContainer:this.scrollingContainer||ngQuillConfig.scrollingContainer,debug:this.debug||this.debug===false?this.debug:ngQuillConfig.debug}};this.$postLink=function(){$timeout(function(){this._initEditor()}.bind(this),0)};this.$onDestroy=function(){editor=null;if(textChangeEvent){textChangeEvent.removeListener("text-change")}if(selectionChangeEvent){selectionChangeEvent.removeListener("selection-change")}};this._initEditor=function(){var $editorElem=this.preserveWhitespace?angular.element("<pre></pre>"):angular.element("<div></div>");var container=$element.children();editorElem=$editorElem[0];if(config.bounds==="self"){config.bounds=editorElem}if($transclude.isSlotFilled("toolbar")){config.modules.toolbar=container.find("ng-quill-toolbar").children()[0]}if(this.styles){for(var activeStyle in this.styles){if(this.styles.hasOwnProperty(activeStyle)){editorElem.style[activeStyle]=this.styles[activeStyle]}}}if(!this.customToolbarPosition||this.customToolbarPosition==="top"){container.append($editorElem)}else{container.prepend($editorElem)}if(this.customOptions){this.customOptions.forEach(function(customOption){var newCustomOption=Quill.import(customOption.import);newCustomOption.whitelist=customOption.whitelist;if(customOption.toRegister){newCustomOption[customOption.toRegister.key]=customOption.toRegister.value}Quill.register(newCustomOption,true)})}editor=new Quill(editorElem,config);this.ready=true;selectionChangeEvent=editor.on("selection-change",function(range,oldRange,source){if(range===null&&this.onBlur){this.onBlur({editor:editor,source:source})}else if(oldRange===null&&this.onFocus){this.onFocus({editor:editor,source:source})}if(this.onSelectionChanged){this.onSelectionChanged({editor:editor,oldRange:oldRange,range:range,source:source})}if(range){return}$scope.$applyAsync(function(){this.ngModelCtrl.$setTouched()}.bind(this))}.bind(this));textChangeEvent=editor.on("text-change",function(delta,oldDelta,source){var html=editorElem.querySelector(".ql-editor").innerHTML;var text=editor.getText();var content=editor.getContents();var emptyModelTag=["<"+editor.root.firstChild.localName+">","</"+editor.root.firstChild.localName+">"];if(html===emptyModelTag[0]+"<br>"+emptyModelTag[1]){html=null}this.validate(text);$scope.$applyAsync(function(){var trackChanges=this.trackChanges||ngQuillConfig.trackChanges;if(source==="user"||trackChanges&&trackChanges==="all"){editorChanged=true;if(format==="text"){if(text===this.ngModelCtrl.$viewValue){editorChanged=false}else{this.ngModelCtrl.$setViewValue(text)}}else if(format==="object"){this.ngModelCtrl.$setViewValue(content)}else if(this.format==="json"){try{this.ngModelCtrl.$setViewValue(JSON.stringify(content))}catch(e){this.ngModelCtrl.$setViewValue(text)}}else{this.ngModelCtrl.$setViewValue(html)}}if(this.onContentChanged){this.onContentChanged({editor:editor,html:html,text:text,content:content,delta:delta,oldDelta:oldDelta,source:source})}}.bind(this))}.bind(this));if(content){if(format==="text"){editor.setText(content,"silent")}else if(format==="object"){editor.setContents(content,"silent")}else if(format==="json"){try{editor.setContents(JSON.parse(content),"silent")}catch(e){editor.setText(content,"silent")}}else{editor.setContents(editor.clipboard.convert(this.sanitize?$sanitize(content):content,"silent"))}editor.history.clear()}this.validate(editor.getText());if(this.onEditorCreated){this.onEditorCreated({editor:editor})}}}]});return app.name});