diff --git a/.codeclimate.yml b/.codeclimate.yml new file mode 100644 index 000000000..264ffdcdc --- /dev/null +++ b/.codeclimate.yml @@ -0,0 +1,23 @@ +--- +engines: + csslint: + enabled: false + duplication: + enabled: false + config: + languages: + - javascript + eslint: + enabled: true + fixme: + enabled: true +ratings: + paths: + - "src/**.js" +exclude_paths: +- node_modules/**/* +- test/**/* +- tutorials/**/* +- components/**/* +- perf/**/* +- dist/**/* \ No newline at end of file diff --git a/.coveralls.yml b/.coveralls.yml new file mode 100644 index 000000000..603860ae4 --- /dev/null +++ b/.coveralls.yml @@ -0,0 +1,2 @@ +service_name: travis-ci +repo_token: 7PbHs1UhR24n9sP01rhKsHLXHaU4rUCvU diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 000000000..9faa37508 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,213 @@ +ecmaFeatures: + modules: true + jsx: true + +env: + amd: true + browser: true + es6: true + jquery: true + node: true + +# http://eslint.org/docs/rules/ +rules: + # Possible Errors + comma-dangle: [2, never] + no-cond-assign: 2 + no-console: 0 + no-constant-condition: 2 + no-control-regex: 2 + no-debugger: 2 + no-dupe-args: 2 + no-dupe-keys: 2 + no-duplicate-case: 2 + no-empty: 2 + no-empty-character-class: 2 + no-ex-assign: 2 + no-extra-boolean-cast: 2 + no-extra-parens: 0 + no-extra-semi: 2 + no-func-assign: 2 + no-inner-declarations: [2, functions] + no-invalid-regexp: 2 + no-irregular-whitespace: 2 + no-negated-in-lhs: 2 + no-obj-calls: 2 + no-regex-spaces: 2 + no-sparse-arrays: 2 + no-unexpected-multiline: 2 + no-unreachable: 2 + use-isnan: 2 + valid-jsdoc: 0 + valid-typeof: 2 + + # Best Practices + accessor-pairs: 2 + block-scoped-var: 0 + complexity: [2, 6] + consistent-return: 0 + curly: 0 + default-case: 0 + dot-location: 0 + dot-notation: 0 + eqeqeq: 2 + guard-for-in: 2 + no-alert: 2 + no-caller: 2 + no-case-declarations: 2 + no-div-regex: 2 + no-else-return: 0 + no-empty-label: 2 + no-empty-pattern: 2 + no-eq-null: 2 + no-eval: 2 + no-extend-native: 2 + no-extra-bind: 2 + no-fallthrough: 2 + no-floating-decimal: 0 + no-implicit-coercion: 0 + no-implied-eval: 2 + no-invalid-this: 0 + no-iterator: 2 + no-labels: 0 + no-lone-blocks: 2 + no-loop-func: 2 + no-magic-number: 0 + no-multi-spaces: 0 + no-multi-str: 0 + no-native-reassign: 2 + no-new-func: 2 + no-new-wrappers: 2 + no-new: 2 + no-octal-escape: 2 + no-octal: 2 + no-proto: 2 + no-redeclare: 2 + no-return-assign: 2 + no-script-url: 2 + no-self-compare: 2 + no-sequences: 0 + no-throw-literal: 0 + no-unused-expressions: 2 + no-useless-call: 2 + no-useless-concat: 2 + no-void: 2 + no-warning-comments: 0 + no-with: 2 + radix: 2 + vars-on-top: 0 + wrap-iife: 2 + yoda: 0 + + # Strict + strict: 0 + + # Variables + init-declarations: 0 + no-catch-shadow: 2 + no-delete-var: 2 + no-label-var: 2 + no-shadow-restricted-names: 2 + no-shadow: 0 + no-undef-init: 2 + no-undef: 0 + no-undefined: 0 + no-unused-vars: 0 + no-use-before-define: 0 + + # Node.js and CommonJS + callback-return: 2 + global-require: 2 + handle-callback-err: 2 + no-mixed-requires: 0 + no-new-require: 0 + no-path-concat: 2 + no-process-exit: 2 + no-restricted-modules: 0 + no-sync: 0 + + # Stylistic Issues + array-bracket-spacing: 0 + block-spacing: 0 + brace-style: 0 + camelcase: 0 + comma-spacing: 0 + comma-style: 0 + computed-property-spacing: 0 + consistent-this: 0 + eol-last: 0 + func-names: 0 + func-style: 0 + id-length: 0 + id-match: 0 + indent: 0 + jsx-quotes: 0 + key-spacing: 0 + linebreak-style: 0 + lines-around-comment: 0 + max-depth: 0 + max-len: 0 + max-nested-callbacks: 0 + max-params: 0 + max-statements: [2, 30] + new-cap: 0 + new-parens: 0 + newline-after-var: 0 + no-array-constructor: 0 + no-bitwise: 0 + no-continue: 0 + no-inline-comments: 0 + no-lonely-if: 0 + no-mixed-spaces-and-tabs: 0 + no-multiple-empty-lines: 0 + no-negated-condition: 0 + no-nested-ternary: 0 + no-new-object: 0 + no-plusplus: 0 + no-restricted-syntax: 0 + no-spaced-func: 0 + no-ternary: 0 + no-trailing-spaces: 0 + no-underscore-dangle: 0 + no-unneeded-ternary: 0 + object-curly-spacing: 0 + one-var: 0 + operator-assignment: 0 + operator-linebreak: 0 + padded-blocks: 0 + quote-props: 0 + quotes: 0 + require-jsdoc: 0 + semi-spacing: 0 + semi: 0 + sort-vars: 0 + space-after-keywords: 0 + space-before-blocks: 0 + space-before-function-paren: 0 + space-before-keywords: 0 + space-in-parens: 0 + space-infix-ops: 0 + space-return-throw-case: 0 + space-unary-ops: 0 + spaced-comment: 0 + wrap-regex: 0 + + # ECMAScript 6 + arrow-body-style: 0 + arrow-parens: 0 + arrow-spacing: 0 + constructor-super: 0 + generator-star-spacing: 0 + no-arrow-condition: 0 + no-class-assign: 0 + no-const-assign: 0 + no-dupe-class-members: 0 + no-this-before-super: 0 + no-var: 0 + object-shorthand: 0 + prefer-arrow-callback: 0 + prefer-const: 0 + prefer-reflect: 0 + prefer-spread: 0 + prefer-template: 0 + require-yield: 0 diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..f04d6a945 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,30 @@ +language: node_js +node_js: +- 6 +branches: + only: + - master +cache: + directories: + - node_modules +before_script: +- export CHROME_BIN=chromium-browser +- export DISPLAY=:99.0 +- sh -e /etc/init.d/xvfb start +install: +- npm install +- npm run buildAvalon +script: +- npm run build + +addons: + code_climate: + repo_token: cecb8ec105dc8e4b3f298312502f078a646f46ff +after_success: +- bash <(curl -s https://codecov.io/bash) +- codeclimate-test-reporter < lcov.info +env: + global: + - CODECOV_TOKEN: 31e8c855-5499-473e-b2b6-ba1d142fbb9e + - secure: oteqj2CHMOma5RCv4YM/QPhqMfEzDtoibgsCT+ABjTUoj36T7HDxQfgiUspv0Iv33i7TmqHBHAPFVSsF+vz00NOTejMaaFfELUuRn4BTZ5zDuz6e6VXy0jgF/7is7dVAf6cqVaQ0Fo+X+XCLg63/CaX23S3IlqS1jyfuX+fpNh8QfaIOIXlaZ8yy6pyfqb+lMfOj4TTwpyFIoyono0qSGLdaSG9BDdZK0skBPeBP3sFiwtptMmY8Mhn7lLiulU0NHl0WSfJMH9FMe9mHdhqsSrFwACKT58JbXCkKdTLjszpMv1gkl+gynzyLOV3f1WqBv/calW65PBWu7uNKNgBILGW5L3THL4Qs6unvzVngeFcZ6jf9B4dtxpS22K3Pq7SkhJOgXNiEa6RavFQm6OFSjBjILiQvMSkWA2PcAxbqDr9oEbe/snUoeK+BbYli2kV3b5TR+wyKBgn6Wms8+QbTr2N8OnAMwhgmPS4if7uqyKNPCfMy4J2HZ3OEbAPTUUYtSSWaEhXAtV5aAXI0/LWTsXsVtvnxcHGdPtN6GKJyKDqAxKWECdCU9Je6fxGcXaEzU3VTlm9HmXuC3UpTERU7Pq9vrpqxYaWtt/M1r0WAeBrPPdZ+XOpL1Qn4fWV9B259+jKI8GNg5+07H54crDBXaV04kLZODPmTe+n8Sq7PsS8= + - secure: QpQKoIDD6GlDglfXBxzuAxM/qLhEAyNO2TwzzeEG7PstLaYo94K+j4gbkiFkwbb2Oj5R/0Jtro1tSXM733DLieVZNyV7VrMkcwkkisR1KfWBynfToDHCkHqM6Rca3PiiVRFHqAh6KmkGZ7EAXXdPbjF49ZqOQMjikD5WKoMkAqagH4dREArBw+Al2qCn41JuLm+uKCJ8YpZysULTSxRoyFqvvXgxDUn6/NjM08Mo5BVmKvANKLO73qjW8y6MeXoAMuQ11YWKz6Wu++GCQvkg9/qy6P6RcOYY5C2+zjmscyI+lZZ9XWEfPNLTUhMxHX+M3LV4dlGcs46q2TX5XItnUKlRqZ2FtjI33nF+kNDD+ts7oD+H/HvsvkZC3wg4KU15XtTe2OP2oxQgOtW2S3j66IHeiWMI+5fj/nVKtmQx9Or41dDCSQQ2+7ieZA+gF4cfVkDMVJcF2joB5Wbzl4E/UoCN7lo1uLdMSPZqW6ePUtBoGlc70/oUj0w6Ct1wqYhIBwX/2P7QLjNLuwW6e0SPOsQDaa3Svqog3/mZL6lae7ARrCjLYh31E6I0mDcz2ea5Y5bzXmgXfViGaGbrN6nlWP+hpHsPvdW+yVyxfHCXDFuHJdGMxErEnIAlEA2dqPtGz8GwV03L0a7z7Vv4bomFnxf5HAtuUwQ1tJToANEGexk= diff --git a/README.md b/README.md index c3fa24d90..4ca6c2db6 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,94 @@ -#avalon 2 + +------- + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
共 {{@totalItems}} 条记录
-行1 | +行2 | +行3 | +操作 | +
{{el.a}} | +{{el.b}} | +{{el.c}} | +{{el.d}} | +
共 {{@totalItems}} 条记录
++ +
+银行卡: +
++ +
+ +共{{@array.length}}条------------------合计{{@total}}分
+ID | +姓名 | +分数 | +操作 | +
---|---|---|---|
{{el.id}} | +{{el.name}} | +{{el.score}} | +移除 | +
这里可以是复杂的HTML
'], + formatCard: function(e) { + var el = e.target + var caret = el.selectionStart + var value = el.value + var prev = value.slice(0, caret) + var sp = (prev.match(/\s/) || []).length + var curr = value.replace(/\s/g, '').replace(/(\d{4})/g, "$1 ").trim() + var now = curr.slice(0, caret) + var curSp = (now.match(/\s/) || []).length + el.value = curr + //同步到ms-duplex中的pos去 + el._ms_duplex_.pos = caret + curSp - sp + } + +}) +//成绩单 +//大家可以对比一下1.*的相同实现 +//http://www.cnblogs.com/rubylouvre/p/3213430.html +var model = avalon.define({ + $id: 'transcript', + id: '', + name: '', + score: 0, + total: 0, + array: [], + add: function() { + this.array.push({ + id: this.id, + name: this.name, + score: this.score + }) + } +}) + +model.$watch("score", function(a) { + var a = Number(a) || 0 + a = a > 100 ? 100 : a < 0 ? 0 : a //强制转换为0~100间 + model.score = a +}) +model.$watch("array", function() { + var a = 0 + model.array.forEach(function(el) { + a += el.score //求得总数 + }) + model.total = a; + model.id = "" + model.name = "" + model.score = 0 +}) +model.array = [ + { id: "d1", name: "李世民", score: 67 }, + { id: "d2", name: "赢政", score: 90 } +] +module.exports = vm \ No newline at end of file diff --git a/components/router/heredoc.js b/components/router/heredoc.js new file mode 100644 index 000000000..b46735432 --- /dev/null +++ b/components/router/heredoc.js @@ -0,0 +1,7 @@ +/*! + * 注意不要压缩这个模块 +*/ +module.exports = function heredoc(fn) { + return fn.toString().replace(/^[^\/]+\/\*!?\s?/, ''). + replace(/\*\/[^\/]+$/, '').trim().replace(/>\s*<') + } diff --git a/components/router/index.html b/components/router/index.html new file mode 100644 index 000000000..fa3d94468 --- /dev/null +++ b/components/router/index.html @@ -0,0 +1,14 @@ + + + +{{@currPath}}
+ + + diff --git a/components/router/main.js b/components/router/main.js new file mode 100644 index 000000000..f85a729d2 --- /dev/null +++ b/components/router/main.js @@ -0,0 +1,87 @@ +var avalon = require('../../dist/avalon') +var mmRouter = require('./mmRouter') +var html1 = require('./first.html') +var html2 = require('./second.html') +var html3 = require('./third.html') +var vm1 = require('./firstVm') +var vm2 = require('./secondVm') + +var root = avalon.define({ + $id: 'main', + currPath: 'aaa',//只是用于测试 + currPage: 'aaa' //这是有用的 +}) + + +var states = {} + +function addState(path, vm, html) { + states[path] = { + vm: vm, + html: html + } +} + +addState('aaa', vm1, html1) + +addState('bbb', vm2, html2) + +addState('ccc', avalon.define({ + $id: 'third', + aaa: 333 +}), html3) + + +avalon.component('ms-view', { + template: '', + defaults: { + page: ' ', + path: 'no', + + onReady: function(e) { + var path = e.vmodel.path + var state = states[path] + avalon.vmodels[state.vm.$id] = state.vm + setTimeout(function() {//必须等它扫描完这个template,才能替换 + e.vmodel.page = state.html + },100) + + }, + onDispose: function(e) { + var path = e.vmodel.path + var state = states[path] + var vm = state.vm + var render = vm.render + render && render.dispose() + delete avalon.vmodels[vm.$id] + } + } +}) + +function getPage(path) { + path = path.slice(1) + var html = '给用户用的API有