# All files / scripts/CDP/UI/listview Utils.ts

20.59% Statements 14/68
13.95% Branches 6/43
21.43% Functions 3/14
19.4% Lines 13/67

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    1771x

    1x

    1x

    1x

    1x

    1x

    1x

    1x

    1x

    1x

    1x

    1x

    1x

     ﻿namespace CDP.UI {

        // cdp.ui.listview は cdp.core に依存しないため、独自にglobal を提供する
        /*jshint evil:true */
        export const global = (<any>CDP).global || Function("return this")();
        /*jshint evil:false */

        /**
         * Backbone.View の新規合成
         *
         * @param base    {Backbone.View}                 [in] prototype chain 最下位の View クラス
         * @param derives {Backbone.View|Backbone.View[]} [in] 派生されるの View クラス
         * @return {Backbone.View|Backbone.View[]} 新規に生成された View のコンストラクタ
         */
        export function composeViews(base: ViewConstructor, derives: ViewConstructor | ViewConstructor[]): ViewConstructor {
            let _composed = base;
            const _derives = <ViewConstructor[]>(derives instanceof Array ? derives : [derives]);
            _derives.forEach((derive) => {
                const seed = {};
                _.extendOwn(seed, derive.prototype);
                delete seed.constructor;
                _composed = (<any>_composed).extend(seed);
            });
            return _composed;
        }

        /**
         * Backbone.View の合成
         * prototype chain を作る合成
         *
         * @param derived {Backbone.View}                 [in] prototype chain 最上位の View クラス
         * @param bases   {Backbone.View|Backbone.View[]} [in] 合成元のView クラス
         */
        export function deriveViews(derived: ViewConstructor, bases: ViewConstructor | ViewConstructor[]): void {
            let _composed: ViewConstructor;
            const _bases = <ViewConstructor[]>(bases instanceof Array ? bases : [bases]);
            if (2 <= _bases.length) {
                _composed = composeViews(_bases[0], _bases.slice(1));
            } else {
                _composed = _bases[0];
            }
            derived = composeViews(_composed, derived);
        }

        /**
         * Backbone.View の合成
         * prototype chain を作らない合成
         *
         * @param derived {Backbone.View}                 [in] 元となる View クラス
         * @param bases   {Backbone.View|Backbone.View[]} [in] 合成元のView クラス
         */
        export function mixinViews(derived: ViewConstructor, bases: ViewConstructor | ViewConstructor[]): void {
            const _bases = <ViewConstructor[]>(bases instanceof Array ? bases : [bases]);
            _bases.forEach((base) => {
                Object.getOwnPropertyNames(base.prototype).forEach(name => {
                    derived.prototype[name] = base.prototype[name];
                });
            });
        }

        //___________________________________________________________________________________________________________________//

        /**
         * @class _ListViewUtils
         * @brief 内部で使用する便利関数
         *        Tools からの最低限の流用
         */
        export module _ListViewUtils {

            /**
             * css の vender 拡張 prefix を返す
             *
             * @return {Array} prefix
             */
            export const cssPrefixes = ["-webkit-", "-moz-", "-ms-", "-o-", ""];

            /**
             * css の matrix の値を取得.
             *
             * @param element {jQuery} [in] 対象の jQuery オブジェクト
             * @param type    {String} [in] matrix type string [translateX | translateY | scaleX | scaleY]
             * @return {Number} value
             */
            export const getCssMatrixValue = (element: JQuery, type: string): number => {
                let transX = 0;
                let transY = 0;
                let scaleX = 0;
                let scaleY = 0;
                for (let i = 0; i < cssPrefixes.length; i++) {
                    let matrix = $(element).css(cssPrefixes[i] + "transform");
                    if (matrix) {
                        const is3dMatrix = matrix.indexOf("3d") !== -1 ? true : false;
                        matrix = matrix.replace("matrix3d", "").replace("matrix", "").replace(/[^\d.,-]/g, "");
                        const arr = matrix.split(",");
                        transX = Number(arr[is3dMatrix ? 12 : 4]);
                        transY = Number(arr[is3dMatrix ? 13 : 5]);
                        scaleX = Number(arr[0]);
                        scaleY = Number(arr[is3dMatrix ? 5 : 3]);
                        break;
                    }
                }
                switch (type) {
                    case "translateX":
                        return isNaN(transX) ? 0 : transX;
                    case "translateY":
                        return isNaN(transY) ? 0 : transY;
                    case "scaleX":
                        return isNaN(scaleX) ? 1 : scaleX;
                    case "scaleY":
                        return isNaN(scaleY) ? 1 : scaleY;
                    default:
                        return 0;
                }
            };

            /**
             * "transitionend" のイベント名配列を返す
             *
             * @return {Array} transitionend イベント名
             */
            export const transitionEnd = "transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd";

            /**
             * transition 設定
             *
             * @private
             * @param {Object} element
             */
            export const setTransformsTransitions = (element: JQuery, prop: string, msec: number, timingFunction: string): void => {
                const $element = $(element);
                const transitions = {};
                const second = (msec / 1000) + "s";
                const animation = " " + second + " " + timingFunction;
                const transform = ", transform" + animation;

                for (let i = 0; i < cssPrefixes.length; i++) {
                    transitions[cssPrefixes[i] + "transition"] = prop + animation + transform;
                }

                $element.css(transitions);
            };

            /**
             * transition 設定の削除
             *
             * @private
             * @param {Object} element
             */
            export const clearTransitions = (element: JQuery): void => {
                const $element = $(element);

                $element.off(transitionEnd);
                const transitions = {};
                for (let i = 0; i < cssPrefixes.length; i++) {
                    transitions[cssPrefixes[i] + "transition"] = "";
                }

                $element.css(transitions);
            };

            /**
             * Math.abs よりも高速な abs
             */
            export const abs = (x: number): number => {
                return x >= 0 ? x : -x;
            };

            /**
             * Math.max よりも高速な max
             */
            export const max = (lhs: number, rhs: number): number => {
                return lhs >= rhs ? lhs : rhs;
            };
        }
    }