only use coffeescript for configuration and in tests

fix-space-nbsp 0.3.2
Dmitri Akatov 11 years ago
parent 4fa785b175
commit 2c8dea244c

3
.gitignore vendored

@ -1,4 +1,3 @@
node_modules node_modules
app/components bower_components
components
.idea .idea

@ -5,46 +5,22 @@ module.exports = (grunt) ->
grunt.initConfig grunt.initConfig
pkg: grunt.file.readJSON 'package.json' pkg: grunt.file.readJSON 'package.json'
meta: meta:
src: 'src'
test: 'test' test: 'test'
target: '<%= pkg.name %>.js'
banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' +
'<%= grunt.template.today("yyyy-mm-dd") %>\n' +
'<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
'* Copyright (c) <%= grunt.template.today("yyyy") %>' +
' <%= pkg.author.name %>;' +
' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n'
clean: target: src: ['<%= pkg.title %>.js']
coffeelint:
src:
files: src: ['<%= meta.src %>/**/*.coffee']
options: max_line_length: level: 'warn'
test:
files: src: ['<%= meta.src %>/**/*.coffee']
options: max_line_length: level: 'warn'
gruntfile:
files: src: ['Gruntfile.coffee']
coffee: src:
files:
'<%= meta.target %>': [
'<%= meta.src %>/**/*.coffee'
]
karma: karma:
unit: configFile: 'test/config-unit.coffee' unit: configFile: 'test/unit.karma.coffee'
e2e: configFile: 'test/config-e2e.coffee' e2e: configFile: 'test/e2e.karma.coffee'
unit_ci: unit_ci:
configFile: 'test/config-unit.coffee' configFile: 'test/unit.karma.coffee'
singleRun: true singleRun: true
browsers: ['PhantomJS'] browsers: ['PhantomJS']
e2e_ci: e2e_ci:
configFile: 'test/config-e2e.coffee' configFile: 'test/e2e.karma.coffee'
singleRun: true singleRun: true
browsers: ['PhantomJS'] browsers: ['PhantomJS']
jshint: target: ['<%= meta.target %>'] jshint: src: ['angular-contenteditable.js']
require('matchdep').filterDev('grunt-*').forEach grunt.loadNpmTasks require('matchdep').filterDev('grunt-*').forEach grunt.loadNpmTasks
grunt.registerTask 'test', ['karma:e2e_ci'] grunt.registerTask 'test', ['karma:e2e_ci']
grunt.registerTask 'lint', ['coffeelint'] grunt.registerTask 'lint', ['jshint']
grunt.registerTask 'build', ['clean', 'coffee'] grunt.registerTask 'default', ['lint' , 'test']
grunt.registerTask 'default', ['lint' , 'test', 'build', 'jshint']

@ -1,70 +1,72 @@
(function() { angular.module('contenteditable', [])
angular.module('contenteditable', []).directive('contenteditable', function() { .directive('contenteditable', function() { return {
return { require: 'ngModel',
require: 'ngModel', link: function($scope, $element, attrs, ngModel) {
link: function(scope, elmt, attrs, ngModel) { var old_render;
var old_render; // view -> model
elmt.bind('input', function(e) { $element.bind('input', function(e) {
return scope.$apply(function() { $scope.$apply(function() {
var html, html2, rerender; var html, html2, rerender;
html = elmt.html(); html = $element.html();
rerender = false; rerender = false;
if (attrs.stripBr && attrs.stripBr !== "false") { if (attrs.stripBr && attrs.stripBr !== "false") {
html = html.replace(/<br>$/, ''); html = html.replace(/<br>$/, '');
} }
if (attrs.noLineBreaks && attrs.noLineBreaks !== "false") { if (attrs.noLineBreaks && attrs.noLineBreaks !== "false") {
html2 = html.replace(/<div>/g, '').replace(/<br>/g, '').replace(/<\/div>/g, ''); html2 = html.replace(/<div>/g, '').replace(/<br>/g, '').replace(/<\/div>/g, '');
if (html2 !== html) { if (html2 !== html) {
rerender = true; rerender = true;
html = html2; html = html2;
} }
} }
ngModel.$setViewValue(html); ngModel.$setViewValue(html);
if (rerender) { if (rerender) {
ngModel.$render(); ngModel.$render();
} }
if (html === '') { if (html === '') {
elmt.blur(); // the cursor disappears if the contents is empty
return elmt.focus(); // so we need to refocus
} $element.blur();
}); $element.focus();
}); }
old_render = ngModel.$render; });
ngModel.$render = function() { });
var el, el2, range, sel;
if (old_render != null) { // model -> view
old_render(); old_render = ngModel.$render;
} ngModel.$render = function() {
elmt.html(ngModel.$viewValue || ''); var el, el2, range, sel;
el = elmt.get(0); if (!!old_render) {
range = document.createRange(); old_render();
sel = window.getSelection(); }
if (el.childNodes.length > 0) { $element.html(ngModel.$viewValue || '');
el2 = el.childNodes[el.childNodes.length - 1]; el = $element.get(0);
range.setStartAfter(el2); range = document.createRange();
} else { sel = window.getSelection();
range.setStartAfter(el); if (el.childNodes.length > 0) {
} el2 = el.childNodes[el.childNodes.length - 1];
range.collapse(true); range.setStartAfter(el2);
sel.removeAllRanges(); } else {
return sel.addRange(range); range.setStartAfter(el);
}; }
if (attrs.selectNonEditable && attrs.selectNonEditable !== "false") { range.collapse(true);
return elmt.click(function(e) { sel.removeAllRanges();
var range, sel, target; sel.addRange(range);
target = e.toElement; };
if (target !== this && angular.element(target).attr('contenteditable') === 'false') { if (attrs.selectNonEditable && attrs.selectNonEditable !== "false") {
range = document.createRange(); $element.click(function(e) {
sel = window.getSelection(); var range, sel, target;
range.setStartBefore(target); target = e.toElement;
range.setEndAfter(target); if (target !== this && angular.element(target).attr('contenteditable') === 'false') {
sel.removeAllRanges(); range = document.createRange();
return sel.addRange(range); sel = window.getSelection();
range.setStartBefore(target);
range.setEndAfter(target);
sel.removeAllRanges();
sel.addRange(range);
}
});
} }
});
} }
} };});
};
});
}).call(this);

@ -1,6 +1,6 @@
{ {
"name": "angular-contenteditable", "name": "angular-contenteditable",
"version": "0.3.1", "version": "0.3.2",
"main": "angular-contenteditable.js", "main": "angular-contenteditable.js",
"ignore": [ "ignore": [
".*", ".*",

@ -1,6 +1,6 @@
{ {
"name": "angular-contenteditable", "name": "angular-contenteditable",
"version": "0.3.1", "version": "0.3.2",
"description": "angular extensions", "description": "angular extensions",
"main": "angular-contenteditable.js", "main": "angular-contenteditable.js",
"directories": { "directories": {
@ -19,20 +19,11 @@
"devDependencies": { "devDependencies": {
"matchdep": "~0.1.2", "matchdep": "~0.1.2",
"grunt": "~0.4.1", "grunt": "~0.4.1",
"grunt-contrib-concat": "~0.3.0",
"grunt-mocha-cli": "~1.0.6",
"should": "~1.2.2",
"grunt-coffee-redux": "~0.2.3",
"grunt-contrib-coffee": "~0.7.0",
"grunt-contrib-clean": "~0.5.0",
"grunt-contrib-watch": "~0.4.4",
"grunt-contrib-jshint": "~0.6.0", "grunt-contrib-jshint": "~0.6.0",
"grunt-coffeelint": "0.0.7",
"coffee-script": "~1.6.3",
"karma": "~0.9.4",
"grunt-karma": "~0.5.0", "grunt-karma": "~0.5.0",
"karma": "~0.9.4",
"karma-ng-scenario": "0.0.2", "karma-ng-scenario": "0.0.2",
"karma-coffee-preprocessor": "0.0.2", "karma-mocha": "~0.0.3",
"karma-mocha": "0.0.3" "karma-coffee-preprocessor": "0.0.2"
} }
} }

@ -1,52 +0,0 @@
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 /<br>$/, ''
if attrs.noLineBreaks && attrs.noLineBreaks != "false"
html2 = html.replace(/<div>/g, '').replace(/<br>/g, '').replace(/<\/div>/g, '')
if html2 != html
rerender = true
html = html2
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)
)

@ -1,52 +0,0 @@
module.exports = (config) ->
toServe = for file in [
'components/bootstrap-css/css/bootstrap.css'
'components/jquery/jquery.js'
'components/angular-unstable/angular.js'
'components/angular-bootstrap/ui-bootstrap.js'
'components/angular-bootstrap/ui-bootstrap-tpls.js'
'angular-contenteditable.js'
'test/fixtures/simple.html'
'test/fixtures/typeahead1.html'
'test/fixtures/typeahead2.html'
'test/fixtures/typeahead3.html'
'test/fixtures/states.json'
'test/fixtures/img/ru.gif'
'test/fixtures/img/gb.gif'
'test/fixtures/img/us.gif'
]
pattern: file
watched: false
included: false
served: true
config.set
basePath: '..'
frameworks: ['ng-scenario']
preprocessors: '**/*.coffee': 'coffee'
files: [
'test/e2e/**/*.coffee'
].concat toServe
exclude: []
reporters: ['progress']
port: 9876
runnerPort: 9100
colors: true
logLevel: config.LOG_INFO
autoWatch: true
browsers: ['Chrome']
captureTimeout: 60000
singleRun: false

@ -0,0 +1,42 @@
module.exports = (karma) ->
toServe = for file in [
'bower_components/**/*.css'
'bower_components/*/*.js'
'test/fixtures/**/*'
]
pattern: file
watched: false
included: false
served: true
karma.set
basePath: '..'
frameworks: ['ng-scenario']
preprocessors: '**/*.coffee': 'coffee'
files: [
'test/e2e/**/*.coffee'
'angular-contenteditable.js'
].concat toServe
exclude: []
reporters: ['progress']
port: 9876
runnerPort: 9100
colors: true
logLevel: karma.LOG_INFO
autoWatch: true
browsers: ['Chrome']
captureTimeout: 60000
singleRun: false

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

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

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

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

@ -2,11 +2,11 @@
<html lang="en" ng-app="typeahead1"> <html lang="en" ng-app="typeahead1">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<link href="../../components/bootstrap-css/css/bootstrap.css" rel="stylesheet"> <link href="../../bower_components/bootstrap-css/css/bootstrap.css" rel="stylesheet">
<script src="../../components/jquery/jquery.js"></script> <script src="../../bower_components/jquery/jquery.js"></script>
<script src="../../components/angular-unstable/angular.js"></script> <script src="../../bower_components/angular-unstable/angular.js"></script>
<script src="../../components/angular-bootstrap/ui-bootstrap.js"></script> <script src="../../bower_components/angular-bootstrap/ui-bootstrap.js"></script>
<script src="../../components/angular-bootstrap/ui-bootstrap-tpls.js"></script> <script src="../../bower_components/angular-bootstrap/ui-bootstrap-tpls.js"></script>
<script src="../../angular-contenteditable.js"></script> <script src="../../angular-contenteditable.js"></script>
<script> <script>
angular.module('typeahead1', ['ui.bootstrap', 'contenteditable']) angular.module('typeahead1', ['ui.bootstrap', 'contenteditable'])

@ -2,11 +2,11 @@
<html lang="en" ng-app="typeahead2"> <html lang="en" ng-app="typeahead2">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<link href="../../components/bootstrap-css/css/bootstrap.css" rel="stylesheet"> <link href="../../bower_components/bootstrap-css/css/bootstrap.css" rel="stylesheet">
<script src="../../components/jquery/jquery.js"></script> <script src="../../bower_components/jquery/jquery.js"></script>
<script src="../../components/angular-unstable/angular.js"></script> <script src="../../bower_components/angular-unstable/angular.js"></script>
<script src="../../components/angular-bootstrap/ui-bootstrap.js"></script> <script src="../../bower_components/angular-bootstrap/ui-bootstrap.js"></script>
<script src="../../components/angular-bootstrap/ui-bootstrap-tpls.js"></script> <script src="../../bower_components/angular-bootstrap/ui-bootstrap-tpls.js"></script>
<script src="../../angular-contenteditable.js"></script> <script src="../../angular-contenteditable.js"></script>
<script> <script>
angular.module('typeahead2', ['ui.bootstrap', 'contenteditable']) angular.module('typeahead2', ['ui.bootstrap', 'contenteditable'])

@ -2,11 +2,11 @@
<html lang="en" ng-app="typeahead3"> <html lang="en" ng-app="typeahead3">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<link href="../../components/bootstrap-css/css/bootstrap.css" rel="stylesheet"> <link href="../../bower_components/bootstrap-css/css/bootstrap.css" rel="stylesheet">
<script src="../../components/jquery/jquery.js"></script> <script src="../../bower_components/jquery/jquery.js"></script>
<script src="../../components/angular-unstable/angular.js"></script> <script src="../../bower_components/angular-unstable/angular.js"></script>
<script src="../../components/angular-bootstrap/ui-bootstrap.js"></script> <script src="../../bower_components/angular-bootstrap/ui-bootstrap.js"></script>
<script src="../../components/angular-bootstrap/ui-bootstrap-tpls.js"></script> <script src="../../bower_components/angular-bootstrap/ui-bootstrap-tpls.js"></script>
<script src="../../angular-contenteditable.js"></script> <script src="../../angular-contenteditable.js"></script>
<script> <script>
angular.module('typeahead3', ['ui.bootstrap', 'contenteditable']) angular.module('typeahead3', ['ui.bootstrap', 'contenteditable'])

@ -1,15 +1,15 @@
module.exports = (config) -> module.exports = (karma) ->
config.set karma.set
basePath: '..' basePath: '..'
frameworks: ['mocha'] frameworks: ['mocha']
files: [ files: [
'components/expect/expect.js' 'bower_components/angular/angular.js'
'components/angular/angular.js' 'angular-contenteditable.js'
'src/**/*.coffee'
'test/unit/*.coffee' 'test/unit/*.coffee'
] ]
preprocessors: '**/*.coffee': 'coffee' preprocessors: '**/*.coffee': 'coffee'
exclude: [] exclude: []
@ -22,7 +22,7 @@ module.exports = (config) ->
colors: true colors: true
logLevel: LOG_INFO logLevel: karma.LOG_INFO
autoWatch: true autoWatch: true