Compare commits

..

No commits in common. 'master' and '0.3.6' have entirely different histories.

@ -7,9 +7,14 @@ module.exports = (grunt) ->
meta:
test: 'test'
karma:
e2e: configFile: 'karma.coffee'
unit: configFile: 'test/unit.karma.coffee'
e2e: configFile: 'test/e2e.karma.coffee'
unit_ci:
configFile: 'test/unit.karma.coffee'
singleRun: true
browsers: ['PhantomJS']
e2e_ci:
configFile: 'karma.coffee'
configFile: 'test/e2e.karma.coffee'
singleRun: true
browsers: ['PhantomJS']
jshint:

@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2013 Dmitri Akatov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

@ -1,6 +1,7 @@
# angular-contenteditable
[![Build Status](https://img.shields.io/travis/akatov/angular-contenteditable.svg)](https://travis-ci.org/akatov/angular-contenteditable)
[![Dependency Status](https://img.shields.io/gemnasium/akatov/angular-contenteditable.svg)](https://gemnasium.com/akatov/angular-contenteditable)
[![Build Status](https://travis-ci.org/akatov/angular-contenteditable.png)](https://travis-ci.org/akatov/angular-contenteditable)
[![Dependency Status](https://gemnasium.com/akatov/angular-contenteditable.png)](https://gemnasium.com/akatov/angular-contenteditable)
[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/akatov/angular-contenteditable/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
[![endorse](https://api.coderwall.com/akatov/endorsecount.png)](https://coderwall.com/akatov)
An AngularJS directive to bind html tags with the `contenteditable` attribute to models.
@ -32,13 +33,10 @@ angular.module('myapp', ['contenteditable'])
## Notice
The directive currently does not work in any version of Internet Explorer or Opera < 15.
Both browsers don't fire the `input` event for contenteditable fields.
In Chrome, when a contenteditable element X contains a non-contenteditable
element Y as the last element, then the behaviour of the caret is the following:
* When X has style `display` set to `block` or `inline-block`, then the caret
* When X has style `dislay` set to `block` or `inline-block`, then the caret
moves to the very far right edge of X when it is _immediately_ at the end of X
(inserting spaces moves the caret back).

@ -8,34 +8,22 @@ angular.module('contenteditable', [])
.directive('contenteditable', ['$timeout', function($timeout) { return {
restrict: 'A',
require: '?ngModel',
link: function(scope, element, attrs, ngModel) {
link: function($scope, $element, attrs, ngModel) {
// don't do anything unless this is actually bound to a model
if (!ngModel) {
return
}
// options
var opts = {}
angular.forEach([
'stripBr',
'noLineBreaks',
'selectNonEditable',
'moveCaretToEndOnChange',
], function(opt) {
var o = attrs[opt]
opts[opt] = o && o !== 'false'
})
// view -> model
element.bind('input', function(e) {
scope.$apply(function() {
$element.bind('input', function(e) {
$scope.$apply(function() {
var html, html2, rerender
html = element.text()
html = $element.html()
rerender = false
if (opts.stripBr) {
if (attrs.stripBr && attrs.stripBr !== "false") {
html = html.replace(/<br>$/, '')
}
if (opts.noLineBreaks) {
if (attrs.noLineBreaks && attrs.noLineBreaks !== "false") {
html2 = html.replace(/<div>/g, '').replace(/<br>/g, '').replace(/<\/div>/g, '')
if (html2 !== html) {
rerender = true
@ -50,8 +38,8 @@ angular.module('contenteditable', [])
// the cursor disappears if the contents is empty
// so we need to refocus
$timeout(function(){
element[0].blur()
element[0].focus()
$element[0].blur()
$element[0].focus()
})
}
})
@ -64,24 +52,22 @@ angular.module('contenteditable', [])
if (!!oldRender) {
oldRender()
}
element.html(ngModel.$viewValue || '')
if (opts.moveCaretToEndOnChange) {
el = element[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)
$element.html(ngModel.$viewValue || '')
el = $element[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)
}
if (opts.selectNonEditable) {
element.bind('click', function(e) {
if (attrs.selectNonEditable && attrs.selectNonEditable !== "false") {
$element.bind('click', function(e) {
var range, sel, target
target = e.toElement
if (target !== this && angular.element(target).attr('contenteditable') === 'false') {
@ -95,4 +81,4 @@ angular.module('contenteditable', [])
})
}
}
}}]);
}}])

@ -1,6 +1,6 @@
{
"name": "angular-contenteditable",
"version": "0.3.7",
"version": "0.3.6",
"main": "angular-contenteditable.js",
"ignore": [
".*",
@ -12,8 +12,10 @@
"src",
"test"
],
"dependencies": {
"angular-unstable": "~1.1.5"
},
"devDependencies": {
"angular": "*",
"angular-mocks": "~1.0.5",
"angular-scenario": "~1.0.5",
"expect": "~0.2.0",

@ -1,6 +1,6 @@
{
"name": "angular-contenteditable",
"version": "0.3.7",
"version": "0.3.6",
"description": "angular model for the 'contenteditable' html attribute",
"repository": {
"type": "git",
@ -11,8 +11,8 @@
"test": "test"
},
"scripts": {
"install": "bower install",
"test": "grunt test"
"install": "node_modules/.bin/bower install",
"test": "node_modules/.bin/grunt test"
},
"repository": "",
"keywords": [
@ -24,12 +24,13 @@
"devDependencies": {
"matchdep": "~0.3.0",
"grunt": "~0.4.1",
"grunt-cli": "~0.1.13",
"grunt-cli": "~0.1.9",
"grunt-contrib-jshint": "~0.7.1",
"grunt-karma": "~0.6.2",
"bower": "~1.3.5",
"bower": "~1.2.7",
"karma": "~0.10.2",
"karma-ng-scenario": "0.1.0",
"karma-mocha": "~0.1.0",
"karma-coffee-preprocessor": "0.1.0"
}
}

@ -10,6 +10,8 @@ module.exports = (karma) ->
served: true
karma.set
basePath: '..'
frameworks: ['ng-scenario']
preprocessors: '**/*.coffee': 'coffee'

@ -4,7 +4,7 @@
<title>Simple</title>
<!-- we need jquery for e2e testing -->
<script src="../../bower_components/jquery/jquery.js"></script>
<script src="../../bower_components/angular/angular.js"></script>
<script src="../../bower_components/angular-unstable/angular.js"></script>
<script src="../../angular-contenteditable.js"></script>
<script>
angular.module('simple', ['contenteditable'])

@ -4,7 +4,7 @@
<title>Simple</title>
<!-- we need jquery for e2e testing -->
<script src="../../bower_components/jquery/jquery.js"></script>
<script src="../../bower_components/angular/angular.js"></script>
<script src="../../bower_components/angular-unstable/angular.js"></script>
<script src="../../angular-contenteditable.js"></script>
<script>
angular.module('simple', ['contenteditable'])

@ -2,7 +2,7 @@
<html ng-app="simple">
<head>
<title>Simple</title>
<script src="../../bower_components/angular/angular.js"></script>
<script src="../../bower_components/angular-unstable/angular.js"></script>
<script src="../../angular-contenteditable.js"></script>
<script>
angular.module('simple', ['contenteditable'])

@ -4,7 +4,7 @@
<title>Simple</title>
<!-- we need jquery for e2e testing -->
<script src="../../bower_components/jquery/jquery.js"></script>
<script src="../../bower_components/angular/angular.js"></script>
<script src="../../bower_components/angular-unstable/angular.js"></script>
<script src="../../angular-contenteditable.js"></script>
<script>
angular.module('simple', ['contenteditable'])

@ -4,7 +4,7 @@
<meta charset="utf-8">
<link href="../../bower_components/bootstrap-css/css/bootstrap.css" rel="stylesheet">
<script src="../../bower_components/jquery/jquery.js"></script>
<script src="../../bower_components/angular/angular.js"></script>
<script src="../../bower_components/angular-unstable/angular.js"></script>
<script src="../../bower_components/angular-bootstrap/ui-bootstrap.js"></script>
<script src="../../bower_components/angular-bootstrap/ui-bootstrap-tpls.js"></script>
<script src="../../angular-contenteditable.js"></script>

@ -4,7 +4,7 @@
<meta charset="utf-8">
<link href="../../bower_components/bootstrap-css/css/bootstrap.css" rel="stylesheet">
<script src="../../bower_components/jquery/jquery.js"></script>
<script src="../../bower_components/angular/angular.js"></script>
<script src="../../bower_components/angular-unstable/angular.js"></script>
<script src="../../bower_components/angular-bootstrap/ui-bootstrap.js"></script>
<script src="../../bower_components/angular-bootstrap/ui-bootstrap-tpls.js"></script>
<script src="../../angular-contenteditable.js"></script>

@ -4,7 +4,7 @@
<meta charset="utf-8">
<link href="../../bower_components/bootstrap-css/css/bootstrap.css" rel="stylesheet">
<script src="../../bower_components/jquery/jquery.js"></script>
<script src="../../bower_components/angular/angular.js"></script>
<script src="../../bower_components/angular-unstable/angular.js"></script>
<script src="../../bower_components/angular-bootstrap/ui-bootstrap.js"></script>
<script src="../../bower_components/angular-bootstrap/ui-bootstrap-tpls.js"></script>
<script src="../../angular-contenteditable.js"></script>

@ -0,0 +1,33 @@
module.exports = (karma) ->
karma.set
basePath: '..'
frameworks: ['mocha']
files: [
'bower_components/angular/angular.js'
'angular-contenteditable.js'
'test/unit/*.coffee'
]
preprocessors: '**/*.coffee': 'coffee'
exclude: []
reporters: ['progress']
port: 9876
runnerPort: 9100
colors: true
logLevel: karma.LOG_INFO
autoWatch: true
browsers: ['Chrome']
captureTimeout: 60000
singleRun: false

@ -0,0 +1,3 @@
describe 'radians', ->
describe 'contenteditable', ->
it 'passes', ->