]> scripts.mit.edu Git - autoinstalls/wordpress.git/blobdiff - wp-includes/js/tinymce/plugins/image/plugin.js
WordPress 4.5
[autoinstalls/wordpress.git] / wp-includes / js / tinymce / plugins / image / plugin.js
index c7f6f5acda595fa90e0afc5d32855c533fa30ed2..a385f3d6d42e57474c2de61c57161670caba7e39 100644 (file)
@@ -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));
 });