import * as is      from '@interactjs/utils/is';
import events       from '@interactjs/utils/events';
import browser      from '@interactjs/utils/browser';

import { nodeContains, matchesSelector } from '@interactjs/utils/domUtils';
import { getWindow } from '@interactjs/utils/window';

function preventDefault (interactable, newValue) {
  if (/^(always|never|auto)$/.test(newValue)) {
    interactable.options.preventDefault = newValue;
    return interactable;
  }

  if (is.bool(newValue)) {
    interactable.options.preventDefault = newValue? 'always' : 'never';
    return interactable;
  }

  return interactable.options.preventDefault;
}

function checkAndPreventDefault (interactable, scope, event) {
  const setting = interactable.options.preventDefault;

  if (setting === 'never') { return; }

  if (setting === 'always') {
    event.preventDefault();
    return;
  }

  // setting === 'auto'

  // don't preventDefault of touch{start,move} events if the browser supports passive
  // events listeners. CSS touch-action and user-selecct should be used instead
  if (events.supportsPassive
    && /^touch(start|move)$/.test(event.type)
    && !browser.isIOS) {
    const docOptions = scope.getDocIndex(getWindow(event.target).document);

    if (!(docOptions && docOptions.events) || docOptions.events.passive !== false) {
      return;
    }
  }

  // don't preventDefault of pointerdown events
  if (/^(mouse|pointer|touch)*(down|start)/i.test(event.type)) {
    return;
  }

  // don't preventDefault on editable elements
  if (is.element(event.target)
      && matchesSelector(event.target, 'input,select,textarea,[contenteditable=true],[contenteditable=true] *')) {
    return;
  }

  event.preventDefault();
}

function onInteractionEvent ({ interaction, event }) {
  if (interaction.target) {
    interaction.target.checkAndPreventDefault(event);
  }
}

export function init (scope) {
  /** @lends Interactable */
  const Interactable = scope.Interactable;
  /**
   * Returns or sets whether to prevent the browser's default behaviour in
   * response to pointer events. Can be set to:
   *  - `'always'` to always prevent
   *  - `'never'` to never prevent
   *  - `'auto'` to let interact.js try to determine what would be best
   *
   * @param {string} [newValue] `true`, `false` or `'auto'`
   * @return {string | Interactable} The current setting or this Interactable
   */
  Interactable.prototype.preventDefault = function (newValue) {
    return preventDefault(this, newValue);
  };

  Interactable.prototype.checkAndPreventDefault = function (event) {
    return checkAndPreventDefault(this, scope, event);
  };

  for (const eventSignal of ['down', 'move', 'up', 'cancel']) {
    scope.interactions.signals.on(eventSignal, onInteractionEvent);
  }

  // prevent native HTML5 drag on interact.js target elements
  scope.interactions.eventMap.dragstart = function preventNativeDrag (event) {
    for (const interaction of scope.interactions.list) {

      if (interaction.element
        && (interaction.element === event.target
          || nodeContains(interaction.element, event.target))) {

        interaction.target.checkAndPreventDefault(event);
        return;
      }
    }
  };
}

export default { init };

@@ -8,21 +8,16 @@
 * as is 
-     
 from '@i
@@ -51,22 +51,16 @@
  events 
-      
 from '@i
@@ -87,62 +87,8 @@
 ts';
-%0Aimport browser      from '@interactjs/utils/browser';
 %0A%0Aim
@@ -843,109 +843,134 @@
  // 
-don't preventDefault of touch%7Bstart,move%7D events if the browser supports passive%0A  // events listener
+if the browser supports passive event listeners and isn't running on iOS,%0A  // don't preventDefault of touch%7Bstart,move%7D event
 s. C
@@ -988,16 +988,21 @@
 tion and
+%0A  //
  user-se
@@ -1004,17 +1004,16 @@
 er-selec
-c
 t should
@@ -1028,16 +1028,51 @@
  instead
+ of calling event.preventDefault().
 %0A  if (e
@@ -1092,20 +1092,16 @@
 sPassive
-%0A   
  && /%5Eto
@@ -1138,107 +1138,108 @@
 ype)
+) %7B
 %0A    
-&& !browser.isIOS) %7B%0A    const docOptions = scope.getDocIndex(getWindow(event.target).document
+const doc = getWindow(event.target).document;%0A    const docOptions = scope.getDocOptions(doc
 );%0A%0A
@@ -2279,21 +2279,27 @@
 e%5D %60
-true%60, %60false
+'always'%60, %60'never'
 %60 or

use doc options