X-Git-Url: https://scripts.mit.edu/gitweb/autoinstalls/wordpress.git/blobdiff_plain/41578db67d72562346e4dbb2a14889b23d522813..refs/tags/wordpress-4.5:/wp-includes/js/tinymce/plugins/image/plugin.js diff --git a/wp-includes/js/tinymce/plugins/image/plugin.js b/wp-includes/js/tinymce/plugins/image/plugin.js index c7f6f5ac..a385f3d6 100644 --- a/wp-includes/js/tinymce/plugins/image/plugin.js +++ b/wp-includes/js/tinymce/plugins/image/plugin.js @@ -1,8 +1,8 @@ /** * 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 @@ -23,7 +23,7 @@ tinymce.PluginManager.add('image', function(editor) { } img.onload = function() { - done(img.clientWidth, img.clientHeight); + done(Math.max(img.width, img.clientWidth), Math.max(img.height, img.clientHeight)); }; img.onerror = function() { @@ -40,27 +40,42 @@ tinymce.PluginManager.add('image', function(editor) { img.src = url; } - function applyPreview(items) { - tinymce.each(items, function(item) { - item.textStyle = function() { - return editor.formatter.getCssText({inline: 'img', classes: [item.value]}); - }; - }); + function buildListItems(inputList, itemCallback, startItems) { + function appendItems(values, output) { + output = output || []; + + tinymce.each(values, function(item) { + var menuItem = {text: item.text || item.title}; + + if (item.menu) { + menuItem.menu = appendItems(item.menu); + } else { + menuItem.value = item.value; + itemCallback(menuItem); + } + + output.push(menuItem); + }); - return items; + return output; + } + + return appendItems(inputList, startItems || []); } function createImageList(callback) { 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") { + imageList(callback); } else { callback(imageList); } @@ -68,46 +83,8 @@ tinymce.PluginManager.add('image', function(editor) { } function showDialog(imageList) { - var win, data = {}, dom = editor.dom, imgElm = editor.selection.getNode(); - var width, height, imageListCtrl, classListCtrl; - - function buildValues(listSettingName, dataItemName, defaultItems) { - var selectedItem, items = []; - - tinymce.each(editor.settings[listSettingName] || defaultItems, function(target) { - var item = { - text: target.text || target.title, - value: target.value - }; - - items.push(item); - - if (data[dataItemName] === target.value || (!selectedItem && target.selected)) { - selectedItem = item; - } - }); - - if (selectedItem && !data[dataItemName]) { - data[dataItemName] = selectedItem.value; - selectedItem.selected = true; - } - - return items; - } - - function buildImageList() { - var imageListItems = [{text: 'None', value: ''}]; - - tinymce.each(imageList, function(image) { - imageListItems.push({ - text: image.text || image.title, - value: editor.convertURL(image.value || image.url, 'src'), - menu: image.menu - }); - }); - - return imageListItems; - } + var win, data = {}, dom = editor.dom, imgElm, figureElm; + var width, height, imageListCtrl, classListCtrl, imageDimensions = editor.settings.image_dimensions !== false; function recalcSize() { var widthCtrl, heightCtrl, newWidth, newHeight; @@ -115,16 +92,26 @@ tinymce.PluginManager.add('image', function(editor) { widthCtrl = win.find('#width')[0]; heightCtrl = win.find('#height')[0]; + if (!widthCtrl || !heightCtrl) { + return; + } + newWidth = widthCtrl.value(); newHeight = heightCtrl.value(); 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); + } } } @@ -133,15 +120,20 @@ tinymce.PluginManager.add('image', function(editor) { } function onSubmitForm() { + var figureElm, oldImg; + function waitLoad(imgElm) { function selectImage() { imgElm.onload = imgElm.onerror = null; - editor.selection.select(imgElm); - editor.nodeChanged(); + + if (editor.selection) { + editor.selection.select(imgElm); + editor.nodeChanged(); + } } imgElm.onload = function() { - if (!data.width && !data.height) { + if (!data.width && !data.height && imageDimensions) { dom.setAttribs(imgElm, { width: imgElm.clientWidth, height: imgElm.clientHeight @@ -160,12 +152,16 @@ tinymce.PluginManager.add('image', function(editor) { 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; } @@ -174,26 +170,26 @@ tinymce.PluginManager.add('image', function(editor) { data.height = null; } - if (data.style === '') { + if (!data.style) { data.style = 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"] }; - if (!data["class"]) { - delete 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 } ); @@ -213,6 +209,10 @@ tinymce.PluginManager.add('image', function(editor) { return; } + if (data.title === "") { + data.title = null; + } + if (!imgElm) { data.id = '__mcenew'; editor.focus(); @@ -223,6 +223,42 @@ tinymce.PluginManager.add('image', function(editor) { 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); }); } @@ -235,45 +271,80 @@ tinymce.PluginManager.add('image', function(editor) { return value; } - function srcChange() { + function srcChange(e) { + var srcURL, prependURL, absoluteURLPattern, meta = e.meta || {}; + if (imageListCtrl) { imageListCtrl.value(editor.convertURL(this.value(), 'src')); } - getImageSize(this.value(), function(data) { - if (data.width && data.height) { - width = data.width; - height = data.height; + tinymce.each(meta, function(value, key) { + win.find('#' + key).value(value); + }); + + if (!meta.width && !meta.height) { + srcURL = editor.convertURL(this.value(), 'src'); - win.find('#width').value(width); - win.find('#height').value(height); + // 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; } - }); + + this.value(srcURL); + + getImageSize(editor.documentBaseURI.toAbsolute(this.value()), function(data) { + if (data.width && data.height && imageDimensions) { + width = data.width; + height = data.height; + + win.find('#width').value(width); + win.find('#height').value(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) { imageListCtrl = { type: 'listbox', label: 'Image list', - values: buildImageList(), + values: buildListItems( + imageList, + function(item) { + item.value = editor.convertURL(item.value || item.url, 'src'); + }, + [{text: 'None', value: ''}] + ), value: data.src && editor.convertURL(data.src, 'src'), onselect: function(e) { var altCtrl = win.find('#alt'); @@ -282,9 +353,10 @@ tinymce.PluginManager.add('image', function(editor) { altCtrl.value(e.control.text()); } - win.find('#src').value(e.control.value()); + win.find('#src').value(e.control.value()).fire('change'); }, onPostRender: function() { + /*eslint consistent-this: 0*/ imageListCtrl = this; } }; @@ -295,13 +367,29 @@ tinymce.PluginManager.add('image', function(editor) { name: 'class', type: 'listbox', label: 'Class', - values: applyPreview(buildValues('image_class_list', 'class')) + values: buildListItems( + editor.settings.image_class_list, + function(item) { + if (item.value) { + item.textStyle = function() { + return editor.formatter.getCssText({inline: 'img', classes: [item.value]}); + }; + } + } + ) }; } // General settings shared between simple and advanced dialogs var generalFormItems = [ - {name: 'src', type: 'filepicker', filetype: 'image', label: 'Source', autofocus: true, onchange: srcChange}, + { + name: 'src', + type: 'filepicker', + filetype: 'image', + label: 'Source', + autofocus: true, + onchange: srcChange + }, imageListCtrl ]; @@ -309,7 +397,11 @@ tinymce.PluginManager.add('image', function(editor) { generalFormItems.push({name: 'alt', type: 'textbox', label: 'Image description'}); } - if (editor.settings.image_dimensions !== false) { + if (editor.settings.image_title) { + generalFormItems.push({name: 'title', type: 'textbox', label: 'Image Title'}); + } + + if (imageDimensions) { generalFormItems.push({ type: 'container', label: 'Dimensions', @@ -328,9 +420,48 @@ tinymce.PluginManager.add('image', function(editor) { 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)) { @@ -344,23 +475,73 @@ tinymce.PluginManager.add('image', function(editor) { 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); - 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); + win.find('#vspace').value(""); + win.find('#hspace').value(""); + + 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'))); } @@ -384,7 +565,8 @@ tinymce.PluginManager.add('image', function(editor) { { label: 'Style', name: 'style', - type: 'textbox' + type: 'textbox', + onchange: updateVSpaceHSpaceBorder }, { type: 'form', @@ -420,23 +602,49 @@ tinymce.PluginManager.add('image', function(editor) { } } - // WP - editor.addCommand( 'mceImage', function() { - createImageList( showDialog )(); + 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 }); + + editor.addCommand('mceImage', createImageList(showDialog)); });