diff-6d8476a38aa50a7d54110d2f35538e56be8dc247L1823">1823
 * Recognized when two or more pointers are moving toward (zoom-in) or away from each other (zoom-out).
1824
 * @constructor
1825
 * @extends AttrRecognizer
1826
 */
1827
function PinchRecognizer() {
1828
    AttrRecognizer.apply(this, arguments);
1829
}
1930
    });
1830 1931
1831
inherit(PinchRecognizer, AttrRecognizer, {
1832 1932
    /**
1833
     * @namespace
1834
     * @memberof PinchRecognizer
1933
     * Rotate
1934
     * Recognized when two or more pointer are moving in a circular motion.
1935
     * @constructor
1936
     * @extends AttrRecognizer
1835 1937
     */
1836
    defaults: {
1837
        event: 'pinch',
1838
        threshold: 0,
1839
        pointers: 2
1840
    },
1841
1842
    getTouchAction: function() {
1843
        return [TOUCH_ACTION_NONE];
1844
    },
1845
1846
    attrTest: function(input) {
1847
        return this._super.attrTest.call(this, input) &&
1848
            (Math.abs(input.scale - 1) > this.options.threshold || this.state & STATE_BEGAN);
1849
    },
1850
1851
    emit: function(input) {
1852
        if (input.scale !== 1) {
1853
            var inOut = input.scale < 1 ? 'in' : 'out';
1854
            input.additionalEvent = this.options.event + inOut;
1855
        }
1856
        this._super.emit.call(this, input);
1938
    function RotateRecognizer() {
1939
        AttrRecognizer.apply(this, arguments);
1857 1940
    }
1858
});
1859 1941
1860
/**
1861
 * Press
1862
 * Recognized when the pointer is down for x ms without any movement.
1863
 * @constructor
1864
 * @extends Recognizer
1865
 */
1866
function PressRecognizer() {
1867
    Recognizer.apply(this, arguments);
1942
    inherit(RotateRecognizer, AttrRecognizer, {
1943
        /**
1944
         * @namespace
1945
         * @memberof RotateRecognizer
1946
         */
1947
        defaults: {
1948
            event: 'rotate',
1949
            threshold: 0,
1950
            pointers: 2
1951
        },
1952
1953
        getTouchAction: function() {
1954
            return [TOUCH_ACTION_NONE];
1955
        },
1868 1956
1869
    this._timer = null;
1870
    this._input = null;
1871
}
1957
        attrTest: function(input) {
1958
            return this._super.attrTest.call(this, input) &&
1959
              (Math.abs(input.rotation) > this.options.threshold || this.state & STATE_BEGAN);
1960
        }
1961
    });
1872 1962
1873
inherit(PressRecognizer, Recognizer, {
1874 1963
    /**
1875
     * @namespace
1876
     * @memberof PressRecognizer
1964
     * Swipe
1965
     * Recognized when the pointer is moving fast (velocity), with enough distance in the allowed direction.
1966
     * @constructor
1967
     * @extends AttrRecognizer
1877 1968
     */
1878
    defaults: {
1879
        event: 'press',
1880
        pointers: 1,
1881
        time: 251, // minimal time of the pointer to be pressed
1882
        threshold: 9 // a minimal movement is ok, but keep it low
1883
    },
1884
1885
    getTouchAction: function() {
1886
        return [TOUCH_ACTION_AUTO];
1887
    },
1888
1889
    process: function(input) {
1890
        var options = this.options;
1891
        var validPointers = input.pointers.length === options.pointers;
1892
        var validMovement = input.distance < options.threshold;
1893
        var validTime = input.deltaTime > options.time;
1894
1895
        this._input = input;
1896
1897
        // we only allow little movement
1898
        // and we've reached an end event, so a tap is possible
1899
        if (!validMovement || !validPointers || (input.eventType & (INPUT_END | INPUT_CANCEL) && !validTime)) {
1900
            this.reset();
1901
        } else if (input.eventType & INPUT_START) {
1902
            this.reset();
1903
            this._timer = setTimeoutContext(function() {
1904
                this.state = STATE_RECOGNIZED;
1905
                this.tryEmit();
1906
            }, options.time, this);
1907
        } else if (input.eventType & INPUT_END) {
1908
            return STATE_RECOGNIZED;
1909
        }
1910
        return STATE_FAILED;
1911
    },
1969
    function SwipeRecognizer() {
1970
        AttrRecognizer.apply(this, arguments);
1971
    }
1912 1972
1913
    reset: function() {
1914
        clearTimeout(this._timer);
1915
    },
1973
    inherit(SwipeRecognizer, AttrRecognizer, {
1974
        /**
1975
         * @namespace
1976
         * @memberof SwipeRecognizer
1977
         */
1978
        defaults: {
1979
            event: 'swipe',
1980
            threshold: 10,
1981
            velocity: 0.3,
1982
            direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL,
1983
            pointers: 1
1984
        },
1985
1986
        getTouchAction: function() {
1987
            return PanRecognizer.prototype.getTouchAction.call(this);
1988
        },
1989
1990
        attrTest: function(input) {
1991
            var direction = this.options.direction;
1992
            var velocity;
1993
1994
            if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) {
1995
                velocity = input.overallVelocity;
1996
            } else if (direction & DIRECTION_HORIZONTAL) {
1997
                velocity = input.overallVelocityX;
1998
            } else if (direction & DIRECTION_VERTICAL) {
1999
                velocity = input.overallVelocityY;
2000
            }
1916 2001
1917
    emit: function(input) {
1918
        if (this.state !== STATE_RECOGNIZED) {
1919
            return;
1920
        }
2002
            return this._super.attrTest.call(this, input) &&
2003
              direction & input.offsetDirection &&
2004
              input.distance > this.options.threshold &&
2005
              input.maxPointers == this.options.pointers &&
2006
              abs(velocity) > this.options.velocity && input.eventType & INPUT_END;
2007
        },
2008
2009
        emit: function(input) {
2010
            var direction = directionStr(input.offsetDirection);
2011
            if (direction) {
2012
                this.manager.emit(this.options.event + direction, input);
2013
            }
1921 2014
1922
        if (input && (input.eventType & INPUT_END)) {
1923
            this.manager.emit(this.options.event + 'up', input);
1924
        } else {
1925
            this._input.timeStamp = now();
1926
            this.manager.emit(this.options.event, this._input);
2015
            this.manager.emit(this.options.event, input);
1927 2016
        }
1928
    }
1929
});
1930
1931
/**
1932
 * Rotate
1933
 * Recognized when two or more pointer are moving in a circular motion.
1934
 * @constructor
1935
 * @extends AttrRecognizer
1936
 */
1937
function RotateRecognizer() {
1938
    AttrRecognizer.apply(this, arguments);
1939
}
2017
    });
1940 2018
1941
inherit(RotateRecognizer, AttrRecognizer, {
1942 2019
    /**
1943
     * @namespace
1944
     * @memberof RotateRecognizer
1945
     */
1946
    defaults: {
1947
        event: 'rotate',
1948
        threshold: 0,
1949
        pointers: 2
1950
    },
1951
1952
    getTouchAction: function() {
1953
        return [TOUCH_ACTION_NONE];
1954
    },
1955
1956
    attrTest: function(input) {
1957
        return this._super.attrTest.call(this, input) &&
1958
            (Math.abs(input.rotation) > this.options.threshold || this.state & STATE_BEGAN);
1959
    }
1960
});
1961
1962
/**
1963
 * Swipe
1964
 * Recognized when the pointer is moving fast (velocity), with enough distance in the allowed direction.
1965
 * @constructor
1966
 * @extends AttrRecognizer
1967
 */
1968
function SwipeRecognizer() {
1969
    AttrRecognizer.apply(this, arguments);
1970
}
1971
1972
inherit(SwipeRecognizer, AttrRecognizer, {
1973
    /**
1974
     * @namespace
1975
     * @memberof SwipeRecognizer
2020
     * A tap is ecognized when the pointer is doing a small tap/click. Multiple taps are recognized if they occur
2021
     * between the given interval and position. The delay option can be used to recognize multi-taps without firing
2022
     * a single tap.
2023
     *
2024
     * The eventData from the emitted event contains the property `tapCount`, which contains the amount of
2025
     * multi-taps being recognized.
2026
     * @constructor
2027
     * @extends Recognizer
1976 2028
     */
1977
    defaults: {
1978
        event: 'swipe',
1979
        threshold: 10,
1980
        velocity: 0.3,
1981
        direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL,
1982
        pointers: 1
1983
    },
1984
1985
    getTouchAction: function() {
1986
        return PanRecognizer.prototype.getTouchAction.call(this);
1987
    },
1988
1989
    attrTest: function(input) {
1990
        var direction = this.options.direction;
1991
        var velocity;
1992
1993
        if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) {
1994
            velocity = input.overallVelocity;
1995
        } else if (direction & DIRECTION_HORIZONTAL) {
1996
            velocity = input.overallVelocityX;
1997
        } else if (direction & DIRECTION_VERTICAL) {
1998
            velocity = input.overallVelocityY;
1999
        }
2029
    function TapRecognizer() {
2030
        Recognizer.apply(this, arguments);
2000 2031
2001
        return this._super.attrTest.call(this, input) &&
2002
            direction & input.offsetDirection &&
2003
            input.distance > this.options.threshold &&
2004
            input.maxPointers == this.options.pointers &&
2005
            abs(velocity) > this.options.velocity && input.eventType & INPUT_END;
2006
    },
2007
2008
    emit: function(input) {
2009
        var direction = directionStr(input.offsetDirection);
2010
        if (direction) {
2011
            this.manager.emit(this.options.event + direction, input);
2012
        }
2032
        // previous time and center,
2033
        // used for tap counting
2034
        this.pTime = false;
2035
        this.pCenter = false;
2013 2036
2014
        this.manager.emit(this.options.event, input);
2037
        this._timer = null;
2038
        this._input = null;
2039
        this.count = 0;
2015 2040
    }
2016
});
2017 2041
2018
/**
2019
 * A tap is ecognized when the pointer is doing a small tap/click. Multiple taps are recognized if they occur
2020
 * between the given interval and position. The delay option can be used to recognize multi-taps without firing
2021
 * a single tap.
2022
 *
2023
 * The eventData from the emitted event contains the property `tapCount`, which contains the amount of
2024
 * multi-taps being recognized.
2025
 * @constructor
2026
 * @extends Recognizer
2027
 */
2028
function TapRecognizer() {
2029
    Recognizer.apply(this, arguments);
2030
2031
    // previous time and center,
2032
    // used for tap counting
2033
    this.pTime = false;
2034
    this.pCenter = false;
2035
2036
    this._timer = null;
2037
    this._input = null;
2038
    this.count = 0;
2039
}
2040
2041
inherit(TapRecognizer, Recognizer, {
2042
    /**
2043
     * @namespace
2044
     * @memberof PinchRecognizer
2045
     */
2046
    defaults: {
2047
        event: 'tap',
2048
        pointers: 1,
2049
        taps: 1,
2050
        interval: 300, // max time between the multi-tap taps
2051
        time: 250, // max time of the pointer to be down (like finger on the screen)
2052
        threshold: 9, // a minimal movement is ok, but keep it low
2053
        posThreshold: 10 // a multi-tap can be a bit off the initial position
2054
    },
2055
2056
    getTouchAction: function() {
2057
        return [TOUCH_ACTION_MANIPULATION];
2058
    },
2059
2060
    process: function(input) {
2061
        var options = this.options;
2062
2063
        var validPointers = input.pointers.length === options.pointers;
2064
        var validMovement = input.distance < options.threshold;
2065
        var validTouchTime = input.deltaTime < options.time;
2066
2067
        this.reset();
2068
2069
        if ((input.eventType & INPUT_START) && (this.count === 0)) {
2070
            return this.failTimeout();
2071
        }
2042
    inherit(TapRecognizer, Recognizer, {
2043
        /**
2044
         * @namespace
2045
         * @memberof PinchRecognizer
2046
         */
2047
        defaults: {
2048
            event: 'tap',
2049
            pointers: 1,
2050
            taps: 1,
2051
            interval: 300, // max time between the multi-tap taps
2052
            time: 250, // max time of the pointer to be down (like finger on the screen)
2053
            threshold: 9, // a minimal movement is ok, but keep it low
2054
            posThreshold: 10 // a multi-tap can be a bit off the initial position
2055
        },
2056
2057
        getTouchAction: function() {
2058
            return [TOUCH_ACTION_MANIPULATION];
2059
        },
2060
2061
        process: function(input) {
2062
            var options = this.options;
2063
2064
            var validPointers = input.pointers.length === options.pointers;
2065
            var validMovement = input.distance < options.threshold;
2066
            var validTouchTime = input.deltaTime < options.time;
2067
2068
            this.reset();
2072 2069
2073
        // we only allow little movement
2074
        // and we've reached an end event, so a tap is possible
2075
        if (validMovement && validTouchTime && validPointers) {
2076
            if (input.eventType != INPUT_END) {
2070
            if ((input.eventType & INPUT_START) && (this.count === 0)) {
2077 2071
                return this.failTimeout();
2078 2072
            }
2079 2073
2080
            var validInterval = this.pTime ? (input.timeStamp - this.pTime < options.interval) : true;
2081
            var validMultiTap = !this.pCenter || getDistance(this.pCenter, input.center) < options.posThreshold;
2082
2083
            this.pTime = input.timeStamp;
2084
            this.pCenter = input.center;
2074
            // we only allow little movement
2075
            // and we've reached an end event, so a tap is possible
2076
            if (validMovement && validTouchTime && validPointers) {
2077
                if (input.eventType != INPUT_END) {
2078
                    return this.failTimeout();
2079
                }
2085 2080
2086
            if (!validMultiTap || !validInterval) {
2087
                this.count = 1;
2088
            } else {
2089
                this.count += 1;
2090
            }
2081
                var validInterval = this.pTime ? (input.timeStamp - this.pTime < options.interval) : true;
2082
                var validMultiTap = !this.pCenter || getDistance(this.pCenter, input.center) < options.posThreshold;
2091 2083
2092
            this._input = input;
2084
                this.pTime = input.timeStamp;
2085
                this.pCenter = input.center;
2093 2086
2094
            // if tap count matches we have recognized it,
2095
            // else it has began recognizing...
2096
            var tapCount = this.count % options.taps;
2097
            if (tapCount === 0) {
2098
                // no failing requirements, immediately trigger the tap event
2099
                // or wait as long as the multitap interval to trigger
2100
                if (!this.hasRequireFailures()) {
2101
                    return STATE_RECOGNIZED;
2087
                if (!validMultiTap || !validInterval) {
2088
                    this.count = 1;
2102 2089
                } else {
2103
                    this._timer = setTimeoutContext(function() {
2104
                        this.state = STATE_RECOGNIZED;
2105
                        this.tryEmit();
2106
                    }, options.interval, this);
2107
                    return STATE_BEGAN;
2090
                    this.count += 1;
2091
                }
2092
2093
                this._input = input;
2094
2095
                // if tap count matches we have recognized it,
2096
                // else it has began recognizing...
2097
                var tapCount = this.count % options.taps;
2098
                if (tapCount === 0) {
2099
                    // no failing requirements, immediately trigger the tap event
2100
                    // or wait as long as the multitap interval to trigger
2101
                    if (!this.hasRequireFailures()) {
2102
                        return STATE_RECOGNIZED;
2103
                    } else {
2104
                        this._timer = setTimeoutContext(function() {
2105
                            this.state = STATE_RECOGNIZED;
2106
                            this.tryEmit();
2107
                        }, options.interval, this);
2108
                        return STATE_BEGAN;
2109
                    }
2108 2110
                }
2109 2111
            }
2110
        }
2111
        return STATE_FAILED;
2112
    },
2112
            return STATE_FAILED;
2113
        },
2113 2114
2114
    failTimeout: function() {
2115
        this._timer = setTimeoutContext(function() {
2116
            this.state = STATE_FAILED;
2117
        }, this.options.interval, this);
2118
        return STATE_FAILED;
2119
    },
2120
2121
    reset: function() {
2122
        clearTimeout(this._timer);
2123
    },
2124
2125
    emit: function() {
2126
        if (this.state == STATE_RECOGNIZED) {
2127
            this._input.tapCount = this.count;
2128
            this.manager.emit(this.options.event, this._input);
2115
        failTimeout: function() {
2116
            this._timer = setTimeoutContext(function() {
2117
                this.state = STATE_FAILED;
2118
            }, this.options.interval, this);
2119
            return STATE_FAILED;
2120
        },
2121
2122
        reset: function() {
2123
            clearTimeout(this._timer);
2124
        },
2125
2126
        emit: function() {
2127
            if (this.state == STATE_RECOGNIZED) {
2128
                this._input.tapCount = this.count;
2129
                this.manager.emit(this.options.event, this._input);
2130
            }
2129 2131
        }
2130
    }
2131
});
2132
2133
/**
2134
 * Simple way to create a manager with a default set of recognizers.
2135
 * @param {HTMLElement} element
2136
 * @param {Object} [options]
2137
 * @constructor
2138
 */
2139
function Hammer(element, options) {
2140
    options = options || {};
2141
    options.recognizers = ifUndefined(options.recognizers, Hammer.defaults.preset);
2142
    return new Manager(element, options);
2143
}
2144
2145
/**
2146
 * @const {string}
2147
 */
2148
Hammer.VERSION = '2.0.7';
2149
2150
/**
2151
 * default settings
2152
 * @namespace
2153
 */
2154
Hammer.defaults = {
2155
    /**
2156
     * set if DOM events are being triggered.
2157
     * But this is slower and unused by simple implementations, so disabled by default.
2158
     * @type {Boolean}
2159
     * @default false
2160
     */
2161
    domEvents: false,
2162
2163
    /**
2164
     * The value for the touchAction property/fallback.
2165
     * When set to `compute` it will magically set the correct value based on the added recognizers.
2166
     * @type {String}
2167
     * @default compute
2168
     */
2169
    touchAction: TOUCH_ACTION_COMPUTE,
2170
2171
    /**
2172
     * @type {Boolean}
2173
     * @default true
2174
     */
2175
    enable: true,
2176
2177
    /**
2178
     * EXPERIMENTAL FEATURE -- can be removed/changed
2179
     * Change the parent input target element.
2180
     * If Null, then it is being set the to main element.
2181
     * @type {Null|EventTarget}
2182
     * @default null
2183
     */
2184
    inputTarget: null,
2132
    });
2185 2133
2186 2134
    /**
2187
     * force an input class
2188
     * @type {Null|Function}
2189
     * @default null
2135
     * Simple way to create a manager with a default set of recognizers.
2136
     * @param {HTMLElement} element
2137
     * @param {Object} [options]
2138
     * @constructor
2190 2139
     */
2191
    inputClass: null,
2140
    function Hammer(element, options) {
2141
        options = options || {};
2142
        options.recognizers = ifUndefined(options.recognizers, Hammer.defaults.preset);
2143
        return new Manager(element, options);
2144
    }
2192 2145
2193 2146
    /**
2194
     * Default recognizer setup when calling `Hammer()`
2195
     * When creating a new Manager these will be skipped.
2196
     * @type {Array}
2147
     * @const {string}
2197 2148
     */
2198
    preset: [
2199
        // RecognizerClass, options, [recognizeWith, ...], [requireFailure, ...]
2200
        [RotateRecognizer, {enable: false}],
2201
        [PinchRecognizer, {enable: false}, ['rotate']],
2202
        [SwipeRecognizer, {direction: DIRECTION_HORIZONTAL}],
2203
        [PanRecognizer, {direction: DIRECTION_HORIZONTAL}, ['swipe']],
2204
        [TapRecognizer],
2205
        [TapRecognizer, {event: 'doubletap', taps: 2}, ['tap']],
2206
        [PressRecognizer]
2207
    ],
2149
    Hammer.VERSION = '2.0.7';
2208 2150
2209 2151
    /**
2210
     * Some CSS properties can be used to improve the working of Hammer.
2211
     * Add them to this method and they will be set when creating a new Manager.
2152
     * default settings
2212 2153
     * @namespace
2213 2154
     */
2214
    cssProps: {
2155
    Hammer.defaults = {
2215 2156
        /**
2216
         * Disables text selection to improve the dragging gesture. Mainly for desktop browsers.
2217
         * @type {String}
2218
         * @default 'none'
2157
         * set if DOM events are being triggered.
2158
         * But this is slower and unused by simple implementations, so disabled by default.
2159
         * @type {Boolean}
2160
         * @default false
2219 2161
         */
2220
        userSelect: 'none',
2162
        domEvents: false,
2221 2163
2222 2164
        /**
2223
         * Disable the Windows Phone grippers when pressing an element.
2165
         * The value for the touchAction property/fallback.
2166
         * When set to `compute` it will magically set the correct value based on the added recognizers.
2224 2167
         * @type {String}
2225
         * @default 'none'
2168
         * @default compute
2226 2169
         */
2227
        touchSelect: 'none',
2170
        touchAction: TOUCH_ACTION_COMPUTE,
2228 2171
2229 2172
        /**
2230
         * Disables the default callout shown when you touch and hold a touch target.
2231
         * On iOS, when you touch and hold a touch target such as a link, Safari displays
2232
         * a callout containing information about the link. This property allows you to disable that callout.
2233
         * @type {String}
2234
         * @default 'none'
2173
         * @type {Boolean}
2174
         * @default true
2235 2175
         */
2236
        touchCallout: 'none',
2176
        enable: true,
2237 2177
2238 2178
        /**
2239
         * Specifies whether zooming is enabled. Used by IE10>
2240
         * @type {String}
2241
         * @default 'none'
2179
         * EXPERIMENTAL FEATURE -- can be removed/changed
2180
         * Change the parent input target element.
2181
         * If Null, then it is being set the to main element.
2182
         * @type {Null|EventTarget}
2183
         * @default null
2242 2184
         */
2243
        contentZooming: 'none',
2185
        inputTarget: null,
2244 2186
2245 2187
        /**
2246
         * Specifies that an entire element should be draggable instead of its contents. Mainly for desktop browsers.
2247
         * @type {String}
2248
         * @default 'none'
2188
         * force an input class
2189
         * @type {Null|Function}
2190
         * @default null
2249 2191
         */
2250
        userDrag: 'none',
2192
        inputClass: null,
2251 2193
2252 2194
        /**
2253
         * Overrides the highlight color shown when the user taps a link or a JavaScript
2254
         * clickable element in iOS. This property obeys the alpha value, if specified.
2255
         * @type {String}
2256
         * @default 'rgba(0,0,0,0)'
2195
         * Default recognizer setup when calling `Hammer()`
2196
         * When creating a new Manager these will be skipped.
2197
         * @type {Array}
2257 2198
         */
2258
        tapHighlightColor: 'rgba(0,0,0,0)'
2259
    }
2260
};
2199
        preset: [
2200
            // RecognizerClass, options, [recognizeWith, ...], [requireFailure, ...]
2201
            [RotateRecognizer, {enable: false}],
2202
            [PinchRecognizer, {enable: false}, ['rotate']],
2203
            [SwipeRecognizer, {direction: DIRECTION_HORIZONTAL}],
2204
            [PanRecognizer, {direction: DIRECTION_HORIZONTAL}, ['swipe']],
2205
            [TapRecognizer],
2206
            [TapRecognizer, {event: 'doubletap', taps: 2}, ['tap']],
2207
            [PressRecognizer]
2208
        ],
2261 2209
2262
var STOP = 1;
2263
var FORCED_STOP = 2;
2210
        /**
2211
         * Some CSS properties can be used to improve the working of Hammer.
2212
         * Add them to this method and they will be set when creating a new Manager.
2213
         * @namespace
2214
         */
2215
        cssProps: {
2216
            /**
2217
             * Disables text selection to improve the dragging gesture. Mainly for desktop browsers.
2218
             * @type {String}
2219
             * @default 'none'
2220
             */
2221
            userSelect: 'none',
2222
2223
            /**
2224
             * Disable the Windows Phone grippers when pressing an element.
2225
             * @type {String}
2226
             * @default 'none'
2227
             */
2228
            touchSelect: 'none',
2229
2230
            /**
2231
             * Disables the default callout shown when you touch and hold a touch target.
2232
             * On iOS, when you touch and hold a touch target such as a link, Safari displays
2233
             * a callout containing information about the link. This property allows you to disable that callout.
2234
             * @type {String}
2235
             * @default 'none'
2236
             */
2237
            touchCallout: 'none',
2238
2239
            /**
2240
             * Specifies whether zooming is enabled. Used by IE10>
2241
             * @type {String}
2242
             * @default 'none'
2243
             */
2244
            contentZooming: 'none',
2245
2246
            /**
2247
             * Specifies that an entire element should be draggable instead of its contents. Mainly for desktop browsers.
2248
             * @type {String}
2249
             * @default 'none'
2250
             */
2251
            userDrag: 'none',
2252
2253
            /**
2254
             * Overrides the highlight color shown when the user taps a link or a JavaScript
2255
             * clickable element in iOS. This property obeys the alpha value, if specified.
2256
             * @type {String}
2257
             * @default 'rgba(0,0,0,0)'
2258
             */
2259
            tapHighlightColor: 'rgba(0,0,0,0)'
2260
        }
2261
    };
2264 2262
2265
/**
2266
 * Manager
2267
 * @param {HTMLElement} element
2268
 * @param {Object} [options]
2269
 * @constructor
2270
 */
2271
function Manager(element, options) {
2272
    this.options = assign({}, Hammer.defaults, options || {});
2263
    var STOP = 1;
2264
    var FORCED_STOP = 2;
2273 2265
2274
    this.options.inputTarget = this.options.inputTarget || element;
2266
    /**
2267
     * Manager
2268
     * @param {HTMLElement} element
2269
     * @param {Object} [options]
2270
     * @constructor
2271
     */
2272
    function Manager(element, options) {
2273
        this.options = assign({}, Hammer.defaults, options || {});
2275 2274
2276
    this.handlers = {};
2277
    this.session = {};
2278
    this.recognizers = [];
2279
    this.oldCssProps = {};
2275
        this.options.inputTarget = this.options.inputTarget || element;
2280 2276
2281
    this.element = element;
2282
    this.input = createInputInstance(this);
2283
    this.touchAction = new TouchAction(this, this.options.touchAction);
2277
        this.handlers = {};
2278
        this.session = {};
2279
        this.recognizers = [];
2280
        this.oldCssProps = {};
2284 2281
2285
    toggleCssProps(this, true);
2282
        this.element = element;
2283
        this.input = createInputInstance(this);
2284
        this.touchAction = new TouchAction(this, this.options.touchAction);
2286 2285
2287
    each(this.options.recognizers, function(item) {
2288
        var recognizer = this.add(new (item[0])(item[1]));
2289
        item[2] && recognizer.recognizeWith(item[2]);
2290
        item[3] && recognizer.requireFailure(item[3]);
2291
    }, this);
2292
}
2286
        toggleCssProps(this, true);
2293 2287
2294
Manager.prototype = {
2295
    /**
2296
     * set options
2297
     * @param {Object} options
2298
     * @returns {Manager}
2299
     */
2300
    set: function(options) {
2301
        assign(this.options, options);
2288
        each(this.options.recognizers, function(item) {
2289
            var recognizer = this.add(new (item[0])(item[1]));
2290
            item[2] && recognizer.recognizeWith(item[2]);
2291
            item[3] && recognizer.requireFailure(item[3]);
2292
        }, this);
2293
    }
2302 2294
2303
        // Options that need a little more setup
2304
        if (options.touchAction) {
2305
            this.touchAction.update();
2306
        }
2307
        if (options.inputTarget) {
2308
            // Clean up existing event listeners and reinitialize
2309
            this.input.destroy();
2310
            this.input.target = options.inputTarget;
2311
            this.input.init();
2312
        }
2313
        return this;
2314
    },
2295
    Manager.prototype = {
2296
        /**
2297
         * set options
2298
         * @param {Object} options
2299
         * @returns {Manager}
2300
         */
2301
        set: function(options) {
2302
            assign(this.options, options);
2315 2303
2316
    /**
2317
     * stop recognizing for this session.
2318
     * This session will be discarded, when a new [input]start event is fired.
2319
     * When forced, the recognizer cycle is stopped immediately.
2320
     * @param {Boolean} [force]
2321
     */
2322
    stop: function(force) {
2323
        this.session.stopped = force ? FORCED_STOP : STOP;
2324
    },
2304
            // Options that need a little more setup
2305
            if (options.touchAction) {
2306
                this.touchAction.update();
2307
            }
2308
            if (options.inputTarget) {
2309
                // Clean up existing event listeners and reinitialize
2310
                this.input.destroy();
2311
                this.input.target = options.inputTarget;
2312
                this.input.init();
2313
            }
2314
            return this;
2315
        },
2325 2316
2326
    /**
2327
     * run the recognizers!
2328
     * called by the inputHandler function on every movement of the pointers (touches)
2329
     * it walks through all the recognizers and tries to detect the gesture that is being made
2330
     * @param {Object} inputData
2331
     */
2332
    recognize: function(inputData) {
2333
        var session = this.session;
2334
        if (session.stopped) {
2335
            return;
2336
        }
2317
        /**
2318
         * stop recognizing for this session.
2319
         * This session will be discarded, when a new [input]start event is fired.
2320
         * When forced, the recognizer cycle is stopped immediately.
2321
         * @param {Boolean} [force]
2322
         */
2323
        stop: function(force) {
2324
            this.session.stopped = force ? FORCED_STOP : STOP;
2325
        },
2337 2326
2338
        // run the touch-action polyfill
2339
        this.touchAction.preventDefaults(inputData);
2327
        /**
2328
         * run the recognizers!
2329
         * called by the inputHandler function on every movement of the pointers (touches)
2330
         * it walks through all the recognizers and tries to detect the gesture that is being made
2331
         * @param {Object} inputData
2332
         */
2333
        recognize: function(inputData) {
2334
            var session = this.session;
2335
            if (session.stopped) {
2336
                return;
2337
            }
2340 2338
2341
        var recognizer;
2342
        var recognizers = this.recognizers;
2339
            // run the touch-action polyfill
2340
            this.touchAction.preventDefaults(inputData);
2343 2341
2344
        // this holds the recognizer that is being recognized.
2345
        // so the recognizer's state needs to be BEGAN, CHANGED, ENDED or RECOGNIZED
2346
        // if no recognizer is detecting a thing, it is set to `null`
2347
        var curRecognizer = session.curRecognizer;
2342
            var recognizer;
2343
            var recognizers = this.recognizers;
2348 2344
2349
        // reset when the last recognizer is recognized
2350
        // or when we're in a new session
2351
        if (!curRecognizer || (curRecognizer && curRecognizer.state & STATE_RECOGNIZED)) {
2352
            curRecognizer = session.curRecognizer = null;
2353
        }
2345
            // this holds the recognizer that is being recognized.
2346
            // so the recognizer's state needs to be BEGAN, CHANGED, ENDED or RECOGNIZED
2347
            // if no recognizer is detecting a thing, it is set to `null`
2348
            var curRecognizer = session.curRecognizer;
2354 2349
2355
        var i = 0;
2356
        while (i < recognizers.length) {
2357
            recognizer = recognizers[i];
2358
2359
            // find out if we are allowed try to recognize the input for this one.
2360
            // 1.   allow if the session is NOT forced stopped (see the .stop() method)
2361
            // 2.   allow if we still haven't recognized a gesture in this session, or the this recognizer is the one
2362
            //      that is being recognized.
2363
            // 3.   allow if the recognizer is allowed to run simultaneous with the current recognized recognizer.
2364
            //      this can be setup with the `recognizeWith()` method on the recognizer.
2365
            if (session.stopped !== FORCED_STOP && ( // 1
2366
                    !curRecognizer || recognizer == curRecognizer || // 2
2367
                    recognizer.canRecognizeWith(curRecognizer))) { // 3
2368
                recognizer.recognize(inputData);
2369
            } else {
2370
                recognizer.reset();
2350
            // reset when the last recognizer is recognized
2351
            // or when we're in a new session
2352
            if (!curRecognizer || (curRecognizer && curRecognizer.state & STATE_RECOGNIZED)) {
2353
                curRecognizer = session.curRecognizer = null;
2371 2354
            }
2372 2355
2373
            // if the recognizer has been recognizing the input as a valid gesture, we want to store this one as the
2374
            // current active recognizer. but only if we don't already have an active recognizer
2375
            if (!curRecognizer && recognizer.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED)) {
2376
                curRecognizer = session.curRecognizer = recognizer;
2356
            var i = 0;
2357
            while (i < recognizers.length) {
2358
                recognizer = recognizers[i];
2359
2360
                // find out if we are allowed try to recognize the input for this one.
2361
                // 1.   allow if the session is NOT forced stopped (see the .stop() method)
2362
                // 2.   allow if we still haven't recognized a gesture in this session, or the this recognizer is the one
2363
                //      that is being recognized.
2364
                // 3.   allow if the recognizer is allowed to run simultaneous with the current recognized recognizer.
2365
                //      this can be setup with the `recognizeWith()` method on the s can be setup with the `recognizeWith()` method on the recognizer.
2366
                if (session.stopped !== FORCED_STOP && ( // 1
2367
                  !curRecognizer || recognizer == curRecognizer || // 2
2368
                  recognizer.canRecognizeWith(curRecognizer))) { // 3
2369
                    recognizer.recognize(inputData);
2370
                } else {
2371
                    recognizer.reset();
2372
                }
2373
2374
                // if the recognizer has been recognizing the input as a valid gesture, we want to store this one as the
2375
                // current active recognizer. but only if we don't already have an active recognizer
2376
                if (!curRecognizer && recognizer.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED)) {
2377
                    curRecognizer = session.curRecognizer = recognizer;
2378
                }
2379
                i++;
2377 2380
            }
2378
            i++;
2379
        }
2380
    },
2381
        },
2381 2382
2382
    /**
2383
     * get a recognizer by its event name.
2384
     * @param {Recognizer|String} recognizer
2385
     * @returns {Recognizer|Null}
2386
     */
2387
    get: function(recognizer) {
2388
        if (recognizer instanceof Recognizer) {
2383
        /**
2384
         * get a recognizer by its event name.
2385
         * @param {Recognizer|String} recognizer
2386
         * @returns {Recognizer|Null}
2387
         */
2388
        get: function(recognizer) {
2389
            if (recognizer instanceof Recognizer) {
2390
                return recognizer;
2391
            }
2392
2393
            var recognizers = this.recognizers;
2394
            for (var i = 0; i < recognizers.length; i++) {
2395
                if (recognizers[i].options.event == recognizer) {
2396
                    return recognizers[i];
2397
                }
2398
            }
2399
            return null;
2400
        },
2401
2402
        /**
2403
         * add a recognizer to the manager
2404
         * existing recognizers with the same event name will be removed
2405
         * @param {Recognizer} recognizer
2406
         * @returns {Recognizer|Manager}
2407
         */
2408
        add: function(recognizer) {
2409
            if (invokeArrayArg(recognizer, 'add', this)) {
2410
                return this;
2411
            }
2412
2413
            // remove existing
2414
            var existing = this.get(recognizer.options.event);
2415
            if (existing) {
2416
                this.remove(existing);
2417
            }
2418
2419
            this.recognizers.push(recognizer);
2420
            recognizer.manager = this;
2421
2422
            this.touchAction.update();
2389 2423
            return recognizer;
2390
        }
2424
        },
2391 2425
2392
        var recognizers = this.recognizers;
2393
        for (var i = 0; i < recognizers.length; i++) {
2394
            if (recognizers[i].options.event == recognizer) {
2395
                return recognizers[i];
2426
        /**
2427
         * remove a recognizer by name or instance
2428
         * @param {Recognizer|String} recognizer
2429
         * @returns {Manager}
2430
         */
2431
        remove: function(recognizer) {
2432
            if (invokeArrayArg(recognizer, 'remove', this)) {
2433
                return this;
2434
            }
2435
2436
            recognizer = this.get(recognizer);
2437
2438
            // let's make sure this recognizer exists
2439
            if (recognizer) {
2440
                var recognizers = this.recognizers;
2441
                var index = inArray(recognizers, recognizer);
2442
2443
                if (index !== -1) {
2444
                    recognizers.splice(index, 1);
2445
                    this.touchAction.update();
2446
                }
2396 2447
            }
2397
        }
2398
        return null;
2399
    },
2400 2448
2401
    /**
2402
     * add a recognizer to the manager
2403
     * existing recognizers with the same event name will be removed
2404
     * @param {Recognizer} recognizer
2405
     * @returns {Recognizer|Manager}
2406
     */
2407
    add: function(recognizer) {
2408
        if (invokeArrayArg(recognizer, 'add', this)) {
2409 2449
            return this;
2410
        }
2450
        },
2411 2451
2412
        // remove existing
2413
        var existing = this.get(recognizer.options.event);
2414
        if (existing) {
2415
            this.remove(existing);
2416
        }
2452
        /**
2453
         * bind event
2454
         * @param {String} events
2455
         * @param {Function} handler
2456
         * @returns {EventEmitter} this
2457
         */
2458
        on: function(events, handler) {
2459
            if (events === undefinedVar) {
2460
                return;
2461
            }
2462
            if (handler === undefinedVar) {
2463
                return;
2464
            }
2417 2465
2418
        this.recognizers.push(recognizer);
2419
        recognizer.manager = this;
2466
            var handlers = this.handlers;
2467
            each(splitStr(events), function(event) {
2468
                handlers[event] = handlers[event] || [];
2469
                handlers[event].push(handler);
2470
            });
2471
            return this;
2472
        },
2420 2473
2421
        this.touchAction.update();
2422
        return recognizer;
2423
    },
2474
        /**
2475
         * unbind event, leave emit blank to remove all handlers
2476
         * @param {String} events
2477
         * @param {Function} [handler]
2478
         * @returns {EventEmitter} this
2479
         */
2480
        off: function(events, handler) {
2481
            if (events === undefinedVar) {
2482
                return;
2483
            }
2424 2484
2425
    /**
2426
     * remove a recognizer by name or instance
2427
     * @param {Recognizer|String} recognizer
2428
     * @returns {Manager}
2429
     */
2430
    remove: function(recognizer) {
2431
        if (invokeArrayArg(recognizer, 'remove', this)) {
2485
            var handlers = this.handlers;
2486
            each(splitStr(events), function(event) {
2487
                if (!handler) {
2488
                    delete handlers[event];
2489
                } else {
2490
                    handlers[event] && handlers[event].splice(inArray(handlers[event], handler), 1);
2491
                }
2492
            });
2432 2493
            return this;
2433
        }
2494
        },
2434 2495
2435
        recognizer = this.get(recognizer);
2496
        /**
2497
         * emit event to the listeners
2498
         * @param {String} event
2499
         * @param {Object} data
2500
         */
2501
        emit: function(event, data) {
2502
            // we also want to trigger dom events
2503
            if (this.options.domEvents) {
2504
                triggerDomEvent(event, data);
2505
            }
2436 2506
2437
        // let's make sure this recognizer exists
2438
        if (recognizer) {
2439
            var recognizers = this.recognizers;
2440
            var index = inArray(recognizers, recognizer);
2507
            // no handlers, so skip it all
2508
            var handlers = this.handlers[event] && this.handlers[event].slice();
2509
            if (!handlers || !handlers.length) {
2510
                return;
2511
            }
2441 2512
2442
            if (index !== -1) {
2443
                recognizers.splice(index, 1);
2444
                this.touchAction.update();
2513
            data.type = event;
2514
            data.preventDefault = function() {
2515
                data.srcEvent.preventDefault();
2516
            };
2517
2518
            var i = 0;
2519
            while (i < handlers.length) {
2520
                handlers[i](data);
2521
                i++;
2445 2522
            }
2446
        }
2523
        },
2447 2524
2448
        return this;
2449
    },
2525
        /**
2526
         * destroy the manager and unbinds all events
2527
         * it doesn't unbind dom events, that is the user own responsibility
2528
         */
2529
        destroy: function() {
2530
            this.element && toggleCssProps(this, false);
2450 2531
2451
    /**
2452
     * bind event
2453
     * @param {String} events
2454
     * @param {Function} handler
2455
     * @returns {EventEmitter} this
2456
     */
2457
    on: function(events, handler) {
2458
        if (events === undefined) {
2459
            return;
2460
        }
2461
        if (handler === undefined) {
2462
            return;
2532
            this.handlers = {};
2533
            this.session = {};
2534
            this.input.destroy();
2535
            this.element = null;
2463 2536
        }
2464
2465
        var handlers = this.handlers;
2466
        each(splitStr(events), function(event) {
2467
            handlers[event] = handlers[event] || [];
2468
            handlers[event].push(handler);
2469
        });
2470
        return this;
2471
    },
2537
    };
2472 2538
2473 2539
    /**
2474
     * unbind event, leave emit blank to remove all handlers
2475
     * @param {String} events
2476
     * @param {Function} [handler]
2477
     * @returns {EventEmitter} this
2540
     * add/remove the css properties as defined in manager.options.cssProps
2541
     * @param {Manager} manager
2542
     * @param {Boolean} add
2478 2543
     */
2479
    off: function(events, handler) {
2480
        if (events === undefined) {
2544
    function toggleCssProps(manager, add) {
2545
        var element = manager.element;
2546
        if (!element.style) {
2481 2547
            return;
2482 2548
        }
2483
2484
        var handlers = this.handlers;
2485
        each(splitStr(events), function(event) {
2486
            if (!handler) {
2487
                delete handlers[event];
2549
        var prop;
2550
        each(manager.options.cssProps, function(value, name) {
2551
            prop = prefixed(element.style, name);
2552
            if (add) {
2553
                manager.oldCssProps[prop] = element.style[prop];
2554
                element.style[prop] = value;
2488 2555
            } else {
2489
                handlers[event] && handlers[event].splice(inArray(handlers[event], handler), 1);
2556
                element.style[prop] = manager.oldCssProps[prop] || '';
2490 2557
            }
2491 2558
        });
2492
        return this;
2493
    },
2559
        if (!add) {
2560
            manager.oldCssProps = {};
2561
        }
2562
    }
2494 2563
2495 2564
    /**
2496
     * emit event to the listeners
2565
     * trigger dom event
2497 2566
     * @param {String} event
2498 2567
     * @param {Object} data
2499 2568
     */
2500
    emit: function(event, data) {
2501
        // we also want to trigger dom events
2502
        if (this.options.domEvents) {
2503
            triggerDomEvent(event, data);
2504
        }
2505
2506
        // no handlers, so skip it all
2507
        var handlers = this.handlers[event] && this.handlers[event].slice();
2508
        if (!handlers || !handlers.length) {
2509
            return;
2510
        }
2511
2512
        data.type = event;
2513
        data.preventDefault = function() {
2514
            data.srcEvent.preventDefault();
2515
        };
2516
2517
        var i = 0;
2518
        while (i < handlers.length) {
2519
            handlers[i](data);
2520
            i++;
2521
        }
2522
    },
2523
2524
    /**
2525
     * destroy the manager and unbinds all events
2526
     * it doesn't unbind dom events, that is the user own responsibility
2527
     */
2528
    destroy: function() {
2529
        this.element && toggleCssProps(this, false);
2569
    function triggerDomEvent(event, data) {
2570
        var gestureEvent = document.createEvent('Event');
2571
        gestureEvent.initEvent(event, true, true);
2572
        gestureEvent.gesture = data;
2573
        data.target.dispatchEvent(gestureEvent);
2574
    }
2530 2575
2531
        this.handlers = {};
2532
        this.session = {};
2533
        this.input.destroy();
2534
        this.element = null;
2535
    }
2536
};
2537
2538
/**
2539
 * add/remove the css properties as defined in manager.options.cssProps
2540
 * @param {Manager} manager
2541
 * @param {Boolean} add
2542
 */
2543
function toggleCssProps(manager, add) {
2544
    var element = manager.element;
2545
    if (!element.style) {
2546
        return;
2547
    }
2548
    var prop;
2549
    each(manager.options.cssProps, function(value, name) {
2550
        prop = prefixed(element.style, name);
2551
        if (add) {
2552
            manager.oldCssProps[prop] = element.style[prop];
2553
            element.style[prop] = value;
2554
        } else {
2555
            element.style[prop] = manager.oldCssProps[prop] || '';
2556
        }
2576
    assign(Hammer, {
2577
        INPUT_START: INPUT_START,
2578
        INPUT_MOVE: INPUT_MOVE,
2579
        INPUT_END: INPUT_END,
2580
        INPUT_CANCEL: INPUT_CANCEL,
2581
2582
        STATE_POSSIBLE: STATE_POSSIBLE,
2583
        STATE_BEGAN: STATE_BEGAN,
2584
        STATE_CHANGED: STATE_CHANGED,
2585
        STATE_ENDED: STATE_ENDED,
2586
        STATE_RECOGNIZED: STATE_RECOGNIZED,
2587
        STATE_CANCELLED: STATE_CANCELLED,
2588
        STATE_FAILED: STATE_FAILED,
2589
2590
        DIRECTION_NONE: DIRECTION_NONE,
2591
        DIRECTION_LEFT: DIRECTION_LEFT,
2592
        DIRECTION_RIGHT: DIRECTION_RIGHT,
2593
        DIRECTION_UP: DIRECTION_UP,
2594
        DIRECTION_DOWN: DIRECTION_DOWN,
2595
        DIRECTION_HORIZONTAL: DIRECTION_HORIZONTAL,
2596
        DIRECTION_VERTICAL: DIRECTION_VERTICAL,
2597
        DIRECTION_ALL: DIRECTION_ALL,
2598
2599
        Manager: Manager,
2600
        Input: Input,
2601
        TouchAction: TouchAction,
2602
2603
        TouchInput: TouchInput,
2604
        MouseInput: MouseInput,
2605
        PointerEventInput: PointerEventInput,
2606
        TouchMouseInput: TouchMouseInput,
2607
        SingleTouchInput: SingleTouchInput,
2608
2609
        Recognizer: Recognizer,
2610
        AttrRecognizer: AttrRecognizer,
2611
        Tap: TapRecognizer,
2612
        Pan: PanRecognizer,
2613
        Swipe: SwipeRecognizer,
2614
        Pinch: PinchRecognizer,
2615
        Rotate: RotateRecognizer,
2616
        Press: PressRecognizer,
2617
2618
        on: addEventListeners,
2619
        off: removeEventListeners,
2620
        each: each,
2621
        merge: merge,
2622
        extend: extend,
2623
        assign: assign,
2624
        inherit: inherit,
2625
        bindFn: bindFn,
2626
        prefixed: prefixed
2557 2627
    });
2558
    if (!add) {
2559
        manager.oldCssProps = {};
2560
    }
2561
}
2562
2563
/**
2564
 * trigger dom event
2565
 * @param {String} event
2566
 * @param {Object} data
2567
 */
2568
function triggerDomEvent(event, data) {
2569
    var gestureEvent = document.createEvent('Event');
2570
    gestureEvent.initEvent(event, true, true);
2571
    gestureEvent.gesture = data;
2572
    data.target.dispatchEvent(gestureEvent);
2573
}
2574
2575
assign(Hammer, {
2576
    INPUT_START: INPUT_START,
2577
    INPUT_MOVE: INPUT_MOVE,
2578
    INPUT_END: INPUT_END,
2579
    INPUT_CANCEL: INPUT_CANCEL,
2580
2581
    STATE_POSSIBLE: STATE_POSSIBLE,
2582
    STATE_BEGAN: STATE_BEGAN,
2583
    STATE_CHANGED: STATE_CHANGED,
2584
    STATE_ENDED: STATE_ENDED,
2585
    STATE_RECOGNIZED: STATE_RECOGNIZED,
2586
    STATE_CANCELLED: STATE_CANCELLED,
2587
    STATE_FAILED: STATE_FAILED,
2588
2589
    DIRECTION_NONE: DIRECTION_NONE,
2590
    DIRECTION_LEFT: DIRECTION_LEFT,
2591
    DIRECTION_RIGHT: DIRECTION_RIGHT,
2592
    DIRECTION_UP: DIRECTION_UP,
2593
    DIRECTION_DOWN: DIRECTION_DOWN,
2594
    DIRECTION_HORIZONTAL: DIRECTION_HORIZONTAL,
2595
    DIRECTION_VERTICAL: DIRECTION_VERTICAL,
2596
    DIRECTION_ALL: DIRECTION_ALL,
2597
2598
    Manager: Manager,
2599
    Input: Input,
2600
    TouchAction: TouchAction,
2601
2602
    TouchInput: TouchInput,
2603
    MouseInput: MouseInput,
2604
    PointerEventInput: PointerEventInput,
2605
    TouchMouseInput: TouchMouseInput,
2606
    SingleTouchInput: SingleTouchInput,
2607
2608
    Recognizer: Recognizer,
2609
    AttrRecognizer: AttrRecognizer,
2610
    Tap: TapRecognizer,
2611
    Pan: PanRecognizer,
2612
    Swipe: SwipeRecognizer,
2613
    Pinch: PinchRecognizer,
2614
    Rotate: RotateRecognizer,
2615
    Press: PressRecognizer,
2616
2617
    on: addEventListeners,
2618
    off: removeEventListeners,
2619
    each: each,
2620
    merge: merge,
2621
    extend: extend,
2622
    assign: assign,
2623
    inherit: inherit,
2624
    bindFn: bindFn,
2625
    prefixed: prefixed
2626
});
2627 2628
2628 2629
// this prevents errors when Hammer is loaded in the presence of an AMD
2629 2630
//  style loader but by script tag, not by the loader.
2630
var freeGlobal = (typeof window !== 'undefined' ? window : (typeof self !== 'undefined' ? self : {})); // jshint ignore:line
2631
freeGlobal.Hammer = Hammer;
2631
    var freeGlobal = (typeof window !== 'undefined' ? window : (typeof self !== 'undefined' ? self : {})); // jshint ignore:line
2632
    freeGlobal.Hammer = Hammer;
2632 2633
2633
if (typeof define === 'function' && define.amd) {
2634
    define(function() {
2635
        return Hammer;
2636
    });
2637
} else if (typeof module != 'undefined' && module.exports) {
2638
    module.exports = Hammer;
2639
} else {
2640
    window[exportName] = Hammer;
2641
}
2634
    if (typeof define === 'function' && define.amd) {
2635
        define(function() {
2636
            return Hammer;
2637
        });
2638
    } else if (typeof module != 'undefined' && module.exports) {
2639
        module.exports = Hammer;
2640
    } else {
2641
        window[exportName] = Hammer;
2642
    }
2642 2643
2643
})(window, document, 'Hammer');
2644
})(window, document, 'Hammer');

android-share - Nuosi Git Service

ipu的trunk版的android工程和服务端工程。

spring-jdbc-3.2.8.RELEASE.jar 396KB