diff --git a/.yo-rc.json b/.yo-rc.json
index 285589f..95f3c17 100644
--- a/.yo-rc.json
+++ b/.yo-rc.json
@@ -2,10 +2,9 @@
"generator-backbone": {
"appPath": "app",
"appName": "Dative",
- "coffee": true,
"testFramework": "mocha",
"templateFramework": "lodash",
"compassBootstrap": true
},
"generator-mocha": {}
-}
\ No newline at end of file
+}
diff --git a/Gruntfile.coffee b/Gruntfile.coffee
deleted file mode 100644
index 55fd3f6..0000000
--- a/Gruntfile.coffee
+++ /dev/null
@@ -1,668 +0,0 @@
-'use strict'
-LIVERELOAD_PORT = 35729
-SERVER_PORT = 9000
-lrSnippet = require('connect-livereload')({port: LIVERELOAD_PORT})
-mountFolder = (connect, dir) ->
- connect.static(require('path').resolve(dir))
-
-# # Globbing
-# for performance reasons we're only matching one level down:
-# 'test/spec/{,*/}*.js'
-# use this if you want to match all subfolders:
-# 'test/spec/**/*.js'
-# templateFramework: 'lodash'
-
-module.exports = (grunt) ->
-
- # show elapsed time at the end
- require('time-grunt') grunt
-
- # load all grunt tasks
- require('load-grunt-tasks') grunt
-
- # configurable paths
- yeomanConfig = app: 'app', dist: 'dist'
-
- grunt.initConfig
-
- markdown:
- all:
- files: [
- expand: true,
- flatten: true,
- src: '<%= yeoman.app %>/help/src/*.md'
- dest: '<%= yeoman.app %>/help/html/'
- ext: '.html'
- ]
- options:
- template: '<%= yeoman.app %>/help/src/template.jst'
-
- yeoman: yeomanConfig
-
- watch:
- options:
- nospawn: true
- livereload: true
- help:
- files: ['<%= yeoman.app %>/help/src/*.md']
- tasks: ['markdown:all']
- coffee:
- files: ['<%= yeoman.app %>/scripts/{,*/}*.coffee']
- tasks: ['copy:coffee', 'coffee:serve']
- coffeeTest:
- #files: ['test/spec/{,*/}*.coffee']
- files: ['test/**/*.coffee']
- tasks: ['coffee:test']
- compass:
- files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}']
- tasks: ['compass']
- livereload:
- options:
- livereload: grunt.option('livereloadport') || LIVERELOAD_PORT
- files: [
- '<%= yeoman.app %>/*.html'
- '{.tmp,<%= yeoman.app %>}/styles/{,*/}*.css'
- '{.tmp,<%= yeoman.app %>}/scripts/{,*/}*.js'
- '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp}'
- '<%= yeoman.app %>/scripts/templates/*.{ejs,mustache,hbs}'
- 'test/spec/**/*.js'
- ]
- jst:
- files: ['<%= yeoman.app %>/scripts/templates/*.ejs']
- tasks: ['jst']
- eco:
- files: ['<%= yeoman.app %>/scripts/templates/{,*/}*.eco']
- tasks: ['eco']
- test:
- files: ['<%= yeoman.app %>/scripts/{,*/}*.js', 'test/spec/**/*.js']
- tasks: ['test:true']
-
- docco:
- src: ['.doctmp/*.coffee']
- #src: ['<%= yeoman.app %>/scripts/**/*.coffee']
- options:
- output: 'docs/'
-
- connect:
- options:
- port: grunt.option('port') || SERVER_PORT
- # change this to '0.0.0.0' to access the server from outside
- #hostname: 'localhost'
- hostname: '0.0.0.0'
- livereload:
- options:
- middleware: (connect) ->
- [
- lrSnippet,
- mountFolder(connect, '.tmp')
- mountFolder(connect, yeomanConfig.app)
- ]
- test:
- options:
- port: 9001
- middleware: (connect) ->
- [
- lrSnippet
- mountFolder(connect, '.tmp')
- mountFolder(connect, 'test')
- mountFolder(connect, yeomanConfig.app)
- ]
- dist:
- options:
- middleware: (connect) ->
- [mountFolder(connect, yeomanConfig.dist)]
-
- open:
- server:
- path: 'http://localhost:<%= connect.options.port %>'
- test:
- path: 'http://localhost:<%= connect.test.options.port %>'
- #app: 'firefox'
-
- clean:
- dist: ['.tmp', '<%= yeoman.dist %>/*']
- postdist: ['<%= yeoman.dist %>/bower_components']
- server: '.tmp'
- doctmp: '.doctmp'
- docs: 'docs'
-
- jshint:
- options:
- jshintrc: '.jshintrc'
- reporter: require('jshint-stylish')
- all: [
- 'Gruntfile.js'
- '<%= yeoman.app %>/scripts/{,*/}*.js'
- '!<%= yeoman.app %>/scripts/vendor/*'
- '!<%= yeoman.app %>/scripts/jquery-extensions/*'
- 'test/spec/{,*/}*.js'
- ]
-
- mocha:
- all:
- options:
- log: true
- run: false # default: true
- reporter: 'Spec'
- testtimeout: 90000
- urls: ['http://localhost:<%= connect.test.options.port %>/index.html']
-
- coffee:
- serve:
- options:
- sourceMap: true
- files: [
- # rather than compiling multiple files here you should
- # require them into your main .coffee file
- expand: true
- cwd: '.tmp/scripts'
- src: '**/*.coffee'
- dest: '.tmp/scripts'
- ext: '.js'
- ]
- dist:
- options:
- sourceMap: false
- files: [
- # rather than compiling multiple files here you should
- # require them into your main .coffee file
- expand: true
- cwd: '.tmp/scripts'
- src: '**/*.coffee'
- dest: '.tmp/scripts'
- ext: '.js'
- ]
- test:
- files: [
- expand: true
- #cwd: 'test/spec' # original
- cwd: 'test'
- #src: '{,*/}*.coffee' # original
- src: '**/*.coffee'
- dest: '.tmp/spec' # original
- #dest: '.tmp'
- ext: '.js'
- ]
-
- # see http://brianflove.com/2014/04/18/web-development-automation-gruntfile-using-coffeescript/
- # see https://www.npmjs.org/package/grunt-coffeelint
- # see http://www.coffeelint.org/
- coffeelint:
- app:
- src: '<%= yeoman.app %>/scripts/**/*.coffee'
- options:
- no_tabs:
- level: 'error'
- indentation:
- level: 'ignore' # Unfortunately, coffeelint and requirejs's define callbacks don't play well together
- no_trailing_whitespace:
- level: 'error'
- no_trailing_semicolons:
- level: 'error'
- no_plusplus:
- level: 'warn'
- no_implicit_parens:
- level: 'ignore' # change to 'warn' to warn about this
- max_line_length:
- level: 'ignore'
-
- compass:
- options:
- sassDir: '<%= yeoman.app %>/styles',
- cssDir: '.tmp/styles',
- imagesDir: '<%= yeoman.app %>/images',
- javascriptsDir: '<%= yeoman.app %>/scripts',
- fontsDir: '<%= yeoman.app %>/styles/fonts',
- importPath: '<%= yeoman.app %>/bower_components',
- relativeAssets: true
- dist: {},
- server:
- options:
- debugInfo: true
-
- requirejs:
- dist:
- # Options: https://github.com/jrburke/r.js/blob/master/build/example.build.js
- options:
- baseUrl: '.tmp/scripts'
- optimize: 'none'
- preserveLicenseComments: false
- useStrict: true
- name: 'main'
- out: '<%= yeoman.dist %>/scripts/main.js'
- generateSourceMaps: false
- #mainConfigFile: '.tmp/scripts/main.js'
- # TODO: Figure out how to make sourcemaps work with grunt-usemin
- # https://github.com/yeoman/grunt-usemin/issues/30
- #generateSourceMaps: true
- # required to support SourceMaps
- # http://requirejs.org/docs/errors.html#sourcemapcomments
- shim_:
- jquery:
- exports: '$'
- lodash:
- exports: '_'
- backbone:
- exports: 'Backbone'
- deps: ['lodash', 'jquery']
- jqueryui: ['jquery']
- backboneindexeddb: ['backbone']
- multiselect: ['jquery', 'jqueryui']
- jqueryelastic: ['jquery']
- perfectscrollbar: ['jquery']
- superfish: ['jquery']
- superclick: ['jquery']
- supersubs: ['jquery']
- backbonerelational: ['backbone']
- backbonelocalstorage: ['backbone']
-
- paths_:
- jquery: '../../<%= yeoman.app %>/bower_components/jquery/dist/jquery'
- backbone: '../../<%= yeoman.app %>/bower_components/backbone/backbone'
- lodash: '../../<%= yeoman.app %>/bower_components/lodash/dist/lodash'
- underscore: '../../<%= yeoman.app %>/bower_components/lodash/dist/lodash.underscore'
- backboneindexeddb:
- '../../<%= yeoman.app %>/bower_components/indexeddb-backbonejs-adapter/backbone-indexeddb'
- bootstrap: '../../<%= yeoman.app %>/bower_components/sass-bootstrap/dist/js/bootstrap'
- text: '../../<%= yeoman.app %>/bower_components/requirejs-text/text'
- jqueryui: '../../<%= yeoman.app %>/bower_components/jqueryui/jquery-ui'
- superfish: '../../<%= yeoman.app%>/bower_components/superfish/dist/js/superfish'
- superclick: '../../<%= yeoman.app%>/bower_components/superclick/dist/js/superclick'
- #superfish: '../../<%= yeoman.app%>/scripts/jquery-extensions/superfish/dist/js/superfish'
- #superfish: '../../<%= yeoman.app %>/bower_components/superfish/dist/js/superfish'
- igt: '../../<%= yeoman.app%>/scripts/jquery-extensions/igt'
- jqueryuicolors: '../../<%= yeoman.app%>/scripts/jquery-extensions/jqueryui-colors'
- sfjquimatch: '../../<%= yeoman.app%>/scripts/jquery-extensions/superfish-jqueryui-match'
- supersubs: '../../<%= yeoman.app%>/bower_components/superfish/dist/js/supersubs'
- #supersubs: '../../<%= yeoman.app%>/scripts/jquery-extensions/superfish/dist/js/supersubs'
- #supersubs: '../../<%= yeoman.app %>/bower_components/superfish/dist/js/supersubs'
- multiselect: '../../<%= yeoman.app %>/bower_components/multiselect/js/jquery.multi-select'
- jqueryelastic: '../../<%= yeoman.app %>/bower_components/jakobmattsson-jquery-elastic/jquery.elastic.source'
- spin: '../../<%= yeoman.app %>/bower_components/spin.js/spin'
- jqueryspin: '../../<%= yeoman.app %>/bower_components/spin.js/jquery.spin'
- perfectscrollbar: '../../<%= yeoman.app %>/bower_components/perfect-scrollbar/src/perfect-scrollbar'
- backbonerelational: '../../<%= yeoman.app %>/bower_components/backbone-relational/backbone-relational'
- backbonelocalstorage: '../../<%= yeoman.app %>/bower_components/backbone.localStorage/backbone.localStorage'
-
- useminPrepare:
- html: '<%= yeoman.app %>/index.html'
- options:
- dest: '<%= yeoman.dist %>'
- # Next 5 lines from http://stackoverflow.com/questions/20509145/managing-images-in-bower-packages-using-grunt?lq=1
- # "Next, the flow configuration tells usemin to skip the concat step for
- # css files. This is because cssmin does a concatenation itself, and
- # cssmin needs to know the origin of the css files in order to do the
- # relative-path correction for referenced resources."
- flow_:
- steps:
- js: ['concat', 'uglify']
- css: ['cssmin']
- post: {}
-
- usemin:
- html: ['<%= yeoman.dist %>/{,*/}*.html']
- css: ['<%= yeoman.dist %>/styles/{,*/}*.css']
- options:
- dirs: ['<%= yeoman.dist %>']
-
- imagemin:
- dist:
- files: [
- expand: true
- cwd: '<%= yeoman.app %>/images'
- src: '{,*/}*.{png,jpg,jpeg}'
- dest: '<%= yeoman.dist %>/images'
- ]
-
- # A config for cssmin is unnecessary since that created by useminPrepare works
- # fine. Hence the name change to `cssmin_' here.
- cssmin_:
- dist:
- files:
- '<%= yeoman.dist %>/styles/main.css': [
- '.tmp/styles/{,*/}*.css'
- '<%= yeoman.app %>/styles/{,*/}*.css'
- '<%= yeoman.app %>/bower_components/jqueryui/themes/eggplant/jquery-ui.css'
- ]
- options:
- root: '<% yeoman.app %>' # This is where `bower_components/` is to be found
-
- htmlmin:
- dist:
- options: {}
- ###
- removeCommentsFromCDATA: true,
- # https://github.com/yeoman/grunt-usemin/issues/44
- #collapseWhitespace: true,
- collapseBooleanAttributes: true,
- removeAttributeQuotes: true,
- removeRedundantAttributes: true,
- useShortDoctype: true,
- removeEmptyAttributes: true,
- removeOptionalTags: true
- ###
- files: [
- expand: true,
- cwd: '<%= yeoman.app %>',
- src: '*.html',
- dest: '<%= yeoman.dist %>'
- ]
-
- copy:
- coffee:
- files: [
- expand: true
- dot: true
- cwd: '<%= yeoman.app %>/scripts'
- dest: '.tmp/scripts'
- src: '**/*.coffee'
- ]
- packagejson:
- src: 'package.json'
- dest: '.tmp/'
- unicodedatajson:
- src: 'UnicodeData.json'
- dest: '.tmp/'
- serversjson:
- src: 'servers.json'
- dest: '.tmp/'
- unicodedatajsondist:
- src: 'UnicodeData.json'
- dest: 'dist/'
- serversjsondist:
- src: 'servers.json'
- dest: 'dist/'
- dist:
- files: [
- expand: true
- dot: true
- cwd: '<%= yeoman.app %>'
- dest: '<%= yeoman.dist %>'
- src_: [
- 'UnicodeData.json'
- 'bower_components/jqueryui/**/*.*' # added, cf. http://stackoverflow.com/questions/20509145/managing-images-in-bower-packages-using-grunt?lq=1
- ]
- src: [
- '*.{ico,txt}'
- '.htaccess'
- 'favicon.png'
- 'help/html/help.html'
- './../package.json'
- './../.tmp/UnicodeData.json'
- './../.tmp/servers.json'
- 'images/{,*/}*.{webp,gif,png,jpg}' # added png so that my jQuery images in /images would copy over, cf. imagemin headache
- 'styles/fonts/{,*/}*.*'
- 'bower_components/sass-bootstrap/fonts/*.*'
- 'bower_components/jqueryui/**/*.*' # added, cf. http://stackoverflow.com/questions/20509145/managing-images-in-bower-packages-using-grunt?lq=1
- ]
- ]
- disttmp:
- files: [
- expand: true
- dot: true
- cwd: '<%= yeoman.app %>'
- dest: '.tmp'
- src: [
- 'bower_components/{,**/}*.*'
- 'scripts/jquery-extensions/{,**/}*.*'
- ]
- ]
- # Copy jQueryUI images to dist/styles/images/
- distJQueryUIImages:
- files: [
- expand: true
- dot: true
- cwd: '<%= yeoman.app %>'
- dest: '<%= yeoman.dist %>/styles/images'
- flatten: true # CRUCIAL!!!
- src: [
- 'bower_components/jqueryui/**/*.{png,jpg,jpeg,gif,webp,svg,eot,ttf,woff}' # added, cf. http://stackoverflow.com/questions/20509145/managing-images-in-bower-packages-using-grunt?lq=1
- ]
- ]
- distrequirejs: # from https://github.com/yeoman/grunt-usemin/issues/192
- expand: true,
- cwd: '<%= yeoman.app %>/bower_components/requirejs/',
- dest: '<%= yeoman.dist %>/scripts/vendor/',
- src: ['require.js']
- docco:
- files: [
- expand: true
- cwd: '<%= yeoman.app %>/scripts/' # src/modules/'
- src: ['**/*.coffee']
- dest: '.doctmp/' # dev/js/'
- rename: (dest, src) ->
- return dest + src.replace(/\//g, '.')
- ,
- expand: true
- cwd: 'test/'
- src: ['!bower_components/*.coffee', '**/*.coffee']
- dest: '.doctmp/'
- rename: (dest, src) ->
- return dest + 'test.' + src.replace(/\//g, '.')
- ]
- requirejs:
- src: '<%= yeoman.app %>/bower_components/requirejs/require.js'
- dest: '<%= yeoman.dist %>/bower_components/requirejs/require.js'
-
- uglify: # altered for debugging purposes.
- dist_:
- files:
- '<%= yeoman.dist %>/scripts/main.js': ['<%= yeoman.dist %>/scripts/main.js']
- requirejs:
- files:
- '<%= yeoman.dist %>/scripts/vendor/require.js': ['<%= yeoman.dist %>/scripts/vendor/require.js']
-
- bower:
- all:
- rjsConfig: '<%= yeoman.app %>/scripts/main.js'
-
- jst:
- options:
- amd: true
- compile:
- files:
- '.tmp/scripts/templates.js': ['<%= yeoman.app %>/scripts/templates/*.ejs']
-
- eco:
- options:
- amd: true
- files:
- expand: true
- cwd: '<%= yeoman.app %>/scripts/templates'
- src: ['*.eco', 'fields/*.eco']
- dest: '.tmp/scripts/templates'
- ext: '.js'
-
- exec:
- setContinuousDeploymentVersion:
- cmd: ->
- return 'bash scripts/set_ci_version.sh'
-
- rev:
- dist:
- files:
- src: [
- '<%= yeoman.dist %>/scripts/{,*/!(require)}*.js' # Add exception not to change name of copied file during "rev" task (added only !(require) exception), cf. https://github.com/yeoman/grunt-usemin/issues/192
- '<%= yeoman.dist %>/styles/{,*/}*.css',
- '<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp}',
- '/styles/fonts/{,*/}*.*',
- 'bower_components/sass-bootstrap/fonts/*.*'
- 'bower_components/**/*.{png,jpg,jpeg,gif,webp,svg,eot,ttf,woff}' # added, cf. http://stackoverflow.com/questions/20509145/managing-images-in-bower-packages-using-grunt?lq=1
- ]
-
- # Replace script tag in index.html, to call require.js from new path using grunt-regex-replace plugin:
- # See https://github.com/yeoman/grunt-usemin/issues/192
- 'regex-replace':
- dist:
- src: ['<%= yeoman.dist %>/index.html'],
- actions: [
- name: 'requirejs-newpath',
- search: '',
- replace: (match) ->
- regex = /scripts\/.*main/
- result = regex.exec(match)
- ''
- flags: 'g'
- ]
-
- grunt.registerTask 'createDefaultTemplate', ->
- grunt.file.write '.tmp/scripts/templates.js', 'this.JST = this.JST || {}'
-
- grunt.registerTask 'server', (target) ->
- grunt.log.warn 'The `server` task has been deprecated. Use `grunt serve` to start a server.'
- grunt.task.run ['serve' + (target ? ':' + target : '')]
-
- grunt.registerTask 'serve', (target) ->
- if target is 'dist'
- return grunt.task.run ['build', 'open:server', 'connect:dist:keepalive']
-
- if target is 'test'
- return grunt.task.run [
- 'markdown:all'
- 'clean:server'
- 'copy:coffee'
- 'copy:packagejson'
- 'copy:unicodedatajson'
- 'copy:serversjson'
- 'coffee:serve'
- 'coffee:test'
- #'createDefaultTemplate'
- #'jst'
- 'eco'
- #'compass:server'
- 'connect:test'
- 'open:test'
- 'watch'
- ]
-
- grunt.task.run [
- 'markdown:all'
- 'clean:server'
- 'copy:coffee'
- 'copy:packagejson'
- 'copy:unicodedatajson'
- 'copy:serversjson'
- 'coffee:serve'
- #'createDefaultTemplate'
- #'jst'
- 'eco'
- #'compass:server'
- 'connect:livereload'
- #'open:server'
- 'watch'
- ]
-
- grunt.registerTask 'coffeeDist', ['copy:coffee', 'coffee:dist']
-
- grunt.registerTask 'test', (isConnected) ->
- isConnected = Boolean(isConnected)
- testTasks = [
- 'clean:server'
- 'coffee'
- #'createDefaultTemplate'
- #'jst'
- 'eco'
- #'compass'
- 'connect:test'
- 'mocha'
- ]
- if not isConnected
- grunt.task.run testTasks
- else
- # already connected so not going to connect again, remove the connect:test task
- testTasks.splice testTasks.indexOf('connect:test'), 1
- grunt.task.run testTasks
-
- grunt.registerTask 'build', [
- 'markdown:all'
- 'clean:dist' # remove everything in dist/ and .tmp/
- 'copy:coffee' # copy all .coffee files in app/scripts/ to .tmp/scripts/
- 'copy:packagejson'
- 'copy:unicodedatajson'
- 'copy:serversjson'
- 'coffee:dist' # convert all .coffee files in .tmp/scripts to .js in situ
-
- # eco: convert all .eco files in app/scripts/templates/ to .js files in
- # .tmp/scripts/templates/
- 'eco'
-
- # permits execution of shell scripts
- 'exec:setContinuousDeploymentVersion'
-
- #'compass:dist' # commented out because not currently using compass
-
- # useminPrepare: read the `build` comments in index.html and dynamically
- # generate concat, uglify, and or cssmin `generated` tasks.
- 'useminPrepare'
-
- # copy:disttmp: my copy task: copies bower_components and jquery-extensions
- # to .tmp. This seems to be necessary: SHOW FAILM MSG: ... Error: ENOENT,
- # no such file or directory '.tmp/bower_components/lodash/dist/lodash.js'
- 'copy:disttmp'
-
- # copy:distJQueryUIImages: my other copy task: copies images in
- # bower_components/jqueryui/ to dist/.
- 'copy:distJQueryUIImages'
-
- # copy:distrequirejs: copy require.js into dist/scripts/vendor/, see
- # https://github.com/yeoman/grunt-usemin/issues/192 #
- 'copy:distrequirejs'
-
- # requirejs: creates a single dist/scripts/main.js file containing all of
- # my JavaScript
- 'requirejs'
-
- # I have commented-out imagemin because it adds a random prefix to my
- # images which screws up my application logic and I don't know how to stop
- # that from happening... The images are already quite small, ...
- # 'imagemin'
-
- 'htmlmin'
- 'concat' # task configured by `useminPrepare` above.
-
- 'cssmin' # Concatenate all CSS files into one, configured by useminPrepare
-
- #'uglify:dist'
- #'copy:dist'
- #'copy:requirejs'
- #'uglify:requirejs'
- 'uglify' # JavaScript minification
- 'uglify:requirejs' # minify dist/scripts/vendor/require.js
-
- # rev: Use the rev task together with yeoman/grunt-usemin for cache busting
- # of static files in your app. This allows them to be cached forever by the
- # browser. See https://github.com/cbas/grunt-rev
- 'rev'
-
- # usemin': two subtasks are configured by useminPrepare: usemin:html and
- # usemin:css tasks; the first renames the references to `main.js`,
- # `modernizr.js` and `main.css` # #
- 'usemin'
-
- # regex-replace:dist: change `src="bower_components/requirejs/require.js"`
- # to `src="scripts/vendor/require.js">` in dist/index.html #
- 'regex-replace:dist' # change `src="bower_components/requirejs/require.js"` to `src="scripts/vendor/require.js">` in dist/index.html
-
- # I don't know why dist/bower_components/ is created (...). In any case,
- # I'm just cleaning it up hackily like so.
- # 'clean:postdist'
-
- # copy everything that is supposed ot be in the dist, not sure why there are other copy tasks like disttmp and distJQueryUIImages and distrequirejs
- 'copy:dist'
-
- 'copy:unicodedatajsondist'
- 'copy:serversjsondist'
- ]
-
- grunt.registerTask 'default', ['jshint', 'test', 'build']
-
- grunt.registerTask 'lint', 'coffeelint'
-
- grunt.registerTask 'docs', ['clean:docs', 'clean:doctmp', 'copy:docco', 'docco', 'clean:doctmp']
-
- grunt.registerTask 'deploy', ['jshint', 'build', 'exec:setContinuousDeploymentVersion']
-
- grunt.registerTask 'copydist', 'copy:dist'
- grunt.registerTask 'cleandist', 'clean:dist'
- grunt.registerTask 'imagemin', 'clean:dist'
-
diff --git a/Gruntfile.js b/Gruntfile.js
new file mode 100644
index 0000000..95e32f4
--- /dev/null
+++ b/Gruntfile.js
@@ -0,0 +1,806 @@
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+'use strict';
+const LIVERELOAD_PORT = 35729;
+const SERVER_PORT = 9000;
+const lrSnippet = require('connect-livereload')({port: LIVERELOAD_PORT});
+const mountFolder = (connect, dir) => connect.static(require('path').resolve(dir));
+
+// # Globbing
+// for performance reasons we're only matching one level down:
+// 'test/spec/{,*/}*.js'
+// use this if you want to match all subfolders:
+// 'test/spec/**/*.js'
+// templateFramework: 'lodash'
+
+module.exports = function(grunt) {
+
+ // show elapsed time at the end
+ require('time-grunt')(grunt);
+
+ // load all grunt tasks
+ require('load-grunt-tasks')(grunt);
+
+ // configurable paths
+ const yeomanConfig = {app: 'app', dist: 'dist'};
+
+ grunt.initConfig({
+
+ markdown: {
+ all: {
+ files: [{
+ expand: true,
+ flatten: true,
+ src: '<%= yeoman.app %>/help/src/*.md',
+ dest: '<%= yeoman.app %>/help/html/',
+ ext: '.html'
+ }
+ ],
+ options: {
+ template: '<%= yeoman.app %>/help/src/template.jst'
+ }
+ }
+ },
+
+ yeoman: yeomanConfig,
+
+ watch: {
+ options: {
+ nospawn: true,
+ livereload: true
+ },
+ help: {
+ files: ['<%= yeoman.app %>/help/src/*.md'],
+ tasks: ['markdown:all']
+ },
+ coffee: {
+ files: ['<%= yeoman.app %>/scripts/{,*/}*.js'],
+ tasks: ['copy:coffee', 'coffee:serve']
+ },
+ coffeeTest: {
+ //files: ['test/spec/{,*/}*.js']
+ files: ['test/**/*.js'],
+ tasks: ['coffee:test']
+ },
+ compass: {
+ files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
+ tasks: ['compass']
+ },
+ livereload: {
+ options: {
+ livereload: grunt.option('livereloadport') || LIVERELOAD_PORT
+ },
+ files: [
+ '<%= yeoman.app %>/*.html',
+ '{.tmp,<%= yeoman.app %>}/styles/{,*/}*.css',
+ '{.tmp,<%= yeoman.app %>}/scripts/{,*/}*.js',
+ '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp}',
+ '<%= yeoman.app %>/scripts/templates/*.{ejs,mustache,hbs}',
+ 'test/spec/**/*.js'
+ ]
+ },
+ jst: {
+ files: ['<%= yeoman.app %>/scripts/templates/*.ejs'],
+ tasks: ['jst']
+ },
+ eco: {
+ files: ['<%= yeoman.app %>/scripts/templates/{,*/}*.eco'],
+ tasks: ['eco']
+ },
+ test: {
+ files: ['<%= yeoman.app %>/scripts/{,*/}*.js', 'test/spec/**/*.js'],
+ tasks: ['test:true']
+ }
+ },
+
+ docco: {
+ src: ['.doctmp/*.js'],
+ //src: ['<%= yeoman.app %>/scripts/**/*.js']
+ options: {
+ output: 'docs/'
+ }
+ },
+
+ connect: {
+ options: {
+ port: grunt.option('port') || SERVER_PORT,
+ // change this to '0.0.0.0' to access the server from outside
+ //hostname: 'localhost'
+ hostname: '0.0.0.0'
+ },
+ livereload: {
+ options: {
+ middleware(connect) {
+ return [
+ lrSnippet,
+ mountFolder(connect, '.tmp'),
+ mountFolder(connect, yeomanConfig.app)
+ ];
+ }
+ }
+ },
+ test: {
+ options: {
+ port: 9001,
+ middleware(connect) {
+ return [
+ lrSnippet,
+ mountFolder(connect, '.tmp'),
+ mountFolder(connect, 'test'),
+ mountFolder(connect, yeomanConfig.app)
+ ];
+ }
+ }
+ },
+ dist: {
+ options: {
+ middleware(connect) {
+ return [mountFolder(connect, yeomanConfig.dist)];
+ }
+ }
+ }
+ },
+
+ open: {
+ server: {
+ path: 'http://localhost:<%= connect.options.port %>'
+ },
+ test: {
+ path: 'http://localhost:<%= connect.test.options.port %>'
+ }
+ },
+ //app: 'firefox'
+
+ clean: {
+ dist: ['.tmp', '<%= yeoman.dist %>/*'],
+ postdist: ['<%= yeoman.dist %>/bower_components'],
+ server: '.tmp',
+ doctmp: '.doctmp',
+ docs: 'docs'
+ },
+
+ jshint: {
+ options: {
+ jshintrc: '.jshintrc',
+ reporter: require('jshint-stylish')
+ },
+ all: [
+ 'Gruntfile.js',
+ '<%= yeoman.app %>/scripts/{,*/}*.js',
+ '!<%= yeoman.app %>/scripts/vendor/*',
+ '!<%= yeoman.app %>/scripts/jquery-extensions/*',
+ 'test/spec/{,*/}*.js'
+ ]
+ },
+
+ mocha: {
+ all: {
+ options: {
+ log: true,
+ run: false, // default: true
+ reporter: 'Spec',
+ testtimeout: 90000,
+ urls: ['http://localhost:<%= connect.test.options.port %>/index.html']
+ }
+ }
+ },
+
+ coffee: {
+ serve: {
+ options: {
+ sourceMap: true
+ },
+ files: [{
+ // rather than compiling multiple files here you should
+ // require them into your main .js file
+ expand: true,
+ cwd: '.tmp/scripts',
+ src: '**/*.js',
+ dest: '.tmp/scripts',
+ ext: '.js'
+ }
+ ]
+ },
+ dist: {
+ options: {
+ sourceMap: false
+ },
+ files: [{
+ // rather than compiling multiple files here you should
+ // require them into your main .js file
+ expand: true,
+ cwd: '.tmp/scripts',
+ src: '**/*.js',
+ dest: '.tmp/scripts',
+ ext: '.js'
+ }
+ ]
+ },
+ test: {
+ files: [{
+ expand: true,
+ //cwd: 'test/spec' # original
+ cwd: 'test',
+ //src: '{,*/}*.js' # original
+ src: '**/*.js',
+ dest: '.tmp/spec', // original
+ //dest: '.tmp'
+ ext: '.js'
+ }
+ ]
+ }
+ },
+
+ // TODO
+ eslint: {
+ app: {
+ src: '<%= yeoman.app %>/scripts/**/*.js'
+ },
+ options: {
+ // no_tabs: {
+ // level: 'error'
+ // },
+ // indentation: {
+ // level: 'ignore'
+ // }, // Unfortunately, eslint and requirejs's define callbacks don't play well together
+ // no_trailing_whitespace: {
+ // level: 'error'
+ // },
+ // no_trailing_semicolons: {
+ // level: 'error'
+ // },
+ // no_plusplus: {
+ // level: 'warn'
+ // },
+ // no_implicit_parens: {
+ // level: 'ignore'
+ // }, // change to 'warn' to warn about this
+ // max_line_length: {
+ // level: 'ignore'
+ // }
+ }
+ },
+
+ compass: {
+ options: {
+ sassDir: '<%= yeoman.app %>/styles',
+ cssDir: '.tmp/styles',
+ imagesDir: '<%= yeoman.app %>/images',
+ javascriptsDir: '<%= yeoman.app %>/scripts',
+ fontsDir: '<%= yeoman.app %>/styles/fonts',
+ importPath: '<%= yeoman.app %>/bower_components',
+ relativeAssets: true
+ },
+ dist: {},
+ server: {
+ options: {
+ debugInfo: true
+ }
+ }
+ },
+
+ requirejs: {
+ dist: {
+ // Options: https://github.com/jrburke/r.js/blob/master/build/example.build.js
+ options: {
+ baseUrl: '.tmp/scripts',
+ optimize: 'none',
+ preserveLicenseComments: false,
+ useStrict: true,
+ name: 'main',
+ out: '<%= yeoman.dist %>/scripts/main.js',
+ generateSourceMaps: false,
+ //mainConfigFile: '.tmp/scripts/main.js'
+ // TODO: Figure out how to make sourcemaps work with grunt-usemin
+ // https://github.com/yeoman/grunt-usemin/issues/30
+ //generateSourceMaps: true
+ // required to support SourceMaps
+ // http://requirejs.org/docs/errors.html#sourcemapcomments
+ shim_: {
+ jquery: {
+ exports: '$'
+ },
+ lodash: {
+ exports: '_'
+ },
+ backbone: {
+ exports: 'Backbone',
+ deps: ['lodash', 'jquery']
+ },
+ jqueryui: ['jquery'],
+ backboneindexeddb: ['backbone'],
+ multiselect: ['jquery', 'jqueryui'],
+ jqueryelastic: ['jquery'],
+ perfectscrollbar: ['jquery'],
+ superfish: ['jquery'],
+ superclick: ['jquery'],
+ supersubs: ['jquery'],
+ backbonerelational: ['backbone'],
+ backbonelocalstorage: ['backbone']
+ },
+
+ paths_: {
+ jquery: '../../<%= yeoman.app %>/bower_components/jquery/dist/jquery',
+ backbone: '../../<%= yeoman.app %>/bower_components/backbone/backbone',
+ lodash: '../../<%= yeoman.app %>/bower_components/lodash/dist/lodash',
+ underscore: '../../<%= yeoman.app %>/bower_components/lodash/dist/lodash.underscore',
+ backboneindexeddb:
+ '../../<%= yeoman.app %>/bower_components/indexeddb-backbonejs-adapter/backbone-indexeddb',
+ bootstrap: '../../<%= yeoman.app %>/bower_components/sass-bootstrap/dist/js/bootstrap',
+ text: '../../<%= yeoman.app %>/bower_components/requirejs-text/text',
+ jqueryui: '../../<%= yeoman.app %>/bower_components/jqueryui/jquery-ui',
+ superfish: '../../<%= yeoman.app%>/bower_components/superfish/dist/js/superfish',
+ superclick: '../../<%= yeoman.app%>/bower_components/superclick/dist/js/superclick',
+ //superfish: '../../<%= yeoman.app%>/scripts/jquery-extensions/superfish/dist/js/superfish'
+ //superfish: '../../<%= yeoman.app %>/bower_components/superfish/dist/js/superfish'
+ igt: '../../<%= yeoman.app%>/scripts/jquery-extensions/igt',
+ jqueryuicolors: '../../<%= yeoman.app%>/scripts/jquery-extensions/jqueryui-colors',
+ sfjquimatch: '../../<%= yeoman.app%>/scripts/jquery-extensions/superfish-jqueryui-match',
+ supersubs: '../../<%= yeoman.app%>/bower_components/superfish/dist/js/supersubs',
+ //supersubs: '../../<%= yeoman.app%>/scripts/jquery-extensions/superfish/dist/js/supersubs'
+ //supersubs: '../../<%= yeoman.app %>/bower_components/superfish/dist/js/supersubs'
+ multiselect: '../../<%= yeoman.app %>/bower_components/multiselect/js/jquery.multi-select',
+ jqueryelastic: '../../<%= yeoman.app %>/bower_components/jakobmattsson-jquery-elastic/jquery.elastic.source',
+ spin: '../../<%= yeoman.app %>/bower_components/spin.js/spin',
+ jqueryspin: '../../<%= yeoman.app %>/bower_components/spin.js/jquery.spin',
+ perfectscrollbar: '../../<%= yeoman.app %>/bower_components/perfect-scrollbar/src/perfect-scrollbar',
+ backbonerelational: '../../<%= yeoman.app %>/bower_components/backbone-relational/backbone-relational',
+ backbonelocalstorage: '../../<%= yeoman.app %>/bower_components/backbone.localStorage/backbone.localStorage'
+ }
+ }
+ }
+ },
+
+ useminPrepare: {
+ html: '<%= yeoman.app %>/index.html',
+ options: {
+ dest: '<%= yeoman.dist %>',
+ // Next 5 lines from http://stackoverflow.com/questions/20509145/managing-images-in-bower-packages-using-grunt?lq=1
+ // "Next, the flow configuration tells usemin to skip the concat step for
+ // css files. This is because cssmin does a concatenation itself, and
+ // cssmin needs to know the origin of the css files in order to do the
+ // relative-path correction for referenced resources."
+ flow_: {
+ steps: {
+ js: ['concat', 'uglify'],
+ css: ['cssmin']
+ },
+ post: {}
+ }
+ }
+ },
+
+ usemin: {
+ html: ['<%= yeoman.dist %>/{,*/}*.html'],
+ css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
+ options: {
+ dirs: ['<%= yeoman.dist %>']
+ }
+ },
+
+ imagemin: {
+ dist: {
+ files: [{
+ expand: true,
+ cwd: '<%= yeoman.app %>/images',
+ src: '{,*/}*.{png,jpg,jpeg}',
+ dest: '<%= yeoman.dist %>/images'
+ }
+ ]
+ }
+ },
+
+ // A config for cssmin is unnecessary since that created by useminPrepare works
+ // fine. Hence the name change to `cssmin_' here.
+ cssmin_: {
+ dist: {
+ files: {
+ '<%= yeoman.dist %>/styles/main.css': [
+ '.tmp/styles/{,*/}*.css',
+ '<%= yeoman.app %>/styles/{,*/}*.css',
+ '<%= yeoman.app %>/bower_components/jqueryui/themes/eggplant/jquery-ui.css'
+ ]
+ },
+ options: {
+ root: '<% yeoman.app %>'
+ }
+ }
+ }, // This is where `bower_components/` is to be found
+
+ htmlmin: {
+ dist: {
+ options: {},
+ /*
+ removeCommentsFromCDATA: true,
+ * https://github.com/yeoman/grunt-usemin/issues/44
+ *collapseWhitespace: true,
+ collapseBooleanAttributes: true,
+ removeAttributeQuotes: true,
+ removeRedundantAttributes: true,
+ useShortDoctype: true,
+ removeEmptyAttributes: true,
+ removeOptionalTags: true
+ */
+ files: [{
+ expand: true,
+ cwd: '<%= yeoman.app %>',
+ src: '*.html',
+ dest: '<%= yeoman.dist %>'
+ }
+ ]
+ }
+ },
+
+ copy: {
+ coffee: {
+ files: [{
+ expand: true,
+ dot: true,
+ cwd: '<%= yeoman.app %>/scripts',
+ dest: '.tmp/scripts',
+ src: '**/*.js'
+ }
+ ]
+ },
+ packagejson: {
+ src: 'package.json',
+ dest: '.tmp/'
+ },
+ unicodedatajson: {
+ src: 'UnicodeData.json',
+ dest: '.tmp/'
+ },
+ serversjson: {
+ src: 'servers.json',
+ dest: '.tmp/'
+ },
+ unicodedatajsondist: {
+ src: 'UnicodeData.json',
+ dest: 'dist/'
+ },
+ serversjsondist: {
+ src: 'servers.json',
+ dest: 'dist/'
+ },
+ dist: {
+ files: [{
+ expand: true,
+ dot: true,
+ cwd: '<%= yeoman.app %>',
+ dest: '<%= yeoman.dist %>',
+ src_: [
+ 'UnicodeData.json',
+ 'bower_components/jqueryui/**/*.*' // added, cf. http://stackoverflow.com/questions/20509145/managing-images-in-bower-packages-using-grunt?lq=1
+ ],
+ src: [
+ '*.{ico,txt}',
+ '.htaccess',
+ 'favicon.png',
+ 'help/html/help.html',
+ './../package.json',
+ './../.tmp/UnicodeData.json',
+ './../.tmp/servers.json',
+ 'images/{,*/}*.{webp,gif,png,jpg}', // added png so that my jQuery images in /images would copy over, cf. imagemin headache
+ 'styles/fonts/{,*/}*.*',
+ 'bower_components/sass-bootstrap/fonts/*.*',
+ 'bower_components/jqueryui/**/*.*' // added, cf. http://stackoverflow.com/questions/20509145/managing-images-in-bower-packages-using-grunt?lq=1
+ ]
+ }
+ ]
+ },
+ disttmp: {
+ files: [{
+ expand: true,
+ dot: true,
+ cwd: '<%= yeoman.app %>',
+ dest: '.tmp',
+ src: [
+ 'bower_components/{,**/}*.*',
+ 'scripts/jquery-extensions/{,**/}*.*'
+ ]
+ }
+ ]
+ },
+ // Copy jQueryUI images to dist/styles/images/
+ distJQueryUIImages: {
+ files: [{
+ expand: true,
+ dot: true,
+ cwd: '<%= yeoman.app %>',
+ dest: '<%= yeoman.dist %>/styles/images',
+ flatten: true, // CRUCIAL!!!
+ src: [
+ 'bower_components/jqueryui/**/*.{png,jpg,jpeg,gif,webp,svg,eot,ttf,woff}' // added, cf. http://stackoverflow.com/questions/20509145/managing-images-in-bower-packages-using-grunt?lq=1
+ ]
+ }
+ ]
+ },
+ distrequirejs: { // from https://github.com/yeoman/grunt-usemin/issues/192
+ expand: true,
+ cwd: '<%= yeoman.app %>/bower_components/requirejs/',
+ dest: '<%= yeoman.dist %>/scripts/vendor/',
+ src: ['require.js']
+ },
+ docco: {
+ files: [{
+ expand: true,
+ cwd: '<%= yeoman.app %>/scripts/', // src/modules/'
+ src: ['**/*.js'],
+ dest: '.doctmp/', // dev/js/'
+ rename(dest, src) {
+ return dest + src.replace(/\//g, '.');
+ }
+ }
+ , {
+ expand: true,
+ cwd: 'test/',
+ src: ['!bower_components/*.js', '**/*.js'],
+ dest: '.doctmp/',
+ rename(dest, src) {
+ return dest + 'test.' + src.replace(/\//g, '.');
+ }
+ }
+ ]
+ },
+ requirejs: {
+ src: '<%= yeoman.app %>/bower_components/requirejs/require.js',
+ dest: '<%= yeoman.dist %>/bower_components/requirejs/require.js'
+ }
+ },
+
+ uglify: { // altered for debugging purposes.
+ dist_: {
+ files: {
+ '<%= yeoman.dist %>/scripts/main.js': ['<%= yeoman.dist %>/scripts/main.js']
+ }
+ },
+ requirejs: {
+ files: {
+ '<%= yeoman.dist %>/scripts/vendor/require.js': ['<%= yeoman.dist %>/scripts/vendor/require.js']
+ }
+ }
+ },
+
+ bower: {
+ all: {
+ rjsConfig: '<%= yeoman.app %>/scripts/main.js'
+ }
+ },
+
+ jst: {
+ options: {
+ amd: true
+ },
+ compile: {
+ files: {
+ '.tmp/scripts/templates.js': ['<%= yeoman.app %>/scripts/templates/*.ejs']
+ }
+ }
+ },
+
+ eco: {
+ options: {
+ amd: true
+ },
+ files: {
+ expand: true,
+ cwd: '<%= yeoman.app %>/scripts/templates',
+ src: ['*.eco', 'fields/*.eco'],
+ dest: '.tmp/scripts/templates',
+ ext: '.js'
+ }
+ },
+
+ exec: {
+ setContinuousDeploymentVersion: {
+ cmd() {
+ return 'bash scripts/set_ci_version.sh';
+ }
+ }
+ },
+
+ rev: {
+ dist: {
+ files: {
+ src: [
+ '<%= yeoman.dist %>/scripts/{,*/!(require)}*.js', // Add exception not to change name of copied file during "rev" task (added only !(require) exception), cf. https://github.com/yeoman/grunt-usemin/issues/192
+ '<%= yeoman.dist %>/styles/{,*/}*.css',
+ '<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp}',
+ '/styles/fonts/{,*/}*.*',
+ 'bower_components/sass-bootstrap/fonts/*.*',
+ 'bower_components/**/*.{png,jpg,jpeg,gif,webp,svg,eot,ttf,woff}' // added, cf. http://stackoverflow.com/questions/20509145/managing-images-in-bower-packages-using-grunt?lq=1
+ ]
+ }
+ }
+ },
+
+ // Replace script tag in index.html, to call require.js from new path using grunt-regex-replace plugin:
+ // See https://github.com/yeoman/grunt-usemin/issues/192
+ 'regex-replace': {
+ dist: {
+ src: ['<%= yeoman.dist %>/index.html'],
+ actions: [{
+ name: 'requirejs-newpath',
+ search: '',
+ replace(match) {
+ const regex = /scripts\/.*main/;
+ const result = regex.exec(match);
+ return '';
+ },
+ flags: 'g'
+ }
+ ]
+ }
+ }});
+
+ grunt.registerTask('createDefaultTemplate', () => grunt.file.write('.tmp/scripts/templates.js', 'this.JST = this.JST || {}'));
+
+ grunt.registerTask('server', function(target) {
+ grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
+ return grunt.task.run(['serve' + (target != null ? target : ':' + {target : ''})]);
+});
+
+ grunt.registerTask('serve', function(target) {
+ if (target === 'dist') {
+ return grunt.task.run(['build', 'open:server', 'connect:dist:keepalive']);
+ }
+
+ if (target === 'test') {
+ return grunt.task.run([
+ 'markdown:all',
+ 'clean:server',
+ 'copy:coffee',
+ 'copy:packagejson',
+ 'copy:unicodedatajson',
+ 'copy:serversjson',
+ 'coffee:serve',
+ 'coffee:test',
+ //'createDefaultTemplate'
+ //'jst'
+ 'eco',
+ //'compass:server'
+ 'connect:test',
+ 'open:test',
+ 'watch'
+ ]);
+ }
+
+ return grunt.task.run([
+ 'markdown:all',
+ 'clean:server',
+ 'copy:coffee',
+ 'copy:packagejson',
+ 'copy:unicodedatajson',
+ 'copy:serversjson',
+ 'coffee:serve',
+ //'createDefaultTemplate'
+ //'jst'
+ 'eco',
+ //'compass:server'
+ 'connect:livereload',
+ //'open:server'
+ 'watch'
+ ]);
+});
+
+ grunt.registerTask('coffeeDist', ['copy:coffee', 'coffee:dist']);
+
+ grunt.registerTask('test', function(isConnected) {
+ isConnected = Boolean(isConnected);
+ const testTasks = [
+ 'clean:server',
+ 'coffee',
+ //'createDefaultTemplate'
+ //'jst'
+ 'eco',
+ //'compass'
+ 'connect:test',
+ 'mocha'
+ ];
+ if (!isConnected) {
+ return grunt.task.run(testTasks);
+ } else {
+ // already connected so not going to connect again, remove the connect:test task
+ testTasks.splice(testTasks.indexOf('connect:test'), 1);
+ return grunt.task.run(testTasks);
+ }
+ });
+
+ grunt.registerTask('build', [
+ 'markdown:all',
+ 'clean:dist', // remove everything in dist/ and .tmp/
+ 'copy:coffee', // copy all .js files in app/scripts/ to .tmp/scripts/
+ 'copy:packagejson',
+ 'copy:unicodedatajson',
+ 'copy:serversjson',
+ 'coffee:dist', // convert all .js files in .tmp/scripts to .js in situ
+
+ // eco: convert all .eco files in app/scripts/templates/ to .js files in
+ // .tmp/scripts/templates/
+ 'eco',
+
+ // permits execution of shell scripts
+ 'exec:setContinuousDeploymentVersion',
+
+ //'compass:dist' # commented out because not currently using compass
+
+ // useminPrepare: read the `build` comments in index.html and dynamically
+ // generate concat, uglify, and or cssmin `generated` tasks.
+ 'useminPrepare',
+
+ // copy:disttmp: my copy task: copies bower_components and jquery-extensions
+ // to .tmp. This seems to be necessary: SHOW FAILM MSG: ... Error: ENOENT,
+ // no such file or directory '.tmp/bower_components/lodash/dist/lodash.js'
+ 'copy:disttmp',
+
+ // copy:distJQueryUIImages: my other copy task: copies images in
+ // bower_components/jqueryui/ to dist/.
+ 'copy:distJQueryUIImages',
+
+ // copy:distrequirejs: copy require.js into dist/scripts/vendor/, see
+ // https://github.com/yeoman/grunt-usemin/issues/192 #
+ 'copy:distrequirejs',
+
+ // requirejs: creates a single dist/scripts/main.js file containing all of
+ // my JavaScript
+ 'requirejs',
+
+ // I have commented-out imagemin because it adds a random prefix to my
+ // images which screws up my application logic and I don't know how to stop
+ // that from happening... The images are already quite small, ...
+ // 'imagemin'
+
+ 'htmlmin',
+ 'concat', // task configured by `useminPrepare` above.
+
+ 'cssmin', // Concatenate all CSS files into one, configured by useminPrepare
+
+ //'uglify:dist'
+ //'copy:dist'
+ //'copy:requirejs'
+ //'uglify:requirejs'
+ 'uglify', // JavaScript minification
+ 'uglify:requirejs', // minify dist/scripts/vendor/require.js
+
+ // rev: Use the rev task together with yeoman/grunt-usemin for cache busting
+ // of static files in your app. This allows them to be cached forever by the
+ // browser. See https://github.com/cbas/grunt-rev
+ 'rev',
+
+ // usemin': two subtasks are configured by useminPrepare: usemin:html and
+ // usemin:css tasks; the first renames the references to `main.js`,
+ // `modernizr.js` and `main.css` # #
+ 'usemin',
+
+ // regex-replace:dist: change `src="bower_components/requirejs/require.js"`
+ // to `src="scripts/vendor/require.js">` in dist/index.html #
+ 'regex-replace:dist', // change `src="bower_components/requirejs/require.js"` to `src="scripts/vendor/require.js">` in dist/index.html
+
+ // I don't know why dist/bower_components/ is created (...). In any case,
+ // I'm just cleaning it up hackily like so.
+ // 'clean:postdist'
+
+ // copy everything that is supposed ot be in the dist, not sure why there are other copy tasks like disttmp and distJQueryUIImages and distrequirejs
+ 'copy:dist',
+
+ 'copy:unicodedatajsondist',
+ 'copy:serversjsondist'
+ ]);
+
+ grunt.registerTask('default', ['jshint', 'test', 'build']);
+
+ grunt.registerTask('lint', 'eslint');
+
+ grunt.registerTask('docs', ['clean:docs', 'clean:doctmp', 'copy:docco', 'docco', 'clean:doctmp']);
+
+ grunt.registerTask('deploy', ['jshint', 'build', 'exec:setContinuousDeploymentVersion']);
+
+ grunt.registerTask('copydist', 'copy:dist');
+ grunt.registerTask('cleandist', 'clean:dist');
+ return grunt.registerTask('imagemin', 'clean:dist');
+};
+
diff --git a/app/scripts/collections/application-settings.coffee b/app/scripts/collections/application-settings.coffee
deleted file mode 100644
index 10277ce..0000000
--- a/app/scripts/collections/application-settings.coffee
+++ /dev/null
@@ -1,13 +0,0 @@
-define [
- 'backbone',
- './../models/application-settings'
- ], (Backbone, ApplicationSettingsModel) ->
-
- # Application Settings Collection
- # -------------------------------
-
- class ApplicationSettingsCollection extends Backbone.Collection
-
- model: ApplicationSettingsModel
- localStorage: new Backbone.LocalStorage('dativeApplicationSettings')
-
diff --git a/app/scripts/collections/collections.coffee b/app/scripts/collections/collections.coffee
deleted file mode 100644
index 5fe49d6..0000000
--- a/app/scripts/collections/collections.coffee
+++ /dev/null
@@ -1,23 +0,0 @@
-define [
- './resources'
- './../models/collection'
-], (ResourcesCollection, CollectionModel) ->
-
- # Collections Collection
- # ----------------------
- #
- # Holds models for (OLD) collections, i.e., texts.
-
- class CollectionsCollection extends ResourcesCollection
-
- resourceName: 'collection'
- model: CollectionModel
-
- # When an OLD collection resource is added/updated and its contents contain
- # bad form references, the attribute will be "forms", though from Dative's
- # perspective it should be "contents".
- errorAttributeTransformer: (errorAttribute) ->
- if errorAttribute == 'forms'
- return 'contents'
- errorAttribute
-
diff --git a/app/scripts/collections/corpora.coffee b/app/scripts/collections/corpora.coffee
deleted file mode 100644
index f0ef8ad..0000000
--- a/app/scripts/collections/corpora.coffee
+++ /dev/null
@@ -1,56 +0,0 @@
-define [
- 'backbone',
- './../models/corpus'
- ], (Backbone, CorpusModel) ->
-
- # Corpora Collection
- # ------------------
- #
- # Holds models for FieldDB corpora.
-
- class CorporaCollection extends Backbone.Collection
-
- model: CorpusModel
-
- # Create a new corpus.
- # POST `/newcorpus`
- newCorpus: (newCorpusName) ->
- Backbone.trigger 'newCorpusStart', newCorpusName
- payload =
- authUrl: @applicationSettings.get?('activeServer')?.get?('url')
- username: @applicationSettings.get?('username')
- password: @applicationSettings.get?('password') # TODO use confirm identity event instead
- serverCode: @applicationSettings.get?('activeServer')?.get?('serverCode')
- newCorpusName: newCorpusName
- CorpusModel.cors.request(
- method: 'POST'
- timeout: 10000
- url: "#{payload.authUrl}/newcorpus"
- payload: payload
- onload: (responseJSON) =>
- Backbone.trigger 'newCorpusEnd'
- if responseJSON.corpusadded
- if responseJSON.corpus
- corpusObject = responseJSON.corpus
- corpusObject.applicationSettings = @applicationSettings
- @unshift corpusObject
- Backbone.trigger 'newCorpusSuccess', newCorpusName
- else
- Backbone.trigger 'newCorpusFail',
- ["There was an error creating corpus “#{newCorpusName}”.",
- "This name is probably already taken.",
- "Try a different one."].join ' '
- console.log responseJSON.userFriendlyErrors[0]
- else
- Backbone.trigger 'newCorpusFail', "Request to create corpus failed: `corpusadded` not truthy."
- console.log 'Failed request to /newcorpus: `corpusadded` not truthy.'
- onerror: (responseJSON) ->
- Backbone.trigger 'newCorpusEnd'
- Backbone.trigger 'newCorpusFail', "Request to create corpus failed with an error."
- console.log 'Failed request to /newcorpus: error.'
- ontimeout: ->
- Backbone.trigger 'newCorpusEnd'
- Backbone.trigger 'newCorpusFail', "Request to create corpus failed: request timed out."
- console.log 'Failed request to /newcorpus: timed out.'
- )
-
diff --git a/app/scripts/collections/elicitation-methods.coffee b/app/scripts/collections/elicitation-methods.coffee
deleted file mode 100644
index 753a703..0000000
--- a/app/scripts/collections/elicitation-methods.coffee
+++ /dev/null
@@ -1,16 +0,0 @@
-define [
- './resources'
- './../models/elicitation-method'
-], (ResourcesCollection, ElicitationMethodModel) ->
-
- # Elicitation Methods Collection
- # ------------------------------
- #
- # Holds models for elicitation methods.
-
- class ElicitationMethodsCollection extends ResourcesCollection
-
- resourceName: 'elicitationMethod'
- model: ElicitationMethodModel
-
-
diff --git a/app/scripts/collections/files.coffee b/app/scripts/collections/files.coffee
deleted file mode 100644
index f1154c2..0000000
--- a/app/scripts/collections/files.coffee
+++ /dev/null
@@ -1,84 +0,0 @@
-define [
- './resources'
- './../models/file'
-], (ResourcesCollection, FileModel) ->
-
- # Files Collection
- # ----------------
- #
- # Holds models for files. Note that because of the particular way in which
- # OLD web services handle the uploading of large files---i.e., the request
- # must be multipart/form-data, not JSON---we make some customizations here.
-
- class FilesCollection extends ResourcesCollection
-
- resourceName: 'file'
- model: FileModel
-
- addResource: (resource, options={}) ->
- options.monitorProgress = true
- options.progressModel = resource
- if resource.get('dative_file_type') is 'storedOnTheServer' and
- resource.get('base64_encoded_file') is ''
- @addFileAsMultipartFormData resource, options
- else
- super resource, options
-
- getResourceForServerCreateMultipartFormData: (resource) ->
- formData = new FormData()
- for attribute of resource.attributes
- value = resource.get attribute
- if attribute in ['elicitor', 'speaker']
- if value is undefined
- value = ''
- else
- value = value.id
- if attribute in ['base64_encoded_file', 'parent_file']
- value = ''
- if attribute isnt 'search-term' # `search-term` isn't a file attribute; also, the OLD will choke on it because it'll expect "term" to be a numeric index.
- if attribute in ['tags', 'forms']
- for element, index in value
- formData.append "#{attribute}-#{index}", element.id
- else
- formData.append attribute, value
- formData
-
- addFileAsMultipartFormData: (resource, options) ->
- resource.trigger "add#{@resourceNameCapitalized}Start"
- payload = @getResourceForServerCreateMultipartFormData resource
- monitorProgress = options.monitorProgress or false
- progressModel = options.progressModel or null
- @model.cors.request(
- monitorProgress: monitorProgress
- progressModel: progressModel
- contentType: "multipart/form-data;" # This isn't actually used, it's just a signal to `CORS` that this is multipart/form-data...
- method: 'POST'
- url: @getAddResourceURL resource
- payload: payload
- onload: (responseJSON, xhr) =>
- @addResourceOnloadHandler resource, responseJSON, xhr, payload
- onerror: (responseJSON) =>
- resource.trigger "add#{@resourceNameCapitalized}End"
- resource.trigger "add#{@resourceNameCapitalized}Fail",
- responseJSON.error, resource
- console.log "Error in POST request to /#{@getServerSideResourceName()}"
- )
-
- # The OLD processes the file create request conditionally based on the
- # *presence* of either of the attributes `base64_encoded_file` and `url`.
- # Since Dative encodes this file "type" explicitly, we delete these
- # attributes from the payload, as appropriate, based on the type.
- getResourceForServerCreate: (resource) ->
- result = super resource
- if resource.get('dative_file_type') is 'storedOnTheServer'
- delete result.url
- if not resource.get 'base64_encoded_file'
- delete result.base64_encoded_file
- delete result.parent_file
- else if resource.get('dative_file_type') is 'storedOnAnotherServer'
- delete result.base64_encoded_file
- else if resource.get('dative_file_type') is 'referencesASubintervalOfAnotherFile'
- delete result.base64_encoded_file
- delete result.url
- result
-
diff --git a/app/scripts/collections/forms.coffee b/app/scripts/collections/forms.coffee
deleted file mode 100644
index c1c02ca..0000000
--- a/app/scripts/collections/forms.coffee
+++ /dev/null
@@ -1,235 +0,0 @@
-define [
- './resources'
- './../models/form'
- './../utils/globals'
- './../utils/utils'
-], (ResourcesCollection, FormModel, globals, utils) ->
-
- # Forms Collection
- # ----------------
- #
- # Holds models for forms.
-
- class FormsCollection extends ResourcesCollection
-
- resourceName: 'form'
- model: FormModel
-
-
- ############################################################################
- # FETCH.
- ############################################################################
-
- # Method to handle the `onload` event of a CORS request to fetch a
- # collection of forms from a server. In the OLD case, we use the
- # superclass method; in the FieldDB case, we use a custom handler defined
- # below.
- fetchResourcesOnloadHandler: (responseJSON) ->
- switch globals.applicationSettings.get('activeServer').get('type')
- when 'OLD' then super responseJSON
- when 'FieldDB' then @fetchResourcesOnloadHandlerFieldDB responseJSON
-
- # Method to handle the `onload` event of a CORS request to fetch a
- # page of datums from a FieldDB server.
- fetchResourcesOnloadHandlerFieldDB: (responseJSON) ->
- @trigger "fetch#{@resourceNamePluralCapitalized}End"
- if responseJSON.rows
- @add @getDativeFormModelsFromFieldDBObjects(responseJSON)
- # The view that listens to `fetchFieldDBFormsSuccess` needs as
- # argument a "paginator", which in this case just means an object
- # with a `count` attribute.
- paginator = count: responseJSON.total_rows
- @trigger("fetch#{@resourceNamePluralCapitalized}Success",
- paginator)
- else
- reason = responseJSON.reason or 'unknown'
- @trigger("fetch#{@resourceNamePluralCapitalized}Fail",
- "Failed in fetching the data. #{reason}")
- console.log "request to datums_chronological failed; reason: #{reason}"
-
- ############################################################################
- # CREATE.
- ############################################################################
-
- # Method to handle the `onload` event of a CORS request to create a
- # form. Delegates to the superclass's method in the OLD case and to a method
- # defined here in the FieldDB case.
- addResourceOnloadHandler: (resource, responseJSON, xhr, payload) ->
- switch globals.applicationSettings.get('activeServer').get('type')
- when 'OLD'
- super resource, responseJSON, xhr, payload
- when 'FieldDB'
- @addResourceOnloadHandlerFieldDB resource, responseJSON, xhr, payload
-
- # Method to handle the `onload` event of a CORS request to add a
- # FieldDB datum (form).
- addResourceOnloadHandlerFieldDB: (resource, responseJSON, xhr, payload) ->
- resource.trigger "add#{@resourceNameCapitalized}End"
- if xhr.status is 201 and responseJSON.ok is true
- resource.set
- id: responseJSON.id
- _id: responseJSON.id
- _rev: responseJSON.rev
- dateEntered: payload.dateEntered
- dateModified: payload.dateModified
- timestamp: payload.timestamp
- pouchname: payload.pouchname
- comments: payload.comments
- newEnteredByUser = _.findWhere payload.datumFields, label: 'enteredByUser'
- enteredByUser = _.findWhere resource.get('datumFields'), label: 'enteredByUser'
- enteredByUser.value = newEnteredByUser.username
- enteredByUser.mask = newEnteredByUser.username
- enteredByUser.user = newEnteredByUser.user
- resource.trigger 'change'
- resource.trigger "add#{@resourceNameCapitalized}Success"
- else
- errors = responseJSON.errors or {}
- error = responseJSON.error
- resource.trigger "add#{@resourceNameCapitalized}Fail", error, resource
- for attribute, error of errors
- resource.trigger "validationError:#{attribute}", error
- console.log "add (POST) request to
- /#{@getAddResourceURLFieldDB resource} failed (status not 201
- and/or `response.ok != true`)"
- console.log errors
-
- ############################################################################
- # UPDATE.
- ############################################################################
-
- # Method to handle the `onload` event of a CORS request to update a
- # form. Delegates to the superclass's method in the OLD case and to a method
- # defined here in the FieldDB case.
- updateResourceOnloadHandler: (resource, responseJSON, xhr, payload) ->
- switch globals.applicationSettings.get('activeServer').get('type')
- when 'OLD'
- super resource, responseJSON, xhr, payload
- when 'FieldDB'
- @updateResourceOnloadHandlerFieldDB resource, responseJSON, xhr, payload
-
- # Method to handle the `onload` event of a CORS request to update a
- # FieldDB datum (form).
- updateResourceOnloadHandlerFieldDB: (resource, responseJSON, xhr, payload) ->
- resource.trigger "update#{@resourceNameCapitalized}End"
- if xhr.status is 201 and responseJSON.ok is true
- # FieldDB does no server-side processing. We just need to update the
- # CouchDB revision UUID and add the client-side-created update-related
- # attributes ...
- resource.set
- _rev: responseJSON.rev
- dateModified: payload.dateModified
- timestamp: payload.timestamp
- pouchname: payload.pouchname
- comments: payload.comments
- newModifiedByUser = _.findWhere payload.datumFields, label: 'modifiedByUser'
- modifiedByUser = _.findWhere resource.get('datumFields'), label: 'modifiedByUser'
- modifiedByUser.users = newModifiedByUser.users
- resource.trigger 'change'
- resource.trigger "update#{@resourceNameCapitalized}Success"
- else
- errors = responseJSON.errors or {}
- error = responseJSON.error
- resource.trigger "update#{@resourceNameCapitalized}Fail", error, resource
- for attribute, error of errors
- resource.trigger "validationError:#{attribute}", error
- console.log "Update (PUT) request to
- /#{@getUpdateResourceURLFieldDB resource} failed (status not 201
- and/or `response.ok != true`)"
- console.log errors
-
-
- ############################################################################
- # Helpers.
- ############################################################################
-
- # Returns the URL for fetching a page of resources.
- getResourcesPaginationURL: (options) ->
- switch globals.applicationSettings.get('activeServer').get('type')
- when 'OLD' then super options
- when 'FieldDB' then @getFieldDBFormsPaginationURL options
-
- # Returns the FieldDB URL for fetching a page of datums.
- getFieldDBFormsPaginationURL: (options) ->
- url = @getFetchAllFieldDBFormsURL()
- if options.page and options.page isnt 0 and options.itemsPerPage
- skip = (options.page - 1) * options.itemsPerPage
- "#{url}?limit=#{options.itemsPerPage}&skip=#{skip}"
- else
- "#{url}?limit=#{options.itemsPerPage}"
-
- # Returns the FieldDB URL for fetching all datums in a corpus, in
- # chronological order.
- getFetchAllFieldDBFormsURL: ->
- url = globals.applicationSettings.get('fieldDBApplication').corpus.url
- "#{url}/_design/deprecated/_view/datums_chronological"
-
- # Returns a URL for updating a resource on a web service.
- getUpdateResourceURL: (resource) ->
- switch globals.applicationSettings.get('activeServer').get('type')
- when 'OLD' then super resource
- when 'FieldDB' then @getUpdateResourceURLFieldDB resource
-
- # Returns a URL for updating a resource on a FieldDB web service.
- # PUT //?rev=
- getUpdateResourceURLFieldDB: (resource) ->
- url = globals.applicationSettings.get 'baseDBURL'
- pouchname = globals.applicationSettings.get 'activeFieldDBCorpus'
- "#{url}/#{pouchname}/#{resource.get '_id'}?rev=#{resource.get '_rev'}"
-
- # Return a URL for adding a resource to a web service.
- getAddResourceURL: (resource) ->
- switch globals.applicationSettings.get('activeServer').get('type')
- when 'OLD' then super resource
- when 'FieldDB' then @getAddResourceURLFieldDB resource
-
- # Returns a URL for adding a resource to a FieldDB web service.
- # POST //
- getAddResourceURLFieldDB: (resource) ->
- url = globals.applicationSettings.get 'baseDBURL'
- pouchname = globals.applicationSettings.get 'activeFieldDBCorpus'
- "#{url}/#{pouchname}"
-
-
- ############################################################################
- # TODOs related to the following two methods.
- ############################################################################
-
- # TODO: How do I valuate the `version` field of a particular datum field
- # object? Example value I've seen in Spreadsheet: "v2.45.02".
- # Relatedly, How do I set the `version` attribute of a user in
- # `enteredByUser` or `modifiedByUser`?
- # Example value seen: '2.45.02.01.33ss Mon Mar 2 01:37:08 EST 2015'
-
- # TODO: most FieldDB apps treat the session as a many-to-one required
- # relation; however, I want to treat them as a many-to-many optional
- # relation, i.e., any datum can belong to zero or more sessions. The only
- # problem with this is that some session attributes will need to be
- # present on datums and the denotation of "session" needs to be more
- # general. Here, provisionally, I delete an empty `session` attribute on a
- # create request.
-
- # TODO: blank comments should never be `setToModel` in the first place.
- # This needs to be handled in the field view.
-
- # TODO: stop Dative from valuating the timestamps of previously created
- # comments.
-
- # TODO: the attributes set here for server consumption need to be carefully
- # saved to the client-side model, iff save has succeeded.
-
- # Returns a representation of a form that a server will accept for form
- # creation.
- getResourceForServerCreate: (resource) ->
- switch globals.applicationSettings.get('activeServer').get('type')
- when 'OLD' then super resource
- when 'FieldDB' then resource.toFieldDBForCreate()
-
- getResourceForServerUpdate: (resource) ->
- switch globals.applicationSettings.get('activeServer').get('type')
- when 'OLD' then super resource
- when 'FieldDB' then resource.toFieldDBForUpdate()
-
- # Return an array of `FormModel` instances built from FieldDB objects.
- getDativeFormModelsFromFieldDBObjects: (responseJSON) ->
- (new FormModel()).fieldDB2dative(o) for o in responseJSON.rows
-
diff --git a/app/scripts/collections/keyboards.coffee b/app/scripts/collections/keyboards.coffee
deleted file mode 100644
index 3a8b114..0000000
--- a/app/scripts/collections/keyboards.coffee
+++ /dev/null
@@ -1,32 +0,0 @@
-define [
- './resources'
- './../models/keyboard'
-], (ResourcesCollection, KeyboardModel) ->
-
- # Keyboards Collection
- # --------------------
- #
- # Holds models for keyboards.
-
- class KeyboardsCollection extends ResourcesCollection
-
- resourceName: 'keyboard'
- model: KeyboardModel
-
- # Return a representation of `resource` that the server will accept (for a
- # create or update request). See `collections/forms.coffee for a
- # FieldDB-specific override.
- getResourceForServer: (resource) ->
- result = resource.toOLD()
- result.keyboard = @prepKeyboard result.keyboard
- result
-
- prepKeyboard: (keyboard) ->
- keysToDelete = []
- for keycode, keyMap of keyboard
- if not _.some(_.values(keyMap))
- keysToDelete.push keycode
- for attr in keysToDelete
- delete keyboard[attr]
- JSON.stringify keyboard
-
diff --git a/app/scripts/collections/language-models.coffee b/app/scripts/collections/language-models.coffee
deleted file mode 100644
index 0fe4735..0000000
--- a/app/scripts/collections/language-models.coffee
+++ /dev/null
@@ -1,17 +0,0 @@
-define [
- './resources'
- './../models/language-model'
-], (ResourcesCollection, LanguageModelModel) ->
-
- # Language Models Collection
- # --------------------------
- #
- # Holds models for language models.
-
- class LanguageModelsCollection extends ResourcesCollection
-
- resourceName: 'languageModel'
- model: LanguageModelModel
-
- serverSideResourceName: 'morphemelanguagemodels'
-
diff --git a/app/scripts/collections/languages.coffee b/app/scripts/collections/languages.coffee
deleted file mode 100644
index 82d3329..0000000
--- a/app/scripts/collections/languages.coffee
+++ /dev/null
@@ -1,18 +0,0 @@
-define [
- './resources'
- './../models/language'
-], (ResourcesCollection, LanguageModel) ->
-
- # Languages Collection
- # --------------------
- #
- # Holds models for languages.
-
- class LanguagesCollection extends ResourcesCollection
-
- resourceName: 'language'
- model: LanguageModel
-
-
-
-
diff --git a/app/scripts/collections/morphological-parsers.coffee b/app/scripts/collections/morphological-parsers.coffee
deleted file mode 100644
index fe7b243..0000000
--- a/app/scripts/collections/morphological-parsers.coffee
+++ /dev/null
@@ -1,17 +0,0 @@
-define [
- './resources'
- './../models/morphological-parser'
-], (ResourcesCollection, MorphologicalParserModel) ->
-
- # Morphological Parsers Collection
- # --------------------------------
- #
- # Holds models for morphological parsers.
-
- class MorphologicalParsersCollection extends ResourcesCollection
-
- resourceName: 'morphologicalParser'
- model: MorphologicalParserModel
-
- serverSideResourceName: 'morphologicalparsers'
-
diff --git a/app/scripts/collections/morphologies.coffee b/app/scripts/collections/morphologies.coffee
deleted file mode 100644
index 478e3c9..0000000
--- a/app/scripts/collections/morphologies.coffee
+++ /dev/null
@@ -1,15 +0,0 @@
-define [
- './resources'
- './../models/morphology'
-], (ResourcesCollection, MorphologyModel) ->
-
- # Morphologies Collection
- # -----------------------
- #
- # Holds models for morphologies.
-
- class MorphologiesCollection extends ResourcesCollection
-
- resourceName: 'morphology'
- model: MorphologyModel
-
diff --git a/app/scripts/collections/old-application-settings.coffee b/app/scripts/collections/old-application-settings.coffee
deleted file mode 100644
index 537d1ed..0000000
--- a/app/scripts/collections/old-application-settings.coffee
+++ /dev/null
@@ -1,38 +0,0 @@
-define [
- './resources'
- './../models/old-application-settings'
-], (ResourcesCollection, OLDApplicationSettingsModel) ->
-
- # OLD Application Settings Collection
- # -----------------------------------
- #
- # Holds models for OLD application settings.
- #
- # *NOTE:* The OLD has no pagination for its application settings `index`
- # action. This means that all we can do is retrieve *all* of the application
- # settings. As a result, this class overrides the super-class's
- # `fetchResourcesOnloadHandler`.
-
- class OLDApplicationSettingsCollection extends ResourcesCollection
-
- resourceName: 'oldApplicationSettings'
- serverSideResourceName: 'applicationsettings'
- model: OLDApplicationSettingsModel
-
- # Method to handle the `onload` event of a CORS request to fetch all of an
- # OLD web service's application settings resources.
- # Note the strange spellings of the events triggered here; just go along
- # with it ...
- fetchResourcesOnloadHandler: (responseJSON) ->
- Backbone.trigger 'fetchOldApplicationSettingsesEnd'
- if @utils.type(responseJSON) is 'array'
- if responseJSON.length isnt 0
- @reset @getDativeResourceModelsFromOLDObjects(responseJSON)
- Backbone.trigger 'fetchOldApplicationSettingsesSuccess'
- else
- # Failure to retrieve application settings indicates that we are not
- # logged in. `AppView` hears the following event and sets its
- # `@loggedIn` to `false` in response.
- Backbone.trigger 'fetchOldApplicationSettingsesFail',
- 'failed to fetch all OLD application settings resources'
-
diff --git a/app/scripts/collections/orthographies.coffee b/app/scripts/collections/orthographies.coffee
deleted file mode 100644
index b54ee8c..0000000
--- a/app/scripts/collections/orthographies.coffee
+++ /dev/null
@@ -1,18 +0,0 @@
-define [
- './resources'
- './../models/orthography'
-], (ResourcesCollection, OrthographyModel) ->
-
- # Orthographies Collection
- # ------------------------
- #
- # Holds models for orthographies.
-
- class OrthographiesCollection extends ResourcesCollection
-
- resourceName: 'orthography'
- model: OrthographyModel
-
-
-
-
diff --git a/app/scripts/collections/pages.coffee b/app/scripts/collections/pages.coffee
deleted file mode 100644
index 1a0d61b..0000000
--- a/app/scripts/collections/pages.coffee
+++ /dev/null
@@ -1,33 +0,0 @@
-define [
- './resources'
- './../models/page'
- './../utils/globals'
- ], (ResourcesCollection, PageModel, globals) ->
-
- # Pages Collection
- # ----------------
- #
- # Holds models for pages.
-
- class PagesCollection extends ResourcesCollection
-
- resourceName: 'page'
- model: PageModel
-
- # If the home page is updated, we need to tell the `AppView` about that.
- updateResourceOnloadHandler: (resource, responseJSON, xhr, payload) ->
- @checkForHomePageChange responseJSON, xhr
- super resource, responseJSON, xhr, payload
-
- # If a 'home' page has just been created, we need to tell the `AppView`
- # about that.
- addResourceOnloadHandler: (resource, responseJSON, xhr, payload) ->
- @checkForHomePageChange responseJSON, xhr
- super resource, responseJSON, xhr, payload
-
- checkForHomePageChange: (responseJSON, xhr) ->
- if xhr.status is 200 and responseJSON.name == 'home'
- globals.applicationSettings.set 'homepage', responseJSON
- globals.applicationSettings.save()
- Backbone.trigger 'homePageChanged'
-
diff --git a/app/scripts/collections/phonologies.coffee b/app/scripts/collections/phonologies.coffee
deleted file mode 100644
index 26e3926..0000000
--- a/app/scripts/collections/phonologies.coffee
+++ /dev/null
@@ -1,15 +0,0 @@
-define [
- './resources'
- './../models/phonology'
-], (ResourcesCollection, PhonologyModel) ->
-
- # Phonollogies Collection
- # -----------------------
- #
- # Holds models for phonologies.
-
- class PhonologiesCollection extends ResourcesCollection
-
- resourceName: 'phonology'
- model: PhonologyModel
-
diff --git a/app/scripts/collections/resources.coffee b/app/scripts/collections/resources.coffee
deleted file mode 100644
index 0302724..0000000
--- a/app/scripts/collections/resources.coffee
+++ /dev/null
@@ -1,299 +0,0 @@
-define [
- 'backbone',
- './../models/resource'
- './../utils/utils'
- './../utils/globals'
-], (Backbone, ResourceModel, utils, globals) ->
-
- # Resources Collection
- # ---------------------
- #
- # Holds models for resources. Houses code for fetching (GET), adding (POST),
- # and updating (PUT) arbitrary resources from an OLD RESTful web service.
- #
- # This is intended to be a base class for other collections, e.g.,
- # PhonologiesCollection. The minimum work required for subclassing is
- # to override `@resourceName` and `@model`.
- #
- # TODO: make this code work for FieldDB web services (if applicable).
-
- class ResourcesCollection extends Backbone.Collection
-
- # Override these two attributes in subclasses.
- resourceName: 'resource'
- model: ResourceModel
-
- # If this is non-null, it is expected to be an object with a `query`
- # attribute and a `paginator` attribute. The presence of such an attribute
- # will change how `fetchResources` behaves.
- search: null
-
- # If this is non-null, it is expected to be a(n OLD-style) corpus model.
- # The presence of such an attribute will change how `fetchResources`
- # behaves.
- corpus: null
-
- initialize: (models, options) ->
- @utils = utils
- @resourceNameCapitalized = utils.capitalize @resourceName
- @resourceNamePlural = utils.pluralize @resourceName
- @resourceNamePluralCapitalized = utils.capitalize @resourceNamePlural
- super models, options
-
- url: 'fake-url'
-
- ############################################################################
- # FETCH.
- ############################################################################
-
- # Fetch Resources (with pagination, if needed)
- # OLD case: GET `/?page=x&items_per_page=y
- # FieldDB case:
- # See http://online-linguistic-database.readthedocs.org/en/latest/interface.html#get-resources
- fetchResources: (options) ->
- @trigger "fetch#{@resourceNamePluralCapitalized}Start"
- @model.cors.request(
- method: @getResourcesHTTPMethod()
- url: @getResourcesPaginationURL options
- payload: @getResourcesPayload options
- onload: (responseJSON) =>
- @fetchResourcesOnloadHandler responseJSON
- onerror: (responseJSON) =>
- @trigger "fetch#{@resourceNamePluralCapitalized}End"
- @trigger "fetch#{@resourceNamePluralCapitalized}Fail",
- "error in fetching #{@getServerSideResourceName()}"
- console.log "Error in GET request to /#{@getServerSideResourceName()}"
- )
-
- getResourcesHTTPMethod: ->
- if @search or @corpus then 'SEARCH' else 'GET'
-
- # Return a payload for the `fetchResources` request. Note: there is only a
- # payload if we have a truthy `@search` attribute, which means the fetching
- # is based on a search and uses a SEARCH (non-standard) HTTP method with a
- # payload describing the search (and pagination, and ordering).
- getResourcesPayload: (options) ->
- if @search or @corpus
- if @corpus
- search =
- filter: ["Form", "corpora", "id", "in", [@corpus.get('id')]]
- order_by: ["Form", "id", "desc" ]
- else
- search = @search
- if options.page and options.itemsPerPage
- query: search
- paginator:
- page: options.page
- items_per_page: options.itemsPerPage
- else
- query: search
- else
- null
-
- # Method to handle the `onload` event of a CORS request to fetch a
- # collection of resources from a server. The default behaviour currently
- # expects an OLD backend. See `collections/forms.coffee` for a FieldDB
- # override/fork.
- fetchResourcesOnloadHandler: (responseJSON) ->
- @trigger "fetch#{@resourceNamePluralCapitalized}End"
- if 'items' of responseJSON
- @add @getDativeResourceModelsFromOLDObjects(responseJSON.items)
- @trigger "fetch#{@resourceNamePluralCapitalized}Success",
- responseJSON.paginator
- # The OLD returns `[]` if there are no resources. This is
- # inconsistent and should probably be changed OLD-side.
- else if utils.type(responseJSON) is 'array' and
- responseJSON.length is 0
- @trigger "fetch#{@resourceNamePluralCapitalized}Success"
- else
- reason = responseJSON.reason or 'unknown'
- @trigger "fetch#{@resourceNamePluralCapitalized}Fail",
- "failed to fetch all #{@getServerSideResourceName()}; reason:
- #{reason}"
- console.log "GET request to /#{@getServerSideResourceName()} failed; reason:
- #{reason}"
-
-
- ############################################################################
- # CREATE.
- ############################################################################
-
- # Add (create) a resource.
- # POST `/`
- addResource: (resource, options={}) ->
- resource.trigger "add#{@resourceNameCapitalized}Start"
- payload = @getResourceForServerCreate resource
- monitorProgress = options.monitorProgress or false
- progressModel = options.progressModel or null
- @model.cors.request(
- method: 'POST'
- url: @getAddResourceURL resource
- payload: payload
- monitorProgress: monitorProgress
- progressModel: progressModel
- onload: (responseJSON, xhr) =>
- @addResourceOnloadHandler resource, responseJSON, xhr, payload
- onerror: (responseJSON) =>
- resource.trigger "add#{@resourceNameCapitalized}End"
- resource.trigger "add#{@resourceNameCapitalized}Fail",
- responseJSON.error, resource
- console.log "Error in POST request to /#{@getServerSideResourceName()}"
- )
-
- # Method to handle the `onload` event of a CORS request to add a
- # particular resource. The default behaviour currently expects an OLD
- # backend. See `collections/forms.coffee` for a FieldDB override/fork.
- addResourceOnloadHandler: (resource, responseJSON, xhr, payload) ->
- resource.trigger "add#{@resourceNameCapitalized}End"
- if xhr.status is 200
- resource.set responseJSON
- # Remember the values of the "sticky" attributes of the resource that
- # we just added so that subsequent adds will have those values as
- # defaults.
- resourcesSettings = globals.applicationSettings.get('resources')
- resourceSettings = resourcesSettings[@resourceNamePlural]
- if resourceSettings
- resourceSettings.pastValues = {}
- stickyAttributes = resourceSettings.stickyAttributes or []
- for attr in stickyAttributes
- resourceSettings.pastValues[attr] = resource.get(attr)
- globals.applicationSettings.save()
- resource.trigger "add#{@resourceNameCapitalized}Success", resource
- else
- errors = responseJSON.errors or {}
- if utils.type(errors) is 'object'
- # TODO: each of the following 2 lines is needed in different
- # contexts; find solution!
- resource.trigger "add#{@resourceNameCapitalized}Fail", errors.error
- # resource.trigger "add#{@resourceNameCapitalized}Fail", errors
- for attribute, error of errors
- attribute = @errorAttributeTransformer attribute
- resource.trigger "validationError:#{attribute}", error
- else
- resource.trigger "add#{@resourceNameCapitalized}Fail", errors
- attribute = @getAttributeForError errors
- if attribute
- resource.trigger "validationError:#{attribute}", errors
- else
- resource.trigger "validationError:general", errors
- console.log "POST request to /#{@getServerSideResourceName()} failed
- (status not 200) ..."
- console.log errors
-
- # Attempt to match an error string to the resource attribute that caused
- # the error. Return a `null` if not possible. Override this in sub-classes.
- getAttributeForError: (error) -> null
-
-
- ############################################################################
- # UPDATE.
- ############################################################################
-
- # Update a resource.
- # PUT `//`
- updateResource: (resource, options) ->
- resource.trigger "update#{@resourceNameCapitalized}Start"
- payload = @getResourceForServerUpdate resource
- @model.cors.request(
- method: 'PUT'
- url: @getUpdateResourceURL resource
- payload: payload
- onload: (responseJSON, xhr) =>
- @updateResourceOnloadHandler resource, responseJSON, xhr, payload
- onerror: (responseJSON) =>
- resource.trigger "update#{@resourceNameCapitalized}End"
- resource.trigger("update#{@resourceNameCapitalized}Fail",
- responseJSON.error, resource)
- console.log "Error in PUT request to /#{@getServerSideResourceName()}"
- )
-
- # Method to handle the `onload` event of a CORS request to update a
- # particular resource. The default behaviour currently expects an OLD
- # backend. See `collections/forms.coffee` for a FieldDB override/fork.
- updateResourceOnloadHandler: (resource, responseJSON, xhr, payload) ->
- resource.trigger "update#{@resourceNameCapitalized}End"
- if xhr.status is 200
- # We remove the `search` value from the response before we set it; we
- # don't want to assign a new object to this attribute because various
- # views are tied to these (mutable) objects.
- if 'search' of responseJSON then delete responseJSON.search
- resource.set responseJSON
- resource.trigger "update#{@resourceNameCapitalized}Success"
- else
- errors = responseJSON.errors or {}
- error = responseJSON.error
- resource.trigger "update#{@resourceNameCapitalized}Fail", error, resource
- for attribute, error of errors
- attribute = @errorAttributeTransformer attribute
- resource.trigger "validationError:#{attribute}", error
- console.log "PUT request to /#{@getServerSideResourceName()} failed (status
- not 200) ..."
- console.log errors
-
- # This is provided so that we can transform the resource attribute
- # associated with a particular error to another attribute in sub-classes.
- # For instance, when an OLD collection resource is added/updated and its
- # contents contain bad form references, the attribute will be "forms",
- # though from Dative's perspective it should be "contents".
- errorAttributeTransformer: (errorAttribute) ->
- return errorAttribute
-
-
- ############################################################################
- # Helpers
- ############################################################################
-
- getOLDURL: ->
- globals.applicationSettings.get('activeServer').get 'url'
-
- # The default is to just use the plural form of the resource name as the
- # server-side name for the resource; however, this can be overridden with
- # `@serverSideResourceName`, as is necessary with "subcorpora"/"corpora".
- getServerSideResourceName: ->
- @serverSideResourceName or @resourceNamePlural.toLowerCase()
-
- # Return a URL for requesting a page of from an OLD
- # web service. GET parameters control pagination and ordering. See
- # `collections/forms.coffee` for a FieldDB-specific override.
- # Note: other possible parameters: `order_by_model`, `order_by_attribute`,
- # and `order_by_direction`.
- getResourcesPaginationURL: (options={}) ->
- if @search or @corpus
- "#{@getOLDURL()}/#{@getServerSideResourceName()}"
- else if options.page and options.itemsPerPage
- "#{@getOLDURL()}/#{@getServerSideResourceName()}?\
- page=#{options.page}&\
- items_per_page=#{options.itemsPerPage}"
- else
- "#{@getOLDURL()}/#{@getServerSideResourceName()}"
-
- # Return a URL for updating a resource on an OLD web service. See
- # `collections/forms.coffee for a FieldDB-specific override.
- getUpdateResourceURL: (resource) ->
- "#{@getOLDURL()}/#{@getServerSideResourceName()}/#{resource.get 'id'}"
-
- # Return a URL for adding a resource to an OLD web service. See
- # `collections/forms.coffee for a FieldDB-specific override.
- getAddResourceURL: (resource) ->
- "#{@getOLDURL()}/#{@getServerSideResourceName()}"
-
- # Return a representation of `resource` that the server will accept (for a
- # create or update request). See `collections/forms.coffee for a
- # FieldDB-specific override.
- getResourceForServer: (resource) ->
- resource.toOLD()
-
- # Return a representation of `resource` that the server will accept for a
- # create request.
- getResourceForServerCreate: (resource) ->
- @getResourceForServer resource
-
- # Return a representation of `resource` that the server will accept for an
- # update request.
- getResourceForServerUpdate: (resource) ->
- @getResourceForServer resource
-
- # Return an array of `@model` instances built from OLD objects.
- getDativeResourceModelsFromOLDObjects: (responseJSON) ->
- (new @model(o) for o in responseJSON)
-
diff --git a/app/scripts/collections/searches.coffee b/app/scripts/collections/searches.coffee
deleted file mode 100644
index b089b08..0000000
--- a/app/scripts/collections/searches.coffee
+++ /dev/null
@@ -1,17 +0,0 @@
-define [
- './resources'
- './../models/search'
-], (ResourcesCollection, SearchModel) ->
-
- # Searches Collection
- # -----------------------
- #
- # Holds models for searches.
-
- class SearchesCollection extends ResourcesCollection
-
- resourceName: 'search'
- model: SearchModel
-
- serverSideResourceName: 'formsearches'
-
diff --git a/app/scripts/collections/servers.coffee b/app/scripts/collections/servers.coffee
deleted file mode 100644
index 252eca2..0000000
--- a/app/scripts/collections/servers.coffee
+++ /dev/null
@@ -1,18 +0,0 @@
-define [
- 'backbone',
- './../models/server'
- ], (Backbone, ServerModel) ->
-
- # Servers Collection
- # ------------------
-
- class ServersCollection extends Backbone.Collection
-
- model: ServerModel
-
- initialize: ->
- @on 'removeme', @_removeModel
-
- _removeModel: (model) ->
- @remove model
-
diff --git a/app/scripts/collections/sources.coffee b/app/scripts/collections/sources.coffee
deleted file mode 100644
index 7753699..0000000
--- a/app/scripts/collections/sources.coffee
+++ /dev/null
@@ -1,15 +0,0 @@
-define [
- './resources'
- './../models/source'
-], (ResourcesCollection, SourceModel) ->
-
- # Sources Collection
- # ------------------
- #
- # Holds models for sources, i.e., texts referenced by data points.
-
- class SourcesCollection extends ResourcesCollection
-
- resourceName: 'source'
- model: SourceModel
-
diff --git a/app/scripts/collections/speakers.coffee b/app/scripts/collections/speakers.coffee
deleted file mode 100644
index f22f717..0000000
--- a/app/scripts/collections/speakers.coffee
+++ /dev/null
@@ -1,15 +0,0 @@
-define [
- './resources'
- './../models/speaker'
-], (ResourcesCollection, SpeakerModel) ->
-
- # Speakers Collection
- # -------------------
- #
- # Holds models for speakers.
-
- class SpeakersCollection extends ResourcesCollection
-
- resourceName: 'speaker'
- model: SpeakerModel
-
diff --git a/app/scripts/collections/subcorpora.coffee b/app/scripts/collections/subcorpora.coffee
deleted file mode 100644
index 6dd8d8f..0000000
--- a/app/scripts/collections/subcorpora.coffee
+++ /dev/null
@@ -1,19 +0,0 @@
-define [
- './resources'
- './../models/subcorpus'
-], (ResourcesCollection, SubcorpusModel) ->
-
- # Subcorpora Collection
- # -----------------------
- #
- # Holds models for subcorpora.
-
- class SubcorporaCollection extends ResourcesCollection
-
- resourceName: 'subcorpus'
- model: SubcorpusModel
-
- # When requesting from the OLD, we need to request 'corpora', not
- # 'subcorpora', hence this attribute.
- serverSideResourceName: 'corpora'
-
diff --git a/app/scripts/collections/syntactic-categories.coffee b/app/scripts/collections/syntactic-categories.coffee
deleted file mode 100644
index 928e17b..0000000
--- a/app/scripts/collections/syntactic-categories.coffee
+++ /dev/null
@@ -1,15 +0,0 @@
-define [
- './resources'
- './../models/syntactic-category'
-], (ResourcesCollection, SyntacticCategoryModel) ->
-
- # Syntactic Categories Collection
- # -------------------------------
- #
- # Holds models for syntactic categories.
-
- class SyntacticCategoriesCollection extends ResourcesCollection
-
- resourceName: 'syntacticCategory'
- model: SyntacticCategoryModel
-
diff --git a/app/scripts/collections/tags.coffee b/app/scripts/collections/tags.coffee
deleted file mode 100644
index 8bf834f..0000000
--- a/app/scripts/collections/tags.coffee
+++ /dev/null
@@ -1,17 +0,0 @@
-define [
- './resources'
- './../models/tag'
-], (ResourcesCollection, TagModel) ->
-
- # Tags Collection
- # ---------------
- #
- # Holds models for tags.
-
- class TagsCollection extends ResourcesCollection
-
- resourceName: 'tag'
- model: TagModel
-
-
-
diff --git a/app/scripts/collections/users.coffee b/app/scripts/collections/users.coffee
deleted file mode 100644
index e9f3a09..0000000
--- a/app/scripts/collections/users.coffee
+++ /dev/null
@@ -1,24 +0,0 @@
-define [
- './resources'
- './../models/user-old'
-], (ResourcesCollection, UserModel) ->
-
- # Users Collection
- # -----------------------
- #
- # Holds models for users.
-
- class UsersCollection extends ResourcesCollection
-
- resourceName: 'user'
- model: UserModel
-
- # This recognizes an OLD "username-already-taken" error message and returns
- # 'username'.
- getAttributeForError: (error) ->
- regex = /^The (\w+) \w+ is already taken\.$/
- if regex.test error
- 'username'
- else
- null
-
diff --git a/app/scripts/main.coffee b/app/scripts/main.coffee
deleted file mode 100644
index 7d95925..0000000
--- a/app/scripts/main.coffee
+++ /dev/null
@@ -1,78 +0,0 @@
-#/*global require*/
-'use strict'
-
-require.config
-
- shim:
- jquery:
- exports: '$'
- lodash:
- exports: '_'
- # FieldDB:
- # exports: 'FieldDB'
- backbone:
- exports: 'Backbone'
- deps: ['lodash', 'jquery']
- #jqueryui: ['../bower_components/jquery/dist/jquery']
- jqueryui: ['jquery']
- # backboneindexeddb: ['backbone']
- multiselect: ['jquery', 'jqueryui']
- jqueryelastic: ['jquery']
- autosize: ['jquery']
- superfish: ['jquery']
- superclick: ['jquery']
- supersubs: ['jquery']
- backbonerelational: ['backbone']
- backbonelocalstorage: ['backbone']
-
- paths:
- jquery: '../bower_components/jquery/dist/jquery'
- backbone: '../bower_components/backbone/backbone'
- lodash: '../bower_components/lodash/dist/lodash'
- underscore: '../bower_components/lodash/dist/lodash.underscore'
- # backboneindexeddb:
- # '../bower_components/indexeddb-backbonejs-adapter/backbone-indexeddb'
- bootstrap: '../bower_components/sass-bootstrap/dist/js/bootstrap'
- text: '../bower_components/requirejs-text/text'
- jqueryui: '../bower_components/jqueryui/jquery-ui'
- superfish: '../bower_components/superfish/dist/js/superfish'
- superclick: '../bower_components/superclick/dist/js/superclick'
- #superfish: '../bower_components/superfish/dist/js/superfish'
- #superfish: 'jquery-extensions/superfish/dist/js/superfish'
- igt: 'jquery-extensions/igt'
- jqueryuicolors: 'jquery-extensions/jqueryui-colors'
- tagit: 'jquery-extensions/tag-it'
- sfjquimatch: 'jquery-extensions/superfish-jqueryui-match'
- # Supersubs plugin removed in v1.6 of superfish. See
- # https://github.com/joeldbirch/superfish.
- supersubs: '../bower_components/superfish/dist/js/supersubs'
- #supersubs: '../bower_components/superfish/dist/js/supersubs'
- #supersubs: 'jquery-extensions/superfish/dist/js/supersubs'
- multiselect: '../bower_components/multiselect/js/jquery.multi-select'
- jqueryelastic: '../bower_components/jakobmattsson-jquery-elastic/jquery.elastic.source'
- autosize: '../bower_components/autosize/jquery.autosize'
- #betterelastictextarea: '../bower_components/better-elastic-textarea/dist/better-elastic-textarea'
- spin: '../bower_components/spin.js/spin'
- jqueryspin: '../bower_components/spin.js/jquery.spin'
- # FieldDB: '../bower_components/fielddb/fielddb'
- backbonerelational: '../bower_components/backbone-relational/backbone-relational'
- backbonelocalstorage: '../bower_components/backbone.localStorage/backbone.localStorage'
-
-require [
- 'views/app',
- 'routes/router'
- 'multiselect'
- 'jqueryelastic'
- 'jqueryuicolors'
- 'tagit'
- 'jqueryspin'
- ], (AppView, Workspace) ->
- window.debugMode = false
-
- $ ->
- app = new AppView()
- window.onbeforeunload = ->
- app.close()
- window.location.href += window.location.hash
- window.location.reload()
-
diff --git a/app/scripts/models/application-settings.coffee b/app/scripts/models/application-settings.coffee
deleted file mode 100644
index 647de77..0000000
--- a/app/scripts/models/application-settings.coffee
+++ /dev/null
@@ -1,794 +0,0 @@
-define [
- './base'
- './server'
- './parser-task-set'
- './keyboard-preference-set'
- './morphology'
- './language-model'
- './../collections/servers'
- './../utils/utils'
- './../utils/globals'
- # 'FieldDB'
-], (BaseModel, ServerModel, ParserTaskSetModel, KeyboardPreferenceSetModel,
- MorphologyModel, LanguageModelModel, ServersCollection, utils, globals) ->
-
- # Application Settings Model
- # --------------------------
- #
- # Holds Dative's application settings. Persisted in the browser using
- # localStorage.
- #
- # Also contains the authentication logic.
-
- class ApplicationSettingsModel extends BaseModel
-
- modelClassName2model:
- 'MorphologyModel': MorphologyModel
- 'LanguageModelModel': LanguageModelModel
-
- initialize: ->
- @fetch()
- # fieldDBTempApp = new (FieldDB.App)(@get('fieldDBApplication'))
- # fieldDBTempApp.authentication.eventDispatcher = Backbone
- @listenTo Backbone, 'authenticate:login', @authenticate
- @listenTo Backbone, 'authenticate:logout', @logout
- @listenTo Backbone, 'authenticate:register', @register
- @listenTo @, 'change:activeServer', @activeServerChanged
- if @get('activeServer')
- activeServer = @get 'activeServer'
- if activeServer instanceof ServerModel
- @listenTo activeServer, 'change:url', @activeServerURLChanged
- if not Modernizr.localstorage
- throw new Error 'localStorage unavailable in this browser, please upgrade.'
-
- @setVersion()
-
- # set app version from package.json
- setVersion: ->
- if @get('version') is 'da'
- $.ajax
- url: 'package.json',
- type: 'GET'
- dataType: 'json'
- error: (jqXHR, textStatus, errorThrown) ->
- console.log "Ajax request for package.json threw an error:
- #{errorThrown}"
- success: (packageDetails, textStatus, jqXHR) =>
- @set 'version', packageDetails.version
-
- activeServerChanged: ->
- #console.log 'active server has changed says the app settings model'
- if @get('fieldDBApplication')
- @get('fieldDBApplication').website = @get('activeServer').get('website')
- @get('fieldDBApplication').brand = @get('activeServer').get('brand') or
- @get('activeServer').get('userFriendlyServerName')
- @get('fieldDBApplication').brandLowerCase =
- @get('activeServer').get('brandLowerCase') or
- @get('activeServer').get('serverCode')
-
- activeServerURLChanged: ->
- #console.log 'active server URL has changed says the app settings model'
-
- getURL: ->
- url = @get('activeServer')?.get('url')
- if url.slice(-1) is '/' then url.slice(0, -1) else url
-
- getCorpusServerURL: ->
- @get('activeServer')?.get 'corpusUrl'
-
- getServerCode: ->
- @get('activeServer')?.get 'serverCode'
-
- authenticateAttemptDone: (taskId) ->
- Backbone.trigger 'longTask:deregister', taskId
- Backbone.trigger 'authenticate:end'
-
-
- # Login (a.k.a. authenticate)
- #=========================================================================
-
- # Attempt to authenticate with the passed-in credentials
- authenticate: (username, password) ->
- if @get('activeServer')?.get('type') is 'FieldDB'
- @authenticateFieldDBAuthService
- username: username
- password: password
- authUrl: @get('activeServer')?.get('url')
- else
- @authenticateOLD username: username, password: password
-
- authenticateOLD: (credentials) ->
- taskId = @guid()
- Backbone.trigger 'longTask:register', 'authenticating', taskId
- Backbone.trigger 'authenticateStart'
- @constructor.cors.request(
- method: 'POST'
- timeout: 20000
- url: "#{@getURL()}/login/authenticate"
- payload: credentials
- onload: (responseJSON) =>
- @authenticateAttemptDone taskId
- Backbone.trigger 'authenticateEnd'
- if responseJSON.authenticated is true
- @set
- username: credentials.username
- loggedIn: true
- loggedInUser: responseJSON.user
- homepage: responseJSON.homepage
- @save()
- Backbone.trigger 'authenticateSuccess'
- else
- Backbone.trigger 'authenticateFail', responseJSON
- onerror: (responseJSON) =>
- Backbone.trigger 'authenticateEnd'
- Backbone.trigger 'authenticateFail', responseJSON
- @authenticateAttemptDone taskId
- ontimeout: =>
- Backbone.trigger 'authenticateEnd'
- Backbone.trigger 'authenticateFail', error: 'Request timed out'
- @authenticateAttemptDone taskId
- )
-
- authenticateFieldDBAuthService: (credentials) =>
- taskId = @guid()
- Backbone.trigger 'longTask:register', 'authenticating', taskId
- Backbone.trigger 'authenticateStart'
- if not @get 'fieldDBApplication'
- @set 'fieldDBApplication', FieldDB.FieldDBObject.application
- if not @get('fieldDBApplication').authentication or not @get('fieldDBApplication').authentication.login
- @get('fieldDBApplication').authentication = new FieldDB.Authentication()
- @get('fieldDBApplication').authentication.login(credentials).then(
- (promisedResult) =>
- @set
- username: credentials.username,
- password: credentials.password, # TODO dont need this!
- loggedInUser: @get('fieldDBApplication').authentication.user
- @save()
- Backbone.trigger 'authenticateEnd'
- Backbone.trigger 'authenticateSuccess'
- @authenticateAttemptDone taskId
- ,
- (error) =>
- @authenticateAttemptDone taskId
- Backbone.trigger 'authenticateEnd'
- Backbone.trigger 'authenticateFail', responseJSON.userFriendlyErrors
- ).fail (error) =>
- Backbone.trigger 'authenticateEnd'
- Backbone.trigger 'authenticateFail', error: 'Request timed out'
- @authenticateAttemptDone taskId
-
- # This is the to-be-deprecated version that has been made obsolete by
- # `authenticateFieldDBAuthService` above.
- authenticateFieldDBAuthService_: (credentials) =>
- taskId = @guid()
- Backbone.trigger 'longTask:register', 'authenticating', taskId
- Backbone.trigger 'authenticateStart'
- @constructor.cors.request(
- method: 'POST'
- timeout: 20000
- url: "#{@getURL()}/login"
- payload: credentials
- onload: (responseJSON) =>
- if responseJSON.user
- # Remember the corpusServiceURL so we can logout.
- @get('activeServer')?.set(
- 'corpusServerURL', @getFieldDBBaseDBURL(responseJSON.user))
- @set
- baseDBURL: @getFieldDBBaseDBURL(responseJSON.user)
- username: credentials.username,
- password: credentials.password,
- gravatar: responseJSON.user.gravatar,
- loggedInUser: responseJSON.user
- @save()
- credentials.name = credentials.username
- @authenticateFieldDBCorpusService credentials, taskId
- else
- Backbone.trigger 'authenticateFail', responseJSON.userFriendlyErrors
- @authenticateAttemptDone taskId
- onerror: (responseJSON) =>
- Backbone.trigger 'authenticateEnd'
- Backbone.trigger 'authenticateFail', responseJSON
- @authenticateAttemptDone taskId
- ontimeout: =>
- Backbone.trigger 'authenticateEnd'
- Backbone.trigger 'authenticateFail', error: 'Request timed out'
- @authenticateAttemptDone taskId
- )
-
- authenticateFieldDBCorpusService: (credentials, taskId) ->
- @constructor.cors.request(
- method: 'POST'
- timeout: 3000
- url: "#{@get('baseDBURL')}/_session"
- payload: credentials
- onload: (responseJSON) =>
- # TODO @jrwdunham: this responseJSON has a roles Array attribute which
- # references more corpora than I'm seeing from the `corpusteam`
- # request. Why the discrepancy?
- Backbone.trigger 'authenticateEnd'
- @authenticateAttemptDone taskId
- if responseJSON.ok
- @set
- loggedIn: true
- loggedInUserRoles: responseJSON.roles
- @save()
- Backbone.trigger 'authenticateSuccess'
- else
- Backbone.trigger 'authenticateFail', responseJSON
- onerror: (responseJSON) =>
- Backbone.trigger 'authenticateEnd'
- Backbone.trigger 'authenticateFail', responseJSON
- @authenticateAttemptDone taskId
- ontimeout: =>
- Backbone.trigger 'authenticateEnd'
- Backbone.trigger 'authenticateFail', error: 'Request timed out'
- @authenticateAttemptDone taskId
- )
-
- localStorageKey: 'dativeApplicationSettings'
-
- # An extremely simple re-implementation of `save`: we just JSON-ify the app
- # settings and store them in localStorage.
- save: ->
- localStorage.setItem @localStorageKey,
- JSON.stringify(@attributes)
-
- # Fetching means simply getting the app settings JSON object from
- # localStorage and setting it to the present model. Certain attributes are
- # evaluated to other Backbone models; handling this conversion is the job
- # of `backbonify`.
- fetch: (options) ->
- if localStorage.getItem @localStorageKey
- applicationSettingsObject =
- JSON.parse(localStorage.getItem(@localStorageKey))
- applicationSettingsObject = @fix applicationSettingsObject
- applicationSettingsObject = @backbonify applicationSettingsObject
- @set applicationSettingsObject
- @usingDefaults = false
- else
- @usingDefaults = true
- @save()
-
- # Fix the application settings, if necessary. This is necessary when Dative
- # has been updated but the user's application settings object, as persisted
- # in their `localStorage`, was built using an older version of Dative. If
- # the app settings are out-of-date, then Dative may break.
- # Note: `aso` is the Application Settings Object.
- # The `ns` (namespace) param is good for debugging.
- fix: (aso, defaults=null, ns='') ->
- defaults = defaults or @defaults()
- if 'attributes' of defaults
- defaults = defaults.attributes
- for attr, defval of defaults
- if attr not of aso
- aso[attr] = defval
- # Recursively call `@fix` if the default val is an object.
- else if ((@utils.type(defval) == 'object') and
- not ((defval instanceof Backbone.Model) or
- (defval instanceof Backbone.Collection)))
- aso[attr] = @fix aso[attr], defval, "#{ns}.#{attr}"
- for attr of aso
- if attr not of defaults
- delete aso[attr]
- return aso
-
- # Logout
- #=========================================================================
-
- logout: ->
- if @get('activeServer')?.get('type') is 'FieldDB'
- @logoutFieldDB()
- else
- @logoutOLD()
-
- logoutOLD: ->
- taskId = @guid()
- Backbone.trigger 'longTask:register', 'logout', taskId
- Backbone.trigger 'logoutStart'
- @constructor.cors.request(
- url: "#{@getURL()}/login/logout"
- method: 'GET'
- timeout: 3000
- onload: (responseJSON, xhr) =>
- @authenticateAttemptDone taskId
- Backbone.trigger 'logoutEnd'
- if responseJSON.authenticated is false or
- (xhr.status is 401 and
- responseJSON.error is "Authentication is required to access this
- resource.")
- @set loggedIn: false, homepage: null
- @save()
- Backbone.trigger 'logoutSuccess'
- else
- Backbone.trigger 'logoutFail'
- onerror: (responseJSON) =>
- Backbone.trigger 'logoutEnd'
- @authenticateAttemptDone taskId
- Backbone.trigger 'logoutFail'
- ontimeout: =>
- Backbone.trigger 'logoutEnd'
- @authenticateAttemptDone taskId
- Backbone.trigger 'logoutFail', error: 'Request timed out'
- )
-
- logoutFieldDB: ->
- taskId = @guid()
- Backbone.trigger 'longTask:register', 'logout', taskId
- Backbone.trigger 'logoutStart'
- if not @get 'fieldDBApplication'
- @set 'fieldDBApplication', FieldDB.FieldDBObject.application
- # TODO: @cesine: I'm getting "`authentication.logout` is not a function"
- # errors here ...
- @get('fieldDBApplication').authentication
- .logout({letClientHandleCleanUp: 'dontReloadWeNeedToCleanUpInDativeClient'})
- .then(
- (responseJSON) =>
- @set
- fieldDBApplication: null
- loggedIn: false
- activeFieldDBCorpus: null
- activeFieldDBCorpusTitle: null
- @save()
- Backbone.trigger 'logoutSuccess'
- ,
- (reason) ->
- Backbone.trigger 'logoutFail', reason.userFriendlyErrors.join ' '
- ).done(
- =>
- Backbone.trigger 'logoutEnd'
- @authenticateAttemptDone taskId
- )
-
- # Check if logged in
- #=========================================================================
-
- # Check if we are already logged in.
- checkIfLoggedIn: ->
- if @get('activeServer')?.get('type') is 'FieldDB'
- @checkIfLoggedInFieldDB()
- else
- @checkIfLoggedInOLD()
-
- # Check with the OLD if we are logged in. We ask for the speakers. and
- # trigger 'authenticateFail' if we can't get them.
- checkIfLoggedInOLD: ->
- taskId = @guid()
- Backbone.trigger('longTask:register', 'checking if already logged in',
- taskId)
- @constructor.cors.request(
- url: "#{@getURL()}/speakers"
- timeout: 3000
- onload: (responseJSON) =>
- @authenticateAttemptDone(taskId)
- if utils.type(responseJSON) is 'array'
- @set 'loggedIn', true
- @save()
- Backbone.trigger 'authenticateSuccess'
- else
- @set 'loggedIn', false
- @save()
- Backbone.trigger 'authenticateFail'
- onerror: (responseJSON) =>
- @set 'loggedIn', false
- @save()
- Backbone.trigger 'authenticateFail', responseJSON
- @authenticateAttemptDone(taskId)
- ontimeout: =>
- @set 'loggedIn', false
- @save()
- Backbone.trigger 'authenticateFail', error: 'Request timed out'
- @authenticateAttemptDone(taskId)
- )
-
- checkIfLoggedInFieldDB: ->
- taskId = @guid()
- Backbone.trigger('longTask:register', 'checking if already logged in',
- taskId)
- FieldDB.Database::resumeAuthenticationSession().then(
- (sessionInfo) =>
- if sessionInfo.ok and sessionInfo.userCtx.name
- @set 'loggedIn', true
- @save()
- Backbone.trigger 'authenticateSuccess'
- else
- @set 'loggedIn', false
- @save()
- Backbone.trigger 'authenticateFail'
- ,
- (reason) =>
- @set 'loggedIn', false
- @save()
- Backbone.trigger 'authenticateFail', reason
- ).done(=> @authenticateAttemptDone taskId)
-
-
- # Register a new user
- # =========================================================================
-
- # `RegisterDialogView` should never allow an OLD registration attempt.
- register: (params) ->
- if @get('activeServer')?.get('type') is 'FieldDB'
- @registerFieldDB params
-
- registerFieldDB: (params) ->
- taskId = @guid()
- Backbone.trigger 'longTask:register', 'registering a new user', taskId
- params.authUrl = @getURL()
- params.appVersionWhenCreated = "v#{@get('version')}da"
- @constructor.cors.request(
- url: "#{@getURL()}/register"
- payload: params
- method: 'POST'
- timeout: 10000 # FieldDB auth can take some time to register a new user ...
- onload: (responseJSON) =>
- @authenticateAttemptDone taskId
- # TODO @cesine: what other kinds of responses to registration requests
- # can the auth service make?
- if responseJSON.user?
- user = responseJSON.user
- Backbone.trigger 'register:success', responseJSON
- else
- Backbone.trigger 'register:fail', responseJSON.userFriendlyErrors
- onerror: (responseJSON) =>
- @authenticateAttemptDone taskId
- Backbone.trigger 'register:fail', 'server responded with error'
- ontimeout: =>
- @authenticateAttemptDone taskId
- Backbone.trigger 'register:fail', 'Request timed out'
- )
-
-
- idAttribute: 'id'
-
- # Transform certain attribute values of the `appSetObj`
- # object into Backbone collections/models and return the `appSetObj`.
- backbonify: (appSetObj) ->
-
- serverModelsArray = ((new ServerModel(s)) for s in appSetObj.servers)
- appSetObj.servers = new ServersCollection(serverModelsArray)
- activeServer = appSetObj.activeServer
- if activeServer
- appSetObj.activeServer = appSetObj.servers.get activeServer.id
-
- longRunningTasks = appSetObj.longRunningTasks
- for task in appSetObj.longRunningTasks
- task.resourceModel =
- new @modelClassName2model[task.modelClassName](task.resourceModel)
- for task in appSetObj.longRunningTasksTerminated
- task.resourceModel =
- new @modelClassName2model[task.modelClassName](task.resourceModel)
-
- appSetObj.parserTaskSet = new ParserTaskSetModel(appSetObj.parserTaskSet)
-
- appSetObj.keyboardPreferenceSet =
- new KeyboardPreferenceSetModel(appSetObj.keyboardPreferenceSet)
-
- appSetObj
-
- ############################################################################
- # Defaults
- ############################################################################
-
- defaults: ->
-
- # Default servers are provided at runtime using servers.json
- server =
- new ServerModel
- id: @guid()
- name: 'OLD Local Development'
- type: 'OLD'
- url: 'http://127.0.0.1:5000'
- serverCode: null
- corpusServerURL: null
- website: 'http://www.onlinelinguisticdatabase.org'
-
- servers = new ServersCollection([server])
-
- parserTaskSetModel = new ParserTaskSetModel()
-
- keyboardPreferenceSetModel = new KeyboardPreferenceSetModel()
-
- id: @guid()
- activeServer: servers.at 0
- loggedIn: false
- loggedInUser: null
- loggedInUserRoles: []
-
- # An OLD will send an object representing the home page when a user
- # successfully logs in, if there is such a page named 'home'.
- homepage: null
-
- baseDBURL: null
- username: ''
-
- # This gets set to `true` as soon as the user makes modifications to the
- # list of servers. This allows us to avoid over-writing the
- # user-specified servers with those supplied by Dative in servers.json.
- serversModified: false
-
- # This contains the array of objects contstituting the last set of
- # servers that Dative has sent us. We use this to decide whether to
- # prompt/annoy the user to merge these servers into their own.
- lastSeenServersFromDative: null
-
- servers: servers
- # serverTypes: ['FieldDB', 'OLD']
- serverTypes: ['OLD']
- fieldDBServerCodes: [
- 'localhost'
- 'testing'
- 'beta'
- 'production'
- 'mcgill'
- 'concordia'
- 'dyslexdisorth'
- ]
-
- # TODO: remove the activeFieldDBCorpusTitle and related attributes. We
- # should simply store a real `CorpusModel` as the value of
- # `activeFieldDBCorpus`. Note that `AppView` adds
- # `activeFieldDBCorpusModel` and stores a Backbone model there. This all
- # needs to be cleaned up.
- activeFieldDBCorpus: null
- activeFieldDBCorpusTitle: null
-
- languagesDisplaySettings:
- itemsPerPage: 100
- dataLabelsVisible: true
- allFormsExpanded: false
-
- formsDisplaySettings:
- itemsPerPage: 10
- dataLabelsVisible: false
- allFormsExpanded: false
-
- subcorporaDisplaySettings:
- itemsPerPage: 10
- dataLabelsVisible: true
- allSubcorporaExpanded: false
-
- phonologiesDisplaySettings:
- itemsPerPage: 1
- dataLabelsVisible: true
- allPhonologiesExpanded: false
-
- morphologiesDisplaySettings:
- itemsPerPage: 1
- dataLabelsVisible: true
- allMorphologiesExpanded: false
-
- activeJQueryUITheme: 'pepper-grinder'
- defaultJQueryUITheme: 'pepper-grinder'
- jQueryUIThemes: [
- ['ui-lightness', 'UI lightness']
- ['ui-darkness', 'UI darkness']
- ['smoothness', 'Smoothness']
- ['start', 'Start']
- ['redmond', 'Redmond']
- ['sunny', 'Sunny']
- ['overcast', 'Overcast']
- ['le-frog', 'Le Frog']
- ['flick', 'Flick']
- ['pepper-grinder', 'Pepper Grinder']
- ['eggplant', 'Eggplant']
- ['dark-hive', 'Dark Hive']
- ['cupertino', 'Cupertino']
- ['south-street', 'South Street']
- ['blitzer', 'Blitzer']
- ['humanity', 'Humanity']
- ['hot-sneaks', 'Hot Sneaks']
- ['excite-bike', 'Excite Bike']
- ['vader', 'Vader']
- ['dot-luv', 'Dot Luv']
- ['mint-choc', 'Mint Choc']
- ['black-tie', 'Black Tie']
- ['trontastic', 'Trontastic']
- ['swanky-purse', 'Swanky Purse']
- ]
-
- # Use this to limit how many "long-running" tasks can be initiated from
- # within the app. A "long-running task" is a request to the server that
- # requires polling to know when it has terminated, e.g., phonology
- # compilation, morphology generation and compilation, etc.
- # NOTE !IMPORTANT: the OLD has a single foma worker and all requests to
- # compile FST-based resources appear to enter into a queue. This means
- # that a 3s request made while a 1h request is ongoing will take 1h1s!
- # Not good ...
- longRunningTasksMax: 2
-
- # An array of objects with keys `resourceName`, `taskName`,
- # `taskStartTimestamp`, and `taskPreviousUUID`.
- longRunningTasks: []
-
- # An array of objects with keys `resourceName`, `taskName`,
- # `taskStartTimestamp`, and `taskPreviousUUID`.
- longRunningTasksTerminated: []
-
- # IME types that can be uploaded (to an OLD server, at least).
- # TODO: this should be expanded and/or made backend-specific.
- allowedFileTypes: [
- 'application/pdf'
- 'image/gif'
- 'image/jpeg'
- 'image/png'
- 'audio/mpeg'
- 'audio/mp3'
- 'audio/ogg'
- 'audio/x-wav'
- 'audio/wav'
- 'video/mpeg'
- 'video/mp4'
- 'video/ogg'
- 'video/quicktime'
- 'video/x-ms-wmv'
- ]
-
- version: 'da'
-
- parserTaskSet: parserTaskSetModel
-
- keyboardPreferenceSet: keyboardPreferenceSetModel
-
- # This object contains metadata about Dative resources, i.e., forms,
- # files, etc.
- # TODO: resource display settings (e.g., `formsDisplaySettings` above)
- # should be migrated here.
- resources:
-
- forms:
-
- # Array of form attributes that are "sticky", i.e., that will stick
- # around and whose values in the most recent add request will be the
- # defaults for subsequent add requests.
- stickyAttributes: []
-
- # Array of form attributes that *may* be specified as "sticky".
- possiblyStickyAttributes: [
- 'date_elicited'
- 'elicitation_method'
- 'elicitor'
- 'source'
- 'speaker'
- 'status'
- 'syntactic_category'
- 'tags'
- ]
-
- # This will be populated by the resources collection upon successful
- # add requests. It will map attribute names in `stickyAttributes`
- # above to their values in the most recent successful add request.
- pastValues: {}
-
- # These objects define metadata on the fields of form resources.
- # Note that there are separate metadata objects for OLD fields and
- # for FieldDB fields.
- fieldsMeta:
-
- OLD:
-
- grammaticality: [
- 'grammaticality'
- ]
-
- # IGT OLD Form Attributes.
- igt: [
- 'narrow_phonetic_transcription'
- 'phonetic_transcription'
- 'transcription'
- 'morpheme_break'
- 'morpheme_gloss'
- ]
-
- # Note: this is currently not being used (just being consistent
- # with the FieldDB `fieldsMeta` object below)
- translation: [
- 'translations'
- ]
-
- # Secondary OLD Form Attributes.
- secondary: [
- 'syntactic_category_string'
- 'break_gloss_category'
- 'comments'
- 'speaker_comments'
- 'elicitation_method'
- 'tags'
- 'syntactic_category'
- 'date_elicited'
- 'speaker'
- 'elicitor'
- 'enterer'
- 'datetime_entered'
- 'modifier'
- 'datetime_modified'
- 'verifier'
- 'source'
- 'files'
- #'collections' # Does the OLD provide the collections when the forms resource is fetched?
- 'syntax'
- 'semantics'
- 'status'
- 'UUID'
- 'id'
- ]
-
- readonly: [
- 'syntactic_category_string'
- 'break_gloss_category'
- 'enterer'
- 'datetime_entered'
- 'modifier'
- 'datetime_modified'
- 'UUID'
- 'id'
- ]
-
- # This array may contain the names of OLD form attributes that should
- # be hidden. This is the (for now only client-side-stored) data
- # structure that users manipulate in the settings widget of a
- # `FormView` instance.
- hidden: [
- 'narrow_phonetic_transcription'
- 'phonetic_transcription'
- 'verifier'
- ]
-
- FieldDB:
-
- # This is the set of form attributes that are considered by
- # Dative to denote grammaticalities.
- grammaticality: [
- 'judgement'
- ]
-
- # IGT FieldDB form attributes.
- # The returned array defines the "IGT" attributes of a FieldDB
- # form (along with their order). These are those that are aligned
- # into columns of one word each when displayed in an IGT view.
- igt: [
- 'utterance'
- 'morphemes'
- 'gloss'
- ]
-
- # This is the set of form attributes that are considered by
- # Dative to denote a translation.
- translation: [
- 'translation'
- ]
-
- # Secondary FieldDB form attributes.
- # The returned array defines the order of how the secondary
- # attributes are displayed. It is defined in
- # models/application-settings because it should ultimately be
- # user-configurable.
- # QUESTION: @cesine: how is the elicitor of a FieldDB
- # datum/session documented?
- # TODO: `audioVideo`, `images`
- secondary: [
- 'syntacticCategory'
- 'comments'
- 'tags'
- 'dateElicited' # session field
- 'language' # session field
- 'dialect' # session field
- 'consultants' # session field
- 'enteredByUser'
- 'dateEntered'
- 'modifiedByUser'
- 'dateModified'
- 'syntacticTreeLatex'
- 'validationStatus'
- 'timestamp' # make this visible?
- 'id'
- ]
-
- # These read-only fields will not be given input fields in
- # add/update interfaces.
- readonly: [
- 'enteredByUser'
- 'dateEntered'
- 'modifiedByUser'
- 'dateModified'
- ]
-
diff --git a/app/scripts/models/base-relational.coffee b/app/scripts/models/base-relational.coffee
deleted file mode 100644
index 2072ca8..0000000
--- a/app/scripts/models/base-relational.coffee
+++ /dev/null
@@ -1,18 +0,0 @@
-define [
- 'backbone'
- './../utils/cors'
- './../utils/utils'
- 'backbonerelational'
-], (Backbone, CORS, utils) ->
-
- # Base Relational Model
- # ---------------------
- #
- # Functionality that all relational models and collections need.
-
- class BaseRelationalModel extends Backbone.RelationalModel
-
- guid: utils.guid
- @cors: new CORS()
- utils: utils
-
diff --git a/app/scripts/models/base.coffee b/app/scripts/models/base.coffee
deleted file mode 100644
index 2019c81..0000000
--- a/app/scripts/models/base.coffee
+++ /dev/null
@@ -1,20 +0,0 @@
-define [
- 'backbone'
- './../utils/cors'
- './../utils/utils'
-], (Backbone, CORS, utils) ->
-
- # Base Model
- # ----------
- #
- # Functionality that all models and collections need.
-
- class BaseModel extends Backbone.Model
-
- guid: utils.guid
- @cors: new CORS()
- utils: utils
-
- requiredString: (value) ->
- if value?.trim?() in ['', undefined] then 'Please enter a value' else null
-
diff --git a/app/scripts/models/collection.coffee b/app/scripts/models/collection.coffee
deleted file mode 100644
index 8c0b315..0000000
--- a/app/scripts/models/collection.coffee
+++ /dev/null
@@ -1,117 +0,0 @@
-define ['./resource'], (ResourceModel) ->
-
- # Collection Model
- # ----------------
- #
- # A Backbone model for Dative collections, i.e., the text-like objects of the
- # OLD.
-
- class CollectionModel extends ResourceModel
-
- resourceName: 'collection'
-
- ############################################################################
- # Collection Schema
- ############################################################################
- #
- # Note: the OLD also returns `contents_unpacked`. This is a version of the
- # `contents` value where all collection-embedding directives are replaced
- # by the `contents` value of the referenced collection. Dative may at some
- # point need to make use of this `contents_unpacked` value.
-
- defaults: ->
- title: '' # Required, unique among collection
- # names, max 255 chars.
- description: '' # description of the collection.
- type: '' # max 255 chars.
- url: '' # max 255 chars.
- markup_language: '' # One of "Markdown" or "reStructuredText",
- # defaults to "reStructuredText".
- contents: '' # a string of lightweight markup that also
- # contains references to forms. This defines the
- # collection.
- html: '' # HTML generated from the user-supplied markup.
- source: null #