├── todo
├── log
│ └── .keep
├── app
│ ├── mailers
│ │ └── .keep
│ ├── models
│ │ ├── .keep
│ │ ├── concerns
│ │ │ └── .keep
│ │ └── task.rb
│ ├── assets
│ │ ├── images
│ │ │ └── .keep
│ │ ├── javascripts
│ │ │ ├── tasks.js
│ │ │ └── application.js
│ │ └── stylesheets
│ │ │ ├── tasks.scss
│ │ │ └── application.css
│ ├── controllers
│ │ ├── concerns
│ │ │ └── .keep
│ │ ├── session_controller.rb
│ │ ├── application_controller.rb
│ │ └── tasks_controller.rb
│ ├── helpers
│ │ ├── tasks_helper.rb
│ │ ├── session_helper.rb
│ │ └── application_helper.rb
│ ├── serializers
│ │ └── task_serializer.rb
│ └── views
│ │ └── layouts
│ │ └── application.html.erb
├── lib
│ ├── assets
│ │ └── .keep
│ └── tasks
│ │ └── .keep
├── public
│ ├── favicon.ico
│ ├── robots.txt
│ ├── 500.html
│ ├── 422.html
│ └── 404.html
├── test
│ ├── helpers
│ │ └── .keep
│ ├── mailers
│ │ └── .keep
│ ├── models
│ │ ├── .keep
│ │ └── task_test.rb
│ ├── controllers
│ │ ├── .keep
│ │ ├── tasks_controller_test.rb
│ │ └── session_controller_test.rb
│ ├── fixtures
│ │ ├── .keep
│ │ └── tasks.yml
│ ├── integration
│ │ └── .keep
│ └── test_helper.rb
├── vendor
│ └── assets
│ │ ├── javascripts
│ │ └── .keep
│ │ └── stylesheets
│ │ └── .keep
├── bin
│ ├── rake
│ ├── bundle
│ ├── rails
│ └── setup
├── config
│ ├── boot.rb
│ ├── initializers
│ │ ├── cookies_serializer.rb
│ │ ├── session_store.rb
│ │ ├── mime_types.rb
│ │ ├── filter_parameter_logging.rb
│ │ ├── backtrace_silencers.rb
│ │ ├── assets.rb
│ │ ├── wrap_parameters.rb
│ │ └── inflections.rb
│ ├── environment.rb
│ ├── database.yml
│ ├── locales
│ │ └── en.yml
│ ├── secrets.yml
│ ├── application.rb
│ ├── environments
│ │ ├── development.rb
│ │ ├── test.rb
│ │ └── production.rb
│ └── routes.rb
├── config.ru
├── Rakefile
├── db
│ ├── migrate
│ │ └── 20150418153320_create_tasks.rb
│ ├── seeds.rb
│ └── schema.rb
├── .gitignore
├── README.rdoc
├── Gemfile
└── Gemfile.lock
├── front
├── vendor
│ └── .gitkeep
├── app
│ ├── helpers
│ │ └── .gitkeep
│ ├── models
│ │ ├── .gitkeep
│ │ └── todo.js
│ ├── routes
│ │ ├── .gitkeep
│ │ ├── application.js
│ │ ├── todos.js
│ │ └── archived.js
│ ├── views
│ │ └── .gitkeep
│ ├── components
│ │ ├── .gitkeep
│ │ └── todo-item.js
│ ├── controllers
│ │ ├── .gitkeep
│ │ ├── archived.js
│ │ ├── application.js
│ │ ├── session
│ │ │ └── new.js
│ │ └── todos.js
│ ├── templates
│ │ ├── components
│ │ │ ├── .gitkeep
│ │ │ └── todo-item.hbs
│ │ ├── archived.hbs
│ │ ├── todos.hbs
│ │ ├── application.hbs
│ │ └── session
│ │ │ └── new.hbs
│ ├── styles
│ │ ├── app.scss
│ │ ├── archived.scss
│ │ ├── _foundation.scss
│ │ └── _settings.scss
│ ├── services
│ │ ├── logger.js
│ │ └── session.js
│ ├── adapters
│ │ └── application.js
│ ├── initializers
│ │ ├── logger.js
│ │ └── session.js
│ ├── mixins
│ │ ├── auth-router.js
│ │ └── auth.js
│ ├── router.js
│ ├── app.js
│ └── index.html
├── tests
│ ├── unit
│ │ ├── .gitkeep
│ │ ├── routes
│ │ │ ├── todos-test.js
│ │ │ ├── archived-test.js
│ │ │ └── application-test.js
│ │ ├── models
│ │ │ └── todo-test.js
│ │ ├── mixins
│ │ │ ├── auth-test.js
│ │ │ └── auth-router-test.js
│ │ ├── controllers
│ │ │ ├── todos-test.js
│ │ │ ├── archived-test.js
│ │ │ └── application-test.js
│ │ ├── adapters
│ │ │ └── application-test.js
│ │ └── components
│ │ │ └── todo-item-test.js
│ ├── test-helper.js
│ ├── helpers
│ │ ├── resolver.js
│ │ └── start-app.js
│ ├── .jshintrc
│ └── index.html
├── public
│ ├── robots.txt
│ └── crossdomain.xml
├── .bowerrc
├── testem.json
├── .ember-cli
├── .gitignore
├── .travis.yml
├── bower.json
├── .editorconfig
├── .jshintrc
├── Brocfile.js
├── package.json
├── config
│ └── environment.js
└── README.md
├── .gitignore
└── README.md
/todo/log/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/front/vendor/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/todo/app/mailers/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/todo/app/models/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/todo/lib/assets/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/todo/lib/tasks/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/todo/public/favicon.ico:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/todo/test/helpers/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/todo/test/mailers/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/todo/test/models/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/front/app/helpers/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/front/app/models/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/front/app/routes/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/front/app/views/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/front/tests/unit/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/todo/app/assets/images/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/todo/test/controllers/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/todo/test/fixtures/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/todo/test/integration/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/front/app/components/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/front/app/controllers/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/todo/app/models/concerns/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/todo/app/controllers/concerns/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/todo/vendor/assets/javascripts/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/todo/vendor/assets/stylesheets/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/front/app/templates/components/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/todo/app/helpers/tasks_helper.rb:
--------------------------------------------------------------------------------
1 | module TasksHelper
2 | end
3 |
--------------------------------------------------------------------------------
/todo/app/helpers/session_helper.rb:
--------------------------------------------------------------------------------
1 | module SessionHelper
2 | end
3 |
--------------------------------------------------------------------------------
/front/public/robots.txt:
--------------------------------------------------------------------------------
1 | # http://www.robotstxt.org
2 | User-agent: *
3 |
--------------------------------------------------------------------------------
/todo/app/helpers/application_helper.rb:
--------------------------------------------------------------------------------
1 | module ApplicationHelper
2 | end
3 |
--------------------------------------------------------------------------------
/front/.bowerrc:
--------------------------------------------------------------------------------
1 | {
2 | "directory": "bower_components",
3 | "analytics": false
4 | }
5 |
--------------------------------------------------------------------------------
/front/app/styles/app.scss:
--------------------------------------------------------------------------------
1 | @import "settings";
2 |
3 | @import "foundation";
4 | @import "archived";
5 |
--------------------------------------------------------------------------------
/todo/app/models/task.rb:
--------------------------------------------------------------------------------
1 | class Task < ActiveRecord::Base
2 | validates_presence_of :title
3 | end
4 |
--------------------------------------------------------------------------------
/todo/bin/rake:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require_relative '../config/boot'
3 | require 'rake'
4 | Rake.application.run
5 |
--------------------------------------------------------------------------------
/todo/bin/bundle:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
3 | load Gem.bin_path('bundler', 'bundle')
4 |
--------------------------------------------------------------------------------
/front/tests/test-helper.js:
--------------------------------------------------------------------------------
1 | import resolver from './helpers/resolver';
2 | import {
3 | setResolver
4 | } from 'ember-qunit';
5 |
6 | setResolver(resolver);
7 |
--------------------------------------------------------------------------------
/todo/config/boot.rb:
--------------------------------------------------------------------------------
1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
2 |
3 | require 'bundler/setup' # Set up gems listed in the Gemfile.
4 |
--------------------------------------------------------------------------------
/todo/app/serializers/task_serializer.rb:
--------------------------------------------------------------------------------
1 | class TaskSerializer < ActiveModel::Serializer
2 | attributes :id, :title, :created_at, :updated_at, :is_done, :is_archive
3 | end
4 |
--------------------------------------------------------------------------------
/todo/bin/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | APP_PATH = File.expand_path('../../config/application', __FILE__)
3 | require_relative '../config/boot'
4 | require 'rails/commands'
5 |
--------------------------------------------------------------------------------
/todo/test/models/task_test.rb:
--------------------------------------------------------------------------------
1 | require 'test_helper'
2 |
3 | class TaskTest < ActiveSupport::TestCase
4 | # test "the truth" do
5 | # assert true
6 | # end
7 | end
8 |
--------------------------------------------------------------------------------
/front/app/routes/application.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 | import AuthRouter from '../mixins/auth-router';
3 |
4 | export default Ember.Route.extend(AuthRouter, {
5 | });
6 |
--------------------------------------------------------------------------------
/todo/config.ru:
--------------------------------------------------------------------------------
1 | # This file is used by Rack-based servers to start the application.
2 |
3 | require ::File.expand_path('../config/environment', __FILE__)
4 | run Rails.application
5 |
--------------------------------------------------------------------------------
/todo/config/initializers/cookies_serializer.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | Rails.application.config.action_dispatch.cookies_serializer = :json
4 |
--------------------------------------------------------------------------------
/front/app/templates/archived.hbs:
--------------------------------------------------------------------------------
1 |
2 | {{#each t in archived}}
3 | {{todo-item tagName='li' classNames='item' todo=t isEdit=false undo=true}}
4 | {{/each}}
5 |
6 | {{outlet}}
7 |
--------------------------------------------------------------------------------
/todo/app/assets/javascripts/tasks.js:
--------------------------------------------------------------------------------
1 | // Place all the behaviors and hooks related to the matching controller here.
2 | // All this logic will automatically be available in application.js.
3 |
--------------------------------------------------------------------------------
/todo/config/initializers/session_store.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | Rails.application.config.session_store :cookie_store, key: '_todo_session'
4 |
--------------------------------------------------------------------------------
/todo/config/environment.rb:
--------------------------------------------------------------------------------
1 | # Load the Rails application.
2 | require File.expand_path('../application', __FILE__)
3 |
4 | # Initialize the Rails application.
5 | Rails.application.initialize!
6 |
--------------------------------------------------------------------------------
/front/app/services/logger.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 |
3 | export default Ember.Service.extend({
4 | log(msg) {
5 | console.log(`${new Date().toISOString()}: ${msg}`);
6 | }
7 | });
8 |
--------------------------------------------------------------------------------
/todo/test/controllers/tasks_controller_test.rb:
--------------------------------------------------------------------------------
1 | require 'test_helper'
2 |
3 | class TasksControllerTest < ActionController::TestCase
4 | # test "the truth" do
5 | # assert true
6 | # end
7 | end
8 |
--------------------------------------------------------------------------------
/todo/config/initializers/mime_types.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new mime types for use in respond_to blocks:
4 | # Mime::Type.register "text/richtext", :rtf
5 |
--------------------------------------------------------------------------------
/todo/app/assets/stylesheets/tasks.scss:
--------------------------------------------------------------------------------
1 | // Place all the styles related to the tasks controller here.
2 | // They will automatically be included in application.css.
3 | // You can use Sass (SCSS) here: http://sass-lang.com/
4 |
--------------------------------------------------------------------------------
/front/app/routes/todos.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 | import AuthRouter from '../mixins/auth-router';
3 |
4 | export default Ember.Route.extend(AuthRouter, {
5 | model() {
6 | return this.store.findAll('todo');
7 | }
8 | });
9 |
--------------------------------------------------------------------------------
/front/testem.json:
--------------------------------------------------------------------------------
1 | {
2 | "framework": "qunit",
3 | "test_page": "tests/index.html?hidepassed",
4 | "launch_in_ci": [
5 | "PhantomJS"
6 | ],
7 | "launch_in_dev": [
8 | "PhantomJS",
9 | "Chrome"
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/todo/public/robots.txt:
--------------------------------------------------------------------------------
1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
2 | #
3 | # To ban all spiders from the entire site uncomment the next two lines:
4 | # User-agent: *
5 | # Disallow: /
6 |
--------------------------------------------------------------------------------
/front/app/adapters/application.js:
--------------------------------------------------------------------------------
1 | import DS from 'ember-data';
2 |
3 | export default DS.ActiveModelAdapter.extend({
4 | //host: 'http://127.0.0.1:3000'
5 | //export default DS.RESTAdapter.extend({
6 | //export default DS.FixtureAdapter.extend({
7 | });
8 |
--------------------------------------------------------------------------------
/todo/config/initializers/filter_parameter_logging.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Configure sensitive parameters which will be filtered from the log file.
4 | Rails.application.config.filter_parameters += [:password]
5 |
--------------------------------------------------------------------------------
/todo/Rakefile:
--------------------------------------------------------------------------------
1 | # Add your own tasks in files placed in lib/tasks ending in .rake,
2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3 |
4 | require File.expand_path('../config/application', __FILE__)
5 |
6 | Rails.application.load_tasks
7 |
--------------------------------------------------------------------------------
/front/.ember-cli:
--------------------------------------------------------------------------------
1 | {
2 | /**
3 | Ember CLI sends analytics information by default. The data is completely
4 | anonymous, but there are times when you might want to disable this behavior.
5 |
6 | Setting `disableAnalytics` to true will prevent any data from being sent.
7 | */
8 | "disableAnalytics": true
9 | }
10 |
--------------------------------------------------------------------------------
/front/tests/helpers/resolver.js:
--------------------------------------------------------------------------------
1 | import Resolver from 'ember/resolver';
2 | import config from '../../config/environment';
3 |
4 | var resolver = Resolver.create();
5 |
6 | resolver.namespace = {
7 | modulePrefix: config.modulePrefix,
8 | podModulePrefix: config.podModulePrefix
9 | };
10 |
11 | export default resolver;
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 | .idea/
3 |
4 | # compiled output
5 | dist
6 | tmp
7 |
8 | # dependencies
9 | node_modules
10 | bower_components
11 |
12 | # misc
13 | .sass-cache
14 | connect.lock
15 | coverage/*
16 | libpeerconnection.log
17 | npm-debug.log
18 | testem.log
19 |
--------------------------------------------------------------------------------
/todo/db/migrate/20150418153320_create_tasks.rb:
--------------------------------------------------------------------------------
1 | class CreateTasks < ActiveRecord::Migration
2 | def change
3 | create_table :tasks do |t|
4 | t.string :title
5 | t.boolean :is_done, default: false
6 | t.boolean :is_archive, default: false
7 |
8 | t.timestamps null: false
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/front/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /dist
5 | /tmp
6 |
7 | # dependencies
8 | /node_modules
9 | /bower_components
10 |
11 | # misc
12 | /.sass-cache
13 | /connect.lock
14 | /coverage/*
15 | /libpeerconnection.log
16 | npm-debug.log
17 | testem.log
18 |
--------------------------------------------------------------------------------
/front/app/controllers/archived.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 |
3 | export default Ember.ArrayController.extend({
4 | // 这种语法现在还无法使用到 es6 中的 function 简写, 因为需要这种语法的时候, 其需要的是 property 不是 function
5 | archived: function() {
6 | return this.store.filter('todo', function(todo) {
7 | return todo.get('isArchive');
8 | });
9 | }.property()
10 | });
11 |
--------------------------------------------------------------------------------
/front/tests/unit/routes/todos-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleFor,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleFor('route:todos', {
7 | // Specify the other units that are required for this test.
8 | // needs: ['controller:foo']
9 | });
10 |
11 | test('it exists', function(assert) {
12 | var route = this.subject();
13 | assert.ok(route);
14 | });
15 |
--------------------------------------------------------------------------------
/front/tests/unit/routes/archived-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleFor,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleFor('route:archived', {
7 | // Specify the other units that are required for this test.
8 | // needs: ['controller:foo']
9 | });
10 |
11 | test('it exists', function(assert) {
12 | var route = this.subject();
13 | assert.ok(route);
14 | });
15 |
--------------------------------------------------------------------------------
/front/tests/unit/routes/application-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleFor,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleFor('route:application', {
7 | // Specify the other units that are required for this test.
8 | // needs: ['controller:foo']
9 | });
10 |
11 | test('it exists', function(assert) {
12 | var route = this.subject();
13 | assert.ok(route);
14 | });
15 |
--------------------------------------------------------------------------------
/todo/db/seeds.rb:
--------------------------------------------------------------------------------
1 | # This file should contain all the record creation needed to seed the database with its default values.
2 | # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
3 | #
4 | # Examples:
5 | #
6 | # cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
7 | # Mayor.create(name: 'Emanuel', city: cities.first)
8 |
--------------------------------------------------------------------------------
/todo/test/test_helper.rb:
--------------------------------------------------------------------------------
1 | ENV['RAILS_ENV'] ||= 'test'
2 | require File.expand_path('../../config/environment', __FILE__)
3 | require 'rails/test_help'
4 |
5 | class ActiveSupport::TestCase
6 | # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
7 | fixtures :all
8 |
9 | # Add more helper methods to be used by all tests here...
10 | end
11 |
--------------------------------------------------------------------------------
/front/.travis.yml:
--------------------------------------------------------------------------------
1 | ---
2 | language: node_js
3 | node_js:
4 | - "0.12"
5 |
6 | sudo: false
7 |
8 | cache:
9 | directories:
10 | - node_modules
11 |
12 | before_install:
13 | - "npm config set spin false"
14 | - "npm install -g npm@^2"
15 |
16 | install:
17 | - npm install -g bower
18 | - npm install
19 | - bower install
20 |
21 | script:
22 | - npm test
23 |
--------------------------------------------------------------------------------
/front/tests/unit/models/todo-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleForModel,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleForModel('todo', {
7 | // Specify the other units that are required for this test.
8 | needs: []
9 | });
10 |
11 | test('it exists', function(assert) {
12 | var model = this.subject();
13 | // var store = this.store();
14 | assert.ok(!!model);
15 | });
16 |
--------------------------------------------------------------------------------
/todo/app/views/layouts/application.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Todo
5 | <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
6 | <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
7 | <%= csrf_meta_tags %>
8 |
9 |
10 |
11 | <%= yield %>
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/front/tests/unit/mixins/auth-test.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 | import AuthMixin from '../../../mixins/auth';
3 | import { module, test } from 'qunit';
4 |
5 | module('AuthMixin');
6 |
7 | // Replace this with your real tests.
8 | test('it works', function(assert) {
9 | var AuthObject = Ember.Object.extend(AuthMixin);
10 | var subject = AuthObject.create();
11 | assert.ok(subject);
12 | });
13 |
--------------------------------------------------------------------------------
/front/tests/unit/controllers/todos-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleFor,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleFor('controller:todos', {
7 | // Specify the other units that are required for this test.
8 | // needs: ['controller:foo']
9 | });
10 |
11 | // Replace this with your real tests.
12 | test('it exists', function(assert) {
13 | var controller = this.subject();
14 | assert.ok(controller);
15 | });
16 |
--------------------------------------------------------------------------------
/todo/test/fixtures/tasks.yml:
--------------------------------------------------------------------------------
1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
2 |
3 | # This model initially had no columns defined. If you add columns to the
4 | # model remove the '{}' from the fixture names and add the columns immediately
5 | # below each fixture, per the syntax in the comments below
6 | #
7 | one: {}
8 | # column: value
9 | #
10 | two: {}
11 | # column: value
12 |
--------------------------------------------------------------------------------
/front/tests/unit/controllers/archived-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleFor,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleFor('controller:archived', {
7 | // Specify the other units that are required for this test.
8 | // needs: ['controller:foo']
9 | });
10 |
11 | // Replace this with your real tests.
12 | test('it exists', function(assert) {
13 | var controller = this.subject();
14 | assert.ok(controller);
15 | });
16 |
--------------------------------------------------------------------------------
/front/tests/unit/controllers/application-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleFor,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleFor('controller:application', {
7 | // Specify the other units that are required for this test.
8 | // needs: ['controller:foo']
9 | });
10 |
11 | // Replace this with your real tests.
12 | test('it exists', function(assert) {
13 | var controller = this.subject();
14 | assert.ok(controller);
15 | });
16 |
--------------------------------------------------------------------------------
/front/app/controllers/application.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 | import Auth from '../mixins/auth';
3 |
4 | export default Ember.Controller.extend(Auth, {
5 |
6 | actions: {
7 | changeToken() {
8 | this.session.set('token', '123123123');
9 | console.log(this.session.get('token'));
10 | },
11 |
12 | logout() {
13 | console.log('logout');
14 | this.session.signout();
15 | }
16 | }
17 | });
18 |
--------------------------------------------------------------------------------
/front/app/initializers/logger.js:
--------------------------------------------------------------------------------
1 | export function initialize(container, application) {
2 | //application.inject('route', 'foo', 'service:foo');
3 | application.inject('route', 'logger', 'service:logger');
4 | application.inject('controller', 'logger', 'service:logger');
5 | application.inject('component:todo-item', 'logger', 'service:logger');
6 | }
7 |
8 | export default {
9 | name: 'logger',
10 | initialize: initialize
11 | };
12 |
--------------------------------------------------------------------------------
/front/tests/unit/adapters/application-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleFor,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleFor('adapter:application', 'ApplicationAdapter', {
7 | // Specify the other units that are required for this test.
8 | // needs: ['serializer:foo']
9 | });
10 |
11 | // Replace this with your real tests.
12 | test('it exists', function(assert) {
13 | var adapter = this.subject();
14 | assert.ok(adapter);
15 | });
16 |
--------------------------------------------------------------------------------
/front/tests/unit/mixins/auth-router-test.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 | import AuthRouterMixin from '../../../mixins/auth-router';
3 | import { module, test } from 'qunit';
4 |
5 | module('AuthRouterMixin');
6 |
7 | // Replace this with your real tests.
8 | test('it works', function(assert) {
9 | var AuthRouterObject = Ember.Object.extend(AuthRouterMixin);
10 | var subject = AuthRouterObject.create();
11 | assert.ok(subject);
12 | });
13 |
--------------------------------------------------------------------------------
/front/app/mixins/auth-router.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 |
3 | export default Ember.Mixin.create({
4 | beforeModel: function() {
5 | if(this.session.isAuthenticate()) {
6 | console.log('success authenticate');
7 | } else {
8 | // 不能在 Router 中设置字段, 需要在 Controller 中设置字段.
9 | // TODO: Ember 2.0(1.13) 中会变化
10 | this.session.set('error', 'Please login');
11 | this.transitionTo('session.new');
12 | }
13 | }
14 | });
15 |
--------------------------------------------------------------------------------
/todo/config/initializers/backtrace_silencers.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
5 |
6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
7 | # Rails.backtrace_cleaner.remove_silencers!
8 |
--------------------------------------------------------------------------------
/front/app/router.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 | import config from './config/environment';
3 |
4 | var Router = Ember.Router.extend({
5 | location: config.locationType
6 | });
7 |
8 | export default Router.map(function() {
9 | // 无法使用 arrays 写法
10 | //export default Router.map(() => {
11 | this.route('todos');
12 | this.route('archived');
13 | this.route('session', function() {
14 | this.route('new');
15 | this.route('logout');
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/front/app/app.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 | import Resolver from 'ember/resolver';
3 | import loadInitializers from 'ember/load-initializers';
4 | import config from './config/environment';
5 |
6 | var App;
7 |
8 | Ember.MODEL_FACTORY_INJECTIONS = true;
9 |
10 | App = Ember.Application.extend({
11 | modulePrefix: config.modulePrefix,
12 | podModulePrefix: config.podModulePrefix,
13 | Resolver: Resolver
14 | });
15 |
16 | loadInitializers(App, config.modulePrefix);
17 |
18 | export default App;
19 |
--------------------------------------------------------------------------------
/front/app/initializers/session.js:
--------------------------------------------------------------------------------
1 | export function initialize(container, application) {
2 | // application.inject('route', 'foo', 'service:foo');
3 | application.inject('route', 'session', 'service:session');
4 | application.inject('controller', 'session', 'service:session');
5 | application.inject('mixins:auth', 'session', 'service:session');
6 | application.inject('mixins:auth-router', 'session', 'service:session');
7 | }
8 |
9 | export default {
10 | name: 'session',
11 | initialize: initialize
12 | };
13 |
--------------------------------------------------------------------------------
/front/app/mixins/auth.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 |
3 | export default Ember.Mixin.create({
4 | error: function() {
5 | return this.session.get('error');
6 | }.property('session.error'),
7 |
8 | isAuthenticate: function() {
9 | console.log('isAuthenticate in auth mixin');
10 | return this.session.isAuthenticate();
11 | }.property('session.token'),
12 |
13 | // 登陆用户的名字
14 | currentUsername: function() {
15 | return this.session.get('email');
16 | }.property('session.email')
17 | });
18 |
--------------------------------------------------------------------------------
/front/app/styles/archived.scss:
--------------------------------------------------------------------------------
1 | ul {
2 | list-style-type: disc;
3 | list-style: none;
4 |
5 | li {
6 | /*display: inline-block;*/
7 |
8 | &.is-done {
9 | color: gray;
10 | text-decoration: line-through;
11 | }
12 |
13 | /* button */
14 | .button {
15 | margin-bottom: 0;
16 | }
17 | }
18 | };
19 |
20 | li.item {
21 | cursor: pointer;
22 | padding: 5px;
23 | border: solid 1px;
24 | margin-top: 1px;
25 | }
26 |
27 |
28 | nav ul li {
29 | display: inline;
30 |
31 | a.active {
32 | color: blue;
33 | }
34 | }
35 |
36 |
--------------------------------------------------------------------------------
/todo/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files.
2 | #
3 | # If you find yourself ignoring temporary files generated by your text editor
4 | # or operating system, you probably want to add a global ignore instead:
5 | # git config --global core.excludesfile '~/.gitignore_global'
6 |
7 | # Ignore bundler config.
8 | /.bundle
9 |
10 | # Ignore the default SQLite database.
11 | /db/*.sqlite3
12 | /db/*.sqlite3-journal
13 |
14 | # Ignore all logfiles and tempfiles.
15 | /log/*
16 | !/log/.keep
17 | /tmp
18 |
--------------------------------------------------------------------------------
/todo/config/initializers/assets.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Version of your assets, change this if you want to expire all your assets.
4 | Rails.application.config.assets.version = '1.0'
5 |
6 | # Add additional assets to the asset load path
7 | # Rails.application.config.assets.paths << Emoji.images_path
8 |
9 | # Precompile additional assets.
10 | # application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
11 | # Rails.application.config.assets.precompile += %w( search.js )
12 |
--------------------------------------------------------------------------------
/todo/config/initializers/wrap_parameters.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # This file contains settings for ActionController::ParamsWrapper which
4 | # is enabled by default.
5 |
6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
7 | ActiveSupport.on_load(:action_controller) do
8 | wrap_parameters format: [:json] if respond_to?(:wrap_parameters)
9 | end
10 |
11 | # To enable root element in JSON for ActiveRecord objects.
12 | # ActiveSupport.on_load(:active_record) do
13 | # self.include_root_in_json = true
14 | # end
15 |
--------------------------------------------------------------------------------
/front/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "todos",
3 | "dependencies": {
4 | "ember": "1.13.0-beta.1",
5 | "ember-cli-shims": "ember-cli/ember-cli-shims#0.0.3",
6 | "ember-cli-test-loader": "ember-cli-test-loader#0.1.3",
7 | "ember-data": "1.0.0-beta.17",
8 | "ember-load-initializers": "ember-cli/ember-load-initializers#0.1.4",
9 | "ember-qunit": "0.3.3",
10 | "ember-qunit-notifications": "0.0.7",
11 | "ember-resolver": "~0.1.15",
12 | "jquery": ">= 1.7.0",
13 | "loader.js": "ember-cli/loader.js#3.2.0",
14 | "qunit": "~1.17.1",
15 |
16 | "foundation": "~5.5.0"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/front/tests/unit/components/todo-item-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleForComponent,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleForComponent('todo-item', {
7 | // Specify the other units that are required for this test
8 | // needs: ['component:foo', 'helper:bar']
9 | });
10 |
11 | test('it renders', function(assert) {
12 | assert.expect(2);
13 |
14 | // Creates the component instance
15 | var component = this.subject();
16 | assert.equal(component._state, 'preRender');
17 |
18 | // Renders the component to the page
19 | this.render();
20 | assert.equal(component._state, 'inDOM');
21 | });
22 |
--------------------------------------------------------------------------------
/todo/README.rdoc:
--------------------------------------------------------------------------------
1 | == README
2 |
3 | This README would normally document whatever steps are necessary to get the
4 | application up and running.
5 |
6 | Things you may want to cover:
7 |
8 | * Ruby version
9 |
10 | * System dependencies
11 |
12 | * Configuration
13 |
14 | * Database creation
15 |
16 | * Database initialization
17 |
18 | * How to run the test suite
19 |
20 | * Services (job queues, cache servers, search engines, etc.)
21 |
22 | * Deployment instructions
23 |
24 | * ...
25 |
26 |
27 | Please feel free to use a different markup language if you do not plan to run
28 | rake doc:app.
29 |
--------------------------------------------------------------------------------
/front/tests/helpers/start-app.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 | import Application from '../../app';
3 | import Router from '../../router';
4 | import config from '../../config/environment';
5 |
6 | export default function startApp(attrs) {
7 | var application;
8 |
9 | var attributes = Ember.merge({}, config.APP);
10 | attributes = Ember.merge(attributes, attrs); // use defaults, but you can override;
11 |
12 | Ember.run(function() {
13 | application = Application.create(attributes);
14 | application.setupForTesting();
15 | application.injectTestHelpers();
16 | });
17 |
18 | return application;
19 | }
20 |
--------------------------------------------------------------------------------
/todo/config/database.yml:
--------------------------------------------------------------------------------
1 | # SQLite version 3.x
2 | # gem install sqlite3
3 | #
4 | # Ensure the SQLite 3 gem is defined in your Gemfile
5 | # gem 'sqlite3'
6 | #
7 | default: &default
8 | adapter: sqlite3
9 | pool: 5
10 | timeout: 5000
11 |
12 | development:
13 | <<: *default
14 | database: db/development.sqlite3
15 |
16 | # Warning: The database defined as "test" will be erased and
17 | # re-generated from your development database when you run "rake".
18 | # Do not set this db to the same as development or production.
19 | test:
20 | <<: *default
21 | database: db/test.sqlite3
22 |
23 | production:
24 | <<: *default
25 | database: db/production.sqlite3
26 |
--------------------------------------------------------------------------------
/front/app/controllers/session/new.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 | import Auth from '../../mixins/auth';
3 |
4 | export default Ember.Controller.extend(Auth, {
5 | email: "",
6 | password: '',
7 | errors: null,
8 |
9 | actions: {
10 | login() {
11 | this.set('errors', null);
12 | this.session.signin(this.get('email'), this.get('password'))
13 | .done(() => {
14 | this.set('errors', null);
15 | this.transitionTo('todos');
16 | }).fail((xhr) => {
17 | this.set('errors', xhr.responseText);
18 | });
19 | },
20 |
21 | logout() {
22 | console.log('11111111111111');
23 | }
24 | }
25 | });
26 |
--------------------------------------------------------------------------------
/front/public/crossdomain.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
15 |
16 |
--------------------------------------------------------------------------------
/front/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 |
8 | [*]
9 | end_of_line = lf
10 | charset = utf-8
11 | trim_trailing_whitespace = true
12 | insert_final_newline = true
13 | indent_style = space
14 | indent_size = 2
15 |
16 | [*.js]
17 | indent_style = space
18 | indent_size = 2
19 |
20 | [*.hbs]
21 | insert_final_newline = false
22 | indent_style = space
23 | indent_size = 2
24 |
25 | [*.css]
26 | indent_style = space
27 | indent_size = 2
28 |
29 | [*.html]
30 | indent_style = space
31 | indent_size = 2
32 |
33 | [*.{diff,md}]
34 | trim_trailing_whitespace = false
35 |
--------------------------------------------------------------------------------
/front/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "predef": [
3 | "document",
4 | "window",
5 | "-Promise",
6 | "Cookies",
7 | "Ember"
8 | ],
9 | "browser": true,
10 | "boss": true,
11 | "curly": true,
12 | "debug": false,
13 | "devel": true,
14 | "eqeqeq": true,
15 | "evil": true,
16 | "forin": false,
17 | "immed": false,
18 | "laxbreak": false,
19 | "newcap": true,
20 | "noarg": true,
21 | "noempty": false,
22 | "nonew": false,
23 | "nomen": false,
24 | "onevar": false,
25 | "plusplus": false,
26 | "regexp": false,
27 | "undef": true,
28 | "sub": true,
29 | "strict": false,
30 | "white": false,
31 | "eqnull": true,
32 | "esnext": true,
33 | "unused": true
34 | }
35 |
--------------------------------------------------------------------------------
/front/app/routes/archived.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 | import AuthRouter from '../mixins/auth-router';
3 |
4 | export default Ember.Route.extend(AuthRouter, {
5 | model() {
6 | //return this.store.filter('todo', function(todo) {
7 | //console.log(todo.get('isArchive'));
8 | //return todo.get('isArchive');
9 | //});
10 |
11 | // filter 仅仅是 Store 的方法, 是用于在 Store 这个 Center Reponsitry 中寻找需要的数据用的.
12 | // 而 Route 的主要职责是相仿设法通过 JSON-API 或者外部其他地方获取到合适的数据.
13 | // 例如数据的分页, 查询, 搜索都应该在 Route 中处理.
14 | return this.store.findAll('todo');
15 | // 可以先让 Store findAll 一下, 然后再进行 filter 给下层使用
16 | //return this.store.filter('todo', function(todo) {
17 | //return todo.get('isArchive');
18 | //});
19 | }
20 | });
21 |
--------------------------------------------------------------------------------
/front/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Todos
7 |
8 |
9 |
10 | {{content-for 'head'}}
11 |
12 |
13 |
14 |
15 | {{content-for 'head-footer'}}
16 |
17 |
18 | {{content-for 'body'}}
19 |
20 |
21 |
22 |
23 | {{content-for 'body-footer'}}
24 |
25 |
26 |
--------------------------------------------------------------------------------
/todo/config/initializers/inflections.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new inflection rules using the following format. Inflections
4 | # are locale specific, and you may define rules for as many different
5 | # locales as you wish. All of these examples are active by default:
6 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
7 | # inflect.plural /^(ox)$/i, '\1en'
8 | # inflect.singular /^(ox)en/i, '\1'
9 | # inflect.irregular 'person', 'people'
10 | # inflect.uncountable %w( fish sheep )
11 | # end
12 |
13 | # These inflection rules are supported but not enabled by default:
14 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
15 | # inflect.acronym 'RESTful'
16 | # end
17 |
--------------------------------------------------------------------------------
/todo/config/locales/en.yml:
--------------------------------------------------------------------------------
1 | # Files in the config/locales directory are used for internationalization
2 | # and are automatically loaded by Rails. If you want to use locales other
3 | # than English, add the necessary files in this directory.
4 | #
5 | # To use the locales, use `I18n.t`:
6 | #
7 | # I18n.t 'hello'
8 | #
9 | # In views, this is aliased to just `t`:
10 | #
11 | # <%= t('hello') %>
12 | #
13 | # To use a different locale, set it with `I18n.locale`:
14 | #
15 | # I18n.locale = :es
16 | #
17 | # This would use the information in config/locales/es.yml.
18 | #
19 | # To learn more, please read the Rails Internationalization guide
20 | # available at http://guides.rubyonrails.org/i18n.html.
21 |
22 | en:
23 | hello: "Hello world"
24 |
--------------------------------------------------------------------------------
/todo/app/assets/javascripts/application.js:
--------------------------------------------------------------------------------
1 | // This is a manifest file that'll be compiled into application.js, which will include all the files
2 | // listed below.
3 | //
4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5 | // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6 | //
7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8 | // compiled file.
9 | //
10 | // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
11 | // about supported directives.
12 | //
13 | //= require jquery
14 | //= require jquery_ujs
15 | //= require turbolinks
16 | //= require_tree .
17 |
--------------------------------------------------------------------------------
/todo/app/assets/stylesheets/application.css:
--------------------------------------------------------------------------------
1 | /*
2 | * This is a manifest file that'll be compiled into application.css, which will include all the files
3 | * listed below.
4 | *
5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6 | * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7 | *
8 | * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9 | * compiled file so the styles you add here take precedence over styles defined in any styles
10 | * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
11 | * file per style scope.
12 | *
13 | *= require_tree .
14 | *= require_self
15 | */
16 |
--------------------------------------------------------------------------------
/front/app/templates/todos.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{#each t in unArchive}}
5 | {{todo-item todo=t}}
6 | {{/each}}
7 | -
8 | Create New Todo: {{input value=todo.title key-press='newTodo'}}
9 | {{#unless todo.errors.isEmpty}}
10 |
11 | {{#each message in todo.errors.messages}}
12 | {{message}}
13 | {{/each}}
14 |
×
15 |
16 | {{/unless}}
17 |
18 |
19 |
20 |
21 | -
22 |
23 |
24 |
25 |
26 | {{outlet}}
27 |
28 |
--------------------------------------------------------------------------------
/front/app/templates/application.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Welcome to Ember-CLI Todos App
4 |
17 |
18 |
19 |
20 |
21 |
22 | {{#if error}}
23 |
{{error}}
24 | {{/if}}
25 | {{outlet}}
26 |
27 |
--------------------------------------------------------------------------------
/todo/test/controllers/session_controller_test.rb:
--------------------------------------------------------------------------------
1 | require 'test_helper'
2 |
3 | class SessionControllerTest < ActionController::TestCase
4 | # test "the truth" do
5 | # assert true
6 | # end
7 |
8 | test "login in" do
9 | post :create, email: 'wyatt', password: '132456'
10 | assert_response :success, %q({"users":{"email":"wyatt"}})
11 | end
12 |
13 | test "login fail" do
14 | post :create, email: 'wyatt', password: '132456'
15 | assert_response :success, %q({"errors":{"email":["User or password is invalid."]}}})
16 | end
17 |
18 | test "logout" do
19 | # login first
20 | post :create, email: 'wyatt', password: '132456'
21 | assert_response :success, %q({"users":{"email":"wyatt"}})
22 |
23 | #logout
24 | delete :destroy
25 | assert_response :success, %q({"status":{"success":"Success log out"}})
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/todo/bin/setup:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require 'pathname'
3 |
4 | # path to your application root.
5 | APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
6 |
7 | Dir.chdir APP_ROOT do
8 | # This script is a starting point to setup your application.
9 | # Add necessary setup steps to this file:
10 |
11 | puts "== Installing dependencies =="
12 | system "gem install bundler --conservative"
13 | system "bundle check || bundle install"
14 |
15 | # puts "\n== Copying sample files =="
16 | # unless File.exist?("config/database.yml")
17 | # system "cp config/database.yml.sample config/database.yml"
18 | # end
19 |
20 | puts "\n== Preparing database =="
21 | system "bin/rake db:setup"
22 |
23 | puts "\n== Removing old logs and tempfiles =="
24 | system "rm -f log/*"
25 | system "rm -rf tmp/cache"
26 |
27 | puts "\n== Restarting application server =="
28 | system "touch tmp/restart.txt"
29 | end
30 |
--------------------------------------------------------------------------------
/todo/app/controllers/session_controller.rb:
--------------------------------------------------------------------------------
1 | class SessionController < ApplicationController
2 | before_action :authenticate!, only: [:destroy]
3 |
4 | # sign in 用户登陆
5 | def create
6 | # 收集用户参数
7 | errors = {}
8 | errors[:email] = ['User name can not be blank!'] if params[:email].blank?
9 | errors[:password] = ['Password can not be blank!'] if params[:password].blank?
10 |
11 | if errors.size > 0
12 | render json: {errors: errors}, status: 422
13 | else
14 | # 验证用户参数
15 | # 做出判断
16 | if USER[params[:email].strip.to_sym] == params[:password]
17 | cookies.encrypted[:token] = generate_token
18 | render json: {users: {email: 'wyatt'}}
19 | else
20 | errors[:email] = ['User or password is invalid.']
21 | render json: {errors: errors}, status: 422
22 | end
23 | end
24 | end
25 |
26 | # log out 用户登出
27 | def destroy
28 | cookies.delete(:token)
29 | flash[:success] = "Success log out"
30 | render json: {status: flash}
31 | end
32 |
33 | end
34 |
--------------------------------------------------------------------------------
/front/tests/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "predef": [
3 | "document",
4 | "window",
5 | "location",
6 | "setTimeout",
7 | "$",
8 | "-Promise",
9 | "define",
10 | "console",
11 | "visit",
12 | "exists",
13 | "fillIn",
14 | "click",
15 | "keyEvent",
16 | "triggerEvent",
17 | "find",
18 | "findWithAssert",
19 | "wait",
20 | "DS",
21 | "andThen",
22 | "currentURL",
23 | "currentPath",
24 | "currentRouteName"
25 | ],
26 | "node": false,
27 | "browser": false,
28 | "boss": true,
29 | "curly": false,
30 | "debug": false,
31 | "devel": false,
32 | "eqeqeq": true,
33 | "evil": true,
34 | "forin": false,
35 | "immed": false,
36 | "laxbreak": false,
37 | "newcap": true,
38 | "noarg": true,
39 | "noempty": false,
40 | "nonew": false,
41 | "nomen": false,
42 | "onevar": false,
43 | "plusplus": false,
44 | "regexp": false,
45 | "undef": true,
46 | "sub": true,
47 | "strict": false,
48 | "white": false,
49 | "eqnull": true,
50 | "esnext": true
51 | }
52 |
--------------------------------------------------------------------------------
/todo/config/secrets.yml:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Your secret key is used for verifying the integrity of signed cookies.
4 | # If you change this key, all old signed cookies will become invalid!
5 |
6 | # Make sure the secret is at least 30 characters and all random,
7 | # no regular words or you'll be exposed to dictionary attacks.
8 | # You can use `rake secret` to generate a secure secret key.
9 |
10 | # Make sure the secrets in this file are kept private
11 | # if you're sharing your code publicly.
12 |
13 | development:
14 | secret_key_base: e8aa94c273e8c094d0a1a0ec8675b702a00425301b45c39997450bc82bb86861eb3dff9b2f7d6706e6136b937ac1790b54b048498f4a806ac177b3cbee57818d
15 |
16 | test:
17 | secret_key_base: 83e152eb425e9af285ece4d396d8edda68c7ab72c1b1afd61d8a02a42667394fa9d602316ed51bc91590452964f57b41c7ad14f1c2d4ab2529bdbd075bb0f210
18 |
19 | # Do not keep production secrets in the repository,
20 | # instead read values from the environment.
21 | production:
22 | secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
23 |
--------------------------------------------------------------------------------
/front/tests/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Todos Tests
7 |
8 |
9 |
10 | {{content-for 'head'}}
11 | {{content-for 'test-head'}}
12 |
13 |
14 |
15 |
16 |
17 | {{content-for 'head-footer'}}
18 | {{content-for 'test-head-footer'}}
19 |
20 |
21 |
22 | {{content-for 'body'}}
23 | {{content-for 'test-body'}}
24 |
25 |
26 |
27 |
28 |
29 |
30 | {{content-for 'body-footer'}}
31 | {{content-for 'test-body-footer'}}
32 |
33 |
34 |
--------------------------------------------------------------------------------
/front/Brocfile.js:
--------------------------------------------------------------------------------
1 | /* global require, module */
2 |
3 | var EmberApp = require('ember-cli/lib/broccoli/ember-app');
4 |
5 | var app = new EmberApp();
6 |
7 | // Use `app.import` to add additional libraries to the generated
8 | // output files.
9 | //
10 | // If you need to use different assets in different
11 | // environments, specify an object as the first parameter. That
12 | // object's keys should be the environment name and the values
13 | // should be the asset to use in that environment.
14 | //
15 | // If the library that you are including contains AMD or ES6
16 | // modules that you would like to import into your application
17 | // please specify an object with the list of modules as keys
18 | // along with the exports of each module as its value.
19 |
20 | //css
21 | app.import('bower_components/foundation/css/normalize.css');
22 |
23 |
24 | // 在这里使用 non-amd import js, 则是依次添加在后面的
25 | app.import('bower_components/Cookies/dist/cookies.min.js');
26 | app.import('bower_components/foundation/js/vendor/modernizr.js');
27 | app.import('bower_components/foundation/js/foundation.js');
28 |
29 | module.exports = app.toTree();
30 |
--------------------------------------------------------------------------------
/front/app/templates/session/new.hbs:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 | {{#if errors}}
10 |
Error: {{errors}}
11 | {{/if}}
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
25 |
26 | 是否登陆: {{isAuthenticate}}
27 |
28 |
29 |
--------------------------------------------------------------------------------
/todo/config/application.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path('../boot', __FILE__)
2 |
3 | require 'rails/all'
4 |
5 | # Require the gems listed in Gemfile, including any gems
6 | # you've limited to :test, :development, or :production.
7 | Bundler.require(*Rails.groups)
8 |
9 | module Todo
10 | class Application < Rails::Application
11 | # Settings in config/environments/* take precedence over those specified here.
12 | # Application configuration should go into files in config/initializers
13 | # -- all .rb files in that directory are automatically loaded.
14 |
15 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
16 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
17 | # config.time_zone = 'Central Time (US & Canada)'
18 |
19 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
20 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
21 | # config.i18n.default_locale = :de
22 |
23 | # Do not swallow errors in after_commit/after_rollback callbacks.
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/todo/db/schema.rb:
--------------------------------------------------------------------------------
1 | # encoding: UTF-8
2 | # This file is auto-generated from the current state of the database. Instead
3 | # of editing this file, please use the migrations feature of Active Record to
4 | # incrementally modify your database, and then regenerate this schema definition.
5 | #
6 | # Note that this schema.rb definition is the authoritative source for your
7 | # database schema. If you need to create the application database on another
8 | # system, you should be using db:schema:load, not running all the migrations
9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations
10 | # you'll amass, the slower it'll run and the greater likelihood for issues).
11 | #
12 | # It's strongly recommended that you check this file into your version control system.
13 |
14 | ActiveRecord::Schema.define(version: 20150418153320) do
15 |
16 | create_table "tasks", force: :cascade do |t|
17 | t.string "title"
18 | t.boolean "is_done", default: false
19 | t.boolean "is_archive", default: false
20 | t.datetime "created_at", null: false
21 | t.datetime "updated_at", null: false
22 | end
23 |
24 | end
25 |
--------------------------------------------------------------------------------
/front/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "todos",
3 | "version": "0.0.0",
4 | "description": "Small description for todos goes here",
5 | "private": true,
6 | "directories": {
7 | "doc": "doc",
8 | "test": "tests"
9 | },
10 | "scripts": {
11 | "start": "ember server",
12 | "build": "ember build",
13 | "test": "ember test"
14 | },
15 | "repository": "",
16 | "engines": {
17 | "node": ">= 0.10.0"
18 | },
19 | "author": "",
20 | "license": "MIT",
21 | "devDependencies": {
22 | "broccoli-asset-rev": "^2.0.2",
23 | "ember-cli": "0.2.5",
24 | "ember-cli-app-version": "0.3.3",
25 | "ember-cli-babel": "^5.0.0",
26 | "ember-cli-content-security-policy": "0.4.0",
27 | "ember-cli-dependency-checker": "^1.0.0",
28 | "ember-cli-htmlbars": "0.7.6",
29 | "ember-cli-ic-ajax": "0.1.1",
30 | "ember-cli-inject-live-reload": "^1.3.0",
31 | "ember-cli-qunit": "0.3.13",
32 | "ember-cli-uglify": "^1.0.1",
33 | "ember-data": "1.0.0-beta.17",
34 | "ember-disable-proxy-controllers": "^0.7.0",
35 | "ember-export-application-global": "^1.0.2",
36 |
37 | "ember-cli-foundation-sass": "1.1.1",
38 | "ember-cli-sass": "3.1.0"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/todo/app/controllers/application_controller.rb:
--------------------------------------------------------------------------------
1 | class ApplicationController < ActionController::Base
2 | # Prevent CSRF attacks by raising an exception.
3 | # For APIs, you may want to use :null_session instead.
4 | # protect_from_forgery with: :exception
5 |
6 | USER = {
7 | wyatt: '132456',
8 | holly: '241356'
9 | }
10 |
11 | # 当前用户
12 | def current_user
13 | cookie_token.split(' ')[0]
14 | end
15 |
16 | def cookie_token
17 | token = cookies.encrypted[:token]
18 | if token
19 | token
20 | else
21 | ""
22 | end
23 | end
24 |
25 | def authenticate!
26 | user, pass = user_and_pass
27 | if cookies.encrypted[:token] == private_generate_token(user, pass)
28 | true
29 | else
30 | errors = {error: "You must be logged in to access this section"}
31 | render json: {errors: errors}, status: 422
32 | false
33 | end
34 | end
35 |
36 | def generate_token
37 | private_generate_token(params[:email], USER[params[:email].strip])
38 | end
39 |
40 | def private_generate_token(user, pass)
41 | "#{user} #{pass}"
42 | end
43 |
44 | private
45 | def user_and_pass
46 | cookie_token.split(' ')
47 | end
48 |
49 | end
50 |
--------------------------------------------------------------------------------
/front/app/templates/components/todo-item.hbs:
--------------------------------------------------------------------------------
1 |
2 | {{#if isEdit}}
3 |
4 |
5 |
6 |
7 | {{input type='checkbox' checked=todo.isDone}}
8 |
9 |
10 | {{input value=todo.title key-up='exitEditWithEnter' bubbles=false class='focus'}}
11 |
12 |
13 |
14 |
15 | {{todo.title}}
16 |
17 |
18 |
19 |
20 |
21 | {{else}}
22 |
23 | {{input type='checkbox' checked=todo.isDone}}
24 | {{todo.title}}
25 | {{#if undo}}
26 |
27 | {{/if}}
28 |
29 |
30 | {{/if}}
31 |
--------------------------------------------------------------------------------
/front/config/environment.js:
--------------------------------------------------------------------------------
1 | /* jshint node: true */
2 |
3 | module.exports = function(environment) {
4 | var ENV = {
5 | modulePrefix: 'todos',
6 | environment: environment,
7 | baseURL: '/',
8 | locationType: 'auto',
9 | EmberENV: {
10 | FEATURES: {
11 | // Here you can enable experimental features on an ember canary build
12 | // e.g. 'with-controller': true
13 | }
14 | },
15 |
16 | APP: {
17 | // Here you can pass flags/options to your application instance
18 | // when it is created
19 | }
20 | };
21 |
22 | if (environment === 'development') {
23 | // ENV.APP.LOG_RESOLVER = true;
24 | // ENV.APP.LOG_ACTIVE_GENERATION = true;
25 | ENV.APP.LOG_TRANSITIONS = true;
26 | // ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
27 | // ENV.APP.LOG_VIEW_LOOKUPS = true;
28 | }
29 |
30 | if (environment === 'test') {
31 | // Testem prefers this...
32 | ENV.baseURL = '/';
33 | ENV.locationType = 'none';
34 |
35 | // keep test console output quieter
36 | ENV.APP.LOG_ACTIVE_GENERATION = false;
37 | ENV.APP.LOG_VIEW_LOOKUPS = false;
38 |
39 | ENV.APP.rootElement = '#ember-testing';
40 | }
41 |
42 | if (environment === 'production') {
43 |
44 | }
45 |
46 | return ENV;
47 | };
48 |
--------------------------------------------------------------------------------
/front/README.md:
--------------------------------------------------------------------------------
1 | # Todos
2 |
3 | This README outlines the details of collaborating on this Ember application.
4 | A short introduction of this app could easily go here.
5 |
6 | ## Prerequisites
7 |
8 | You will need the following things properly installed on your computer.
9 |
10 | * [Git](http://git-scm.com/)
11 | * [Node.js](http://nodejs.org/) (with NPM)
12 | * [Bower](http://bower.io/)
13 | * [Ember CLI](http://www.ember-cli.com/)
14 | * [PhantomJS](http://phantomjs.org/)
15 |
16 | ## Installation
17 |
18 | * `git clone ` this repository
19 | * change into the new directory
20 | * `npm install`
21 | * `bower install`
22 |
23 | ## Running / Development
24 |
25 | * `ember server`
26 | * Visit your app at [http://localhost:4200](http://localhost:4200).
27 |
28 | ### Code Generators
29 |
30 | Make use of the many generators for code, try `ember help generate` for more details
31 |
32 | ### Running Tests
33 |
34 | * `ember test`
35 | * `ember test --server`
36 |
37 | ### Building
38 |
39 | * `ember build` (development)
40 | * `ember build --environment production` (production)
41 |
42 | ### Deploying
43 |
44 | Specify what it takes to deploy your app.
45 |
46 | ## Further Reading / Useful Links
47 |
48 | * [ember.js](http://emberjs.com/)
49 | * [ember-cli](http://www.ember-cli.com/)
50 | * Development Browser Extensions
51 | * [ember inspector for chrome](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi)
52 | * [ember inspector for firefox](https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/)
53 |
54 |
--------------------------------------------------------------------------------
/front/app/services/session.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 |
3 | export default Ember.Service.extend({
4 | email: null,
5 | token: null,
6 | // 当前 session service 的 error
7 | error: null,
8 | // 登陆
9 | signin(email, password) {
10 | return Ember.$.ajax('/session', {
11 | type: 'POST',
12 | data: {
13 | email: email,
14 | password: password
15 | },
16 | dataType: 'json'
17 | }).done((r) => {
18 | // 在这里将原始 Cookie 存储
19 | this.set('token', Cookies.get('token'));
20 | this.set('email', email);
21 | localStorage.setItem('token', Cookies.get('token'));
22 | localStorage.setItem('email', email);
23 | console.log("response: " + JSON.stringify(r) + ";;;;" + this.get('email'));
24 | }).fail((xhr) => {
25 | console.log('error in session service: ' + xhr.responseText);
26 | });
27 | },
28 |
29 | // 登出
30 | signout() {
31 | // clear all information
32 | localStorage.removeItem('token');
33 | this.set('token', null);
34 | this.set('error', null);
35 | this.set('email', null);
36 | },
37 |
38 | // 检查本地是否有已经登陆过
39 | loadFromClient() {
40 | if(Cookies.get('token') != null) {
41 | this.set('token', Cookies.get('token'));
42 | this.set('email', localStorage.getItem('email'));
43 | }
44 | return this.get('token');
45 | },
46 |
47 | // 验证是否登陆
48 | isAuthenticate() {
49 | if(localStorage.getItem('token') == null) {
50 | return false;
51 | }
52 | return localStorage.getItem('token') === this.loadFromClient();
53 | }
54 |
55 | // TODO 验证有了, 还需要考虑授权.
56 |
57 | });
58 |
--------------------------------------------------------------------------------
/todo/app/controllers/tasks_controller.rb:
--------------------------------------------------------------------------------
1 | class TasksController < ApplicationController
2 | def index
3 | # for test dev
4 | tasks = Task.all
5 | render json: tasks, root: 'todos'
6 | end
7 |
8 | def create
9 | task = Task.new(save_task_params)
10 | # sleep(0.4) # 300ms, 调教延迟, 测试用户操作感觉.
11 | if task.save
12 | render json: task, root: 'todos'
13 | else
14 | render json: {errors: task.errors}, status: 422
15 | end
16 | end
17 |
18 | def show
19 | task = Task.find(params[:id])
20 | render json: task, root: 'todos'
21 | rescue ActiveRecord::RecordNotFound => e
22 | render json: {errors: {exception: e.message}}, status: 422
23 | end
24 |
25 | def update
26 | task = Task.find(params[:id])
27 | if task.update(update_task_params)
28 | render json: task, root: 'todos'
29 | else
30 | render json: {errors: task.errors}, status: 422
31 | end
32 | end
33 |
34 | def destroy
35 | task = Task.find(params[:id])
36 | if task.destroy
37 | render json: task, root: 'todo'
38 | else
39 | render json: {errors: {message: 'delete faild.'}}
40 | end
41 | end
42 |
43 | # 批量进行 Archive
44 | def archives
45 | Task.where(id: params[:ids]).update_all(is_done: true, is_archive: true)
46 | render json: {success: 'ok'}
47 | end
48 |
49 |
50 | def update_task_params
51 | params.require(:todo).permit(:title, :is_done, :is_archive)
52 | end
53 |
54 | def save_task_params
55 | params.require(:todo).permit(:title)
56 | end
57 | end
58 |
--------------------------------------------------------------------------------
/todo/public/500.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | We're sorry, but something went wrong (500)
5 |
6 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
We're sorry, but something went wrong.
62 |
63 |
If you are the application owner check the logs for more information.
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/todo/config/environments/development.rb:
--------------------------------------------------------------------------------
1 | Rails.application.configure do
2 | # Settings specified here will take precedence over those in config/application.rb.
3 |
4 | # In the development environment your application's code is reloaded on
5 | # every request. This slows down response time but is perfect for development
6 | # since you don't have to restart the web server when you make code changes.
7 | config.cache_classes = false
8 |
9 | # Do not eager load code on boot.
10 | config.eager_load = false
11 |
12 | # Show full error reports and disable caching.
13 | config.consider_all_requests_local = true
14 | config.action_controller.perform_caching = false
15 |
16 | # Don't care if the mailer can't send.
17 | config.action_mailer.raise_delivery_errors = false
18 |
19 | # Print deprecation notices to the Rails logger.
20 | config.active_support.deprecation = :log
21 |
22 | # Raise an error on page load if there are pending migrations.
23 | config.active_record.migration_error = :page_load
24 |
25 | # Debug mode disables concatenation and preprocessing of assets.
26 | # This option may cause significant delays in view rendering with a large
27 | # number of complex assets.
28 | config.assets.debug = true
29 |
30 | # Asset digests allow you to set far-future HTTP expiration dates on all assets,
31 | # yet still be able to expire them through the digest params.
32 | config.assets.digest = true
33 |
34 | # Adds additional error checking when serving assets at runtime.
35 | # Checks for improperly declared sprockets dependencies.
36 | # Raises helpful error messages.
37 | config.assets.raise_runtime_errors = true
38 |
39 | # Raises error for missing translations
40 | # config.action_view.raise_on_missing_translations = true
41 | end
42 |
--------------------------------------------------------------------------------
/front/app/models/todo.js:
--------------------------------------------------------------------------------
1 | import DS from 'ember-data';
2 | import Ember from 'ember';
3 |
4 | var Todo = DS.Model.extend({
5 | // 是否完成
6 | isDone: DS.attr('boolean'),
7 | // 是否存档
8 | isArchive: DS.attr('boolean'),
9 | title: DS.attr('string'),
10 | createdAt: DS.attr('date')
11 | });
12 |
13 |
14 | // !! reopenClass 与 reopen 的区别, 在学习 Ruby 中的 class_eval, instance_eval
15 | Todo.reopenClass({
16 | FIXTURES: [
17 | {id: 1, isDone: false, isArchive: false, title: 'First Todo to do.', createdAt: new Date('2015-04-11')},
18 | {id: 2, isDone: false, isArchive: false, title: '2 Todo to do.', createdAt: new Date('2015-04-12')},
19 | {id: 3, isDone: false, isArchive: false, title: '3 Todo to do.', createdAt: new Date('2015-04-13')},
20 | {id: 4, isDone: false, isArchive: false, title: '4 Todo to do.', createdAt: new Date('2015-04-14')},
21 | {id: 5, isDone: false, isArchive: false, title: '5 Todo to do.', createdAt: new Date('2015-04-15')},
22 | {id: 6, isDone: true, isArchive: true, title: '6 Todo to do.', createdAt: new Date('2015-04-16')},
23 | {id: 7, isDone: true, isArchive: true, title: '7 Todo to do.', createdAt: new Date('2015-04-17')},
24 | {id: 8, isDone: true, isArchive: true, title: '8 Todo to do.', createdAt: new Date('2015-04-18')}
25 | ],
26 |
27 | /**
28 | * 批量存档 Todo
29 | */
30 | archives(todos) {
31 | var ids = todos.mapBy('id');
32 | todos.setEach('isArchive', true);
33 | Ember.$.ajax('/todos/archives', {
34 | dataType: 'json',
35 | type: 'put',
36 | data: {ids: ids}
37 | }).then(() => {
38 | console.log("Success");
39 | }).fail((error) => {
40 | todos.forEach((todo) => {
41 | todo.rollback();
42 | });
43 | console.log(error);
44 | });
45 | }
46 | });
47 |
48 | export default Todo;
49 |
--------------------------------------------------------------------------------
/todo/public/422.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | The change you wanted was rejected (422)
5 |
6 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
The change you wanted was rejected.
62 |
Maybe you tried to change something you didn't have access to.
63 |
64 |
If you are the application owner check the logs for more information.
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/todo/public/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | The page you were looking for doesn't exist (404)
5 |
6 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
The page you were looking for doesn't exist.
62 |
You may have mistyped the address or the page may have moved.
63 |
64 |
If you are the application owner check the logs for more information.
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/todo/Gemfile:
--------------------------------------------------------------------------------
1 | #source 'https://rubygems.org'
2 | source 'http://ruby.taobao.org'
3 |
4 |
5 | # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
6 | gem 'rails', '4.2.0'
7 | # Use sqlite3 as the database for Active Record
8 | gem 'sqlite3'
9 | # Use SCSS for stylesheets
10 | gem 'sass-rails', '~> 5.0'
11 | # Use Uglifier as compressor for JavaScript assets
12 | gem 'uglifier', '>= 1.3.0'
13 | # Use CoffeeScript for .coffee assets and views
14 | #gem 'coffee-rails', '~> 4.1.0'
15 | # See https://github.com/sstephenson/execjs#readme for more supported runtimes
16 | # gem 'therubyracer', platforms: :ruby
17 |
18 | # Use jquery as the JavaScript library
19 | gem 'jquery-rails'
20 | # Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
21 | #gem 'turbolinks'
22 | # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
23 | #gem 'jbuilder', '~> 2.0'
24 | # bundle exec rake doc:rails generates the API under doc/api.
25 | #gem 'sdoc', '~> 0.4.0', group: :doc
26 |
27 |
28 | ## ---------------- API --------------------
29 | # 到时候再更新到 0.9 或者 1.0
30 | gem 'active_model_serializers', '~> 0.8'
31 | #gem 'rack-cors', :require => 'rack/cors'
32 |
33 | # Use ActiveModel has_secure_password
34 | # gem 'bcrypt', '~> 3.1.7'
35 |
36 | # Use Unicorn as the app server
37 | # gem 'unicorn'
38 |
39 | # Use Capistrano for deployment
40 | # gem 'capistrano-rails', group: :development
41 |
42 | group :development, :test do
43 | # Call 'byebug' anywhere in the code to stop execution and get a debugger console
44 | gem 'byebug'
45 |
46 | # Access an IRB console on exception pages or by using <%= console %> in views
47 | gem 'web-console', '~> 2.0'
48 |
49 | # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
50 | #gem 'spring'
51 | gem 'zeus'
52 | end
53 |
54 |
--------------------------------------------------------------------------------
/todo/config/environments/test.rb:
--------------------------------------------------------------------------------
1 | Rails.application.configure do
2 | # Settings specified here will take precedence over those in config/application.rb.
3 |
4 | # The test environment is used exclusively to run your application's
5 | # test suite. You never need to work with it otherwise. Remember that
6 | # your test database is "scratch space" for the test suite and is wiped
7 | # and recreated between test runs. Don't rely on the data there!
8 | config.cache_classes = true
9 |
10 | # Do not eager load code on boot. This avoids loading your whole application
11 | # just for the purpose of running a single test. If you are using a tool that
12 | # preloads Rails for running tests, you may have to set it to true.
13 | config.eager_load = false
14 |
15 | # Configure static file server for tests with Cache-Control for performance.
16 | config.serve_static_files = true
17 | config.static_cache_control = 'public, max-age=3600'
18 |
19 | # Show full error reports and disable caching.
20 | config.consider_all_requests_local = true
21 | config.action_controller.perform_caching = false
22 |
23 | # Raise exceptions instead of rendering exception templates.
24 | config.action_dispatch.show_exceptions = false
25 |
26 | # Disable request forgery protection in test environment.
27 | config.action_controller.allow_forgery_protection = false
28 |
29 | # Tell Action Mailer not to deliver emails to the real world.
30 | # The :test delivery method accumulates sent emails in the
31 | # ActionMailer::Base.deliveries array.
32 | config.action_mailer.delivery_method = :test
33 |
34 | # Randomize the order test cases are executed.
35 | config.active_support.test_order = :random
36 |
37 | # Print deprecation notices to the stderr.
38 | config.active_support.deprecation = :stderr
39 |
40 | # Raises error for missing translations
41 | # config.action_view.raise_on_missing_translations = true
42 | end
43 |
--------------------------------------------------------------------------------
/front/app/styles/_foundation.scss:
--------------------------------------------------------------------------------
1 | // Foundation by ZURB
2 | // foundation.zurb.com
3 | // Licensed under MIT Open Source
4 |
5 | // Make sure the charset is set appropriately
6 |
7 | // Behold, here are all the Foundation components.
8 | @import 'foundation/components/grid';
9 | @import 'foundation/components/accordion';
10 | @import 'foundation/components/alert-boxes';
11 | @import 'foundation/components/block-grid';
12 | @import 'foundation/components/breadcrumbs';
13 | @import 'foundation/components/button-groups';
14 | @import 'foundation/components/buttons';
15 | @import 'foundation/components/clearing';
16 | @import 'foundation/components/dropdown';
17 | @import 'foundation/components/dropdown-buttons';
18 | @import 'foundation/components/flex-video';
19 | @import 'foundation/components/forms';
20 | @import 'foundation/components/icon-bar';
21 | @import 'foundation/components/inline-lists';
22 | @import 'foundation/components/joyride';
23 | @import 'foundation/components/keystrokes';
24 | @import 'foundation/components/labels';
25 | @import 'foundation/components/magellan';
26 | @import 'foundation/components/orbit';
27 | @import 'foundation/components/pagination';
28 | @import 'foundation/components/panels';
29 | @import 'foundation/components/pricing-tables';
30 | @import 'foundation/components/progress-bars';
31 | @import 'foundation/components/range-slider';
32 | @import 'foundation/components/reveal';
33 | @import 'foundation/components/side-nav';
34 | @import 'foundation/components/split-buttons';
35 | @import 'foundation/components/sub-nav';
36 | @import 'foundation/components/switches';
37 | @import 'foundation/components/tables';
38 | @import 'foundation/components/tabs';
39 | @import 'foundation/components/thumbs';
40 | @import 'foundation/components/tooltips';
41 | @import 'foundation/components/top-bar';
42 | @import 'foundation/components/type';
43 | @import 'foundation/components/offcanvas';
44 | @import 'foundation/components/visibility';
45 |
--------------------------------------------------------------------------------
/front/app/controllers/todos.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 | import Todo from '../models/todo';
3 |
4 | export default Ember.ArrayController.extend({
5 | unArchive: function() {
6 | return this.filter(function(todo) {
7 | if(todo.get('isNew')) {
8 | return false;
9 | }
10 | return !todo.get('isArchive');
11 | });
12 | }.property('@each.isArchive'),
13 |
14 | todo: function() {
15 | return this.store.createRecord('todo', {
16 | isDone: false,
17 | isArchive: false,
18 | createdAt: new Date()
19 | });
20 | }.property('newCount'),
21 | // 保证每创建完成一个后, 能够自动生成一个空的 Todo 用于收集前台的数据
22 | newCount: 0,
23 |
24 | actions: {
25 | newTodo() {
26 | // 回车
27 | if(event.keyCode === 13) {
28 | var self = this;
29 | //this.get('todo').save().then(function() {
30 | // self.incrementProperty('newCount', 1);
31 | //}, function(error) {
32 | // // 需要对 promise 中的异常部分进行处理.
33 | // console.log(error);
34 | //});
35 | this.get('todo').save().then(() => {
36 | self.incrementProperty('newCount', 1);
37 | }).catch(() => {
38 | console.log(self.get('todo.errors.messages'));
39 | });
40 | }
41 | },
42 |
43 | archiveTodos() {
44 | this.logger.log('archiveTodos..!!!..');
45 | // 这里更新了, 但如果不进行 save 的话, 这些 Model 仍然会被加载出来进行批量更新
46 | var archivedTodos = this.filter(todo => {
47 | return todo.get('isDone');
48 | });
49 | /* 每一个 mode 都进行一次独立的保存(批量 Archive) 的方式, 这样 model 信息会一致.
50 | archivedTodos.forEach((todo) => {
51 | todo.set('isArchive', true);
52 | todo.save().catch((error) => {
53 | todo.rollback();
54 | console.log(error);
55 | });
56 | });
57 | */
58 |
59 | // Model 通过 Ember.$.ajax 的处理方式, 一次性批量处理.
60 | Todo.archives(archivedTodos);
61 | },
62 |
63 | closeAlert() {
64 | this.get('todo.errors').clear();
65 | }
66 | }
67 | });
68 |
--------------------------------------------------------------------------------
/todo/config/routes.rb:
--------------------------------------------------------------------------------
1 | Rails.application.routes.draw do
2 | resources :tasks, path: 'todos' do
3 | collection do
4 | put 'archives'
5 | end
6 | end
7 |
8 | post :session, to: 'session#create'
9 | delete :session, to: 'session#destroy'
10 |
11 | # The priority is based upon order of creation: first created -> highest priority.
12 | # See how all your routes lay out with "rake routes".
13 |
14 | # You can have the root of your site routed with "root"
15 | # root 'welcome#index'
16 |
17 | # Example of regular route:
18 | # get 'products/:id' => 'catalog#view'
19 |
20 | # Example of named route that can be invoked with purchase_url(id: product.id)
21 | # get 'products/:id/purchase' => 'catalog#purchase', as: :purchase
22 |
23 | # Example resource route (maps HTTP verbs to controller actions automatically):
24 | # resources :products
25 |
26 | # Example resource route with options:
27 | # resources :products do
28 | # member do
29 | # get 'short'
30 | # post 'toggle'
31 | # end
32 | #
33 | # collection do
34 | # get 'sold'
35 | # end
36 | # end
37 |
38 | # Example resource route with sub-resources:
39 | # resources :products do
40 | # resources :comments, :sales
41 | # resource :seller
42 | # end
43 |
44 | # Example resource route with more complex sub-resources:
45 | # resources :products do
46 | # resources :comments
47 | # resources :sales do
48 | # get 'recent', on: :collection
49 | # end
50 | # end
51 |
52 | # Example resource route with concerns:
53 | # concern :toggleable do
54 | # post 'toggle'
55 | # end
56 | # resources :posts, concerns: :toggleable
57 | # resources :photos, concerns: :toggleable
58 |
59 | # Example resource route within a namespace:
60 | # namespace :admin do
61 | # # Directs /admin/products/* to Admin::ProductsController
62 | # # (app/controllers/admin/products_controller.rb)
63 | # resources :products
64 | # end
65 | end
66 |
--------------------------------------------------------------------------------
/front/app/components/todo-item.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 |
3 | // 在页面上测试后, 发现 Component 如果频繁计算, 其实还是会有一些慢的,
4 | // 例如: 当我添加到 50 个左右的 Todo 后(用 Component 来组成的) 接下来每一次的 Todo 变化都引起
5 | // each 内所有的 Component 重新绘制.
6 | // 问题:
7 | // 1. 为什么每一个独立的 Component 自己的 Edit 变化会让整个 {{#each}} 中的 Component 重新绘制? 不应该只绘制自己吗?
8 | // 2. Compoennt 绘制速度真的很慢吗? 是因为量多导致的吗? 在 50 个量级会有明显感觉.
9 | export default Ember.Component.extend({
10 | tagName: 'li',
11 | isEdit: false,
12 | classNames: ['item'],
13 | classNameBindings: ['todo.isDone'],
14 | actions: {
15 | exitEditWithEnter() {
16 | console.log(event.keyCode);
17 | if(event.keyCode === 13) {
18 | console.log("in Enter");
19 | this.set('isEdit', false);
20 | this.get('todo').save().then(() => {
21 | console.log("Save Success");
22 | }).catch(error => {
23 | console.log(error);
24 | });
25 | }
26 | },
27 | // 可以将上面的 openEdit, closeEdit 合并, 分成上面两个写法主要是因为在页面刷新后, 点击
28 | // 里面的 title 开启 isEdit 后, 只要在 Edit 模式中的 input 框中按下一个键就会自动将 isEdit 标记为 false,
29 | // 这里我没有弄明白是如何变化的? 并且是所有 todo item 的 component 都会被重新绘制一遍.
30 | // -- 在 archived 页面没有, 只有在 todos 页面一直有这问题.
31 | // - 解决问题, 为 controller:todos 中关于 unArchive 这个 property 的监控计算问题导致, 取消了 @each.isNew
32 | toggleEdit(todo) {
33 | this.toggleProperty('isEdit');
34 | if(this.get('isEdit')) {
35 | var self = this;
36 | // Em 是 Ember 库中的简写
37 | //Em.run.later(function() {
38 | Ember.run.later(() => {
39 | if(todo.get('isDrity')) {
40 | todo.save().catch((error) => {
41 | console.log(error);
42 | });
43 | }
44 | self.$('input.focus').focus();
45 | }, 200);
46 | }
47 | },
48 | removeTodo(todo) {
49 | //todo.deleteRecord();
50 | if(confirm('确认删除?')) {
51 | todo.destroyRecord().catch(error => {
52 | console.log("Fail destory one record" + error);
53 | });
54 | }
55 | },
56 | undo(todo) {
57 | todo.set('isDone', false).set('isArchive', false).save().catch((error) => {
58 | todo.rollback();
59 | console.log(error);
60 | });
61 | }
62 | }
63 | });
64 |
--------------------------------------------------------------------------------
/todo/config/environments/production.rb:
--------------------------------------------------------------------------------
1 | Rails.application.configure do
2 | # Settings specified here will take precedence over those in config/application.rb.
3 |
4 | # Code is not reloaded between requests.
5 | config.cache_classes = true
6 |
7 | # Eager load code on boot. This eager loads most of Rails and
8 | # your application in memory, allowing both threaded web servers
9 | # and those relying on copy on write to perform better.
10 | # Rake tasks automatically ignore this option for performance.
11 | config.eager_load = true
12 |
13 | # Full error reports are disabled and caching is turned on.
14 | config.consider_all_requests_local = false
15 | config.action_controller.perform_caching = true
16 |
17 | # Enable Rack::Cache to put a simple HTTP cache in front of your application
18 | # Add `rack-cache` to your Gemfile before enabling this.
19 | # For large-scale production use, consider using a caching reverse proxy like
20 | # NGINX, varnish or squid.
21 | # config.action_dispatch.rack_cache = true
22 |
23 | # Disable serving static files from the `/public` folder by default since
24 | # Apache or NGINX already handles this.
25 | config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present?
26 |
27 | # Compress JavaScripts and CSS.
28 | config.assets.js_compressor = :uglifier
29 | # config.assets.css_compressor = :sass
30 |
31 | # Do not fallback to assets pipeline if a precompiled asset is missed.
32 | config.assets.compile = false
33 |
34 | # Asset digests allow you to set far-future HTTP expiration dates on all assets,
35 | # yet still be able to expire them through the digest params.
36 | config.assets.digest = true
37 |
38 | # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb
39 |
40 | # Specifies the header that your server uses for sending files.
41 | # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
42 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
43 |
44 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
45 | # config.force_ssl = true
46 |
47 | # Use the lowest log level to ensure availability of diagnostic information
48 | # when problems arise.
49 | config.log_level = :debug
50 |
51 | # Prepend all log lines with the following tags.
52 | # config.log_tags = [ :subdomain, :uuid ]
53 |
54 | # Use a different logger for distributed setups.
55 | # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
56 |
57 | # Use a different cache store in production.
58 | # config.cache_store = :mem_cache_store
59 |
60 | # Enable serving of images, stylesheets, and JavaScripts from an asset server.
61 | # config.action_controller.asset_host = 'http://assets.example.com'
62 |
63 | # Ignore bad email addresses and do not raise email delivery errors.
64 | # Set this to true and configure the email server for immediate delivery to raise delivery errors.
65 | # config.action_mailer.raise_delivery_errors = false
66 |
67 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
68 | # the I18n.default_locale when a translation cannot be found).
69 | config.i18n.fallbacks = true
70 |
71 | # Send deprecation notices to registered listeners.
72 | config.active_support.deprecation = :notify
73 |
74 | # Use default logging formatter so that PID and timestamp are not suppressed.
75 | config.log_formatter = ::Logger::Formatter.new
76 |
77 | # Do not dump schema after migrations.
78 | config.active_record.dump_schema_after_migration = false
79 | end
80 |
--------------------------------------------------------------------------------
/todo/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: http://ruby.taobao.org/
3 | specs:
4 | actionmailer (4.2.0)
5 | actionpack (= 4.2.0)
6 | actionview (= 4.2.0)
7 | activejob (= 4.2.0)
8 | mail (~> 2.5, >= 2.5.4)
9 | rails-dom-testing (~> 1.0, >= 1.0.5)
10 | actionpack (4.2.0)
11 | actionview (= 4.2.0)
12 | activesupport (= 4.2.0)
13 | rack (~> 1.6.0)
14 | rack-test (~> 0.6.2)
15 | rails-dom-testing (~> 1.0, >= 1.0.5)
16 | rails-html-sanitizer (~> 1.0, >= 1.0.1)
17 | actionview (4.2.0)
18 | activesupport (= 4.2.0)
19 | builder (~> 3.1)
20 | erubis (~> 2.7.0)
21 | rails-dom-testing (~> 1.0, >= 1.0.5)
22 | rails-html-sanitizer (~> 1.0, >= 1.0.1)
23 | active_model_serializers (0.9.3)
24 | activemodel (>= 3.2)
25 | activejob (4.2.0)
26 | activesupport (= 4.2.0)
27 | globalid (>= 0.3.0)
28 | activemodel (4.2.0)
29 | activesupport (= 4.2.0)
30 | builder (~> 3.1)
31 | activerecord (4.2.0)
32 | activemodel (= 4.2.0)
33 | activesupport (= 4.2.0)
34 | arel (~> 6.0)
35 | activesupport (4.2.0)
36 | i18n (~> 0.7)
37 | json (~> 1.7, >= 1.7.7)
38 | minitest (~> 5.1)
39 | thread_safe (~> 0.3, >= 0.3.4)
40 | tzinfo (~> 1.1)
41 | arel (6.0.0)
42 | binding_of_caller (0.7.2)
43 | debug_inspector (>= 0.0.1)
44 | builder (3.2.2)
45 | byebug (4.0.5)
46 | columnize (= 0.9.0)
47 | columnize (0.9.0)
48 | debug_inspector (0.0.2)
49 | erubis (2.7.0)
50 | execjs (2.5.2)
51 | globalid (0.3.5)
52 | activesupport (>= 4.1.0)
53 | i18n (0.7.0)
54 | jquery-rails (4.0.3)
55 | rails-dom-testing (~> 1.0)
56 | railties (>= 4.2.0)
57 | thor (>= 0.14, < 2.0)
58 | json (1.8.2)
59 | loofah (2.0.1)
60 | nokogiri (>= 1.5.9)
61 | mail (2.6.3)
62 | mime-types (>= 1.16, < 3)
63 | method_source (0.8.2)
64 | mime-types (2.4.3)
65 | mini_portile (0.6.2)
66 | minitest (5.6.0)
67 | nokogiri (1.6.6.2)
68 | mini_portile (~> 0.6.0)
69 | rack (1.6.0)
70 | rack-test (0.6.3)
71 | rack (>= 1.0)
72 | rails (4.2.0)
73 | actionmailer (= 4.2.0)
74 | actionpack (= 4.2.0)
75 | actionview (= 4.2.0)
76 | activejob (= 4.2.0)
77 | activemodel (= 4.2.0)
78 | activerecord (= 4.2.0)
79 | activesupport (= 4.2.0)
80 | bundler (>= 1.3.0, < 2.0)
81 | railties (= 4.2.0)
82 | sprockets-rails
83 | rails-deprecated_sanitizer (1.0.3)
84 | activesupport (>= 4.2.0.alpha)
85 | rails-dom-testing (1.0.6)
86 | activesupport (>= 4.2.0.beta, < 5.0)
87 | nokogiri (~> 1.6.0)
88 | rails-deprecated_sanitizer (>= 1.0.1)
89 | rails-html-sanitizer (1.0.2)
90 | loofah (~> 2.0)
91 | railties (4.2.0)
92 | actionpack (= 4.2.0)
93 | activesupport (= 4.2.0)
94 | rake (>= 0.8.7)
95 | thor (>= 0.18.1, < 2.0)
96 | rake (10.4.2)
97 | sass (3.4.13)
98 | sass-rails (5.0.3)
99 | railties (>= 4.0.0, < 5.0)
100 | sass (~> 3.1)
101 | sprockets (>= 2.8, < 4.0)
102 | sprockets-rails (>= 2.0, < 4.0)
103 | tilt (~> 1.1)
104 | sprockets (3.0.1)
105 | rack (~> 1.0)
106 | sprockets-rails (2.2.4)
107 | actionpack (>= 3.0)
108 | activesupport (>= 3.0)
109 | sprockets (>= 2.8, < 4.0)
110 | sqlite3 (1.3.10)
111 | thor (0.19.1)
112 | thread_safe (0.3.5)
113 | tilt (1.4.1)
114 | tzinfo (1.2.2)
115 | thread_safe (~> 0.1)
116 | uglifier (2.7.1)
117 | execjs (>= 0.3.0)
118 | json (>= 1.8.0)
119 | web-console (2.1.2)
120 | activemodel (>= 4.0)
121 | binding_of_caller (>= 0.7.2)
122 | railties (>= 4.0)
123 | sprockets-rails (>= 2.0, < 4.0)
124 | zeus (0.15.3)
125 | method_source (>= 0.6.7)
126 |
127 | PLATFORMS
128 | ruby
129 |
130 | DEPENDENCIES
131 | active_model_serializers (~> 0.8)
132 | byebug
133 | jquery-rails
134 | rails (= 4.2.0)
135 | sass-rails (~> 5.0)
136 | sqlite3
137 | uglifier (>= 1.3.0)
138 | web-console (~> 2.0)
139 | zeus
140 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 目的
2 | 用于练习 Ember.js + Rails 的组合的 demo 应用及寻坑
3 |
4 | **内容的更新改变为以 issue 记录, 每一个问题拥有一个 issue 如果拥有了一个结论, 则标记 close 有结论. 可以使用 Github 的搜索来寻找这些问题以及答案.**
5 |
6 |
7 | # ember stack
8 | ember.js 社区的变化太快了, 从 ember stack 大的方向来说, 已经从 ember.js 已经成长到了 [ember.js](https://github.com/emberjs/ember.js), [ember-data](https://github.com/emberjs/data), [ember-cli](https://github.com/ember-cli/ember-cli), [Liquid Fire](https://github.com/ef4/liquid-fire), [List View](https://github.com/emberjs/list-view) 5 个套间的统一版本发布.
9 | 从 ember.js 这一个项目看, 在其进入 ember.js 1.12 后变化越来越快, 新的 render enging 新的 component 语法, 新的 action 语法(嵌套), 以及即将到来的 routable component. 因为这些变化, 使得我记录在下面的没有办法那么快的更新, 同时我也只能记录与特性无关的思路性的内容. 开始拥抱 ember.js 吧, 从 ember.js-1.13 开始.
10 |
11 | PS:
12 | * [List View](http://talks.erikbryn.com/ember-list-view/), 用于处理大量 Dom 在页面便利的问题, 避免内存溢出.
13 | * Liquid Fire, transition 的动画效果.
14 |
15 |
16 | # Tech stack(import point):
17 |
18 | * ember-cli : ember.js 开发的工具集 (类似 rails 的 generate)
19 | - ember.js : 核心 ember.js 前端开发框架
20 | - ember-data : ember.js 中独立的前端与后端数据交互, 数据缓存等等的问题的库
21 | - foundation 5 : 响应式优先的前端 Sass 编写的库文件.
22 | - es6 transpiler : es6 特性提前使用
23 | - sass : 前端 css 的预处理编译器
24 | - npm : node.js 后端 JavaScript 包依赖管理工具. (主要 ember-cli 自己使用)
25 | - bower : JavaScript 前端包管理工具, ember-cli 中开发人员重点使用. (例如 foundation 5 利用 bower 将依赖下载回来)
26 | * rails : 后端开发框架
27 | - active_model_serializers : rails 中用于处理数据 json 序列化问题的 gem
28 |
29 |
30 | # 记录:
31 |
32 | ## [x]对 es6 transpiler 现在的使用情况?
33 | 现在 es6 transpiler 的使用还是挺有限的, 但现在所需要的也就是[ 22 个特性](https://babeljs.io/docs/learn-es6/#classes)中的 6 个重点特性, 其他的现在都无所谓, 重点特性如下
34 |
35 | * arrays: 用于闭包函数的简写方法, 使用 () => {} 来代替 function() {}
36 | * template string: 类似 ruby 中的 string interpolation. 使用 \`hello ${a}\` 代替 "hello " + a;
37 | * let + const: 代替 var 的 let , 变量当前语句\[块作用域\]; const, 和 let 类似但只读. (var 是函数级作用域)
38 | * promises: 非常重要的一个对象, 但简单到只有两个函数: then(onFulfilled, onRejected), catch(onRejected)
39 | * modules: 另外一个非常重要的模块化特性, ember-cli 中利用 [AMD](http://requirejs.org/docs/why.html) 来在 ES5 中实现.
40 | * enhanced object literals: 这个已经在 ember.js 中应用了. 简化在一个地方:
41 |
42 | ```javascript
43 | b = {
44 | a: function {
45 | console.log('a');
46 | }
47 | // 被替换成.
48 | // - 在 Ember.js 中定义 property() 则无法也不要用这种写法
49 | // - 在 router.js 文件中, export default Router.map() 无法享受这样写法, 原因不知
50 | b() {
51 | console.log('b');
52 | }
53 | }
54 | ```
55 |
56 | ## [x]ember.js 与 rails api 之间的 [cors](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing) 问题?
57 | 这个问题其实就是在浏览器中运行的 JavaScript 的跨域安全问题, 如果一定需要部署一个 API 服务器给 Ember.js 进行跨域独立进行, 则需要服务器返回一系列的 Header 头信息和应对处理 Options 代替 HTTP Verb 中的 GET/PUT 请求.
58 | 所以自己为了简便, 以及实际情况 Ember.js 与 rails api 并不会在两个域名下, 所以开发环境使用 ember-cli 提供的 `ember server --proxy http://localhost:3000` 解决了(ember-cli 已经想到这个事情了)
59 |
60 | cors 在 rails 中的应用可以直接使用 [rack-cors](https://github.com/cyu/rack-cors), 然后具体使用例子可参考 ruby-china [#263](https://github.com/ruby-china/ruby-china/pull/263)
61 |
62 |
63 | ## [x]ember.js 与 rails api 交换数据的问题 (json-api)?
64 | 现在(2015.6.18) ember-data 已经随着 ember.js 的版本发布了 ember-data 1.13, 同时 json-api 的规范中的 API 也进入稳定的 1.0. ember-data 也将特定针对 ActiveModelSerialzer 的 Adatper 挪进了 addon 不再进行内置提供. 鼓励大家直接使用 json-api adapter.
65 | 站在 rails 项目的角度, rails 5 将发 rails --api ([#19832](https://github.com/rails/rails/pull/19832)), [Active Model Serialzer](https://github.com/rails-api/active_model_serializers/) 也在 0.10 版本添加上了 JSONAPI Adapter 的支持.
66 | 所以 rails 和 ember-data 之间的数据交互问题, 已经直接通过 JSONAPI 的中间规范解决了.
67 |
68 |
69 | ## [x]SPA 应用第一次访问的初始化加载的问题?
70 | 现在 ember.js 正在着力开发 [FastBoot](https://github.com/tildeio/ember-cli-fastboot); [INSIDE FASTBOOT(1)](http://emberjs.com/blog/2014/12/22/inside-fastboot-the-road-to-server-side-rendering.html), [INSIDE FASTBOOT(2)](http://emberjs.com/blog/2015/01/08/inside-fastboot-faking-the-dom-in-node.html) 这个可以解决这个问题(看看 Discourse 中首次 URL 访问的 Preload js 数据), 所以现在可以不用自己担心在这个方向, 因为整个社区的大方向是这样.
71 | 但现在需要一个过度方案, 现在的过度方案可以学的 Gmail 应用的首次访问的 js 加载进度条以及 js,css 文件访问 CDN 加速方案.
72 | 以下是这个方案比较有用的参考链接:
73 | * [Experimentally verified: "Why client-side templating is wrong"](http://www.onebigfluke.com/2015/01/experimentally-verified-why-client-side.html?m=1)
74 | * [You’re Missing the Point of Server-Side Rendered JavaScript Apps](http://tomdale.net/2015/02/youre-missing-the-point-of-server-side-rendered-javascript-apps/)
75 | * [Ember 2.0 and the Indie Web with Yehuda Katz and Tom Dale](https://frontsidethepodcast.simplecast.fm/16)
76 |
77 |
78 | 如果实在想让抓取引擎抓取 JavaScript 渲染后的东西那么查看一下 [prerender.io](https://prerender.io) 利用 phantomjs 在你的应用与抓取服务器之间做了一个缓存代理.
79 |
80 | ## [x]ember.js 中 Component 数量大, 重绘制速度慢的问题?
81 | 这个问题与我实现 todo item 的功能操作有关, 当自己测试将 todo item 量添加到大概 50 个左右的时候, 每一次改变其中一个 todo item 的 component 的值的时候, 整个 {{#each}} 中的所有 component 都重新计算一次,
82 | 现在还不清楚为什么整个 {{#each}} 中所有 component 都需要重算一次? 但如果后续还有如此的需求, 这样实现肯定是有性能问题的(需要观察正在进行中的新 Ember.js Dom Diff 渲染引擎会有多大改善)
83 |
84 | Ember 1.13 引入的 [Glimmer Engine](https://github.com/emberjs/ember.js/pull/10501)已经有了变化, 原来添加一个新 todo 会重新渲染 50+ 个 todo item 而现在只渲染新增加的那一个, 速度改观非常明显, 这个问题 Ember 1.13 后已经不存在了.
85 | * [isemberfastyet](https://www.isemberfastyet.com/)
86 | * [dbmonster](https://dbmonster.firebaseapp.com/)
87 |
88 | ## [x]ember-cli server 中编译文件现在是全部重新编译, 项目越大文件越多会越慢?
89 | 这个暂时在使用 ember-cli 的时候没有办法解决, 不过好在 ember-cli 在来临的 v1.0.0 版本着手解决这个问题了, 见 [issue 2371](https://github.com/ember-cli/ember-cli/issues/2371), 所以这个什么都不用做, 等着 ember-cli 社区完成后对 ember-cli 更新即可.
90 |
91 | ## [x]如何通过 ember-cli 添加与 bootstrap 或者 sass 的集成?
92 | * [Ember.js Example App w/ Twitter Bootstrap (SASS) and ember-cli](http://erikaybar.name/ember-js-bootstrap-sass-and-ember-cli-quick-start/)
93 | * [Ember-cli, broccoli, bootstrap & sass](http://www.octolabs.com/blogs/octoblog/2014/05/08/ember-cli-broccoli-bootstrap-sass/)
94 |
95 | 1. 通过 bower 为 ember-cli 添加 bootstrap 指定版本的前端依赖.
96 | 2. 通过 npm 为 ember-cli 添加 node.js 需要用到的 broccoli-sass 依赖(使用 broccoli 进行编译)
97 | 3. 引入 bootstrap
98 |
99 | ```javascript
100 | // Brocfile.js
101 | app.import('bower_components/bootstrap-sass-official/assets/javascripts/bootstrap.js');
102 |
103 | ```
104 | 4. 将 app.css 变为 scss
105 |
106 | ```bash
107 | mv app/styles/.css app/styles/.scss
108 | ```
109 | 5. 在 .scss 中 @import 需要的 scss 文件.
110 |
111 | ## [x]ember.js 处理 rails 过来的 Validation errors 问题?
112 | ember.js 中使用 DS.Errors 来封装的 model 中的各项错误, 不愧是来自 jQuery, Rails 社区的 Yehuda Katz 将好东西直接拿过了, 与 Rails 中的 Errors 处理基本上一个模子. 借用了 JavaScript 原生的 Error class 然后封装成 DS.Errors, 当 DS.Model 进行 save/update 等方法执行错误后需要满足两个条件则会自动解析内容并且填充到 DS.Model.errors 中, 其就是 DS.Errors 实例.
113 |
114 | 1. 要求服务器端返回[ 422 错误](https://tools.ietf.org/html/rfc4918#section-11.2)
115 | 2. 返回的结果是 {attribute: [...message]}.
116 | 错误填充到 DS.Model.errors 然后在页面上可以 DS.Model.errors.username 获取展示错误以及通过 DS.Model.errors.messages 展示全部错误信息.
117 |
118 | 在 ember-data 中, 已经根据 JSONAPI 规范进行了处理, 详情见: [#3194](https://github.com/emberjs/data/pull/3194)
119 |
120 | * 服务器响应 4xx , 5xx 错误
121 | * 使用专门的 error Object 来封装错误
122 |
123 |
124 | ## [x]ember.js 与 rails 之间如何进行数据批量保存/更新?
125 | 现在刚刚熟悉 ember.js 的时候要编写批量保存的时候, 思路是想着在页面上为 checkbox 设置自己的 name 属性进行提交, 但实际上应该将提交的属性名字交由 ES.Model 去处理. 我没有在 Ember Data 中找到这样对批量更新的支持, 所以两种方式:
126 |
127 | 1. 将批量变为借用 Ember Data 的 Model 中每一个的 save.
128 | 2. 通过 Ember Data 的 Model 收集数据, 然后 `ic-ajax` 进行自行提交, 但需要自行处理 DS.Model.isDrity 的问题
129 | 这两种方法各有优点, 暂时还没办法直接替代.
130 |
131 |
132 | ## [x]ember.js 中使用 jQuery 的 ajax 返回非标准的 Promise 如何解决?
133 | 在 ember.js 中, 很多情况都会需要使用到 Ember.$.ajax 请求去处理异步的 action 操作或者额外的处理, 但调用的是 jQuery 的 ajax 方法, 返回的是 jQuery Defer 对象. 这里会有两个问题:
134 |
135 | 1. 与 Ember.js 中整体使用的异步请求处理对象 Promise 不匹配. 具体体现在, `$.ajax()` 返回的 defer 对象无 finally 方法, 并且得使用 done, fail 来代替 Promise API 中的 then, catch.
136 | 2. 事件没有最优化进入整个 Ember 的 [run loop](http://guides.emberjs.com/v1.12.0/understanding-ember/run-loop/)
137 |
138 | 但其实, 如果使用 ember-cli 的话, 其生成的项目中已经内置了 [ember-cli-ic-ajax](https://github.com/rwjblue/ember-cli-ic-ajax), 要使用则在代码中 `import ajax from 'ic-ajax';` 即可使用 `ajax()` 方法代替原来的 `Ember.$.ajax()` 方法并且他们接收的参数是一样的.
139 |
140 | ## [x]使用 ember-data 如何处理分页的问题?
141 | 这个问题从 ruby-china 上的一个问题引发过来的, 开始自己还没想到这.
142 | 找到的一个分页例子代码: [Pagination with Ember](http://hawkins.io/2013/07/pagination-with-ember/)
143 |
144 | 分页的问题有两个选择, 一个为本地分页, 一个为远程分页. 个人倾向: 远程分页.
145 |
146 | #### 本地分页
147 | 这个需要利用 ember-data 将数据全部加载到前端的 identity map 缓存住. 但还需要考虑的一个问题是, 这里缓存的数据需要在什么时机与后端的数据进行同步? 进行分页后, 如果控制缓存中直接访问"第N页"?
148 | 可以参考 Gmail 这个应用, 他是拥有本地缓存分页的, 当你加载过数据后, 前后两页的数据是否缓存的, 但其没有仍然是没有给你明确的还有多少页, 只会提供 *下一页* 和 *上一页* 还有就是总数与当前页的数量, 他从用户使用的角度将传统的 1,2,3... page 的功能给省略了, 用户在当前页面处理数据并且自动帮用户加载数据.
149 |
150 | #### 远程分页
151 | 这种方式与原有的结构结合比较容易, 分页的代码交给后端处理, 前端提供参数以及 URL 来访问不同的页面, 并且每一次的分页 URL 请求都将根据 model.id 来更新前端的 identity map 的缓存.
152 | 但这种效果肯定是没有本地分页的那个速度的.
153 |
154 | 从这两个问题我才理解为什么会有 [ember-restless](https://github.com/bustlelabs/ember-restless), 因为很多时候我真的不需要 identity map 这个特性, 即使我退一步每一次数据请求都是通过 Ajax, 即使请求的数据没有缓存. 通过 Ajax 化获取数据, 并将网络控制在一定范围内效果已经非常不错了. (虽然类似 Gmail 这样的应用, 前端的数据使用了缓存)
155 |
156 | #### ember-data 对分页的态度
157 | 完整的讨论 [#1517](https://github.com/emberjs/data/pull/1517), 这个 pull request 还是没有被 merge, 因为 core team 对分页所可能出现的与服务器之间数据的创建和删除导致的页码不一致如何处理等还没有结论.
158 |
159 | ## [x]ember.js 中通过 Ajax 请求超时后怎么办?
160 | 这个学习 Gmail 的应用, 所有需要应对远程的请求, 先进行网络处理并带有非阻拦式的提示处理框, 成功后再对页面 UI 做响应处理. 其次出现网络问题, 在页面给予提示处理. (Ajax 体验类型的问题, 都可以参考 Gmail 这个 SPA Web App)
161 |
162 | [现在代码中是尝试的先 UI 响应, 再网络处理, 失败则 rollback 的处理方法]
163 |
164 | ## [x]将 ember.js 与 rails 部署在不同的地区, 使他们响应时间延长所出现的问题?
165 | 当 ember.js ajax 到 api 的时间在 400ms 以上的时候用户有明显的感觉, 测试后最慢也要控制在 *300ms* 之内, 就算有延时用户也不会感觉迟缓.
166 | #### 响应时间过长的提速
167 | 1. api 后面的本身的计算问题: 这个问题除非后端出现 db 或者自己代码编写的问题会产生延迟, 如果在没有 view render 的情况下还有 300ms 的时间那么这个 api 则是有问题的.
168 | 2. ember.js 与 api 之间的物理网络问题, 这个是一定要想办法控制住的, api 的服务器一定需要尽可能的离客户比较近. 例如中国, 要控制服务器在全国 ping 值常规在 200ms 以内即可(例如到香港,或者国内阿里云), 链接到美国则需要控制机房地址.
169 |
170 | #### 响应间过长,需要避免重复提交
171 | 当响应时间变长的时候引发另外的一个问题, 对 action 触发的事件, 是需要做重复提交处理的, 现在观察 Gmail 的邮件搜索等等功能都没有做处理, 其并非创建这个不处理可以理解, 但最重要的是要避免重复创建提交(例如快速回车重复创建 task 是可能的), 这个则需要对所操作的 action 进行 rails 中的 disabled-with 处理.
172 |
173 | 寻找到几个可行方法:
174 | * Ember 1.13 中的 [`ember-routing-transitioning-classes`](https://github.com/emberjs/ember.js/pull/9919) 功能, 可以让 Link 随着 state 的变化有不同的 className 添加上.
175 | * 模仿 [`Ember.LinkView`](http://emberjs.com/api/classes/Ember.LinkView.html#property_classNameBindings) 中的 `classNameBindings` 控制 button 或者 form 表单的提交.
176 | * [Don't trigger action if its element is disabled](https://github.com/emberjs/ember.js/pull/2240) 这个 issue 中有说明.
177 |
178 | #### 响应时间过长, 连接需要拥有超时控制
179 | 当响应时间变长的时候引发第三个问题, 对于网络链接时间要拥有一个时间控制, 当连接的时间超过某个时间需要对用户进行提示, 并且超过某个阀值后需要对网络做 cancel 或者重试, 类似 Gmail 中每个请求有 timeout, 同样每个请求有自动 retry 以及多次 retry 的间隔时间变长. 这个应该在 ember.js 所依赖的 jQuery 的 ajax 操作中处理.
180 |
181 |
182 | ## [x]在 ember.js 中如何使用第三方的需要全局变量的库文件?
183 | 因为 ember-cli 的 resolver 机制, 所有的库文件默认是不会污染 global 空间的, 这个对原来 Ember 定义 Controller, Router, Model 等等都是放在顶层空间非常不一样, 这种方法也成为 Ember 2.0 的处理方法.
184 | 但还是会有一下现在的 JavaScript 库文件没有使用这样的模块化, 需要使用到 global 空间, 那么 ember-cli 也提供了这种方法, 将需要放在 global 空间中的类名添加到 .jshintrc 中添加需要的全局常量 `{"predef": [..., "Ember", "$", "Cookies"]}` 详细解释在 [stackoverflow](http://stackoverflow.com/questions/24312362/ember-cli-fix-for-ember-is-not-defined) (写法上会有一点区别)
185 |
186 | ## [x]在 ember.js 中使用的 Promise
187 | 在 ember 中, 非常多的地方使用到 Promise, 那么理解 Promise 非常重要. 参看两个链接, 一个[中文](http://www.html-js.com/article/Learn-JavaScript-every-day-to-understand-what-JavaScript-Promises)一个[英文](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise).
188 | [例子代码](http://jsbin.com/IkaS/1/edit?html,js,output)
189 |
190 | #### 四个状态:
191 | * pending: initial state, not fulfilled or rejected
192 | * fulfilled: successful operation
193 | * rejected: failed operation
194 | * settled: the Promise is either fulfilled or rejected, but not pending.
195 |
196 | #### 两个参数
197 | * resolve: fulfilled 状态需要调用的方法
198 | * reject: rejected 需要调用的方法
199 |
200 | #### 两个方法
201 | * then: Appends fulfillment and rejection handlers to the promise, and returns a new promise resolving to the return value of the called handler
202 | * catch: Appends a rejection handler callback to the promise, and returns a new promise resolving to the return value of the callback if it is called, or to its original fulfillment value if the promise is instead fulfilled
203 |
204 | ## [x]ember-cli 前端如何处理权限以及验证的问题?
205 | 如果需要很多部分进行合作处理, 并且在参考了多个建立在 Ember 1.x 版本中的例子[ember-simple-auth](https://github.com/simplabs/ember-simple-auth) 以及 [torii](https://github.com/vestorly/torii). 下面是主要的思路:
206 | 1. 需要使用 Service 在多个不同的上下文 Context 中共享一些用户登陆的信息, 并且需要自己处理用户体验方面的功能.
207 | 2. 在 template 中需要使用到重复字段的时候, 需要使用到 Ember.Mixin. Ember 中专门用于共享页面上下文字段功能
208 | 3. 根据所需要的功能, 将 Ember.Mixin 引入到 Router(在 beforeModel 中拦截请求) , Controller(在各种 Controller 里面共享变量) 上, 为需要进行验证的 Route 与 Controller 添加特性.
209 |
210 | #### [90%]注意几个点
211 | 1. 与前端登陆/登陆/用户/错误信息等的完整一套在 service 中全部处理.
212 | 2. 利用 mixin 将 service 中需要共享给 Router 与 Controller 的字段全部共享出去.
213 | 3. 思考, 在 Ember 2.1 中没有 Controller 了使用 [Routable Components](https://github.com/emberjs/rfcs/pull/38) 该如何处理?
214 |
215 | ## [70%]Ember 1.13 [Glimmer] 对 Component 中的 attrs 不同处理.
216 | 在新 Glimmer 引擎下, 传入 Component 的参数都被存储在默认不可变的 `attrs` 中, 如果 attrs 与 Component 中有同名的属性会优先使用 *不可变* 的 attrs 中的.
217 | 对于 [Glimmer] 的新功能详细介绍, 还需要等 Ember 官方更新一些文档后才能详细知晓.
218 |
219 | 现在还是建议使用 `{{my-component}}` 的形式, `angle bracket components` 还是等 Ember 1.13 更新了文档了解清楚后再使用. 因为使用后者还是有一些小问题, 例如 Component 中的 tagName 属性失效了.
220 | 还有例如: 现在传入 Component 的 `model` todo, 会自动标记为 `mutable` 拥有 `update` 函数, 同时在 Component 中作为参数的 `todo` 和 `attrs.todo` 都可使用, 但不知道具体会有什么区别, 这个也需要等待文档更新(何时判断为传入 function 的参数? 何时判断为 attrs?).
221 |
222 | ## [x]ember-cli 中在开发环境中不断出现的 Content Security Policy violation 提示还不知道如何解决?
223 | ember-cli 中的 [Content Security Policy](http://content-security-policy.com), 在 emberjs 中使用的是 [ember-cli content-security-policy addon](https://github.com/rwjblue/ember-cli-content-security-policy), 例如: 在 `enviroment.js` 文件中添加:
224 |
225 | ```javascript
226 | contentSecurityPolicy: {
227 | 'default-src': "'none'",
228 | 'script-src': "'self' https://cdn.mxpnl.com", // Allow scripts from https://cdn.mxpnl.com
229 | 'font-src': "'self' http://fonts.gstatic.com", // Allow fonts to be loaded from http://fonts.gstatic.com
230 | 'connect-src': "'self' https://api.mixpanel.com http://custom-api.local", // Allow data (ajax/websocket) from api.mixpanel.com and custom-api.local
231 | 'img-src': "'self' https://ruby-china.org https://*.upaiyun.com",
232 | 'style-src': "'self' 'unsafe-inline' http://fonts.googleapis.com", // Allow inline styles and loaded CSS from http://fonts.googleapis.com
233 | 'media-src': "'self'"
234 | }
235 | ```
236 |
237 | ## [x]开发中碰到 scroll 的状态在页面 transition 后记录, 但是我们希望他不被记录, 每次页面转换都是在最上面.
238 | 这个问题 emberjs 有官方解答 [RESETTING SCROLL ON ROUTE CHANGES](http://guides.emberjs.com/v1.10.0/cookbook/user_interface_and_interaction/resetting_scroll_on_route_changes/), 使用 mixin 进行解决.
239 | 作为我自己的使用来说, 因为 Ember.Route 中的 `activate` hook 只有在进入这个 Route 的时候才被调用而如果在同一个页面使用 `?page=2` 这样的参数 Link 访问是不会跳出(deactivate)再跳入的, 所以我更喜欢使用 `didTransition` 这个 action 来处理这个事情. 例如下面的 Mixin 代码 `scroll-rest.js`:
240 |
241 | ```javascript
242 | export default Ember.Mixin.create({
243 | actions: {
244 | didTransition() {
245 | window.scrollTo(0, 0);
246 | console.log('mixin didTransition');
247 | return true;
248 | }
249 | }
250 | });
251 | ```
252 |
253 | ## SPA 应用中的实时交互问题及 ember.js + socket.io 的问题?
254 | TODO 有思路以及方向, 但还需要具体方案在以及 demo 去实践, 寻找坑填坑.
255 |
256 | ## ember.js 应用如何使用 socket.io 与 rails 结合起来组成实时信息推送的问题?
257 | TODO rails -> redis pub, redis sub -> socket.io -> ember.js?
258 |
259 | ## 产品环境如何部署 ember-cli, socket.io, rails ?
260 | TODO 难道使用 docker 将三个东西打包到一起进行更新?
261 |
262 |
--------------------------------------------------------------------------------
/front/app/styles/_settings.scss:
--------------------------------------------------------------------------------
1 | // Foundation by ZURB
2 | // foundation.zurb.com
3 | // Licensed under MIT Open Source
4 |
5 | //
6 |
7 | // Table of Contents
8 | // Foundation Settings
9 | //
10 | // a. Base
11 | // b. Grid
12 | // c. Global
13 | // d. Media Query Ranges
14 | // e. Typography
15 | // 01. Accordion
16 | // 02. Alert Boxes
17 | // 03. Block Grid
18 | // 04. Breadcrumbs
19 | // 05. Buttons
20 | // 06. Button Groups
21 | // 07. Clearing
22 | // 08. Dropdown
23 | // 09. Dropdown Buttons
24 | // 10. Flex Video
25 | // 11. Forms
26 | // 12. Icon Bar
27 | // 13. Inline Lists
28 | // 14. Joyride
29 | // 15. Keystrokes
30 | // 16. Labels
31 | // 17. Magellan
32 | // 18. Off-canvas
33 | // 19. Orbit
34 | // 20. Pagination
35 | // 21. Panels
36 | // 22. Pricing Tables
37 | // 23. Progress Bar
38 | // 24. Range Slider
39 | // 25. Reveal
40 | // 26. Side Nav
41 | // 27. Split Buttons
42 | // 28. Sub Nav
43 | // 29. Switch
44 | // 30. Tables
45 | // 31. Tabs
46 | // 32. Thumbnails
47 | // 33. Tooltips
48 | // 34. Top Bar
49 | // 36. Visibility Classes
50 |
51 | // a. Base
52 | // - - - - - - - - - - - - - - - - - - - - - - - - -
53 |
54 | // This is the default html and body font-size for the base rem value.
55 | // $rem-base: 16px;
56 |
57 | // Allows the use of rem-calc() or lower-bound() in your settings
58 | @import 'foundation/functions';
59 |
60 | // The default font-size is set to 100% of the browser style sheet (usually 16px)
61 | // for compatibility with browser-based text zoom or user-set defaults.
62 |
63 | // Since the typical default browser font-size is 16px, that makes the calculation for grid size.
64 | // If you want your base font-size to be different and not have it affect the grid breakpoints,
65 | // set $rem-base to $base-font-size and make sure $base-font-size is a px value.
66 | // $base-font-size: 100%;
67 |
68 | // The $base-font-size is 100% while $base-line-height is 150%
69 | // $base-line-height: 150%;
70 |
71 | // We use this to control whether or not CSS classes come through in the gem files.
72 | $include-html-classes: true;
73 | // $include-print-styles: true;
74 | $include-html-global-classes: $include-html-classes;
75 |
76 | // b. Grid
77 | // - - - - - - - - - - - - - - - - - - - - - - - - -
78 |
79 | // $include-html-grid-classes: $include-html-classes;
80 | // $include-xl-html-grid-classes: false;
81 |
82 | // $row-width: rem-calc(1000);
83 | // $total-columns: 12;
84 | // $column-gutter: rem-calc(30);
85 |
86 | // c. Global
87 | // - - - - - - - - - - - - - - - - - - - - - - - - -
88 |
89 | // We use these to define default font stacks
90 | // $font-family-sans-serif: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif;
91 | // $font-family-serif: Georgia, Cambria, "Times New Roman", Times, serif;
92 | // $font-family-monospace: Consolas, "Liberation Mono", Courier, monospace;
93 |
94 | // We use these to define default font weights
95 | // $font-weight-normal: normal;
96 | // $font-weight-bold: bold;
97 |
98 | // $white : #FFFFFF;
99 | // $ghost : #FAFAFA;
100 | // $snow : #F9F9F9;
101 | // $vapor : #F6F6F6;
102 | // $white-smoke : #F5F5F5;
103 | // $silver : #EFEFEF;
104 | // $smoke : #EEEEEE;
105 | // $gainsboro : #DDDDDD;
106 | // $iron : #CCCCCC;
107 | // $base : #AAAAAA;
108 | // $aluminum : #999999;
109 | // $jumbo : #888888;
110 | // $monsoon : #777777;
111 | // $steel : #666666;
112 | // $charcoal : #555555;
113 | // $tuatara : #444444;
114 | // $oil : #333333;
115 | // $jet : #222222;
116 | // $black : #000000;
117 |
118 | // We use these as default colors throughout
119 | // $primary-color: #008CBA;
120 | // $secondary-color: #e7e7e7;
121 | // $alert-color: #f04124;
122 | // $success-color: #43AC6A;
123 | // $warning-color: #f08a24;
124 | // $info-color: #a0d3e8;
125 |
126 | // We use these to control various global styles
127 | // $body-bg: $white;
128 | // $body-font-color: $jet;
129 | // $body-font-family: $font-family-sans-serif;
130 | // $body-font-weight: $font-weight-normal;
131 | // $body-font-style: normal;
132 |
133 | // We use this to control font-smoothing
134 | // $font-smoothing: antialiased;
135 |
136 | // We use these to control text direction settings
137 | // $text-direction: ltr;
138 | // $opposite-direction: right;
139 | // $default-float: left;
140 | // $last-child-float: $opposite-direction;
141 |
142 | // We use these to make sure border radius matches unless we want it different.
143 | // $global-radius: 3px;
144 | // $global-rounded: 1000px;
145 |
146 | // We use these to control inset shadow shiny edges and depressions.
147 | // $shiny-edge-size: 0 1px 0;
148 | // $shiny-edge-color: rgba($white, .5);
149 | // $shiny-edge-active-color: rgba($black, .2);
150 |
151 | // d. Media Query Ranges
152 | // - - - - - - - - - - - - - - - - - - - - - - - - -
153 |
154 | // $small-breakpoint: em-calc(640);
155 | // $medium-breakpoint: em-calc(1024);
156 | // $large-breakpoint: em-calc(1440);
157 | // $xlarge-breakpoint: em-calc(1920);
158 |
159 | // $small-range: (0, $small-breakpoint);
160 | // $medium-range: ($small-breakpoint + em-calc(1), $medium-breakpoint);
161 | // $large-range: ($medium-breakpoint + em-calc(1), $large-breakpoint);
162 | // $xlarge-range: ($large-breakpoint + em-calc(1), $xlarge-breakpoint);
163 | // $xxlarge-range: ($xlarge-breakpoint + em-calc(1), em-calc(99999999));
164 |
165 | // $screen: "only screen";
166 |
167 | // $landscape: "#{$screen} and (orientation: landscape)";
168 | // $portrait: "#{$screen} and (orientation: portrait)";
169 |
170 | // $small-up: $screen;
171 | // $small-only: "#{$screen} and (max-width: #{upper-bound($small-range)})";
172 |
173 | // $medium-up: "#{$screen} and (min-width:#{lower-bound($medium-range)})";
174 | // $medium-only: "#{$screen} and (min-width:#{lower-bound($medium-range)}) and (max-width:#{upper-bound($medium-range)})";
175 |
176 | // $large-up: "#{$screen} and (min-width:#{lower-bound($large-range)})";
177 | // $large-only: "#{$screen} and (min-width:#{lower-bound($large-range)}) and (max-width:#{upper-bound($large-range)})";
178 |
179 | // $xlarge-up: "#{$screen} and (min-width:#{lower-bound($xlarge-range)})";
180 | // $xlarge-only: "#{$screen} and (min-width:#{lower-bound($xlarge-range)}) and (max-width:#{upper-bound($xlarge-range)})";
181 |
182 | // $xxlarge-up: "#{$screen} and (min-width:#{lower-bound($xxlarge-range)})";
183 | // $xxlarge-only: "#{$screen} and (min-width:#{lower-bound($xxlarge-range)}) and (max-width:#{upper-bound($xxlarge-range)})";
184 |
185 | // $retina: (
186 | // "#{$screen} and (-webkit-min-device-pixel-ratio: 2)",
187 | // "#{$screen} and (min--moz-device-pixel-ratio: 2)",
188 | // "#{$screen} and (-o-min-device-pixel-ratio: 2/1)",
189 | // "#{$screen} and (min-device-pixel-ratio: 2)",
190 | // "#{$screen} and (min-resolution: 192dpi)",
191 | // "#{$screen} and (min-resolution: 2dppx)"
192 | // );
193 |
194 | // Legacy
195 | // $small: $medium-up;
196 | // $medium: $medium-up;
197 | // $large: $large-up;
198 |
199 | // We use this as cursors values for enabling the option of having custom cursors in the whole site's stylesheet
200 | // $cursor-crosshair-value: crosshair;
201 | // $cursor-default-value: default;
202 | // $cursor-disabled-value: not-allowed;
203 | // $cursor-pointer-value: pointer;
204 | // $cursor-help-value: help;
205 | // $cursor-text-value: text;
206 |
207 | // e. Typography
208 | // - - - - - - - - - - - - - - - - - - - - - - - - -
209 |
210 | // $include-html-type-classes: $include-html-classes;
211 |
212 | // We use these to control header font styles
213 | // $header-font-family: $body-font-family;
214 | // $header-font-weight: $font-weight-normal;
215 | // $header-font-style: normal;
216 | // $header-font-color: $jet;
217 | // $header-line-height: 1.4;
218 | // $header-top-margin: .2rem;
219 | // $header-bottom-margin: .5rem;
220 | // $header-text-rendering: optimizeLegibility;
221 |
222 | // We use these to control header font sizes
223 | // $h1-font-size: rem-calc(44);
224 | // $h2-font-size: rem-calc(37);
225 | // $h3-font-size: rem-calc(27);
226 | // $h4-font-size: rem-calc(23);
227 | // $h5-font-size: rem-calc(18);
228 | // $h6-font-size: 1rem;
229 |
230 | // We use these to control header size reduction on small screens
231 | // $h1-font-reduction: rem-calc(10);
232 | // $h2-font-reduction: rem-calc(10);
233 | // $h3-font-reduction: rem-calc(5);
234 | // $h4-font-reduction: rem-calc(5);
235 | // $h5-font-reduction: 0;
236 | // $h6-font-reduction: 0;
237 |
238 | // These control how subheaders are styled.
239 | // $subheader-line-height: 1.4;
240 | // $subheader-font-color: scale-color($header-font-color, $lightness: 35%);
241 | // $subheader-font-weight: $font-weight-normal;
242 | // $subheader-top-margin: .2rem;
243 | // $subheader-bottom-margin: .5rem;
244 |
245 | // A general styling
246 | // $small-font-size: 60%;
247 | // $small-font-color: scale-color($header-font-color, $lightness: 35%);
248 |
249 | // We use these to style paragraphs
250 | // $paragraph-font-family: inherit;
251 | // $paragraph-font-weight: $font-weight-normal;
252 | // $paragraph-font-size: 1rem;
253 | // $paragraph-line-height: 1.6;
254 | // $paragraph-margin-bottom: rem-calc(20);
255 | // $paragraph-aside-font-size: rem-calc(14);
256 | // $paragraph-aside-line-height: 1.35;
257 | // $paragraph-aside-font-style: italic;
258 | // $paragraph-text-rendering: optimizeLegibility;
259 |
260 | // We use these to style tags
261 | // $code-color: $oil;
262 | // $code-font-family: $font-family-monospace;
263 | // $code-font-weight: $font-weight-normal;
264 | // $code-background-color: scale-color($secondary-color, $lightness: 70%);
265 | // $code-border-size: 1px;
266 | // $code-border-style: solid;
267 | // $code-border-color: scale-color($code-background-color, $lightness: -10%);
268 | // $code-padding: rem-calc(2) rem-calc(5) rem-calc(1);
269 |
270 | // We use these to style anchors
271 | // $anchor-text-decoration: none;
272 | // $anchor-text-decoration-hover: none;
273 | // $anchor-font-color: $primary-color;
274 | // $anchor-font-color-hover: scale-color($anchor-font-color, $lightness: -14%);
275 |
276 | // We use these to style the
element
277 | // $hr-border-width: 1px;
278 | // $hr-border-style: solid;
279 | // $hr-border-color: $gainsboro;
280 | // $hr-margin: rem-calc(20);
281 |
282 | // We use these to style lists
283 | // $list-font-family: $paragraph-font-family;
284 | // $list-font-size: $paragraph-font-size;
285 | // $list-line-height: $paragraph-line-height;
286 | // $list-margin-bottom: $paragraph-margin-bottom;
287 | // $list-style-position: outside;
288 | // $list-side-margin: 1.1rem;
289 | // $list-ordered-side-margin: 1.4rem;
290 | // $list-side-margin-no-bullet: 0;
291 | // $list-nested-margin: rem-calc(20);
292 | // $definition-list-header-weight: $font-weight-bold;
293 | // $definition-list-header-margin-bottom: .3rem;
294 | // $definition-list-margin-bottom: rem-calc(12);
295 |
296 | // We use these to style blockquotes
297 | // $blockquote-font-color: scale-color($header-font-color, $lightness: 35%);
298 | // $blockquote-padding: rem-calc(9 20 0 19);
299 | // $blockquote-border: 1px solid $gainsboro;
300 | // $blockquote-cite-font-size: rem-calc(13);
301 | // $blockquote-cite-font-color: scale-color($header-font-color, $lightness: 23%);
302 | // $blockquote-cite-link-color: $blockquote-cite-font-color;
303 |
304 | // Acronym styles
305 | // $acronym-underline: 1px dotted $gainsboro;
306 |
307 | // We use these to control padding and margin
308 | // $microformat-padding: rem-calc(10 12);
309 | // $microformat-margin: rem-calc(0 0 20 0);
310 |
311 | // We use these to control the border styles
312 | // $microformat-border-width: 1px;
313 | // $microformat-border-style: solid;
314 | // $microformat-border-color: $gainsboro;
315 |
316 | // We use these to control full name font styles
317 | // $microformat-fullname-font-weight: $font-weight-bold;
318 | // $microformat-fullname-font-size: rem-calc(15);
319 |
320 | // We use this to control the summary font styles
321 | // $microformat-summary-font-weight: $font-weight-bold;
322 |
323 | // We use this to control abbr padding
324 | // $microformat-abbr-padding: rem-calc(0 1);
325 |
326 | // We use this to control abbr font styles
327 | // $microformat-abbr-font-weight: $font-weight-bold;
328 | // $microformat-abbr-font-decoration: none;
329 |
330 | // 01. Accordion
331 | // - - - - - - - - - - - - - - - - - - - - - - - - -
332 |
333 | // $include-html-accordion-classes: $include-html-classes;
334 |
335 | // $accordion-navigation-padding: rem-calc(16);
336 | // $accordion-navigation-bg-color: $silver;
337 | // $accordion-navigation-hover-bg-color: scale-color($accordion-navigation-bg-color, $lightness: -5%);
338 | // $accordion-navigation-active-bg-color: scale-color($accordion-navigation-bg-color, $lightness: -3%);
339 | // $accordion-navigation-font-color: $jet;
340 | // $accordion-navigation-font-size: rem-calc(16);
341 | // $accordion-navigation-font-family: $body-font-family;
342 |
343 | // $accordion-content-padding: ($column-gutter/2);
344 | // $accordion-content-active-bg-color: $white;
345 |
346 | // 02. Alert Boxes
347 | // - - - - - - - - - - - - - - - - - - - - - - - - -
348 |
349 | // $include-html-alert-classes: $include-html-classes;
350 |
351 | // We use this to control alert padding.
352 | // $alert-padding-top: rem-calc(14);
353 | // $alert-padding-default-float: $alert-padding-top;
354 | // $alert-padding-opposite-direction: $alert-padding-top + rem-calc(10);
355 | // $alert-padding-bottom: $alert-padding-top;
356 |
357 | // We use these to control text style.
358 | // $alert-font-weight: $font-weight-normal;
359 | // $alert-font-size: rem-calc(13);
360 | // $alert-font-color: $white;
361 | // $alert-font-color-alt: scale-color($secondary-color, $lightness: -66%);
362 |
363 | // We use this for close hover effect.
364 | // $alert-function-factor: -14%;
365 |
366 | // We use these to control border styles.
367 | // $alert-border-style: solid;
368 | // $alert-border-width: 1px;
369 | // $alert-border-color: scale-color($primary-color, $lightness: $alert-function-factor);
370 | // $alert-bottom-margin: rem-calc(20);
371 |
372 | // We use these to style the close buttons
373 | // $alert-close-color: $oil;
374 | // $alert-close-top: 50%;
375 | // $alert-close-position: rem-calc(4);
376 | // $alert-close-font-size: rem-calc(22);
377 | // $alert-close-opacity: .3;
378 | // $alert-close-opacity-hover: .5;
379 | // $alert-close-padding: 9px 6px 4px;
380 | // $alert-close-background: inherit;
381 |
382 | // We use this to control border radius
383 | // $alert-radius: $global-radius;
384 |
385 | // $alert-transition-speed: 300ms;
386 | // $alert-transition-ease: ease-out;
387 |
388 | // 03. Block Grid
389 | // - - - - - - - - - - - - - - - - - - - - - - - - -
390 |
391 | // $include-html-block-grid-classes: $include-html-classes;
392 | // $include-xl-html-block-grid-classes: false;
393 |
394 | // We use this to control the maximum number of block grid elements per row
395 | // $block-grid-elements: 12;
396 | // $block-grid-default-spacing: rem-calc(20);
397 |
398 | // $align-block-grid-to-grid: false;
399 | // @if $align-block-grid-to-grid {$block-grid-default-spacing: $column-gutter;}
400 |
401 | // Enables media queries for block-grid classes. Set to false if writing semantic HTML.
402 | // $block-grid-media-queries: true;
403 |
404 | // 04. Breadcrumbs
405 | // - - - - - - - - - - - - - - - - - - - - - - - - -
406 |
407 | // $include-html-nav-classes: $include-html-classes;
408 |
409 | // We use this to set the background color for the breadcrumb container.
410 | // $crumb-bg: scale-color($secondary-color, $lightness: 55%);
411 |
412 | // We use these to set the padding around the breadcrumbs.
413 | // $crumb-padding: rem-calc(9 14 9);
414 | // $crumb-side-padding: rem-calc(12);
415 |
416 | // We use these to control border styles.
417 | // $crumb-function-factor: -10%;
418 | // $crumb-border-size: 1px;
419 | // $crumb-border-style: solid;
420 | // $crumb-border-color: scale-color($crumb-bg, $lightness: $crumb-function-factor);
421 | // $crumb-radius: $global-radius;
422 |
423 | // We use these to set various text styles for breadcrumbs.
424 | // $crumb-font-size: rem-calc(11);
425 | // $crumb-font-color: $primary-color;
426 | // $crumb-font-color-current: $oil;
427 | // $crumb-font-color-unavailable: $aluminum;
428 | // $crumb-font-transform: uppercase;
429 | // $crumb-link-decor: underline;
430 |
431 | // We use these to control the slash between breadcrumbs
432 | // $crumb-slash-color: $base;
433 | // $crumb-slash: "/";
434 |
435 | // 05. Buttons
436 | // - - - - - - - - - - - - - - - - - - - - - - - - -
437 |
438 | // $include-html-button-classes: $include-html-classes;
439 |
440 | // We use these to build padding for buttons.
441 | // $button-tny: rem-calc(10);
442 | // $button-sml: rem-calc(14);
443 | // $button-med: rem-calc(16);
444 | // $button-lrg: rem-calc(18);
445 |
446 | // We use this to control the display property.
447 | // $button-display: inline-block;
448 | // $button-margin-bottom: rem-calc(20);
449 |
450 | // We use these to control button text styles.
451 | // $button-font-family: $body-font-family;
452 | // $button-font-color: $white;
453 | // $button-font-color-alt: $oil;
454 | // $button-font-tny: rem-calc(11);
455 | // $button-font-sml: rem-calc(13);
456 | // $button-font-med: rem-calc(16);
457 | // $button-font-lrg: rem-calc(20);
458 | // $button-font-weight: $font-weight-normal;
459 | // $button-font-align: center;
460 |
461 | // We use these to control various hover effects.
462 | // $button-function-factor: -20%;
463 |
464 | // We use these to control button border styles.
465 | // $button-border-width: 0;
466 | // $button-border-style: solid;
467 | // $button-bg-color: $primary-color;
468 | // $button-bg-hover: scale-color($button-bg-color, $lightness: $button-function-factor);
469 | // $button-border-color: $button-bg-hover;
470 | // $secondary-button-bg-hover: scale-color($secondary-color, $lightness: $button-function-factor);
471 | // $secondary-button-border-color: $secondary-button-bg-hover;
472 | // $success-button-bg-hover: scale-color($success-color, $lightness: $button-function-factor);
473 | // $success-button-border-color: $success-button-bg-hover;
474 | // $alert-button-bg-hover: scale-color($alert-color, $lightness: $button-function-factor);
475 | // $alert-button-border-color: $alert-button-bg-hover;
476 | // $warning-button-bg-hover: scale-color($warning-color, $lightness: $button-function-factor);
477 | // $warning-button-border-color: $warning-button-bg-hover;
478 | // $info-button-bg-hover: scale-color($info-color, $lightness: $button-function-factor);
479 | // $info-button-border-color: $info-button-bg-hover;
480 |
481 | // We use this to set the default radius used throughout the core.
482 | // $button-radius: $global-radius;
483 | // $button-round: $global-rounded;
484 |
485 | // We use this to set default opacity and cursor for disabled buttons.
486 | // $button-disabled-opacity: .7;
487 | // $button-disabled-cursor: $cursor-default-value;
488 |
489 | // 06. Button Groups
490 | // - - - - - - - - - - - - - - - - - - - - - - - - -
491 |
492 | // $include-html-button-classes: $include-html-classes;
493 |
494 | // Sets the margin for the right side by default, and the left margin if right-to-left direction is used
495 | // $button-bar-margin-opposite: rem-calc(10);
496 | // $button-group-border-width: 1px;
497 |
498 | // 07. Clearing
499 | // - - - - - - - - - - - - - - - - - - - - - - - - -
500 |
501 | // $include-html-clearing-classes: $include-html-classes;
502 |
503 | // We use these to set the background colors for parts of Clearing.
504 | // $clearing-bg: $oil;
505 | // $clearing-caption-bg: $clearing-bg;
506 | // $clearing-carousel-bg: rgba(51,51,51,0.8);
507 | // $clearing-img-bg: $clearing-bg;
508 |
509 | // We use these to style the close button
510 | // $clearing-close-color: $iron;
511 | // $clearing-close-size: 30px;
512 |
513 | // We use these to style the arrows
514 | // $clearing-arrow-size: 12px;
515 | // $clearing-arrow-color: $clearing-close-color;
516 |
517 | // We use these to style captions
518 | // $clearing-caption-font-color: $iron;
519 | // $clearing-caption-font-size: .875em;
520 | // $clearing-caption-padding: 10px 30px 20px;
521 |
522 | // We use these to make the image and carousel height and style
523 | // $clearing-active-img-height: 85%;
524 | // $clearing-carousel-height: 120px;
525 | // $clearing-carousel-thumb-width: 120px;
526 | // $clearing-carousel-thumb-active-border: 1px solid rgb(255,255,255);
527 |
528 | // 08. Dropdown
529 | // - - - - - - - - - - - - - - - - - - - - - - - - -
530 |
531 | // $include-html-dropdown-classes: $include-html-classes;
532 |
533 | // We use these to controls height and width styles.
534 | // $f-dropdown-max-width: 200px;
535 | // $f-dropdown-height: auto;
536 | // $f-dropdown-max-height: none;
537 |
538 | // Used for bottom position
539 | // $f-dropdown-margin-top: 2px;
540 |
541 | // Used for right position
542 | // $f-dropdown-margin-left: $f-dropdown-margin-top;
543 |
544 | // Used for left position
545 | // $f-dropdown-margin-right: $f-dropdown-margin-top;
546 |
547 | // Used for top position
548 | // $f-dropdown-margin-bottom: $f-dropdown-margin-top;
549 |
550 | // We use this to control the background color
551 | // $f-dropdown-bg: $white;
552 |
553 | // We use this to set the border styles for dropdowns.
554 | // $f-dropdown-border-style: solid;
555 | // $f-dropdown-border-width: 1px;
556 | // $f-dropdown-border-color: scale-color($white, $lightness: -20%);
557 |
558 | // We use these to style the triangle pip.
559 | // $f-dropdown-triangle-size: 6px;
560 | // $f-dropdown-triangle-color: $white;
561 | // $f-dropdown-triangle-side-offset: 10px;
562 |
563 | // We use these to control styles for the list elements.
564 | // $f-dropdown-list-style: none;
565 | // $f-dropdown-font-color: $charcoal;
566 | // $f-dropdown-font-size: rem-calc(14);
567 | // $f-dropdown-list-padding: rem-calc(5, 10);
568 | // $f-dropdown-line-height: rem-calc(18);
569 | // $f-dropdown-list-hover-bg: $smoke;
570 | // $dropdown-mobile-default-float: 0;
571 |
572 | // We use this to control the styles for when the dropdown has custom content.
573 | // $f-dropdown-content-padding: rem-calc(20);
574 |
575 | // Default radius for dropdown.
576 | // $f-dropdown-radius: $global-radius;
577 |
578 |
579 | // 09. Dropdown Buttons
580 | // - - - - - - - - - - - - - - - - - - - - - - - - -
581 |
582 | // $include-html-button-classes: $include-html-classes;
583 |
584 | // We use these to set the color of the pip in dropdown buttons
585 | // $dropdown-button-pip-color: $white;
586 | // $dropdown-button-pip-color-alt: $oil;
587 |
588 | // We use these to set the size of the pip in dropdown buttons
589 | // $button-pip-tny: rem-calc(6);
590 | // $button-pip-sml: rem-calc(7);
591 | // $button-pip-med: rem-calc(9);
592 | // $button-pip-lrg: rem-calc(11);
593 |
594 | // We use these to style tiny dropdown buttons
595 | // $dropdown-button-padding-tny: $button-pip-tny * 7;
596 | // $dropdown-button-pip-size-tny: $button-pip-tny;
597 | // $dropdown-button-pip-opposite-tny: $button-pip-tny * 3;
598 | // $dropdown-button-pip-top-tny: (-$button-pip-tny / 2) + rem-calc(1);
599 |
600 | // We use these to style small dropdown buttons
601 | // $dropdown-button-padding-sml: $button-pip-sml * 7;
602 | // $dropdown-button-pip-size-sml: $button-pip-sml;
603 | // $dropdown-button-pip-opposite-sml: $button-pip-sml * 3;
604 | // $dropdown-button-pip-top-sml: (-$button-pip-sml / 2) + rem-calc(1);
605 |
606 | // We use these to style medium dropdown buttons
607 | // $dropdown-button-padding-med: $button-pip-med * 6 + rem-calc(3);
608 | // $dropdown-button-pip-size-med: $button-pip-med - rem-calc(3);
609 | // $dropdown-button-pip-opposite-med: $button-pip-med * 2.5;
610 | // $dropdown-button-pip-top-med: (-$button-pip-med / 2) + rem-calc(2);
611 |
612 | // We use these to style large dropdown buttons
613 | // $dropdown-button-padding-lrg: $button-pip-lrg * 5 + rem-calc(3);
614 | // $dropdown-button-pip-size-lrg: $button-pip-lrg - rem-calc(6);
615 | // $dropdown-button-pip-opposite-lrg: $button-pip-lrg * 2.5;
616 | // $dropdown-button-pip-top-lrg: (-$button-pip-lrg / 2) + rem-calc(3);
617 |
618 | // 10. Flex Video
619 | // - - - - - - - - - - - - - - - - - - - - - - - - -
620 |
621 | // $include-html-media-classes: $include-html-classes;
622 |
623 | // We use these to control video container padding and margins
624 | // $flex-video-padding-top: rem-calc(25);
625 | // $flex-video-padding-bottom: 67.5%;
626 | // $flex-video-margin-bottom: rem-calc(16);
627 |
628 | // We use this to control widescreen bottom padding
629 | // $flex-video-widescreen-padding-bottom: 56.34%;
630 |
631 | // 11. Forms
632 | // - - - - - - - - - - - - - - - - - - - - - - - - -
633 |
634 | // $include-html-form-classes: $include-html-classes;
635 |
636 | // We use this to set the base for lots of form spacing and positioning styles
637 | // $form-spacing: rem-calc(16);
638 |
639 | // We use these to style the labels in different ways
640 | // $form-label-pointer: pointer;
641 | // $form-label-font-size: rem-calc(14);
642 | // $form-label-font-weight: $font-weight-normal;
643 | // $form-label-line-height: 1.5;
644 | // $form-label-font-color: scale-color($black, $lightness: 30%);
645 | // $form-label-small-transform: capitalize;
646 | // $form-label-bottom-margin: 0;
647 | // $input-font-family: inherit;
648 | // $input-font-color: rgba(0,0,0,0.75);
649 | // $input-font-size: rem-calc(14);
650 | // $input-bg-color: $white;
651 | // $input-focus-bg-color: scale-color($white, $lightness: -2%);
652 | // $input-border-color: scale-color($white, $lightness: -20%);
653 | // $input-focus-border-color: scale-color($white, $lightness: -40%);
654 | // $input-border-style: solid;
655 | // $input-border-width: 1px;
656 | // $input-border-radius: $global-radius;
657 | // $input-disabled-bg: $gainsboro;
658 | // $input-disabled-cursor: $cursor-default-value;
659 | // $input-box-shadow: inset 0 1px 2px rgba(0,0,0,0.1);
660 | // $input-include-glowing-effect: false;
661 |
662 | // We use these to style the fieldset border and spacing.
663 | // $fieldset-border-style: solid;
664 | // $fieldset-border-width: 1px;
665 | // $fieldset-border-color: $gainsboro;
666 | // $fieldset-padding: rem-calc(20);
667 | // $fieldset-margin: rem-calc(18 0);
668 |
669 | // We use these to style the legends when you use them
670 | // $legend-bg: $white;
671 | // $legend-font-weight: $font-weight-bold;
672 | // $legend-padding: rem-calc(0 3);
673 |
674 | // We use these to style the prefix and postfix input elements
675 | // $input-prefix-bg: scale-color($white, $lightness: -5%);
676 | // $input-prefix-border-color: scale-color($white, $lightness: -20%);
677 | // $input-prefix-border-size: 1px;
678 | // $input-prefix-border-type: solid;
679 | // $input-prefix-overflow: hidden;
680 | // $input-prefix-font-color: $oil;
681 | // $input-prefix-font-color-alt: $white;
682 |
683 | // We use this setting to turn on/off HTML5 number spinners (the up/down arrows)
684 | // $input-number-spinners: true;
685 |
686 | // We use these to style the error states for inputs and labels
687 | // $input-error-message-padding: rem-calc(6 9 9);
688 | // $input-error-message-top: -1px;
689 | // $input-error-message-font-size: rem-calc(12);
690 | // $input-error-message-font-weight: $font-weight-normal;
691 | // $input-error-message-font-style: italic;
692 | // $input-error-message-font-color: $white;
693 | // $input-error-message-bg-color: $alert-color;
694 | // $input-error-message-font-color-alt: $oil;
695 |
696 | // We use this to style the glowing effect of inputs when focused
697 | // $glowing-effect-fade-time: .45s;
698 | // $glowing-effect-color: $input-focus-border-color;
699 |
700 | // We use this to style the transition when inputs are focused and when the glowing effect is disabled.
701 | // $input-transition-fade-time: 0.15s;
702 | // $input-transition-fade-timing-function: linear;
703 |
704 | // Select variables
705 | // $select-bg-color: $ghost;
706 | // $select-hover-bg-color: scale-color($select-bg-color, $lightness: -3%);
707 |
708 |
709 | // 12. Icon Bar
710 | // - - - - - - - - - - - - - - - - - - - - - - - - -
711 |
712 | // We use these to style the icon-bar and items
713 | // $icon-bar-bg: $oil;
714 | // $icon-bar-font-color: $white;
715 | // $icon-bar-font-color-hover: $icon-bar-font-color;
716 | // $icon-bar-font-size: 1rem;
717 | // $icon-bar-hover-color: $primary-color;
718 | // $icon-bar-icon-color: $white;
719 | // $icon-bar-icon-color-hover: $icon-bar-icon-color;
720 | // $icon-bar-icon-size: 1.875rem;
721 | // $icon-bar-image-width: 1.875rem;
722 | // $icon-bar-image-height: 1.875rem;
723 | // $icon-bar-active-color: $primary-color;
724 | // $icon-bar-item-padding: 1.25rem;
725 |
726 | // We use this to set default opacity and cursor for disabled icons.
727 | // $icon-bar-disabled-opacity: .7;
728 |
729 | // 13. Inline Lists
730 | // - - - - - - - - - - - - - - - - - - - - - - - - -
731 |
732 | // $include-html-inline-list-classes: $include-html-classes;
733 |
734 | // We use this to control the margins and padding of the inline list.
735 | // $inline-list-top-margin: 0;
736 | // $inline-list-opposite-margin: 0;
737 | // $inline-list-bottom-margin: rem-calc(17);
738 | // $inline-list-default-float-margin: rem-calc(-22);
739 | // $inline-list-default-float-list-margin: rem-calc(22);
740 |
741 | // $inline-list-padding: 0;
742 |
743 | // We use this to control the overflow of the inline list.
744 | // $inline-list-overflow: hidden;
745 |
746 | // We use this to control the list items
747 | // $inline-list-display: block;
748 |
749 | // We use this to control any elements within list items
750 | // $inline-list-children-display: block;
751 |
752 | // 14. Joyride
753 | // - - - - - - - - - - - - - - - - - - - - - - - - -
754 |
755 | // $include-html-joyride-classes: $include-html-classes;
756 |
757 | // Controlling default Joyride styles
758 | // $joyride-tip-bg: $oil;
759 | // $joyride-tip-default-width: 300px;
760 | // $joyride-tip-padding: rem-calc(18 20 24);
761 | // $joyride-tip-border: solid 1px $charcoal;
762 | // $joyride-tip-radius: 4px;
763 | // $joyride-tip-position-offset: 22px;
764 |
765 | // Here, we're setting the tip font styles
766 | // $joyride-tip-font-color: $white;
767 | // $joyride-tip-font-size: rem-calc(14);
768 | // $joyride-tip-header-weight: $font-weight-bold;
769 |
770 | // This changes the nub size
771 | // $joyride-tip-nub-size: 10px;
772 |
773 | // This adjusts the styles for the timer when its enabled
774 | // $joyride-tip-timer-width: 50px;
775 | // $joyride-tip-timer-height: 3px;
776 | // $joyride-tip-timer-color: $steel;
777 |
778 | // This changes up the styles for the close button
779 | // $joyride-tip-close-color: $monsoon;
780 | // $joyride-tip-close-size: 24px;
781 | // $joyride-tip-close-weight: $font-weight-normal;
782 |
783 | // When Joyride is filling the screen, we use this style for the bg
784 | // $joyride-screenfill: rgba(0,0,0,0.5);
785 |
786 | // 15. Keystrokes
787 | // - - - - - - - - - - - - - - - - - - - - - - - - -
788 |
789 | // $include-html-keystroke-classes: $include-html-classes;
790 |
791 | // We use these to control text styles.
792 | // $keystroke-font: "Consolas", "Menlo", "Courier", monospace;
793 | // $keystroke-font-size: inherit;
794 | // $keystroke-font-color: $jet;
795 | // $keystroke-font-color-alt: $white;
796 | // $keystroke-function-factor: -7%;
797 |
798 | // We use this to control keystroke padding.
799 | // $keystroke-padding: rem-calc(2 4 0);
800 |
801 | // We use these to control background and border styles.
802 | // $keystroke-bg: scale-color($white, $lightness: $keystroke-function-factor);
803 | // $keystroke-border-style: solid;
804 | // $keystroke-border-width: 1px;
805 | // $keystroke-border-color: scale-color($keystroke-bg, $lightness: $keystroke-function-factor);
806 | // $keystroke-radius: $global-radius;
807 |
808 | // 16. Labels
809 | // - - - - - - - - - - - - - - - - - - - - - - - - -
810 |
811 | // $include-html-label-classes: $include-html-classes;
812 |
813 | // We use these to style the labels
814 | // $label-padding: rem-calc(4 8 4);
815 | // $label-radius: $global-radius;
816 |
817 | // We use these to style the label text
818 | // $label-font-sizing: rem-calc(11);
819 | // $label-font-weight: $font-weight-normal;
820 | // $label-font-color: $oil;
821 | // $label-font-color-alt: $white;
822 | // $label-font-family: $body-font-family;
823 |
824 | // 17. Magellan
825 | // - - - - - - - - - - - - - - - - - - - - - - - - -
826 |
827 | // $include-html-magellan-classes: $include-html-classes;
828 |
829 | // $magellan-bg: $white;
830 | // $magellan-padding: 10px;
831 |
832 | // 18. Off-canvas
833 | // - - - - - - - - - - - - - - - - - - - - - - - - -
834 |
835 | // Off Canvas Tab Bar Variables
836 | // $include-html-off-canvas-classes: $include-html-classes;
837 |
838 | // $tabbar-bg: $oil;
839 | // $tabbar-height: rem-calc(45);
840 | // $tabbar-icon-width: $tabbar-height;
841 | // $tabbar-line-height: $tabbar-height;
842 | // $tabbar-color: $white;
843 | // $tabbar-middle-padding: 0 rem-calc(10);
844 |
845 | // Off Canvas Divider Styles
846 | // $tabbar-left-section-border: solid 1px scale-color($tabbar-bg, $lightness: -50%);
847 | // $tabbar-right-section-border: $tabbar-left-section-border;
848 |
849 |
850 | // Off Canvas Tab Bar Headers
851 | // $tabbar-header-color: $white;
852 | // $tabbar-header-weight: $font-weight-bold;
853 | // $tabbar-header-line-height: $tabbar-height;
854 | // $tabbar-header-margin: 0;
855 |
856 | // Off Canvas Menu Variables
857 | // $off-canvas-width: rem-calc(250);
858 | // $off-canvas-bg: $oil;
859 | // $off-canvas-bg-hover: scale-color($tabbar-bg, $lightness: -30%);
860 | // $off-canvas-bg-active: scale-color($tabbar-bg, $lightness: -30%);
861 |
862 | // Off Canvas Menu List Variables
863 | // $off-canvas-label-padding: .3rem rem-calc(15);
864 | // $off-canvas-label-color: $aluminum;
865 | // $off-canvas-label-text-transform: uppercase;
866 | // $off-canvas-label-font-size: rem-calc(12);
867 | // $off-canvas-label-font-weight: $font-weight-bold;
868 | // $off-canvas-label-bg: $tuatara;
869 | // $off-canvas-label-border-top: 1px solid scale-color($off-canvas-label-bg, $lightness: 14%);
870 | // $off-canvas-label-border-bottom: none;
871 | // $off-canvas-label-margin:0;
872 | // $off-canvas-link-padding: rem-calc(10, 15);
873 | // $off-canvas-link-color: rgba($white, .7);
874 | // $off-canvas-link-border-bottom: 1px solid scale-color($off-canvas-bg, $lightness: -25%);
875 | // $off-canvas-back-bg: #444;
876 | // $off-canvas-back-border-top: $off-canvas-label-border-top;
877 | // $off-canvas-back-border-bottom: $off-canvas-label-border-bottom;
878 | // $off-canvas-back-hover-bg: scale-color($off-canvas-back-bg, $lightness: -30%);
879 | // $off-canvas-back-hover-border-top: 1px solid scale-color($off-canvas-label-bg, $lightness: 14%);
880 | // $off-canvas-back-hover-border-bottom: none;
881 |
882 | // Off Canvas Menu Icon Variables
883 | // $tabbar-menu-icon-color: $white;
884 | // $tabbar-menu-icon-hover: scale-color($tabbar-menu-icon-color, $lightness: -30%);
885 |
886 | // $tabbar-menu-icon-text-indent: rem-calc(35);
887 | // $tabbar-menu-icon-width: $tabbar-icon-width;
888 | // $tabbar-menu-icon-height: $tabbar-height;
889 | // $tabbar-menu-icon-padding: 0;
890 |
891 | // $tabbar-hamburger-icon-width: rem-calc(16);
892 | // $tabbar-hamburger-icon-left: false;
893 | // $tabbar-hamburger-icon-top: false;
894 | // $tabbar-hamburger-icon-thickness: 1px;
895 | // $tabbar-hamburger-icon-gap: 6px;
896 |
897 | // Off Canvas Back-Link Overlay
898 | // $off-canvas-overlay-transition: background 300ms ease;
899 | // $off-canvas-overlay-cursor: pointer;
900 | // $off-canvas-overlay-box-shadow: -4px 0 4px rgba($black, .5), 4px 0 4px rgba($black, .5);
901 | // $off-canvas-overlay-background: rgba($white, .2);
902 | // $off-canvas-overlay-background-hover: rgba($white, .05);
903 |
904 | // Transition Variables
905 | // $menu-slide: "transform 500ms ease";
906 |
907 | // 19. Orbit
908 | // - - - - - - - - - - - - - - - - - - - - - - - - -
909 |
910 | // $include-html-orbit-classes: $include-html-classes;
911 |
912 | // We use these to control the caption styles
913 | // $orbit-container-bg: none;
914 | // $orbit-caption-bg: rgba(51,51,51, .8);
915 | // $orbit-caption-font-color: $white;
916 | // $orbit-caption-font-size: rem-calc(14);
917 | // $orbit-caption-position: "bottom"; // Supported values: "bottom", "under"
918 | // $orbit-caption-padding: rem-calc(10 14);
919 | // $orbit-caption-height: auto;
920 |
921 | // We use these to control the left/right nav styles
922 | // $orbit-nav-bg: transparent;
923 | // $orbit-nav-bg-hover: rgba(0,0,0,0.3);
924 | // $orbit-nav-arrow-color: $white;
925 | // $orbit-nav-arrow-color-hover: $white;
926 |
927 | // We use these to control the timer styles
928 | // $orbit-timer-bg: rgba(255,255,255,0.3);
929 | // $orbit-timer-show-progress-bar: true;
930 |
931 | // We use these to control the bullet nav styles
932 | // $orbit-bullet-nav-color: $iron;
933 | // $orbit-bullet-nav-color-active: $aluminum;
934 | // $orbit-bullet-radius: rem-calc(9);
935 |
936 | // We use these to controls the style of slide numbers
937 | // $orbit-slide-number-bg: rgba(0,0,0,0);
938 | // $orbit-slide-number-font-color: $white;
939 | // $orbit-slide-number-padding: rem-calc(5);
940 |
941 | // Graceful Loading Wrapper and preloader
942 | // $wrapper-class: "slideshow-wrapper";
943 | // $preloader-class: "preloader";
944 |
945 | // Hide controls on small
946 | // $orbit-nav-hide-for-small: true;
947 | // $orbit-bullet-hide-for-small: true;
948 | // $orbit-timer-hide-for-small: true;
949 |
950 | // 20. Pagination
951 | // - - - - - - - - - - - - - - - - - - - - - - - - -
952 |
953 | // $include-pagination-classes: $include-html-classes;
954 |
955 | // We use these to control the pagination container
956 | // $pagination-height: rem-calc(24);
957 | // $pagination-margin: rem-calc(-5);
958 |
959 | // We use these to set the list-item properties
960 | // $pagination-li-float: $default-float;
961 | // $pagination-li-height: rem-calc(24);
962 | // $pagination-li-font-color: $jet;
963 | // $pagination-li-font-size: rem-calc(14);
964 | // $pagination-li-margin: rem-calc(5);
965 |
966 | // We use these for the pagination anchor links
967 | // $pagination-link-pad: rem-calc(1 10 1);
968 | // $pagination-link-font-color: $aluminum;
969 | // $pagination-link-active-bg: scale-color($white, $lightness: -10%);
970 |
971 | // We use these for disabled anchor links
972 | // $pagination-link-unavailable-cursor: default;
973 | // $pagination-link-unavailable-font-color: $aluminum;
974 | // $pagination-link-unavailable-bg-active: transparent;
975 |
976 | // We use these for currently selected anchor links
977 | // $pagination-link-current-background: $primary-color;
978 | // $pagination-link-current-font-color: $white;
979 | // $pagination-link-current-font-weight: $font-weight-bold;
980 | // $pagination-link-current-cursor: default;
981 | // $pagination-link-current-active-bg: $primary-color;
982 |
983 | // 21. Panels
984 | // - - - - - - - - - - - - - - - - - - - - - - - - -
985 |
986 | // $include-html-panel-classes: $include-html-classes;
987 |
988 | // We use these to control the background and border styles
989 | // $panel-bg: scale-color($white, $lightness: -5%);
990 | // $panel-border-style: solid;
991 | // $panel-border-size: 1px;
992 | // $callout-panel-bg: scale-color($primary-color, $lightness: 94%);
993 |
994 | // We use this % to control how much we darken things on hover
995 | // $panel-border-color: scale-color($panel-bg, $lightness: -11%);
996 |
997 | // We use these to set default inner padding and bottom margin
998 | // $panel-margin-bottom: rem-calc(20);
999 | // $panel-padding: rem-calc(20);
1000 |
1001 | // We use these to set default font colors
1002 | // $panel-font-color: $oil;
1003 | // $panel-font-color-alt: $white;
1004 |
1005 | // $panel-header-adjust: true;
1006 | // $callout-panel-link-color: $primary-color;
1007 | // $callout-panel-link-color-hover: scale-color($callout-panel-link-color, $lightness: -14%);
1008 |
1009 | // 22. Pricing Tables
1010 | // - - - - - - - - - - - - - - - - - - - - - - - - -
1011 |
1012 | // $include-html-pricing-classes: $include-html-classes;
1013 |
1014 | // We use this to control the border color
1015 | // $price-table-border: solid 1px $gainsboro;
1016 |
1017 | // We use this to control the bottom margin of the pricing table
1018 | // $price-table-margin-bottom: rem-calc(20);
1019 |
1020 | // We use these to control the title styles
1021 | // $price-title-bg: $oil;
1022 | // $price-title-padding: rem-calc(15 20);
1023 | // $price-title-align: center;
1024 | // $price-title-color: $smoke;
1025 | // $price-title-weight: $font-weight-normal;
1026 | // $price-title-size: rem-calc(16);
1027 | // $price-title-font-family: $body-font-family;
1028 |
1029 | // We use these to control the price styles
1030 | // $price-money-bg: $vapor;
1031 | // $price-money-padding: rem-calc(15 20);
1032 | // $price-money-align: center;
1033 | // $price-money-color: $oil;
1034 | // $price-money-weight: $font-weight-normal;
1035 | // $price-money-size: rem-calc(32);
1036 | // $price-money-font-family: $body-font-family;
1037 |
1038 |
1039 | // We use these to control the description styles
1040 | // $price-bg: $white;
1041 | // $price-desc-color: $monsoon;
1042 | // $price-desc-padding: rem-calc(15);
1043 | // $price-desc-align: center;
1044 | // $price-desc-font-size: rem-calc(12);
1045 | // $price-desc-weight: $font-weight-normal;
1046 | // $price-desc-line-height: 1.4;
1047 | // $price-desc-bottom-border: dotted 1px $gainsboro;
1048 |
1049 | // We use these to control the list item styles
1050 | // $price-item-color: $oil;
1051 | // $price-item-padding: rem-calc(15);
1052 | // $price-item-align: center;
1053 | // $price-item-font-size: rem-calc(14);
1054 | // $price-item-weight: $font-weight-normal;
1055 | // $price-item-bottom-border: dotted 1px $gainsboro;
1056 |
1057 | // We use these to control the CTA area styles
1058 | // $price-cta-bg: $white;
1059 | // $price-cta-align: center;
1060 | // $price-cta-padding: rem-calc(20 20 0);
1061 |
1062 | // 23. Progress Bar
1063 | // - - - - - - - - - - - - - - - - - - - - - - - - -
1064 |
1065 | // $include-html-media-classes: $include-html-classes;
1066 |
1067 | // We use this to set the progress bar height
1068 | // $progress-bar-height: rem-calc(25);
1069 | // $progress-bar-color: $vapor;
1070 |
1071 | // We use these to control the border styles
1072 | // $progress-bar-border-color: scale-color($white, $lightness: 20%);
1073 | // $progress-bar-border-size: 1px;
1074 | // $progress-bar-border-style: solid;
1075 | // $progress-bar-border-radius: $global-radius;
1076 |
1077 | // We use these to control the margin & padding
1078 | // $progress-bar-margin-bottom: rem-calc(10);
1079 |
1080 | // We use these to set the meter colors
1081 | // $progress-meter-color: $primary-color;
1082 | // $progress-meter-secondary-color: $secondary-color;
1083 | // $progress-meter-success-color: $success-color;
1084 | // $progress-meter-alert-color: $alert-color;
1085 |
1086 | // 24. Range Slider
1087 | // - - - - - - - - - - - - - - - - - - - - - - - - -
1088 |
1089 | // $include-html-range-slider-classes: $include-html-classes;
1090 |
1091 | // These variables define the slider bar styles
1092 | // $range-slider-bar-width: 100%;
1093 | // $range-slider-bar-height: rem-calc(16);
1094 |
1095 | // $range-slider-bar-border-width: 1px;
1096 | // $range-slider-bar-border-style: solid;
1097 | // $range-slider-bar-border-color: $gainsboro;
1098 | // $range-slider-radius: $global-radius;
1099 | // $range-slider-round: $global-rounded;
1100 | // $range-slider-bar-bg-color: $ghost;
1101 | // $range-slider-active-segment-bg-color: scale-color($secondary-color, $lightness: -1%);
1102 |
1103 | // Vertical bar styles
1104 | // $range-slider-vertical-bar-width: rem-calc(16);
1105 | // $range-slider-vertical-bar-height: rem-calc(200);
1106 |
1107 | // These variabels define the slider handle styles
1108 | // $range-slider-handle-width: rem-calc(32);
1109 | // $range-slider-handle-height: rem-calc(22);
1110 | // $range-slider-handle-position-top: rem-calc(-5);
1111 | // $range-slider-handle-bg-color: $primary-color;
1112 | // $range-slider-handle-border-width: 1px;
1113 | // $range-slider-handle-border-style: solid;
1114 | // $range-slider-handle-border-color: none;
1115 | // $range-slider-handle-radius: $global-radius;
1116 | // $range-slider-handle-round: $global-rounded;
1117 | // $range-slider-handle-bg-hover-color: scale-color($primary-color, $lightness: -12%);
1118 | // $range-slider-handle-cursor: pointer;
1119 |
1120 | // $range-slider-disabled-opacity: .7;
1121 | // $range-slider-disabled-cursor: $cursor-disabled-value;
1122 |
1123 | // 25. Reveal
1124 | // - - - - - - - - - - - - - - - - - - - - - - - - -
1125 |
1126 | // $include-html-reveal-classes: $include-html-classes;
1127 |
1128 | // We use these to control the style of the reveal overlay.
1129 | // $reveal-overlay-bg: rgba($black, .45);
1130 | // $reveal-overlay-bg-old: $black;
1131 |
1132 | // We use these to control the style of the modal itself.
1133 | // $reveal-modal-bg: $white;
1134 | // $reveal-position-top: rem-calc(100);
1135 | // $reveal-default-width: 80%;
1136 | // $reveal-max-width: $row-width;
1137 | // $reveal-modal-padding: rem-calc(20);
1138 | // $reveal-box-shadow: 0 0 10px rgba($black,.4);
1139 |
1140 | // We use these to style the reveal close button
1141 | // $reveal-close-font-size: rem-calc(40);
1142 | // $reveal-close-top: rem-calc(10);
1143 | // $reveal-close-side: rem-calc(22);
1144 | // $reveal-close-color: $base;
1145 | // $reveal-close-weight: $font-weight-bold;
1146 |
1147 | // We use this to set the default radius used throughout the core.
1148 | // $reveal-radius: $global-radius;
1149 | // $reveal-round: $global-rounded;
1150 |
1151 | // We use these to control the modal border
1152 | // $reveal-border-style: solid;
1153 | // $reveal-border-width: 1px;
1154 | // $reveal-border-color: $steel;
1155 |
1156 | // $reveal-modal-class: "reveal-modal";
1157 | // $close-reveal-modal-class: "close-reveal-modal";
1158 |
1159 | // 26. Side Nav
1160 | // - - - - - - - - - - - - - - - - - - - - - - - - -
1161 |
1162 | // $include-html-nav-classes: $include-html-classes;
1163 |
1164 | // We use this to control padding.
1165 | // $side-nav-padding: rem-calc(14 0);
1166 |
1167 | // We use these to control list styles.
1168 | // $side-nav-list-type: none;
1169 | // $side-nav-list-position: outside;
1170 | // $side-nav-list-margin: rem-calc(0 0 7 0);
1171 |
1172 | // We use these to control link styles.
1173 | // $side-nav-link-color: $primary-color;
1174 | // $side-nav-link-color-active: scale-color($side-nav-link-color, $lightness: 30%);
1175 | // $side-nav-link-color-hover: scale-color($side-nav-link-color, $lightness: 30%);
1176 | // $side-nav-link-bg-hover: hsla(0, 0, 0, .025);
1177 | // $side-nav-link-margin: 0;
1178 | // $side-nav-link-padding: rem-calc(7 14);
1179 | // $side-nav-font-size: rem-calc(14);
1180 | // $side-nav-font-weight: $font-weight-normal;
1181 | // $side-nav-font-weight-active: $side-nav-font-weight;
1182 | // $side-nav-font-family: $body-font-family;
1183 | // $side-nav-font-family-active: $side-nav-font-family;
1184 |
1185 | // We use these to control heading styles.
1186 | // $side-nav-heading-color: $side-nav-link-color;
1187 | // $side-nav-heading-font-size: $side-nav-font-size;
1188 | // $side-nav-heading-font-weight: bold;
1189 | // $side-nav-heading-text-transform: uppercase;
1190 |
1191 | // We use these to control border styles
1192 | // $side-nav-divider-size: 1px;
1193 | // $side-nav-divider-style: solid;
1194 | // $side-nav-divider-color: scale-color($white, $lightness: 10%);
1195 |
1196 | // 27. Split Buttons
1197 | // - - - - - - - - - - - - - - - - - - - - - - - - -
1198 |
1199 | // $include-html-button-classes: $include-html-classes;
1200 |
1201 | // We use these to control different shared styles for Split Buttons
1202 | // $split-button-function-factor: 10%;
1203 | // $split-button-pip-color: $white;
1204 | // $split-button-span-border-color: rgba(255,255,255,0.5);
1205 | // $split-button-pip-color-alt: $oil;
1206 | // $split-button-active-bg-tint: rgba(0,0,0,0.1);
1207 |
1208 | // We use these to control tiny split buttons
1209 | // $split-button-padding-tny: $button-pip-tny * 10;
1210 | // $split-button-span-width-tny: $button-pip-tny * 6;
1211 | // $split-button-pip-size-tny: $button-pip-tny;
1212 | // $split-button-pip-top-tny: $button-pip-tny * 2;
1213 | // $split-button-pip-default-float-tny: rem-calc(-6);
1214 |
1215 | // We use these to control small split buttons
1216 | // $split-button-padding-sml: $button-pip-sml * 10;
1217 | // $split-button-span-width-sml: $button-pip-sml * 6;
1218 | // $split-button-pip-size-sml: $button-pip-sml;
1219 | // $split-button-pip-top-sml: $button-pip-sml * 1.5;
1220 | // $split-button-pip-default-float-sml: rem-calc(-6);
1221 |
1222 | // We use these to control medium split buttons
1223 | // $split-button-padding-med: $button-pip-med * 9;
1224 | // $split-button-span-width-med: $button-pip-med * 5.5;
1225 | // $split-button-pip-size-med: $button-pip-med - rem-calc(3);
1226 | // $split-button-pip-top-med: $button-pip-med * 1.5;
1227 | // $split-button-pip-default-float-med: rem-calc(-6);
1228 |
1229 | // We use these to control large split buttons
1230 | // $split-button-padding-lrg: $button-pip-lrg * 8;
1231 | // $split-button-span-width-lrg: $button-pip-lrg * 5;
1232 | // $split-button-pip-size-lrg: $button-pip-lrg - rem-calc(6);
1233 | // $split-button-pip-top-lrg: $button-pip-lrg + rem-calc(5);
1234 | // $split-button-pip-default-float-lrg: rem-calc(-6);
1235 |
1236 | // 28. Sub Nav
1237 | // - - - - - - - - - - - - - - - - - - - - - - - - -
1238 |
1239 | // $include-html-nav-classes: $include-html-classes;
1240 |
1241 | // We use these to control margin and padding
1242 | // $sub-nav-list-margin: rem-calc(-4 0 18);
1243 | // $sub-nav-list-padding-top: rem-calc(4);
1244 |
1245 | // We use this to control the definition
1246 | // $sub-nav-font-family: $body-font-family;
1247 | // $sub-nav-font-size: rem-calc(14);
1248 | // $sub-nav-font-color: $aluminum;
1249 | // $sub-nav-font-weight: $font-weight-normal;
1250 | // $sub-nav-text-decoration: none;
1251 | // $sub-nav-padding: rem-calc(3 16);
1252 | // $sub-nav-border-radius: 3px;
1253 | // $sub-nav-font-color-hover: scale-color($sub-nav-font-color, $lightness: -25%);
1254 |
1255 |
1256 | // We use these to control the active item styles
1257 |
1258 | // $sub-nav-active-font-weight: $font-weight-normal;
1259 | // $sub-nav-active-bg: $primary-color;
1260 | // $sub-nav-active-bg-hover: scale-color($sub-nav-active-bg, $lightness: -14%);
1261 | // $sub-nav-active-color: $white;
1262 | // $sub-nav-active-padding: $sub-nav-padding;
1263 | // $sub-nav-active-cursor: default;
1264 |
1265 | // $sub-nav-item-divider: "";
1266 | // $sub-nav-item-divider-margin: rem-calc(12);
1267 |
1268 | // 29. Switch
1269 | // - - - - - - - - - - - - - - - - - - - - - - - - -
1270 |
1271 | // $include-html-form-classes: $include-html-classes;
1272 |
1273 | // Controlling background color for the switch container
1274 | // $switch-bg: $gainsboro;
1275 |
1276 | // We use these to control the switch heights for our default classes
1277 | // $switch-height-tny: 1.5rem;
1278 | // $switch-height-sml: 1.75rem;
1279 | // $switch-height-med: 2rem;
1280 | // $switch-height-lrg: 2.5rem;
1281 | // $switch-bottom-margin: 1.5rem;
1282 |
1283 | // We use these to style the switch-paddle
1284 | // $switch-paddle-bg: $white;
1285 | // $switch-paddle-transition-speed: .15s;
1286 | // $switch-paddle-transition-ease: ease-out;
1287 | // $switch-active-color: $primary-color;
1288 |
1289 | // 30. Tables
1290 | // - - - - - - - - - - - - - - - - - - - - - - - - -
1291 |
1292 | // $include-html-table-classes: $include-html-classes;
1293 |
1294 | // These control the background color for the table and even rows
1295 | // $table-bg: $white;
1296 | // $table-even-row-bg: $snow;
1297 |
1298 | // These control the table cell border style
1299 | // $table-border-style: solid;
1300 | // $table-border-size: 1px;
1301 | // $table-border-color: $gainsboro;
1302 |
1303 | // These control the table head styles
1304 | // $table-head-bg: $white-smoke;
1305 | // $table-head-font-size: rem-calc(14);
1306 | // $table-head-font-color: $jet;
1307 | // $table-head-font-weight: $font-weight-bold;
1308 | // $table-head-padding: rem-calc(8 10 10);
1309 |
1310 | // These control the table foot styles
1311 | // $table-foot-bg: $table-head-bg;
1312 | // $table-foot-font-size: $table-head-font-size;
1313 | // $table-foot-font-color: $table-head-font-color;
1314 | // $table-foot-font-weight: $table-head-font-weight;
1315 | // $table-foot-padding: $table-head-padding;
1316 |
1317 | // These control the caption
1318 | // table-caption-bg: transparent;
1319 | // $table-caption-font-color: $table-head-font-color;
1320 | // $table-caption-font-size: rem-calc(16);
1321 | // $table-caption-font-weight: bold;
1322 |
1323 | // These control the row padding and font styles
1324 | // $table-row-padding: rem-calc(9 10);
1325 | // $table-row-font-size: rem-calc(14);
1326 | // $table-row-font-color: $jet;
1327 | // $table-line-height: rem-calc(18);
1328 |
1329 | // These are for controlling the layout, display and margin of tables
1330 | // $table-layout: auto;
1331 | // $table-display: table-cell;
1332 | // $table-margin-bottom: rem-calc(20);
1333 |
1334 |
1335 | // 31. Tabs
1336 | // - - - - - - - - - - - - - - - - - - - - - - - - -
1337 |
1338 | // $include-html-tabs-classes: $include-html-classes;
1339 |
1340 | // $tabs-navigation-padding: rem-calc(16);
1341 | // $tabs-navigation-bg-color: $silver;
1342 | // $tabs-navigation-active-bg-color: $white;
1343 | // $tabs-navigation-hover-bg-color: scale-color($tabs-navigation-bg-color, $lightness: -6%);
1344 | // $tabs-navigation-font-color: $jet;
1345 | // $tabs-navigation-active-font-color: $tabs-navigation-font-color;
1346 | // $tabs-navigation-font-size: rem-calc(16);
1347 | // $tabs-navigation-font-family: $body-font-family;
1348 |
1349 | // $tabs-content-margin-bottom: rem-calc(24);
1350 | // $tabs-content-padding: ($column-gutter/2);
1351 |
1352 | // $tabs-vertical-navigation-margin-bottom: 1.25rem;
1353 |
1354 | // 32. Thumbnails
1355 | // - - - - - - - - - - - - - - - - - - - - - - - - -
1356 |
1357 | // $include-html-media-classes: $include-html-classes;
1358 |
1359 | // We use these to control border styles
1360 | // $thumb-border-style: solid;
1361 | // $thumb-border-width: 4px;
1362 | // $thumb-border-color: $white;
1363 | // $thumb-box-shadow: 0 0 0 1px rgba($black,.2);
1364 | // $thumb-box-shadow-hover: 0 0 6px 1px rgba($primary-color,0.5);
1365 |
1366 | // Radius and transition speed for thumbs
1367 | // $thumb-radius: $global-radius;
1368 | // $thumb-transition-speed: 200ms;
1369 |
1370 | // 33. Tooltips
1371 | // - - - - - - - - - - - - - - - - - - - - - - - - -
1372 |
1373 | // $include-html-tooltip-classes: $include-html-classes;
1374 |
1375 | // $has-tip-border-bottom: dotted 1px $iron;
1376 | // $has-tip-font-weight: $font-weight-bold;
1377 | // $has-tip-font-color: $oil;
1378 | // $has-tip-border-bottom-hover: dotted 1px scale-color($primary-color, $lightness: -55%);
1379 | // $has-tip-font-color-hover: $primary-color;
1380 | // $has-tip-cursor-type: help;
1381 |
1382 | // $tooltip-padding: rem-calc(12);
1383 | // $tooltip-bg: $oil;
1384 | // $tooltip-font-size: rem-calc(14);
1385 | // $tooltip-font-weight: $font-weight-normal;
1386 | // $tooltip-font-color: $white;
1387 | // $tooltip-line-height: 1.3;
1388 | // $tooltip-close-font-size: rem-calc(10);
1389 | // $tooltip-close-font-weight: $font-weight-normal;
1390 | // $tooltip-close-font-color: $monsoon;
1391 | // $tooltip-font-size-sml: rem-calc(14);
1392 | // $tooltip-radius: $global-radius;
1393 | // $tooltip-rounded: $global-rounded;
1394 | // $tooltip-pip-size: 5px;
1395 | // $tooltip-max-width: 300px;
1396 |
1397 | // 34. Top Bar
1398 | // - - - - - - - - - - - - - - - - - - - - - - - - -
1399 |
1400 | // $include-html-top-bar-classes: $include-html-classes;
1401 |
1402 | // Background color for the top bar
1403 | // $topbar-bg-color: $oil;
1404 | // $topbar-bg: $topbar-bg-color;
1405 |
1406 | // Height and margin
1407 | // $topbar-height: rem-calc(45);
1408 | // $topbar-margin-bottom: 0;
1409 |
1410 | // Controlling the styles for the title in the top bar
1411 | // $topbar-title-weight: $font-weight-normal;
1412 | // $topbar-title-font-size: rem-calc(17);
1413 |
1414 | // Set the link colors and styles for top-level nav
1415 | // $topbar-link-color: $white;
1416 | // $topbar-link-color-hover: $white;
1417 | // $topbar-link-color-active: $white;
1418 | // $topbar-link-color-active-hover: $white;
1419 | // $topbar-link-weight: $font-weight-normal;
1420 | // $topbar-link-font-size: rem-calc(13);
1421 | // $topbar-link-hover-lightness: -10%; // Darken by 10%
1422 | // $topbar-link-bg: $topbar-bg;
1423 | // $topbar-link-bg-hover: $jet;
1424 | // $topbar-link-bg-color-hover: $charcoal;
1425 | // $topbar-link-bg-active: $primary-color;
1426 | // $topbar-link-bg-active-hover: scale-color($primary-color, $lightness: -14%);
1427 | // $topbar-link-font-family: $body-font-family;
1428 | // $topbar-link-text-transform: none;
1429 | // $topbar-link-padding: ($topbar-height / 3);
1430 | // $topbar-back-link-size: rem-calc(18);
1431 | // $topbar-link-dropdown-padding: rem-calc(20);
1432 | // $topbar-button-font-size: .75rem;
1433 | // $topbar-button-top: 7px;
1434 |
1435 | // Style the top bar dropdown elements
1436 | // $topbar-dropdown-bg: $oil;
1437 | // $topbar-dropdown-link-color: $white;
1438 | // $topbar-dropdown-link-color-hover: $topbar-link-color-hover;
1439 | // $topbar-dropdown-link-bg: $oil;
1440 | // $topbar-dropdown-link-bg-hover: $jet;
1441 | // $topbar-dropdown-link-weight: $font-weight-normal;
1442 | // $topbar-dropdown-toggle-size: 5px;
1443 | // $topbar-dropdown-toggle-color: $white;
1444 | // $topbar-dropdown-toggle-alpha: .4;
1445 |
1446 | // $topbar-dropdown-label-color: $monsoon;
1447 | // $topbar-dropdown-label-text-transform: uppercase;
1448 | // $topbar-dropdown-label-font-weight: $font-weight-bold;
1449 | // $topbar-dropdown-label-font-size: rem-calc(10);
1450 | // $topbar-dropdown-label-bg: $oil;
1451 |
1452 | // Top menu icon styles
1453 | // $topbar-menu-link-transform: uppercase;
1454 | // $topbar-menu-link-font-size: rem-calc(13);
1455 | // $topbar-menu-link-weight: $font-weight-bold;
1456 | // $topbar-menu-link-color: $white;
1457 | // $topbar-menu-icon-color: $white;
1458 | // $topbar-menu-link-color-toggled: $jumbo;
1459 | // $topbar-menu-icon-color-toggled: $jumbo;
1460 | // $topbar-menu-icon-position: $opposite-direction; // Change to $default-float for a left menu icon
1461 |
1462 | // Transitions and breakpoint styles
1463 | // $topbar-transition-speed: 300ms;
1464 | // Using rem-calc for the below breakpoint causes issues with top bar
1465 | // $topbar-breakpoint: #{lower-bound($medium-range)}; // Change to 9999px for always mobile layout
1466 | // $topbar-media-query: "#{$screen} and (min-width:#{lower-bound($topbar-breakpoint)})";
1467 |
1468 | // Top-bar input styles
1469 | // $topbar-input-height: rem-calc(28);
1470 |
1471 | // Divider Styles
1472 | // $topbar-divider-border-bottom: solid 1px scale-color($topbar-bg-color, $lightness: 13%);
1473 | // $topbar-divider-border-top: solid 1px scale-color($topbar-bg-color, $lightness: -50%);
1474 |
1475 | // Sticky Class
1476 | // $topbar-sticky-class: ".sticky";
1477 | // $topbar-arrows: true; //Set false to remove the triangle icon from the menu item
1478 | // $topbar-dropdown-arrows: true; //Set false to remove the \00bb >> text from dropdown subnavigation li//
1479 |
1480 | // 36. Visibility Classes
1481 | // - - - - - - - - - - - - - - - - - - - - - - - - -
1482 |
1483 | // $include-html-visibility-classes: $include-html-classes;
1484 | // $include-accessibility-classes: true;
1485 | // $include-table-visibility-classes: true;
1486 | // $include-legacy-visibility-classes: true;
1487 |
--------------------------------------------------------------------------------