wp/wp-includes/js/tinymce/plugins/media/plugin.js
changeset 7 cf61fcea0001
parent 5 5e2f62d02dcd
child 9 177826044cd9
equal deleted inserted replaced
6:490d5cc509ed 7:cf61fcea0001
     1 /**
     1 (function () {
     2  * plugin.js
     2 var media = (function () {
     3  *
     3   'use strict';
     4  * Copyright, Moxiecode Systems AB
     4 
     5  * Released under LGPL License.
     5   var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
     6  *
     6 
     7  * License: http://www.tinymce.com/license
     7   var global$1 = tinymce.util.Tools.resolve('tinymce.Env');
     8  * Contributing: http://www.tinymce.com/contributing
     8 
     9  */
     9   var global$2 = tinymce.util.Tools.resolve('tinymce.util.Tools');
    10 
    10 
    11 /*jshint maxlen:255 */
    11   var getScripts = function (editor) {
    12 /*eslint max-len:0 */
    12     return editor.getParam('media_scripts');
    13 /*global tinymce:true */
    13   };
    14 
    14   var getAudioTemplateCallback = function (editor) {
    15 tinymce.PluginManager.add('media', function(editor, url) {
    15     return editor.getParam('audio_template_callback');
    16 	var urlPatterns = [
    16   };
    17 		{regex: /youtu\.be\/([\w\-.]+)/, type: 'iframe', w: 425, h: 350, url: '//www.youtube.com/embed/$1'},
    17   var getVideoTemplateCallback = function (editor) {
    18 		{regex: /youtube\.com(.+)v=([^&]+)/, type: 'iframe', w: 425, h: 350, url: '//www.youtube.com/embed/$2'},
    18     return editor.getParam('video_template_callback');
    19 		{regex: /vimeo\.com\/([0-9]+)/, type: 'iframe', w: 425, h: 350, url: '//player.vimeo.com/video/$1?title=0&byline=0&portrait=0&color=8dc7dc'},
    19   };
    20 		{regex: /vimeo\.com\/(.*)\/([0-9]+)/, type: "iframe", w: 425, h: 350, url: "//player.vimeo.com/video/$2?title=0&byline=0"},
    20   var hasLiveEmbeds = function (editor) {
    21 		{regex: /maps\.google\.([a-z]{2,3})\/maps\/(.+)msid=(.+)/, type: 'iframe', w: 425, h: 350, url: '//maps.google.com/maps/ms?msid=$2&output=embed"'}
    21     return editor.getParam('media_live_embeds', true);
    22 	];
    22   };
    23 
    23   var shouldFilterHtml = function (editor) {
    24 	var embedChange = (tinymce.Env.ie && tinymce.Env.ie <= 8) ? 'onChange' : 'onInput';
    24     return editor.getParam('media_filter_html', true);
    25 
    25   };
    26 	function guessMime(url) {
    26   var getUrlResolver = function (editor) {
    27 		url = url.toLowerCase();
    27     return editor.getParam('media_url_resolver');
    28 
    28   };
    29 		if (url.indexOf('.mp3') != -1) {
    29   var hasAltSource = function (editor) {
    30 			return 'audio/mpeg';
    30     return editor.getParam('media_alt_source', true);
    31 		}
    31   };
    32 
    32   var hasPoster = function (editor) {
    33 		if (url.indexOf('.wav') != -1) {
    33     return editor.getParam('media_poster', true);
    34 			return 'audio/wav';
    34   };
    35 		}
    35   var hasDimensions = function (editor) {
    36 
    36     return editor.getParam('media_dimensions', true);
    37 		if (url.indexOf('.mp4') != -1) {
    37   };
    38 			return 'video/mp4';
    38   var $_69rpmgh3jjgwecnr = {
    39 		}
    39     getScripts: getScripts,
    40 
    40     getAudioTemplateCallback: getAudioTemplateCallback,
    41 		if (url.indexOf('.webm') != -1) {
    41     getVideoTemplateCallback: getVideoTemplateCallback,
    42 			return 'video/webm';
    42     hasLiveEmbeds: hasLiveEmbeds,
    43 		}
    43     shouldFilterHtml: shouldFilterHtml,
    44 
    44     getUrlResolver: getUrlResolver,
    45 		if (url.indexOf('.ogg') != -1) {
    45     hasAltSource: hasAltSource,
    46 			return 'video/ogg';
    46     hasPoster: hasPoster,
    47 		}
    47     hasDimensions: hasDimensions
    48 
    48   };
    49 		if (url.indexOf('.swf') != -1) {
    49 
    50 			return 'application/x-shockwave-flash';
    50   var global$3 = tinymce.util.Tools.resolve('tinymce.html.SaxParser');
    51 		}
    51 
    52 
    52   var global$4 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils');
    53 		return '';
    53 
    54 	}
    54   var getVideoScriptMatch = function (prefixes, src) {
    55 
    55     if (prefixes) {
    56 	function getVideoScriptMatch(src) {
    56       for (var i = 0; i < prefixes.length; i++) {
    57 		var prefixes = editor.settings.media_scripts;
    57         if (src.indexOf(prefixes[i].filter) !== -1) {
    58 
    58           return prefixes[i];
    59 		if (prefixes) {
    59         }
    60 			for (var i = 0; i < prefixes.length; i++) {
    60       }
    61 				if (src.indexOf(prefixes[i].filter) !== -1) {
    61     }
    62 					return prefixes[i];
    62   };
    63 				}
    63   var $_4q3fmh7jjgwecnw = { getVideoScriptMatch: getVideoScriptMatch };
    64 			}
    64 
    65 		}
    65   var trimPx = function (value) {
    66 	}
    66     return value.replace(/px$/, '');
    67 
    67   };
    68 	function showDialog() {
    68   var addPx = function (value) {
    69 		var win, width, height, data;
    69     return /^[0-9.]+$/.test(value) ? value + 'px' : value;
    70 
    70   };
    71 		var generalFormItems = [
    71   var getSize = function (name) {
    72 			{
    72     return function (elm) {
    73 				name: 'source1',
    73       return elm ? trimPx(elm.style[name]) : '';
    74 				type: 'filepicker',
    74     };
    75 				filetype: 'media',
    75   };
    76 				size: 40,
    76   var setSize = function (name) {
    77 				autofocus: true,
    77     return function (elm, value) {
    78 				label: 'Source',
    78       if (elm) {
    79 				onchange: function(e) {
    79         elm.style[name] = addPx(value);
    80 					tinymce.each(e.meta, function(value, key) {
    80       }
    81 						win.find('#' + key).value(value);
    81     };
    82 					});
    82   };
    83 				}
    83   var $_jbvx7h8jjgwecnx = {
    84 			}
    84     getMaxWidth: getSize('maxWidth'),
    85 		];
    85     getMaxHeight: getSize('maxHeight'),
    86 
    86     setMaxWidth: setSize('maxWidth'),
    87 		function recalcSize(e) {
    87     setMaxHeight: setSize('maxHeight')
    88 			var widthCtrl, heightCtrl, newWidth, newHeight;
    88   };
    89 
    89 
    90 			widthCtrl = win.find('#width')[0];
    90   var DOM = global$4.DOM;
    91 			heightCtrl = win.find('#height')[0];
    91   var getEphoxEmbedIri = function (elm) {
    92 
    92     return DOM.getAttrib(elm, 'data-ephox-embed-iri');
    93 			newWidth = widthCtrl.value();
    93   };
    94 			newHeight = heightCtrl.value();
    94   var isEphoxEmbed = function (html) {
    95 
    95     var fragment = DOM.createFragment(html);
    96 			if (win.find('#constrain')[0].checked() && width && height && newWidth && newHeight) {
    96     return getEphoxEmbedIri(fragment.firstChild) !== '';
    97 				if (e.control == widthCtrl) {
    97   };
    98 					newHeight = Math.round((newWidth / width) * newHeight);
    98   var htmlToDataSax = function (prefixes, html) {
    99 
    99     var data = {};
   100 					if (!isNaN(newHeight)) {
   100     global$3({
   101 						heightCtrl.value(newHeight);
   101       validate: false,
   102 					}
   102       allow_conditional_comments: true,
   103 				} else {
   103       special: 'script,noscript',
   104 					newWidth = Math.round((newHeight / height) * newWidth);
   104       start: function (name, attrs) {
   105 
   105         if (!data.source1 && name === 'param') {
   106 					if (!isNaN(newWidth)) {
   106           data.source1 = attrs.map.movie;
   107 						widthCtrl.value(newWidth);
   107         }
   108 					}
   108         if (name === 'iframe' || name === 'object' || name === 'embed' || name === 'video' || name === 'audio') {
   109 				}
   109           if (!data.type) {
   110 			}
   110             data.type = name;
   111 
   111           }
   112 			width = newWidth;
   112           data = global$2.extend(attrs.map, data);
   113 			height = newHeight;
   113         }
   114 		}
   114         if (name === 'script') {
   115 
   115           var videoScript = $_4q3fmh7jjgwecnw.getVideoScriptMatch(prefixes, attrs.map.src);
   116 		if (editor.settings.media_alt_source !== false) {
   116           if (!videoScript) {
   117 			generalFormItems.push({name: 'source2', type: 'filepicker', filetype: 'media', size: 40, label: 'Alternative source'});
   117             return;
   118 		}
   118           }
   119 
   119           data = {
   120 		if (editor.settings.media_poster !== false) {
   120             type: 'script',
   121 			generalFormItems.push({name: 'poster', type: 'filepicker', filetype: 'image', size: 40, label: 'Poster'});
   121             source1: attrs.map.src,
   122 		}
   122             width: videoScript.width,
   123 
   123             height: videoScript.height
   124 		if (editor.settings.media_dimensions !== false) {
   124           };
   125 			generalFormItems.push({
   125         }
   126 				type: 'container',
   126         if (name === 'source') {
   127 				label: 'Dimensions',
   127           if (!data.source1) {
   128 				layout: 'flex',
   128             data.source1 = attrs.map.src;
   129 				align: 'center',
   129           } else if (!data.source2) {
   130 				spacing: 5,
   130             data.source2 = attrs.map.src;
   131 				items: [
   131           }
   132 					{name: 'width', type: 'textbox', maxLength: 5, size: 3, onchange: recalcSize, ariaLabel: 'Width'},
   132         }
   133 					{type: 'label', text: 'x'},
   133         if (name === 'img' && !data.poster) {
   134 					{name: 'height', type: 'textbox', maxLength: 5, size: 3, onchange: recalcSize, ariaLabel: 'Height'},
   134           data.poster = attrs.map.src;
   135 					{name: 'constrain', type: 'checkbox', checked: true, text: 'Constrain proportions'}
   135         }
   136 				]
   136       }
   137 			});
   137     }).parse(html);
   138 		}
   138     data.source1 = data.source1 || data.src || data.data;
   139 
   139     data.source2 = data.source2 || '';
   140 		data = getData(editor.selection.getNode());
   140     data.poster = data.poster || '';
   141 		width = data.width;
   141     return data;
   142 		height = data.height;
   142   };
   143 
   143   var ephoxEmbedHtmlToData = function (html) {
   144 		var embedTextBox = {
   144     var fragment = DOM.createFragment(html);
   145 			id: 'mcemediasource',
   145     var div = fragment.firstChild;
   146 			type: 'textbox',
   146     return {
   147 			flex: 1,
   147       type: 'ephox-embed-iri',
   148 			name: 'embed',
   148       source1: getEphoxEmbedIri(div),
   149 			value: getSource(),
   149       source2: '',
   150 			multiline: true,
   150       poster: '',
   151 			label: 'Source'
   151       width: $_jbvx7h8jjgwecnx.getMaxWidth(div),
   152 		};
   152       height: $_jbvx7h8jjgwecnx.getMaxHeight(div)
   153 
   153     };
   154 		function updateValueOnChange() {
   154   };
   155 			data = htmlToData(this.value());
   155   var htmlToData = function (prefixes, html) {
   156 			this.parent().parent().fromJSON(data);
   156     return isEphoxEmbed(html) ? ephoxEmbedHtmlToData(html) : htmlToDataSax(prefixes, html);
   157 		}
   157   };
   158 
   158   var $_6mep3hh4jjgwecnt = { htmlToData: htmlToData };
   159 		embedTextBox[embedChange] = updateValueOnChange;
   159 
   160 
   160   var global$5 = tinymce.util.Tools.resolve('tinymce.util.Promise');
   161 		win = editor.windowManager.open({
   161 
   162 			title: 'Insert/edit video',
   162   var guess = function (url) {
   163 			data: data,
   163     var mimes = {
   164 			bodyType: 'tabpanel',
   164       mp3: 'audio/mpeg',
   165 			body: [
   165       wav: 'audio/wav',
   166 				{
   166       mp4: 'video/mp4',
   167 					title: 'General',
   167       webm: 'video/webm',
   168 					type: "form",
   168       ogg: 'video/ogg',
   169 					onShowTab: function() {
   169       swf: 'application/x-shockwave-flash'
   170 						data = htmlToData(this.next().find('#embed').value());
   170     };
   171 						this.fromJSON(data);
   171     var fileEnd = url.toLowerCase().split('.').pop();
   172 					},
   172     var mime = mimes[fileEnd];
   173 					items: generalFormItems
   173     return mime ? mime : '';
   174 				},
   174   };
   175 
   175   var $_d9gn6bhcjjgwecol = { guess: guess };
   176 				{
   176 
   177 					title: 'Embed',
   177   var global$6 = tinymce.util.Tools.resolve('tinymce.html.Writer');
   178 					type: "panel",
   178 
   179 					layout: 'flex',
   179   var global$7 = tinymce.util.Tools.resolve('tinymce.html.Schema');
   180 					direction: 'column',
   180 
   181 					align: 'stretch',
   181   var DOM$1 = global$4.DOM;
   182 					padding: 10,
   182   var setAttributes = function (attrs, updatedAttrs) {
   183 					spacing: 10,
   183     var name;
   184 					onShowTab: function() {
   184     var i;
   185 						this.find('#embed').value(dataToHtml(this.parent().toJSON()));
   185     var value;
   186 					},
   186     var attr;
   187 					items: [
   187     for (name in updatedAttrs) {
   188 						{
   188       value = '' + updatedAttrs[name];
   189 							type: 'label',
   189       if (attrs.map[name]) {
   190 							text: 'Paste your embed code below:',
   190         i = attrs.length;
   191 							forId: 'mcemediasource'
   191         while (i--) {
   192 						},
   192           attr = attrs[i];
   193 						embedTextBox
   193           if (attr.name === name) {
   194 					]
   194             if (value) {
   195 				}
   195               attrs.map[name] = value;
   196 			],
   196               attr.value = value;
   197 			onSubmit: function() {
   197             } else {
   198 				var beforeObjects, afterObjects, i, y;
   198               delete attrs.map[name];
   199 
   199               attrs.splice(i, 1);
   200 				beforeObjects = editor.dom.select('img[data-mce-object]');
   200             }
   201 				editor.insertContent(dataToHtml(this.toJSON()));
   201           }
   202 				afterObjects = editor.dom.select('img[data-mce-object]');
   202         }
   203 
   203       } else if (value) {
   204 				// Find new image placeholder so we can select it
   204         attrs.push({
   205 				for (i = 0; i < beforeObjects.length; i++) {
   205           name: name,
   206 					for (y = afterObjects.length - 1; y >= 0; y--) {
   206           value: value
   207 						if (beforeObjects[i] == afterObjects[y]) {
   207         });
   208 							afterObjects.splice(y, 1);
   208         attrs.map[name] = value;
   209 						}
   209       }
   210 					}
   210     }
   211 				}
   211   };
   212 
   212   var normalizeHtml = function (html) {
   213 				editor.selection.select(afterObjects[0]);
   213     var writer = global$6();
   214 				editor.nodeChanged();
   214     var parser = global$3(writer);
   215 			}
   215     parser.parse(html);
   216 		});
   216     return writer.getContent();
   217 	}
   217   };
   218 
   218   var updateHtmlSax = function (html, data, updateAll) {
   219 	function getSource() {
   219     var writer = global$6();
   220 		var elm = editor.selection.getNode();
   220     var sourceCount = 0;
   221 
   221     var hasImage;
   222 		if (elm.getAttribute('data-mce-object')) {
   222     global$3({
   223 			return editor.selection.getContent();
   223       validate: false,
   224 		}
   224       allow_conditional_comments: true,
   225 	}
   225       special: 'script,noscript',
   226 
   226       comment: function (text) {
   227 	function dataToHtml(data) {
   227         writer.comment(text);
   228 		var html = '';
   228       },
   229 
   229       cdata: function (text) {
   230 		if (!data.source1) {
   230         writer.cdata(text);
   231 			tinymce.extend(data, htmlToData(data.embed));
   231       },
   232 			if (!data.source1) {
   232       text: function (text, raw) {
   233 				return '';
   233         writer.text(text, raw);
   234 			}
   234       },
   235 		}
   235       start: function (name, attrs, empty) {
   236 
   236         switch (name) {
   237 		if (!data.source2) {
   237         case 'video':
   238 			data.source2 = '';
   238         case 'object':
   239 		}
   239         case 'embed':
   240 
   240         case 'img':
   241 		if (!data.poster) {
   241         case 'iframe':
   242 			data.poster = '';
   242           if (data.height !== undefined && data.width !== undefined) {
   243 		}
   243             setAttributes(attrs, {
   244 
   244               width: data.width,
   245 		data.source1 = editor.convertURL(data.source1, "source");
   245               height: data.height
   246 		data.source2 = editor.convertURL(data.source2, "source");
   246             });
   247 		data.source1mime = guessMime(data.source1);
   247           }
   248 		data.source2mime = guessMime(data.source2);
   248           break;
   249 		data.poster = editor.convertURL(data.poster, "poster");
   249         }
   250 		data.flashPlayerUrl = editor.convertURL(url + '/moxieplayer.swf', "movie");
   250         if (updateAll) {
   251 
   251           switch (name) {
   252 		tinymce.each(urlPatterns, function(pattern) {
   252           case 'video':
   253 			var match, i, url;
   253             setAttributes(attrs, {
   254 
   254               poster: data.poster,
   255 			if ((match = pattern.regex.exec(data.source1))) {
   255               src: ''
   256 				url = pattern.url;
   256             });
   257 
   257             if (data.source2) {
   258 				for (i = 0; match[i]; i++) {
   258               setAttributes(attrs, { src: '' });
   259 					/*jshint loopfunc:true*/
   259             }
   260 					/*eslint no-loop-func:0 */
   260             break;
   261 					url = url.replace('$' + i, function() {
   261           case 'iframe':
   262 						return match[i];
   262             setAttributes(attrs, { src: data.source1 });
   263 					});
   263             break;
   264 				}
   264           case 'source':
   265 
   265             sourceCount++;
   266 				data.source1 = url;
   266             if (sourceCount <= 2) {
   267 				data.type = pattern.type;
   267               setAttributes(attrs, {
   268 				data.width = data.width || pattern.w;
   268                 src: data['source' + sourceCount],
   269 				data.height = data.height || pattern.h;
   269                 type: data['source' + sourceCount + 'mime']
   270 			}
   270               });
   271 		});
   271               if (!data['source' + sourceCount]) {
   272 
   272                 return;
   273 		if (data.embed) {
   273               }
   274 			html = updateHtml(data.embed, data, true);
   274             }
   275 		} else {
   275             break;
   276 			var videoScript = getVideoScriptMatch(data.source1);
   276           case 'img':
   277 			if (videoScript) {
   277             if (!data.poster) {
   278 				data.type = 'script';
   278               return;
   279 				data.width = videoScript.width;
   279             }
   280 				data.height = videoScript.height;
   280             hasImage = true;
   281 			}
   281             break;
   282 
   282           }
   283 			data.width = data.width || 300;
   283         }
   284 			data.height = data.height || 150;
   284         writer.start(name, attrs, empty);
   285 
   285       },
   286 			tinymce.each(data, function(value, key) {
   286       end: function (name) {
   287 				data[key] = editor.dom.encode(value);
   287         if (name === 'video' && updateAll) {
   288 			});
   288           for (var index = 1; index <= 2; index++) {
   289 
   289             if (data['source' + index]) {
   290 			if (data.type == "iframe") {
   290               var attrs = [];
   291 				html += '<iframe src="' + data.source1 + '" width="' + data.width + '" height="' + data.height + '"></iframe>';
   291               attrs.map = {};
   292 			} else if (data.source1mime == "application/x-shockwave-flash") {
   292               if (sourceCount < index) {
   293 				html += '<object data="' + data.source1 + '" width="' + data.width + '" height="' + data.height + '" type="application/x-shockwave-flash">';
   293                 setAttributes(attrs, {
   294 
   294                   src: data['source' + index],
   295 				if (data.poster) {
   295                   type: data['source' + index + 'mime']
   296 					html += '<img src="' + data.poster + '" width="' + data.width + '" height="' + data.height + '" />';
   296                 });
   297 				}
   297                 writer.start('source', attrs, true);
   298 
   298               }
   299 				html += '</object>';
   299             }
   300 			} else if (data.source1mime.indexOf('audio') != -1) {
   300           }
   301 				if (editor.settings.audio_template_callback) {
   301         }
   302 					html = editor.settings.audio_template_callback(data);
   302         if (data.poster && name === 'object' && updateAll && !hasImage) {
   303 				} else {
   303           var imgAttrs = [];
   304 					html += (
   304           imgAttrs.map = {};
   305 						'<audio controls="controls" src="' + data.source1 + '">' +
   305           setAttributes(imgAttrs, {
   306 							(data.source2 ? '\n<source src="' + data.source2 + '"' + (data.source2mime ? ' type="' + data.source2mime + '"' : '') + ' />\n' : '') +
   306             src: data.poster,
   307 						'</audio>'
   307             width: data.width,
   308 					);
   308             height: data.height
   309 				}
   309           });
   310 			} else if (data.type == "script") {
   310           writer.start('img', imgAttrs, true);
   311 				html += '<script src="' + data.source1 + '"></script>';
   311         }
   312 			} else {
   312         writer.end(name);
   313 				if (editor.settings.video_template_callback) {
   313       }
   314 					html = editor.settings.video_template_callback(data);
   314     }, global$7({})).parse(html);
   315 				} else {
   315     return writer.getContent();
   316 					html = (
   316   };
   317 						'<video width="' + data.width + '" height="' + data.height + '"' + (data.poster ? ' poster="' + data.poster + '"' : '') + ' controls="controls">\n' +
   317   var isEphoxEmbed$1 = function (html) {
   318 							'<source src="' + data.source1 + '"' + (data.source1mime ? ' type="' + data.source1mime + '"' : '') + ' />\n' +
   318     var fragment = DOM$1.createFragment(html);
   319 							(data.source2 ? '<source src="' + data.source2 + '"' + (data.source2mime ? ' type="' + data.source2mime + '"' : '') + ' />\n' : '') +
   319     return DOM$1.getAttrib(fragment.firstChild, 'data-ephox-embed-iri') !== '';
   320 						'</video>'
   320   };
   321 					);
   321   var updateEphoxEmbed = function (html, data) {
   322 				}
   322     var fragment = DOM$1.createFragment(html);
   323 			}
   323     var div = fragment.firstChild;
   324 		}
   324     $_jbvx7h8jjgwecnx.setMaxWidth(div, data.width);
   325 
   325     $_jbvx7h8jjgwecnx.setMaxHeight(div, data.height);
   326 		return html;
   326     return normalizeHtml(div.outerHTML);
   327 	}
   327   };
   328 
   328   var updateHtml = function (html, data, updateAll) {
   329 	function htmlToData(html) {
   329     return isEphoxEmbed$1(html) ? updateEphoxEmbed(html, data) : updateHtmlSax(html, data, updateAll);
   330 		var data = {};
   330   };
   331 
   331   var $_s3qkohdjjgwecon = { updateHtml: updateHtml };
   332 		new tinymce.html.SaxParser({
   332 
   333 			validate: false,
   333   var urlPatterns = [
   334 			allow_conditional_comments: true,
   334     {
   335 			special: 'script,noscript',
   335       regex: /youtu\.be\/([\w\-_\?&=.]+)/i,
   336 			start: function(name, attrs) {
   336       type: 'iframe',
   337 				if (!data.source1 && name == "param") {
   337       w: 560,
   338 					data.source1 = attrs.map.movie;
   338       h: 314,
   339 				}
   339       url: '//www.youtube.com/embed/$1',
   340 
   340       allowFullscreen: true
   341 				if (name == "iframe" || name == "object" || name == "embed" || name == "video" || name == "audio") {
   341     },
   342 					if (!data.type) {
   342     {
   343 						data.type = name;
   343       regex: /youtube\.com(.+)v=([^&]+)(&([a-z0-9&=\-_]+))?/i,
   344 					}
   344       type: 'iframe',
   345 
   345       w: 560,
   346 					data = tinymce.extend(attrs.map, data);
   346       h: 314,
   347 				}
   347       url: '//www.youtube.com/embed/$2?$4',
   348 
   348       allowFullscreen: true
   349 				if (name == "script") {
   349     },
   350 					var videoScript = getVideoScriptMatch(attrs.map.src);
   350     {
   351 					if (!videoScript) {
   351       regex: /youtube.com\/embed\/([a-z0-9\?&=\-_]+)/i,
   352 						return;
   352       type: 'iframe',
   353 					}
   353       w: 560,
   354 
   354       h: 314,
   355 					data = {
   355       url: '//www.youtube.com/embed/$1',
   356 						type: "script",
   356       allowFullscreen: true
   357 						source1: attrs.map.src,
   357     },
   358 						width: videoScript.width,
   358     {
   359 						height: videoScript.height
   359       regex: /vimeo\.com\/([0-9]+)/,
   360 					};
   360       type: 'iframe',
   361 				}
   361       w: 425,
   362 
   362       h: 350,
   363 				if (name == "source") {
   363       url: '//player.vimeo.com/video/$1?title=0&byline=0&portrait=0&color=8dc7dc',
   364 					if (!data.source1) {
   364       allowFullscreen: true
   365 						data.source1 = attrs.map.src;
   365     },
   366 					} else if (!data.source2) {
   366     {
   367 						data.source2 = attrs.map.src;
   367       regex: /vimeo\.com\/(.*)\/([0-9]+)/,
   368 					}
   368       type: 'iframe',
   369 				}
   369       w: 425,
   370 
   370       h: 350,
   371 				if (name == "img" && !data.poster) {
   371       url: '//player.vimeo.com/video/$2?title=0&amp;byline=0',
   372 					data.poster = attrs.map.src;
   372       allowFullscreen: true
   373 				}
   373     },
   374 			}
   374     {
   375 		}).parse(html);
   375       regex: /maps\.google\.([a-z]{2,3})\/maps\/(.+)msid=(.+)/,
   376 
   376       type: 'iframe',
   377 		data.source1 = data.source1 || data.src || data.data;
   377       w: 425,
   378 		data.source2 = data.source2 || '';
   378       h: 350,
   379 		data.poster = data.poster || '';
   379       url: '//maps.google.com/maps/ms?msid=$2&output=embed"',
   380 
   380       allowFullscreen: false
   381 		return data;
   381     },
   382 	}
   382     {
   383 
   383       regex: /dailymotion\.com\/video\/([^_]+)/,
   384 	function getData(element) {
   384       type: 'iframe',
   385 		if (element.getAttribute('data-mce-object')) {
   385       w: 480,
   386 			return htmlToData(editor.serializer.serialize(element, {selection: true}));
   386       h: 270,
   387 		}
   387       url: '//www.dailymotion.com/embed/video/$1',
   388 
   388       allowFullscreen: true
   389 		return {};
   389     },
   390 	}
   390     {
   391 
   391       regex: /dai\.ly\/([^_]+)/,
   392 	function sanitize(html) {
   392       type: 'iframe',
   393 		if (editor.settings.media_filter_html === false) {
   393       w: 480,
   394 			return html;
   394       h: 270,
   395 		}
   395       url: '//www.dailymotion.com/embed/video/$1',
   396 
   396       allowFullscreen: true
   397 		var writer = new tinymce.html.Writer();
   397     }
   398 
   398   ];
   399 		new tinymce.html.SaxParser({
   399   var getUrl = function (pattern, url) {
   400 			validate: false,
   400     var match = pattern.regex.exec(url);
   401 			allow_conditional_comments: false,
   401     var newUrl = pattern.url;
   402 			special: 'script,noscript',
   402     var _loop_1 = function (i) {
   403 
   403       newUrl = newUrl.replace('$' + i, function () {
   404 			comment: function(text) {
   404         return match[i] ? match[i] : '';
   405 				writer.comment(text);
   405       });
   406 			},
   406     };
   407 
   407     for (var i = 0; i < match.length; i++) {
   408 			cdata: function(text) {
   408       _loop_1(i);
   409 				writer.cdata(text);
   409     }
   410 			},
   410     return newUrl.replace(/\?$/, '');
   411 
   411   };
   412 			text: function(text, raw) {
   412   var matchPattern = function (url) {
   413 				writer.text(text, raw);
   413     var pattern = urlPatterns.filter(function (pattern) {
   414 			},
   414       return pattern.regex.test(url);
   415 
   415     });
   416 			start: function(name, attrs, empty) {
   416     if (pattern.length > 0) {
   417 				if (name == 'script' || name == 'noscript') {
   417       return global$2.extend({}, pattern[0], { url: getUrl(pattern[0], url) });
   418 					return;
   418     } else {
   419 				}
   419       return null;
   420 
   420     }
   421 				for (var i = 0; i < attrs.length; i++) {
   421   };
   422 					if (attrs[i].name.indexOf('on') === 0) {
   422 
   423 						return;
   423   var getIframeHtml = function (data) {
   424 					}
   424     var allowFullscreen = data.allowFullscreen ? ' allowFullscreen="1"' : '';
   425 				}
   425     return '<iframe src="' + data.source1 + '" width="' + data.width + '" height="' + data.height + '"' + allowFullscreen + '></iframe>';
   426 
   426   };
   427 				writer.start(name, attrs, empty);
   427   var getFlashHtml = function (data) {
   428 			},
   428     var html = '<object data="' + data.source1 + '" width="' + data.width + '" height="' + data.height + '" type="application/x-shockwave-flash">';
   429 
   429     if (data.poster) {
   430 			end: function(name) {
   430       html += '<img src="' + data.poster + '" width="' + data.width + '" height="' + data.height + '" />';
   431 				if (name == 'script' || name == 'noscript') {
   431     }
   432 					return;
   432     html += '</object>';
   433 				}
   433     return html;
   434 
   434   };
   435 				writer.end(name);
   435   var getAudioHtml = function (data, audioTemplateCallback) {
   436 			}
   436     if (audioTemplateCallback) {
   437 		}, new tinymce.html.Schema({})).parse(html);
   437       return audioTemplateCallback(data);
   438 
   438     } else {
   439 		return writer.getContent();
   439       return '<audio controls="controls" src="' + data.source1 + '">' + (data.source2 ? '\n<source src="' + data.source2 + '"' + (data.source2mime ? ' type="' + data.source2mime + '"' : '') + ' />\n' : '') + '</audio>';
   440 	}
   440     }
   441 
   441   };
   442 	function updateHtml(html, data, updateAll) {
   442   var getVideoHtml = function (data, videoTemplateCallback) {
   443 		var writer = new tinymce.html.Writer();
   443     if (videoTemplateCallback) {
   444 		var sourceCount = 0, hasImage;
   444       return videoTemplateCallback(data);
   445 
   445     } else {
   446 		function setAttributes(attrs, updatedAttrs) {
   446       return '<video width="' + data.width + '" height="' + data.height + '"' + (data.poster ? ' poster="' + data.poster + '"' : '') + ' controls="controls">\n' + '<source src="' + data.source1 + '"' + (data.source1mime ? ' type="' + data.source1mime + '"' : '') + ' />\n' + (data.source2 ? '<source src="' + data.source2 + '"' + (data.source2mime ? ' type="' + data.source2mime + '"' : '') + ' />\n' : '') + '</video>';
   447 			var name, i, value, attr;
   447     }
   448 
   448   };
   449 			for (name in updatedAttrs) {
   449   var getScriptHtml = function (data) {
   450 				value = "" + updatedAttrs[name];
   450     return '<script src="' + data.source1 + '"></script>';
   451 
   451   };
   452 				if (attrs.map[name]) {
   452   var dataToHtml = function (editor, dataIn) {
   453 					i = attrs.length;
   453     var data = global$2.extend({}, dataIn);
   454 					while (i--) {
   454     if (!data.source1) {
   455 						attr = attrs[i];
   455       global$2.extend(data, $_6mep3hh4jjgwecnt.htmlToData($_69rpmgh3jjgwecnr.getScripts(editor), data.embed));
   456 
   456       if (!data.source1) {
   457 						if (attr.name == name) {
   457         return '';
   458 							if (value) {
   458       }
   459 								attrs.map[name] = value;
   459     }
   460 								attr.value = value;
   460     if (!data.source2) {
   461 							} else {
   461       data.source2 = '';
   462 								delete attrs.map[name];
   462     }
   463 								attrs.splice(i, 1);
   463     if (!data.poster) {
   464 							}
   464       data.poster = '';
   465 						}
   465     }
   466 					}
   466     data.source1 = editor.convertURL(data.source1, 'source');
   467 				} else if (value) {
   467     data.source2 = editor.convertURL(data.source2, 'source');
   468 					attrs.push({
   468     data.source1mime = $_d9gn6bhcjjgwecol.guess(data.source1);
   469 						name: name,
   469     data.source2mime = $_d9gn6bhcjjgwecol.guess(data.source2);
   470 						value: value
   470     data.poster = editor.convertURL(data.poster, 'poster');
   471 					});
   471     var pattern = matchPattern(data.source1);
   472 
   472     if (pattern) {
   473 					attrs.map[name] = value;
   473       data.source1 = pattern.url;
   474 				}
   474       data.type = pattern.type;
   475 			}
   475       data.allowFullscreen = pattern.allowFullscreen;
   476 		}
   476       data.width = data.width || pattern.w;
   477 
   477       data.height = data.height || pattern.h;
   478 		new tinymce.html.SaxParser({
   478     }
   479 			validate: false,
   479     if (data.embed) {
   480 			allow_conditional_comments: true,
   480       return $_s3qkohdjjgwecon.updateHtml(data.embed, data, true);
   481 			special: 'script,noscript',
   481     } else {
   482 
   482       var videoScript = $_4q3fmh7jjgwecnw.getVideoScriptMatch($_69rpmgh3jjgwecnr.getScripts(editor), data.source1);
   483 			comment: function(text) {
   483       if (videoScript) {
   484 				writer.comment(text);
   484         data.type = 'script';
   485 			},
   485         data.width = videoScript.width;
   486 
   486         data.height = videoScript.height;
   487 			cdata: function(text) {
   487       }
   488 				writer.cdata(text);
   488       var audioTemplateCallback = $_69rpmgh3jjgwecnr.getAudioTemplateCallback(editor);
   489 			},
   489       var videoTemplateCallback = $_69rpmgh3jjgwecnr.getVideoTemplateCallback(editor);
   490 
   490       data.width = data.width || 300;
   491 			text: function(text, raw) {
   491       data.height = data.height || 150;
   492 				writer.text(text, raw);
   492       global$2.each(data, function (value, key) {
   493 			},
   493         data[key] = editor.dom.encode(value);
   494 
   494       });
   495 			start: function(name, attrs, empty) {
   495       if (data.type === 'iframe') {
   496 				switch (name) {
   496         return getIframeHtml(data);
   497 					case "video":
   497       } else if (data.source1mime === 'application/x-shockwave-flash') {
   498 					case "object":
   498         return getFlashHtml(data);
   499 					case "embed":
   499       } else if (data.source1mime.indexOf('audio') !== -1) {
   500 					case "img":
   500         return getAudioHtml(data, audioTemplateCallback);
   501 					case "iframe":
   501       } else if (data.type === 'script') {
   502 						setAttributes(attrs, {
   502         return getScriptHtml(data);
   503 							width: data.width,
   503       } else {
   504 							height: data.height
   504         return getVideoHtml(data, videoTemplateCallback);
   505 						});
   505       }
   506 						break;
   506     }
   507 				}
   507   };
   508 
   508   var $_bc7nlthbjjgwecoh = { dataToHtml: dataToHtml };
   509 				if (updateAll) {
   509 
   510 					switch (name) {
   510   var cache = {};
   511 						case "video":
   511   var embedPromise = function (data, dataToHtml, handler) {
   512 							setAttributes(attrs, {
   512     return new global$5(function (res, rej) {
   513 								poster: data.poster,
   513       var wrappedResolve = function (response) {
   514 								src: ""
   514         if (response.html) {
   515 							});
   515           cache[data.source1] = response;
   516 
   516         }
   517 							if (data.source2) {
   517         return res({
   518 								setAttributes(attrs, {
   518           url: data.source1,
   519 									src: ""
   519           html: response.html ? response.html : dataToHtml(data)
   520 								});
   520         });
   521 							}
   521       };
   522 							break;
   522       if (cache[data.source1]) {
   523 
   523         wrappedResolve(cache[data.source1]);
   524 						case "iframe":
   524       } else {
   525 							setAttributes(attrs, {
   525         handler({ url: data.source1 }, wrappedResolve, rej);
   526 								src: data.source1
   526       }
   527 							});
   527     });
   528 							break;
   528   };
   529 
   529   var defaultPromise = function (data, dataToHtml) {
   530 						case "source":
   530     return new global$5(function (res) {
   531 							sourceCount++;
   531       res({
   532 
   532         html: dataToHtml(data),
   533 							if (sourceCount <= 2) {
   533         url: data.source1
   534 								setAttributes(attrs, {
   534       });
   535 									src: data["source" + sourceCount],
   535     });
   536 									type: data["source" + sourceCount + "mime"]
   536   };
   537 								});
   537   var loadedData = function (editor) {
   538 
   538     return function (data) {
   539 								if (!data["source" + sourceCount]) {
   539       return $_bc7nlthbjjgwecoh.dataToHtml(editor, data);
   540 									return;
   540     };
   541 								}
   541   };
   542 							}
   542   var getEmbedHtml = function (editor, data) {
   543 							break;
   543     var embedHandler = $_69rpmgh3jjgwecnr.getUrlResolver(editor);
   544 
   544     return embedHandler ? embedPromise(data, loadedData(editor), embedHandler) : defaultPromise(data, loadedData(editor));
   545 						case "img":
   545   };
   546 							if (!data.poster) {
   546   var isCached = function (url) {
   547 								return;
   547     return cache.hasOwnProperty(url);
   548 							}
   548   };
   549 
   549   var $_cwvqyth9jjgweco9 = {
   550 							hasImage = true;
   550     getEmbedHtml: getEmbedHtml,
   551 							break;
   551     isCached: isCached
   552 					}
   552   };
   553 				}
   553 
   554 
   554   var doSyncSize = function (widthCtrl, heightCtrl) {
   555 				writer.start(name, attrs, empty);
   555     widthCtrl.state.set('oldVal', widthCtrl.value());
   556 			},
   556     heightCtrl.state.set('oldVal', heightCtrl.value());
   557 
   557   };
   558 			end: function(name) {
   558   var doSizeControls = function (win, f) {
   559 				if (name == "video" && updateAll) {
   559     var widthCtrl = win.find('#width')[0];
   560 					for (var index = 1; index <= 2; index++) {
   560     var heightCtrl = win.find('#height')[0];
   561 						if (data["source" + index]) {
   561     var constrained = win.find('#constrain')[0];
   562 							var attrs = [];
   562     if (widthCtrl && heightCtrl && constrained) {
   563 							attrs.map = {};
   563       f(widthCtrl, heightCtrl, constrained.checked());
   564 
   564     }
   565 							if (sourceCount < index) {
   565   };
   566 								setAttributes(attrs, {
   566   var doUpdateSize = function (widthCtrl, heightCtrl, isContrained) {
   567 									src: data["source" + index],
   567     var oldWidth = widthCtrl.state.get('oldVal');
   568 									type: data["source" + index + "mime"]
   568     var oldHeight = heightCtrl.state.get('oldVal');
   569 								});
   569     var newWidth = widthCtrl.value();
   570 
   570     var newHeight = heightCtrl.value();
   571 								writer.start("source", attrs, true);
   571     if (isContrained && oldWidth && oldHeight && newWidth && newHeight) {
   572 							}
   572       if (newWidth !== oldWidth) {
   573 						}
   573         newHeight = Math.round(newWidth / oldWidth * newHeight);
   574 					}
   574         if (!isNaN(newHeight)) {
   575 				}
   575           heightCtrl.value(newHeight);
   576 
   576         }
   577 				if (data.poster && name == "object" && updateAll && !hasImage) {
   577       } else {
   578 					var imgAttrs = [];
   578         newWidth = Math.round(newHeight / oldHeight * newWidth);
   579 					imgAttrs.map = {};
   579         if (!isNaN(newWidth)) {
   580 
   580           widthCtrl.value(newWidth);
   581 					setAttributes(imgAttrs, {
   581         }
   582 						src: data.poster,
   582       }
   583 						width: data.width,
   583     }
   584 						height: data.height
   584     doSyncSize(widthCtrl, heightCtrl);
   585 					});
   585   };
   586 
   586   var syncSize = function (win) {
   587 					writer.start("img", imgAttrs, true);
   587     doSizeControls(win, doSyncSize);
   588 				}
   588   };
   589 
   589   var updateSize = function (win) {
   590 				writer.end(name);
   590     doSizeControls(win, doUpdateSize);
   591 			}
   591   };
   592 		}, new tinymce.html.Schema({})).parse(html);
   592   var createUi = function (onChange) {
   593 
   593     var recalcSize = function () {
   594 		return writer.getContent();
   594       onChange(function (win) {
   595 	}
   595         updateSize(win);
   596 
   596       });
   597 	editor.on('ResolveName', function(e) {
   597     };
   598 		var name;
   598     return {
   599 
   599       type: 'container',
   600 		if (e.target.nodeType == 1 && (name = e.target.getAttribute("data-mce-object"))) {
   600       label: 'Dimensions',
   601 			e.name = name;
   601       layout: 'flex',
   602 		}
   602       align: 'center',
   603 	});
   603       spacing: 5,
   604 
   604       items: [
   605 	editor.on('preInit', function() {
   605         {
   606 		// Make sure that any messy HTML is retained inside these
   606           name: 'width',
   607 		var specialElements = editor.schema.getSpecialElements();
   607           type: 'textbox',
   608 		tinymce.each('video audio iframe object'.split(' '), function(name) {
   608           maxLength: 5,
   609 			specialElements[name] = new RegExp('<\/' + name + '[^>]*>', 'gi');
   609           size: 5,
   610 		});
   610           onchange: recalcSize,
   611 
   611           ariaLabel: 'Width'
   612 		// Allow elements
   612         },
   613 		//editor.schema.addValidElements('object[id|style|width|height|classid|codebase|*],embed[id|style|width|height|type|src|*],video[*],audio[*]');
   613         {
   614 
   614           type: 'label',
   615 		// Set allowFullscreen attribs as boolean
   615           text: 'x'
   616 		var boolAttrs = editor.schema.getBoolAttrs();
   616         },
   617 		tinymce.each('webkitallowfullscreen mozallowfullscreen allowfullscreen'.split(' '), function(name) {
   617         {
   618 			boolAttrs[name] = {};
   618           name: 'height',
   619 		});
   619           type: 'textbox',
   620 
   620           maxLength: 5,
   621 		// Converts iframe, video etc into placeholder images
   621           size: 5,
   622 		editor.parser.addNodeFilter('iframe,video,audio,object,embed,script', function(nodes, name) {
   622           onchange: recalcSize,
   623 			var i = nodes.length, ai, node, placeHolder, attrName, attrValue, attribs, innerHtml;
   623           ariaLabel: 'Height'
   624 			var videoScript;
   624         },
   625 
   625         {
   626 			while (i--) {
   626           name: 'constrain',
   627 				node = nodes[i];
   627           type: 'checkbox',
   628 				if (!node.parent) {
   628           checked: true,
   629 					continue;
   629           text: 'Constrain proportions'
   630 				}
   630         }
   631 
   631       ]
   632 				if (node.name == 'script') {
   632     };
   633 					videoScript = getVideoScriptMatch(node.attr('src'));
   633   };
   634 					if (!videoScript) {
   634   var $_ewaahuhhjjgwecow = {
   635 						continue;
   635     createUi: createUi,
   636 					}
   636     syncSize: syncSize,
   637 				}
   637     updateSize: updateSize
   638 
   638   };
   639 				placeHolder = new tinymce.html.Node('img', 1);
   639 
   640 				placeHolder.shortEnded = true;
   640   var embedChange = global$1.ie && global$1.ie <= 8 ? 'onChange' : 'onInput';
   641 
   641   var handleError = function (editor) {
   642 				if (videoScript) {
   642     return function (error) {
   643 					if (videoScript.width) {
   643       var errorMessage = error && error.msg ? 'Media embed handler error: ' + error.msg : 'Media embed handler threw unknown error.';
   644 						node.attr('width', videoScript.width.toString());
   644       editor.notificationManager.open({
   645 					}
   645         type: 'error',
   646 
   646         text: errorMessage
   647 					if (videoScript.height) {
   647       });
   648 						node.attr('height', videoScript.height.toString());
   648     };
   649 					}
   649   };
   650 				}
   650   var getData = function (editor) {
   651 
   651     var element = editor.selection.getNode();
   652 				// Prefix all attributes except width, height and style since we
   652     var dataEmbed = element.getAttribute('data-ephox-embed-iri');
   653 				// will add these to the placeholder
   653     if (dataEmbed) {
   654 				attribs = node.attributes;
   654       return {
   655 				ai = attribs.length;
   655         'source1': dataEmbed,
   656 				while (ai--) {
   656         'data-ephox-embed-iri': dataEmbed,
   657 					attrName = attribs[ai].name;
   657         'width': $_jbvx7h8jjgwecnx.getMaxWidth(element),
   658 					attrValue = attribs[ai].value;
   658         'height': $_jbvx7h8jjgwecnx.getMaxHeight(element)
   659 
   659       };
   660 					if (attrName !== "width" && attrName !== "height" && attrName !== "style") {
   660     }
   661 						if (attrName == "data" || attrName == "src") {
   661     return element.getAttribute('data-mce-object') ? $_6mep3hh4jjgwecnt.htmlToData($_69rpmgh3jjgwecnr.getScripts(editor), editor.serializer.serialize(element, { selection: true })) : {};
   662 							attrValue = editor.convertURL(attrValue, attrName);
   662   };
   663 						}
   663   var getSource = function (editor) {
   664 
   664     var elm = editor.selection.getNode();
   665 						placeHolder.attr('data-mce-p-' + attrName, attrValue);
   665     if (elm.getAttribute('data-mce-object') || elm.getAttribute('data-ephox-embed-iri')) {
   666 					}
   666       return editor.selection.getContent();
   667 				}
   667     }
   668 
   668   };
   669 				// Place the inner HTML contents inside an escaped attribute
   669   var addEmbedHtml = function (win, editor) {
   670 				// This enables us to copy/paste the fake object
   670     return function (response) {
   671 				innerHtml = node.firstChild && node.firstChild.value;
   671       var html = response.html;
   672 				if (innerHtml) {
   672       var embed = win.find('#embed')[0];
   673 					placeHolder.attr("data-mce-html", escape(innerHtml));
   673       var data = global$2.extend($_6mep3hh4jjgwecnt.htmlToData($_69rpmgh3jjgwecnr.getScripts(editor), html), { source1: response.url });
   674 					placeHolder.firstChild = null;
   674       win.fromJSON(data);
   675 				}
   675       if (embed) {
   676 
   676         embed.value(html);
   677 				placeHolder.attr({
   677         $_ewaahuhhjjgwecow.updateSize(win);
   678 					width: node.attr('width') || "300",
   678       }
   679 					height: node.attr('height') || (name == "audio" ? "30" : "150"),
   679     };
   680 					style: node.attr('style'),
   680   };
   681 					src: tinymce.Env.transparentSrc,
   681   var selectPlaceholder = function (editor, beforeObjects) {
   682 					"data-mce-object": name,
   682     var i;
   683 					"class": "mce-object mce-object-" + name
   683     var y;
   684 				});
   684     var afterObjects = editor.dom.select('img[data-mce-object]');
   685 
   685     for (i = 0; i < beforeObjects.length; i++) {
   686 				node.replace(placeHolder);
   686       for (y = afterObjects.length - 1; y >= 0; y--) {
   687 			}
   687         if (beforeObjects[i] === afterObjects[y]) {
   688 		});
   688           afterObjects.splice(y, 1);
   689 
   689         }
   690 		// Replaces placeholder images with real elements for video, object, iframe etc
   690       }
   691 		editor.serializer.addAttributeFilter('data-mce-object', function(nodes, name) {
   691     }
   692 			var i = nodes.length, node, realElm, ai, attribs, innerHtml, innerNode, realElmName;
   692     editor.selection.select(afterObjects[0]);
   693 
   693   };
   694 			while (i--) {
   694   var handleInsert = function (editor, html) {
   695 				node = nodes[i];
   695     var beforeObjects = editor.dom.select('img[data-mce-object]');
   696 				if (!node.parent) {
   696     editor.insertContent(html);
   697 					continue;
   697     selectPlaceholder(editor, beforeObjects);
   698 				}
   698     editor.nodeChanged();
   699 
   699   };
   700 				realElmName = node.attr(name);
   700   var submitForm = function (win, editor) {
   701 				realElm = new tinymce.html.Node(realElmName, 1);
   701     var data = win.toJSON();
   702 
   702     data.embed = $_s3qkohdjjgwecon.updateHtml(data.embed, data);
   703 				// Add width/height to everything but audio
   703     if (data.embed && $_cwvqyth9jjgweco9.isCached(data.source1)) {
   704 				if (realElmName != "audio" && realElmName != "script") {
   704       handleInsert(editor, data.embed);
   705 					realElm.attr({
   705     } else {
   706 						width: node.attr('width'),
   706       $_cwvqyth9jjgweco9.getEmbedHtml(editor, data).then(function (response) {
   707 						height: node.attr('height')
   707         handleInsert(editor, response.html);
   708 					});
   708       }).catch(handleError(editor));
   709 				}
   709     }
   710 
   710   };
   711 				realElm.attr({
   711   var populateMeta = function (win, meta) {
   712 					style: node.attr('style')
   712     global$2.each(meta, function (value, key) {
   713 				});
   713       win.find('#' + key).value(value);
   714 
   714     });
   715 				// Unprefix all placeholder attributes
   715   };
   716 				attribs = node.attributes;
   716   var showDialog = function (editor) {
   717 				ai = attribs.length;
   717     var win;
   718 				while (ai--) {
   718     var data;
   719 					var attrName = attribs[ai].name;
   719     var generalFormItems = [{
   720 
   720         name: 'source1',
   721 					if (attrName.indexOf('data-mce-p-') === 0) {
   721         type: 'filepicker',
   722 						realElm.attr(attrName.substr(11), attribs[ai].value);
   722         filetype: 'media',
   723 					}
   723         size: 40,
   724 				}
   724         autofocus: true,
   725 
   725         label: 'Source',
   726 				if (realElmName == "script") {
   726         onpaste: function () {
   727 					realElm.attr('type', 'text/javascript');
   727           setTimeout(function () {
   728 				}
   728             $_cwvqyth9jjgweco9.getEmbedHtml(editor, win.toJSON()).then(addEmbedHtml(win, editor)).catch(handleError(editor));
   729 
   729           }, 1);
   730 				// Inject innerhtml
   730         },
   731 				innerHtml = node.attr('data-mce-html');
   731         onchange: function (e) {
   732 				if (innerHtml) {
   732           $_cwvqyth9jjgweco9.getEmbedHtml(editor, win.toJSON()).then(addEmbedHtml(win, editor)).catch(handleError(editor));
   733 					innerNode = new tinymce.html.Node('#text', 3);
   733           populateMeta(win, e.meta);
   734 					innerNode.raw = true;
   734         },
   735 					innerNode.value = sanitize(unescape(innerHtml));
   735         onbeforecall: function (e) {
   736 					realElm.append(innerNode);
   736           e.meta = win.toJSON();
   737 				}
   737         }
   738 
   738       }];
   739 				node.replace(realElm);
   739     var advancedFormItems = [];
   740 			}
   740     var reserialise = function (update) {
   741 		});
   741       update(win);
   742 	});
   742       data = win.toJSON();
   743 
   743       win.find('#embed').value($_s3qkohdjjgwecon.updateHtml(data.embed, data));
   744 	editor.on('ObjectSelected', function(e) {
   744     };
   745 		var objectType = e.target.getAttribute('data-mce-object');
   745     if ($_69rpmgh3jjgwecnr.hasAltSource(editor)) {
   746 
   746       advancedFormItems.push({
   747 		if (objectType == "audio" || objectType == "script") {
   747         name: 'source2',
   748 			e.preventDefault();
   748         type: 'filepicker',
   749 		}
   749         filetype: 'media',
   750 	});
   750         size: 40,
   751 
   751         label: 'Alternative source'
   752 	editor.on('objectResized', function(e) {
   752       });
   753 		var target = e.target, html;
   753     }
   754 
   754     if ($_69rpmgh3jjgwecnr.hasPoster(editor)) {
   755 		if (target.getAttribute('data-mce-object')) {
   755       advancedFormItems.push({
   756 			html = target.getAttribute('data-mce-html');
   756         name: 'poster',
   757 			if (html) {
   757         type: 'filepicker',
   758 				html = unescape(html);
   758         filetype: 'image',
   759 				target.setAttribute('data-mce-html', escape(
   759         size: 40,
   760 					updateHtml(html, {
   760         label: 'Poster'
   761 						width: e.width,
   761       });
   762 						height: e.height
   762     }
   763 					})
   763     if ($_69rpmgh3jjgwecnr.hasDimensions(editor)) {
   764 				));
   764       var control = $_ewaahuhhjjgwecow.createUi(reserialise);
   765 			}
   765       generalFormItems.push(control);
   766 		}
   766     }
   767 	});
   767     data = getData(editor);
   768 
   768     var embedTextBox = {
   769 	editor.addButton('media', {
   769       id: 'mcemediasource',
   770 		tooltip: 'Insert/edit video',
   770       type: 'textbox',
   771 		onclick: showDialog,
   771       flex: 1,
   772 		stateSelector: ['img[data-mce-object=video]', 'img[data-mce-object=iframe]']
   772       name: 'embed',
   773 	});
   773       value: getSource(editor),
   774 
   774       multiline: true,
   775 	editor.addMenuItem('media', {
   775       rows: 5,
   776 		icon: 'media',
   776       label: 'Source'
   777 		text: 'Insert/edit video',
   777     };
   778 		onclick: showDialog,
   778     var updateValueOnChange = function () {
   779 		context: 'insert',
   779       data = global$2.extend({}, $_6mep3hh4jjgwecnt.htmlToData($_69rpmgh3jjgwecnr.getScripts(editor), this.value()));
   780 		prependToContext: true
   780       this.parent().parent().fromJSON(data);
   781 	});
   781     };
   782 });
   782     embedTextBox[embedChange] = updateValueOnChange;
       
   783     var body = [
       
   784       {
       
   785         title: 'General',
       
   786         type: 'form',
       
   787         items: generalFormItems
       
   788       },
       
   789       {
       
   790         title: 'Embed',
       
   791         type: 'container',
       
   792         layout: 'flex',
       
   793         direction: 'column',
       
   794         align: 'stretch',
       
   795         padding: 10,
       
   796         spacing: 10,
       
   797         items: [
       
   798           {
       
   799             type: 'label',
       
   800             text: 'Paste your embed code below:',
       
   801             forId: 'mcemediasource'
       
   802           },
       
   803           embedTextBox
       
   804         ]
       
   805       }
       
   806     ];
       
   807     if (advancedFormItems.length > 0) {
       
   808       body.push({
       
   809         title: 'Advanced',
       
   810         type: 'form',
       
   811         items: advancedFormItems
       
   812       });
       
   813     }
       
   814     win = editor.windowManager.open({
       
   815       title: 'Insert/edit media',
       
   816       data: data,
       
   817       bodyType: 'tabpanel',
       
   818       body: body,
       
   819       onSubmit: function () {
       
   820         $_ewaahuhhjjgwecow.updateSize(win);
       
   821         submitForm(win, editor);
       
   822       }
       
   823     });
       
   824     $_ewaahuhhjjgwecow.syncSize(win);
       
   825   };
       
   826   var $_e3lvjbh0jjgwecnm = { showDialog: showDialog };
       
   827 
       
   828   var get = function (editor) {
       
   829     var showDialog = function () {
       
   830       $_e3lvjbh0jjgwecnm.showDialog(editor);
       
   831     };
       
   832     return { showDialog: showDialog };
       
   833   };
       
   834   var $_9lh0mgzjjgwecnk = { get: get };
       
   835 
       
   836   var register = function (editor) {
       
   837     var showDialog = function () {
       
   838       $_e3lvjbh0jjgwecnm.showDialog(editor);
       
   839     };
       
   840     editor.addCommand('mceMedia', showDialog);
       
   841   };
       
   842   var $_3pne6fhijjgwecoz = { register: register };
       
   843 
       
   844   var global$8 = tinymce.util.Tools.resolve('tinymce.html.Node');
       
   845 
       
   846   var sanitize = function (editor, html) {
       
   847     if ($_69rpmgh3jjgwecnr.shouldFilterHtml(editor) === false) {
       
   848       return html;
       
   849     }
       
   850     var writer = global$6();
       
   851     var blocked;
       
   852     global$3({
       
   853       validate: false,
       
   854       allow_conditional_comments: false,
       
   855       special: 'script,noscript',
       
   856       comment: function (text) {
       
   857         writer.comment(text);
       
   858       },
       
   859       cdata: function (text) {
       
   860         writer.cdata(text);
       
   861       },
       
   862       text: function (text, raw) {
       
   863         writer.text(text, raw);
       
   864       },
       
   865       start: function (name, attrs, empty) {
       
   866         blocked = true;
       
   867         if (name === 'script' || name === 'noscript') {
       
   868           return;
       
   869         }
       
   870         for (var i = 0; i < attrs.length; i++) {
       
   871           if (attrs[i].name.indexOf('on') === 0) {
       
   872             return;
       
   873           }
       
   874           if (attrs[i].name === 'style') {
       
   875             attrs[i].value = editor.dom.serializeStyle(editor.dom.parseStyle(attrs[i].value), name);
       
   876           }
       
   877         }
       
   878         writer.start(name, attrs, empty);
       
   879         blocked = false;
       
   880       },
       
   881       end: function (name) {
       
   882         if (blocked) {
       
   883           return;
       
   884         }
       
   885         writer.end(name);
       
   886       }
       
   887     }, global$7({})).parse(html);
       
   888     return writer.getContent();
       
   889   };
       
   890   var $_58i2qvhmjjgwecp7 = { sanitize: sanitize };
       
   891 
       
   892   var createPlaceholderNode = function (editor, node) {
       
   893     var placeHolder;
       
   894     var name = node.name;
       
   895     placeHolder = new global$8('img', 1);
       
   896     placeHolder.shortEnded = true;
       
   897     retainAttributesAndInnerHtml(editor, node, placeHolder);
       
   898     placeHolder.attr({
       
   899       'width': node.attr('width') || '300',
       
   900       'height': node.attr('height') || (name === 'audio' ? '30' : '150'),
       
   901       'style': node.attr('style'),
       
   902       'src': global$1.transparentSrc,
       
   903       'data-mce-object': name,
       
   904       'class': 'mce-object mce-object-' + name
       
   905     });
       
   906     return placeHolder;
       
   907   };
       
   908   var createPreviewIframeNode = function (editor, node) {
       
   909     var previewWrapper;
       
   910     var previewNode;
       
   911     var shimNode;
       
   912     var name = node.name;
       
   913     previewWrapper = new global$8('span', 1);
       
   914     previewWrapper.attr({
       
   915       'contentEditable': 'false',
       
   916       'style': node.attr('style'),
       
   917       'data-mce-object': name,
       
   918       'class': 'mce-preview-object mce-object-' + name
       
   919     });
       
   920     retainAttributesAndInnerHtml(editor, node, previewWrapper);
       
   921     previewNode = new global$8(name, 1);
       
   922     previewNode.attr({
       
   923       src: node.attr('src'),
       
   924       allowfullscreen: node.attr('allowfullscreen'),
       
   925       style: node.attr('style'),
       
   926       class: node.attr('class'),
       
   927       width: node.attr('width'),
       
   928       height: node.attr('height'),
       
   929       frameborder: '0'
       
   930     });
       
   931     shimNode = new global$8('span', 1);
       
   932     shimNode.attr('class', 'mce-shim');
       
   933     previewWrapper.append(previewNode);
       
   934     previewWrapper.append(shimNode);
       
   935     return previewWrapper;
       
   936   };
       
   937   var retainAttributesAndInnerHtml = function (editor, sourceNode, targetNode) {
       
   938     var attrName;
       
   939     var attrValue;
       
   940     var attribs;
       
   941     var ai;
       
   942     var innerHtml;
       
   943     attribs = sourceNode.attributes;
       
   944     ai = attribs.length;
       
   945     while (ai--) {
       
   946       attrName = attribs[ai].name;
       
   947       attrValue = attribs[ai].value;
       
   948       if (attrName !== 'width' && attrName !== 'height' && attrName !== 'style') {
       
   949         if (attrName === 'data' || attrName === 'src') {
       
   950           attrValue = editor.convertURL(attrValue, attrName);
       
   951         }
       
   952         targetNode.attr('data-mce-p-' + attrName, attrValue);
       
   953       }
       
   954     }
       
   955     innerHtml = sourceNode.firstChild && sourceNode.firstChild.value;
       
   956     if (innerHtml) {
       
   957       targetNode.attr('data-mce-html', escape($_58i2qvhmjjgwecp7.sanitize(editor, innerHtml)));
       
   958       targetNode.firstChild = null;
       
   959     }
       
   960   };
       
   961   var isWithinEphoxEmbed = function (node) {
       
   962     while (node = node.parent) {
       
   963       if (node.attr('data-ephox-embed-iri')) {
       
   964         return true;
       
   965       }
       
   966     }
       
   967     return false;
       
   968   };
       
   969   var placeHolderConverter = function (editor) {
       
   970     return function (nodes) {
       
   971       var i = nodes.length;
       
   972       var node;
       
   973       var videoScript;
       
   974       while (i--) {
       
   975         node = nodes[i];
       
   976         if (!node.parent) {
       
   977           continue;
       
   978         }
       
   979         if (node.parent.attr('data-mce-object')) {
       
   980           continue;
       
   981         }
       
   982         if (node.name === 'script') {
       
   983           videoScript = $_4q3fmh7jjgwecnw.getVideoScriptMatch($_69rpmgh3jjgwecnr.getScripts(editor), node.attr('src'));
       
   984           if (!videoScript) {
       
   985             continue;
       
   986           }
       
   987         }
       
   988         if (videoScript) {
       
   989           if (videoScript.width) {
       
   990             node.attr('width', videoScript.width.toString());
       
   991           }
       
   992           if (videoScript.height) {
       
   993             node.attr('height', videoScript.height.toString());
       
   994           }
       
   995         }
       
   996         if (node.name === 'iframe' && $_69rpmgh3jjgwecnr.hasLiveEmbeds(editor) && global$1.ceFalse) {
       
   997           if (!isWithinEphoxEmbed(node)) {
       
   998             node.replace(createPreviewIframeNode(editor, node));
       
   999           }
       
  1000         } else {
       
  1001           if (!isWithinEphoxEmbed(node)) {
       
  1002             node.replace(createPlaceholderNode(editor, node));
       
  1003           }
       
  1004         }
       
  1005       }
       
  1006     };
       
  1007   };
       
  1008   var $_ggjz3ehljjgwecp4 = {
       
  1009     createPreviewIframeNode: createPreviewIframeNode,
       
  1010     createPlaceholderNode: createPlaceholderNode,
       
  1011     placeHolderConverter: placeHolderConverter
       
  1012   };
       
  1013 
       
  1014   var setup = function (editor) {
       
  1015     editor.on('preInit', function () {
       
  1016       var specialElements = editor.schema.getSpecialElements();
       
  1017       global$2.each('video audio iframe object'.split(' '), function (name) {
       
  1018         specialElements[name] = new RegExp('</' + name + '[^>]*>', 'gi');
       
  1019       });
       
  1020       var boolAttrs = editor.schema.getBoolAttrs();
       
  1021       global$2.each('webkitallowfullscreen mozallowfullscreen allowfullscreen'.split(' '), function (name) {
       
  1022         boolAttrs[name] = {};
       
  1023       });
       
  1024       editor.parser.addNodeFilter('iframe,video,audio,object,embed,script', $_ggjz3ehljjgwecp4.placeHolderConverter(editor));
       
  1025       editor.serializer.addAttributeFilter('data-mce-object', function (nodes, name) {
       
  1026         var i = nodes.length;
       
  1027         var node;
       
  1028         var realElm;
       
  1029         var ai;
       
  1030         var attribs;
       
  1031         var innerHtml;
       
  1032         var innerNode;
       
  1033         var realElmName;
       
  1034         var className;
       
  1035         while (i--) {
       
  1036           node = nodes[i];
       
  1037           if (!node.parent) {
       
  1038             continue;
       
  1039           }
       
  1040           realElmName = node.attr(name);
       
  1041           realElm = new global$8(realElmName, 1);
       
  1042           if (realElmName !== 'audio' && realElmName !== 'script') {
       
  1043             className = node.attr('class');
       
  1044             if (className && className.indexOf('mce-preview-object') !== -1) {
       
  1045               realElm.attr({
       
  1046                 width: node.firstChild.attr('width'),
       
  1047                 height: node.firstChild.attr('height')
       
  1048               });
       
  1049             } else {
       
  1050               realElm.attr({
       
  1051                 width: node.attr('width'),
       
  1052                 height: node.attr('height')
       
  1053               });
       
  1054             }
       
  1055           }
       
  1056           realElm.attr({ style: node.attr('style') });
       
  1057           attribs = node.attributes;
       
  1058           ai = attribs.length;
       
  1059           while (ai--) {
       
  1060             var attrName = attribs[ai].name;
       
  1061             if (attrName.indexOf('data-mce-p-') === 0) {
       
  1062               realElm.attr(attrName.substr(11), attribs[ai].value);
       
  1063             }
       
  1064           }
       
  1065           if (realElmName === 'script') {
       
  1066             realElm.attr('type', 'text/javascript');
       
  1067           }
       
  1068           innerHtml = node.attr('data-mce-html');
       
  1069           if (innerHtml) {
       
  1070             innerNode = new global$8('#text', 3);
       
  1071             innerNode.raw = true;
       
  1072             innerNode.value = $_58i2qvhmjjgwecp7.sanitize(editor, unescape(innerHtml));
       
  1073             realElm.append(innerNode);
       
  1074           }
       
  1075           node.replace(realElm);
       
  1076         }
       
  1077       });
       
  1078     });
       
  1079     editor.on('setContent', function () {
       
  1080       editor.$('span.mce-preview-object').each(function (index, elm) {
       
  1081         var $elm = editor.$(elm);
       
  1082         if ($elm.find('span.mce-shim', elm).length === 0) {
       
  1083           $elm.append('<span class="mce-shim"></span>');
       
  1084         }
       
  1085       });
       
  1086     });
       
  1087   };
       
  1088   var $_4o7ga9hjjjgwecp0 = { setup: setup };
       
  1089 
       
  1090   var setup$1 = function (editor) {
       
  1091     editor.on('ResolveName', function (e) {
       
  1092       var name;
       
  1093       if (e.target.nodeType === 1 && (name = e.target.getAttribute('data-mce-object'))) {
       
  1094         e.name = name;
       
  1095       }
       
  1096     });
       
  1097   };
       
  1098   var $_1y6lb6hnjjgwecp9 = { setup: setup$1 };
       
  1099 
       
  1100   var setup$2 = function (editor) {
       
  1101     editor.on('click keyup', function () {
       
  1102       var selectedNode = editor.selection.getNode();
       
  1103       if (selectedNode && editor.dom.hasClass(selectedNode, 'mce-preview-object')) {
       
  1104         if (editor.dom.getAttrib(selectedNode, 'data-mce-selected')) {
       
  1105           selectedNode.setAttribute('data-mce-selected', '2');
       
  1106         }
       
  1107       }
       
  1108     });
       
  1109     editor.on('ObjectSelected', function (e) {
       
  1110       var objectType = e.target.getAttribute('data-mce-object');
       
  1111       if (objectType === 'audio' || objectType === 'script') {
       
  1112         e.preventDefault();
       
  1113       }
       
  1114     });
       
  1115     editor.on('objectResized', function (e) {
       
  1116       var target = e.target;
       
  1117       var html;
       
  1118       if (target.getAttribute('data-mce-object')) {
       
  1119         html = target.getAttribute('data-mce-html');
       
  1120         if (html) {
       
  1121           html = unescape(html);
       
  1122           target.setAttribute('data-mce-html', escape($_s3qkohdjjgwecon.updateHtml(html, {
       
  1123             width: e.width,
       
  1124             height: e.height
       
  1125           })));
       
  1126         }
       
  1127       }
       
  1128     });
       
  1129   };
       
  1130   var $_dnm1d2hojjgwecpa = { setup: setup$2 };
       
  1131 
       
  1132   var register$1 = function (editor) {
       
  1133     editor.addButton('media', {
       
  1134       tooltip: 'Insert/edit media',
       
  1135       cmd: 'mceMedia',
       
  1136       stateSelector: [
       
  1137         'img[data-mce-object]',
       
  1138         'span[data-mce-object]',
       
  1139         'div[data-ephox-embed-iri]'
       
  1140       ]
       
  1141     });
       
  1142     editor.addMenuItem('media', {
       
  1143       icon: 'media',
       
  1144       text: 'Media',
       
  1145       cmd: 'mceMedia',
       
  1146       context: 'insert',
       
  1147       prependToContext: true
       
  1148     });
       
  1149   };
       
  1150   var $_94c7u1hpjjgwecpc = { register: register$1 };
       
  1151 
       
  1152   global.add('media', function (editor) {
       
  1153     $_3pne6fhijjgwecoz.register(editor);
       
  1154     $_94c7u1hpjjgwecpc.register(editor);
       
  1155     $_1y6lb6hnjjgwecp9.setup(editor);
       
  1156     $_4o7ga9hjjjgwecp0.setup(editor);
       
  1157     $_dnm1d2hojjgwecpa.setup(editor);
       
  1158     return $_9lh0mgzjjgwecnk.get(editor);
       
  1159   });
       
  1160   function Plugin () {
       
  1161   }
       
  1162 
       
  1163   return Plugin;
       
  1164 
       
  1165 }());
       
  1166 })();