src/pyams_skin/resources/js/ext/tinymce/dev/plugins/paste/classes/Quirks.js
changeset 557 bca7a7e058a3
equal deleted inserted replaced
-1:000000000000 557:bca7a7e058a3
       
     1 /**
       
     2  * Quirks.js
       
     3  *
       
     4  * Copyright, Moxiecode Systems AB
       
     5  * Released under LGPL License.
       
     6  *
       
     7  * License: http://www.tinymce.com/license
       
     8  * Contributing: http://www.tinymce.com/contributing
       
     9  */
       
    10 
       
    11 /**
       
    12  * This class contains various fixes for browsers. These issues can not be feature
       
    13  * detected since we have no direct control over the clipboard. However we might be able
       
    14  * to remove some of these fixes once the browsers gets updated/fixed.
       
    15  *
       
    16  * @class tinymce.pasteplugin.Quirks
       
    17  * @private
       
    18  */
       
    19 define("tinymce/pasteplugin/Quirks", [
       
    20 	"tinymce/Env",
       
    21 	"tinymce/util/Tools",
       
    22 	"tinymce/pasteplugin/WordFilter",
       
    23 	"tinymce/pasteplugin/Utils"
       
    24 ], function(Env, Tools, WordFilter, Utils) {
       
    25 	"use strict";
       
    26 
       
    27 	return function(editor) {
       
    28 		function addPreProcessFilter(filterFunc) {
       
    29 			editor.on('BeforePastePreProcess', function(e) {
       
    30 				e.content = filterFunc(e.content);
       
    31 			});
       
    32 		}
       
    33 
       
    34 		/**
       
    35 		 * Removes BR elements after block elements. IE9 has a nasty bug where it puts a BR element after each
       
    36 		 * block element when pasting from word. This removes those elements.
       
    37 		 *
       
    38 		 * This:
       
    39 		 *  <p>a</p><br><p>b</p>
       
    40 		 *
       
    41 		 * Becomes:
       
    42 		 *  <p>a</p><p>b</p>
       
    43 		 */
       
    44 		function removeExplorerBrElementsAfterBlocks(html) {
       
    45 			// Only filter word specific content
       
    46 			if (!WordFilter.isWordContent(html)) {
       
    47 				return html;
       
    48 			}
       
    49 
       
    50 			// Produce block regexp based on the block elements in schema
       
    51 			var blockElements = [];
       
    52 
       
    53 			Tools.each(editor.schema.getBlockElements(), function(block, blockName) {
       
    54 				blockElements.push(blockName);
       
    55 			});
       
    56 
       
    57 			var explorerBlocksRegExp = new RegExp(
       
    58 				'(?:<br>&nbsp;[\\s\\r\\n]+|<br>)*(<\\/?(' + blockElements.join('|') + ')[^>]*>)(?:<br>&nbsp;[\\s\\r\\n]+|<br>)*',
       
    59 				'g'
       
    60 			);
       
    61 
       
    62 			// Remove BR:s from: <BLOCK>X</BLOCK><BR>
       
    63 			html = Utils.filter(html, [
       
    64 				[explorerBlocksRegExp, '$1']
       
    65 			]);
       
    66 
       
    67 			// IE9 also adds an extra BR element for each soft-linefeed and it also adds a BR for each word wrap break
       
    68 			html = Utils.filter(html, [
       
    69 				[/<br><br>/g, '<BR><BR>'], // Replace multiple BR elements with uppercase BR to keep them intact
       
    70 				[/<br>/g, ' '],            // Replace single br elements with space since they are word wrap BR:s
       
    71 				[/<BR><BR>/g, '<br>']      // Replace back the double brs but into a single BR
       
    72 			]);
       
    73 
       
    74 			return html;
       
    75 		}
       
    76 
       
    77 		/**
       
    78 		 * WebKit has a nasty bug where the all computed styles gets added to style attributes when copy/pasting contents.
       
    79 		 * This fix solves that by simply removing the whole style attribute.
       
    80 		 *
       
    81 		 * The paste_webkit_styles option can be set to specify what to keep:
       
    82 		 *  paste_webkit_styles: "none" // Keep no styles
       
    83 		 *  paste_webkit_styles: "all", // Keep all of them
       
    84 		 *  paste_webkit_styles: "font-weight color" // Keep specific ones
       
    85 		 *
       
    86 		 * @param {String} content Content that needs to be processed.
       
    87 		 * @return {String} Processed contents.
       
    88 		 */
       
    89 		function removeWebKitStyles(content) {
       
    90 			// Passthrough all styles from Word and let the WordFilter handle that junk
       
    91 			if (WordFilter.isWordContent(content)) {
       
    92 				return content;
       
    93 			}
       
    94 
       
    95 			// Filter away styles that isn't matching the target node
       
    96 			var webKitStyles = editor.settings.paste_webkit_styles;
       
    97 
       
    98 			if (editor.settings.paste_remove_styles_if_webkit === false || webKitStyles == "all") {
       
    99 				return content;
       
   100 			}
       
   101 
       
   102 			if (webKitStyles) {
       
   103 				webKitStyles = webKitStyles.split(/[, ]/);
       
   104 			}
       
   105 
       
   106 			// Keep specific styles that doesn't match the current node computed style
       
   107 			if (webKitStyles) {
       
   108 				var dom = editor.dom, node = editor.selection.getNode();
       
   109 
       
   110 				content = content.replace(/(<[^>]+) style="([^"]*)"([^>]*>)/gi, function(all, before, value, after) {
       
   111 					var inputStyles = dom.parseStyle(value, 'span'), outputStyles = {};
       
   112 
       
   113 					if (webKitStyles === "none") {
       
   114 						return before + after;
       
   115 					}
       
   116 
       
   117 					for (var i = 0; i < webKitStyles.length; i++) {
       
   118 						var inputValue = inputStyles[webKitStyles[i]], currentValue = dom.getStyle(node, webKitStyles[i], true);
       
   119 
       
   120 						if (/color/.test(webKitStyles[i])) {
       
   121 							inputValue = dom.toHex(inputValue);
       
   122 							currentValue = dom.toHex(currentValue);
       
   123 						}
       
   124 
       
   125 						if (currentValue != inputValue) {
       
   126 							outputStyles[webKitStyles[i]] = inputValue;
       
   127 						}
       
   128 					}
       
   129 
       
   130 					outputStyles = dom.serializeStyle(outputStyles, 'span');
       
   131 					if (outputStyles) {
       
   132 						return before + ' style="' + outputStyles + '"' + after;
       
   133 					}
       
   134 
       
   135 					return before + after;
       
   136 				});
       
   137 			} else {
       
   138 				// Remove all external styles
       
   139 				content = content.replace(/(<[^>]+) style="([^"]*)"([^>]*>)/gi, '$1$3');
       
   140 			}
       
   141 
       
   142 			// Keep internal styles
       
   143 			content = content.replace(/(<[^>]+) data-mce-style="([^"]+)"([^>]*>)/gi, function(all, before, value, after) {
       
   144 				return before + ' style="' + value + '"' + after;
       
   145 			});
       
   146 
       
   147 			return content;
       
   148 		}
       
   149 
       
   150 		// Sniff browsers and apply fixes since we can't feature detect
       
   151 		if (Env.webkit) {
       
   152 			addPreProcessFilter(removeWebKitStyles);
       
   153 		}
       
   154 
       
   155 		if (Env.ie) {
       
   156 			addPreProcessFilter(removeExplorerBrElementsAfterBlocks);
       
   157 		}
       
   158 	};
       
   159 });