From f5dd190d8f8752e9401a233b37fb95992d4a90fc Mon Sep 17 00:00:00 2001 From: Carl Ambroselli Date: Sat, 14 Nov 2015 19:08:35 +0100 Subject: [PATCH 1/2] Add ability to create codemirror with merge plugin, fixes #91 --- src/ui-codemirror.js | 93 ++++++++++++++++++++++++++++++++------------ 1 file changed, 69 insertions(+), 24 deletions(-) diff --git a/src/ui-codemirror.js b/src/ui-codemirror.js index 480f4f2..323fc2f 100644 --- a/src/ui-codemirror.js +++ b/src/ui-codemirror.js @@ -35,7 +35,19 @@ function uiCodemirrorDirective($timeout, uiCodemirrorConfig) { scope.$eval(iAttrs.uiCodemirrorOpts) ); - var codemirror = newCodemirrorEditor(iElement, codemirrorOptions); + var codemirror; + + var showMergeView = angular.isDefined(iAttrs.mergeView); + + if(showMergeView) { + if(angular.isUndefined(CodeMirror.MergeView)) { + throw new Error('merge-view needs the merge plugin and diff_match_patch to be loaded!'); + } + codemirror = newCodemirrorMergeEditor(iElement, codemirrorOptions); + } else { + codemirror = newCodemirrorEditor(iElement, codemirrorOptions); + } + configOptionsWatcher( codemirror, @@ -43,7 +55,8 @@ function uiCodemirrorDirective($timeout, uiCodemirrorConfig) { scope ); - configNgModelLink(codemirror, ngModel, scope); + configNgModelLink(codemirror, ngModel, scope, showMergeView); + configUiRefreshAttribute(codemirror, iAttrs.uiRefresh, scope); @@ -64,19 +77,28 @@ function uiCodemirrorDirective($timeout, uiCodemirrorConfig) { } function newCodemirrorEditor(iElement, codemirrorOptions) { - var codemirrot; + var codemirror; if (iElement[0].tagName === 'TEXTAREA') { // Might bug but still ... - codemirrot = window.CodeMirror.fromTextArea(iElement[0], codemirrorOptions); + codemirror = window.CodeMirror.fromTextArea(iElement[0], codemirrorOptions); } else { iElement.html(''); - codemirrot = new window.CodeMirror(function(cm_el) { + codemirror = new window.CodeMirror(function(cm_el) { iElement.append(cm_el); }, codemirrorOptions); } - return codemirrot; + return codemirror; + } + + function newCodemirrorMergeEditor(iElement, codemirrorOptions) { + var codemirror; + + iElement.html(''); + codemirror = new window.CodeMirror.MergeView(iElement[0], codemirrorOptions); + + return codemirror; } function configOptionsWatcher(codemirrot, uiCodemirrorAttr, scope) { @@ -99,7 +121,7 @@ function uiCodemirrorDirective($timeout, uiCodemirrorConfig) { } } - function configNgModelLink(codemirror, ngModel, scope) { + function configNgModelLink(codemirror, ngModel, scope, showMergeView) { if (!ngModel) { return; } // CodeMirror expects a string, so make sure it gets one. // This does not change the model. @@ -113,25 +135,46 @@ function uiCodemirrorDirective($timeout, uiCodemirrorConfig) { }); - // Override the ngModelController $render method, which is what gets called when the model is updated. - // This takes care of the synchronizing the codeMirror element with the underlying model, in the case that it is changed by something else. - ngModel.$render = function() { - //Code mirror expects a string so make sure it gets one - //Although the formatter have already done this, it can be possible that another formatter returns undefined (for example the required directive) - var safeViewValue = ngModel.$viewValue || ''; - codemirror.setValue(safeViewValue); - }; + // Keep the ngModel in sync with changes from CodeMirror + if(showMergeView) { + // Override the ngModelController $render method, which is what gets called when the model is updated. + // This takes care of the synchronizing the codeMirror element with the underlying model, in the case that it is changed by something else. + ngModel.$render = function() { + //Code mirror expects a string so make sure it gets one + //Although the formatter have already done this, it can be possible that another formatter returns undefined (for example the required directive) + var safeViewValue = ngModel.$viewValue || ''; + codemirror.edit.setValue(safeViewValue); + }; + + codemirror.edit.on('change', function(instance) { + var newValue = instance.getValue(); + if (newValue !== ngModel.$viewValue) { + scope.$evalAsync(function() { + ngModel.$setViewValue(newValue); + }); + } + }); + } else { + // Override the ngModelController $render method, which is what gets called when the model is updated. + // This takes care of the synchronizing the codeMirror element with the underlying model, in the case that it is changed by something else. + ngModel.$render = function() { + //Code mirror expects a string so make sure it gets one + //Although the formatter have already done this, it can be possible that another formatter returns undefined (for example the required directive) + var safeViewValue = ngModel.$viewValue || ''; + codemirror.setValue(safeViewValue); + }; + + codemirror.on('change', function(instance) { + var newValue = instance.getValue(); + if (newValue !== ngModel.$viewValue) { + scope.$evalAsync(function() { + ngModel.$setViewValue(newValue); + }); + } + }); + } - // Keep the ngModel in sync with changes from CodeMirror - codemirror.on('change', function(instance) { - var newValue = instance.getValue(); - if (newValue !== ngModel.$viewValue) { - scope.$evalAsync(function() { - ngModel.$setViewValue(newValue); - }); - } - }); } function configUiRefreshAttribute(codeMirror, uiRefreshAttr, scope) { @@ -148,3 +191,5 @@ function uiCodemirrorDirective($timeout, uiCodemirrorConfig) { } } + +uiCodemirrorDirective.$inject = ['$timeout', 'uiCodemirrorConfig']; From 8806332869a39f207ecc189edd0ae9e4b325f0d9 Mon Sep 17 00:00:00 2001 From: Carl Ambroselli Date: Sat, 14 Nov 2015 19:15:47 +0100 Subject: [PATCH 2/2] Search for CodeMirror in window object. --- src/ui-codemirror.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui-codemirror.js b/src/ui-codemirror.js index 323fc2f..22c2872 100644 --- a/src/ui-codemirror.js +++ b/src/ui-codemirror.js @@ -40,7 +40,7 @@ function uiCodemirrorDirective($timeout, uiCodemirrorConfig) { var showMergeView = angular.isDefined(iAttrs.mergeView); if(showMergeView) { - if(angular.isUndefined(CodeMirror.MergeView)) { + if(angular.isUndefined(window.CodeMirror.MergeView)) { throw new Error('merge-view needs the merge plugin and diff_match_patch to be loaded!'); } codemirror = newCodemirrorMergeEditor(iElement, codemirrorOptions);