define([
  '../core',
  '../manipulation', // appendTo
], function(jQuery) {
  var iframe,
    elemdisplay = {};

  /**
   * Retrieve the actual display of a element
   * @param {String} name nodeName of the element
   * @param {Object} doc Document object
   */
  // Called only from within defaultDisplay
  function actualDisplay(name, doc) {
    var style,
      elem = jQuery(doc.createElement(name)).appendTo(doc.body),
      // getDefaultComputedStyle might be reliably used only on attached element
      display =
        window.getDefaultComputedStyle &&
        (style = window.getDefaultComputedStyle(elem[0]))
          ? // Use of this method is a temporary fix (more like optimization) until something better comes along,
            // since it was removed from specification and supported only in FF
            style.display
          : jQuery.css(elem[0], 'display');

    // We don't have any data stored on the element,
    // so use "detach" method as fast way to get rid of the element
    elem.detach();

    return display;
  }

  /**
   * Try to determine the default display value of an element
   * @param {String} nodeName
   */
  function defaultDisplay(nodeName) {
    var doc = document,
      display = elemdisplay[nodeName];

    if (!display) {
      display = actualDisplay(nodeName, doc);

      // If the simple way fails, read from inside an iframe
      if (display === 'none' || !display) {
        // Use the already-created iframe if possible
        iframe = (
          iframe || jQuery("<iframe frameborder='0' width='0' height='0'/>")
        ).appendTo(doc.documentElement);

        // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
        doc = iframe[0].contentDocument;

        // Support: IE
        doc.write();
        doc.close();

        display = actualDisplay(nodeName, doc);
        iframe.detach();
      }

      // Store the correct default display
      elemdisplay[nodeName] = display;
    }

    return display;
  }

  return defaultDisplay;
});
