data-original-title="<%=title%>"<%}%>>
<%if(icon){%>
<%}%><%if(text){%><%=text%><%}%>
' +
5 | '
' +
6 | '
<\/div>' +
7 | '
' +
8 | '
',
9 | defaultOpt: {
10 | text: '',
11 | title: '',
12 | click: function () {
13 | }
14 | },
15 | init: function (options) {
16 | var me = this;
17 | me.root($($.parseTmpl(me.tpl, options)));
18 | me.root().find('.ufui-btn:first').click(function (evt) {
19 | if (!me.disabled()) {
20 | $.proxy(options.click, me)();
21 | }
22 | });
23 | me.root().find('.ufui-dropdown-toggle').click(function () {
24 | if (!me.disabled()) {
25 | me.trigger('arrowclick');
26 | }
27 | });
28 | me.root().hover(function () {
29 | if (!me.root().hasClass("ufui-disabled")) {
30 | me.root().toggleClass('ufui-hover');
31 | }
32 | });
33 |
34 | return me;
35 | },
36 | wrapclick: function (fn, evt) {
37 | if (!this.disabled()) {
38 | $.proxy(fn, this, evt)();
39 | }
40 | return this;
41 | },
42 | disabled: function (state) {
43 | if (state === undefined) {
44 | return this.root().hasClass('ufui-disabled');
45 | }
46 | this.root().toggleClass('ufui-disabled', state).find('.ufui-btn').toggleClass('ufui-disabled', state);
47 | return this;
48 | },
49 | active: function (state) {
50 | if (state === undefined) {
51 | return this.root().hasClass('ufui-active');
52 | }
53 | this.root().toggleClass('ufui-active', state).find('.ufui-btn:first').toggleClass('ufui-active', state);
54 | return this;
55 | },
56 | mergeWith: function ($obj) {
57 | var me = this;
58 | me.data('$mergeObj', $obj);
59 | $obj.ufui().data('$mergeObj', me.root());
60 | if (!$.contains(document.body, $obj[0])) {
61 | $obj.appendTo(me.root());
62 | }
63 | me.root().delegate('.ufui-dropdown-toggle', 'click', function () {
64 | me.wrapclick(function () {
65 | $obj.ufui().show();
66 | });
67 | });
68 | me.register('click', me.root().find('.ufui-dropdown-toggle'), function (evt) {
69 | $obj.hide();
70 | });
71 | }
72 | });
--------------------------------------------------------------------------------
/_spec/tools/list.php:
--------------------------------------------------------------------------------
1 |
15 |
16 |
17 |
18 |
19 |
20 |
Kity Test Index Page
21 |
22 |
23 |
24 |
26 |
27 |
28 |
29 |
Kity Test Index Page
30 |
31 |
32 |
33 |
38 |
39 |
40 | 自动下一个
41 | 出错时终止
42 |
44 |
45 |
46 |
52 |
53 |
61 |
63 |
64 |
65 |
72 |
73 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration
2 | // Generated on Wed Oct 09 2013 19:20:49 GMT+0800 (中国标准时间)
3 |
4 | module.exports = function(config) {
5 | config.set({
6 |
7 | // base path, that will be used to resolve files and exclude
8 | basePath: '',
9 |
10 |
11 | // frameworks to use
12 | frameworks: ['jasmine'],
13 |
14 |
15 | // list of files / patterns to load in the browser
16 | files: [
17 | './jquery-1.11.0.min.js',
18 | './ufinder.config.js',
19 | './_src/core/ufinder.js',
20 | './_src/core/ufinder.*.js',
21 | './_src/core/class.js',
22 | './_src/core/utils.js',
23 | './_src/core/finder.js',
24 | './_src/core/finder.*.js',
25 | './_src/core/selection.js',
26 | './_src/core/datatree.js',
27 | './_src/core/request.js',
28 | './_src/core/uploader.js',
29 | './_src/core/proxy.js',
30 | './_src/adapter/*.js',
31 | './_spec/tools/js/UserAction.js',
32 | // './spec/karmaConfig.js',
33 | './_spec/SpecHelper.js',
34 | './_spec/core/*.js'
35 | // ,'./spec/graphic/*.js'
36 | ],
37 |
38 |
39 | // list of files to exclude
40 | exclude: [
41 | 'karma.conf.js'
42 | ],
43 |
44 |
45 | // test results reporter to use
46 | // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
47 | // reporters: ['progress'],
48 |
49 |
50 | // web server port
51 | port: 9876,
52 |
53 |
54 | // enable / disable colors in the output (reporters and logs)
55 | colors: true,
56 |
57 |
58 | // level of logging
59 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
60 | logLevel: config.LOG_INFO,
61 |
62 |
63 | // enable / disable watching file and executing tests whenever any file changes
64 | autoWatch: true,
65 |
66 |
67 | // Start these browsers, currently available:
68 | // - Chrome
69 | // - ChromeCanary
70 | // - Firefox
71 | // - Opera
72 | // - Safari (only Mac)
73 | // - PhantomJS
74 | // - IE (only Windows)
75 | browsers: ['Firefox'],//,'Chrome'
76 |
77 |
78 | // If browser does not capture in given timeout [ms], kill it
79 | captureTimeout: 60000,
80 |
81 |
82 | // Continuous Integration mode
83 | // if true, it capture browsers, run tests and exit
84 | singleRun: true,
85 | //coverage
86 | // reporters: ['progress', 'coverage'],
87 |
88 | reporters: ['progress', 'coverage','junit'],
89 | preprocessors: {
90 | './_src/core/*.js': ['coverage']
91 | }
92 | ,
93 | coverageReporter: {
94 | type: 'text',
95 | dir: './_spec/coverage'
96 | }
97 | ,
98 | junitReporter: {
99 | outputFile: 'test-results.xml'
100 | }
101 | });
102 | };
103 |
--------------------------------------------------------------------------------
/_src/ui/message.js:
--------------------------------------------------------------------------------
1 | UF.ui.define('message', {
2 | tpl: '
' +
3 | '
' +
4 | '
' +
5 | '
' +
6 | '
' +
7 | '
<%=title%>
' +
8 | '
' +
9 | '
' +
10 | '
' +
11 | '
',
12 | defaultOpt: {
13 | icon: '',
14 | title: ''
15 | },
16 | init: function (options) {
17 | var me = this;
18 | me.root($($.parseTmpl(me.tpl, options)));
19 | me.root().hide();
20 |
21 | me.$title = me.root().find('.ufui-message-title');
22 | me.$loadbar = me.root().find('.ufui-message-loadbar');
23 |
24 | //初始化进度
25 | me.loadedPercent = options.loadedPercent || 0;
26 | me.setLoadedPercent(me.loadedPercent);
27 |
28 | //设置关闭按钮事件
29 | me.root().find('.ufui-message-close').on('click', function () {
30 | me.hide();
31 | });
32 |
33 | //设置关闭的定时器
34 | if (options.timeout !== undefined && options.timeout >= 0) {
35 | me.timer = setTimeout(function () {
36 | me.hide();
37 | }, options.timeout);
38 | }
39 |
40 | return me;
41 | },
42 | show: function () {
43 | return this.root().fadeIn(400);
44 | },
45 | hide: function () {
46 | return this.root().fadeOut(400);
47 | },
48 | setIcon: function (icon) {
49 | this.root().find('.ufui-message-icon i').attr('class', 'ufui-message-icon-' + icon);
50 | return this;
51 | },
52 | getIcon: function () {
53 | var c = this.root().find('.ufui-message-icon i'),
54 | m = c.attr('class').match(/ufui-message-icon-([\w]+)(\s|$)/);
55 | return m ? m[1] : null;
56 | },
57 | setMessage: function (message) {
58 | this.$title.text(message);
59 | return this;
60 | },
61 | getMessage: function () {
62 | return this.$title.text();
63 | },
64 | setLoadedPercent: function (percent) {
65 | this.root().find('.ufui-message-loadbar-percent').css('width', percent + '%');
66 | return this;
67 | },
68 | getLoadedPercent: function () {
69 | return this.root().find('.ufui-message-loadbar-percent').css('width');
70 | },
71 | setTimer: function (timeout) {
72 | var me = this;
73 | if (timeout !== undefined) {
74 | clearTimeout(me.timer);
75 | }
76 | if (timeout >= 0) {
77 | me.timer = setTimeout(function () {
78 | me.hide();
79 | }, timeout);
80 | }
81 | return this;
82 | },
83 | getTimer: function () {
84 | return this.timer;
85 | }
86 | });
--------------------------------------------------------------------------------
/_src/adapter/tree.js:
--------------------------------------------------------------------------------
1 | UF.registerUI('tree',
2 | function (name) {
3 | var me = this,
4 | $tree = $.ufuitree(),
5 | ufTree = $tree.ufui(),
6 | addItem = function (info) {
7 | if (info.type == 'dir') {
8 | if (!ufTree.isItemInTree(info.path)) {
9 | ufTree.addItem({
10 | type: info.type,
11 | title: info.name,
12 | path: info.path
13 | });
14 | }
15 | }
16 | },
17 | openDir = function (path) {
18 | var info = me.dataTree.getFileInfo(path);
19 | if (info.read && !me.dataTree.isFileLocked(path)) {
20 | me.execCommand('open', path);
21 | }
22 | };
23 |
24 | /* 点击目录执行打开命令 */
25 | $tree.delegate('.ufui-leaf-expand,.ufui-leaf-folder,.ufui-leaf-title', 'click', function () {
26 | var $target = $(this),
27 | $detail = $target.parent(),
28 | $leaf = $detail.parent(),
29 | path = $leaf.attr('data-path'),
30 | info = me.dataTree.getFileInfo(path);
31 | if (info.read && !me.dataTree.isFileLocked(path)) {
32 | if ($target.hasClass('ufui-leaf-expand')) {
33 | if (!$detail.hasClass('ufui-leaf-detail-closed')) {
34 | me.execCommand('list', path);
35 | }
36 | } else {
37 | me.execCommand('open', path);
38 | }
39 | }
40 | });
41 |
42 | /* 初始化根节点 */
43 | me.on('dataReady', function (type, info) {
44 | ufTree.setRoot({
45 | type: info.type,
46 | title: 'Root',
47 | path: info.path
48 | });
49 | });
50 |
51 | /* 打开目录 */
52 | me.on('listFile', function (type, filelist) {
53 | $.each(filelist, function (i, file) {
54 | addItem(file);
55 | });
56 | });
57 |
58 | /* 打开目录 */
59 | me.on('addfiles', function (type, files) {
60 | $.each($.isArray(files) ? files : [files], function (k, file) {
61 | addItem(file);
62 | });
63 | });
64 |
65 | /* 重命名文件 */
66 | me.on('renamefile', function (type, path, file) {
67 | if (file.type != 'dir') return;
68 | var ufLeaf = ufTree.getItem(path);
69 | if (ufLeaf) {
70 | ufTree.removeItem(path);
71 | addItem(file);
72 | }
73 | });
74 |
75 | /* 删除文件 */
76 | me.on('removefiles', function (type, paths) {
77 | $.each($.isArray(paths) ? paths : [paths], function (i, path) {
78 | ufTree.isItemInTree(path) && ufTree.removeItem(path);
79 | });
80 | });
81 |
82 | return $tree;
83 | }
84 | );
85 |
--------------------------------------------------------------------------------
/_src/ui/button.js:
--------------------------------------------------------------------------------
1 | //button 类
2 | UF.ui.define('button', {
3 | tpl: '<<%if(!texttype){%>div class="ufui-btn ufui-btn-<%=icon%> <%if(name){%>ufui-btn-name-<%=name%><%}%>" unselectable="on" onmousedown="return false" <%}else{%>a class="ufui-text-btn"<%}%><% if(title) {%>title="<%=title%>" data-original-title="<%=title%>" <%};%>> ' +
4 | '<% if(icon) {%>
<% }; %><%if(text) {%>
<%=text%><%}%>' +
5 | '<%if(caret && text){%>
<%}%>' +
6 | '<% if(caret) {%>
<% };%><%if(!texttype){%>div<%}else{%>a<%}%>>',
7 | defaultOpt: {
8 | text: '',
9 | title: '',
10 | icon: '',
11 | width: '',
12 | caret: false,
13 | texttype: false,
14 | click: function () {
15 | }
16 | },
17 | init: function (options) {
18 | var me = this;
19 |
20 | me.root($($.parseTmpl(me.tpl, options)))
21 | .click(function (evt) {
22 | me.wrapclick(options.click, evt);
23 | });
24 |
25 | me.root().hover(function () {
26 | if (!me.root().hasClass("ufui-disabled")) {
27 | me.root().toggleClass('ufui-hover');
28 | }
29 | });
30 |
31 | return me;
32 | },
33 | wrapclick: function (fn, evt) {
34 | if (!this.disabled()) {
35 | this.root().trigger('wrapclick');
36 | return $.proxy(fn, this, evt)();
37 | }
38 | },
39 | label: function (text) {
40 | if (text === undefined) {
41 | return this.root().find('.ufui-button-label').text();
42 | } else {
43 | this.root().find('.ufui-button-label').text(text);
44 | return this;
45 | }
46 | },
47 | disabled: function (state) {
48 | if (state === undefined) {
49 | return this.root().hasClass('ufui-disabled');
50 | }
51 | this.root().toggleClass('ufui-disabled', state);
52 | if (this.root().hasClass('ufui-disabled')) {
53 | this.root().removeClass('ufui-hover');
54 | }
55 | return this;
56 | },
57 | active: function (state) {
58 | if (state === undefined) {
59 | return this.root().hasClass('ufui-active');
60 | }
61 | this.root().toggleClass('ufui-active', state);
62 |
63 | return this;
64 | },
65 | mergeWith: function ($obj) {
66 | var me = this;
67 | me.data('$mergeObj', $obj);
68 | $obj.ufui().data('$mergeObj', me.root());
69 | if (!$.contains(document.body, $obj[0])) {
70 | $obj.appendTo(me.root());
71 | }
72 | me.on('click', function () {
73 | me.wrapclick(function () {
74 | $obj.ufui().show();
75 | });
76 | }).register('click', me.root(), function (evt) {
77 | $obj.hide();
78 | });
79 | }
80 | });
--------------------------------------------------------------------------------
/_src/ui/search.js:
--------------------------------------------------------------------------------
1 | //button 类
2 | UF.ui.define('button', {
3 | tpl: '<<%if(!texttype){%>div class="ufui-btn ufui-btn-<%=icon%> <%if(name){%>ufui-btn-name-<%=name%><%}%>" unselectable="on" onmousedown="return false" <%}else{%>a class="ufui-text-btn"<%}%><% if(title) {%>title="<%=title%>" data-original-title="<%=title%>" <%};%>> ' +
4 | '<% if(icon) {%>
<% }; %><%if(text) {%>
<%=text%><%}%>' +
5 | '<%if(caret && text){%>
<%}%>' +
6 | '<% if(caret) {%>
<% };%><%if(!texttype){%>div<%}else{%>a<%}%>>',
7 | defaultOpt: {
8 | text: '',
9 | title: '',
10 | icon: '',
11 | width: '',
12 | caret: false,
13 | texttype: false,
14 | click: function () {
15 | }
16 | },
17 | init: function (options) {
18 | var me = this;
19 |
20 | me.root($($.parseTmpl(me.tpl, options)))
21 | .click(function (evt) {
22 | me.wrapclick(options.click, evt);
23 | });
24 |
25 | me.root().hover(function () {
26 | if (!me.root().hasClass("ufui-disabled")) {
27 | me.root().toggleClass('ufui-hover');
28 | }
29 | });
30 |
31 | return me;
32 | },
33 | wrapclick: function (fn, evt) {
34 | if (!this.disabled()) {
35 | this.root().trigger('wrapclick');
36 | $.proxy(fn, this, evt)();
37 | }
38 | return this;
39 | },
40 | label: function (text) {
41 | if (text === undefined) {
42 | return this.root().find('.ufui-button-label').text();
43 | } else {
44 | this.root().find('.ufui-button-label').text(text);
45 | return this;
46 | }
47 | },
48 | disabled: function (state) {
49 | if (state === undefined) {
50 | return this.root().hasClass('ufui-disabled');
51 | }
52 | this.root().toggleClass('ufui-disabled', state);
53 | if (this.root().hasClass('ufui-disabled')) {
54 | this.root().removeClass('ufui-hover');
55 | }
56 | return this;
57 | },
58 | active: function (state) {
59 | if (state === undefined) {
60 | return this.root().hasClass('ufui-active');
61 | }
62 | this.root().toggleClass('ufui-active', state);
63 |
64 | return this;
65 | },
66 | mergeWith: function ($obj) {
67 | var me = this;
68 | me.data('$mergeObj', $obj);
69 | $obj.ufui().data('$mergeObj', me.root());
70 | if (!$.contains(document.body, $obj[0])) {
71 | $obj.appendTo(me.root());
72 | }
73 | me.on('click', function () {
74 | me.wrapclick(function () {
75 | $obj.ufui().show();
76 | });
77 | }).register('click', me.root(), function (evt) {
78 | $obj.hide();
79 | });
80 | }
81 | });
--------------------------------------------------------------------------------
/_spec/tools/js/ext_jasmine.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created with JetBrains PhpStorm.
3 | * User: dongyancen
4 | * Date: 14-3-5
5 | * Time: 上午2:24
6 | * To change this template use File | Settings | File Templates.
7 | */
8 | /**
9 | * rewrite jasmine function to support batchrun
10 | */
11 | (function() {
12 | if (!jasmine)
13 | return;
14 | var s = jasmine.Queue.prototype.start
15 | // ,n = jasmine.Queue.prototype.next_
16 | ,f = jasmine.Runner.prototype.finishCallback;
17 | function _f(self,args /* failures, total */) {
18 | //todo 写到调用HtmlReporter后
19 | /*another way to apply:
20 | *
21 | * var reporterView = self.env.reporter.subReporters_[0].getReporterView();
22 | *totalSpecCount,completeSpecCount,failedCount,passedCount
23 | *reporterView.views.specs[0].detail
24 | * */
25 |
26 | var totalSpecCount = 0,failedCount = 0,passedCount = 0;
27 | var tmpSpec = null;
28 | for(var i=0;i
2 |
3 |
4 |
5 | ufinder demo
6 |
7 |
8 |
9 |
10 |
11 |
12 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/_src/ui/tree.js:
--------------------------------------------------------------------------------
1 | UF.ui.define('tree', {
2 | tpl: '',
5 | defaultOpt: {
6 | },
7 | init: function (options) {
8 | var me = this;
9 |
10 | me.root($($.parseTmpl(me.tpl, options)));
11 | me.$branch = me.root().find('.ufui-tree-branch');
12 |
13 | me._ufItems = {};
14 |
15 | return me;
16 | },
17 | disabled: function (state) {
18 | if (state === undefined) {
19 | return this.root().hasClass('ufui-disabled');
20 | }
21 | this.root().toggleClass('ufui-disabled', state);
22 | if (this.root().hasClass('ufui-disabled')) {
23 | this.root().removeClass('ufui-hover');
24 | }
25 | return this;
26 | },
27 | active: function (state) {
28 | if (state === undefined) {
29 | return this.root().hasClass('ufui-active');
30 | }
31 | this.root().toggleClass('ufui-active', state);
32 |
33 | return this;
34 | },
35 | _compare: function (a, b) {
36 | var type1 = a.getType(),
37 | type2 = b.getType(),
38 | title1 = a.getTitle(),
39 | title2 = b.getTitle();
40 |
41 | if (type1 == 'dir' && type2 != 'dir') {
42 | return 0;
43 | } else if (type1 != 'dir' && type2 == 'dir') {
44 | return 1;
45 | } else {
46 | return title1 > title2;
47 | }
48 | },
49 | getItem: function (path) {
50 | return this._ufItems[Utils.regularDirPath(path)];
51 | },
52 | getItems: function () {
53 | return this._ufItems;
54 | },
55 | addItem: function (options) {
56 | var path = options.path,
57 | $l = $.ufuileaf(options),
58 | ufLeaf = $l.ufui(),
59 | $parent = this.getItem(Utils.getParentPath(path));
60 |
61 | if (!this._ufItems[path]) {
62 | if ($parent) {
63 | $parent.addChild(ufLeaf);
64 | } else {
65 | this.$branch.append($l);
66 | }
67 | this._ufItems[path] = ufLeaf;
68 | }
69 |
70 | return this;
71 | },
72 | setRoot: function (options) {
73 | options.name = 'Root';
74 |
75 | var $l = $.ufuileaf(options),
76 | ufLeaf = $l.ufui();
77 |
78 | this.$branch.append($l);
79 | this._ufItems[options.path] = ufLeaf;
80 | $l.addClass('ufui-tree-leaf-root');
81 | // ufLeaf.expand(true);
82 |
83 | return this;
84 | },
85 | removeItem: function (path) {
86 | var me = this;
87 | path = Utils.regularDirPath(path);
88 | if (me._ufItems[path]) {
89 | me._ufItems[path].root().remove();
90 | delete me._ufItems[path];
91 | }
92 | return this;
93 | },
94 | clearItems: function () {
95 | $.each(this._ufItems, function (k, f) {
96 | f.root().remove();
97 | });
98 | this._ufItems = [];
99 | return this;
100 | },
101 | isItemInTree: function (path) {
102 | return this.getItem(path) ? true : false;
103 | }
104 | });
--------------------------------------------------------------------------------
/_spec/tools/css/test.css:
--------------------------------------------------------------------------------
1 | * {
2 | margin: 0;
3 | padding: 0;
4 | }
5 |
6 | html {
7 | border: 0;
8 | height: 100%;
9 | }
10 |
11 | body {
12 | font: 12px/1.5 Lucida Grande, Helvetica, Arial, sans-serif;
13 | background: #F3F1F1;
14 | color: #41464D;
15 | }
16 |
17 | body,#container {
18 | width: 100%;
19 | height: 100%;
20 | }
21 |
22 | .clear { /* generic container (i.e. div) for floating buttons */
23 | overflow: hidden;
24 | width: 100%;
25 | }
26 |
27 | a {
28 | text-decoration: none;
29 | overflow: hidden;
30 | }
31 |
32 | #title {
33 | top: 0;
34 | left: 0;
35 | width: 100%;
36 | padding: 5px 0;
37 | background: #aaa;
38 | background: #41464D;
39 | color: #F3F1F1;
40 | height: 30px;
41 | }
42 |
43 | a:link,a:visited {
44 | color: #528CE0;
45 | }
46 |
47 | a:hover,a:active {
48 | color: #41464D !important;
49 | cursor: pointer !important;
50 | }
51 |
52 | #title h1 {
53 | height: 30px;
54 | font: 25px/1.1 Arial, sans-serif;
55 | font-weight: bolder;
56 | float: left;
57 | margin: 1px 0 2px 20px;
58 | text-shadow: 0 2px 2px rgba(0, 0, 0, 0.4);
59 | }
60 |
61 | h3 {
62 | font-size: 14px;
63 | padding: 3px 5px 1px;
64 | }
65 |
66 | .control {
67 | background: #d5ded7;
68 | width: 99%;
69 | }
70 |
71 | .testlist {
72 | max-height: 200px;
73 | overflow-y: scroll;
74 | border-style: double;
75 | }
76 |
77 | .testlist a {
78 | display: block;
79 | width: 150px;
80 | color: #657528;
81 | background: #d5dea7;
82 | border: 1px solid #c8dc7b;
83 | margin: 5px 0 0 5px;
84 | text-indent: 5px;
85 | line-height: 24px;
86 | font-size: 14px;
87 | float: left;
88 | }
89 |
90 | a.button {
91 | background: transparent url('bg_button_a.gif') no-repeat scroll top
92 | right;
93 | color: #444;
94 | display: block;
95 | float: left;
96 | font: normal 12px arial, sans-serif;
97 | height: 24px;
98 | margin-right: 6px;
99 | padding-right: 18px; /* sliding doors padding */
100 | text-decoration: none;
101 | }
102 |
103 | a.button span {
104 | background: transparent url('bg_button_span.gif') no-repeat;
105 | display: block;
106 | line-height: 14px;
107 | padding: 5px 0 5px 18px;
108 | }
109 |
110 | a.button:active {
111 | background-position: bottom right;
112 | color: #000;
113 | outline: none; /* hide dotted outline in Firefox */
114 | }
115 |
116 | a.button:active span {
117 | background-position: bottom left;
118 | padding: 6px 0 4px 18px; /* push text down 1px */
119 | }
120 |
121 | .testlist a:link {
122 |
123 | }
124 |
125 | .testlist a:visited {
126 |
127 | }
128 |
129 | .testlist a:hover {
130 | background: #c8dc7b;
131 | }
132 |
133 | .testlist a.jsframe_jsspec {
134 | background: #DDDDDD
135 | }
136 |
137 | .testlist a.running_case {
138 | color: yellow;
139 | }
140 |
141 | .testlist a.fail_case {
142 | color: red;
143 | }
144 |
145 | .testlist a.pass_case {
146 | color: green;
147 | }
148 |
149 | .runningarea {
150 | height: 60%;
151 | }
152 |
153 | .runningmaindiv {
154 | height: 99%;
155 | }
156 |
157 | .runningframe {
158 | height: 99.99%;
159 | width: 99.99%;
160 | }
161 |
162 | .runningstatus {
163 | clear: both;
164 | height: 10%;
165 | border: solid
166 | }
167 |
168 | .reportarea {
169 | padding: 10px;
170 | border: 10px blue;
171 | max-height: 200px;
172 | overflow-y: scroll;
173 | }
--------------------------------------------------------------------------------
/_src/modules/addfile.js:
--------------------------------------------------------------------------------
1 | UF.registerModule("addfilemodule", function () {
2 | var uf = this;
3 | return {
4 | "init": function () {
5 |
6 | },
7 | "defaultOptions": {
8 | },
9 | "commands": {
10 | "touch": {
11 | execute: function (name) {
12 | uf.fire('newFileTitle', '', function (name, callback) {
13 | console.log('|******** touch done ********|');
14 | var fullname = uf.getCurrentPath() + name;
15 | if (name) {
16 | uf.proxy.touch(fullname, function (d) {
17 | callback && callback(d.state == 0);
18 | if (d.state == 0) {
19 | var file = (d && d.data && d.data.file);
20 | uf.dataTree.addFile(file);
21 | uf.fire('selectfiles', file.path);
22 | } else {
23 | uf.fire('showmessage', {title: d.message, timeout: 3000});
24 | }
25 | });
26 | }
27 | });
28 | },
29 | queryState: function () {
30 | var info, path = uf.getCurrentPath();
31 | info = uf.dataTree.getFileInfo(path);
32 | return info && info.write && !uf.dataTree.isFileLocked(path) ? 0 : -1;
33 | }
34 | },
35 | "mkdir": {
36 | execute: function (name) {
37 | // if (name === undefined) {
38 | // name = prompt('新建文件夹', '新建文件夹');
39 | // } else if (name == '') {
40 | // name = '新建文件夹';
41 | // }
42 |
43 | uf.fire('newFileTitle', 'dir', function (name, callback) {
44 | console.log('|******** mkdir done ********|');
45 | var fullname = uf.getCurrentPath() + name;
46 | if (name) {
47 | uf.proxy.mkdir(fullname, function (d) {
48 | callback && callback(d.state == 0);
49 | if (d.state == 0) {
50 | var file = (d && d.data && d.data.file);
51 | uf.dataTree.addFile(file);
52 | uf.fire('selectfiles', file.path);
53 | } else {
54 | uf.fire('showmessage', {title: d.message, timeout: 3000});
55 | }
56 | });
57 | }
58 | });
59 | },
60 | queryState: function () {
61 | var info, path = uf.getCurrentPath();
62 | info = uf.dataTree.getFileInfo(path);
63 | return info && info.write && !uf.dataTree.isFileLocked(path) ? 0 : -1;
64 | }
65 | }
66 | },
67 | "shortcutKeys": {
68 | "touch": "ctrl+78" //newfile ctrl+N
69 | },
70 | "events": {
71 | }
72 | };
73 | });
--------------------------------------------------------------------------------
/_src/ui/dropmenu.js:
--------------------------------------------------------------------------------
1 | //dropmenu 类
2 | UF.ui.define('dropmenu', {
3 | tmpl: '',
11 | defaultOpt: {
12 | data: [],
13 | click: function () {
14 |
15 | }
16 | },
17 | init: function (options) {
18 | var me = this;
19 | var eventName = {
20 | click: 1,
21 | mouseover: 1,
22 | mouseout: 1
23 | };
24 |
25 | this.root($($.parseTmpl(this.tmpl, options))).on('click', 'li[class!="ufui-disabled ufui-divider ufui-dropdown-submenu"]', function (evt) {
26 | $.proxy(options.click, me, evt, $(this).data('value'), $(this))();
27 | }).find('li').each(function (i, el) {
28 | var $this = $(this);
29 | if (!$this.hasClass("ufui-disabled ufui-divider ufui-dropdown-submenu")) {
30 | var data = options.data[i];
31 | $.each(eventName, function (k) {
32 | data[k] && $this[k](function (evt) {
33 | $.proxy(data[k], el)(evt, data, me.root);
34 | });
35 | });
36 | }
37 | });
38 |
39 | },
40 | disabled: function (cb) {
41 | $('li[class!=ufui-divider]', this.root()).each(function () {
42 | var $el = $(this);
43 | if (cb === true) {
44 | $el.addClass('ufui-disabled');
45 | } else if ($.isFunction(cb)) {
46 | $el.toggleClass('ufui-disabled', cb(li));
47 | } else {
48 | $el.removeClass('ufui-disabled');
49 | }
50 |
51 | });
52 | },
53 | val: function (val) {
54 | var currentVal;
55 | $('li[class!="ufui-divider ufui-disabled ufui-dropdown-submenu"]', this.root()).each(function () {
56 | var $el = $(this);
57 | if (val === undefined) {
58 | if ($el.find('em.ufui-dropmenu-checked').length) {
59 | currentVal = $el.data('value');
60 | return false;
61 | }
62 | } else {
63 | $el.find('em').toggleClass('ufui-dropmenu-checked', $el.data('value') == val);
64 | }
65 | });
66 | if (val === undefined) {
67 | return currentVal;
68 | }
69 | },
70 | addSubmenu: function (label, menu, index) {
71 | index = index || 0;
72 |
73 | var $list = $('li[class!=ufui-divider]', this.root());
74 | var $node = $('').append(menu);
75 |
76 | if (index >= 0 && index < $list.length) {
77 | $node.insertBefore($list[index]);
78 | } else if (index < 0) {
79 | $node.insertBefore($list[0]);
80 | } else if (index >= $list.length) {
81 | $node.appendTo($list);
82 | }
83 | }
84 | }, 'menu');
--------------------------------------------------------------------------------
/_src/adapter/dialog.js:
--------------------------------------------------------------------------------
1 | UF.registerUI('lookimage lookcode', function (name) {
2 |
3 | var me = this, $dialog,
4 | labelMap = me.getOption('labelMap'),
5 | opt = {
6 | title: (labelMap && labelMap[name]) || me.getLang("labelMap." + name),
7 | url: me.getOption('URL') + '/dialogs/' + name + '/' + name + '.js'
8 | };
9 |
10 | var $btn = $.ufuibutton({
11 | icon: name,
12 | title: this.getLang('labelMap')[name] || ''
13 | });
14 |
15 | /* 加载dialog模版数据 */
16 | Utils.loadFile(document, {
17 | src: opt.url,
18 | tag: "script",
19 | type: "text/javascript",
20 | defer: "defer"
21 | }, function () {
22 | /* 调整数据 */
23 | var data = UF.getWidgetData(name);
24 | if (data.buttons) {
25 | var ok = data.buttons.ok;
26 | if (ok) {
27 | opt.oklabel = ok.label || me.getLang('ok');
28 | if (ok.exec) {
29 | opt.okFn = function () {
30 | return $.proxy(ok.exec, null, me, $dialog)();
31 | };
32 | }
33 | }
34 | var cancel = data.buttons.cancel;
35 | if (cancel) {
36 | opt.cancellabel = cancel.label || me.getLang('cancel');
37 | if (cancel.exec) {
38 | opt.cancelFn = function () {
39 | return $.proxy(cancel.exec, null, me, $dialog)();
40 | };
41 | }
42 | }
43 | }
44 | data.width && (opt.width = data.width);
45 | data.height && (opt.height = data.height);
46 |
47 | $dialog = $.ufuimodal(opt);
48 |
49 | $dialog.attr('id', 'ufui-dialog-' + name).addClass('ufui-dialog-' + name)
50 | .find('.ufui-modal-body').addClass('ufui-dialog-' + name + '-body');
51 |
52 | $dialog.ufui().on('beforehide', function () {
53 |
54 | }).on('beforeshow', function () {
55 | var $root = this.root(),
56 | win = null,
57 | offset = null;
58 | if (!$root.parent()[0]) {
59 | me.$container.find('.ufui-dialog-container').append($root);
60 | }
61 |
62 | /* IE6下 特殊处理, 通过计算进行定位 */
63 | if ($.IE6) {
64 |
65 | win = {
66 | width: $(window).width(),
67 | height: $(window).height()
68 | };
69 | offset = $root.parents(".ufui-toolbar")[0].getBoundingClientRect();
70 | $root.css({
71 | position: 'absolute',
72 | margin: 0,
73 | left: ( win.width - $root.width() ) / 2 - offset.left,
74 | top: 100 - offset.top
75 | });
76 |
77 | }
78 | UF.setWidgetBody(name, $dialog, me);
79 | }).on('afterbackdrop', function () {
80 | this.$backdrop.css('zIndex', me.getOption('zIndex') + 1).appendTo(me.$container.find('.ufui-dialog-container'));
81 | $dialog.css('zIndex', me.getOption('zIndex') + 2);
82 | }).on('beforeok', function () {
83 |
84 | }).attachTo($btn);
85 | });
86 |
87 | me.on('selectionchange ready focus blur currentpathchange', function () {
88 | var state = me.queryCommandState(name);
89 | $btn.ufui().disabled(state == -1).active(state == 1);
90 | });
91 | return $btn;
92 | });
--------------------------------------------------------------------------------
/ufinder.config.js:
--------------------------------------------------------------------------------
1 | (function(){
2 |
3 | var URL = window.UFINDER_HOME_URL || (function(){
4 | function PathStack() {
5 | this.documentURL = self.document.URL || self.location.href;
6 | this.separator = '/';
7 | this.separatorPattern = /\\|\//g;
8 | this.currentDir = './';
9 | this.currentDirPattern = /^[.]\/]/;
10 | this.path = this.documentURL;
11 | this.stack = [];
12 | this.push( this.documentURL );
13 | }
14 |
15 | PathStack.isParentPath = function( path ){
16 | return path === '..';
17 | };
18 |
19 | PathStack.hasProtocol = function( path ){
20 | return !!PathStack.getProtocol( path );
21 | };
22 |
23 | PathStack.getProtocol = function( path ){
24 |
25 | var protocol = /^[^:]*:\/*/.exec( path );
26 |
27 | return protocol ? protocol[0] : null;
28 |
29 | };
30 |
31 | PathStack.prototype = {
32 | push: function( path ){
33 |
34 | this.path = path;
35 |
36 | update.call( this );
37 | parse.call( this );
38 |
39 | return this;
40 |
41 | },
42 | getPath: function(){
43 | return this + "";
44 | },
45 | toString: function(){
46 | return this.protocol + ( this.stack.concat( [''] ) ).join( this.separator );
47 | }
48 | };
49 |
50 | function update() {
51 |
52 | var protocol = PathStack.getProtocol( this.path || '' );
53 |
54 | if( protocol ) {
55 |
56 | //根协议
57 | this.protocol = protocol;
58 |
59 | //local
60 | this.localSeparator = /\\|\//.exec( this.path.replace( protocol, '' ) )[0];
61 |
62 | this.stack = [];
63 | } else {
64 | protocol = /\\|\//.exec( this.path );
65 | protocol && (this.localSeparator = protocol[0]);
66 | }
67 |
68 | }
69 |
70 | function parse(){
71 |
72 | var parsedStack = this.path.replace( this.currentDirPattern, '' );
73 |
74 | if( PathStack.hasProtocol( this.path ) ) {
75 | parsedStack = parsedStack.replace( this.protocol , '');
76 | }
77 |
78 | parsedStack = parsedStack.split( this.localSeparator );
79 | parsedStack.length = parsedStack.length - 1;
80 |
81 | for(var i= 0,tempPath,l=parsedStack.length,root = this.stack;i' +
3 | ' ' +
4 | '
' +
5 | '
' +
6 | '
<%=title%>
' +
7 | '
' +
8 | ' ' +
9 | '',
10 | defaultOpt: {
11 | type: 'dir',
12 | title: '',
13 | path: '/',
14 | pers: 'wr'
15 | },
16 | init: function (options) {
17 | var me = this;
18 | options.path = Utils.regularDirPath(options.path);
19 | me.root($($.parseTmpl(me.tpl, options)));
20 | var $detail = me.$detail = me.root().children().eq(0);
21 | me.$branch = me.root().children().eq(1);
22 |
23 | /* 设置展开收起文件夹 */
24 | $detail.find('.ufui-leaf-expand').on('click', function () {
25 | if ($detail.hasClass('ufui-leaf-detail-opened')) {
26 | me.expand(false);
27 | } else {
28 | me.expand(true);
29 | }
30 | });
31 |
32 | return me;
33 | },
34 | disabled: function (state) {
35 | if (state === undefined) {
36 | return this.root().hasClass('ufui-disabled');
37 | }
38 | this.root().toggleClass('ufui-disabled', state);
39 | if (this.root().hasClass('ufui-disabled')) {
40 | this.root().removeClass('ufui-hover');
41 | }
42 | return this;
43 | },
44 | active: function (state) {
45 | if (state === undefined) {
46 | return this.root().hasClass('ufui-active');
47 | }
48 | this.root().toggleClass('ufui-active', state);
49 |
50 | return this;
51 | },
52 | expand: function (state) {
53 | if (state) {
54 | this.$detail.removeClass('ufui-leaf-detail-closed').addClass('ufui-leaf-detail-opened');
55 | this.$branch.removeClass('ufui-tree-branch-closed').addClass('ufui-tree-branch-opened');
56 | } else {
57 | this.$detail.removeClass('ufui-leaf-detail-opened').addClass('ufui-leaf-detail-closed');
58 | this.$branch.removeClass('ufui-tree-branch-opened').addClass('ufui-tree-branch-closed');
59 | }
60 | },
61 | _compare: function (a, b) {
62 | var type1 = a.getType(),
63 | type2 = b.getType(),
64 | title1 = a.getTitle(),
65 | title2 = b.getTitle();
66 |
67 | if (type1 == 'dir' && type2 != 'dir') {
68 | return 0;
69 | } else if (type1 != 'dir' && type2 == 'dir') {
70 | return 1;
71 | } else {
72 | return title1 > title2;
73 | }
74 | },
75 | setPath: function (path) {
76 | this.root().attr('data-path', Utils.regularDirPath(path));
77 | return this;
78 | },
79 | getPath: function () {
80 | return this.root().attr('data-path');
81 | },
82 | setType: function (type) {
83 | this.$detail.find('.ufui-leaf-folder i').attr('class', 'ufui-leaf-folder-' + type);
84 | return this;
85 | },
86 | getType: function () {
87 | var c = this.$detail.find('.ufui-leaf-folder i'),
88 | m = c.attr('class').match(/ufui-leaf-folder-([\w]+)(\s|$)/);
89 | return m ? m[1] : null;
90 | },
91 | setTitle: function (title) {
92 | this.$detail.find('.ufui-leaf-title').text(title);
93 | return this;
94 | },
95 | getTitle: function () {
96 | return this.$detail.find('.ufui-leaf-title').text();
97 | },
98 | addChild: function (ufLeaf) {
99 | var children = this.$branch.children();
100 | for (var i = 0; i < children.length; i++) {
101 | if (this._compare($(children[i]).ufui(), ufLeaf)) break;
102 | }
103 | if (i == 0) {
104 | this.$branch.prepend(ufLeaf.root());
105 | } else {
106 | $(children[i - 1]).after(ufLeaf.root());
107 | }
108 | this.expand(true);
109 | return this;
110 | },
111 | removeChild: function ($leaf) {
112 | $leaf.remove();
113 | return this;
114 | },
115 | getChildren: function () {
116 | return this.$branch.children();
117 | }
118 | });
--------------------------------------------------------------------------------
/_src/core/utils.js:
--------------------------------------------------------------------------------
1 | var Utils = UFinder.Utils = {
2 | argsToArray: function (args, index) {
3 | return Array.prototype.slice.call(args, index || 0);
4 | },
5 | regularDirPath: function (path) {
6 | return path.replace(/([^\/])$/, '$1/').replace(/^([^\/])/, '/$1');
7 | },
8 | getParentPath: function (path) {
9 | return path.replace(/[^\/]+\/?$/, '');
10 | },
11 | getPathExt: function (path) {
12 | var index = path.lastIndexOf('.');
13 | return path.substr((index == -1 ? path.length : index) + 1);
14 | },
15 | isImagePath: function (path) {
16 | return path && 'png gif bmp jpg jpeg'.split(' ').indexOf(Utils.getPathExt(path)) != -1;
17 | },
18 | isCodePath: function (path) {
19 | return path && 'txt md json js css html htm xml php asp jsp'.split(' ').indexOf(Utils.getPathExt(path)) != -1;
20 | },
21 | isWebPagePath: function (path) {
22 | return path && 'html php asp jsp'.split(' ').indexOf(Utils.getPathExt(path)) != -1;
23 | },
24 | extend: function (t, s, b) {
25 | if (s) {
26 | for (var k in s) {
27 | if (!b || !t.hasOwnProperty(k)) {
28 | t[k] = s[k];
29 | }
30 | }
31 | }
32 | return t;
33 | },
34 | clone: function (source, target) {
35 | var tmp;
36 | target = target || {};
37 | for (var i in source) {
38 | if (source.hasOwnProperty(i)) {
39 | tmp = source[i];
40 | if (typeof tmp == 'object') {
41 | target[i] = Utils.isArray(tmp) ? [] : {};
42 | Utils.clone(source[i], target[i]);
43 | } else {
44 | target[i] = tmp;
45 | }
46 | }
47 | }
48 | return target;
49 | },
50 | loadFile: (function () {
51 | var tmpList = [];
52 |
53 | function getItem(doc, obj) {
54 | try {
55 | for (var i = 0, ci; ci = tmpList[i++];) {
56 | if (ci.doc === doc && ci.url == (obj.src || obj.href)) {
57 | return ci;
58 | }
59 | }
60 | } catch (e) {
61 | return null;
62 | }
63 |
64 | }
65 |
66 | return function (doc, obj, fn) {
67 | var p, item = getItem(doc, obj);
68 | if (item) {
69 | if (item.ready) {
70 | fn && fn();
71 | } else {
72 | item.funs.push(fn);
73 | }
74 | return;
75 | }
76 | tmpList.push({
77 | doc: doc,
78 | url: obj.src || obj.href,
79 | funs: [fn]
80 | });
81 | if (!doc.body) {
82 | var html = [];
83 | for (p in obj) {
84 | if (p == 'tag')continue;
85 | html.push(p + '="' + obj[p] + '"');
86 | }
87 | doc.write('<' + obj.tag + ' ' + html.join(' ') + ' >' + obj.tag + '>');
88 | return;
89 | }
90 | if (obj.id && doc.getElementById(obj.id)) {
91 | return;
92 | }
93 | var element = doc.createElement(obj.tag);
94 | delete obj.tag;
95 | for (p in obj) {
96 | element.setAttribute(p, obj[p]);
97 | }
98 | element.onload = element.onreadystatechange = function () {
99 | if (!this.readyState || /loaded|complete/.test(this.readyState)) {
100 | item = getItem(doc, obj);
101 | if (item.funs.length > 0) {
102 | item.ready = 1;
103 | for (var fi; fi = item.funs.pop();) {
104 | fi();
105 | }
106 | }
107 | element.onload = element.onreadystatechange = null;
108 | }
109 | };
110 | element.onerror = function () {
111 | throw new Error('The load ' + (obj.href || obj.src) + ' fails,check the url');
112 | };
113 | doc.getElementsByTagName("head")[0].appendChild(element);
114 | };
115 | })()
116 | };
117 |
118 | $.each(['String', 'Function', 'Array', 'Number', 'RegExp', 'Object', 'Boolean'], function (k, v) {
119 | Utils['is' + v] = function (obj) {
120 | return Object.prototype.toString.apply(obj) == '[object ' + v + ']';
121 | };
122 | });
--------------------------------------------------------------------------------
/_src/core/proxy.js:
--------------------------------------------------------------------------------
1 | var Proxy = UF.Proxy = UF.createClass("Proxy", {
2 | constructor: function (finder) {
3 | this.finder = finder;
4 | this._queue = [];
5 | this.active = false;
6 | this.nextSendIndex = 0;
7 | this._url = finder.getOption('serverUrl');
8 | },
9 | 'init': function (callback) {
10 | return this._get({
11 | 'cmd': 'init'
12 | }, callback);
13 | },
14 | getRequestUrl: function (options) {
15 | var url = this._url + '?';
16 | $.each(options || {}, function (k, v) {
17 | url += (k + '=' + v + '&');
18 | });
19 | if (url.charAt(url.length - 1) == '&') url = url.substr(0, url.length - 1);
20 | if (url.charAt(url.length - 1) == '?') url = url.substr(0, url.length - 1);
21 | return url;
22 | },
23 | 'ls': function (target, callback) {
24 | return this._get({
25 | 'cmd': 'ls',
26 | 'target': target
27 | }, callback);
28 | },
29 | 'rename': function (target, name, callback) {
30 | return this._get({
31 | 'cmd': 'rename',
32 | 'target': target,
33 | 'name': name
34 | }, callback);
35 | },
36 | 'touch': function (target, callback) {
37 | return this._get({
38 | 'cmd': 'touch',
39 | 'target': target
40 | }, callback);
41 | },
42 | 'mkdir': function (target, callback) {
43 | return this._get({
44 | 'cmd': 'mkdir',
45 | 'target': target
46 | }, callback);
47 | },
48 | 'rm': function (target, callback) {
49 | return this._get({
50 | 'cmd': 'rm',
51 | 'target': target
52 | }, callback);
53 | },
54 | upload: function (target, file, callback) {
55 | return this._upload({
56 | 'cmd': 'upload',
57 | 'target': target,
58 | 'file': file
59 | }, callback, file);
60 | },
61 | info: function (target, callback) {
62 | return this._get({
63 | 'cmd': 'info',
64 | 'target': target
65 | }, callback);
66 | },
67 | _get: function (data, callback) {
68 | return this._ajax('GET', data, callback);
69 | },
70 | _post: function (data, callback) {
71 | return this._ajax('POST', data, callback);
72 | },
73 | _upload: function (data, callback) {
74 | return this._ajax('UPLOAD', data, callback);
75 | },
76 | _ajax: function (type, data, callback) {
77 | var me = this,
78 | request,
79 | handler = function (d) {
80 | me._beforeRequestComplete(d, request);
81 | callback && callback(d, request);
82 | me._afterRequestComplete(d, request);
83 | };
84 |
85 | if (type == 'UPLOAD') {
86 | request = new Uploader({
87 | url: me._url,
88 | type: type,
89 | webuploader: me.finder.webuploader,
90 | data: data,
91 | process: function (p) {
92 | me.finder.fire('updatemessage', {
93 | loadedPercent: p,
94 | request: request,
95 | id: request.id
96 | });
97 | }
98 | }, handler);
99 | } else {
100 | request = new Request({
101 | url: me._url,
102 | type: type,
103 | data: data
104 | }, handler);
105 | }
106 |
107 | me._pushRequest(request);
108 | me.finder.fire('showmessage', {
109 | icon: 'loading',
110 | title: data.cmd + ' loading...',
111 | loadedPercent: 100,
112 | request: request,
113 | id: request.id
114 | });
115 |
116 | return request;
117 | },
118 | _pushRequest: function (request) {
119 | this._queue.push(request);
120 | this._sendRequest();
121 | },
122 | _sendRequest: function () {
123 | if (!this.active && this.nextSendIndex < this._queue.length) {
124 | this.active = true;
125 | this._queue[this.nextSendIndex++].send();
126 | }
127 | },
128 | _beforeRequestComplete: function (d, request) {
129 | this.finder.fire('beforeRequestComplete', d, request);
130 | this.finder.fire('hidemessage', {id: request.id});
131 | this.active = false;
132 | this._sendRequest();
133 | },
134 | _afterRequestComplete: function (d, request) {
135 | this.finder.fire('afterRequestComplete', d, request);
136 | }
137 | });
--------------------------------------------------------------------------------
/_spec/mergeCoverageForistanbul.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by dongyancen on 14-3-26.
3 | */
4 | var fs = require('fs');
5 | var browsers = ['Chrome', 'Firefox', 'PhantomJS', 'IE'];
6 | var result_forBrowser = {};
7 | var jsonFileBasePath = './coverage/json_files/';
8 | var jsonFiles = fs.readdirSync(jsonFileBasePath);
9 | var finalJsonFile = 'defaultFileName';
10 | var curPath = '/_spec';
11 | var resultPath = '.';
12 |
13 | //找出所有的json文件
14 | for (var i = 0; i < jsonFiles.length; i++) {
15 | // json文件名必须是有8位的日期和6位的时间戳如:-20140326_161249
16 | if (!isJsonFiles(jsonFiles[i])) {
17 | jsonFiles.splice(i, 1);
18 | i--;
19 | }
20 | }
21 | //没有找到合适的文件
22 | if(jsonFiles.length==0)return;
23 |
24 | //先排序 按时间从小到大 及从旧到新
25 | jsonFiles.sort(function (f1, f2) {
26 | var t1 = getFileTime(f1);//形如['-20140326_161249','20140326','161249']
27 | var t2 = getFileTime(f2);
28 | var dateDiff = parseInt(t1[1]) - parseInt(t2[1]);
29 | if (dateDiff != 0)return dateDiff;
30 | else return parseInt(t1[2]) - parseInt(t2[2]);
31 | });
32 | //以时间命名新的文件
33 | finalJsonFile = getFileTime(jsonFiles[jsonFiles.length-1])[0].substring(1);
34 | //如:20140326_161249
35 |
36 | //取最新的
37 | // 按浏览器类型分类 result_forBrowser属性形如:{'Crome':'filename1','Firefox':'filename2'}
38 | for (i = 0; i < jsonFiles.length; i++) {
39 | for (var j = 0; j < browsers.length; j++) {
40 | if (eval('/' + browsers[j] + '/.test("' + jsonFiles[i] + '");')) {
41 | eval('result_forBrowser.' + browsers[j] + '="' + jsonFiles[i] + '";');
42 | }
43 | }
44 | }
45 |
46 | //以上得到所有要合计的json文件
47 | //读取,合计数字,需要合计的属性: 's' 'b' 'f' 'l'
48 | //修正路径
49 | var jsonToWrite = null;
50 | for (var a in result_forBrowser) {
51 | var r = fs.readFileSync(jsonFileBasePath + result_forBrowser[a]);
52 | if (!jsonToWrite) {
53 | jsonToWrite = JSON.parse(r);
54 | continue;
55 | } else {
56 | jsonToWrite = mergeResult(jsonToWrite, JSON.parse(r));
57 | }
58 | }
59 |
60 |
61 | //写文件
62 | fs.writeFileSync(jsonFileBasePath+finalJsonFile+'.json',JSON.stringify(jsonToWrite));
63 |
64 | function isJsonFiles(fileName) {
65 | var e = fileName.substring(fileName.lastIndexOf(".") + 1);
66 | // json文件名必须是有8位的日期和6位的时间戳如:-20140326_161249
67 | //否则无法判断文件生成时间,也就无法合并同一次运行产生的结果
68 | return e == 'json' && getFileTime(fileName);
69 | }
70 | function getFileTime(fileName) {
71 | // json文件名必须是有8位的日期和6位的时间戳如:-20140326_161249
72 | return fileName.match(/-(\d{8})_(\d{6})/);
73 | }
74 | function mergeResult(allR, addR) {
75 | var resultR = {};
76 | for (var allRKey in allR) {
77 |
78 | if (addR[allRKey]) {
79 |
80 | allR[allRKey] = mergeDetail(allR[allRKey], addR[allRKey], 's', 1);
81 | allR[allRKey] = mergeDetail(allR[allRKey], addR[allRKey], 'f', 1);
82 | allR[allRKey] = mergeDetail(allR[allRKey], addR[allRKey], 'l', 1);
83 | allR[allRKey] = mergeDetail(allR[allRKey], addR[allRKey], 'b', 2);
84 | }
85 | //修正路径
86 | resultR[fixPath(allRKey)] = allR[allRKey]
87 | }
88 | return resultR;
89 | }
90 | //type = 1 合并 s f l ,如:{"1":1,"2":1,"3":1}
91 | //type = 2 合并 b ,如:{"1":[0,0],"2":[0,0]}
92 | function mergeDetail(allEle, addEle, attrName, type) {
93 |
94 | if (allEle[attrName] && addEle[attrName]) {
95 | if (type == 1) {
96 | for (var k in allEle[attrName]) {
97 | //todo 现在没有考虑两个文件中同一项覆盖率的统计行数不一致的问题
98 | if ( parseInt(allEle[attrName][k])==0 && parseInt(addEle[attrName][k]) ==1) {
99 | allEle[attrName][k] = 1;
100 | }
101 | }
102 | }
103 | else if (type == 2) {
104 | for (var k in allEle[attrName]) {
105 | //todo 现在没有考虑两个文件中同一项覆盖率的统计行数不一致的问题
106 | if (addEle[attrName][k]) {
107 | if (parseInt(allEle[attrName][k][0])==0 &&parseInt(addEle[attrName][k][0])==1 ) {
108 | allEle[attrName][k][0] = 1;
109 | }
110 | if (parseInt(allEle[attrName][k][1])==0 &&parseInt(addEle[attrName][k][1])==1 ) {
111 | allEle[attrName][k][1] = 1;
112 | }
113 | }
114 | }
115 | }
116 | }
117 | return allEle;
118 | }
119 | //修正路径
120 | function fixPath(oldPath){
121 | //例如把 "D:/workspace/ufinder/_src/core/finder.js" 修正为
122 | // ./_src/core/finder.js 注意这里一定要用相对路径(相对于_spec/coverage)
123 | var s = __dirname.replace(/\\/g,'/');
124 | if(s.lastIndexOf(curPath)){
125 | s = s.substring(0,s.lastIndexOf(curPath) );
126 | }
127 | oldPath = oldPath.replace(s,resultPath);
128 | return oldPath;
129 | }
130 | console.log(finalJsonFile);
--------------------------------------------------------------------------------
/themes/css/file.css:
--------------------------------------------------------------------------------
1 | .ufui-file{
2 | display: block;
3 | float: left;
4 | width: 90px;
5 | height: 90px;
6 | margin: 10px 0 0 10px;
7 | padding: 2px;
8 | list-style: none;
9 | overflow: hidden;
10 | }
11 | .ufui-file.ufui-active{
12 | border: 2px solid #2e80dc;
13 | padding: 0;
14 | }
15 | .ufui-container.ufui-disabled .ufui-file.ufui-active{
16 | border: 2px solid #cccccc;
17 | }
18 | .ufui-file.ufui-disabled .ufui-file-icon,
19 | .ufui-file.ufui-disabled .ufui-file-icon{
20 | opacity: .35;
21 | filter: alpha(opacity=35);
22 | background-image: none;
23 | }
24 | .ufui-file-icon {
25 | width: 70px;
26 | height: 70px;
27 | margin: 0 auto 0 auto;
28 | overflow: hidden;
29 | }
30 | .ufui-file-icon i{
31 | display: block;
32 | width: 100%;
33 | height: 100%;
34 | }
35 |
36 | .ufui-file-title{
37 | padding: 0;
38 | margin: 3px 0 0 0;
39 | font-size: 12px;
40 | height: 13px;
41 | color: #555555;
42 | text-align: center;
43 | width: 90px;
44 | white-space:nowrap;
45 | word-break:keep-all;
46 | overflow:hidden;
47 | text-overflow:ellipsis;
48 | }
49 | .ufui-file-title.ufui-file-title-editable{
50 | margin: 3px 4px 0 4px;
51 | width: 82px;
52 | overflow:hidden;
53 | text-overflow: clip;
54 | }
55 |
56 | .ufui-file-pers{
57 | }
58 | .ufui-file-nwr .ufui-file-pers{
59 | float: right;
60 | margin: -16px 0 0 0;
61 | width: 16px;
62 | height: 16px;
63 | background-image: url("../images/icons.png");
64 | background-position: 0 -64px;
65 | }
66 | .ufui-file-wnr .ufui-file-pers,
67 | .ufui-file-nwnr .ufui-file-pers{
68 | float: right;
69 | margin: -16px 0 0 0;
70 | width: 16px;
71 | height: 16px;
72 | background-image: url("../images/icons.png");
73 | background-position: 0 -96px;
74 | }
75 |
76 | /* filetype style */
77 | .ufui-file-icon i{
78 | background-image: url("../images/file-icons.png");
79 | background-position: -140px center;
80 | }
81 | .ufui-file-icon .ufui-file-icon-dir{
82 | background-position: 0 center;
83 | }
84 | .ufui-file-icon .ufui-file-icon-zip{
85 | background-position: -70px center;
86 | }
87 | .ufui-file-icon .ufui-file-icon-file{
88 | background-position: -140px center;
89 | }
90 | .ufui-file-icon .ufui-file-icon-filelist{
91 | background-position: -210px center;
92 | }
93 | .ufui-file-icon .ufui-file-icon-rar,
94 | .ufui-file-icon .ufui-file-icon-7z,
95 | .ufui-file-icon .ufui-file-icon-tar,
96 | .ufui-file-icon .ufui-file-icon-gz{
97 | background-position: -280px center;
98 | }
99 | .ufui-file-icon .ufui-file-icon-xls,
100 | .ufui-file-icon .ufui-file-icon-xlsx{
101 | background-position: -350px center;
102 | }
103 | .ufui-file-icon .ufui-file-icon-doc,
104 | .ufui-file-icon .ufui-file-icon-docx{
105 | background-position: -420px center;
106 | }
107 | .ufui-file-icon .ufui-file-icon-ppt,
108 | .ufui-file-icon .ufui-file-icon-pptx{
109 | background-position: -490px center;
110 | }
111 | .ufui-file-icon .ufui-file-icon-vsd{
112 | background-position: -560px center;
113 | }
114 | .ufui-file-icon .ufui-file-icon-pdf{
115 | background-position: -630px center;
116 | }
117 | .ufui-file-icon .ufui-file-icon-txt,
118 | .ufui-file-icon .ufui-file-icon-md,
119 | .ufui-file-icon .ufui-file-icon-json,
120 | .ufui-file-icon .ufui-file-icon-htm,
121 | .ufui-file-icon .ufui-file-icon-xml,
122 | .ufui-file-icon .ufui-file-icon-html,
123 | .ufui-file-icon .ufui-file-icon-js,
124 | .ufui-file-icon .ufui-file-icon-css,
125 | .ufui-file-icon .ufui-file-icon-php,
126 | .ufui-file-icon .ufui-file-icon-jsp,
127 | .ufui-file-icon .ufui-file-icon-asp{
128 | background-position: -700px center;
129 | }
130 | .ufui-file-icon .ufui-file-icon-apk{
131 | background-position: -770px center;
132 | }
133 | .ufui-file-icon .ufui-file-icon-exe{
134 | background-position: -840px center;
135 | }
136 | .ufui-file-icon .ufui-file-icon-ipa{
137 | background-position: -910px center;
138 | }
139 | .ufui-file-icon .ufui-file-icon-mp4,
140 | .ufui-file-icon .ufui-file-icon-mov,
141 | .ufui-file-icon .ufui-file-icon-mpeg,
142 | .ufui-file-icon .ufui-file-icon-rm,
143 | .ufui-file-icon .ufui-file-icon-rmvb{
144 | background-position: -980px center;
145 | }
146 | .ufui-file-icon .ufui-file-icon-wav,
147 | .ufui-file-icon .ufui-file-icon-wmv,
148 | .ufui-file-icon .ufui-file-icon-mid,
149 | .ufui-file-icon .ufui-file-icon-mp3{
150 | background-position: -1050px center;
151 | }
152 | .ufui-file-icon .ufui-file-icon-jpg,
153 | .ufui-file-icon .ufui-file-icon-jpeg,
154 | .ufui-file-icon .ufui-file-icon-gif,
155 | .ufui-file-icon .ufui-file-icon-bmp,
156 | .ufui-file-icon .ufui-file-icon-png,
157 | .ufui-file-icon .ufui-file-icon-psd{
158 | background-position: -140px center;
159 | }
--------------------------------------------------------------------------------
/dist/themes/css/file.css:
--------------------------------------------------------------------------------
1 | .ufui-file{
2 | display: block;
3 | float: left;
4 | width: 90px;
5 | height: 90px;
6 | margin: 10px 0 0 10px;
7 | padding: 2px;
8 | list-style: none;
9 | overflow: hidden;
10 | }
11 | .ufui-file.ufui-active{
12 | border: 2px solid #2e80dc;
13 | padding: 0;
14 | }
15 | .ufui-container.ufui-disabled .ufui-file.ufui-active{
16 | border: 2px solid #cccccc;
17 | }
18 | .ufui-file.ufui-disabled .ufui-file-icon,
19 | .ufui-file.ufui-disabled .ufui-file-icon{
20 | opacity: .35;
21 | filter: alpha(opacity=35);
22 | background-image: none;
23 | }
24 | .ufui-file-icon {
25 | width: 70px;
26 | height: 70px;
27 | margin: 0 auto 0 auto;
28 | overflow: hidden;
29 | }
30 | .ufui-file-icon i{
31 | display: block;
32 | width: 100%;
33 | height: 100%;
34 | }
35 |
36 | .ufui-file-title{
37 | padding: 0;
38 | margin: 3px 0 0 0;
39 | font-size: 12px;
40 | height: 13px;
41 | color: #555555;
42 | text-align: center;
43 | width: 90px;
44 | white-space:nowrap;
45 | word-break:keep-all;
46 | overflow:hidden;
47 | text-overflow:ellipsis;
48 | }
49 | .ufui-file-title.ufui-file-title-editable{
50 | margin: 3px 4px 0 4px;
51 | width: 82px;
52 | overflow:hidden;
53 | text-overflow: clip;
54 | }
55 |
56 | .ufui-file-pers{
57 | }
58 | .ufui-file-nwr .ufui-file-pers{
59 | float: right;
60 | margin: -16px 0 0 0;
61 | width: 16px;
62 | height: 16px;
63 | background-image: url("../images/icons.png");
64 | background-position: 0 -64px;
65 | }
66 | .ufui-file-wnr .ufui-file-pers,
67 | .ufui-file-nwnr .ufui-file-pers{
68 | float: right;
69 | margin: -16px 0 0 0;
70 | width: 16px;
71 | height: 16px;
72 | background-image: url("../images/icons.png");
73 | background-position: 0 -96px;
74 | }
75 |
76 | /* filetype style */
77 | .ufui-file-icon i{
78 | background-image: url("../images/file-icons.png");
79 | background-position: -140px center;
80 | }
81 | .ufui-file-icon .ufui-file-icon-dir{
82 | background-position: 0 center;
83 | }
84 | .ufui-file-icon .ufui-file-icon-zip{
85 | background-position: -70px center;
86 | }
87 | .ufui-file-icon .ufui-file-icon-file{
88 | background-position: -140px center;
89 | }
90 | .ufui-file-icon .ufui-file-icon-filelist{
91 | background-position: -210px center;
92 | }
93 | .ufui-file-icon .ufui-file-icon-rar,
94 | .ufui-file-icon .ufui-file-icon-7z,
95 | .ufui-file-icon .ufui-file-icon-tar,
96 | .ufui-file-icon .ufui-file-icon-gz{
97 | background-position: -280px center;
98 | }
99 | .ufui-file-icon .ufui-file-icon-xls,
100 | .ufui-file-icon .ufui-file-icon-xlsx{
101 | background-position: -350px center;
102 | }
103 | .ufui-file-icon .ufui-file-icon-doc,
104 | .ufui-file-icon .ufui-file-icon-docx{
105 | background-position: -420px center;
106 | }
107 | .ufui-file-icon .ufui-file-icon-ppt,
108 | .ufui-file-icon .ufui-file-icon-pptx{
109 | background-position: -490px center;
110 | }
111 | .ufui-file-icon .ufui-file-icon-vsd{
112 | background-position: -560px center;
113 | }
114 | .ufui-file-icon .ufui-file-icon-pdf{
115 | background-position: -630px center;
116 | }
117 | .ufui-file-icon .ufui-file-icon-txt,
118 | .ufui-file-icon .ufui-file-icon-md,
119 | .ufui-file-icon .ufui-file-icon-json,
120 | .ufui-file-icon .ufui-file-icon-htm,
121 | .ufui-file-icon .ufui-file-icon-xml,
122 | .ufui-file-icon .ufui-file-icon-html,
123 | .ufui-file-icon .ufui-file-icon-js,
124 | .ufui-file-icon .ufui-file-icon-css,
125 | .ufui-file-icon .ufui-file-icon-php,
126 | .ufui-file-icon .ufui-file-icon-jsp,
127 | .ufui-file-icon .ufui-file-icon-asp{
128 | background-position: -700px center;
129 | }
130 | .ufui-file-icon .ufui-file-icon-apk{
131 | background-position: -770px center;
132 | }
133 | .ufui-file-icon .ufui-file-icon-exe{
134 | background-position: -840px center;
135 | }
136 | .ufui-file-icon .ufui-file-icon-ipa{
137 | background-position: -910px center;
138 | }
139 | .ufui-file-icon .ufui-file-icon-mp4,
140 | .ufui-file-icon .ufui-file-icon-mov,
141 | .ufui-file-icon .ufui-file-icon-mpeg,
142 | .ufui-file-icon .ufui-file-icon-rm,
143 | .ufui-file-icon .ufui-file-icon-rmvb{
144 | background-position: -980px center;
145 | }
146 | .ufui-file-icon .ufui-file-icon-wav,
147 | .ufui-file-icon .ufui-file-icon-wmv,
148 | .ufui-file-icon .ufui-file-icon-mid,
149 | .ufui-file-icon .ufui-file-icon-mp3{
150 | background-position: -1050px center;
151 | }
152 | .ufui-file-icon .ufui-file-icon-jpg,
153 | .ufui-file-icon .ufui-file-icon-jpeg,
154 | .ufui-file-icon .ufui-file-icon-gif,
155 | .ufui-file-icon .ufui-file-icon-bmp,
156 | .ufui-file-icon .ufui-file-icon-png,
157 | .ufui-file-icon .ufui-file-icon-psd{
158 | background-position: -140px center;
159 | }
--------------------------------------------------------------------------------
/_src/core/finder.event.js:
--------------------------------------------------------------------------------
1 | UF.extendClass(Finder, {
2 | _initEvents: function () {
3 | this._eventCallbacks = {};
4 | },
5 | _initDomEvent: function () {
6 | var me = this,
7 | $container = me.$container,
8 | $keyListener = $('');
9 |
10 | $container.append($('').append($keyListener));
11 | me._proxyDomEvent = $.proxy(me._proxyDomEvent, me);
12 |
13 | /* 点击事件触发隐藏域聚焦,用于捕获键盘事件 */
14 | me._initKeyListener($container, $keyListener);
15 |
16 | /* 键盘事件 */
17 | $(document).on('keydown keyup keypress', me._proxyDomEvent);
18 |
19 | /* 鼠标事件 */
20 | $container.on('click mousedown mouseup mousemove mouseover mouseout contextmenu selectstart', me._proxyDomEvent);
21 |
22 | },
23 | _proxyDomEvent: function (evt) {
24 | var me = this;
25 | if (evt.originalEvent) {
26 | var $target = $(evt.originalEvent.target);
27 | /* 同时触发 tree.click 等事件 */
28 | $.each(['tree', 'list', 'toolbar'], function (k, p) {
29 | if ($target[0] == me['$' + p][0] || $target.parents('.ufui-' + p)[0] == me['$' + p][0]) {
30 | me.fire(p + '.' + evt.type.replace(/^on/, ''), evt);
31 | }
32 | });
33 | }
34 | return this.fire(evt.type.replace(/^on/, ''), evt);
35 | },
36 | _initKeyListener: function ($container, $keyListener) {
37 | var me = this;
38 | /* 点击让ufinder获得焦点,帮助获取键盘事件 */
39 | $container.on('click', function (evt) {
40 | var target = evt.target;
41 | if (target.tagName != 'INPUT' && target.tagName != 'TEXTAREA' &&
42 | target.contentEditable != true) {
43 | // console.log('ufinder focus');
44 | $keyListener.focus();
45 | me.isFocused == false && me.setFocus();
46 | }
47 | });
48 | /* 点击document除掉当前ufinder的位置,让ufinder失去焦点 */
49 | $(document).on('click', function (evt) {
50 | /* 忽略代码触发的点击事件 */
51 | if (evt.originalEvent) {
52 | var $ufContainer = $(evt.originalEvent.target).parents('.ufui-container');
53 | if ($ufContainer[0] != $container[0]) {
54 | $keyListener.blur();
55 | me.isFocused == true && me.setBlur();
56 | }
57 | }
58 | });
59 | me.on('afterexeccommand', function (type, cmd) {
60 | if (['rename', 'touch', 'mkdir'].indexOf(cmd) == -1) {
61 | $keyListener.focus();
62 | }
63 | });
64 | },
65 | setFocus: function () {
66 | this.isFocused = true;
67 | this.fire('focus');
68 | },
69 | setBlur: function () {
70 | this.isFocused = false;
71 | this.fire('blur');
72 | },
73 | _listen: function (type, callback) {
74 | var callbacks = this._eventCallbacks[type] || ( this._eventCallbacks[type] = [] );
75 | callbacks.push(callback);
76 | },
77 | on: function (name, callback) {
78 | var types = name.split(' ');
79 | for (var i = 0; i < types.length; i++) {
80 | this._listen(types[i].toLowerCase(), callback);
81 | }
82 | return this;
83 | },
84 | one: function (name, callback) {
85 | var me = this,
86 | handler = function () {
87 | callback();
88 | me.off(name, handler);
89 | };
90 |
91 | me.on(name, handler);
92 | return this;
93 | },
94 | off: function (name, callback) {
95 | var types = name.split(' ');
96 | var i, j, callbacks, removeIndex;
97 | for (i = 0; i < types.length; i++) {
98 | callbacks = this._eventCallbacks[types[i].toLowerCase()];
99 | if (callbacks) {
100 | removeIndex = null;
101 | for (j = 0; j < callbacks.length; j++) {
102 | if (callbacks[j] == callback) {
103 | removeIndex = j;
104 | }
105 | }
106 | if (removeIndex !== null) {
107 | callbacks.splice(removeIndex, 1);
108 | }
109 | }
110 | }
111 | },
112 | fire: function (type) {
113 | var callbacks = this._eventCallbacks[type.toLowerCase()];
114 | if (!callbacks) {
115 | return;
116 | }
117 | for (var i = 0; i < callbacks.length; i++) {
118 | var res = callbacks[i].apply(this, arguments);
119 | if (res == false) {
120 | break;
121 | }
122 | }
123 | return res;
124 | }
125 | });
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | /*-----------------------------------------------------
2 | * livereload Default Setting
3 | *-----------------------------------------------------*/
4 | 'use strict';
5 | var path = require('path');
6 | var lrSnippet = require('grunt-contrib-livereload/lib/utils').livereloadSnippet;
7 |
8 | /*-----------------------------------------------------
9 | * Module Setting
10 | *-----------------------------------------------------*/
11 | module.exports = function (grunt) {
12 |
13 | var banner = '/*!\n' +
14 | ' * ====================================================\n' +
15 | ' * <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' +
16 | '<%= grunt.template.today("yyyy-mm-dd") %>\n' +
17 | '<%= pkg.homepage ? " * " + pkg.homepage + "\\n" : "" %>' +
18 | ' * GitHub: <%= pkg.repository.url %> \n' +
19 | ' * Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
20 | ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %>\n' +
21 | ' * ====================================================\n' +
22 | ' */\n\n',
23 | buildPath = 'index.html',
24 | srcDir = '_src/',
25 | distDir = 'dist/',
26 | serverPort = 9001,
27 | livereloadPort = 35729;
28 |
29 | var getPath = function ( readFile, srcDir) {
30 | var sources = require("fs").readFileSync(readFile);
31 | sources = /filelist = \[([^)]+)\]/.exec( sources );
32 | sources = sources[1].replace( /\/\/.*\n/g, '\n' ).replace( /'|"|\n|\t|\s/g, '' );
33 | sources = sources.split( "," );
34 | sources.forEach( function ( filepath, index ) {
35 | sources[ index ] = srcDir + filepath;
36 | });
37 | return sources;
38 | };
39 |
40 | // Project configuration.
41 | grunt.initConfig({
42 |
43 | // Metadata.
44 | pkg: grunt.file.readJSON('package.json'),
45 |
46 | concat: {
47 |
48 | js: {
49 | options: {
50 | banner: banner + '(function($, window) {\n\n',
51 | footer: '\n\n})(jQuery, window);\n',
52 | process: function(src, filepath) {
53 | return src + "\n";
54 | }
55 | },
56 | src: getPath( buildPath, srcDir ),
57 | dest: distDir + 'ufinder.js'
58 | }
59 |
60 | },
61 |
62 | uglify: {
63 | minimize: {
64 | files: (function (){
65 | var o = {};
66 | o[distDir + 'ufinder.min.js'] = distDir + 'ufinder.js';
67 | return o;
68 | })()
69 | }
70 | },
71 |
72 | copy: {
73 | base: {
74 | files: [
75 | {
76 | src: ['dialogs/**', 'lang/**', 'lib/**', 'server/**', 'themes/**'],
77 | dest: distDir
78 | }
79 | ]
80 | }
81 | },
82 |
83 | /* Start [Task liverload] ------------------------------------*/
84 | livereload: {
85 | port: livereloadPort // Default livereload listening port.
86 | },
87 | connect: {
88 | livereload: {
89 | options: {
90 | hostname: '*',
91 | port: serverPort,
92 | base: '.',
93 | middleware: function(connect, options, middlewares) {
94 | return [
95 | lrSnippet,
96 | connect.static(options.base.toString()),
97 | connect.directory(options.base.toString())
98 | ]
99 | }
100 | }
101 | }
102 | },
103 | regarde: {
104 | js:{
105 | files: srcDir + '**/*.js',
106 | tasks: ['default', 'livereload']
107 | }
108 | }
109 | /* End [Task liverload] ------------------------------------*/
110 |
111 | });
112 |
113 | // These plugins provide necessary tasks.
114 | /* [Build plugin & task ] ------------------------------------*/
115 | grunt.loadNpmTasks('grunt-contrib-concat');
116 | grunt.loadNpmTasks('grunt-contrib-uglify');
117 | grunt.loadNpmTasks('grunt-contrib-copy');
118 | // Build task(s).
119 | grunt.registerTask( 'default', [ 'concat:js', 'uglify:minimize', 'copy' ] );
120 |
121 | /* [liverload plugin & task ] ------------------------------------*/
122 | grunt.loadNpmTasks('grunt-regarde');
123 | grunt.loadNpmTasks('grunt-contrib-connect');
124 | grunt.loadNpmTasks('grunt-contrib-livereload');
125 | grunt.registerTask('live', ['livereload-start', 'connect', 'regarde']);
126 |
127 | };
128 |
--------------------------------------------------------------------------------