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
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;
2354
            }
2355
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 recognizer.
2366
                if (session.stopped !== FORCED_STOP && ( // 1
2366 2367
                    !curRecognizer || recognizer == curRecognizer || // 2
2367 2368
                    recognizer.canRecognizeWith(curRecognizer))) { // 3
2368
                recognizer.recognize(inputData);
2369
            } else {
2370
                s can be setup with the `recognizeWith()` method on the recognizer.reset();
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++;
2371 2380
            }
2381
        },
2372 2382
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;
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;
2377 2391
            }
2378
            i++;
2379
        }
2380
    },
2381 2392
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) {
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 2644
})(window, document, 'Hammer');

+ 1 - 1
ipuui/ipu/dist/js/ipu.js

@ -1316,7 +1316,7 @@
1316 1316
    };
1317 1317
    ipu.closeModal = function (modal) {
1318 1318
        modal = $(modal || '.ipu-modal-in');
1319
        if (typeof modal !== 'undefined' && modal.length === 0) {
1319
        if (typeof modalObj === 'undefined' || modalObj == null || (typeof modalObj !== 'undefined' && modalObj.length === 0)) {
1320 1320
            return;
1321 1321
        }
1322 1322
        var isModal = modal.hasClass('ipu-modal'),

code-example - Nuosi Git Service

团队对封装组件的代码范例

liutong3 69fef4d69a 添加注释 5 年之前
..
src 69fef4d69a 添加注释 5 年之前
.gitignore cbfab71f08 gitignore调整 5 年之前
pom.xml 69fef4d69a 添加注释 5 年之前
ipu/ios-share - Nuosi Git Service

2 Commitit (819e0481c1d1a0cd0c016dd5350992b3600898f0)

Tekijä SHA1 Viesti Päivämäärä
  huangbo 819e0481c1 更新 9 vuotta sitten
  huangbo 8ed9de5908 初始化 9 vuotta sitten