angular-content-editable
Advanced tools
Comparing version
@@ -5,175 +5,181 @@ angular.module('angular-content-editable', []); | ||
.directive('contentEditable', ['$log', '$sce', '$compile', '$window', 'contentEditable', function ($log,$sce,$compile,$window,contentEditable) { | ||
.directive('contentEditable', ['$log', '$sce', '$parse', '$window', 'contentEditable', function ($log, $sce, $parse, $window, contentEditable) { | ||
var directive = { | ||
restrict: 'A', | ||
require: '?ngModel', | ||
scope: { editCallback: '=', ngModel: '=' }, | ||
link: _link | ||
} | ||
var directive = { | ||
restrict: 'A', | ||
require: '?ngModel', | ||
scope: { editCallback: '=' }, | ||
link: _link | ||
} | ||
return directive; | ||
return directive; | ||
function _link(scope, elem, attrs, ngModel) { | ||
function _link(scope, elem, attrs, ngModel) { | ||
// return if ng model not specified | ||
if(!ngModel) { | ||
$log.warn('Error: ngModel is required in elem: ', elem); | ||
return; | ||
} | ||
// return if ng model not specified | ||
if(!ngModel) { | ||
$log.warn('Error: ngModel is required in elem: ', elem); | ||
return; | ||
} | ||
var noEscape = true; | ||
var originalElement = elem[0]; | ||
// get default usage options | ||
var options = angular.copy(contentEditable); | ||
// update options with attributes | ||
angular.forEach(options, function (val, key) { | ||
if( key in attrs && typeof attrs[key] !== 'undefined' ) { options[key] = attrs[key]; } | ||
}) | ||
var noEscape = true; | ||
var originalElement = elem[0]; | ||
// if model is invalid or null | ||
// fill his value with elem html content | ||
if( !scope.ngModel ) { | ||
ngModel.$setViewValue( elem.html() ); | ||
} | ||
// get default usage options | ||
var options = angular.copy(contentEditable); | ||
// add editable class | ||
attrs.$addClass(options.editableClass); | ||
// update options with attributes | ||
angular.forEach(options, function (val, key) { | ||
if( key in attrs ) { | ||
options[key] = $parse(attrs[key])(scope); | ||
} | ||
}); | ||
// render always with model value | ||
ngModel.$render = function() { | ||
elem.html( ngModel.$modelValue || '' ); | ||
} | ||
// if model is invalid or null | ||
// fill his value with elem html content | ||
if( !scope.ngModel ) { | ||
ngModel.$setViewValue( elem.html() ); | ||
} | ||
// handle click on element | ||
function onClick(e){ | ||
e.preventDefault(); | ||
attrs.$set('contenteditable', 'true'); | ||
return originalElement.focus(); | ||
} | ||
// add editable class | ||
attrs.$addClass(options.editableClass); | ||
// check some option extra | ||
// conditions during focus | ||
function onFocus(e) { | ||
// turn on the flag | ||
noEscape = true; | ||
// select all on focus | ||
if( options.focusSelect ) { | ||
var range = $window.document.createRange(); | ||
range.selectNodeContents( originalElement ); | ||
$window.getSelection().addRange(range); | ||
} | ||
// if render-html is enabled convert | ||
// all text content to plaintext | ||
// in order to modify html tags | ||
if( options.renderHtml ) { | ||
originalElement.textContent = elem.html(); | ||
} | ||
} | ||
// render always with model value | ||
ngModel.$render = function() { | ||
elem.html( ngModel.$modelValue || '' ); | ||
} | ||
function onBlur(e) { | ||
// handle click on element | ||
function onClick(e){ | ||
e.preventDefault(); | ||
attrs.$set('contenteditable', 'true'); | ||
return originalElement.focus(); | ||
} | ||
// the text | ||
var html; | ||
// check some option extra | ||
// conditions during focus | ||
function onFocus(e) { | ||
// turn on the flag | ||
noEscape = true; | ||
// select all on focus | ||
if( options.focusSelect ) { | ||
var range = $window.document.createRange(); | ||
var selection = $window.getSelection(); | ||
range.selectNodeContents( originalElement ); | ||
selection.removeAllRanges(); | ||
selection.addRange(range); | ||
} | ||
// if render-html is enabled convert | ||
// all text content to plaintext | ||
// in order to modify html tags | ||
if( options.renderHtml ) { | ||
originalElement.textContent = elem.html(); | ||
} | ||
} | ||
// disable editability | ||
attrs.$set('contenteditable', 'false'); | ||
function onBlur(e) { | ||
// if text needs to be rendered as html | ||
if( options.renderHtml && noEscape ) { | ||
// get plain text html (with html tags) | ||
// replace all blank spaces | ||
html = originalElement.textContent.replace(/\u00a0/g, " "); | ||
// update elem html value | ||
elem.html(html); | ||
// the text | ||
var html; | ||
} else { | ||
// get element content replacing html tag | ||
html = elem.html().replace(/ /g, ' '); | ||
} | ||
// disable editability | ||
attrs.$set('contenteditable', 'false'); | ||
// if element value is | ||
// different from model value | ||
if( html != ngModel.$modelValue ) { | ||
// if text needs to be rendered as html | ||
if( options.renderHtml && noEscape ) { | ||
// get plain text html (with html tags) | ||
// replace all blank spaces | ||
html = originalElement.textContent.replace(/\u00a0/g, " "); | ||
// update elem html value | ||
elem.html(html); | ||
/** | ||
* This method should be called | ||
* when a controller wants to | ||
* change the view value | ||
*/ | ||
ngModel.$setViewValue(html) | ||
// if user passed a variable | ||
// and is a function | ||
if( scope.editCallback && angular.isFunction(scope.editCallback) ) { | ||
// apply the callback | ||
// with arguments: current text and element | ||
return scope.$apply( scope.editCallback(html, elem) ); | ||
} | ||
} else { | ||
// get element content replacing html tag | ||
html = elem.html().replace(/ /g, ' '); | ||
} | ||
} | ||
// if element value is | ||
// different from model value | ||
if( html != ngModel.$modelValue ) { | ||
/** | ||
* This method should be called | ||
* when a controller wants to | ||
* change the view value | ||
*/ | ||
ngModel.$setViewValue(html) | ||
// if user passed a variable | ||
// and is a function | ||
if( scope.editCallback && angular.isFunction(scope.editCallback) ) { | ||
// apply the callback | ||
// with arguments: current text and element | ||
return scope.$apply( scope.editCallback(html, elem) ); | ||
} | ||
function onKeyDown(e) { | ||
} | ||
// on tab key blur and | ||
// TODO: focus to next | ||
if( e.which == 9 ) { | ||
originalElement.blur(); | ||
return; | ||
} | ||
} | ||
// on esc key roll back value and blur | ||
if( e.which == 27 ) { | ||
ngModel.$rollbackViewValue(); | ||
noEscape = false; | ||
return originalElement.blur(); | ||
} | ||
function onKeyDown(e) { | ||
// if single line or ctrl key is | ||
// pressed trigger the blur event | ||
if( e.which == 13 && (options.singleLine || e.ctrlKey) ) { | ||
return originalElement.blur(); | ||
} | ||
// on tab key blur and | ||
// TODO: focus to next | ||
if( e.which == 9 ) { | ||
originalElement.blur(); | ||
return; | ||
} | ||
} | ||
// on esc key roll back value and blur | ||
if( e.which == 27 ) { | ||
ngModel.$rollbackViewValue(); | ||
noEscape = false; | ||
return originalElement.blur(); | ||
} | ||
/** | ||
* On click turn the element | ||
* to editable and focus it | ||
*/ | ||
elem.bind('click', onClick); | ||
// if single line or ctrl key is | ||
// pressed trigger the blur event | ||
if( e.which == 13 && (options.singleLine || e.ctrlKey) ) { | ||
return originalElement.blur(); | ||
} | ||
/** | ||
* On element focus | ||
*/ | ||
elem.bind('focus', onFocus); | ||
} | ||
/** | ||
* On element blur turn off | ||
* editable mode, if HTML, render | ||
* update model value and run callback | ||
* if specified | ||
*/ | ||
elem.bind('blur', onBlur); | ||
/** | ||
* On click turn the element | ||
* to editable and focus it | ||
*/ | ||
elem.on('click', onClick); | ||
/** | ||
* Bind the keydown event for many functions | ||
* TODO: more to come | ||
*/ | ||
elem.bind('keydown', onKeyDown); | ||
/** | ||
* On element focus | ||
*/ | ||
elem.on('focus', onFocus); | ||
/** | ||
* On element destroy, remove all event | ||
* listeners related to the directive | ||
* (helps to prevent memory leaks) | ||
*/ | ||
scope.$on('$destroy', function () { | ||
elem.unbind(onClick); | ||
elem.unbind(onFocus); | ||
elem.unbind(onBlur); | ||
}) | ||
/** | ||
* On element blur turn off | ||
* editable mode, if HTML, render | ||
* update model value and run callback | ||
* if specified | ||
*/ | ||
elem.on('blur', onBlur); | ||
} | ||
/** | ||
* Bind the keydown event for many functions | ||
*/ | ||
elem.on('keydown', onKeyDown); | ||
/** | ||
* On element destroy, remove all event | ||
* listeners related to the directive | ||
* (helps to prevent memory leaks) | ||
*/ | ||
scope.$on('$destroy', function () { | ||
elem.off('click', onClick); | ||
elem.off('focus', onFocus); | ||
elem.off('blur', onBlur); | ||
elem.off('keydown', onKeyDown); | ||
}); | ||
} | ||
}]) | ||
@@ -180,0 +186,0 @@ |
@@ -1,1 +0,1 @@ | ||
angular.module("angular-content-editable",[]),angular.module("angular-content-editable").directive("contentEditable",["$log","$sce","$compile","$window","contentEditable",function($log,$sce,$compile,$window,contentEditable){function _link(scope,elem,attrs,ngModel){function onClick(e){return e.preventDefault(),attrs.$set("contenteditable","true"),originalElement.focus()}function onFocus(e){if(noEscape=!0,options.focusSelect){var range=$window.document.createRange();range.selectNodeContents(originalElement),$window.getSelection().addRange(range)}options.renderHtml&&(originalElement.textContent=elem.html())}function onBlur(e){var html;if(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),scope.editCallback&&angular.isFunction(scope.editCallback)))return scope.$apply(scope.editCallback(html,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 noEscape=!0,originalElement=elem[0],options=angular.copy(contentEditable);angular.forEach(options,function(val,key){key in attrs&&"undefined"!=typeof attrs[key]&&(options[key]=attrs[key])}),scope.ngModel||ngModel.$setViewValue(elem.html()),attrs.$addClass(options.editableClass),ngModel.$render=function(){elem.html(ngModel.$modelValue||"")},elem.bind("click",onClick),elem.bind("focus",onFocus),elem.bind("blur",onBlur),elem.bind("keydown",onKeyDown),scope.$on("$destroy",function(){elem.unbind(onClick),elem.unbind(onFocus),elem.unbind(onBlur)})}var directive={restrict:"A",require:"?ngModel",scope:{editCallback:"=",ngModel:"="},link:_link};return directive}]),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){return e.preventDefault(),attrs.$set("contenteditable","true"),originalElement.focus()}function onFocus(e){if(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){var html;if(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),scope.editCallback&&angular.isFunction(scope.editCallback)))return scope.$apply(scope.editCallback(html,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 noEscape=!0,originalElement=elem[0],options=angular.copy(contentEditable);angular.forEach(options,function(val,key){key in attrs&&(options[key]=$parse(attrs[key])(scope))}),scope.ngModel||ngModel.$setViewValue(elem.html()),attrs.$addClass(options.editableClass),ngModel.$render=function(){elem.html(ngModel.$modelValue||"")},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:"="},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}}); |
@@ -26,2 +26,5 @@ module.exports = function(grunt) { | ||
watch: { | ||
options: { | ||
spawn: false | ||
}, | ||
files: ['src/**/*.js'], | ||
@@ -28,0 +31,0 @@ tasks: ['build'], |
{ | ||
"name": "angular-content-editable", | ||
"version": "1.1.1", | ||
"version": "1.1.2", | ||
"description": "modify in real time any html tag you want", | ||
"main": "Gruntfile.js", | ||
"main": "dist/angular-content-editable.js", | ||
"directories": { | ||
@@ -7,0 +7,0 @@ "example": "example" |
angular.module('angular-content-editable') | ||
.directive('contentEditable', function ($log,$sce,$compile,$window,contentEditable) { | ||
.directive('contentEditable', function ($log, $sce, $parse, $window, contentEditable) { | ||
var directive = { | ||
restrict: 'A', | ||
require: '?ngModel', | ||
scope: { editCallback: '=', ngModel: '=' }, | ||
link: _link | ||
} | ||
var directive = { | ||
restrict: 'A', | ||
require: '?ngModel', | ||
scope: { editCallback: '=' }, | ||
link: _link | ||
} | ||
return directive; | ||
return directive; | ||
function _link(scope, elem, attrs, ngModel) { | ||
function _link(scope, elem, attrs, ngModel) { | ||
// return if ng model not specified | ||
if(!ngModel) { | ||
$log.warn('Error: ngModel is required in elem: ', elem); | ||
return; | ||
} | ||
// return if ng model not specified | ||
if(!ngModel) { | ||
$log.warn('Error: ngModel is required in elem: ', elem); | ||
return; | ||
} | ||
var noEscape = true; | ||
var originalElement = elem[0]; | ||
// get default usage options | ||
var options = angular.copy(contentEditable); | ||
// update options with attributes | ||
angular.forEach(options, function (val, key) { | ||
if( key in attrs && typeof attrs[key] !== 'undefined' ) { options[key] = attrs[key]; } | ||
}) | ||
var noEscape = true; | ||
var originalElement = elem[0]; | ||
// if model is invalid or null | ||
// fill his value with elem html content | ||
if( !scope.ngModel ) { | ||
ngModel.$setViewValue( elem.html() ); | ||
} | ||
// get default usage options | ||
var options = angular.copy(contentEditable); | ||
// add editable class | ||
attrs.$addClass(options.editableClass); | ||
// update options with attributes | ||
angular.forEach(options, function (val, key) { | ||
if( key in attrs ) { | ||
options[key] = $parse(attrs[key])(scope); | ||
} | ||
}); | ||
// render always with model value | ||
ngModel.$render = function() { | ||
elem.html( ngModel.$modelValue || '' ); | ||
} | ||
// if model is invalid or null | ||
// fill his value with elem html content | ||
if( !scope.ngModel ) { | ||
ngModel.$setViewValue( elem.html() ); | ||
} | ||
// handle click on element | ||
function onClick(e){ | ||
e.preventDefault(); | ||
attrs.$set('contenteditable', 'true'); | ||
return originalElement.focus(); | ||
} | ||
// add editable class | ||
attrs.$addClass(options.editableClass); | ||
// check some option extra | ||
// conditions during focus | ||
function onFocus(e) { | ||
// turn on the flag | ||
noEscape = true; | ||
// select all on focus | ||
if( options.focusSelect ) { | ||
var range = $window.document.createRange(); | ||
range.selectNodeContents( originalElement ); | ||
$window.getSelection().addRange(range); | ||
} | ||
// if render-html is enabled convert | ||
// all text content to plaintext | ||
// in order to modify html tags | ||
if( options.renderHtml ) { | ||
originalElement.textContent = elem.html(); | ||
} | ||
} | ||
// render always with model value | ||
ngModel.$render = function() { | ||
elem.html( ngModel.$modelValue || '' ); | ||
} | ||
function onBlur(e) { | ||
// handle click on element | ||
function onClick(e){ | ||
e.preventDefault(); | ||
attrs.$set('contenteditable', 'true'); | ||
return originalElement.focus(); | ||
} | ||
// the text | ||
var html; | ||
// check some option extra | ||
// conditions during focus | ||
function onFocus(e) { | ||
// turn on the flag | ||
noEscape = true; | ||
// select all on focus | ||
if( options.focusSelect ) { | ||
var range = $window.document.createRange(); | ||
var selection = $window.getSelection(); | ||
range.selectNodeContents( originalElement ); | ||
selection.removeAllRanges(); | ||
selection.addRange(range); | ||
} | ||
// if render-html is enabled convert | ||
// all text content to plaintext | ||
// in order to modify html tags | ||
if( options.renderHtml ) { | ||
originalElement.textContent = elem.html(); | ||
} | ||
} | ||
// disable editability | ||
attrs.$set('contenteditable', 'false'); | ||
function onBlur(e) { | ||
// if text needs to be rendered as html | ||
if( options.renderHtml && noEscape ) { | ||
// get plain text html (with html tags) | ||
// replace all blank spaces | ||
html = originalElement.textContent.replace(/\u00a0/g, " "); | ||
// update elem html value | ||
elem.html(html); | ||
// the text | ||
var html; | ||
} else { | ||
// get element content replacing html tag | ||
html = elem.html().replace(/ /g, ' '); | ||
} | ||
// disable editability | ||
attrs.$set('contenteditable', 'false'); | ||
// if element value is | ||
// different from model value | ||
if( html != ngModel.$modelValue ) { | ||
// if text needs to be rendered as html | ||
if( options.renderHtml && noEscape ) { | ||
// get plain text html (with html tags) | ||
// replace all blank spaces | ||
html = originalElement.textContent.replace(/\u00a0/g, " "); | ||
// update elem html value | ||
elem.html(html); | ||
/** | ||
* This method should be called | ||
* when a controller wants to | ||
* change the view value | ||
*/ | ||
ngModel.$setViewValue(html) | ||
// if user passed a variable | ||
// and is a function | ||
if( scope.editCallback && angular.isFunction(scope.editCallback) ) { | ||
// apply the callback | ||
// with arguments: current text and element | ||
return scope.$apply( scope.editCallback(html, elem) ); | ||
} | ||
} else { | ||
// get element content replacing html tag | ||
html = elem.html().replace(/ /g, ' '); | ||
} | ||
} | ||
// if element value is | ||
// different from model value | ||
if( html != ngModel.$modelValue ) { | ||
/** | ||
* This method should be called | ||
* when a controller wants to | ||
* change the view value | ||
*/ | ||
ngModel.$setViewValue(html) | ||
// if user passed a variable | ||
// and is a function | ||
if( scope.editCallback && angular.isFunction(scope.editCallback) ) { | ||
// apply the callback | ||
// with arguments: current text and element | ||
return scope.$apply( scope.editCallback(html, elem) ); | ||
} | ||
function onKeyDown(e) { | ||
} | ||
// on tab key blur and | ||
// TODO: focus to next | ||
if( e.which == 9 ) { | ||
originalElement.blur(); | ||
return; | ||
} | ||
} | ||
// on esc key roll back value and blur | ||
if( e.which == 27 ) { | ||
ngModel.$rollbackViewValue(); | ||
noEscape = false; | ||
return originalElement.blur(); | ||
} | ||
function onKeyDown(e) { | ||
// if single line or ctrl key is | ||
// pressed trigger the blur event | ||
if( e.which == 13 && (options.singleLine || e.ctrlKey) ) { | ||
return originalElement.blur(); | ||
} | ||
// on tab key blur and | ||
// TODO: focus to next | ||
if( e.which == 9 ) { | ||
originalElement.blur(); | ||
return; | ||
} | ||
} | ||
// on esc key roll back value and blur | ||
if( e.which == 27 ) { | ||
ngModel.$rollbackViewValue(); | ||
noEscape = false; | ||
return originalElement.blur(); | ||
} | ||
/** | ||
* On click turn the element | ||
* to editable and focus it | ||
*/ | ||
elem.bind('click', onClick); | ||
// if single line or ctrl key is | ||
// pressed trigger the blur event | ||
if( e.which == 13 && (options.singleLine || e.ctrlKey) ) { | ||
return originalElement.blur(); | ||
} | ||
/** | ||
* On element focus | ||
*/ | ||
elem.bind('focus', onFocus); | ||
} | ||
/** | ||
* On element blur turn off | ||
* editable mode, if HTML, render | ||
* update model value and run callback | ||
* if specified | ||
*/ | ||
elem.bind('blur', onBlur); | ||
/** | ||
* On click turn the element | ||
* to editable and focus it | ||
*/ | ||
elem.on('click', onClick); | ||
/** | ||
* Bind the keydown event for many functions | ||
* TODO: more to come | ||
*/ | ||
elem.bind('keydown', onKeyDown); | ||
/** | ||
* On element focus | ||
*/ | ||
elem.on('focus', onFocus); | ||
/** | ||
* On element destroy, remove all event | ||
* listeners related to the directive | ||
* (helps to prevent memory leaks) | ||
*/ | ||
scope.$on('$destroy', function () { | ||
elem.unbind(onClick); | ||
elem.unbind(onFocus); | ||
elem.unbind(onBlur); | ||
}) | ||
/** | ||
* On element blur turn off | ||
* editable mode, if HTML, render | ||
* update model value and run callback | ||
* if specified | ||
*/ | ||
elem.on('blur', onBlur); | ||
} | ||
/** | ||
* Bind the keydown event for many functions | ||
*/ | ||
elem.on('keydown', onKeyDown); | ||
/** | ||
* On element destroy, remove all event | ||
* listeners related to the directive | ||
* (helps to prevent memory leaks) | ||
*/ | ||
scope.$on('$destroy', function () { | ||
elem.off('click', onClick); | ||
elem.off('focus', onFocus); | ||
elem.off('blur', onBlur); | ||
elem.off('keydown', onKeyDown); | ||
}); | ||
} | ||
}) |
angular.module('angular-content-editable', []); |
@@ -0,0 +0,0 @@ angular.module('angular-content-editable') |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
431
2.62%25391
-3.22%