Your IP : 216.73.217.176


Current Path : /home/bechata/mp/wp-content/uploads/2022/ejn73c/
Upload File :
Current File : /home/bechata/mp/wp-content/uploads/2022/ejn73c/inline-attachment.tar

codemirror-4.inline-attachment.min.js000066600000011341151761610720013607 0ustar00/*! inline-attachment - v2.0.3 - 2016-08-20 */
!function(a,b){"use strict";var c=function(a,b){this.settings=c.util.merge(a,c.defaults),this.editor=b,this.filenameTag="{filename}",this.lastValue=null};c.editors={},c.util={merge:function(){for(var a={},b=arguments.length-1;b>=0;b--){var c=arguments[b];for(var d in c)c.hasOwnProperty(d)&&(a[d]=c[d])}return a},appendInItsOwnLine:function(a,b){return(a+"\n\n[[D]]"+b).replace(/(\n{2,})\[\[D\]\]/,"\n\n").replace(/^(\n*)/,"")},insertTextAtCursor:function(b,c){var d,e=b.scrollTop,f=0,g=!1;b.selectionStart||"0"===b.selectionStart?g="ff":a.selection&&(g="ie"),"ie"===g?(b.focus(),d=a.selection.createRange(),d.moveStart("character",-b.value.length),f=d.text.length):"ff"===g&&(f=b.selectionStart);var h=b.value.substring(0,f),i=b.value.substring(f,b.value.length);b.value=h+c+i,f+=c.length,"ie"===g?(b.focus(),d=a.selection.createRange(),d.moveStart("character",-b.value.length),d.moveStart("character",f),d.moveEnd("character",0),d.select()):"ff"===g&&(b.selectionStart=f,b.selectionEnd=f,b.focus()),b.scrollTop=e}},c.defaults={uploadUrl:"upload_attachment.php",uploadMethod:"POST",uploadFieldName:"file",defaultExtension:"png",jsonFieldName:"filename",allowedTypes:["image/jpeg","image/png","image/jpg","image/gif"],progressText:"![Uploading file...]()",urlText:"![file]({filename})",errorText:"Error uploading file",extraParams:{},extraHeaders:{},beforeFileUpload:function(){return!0},onFileReceived:function(){},onFileUploadResponse:function(){return!0},onFileUploadError:function(){return!0},onFileUploaded:function(){}},c.prototype.uploadFile=function(a){var b=this,c=new FormData,d=new XMLHttpRequest,e=this.settings,f=e.defaultExtension||e.defualtExtension;if("function"==typeof e.setupFormData&&e.setupFormData(c,a),a.name){var g=a.name.match(/\.(.+)$/);g&&(f=g[1])}var h="image-"+Date.now()+"."+f;if("function"==typeof e.remoteFilename&&(h=e.remoteFilename(a)),c.append(e.uploadFieldName,a,h),"object"==typeof e.extraParams)for(var i in e.extraParams)e.extraParams.hasOwnProperty(i)&&c.append(i,e.extraParams[i]);if(d.open("POST",e.uploadUrl),"object"==typeof e.extraHeaders)for(var j in e.extraHeaders)e.extraHeaders.hasOwnProperty(j)&&d.setRequestHeader(j,e.extraHeaders[j]);return d.onload=function(){200===d.status||201===d.status?b.onFileUploadResponse(d):b.onFileUploadError(d)},e.beforeFileUpload(d)!==!1&&d.send(c),d},c.prototype.isFileAllowed=function(a){return"string"===a.kind?!1:0===this.settings.allowedTypes.indexOf("*")?!0:this.settings.allowedTypes.indexOf(a.type)>=0},c.prototype.onFileUploadResponse=function(a){if(this.settings.onFileUploadResponse.call(this,a)!==!1){var b=JSON.parse(a.responseText),c=b[this.settings.jsonFieldName];if(b&&c){var d;d="function"==typeof this.settings.urlText?this.settings.urlText.call(this,c,b):this.settings.urlText.replace(this.filenameTag,c);var e=this.editor.getValue().replace(this.lastValue,d);this.editor.setValue(e),this.settings.onFileUploaded.call(this,c)}}},c.prototype.onFileUploadError=function(a){if(this.settings.onFileUploadError.call(this,a)!==!1){var b=this.editor.getValue().replace(this.lastValue,"");this.editor.setValue(b)}},c.prototype.onFileInserted=function(a){this.settings.onFileReceived.call(this,a)!==!1&&(this.lastValue=this.settings.progressText,this.editor.insertValue(this.lastValue))},c.prototype.onPaste=function(a){var b,c=!1,d=a.clipboardData;if("object"==typeof d){b=d.items||d.files||[];for(var e=0;e<b.length;e++){var f=b[e];this.isFileAllowed(f)&&(c=!0,this.onFileInserted(f.getAsFile()),this.uploadFile(f.getAsFile()))}}return c&&a.preventDefault(),c},c.prototype.onDrop=function(a){for(var b=!1,c=0;c<a.dataTransfer.files.length;c++){var d=a.dataTransfer.files[c];this.isFileAllowed(d)&&(b=!0,this.onFileInserted(d),this.uploadFile(d))}return b},b.inlineAttachment=c}(document,window),function(){"use strict";var a=function(a){if(!a.getWrapperElement)throw"Invalid CodeMirror object given";this.codeMirror=a};a.prototype.getValue=function(){return this.codeMirror.getValue()},a.prototype.insertValue=function(a){this.codeMirror.replaceSelection(a)},a.prototype.setValue=function(a){var b=this.codeMirror.getCursor();this.codeMirror.setValue(a),this.codeMirror.setCursor(b)},a.attach=function(b,c){c=c||{};var d=new a(b),e=new inlineAttachment(c,d),f=b.getWrapperElement();f.addEventListener("paste",function(a){e.onPaste(a)},!1),b.setOption("onDragEvent",function(a,b){return"drop"===b.type?(b.stopPropagation(),b.preventDefault(),e.onDrop(b)):void 0})};var b=function(b){a.call(this,b)};b.attach=function(b,c){c=c||{};var d=new a(b),e=new inlineAttachment(c,d),f=b.getWrapperElement();f.addEventListener("paste",function(a){e.onPaste(a)},!1),b.on("drop",function(a,b){return e.onDrop(b)?(b.stopPropagation(),b.preventDefault(),!0):!1})},inlineAttachment.editors.codemirror4=b}();inline-attachment.js000066600000027307151761610720010531 0ustar00/*! inline-attachment - v2.0.3 - 2016-08-20 */
/*jslint newcap: true */
/*global XMLHttpRequest: false, FormData: false */
/*
 * Inline Text Attachment
 *
 * Author: Roy van Kaathoven
 * Contact: ik@royvankaathoven.nl
 */
(function(document, window) {
  'use strict';

  var inlineAttachment = function(options, instance) {
    this.settings = inlineAttachment.util.merge(options, inlineAttachment.defaults);
    this.editor = instance;
    this.filenameTag = '{filename}';
    this.lastValue = null;
  };

  /**
   * Will holds the available editors
   *
   * @type {Object}
   */
  inlineAttachment.editors = {};

  /**
   * Utility functions
   */
  inlineAttachment.util = {

    /**
     * Simple function to merge the given objects
     *
     * @param {Object[]} object Multiple object parameters
     * @returns {Object}
     */
    merge: function() {
      var result = {};
      for (var i = arguments.length - 1; i >= 0; i--) {
        var obj = arguments[i];
        for (var k in obj) {
          if (obj.hasOwnProperty(k)) {
            result[k] = obj[k];
          }
        }
      }
      return result;
    },

    /**
     * Append a line of text at the bottom, ensuring there aren't unnecessary newlines
     *
     * @param {String} appended Current content
     * @param {String} previous Value which should be appended after the current content
     */
    appendInItsOwnLine: function(previous, appended) {
      return (previous + "\n\n[[D]]" + appended)
        .replace(/(\n{2,})\[\[D\]\]/, "\n\n")
        .replace(/^(\n*)/, "");
    },

    /**
     * Inserts the given value at the current cursor position of the textarea element
     *
     * @param  {HtmlElement} el
     * @param  {String} value Text which will be inserted at the cursor position
     */
    insertTextAtCursor: function(el, text) {
      var scrollPos = el.scrollTop,
        strPos = 0,
        browser = false,
        range;

      if ((el.selectionStart || el.selectionStart === '0')) {
        browser = "ff";
      } else if (document.selection) {
        browser = "ie";
      }

      if (browser === "ie") {
        el.focus();
        range = document.selection.createRange();
        range.moveStart('character', -el.value.length);
        strPos = range.text.length;
      } else if (browser === "ff") {
        strPos = el.selectionStart;
      }

      var front = (el.value).substring(0, strPos);
      var back = (el.value).substring(strPos, el.value.length);
      el.value = front + text + back;
      strPos = strPos + text.length;
      if (browser === "ie") {
        el.focus();
        range = document.selection.createRange();
        range.moveStart('character', -el.value.length);
        range.moveStart('character', strPos);
        range.moveEnd('character', 0);
        range.select();
      } else if (browser === "ff") {
        el.selectionStart = strPos;
        el.selectionEnd = strPos;
        el.focus();
      }
      el.scrollTop = scrollPos;
    }
  };

  /**
   * Default configuration options
   *
   * @type {Object}
   */
  inlineAttachment.defaults = {
    /**
     * URL where the file will be send
     */
    uploadUrl: 'upload_attachment.php',

    /**
     * Which method will be used to send the file to the upload URL
     */
    uploadMethod: 'POST',

    /**
     * Name in which the file will be placed
     */
    uploadFieldName: 'file',

    /**
     * Extension which will be used when a file extension could not
     * be detected
     */
    defaultExtension: 'png',

    /**
     * JSON field which refers to the uploaded file URL
     */
    jsonFieldName: 'filename',

    /**
     * Allowed MIME types
     */
    allowedTypes: [
      'image/jpeg',
      'image/png',
      'image/jpg',
      'image/gif'
    ],

    /**
     * Text which will be inserted when dropping or pasting a file.
     * Acts as a placeholder which will be replaced when the file is done with uploading
     */
    progressText: '![Uploading file...]()',

    /**
     * When a file has successfully been uploaded the progressText
     * will be replaced by the urlText, the {filename} tag will be replaced
     * by the filename that has been returned by the server
     */
    urlText: "![file]({filename})",

    /**
     * Text which will be used when uploading has failed
     */
    errorText: "Error uploading file",

    /**
     * Extra parameters which will be send when uploading a file
     */
    extraParams: {},

    /**
     * Extra headers which will be send when uploading a file
     */
    extraHeaders: {},

    /**
     * Before the file is send
     */
    beforeFileUpload: function() {
      return true;
    },

    /**
     * Triggers when a file is dropped or pasted
     */
    onFileReceived: function() {},

    /**
     * Custom upload handler
     *
     * @return {Boolean} when false is returned it will prevent default upload behavior
     */
    onFileUploadResponse: function() {
      return true;
    },

    /**
     * Custom error handler. Runs after removing the placeholder text and before the alert().
     * Return false from this function to prevent the alert dialog.
     *
     * @return {Boolean} when false is returned it will prevent default error behavior
     */
    onFileUploadError: function() {
      return true;
    },

    /**
     * When a file has succesfully been uploaded
     */
    onFileUploaded: function() {}
  };

  /**
   * Uploads the blob
   *
   * @param  {Blob} file blob data received from event.dataTransfer object
   * @return {XMLHttpRequest} request object which sends the file
   */
  inlineAttachment.prototype.uploadFile = function(file) {
    var me = this,
      formData = new FormData(),
      xhr = new XMLHttpRequest(),
      settings = this.settings,
      extension = settings.defaultExtension || settings.defualtExtension;

    if (typeof settings.setupFormData === 'function') {
      settings.setupFormData(formData, file);
    }

    // Attach the file. If coming from clipboard, add a default filename (only works in Chrome for now)
    // http://stackoverflow.com/questions/6664967/how-to-give-a-blob-uploaded-as-formdata-a-file-name
    if (file.name) {
      var fileNameMatches = file.name.match(/\.(.+)$/);
      if (fileNameMatches) {
        extension = fileNameMatches[1];
      }
    }

    var remoteFilename = "image-" + Date.now() + "." + extension;
    if (typeof settings.remoteFilename === 'function') {
      remoteFilename = settings.remoteFilename(file);
    }

    formData.append(settings.uploadFieldName, file, remoteFilename);

    // Append the extra parameters to the formdata
    if (typeof settings.extraParams === "object") {
      for (var key in settings.extraParams) {
        if (settings.extraParams.hasOwnProperty(key)) {
          formData.append(key, settings.extraParams[key]);
        }
      }
    }

    xhr.open('POST', settings.uploadUrl);

    // Add any available extra headers
    if (typeof settings.extraHeaders === "object") {
        for (var header in settings.extraHeaders) {
            if (settings.extraHeaders.hasOwnProperty(header)) {
                xhr.setRequestHeader(header, settings.extraHeaders[header]);
            }
        }
    }

    xhr.onload = function() {
      // If HTTP status is OK or Created
      if (xhr.status === 200 || xhr.status === 201) {
        me.onFileUploadResponse(xhr);
      } else {
        me.onFileUploadError(xhr);
      }
    };
    if (settings.beforeFileUpload(xhr) !== false) {
      xhr.send(formData);
    }
    return xhr;
  };

  /**
   * Returns if the given file is allowed to handle
   *
   * @param {File} clipboard data file
   */
  inlineAttachment.prototype.isFileAllowed = function(file) {
    if (file.kind === 'string') { return false; }
    if (this.settings.allowedTypes.indexOf('*') === 0){
      return true;
    } else {
      return this.settings.allowedTypes.indexOf(file.type) >= 0;
    }
  };

  /**
   * Handles upload response
   *
   * @param  {XMLHttpRequest} xhr
   * @return {Void}
   */
  inlineAttachment.prototype.onFileUploadResponse = function(xhr) {
    if (this.settings.onFileUploadResponse.call(this, xhr) !== false) {
      var result = JSON.parse(xhr.responseText),
        filename = result[this.settings.jsonFieldName];

      if (result && filename) {
        var newValue;
        if (typeof this.settings.urlText === 'function') {
          newValue = this.settings.urlText.call(this, filename, result);
        } else {
          newValue = this.settings.urlText.replace(this.filenameTag, filename);
        }
        var text = this.editor.getValue().replace(this.lastValue, newValue);
        this.editor.setValue(text);
        this.settings.onFileUploaded.call(this, filename);
      }
    }
  };


  /**
   * Called when a file has failed to upload
   *
   * @param  {XMLHttpRequest} xhr
   * @return {Void}
   */
  inlineAttachment.prototype.onFileUploadError = function(xhr) {
    if (this.settings.onFileUploadError.call(this, xhr) !== false) {
      var text = this.editor.getValue().replace(this.lastValue, "");
      this.editor.setValue(text);
    }
  };

  /**
   * Called when a file has been inserted, either by drop or paste
   *
   * @param  {File} file
   * @return {Void}
   */
  inlineAttachment.prototype.onFileInserted = function(file) {
    if (this.settings.onFileReceived.call(this, file) !== false) {
      this.lastValue = this.settings.progressText;
      this.editor.insertValue(this.lastValue);
    }
  };


  /**
   * Called when a paste event occured
   * @param  {Event} e
   * @return {Boolean} if the event was handled
   */
  inlineAttachment.prototype.onPaste = function(e) {
    var result = false,
      clipboardData = e.clipboardData,
      items;

    if (typeof clipboardData === "object") {
      items = clipboardData.items || clipboardData.files || [];

      for (var i = 0; i < items.length; i++) {
        var item = items[i];
        if (this.isFileAllowed(item)) {
          result = true;
          this.onFileInserted(item.getAsFile());
          this.uploadFile(item.getAsFile());
        }
      }
    }

    if (result) { e.preventDefault(); }

    return result;
  };

  /**
   * Called when a drop event occures
   * @param  {Event} e
   * @return {Boolean} if the event was handled
   */
  inlineAttachment.prototype.onDrop = function(e) {
    var result = false;
    for (var i = 0; i < e.dataTransfer.files.length; i++) {
      var file = e.dataTransfer.files[i];
      if (this.isFileAllowed(file)) {
        result = true;
        this.onFileInserted(file);
        this.uploadFile(file);
      }
    }

    return result;
  };

  window.inlineAttachment = inlineAttachment;

})(document, window);

/*jslint newcap: true */
/*global inlineAttachment: false */
(function() {
  'use strict';

  inlineAttachment.editors.input = {
    Editor: function(instance) {

      var input = instance;

      return {
        getValue: function() {
          return input.value;
        },
        insertValue: function(val) {
          inlineAttachment.util.insertTextAtCursor(input, val);
        },
        setValue: function(val) {
          input.value = val;
        }
      };
    },
    attachToInput: function(input, options) {
      options = options || {};

      var editor = new inlineAttachment.editors.input.Editor(input),
        inlineattach = new inlineAttachment(options, editor);

      input.addEventListener('paste', function(e) {
        inlineattach.onPaste(e);
      }, false);
      input.addEventListener('drop', function(e) {
        e.stopPropagation();
        e.preventDefault();
        inlineattach.onDrop(e);
      }, false);
      input.addEventListener('dragenter', function(e) {
        e.stopPropagation();
        e.preventDefault();
      }, false);
      input.addEventListener('dragover', function(e) {
        e.stopPropagation();
        e.preventDefault();
      }, false);
    }
  };

})();codemirror-4.inline-attachment.js000066600000031150151761610720013025 0ustar00/*! inline-attachment - v2.0.3 - 2016-08-20 */
/*jslint newcap: true */
/*global XMLHttpRequest: false, FormData: false */
/*
 * Inline Text Attachment
 *
 * Author: Roy van Kaathoven
 * Contact: ik@royvankaathoven.nl
 */
(function(document, window) {
  'use strict';

  var inlineAttachment = function(options, instance) {
    this.settings = inlineAttachment.util.merge(options, inlineAttachment.defaults);
    this.editor = instance;
    this.filenameTag = '{filename}';
    this.lastValue = null;
  };

  /**
   * Will holds the available editors
   *
   * @type {Object}
   */
  inlineAttachment.editors = {};

  /**
   * Utility functions
   */
  inlineAttachment.util = {

    /**
     * Simple function to merge the given objects
     *
     * @param {Object[]} object Multiple object parameters
     * @returns {Object}
     */
    merge: function() {
      var result = {};
      for (var i = arguments.length - 1; i >= 0; i--) {
        var obj = arguments[i];
        for (var k in obj) {
          if (obj.hasOwnProperty(k)) {
            result[k] = obj[k];
          }
        }
      }
      return result;
    },

    /**
     * Append a line of text at the bottom, ensuring there aren't unnecessary newlines
     *
     * @param {String} appended Current content
     * @param {String} previous Value which should be appended after the current content
     */
    appendInItsOwnLine: function(previous, appended) {
      return (previous + "\n\n[[D]]" + appended)
        .replace(/(\n{2,})\[\[D\]\]/, "\n\n")
        .replace(/^(\n*)/, "");
    },

    /**
     * Inserts the given value at the current cursor position of the textarea element
     *
     * @param  {HtmlElement} el
     * @param  {String} value Text which will be inserted at the cursor position
     */
    insertTextAtCursor: function(el, text) {
      var scrollPos = el.scrollTop,
        strPos = 0,
        browser = false,
        range;

      if ((el.selectionStart || el.selectionStart === '0')) {
        browser = "ff";
      } else if (document.selection) {
        browser = "ie";
      }

      if (browser === "ie") {
        el.focus();
        range = document.selection.createRange();
        range.moveStart('character', -el.value.length);
        strPos = range.text.length;
      } else if (browser === "ff") {
        strPos = el.selectionStart;
      }

      var front = (el.value).substring(0, strPos);
      var back = (el.value).substring(strPos, el.value.length);
      el.value = front + text + back;
      strPos = strPos + text.length;
      if (browser === "ie") {
        el.focus();
        range = document.selection.createRange();
        range.moveStart('character', -el.value.length);
        range.moveStart('character', strPos);
        range.moveEnd('character', 0);
        range.select();
      } else if (browser === "ff") {
        el.selectionStart = strPos;
        el.selectionEnd = strPos;
        el.focus();
      }
      el.scrollTop = scrollPos;
    }
  };

  /**
   * Default configuration options
   *
   * @type {Object}
   */
  inlineAttachment.defaults = {
    /**
     * URL where the file will be send
     */
    uploadUrl: 'upload_attachment.php',

    /**
     * Which method will be used to send the file to the upload URL
     */
    uploadMethod: 'POST',

    /**
     * Name in which the file will be placed
     */
    uploadFieldName: 'file',

    /**
     * Extension which will be used when a file extension could not
     * be detected
     */
    defaultExtension: 'png',

    /**
     * JSON field which refers to the uploaded file URL
     */
    jsonFieldName: 'filename',

    /**
     * Allowed MIME types
     */
    allowedTypes: [
      'image/jpeg',
      'image/png',
      'image/jpg',
      'image/gif'
    ],

    /**
     * Text which will be inserted when dropping or pasting a file.
     * Acts as a placeholder which will be replaced when the file is done with uploading
     */
    progressText: '![Uploading file...]()',

    /**
     * When a file has successfully been uploaded the progressText
     * will be replaced by the urlText, the {filename} tag will be replaced
     * by the filename that has been returned by the server
     */
    urlText: "![file]({filename})",

    /**
     * Text which will be used when uploading has failed
     */
    errorText: "Error uploading file",

    /**
     * Extra parameters which will be send when uploading a file
     */
    extraParams: {},

    /**
     * Extra headers which will be send when uploading a file
     */
    extraHeaders: {},

    /**
     * Before the file is send
     */
    beforeFileUpload: function() {
      return true;
    },

    /**
     * Triggers when a file is dropped or pasted
     */
    onFileReceived: function() {},

    /**
     * Custom upload handler
     *
     * @return {Boolean} when false is returned it will prevent default upload behavior
     */
    onFileUploadResponse: function() {
      return true;
    },

    /**
     * Custom error handler. Runs after removing the placeholder text and before the alert().
     * Return false from this function to prevent the alert dialog.
     *
     * @return {Boolean} when false is returned it will prevent default error behavior
     */
    onFileUploadError: function() {
      return true;
    },

    /**
     * When a file has succesfully been uploaded
     */
    onFileUploaded: function() {}
  };

  /**
   * Uploads the blob
   *
   * @param  {Blob} file blob data received from event.dataTransfer object
   * @return {XMLHttpRequest} request object which sends the file
   */
  inlineAttachment.prototype.uploadFile = function(file) {
    var me = this,
      formData = new FormData(),
      xhr = new XMLHttpRequest(),
      settings = this.settings,
      extension = settings.defaultExtension || settings.defualtExtension;

    if (typeof settings.setupFormData === 'function') {
      settings.setupFormData(formData, file);
    }

    // Attach the file. If coming from clipboard, add a default filename (only works in Chrome for now)
    // http://stackoverflow.com/questions/6664967/how-to-give-a-blob-uploaded-as-formdata-a-file-name
    if (file.name) {
      var fileNameMatches = file.name.match(/\.(.+)$/);
      if (fileNameMatches) {
        extension = fileNameMatches[1];
      }
    }

    var remoteFilename = "image-" + Date.now() + "." + extension;
    if (typeof settings.remoteFilename === 'function') {
      remoteFilename = settings.remoteFilename(file);
    }

    formData.append(settings.uploadFieldName, file, remoteFilename);

    // Append the extra parameters to the formdata
    if (typeof settings.extraParams === "object") {
      for (var key in settings.extraParams) {
        if (settings.extraParams.hasOwnProperty(key)) {
          formData.append(key, settings.extraParams[key]);
        }
      }
    }

    xhr.open('POST', settings.uploadUrl);

    // Add any available extra headers
    if (typeof settings.extraHeaders === "object") {
        for (var header in settings.extraHeaders) {
            if (settings.extraHeaders.hasOwnProperty(header)) {
                xhr.setRequestHeader(header, settings.extraHeaders[header]);
            }
        }
    }

    xhr.onload = function() {
      // If HTTP status is OK or Created
      if (xhr.status === 200 || xhr.status === 201) {
        me.onFileUploadResponse(xhr);
      } else {
        me.onFileUploadError(xhr);
      }
    };
    if (settings.beforeFileUpload(xhr) !== false) {
      xhr.send(formData);
    }
    return xhr;
  };

  /**
   * Returns if the given file is allowed to handle
   *
   * @param {File} clipboard data file
   */
  inlineAttachment.prototype.isFileAllowed = function(file) {
    if (file.kind === 'string') { return false; }
    if (this.settings.allowedTypes.indexOf('*') === 0){
      return true;
    } else {
      return this.settings.allowedTypes.indexOf(file.type) >= 0;
    }
  };

  /**
   * Handles upload response
   *
   * @param  {XMLHttpRequest} xhr
   * @return {Void}
   */
  inlineAttachment.prototype.onFileUploadResponse = function(xhr) {
    if (this.settings.onFileUploadResponse.call(this, xhr) !== false) {
      var result = JSON.parse(xhr.responseText),
        filename = result[this.settings.jsonFieldName];

      if (result && filename) {
        var newValue;
        if (typeof this.settings.urlText === 'function') {
          newValue = this.settings.urlText.call(this, filename, result);
        } else {
          newValue = this.settings.urlText.replace(this.filenameTag, filename);
        }
        var text = this.editor.getValue().replace(this.lastValue, newValue);
        this.editor.setValue(text);
        this.settings.onFileUploaded.call(this, filename);
      }
    }
  };


  /**
   * Called when a file has failed to upload
   *
   * @param  {XMLHttpRequest} xhr
   * @return {Void}
   */
  inlineAttachment.prototype.onFileUploadError = function(xhr) {
    if (this.settings.onFileUploadError.call(this, xhr) !== false) {
      var text = this.editor.getValue().replace(this.lastValue, "");
      this.editor.setValue(text);
    }
  };

  /**
   * Called when a file has been inserted, either by drop or paste
   *
   * @param  {File} file
   * @return {Void}
   */
  inlineAttachment.prototype.onFileInserted = function(file) {
    if (this.settings.onFileReceived.call(this, file) !== false) {
      this.lastValue = this.settings.progressText;
      this.editor.insertValue(this.lastValue);
    }
  };


  /**
   * Called when a paste event occured
   * @param  {Event} e
   * @return {Boolean} if the event was handled
   */
  inlineAttachment.prototype.onPaste = function(e) {
    var result = false,
      clipboardData = e.clipboardData,
      items;

    if (typeof clipboardData === "object") {
      items = clipboardData.items || clipboardData.files || [];

      for (var i = 0; i < items.length; i++) {
        var item = items[i];
        if (this.isFileAllowed(item)) {
          result = true;
          this.onFileInserted(item.getAsFile());
          this.uploadFile(item.getAsFile());
        }
      }
    }

    if (result) { e.preventDefault(); }

    return result;
  };

  /**
   * Called when a drop event occures
   * @param  {Event} e
   * @return {Boolean} if the event was handled
   */
  inlineAttachment.prototype.onDrop = function(e) {
    var result = false;
    for (var i = 0; i < e.dataTransfer.files.length; i++) {
      var file = e.dataTransfer.files[i];
      if (this.isFileAllowed(file)) {
        result = true;
        this.onFileInserted(file);
        this.uploadFile(file);
      }
    }

    return result;
  };

  window.inlineAttachment = inlineAttachment;

})(document, window);

/*jslint newcap: true */
/*global inlineAttachment: false */
/**
 * CodeMirror version for inlineAttachment
 *
 * Call inlineAttachment.attach(editor) to attach to a codemirror instance
 */
(function() {
  'use strict';

  var codeMirrorEditor = function(instance) {

    if (!instance.getWrapperElement) {
      throw "Invalid CodeMirror object given";
    }

    this.codeMirror = instance;
  };

  codeMirrorEditor.prototype.getValue = function() {
    return this.codeMirror.getValue();
  };

  codeMirrorEditor.prototype.insertValue = function(val) {
    this.codeMirror.replaceSelection(val);
  };

  codeMirrorEditor.prototype.setValue = function(val) {
    var cursor = this.codeMirror.getCursor();
    this.codeMirror.setValue(val);
    this.codeMirror.setCursor(cursor);
  };

  /**
   * Attach InlineAttachment to CodeMirror
   *
   * @param {CodeMirror} codeMirror
   */
  codeMirrorEditor.attach = function(codeMirror, options) {

    options = options || {};

    var editor = new codeMirrorEditor(codeMirror),
      inlineattach = new inlineAttachment(options, editor),
      el = codeMirror.getWrapperElement();

    el.addEventListener('paste', function(e) {
      inlineattach.onPaste(e);
    }, false);

    codeMirror.setOption('onDragEvent', function(data, e) {
      if (e.type === "drop") {
        e.stopPropagation();
        e.preventDefault();
        return inlineattach.onDrop(e);
      }
    });
  };

  var codeMirrorEditor4 = function(instance) {
    codeMirrorEditor.call(this, instance);
  };

  codeMirrorEditor4.attach = function(codeMirror, options) {

    options = options || {};

    var editor = new codeMirrorEditor(codeMirror),
      inlineattach = new inlineAttachment(options, editor),
      el = codeMirror.getWrapperElement();

    el.addEventListener('paste', function(e) {
      inlineattach.onPaste(e);
    }, false);

    codeMirror.on('drop', function(data, e) {
      if (inlineattach.onDrop(e)) {
        e.stopPropagation();
        e.preventDefault();
        return true;
      } else {
        return false;
      }
    });
  };

  inlineAttachment.editors.codemirror4 = codeMirrorEditor4;

})();codemirror-3.inline-attachment.min.js000066600000010705151761610720013611 0ustar00/*! inline-attachment - v2.0.3 - 2016-08-20 */
!function(a,b){"use strict";var c=function(a,b){this.settings=c.util.merge(a,c.defaults),this.editor=b,this.filenameTag="{filename}",this.lastValue=null};c.editors={},c.util={merge:function(){for(var a={},b=arguments.length-1;b>=0;b--){var c=arguments[b];for(var d in c)c.hasOwnProperty(d)&&(a[d]=c[d])}return a},appendInItsOwnLine:function(a,b){return(a+"\n\n[[D]]"+b).replace(/(\n{2,})\[\[D\]\]/,"\n\n").replace(/^(\n*)/,"")},insertTextAtCursor:function(b,c){var d,e=b.scrollTop,f=0,g=!1;b.selectionStart||"0"===b.selectionStart?g="ff":a.selection&&(g="ie"),"ie"===g?(b.focus(),d=a.selection.createRange(),d.moveStart("character",-b.value.length),f=d.text.length):"ff"===g&&(f=b.selectionStart);var h=b.value.substring(0,f),i=b.value.substring(f,b.value.length);b.value=h+c+i,f+=c.length,"ie"===g?(b.focus(),d=a.selection.createRange(),d.moveStart("character",-b.value.length),d.moveStart("character",f),d.moveEnd("character",0),d.select()):"ff"===g&&(b.selectionStart=f,b.selectionEnd=f,b.focus()),b.scrollTop=e}},c.defaults={uploadUrl:"upload_attachment.php",uploadMethod:"POST",uploadFieldName:"file",defaultExtension:"png",jsonFieldName:"filename",allowedTypes:["image/jpeg","image/png","image/jpg","image/gif"],progressText:"![Uploading file...]()",urlText:"![file]({filename})",errorText:"Error uploading file",extraParams:{},extraHeaders:{},beforeFileUpload:function(){return!0},onFileReceived:function(){},onFileUploadResponse:function(){return!0},onFileUploadError:function(){return!0},onFileUploaded:function(){}},c.prototype.uploadFile=function(a){var b=this,c=new FormData,d=new XMLHttpRequest,e=this.settings,f=e.defaultExtension||e.defualtExtension;if("function"==typeof e.setupFormData&&e.setupFormData(c,a),a.name){var g=a.name.match(/\.(.+)$/);g&&(f=g[1])}var h="image-"+Date.now()+"."+f;if("function"==typeof e.remoteFilename&&(h=e.remoteFilename(a)),c.append(e.uploadFieldName,a,h),"object"==typeof e.extraParams)for(var i in e.extraParams)e.extraParams.hasOwnProperty(i)&&c.append(i,e.extraParams[i]);if(d.open("POST",e.uploadUrl),"object"==typeof e.extraHeaders)for(var j in e.extraHeaders)e.extraHeaders.hasOwnProperty(j)&&d.setRequestHeader(j,e.extraHeaders[j]);return d.onload=function(){200===d.status||201===d.status?b.onFileUploadResponse(d):b.onFileUploadError(d)},e.beforeFileUpload(d)!==!1&&d.send(c),d},c.prototype.isFileAllowed=function(a){return"string"===a.kind?!1:0===this.settings.allowedTypes.indexOf("*")?!0:this.settings.allowedTypes.indexOf(a.type)>=0},c.prototype.onFileUploadResponse=function(a){if(this.settings.onFileUploadResponse.call(this,a)!==!1){var b=JSON.parse(a.responseText),c=b[this.settings.jsonFieldName];if(b&&c){var d;d="function"==typeof this.settings.urlText?this.settings.urlText.call(this,c,b):this.settings.urlText.replace(this.filenameTag,c);var e=this.editor.getValue().replace(this.lastValue,d);this.editor.setValue(e),this.settings.onFileUploaded.call(this,c)}}},c.prototype.onFileUploadError=function(a){if(this.settings.onFileUploadError.call(this,a)!==!1){var b=this.editor.getValue().replace(this.lastValue,"");this.editor.setValue(b)}},c.prototype.onFileInserted=function(a){this.settings.onFileReceived.call(this,a)!==!1&&(this.lastValue=this.settings.progressText,this.editor.insertValue(this.lastValue))},c.prototype.onPaste=function(a){var b,c=!1,d=a.clipboardData;if("object"==typeof d){b=d.items||d.files||[];for(var e=0;e<b.length;e++){var f=b[e];this.isFileAllowed(f)&&(c=!0,this.onFileInserted(f.getAsFile()),this.uploadFile(f.getAsFile()))}}return c&&a.preventDefault(),c},c.prototype.onDrop=function(a){for(var b=!1,c=0;c<a.dataTransfer.files.length;c++){var d=a.dataTransfer.files[c];this.isFileAllowed(d)&&(b=!0,this.onFileInserted(d),this.uploadFile(d))}return b},b.inlineAttachment=c}(document,window),function(){"use strict";var a=function(a){if(!a.getWrapperElement)throw"Invalid CodeMirror object given";this.codeMirror=a};a.prototype.getValue=function(){return this.codeMirror.getValue()},a.prototype.insertValue=function(a){this.codeMirror.replaceSelection(a)},a.prototype.setValue=function(a){var b=this.codeMirror.getCursor();this.codeMirror.setValue(a),this.codeMirror.setCursor(b)},a.attach=function(b,c){c=c||{};var d=new a(b),e=new inlineAttachment(c,d),f=b.getWrapperElement();f.addEventListener("paste",function(a){e.onPaste(a)},!1),b.setOption("onDragEvent",function(a,b){return"drop"===b.type?(b.stopPropagation(),b.preventDefault(),e.onDrop(b)):void 0})},inlineAttachment.editors.codemirror3=a}();angularjs.inline-attachment.js000066600000032147151761610720012514 0ustar00/*! inline-attachment - v2.0.3 - 2016-08-20 */
/*jslint newcap: true */
/*global XMLHttpRequest: false, FormData: false */
/*
 * Inline Text Attachment
 *
 * Author: Roy van Kaathoven
 * Contact: ik@royvankaathoven.nl
 */
(function(document, window) {
  'use strict';

  var inlineAttachment = function(options, instance) {
    this.settings = inlineAttachment.util.merge(options, inlineAttachment.defaults);
    this.editor = instance;
    this.filenameTag = '{filename}';
    this.lastValue = null;
  };

  /**
   * Will holds the available editors
   *
   * @type {Object}
   */
  inlineAttachment.editors = {};

  /**
   * Utility functions
   */
  inlineAttachment.util = {

    /**
     * Simple function to merge the given objects
     *
     * @param {Object[]} object Multiple object parameters
     * @returns {Object}
     */
    merge: function() {
      var result = {};
      for (var i = arguments.length - 1; i >= 0; i--) {
        var obj = arguments[i];
        for (var k in obj) {
          if (obj.hasOwnProperty(k)) {
            result[k] = obj[k];
          }
        }
      }
      return result;
    },

    /**
     * Append a line of text at the bottom, ensuring there aren't unnecessary newlines
     *
     * @param {String} appended Current content
     * @param {String} previous Value which should be appended after the current content
     */
    appendInItsOwnLine: function(previous, appended) {
      return (previous + "\n\n[[D]]" + appended)
        .replace(/(\n{2,})\[\[D\]\]/, "\n\n")
        .replace(/^(\n*)/, "");
    },

    /**
     * Inserts the given value at the current cursor position of the textarea element
     *
     * @param  {HtmlElement} el
     * @param  {String} value Text which will be inserted at the cursor position
     */
    insertTextAtCursor: function(el, text) {
      var scrollPos = el.scrollTop,
        strPos = 0,
        browser = false,
        range;

      if ((el.selectionStart || el.selectionStart === '0')) {
        browser = "ff";
      } else if (document.selection) {
        browser = "ie";
      }

      if (browser === "ie") {
        el.focus();
        range = document.selection.createRange();
        range.moveStart('character', -el.value.length);
        strPos = range.text.length;
      } else if (browser === "ff") {
        strPos = el.selectionStart;
      }

      var front = (el.value).substring(0, strPos);
      var back = (el.value).substring(strPos, el.value.length);
      el.value = front + text + back;
      strPos = strPos + text.length;
      if (browser === "ie") {
        el.focus();
        range = document.selection.createRange();
        range.moveStart('character', -el.value.length);
        range.moveStart('character', strPos);
        range.moveEnd('character', 0);
        range.select();
      } else if (browser === "ff") {
        el.selectionStart = strPos;
        el.selectionEnd = strPos;
        el.focus();
      }
      el.scrollTop = scrollPos;
    }
  };

  /**
   * Default configuration options
   *
   * @type {Object}
   */
  inlineAttachment.defaults = {
    /**
     * URL where the file will be send
     */
    uploadUrl: 'upload_attachment.php',

    /**
     * Which method will be used to send the file to the upload URL
     */
    uploadMethod: 'POST',

    /**
     * Name in which the file will be placed
     */
    uploadFieldName: 'file',

    /**
     * Extension which will be used when a file extension could not
     * be detected
     */
    defaultExtension: 'png',

    /**
     * JSON field which refers to the uploaded file URL
     */
    jsonFieldName: 'filename',

    /**
     * Allowed MIME types
     */
    allowedTypes: [
      'image/jpeg',
      'image/png',
      'image/jpg',
      'image/gif'
    ],

    /**
     * Text which will be inserted when dropping or pasting a file.
     * Acts as a placeholder which will be replaced when the file is done with uploading
     */
    progressText: '![Uploading file...]()',

    /**
     * When a file has successfully been uploaded the progressText
     * will be replaced by the urlText, the {filename} tag will be replaced
     * by the filename that has been returned by the server
     */
    urlText: "![file]({filename})",

    /**
     * Text which will be used when uploading has failed
     */
    errorText: "Error uploading file",

    /**
     * Extra parameters which will be send when uploading a file
     */
    extraParams: {},

    /**
     * Extra headers which will be send when uploading a file
     */
    extraHeaders: {},

    /**
     * Before the file is send
     */
    beforeFileUpload: function() {
      return true;
    },

    /**
     * Triggers when a file is dropped or pasted
     */
    onFileReceived: function() {},

    /**
     * Custom upload handler
     *
     * @return {Boolean} when false is returned it will prevent default upload behavior
     */
    onFileUploadResponse: function() {
      return true;
    },

    /**
     * Custom error handler. Runs after removing the placeholder text and before the alert().
     * Return false from this function to prevent the alert dialog.
     *
     * @return {Boolean} when false is returned it will prevent default error behavior
     */
    onFileUploadError: function() {
      return true;
    },

    /**
     * When a file has succesfully been uploaded
     */
    onFileUploaded: function() {}
  };

  /**
   * Uploads the blob
   *
   * @param  {Blob} file blob data received from event.dataTransfer object
   * @return {XMLHttpRequest} request object which sends the file
   */
  inlineAttachment.prototype.uploadFile = function(file) {
    var me = this,
      formData = new FormData(),
      xhr = new XMLHttpRequest(),
      settings = this.settings,
      extension = settings.defaultExtension || settings.defualtExtension;

    if (typeof settings.setupFormData === 'function') {
      settings.setupFormData(formData, file);
    }

    // Attach the file. If coming from clipboard, add a default filename (only works in Chrome for now)
    // http://stackoverflow.com/questions/6664967/how-to-give-a-blob-uploaded-as-formdata-a-file-name
    if (file.name) {
      var fileNameMatches = file.name.match(/\.(.+)$/);
      if (fileNameMatches) {
        extension = fileNameMatches[1];
      }
    }

    var remoteFilename = "image-" + Date.now() + "." + extension;
    if (typeof settings.remoteFilename === 'function') {
      remoteFilename = settings.remoteFilename(file);
    }

    formData.append(settings.uploadFieldName, file, remoteFilename);

    // Append the extra parameters to the formdata
    if (typeof settings.extraParams === "object") {
      for (var key in settings.extraParams) {
        if (settings.extraParams.hasOwnProperty(key)) {
          formData.append(key, settings.extraParams[key]);
        }
      }
    }

    xhr.open('POST', settings.uploadUrl);

    // Add any available extra headers
    if (typeof settings.extraHeaders === "object") {
        for (var header in settings.extraHeaders) {
            if (settings.extraHeaders.hasOwnProperty(header)) {
                xhr.setRequestHeader(header, settings.extraHeaders[header]);
            }
        }
    }

    xhr.onload = function() {
      // If HTTP status is OK or Created
      if (xhr.status === 200 || xhr.status === 201) {
        me.onFileUploadResponse(xhr);
      } else {
        me.onFileUploadError(xhr);
      }
    };
    if (settings.beforeFileUpload(xhr) !== false) {
      xhr.send(formData);
    }
    return xhr;
  };

  /**
   * Returns if the given file is allowed to handle
   *
   * @param {File} clipboard data file
   */
  inlineAttachment.prototype.isFileAllowed = function(file) {
    if (file.kind === 'string') { return false; }
    if (this.settings.allowedTypes.indexOf('*') === 0){
      return true;
    } else {
      return this.settings.allowedTypes.indexOf(file.type) >= 0;
    }
  };

  /**
   * Handles upload response
   *
   * @param  {XMLHttpRequest} xhr
   * @return {Void}
   */
  inlineAttachment.prototype.onFileUploadResponse = function(xhr) {
    if (this.settings.onFileUploadResponse.call(this, xhr) !== false) {
      var result = JSON.parse(xhr.responseText),
        filename = result[this.settings.jsonFieldName];

      if (result && filename) {
        var newValue;
        if (typeof this.settings.urlText === 'function') {
          newValue = this.settings.urlText.call(this, filename, result);
        } else {
          newValue = this.settings.urlText.replace(this.filenameTag, filename);
        }
        var text = this.editor.getValue().replace(this.lastValue, newValue);
        this.editor.setValue(text);
        this.settings.onFileUploaded.call(this, filename);
      }
    }
  };


  /**
   * Called when a file has failed to upload
   *
   * @param  {XMLHttpRequest} xhr
   * @return {Void}
   */
  inlineAttachment.prototype.onFileUploadError = function(xhr) {
    if (this.settings.onFileUploadError.call(this, xhr) !== false) {
      var text = this.editor.getValue().replace(this.lastValue, "");
      this.editor.setValue(text);
    }
  };

  /**
   * Called when a file has been inserted, either by drop or paste
   *
   * @param  {File} file
   * @return {Void}
   */
  inlineAttachment.prototype.onFileInserted = function(file) {
    if (this.settings.onFileReceived.call(this, file) !== false) {
      this.lastValue = this.settings.progressText;
      this.editor.insertValue(this.lastValue);
    }
  };


  /**
   * Called when a paste event occured
   * @param  {Event} e
   * @return {Boolean} if the event was handled
   */
  inlineAttachment.prototype.onPaste = function(e) {
    var result = false,
      clipboardData = e.clipboardData,
      items;

    if (typeof clipboardData === "object") {
      items = clipboardData.items || clipboardData.files || [];

      for (var i = 0; i < items.length; i++) {
        var item = items[i];
        if (this.isFileAllowed(item)) {
          result = true;
          this.onFileInserted(item.getAsFile());
          this.uploadFile(item.getAsFile());
        }
      }
    }

    if (result) { e.preventDefault(); }

    return result;
  };

  /**
   * Called when a drop event occures
   * @param  {Event} e
   * @return {Boolean} if the event was handled
   */
  inlineAttachment.prototype.onDrop = function(e) {
    var result = false;
    for (var i = 0; i < e.dataTransfer.files.length; i++) {
      var file = e.dataTransfer.files[i];
      if (this.isFileAllowed(file)) {
        result = true;
        this.onFileInserted(file);
        this.uploadFile(file);
      }
    }

    return result;
  };

  window.inlineAttachment = inlineAttachment;

})(document, window);

/*jslint newcap: true */
/*global inlineAttachment: false */
(function() {
  'use strict';

  inlineAttachment.editors.input = {
    Editor: function(instance) {

      var input = instance;

      return {
        getValue: function() {
          return input.value;
        },
        insertValue: function(val) {
          inlineAttachment.util.insertTextAtCursor(input, val);
        },
        setValue: function(val) {
          input.value = val;
        }
      };
    },
    attachToInput: function(input, options) {
      options = options || {};

      var editor = new inlineAttachment.editors.input.Editor(input),
        inlineattach = new inlineAttachment(options, editor);

      input.addEventListener('paste', function(e) {
        inlineattach.onPaste(e);
      }, false);
      input.addEventListener('drop', function(e) {
        e.stopPropagation();
        e.preventDefault();
        inlineattach.onDrop(e);
      }, false);
      input.addEventListener('dragenter', function(e) {
        e.stopPropagation();
        e.preventDefault();
      }, false);
      input.addEventListener('dragover', function(e) {
        e.stopPropagation();
        e.preventDefault();
      }, false);
    }
  };

})();
/*jslint newcap: true */
/*global inlineAttachment: false, angular: false */
/**
 * AngularJS plugin for inline attachment
 *
 * @param {document} document
 * @param {window} window
 * @param {Object} ng
 */
(function(document, window, ng) {
  'use strict';

  inlineAttachment.editors.angular = {};

  var module = ng.module('inlineattachment', []),
    attrName = 'inlineattachment';

  function lcfirst(str) {
    return str.charAt(0).toLowerCase() + str.substr(1);
  }

  /**
   * Read all parameters from the given attributes object
   *
   * @param  {Object} obj attributes
   * @return {Object}
   */
  function readParameters(obj, scope) {
    var result = {},
      attrs = obj.$attr,
      option, value;

    for (var key in attrs) {
      option = lcfirst(key.substr(attrName.length));
      value = obj[key];
      // Check if the given key is a valid string type, not empty and starts with the attribute name
      if ((option.length > 0) && (key.substring(0, attrName.length) === attrName)) {
        result[option] = value;
        if (typeof scope[value] === 'function') {
          result[option] = scope[value];
        }
      }
    }

    return result;
  }

  module.directive(attrName, function() {
    return function(scope, element, attrs) {
      var options = readParameters(attrs, scope);
      inlineAttachment.editors.input.attachToInput(element.context, options);
    };
  });
})(document, window, angular);
codemirror-3.inline-attachment.js000066600000027726151761610720013042 0ustar00/*! inline-attachment - v2.0.3 - 2016-08-20 */
/*jslint newcap: true */
/*global XMLHttpRequest: false, FormData: false */
/*
 * Inline Text Attachment
 *
 * Author: Roy van Kaathoven
 * Contact: ik@royvankaathoven.nl
 */
(function(document, window) {
  'use strict';

  var inlineAttachment = function(options, instance) {
    this.settings = inlineAttachment.util.merge(options, inlineAttachment.defaults);
    this.editor = instance;
    this.filenameTag = '{filename}';
    this.lastValue = null;
  };

  /**
   * Will holds the available editors
   *
   * @type {Object}
   */
  inlineAttachment.editors = {};

  /**
   * Utility functions
   */
  inlineAttachment.util = {

    /**
     * Simple function to merge the given objects
     *
     * @param {Object[]} object Multiple object parameters
     * @returns {Object}
     */
    merge: function() {
      var result = {};
      for (var i = arguments.length - 1; i >= 0; i--) {
        var obj = arguments[i];
        for (var k in obj) {
          if (obj.hasOwnProperty(k)) {
            result[k] = obj[k];
          }
        }
      }
      return result;
    },

    /**
     * Append a line of text at the bottom, ensuring there aren't unnecessary newlines
     *
     * @param {String} appended Current content
     * @param {String} previous Value which should be appended after the current content
     */
    appendInItsOwnLine: function(previous, appended) {
      return (previous + "\n\n[[D]]" + appended)
        .replace(/(\n{2,})\[\[D\]\]/, "\n\n")
        .replace(/^(\n*)/, "");
    },

    /**
     * Inserts the given value at the current cursor position of the textarea element
     *
     * @param  {HtmlElement} el
     * @param  {String} value Text which will be inserted at the cursor position
     */
    insertTextAtCursor: function(el, text) {
      var scrollPos = el.scrollTop,
        strPos = 0,
        browser = false,
        range;

      if ((el.selectionStart || el.selectionStart === '0')) {
        browser = "ff";
      } else if (document.selection) {
        browser = "ie";
      }

      if (browser === "ie") {
        el.focus();
        range = document.selection.createRange();
        range.moveStart('character', -el.value.length);
        strPos = range.text.length;
      } else if (browser === "ff") {
        strPos = el.selectionStart;
      }

      var front = (el.value).substring(0, strPos);
      var back = (el.value).substring(strPos, el.value.length);
      el.value = front + text + back;
      strPos = strPos + text.length;
      if (browser === "ie") {
        el.focus();
        range = document.selection.createRange();
        range.moveStart('character', -el.value.length);
        range.moveStart('character', strPos);
        range.moveEnd('character', 0);
        range.select();
      } else if (browser === "ff") {
        el.selectionStart = strPos;
        el.selectionEnd = strPos;
        el.focus();
      }
      el.scrollTop = scrollPos;
    }
  };

  /**
   * Default configuration options
   *
   * @type {Object}
   */
  inlineAttachment.defaults = {
    /**
     * URL where the file will be send
     */
    uploadUrl: 'upload_attachment.php',

    /**
     * Which method will be used to send the file to the upload URL
     */
    uploadMethod: 'POST',

    /**
     * Name in which the file will be placed
     */
    uploadFieldName: 'file',

    /**
     * Extension which will be used when a file extension could not
     * be detected
     */
    defaultExtension: 'png',

    /**
     * JSON field which refers to the uploaded file URL
     */
    jsonFieldName: 'filename',

    /**
     * Allowed MIME types
     */
    allowedTypes: [
      'image/jpeg',
      'image/png',
      'image/jpg',
      'image/gif'
    ],

    /**
     * Text which will be inserted when dropping or pasting a file.
     * Acts as a placeholder which will be replaced when the file is done with uploading
     */
    progressText: '![Uploading file...]()',

    /**
     * When a file has successfully been uploaded the progressText
     * will be replaced by the urlText, the {filename} tag will be replaced
     * by the filename that has been returned by the server
     */
    urlText: "![file]({filename})",

    /**
     * Text which will be used when uploading has failed
     */
    errorText: "Error uploading file",

    /**
     * Extra parameters which will be send when uploading a file
     */
    extraParams: {},

    /**
     * Extra headers which will be send when uploading a file
     */
    extraHeaders: {},

    /**
     * Before the file is send
     */
    beforeFileUpload: function() {
      return true;
    },

    /**
     * Triggers when a file is dropped or pasted
     */
    onFileReceived: function() {},

    /**
     * Custom upload handler
     *
     * @return {Boolean} when false is returned it will prevent default upload behavior
     */
    onFileUploadResponse: function() {
      return true;
    },

    /**
     * Custom error handler. Runs after removing the placeholder text and before the alert().
     * Return false from this function to prevent the alert dialog.
     *
     * @return {Boolean} when false is returned it will prevent default error behavior
     */
    onFileUploadError: function() {
      return true;
    },

    /**
     * When a file has succesfully been uploaded
     */
    onFileUploaded: function() {}
  };

  /**
   * Uploads the blob
   *
   * @param  {Blob} file blob data received from event.dataTransfer object
   * @return {XMLHttpRequest} request object which sends the file
   */
  inlineAttachment.prototype.uploadFile = function(file) {
    var me = this,
      formData = new FormData(),
      xhr = new XMLHttpRequest(),
      settings = this.settings,
      extension = settings.defaultExtension || settings.defualtExtension;

    if (typeof settings.setupFormData === 'function') {
      settings.setupFormData(formData, file);
    }

    // Attach the file. If coming from clipboard, add a default filename (only works in Chrome for now)
    // http://stackoverflow.com/questions/6664967/how-to-give-a-blob-uploaded-as-formdata-a-file-name
    if (file.name) {
      var fileNameMatches = file.name.match(/\.(.+)$/);
      if (fileNameMatches) {
        extension = fileNameMatches[1];
      }
    }

    var remoteFilename = "image-" + Date.now() + "." + extension;
    if (typeof settings.remoteFilename === 'function') {
      remoteFilename = settings.remoteFilename(file);
    }

    formData.append(settings.uploadFieldName, file, remoteFilename);

    // Append the extra parameters to the formdata
    if (typeof settings.extraParams === "object") {
      for (var key in settings.extraParams) {
        if (settings.extraParams.hasOwnProperty(key)) {
          formData.append(key, settings.extraParams[key]);
        }
      }
    }

    xhr.open('POST', settings.uploadUrl);

    // Add any available extra headers
    if (typeof settings.extraHeaders === "object") {
        for (var header in settings.extraHeaders) {
            if (settings.extraHeaders.hasOwnProperty(header)) {
                xhr.setRequestHeader(header, settings.extraHeaders[header]);
            }
        }
    }

    xhr.onload = function() {
      // If HTTP status is OK or Created
      if (xhr.status === 200 || xhr.status === 201) {
        me.onFileUploadResponse(xhr);
      } else {
        me.onFileUploadError(xhr);
      }
    };
    if (settings.beforeFileUpload(xhr) !== false) {
      xhr.send(formData);
    }
    return xhr;
  };

  /**
   * Returns if the given file is allowed to handle
   *
   * @param {File} clipboard data file
   */
  inlineAttachment.prototype.isFileAllowed = function(file) {
    if (file.kind === 'string') { return false; }
    if (this.settings.allowedTypes.indexOf('*') === 0){
      return true;
    } else {
      return this.settings.allowedTypes.indexOf(file.type) >= 0;
    }
  };

  /**
   * Handles upload response
   *
   * @param  {XMLHttpRequest} xhr
   * @return {Void}
   */
  inlineAttachment.prototype.onFileUploadResponse = function(xhr) {
    if (this.settings.onFileUploadResponse.call(this, xhr) !== false) {
      var result = JSON.parse(xhr.responseText),
        filename = result[this.settings.jsonFieldName];

      if (result && filename) {
        var newValue;
        if (typeof this.settings.urlText === 'function') {
          newValue = this.settings.urlText.call(this, filename, result);
        } else {
          newValue = this.settings.urlText.replace(this.filenameTag, filename);
        }
        var text = this.editor.getValue().replace(this.lastValue, newValue);
        this.editor.setValue(text);
        this.settings.onFileUploaded.call(this, filename);
      }
    }
  };


  /**
   * Called when a file has failed to upload
   *
   * @param  {XMLHttpRequest} xhr
   * @return {Void}
   */
  inlineAttachment.prototype.onFileUploadError = function(xhr) {
    if (this.settings.onFileUploadError.call(this, xhr) !== false) {
      var text = this.editor.getValue().replace(this.lastValue, "");
      this.editor.setValue(text);
    }
  };

  /**
   * Called when a file has been inserted, either by drop or paste
   *
   * @param  {File} file
   * @return {Void}
   */
  inlineAttachment.prototype.onFileInserted = function(file) {
    if (this.settings.onFileReceived.call(this, file) !== false) {
      this.lastValue = this.settings.progressText;
      this.editor.insertValue(this.lastValue);
    }
  };


  /**
   * Called when a paste event occured
   * @param  {Event} e
   * @return {Boolean} if the event was handled
   */
  inlineAttachment.prototype.onPaste = function(e) {
    var result = false,
      clipboardData = e.clipboardData,
      items;

    if (typeof clipboardData === "object") {
      items = clipboardData.items || clipboardData.files || [];

      for (var i = 0; i < items.length; i++) {
        var item = items[i];
        if (this.isFileAllowed(item)) {
          result = true;
          this.onFileInserted(item.getAsFile());
          this.uploadFile(item.getAsFile());
        }
      }
    }

    if (result) { e.preventDefault(); }

    return result;
  };

  /**
   * Called when a drop event occures
   * @param  {Event} e
   * @return {Boolean} if the event was handled
   */
  inlineAttachment.prototype.onDrop = function(e) {
    var result = false;
    for (var i = 0; i < e.dataTransfer.files.length; i++) {
      var file = e.dataTransfer.files[i];
      if (this.isFileAllowed(file)) {
        result = true;
        this.onFileInserted(file);
        this.uploadFile(file);
      }
    }

    return result;
  };

  window.inlineAttachment = inlineAttachment;

})(document, window);

/*jslint newcap: true */
/*global inlineAttachment: false */
/**
 * CodeMirror version for inlineAttachment
 *
 * Call inlineAttachment.attach(editor) to attach to a codemirror instance
 */
(function() {
  'use strict';

  var codeMirrorEditor = function(instance) {

    if (!instance.getWrapperElement) {
      throw "Invalid CodeMirror object given";
    }

    this.codeMirror = instance;
  };

  codeMirrorEditor.prototype.getValue = function() {
    return this.codeMirror.getValue();
  };

  codeMirrorEditor.prototype.insertValue = function(val) {
    this.codeMirror.replaceSelection(val);
  };

  codeMirrorEditor.prototype.setValue = function(val) {
    var cursor = this.codeMirror.getCursor();
    this.codeMirror.setValue(val);
    this.codeMirror.setCursor(cursor);
  };

  /**
   * Attach InlineAttachment to CodeMirror
   *
   * @param {CodeMirror} codeMirror
   */
  codeMirrorEditor.attach = function(codeMirror, options) {

    options = options || {};

    var editor = new codeMirrorEditor(codeMirror),
      inlineattach = new inlineAttachment(options, editor),
      el = codeMirror.getWrapperElement();

    el.addEventListener('paste', function(e) {
      inlineattach.onPaste(e);
    }, false);

    codeMirror.setOption('onDragEvent', function(data, e) {
      if (e.type === "drop") {
        e.stopPropagation();
        e.preventDefault();
        return inlineattach.onDrop(e);
      }
    });
  };

  inlineAttachment.editors.codemirror3 = codeMirrorEditor;
})();angularjs.inline-attachment.min.js000066600000011641151761610720013272 0ustar00/*! inline-attachment - v2.0.3 - 2016-08-20 */
!function(a,b){"use strict";var c=function(a,b){this.settings=c.util.merge(a,c.defaults),this.editor=b,this.filenameTag="{filename}",this.lastValue=null};c.editors={},c.util={merge:function(){for(var a={},b=arguments.length-1;b>=0;b--){var c=arguments[b];for(var d in c)c.hasOwnProperty(d)&&(a[d]=c[d])}return a},appendInItsOwnLine:function(a,b){return(a+"\n\n[[D]]"+b).replace(/(\n{2,})\[\[D\]\]/,"\n\n").replace(/^(\n*)/,"")},insertTextAtCursor:function(b,c){var d,e=b.scrollTop,f=0,g=!1;b.selectionStart||"0"===b.selectionStart?g="ff":a.selection&&(g="ie"),"ie"===g?(b.focus(),d=a.selection.createRange(),d.moveStart("character",-b.value.length),f=d.text.length):"ff"===g&&(f=b.selectionStart);var h=b.value.substring(0,f),i=b.value.substring(f,b.value.length);b.value=h+c+i,f+=c.length,"ie"===g?(b.focus(),d=a.selection.createRange(),d.moveStart("character",-b.value.length),d.moveStart("character",f),d.moveEnd("character",0),d.select()):"ff"===g&&(b.selectionStart=f,b.selectionEnd=f,b.focus()),b.scrollTop=e}},c.defaults={uploadUrl:"upload_attachment.php",uploadMethod:"POST",uploadFieldName:"file",defaultExtension:"png",jsonFieldName:"filename",allowedTypes:["image/jpeg","image/png","image/jpg","image/gif"],progressText:"![Uploading file...]()",urlText:"![file]({filename})",errorText:"Error uploading file",extraParams:{},extraHeaders:{},beforeFileUpload:function(){return!0},onFileReceived:function(){},onFileUploadResponse:function(){return!0},onFileUploadError:function(){return!0},onFileUploaded:function(){}},c.prototype.uploadFile=function(a){var b=this,c=new FormData,d=new XMLHttpRequest,e=this.settings,f=e.defaultExtension||e.defualtExtension;if("function"==typeof e.setupFormData&&e.setupFormData(c,a),a.name){var g=a.name.match(/\.(.+)$/);g&&(f=g[1])}var h="image-"+Date.now()+"."+f;if("function"==typeof e.remoteFilename&&(h=e.remoteFilename(a)),c.append(e.uploadFieldName,a,h),"object"==typeof e.extraParams)for(var i in e.extraParams)e.extraParams.hasOwnProperty(i)&&c.append(i,e.extraParams[i]);if(d.open("POST",e.uploadUrl),"object"==typeof e.extraHeaders)for(var j in e.extraHeaders)e.extraHeaders.hasOwnProperty(j)&&d.setRequestHeader(j,e.extraHeaders[j]);return d.onload=function(){200===d.status||201===d.status?b.onFileUploadResponse(d):b.onFileUploadError(d)},e.beforeFileUpload(d)!==!1&&d.send(c),d},c.prototype.isFileAllowed=function(a){return"string"===a.kind?!1:0===this.settings.allowedTypes.indexOf("*")?!0:this.settings.allowedTypes.indexOf(a.type)>=0},c.prototype.onFileUploadResponse=function(a){if(this.settings.onFileUploadResponse.call(this,a)!==!1){var b=JSON.parse(a.responseText),c=b[this.settings.jsonFieldName];if(b&&c){var d;d="function"==typeof this.settings.urlText?this.settings.urlText.call(this,c,b):this.settings.urlText.replace(this.filenameTag,c);var e=this.editor.getValue().replace(this.lastValue,d);this.editor.setValue(e),this.settings.onFileUploaded.call(this,c)}}},c.prototype.onFileUploadError=function(a){if(this.settings.onFileUploadError.call(this,a)!==!1){var b=this.editor.getValue().replace(this.lastValue,"");this.editor.setValue(b)}},c.prototype.onFileInserted=function(a){this.settings.onFileReceived.call(this,a)!==!1&&(this.lastValue=this.settings.progressText,this.editor.insertValue(this.lastValue))},c.prototype.onPaste=function(a){var b,c=!1,d=a.clipboardData;if("object"==typeof d){b=d.items||d.files||[];for(var e=0;e<b.length;e++){var f=b[e];this.isFileAllowed(f)&&(c=!0,this.onFileInserted(f.getAsFile()),this.uploadFile(f.getAsFile()))}}return c&&a.preventDefault(),c},c.prototype.onDrop=function(a){for(var b=!1,c=0;c<a.dataTransfer.files.length;c++){var d=a.dataTransfer.files[c];this.isFileAllowed(d)&&(b=!0,this.onFileInserted(d),this.uploadFile(d))}return b},b.inlineAttachment=c}(document,window),function(){"use strict";inlineAttachment.editors.input={Editor:function(a){var b=a;return{getValue:function(){return b.value},insertValue:function(a){inlineAttachment.util.insertTextAtCursor(b,a)},setValue:function(a){b.value=a}}},attachToInput:function(a,b){b=b||{};var c=new inlineAttachment.editors.input.Editor(a),d=new inlineAttachment(b,c);a.addEventListener("paste",function(a){d.onPaste(a)},!1),a.addEventListener("drop",function(a){a.stopPropagation(),a.preventDefault(),d.onDrop(a)},!1),a.addEventListener("dragenter",function(a){a.stopPropagation(),a.preventDefault()},!1),a.addEventListener("dragover",function(a){a.stopPropagation(),a.preventDefault()},!1)}}}(),function(a,b,c){"use strict";function d(a){return a.charAt(0).toLowerCase()+a.substr(1)}function e(a,b){var c,e,f={},h=a.$attr;for(var i in h)c=d(i.substr(g.length)),e=a[i],c.length>0&&i.substring(0,g.length)===g&&(f[c]=e,"function"==typeof b[e]&&(f[c]=b[e]));return f}inlineAttachment.editors.angular={};var f=c.module("inlineattachment",[]),g="inlineattachment";f.directive(g,function(){return function(a,b,c){var d=e(c,a);inlineAttachment.editors.input.attachToInput(b.context,d)}})}(document,window,angular);jquery.inline-attachment.min.js000066600000010615151761610720012623 0ustar00/*! inline-attachment - v2.0.3 - 2016-08-20 */
!function(a,b){"use strict";var c=function(a,b){this.settings=c.util.merge(a,c.defaults),this.editor=b,this.filenameTag="{filename}",this.lastValue=null};c.editors={},c.util={merge:function(){for(var a={},b=arguments.length-1;b>=0;b--){var c=arguments[b];for(var d in c)c.hasOwnProperty(d)&&(a[d]=c[d])}return a},appendInItsOwnLine:function(a,b){return(a+"\n\n[[D]]"+b).replace(/(\n{2,})\[\[D\]\]/,"\n\n").replace(/^(\n*)/,"")},insertTextAtCursor:function(b,c){var d,e=b.scrollTop,f=0,g=!1;b.selectionStart||"0"===b.selectionStart?g="ff":a.selection&&(g="ie"),"ie"===g?(b.focus(),d=a.selection.createRange(),d.moveStart("character",-b.value.length),f=d.text.length):"ff"===g&&(f=b.selectionStart);var h=b.value.substring(0,f),i=b.value.substring(f,b.value.length);b.value=h+c+i,f+=c.length,"ie"===g?(b.focus(),d=a.selection.createRange(),d.moveStart("character",-b.value.length),d.moveStart("character",f),d.moveEnd("character",0),d.select()):"ff"===g&&(b.selectionStart=f,b.selectionEnd=f,b.focus()),b.scrollTop=e}},c.defaults={uploadUrl:"upload_attachment.php",uploadMethod:"POST",uploadFieldName:"file",defaultExtension:"png",jsonFieldName:"filename",allowedTypes:["image/jpeg","image/png","image/jpg","image/gif"],progressText:"![Uploading file...]()",urlText:"![file]({filename})",errorText:"Error uploading file",extraParams:{},extraHeaders:{},beforeFileUpload:function(){return!0},onFileReceived:function(){},onFileUploadResponse:function(){return!0},onFileUploadError:function(){return!0},onFileUploaded:function(){}},c.prototype.uploadFile=function(a){var b=this,c=new FormData,d=new XMLHttpRequest,e=this.settings,f=e.defaultExtension||e.defualtExtension;if("function"==typeof e.setupFormData&&e.setupFormData(c,a),a.name){var g=a.name.match(/\.(.+)$/);g&&(f=g[1])}var h="image-"+Date.now()+"."+f;if("function"==typeof e.remoteFilename&&(h=e.remoteFilename(a)),c.append(e.uploadFieldName,a,h),"object"==typeof e.extraParams)for(var i in e.extraParams)e.extraParams.hasOwnProperty(i)&&c.append(i,e.extraParams[i]);if(d.open("POST",e.uploadUrl),"object"==typeof e.extraHeaders)for(var j in e.extraHeaders)e.extraHeaders.hasOwnProperty(j)&&d.setRequestHeader(j,e.extraHeaders[j]);return d.onload=function(){200===d.status||201===d.status?b.onFileUploadResponse(d):b.onFileUploadError(d)},e.beforeFileUpload(d)!==!1&&d.send(c),d},c.prototype.isFileAllowed=function(a){return"string"===a.kind?!1:0===this.settings.allowedTypes.indexOf("*")?!0:this.settings.allowedTypes.indexOf(a.type)>=0},c.prototype.onFileUploadResponse=function(a){if(this.settings.onFileUploadResponse.call(this,a)!==!1){var b=JSON.parse(a.responseText),c=b[this.settings.jsonFieldName];if(b&&c){var d;d="function"==typeof this.settings.urlText?this.settings.urlText.call(this,c,b):this.settings.urlText.replace(this.filenameTag,c);var e=this.editor.getValue().replace(this.lastValue,d);this.editor.setValue(e),this.settings.onFileUploaded.call(this,c)}}},c.prototype.onFileUploadError=function(a){if(this.settings.onFileUploadError.call(this,a)!==!1){var b=this.editor.getValue().replace(this.lastValue,"");this.editor.setValue(b)}},c.prototype.onFileInserted=function(a){this.settings.onFileReceived.call(this,a)!==!1&&(this.lastValue=this.settings.progressText,this.editor.insertValue(this.lastValue))},c.prototype.onPaste=function(a){var b,c=!1,d=a.clipboardData;if("object"==typeof d){b=d.items||d.files||[];for(var e=0;e<b.length;e++){var f=b[e];this.isFileAllowed(f)&&(c=!0,this.onFileInserted(f.getAsFile()),this.uploadFile(f.getAsFile()))}}return c&&a.preventDefault(),c},c.prototype.onDrop=function(a){for(var b=!1,c=0;c<a.dataTransfer.files.length;c++){var d=a.dataTransfer.files[c];this.isFileAllowed(d)&&(b=!0,this.onFileInserted(d),this.uploadFile(d))}return b},b.inlineAttachment=c}(document,window),function(a,b,c){"use strict";inlineAttachment.editors.jquery={};var d=function(a){var b=c(a);return{getValue:function(){return b.val()},insertValue:function(a){inlineAttachment.util.insertTextAtCursor(b[0],a)},setValue:function(a){b.val(a)}}};c.fn.inlineattachment=function(a){var b=c(this);return b.each(function(){var b=c(this),e=new d(b),f=new inlineAttachment(a,e);b.bind({paste:function(a){f.onPaste(a.originalEvent)},drop:function(a){a.stopPropagation(),a.preventDefault(),f.onDrop(a.originalEvent)},"dragenter dragover":function(a){a.stopPropagation(),a.preventDefault()}})}),this},inlineAttachment.editors.jquery.Editor=d}(document,window,jQuery);jquery.inline-attachment.js000066600000027551151761610720012050 0ustar00/*! inline-attachment - v2.0.3 - 2016-08-20 */
/*jslint newcap: true */
/*global XMLHttpRequest: false, FormData: false */
/*
 * Inline Text Attachment
 *
 * Author: Roy van Kaathoven
 * Contact: ik@royvankaathoven.nl
 */
(function(document, window) {
  'use strict';

  var inlineAttachment = function(options, instance) {
    this.settings = inlineAttachment.util.merge(options, inlineAttachment.defaults);
    this.editor = instance;
    this.filenameTag = '{filename}';
    this.lastValue = null;
  };

  /**
   * Will holds the available editors
   *
   * @type {Object}
   */
  inlineAttachment.editors = {};

  /**
   * Utility functions
   */
  inlineAttachment.util = {

    /**
     * Simple function to merge the given objects
     *
     * @param {Object[]} object Multiple object parameters
     * @returns {Object}
     */
    merge: function() {
      var result = {};
      for (var i = arguments.length - 1; i >= 0; i--) {
        var obj = arguments[i];
        for (var k in obj) {
          if (obj.hasOwnProperty(k)) {
            result[k] = obj[k];
          }
        }
      }
      return result;
    },

    /**
     * Append a line of text at the bottom, ensuring there aren't unnecessary newlines
     *
     * @param {String} appended Current content
     * @param {String} previous Value which should be appended after the current content
     */
    appendInItsOwnLine: function(previous, appended) {
      return (previous + "\n\n[[D]]" + appended)
        .replace(/(\n{2,})\[\[D\]\]/, "\n\n")
        .replace(/^(\n*)/, "");
    },

    /**
     * Inserts the given value at the current cursor position of the textarea element
     *
     * @param  {HtmlElement} el
     * @param  {String} value Text which will be inserted at the cursor position
     */
    insertTextAtCursor: function(el, text) {
      var scrollPos = el.scrollTop,
        strPos = 0,
        browser = false,
        range;

      if ((el.selectionStart || el.selectionStart === '0')) {
        browser = "ff";
      } else if (document.selection) {
        browser = "ie";
      }

      if (browser === "ie") {
        el.focus();
        range = document.selection.createRange();
        range.moveStart('character', -el.value.length);
        strPos = range.text.length;
      } else if (browser === "ff") {
        strPos = el.selectionStart;
      }

      var front = (el.value).substring(0, strPos);
      var back = (el.value).substring(strPos, el.value.length);
      el.value = front + text + back;
      strPos = strPos + text.length;
      if (browser === "ie") {
        el.focus();
        range = document.selection.createRange();
        range.moveStart('character', -el.value.length);
        range.moveStart('character', strPos);
        range.moveEnd('character', 0);
        range.select();
      } else if (browser === "ff") {
        el.selectionStart = strPos;
        el.selectionEnd = strPos;
        el.focus();
      }
      el.scrollTop = scrollPos;
    }
  };

  /**
   * Default configuration options
   *
   * @type {Object}
   */
  inlineAttachment.defaults = {
    /**
     * URL where the file will be send
     */
    uploadUrl: 'upload_attachment.php',

    /**
     * Which method will be used to send the file to the upload URL
     */
    uploadMethod: 'POST',

    /**
     * Name in which the file will be placed
     */
    uploadFieldName: 'file',

    /**
     * Extension which will be used when a file extension could not
     * be detected
     */
    defaultExtension: 'png',

    /**
     * JSON field which refers to the uploaded file URL
     */
    jsonFieldName: 'filename',

    /**
     * Allowed MIME types
     */
    allowedTypes: [
      'image/jpeg',
      'image/png',
      'image/jpg',
      'image/gif'
    ],

    /**
     * Text which will be inserted when dropping or pasting a file.
     * Acts as a placeholder which will be replaced when the file is done with uploading
     */
    progressText: '![Uploading file...]()',

    /**
     * When a file has successfully been uploaded the progressText
     * will be replaced by the urlText, the {filename} tag will be replaced
     * by the filename that has been returned by the server
     */
    urlText: "![file]({filename})",

    /**
     * Text which will be used when uploading has failed
     */
    errorText: "Error uploading file",

    /**
     * Extra parameters which will be send when uploading a file
     */
    extraParams: {},

    /**
     * Extra headers which will be send when uploading a file
     */
    extraHeaders: {},

    /**
     * Before the file is send
     */
    beforeFileUpload: function() {
      return true;
    },

    /**
     * Triggers when a file is dropped or pasted
     */
    onFileReceived: function() {},

    /**
     * Custom upload handler
     *
     * @return {Boolean} when false is returned it will prevent default upload behavior
     */
    onFileUploadResponse: function() {
      return true;
    },

    /**
     * Custom error handler. Runs after removing the placeholder text and before the alert().
     * Return false from this function to prevent the alert dialog.
     *
     * @return {Boolean} when false is returned it will prevent default error behavior
     */
    onFileUploadError: function() {
      return true;
    },

    /**
     * When a file has succesfully been uploaded
     */
    onFileUploaded: function() {}
  };

  /**
   * Uploads the blob
   *
   * @param  {Blob} file blob data received from event.dataTransfer object
   * @return {XMLHttpRequest} request object which sends the file
   */
  inlineAttachment.prototype.uploadFile = function(file) {
    var me = this,
      formData = new FormData(),
      xhr = new XMLHttpRequest(),
      settings = this.settings,
      extension = settings.defaultExtension || settings.defualtExtension;

    if (typeof settings.setupFormData === 'function') {
      settings.setupFormData(formData, file);
    }

    // Attach the file. If coming from clipboard, add a default filename (only works in Chrome for now)
    // http://stackoverflow.com/questions/6664967/how-to-give-a-blob-uploaded-as-formdata-a-file-name
    if (file.name) {
      var fileNameMatches = file.name.match(/\.(.+)$/);
      if (fileNameMatches) {
        extension = fileNameMatches[1];
      }
    }

    var remoteFilename = "image-" + Date.now() + "." + extension;
    if (typeof settings.remoteFilename === 'function') {
      remoteFilename = settings.remoteFilename(file);
    }

    formData.append(settings.uploadFieldName, file, remoteFilename);

    // Append the extra parameters to the formdata
    if (typeof settings.extraParams === "object") {
      for (var key in settings.extraParams) {
        if (settings.extraParams.hasOwnProperty(key)) {
          formData.append(key, settings.extraParams[key]);
        }
      }
    }

    xhr.open('POST', settings.uploadUrl);

    // Add any available extra headers
    if (typeof settings.extraHeaders === "object") {
        for (var header in settings.extraHeaders) {
            if (settings.extraHeaders.hasOwnProperty(header)) {
                xhr.setRequestHeader(header, settings.extraHeaders[header]);
            }
        }
    }

    xhr.onload = function() {
      // If HTTP status is OK or Created
      if (xhr.status === 200 || xhr.status === 201) {
        me.onFileUploadResponse(xhr);
      } else {
        me.onFileUploadError(xhr);
      }
    };
    if (settings.beforeFileUpload(xhr) !== false) {
      xhr.send(formData);
    }
    return xhr;
  };

  /**
   * Returns if the given file is allowed to handle
   *
   * @param {File} clipboard data file
   */
  inlineAttachment.prototype.isFileAllowed = function(file) {
    if (file.kind === 'string') { return false; }
    if (this.settings.allowedTypes.indexOf('*') === 0){
      return true;
    } else {
      return this.settings.allowedTypes.indexOf(file.type) >= 0;
    }
  };

  /**
   * Handles upload response
   *
   * @param  {XMLHttpRequest} xhr
   * @return {Void}
   */
  inlineAttachment.prototype.onFileUploadResponse = function(xhr) {
    if (this.settings.onFileUploadResponse.call(this, xhr) !== false) {
      var result = JSON.parse(xhr.responseText),
        filename = result[this.settings.jsonFieldName];

      if (result && filename) {
        var newValue;
        if (typeof this.settings.urlText === 'function') {
          newValue = this.settings.urlText.call(this, filename, result);
        } else {
          newValue = this.settings.urlText.replace(this.filenameTag, filename);
        }
        var text = this.editor.getValue().replace(this.lastValue, newValue);
        this.editor.setValue(text);
        this.settings.onFileUploaded.call(this, filename);
      }
    }
  };


  /**
   * Called when a file has failed to upload
   *
   * @param  {XMLHttpRequest} xhr
   * @return {Void}
   */
  inlineAttachment.prototype.onFileUploadError = function(xhr) {
    if (this.settings.onFileUploadError.call(this, xhr) !== false) {
      var text = this.editor.getValue().replace(this.lastValue, "");
      this.editor.setValue(text);
    }
  };

  /**
   * Called when a file has been inserted, either by drop or paste
   *
   * @param  {File} file
   * @return {Void}
   */
  inlineAttachment.prototype.onFileInserted = function(file) {
    if (this.settings.onFileReceived.call(this, file) !== false) {
      this.lastValue = this.settings.progressText;
      this.editor.insertValue(this.lastValue);
    }
  };


  /**
   * Called when a paste event occured
   * @param  {Event} e
   * @return {Boolean} if the event was handled
   */
  inlineAttachment.prototype.onPaste = function(e) {
    var result = false,
      clipboardData = e.clipboardData,
      items;

    if (typeof clipboardData === "object") {
      items = clipboardData.items || clipboardData.files || [];

      for (var i = 0; i < items.length; i++) {
        var item = items[i];
        if (this.isFileAllowed(item)) {
          result = true;
          this.onFileInserted(item.getAsFile());
          this.uploadFile(item.getAsFile());
        }
      }
    }

    if (result) { e.preventDefault(); }

    return result;
  };

  /**
   * Called when a drop event occures
   * @param  {Event} e
   * @return {Boolean} if the event was handled
   */
  inlineAttachment.prototype.onDrop = function(e) {
    var result = false;
    for (var i = 0; i < e.dataTransfer.files.length; i++) {
      var file = e.dataTransfer.files[i];
      if (this.isFileAllowed(file)) {
        result = true;
        this.onFileInserted(file);
        this.uploadFile(file);
      }
    }

    return result;
  };

  window.inlineAttachment = inlineAttachment;

})(document, window);

/*jslint newcap: true */
/*global inlineAttachment: false, jQuery: false */
/**
 * jQuery plugin for inline attach
 *
 * @param {document} document
 * @param {window} window
 * @param {jQuery} $
 */
(function(document, window, $) {
  'use strict';

  inlineAttachment.editors.jquery = {};

  /**
   * Creates a new editor using jQuery
   */
  var editor = function(instance) {

    var $this = $(instance);

    return {
      getValue: function() {
        return $this.val();
      },
      insertValue: function(val) {
        inlineAttachment.util.insertTextAtCursor($this[0], val);
      },
      setValue: function(val) {
        $this.val(val);
      }
    };
  };

  $.fn.inlineattachment = function(options) {

    var set = $(this);

    set.each(function() {

      var $this = $(this),
        ed = new editor($this),
        inlineattach = new inlineAttachment(options, ed);

      $this.bind({
        'paste': function(e) {
          inlineattach.onPaste(e.originalEvent);
        },
        'drop': function(e) {
          e.stopPropagation();
          e.preventDefault();
          inlineattach.onDrop(e.originalEvent);
        },
        'dragenter dragover': function(e) {
          e.stopPropagation();
          e.preventDefault();
        }
      });
    });

    return this;
  };

  inlineAttachment.editors.jquery.Editor = editor;

})(document, window, jQuery);inline-attachment.min.js000066600000010641151761610720011304 0ustar00/*! inline-attachment - v2.0.3 - 2016-08-20 */
!function(a,b){"use strict";var c=function(a,b){this.settings=c.util.merge(a,c.defaults),this.editor=b,this.filenameTag="{filename}",this.lastValue=null};c.editors={},c.util={merge:function(){for(var a={},b=arguments.length-1;b>=0;b--){var c=arguments[b];for(var d in c)c.hasOwnProperty(d)&&(a[d]=c[d])}return a},appendInItsOwnLine:function(a,b){return(a+"\n\n[[D]]"+b).replace(/(\n{2,})\[\[D\]\]/,"\n\n").replace(/^(\n*)/,"")},insertTextAtCursor:function(b,c){var d,e=b.scrollTop,f=0,g=!1;b.selectionStart||"0"===b.selectionStart?g="ff":a.selection&&(g="ie"),"ie"===g?(b.focus(),d=a.selection.createRange(),d.moveStart("character",-b.value.length),f=d.text.length):"ff"===g&&(f=b.selectionStart);var h=b.value.substring(0,f),i=b.value.substring(f,b.value.length);b.value=h+c+i,f+=c.length,"ie"===g?(b.focus(),d=a.selection.createRange(),d.moveStart("character",-b.value.length),d.moveStart("character",f),d.moveEnd("character",0),d.select()):"ff"===g&&(b.selectionStart=f,b.selectionEnd=f,b.focus()),b.scrollTop=e}},c.defaults={uploadUrl:"upload_attachment.php",uploadMethod:"POST",uploadFieldName:"file",defaultExtension:"png",jsonFieldName:"filename",allowedTypes:["image/jpeg","image/png","image/jpg","image/gif"],progressText:"![Uploading file...]()",urlText:"![file]({filename})",errorText:"Error uploading file",extraParams:{},extraHeaders:{},beforeFileUpload:function(){return!0},onFileReceived:function(){},onFileUploadResponse:function(){return!0},onFileUploadError:function(){return!0},onFileUploaded:function(){}},c.prototype.uploadFile=function(a){var b=this,c=new FormData,d=new XMLHttpRequest,e=this.settings,f=e.defaultExtension||e.defualtExtension;if("function"==typeof e.setupFormData&&e.setupFormData(c,a),a.name){var g=a.name.match(/\.(.+)$/);g&&(f=g[1])}var h="image-"+Date.now()+"."+f;if("function"==typeof e.remoteFilename&&(h=e.remoteFilename(a)),c.append(e.uploadFieldName,a,h),"object"==typeof e.extraParams)for(var i in e.extraParams)e.extraParams.hasOwnProperty(i)&&c.append(i,e.extraParams[i]);if(d.open("POST",e.uploadUrl),"object"==typeof e.extraHeaders)for(var j in e.extraHeaders)e.extraHeaders.hasOwnProperty(j)&&d.setRequestHeader(j,e.extraHeaders[j]);return d.onload=function(){200===d.status||201===d.status?b.onFileUploadResponse(d):b.onFileUploadError(d)},e.beforeFileUpload(d)!==!1&&d.send(c),d},c.prototype.isFileAllowed=function(a){return"string"===a.kind?!1:0===this.settings.allowedTypes.indexOf("*")?!0:this.settings.allowedTypes.indexOf(a.type)>=0},c.prototype.onFileUploadResponse=function(a){if(this.settings.onFileUploadResponse.call(this,a)!==!1){var b=JSON.parse(a.responseText),c=b[this.settings.jsonFieldName];if(b&&c){var d;d="function"==typeof this.settings.urlText?this.settings.urlText.call(this,c,b):this.settings.urlText.replace(this.filenameTag,c);var e=this.editor.getValue().replace(this.lastValue,d);this.editor.setValue(e),this.settings.onFileUploaded.call(this,c)}}},c.prototype.onFileUploadError=function(a){if(this.settings.onFileUploadError.call(this,a)!==!1){var b=this.editor.getValue().replace(this.lastValue,"");this.editor.setValue(b)}},c.prototype.onFileInserted=function(a){this.settings.onFileReceived.call(this,a)!==!1&&(this.lastValue=this.settings.progressText,this.editor.insertValue(this.lastValue))},c.prototype.onPaste=function(a){var b,c=!1,d=a.clipboardData;if("object"==typeof d){b=d.items||d.files||[];for(var e=0;e<b.length;e++){var f=b[e];this.isFileAllowed(f)&&(c=!0,this.onFileInserted(f.getAsFile()),this.uploadFile(f.getAsFile()))}}return c&&a.preventDefault(),c},c.prototype.onDrop=function(a){for(var b=!1,c=0;c<a.dataTransfer.files.length;c++){var d=a.dataTransfer.files[c];this.isFileAllowed(d)&&(b=!0,this.onFileInserted(d),this.uploadFile(d))}return b},b.inlineAttachment=c}(document,window),function(){"use strict";inlineAttachment.editors.input={Editor:function(a){var b=a;return{getValue:function(){return b.value},insertValue:function(a){inlineAttachment.util.insertTextAtCursor(b,a)},setValue:function(a){b.value=a}}},attachToInput:function(a,b){b=b||{};var c=new inlineAttachment.editors.input.Editor(a),d=new inlineAttachment(b,c);a.addEventListener("paste",function(a){d.onPaste(a)},!1),a.addEventListener("drop",function(a){a.stopPropagation(),a.preventDefault(),d.onDrop(a)},!1),a.addEventListener("dragenter",function(a){a.stopPropagation(),a.preventDefault()},!1),a.addEventListener("dragover",function(a){a.stopPropagation(),a.preventDefault()},!1)}}}();