| /**
 * Actions.js
 *
 * Released under LGPL License.
 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
 *
 * License: http://www.tinymce.com/license
 * Contributing: http://www.tinymce.com/contributing
 */
define(
  'tinymce.plugins.imagetools.core.Actions',
  [
    'ephox.imagetools.api.BlobConversions',
    'ephox.imagetools.api.ImageTransformations',
    'ephox.imagetools.api.ResultConversions',
    'ephox.katamari.api.Fun',
    'ephox.sand.api.URL',
    'global!clearTimeout',
    'tinymce.core.util.Delay',
    'tinymce.core.util.Promise',
    'tinymce.core.util.Tools',
    'tinymce.core.util.URI',
    'tinymce.plugins.imagetools.api.Settings',
    'tinymce.plugins.imagetools.core.ImageSize',
    'tinymce.plugins.imagetools.core.Proxy',
    'tinymce.plugins.imagetools.ui.Dialog'
  ],
  function (BlobConversions, ImageTransformations, ResultConversions, Fun, URL, clearTimeout, Delay, Promise, Tools, URI, Settings, ImageSize, Proxy, Dialog) {
    var count = 0;
    var isEditableImage = function (editor, img) {
      var selectorMatched = editor.dom.is(img, 'img:not([data-mce-object],[data-mce-placeholder])');
      return selectorMatched && (isLocalImage(editor, img) || isCorsImage(editor, img) || editor.settings.imagetools_proxy);
    };
    var displayError = function (editor, error) {
      editor.notificationManager.open({
        text: error,
        type: 'error'
      });
    };
    var getSelectedImage = function (editor) {
      return editor.selection.getNode();
    };
    var extractFilename = function (editor, url) {
      var m = url.match(/\/([^\/\?]+)?\.(?:jpeg|jpg|png|gif)(?:\?|$)/i);
      if (m) {
        return editor.dom.encode(m[1]);
      }
      return null;
    };
    var createId = function () {
      return 'imagetools' + count++;
    };
    var isLocalImage = function (editor, img) {
      var url = img.src;
      return url.indexOf('data:') === 0 || url.indexOf('blob:') === 0 || new URI(url).host === editor.documentBaseURI.host;
    };
    var isCorsImage = function (editor, img) {
      return Tools.inArray(editor.settings.imagetools_cors_hosts, new URI(img.src).host) !== -1;
    };
    var getApiKey = function (editor) {
      return editor.settings.api_key || editor.settings.imagetools_api_key;
    };
    var imageToBlob = function (editor, img) {
      var src = img.src, apiKey;
      if (isCorsImage(editor, img)) {
        return Proxy.getUrl(img.src, null);
      }
      if (!isLocalImage(editor, img)) {
        src = Settings.getProxyUrl(editor);
        src += (src.indexOf('?') === -1 ? '?' : '&') + 'url=' + encodeURIComponent(img.src);
        apiKey = getApiKey(editor);
        return Proxy.getUrl(src, apiKey);
      }
      return BlobConversions.imageToBlob(img);
    };
    var findSelectedBlob = function (editor) {
      var blobInfo;
      blobInfo = editor.editorUpload.blobCache.getByUri(getSelectedImage(editor).src);
      if (blobInfo) {
        return Promise.resolve(blobInfo.blob());
      }
      return imageToBlob(editor, getSelectedImage(editor));
    };
    var startTimedUpload = function (editor, imageUploadTimerState) {
      var imageUploadTimer = Delay.setEditorTimeout(editor, function () {
        editor.editorUpload.uploadImagesAuto();
      }, editor.settings.images_upload_timeout || 30000);
      imageUploadTimerState.set(imageUploadTimer);
    };
    var cancelTimedUpload = function (imageUploadTimerState) {
      clearTimeout(imageUploadTimerState.get());
    };
    var updateSelectedImage = function (editor, ir, uploadImmediately, imageUploadTimerState) {
      return ir.toBlob().then(function (blob) {
        var uri, name, blobCache, blobInfo, selectedImage;
        blobCache = editor.editorUpload.blobCache;
        selectedImage = getSelectedImage(editor);
        uri = selectedImage.src;
        if (editor.settings.images_reuse_filename) {
          blobInfo = blobCache.getByUri(uri);
          if (blobInfo) {
            uri = blobInfo.uri();
            name = blobInfo.name();
          } else {
            name = extractFilename(editor, uri);
          }
        }
        blobInfo = blobCache.create({
          id: createId(),
          blob: blob,
          base64: ir.toBase64(),
          uri: uri,
          name: name
        });
        blobCache.add(blobInfo);
        editor.undoManager.transact(function () {
          function imageLoadedHandler() {
            editor.$(selectedImage).off('load', imageLoadedHandler);
            editor.nodeChanged();
            if (uploadImmediately) {
              editor.editorUpload.uploadImagesAuto();
            } else {
              cancelTimedUpload(imageUploadTimerState);
              startTimedUpload(editor, imageUploadTimerState);
            }
          }
          editor.$(selectedImage).on('load', imageLoadedHandler);
          editor.$(selectedImage).attr({
            src: blobInfo.blobUri()
          }).removeAttr('data-mce-src');
        });
        return blobInfo;
      });
    };
    var selectedImageOperation = function (editor, imageUploadTimerState, fn) {
      return function () {
        return editor._scanForImages().
          then(Fun.curry(findSelectedBlob, editor)).
          then(ResultConversions.blobToImageResult).
          then(fn).
          then(function (imageResult) {
            return updateSelectedImage(editor, imageResult, false, imageUploadTimerState);
          }, function (error) {
            displayError(editor, error);
          });
      };
    };
    var rotate = function (editor, imageUploadTimerState, angle) {
      return function () {
        return selectedImageOperation(editor, imageUploadTimerState, function (imageResult) {
          var size = ImageSize.getImageSize(getSelectedImage(editor));
          if (size) {
            ImageSize.setImageSize(getSelectedImage(editor), {
              w: size.h,
              h: size.w
            });
          }
          return ImageTransformations.rotate(imageResult, angle);
        })();
      };
    };
    var flip = function (editor, imageUploadTimerState, axis) {
      return function () {
        return selectedImageOperation(editor, imageUploadTimerState, function (imageResult) {
          return ImageTransformations.flip(imageResult, axis);
        })();
      };
    };
    var editImageDialog = function (editor, imageUploadTimerState) {
      return function () {
        var img = getSelectedImage(editor), originalSize = ImageSize.getNaturalImageSize(img);
        var handleDialogBlob = function (blob) {
          return new Promise(function (resolve) {
            BlobConversions.blobToImage(blob).
              then(function (newImage) {
                var newSize = ImageSize.getNaturalImageSize(newImage);
                if (originalSize.w !== newSize.w || originalSize.h !== newSize.h) {
                  if (ImageSize.getImageSize(img)) {
                    ImageSize.setImageSize(img, newSize);
                  }
                }
                URL.revokeObjectURL(newImage.src);
                resolve(blob);
              });
          });
        };
        var openDialog = function (editor, imageResult) {
          return Dialog.edit(editor, imageResult).then(handleDialogBlob).
            then(ResultConversions.blobToImageResult).
            then(function (imageResult) {
              return updateSelectedImage(editor, imageResult, true, imageUploadTimerState);
            }, function () {
              // Close dialog
            });
        };
        findSelectedBlob(editor).
          then(ResultConversions.blobToImageResult).
          then(Fun.curry(openDialog, editor), function (error) {
            displayError(editor, error);
          });
      };
    };
    return {
      rotate: rotate,
      flip: flip,
      editImageDialog: editImageDialog,
      isEditableImage: isEditableImage,
      cancelTimedUpload: cancelTimedUpload
    };
  }
);
 |