Skip to content
This repository has been archived by the owner on May 25, 2019. It is now read-only.

Commit

Permalink
Webpack minimisation and CommonJS support.
Browse files Browse the repository at this point in the history
  • Loading branch information
Antonios Sarhanis committed Sep 27, 2018
1 parent 892b096 commit f700368
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 117 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ bower_components/
node_modules/
out/
dist/
.idea/
258 changes: 141 additions & 117 deletions src/ui-codemirror.js
Original file line number Diff line number Diff line change
@@ -1,150 +1,174 @@
/*global module */
'use strict';

/**
* Binds a CodeMirror widget to a <textarea> element.
*/
angular.module('ui.codemirror', [])
.constant('uiCodemirrorConfig', {})
.directive('uiCodemirror', uiCodemirrorDirective);

/**
* @ngInject
*/
function uiCodemirrorDirective($timeout, uiCodemirrorConfig) {

return {
restrict: 'EA',
require: '?ngModel',
compile: function compile() {

// Require CodeMirror
if (angular.isUndefined(window.CodeMirror)) {
throw new Error('ui-codemirror needs CodeMirror to work... (o rly?)');
(function(factory) {
var moduleName = 'ui.codemirror';
if (typeof module === 'object' && module.exports) {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports,
// like Node.
module.exports = moduleName;
factory(moduleName);
} else {
factory(moduleName);
}
}(function(moduleName) {

/**
* Binds a CodeMirror widget to a <textarea> element.
*/
angular.module(moduleName, [])
.constant('uiCodemirrorConfig', {})
.directive('uiCodemirror', ['$timeout', 'uiCodemirrorConfig', uiCodemirrorDirective]);

/**
* @ngInject
*/
function uiCodemirrorDirective($timeout, uiCodemirrorConfig) {

return {
restrict: 'EA',
require: '?ngModel',
compile: function compile() {

// Require CodeMirror
if (angular.isUndefined(window.CodeMirror)) {
throw new Error('ui-codemirror needs CodeMirror to work... (o rly?)');
}

return postLink;
}
};

return postLink;
}
};
function postLink(scope, iElement, iAttrs, ngModel) {

function postLink(scope, iElement, iAttrs, ngModel) {
var codemirrorOptions = angular.extend(
{value: iElement.text()},
uiCodemirrorConfig.codemirror || {},
scope.$eval(iAttrs.uiCodemirror),
scope.$eval(iAttrs.uiCodemirrorOpts)
);

var codemirrorOptions = angular.extend(
{ value: iElement.text() },
uiCodemirrorConfig.codemirror || {},
scope.$eval(iAttrs.uiCodemirror),
scope.$eval(iAttrs.uiCodemirrorOpts)
);
var codemirror = newCodemirrorEditor(iElement, codemirrorOptions);

var codemirror = newCodemirrorEditor(iElement, codemirrorOptions);
configOptionsWatcher(
codemirror,
iAttrs.uiCodemirror || iAttrs.uiCodemirrorOpts,
scope
);

configOptionsWatcher(
codemirror,
iAttrs.uiCodemirror || iAttrs.uiCodemirrorOpts,
scope
);
configNgModelLink(codemirror, ngModel, scope);

configUiRefreshAttribute(codemirror, iAttrs.uiRefresh, scope);

// Allow access to the CodeMirror instance through a broadcasted event
// eg: $broadcast('CodeMirror', function(cm){...});
scope.$on('CodeMirror', function(event, callback) {
if (angular.isFunction(callback)) {
callback(codemirror);
} else {
throw new Error('the CodeMirror event requires a callback function');
}
});

configNgModelLink(codemirror, ngModel, scope);
// onLoad callback
if (angular.isFunction(codemirrorOptions.onLoad)) {
codemirrorOptions.onLoad(codemirror);
}
}

configUiRefreshAttribute(codemirror, iAttrs.uiRefresh, scope);
function newCodemirrorEditor(iElement, codemirrorOptions) {
var codemirrot;

// Allow access to the CodeMirror instance through a broadcasted event
// eg: $broadcast('CodeMirror', function(cm){...});
scope.$on('CodeMirror', function(event, callback) {
if (angular.isFunction(callback)) {
callback(codemirror);
if (iElement[0].tagName === 'TEXTAREA') {
// Might bug but still ...
codemirrot = window.CodeMirror.fromTextArea(iElement[0], codemirrorOptions);
} else {
throw new Error('the CodeMirror event requires a callback function');
iElement.html('');
codemirrot = new window.CodeMirror(function(cm_el) {
iElement.append(cm_el);
}, codemirrorOptions);
}
});

// onLoad callback
if (angular.isFunction(codemirrorOptions.onLoad)) {
codemirrorOptions.onLoad(codemirror);
return codemirrot;
}
}

function newCodemirrorEditor(iElement, codemirrorOptions) {
var codemirrot;

if (iElement[0].tagName === 'TEXTAREA') {
// Might bug but still ...
codemirrot = window.CodeMirror.fromTextArea(iElement[0], codemirrorOptions);
} else {
iElement.html('');
codemirrot = new window.CodeMirror(function(cm_el) {
iElement.append(cm_el);
}, codemirrorOptions);
}
function configOptionsWatcher(codemirrot, uiCodemirrorAttr, scope) {
if (!uiCodemirrorAttr) {
return;
}

return codemirrot;
}
var codemirrorDefaultsKeys = Object.keys(window.CodeMirror.defaults);
scope.$watch(uiCodemirrorAttr, updateOptions, true);

function configOptionsWatcher(codemirrot, uiCodemirrorAttr, scope) {
if (!uiCodemirrorAttr) { return; }
function updateOptions(newValues, oldValue) {
if (!angular.isObject(newValues)) {
return;
}
codemirrorDefaultsKeys.forEach(function(key) {
if (newValues.hasOwnProperty(key)) {

var codemirrorDefaultsKeys = Object.keys(window.CodeMirror.defaults);
scope.$watch(uiCodemirrorAttr, updateOptions, true);
function updateOptions(newValues, oldValue) {
if (!angular.isObject(newValues)) { return; }
codemirrorDefaultsKeys.forEach(function(key) {
if (newValues.hasOwnProperty(key)) {
if (oldValue && newValues[key] === oldValue[key]) {
return;
}

if (oldValue && newValues[key] === oldValue[key]) {
return;
codemirrot.setOption(key, newValues[key]);
}
});
}
}

codemirrot.setOption(key, newValues[key]);
function configNgModelLink(codemirror, ngModel, scope) {
if (!ngModel) {
return;
}
// CodeMirror expects a string, so make sure it gets one.
// This does not change the model.
ngModel.$formatters.push(function(value) {
if (angular.isUndefined(value) || value === null) {
return '';
} else if (angular.isObject(value) || angular.isArray(value)) {
throw new Error('ui-codemirror cannot use an object or an array as a model');
}
return value;
});
}
}

function configNgModelLink(codemirror, ngModel, scope) {
if (!ngModel) { return; }
// CodeMirror expects a string, so make sure it gets one.
// This does not change the model.
ngModel.$formatters.push(function(value) {
if (angular.isUndefined(value) || value === null) {
return '';
} else if (angular.isObject(value) || angular.isArray(value)) {
throw new Error('ui-codemirror cannot use an object or an array as a model');
}
return value;
});

// 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);
};

// 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
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) {
if (!uiRefreshAttr) {
return;
}
});
}

function configUiRefreshAttribute(codeMirror, uiRefreshAttr, scope) {
if (!uiRefreshAttr) { return; }
scope.$watch(uiRefreshAttr, function(newVal, oldVal) {
// Skip the initial watch firing
if (newVal !== oldVal) {
$timeout(function() {
codeMirror.refresh();
});
}
});
}

scope.$watch(uiRefreshAttr, function(newVal, oldVal) {
// Skip the initial watch firing
if (newVal !== oldVal) {
$timeout(function() {
codeMirror.refresh();
});
}
});
}

}
}));

0 comments on commit f700368

Please sign in to comment.