Beispiel #1
0
                it('only wait the last action', function (done) {
                    var p1 = extend({}, require('mock/foo'));
                    var p2 = extend({}, require('mock/foo'));
                    var p3 = extend({}, require('mock/foo'));
                    p1.events = {
                        enter: jasmine.createSpy('p1')
                    };
                    p2.events = {
                        enter: jasmine.createSpy('p2')
                    };
                    p3.events = {
                        enter: jasmine.createSpy('p3')
                    };
                    firework.load({path: '/foo', action: p1});
                    firework.load({path: '/boo', action: p2});
                    firework.load({path: '/new', action: p3});

                    router.redirect('/foo');
                    router.redirect('/boo');
                    router.redirect('/new');

                    expect(p1.events.enter).not.toHaveBeenCalled();
                    expect(p2.events.enter).not.toHaveBeenCalled();
                    expect(p3.events.enter).not.toHaveBeenCalled();

                    setTimeout(function () {
                        expect(p1.events.enter).toHaveBeenCalled();
                        expect(p2.events.enter).not.toHaveBeenCalled();
                        expect(p3.events.enter).toHaveBeenCalled();
                        finish(done);
                    }, WAITE_TIME);
                });
Beispiel #2
0
                it('timeout', function (done) {
                    var p1 = extend({}, require('mock/foo'));
                    p1.model = extend({}, require('mock/fooModel'));
                    p1.model.fetch = function () {
                        var resolver = new Resolver();
                        setTimeout(function () {
                            resolver.resolve();
                        }, 1300);
                        return resolver.promise();
                    };
                    var p2 = extend({}, require('mock/foo'));
                    p2.events = {
                        enter: jasmine.createSpy('p2')
                    };

                    firework.load({path: '/foo', action: p1});
                    firework.load({path: '/boo', action: p2});

                    router.redirect('/foo');

                    setTimeout(function () {
                        router.redirect('/boo');
                        setTimeout(function () {
                            expect(p2.events.enter).toHaveBeenCalled();
                            finish(done);
                        }, WAITE_TIME);
                    }, 1100);

                });
Beispiel #3
0
            it('wait other action', function (done) {
                var p1 = extend({}, require('page/src/foo'));
                var p2 = extend({}, require('page/src/foo'));
                p1.events = {
                    ready: jasmine.createSpy('p11')
                };
                p2.events = {
                    ready: jasmine.createSpy('p12')
                };
                firework.load({path: '/test/page/foo1.html', action: p1});
                firework.load({path: '/test/page/foo2.html', action: p2});

                router.redirect('/test/page/foo1.html');
                router.redirect('/test/page/foo2.html');

                expect(p1.events.ready).not.toHaveBeenCalled();
                expect(p2.events.ready).not.toHaveBeenCalled();

                setTimeout(function () {
                    expect(p1.events.ready).toHaveBeenCalled();
                    expect(p2.events.ready).toHaveBeenCalled();

                    expect(main.innerHTML.trim().replace(/\s+<\/div>/g, '<\/div>'))
                        .toEqual('<div class="foo"><div>foo2</div></div>');

                    done();
                }, WAITE_TIME * 10);
            });
Beispiel #4
0
                it('check action events with error & cache', function (done) {
                    var errorModel = extend({}, require('mock/errorModel'));
                    errorModel.fetch = function (query) {
                        if (!query.type) {
                            return Resolver.rejected();
                        }
                        else {
                            return Resolver.resolved();
                        }
                    };
                    var events = [];
                    var errorAction = extend({}, require('mock/error'));
                    errorAction.model = errorModel;
                    errorAction.events = {
                        init: function () {
                            events.push('init');
                        },
                        enter: function () {
                            events.push('enter');
                        },
                        ready: function () {
                            events.push('ready');
                        },
                        complete: function () {
                            events.push('complete');
                        },
                        sleep: function () {
                            events.push('sleep');
                        },
                        wakeup: function () {
                            events.push('wakeup');
                        },
                        leave: function () {
                            events.push('leave');
                        }
                    };

                    firework.load({path: '/error', action: errorAction});

                    router.redirect('/error~type=test');
                    setTimeout(function () {
                        router.redirect('/error');
                        setTimeout(function () {
                            expect(main.innerHTML).toEqual('<div></div>');
                            expect(events).toEqual(['init', 'enter', 'ready', 'complete', 'leave', 'init', 'enter']);
                            finish(done)
                        }, WAITE_TIME);
                    }, WAITE_TIME);
                });
Beispiel #5
0
    function Action(options) {
        options = options || {};
        extend(events, options.events || {});
        options.events = events;

        BaseAction.call(this, options);
    }
Beispiel #6
0
                it('with the same path', function (done) {
                    var config = extend({}, require('mock/foo'));
                    config.events = {
                        enter: jasmine.createSpy()
                    };
                    firework.load({path: '/foo', action: config});

                    router.redirect('/foo');

                    setTimeout(function () {
                        expect(config.events.enter.calls.count()).toBe(1);
                        router.redirect('/foo');
                        setTimeout(function () {
                            expect(config.events.enter.calls.count()).toBe(1);
                            router.redirect('/foo~type=test');
                            setTimeout(function () {
                                expect(config.events.enter.calls.count()).toBe(2);
                                router.redirect('/foo~type=test', null, {force: true});
                                setTimeout(function () {
                                    expect(config.events.enter.calls.count()).toBe(3);
                                    finish(done);
                                }, WAITE_TIME);
                            }, WAITE_TIME);
                        }, WAITE_TIME);
                    }, WAITE_TIME);
                });
Beispiel #7
0
    Animation.prototype.run = function () {
        var ele = this._main;
        var action = extend({}, this._action);

        if (Object.keys(action).length <= 0) {
            return this;
        }

        var options = this._options;

        this.reset();
        this._promise = this._promise.then(function () {
            var item;

            Object.keys(action).forEach(function (key) {
                item = action[key];
                // 如果动作是一个function
                // 则将其执行后的返回结果作为动作
                if (typeof item == 'function') {
                    item = item(ele) || {};
                    delete action[key];
                    setAction(item, action);
                }
            });

            return runner.transition(ele, action, options);
        });

        return this;
    };
Beispiel #8
0
    function View(options) {
        options = options || {};
        extend(domEvents, options.domEvents || {});
        options.domEvents = domEvents;

        BaseView.call(this, options);
    }
Beispiel #9
0
define(function (require) {

    var extend = require('saber-lang/extend');
    var Animation = require('./Animation');

    var exports = {};

    extend(exports, require('./transition'));
    extend(exports, require('./util'));

    exports.animation = function (ele, options) {
        return new Animation(ele, options);
    };

    return exports;
});
 function fireEvent(ele, type, proto) {
     var e = document.createEvent('Event');
     e.initEvent(type, true, true);
     if (proto) {
         extend(e, proto);
     }
     ele.dispatchEvent(e);
 }
Beispiel #11
0
        initOptions: function ( options ) {
            this.options = extend( {}, this.options, options );

            if ( this.target.is( 'render' ) ) {
                this.render();
            }
            else {
                this.target.once( 'afterrender', bind( this.render, this ) );
            }
        },
Beispiel #12
0
    /**
     * @constructor
     * @param {string} url
     * @param {Object} queryInfo 查询条件
     * @param {number} queryInfo.pageSize 默认每页记录数 默认10
     * @param {Object} options 配置参数
     * @param {number} options.method 请求方法 默认`GET`
     *
     */
    function DataList(url, queryInfo, options) {
        options = options || {};
        this.url = url || '';
        this.queryInfo = extend({}, queryInfo || {});
        this.data = [];
        this.total = 0;
        this.pageSize = this.queryInfo.pageSize || 10;
        this.method = options.method || 'GET';
        this.condition = {};

        Emitter.mixin(this);
    }
Beispiel #13
0
 Object.keys(properties).forEach(function (property) {
     value = properties[property];
     if (property == 'transform') {
         properties = parseTransform(action[property] || '');
         value = parseTransform(value);
         properties = extend(properties, value);
         action[property] = stringifyTransform(properties);
     }
     else {
         action[property] = value;
     }
 });
Beispiel #14
0
                it('check action events with cache', function (done) {
                    var events = [];
                    var actionConfig = extend({}, require('mock/foo'));
                    actionConfig.events = {
                        init: function () {
                            events.push('init');
                        },
                        enter: function () {
                            events.push('enter');
                        },
                        wakeup: function () {
                            events.push('wakeup');
                        },
                        revived: function () {
                            events.push('revived');
                        },
                        sleep: function () {
                            events.push('sleep');
                        },
                        ready: function () {
                            events.push('ready');
                        },
                        complete: function () {
                            events.push('complete');
                        },
                        leave: function () {
                            events.push('leave');
                        }
                    };

                    firework.load({path: '/foo', action: actionConfig, cached: true});

                    router.redirect('/foo');
                    setTimeout(function () {
                        router.redirect('/');
                        setTimeout(function () {
                            router.redirect('/foo');
                            setTimeout(function () {
                                router.redirect('/foo~name=saber', null, {noCache: true});
                                setTimeout(function () {
                                    expect(events).toEqual([
                                        'init', 'enter', 'ready', 'complete', 'sleep', 'wakeup', 'revived', 'complete',
                                        'leave', 'init', 'enter', 'ready', 'complete'
                                    ]);
                                    finish(done);
                                }, WAITE_TIME);
                            }, WAITE_TIME);
                        }, WAITE_TIME);
                    }, WAITE_TIME);
                });
Beispiel #15
0
    exports.updateURL = function (url, query) {
        if (!query || !Object.keys(query).length) {
            return url;
        }

        var urlInfo = exports.parseURL(url);
        var search = urlInfo.search;
        var queryInfo = search ? exports.parseQuery(search.substr(1)) : {};
        queryInfo = extend(queryInfo, query || {});

        // 不考虑 authority info
        var newUrl = urlInfo.protocol + '//' + urlInfo.host + urlInfo.pathname;
        var querStr = exports.serialize(queryInfo);
        newUrl += (querStr ? '?' : '') + querStr;
        newUrl += urlInfo.hash;
        return newUrl;
    };
Beispiel #16
0
    var Plugin = function( widget, options ) {
        /**
         * 插件状态集
         *
         * @private
         * @type {Object}
         */
        this.states = extend(

            // `基类`默认属性集
            // 使用`extend`确保正确`mixin`子类构造函数中定义的默认状态
            {

                // 默认为禁用状态
                disable: true

            },

            // `子类`默认属性集
            this.states

        );

        /**
         * 控件实例
         *
         * @public
         * @type {Widget}
         */
        this.target = widget;

        // 初始化配置
        this.initOptions( options );

        // 更新状态
        this.addState( 'init' );

        /**
         * @event Widget#init
         * @param {Object} ev 事件参数对象
         * @param {string} ev.type 事件类型
         * @param {Widget} ev.target 触发事件的插件对象
         */
        this.emit( 'init' );
    };
Beispiel #17
0
                it('support refresh', function (done) {
                    var actionConfig = extend({}, require('mock/foo'));
                    var res = {};

                    actionConfig.refresh = function (query, options) {
                        res.query = query;
                        res.options = options;
                        return Resolver.resolved();
                    };
                    firework.load({path: '/foo', action: actionConfig});
                    router.redirect('/foo');

                    setTimeout(function () {
                        router.redirect('/foo~name=saber', null, {type: 'test'});
                        setTimeout(function () {
                            expect(res.query).toEqual({name: 'saber'});
                            expect(res.options).toEqual({type: 'test'});
                            finish(done);
                        }, WAITE_TIME);
                    }, WAITE_TIME);
                });
Beispiel #18
0
    DataList.prototype.query = function (queryInfo) {

        var me = this;

        me.emit('query:before');

        var query = extend(this.queryInfo, queryInfo || {});

        var queryStr = [];
        Object.keys(query).forEach(function (key) {
            queryStr.push(key + '=' + encodeURIComponent(query[key]));
        });
        queryStr = queryStr.join('&');
        var url = this.url;
        var options = { method: this.method.toUpperCase() };
        if (options.method == 'POST') {
            options.data = queryStr;
        }
        else {
            url += (url.indexOf('?') >= 0 ? '&' : '?') + queryStr;
        }

        me.emit('query');

        return (this.requestHook || request).request(url, options).then(
            function (res) {
                me.data = res.data || [];
                me.page = parseInt( res.page, 10 ) || 1;
                me.pageSize = parseInt( res.pageSize, 10 ) || me.pageSize;
                me.total = parseInt( res.total, 10 ) || 0;
                me.condition = res.condition || {};
                // 时间校验码
                me.signTime = res.signTime || 0;

                me.emit('query:after');

                return me.data;
            }
        );
    };
Beispiel #19
0
    /**
     * 获取事件处理函数
     *
     * @inner
     * @param {EventHost} eventHost
     * @param {Event} e
     * @return {Array}
     */
    function getHandlers(eventHost, e) {
        var target = e.target;
        var type = e.type;
        var res = [];
        var handlers = eventHost.handlers[type] || [];

        while (handlers.delegateCount && target && target !== eventHost.ele) {
            var handler;
            var max = handlers.delegateCount;
            for (var i = 0; i < max && (handler = handlers[i]); i++) {
                if (matchElement(target, handler.selector, eventHost.ele)) {
                    var item = extend({}, handler);
                    item.thisArg = target;
                    res.push(item);
                }
            }
            target = target.parentNode;
        }

        res = res.concat(handlers.slice(handlers.delegateCount || 0));

        return res;
    }
Beispiel #20
0
define("saber-widget/Widget",["require","saber-lang/extend","./main","saber-dom","./base/event","./base/state","./base/attribute","./base/dom"],function(require){function t(t){var n,i;for(n in t)if(t.hasOwnProperty(n)){if(i=t[n],/^on[A-Z]/.test(n)&&e(i))this.on(n.charAt(2).toLowerCase()+n.slice(3),i),delete t[n];else if(e(this[n])&&e(i))this[n]=i,delete t[n]}else;return t}function e(t){return"function"==typeof t}var n=require("saber-lang/extend"),i=require("./main"),r=function(t){t=t||{},this.attrs=n({},this.attrs||{},{type:{readOnly:!0,value:this.type},id:{readOnly:!0,getter:function(){return this.id}},main:{readOnly:!0,getter:function(){return this.main}}}),this.states=n({disable:!0},this.states),this.runtime={},this.id=t.id||i.getGUID(),this.main=require("saber-dom").query(t.main),delete t.id,delete t.main,this.initOptions(t),i.add(this),this.addState("init"),this.emit("init")};return r.prototype={constructor:r,type:"Widget",initOptions:function(e){e=t.call(this,e),this.options=n({},e),this.set(this.options)},initDom:function(){},initEvent:function(){},render:function(){var t=this.is("render");if(!t)this.emit("beforerender"),this.initDom(),this.initEvent(),this.get("main").setAttribute(i.getConfig("instanceAttr"),this.get("id")),this.addState("render");if(this.repaint(),!t)this.emit("afterrender");return this},repaint:function(){},dispose:function(){if(!this.is("dispose"))this.emit("beforedispose"),this.disable(),this.runtime=null,this.clearEvents(),i.remove(this),i.disposePlugin(this),this.emit("afterdispose"),this.off(),this.addState("dispose"),this.main.removeAttribute(i.getConfig("instanceAttr")),this.main=null},enable:function(){if(this.is("disable"))this.removeState("disable"),this.emit("enable");return this},disable:function(){if(!this.is("disable"))this.addState("disable"),this.emit("disable");return this},plugin:function(t){return(this.plugins||{})[t]},enablePlugin:function(t,e){return i.enablePlugin(this,t,(this.options.plugin||{})[e||t.toLowerCase()]),this},disablePlugin:function(t){return i.disablePlugin(this,t),this}},n(r.prototype,require("./base/event"),require("./base/state"),require("./base/attribute"),require("./base/dom")),r});
Beispiel #21
0
define("saber-uri/component/Query",["require","saber-lang/inherits","saber-lang/extend","./Abstract","../util/parse-query","../util/stringify-query"],function(require){function t(t){return"[object Object]"===Object.prototype.toString.call(t)}function e(t){return"string"==typeof t}function n(t,e){if(!Array.isArray(t)||!Array.isArray(e))return!1;if(t.length!==e.length)return!1;t=t.slice(0),t=t.slice(0),t.sort(),e.sort();for(var n=!0,r=0,i=t.length;n&&i>r;r++)n=t[r]==e[r];return n}function r(e,r){if(!t(e)||!t(r))return!1;var i=Object.keys(e),o=Object.keys(r);if(i.length!==o.length)return!1;for(var s,a,u=!0,c=0;u&&(s=i[c]);c++){if(!r.hasOwnProperty(s)){u=!1;break}if(a=e[s],Array.isArray(a))u=n(a,r[s]);else u=a==r[s]}return u}function i(t){if(Array.isArray(t))t=t.map(function(t){return decodeURIComponent(t)});else t=decodeURIComponent(t);return t}function o(t,e,n){var r=n[t];if(e=i(e),r){if(!Array.isArray(r))r=[r];if(Array.isArray(e))r=r.concat(e);else r.push(e)}else r=e;return n[t]=r,n}function s(t){t=t||{},c.call(this,t)}var a=require("saber-lang/inherits"),u=require("saber-lang/extend"),c=require("./Abstract"),f=require("../util/parse-query"),l=require("../util/stringify-query"),p="?";return a(s,c),s.prototype.set=function(){if(1===arguments.length){var e=arguments[0];if(t(e)){var n=this.data={};Object.keys(e).forEach(function(t){n[t]=i(e[t])})}else this.data=f(e)}else this.data[arguments[0]]=decodeURIComponent(arguments[1])},s.prototype.get=function(t){return t?this.data[t]:u({},this.data)},s.prototype.toString=function(t){t=t||p;var e=l(this.data);return e?t+e:""},s.prototype.equal=function(t){if(e(t))t=f(t);else if(t instanceof s)t=t.get();return r(this.data,t)},s.prototype.add=function(e,n){var r=this.data;if(t(e))Object.keys(e).forEach(function(t){o(t,e[t],r)});else o(e,n,r);this.data=r},s.prototype.remove=function(t){if(!t)this.data={};else if(this.data.hasOwnProperty(t))delete this.data[t]},s});
Beispiel #22
0
define( function ( require ) {

    var bind = require( 'saber-lang/bind' );
    var extend = require( 'saber-lang/extend' );


    /**
     * 插件基类
     *
     * @constructor
     * @exports Plugin
     * @class
     * @mixes event
     * @mixes state
     * @requires saber-lang
     * @requires saber-emitter
     * @fires Plugin#init
     * @fires Plugin#beforerender
     * @fires Plugin#afterrender
     * @fires Plugin#beforedispose
     * @fires Plugin#afterdispose
     * @fires Plugin#enable
     * @fires Plugin#disable
     * @param {Widget} widget 控件实例
     * @param {Object=} options 插件配置项
     */
    var Plugin = function( widget, options ) {
        /**
         * 插件状态集
         *
         * @private
         * @type {Object}
         */
        this.states = extend(

            // `基类`默认属性集
            // 使用`extend`确保正确`mixin`子类构造函数中定义的默认状态
            {

                // 默认为禁用状态
                disable: true

            },

            // `子类`默认属性集
            this.states

        );

        /**
         * 控件实例
         *
         * @public
         * @type {Widget}
         */
        this.target = widget;

        // 初始化配置
        this.initOptions( options );

        // 更新状态
        this.addState( 'init' );

        /**
         * @event Widget#init
         * @param {Object} ev 事件参数对象
         * @param {string} ev.type 事件类型
         * @param {Widget} ev.target 触发事件的插件对象
         */
        this.emit( 'init' );
    };

    Plugin.prototype = {

        /**
         * 插件类型标识
         *
         * @private
         * @type {string}
         */
        type: 'Plugin',

        /**
         * 插件初始化
         *
         * @protected
         * @param {Object=} options 构造函数传入的配置参数
         */
        initOptions: function ( options ) {
            this.options = extend( {}, this.options, options );

            if ( this.target.is( 'render' ) ) {
                this.render();
            }
            else {
                this.target.once( 'afterrender', bind( this.render, this ) );
            }
        },

        /**
         * 初始化DOM结构,仅在第一次渲染时调用
         *
         * @protected
         */
        initDom: function () {},

        /**
         * 初始化所有事件监听
         *
         * @protected
         */
        initEvent: function () {},

        /**
         * 清理所有事件监听
         *
         * @protected
         */
        clearEvent: function () {},

        /**
         * 销毁插件
         *
         * @public
         * @fires Plugin#beforedispose
         * @fires Plugin#afterdispose
         */
        dispose: function () {
            if ( !this.is( 'dispose' ) ) {
                /**
                 * @event Plugin#beforedispose
                 * @param {Object} ev 事件参数对象
                 * @param {string} ev.type 事件类型
                 * @param {Plugin} ev.target 触发事件的插件对象
                 */
                this.emit( 'beforedispose' );

                // 清理相关事件
                this.clearEvent();

                // 释放控件引用
                this.target = null;

                /**
                 * @event Plugin#afterdispose
                 * @param {Object} ev 事件参数对象
                 * @param {string} ev.type 事件类型
                 * @param {Plugin} ev.target 触发事件的插件对象
                 */
                this.emit( 'afterdispose' );

                // 清理自定义事件
                this.off();

                // 更新状态
                this.addState( 'dispose' );
            }
        },

        /**
         * 启用插件
         *
         * @public
         * @fires Plugin#enable
         */
        enable: function () {
            if ( this.is( 'disable' ) ) {
                this.removeState( 'disable' );

                /**
                 * @event Plugin#enable
                 * @param {Object} ev 事件参数对象
                 * @param {string} ev.type 事件类型
                 * @param {Plugin} ev.target 触发事件的插件对象
                 */
                this.emit( 'enable' );
            }

            return this;
        },

        /**
         * 禁用插件
         *
         * @public
         * @fires Plugin#disable
         */
        disable: function () {
            if ( !this.is( 'disable' ) ) {
                this.addState( 'disable' );

                /**
                 * @event Plugin#disable
                 * @param {Object} ev 事件参数对象
                 * @param {string} ev.type 事件类型
                 * @param {Plugin} ev.target 触发事件的插件对象
                 */
                this.emit( 'disable' );
            }

            return this;
        },

        /**
         * 重绘插件
         *
         * @protected
         */
        repaint: function () {},

        /**
         * 渲染控件
         *
         * @protected
         * @fires Plugin#beforerender
         * @fires Plugin#afterrender
         */
        render: function () {
            var rendered = this.is( 'render' );

            if ( !rendered ) {
                this.addState( 'render' );

                /**
                 * @event Plugin#beforerender
                 * @param {Object} ev 事件参数对象
                 * @param {string} ev.type 事件类型
                 * @param {Plugin} ev.target 触发事件的插件对象
                 */
                this.emit( 'beforerender' );

                // DOM初始化
                this.initDom();

                // 事件初始化
                this.initEvent();
            }

            // DOM重绘
            this.repaint();

            if ( !rendered ) {
                /**
                 * @event Plugin#afterrender
                 * @param {Object} ev 事件参数对象
                 * @param {string} ev.type 事件类型
                 * @param {Plugin} ev.target 触发事件的插件对象
                 */
                this.emit( 'afterrender' );
            }

            return this;
        }

    };



    // 混入 `定义事件`、`状态管理` 支持
    extend(
        Plugin.prototype,
        require( '../base/event' ),
        require( '../base/state' )
    );


    return Plugin;

} );
Beispiel #23
0
    exports.set = function (name, value, options) {
        // 当前的属性集合
        var currentAttrs = this.attrs;


        // 待设置的属性集合: { 'key1': value1, 'key2': value2 ... }
        var newAttrs = {};

        // 参数多态处理
        if ('string' === typeof name) {
            newAttrs[ name ] = value;
        }
        else if ('object' === typeof name) {
            newAttrs = name;
            options = value;
        }


        options = options || {};

        var isInited = this.is('init');
        var repaintChanges = {};

        // 循环处理每个属性
        for (var key in newAttrs) {

            if (!newAttrs.hasOwnProperty(key)) {
                continue;
            }

            // 属性`key`的新值
            var newVal = newAttrs[ key ];

            // 属性`key`的当前状态
            var attr = currentAttrs[ key ] || (currentAttrs[ key ] = {});

            // 属性`key`只读时,立即抛出异常
            if (attr.readOnly || attr.readonly) {
                throw new Error('attribute is readOnly: ' + key);
            }

            // 属性`key`有`setter`方法,优先使用
            if (attr.setter) {
                attr.setter.call(this, newVal, key);
            }

            // 属性`key`的值若是`Object`
            // 且新值也是`Object`时,
            // 非覆盖模式需要`merge`防止丢失属性
            var oldValue = attr.value;
            if (!options.override && Type.isPlainObject(oldValue) && Type.isPlainObject(newVal)) {
                newVal = extend({}, oldValue, newVal);
            }

            // 更新属性`key`的值
            currentAttrs[ key ].value = newVal;

            // 忽略重复赋值
            if (isEqual(newVal, oldValue)) {
                continue;
            }

            // TODO: 是否有必要按属性触发? 或许集中在一起一次性通知更好? 暂时先这样吧
            // 未指定静默 或 非初始化阶段 才触发事件
            if (!options.silent && isInited) {
                /**
                 * @event Widget#propertychange
                 * @param {Object} ev 事件参数对象
                 * @param {string} ev.type 事件类型
                 * @param {Widget} ev.target 触发事件的控件对象
                 * @param {string} key 属性名
                 * @param {*} oldValue 变更前的属性值
                 * @param {*} newVal 变更后的属性值
                 */
                this.emit('propertychange', key, oldValue, newVal);
            }

            // 属性`key`的变化影响重绘,则加入重绘通知对象列表
            if (currentAttrs[ key ].repaint) {
                repaintChanges[ key ] = [oldValue, newVal];
            }
        }

        // 存在影响重绘的属性变更时执行一次重绘
        if (this.is('render') && Object.keys(repaintChanges).length > 0) {
            this.repaint(repaintChanges);
        }

    };
Beispiel #24
0
 DataList.prototype.getQuery = function () {
     return extend({}, this.queryInfo);
 };
Beispiel #25
0
define("list/Action",function(require){function t(t){t=t||{},e(o,t.events||{}),t.events=o,r.call(this,t)}var e=require("saber-lang/extend"),n=require("saber-lang/bind"),i=require("saber-lang/inherits"),r=require("saber-firework/Action"),o={"view:more":function(){var t=this.view;this.model.more().then(n(t.add,t))}};return i(t,r),t});
Beispiel #26
0
define(function (require) {
    var ajax = require('./ajax');
    var Resolver = require('saber-promise');
    var bind = require('saber-lang/bind');
    var extend = require('saber-lang/extend');
    var Emitter = require('saber-emitter');

    var ERROR = {
        DATA: -1, // json解析错误
        ABORT: -2, // 请求 abort
        TIMEOUT: -3,  // 请求超时
        ERROR: -500 // 未知错误
    };

    var exports = {};

    Emitter.mixin(exports);

    function request(url, options) {
        var resolver = new Resolver();
        var req = ajax.request(url, options);

        req.then(
            function (res) {
                try {
                    res = JSON.parse(res);
                    if (!res.status) {
                        resolver.fulfill(res.data);
                    }
                    else {
                        resolver.reject(res);
                    }
                }
                catch (e) {
                    resolver.reject({status: ERROR.DATA});
                }
            },
            function (reason) {
                if (typeof reason === 'string') {
                    reason = ERROR[reason.toUpperCase()] || ERROR.ERROR;
                }
                resolver.reject({status: reason});
            }
        );

        req.promise = resolver.promise();
        req.promise.then(
            bind(exports.emit, exports, 'success', req),
            bind(exports.emit, exports, 'fail', req)
        );
        req.handleSuccess = false;
        req.handleFail = false;

        return req;
    }

    exports.get = function (url, query) {
        var options = {
            method: 'GET',
            data: query
        };

        return request(url, options);
    };

    exports.post = function (url, data) {
        var options = {
            method: 'POST',
            data: data
        };

        return request(url, options);
    };

    exports.request = request;

    exports.ERROR = extend({}, ERROR);

    return exports;
});
Beispiel #27
0
    /**
     * 滑动转场
     *
     * @public
     * @param {Resolver} resolver Resolver对象
     * @param {Object} options 转场参数
     * @param {Page} options.frontPage 转场前页(转出页)
     * @param {Page} options.backPage 转场后页(转入页)
     * @param {number} options.duration 动画时间 秒为单位
     * @param {string} options.timing 过渡速度曲线
     * @param {string} options.direction 转场方向 默认是右转入
     * @param {boolean} options.transform 是否启用transform
     */
    function slide(resolver, options) {
        var duration = options.duration || config.duration;
        var timing = options.timing || config.timing;
        var frontPage = options.frontPage;
        var backPage = options.backPage;

        options.transform = options.transform !== undefined
                                ? options.transform
                                : config.transform;

        // 转场方向设置
        options.direction = options.direction
            || (backPage.hasVisited ? DIRECTION.LEFT : DIRECTION.RIGHT);

        // 设置处理器
        processor = extend(options.processor || {}, buildinProcessor);

        // TODO
        // PROFORMANCE
        var container = prepare(frontPage, backPage, options);

        var bars = prepareBars(frontPage, backPage, options);

        var transitions = [];
        // bar处理
        bars.forEach(function (item) {
            // 设置前页bar的转化效果
            transitions.push(
                runner.transition(
                    item.front,
                    {opacity: 0},
                    {
                        // 如果不需要转场效果则设置成突变转化
                        // android 2.3 不支持 steps
                        // 改用delay模拟
                        duration: item.change ? duration : 0.1,
                        timing: timing,
                        delay: item.change ? 0 : duration
                    }
                )
            );
        });

        var value = options.direction === DIRECTION.LEFT
                        ? 0
                        : -frontPage.main.offsetWidth;
        var styles = options.transform
                        ? {transform: 'translate3d(' + value + 'px, 0, 0)'}
                        : {marginLeft: value + 'px'};

        var promise = runner.transition(
                container,
                styles,
                {
                    duration: duration,
                    timing: timing
                }
            );

        transitions.push(promise);

        // 动画完成后执行finish收尾工作
        Resolver.all(transitions).then(curry(finish, frontPage, backPage, bars, resolver));
    }
Beispiel #28
0
        before: function (front, back) {
            var eles = front.getFixed();
            var frontFixedNum = eles.length;
            eles = eles.concat(back.getFixed());

            // 添加不配对的fixed bar
            var frontBar = front.getBar();
            var backBar = back.getBar();
            var commonKeys = getCommonKey(frontBar, backBar);
            var bar = extend(frontBar, backBar);
            Object.keys(bar).forEach(function (key) {
                if (commonKeys.indexOf(key) < 0
                    && dom.getStyle(bar[key], 'position') === 'fixed'
                ) {
                    eles.push(bar[key]);
                }
            });

            this.fixedEles = eles;
            var attrData = this.data = [];

            var attrs = ['top', 'left', 'right', 'bottom', 'width', 'height', 'position'];
            var data;
            var value;
            var pos;
            var parent = front.main;
            eles.forEach(function (ele, index) {
                if (index >= frontFixedNum) {
                    parent = back.main;
                }
                // 保存原始样式信息
                data = {};
                attrs.forEach(function (key) {
                    data[key] = ele.style[key] || null;
                });
                attrData.push(data);

                // 当前位置计算
                pos = dom.position(ele);
                // 计算margin-top, margin-left
                for (var i = 0, max = 2; i < max; i++) {
                    value = parseInt(dom.getStyle(ele, 'margin-' + attrs[i]), 10);
                    if (!isNaN(value)) {
                        pos[attrs[i]] -= value;
                    }

                    // 修正offsetParent的margin影响
                    value = parseInt(dom.getStyle(parent, 'margin-' + attrs[i]), 10);
                    if (!isNaN(value)) {
                        pos[attrs[i]] -= value;
                    }
                }

                // 改变position
                util.setStyles(ele, {
                    position: 'absolute',
                    top: pos.top + 'px',
                    left: pos.left + 'px',
                    width: dom.getStyle(ele, 'width') + 'px',
                    height: dom.getStyle(ele, 'height') + 'px',
                    bottom: 'auto',
                    right: 'atuo'
                });
            });
        },
Beispiel #29
0
 Animation.prototype.reset = function () {
     this._action = {};
     this._options = extend({}, this._defaultOptions);
     return this;
 };