├── .travis.yml
├── yarn.lock
├── .idea
├── .name
├── encodings.xml
├── vcs.xml
├── modules.xml
├── jsLibraryMappings.xml
├── sparrow.iml
├── libraries
│ └── sparrow_node_modules.xml
└── misc.xml
├── .npmignore
├── _config.yml
├── .github
├── PULL_REQUEST_TEMPLATE.md
├── ISSUE_TEMPLATE.md
└── CONTRIBUTING.md
├── docs
├── SUMMARY.md
├── install.md
├── dom.md
├── isobject.md
├── event.md
├── style.md
├── device.md
└── method.md
├── snippets
├── SUMMARY.md
├── install.md
├── dom.md
├── isobject.md
├── event.md
├── style.md
├── device.md
└── method.md
├── .babelrc
├── bin
└── utool.js
├── test
├── sparrow.spec.js
└── test.html
├── lib
├── enumerables.js
├── cookies.js
├── extend.js
├── util
│ ├── formater.js
│ ├── i18n.js
│ ├── dataRender.js
│ ├── hotKeys.js
│ └── ripple.js
├── index.js
├── ajax.js
├── event.js
├── util.js
├── BaseComponent.js
├── core.js
├── class.js
├── fetch.js
├── env.js
├── mobileEvents.js
└── dom.js
├── .gitignore
├── src
├── enumerables.js
├── cookies.js
├── extend.js
├── util
│ ├── formater.js
│ ├── i18n.js
│ ├── dataRender.js
│ ├── hotKeys.js
│ └── ripple.js
├── locales
│ ├── zh-CN
│ │ └── uui-trans.json
│ ├── zh-TW
│ │ └── uui-trans.json
│ ├── zh
│ │ └── uui-trans.json
│ ├── zh_CN
│ │ └── uui-trans.json
│ ├── en
│ │ └── uui-trans.json
│ ├── en-US
│ │ └── uui-trans.json
│ └── en_US
│ │ └── uui-trans.json
├── fetch.js
├── ajax.js
├── index.js
├── event.js
├── util.js
├── core.js
├── class.js
├── env.js
└── mobileEvents.js
├── LICENSE
├── rollup.config.js
├── README_CN.md
├── README.md
├── package.json
├── CHANGELOG.md
├── webpack.config.js
└── .eslintrc
/.travis.yml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | sparrow
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .babelrc
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | [](https://www.npmjs.com/package/tinper-sparrow)
5 | [](https://travis-ci.org/iuap-design/tinper-sparrow)
6 | [](https://david-dm.org/iuap-design/tinper-sparrow#info=devDependencies)
7 | [](https://npmjs.org/package/tinper-sparrow)
8 |
9 |
10 | [English Document](./README.md)
11 | ## 介绍
12 | `sparrow.js`是一个短小精悍的前端基础库,它包含对DOM、CSS基本操作、多平台浏览器移动设备判断、Cookies操作、事件的绑定、日期、数字、字符串相关判断、以及浏览器自身函数不足所扩展的一系列功能.
13 |
14 | ## 快速上手
15 |
16 | ### 获取sparrow
17 |
18 | * npm 资源
19 | ```
20 | npm install tinper-sparrow
21 | ```
22 |
23 | * cdn 资源
24 | ```
25 | //design.yonyoucloud.com/static/tinper-sparrow/latest/tinper-sparrow.js
26 | ```
27 | ### 引入sparrow
28 | - ES6语法
29 | ```
30 | import { sparrow} from "tinper-sparrow"
31 |
32 | ```
33 | * HTML直接引入
34 |
35 | ```
36 |
37 |
38 | ```
39 | **注**: sparrow依赖于jquery,引入资源时需先引入jquery
40 |
41 | ### 具体使用
42 | ```
43 | sparrow.isIE //IE浏览器返回true,其他返回false
44 |
45 | sparrow.isDate(new Date()); //传入对象为Date对象返回true否则返回false
46 |
47 | ```
48 | 开发文档详见[这里](http://tinper.org/dist/sparrow/index.html)
49 |
50 | ## 如何参与贡献
51 |
52 | ### 开发及构建
53 |
54 | 开发者可以一起参与为 sparrow贡献代码,同时也可以基于 sparrow进行二次开发或封装插件。
55 |
56 | 克隆项目文件:
57 |
58 | ```
59 | $ git clone git@github.com:iuap-design/tinper-sparrow.git
60 | ```
61 |
62 | 然后进入目录安装依赖:
63 |
64 | ```
65 | $ npm install
66 | ```
67 |
68 | 接下来,编译:
69 |
70 | ```
71 | $ npm run product
72 | ```
73 |
74 | ### 反馈
75 | 如在使用过程中遇到任何问题,可以在[这里](https://github.com/iuap-design/tinper-sparrow/issues)提交issue反馈;
76 |
77 | 或者直接fork代码到你的github仓库,提交pull request给我们。
78 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # tinper sparrow
2 |
3 |
4 | [](https://www.npmjs.com/package/tinper-sparrow)
5 | [](https://travis-ci.org/iuap-design/tinper-sparrow)
6 | [](https://david-dm.org/iuap-design/tinper-sparrow#info=devDependencies)
7 | [](https://npmjs.org/package/tinper-sparrow)
8 |
9 | [中文文档](./README_CN.md)
10 | ## Introduction
11 | `sparrow.js` is a front-end base library, which contains the basic operation of DOM, browser and device judgments, Cookies operations, as well as the browser's own function expansion, etc..
12 |
13 | ## Quickstart
14 |
15 | ### Get sparrow
16 |
17 | * npm
18 | ```
19 | npm install tinper-sparrow
20 | ```
21 |
22 | * cdn
23 | ```
24 | //design.yonyoucloud.com/static/tinper-sparrow/latest/tinper-sparrow.js
25 | ```
26 | ### Introducing sparrow
27 | - ES6
28 | ```
29 | import { sparrow} from "tinper-sparrow"
30 |
31 | ```
32 | * HTML
33 |
34 | ```
35 |
36 |
37 | ```
38 | **Note**: sparrow is dependent on jQuery
39 |
40 | ### Use
41 | ```
42 | sparrow.isIE //IE browser returns true, others return to false
43 |
44 | sparrow.isDate(new Date()); //Date Object returns true, others return to false
45 |
46 | ```
47 | Read the [Develop documentation](http://tinper.org/dist/sparrow/index.html)
48 |
49 | ## Contributing
50 |
51 | ### Develop
52 |
53 | Developers can participate in the development of sparrow, but also can be based on sparrow two development
54 |
55 | clone:
56 |
57 | ```
58 | $ git clone git@github.com:iuap-design/tinper-sparrow.git
59 | ```
60 |
61 | install:
62 |
63 | ```
64 | $ npm install
65 | ```
66 |
67 | build:
68 |
69 | ```
70 | $ npm run product
71 | ```
72 |
73 | ### Feedback
74 |
75 | If you encounter any problems , submit [issues]((https://github.com/iuap-design/tinper-sparrow/issues),or pull request。
76 |
--------------------------------------------------------------------------------
/snippets/device.md:
--------------------------------------------------------------------------------
1 | ## 终端API
2 |
3 | ### isIE
4 |
5 | * 说明:
6 |
7 | 判断是否为IE浏览器
8 |
9 | * 类型:
10 |
11 | Boolean
12 |
13 | * 用法:
14 |
15 | ```
16 | u.isIE //IE浏览器返回true,其他返回false
17 |
18 | ```
19 |
20 | ### isFF
21 |
22 | * 说明:
23 |
24 | 判断是否为火狐浏览器
25 | * 类型:
26 |
27 | Boolean
28 |
29 | ### isOpera
30 |
31 | * 说明:
32 |
33 | 判断是否为Opera浏览器
34 | * 类型:
35 |
36 | Boolean
37 |
38 | ### isChrome
39 |
40 | * 说明:
41 |
42 | 判断是否为Chrome浏览器
43 | * 类型:
44 |
45 | Boolean
46 |
47 | ### isSafari
48 |
49 | * 说明:
50 |
51 | 判断是否为Safari浏览器
52 | * 类型:
53 |
54 | Boolean
55 |
56 | ### isWebkit
57 |
58 | * 说明:
59 |
60 | 判断是否为Webkit内核浏览器
61 | * 类型:
62 |
63 | Boolean
64 |
65 | ### isIE8_BEFORE
66 |
67 | * 说明:
68 |
69 | 判断是否为IE8之前的浏览器
70 | * 类型:
71 |
72 | Boolean
73 |
74 | ### isIE8
75 |
76 | * 说明:
77 |
78 | 判断是否为IE8浏览器
79 | * 类型:
80 |
81 | Boolean
82 |
83 | ### isIE8_CORE
84 |
85 | * 说明:
86 |
87 | 判断是否为IE8内核浏览器
88 | * 类型:
89 |
90 | Boolean
91 |
92 | ### isIE9
93 |
94 | * 说明:
95 |
96 | 判断是否为IE9浏览器
97 | * 类型:
98 |
99 | Boolean
100 |
101 | ### isIE9_CORE
102 |
103 | * 说明:
104 |
105 | 判断是否为IE9内核浏览器
106 | * 类型:
107 |
108 | Boolean
109 |
110 | ### isIE10
111 |
112 | * 说明:
113 |
114 | 判断是否为IE10浏览器
115 | * 类型:
116 |
117 | Boolean
118 |
119 | ### isIE11
120 |
121 | * 说明:
122 |
123 | 判断是否为IE11浏览器
124 | * 类型:
125 |
126 | Boolean
127 |
128 | ### isIOS
129 |
130 | * 说明:
131 |
132 | 判断是否为IOS系统
133 | * 类型:
134 |
135 | Boolean
136 |
137 | ### isIphone
138 |
139 | * 说明:
140 |
141 | 判断是否为iphone浏览器
142 | * 类型:
143 |
144 | Boolean
145 |
146 | ### isIPAD
147 |
148 | * 说明:
149 |
150 | 判断是否为ipad浏览器
151 | * 类型:
152 |
153 | Boolean
154 |
155 | ### isWin
156 |
157 | * 说明:
158 |
159 | 判断是否为window系统
160 | * 类型:
161 |
162 | Boolean
163 |
164 | ### isUnix
165 |
166 | * 说明:
167 |
168 | 判断是否为unix系统
169 | * 类型:
170 |
171 | Boolean
172 |
173 | ### isLinux
174 |
175 | * 说明:
176 |
177 | 判断是否为linux系统
178 | * 类型:
179 |
180 | Boolean
181 |
182 | ### isAndroid
183 |
184 | * 说明:
185 |
186 | 判断是否为安卓系统
187 | * 类型:
188 |
189 | Boolean
190 |
191 | ### isMac
192 |
193 | * 说明:
194 |
195 | 判断是否为MAC
196 | * 类型:
197 |
198 | Boolean
199 |
200 | ### hasTouch
201 |
202 | * 说明:
203 |
204 | 判断是否存在touch事件
205 | * 类型:
206 |
207 | Boolean
208 |
--------------------------------------------------------------------------------
/docs/device.md:
--------------------------------------------------------------------------------
1 | # 终端API
2 |
3 | ## # isIE
4 |
5 | * 说明:
6 |
7 | 判断是否为IE浏览器
8 |
9 | * 类型:
10 |
11 | Boolean
12 |
13 | * 用法:
14 |
15 | ```
16 | u.isIE //IE浏览器返回true,其他返回false
17 |
18 | ```
19 |
20 | ## # isFF
21 |
22 | * 说明:
23 |
24 | 判断是否为火狐浏览器
25 | * 类型:
26 |
27 | Boolean
28 |
29 | ## # isOpera
30 |
31 | * 说明:
32 |
33 | 判断是否为Opera浏览器
34 | * 类型:
35 |
36 | Boolean
37 |
38 | ## # isChrome
39 |
40 | * 说明:
41 |
42 | 判断是否为Chrome浏览器
43 | * 类型:
44 |
45 | Boolean
46 |
47 | ## # isSafari
48 |
49 | * 说明:
50 |
51 | 判断是否为Safari浏览器
52 | * 类型:
53 |
54 | Boolean
55 |
56 | ## # isWebkit
57 |
58 | * 说明:
59 |
60 | 判断是否为Webkit内核浏览器
61 | * 类型:
62 |
63 | Boolean
64 |
65 | ## # isIE8_BEFORE
66 |
67 | * 说明:
68 |
69 | 判断是否为IE8之前的浏览器
70 | * 类型:
71 |
72 | Boolean
73 |
74 | ## # isIE8
75 |
76 | * 说明:
77 |
78 | 判断是否为IE8浏览器
79 | * 类型:
80 |
81 | Boolean
82 |
83 | ## # isIE8_CORE
84 |
85 | * 说明:
86 |
87 | 判断是否为IE8内核浏览器
88 | * 类型:
89 |
90 | Boolean
91 |
92 | ## # isIE9
93 |
94 | * 说明:
95 |
96 | 判断是否为IE9浏览器
97 | * 类型:
98 |
99 | Boolean
100 |
101 | ## # isIE9_CORE
102 |
103 | * 说明:
104 |
105 | 判断是否为IE9内核浏览器
106 | * 类型:
107 |
108 | Boolean
109 |
110 | ## # isIE10
111 |
112 | * 说明:
113 |
114 | 判断是否为IE10浏览器
115 | * 类型:
116 |
117 | Boolean
118 |
119 | ## # isIE11
120 |
121 | * 说明:
122 |
123 | 判断是否为IE11浏览器
124 | * 类型:
125 |
126 | Boolean
127 |
128 | ## # isIOS
129 |
130 | * 说明:
131 |
132 | 判断是否为IOS系统
133 | * 类型:
134 |
135 | Boolean
136 |
137 | ## # isIphone
138 |
139 | * 说明:
140 |
141 | 判断是否为iphone浏览器
142 | * 类型:
143 |
144 | Boolean
145 |
146 | ## # isIPAD
147 |
148 | * 说明:
149 |
150 | 判断是否为ipad浏览器
151 | * 类型:
152 |
153 | Boolean
154 |
155 | ## # isWin
156 |
157 | * 说明:
158 |
159 | 判断是否为window系统
160 | * 类型:
161 |
162 | Boolean
163 |
164 | ## # isUnix
165 |
166 | * 说明:
167 |
168 | 判断是否为unix系统
169 | * 类型:
170 |
171 | Boolean
172 |
173 | ## # isLinux
174 |
175 | * 说明:
176 |
177 | 判断是否为linux系统
178 | * 类型:
179 |
180 | Boolean
181 |
182 | ## # isAndroid
183 |
184 | * 说明:
185 |
186 | 判断是否为安卓系统
187 | * 类型:
188 |
189 | Boolean
190 |
191 | ## # isMac
192 |
193 | * 说明:
194 |
195 | 判断是否为MAC
196 | * 类型:
197 |
198 | Boolean
199 |
200 | ## # hasTouch
201 |
202 | * 说明:
203 |
204 | 判断是否存在touch事件
205 | * 类型:
206 |
207 | Boolean
208 |
209 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tinper-sparrow",
3 | "version": "3.2.4",
4 | "description": "sparrow.js",
5 | "main": "src/index.js",
6 | "scripts": {
7 | "r-watch": "rollup -c -w",
8 | "r-build": "rollup -c",
9 | "build": "webpack --colors --progress --env.mode=build",
10 | "dev": "webpack --progress --colors --env.mode=dev",
11 | "test": "mocha --compilers js:babel-core/register --colors -w ./test/*.spec.js",
12 | "es": "babel src -d lib",
13 | "prod": "npm run es && npm run r-build",
14 | "product": "npm run es && npm run r-build",
15 | "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0",
16 | "docs": "node bin/mdconcat.js"
17 | },
18 | "repository": {
19 | "type": "git",
20 | "url": "git+https://github.com/iuap-design/tinper-sparrow.git"
21 | },
22 | "keywords": [
23 | "sparrow",
24 | "iuap",
25 | "design"
26 | ],
27 | "author": "Yonyou FED",
28 | "license": "ISC",
29 | "bugs": {
30 | "url": "https://github.com/iuap-design/tinper-sparrow/issues"
31 | },
32 | "homepage": "https://github.com/iuap-design/tinper-sparrow#readme",
33 | "dependencies": {
34 | },
35 | "devDependencies": {
36 | "babel-cli": "^6.11.4",
37 | "babel-core": "^6.11.4",
38 | "babel-eslint": "^6.1.2",
39 | "babel-polyfill": "^6.3.14",
40 | "babel-loader": "^6.2.0",
41 | "babel-preset-es2015": "^6.3.13",
42 | "babel-plugin-add-module-exports": "^0.2.1",
43 | "babel-plugin-transform-es2015-modules-commonjs": "^6.11.5",
44 | "babel-plugin-transform-es3-member-expression-literals": "^6.8.0",
45 | "babel-plugin-transform-es3-property-literals": "^6.8.0",
46 | "babel-preset-es2015-loose": "^8.0.0",
47 | "babel-preset-stage-0": "^6.5.0",
48 | "chai": "^3.5.0",
49 | "deepmerge": "^1.3.2",
50 | "eslint": "^3.1.1",
51 | "eslint-loader": "^1.4.1",
52 | "file": "^0.2.2",
53 | "fs-extra": "^2.0.0",
54 | "mocha": "^2.5.3",
55 | "webpack": "^2.2.1",
56 | "babel-plugin-external-helpers": "^6.22.0",
57 | "babel-preset-latest": "^6.24.1",
58 | "rollup": "^0.41.6",
59 | "rollup-plugin-babel": "^2.7.1",
60 | "rollup-plugin-license": "^0.3.0",
61 | "rollup-plugin-multi-entry": "^2.0.1",
62 | "rollup-plugin-multidest": "^1.0.0",
63 | "rollup-plugin-node-resolve": "^3.0.0",
64 | "rollup-plugin-uglify": "^1.0.2",
65 | "rollup-watch": "^3.2.2",
66 | "yargs": "^4.8.1"
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/locales/en/uui-trans.json:
--------------------------------------------------------------------------------
1 | {
2 | "public":{
3 | "clear": "Clear",
4 | "confirm": "Ok",
5 | "cancel": "Cancel",
6 | "day": "",
7 | "ok": "Ok"
8 | },
9 | "gridComp": {
10 | "show_column": "show hide column",
11 | "clear_set": "clear set",
12 | "no_rows": "no data",
13 | "sum": "sum:",
14 | "close": "close"
15 | },
16 | "dialog": {
17 | "info_dialog": "Info Dialog",
18 | "title":"Tips",
19 | "okText":"Confirm",
20 | "cancelText":"Cancel"
21 | },
22 | "validate": {
23 | "required": "Required!",
24 | "integer": "please input an integer!",
25 | "float": "please input a number!",
26 | "zipCode": "please input zipcode!",
27 | "phone": "please input phone number!",
28 | "email": "please input email!",
29 | "url": "please input url!",
30 | "error_zipCode": "error zipcode!",
31 | "error_phone": "error phone number!",
32 | "error_email": "error email!",
33 | "error_url": "error url!",
34 | "input_minlength": "Input length can not be less than ",
35 | "input_maxlength": "Input length can not be greater than ",
36 | "input_unit": " characters",
37 | "input_maxvalue": "The input value can not be greater than ",
38 | "input_minvalue": "The input value can not be less than ",
39 | "input_equalMax": "The input value can not be greater than or equal to ",
40 | "input_equalMin": "The input value can not be less than or equal to ",
41 | "landline": "please input landline number!",
42 | "datetime":"please input datetime",
43 | "phoneNumber":"please input correct number",
44 | "error_integer":"error integer",
45 | "error_float":"error float",
46 | "error_landline":"error landline",
47 | "error_datetime":"error datetime",
48 | "error_phoneNumber":"error phoneNumber"
49 |
50 | },
51 | "date":{
52 | "months": ["January","February","March","April","May","June","July","August","September","October","November","December"],
53 | "monthsShort": ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],
54 | "weekdays": ["Sunday","Monday","Tuesday","Wednesday","Thurday","Friday","Saturday"],
55 | "weekdaysShort": ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],
56 | "weekdaysMin": ["S","M","T","W","T","F","S"]
57 | },
58 | "pagination":{
59 | "totalText":"Total ",
60 | "listText": "lists",
61 | "pageText":"Page",
62 | "showText":"Show ",
63 | "toText":"To "
64 | },
65 | "dataTable":{
66 | "Y":"Yes",
67 | "N":"No"
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/locales/en-US/uui-trans.json:
--------------------------------------------------------------------------------
1 | {
2 | "public":{
3 | "clear": "Clear",
4 | "confirm": "Ok",
5 | "cancel": "Cancel",
6 | "day": "",
7 | "ok": "Ok"
8 | },
9 | "gridComp": {
10 | "show_column": "show hide column",
11 | "clear_set": "clear set",
12 | "no_rows": "no data",
13 | "sum": "sum:",
14 | "close": "close"
15 | },
16 | "dialog": {
17 | "info_dialog": "Info Dialog",
18 | "title":"Tips",
19 | "okText":"Confirm",
20 | "cancelText":"Cancel"
21 | },
22 | "validate": {
23 | "required": "Required!",
24 | "integer": "please input an integer!",
25 | "float": "please input a number!",
26 | "zipCode": "please input zipcode!",
27 | "phone": "please input phone number!",
28 | "email": "please input email!",
29 | "url": "please input url!",
30 | "error_zipCode": "error zipcode!",
31 | "error_phone": "error phone number!",
32 | "error_email": "error email!",
33 | "error_url": "error url!",
34 | "input_minlength": "Input length can not be less than ",
35 | "input_maxlength": "Input length can not be greater than ",
36 | "input_unit": " characters",
37 | "input_maxvalue": "The input value can not be greater than ",
38 | "input_minvalue": "The input value can not be less than ",
39 | "input_equalMax": "The input value can not be greater than or equal to ",
40 | "input_equalMin": "The input value can not be less than or equal to ",
41 | "landline": "please input landline number!",
42 | "datetime":"please input datetime",
43 | "phoneNumber":"please input correct number",
44 | "error_integer":"error integer",
45 | "error_float":"error float",
46 | "error_landline":"error landline",
47 | "error_datetime":"error datetime",
48 | "error_phoneNumber":"error phoneNumber"
49 |
50 | },
51 | "date":{
52 | "months": ["January","February","March","April","May","June","July","August","September","October","November","December"],
53 | "monthsShort": ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],
54 | "weekdays": ["Sunday","Monday","Tuesday","Wednesday","Thurday","Friday","Saturday"],
55 | "weekdaysShort": ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],
56 | "weekdaysMin": ["S","M","T","W","T","F","S"]
57 | },
58 | "pagination":{
59 | "totalText":"Total ",
60 | "listText": "lists",
61 | "pageText":"Page",
62 | "showText":"Show ",
63 | "toText":"To "
64 | },
65 | "dataTable":{
66 | "Y":"Yes",
67 | "N":"No"
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/locales/en_US/uui-trans.json:
--------------------------------------------------------------------------------
1 | {
2 | "public":{
3 | "clear": "Clear",
4 | "confirm": "Ok",
5 | "cancel": "Cancel",
6 | "day": "",
7 | "ok": "Ok"
8 | },
9 | "gridComp": {
10 | "show_column": "show hide column",
11 | "clear_set": "clear set",
12 | "no_rows": "no data",
13 | "sum": "sum:",
14 | "close": "close"
15 | },
16 | "dialog": {
17 | "info_dialog": "Info Dialog",
18 | "title":"Tips",
19 | "okText":"Confirm",
20 | "cancelText":"Cancel"
21 | },
22 | "validate": {
23 | "required": "Required!",
24 | "integer": "please input an integer!",
25 | "float": "please input a number!",
26 | "zipCode": "please input zipcode!",
27 | "phone": "please input phone number!",
28 | "email": "please input email!",
29 | "url": "please input url!",
30 | "error_zipCode": "error zipcode!",
31 | "error_phone": "error phone number!",
32 | "error_email": "error email!",
33 | "error_url": "error url!",
34 | "input_minlength": "Input length can not be less than ",
35 | "input_maxlength": "Input length can not be greater than ",
36 | "input_unit": " characters",
37 | "input_maxvalue": "The input value can not be greater than ",
38 | "input_minvalue": "The input value can not be less than ",
39 | "input_equalMax": "The input value can not be greater than or equal to ",
40 | "input_equalMin": "The input value can not be less than or equal to ",
41 | "landline": "please input landline number!",
42 | "datetime":"please input datetime",
43 | "phoneNumber":"please input correct number",
44 | "error_integer":"error integer",
45 | "error_float":"error float",
46 | "error_landline":"error landline",
47 | "error_datetime":"error datetime",
48 | "error_phoneNumber":"error phoneNumber"
49 |
50 | },
51 | "date":{
52 | "months": ["January","February","March","April","May","June","July","August","September","October","November","December"],
53 | "monthsShort": ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],
54 | "weekdays": ["Sunday","Monday","Tuesday","Wednesday","Thurday","Friday","Saturday"],
55 | "weekdaysShort": ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],
56 | "weekdaysMin": ["S","M","T","W","T","F","S"]
57 | },
58 | "pagination":{
59 | "totalText":"Total ",
60 | "listText": "lists",
61 | "pageText":"Page",
62 | "showText":"Show ",
63 | "toText":"To "
64 | } ,
65 | "dataTable":{
66 | "Y":"Yes",
67 | "N":"No"
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/lib/util/dataRender.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : Sparrow data display formater
3 | * Author : Kvkens(yueming@yonyou.com)
4 | * Date : 2016-07-28 15:39:01
5 | */
6 | import { core } from '../core';
7 | import { NumberFormater } from './formater';
8 | import { AddressMasker, NumberMasker, CurrencyMasker, PercentMasker, PhoneNumberMasker } from './masker';
9 | import { date } from './dateUtils';
10 |
11 | var floatRender = function floatRender(value, precision) {
12 | var trueValue = value;
13 | if (typeof value === 'undefined' || value === null) return value;
14 | //value 为 ko对象
15 | if (typeof value === 'function') trueValue = value();
16 | var maskerMeta = core.getMaskerMeta('float') || {};
17 | if (typeof precision === 'number') maskerMeta.precision = precision;
18 | var formater = new NumberFormater(maskerMeta.precision);
19 | var masker = new NumberMasker(maskerMeta);
20 | return masker.format(formater.format(trueValue)).value;
21 | };
22 |
23 | var integerRender = function integerRender(value) {
24 | var trueValue = value;
25 | if (typeof value === 'undefined' || value === null) return value;
26 | //value 为 ko对象
27 | if (typeof value === 'function') trueValue = value();
28 | return trueValue;
29 | };
30 |
31 | var _dateRender = function _dateRender(value, format, type) {
32 | var trueValue = value;
33 | if (typeof value === 'undefined' || value === null) return value;
34 | //value 为 ko对象
35 | if (typeof value === 'function') trueValue = value();
36 | var maskerMeta = core.getMaskerMeta(type) || {};
37 | if (typeof format != 'undefined') maskerMeta.format = format;
38 | var maskerValue = date.format(trueValue, maskerMeta.format);
39 | return maskerValue;
40 | };
41 |
42 | var dateRender = function dateRender(value, format) {
43 | return _dateRender(value, format, 'date');
44 | };
45 |
46 | var dateTimeRender = function dateTimeRender(value, format) {
47 | return _dateRender(value, format, 'datetime');
48 | };
49 |
50 | var timeRender = function timeRender(value, format) {
51 | return _dateRender(value, format, 'time');
52 | };
53 |
54 | var percentRender = function percentRender(value) {
55 | var trueValue = value;
56 | if (typeof value === 'undefined' || value === null) return value;
57 | //value 为 ko对象
58 | if (typeof value === 'function') trueValue = value();
59 | var maskerMeta = core.getMaskerMeta('percent') || {};
60 | var masker = new PercentMasker(maskerMeta);
61 | var maskerValue = masker.format(trueValue);
62 | return maskerValue && maskerValue.value ? maskerValue.value : '';
63 | };
64 |
65 | var phoneNumberRender = function phoneNumberRender() {
66 | var trueValue = value;
67 | if (typeof value === 'undefined' || value === null) return value;
68 | //value 为 ko对象
69 | if (typeof value === 'function') trueValue = value();
70 | var maskerMeta = core.getMaskerMeta('phoneNumber') || {};
71 | var masker = new PhoneNumberMasker(maskerMeta);
72 | var maskerValue = masker.format(trueValue);
73 | return maskerValue && maskerValue.value ? maskerValue.value : '';
74 | };
75 |
76 | var dateToUTCString = function dateToUTCString(date) {
77 | if (!date) return '';
78 | if (date.indexOf("-") > -1) date = date.replace(/\-/g, "/");
79 | var utcString = Date.parse(date);
80 | if (isNaN(utcString)) return "";
81 | return utcString;
82 | };
83 |
84 | export { floatRender, integerRender, dateRender, dateTimeRender, timeRender, percentRender, dateToUTCString, phoneNumberRender };
--------------------------------------------------------------------------------
/lib/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : Sparrow entry index
3 | * Author : Kvkens(yueming@yonyou.com)
4 | * Date : 2016-08-04 09:48:36
5 | */
6 |
7 | import { extend } from './extend';
8 | import { setCookie, getCookie } from './cookies';
9 | import { createShellObject, execIgnoreError, getFunction, getJSObject, isDate, isNumber, isArray, isEmptyObject, inArray, isDomElement, each } from './util';
10 | import { env } from './env';
11 | import { on, off, trigger, stopEvent } from './event';
12 | import { event } from './mobileEvents';
13 | import { addClass, removeClass, hasClass, toggleClass, closest, css, wrap, getStyle, getZIndex, makeDOM, makeModal, getOffset, getScroll, showPanelByEle } from './dom';
14 | import { Class } from './class';
15 | import { core } from './core';
16 |
17 | import { ajax } from './ajax';
18 |
19 | import { get, post } from './fetch';
20 |
21 | import { floatRender, integerRender, dateRender, dateTimeRender, timeRender, percentRender, dateToUTCString } from './util/dataRender';
22 |
23 | import { NumberFormater, DateFormater } from './util/formater';
24 |
25 | import { date } from './util/dateUtils';
26 | import { AddressMasker, NumberMasker, CurrencyMasker, PercentMasker } from './util/masker';
27 |
28 | import { hotkeys } from './util/hotKeys';
29 |
30 | import { Ripple } from './util/ripple';
31 |
32 | import { RSAUtils, BigInt, BarrettMu, twoDigit } from './util/rsautils';
33 |
34 | import { trans } from './util/i18n';
35 |
36 | //公开接口、属性对外暴露
37 | var api = {
38 | ajax: ajax,
39 | get: get,
40 | post: post,
41 | extend: extend,
42 | setCookie: setCookie,
43 | getCookie: getCookie,
44 | createShellObject: createShellObject,
45 | execIgnoreError: execIgnoreError,
46 | getFunction: getFunction,
47 | getJSObject: getJSObject,
48 | isDate: isDate,
49 | isNumber: isNumber,
50 | isArray: isArray,
51 | isEmptyObject: isEmptyObject,
52 | inArray: inArray,
53 | isDomElement: isDomElement,
54 | each: each,
55 | on: on,
56 | off: off,
57 | trigger: trigger,
58 | stopEvent: stopEvent,
59 | event: event,
60 | addClass: addClass,
61 | removeClass: removeClass,
62 | hasClass: hasClass,
63 | toggleClass: toggleClass,
64 | closest: closest,
65 | css: css,
66 | wrap: wrap,
67 | getStyle: getStyle,
68 | getZIndex: getZIndex,
69 | makeDOM: makeDOM,
70 | makeModal: makeModal,
71 | getOffset: getOffset,
72 | getScroll: getScroll,
73 | showPanelByEle: showPanelByEle,
74 | Class: Class,
75 | core: core,
76 | floatRender: floatRender,
77 | integerRender: integerRender,
78 | dateRender: dateRender,
79 | dateTimeRender: dateTimeRender,
80 | timeRender: timeRender,
81 | percentRender: percentRender,
82 | dateToUTCString: dateToUTCString,
83 | date: date,
84 | NumberFormater: NumberFormater,
85 | DateFormater: DateFormater,
86 | AddressMasker: AddressMasker,
87 | NumberMasker: NumberMasker,
88 | CurrencyMasker: CurrencyMasker,
89 | PercentMasker: PercentMasker,
90 | hotkeys: hotkeys,
91 | Ripple: Ripple,
92 | RSAUtils: RSAUtils,
93 | BigInt: BigInt,
94 | BarrettMu: BarrettMu,
95 | twoDigit: twoDigit,
96 | trans: trans
97 |
98 | };
99 | extend(api, env);
100 | // export api;
101 | //export default api;
102 | extend(api, window.u || {});
103 |
104 | window.u = api;
105 | window.iweb = {};
106 | window.iweb.browser = window.u;
107 | window.sparrow = window.u;
108 | export { u, sparrow };
--------------------------------------------------------------------------------
/src/util/dataRender.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : Sparrow data display formater
3 | * Author : Kvkens(yueming@yonyou.com)
4 | * Date : 2016-07-28 15:39:01
5 | */
6 | import {
7 | core
8 | } from '../core';
9 | import {
10 | NumberFormater
11 | } from './formater';
12 | import {
13 | AddressMasker,
14 | NumberMasker,
15 | CurrencyMasker,
16 | PercentMasker,
17 | PhoneNumberMasker
18 | } from './masker';
19 | import {
20 | date
21 | } from './dateUtils';
22 |
23 | var floatRender = function(value, precision) {
24 | var trueValue = value;
25 | if(typeof value === 'undefined' || value === null)
26 | return value;
27 | //value 为 ko对象
28 | if(typeof value === 'function')
29 | trueValue = value();
30 | var maskerMeta = core.getMaskerMeta('float') || {};
31 | if(typeof precision === 'number')
32 | maskerMeta.precision = precision;
33 | var formater = new NumberFormater(maskerMeta.precision);
34 | var masker = new NumberMasker(maskerMeta);
35 | return masker.format(formater.format(trueValue)).value;
36 | };
37 |
38 | var integerRender = function(value) {
39 | var trueValue = value;
40 | if(typeof value === 'undefined' || value === null)
41 | return value;
42 | //value 为 ko对象
43 | if(typeof value === 'function')
44 | trueValue = value();
45 | return trueValue
46 | };
47 |
48 | var _dateRender = function(value, format, type) {
49 | var trueValue = value;
50 | if(typeof value === 'undefined' || value === null)
51 | return value
52 | //value 为 ko对象
53 | if(typeof value === 'function')
54 | trueValue = value()
55 | var maskerMeta = core.getMaskerMeta(type) || {}
56 | if(typeof format != 'undefined')
57 | maskerMeta.format = format
58 | var maskerValue = date.format(trueValue, maskerMeta.format);
59 | return maskerValue;
60 | }
61 |
62 | var dateRender = function(value, format) {
63 | return _dateRender(value, format, 'date');
64 | };
65 |
66 | var dateTimeRender = function(value, format) {
67 | return _dateRender(value, format, 'datetime');
68 | };
69 |
70 | var timeRender = function(value, format) {
71 | return _dateRender(value, format, 'time');
72 | };
73 |
74 | var percentRender = function(value) {
75 | var trueValue = value
76 | if(typeof value === 'undefined' || value === null)
77 | return value
78 | //value 为 ko对象
79 | if(typeof value === 'function')
80 | trueValue = value()
81 | var maskerMeta = core.getMaskerMeta('percent') || {}
82 | var masker = new PercentMasker(maskerMeta);
83 | var maskerValue = masker.format(trueValue);
84 | return(maskerValue && maskerValue.value) ? maskerValue.value : '';
85 | };
86 |
87 | var phoneNumberRender = function () {
88 | var trueValue = value
89 | if(typeof value === 'undefined' || value === null)
90 | return value
91 | //value 为 ko对象
92 | if(typeof value === 'function')
93 | trueValue = value()
94 | var maskerMeta = core.getMaskerMeta('phoneNumber') || {}
95 | var masker = new PhoneNumberMasker(maskerMeta);
96 | var maskerValue = masker.format(trueValue);
97 | return(maskerValue && maskerValue.value) ? maskerValue.value : '';
98 | }
99 |
100 | var dateToUTCString = function(date) {
101 | if(!date) return ''
102 | if(date.indexOf("-") > -1)
103 | date = date.replace(/\-/g, "/");
104 | var utcString = Date.parse(date);
105 | if(isNaN(utcString)) return "";
106 | return utcString;
107 | }
108 |
109 | export {
110 | floatRender,
111 | integerRender,
112 | dateRender,
113 | dateTimeRender,
114 | timeRender,
115 | percentRender,
116 | dateToUTCString,
117 | phoneNumberRender
118 | };
119 |
--------------------------------------------------------------------------------
/src/fetch.js:
--------------------------------------------------------------------------------
1 | import { extend } from './extend';
2 | const getHost = (key = 'api') => {
3 | const hosts = {
4 | api: {
5 | production: process.env.HOST || "",
6 | development: process.env.HOST || "",
7 | }
8 | };
9 | return hosts[key][process.env.NODE_ENV];
10 | };
11 |
12 | const fetchTools = {
13 | params(params) {
14 | try {
15 | return Object.keys(params).map((key) => {
16 | let param = params[key];
17 | switch (typeof param) {
18 | case 'object':
19 | param = escape(JSON.stringify(param));
20 | break;
21 | case 'undefined':
22 | param = '';
23 | break;
24 | default:
25 | break;
26 | }
27 | return `${key}=${param}`;
28 | }).join('&');
29 | } catch (e) {
30 | console.log('error in urlParams');
31 | return '';
32 | }
33 | },
34 | fetch(url, options) {
35 | return fetch(url, options).then((response) => {
36 | if (response.ok) {
37 | return response.text().then((text) => {
38 | if (text) {
39 | let result = {
40 | success: false,
41 | message: '接口请求失败',
42 | };
43 | try {
44 | result = JSON.parse(text);
45 | } catch (e) {
46 | return Promise.reject(new Error('接口返回数据无法解析'));
47 | }
48 | const { success, data, message } = result;
49 | if (success) {
50 | return Promise.resolve(data);
51 | }
52 | return Promise.reject(message);
53 | }
54 | return Promise.reject(new Error('接口未返回数据'));
55 | });
56 | }
57 | return Promise.reject(new Error('请求失败'));
58 | });
59 | },
60 | options(method = 'get', options = {}) {
61 | return extend({
62 | method: method.toUpperCase(),
63 | credentials: 'include',
64 | cache: 'no-cache',
65 | headers: {
66 | 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
67 | 'isAjax': 1,
68 | },
69 | },options);
70 | },
71 | urlMaker(url) {
72 | if (!url) {
73 | throw new Error('has no url!');
74 | } else if (url.indexOf('http') !== 0) {
75 | url = `${getHost()}${url}`;
76 | }
77 | return url;
78 | },
79 | };
80 |
81 | export function post(oriUrl, oriParams = {}) {
82 | const {
83 | params,
84 | fetch,
85 | options: optionsMaker,
86 | urlMaker,
87 | } = fetchTools;
88 | const data = params(oriParams);
89 | const options = optionsMaker('post');
90 | options.headers['Content-Type'] = 'application/json;charset=UTF-8';
91 | try {
92 | options.body = JSON.stringify(oriParams);
93 | } catch (e) {
94 | return Promise.reject(e);
95 | }
96 | return fetch(urlMaker(oriUrl), options);
97 | }
98 |
99 | export function get(oriUrl, oriParams = {}) {
100 | const {
101 | params,
102 | fetch,
103 | options,
104 | urlMaker
105 | } = fetchTools;
106 |
107 | const data = params(oriParams);
108 | let url = urlMaker(oriUrl);
109 | if (data) {
110 | url = `${url}?${data}`;
111 | }
112 | return fetch(url, options());
113 | }
--------------------------------------------------------------------------------
/src/ajax.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : Sparrow ajax
3 | * Author : Kvkens(yueming@yonyou.com)
4 | * Date : 2016-07-28 19:06:36
5 | */
6 |
7 | import {env} from './env';
8 |
9 | var XmlHttp = {
10 | get: "get",
11 | post: "post",
12 | reqCount: 4,
13 | createXhr: function() {
14 | var xmlhttp = null;
15 | /*if (window.XMLHttpRequest) {
16 | xmlhttp = new XMLHttpRequest();
17 | } else {
18 | xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
19 | }*/
20 | if(env.isIE8) {
21 | xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); //IE低版本创建XMLHTTP
22 | } else if(env.isIE) {
23 | xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); //IE高版本创建XMLHTTP
24 | } else if(window.XMLHttpRequest) {
25 | xmlhttp = new XMLHttpRequest();
26 | }
27 | return xmlhttp;
28 | },
29 | ajax: function(_json) {
30 | var url = _json["url"];
31 | var callback = _json["success"];
32 | var async = (_json["async"] == undefined ? true : _json["async"]);
33 | var error = _json["error"];
34 | var params = _json["data"] || {};
35 | var method = (_json["type"] == undefined ? XmlHttp.post : _json["type"]).toLowerCase();
36 | var gzipFlag = params.compressType;
37 | url = XmlHttp.serializeUrl(url);
38 | params = XmlHttp.serializeParams(params);
39 | if(method == XmlHttp.get && params != null) {
40 | url += ("&" + params);
41 | params = null; //如果是get请求,保证最终会执行send(null)
42 | }
43 |
44 | var xmlhttp = XmlHttp.createXhr();
45 | //xmlhttp.open(method, url+ escape(new Date()), async);
46 | xmlhttp.open(method, url, async);
47 |
48 | if(method == XmlHttp.post) {
49 | xmlhttp.setRequestHeader("Content-type",
50 | "application/x-www-form-urlencoded;charset=UTF-8");
51 | }
52 |
53 | var execount = 0;
54 | // 异步
55 | if(async) {
56 | // readyState 从 1~4发生4次变化
57 | xmlhttp.onreadystatechange = function() {
58 | execount++;
59 | // 等待readyState状态不再变化之后,再执行回调函数
60 | //if (execount == XmlHttp.reqCount) {// 火狐下存在问题,修改判断方式
61 | if(xmlhttp.readyState == XmlHttp.reqCount) {
62 | XmlHttp.execBack(xmlhttp, callback, error);
63 | }
64 | };
65 | // send方法要在在回调函数之后执行
66 | xmlhttp.send(params);
67 | } else {
68 | // 同步 readyState 直接变为 4
69 | // 并且 send 方法要在回调函数之前执行
70 | xmlhttp.send(params);
71 | XmlHttp.execBack(xmlhttp, callback, error);
72 | }
73 | },
74 | execBack: function(xmlhttp, callback, error) {
75 | //if (xmlhttp.readyState == 4
76 | if(xmlhttp.status == 200 || xmlhttp.status == 304 || xmlhttp.readyState == 4) {
77 | callback(xmlhttp.responseText, xmlhttp.status, xmlhttp);
78 | } else {
79 | if(error) {
80 | error(xmlhttp.responseText, xmlhttp.status, xmlhttp);
81 | } else {
82 | var errorMsg = "no error callback function!";
83 | if(xmlhttp.responseText) {
84 | errorMsg = xmlhttp.responseText;
85 | }
86 | alert(errorMsg);
87 | // throw errorMsg;
88 | }
89 | }
90 | },
91 | serializeUrl: function(url) {
92 | var cache = "cache=" + Math.random();
93 | if(url.indexOf("?") > 0) {
94 | url += ("&" + cache);
95 | } else {
96 | url += ("?" + cache);
97 | }
98 | return url;
99 | },
100 | serializeParams: function(params) {
101 | var ud = undefined;
102 | if(ud == params || params == null || params == "") {
103 | return null;
104 | }
105 | if(params.constructor == Object) {
106 | var result = "";
107 | for(var p in params) {
108 | result += (p + "=" + encodeURIComponent(params[p]) + "&");
109 | }
110 | return result.substring(0, result.length - 1);
111 | }
112 | return params;
113 | }
114 | };
115 |
116 |
117 | var ajax = XmlHttp.ajax;
118 | export {ajax};
119 |
--------------------------------------------------------------------------------
/lib/ajax.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : Sparrow ajax
3 | * Author : Kvkens(yueming@yonyou.com)
4 | * Date : 2016-07-28 19:06:36
5 | */
6 |
7 | import { env } from './env';
8 |
9 | var XmlHttp = {
10 | get: "get",
11 | post: "post",
12 | reqCount: 4,
13 | createXhr: function createXhr() {
14 | var xmlhttp = null;
15 | /*if (window.XMLHttpRequest) {
16 | xmlhttp = new XMLHttpRequest();
17 | } else {
18 | xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
19 | }*/
20 | if (env.isIE8) {
21 | xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); //IE低版本创建XMLHTTP
22 | } else if (env.isIE) {
23 | xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); //IE高版本创建XMLHTTP
24 | } else if (window.XMLHttpRequest) {
25 | xmlhttp = new XMLHttpRequest();
26 | }
27 | return xmlhttp;
28 | },
29 | ajax: function ajax(_json) {
30 | var url = _json["url"];
31 | var callback = _json["success"];
32 | var async = _json["async"] == undefined ? true : _json["async"];
33 | var error = _json["error"];
34 | var params = _json["data"] || {};
35 | var method = (_json["type"] == undefined ? XmlHttp.post : _json["type"]).toLowerCase();
36 | var gzipFlag = params.compressType;
37 | url = XmlHttp.serializeUrl(url);
38 | params = XmlHttp.serializeParams(params);
39 | if (method == XmlHttp.get && params != null) {
40 | url += "&" + params;
41 | params = null; //如果是get请求,保证最终会执行send(null)
42 | }
43 |
44 | var xmlhttp = XmlHttp.createXhr();
45 | //xmlhttp.open(method, url+ escape(new Date()), async);
46 | xmlhttp.open(method, url, async);
47 |
48 | if (method == XmlHttp.post) {
49 | xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded;charset=UTF-8");
50 | }
51 |
52 | var execount = 0;
53 | // 异步
54 | if (async) {
55 | // readyState 从 1~4发生4次变化
56 | xmlhttp.onreadystatechange = function () {
57 | execount++;
58 | // 等待readyState状态不再变化之后,再执行回调函数
59 | //if (execount == XmlHttp.reqCount) {// 火狐下存在问题,修改判断方式
60 | if (xmlhttp.readyState == XmlHttp.reqCount) {
61 | XmlHttp.execBack(xmlhttp, callback, error);
62 | }
63 | };
64 | // send方法要在在回调函数之后执行
65 | xmlhttp.send(params);
66 | } else {
67 | // 同步 readyState 直接变为 4
68 | // 并且 send 方法要在回调函数之前执行
69 | xmlhttp.send(params);
70 | XmlHttp.execBack(xmlhttp, callback, error);
71 | }
72 | },
73 | execBack: function execBack(xmlhttp, callback, error) {
74 | //if (xmlhttp.readyState == 4
75 | if (xmlhttp.status == 200 || xmlhttp.status == 304 || xmlhttp.readyState == 4) {
76 | callback(xmlhttp.responseText, xmlhttp.status, xmlhttp);
77 | } else {
78 | if (error) {
79 | error(xmlhttp.responseText, xmlhttp.status, xmlhttp);
80 | } else {
81 | var errorMsg = "no error callback function!";
82 | if (xmlhttp.responseText) {
83 | errorMsg = xmlhttp.responseText;
84 | }
85 | alert(errorMsg);
86 | // throw errorMsg;
87 | }
88 | }
89 | },
90 | serializeUrl: function serializeUrl(url) {
91 | var cache = "cache=" + Math.random();
92 | if (url.indexOf("?") > 0) {
93 | url += "&" + cache;
94 | } else {
95 | url += "?" + cache;
96 | }
97 | return url;
98 | },
99 | serializeParams: function serializeParams(params) {
100 | var ud = undefined;
101 | if (ud == params || params == null || params == "") {
102 | return null;
103 | }
104 | if (params.constructor == Object) {
105 | var result = "";
106 | for (var p in params) {
107 | result += p + "=" + encodeURIComponent(params[p]) + "&";
108 | }
109 | return result.substring(0, result.length - 1);
110 | }
111 | return params;
112 | }
113 | };
114 |
115 | var ajax = XmlHttp.ajax;
116 | export { ajax };
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 |
2 | ## [3.2.4](https://github.com/iuap-design/tinper-sparrow/compare/v3.2.5...v3.2.4) (2017-08-07)
3 |
4 |
5 |
6 |
7 | ## [3.2.5](https://github.com/iuap-design/tinper-sparrow/compare/v3.2.4...v3.2.5) (2017-06-28)
8 |
9 |
10 |
11 |
12 | ## [3.2.3](https://github.com/iuap-design/tinper-sparrow/compare/v3.2.2...v3.2.3) (2017-06-23)
13 |
14 |
15 |
16 |
17 | ## [3.2.2](https://github.com/iuap-design/tinper-sparrow/compare/v3.2.1...v3.2.2) (2017-05-05)
18 |
19 |
20 |
21 |
22 | ## [3.2.1](https://github.com/iuap-design/tinper-sparrow/compare/v3.2.0...v3.2.1) (2017-04-06)
23 |
24 |
25 |
26 |
27 | # [3.2.0](https://github.com/iuap-design/tinper-sparrow/compare/v3.1.27...v3.2.0) (2017-03-22)
28 |
29 |
30 |
31 |
32 | ## [3.1.27](https://github.com/iuap-design/tinper-sparrow/compare/v3.1.26...v3.1.27) (2017-02-23)
33 |
34 |
35 |
36 |
37 | ## [3.1.26](https://github.com/iuap-design/tinper-sparrow/compare/v3.1.25...v3.1.26) (2017-02-20)
38 |
39 |
40 |
41 |
42 | ## [3.1.25](https://github.com/iuap-design/tinper-sparrow/compare/v3.1.22...v3.1.25) (2017-02-10)
43 |
44 |
45 |
46 |
47 | ## [3.1.22](https://github.com/iuap-design/tinper-sparrow/compare/v3.1.21...v3.1.22) (2017-01-12)
48 |
49 |
50 |
51 |
52 | ## [3.1.21](https://github.com/iuap-design/tinper-sparrow/compare/v3.1.20...v3.1.21) (2017-01-05)
53 |
54 |
55 |
56 |
57 | ## [3.1.20](https://github.com/iuap-design/tinper-sparrow/compare/v3.1.19...v3.1.20) (2017-01-05)
58 |
59 |
60 | ### Bug Fixes
61 |
62 | * isNumber判断 ([ebd1848](https://github.com/iuap-design/tinper-sparrow/commit/ebd1848))
63 | * isNumber判断 ([ff8b74f](https://github.com/iuap-design/tinper-sparrow/commit/ff8b74f))
64 | * setFmormat输入undefined造成bug ([e7bb1e3](https://github.com/iuap-design/tinper-sparrow/commit/e7bb1e3))
65 |
66 |
67 |
68 |
69 | ## [3.1.18](https://github.com/iuap-design/tinper-sparrow/compare/v3.1.17...v3.1.18) (2016-12-20)
70 |
71 |
72 |
73 |
74 | ## [3.1.17](https://github.com/iuap-design/tinper-sparrow/compare/v3.1.16...v3.1.17) (2016-12-14)
75 |
76 |
77 | ### Bug Fixes
78 |
79 | * addClass ie9兼容 ([b2bb857](https://github.com/iuap-design/tinper-sparrow/commit/b2bb857))
80 | * i18n bug ([06ed3fc](https://github.com/iuap-design/tinper-sparrow/commit/06ed3fc))
81 | * removeClass hasClass bug other2jquery ([6fec69e](https://github.com/iuap-design/tinper-sparrow/commit/6fec69e))
82 |
83 |
84 |
85 |
86 | ## [3.1.15](https://github.com/iuap-design/tinper-sparrow/compare/v3.1.14...v3.1.15) (2016-11-29)
87 |
88 |
89 |
90 |
91 | ## [3.1.14](https://github.com/iuap-design/tinper-sparrow/compare/v3.1.13...v3.1.14) (2016-11-24)
92 |
93 |
94 |
95 |
96 | ## [3.1.13](https://github.com/iuap-design/tinper-sparrow/compare/v3.1.12...v3.1.13) (2016-11-18)
97 |
98 |
99 |
100 |
101 | ## [3.1.12](https://github.com/iuap-design/tinper-sparrow/compare/v3.1.10...v3.1.12) (2016-11-17)
102 |
103 |
104 |
105 |
106 | ## [3.1.10](https://github.com/iuap-design/tinper-sparrow/compare/v3.1.9...v3.1.10) (2016-11-17)
107 |
108 |
109 | ### Bug Fixes
110 |
111 | * IUAPDESIGN:云表单:日期年月ios获取bug ([02c2f80](https://github.com/iuap-design/tinper-sparrow/commit/02c2f80))
112 |
113 |
114 |
115 |
116 | ## [3.1.7](https://github.com/iuap-design/tinper-sparrow/compare/v3.1.1...v3.1.7) (2016-11-04)
117 |
118 |
119 |
120 |
121 | ## 3.1.1 (2016-10-17)
122 |
123 |
124 |
125 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : Sparrow entry index
3 | * Author : Kvkens(yueming@yonyou.com)
4 | * Date : 2016-08-04 09:48:36
5 | */
6 |
7 | import {extend} from './extend';
8 | import {
9 | setCookie,
10 | getCookie
11 | } from './cookies';
12 | import {
13 | createShellObject,
14 | execIgnoreError,
15 | getFunction,
16 | getJSObject,
17 | isDate,
18 | isNumber,
19 | isArray,
20 | isEmptyObject,
21 | inArray,
22 | isDomElement,
23 | each
24 | } from './util';
25 | import {
26 | env
27 | } from './env';
28 | import {
29 | on,
30 | off,
31 | trigger,
32 | stopEvent
33 | } from './event';
34 | import{
35 | event
36 | } from './mobileEvents'
37 | import {
38 | addClass,
39 | removeClass,
40 | hasClass,
41 | toggleClass,
42 | closest,
43 | css,
44 | wrap,
45 | getStyle,
46 | getZIndex,
47 | makeDOM,
48 | makeModal,
49 | getOffset,
50 | getScroll,
51 | showPanelByEle
52 | } from './dom';
53 | import {
54 | Class
55 | } from './class';
56 | import {
57 | core
58 | } from './core';
59 |
60 | import {
61 | ajax
62 | } from './ajax';
63 |
64 | import {
65 | get,
66 | post
67 | } from './fetch';
68 |
69 | import {
70 | floatRender,
71 | integerRender,
72 | dateRender,
73 | dateTimeRender,
74 | timeRender,
75 | percentRender,
76 | dateToUTCString
77 | } from './util/dataRender';
78 |
79 | import {
80 | NumberFormater,
81 | DateFormater
82 | } from './util/formater';
83 |
84 | import {
85 | date
86 | } from './util/dateUtils';
87 | import {
88 | AddressMasker,
89 | NumberMasker,
90 | CurrencyMasker,
91 | PercentMasker
92 | } from './util/masker'
93 |
94 | import {
95 | hotkeys
96 | } from './util/hotKeys';
97 |
98 | import {
99 | Ripple
100 | } from './util/ripple';
101 |
102 | import {
103 | RSAUtils,
104 | BigInt,
105 | BarrettMu,
106 | twoDigit
107 | } from './util/rsautils';
108 |
109 | import {
110 | trans
111 | } from './util/i18n';
112 |
113 |
114 | //公开接口、属性对外暴露
115 | let api = {
116 | ajax: ajax,
117 | get,
118 | post,
119 | extend : extend,
120 | setCookie: setCookie,
121 | getCookie: getCookie,
122 | createShellObject: createShellObject,
123 | execIgnoreError: execIgnoreError,
124 | getFunction: getFunction,
125 | getJSObject: getJSObject,
126 | isDate: isDate,
127 | isNumber: isNumber,
128 | isArray: isArray,
129 | isEmptyObject: isEmptyObject,
130 | inArray: inArray,
131 | isDomElement: isDomElement,
132 | each: each,
133 | on: on,
134 | off: off,
135 | trigger: trigger,
136 | stopEvent: stopEvent,
137 | event: event,
138 | addClass: addClass,
139 | removeClass: removeClass,
140 | hasClass: hasClass,
141 | toggleClass: toggleClass,
142 | closest: closest,
143 | css: css,
144 | wrap: wrap,
145 | getStyle: getStyle,
146 | getZIndex: getZIndex,
147 | makeDOM: makeDOM,
148 | makeModal: makeModal,
149 | getOffset: getOffset,
150 | getScroll: getScroll,
151 | showPanelByEle: showPanelByEle,
152 | Class: Class,
153 | core: core,
154 | floatRender: floatRender,
155 | integerRender: integerRender,
156 | dateRender: dateRender,
157 | dateTimeRender: dateTimeRender,
158 | timeRender: timeRender,
159 | percentRender: percentRender,
160 | dateToUTCString: dateToUTCString,
161 | date: date,
162 | NumberFormater: NumberFormater,
163 | DateFormater: DateFormater,
164 | AddressMasker: AddressMasker,
165 | NumberMasker: NumberMasker,
166 | CurrencyMasker: CurrencyMasker,
167 | PercentMasker: PercentMasker,
168 | hotkeys: hotkeys,
169 | Ripple: Ripple,
170 | RSAUtils: RSAUtils,
171 | BigInt: BigInt,
172 | BarrettMu: BarrettMu,
173 | twoDigit: twoDigit,
174 | trans: trans,
175 |
176 | };
177 | extend(api,env);
178 | // export api;
179 | //export default api;
180 | extend(api,window.u || {});
181 |
182 | window.u = api;
183 | window.iweb = {}
184 | window.iweb.browser = window.u;
185 | window.sparrow = window.u;
186 | export {
187 | u,
188 | sparrow
189 | };
190 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | /* global __dirname */
2 |
3 | var path = require('path');
4 | var webpack = require('webpack');
5 | var UglifyJsPlugin = webpack.optimize.UglifyJsPlugin;
6 | var fs = require('fs');
7 |
8 | var dir_js = path.resolve(__dirname, 'src');
9 | var dir_build = path.resolve(__dirname, 'dist');
10 |
11 | var libraryName = 'tinper-sparrow';
12 |
13 | var data = fs.readFileSync('./package.json', 'utf8');
14 | var packageObj = JSON.parse(data);
15 | var headerStr = '';
16 | headerStr += packageObj.name + ' v' + packageObj.version + '\r\n';
17 | headerStr += packageObj.description + '\r\n';
18 | headerStr += 'author : ' + packageObj.author + '\r\n';
19 | headerStr += 'homepage : ' + packageObj.homepage + '\r\n';
20 | headerStr += 'bugs : ' + packageObj.bugs.url;
21 | var plugins = [new webpack.BannerPlugin(headerStr),
22 | new webpack.LoaderOptionsPlugin({
23 | minimize: true
24 | }),
25 | new webpack.NoErrorsPlugin()
26 | ]
27 |
28 | var returnFUn = function(env) {
29 | var mode = env.mode,
30 | outputFile;
31 |
32 | if (mode == 'build') {
33 | outputFile = libraryName + '.min.js';
34 | plugins.push(new webpack.optimize.UglifyJsPlugin({
35 | mangle: true,
36 | beautify: true
37 | }))
38 | plugins.push(new UglifyJsPlugin({
39 | minimize: true
40 | }));
41 | } else {
42 | outputFile = libraryName + '.js';
43 | plugins.push(new webpack.optimize.UglifyJsPlugin({
44 | mangle: false,
45 | beautify: true
46 | }))
47 | }
48 |
49 | var obj = {
50 | entry: path.resolve(dir_js, 'index.js'),
51 | output: {
52 | path: dir_build,
53 | filename: outputFile
54 | },
55 | devServer: {
56 | contentBase: dir_build,
57 | },
58 | module: {
59 | loaders: [{
60 | loader: 'babel-loader',
61 | test: dir_js,
62 | query: {
63 | //presets: ['es2015'],
64 |
65 | // All of the plugins of babel-preset-es2015,
66 | // minus babel-plugin-transform-es2015-modules-commonjs
67 | plugins: [
68 | 'transform-es2015-template-literals',
69 | 'transform-es2015-literals',
70 | 'transform-es2015-function-name',
71 | 'transform-es2015-arrow-functions',
72 | 'transform-es2015-block-scoped-functions',
73 | 'transform-es2015-classes',
74 | 'transform-es2015-object-super',
75 | 'transform-es2015-shorthand-properties',
76 | 'transform-es2015-computed-properties',
77 | 'transform-es2015-for-of',
78 | 'transform-es2015-sticky-regex',
79 | 'transform-es2015-unicode-regex',
80 | 'check-es2015-constants',
81 | 'transform-es2015-spread',
82 | 'transform-es2015-parameters',
83 | 'transform-es2015-destructuring',
84 | 'transform-es2015-block-scoping',
85 | 'transform-es2015-typeof-symbol', ['transform-regenerator', {
86 | async: false,
87 | asyncGenerators: false
88 | }],
89 | ],
90 | },
91 | }]
92 | },
93 | plugins: plugins,
94 | stats: {
95 | // Nice colored output
96 | colors: true
97 | },
98 | // Create source maps for the bundle
99 | devtool: 'source-map',
100 | }
101 | return obj;
102 | }
103 | module.exports = returnFUn;
104 |
--------------------------------------------------------------------------------
/lib/event.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : Sparrow touch event
3 | * Author : Kvkens(yueming@yonyou.com)
4 | * Date : 2016-07-28 14:41:17
5 | */
6 |
7 | var on = function on(element, eventName, child, listener) {
8 | if (!element) return;
9 | if (arguments.length < 4) {
10 | listener = child;
11 | child = undefined;
12 | } else {
13 | var childlistener = function childlistener(e) {
14 | if (!e) {
15 | return;
16 | }
17 | var tmpchildren = element.querySelectorAll(child);
18 | tmpchildren.forEach(function (node) {
19 | if (node == e.target) {
20 | listener.call(e.target, e);
21 | }
22 | });
23 | };
24 | }
25 | //capture = capture || false;
26 |
27 | if (!element["uEvent"]) {
28 | //在dom上添加记录区
29 | element["uEvent"] = {};
30 | }
31 | //判断是否元素上是否用通过on方法填加进去的事件
32 | if (!element["uEvent"][eventName]) {
33 | element["uEvent"][eventName] = [child ? childlistener : listener];
34 | if (u.event && u.event[eventName] && u.event[eventName].setup) {
35 | u.event[eventName].setup.call(element);
36 | }
37 | element["uEvent"][eventName + 'fn'] = function (e) {
38 | //火狐下有问题修改判断
39 | if (!e) e = typeof event != 'undefined' && event ? event : window.event;
40 | element["uEvent"][eventName].forEach(function (fn) {
41 | try {
42 | e.target = e.target || e.srcElement; //兼容IE8
43 | } catch (ee) {}
44 | if (fn) fn.call(element, e);
45 | });
46 | };
47 | if (element.addEventListener) {
48 | // 用于支持DOM的浏览器
49 | element.addEventListener(eventName, element["uEvent"][eventName + 'fn']);
50 | } else if (element.attachEvent) {
51 | // 用于IE浏览器
52 | element.attachEvent("on" + eventName, element["uEvent"][eventName + 'fn']);
53 | } else {
54 | // 用于其它浏览器
55 | element["on" + eventName] = element["uEvent"][eventName + 'fn'];
56 | }
57 | } else {
58 | //如果有就直接往元素的记录区添加事件
59 | var lis = child ? childlistener : listener;
60 | var hasLis = false;
61 | element["uEvent"][eventName].forEach(function (fn) {
62 | if (fn == lis) {
63 | hasLis = true;
64 | }
65 | });
66 | if (!hasLis) {
67 | element["uEvent"][eventName].push(child ? childlistener : listener);
68 | }
69 | }
70 | };
71 |
72 | var off = function off(element, eventName, listener) {
73 | //删除事件数组
74 | if (listener) {
75 | if (element && element["uEvent"] && element["uEvent"][eventName]) {
76 | element["uEvent"][eventName].forEach(function (fn, i) {
77 | if (fn == listener) {
78 | element["uEvent"][eventName].splice(i, 1);
79 | }
80 | });
81 | }
82 | return;
83 | }
84 | var eventfn;
85 | if (element && element["uEvent"] && element["uEvent"][eventName + 'fn']) eventfn = element["uEvent"][eventName + 'fn'];
86 | if (element.removeEventListener) {
87 | // 用于支持DOM的浏览器
88 | element.removeEventListener(eventName, eventfn);
89 | } else if (element.removeEvent) {
90 | // 用于IE浏览器
91 | element.removeEvent("on" + eventName, eventfn);
92 | } else {
93 | // 用于其它浏览器
94 | delete element["on" + eventName];
95 | }
96 | if (u.event && u.event[eventName] && u.event[eventName].teardown) {
97 | u.event[eventName].teardown.call(element);
98 | }
99 |
100 | if (element && element["uEvent"] && element["uEvent"][eventName]) element["uEvent"][eventName] = undefined;
101 | if (element && element["uEvent"] && element["uEvent"][eventName + 'fn']) element["uEvent"][eventName + 'fn'] = undefined;
102 | };
103 | var trigger = function trigger(element, eventName) {
104 | if (element["uEvent"] && element["uEvent"][eventName]) {
105 | element["uEvent"][eventName + 'fn']();
106 | }
107 | };
108 |
109 | /**
110 | * 阻止冒泡
111 | */
112 | var stopEvent = function stopEvent(e) {
113 | if (typeof e != "undefined") {
114 | if (e.stopPropagation) e.stopPropagation();else {
115 | e.cancelBubble = true;
116 | }
117 | //阻止默认浏览器动作(W3C)
118 | if (e && e.preventDefault) e.preventDefault();
119 | //IE中阻止函数器默认动作的方式
120 | else window.event.returnValue = false;
121 | }
122 | };
123 |
124 | export { on, off, trigger, stopEvent };
--------------------------------------------------------------------------------
/src/event.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : Sparrow touch event
3 | * Author : Kvkens(yueming@yonyou.com)
4 | * Date : 2016-07-28 14:41:17
5 | */
6 |
7 | var on = function(element, eventName, child, listener) {
8 | if(!element)
9 | return;
10 | if(arguments.length < 4) {
11 | listener = child;
12 | child = undefined;
13 | } else {
14 | var childlistener = function(e) {
15 | if(!e) {
16 | return;
17 | }
18 | var tmpchildren = element.querySelectorAll(child)
19 | tmpchildren.forEach(function(node) {
20 | if(node == e.target) {
21 | listener.call(e.target, e)
22 | }
23 | })
24 | }
25 | }
26 | //capture = capture || false;
27 |
28 | if(!element["uEvent"]) {
29 | //在dom上添加记录区
30 | element["uEvent"] = {}
31 | }
32 | //判断是否元素上是否用通过on方法填加进去的事件
33 | if(!element["uEvent"][eventName]) {
34 | element["uEvent"][eventName] = [child ? childlistener : listener]
35 | if(u.event && u.event[eventName] && u.event[eventName].setup) {
36 | u.event[eventName].setup.call(element);
37 | }
38 | element["uEvent"][eventName + 'fn'] = function(e) {
39 | //火狐下有问题修改判断
40 | if(!e)
41 | e = typeof event != 'undefined' && event ? event : window.event;
42 | element["uEvent"][eventName].forEach(function(fn) {
43 | try {
44 | e.target = e.target || e.srcElement; //兼容IE8
45 | } catch(ee) {}
46 | if(fn)
47 | fn.call(element, e)
48 | })
49 | }
50 | if(element.addEventListener) { // 用于支持DOM的浏览器
51 | element.addEventListener(eventName, element["uEvent"][eventName + 'fn']);
52 | } else if(element.attachEvent) { // 用于IE浏览器
53 | element.attachEvent("on" + eventName, element["uEvent"][eventName + 'fn']);
54 | } else { // 用于其它浏览器
55 | element["on" + eventName] = element["uEvent"][eventName + 'fn']
56 | }
57 | } else {
58 | //如果有就直接往元素的记录区添加事件
59 | var lis = child ? childlistener : listener;
60 | var hasLis = false;
61 | element["uEvent"][eventName].forEach(function(fn) {
62 | if(fn == lis) {
63 | hasLis = true;
64 | }
65 | });
66 | if(!hasLis) {
67 | element["uEvent"][eventName].push(child ? childlistener : listener)
68 | }
69 | }
70 |
71 | };
72 |
73 | var off = function(element, eventName, listener) {
74 | //删除事件数组
75 | if(listener) {
76 | if(element && element["uEvent"] && element["uEvent"][eventName]) {
77 | element["uEvent"][eventName].forEach(function(fn, i) {
78 | if(fn == listener) {
79 | element["uEvent"][eventName].splice(i, 1);
80 | }
81 | });
82 | }
83 | return;
84 | }
85 | var eventfn;
86 | if(element && element["uEvent"] && element["uEvent"][eventName + 'fn'])
87 | eventfn = element["uEvent"][eventName + 'fn']
88 | if(element.removeEventListener) { // 用于支持DOM的浏览器
89 | element.removeEventListener(eventName, eventfn);
90 | } else if(element.removeEvent) { // 用于IE浏览器
91 | element.removeEvent("on" + eventName, eventfn);
92 | } else { // 用于其它浏览器
93 | delete element["on" + eventName]
94 | }
95 | if(u.event && u.event[eventName] && u.event[eventName].teardown) {
96 | u.event[eventName].teardown.call(element);
97 | }
98 |
99 | if(element && element["uEvent"] && element["uEvent"][eventName])
100 | element["uEvent"][eventName] = undefined
101 | if(element && element["uEvent"] && element["uEvent"][eventName + 'fn'])
102 | element["uEvent"][eventName + 'fn'] = undefined
103 |
104 | };
105 | var trigger = function(element, eventName) {
106 | if(element["uEvent"] && element["uEvent"][eventName]) {
107 | element["uEvent"][eventName + 'fn']()
108 | }
109 | };
110 |
111 | /**
112 | * 阻止冒泡
113 | */
114 | var stopEvent = function(e) {
115 | if(typeof(e) != "undefined") {
116 | if(e.stopPropagation)
117 | e.stopPropagation();
118 | else {
119 | e.cancelBubble = true;
120 | }
121 | //阻止默认浏览器动作(W3C)
122 | if(e && e.preventDefault)
123 | e.preventDefault();
124 | //IE中阻止函数器默认动作的方式
125 | else
126 | window.event.returnValue = false;
127 | }
128 | };
129 |
130 | export {
131 | on,
132 | off,
133 | trigger,
134 | stopEvent
135 | };
136 |
--------------------------------------------------------------------------------
/src/util.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : Sparrow util tools
3 | * Author : Kvkens(yueming@yonyou.com)
4 | * Date : 2016-07-27 21:46:50
5 | */
6 |
7 | /**
8 | * 创建一个带壳的对象,防止外部修改
9 | * @param {Object} proto
10 | */
11 | var createShellObject = function(proto) {
12 | var exf = function() {}
13 | exf.prototype = proto;
14 | return new exf();
15 | };
16 | var execIgnoreError = function(a, b, c) {
17 | try {
18 | a.call(b, c);
19 | } catch(e) {}
20 | };
21 |
22 | var getFunction = function(target, val) {
23 | if(!val || typeof val == 'function') return val
24 | if(typeof target[val] == 'function')
25 | return target[val]
26 | else if(typeof window[val] == 'function')
27 | return window[val]
28 | else if(val.indexOf('.') != -1) {
29 | var func = getJSObject(target, val)
30 | if(typeof func == 'function') return func
31 | func = getJSObject(window, val)
32 | if(typeof func == 'function') return func
33 | }
34 | return val
35 | };
36 | var getJSObject = function(target, names) {
37 | if(!names) {
38 | return;
39 | }
40 | if(typeof names == 'object')
41 | return names
42 | var nameArr = names.split('.')
43 | var obj = target
44 | for(var i = 0; i < nameArr.length; i++) {
45 | obj = obj[nameArr[i]]
46 | if(!obj) return null
47 | }
48 | return obj
49 | };
50 | var isDate = function(input) {
51 | return Object.prototype.toString.call(input) === '[object Date]' ||
52 | input instanceof Date;
53 | };
54 | var isNumber = function(obj) {
55 | //return obj === +obj
56 | //加了个typeof 判断,因为'431027199110.078573'会解析成number
57 | return obj - parseFloat(obj) + 1 >= 0;
58 | };
59 | var isArray = Array.isArray || function(val) {
60 | return Object.prototype.toString.call(val) === '[object Array]';
61 | };
62 | var isEmptyObject = function(obj) {
63 | var name;
64 | for(name in obj) {
65 | return false;
66 | }
67 | return true;
68 | };
69 | var inArray = function(node, arr) {
70 | if(!arr instanceof Array) {
71 | throw "arguments is not Array";
72 | }
73 | for(var i = 0, k = arr.length; i < k; i++) {
74 | if(node == arr[i]) {
75 | return true;
76 | }
77 | }
78 | return false;
79 | };
80 | var isDomElement = function(obj) {
81 | if(window['HTMLElement']) {
82 | return obj instanceof HTMLElement;
83 | } else {
84 | return obj && obj.tagName && obj.nodeType === 1;
85 | }
86 | };
87 | var each = function(obj, callback) {
88 | if(obj.forEach) {
89 | obj.forEach(function(v, k) {
90 | callback(k, v);
91 | });
92 |
93 | } else if(obj instanceof Object) {
94 | for(var k in obj) {
95 | callback(k, obj[k]);
96 | }
97 | } else {
98 | return;
99 | }
100 |
101 | };
102 | try{
103 | NodeList.prototype.forEach = Array.prototype.forEach;
104 | }catch(e){
105 |
106 | }
107 |
108 |
109 | /**
110 | * 获得字符串的字节长度
111 | */
112 | String.prototype.lengthb = function() {
113 | // var str = this.replace(/[^\x800-\x10000]/g, "***");
114 | var str = this.replace(/[^\x00-\xff]/g, "**");
115 | return str.length;
116 | };
117 |
118 | /**
119 | * 将AFindText全部替换为ARepText
120 | */
121 | String.prototype.replaceAll = function(AFindText, ARepText) {
122 | //自定义String对象的方法
123 | var raRegExp = new RegExp(AFindText, "g");
124 | return this.replace(raRegExp, ARepText);
125 | };
126 |
127 |
128 | var dateFormat = function ( str ) {
129 | //如果不是string类型 原型返回
130 | if ( typeof ( str ) !== 'string')
131 | {
132 | return str;
133 | }
134 | //判断 str 格式如果是 yy-mm-dd
135 | if (str && str.indexOf ('-') > -1){
136 | //获取当前是否是 ios版本,>8是因为ios不识别new Date(“2016/11”)格式
137 | var ua = navigator.userAgent.toLowerCase();
138 | if (/iphone|ipad|ipod/.test(ua)) {
139 | //转换成 yy/mm/dd
140 | str = str.replace(/-/g,"/");
141 | str = str.replace(/(^\s+)|(\s+$)/g,"");
142 | if(str.length <= 8){
143 | str = str += "/01";
144 | }
145 | }
146 | }
147 |
148 |
149 | return str;
150 | }
151 |
152 | export {
153 | createShellObject,
154 | execIgnoreError,
155 | getFunction,
156 | getJSObject,
157 | isDate,
158 | isNumber,
159 | isArray,
160 | isEmptyObject,
161 | inArray,
162 | isDomElement,
163 | each,
164 | dateFormat
165 | };
166 |
--------------------------------------------------------------------------------
/lib/util.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : Sparrow util tools
3 | * Author : Kvkens(yueming@yonyou.com)
4 | * Date : 2016-07-27 21:46:50
5 | */
6 |
7 | /**
8 | * 创建一个带壳的对象,防止外部修改
9 | * @param {Object} proto
10 | */
11 | var createShellObject = function createShellObject(proto) {
12 | var exf = function exf() {};
13 | exf.prototype = proto;
14 | return new exf();
15 | };
16 | var execIgnoreError = function execIgnoreError(a, b, c) {
17 | try {
18 | a.call(b, c);
19 | } catch (e) {}
20 | };
21 |
22 | var getFunction = function getFunction(target, val) {
23 | if (!val || typeof val == 'function') return val;
24 | if (typeof target[val] == 'function') return target[val];else if (typeof window[val] == 'function') return window[val];else if (val.indexOf('.') != -1) {
25 | var func = getJSObject(target, val);
26 | if (typeof func == 'function') return func;
27 | func = getJSObject(window, val);
28 | if (typeof func == 'function') return func;
29 | }
30 | return val;
31 | };
32 | var getJSObject = function getJSObject(target, names) {
33 | if (!names) {
34 | return;
35 | }
36 | if ((typeof names === 'undefined' ? 'undefined' : babelHelpers['typeof'](names)) == 'object') return names;
37 | var nameArr = names.split('.');
38 | var obj = target;
39 | for (var i = 0; i < nameArr.length; i++) {
40 | obj = obj[nameArr[i]];
41 | if (!obj) return null;
42 | }
43 | return obj;
44 | };
45 | var isDate = function isDate(input) {
46 | return Object.prototype.toString.call(input) === '[object Date]' || input instanceof Date;
47 | };
48 | var isNumber = function isNumber(obj) {
49 | //return obj === +obj
50 | //加了个typeof 判断,因为'431027199110.078573'会解析成number
51 | return obj - parseFloat(obj) + 1 >= 0;
52 | };
53 | var isArray = Array.isArray || function (val) {
54 | return Object.prototype.toString.call(val) === '[object Array]';
55 | };
56 | var isEmptyObject = function isEmptyObject(obj) {
57 | var name;
58 | for (name in obj) {
59 | return false;
60 | }
61 | return true;
62 | };
63 | var inArray = function inArray(node, arr) {
64 | if (!arr instanceof Array) {
65 | throw "arguments is not Array";
66 | }
67 | for (var i = 0, k = arr.length; i < k; i++) {
68 | if (node == arr[i]) {
69 | return true;
70 | }
71 | }
72 | return false;
73 | };
74 | var isDomElement = function isDomElement(obj) {
75 | if (window['HTMLElement']) {
76 | return obj instanceof HTMLElement;
77 | } else {
78 | return obj && obj.tagName && obj.nodeType === 1;
79 | }
80 | };
81 | var each = function each(obj, callback) {
82 | if (obj.forEach) {
83 | obj.forEach(function (v, k) {
84 | callback(k, v);
85 | });
86 | } else if (obj instanceof Object) {
87 | for (var k in obj) {
88 | callback(k, obj[k]);
89 | }
90 | } else {
91 | return;
92 | }
93 | };
94 | try {
95 | NodeList.prototype.forEach = Array.prototype.forEach;
96 | } catch (e) {}
97 |
98 | /**
99 | * 获得字符串的字节长度
100 | */
101 | String.prototype.lengthb = function () {
102 | // var str = this.replace(/[^\x800-\x10000]/g, "***");
103 | var str = this.replace(/[^\x00-\xff]/g, "**");
104 | return str.length;
105 | };
106 |
107 | /**
108 | * 将AFindText全部替换为ARepText
109 | */
110 | String.prototype.replaceAll = function (AFindText, ARepText) {
111 | //自定义String对象的方法
112 | var raRegExp = new RegExp(AFindText, "g");
113 | return this.replace(raRegExp, ARepText);
114 | };
115 |
116 | var dateFormat = function dateFormat(str) {
117 | //如果不是string类型 原型返回
118 | if (typeof str !== 'string') {
119 | return str;
120 | }
121 | //判断 str 格式如果是 yy-mm-dd
122 | if (str && str.indexOf('-') > -1) {
123 | //获取当前是否是 ios版本,>8是因为ios不识别new Date(“2016/11”)格式
124 | var ua = navigator.userAgent.toLowerCase();
125 | if (/iphone|ipad|ipod/.test(ua)) {
126 | //转换成 yy/mm/dd
127 | str = str.replace(/-/g, "/");
128 | str = str.replace(/(^\s+)|(\s+$)/g, "");
129 | if (str.length <= 8) {
130 | str = str += "/01";
131 | }
132 | }
133 | }
134 |
135 | return str;
136 | };
137 |
138 | export { createShellObject, execIgnoreError, getFunction, getJSObject, isDate, isNumber, isArray, isEmptyObject, inArray, isDomElement, each, dateFormat };
--------------------------------------------------------------------------------
/lib/BaseComponent.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.BaseComponent = undefined;
7 |
8 | var _class = require('./class');
9 |
10 | var _util = require('./util');
11 |
12 | var _event = require('./event');
13 |
14 | var _compMgr = require('./compMgr');
15 |
16 | /**
17 | * Module : Sparrow base component
18 | * Author : Kvkens(yueming@yonyou.com)
19 | * Date : 2016-07-28 18:45:08
20 | */
21 |
22 | var BaseComponent = _class.Class.create({
23 | initialize: function initialize(element) {
24 | if ((0, _util.isDomElement)(element)) {
25 | this.element = element;
26 | this.options = {};
27 | } else {
28 | this.element = element['el'];
29 | this.options = element;
30 | }
31 | this.element = typeof this.element === 'string' ? document.querySelector(this.element) : this.element;
32 |
33 | this.compType = this.compType || this.constructor.compType;
34 | this.element[this.compType] = this;
35 | this.element['init'] = true;
36 | this.init();
37 | },
38 | /**
39 | * 绑定事件
40 | * @param {String} name
41 | * @param {Function} callback
42 | */
43 | on: function on(name, callback) {
44 | name = name.toLowerCase();
45 | this._events || (this._events = {});
46 | var events = this._events[name] || (this._events[name] = []);
47 | events.push({
48 | callback: callback
49 | });
50 | return this;
51 | },
52 | /**
53 | * 触发事件
54 | * @param {String} name
55 | */
56 | trigger: function trigger(name) {
57 | name = name.toLowerCase();
58 | if (!this._events || !this._events[name]) return this;
59 | var args = Array.prototype.slice.call(arguments, 1);
60 | var events = this._events[name];
61 | for (var i = 0, count = events.length; i < count; i++) {
62 | events[i].callback.apply(this, args);
63 | }
64 | return this;
65 | },
66 | /**
67 | * 初始化
68 | */
69 | init: function init() {},
70 | /**
71 | * 渲染控件
72 | */
73 | render: function render() {},
74 | /**
75 | * 销毁控件
76 | */
77 | destroy: function destroy() {
78 | delete this.element['comp'];
79 | this.element.innerHTML = '';
80 | },
81 | /**
82 | * 增加dom事件
83 | * @param {String} name
84 | * @param {Function} callback
85 | */
86 | addDomEvent: function addDomEvent(name, callback) {
87 | (0, _event.on)(this.element, name, callback);
88 | return this;
89 | },
90 | /**
91 | * 移除dom事件
92 | * @param {String} name
93 | */
94 | removeDomEvent: function removeDomEvent(name, callback) {
95 | (0, _event.off)(this.element, name, callback);
96 | return this;
97 | },
98 | setEnable: function setEnable(enable) {
99 | return this;
100 | },
101 | /**
102 | * 判断是否为DOM事件
103 | */
104 | isDomEvent: function isDomEvent(eventName) {
105 | if (this.element['on' + eventName] === undefined) return false;else return true;
106 | },
107 | createDateAdapter: function createDateAdapter(options) {
108 | var opt = options['options'],
109 | model = options['model'];
110 | var Adapter = _compMgr.compMgr.getDataAdapter(this.compType, opt['dataType']);
111 | if (Adapter) {
112 | this.dataAdapter = new Adapter(this, options);
113 | }
114 | },
115 | Statics: {
116 | compName: '',
117 | EVENT_VALUE_CHANGE: 'valueChange',
118 | getName: function getName() {
119 | return this.compName;
120 | }
121 | }
122 | });
123 |
124 | function adjustDataType(options) {
125 | var types = ['integer', 'float', 'currency', 'percent', 'string', 'textarea'];
126 | var _type = options['type'],
127 | _dataType = options['dataType'];
128 | if (types.indexOf(_type) != -1) {
129 | options['dataType'] = _type;
130 | options['type'] = 'originText';
131 | }
132 | }
133 |
134 | var BaseComponent = BaseComponent;
135 |
136 | exports.BaseComponent = BaseComponent;
--------------------------------------------------------------------------------
/lib/core.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : Sparrow core context
3 | * Author : Kvkens(yueming@yonyou.com)
4 | * Date : 2016-07-28 13:52:19
5 | */
6 | import { extend } from './extend';
7 | import { createShellObject } from './util';
8 | import { getCookie, setCookie } from './cookies';
9 | import { U_LANGUAGES, U_THEME, U_LOCALE, U_USERCODE } from './enumerables';
10 |
11 | var environment = {};
12 | /**
13 | * client attributes
14 | */
15 | var clientAttributes = {};
16 |
17 | var sessionAttributes = {};
18 |
19 | var fn = {};
20 | var maskerMeta = {
21 | 'float': {
22 | precision: 2
23 | },
24 | 'datetime': {
25 | format: 'YYYY-MM-DD HH:mm:ss',
26 | metaType: 'DateTimeFormatMeta',
27 | speratorSymbol: '-'
28 | },
29 | 'time': {
30 | format: 'HH:mm'
31 | },
32 | 'date': {
33 | format: 'YYYY-MM-DD'
34 | },
35 | 'currency': {
36 | precision: 2,
37 | curSymbol: '¥'
38 | },
39 | 'percent': {},
40 | 'phoneNumber': {}
41 | };
42 | /**
43 | * 获取环境信息
44 | * @return {environment}
45 | */
46 | fn.getEnvironment = function () {
47 | return createShellObject(environment);
48 | };
49 |
50 | /**
51 | * 获取客户端参数对象
52 | * @return {clientAttributes}
53 | */
54 | fn.getClientAttributes = function () {
55 | var exf = function exf() {};
56 | return createShellObject(clientAttributes);
57 | };
58 |
59 | fn.setContextPath = function (contextPath) {
60 | return environment[IWEB_CONTEXT_PATH] = contextPath;
61 | };
62 | fn.getContextPath = function (contextPath) {
63 | return environment[IWEB_CONTEXT_PATH];
64 | };
65 | /**
66 | * 设置客户端参数对象
67 | * @param {Object} k 对象名称
68 | * @param {Object} v 对象值(建议使用简单类型)
69 | */
70 | fn.setClientAttribute = function (k, v) {
71 | clientAttributes[k] = v;
72 | };
73 | /**
74 | * 获取会话级参数对象
75 | * @return {clientAttributes}
76 | */
77 | fn.getSessionAttributes = function () {
78 | var exf = function exf() {};
79 | return createShellObject(sessionAttributes);
80 | };
81 |
82 | /**
83 | * 设置会话级参数对象
84 | * @param {Object} k 对象名称
85 | * @param {Object} v 对象值(建议使用简单类型)
86 | */
87 | fn.setSessionAttribute = function (k, v) {
88 | sessionAttributes[k] = v;
89 | setCookie("ISES_" + k, v);
90 | };
91 |
92 | /**
93 | * 移除客户端参数
94 | * @param {Object} k 对象名称
95 | */
96 | fn.removeClientAttribute = function (k) {
97 | clientAttributes[k] = null;
98 | execIgnoreError(function () {
99 | delete clientAttributes[k];
100 | });
101 | };
102 |
103 | /**
104 | * 获取地区信息编码
105 | */
106 | fn.getLocale = function () {
107 | return this.getEnvironment().locale;
108 | };
109 |
110 | /**
111 | * 获取多语信息
112 | */
113 | fn.getLanguages = function () {
114 | return this.getEnvironment().languages;
115 | };
116 | /**
117 | * 收集环境信息(包括客户端参数)
118 | * @return {Object}
119 | */
120 | fn.collectEnvironment = function () {
121 | var _env = this.getEnvironment();
122 | var _ses = this.getSessionAttributes();
123 |
124 | for (var i in clientAttributes) {
125 | _ses[i] = clientAttributes[i];
126 | }
127 | _env.clientAttributes = _ses;
128 | return _env;
129 | };
130 |
131 | /**
132 | * 设置数据格式信息
133 | * @param {String} type
134 | * @param {Object} meta
135 | */
136 | fn.setMaskerMeta = function (type, meta) {
137 | if (typeof type == 'function') {
138 | getMetaFunc = type;
139 | } else {
140 | if (!maskerMeta[type]) maskerMeta[type] = meta;else {
141 | if ((typeof meta === 'undefined' ? 'undefined' : babelHelpers['typeof'](meta)) != 'object') maskerMeta[type] = meta;else for (var key in meta) {
142 | maskerMeta[type][key] = meta[key];
143 | }
144 | }
145 | }
146 | };
147 | fn.getMaskerMeta = function (type) {
148 | if (typeof getMetaFunc == 'function') {
149 | var meta = getMetaFunc.call(this);
150 | return meta[type];
151 | } else return extend({}, maskerMeta[type]);
152 | };
153 | environment.languages = getCookie(U_LANGUAGES) ? getCookie(U_LANGUAGES).split(',') : navigator.language ? navigator.language : 'zh-CN';
154 | if (environment.languages == 'zh-cn') environment.languages = 'zh-CN';
155 | if (environment.languages == 'en-us') environment.languages = 'en-US';
156 |
157 | environment.theme = getCookie(U_THEME);
158 | environment.locale = getCookie(U_LOCALE);
159 | //environment.timezoneOffset = (new Date()).getTimezoneOffset()
160 | environment.usercode = getCookie(U_USERCODE);
161 | //init session attribute
162 | document.cookie.replace(/ISES_(\w*)=([^;]*);?/ig, function (a, b, c) {
163 | sessionAttributes[b] = c;
164 | });
165 |
166 | var Core = function Core() {};
167 | Core.prototype = fn;
168 |
169 | var core = new Core();
170 |
171 | export { core };
--------------------------------------------------------------------------------
/src/core.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : Sparrow core context
3 | * Author : Kvkens(yueming@yonyou.com)
4 | * Date : 2016-07-28 13:52:19
5 | */
6 | import {extend} from './extend';
7 | import {createShellObject} from './util';
8 | import {getCookie,setCookie} from './cookies';
9 | import {U_LANGUAGES,U_THEME,U_LOCALE,U_USERCODE} from './enumerables'
10 |
11 |
12 | var environment = {};
13 | /**
14 | * client attributes
15 | */
16 | var clientAttributes = {};
17 |
18 | var sessionAttributes = {};
19 |
20 | var fn = {};
21 | var maskerMeta = {
22 | 'float': {
23 | precision: 2
24 | },
25 | 'datetime': {
26 | format: 'YYYY-MM-DD HH:mm:ss',
27 | metaType: 'DateTimeFormatMeta',
28 | speratorSymbol: '-'
29 | },
30 | 'time': {
31 | format: 'HH:mm'
32 | },
33 | 'date': {
34 | format: 'YYYY-MM-DD'
35 | },
36 | 'currency': {
37 | precision: 2,
38 | curSymbol: '¥'
39 | },
40 | 'percent': {
41 |
42 | },
43 | 'phoneNumber': {
44 |
45 | }
46 | };
47 | /**
48 | * 获取环境信息
49 | * @return {environment}
50 | */
51 | fn.getEnvironment = function() {
52 | return createShellObject(environment);
53 | };
54 |
55 | /**
56 | * 获取客户端参数对象
57 | * @return {clientAttributes}
58 | */
59 | fn.getClientAttributes = function() {
60 | var exf = function() {}
61 | return createShellObject(clientAttributes);
62 | }
63 |
64 | fn.setContextPath = function(contextPath) {
65 | return environment[IWEB_CONTEXT_PATH] = contextPath
66 | }
67 | fn.getContextPath = function(contextPath) {
68 | return environment[IWEB_CONTEXT_PATH]
69 | }
70 | /**
71 | * 设置客户端参数对象
72 | * @param {Object} k 对象名称
73 | * @param {Object} v 对象值(建议使用简单类型)
74 | */
75 | fn.setClientAttribute = function(k, v) {
76 | clientAttributes[k] = v;
77 | }
78 | /**
79 | * 获取会话级参数对象
80 | * @return {clientAttributes}
81 | */
82 | fn.getSessionAttributes = function() {
83 | var exf = function() {}
84 | return createShellObject(sessionAttributes);
85 | }
86 |
87 | /**
88 | * 设置会话级参数对象
89 | * @param {Object} k 对象名称
90 | * @param {Object} v 对象值(建议使用简单类型)
91 | */
92 | fn.setSessionAttribute = function(k, v) {
93 | sessionAttributes[k] = v;
94 | setCookie("ISES_" + k, v);
95 | }
96 |
97 | /**
98 | * 移除客户端参数
99 | * @param {Object} k 对象名称
100 | */
101 | fn.removeClientAttribute = function(k) {
102 | clientAttributes[k] = null;
103 | execIgnoreError(function() {
104 | delete clientAttributes[k];
105 | })
106 | }
107 |
108 | /**
109 | * 获取地区信息编码
110 | */
111 | fn.getLocale = function() {
112 | return this.getEnvironment().locale
113 | }
114 |
115 | /**
116 | * 获取多语信息
117 | */
118 | fn.getLanguages = function() {
119 | return this.getEnvironment().languages
120 | };
121 | /**
122 | * 收集环境信息(包括客户端参数)
123 | * @return {Object}
124 | */
125 | fn.collectEnvironment = function() {
126 | var _env = this.getEnvironment();
127 | var _ses = this.getSessionAttributes();
128 |
129 | for(var i in clientAttributes) {
130 | _ses[i] = clientAttributes[i];
131 | }
132 | _env.clientAttributes = _ses;
133 | return _env
134 | }
135 |
136 | /**
137 | * 设置数据格式信息
138 | * @param {String} type
139 | * @param {Object} meta
140 | */
141 | fn.setMaskerMeta = function(type, meta) {
142 | if(typeof type == 'function') {
143 | getMetaFunc = type;
144 | } else {
145 | if(!maskerMeta[type])
146 | maskerMeta[type] = meta;
147 | else {
148 | if(typeof meta != 'object')
149 | maskerMeta[type] = meta;
150 | else
151 | for(var key in meta) {
152 | maskerMeta[type][key] = meta[key];
153 | }
154 | }
155 | }
156 | };
157 | fn.getMaskerMeta = function(type) {
158 | if(typeof getMetaFunc == 'function') {
159 | var meta = getMetaFunc.call(this);
160 | return meta[type];
161 | } else
162 | return extend({}, maskerMeta[type]);
163 | };
164 | environment.languages = getCookie(U_LANGUAGES) ? getCookie(U_LANGUAGES).split(',') : navigator.language ? navigator.language : 'zh-CN';
165 | if(environment.languages == 'zh-cn')
166 | environment.languages = 'zh-CN'
167 | if(environment.languages == 'en-us')
168 | environment.languages = 'en-US'
169 |
170 | environment.theme = getCookie(U_THEME);
171 | environment.locale = getCookie(U_LOCALE);
172 | //environment.timezoneOffset = (new Date()).getTimezoneOffset()
173 | environment.usercode = getCookie(U_USERCODE);
174 | //init session attribute
175 | document.cookie.replace(/ISES_(\w*)=([^;]*);?/ig, function(a, b, c) {
176 | sessionAttributes[b] = c;
177 | });
178 |
179 | var Core = function() {};
180 | Core.prototype = fn;
181 |
182 | var core = new Core();
183 |
184 | export { core };
185 |
--------------------------------------------------------------------------------
/snippets/method.md:
--------------------------------------------------------------------------------
1 | ## 方法扩展
2 |
3 | ### extend(object, config)
4 | * 说明:
5 |
6 | 复制对象属性
7 |
8 | * 参数:
9 | * {Object} object:必需。目标对象
10 | * {Object} config:必需。源对象
11 | * 返回值:
12 |
13 | {Object}复制之后的object
14 | * 用法:
15 | var obj1 = {
16 | id : 'id',
17 | name : 'name'
18 | }
19 | var obj2 = {
20 | code : 'code',
21 | name : 'newName'
22 | }
23 | u.extend(obj1, obj2); //obj1为{id: "id", name: "newName", code: "code"}
24 |
25 | ### setCookie(sName, sValue, oExpires, sPath, sDomain, bSecure)
26 | * 说明:
27 |
28 | 设置cookie属性
29 |
30 | * 参数:
31 | * {String} sName:必需。规定 cookie 的名称。
32 | * {String} sValue:必需。规定 cookie 的值。
33 | * {String} oExpires:可选。规定 cookie 的有效期。
34 | * {String} sPath:可选。规定 cookie 的服务器路径。
35 | * {String} sDomain:可选。规定 cookie 的域名。
36 | * {String} bSecure:可选。规定是否通过安全的 HTTPS 连接来传输 cookie。
37 | * 返回值:
38 |
39 | 无
40 | * 用法:
41 | u.setCookie('COOKIENAME', 'COOKIVALUE'); //设置cookie的COOKIENAME为COOKIVALUE
42 |
43 | ### getCookie(sName)
44 | * 说明:
45 |
46 | 获取cookie属性
47 |
48 |
49 | * 参数:
50 | * {String} sName:必需。获取 cookie 的名称。
51 | * 返回值:
52 |
53 | cookie中sName对应的属性
54 | * 用法:
55 | u.getCookie('COOKIENAME'); //获取cookie的COOKIENAME
56 |
57 | ### getFunction(target, val)
58 | * 说明:
59 |
60 | 获取function
61 |
62 | * 参数:
63 |
64 | * {Object} target:必需。function定义的上下文。
65 | * {String} value:必需。function名称。
66 | * 返回值:
67 |
68 | {function}获取到的function
69 | * 用法:
70 |
71 | u.getFunction(window,'funName1');
72 |
73 |
74 | ### getJSObject(target, names)
75 | * 说明:
76 |
77 | 获取Object对象
78 |
79 | * 参数:
80 |
81 | * {Object} target:必需。Object定义的上下文。
82 | * {String} names:必需。Objcet名称。
83 | * 返回值:
84 |
85 | {Object}获取到的Object
86 | * 用法:
87 | u.getJSObject(window,'funName1'); //获取window对象上的funName1对象
88 |
89 |
90 | ### each(obj,callback)
91 | * 说明:
92 |
93 | 遍历传入的obj执行callback方法
94 |
95 | * 参数:
96 |
97 | * {Object}/{Array} obj:必需。需要进行遍历的对象或数组。
98 | * {function} callback:必需。需要执行的function。
99 | * 返回值:
100 |
101 | 无
102 | * 用法:
103 | var tmpdata = [];
104 | u.each(target_div.querySelectorAll(".m_context"),function(i,node){
105 | tmpdata[i] = node.innerHTML
106 | })
107 | //遍历将class为m_context的HTML的内容翻入数组tmpdata中。
108 |
109 |
110 | ### getStyle(element,key)
111 | * 说明:
112 |
113 | 获取HTML元素的style属性。
114 |
115 | * 参数:
116 | * {HTMLElement} element:必需。HTML元素。
117 | * {String} key:必需。需要获取的style属性名称。
118 | * 返回值:
119 |
120 | HTML元素的style属性值
121 | * 用法:
122 | u.getStyle(document.getElementById('id1'), 'width');
123 |
124 | ### getZIndex()
125 | * 说明:
126 |
127 | 统一zindex值, 不同控件每次显示时都取最大的zindex,防止显示错乱
128 |
129 | * 参数:
130 |
131 | 无
132 |
133 | * 返回值:
134 |
135 | 新的zindex最大值
136 | * 用法:
137 | u.getZIndex();
138 |
139 |
140 |
141 |
142 | ### getOffset(ele, offset)
143 | * 说明:
144 |
145 | 获取/设置元素`ele`相对顶层`body`的偏移量
146 |
147 | * 参数:
148 | * {HTMLElement} element:必需。目标对象
149 | * {Object} config:可选。设置的元素偏移量。默认则最终返回`ele`相对`body`的偏移量
150 | * 返回值:
151 |
152 | {Object}:包含`top`,`left`值
153 | * 用法:
154 | var offsetObj = {
155 | top : 10,
156 | left : 20
157 | };
158 | var ele = document.getElementById('tit');
159 |
160 | u.getOffset(ele,offsetObj) // {top: 120, left:100}
161 |
162 |
163 |
164 | ### getScroll(ele, offset)
165 |
166 | - 说明:
167 |
168 | 获取/设置元素`ele`滚动的偏移量
169 |
170 | - 参数:
171 |
172 | - {HTMLElement} element:必需。目标对象
173 | - {Object} config:可选。设置的元素偏移量。默认则最终返回`ele`相对浏览器顶部的偏移量
174 |
175 | - 返回值:
176 |
177 | {Object}:包含`top`,`left`值
178 |
179 | - 用法:
180 |
181 | ```
182 | 同getOffset
183 | ```
184 |
185 |
186 |
187 | ### ajax({...})
188 |
189 | - 说明:
190 |
191 | 执行Ajax数交互
192 |
193 | - 参数:
194 |
195 | ```
196 | {
197 | url: 'test.html',
198 | type: 'GET'
199 | success: function(){},
200 | async: true,
201 | error: function(){},
202 | }
203 | ```
204 |
205 |
206 |
207 | - {String} url:必需,文件在服务器上的位置
208 | - {String} type:可选,默认为`post`
209 | - {Function} success:可选,回调函数
210 | - {Function} error:可选,回调函数
211 | - {Boolean} async: 可选,默认为`true`
212 |
213 | - 返回值:
214 |
215 | {Object}
216 |
217 | - 用法:
218 |
219 | ```
220 |
221 | document.getElementById('btn').addEventListener('click', function(){
222 | u.ajax({
223 | url: './package.json',
224 | type: 'GET',
225 | success: function(data){
226 | alert(data)
227 | },
228 | error: function(){
229 | alert("error")
230 | }
231 | })
232 | })
233 | ```
234 |
--------------------------------------------------------------------------------
/docs/method.md:
--------------------------------------------------------------------------------
1 | # 方法扩展
2 |
3 | ## # extend(object, config)
4 | * 说明:
5 |
6 | 复制对象属性
7 |
8 | * 参数:
9 | * {Object} object:必需。目标对象
10 | * {Object} config:必需。源对象
11 | * 返回值:
12 |
13 | {Object}复制之后的object
14 | * 用法:
15 | var obj1 = {
16 | id : 'id',
17 | name : 'name'
18 | }
19 | var obj2 = {
20 | code : 'code',
21 | name : 'newName'
22 | }
23 | u.extend(obj1, obj2); //obj1为{id: "id", name: "newName", code: "code"}
24 |
25 | ## # setCookie(sName, sValue, oExpires, sPath, sDomain, bSecure)
26 | * 说明:
27 |
28 | 设置cookie属性
29 |
30 | * 参数:
31 | * {String} sName:必需。规定 cookie 的名称。
32 | * {String} sValue:必需。规定 cookie 的值。
33 | * {String} oExpires:可选。规定 cookie 的有效期。
34 | * {String} sPath:可选。规定 cookie 的服务器路径。
35 | * {String} sDomain:可选。规定 cookie 的域名。
36 | * {String} bSecure:可选。规定是否通过安全的 HTTPS 连接来传输 cookie。
37 | * 返回值:
38 |
39 | 无
40 | * 用法:
41 | u.setCookie('COOKIENAME', 'COOKIVALUE'); //设置cookie的COOKIENAME为COOKIVALUE
42 |
43 | ## # getCookie(sName)
44 | * 说明:
45 |
46 | 获取cookie属性
47 |
48 |
49 | * 参数:
50 | * {String} sName:必需。获取 cookie 的名称。
51 | * 返回值:
52 |
53 | cookie中sName对应的属性
54 | * 用法:
55 | u.getCookie('COOKIENAME'); //获取cookie的COOKIENAME
56 |
57 | ## # getFunction(target, val)
58 | * 说明:
59 |
60 | 获取function
61 |
62 | * 参数:
63 |
64 | * {Object} target:必需。function定义的上下文。
65 | * {String} value:必需。function名称。
66 | * 返回值:
67 |
68 | {function}获取到的function
69 | * 用法:
70 |
71 | u.getFunction(window,'funName1');
72 |
73 |
74 | ## # getJSObject(target, names)
75 | * 说明:
76 |
77 | 获取Object对象
78 |
79 | * 参数:
80 |
81 | * {Object} target:必需。Object定义的上下文。
82 | * {String} names:必需。Objcet名称。
83 | * 返回值:
84 |
85 | {Object}获取到的Object
86 | * 用法:
87 | u.getJSObject(window,'funName1'); //获取window对象上的funName1对象
88 |
89 |
90 | ## # each(obj,callback)
91 | * 说明:
92 |
93 | 遍历传入的obj执行callback方法
94 |
95 | * 参数:
96 |
97 | * {Object}/{Array} obj:必需。需要进行遍历的对象或数组。
98 | * {function} callback:必需。需要执行的function。
99 | * 返回值:
100 |
101 | 无
102 | * 用法:
103 | var tmpdata = [];
104 | u.each(target_div.querySelectorAll(".m_context"),function(i,node){
105 | tmpdata[i] = node.innerHTML
106 | })
107 | //遍历将class为m_context的HTML的内容翻入数组tmpdata中。
108 |
109 |
110 | ## # getStyle(element,key)
111 | * 说明:
112 |
113 | 获取HTML元素的style属性。
114 |
115 | * 参数:
116 | * {HTMLElement} element:必需。HTML元素。
117 | * {String} key:必需。需要获取的style属性名称。
118 | * 返回值:
119 |
120 | HTML元素的style属性值
121 | * 用法:
122 | u.getStyle(document.getElementById('id1'), 'width');
123 |
124 | ## # getZIndex()
125 | * 说明:
126 |
127 | 统一zindex值, 不同控件每次显示时都取最大的zindex,防止显示错乱
128 |
129 | * 参数:
130 |
131 | 无
132 |
133 | * 返回值:
134 |
135 | 新的zindex最大值
136 | * 用法:
137 | u.getZIndex();
138 |
139 |
140 |
141 |
142 | ## # getOffset(ele, offset)
143 | * 说明:
144 |
145 | 获取/设置元素`ele`相对顶层`body`的偏移量
146 |
147 | * 参数:
148 | * {HTMLElement} element:必需。目标对象
149 | * {Object} config:可选。设置的元素偏移量。默认则最终返回`ele`相对`body`的偏移量
150 | * 返回值:
151 |
152 | {Object}:包含`top`,`left`值
153 | * 用法:
154 | var offsetObj = {
155 | top : 10,
156 | left : 20
157 | };
158 | var ele = document.getElementById('tit');
159 |
160 | u.getOffset(ele,offsetObj) // {top: 120, left:100}
161 |
162 |
163 |
164 | ## # getScroll(ele, offset)
165 |
166 | - 说明:
167 |
168 | 获取/设置元素`ele`滚动的偏移量
169 |
170 | - 参数:
171 |
172 | - {HTMLElement} element:必需。目标对象
173 | - {Object} config:可选。设置的元素偏移量。默认则最终返回`ele`相对浏览器顶部的偏移量
174 |
175 | - 返回值:
176 |
177 | {Object}:包含`top`,`left`值
178 |
179 | - 用法:
180 |
181 | ```
182 | 同getOffset
183 | ```
184 |
185 |
186 |
187 | ## # ajax({...})
188 |
189 | - 说明:
190 |
191 | 执行Ajax数交互
192 |
193 | - 参数:
194 |
195 | ```
196 | {
197 | url: 'test.html',
198 | type: 'GET'
199 | success: function(){},
200 | async: true,
201 | error: function(){},
202 | }
203 | ```
204 |
205 |
206 |
207 | - {String} url:必需,文件在服务器上的位置
208 | - {String} type:可选,默认为`post`
209 | - {Function} success:可选,回调函数
210 | - {Function} error:可选,回调函数
211 | - {Boolean} async: 可选,默认为`true`
212 |
213 | - 返回值:
214 |
215 | {Object}
216 |
217 | - 用法:
218 |
219 | ```
220 |
221 | document.getElementById('btn').addEventListener('click', function(){
222 | u.ajax({
223 | url: './package.json',
224 | type: 'GET',
225 | success: function(data){
226 | alert(data)
227 | },
228 | error: function(){
229 | alert("error")
230 | }
231 | })
232 | })
233 | ```
234 |
235 |
--------------------------------------------------------------------------------
/src/class.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : Sparrow class
3 | * Author : Kvkens(yueming@yonyou.com)
4 | * Date : 2016-07-28 08:45:39
5 | */
6 |
7 | var Class = function(o) {
8 | if(!(this instanceof Class) && isFunction(o)) {
9 | return classify(o);
10 | }
11 | }
12 |
13 | // Create a new Class.
14 | //
15 | // var SuperPig = Class.create({
16 | // Extends: Animal,
17 | // Implements: Flyable,
18 | // initialize: function() {
19 | // SuperPig.superclass.initialize.apply(this, arguments)
20 | // },
21 | // Statics: {
22 | // COLOR: 'red'
23 | // }
24 | // })
25 | //
26 | Class.create = function(parent, properties) {
27 | if(!isFunction(parent)) {
28 | properties = parent;
29 | parent = null;
30 | }
31 |
32 | properties || (properties = {});
33 | parent || (parent = properties.Extends || Class);
34 | properties.Extends = parent;
35 |
36 | // The created class constructor
37 | function SubClass() {
38 | var ret;
39 | // Call the parent constructor.
40 | parent.apply(this, arguments);
41 |
42 | // Only call initialize in self constructor.
43 | if(this.constructor === SubClass && this.initialize) {
44 | ret = this.initialize.apply(this, arguments);
45 | }
46 | return ret ? ret : this;
47 | }
48 |
49 | // Inherit class (static) properties from parent.
50 | if(parent !== Class) {
51 | mix(SubClass, parent, parent.StaticsWhiteList);
52 | }
53 |
54 | // Add instance properties to the subclass.
55 | implement.call(SubClass, properties);
56 |
57 | // Make subclass extendable.
58 | return classify(SubClass);
59 | }
60 |
61 | function implement(properties) {
62 | var key, value
63 |
64 | for(key in properties) {
65 | value = properties[key];
66 |
67 | if(Class.Mutators.hasOwnProperty(key)) {
68 | Class.Mutators[key].call(this, value);
69 | } else {
70 | this.prototype[key] = value;
71 | }
72 | }
73 | }
74 |
75 | // Create a sub Class based on `Class`.
76 | Class.extend = function(properties) {
77 | properties || (properties = {});
78 | properties.Extends = this;
79 |
80 | return Class.create(properties);
81 | }
82 |
83 | function classify(cls) {
84 | cls.extend = Class.extend;
85 | cls.implement = implement;
86 | return cls;
87 | }
88 |
89 | // Mutators define special properties.
90 | Class.Mutators = {
91 |
92 | 'Extends': function(parent) {
93 | var existed = this.prototype;
94 | var proto = createProto(parent.prototype);
95 |
96 | // Keep existed properties.
97 | mix(proto, existed);
98 |
99 | // Enforce the constructor to be what we expect.
100 | proto.constructor = this;
101 |
102 | // Set the prototype chain to inherit from `parent`.
103 | this.prototype = proto;
104 |
105 | // Set a convenience property in case the parent's prototype is
106 | // needed later.
107 | this.superclass = parent.prototype;
108 | },
109 |
110 | 'Implements': function(items) {
111 | isArray(items) || (items = [items]);
112 | var proto = this.prototype,
113 | item;
114 |
115 | while(item = items.shift()) {
116 | mix(proto, item.prototype || item);
117 | }
118 | },
119 |
120 | 'Statics': function(staticProperties) {
121 | mix(this, staticProperties);
122 | }
123 | }
124 |
125 | // Shared empty constructor function to aid in prototype-chain creation.
126 | function Ctor() {}
127 |
128 | // See: http://jsperf.com/object-create-vs-new-ctor
129 | var createProto = Object.__proto__ ?
130 | function(proto) {
131 | return {
132 | __proto__: proto
133 | }
134 | } :
135 | function(proto) {
136 | Ctor.prototype = proto;
137 | return new Ctor();
138 | }
139 |
140 | // Helpers
141 | // ------------
142 |
143 | function mix(r, s, wl) {
144 | // Copy "all" properties including inherited ones.
145 | for(var p in s) {
146 | if(s.hasOwnProperty(p)) {
147 | if(wl && indexOf(wl, p) === -1) continue;
148 |
149 | // 在 iPhone 1 代等设备的 Safari 中,prototype 也会被枚举出来,需排除
150 | if(p !== 'prototype') {
151 | r[p] = s[p];
152 | }
153 | }
154 | }
155 | }
156 |
157 | var toString = Object.prototype.toString;
158 |
159 | var isArray = Array.isArray || function(val) {
160 | return toString.call(val) === '[object Array]';
161 | }
162 |
163 | var isFunction = function(val) {
164 | return toString.call(val) === '[object Function]';
165 | }
166 |
167 | var indexOf = function(arr, item) {
168 | if(Array.prototype.indexOf && arr.indexOf) {
169 | return arr.indexOf(item);
170 | } else {
171 | for(var i = 0, len = arr.length; i < len; i++) {
172 | if(arr[i] === item) {
173 | return i;
174 | }
175 | }
176 | return -1;
177 | }
178 | }
179 |
180 | export {
181 | Class,
182 | isFunction
183 | };
--------------------------------------------------------------------------------
/lib/class.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : Sparrow class
3 | * Author : Kvkens(yueming@yonyou.com)
4 | * Date : 2016-07-28 08:45:39
5 | */
6 |
7 | var Class = function Class(o) {
8 | if (!(this instanceof Class) && isFunction(o)) {
9 | return classify(o);
10 | }
11 | };
12 |
13 | // Create a new Class.
14 | //
15 | // var SuperPig = Class.create({
16 | // Extends: Animal,
17 | // Implements: Flyable,
18 | // initialize: function() {
19 | // SuperPig.superclass.initialize.apply(this, arguments)
20 | // },
21 | // Statics: {
22 | // COLOR: 'red'
23 | // }
24 | // })
25 | //
26 | Class.create = function (parent, properties) {
27 | if (!isFunction(parent)) {
28 | properties = parent;
29 | parent = null;
30 | }
31 |
32 | properties || (properties = {});
33 | parent || (parent = properties.Extends || Class);
34 | properties.Extends = parent;
35 |
36 | // The created class constructor
37 | function SubClass() {
38 | var ret;
39 | // Call the parent constructor.
40 | parent.apply(this, arguments);
41 |
42 | // Only call initialize in self constructor.
43 | if (this.constructor === SubClass && this.initialize) {
44 | ret = this.initialize.apply(this, arguments);
45 | }
46 | return ret ? ret : this;
47 | }
48 |
49 | // Inherit class (static) properties from parent.
50 | if (parent !== Class) {
51 | mix(SubClass, parent, parent.StaticsWhiteList);
52 | }
53 |
54 | // Add instance properties to the subclass.
55 | implement.call(SubClass, properties);
56 |
57 | // Make subclass extendable.
58 | return classify(SubClass);
59 | };
60 |
61 | function implement(properties) {
62 | var key, value;
63 |
64 | for (key in properties) {
65 | value = properties[key];
66 |
67 | if (Class.Mutators.hasOwnProperty(key)) {
68 | Class.Mutators[key].call(this, value);
69 | } else {
70 | this.prototype[key] = value;
71 | }
72 | }
73 | }
74 |
75 | // Create a sub Class based on `Class`.
76 | Class.extend = function (properties) {
77 | properties || (properties = {});
78 | properties.Extends = this;
79 |
80 | return Class.create(properties);
81 | };
82 |
83 | function classify(cls) {
84 | cls.extend = Class.extend;
85 | cls.implement = implement;
86 | return cls;
87 | }
88 |
89 | // Mutators define special properties.
90 | Class.Mutators = {
91 |
92 | 'Extends': function Extends(parent) {
93 | var existed = this.prototype;
94 | var proto = createProto(parent.prototype);
95 |
96 | // Keep existed properties.
97 | mix(proto, existed);
98 |
99 | // Enforce the constructor to be what we expect.
100 | proto.constructor = this;
101 |
102 | // Set the prototype chain to inherit from `parent`.
103 | this.prototype = proto;
104 |
105 | // Set a convenience property in case the parent's prototype is
106 | // needed later.
107 | this.superclass = parent.prototype;
108 | },
109 |
110 | 'Implements': function Implements(items) {
111 | isArray(items) || (items = [items]);
112 | var proto = this.prototype,
113 | item;
114 |
115 | while (item = items.shift()) {
116 | mix(proto, item.prototype || item);
117 | }
118 | },
119 |
120 | 'Statics': function Statics(staticProperties) {
121 | mix(this, staticProperties);
122 | }
123 |
124 | // Shared empty constructor function to aid in prototype-chain creation.
125 | };function Ctor() {}
126 |
127 | // See: http://jsperf.com/object-create-vs-new-ctor
128 | var createProto = Object.__proto__ ? function (proto) {
129 | return {
130 | __proto__: proto
131 | };
132 | } : function (proto) {
133 | Ctor.prototype = proto;
134 | return new Ctor();
135 | };
136 |
137 | // Helpers
138 | // ------------
139 |
140 | function mix(r, s, wl) {
141 | // Copy "all" properties including inherited ones.
142 | for (var p in s) {
143 | if (s.hasOwnProperty(p)) {
144 | if (wl && indexOf(wl, p) === -1) continue;
145 |
146 | // 在 iPhone 1 代等设备的 Safari 中,prototype 也会被枚举出来,需排除
147 | if (p !== 'prototype') {
148 | r[p] = s[p];
149 | }
150 | }
151 | }
152 | }
153 |
154 | var toString = Object.prototype.toString;
155 |
156 | var isArray = Array.isArray || function (val) {
157 | return toString.call(val) === '[object Array]';
158 | };
159 |
160 | var isFunction = function isFunction(val) {
161 | return toString.call(val) === '[object Function]';
162 | };
163 |
164 | var indexOf = function indexOf(arr, item) {
165 | if (Array.prototype.indexOf && arr.indexOf) {
166 | return arr.indexOf(item);
167 | } else {
168 | for (var i = 0, len = arr.length; i < len; i++) {
169 | if (arr[i] === item) {
170 | return i;
171 | }
172 | }
173 | return -1;
174 | }
175 | };
176 |
177 | export { Class, isFunction };
--------------------------------------------------------------------------------
/lib/fetch.js:
--------------------------------------------------------------------------------
1 | import { extend } from './extend';
2 | var getHost = function getHost() {
3 | var key = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'api';
4 |
5 | var hosts = {
6 | api: {
7 | production: process.env.HOST || "",
8 | development: process.env.HOST || ""
9 | }
10 | };
11 | return hosts[key][process.env.NODE_ENV];
12 | };
13 |
14 | var fetchTools = {
15 | params: function params(_params) {
16 | try {
17 | return Object.keys(_params).map(function (key) {
18 | var param = _params[key];
19 | switch (typeof param === 'undefined' ? 'undefined' : babelHelpers['typeof'](param)) {
20 | case 'object':
21 | param = escape(JSON.stringify(param));
22 | break;
23 | case 'undefined':
24 | param = '';
25 | break;
26 | default:
27 | break;
28 | }
29 | return key + '=' + param;
30 | }).join('&');
31 | } catch (e) {
32 | console.log('error in urlParams');
33 | return '';
34 | }
35 | },
36 | fetch: function (_fetch) {
37 | function fetch(_x2, _x3) {
38 | return _fetch.apply(this, arguments);
39 | }
40 |
41 | fetch.toString = function () {
42 | return _fetch.toString();
43 | };
44 |
45 | return fetch;
46 | }(function (url, options) {
47 | return fetch(url, options).then(function (response) {
48 | if (response.ok) {
49 | return response.text().then(function (text) {
50 | if (text) {
51 | var result = {
52 | success: false,
53 | message: '接口请求失败'
54 | };
55 | try {
56 | result = JSON.parse(text);
57 | } catch (e) {
58 | return Promise.reject(new Error('接口返回数据无法解析'));
59 | }
60 | var _result = result,
61 | success = _result.success,
62 | data = _result.data,
63 | message = _result.message;
64 |
65 | if (success) {
66 | return Promise.resolve(data);
67 | }
68 | return Promise.reject(message);
69 | }
70 | return Promise.reject(new Error('接口未返回数据'));
71 | });
72 | }
73 | return Promise.reject(new Error('请求失败'));
74 | });
75 | }),
76 | options: function options() {
77 | var method = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'get';
78 |
79 | var _options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
80 |
81 | return extend({
82 | method: method.toUpperCase(),
83 | credentials: 'include',
84 | cache: 'no-cache',
85 | headers: {
86 | 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
87 | 'isAjax': 1
88 | }
89 | }, _options);
90 | },
91 | urlMaker: function urlMaker(url) {
92 | if (!url) {
93 | throw new Error('has no url!');
94 | } else if (url.indexOf('http') !== 0) {
95 | url = '' + getHost() + url;
96 | }
97 | return url;
98 | }
99 | };
100 |
101 | export function post(oriUrl) {
102 | var oriParams = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
103 | var params = fetchTools.params,
104 | fetch = fetchTools.fetch,
105 | optionsMaker = fetchTools.options,
106 | urlMaker = fetchTools.urlMaker;
107 |
108 | var data = params(oriParams);
109 | var options = optionsMaker('post');
110 | options.headers['Content-Type'] = 'application/json;charset=UTF-8';
111 | try {
112 | options.body = JSON.stringify(oriParams);
113 | } catch (e) {
114 | return Promise.reject(e);
115 | }
116 | return fetch(urlMaker(oriUrl), options);
117 | }
118 |
119 | export function get(oriUrl) {
120 | var oriParams = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
121 | var params = fetchTools.params,
122 | fetch = fetchTools.fetch,
123 | options = fetchTools.options,
124 | urlMaker = fetchTools.urlMaker;
125 |
126 |
127 | var data = params(oriParams);
128 | var url = urlMaker(oriUrl);
129 | if (data) {
130 | url = url + '?' + data;
131 | }
132 | return fetch(url, options());
133 | }
--------------------------------------------------------------------------------
/src/env.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : Sparrow browser environment
3 | * Author : Kvkens(yueming@yonyou.com)
4 | * Date : 2016-07-27 21:46:50
5 | */
6 |
7 | import {extend} from './extend';
8 | var u = {};
9 |
10 |
11 | extend(u, {
12 | isIE: false,
13 | isFF: false,
14 | isOpera: false,
15 | isChrome: false,
16 | isSafari: false,
17 | isWebkit: false,
18 | isIE8_BEFORE: false,
19 | isIE8: false,
20 | isIE8_CORE: false,
21 | isIE9: false,
22 | isIE9_CORE: false,
23 | isIE10: false,
24 | isIE10_ABOVE: false,
25 | isIE11: false,
26 | isEdge: false,
27 | isIOS: false,
28 | isIphone: false,
29 | isIPAD: false,
30 | isStandard: false,
31 | version: 0,
32 | isWin: false,
33 | isUnix: false,
34 | isLinux: false,
35 | isAndroid: false,
36 | isAndroidPAD:false,
37 | isAndroidPhone:false,
38 | isMac: false,
39 | hasTouch: false,
40 | isMobile: false
41 | });
42 |
43 | (function() {
44 | var userAgent = navigator.userAgent,
45 | rMsie = /(msie\s|trident.*rv:)([\w.]+)/,
46 | rFirefox = /(firefox)\/([\w.]+)/,
47 | rOpera = /(opera).+version\/([\w.]+)/,
48 | rChrome = /(chrome)\/([\w.]+)/,
49 | rSafari = /version\/([\w.]+).*(safari)/,
50 | version,
51 | ua = userAgent.toLowerCase(),
52 | s,
53 | browserMatch = {
54 | browser: "",
55 | version: ''
56 | },
57 | match = rMsie.exec(ua);
58 |
59 | if(match != null) {
60 | browserMatch = {
61 | browser: "IE",
62 | version: match[2] || "0"
63 | };
64 | }
65 | match = rFirefox.exec(ua);
66 | if(match != null) {
67 | browserMatch = {
68 | browser: match[1] || "",
69 | version: match[2] || "0"
70 | };
71 | }
72 | match = rOpera.exec(ua);
73 | if(match != null) {
74 | browserMatch = {
75 | browser: match[1] || "",
76 | version: match[2] || "0"
77 | };
78 | }
79 | match = rChrome.exec(ua);
80 | if(match != null) {
81 | browserMatch = {
82 | browser: match[1] || "",
83 | version: match[2] || "0"
84 | };
85 | }
86 | match = rSafari.exec(ua);
87 | if(match != null) {
88 | browserMatch = {
89 | browser: match[2] || "",
90 | version: match[1] || "0"
91 | };
92 | }
93 |
94 | if(userAgent.indexOf("Edge") > -1){
95 | u.isEdge = true;
96 | }
97 | if(s = ua.match(/opera.([\d.]+)/)) {
98 | u.isOpera = true;
99 | } else if(browserMatch.browser == "IE" && browserMatch.version == 11) {
100 | u.isIE11 = true;
101 | u.isIE = true;
102 | } else if(s = ua.match(/chrome\/([\d.]+)/)) {
103 | u.isChrome = true;
104 | u.isStandard = true;
105 | } else if(s = ua.match(/version\/([\d.]+).*safari/)) {
106 | u.isSafari = true;
107 | u.isStandard = true;
108 | } else if(s = ua.match(/gecko/)) {
109 | //add by licza : support XULRunner
110 | u.isFF = true;
111 | u.isStandard = true;
112 | } else if(s = ua.match(/msie ([\d.]+)/)) {
113 | u.isIE = true;
114 | } else if(s = ua.match(/firefox\/([\d.]+)/)) {
115 | u.isFF = true;
116 | u.isStandard = true;
117 | }
118 | if(ua.match(/webkit\/([\d.]+)/)) {
119 | u.isWebkit = true;
120 | }
121 | if(ua.match(/ipad/i)) {
122 | u.isIOS = true;
123 | u.isIPAD = true;
124 | u.isStandard = true;
125 | }
126 |
127 | if(ua.match(/iphone/i)) {
128 | u.isIOS = true;
129 | u.isIphone = true;
130 | }
131 |
132 | if((navigator.platform == "Mac68K") || (navigator.platform == "MacPPC") || (navigator.platform == "Macintosh") || (navigator.platform == "MacIntel")) {
133 | //u.isIOS = true;
134 | u.isMac = true;
135 | }
136 |
137 | if((navigator.platform == "Win32") || (navigator.platform == "Windows") || (navigator.platform == "Win64")) {
138 | u.isWin = true;
139 | }
140 |
141 | if((navigator.platform == "X11") && !u.isWin && !u.isMac) {
142 | u.isUnix = true;
143 | }
144 | if((String(navigator.platform).indexOf("Linux") > -1)) {
145 | u.isLinux = true;
146 | }
147 |
148 | if(ua.indexOf('Android') > -1 || ua.indexOf('android') > -1 || ua.indexOf('Adr') > -1 || ua.indexOf('adr') > -1) {
149 | u.isAndroid = true;
150 | }
151 |
152 | u.version = version ? (browserMatch.version ? browserMatch.version : 0) : 0;
153 | if(u.isAndroid){
154 | if(window.screen.width>=768&&window.screen.width<1024){
155 | u.isAndroidPAD=true;
156 | }
157 | if(window.screen.width<=768) {
158 | u.isAndroidPhone = true;
159 | }
160 | }
161 | if(u.isIE) {
162 | var intVersion = parseInt(u.version);
163 | var mode = document.documentMode;
164 | if(mode == null) {
165 | if(intVersion == 6 || intVersion == 7) {
166 | u.isIE8_BEFORE = true;
167 | }
168 | } else {
169 | if(mode == 7) {
170 | u.isIE8_BEFORE = true;
171 | } else if(mode == 8) {
172 | u.isIE8 = true;
173 | } else if(mode == 9) {
174 | u.isIE9 = true;
175 | u.isSTANDARD = true;
176 | } else if(mode == 10) {
177 | u.isIE10 = true;
178 | u.isSTANDARD = true;
179 | u.isIE10_ABOVE = true;
180 | } else {
181 | u.isSTANDARD = true;
182 | }
183 | if(intVersion == 8) {
184 | u.isIE8_CORE = true;
185 | } else if(intVersion == 9) {
186 | u.isIE9_CORE = true;
187 | } else if(browserMatch.version == 11) {
188 | u.isIE11 = true;
189 | }
190 | }
191 | }
192 | if("ontouchend" in document) {
193 | u.hasTouch = true;
194 | }
195 | if(u.isIphone || u.isAndroidPhone)
196 | u.isMobile = true;
197 |
198 | })();
199 |
200 | var env = u;
201 | export {env};
202 |
--------------------------------------------------------------------------------
/lib/env.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : Sparrow browser environment
3 | * Author : Kvkens(yueming@yonyou.com)
4 | * Date : 2016-07-27 21:46:50
5 | */
6 |
7 | import { extend } from './extend';
8 | var u = {};
9 |
10 | extend(u, {
11 | isIE: false,
12 | isFF: false,
13 | isOpera: false,
14 | isChrome: false,
15 | isSafari: false,
16 | isWebkit: false,
17 | isIE8_BEFORE: false,
18 | isIE8: false,
19 | isIE8_CORE: false,
20 | isIE9: false,
21 | isIE9_CORE: false,
22 | isIE10: false,
23 | isIE10_ABOVE: false,
24 | isIE11: false,
25 | isEdge: false,
26 | isIOS: false,
27 | isIphone: false,
28 | isIPAD: false,
29 | isStandard: false,
30 | version: 0,
31 | isWin: false,
32 | isUnix: false,
33 | isLinux: false,
34 | isAndroid: false,
35 | isAndroidPAD: false,
36 | isAndroidPhone: false,
37 | isMac: false,
38 | hasTouch: false,
39 | isMobile: false
40 | });
41 |
42 | (function () {
43 | var userAgent = navigator.userAgent,
44 | rMsie = /(msie\s|trident.*rv:)([\w.]+)/,
45 | rFirefox = /(firefox)\/([\w.]+)/,
46 | rOpera = /(opera).+version\/([\w.]+)/,
47 | rChrome = /(chrome)\/([\w.]+)/,
48 | rSafari = /version\/([\w.]+).*(safari)/,
49 | version,
50 | ua = userAgent.toLowerCase(),
51 | s,
52 | browserMatch = {
53 | browser: "",
54 | version: ''
55 | },
56 | match = rMsie.exec(ua);
57 |
58 | if (match != null) {
59 | browserMatch = {
60 | browser: "IE",
61 | version: match[2] || "0"
62 | };
63 | }
64 | match = rFirefox.exec(ua);
65 | if (match != null) {
66 | browserMatch = {
67 | browser: match[1] || "",
68 | version: match[2] || "0"
69 | };
70 | }
71 | match = rOpera.exec(ua);
72 | if (match != null) {
73 | browserMatch = {
74 | browser: match[1] || "",
75 | version: match[2] || "0"
76 | };
77 | }
78 | match = rChrome.exec(ua);
79 | if (match != null) {
80 | browserMatch = {
81 | browser: match[1] || "",
82 | version: match[2] || "0"
83 | };
84 | }
85 | match = rSafari.exec(ua);
86 | if (match != null) {
87 | browserMatch = {
88 | browser: match[2] || "",
89 | version: match[1] || "0"
90 | };
91 | }
92 |
93 | if (userAgent.indexOf("Edge") > -1) {
94 | u.isEdge = true;
95 | }
96 | if (s = ua.match(/opera.([\d.]+)/)) {
97 | u.isOpera = true;
98 | } else if (browserMatch.browser == "IE" && browserMatch.version == 11) {
99 | u.isIE11 = true;
100 | u.isIE = true;
101 | } else if (s = ua.match(/chrome\/([\d.]+)/)) {
102 | u.isChrome = true;
103 | u.isStandard = true;
104 | } else if (s = ua.match(/version\/([\d.]+).*safari/)) {
105 | u.isSafari = true;
106 | u.isStandard = true;
107 | } else if (s = ua.match(/gecko/)) {
108 | //add by licza : support XULRunner
109 | u.isFF = true;
110 | u.isStandard = true;
111 | } else if (s = ua.match(/msie ([\d.]+)/)) {
112 | u.isIE = true;
113 | } else if (s = ua.match(/firefox\/([\d.]+)/)) {
114 | u.isFF = true;
115 | u.isStandard = true;
116 | }
117 | if (ua.match(/webkit\/([\d.]+)/)) {
118 | u.isWebkit = true;
119 | }
120 | if (ua.match(/ipad/i)) {
121 | u.isIOS = true;
122 | u.isIPAD = true;
123 | u.isStandard = true;
124 | }
125 |
126 | if (ua.match(/iphone/i)) {
127 | u.isIOS = true;
128 | u.isIphone = true;
129 | }
130 |
131 | if (navigator.platform == "Mac68K" || navigator.platform == "MacPPC" || navigator.platform == "Macintosh" || navigator.platform == "MacIntel") {
132 | //u.isIOS = true;
133 | u.isMac = true;
134 | }
135 |
136 | if (navigator.platform == "Win32" || navigator.platform == "Windows" || navigator.platform == "Win64") {
137 | u.isWin = true;
138 | }
139 |
140 | if (navigator.platform == "X11" && !u.isWin && !u.isMac) {
141 | u.isUnix = true;
142 | }
143 | if (String(navigator.platform).indexOf("Linux") > -1) {
144 | u.isLinux = true;
145 | }
146 |
147 | if (ua.indexOf('Android') > -1 || ua.indexOf('android') > -1 || ua.indexOf('Adr') > -1 || ua.indexOf('adr') > -1) {
148 | u.isAndroid = true;
149 | }
150 |
151 | u.version = version ? browserMatch.version ? browserMatch.version : 0 : 0;
152 | if (u.isAndroid) {
153 | if (window.screen.width >= 768 && window.screen.width < 1024) {
154 | u.isAndroidPAD = true;
155 | }
156 | if (window.screen.width <= 768) {
157 | u.isAndroidPhone = true;
158 | }
159 | }
160 | if (u.isIE) {
161 | var intVersion = parseInt(u.version);
162 | var mode = document.documentMode;
163 | if (mode == null) {
164 | if (intVersion == 6 || intVersion == 7) {
165 | u.isIE8_BEFORE = true;
166 | }
167 | } else {
168 | if (mode == 7) {
169 | u.isIE8_BEFORE = true;
170 | } else if (mode == 8) {
171 | u.isIE8 = true;
172 | } else if (mode == 9) {
173 | u.isIE9 = true;
174 | u.isSTANDARD = true;
175 | } else if (mode == 10) {
176 | u.isIE10 = true;
177 | u.isSTANDARD = true;
178 | u.isIE10_ABOVE = true;
179 | } else {
180 | u.isSTANDARD = true;
181 | }
182 | if (intVersion == 8) {
183 | u.isIE8_CORE = true;
184 | } else if (intVersion == 9) {
185 | u.isIE9_CORE = true;
186 | } else if (browserMatch.version == 11) {
187 | u.isIE11 = true;
188 | }
189 | }
190 | }
191 | if ("ontouchend" in document) {
192 | u.hasTouch = true;
193 | }
194 | if (u.isIphone || u.isAndroidPhone) u.isMobile = true;
195 | })();
196 |
197 | var env = u;
198 | export { env };
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "ecmaFeatures": {
3 | "globalReturn": true,
4 | "jsx": true,
5 | "modules": true
6 | },
7 |
8 | "env": {
9 | "browser": true,
10 | "es6": true,
11 | "node": true
12 | },
13 |
14 | "globals": {
15 | "document": false,
16 | "escape": false,
17 | "navigator": false,
18 | "unescape": false,
19 | "window": false,
20 | "describe": true,
21 | "before": true,
22 | "it": true,
23 | "expect": true,
24 | "sinon": true
25 | },
26 |
27 | "parser": "babel-eslint",
28 |
29 | "plugins": [
30 |
31 | ],
32 |
33 | "rules": {
34 | /* "block-scoped-var": 2,
35 | "brace-style": [2, "1tbs", { "allowSingleLine": true }],
36 | "camelcase": [2, { "properties": "always" }],
37 | "comma-dangle": [2, "never"],
38 | "comma-spacing": [2, { "before": false, "after": true }],
39 | "comma-style": [2, "last"],
40 | "complexity": 0,
41 | "consistent-return": 2,
42 | "consistent-this": 0,
43 | "curly": [2, "multi-line"],
44 | "default-case": 0,
45 | "dot-location": [2, "property"],
46 | "dot-notation": 0,
47 | "eol-last": 2,
48 | "eqeqeq": [2, "allow-null"],
49 | "func-names": 0,
50 | "func-style": 0,
51 | "generator-star-spacing": [2, "both"],
52 | "guard-for-in": 0,
53 | "handle-callback-err": [2, "^(err|error|anySpecificError)$" ],
54 | "indent": [2, 2, { "SwitchCase": 1 }],
55 | "key-spacing": [2, { "beforeColon": false, "afterColon": true }],
56 | "linebreak-style": 0,
57 | "max-depth": 0,
58 | "max-len": [2, 120, 4],
59 | "max-nested-callbacks": 0,
60 | "max-params": 0,
61 | "max-statements": 0,
62 | "new-cap": [2, { "newIsCap": true, "capIsNew": false }],
63 | "newline-after-var": [2, "always"],
64 | "new-parens": 2,
65 | "no-alert": 0,
66 | "no-array-constructor": 2,
67 | "no-bitwise": 0,
68 | "no-caller": 2,
69 | "no-catch-shadow": 0,
70 | "no-cond-assign": 2,
71 | "no-console": 0,
72 | "no-constant-condition": 0,
73 | "no-continue": 0,
74 | "no-control-regex": 2,
75 | "no-debugger": 2,
76 | "no-delete-var": 2,
77 | "no-div-regex": 0,
78 | "no-dupe-args": 2,
79 | "no-dupe-keys": 2,
80 | "no-duplicate-case": 2,
81 | "no-else-return": 2,
82 | "no-empty": 0,
83 | "no-empty-character-class": 2,
84 | "no-empty-label": 2,
85 | "no-eq-null": 0,
86 | "no-eval": 2,
87 | "no-ex-assign": 2,
88 | "no-extend-native": 2,
89 | "no-extra-bind": 2,
90 | "no-extra-boolean-cast": 2,
91 | "no-extra-parens": 0,
92 | "no-extra-semi": 0,
93 | "no-extra-strict": 0,
94 | "no-fallthrough": 2,
95 | "no-floating-decimal": 2,
96 | "no-func-assign": 2,
97 | "no-implied-eval": 2,
98 | "no-inline-comments": 0,
99 | "no-inner-declarations": [2, "functions"],
100 | "no-invalid-regexp": 2,
101 | "no-irregular-whitespace": 2,
102 | "no-iterator": 2,
103 | "no-label-var": 2,
104 | "no-labels": 2,
105 | "no-lone-blocks": 0,
106 | "no-lonely-if": 0,
107 | "no-loop-func": 0,
108 | "no-mixed-requires": 0,
109 | "no-mixed-spaces-and-tabs": [2, false],
110 | "no-multi-spaces": 2,
111 | "no-multi-str": 2,
112 | "no-multiple-empty-lines": [2, { "max": 1 }],
113 | "no-native-reassign": 2,
114 | "no-negated-in-lhs": 2,
115 | "no-nested-ternary": 0,
116 | "no-new": 2,
117 | "no-new-func": 2,
118 | "no-new-object": 2,
119 | "no-new-require": 2,
120 | "no-new-wrappers": 2,
121 | "no-obj-calls": 2,
122 | "no-octal": 2,
123 | "no-octal-escape": 2,
124 | "no-path-concat": 0,
125 | "no-plusplus": 0,
126 | "no-process-env": 0,
127 | "no-process-exit": 0,
128 | "no-proto": 2,
129 | "no-redeclare": 2,
130 | "no-regex-spaces": 2,
131 | "no-reserved-keys": 0,
132 | "no-restricted-modules": 0,
133 | "no-return-assign": 2,
134 | "no-script-url": 0,
135 | "no-self-compare": 2,
136 | "no-sequences": 2,
137 | "no-shadow": 0,
138 | "no-shadow-restricted-names": 2,
139 | "no-spaced-func": 2,
140 | "no-sparse-arrays": 2,
141 | "no-sync": 0,
142 | "no-ternary": 0,
143 | "no-throw-literal": 2,
144 | "no-trailing-spaces": 2,
145 | "no-undef": 2,
146 | "no-undef-init": 2,
147 | "no-undefined": 0,
148 | "no-underscore-dangle": 0,
149 | "no-unneeded-ternary": 2,
150 | "no-unreachable": 2,
151 | "no-unused-expressions": 0,
152 | "no-unused-vars": [2, { "vars": "all", "args": "none" }],
153 | "no-use-before-define": 2,
154 | "no-var": 0,
155 | "no-void": 0,
156 | "no-warning-comments": 0,
157 | "no-with": 2,
158 | "one-var": 0,
159 | "operator-assignment": 0,
160 | "operator-linebreak": [2, "after"],
161 | "padded-blocks": 0,
162 | "quote-props": 0,
163 | "quotes": [2, "single", "avoid-escape"],
164 | "radix": 2,
165 | "semi": [2, "always"],
166 | "semi-spacing": 0,
167 | "sort-vars": 0,
168 | "space-after-keywords": [2, "always"],
169 | "space-before-blocks": [2, "always"],
170 | "space-before-function-paren": [2, {"anonymous": "always", "named": "never"}],
171 | "space-in-brackets": 0,
172 | "space-in-parens": [2, "never"],
173 | "space-infix-ops": 2,
174 | "space-return-throw-case": 2,
175 | "space-unary-ops": [2, { "words": true, "nonwords": false }],
176 | "spaced-comment": [2, "always"],
177 | "strict": 0,
178 | "use-isnan": 2,
179 | "valid-jsdoc": 0,
180 | "valid-typeof": 2,
181 | "vars-on-top": 2,
182 | "wrap-iife": [2, "any"],
183 | "wrap-regex": 0,
184 | "yoda": [2, "never"] */
185 | }
186 | }
187 |
--------------------------------------------------------------------------------
/src/util/hotKeys.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : Sparrow hotKeys
3 | * Author : Kvkens(yueming@yonyou.com)
4 | * Date : 2016-07-28 20:25:39
5 | */
6 |
7 | import {isFunction} from '../class';
8 | import {extend} from '../extend';
9 | import {getFunction} from '../util';
10 | var hotkeys = {};
11 | hotkeys.special_keys = {
12 | 27: 'esc', 9: 'tab', 32: 'space', 13: 'enter', 8: 'backspace', 145: 'scroll', 20: 'capslock',
13 | 144: 'numlock', 19: 'pause', 45: 'insert', 36: 'home', 46: 'del', 35: 'end', 33: 'pageup',
14 | 34: 'pagedown', 37: 'left', 38: 'up', 39: 'right', 40: 'down', 112: 'f1', 113: 'f2', 114: 'f3',
15 | 115: 'f4', 116: 'f5', 117: 'f6', 118: 'f7', 119: 'f8', 120: 'f9', 121: 'f10', 122: 'f11', 123: 'f12'
16 | };
17 |
18 | hotkeys.shift_nums = {
19 | "`": "~", "1": "!", "2": "@", "3": "#", "4": "$", "5": "%", "6": "^", "7": "&",
20 | "8": "*", "9": "(", "0": ")", "-": "_", "=": "+", ";": ":", "'": "\"", ",": "<",
21 | ".": ">", "/": "?", "\\": "|"
22 | };
23 |
24 | hotkeys.add = function (combi, options, callback) {
25 | if (isFunction(options)) {
26 | callback = options;
27 | options = {};
28 | }
29 | var opt = {},
30 | defaults = {type: 'keydown', propagate: false, disableInInput: false, target: document.body, checkParent: true},
31 | that = this;
32 | opt = extend(opt, defaults, options || {});
33 | combi = combi.toLowerCase();
34 |
35 | // inspect if keystroke matches
36 | var inspector = function (event) {
37 | //event = $.event.fix(event); // jQuery event normalization.
38 | var element = this//event.target;
39 | // @ TextNode -> nodeType == 3
40 | element = (element.nodeType == 3) ? element.parentNode : element;
41 |
42 | if (opt['disableInInput']) { // Disable shortcut keys in Input, Textarea fields
43 | var target = element;//$(element);
44 | if (target.tagName == "INPUT" || target.tagName == "TEXTAREA") {
45 | return;
46 | }
47 | }
48 | var code = event.which,
49 | type = event.type,
50 | character = String.fromCharCode(code).toLowerCase(),
51 | special = that.special_keys[code],
52 | shift = event.shiftKey,
53 | ctrl = event.ctrlKey,
54 | alt = event.altKey,
55 | propagate = true, // default behaivour
56 | mapPoint = null;
57 |
58 | // in opera + safari, the event.target is unpredictable.
59 | // for example: 'keydown' might be associated with HtmlBodyElement
60 | // or the element where you last clicked with your mouse.
61 | if (opt.checkParent) {
62 | // while (!that.all[element] && element.parentNode){
63 | while (!element['hotkeys'] && element.parentNode) {
64 | element = element.parentNode;
65 | }
66 | }
67 |
68 | // var cbMap = that.all[element].events[type].callbackMap;
69 | var cbMap = element['hotkeys'].events[type].callbackMap;
70 | if (!shift && !ctrl && !alt) { // No Modifiers
71 | mapPoint = cbMap[special] || cbMap[character]
72 | }
73 | // deals with combinaitons (alt|ctrl|shift+anything)
74 | else {
75 | var modif = '';
76 | if (alt) modif += 'alt+';
77 | if (ctrl) modif += 'ctrl+';
78 | if (shift) modif += 'shift+';
79 | // modifiers + special keys or modifiers + characters or modifiers + shift characters
80 | mapPoint = cbMap[modif + special] || cbMap[modif + character] || cbMap[modif + that.shift_nums[character]]
81 | }
82 | if (mapPoint) {
83 | mapPoint.cb(event);
84 | if (!mapPoint.propagate) {
85 | event.stopPropagation();
86 | event.preventDefault();
87 | return false;
88 | }
89 | }
90 | };
91 | // first hook for this element
92 | var data = opt.target['hotkeys'];
93 | if (!data) {
94 | opt.target['hotkeys'] = data = {events: {}};
95 | }
96 | // if (!hotkeys.all[opt.target]){
97 | // hotkeys.all[opt.target] = {events:{}};
98 | // }
99 | if (!data.events[opt.type]) {
100 | data.events[opt.type] = {callbackMap: {}};
101 | on(opt.target, opt.type, inspector);
102 | //$.event.add(opt.target, opt.type, inspector);
103 | }
104 | // if (!hotkeys.all[opt.target].events[opt.type]){
105 | // hotkeys.all[opt.target].events[opt.type] = {callbackMap: {}}
106 | // $.event.add(opt.target, opt.type, inspector);
107 | // }
108 | data.events[opt.type].callbackMap[combi] = {cb: callback, propagate: opt.propagate};
109 | // hotkeys.all[opt.target].events[opt.type].callbackMap[combi] = {cb: callback, propagate:opt.propagate};
110 | return hotkeys;
111 | };
112 | hotkeys.remove = function (exp, opt) {
113 | opt = opt || {};
114 | target = opt.target || document.body;
115 | type = opt.type || 'keydown';
116 | exp = exp.toLowerCase();
117 |
118 | delete target['hotkeys'].events[type].callbackMap[exp];
119 | };
120 |
121 | hotkeys.scan = function (element, target) {
122 | element = element || document.body;
123 | element.querySelectorAll('[u-enter]').forEach(function(el){
124 | var enterValue = el.getAttribute('u-enter');
125 | if (!enterValue) return;
126 | if (enterValue.substring(0, 1) == '#')
127 | hotkeys.add('enter', {target: this}, function () {
128 | var _el = element.querySelector(enterValue);
129 | if (_el){
130 | _el.focus();
131 | }
132 | });
133 | else {
134 | target = target || window
135 | var func = h(target, enterValue)
136 | hotkeys.add('enter', {target: this}, function () {
137 | func.call(this)
138 | })
139 | }
140 | });
141 | element.querySelectorAll('[u-hotkey]').forEach(function(el){
142 | var hotkey = el.getAttribute('u-hotkey');
143 | if (!hotkey) return;
144 | hotkeys.add(hotkey, function () {
145 | el.click();
146 | })
147 |
148 | });
149 | }
150 |
151 | var hotkeys = hotkeys;
152 |
153 | export {hotkeys};
154 |
--------------------------------------------------------------------------------
/lib/util/hotKeys.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : Sparrow hotKeys
3 | * Author : Kvkens(yueming@yonyou.com)
4 | * Date : 2016-07-28 20:25:39
5 | */
6 |
7 | import { isFunction } from '../class';
8 | import { extend } from '../extend';
9 | import { getFunction } from '../util';
10 | var hotkeys = {};
11 | hotkeys.special_keys = {
12 | 27: 'esc', 9: 'tab', 32: 'space', 13: 'enter', 8: 'backspace', 145: 'scroll', 20: 'capslock',
13 | 144: 'numlock', 19: 'pause', 45: 'insert', 36: 'home', 46: 'del', 35: 'end', 33: 'pageup',
14 | 34: 'pagedown', 37: 'left', 38: 'up', 39: 'right', 40: 'down', 112: 'f1', 113: 'f2', 114: 'f3',
15 | 115: 'f4', 116: 'f5', 117: 'f6', 118: 'f7', 119: 'f8', 120: 'f9', 121: 'f10', 122: 'f11', 123: 'f12'
16 | };
17 |
18 | hotkeys.shift_nums = {
19 | "`": "~", "1": "!", "2": "@", "3": "#", "4": "$", "5": "%", "6": "^", "7": "&",
20 | "8": "*", "9": "(", "0": ")", "-": "_", "=": "+", ";": ":", "'": "\"", ",": "<",
21 | ".": ">", "/": "?", "\\": "|"
22 | };
23 |
24 | hotkeys.add = function (combi, options, callback) {
25 | if (isFunction(options)) {
26 | callback = options;
27 | options = {};
28 | }
29 | var opt = {},
30 | defaults = { type: 'keydown', propagate: false, disableInInput: false, target: document.body, checkParent: true },
31 | that = this;
32 | opt = extend(opt, defaults, options || {});
33 | combi = combi.toLowerCase();
34 |
35 | // inspect if keystroke matches
36 | var inspector = function inspector(event) {
37 | //event = $.event.fix(event); // jQuery event normalization.
38 | var element = this; //event.target;
39 | // @ TextNode -> nodeType == 3
40 | element = element.nodeType == 3 ? element.parentNode : element;
41 |
42 | if (opt['disableInInput']) {
43 | // Disable shortcut keys in Input, Textarea fields
44 | var target = element; //$(element);
45 | if (target.tagName == "INPUT" || target.tagName == "TEXTAREA") {
46 | return;
47 | }
48 | }
49 | var code = event.which,
50 | type = event.type,
51 | character = String.fromCharCode(code).toLowerCase(),
52 | special = that.special_keys[code],
53 | shift = event.shiftKey,
54 | ctrl = event.ctrlKey,
55 | alt = event.altKey,
56 | propagate = true,
57 | // default behaivour
58 | mapPoint = null;
59 |
60 | // in opera + safari, the event.target is unpredictable.
61 | // for example: 'keydown' might be associated with HtmlBodyElement
62 | // or the element where you last clicked with your mouse.
63 | if (opt.checkParent) {
64 | // while (!that.all[element] && element.parentNode){
65 | while (!element['hotkeys'] && element.parentNode) {
66 | element = element.parentNode;
67 | }
68 | }
69 |
70 | // var cbMap = that.all[element].events[type].callbackMap;
71 | var cbMap = element['hotkeys'].events[type].callbackMap;
72 | if (!shift && !ctrl && !alt) {
73 | // No Modifiers
74 | mapPoint = cbMap[special] || cbMap[character];
75 | }
76 | // deals with combinaitons (alt|ctrl|shift+anything)
77 | else {
78 | var modif = '';
79 | if (alt) modif += 'alt+';
80 | if (ctrl) modif += 'ctrl+';
81 | if (shift) modif += 'shift+';
82 | // modifiers + special keys or modifiers + characters or modifiers + shift characters
83 | mapPoint = cbMap[modif + special] || cbMap[modif + character] || cbMap[modif + that.shift_nums[character]];
84 | }
85 | if (mapPoint) {
86 | mapPoint.cb(event);
87 | if (!mapPoint.propagate) {
88 | event.stopPropagation();
89 | event.preventDefault();
90 | return false;
91 | }
92 | }
93 | };
94 | // first hook for this element
95 | var data = opt.target['hotkeys'];
96 | if (!data) {
97 | opt.target['hotkeys'] = data = { events: {} };
98 | }
99 | // if (!hotkeys.all[opt.target]){
100 | // hotkeys.all[opt.target] = {events:{}};
101 | // }
102 | if (!data.events[opt.type]) {
103 | data.events[opt.type] = { callbackMap: {} };
104 | on(opt.target, opt.type, inspector);
105 | //$.event.add(opt.target, opt.type, inspector);
106 | }
107 | // if (!hotkeys.all[opt.target].events[opt.type]){
108 | // hotkeys.all[opt.target].events[opt.type] = {callbackMap: {}}
109 | // $.event.add(opt.target, opt.type, inspector);
110 | // }
111 | data.events[opt.type].callbackMap[combi] = { cb: callback, propagate: opt.propagate };
112 | // hotkeys.all[opt.target].events[opt.type].callbackMap[combi] = {cb: callback, propagate:opt.propagate};
113 | return hotkeys;
114 | };
115 | hotkeys.remove = function (exp, opt) {
116 | opt = opt || {};
117 | target = opt.target || document.body;
118 | type = opt.type || 'keydown';
119 | exp = exp.toLowerCase();
120 |
121 | delete target['hotkeys'].events[type].callbackMap[exp];
122 | };
123 |
124 | hotkeys.scan = function (element, target) {
125 | element = element || document.body;
126 | element.querySelectorAll('[u-enter]').forEach(function (el) {
127 | var enterValue = el.getAttribute('u-enter');
128 | if (!enterValue) return;
129 | if (enterValue.substring(0, 1) == '#') hotkeys.add('enter', { target: this }, function () {
130 | var _el = element.querySelector(enterValue);
131 | if (_el) {
132 | _el.focus();
133 | }
134 | });else {
135 | target = target || window;
136 | var func = h(target, enterValue);
137 | hotkeys.add('enter', { target: this }, function () {
138 | func.call(this);
139 | });
140 | }
141 | });
142 | element.querySelectorAll('[u-hotkey]').forEach(function (el) {
143 | var hotkey = el.getAttribute('u-hotkey');
144 | if (!hotkey) return;
145 | hotkeys.add(hotkey, function () {
146 | el.click();
147 | });
148 | });
149 | };
150 |
151 | var hotkeys = hotkeys;
152 |
153 | export { hotkeys };
--------------------------------------------------------------------------------
/lib/util/ripple.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : Sparrow ripple
3 | * Author : Kvkens(yueming@yonyou.com)
4 | * Date : 2016-07-29 08:42:13
5 | */
6 |
7 | import { env } from '../env';
8 | import { addClass, removeClass } from '../dom';
9 | import { on, off } from '../event';
10 |
11 | var URipple = function URipple(element) {
12 | if (env.isIE8 || env.isMobile || env.isAndroidPAD || env.isIPAD) return;
13 | this._element = element;
14 |
15 | // Initialize instance.
16 | this.init();
17 | };
18 | //window['URipple'] = URipple;
19 |
20 | URipple.prototype._down = function (event) {
21 | if (env.isIE8 || env.isMobile || env.isAndroidPAD || env.isIPAD) return;
22 | if (!this._rippleElement.style.width && !this._rippleElement.style.height) {
23 | var rect = this._element.getBoundingClientRect();
24 | this.rippleSize_ = Math.sqrt(rect.width * rect.width + rect.height * rect.height) * 2 + 2;
25 | if (this.rippleSize_ > 0) {
26 | this._rippleElement.style.width = this.rippleSize_ + 'px';
27 | this._rippleElement.style.height = this.rippleSize_ + 'px';
28 | }
29 | }
30 |
31 | addClass(this._rippleElement, 'is-visible');
32 |
33 | if (event.type === 'mousedown' && this._ignoringMouseDown) {
34 | this._ignoringMouseDown = false;
35 | } else {
36 | if (event.type === 'touchstart') {
37 | this._ignoringMouseDown = true;
38 | }
39 | var frameCount = this.getFrameCount();
40 | if (frameCount > 0) {
41 | return;
42 | }
43 | this.setFrameCount(1);
44 | var t = event.currentTarget || event.target || event.srcElement;
45 | var bound = t.getBoundingClientRect();
46 | var x;
47 | var y;
48 | // Check if we are handling a keyboard click.
49 | if (event.clientX === 0 && event.clientY === 0) {
50 | x = Math.round(bound.width / 2);
51 | y = Math.round(bound.height / 2);
52 | } else {
53 | var clientX = event.clientX ? event.clientX : event.touches[0].clientX;
54 | var clientY = event.clientY ? event.clientY : event.touches[0].clientY;
55 | x = Math.round(clientX - bound.left);
56 | y = Math.round(clientY - bound.top);
57 | }
58 | this.setRippleXY(x, y);
59 | this.setRippleStyles(true);
60 | if (window.requestAnimationFrame) window.requestAnimationFrame(this.animFrameHandler.bind(this));
61 | }
62 | };
63 |
64 | /**
65 | * Handle mouse / finger up on element.
66 | *
67 | * @param {Event} event The event that fired.
68 | * @private
69 | */
70 | URipple.prototype._up = function (event) {
71 | if (env.isIE8 || env.isMobile || env.isAndroidPAD || env.isIPAD) return;
72 | var self = this;
73 | // Don't fire for the artificial "mouseup" generated by a double-click.
74 | if (event && event.detail !== 2) {
75 | removeClass(this._rippleElement, 'is-visible');
76 | }
77 | // Allow a repaint to occur before removing this class, so the animation
78 | // shows for tap events, which seem to trigger a mouseup too soon after
79 | // mousedown.
80 | window.setTimeout(function () {
81 | removeClass(self._rippleElement, 'is-visible');
82 | }, 0);
83 | };
84 |
85 | /**
86 | * Getter for frameCount_.
87 | * @return {number} the frame count.
88 | */
89 | URipple.prototype.getFrameCount = function () {
90 | if (env.isIE8 || env.isMobile || env.isAndroidPAD || env.isIPAD) return;
91 | return this.frameCount_;
92 | };
93 | /**
94 | * Setter for frameCount_.
95 | * @param {number} fC the frame count.
96 | */
97 | URipple.prototype.setFrameCount = function (fC) {
98 | if (env.isIE8 || env.isMobile || env.isAndroidPAD || env.isIPAD) return;
99 | this.frameCount_ = fC;
100 | };
101 |
102 | /**
103 | * Getter for _rippleElement.
104 | * @return {Element} the ripple element.
105 | */
106 | URipple.prototype.getRippleElement = function () {
107 | if (env.isIE8 || env.isMobile || env.isAndroidPAD || env.isIPAD) return;
108 | return this._rippleElement;
109 | };
110 |
111 | /**
112 | * Sets the ripple X and Y coordinates.
113 | * @param {number} newX the new X coordinate
114 | * @param {number} newY the new Y coordinate
115 | */
116 | URipple.prototype.setRippleXY = function (newX, newY) {
117 | if (env.isIE8 || env.isMobile || env.isAndroidPAD || env.isIPAD) return;
118 | this.x_ = newX;
119 | this.y_ = newY;
120 | };
121 |
122 | /**
123 | * Sets the ripple styles.
124 | * @param {boolean} start whether or not this is the start frame.
125 | */
126 | URipple.prototype.setRippleStyles = function (start) {
127 | if (env.isIE8 || env.isMobile || env.isAndroidPAD || env.isIPAD) return;
128 | if (this._rippleElement !== null) {
129 | var transformString;
130 | var scale;
131 | var size;
132 | var offset = 'translate(' + this.x_ + 'px, ' + this.y_ + 'px)';
133 |
134 | if (start) {
135 | scale = 'scale(0.0001, 0.0001)';
136 | size = '1px';
137 | } else {
138 | scale = '';
139 | size = this.rippleSize_ + 'px';
140 | }
141 |
142 | transformString = 'translate(-50%, -50%) ' + offset + scale;
143 |
144 | this._rippleElement.style.webkitTransform = transformString;
145 | this._rippleElement.style.msTransform = transformString;
146 | this._rippleElement.style.transform = transformString;
147 |
148 | if (start) {
149 | removeClass(this._rippleElement, 'is-animating');
150 | } else {
151 | addClass(this._rippleElement, 'is-animating');
152 | }
153 | }
154 | };
155 |
156 | /**
157 | * Handles an animation frame.
158 | */
159 | URipple.prototype.animFrameHandler = function () {
160 | if (env.isIE8 || env.isMobile || env.isAndroidPAD || env.isIPAD) return;
161 | if (this.frameCount_-- > 0) {
162 | window.requestAnimationFrame(this.animFrameHandler.bind(this));
163 | } else {
164 | this.setRippleStyles(false);
165 | }
166 | };
167 |
168 | /**
169 | * Initialize element.
170 | */
171 | URipple.prototype.init = function () {
172 | if (env.isIE8 || env.isMobile || env.isAndroidPAD || env.isIPAD) return;
173 | var self = this;
174 | if (this._element) {
175 | this._rippleElement = this._element.querySelector('.u-ripple');
176 | if (!this._rippleElement) {
177 | this._rippleElement = document.createElement('span');
178 | addClass(this._rippleElement, 'u-ripple');
179 | this._element.appendChild(this._rippleElement);
180 | this._element.style.overflow = 'hidden';
181 | this._element.style.position = 'relative';
182 | }
183 | this.frameCount_ = 0;
184 | this.rippleSize_ = 0;
185 | this.x_ = 0;
186 | this.y_ = 0;
187 |
188 | // Touch start produces a compat mouse down event, which would cause a
189 | // second ripples. To avoid that, we use this property to ignore the first
190 | // mouse down after a touch start.
191 | this._ignoringMouseDown = false;
192 | on(this._element, 'mousedown', function (e) {
193 | self._down(e);
194 | });
195 | on(this._element, 'touchstart', function (e) {
196 | self._down(e);
197 | });
198 |
199 | on(this._element, 'mouseup', function (e) {
200 | self._up(e);
201 | });
202 | on(this._element, 'mouseleave', function (e) {
203 | self._up(e);
204 | });
205 | on(this._element, 'touchend', function (e) {
206 | self._up(e);
207 | });
208 | on(this._element, 'blur', function (e) {
209 | self._up(e);
210 | });
211 | }
212 | };
213 |
214 | var Ripple = URipple;
215 |
216 | export { Ripple, URipple };
--------------------------------------------------------------------------------
/src/util/ripple.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : Sparrow ripple
3 | * Author : Kvkens(yueming@yonyou.com)
4 | * Date : 2016-07-29 08:42:13
5 | */
6 |
7 | import {env} from '../env';
8 | import {addClass,removeClass} from '../dom';
9 | import {on,off} from '../event';
10 |
11 |
12 | var URipple = function URipple(element) {
13 | if (env.isIE8 || env.isMobile || env.isAndroidPAD || env.isIPAD) return;
14 | this._element = element;
15 |
16 | // Initialize instance.
17 | this.init();
18 | };
19 | //window['URipple'] = URipple;
20 |
21 | URipple.prototype._down = function(event) {
22 | if (env.isIE8 || env.isMobile || env.isAndroidPAD || env.isIPAD) return;
23 | if (!this._rippleElement.style.width && !this._rippleElement.style.height) {
24 | var rect = this._element.getBoundingClientRect();
25 | this.rippleSize_ = Math.sqrt(rect.width * rect.width + rect.height * rect.height) * 2 + 2;
26 | if(this.rippleSize_ > 0){
27 | this._rippleElement.style.width = this.rippleSize_ + 'px';
28 | this._rippleElement.style.height = this.rippleSize_ + 'px';
29 | }
30 |
31 | }
32 |
33 | addClass(this._rippleElement, 'is-visible');
34 |
35 | if (event.type === 'mousedown' && this._ignoringMouseDown) {
36 | this._ignoringMouseDown = false;
37 | } else {
38 | if (event.type === 'touchstart') {
39 | this._ignoringMouseDown = true;
40 | }
41 | var frameCount = this.getFrameCount();
42 | if (frameCount > 0) {
43 | return;
44 | }
45 | this.setFrameCount(1);
46 | var t = event.currentTarget || event.target || event.srcElement;
47 | var bound = t.getBoundingClientRect();
48 | var x;
49 | var y;
50 | // Check if we are handling a keyboard click.
51 | if (event.clientX === 0 && event.clientY === 0) {
52 | x = Math.round(bound.width / 2);
53 | y = Math.round(bound.height / 2);
54 | } else {
55 | var clientX = event.clientX ? event.clientX : event.touches[0].clientX;
56 | var clientY = event.clientY ? event.clientY : event.touches[0].clientY;
57 | x = Math.round(clientX - bound.left);
58 | y = Math.round(clientY - bound.top);
59 | }
60 | this.setRippleXY(x, y);
61 | this.setRippleStyles(true);
62 | if(window.requestAnimationFrame)
63 | window.requestAnimationFrame(this.animFrameHandler.bind(this));
64 | }
65 | };
66 |
67 | /**
68 | * Handle mouse / finger up on element.
69 | *
70 | * @param {Event} event The event that fired.
71 | * @private
72 | */
73 | URipple.prototype._up = function(event) {
74 | if (env.isIE8 || env.isMobile || env.isAndroidPAD || env.isIPAD) return;
75 | var self = this;
76 | // Don't fire for the artificial "mouseup" generated by a double-click.
77 | if (event && event.detail !== 2) {
78 | removeClass(this._rippleElement,'is-visible')
79 | }
80 | // Allow a repaint to occur before removing this class, so the animation
81 | // shows for tap events, which seem to trigger a mouseup too soon after
82 | // mousedown.
83 | window.setTimeout(function() {
84 | removeClass(self._rippleElement,'is-visible')
85 | }, 0);
86 | };
87 |
88 | /**
89 | * Getter for frameCount_.
90 | * @return {number} the frame count.
91 | */
92 | URipple.prototype.getFrameCount = function() {
93 | if (env.isIE8 || env.isMobile || env.isAndroidPAD || env.isIPAD) return;
94 | return this.frameCount_;
95 | };
96 | /**
97 | * Setter for frameCount_.
98 | * @param {number} fC the frame count.
99 | */
100 | URipple.prototype.setFrameCount = function(fC) {
101 | if (env.isIE8 || env.isMobile || env.isAndroidPAD || env.isIPAD) return;
102 | this.frameCount_ = fC;
103 | };
104 |
105 |
106 | /**
107 | * Getter for _rippleElement.
108 | * @return {Element} the ripple element.
109 | */
110 | URipple.prototype.getRippleElement = function() {
111 | if (env.isIE8 || env.isMobile || env.isAndroidPAD || env.isIPAD) return;
112 | return this._rippleElement;
113 | };
114 |
115 | /**
116 | * Sets the ripple X and Y coordinates.
117 | * @param {number} newX the new X coordinate
118 | * @param {number} newY the new Y coordinate
119 | */
120 | URipple.prototype.setRippleXY = function(newX, newY) {
121 | if (env.isIE8 || env.isMobile || env.isAndroidPAD || env.isIPAD) return;
122 | this.x_ = newX;
123 | this.y_ = newY;
124 | };
125 |
126 | /**
127 | * Sets the ripple styles.
128 | * @param {boolean} start whether or not this is the start frame.
129 | */
130 | URipple.prototype.setRippleStyles = function(start) {
131 | if (env.isIE8 || env.isMobile || env.isAndroidPAD || env.isIPAD) return;
132 | if (this._rippleElement !== null) {
133 | var transformString;
134 | var scale;
135 | var size;
136 | var offset = 'translate(' + this.x_ + 'px, ' + this.y_ + 'px)';
137 |
138 | if (start) {
139 | scale = 'scale(0.0001, 0.0001)';
140 | size = '1px';
141 | } else {
142 | scale = '';
143 | size = this.rippleSize_ + 'px';
144 | }
145 |
146 | transformString = 'translate(-50%, -50%) ' + offset + scale;
147 |
148 | this._rippleElement.style.webkitTransform = transformString;
149 | this._rippleElement.style.msTransform = transformString;
150 | this._rippleElement.style.transform = transformString;
151 |
152 | if (start) {
153 | removeClass(this._rippleElement,'is-animating')
154 | } else {
155 | addClass(this._rippleElement,'is-animating')
156 | }
157 | }
158 | };
159 |
160 | /**
161 | * Handles an animation frame.
162 | */
163 | URipple.prototype.animFrameHandler = function() {
164 | if (env.isIE8 || env.isMobile || env.isAndroidPAD || env.isIPAD) return;
165 | if (this.frameCount_-- > 0) {
166 | window.requestAnimationFrame(this.animFrameHandler.bind(this));
167 | } else {
168 | this.setRippleStyles(false);
169 | }
170 | };
171 |
172 | /**
173 | * Initialize element.
174 | */
175 | URipple.prototype.init = function() {
176 | if (env.isIE8 || env.isMobile || env.isAndroidPAD || env.isIPAD) return;
177 | var self = this;
178 | if (this._element) {
179 | this._rippleElement = this._element.querySelector('.u-ripple');
180 | if (!this._rippleElement){
181 | this._rippleElement = document.createElement('span');
182 | addClass(this._rippleElement,'u-ripple');
183 | this._element.appendChild(this._rippleElement);
184 | this._element.style.overflow = 'hidden';
185 | this._element.style.position = 'relative';
186 | }
187 | this.frameCount_ = 0;
188 | this.rippleSize_ = 0;
189 | this.x_ = 0;
190 | this.y_ = 0;
191 |
192 | // Touch start produces a compat mouse down event, which would cause a
193 | // second ripples. To avoid that, we use this property to ignore the first
194 | // mouse down after a touch start.
195 | this._ignoringMouseDown = false;
196 | on(this._element, 'mousedown',function(e){self._down(e);})
197 | on(this._element, 'touchstart',function(e){self._down(e);})
198 |
199 | on(this._element, 'mouseup',function(e){self._up(e);})
200 | on(this._element, 'mouseleave',function(e){self._up(e);})
201 | on(this._element, 'touchend',function(e){self._up(e);})
202 | on(this._element, 'blur',function(e){self._up(e);})
203 | }
204 | };
205 |
206 | var Ripple = URipple;
207 |
208 | export {Ripple,URipple};
209 |
--------------------------------------------------------------------------------
/lib/mobileEvents.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : Sparrow touch mobileEvents
3 | * Author : liuyk(liuyk@yonyou.com)
4 | * Date : 2017-03-16 14:41:17
5 | */
6 |
7 | import { env } from './env';
8 |
9 | var u = {};
10 | u.event = {};
11 |
12 | var touchStartEvent = env.hasTouch ? "touchstart" : "mousedown",
13 | touchStopEvent = env.hasTouch ? "touchend" : "mouseup",
14 | touchMoveEvent = env.hasTouch ? "touchmove" : "mousemove";
15 |
16 | // tap和taphold
17 | u.event.tap = {
18 | tapholdThreshold: 750,
19 | emitTapOnTaphold: true,
20 | touchstartFun: function touchstartFun() {
21 | trigger(this, 'vmousedown');
22 | },
23 | touchendFun: function touchendFun() {
24 | trigger(this, 'vmouseup');
25 | trigger(this, 'vclick');
26 | },
27 | setup: function setup() {
28 | var thisObject = this,
29 | isTaphold = false;
30 |
31 | on(thisObject, "vmousedown", function (event) {
32 | isTaphold = false;
33 | if (event.which && event.which !== 1) {
34 | return false;
35 | }
36 |
37 | var origTarget = event.target,
38 | timer;
39 |
40 | function clearTapTimer() {
41 | clearTimeout(timer);
42 | }
43 |
44 | function clearTapHandlers() {
45 | clearTapTimer();
46 |
47 | off(thisObject, 'vclick');
48 | off(thisObject, 'vmouseup');
49 | off(document, 'vmousecancel');
50 | }
51 |
52 | function clickHandler(event) {
53 | clearTapHandlers();
54 |
55 | // ONLY trigger a 'tap' event if the start target is
56 | // the same as the stop target.
57 | if (!isTaphold && origTarget === event.target) {
58 | trigger(thisObject, 'tap');
59 | } else if (isTaphold) {
60 | event.preventDefault();
61 | }
62 | }
63 | on(thisObject, 'vmouseup', clearTapTimer);
64 | on(thisObject, 'vclick', clickHandler);
65 | on(document, 'vmousecancel', clearTapHandlers);
66 |
67 | timer = setTimeout(function () {
68 | if (!u.event.tap.emitTapOnTaphold) {
69 | isTaphold = true;
70 | }
71 | trigger(thisObject, "taphold");
72 | clearTapHandlers();
73 | }, u.event.tap.tapholdThreshold);
74 | });
75 |
76 | on(thisObject, 'touchstart', u.event.tap.touchstartFun);
77 | on(thisObject, 'touchend', u.event.tap.touchendFun);
78 | },
79 | teardown: function teardown() {
80 | off(thisObject, 'vmousedown');
81 | off(thisObject, 'vclick');
82 | off(thisObject, 'vmouseup');
83 | off(document, 'vmousecancel');
84 | }
85 | };
86 |
87 | u.event.taphold = u.event.tap;
88 |
89 | u.event.swipe = {
90 |
91 | // More than this horizontal displacement, and we will suppress scrolling.
92 | scrollSupressionThreshold: 30,
93 |
94 | // More time than this, and it isn't a swipe.
95 | durationThreshold: 1000,
96 |
97 | // Swipe horizontal displacement must be more than this.
98 | horizontalDistanceThreshold: 30,
99 |
100 | // Swipe vertical displacement must be less than this.
101 | verticalDistanceThreshold: 30,
102 |
103 | getLocation: function getLocation(event) {
104 | var winPageX = window.pageXOffset,
105 | winPageY = window.pageYOffset,
106 | x = event.clientX,
107 | y = event.clientY;
108 |
109 | if (event.pageY === 0 && Math.floor(y) > Math.floor(event.pageY) || event.pageX === 0 && Math.floor(x) > Math.floor(event.pageX)) {
110 |
111 | // iOS4 clientX/clientY have the value that should have been
112 | // in pageX/pageY. While pageX/page/ have the value 0
113 | x = x - winPageX;
114 | y = y - winPageY;
115 | } else if (y < event.pageY - winPageY || x < event.pageX - winPageX) {
116 |
117 | // Some Android browsers have totally bogus values for clientX/Y
118 | // when scrolling/zooming a page. Detectable since clientX/clientY
119 | // should never be smaller than pageX/pageY minus page scroll
120 | x = event.pageX - winPageX;
121 | y = event.pageY - winPageY;
122 | }
123 |
124 | return {
125 | x: x,
126 | y: y
127 | };
128 | },
129 |
130 | start: function start(event) {
131 | var data = event.touches ? event.touches[0] : event,
132 | location = u.event.swipe.getLocation(data);
133 | return {
134 | time: new Date().getTime(),
135 | coords: [location.x, location.y],
136 | origin: event.target
137 | };
138 | },
139 |
140 | stop: function stop(event) {
141 | var data = event.touches ? event.touches[0] : event,
142 | location = u.event.swipe.getLocation(data);
143 | return {
144 | time: new Date().getTime(),
145 | coords: [location.x, location.y]
146 | };
147 | },
148 |
149 | handleSwipe: function handleSwipe(start, stop, thisObject, origTarget) {
150 | if (stop.time - start.time < u.event.swipe.durationThreshold && Math.abs(start.coords[0] - stop.coords[0]) > u.event.swipe.horizontalDistanceThreshold && Math.abs(start.coords[1] - stop.coords[1]) < u.event.swipe.verticalDistanceThreshold) {
151 | var direction = start.coords[0] > stop.coords[0] ? "swipeleft" : "swiperight";
152 |
153 | trigger(thisObject, "swipe");
154 | trigger(thisObject, direction);
155 | return true;
156 | }
157 | return false;
158 | },
159 |
160 | // This serves as a flag to ensure that at most one swipe event event is
161 | // in work at any given time
162 | eventInProgress: false,
163 |
164 | setup: function setup() {
165 | var events,
166 | thisObject = this,
167 | context = {};
168 |
169 | // Retrieve the events data for this element and add the swipe context
170 | events = thisObject["mobile-events"];
171 | if (!events) {
172 | events = {
173 | length: 0
174 | };
175 | thisObject["mobile-events"] = events;
176 | }
177 | events.length++;
178 | events.swipe = context;
179 |
180 | context.start = function (event) {
181 |
182 | // Bail if we're already working on a swipe event
183 | if (u.event.swipe.eventInProgress) {
184 | return;
185 | }
186 | u.event.swipe.eventInProgress = true;
187 |
188 | var stop,
189 | start = u.event.swipe.start(event),
190 | origTarget = event.target,
191 | emitted = false;
192 |
193 | context.move = function (event) {
194 | // if ( !start || event.isDefaultPrevented() ) {
195 | if (!start) {
196 | return;
197 | }
198 |
199 | stop = u.event.swipe.stop(event);
200 | if (!emitted) {
201 | emitted = u.event.swipe.handleSwipe(start, stop, thisObject, origTarget);
202 | if (emitted) {
203 |
204 | // Reset the context to make way for the next swipe event
205 | u.event.swipe.eventInProgress = false;
206 | }
207 | }
208 | // prevent scrolling
209 | if (Math.abs(start.coords[0] - stop.coords[0]) > u.event.swipe.scrollSupressionThreshold) {
210 | event.preventDefault();
211 | }
212 | };
213 |
214 | context.stop = function () {
215 | emitted = true;
216 |
217 | // Reset the context to make way for the next swipe event
218 | u.event.swipe.eventInProgress = false;
219 | off(document, touchMoveEvent, context.move);
220 | context.move = null;
221 | };
222 |
223 | on(document, touchMoveEvent, context.move);
224 | on(document, touchStopEvent, context.stop);
225 | };
226 | on(thisObject, touchStartEvent, context.start);
227 | },
228 |
229 | teardown: function teardown() {
230 | var events, context;
231 |
232 | events = thisObject["mobile-events"];
233 | if (events) {
234 | context = events.swipe;
235 | delete events.swipe;
236 | events.length--;
237 | if (events.length === 0) {
238 | thisObject["mobile-events"] = null;
239 | }
240 | }
241 |
242 | if (context) {
243 | if (context.start) {
244 | off(thisObject, touchStartEvent, context.start);
245 | }
246 | if (context.move) {
247 | off(document, touchMoveEvent, context.move);
248 | }
249 | if (context.stop) {
250 | off(document, touchStopEvent, context.stop);
251 | }
252 | }
253 | }
254 | };
255 |
256 | u.event.swipeleft = u.event.swipe;
257 |
258 | u.event.swiperight = u.event.swipe;
259 |
260 | var event = u.event;
261 |
262 | export { event };
--------------------------------------------------------------------------------
/src/mobileEvents.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : Sparrow touch mobileEvents
3 | * Author : liuyk(liuyk@yonyou.com)
4 | * Date : 2017-03-16 14:41:17
5 | */
6 |
7 | import {
8 | env
9 | } from './env';
10 |
11 | var u = {};
12 | u.event = {};
13 |
14 | var touchStartEvent = env.hasTouch ? "touchstart" : "mousedown",
15 | touchStopEvent = env.hasTouch ? "touchend" : "mouseup",
16 | touchMoveEvent = env.hasTouch ? "touchmove" : "mousemove";
17 |
18 | // tap和taphold
19 | u.event.tap = {
20 | tapholdThreshold: 750,
21 | emitTapOnTaphold: true,
22 | touchstartFun: function() {
23 | trigger(this, 'vmousedown');
24 | },
25 | touchendFun: function() {
26 | trigger(this, 'vmouseup');
27 | trigger(this, 'vclick');
28 | },
29 | setup: function() {
30 | var thisObject = this,
31 | isTaphold = false;
32 |
33 | on(thisObject, "vmousedown", function(event) {
34 | isTaphold = false;
35 | if (event.which && event.which !== 1) {
36 | return false;
37 | }
38 |
39 | var origTarget = event.target,
40 | timer;
41 |
42 | function clearTapTimer() {
43 | clearTimeout(timer);
44 | }
45 |
46 | function clearTapHandlers() {
47 | clearTapTimer();
48 |
49 | off(thisObject, 'vclick');
50 | off(thisObject, 'vmouseup');
51 | off(document, 'vmousecancel');
52 | }
53 |
54 | function clickHandler(event) {
55 | clearTapHandlers();
56 |
57 | // ONLY trigger a 'tap' event if the start target is
58 | // the same as the stop target.
59 | if (!isTaphold && origTarget === event.target) {
60 | trigger(thisObject, 'tap');
61 | } else if (isTaphold) {
62 | event.preventDefault();
63 | }
64 | }
65 | on(thisObject, 'vmouseup', clearTapTimer);
66 | on(thisObject, 'vclick', clickHandler);
67 | on(document, 'vmousecancel', clearTapHandlers);
68 |
69 | timer = setTimeout(function() {
70 | if (!u.event.tap.emitTapOnTaphold) {
71 | isTaphold = true;
72 | }
73 | trigger(thisObject, "taphold");
74 | clearTapHandlers();
75 | }, u.event.tap.tapholdThreshold);
76 | });
77 |
78 | on(thisObject, 'touchstart', u.event.tap.touchstartFun);
79 | on(thisObject, 'touchend', u.event.tap.touchendFun);
80 | },
81 | teardown: function() {
82 | off(thisObject, 'vmousedown');
83 | off(thisObject, 'vclick');
84 | off(thisObject, 'vmouseup');
85 | off(document, 'vmousecancel');
86 | }
87 | };
88 |
89 | u.event.taphold = u.event.tap;
90 |
91 | u.event.swipe = {
92 |
93 | // More than this horizontal displacement, and we will suppress scrolling.
94 | scrollSupressionThreshold: 30,
95 |
96 | // More time than this, and it isn't a swipe.
97 | durationThreshold: 1000,
98 |
99 | // Swipe horizontal displacement must be more than this.
100 | horizontalDistanceThreshold: 30,
101 |
102 | // Swipe vertical displacement must be less than this.
103 | verticalDistanceThreshold: 30,
104 |
105 | getLocation: function(event) {
106 | var winPageX = window.pageXOffset,
107 | winPageY = window.pageYOffset,
108 | x = event.clientX,
109 | y = event.clientY;
110 |
111 | if (event.pageY === 0 && Math.floor(y) > Math.floor(event.pageY) ||
112 | event.pageX === 0 && Math.floor(x) > Math.floor(event.pageX)) {
113 |
114 | // iOS4 clientX/clientY have the value that should have been
115 | // in pageX/pageY. While pageX/page/ have the value 0
116 | x = x - winPageX;
117 | y = y - winPageY;
118 | } else if (y < (event.pageY - winPageY) || x < (event.pageX - winPageX)) {
119 |
120 | // Some Android browsers have totally bogus values for clientX/Y
121 | // when scrolling/zooming a page. Detectable since clientX/clientY
122 | // should never be smaller than pageX/pageY minus page scroll
123 | x = event.pageX - winPageX;
124 | y = event.pageY - winPageY;
125 | }
126 |
127 | return {
128 | x: x,
129 | y: y
130 | };
131 | },
132 |
133 | start: function(event) {
134 | var data = event.touches ?
135 | event.touches[0] : event,
136 | location = u.event.swipe.getLocation(data);
137 | return {
138 | time: (new Date()).getTime(),
139 | coords: [location.x, location.y],
140 | origin: event.target
141 | };
142 | },
143 |
144 | stop: function(event) {
145 | var data = event.touches ?
146 | event.touches[0] : event,
147 | location = u.event.swipe.getLocation(data);
148 | return {
149 | time: (new Date()).getTime(),
150 | coords: [location.x, location.y]
151 | };
152 | },
153 |
154 | handleSwipe: function(start, stop, thisObject, origTarget) {
155 | if (stop.time - start.time < u.event.swipe.durationThreshold &&
156 | Math.abs(start.coords[0] - stop.coords[0]) > u.event.swipe.horizontalDistanceThreshold &&
157 | Math.abs(start.coords[1] - stop.coords[1]) < u.event.swipe.verticalDistanceThreshold) {
158 | var direction = start.coords[0] > stop.coords[0] ? "swipeleft" : "swiperight";
159 |
160 | trigger(thisObject, "swipe");
161 | trigger(thisObject, direction);
162 | return true;
163 | }
164 | return false;
165 |
166 | },
167 |
168 | // This serves as a flag to ensure that at most one swipe event event is
169 | // in work at any given time
170 | eventInProgress: false,
171 |
172 | setup: function() {
173 | var events,
174 | thisObject = this,
175 | context = {};
176 |
177 | // Retrieve the events data for this element and add the swipe context
178 | events = thisObject["mobile-events"];
179 | if (!events) {
180 | events = {
181 | length: 0
182 | };
183 | thisObject["mobile-events"] = events;
184 | }
185 | events.length++;
186 | events.swipe = context;
187 |
188 | context.start = function(event) {
189 |
190 | // Bail if we're already working on a swipe event
191 | if (u.event.swipe.eventInProgress) {
192 | return;
193 | }
194 | u.event.swipe.eventInProgress = true;
195 |
196 | var stop,
197 | start = u.event.swipe.start(event),
198 | origTarget = event.target,
199 | emitted = false;
200 |
201 | context.move = function(event) {
202 | // if ( !start || event.isDefaultPrevented() ) {
203 | if (!start) {
204 | return;
205 | }
206 |
207 | stop = u.event.swipe.stop(event);
208 | if (!emitted) {
209 | emitted = u.event.swipe.handleSwipe(start, stop, thisObject, origTarget);
210 | if (emitted) {
211 |
212 | // Reset the context to make way for the next swipe event
213 | u.event.swipe.eventInProgress = false;
214 | }
215 | }
216 | // prevent scrolling
217 | if (Math.abs(start.coords[0] - stop.coords[0]) > u.event.swipe.scrollSupressionThreshold) {
218 | event.preventDefault();
219 | }
220 | };
221 |
222 | context.stop = function() {
223 | emitted = true;
224 |
225 | // Reset the context to make way for the next swipe event
226 | u.event.swipe.eventInProgress = false;
227 | off(document, touchMoveEvent, context.move);
228 | context.move = null;
229 | };
230 |
231 | on(document, touchMoveEvent, context.move);
232 | on(document, touchStopEvent, context.stop);
233 | };
234 | on(thisObject, touchStartEvent, context.start);
235 | },
236 |
237 | teardown: function() {
238 | var events, context;
239 |
240 | events = thisObject["mobile-events"];
241 | if (events) {
242 | context = events.swipe;
243 | delete events.swipe;
244 | events.length--;
245 | if (events.length === 0) {
246 | thisObject["mobile-events"] = null;
247 | }
248 | }
249 |
250 | if (context) {
251 | if (context.start) {
252 | off(thisObject, touchStartEvent, context.start);
253 | }
254 | if (context.move) {
255 | off(document, touchMoveEvent, context.move);
256 | }
257 | if (context.stop) {
258 | off(document, touchStopEvent, context.stop);
259 | }
260 | }
261 | }
262 | };
263 |
264 | u.event.swipeleft = u.event.swipe;
265 |
266 | u.event.swiperight = u.event.swipe;
267 |
268 | var event = u.event;
269 |
270 | export {
271 | event
272 | }
273 |
--------------------------------------------------------------------------------
/lib/dom.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : Sparrow dom
3 | * Author : Kvkens(yueming@yonyou.com)
4 | * Date : 2016-08-16 13:59:17
5 | */
6 | import { on, stopEvent } from './event';
7 | /**
8 | * 元素增加指定样式
9 | * @param value
10 | * @returns {*}
11 | */
12 | var addClass = function addClass(element, value) {
13 | if (element) {
14 | if (typeof element.classList === 'undefined') {
15 | if (u._addClass) {
16 | u._addClass(element, value);
17 | } else {
18 | $(element).addClass(value);
19 | }
20 | } else {
21 | element.classList.add(value);
22 | }
23 | }
24 |
25 | return this;
26 | };
27 | /**
28 | * 删除元素上指定样式
29 | * @param {Object} element
30 | * @param {Object} value
31 | */
32 | var removeClass = function removeClass(element, value) {
33 | if (element) {
34 | if (typeof element.classList === 'undefined') {
35 | if (u._removeClass) {
36 | u._removeClass(element, value);
37 | } else {
38 | $(element).removeClass(value);
39 | }
40 | } else {
41 | element.classList.remove(value);
42 | }
43 | }
44 | return this;
45 | };
46 | /**
47 | * 元素上是否存在该类
48 | * @param {Object} element
49 | * @param {Object} value
50 | */
51 | var hasClass = function hasClass(element, value) {
52 | if (!element) return false;
53 | if (element.nodeName && (element.nodeName === '#text' || element.nodeName === '#comment')) return false;
54 | if (typeof element.classList === 'undefined') {
55 | if (u._hasClass) {
56 | return u._hasClass(element, value);
57 | } else {
58 | return $(element).hasClass(value);
59 | }
60 |
61 | return false;
62 | } else {
63 | return element.classList.contains(value);
64 | }
65 | };
66 | /**
67 | * 选择元素类切换
68 | * @param {Object} element
69 | * @param {Object} value
70 | */
71 | var toggleClass = function toggleClass(element, value) {
72 | if (typeof element.classList === 'undefined') {
73 | return u._toggleClass(element, value);
74 | } else {
75 | return element.classList.toggle(value);
76 | }
77 | };
78 |
79 | /**
80 | * 向上查找指定类元素
81 | * @param {Object} element
82 | * @param {Object} selector
83 | */
84 | var closest = function closest(element, selector) {
85 | var tmp = element;
86 | while (tmp != null && !hasClass(tmp, selector) && tmp != document.body) {
87 | tmp = tmp.parentNode;
88 | }
89 | if (tmp == document.body) return null;
90 | return tmp;
91 | };
92 |
93 | /**
94 | * 元素CSS操作
95 | * @param {Object} element
96 | * @param {Object} csstext
97 | * @param {Object} val
98 | */
99 | var css = function css(element, csstext, val) {
100 | //TO DO : 实现u.相关方法
101 | if (csstext instanceof Object) {
102 | for (var k in csstext) {
103 | var tmpcss = csstext[k];
104 | if (["width", "height", "top", "bottom", "left", "right"].indexOf(k) > -1 && isNumber(tmpcss)) {
105 | tmpcss = tmpcss + "px";
106 | }
107 | element.style[k] = tmpcss;
108 | }
109 | } else {
110 | if (arguments.length > 2) {
111 | element.style[csstext] = val;
112 | } else {
113 | return getStyle(element, csstext);
114 | }
115 | }
116 | };
117 |
118 | var wrap = function wrap(element, parent) {
119 | var p = makeDOM(parent);
120 | element.parentNode.insertBefore(p, element);
121 | p.appendChild(element);
122 | };
123 | var getStyle = function getStyle(element, key) {
124 | //不要在循环里用
125 | var allCSS;
126 | if (window.getComputedStyle) {
127 | allCSS = window.getComputedStyle(element);
128 | } else {
129 | allCSS = element.currentStyle;
130 | }
131 | if (allCSS[key] !== undefined) {
132 | return allCSS[key];
133 | } else {
134 | return "";
135 | }
136 | };
137 | var globalZIndex;
138 | /**
139 | * 统一zindex值, 不同控件每次显示时都取最大的zindex,防止显示错乱
140 | */
141 | var getZIndex = function getZIndex() {
142 | if (!globalZIndex) {
143 | globalZIndex = 2000;
144 | }
145 | return globalZIndex++;
146 | };
147 | var makeDOM = function makeDOM(htmlString) {
148 | var tempDiv = document.createElement("div");
149 | tempDiv.innerHTML = htmlString;
150 | var _dom = tempDiv.children[0];
151 | return _dom;
152 | };
153 | /**
154 | * element
155 | */
156 | var makeModal = function makeModal(element, parEle) {
157 | var overlayDiv = document.createElement('div');
158 | $(overlayDiv).addClass('u-overlay');
159 | overlayDiv.style.zIndex = getZIndex();
160 | // 如果有父元素则插入到父元素上,没有则添加到body上
161 | if (parEle && parEle != document.body) {
162 | addClass(overlayDiv, 'hasPar');
163 | parEle.appendChild(overlayDiv);
164 | } else {
165 | document.body.appendChild(overlayDiv);
166 | }
167 |
168 | element.style.zIndex = getZIndex();
169 | on(overlayDiv, 'click', function (e) {
170 | stopEvent(e);
171 | });
172 | return overlayDiv;
173 | };
174 |
175 | var makModalAssign = function makModalAssign(element, parEle) {
176 | var overlayDiv = document.createElement('div');
177 | $(overlayDiv).addClass('u-overlay-assign');
178 | overlayDiv.style.zIndex = getZIndex();
179 | // 如果有父元素则插入到父元素上,没有则添加到body上
180 | if (parEle && parEle != document.body) {
181 | addClass(overlayDiv, 'hasPar');
182 | parEle.appendChild(overlayDiv);
183 | } else {
184 | document.body.appendChild(overlayDiv);
185 | }
186 | $('.u-overlay-assign').css('display', "none");
187 | $('.u-overlay-assign:eq(0)').css('display', "block");
188 |
189 | element.style.zIndex = getZIndex();
190 | on(overlayDiv, 'click', function (e) {
191 | stopEvent(e);
192 | });
193 | return overlayDiv;
194 | };
195 | var getOffset = function getOffset(Node, offset) {
196 | if (!offset) {
197 | offset = {};
198 | offset.top = 0;
199 | offset.left = 0;
200 | }
201 | if (Node == document.body) {
202 | return offset;
203 | }
204 | offset.top += Node.offsetTop;
205 | offset.left += Node.offsetLeft;
206 | if (Node.offsetParent) return getOffset(Node.offsetParent, offset);else return offset;
207 | };
208 | var getScroll = function getScroll(Node, offset) {
209 | if (!offset) {
210 | offset = {};
211 | offset.top = 0;
212 | offset.left = 0;
213 | }
214 | if (Node == document.body) {
215 | offset.top += Node.scrollTop || document.documentElement.scrollTop;
216 | offset.left += Node.scrollLeft || document.documentElement.scrollLeft;
217 | return offset;
218 | }
219 | if (Node.tagName != 'INPUT') {
220 | offset.top += Node.scrollTop;
221 | offset.left += Node.scrollLeft;
222 | }
223 |
224 | if (Node.parentNode) return getScroll(Node.parentNode, offset);else return offset;
225 | };
226 | var showPanelByEle = function showPanelByEle(obj) {
227 | var ele = obj.ele,
228 | panel = obj.panel,
229 | position = obj.position,
230 |
231 | // off = u.getOffset(ele),scroll = u.getScroll(ele),
232 | // offLeft = off.left,offTop = off.top,
233 | // scrollLeft = scroll.left,scrollTop = scroll.top,
234 | // eleWidth = ele.offsetWidth,eleHeight = ele.offsetHeight,
235 | // panelWidth = panel.offsetWidth,panelHeight = panel.offsetHeight,
236 | bodyWidth = document.body.clientWidth,
237 | bodyHeight = document.body.clientHeight,
238 | position = position || 'top',
239 |
240 | // left = offLeft - scrollLeft,top = offTop - scrollTop,
241 | eleRect = obj.ele.getBoundingClientRect(),
242 | panelRect = obj.panel.getBoundingClientRect(),
243 | eleWidth = eleRect.width || 0,
244 | eleHeight = eleRect.height || 0,
245 | left = eleRect.left || 0,
246 | top = eleRect.top || 0,
247 | panelWidth = panelRect.width || 0,
248 | panelHeight = panelRect.height || 0,
249 | docWidth = document.documentElement.clientWidth,
250 | docHeight = document.documentElement.clientHeight;
251 |
252 | // 基准点为Ele的左上角
253 | // 后续根据需要完善
254 | if (position == 'left') {
255 | left = left - panelWidth;
256 | top = top + (eleHeight - panelHeight) / 2;
257 | } else if (position == 'right') {
258 | left = left + eleWidth;
259 | top = top + (eleHeight - panelHeight) / 2;
260 | } else if (position == 'top' || position == 'topCenter') {
261 | left = left + (eleWidth - panelWidth) / 2;
262 | top = top - panelHeight;
263 | } else if (position == 'bottom' || position == 'bottomCenter') {
264 | left = left + (eleWidth - panelWidth) / 2;
265 | top = top + eleHeight;
266 | } else if (position == 'bottomLeft') {
267 | left = left;
268 | top = top + eleHeight;
269 | }
270 |
271 | if (left + panelWidth > docWidth) left = docWidth - panelWidth - 10;
272 | if (left < 0) left = 0;
273 |
274 | if (top + panelHeight > docHeight) {
275 | top = docHeight - panelHeight - 10;
276 | }
277 |
278 | if (top < 0) top = 0;
279 | panel.style.left = left + 'px';
280 | panel.style.top = top + 'px';
281 | };
282 |
283 | var getElementLeft = function getElementLeft(element) {
284 | var actualLeft = element.offsetLeft;
285 | var current = element.offsetParent;
286 | while (current !== null) {
287 | actualLeft += current.offsetLeft;
288 | current = current.offsetParent;
289 | }
290 | if (document.compatMode == "BackCompat") {
291 | var elementScrollLeft = document.body.scrollLeft;
292 | } else {
293 | var elementScrollLeft = document.documentElement.scrollLeft;
294 | }
295 | return actualLeft - elementScrollLeft;
296 | };
297 | var getElementTop = function getElementTop(element) {
298 | var actualTop = element.offsetTop;
299 | var current = element.offsetParent;
300 | while (current !== null) {
301 | actualTop += current.offsetTop;
302 | current = current.offsetParent;
303 | }
304 | if (document.compatMode == "BackCompat") {
305 | var elementScrollTop = document.body.scrollTop;
306 | } else {
307 | var elementScrollTop = document.documentElement.scrollTop;
308 | }
309 | return actualTop - elementScrollTop;
310 | };
311 | export { addClass, removeClass, hasClass, toggleClass, closest, css, wrap, getStyle, getZIndex, makeDOM, makeModal, makModalAssign, getOffset, getScroll, showPanelByEle, getElementLeft, getElementTop };
--------------------------------------------------------------------------------