├── src ├── main │ └── web │ │ ├── www │ │ ├── modules │ │ │ ├── home │ │ │ │ ├── content.html │ │ │ │ ├── menu.html │ │ │ │ ├── body.html │ │ │ │ ├── menu.js │ │ │ │ ├── content.js │ │ │ │ ├── page.js │ │ │ │ └── body.js │ │ │ ├── login │ │ │ │ ├── header.html │ │ │ │ ├── footer.html │ │ │ │ ├── body.html │ │ │ │ ├── footer.coffee │ │ │ │ ├── page.js │ │ │ │ ├── header.js │ │ │ │ └── body.js │ │ │ ├── utils.coffee │ │ │ └── app.js │ │ ├── img │ │ │ └── logo.png │ │ ├── index.html │ │ ├── main.js │ │ ├── css │ │ │ └── index.css │ │ └── vendor │ │ │ ├── require │ │ │ ├── domReady.js │ │ │ ├── css.js │ │ │ ├── i18n.js │ │ │ ├── cs.js │ │ │ ├── require.min.js │ │ │ └── text.js │ │ │ ├── avalon │ │ │ ├── mmPromise.js │ │ │ ├── mmRouter.js │ │ │ ├── mmHistory.js │ │ │ └── mmRequest.modern.js │ │ │ └── statemachine │ │ │ └── state-machine.js │ │ └── config.xml └── test │ ├── unit │ ├── login │ │ └── login.js │ └── testamd.js │ ├── functional │ └── login │ │ ├── LoginPage.js │ │ └── login.js │ └── intern.js ├── .gitignore ├── package.json ├── README.md ├── LICENSE └── gulpfile.js /src/main/web/www/modules/home/content.html: -------------------------------------------------------------------------------- 1 |
内容
-------------------------------------------------------------------------------- /src/main/web/www/modules/home/menu.html: -------------------------------------------------------------------------------- 1 |
menu
-------------------------------------------------------------------------------- /src/main/web/www/modules/login/header.html: -------------------------------------------------------------------------------- 1 |
2 |
-------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /* 2 | !.gitignore 3 | !gulpfile.js 4 | !LICENSE 5 | !package.json 6 | !README.md 7 | !src 8 | -------------------------------------------------------------------------------- /src/main/web/www/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pinghe/seedfrontend/HEAD/src/main/web/www/img/logo.png -------------------------------------------------------------------------------- /src/main/web/www/modules/login/footer.html: -------------------------------------------------------------------------------- 1 |
2 | login footer 3 |
-------------------------------------------------------------------------------- /src/main/web/www/modules/utils.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | define [], () -> 4 | noopfunc: () -> 5 | emptydiv: '
' -------------------------------------------------------------------------------- /src/main/web/www/modules/login/body.html: -------------------------------------------------------------------------------- 1 |
2 |
登录名:
3 |
口 令:
4 | 5 | 6 |
home
7 |
-------------------------------------------------------------------------------- /src/main/web/www/modules/home/body.html: -------------------------------------------------------------------------------- 1 |
2 |
已登录用户:{{user.name}}
3 |
登录时间:{{user.logintime}}
4 | 5 |
login
6 |
7 |
8 |
-------------------------------------------------------------------------------- /src/main/web/www/modules/login/footer.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | define ["avalon", "text!./footer.html"], (avalon, footerhtml) -> 4 | avalon.define({ 5 | $id: "loginfooterid" 6 | }) 7 | 8 | avalon.templateCache.loginfooter = footerhtml 9 | 10 | return 11 | # loadpage: () -> 12 | # avalon.templateCache.loginfooter = footerhtml 13 | # return 14 | # 15 | # leavepage: () -> 16 | # avalon.templateCache.loginfooter = Utils.emptydiv 17 | # return 18 | 19 | -------------------------------------------------------------------------------- /src/main/web/www/modules/home/menu.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mengzhx on 2015-01-06. 3 | */ 4 | 'use strict' 5 | 6 | define(['utils', 'avalon', "text!./menu.html"], function (Utils, Avalon, pagehtml) { 7 | avalon.templateCache.homemenu = pagehtml; 8 | 9 | //return { 10 | // loadpage: function () { 11 | // avalon.templateCache.homemenu = pagehtml; 12 | // }, 13 | // leavepage: function(){ 14 | // Avalon.templateCache.homemenu = Utils.emptydiv; 15 | // } 16 | //} 17 | 18 | }); -------------------------------------------------------------------------------- /src/main/web/www/modules/home/content.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mengzhx on 2015-01-06. 3 | */ 4 | 'use strict' 5 | 6 | define(['utils', 'avalon', "text!./content.html"], function (Utils, Avalon, pagehtml) { 7 | avalon.templateCache.homecontent = pagehtml; 8 | 9 | //return { 10 | // loadpage: function () { 11 | // avalon.templateCache.homecontent = pagehtml; 12 | // }, 13 | // leavepage: function(){ 14 | // Avalon.templateCache.homecontent = Utils.emptydiv; 15 | // } 16 | //} 17 | 18 | }); -------------------------------------------------------------------------------- /src/main/web/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | seedprjfrontend 4 | 5 | A sample Apache Cordova application that responds to the deviceready event. 6 | 7 | 8 | Apache Cordova Team 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/main/web/www/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | JavaScript前端原型模板项目 5 | 6 | 7 | 8 | 13 | 14 | 15 | 16 |
17 |
18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /src/main/web/www/modules/login/page.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mengzhx on 2015-01-04. 3 | */ 4 | 'use strict' 5 | 6 | define(['login/header', 'login/body', 'login/footer'], function (header, body, footer) {//第三块,加载其他模块 7 | //return { 8 | // load: function () { 9 | // header.loadpage(); 10 | // body.loadpage(); 11 | // footer.loadpage(); 12 | // avalon.log("加载loginpage完毕!"); 13 | // }, 14 | // leave: function() { 15 | // header.leavepage(); 16 | // body.leavepage(); 17 | // footer.leavepage(); 18 | // avalon.log("卸载loginpage完毕!"); 19 | // } 20 | //} 21 | }); -------------------------------------------------------------------------------- /src/main/web/www/modules/login/header.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | define(['utils', 'avalon', 'text!./header.html'], function(Utils, Avalon, headerhtml) { 4 | 5 | Avalon.define({ 6 | $id: "loginheaderid" 7 | }); 8 | Avalon.templateCache.loginheader = headerhtml; 9 | //return { 10 | // loadpage: function () { 11 | // Avalon.templateCache.loginheader = headerhtml; 12 | // //Avalon.vmodels.pageroute.header = "loginheader" 13 | // }, 14 | // leavepage: function () { 15 | // Avalon.templateCache.loginheader = Utils.emptydiv; 16 | // //Avalon.vmodels.pageroute.header = Utils.emptydiv 17 | // } 18 | //} 19 | 20 | }); 21 | -------------------------------------------------------------------------------- /src/main/web/www/modules/home/page.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mengzhx on 2015-01-04. 3 | */ 4 | 'use strict' 5 | 6 | define(['utils', 'avalon', 'home/body'], function (Utils, Avalon, body) {//第三块,加载其他模块 7 | 8 | //body.loadpage(); 9 | Avalon.templateCache.homeheader = Utils.emptydiv; 10 | Avalon.templateCache.homefooter = Utils.emptydiv; 11 | 12 | //return { 13 | // load: function () { 14 | // body.loadpage(); 15 | // Avalon.templateCache.homeheader = Utils.emptydiv; 16 | // Avalon.templateCache.homefooter = Utils.emptydiv; 17 | // Avalon.log("加载homepage完毕!"); 18 | // }, 19 | // leave: function () { 20 | // body.leavepage(); 21 | // Avalon.templateCache.homeheader = Utils.emptydiv; 22 | // Avalon.templateCache.homefooter = Utils.emptydiv; 23 | // Avalon.log("卸载homepage完毕!"); 24 | // } 25 | //} 26 | }); -------------------------------------------------------------------------------- /src/main/web/www/modules/home/body.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | define(['utils', 'mmRouter', 'text!./body.html','home/menu','home/content'], function (Utils, Avalon, pagehtml, menu, content) { 4 | 5 | var pagemodel = Avalon.define({ 6 | $id: "homebodyid", 7 | content: "empty", 8 | menu: "empty", 9 | $loadpage: function(state) { 10 | pagemodel.content = state+'content'; 11 | pagemodel.menu = state+'menu'; 12 | }, 13 | 14 | logout: function () { 15 | avalon.vmodels.loginbodyid.logout() 16 | } 17 | }); 18 | Avalon.templateCache.homebody = pagehtml; 19 | //menu.loadpage(); 20 | //content.loadpage(); 21 | 22 | pagemodel.$loadpage('home'); 23 | 24 | //return { 25 | // loadpage: function () { 26 | // Avalon.templateCache.homebody = pagehtml; 27 | // menu.loadpage(); 28 | // content.loadpage(); 29 | // }, 30 | // leavepage: function(){ 31 | // Avalon.templateCache.homebody = Utils.emptydiv; 32 | // } 33 | //} 34 | 35 | }); 36 | -------------------------------------------------------------------------------- /src/main/web/www/main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mengzhx on 2015-01-04. 3 | */ 4 | 'use strict'; 5 | 6 | require.config({//第一块,配置 7 | baseUrl: './modules/', 8 | paths: { 9 | main: '../main', 10 | jquery: '../vendor/jquery/jquery-2.1.3', 11 | stateMachine: '../vendor/statemachine/state-machine', 12 | avalon: "../vendor/avalon/avalon.mobile.shim", 13 | mmPromise: "../vendor/avalon/mmPromise", 14 | mmRequest: "../vendor/avalon/mmRequest.modern", 15 | mmHistory: "../vendor/avalon/mmHistory", 16 | mmRouter: "../vendor/avalon/mmRouter", 17 | text: '../vendor/require/text', 18 | domReady: '../vendor/require/domReady', 19 | css: '../vendor/require/css.js', 20 | i18n: '../vendor/require/i18n.js', 21 | mycordova: "../cordova" 22 | }, 23 | priority: ['text', 'css'], 24 | shim: { 25 | //avalon: { 26 | // exports: "avalon" 27 | //}, 28 | "mycordova": { 29 | exports: "cordova" 30 | } 31 | }, 32 | config: { 33 | //'_@r6': { 34 | 'app': { 35 | 'basepath': '/' 36 | } 37 | }, 38 | deps: ['./app'] 39 | }); -------------------------------------------------------------------------------- /src/main/web/www/modules/login/body.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | define(['utils', "avalon", "text!./body.html", "mmRequest"], function (Utils, Avalon, pagehtml) { 4 | 5 | var pagemodel = Avalon.define({ 6 | $id: "loginbodyid", 7 | username: "", 8 | password: "", 9 | login: function (username, password, logintime) { 10 | console.log(pagemodel.username, username); 11 | // todo ajax 登录 12 | if (logintime === undefined) { 13 | logintime = new Date(); 14 | } 15 | avalon.vmodels.pageroute.$fsm.logged(username, password, logintime); 16 | // pagemodel 17 | }, 18 | logout: function () { 19 | console.log(pagemodel.username); 20 | avalon.vmodels.pageroute.$fsm.logout(); 21 | // pagemodel 22 | } 23 | }); 24 | Avalon.templateCache.loginbody = pagehtml; 25 | 26 | //return { 27 | // loadpage: function () { 28 | // Avalon.templateCache.loginpage = pagehtml; 29 | // }, 30 | // leavepage: function(){ 31 | // Avalon.templateCache.loginpage = Utils.emptydiv; 32 | // } 33 | //} 34 | }); 35 | -------------------------------------------------------------------------------- /src/test/unit/login/login.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mengzhx on 2015-01-07. 3 | */ 4 | define([ 5 | 'intern!tdd', 6 | 'intern/chai!expect' 7 | //'login/body' 8 | ], function (tdd, expect) { 9 | require("avalon")(windows) 10 | tdd.suite('登录功能', function () { 11 | //require('avalon')(windows) 12 | //require('login/body') 13 | console.log('==================='); 14 | 15 | var user = {name: 'testuser', password: 'pass', logintime: new Date()}; 16 | tdd.before(function () { 17 | avalon.vmodels.loginbodyid.login(user.name, user.password, user.logintime); 18 | }); 19 | 20 | tdd.after(function () { 21 | avalon.vmodels.loginbodyid.logout(); 22 | //avalon.vmodels.loginpageid.logout(); 23 | }); 24 | 25 | tdd.test('成功登录', function () { 26 | expect(avalon.vmodels.loginpageid.password).to.equal(''); 27 | //assert.strictEqual(avalon.vmodels.loginpageid.password, '', 28 | // '口令应该不保存'); 29 | expect(avalon.vmodels.pageroute.user).to.deep.equal({ 30 | logged: true, 31 | name: user.name, 32 | logintime: user.logintime 33 | }); 34 | }); 35 | }); 36 | }); -------------------------------------------------------------------------------- /src/test/functional/login/LoginPage.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mengzhx on 2015-01-12. 3 | */ 4 | define([], function () { 5 | // the page object is created as a constructor 6 | // so we can provide the remote Command object 7 | // at runtime 8 | function LoginPage(remote) { 9 | this.remote = remote; 10 | } 11 | 12 | LoginPage.prototype = { 13 | constructor: LoginPage, 14 | 15 | // the login function accepts username and password 16 | // and returns a promise that resolves to `true` on 17 | // success or rejects with an error on failure 18 | login: function (username, password) { 19 | return this.remote 20 | .get(require.toUrl('http://localhost:8888/index.html')) 21 | .setFindTimeout(5000) 22 | // first, we perform the login action, using the 23 | // specified username and password 24 | .findById('username').findByTagName('input') 25 | .click() 26 | .type(password) 27 | .end(2) 28 | .findById('password').findByTagName('input') 29 | .click() 30 | .type(username) 31 | .end(2) 32 | .findById('login') 33 | .click() 34 | .end(2) 35 | // then, we verify the success of the action by 36 | // looking for a login success marker on the page 37 | .setFindTimeout(5000) 38 | .findById('logedusername') 39 | .then(function (elm) { 40 | return elm; 41 | }); 42 | } 43 | }; 44 | 45 | return LoginPage; 46 | }); -------------------------------------------------------------------------------- /src/test/functional/login/login.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mengzhx on 2015-01-07. 3 | */ 4 | define([ 5 | 'intern!bdd', 6 | 'intern/chai!assert', 7 | 'functest/login/LoginPage' 8 | ], function (bdd, assert, LoginPage) { 9 | bdd.describe('登录注销', function () { 10 | 11 | var loginPage; 12 | bdd.before(function () { 13 | loginPage = new LoginPage(this.remote); 14 | }); 15 | 16 | bdd.after(function () { 17 | //browser.quit(); 18 | }); 19 | 20 | 21 | bdd.it('当用户输入正确的用户名和口令,单击登录时进入主页面', function () { 22 | 23 | 24 | return loginPage 25 | .login('test', 'test') 26 | .getVisibleText() 27 | .then(function(logedusername){ 28 | console.log("-----%s",logedusername) 29 | assert.strictEqual(logedusername,'已登录用户:test','成功登录后,已登录用户名应该等于登录页面输入用户名') 30 | assert.isString(logedusername,'应该是一个字符串') 31 | }); 32 | 33 | //this.remote // This is following the syntax WD.js https://github.com/admc/wd#supported-methods 34 | // .get(require.toUrl('http://localhost:8888/index.html')) // @todo: find out if you can get this value from Node.js settings 35 | // .findById('username') // Find Element By Id 36 | // .type('testuser') 37 | // .getValue().should().equal('testuser') 38 | // .end() 39 | // .findById('password') // Find Element By Id 40 | // .type('password') 41 | // .end() 42 | // .findById('login') // Find Element By Id 43 | // .click() // Click Event 44 | // .end() 45 | // //.fin(function () { 46 | // // browser.elementById('username') 47 | // // .getValue().should.become('testuser') 48 | // // .elementById('logout') 49 | // // .click() 50 | // // .fin(function () { 51 | // // browser.elementById('password') 52 | // // .getValue().should.become('') 53 | // // }); 54 | // // return browser.quit(); 55 | // //}) 56 | // .done(); 57 | }); 58 | }); 59 | }); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "seedprjfrontend", 3 | "version": "0.0.1", 4 | "description": "前端js原型项目.", 5 | "main": "main.js", 6 | "scripts": { 7 | "test": "gulp itest" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "http://115.29.138.130/gitbucket/git/mengzhx/seedprjfrontend.git" 12 | }, 13 | "keywords": [ 14 | "Cordova", 15 | "Gulp" 16 | ], 17 | "engines": { 18 | "node": ">=0.10.0" 19 | }, 20 | "author": "mengzhx ", 21 | "license": "Apache version 2.0", 22 | "devDependencies": { 23 | "ecstatic": "^0.5.8", 24 | "format": "^0.2.1", 25 | "intern": "^2.2.2", 26 | "chromedriver": "^2.12.0", 27 | "selenium-server-standalone-jar": "^2.44.0", 28 | "selenium-webdriver": "^2.44.0", 29 | "sinon": "^1.12.2", 30 | "bluebird": "^2.6.0", 31 | "requirejs": "^2.1.15", 32 | "ftps": "^0.2.8", 33 | "node-sftp": "^0.1.1", 34 | "browser-sync": "^1.8.0", 35 | "amd-optimize": "^0.4.0", 36 | "merge-stream": "^0.1.6", 37 | "event-stream": "^3.1.7", 38 | "q": "^1.1.2", 39 | "del": "^1.1.0", 40 | "graceful-fs": "^3.0.5", 41 | "streamqueue": "^0.1.1", 42 | "minimist": "^1.1.0", 43 | "cordova-lib": "^4.1.2", 44 | "gulp": "^3.8.10", 45 | "gulp-replace": "^0.5.0", 46 | "gulp-load-plugins": "^0.8.0", 47 | "gulp-coffee": "^2.2.0", 48 | "gulp-concat": "^2.4.2", 49 | "gulp-uglify": "^1.0.2", 50 | "gulp-requirejs": "^0.1.3", 51 | "gulp-sourcemaps": "^1.2.8", 52 | "gulp-less": "^2.0.1", 53 | "gulp-autoprefixer": "^2.0.0", 54 | "gulp-if": "^1.2.5", 55 | "gulp-order": "^1.1.1", 56 | "gulp-traceur": "^0.14.1", 57 | "gulp-sass": "^1.2.4", 58 | "gulp-util": "^3.0.1", 59 | "gulp-plumber": "^0.6.6", 60 | "gulp-cond": "^0.0.2", 61 | "gulp-imagemin": "^2.0.0", 62 | "gulp-rimraf": "^0.1.1", 63 | "gulp-notify": "^2.1.0", 64 | "gulp-rename": "^1.2.0", 65 | "gulp-minify-css": "^0.3.11", 66 | "gulp-htmlmin": "^0.2.0", 67 | "gulp-cached": "^1.0.1", 68 | "gulp-changed": "^1.1.0", 69 | "gulp-remember": "^0.3.0", 70 | "gulp-watch": "^3.0.0", 71 | "gulp-sftp": "^0.1.4", 72 | "gulp-shell": "^0.2.11", 73 | "gulp-open": "^0.3.1", 74 | "gulp-livereload": "^3.0.2", 75 | "gulp-traceur": "^0.14.1", 76 | "gulp-spawn": "^0.3.0", 77 | "gulp-jshint": "^1.9.0" 78 | 79 | }, 80 | "dependencies": { 81 | "cordova-android": "^3.6.4", 82 | "cordova-browser": "^3.6.0" 83 | }, 84 | "cordovaplugins": [ 85 | "org.apache.cordova.file" 86 | ], 87 | "appId": "Seedprjfrontend" 88 | } 89 | -------------------------------------------------------------------------------- /src/test/unit/testamd.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mengzhx on 2015-01-08. 3 | */ 4 | (function( global, factory ) { 5 | 6 | if ( typeof module === "object" && typeof module.exports === "object" ) { 7 | // For CommonJS and CommonJS-like environments where a proper `window` 8 | // is present, execute the factory and get avalon. 9 | // For environments that do not have a `window` with a `document` 10 | // (such as Node.js), expose a factory as module.exports. 11 | // This accentuates the need for the creation of a real `window`. 12 | // e.g. var avalon = require("avalon")(window); 13 | module.exports = global.document ? 14 | factory( global, true ) : 15 | function( w ) { 16 | if ( !w.document ) { 17 | throw new Error( "Avalon requires a window with a document" ); 18 | } 19 | return factory( w ); 20 | }; 21 | } else { 22 | factory( global ); 23 | } 24 | 25 | // Pass this if window is not defined yet 26 | }(typeof window !== "undefined" ? window : this, function( window, noGlobal ) 27 | { 28 | var strundefined = typeof undefined; 29 | 30 | var testamd = {}; 31 | 32 | 33 | 34 | // Register as a named AMD module, since avalon can be concatenated with other 35 | // files that may use define, but not via a proper concatenation script that 36 | // understands anonymous AMD modules. A named AMD is safest and most robust 37 | // way to register. Lowercase avalon is used because AMD module names are 38 | // derived from file names, and Avalon is normally delivered in a lowercase 39 | // file name. Do this after creating the global so that if an AMD module wants 40 | // to call noConflict to hide this version of avalon, it will work. 41 | 42 | // Note that for maximum portability, libraries that are not avalon should 43 | // declare themselves as anonymous modules, and avoid setting a global if an 44 | // AMD loader is present. avalon is a special case. For more information, see 45 | // https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon 46 | 47 | if ( typeof define === "function" && define.amd ) { 48 | define( "testamd", [], function() { 49 | return testamd; 50 | }); 51 | } 52 | 53 | var 54 | // Map over avalon in case of overwrite 55 | _testamd = window.testamd; 56 | 57 | testamd.noConflict = function( deep ) { 58 | 59 | if ( deep && window.testamd === testamd ) { 60 | window.testamd = testamd; 61 | } 62 | 63 | return testamd; 64 | }; 65 | 66 | 67 | // Expose avalon and $ identifiers, even in AMD 68 | // and CommonJS for browser emulators 69 | if ( typeof noGlobal === strundefined ) { 70 | window.testamd = testamd; 71 | } 72 | 73 | return testamd; 74 | 75 | })); 76 | 77 | //(function(factory) { 78 | // if (typeof define === 'function' && define.amd) { 79 | // define([], factory); 80 | // } 81 | // else { 82 | // factory(); 83 | // } 84 | //})(function() { 85 | // 86 | //}) -------------------------------------------------------------------------------- /src/main/web/www/css/index.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | * { 20 | -webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */ 21 | } 22 | 23 | body { 24 | -webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */ 25 | -webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */ 26 | -webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */ 27 | background-color:#E4E4E4; 28 | background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%); 29 | background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%); 30 | background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%); 31 | background-image:-webkit-gradient( 32 | linear, 33 | left top, 34 | left bottom, 35 | color-stop(0, #A7A7A7), 36 | color-stop(0.51, #E4E4E4) 37 | ); 38 | background-attachment:fixed; 39 | font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif; 40 | font-size:12px; 41 | height:100%; 42 | margin:0px; 43 | padding:0px; 44 | text-transform:uppercase; 45 | width:100%; 46 | } 47 | 48 | /* Portrait layout (default) */ 49 | .app { 50 | background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */ 51 | position:absolute; /* position in the center of the screen */ 52 | left:50%; 53 | top:50%; 54 | height:50px; /* text area height */ 55 | width:225px; /* text area width */ 56 | text-align:center; 57 | padding:180px 0px 0px 0px; /* image height is 200px (bottom 20px are overlapped with text) */ 58 | margin:-115px 0px 0px -112px; /* offset vertical: half of image height and text area height */ 59 | /* offset horizontal: half of text area width */ 60 | } 61 | 62 | /* Landscape layout (with min-width) */ 63 | @media screen and (min-aspect-ratio: 1/1) and (min-width:400px) { 64 | .app { 65 | background-position:left center; 66 | padding:75px 0px 75px 170px; /* padding-top + padding-bottom + text area = image height */ 67 | margin:-90px 0px 0px -198px; /* offset vertical: half of image height */ 68 | /* offset horizontal: half of image width and text area width */ 69 | } 70 | } 71 | 72 | h1 { 73 | font-size:24px; 74 | font-weight:normal; 75 | margin:0px; 76 | overflow:visible; 77 | padding:0px; 78 | text-align:center; 79 | } 80 | 81 | .event { 82 | border-radius:4px; 83 | -webkit-border-radius:4px; 84 | color:#FFFFFF; 85 | font-size:12px; 86 | margin:0px 30px; 87 | padding:2px 0px; 88 | } 89 | 90 | .event.listening { 91 | background-color:#333333; 92 | display:block; 93 | } 94 | 95 | .event.received { 96 | background-color:#4B946A; 97 | display:none; 98 | } 99 | 100 | @keyframes fade { 101 | from { opacity: 1.0; } 102 | 50% { opacity: 0.4; } 103 | to { opacity: 1.0; } 104 | } 105 | 106 | @-webkit-keyframes fade { 107 | from { opacity: 1.0; } 108 | 50% { opacity: 0.4; } 109 | to { opacity: 1.0; } 110 | } 111 | 112 | .blink { 113 | animation:fade 3000ms infinite; 114 | -webkit-animation:fade 3000ms infinite; 115 | } 116 | -------------------------------------------------------------------------------- /src/main/web/www/modules/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | define(['mmRouter', 'module', 'stateMachine', 'utils', 'login/page', 'home/page', 'mycordova', 'domReady!'], function (avalon, rjsmodule, StateMachine, Utils) {//第二块,添加根VM(处理共用部分) 4 | 5 | avalon.log("加载avalon完毕,开始构建根VM与加载其他模块"); 6 | 7 | //avalon.templateCache.empty = " "; 8 | avalon.templateCache.empty = Utils.emptydiv; 9 | var pageroutemodel = avalon.define({ 10 | $id: "pageroute", 11 | header: "empty", 12 | footer: "empty", 13 | body: "empty", 14 | $loadpage: function (state) { 15 | pageroutemodel.header = state + 'header'; 16 | pageroutemodel.footer = state + 'footer'; 17 | pageroutemodel.body = state + 'body'; 18 | }, 19 | //下面是路由路径参数 20 | currPath: "/index.html", 21 | //params: {}, 22 | //query: {}, 23 | //args: "[]", 24 | //缓存的登录用户信息 25 | user: { 26 | logged: false, 27 | name: '不明', 28 | logintime: new Date() // 登录时间 29 | }, 30 | //页面路由状态机 31 | $fsm: StateMachine.create({ 32 | initial: {state: 'login', event: 'init', defer: true}, 33 | events: [ 34 | {name: 'logged', from: 'login', to: 'home'}, 35 | {name: 'logout', from: 'home', to: 'login'} 36 | ], 37 | callbacks: { // onlogged --> onleavelogin --> onenterhome --> onafterlogget 38 | onbeforelogged: function (event, from, to, username, password, logintime) { 39 | // noop 40 | }, 41 | onleavelogin: function (event, from, to, username, password, logintime) { 42 | //缓存登录用户信息 43 | pageroutemodel.user.logged = true; 44 | pageroutemodel.user.name = username; 45 | pageroutemodel.user.logintime = logintime; 46 | //loginpage.leavepage(); 47 | }, 48 | onhome: function (event, from, to, username, password, logintime) { 49 | //切换home页面 50 | pageroutemodel.currPath = '/home'; 51 | avalon.router.navigate(pageroutemodel.currPath); 52 | //avalon.vmodels.pageroute.currPath = '/home'; 53 | //avalon.router.navigate('/home'); 54 | //loginpage.loadpage(); 55 | //avalon.vmodels.pageroute.loadpage('home'); 56 | //pageroutemodel.$loadpage('home'); 57 | }, 58 | onlogged: function (event, from, to, username, password, logintime) { 59 | // noop 60 | }, 61 | 62 | onbeforelogout: function (event, from, to) { 63 | // noop 64 | }, 65 | onleavehome: function (event, from, to, username, logintime) { 66 | pageroutemodel.user.logged = false; 67 | pageroutemodel.user.name = '不明'; 68 | //homepage.leavepage(); 69 | }, 70 | onlogin: function (event, from, to) { 71 | pageroutemodel.currPath = '/login'; 72 | avalon.router.navigate(pageroutemodel.currPath); 73 | //avalon.router.navigate('/login'); 74 | ////avalon.vmodels.pageroute.loadpage('login'); 75 | //pageroutemodel.$loadpage('login'); 76 | }, 77 | onlogout: function (event, from, to) { 78 | // noop 79 | } 80 | 81 | } 82 | }) 83 | }); 84 | 85 | var init = function () { 86 | avalon.router.get("/login", function () { 87 | //avalon.router.navigate('/login'); 88 | pageroutemodel.$loadpage('login'); 89 | console.log('加载loginpage完毕') 90 | }); 91 | avalon.router.get("/home", function () { 92 | pageroutemodel.$loadpage('home'); 93 | }); 94 | 95 | avalon.history.start({ 96 | basepath: rjsmodule.config().basepath, 97 | html5Mode: false 98 | }); 99 | 100 | console.log(avalon.router.getLastPath()); 101 | //avalon.router.navigate('/login'); 102 | pageroutemodel.$fsm.init(); 103 | avalon.scan(document.body); 104 | 105 | }; 106 | 107 | document.addEventListener('deviceready', init, false); 108 | }); 109 | -------------------------------------------------------------------------------- /src/main/web/www/vendor/require/domReady.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license RequireJS domReady 2.0.1 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved. 3 | * Available via the MIT or new BSD license. 4 | * see: http://github.com/requirejs/domReady for details 5 | */ 6 | /*jslint */ 7 | /*global require: false, define: false, requirejs: false, 8 | window: false, clearInterval: false, document: false, 9 | self: false, setInterval: false */ 10 | 11 | 12 | define(function () { 13 | 'use strict'; 14 | 15 | var isTop, testDiv, scrollIntervalId, 16 | isBrowser = typeof window !== "undefined" && window.document, 17 | isPageLoaded = !isBrowser, 18 | doc = isBrowser ? document : null, 19 | readyCalls = []; 20 | 21 | function runCallbacks(callbacks) { 22 | var i; 23 | for (i = 0; i < callbacks.length; i += 1) { 24 | callbacks[i](doc); 25 | } 26 | } 27 | 28 | function callReady() { 29 | var callbacks = readyCalls; 30 | 31 | if (isPageLoaded) { 32 | //Call the DOM ready callbacks 33 | if (callbacks.length) { 34 | readyCalls = []; 35 | runCallbacks(callbacks); 36 | } 37 | } 38 | } 39 | 40 | /** 41 | * Sets the page as loaded. 42 | */ 43 | function pageLoaded() { 44 | if (!isPageLoaded) { 45 | isPageLoaded = true; 46 | if (scrollIntervalId) { 47 | clearInterval(scrollIntervalId); 48 | } 49 | 50 | callReady(); 51 | } 52 | } 53 | 54 | if (isBrowser) { 55 | if (document.addEventListener) { 56 | //Standards. Hooray! Assumption here that if standards based, 57 | //it knows about DOMContentLoaded. 58 | document.addEventListener("DOMContentLoaded", pageLoaded, false); 59 | window.addEventListener("load", pageLoaded, false); 60 | } else if (window.attachEvent) { 61 | window.attachEvent("onload", pageLoaded); 62 | 63 | testDiv = document.createElement('div'); 64 | try { 65 | isTop = window.frameElement === null; 66 | } catch (e) {} 67 | 68 | //DOMContentLoaded approximation that uses a doScroll, as found by 69 | //Diego Perini: http://javascript.nwbox.com/IEContentLoaded/, 70 | //but modified by other contributors, including jdalton 71 | if (testDiv.doScroll && isTop && window.external) { 72 | scrollIntervalId = setInterval(function () { 73 | try { 74 | testDiv.doScroll(); 75 | pageLoaded(); 76 | } catch (e) {} 77 | }, 30); 78 | } 79 | } 80 | 81 | //Check if document already complete, and if so, just trigger page load 82 | //listeners. Latest webkit browsers also use "interactive", and 83 | //will fire the onDOMContentLoaded before "interactive" but not after 84 | //entering "interactive" or "complete". More details: 85 | //http://dev.w3.org/html5/spec/the-end.html#the-end 86 | //http://stackoverflow.com/questions/3665561/document-readystate-of-interactive-vs-ondomcontentloaded 87 | //Hmm, this is more complicated on further use, see "firing too early" 88 | //bug: https://github.com/requirejs/domReady/issues/1 89 | //so removing the || document.readyState === "interactive" test. 90 | //There is still a window.onload binding that should get fired if 91 | //DOMContentLoaded is missed. 92 | if (document.readyState === "complete") { 93 | pageLoaded(); 94 | } 95 | } 96 | 97 | /** START OF PUBLIC API **/ 98 | 99 | /** 100 | * Registers a callback for DOM ready. If DOM is already ready, the 101 | * callback is called immediately. 102 | * @param {Function} callback 103 | */ 104 | function domReady(callback) { 105 | if (isPageLoaded) { 106 | callback(doc); 107 | } else { 108 | readyCalls.push(callback); 109 | } 110 | return domReady; 111 | } 112 | 113 | domReady.version = '2.0.1'; 114 | 115 | /** 116 | * Loader Plugin API method 117 | */ 118 | domReady.load = function (name, req, onLoad, config) { 119 | if (config.isBuild) { 120 | onLoad(null); 121 | } else { 122 | domReady(onLoad); 123 | } 124 | }; 125 | 126 | /** END OF PUBLIC API **/ 127 | 128 | return domReady; 129 | }); 130 | -------------------------------------------------------------------------------- /src/main/web/www/vendor/require/css.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Require-CSS RequireJS css! loader plugin 3 | * 0.1.2 4 | * Guy Bedford 2013 5 | * MIT 6 | */ 7 | 8 | /* 9 | * 10 | * Usage: 11 | * require(['css!./mycssFile']); 12 | * 13 | * Tested and working in (up to latest versions as of March 2013): 14 | * Android 15 | * iOS 6 16 | * IE 6 - 10 17 | * Chome 3 - 26 18 | * Firefox 3.5 - 19 19 | * Opera 10 - 12 20 | * 21 | * browserling.com used for virtual testing environment 22 | * 23 | * Credit to B Cavalier & J Hann for the IE 6 - 9 method, 24 | * refined with help from Martin Cermak 25 | * 26 | * Sources that helped along the way: 27 | * - https://developer.mozilla.org/en-US/docs/Browser_detection_using_the_user_agent 28 | * - http://www.phpied.com/when-is-a-stylesheet-really-loaded/ 29 | * - https://github.com/cujojs/curl/blob/master/src/curl/plugin/css.js 30 | * 31 | */ 32 | 33 | define(function() { 34 | //>>excludeStart('excludeRequireCss', pragmas.excludeRequireCss) 35 | if (typeof window == 'undefined') 36 | return { load: function(n, r, load){ load() } }; 37 | 38 | var head = document.getElementsByTagName('head')[0]; 39 | 40 | var engine = window.navigator.userAgent.match(/Trident\/([^ ;]*)|AppleWebKit\/([^ ;]*)|Opera\/([^ ;]*)|rv\:([^ ;]*)(.*?)Gecko\/([^ ;]*)|MSIE\s([^ ;]*)/) || 0; 41 | 42 | // use