From 7fe646bd51872f9ae5ab53cd46f98e8c072da0c6 Mon Sep 17 00:00:00 2001
From: Simon Babay <simon@babay.fr>
Date: Wed, 20 Apr 2016 22:08:59 +0200
Subject: [PATCH] Better way to update ngModel + Cleaning

---
 .gitignore          |  1 +
 gulpfile.js         | 15 +++--------
 lib/CKEditor.js     | 63 +++++++++++++++++++++++++++------------------
 lib/CKEditor.js.map |  1 +
 package.json        | 22 ++++++++--------
 src/CKEditor.es6    | 41 ++++++++++++++++++-----------
 6 files changed, 80 insertions(+), 63 deletions(-)
 create mode 100644 lib/CKEditor.js.map

diff --git a/.gitignore b/.gitignore
index 8d87b1d..6adcd01 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
 node_modules/*
+npm-debug.log
diff --git a/gulpfile.js b/gulpfile.js
index 7fe5732..e6495dc 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -17,16 +17,7 @@ gulp.task('default', ['watch']);
 /**
  * Build all
  */
-gulp.task('build', ['babel', 'assets']);
-
-/**
- * Copy assets
- */
-gulp.task('assets', function(){
-    return gulp.src(paths.assets)
-        .pipe(cache('assets-dev'))
-        .pipe(gulp.dest(paths.dest));
-});
+gulp.task('build', ['babel', 'uglify']);
 
 /**
  * Babel transpile all sources
@@ -40,7 +31,7 @@ gulp.task('babel', function(){
             console.error(err.stack);
             this.emit('end');
         })
-        .pipe(sourcemaps.write())
+        .pipe(sourcemaps.write('.'))
         .pipe(gulp.dest(paths.dest));
 });
 
@@ -48,5 +39,5 @@ gulp.task('babel', function(){
  * Babel watch
  */
 gulp.task('watch', function(){
-    return gulp.watch([paths.sources, paths.assets], ['babel', 'assets']);
+    return gulp.watch([paths.sources, paths.assets], ['babel']);
 });
diff --git a/lib/CKEditor.js b/lib/CKEditor.js
index ae484bc..89f2fe8 100644
--- a/lib/CKEditor.js
+++ b/lib/CKEditor.js
@@ -66,37 +66,36 @@ function _initializerWarningHelper(descriptor, context) {
  */
 var CKEditor = exports.CKEditor = (_dec = (0, _core.Component)({
     selector: 'ckeditor',
-    template: '<textarea #host></textarea>'
-}), _dec2 = Reflect.metadata('parameters', [null, [new _core.OptionalMetadata()]]), _dec3 = (0, _core.Input)(), _dec4 = (0, _core.Input)(), _dec5 = (0, _core.Output)(), _dec6 = (0, _core.ViewChild)('host'), _dec7 = (0, _core.ViewChild)('button'), _dec(_class = _dec2(_class = (_class2 = function () {
+    template: '<textarea #host (change)="onValueChange($event)"></textarea>'
+}), _dec2 = Reflect.metadata('parameters', [null, [new _core.OptionalMetadata()]]), _dec3 = (0, _core.Input)(), _dec4 = (0, _core.Input)(), _dec5 = (0, _core.Input)(), _dec6 = (0, _core.Output)(), _dec7 = (0, _core.ViewChild)('host'), _dec(_class = _dec2(_class = (_class2 = function () {
 
     /**
      * Constructor
      */
 
-    function CKEditor(elementRef, ngControl, zone) {
+    function CKEditor(elementRef, ngControl, renderer) {
         _classCallCheck(this, CKEditor);
 
         _initDefineProp(this, 'config', _descriptor, this);
 
         _initDefineProp(this, 'configFile', _descriptor2, this);
 
-        _initDefineProp(this, 'change', _descriptor3, this);
+        _initDefineProp(this, 'ngModel', _descriptor3, this);
 
-        _initDefineProp(this, 'host', _descriptor4, this);
+        _initDefineProp(this, 'change', _descriptor4, this);
 
-        _initDefineProp(this, 'button', _descriptor5, this);
+        _initDefineProp(this, 'host', _descriptor5, this);
 
         this.value = '';
-        this.instance = null;
+        this.instance = this.instance;
         this.ngControl = this.ngControl;
-        this.zone = this.zone;
+        this.renderer = this.renderer;
 
         if (ngControl) {
             ngControl.valueAccessor = this;
             this.ngControl = ngControl;
         }
-
-        this.zone = zone;
+        this.renderer = renderer;
     }
 
     /**
@@ -142,6 +141,18 @@ var CKEditor = exports.CKEditor = (_dec = (0, _core.Component)({
                 }
         }
 
+        /**
+         * Detect textarea value change
+         */
+
+    }, {
+        key: 'onValueChange',
+        value: function onValueChange(event) {
+            var value = this.host.nativeElement.value;
+            this.change.emit(value);
+            this.ngControl.viewToModelUpdate(value);
+        }
+
         /**
          * CKEditor init
          */
@@ -151,19 +162,21 @@ var CKEditor = exports.CKEditor = (_dec = (0, _core.Component)({
         value: function ckeditorInit(config) {
             var _this2 = this;
 
+            if (!CKEDITOR) {
+                console.error('Please include CKEditor in your page');
+                return;
+            }
+
             // CKEditor replace textarea
-            this.instance = CKEDITOR.replace(this.host._appElement.nativeElement, config);
+            this.instance = CKEDITOR.replace(this.host.nativeElement, config);
 
             // Set initial value
             this.instance.setData(this.value);
 
-            // Change event
+            // CKEditor change event
             this.instance.on('change', function () {
-                _this2.zone.run(function () {
-                    var value = _this2.instance.getData();
-                    _this2.change.emit(value);
-                    _this2.ngControl.viewToModelUpdate(value);
-                });
+                _this2.renderer.setElementProperty(_this2.host.nativeElement, 'value', _this2.instance.getData());
+                _this2.renderer.invokeElementMethod(_this2.host.nativeElement, 'dispatchEvent', [new Event('change')]);
             });
         }
 
@@ -206,21 +219,21 @@ var CKEditor = exports.CKEditor = (_dec = (0, _core.Component)({
     initializer: function initializer() {
         return this.configFile;
     }
-}), _descriptor3 = _applyDecoratedDescriptor(_class2.prototype, 'change', [_dec5], {
+}), _descriptor3 = _applyDecoratedDescriptor(_class2.prototype, 'ngModel', [_dec5], {
     enumerable: true,
     initializer: function initializer() {
-        return new _core.EventEmitter();
+        return this.ngModel;
     }
-}), _descriptor4 = _applyDecoratedDescriptor(_class2.prototype, 'host', [_dec6], {
+}), _descriptor4 = _applyDecoratedDescriptor(_class2.prototype, 'change', [_dec6], {
     enumerable: true,
     initializer: function initializer() {
-        return this.host;
+        return new _core.EventEmitter();
     }
-}), _descriptor5 = _applyDecoratedDescriptor(_class2.prototype, 'button', [_dec7], {
+}), _descriptor5 = _applyDecoratedDescriptor(_class2.prototype, 'host', [_dec7], {
     enumerable: true,
     initializer: function initializer() {
-        return this.button;
+        return this.host;
     }
 })), _class2)) || _class) || _class);
-Reflect.defineMetadata('design:paramtypes', [_core.ElementRef, _common.NgControl, _core.NgZone], CKEditor);
-//# sourceMappingURL=data:application/json;charset=utf8;base64,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ZmlsZSI6IkNLRWRpdG9yLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gSW1wb3J0c1xuaW1wb3J0IHtcbiAgICBDb21wb25lbnQsXG4gICAgRGlyZWN0aXZlLFxuICAgIElucHV0LFxuICAgIE91dHB1dCxcbiAgICBFbGVtZW50UmVmLFxuICAgIFZpZXdDaGlsZCxcbiAgICBPcHRpb25hbCxcbiAgICBPcHRpb25hbE1ldGFkYXRhLFxuICAgIEV2ZW50RW1pdHRlcixcbiAgICBOZ1pvbmVcbn0gZnJvbSAnYW5ndWxhcjIvY29yZSc7XG5pbXBvcnQge05nQ29udHJvbCwgQ29udHJvbFZhbHVlQWNjZXNzb3J9IGZyb20gJ2FuZ3VsYXIyL2NvbW1vbic7XG5cbi8qKlxuICogQ0tFZGl0b3IgY29tcG9uZW50XG4gKiBVc2FnZSA6XG4gKiA8Y2tlZGl0b3IgWyhuZ01vZGVsKV09XCJkYXRhXCIgW2NvbmZpZ109XCJ7Li4ufVwiIGNvbmZpZ0ZpbGU9XCJmaWxlLmpzXCI+PC9ja2VkaXRvcj5cbiAqL1xuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdja2VkaXRvcicsXG4gICAgdGVtcGxhdGU6IGA8dGV4dGFyZWEgI2hvc3Q+PC90ZXh0YXJlYT5gLFxufSlcbkBSZWZsZWN0Lm1ldGFkYXRhKCdwYXJhbWV0ZXJzJywgW251bGwsIFtuZXcgT3B0aW9uYWxNZXRhZGF0YSgpXV0pXG5leHBvcnQgY2xhc3MgQ0tFZGl0b3Ige1xuXG4gICAgQElucHV0KCkgY29uZmlnO1xuICAgIEBJbnB1dCgpIGNvbmZpZ0ZpbGU7XG5cbiAgICBAT3V0cHV0KCkgY2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIEBWaWV3Q2hpbGQoJ2hvc3QnKSBob3N0O1xuICAgIEBWaWV3Q2hpbGQoJ2J1dHRvbicpIGJ1dHRvbjtcblxuICAgIHZhbHVlID0gJyc7XG4gICAgaW5zdGFuY2UgPSBudWxsO1xuICAgIG5nQ29udHJvbDtcbiAgICB6b25lO1xuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihlbGVtZW50UmVmOkVsZW1lbnRSZWYsIG5nQ29udHJvbDpOZ0NvbnRyb2wsIHpvbmU6Tmdab25lKXtcbiAgICAgICAgaWYoIG5nQ29udHJvbCApe1xuICAgICAgICAgICAgbmdDb250cm9sLnZhbHVlQWNjZXNzb3IgPSB0aGlzO1xuICAgICAgICAgICAgdGhpcy5uZ0NvbnRyb2wgPSBuZ0NvbnRyb2w7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnpvbmUgPSB6b25lO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE9uIGNvbXBvbmVudCBkZXN0cm95XG4gICAgICovXG4gICAgbmdPbkRlc3Ryb3koKXtcbiAgICAgICAgaWYoIHRoaXMuaW5zdGFuY2UgKSB7XG4gICAgICAgICAgICB0aGlzLmluc3RhbmNlLnJlbW92ZUFsbExpc3RlbmVycygpO1xuICAgICAgICAgICAgdGhpcy5pbnN0YW5jZS5kZXN0cm95KCk7XG4gICAgICAgICAgICB0aGlzLmluc3RhbmNlID0gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE9uIGNvbXBvbmVudCB2aWV3IGluaXRcbiAgICAgKi9cbiAgICBuZ0FmdGVyVmlld0luaXQoKXtcbiAgICAgICAgLy8gQ29uZmlndXJhdGlvblxuICAgICAgICB2YXIgY29uZmlnID0ge307XG5cbiAgICAgICAgLy8gRmV0Y2ggZmlsZVxuICAgICAgICBpZiggdGhpcy5jb25maWdGaWxlICl7XG5cbiAgICAgICAgICAgIGlmKCBTeXN0ZW0gJiYgU3lzdGVtLmltcG9ydCApe1xuICAgICAgICAgICAgICAgIFN5c3RlbS5pbXBvcnQodGhpcy5jb25maWdGaWxlKVxuICAgICAgICAgICAgICAgICAgICAudGhlbigocmVzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNrZWRpdG9ySW5pdCggcmVzLmNvbmZpZyApO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfVxuXG4gICAgICAgIC8vIENvbmZpZyBvYmplY3RcbiAgICAgICAgfWVsc2V7XG4gICAgICAgICAgICBjb25maWcgPSB0aGlzLmNvbmZpZyB8fCB7fTtcbiAgICAgICAgICAgIHRoaXMuY2tlZGl0b3JJbml0KCBjb25maWcgKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENLRWRpdG9yIGluaXRcbiAgICAgKi9cbiAgICBja2VkaXRvckluaXQoIGNvbmZpZyApe1xuICAgICAgICAvLyBDS0VkaXRvciByZXBsYWNlIHRleHRhcmVhXG4gICAgICAgIHRoaXMuaW5zdGFuY2UgPSBDS0VESVRPUi5yZXBsYWNlKCB0aGlzLmhvc3QuX2FwcEVsZW1lbnQubmF0aXZlRWxlbWVudCwgY29uZmlnICk7XG5cbiAgICAgICAgLy8gU2V0IGluaXRpYWwgdmFsdWVcbiAgICAgICAgdGhpcy5pbnN0YW5jZS5zZXREYXRhKHRoaXMudmFsdWUpO1xuXG4gICAgICAgIC8vIENoYW5nZSBldmVudFxuICAgICAgICB0aGlzLmluc3RhbmNlLm9uKCdjaGFuZ2UnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnpvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgdmFsdWUgPSB0aGlzLmluc3RhbmNlLmdldERhdGEoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmNoYW5nZS5lbWl0KCB2YWx1ZSApO1xuICAgICAgICAgICAgICAgIHRoaXMubmdDb250cm9sLnZpZXdUb01vZGVsVXBkYXRlKHZhbHVlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yXG4gICAgICovXG4gICAgd3JpdGVWYWx1ZSh2YWx1ZSl7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgaWYoIHRoaXMuaW5zdGFuY2UgKVxuICAgICAgICAgICAgdGhpcy5pbnN0YW5jZS5zZXREYXRhKHZhbHVlKTtcbiAgICB9XG4gICAgb25DaGFuZ2UoXyl7fVxuICAgIG9uVG91Y2hlZCgpe31cbiAgICByZWdpc3Rlck9uQ2hhbmdlKGZuKXt0aGlzLm9uQ2hhbmdlID0gZm47fVxuICAgIHJlZ2lzdGVyT25Ub3VjaGVkKGZuKXt0aGlzLm9uVG91Y2hlZCA9IGZuO31cbn1cbiJdfQ==
+Reflect.defineMetadata('design:paramtypes', [_core.ElementRef, _common.NgControl, _core.Renderer], CKEditor);
+//# sourceMappingURL=CKEditor.js.map
diff --git a/lib/CKEditor.js.map b/lib/CKEditor.js.map
new file mode 100644
index 0000000..28b3665
--- /dev/null
+++ b/lib/CKEditor.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["CKEditor.es6"],"names":[],"mappings":";;;;;;;;;;;;AACA;;AAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAYa,sCALZ,qBAAU;AACP,cAAU,UAAV;AACA,4EAFO;CAAV,WAIA,QAAQ,QAAR,CAAiB,YAAjB,EAA+B,CAAC,IAAD,EAAO,CAAC,4BAAD,CAAP,CAA/B,WAGI,4BACA,4BACA,4BAEA,6BACA,qBAAU,MAAV;;;;;;AAUD,aAjBS,QAiBT,CAAY,UAAZ,EAAmC,SAAnC,EAAwD,QAAxD,EAA0E;8BAjBjE,UAiBiE;;;;;;;;;;;;aAR1E,QAAQ,GAQkE;aAP1E,yBAO0E;aAN1E,2BAM0E;aAL1E,yBAK0E;;AACtE,YAAI,SAAJ,EAAe;AACX,sBAAU,aAAV,GAA0B,IAA1B,CADW;AAEX,iBAAK,SAAL,GAAiB,SAAjB,CAFW;SAAf;AAIA,aAAK,QAAL,GAAgB,QAAhB,CALsE;KAA1E;;;;;;;iBAjBS;;sCA4BI;AACT,gBAAI,KAAK,QAAL,EAAgB;AAChB,qBAAK,QAAL,CAAc,kBAAd,GADgB;AAEhB,qBAAK,QAAL,CAAc,OAAd,GAFgB;AAGhB,qBAAK,QAAL,GAAgB,IAAhB,CAHgB;aAApB;;;;;;;;;0CAUa;;;;AAEb,gBAAI,SAAS,EAAT;;;AAFS,gBAKT,KAAK,UAAL,EAAiB;;AAEjB,oBAAI,UAAU,OAAO,MAAP,EAAe;AACzB,2BAAO,MAAP,CAAc,KAAK,UAAL,CAAd,CACK,IADL,CACU,UAAC,GAAD,EAAS;AACX,8BAAK,YAAL,CAAmB,IAAI,MAAJ,CAAnB,CADW;qBAAT,CADV,CADyB;iBAA7B;;;AAFiB,aAArB,MAUK;AACD,6BAAS,KAAK,MAAL,IAAe,EAAf,CADR;AAED,yBAAK,YAAL,CAAmB,MAAnB,EAFC;iBAVL;;;;;;;;;sCAmBU,OAAM;AAChB,gBAAI,QAAQ,KAAK,IAAL,CAAU,aAAV,CAAwB,KAAxB,CADI;AAEhB,iBAAK,MAAL,CAAY,IAAZ,CAAkB,KAAlB,EAFgB;AAGhB,iBAAK,SAAL,CAAe,iBAAf,CAAkC,KAAlC,EAHgB;;;;;;;;;qCASN,QAAQ;;;AAElB,gBAAG,CAAC,QAAD,EAAU;AACT,wBAAQ,KAAR,CAAc,sCAAd,EADS;AAET,uBAFS;aAAb;;;AAFkB,gBAQlB,CAAK,QAAL,GAAgB,SAAS,OAAT,CAAkB,KAAK,IAAL,CAAU,aAAV,EAAyB,MAA3C,CAAhB;;;AARkB,gBAWlB,CAAK,QAAL,CAAc,OAAd,CAAsB,KAAK,KAAL,CAAtB;;;AAXkB,gBAclB,CAAK,QAAL,CAAc,EAAd,CAAiB,QAAjB,EAA2B,YAAM;AAC7B,uBAAK,QAAL,CAAc,kBAAd,CAAiC,OAAK,IAAL,CAAU,aAAV,EAAyB,OAA1D,EAAmE,OAAK,QAAL,CAAc,OAAd,EAAnE,EAD6B;AAE7B,uBAAK,QAAL,CAAc,mBAAd,CAAkC,OAAK,IAAL,CAAU,aAAV,EAAyB,eAA3D,EAA4E,CAAC,IAAI,KAAJ,CAAU,QAAV,CAAD,CAA5E,EAF6B;aAAN,CAA3B,CAdkB;;;;;;;;;mCAuBX,OAAM;AACb,iBAAK,KAAL,GAAa,KAAb,CADa;AAEb,gBAAI,KAAK,QAAL,EACA,KAAK,QAAL,CAAc,OAAd,CAAsB,KAAtB,EADJ;;;;iCAGK,GAAE;;;oCACA;;;yCACM,IAAG;AAAC,iBAAK,QAAL,GAAgB,EAAhB,CAAD;;;;0CACF,IAAG;AAAC,iBAAK,SAAL,GAAiB,EAAjB,CAAD;;;;WAvGZ;;;;oBAEA;;;;;oBACA;;;;;oBACA;;;;;eAEU;;;;;oBACA;;;mGAPV","file":"CKEditor.js","sourcesContent":["// Imports\nimport {\n    Component,\n    Directive,\n    Input,\n    Output,\n    ElementRef,\n    ViewChild,\n    Optional,\n    OptionalMetadata,\n    EventEmitter,\n    Renderer\n} from 'angular2/core';\nimport {NgControl, ControlValueAccessor} from 'angular2/common';\n\n/**\n * CKEditor component\n * Usage :\n * <ckeditor [(ngModel)]=\"data\" [config]=\"{...}\" configFile=\"file.js\"></ckeditor>\n */\n@Component({\n    selector: 'ckeditor',\n    template: `<textarea #host (change)=\"onValueChange($event)\"></textarea>`,\n})\n@Reflect.metadata('parameters', [null, [new OptionalMetadata()]])\nexport class CKEditor {\n\n    @Input() config;\n    @Input() configFile;\n    @Input() ngModel;\n\n    @Output() change = new EventEmitter();\n    @ViewChild('host') host;\n\n    value = '';\n    instance;\n    ngControl;\n    renderer;\n\n    /**\n     * Constructor\n     */\n    constructor(elementRef:ElementRef, ngControl:NgControl, renderer:Renderer){\n        if( ngControl ){\n            ngControl.valueAccessor = this;\n            this.ngControl = ngControl;\n        }\n        this.renderer = renderer;\n    }\n\n    /**\n     * On component destroy\n     */\n    ngOnDestroy(){\n        if( this.instance ) {\n            this.instance.removeAllListeners();\n            this.instance.destroy();\n            this.instance = null;\n        }\n    }\n\n    /**\n     * On component view init\n     */\n    ngAfterViewInit(){\n        // Configuration\n        var config = {};\n\n        // Fetch file\n        if( this.configFile ){\n\n            if( System && System.import ){\n                System.import(this.configFile)\n                    .then((res) => {\n                        this.ckeditorInit( res.config );\n                    })\n            }\n\n        // Config object\n        }else{\n            config = this.config || {};\n            this.ckeditorInit( config );\n        }\n    }\n\n    /**\n     * Detect textarea value change\n     */\n    onValueChange(event){\n        var value = this.host.nativeElement.value;\n        this.change.emit( value );\n        this.ngControl.viewToModelUpdate( value );\n    }\n\n    /**\n     * CKEditor init\n     */\n    ckeditorInit( config ){\n\n        if(!CKEDITOR){\n            console.error('Please include CKEditor in your page');\n            return;\n        }\n\n        // CKEditor replace textarea\n        this.instance = CKEDITOR.replace( this.host.nativeElement, config );\n\n        // Set initial value\n        this.instance.setData(this.value);\n\n        // CKEditor change event\n        this.instance.on('change', () => {\n            this.renderer.setElementProperty(this.host.nativeElement, 'value', this.instance.getData());\n            this.renderer.invokeElementMethod(this.host.nativeElement, 'dispatchEvent', [new Event('change')]);\n        });\n    }\n\n    /**\n     * Implements ControlValueAccessor\n     */\n    writeValue(value){\n        this.value = value;\n        if( this.instance )\n            this.instance.setData(value);\n    }\n    onChange(_){}\n    onTouched(){}\n    registerOnChange(fn){this.onChange = fn;}\n    registerOnTouched(fn){this.onTouched = fn;}\n}\n"],"sourceRoot":"/source/"}
\ No newline at end of file
diff --git a/package.json b/package.json
index b0359dc..ae176ce 100644
--- a/package.json
+++ b/package.json
@@ -23,16 +23,16 @@
   },
   "homepage": "https://github.com/chymz/ng2-ckeditor#readme",
   "devDependencies": {
-    "babel-cli": "^6.4.0",
-    "babel-plugin-angular2-annotations": "^5.0.0",
-    "babel-plugin-transform-class-properties": "^6.3.13",
-    "babel-plugin-transform-decorators-legacy": "^1.3.4",
-    "babel-plugin-transform-es2015-modules-commonjs": "^6.4.5",
-    "babel-plugin-transform-flow-strip-types": "~6.3.15",
-    "babel-preset-es2015": "~6.3.13",
-    "gulp": "^3.9.0",
-    "gulp-babel": "^6.1.1",
-    "gulp-cached": "^1.1.0",
-    "gulp-sourcemaps": "^1.6.0"
+    "babel-cli": "~6.7.5",
+    "babel-plugin-angular2-annotations": "~5.0.0",
+    "babel-plugin-transform-class-properties": "~6.6.0",
+    "babel-plugin-transform-decorators-legacy": "~1.3.4",
+    "babel-plugin-transform-es2015-modules-commonjs": "~6.7.4",
+    "babel-plugin-transform-flow-strip-types": "~6.7.0",
+    "babel-preset-es2015": "~6.6.0",
+    "gulp": "~3.9.0",
+    "gulp-babel": "~6.1.1",
+    "gulp-cached": "~1.1.0",
+    "gulp-sourcemaps": "~2.0.0-alpha",
   }
 }
diff --git a/src/CKEditor.es6 b/src/CKEditor.es6
index 9c7ca00..1451ec5 100644
--- a/src/CKEditor.es6
+++ b/src/CKEditor.es6
@@ -9,7 +9,7 @@ import {
     Optional,
     OptionalMetadata,
     EventEmitter,
-    NgZone
+    Renderer
 } from 'angular2/core';
 import {NgControl, ControlValueAccessor} from 'angular2/common';
 
@@ -20,33 +20,32 @@ import {NgControl, ControlValueAccessor} from 'angular2/common';
  */
 @Component({
     selector: 'ckeditor',
-    template: `<textarea #host></textarea>`,
+    template: `<textarea #host (change)="onValueChange($event)"></textarea>`,
 })
 @Reflect.metadata('parameters', [null, [new OptionalMetadata()]])
 export class CKEditor {
 
     @Input() config;
     @Input() configFile;
+    @Input() ngModel;
 
     @Output() change = new EventEmitter();
     @ViewChild('host') host;
-    @ViewChild('button') button;
 
     value = '';
-    instance = null;
+    instance;
     ngControl;
-    zone;
+    renderer;
 
     /**
      * Constructor
      */
-    constructor(elementRef:ElementRef, ngControl:NgControl, zone:NgZone){
+    constructor(elementRef:ElementRef, ngControl:NgControl, renderer:Renderer){
         if( ngControl ){
             ngControl.valueAccessor = this;
             this.ngControl = ngControl;
         }
-
-        this.zone = zone;
+        this.renderer = renderer;
     }
 
     /**
@@ -84,23 +83,35 @@ export class CKEditor {
         }
     }
 
+    /**
+     * Detect textarea value change
+     */
+    onValueChange(event){
+        var value = this.host.nativeElement.value;
+        this.change.emit( value );
+        this.ngControl.viewToModelUpdate( value );
+    }
+
     /**
      * CKEditor init
      */
     ckeditorInit( config ){
+
+        if(!CKEDITOR){
+            console.error('Please include CKEditor in your page');
+            return;
+        }
+
         // CKEditor replace textarea
-        this.instance = CKEDITOR.replace( this.host._appElement.nativeElement, config );
+        this.instance = CKEDITOR.replace( this.host.nativeElement, config );
 
         // Set initial value
         this.instance.setData(this.value);
 
-        // Change event
+        // CKEditor change event
         this.instance.on('change', () => {
-            this.zone.run(() => {
-                let value = this.instance.getData();
-                this.change.emit( value );
-                this.ngControl.viewToModelUpdate(value);
-            });
+            this.renderer.setElementProperty(this.host.nativeElement, 'value', this.instance.getData());
+            this.renderer.invokeElementMethod(this.host.nativeElement, 'dispatchEvent', [new Event('change')]);
         });
     }