UNPKG

knockout-froala

Version:

Knockout.js binding for Froala WYSIWYG HTML Rich Text Editor

151 lines (114 loc) 3.85 kB
/** * knockout binding for Froala Editor */ (function() { 'use strict'; // locals var unwrap = ko.utils.unwrapObservable; var editorInstance =null; /** * initiate froala editor, listen to its changes * and updates the underlying observable model * * @param {element} element * @param {object} value * @param {object} bindings * @api public */ function init( element, value, bindings ) { var model = value(); var allBindings = unwrap( bindings() ); var options = ko.toJS( allBindings.froalaOptions ); // register events before initializing the editor for( var eventName in allBindings.froalaEvents ) { $el.on( 'froalaEditor.' + eventName, allBindings.froalaEvents[eventName] ); } // initialize the editor // provide froala editor instance for flexibility if( allBindings.froalaInstance && ko.isWriteableObservable( allBindings.froalaInstance ) ) { allBindings.froalaInstance( $el.data( 'froala.editor' ) ); } // update underlying model whenever editor content changed var processUpdateEvent = function (e) { if (ko.isWriteableObservable(model)) { //if froalaInstance defined, use that for the editor instance if(allBindings.froalaInstance && ko.isWriteableObservable( allBindings.froalaInstance ) ) { editorInstance = allBindings.froalaInstance(); } if(editorInstance!=null) { var editorValue = editorInstance.html.get(); var current = model(); if (current !== editorValue) { model(editorValue); } } } } options.events = { initialized: function() { editorInstance=this; // provide froala editor instance for flexibility if(allBindings.froalaInstance && ko.isWriteableObservable( allBindings.froalaInstance ) ) { allBindings.froalaInstance( editorInstance ); } }, 'contentChanged': processUpdateEvent, 'paste.after':processUpdateEvent } new FroalaEditor(element,options||{}); // cleanup editor, when dom node is removed ko.utils.domNodeDisposal.addDisposeCallback( element, destroy( element, bindings ) ); // do not handle child nodes return { controlsDescendantBindings: true }; } /** * update froala editor whenever underlying observable model * is updated * * @param {element} element * @param {object} value * @api public */ function update( element, value, bindings ) { var modelValue = unwrap( value() ); //if froalaInstance defined, use that for the editor instance var allBindings = unwrap( bindings() ); if(allBindings.froalaInstance && ko.isWriteableObservable( allBindings.froalaInstance ) ) { editorInstance = allBindings.froalaInstance(); } if( editorInstance == null ) { return; } var editorValue = editorInstance.html.get(); // avoid any un-necessary updates if( editorValue !== modelValue && (typeof modelValue === 'string' || modelValue === null)) { editorInstance.html.set( modelValue ); } } /** * destroy froala editor instance * * @param {dom} element * @return {function} handler * @api private */ function destroy( element, bindings ) { return function() { //if froalaInstance defined, use that for the editor instance var allBindings = unwrap( bindings() ); if(allBindings.froalaInstance && ko.isWriteableObservable( allBindings.froalaInstance ) ) { editorInstance = allBindings.froalaInstance(); } if( editorInstance!=null ) { editorInstance.destroy(); } } } /** * expose `froala` binding handler methods */ ko.bindingHandlers.froala = { init: init, update: update } })();