380 lines
14 KiB
JavaScript
380 lines
14 KiB
JavaScript
(function() {
|
||
|
||
CKEDITOR.plugins.add('pwimage', {
|
||
|
||
requires: 'dialog',
|
||
|
||
init: function(editor) {
|
||
|
||
var pluginName = 'pwimage';
|
||
|
||
// These are the allowed and required elements & attributes for images.
|
||
// It should clean all other classes but hidpi and three align classes that are generated by ProcessWire
|
||
var allowed =
|
||
'img[alt,id,!src,title,width](align_left,align_center,align_right,hidpi,align-left,align-center,align-right);' +
|
||
'a[!href];' +
|
||
'figure{width}(align_left,align_center,align_right,hidpi,align-left,align-center,align-right);' +
|
||
'figcaption;';
|
||
var required = 'img[alt,src]';
|
||
|
||
// add pwimage command (opens the ProcessWire image selection iFrame)
|
||
editor.addCommand(pluginName, {
|
||
allowedContent: allowed,
|
||
requiredContent: required,
|
||
exec: loadIframeImagePicker
|
||
});
|
||
|
||
editor.ui.addButton('PWImage', {
|
||
label: editor.lang.common.image,
|
||
command: pluginName,
|
||
hidpi: true,
|
||
icon: (CKEDITOR.env.hidpi ? this.path + 'images/hidpi/pwimage.png' : this.path + 'images/pwimage.png')
|
||
});
|
||
|
||
// On double click we execute the command (= we open the pw image selection iFrame defined above)
|
||
editor.on( 'doubleclick', function( evt ) {
|
||
var element = evt.data.element;
|
||
if ( (element.is( 'img' ) ) && !element.data( 'cke-realelement' ) && !element.isReadOnly() ) {
|
||
//var selection = editor.getSelection();
|
||
//editor.lockSelection();
|
||
//selection.lock();
|
||
evt.cancel(); // prevent CKE's link dialog from showing up (if image is linked)
|
||
editor.commands.pwimage.exec();
|
||
}
|
||
});
|
||
|
||
// If the "menu" plugin is loaded, register the menu items.
|
||
if ( editor.addMenuItems ) {
|
||
editor.addMenuItems({
|
||
image: {
|
||
label: editor.lang.image.menu,
|
||
command: 'pwimage',
|
||
group: 'image'
|
||
}
|
||
});
|
||
}
|
||
|
||
// If the "contextmenu" plugin is loaded, register the listeners.
|
||
if ( editor.contextMenu ) {
|
||
editor.contextMenu.addListener( function( element, selection ) {
|
||
if ( getSelectedImage( editor, element ) )
|
||
return { image: CKEDITOR.TRISTATE_OFF };
|
||
});
|
||
}
|
||
|
||
}
|
||
});
|
||
|
||
function getSelectedImage( editor, element ) {
|
||
if ( !element ) {
|
||
var sel = editor.getSelection();
|
||
element = sel.getSelectedElement();
|
||
}
|
||
|
||
if ( element && element.is( 'img' ) && !element.data( 'cke-realelement' ) && !element.isReadOnly() )
|
||
return element;
|
||
}
|
||
|
||
function loadIframeImagePicker(editor) {
|
||
|
||
var $in = jQuery("#Inputfield_id");
|
||
var page_id;
|
||
if($in.length) {
|
||
page_id = $in.val();
|
||
} else {
|
||
page_id = jQuery("#" + editor.name).closest('.Inputfield').attr('data-pid');
|
||
}
|
||
var edit_page_id = page_id;
|
||
var file = '';
|
||
var imgClass = '';
|
||
var imgWidth = 0;
|
||
var imgHeight = 0;
|
||
var imgDescription = '';
|
||
var imgLink = '';
|
||
var hidpi = false;
|
||
var selection = editor.getSelection();
|
||
var se = selection.getSelectedElement();
|
||
var node = selection.getStartElement();
|
||
var $node = jQuery(node);
|
||
var nodeParent = node.getParent();
|
||
var nodeGrandparent = nodeParent.getParent();
|
||
var src = $node.attr('src');
|
||
var $linkWrapper = null; // if img is wrapped in link, this is it
|
||
var $figureWrapper = null;
|
||
var $figureCaption = null;
|
||
var nodeParentName = nodeParent.$.nodeName.toUpperCase();
|
||
var nodeGrandparentName = nodeGrandparent ? nodeGrandparent.$.nodeName.toUpperCase() : '';
|
||
var figureNodeSafari = null;
|
||
var $repeaterItem = jQuery("#" + editor.name).closest('.InputfieldRepeaterItem');
|
||
|
||
if(selection.getType() == CKEDITOR.SELECTION_TEXT) {
|
||
// Safari doesn’t support independent selection of figure elements without display:block,
|
||
// so restart selection after changing display property of <figure> to block which then
|
||
// makes it selectable in Safari
|
||
if(nodeParentName == 'FIGURE') {
|
||
figureNodeSafari = nodeParent;
|
||
} else if(nodeGrandparentName == 'FIGURE') {
|
||
figureNodeSafari = nodeGrandparent;
|
||
}
|
||
if(figureNodeSafari) {
|
||
selection.reset();
|
||
selection.removeAllRanges();
|
||
figureNodeSafari.$.style.display = 'block';
|
||
selection.selectElement(figureNodeSafari);
|
||
}
|
||
}
|
||
|
||
if($repeaterItem.length && $repeaterItem.find('.InputfieldImage').length) {
|
||
var dataPageAttr = $repeaterItem.attr('data-page');
|
||
if(typeof dataPageAttr !== 'undefined') page_id = parseInt(dataPageAttr);
|
||
}
|
||
/*
|
||
// pwAssetPageID for potential future use
|
||
else if(typeof ckeGetProcessWireConfig != "undefined") {
|
||
// note: ckeGetProcessWireConfig not yet present in front-end editor
|
||
var pwCkeSettings = ckeGetProcessWireConfig(editor);
|
||
if(pwCkeSettings && pwCkeSettings['pwAssetPageID']) page_id = pwCkeSettings['pwAssetPageID'];
|
||
}
|
||
*/
|
||
|
||
selection.lock();
|
||
editor.lockSelection();
|
||
|
||
if(nodeGrandparentName == 'FIGURE') {
|
||
$figureWrapper = jQuery(nodeGrandparent.getOuterHtml());
|
||
$figureCaption = $figureWrapper.find("figcaption");
|
||
$figureWrapper.find('img').remove();
|
||
} else if(nodeParentName == 'FIGURE') {
|
||
$figureWrapper = jQuery(nodeParent.getOuterHtml());
|
||
$figureCaption = $figureWrapper.find("figcaption");
|
||
$figureWrapper.find('img').remove();
|
||
}
|
||
if(nodeParentName === 'A') {
|
||
$linkWrapper = jQuery(nodeParent.getOuterHtml());
|
||
$linkWrapper.find('img').remove();
|
||
}
|
||
|
||
if(src) {
|
||
imgClass = $figureWrapper ? $figureWrapper.attr('class') : $node.attr('class');
|
||
hidpi = imgClass && imgClass.indexOf('hidpi') > -1;
|
||
imgWidth = $node.attr('width');
|
||
imgHeight = $node.attr('height');
|
||
imgDescription = $node.attr('alt');
|
||
imgLink = nodeParentName === "A" ? nodeParent.$.href : '';
|
||
|
||
var parts = src.split('/');
|
||
file = parts.pop();
|
||
parts = parts.reverse();
|
||
page_id = '';
|
||
// pull page_id out of img[src]
|
||
for(var n = 0; n < parts.length; n++) {
|
||
// accounts for either /1/2/3/ or /123/ format
|
||
if(parts[n].match(/^\d+$/)) {
|
||
page_id = parts[n] + page_id;
|
||
} else if(page_id.length) {
|
||
break;
|
||
}
|
||
}
|
||
page_id = parseInt(page_id);
|
||
}
|
||
|
||
var modalUri = ProcessWire.config.urls.admin + 'page/image/';
|
||
var queryString = '?id=' + page_id + '&edit_page_id=' + edit_page_id + '&modal=1';
|
||
|
||
if(file.length) queryString += "&file=" + file;
|
||
if(imgWidth) queryString += "&width=" + imgWidth;
|
||
if(imgHeight) queryString += "&height=" + imgHeight;
|
||
if(imgClass && imgClass.length) queryString += "&class=" + encodeURIComponent(imgClass);
|
||
queryString += '&hidpi=' + (hidpi ? '1' : '0');
|
||
if(imgDescription && imgDescription.length) {
|
||
queryString += "&description=" + encodeURIComponent(imgDescription);
|
||
}
|
||
if($figureCaption) queryString += "&caption=1";
|
||
if(imgLink && imgLink.length) queryString += "&link=" + encodeURIComponent(imgLink);
|
||
queryString += ("&winwidth=" + (jQuery(window).width() - 30));
|
||
|
||
// create iframe dialog box
|
||
var modalSettings = {
|
||
title: "<i class='fa fa-fw fa-folder-open'></i> " + ProcessWire.config.InputfieldCKEditor.pwimage.selectLabel, // "Select Image",
|
||
open: function() {
|
||
if(jQuery(".cke_maximized").length > 0) {
|
||
// the following is required when CKE is maximized to make sure dialog is on top of it
|
||
jQuery('.ui-dialog').css('z-index', 9999);
|
||
jQuery('.ui-widget-overlay').css('z-index', 9998);
|
||
}
|
||
}
|
||
};
|
||
|
||
var $iframe = pwModalWindow(modalUri + queryString, modalSettings, 'large');
|
||
|
||
$iframe.on('load', function() {
|
||
|
||
// when iframe loads, pull the contents into $i
|
||
var $i = $iframe.contents();
|
||
var buttons;
|
||
|
||
if($i.find("#selected_image").length > 0) {
|
||
// if there is a #selected_image element on the page...
|
||
|
||
buttons = [
|
||
{
|
||
html: "<i class='fa fa-camera'></i> " + ProcessWire.config.InputfieldCKEditor.pwimage.insertBtn, // "Insert This Image",
|
||
click: function() {
|
||
|
||
function insertImage(src) {
|
||
|
||
var $i = $iframe.contents();
|
||
var $img = jQuery("#selected_image", $i);
|
||
var width = $img.attr('width');
|
||
var height = $img.attr('height');
|
||
var alt = jQuery("#selected_image_description", $i).val();
|
||
var caption = jQuery("#selected_image_caption", $i).is(":checked") ? true : false;
|
||
var hidpi = jQuery("#selected_image_hidpi", $i).is(":checked") ? true : false;
|
||
var cls = $img.removeClass('ui-resizable No Alignment resizable_setup')
|
||
.removeClass('rotate90 rotate180 rotate270 rotate-90 rotate-180 rotate-270')
|
||
.removeClass('flip_vertical flip_horizontal').attr('class');
|
||
var $linkToLarger = jQuery('#selected_image_link', $i);
|
||
var link = $linkToLarger.is(":checked") ? $linkToLarger.val() : ''; // link to larger version
|
||
var $insertHTML = jQuery("<img />").attr('src', src).attr('alt', alt);
|
||
|
||
if(hidpi) cls += (cls.length > 0 ? ' ' : '') + 'hidpi';
|
||
|
||
// note: class is added to figureWrapper (rather than <img>) when this is a caption
|
||
if(caption === false) $insertHTML.addClass(cls);
|
||
|
||
if(width > 0 && $img.attr('data-nosize') != '1') $insertHTML.attr('width', width);
|
||
|
||
if($linkWrapper) {
|
||
// img was wrapped in an <a>...</a> and/or <figure>
|
||
if(link && link.length > 0) {
|
||
$linkWrapper.attr('href', link).attr('data-cke-saved-href', link); // populate existing link with new href
|
||
} else if($linkToLarger.attr('data-was-checked') == 1) {
|
||
// box was checked but no longer is
|
||
$linkWrapper = null;
|
||
}
|
||
if($linkWrapper !== null) {
|
||
$linkWrapper.append($insertHTML);
|
||
$insertHTML = $linkWrapper;
|
||
}
|
||
} else if(link && link.length > 0) {
|
||
var $a = jQuery("<a />").attr('href', link).append($insertHTML);
|
||
$insertHTML = $a;
|
||
}
|
||
|
||
if(caption) {
|
||
var $figure = jQuery("<figure />");
|
||
//$figure.css('width', width + 'px');
|
||
if(cls.length) $figure.addClass(cls);
|
||
if(!$figureCaption) {
|
||
$figureCaption = jQuery("<figcaption />");
|
||
if(alt.length > 1) {
|
||
$figureCaption.append(alt);
|
||
} else {
|
||
$figureCaption.append(ProcessWire.config.InputfieldCKEditor.pwimage.captionLabel);
|
||
}
|
||
}
|
||
if($figureCaption) $figure.append($figureCaption);
|
||
$figure.prepend($insertHTML);
|
||
$insertHTML = $figure;
|
||
}
|
||
|
||
// select the entire element surrounding the image so that we replace it all
|
||
if(nodeGrandparentName === 'FIGURE') {
|
||
editor.unlockSelection();
|
||
selection.unlock();
|
||
selection.selectElement(nodeGrandparent);
|
||
} else if(nodeParentName === "A" || nodeParentName == 'FIGURE') {
|
||
editor.unlockSelection();
|
||
selection.unlock();
|
||
// @todo does not work in inline mode for some reason
|
||
selection.selectElement(nodeParent);
|
||
}
|
||
|
||
var html = $insertHTML[0].outerHTML;
|
||
if(figureNodeSafari) figureNodeSafari.remove(); // Safari inserts an extra <figure>, so remove the original
|
||
editor.insertHtml(html);
|
||
editor.fire('change');
|
||
$iframe.dialog("close");
|
||
}
|
||
|
||
/*** INSERT BUTTON CLICKED *********************************/
|
||
|
||
var $i = $iframe.contents();
|
||
var $img = jQuery("#selected_image", $i);
|
||
|
||
$iframe.dialog("disable");
|
||
$iframe.setTitle(ProcessWire.config.InputfieldCKEditor.pwimage.savingNote); // Saving Image
|
||
$img.removeClass("resized");
|
||
|
||
var width = $img.attr('width');
|
||
if(!width) width = $img.width();
|
||
var height = $img.attr('height');
|
||
if(!height) height = $img.height();
|
||
var file = $img.attr('src');
|
||
var page_id = jQuery("#page_id", $i).val();
|
||
var hidpi = jQuery("#selected_image_hidpi", $i).is(":checked") ? 1 : 0;
|
||
var rotate = parseInt(jQuery("#selected_image_rotate", $i).val());
|
||
file = file.substring(file.lastIndexOf('/')+1);
|
||
|
||
var resizeURL = modalUri + 'resize?id=' + page_id +
|
||
'&file=' + file +
|
||
'&width=' + width +
|
||
'&height=' + height +
|
||
'&hidpi=' + hidpi;
|
||
|
||
if(rotate) resizeURL += '&rotate=' + rotate;
|
||
if($img.hasClass('flip_horizontal')) resizeURL += '&flip=h';
|
||
else if($img.hasClass('flip_vertical')) resizeURL += '&flip=v';
|
||
jQuery.get(resizeURL, function(data) {
|
||
var $div = jQuery("<div></div>").html(data);
|
||
var src = $div.find('#selected_image').attr('src');
|
||
insertImage(src);
|
||
});
|
||
|
||
}
|
||
}, {
|
||
|
||
html: "<i class='fa fa-folder-open'></i> " + ProcessWire.config.InputfieldCKEditor.pwimage.selectBtn, // "Select Another Image",
|
||
'class': 'ui-priority-secondary',
|
||
click: function() {
|
||
var $i = $iframe.contents();
|
||
var page_id = jQuery("#page_id", $i).val();
|
||
$iframe.attr('src', modalUri + '?id=' + page_id + '&modal=1');
|
||
$iframe.setButtons({});
|
||
}
|
||
}, {
|
||
html: "<i class='fa fa-times-circle'></i> " + ProcessWire.config.InputfieldCKEditor.pwimage.cancelBtn, // "Cancel",
|
||
'class': 'ui-priority-secondary',
|
||
click: function() { $iframe.dialog("close"); }
|
||
}
|
||
|
||
];
|
||
|
||
$iframe.setButtons(buttons);
|
||
$iframe.setTitle($i.find('title').html());
|
||
|
||
} else {
|
||
buttons = [];
|
||
jQuery("button.pw-modal-button, button[type=submit]:visible", $i).each(function() {
|
||
var $button = jQuery(this);
|
||
var button = {
|
||
html: $button.html(),
|
||
click: function() {
|
||
$button.trigger('click');
|
||
}
|
||
}
|
||
buttons.push(button);
|
||
if(!$button.hasClass('pw-modal-button-visible')) $button.hide();
|
||
});
|
||
var cancelButton = {
|
||
html: "<i class='fa fa-times-circle'></i> " + ProcessWire.config.InputfieldCKEditor.pwimage.cancelBtn, // "Cancel",
|
||
'class': "ui-priority-secondary",
|
||
click: function() { $iframe.dialog("close"); }
|
||
};
|
||
buttons.push(cancelButton);
|
||
$iframe.setButtons(buttons);
|
||
}
|
||
});
|
||
}
|
||
|
||
})();
|