angular.module('contenteditable', []) .directive('contenteditable', -> require: 'ngModel', link: (scope, elmt, attrs, ngModel) -> # view -> model elmt.bind 'input', (e) -> scope.$apply -> html = elmt.html() rerender = false if attrs.stripBr && attrs.stripBr != "false" html = html.replace /
$/, '' if attrs.noLineBreaks && attrs.noLineBreaks != "false" html = html.replace(/
/g, '').replace(/
/g, '').replace(/<\/div>/g, '') rerender = true ngModel.$setViewValue(html) ngModel.$render() if rerender if html == '' # the cursor if the contents is emty, so need to refocus elmt.blur() elmt.focus() # model -> view old_render = ngModel.$render # save for later ngModel.$render = -> old_render() if old_render? elmt.html(ngModel.$viewValue || '') # move cursor to the end el = elmt.get(0) range = document.createRange() sel = window.getSelection() if el.childNodes.length > 0 el2 = el.childNodes[el.childNodes.length - 1] range.setStartAfter(el2) else range.setStartAfter(el) range.collapse(true) sel.removeAllRanges() sel.addRange(range) # select whole sub-span if it has contenteditable="false" if attrs.selectNonEditable && attrs.selectNonEditable != "false" elmt.click (e) -> target = e.toElement if target != @ && angular.element(target).attr('contenteditable') == 'false' range = document.createRange() sel = window.getSelection() range.setStartBefore(target) range.setEndAfter(target) sel.removeAllRanges() sel.addRange(range) )