/*! * medium-editor-insert-plugin v2.5.0 - jQuery insert plugin for MediumEditor * * http://linkesch.com/medium-editor-insert-plugin * * Copyright (c) 2014 Pavel Linkesch (http://linkesch.com) * Released under the MIT license */ (function (factory) { if (typeof define === 'function' && define.amd) { define(['jquery', 'handlebars/runtime', 'medium-editor', 'blueimp-file-upload', 'jquery-sortable'], factory); } else if (typeof module === 'object' && module.exports) { module.exports = function (jQuery) { if (typeof window === 'undefined') { throw new Error("medium-editor-insert-plugin runs only in a browser.") } if (jQuery === undefined) { jQuery = require('jquery'); } window.jQuery = jQuery; Handlebars = require('handlebars/runtime'); MediumEditor = require('medium-editor'); require('jquery-sortable'); require('blueimp-file-upload'); factory(jQuery, Handlebars, MediumEditor); return jQuery; }; } else { factory(jQuery, Handlebars, MediumEditor); } }(function ($, Handlebars, MediumEditor) { this["MediumInsert"] = this["MediumInsert"] || {}; this["MediumInsert"]["Templates"] = this["MediumInsert"]["Templates"] || {}; this["MediumInsert"]["Templates"]["src/js/templates/core-buttons.hbs"] = Handlebars.template({"1":function(container,depth0,helpers,partials,data) { var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function"; return "
  • \n"; },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { var stack1; return "
    \n \n \n
    \n"; },"useData":true}); this["MediumInsert"]["Templates"]["src/js/templates/core-caption.hbs"] = Handlebars.template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { var helper; return "
    "; },"useData":true}); this["MediumInsert"]["Templates"]["src/js/templates/core-empty-line.hbs"] = Handlebars.template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { return "


    \n"; },"useData":true}); this["MediumInsert"]["Templates"]["src/js/templates/embeds-toolbar.hbs"] = Handlebars.template({"1":function(container,depth0,helpers,partials,data) { var stack1; return "
    \n \n
    \n"; },"2":function(container,depth0,helpers,partials,data) { var stack1; return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.label : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : ""); },"3":function(container,depth0,helpers,partials,data) { var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function"; return "
  • \n \n
  • \n"; },"5":function(container,depth0,helpers,partials,data) { var stack1; return "
    \n \n
    \n"; },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { var stack1, alias1=depth0 != null ? depth0 : (container.nullContext || {}); return ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.styles : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + "\n" + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.actions : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : ""); },"useData":true}); this["MediumInsert"]["Templates"]["src/js/templates/embeds-wrapper.hbs"] = Handlebars.template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { var stack1, helper; return "
    \n
    \n
    \n " + ((stack1 = ((helper = (helper = helpers.html || (depth0 != null ? depth0.html : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"html","hash":{},"data":data}) : helper))) != null ? stack1 : "") + "\n
    \n
    \n
    \n
    "; },"useData":true}); this["MediumInsert"]["Templates"]["src/js/templates/images-fileupload.hbs"] = Handlebars.template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { return ""; },"useData":true}); this["MediumInsert"]["Templates"]["src/js/templates/images-image.hbs"] = Handlebars.template({"1":function(container,depth0,helpers,partials,data) { return "
    \n"; },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}); return "
    \n \""\n" + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.progress : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + "
    \n"; },"useData":true}); this["MediumInsert"]["Templates"]["src/js/templates/images-video.hbs"] = Handlebars.template({"1":function(container,depth0,helpers,partials,data) { return "
    \n"; },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}); return "
    \n
    \n" + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.progress : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + "
    \n"; },"useData":true}); this["MediumInsert"]["Templates"]["src/js/templates/images-progressbar.hbs"] = Handlebars.template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { return "0"; },"useData":true}); this["MediumInsert"]["Templates"]["src/js/templates/images-toolbar.hbs"] = Handlebars.template({"1":function(container,depth0,helpers,partials,data) { var stack1; return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.label : depth0),{"name":"if","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : ""); },"2":function(container,depth0,helpers,partials,data) { var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function"; return "
  • \n \n
  • \n"; },"4":function(container,depth0,helpers,partials,data) { var stack1; return "
    \n \n
    \n"; },"5":function(container,depth0,helpers,partials,data) { var stack1; return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.label : depth0),{"name":"if","hash":{},"fn":container.program(6, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : ""); },"6":function(container,depth0,helpers,partials,data) { var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function"; return "
  • \n \n
  • \n"; },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { var stack1, alias1=depth0 != null ? depth0 : (container.nullContext || {}); return "
    \n \n
    \n\n" + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.actions : depth0),{"name":"if","hash":{},"fn":container.program(4, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : ""); },"useData":true}); ;(function ($, window, document, undefined) { 'use strict'; /** Default values */ var pluginName = 'mediumInsert', defaults = { editor: null, enabled: true, addons: { images: true, // boolean or object containing configuration embeds: true } }; /** * Capitalize first character * * @param {string} str * @return {string} */ function ucfirst(str) { return str.charAt(0).toUpperCase() + str.slice(1); } /** * Core plugin's object * * Sets options, variables and calls init() function * * @constructor * @param {DOM} el - DOM element to init the plugin on * @param {object} options - Options to override defaults * @return {void} */ function Core(el, options) { var editor; this.el = el; this.$el = $(el); this.templates = window.MediumInsert.Templates; if (options) { // Fix #142 // Avoid deep copying editor object, because since v2.3.0 it contains circular references which causes jQuery.extend to break // Instead copy editor object to this.options manually editor = options.editor; options.editor = null; } this.options = $.extend(true, {}, defaults, options); this.options.editor = editor; if (options) { options.editor = editor; // Restore original object definition } this._defaults = defaults; this._name = pluginName; // Extend editor's functions if (this.options && this.options.editor) { if (this.options.editor._serialize === undefined) { this.options.editor._serialize = this.options.editor.serialize; } if (this.options.editor._destroy === undefined) { this.options.editor._destroy = this.options.editor.destroy; } if (this.options.editor._setup === undefined) { this.options.editor._setup = this.options.editor.setup; } this.options.editor._hideInsertButtons = this.hideButtons; this.options.editor.serialize = this.editorSerialize; this.options.editor.destroy = this.editorDestroy; this.options.editor.setup = this.editorSetup; if (this.options.editor.getExtensionByName('placeholder') !== undefined) { this.options.editor.getExtensionByName('placeholder').updatePlaceholder = this.editorUpdatePlaceholder; } } } /** * Initialization * * @return {void} */ Core.prototype.init = function () { this.$el.addClass('medium-editor-insert-plugin'); if (typeof this.options.addons !== 'object' || Object.keys(this.options.addons).length === 0) { this.disable(); } this.initAddons(); this.clean(); this.events(); }; /** * Event listeners * * @return {void} */ Core.prototype.events = function () { var that = this; this.$el /*.on('dragover drop', function (e) { e.preventDefault(); })*/ .on('keyup click', $.proxy(this, 'toggleButtons')) .on('selectstart mousedown', '.medium-insert, .medium-insert-buttons', $.proxy(this, 'disableSelection')) .on('click', '.medium-insert-buttons-show', $.proxy(this, 'toggleAddons')) .on('click', '.medium-insert-action', $.proxy(this, 'addonAction')) .on('paste', '.medium-insert-caption-placeholder', function (e) { $.proxy(that, 'removeCaptionPlaceholder')($(e.target)); }); $(window).on('resize', $.proxy(this, 'positionButtons', null)); }; /** * Return editor instance * * @return {object} MediumEditor */ Core.prototype.getEditor = function () { return this.options.editor; }; /** * Extend editor's serialize function * * @return {object} Serialized data */ Core.prototype.editorSerialize = function () { var data = this._serialize(); $.each(data, function (key) { var $data = $('
    ').html(data[key].value); $data.find('.medium-insert-buttons').remove(); $data.find('.medium-insert-active').removeClass('medium-insert-active'); // Restore original embed code from embed wrapper attribute value. $data.find('[data-embed-code]').each(function () { var $this = $(this), html = $('
    ').html($this.attr('data-embed-code')).text(); $this.html(html); }); data[key].value = $data.html(); }); return data; }; /** * Extend editor's destroy function to deactivate this plugin too * * @return {void} */ Core.prototype.editorDestroy = function () { $.each(this.elements, function (key, el) { if ($(el).data('plugin_' + pluginName) instanceof Core) { $(el).data('plugin_' + pluginName).disable(); } }); this._destroy(); }; /** * Extend editor's setup function to activate this plugin too * * @return {void} */ Core.prototype.editorSetup = function () { this._setup(); $.each(this.elements, function (key, el) { if ($(el).data('plugin_' + pluginName) instanceof Core) { $(el).data('plugin_' + pluginName).enable(); } }); }; /** * Extend editor's placeholder.updatePlaceholder function to show placeholder dispite of the plugin buttons * * @return {void} */ Core.prototype.editorUpdatePlaceholder = function (el, dontShow) { var contents = $(el).children() .not('.medium-insert-buttons').contents(); if (!dontShow && contents.length === 1 && contents[0].nodeName.toLowerCase() === 'br') { this.showPlaceholder(el); this.base._hideInsertButtons($(el)); } else { this.hidePlaceholder(el); } }; /** * Trigger editableInput on editor * * @return {void} */ Core.prototype.triggerInput = function () { if (this.getEditor()) { this.getEditor().trigger('editableInput', null, this.el); } }; /** * Deselects selected text * * @return {void} */ Core.prototype.deselect = function () { document.getSelection().removeAllRanges(); }; /** * Disables the plugin * * @return {void} */ Core.prototype.disable = function () { this.options.enabled = false; this.$el.find('.medium-insert-buttons').addClass('hide'); }; /** * Enables the plugin * * @return {void} */ Core.prototype.enable = function () { this.options.enabled = true; this.$el.find('.medium-insert-buttons').removeClass('hide'); }; /** * Disables selectstart mousedown events on plugin elements except images * * @return {void} */ Core.prototype.disableSelection = function (e) { var $el = $(e.target); if ($el.is('img') === false || $el.hasClass('medium-insert-buttons-show')) { e.preventDefault(); } }; /** * Initialize addons * * @return {void} */ Core.prototype.initAddons = function () { var that = this; if (!this.options.addons || this.options.addons.length === 0) { return; } $.each(this.options.addons, function (addon, options) { var addonName = pluginName + ucfirst(addon); if (options === false) { delete that.options.addons[addon]; return; } that.$el[addonName](options); that.options.addons[addon] = that.$el.data('plugin_' + addonName).options; }); }; /** * Cleans a content of the editor * * @return {void} */ Core.prototype.clean = function () { var that = this, $buttons, $lastEl, $text; if (this.options.enabled === false) { return; } if (this.$el.html().length === 0) { this.$el.html(this.templates['src/js/templates/core-empty-line.hbs']().trim()); } // Fix #29 // Wrap content text in

    to avoid Firefox problems $text = this.$el .contents() .filter(function () { return (this.nodeName === '#text' && $.trim($(this).text()) !== '') || this.nodeName.toLowerCase() === 'br'; }); $text.each(function () { $(this).wrap('

    '); // Fix #145 // Move caret at the end of the element that's being wrapped that.moveCaret($(this).parent(), $(this).text().length); }); this.addButtons(); $buttons = this.$el.find('.medium-insert-buttons'); $lastEl = $buttons.prev(); if ($lastEl.attr('class') && $lastEl.attr('class').match(/medium\-insert(?!\-active)/)) { $buttons.before(this.templates['src/js/templates/core-empty-line.hbs']().trim()); } }; /** * Returns HTML template of buttons * * @return {string} HTML template of buttons */ Core.prototype.getButtons = function () { if (this.options.enabled === false) { return; } return this.templates['src/js/templates/core-buttons.hbs']({ addons: this.options.addons }).trim(); }; /** * Appends buttons at the end of the $el * * @return {void} */ Core.prototype.addButtons = function () { if (this.$el.find('.medium-insert-buttons').length === 0) { this.$el.append(this.getButtons()); } }; /** * Move buttons to current active, empty paragraph and show them * * @return {void} */ Core.prototype.toggleButtons = function (e) { var $el = $(e.target), selection = window.getSelection(), that = this, range, $current, $p, activeAddon; if (this.options.enabled === false) { return; } if (!selection || selection.rangeCount === 0) { $current = $el; } else { range = selection.getRangeAt(0); $current = $(range.commonAncestorContainer); } // When user clicks on editor's placeholder in FF, $current el is editor itself, not the first paragraph as it should if ($current.hasClass('medium-editor-insert-plugin')) { $current = $current.find('p:first'); } $p = $current.is('p') ? $current : $current.closest('p'); this.clean(); if ($el.hasClass('medium-editor-placeholder') === false && $el.closest('.medium-insert-buttons').length === 0 && $current.closest('.medium-insert-buttons').length === 0) { this.$el.find('.medium-insert-active').removeClass('medium-insert-active'); $.each(this.options.addons, function (addon) { if ($el.closest('.medium-insert-' + addon).length) { $current = $el; } if ($current.closest('.medium-insert-' + addon).length) { $p = $current.closest('.medium-insert-' + addon); activeAddon = addon; return; } }); if ($p.length && (($p.text().trim() === '' && !activeAddon) || activeAddon === 'images')) { $p.addClass('medium-insert-active'); if (activeAddon === 'images') { this.$el.find('.medium-insert-buttons').attr('data-active-addon', activeAddon); } else { this.$el.find('.medium-insert-buttons').removeAttr('data-active-addon'); } // If buttons are displayed on addon paragraph, wait 100ms for possible captions to display setTimeout(function () { that.positionButtons(activeAddon); that.showButtons(activeAddon); }, activeAddon ? 100 : 0); } else { this.hideButtons(); } } }; /** * Show buttons * * @param {string} activeAddon - Name of active addon * @returns {void} */ Core.prototype.showButtons = function (activeAddon) { var $buttons = this.$el.find('.medium-insert-buttons'); $buttons.show(); $buttons.find('li').show(); if (activeAddon) { $buttons.find('li').hide(); $buttons.find('button[data-addon="' + activeAddon + '"]').parent().show(); } }; /** * Hides buttons * * @param {jQuery} $el - Editor element * @returns {void} */ Core.prototype.hideButtons = function ($el) { $el = $el || this.$el; $el.find('.medium-insert-buttons').hide(); $el.find('.medium-insert-buttons-addons').hide(); $el.find('.medium-insert-buttons-show').removeClass('medium-insert-buttons-rotate'); }; /** * Position buttons * * @param {string} activeAddon - Name of active addon * @return {void} */ Core.prototype.positionButtons = function (activeAddon) { var $buttons = this.$el.find('.medium-insert-buttons'), $p = this.$el.find('.medium-insert-active'), $lastCaption = $p.hasClass('medium-insert-images-grid') ? [] : $p.find('figure:last figcaption'), elementsContainer = this.getEditor() ? this.getEditor().options.elementsContainer : $('body').get(0), elementsContainerAbsolute = ['absolute', 'fixed'].indexOf(window.getComputedStyle(elementsContainer).getPropertyValue('position')) > -1, position = {}; if ($p.length) { position.left = $p.position().left; position.top = $p.position().top; if (activeAddon) { position.left += $p.width() - $buttons.find('.medium-insert-buttons-show').width() - 10; position.top += $p.height() - 20 + ($lastCaption.length ? -$lastCaption.height() - parseInt($lastCaption.css('margin-top'), 10) : 10); } else { position.left += -parseInt($buttons.find('.medium-insert-buttons-addons').css('left'), 10) - parseInt($buttons.find('.medium-insert-buttons-addons button:first').css('margin-left'), 10); position.top += parseInt($p.css('margin-top'), 10); } if (elementsContainerAbsolute) { position.top += elementsContainer.scrollTop; } if (this.$el.hasClass('medium-editor-placeholder') === false && position.left < 0) { position.left = $p.position().left; } $buttons.css(position); } }; /** * Toggles addons buttons * * @return {void} */ Core.prototype.toggleAddons = function () { if (this.$el.find('.medium-insert-buttons').attr('data-active-addon') === 'images') { this.$el.find('.medium-insert-buttons').find('button[data-addon="images"]').click(); return; } this.$el.find('.medium-insert-buttons-addons').fadeToggle(); this.$el.find('.medium-insert-buttons-show').toggleClass('medium-insert-buttons-rotate'); }; /** * Hide addons buttons * * @return {void} */ Core.prototype.hideAddons = function () { this.$el.find('.medium-insert-buttons-addons').hide(); this.$el.find('.medium-insert-buttons-show').removeClass('medium-insert-buttons-rotate'); }; /** * Call addon's action * * @param {Event} e * @return {void} */ Core.prototype.addonAction = function (e) { var $a = $(e.currentTarget), addon = $a.data('addon'), action = $a.data('action'); this.$el.data('plugin_' + pluginName + ucfirst(addon))[action](); }; /** * Move caret at the beginning of the empty paragraph * * @param {jQuery} $el Element where to place the caret * @param {integer} position Position where to move caret. Default: 0 * * @return {void} */ Core.prototype.moveCaret = function ($el, position) { var range, sel, el, textEl; position = position || 0; range = document.createRange(); sel = window.getSelection(); el = $el.get(0); if (!el.childNodes.length) { textEl = document.createTextNode(' '); el.appendChild(textEl); } range.setStart(el.childNodes[0], position); range.collapse(true); sel.removeAllRanges(); sel.addRange(range); }; /** * Add caption * * @param {jQuery Element} $el * @param {string} placeholder * @return {void} */ Core.prototype.addCaption = function ($el, placeholder) { var $caption = $el.find('figcaption'); if ($caption.length === 0) { $el.append(this.templates['src/js/templates/core-caption.hbs']({ placeholder: placeholder })); } }; /** * Remove captions * * @param {jQuery Element} $ignore * @return {void} */ Core.prototype.removeCaptions = function ($ignore) { var $captions = this.$el.find('figcaption'); if ($ignore) { $captions = $captions.not($ignore); } $captions.each(function () { if ($(this).hasClass('medium-insert-caption-placeholder') || $(this).text().trim() === '') { $(this).remove(); } }); }; /** * Remove caption placeholder * * @param {jQuery Element} $el * @return {void} */ Core.prototype.removeCaptionPlaceholder = function ($el) { var $caption = $el.is('figcaption') ? $el : $el.find('figcaption'); if ($caption.length) { $caption .removeClass('medium-insert-caption-placeholder') .removeAttr('data-placeholder'); } }; /** Plugin initialization */ $.fn[pluginName] = function (options) { return this.each(function () { var that = this, textareaId; if ($(that).is('textarea')) { textareaId = $(that).attr('medium-editor-textarea-id'); that = $(that).siblings('[medium-editor-textarea-id="' + textareaId + '"]').get(0); } if (!$.data(that, 'plugin_' + pluginName)) { // Plugin initialization $.data(that, 'plugin_' + pluginName, new Core(that, options)); $.data(that, 'plugin_' + pluginName).init(); } else if (typeof options === 'string' && $.data(that, 'plugin_' + pluginName)[options]) { // Method call $.data(that, 'plugin_' + pluginName)[options](); } }); }; })(jQuery, window, document); ; (function ($, window, document, undefined) { 'use strict'; // defaultStatus var pluginName = 'mediumInsert', addonName = 'Videos', defaults = { label: '', videos: '

    ', video: '
    ', emptyMessage: 'No videos are in the videos', url: '/handlers/DragNDrop/UploadHandler.ashx', data: [{ name: 'domain', value: 'current' }, { name: 'filter', value: 'video' }] //, 'filter': 'user'] }; // this is redundant function Videos(el, options) { this.el = el; this.$el = $(el); this.templates = window.MediumInsert.Templates; this.core = this.$el.data('plugin_' + pluginName); this.options = $.extend(true, {}, defaults, options); // patch optional allow options! this.options.data = $.extend(true, [], defaults.data, this.options.data); this._defaults = defaults; this._name = pluginName; this.init(); } Videos.prototype.init = function () { $('#medium-videos').remove(); $(document.body).append(this.options.videos); this.events(); }; Videos.prototype.events = function() { }; Videos.prototype.getCore = function() { return this.core; }; Videos.prototype.add = function() { // make the videos if (this.options.url.length && this.options.data.length) { /////KANG'd from Images.prototype.add var $place = this.$el.find('.medium-insert-active'); // Fix #132 // Make sure that the content of the paragraph is empty and
    is wrapped in

    to avoid Firefox problems $place.html(this.templates['src/js/templates/core-empty-line.hbs']().trim()); // Replace paragraph with div to prevent #124 issue with pasting in Chrome, // because medium editor wraps inserted content into paragraph and paragraphs can't be nested if ($place.is('p')) { $place.replaceWith('
    ' + $place.html() + '
    '); $place = this.$el.find('.medium-insert-active'); this.core.moveCaret($place); } ///// //var Videos = this.options.Videos; //var imageHtml = this.options.image; //var emptyMessage = this.options.emptyMessage; var that = this; $.ajax({url: this.options.url, type: 'GET', data: this.options.data, dataType: 'json', success: function (data) { //console.log(data); var imagesHtml = ''; //data = $.parseJSON(data); $.each(data, function(i, item) { imagesHtml += that.options.video.formatUnicorn({path: item.path}); }); if (imagesHtml.length == 0) imagesHtml = that.options.emptyMessage; var videos = that.options.videos.formatUnicorn({paths: imagesHtml}); $("#medium-videos").remove(); $(document.body).append(videos); $("#medium-videos").modal(); $('#medium-videos .videos-pick').click(function (e) { $.proxy(that, 'showImage', $(this).find('iframe').first().attr('src'))(); $('#medium-videos').modal('hide'); }); }, error: function (data) { console.log(data); } }); } else console.log('Please check the data and URL configuration for the Videos Plugin.') }; Videos.prototype.showImage = function (img) { var $place = this.$el.find('.medium-insert-active'), that; // Hide editor's placeholder $place.click(); // If preview is allowed and preview image already exists, // replace it with uploaded image that = this; // check for medium insert var wrapper = $place.parent(); if ($(wrapper).is('div') && !$(wrapper).hasClass('html_content')) { // form-control medium-editor-element medium-editor-insert-plugin medium-insert-active if (!$(wrapper).hasClass('medium-insert-active')) $(wrapper).addClass('medium-insert-active'); } else $place.wrap('
    '); $place.replaceWith($(this.templates['src/js/templates/images-video.hbs']({ img: img, class: 'embed-responsive embed-responsive-16by9' }))); //.wrap('
    '); //$place.find('br').remove(); // make editable //$place.find('figure[contenteditable="false"]').attr('contenteditable', 'true'); $(this.$el.find('.medium-insert-active')).click(); this.core.hideButtons(); this.core.triggerInput(); //return data.context; }; $.fn[pluginName + addonName] = function(options) { return this.each(function() { if (!$.data(this, 'plugin_' + pluginName + addonName)) { $.data(this, 'plugin_' + pluginName + addonName, new Videos(this, options)); } }); }; })(jQuery, window, document); ; (function ($, window, document, undefined) { 'use strict'; // defaultStatus var pluginName = 'mediumInsert', addonName = 'Gallery', defaults = { label: '', gallery: '', image: '
    ', emptyMessage: 'No images are in the gallery', url: '/handlers/DragNDrop/UploadHandler.ashx', data: [{ name: 'domain', value: 'current' }, { name: 'filter', value: 'images/' }] //, 'filter': 'user'] }; // this is redundant function Gallery(el, options) { this.el = el; this.$el = $(el); this.templates = window.MediumInsert.Templates; this.core = this.$el.data('plugin_' + pluginName); this.options = $.extend(true, {}, defaults, options); // patch optional allow options! this.options.data = $.extend(true, [], defaults.data, this.options.data); this._defaults = defaults; this._name = pluginName; this.init(); } Gallery.prototype.init = function () { $('#medium-gallery').remove(); $(document.body).append(this.options.gallery); this.events(); }; Gallery.prototype.events = function() { }; Gallery.prototype.getCore = function() { return this.core; }; Gallery.prototype.add = function() { // make the gallery if (this.options.url.length && this.options.data.length) { /////KANG'd from Images.prototype.add var $place = this.$el.find('.medium-insert-active'); // Fix #132 // Make sure that the content of the paragraph is empty and
    is wrapped in

    to avoid Firefox problems $place.html(this.templates['src/js/templates/core-empty-line.hbs']().trim()); // Replace paragraph with div to prevent #124 issue with pasting in Chrome, // because medium editor wraps inserted content into paragraph and paragraphs can't be nested if ($place.is('p')) { $place.replaceWith('
    ' + $place.html() + '
    '); $place = this.$el.find('.medium-insert-active'); this.core.moveCaret($place); } ///// //var gallery = this.options.gallery; //var imageHtml = this.options.image; //var emptyMessage = this.options.emptyMessage; var that = this; $.ajax({url: this.options.url, type: 'GET', data: this.options.data, dataType: 'json', success: function (data) { //console.log(data); var imagesHtml = ''; //data = $.parseJSON(data); $.each(data, function(i, item) { imagesHtml += that.options.image.formatUnicorn({path: item.path}); }); if (imagesHtml.length == 0) imagesHtml = that.options.emptyMessage; var gallery = that.options.gallery.formatUnicorn({paths: imagesHtml}); $("#medium-gallery").remove(); $(document.body).append(gallery); $("#medium-gallery").modal(); $('#medium-gallery .gallery-pick').click(function (e) { $.proxy(that, 'showImage', $(this).attr('src'))(); $('#medium-gallery').modal('hide'); }); }, error: function (data) { console.log(data); } }); } else console.log('Please check the data and URL configuration for the Gallery Plugin.') }; Gallery.prototype.showImage = function (img) { var $place = this.$el.find('.medium-insert-active'), that; // Hide editor's placeholder $place.click(); // If preview is allowed and preview image already exists, // replace it with uploaded image that = this; // check for medium insert var wrapper = $place.parent(); if ($(wrapper).is('div') && !$(wrapper).hasClass('html_content')) { // form-control medium-editor-element medium-editor-insert-plugin medium-insert-active if (!$(wrapper).hasClass('medium-insert-active')) $(wrapper).addClass('medium-insert-active'); } else $place.wrap('
    '); $place.replaceWith($(this.templates['src/js/templates/images-image.hbs']({ img: img, class: 'img-responsive content-image' }))); //.wrap('
    '); //$place.find('br').remove(); // make editable //$place.find('figure[contenteditable="false"]').attr('contenteditable', 'true'); $(this.$el.find('.medium-insert-active')).click(); this.core.hideButtons(); this.core.triggerInput(); //return data.context; }; $.fn[pluginName + addonName] = function(options) { return this.each(function() { if (!$.data(this, 'plugin_' + pluginName + addonName)) { $.data(this, 'plugin_' + pluginName + addonName, new Gallery(this, options)); } }); }; })(jQuery, window, document); ; (function ($, window, document, undefined) { 'use strict'; /** Default values */ var pluginName = 'mediumInsert', addonName = 'Embeds', // first char is uppercase defaults = { label: '', placeholder: 'Paste a YouTube, Vimeo, Facebook, Twitter or Instagram link and press Enter', oembedProxy: 'http://medium.iframe.ly/api/oembed?iframe=1', captions: true, captionPlaceholder: 'Type caption (optional)', storeMeta: false, styles: { wide: { label: '' // added: function ($el) {}, // removed: function ($el) {} }, left: { label: '' // added: function ($el) {}, // removed: function ($el) {} }, right: { label: '' // added: function ($el) {}, // removed: function ($el) {} } }, actions: { remove: { label: '', clicked: function () { var $event = $.Event('keydown'); $event.which = 8; $(document).trigger($event); } } }, parseOnPaste: false }; /** * Embeds object * * Sets options, variables and calls init() function * * @constructor * @param {DOM} el - DOM element to init the plugin on * @param {object} options - Options to override defaults * @return {void} */ function Embeds(el, options) { this.el = el; this.$el = $(el); this.templates = window.MediumInsert.Templates; this.core = this.$el.data('plugin_' + pluginName); this.options = $.extend(true, {}, defaults, options); this._defaults = defaults; this._name = pluginName; // Extend editor's functions if (this.core.getEditor()) { this.core.getEditor()._serializePreEmbeds = this.core.getEditor().serialize; this.core.getEditor().serialize = this.editorSerialize; } this.init(); } /** * Initialization * * @return {void} */ Embeds.prototype.init = function () { var $embeds = this.$el.find('.medium-insert-embeds'); $embeds.attr('contenteditable', false); $embeds.each(function () { if ($(this).find('.medium-insert-embeds-overlay').length === 0) { $(this).append($('
    ').addClass('medium-insert-embeds-overlay')); } }); this.events(); this.backwardsCompatibility(); }; /** * Event listeners * * @return {void} */ Embeds.prototype.events = function () { $(document) .on('click', $.proxy(this, 'unselectEmbed')) .on('keydown', $.proxy(this, 'removeEmbed')) .on('click', '.medium-insert-embeds-toolbar .medium-editor-action', $.proxy(this, 'toolbarAction')) .on('click', '.medium-insert-embeds-toolbar2 .medium-editor-action', $.proxy(this, 'toolbar2Action')); this.$el .on('keyup click paste', $.proxy(this, 'togglePlaceholder')) .on('keydown', $.proxy(this, 'processLink')) .on('click', '.medium-insert-embeds-overlay', $.proxy(this, 'selectEmbed')) .on('contextmenu', '.medium-insert-embeds-placeholder', $.proxy(this, 'fixRightClickOnPlaceholder')); if (this.options.parseOnPaste) { this.$el .on('paste', $.proxy(this, 'processPasted')); } $(window) .on('resize', $.proxy(this, 'autoRepositionToolbars')); }; /** * Replace v0.* class names with new ones, wrap embedded content to new structure * * @return {void} */ Embeds.prototype.backwardsCompatibility = function () { var that = this; this.$el.find('.mediumInsert-embeds') .removeClass('mediumInsert-embeds') .addClass('medium-insert-embeds'); this.$el.find('.medium-insert-embeds').each(function () { if ($(this).find('.medium-insert-embed').length === 0) { $(this).after(that.templates['src/js/templates/embeds-wrapper.hbs']({ html: $(this).html() })); $(this).remove(); } }); }; /** * Extend editor's serialize function * * @return {object} Serialized data */ Embeds.prototype.editorSerialize = function () { var data = this._serializePreEmbeds(); $.each(data, function (key) { var $data = $('
    ').html(data[key].value), $embeds = $data.find('.medium-insert-embeds'); $embeds.removeAttr('contenteditable'); $embeds.find('figcaption').removeAttr('contenteditable'); $data.find('.medium-insert-embeds-overlay').remove(); data[key].value = $data.html(); }); return data; }; /** * Add embedded element * * @return {void} */ Embeds.prototype.add = function () { var $place = this.$el.find('.medium-insert-active'); // Fix #132 // Make sure that the content of the paragraph is empty and
    is wrapped in

    to avoid Firefox problems $place.html(this.templates['src/js/templates/core-empty-line.hbs']().trim()); // Replace paragraph with div to prevent #124 issue with pasting in Chrome, // because medium editor wraps inserted content into paragraph and paragraphs can't be nested if ($place.is('p')) { $place.replaceWith('
    ' + $place.html() + '
    '); $place = this.$el.find('.medium-insert-active'); this.core.moveCaret($place); } $place.addClass('medium-insert-embeds medium-insert-embeds-input medium-insert-embeds-active'); this.togglePlaceholder({ target: $place.get(0) }); $place.click(); this.core.hideButtons(); }; /** * Toggles placeholder * * @param {Event} e * @return {void} */ Embeds.prototype.togglePlaceholder = function (e) { var $place = $(e.target), selection = window.getSelection(), range, $current, text; if (!selection || selection.rangeCount === 0) { return; } range = selection.getRangeAt(0); $current = $(range.commonAncestorContainer); if ($current.hasClass('medium-insert-embeds-active')) { $place = $current; } else if ($current.closest('.medium-insert-embeds-active').length) { $place = $current.closest('.medium-insert-embeds-active'); } if ($place.hasClass('medium-insert-embeds-active')) { text = $place.text().trim(); if (text === '' && $place.hasClass('medium-insert-embeds-placeholder') === false) { $place .addClass('medium-insert-embeds-placeholder') .attr('data-placeholder', this.options.placeholder); } else if (text !== '' && $place.hasClass('medium-insert-embeds-placeholder')) { $place .removeClass('medium-insert-embeds-placeholder') .removeAttr('data-placeholder'); } } else { this.$el.find('.medium-insert-embeds-active').remove(); } }; /** * Right click on placeholder in Chrome selects whole line. Fix this by placing caret at the end of line * * @param {Event} e * @return {void} */ Embeds.prototype.fixRightClickOnPlaceholder = function (e) { this.core.moveCaret($(e.target)); }; /** * Process link * * @param {Event} e * @return {void} */ Embeds.prototype.processLink = function (e) { var $place = this.$el.find('.medium-insert-embeds-active'), url; if (!$place.length) { return; } url = $place.text().trim(); // Return empty placeholder on backspace, delete or enter if (url === '' && [8, 46, 13].indexOf(e.which) !== -1) { $place.remove(); return; } if (e.which === 13) { e.preventDefault(); e.stopPropagation(); if (this.options.oembedProxy) { this.oembed(url); } else { this.parseUrl(url); } } }; /** * Process Pasted * * @param {Event} e * @return {void} */ Embeds.prototype.processPasted = function (e) { var pastedUrl, linkRegEx; if ($(".medium-insert-embeds-active").length) { return; } pastedUrl = e.originalEvent.clipboardData.getData('text'); linkRegEx = new RegExp('^(http(s?):)?\/\/','i'); if (linkRegEx.test(pastedUrl)) { if (this.options.oembedProxy) { this.oembed(pastedUrl, true); } else { this.parseUrl(pastedUrl, true); } } }; /** * Get HTML via oEmbed proxy * * @param {string} url * @return {void} */ Embeds.prototype.oembed = function (url, pasted) { var that = this; $.support.cors = true; $.ajax({ crossDomain: true, cache: false, url: this.options.oembedProxy, dataType: 'json', data: { url: url }, success: function (data) { var html = data && data.html; if (that.options.storeMeta) { html += '
    '; } if (data && !html && data.type === 'photo' && data.url) { html = ''; } if (!html) { // Prevent render empty embed. $.proxy(that, 'convertBadEmbed', url)(); return; } if (pasted) { $.proxy(that, 'embed', html, url)(); } else { $.proxy(that, 'embed', html)(); } }, error: function (jqXHR, textStatus, errorThrown) { var responseJSON = (function () { try { return JSON.parse(jqXHR.responseText); } catch (e) { } })(); if (typeof window.console !== 'undefined') { window.console.log((responseJSON && responseJSON.error) || jqXHR.status || errorThrown.message); } else { window.alert('Error requesting media from ' + that.options.oembedProxy + ' to insert: ' + errorThrown + ' (response status: ' + jqXHR.status + ')'); } $.proxy(that, 'convertBadEmbed', url)(); } }); }; /** * Get HTML using regexp * * @param {string} url * @param {bool} pasted * @return {void} */ Embeds.prototype.parseUrl = function (url, pasted) { var html; if (!(new RegExp(['youtube', 'youtu.be', 'vimeo', 'instagram', 'twitter', 'facebook', 'hudl'].join('|')).test(url))) { $.proxy(this, 'convertBadEmbed', url)(); return false; } if (url.includes('hudl.com/v/')) return false; html = url.replace(/\n?/g, '') .replace(/^(https?:)?\/\/www\.hudl\.com\/(embed\/)?v?(ideo)?\/(.+)\/?$/, //PATCH 4/12/2019: enable hudl '
    ') .replace(/^((http(s)?:\/\/)?(www\.)?(youtube\.com|youtu\.be)\/(watch\?v=|v\/)?)([a-zA-Z0-9\-_]+)(.*)?$/, '
    ') .replace(/^https?:\/\/vimeo\.com(\/.+)?\/([0-9]+)$/, '
    ') .replace(/^https:\/\/twitter\.com\/(\w+)\/status\/(\d+)\/?$/, '') .replace(/^(https:\/\/www\.facebook\.com\/(.*))$/, '
    ') .replace(/^https?:\/\/instagram\.com\/p\/(.+)\/?$/, '
    '); if (this.options.storeMeta) { html += '
    '; } /*if (html.includes('hudl')) { if (html.startsWith('http:')) html = html.slice(5); else if (html.startsWith('https:')) html = html.slice(6); html = '
    '.formatUnicorn({hudl: html}); }*/ if ((/<("[^"]*"|'[^']*'|[^'">])*>/).test(html) === false) { $.proxy(this, 'convertBadEmbed', url)(); return false; } if (pasted) { this.embed(html, url); } else { this.embed(html); } }; /** * Add html to page * * @param {string} html * @param {string} pastedUrl * @return {void} */ Embeds.prototype.embed = function (html, pastedUrl) { var $place = this.$el.find('.medium-insert-embeds-active'), $div; if (!html) { alert('Incorrect URL format specified'); return false; } else { if (html.indexOf('') > -1) { // Store embed code with