diff --git a/src/textAngular.js b/src/textAngular.js index 1abd2c0a..ae874d13 100644 --- a/src/textAngular.js +++ b/src/textAngular.js @@ -821,7 +821,7 @@ See README.md or https://github.com/fraywing/textAngular/wiki for requirements a listElement.remove(); selectLi($target.find('li')[0]); }; - return function(taDefaultWrap){ + return function(taDefaultWrap, topNode){ taDefaultWrap = taBrowserTag(taDefaultWrap); return function(command, showUI, options){ var i, $target, html, _nodes, next, optionsTagName, selectedElement; @@ -988,11 +988,11 @@ See README.md or https://github.com/fraywing/textAngular/wiki for requirements a var _selection = taSelection.getSelection(); if(_selection.collapsed){ // insert text at selection, then select then just let normal exec-command run - taSelection.insertHtml('' + options + ''); + taSelection.insertHtml('' + options + '', topNode); return; } }else if(command.toLowerCase() === 'inserthtml'){ - taSelection.insertHtml(options); + taSelection.insertHtml(options, topNode); return; } } @@ -1020,14 +1020,14 @@ See README.md or https://github.com/fraywing/textAngular/wiki for requirements a // defaults to the paragraph element, but we need the line-break or it doesn't allow you to type into the empty element // non IE is '
' : '
'; - _trimTest = (ie === undefined)? /^
(\s| )*<\/p>$/ig;
}else{
_defaultVal = (ie === undefined || ie >= 11)?
'<' + attrs.taDefaultWrap + '>
' + attrs.taDefaultWrap + '>' :
@@ -1039,9 +1039,15 @@ See README.md or https://github.com/fraywing/textAngular/wiki for requirements a
(ie <= 8)?
'<' + attrs.taDefaultWrap.toUpperCase() + '> ' + attrs.taDefaultWrap.toUpperCase() + '>' :
'<' + attrs.taDefaultWrap + '> ' + attrs.taDefaultWrap + '>';
- _trimTest = new RegExp('^<' + attrs.taDefaultWrap + '>(\\s| )*<\\/' + attrs.taDefaultWrap + '>$', 'ig');
}
+ var _blankTest = function(val){
+ val = val.trim();
+ if(val.length === 0 || val === _defaultTest || _trimTest.test(val)) return true;
+ if(/>\s*(([^\s<]+)\s*)+]+\s*)+$/.test(val)) return false;// this regex tests if there is some content that isn't white space between tags, or there is just some text passed in
+ return true;
+ };
+
element.addClass('ta-bind');
var _undoKeyupTimeout;
@@ -1118,7 +1124,7 @@ See README.md or https://github.com/fraywing/textAngular/wiki for requirements a
var _setViewValue = function(val, triggerUndo){
if(typeof triggerUndo === "undefined" || triggerUndo === null) triggerUndo = true && _isContentEditable; // if not contentEditable then the native undo/redo is fine
if(!val) val = _compileHtml();
- if(val === _defaultTest || _trimTest.test(val)){
+ if(_blankTest(val)){
// this avoids us from tripping the ng-pristine flag if we click in and out with out typing
if(ngModel.$viewValue !== '') ngModel.$setViewValue('');
if(triggerUndo && ngModel.$undoManager.current() !== '') ngModel.$undoManager.push('');
@@ -1235,7 +1241,7 @@ See README.md or https://github.com/fraywing/textAngular/wiki for requirements a
}
text = taSanitize(text, '', _disableSanitizer);
- taSelection.insertHtml(text);
+ taSelection.insertHtml(text, element[0]);
$timeout(function(){
ngModel.$setViewValue(_compileHtml());
}, 0);
@@ -1379,7 +1385,7 @@ See README.md or https://github.com/fraywing/textAngular/wiki for requirements a
// trigger the validation calls
var _validity = function(value){
- if(attrs.required) ngModel.$setValidity('required', !(!value || value.trim() === _defaultTest || value.trim().match(_trimTest) || value.trim() === ''));
+ if(attrs.required) ngModel.$setValidity('required', !_blankTest(value));
return value;
};
// parsers trigger from the above keyup function or any other time that the viewValue is updated and parses it for storage in the ngModel
@@ -1387,6 +1393,14 @@ See README.md or https://github.com/fraywing/textAngular/wiki for requirements a
ngModel.$parsers.push(_validity);
// because textAngular is bi-directional (which is awesome) we need to also sanitize values going in from the server
ngModel.$formatters.push(_sanitize);
+ ngModel.$formatters.push(function(value){
+ if(_blankTest(value)) return value;
+ var domTest = angular.element("
Test 2 Content
'); + }); it('should prevent links default event', function () { $rootScope.html = ''; + $rootScope.$digest(); + }); + it('ng-required', function(){ + expect($rootScope.form.test.$error.required).toBe(true); + }); + it('valid', function(){ + expect($rootScope.form.$valid).toBe(false); + }); + it('field valid', function(){ + expect($rootScope.form.test.$valid).toBe(false); + }); + }); + describe('should change on input update', function () { beforeEach(inject(function(textAngularManager){ element.html('
Test Contents
'); })); it('should handle initial null to originalContents', inject(function ($compile, $rootScope, textAngularManager) { $rootScope.html = null; var element = $compile('Test Contents
'); })); describe('should reset', function(){