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