| define(
  'tinymce.themes.mobile.ios.view.IosKeyboard',
  [
    'ephox.katamari.api.Arr',
    'ephox.katamari.api.Fun',
    'ephox.sugar.api.dom.Focus',
    'ephox.sugar.api.events.DomEvent',
    'ephox.sugar.api.node.Body',
    'ephox.sugar.api.node.Node',
    'tinymce.themes.mobile.ios.focus.ResumeEditing',
    'tinymce.themes.mobile.util.CaptureBin'
  ],
  function (Arr, Fun, Focus, DomEvent, Body, Node, ResumeEditing, CaptureBin) {
    /*
     * Stubborn IOS Keyboard mode:
     *
     * The keyboard will stubbornly refuse to go away. The only time it will go away is when toReading
     * is called (which is currently only used by the insert image button). It will probably go away
     * at other times, but we never explicitly try to make it go away.
     *
     * The major problem with not dismissing the keyboard when the user presses the toolbar is that
     * the input focus can be put in some very interesting things. Once the input focus is in something
     * that is not the content or an input that the user can clearly see, behaviour gets very strange
     * very quickly. The Stubborn keyboard tries to resolve this issue in a few ways:
     *
     * 1. After scrolling the toolbar, it resumes editing of the content. This has the built-in assumption
     * that there are no slick toolbars that require scrolling AND input focus
     * 2. Any time a keydown is received on the outer page, we resume editing of the content. What this means
     * is that in situations where the user has still managed to get into the toolbar (e.g. they typed while
     * the dropdown was visible, or the insert image toReading didn't quite work etc.), then the first keystroke
     * sends the input back to the content, and then subsequent keystrokes appear in the content. Although
     * this means that their first keystroke is lost, it is a reasonable way of ensuring that they don't
     * get stuck in some weird input somewhere. The goal of the stubborn keyboard is to view this as a
     * fallback ... we want to prevent it getting to this state wherever possible. However, there are just
     * some situations where we really don't know what typing on the keyboard should do (e.g. a dropdown is open).
     * Note, when we transfer the focus back to the content, we also close any menus that are still visible.
     *
     * Now, because in WebView mode, the actual window is shrunk when the keyboard appears, the dropdown vertical
     * scrolling is set to the right height. However, when running as a webapp, this won't be the case. To use
     * the stubborn keyboard in webapp mode, we will need to find some way to let repartee know the MaxHeight
     * needs to exclude the keyboard. This isn't a problem with timid, because the keyboard is dismissed.
     */
    var stubborn = function (outerBody, cWin, page, frame/*, toolstrip, toolbar*/) {
      var toEditing = function () {
        ResumeEditing.resume(cWin, frame);
      };
      var toReading = function () {
        CaptureBin.input(outerBody, Focus.blur);
      };
      var captureInput = DomEvent.bind(page, 'keydown', function (evt) {
        // Think about killing the event.
        if (! Arr.contains([ 'input', 'textarea' ], Node.name(evt.target()))) {
          // FIX: Close the menus
          // closeMenus()
          toEditing();
        }
      });
      var onToolbarTouch = function (/* event */) {
        // Do nothing
      };
      var destroy = function () {
        captureInput.unbind();
      };
      return {
        toReading: toReading,
        toEditing: toEditing,
        onToolbarTouch: onToolbarTouch,
        destroy: destroy
      };
    };
    /*
     * Timid IOS Keyboard mode:
     *
     * In timid mode, the keyboard will be dismissed as soon as the toolbar is clicked. In lot of
     * situations, it will then quickly reappear is toEditing is called. The timid mode is safe,
     * but can be very jarring.
     *
     * One situation that the timid mode does not handle is when in a WebView, if the user has
     * scrolled to the bottom of the content and is editing it, as soon as they click on a formatting
     * operation, the keyboard will be dismissed, and the content will visibly jump back down to
     * the bottom of the screen (because the increased window size has decreased the amount of
     * scrolling available). As soon as the formatting operation is completed (which can be
     * instantaneously for something like bold), then the keyboard reappears and the content
     * jumps again. It's very jarring and there's not much we can do (I think).
     *
     * However, the timid keyboard mode will seamlessly integrate with dropdowns max-height, because
     * dropdowns dismiss the keyboard, so they have all the height they require.
     */
    var timid = function (outerBody, cWin, page, frame/*, toolstrip, toolbar*/) {
      var dismissKeyboard = function () {
        Focus.blur(frame);
      };
      var onToolbarTouch = function () {
        dismissKeyboard();
      };
      var toReading = function () {
        dismissKeyboard();
      };
      var toEditing = function () {
        ResumeEditing.resume(cWin, frame);
      };
      return {
        toReading: toReading,
        toEditing: toEditing,
        onToolbarTouch: onToolbarTouch,
        destroy: Fun.noop
      };
    };
    return {
      stubborn: stubborn,
      timid: timid
    };
  }
);
 |