westures-core 1.2.1 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -32,8 +32,7 @@ let $de0d6a332419bf3c$var$g_id = 0;
32
32
  * @param {number} [options.maxInputs=Number.MAX_VALUE] - The maximum number of
33
33
  * pointers that may be active for the gesture to be recognized. Uses <=.
34
34
  */ class $de0d6a332419bf3c$var$Gesture {
35
- constructor(type, element, handler, options = {
36
- }){
35
+ constructor(type, element, handler, options = {}){
37
36
  if (typeof type !== 'string') throw new TypeError('Gestures require a string type / name');
38
37
  /**
39
38
  * The name of the gesture. (e.g. 'pan' or 'tap' or 'pinch').
@@ -77,10 +76,8 @@ let $de0d6a332419bf3c$var$g_id = 0;
77
76
  */ isEnabled(state) {
78
77
  const count = state.active.length;
79
78
  const event = state.event;
80
- const { enableKeys: enableKeys , disableKeys: disableKeys , minInputs: minInputs , maxInputs: maxInputs } = this.options;
81
- return minInputs <= count && maxInputs >= count && (enableKeys.length === 0 || enableKeys.some((k)=>event[k]
82
- )) && !disableKeys.some((k)=>event[k]
83
- );
79
+ const { enableKeys: enableKeys, disableKeys: disableKeys, minInputs: minInputs, maxInputs: maxInputs } = this.options;
80
+ return minInputs <= count && maxInputs >= count && (enableKeys.length === 0 || enableKeys.some((k)=>event[k])) && !disableKeys.some((k)=>event[k]);
84
81
  }
85
82
  /**
86
83
  * Event hook for the start phase of a gesture.
@@ -214,8 +211,7 @@ var $6c3676f10a43b740$exports = {};
214
211
  *
215
212
  * @returns {number[]}
216
213
  */ anglesTo(points) {
217
- return points.map((point)=>this.angleTo(point)
218
- );
214
+ return points.map((point)=>this.angleTo(point));
219
215
  }
220
216
  /**
221
217
  * Determine the average distance from this point to the provided array of
@@ -275,8 +271,7 @@ var $6c3676f10a43b740$exports = {};
275
271
  *
276
272
  * @return {number} The total distance from this point to the provided points.
277
273
  */ totalDistanceTo(points) {
278
- return points.reduce((d, p)=>d + this.distanceTo(p)
279
- , 0);
274
+ return points.reduce((d, p)=>d + this.distanceTo(p), 0);
280
275
  }
281
276
  /**
282
277
  * Calculates the centroid of a list of points.
@@ -319,9 +314,10 @@ var $be6f0e84320366a7$exports = {};
319
314
  * @type {string[]}
320
315
  */ const $be6f0e84320366a7$var$CANCEL_EVENTS = [
321
316
  'blur',
317
+ 'contextmenu',
322
318
  'pointercancel',
323
319
  'touchcancel',
324
- 'mouseleave',
320
+ 'mouseleave'
325
321
  ];
326
322
  /**
327
323
  * List of keyboard events that trigger a restart.
@@ -330,7 +326,7 @@ var $be6f0e84320366a7$exports = {};
330
326
  * @type {string[]}
331
327
  */ const $be6f0e84320366a7$var$KEYBOARD_EVENTS = [
332
328
  'keydown',
333
- 'keyup',
329
+ 'keyup'
334
330
  ];
335
331
  /**
336
332
  * List of mouse events to listen to.
@@ -340,7 +336,7 @@ var $be6f0e84320366a7$exports = {};
340
336
  */ const $be6f0e84320366a7$var$MOUSE_EVENTS = [
341
337
  'mousedown',
342
338
  'mousemove',
343
- 'mouseup',
339
+ 'mouseup'
344
340
  ];
345
341
  /**
346
342
  * List of pointer events to listen to.
@@ -350,7 +346,7 @@ var $be6f0e84320366a7$exports = {};
350
346
  */ const $be6f0e84320366a7$var$POINTER_EVENTS = [
351
347
  'pointerdown',
352
348
  'pointermove',
353
- 'pointerup',
349
+ 'pointerup'
354
350
  ];
355
351
  /**
356
352
  * List of touch events to listen to.
@@ -360,7 +356,7 @@ var $be6f0e84320366a7$exports = {};
360
356
  */ const $be6f0e84320366a7$var$TOUCH_EVENTS = [
361
357
  'touchend',
362
358
  'touchmove',
363
- 'touchstart',
359
+ 'touchstart'
364
360
  ];
365
361
  /**
366
362
  * List of potentially state-modifying keys.
@@ -372,7 +368,7 @@ var $be6f0e84320366a7$exports = {};
372
368
  'altKey',
373
369
  'ctrlKey',
374
370
  'metaKey',
375
- 'shiftKey',
371
+ 'shiftKey'
376
372
  ];
377
373
  /**
378
374
  * List of the 'key' values on KeyboardEvent objects of the potentially
@@ -384,7 +380,7 @@ var $be6f0e84320366a7$exports = {};
384
380
  'Alt',
385
381
  'Control',
386
382
  'Meta',
387
- 'Shift',
383
+ 'Shift'
388
384
  ];
389
385
  /**
390
386
  * The cancel phase.
@@ -482,7 +478,7 @@ var $0ca7bfe1c074e8ca$require$PHASE = $be6f0e84320366a7$exports.PHASE;
482
478
  * @param {number} identifier - The index of touch if applicable
483
479
  */ class $0ca7bfe1c074e8ca$var$PointerData {
484
480
  constructor(event, identifier){
485
- const { clientX: clientX , clientY: clientY } = $0ca7bfe1c074e8ca$var$getEventObject(event, identifier);
481
+ const { clientX: clientX, clientY: clientY } = $0ca7bfe1c074e8ca$var$getEventObject(event, identifier);
486
482
  /**
487
483
  * The original event object.
488
484
  *
@@ -575,8 +571,7 @@ const $4559ecf940edc78d$var$PI_NVE = -Math.PI;
575
571
  * @return {Set} Set consisting of elements in 'left' that are not in
576
572
  * 'right'.
577
573
  */ function $4559ecf940edc78d$var$setDifference(left, right) {
578
- return $4559ecf940edc78d$var$setFilter(left, (element)=>!right.has(element)
579
- );
574
+ return $4559ecf940edc78d$var$setFilter(left, (element)=>!right.has(element));
580
575
  }
581
576
  $4559ecf940edc78d$exports = {
582
577
  angularDifference: $4559ecf940edc78d$var$angularDifference,
@@ -598,14 +593,17 @@ var $e2125e2e71e37a0c$require$getPropagationPath = $4559ecf940edc78d$exports.get
598
593
  * @param {number} identifier - The identifier for this input, so that it can
599
594
  * be located in subsequent Event objects.
600
595
  */ class $e2125e2e71e37a0c$var$Input {
601
- constructor(event, identifier){
596
+ constructor(event, identifier, headless = false){
602
597
  const currentData = new $0ca7bfe1c074e8ca$exports(event, identifier);
603
598
  /**
604
599
  * The set of elements along the original event's propagation path at the
605
600
  * time it was dispatched.
606
601
  *
607
602
  * @type {WeakSet.<Element>}
608
- */ this.initialElements = new WeakSet($e2125e2e71e37a0c$require$getPropagationPath(event));
603
+ */ if (headless) this.initialElements = new WeakSet([
604
+ event.target
605
+ ]);
606
+ else this.initialElements = new WeakSet($e2125e2e71e37a0c$require$getPropagationPath(event));
609
607
  /**
610
608
  * Holds the initial data from the mousedown / touchstart / pointerdown that
611
609
  * began this input.
@@ -683,31 +681,14 @@ var $639be6fb478a6d5a$require$END = $be6f0e84320366a7$exports.END;
683
681
  var $639be6fb478a6d5a$require$MOVE = $be6f0e84320366a7$exports.MOVE;
684
682
  var $639be6fb478a6d5a$require$PHASE = $be6f0e84320366a7$exports.PHASE;
685
683
  var $639be6fb478a6d5a$require$START = $be6f0e84320366a7$exports.START;
684
+ var $639be6fb478a6d5a$require$MOUSE_EVENTS = $be6f0e84320366a7$exports.MOUSE_EVENTS;
685
+ var $639be6fb478a6d5a$require$POINTER_EVENTS = $be6f0e84320366a7$exports.POINTER_EVENTS;
686
+ var $639be6fb478a6d5a$require$TOUCH_EVENTS = $be6f0e84320366a7$exports.TOUCH_EVENTS;
686
687
 
687
688
 
688
689
  const $639be6fb478a6d5a$var$symbols = {
689
690
  inputs: Symbol.for('inputs')
690
691
  };
691
- /**
692
- * Set of helper functions for updating inputs based on type of input.
693
- * Must be called with a bound 'this', via bind(), or call(), or apply().
694
- *
695
- * @private
696
- * @inner
697
- * @memberof westure-core.State
698
- */ const $639be6fb478a6d5a$var$update_fns = {
699
- TouchEvent: function TouchEvent(event) {
700
- Array.from(event.changedTouches).forEach((touch)=>{
701
- this.updateInput(event, touch.identifier);
702
- });
703
- },
704
- PointerEvent: function PointerEvent(event) {
705
- this.updateInput(event, event.pointerId);
706
- },
707
- MouseEvent: function MouseEvent(event) {
708
- if (event.button === 0) this.updateInput(event, event.button);
709
- }
710
- };
711
692
  /**
712
693
  * Keeps track of currently active and ending input points on the interactive
713
694
  * surface.
@@ -715,14 +696,21 @@ const $639be6fb478a6d5a$var$symbols = {
715
696
  * @memberof westures-core
716
697
  *
717
698
  * @param {Element} element - The element underpinning the associated Region.
699
+ * @param {boolean} [headless=false] - Whether westures is operating in
700
+ * "headless" mode.
718
701
  */ class $639be6fb478a6d5a$var$State {
719
- constructor(element){
702
+ constructor(element, headless = false){
720
703
  /**
721
704
  * Keep a reference to the element for the associated region.
722
705
  *
723
706
  * @type {Element}
724
707
  */ this.element = element;
725
708
  /**
709
+ * Whether westures is operating in "headless" mode.
710
+ *
711
+ * @type {boolean}
712
+ */ this.headless = headless;
713
+ /**
726
714
  * Keeps track of the current Input objects.
727
715
  *
728
716
  * @alias [@@inputs]
@@ -747,11 +735,11 @@ const $639be6fb478a6d5a$var$symbols = {
747
735
  * @type {westures-core.Point2D[]}
748
736
  */ this.activePoints = [];
749
737
  /**
750
- * The centroid of the currently active points.
738
+ * The centroid of the currently active points, or null when there are no
739
+ * active inputs (such as during the final end event).
751
740
  *
752
- * @type {westures-core.Point2D}
753
- */ this.centroid = {
754
- };
741
+ * @type {?westures-core.Point2D}
742
+ */ this.centroid = null;
755
743
  /**
756
744
  * The latest event that the state processed.
757
745
  *
@@ -770,16 +758,14 @@ const $639be6fb478a6d5a$var$symbols = {
770
758
  *
771
759
  * @return {westures-core.Input[]} Inputs in the given phase.
772
760
  */ getInputsInPhase(phase) {
773
- return this.inputs.filter((i)=>i.phase === phase
774
- );
761
+ return this.inputs.filter((i)=>i.phase === phase);
775
762
  }
776
763
  /**
777
764
  * @param {string} phase - One of 'start', 'move', 'end', or 'cancel'.
778
765
  *
779
766
  * @return {westures-core.Input[]} Inputs <b>not</b> in the given phase.
780
767
  */ getInputsNotInPhase(phase) {
781
- return this.inputs.filter((i)=>i.phase !== phase
782
- );
768
+ return this.inputs.filter((i)=>i.phase !== phase);
783
769
  }
784
770
  /**
785
771
  * @return {boolean} True if there are no active inputs. False otherwise.
@@ -796,8 +782,8 @@ const $639be6fb478a6d5a$var$symbols = {
796
782
  */ updateInput(event, identifier) {
797
783
  switch($639be6fb478a6d5a$require$PHASE[event.type]){
798
784
  case $639be6fb478a6d5a$require$START:
799
- this[$639be6fb478a6d5a$var$symbols.inputs].set(identifier, new $e2125e2e71e37a0c$exports(event, identifier));
800
- try {
785
+ this[$639be6fb478a6d5a$var$symbols.inputs].set(identifier, new $e2125e2e71e37a0c$exports(event, identifier, this.headless));
786
+ if (!this.headless) try {
801
787
  this.element.setPointerCapture(identifier);
802
788
  } catch (e) {
803
789
  // NOP: Optional operation failed.
@@ -806,9 +792,9 @@ const $639be6fb478a6d5a$var$symbols = {
806
792
  // All of 'end', 'move', and 'cancel' perform updates, hence the
807
793
  // following fall-throughs
808
794
  case $639be6fb478a6d5a$require$END:
809
- try {
795
+ if (!this.headless) try {
810
796
  this.element.releasePointerCapture(identifier);
811
- } catch (e1) {
797
+ } catch (e) {
812
798
  // NOP: Optional operation failed.
813
799
  }
814
800
  case $639be6fb478a6d5a$require$CANCEL:
@@ -825,7 +811,13 @@ const $639be6fb478a6d5a$var$symbols = {
825
811
  * @private
826
812
  * @param {Event} event - The event being captured.
827
813
  */ updateAllInputs(event) {
828
- $639be6fb478a6d5a$var$update_fns[event.constructor.name].call(this, event);
814
+ if ($639be6fb478a6d5a$require$POINTER_EVENTS.includes(event.type)) this.updateInput(event, event.pointerId);
815
+ else if ($639be6fb478a6d5a$require$MOUSE_EVENTS.includes(event.type)) {
816
+ if (event.button === 0) this.updateInput(event, event.button);
817
+ } else if ($639be6fb478a6d5a$require$TOUCH_EVENTS.includes(event.type)) Array.from(event.changedTouches).forEach((touch)=>{
818
+ this.updateInput(event, touch.identifier);
819
+ });
820
+ else throw new Error(`Unexpected event type: ${event.type}`);
829
821
  this.updateFields(event);
830
822
  }
831
823
  /**
@@ -836,8 +828,7 @@ const $639be6fb478a6d5a$var$symbols = {
836
828
  */ updateFields(event) {
837
829
  this.inputs = Array.from(this[$639be6fb478a6d5a$var$symbols.inputs].values());
838
830
  this.active = this.getInputsNotInPhase('end');
839
- this.activePoints = this.active.map((i)=>i.current.point
840
- );
831
+ this.activePoints = this.active.map((i)=>i.current.point);
841
832
  this.centroid = $6c3676f10a43b740$exports.centroid(this.activePoints);
842
833
  this.event = event;
843
834
  }
@@ -865,8 +856,9 @@ var $b66a0f22c18e3e3d$require$setFilter = $4559ecf940edc78d$exports.setFilter;
865
856
  *
866
857
  * @memberof westures-core
867
858
  *
868
- * @param {Element} element=window - The element which should listen to input
869
- * events.
859
+ * @param {Element} [element=null] - The element which should listen to input
860
+ * events. If not provided, will be set to the window unless operating in
861
+ * "headless" mode.
870
862
  * @param {object} [options]
871
863
  * @param {boolean} [options.capture=false] - Whether the region uses the
872
864
  * capture phase of input events. If false, uses the bubbling phase.
@@ -877,13 +869,26 @@ var $b66a0f22c18e3e3d$require$setFilter = $4559ecf940edc78d$exports.setFilter;
877
869
  * ignored. Here there by dragons if set to false.
878
870
  * @param {string} [options.touchAction='none'] - Value to set the CSS
879
871
  * 'touch-action' property to on elements added to the region.
872
+ * @param {boolean} [options.headless=false] - Set to true to turn on "headless"
873
+ * mode. This mode is intended for use outside of a browser environment. It does
874
+ * not listen to window events, so instead you will have to send events directly
875
+ * into the region. Pointer down/move/up events should be sent to
876
+ * Region.arbitrate(event), cancel events should be sent to
877
+ * Region.cancel(event), and keyboard events should be sent to
878
+ * Region.handleKeyboardEvent(event). You do not need to supply an element to
879
+ * the Region constructor in this mode, but you will still need to attach
880
+ * elements to Gestures, and the events you pass in should specify event.target
881
+ * appropriately, in order to select which gestures to run.
880
882
  */ class $b66a0f22c18e3e3d$var$Region {
881
- constructor(element = window, options = {
882
- }){
883
+ constructor(element = null, options = {}){
883
884
  options = {
884
885
  ...$b66a0f22c18e3e3d$var$Region.DEFAULTS,
885
886
  ...options
886
887
  };
888
+ if (element === null) {
889
+ if (options.headless) element = null;
890
+ else element = window;
891
+ }
887
892
  /**
888
893
  * The list of relations between elements, their gestures, and the handlers.
889
894
  *
@@ -914,8 +919,8 @@ var $b66a0f22c18e3e3d$require$setFilter = $4559ecf940edc78d$exports.setFilter;
914
919
  * The internal state object for a Region. Keeps track of inputs.
915
920
  *
916
921
  * @type {westures-core.State}
917
- */ this.state = new $639be6fb478a6d5a$exports(this.element);
918
- // Begin operating immediately.
922
+ */ this.state = new $639be6fb478a6d5a$exports(this.element, options.headless);
923
+ if (!options.headless) // Begin operating immediately.
919
924
  this.activate();
920
925
  }
921
926
  /**
@@ -937,9 +942,7 @@ var $b66a0f22c18e3e3d$require$setFilter = $4559ecf940edc78d$exports.setFilter;
937
942
  * https://www.html5rocks.com/en/mobile/touchandmouse/
938
943
  * https://developer.mozilla.org/en-US/docs/Web/API/Touch_events
939
944
  * https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events
940
- */ let eventNames = [];
941
- if (this.options.preferPointer && window.PointerEvent) eventNames = $b66a0f22c18e3e3d$require$POINTER_EVENTS;
942
- else eventNames = $b66a0f22c18e3e3d$require$MOUSE_EVENTS.concat($b66a0f22c18e3e3d$require$TOUCH_EVENTS);
945
+ */ const eventNames = this.options.preferPointer && window.PointerEvent ? $b66a0f22c18e3e3d$require$POINTER_EVENTS : $b66a0f22c18e3e3d$require$MOUSE_EVENTS.concat($b66a0f22c18e3e3d$require$TOUCH_EVENTS);
943
946
  // Bind detected browser events to the region element.
944
947
  const arbitrate = this.arbitrate.bind(this);
945
948
  eventNames.forEach((eventName)=>{
@@ -965,14 +968,14 @@ var $b66a0f22c18e3e3d$require$setFilter = $4559ecf940edc78d$exports.setFilter;
965
968
  * @private
966
969
  * @param {Event} event - The event emitted from the window object.
967
970
  */ cancel(event) {
968
- if (this.options.preventDefault) event.preventDefault();
971
+ if (this.options.preventDefault && typeof event.preventDefault === 'function') event.preventDefault();
969
972
  this.state.inputs.forEach((input)=>{
970
973
  input.update(event);
971
974
  });
972
975
  this.activeGestures.forEach((gesture)=>{
973
976
  gesture.evaluateHook($b66a0f22c18e3e3d$require$CANCEL, this.state);
974
977
  });
975
- this.state = new $639be6fb478a6d5a$exports(this.element);
978
+ this.state = new $639be6fb478a6d5a$exports(this.element, this.options.headless);
976
979
  this.resetActiveGestures();
977
980
  }
978
981
  /**
@@ -1057,7 +1060,7 @@ var $b66a0f22c18e3e3d$require$setFilter = $4559ecf940edc78d$exports.setFilter;
1057
1060
  this.state.updateAllInputs(event);
1058
1061
  this.updateActiveGestures(event, isInitial);
1059
1062
  if (this.activeGestures.size > 0) {
1060
- if (this.options.preventDefault) event.preventDefault();
1063
+ if (this.options.preventDefault && typeof event.preventDefault === 'function') event.preventDefault();
1061
1064
  this.activeGestures.forEach((gesture)=>{
1062
1065
  gesture.evaluateHook($b66a0f22c18e3e3d$require$PHASE[event.type], this.state);
1063
1066
  });
@@ -1070,7 +1073,7 @@ var $b66a0f22c18e3e3d$require$setFilter = $4559ecf940edc78d$exports.setFilter;
1070
1073
  *
1071
1074
  * @param {westures-core.Gesture} gesture - Instantiated gesture to add.
1072
1075
  */ addGesture(gesture) {
1073
- gesture.element.style.touchAction = this.options.touchAction;
1076
+ if (!this.options.headless) gesture.element.style.touchAction = this.options.touchAction;
1074
1077
  this.gestures.add(gesture);
1075
1078
  }
1076
1079
  /**
@@ -1089,23 +1092,22 @@ var $b66a0f22c18e3e3d$require$setFilter = $4559ecf940edc78d$exports.setFilter;
1089
1092
  *
1090
1093
  * @return {westures-core.Gesture[]} Gestures to which the element is bound.
1091
1094
  */ getGesturesByElement(element) {
1092
- return $b66a0f22c18e3e3d$require$setFilter(this.gestures, (gesture)=>gesture.element === element
1093
- );
1095
+ return $b66a0f22c18e3e3d$require$setFilter(this.gestures, (gesture)=>gesture.element === element);
1094
1096
  }
1095
1097
  /**
1096
1098
  * Remove all gestures bound to the given element.
1097
1099
  *
1098
1100
  * @param {Element} element - The element to unbind.
1099
1101
  */ removeGesturesByElement(element) {
1100
- this.getGesturesByElement(element).forEach((g)=>this.removeGesture(g)
1101
- );
1102
+ this.getGesturesByElement(element).forEach((g)=>this.removeGesture(g));
1102
1103
  }
1103
1104
  }
1104
1105
  $b66a0f22c18e3e3d$var$Region.DEFAULTS = {
1105
1106
  capture: false,
1106
1107
  preferPointer: true,
1107
1108
  preventDefault: true,
1108
- touchAction: 'none'
1109
+ touchAction: 'none',
1110
+ headless: false
1109
1111
  };
1110
1112
  $b66a0f22c18e3e3d$exports = $b66a0f22c18e3e3d$var$Region;
1111
1113
 
@@ -1162,8 +1164,7 @@ const $01c3d7b128023e4f$var$smooth = Symbol('smooth');
1162
1164
  * the data.
1163
1165
  * @param {*} [options.identity=0] The identity value of this smoothable data.
1164
1166
  */ class $01c3d7b128023e4f$var$Smoothable {
1165
- constructor(options = {
1166
- }){
1167
+ constructor(options = {}){
1167
1168
  const final_options = {
1168
1169
  ...$01c3d7b128023e4f$var$Smoothable.DEFAULTS,
1169
1170
  ...options
@@ -1177,8 +1178,7 @@ const $01c3d7b128023e4f$var$smooth = Symbol('smooth');
1177
1178
  * @return {*} The smoothed out data.
1178
1179
  */ this.next = null;
1179
1180
  if ($01c3d7b128023e4f$var$smoothingIsApplicable(final_options.applySmoothing)) this.next = this[$01c3d7b128023e4f$var$smooth].bind(this);
1180
- else this.next = (data)=>data
1181
- ;
1181
+ else this.next = (data)=>data;
1182
1182
  /**
1183
1183
  * The "identity" value of the data that will be smoothed.
1184
1184
  *