/**
* plugin.js
*
- * Copyright, Moxiecode Systems AB
* Released under LGPL License.
+ * Copyright (c) 1999-2015 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
}
img.onload = function() {
- done(img.clientWidth, img.clientHeight);
+ done(Math.max(img.width, img.clientWidth), Math.max(img.height, img.clientHeight));
};
img.onerror = function() {
return function() {
var imageList = editor.settings.image_list;
- if (typeof(imageList) == "string") {
+ if (typeof imageList == "string") {
tinymce.util.XHR.send({
url: imageList,
success: function(text) {
callback(tinymce.util.JSON.parse(text));
}
});
- } else if (typeof(imageList) == "function") {
+ } else if (typeof imageList == "function") {
imageList(callback);
} else {
callback(imageList);
}
function showDialog(imageList) {
- var win, data = {}, dom = editor.dom, imgElm = editor.selection.getNode();
+ var win, data = {}, dom = editor.dom, imgElm, figureElm;
var width, height, imageListCtrl, classListCtrl, imageDimensions = editor.settings.image_dimensions !== false;
function recalcSize() {
if (win.find('#constrain')[0].checked() && width && height && newWidth && newHeight) {
if (width != newWidth) {
newHeight = Math.round((newWidth / width) * newHeight);
- heightCtrl.value(newHeight);
+
+ if (!isNaN(newHeight)) {
+ heightCtrl.value(newHeight);
+ }
} else {
newWidth = Math.round((newHeight / height) * newWidth);
- widthCtrl.value(newWidth);
+
+ if (!isNaN(newWidth)) {
+ widthCtrl.value(newWidth);
+ }
}
}
}
function onSubmitForm() {
+ var figureElm, oldImg;
+
function waitLoad(imgElm) {
function selectImage() {
imgElm.onload = imgElm.onerror = null;
recalcSize();
data = tinymce.extend(data, win.toJSON());
- var caption = data.caption; // WP
+ var wpcaption = data.wpcaption; // WP
if (!data.alt) {
data.alt = '';
}
+ if (!data.title) {
+ data.title = '';
+ }
+
if (data.width === '') {
data.width = null;
}
}
// Setup new data excluding style properties
+ /*eslint dot-notation: 0*/
data = {
src: data.src,
alt: data.alt,
+ title: data.title,
width: data.width,
height: data.height,
style: data.style,
+ caption: data.caption,
"class": data["class"]
};
editor.undoManager.transact(function() {
// WP
- var eventData = { node: imgElm, data: data, caption: caption };
+ var eventData = { node: imgElm, data: data, wpcaption: wpcaption };
editor.fire( 'wpImageFormSubmit', { imgData: eventData } );
return;
}
+ if (data.title === "") {
+ data.title = null;
+ }
+
if (!imgElm) {
data.id = '__mcenew';
editor.focus();
dom.setAttribs(imgElm, data);
}
+ editor.editorUpload.uploadImagesAuto();
+
+ if (data.caption === false) {
+ if (dom.is(imgElm.parentNode, 'figure.image')) {
+ figureElm = imgElm.parentNode;
+ dom.insertAfter(imgElm, figureElm);
+ dom.remove(figureElm);
+ }
+ }
+
+ function isTextBlock(node) {
+ return editor.schema.getTextBlockElements()[node.nodeName];
+ }
+
+ if (data.caption === true) {
+ if (!dom.is(imgElm.parentNode, 'figure.image')) {
+ oldImg = imgElm;
+ imgElm = imgElm.cloneNode(true);
+ figureElm = dom.create('figure', {'class': 'image'});
+ figureElm.appendChild(imgElm);
+ figureElm.appendChild(dom.create('figcaption', {contentEditable: true}, 'Caption'));
+ figureElm.contentEditable = false;
+
+ var textBlock = dom.getParent(oldImg, isTextBlock);
+ if (textBlock) {
+ dom.split(textBlock, oldImg, figureElm);
+ } else {
+ dom.replace(figureElm, oldImg);
+ }
+
+ editor.selection.select(figureElm);
+ }
+
+ return;
+ }
+
waitLoad(imgElm);
});
}
}
function srcChange(e) {
- var meta = e.meta || {};
+ var srcURL, prependURL, absoluteURLPattern, meta = e.meta || {};
if (imageListCtrl) {
imageListCtrl.value(editor.convertURL(this.value(), 'src'));
});
if (!meta.width && !meta.height) {
- var srcURL = this.value(),
- absoluteURLPattern = new RegExp('^(?:[a-z]+:)?//', 'i'),
- baseURL = editor.settings.document_base_url;
+ srcURL = editor.convertURL(this.value(), 'src');
- //Pattern test the src url and make sure we haven't already prepended the url
- if (baseURL && !absoluteURLPattern.test(srcURL) && srcURL.substring(0, baseURL.length) !== baseURL) {
- this.value(baseURL + srcURL);
+ // Pattern test the src url and make sure we haven't already prepended the url
+ prependURL = editor.settings.image_prepend_url;
+ absoluteURLPattern = new RegExp('^(?:[a-z]+:)?//', 'i');
+ if (prependURL && !absoluteURLPattern.test(srcURL) && srcURL.substring(0, prependURL.length) !== prependURL) {
+ srcURL = prependURL + srcURL;
}
- getImageSize(this.value(), function(data) {
+ this.value(srcURL);
+
+ getImageSize(editor.documentBaseURI.toAbsolute(this.value()), function(data) {
if (data.width && data.height && imageDimensions) {
width = data.width;
height = data.height;
}
}
- width = dom.getAttrib(imgElm, 'width');
- height = dom.getAttrib(imgElm, 'height');
+ imgElm = editor.selection.getNode();
+ figureElm = dom.getParent(imgElm, 'figure.image');
+ if (figureElm) {
+ imgElm = dom.select('img', figureElm)[0];
+ }
+
+ if (imgElm && (imgElm.nodeName != 'IMG' || imgElm.getAttribute('data-mce-object') || imgElm.getAttribute('data-mce-placeholder'))) {
+ imgElm = null;
+ }
+
+ if (imgElm) {
+ width = dom.getAttrib(imgElm, 'width');
+ height = dom.getAttrib(imgElm, 'height');
- if (imgElm.nodeName == 'IMG' && !imgElm.getAttribute('data-mce-object') && !imgElm.getAttribute('data-mce-placeholder')) {
data = {
src: dom.getAttrib(imgElm, 'src'),
alt: dom.getAttrib(imgElm, 'alt'),
+ title: dom.getAttrib(imgElm, 'title'),
"class": dom.getAttrib(imgElm, 'class'),
width: width,
- height: height
+ height: height,
+ caption: !!figureElm
};
// WP
editor.fire( 'wpLoadImageData', { imgData: { data: data, node: imgElm } } );
- } else {
- imgElm = null;
}
if (imageList) {
win.find('#src').value(e.control.value()).fire('change');
},
onPostRender: function() {
+ /*eslint consistent-this: 0*/
imageListCtrl = this;
}
};
generalFormItems.push({name: 'alt', type: 'textbox', label: 'Image description'});
}
+ if (editor.settings.image_title) {
+ generalFormItems.push({name: 'title', type: 'textbox', label: 'Image Title'});
+ }
+
if (imageDimensions) {
generalFormItems.push({
type: 'container',
generalFormItems.push(classListCtrl);
+ if (editor.settings.image_caption && tinymce.Env.ceFalse) {
+ generalFormItems.push({name: 'caption', type: 'checkbox', label: 'Caption'});
+ }
+
// WP
editor.fire( 'wpLoadImageForm', { data: generalFormItems } );
+ function mergeMargins(css) {
+ if (css.margin) {
+
+ var splitMargin = css.margin.split(" ");
+
+ switch (splitMargin.length) {
+ case 1: //margin: toprightbottomleft;
+ css['margin-top'] = css['margin-top'] || splitMargin[0];
+ css['margin-right'] = css['margin-right'] || splitMargin[0];
+ css['margin-bottom'] = css['margin-bottom'] || splitMargin[0];
+ css['margin-left'] = css['margin-left'] || splitMargin[0];
+ break;
+ case 2: //margin: topbottom rightleft;
+ css['margin-top'] = css['margin-top'] || splitMargin[0];
+ css['margin-right'] = css['margin-right'] || splitMargin[1];
+ css['margin-bottom'] = css['margin-bottom'] || splitMargin[0];
+ css['margin-left'] = css['margin-left'] || splitMargin[1];
+ break;
+ case 3: //margin: top rightleft bottom;
+ css['margin-top'] = css['margin-top'] || splitMargin[0];
+ css['margin-right'] = css['margin-right'] || splitMargin[1];
+ css['margin-bottom'] = css['margin-bottom'] || splitMargin[2];
+ css['margin-left'] = css['margin-left'] || splitMargin[1];
+ break;
+ case 4: //margin: top right bottom left;
+ css['margin-top'] = css['margin-top'] || splitMargin[0];
+ css['margin-right'] = css['margin-right'] || splitMargin[1];
+ css['margin-bottom'] = css['margin-bottom'] || splitMargin[2];
+ css['margin-left'] = css['margin-left'] || splitMargin[3];
+ }
+ delete css.margin;
+ }
+ return css;
+ }
+
function updateStyle() {
function addPixelSuffix(value) {
if (value.length > 0 && /^[0-9]+$/.test(value)) {
return;
}
- var data = win.toJSON();
- var css = dom.parseStyle(data.style);
+ var data = win.toJSON(),
+ css = dom.parseStyle(data.style);
+
+ css = mergeMargins(css);
+
+ if (data.vspace) {
+ css['margin-top'] = css['margin-bottom'] = addPixelSuffix(data.vspace);
+ }
+ if (data.hspace) {
+ css['margin-left'] = css['margin-right'] = addPixelSuffix(data.hspace);
+ }
+ if (data.border) {
+ css['border-width'] = addPixelSuffix(data.border);
+ }
+
+ win.find('#style').value(dom.serializeStyle(dom.parseStyle(dom.serializeStyle(css))));
+ }
+
+ function updateVSpaceHSpaceBorder() {
+ if (!editor.settings.image_advtab) {
+ return;
+ }
+
+ var data = win.toJSON(),
+ css = dom.parseStyle(data.style);
+
+ win.find('#vspace').value("");
+ win.find('#hspace').value("");
- delete css.margin;
- css['margin-top'] = css['margin-bottom'] = addPixelSuffix(data.vspace);
- css['margin-left'] = css['margin-right'] = addPixelSuffix(data.hspace);
- css['border-width'] = addPixelSuffix(data.border);
+ css = mergeMargins(css);
+
+ //Move opposite equal margins to vspace/hspace field
+ if ((css['margin-top'] && css['margin-bottom']) || (css['margin-right'] && css['margin-left'])) {
+ if (css['margin-top'] === css['margin-bottom']) {
+ win.find('#vspace').value(removePixelSuffix(css['margin-top']));
+ } else {
+ win.find('#vspace').value('');
+ }
+ if (css['margin-right'] === css['margin-left']) {
+ win.find('#hspace').value(removePixelSuffix(css['margin-right']));
+ } else {
+ win.find('#hspace').value('');
+ }
+ }
+
+ //Move border-width
+ if (css['border-width']) {
+ win.find('#border').value(removePixelSuffix(css['border-width']));
+ }
win.find('#style').value(dom.serializeStyle(dom.parseStyle(dom.serializeStyle(css))));
+
}
if (editor.settings.image_advtab) {
// Parse styles from img
if (imgElm) {
- data.hspace = removePixelSuffix(imgElm.style.marginLeft || imgElm.style.marginRight);
- data.vspace = removePixelSuffix(imgElm.style.marginTop || imgElm.style.marginBottom);
- data.border = removePixelSuffix(imgElm.style.borderWidth);
+ if (imgElm.style.marginLeft && imgElm.style.marginRight && imgElm.style.marginLeft === imgElm.style.marginRight) {
+ data.hspace = removePixelSuffix(imgElm.style.marginLeft);
+ }
+ if (imgElm.style.marginTop && imgElm.style.marginBottom && imgElm.style.marginTop === imgElm.style.marginBottom) {
+ data.vspace = removePixelSuffix(imgElm.style.marginTop);
+ }
+ if (imgElm.style.borderWidth) {
+ data.border = removePixelSuffix(imgElm.style.borderWidth);
+ }
+
data.style = editor.dom.serializeStyle(editor.dom.parseStyle(editor.dom.getAttrib(imgElm, 'style')));
}
{
label: 'Style',
name: 'style',
- type: 'textbox'
+ type: 'textbox',
+ onchange: updateVSpaceHSpaceBorder
},
{
type: 'form',
}
}
+ editor.on('preInit', function() {
+ function hasImageClass(node) {
+ var className = node.attr('class');
+ return className && /\bimage\b/.test(className);
+ }
+
+ function toggleContentEditableState(state) {
+ return function(nodes) {
+ var i = nodes.length, node;
+
+ function toggleContentEditable(node) {
+ node.attr('contenteditable', state ? 'true' : null);
+ }
+
+ while (i--) {
+ node = nodes[i];
+
+ if (hasImageClass(node)) {
+ node.attr('contenteditable', state ? 'false' : null);
+ tinymce.each(node.getAll('figcaption'), toggleContentEditable);
+ }
+ }
+ };
+ }
+
+ editor.parser.addNodeFilter('figure', toggleContentEditableState(true));
+ editor.serializer.addNodeFilter('figure', toggleContentEditableState(false));
+ });
+
editor.addButton('image', {
icon: 'image',
tooltip: 'Insert/edit image',
onclick: createImageList(showDialog),
- stateSelector: 'img:not([data-mce-object],[data-mce-placeholder])'
+ stateSelector: 'img:not([data-mce-object],[data-mce-placeholder]),figure.image'
});
editor.addMenuItem('image', {
icon: 'image',
- text: 'Insert image',
+ text: 'Insert/edit image',
onclick: createImageList(showDialog),
context: 'insert',
prependToContext: true