Code coverage report for src/js/base/module/ImageDialog.js

# all files / src/js/base/module/ ImageDialog.js

40% Statements 26/65
14.29% Branches 2/14
25% Functions 4/16
40% Lines 26/65

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    1321×
    1×
    1×

    1×
    1×
    77×
    77×
    77×
    77×
    77×
    77×

    1×
    77×

    77×
    77×

    77×

    77×
    77×

    77×

    1×
    2×
    2×

    1×

    1×

    1×

    1×
     import $ from 'jquery';
    import env from '../core/env';
    import key from '../core/key';

    export default class ImageDialog {
      constructor(context) {
        this.context = context;
        this.ui = $.summernote.ui;
        this.$body = $(document.body);
        this.$editor = context.layoutInfo.editor;
        this.options = context.options;
        this.lang = this.options.langInfo;
      }

      initialize() {
        const $container = this.options.dialogsInBody ? this.$body : this.$editor;

        let imageLimitation = '';
        Iif (this.options.maximumImageFileSize) {
          const unit = Math.floor(Math.log(this.options.maximumImageFileSize) / Math.log(1024));
          const readableSize = (this.options.maximumImageFileSize / Math.pow(1024, unit)).toFixed(2) * 1 +
                             ' ' + ' KMGTP'[unit] + 'B';
          imageLimitation = `<small>${this.lang.image.maximumFileSize + ' : ' + readableSize}</small>`;
        }

        const body = [
          '<div class="form-group note-form-group note-group-select-from-files">',
          '<label class="note-form-label">' + this.lang.image.selectFromFiles + '</label>',
          '<input class="note-image-input note-form-control note-input" ',
          ' type="file" name="files" accept="image/*" multiple="multiple" />',
          imageLimitation,
          '</div>',
          '<div class="form-group note-group-image-url" style="overflow:auto;">',
          '<label class="note-form-label">' + this.lang.image.url + '</label>',
          '<input class="note-image-url form-control note-form-control note-input ',
          ' col-md-12" type="text" />',
          '</div>'
        ].join('');
        const buttonClass = 'btn btn-primary note-btn note-btn-primary note-image-btn';
        const footer = `<button type="submit" href="#" class="${buttonClass}" disabled>${this.lang.image.insert}</button>`;

        this.$dialog = this.ui.dialog({
          title: this.lang.image.insert,
          fade: this.options.dialogsFade,
          body: body,
          footer: footer
        }).render().appendTo($container);
      }

      destroy() {
        this.ui.hideDialog(this.$dialog);
        this.$dialog.remove();
      }

      bindEnterKey($input, $btn) {
        $input.on('keypress', (event) => {
          if (event.keyCode === key.code.ENTER) {
            event.preventDefault();
            $btn.trigger('click');
          }
        });
      }

      show() {
        this.context.invoke('editor.saveRange');
        this.showImageDialog().then((data) => {
          // [workaround] hide dialog before restore range for IE range focus
          this.ui.hideDialog(this.$dialog);
          this.context.invoke('editor.restoreRange');

          if (typeof data === 'string') { // image url
            this.context.invoke('editor.insertImage', data);
          } else { // array of files
            this.context.invoke('editor.insertImagesOrCallback', data);
          }
        }).fail(() => {
          this.context.invoke('editor.restoreRange');
        });
      }

      /**
       * show image dialog
       *
       * @param {jQuery} $dialog
       * @return {Promise}
       */
      showImageDialog() {
        return $.Deferred((deferred) => {
          const $imageInput = this.$dialog.find('.note-image-input');
          const $imageUrl = this.$dialog.find('.note-image-url');
          const $imageBtn = this.$dialog.find('.note-image-btn');

          this.ui.onDialogShown(this.$dialog, () => {
            this.context.triggerEvent('dialog.shown');

            // Cloning imageInput to clear element.
            $imageInput.replaceWith($imageInput.clone().on('change', (event) => {
              deferred.resolve(event.target.files || event.target.value);
            }).val(''));

            $imageBtn.click((event) => {
              event.preventDefault();

              deferred.resolve($imageUrl.val());
            });

            $imageUrl.on('keyup paste', () => {
              const url = $imageUrl.val();
              this.ui.toggleBtn($imageBtn, url);
            }).val('');

            if (!env.isSupportTouch) {
              $imageUrl.trigger('focus');
            }
            this.bindEnterKey($imageUrl, $imageBtn);
          });

          this.ui.onDialogHidden(this.$dialog, () => {
            $imageInput.off('change');
            $imageUrl.off('keyup paste keypress');
            $imageBtn.off('click');

            if (deferred.state() === 'pending') {
              deferred.reject();
            }
          });

          this.ui.showDialog(this.$dialog);
        });
      }
    }