angular-content-editable
Advanced tools
Comparing version 1.2.2 to 1.2.3
@@ -10,3 +10,3 @@ angular.module('angular-content-editable', []); | ||
require: 'ngModel', | ||
scope: { editCallback: '&?', isEditing: '=?' }, | ||
scope: { editCallback: '&?', isEditing: '=?', stripReplace: '=?' }, | ||
link: _link | ||
@@ -25,3 +25,3 @@ }; | ||
var noEscape = true, originalElement = elem[0], callback; | ||
var noEscape = true, originalElement = elem[0], callback, stripReplace; | ||
@@ -41,2 +41,5 @@ // get default usage options | ||
// Get the strip tags option from item scope or global defined | ||
stripReplace = scope.stripReplace || options.stripReplace; | ||
// add editable class | ||
@@ -130,3 +133,21 @@ attrs.$addClass(options.editableClass); | ||
if( html != ngModel.$modelValue ) { | ||
// if user defined strip-replace variable | ||
if( stripReplace ){ | ||
if( angular.isString(stripReplace) ) { | ||
// if stripReplace is a string create new RegExp with gi (global, ignore case) | ||
html = html.replace( new RegExp( stripReplace, 'g' ), '' ); | ||
}else if( angular.isArray(stripReplace) ){ | ||
// if stripReplace is an array create new RegExp from array values | ||
// get values from array or set default | ||
var e = stripReplace[0] || '', r = stripReplace[1] || '', f = stripReplace[2] || 'g'; | ||
html = html.replace( new RegExp( e, f ), r ); | ||
}else{ | ||
// if stripReplace is set to "true", remove all html tags and new line breaks | ||
html = html.replace(/(<([^>]+)>)/ig, '').replace(/\r?\n|\r/g, ''); | ||
} | ||
// update elem html value | ||
elem.html(html); | ||
} | ||
/** | ||
@@ -235,3 +256,4 @@ * This method should be called | ||
renderHtml: false, | ||
editCallback: false | ||
editCallback: false, | ||
stripReplace: false | ||
} | ||
@@ -238,0 +260,0 @@ |
@@ -1,1 +0,1 @@ | ||
angular.module("angular-content-editable",[]),angular.module("angular-content-editable").directive("contentEditable",["$log","$sce","$parse","$window","contentEditable",function($log,$sce,$parse,$window,contentEditable){function _link(scope,elem,attrs,ngModel){function onClick(e){e.preventDefault(),attrs.$set("contenteditable","true"),attrs.$addClass("active"),originalElement.focus()}function onFocus(e){scope.$evalAsync(function(){if(scope.isEditing=!0,noEscape=!0,options.focusSelect){var range=$window.document.createRange(),selection=$window.getSelection();range.selectNodeContents(originalElement),selection.removeAllRanges(),selection.addRange(range)}options.renderHtml&&(originalElement.textContent=elem.html())})}function onBlur(e){scope.$apply(function(){var html;if(scope.isEditing=!1,attrs.$removeClass("active"),attrs.$set("contenteditable","false"),options.renderHtml&&noEscape?(html=originalElement.textContent.replace(/\u00a0/g," "),elem.html(html)):html=elem.html().replace(/ /g," "),html!=ngModel.$modelValue&&(ngModel.$setViewValue(html),callback&&angular.isFunction(callback)))return callback({text:html,elem:elem})})}function onKeyDown(e){return 9==e.which?void originalElement.blur():27==e.which?(ngModel.$rollbackViewValue(),noEscape=!1,originalElement.blur()):13==e.which&&(options.singleLine||e.ctrlKey)?originalElement.blur():void 0}if(!ngModel)return void $log.warn("Error: ngModel is required in elem: ",elem);var callback,noEscape=!0,originalElement=elem[0],options=angular.copy(contentEditable);angular.forEach(options,function(val,key){key in attrs&&(options[key]=$parse(attrs[key])(scope))}),callback=scope.editCallback||options.editCallback,attrs.$addClass(options.editableClass),scope.$watch("isEditing",function(newValue,oldValue){newValue!==oldValue&&(newValue?originalElement.click():originalElement.blur())}),ngModel.$render=function(){elem.html(ngModel.$modelValue||elem.html())},elem.on("click",onClick),elem.on("focus",onFocus),elem.on("blur",onBlur),elem.on("keydown",onKeyDown),scope.$on("$destroy",function(){elem.off("click",onClick),elem.off("focus",onFocus),elem.off("blur",onBlur),elem.off("keydown",onKeyDown)})}return{restrict:"A",require:"ngModel",scope:{editCallback:"&?",isEditing:"=?"},link:_link}}]),angular.module("angular-content-editable").provider("contentEditable",function(){var defaults={editableClass:"editable",keyBindings:!0,singleLine:!1,focusSelect:!0,renderHtml:!1,editCallback:!1};this.configure=function(options){return angular.extend(defaults,options)},this.$get=function(){return defaults}}); | ||
angular.module("angular-content-editable",[]),angular.module("angular-content-editable").directive("contentEditable",["$log","$sce","$parse","$window","contentEditable",function($log,$sce,$parse,$window,contentEditable){function _link(scope,elem,attrs,ngModel){function onClick(e){e.preventDefault(),attrs.$set("contenteditable","true"),attrs.$addClass("active"),originalElement.focus()}function onFocus(e){scope.$evalAsync(function(){if(scope.isEditing=!0,noEscape=!0,options.focusSelect){var range=$window.document.createRange(),selection=$window.getSelection();range.selectNodeContents(originalElement),selection.removeAllRanges(),selection.addRange(range)}options.renderHtml&&(originalElement.textContent=elem.html())})}function onBlur(e){scope.$apply(function(){var html;if(scope.isEditing=!1,attrs.$removeClass("active"),attrs.$set("contenteditable","false"),options.renderHtml&&noEscape?(html=originalElement.textContent.replace(/\u00a0/g," "),elem.html(html)):html=elem.html().replace(/ /g," "),html!=ngModel.$modelValue){if(stripReplace){if(angular.isString(stripReplace))html=html.replace(new RegExp(stripReplace,"g"),"");else if(angular.isArray(stripReplace)){var e=stripReplace[0]||"",r=stripReplace[1]||"",f=stripReplace[2]||"g";html=html.replace(new RegExp(e,f),r)}else html=html.replace(/(<([^>]+)>)/gi,"").replace(/\r?\n|\r/g,"");elem.html(html)}if(ngModel.$setViewValue(html),callback&&angular.isFunction(callback))return callback({text:html,elem:elem})}})}function onKeyDown(e){return 9==e.which?void originalElement.blur():27==e.which?(ngModel.$rollbackViewValue(),noEscape=!1,originalElement.blur()):13==e.which&&(options.singleLine||e.ctrlKey)?originalElement.blur():void 0}if(!ngModel)return void $log.warn("Error: ngModel is required in elem: ",elem);var callback,stripReplace,noEscape=!0,originalElement=elem[0],options=angular.copy(contentEditable);angular.forEach(options,function(val,key){key in attrs&&(options[key]=$parse(attrs[key])(scope))}),callback=scope.editCallback||options.editCallback,stripReplace=scope.stripReplace||options.stripReplace,attrs.$addClass(options.editableClass),scope.$watch("isEditing",function(newValue,oldValue){newValue!==oldValue&&(newValue?originalElement.click():originalElement.blur())}),ngModel.$render=function(){elem.html(ngModel.$modelValue||elem.html())},elem.on("click",onClick),elem.on("focus",onFocus),elem.on("blur",onBlur),elem.on("keydown",onKeyDown),scope.$on("$destroy",function(){elem.off("click",onClick),elem.off("focus",onFocus),elem.off("blur",onBlur),elem.off("keydown",onKeyDown)})}return{restrict:"A",require:"ngModel",scope:{editCallback:"&?",isEditing:"=?",stripReplace:"=?"},link:_link}}]),angular.module("angular-content-editable").provider("contentEditable",function(){var defaults={editableClass:"editable",keyBindings:!0,singleLine:!1,focusSelect:!0,renderHtml:!1,editCallback:!1,stripReplace:!1};this.configure=function(options){return angular.extend(defaults,options)},this.$get=function(){return defaults}}); |
{ | ||
"name": "angular-content-editable", | ||
"version": "1.2.2", | ||
"version": "1.2.3", | ||
"description": "modify in real time any html tag you want", | ||
@@ -5,0 +5,0 @@ "main": "dist/angular-content-editable.js", |
@@ -40,2 +40,3 @@ # angular-content-editable | ||
* __is-editing__: optional argument that can be used to programatically enable/disable the editor | ||
* __strip-replace__: optional argument that can be `true` to remove all HTML tags and line breaks, `string` to remove or custom regular `expression`, or array with `expression` to match with `replacement` to and `flags` use: `['expression','replacement','flags']` | ||
@@ -85,2 +86,14 @@ Note that, __edit-callback__ has two arguments, that you must specify in your template to use them: | ||
With __strip-replace__ attribute set as `boolean`: | ||
```html | ||
<!-- boolean: removes all HTML tags and line breaks --> | ||
<span focus-select="true" ng-model="myModel" strip-replace="true" content-editable>Change me!<br><b>I will become clear text without formating</b></span> | ||
``` | ||
With __strip-replace__ attribute set as `array`: | ||
```html | ||
<!-- array: creates new RegExp() from array ['string / regular expression','replace with','expression flags'] --> | ||
<span focus-select="true" ng-model="myModel" strip-replace="[' ','-','gi']" content-editable>Change me!</span> | ||
``` | ||
If you want to run a callback you must use __edit-callback__ attribute with a valid function and it will run every time the model value is __changed__. | ||
@@ -87,0 +100,0 @@ |
@@ -8,3 +8,3 @@ angular.module('angular-content-editable') | ||
require: 'ngModel', | ||
scope: { editCallback: '&?', isEditing: '=?' }, | ||
scope: { editCallback: '&?', isEditing: '=?', stripReplace: '=?' }, | ||
link: _link | ||
@@ -23,3 +23,3 @@ }; | ||
var noEscape = true, originalElement = elem[0], callback; | ||
var noEscape = true, originalElement = elem[0], callback, stripReplace; | ||
@@ -39,2 +39,5 @@ // get default usage options | ||
// Get the strip tags option from item scope or global defined | ||
stripReplace = scope.stripReplace || options.stripReplace; | ||
// add editable class | ||
@@ -128,3 +131,21 @@ attrs.$addClass(options.editableClass); | ||
if( html != ngModel.$modelValue ) { | ||
// if user defined strip-replace variable | ||
if( stripReplace ){ | ||
if( angular.isString(stripReplace) ) { | ||
// if stripReplace is a string create new RegExp with gi (global, ignore case) | ||
html = html.replace( new RegExp( stripReplace, 'g' ), '' ); | ||
}else if( angular.isArray(stripReplace) ){ | ||
// if stripReplace is an array create new RegExp from array values | ||
// get values from array or set default | ||
var e = stripReplace[0] || '', r = stripReplace[1] || '', f = stripReplace[2] || 'g'; | ||
html = html.replace( new RegExp( e, f ), r ); | ||
}else{ | ||
// if stripReplace is set to "true", remove all html tags and new line breaks | ||
html = html.replace(/(<([^>]+)>)/ig, '').replace(/\r?\n|\r/g, ''); | ||
} | ||
// update elem html value | ||
elem.html(html); | ||
} | ||
/** | ||
@@ -131,0 +152,0 @@ * This method should be called |
@@ -15,3 +15,4 @@ angular.module('angular-content-editable') | ||
renderHtml: false, | ||
editCallback: false | ||
editCallback: false, | ||
stripReplace: false | ||
} | ||
@@ -18,0 +19,0 @@ |
@@ -55,2 +55,22 @@ describe("Angular Content Editable: Directive", function () { | ||
}); | ||
it('should strip all html tags from text', function () { | ||
element = angular.element('<h1 ng-model="myModel" edit-callback="onEdit(\'extraArg\', text, elem)" is-editing="isEditing" strip-replace="true" content-editable></h1>'); | ||
$compile(element)(scope); | ||
scope.$digest(); | ||
element.triggerHandler('click'); | ||
element.html('Some random text <b>change</b>.'); | ||
element.triggerHandler('blur'); | ||
expect(element.html()).toContain("Some random text change."); | ||
}); | ||
it('should replace all matching strings', function () { | ||
element = angular.element('<h1 ng-model="myModel" edit-callback="onEdit(\'extraArg\', text, elem)" is-editing="isEditing" strip-replace="[\'change\',\'success\',\'g\']" content-editable></h1>'); | ||
$compile(element)(scope); | ||
scope.$digest(); | ||
element.triggerHandler('click'); | ||
element.html('Some random text change.'); | ||
element.triggerHandler('blur'); | ||
expect(element.html()).toContain("Some random text success."); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
38109
661
143