]> scripts.mit.edu Git - autoinstalls/wordpress.git/blobdiff - wp-includes/js/tinymce/plugins/paste/plugin.js
WordPress 4.5-scripts
[autoinstalls/wordpress.git] / wp-includes / js / tinymce / plugins / paste / plugin.js
index 65ed95d2256dd180f72633565e8562b89d95f501..249f0cc3338bc73a71eba6e8543c22c3b5a67715 100644 (file)
        }
 
        function expose(ids) {
-               for (var i = 0; i < ids.length; i++) {
-                       var target = exports;
-                       var id = ids[i];
-                       var fragments = id.split(/[.\/]/);
+               var i, target, id, fragments, privateModules;
+
+               for (i = 0; i < ids.length; i++) {
+                       target = exports;
+                       id = ids[i];
+                       fragments = id.split(/[.\/]/);
 
                        for (var fi = 0; fi < fragments.length - 1; ++fi) {
                                if (target[fragments[fi]] === undefined) {
 
                        target[fragments[fragments.length - 1]] = modules[id];
                }
+               
+               // Expose private modules for unit tests
+               if (exports.AMDLC_TESTS) {
+                       privateModules = exports.privateModules || {};
+
+                       for (id in modules) {
+                               privateModules[id] = modules[id];
+                       }
+
+                       for (i = 0; i < ids.length; i++) {
+                               delete privateModules[ids[i]];
+                       }
+
+                       exports.privateModules = privateModules;
+               }
        }
 
 // Included from: js/tinymce/plugins/paste/classes/Utils.js
 /**
  * Utils.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
@@ -199,16 +216,27 @@ define("tinymce/pasteplugin/Utils", [
                        /^[\s\S]*<body[^>]*>\s*|\s*<\/body[^>]*>[\s\S]*$/g, // Remove anything but the contents within the BODY element
                        /<!--StartFragment-->|<!--EndFragment-->/g, // Inner fragments (tables from excel on mac)
                        [/( ?)<span class="Apple-converted-space">\u00a0<\/span>( ?)/g, trimSpaces],
+                       /<br class="Apple-interchange-newline">/g,
                        /<br>$/i // Trailing BR elements
                ]);
 
                return html;
        }
 
+       // TODO: Should be in some global class
+       function createIdGenerator(prefix) {
+               var count = 0;
+
+               return function() {
+                       return prefix + (count++);
+               };
+       }
+
        return {
                filter: filter,
                innerText: innerText,
-               trimHtml: trimHtml
+               trimHtml: trimHtml,
+               createIdGenerator: createIdGenerator
        };
 });
 
@@ -217,8 +245,8 @@ define("tinymce/pasteplugin/Utils", [
 /**
  * Clipboard.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
@@ -247,12 +275,14 @@ define("tinymce/pasteplugin/Clipboard", [
        "tinymce/Env",
        "tinymce/dom/RangeUtils",
        "tinymce/util/VK",
-       "tinymce/pasteplugin/Utils"
-], function(Env, RangeUtils, VK, Utils) {
+       "tinymce/pasteplugin/Utils",
+       "tinymce/util/Delay"
+], function(Env, RangeUtils, VK, Utils, Delay) {
        return function(editor) {
                var self = this, pasteBinElm, lastRng, keyboardPasteTimeStamp = 0, draggingInternally = false;
                var pasteBinDefaultContent = '%MCEPASTEBIN%', keyboardPastePlainTextState;
                var mceInternalUrlPrefix = 'data:text/mce-internal,';
+               var uniqueId = Utils.createIdGenerator("mceclip");
 
                /**
                 * Pastes the specified HTML. This means that the HTML is filtered and then
@@ -281,7 +311,7 @@ define("tinymce/pasteplugin/Clipboard", [
                                }
 
                                if (!args.isDefaultPrevented()) {
-                                       editor.insertContent(html, {merge: editor.settings.paste_merge_formats !== false});
+                                       editor.insertContent(html, {merge: editor.settings.paste_merge_formats !== false, data: {paste: true}});
                                }
                        }
                }
@@ -502,7 +532,7 @@ define("tinymce/pasteplugin/Clipboard", [
                 * @return {Object} Object with mime types and data for those mime types.
                 */
                function getDataTransferItems(dataTransfer) {
-                       var data = {};
+                       var items = {};
 
                        if (dataTransfer) {
                                // Use old WebKit/IE API
@@ -510,7 +540,7 @@ define("tinymce/pasteplugin/Clipboard", [
                                        var legacyText = dataTransfer.getData('Text');
                                        if (legacyText && legacyText.length > 0) {
                                                if (legacyText.indexOf(mceInternalUrlPrefix) == -1) {
-                                                       data['text/plain'] = legacyText;
+                                                       items['text/plain'] = legacyText;
                                                }
                                        }
                                }
@@ -518,12 +548,12 @@ define("tinymce/pasteplugin/Clipboard", [
                                if (dataTransfer.types) {
                                        for (var i = 0; i < dataTransfer.types.length; i++) {
                                                var contentType = dataTransfer.types[i];
-                                               data[contentType] = dataTransfer.getData(contentType);
+                                               items[contentType] = dataTransfer.getData(contentType);
                                        }
                                }
                        }
 
-                       return data;
+                       return items;
                }
 
                /**
@@ -537,27 +567,46 @@ define("tinymce/pasteplugin/Clipboard", [
                        return getDataTransferItems(clipboardEvent.clipboardData || editor.getDoc().dataTransfer);
                }
 
+               function hasHtmlOrText(content) {
+                       return hasContentType(content, 'text/html') || hasContentType(content, 'text/plain');
+               }
+
                /**
                 * Checks if the clipboard contains image data if it does it will take that data
                 * and convert it into a data url image and paste that image at the caret location.
                 *
                 * @param  {ClipboardEvent} e Paste/drop event object.
-                * @param  {DOMRange} rng Optional rng object to move selection to.
+                * @param  {DOMRange} rng Rng object to move selection to.
                 * @return {Boolean} true/false if the image data was found or not.
                 */
                function pasteImageData(e, rng) {
                        var dataTransfer = e.clipboardData || e.dataTransfer;
 
+                       function getBase64FromUri(uri) {
+                               var idx;
+
+                               idx = uri.indexOf(',');
+                               if (idx !== -1) {
+                                       return uri.substr(idx + 1);
+                               }
+
+                               return null;
+                       }
+
                        function processItems(items) {
                                var i, item, reader, hadImage = false;
 
-                               function pasteImage(reader) {
+                               function pasteImage(reader, blob) {
                                        if (rng) {
                                                editor.selection.setRng(rng);
                                                rng = null;
                                        }
 
-                                       pasteHtml('<img src="' + reader.result + '">');
+                                       var blobCache = editor.editorUpload.blobCache;
+                                       var blobInfo = blobCache.create(uniqueId(), blob, getBase64FromUri(reader.result));
+                                       blobCache.add(blobInfo);
+
+                                       pasteHtml('<img src="' + blobInfo.blobUri() + '">');
                                }
 
                                if (items) {
@@ -565,9 +614,11 @@ define("tinymce/pasteplugin/Clipboard", [
                                                item = items[i];
 
                                                if (/^image\/(jpeg|png|gif|bmp)$/.test(item.type)) {
+                                                       var blob = item.getAsFile ? item.getAsFile() : item;
+
                                                        reader = new FileReader();
-                                                       reader.onload = pasteImage.bind(null, reader);
-                                                       reader.readAsDataURL(item.getAsFile ? item.getAsFile() : item);
+                                                       reader.onload = pasteImage.bind(null, reader, blob);
+                                                       reader.readAsDataURL(blob);
 
                                                        e.preventDefault();
                                                        hadImage = true;
@@ -651,6 +702,69 @@ define("tinymce/pasteplugin/Clipboard", [
                                }
                        });
 
+                       function insertClipboardContent(clipboardContent, isKeyBoardPaste, plainTextMode) {
+                               var content;
+
+                               // Grab HTML from Clipboard API or paste bin as a fallback
+                               if (hasContentType(clipboardContent, 'text/html')) {
+                                       content = clipboardContent['text/html'];
+                               } else {
+                                       content = getPasteBinHtml();
+
+                                       // If paste bin is empty try using plain text mode
+                                       // since that is better than nothing right
+                                       if (content == pasteBinDefaultContent) {
+                                               plainTextMode = true;
+                                       }
+                               }
+
+                               content = Utils.trimHtml(content);
+
+                               // WebKit has a nice bug where it clones the paste bin if you paste from for example notepad
+                               // so we need to force plain text mode in this case
+                               if (pasteBinElm && pasteBinElm.firstChild && pasteBinElm.firstChild.id === 'mcepastebin') {
+                                       plainTextMode = true;
+                               }
+
+                               removePasteBin();
+
+                               // If we got nothing from clipboard API and pastebin then we could try the last resort: plain/text
+                               if (!content.length) {
+                                       plainTextMode = true;
+                               }
+
+                               // Grab plain text from Clipboard API or convert existing HTML to plain text
+                               if (plainTextMode) {
+                                       // Use plain text contents from Clipboard API unless the HTML contains paragraphs then
+                                       // we should convert the HTML to plain text since works better when pasting HTML/Word contents as plain text
+                                       if (hasContentType(clipboardContent, 'text/plain') && content.indexOf('</p>') == -1) {
+                                               content = clipboardContent['text/plain'];
+                                       } else {
+                                               content = Utils.innerText(content);
+                                       }
+                               }
+
+                               // If the content is the paste bin default HTML then it was
+                               // impossible to get the cliboard data out.
+                               if (content == pasteBinDefaultContent) {
+                                       if (!isKeyBoardPaste) {
+                                               editor.windowManager.alert('Please use Ctrl+V/Cmd+V keyboard shortcuts to paste contents.');
+                                       }
+
+                                       return;
+                               }
+
+                               if (plainTextMode) {
+                                       pasteText(content);
+                               } else {
+                                       pasteHtml(content);
+                               }
+                       }
+
+                       var getLastRng = function() {
+                               return lastRng || editor.selection.getRng();
+                       };
+
                        editor.on('paste', function(e) {
                                // Getting content from the Clipboard can take some time
                                var clipboardTimer = new Date().getTime();
@@ -667,7 +781,7 @@ define("tinymce/pasteplugin/Clipboard", [
                                        return;
                                }
 
-                               if (pasteImageData(e)) {
+                               if (!hasHtmlOrText(clipboardContent) && pasteImageData(e, getLastRng())) {
                                        removePasteBin();
                                        return;
                                }
@@ -689,64 +803,15 @@ define("tinymce/pasteplugin/Clipboard", [
                                        clipboardContent["text/html"] = getPasteBinHtml();
                                }
 
-                               setTimeout(function() {
-                                       var content;
-
-                                       // Grab HTML from Clipboard API or paste bin as a fallback
-                                       if (hasContentType(clipboardContent, 'text/html')) {
-                                               content = clipboardContent['text/html'];
-                                       } else {
-                                               content = getPasteBinHtml();
-
-                                               // If paste bin is empty try using plain text mode
-                                               // since that is better than nothing right
-                                               if (content == pasteBinDefaultContent) {
-                                                       plainTextMode = true;
-                                               }
-                                       }
-
-                                       content = Utils.trimHtml(content);
-
-                                       // WebKit has a nice bug where it clones the paste bin if you paste from for example notepad
-                                       // so we need to force plain text mode in this case
-                                       if (pasteBinElm && pasteBinElm.firstChild && pasteBinElm.firstChild.id === 'mcepastebin') {
-                                               plainTextMode = true;
-                                       }
-
-                                       removePasteBin();
-
-                                       // If we got nothing from clipboard API and pastebin then we could try the last resort: plain/text
-                                       if (!content.length) {
-                                               plainTextMode = true;
-                                       }
-
-                                       // Grab plain text from Clipboard API or convert existing HTML to plain text
-                                       if (plainTextMode) {
-                                               // Use plain text contents from Clipboard API unless the HTML contains paragraphs then
-                                               // we should convert the HTML to plain text since works better when pasting HTML/Word contents as plain text
-                                               if (hasContentType(clipboardContent, 'text/plain') && content.indexOf('</p>') == -1) {
-                                                       content = clipboardContent['text/plain'];
-                                               } else {
-                                                       content = Utils.innerText(content);
-                                               }
-                                       }
-
-                                       // If the content is the paste bin default HTML then it was
-                                       // impossible to get the cliboard data out.
-                                       if (content == pasteBinDefaultContent) {
-                                               if (!isKeyBoardPaste) {
-                                                       editor.windowManager.alert('Please use Ctrl+V/Cmd+V keyboard shortcuts to paste contents.');
-                                               }
-
-                                               return;
-                                       }
-
-                                       if (plainTextMode) {
-                                               pasteText(content);
-                                       } else {
-                                               pasteHtml(content);
-                                       }
-                               }, 0);
+                               // If clipboard API has HTML then use that directly
+                               if (hasContentType(clipboardContent, 'text/html')) {
+                                       e.preventDefault();
+                                       insertClipboardContent(clipboardContent, isKeyBoardPaste, plainTextMode);
+                               } else {
+                                       Delay.setEditorTimeout(editor, function() {
+                                               insertClipboardContent(clipboardContent, isKeyBoardPaste, plainTextMode);
+                                       }, 0);
+                               }
                        });
 
                        editor.on('dragstart dragend', function(e) {
@@ -754,18 +819,21 @@ define("tinymce/pasteplugin/Clipboard", [
                        });
 
                        editor.on('drop', function(e) {
-                               var rng = getCaretRangeFromEvent(e);
+                               var dropContent, rng;
+
+                               rng = getCaretRangeFromEvent(e);
 
                                if (e.isDefaultPrevented() || draggingInternally) {
                                        return;
                                }
 
-                               if (pasteImageData(e, rng)) {
+                               dropContent = getDataTransferItems(e.dataTransfer);
+
+                               if (!hasHtmlOrText(dropContent) && pasteImageData(e, rng)) {
                                        return;
                                }
 
                                if (rng && editor.settings.paste_filter_drop !== false) {
-                                       var dropContent = getDataTransferItems(e.dataTransfer);
                                        var content = dropContent['mce-internal'] || dropContent['text/html'] || dropContent['text/plain'];
 
                                        if (content) {
@@ -805,19 +873,40 @@ define("tinymce/pasteplugin/Clipboard", [
 
                        // Remove all data images from paste for example from Gecko
                        // except internal images like video elements
-                       editor.parser.addNodeFilter('img', function(nodes) {
-                               if (!editor.settings.paste_data_images) {
+                       editor.parser.addNodeFilter('img', function(nodes, name, args) {
+                               function isPasteInsert(args) {
+                                       return args.data && args.data.paste === true;
+                               }
+
+                               function remove(node) {
+                                       if (!node.attr('data-mce-object') && src !== Env.transparentSrc) {
+                                               node.remove();
+                                       }
+                               }
+
+                               function isWebKitFakeUrl(src) {
+                                       return src.indexOf("webkit-fake-url") === 0;
+                               }
+
+                               function isDataUri(src) {
+                                       return src.indexOf("data:") === 0;
+                               }
+
+                               if (!editor.settings.paste_data_images && isPasteInsert(args)) {
                                        var i = nodes.length;
 
                                        while (i--) {
                                                var src = nodes[i].attributes.map.src;
 
-                                               // Some browsers automatically produce data uris on paste
+                                               if (!src) {
+                                                       continue;
+                                               }
+
                                                // Safari on Mac produces webkit-fake-url see: https://bugs.webkit.org/show_bug.cgi?id=49141
-                                               if (src && /^(data:image|webkit\-fake\-url)/.test(src)) {
-                                                       if (!nodes[i].attr('data-mce-object') && src !== Env.transparentSrc) {
-                                                               nodes[i].remove();
-                                                       }
+                                               if (isWebKitFakeUrl(src)) {
+                                                       remove(nodes[i]);
+                                               } else if (!editor.settings.allow_html_data_urls && isDataUri(src)) {
+                                                       remove(nodes[i]);
                                                }
                                        }
                                }
@@ -831,8 +920,8 @@ define("tinymce/pasteplugin/Clipboard", [
 /**
  * WordFilter.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
@@ -1317,7 +1406,9 @@ define("tinymce/pasteplugin/WordFilter", [
                                }
 
                                // Serialize DOM back to HTML
-                               e.content = new Serializer({}, schema).serialize(rootNode);
+                               e.content = new Serializer({
+                                       validate: settings.validate
+                               }, schema).serialize(rootNode);
                        }
                });
        }
@@ -1332,8 +1423,8 @@ define("tinymce/pasteplugin/WordFilter", [
 /**
  * Quirks.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
@@ -1494,8 +1585,8 @@ define("tinymce/pasteplugin/Quirks", [
 /**
  * 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
@@ -1518,23 +1609,34 @@ define("tinymce/pasteplugin/Plugin", [
        PluginManager.add('paste', function(editor) {
                var self = this, clipboard, settings = editor.settings;
 
+               function isUserInformedAboutPlainText() {
+                       return userIsInformed || editor.settings.paste_plaintext_inform === false;
+               }
+
                function togglePlainTextPaste() {
                        if (clipboard.pasteFormat == "text") {
                                this.active(false);
                                clipboard.pasteFormat = "html";
+                               editor.fire('PastePlainTextToggle', {state: false});
                        } else {
                                clipboard.pasteFormat = "text";
                                this.active(true);
 
-                               if (!userIsInformed) {
-                                       editor.windowManager.alert(
-                                               'Paste is now in plain text mode. Contents will now ' +
-                                               'be pasted as plain text until you toggle this option off.'
-                                       );
+                               if (!isUserInformedAboutPlainText()) {
+                                       var message = editor.translate('Paste is now in plain text mode. Contents will now ' +
+                                               'be pasted as plain text until you toggle this option off.');
+
+                                       editor.notificationManager.open({
+                                               text: message,
+                                               type: 'info'
+                                       });
 
                                        userIsInformed = true;
+                                       editor.fire('PastePlainTextToggle', {state: true});
                                }
                        }
+
+                       editor.focus();
                }
 
                self.clipboard = clipboard = new Clipboard(editor);