From 85ec44e4dc5546e8e1a6990b0867ff2e40ee3cdc Mon Sep 17 00:00:00 2001 From: Rory Walsh Date: Tue, 31 Aug 2021 11:04:33 +1000 Subject: [PATCH 1/2] V4.0.5 Fixed broken syntax errors, moved away from using a global editorInstance, so now has support for multiple editors on same page. --- src/knockout-froala.js | 184 ++++++++++++++++------------------------- 1 file changed, 71 insertions(+), 113 deletions(-) diff --git a/src/knockout-froala.js b/src/knockout-froala.js index e869723..923e801 100644 --- a/src/knockout-froala.js +++ b/src/knockout-froala.js @@ -1,12 +1,11 @@ +/* global FroalaEditor */ + /** * knockout binding for Froala Editor */ +(function () { + 'use strict'; -(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 @@ -16,136 +15,95 @@ * @param {object} bindings * @api public */ - - function init( element, value, bindings ) { - + function init(element, value, bindings) { var model = value(); - var allBindings = unwrap( bindings() ); - var options = ko.toJS( allBindings.froalaOptions ); + var allBindings = ko.utils.unwrapObservable(bindings()); + var options = allBindings.froalaOptions ? ko.toJS(allBindings.froalaOptions) : {}; // register events before initializing the editor - for( var eventName in allBindings.froalaEvents ) { - $el.on( 'froalaEditor.' + eventName, allBindings.froalaEvents[eventName] ); + for (var eventName in allBindings.froalaEvents) { + options.events[eventName] = allBindings.froalaEvents[eventName]; } - // initialize the editor - $el.froalaEditor( options || {} ); - - // 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) { - + // update underlying KO model whenever editor content changed + var processUpdateEvent = function (editorInstance) { 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); - } + 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||{}); - - - + }; + + options.events = { + contentChanged: function () { + processUpdateEvent(this); + }, + 'paste.after': function () { + processUpdateEvent(this); + }, + 'image.beforeUpload': function (files) { + var editorInstance = this; + if (files.length) { + var reader = new FileReader(); + reader.onload = function (e) { + var result = e.target.result; + editorInstance.image.insert(result, null, null, editorInstance.image.get()); + processUpdateEvent(editorInstance); + }; + reader.readAsDataURL(files[0]); + } + return false; + }, + }; - + // initialize the editor + 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 - */ + ko.utils.domNodeDisposal.addDisposeCallback(element, function () { + element['data-froala.editor'].destroy(); + }); - 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(); - } + // remove iframe only embedding restrictions, some vendors now wrap snippets in divs for responsivness. + FroalaEditor.VIDEO_EMBED_REGEX = /.*/; - - 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 ); - - } + // do not handle child nodes (e.g. if user pasted KO laced content.) + return { + controlsDescendantBindings: true, + }; } - /** - * 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(); + * update froala editor whenever underlying observable model + * is updated + * + * @param {element} element + * @param {object} value + * @api public + */ + function update(element, value) { + var modelValue = ko.utils.unwrapObservable(value()); + + if (element) { + var editorInstance = element['data-froala.editor']; + if (editorInstance.html) { + var editorValue = editorInstance.html.get(); + + // avoid any un-necessary updates + if (editorValue !== modelValue && (typeof modelValue === 'string' || modelValue === null)) { + editorInstance.html.set(modelValue); + } } } } - /** * expose `froala` binding handler methods - */ - + */ ko.bindingHandlers.froala = { init: init, - update: update - } - + update: update, + }; })(); From 8242d4622876402a06ba1c0f22a971daa9c6b0ad Mon Sep 17 00:00:00 2001 From: Rory Walsh Date: Tue, 31 Aug 2021 11:20:43 +1000 Subject: [PATCH 2/2] Rory-Walsh-V4.0.5-patch-2 Removed the config option changing VIDEO_EMBED_REGEX from previous commit. --- src/knockout-froala.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/knockout-froala.js b/src/knockout-froala.js index 923e801..0e038c3 100644 --- a/src/knockout-froala.js +++ b/src/knockout-froala.js @@ -66,9 +66,6 @@ element['data-froala.editor'].destroy(); }); - // remove iframe only embedding restrictions, some vendors now wrap snippets in divs for responsivness. - FroalaEditor.VIDEO_EMBED_REGEX = /.*/; - // do not handle child nodes (e.g. if user pasted KO laced content.) return { controlsDescendantBindings: true,