first steps to ember-cli
This commit is contained in:
parent
5243b6c046
commit
7a241bd311
94 changed files with 444 additions and 1547 deletions
3
.bowerrc
3
.bowerrc
|
@ -1,3 +1,4 @@
|
||||||
{
|
{
|
||||||
"directory": "vendor"
|
"directory": "bower_components",
|
||||||
|
"analytics": false
|
||||||
}
|
}
|
||||||
|
|
33
.editorconfig
Normal file
33
.editorconfig
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
# EditorConfig helps developers define and maintain consistent
|
||||||
|
# coding styles between different editors and IDEs
|
||||||
|
# editorconfig.org
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
|
||||||
|
[*]
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[*.js]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[*.hbs]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[*.css]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[*.html]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
9
.ember-cli
Normal file
9
.ember-cli
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
Ember CLI sends analytics information by default. The data is completely
|
||||||
|
anonymous, but there are times when you might want to disable this behavior.
|
||||||
|
|
||||||
|
Setting `disableAnalytics` to true will prevent any data from being sent.
|
||||||
|
*/
|
||||||
|
"disableAnalytics": false
|
||||||
|
}
|
11
.gitignore
vendored
11
.gitignore
vendored
|
@ -3,18 +3,15 @@
|
||||||
# compiled output
|
# compiled output
|
||||||
/dist
|
/dist
|
||||||
/tmp
|
/tmp
|
||||||
/docs
|
|
||||||
|
|
||||||
# dependencies
|
# dependencies
|
||||||
/node_modules
|
/node_modules
|
||||||
/vendor/*
|
/bower_components
|
||||||
!/vendor/ember-shim.js
|
|
||||||
!/vendor/qunit-shim.js
|
|
||||||
|
|
||||||
# misc
|
# misc
|
||||||
/.sass-cache
|
/.sass-cache
|
||||||
/connect.lock
|
/connect.lock
|
||||||
/libpeerconnection.log
|
|
||||||
.DS_Store
|
|
||||||
Thumbs.db
|
|
||||||
/coverage/*
|
/coverage/*
|
||||||
|
/libpeerconnection.log
|
||||||
|
npm-debug.log
|
||||||
|
testem.log
|
||||||
|
|
27
.jshintrc
27
.jshintrc
|
@ -1,22 +1,14 @@
|
||||||
{
|
{
|
||||||
"predef": {
|
"predef": [
|
||||||
"document": true,
|
"document",
|
||||||
"window": true,
|
"window",
|
||||||
"location": true,
|
"-Promise"
|
||||||
"setTimeout": true,
|
],
|
||||||
"Ember": true,
|
"browser" : true,
|
||||||
"Em": true,
|
|
||||||
"DS": true,
|
|
||||||
"$": true,
|
|
||||||
"moment": true,
|
|
||||||
"sjcl": true
|
|
||||||
},
|
|
||||||
"node" : false,
|
|
||||||
"browser" : false,
|
|
||||||
"boss" : true,
|
"boss" : true,
|
||||||
"curly": false,
|
"curly": true,
|
||||||
"debug": false,
|
"debug": false,
|
||||||
"devel": false,
|
"devel": true,
|
||||||
"eqeqeq": true,
|
"eqeqeq": true,
|
||||||
"evil": true,
|
"evil": true,
|
||||||
"forin": false,
|
"forin": false,
|
||||||
|
@ -35,5 +27,6 @@
|
||||||
"strict": false,
|
"strict": false,
|
||||||
"white": false,
|
"white": false,
|
||||||
"eqnull": true,
|
"eqnull": true,
|
||||||
"esnext": true
|
"esnext": true,
|
||||||
|
"unused": true
|
||||||
}
|
}
|
||||||
|
|
17
.travis.yml
17
.travis.yml
|
@ -1,7 +1,16 @@
|
||||||
|
---
|
||||||
language: node_js
|
language: node_js
|
||||||
node_js:
|
|
||||||
- 0.10
|
sudo: false
|
||||||
before_script:
|
|
||||||
- npm install -g grunt-cli
|
cache:
|
||||||
|
directories:
|
||||||
|
- node_modules
|
||||||
|
|
||||||
|
install:
|
||||||
- npm install -g bower
|
- npm install -g bower
|
||||||
|
- npm install
|
||||||
- bower install
|
- bower install
|
||||||
|
|
||||||
|
script:
|
||||||
|
- npm test
|
||||||
|
|
56
Brocfile.js
Normal file
56
Brocfile.js
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
/* global require, module */
|
||||||
|
|
||||||
|
var EmberApp = require('ember-cli/lib/broccoli/ember-app');
|
||||||
|
|
||||||
|
var app = new EmberApp();
|
||||||
|
|
||||||
|
// Use `app.import` to add additional libraries to the generated
|
||||||
|
// output files.
|
||||||
|
//
|
||||||
|
// If you need to use different assets in different
|
||||||
|
// environments, specify an object as the first parameter. That
|
||||||
|
// object's keys should be the environment name and the values
|
||||||
|
// should be the asset to use in that environment.
|
||||||
|
//
|
||||||
|
// If the library that you are including contains AMD or ES6
|
||||||
|
// modules that you would like to import into your application
|
||||||
|
// please specify an object with the list of modules as keys
|
||||||
|
// along with the exports of each module as its value.
|
||||||
|
|
||||||
|
app.import({
|
||||||
|
development: 'bower_components/moment/min/moment-with-locales.js',
|
||||||
|
production: 'bower_components/momemt/min/moment-with-locales.min.js'
|
||||||
|
});
|
||||||
|
|
||||||
|
app.import({
|
||||||
|
development: 'bower_components/bootstrap/dist/js/bootstrap.js',
|
||||||
|
production: 'bower_components/bootstrap/dist/js/bootstrap.min.js'
|
||||||
|
});
|
||||||
|
|
||||||
|
app.import('bower_components/bootstrap-datepicker/js/bootstrap-datepicker.js');
|
||||||
|
|
||||||
|
app.import('bower_components/ember-easyForm/index.js');
|
||||||
|
|
||||||
|
app.import('bower_components/cldr/plurals.js');
|
||||||
|
|
||||||
|
app.import('bower_components/ember-i18n/lib/i18n.js');
|
||||||
|
app.import('bower_components/ember-i18n/lib/i18n-plurals.js');
|
||||||
|
|
||||||
|
app.import({
|
||||||
|
development: 'bower_components/floatThead/dist/jquery.floatThead.js',
|
||||||
|
production: 'bower_components/floatThead/dist/jquery.floatThead.min.js'
|
||||||
|
});
|
||||||
|
|
||||||
|
app.import({
|
||||||
|
development: 'bower_components/webshim/js-webshim/dev/polyfiller.js',
|
||||||
|
production: 'bower_components/webshim/js-webshim/minified/polyfiller.js'
|
||||||
|
});
|
||||||
|
|
||||||
|
app.import('bower_components/ember-validations/index.js');
|
||||||
|
|
||||||
|
app.import('bower_components/sjcl/sjcl.js');
|
||||||
|
|
||||||
|
app.import('bower_components/modernizr/modernizr.js');
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = app.toTree();
|
256
Gruntfile.js
256
Gruntfile.js
|
@ -1,256 +0,0 @@
|
||||||
// jshint node:true
|
|
||||||
|
|
||||||
module.exports = function(grunt) {
|
|
||||||
// To support Coffeescript, SASS, LESS and others, just install
|
|
||||||
// the appropriate grunt package and it will be automatically included
|
|
||||||
// in the build process:
|
|
||||||
//
|
|
||||||
// * for Coffeescript, run `npm install --save-dev grunt-contrib-coffee`
|
|
||||||
//
|
|
||||||
// * for SCSS (without SASS), run `npm install --save-dev grunt-sass`
|
|
||||||
// * for SCSS/SASS support (may be slower), run
|
|
||||||
// `npm install --save-dev grunt-contrib-sass`
|
|
||||||
// This depends on the ruby sass gem, which can be installed with
|
|
||||||
// `gem install sass`
|
|
||||||
// * for Compass, run `npm install --save-dev grunt-contrib-compass`
|
|
||||||
// This depends on the ruby compass gem, which can be installed with
|
|
||||||
// `gem install compass`
|
|
||||||
// You should not install SASS if you have installed Compass.
|
|
||||||
//
|
|
||||||
// * for LESS, run `npm install --save-dev grunt-contrib-less`
|
|
||||||
//
|
|
||||||
// * for Stylus/Nib, `npm install --save-dev grunt-contrib-stylus`
|
|
||||||
//
|
|
||||||
// * for Emblem, run the following commands:
|
|
||||||
// `npm uninstall --save-dev grunt-ember-templates`
|
|
||||||
// `npm install --save-dev grunt-emblem`
|
|
||||||
// `bower install emblem.js --save`
|
|
||||||
//
|
|
||||||
// * For EmberScript, run `npm install --save-dev grunt-ember-script`
|
|
||||||
//
|
|
||||||
// * for LiveReload, `npm install --save-dev connect-livereload`
|
|
||||||
//
|
|
||||||
// * for YUIDoc support, `npm install --save-dev grunt-contrib-yuidoc`
|
|
||||||
// It is also nice to use a theme other than default. For example,
|
|
||||||
// simply do: `npm install yuidoc-theme-blue`
|
|
||||||
// Currently, only the `app` directory is used for generating docs.
|
|
||||||
// When installed, visit: http[s]://[host:port]/docs
|
|
||||||
//
|
|
||||||
// * for displaying the execution time of the grunt tasks,
|
|
||||||
// `npm install --save-dev time-grunt`
|
|
||||||
//
|
|
||||||
// * for minimizing the index.html at the end of the dist task
|
|
||||||
// `npm install --save-dev grunt-contrib-htmlmin`
|
|
||||||
//
|
|
||||||
// * for minimizing images in the dist task
|
|
||||||
// `npm install --save-dev grunt-contrib-imagemin`
|
|
||||||
//
|
|
||||||
// * for using images based CSS sprites (http://youtu.be/xD8DW6IQ6r0)
|
|
||||||
// `npm install --save-dev grunt-fancy-sprites`
|
|
||||||
// `bower install --save fancy-sprites-scss`
|
|
||||||
//
|
|
||||||
// * for automatically adding CSS vendor prefixes (autoprefixer)
|
|
||||||
// `npm install --save-dev grunt-autoprefixer`
|
|
||||||
//
|
|
||||||
// * for package import validations
|
|
||||||
// `npm install --save-dev grunt-es6-import-validate`
|
|
||||||
//
|
|
||||||
|
|
||||||
var Helpers = require('./tasks/helpers'),
|
|
||||||
filterAvailable = Helpers.filterAvailableTasks,
|
|
||||||
_ = grunt.util._,
|
|
||||||
path = require('path');
|
|
||||||
|
|
||||||
Helpers.pkg = require("./package.json");
|
|
||||||
|
|
||||||
if (Helpers.isPackageAvailable("time-grunt")) {
|
|
||||||
require("time-grunt")(grunt);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loads task options from `tasks/options/` and `tasks/custom-options`
|
|
||||||
// and loads tasks defined in `package.json`
|
|
||||||
var config = _.extend({},
|
|
||||||
require('load-grunt-config')(grunt, {
|
|
||||||
configPath: path.join(__dirname, 'tasks/options'),
|
|
||||||
loadGruntTasks: false,
|
|
||||||
init: false
|
|
||||||
}),
|
|
||||||
require('load-grunt-config')(grunt, { // Custom options have precedence
|
|
||||||
configPath: path.join(__dirname, 'tasks/custom-options'),
|
|
||||||
init: false
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
grunt.loadTasks('tasks'); // Loads tasks in `tasks/` folder
|
|
||||||
|
|
||||||
config.env = process.env;
|
|
||||||
|
|
||||||
|
|
||||||
// App Kit's Main Tasks
|
|
||||||
// ====================
|
|
||||||
|
|
||||||
|
|
||||||
// Generate the production version
|
|
||||||
// ------------------
|
|
||||||
grunt.registerTask('dist', "Build a minified & production-ready version of your app.", [
|
|
||||||
'clean:dist',
|
|
||||||
'build:dist',
|
|
||||||
'copy:assemble',
|
|
||||||
'createDistVersion'
|
|
||||||
]);
|
|
||||||
|
|
||||||
|
|
||||||
// Default Task
|
|
||||||
// ------------------
|
|
||||||
grunt.registerTask('default', "Build (in debug mode) & test your application.", ['test']);
|
|
||||||
|
|
||||||
|
|
||||||
// Servers
|
|
||||||
// -------------------
|
|
||||||
grunt.registerTask('server', "Run your server in development mode, auto-rebuilding when files change.", function(proxyMethod) {
|
|
||||||
var expressServerTask = 'expressServer:debug';
|
|
||||||
if (proxyMethod) {
|
|
||||||
expressServerTask += ':' + proxyMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
grunt.task.run(['clean:debug',
|
|
||||||
'build:debug',
|
|
||||||
expressServerTask,
|
|
||||||
'watch'
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
grunt.registerTask('server:dist', "Build and preview a minified & production-ready version of your app.", [
|
|
||||||
'dist',
|
|
||||||
'expressServer:dist:keepalive'
|
|
||||||
]);
|
|
||||||
|
|
||||||
|
|
||||||
// Testing
|
|
||||||
// -------
|
|
||||||
grunt.registerTask('test', "Run your apps's tests once. Uses Google Chrome by default.", [
|
|
||||||
'clean:debug', 'build:debug', 'testem:ci:basic' ]);
|
|
||||||
|
|
||||||
grunt.registerTask('test:ci', "Run your app's tests in PhantomJS. For use in continuous integration (i.e. Travis CI).", [
|
|
||||||
'clean:debug', 'build:debug', 'testem:ci:basic' ]);
|
|
||||||
|
|
||||||
grunt.registerTask('test:browsers', "Run your app's tests in multiple browsers (see tasks/options/testem.js for configuration).", [
|
|
||||||
'clean:debug', 'build:debug', 'testem:ci:browsers' ]);
|
|
||||||
|
|
||||||
grunt.registerTask('test:server', "Alias to `testem:run:basic`. Be sure to install testem first using `npm install -g testem`", [
|
|
||||||
'testem:run:basic' ]);
|
|
||||||
|
|
||||||
// Worker tasks
|
|
||||||
// =================================
|
|
||||||
|
|
||||||
grunt.registerTask('build:dist', filterAvailable([
|
|
||||||
'createResultDirectory', // Create directoy beforehand, fixes race condition
|
|
||||||
'fancySprites:create',
|
|
||||||
'concurrent:buildDist', // Executed in parallel, see config below
|
|
||||||
]));
|
|
||||||
|
|
||||||
grunt.registerTask('build:debug', filterAvailable([
|
|
||||||
'jshint:tooling',
|
|
||||||
'createResultDirectory', // Create directoy beforehand, fixes race condition
|
|
||||||
'fancySprites:create',
|
|
||||||
'concurrent:buildDebug', // Executed in parallel, see config below
|
|
||||||
]));
|
|
||||||
|
|
||||||
grunt.registerTask('createDistVersion', filterAvailable([
|
|
||||||
'useminPrepare', // Configures concat, cssmin and uglify
|
|
||||||
'concat', // Combines css and javascript files
|
|
||||||
|
|
||||||
'cssmin', // Minifies css
|
|
||||||
'uglify', // Minifies javascript
|
|
||||||
'imagemin', // Optimizes image compression
|
|
||||||
// 'svgmin',
|
|
||||||
'copy:dist', // Copies files not covered by concat and imagemin
|
|
||||||
|
|
||||||
'rev', // Appends 8 char hash value to filenames
|
|
||||||
'usemin', // Replaces file references
|
|
||||||
'htmlmin:dist' // Removes comments and whitespace
|
|
||||||
]));
|
|
||||||
|
|
||||||
// Documentation
|
|
||||||
// -------
|
|
||||||
grunt.registerTask('docs', "Build YUIDoc documentation.", [
|
|
||||||
'buildDocs',
|
|
||||||
'server:debug'
|
|
||||||
]);
|
|
||||||
|
|
||||||
|
|
||||||
// Parallelize most of the build process
|
|
||||||
_.merge(config, {
|
|
||||||
concurrent: {
|
|
||||||
buildDist: [
|
|
||||||
"buildTemplates:dist",
|
|
||||||
"buildScripts",
|
|
||||||
"buildStyles",
|
|
||||||
"buildIndexHTML:dist"
|
|
||||||
],
|
|
||||||
buildDebug: [
|
|
||||||
"buildTemplates:debug",
|
|
||||||
"buildScripts",
|
|
||||||
"buildStyles",
|
|
||||||
"buildIndexHTML:debug"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Templates
|
|
||||||
grunt.registerTask('buildTemplates:dist', filterAvailable([
|
|
||||||
'emblem:compile',
|
|
||||||
'emberTemplates:dist'
|
|
||||||
]));
|
|
||||||
|
|
||||||
grunt.registerTask('buildTemplates:debug', filterAvailable([
|
|
||||||
'emblem:compile',
|
|
||||||
'emberTemplates:debug'
|
|
||||||
]));
|
|
||||||
|
|
||||||
// Scripts
|
|
||||||
grunt.registerTask('buildScripts', filterAvailable([
|
|
||||||
'jshint:app',
|
|
||||||
'jshint:tests',
|
|
||||||
'validate-imports:app',
|
|
||||||
'validate-imports:tests',
|
|
||||||
'coffee',
|
|
||||||
'emberscript',
|
|
||||||
'copy:javascriptToTmp',
|
|
||||||
'transpile',
|
|
||||||
'buildDocs',
|
|
||||||
'concat_sourcemap'
|
|
||||||
]));
|
|
||||||
|
|
||||||
// Styles
|
|
||||||
grunt.registerTask('buildStyles', filterAvailable([
|
|
||||||
'compass:compile',
|
|
||||||
'sass:compile',
|
|
||||||
'less:compile',
|
|
||||||
'stylus:compile',
|
|
||||||
'copy:cssToResult',
|
|
||||||
'autoprefixer:app'
|
|
||||||
]));
|
|
||||||
|
|
||||||
// Documentation
|
|
||||||
grunt.registerTask('buildDocs', filterAvailable([
|
|
||||||
'yuidoc:debug',
|
|
||||||
]));
|
|
||||||
|
|
||||||
// Index HTML
|
|
||||||
grunt.registerTask('buildIndexHTML:dist', [
|
|
||||||
'preprocess:indexHTMLDistApp',
|
|
||||||
'preprocess:indexHTMLDistTests'
|
|
||||||
]);
|
|
||||||
|
|
||||||
grunt.registerTask('buildIndexHTML:debug', [
|
|
||||||
'preprocess:indexHTMLDebugApp',
|
|
||||||
'preprocess:indexHTMLDebugTests'
|
|
||||||
]);
|
|
||||||
|
|
||||||
grunt.registerTask('createResultDirectory', function() {
|
|
||||||
grunt.file.mkdir('tmp/result');
|
|
||||||
});
|
|
||||||
|
|
||||||
grunt.initConfig(config);
|
|
||||||
};
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import DS from "ember-data";
|
||||||
|
|
||||||
export default DS.RESTAdapter.extend({
|
export default DS.RESTAdapter.extend({
|
||||||
// set namespace to api.php in same subdirectory
|
// set namespace to api.php in same subdirectory
|
||||||
namespace:
|
namespace:
|
||||||
|
|
25
app/app.js
25
app/app.js
|
@ -1,5 +1,10 @@
|
||||||
|
import Ember from 'ember';
|
||||||
import Resolver from 'ember/resolver';
|
import Resolver from 'ember/resolver';
|
||||||
import loadInitializers from 'ember/load-initializers';
|
import loadInitializers from 'ember/load-initializers';
|
||||||
|
import config from './config/environment';
|
||||||
|
import sjcl from 'sjcl';
|
||||||
|
|
||||||
|
Ember.MODEL_FACTORY_INJECTIONS = true;
|
||||||
|
|
||||||
// decrypt / encrypt computed property helper
|
// decrypt / encrypt computed property helper
|
||||||
Ember.computed.encrypted = function(encryptedField, dataType) {
|
Ember.computed.encrypted = function(encryptedField, dataType) {
|
||||||
|
@ -46,10 +51,9 @@ Ember.computed.encrypted = function(encryptedField, dataType) {
|
||||||
|
|
||||||
case 'date':
|
case 'date':
|
||||||
// https://github.com/emberjs/data/blob/master/packages/ember-data/lib/transforms/date.js
|
// https://github.com/emberjs/data/blob/master/packages/ember-data/lib/transforms/date.js
|
||||||
var type = typeof decryptedValue;
|
if (typeof decryptedValue === "string") {
|
||||||
if (type === "string") {
|
|
||||||
return new Date(Ember.Date.parse(decryptedValue));
|
return new Date(Ember.Date.parse(decryptedValue));
|
||||||
} else if (type === "number") {
|
} else if (typeof decryptedValue === "number") {
|
||||||
return new Date(decryptedValue);
|
return new Date(decryptedValue);
|
||||||
} else if (decryptedValue === null || decryptedValue === undefined) {
|
} else if (decryptedValue === null || decryptedValue === undefined) {
|
||||||
// if the value is not present in the data,
|
// if the value is not present in the data,
|
||||||
|
@ -68,12 +72,11 @@ Ember.computed.encrypted = function(encryptedField, dataType) {
|
||||||
|
|
||||||
case 'boolean':
|
case 'boolean':
|
||||||
// https://github.com/emberjs/data/blob/master/packages/ember-data/lib/transforms/boolean.js
|
// https://github.com/emberjs/data/blob/master/packages/ember-data/lib/transforms/boolean.js
|
||||||
var type = typeof decryptedValue;
|
if (typeof decryptedValue === "boolean") {
|
||||||
if (type === "boolean") {
|
|
||||||
return decryptedValue;
|
return decryptedValue;
|
||||||
} else if (type === "string") {
|
} else if (typeof decryptedValue === "string") {
|
||||||
return decryptedValue.match(/^true$|^t$|^1$/i) !== null;
|
return decryptedValue.match(/^true$|^t$|^1$/i) !== null;
|
||||||
} else if (type === "number") {
|
} else if (typeof decryptedValue === "number") {
|
||||||
return decryptedValue === 1;
|
return decryptedValue === 1;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -83,16 +86,14 @@ Ember.computed.encrypted = function(encryptedField, dataType) {
|
||||||
};
|
};
|
||||||
|
|
||||||
var App = Ember.Application.extend({
|
var App = Ember.Application.extend({
|
||||||
modulePrefix: 'croodle', // TODO: loaded via config
|
modulePrefix: config.modulePrefix,
|
||||||
|
podModulePrefix: config.podModulePrefix,
|
||||||
Resolver: Resolver
|
Resolver: Resolver
|
||||||
});
|
});
|
||||||
|
|
||||||
import extendTextField from 'croodle/ext/text-field';
|
|
||||||
extendTextField();
|
|
||||||
|
|
||||||
import formattedDateHelper from 'croodle/helpers/formatted-date';
|
import formattedDateHelper from 'croodle/helpers/formatted-date';
|
||||||
Ember.Handlebars.registerBoundHelper('formattedDate', formattedDateHelper);
|
Ember.Handlebars.registerBoundHelper('formattedDate', formattedDateHelper);
|
||||||
|
|
||||||
loadInitializers(App, 'croodle');
|
loadInitializers(App, config.modulePrefix);
|
||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import Ember from "ember";
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
classNames: ['pretty-color'],
|
classNames: ['pretty-color'],
|
||||||
attributeBindings: ['style'],
|
attributeBindings: ['style'],
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import Ember from "ember";
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
classNames: ['look-ma-no-template'],
|
classNames: ['look-ma-no-template'],
|
||||||
tagName: ['span']
|
tagName: ['span']
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
import Ember from "ember";
|
||||||
|
import $ from "jquery";
|
||||||
|
|
||||||
export default Ember.ObjectController.extend(Ember.Validations.Mixin, {
|
export default Ember.ObjectController.extend(Ember.Validations.Mixin, {
|
||||||
actions: {
|
actions: {
|
||||||
save: function() {
|
save: function() {
|
||||||
|
@ -22,11 +25,11 @@ export default Ember.ObjectController.extend(Ember.Validations.Mixin, {
|
||||||
|
|
||||||
pollTypes: function(){
|
pollTypes: function(){
|
||||||
return [
|
return [
|
||||||
Em.Object.extend(Em.I18n.TranslateableProperties, {}).create({
|
Ember.Object.extend(Ember.I18n.TranslateableProperties, {}).create({
|
||||||
id : "FindADate",
|
id : "FindADate",
|
||||||
labelTranslation : "pollTypes.findADate.label"
|
labelTranslation : "pollTypes.findADate.label"
|
||||||
}),
|
}),
|
||||||
Em.Object.extend(Em.I18n.TranslateableProperties, {}).create({
|
Ember.Object.extend(Ember.I18n.TranslateableProperties, {}).create({
|
||||||
id : "MakeAPoll",
|
id : "MakeAPoll",
|
||||||
labelTranslation : "pollTypes.makeAPoll.label"
|
labelTranslation : "pollTypes.makeAPoll.label"
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
import Ember from "ember";
|
||||||
|
import $ from "jquery";
|
||||||
|
|
||||||
export default Ember.ObjectController.extend(Ember.Validations.Mixin, {
|
export default Ember.ObjectController.extend(Ember.Validations.Mixin, {
|
||||||
actions: {
|
actions: {
|
||||||
save: function() {
|
save: function() {
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
import Ember from "ember";
|
||||||
|
import $ from "jquery";
|
||||||
|
|
||||||
export default Ember.ObjectController.extend(Ember.Validations.Mixin, {
|
export default Ember.ObjectController.extend(Ember.Validations.Mixin, {
|
||||||
actions: {
|
actions: {
|
||||||
/*
|
/*
|
||||||
|
@ -50,8 +53,7 @@ export default Ember.ObjectController.extend(Ember.Validations.Mixin, {
|
||||||
|
|
||||||
datetimes.forEach(function(datetime){
|
datetimes.forEach(function(datetime){
|
||||||
datetime.contents.times.forEach(function(t){
|
datetime.contents.times.forEach(function(t){
|
||||||
var date = new Date(datetime.contents.title),
|
var date = new Date(datetime.contents.title);
|
||||||
delimiter = '';
|
|
||||||
|
|
||||||
// check if there is a value for time
|
// check if there is a value for time
|
||||||
if (Ember.isEmpty(t.value)) {
|
if (Ember.isEmpty(t.value)) {
|
||||||
|
@ -104,7 +106,7 @@ export default Ember.ObjectController.extend(Ember.Validations.Mixin, {
|
||||||
/*
|
/*
|
||||||
* only used on init, not on increasing number of input fields!
|
* only used on init, not on increasing number of input fields!
|
||||||
*/
|
*/
|
||||||
datetimes: function(key, value, previousValue){
|
datetimes: function(){
|
||||||
var datetimes = Ember.A(),
|
var datetimes = Ember.A(),
|
||||||
dates = this.get('options'),
|
dates = this.get('options'),
|
||||||
datetimesCount = this.get('datetimesInputFields'),
|
datetimesCount = this.get('datetimesInputFields'),
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
import Ember from "ember";
|
||||||
|
import $ from "jquery";
|
||||||
|
|
||||||
export default Ember.ObjectController.extend(Ember.Validations.Mixin, {
|
export default Ember.ObjectController.extend(Ember.Validations.Mixin, {
|
||||||
actions: {
|
actions: {
|
||||||
save: function(){
|
save: function(){
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
import Ember from "ember";
|
||||||
|
import $ from "jquery";
|
||||||
|
|
||||||
export default Ember.ObjectController.extend(Ember.Validations.Mixin, {
|
export default Ember.ObjectController.extend(Ember.Validations.Mixin, {
|
||||||
actions: {
|
actions: {
|
||||||
save: function(){
|
save: function(){
|
||||||
|
@ -35,44 +38,44 @@ export default Ember.ObjectController.extend(Ember.Validations.Mixin, {
|
||||||
|
|
||||||
answerTypes: function() {
|
answerTypes: function() {
|
||||||
return [
|
return [
|
||||||
Em.Object.extend(Em.I18n.TranslateableProperties, {}).create({
|
Ember.Object.extend(Ember.I18n.TranslateableProperties, {}).create({
|
||||||
id : "YesNo",
|
id : "YesNo",
|
||||||
labelTranslation : "answerTypes.yesNo.label",
|
labelTranslation : "answerTypes.yesNo.label",
|
||||||
answers : [
|
answers : [
|
||||||
Em.Object.extend(Em.I18n.TranslateableProperties, {}).create({
|
Ember.Object.extend(Ember.I18n.TranslateableProperties, {}).create({
|
||||||
id: "yes",
|
id: "yes",
|
||||||
labelTranslation: "answerTypes.yes.label",
|
labelTranslation: "answerTypes.yes.label",
|
||||||
icon: "glyphicon glyphicon-thumbs-up"
|
icon: "glyphicon glyphicon-thumbs-up"
|
||||||
}),
|
}),
|
||||||
Em.Object.extend(Em.I18n.TranslateableProperties, {}).create({
|
Ember.Object.extend(Ember.I18n.TranslateableProperties, {}).create({
|
||||||
id: "no",
|
id: "no",
|
||||||
labelTranslation: "answerTypes.no.label",
|
labelTranslation: "answerTypes.no.label",
|
||||||
icon: "glyphicon glyphicon-thumbs-down"
|
icon: "glyphicon glyphicon-thumbs-down"
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
Em.Object.extend(Em.I18n.TranslateableProperties, {}).create({
|
Ember.Object.extend(Ember.I18n.TranslateableProperties, {}).create({
|
||||||
id : "YesNoMaybe",
|
id : "YesNoMaybe",
|
||||||
labelTranslation : "answerTypes.yesNoMaybe.label",
|
labelTranslation : "answerTypes.yesNoMaybe.label",
|
||||||
answers : [
|
answers : [
|
||||||
Em.Object.extend(Em.I18n.TranslateableProperties, {}).create({
|
Ember.Object.extend(Ember.I18n.TranslateableProperties, {}).create({
|
||||||
id: "yes",
|
id: "yes",
|
||||||
labelTranslation: "answerTypes.yes.label",
|
labelTranslation: "answerTypes.yes.label",
|
||||||
icon: "glyphicon glyphicon-thumbs-up"
|
icon: "glyphicon glyphicon-thumbs-up"
|
||||||
}),
|
}),
|
||||||
Em.Object.extend(Em.I18n.TranslateableProperties, {}).create({
|
Ember.Object.extend(Ember.I18n.TranslateableProperties, {}).create({
|
||||||
id: "maybe",
|
id: "maybe",
|
||||||
labelTranslation: "answerTypes.maybe.label",
|
labelTranslation: "answerTypes.maybe.label",
|
||||||
icon: "glyphicon glyphicon-hand-right"
|
icon: "glyphicon glyphicon-hand-right"
|
||||||
}),
|
}),
|
||||||
Em.Object.extend(Em.I18n.TranslateableProperties, {}).create({
|
Ember.Object.extend(Ember.I18n.TranslateableProperties, {}).create({
|
||||||
id: "no",
|
id: "no",
|
||||||
labelTranslation: "answerTypes.no.label",
|
labelTranslation: "answerTypes.no.label",
|
||||||
icon: "glyphicon glyphicon-thumbs-down"
|
icon: "glyphicon glyphicon-thumbs-down"
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
Em.Object.extend(Em.I18n.TranslateableProperties, {}).create({
|
Ember.Object.extend(Ember.I18n.TranslateableProperties, {}).create({
|
||||||
id : "FreeText",
|
id : "FreeText",
|
||||||
labelTranslation : "answerTypes.freeText.label",
|
labelTranslation : "answerTypes.freeText.label",
|
||||||
answers : []
|
answers : []
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import Ember from "ember";
|
||||||
|
|
||||||
export default Ember.ObjectController.extend({
|
export default Ember.ObjectController.extend({
|
||||||
is404: function(){
|
is404: function(){
|
||||||
return this.get('status') === 404;
|
return this.get('status') === 404;
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
import Ember from "ember";
|
||||||
|
import $ from "jquery";
|
||||||
|
|
||||||
export default Ember.ObjectController.extend(Ember.Validations.Mixin, {
|
export default Ember.ObjectController.extend(Ember.Validations.Mixin, {
|
||||||
encryptionKey: '',
|
encryptionKey: '',
|
||||||
newUserName: '',
|
newUserName: '',
|
||||||
|
@ -72,12 +75,10 @@ export default Ember.ObjectController.extend(Ember.Validations.Mixin, {
|
||||||
}
|
}
|
||||||
|
|
||||||
var datetimes = this.get('dates'),
|
var datetimes = this.get('dates'),
|
||||||
dates = [],
|
|
||||||
datesCount = {},
|
|
||||||
dateGroups = [];
|
dateGroups = [];
|
||||||
|
|
||||||
var lastDate = null,
|
var count = 0,
|
||||||
count = 0;
|
lastDate = null;
|
||||||
datetimes.forEach(function(el){
|
datetimes.forEach(function(el){
|
||||||
var date;
|
var date;
|
||||||
date = new Date( el.title );
|
date = new Date( el.title );
|
||||||
|
@ -133,12 +134,11 @@ export default Ember.ObjectController.extend(Ember.Validations.Mixin, {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var timezoneDifference = new Date().getTimezoneOffset() - this.get('timezoneOffset'),
|
var timezoneDifference = new Date().getTimezoneOffset() - this.get('timezoneOffset'),
|
||||||
dates = [],
|
dates = [];
|
||||||
self = this;
|
|
||||||
this.get('options').forEach(function(option){
|
this.get('options').forEach(function(option){
|
||||||
dates.pushObject({
|
dates.pushObject({
|
||||||
title: new Date( option.title ).setMinutes(
|
title: new Date( option.title ).setMinutes(
|
||||||
new Date( option.title ).getMinutes() - self.get('timezoneOffset')
|
timezoneDifference
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -226,7 +226,7 @@ export default Ember.ObjectController.extend(Ember.Validations.Mixin, {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
newUserSelections.forEach(function(item, index, enumerable){
|
newUserSelections.forEach(function(item){
|
||||||
if (Ember.isEmpty(item.value)) {
|
if (Ember.isEmpty(item.value)) {
|
||||||
allAnswered = false;
|
allAnswered = false;
|
||||||
}
|
}
|
||||||
|
@ -313,7 +313,7 @@ export default Ember.ObjectController.extend(Ember.Validations.Mixin, {
|
||||||
* ToDo: Show validation errors
|
* ToDo: Show validation errors
|
||||||
*/
|
*/
|
||||||
acceptance: {
|
acceptance: {
|
||||||
if: function(object, validator){
|
if: function(object){
|
||||||
return object.get('forceAnswer');
|
return object.get('forceAnswer');
|
||||||
},
|
},
|
||||||
message: Ember.I18n.t('poll.error.newUser.everyOptionIsAnswered')
|
message: Ember.I18n.t('poll.error.newUser.everyOptionIsAnswered')
|
||||||
|
@ -326,7 +326,7 @@ export default Ember.ObjectController.extend(Ember.Validations.Mixin, {
|
||||||
* validate if a user name is given
|
* validate if a user name is given
|
||||||
* if it's forced by poll settings (anonymousUser === false)
|
* if it's forced by poll settings (anonymousUser === false)
|
||||||
*/
|
*/
|
||||||
unless: function(object, validator){
|
unless: function(object){
|
||||||
/* have in mind that anonymousUser is undefined on init */
|
/* have in mind that anonymousUser is undefined on init */
|
||||||
return object.get('anonymousUser');
|
return object.get('anonymousUser');
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import Ember from "ember";
|
||||||
|
|
||||||
export default function() {
|
export default function() {
|
||||||
Ember.TextField.reopen({
|
Ember.TextField.reopen({
|
||||||
attributeBindings: ['data-option']
|
attributeBindings: ['data-option']
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import moment from "moment";
|
||||||
|
|
||||||
export default function(date, options) {
|
export default function(date, options) {
|
||||||
var times = options.hash.times ? options.hash.times : false,
|
var times = options.hash.times ? options.hash.times : false,
|
||||||
format = options.hash.format ? options.hash.format : 'LLLL';
|
format = options.hash.format ? options.hash.format : 'LLLL';
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import Ember from "ember";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* radio button helper by FellowMD
|
* radio button helper by FellowMD
|
||||||
* https://gist.github.com/FellowMD/84f5b113de2db762cb1d
|
* https://gist.github.com/FellowMD/84f5b113de2db762cb1d
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import Ember from "ember";
|
||||||
|
|
||||||
// Please note that Handlebars helpers will only be found automatically by the
|
// Please note that Handlebars helpers will only be found automatically by the
|
||||||
// resolver if their name contains a dash (reverse-word, translate-text, etc.)
|
// resolver if their name contains a dash (reverse-word, translate-text, etc.)
|
||||||
// For more details: http://stefanpenner.github.io/ember-app-kit/guides/using-modules.html
|
// For more details: http://stefanpenner.github.io/ember-app-kit/guides/using-modules.html
|
||||||
|
|
154
app/index.html
154
app/index.html
|
@ -1,140 +1,24 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<title>Croodle</title>
|
<title>Croodle</title>
|
||||||
<meta name="description" content="">
|
<meta name="description" content="">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
<!-- build:css(tmp/result) assets/app.min.css -->
|
{{content-for 'head'}}
|
||||||
<link rel="stylesheet" href="/assets/app.css">
|
|
||||||
<!-- endbuild -->
|
|
||||||
|
|
||||||
<!-- for more details visit: https://github.com/yeoman/grunt-usemin -->
|
<link rel="stylesheet" href="assets/vendor.css">
|
||||||
|
<link rel="stylesheet" href="assets/croodle.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{{content-for 'body'}}
|
||||||
|
|
||||||
<!-- build:js(tmp/result) assets/config.min.js -->
|
<script>
|
||||||
|
webshim.polyfill('forms forms-ext');
|
||||||
<script src="/config/environment.js"></script>
|
</script>
|
||||||
<!-- @if tests=false -->
|
<script src="assets/vendor.js"></script>
|
||||||
|
<script src="assets/croodle.js"></script>
|
||||||
<!-- @if dist=false -->
|
</body>
|
||||||
<script src="/config/environments/development.js"></script>
|
|
||||||
<!-- @endif -->
|
|
||||||
<!-- @if dist=true -->
|
|
||||||
<script src="/config/environments/production.js"></script>
|
|
||||||
<!-- @endif -->
|
|
||||||
|
|
||||||
<!-- @endif --><!-- @if tests=true -->
|
|
||||||
<script src="/config/environments/test.js"></script>
|
|
||||||
<!-- @endif -->
|
|
||||||
|
|
||||||
<!-- endbuild -->
|
|
||||||
|
|
||||||
<!-- build:js(tmp/result) assets/vendor.min.js -->
|
|
||||||
|
|
||||||
<!-- @if dist=false -->
|
|
||||||
<script src="/vendor/jquery/dist/jquery.js"></script>
|
|
||||||
<script src="/vendor/handlebars/handlebars.js"></script>
|
|
||||||
<script src="/vendor/ember/ember.js"></script>
|
|
||||||
<script src="/vendor/ember-data/ember-data.js"></script>
|
|
||||||
<script src="/vendor/floatThead/dist/jquery.floatThead.js"></script>
|
|
||||||
<script src="/vendor/moment/min/moment-with-locales.js"></script>
|
|
||||||
<script src="/vendor/webshim/js-webshim/dev/polyfiller.js"></script>
|
|
||||||
<script src="/vendor/bootstrap/dist/js/bootstrap.js"></script>
|
|
||||||
<!-- @endif -->
|
|
||||||
<!-- @if dist=true -->
|
|
||||||
<script src="/vendor/jquery/dist/jquery.min.js"></script>
|
|
||||||
<script src="/vendor/handlebars/handlebars.runtime.js"></script>
|
|
||||||
<script src="/vendor/ember/ember.prod.js"></script>
|
|
||||||
<script src="/vendor/ember-data/ember-data.prod.js"></script>
|
|
||||||
<script src="/vendor/floatThead/dist/jquery.floatThead.min.js"></script>
|
|
||||||
<script src="/vendor/moment/min/moment-with-locales.min.js"></script>
|
|
||||||
<script src="/vendor/webshim/js-webshim/minified/polyfiller.js"></script>
|
|
||||||
<script src="/vendor/bootstrap/dist/js/bootstrap.min.js"></script>
|
|
||||||
<!-- @endif -->
|
|
||||||
|
|
||||||
<script src="/vendor/loader.js/loader.js"></script>
|
|
||||||
<script src="/vendor/ember-resolver/dist/ember-resolver.js"></script>
|
|
||||||
<script src="/vendor/ember-shim.js"></script>
|
|
||||||
<script src="/vendor/ic-ajax/dist/named-amd/main.js"></script>
|
|
||||||
<script src="/vendor/ember-load-initializers/ember-load-initializers.js"></script>
|
|
||||||
<script src="/vendor/ember-validations/index.js"></script>
|
|
||||||
<script src="/vendor/ember-easyForm/index.js"></script>
|
|
||||||
<script src="/vendor/cldr/plurals.js"></script>
|
|
||||||
<script src="/vendor/ember-i18n/lib/i18n.js"></script>
|
|
||||||
<script src="/vendor/ember-i18n/lib/i18n-plurals.js"></script>
|
|
||||||
<script src="/vendor/sjcl/sjcl.js"></script>
|
|
||||||
<script src="/vendor/bootstrap-datepicker/js/bootstrap-datepicker.js"></script>
|
|
||||||
|
|
||||||
<script src="/vendor/modernizr/modernizr.js"></script>
|
|
||||||
<!-- endbuild -->
|
|
||||||
|
|
||||||
<!-- build:js(tmp/result) assets/app.min.js -->
|
|
||||||
|
|
||||||
<script src="/assets/app.js"></script>
|
|
||||||
<script src="/assets/templates.js"></script>
|
|
||||||
|
|
||||||
<!-- endbuild -->
|
|
||||||
|
|
||||||
<!-- @if dist=false -->
|
|
||||||
<style>
|
|
||||||
@keyframes domChanged { from { background: yellow; } }
|
|
||||||
@-webkit-keyframes domChanged { from { background: yellow; } }
|
|
||||||
.ember-view { animation: domChanged 1s; -webkit-animation: domChanged 1s; }
|
|
||||||
</style>
|
|
||||||
<!-- @endif -->
|
|
||||||
<!-- @if tests=true -->
|
|
||||||
<script src="/vendor/ember-shim.js"></script>
|
|
||||||
<link rel="stylesheet" href="/vendor/qunit/qunit/qunit.css">
|
|
||||||
<script src="/vendor/qunit/qunit/qunit.js"></script>
|
|
||||||
<script src="/vendor/qunit-shim.js"></script>
|
|
||||||
<script src="/vendor/ember-qunit/dist/named-amd/main.js"></script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
#ember-testing-container {
|
|
||||||
position: absolute;
|
|
||||||
background: white;
|
|
||||||
bottom: 0;
|
|
||||||
right: 0;
|
|
||||||
width: 640px;
|
|
||||||
height: 384px;
|
|
||||||
overflow: auto;
|
|
||||||
z-index: 9999;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
}
|
|
||||||
#ember-testing {
|
|
||||||
zoom: 50%;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<!-- @endif -->
|
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<!--[if lt IE 8]>
|
|
||||||
<p class="browsehappy">
|
|
||||||
You are using an <strong>outdated</strong> browser. Please
|
|
||||||
<a href="http://browsehappy.com/">upgrade your browser</a>
|
|
||||||
to improve your experience.
|
|
||||||
</p>
|
|
||||||
<![endif]-->
|
|
||||||
|
|
||||||
<!-- @if tests=true -->
|
|
||||||
<div id="qunit"></div>
|
|
||||||
<div id="qunit-fixture"></div>
|
|
||||||
<script src="/tests/tests.js"></script>
|
|
||||||
<script src="/tests/test-helper.js"></script>
|
|
||||||
<script src="/tests/test-loader.js"></script>
|
|
||||||
<script src="/testem.js"></script>
|
|
||||||
<!-- @endif -->
|
|
||||||
|
|
||||||
<!-- @if tests=false -->
|
|
||||||
<script>
|
|
||||||
window.App = require('croodle/app')['default'].create(ENV.APP);
|
|
||||||
|
|
||||||
webshim.polyfill('forms forms-ext');
|
|
||||||
</script>
|
|
||||||
<!-- @endif -->
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
|
@ -1,3 +1,5 @@
|
||||||
|
import Ember from "ember";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* make ember-easyForm support Bootstrap 3
|
* make ember-easyForm support Bootstrap 3
|
||||||
* https://github.com/dockyard/ember-easyForm/wiki/Bootstrap-3-and-Ember-Data-With-Server-Side-Validations
|
* https://github.com/dockyard/ember-easyForm/wiki/Bootstrap-3-and-Ember-Data-With-Server-Side-Validations
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
import Ember from "ember";
|
||||||
import translations from "croodle/lang/translations";
|
import translations from "croodle/lang/translations";
|
||||||
|
import moment from "moment";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'i18n',
|
name: 'i18n',
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import Ember from "ember";
|
||||||
|
|
||||||
export default Ember.Object.extend({
|
export default Ember.Object.extend({
|
||||||
key : '',
|
key : '',
|
||||||
isSet: false
|
isSet: false
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
import DS from "ember-data";
|
||||||
|
import Ember from "ember";
|
||||||
|
|
||||||
export default DS.Model.extend({
|
export default DS.Model.extend({
|
||||||
// relationship
|
// relationship
|
||||||
users : DS.hasMany('user'),
|
users : DS.hasMany('user'),
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
import DS from "ember-data";
|
||||||
|
import Ember from "ember";
|
||||||
|
|
||||||
export default DS.Model.extend({
|
export default DS.Model.extend({
|
||||||
// relationship
|
// relationship
|
||||||
poll : DS.belongsTo('poll'),
|
poll : DS.belongsTo('poll'),
|
||||||
|
|
|
@ -1,14 +1,19 @@
|
||||||
var Router = Ember.Router.extend(); // ensure we don't share routes between all Router instances
|
import Ember from 'ember';
|
||||||
|
import config from './config/environment';
|
||||||
|
|
||||||
|
var Router = Ember.Router.extend({
|
||||||
|
location: config.locationType
|
||||||
|
});
|
||||||
|
|
||||||
Router.map(function(){
|
Router.map(function(){
|
||||||
this.route('poll', { path: '/poll/:poll_id' });
|
this.route('poll', { path: '/poll/:poll_id' });
|
||||||
this.resource('create', function(){
|
this.resource('create', function(){
|
||||||
this.route('meta');
|
this.route('meta');
|
||||||
this.route('options');
|
this.route('options');
|
||||||
this.route('options-datetime');
|
this.route('options-datetime');
|
||||||
this.route('settings');
|
this.route('settings');
|
||||||
});
|
});
|
||||||
this.route('404');
|
this.route('404');
|
||||||
});
|
});
|
||||||
|
|
||||||
export default Router;
|
export default Router;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import Ember from "ember";
|
||||||
|
|
||||||
export default Ember.Route.extend({
|
export default Ember.Route.extend({
|
||||||
beforeModel: function(){
|
beforeModel: function(){
|
||||||
// generate encryptionKey
|
// generate encryptionKey
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import Ember from "ember";
|
||||||
|
|
||||||
export default Ember.Route.extend({
|
export default Ember.Route.extend({
|
||||||
model: function(){
|
model: function(){
|
||||||
return this.modelFor('create');
|
return this.modelFor('create');
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import Ember from "ember";
|
||||||
|
|
||||||
export default Ember.Route.extend({
|
export default Ember.Route.extend({
|
||||||
model: function(){
|
model: function(){
|
||||||
return this.modelFor('create');
|
return this.modelFor('create');
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import Ember from "ember";
|
||||||
|
|
||||||
export default Ember.Route.extend({
|
export default Ember.Route.extend({
|
||||||
model: function(){
|
model: function(){
|
||||||
return this.modelFor('create');
|
return this.modelFor('create');
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import Ember from "ember";
|
||||||
|
|
||||||
export default Ember.Route.extend({
|
export default Ember.Route.extend({
|
||||||
model: function(){
|
model: function(){
|
||||||
return this.modelFor('create');
|
return this.modelFor('create');
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import Ember from "ember";
|
||||||
|
|
||||||
export default Ember.Route.extend({
|
export default Ember.Route.extend({
|
||||||
model: function(){
|
model: function(){
|
||||||
return this.modelFor('create');
|
return this.modelFor('create');
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
import Ember from "ember";
|
||||||
|
|
||||||
export default Ember.Route.extend({
|
export default Ember.Route.extend({
|
||||||
actions: {
|
actions: {
|
||||||
error: function(error, transition) {
|
error: function(error) {
|
||||||
if (error && error.status === 404) {
|
if (error && error.status === 404) {
|
||||||
return this.transitionTo('404');
|
return this.transitionTo('404');
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1,3 @@
|
||||||
|
import DS from "ember-data";
|
||||||
|
|
||||||
export default DS.RESTSerializer.extend();
|
export default DS.RESTSerializer.extend();
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import DS from "ember-data";
|
||||||
|
|
||||||
export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
|
export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
|
||||||
attrs: {
|
attrs: {
|
||||||
users: {embedded: 'always'}
|
users: {embedded: 'always'}
|
||||||
|
|
3
app/styles/app.css
Normal file
3
app/styles/app.css
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
html, body {
|
||||||
|
margin: 20px;
|
||||||
|
}
|
|
@ -1,4 +1,7 @@
|
||||||
export default Em.View.extend({
|
import Ember from "ember";
|
||||||
|
import webshim from "webshim";
|
||||||
|
|
||||||
|
export default Ember.View.extend({
|
||||||
didInsertElement: function(){
|
didInsertElement: function(){
|
||||||
this._super();
|
this._super();
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import Ember from "ember";
|
||||||
|
|
||||||
export default Ember.View.extend({
|
export default Ember.View.extend({
|
||||||
title: '',
|
title: '',
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
export default Em.View.extend({
|
import Ember from "ember";
|
||||||
|
import $ from "jquery";
|
||||||
|
|
||||||
|
export default Ember.View.extend({
|
||||||
classNames: ['datepicker'],
|
classNames: ['datepicker'],
|
||||||
|
|
||||||
didInsertElement: function() {
|
didInsertElement: function() {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import Ember from "ember";
|
||||||
import translations from "croodle/lang/translations";
|
import translations from "croodle/lang/translations";
|
||||||
|
|
||||||
export default Ember.View.extend({
|
export default Ember.View.extend({
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
export default Ember.View.extend(Em.I18n.TranslateableProperties, {
|
import Ember from "ember";
|
||||||
|
import moment from "moment";
|
||||||
|
import $ from "jquery";
|
||||||
|
|
||||||
|
export default Ember.View.extend(Ember.I18n.TranslateableProperties, {
|
||||||
showEvaluation: false,
|
showEvaluation: false,
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import Ember from "ember";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ember-radio by FellowMD
|
* ember-radio by FellowMD
|
||||||
* https://github.com/FellowMD/ember-radio/blob/master/app/views/radio.js
|
* https://github.com/FellowMD/ember-radio/blob/master/app/views/radio.js
|
||||||
|
|
31
bower.json
31
bower.json
|
@ -2,26 +2,27 @@
|
||||||
"name": "croodle",
|
"name": "croodle",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"handlebars": "~1.3.0",
|
"handlebars": "~1.3.0",
|
||||||
"jquery": "~1.11",
|
"jquery": "^1.11.1",
|
||||||
"qunit": "~1.12.0",
|
"ember": "1.7.0",
|
||||||
|
"ember-data": "1.0.0-beta.10",
|
||||||
|
"ember-resolver": "~0.1.7",
|
||||||
|
"loader.js": "stefanpenner/loader.js#1.0.1",
|
||||||
|
"ember-cli-shims": "stefanpenner/ember-cli-shims#0.0.3",
|
||||||
|
"ember-cli-test-loader": "rwjblue/ember-cli-test-loader#0.0.4",
|
||||||
|
"ember-load-initializers": "stefanpenner/ember-load-initializers#0.0.2",
|
||||||
"ember-qunit": "0.1.8",
|
"ember-qunit": "0.1.8",
|
||||||
"ember": "~1.7.0",
|
"ember-qunit-notifications": "0.0.4",
|
||||||
"ember-data": "~1.0.0",
|
"qunit": "~1.15.0",
|
||||||
"ember-resolver": "~0.1",
|
|
||||||
"ic-ajax": "~1.0.4",
|
|
||||||
"ember-testing-httpRespond": "~0.1.1",
|
|
||||||
"loader.js": "git://github.com/stefanpenner/loader.js",
|
|
||||||
"ember-load-initializers": "git://github.com/stefanpenner/ember-load-initializers.git#0.0.1",
|
|
||||||
"moment": "~2.8.3",
|
|
||||||
"sjcl": "~1.0.0",
|
|
||||||
"ember-validations": "http://builds.dockyard.com.s3.amazonaws.com/ember-validations/tags/v1.0.0/ember-validations.js",
|
"ember-validations": "http://builds.dockyard.com.s3.amazonaws.com/ember-validations/tags/v1.0.0/ember-validations.js",
|
||||||
|
"ember-easyForm": "http://builds.dockyard.com/ember-easyForm/latest/ember-easyForm.js",
|
||||||
|
"cldr": "~1.0.2",
|
||||||
|
"ember-i18n": "~2.9.0",
|
||||||
|
"sjcl": "~1.0.0",
|
||||||
"bootstrap": "~3.2.0",
|
"bootstrap": "~3.2.0",
|
||||||
"bootstrap-datepicker": "~1.3.0",
|
"bootstrap-datepicker": "~1.3.0",
|
||||||
"ember-easyForm": "http://builds.dockyard.com/ember-easyForm/latest/ember-easyForm.js",
|
"moment": "~2.8.3",
|
||||||
"floatThead": "~1.2.9",
|
"floatThead": "~1.2.9",
|
||||||
"webshim": "~1.15.3",
|
"webshim": "~1.15.3",
|
||||||
"modernizr": "~2.8.3",
|
"modernizr": "~2.8.3"
|
||||||
"ember-i18n": "~2.9.0",
|
|
||||||
"cldr": "~1.0.2"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,46 @@
|
||||||
// Put general configuration here. This file is included
|
/* jshint node: true */
|
||||||
// in both production and development BEFORE Ember is
|
|
||||||
// loaded.
|
|
||||||
//
|
|
||||||
// For example to enable a feature on a canary build you
|
|
||||||
// might do:
|
|
||||||
//
|
|
||||||
// window.ENV = {FEATURES: {'with-controller': true}};
|
|
||||||
|
|
||||||
window.ENV = {
|
module.exports = function(environment) {
|
||||||
FEATURES: {
|
var ENV = {
|
||||||
|
modulePrefix: 'croodle',
|
||||||
|
environment: environment,
|
||||||
|
baseURL: '/',
|
||||||
|
locationType: 'auto',
|
||||||
|
EmberENV: {
|
||||||
|
FEATURES: {
|
||||||
'query-params-new': true
|
'query-params-new': true
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
|
||||||
window.ENV.MODEL_FACTORY_INJECTIONS = true;
|
APP: {
|
||||||
|
// Here you can pass flags/options to your application instance
|
||||||
|
// when it is created
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (environment === 'development') {
|
||||||
|
// ENV.APP.LOG_RESOLVER = true;
|
||||||
|
ENV.APP.LOG_ACTIVE_GENERATION = true;
|
||||||
|
// ENV.APP.LOG_TRANSITIONS = true;
|
||||||
|
// ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
|
||||||
|
ENV.APP.LOG_VIEW_LOOKUPS = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (environment === 'test') {
|
||||||
|
// Testem prefers this...
|
||||||
|
ENV.baseURL = '/';
|
||||||
|
ENV.locationType = 'auto';
|
||||||
|
|
||||||
|
// keep test console output quieter
|
||||||
|
ENV.APP.LOG_ACTIVE_GENERATION = false;
|
||||||
|
ENV.APP.LOG_VIEW_LOOKUPS = false;
|
||||||
|
|
||||||
|
ENV.APP.rootElement = '#ember-testing';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (environment === 'production') {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return ENV;
|
||||||
|
};
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
// Put your development configuration here.
|
|
||||||
//
|
|
||||||
// This is useful when using a separate API
|
|
||||||
// endpoint in development than in production.
|
|
||||||
//
|
|
||||||
// window.ENV.public_key = '123456'
|
|
||||||
|
|
||||||
window.ENV.APP = {
|
|
||||||
LOG_ACTIVE_GENERATION: true,
|
|
||||||
LOG_MODULE_RESOLVER: true,
|
|
||||||
LOG_TRANSITIONS: true,
|
|
||||||
LOG_TRANSITIONS_INTERNAL: true,
|
|
||||||
LOG_VIEW_LOOKUPS: true
|
|
||||||
};
|
|
|
@ -1,6 +0,0 @@
|
||||||
// Put your production configuration here.
|
|
||||||
//
|
|
||||||
// This is useful when using a separate API
|
|
||||||
// endpoint in development than in production.
|
|
||||||
//
|
|
||||||
// window.ENV.public_key = '123456'
|
|
|
@ -1,6 +0,0 @@
|
||||||
// Put your test configuration here.
|
|
||||||
//
|
|
||||||
// This is useful when using a separate API
|
|
||||||
// endpoint in test than in production.
|
|
||||||
//
|
|
||||||
// window.ENV.public_key = '123456'
|
|
58
package.json
58
package.json
|
@ -1,57 +1,37 @@
|
||||||
{
|
{
|
||||||
"name": "croodle",
|
"name": "croodle",
|
||||||
"namespace": "croodle",
|
|
||||||
"APIMethod": "proxy",
|
"APIMethod": "proxy",
|
||||||
"proxyURL": "http://localhost:80/croodle",
|
"proxyURL": "http://localhost:80/croodle",
|
||||||
"proxyPath": "/api.php",
|
"proxyPath": "/api.php",
|
||||||
"docURL": "http://localhost:8000/docs/index.html",
|
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"directories": {
|
"directories": {
|
||||||
"doc": "doc",
|
"doc": "doc",
|
||||||
"test": "test"
|
"test": "tests"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "grunt server",
|
"start": "ember server",
|
||||||
"build": "grunt build:debug",
|
"build": "ember build",
|
||||||
"test": "grunt test:ci",
|
"test": "ember test"
|
||||||
"postinstall": "bower install"
|
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": "https://github.com/stefanpenner/ember-cli",
|
||||||
"type": "git",
|
"engines": {
|
||||||
"url": "git://github.com/stefanpenner/ember-app-kit.git"
|
"node": ">= 0.10.0"
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"express": "~3.4.8",
|
"body-parser": "^1.2.0",
|
||||||
"lockfile": "~0.4.2",
|
"broccoli-asset-rev": "0.3.1",
|
||||||
"bower": "~1.3.2",
|
"broccoli-ember-hbs-template-compiler": "^1.6.1",
|
||||||
"grunt": "~0.4.2",
|
"ember-cli": "0.1.2",
|
||||||
"grunt-cli": "~0.1.9",
|
"ember-cli-content-security-policy": "0.3.0",
|
||||||
"load-grunt-config": "~0.7.0",
|
"ember-export-application-global": "^1.0.0",
|
||||||
"grunt-contrib-watch": "~0.5.3",
|
"ember-cli-ic-ajax": "0.1.1",
|
||||||
"grunt-contrib-copy": "~0.4.1",
|
"ember-cli-inject-live-reload": "^1.3.0",
|
||||||
"grunt-contrib-concat": "~0.3.0",
|
"ember-cli-qunit": "0.1.0",
|
||||||
"grunt-contrib-clean": "~0.5.0",
|
"ember-data": "1.0.0-beta.10",
|
||||||
"grunt-contrib-jshint": "~0.8.0",
|
"express": "^4.8.5",
|
||||||
"grunt-contrib-uglify": "~0.2.7",
|
"glob": "^4.0.5"
|
||||||
"grunt-contrib-cssmin": "~0.6.2",
|
|
||||||
"grunt-preprocess": "~3.0.1",
|
|
||||||
"grunt-es6-module-transpiler": "~0.6.0",
|
|
||||||
"grunt-concat-sourcemap": "~0.4.0",
|
|
||||||
"grunt-concurrent": "~0.4.3",
|
|
||||||
"grunt-usemin": "~0.1.13",
|
|
||||||
"grunt-rev": "~0.1.0",
|
|
||||||
"grunt-ember-templates": "~0.4.18",
|
|
||||||
"grunt-contrib-testem": "~0.5.16",
|
|
||||||
"express-namespace": "~0.1.1",
|
|
||||||
"request": "~2.33.0",
|
|
||||||
"loom-generators-ember-appkit": "~1.0.5",
|
|
||||||
"originate": "~0.1.5",
|
|
||||||
"loom": "~3.1.2",
|
|
||||||
"connect-livereload": "~0.3.1",
|
|
||||||
"grunt-es6-import-validate": "0.0.6",
|
|
||||||
"grunt-contrib-less": "~0.11.4"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
{
|
|
||||||
"node" : true,
|
|
||||||
"browser" : false,
|
|
||||||
"boss" : true,
|
|
||||||
"curly": false,
|
|
||||||
"debug": false,
|
|
||||||
"devel": false,
|
|
||||||
"eqeqeq": true,
|
|
||||||
"evil": true,
|
|
||||||
"forin": false,
|
|
||||||
"immed": false,
|
|
||||||
"laxbreak": false,
|
|
||||||
"newcap": true,
|
|
||||||
"noarg": true,
|
|
||||||
"noempty": false,
|
|
||||||
"nonew": false,
|
|
||||||
"nomen": false,
|
|
||||||
"onevar": false,
|
|
||||||
"plusplus": false,
|
|
||||||
"regexp": false,
|
|
||||||
"undef": true,
|
|
||||||
"sub": true,
|
|
||||||
"strict": false,
|
|
||||||
"white": false,
|
|
||||||
"eqnull": true,
|
|
||||||
"esnext": true
|
|
||||||
}
|
|
|
@ -1,78 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
|
|
||||||
// Note: These tasks are listed in the order in which they will run.
|
|
||||||
|
|
||||||
javascriptToTmp: {
|
|
||||||
files: [{
|
|
||||||
expand: true,
|
|
||||||
cwd: 'app',
|
|
||||||
src: '**/*.js',
|
|
||||||
dest: 'tmp/javascript/app'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
expand: true,
|
|
||||||
cwd: 'tests',
|
|
||||||
src: ['**/*.js', '!test-helper.js', '!test-loader.js'],
|
|
||||||
dest: 'tmp/javascript/tests/'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
|
|
||||||
cssToResult: {
|
|
||||||
expand: true,
|
|
||||||
cwd: 'app/styles',
|
|
||||||
src: ['**/*.css'],
|
|
||||||
dest: 'tmp/result/assets'
|
|
||||||
},
|
|
||||||
|
|
||||||
// Assembles everything in `tmp/result`.
|
|
||||||
// The sole purpose of this task is to keep things neat. Gathering everything in one
|
|
||||||
// place (tmp/dist) enables the subtasks of dist to only look there. Note: However,
|
|
||||||
// for normal development this is done on the fly by the development server.
|
|
||||||
assemble: {
|
|
||||||
files: [{
|
|
||||||
expand: true,
|
|
||||||
cwd: 'tests',
|
|
||||||
src: ['test-helper.js', 'test-loader.js'],
|
|
||||||
dest: 'tmp/result/tests/'
|
|
||||||
}, {
|
|
||||||
expand: true,
|
|
||||||
cwd: 'public',
|
|
||||||
src: ['**'],
|
|
||||||
dest: 'tmp/result/'
|
|
||||||
}, {
|
|
||||||
src: ['vendor/**/*.js', 'vendor/**/*.css'],
|
|
||||||
dest: 'tmp/result/'
|
|
||||||
}, {
|
|
||||||
src: ['config/environment.js', 'config/environments/production.js'],
|
|
||||||
dest: 'tmp/result/'
|
|
||||||
}
|
|
||||||
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
imageminFallback: {
|
|
||||||
files: '<%= imagemin.dist.files %>'
|
|
||||||
},
|
|
||||||
|
|
||||||
dist: {
|
|
||||||
files: [{
|
|
||||||
expand: true,
|
|
||||||
cwd: 'tmp/result',
|
|
||||||
src: [
|
|
||||||
'**',
|
|
||||||
'!**/*.{css,js}', // Already handled by concat
|
|
||||||
'!**/*.{png,gif,jpg,jpeg}', // Already handled by imagemin
|
|
||||||
'!tests/**/*', // No tests, please
|
|
||||||
'!**/*.map' // No source maps
|
|
||||||
],
|
|
||||||
filter: 'isFile',
|
|
||||||
dest: 'dist/'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
expand: true,
|
|
||||||
cwd: 'vendor/webshim/js-webshim/minified/shims',
|
|
||||||
src: ['**'],
|
|
||||||
dest: 'dist/assets/shims'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,129 +0,0 @@
|
||||||
module.exports = function(grunt) {
|
|
||||||
var express = require('express'),
|
|
||||||
lockFile = require('lockfile'),
|
|
||||||
Helpers = require('./helpers'),
|
|
||||||
fs = require('fs'),
|
|
||||||
path = require('path'),
|
|
||||||
request = require('request');
|
|
||||||
|
|
||||||
/**
|
|
||||||
Task for serving the static files.
|
|
||||||
|
|
||||||
Note: The expressServer:debug task looks for files in multiple directories.
|
|
||||||
*/
|
|
||||||
grunt.registerTask('expressServer', function(target, proxyMethodToUse) {
|
|
||||||
// Load namespace module before creating the server
|
|
||||||
require('express-namespace');
|
|
||||||
|
|
||||||
var app = express(),
|
|
||||||
done = this.async(),
|
|
||||||
proxyMethod = proxyMethodToUse || grunt.config('express-server.options.APIMethod');
|
|
||||||
|
|
||||||
app.use(lock);
|
|
||||||
app.use(express.compress());
|
|
||||||
|
|
||||||
if (proxyMethod === 'stub') {
|
|
||||||
grunt.log.writeln('Using API Stub');
|
|
||||||
|
|
||||||
// Load API stub routes
|
|
||||||
app.use(express.json());
|
|
||||||
app.use(express.urlencoded());
|
|
||||||
require('../api-stub/routes')(app);
|
|
||||||
} else if (proxyMethod === 'proxy') {
|
|
||||||
var proxyURL = grunt.config('express-server.options.proxyURL'),
|
|
||||||
proxyPath = grunt.config('express-server.options.proxyPath') || '/api';
|
|
||||||
grunt.log.writeln('Proxying API requests matching ' + proxyPath + '/* to: ' + proxyURL);
|
|
||||||
|
|
||||||
// Use API proxy
|
|
||||||
app.all(proxyPath + '*', passThrough(proxyURL));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target === 'debug') {
|
|
||||||
// For `expressServer:debug`
|
|
||||||
|
|
||||||
// Add livereload middleware after lock middleware if enabled
|
|
||||||
if (Helpers.isPackageAvailable("connect-livereload")) {
|
|
||||||
var liveReloadPort = grunt.config('watch.options.livereload');
|
|
||||||
app.use(require("connect-livereload")({port: liveReloadPort}));
|
|
||||||
}
|
|
||||||
|
|
||||||
// YUIDoc serves static HTML, so just serve the index.html
|
|
||||||
app.all('/docs', function(req, res) { res.redirect(302, '/docs/index.html'); });
|
|
||||||
app.use(static({ urlRoot: '/docs', directory: 'docs' }));
|
|
||||||
|
|
||||||
// These three lines simulate what the `copy:assemble` task does
|
|
||||||
app.use(static({ urlRoot: '/config', directory: 'config' }));
|
|
||||||
app.use(static({ urlRoot: '/vendor', directory: 'vendor' }));
|
|
||||||
app.use(static({ directory: 'public' }));
|
|
||||||
app.use(static({ urlRoot: '/tests', directory: 'tests' })); // For test-helper.js and test-loader.js
|
|
||||||
app.use(static({ directory: 'tmp/result' }));
|
|
||||||
app.use(static({ file: 'tmp/result/index.html', ignoredFileExtensions: /\.\w{1,5}$/ })); // Gotta catch 'em all
|
|
||||||
} else {
|
|
||||||
// For `expressServer:dist`
|
|
||||||
|
|
||||||
app.use(lock);
|
|
||||||
app.use(static({ directory: 'dist' }));
|
|
||||||
app.use(static({ file: 'dist/index.html', ignoredFileExtensions: /\.\w{1,5}$/ })); // Gotta catch 'em all
|
|
||||||
}
|
|
||||||
|
|
||||||
var port = parseInt(process.env.PORT || 8000, 10);
|
|
||||||
if (isNaN(port) || port < 1 || port > 65535) {
|
|
||||||
grunt.fail.fatal('The PORT environment variable of ' + process.env.PORT + ' is not valid.');
|
|
||||||
}
|
|
||||||
app.listen(port);
|
|
||||||
grunt.log.ok('Started development server on port %d.', port);
|
|
||||||
if (!this.flags.keepalive) { done(); }
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// Middleware
|
|
||||||
// ==========
|
|
||||||
|
|
||||||
function lock(req, res, next) { // Works with tasks/locking.js
|
|
||||||
(function retry() {
|
|
||||||
if (lockFile.checkSync('tmp/connect.lock')) {
|
|
||||||
setTimeout(retry, 30);
|
|
||||||
} else { next(); }
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
|
|
||||||
function static(options) {
|
|
||||||
return function(req, res, next) { // Gotta catch 'em all (and serve index.html)
|
|
||||||
var filePath = "";
|
|
||||||
if (options.directory) {
|
|
||||||
var regex = new RegExp('^' + (options.urlRoot || ''));
|
|
||||||
// URL must begin with urlRoot's value
|
|
||||||
if (!req.path.match(regex)) { next(); return; }
|
|
||||||
filePath = options.directory + req.path.replace(regex, '');
|
|
||||||
} else if (options.file) {
|
|
||||||
filePath = options.file;
|
|
||||||
} else { throw new Error('static() isn\'t properly configured!'); }
|
|
||||||
|
|
||||||
fs.stat(filePath, function(err, stats) {
|
|
||||||
if (err) { next(); return; } // Not a file, not a folder => can't handle it
|
|
||||||
|
|
||||||
if (options.ignoredFileExtensions) {
|
|
||||||
if (options.ignoredFileExtensions.test(req.path)) {
|
|
||||||
res.send(404, {error: 'Resource not found'});
|
|
||||||
return; // Do not serve index.html
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is it a directory? If so, search for an index.html in it.
|
|
||||||
if (stats.isDirectory()) { filePath = path.join(filePath, 'index.html'); }
|
|
||||||
|
|
||||||
// Serve the file
|
|
||||||
res.sendfile(filePath, function(err) {
|
|
||||||
if (err) { next(); return; }
|
|
||||||
grunt.verbose.ok('Served: ' + filePath);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function passThrough(target) {
|
|
||||||
return function(req, res) {
|
|
||||||
req.pipe(request(target+req.url)).pipe(res);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,60 +0,0 @@
|
||||||
var grunt = require('grunt'),
|
|
||||||
_ = grunt.util._,
|
|
||||||
Helpers = {};
|
|
||||||
|
|
||||||
// List of package requisits for tasks
|
|
||||||
// Notated in conjunctive normal form (CNF)
|
|
||||||
// e.g. ['a', ['b', 'alternative-to-b']]
|
|
||||||
var taskRequirements = {
|
|
||||||
coffee: ['grunt-contrib-coffee'],
|
|
||||||
compass: ['grunt-contrib-compass'],
|
|
||||||
sass: [['grunt-sass', 'grunt-contrib-sass']],
|
|
||||||
less: ['grunt-contrib-less'],
|
|
||||||
stylus: ['grunt-contrib-stylus'],
|
|
||||||
emberTemplates: ['grunt-ember-templates'],
|
|
||||||
emblem: ['grunt-emblem'],
|
|
||||||
emberscript: ['grunt-ember-script'],
|
|
||||||
imagemin: ['grunt-contrib-imagemin'],
|
|
||||||
htmlmin: ['grunt-contrib-htmlmin'],
|
|
||||||
fancySprites: ['grunt-fancy-sprites'],
|
|
||||||
autoprefixer: ['grunt-autoprefixer'],
|
|
||||||
rev: ['grunt-rev'],
|
|
||||||
'validate-imports': ['grunt-es6-import-validate'],
|
|
||||||
yuidoc: ['grunt-contrib-yuidoc']
|
|
||||||
};
|
|
||||||
|
|
||||||
// Task fallbacks
|
|
||||||
// e.g. 'a': ['fallback-a-step-1', 'fallback-a-step-2']
|
|
||||||
var taskFallbacks = {
|
|
||||||
'imagemin': 'copy:imageminFallback'
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
Helpers.filterAvailableTasks = function(tasks){
|
|
||||||
tasks = tasks.map(function(taskName) {
|
|
||||||
// Maps to task name or fallback if task is unavailable
|
|
||||||
|
|
||||||
var baseName = taskName.split(':')[0]; // e.g. 'coffee' for 'coffee:compile'
|
|
||||||
var reqs = taskRequirements[baseName];
|
|
||||||
var isAvailable = Helpers.isPackageAvailable(reqs);
|
|
||||||
return isAvailable ? taskName : taskFallbacks[taskName];
|
|
||||||
});
|
|
||||||
|
|
||||||
return _.flatten(_.compact(tasks)); // Remove undefined's and flatten it
|
|
||||||
};
|
|
||||||
|
|
||||||
Helpers.isPackageAvailable = function(pkgNames) {
|
|
||||||
if (!pkgNames) return true; // packages are assumed to exist
|
|
||||||
|
|
||||||
if (!_.isArray(pkgNames)) { pkgNames = [pkgNames]; }
|
|
||||||
|
|
||||||
return _.every(pkgNames, function(pkgNames) {
|
|
||||||
if (!_.isArray(pkgNames)) { pkgNames = [pkgNames]; }
|
|
||||||
|
|
||||||
return _.any(pkgNames, function(pkgName) {
|
|
||||||
return !!Helpers.pkg.devDependencies[pkgName];
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = Helpers;
|
|
|
@ -1,14 +0,0 @@
|
||||||
var lockFile = require('lockfile');
|
|
||||||
|
|
||||||
module.exports = function(grunt) {
|
|
||||||
grunt.registerTask('lock', 'Set semaphore for connect server to wait on.', function() {
|
|
||||||
grunt.file.mkdir('tmp');
|
|
||||||
lockFile.lockSync('tmp/connect.lock');
|
|
||||||
grunt.log.writeln("Locked - Development server won't answer incoming requests until App Kit is done updating.");
|
|
||||||
});
|
|
||||||
|
|
||||||
grunt.registerTask('unlock', 'Release semaphore that connect server waits on.', function() {
|
|
||||||
lockFile.unlockSync('tmp/connect.lock');
|
|
||||||
grunt.log.writeln("Unlocked - Development server now handles requests.");
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,5 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
app: {
|
|
||||||
src: 'tmp/result/assets/**/*.css'
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,4 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
'debug': ['tmp'],
|
|
||||||
'dist': ['tmp', 'dist']
|
|
||||||
};
|
|
|
@ -1,42 +0,0 @@
|
||||||
// CoffeeScript compilation. This must be enabled by modification
|
|
||||||
// of Gruntfile.js.
|
|
||||||
//
|
|
||||||
// The `bare` option is used since this file will be transpiled
|
|
||||||
// anyway. In CoffeeScript files, you need to escape out for
|
|
||||||
// some ES6 features like import and export. For example:
|
|
||||||
//
|
|
||||||
// `import User from 'appkit/models/user'`
|
|
||||||
//
|
|
||||||
// Post = Em.Object.extend
|
|
||||||
// init: (userId) ->
|
|
||||||
// @set 'user', User.findById(userId)
|
|
||||||
//
|
|
||||||
// `export default Post`
|
|
||||||
//
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
"test": {
|
|
||||||
options: {
|
|
||||||
bare: true
|
|
||||||
},
|
|
||||||
files: [{
|
|
||||||
expand: true,
|
|
||||||
cwd: 'tests/',
|
|
||||||
src: '**/*.coffee',
|
|
||||||
dest: 'tmp/javascript/tests',
|
|
||||||
ext: '.js'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
"app": {
|
|
||||||
options: {
|
|
||||||
bare: true
|
|
||||||
},
|
|
||||||
files: [{
|
|
||||||
expand: true,
|
|
||||||
cwd: 'app/',
|
|
||||||
src: '**/*.coffee',
|
|
||||||
dest: 'tmp/javascript/app',
|
|
||||||
ext: '.js'
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,17 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
options: {
|
|
||||||
sassDir: "app/styles",
|
|
||||||
cssDir: "tmp/result/assets",
|
|
||||||
generatedImagesDir: "tmp/result/assets/images/generated",
|
|
||||||
imagesDir: "public/assets/images",
|
|
||||||
javascriptsDir: "app",
|
|
||||||
fontsDir: "public/assets/fonts",
|
|
||||||
importPath: ["vendor"],
|
|
||||||
httpImagesPath: "/assets/images",
|
|
||||||
httpGeneratedImagesPath: "/assets/images/generated",
|
|
||||||
httpFontsPath: "/assets/fonts",
|
|
||||||
relativeAssets: false,
|
|
||||||
debugInfo: true
|
|
||||||
},
|
|
||||||
compile: {}
|
|
||||||
};
|
|
|
@ -1,25 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
app: {
|
|
||||||
src: ['tmp/transpiled/app/**/*.js'],
|
|
||||||
dest: 'tmp/result/assets/app.js',
|
|
||||||
options: {
|
|
||||||
sourcesContent: true
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
config: {
|
|
||||||
src: ['tmp/result/config/**/*.js'],
|
|
||||||
dest: 'tmp/result/assets/config.js',
|
|
||||||
options: {
|
|
||||||
sourcesContent: true
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
test: {
|
|
||||||
src: 'tmp/transpiled/tests/**/*.js',
|
|
||||||
dest: 'tmp/result/tests/tests.js',
|
|
||||||
options: {
|
|
||||||
sourcesContent: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,6 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
// Remaining configuration done in Gruntfile.js
|
|
||||||
options: {
|
|
||||||
logConcurrentOutput: true
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,72 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
|
|
||||||
// Note: These tasks are listed in the order in which they will run.
|
|
||||||
|
|
||||||
javascriptToTmp: {
|
|
||||||
files: [{
|
|
||||||
expand: true,
|
|
||||||
cwd: 'app',
|
|
||||||
src: '**/*.js',
|
|
||||||
dest: 'tmp/javascript/app'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
expand: true,
|
|
||||||
cwd: 'tests',
|
|
||||||
src: ['**/*.js', '!test-helper.js', '!test-loader.js'],
|
|
||||||
dest: 'tmp/javascript/tests/'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
|
|
||||||
cssToResult: {
|
|
||||||
expand: true,
|
|
||||||
cwd: 'app/styles',
|
|
||||||
src: ['**/*.css'],
|
|
||||||
dest: 'tmp/result/assets'
|
|
||||||
},
|
|
||||||
|
|
||||||
// Assembles everything in `tmp/result`.
|
|
||||||
// The sole purpose of this task is to keep things neat. Gathering everything in one
|
|
||||||
// place (tmp/dist) enables the subtasks of dist to only look there. Note: However,
|
|
||||||
// for normal development this is done on the fly by the development server.
|
|
||||||
assemble: {
|
|
||||||
files: [{
|
|
||||||
expand: true,
|
|
||||||
cwd: 'tests',
|
|
||||||
src: ['test-helper.js', 'test-loader.js'],
|
|
||||||
dest: 'tmp/result/tests/'
|
|
||||||
}, {
|
|
||||||
expand: true,
|
|
||||||
cwd: 'public',
|
|
||||||
src: ['**'],
|
|
||||||
dest: 'tmp/result/'
|
|
||||||
}, {
|
|
||||||
src: ['vendor/**/*.js', 'vendor/**/*.css'],
|
|
||||||
dest: 'tmp/result/'
|
|
||||||
}, {
|
|
||||||
src: ['config/environment.js', 'config/environments/production.js'],
|
|
||||||
dest: 'tmp/result/'
|
|
||||||
}
|
|
||||||
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
imageminFallback: {
|
|
||||||
files: '<%= imagemin.dist.files %>'
|
|
||||||
},
|
|
||||||
|
|
||||||
dist: {
|
|
||||||
files: [{
|
|
||||||
expand: true,
|
|
||||||
cwd: 'tmp/result',
|
|
||||||
src: [
|
|
||||||
'**',
|
|
||||||
'!**/*.{css,js}', // Already handled by concat
|
|
||||||
'!**/*.{png,gif,jpg,jpeg}', // Already handled by imagemin
|
|
||||||
'!tests/**/*', // No tests, please
|
|
||||||
'!**/*.map' // No source maps
|
|
||||||
],
|
|
||||||
filter: 'isFile',
|
|
||||||
dest: 'dist/'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,22 +0,0 @@
|
||||||
var grunt = require('grunt');
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
options: {
|
|
||||||
templateBasePath: /app\//,
|
|
||||||
templateFileExtensions: /\.(hbs|hjs|handlebars)/,
|
|
||||||
templateRegistration: function(name, template) {
|
|
||||||
return grunt.config.process("define('<%= package.namespace %>/") + name + "', ['exports'], function(__exports__){ __exports__['default'] = " + template + "; });";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
debug: {
|
|
||||||
options: {
|
|
||||||
precompile: false
|
|
||||||
},
|
|
||||||
src: "app/**/*.{hbs,hjs,handlebars}",
|
|
||||||
dest: "tmp/result/assets/templates.js"
|
|
||||||
},
|
|
||||||
dist: {
|
|
||||||
src: "<%= emberTemplates.debug.src %>",
|
|
||||||
dest: "<%= emberTemplates.debug.dest %>"
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,42 +0,0 @@
|
||||||
// EmberScript compilation. This must be enabled by modification
|
|
||||||
// of Gruntfile.js.
|
|
||||||
//
|
|
||||||
// The `bare` option is used since this file will be transpiled
|
|
||||||
// anyway. In EmberScript files, you need to escape out for
|
|
||||||
// some ES6 features like import and export. For example:
|
|
||||||
//
|
|
||||||
// `import User from 'appkit/models/user'`
|
|
||||||
//
|
|
||||||
// class Post
|
|
||||||
// init: (userId) ->
|
|
||||||
// @user = User.findById(userId)
|
|
||||||
//
|
|
||||||
// `export default Post`
|
|
||||||
//
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
"test": {
|
|
||||||
options: {
|
|
||||||
bare: true
|
|
||||||
},
|
|
||||||
files: [{
|
|
||||||
expand: true,
|
|
||||||
cwd: 'tests/',
|
|
||||||
src: '**/*.em',
|
|
||||||
dest: 'tmp/javascript/tests',
|
|
||||||
ext: '.js'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
"app": {
|
|
||||||
options: {
|
|
||||||
bare: true
|
|
||||||
},
|
|
||||||
files: [{
|
|
||||||
expand: true,
|
|
||||||
cwd: 'app/',
|
|
||||||
src: '**/*.em',
|
|
||||||
dest: 'tmp/javascript/app',
|
|
||||||
ext: '.js'
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,16 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
compile: {
|
|
||||||
files: {
|
|
||||||
"tmp/result/assets/templates.js": ['app/templates/**/*.{emblem,hbs,hjs,handlebars}']
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
root: 'app/templates/',
|
|
||||||
dependencies: {
|
|
||||||
jquery: 'vendor/jquery/jquery.js',
|
|
||||||
ember: 'vendor/ember/ember.js',
|
|
||||||
handlebars: 'vendor/handlebars/handlebars.js',
|
|
||||||
emblem: 'vendor/emblem.js/emblem.js'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,9 +0,0 @@
|
||||||
var grunt = require('grunt');
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
options: {
|
|
||||||
APIMethod: "<%= package.APIMethod %>", // stub or proxy
|
|
||||||
proxyURL: "<%= package.proxyURL %>", // URL to the API server, if using APIMethod: 'proxy'
|
|
||||||
proxyPath: "<%= package.proxyPath %>" // path for the API endpoints, default is '/api', if using APIMethod: 'proxy'
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,22 +0,0 @@
|
||||||
var path = require('path');
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
create: {
|
|
||||||
destStyles: 'tmp/sprites',
|
|
||||||
destSpriteSheets: 'tmp/result/assets/sprites',
|
|
||||||
files: [{
|
|
||||||
src: ['app/sprites/**/*.{png,jpg,jpeg}', '!app/sprites/**/*@2x.{png,jpg,jpeg}'],
|
|
||||||
spriteSheetName: '1x',
|
|
||||||
spriteName: function(name) {
|
|
||||||
return path.basename(name, path.extname(name));
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
src: 'app/sprites/**/*@2x.{png,jpg,jpeg}',
|
|
||||||
spriteSheetName: '2x',
|
|
||||||
spriteName: function(name) {
|
|
||||||
return path.basename(name, path.extname(name)).replace(/@2x/, '');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,12 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
dist: {
|
|
||||||
options: {
|
|
||||||
removeComments: true,
|
|
||||||
collapseWhitespace: true
|
|
||||||
},
|
|
||||||
files: [{
|
|
||||||
src: 'dist/index.html',
|
|
||||||
dest: 'dist/index.html'
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,13 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
dist: {
|
|
||||||
options: {
|
|
||||||
cache: false
|
|
||||||
},
|
|
||||||
files: [{
|
|
||||||
expand: true,
|
|
||||||
cwd: 'tmp/result',
|
|
||||||
src: '**/*.{png,gif,jpg,jpeg}',
|
|
||||||
dest: 'dist/'
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,27 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
app: {
|
|
||||||
src: [
|
|
||||||
'app/**/*.js'
|
|
||||||
],
|
|
||||||
options: { jshintrc: '.jshintrc' }
|
|
||||||
},
|
|
||||||
|
|
||||||
tooling: {
|
|
||||||
src: [
|
|
||||||
'Gruntfile.js',
|
|
||||||
'tasks/**/*.js'
|
|
||||||
],
|
|
||||||
options: { jshintrc: 'tasks/.jshintrc' }
|
|
||||||
},
|
|
||||||
|
|
||||||
tests: {
|
|
||||||
src: [
|
|
||||||
'tests/**/*.js',
|
|
||||||
],
|
|
||||||
options: { jshintrc: 'tests/.jshintrc' }
|
|
||||||
},
|
|
||||||
|
|
||||||
options: {
|
|
||||||
force: true
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,11 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
compile: {
|
|
||||||
files: [{
|
|
||||||
expand: true,
|
|
||||||
cwd: 'app/styles',
|
|
||||||
src: ['**/*.less', '!**/_*.less'],
|
|
||||||
dest: 'tmp/result/assets/',
|
|
||||||
ext: '.css'
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,18 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
indexHTMLDebugApp: {
|
|
||||||
src : 'app/index.html', dest : 'tmp/result/index.html',
|
|
||||||
options: { context: { dist: false, tests: false } }
|
|
||||||
},
|
|
||||||
indexHTMLDebugTests: {
|
|
||||||
src : 'app/index.html', dest : 'tmp/result/tests/index.html',
|
|
||||||
options: { context: { dist: false, tests: true } }
|
|
||||||
},
|
|
||||||
indexHTMLDistApp: {
|
|
||||||
src : 'app/index.html', dest : 'tmp/result/index.html',
|
|
||||||
options: { context: { dist: true, tests: false } }
|
|
||||||
},
|
|
||||||
indexHTMLDistTests: {
|
|
||||||
src : 'app/index.html', dest : 'tmp/result/tests/index.html',
|
|
||||||
options: { context: { dist: true, tests: true } }
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,12 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
dist: {
|
|
||||||
files: {
|
|
||||||
src: [
|
|
||||||
'dist/assets/config.min.js',
|
|
||||||
'dist/assets/app.min.js',
|
|
||||||
'dist/assets/vendor.min.js',
|
|
||||||
'dist/assets/app.min.css'
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,11 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
compile: {
|
|
||||||
files: [{
|
|
||||||
expand: true,
|
|
||||||
cwd: 'app/styles',
|
|
||||||
src: ['**/*.{scss,sass}', '!**/_*.{scss,sass}'],
|
|
||||||
dest: 'tmp/result/assets/',
|
|
||||||
ext: '.css'
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,11 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
compile: {
|
|
||||||
files: [{
|
|
||||||
expand: true,
|
|
||||||
cwd: 'app/styles',
|
|
||||||
src: ['**/*.styl', '!**/_*.styl'],
|
|
||||||
dest: 'tmp/result/assets/',
|
|
||||||
ext: '.css'
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,55 +0,0 @@
|
||||||
// See https://npmjs.org/package/grunt-contrib-testem for more config options
|
|
||||||
module.exports = {
|
|
||||||
basic: {
|
|
||||||
options: {
|
|
||||||
parallel: 2,
|
|
||||||
framework: 'qunit',
|
|
||||||
port: (parseInt(process.env.PORT || 7358, 10) + 1),
|
|
||||||
test_page: 'tmp/result/tests/index.html',
|
|
||||||
routes: {
|
|
||||||
'/tests/tests.js': 'tmp/result/tests/tests.js',
|
|
||||||
'/assets/app.js': 'tmp/result/assets/app.js',
|
|
||||||
'/assets/templates.js': 'tmp/result/assets/templates.js',
|
|
||||||
'/assets/app.css': 'tmp/result/assets/app.css'
|
|
||||||
},
|
|
||||||
src_files: [
|
|
||||||
'tmp/result/**/*.js'
|
|
||||||
],
|
|
||||||
launch_in_dev: ['PhantomJS', 'Chrome'],
|
|
||||||
launch_in_ci: ['PhantomJS', 'Chrome'],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
browsers: {
|
|
||||||
options: {
|
|
||||||
parallel: 8,
|
|
||||||
framework: 'qunit',
|
|
||||||
port: (parseInt(process.env.PORT || 7358, 10) + 1),
|
|
||||||
test_page: 'tmp/result/tests/index.html',
|
|
||||||
routes: {
|
|
||||||
'/tests/tests.js': 'tmp/result/tests/tests.js',
|
|
||||||
'/assets/app.js': 'tmp/result/assets/app.js',
|
|
||||||
'/assets/templates.js': 'tmp/result/assets/templates.js',
|
|
||||||
'/assets/app.css': 'tmp/result/assets/app.css'
|
|
||||||
},
|
|
||||||
src_files: [
|
|
||||||
'tmp/result/**/*.js'
|
|
||||||
],
|
|
||||||
launch_in_dev: ['PhantomJS',
|
|
||||||
'Chrome',
|
|
||||||
'ChromeCanary',
|
|
||||||
'Firefox',
|
|
||||||
'Safari',
|
|
||||||
'IE7',
|
|
||||||
'IE8',
|
|
||||||
'IE9'],
|
|
||||||
launch_in_ci: ['PhantomJS',
|
|
||||||
'Chrome',
|
|
||||||
'ChromeCanary',
|
|
||||||
'Firefox',
|
|
||||||
'Safari',
|
|
||||||
'IE7',
|
|
||||||
'IE8',
|
|
||||||
'IE9'],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,28 +0,0 @@
|
||||||
var grunt = require('grunt');
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
"tests": {
|
|
||||||
type: 'amd',
|
|
||||||
moduleName: function(path) {
|
|
||||||
return grunt.config.process('<%= package.namespace %>/tests/') + path;
|
|
||||||
},
|
|
||||||
files: [{
|
|
||||||
expand: true,
|
|
||||||
cwd: 'tmp/javascript/tests/',
|
|
||||||
src: '**/*.js',
|
|
||||||
dest: 'tmp/transpiled/tests/'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
"app": {
|
|
||||||
type: 'amd',
|
|
||||||
moduleName: function(path) {
|
|
||||||
return grunt.config.process('<%= package.namespace %>/') + path;
|
|
||||||
},
|
|
||||||
files: [{
|
|
||||||
expand: true,
|
|
||||||
cwd: 'tmp/javascript/app/',
|
|
||||||
src: '**/*.js',
|
|
||||||
dest: 'tmp/transpiled/app/'
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,3 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
html: ['dist/index.html'],
|
|
||||||
};
|
|
|
@ -1,6 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
html: 'tmp/result/index.html',
|
|
||||||
options: {
|
|
||||||
dest: 'dist/'
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,47 +0,0 @@
|
||||||
var grunt = require('grunt');
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
options: {
|
|
||||||
whitelist: {
|
|
||||||
'ember/resolver': ['default'],
|
|
||||||
'ember/load-initializers': ['default'],
|
|
||||||
'ember-qunit': ['moduleForComponent', 'moduleForModel', 'moduleFor', 'test', 'default'],
|
|
||||||
'ic-ajax': ['default', 'request', 'raw', 'defineFixture', 'lookupFixture'],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
app: {
|
|
||||||
options: {
|
|
||||||
moduleName: function (name) {
|
|
||||||
return grunt.config.process('<%= package.namespace %>/') + name;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
files: [{
|
|
||||||
expand: true,
|
|
||||||
cwd: 'app',
|
|
||||||
src: ['**/*.js']
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
|
|
||||||
tests: {
|
|
||||||
options: {
|
|
||||||
moduleName: function (name) {
|
|
||||||
// Trim of the leading app/ from app modules
|
|
||||||
if (name.slice(0, 4) === 'app/') {
|
|
||||||
name = name.slice(4);
|
|
||||||
}
|
|
||||||
return grunt.config.process('<%= package.namespace %>/') + name;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// Test files reference app files so we have to make sure we pull in both sets
|
|
||||||
files: [{
|
|
||||||
expand: true,
|
|
||||||
cwd: '.',
|
|
||||||
src: ['tests/**/*.js']
|
|
||||||
}, {
|
|
||||||
expand: true,
|
|
||||||
cwd: '.',
|
|
||||||
src: ['app/**/*.js']
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,53 +0,0 @@
|
||||||
var Helpers = require('../helpers'),
|
|
||||||
filterAvailable = Helpers.filterAvailableTasks,
|
|
||||||
LIVERELOAD_PORT = 35729,
|
|
||||||
liveReloadPort = (parseInt(process.env.PORT || 8000, 10) - 8000) + LIVERELOAD_PORT;
|
|
||||||
|
|
||||||
var docs = '{app}/**/*.{js,coffee,em}',
|
|
||||||
scripts = '{app,tests,config}/**/*.{js,coffee,em}',
|
|
||||||
templates = 'app/templates/**/*.{hbs,handlebars,hjs,emblem}',
|
|
||||||
sprites = 'app/sprites/**/*.{png,jpg,jpeg}',
|
|
||||||
styles = 'app/styles/**/*.{css,sass,scss,less,styl}',
|
|
||||||
indexHTML = 'app/index.html',
|
|
||||||
other = '{app,tests,public}/**/*',
|
|
||||||
bowerFile = 'bower.json',
|
|
||||||
npmFile = 'package.json';
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
scripts: {
|
|
||||||
files: [scripts],
|
|
||||||
tasks: ['lock', 'buildScripts', 'unlock']
|
|
||||||
},
|
|
||||||
templates: {
|
|
||||||
files: [templates],
|
|
||||||
tasks: ['lock', 'buildTemplates:debug', 'unlock']
|
|
||||||
},
|
|
||||||
sprites: {
|
|
||||||
files: [sprites],
|
|
||||||
tasks: filterAvailable(['lock', 'fancySprites:create', 'unlock'])
|
|
||||||
},
|
|
||||||
styles: {
|
|
||||||
files: [styles],
|
|
||||||
tasks: ['lock', 'buildStyles', 'unlock']
|
|
||||||
},
|
|
||||||
indexHTML: {
|
|
||||||
files: [indexHTML],
|
|
||||||
tasks: ['lock', 'buildIndexHTML:debug', 'unlock']
|
|
||||||
},
|
|
||||||
docs: {
|
|
||||||
files: [docs],
|
|
||||||
tasks: ['lock', 'buildDocs', 'unlock']
|
|
||||||
},
|
|
||||||
other: {
|
|
||||||
files: [other, '!'+scripts, '!'+templates, '!'+styles, '!'+indexHTML, bowerFile, npmFile],
|
|
||||||
tasks: ['lock', 'build:debug', 'unlock']
|
|
||||||
},
|
|
||||||
|
|
||||||
options: {
|
|
||||||
// No need to debounce
|
|
||||||
debounceDelay: 0,
|
|
||||||
// When we don't have inotify
|
|
||||||
interval: 100,
|
|
||||||
livereload: liveReloadPort
|
|
||||||
}
|
|
||||||
};
|
|
16
tasks/options/yuidoc.js
vendored
16
tasks/options/yuidoc.js
vendored
|
@ -1,16 +0,0 @@
|
||||||
var grunt = require('grunt');
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
debug: {
|
|
||||||
name: '<%= package.name %>',
|
|
||||||
description: '<%= package.description %>',
|
|
||||||
version: '<%= package.version %>',
|
|
||||||
url: '<%= package.docURL %>/',
|
|
||||||
logo: 'http://emberjs.com/images/ember_logo.png',
|
|
||||||
options: {
|
|
||||||
paths: ['app/'],
|
|
||||||
outdir: './docs',
|
|
||||||
themedir: './node_modules/yuidoc-theme-blue'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
17
testem.json
17
testem.json
|
@ -1,14 +1,11 @@
|
||||||
{
|
{
|
||||||
"framework": "qunit",
|
"framework": "qunit",
|
||||||
"test_page": "tmp/result/tests/index.html",
|
"test_page": "tests/index.html",
|
||||||
"routes": {
|
"launch_in_ci": [
|
||||||
"/tests/tests.js": "tmp/result/tests/tests.js",
|
"PhantomJS"
|
||||||
"/assets/app.js": "tmp/result/assets/app.js",
|
|
||||||
"/assets/templates.js": "tmp/result/assets/templates.js",
|
|
||||||
"/assets/app.css": "tmp/result/assets/app.css"
|
|
||||||
},
|
|
||||||
"src_files": [
|
|
||||||
"tmp/result/**/*.js"
|
|
||||||
],
|
],
|
||||||
"launch_in_dev": ["PhantomJS", "Chrome"]
|
"launch_in_dev": [
|
||||||
|
"PhantomJS",
|
||||||
|
"Chrome"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,14 +4,11 @@
|
||||||
"window",
|
"window",
|
||||||
"location",
|
"location",
|
||||||
"setTimeout",
|
"setTimeout",
|
||||||
"Ember",
|
|
||||||
"Em",
|
|
||||||
"$",
|
"$",
|
||||||
|
"-Promise",
|
||||||
"QUnit",
|
"QUnit",
|
||||||
"define",
|
"define",
|
||||||
"console",
|
"console",
|
||||||
"require",
|
|
||||||
"requirejs",
|
|
||||||
"equal",
|
"equal",
|
||||||
"notEqual",
|
"notEqual",
|
||||||
"notStrictEqual",
|
"notStrictEqual",
|
||||||
|
@ -27,6 +24,9 @@
|
||||||
"ok",
|
"ok",
|
||||||
"strictEqual",
|
"strictEqual",
|
||||||
"module",
|
"module",
|
||||||
|
"moduleFor",
|
||||||
|
"moduleForComponent",
|
||||||
|
"moduleForModel",
|
||||||
"process",
|
"process",
|
||||||
"expect",
|
"expect",
|
||||||
"visit",
|
"visit",
|
||||||
|
@ -34,16 +34,21 @@
|
||||||
"fillIn",
|
"fillIn",
|
||||||
"click",
|
"click",
|
||||||
"keyEvent",
|
"keyEvent",
|
||||||
|
"triggerEvent",
|
||||||
"find",
|
"find",
|
||||||
|
"findWithAssert",
|
||||||
"wait",
|
"wait",
|
||||||
"DS",
|
"DS",
|
||||||
"keyEvent",
|
|
||||||
"isolatedContainer",
|
"isolatedContainer",
|
||||||
"startApp"
|
"startApp",
|
||||||
|
"andThen",
|
||||||
|
"currentURL",
|
||||||
|
"currentPath",
|
||||||
|
"currentRouteName"
|
||||||
],
|
],
|
||||||
"node" : false,
|
"node": false,
|
||||||
"browser" : false,
|
"browser": false,
|
||||||
"boss" : true,
|
"boss": true,
|
||||||
"curly": false,
|
"curly": false,
|
||||||
"debug": false,
|
"debug": false,
|
||||||
"devel": false,
|
"devel": false,
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import Resolver from 'ember/resolver';
|
import Resolver from 'ember/resolver';
|
||||||
|
import config from '../../config/environment';
|
||||||
|
|
||||||
var resolver = Resolver.create();
|
var resolver = Resolver.create();
|
||||||
|
|
||||||
resolver.namespace = {
|
resolver.namespace = {
|
||||||
modulePrefix: 'croodle'
|
modulePrefix: config.modulePrefix,
|
||||||
|
podModulePrefix: config.podModulePrefix
|
||||||
};
|
};
|
||||||
|
|
||||||
export default resolver;
|
export default resolver;
|
||||||
|
|
|
@ -1,21 +1,19 @@
|
||||||
import Application from 'croodle/app';
|
import Ember from 'ember';
|
||||||
import Router from 'croodle/router';
|
import Application from '../../app';
|
||||||
|
import Router from '../../router';
|
||||||
|
import config from '../../config/environment';
|
||||||
|
|
||||||
function startApp(attrs) {
|
export default function startApp(attrs) {
|
||||||
var App;
|
var App;
|
||||||
|
|
||||||
var attributes = Ember.merge({
|
var attributes = Ember.merge({}, config.APP);
|
||||||
// useful Test defaults
|
attributes = Ember.merge(attributes, attrs); // use defaults, but you can override;
|
||||||
rootElement: '#ember-testing',
|
|
||||||
LOG_ACTIVE_GENERATION:false,
|
|
||||||
LOG_VIEW_LOOKUPS: false
|
|
||||||
}, attrs); // but you can override;
|
|
||||||
|
|
||||||
Router.reopen({
|
Router.reopen({
|
||||||
location: 'none'
|
location: 'none'
|
||||||
});
|
});
|
||||||
|
|
||||||
Ember.run(function(){
|
Ember.run(function() {
|
||||||
App = Application.create(attributes);
|
App = Application.create(attributes);
|
||||||
App.setupForTesting();
|
App.setupForTesting();
|
||||||
App.injectTestHelpers();
|
App.injectTestHelpers();
|
||||||
|
@ -25,5 +23,3 @@ function startApp(attrs) {
|
||||||
|
|
||||||
return App;
|
return App;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default startApp;
|
|
||||||
|
|
45
tests/index.html
Normal file
45
tests/index.html
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<title>Croodle Tests</title>
|
||||||
|
<meta name="description" content="">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
{{content-for 'head'}}
|
||||||
|
{{content-for 'test-head'}}
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="assets/vendor.css">
|
||||||
|
<link rel="stylesheet" href="assets/croodle.css">
|
||||||
|
<link rel="stylesheet" href="assets/test-support.css">
|
||||||
|
<style>
|
||||||
|
#ember-testing-container {
|
||||||
|
position: absolute;
|
||||||
|
background: white;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 640px;
|
||||||
|
height: 384px;
|
||||||
|
overflow: auto;
|
||||||
|
z-index: 9999;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
#ember-testing {
|
||||||
|
zoom: 50%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="qunit"></div>
|
||||||
|
<div id="qunit-fixture"></div>
|
||||||
|
|
||||||
|
{{content-for 'body'}}
|
||||||
|
{{content-for 'test-body'}}
|
||||||
|
<script src="assets/vendor.js"></script>
|
||||||
|
<script src="assets/test-support.js"></script>
|
||||||
|
<script src="assets/croodle.js"></script>
|
||||||
|
<script src="testem.js"></script>
|
||||||
|
<script src="assets/test-loader.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -1,30 +1,12 @@
|
||||||
|
import resolver from './helpers/resolver';
|
||||||
|
import {
|
||||||
|
setResolver
|
||||||
|
} from 'ember-qunit';
|
||||||
|
|
||||||
|
setResolver(resolver);
|
||||||
|
|
||||||
document.write('<div id="ember-testing-container"><div id="ember-testing"></div></div>');
|
document.write('<div id="ember-testing-container"><div id="ember-testing"></div></div>');
|
||||||
|
|
||||||
var resolver = require('croodle/tests/helpers/resolver')['default'];
|
QUnit.config.urlConfig.push({ id: 'nocontainer', label: 'Hide container'});
|
||||||
require('ember-qunit').setResolver(resolver);
|
var containerVisibility = QUnit.urlParams.nocontainer ? 'hidden' : 'visible';
|
||||||
|
document.getElementById('ember-testing-container').style.visibility = containerVisibility;
|
||||||
|
|
||||||
window.startApp = require('croodle/tests/helpers/start-app')['default'];
|
|
||||||
window.isolatedContainer = require('ember-qunit/isolated-container')['default'];
|
|
||||||
|
|
||||||
function exists(selector, context) {
|
|
||||||
return !!find(selector, context).length;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getAssertionMessage(actual, expected, message) {
|
|
||||||
return message || QUnit.jsDump.parse(expected) + " expected but was " + QUnit.jsDump.parse(actual);
|
|
||||||
}
|
|
||||||
|
|
||||||
function equal(actual, expected, message) {
|
|
||||||
message = getAssertionMessage(actual, expected, message);
|
|
||||||
QUnit.equal.call(this, actual, expected, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
function strictEqual(actual, expected, message) {
|
|
||||||
message = getAssertionMessage(actual, expected, message);
|
|
||||||
QUnit.strictEqual.call(this, actual, expected, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
window.exists = exists;
|
|
||||||
window.equal = equal;
|
|
||||||
window.strictEqual = strictEqual;
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
// TODO: load based on params
|
|
||||||
Ember.keys(requirejs.entries).forEach(function(entry) {
|
|
||||||
if ((/\-test/).test(entry)) {
|
|
||||||
require(entry, null, null, true);
|
|
||||||
}
|
|
||||||
});
|
|
3
vendor/ember-shim.js
vendored
3
vendor/ember-shim.js
vendored
|
@ -1,3 +0,0 @@
|
||||||
define('ember', [ ], function(){
|
|
||||||
return Ember;
|
|
||||||
});
|
|
3
vendor/qunit-shim.js
vendored
3
vendor/qunit-shim.js
vendored
|
@ -1,3 +0,0 @@
|
||||||
define('qunit', [ ], function(){
|
|
||||||
return QUnit;
|
|
||||||
});
|
|
Loading…
Reference in a new issue