├── .gitignore ├── README.md ├── doc ├── controller-doc.md ├── directory.md ├── get-started.md ├── module-doc.md ├── more-doc.md ├── others.md ├── route.md └── seed.md ├── gulpfile.js ├── package.json └── seed ├── css ├── config.css └── vtui.css ├── demo.html ├── fonts ├── themify.eot ├── themify.svg ├── themify.ttf └── themify.woff ├── img ├── angular-amd-logo.png └── article-theme.jpg ├── index.html ├── js ├── app.js ├── controller │ ├── controller.js │ ├── home.js │ └── module.js ├── directive │ ├── cat.js │ └── pagination.js ├── lib │ ├── angular-route.js │ ├── angular.min.js │ ├── angularAMD.min.js │ ├── jquery-1.7.2.min.js │ ├── jquery-ui.min.js │ ├── less.js │ ├── ngload.min.js │ ├── ngprogress.min.js │ ├── require.js │ └── validator.min.js ├── main.js ├── service │ └── keyshortcut.js └── templates │ ├── cat.tpl.html │ └── pagination.tpl.html ├── less ├── config.less ├── modules │ ├── m-button.less │ ├── m-icon.less │ ├── m-layout.less │ ├── m-pagination.less │ ├── m-table.less │ ├── m-type.less │ └── reset.less ├── plugins │ ├── angular.progress.less │ └── hljs.theme.less └── vtui.less ├── package.json └── views ├── controller-doc.html ├── controller.html ├── directory.html ├── get-started.html ├── guide1.html ├── home.html ├── module-doc.html ├── module.html ├── more-doc.html ├── others.html ├── route.html └── seed.html /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | 25 | # Android/IJ 26 | # 27 | .idea 28 | .gradle 29 | local.properties 30 | 31 | 32 | node_modules/ 33 | 34 | npm-debug.log 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Angular AMD 快速入门 2 | 3 | [angularAMD](https://github.com/marcoslin/angularAMD)是作者@ [marcoslin](https://github.com/marcoslin)使用 RequireJS + AngularJS开发的前端`mvvm`框架,因此你可以使用它快速创建一款Web App.他特别适合快速开发`SPA`应用。 4 | 5 | [中文文档](http://vanthink-ued.github.io/AngularAMD-Tutorial/index.html#/get-started) 6 | 7 | [英文文档](http://marcoslin.github.io/angularAMD/#/home) 8 | 9 | 10 | ### 快速开始 11 | 12 | ``` bash 13 | git clone https://github.com/Vanthink-UED/AngularAMD-Tutorial 14 | 15 | npm install 16 | 17 | gulp 18 | ``` 19 | 20 | 访问 http://localhost:8360/#/home 21 | 22 | # MIT License 23 | The MIT License (MIT) 24 | 25 | Copyright (c) [2016] [Angular AMD] 26 | 27 | Permission is hereby granted, free of charge, to any person obtaining a copy 28 | of this software and associated documentation files (the "Software"), to deal 29 | in the Software without restriction, including without limitation the rights 30 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 31 | copies of the Software, and to permit persons to whom the Software is 32 | furnished to do so, subject to the following conditions: 33 | 34 | The above copyright notice and this permission notice shall be included in all 35 | copies or substantial portions of the Software. 36 | 37 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 38 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 39 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 40 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 41 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 42 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 43 | SOFTWARE 44 | -------------------------------------------------------------------------------- /doc/controller-doc.md: -------------------------------------------------------------------------------- 1 | ## controller 的使用 2 | 3 | 在AngularAMD定义controller非常简单,我们推荐两种写法: 4 | 5 | ``` javascript 6 | // home.js 7 | define(['app'], function (app) { 8 | app.controller('ControllerCtrl', function ($scope,$routeParams,$http,$location) { 9 | // 数据集 10 | $scope.list = false; 11 | 12 | // 初始化函数 需要在 view 里面和 ng-init 绑定 13 | $scope.init = function() { 14 | 15 | } 16 | 17 | // 刷新数据 18 | $scope.refresh = function() { 19 | 20 | } 21 | 22 | // 绑定点击事件 和 指定 view 中 ng-click 绑定 23 | $scope.clickEvent = function(e) { 24 | 25 | } 26 | 27 | }); 28 | }); 29 | 30 | ``` 31 | 或者我们也可以这样写 32 | ``` javascript 33 | // controller.js 34 | define(['app'], function (app) { 35 | app.controller('ControllerCtrl', function ($scope,$routeParams,$http,$location) { 36 | var modules = { 37 | 38 | init: function() { 39 | this.list = false; 40 | }, 41 | 42 | refresh: function() { 43 | 44 | }, 45 | 46 | events:{ 47 | click: function(e) { 48 | 49 | } 50 | }, 51 | 52 | 53 | }; 54 | 55 | return angular.extend($scope, modules); 56 | 57 | }); 58 | }); 59 | ``` 60 | ```javascript 61 | 62 | define(['app'], function (app) { 63 | app.controller('ControllerCtrl', function ($scope,$routeParams,$http,$location) { 64 | $scope.list = false; 65 | $scope.init = function() { 66 | var blocks = document.querySelectorAll('pre code'); 67 | for(var i=0;i 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 |
nameagecontrol
{{item.name}}{{item.age}}View Detail
暂无数据
147 | 148 | 149 | 150 | ``` 151 | 152 | 153 | [下一章:种子使用](#seed) 154 | 155 | 156 | 157 | 158 | -------------------------------------------------------------------------------- /doc/more-doc.md: -------------------------------------------------------------------------------- 1 | ## 更多参考阅读 2 | 3 | 这里有更多资料,作者整理的用于理解项目的来源和实践 4 | 5 | [Dynamically Loading Controllers and Views with AngularJS and RequireJS by Dan Wahlin](http://weblogs.asp.net/dwahlin/archive/2013/05/22/dynamically-loading-controllers-and-views-with-angularjs-and-requirejs.aspx) 6 | 7 | [Dependency Injection using RequireJS & AngularJS by Thomas Burleson](http://solutionoptimist.com/2013/09/30/requirejs-angularjs-dependency-injection/) 8 | 9 | [http://stackoverflow.com/questions/19134023/lazy-loading-angularjs-modules-with-requirejs](http://stackoverflow.com/questions/19134023/lazy-loading-angularjs-modules-with-requirejs) 10 | 11 | [angular-require-lazy by Nikos Paraskevopoulos](https://github.com/nikospara/angular-require-lazy) -------------------------------------------------------------------------------- /doc/others.md: -------------------------------------------------------------------------------- 1 | ## 持续完善中 2 | 3 | 我们会持续完善该文档,把团队的最佳实践总结出来。 4 | 5 | 您也可以在 https://github.com/Vanthink-UED/AngularAMD-Tutorial/issues 提出您的看法和建议。 6 | 7 | 最后感谢作者 [@marcoslin](https://github.com/marcoslin)的授权和认可。 8 | 9 | 10 | -------------------------------------------------------------------------------- /doc/route.md: -------------------------------------------------------------------------------- 1 | ## angularAMD.route 路由配置 2 | 3 | 通过使用 `angularAMD.route` 我们可以动态配置所需要加载的 `controllers`; 4 | 5 | ```javascript 6 | app.config(function ($routeProvider) { 7 | $routeProvider.when( 8 | "/home", 9 | angularAMD.route({ 10 | templateUrl: 'views/home.html', 11 | controller: 'HomeController', 12 | controllerUrl: './js/controller/home' 13 | }) 14 | ); 15 | }); 16 | ``` 17 | 18 | #### 指定默认访问地址 19 | 20 | 通过配置`otherwise`,我们可以讲没有定义的路由地址默认请求到404或者首页上来。 21 | ``` javascript 22 | app.config(function ($routeProvider) { 23 | $routeProvider 24 | 25 | .when("/home", angularAMD.route({ 26 | templateUrl: 'views/home.html', 27 | controller: 'HomeCtrl', 28 | controllerUrl: './js/controller/home.js' 29 | })) 30 | 31 | ... 32 | 33 | .otherwise({ 34 | redirectTo: "/home" 35 | }); 36 | }); 37 | ``` 38 | 39 | #### 不设置 controllerUrl 40 | 41 | 当然如果你已经在 `main.js` 中定义了controller 的地址这样你可以不用设置controlerUrl 42 | ```javascript 43 | // main.js 44 | paths: { 'HomeController': 'scripts/controller' } 45 | ``` 46 | 47 | #### 不设置 controller 48 | 49 | 如果你忽略了在配置中设置`controller`选项,那么`angularAMD.route`则会讲函数从`controlerUrl`返回回来,那么这样 50 | 你可以避免抛出一个未定义的controller 名称的错误。 51 | ``` javascript 52 | define(['app'], function (app) { 53 | return ["$scope", function ($scope) { 54 | ... 55 | }]; 56 | }); 57 | ``` 58 | 59 | ### 扩展路由 60 | 61 | 当然我们可以自定义设置路由的返回,我们可以自定义扩展一个函数,动态解析url,自动匹配controller 和 controllerUrl. 62 | 63 | ``` javascript 64 | /** 路由分析 传入路由地址自动拆分寻找 view 和 controller 65 | ** @routeUrl 路由定义 66 | ** @data 是否需要数据 67 | ** 输入 '/test/home' => { view: '/test_home/view',controller:TestHomeCtrl,controllerUrl: /test/home.js } 68 | **/ 69 | 70 | var routeConfig = function (routeUrl, data) { 71 | var paramStr = ''; 72 | if (typeof (data) == 'object' && data != {}) { 73 | paramStr = '?'.serialize(data); 74 | }; 75 | var t = routeUrl.replace(/\//g, '-'); 76 | 77 | var routeArr = t.split('-'); 78 | routeArr = routeArr.splice(1); 79 | 80 | var viewUrl = '/' + routeArr.join('_') + '/view'; 81 | // JS_ROOT 为 js 根目录 82 | var jsUrl = JS_ROOT + '/' + routeArr[0] + '/' + routeArr.splice(1).join('-') + '.js'; 83 | var c = dashToCamel(t + '-' + 'ctrl'); 84 | return { 85 | templateUrl: viewUrl + '?' + paramStr, 86 | controller: c, 87 | controllerUrl: jsUrl 88 | } 89 | 90 | } 91 | 92 | ``` 93 | 94 | ### 监测路由 95 | 96 | 我们可以在`app.js` 去检测路由的请求状态 97 | 98 | ``` javascript 99 | app.run(function($rootScope) { 100 | 101 | var ngProgress = ngProgressFactory.createInstance(); 102 | 103 | $rootScope.$on('$routeChangeStart', function() { 104 | // 路由请求开始 105 | }); 106 | 107 | $rootScope.$on('$routeChangeSuccess', function() { 108 | // 路由请求完成 109 | }); 110 | 111 | $rootScope.$on('$routeChangeError', function() { 112 | // 路由请求出错 113 | }); 114 | 115 | }); 116 | 117 | ``` 118 | 更多参数设置: https://docs.angularjs.org/api/ngRoute/service/$route 119 | 120 | 121 | [下一章:控制器](#controller) 122 | 123 | -------------------------------------------------------------------------------- /doc/seed.md: -------------------------------------------------------------------------------- 1 | ## 种子使用 2 | 3 | AngularAMD官方提供了一个种子[案例](https://github.com/marcoslin/angularAMD-sample),你也可以直接使用 4 | [中文案例](https://github.com/Vanthink-UED/AngularAMD-Tutorial) 5 | 6 | [在线文档](http://marcoslin.github.io/angularAMD/#/home)便是是基于`AngularAMD-Seed`构建。 7 | 8 | 中文案例继承了对`less`和`js压缩`的支持,你可以自己修改`gulpfile.js`; 9 | 10 | ### 使用 11 | 12 | ``` bash 13 | git clone https://github.com/Vanthink-UED/AngularAMD-Tutorial 14 | 15 | npm install 16 | 17 | gulp 18 | 19 | ``` 20 | 21 | 访问 http://localhost:8360/#/home 22 | 23 | [下一章:更多阅读](#more-doc) -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var uglify = require('gulp-uglify'); 3 | var markdown = require('gulp-markdown'); 4 | 5 | var minifycss = require('gulp-minify-css'); 6 | var plumber = require('gulp-plumber'); 7 | var less = require('gulp-less'); 8 | var path = require('path'); 9 | var gutil = require('gulp-util'); 10 | var webserver = require('gulp-webserver'); 11 | 12 | gulp.task('less', function () { 13 | return gulp.src('./seed/less/*.less') 14 | .pipe(plumber(function(error) { 15 | gutil.log(gutil.colors.red(error.message)); 16 | gutil.beep(); 17 | this.emit('end'); 18 | })) 19 | .pipe(less()) 20 | .pipe(minifycss()) 21 | .pipe(gulp.dest('./seed/css')); 22 | }); 23 | 24 | 25 | gulp.task('md', function () { 26 | gulp.src('doc/*.md') 27 | .pipe(markdown()) 28 | .pipe(gulp.dest('./seed/views')); 29 | }); 30 | 31 | gulp.task('webserver', function() { 32 | gulp.src('./seed/') 33 | .pipe(webserver({ 34 | fallback: './index.html', 35 | livereload: true, 36 | port: 8360, 37 | directoryListing: false, 38 | open: true 39 | })); 40 | }); 41 | 42 | //gulp.task('minify', function () { 43 | // gulp.src('static/js/app.js') 44 | // .pipe(uglify()) 45 | // .pipe(gulp.dest('build/js')) 46 | //}); 47 | 48 | gulp.task('default', function(){ 49 | 50 | gulp.run('webserver'); 51 | 52 | gulp.watch('doc/*.md', function(){ 53 | gulp.run('md'); 54 | }); 55 | gulp.watch('./seed/less/**/*.less', function(){ 56 | gulp.run('less'); 57 | }); 58 | 59 | }); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular2", 3 | "version": "1.0.0", 4 | "scripts": { 5 | "tsc": "tsc", 6 | "tsc:w": "tsc -w", 7 | "lite": "lite-server", 8 | "start": "concurrent \"npm run tsc:w\" \"npm run lite\" " 9 | }, 10 | "license": "ISC", 11 | "dependencies": { 12 | "angular2": "2.0.0-beta.2", 13 | "systemjs": "0.19.6", 14 | "es6-promise": "^3.0.2", 15 | "es6-shim": "^0.33.3", 16 | "reflect-metadata": "0.1.2", 17 | "rxjs": "5.0.0-beta.0", 18 | "zone.js": "0.5.10" 19 | }, 20 | "devDependencies": { 21 | "concurrently": "^1.0.0", 22 | "gulp-plumber": "^1.1.0", 23 | "gulp-util": "^3.0.7", 24 | "gulp-webserver": "^0.9.1", 25 | "lite-server": "^1.3.4", 26 | "typescript": "^1.7.5" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /seed/css/config.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vanthink-UED/AngularAMD-Tutorial/ea200d1c74ecf0a8c223b0ccea70ed1d48d08b61/seed/css/config.css -------------------------------------------------------------------------------- /seed/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AngularAMD-案例演示 6 | 7 | 8 | 9 | 10 | 26 | 27 | 28 | 29 | 39 |
40 |

参考案例

41 | 45 |
46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /seed/fonts/themify.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vanthink-UED/AngularAMD-Tutorial/ea200d1c74ecf0a8c223b0ccea70ed1d48d08b61/seed/fonts/themify.eot -------------------------------------------------------------------------------- /seed/fonts/themify.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vanthink-UED/AngularAMD-Tutorial/ea200d1c74ecf0a8c223b0ccea70ed1d48d08b61/seed/fonts/themify.ttf -------------------------------------------------------------------------------- /seed/fonts/themify.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vanthink-UED/AngularAMD-Tutorial/ea200d1c74ecf0a8c223b0ccea70ed1d48d08b61/seed/fonts/themify.woff -------------------------------------------------------------------------------- /seed/img/angular-amd-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vanthink-UED/AngularAMD-Tutorial/ea200d1c74ecf0a8c223b0ccea70ed1d48d08b61/seed/img/angular-amd-logo.png -------------------------------------------------------------------------------- /seed/img/article-theme.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vanthink-UED/AngularAMD-Tutorial/ea200d1c74ecf0a8c223b0ccea70ed1d48d08b61/seed/img/article-theme.jpg -------------------------------------------------------------------------------- /seed/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AngularAMD-Seeds 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 25 | 26 | 27 |
28 |
29 | Support By Vanthink-UED 30 |
31 | 32 | 33 | -------------------------------------------------------------------------------- /seed/js/app.js: -------------------------------------------------------------------------------- 1 | // 入口文件 2 | define(['angularAMD', 'angular-route','vued.cat','ng-progress'], function (angularAMD) { 3 | 4 | var app = angular.module("webapp", ['ngRoute','Vued.cat','ngProgress']); 5 | app.config(function ($routeProvider) { 6 | $routeProvider 7 | 8 | .when("/home", angularAMD.route({ 9 | templateUrl: 'views/home.html', 10 | controller: 'HomeCtrl', 11 | controllerUrl: './js/controller/home.js' 12 | })) 13 | 14 | .when("/get-started", angularAMD.route({ 15 | templateUrl: 'views/get-started.html', 16 | controller: 'HomeCtrl', 17 | controllerUrl: './js/controller/home.js' 18 | })) 19 | .when("/directory", angularAMD.route({ 20 | templateUrl: 'views/directory.html', 21 | controller: 'HomeCtrl', 22 | controllerUrl: './js/controller/home.js' 23 | })) 24 | .when("/route", angularAMD.route({ 25 | templateUrl: 'views/route.html', 26 | controller: 'HomeCtrl', 27 | controllerUrl: './js/controller/home.js' 28 | })) 29 | .when("/controller", angularAMD.route({ 30 | templateUrl: 'views/controller.html', 31 | controller: 'ControllerCtrl', 32 | controllerUrl: './js/controller/controller.js' 33 | })) 34 | .when("/module", angularAMD.route({ 35 | templateUrl: 'views/module.html', 36 | controller: 'ModuleCtrl', 37 | controllerUrl: './js/controller/module.js' 38 | })) 39 | .when("/seed", angularAMD.route({ 40 | templateUrl: 'views/seed.html', 41 | controller: 'HomeCtrl', 42 | controllerUrl: './js/controller/home.js' 43 | })) 44 | .when("/more-doc", angularAMD.route({ 45 | templateUrl: 'views/more-doc.html', 46 | controller: 'HomeCtrl', 47 | controllerUrl: './js/controller/home.js' 48 | })) 49 | .when("/others", angularAMD.route({ 50 | templateUrl: 'views/others.html', 51 | controller: 'HomeCtrl', 52 | controllerUrl: './js/controller/home.js' 53 | })) 54 | 55 | 56 | .otherwise({ 57 | redirectTo: "/home" 58 | }); 59 | }); 60 | 61 | 62 | /** route watch **/ 63 | app.run(function($rootScope, ngProgressFactory,catset) { 64 | 65 | var ngProgress = ngProgressFactory.createInstance(); 66 | 67 | $rootScope.$on('$routeChangeStart', function() { 68 | ngProgress.start(); 69 | catset(); 70 | }); 71 | 72 | $rootScope.$on('$routeChangeSuccess', function() { 73 | // code highlight 74 | ngProgress.complete(); 75 | document.querySelector('body').className =""; 76 | var blocks = document.querySelectorAll('pre code'); 77 | for(var i=0;i"; 199 | strVar += "
  • "; 200 | strVar += " ‹<\/a>"; 201 | strVar += " <\/li>"; 202 | strVar += "
  • "; 203 | strVar += " {{ pageNumber }}<\/a>"; 204 | strVar += " <\/li>"; 205 | strVar += ""; 206 | strVar += "
  • "; 207 | strVar += " ›<\/a>"; 208 | strVar += " <\/li>"; 209 | strVar += "<\/ul>"; 210 | return { 211 | restrict: 'AE', 212 | template: strVar, 213 | scope: { 214 | maxSize: '=?', 215 | onPageChange: '&?', 216 | paginationId: '=?' 217 | }, 218 | link: dirPaginationControlsLinkFn 219 | }; 220 | 221 | function dirPaginationControlsLinkFn(scope, element, attrs) { 222 | // rawId is the un-interpolated value of the pagination-id attribute. This is only important when the corresponding dir-paginate directive has 223 | // not yet been linked (e.g. if it is inside an ng-if block), and in that case it prevents this controls directive from assuming that there is 224 | // no corresponding dir-paginate directive and wrongly throwing an exception. 225 | var rawId = attrs.paginationId || DEFAULT_ID; 226 | var paginationId = scope.paginationId || attrs.paginationId || DEFAULT_ID; 227 | 228 | if (!paginationService.isRegistered(paginationId) && !paginationService.isRegistered(rawId)) { 229 | var idMessage = (paginationId !== DEFAULT_ID) ? ' (id: ' + paginationId + ') ' : ' '; 230 | throw 'pagination directive: the pagination controls' + idMessage + 'cannot be used without the corresponding pagination directive.'; 231 | } 232 | 233 | if (!scope.maxSize) { scope.maxSize = 9; } 234 | scope.directionLinks = angular.isDefined(attrs.directionLinks) ? scope.$parent.$eval(attrs.directionLinks) : true; 235 | scope.boundaryLinks = angular.isDefined(attrs.boundaryLinks) ? scope.$parent.$eval(attrs.boundaryLinks) : false; 236 | 237 | var paginationRange = Math.max(scope.maxSize, 5); 238 | scope.pages = []; 239 | scope.pagination = { 240 | last: 1, 241 | current: 1 242 | }; 243 | scope.range = { 244 | lower: 1, 245 | upper: 1, 246 | total: 1 247 | }; 248 | 249 | scope.$watch(function() { 250 | return paginationService.getCollectionLength(paginationId) ; 251 | }, function(length) { 252 | if (0 < length) { 253 | generatePagination(); 254 | } 255 | }); 256 | 257 | scope.$watch(function() { 258 | return (paginationService.getItemsPerPage(paginationId)); 259 | }, function(current, previous) { 260 | if (current != previous && typeof previous !== 'undefined') { 261 | //goToPage(scope.pagination.current); 262 | } 263 | }); 264 | 265 | scope.$watch(function() { 266 | return paginationService.getCurrentPage(paginationId); 267 | }, function(currentPage, previousPage) { 268 | if (currentPage != previousPage) { 269 | // goToPage(currentPage); 270 | } 271 | }); 272 | 273 | scope.setCurrent = function(num) { 274 | if (isValidPageNumber(num)) { 275 | num = parseInt(num, 10); 276 | //paginationService.setCurrentPage(paginationId, num); 277 | goToPage(num); 278 | } 279 | }; 280 | 281 | function goToPage(num) { 282 | if (isValidPageNumber(num)) { 283 | scope.pages = generatePagesArray(num, paginationService.getCollectionLength(paginationId), paginationService.getItemsPerPage(paginationId), paginationRange); 284 | scope.pagination.current = num; 285 | updateRangeValues(); 286 | 287 | // if a callback has been set, then call it with the page number as an argument 288 | if (scope.onPageChange) { 289 | scope.onPageChange({ newPageNumber : num }); 290 | } 291 | } 292 | } 293 | 294 | function generatePagination() { 295 | var page = parseInt(paginationService.getCurrentPage(paginationId)) || 1; 296 | 297 | scope.pages = generatePagesArray(page, paginationService.getCollectionLength(paginationId), paginationService.getItemsPerPage(paginationId), paginationRange); 298 | scope.pagination.current = page; 299 | scope.pagination.last = scope.pages[scope.pages.length - 1]; 300 | if (scope.pagination.last < scope.pagination.current) { 301 | scope.setCurrent(scope.pagination.last); 302 | } else { 303 | updateRangeValues(); 304 | } 305 | } 306 | 307 | /** 308 | * This function updates the values (lower, upper, total) of the `scope.range` object, which can be used in the pagination 309 | * template to display the current page range, e.g. "showing 21 - 40 of 144 results"; 310 | */ 311 | function updateRangeValues() { 312 | var currentPage = paginationService.getCurrentPage(paginationId), 313 | itemsPerPage = paginationService.getItemsPerPage(paginationId), 314 | totalItems = paginationService.getCollectionLength(paginationId); 315 | 316 | scope.range.lower = (currentPage - 1) * itemsPerPage + 1; 317 | scope.range.upper = Math.min(currentPage * itemsPerPage, totalItems); 318 | scope.range.total = totalItems; 319 | } 320 | 321 | function isValidPageNumber(num) { 322 | return (numberRegex.test(num) && (0 < num && num <= scope.pagination.last)); 323 | } 324 | } 325 | 326 | /** 327 | * Generate an array of page numbers (or the '...' string) which is used in an ng-repeat to generate the 328 | * links used in pagination 329 | * 330 | * @param currentPage 331 | * @param rowsPerPage 332 | * @param paginationRange 333 | * @param collectionLength 334 | * @returns {Array} 335 | */ 336 | function generatePagesArray(currentPage, collectionLength, rowsPerPage, paginationRange) { 337 | var pages = []; 338 | var totalPages = Math.ceil(collectionLength / rowsPerPage); 339 | var halfWay = Math.ceil(paginationRange / 2); 340 | var position; 341 | 342 | if (currentPage <= halfWay) { 343 | position = 'start'; 344 | } else if (totalPages - halfWay < currentPage) { 345 | position = 'end'; 346 | } else { 347 | position = 'middle'; 348 | } 349 | 350 | var ellipsesNeeded = paginationRange < totalPages; 351 | var i = 1; 352 | while (i <= totalPages && i <= paginationRange) { 353 | var pageNumber = calculatePageNumber(i, currentPage, paginationRange, totalPages); 354 | 355 | var openingEllipsesNeeded = (i === 2 && (position === 'middle' || position === 'end')); 356 | var closingEllipsesNeeded = (i === paginationRange - 1 && (position === 'middle' || position === 'start')); 357 | if (ellipsesNeeded && (openingEllipsesNeeded || closingEllipsesNeeded)) { 358 | pages.push('...'); 359 | } else { 360 | pages.push(pageNumber); 361 | } 362 | i ++; 363 | } 364 | return pages; 365 | } 366 | 367 | /** 368 | * Given the position in the sequence of pagination links [i], figure out what page number corresponds to that position. 369 | * 370 | * @param i 371 | * @param currentPage 372 | * @param paginationRange 373 | * @param totalPages 374 | * @returns {*} 375 | */ 376 | function calculatePageNumber(i, currentPage, paginationRange, totalPages) { 377 | var halfWay = Math.ceil(paginationRange/2); 378 | if (i === paginationRange) { 379 | return totalPages; 380 | } else if (i === 1) { 381 | return i; 382 | } else if (paginationRange < totalPages) { 383 | if (totalPages - halfWay < currentPage) { 384 | return totalPages - paginationRange + i; 385 | } else if (halfWay < currentPage) { 386 | return currentPage - halfWay + i; 387 | } else { 388 | return i; 389 | } 390 | } else { 391 | return i; 392 | } 393 | } 394 | } 395 | 396 | /** 397 | * This filter slices the collection into pages based on the current page number and number of items per page. 398 | * @param paginationService 399 | * @returns {Function} 400 | */ 401 | function itemsPerPageFilter(paginationService) { 402 | 403 | return function(collection, itemsPerPage, paginationId) { 404 | if (typeof (paginationId) === 'undefined') { 405 | paginationId = DEFAULT_ID; 406 | } 407 | if (!paginationService.isRegistered(paginationId)) { 408 | throw 'pagination directive: the itemsPerPage id argument (id: ' + paginationId + ') does not match a registered pagination-id.'; 409 | } 410 | var end; 411 | var start; 412 | if (collection instanceof Array) { 413 | itemsPerPage = parseInt(itemsPerPage) || 9999999999; 414 | if (paginationService.isAsyncMode(paginationId)) { 415 | start = 0; 416 | } else { 417 | start = (paginationService.getCurrentPage(paginationId) - 1) * itemsPerPage; 418 | } 419 | end = start + itemsPerPage; 420 | paginationService.setItemsPerPage(paginationId, itemsPerPage); 421 | 422 | return collection.slice(start, end); 423 | } else { 424 | return collection; 425 | } 426 | }; 427 | } 428 | 429 | /** 430 | * This service allows the various parts of the module to communicate and stay in sync. 431 | */ 432 | function paginationService() { 433 | 434 | var instances = {}; 435 | var lastRegisteredInstance; 436 | 437 | this.registerInstance = function(instanceId) { 438 | if (typeof instances[instanceId] === 'undefined') { 439 | instances[instanceId] = { 440 | asyncMode: false 441 | }; 442 | lastRegisteredInstance = instanceId; 443 | } 444 | }; 445 | 446 | this.isRegistered = function(instanceId) { 447 | return (typeof instances[instanceId] !== 'undefined'); 448 | }; 449 | 450 | this.getLastInstanceId = function() { 451 | return lastRegisteredInstance; 452 | }; 453 | 454 | this.setCurrentPageParser = function(instanceId, val, scope) { 455 | instances[instanceId].currentPageParser = val; 456 | instances[instanceId].context = scope; 457 | }; 458 | this.setCurrentPage = function(instanceId, val) { 459 | instances[instanceId].currentPageParser.assign(instances[instanceId].context, val); 460 | }; 461 | this.getCurrentPage = function(instanceId) { 462 | var parser = instances[instanceId].currentPageParser; 463 | return parser ? parser(instances[instanceId].context) : 1; 464 | }; 465 | 466 | this.setItemsPerPage = function(instanceId, val) { 467 | instances[instanceId].itemsPerPage = val; 468 | }; 469 | this.getItemsPerPage = function(instanceId) { 470 | return instances[instanceId].itemsPerPage; 471 | }; 472 | 473 | this.setCollectionLength = function(instanceId, val) { 474 | instances[instanceId].collectionLength = val; 475 | }; 476 | this.getCollectionLength = function(instanceId) { 477 | return instances[instanceId].collectionLength; 478 | }; 479 | 480 | this.setAsyncModeTrue = function(instanceId) { 481 | instances[instanceId].asyncMode = true; 482 | }; 483 | 484 | this.isAsyncMode = function(instanceId) { 485 | return instances[instanceId].asyncMode; 486 | }; 487 | } 488 | 489 | /** 490 | * This provider allows global configuration of the template path used by the dir-pagination-controls directive. 491 | */ 492 | function paginationTemplateProvider() { 493 | 494 | var templatePath = './js/templates/pagination.tpl.html'; 495 | 496 | this.setPath = function(path) { 497 | templatePath = path; 498 | }; 499 | 500 | this.$get = function() { 501 | return { 502 | getPath: function() { 503 | return templatePath; 504 | } 505 | }; 506 | }; 507 | } 508 | 509 | 510 | return angularAMD; 511 | 512 | 513 | 514 | }); 515 | -------------------------------------------------------------------------------- /seed/js/lib/angular-route.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.2.5 3 | (c) 2010-2014 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(h,e,A){'use strict';function u(w,q,k){return{restrict:"ECA",terminal:!0,priority:400,transclude:"element",link:function(a,c,b,f,n){function y(){l&&(l.$destroy(),l=null);g&&(k.leave(g),g=null)}function v(){var b=w.current&&w.current.locals;if(b&&b.$template){var b=a.$new(),f=w.current;g=n(b,function(d){k.enter(d,null,g||c,function(){!e.isDefined(t)||t&&!a.$eval(t)||q()});y()});l=f.scope=b;l.$emit("$viewContentLoaded");l.$eval(h)}else y()}var l,g,t=b.autoscroll,h=b.onload||"";a.$on("$routeChangeSuccess", 7 | v);v()}}}function z(e,h,k){return{restrict:"ECA",priority:-400,link:function(a,c){var b=k.current,f=b.locals;c.html(f.$template);var n=e(c.contents());b.controller&&(f.$scope=a,f=h(b.controller,f),b.controllerAs&&(a[b.controllerAs]=f),c.data("$ngControllerController",f),c.children().data("$ngControllerController",f));n(a)}}}h=e.module("ngRoute",["ng"]).provider("$route",function(){function h(a,c){return e.extend(new (e.extend(function(){},{prototype:a})),c)}function q(a,e){var b=e.caseInsensitiveMatch, 8 | f={originalPath:a,regexp:a},h=f.keys=[];a=a.replace(/([().])/g,"\\$1").replace(/(\/)?:(\w+)([\?|\*])?/g,function(a,e,b,c){a="?"===c?c:null;c="*"===c?c:null;h.push({name:b,optional:!!a});e=e||"";return""+(a?"":e)+"(?:"+(a?e:"")+(c&&"(.+?)"||"([^/]+)")+(a||"")+")"+(a||"")}).replace(/([\/$\*])/g,"\\$1");f.regexp=RegExp("^"+a+"$",b?"i":"");return f}var k={};this.when=function(a,c){k[a]=e.extend({reloadOnSearch:!0},c,a&&q(a,c));if(a){var b="/"==a[a.length-1]?a.substr(0,a.length-1):a+"/";k[b]=e.extend({redirectTo:a}, 9 | q(b,c))}return this};this.otherwise=function(a){this.when(null,a);return this};this.$get=["$rootScope","$location","$routeParams","$q","$injector","$http","$templateCache","$sce",function(a,c,b,f,n,q,v,l){function g(){var d=t(),m=r.current;if(d&&m&&d.$$route===m.$$route&&e.equals(d.pathParams,m.pathParams)&&!d.reloadOnSearch&&!x)m.params=d.params,e.copy(m.params,b),a.$broadcast("$routeUpdate",m);else if(d||m)x=!1,a.$broadcast("$routeChangeStart",d,m),(r.current=d)&&d.redirectTo&&(e.isString(d.redirectTo)? 10 | c.path(u(d.redirectTo,d.params)).search(d.params).replace():c.url(d.redirectTo(d.pathParams,c.path(),c.search())).replace()),f.when(d).then(function(){if(d){var a=e.extend({},d.resolve),c,b;e.forEach(a,function(d,c){a[c]=e.isString(d)?n.get(d):n.invoke(d)});e.isDefined(c=d.template)?e.isFunction(c)&&(c=c(d.params)):e.isDefined(b=d.templateUrl)&&(e.isFunction(b)&&(b=b(d.params)),b=l.getTrustedResourceUrl(b),e.isDefined(b)&&(d.loadedTemplateUrl=b,c=q.get(b,{cache:v}).then(function(a){return a.data}))); 11 | e.isDefined(c)&&(a.$template=c);return f.all(a)}}).then(function(c){d==r.current&&(d&&(d.locals=c,e.copy(d.params,b)),a.$broadcast("$routeChangeSuccess",d,m))},function(c){d==r.current&&a.$broadcast("$routeChangeError",d,m,c)})}function t(){var a,b;e.forEach(k,function(f,k){var p;if(p=!b){var s=c.path();p=f.keys;var l={};if(f.regexp)if(s=f.regexp.exec(s)){for(var g=1,q=s.length;g0){for(var k=0;k")(this.$scope),this.parent.appendChild(this.progressbarEl[0]),this.$scope.count=this.count,void 0!==this.height&&this.progressbarEl.eq(0).children().css("height",this.height),void 0!==this.color&&(this.progressbarEl.eq(0).children().css("background-color",this.color),this.progressbarEl.eq(0).children().css("color",this.color)),this.intervalCounterId=0,this.start=function(){this.show();var a=this;clearInterval(this.intervalCounterId),this.intervalCounterId=setInterval(function(){isNaN(a.count)?(clearInterval(a.intervalCounterId),a.count=0,a.hide()):(a.remaining=100-a.count,a.count=a.count+.15*Math.pow(1-Math.sqrt(a.remaining),2),a.updateCount(a.count))},200)},this.updateCount=function(a){this.$scope.count=a,this.$scope.$$phase||this.$scope.$apply()},this.setHeight=function(a){return void 0!==a&&(this.height=a,this.$scope.height=this.height,this.$scope.$$phase||this.$scope.$apply()),this.height},this.setColor=function(a){return void 0!==a&&(this.color=a,this.$scope.color=this.color,this.$scope.$$phase||this.$scope.$apply()),this.color},this.hide=function(){this.progressbarEl.children().css("opacity","0");var a=this;a.animate(function(){a.progressbarEl.children().css("width","0%"),a.animate(function(){a.show()},500)},500)},this.show=function(){var a=this;a.animate(function(){a.progressbarEl.children().css("opacity","1")},100)},this.animate=function(a,b){void 0!==this.animation&&e.cancel(this.animation),this.animation=e(a,b)},this.status=function(){return this.count},this.stop=function(){clearInterval(this.intervalCounterId)},this.set=function(a){return this.show(),this.updateCount(a),this.count=a,clearInterval(this.intervalCounterId),this.count},this.css=function(a){return this.progressbarEl.children().css(a)},this.reset=function(){return clearInterval(this.intervalCounterId),this.count=0,this.updateCount(this.count),0},this.complete=function(){this.count=100,this.updateCount(this.count);var a=this;return clearInterval(this.intervalCounterId),e(function(){a.hide(),e(function(){a.count=0,a.updateCount(a.count)},500)},1e3),this.count},this.setParent=function(a){if(null===a||void 0===a)throw new Error("Provide a valid parent of type HTMLElement");null!==this.parent&&void 0!==this.parent&&this.parent.removeChild(this.progressbarEl[0]),this.parent=a,this.parent.appendChild(this.progressbarEl[0])},this.getDomElement=function(){return this.progressbarEl},this.setAbsolute=function(){this.progressbarEl.css("position","absolute")}}]}).factory("ngProgressFactory",["$injector","ngProgress",function(a,b){var c={createInstance:function(){return a.instantiate(b)}};return c}]),angular.module("ngProgress.directive",[]).directive("ngProgress",["$window","$rootScope",function(a,b){var c={replace:!0,restrict:"E",link:function(a,b,c,d){a.$watch("count",function(c){(void 0!==c||null!==c)&&(a.counter=c,b.eq(0).children().css("width",c+"%"))}),a.$watch("color",function(c){(void 0!==c||null!==c)&&(a.color=c,b.eq(0).children().css("background-color",c),b.eq(0).children().css("color",c))}),a.$watch("height",function(c){(void 0!==c||null!==c)&&(a.height=c,b.eq(0).children().css("height",c))})},template:'
    '};return c}]),angular.module("ngProgress",["ngProgress.directive","ngProgress.provider"]); -------------------------------------------------------------------------------- /seed/js/lib/validator.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Validator v0.6.0 for Bootstrap 3, by @1000hz 3 | * Copyright 2014 Spiceworks, Inc. 4 | * Licensed under http://opensource.org/licenses/MIT 5 | * 6 | * https://github.com/1000hz/bootstrap-validator 7 | */ 8 | 9 | +function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),f=d.data("bs.validator");(f||"destroy"!=b)&&(f||d.data("bs.validator",f=new c(this,e)),"string"==typeof b&&f[b]())})}var c=function(b,c){this.$element=a(b),this.options=c,this.$element.attr("novalidate",!0),this.toggleSubmit(),this.$element.on("input.bs.validator change.bs.validator focusout.bs.validator",a.proxy(this.validateInput,this)),this.$element.on("submit.bs.validator",a.proxy(this.onSubmit,this)),this.$element.find("[data-match]").each(function(){var b=a(this),c=b.data("match");a(c).on("input.bs.validator",function(){b.val()&&b.trigger("input")})})};c.DEFAULTS={delay:500,html:!1,disable:!0,errors:{match:"Does not match",minlength:"Not long enough"}},c.VALIDATORS={"native":function(a){var b=a[0];return b.checkValidity?b.checkValidity():!0},match:function(b){var c=b.data("match");return!b.val()||b.val()===a(c).val()},minlength:function(a){var b=a.data("minlength");return!a.val()||a.val().length>=b}},c.prototype.validateInput=function(b){var c=a(b.target),d=c.data("bs.validator.errors");if(c.is('[type="radio"]')&&(c=this.$element.find('input[name="'+c.attr("name")+'"]')),this.$element.trigger(b=a.Event("validate.bs.validator",{relatedTarget:c[0]})),!b.isDefaultPrevented()){var e=this;this.runValidators(c).done(function(f){c.data("bs.validator.errors",f),f.length?e.showErrors(c):e.clearErrors(c),d&&f.toString()===d.toString()||(b=f.length?a.Event("invalid.bs.validator",{relatedTarget:c[0],detail:f}):a.Event("valid.bs.validator",{relatedTarget:c[0],detail:d}),e.$element.trigger(b)),e.toggleSubmit(),e.$element.trigger(a.Event("validated.bs.validator",{relatedTarget:c[0]}))})}},c.prototype.runValidators=function(b){function d(a){return b.data(a+"-error")||b.data("error")||"native"==a&&b[0].validationMessage||g.errors[a]}var e=[],f=([c.VALIDATORS["native"]],a.Deferred()),g=this.options;return b.data("bs.validator.deferred")&&b.data("bs.validator.deferred").reject(),b.data("bs.validator.deferred",f),a.each(c.VALIDATORS,a.proxy(function(a,c){if((b.data(a)||"native"==a)&&!c.call(this,b)){var f=d(a);!~e.indexOf(f)&&e.push(f)}},this)),!e.length&&b.val()&&b.data("remote")?this.defer(b,function(){a.get(b.data("remote"),[b.attr("name"),b.val()].join("=")).fail(function(a,b,c){e.push(d("remote")||c)}).always(function(){f.resolve(e)})}):f.resolve(e),f.promise()},c.prototype.validate=function(){var a=this.options.delay;return this.options.delay=0,this.$element.find(":input").trigger("input"),this.options.delay=a,this},c.prototype.showErrors=function(b){var c=this.options.html?"html":"text";this.defer(b,function(){var d=b.closest(".form-group"),e=d.find(".help-block.with-errors"),f=b.data("bs.validator.errors");f.length&&(f=a("
      ").addClass("list-unstyled").append(a.map(f,function(b){return a("
    • ")[c](b)})),void 0===e.data("bs.validator.originalContent")&&e.data("bs.validator.originalContent",e.html()),e.empty().append(f),d.addClass("has-error"))})},c.prototype.clearErrors=function(a){var b=a.closest(".form-group"),c=b.find(".help-block.with-errors");c.html(c.data("bs.validator.originalContent")),b.removeClass("has-error")},c.prototype.hasErrors=function(){function b(){return!!(a(this).data("bs.validator.errors")||[]).length}return!!this.$element.find(":input:enabled").filter(b).length},c.prototype.isIncomplete=function(){function b(){return"checkbox"===this.type?!this.checked:"radio"===this.type?!a('[name="'+this.name+'"]:checked').length:""===a.trim(this.value)}return!!this.$element.find(":input[required]:enabled").filter(b).length},c.prototype.onSubmit=function(a){this.validate(),(this.isIncomplete()||this.hasErrors())&&a.preventDefault()},c.prototype.toggleSubmit=function(){if(this.options.disable){var a=this.$element.find('input[type="submit"], button[type="submit"]');a.toggleClass("disabled",this.isIncomplete()||this.hasErrors()).css({"pointer-events":"all",cursor:"pointer"})}},c.prototype.defer=function(a,b){return this.options.delay?(window.clearTimeout(a.data("bs.validator.timeout")),void a.data("bs.validator.timeout",window.setTimeout(b,this.options.delay))):b()},c.prototype.destroy=function(){return this.$element.removeAttr("novalidate").removeData("bs.validator").off(".bs.validator"),this.$element.find(":input").removeData(["bs.validator.errors","bs.validator.deferred","bs.validator.timeout"]).off(".bs.validator"),this.$element.find(".help-block.with-errors").each(function(){var b=a(this),c=b.data("bs.validator.originalContent");b.removeData("bs.validator.originalContent").html(c)}),this.$element.find('input[type="submit"], button[type="submit"]').removeClass("disabled"),this.$element.find(".has-error").removeClass("has-error"),this};var d=a.fn.validator;a.fn.validator=b,a.fn.validator.Constructor=c,a.fn.validator.noConflict=function(){return a.fn.validator=d,this},a(window).on("load",function(){a('form[data-toggle="validator"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery); -------------------------------------------------------------------------------- /seed/js/main.js: -------------------------------------------------------------------------------- 1 | // 定义入口文件 2 | 3 | require.config({ 4 | baseUrl: "./js/", 5 | urlArgs: 'v=' + (new Date()).getTime() + Math.random() * 10000, 6 | paths: { 7 | 'angular': './lib/angular.min', 8 | 'angular-route': './lib/angular-route', 9 | 'angularAMD': './lib/angularAMD.min', 10 | 'ngload' : './lib/' + 'ngload.min', 11 | 'ng-progress': './lib/ngprogress.min', 12 | 'vued.cat': './directive/cat', 13 | 'pagination': './directive/pagination' 14 | }, 15 | shim: { 16 | 'angularAMD': ['angular'], 17 | 'angular-route': ['angular'], 18 | 'ng-progress': ['angular'], 19 | }, 20 | deps: ['app'] 21 | }); 22 | -------------------------------------------------------------------------------- /seed/js/service/keyshortcut.js: -------------------------------------------------------------------------------- 1 | define(['angularAMD'], function (angularAMD) { 2 | 3 | // This service was based on OpenJS library available in BSD License 4 | // http://www.openjs.com/scripts/events/keyboard_shortcuts/index.php 5 | angularAMD.factory('keyshortcut', ['$window', '$timeout', function ($window, $timeout) { 6 | var keyboardManagerService = {}; 7 | 8 | var defaultOpt = { 9 | 'type': 'keydown', 10 | 'propagate': false, 11 | 'inputDisabled': false, 12 | 'target': $window.document, 13 | 'keyCode': false 14 | }; 15 | // Store all keyboard combination shortcuts 16 | keyboardManagerService.keyboardEvent = {} 17 | 18 | // when keydown a return a 19 | keyboardManagerService.input = function(callback,opt){ 20 | var fct, elt, code, k; 21 | // Initialize opt object 22 | opt = angular.extend({}, defaultOpt, opt); 23 | elt = opt.target; 24 | if(typeof opt.target == 'string') elt = document.getElementById(opt.target); 25 | 26 | fct = function (e) { 27 | e = e || $window.event; 28 | 29 | // Disable event handler when focus input and textarea 30 | if (opt['inputDisabled']) { 31 | var elt; 32 | if (e.target) elt = e.target; 33 | else if (e.srcElement) elt = e.srcElement; 34 | if (elt.nodeType == 3) elt = elt.parentNode; 35 | if (elt.tagName == 'INPUT' || elt.tagName == 'TEXTAREA') return; 36 | } 37 | 38 | // Find out which key is pressed 39 | if (e.keyCode) code = e.keyCode; 40 | else if (e.which) code = e.which; 41 | var character = String.fromCharCode(code).toLowerCase(); 42 | 43 | if (code == 188) character = ","; 44 | if (code == 189) character = "-"; 45 | if (code == 190) character = "."; 46 | if (code == 222) character = "'"; 47 | 48 | callback(character); 49 | 50 | }; 51 | 52 | //Attach the function with the event 53 | if(elt.addEventListener) elt.addEventListener(opt['type'], fct, false); 54 | else if(elt.attachEvent) elt.attachEvent('on' + opt['type'], fct); 55 | else elt['on' + opt['type']] = fct; 56 | } 57 | 58 | // Add a new keyboard combination shortcut 59 | keyboardManagerService.bind = function (label, callback, opt) { 60 | var fct, elt, code, k; 61 | // Initialize opt object 62 | opt = angular.extend({}, defaultOpt, opt); 63 | label = label.toLowerCase(); 64 | elt = opt.target; 65 | if(typeof opt.target == 'string') elt = document.getElementById(opt.target); 66 | 67 | fct = function (e) { 68 | e = e || $window.event; 69 | 70 | // Disable event handler when focus input and textarea 71 | if (opt['inputDisabled']) { 72 | var elt; 73 | if (e.target) elt = e.target; 74 | else if (e.srcElement) elt = e.srcElement; 75 | if (elt.nodeType == 3) elt = elt.parentNode; 76 | if (elt.tagName == 'INPUT' || elt.tagName == 'TEXTAREA') return; 77 | } 78 | 79 | // Find out which key is pressed 80 | if (e.keyCode) code = e.keyCode; 81 | else if (e.which) code = e.which; 82 | var character = String.fromCharCode(code).toLowerCase(); 83 | 84 | if (code == 188) character = ","; // If the user presses , when the type is onkeydown 85 | if (code == 190) character = "."; // If the user presses , when the type is onkeydown 86 | 87 | var keys = label.split("+"); 88 | // Key Pressed - counts the number of valid keypresses - if it is same as the number of keys, the shortcut function is invoked 89 | var kp = 0; 90 | // Work around for stupid Shift key bug created by using lowercase - as a result the shift+num combination was broken 91 | var shift_nums = { 92 | "`":"~", 93 | "1":"!", 94 | "2":"@", 95 | "3":"#", 96 | "4":"$", 97 | "5":"%", 98 | "6":"^", 99 | "7":"&", 100 | "8":"*", 101 | "9":"(", 102 | "0":")", 103 | "-":"_", 104 | "=":"+", 105 | ";":":", 106 | "'":"\"", 107 | ",":"<", 108 | ".":">", 109 | "/":"?", 110 | "\\":"|" 111 | }; 112 | // Special Keys - and their codes 113 | var special_keys = { 114 | 'esc':27, 115 | 'escape':27, 116 | 'tab':9, 117 | 'space':32, 118 | 'return':13, 119 | 'enter':13, 120 | 'backspace':8, 121 | 122 | 'scrolllock':145, 123 | 'scroll_lock':145, 124 | 'scroll':145, 125 | 'capslock':20, 126 | 'caps_lock':20, 127 | 'caps':20, 128 | 'numlock':144, 129 | 'num_lock':144, 130 | 'num':144, 131 | 132 | 'pause':19, 133 | 'break':19, 134 | 135 | 'insert':45, 136 | 'home':36, 137 | 'delete':46, 138 | 'end':35, 139 | 140 | 'pageup':33, 141 | 'page_up':33, 142 | 'pu':33, 143 | 144 | 'pagedown':34, 145 | 'page_down':34, 146 | 'pd':34, 147 | 148 | 'left':37, 149 | 'up':38, 150 | 'right':39, 151 | 'down':40, 152 | 153 | 'f1':112, 154 | 'f2':113, 155 | 'f3':114, 156 | 'f4':115, 157 | 'f5':116, 158 | 'f6':117, 159 | 'f7':118, 160 | 'f8':119, 161 | 'f9':120, 162 | 'f10':121, 163 | 'f11':122, 164 | 'f12':123 165 | }; 166 | // Some modifiers key 167 | var modifiers = { 168 | shift: { 169 | wanted: false, 170 | pressed: e.shiftKey ? true : false 171 | }, 172 | ctrl : { 173 | wanted: false, 174 | pressed: e.ctrlKey ? true : false 175 | }, 176 | alt : { 177 | wanted: false, 178 | pressed: e.altKey ? true : false 179 | }, 180 | meta : { //Meta is Mac specific 181 | wanted: false, 182 | pressed: e.metaKey ? true : false 183 | } 184 | }; 185 | // Foreach keys in label (split on +) 186 | for(var i=0, l=keys.length; k=keys[i],i 1) { // If it is a special key 202 | if(special_keys[k] == code) kp++; 203 | } else if (opt['keyCode']) { // If a specific key is set into the config 204 | if (opt['keyCode'] == code) kp++; 205 | } else { // The special keys did not match 206 | if(character == k) kp++; 207 | else { 208 | if(shift_nums[character] && e.shiftKey) { // Stupid Shift key bug created by using lowercase 209 | character = shift_nums[character]; 210 | if(character == k) kp++; 211 | } 212 | } 213 | } 214 | } 215 | 216 | if(kp == keys.length && 217 | modifiers.ctrl.pressed == modifiers.ctrl.wanted && 218 | modifiers.shift.pressed == modifiers.shift.wanted && 219 | modifiers.alt.pressed == modifiers.alt.wanted && 220 | modifiers.meta.pressed == modifiers.meta.wanted) { 221 | $timeout(function() { 222 | callback(e); 223 | }, 1); 224 | 225 | if(!opt['propagate']) { // Stop the event 226 | // e.cancelBubble is supported by IE - this will kill the bubbling process. 227 | e.cancelBubble = true; 228 | e.returnValue = false; 229 | 230 | // e.stopPropagation works in Firefox. 231 | if (e.stopPropagation) { 232 | e.stopPropagation(); 233 | e.preventDefault(); 234 | } 235 | return false; 236 | } 237 | } 238 | 239 | }; 240 | // Store shortcut 241 | keyboardManagerService.keyboardEvent[label] = { 242 | 'callback': fct, 243 | 'target': elt, 244 | 'event': opt['type'] 245 | }; 246 | //Attach the function with the event 247 | if(elt.addEventListener) elt.addEventListener(opt['type'], fct, false); 248 | else if(elt.attachEvent) elt.attachEvent('on' + opt['type'], fct); 249 | else elt['on' + opt['type']] = fct; 250 | }; 251 | // Remove the shortcut - just specify the shortcut and I will remove the binding 252 | keyboardManagerService.unbind = function (label) { 253 | label = label.toLowerCase(); 254 | var binding = keyboardManagerService.keyboardEvent[label]; 255 | delete(keyboardManagerService.keyboardEvent[label]) 256 | if(!binding) return; 257 | var type = binding['event'], 258 | elt = binding['target'], 259 | callback = binding['callback']; 260 | if(elt.detachEvent) elt.detachEvent('on' + type, callback); 261 | else if(elt.removeEventListener) elt.removeEventListener(type, callback, false); 262 | else elt['on'+type] = false; 263 | }; 264 | // 265 | return keyboardManagerService; 266 | }]); 267 | 268 | 269 | 270 | 271 | 272 | }); 273 | -------------------------------------------------------------------------------- /seed/js/templates/cat.tpl.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /seed/js/templates/pagination.tpl.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /seed/less/config.less: -------------------------------------------------------------------------------- 1 | /**config **/ 2 | 3 | @bgcolor: #f1f1f1; 4 | 5 | 6 | 7 | /***flat ui color**/ 8 | 9 | @turquoise: #1abc9c; 10 | @green-sea: #16a085; 11 | 12 | @emerald: #2ecc71; 13 | @nephritis: #27ae60; 14 | 15 | @peter-river: #3498db; 16 | @belize-hole: #2980b9; 17 | 18 | @amethyst: #9b59b6; 19 | @wisteria: #8e44ad; 20 | 21 | @wet-asphalt: #34495e; 22 | @midnight-blue: #2c3e50; 23 | 24 | @sun-flower: #f1c40f; 25 | @orange: #f39c12; 26 | 27 | @carrot: #e67e22; 28 | @pumpkin: #d35400; 29 | 30 | @alizarin: #e74c3c; 31 | @pomegranate: #c0392b; 32 | 33 | @clouds: #ecf0f1; 34 | @silver: #bdc3c7; 35 | 36 | @concrete: #95a5a6; 37 | @asbestos: #7f8c8d; 38 | 39 | /****/ 40 | 41 | @gray: @concrete; 42 | @gray-light: @silver; 43 | @inverse: white; 44 | 45 | // Brand colors 46 | @brand-primary: @wet-asphalt; 47 | @brand-secondary: @turquoise; 48 | @brand-success: @emerald; 49 | @brand-warning: @sun-flower; 50 | @brand-danger: @alizarin; 51 | @brand-info: @peter-river; 52 | 53 | @body-bg: #fff; 54 | @text-color: @brand-primary; 55 | 56 | //** Global textual link color. 57 | @link-color: @green-sea; 58 | @link-hover-color: @turquoise; 59 | //** Link hover decoration. 60 | @link-hover-decoration: none; 61 | 62 | 63 | //== Typography 64 | // 65 | //## Font, line-height for body text, headings, and more. 66 | 67 | @font-family-base: '\5FAE\8F6F\96C5\9ED1','\9ED1\4F53',arial,sans-serif; 68 | @font-family-demo: "Helvetica Neue", Helvetica, Arial, sans-serif; 69 | @font-family-monospace: Monaco, Menlo, Consolas, "Courier New", monospace; 70 | @font-size-base: 14px; 71 | 72 | @local-font-path: "../fonts/lato/"; 73 | @local-font-name: "lato-regular"; 74 | @local-font-svg-id: "latoregular"; 75 | @local-font-name-light: "lato-light"; 76 | @local-font-svg-id-light: "latolight"; 77 | @local-font-name-black: "lato-black"; 78 | @local-font-svg-id-black: "latoblack"; 79 | @local-font-name-bold: "lato-bold"; 80 | @local-font-svg-id-bold: "latobold"; 81 | @local-font-name-italic: "lato-italic"; 82 | @local-font-svg-id-italic: "latoitalic"; 83 | @local-font-name-bold-italic: "lato-bolditalic"; 84 | @local-font-svg-id-bold-italic: "latobold-italic"; 85 | 86 | @font-size-h1: floor((@font-size-base * 3.444)); // ~62px 87 | @font-size-h2: ceil((@font-size-base * 2.889)); // ~52px 88 | @font-size-h3: ceil((@font-size-base * 2.222)); // ~40px 89 | @font-size-h4: ceil((@font-size-base * 1.611)); // ~29px 90 | @font-size-h5: floor((@font-size-base * 1.556)); // ~28px 91 | @font-size-h6: ceil((@font-size-base * 1.333)); // ~24px 92 | 93 | @line-height-base: 1.72222; // 31/18 94 | @line-height-computed: floor((@font-size-base * @line-height-base)); // ~31px 95 | 96 | @headings-font-family: inherit; 97 | @headings-font-weight: 700; 98 | @headings-line-height: 1.1; 99 | @headings-color: inherit; 100 | 101 | 102 | //== Iconography 103 | // 104 | //## Specify custom locations of the include Glyphicons icon font. 105 | 106 | @icon-font-path: "../fonts/glyphicons/"; 107 | @icon-font-name: "flat-ui-icons-regular"; 108 | @icon-font-svg-id: "flat-ui-icons-regular"; 109 | 110 | //** Icon sizes for use in components 111 | @icon-normal: 16px; 112 | @icon-medium: 18px; 113 | @icon-large: 32px; 114 | 115 | 116 | //== Components 117 | // 118 | //## Define common padding and border radius sizes and more. 119 | 120 | //** Default font-size in components 121 | @component-font-size-base: ceil((@font-size-base * 0.833)); // ~15px 122 | 123 | // Border-radius 124 | @border-radius-base: 4px; 125 | @border-radius-large: 6px; 126 | @border-radius-small: 3px; 127 | 128 | //** Width of the `border` for generating carets that indicator dropdowns. 129 | @caret-width-base: 6px; 130 | @caret-width-base-vertical: (@caret-width-base + 2); 131 | 132 | @caret-width-xs: 4px; 133 | @caret-width-xs-vertical: (@caret-width-xs + 2); 134 | 135 | //== Buttons 136 | // 137 | //## For each of Flat UI's buttons, define text, background, font size and height. 138 | 139 | @btn-font-size-base: @component-font-size-base; 140 | @btn-font-size-xs: ceil((@component-font-size-base * 0.8)); // ~12px 141 | @btn-font-size-sm: floor((@component-font-size-base * 0.867)); // ~13px 142 | @btn-font-size-lg: ceil((@component-font-size-base * 1.133)); // ~17px 143 | @btn-font-size-hg: floor((@component-font-size-base * 1.467)); // ~22px 144 | 145 | @btn-line-height-base: 1.4; // ~21px 146 | @btn-line-height-hg: 1.227; // ~27px 147 | @btn-line-height-lg: 1.471; // ~25px 148 | @btn-line-height-sm: 1.385; // ~16px 149 | @btn-line-height-xs: 1.083; // ~13px 150 | 151 | @btn-social-font-size-base: floor((@component-font-size-base * 0.867)); // ~13px 152 | @btn-social-line-height-base: 1.077; // ~14px 153 | 154 | @btn-font-weight: normal; 155 | 156 | @btn-default-color: @inverse; 157 | @btn-default-bg: @gray-light; 158 | @btn-hover-bg: mix(@gray-light, white, 80%); 159 | @btn-active-bg: mix(@gray-light, black, 85%); 160 | 161 | @btn-primary-hover-bg: mix(@brand-secondary, white, 80%); 162 | @btn-primary-active-bg: mix(@brand-secondary, black, 85%); 163 | 164 | @btn-info-hover-bg: mix(@brand-info, white, 80%); 165 | @btn-info-active-bg: mix(@brand-info, black, 85%); 166 | 167 | @btn-success-hover-bg: mix(@brand-success, white, 80%); 168 | @btn-success-active-bg: mix(@brand-success, black, 85%); 169 | 170 | @btn-danger-hover-bg: mix(@brand-danger, white, 80%); 171 | @btn-danger-active-bg: mix(@brand-danger, black, 85%); 172 | 173 | @btn-warning-hover-bg: overlay(@brand-warning, darken(white, 37.5%)); 174 | @btn-warning-active-bg: mix(@brand-warning, black, 85%); 175 | 176 | @btn-inverse-hover-bg: overlay(@brand-primary, darken(white, 37.5%)); 177 | @btn-inverse-active-bg: mix(@brand-primary, black, 85%); 178 | 179 | @btn-link-disabled-color: @gray-light; 180 | 181 | 182 | //== Forms 183 | // 184 | //## 185 | 186 | @input-font-size-base: @component-font-size-base; 187 | @input-font-size-sm: floor((@component-font-size-base * 0.867)); // ~13px 188 | @input-font-size-lg: ceil((@component-font-size-base * 1.133)); // ~17px 189 | @input-font-size-hg: floor((@component-font-size-base * 1.467)); // ~22px 190 | 191 | @input-line-height-base: 1.467; // ~22px 192 | @input-line-height-sm: 1.462; // ~19px 193 | @input-line-height-lg: 1.235; // ~21px 194 | @input-line-height-hg: 1.318; // ~29px 195 | 196 | @input-icon-font-size: ceil((@component-font-size-base * 1.067)); // ~16px 197 | @input-icon-font-size-lg: ceil((@component-font-size-base * 1.2)); // ~18px 198 | @input-icon-font-size-hg: ceil((@component-font-size-base * 1.333)); // ~20px 199 | 200 | @input-bg: @inverse; 201 | @input-bg-disabled: mix(@gray, white, 10%); 202 | 203 | @input-height-sm: 35px; 204 | @input-height-base: 41px; 205 | @input-height-lg: 45px; 206 | @input-height-hg: 53px; 207 | 208 | @input-border-radius: @border-radius-large; 209 | 210 | //** Disabled cursor for form controls and buttons. 211 | @cursor-disabled: not-allowed; 212 | 213 | @legend-color: inherit; 214 | 215 | 216 | 217 | 218 | 219 | 220 | //== Tags Input 221 | // 222 | //## 223 | 224 | @tagsinput-container-bg: @inverse; 225 | @tagsinput-container-border-color: mix(@inverse, @brand-primary, 90%); 226 | @tagsinput-container-border-radius: @border-radius-large; 227 | 228 | @tagsinput-input-color: @brand-primary; 229 | 230 | @tagsinput-tag-bg: mix(@inverse, @brand-primary, 90%); 231 | @tagsinput-tag-color: mix(@brand-primary, @inverse, 65%); 232 | @tagsinput-tag-hover-bg: mix(@brand-secondary, black, 85%); 233 | @tagsinput-tag-hover-color: @inverse; 234 | @tagsinput-tag-icon-color: @inverse; 235 | @tagsinput-tag-border-radius: @border-radius-base; 236 | 237 | @tagsinput-primary-container-border-color: @brand-secondary; 238 | @tagsinput-primary-tag-bg: @brand-secondary; 239 | @tagsinput-primary-tag-color: @inverse; 240 | @tagsinput-primary-tag-hover-bg: mix(@brand-secondary, black, 85%); 241 | @tagsinput-primary-tag-hover-color: @inverse; 242 | 243 | 244 | //== Selects 245 | // 246 | //## For each of Flat UI's selects, define text, background, font size and height. 247 | 248 | @select-font-size-base: @btn-font-size-base; 249 | @select-font-size-sm: @btn-font-size-sm; 250 | @select-font-size-lg: @btn-font-size-lg; 251 | @select-font-size-hg: @btn-font-size-hg; 252 | 253 | @select-line-height-base: @btn-line-height-base; 254 | @select-line-height-hg: @btn-line-height-hg; 255 | @select-line-height-lg: @btn-line-height-lg; 256 | @select-line-height-sm: @btn-line-height-sm; 257 | 258 | @select-font-weight: @btn-font-weight; 259 | 260 | @select-disabled-opacity: 0.7; 261 | 262 | @select-default-color: @btn-default-color; 263 | @select-default-bg: @btn-default-bg; 264 | @select-default-hover-bg: @btn-hover-bg; 265 | @select-default-active-bg: @btn-active-bg; 266 | 267 | @select-primary-hover-bg: @btn-primary-hover-bg; 268 | @select-primary-active-bg: @btn-primary-active-bg; 269 | 270 | @select-info-hover-bg: @btn-info-hover-bg; 271 | @select-info-active-bg: @btn-info-active-bg; 272 | 273 | @select-success-hover-bg: @btn-success-hover-bg; 274 | @select-success-active-bg: @btn-success-active-bg; 275 | 276 | @select-danger-hover-bg: @btn-danger-hover-bg; 277 | @select-danger-active-bg: @btn-danger-active-bg; 278 | 279 | @select-warning-hover-bg: @btn-warning-hover-bg; 280 | @select-warning-active-bg: @btn-warning-active-bg; 281 | 282 | @select-inverse-hover-bg: @btn-inverse-hover-bg; 283 | @select-inverse-active-bg: @btn-inverse-active-bg; 284 | 285 | @select-link-disabled-color: @btn-link-disabled-color; 286 | @select-arrow-color: @brand-primary; 287 | 288 | // Select dropdowns 289 | @select-dropdown-border-radius: @border-radius-base; 290 | 291 | @select-dropdown-item-color: fade(@brand-primary, 85%); 292 | @select-dropdown-item-hover-color: inherit; 293 | @select-dropdown-item-hover-bg: mix(@inverse, @brand-primary, 85%); 294 | 295 | @select-dropdown-disabled-item-color: fade(@brand-primary, 95%); 296 | @select-dropdown-disabled-item-opacity: 0.4; 297 | 298 | @select-dropdown-highlighted-item-bg: @brand-secondary; 299 | @select-dropdown-highlighted-item-color: @inverse; 300 | 301 | @select-dropdown-optgroup-color: fade(@brand-primary, 60%); 302 | 303 | // Multiselect 304 | @multiselect-container-bg: @tagsinput-container-bg; 305 | @multiselect-container-border-color: @tagsinput-container-border-color; 306 | @multiselect-container-border-radius: @tagsinput-container-border-radius; 307 | 308 | @multiselect-tag-border-radius: @tagsinput-tag-border-radius; 309 | @multiselect-tag-color: @inverse; 310 | @multiselect-tag-hover-color: @tagsinput-tag-hover-color; 311 | @multiselect-tag-icon-color: @tagsinput-tag-icon-color; 312 | 313 | @multiselect-dropdown-border-radius: @border-radius-large; 314 | @multiselect-dropdown-item-border-radius: @border-radius-base; 315 | 316 | @multiselect-input-color: @tagsinput-input-color; 317 | 318 | 319 | //== Pagination 320 | // 321 | //## 322 | 323 | @pagination-bg: mix(@brand-primary, white, 20%); 324 | @pagination-hover-bg: @brand-secondary; 325 | @pagination-color: @inverse; 326 | @pagination-border-radius: @border-radius-large; 327 | 328 | 329 | //== Pager 330 | // 331 | //## 332 | 333 | @pager-padding: 9px 15px 10px; 334 | @pager-bg: @brand-primary; 335 | @pager-hover-bg: mix(@brand-primary, black, 85%); 336 | @pager-active-bg: @pager-hover-bg; 337 | @pager-border-radius: @border-radius-large; 338 | @pager-color: @inverse; 339 | 340 | 341 | 342 | 343 | //== Navbar 344 | // 345 | //## 346 | 347 | // Basics of a navbar 348 | @zindex-navbar: 1000; 349 | @zindex-navbar-fixed: 1030; 350 | @navbar-height-base: 53px; 351 | @navbar-height-large: 76px; 352 | @navbar-input-line-height: 1.4; // ~21px 353 | @navbar-margin-bottom: @line-height-computed; 354 | @navbar-border-radius: @border-radius-large; 355 | 356 | @navbar-default-bg: saturate(spin(tint(@brand-primary, 91%), -18), 2%); 357 | 358 | // Navbar links 359 | @navbar-default-link-color: @brand-primary; 360 | @navbar-default-link-hover-color: @brand-secondary; 361 | @navbar-default-link-hover-bg: transparent; 362 | @navbar-default-link-active-color: @brand-secondary; 363 | @navbar-default-link-active-bg: transparent; 364 | @navbar-default-link-disabled-color: #ccc; 365 | @navbar-default-link-disabled-bg: transparent; 366 | 367 | // Navbar nav carets 368 | @navbar-default-caret-color: @navbar-default-link-color; 369 | @navbar-default-caret-hover-color: @navbar-default-link-hover-color; 370 | @navbar-default-caret-active-color: @navbar-default-link-active-color; 371 | 372 | // Navbar brand label 373 | @navbar-default-brand-color: @navbar-default-link-color; 374 | @navbar-default-brand-hover-color: @navbar-default-link-hover-color; 375 | @navbar-default-brand-hover-bg: transparent; 376 | 377 | // Navbar toggle 378 | @navbar-default-toggle-color: @navbar-default-link-color; 379 | @navbar-default-toggle-hover-color: @navbar-default-link-hover-color; 380 | 381 | // Navbar form 382 | @navbar-default-form-placeholder: spin(tint(@brand-primary, 60%), 2); 383 | @navbar-default-form-icon: desaturate(tint(@brand-primary, 45%), 2%); 384 | @navbar-default-form-border: shade(@navbar-default-bg, 3%); 385 | 386 | 387 | // Inverted navbar 388 | // Reset inverted navbar basics 389 | @navbar-inverse-divider: darken(@brand-primary, 3%); 390 | 391 | // Reset inverted navbar basics 392 | @navbar-inverse-color: @inverse; 393 | @navbar-inverse-bg: @brand-primary; 394 | @navbar-inverse-border: darken(@navbar-inverse-bg, 10%); 395 | 396 | // Inverted navbar links 397 | @navbar-inverse-link-color: @inverse; 398 | @navbar-inverse-link-hover-color: @brand-secondary; 399 | @navbar-inverse-link-hover-bg: transparent; 400 | @navbar-inverse-link-active-color: @navbar-inverse-link-color; 401 | @navbar-inverse-link-active-bg: @brand-secondary; 402 | @navbar-inverse-link-disabled-color: #444; 403 | @navbar-inverse-link-disabled-bg: transparent; 404 | 405 | // Navbar nav carets 406 | @navbar-inverse-caret-color: lighten(desaturate(@brand-primary, 7%), 9%); 407 | @navbar-inverse-caret-hover-color: @navbar-inverse-link-hover-color; 408 | @navbar-inverse-caret-active-color: @navbar-inverse-link-active-color; 409 | 410 | // Inverted navbar brand label 411 | @navbar-inverse-brand-color: @navbar-inverse-link-color; 412 | @navbar-inverse-brand-hover-color: @navbar-inverse-link-hover-color; 413 | @navbar-inverse-brand-hover-bg: transparent; 414 | 415 | // Inverted navbar toggle 416 | @navbar-inverse-toggle-color: @navbar-inverse-link-color; 417 | @navbar-inverse-toggle-hover-color: @navbar-inverse-link-hover-color; 418 | 419 | // Navbar form 420 | @navbar-inverse-form-bg: darken(@brand-primary, 6%); 421 | @navbar-inverse-form-placeholder: desaturate(lighten(@brand-primary, 13%), 7%); 422 | @navbar-inverse-form-icon: desaturate(lighten(@brand-primary, 13%), 6%); 423 | @navbar-inverse-form-border: @navbar-inverse-divider; 424 | 425 | // Navbar dropdowns 426 | @navbar-inverse-dropdown-bg: @navbar-inverse-bg; 427 | @navbar-inverse-dropdown-link-color: mix(@navbar-inverse-bg, @navbar-inverse-color, 15%); 428 | @navbar-inverse-dropdown-link-hover-color: @inverse; 429 | @navbar-inverse-dropdown-link-hover-bg: @brand-secondary; 430 | 431 | //== Dropdowns 432 | // 433 | //## Dropdown menu container and contents. 434 | 435 | 436 | @zindex-dropdown: 1000; 437 | @dropdown-border-radius: @border-radius-base; 438 | 439 | //** Background for the dropdown menu. 440 | @dropdown-bg: desaturate(lighten(@brand-primary, 67%), 20%); 441 | 442 | //** Dropdown link text color. 443 | @dropdown-link-color: mix(darken(@brand-primary, 5%), @inverse, 75%); 444 | //** Hover color for dropdown links. 445 | @dropdown-link-hover-color: darken(@dropdown-link-color, 5%); 446 | //** Hover background for dropdown links. 447 | @dropdown-link-hover-bg: fade(desaturate(lighten(@brand-primary, 52%), 21%), 50%); 448 | 449 | //** Active dropdown menu item text color. 450 | @dropdown-link-active-color: @inverse; 451 | //** Active dropdown menu item background color. 452 | @dropdown-link-active-bg: @brand-secondary; 453 | 454 | //** Disabled dropdown menu item background color. 455 | @dropdown-link-disabled-color: @gray-light; 456 | 457 | //** Divider color for between dropdown items. 458 | @dropdown-divider-bg: fade(@dropdown-link-hover-bg, 50%); 459 | 460 | //** Text color for headers within dropdown menus. 461 | @dropdown-header-color: fade(@brand-primary, 60%); 462 | 463 | 464 | // Inverted dropdown 465 | // 466 | 467 | @dropdown-inverse-bg: @brand-primary; 468 | 469 | 470 | //** Dropdown link text color. 471 | @dropdown-inverse-link-color: fade(@inverse, 85%); 472 | //** Hover color for dropdown links. 473 | @dropdown-inverse-link-hover-color: fade(@inverse, 85%); 474 | //** Hover background for dropdown links. 475 | @dropdown-inverse-link-hover-bg: fade(darken(@brand-primary, 5%), 50%); 476 | 477 | //** Active dropdown menu item text color. 478 | @dropdown-inverse-link-active-color: fade(@inverse, 85%); 479 | //** Active dropdown menu item background color. 480 | @dropdown-inverse-link-active-bg: @brand-secondary; 481 | 482 | //** Disabled dropdown menu item background color. 483 | @dropdown-inverse-link-disabled-color: fade(@dropdown-inverse-link-color, 50%); 484 | 485 | //** Divider color for between dropdown items. 486 | @dropdown-inverse-divider-bg: @dropdown-inverse-link-hover-bg; 487 | 488 | //** Text color for headers within dropdown menus. 489 | @dropdown-inverse-header-color: fade(@inverse, 40%); 490 | 491 | 492 | //== Progress bars 493 | // 494 | //## 495 | 496 | @progress-height: 12px; 497 | 498 | 499 | //== Slider 500 | // 501 | //## 502 | 503 | @slider-height: 12px; 504 | @slider-value-font-size: floor((@component-font-size-base * 0.867)); // ~13px; 505 | 506 | @slider-handle-bg: mix(@brand-secondary, black, 85%); 507 | @slider-handle-hover-bg: mix(@brand-secondary, white, 80%); 508 | @slider-handle-active-bg: mix(@brand-secondary, black, 85%); 509 | 510 | @slider-range-bg: @brand-secondary; 511 | 512 | @slider-segment-bg: mix(desaturate(@brand-primary, 15%), white, 20%); 513 | 514 | 515 | //== Switch 516 | // 517 | //## 518 | 519 | @switch-name: bootstrap-switch; 520 | @switch-border-radius: 30px; 521 | @switch-width: 80px; 522 | @switch-height: 29px; 523 | 524 | 525 | 526 | //== Video player 527 | // 528 | //## 529 | 530 | @vplayer-border-radius: @border-radius-large; 531 | @vplayer-fullscreen-bg: #000; 532 | @vplayer-fullscreen-zindex: 10000; 533 | 534 | @vplayer-control-bar-color: @inverse; 535 | @vplayer-control-bar-bg: @midnight-blue; 536 | 537 | @vplayer-preloader-primary-bg: #e74c3c; 538 | @vplayer-preloader-secondary-bg: #ebedee; 539 | 540 | @vplayer-text-track-bg: rgba(0,0,0,.5); 541 | 542 | @vplaver-play-control-color: @brand-secondary; 543 | @vplaver-play-control-hover-color: mix(@brand-secondary, black, 85%); 544 | 545 | @vplaver-second-controls-color: desaturate(lighten(@midnight-blue, 12%), 6%); 546 | @vplaver-second-controls-hover-color: desaturate(lighten(@midnight-blue, 20%), 6%); 547 | 548 | @vplaver-progress-bg: mix(@brand-primary, @inverse, 93%); 549 | @vplaver-play-progress-bg: @brand-secondary; 550 | @vplaver-load-progress-bg: mix(@brand-primary, @inverse, 20%); 551 | 552 | @vplayer-seek-handle-bg: mix(@brand-secondary, black, 85%); 553 | @vplayer-seek-handle-hover-bg: mix(@brand-secondary, black, 75%); 554 | @vplayer-seek-handle-active-bg: mix(@brand-secondary, black, 65%); 555 | 556 | @vplayer-time-divider-color: mix(@brand-primary, @inverse, 80%); 557 | @vplayer-duration-color: mix(@brand-primary, @inverse, 80%); 558 | 559 | 560 | 561 | 562 | //== Todo list 563 | // 564 | //## 565 | 566 | @todo-bg: @brand-primary; 567 | @todo-bg-active: mix(@brand-primary, black, 85%); 568 | @todo-search-bg: @brand-secondary; 569 | @todo-search-color: @brand-primary; 570 | @todo-color: mix(@brand-primary, @inverse, 66%); 571 | @todo-name-color: @inverse; 572 | @todo-color-active: @brand-secondary; 573 | @todo-border-radius: @border-radius-large; 574 | 575 | 576 | //== Thumbnails 577 | // 578 | //## 579 | 580 | //** Padding around the thumbnail image 581 | @thumbnail-padding: 4px; 582 | //** Thumbnail background color 583 | @thumbnail-bg: @body-bg; 584 | //** Thumbnail border color 585 | @thumbnail-border: @gray-light; 586 | //** Thumbnail border radius 587 | @thumbnail-border-radius: @border-radius-large; 588 | 589 | //** Custom text color for thumbnail captions 590 | @thumbnail-caption-color: @text-color; 591 | //** Padding around the thumbnail caption 592 | @thumbnail-caption-padding: 9px; 593 | 594 | 595 | //== Tiles 596 | // 597 | //## 598 | 599 | @tiles-bg: mix(@brand-primary, @inverse, 8%); 600 | @tiles-border-radius: @border-radius-large; 601 | 602 | 603 | 604 | //== Media queries breakpoints 605 | // 606 | //## Define the breakpoints at which your layout will change, adapting to different screen sizes. 607 | 608 | // Extra small screen / phone 609 | @screen-xs-min: 480px; 610 | 611 | // Small screen / tablet 612 | @screen-sm-min: 768px; 613 | 614 | // Medium screen / desktop 615 | @screen-md-min: 992px; 616 | 617 | // Large screen / wide desktop 618 | @screen-lg-min: 1200px; 619 | 620 | // So media queries don't overlap when required, provide a maximum 621 | @screen-xs-max: (@screen-sm-min - 1); 622 | @screen-sm-max: (@screen-md-min - 1); 623 | @screen-md-max: (@screen-lg-min - 1); 624 | 625 | 626 | //== Grid system 627 | // 628 | //## Define your custom responsive grid. 629 | 630 | //** Number of columns in the grid. 631 | @grid-columns: 12; 632 | //** Padding between columns. Gets divided in half for the left and right. 633 | @grid-gutter-width: 30px; 634 | // Navbar collapse 635 | //** Point at which the navbar becomes uncollapsed. 636 | @grid-float-breakpoint: @screen-sm-min; 637 | //** Point at which the navbar begins collapsing. 638 | @grid-float-breakpoint-max: (@grid-float-breakpoint - 1); 639 | 640 | 641 | //== Form states and alerts 642 | // 643 | //## Define colors for form feedback states and, by default, alerts. 644 | 645 | @state-success-text: @brand-success; 646 | @state-success-bg: #dff0d8; 647 | @state-success-border: darken(spin(@state-success-bg, -10), 5%); 648 | 649 | @state-info-text: @brand-info; 650 | @state-info-bg: #d9edf7; 651 | @state-info-border: darken(spin(@state-info-bg, -10), 7%); 652 | 653 | @state-warning-text: @brand-warning; 654 | @state-warning-bg: #fcf8e3; 655 | @state-warning-border: darken(spin(@state-warning-bg, -10), 5%); 656 | 657 | @state-danger-text: @brand-danger; 658 | @state-danger-bg: #f2dede; 659 | @state-danger-border: darken(spin(@state-danger-bg, -10), 5%); 660 | 661 | 662 | //== Tooltips 663 | // 664 | //## 665 | 666 | //** Tooltip max width 667 | @tooltip-max-width: 183px; 668 | //** Tooltip text color 669 | @tooltip-color: @inverse; 670 | //** Tooltip background color 671 | @tooltip-bg: @brand-primary; 672 | @tooltip-opacity: 1; 673 | //** Tooltip zIndex 674 | @zindex-tooltip: 1070; 675 | 676 | //** Tooltip inverse text color 677 | @tooltip-inverse-color: @brand-primary; 678 | //** Tooltip inverse background color 679 | @tooltip-inverse-bg: mix(@brand-primary, white, 9%); 680 | 681 | //** Tooltip arrow width 682 | @tooltip-arrow-width: 9px; 683 | //** Tooltip arrow color 684 | @tooltip-arrow-color: @tooltip-bg; 685 | //** Tooltip inverse arrow color 686 | @tooltip-inverse-arrow-color: @tooltip-inverse-bg; 687 | 688 | 689 | 690 | 691 | //== Code 692 | // 693 | //## 694 | 695 | @code-color: #c7254e; 696 | @code-bg: #f9f2f4; 697 | 698 | @kbd-color: @inverse; 699 | @kbd-bg: @brand-primary; 700 | 701 | @pre-bg: @inverse; 702 | @pre-color: inherit; 703 | @pre-border-color: mix(@brand-primary, @inverse, 12%); 704 | @pre-scrollable-max-height: 340px; 705 | @pre-border-radius: @border-radius-large; 706 | 707 | 708 | //== Form states and alerts 709 | // 710 | //## 711 | 712 | //** Text muted color 713 | @text-muted: @gray-light; 714 | //** Abbreviations and acronyms border color 715 | @abbr-border-color: @gray-light; 716 | //** Headings small color 717 | @headings-small-color: mix(@brand-primary, @inverse, 12%); 718 | //** Blockquote small color 719 | @blockquote-small-color: inherit; 720 | //** Blockquote border color 721 | @blockquote-border-color: mix(@brand-primary, @inverse, 12%); 722 | //** Page header border color 723 | @page-header-border-color: mix(@brand-primary, @inverse, 12%); 724 | //** Width of horizontal description list titles 725 | @dl-horizontal-offset: @component-offset-horizontal; 726 | 727 | 728 | //== Miscellaneous 729 | // 730 | //## 731 | 732 | //** Hr border color 733 | @hr-border: mix(@brand-primary, @inverse, 63%); 734 | 735 | //** Horizontal forms & lists 736 | @component-offset-horizontal: 180px; 737 | -------------------------------------------------------------------------------- /seed/less/modules/m-button.less: -------------------------------------------------------------------------------- 1 | /** just for button **/ 2 | .btn { 3 | display: inline-block; 4 | line-height: 30px; 5 | padding: 0 15px; 6 | border-radius: 2px; 7 | background: #fff; 8 | border: 1px solid #e7eaec; 9 | min-width: 46px; 10 | color:#323c48; 11 | text-align: center; 12 | transition: all .15s ease; 13 | font-size: 13px; 14 | cursor: pointer; 15 | outline: none !important; 16 | ox-shadow: 0 1px 1px rgba(90,90,90,0.1); 17 | transition: all .25s ease; 18 | } 19 | .btn-sl{ 20 | padding: 0 8px; 21 | line-height: 22px; 22 | font-size: 12px; 23 | } 24 | .btn:hover { 25 | border-color: #d2d2d2; 26 | box-shadow: 0px 2px 5px rgba(0,0,0,.1); 27 | } 28 | .btn:disabled, 29 | .btn:disabled:hover{ 30 | background: #b4b4b4 !important; 31 | color:#fff; 32 | border-color: #ccc; 33 | box-shadow: none; 34 | cursor: not-allowed; 35 | } 36 | 37 | .submit-btn { 38 | margin-right: 6px; 39 | } 40 | .btn-primary, 41 | .submit-btn, 42 | .btn.active{ 43 | color:#fff; 44 | background: #00a8e6; 45 | border-color:#00a8e6; 46 | } 47 | .btn-primary:focus, 48 | .btn-primary:active, 49 | .submit-btn:focus, 50 | .submit-btn:active, 51 | .btn.active:focuss, 52 | .btn.active:active{ 53 | border-color:#009cd6; 54 | } 55 | .btn-primary:hover, 56 | .submit-btn:hover, 57 | .btn.active:hover{ 58 | background: #009cd6; 59 | border-color: #009cd6; 60 | } 61 | .btn-info{ 62 | color:#00a8e6; 63 | background: #fff; 64 | border-color:#00a8e6; 65 | } 66 | .btn-info:focus, 67 | .btn-info:active{ 68 | background: #009cd6; 69 | border-color: #009cd6; 70 | color:#fff; 71 | } 72 | .btn-info:hover{ 73 | background: #00a8e6; 74 | border-color:#00a8e6; 75 | color:#fff; 76 | } 77 | a.btn-info:hover { 78 | color: #fff; 79 | } 80 | 81 | 82 | .btn-warning{ 83 | color:#fff; 84 | background: #faa732; 85 | border-color:#faa732; 86 | } 87 | .btn-warning:focus, 88 | .btn-warning:active{ 89 | border-color:#dd942e; 90 | } 91 | .btn-warning:hover{ 92 | background: #dd942e; 93 | border-color: #dd942e; 94 | } 95 | 96 | .btn-danger{ 97 | color:#fff; 98 | background: #ea6153; 99 | border-color:#d14233; 100 | } 101 | .btn-danger:focus, 102 | .btn-danger:active{ 103 | border-color:#d14233; 104 | } 105 | .btn-danger:hover{ 106 | background: #dc5b4e; 107 | border-color: #bd2b41; 108 | } 109 | .btn-link{ 110 | line-height: 28px; 111 | padding: 0 15px; 112 | background-color: transparent; 113 | border:none; 114 | color:#00a8e6; 115 | } 116 | .btn-link:focus, 117 | .btn-link:active{ 118 | color:#005598; 119 | } 120 | .btn-link:hover{ 121 | color:#0077dd; 122 | border:0px; 123 | } 124 | .btn-lg{ 125 | line-height: 36px; 126 | padding: 0 30px; 127 | } 128 | .btn-sm{ 129 | line-height: 28px; 130 | padding: 0 15px; 131 | } 132 | 133 | .btn-icon{ 134 | position: relative; 135 | width: 32px; 136 | min-width: 32px; 137 | height: 32px; 138 | padding: 0; 139 | margin-right: 15px; 140 | text-align: center; 141 | } 142 | .btn.btn-icon .icon{ 143 | margin: 0; 144 | font-size: 0.9rem; 145 | } 146 | .btn-icon:hover .icon-tips-box{ 147 | display: inline-block; 148 | } 149 | .icon-tips-box{ 150 | z-index: 5; 151 | position: absolute; 152 | display: none; 153 | left:100%; 154 | top:50%; 155 | margin-top: -15px; 156 | min-width: 56px; 157 | height: 30px; 158 | line-height: 30px; 159 | margin-left: 10px; 160 | padding: 0 15px; 161 | border-radius: 3px; 162 | color:#f1f1f1; 163 | background: rgba(0,0,0,.8); 164 | background-color: #333; 165 | font-size: 12px; 166 | } 167 | .icon-tips-box:before{ 168 | content: ''; 169 | position: absolute; 170 | display: inline-block; 171 | top:50%; 172 | margin-top: -6px; 173 | left:-12px; 174 | border-width:6px; 175 | border-style: solid; 176 | border-color: transparent rgba(0,0,0,.8) transparent transparent ; 177 | } 178 | .btn-icon.left .icon-tips-box{ 179 | left:inherit; 180 | right: 100%; 181 | margin-right: 5px; 182 | } 183 | .btn-icon.left .icon-tips-box:before{ 184 | left:inherit; 185 | right:-12px; 186 | border-color: transparent transparent transparent rgba(0,0,0,.8) ; 187 | 188 | } 189 | .btn-group .btn, 190 | .btn-group .text{ 191 | float: left; 192 | margin-left: 0p; 193 | margin-right: -1px; 194 | } 195 | .btn-group .btn.active{ 196 | background: #00a8e6; 197 | border-color: #00a8e6; 198 | color:#fff; 199 | } 200 | .btn-group .btn.active:hover{ 201 | background: #009cd6; 202 | } 203 | .btn-group.hover-group{ 204 | padding-right: 10px; 205 | } 206 | .btn-group.hover-group .btn-primary{ 207 | opacity: 0; 208 | } 209 | .btn-group.hover-group:hover .btn-primary{ 210 | opacity: 1; 211 | } 212 | 213 | 214 | .btn .icon{ 215 | font-size: 16px; 216 | margin-right: 6px; 217 | } 218 | .btn-noborder { 219 | background: none; 220 | border: none 0; 221 | padding: 0 15px; 222 | } 223 | .btn-noborder:hover{ 224 | color:#333; 225 | } 226 | 227 | 228 | /*.btn.btn-default { 229 | background: #fff; 230 | color: #636365; 231 | border: 1px solid #D8DCE1; 232 | border-radius: 2px; 233 | line-height: 30px; 234 | padding: 0 10px; 235 | } 236 | 237 | 238 | .btn-noborder i { 239 | font-size: 0.85714285714286rem; 240 | border: 1px solid #707070; 241 | color: #707070; 242 | border-radius: 2px; 243 | padding: 1px 2px; 244 | background: #fff; 245 | } 246 | .btn-noborder:hover i { 247 | border: 1px solid #61bbf4; 248 | color: #61bbf4; 249 | } 250 | .btn-default:hover, 251 | .btn-default:focus, 252 | .btn-default:active, 253 | .btn-default.active, 254 | .open .dropdown-toggle.btn-default { 255 | color: #333333; 256 | background-color: #ebebeb; 257 | border-color: #adadad; 258 | } 259 | 260 | .btn-default:active, 261 | .btn-default.active, 262 | .open .dropdown-toggle.btn-default { 263 | background-image: none; 264 | } 265 | 266 | .btn-default.disabled, 267 | .btn-default[disabled], 268 | fieldset[disabled] .btn-default, 269 | .btn-default.disabled:hover, 270 | .btn-default[disabled]:hover, 271 | fieldset[disabled] .btn-default:hover, 272 | .btn-default.disabled:focus, 273 | .btn-default[disabled]:focus, 274 | fieldset[disabled] .btn-default:focus, 275 | .btn-default.disabled:active, 276 | .btn-default[disabled]:active, 277 | fieldset[disabled] .btn-default:active, 278 | .btn-default.disabled.active, 279 | .btn-default[disabled].active, 280 | fieldset[disabled] .btn-default.active { 281 | background-color: #ffffff; 282 | border-color: #cccccc; 283 | }*/ 284 | .btn-group, 285 | .btn-group-vertical { 286 | position: relative; 287 | display: inline-block; 288 | vertical-align: middle; 289 | } 290 | .btn-group > .btn, 291 | .btn-group-vertical > .btn { 292 | position: relative; 293 | float: left; 294 | } 295 | .btn-group > .btn:focus, 296 | .btn-group-vertical > .btn:focus { 297 | outline: none; 298 | } 299 | .btn-group .btn + .btn, 300 | .btn-group .btn + .btn-group, 301 | .btn-group .btn-group + .btn, 302 | .btn-group .btn-group + .btn-group { 303 | margin-left: -1px; 304 | } 305 | .btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { 306 | border-radius: 0; 307 | } 308 | .btn-group > .btn:first-child { 309 | margin-left: 0; 310 | } 311 | .btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { 312 | border-top-right-radius: 0; 313 | border-bottom-right-radius: 0; 314 | } 315 | .btn-group > .btn:last-child:not(:first-child), 316 | .btn-group > .dropdown-toggle:not(:first-child) { 317 | border-top-left-radius: 0; 318 | border-bottom-left-radius: 0; 319 | } 320 | .btn-group > .btn-group { 321 | float: left; 322 | } 323 | .btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { 324 | border-radius: 0; 325 | } 326 | .btn-group > .btn-group:first-child > .btn:last-child, 327 | .btn-group > .btn-group:first-child > .dropdown-toggle { 328 | border-top-right-radius: 0; 329 | border-bottom-right-radius: 0; 330 | } 331 | .btn-group > .btn-group:last-child > .btn:first-child { 332 | border-top-left-radius: 0; 333 | border-bottom-left-radius: 0; 334 | } 335 | .btn-group .dropdown-toggle:active, 336 | .btn-group.open .dropdown-toggle { 337 | outline: 0; 338 | } 339 | .btn-group > .btn + .dropdown-toggle { 340 | padding-right: 8px; 341 | padding-left: 8px; 342 | } 343 | .btn-group > .btn-lg + .dropdown-toggle { 344 | padding-right: 12px; 345 | padding-left: 12px; 346 | } 347 | .btn-group.open .dropdown-toggle { 348 | -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); 349 | box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); 350 | } 351 | .btn-group.open .dropdown-toggle.btn-link { 352 | -webkit-box-shadow: none; 353 | box-shadow: none; 354 | } 355 | 356 | .btn-circle{ 357 | position: relative; 358 | width: 60px; 359 | height: 60px; 360 | background: #fff; 361 | border-radius: 30px; 362 | box-shadow: 0px 2px 5px rgba(0,0,0,.05); 363 | line-height: 60px; 364 | font-size: 18px; 365 | color:#999; 366 | } 367 | .btn-circle:hover{ 368 | box-shadow: 0px 5px 12px rgba(0,0,0,.1); 369 | } 370 | .btn-circle:hover:after{ 371 | content: attr(data-tooltip); 372 | position: absolute; 373 | top:70px; 374 | width: 80px; 375 | left:-10px; 376 | background: #333; 377 | background: rgba(0,0,0,.8); 378 | border-radius: 2px; 379 | color: #fff; 380 | padding: 0 10px; 381 | font-size: 12px; 382 | line-height: 25px; 383 | } 384 | -------------------------------------------------------------------------------- /seed/less/modules/m-icon.less: -------------------------------------------------------------------------------- 1 | /** icon font modules 2 | ** font resource http://themify.me/themify-icons 3 | **/ 4 | @font-face { 5 | font-family: 'themify'; 6 | src:url('../fonts/themify.eot?-fvbane'); 7 | src:url('../fonts/themify.eot?#iefix-fvbane') format('embedded-opentype'), 8 | url('../fonts/themify.woff?-fvbane') format('woff'), 9 | url('../fonts/themify.ttf?-fvbane') format('truetype'), 10 | url('../fonts/themify.svg?-fvbane#themify') format('svg'); 11 | font-weight: normal; 12 | font-style: normal; 13 | } 14 | 15 | [class^="icon-"], [class*="icon-"] { 16 | font-family: 'themify'; 17 | speak: none; 18 | font-style: normal; 19 | font-weight: normal; 20 | font-variant: normal; 21 | text-transform: none; 22 | line-height: 1; 23 | /* Better Font Rendering =========== */ 24 | -webkit-font-smoothing: antialiased; 25 | -moz-osx-font-smoothing: grayscale; 26 | } 27 | 28 | .ti-wand:before { 29 | content: "\e600"; 30 | } 31 | .ti-volume:before { 32 | content: "\e601"; 33 | } 34 | .icon-user:before { 35 | content: "\e602"; 36 | } 37 | .ti-unlock:before { 38 | content: "\e603"; 39 | } 40 | .ti-unlink:before { 41 | content: "\e604"; 42 | } 43 | .icon-trash:before { 44 | content: "\e605"; 45 | } 46 | .ti-thought:before { 47 | content: "\e606"; 48 | } 49 | .ti-target:before { 50 | content: "\e607"; 51 | } 52 | .ti-tag:before { 53 | content: "\e608"; 54 | } 55 | .ti-tablet:before { 56 | content: "\e609"; 57 | } 58 | .ti-star:before { 59 | content: "\e60a"; 60 | } 61 | .ti-spray:before { 62 | content: "\e60b"; 63 | } 64 | .ti-signal:before { 65 | content: "\e60c"; 66 | } 67 | .ti-shopping-cart:before { 68 | content: "\e60d"; 69 | } 70 | .ti-shopping-cart-full:before { 71 | content: "\e60e"; 72 | } 73 | .ti-settings:before { 74 | content: "\e60f"; 75 | } 76 | .ti-search:before { 77 | content: "\e610"; 78 | } 79 | .ti-zoom-in:before { 80 | content: "\e611"; 81 | } 82 | .ti-zoom-out:before { 83 | content: "\e612"; 84 | } 85 | .ti-cut:before { 86 | content: "\e613"; 87 | } 88 | .ti-ruler:before { 89 | content: "\e614"; 90 | } 91 | .ti-ruler-pencil:before { 92 | content: "\e615"; 93 | } 94 | .ti-ruler-alt:before { 95 | content: "\e616"; 96 | } 97 | .ti-bookmark:before { 98 | content: "\e617"; 99 | } 100 | .ti-bookmark-alt:before { 101 | content: "\e618"; 102 | } 103 | .ti-reload:before { 104 | content: "\e619"; 105 | } 106 | .ti-plus:before { 107 | content: "\e61a"; 108 | } 109 | .ti-pin:before { 110 | content: "\e61b"; 111 | } 112 | .ti-pencil:before { 113 | content: "\e61c"; 114 | } 115 | .ti-pencil-alt:before { 116 | content: "\e61d"; 117 | } 118 | .ti-paint-roller:before { 119 | content: "\e61e"; 120 | } 121 | .ti-paint-bucket:before { 122 | content: "\e61f"; 123 | } 124 | .ti-na:before { 125 | content: "\e620"; 126 | } 127 | .ti-mobile:before { 128 | content: "\e621"; 129 | } 130 | .ti-minus:before { 131 | content: "\e622"; 132 | } 133 | .ti-medall:before { 134 | content: "\e623"; 135 | } 136 | .ti-medall-alt:before { 137 | content: "\e624"; 138 | } 139 | .ti-marker:before { 140 | content: "\e625"; 141 | } 142 | .ti-marker-alt:before { 143 | content: "\e626"; 144 | } 145 | .ti-arrow-up:before { 146 | content: "\e627"; 147 | } 148 | .ti-arrow-right:before { 149 | content: "\e628"; 150 | } 151 | .ti-arrow-left:before { 152 | content: "\e629"; 153 | } 154 | .ti-arrow-down:before { 155 | content: "\e62a"; 156 | } 157 | .ti-lock:before { 158 | content: "\e62b"; 159 | } 160 | .ti-location-arrow:before { 161 | content: "\e62c"; 162 | } 163 | .icon-link:before { 164 | content: "\e62d"; 165 | } 166 | .ti-layout:before { 167 | content: "\e62e"; 168 | } 169 | .ti-layers:before { 170 | content: "\e62f"; 171 | } 172 | .ti-layers-alt:before { 173 | content: "\e630"; 174 | } 175 | .ti-key:before { 176 | content: "\e631"; 177 | } 178 | .ti-import:before { 179 | content: "\e632"; 180 | } 181 | .ti-image:before { 182 | content: "\e633"; 183 | } 184 | .ti-heart:before { 185 | content: "\e634"; 186 | } 187 | .ti-heart-broken:before { 188 | content: "\e635"; 189 | } 190 | .ti-hand-stop:before { 191 | content: "\e636"; 192 | } 193 | .ti-hand-open:before { 194 | content: "\e637"; 195 | } 196 | .ti-hand-drag:before { 197 | content: "\e638"; 198 | } 199 | .ti-folder:before { 200 | content: "\e639"; 201 | } 202 | .ti-flag:before { 203 | content: "\e63a"; 204 | } 205 | .ti-flag-alt:before { 206 | content: "\e63b"; 207 | } 208 | .ti-flag-alt-2:before { 209 | content: "\e63c"; 210 | } 211 | .ti-eye:before { 212 | content: "\e63d"; 213 | } 214 | .ti-export:before { 215 | content: "\e63e"; 216 | } 217 | .ti-exchange-vertical:before { 218 | content: "\e63f"; 219 | } 220 | .ti-desktop:before { 221 | content: "\e640"; 222 | } 223 | .ti-cup:before { 224 | content: "\e641"; 225 | } 226 | .ti-crown:before { 227 | content: "\e642"; 228 | } 229 | .ti-comments:before { 230 | content: "\e643"; 231 | } 232 | .ti-comment:before { 233 | content: "\e644"; 234 | } 235 | .ti-comment-alt:before { 236 | content: "\e645"; 237 | } 238 | .ti-close:before { 239 | content: "\e646"; 240 | } 241 | .ti-clip:before { 242 | content: "\e647"; 243 | } 244 | .ti-angle-up:before { 245 | content: "\e648"; 246 | } 247 | .ti-angle-right:before { 248 | content: "\e649"; 249 | } 250 | .ti-angle-left:before { 251 | content: "\e64a"; 252 | } 253 | .ti-angle-down:before { 254 | content: "\e64b"; 255 | } 256 | .ti-check:before { 257 | content: "\e64c"; 258 | } 259 | .ti-check-box:before { 260 | content: "\e64d"; 261 | } 262 | .ti-camera:before { 263 | content: "\e64e"; 264 | } 265 | .ti-announcement:before { 266 | content: "\e64f"; 267 | } 268 | .ti-brush:before { 269 | content: "\e650"; 270 | } 271 | .ti-briefcase:before { 272 | content: "\e651"; 273 | } 274 | .ti-bolt:before { 275 | content: "\e652"; 276 | } 277 | .ti-bolt-alt:before { 278 | content: "\e653"; 279 | } 280 | .ti-blackboard:before { 281 | content: "\e654"; 282 | } 283 | .ti-bag:before { 284 | content: "\e655"; 285 | } 286 | .ti-move:before { 287 | content: "\e656"; 288 | } 289 | .ti-arrows-vertical:before { 290 | content: "\e657"; 291 | } 292 | .ti-arrows-horizontal:before { 293 | content: "\e658"; 294 | } 295 | .ti-fullscreen:before { 296 | content: "\e659"; 297 | } 298 | .ti-arrow-top-right:before { 299 | content: "\e65a"; 300 | } 301 | .ti-arrow-top-left:before { 302 | content: "\e65b"; 303 | } 304 | .ti-arrow-circle-up:before { 305 | content: "\e65c"; 306 | } 307 | .ti-arrow-circle-right:before { 308 | content: "\e65d"; 309 | } 310 | .ti-arrow-circle-left:before { 311 | content: "\e65e"; 312 | } 313 | .ti-arrow-circle-down:before { 314 | content: "\e65f"; 315 | } 316 | .ti-angle-double-up:before { 317 | content: "\e660"; 318 | } 319 | .ti-angle-double-right:before { 320 | content: "\e661"; 321 | } 322 | .ti-angle-double-left:before { 323 | content: "\e662"; 324 | } 325 | .ti-angle-double-down:before { 326 | content: "\e663"; 327 | } 328 | .ti-zip:before { 329 | content: "\e664"; 330 | } 331 | .ti-world:before { 332 | content: "\e665"; 333 | } 334 | .ti-wheelchair:before { 335 | content: "\e666"; 336 | } 337 | .ti-view-list:before { 338 | content: "\e667"; 339 | } 340 | .ti-view-list-alt:before { 341 | content: "\e668"; 342 | } 343 | .ti-view-grid:before { 344 | content: "\e669"; 345 | } 346 | .ti-uppercase:before { 347 | content: "\e66a"; 348 | } 349 | .ti-upload:before { 350 | content: "\e66b"; 351 | } 352 | .ti-underline:before { 353 | content: "\e66c"; 354 | } 355 | .ti-truck:before { 356 | content: "\e66d"; 357 | } 358 | .ti-timer:before { 359 | content: "\e66e"; 360 | } 361 | .ti-ticket:before { 362 | content: "\e66f"; 363 | } 364 | .ti-thumb-up:before { 365 | content: "\e670"; 366 | } 367 | .ti-thumb-down:before { 368 | content: "\e671"; 369 | } 370 | .ti-text:before { 371 | content: "\e672"; 372 | } 373 | .ti-stats-up:before { 374 | content: "\e673"; 375 | } 376 | .ti-stats-down:before { 377 | content: "\e674"; 378 | } 379 | .ti-split-v:before { 380 | content: "\e675"; 381 | } 382 | .ti-split-h:before { 383 | content: "\e676"; 384 | } 385 | .ti-smallcap:before { 386 | content: "\e677"; 387 | } 388 | .ti-shine:before { 389 | content: "\e678"; 390 | } 391 | .ti-shift-right:before { 392 | content: "\e679"; 393 | } 394 | .ti-shift-left:before { 395 | content: "\e67a"; 396 | } 397 | .ti-shield:before { 398 | content: "\e67b"; 399 | } 400 | .ti-notepad:before { 401 | content: "\e67c"; 402 | } 403 | .ti-server:before { 404 | content: "\e67d"; 405 | } 406 | .ti-quote-right:before { 407 | content: "\e67e"; 408 | } 409 | .ti-quote-left:before { 410 | content: "\e67f"; 411 | } 412 | .ti-pulse:before { 413 | content: "\e680"; 414 | } 415 | .ti-printer:before { 416 | content: "\e681"; 417 | } 418 | .ti-power-off:before { 419 | content: "\e682"; 420 | } 421 | .ti-plug:before { 422 | content: "\e683"; 423 | } 424 | .ti-pie-chart:before { 425 | content: "\e684"; 426 | } 427 | .ti-paragraph:before { 428 | content: "\e685"; 429 | } 430 | .ti-panel:before { 431 | content: "\e686"; 432 | } 433 | .ti-package:before { 434 | content: "\e687"; 435 | } 436 | .ti-music:before { 437 | content: "\e688"; 438 | } 439 | .ti-music-alt:before { 440 | content: "\e689"; 441 | } 442 | .ti-mouse:before { 443 | content: "\e68a"; 444 | } 445 | .ti-mouse-alt:before { 446 | content: "\e68b"; 447 | } 448 | .ti-money:before { 449 | content: "\e68c"; 450 | } 451 | .ti-microphone:before { 452 | content: "\e68d"; 453 | } 454 | .ti-menu:before { 455 | content: "\e68e"; 456 | } 457 | .ti-menu-alt:before { 458 | content: "\e68f"; 459 | } 460 | .ti-map:before { 461 | content: "\e690"; 462 | } 463 | .ti-map-alt:before { 464 | content: "\e691"; 465 | } 466 | .ti-loop:before { 467 | content: "\e692"; 468 | } 469 | .ti-location-pin:before { 470 | content: "\e693"; 471 | } 472 | .ti-list:before { 473 | content: "\e694"; 474 | } 475 | .ti-light-bulb:before { 476 | content: "\e695"; 477 | } 478 | .ti-Italic:before { 479 | content: "\e696"; 480 | } 481 | .ti-info:before { 482 | content: "\e697"; 483 | } 484 | .ti-infinite:before { 485 | content: "\e698"; 486 | } 487 | .ti-id-badge:before { 488 | content: "\e699"; 489 | } 490 | .ti-hummer:before { 491 | content: "\e69a"; 492 | } 493 | .ti-home:before { 494 | content: "\e69b"; 495 | } 496 | .ti-help:before { 497 | content: "\e69c"; 498 | } 499 | .ti-headphone:before { 500 | content: "\e69d"; 501 | } 502 | .ti-harddrives:before { 503 | content: "\e69e"; 504 | } 505 | .ti-harddrive:before { 506 | content: "\e69f"; 507 | } 508 | .ti-gift:before { 509 | content: "\e6a0"; 510 | } 511 | .ti-game:before { 512 | content: "\e6a1"; 513 | } 514 | .ti-filter:before { 515 | content: "\e6a2"; 516 | } 517 | .ti-files:before { 518 | content: "\e6a3"; 519 | } 520 | .ti-file:before { 521 | content: "\e6a4"; 522 | } 523 | .ti-eraser:before { 524 | content: "\e6a5"; 525 | } 526 | .ti-envelope:before { 527 | content: "\e6a6"; 528 | } 529 | .ti-download:before { 530 | content: "\e6a7"; 531 | } 532 | .ti-direction:before { 533 | content: "\e6a8"; 534 | } 535 | .ti-direction-alt:before { 536 | content: "\e6a9"; 537 | } 538 | .ti-dashboard:before { 539 | content: "\e6aa"; 540 | } 541 | .ti-control-stop:before { 542 | content: "\e6ab"; 543 | } 544 | .ti-control-shuffle:before { 545 | content: "\e6ac"; 546 | } 547 | .ti-control-play:before { 548 | content: "\e6ad"; 549 | } 550 | .ti-control-pause:before { 551 | content: "\e6ae"; 552 | } 553 | .ti-control-forward:before { 554 | content: "\e6af"; 555 | } 556 | .ti-control-backward:before { 557 | content: "\e6b0"; 558 | } 559 | .ti-cloud:before { 560 | content: "\e6b1"; 561 | } 562 | .ti-cloud-up:before { 563 | content: "\e6b2"; 564 | } 565 | .ti-cloud-down:before { 566 | content: "\e6b3"; 567 | } 568 | .ti-clipboard:before { 569 | content: "\e6b4"; 570 | } 571 | .ti-car:before { 572 | content: "\e6b5"; 573 | } 574 | .ti-calendar:before { 575 | content: "\e6b6"; 576 | } 577 | .ti-book:before { 578 | content: "\e6b7"; 579 | } 580 | .ti-bell:before { 581 | content: "\e6b8"; 582 | } 583 | .ti-basketball:before { 584 | content: "\e6b9"; 585 | } 586 | .ti-bar-chart:before { 587 | content: "\e6ba"; 588 | } 589 | .ti-bar-chart-alt:before { 590 | content: "\e6bb"; 591 | } 592 | .ti-back-right:before { 593 | content: "\e6bc"; 594 | } 595 | .ti-back-left:before { 596 | content: "\e6bd"; 597 | } 598 | .ti-arrows-corner:before { 599 | content: "\e6be"; 600 | } 601 | .ti-archive:before { 602 | content: "\e6bf"; 603 | } 604 | .ti-anchor:before { 605 | content: "\e6c0"; 606 | } 607 | .ti-align-right:before { 608 | content: "\e6c1"; 609 | } 610 | .ti-align-left:before { 611 | content: "\e6c2"; 612 | } 613 | .ti-align-justify:before { 614 | content: "\e6c3"; 615 | } 616 | .ti-align-center:before { 617 | content: "\e6c4"; 618 | } 619 | .ti-alert:before { 620 | content: "\e6c5"; 621 | } 622 | .ti-alarm-clock:before { 623 | content: "\e6c6"; 624 | } 625 | .ti-agenda:before { 626 | content: "\e6c7"; 627 | } 628 | .ti-write:before { 629 | content: "\e6c8"; 630 | } 631 | .ti-window:before { 632 | content: "\e6c9"; 633 | } 634 | .ti-widgetized:before { 635 | content: "\e6ca"; 636 | } 637 | .ti-widget:before { 638 | content: "\e6cb"; 639 | } 640 | .ti-widget-alt:before { 641 | content: "\e6cc"; 642 | } 643 | .ti-wallet:before { 644 | content: "\e6cd"; 645 | } 646 | .ti-video-clapper:before { 647 | content: "\e6ce"; 648 | } 649 | .ti-video-camera:before { 650 | content: "\e6cf"; 651 | } 652 | .ti-vector:before { 653 | content: "\e6d0"; 654 | } 655 | .ti-themify-logo:before { 656 | content: "\e6d1"; 657 | } 658 | .ti-themify-favicon:before { 659 | content: "\e6d2"; 660 | } 661 | .ti-themify-favicon-alt:before { 662 | content: "\e6d3"; 663 | } 664 | .ti-support:before { 665 | content: "\e6d4"; 666 | } 667 | .ti-stamp:before { 668 | content: "\e6d5"; 669 | } 670 | .ti-split-v-alt:before { 671 | content: "\e6d6"; 672 | } 673 | .ti-slice:before { 674 | content: "\e6d7"; 675 | } 676 | .ti-shortcode:before { 677 | content: "\e6d8"; 678 | } 679 | .ti-shift-right-alt:before { 680 | content: "\e6d9"; 681 | } 682 | .ti-shift-left-alt:before { 683 | content: "\e6da"; 684 | } 685 | .ti-ruler-alt-2:before { 686 | content: "\e6db"; 687 | } 688 | .ti-receipt:before { 689 | content: "\e6dc"; 690 | } 691 | .ti-pin2:before { 692 | content: "\e6dd"; 693 | } 694 | .ti-pin-alt:before { 695 | content: "\e6de"; 696 | } 697 | .ti-pencil-alt2:before { 698 | content: "\e6df"; 699 | } 700 | .ti-palette:before { 701 | content: "\e6e0"; 702 | } 703 | .ti-more:before { 704 | content: "\e6e1"; 705 | } 706 | .ti-more-alt:before { 707 | content: "\e6e2"; 708 | } 709 | .ti-microphone-alt:before { 710 | content: "\e6e3"; 711 | } 712 | .ti-magnet:before { 713 | content: "\e6e4"; 714 | } 715 | .ti-line-double:before { 716 | content: "\e6e5"; 717 | } 718 | .ti-line-dotted:before { 719 | content: "\e6e6"; 720 | } 721 | .ti-line-dashed:before { 722 | content: "\e6e7"; 723 | } 724 | .ti-layout-width-full:before { 725 | content: "\e6e8"; 726 | } 727 | .ti-layout-width-default:before { 728 | content: "\e6e9"; 729 | } 730 | .ti-layout-width-default-alt:before { 731 | content: "\e6ea"; 732 | } 733 | .ti-layout-tab:before { 734 | content: "\e6eb"; 735 | } 736 | .ti-layout-tab-window:before { 737 | content: "\e6ec"; 738 | } 739 | .ti-layout-tab-v:before { 740 | content: "\e6ed"; 741 | } 742 | .ti-layout-tab-min:before { 743 | content: "\e6ee"; 744 | } 745 | .ti-layout-slider:before { 746 | content: "\e6ef"; 747 | } 748 | .ti-layout-slider-alt:before { 749 | content: "\e6f0"; 750 | } 751 | .ti-layout-sidebar-right:before { 752 | content: "\e6f1"; 753 | } 754 | .ti-layout-sidebar-none:before { 755 | content: "\e6f2"; 756 | } 757 | .ti-layout-sidebar-left:before { 758 | content: "\e6f3"; 759 | } 760 | .ti-layout-placeholder:before { 761 | content: "\e6f4"; 762 | } 763 | .ti-layout-menu:before { 764 | content: "\e6f5"; 765 | } 766 | .ti-layout-menu-v:before { 767 | content: "\e6f6"; 768 | } 769 | .ti-layout-menu-separated:before { 770 | content: "\e6f7"; 771 | } 772 | .ti-layout-menu-full:before { 773 | content: "\e6f8"; 774 | } 775 | .ti-layout-media-right-alt:before { 776 | content: "\e6f9"; 777 | } 778 | .ti-layout-media-right:before { 779 | content: "\e6fa"; 780 | } 781 | .ti-layout-media-overlay:before { 782 | content: "\e6fb"; 783 | } 784 | .ti-layout-media-overlay-alt:before { 785 | content: "\e6fc"; 786 | } 787 | .ti-layout-media-overlay-alt-2:before { 788 | content: "\e6fd"; 789 | } 790 | .ti-layout-media-left-alt:before { 791 | content: "\e6fe"; 792 | } 793 | .ti-layout-media-left:before { 794 | content: "\e6ff"; 795 | } 796 | .ti-layout-media-center-alt:before { 797 | content: "\e700"; 798 | } 799 | .ti-layout-media-center:before { 800 | content: "\e701"; 801 | } 802 | .ti-layout-list-thumb:before { 803 | content: "\e702"; 804 | } 805 | .ti-layout-list-thumb-alt:before { 806 | content: "\e703"; 807 | } 808 | .ti-layout-list-post:before { 809 | content: "\e704"; 810 | } 811 | .ti-layout-list-large-image:before { 812 | content: "\e705"; 813 | } 814 | .ti-layout-line-solid:before { 815 | content: "\e706"; 816 | } 817 | .ti-layout-grid4:before { 818 | content: "\e707"; 819 | } 820 | .ti-layout-grid3:before { 821 | content: "\e708"; 822 | } 823 | .ti-layout-grid2:before { 824 | content: "\e709"; 825 | } 826 | .ti-layout-grid2-thumb:before { 827 | content: "\e70a"; 828 | } 829 | .ti-layout-cta-right:before { 830 | content: "\e70b"; 831 | } 832 | .ti-layout-cta-left:before { 833 | content: "\e70c"; 834 | } 835 | .ti-layout-cta-center:before { 836 | content: "\e70d"; 837 | } 838 | .ti-layout-cta-btn-right:before { 839 | content: "\e70e"; 840 | } 841 | .ti-layout-cta-btn-left:before { 842 | content: "\e70f"; 843 | } 844 | .ti-layout-column4:before { 845 | content: "\e710"; 846 | } 847 | .ti-layout-column3:before { 848 | content: "\e711"; 849 | } 850 | .ti-layout-column2:before { 851 | content: "\e712"; 852 | } 853 | .ti-layout-accordion-separated:before { 854 | content: "\e713"; 855 | } 856 | .ti-layout-accordion-merged:before { 857 | content: "\e714"; 858 | } 859 | .ti-layout-accordion-list:before { 860 | content: "\e715"; 861 | } 862 | .ti-ink-pen:before { 863 | content: "\e716"; 864 | } 865 | .ti-info-alt:before { 866 | content: "\e717"; 867 | } 868 | .ti-help-alt:before { 869 | content: "\e718"; 870 | } 871 | .ti-headphone-alt:before { 872 | content: "\e719"; 873 | } 874 | .ti-hand-point-up:before { 875 | content: "\e71a"; 876 | } 877 | .ti-hand-point-right:before { 878 | content: "\e71b"; 879 | } 880 | .ti-hand-point-left:before { 881 | content: "\e71c"; 882 | } 883 | .ti-hand-point-down:before { 884 | content: "\e71d"; 885 | } 886 | .ti-gallery:before { 887 | content: "\e71e"; 888 | } 889 | .ti-face-smile:before { 890 | content: "\e71f"; 891 | } 892 | .ti-face-sad:before { 893 | content: "\e720"; 894 | } 895 | .ti-credit-card:before { 896 | content: "\e721"; 897 | } 898 | .ti-control-skip-forward:before { 899 | content: "\e722"; 900 | } 901 | .ti-control-skip-backward:before { 902 | content: "\e723"; 903 | } 904 | .ti-control-record:before { 905 | content: "\e724"; 906 | } 907 | .ti-control-eject:before { 908 | content: "\e725"; 909 | } 910 | .ti-comments-smiley:before { 911 | content: "\e726"; 912 | } 913 | .ti-brush-alt:before { 914 | content: "\e727"; 915 | } 916 | .ti-youtube:before { 917 | content: "\e728"; 918 | } 919 | .ti-vimeo:before { 920 | content: "\e729"; 921 | } 922 | .ti-twitter:before { 923 | content: "\e72a"; 924 | } 925 | .ti-time:before { 926 | content: "\e72b"; 927 | } 928 | .ti-tumblr:before { 929 | content: "\e72c"; 930 | } 931 | .ti-skype:before { 932 | content: "\e72d"; 933 | } 934 | .ti-share:before { 935 | content: "\e72e"; 936 | } 937 | .ti-share-alt:before { 938 | content: "\e72f"; 939 | } 940 | .ti-rocket:before { 941 | content: "\e730"; 942 | } 943 | .ti-pinterest:before { 944 | content: "\e731"; 945 | } 946 | .ti-new-window:before { 947 | content: "\e732"; 948 | } 949 | .ti-microsoft:before { 950 | content: "\e733"; 951 | } 952 | .ti-list-ol:before { 953 | content: "\e734"; 954 | } 955 | .ti-linkedin:before { 956 | content: "\e735"; 957 | } 958 | .ti-layout-sidebar-2:before { 959 | content: "\e736"; 960 | } 961 | .ti-layout-grid4-alt:before { 962 | content: "\e737"; 963 | } 964 | .ti-layout-grid3-alt:before { 965 | content: "\e738"; 966 | } 967 | .ti-layout-grid2-alt:before { 968 | content: "\e739"; 969 | } 970 | .ti-layout-column4-alt:before { 971 | content: "\e73a"; 972 | } 973 | .ti-layout-column3-alt:before { 974 | content: "\e73b"; 975 | } 976 | .ti-layout-column2-alt:before { 977 | content: "\e73c"; 978 | } 979 | .ti-instagram:before { 980 | content: "\e73d"; 981 | } 982 | .ti-google:before { 983 | content: "\e73e"; 984 | } 985 | .icon-github:before { 986 | content: "\e73f"; 987 | } 988 | .ti-flickr:before { 989 | content: "\e740"; 990 | } 991 | .ti-facebook:before { 992 | content: "\e741"; 993 | } 994 | .ti-dropbox:before { 995 | content: "\e742"; 996 | } 997 | .ti-dribbble:before { 998 | content: "\e743"; 999 | } 1000 | .ti-apple:before { 1001 | content: "\e744"; 1002 | } 1003 | .ti-android:before { 1004 | content: "\e745"; 1005 | } 1006 | .icon-save:before { 1007 | content: "\e746"; 1008 | } 1009 | .ti-save-alt:before { 1010 | content: "\e747"; 1011 | } 1012 | .ti-yahoo:before { 1013 | content: "\e748"; 1014 | } 1015 | .ti-wordpress:before { 1016 | content: "\e749"; 1017 | } 1018 | .ti-vimeo-alt:before { 1019 | content: "\e74a"; 1020 | } 1021 | .ti-twitter-alt:before { 1022 | content: "\e74b"; 1023 | } 1024 | .ti-tumblr-alt:before { 1025 | content: "\e74c"; 1026 | } 1027 | .ti-trello:before { 1028 | content: "\e74d"; 1029 | } 1030 | .ti-stack-overflow:before { 1031 | content: "\e74e"; 1032 | } 1033 | .ti-soundcloud:before { 1034 | content: "\e74f"; 1035 | } 1036 | .ti-sharethis:before { 1037 | content: "\e750"; 1038 | } 1039 | .ti-sharethis-alt:before { 1040 | content: "\e751"; 1041 | } 1042 | .ti-reddit:before { 1043 | content: "\e752"; 1044 | } 1045 | .ti-pinterest-alt:before { 1046 | content: "\e753"; 1047 | } 1048 | .ti-microsoft-alt:before { 1049 | content: "\e754"; 1050 | } 1051 | .ti-linux:before { 1052 | content: "\e755"; 1053 | } 1054 | .ti-jsfiddle:before { 1055 | content: "\e756"; 1056 | } 1057 | .ti-joomla:before { 1058 | content: "\e757"; 1059 | } 1060 | .ti-html5:before { 1061 | content: "\e758"; 1062 | } 1063 | .ti-flickr-alt:before { 1064 | content: "\e759"; 1065 | } 1066 | .ti-email:before { 1067 | content: "\e75a"; 1068 | } 1069 | .ti-drupal:before { 1070 | content: "\e75b"; 1071 | } 1072 | .ti-dropbox-alt:before { 1073 | content: "\e75c"; 1074 | } 1075 | .ti-css3:before { 1076 | content: "\e75d"; 1077 | } 1078 | .ti-rss:before { 1079 | content: "\e75e"; 1080 | } 1081 | .ti-rss-alt:before { 1082 | content: "\e75f"; 1083 | } 1084 | -------------------------------------------------------------------------------- /seed/less/modules/m-layout.less: -------------------------------------------------------------------------------- 1 | /** layout **/ 2 | 3 | .nav { 4 | position: fixed; 5 | top: 0; 6 | left: 0; 7 | right: 0; 8 | bottom: 0; 9 | z-index: 5; 10 | height: 70px; 11 | background: #fff; 12 | margin-bottom: 0; 13 | font-size: 1.5rem; 14 | line-height: 70px; 15 | box-shadow: 0px 1px 3px -1px rgba(0, 0, 0, 0.1); 16 | opacity: .95; 17 | } 18 | 19 | .nav .container { 20 | position: relative; 21 | width: 1170px; 22 | margin: 0 auto; 23 | } 24 | 25 | .nav-logo { 26 | display: inline-block; 27 | width: 75px; 28 | height: 45px; 29 | background-image: url(data:image/png;base64,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); 30 | background-size: cover; 31 | vertical-align: middle; 32 | } 33 | 34 | .nav-title { 35 | position: absolute; 36 | top: 45px; 37 | left: 30px; 38 | font-size: 16px; 39 | font-weight: 100; 40 | text-transform: uppercase; 41 | color: #fff; 42 | } 43 | 44 | .nav-list { 45 | float: right; 46 | z-index: 100; 47 | height: 40px; 48 | line-height: 40px; 49 | margin-top: 15px; 50 | margin-left: 2rem; 51 | padding-right: 2.5rem; 52 | transition: all .25s ease; 53 | text-align: right; 54 | } 55 | 56 | 57 | .nav-list a { 58 | text-decoration: none; 59 | font-size: 14px; 60 | display: inline-block; 61 | padding: 0 1rem; 62 | overflow: hidden; 63 | white-space: nowrap; 64 | text-overflow: ellipsis; 65 | transition: all .25s ease; 66 | color: #444; 67 | } 68 | 69 | .nav-list:hover a { 70 | opacity: 1; 71 | color:#111; 72 | } 73 | .nav-list a.active{ 74 | color:#000; 75 | } 76 | aside{ 77 | float: left; 78 | position: relative; 79 | width: 220px; 80 | padding: 80px 15px 40px 20px; 81 | background: #fff; 82 | li{ 83 | margin-bottom: 5px; 84 | } 85 | a{ 86 | display: inline-block; 87 | line-height: 30px; 88 | color: #999; 89 | border-left: 3px solid #fff; 90 | padding-left: 10px; 91 | &.active{ 92 | color: @peter-river; 93 | } 94 | } 95 | 96 | } 97 | 98 | 99 | .main{ 100 | margin-left: 240px; 101 | max-width: 900px; 102 | min-height: 400px; 103 | padding: 80px 20px; 104 | } 105 | 106 | body.loading{ 107 | background: url(../img/article-theme.jpg) no-repeat center 120px; 108 | } 109 | 110 | 111 | .ft{ 112 | margin-left: 240px; 113 | max-width: 900px; 114 | padding-top: 40px; 115 | padding-bottom: 20px; 116 | text-align: center; 117 | font-size: 13px; 118 | color: #999; 119 | } -------------------------------------------------------------------------------- /seed/less/modules/m-pagination.less: -------------------------------------------------------------------------------- 1 | .m-pagination{ 2 | position: relative; 3 | text-align: center; 4 | margin-top: 20px; 5 | } 6 | 7 | .m-pagination li,.m-pagination li a{ 8 | display: inline-block; 9 | width:34px; 10 | height: 34px; 11 | line-height: 32px; 12 | background: #fff; 13 | color:#313c48; 14 | 15 | } 16 | .m-pagination li{ 17 | margin-left: 5px; 18 | } 19 | .m-pagination li a{ 20 | border:1px solid #e6eaed; 21 | border-radius: 2px; 22 | } 23 | .m-pagination li a:hover{ 24 | border-color: #00a8e6; 25 | color:#00a8e6; 26 | } 27 | .m-pagination li a.active, 28 | .m-pagination li.active a{ 29 | background:#00a8e6; 30 | border-color: #00a8e6; 31 | color:#fff; 32 | } 33 | 34 | 35 | .m-pagination li a.disabled,.m-pagination li.disabled a{ 36 | background: #b4b4b4; 37 | border-color: #b4b4b4; 38 | color: #fff; 39 | cursor: not-allowed; 40 | } 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /seed/less/modules/m-table.less: -------------------------------------------------------------------------------- 1 | .m-table-label { 2 | margin-bottom: 24px; 3 | border-bottom:1px solid #ddd; 4 | line-height: 49px; 5 | color:#313c48; 6 | } 7 | .m-table thead th,.m-table tbody td { 8 | padding:10px 14px; 9 | border-bottom: 1px solid #d9dde3; 10 | border-collapse: collapse; 11 | } 12 | .m-table { 13 | width:100%; 14 | text-align: left; 15 | line-height: 100%; 16 | thead { 17 | background: #fff; 18 | border-bottom: 2px solid #d9dde3; 19 | th { 20 | border-width: 0px; 21 | text-align: left; 22 | } 23 | } 24 | tbody { 25 | tr.disabled td{ 26 | background: #e3e3e3 !important; 27 | cursor: not-allowed; 28 | } 29 | td.rowspan-td { 30 | border-right: 1px solid #d9dde3; 31 | border-left: 1px solid #d9dde3; 32 | padding-left:48px; 33 | text-align: left; 34 | } 35 | td.rowspan-right { 36 | border-right: 1px solid #d9dde3; 37 | } 38 | tr:hover { 39 | td { 40 | background-color: #fff; 41 | } 42 | td.rowspan-td { 43 | background: none; 44 | } 45 | } 46 | tr.error { 47 | background: #faf2ca !important; 48 | } 49 | tr { 50 | 51 | 52 | td { 53 | .icon-btn { 54 | color: #707070; 55 | border: none; 56 | background: transparent; 57 | } 58 | .icon-btn:hover { 59 | color: #61bbf4; 60 | } 61 | .icon-btn[disabled] { 62 | color: #ccc; 63 | } 64 | 65 | } 66 | 67 | &.selected{ 68 | 69 | border-left:3px solid @peter-river; 70 | 71 | } 72 | } 73 | td.inner:only-child { 74 | padding-right: 48px; 75 | padding-top: 10px; 76 | padding-bottom: 10px; 77 | } 78 | td.inner:only-child:hover { 79 | background-color: transparent; 80 | } 81 | td.inner { 82 | th { 83 | text-align: center; 84 | } 85 | th:first-child { 86 | text-align: left; 87 | } 88 | td { 89 | background-color: transparent; 90 | } 91 | tr:hover { 92 | td { 93 | background-color: #f8f8f8; 94 | } 95 | } 96 | } 97 | tr.end-noborder td{ 98 | border-bottom-width: 0px; 99 | } 100 | 101 | } 102 | input[type="checkbox"] { 103 | margin-right:10px; 104 | } 105 | 106 | .text-link { 107 | color: #61bbf4; 108 | } 109 | .text-link:hover { 110 | color: #707070; 111 | } 112 | td.inner { 113 | & > table { 114 | width: 100%; 115 | thead { 116 | background: #d9dde3; 117 | border-color: #d9dde3; 118 | color: #707070; 119 | } 120 | } 121 | } 122 | } 123 | 124 | .disable { 125 | tbody { 126 | tr:hover { 127 | td { 128 | background: #f8f8f8; 129 | } 130 | } 131 | } 132 | } 133 | .no-bottom-border{ 134 | tbody tr td { 135 | border-bottom-width: 0px; 136 | } 137 | } 138 | .bordered { 139 | thead { 140 | tr th{ 141 | border:1px solid #d9dde3; 142 | } 143 | } 144 | tbody { 145 | td:first-child { 146 | border-left: 1px solid #d9dde3; 147 | } 148 | td:last-child { 149 | border-right: 1px solid #d9dde3; 150 | } 151 | tr:hover { 152 | td { 153 | background: #fff; 154 | } 155 | } 156 | } 157 | thead { 158 | background: #f5f5f7; 159 | } 160 | } 161 | .bordered thead,.bordered tbody tr td { 162 | border:1px solid #d9dde3; 163 | } 164 | .centered { 165 | text-align: center; 166 | } 167 | .m-table.dark { 168 | thead { 169 | border-color: #e5eef5; 170 | border:1px solid #d9dde3; 171 | border-bottom: none; 172 | tr { 173 | background: #e5eef5; 174 | height: 30px; 175 | th { 176 | color:#687178; 177 | } 178 | } 179 | } 180 | } 181 | .dark { 182 | tbody { 183 | tr:nth-child(even) { 184 | background: #fff; 185 | } 186 | tr { 187 | td:first-child { 188 | border-left:1px solid #d9dde3; 189 | } 190 | td:last-child { 191 | border-right:1px solid #d9dde3; 192 | } 193 | } 194 | } 195 | } 196 | .tbl-form { 197 | tbody { 198 | tr { 199 | td { 200 | padding-top: 10px; 201 | border-bottom: 0px; 202 | } 203 | } 204 | } 205 | } 206 | 207 | .hover{ 208 | tbody tr:hover td{ 209 | background: #f3f3f3; 210 | cursor: pointer; 211 | } 212 | } 213 | 214 | .no-bordered tbody tr td, 215 | .no-bordered thead, 216 | .no-bordered thead tr th 217 | { 218 | border-width: 0px !important; 219 | } 220 | -------------------------------------------------------------------------------- /seed/less/modules/m-type.less: -------------------------------------------------------------------------------- 1 | // 2 | // Typography 3 | // -------------------------------------------------- 4 | // Headings 5 | // ------------------------- 6 | a { 7 | text-decoration: none; 8 | color: @peter-river; 9 | } 10 | 11 | h1, 12 | h2, 13 | h3, 14 | h4, 15 | h5, 16 | h6, 17 | .h1, 18 | .h2, 19 | .h3, 20 | .h4, 21 | .h5, 22 | .h6 { 23 | font-family: @headings-font-family; 24 | font-weight: @headings-font-weight; 25 | line-height: @headings-line-height; 26 | color: @headings-color; 27 | small { 28 | color: @headings-small-color; 29 | } 30 | } 31 | 32 | h1, 33 | h2, 34 | h3 { 35 | margin-top: @line-height-computed; 36 | margin-bottom: (@line-height-computed / 2); 37 | padding-bottom: (@line-height-computed / 2); 38 | } 39 | 40 | h3 { 41 | border-bottom: 1px solid #ddd; 42 | } 43 | 44 | h4, 45 | h5, 46 | h6 { 47 | margin-top: (@line-height-computed / 2); 48 | margin-bottom: (@line-height-computed / 2); 49 | } 50 | 51 | h6 { 52 | font-weight: normal; 53 | } 54 | 55 | h1, 56 | .h1 { 57 | font-size: @font-size-h1; 58 | } // ~62px 59 | h2, 60 | .h2 { 61 | font-size: @font-size-h2; 62 | } // ~52px 63 | h3, 64 | .h3 { 65 | font-size: @font-size-h3; 66 | } // ~40px 67 | h4, 68 | .h4 { 69 | font-size: @font-size-h4; 70 | } // ~29px 71 | h5, 72 | .h5 { 73 | font-size: @font-size-h5; 74 | } // ~28px 75 | h6, 76 | .h6 { 77 | font-size: @font-size-h6; 78 | } // ~24px 79 | // Body text 80 | // ------------------------- 81 | p { 82 | font-size: @font-size-base; 83 | line-height: @line-height-base; 84 | margin: 0 0 (@line-height-computed / 2); 85 | } 86 | 87 | .lead { 88 | margin-bottom: @line-height-computed; 89 | font-size: floor((@font-size-base * 1.556)); // ~28px 90 | line-height: 1.46428571; // ~41px 91 | font-weight: 300; 92 | @media (min-width: @screen-sm-min) { 93 | font-size: (@font-size-base * 1.667); // ~30px 94 | } 95 | } 96 | 97 | // Emphasis & misc 98 | // ------------------------- 99 | // Ex: 18px base font * 83% = about 15px 100 | small, 101 | .small { 102 | font-size: 83%; // ~15px 103 | line-height: 2.067; // ~31px 104 | } 105 | 106 | // Contextual emphasis 107 | .text-muted { 108 | color: @text-muted; 109 | } 110 | 111 | .text-inverse { 112 | color: @inverse; 113 | } 114 | 115 | // Page header 116 | // ------------------------- 117 | .page-header { 118 | padding-bottom: ((@line-height-computed / 2) - 1); 119 | margin: (@line-height-computed * 2) 0 @line-height-computed; 120 | border-bottom: 2px solid @page-header-border-color; 121 | } 122 | 123 | // Lists 124 | // -------------------------------------------------- 125 | // Unordered and Ordered lists 126 | ul, 127 | ol { 128 | margin-bottom: (@line-height-computed / 2); 129 | } 130 | 131 | // Description Lists 132 | dl { 133 | margin-bottom: @line-height-computed; 134 | } 135 | 136 | dt, 137 | dd { 138 | line-height: @line-height-base; 139 | } 140 | 141 | // Horizontal description lists 142 | // 143 | // Defaults to being stacked without any of the below styles applied, until the 144 | // grid breakpoint is reached (default of ~768px). 145 | @media (min-width: @grid-float-breakpoint) { 146 | .dl-horizontal { 147 | dt { 148 | width: (@dl-horizontal-offset - 20); 149 | } 150 | dd { 151 | margin-left: @dl-horizontal-offset; 152 | } 153 | } 154 | } 155 | 156 | // MISC 157 | // ---- 158 | // Abbreviations and acronyms 159 | abbr[title], 160 | abbr[data-original-title] { 161 | border-bottom: 1px dotted @abbr-border-color; 162 | } 163 | 164 | // Blockquotes 165 | blockquote { 166 | border-left: 3px solid @blockquote-border-color; 167 | padding: 0 0 0 16px; 168 | margin: 0 0 @line-height-computed; 169 | p { 170 | font-size: ceil((@font-size-base * 1.111)); // ~20px 171 | line-height: 1.55; // ~31px 172 | font-weight: normal; 173 | margin-bottom: .4em; 174 | } 175 | small, 176 | .small { 177 | font-size: @font-size-base; 178 | line-height: @line-height-base; 179 | font-style: italic; 180 | color: @blockquote-small-color; 181 | &:before { 182 | content: ""; 183 | } 184 | } 185 | // Float right with text-align: right 186 | &.pull-right { 187 | padding-right: 16px; 188 | padding-left: 0; 189 | border-right: 3px solid @blockquote-border-color; 190 | border-left: 0; 191 | small:after { 192 | content: ""; 193 | } 194 | } 195 | } 196 | 197 | // Addresses 198 | address { 199 | margin-bottom: @line-height-computed; 200 | line-height: @line-height-base; 201 | } 202 | 203 | // Sup and Sub 204 | sub, 205 | sup { 206 | font-size: 70%; 207 | } 208 | 209 | hr { 210 | display: block; 211 | height: 1px; 212 | border: 0; 213 | border-top: #EFEFEF 1px solid; 214 | margin: 3.2em 0; 215 | padding: 0; 216 | } 217 | 218 | blockquote { 219 | -moz-box-sizing: border-box; 220 | box-sizing: border-box; 221 | margin: 1.75em 0 1.75em -2.2em; 222 | padding: 0 0 0 1.75em; 223 | border-left: #3498db 0.4em solid; 224 | } 225 | 226 | blockquote p { 227 | margin: 0.8em 0; 228 | font-style: italic; 229 | } 230 | 231 | blockquote small { 232 | display: inline-block; 233 | margin: 0.8em 0 0.8em 1.5em; 234 | font-size: 0.9em; 235 | color: #CCC; 236 | } 237 | 238 | blockquote small:before { 239 | content: "\2014 \00A0"; 240 | } 241 | 242 | blockquote cite { 243 | font-weight: 700; 244 | } 245 | 246 | blockquote cite a { 247 | font-weight: normal; 248 | } 249 | 250 | mark { 251 | background-color: #fdffb6; 252 | } 253 | 254 | code, 255 | tt { 256 | padding: 1px 3px; 257 | border: #f8f8f8 1px solid; 258 | background: #f8f8f8; 259 | border-radius: 2px; 260 | white-space: pre-wrap; 261 | color: #e67e22; 262 | } 263 | 264 | pre { 265 | -moz-box-sizing: border-box; 266 | box-sizing: border-box; 267 | margin: 0 0 1.75em 0; 268 | width: 100%; 269 | padding: 10px; 270 | font-size: 0.9em; 271 | white-space: pre; 272 | overflow: auto; 273 | background: #f7f7f7; 274 | border-radius: 3px; 275 | } 276 | 277 | pre code, 278 | pre tt { 279 | font-size: inherit; 280 | white-space: pre-wrap; 281 | background: transparent; 282 | border: none; 283 | padding: 0; 284 | } 285 | 286 | kbd { 287 | display: inline-block; 288 | margin-bottom: 0.4em; 289 | padding: 1px 8px; 290 | border: #CCC 1px solid; 291 | color: #666; 292 | text-shadow: #FFF 0 1px 0; 293 | font-size: 0.9em; 294 | font-weight: 700; 295 | background: #F4F4F4; 296 | border-radius: 4px; 297 | box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 1px 0 0 #ffffff inset; 298 | } 299 | 300 | table { 301 | -moz-box-sizing: border-box; 302 | box-sizing: border-box; 303 | margin: 1.75em 0; 304 | width: 100%; 305 | max-width: 100%; 306 | background-color: transparent; 307 | } 308 | 309 | table th, 310 | table td { 311 | padding: 8px; 312 | line-height: 20px; 313 | text-align: left; 314 | vertical-align: top; 315 | border-top: #EFEFEF 1px solid; 316 | } 317 | 318 | table th { 319 | color: #000; 320 | } 321 | 322 | table caption + thead tr:first-child th, 323 | table caption + thead tr:first-child td, 324 | table colgroup + thead tr:first-child th, 325 | table colgroup + thead tr:first-child td, 326 | table thead:first-child tr:first-child th, 327 | table thead:first-child tr:first-child td { 328 | border-top: 0; 329 | } 330 | 331 | table tbody + tbody { 332 | border-top: #EFEFEF 2px solid; 333 | } 334 | 335 | table table table { 336 | background-color: #FFF; 337 | } 338 | 339 | table tbody > tr:nth-child(odd) > td, 340 | table tbody > tr:nth-child(odd) > th { 341 | background-color: #F6F6F6; 342 | } 343 | 344 | table.plain tbody > tr:nth-child(odd) > td, 345 | table.plain tbody > tr:nth-child(odd) > th { 346 | background: transparent; 347 | } 348 | 349 | iframe, 350 | .fluid-width-video-wrapper { 351 | display: block; 352 | margin: 1.75em 0; 353 | } 354 | /* When a video is inside the fitvids wrapper, drop the 355 | margin on the iframe, cause it breaks stuff. */ 356 | 357 | .fluid-width-video-wrapper iframe { 358 | margin: 0; 359 | } -------------------------------------------------------------------------------- /seed/less/modules/reset.less: -------------------------------------------------------------------------------- 1 | /**reset css**/ 2 | html,body,div,span, 3 | applet,object,iframe, 4 | h1,h2,h3,h4,h5,h6,p,blockquote,pre, 5 | a,abbr,acronym,address,big,cite,code, 6 | del,dfn,em,font,img,ins,kbd,q,s,samp, 7 | small,strike,strong,sub,sup,tt,var, 8 | dd,dl,dt,li,ol,ul, 9 | fieldset,form,label,legend, 10 | table,caption,tbody,tfoot,thead,tr,th,td { 11 | margin: 0; 12 | padding: 0; 13 | border: 0; 14 | } 15 | table { 16 | border-collapse: collapse; 17 | border-spacing: 0; 18 | } 19 | ol,ul { 20 | list-style: none; 21 | } 22 | 23 | q:before,q:after, 24 | blockquote:before,blockquote:after { 25 | content: ""; 26 | } 27 | /**base style**/ 28 | body{ 29 | font-family: '\5FAE\8F6F\96C5\9ED1','\9ED1\4F53',arial,sans-serif; 30 | font-size: @font-size-base; 31 | font-weight: lighter; 32 | } 33 | -------------------------------------------------------------------------------- /seed/less/plugins/angular.progress.less: -------------------------------------------------------------------------------- 1 | /* Styling for the ngProgress itself */ 2 | #ngProgress { 3 | margin: 0; 4 | padding: 0; 5 | z-index: 99998; 6 | background-color: @nephritis !important; 7 | color: @nephritis; 8 | box-shadow:none; /* Inherits the font color */ 9 | height: 2px; 10 | opacity: 0; 11 | 12 | /* Add CSS3 styles for transition smoothing */ 13 | -webkit-transition: all 0.5s ease-in-out; 14 | -moz-transition: all 0.5s ease-in-out; 15 | -o-transition: all 0.5s ease-in-out; 16 | transition: all 0.5s ease-in-out; 17 | } 18 | 19 | /* Styling for the ngProgress-container */ 20 | #ngProgress-container { 21 | position: fixed; 22 | margin: 0; 23 | padding: 0; 24 | top: 0; 25 | left: 0; 26 | right: 0; 27 | z-index: 99999; 28 | } -------------------------------------------------------------------------------- /seed/less/plugins/hljs.theme.less: -------------------------------------------------------------------------------- 1 | /** view doc https://highlightjs.org **/ 2 | .hljs { 3 | display: block; 4 | overflow-x: auto; 5 | padding: 0.5em; 6 | background: #f7f7f7; 7 | line-height: 1.65; 8 | } 9 | .hljs, 10 | .hljs-subst { 11 | color: #2c3e50; 12 | } 13 | .hljs-comment { 14 | color: #999; 15 | } 16 | .hljs-keyword, 17 | .hljs-attribute, 18 | .hljs-selector-tag, 19 | .hljs-meta-keyword, 20 | .hljs-doctag, 21 | .hljs-name { 22 | font-weight: bold; 23 | } 24 | .hljs-type, 25 | .hljs-string, 26 | .hljs-number, 27 | .hljs-selector-id, 28 | .hljs-selector-class, 29 | .hljs-quote, 30 | .hljs-template-tag, 31 | .hljs-deletion { 32 | color: #e74c3c; 33 | } 34 | .hljs-title, 35 | .hljs-section { 36 | color: #e74c3c; 37 | font-weight: bold; 38 | } 39 | .hljs-regexp, 40 | .hljs-symbol, 41 | .hljs-variable, 42 | .hljs-template-variable, 43 | .hljs-link, 44 | .hljs-selector-attr, 45 | .hljs-selector-pseudo { 46 | color: #bc6060; 47 | } 48 | .hljs-literal { 49 | color: #78a960; 50 | } 51 | .hljs-built_in, 52 | .hljs-bullet, 53 | .hljs-code, 54 | .hljs-addition { 55 | color: #16a085; 56 | } 57 | .hljs-meta { 58 | color: #2980b9; 59 | } 60 | .hljs-meta-string { 61 | color: #2980b9; 62 | } 63 | .hljs-emphasis { 64 | font-style: italic; 65 | } 66 | .hljs-strong { 67 | font-weight: bold; 68 | } 69 | 70 | -------------------------------------------------------------------------------- /seed/less/vtui.less: -------------------------------------------------------------------------------- 1 | /** vtui 2 | ** https://github.com/Vanthink-UED/VTUI @Vanthink-UED 3 | **/ 4 | @import "./config.less"; 5 | @import "modules/reset.less"; 6 | 7 | @import "modules/m-layout.less"; 8 | @import "modules/m-icon.less"; 9 | @import "modules/m-type.less"; 10 | @import "modules/m-button.less"; 11 | @import "modules/m-table.less"; 12 | @import "modules/m-pagination.less"; 13 | 14 | 15 | /**the plugins**/ 16 | 17 | @import "plugins/angular.progress.less"; 18 | @import "plugins/hljs.theme.less"; 19 | 20 | -------------------------------------------------------------------------------- /seed/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular_amd_seed_cn", 3 | "version": "0.9.2", 4 | "description": "an seed for angular amd tutorial", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/Vanthink-UED/AngularAMD-Tutorial.git" 12 | }, 13 | "keywords": [ 14 | "angular", 15 | "AMD", 16 | "SPA" 17 | ], 18 | "author": "Vanthink-UED", 19 | "license": "MIT", 20 | "bugs": { 21 | "url": "https://github.com/Vanthink-UED/AngularAMD-Tutorial/issues" 22 | }, 23 | "homepage": "https://github.com/Vanthink-UED/AngularAMD-Tutorial#readme" 24 | } 25 | -------------------------------------------------------------------------------- /seed/views/controller-doc.html: -------------------------------------------------------------------------------- 1 |

      controller 的使用

      2 |

      在AngularAMD定义controller非常简单,我们推荐两种写法:

      3 |
      // home.js
       4 | define(['app'], function (app) {  
       5 |     app.controller('ControllerCtrl', function ($scope,$routeParams,$http,$location) {  
       6 |         // 数据集
       7 |         $scope.list = false;
       8 | 
       9 |         // 初始化函数 需要在 view 里面和 ng-init 绑定
      10 |         $scope.init = function() {
      11 | 
      12 |         }
      13 | 
      14 |         // 刷新数据
      15 |         $scope.refresh = function() {
      16 | 
      17 |         }
      18 | 
      19 |         // 绑定点击事件 和 指定 view 中 ng-click 绑定
      20 |         $scope.clickEvent = function(e) {
      21 | 
      22 |         }
      23 | 
      24 |     });
      25 | });
      26 | 
      27 |

      或者我们也可以这样写

      28 |
      // controller.js
      29 | define(['app'], function (app) {  
      30 |     app.controller('ControllerCtrl', function ($scope,$routeParams,$http,$location) {  
      31 |         var modules = {
      32 | 
      33 |             init: function() {
      34 |                 this.list = false;       
      35 |             },
      36 | 
      37 |             refresh: function() {
      38 | 
      39 |             },
      40 | 
      41 |             events:{
      42 |                 click: function(e) {
      43 | 
      44 |                 }
      45 |             },
      46 | 
      47 | 
      48 |         };
      49 | 
      50 |         return angular.extend($scope, modules);
      51 | 
      52 |     });
      53 | });
      54 | 
      55 |
      
      56 | define(['app'], function (app) {  
      57 |     app.controller('ControllerCtrl', function ($scope,$routeParams,$http,$location) {  
      58 |         $scope.list = false;
      59 |         $scope.init = function() {
      60 |             var blocks = document.querySelectorAll('pre code');
      61 |             for(var i=0;i<blocks.length;i++) {
      62 | 
      63 |                 hljs.highlightBlock(blocks[i]);    
      64 |             }
      65 |         }
      66 |         $scope.refresh = function() {
      67 |             var url = 'http://api.geonames.org/postalCodeLookupJSON?postalcode=6600&country=AT&username=demo';
      68 | 
      69 |             $http.get(url).
      70 |               success(function (data, status, headers, config) {
      71 |                   $scope.list = data.postalcodes;
      72 |               }).
      73 |               error(function (data, status, headers, config) {
      74 |                    $scope.list = false;
      75 |               });
      76 |         }
      77 | 
      78 |         $scope.clickEvent = function(e) {
      79 |             $scope.refresh();
      80 |         }
      81 |     });
      82 | });
      83 | 
      84 |

      下一章:模块

      85 | -------------------------------------------------------------------------------- /seed/views/controller.html: -------------------------------------------------------------------------------- 1 |

      controller 的使用

      2 |

      在AngularAMD定义controller非常简单,我们推荐两种写法:

      3 |
      // home.js
        4 | define(['app'], function (app) {  
        5 |     app.controller('ControllerCtrl', function ($scope,$routeParams,$http,$location) {  
        6 |         // 数据集
        7 |         $scope.list = false;
        8 | 
        9 |         // 初始化函数 需要在 view 里面和 ng-init 绑定
       10 |         $scope.init = function() {
       11 | 
       12 |         }
       13 | 
       14 |         // 刷新数据
       15 |         $scope.refresh = function() {
       16 | 
       17 |         }
       18 | 
       19 |         // 绑定点击事件 和 指定 view 中 ng-click 绑定
       20 |         $scope.clickEvent = function(e) {
       21 | 
       22 |         }
       23 | 
       24 |     });
       25 | });
       26 | 
      27 |

      或者我们也可以这样写

      28 |
      // controller.js
       29 | define(['app'], function (app) {  
       30 |     app.controller('ControllerCtrl', function ($scope,$routeParams,$http,$location) {  
       31 |         var modules = {
       32 | 
       33 |             init: function() {
       34 |                 this.list = false;       
       35 |             },
       36 | 
       37 |             refresh: function() {
       38 | 
       39 |             },
       40 | 
       41 |             events:{
       42 |                 click: function(e) {
       43 | 
       44 |                 }
       45 |             },
       46 | 
       47 | 
       48 |         };
       49 | 
       50 |         return angular.extend($scope, modules);
       51 | 
       52 |     });
       53 | });
       54 | 
      55 | 56 |

      演示:

      57 | 58 |
      59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 |
      citynamecity codecountry code
      {{item.adminName3}}{{item.adminCode1}}{{item.countryCode}}
      暂无数据
      79 |
      80 |

      演示代码:

      81 |
      
       82 | define(['app'], function (app) {  
       83 |     app.controller('ControllerCtrl', function ($scope,$routeParams,$http,$location) {  
       84 |         $scope.list = false;
       85 |         $scope.init = function() {
       86 |             var blocks = document.querySelectorAll('pre code');
       87 |             for(var i=0;i<blocks.length;i++) {
       88 | 
       89 |                 hljs.highlightBlock(blocks[i]);    
       90 |             }
       91 |         }
       92 |         $scope.refresh = function() {
       93 |             var url = 'http://api.geonames.org/postalCodeLookupJSON?postalcode=6600&country=AT&username=demo';
       94 | 
       95 |             $http.get(url).
       96 |               success(function (data, status, headers, config) {
       97 |                   $scope.list = data.postalcodes;
       98 |               }).
       99 |               error(function (data, status, headers, config) {
      100 |                    $scope.list = false;
      101 |               });
      102 |         }
      103 | 
      104 |         $scope.clickEvent = function(e) {
      105 |             $scope.refresh();
      106 |         }
      107 |     });
      108 | });
      109 | 
      110 |

      下一章:模块

      111 | -------------------------------------------------------------------------------- /seed/views/directory.html: -------------------------------------------------------------------------------- 1 |

      目录结构

      2 |

      我们建议您的目录划分足够有目的性,这样方便你的管理和团队代码维护。

      3 |
      - index.html
       4 | + js/
       5 | -   app.js
       6 | -   main.js
       7 | +   controller/
       8 | -       home.js
       9 | -       doc.js
      10 | +   directive/
      11 | +   service/
      12 | 
      13 | +   libs/   第三方类库
      14 | 
      15 | +   templates/
      16 |         cat.tpl.html
      17 | 
      18 |

      下一章:路由

      19 | -------------------------------------------------------------------------------- /seed/views/get-started.html: -------------------------------------------------------------------------------- 1 |

      快速开始

      2 |

      angularAMD是作者@ marcoslin使用 RequireJS + AngularJS开发的前端mvvm框架,因此你可以使用它快速创建一款Web App.它特别适合快速开发SPA应用。

      3 |

      安装

      4 |

      bower

      5 |
      bower install angularAMD
       6 | 
      7 |

      node

      8 |
      npm install angular-amd
       9 | 
      10 |

      外链

      11 |
      //cdn.jsdelivr.net/angular.amd/0.2/angularAMD.min.js
      12 | 
      13 |

      使用

      14 |

      定义require.js 入口文件

      15 |

      我们定义main.js 作为项目的入口文件,在这里可以定义我们的组件以及组件的依赖项;然后在deps里设置我们的项目主文件 16 | app.js

      17 |
      // 定义入口文件
      18 | 
      19 | require.config({
      20 |         baseUrl: "./js/",
      21 |         urlArgs:  'v=' + (new Date()).getTime() + Math.random() * 10000,
      22 |         paths: {
      23 |             'angular': './lib/angular.min',
      24 |             'angular-route': './lib/angular-route',
      25 |             'angularAMD': './lib/angularAMD.min',
      26 |             'ngload' : './lib/' + 'ngload.min',
      27 |             'ng-progress': './lib/ngprogress.min',
      28 |             'vued.cat': './directive/cat',
      29 |         },
      30 |         shim: {
      31 |                 'angularAMD': ['angular'],
      32 |                 'angular-route': ['angular'],
      33 |                 'ng-progress': ['angular'],
      34 |         },
      35 |         deps: ['app']
      36 | });
      37 | 
      38 |

      启动 AngularJS

      39 |

      当所有的组件依赖项全部被定义完成,那么app.js作为 Angular 项目的入口文件,将开始执行启动程序.

      40 |
      define(['angularAMD'], function (angularAMD) {
      41 |     var app = angular.module(app_name, ['webapp']);
      42 |     ... // Setup app here. E.g.: run .config with $routeProvider
      43 |     return angularAMD.bootstrap(app);
      44 | });
      45 | 
      46 |

      如果引导程序被触发,那么原有 ng-app就不应该被放置在 HTML中. angularAMD.bootstrap(app)将会取代程序启动。

      47 |

      配置路由

      48 |

      通过使用 angularAMD.route 我们可以动态配置所需要加载的 controllers;

      49 |
      app.config(function ($routeProvider) {
      50 |     $routeProvider.when(
      51 |         "/home",
      52 |         angularAMD.route({
      53 |             templateUrl: 'views/home.html',
      54 |             controller: 'HomeController',
      55 |             controllerUrl: './js/controller/home'
      56 |         })
      57 |     );
      58 | });
      59 | 
      60 |

      angularAMD.route 主要目的是去设置 require.js 中 resolve 去进行惰性加载 controller 以及 view,无论 61 | 你传入什么样的参数值进去,都会被返回。

      62 |

      这样访问 index.html#/home 就可以查看所做的修改了

      63 |

      下一章:目录划分

      64 | -------------------------------------------------------------------------------- /seed/views/guide1.html: -------------------------------------------------------------------------------- 1 |

      快速开始

      2 | -------------------------------------------------------------------------------- /seed/views/home.html: -------------------------------------------------------------------------------- 1 | 23 |
      24 |

      25 | Alt text 26 |

      27 |

      28 | 快速开始 29 |

      30 |
      Power By Require.js + Angular.js
      31 |
      32 | 33 | -------------------------------------------------------------------------------- /seed/views/module-doc.html: -------------------------------------------------------------------------------- 1 |

      创建 Module

      2 |

      目前 angularAMD 支持的模块内部定义的方法有:

      3 |
        4 |
      • .provider

        5 |
      • 6 |
      • .controller

        7 |
      • 8 |
      • .factory

        9 |
      • 10 |
      • .service

        11 |
      • 12 |
      • .constant

        13 |
      • 14 |
      • .value

        15 |
      • 16 |
      • .directive

        17 |
      • 18 |
      • .filter

        19 |
      • 20 |
      • .animation

        21 |
      • 22 |
      23 |

      你可以快速写一个 fatory

      24 |
      define(['app'], function (app) {
       25 |     app.factory('Pictures', function (...) {
       26 |         ...
       27 |     });
       28 | });
       29 | 
      30 |

      加载单独定义的模块服务

      31 |

      如果我们希望自己写一些单独定义的功能的服务,比如service,directive等。angularAMD提供了这样的功能; 32 | directive/navMenu.js

      33 |
      define(['angularAMD'], function (angularAMD) {
       34 |     angularAMD.directive('navMenu', function (...) {
       35 |         ...
       36 |     });
       37 | });
       38 | 
      39 |

      app.js

      40 |
      define(['angularAMD', 'directive/navMenu'], function (angularAMD) {
       41 |     var app = angular.module(app_name, ['webapp']);
       42 |     ...
       43 |     // `navMenu` is automatically registered bootstrap 
       44 |     return angularAMD.bootstrap(app);
       45 | });
       46 | 
      47 |

      引入第三方 Modules

      48 |

      第三方插件我们经常会用到,在AngularAMD中使用这些插件可以直接在main.js定义后直接在app.js中引用即可.

      49 |

      ng-progress 中已经在main.js中定义过;

      50 |
      define(['angularAMD', 'angular-route','vued.cat','ng-progress'], function (angularAMD) {
       51 | 
       52 |     var app = angular.module("webapp", ['ngRoute','Vued.cat','ngProgress']);
       53 | 
       54 |     // ...
       55 |     return angularAMD.bootstrap(app);
       56 | });
       57 | 
      58 |

      如果你希望在某个controller 中引入第三方插件,比如一个分页插件

      59 |
      define(['app', 'ngload!pagination'], function (app) {
       60 |     app.controller('ModuleCtrl', function ($scope,$http) { 
       61 | 
       62 |     });
       63 | });
       64 | 
      65 |

      demo

      66 |
      
       67 | // module.js
       68 | define(['app','ngload!pagination'], function (app) {  
       69 |     app.controller('ModuleCtrl', function ($scope,$routeParams,$http,$location) {  
       70 | 
       71 |         $scope.list = [];
       72 |         $scope.totalCount = 100;
       73 |         $scope.init = function() {
       74 |             var blocks = document.querySelectorAll('pre code');
       75 |             for(var i=0;i<blocks.length;i++) {
       76 | 
       77 |                 hljs.highlightBlock(blocks[i]);    
       78 |             }
       79 |             $scope.refresh();
       80 |         };
       81 | 
       82 |         $scope.refresh = function() {
       83 |             var list = [];
       84 |             for(var i = 0;i<10; i++){
       85 |                 list.push({
       86 |                     'name': 'Naruto',
       87 |                     'sex': 'man',
       88 |                     'age': parseInt(Math.random() * 100)
       89 |                 });
       90 |             }
       91 |             $scope.list = list;
       92 |         };
       93 | 
       94 |         $scope.pageChangeEvent = function(num) {
       95 |             $scope.pageno = num;
       96 |             $scope.refresh();
       97 |         };
       98 | 
       99 |         $scope.viewOldEvent = function() {
      100 |             alert(this.item.name + ' is ' + this.item.age + ' years old!');
      101 |         }
      102 | 
      103 | 
      104 |         $scope.init();
      105 |     });
      106 | });
      107 | 
      108 |

      html

      109 |
      <div class="demo" style="padding:20px;border:1px solid #ddd;">
      110 | 
      111 |     <table class="m-table bordered">
      112 |         <thead>
      113 |             <tr>
      114 |                 <th>name</th>
      115 |                 <th>age</th>
      116 |                 <th>control</th>
      117 |             </tr>
      118 |         </thead>
      119 |         <tbody>
      120 |             <tr dir-paginate="item in list | itemsPerPage:10" total-items="totalCount" current-page="pageno">
      121 |                 <td>{{item.name}}</td>
      122 |                 <td>{{item.age}}</td>
      123 |                 <td><a href="" ng-click="viewOldEvent()">View Detail</a></td>
      124 |             </tr>
      125 |             <tr ng-show="list==false">
      126 |                 <td colspan="3">暂无数据</td>
      127 |             </tr>
      128 |         </tbody>
      129 |     </table>
      130 |     <dir-pagination-controls boundary-links="true" ng-hide="list2.length==0" on-page-change="pageChangeEvent(newPageNumber)"></dir-pagination-controls>
      131 | 
      132 | </div>
      133 | 
      134 |

      下一章:种子使用

      135 | -------------------------------------------------------------------------------- /seed/views/module.html: -------------------------------------------------------------------------------- 1 |

      创建 Module

      2 |

      目前 angularAMD 支持的模块内部定义的方法有:

      3 |
        4 |
      • .provider

        5 |
      • 6 |
      • .controller

        7 |
      • 8 |
      • .factory

        9 |
      • 10 |
      • .service

        11 |
      • 12 |
      • .constant

        13 |
      • 14 |
      • .value

        15 |
      • 16 |
      • .directive

        17 |
      • 18 |
      • .filter

        19 |
      • 20 |
      • .animation

        21 |
      • 22 |
      23 |

      你可以快速写一个 fatory

      24 |
      define(['app'], function (app) {
       25 |     app.factory('Pictures', function (...) {
       26 |         ...
       27 |     });
       28 | });
       29 | 
      30 |

      加载单独定义的模块服务

      31 |

      如果我们希望自己写一些单独定义的功能的服务,比如service,directive等。angularAMD提供了这样的功能; 32 | directive/navMenu.js

      33 |
      define(['angularAMD'], function (angularAMD) {
       34 |     angularAMD.directive('navMenu', function (...) {
       35 |         ...
       36 |     });
       37 | });
       38 | 
      39 |

      app.js

      40 |
      define(['angularAMD', 'directive/navMenu'], function (angularAMD) {
       41 |     var app = angular.module(app_name, ['webapp']);
       42 |     ...
       43 |     // `navMenu` is automatically registered bootstrap 
       44 |     return angularAMD.bootstrap(app);
       45 | });
       46 | 
      47 |

      引入第三方 Modules

      48 |

      第三方插件我们经常会用到,在AngularAMD中使用这些插件可以直接在main.js定义后直接在app.js中引用即可.

      49 |

      ng-progress 中已经在main.js中定义过;

      50 |
      define(['angularAMD', 'angular-route','vued.cat','ng-progress'], function (angularAMD) {
       51 | 
       52 |     var app = angular.module("webapp", ['ngRoute','Vued.cat','ngProgress']);
       53 | 
       54 |     // ...
       55 |     return angularAMD.bootstrap(app);
       56 | });
       57 | 
      58 |

      如果你希望在某个controller 中引入第三方插件,比如一个分页插件

      59 |
      define(['app', 'ngload!pagination'], function (app) {
       60 |     app.controller('ModuleCtrl', function ($scope,$http) { 
       61 | 
       62 |     });
       63 | });
       64 | 
      65 | 66 |

      Demo

      67 |
      68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 |
      nameagecontrol
      {{item.name}}{{item.age}}View Detail
      暂无数据
      88 | 89 | 90 |
      91 |

      代码

      92 |
      
       93 | // module.js
       94 | define(['app','ngload!pagination'], function (app) {  
       95 |     app.controller('ModuleCtrl', function ($scope,$routeParams,$http,$location) {  
       96 | 
       97 |         $scope.list = [];
       98 |         $scope.totalCount = 100;
       99 |         $scope.init = function() {
      100 |             var blocks = document.querySelectorAll('pre code');
      101 |             for(var i=0;i<blocks.length;i++) {
      102 | 
      103 |                 hljs.highlightBlock(blocks[i]);    
      104 |             }
      105 |             $scope.refresh();
      106 |         };
      107 | 
      108 |         $scope.refresh = function() {
      109 |             var list = [];
      110 |             for(var i = 0;i<10; i++){
      111 |                 list.push({
      112 |                     'name': 'Naruto',
      113 |                     'sex': 'man',
      114 |                     'age': parseInt(Math.random() * 100)
      115 |                 });
      116 |             }
      117 |             $scope.list = list;
      118 |         };
      119 | 
      120 |         $scope.pageChangeEvent = function(num) {
      121 |             $scope.pageno = num;
      122 |             $scope.refresh();
      123 |         };
      124 | 
      125 |         $scope.viewOldEvent = function() {
      126 |             alert(this.item.name + ' is ' + this.item.age + ' years old!');
      127 |         }
      128 | 
      129 | 
      130 |         $scope.init();
      131 |     });
      132 | });
      133 | 
      134 |
      html
      135 |
      <div class="demo" style="padding:20px;border:1px solid #ddd;">
      136 | 
      137 |     <table class="m-table bordered">
      138 |         <thead>
      139 |             <tr>
      140 |                 <th>name</th>
      141 |                 <th>age</th>
      142 |                 <th>control</th>
      143 |             </tr>
      144 |         </thead>
      145 |         <tbody>
      146 |             <tr dir-paginate="item in list | itemsPerPage:10" total-items="totalCount" current-page="pageno">
      147 |                 <td>{{item.name}}</td>
      148 |                 <td>{{item.age}}</td>
      149 |                 <td><a href="" ng-click="viewOldEvent()">View Detail</a></td>
      150 |             </tr>
      151 |             <tr ng-show="list==false">
      152 |                 <td colspan="3">暂无数据</td>
      153 |             </tr>
      154 |         </tbody>
      155 |     </table>
      156 |     <dir-pagination-controls boundary-links="true" ng-hide="list.length==0" on-page-change="pageChangeEvent(newPageNumber)"></dir-pagination-controls>
      157 | 
      158 | </div>
      159 | 
      160 | 161 |

      下一章:种子使用

      162 | -------------------------------------------------------------------------------- /seed/views/more-doc.html: -------------------------------------------------------------------------------- 1 |

      更多参考阅读

      2 |

      这里有更多资料,作者整理的用于理解项目的来源和实践

      3 |

      Dynamically Loading Controllers and Views with AngularJS and RequireJS by Dan Wahlin

      4 |

      Dependency Injection using RequireJS & AngularJS by Thomas Burleson

      5 |

      http://stackoverflow.com/questions/19134023/lazy-loading-angularjs-modules-with-requirejs

      6 |

      angular-require-lazy by Nikos Paraskevopoulos

      7 | -------------------------------------------------------------------------------- /seed/views/others.html: -------------------------------------------------------------------------------- 1 |

      持续完善中

      2 |

      我们会持续完善该文档,把团队的最佳实践总结出来。

      3 |

      您也可以在 https://github.com/Vanthink-UED/AngularAMD-Tutorial/issues 提出您的看法和建议。

      4 |

      最后感谢作者 @marcoslin的授权和认可。

      5 | -------------------------------------------------------------------------------- /seed/views/route.html: -------------------------------------------------------------------------------- 1 |

      angularAMD.route 路由配置

      2 |

      通过使用 angularAMD.route 我们可以动态配置所需要加载的 controllers;

      3 |
      app.config(function ($routeProvider) {
       4 |     $routeProvider.when(
       5 |         "/home",
       6 |         angularAMD.route({
       7 |             templateUrl: 'views/home.html',
       8 |             controller: 'HomeController',
       9 |             controllerUrl: './js/controller/home'
      10 |         })
      11 |     );
      12 | });
      13 | 
      14 |

      指定默认访问地址

      15 |

      通过配置otherwise,我们可以讲没有定义的路由地址默认请求到404或者首页上来。

      16 |
      app.config(function ($routeProvider) {
      17 |     $routeProvider
      18 | 
      19 |         .when("/home", angularAMD.route({
      20 |             templateUrl: 'views/home.html',
      21 |             controller: 'HomeCtrl',
      22 |             controllerUrl: './js/controller/home.js'
      23 |         }))
      24 | 
      25 |         ...
      26 | 
      27 |     .otherwise({
      28 |         redirectTo: "/home"
      29 |     });
      30 | });
      31 | 
      32 |

      不设置 controllerUrl

      33 |

      当然如果你已经在 main.js 中定义了controller 的地址这样你可以不用设置controlerUrl

      34 |
      // main.js
      35 | paths: { 'HomeController': 'scripts/controller' }
      36 | 
      37 |

      不设置 controller

      38 |

      如果你忽略了在配置中设置controller选项,那么angularAMD.route则会讲函数从controlerUrl返回回来,那么这样 39 | 你可以避免抛出一个未定义的controller 名称的错误。

      40 |
      define(['app'], function (app) {
      41 |     return ["$scope", function ($scope) {
      42 |         ...
      43 |     }];
      44 | });
      45 | 
      46 |

      扩展路由

      47 |

      当然我们可以自定义设置路由的返回,我们可以自定义扩展一个函数,动态解析url,自动匹配controller 和 controllerUrl.

      48 |
      /** 路由分析 传入路由地址自动拆分寻找 view 和 controller
      49 |  ** @routeUrl  路由定义
      50 |  ** @data 是否需要数据
      51 |  ** 输入 '/test/home' => { view: '/test_home/view',controller:TestHomeCtrl,controllerUrl: /test/home.js }
      52 |  **/
      53 | 
      54 | var routeConfig = function (routeUrl, data) {
      55 |     var paramStr = '';
      56 |     if (typeof (data) == 'object' && data != {}) {
      57 |         paramStr = '?'.serialize(data);
      58 |     };
      59 |     var t = routeUrl.replace(/\//g, '-');
      60 | 
      61 |     var routeArr = t.split('-');
      62 |     routeArr = routeArr.splice(1);
      63 | 
      64 |     var viewUrl =  '/' + routeArr.join('_') + '/view';
      65 |     // JS_ROOT 为 js 根目录
      66 |     var jsUrl = JS_ROOT + '/' + routeArr[0] + '/' + routeArr.splice(1).join('-') + '.js';
      67 |     var c = dashToCamel(t + '-' + 'ctrl');
      68 |     return {
      69 |         templateUrl: viewUrl + '?' + paramStr,
      70 |         controller: c,
      71 |         controllerUrl: jsUrl
      72 |     }
      73 | 
      74 | }
      75 | 
      76 |

      监测路由

      77 |

      我们可以在app.js 去检测路由的请求状态

      78 |
      app.run(function($rootScope) {
      79 | 
      80 |     var ngProgress = ngProgressFactory.createInstance();
      81 | 
      82 |     $rootScope.$on('$routeChangeStart', function() {
      83 |         // 路由请求开始    
      84 |     });
      85 | 
      86 |     $rootScope.$on('$routeChangeSuccess', function() {
      87 |        // 路由请求完成
      88 |     });
      89 | 
      90 |     $rootScope.$on('$routeChangeError', function() {
      91 |        // 路由请求出错
      92 |     });
      93 | 
      94 | });
      95 | 
      96 |

      更多参数设置: https://docs.angularjs.org/api/ngRoute/service/$route

      97 |

      下一章:控制器

      98 | -------------------------------------------------------------------------------- /seed/views/seed.html: -------------------------------------------------------------------------------- 1 |

      种子使用

      2 |

      AngularAMD官方提供了一个种子案例,你也可以直接使用 3 | 中文案例

      4 |

      在线文档便是是基于AngularAMD-Seed构建。

      5 |

      中文案例继承了对lessjs压缩的支持,你可以自己修改gulpfile.js;

      6 |

      使用

      7 |
      git clone  https://github.com/Vanthink-UED/AngularAMD-Tutorial
       8 | 
       9 | npm install
      10 | 
      11 | gulp
      12 | 
      13 |

      访问 http://localhost:8360/#/home

      14 |

      下一章:更多阅读

      15 | --------------------------------------------------------------------------------