/* https://github.com/adeelhussain/summernote-image-attribute-editor */
(function (factory) {
if (typeof define === 'function' && define.amd) {
define(['jquery'], factory)
} else if (typeof module === 'object' && module.exports) {
module.exports = factory(require('jquery'));
} else {
factory(window.jQuery)
}
}
(function ($) {
// TODO: Add more languages!
$.extend(true, $.summernote.lang, {
'en-US': {
imageAttributes: {
edit: 'Edit Attributes',
titleLabel: 'Title',
altLabel: 'Alternative Text',
captionLabel: 'Caption',
tooltip: 'Edit Image',
dialogSaveBtnMessage: 'Save',
dialogTitle: 'Change Image Attributes'
}
}
});
$.extend($.summernote.options, {
imageAttributes: {
icon: '',
figureClass: '',
figcaptionClass: '',
captionText: 'Caption Goes Here.'
}
});
$.extend($.summernote.plugins, {
'imageAttributes': function (context) {
var self = this;
var ui = $.summernote.ui,
$editable = context.layoutInfo.editable,
options = context.options,
$editor = context.layoutInfo.editor,
lang = options.langInfo,
$note = context.layoutInfo.note;
context.memo('button.imageAttributes', function () {
var button = ui.button({
contents: options.imageAttributes.icon,
container: false,
tooltip: lang.imageAttributes.tooltip,
click: function () {
context.invoke('imageAttributes.show');
}
});
return button.render();
});
this.initialize = function () {
// Either the modal appends in Body or Inside the Editor
var $container = options.imageAttributes.dialogsInBody ? $(document.body) : $editor;
var body = `
`;
var footer = ``;
this.$dialog = ui.dialog({
title: lang.imageAttributes.dialogTitle,
body: body,
footer: footer
}).render().appendTo($container);
};
this.destroy = function () {
ui.hideDialog(this.$dialog);
this.$dialog.remove();
};
this.bindEnterKey = function ($input, $btn) {
$input.on('keypress', function (event) {
if (event.keyCode === 13) {
$btn.trigger('click');
}
});
};
this.show = function () {
var $img = $($editable.data('target'));
var _imgInfo = {
title: $img.attr('title'),
alt: $img.attr('alt'),
caption: $img.next('figcaption').text(),
width: $img.width(),
height: $img.height()
};
var img = new Image();
img.onload = function () {
_imgInfo.naturalWidth = img.width
_imgInfo.naturalHeight = img.height;
}
img.src = $img.attr('src');
this.showLinkDialog(_imgInfo)
.then(function (imgInfo) {
ui.hideDialog(self.$dialog);
var isAnyChangeMade = false;
// NOTE: Must add more conditions if any new field is being added!
if (_imgInfo.title != imgInfo.title || _imgInfo.alt != imgInfo.alt || _imgInfo.caption != imgInfo.caption
|| _imgInfo.width != imgInfo.width || _imgInfo.height != imgInfo.height) {
isAnyChangeMade = true;
}
if (imgInfo.alt) {
$img.attr('alt', imgInfo.alt);
}
else {
$img.removeAttr('alt');
}
if (imgInfo.title) {
$img.attr('title', imgInfo.title);
}
else {
$img.removeAttr('title');
}
if (imgInfo.width) {
$img.css('width', imgInfo.width);
}
if (imgInfo.height) {
$img.css('height', imgInfo.height);
}
var captionText = imgInfo.caption;
var $parentAnchorLink = $img.parent();
// If caption are not same, then its mean need to update!
var isUpdateCaption = (captionText !== _imgInfo.caption);
// If image already have a caption and is equal to old one, then remove that!
var $imgFigure = $img.closest('figure');
if ($imgFigure.length && isUpdateCaption) {
// Means image wrpped in figure
$imgFigure.find('figcaption').remove();
$imgFigure.children().first().unwrap();
}
// If caption text is present then add that caption, otherwise don't do any thing
if (isUpdateCaption && captionText) {
var $newFigure;
if ($parentAnchorLink.is('a')) {
$newFigure = $parentAnchorLink.wrap(``).parent();
$newFigure.append(` ${captionText}`);
} else {
$newFigure = $img.wrap(``).parent();
$img.after(`${captionText}`);
}
}
if (isAnyChangeMade) {
var _content = context.invoke('code');
$note.val(_content);
$note.trigger('summernote.change', _content);
}
});
};
this.showLinkDialog = function (imgInfo) {
return $.Deferred(function (deferred) {
var $imageTitle = self.$dialog.find('.note-image-title-text');
var $imageCaption = self.$dialog.find('.note-image-caption-text');
var $imageAlt = self.$dialog.find('.note-image-alt-text');
var $editBtn = self.$dialog.find('.note-image-title-btn');
var $imageWidthInput = self.$dialog.find('.note-image-width');
var $imageHeightInput = self.$dialog.find('.note-image-height');
var $lockButton = self.$dialog.find('.lock-button');
var $resetSizeButton = self.$dialog.find('.reset-size-buttton');
var $unlockIcon = $lockButton.find('.icon-unlock');
var $lockIcon = $lockButton.find('.icon-lock');
var isLocked = (typeof options.imageAttributes.manageAspectRatio === 'undefined') ? true: options.imageAttributes.manageAspectRatio;
if(isLocked){
$unlockIcon.addClass('hide').removeClass('show');
$lockIcon.addClass('show').removeClass('hide');
}
else {
$unlockIcon.addClass('show').removeClass('hide');
$lockIcon.addClass('hide').removeClass('show');
}
$lockButton.on('click', function (event) {
event.preventDefault();
isLocked = !isLocked;
if (isLocked) {
$unlockIcon.addClass('hide').removeClass('show')
$lockIcon.addClass('show').removeClass('hide')
$imageHeightInput.val(imageAdjustedHeight($imageWidthInput.val(), imgInfo.naturalWidth, imgInfo.naturalHeight));
}
else {
$unlockIcon.addClass('show').removeClass('hide')
$lockIcon.addClass('hide').removeClass('show')
}
});
$resetSizeButton.on('click', function (event) {
event.preventDefault();
$imageWidthInput.val(imgInfo.width);
$imageHeightInput.val(imgInfo.height);
});
$imageHeightInput.on("input", function () {
if (isLocked) {
$imageWidthInput.val(imageAdjustedWidth(this.value, imgInfo.naturalWidth, imgInfo.naturalHeight));
}
});
$imageWidthInput.on("input", function () {
if (isLocked) {
$imageHeightInput.val(imageAdjustedHeight(this.value, imgInfo.naturalWidth, imgInfo.naturalHeight));
}
});
ui.onDialogShown(self.$dialog, function () {
context.triggerEvent('dialog.shown');
$editBtn.on('click', function (event) {
event.preventDefault();
deferred.resolve({
title: $imageTitle.val(),
alt: $imageAlt.val(),
caption: $imageCaption.val(),
width: $imageWidthInput.val(),
height: $imageHeightInput.val(),
});
});
$imageTitle.val(imgInfo.title).trigger('focus');
self.bindEnterKey($imageTitle, $editBtn);
$imageAlt.val(imgInfo.alt);
self.bindEnterKey($imageAlt, $editBtn);
$imageCaption.val(imgInfo.caption);
self.bindEnterKey($imageCaption, $editBtn);
$imageWidthInput.val(imgInfo.width);
self.bindEnterKey($imageWidthInput, $editBtn);
$imageHeightInput.val(imgInfo.height);
self.bindEnterKey($imageHeightInput, $editBtn);
});
ui.onDialogHidden(self.$dialog, function () {
$editBtn.off('click');
$imageWidthInput.off('input');
$imageHeightInput.off('input');
$lockButton.off('click');
$resetSizeButton.off('click');
$unlockIcon.off('click');
$lockIcon.off('click');
if (deferred.state() === 'pending') {
deferred.reject();
}
});
ui.showDialog(self.$dialog);
});
};
function imageAdjustedHeight(heightInputValue, imageOriginalWidth, imageOriginalHeight) {
return parseInt(heightInputValue * (imageOriginalHeight / imageOriginalWidth), 10)
}
function imageAdjustedWidth(widthInputValue, imageOriginalWidth, imageOriginalHeight) {
return parseInt(widthInputValue * (imageOriginalWidth / imageOriginalHeight), 10)
}
}
});
}));