/**
 * Copyright 2013-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactErrorUtils
 */

'use strict';

var SyntheticDragEvent = require('SyntheticDragEvent');

var caughtError = null;

/**
 * Call a function while guarding against errors that happens within it.
 *
 * @param {?String} name of the guard to use for logging or debugging
 * @param {Function} func The function to invoke
 * @param {*} a First argument
 * @param {*} b Second argument
 */
function invokeGuardedCallback(name, func, a, b) {
  try {
    return func(a, b);
  } catch (x) {
    if (caughtError === null) {
      caughtError = x;
    }
    return undefined;
  }
}

var ReactErrorUtils = {
  invokeGuardedCallback: invokeGuardedCallback,

  /**
   * Invoked by ReactTestUtils.Simulate so that any errors thrown by the event
   * handler are sure to be rethrown by rethrowCaughtError.
   */
  invokeGuardedCallbackWithCatch: invokeGuardedCallback,

  /**
   * During execution of guarded functions we will capture the first error which
   * we will rethrow to be handled by the top level error handler.
   */
  rethrowCaughtError: function() {
    if (caughtError) {
      var error = caughtError;
      caughtError = null;
      throw error;
    }
  },
};

if (__DEV__) {
  /**
   * To help development we can get better devtools integration by simulating a
   * real browser event.
   */
  if (typeof window !== 'undefined' &&
      typeof window.dispatchEvent === 'function' &&
      typeof document !== 'undefined' &&
      typeof document.createEvent === 'function') {
    var fakeNode = document.createElement('react');
    ReactErrorUtils.invokeGuardedCallback = function(name, func, a, b) {
      if (!canWrapEvent(a)) {
        invokeGuardedCallback(name, func, a, b);
        return;
      }

      var boundFunc = func.bind(null, a, b);
      var evtType = `react-${name}`;
      fakeNode.addEventListener(evtType, boundFunc, false);
      var evt = document.createEvent('Event');
      evt.initEvent(evtType, false, false);
      fakeNode.dispatchEvent(evt);
      fakeNode.removeEventListener(evtType, boundFunc, false);
    };
  }

  var cacheCanWrapEvent = null;

  /**
   * IE and Edge don't allow access to the DataTransfer.dropEffect property when
   * it's wrapped in another event. This function detects whether we're in an
   * environment that behaves this way.
   *
   * @param {*} ev Event that is being tested
   */
  function canWrapEvent(ev) {
    if (!(ev instanceof SyntheticDragEvent)) {
      return true;
    } else if (cacheCanWrapEvent !== null) {
      return cacheCanWrapEvent;
    }

    var canAccessDropEffect = false;
    function handleWrappedEvent() {
      try {
        ev.dataTransfer.dropEffect; // eslint-disable-line no-unused-expressions
        canAccessDropEffect = true;
      } catch (e) {}
    }

    var wrappedEventName = 'react-wrappeddragevent';
    var wrappedEvent = document.createEvent('Event');
    wrappedEvent.initEvent(wrappedEventName, false, false);
    fakeNode.addEventListener(wrappedEventName, handleWrappedEvent, false);
    fakeNode.dispatchEvent(wrappedEvent);
    fakeNode.removeEventListener(wrappedEventName, handleWrappedEvent, false);

    cacheCanWrapEvent = canAccessDropEffect;
    return canAccessDropEffect;
  }
}

module.exports = ReactErrorUtils;

@@ -356,65 +356,8 @@
 ';%0A%0A
-var SyntheticDragEvent = require('SyntheticDragEvent');%0A%0A
 var 
@@ -376,16 +376,16 @@
 = null;%0A
+
 %0A/**%0A * 
@@ -1867,112 +1867,8 @@
 ) %7B%0A
-      if (!canWrapEvent(a)) %7B%0A        invokeGuardedCallback(name, func, a, b);%0A        return;%0A      %7D%0A%0A
     
@@ -2190,24 +2190,24 @@
 nc, false);%0A
+
     %7D;%0A  %7D%0A%0A
@@ -2208,1160 +2208,8 @@
 %0A  %7D
-%0A%0A  var cacheCanWrapEvent = null;%0A%0A  /**%0A   * IE and Edge don't allow access to the DataTransfer.dropEffect property when%0A   * it's wrapped in another event. This function detects whether we're in an%0A   * environment that behaves this way.%0A   *%0A   * @param %7B*%7D ev Event that is being tested%0A   */%0A  function canWrapEvent(ev) %7B%0A    if (!(ev instanceof SyntheticDragEvent)) %7B%0A      return true;%0A    %7D else if (cacheCanWrapEvent !== null) %7B%0A      return cacheCanWrapEvent;%0A    %7D%0A%0A    var canAccessDropEffect = false;%0A    function handleWrappedEvent() %7B%0A      try %7B%0A        ev.dataTransfer.dropEffect; // eslint-disable-line no-unused-expressions%0A        canAccessDropEffect = true;%0A      %7D catch (e) %7B%7D%0A    %7D%0A%0A    var wrappedEventName = 'react-wrappeddragevent';%0A    var wrappedEvent = document.createEvent('Event');%0A    wrappedEvent.initEvent(wrappedEventName, false, false);%0A    fakeNode.addEventListener(wrappedEventName, handleWrappedEvent, false);%0A    fakeNode.dispatchEvent(wrappedEvent);%0A    fakeNode.removeEventListener(wrappedEventName, handleWrappedEvent, false);%0A%0A    cacheCanWrapEvent = canAccessDropEffect;%0A    return canAccessDropEffect;%0A  %7D
 %0A%7D%0A%0A

Revert "Don't wrap drag events in IE/Edge in dev builds" (#6741)