├── map.json
├── modules
├── css
│ ├── _global.less
│ ├── _mixin.scss
│ ├── test.less
│ ├── _layout.scss
│ ├── img
│ │ └── index.jpg
│ ├── mixin
│ │ ├── _size.scss
│ │ └── _clearfix.scss
│ ├── common.scss
│ └── index.scss
├── html
│ ├── footer
│ │ ├── footer.scss
│ │ └── footer.html
│ └── header
│ │ ├── header.html
│ │ └── header.scss
├── app
│ ├── test.tmpl
│ ├── test-npm.es
│ └── test.es
├── util
│ └── template
│ │ └── template.es
└── lib
│ ├── template
│ └── template.js
│ └── data.js
│ └── data.js
├── test
├── test.json
├── server.conf
└── dynamic.js
├── .gitignore
├── img
└── test.jpg
├── lib
├── html5-shim.js
├── mod.js
├── es5-sham.js
└── es5-shim.js
├── test.html
├── test-npm.html
├── component.json
├── .github
└── FUNDING.yml
├── pc.html
├── README.md
├── LICENSE
├── wap.html
├── README_NG.md
├── index.html
├── package.json
├── INTRO.md
├── fis-conf.js
└── fis-conf-npm.js
/map.json:
--------------------------------------------------------------------------------
1 | __RESOURCE_MAP__
2 |
--------------------------------------------------------------------------------
/modules/css/_global.less:
--------------------------------------------------------------------------------
1 | @color: red;
2 |
--------------------------------------------------------------------------------
/test/test.json:
--------------------------------------------------------------------------------
1 | {
2 | errno: 0
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | components/*
3 | output
4 |
--------------------------------------------------------------------------------
/modules/html/footer/footer.scss:
--------------------------------------------------------------------------------
1 | footer {
2 | text-align: center;
3 | }
4 |
--------------------------------------------------------------------------------
/img/test.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yanhaijing/fis3-base/HEAD/img/test.jpg
--------------------------------------------------------------------------------
/modules/css/_mixin.scss:
--------------------------------------------------------------------------------
1 | @import "mixin/size";
2 | @import "mixin/clearfix";
3 |
--------------------------------------------------------------------------------
/modules/app/test.tmpl:
--------------------------------------------------------------------------------
1 | <#for (var i = 0; i < 3; i++) {#>
2 | template.js
3 | <#}#>
4 |
--------------------------------------------------------------------------------
/modules/css/test.less:
--------------------------------------------------------------------------------
1 | @import "_global.less";
2 |
3 | p {
4 | color: @color;
5 | }
6 |
--------------------------------------------------------------------------------
/modules/css/_layout.scss:
--------------------------------------------------------------------------------
1 | .container {
2 | margin: auto;
3 | max-width: 1100px;
4 | }
5 |
--------------------------------------------------------------------------------
/modules/css/img/index.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yanhaijing/fis3-base/HEAD/modules/css/img/index.jpg
--------------------------------------------------------------------------------
/modules/css/mixin/_size.scss:
--------------------------------------------------------------------------------
1 | @mixin size($width, $height: $width) {
2 | width: $width;
3 | height: $height;
4 | }
5 |
--------------------------------------------------------------------------------
/test/server.conf:
--------------------------------------------------------------------------------
1 | rewrite ^\/api\/test$ /test/test.json
2 |
3 | rewrite ^\/api\/dynamic\/time$ /test/dynamic.js
4 |
5 |
--------------------------------------------------------------------------------
/modules/css/common.scss:
--------------------------------------------------------------------------------
1 | // @import "compass-mixins/compass";
2 | @import "mixin";
3 |
4 | @import "normalize.css/normalize.css";
5 |
6 | @import "layout";
7 |
--------------------------------------------------------------------------------
/modules/css/mixin/_clearfix.scss:
--------------------------------------------------------------------------------
1 | @mixin clearfix() {
2 | &::after {
3 | content: "";
4 | display: table;
5 | clear: both;
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/modules/html/footer/footer.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/modules/html/header/header.html:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/lib/html5-shim.js:
--------------------------------------------------------------------------------
1 | (function(){
2 | var e="abbr,article,aside,audio,canvas,datalist,details,dialog,eventsource,figure,footer,header,hgroup,mark,menu,meter,nav,output,progress,section,time,video".split(","),
3 | i=e.length;
4 | while(i--){document.createElement(e[i])}
5 | })();
6 |
--------------------------------------------------------------------------------
/modules/html/header/header.scss:
--------------------------------------------------------------------------------
1 | // @import "compass-mixins/compass";
2 | @import "mixin";
3 |
4 | .header {
5 | b {
6 | display: inline-block;
7 | @include size(36px, 36px);
8 | background: url(img/1.jpg);
9 | background-size: 100% 100%;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/modules/app/test-npm.es:
--------------------------------------------------------------------------------
1 | // 测试template
2 | var template = require('template_js');
3 | console.log(template);
4 |
5 | window.template = template;
6 | var tpl = __inline('test.tmpl');
7 | document.body.innerHTML = tpl({});
8 |
9 | var EventEmitter = require('@jsmini/event').EventEmitter;
10 | console.log(EventEmitter);
11 |
--------------------------------------------------------------------------------
/modules/util/template/template.es:
--------------------------------------------------------------------------------
1 | /**
2 | * template 引擎
3 | * @author yanhaijing
4 | * @date 2015年8月1日
5 | */
6 |
7 | import template from 'lib/template/template.js';
8 |
9 | template.config({
10 | sTag: '<#',
11 | eTag: '#>'
12 | });
13 |
14 | // 暴漏到windows,供预编译使用
15 | window.template = template;
16 |
17 | export {template};
18 |
--------------------------------------------------------------------------------
/test/dynamic.js:
--------------------------------------------------------------------------------
1 | module.exports = function(req, res, next) {
2 | if (req['query']['yan'] == 123) {
3 | res.sendFile(__dirname + '/test.json', function(err) {
4 | if (err) {
5 | next(err);
6 | // res.status(err.status).end();
7 | }
8 | // res.end();
9 | });
10 | } else {
11 | res.write('empty');
12 | res.end();
13 | }
14 | };
15 |
--------------------------------------------------------------------------------
/modules/app/test.es:
--------------------------------------------------------------------------------
1 | // 测试jq
2 | var $ = require('jquery');
3 | console.log($)
4 |
5 | // 测试Promise
6 | var Promise = require('es6-promise').Promise;
7 | console.log(Promise);
8 |
9 | // 测试template
10 | require('util/template/template').template;
11 | var tpl = __inline('test.tmpl');
12 | $('body').append(tpl({}));
13 |
14 | // 测试 underscore
15 | var _ = require('underscore');
16 | console.log(_)
17 |
18 | // 测试data.js
19 | var Data = require('lib/data.js/data.js');
20 | console.log(Data);
21 |
--------------------------------------------------------------------------------
/test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 测试页面_fis3 base
6 |
7 |
8 |
9 |
10 |
11 |
测试页面
12 |
13 |
14 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/test-npm.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 测试页面_fis3 base
6 |
7 |
8 |
9 |
10 |
11 |
测试页面
12 |
13 |
14 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/component.json:
--------------------------------------------------------------------------------
1 | {
2 | "protocol": "github",
3 | "gihub": {
4 | "author": "fis-components"
5 | },
6 | "dependencies": [
7 | "jquery@~1.9.1",
8 | "jquery-ui@~1.11.2",
9 | "jquery-validation@~1.13.1",
10 | "jquery-placeholder@~2.0.8",
11 | "underscore@~1.8.3",
12 | "es6-promise@~2.0.1",
13 | "fetch@~0.7.0",
14 | "bootstrap@~3.3.5",
15 | "compass-mixins@~0.12.7",
16 | "zepto@~1.1.6",
17 | "animate.css@~3.1.0",
18 | "normalize.css@~3.0.3",
19 | "react@~15.1.0",
20 | "react-dom@~15.1.0"
21 | ]
22 | }
23 |
--------------------------------------------------------------------------------
/modules/css/index.scss:
--------------------------------------------------------------------------------
1 | // @import "compass-mixins/compass";
2 | @import "mixin";
3 |
4 | // 测试 autoprefixer
5 | @keyframes anim {
6 | 0% {
7 | transform: translate(0px, 0px);
8 | }
9 | 100% {
10 | transform: translate(10px, 10px);
11 | }
12 | }
13 | .autoprefixer {
14 | display: flex;
15 | border-radius: 10px;
16 | width: calc(100% - 50px);
17 | box-shadow: 1px 1px 1px #aaa;
18 | text-shadow:1px 1px #aaa;
19 | opacity: 1;
20 | columns:200px 3;
21 | transform: translate(10px, 10px);
22 | transition: all 1s;
23 | animation: anim 1s;
24 | }
25 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: ['https://yanhaijing.com/mywallet/']# Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
--------------------------------------------------------------------------------
/pc.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | pc_fis3 base
12 |
13 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # [fis3 base](https://github.com/yanhaijing/fis3-base) [](https://github.com/yanhaijing/fis3-base) [](https://github.com/yanhaijing/fis3-base/blob/master/LICENSE)
2 | 基于fis3的纯前端解决方案,拿来即用的fis3脚手架。
3 |
4 | [English README](https://github.com/yanhaijing/fis3-base/blob/master/README_NG.md)
5 |
6 | ## 特色
7 | fis3 base有如下功能特色。
8 | - commonjs
9 | - ECMASCript2015
10 | - [SASS](http://sass-lang.com/) & [Compass](http://compass-style.org/)
11 | - [less](http://www.lesscss.net/)
12 | - [autoprefixer](https://github.com/postcss/autoprefixer)
13 | - [fis components](https://github.com/fis-components) or [npm](https://www.npmjs.com/package/fis3-hook-npm)
14 | - [data.js](https://github.com/yanhaijing/data.js)
15 | - [template.js](https://github.com/yanhaijing/template.js)
16 | - 集成[jsmini](https://github.com/jsmini)
17 | - html,js,css组件
18 | - 本地模拟数据
19 | - 开发,测试,发布等多种模式
20 |
21 | ## 说明文档
22 | [INTRO](INTRO.md)
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (C) 2015-2018 yanhaijing
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/wap.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | wap_fis3 base
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/README_NG.md:
--------------------------------------------------------------------------------
1 | # [fis3 base](https://github.com/yanhaijing/fis3-base) [](https://github.com/yanhaijing/fis3-base) [](https://github.com/yanhaijing/fis3-base/blob/master/MIT-LICENSE)
2 | A pure front end solution based on fis3 for use as a fis3 scaffolding tool.
3 |
4 | [Chinese README 中文版本](https://github.com/yanhaijing/fis3-base/blob/master/README.md)
5 |
6 | ## Features
7 | fis3 base has the following features:
8 | - commonjs
9 | - ECMASCript2015
10 | - [SASS](http://sass-lang.com/) & [Compass](http://compass-style.org/)
11 | - [less](http://www.lesscss.net/)
12 | - [autoprefixer](https://github.com/postcss/autoprefixer)
13 | - [fis components](https://github.com/fis-components) or [npm](https://www.npmjs.com/package/fis3-hook-npm)
14 | - [data.js](https://github.com/yanhaijing/data.js)
15 | - [template.js](https://github.com/yanhaijing/template.js)
16 | - Integration of [jsmini](https://github.com/jsmini)
17 | - html,js,css components
18 | - Local analog data
19 | - Developing, testing, publishing, and other modes
20 |
21 | ## Instructions
22 | [INTRO](INTRO.md)
23 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | fis3 base
10 |
11 |
12 |
13 |
14 |
15 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fis3-base",
3 | "version": "0.1.0",
4 | "description": "基于fis3的纯前端解决方案,拿来即用的fis3脚手架。",
5 | "main": "fis-conf.js",
6 | "directories": {
7 | "test": "test"
8 | },
9 | "scripts": {
10 | "test": "echo \"Error: no test specified\" && exit 1"
11 | },
12 | "repository": {
13 | "type": "git",
14 | "url": "https://github.com/yanhaijing/fis3-base.git"
15 | },
16 | "author": {
17 | "name": "yanhaijing",
18 | "email": "yanhaijing@yeah.net",
19 | "url": "http://yanhaijing.com"
20 | },
21 | "license": [
22 | {
23 | "type": "MIT",
24 | "url": "https://github.com/yanhaijing/fis3-base/blob/master/MIT-LICENSE.txt"
25 | }
26 | ],
27 | "bugs": {
28 | "url": "https://github.com/yanhaijing/fis3-base/issues"
29 | },
30 | "homepage": "https://github.com/yanhaijing/fis3-base",
31 | "dependencies": {
32 | "@jsmini/clone": "0.3.0",
33 | "@jsmini/console": "0.6.0",
34 | "@jsmini/event": "0.5.1",
35 | "@jsmini/extend": "0.2.0",
36 | "@jsmini/guid": "0.6.0",
37 | "@jsmini/inherits": "0.5.0",
38 | "@jsmini/is": "0.4.0",
39 | "@jsmini/load": "0.1.0",
40 | "@jsmini/pubsub": "0.1.0",
41 | "@jsmini/querystring": "0.1.0",
42 | "@jsmini/type": "0.4.0",
43 | "@jsmini/url": "0.1.0",
44 | "data_js": "0.3.0",
45 | "template_js": "0.6.1"
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/INTRO.md:
--------------------------------------------------------------------------------
1 | # 文档
2 | 这里说明文档。依赖fis3,如果你不了解fis3,请移步[fis3官网](http://fis.baidu.com/)。
3 |
4 | ## 推荐环境
5 | 作者长期使用和测试的平台如下,对于没测试过的平台,可能会遇到一些问题,欢迎反馈哈
6 |
7 | - window7 node0.12.x
8 | - mac10.13 node8.9.x
9 |
10 | ## 依赖
11 | fis依赖node,了解node请看这里[nodejs.org](http://nodejs.org/)。
12 |
13 | **注意:windows平台,推荐node版本 0.12.x。**
14 |
15 | 第一步,用下面的命令安装fis3(安装失败,可以试试[淘宝镜像](http://yanhaijing.com/tool/2015/09/01/my-npm-note/))
16 |
17 | ``` bash
18 | npm install -g fis3
19 | ```
20 |
21 | 第二步,安装fis插件
22 |
23 | ``` bash
24 | # hook类
25 | npm install -g fis3-hook-commonjs
26 |
27 | # parser类
28 | ## 下面两个sass插件二选一,还需要更改fisconf里对应的插件
29 | npm install -g fis-parser-sass # node版本需 <= 0.12
30 | npm install -g fis-parser-node-sass # node >= 4
31 |
32 | npm install -g fis-parser-less
33 | npm install -g fis-parser-template
34 | npm install -g fis-parser-babel-5.x
35 |
36 | # preprocessor类
37 | npm install -g fis3-preprocessor-js-require-file
38 | npm install -g fis3-preprocessor-js-require-css
39 |
40 | # postprocessor类
41 | npm install -g fis-postprocessor-autoprefixer
42 |
43 | # postpackager类
44 | npm install -g fis3-postpackager-loader
45 |
46 | # optimizer类
47 | # npm install -g fis3-optimizer-html-compress # 此插件已废弃,可跳过
48 |
49 | # deploy类
50 | npm install -g fis3-deploy-skip-packed
51 | ```
52 |
53 | 下面给出把上面插件一起安装的命令
54 |
55 | ``` bash
56 | npm install -g fis3-hook-commonjs fis-parser-node-sass fis-parser-less fis-parser-template fis-parser-babel-5.x fis3-preprocessor-js-require-file fis3-preprocessor-js-require-css fis-postprocessor-autoprefixer fis3-postpackager-loader fis3-optimizer-html-compress fis3-deploy-skip-packed
57 | ```
58 |
59 | 更多插件可以看[fis3插件开发](http://fis.baidu.com/fis3/docs/api/dev-plugin.html)和[fis3常用插件列表](http://fis.baidu.com/fis3/docs/common-plugin.html)。
60 |
61 | 第三步,需要安装组件,此处需要区分使用npm,还是components
62 |
63 | 如果你是用的是npm(也就是使用fis-conf-npm.js),接下来需要安装npm依赖
64 |
65 | ``` bash
66 | npm install
67 | ```
68 |
69 | 如果你使用fis-components(也就是使用fis-conf.js),接下来需要安装fis组件
70 |
71 | ``` bash
72 | fis3 install
73 | ```
74 |
75 | 更多信息请看[fis用户文档](http://fis.baidu.com/fis3/docs/beginning/install.html)。
76 |
77 | 如果
78 |
79 | ## 如何运行
80 | 开启fis服务器
81 |
82 | ``` bash
83 | fis3 server start
84 | ```
85 |
86 | 发布
87 |
88 | ``` bash
89 | fis3 release
90 |
91 | fis3 release prod-debug # 本地查看发布产品库状态
92 | fis3 release prod # 发布产品库
93 |
94 | fis3 release rd # 发布到指定机器
95 | fis3 release rd-debug # 发布到指定机器调试
96 | ```
97 |
98 | 如果是想使用npm可以再release后面指定fis-conf文件
99 |
100 | ``` bash
101 | fis3 release -f fis-conf-npm.js
102 | ```
103 |
104 | 更多命令请[查看这里](http://fis.baidu.com/fis3/docs/api/command.html)。
105 |
106 | ## 目录说明
107 | 项目的目录树如下:
108 |
109 | ```
110 | ┌─components
111 | ├─img
112 | ├─lib
113 | ├─modules
114 | │ ├─app
115 | │ ├─css
116 | │ ├─lib
117 | │ ├─ui
118 | │ └─util
119 | └─test
120 | ```
121 | 根目录下存放html文件。
122 |
123 | - components fis 组件的目录
124 | - img html中用到的图片
125 | - lib 存放一些不打包的js库
126 | - modules 项目的组件
127 | - app 项目用到的js
128 | - css 项目用到的css
129 | - lib 第三方js
130 | - ui UI 组件
131 | - util 工具组件
132 | - test 模拟测试数据
133 |
134 | ## fis components
135 | fis提供了大量组件,社区比较活跃的库一般都有组件存在,你可以在下面的链接查找对应组件。
136 | https://github.com/fis-components
137 |
138 | **注意:为了稳定性,建议把components也加入版本控制库。**
139 |
140 | ## 问题反馈
141 | 使用过程中的常见问题请见这里 [issue](https://github.com/yanhaijing/fis3-base/issues)。
142 |
--------------------------------------------------------------------------------
/fis-conf.js:
--------------------------------------------------------------------------------
1 | // 设置项目属性
2 | fis.set('project.name', 'fis3-base');
3 | fis.set('project.static', '/static');
4 | fis.set('project.files', ['*.html', 'map.json', '/test/*']);
5 |
6 | // 引入模块化开发插件,设置规范为 commonJs 规范。
7 |
8 | fis.hook('commonjs', {
9 | baseUrl: './modules',
10 | extList: ['.js', '.es']
11 | });
12 |
13 | /*************************目录规范*****************************/
14 |
15 | // 开启同名依赖
16 | fis.match('/modules/**', {
17 | useSameNameRequire: true
18 | });
19 |
20 |
21 | // ------ 全局配置
22 | // 允许你在 js 中直接 require css+文件
23 | fis.match('*.{js,es}', {
24 | preprocessor: [
25 | fis.plugin('js-require-file'),
26 | fis.plugin('js-require-css', {
27 | mode: 'dependency'
28 | })
29 | ]
30 | });
31 |
32 | // 配置图片压缩
33 | fis.match('**.png', {
34 | optimizer: fis.plugin('png-compressor', {
35 | type: 'pngquant'
36 | })
37 | });
38 |
39 |
40 | // ------ 配置lib
41 | fis.match('/lib/**.js', {
42 | release: '${project.static}/$&'
43 | });
44 |
45 |
46 | // ------ 配置components
47 | fis.match('/components/**', {
48 | release: '${project.static}/$&'
49 | });
50 | fis.match('/components/**.css', {
51 | isMod: true,
52 | release: '${project.static}/$&'
53 | });
54 | fis.match('/components/**.js', {
55 | isMod: true,
56 | release: '${project.static}/$&'
57 | });
58 |
59 |
60 | // ------ 配置modules
61 | fis.match('/modules/(**)', {
62 | release: '${project.static}/$1'
63 | })
64 |
65 | // 配置css
66 | fis.match(/^\/modules\/(.*\.scss)$/i, {
67 | parser: fis.plugin('node-sass', {
68 | include_paths: ['modules/css', 'components'] // 加入文件查找目录
69 | })
70 | });
71 | fis.match(/^\/modules\/(.*\.less)$/i, {
72 | parser: fis.plugin('less', {
73 | paths: []
74 | })
75 | });
76 | fis.match(/^\/modules\/(.*\.(scss|less|css))$/i, {
77 | rExt: '.css',
78 | isMod: true,
79 | release: '${project.static}/$1',
80 | postprocessor: fis.plugin('autoprefixer', {
81 | browsers: ['IE >= 8', 'Chrome >= 30', 'last 2 versions'] // pc
82 | // browsers: ['Android >= 4', 'ChromeAndroid > 1%', 'iOS >= 6'] // wap
83 | })
84 | });
85 | fis.match(/^\/modules\/(.*\.(?:png|jpg|gif))$/i, {
86 | release: '${project.static}/$1'
87 | });
88 |
89 | // 配置js
90 | fis.match(/^\/modules\/(.*\.es)$/i, {
91 | parser: fis.plugin('babel-5.x'),
92 | rExt: 'js',
93 | isMod: true,
94 | release: '${project.static}/$1'
95 | });
96 | fis.match(/^\/modules\/(.*\.js)$/i, {
97 | isMod: true,
98 | release: '${project.static}/$1'
99 | });
100 |
101 |
102 | // ------ 配置前端模版 使用template.js
103 | fis.match('**.tmpl', {
104 | parser: fis.plugin('template', {
105 | sTag: '<#',
106 | eTag: '#>',
107 | global: 'template'
108 | }),
109 | isJsLike: true,
110 | release: false
111 | });
112 |
113 |
114 | // ------ 配置模拟数据
115 | fis.match('/test/**', {
116 | release: '$0'
117 | });
118 | fis.match('/test/server.conf', {
119 | release: '/config/server.conf'
120 | });
121 |
122 |
123 | /*************************打包规范*****************************/
124 |
125 | // 因为是纯前端项目,依赖不能自断被加载进来,所以这里需要借助一个 loader 来完成,
126 | // 注意:与后端结合的项目不需要此插件!!!
127 | fis.match('::package', {
128 | // npm install [-g] fis3-postpackager-loader
129 | // 分析 __RESOURCE_MAP__ 结构,来解决资源加载问题
130 | postpackager: fis.plugin('loader', {
131 | resourceType: 'commonJs',
132 | useInlineMap: true // 资源映射表内嵌
133 | })
134 | });
135 |
136 | // debug后缀 不会压缩
137 | var map = {
138 | 'rd': {
139 | host: '',
140 | path: ''
141 | },
142 | 'rd-debug': {
143 | host: '',
144 | path: ''
145 | },
146 | 'prod': {
147 | host: 'http://yanhaijing.com',
148 | path: '/${project.name}'
149 | },
150 | 'prod-debug': {
151 | host: '',
152 | path: ''
153 | }
154 | };
155 |
156 | // 通用 1.替换url前缀 2.添加mr5码 3.打包 4.合图 5.重新定义资源路径
157 | Object.keys(map).forEach(function(v) {
158 | var o = map[v];
159 | var domain = o.host + o.path;
160 |
161 | fis.media(v)
162 | .match('**.{es,js}', {
163 | useHash: true,
164 | domain: domain
165 | })
166 | .match('**.{scss,less,css}', {
167 | useSprite: true,
168 | useHash: true,
169 | domain: domain
170 | })
171 | .match('::image', {
172 | useHash: true,
173 | domain: domain
174 | })
175 | .match('**/(*_{x,y,z}.png)', {
176 | release: '/pkg/$1'
177 | })
178 | // 启用打包插件,必须匹配 ::package
179 | .match('::package', {
180 | spriter: fis.plugin('csssprites', {
181 | layout: 'matrix',
182 | // scale: 0.5, // 移动端二倍图用
183 | margin: '10'
184 | }),
185 | postpackager: fis.plugin('loader', {
186 | allInOne: true,
187 | })
188 | })
189 | .match('/lib/es5-{shim,sham}.js', {
190 | packTo: '/pkg/es5-shim.js'
191 | })
192 | .match('/components/**.css', {
193 | packTo: '/pkg/components.css'
194 | })
195 | .match('/components/**.js', {
196 | packTo: '/pkg/components.js'
197 | })
198 | .match('/modules/**.{scss,less,css}', {
199 | packTo: '/pkg/modules.css'
200 | })
201 | .match('/modules/css/**.{scss,less,css}', {
202 | packTo: ''
203 | })
204 | .match('/modules/css/common.scss', {
205 | packTo: '/pkg/common.css'
206 | })
207 | .match('/modules/**.{es,js}', {
208 | packTo: '/pkg/modules.js'
209 | })
210 | .match('/modules/app/**.{es,js}', {
211 | packTo: '/pkg/aio.js'
212 | })
213 | // 为了上线方便,将静态文件发布到同一个目录
214 | // .match('**/(*.{css,less,scss,es,js,jpg,png,gif})', {
215 | // release: '/prod/$1'
216 | // })
217 | });
218 |
219 |
220 | // 压缩css js html
221 | Object.keys(map)
222 | .filter(function(v) {
223 | return v.indexOf('debug') < 0
224 | })
225 | .forEach(function(v) {
226 | fis.media(v)
227 | // .match('**.html', {
228 | // optimizer: fis.plugin('html-compress')
229 | // })
230 | .match('**.{es,js}', {
231 | optimizer: fis.plugin('uglify-js')
232 | })
233 | .match('**.{scss,less,css}', {
234 | optimizer: fis.plugin('clean-css', {
235 | 'keepBreaks': true //保持一个规则一个换行
236 | })
237 | });
238 | });
239 |
240 | // 本地产出发布
241 | fis.media('prod')
242 | .match('**', {
243 | deploy: [
244 | fis.plugin('skip-packed', {
245 | // 默认被打包了 js 和 css 以及被 css sprite 合并了的图片都会在这过滤掉,
246 | // 但是如果这些文件满足下面的规则,则依然不过滤
247 | ignore: []
248 | }),
249 |
250 | fis.plugin('local-deliver', {
251 | to: 'output'
252 | })
253 | ]
254 | });
255 |
256 |
257 | // 发布到指定的机器
258 | ['rd', 'rd-debug'].forEach(function(v) {
259 | fis.media(v)
260 | .match('*', {
261 | deploy: [
262 | fis.plugin('skip-packed', {
263 | // 默认被打包了 js 和 css 以及被 css sprite 合并了的图片都会在这过滤掉,
264 | // 但是如果这些文件满足下面的规则,则依然不过滤
265 | ignore: []
266 | }),
267 | fis.plugin('http-push', {
268 | receiver: 'xxx/fisreceiver.php',
269 | to: 'xxx/' + fis.get('project.name')
270 | })
271 | ]
272 | });
273 | });
274 |
--------------------------------------------------------------------------------
/fis-conf-npm.js:
--------------------------------------------------------------------------------
1 | // 设置项目属性
2 | fis.set('project.name', 'fis3-base');
3 | fis.set('project.static', '/static');
4 | fis.set('project.files', ['*.html', 'map.json', '/test/*']);
5 |
6 | // 引入模块化开发插件,设置规范为 commonJs 规范。
7 |
8 | fis.hook('commonjs', {
9 | baseUrl: './modules',
10 | extList: ['.js', '.es']
11 | });
12 |
13 | // 配置node_modules
14 | fis.unhook('components')
15 | fis.hook('node_modules')
16 |
17 | fis.match('/node_modules/**.js', {
18 | isMod: true,
19 | useSameNameRequire: true
20 | });
21 |
22 | /*************************目录规范*****************************/
23 |
24 | // 开启同名依赖
25 | fis.match('/modules/**', {
26 | useSameNameRequire: true
27 | });
28 |
29 |
30 | // ------ 全局配置
31 | // 允许你在 js 中直接 require css+文件
32 | fis.match('*.{js,es}', {
33 | preprocessor: [
34 | fis.plugin('js-require-file'),
35 | fis.plugin('js-require-css', {
36 | mode: 'dependency'
37 | })
38 | ]
39 | });
40 |
41 | // 配置图片压缩
42 | fis.match('**.png', {
43 | optimizer: fis.plugin('png-compressor', {
44 | type: 'pngquant'
45 | })
46 | });
47 |
48 |
49 | // ------ 配置lib
50 | fis.match('/lib/**.js', {
51 | release: '${project.static}/$&'
52 | });
53 |
54 |
55 | // ------ 配置components
56 | fis.match('/components/**', {
57 | release: '${project.static}/$&'
58 | });
59 | fis.match('/components/**.css', {
60 | isMod: true,
61 | release: '${project.static}/$&'
62 | });
63 | fis.match('/components/**.js', {
64 | isMod: true,
65 | release: '${project.static}/$&'
66 | });
67 |
68 |
69 | // ------ 配置modules
70 | fis.match('/modules/(**)', {
71 | release: '${project.static}/$1'
72 | })
73 |
74 | // 配置css
75 | fis.match(/^\/modules\/(.*\.scss)$/i, {
76 | parser: fis.plugin('node-sass', {
77 | include_paths: ['modules/css', 'components'] // 加入文件查找目录
78 | })
79 | });
80 | fis.match(/^\/modules\/(.*\.less)$/i, {
81 | parser: fis.plugin('less', {
82 | paths: []
83 | })
84 | });
85 | fis.match(/^\/modules\/(.*\.(scss|less|css))$/i, {
86 | rExt: '.css',
87 | isMod: true,
88 | release: '${project.static}/$1',
89 | postprocessor: fis.plugin('autoprefixer', {
90 | browsers: ['IE >= 8', 'Chrome >= 30', 'last 2 versions'] // pc
91 | // browsers: ['Android >= 4', 'ChromeAndroid > 1%', 'iOS >= 6'] // wap
92 | })
93 | });
94 | fis.match(/^\/modules\/(.*\.(?:png|jpg|gif))$/i, {
95 | release: '${project.static}/$1'
96 | });
97 |
98 | // 配置js
99 | fis.match(/^\/modules\/(.*\.es)$/i, {
100 | parser: fis.plugin('babel-5.x'),
101 | rExt: 'js',
102 | isMod: true,
103 | release: '${project.static}/$1'
104 | });
105 | fis.match(/^\/modules\/(.*\.js)$/i, {
106 | isMod: true,
107 | release: '${project.static}/$1'
108 | });
109 |
110 |
111 | // ------ 配置前端模版 使用template.js
112 | fis.match('**.tmpl', {
113 | parser: fis.plugin('template', {
114 | sTag: '<#',
115 | eTag: '#>',
116 | global: 'template'
117 | }),
118 | isJsLike: true,
119 | release: false
120 | });
121 |
122 |
123 | // ------ 配置模拟数据
124 | fis.match('/test/**', {
125 | release: '$0'
126 | });
127 | fis.match('/test/server.conf', {
128 | release: '/config/server.conf'
129 | });
130 |
131 |
132 | /*************************打包规范*****************************/
133 |
134 | // 因为是纯前端项目,依赖不能自断被加载进来,所以这里需要借助一个 loader 来完成,
135 | // 注意:与后端结合的项目不需要此插件!!!
136 | fis.match('::package', {
137 | // npm install [-g] fis3-postpackager-loader
138 | // 分析 __RESOURCE_MAP__ 结构,来解决资源加载问题
139 | postpackager: fis.plugin('loader', {
140 | resourceType: 'commonJs',
141 | useInlineMap: true // 资源映射表内嵌
142 | })
143 | });
144 |
145 | // debug后缀 不会压缩
146 | var map = {
147 | 'rd': {
148 | host: '',
149 | path: ''
150 | },
151 | 'rd-debug': {
152 | host: '',
153 | path: ''
154 | },
155 | 'prod': {
156 | host: 'http://yanhaijing.com',
157 | path: '/${project.name}'
158 | },
159 | 'prod-debug': {
160 | host: '',
161 | path: ''
162 | }
163 | };
164 |
165 | // 通用 1.替换url前缀 2.添加mr5码 3.打包 4.合图 5.重新定义资源路径
166 | Object.keys(map).forEach(function(v) {
167 | var o = map[v];
168 | var domain = o.host + o.path;
169 |
170 | fis.media(v)
171 | .match('**.{es,js}', {
172 | useHash: true,
173 | domain: domain
174 | })
175 | .match('**.{scss,less,css}', {
176 | useSprite: true,
177 | useHash: true,
178 | domain: domain
179 | })
180 | .match('::image', {
181 | useHash: true,
182 | domain: domain
183 | })
184 | .match('**/(*_{x,y,z}.png)', {
185 | release: '/pkg/$1'
186 | })
187 | // 启用打包插件,必须匹配 ::package
188 | .match('::package', {
189 | spriter: fis.plugin('csssprites', {
190 | layout: 'matrix',
191 | // scale: 0.5, // 移动端二倍图用
192 | margin: '10'
193 | }),
194 | postpackager: fis.plugin('loader', {
195 | allInOne: true,
196 | })
197 | })
198 | .match('/lib/es5-{shim,sham}.js', {
199 | packTo: '/pkg/es5-shim.js'
200 | })
201 | .match('/components/**.css', {
202 | packTo: '/pkg/components.css'
203 | })
204 | .match('/components/**.js', {
205 | packTo: '/pkg/components.js'
206 | })
207 | .match('/modules/**.{scss,less,css}', {
208 | packTo: '/pkg/modules.css'
209 | })
210 | .match('/modules/css/**.{scss,less,css}', {
211 | packTo: ''
212 | })
213 | .match('/modules/css/common.scss', {
214 | packTo: '/pkg/common.css'
215 | })
216 | .match('/modules/**.{es,js}', {
217 | packTo: '/pkg/modules.js'
218 | })
219 | .match('/modules/app/**.{es,js}', {
220 | packTo: '/pkg/aio.js'
221 | })
222 | // 为了上线方便,将静态文件发布到同一个目录
223 | // .match('**/(*.{css,less,scss,es,js,jpg,png,gif})', {
224 | // release: '/prod/$1'
225 | // })
226 | });
227 |
228 |
229 | // 压缩css js html
230 | Object.keys(map)
231 | .filter(function(v) {
232 | return v.indexOf('debug') < 0
233 | })
234 | .forEach(function(v) {
235 | fis.media(v)
236 | // .match('**.html', {
237 | // optimizer: fis.plugin('html-compress')
238 | // })
239 | .match('**.{es,js}', {
240 | optimizer: fis.plugin('uglify-js')
241 | })
242 | .match('**.{scss,less,css}', {
243 | optimizer: fis.plugin('clean-css', {
244 | 'keepBreaks': true //保持一个规则一个换行
245 | })
246 | });
247 | });
248 |
249 | // 本地产出发布
250 | fis.media('prod')
251 | .match('**', {
252 | deploy: [
253 | fis.plugin('skip-packed', {
254 | // 默认被打包了 js 和 css 以及被 css sprite 合并了的图片都会在这过滤掉,
255 | // 但是如果这些文件满足下面的规则,则依然不过滤
256 | ignore: []
257 | }),
258 |
259 | fis.plugin('local-deliver', {
260 | to: 'output'
261 | })
262 | ]
263 | });
264 |
265 |
266 | // 发布到指定的机器
267 | ['rd', 'rd-debug'].forEach(function(v) {
268 | fis.media(v)
269 | .match('*', {
270 | deploy: [
271 | fis.plugin('skip-packed', {
272 | // 默认被打包了 js 和 css 以及被 css sprite 合并了的图片都会在这过滤掉,
273 | // 但是如果这些文件满足下面的规则,则依然不过滤
274 | ignore: []
275 | }),
276 | fis.plugin('http-push', {
277 | receiver: 'xxx/fisreceiver.php',
278 | to: 'xxx/' + fis.get('project.name')
279 | })
280 | ]
281 | });
282 | });
283 |
--------------------------------------------------------------------------------
/lib/mod.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @file: mod.js
3 | * @author fis
4 | * ver: 1.0.13
5 | * update: 2016/01/27
6 | * https://github.com/fex-team/mod
7 | */
8 | var require;
9 |
10 | /* eslint-disable no-unused-vars */
11 | var define;
12 |
13 | (function (global) {
14 |
15 | // 避免重复加载而导致已定义模块丢失
16 | if (require) {
17 | return;
18 | }
19 |
20 | var head = document.getElementsByTagName('head')[0];
21 | var loadingMap = {};
22 | var factoryMap = {};
23 | var modulesMap = {};
24 | var scriptsMap = {};
25 | var resMap = {};
26 | var pkgMap = {};
27 |
28 | var createScripts = function (queues, onerror) {
29 |
30 | var docFrag = document.createDocumentFragment();
31 |
32 | for (var i = 0, len = queues.length; i < len; i++) {
33 | var id = queues[i].id;
34 | var url = queues[i].url;
35 |
36 | if (url in scriptsMap) {
37 | continue;
38 | }
39 |
40 | scriptsMap[url] = true;
41 |
42 | var script = document.createElement('script');
43 | if (onerror) {
44 | (function (script, id) {
45 | var tid = setTimeout(function () {
46 | onerror(id);
47 | }, require.timeout);
48 |
49 | script.onerror = function () {
50 | clearTimeout(tid);
51 | onerror(id);
52 | };
53 |
54 | var onload = function () {
55 | clearTimeout(tid);
56 | };
57 |
58 | if ('onload' in script) {
59 | script.onload = onload;
60 | }
61 | else {
62 | script.onreadystatechange = function () {
63 | if (this.readyState === 'loaded' || this.readyState === 'complete') {
64 | onload();
65 | }
66 | };
67 | }
68 | })(script, id);
69 | }
70 | script.type = 'text/javascript';
71 | script.src = url;
72 |
73 | docFrag.appendChild(script);
74 | }
75 |
76 | head.appendChild(docFrag);
77 | };
78 |
79 | var loadScripts = function (ids, callback, onerror) {
80 | var queues = [];
81 | for (var i = 0, len = ids.length; i < len; i++) {
82 | var id = ids[i];
83 | var queue = loadingMap[id] || (loadingMap[id] = []);
84 | queue.push(callback);
85 |
86 | //
87 | // resource map query
88 | //
89 | var res = resMap[id] || resMap[id + '.js'] || {};
90 | var pkg = res.pkg;
91 | var url;
92 |
93 | if (pkg) {
94 | url = pkgMap[pkg].url || pkgMap[pkg].uri;
95 | }
96 | else {
97 | url = res.url || res.uri || id;
98 | }
99 |
100 | queues.push({
101 | id: id,
102 | url: url
103 | });
104 | }
105 |
106 | createScripts(queues, onerror);
107 | };
108 |
109 | define = function (id, factory) {
110 | id = id.replace(/\.js$/i, '');
111 | factoryMap[id] = factory;
112 |
113 | var queue = loadingMap[id];
114 | if (queue) {
115 | for (var i = 0, n = queue.length; i < n; i++) {
116 | queue[i]();
117 | }
118 | delete loadingMap[id];
119 | }
120 | };
121 |
122 | require = function (id) {
123 |
124 | // compatible with require([dep, dep2...]) syntax.
125 | if (id && id.splice) {
126 | return require.async.apply(this, arguments);
127 | }
128 |
129 | id = require.alias(id);
130 |
131 | var mod = modulesMap[id];
132 | if (mod) {
133 | return mod.exports;
134 | }
135 |
136 | //
137 | // init module
138 | //
139 | var factory = factoryMap[id];
140 | if (!factory) {
141 | throw '[ModJS] Cannot find module `' + id + '`';
142 | }
143 |
144 | mod = modulesMap[id] = {
145 | exports: {}
146 | };
147 |
148 | //
149 | // factory: function OR value
150 | //
151 | var ret = (typeof factory === 'function') ? factory.apply(mod, [require, mod.exports, mod]) : factory;
152 |
153 | if (ret) {
154 | mod.exports = ret;
155 | }
156 |
157 | return mod.exports;
158 | };
159 |
160 | require.async = function (names, onload, onerror) {
161 | if (typeof names === 'string') {
162 | names = [names];
163 | }
164 |
165 | var needMap = {};
166 | var needNum = 0;
167 | var needLoad = [];
168 |
169 | function findNeed(depArr) {
170 | var child;
171 |
172 | for (var i = 0, n = depArr.length; i < n; i++) {
173 | //
174 | // skip loading or loaded
175 | //
176 | var dep = require.alias(depArr[i]);
177 |
178 | if (dep in needMap) {
179 | continue;
180 | }
181 |
182 | needMap[dep] = true;
183 |
184 | if (dep in factoryMap) {
185 | // check whether loaded resource's deps is loaded or not
186 | child = resMap[dep] || resMap[dep + '.js'];
187 | if (child && 'deps' in child) {
188 | findNeed(child.deps);
189 | }
190 | continue;
191 | }
192 |
193 | needLoad.push(dep);
194 | needNum++;
195 |
196 | child = resMap[dep] || resMap[dep + '.js'];
197 | if (child && 'deps' in child) {
198 | findNeed(child.deps);
199 | }
200 | }
201 | }
202 |
203 | function updateNeed() {
204 | if (0 === needNum--) {
205 | var args = [];
206 | for (var i = 0, n = names.length; i < n; i++) {
207 | args[i] = require(names[i]);
208 | }
209 |
210 | onload && onload.apply(global, args);
211 | }
212 | }
213 |
214 | findNeed(names);
215 | loadScripts(needLoad, updateNeed, onerror);
216 | updateNeed();
217 | };
218 |
219 | require.ensure = function (names, callback) {
220 | require.async(names, function () {
221 | callback && callback.call(this, require);
222 | });
223 | };
224 |
225 | require.resourceMap = function (obj) {
226 | var k;
227 | var col;
228 |
229 | // merge `res` & `pkg` fields
230 | col = obj.res;
231 | for (k in col) {
232 | if (col.hasOwnProperty(k)) {
233 | resMap[k] = col[k];
234 | }
235 | }
236 |
237 | col = obj.pkg;
238 | for (k in col) {
239 | if (col.hasOwnProperty(k)) {
240 | pkgMap[k] = col[k];
241 | }
242 | }
243 | };
244 |
245 | require.loadJs = function (url) {
246 | if (url in scriptsMap) {
247 | return;
248 | }
249 |
250 | scriptsMap[url] = true;
251 |
252 | var script = document.createElement('script');
253 | script.type = 'text/javascript';
254 | script.src = url;
255 | head.appendChild(script);
256 | };
257 |
258 | require.loadCss = function (cfg) {
259 | if (cfg.content) {
260 | var sty = document.createElement('style');
261 | sty.type = 'text/css';
262 |
263 | if (sty.styleSheet) { // IE
264 | sty.styleSheet.cssText = cfg.content;
265 | }
266 | else {
267 | sty.innerHTML = cfg.content;
268 | }
269 | head.appendChild(sty);
270 | }
271 | else if (cfg.url) {
272 | var link = document.createElement('link');
273 | link.href = cfg.url;
274 | link.rel = 'stylesheet';
275 | link.type = 'text/css';
276 | head.appendChild(link);
277 | }
278 | };
279 |
280 |
281 | require.alias = function (id) {
282 | return id.replace(/\.js$/i, '');
283 | };
284 |
285 | require.timeout = 5000;
286 |
287 | })(this);
288 |
--------------------------------------------------------------------------------
/modules/lib/template/template.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * template.js v0.6.1 (https://github.com/yanhaijing/template.js)
3 | * API https://github.com/yanhaijing/template.js/blob/master/doc/api.md
4 | * Copyright 2015 yanhaijing. All Rights Reserved
5 | * Licensed under MIT (https://github.com/yanhaijing/template.js/blob/master/MIT-LICENSE.txt)
6 | */
7 | ;(function(root, factory) {
8 | var template = factory(root);
9 | if (typeof define === 'function' && define.amd) {
10 | // AMD
11 | define('template', function() {
12 | return template;
13 | });
14 | } else if (typeof exports === 'object') {
15 | // Node.js
16 | module.exports = template;
17 | } else {
18 | // Browser globals
19 | var _template = root.template;
20 |
21 | template.noConflict = function() {
22 | if (root.template === template) {
23 | root.template = _template;
24 | }
25 |
26 | return template;
27 | };
28 | root.template = template;
29 | }
30 | }(this, function(root) {
31 | 'use strict';
32 | var o = {
33 | sTag: '<%',//开始标签
34 | eTag: '%>',//结束标签
35 | compress: false,//是否压缩html
36 | escape: true, //默认输出是否进行HTML转义
37 | error: function (e) {}//错误回调
38 | };
39 | var toString = {}.toString;
40 |
41 | function getType(x) {
42 | if(x === null){
43 | return 'null';
44 | }
45 |
46 | var t= typeof x;
47 |
48 | if(t !== 'object'){
49 | return t;
50 | }
51 |
52 | var c = toString.call(x).slice(8, -1).toLowerCase();
53 | if(c !== 'object'){
54 | return c;
55 | }
56 |
57 | if(x.constructor==Object){
58 | return c;
59 | }
60 |
61 | return 'unkonw';
62 | }
63 |
64 | function isObject(obj) {
65 | return getType(obj) === 'object';
66 | }
67 | function extend() {
68 | var target = arguments[0] || {};
69 | var arrs = Array.prototype.slice.call(arguments, 1);
70 | var len = arrs.length;
71 |
72 | for (var i = 0; i < len; i++) {
73 | var arr = arrs[i];
74 | for (var name in arr) {
75 | target[name] = arr[name];
76 | }
77 |
78 | }
79 | return target;
80 | }
81 | function encodeHTML(source) {
82 | return String(source)
83 | .replace(/&/g,'&')
84 | .replace(//g,'>')
86 | .replace(/\\/g,'\')
87 | .replace(/"/g,'"')
88 | .replace(/'/g,''');
89 | };
90 | function compress(html) {
91 | return html.replace(/\s+/g, ' ').replace(//g, '');
92 | }
93 | function handelError(e) {
94 | var message = 'template.js error\n\n';
95 |
96 | for (var key in e) {
97 | message += '<' + key + '>\n' + e[key] + '\n\n';
98 | }
99 | message += '\n' + e.message + '\n\n';
100 | typeof console !== 'undefined' && console.error && console.error(message);
101 |
102 | o.error(e);
103 | function error() {
104 | return 'template.js error';
105 | }
106 | error.toString = function () {
107 | return '__code__ = "template.js error"';
108 | }
109 | return error;
110 | }
111 | function parse(tpl, opt) {
112 | var code = '';
113 | var sTag = opt.sTag;
114 | var eTag = opt.eTag;
115 | var escape = opt.escape;
116 | function parsehtml(line) {
117 | // 单双引号转义,换行符替换为空格
118 | line = line.replace(/('|")/g, '\\$1').replace(/\n/g, ' ');
119 | return ';__code__ += ("' + line + '")\n';
120 | }
121 | function parsejs(line) {
122 | var html;
123 | if (line.search(/^=/) !== -1) {
124 | //默认输出
125 | html = line.slice(1);
126 | html = escape ? ('__encodeHTML__(typeof (' + html + ') === "undefined" ? "" : ' + html + ')') : html;
127 | return ';__code__ += (' + html + ')\n';
128 | }
129 |
130 | if (line.search(/^:h=/) !== -1) {
131 | //HTML转义输出
132 | html = line.slice(3);
133 | return ';__code__ += (__encodeHTML__(typeof (' + html + ') === "undefined" ? "" : ' + html + '))\n';
134 | }
135 |
136 | if (line.search(/^:=/) !== -1) {
137 | //不转义
138 | html = line.slice(2);
139 | return ';__code__ += (typeof (' + html + ') === "undefined" ? "" : ' + html + ')\n';
140 | }
141 |
142 | if (line.search(/^:u=/) !== -1) {
143 | //URL转义
144 | html = line.slice(3);
145 | return ';__code__ += (typeof (' + html + ') === "undefined" ? "" : encodeURI(' + html + '))\n';
146 | }
147 |
148 | //原生js
149 | return ';' + line + '\n';
150 | }
151 |
152 | var tokens = tpl.split(sTag);
153 |
154 | for (var i = 0, len = tokens.length; i < len; i++) {
155 | var token = tokens[i].split(eTag);
156 |
157 | if (token.length === 1) {
158 | code += parsehtml(token[0]);
159 | } else {
160 | code += parsejs(token[0], true);
161 | if (token[1]) {
162 | code += parsehtml(token[1]);
163 | }
164 | }
165 | }
166 |
167 | return code;
168 | }
169 | function compiler(tpl, opt) {
170 | var mainCode = parse(tpl, opt);
171 |
172 | var headerCode = '\n' +
173 | ' var html = (function (__data__, __encodeHTML__) {\n' +
174 | ' var __str__ = "", __code__ = "";\n' +
175 | ' for(var key in __data__) {\n' +
176 | ' __str__+=("var " + key + "=__data__[\'" + key + "\'];");\n' +
177 | ' }\n' +
178 | ' eval(__str__);\n\n';
179 |
180 | var footerCode = '\n' +
181 | ' ;return __code__;\n' +
182 | ' }(__data__, __encodeHTML__));\n' +
183 | ' return html;\n';
184 |
185 | var code = headerCode + mainCode + footerCode;
186 | code = code.replace(/[\r]/g, ' '); // ie 7 8 会报错,不知道为什么
187 | try {
188 | var Render = new Function('__data__', '__encodeHTML__', code);
189 | Render.toString = function () {
190 | return mainCode;
191 | }
192 | return Render;
193 | } catch(e) {
194 | e.temp = 'function anonymous(__data__, __encodeHTML__) {' + code + '}';
195 | throw e;
196 | }
197 | }
198 | function compile(tpl, opt) {
199 | opt = extend({}, o, opt);
200 |
201 | try {
202 | var Render = compiler(tpl, opt);
203 | } catch(e) {
204 | e.name = 'CompileError';
205 | e.tpl = tpl;
206 | e.render = e.temp;
207 | delete e.temp;
208 | return handelError(e);
209 | }
210 |
211 | function render(data) {
212 | try {
213 | var html = Render(data, encodeHTML);
214 | html = opt.compress ? compress(html) : html;
215 | return html;
216 | } catch(e) {
217 | e.name = 'RenderError';
218 | e.tpl = tpl;
219 | e.render = Render.toString();
220 | return handelError(e);
221 | }
222 | }
223 |
224 | render.toString = function () {
225 | return Render.toString();
226 | };
227 | return render;
228 | }
229 | function template(tpl, data) {
230 | if (typeof tpl !== 'string') {
231 | return '';
232 | }
233 |
234 | var fn = compile(tpl);
235 | if (!isObject(data)) {
236 | return fn;
237 | }
238 |
239 | return fn(data);
240 | }
241 |
242 | template.config = function (option) {
243 | if (isObject(option)) {
244 | o = extend(o, option);
245 | }
246 |
247 | return extend({}, o);
248 | };
249 |
250 | template.__encodeHTML = encodeHTML;
251 | template.__compress = compress;
252 | template.__handelError = handelError;
253 | template.__compile = compile;
254 | template.version = '0.6.1';
255 | return template;
256 | }));
257 |
--------------------------------------------------------------------------------
/modules/lib/data.js/data.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * data.js v0.3.0 (https://github.com/yanhaijing/data.js)
3 | * Copyright 2013 yanhaijing. All Rights Reserved
4 | * Licensed under MIT (https://github.com/yanhaijing/data.js/blob/master/MIT-LICENSE.txt)
5 | */
6 | (function (root, factory) {
7 | var Data = factory(root);
8 | if ( typeof define === 'function' && define.amd) {
9 | // AMD
10 | define('data', function() {
11 | return Data;
12 | });
13 | } else if ( typeof exports === 'object') {
14 | // Node.js
15 | module.exports = Data;
16 | } else {
17 | // Browser globals
18 | var _Data = root.Data;
19 |
20 | Data.noConflict = function () {
21 | if (root.Data === Data) {
22 | root.Data = _Data;
23 | }
24 |
25 | return Data;
26 | };
27 | root.Data = Data;
28 | }
29 | }(this, function (root) {
30 | 'use strict';
31 | var slice = [].slice;
32 | var obj = {};
33 | var toString = obj.toString;
34 | var hasOwn = obj.hasOwnProperty;
35 | var euid = 0;
36 | function getType(x) {
37 | if(x === null){
38 | return 'null';
39 | }
40 |
41 | var t= typeof x;
42 |
43 | if(t !== 'object'){
44 | return t;
45 | }
46 | var c;
47 | // 某些类型会报错
48 | try {
49 | c = toString.call(x).slice(8, -1).toLowerCase();
50 | } catch(exp) {
51 | return 'unknow';
52 | }
53 | if(c !== 'object'){
54 | return c;
55 | }
56 |
57 | if(x.constructor===Object){
58 | return c;
59 | }
60 |
61 | return 'unknow';
62 | }
63 | function isFn(fn) {
64 | return getType(fn) === 'function';
65 | }
66 | function isArr(arr) {
67 | return Array.isArray ? Array.isArray(arr) : getType(arr) === 'array';
68 | }
69 | function isObj(obj) {
70 | return getType(obj) === 'object';
71 | }
72 | function extendDeep() {
73 | var target = arguments[0] || {};
74 | var arrs = slice.call(arguments, 1);
75 | var len = arrs.length;
76 | var copyIsArr;
77 | var clone;
78 |
79 | for (var i = 0; i < len; i++) {
80 | var arr = arrs[i];
81 | for (var name in arr) {
82 | var src = target[name];
83 | var copy = arr[name];
84 |
85 | //避免无限循环
86 | if (target === copy) {
87 | continue;
88 | }
89 |
90 | // 非可枚举属性
91 | if (!hasOwn.call(arr, name)) {
92 | continue;
93 | }
94 |
95 | if (copy && (isObj(copy) || (copyIsArr = isArr(copy)))) {
96 | if (copyIsArr) {
97 | copyIsArr = false;
98 | clone = src && isArr(src) ? src : [];
99 |
100 | } else {
101 | clone = src && isObj(src) ? src : {};
102 | }
103 | target[ name ] = extendDeep(clone, copy);
104 | } else if (typeof copy !== 'undefined'){
105 | target[name] = copy;
106 | }
107 | }
108 |
109 | }
110 |
111 | return target;
112 | }
113 |
114 | function pub(events, event, key, data) {
115 | events = events[event][key];
116 |
117 | if (isObj(events)) {
118 | for (var name in events) {
119 | if (events.hasOwnProperty(name)) {
120 | events[name]({
121 | type: event,
122 | key: key,
123 | data: data
124 | });
125 | }
126 | }
127 | }
128 | }
129 | function extendData(key, events, context, src) {
130 | var nkey;
131 | for (var name in src) {
132 | var ctx = context[name];
133 | var copy = src[name];
134 | var copyIsArr;
135 | var isadd = false;
136 | var isdelete = false;
137 | //避免无限循环
138 | if (context === copy) {
139 | continue;
140 | }
141 |
142 | // 非可枚举属性
143 | if (!hasOwn.call(src, name)) {
144 | continue;
145 | }
146 |
147 | if (typeof copy === 'undefined') {
148 | isdelete = true;
149 | } else if (typeof context[name] === 'undefined') {
150 | isadd = true;
151 | }
152 |
153 | nkey = (typeof key === 'undefined' ? '' : (key + '.')) + name;
154 |
155 | if (copy && (isObj(copy) || (copyIsArr = isArr(copy)))) {
156 | if (copyIsArr) {
157 | copyIsArr = false;
158 | context[name] = ctx && isArr(ctx) ? ctx : [];
159 |
160 | } else {
161 | context[name] = ctx && isObj(ctx) ? ctx : {};
162 | }
163 | context[name] = extendData(nkey, events, context[name], copy);
164 | } else {
165 | context[name] = copy;
166 | }
167 |
168 | pub(events, 'set', nkey, context[name]);
169 |
170 | if (isdelete) {
171 | pub(events, 'delete', nkey, context[name]);
172 | } else if (isadd) {
173 | pub(events, 'add', nkey, context[name]);
174 | } else {
175 | pub(events, 'update', nkey, context[name]);
176 | }
177 | }
178 |
179 | return context;
180 | }
181 |
182 | function parseKey(key) {
183 | return key.split('.');
184 | }
185 |
186 | function cloneDeep(src) {
187 | if (isObj(src)) {
188 | return extendDeep({}, src);
189 | }
190 |
191 | if (isArr(src)){
192 | return extendDeep([], src);
193 | }
194 |
195 | return src;
196 | }
197 |
198 | //Data构造函数
199 | var Data = function () {
200 | if (!(this instanceof Data)) {
201 | return new Data();
202 | }
203 | this._init();
204 | };
205 |
206 | //扩展Data原型
207 | extendDeep(Data.prototype, {
208 | _init: function () {
209 | this._context = {};
210 | this._events = {
211 | 'set': {},
212 | 'delete': {},
213 | 'add': {},
214 | 'update': {}
215 | };
216 | },
217 | set: function (key, val) {
218 | var ctx = this._context;
219 |
220 | if (typeof key !== 'string') {
221 | return false;
222 | }
223 |
224 | var keys = parseKey(key);
225 | var len = keys.length;
226 | var i = 0;
227 | var name;
228 | var src;
229 | //键值为 单个的情况
230 | if (len < 2) {
231 | src = {};
232 | src[key] = val;
233 | extendData(undefined, this._events, ctx, src);
234 | return true;
235 | }
236 |
237 | //切换到对应上下文
238 | for (; i < len - 1; i++) {
239 | name = keys[i];
240 |
241 | //若不存在对应上下文自动创建
242 | if (!isArr(ctx[name]) && !isObj(ctx[name])) {
243 | //删除操作不存在对应值时,提前退出
244 | if (typeof val === 'undefined') {
245 | return false;
246 | }
247 | //若键值为数组则新建数组,否则新建对象
248 | ctx[name] = isNaN(Number(name)) ? {} : [];
249 | }
250 |
251 | ctx = ctx[name];
252 | }
253 |
254 | name = keys.pop();
255 |
256 | src = isArr(ctx) ? [] : {};
257 |
258 | src[name] = val;
259 |
260 | ctx = extendData(keys.join('.'), this._events, ctx, src);
261 |
262 | return true;
263 | },
264 | get: function (key) {
265 | //key不为字符串返回undefined
266 | if (typeof key !== 'string') {
267 | return undefined;
268 | }
269 |
270 | var keys = parseKey(key);
271 | var len = keys.length;
272 | var i = 0;
273 | var ctx = this._context;
274 | var name;
275 |
276 | for (; i < len; i++) {
277 | name = keys[i];
278 | ctx = ctx[name];
279 |
280 | if (typeof ctx === 'undefined' || ctx === null) {
281 | return ctx;
282 | }
283 | }
284 |
285 | //返回数据的副本
286 | return cloneDeep(ctx);
287 | },
288 | has: function (key) {
289 | return typeof this.get(key) === 'undefined' ? false : true;
290 | },
291 | sub: function (type, key, callback) {
292 | //参数不合法
293 | if (typeof type !== 'string' || typeof key !== 'string' || !isFn(callback)) {
294 | return -1;
295 | }
296 |
297 | //不支持的事件
298 | if (!(type in this._events)) {
299 | return -2;
300 | }
301 |
302 | var events = this._events[type];
303 |
304 | events[key] = events[key] || {};
305 |
306 | events[key][euid++] = callback;
307 |
308 | return euid - 1;
309 | },
310 | unsub: function (type, key, id ) {
311 | //参数不合法
312 | if (typeof type !== 'string' || typeof key !== 'string') {
313 | return false;
314 | }
315 |
316 | //不支持的事件
317 | if (!(type in this._events)) {
318 | return false;
319 | }
320 |
321 | var events = this._events[type];
322 |
323 | if (!isObj(events[key])) {
324 | return false;
325 | }
326 |
327 | if (typeof id !== 'number') {
328 | delete events[key];
329 | return true;
330 | }
331 |
332 | delete events[key][id];
333 |
334 | return true;
335 | },
336 | _clear: function () {
337 | return this._init();
338 | }
339 | });
340 |
341 | //新建默认数据中心
342 | var data = new Data();
343 |
344 | //扩展Data接口
345 | extendDeep(Data, {
346 | version: '0.3.0',
347 | has: function (key) {
348 | return data.has(key);
349 | },
350 | get: function (key) {
351 | return data.get(key);
352 | },
353 | set: function (key, val) {
354 | return data.set(key, val);
355 | },
356 | sub: function (type, key, callback) {
357 | return data.sub(type, key, callback);
358 | },
359 | unsub: function (type, key, id) {
360 | return data.unsub(type, key, id);
361 | },
362 | _clear: function () {
363 | return data._clear();
364 | }
365 | });
366 |
367 | return Data;//return Data
368 | }));
369 |
--------------------------------------------------------------------------------
/lib/es5-sham.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * https://github.com/es-shims/es5-shim
3 | * @license es5-shim Copyright 2009-2015 by contributors, MIT License
4 | * see https://github.com/es-shims/es5-shim/blob/master/LICENSE
5 | */
6 |
7 | // vim: ts=4 sts=4 sw=4 expandtab
8 |
9 | // Add semicolon to prevent IIFE from being passed as argument to concatenated code.
10 | ;
11 |
12 | // UMD (Universal Module Definition)
13 | // see https://github.com/umdjs/umd/blob/master/templates/returnExports.js
14 | (function (root, factory) {
15 | 'use strict';
16 |
17 | /* global define, exports, module */
18 | if (typeof define === 'function' && define.amd) {
19 | // AMD. Register as an anonymous module.
20 | define(factory);
21 | } else if (typeof exports === 'object') {
22 | // Node. Does not work with strict CommonJS, but
23 | // only CommonJS-like enviroments that support module.exports,
24 | // like Node.
25 | module.exports = factory();
26 | } else {
27 | // Browser globals (root is window)
28 | root.returnExports = factory();
29 | }
30 | }(this, function () {
31 |
32 | var call = Function.call;
33 | var prototypeOfObject = Object.prototype;
34 | var owns = call.bind(prototypeOfObject.hasOwnProperty);
35 | var isEnumerable = call.bind(prototypeOfObject.propertyIsEnumerable);
36 | var toStr = call.bind(prototypeOfObject.toString);
37 |
38 | // If JS engine supports accessors creating shortcuts.
39 | var defineGetter;
40 | var defineSetter;
41 | var lookupGetter;
42 | var lookupSetter;
43 | var supportsAccessors = owns(prototypeOfObject, '__defineGetter__');
44 | if (supportsAccessors) {
45 | /* eslint-disable no-underscore-dangle */
46 | defineGetter = call.bind(prototypeOfObject.__defineGetter__);
47 | defineSetter = call.bind(prototypeOfObject.__defineSetter__);
48 | lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
49 | lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
50 | /* eslint-enable no-underscore-dangle */
51 | }
52 |
53 | // ES5 15.2.3.2
54 | // http://es5.github.com/#x15.2.3.2
55 | if (!Object.getPrototypeOf) {
56 | // https://github.com/es-shims/es5-shim/issues#issue/2
57 | // http://ejohn.org/blog/objectgetprototypeof/
58 | // recommended by fschaefer on github
59 | //
60 | // sure, and webreflection says ^_^
61 | // ... this will nerever possibly return null
62 | // ... Opera Mini breaks here with infinite loops
63 | Object.getPrototypeOf = function getPrototypeOf(object) {
64 | /* eslint-disable no-proto */
65 | var proto = object.__proto__;
66 | /* eslint-enable no-proto */
67 | if (proto || proto === null) {
68 | return proto;
69 | } else if (toStr(object.constructor) === '[object Function]') {
70 | return object.constructor.prototype;
71 | } else if (object instanceof Object) {
72 | return prototypeOfObject;
73 | } else {
74 | // Correctly return null for Objects created with `Object.create(null)`
75 | // (shammed or native) or `{ __proto__: null}`. Also returns null for
76 | // cross-realm objects on browsers that lack `__proto__` support (like
77 | // IE <11), but that's the best we can do.
78 | return null;
79 | }
80 | };
81 | }
82 |
83 | // ES5 15.2.3.3
84 | // http://es5.github.com/#x15.2.3.3
85 |
86 | var doesGetOwnPropertyDescriptorWork = function doesGetOwnPropertyDescriptorWork(object) {
87 | try {
88 | object.sentinel = 0;
89 | return Object.getOwnPropertyDescriptor(object, 'sentinel').value === 0;
90 | } catch (exception) {
91 | return false;
92 | }
93 | };
94 |
95 | // check whether getOwnPropertyDescriptor works if it's given. Otherwise, shim partially.
96 | if (Object.defineProperty) {
97 | var getOwnPropertyDescriptorWorksOnObject = doesGetOwnPropertyDescriptorWork({});
98 | var getOwnPropertyDescriptorWorksOnDom = typeof document === 'undefined' ||
99 | doesGetOwnPropertyDescriptorWork(document.createElement('div'));
100 | if (!getOwnPropertyDescriptorWorksOnDom || !getOwnPropertyDescriptorWorksOnObject) {
101 | var getOwnPropertyDescriptorFallback = Object.getOwnPropertyDescriptor;
102 | }
103 | }
104 |
105 | if (!Object.getOwnPropertyDescriptor || getOwnPropertyDescriptorFallback) {
106 | var ERR_NON_OBJECT = 'Object.getOwnPropertyDescriptor called on a non-object: ';
107 |
108 | /* eslint-disable no-proto */
109 | Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) {
110 | if ((typeof object !== 'object' && typeof object !== 'function') || object === null) {
111 | throw new TypeError(ERR_NON_OBJECT + object);
112 | }
113 |
114 | // make a valiant attempt to use the real getOwnPropertyDescriptor
115 | // for I8's DOM elements.
116 | if (getOwnPropertyDescriptorFallback) {
117 | try {
118 | return getOwnPropertyDescriptorFallback.call(Object, object, property);
119 | } catch (exception) {
120 | // try the shim if the real one doesn't work
121 | }
122 | }
123 |
124 | var descriptor;
125 |
126 | // If object does not owns property return undefined immediately.
127 | if (!owns(object, property)) {
128 | return descriptor;
129 | }
130 |
131 | // If object has a property then it's for sure `configurable`, and
132 | // probably `enumerable`. Detect enumerability though.
133 | descriptor = {
134 | enumerable: isEnumerable(object, property),
135 | configurable: true
136 | };
137 |
138 | // If JS engine supports accessor properties then property may be a
139 | // getter or setter.
140 | if (supportsAccessors) {
141 | // Unfortunately `__lookupGetter__` will return a getter even
142 | // if object has own non getter property along with a same named
143 | // inherited getter. To avoid misbehavior we temporary remove
144 | // `__proto__` so that `__lookupGetter__` will return getter only
145 | // if it's owned by an object.
146 | var prototype = object.__proto__;
147 | var notPrototypeOfObject = object !== prototypeOfObject;
148 | // avoid recursion problem, breaking in Opera Mini when
149 | // Object.getOwnPropertyDescriptor(Object.prototype, 'toString')
150 | // or any other Object.prototype accessor
151 | if (notPrototypeOfObject) {
152 | object.__proto__ = prototypeOfObject;
153 | }
154 |
155 | var getter = lookupGetter(object, property);
156 | var setter = lookupSetter(object, property);
157 |
158 | if (notPrototypeOfObject) {
159 | // Once we have getter and setter we can put values back.
160 | object.__proto__ = prototype;
161 | }
162 |
163 | if (getter || setter) {
164 | if (getter) {
165 | descriptor.get = getter;
166 | }
167 | if (setter) {
168 | descriptor.set = setter;
169 | }
170 | // If it was accessor property we're done and return here
171 | // in order to avoid adding `value` to the descriptor.
172 | return descriptor;
173 | }
174 | }
175 |
176 | // If we got this far we know that object has an own property that is
177 | // not an accessor so we set it as a value and return descriptor.
178 | descriptor.value = object[property];
179 | descriptor.writable = true;
180 | return descriptor;
181 | };
182 | /* eslint-enable no-proto */
183 | }
184 |
185 | // ES5 15.2.3.4
186 | // http://es5.github.com/#x15.2.3.4
187 | if (!Object.getOwnPropertyNames) {
188 | Object.getOwnPropertyNames = function getOwnPropertyNames(object) {
189 | return Object.keys(object);
190 | };
191 | }
192 |
193 | // ES5 15.2.3.5
194 | // http://es5.github.com/#x15.2.3.5
195 | if (!Object.create) {
196 |
197 | // Contributed by Brandon Benvie, October, 2012
198 | var createEmpty;
199 | var supportsProto = !({ __proto__: null } instanceof Object);
200 | // the following produces false positives
201 | // in Opera Mini => not a reliable check
202 | // Object.prototype.__proto__ === null
203 |
204 | // Check for document.domain and active x support
205 | // No need to use active x approach when document.domain is not set
206 | // see https://github.com/es-shims/es5-shim/issues/150
207 | // variation of https://github.com/kitcambridge/es5-shim/commit/4f738ac066346
208 | /* global ActiveXObject */
209 | var shouldUseActiveX = function shouldUseActiveX() {
210 | // return early if document.domain not set
211 | if (!document.domain) {
212 | return false;
213 | }
214 |
215 | try {
216 | return !!new ActiveXObject('htmlfile');
217 | } catch (exception) {
218 | return false;
219 | }
220 | };
221 |
222 | // This supports IE8 when document.domain is used
223 | // see https://github.com/es-shims/es5-shim/issues/150
224 | // variation of https://github.com/kitcambridge/es5-shim/commit/4f738ac066346
225 | var getEmptyViaActiveX = function getEmptyViaActiveX() {
226 | var empty;
227 | var xDoc;
228 |
229 | xDoc = new ActiveXObject('htmlfile');
230 |
231 | xDoc.write('