[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-includes/js/tinymce/plugins/media/ -> plugin.js (source)

   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 global$3 = tinymce.util.Tools.resolve('tinymce.html.SaxParser');
  51  
  52      var global$4 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils');
  53  
  54      var getVideoScriptMatch = function (prefixes, src) {
  55        if (prefixes) {
  56          for (var i = 0; i < prefixes.length; i++) {
  57            if (src.indexOf(prefixes[i].filter) !== -1) {
  58              return prefixes[i];
  59            }
  60          }
  61        }
  62      };
  63      var VideoScript = { getVideoScriptMatch: getVideoScriptMatch };
  64  
  65      var trimPx = function (value) {
  66        return value.replace(/px$/, '');
  67      };
  68      var addPx = function (value) {
  69        return /^[0-9.]+$/.test(value) ? value + 'px' : value;
  70      };
  71      var getSize = function (name) {
  72        return function (elm) {
  73          return elm ? trimPx(elm.style[name]) : '';
  74        };
  75      };
  76      var setSize = function (name) {
  77        return function (elm, value) {
  78          if (elm) {
  79            elm.style[name] = addPx(value);
  80          }
  81        };
  82      };
  83      var Size = {
  84        getMaxWidth: getSize('maxWidth'),
  85        getMaxHeight: getSize('maxHeight'),
  86        setMaxWidth: setSize('maxWidth'),
  87        setMaxHeight: setSize('maxHeight')
  88      };
  89  
  90      var DOM = global$4.DOM;
  91      var getEphoxEmbedIri = function (elm) {
  92        return DOM.getAttrib(elm, 'data-ephox-embed-iri');
  93      };
  94      var isEphoxEmbed = function (html) {
  95        var fragment = DOM.createFragment(html);
  96        return getEphoxEmbedIri(fragment.firstChild) !== '';
  97      };
  98      var htmlToDataSax = function (prefixes, html) {
  99        var data = {};
 100        global$3({
 101          validate: false,
 102          allow_conditional_comments: true,
 103          special: 'script,noscript',
 104          start: function (name, attrs) {
 105            if (!data.source1 && name === 'param') {
 106              data.source1 = attrs.map.movie;
 107            }
 108            if (name === 'iframe' || name === 'object' || name === 'embed' || name === 'video' || name === 'audio') {
 109              if (!data.type) {
 110                data.type = name;
 111              }
 112              data = global$2.extend(attrs.map, data);
 113            }
 114            if (name === 'script') {
 115              var videoScript = VideoScript.getVideoScriptMatch(prefixes, attrs.map.src);
 116              if (!videoScript) {
 117                return;
 118              }
 119              data = {
 120                type: 'script',
 121                source1: attrs.map.src,
 122                width: videoScript.width,
 123                height: videoScript.height
 124              };
 125            }
 126            if (name === 'source') {
 127              if (!data.source1) {
 128                data.source1 = attrs.map.src;
 129              } else if (!data.source2) {
 130                data.source2 = attrs.map.src;
 131              }
 132            }
 133            if (name === 'img' && !data.poster) {
 134              data.poster = attrs.map.src;
 135            }
 136          }
 137        }).parse(html);
 138        data.source1 = data.source1 || data.src || data.data;
 139        data.source2 = data.source2 || '';
 140        data.poster = data.poster || '';
 141        return data;
 142      };
 143      var ephoxEmbedHtmlToData = function (html) {
 144        var fragment = DOM.createFragment(html);
 145        var div = fragment.firstChild;
 146        return {
 147          type: 'ephox-embed-iri',
 148          source1: getEphoxEmbedIri(div),
 149          source2: '',
 150          poster: '',
 151          width: Size.getMaxWidth(div),
 152          height: Size.getMaxHeight(div)
 153        };
 154      };
 155      var htmlToData = function (prefixes, html) {
 156        return isEphoxEmbed(html) ? ephoxEmbedHtmlToData(html) : htmlToDataSax(prefixes, html);
 157      };
 158      var HtmlToData = { htmlToData: htmlToData };
 159  
 160      var global$5 = tinymce.util.Tools.resolve('tinymce.util.Promise');
 161  
 162      var guess = function (url) {
 163        var mimes = {
 164          mp3: 'audio/mpeg',
 165          wav: 'audio/wav',
 166          mp4: 'video/mp4',
 167          webm: 'video/webm',
 168          ogg: 'video/ogg',
 169          swf: 'application/x-shockwave-flash'
 170        };
 171        var fileEnd = url.toLowerCase().split('.').pop();
 172        var mime = mimes[fileEnd];
 173        return mime ? mime : '';
 174      };
 175      var Mime = { guess: guess };
 176  
 177      var global$6 = tinymce.util.Tools.resolve('tinymce.html.Writer');
 178  
 179      var global$7 = tinymce.util.Tools.resolve('tinymce.html.Schema');
 180  
 181      var DOM$1 = global$4.DOM;
 182      var setAttributes = function (attrs, updatedAttrs) {
 183        var name;
 184        var i;
 185        var value;
 186        var attr;
 187        for (name in updatedAttrs) {
 188          value = '' + updatedAttrs[name];
 189          if (attrs.map[name]) {
 190            i = attrs.length;
 191            while (i--) {
 192              attr = attrs[i];
 193              if (attr.name === name) {
 194                if (value) {
 195                  attrs.map[name] = value;
 196                  attr.value = value;
 197                } else {
 198                  delete attrs.map[name];
 199                  attrs.splice(i, 1);
 200                }
 201              }
 202            }
 203          } else if (value) {
 204            attrs.push({
 205              name: name,
 206              value: value
 207            });
 208            attrs.map[name] = value;
 209          }
 210        }
 211      };
 212      var normalizeHtml = function (html) {
 213        var writer = global$6();
 214        var parser = global$3(writer);
 215        parser.parse(html);
 216        return writer.getContent();
 217      };
 218      var updateHtmlSax = function (html, data, updateAll) {
 219        var writer = global$6();
 220        var sourceCount = 0;
 221        var hasImage;
 222        global$3({
 223          validate: false,
 224          allow_conditional_comments: true,
 225          special: 'script,noscript',
 226          comment: function (text) {
 227            writer.comment(text);
 228          },
 229          cdata: function (text) {
 230            writer.cdata(text);
 231          },
 232          text: function (text, raw) {
 233            writer.text(text, raw);
 234          },
 235          start: function (name, attrs, empty) {
 236            switch (name) {
 237            case 'video':
 238            case 'object':
 239            case 'embed':
 240            case 'img':
 241            case 'iframe':
 242              if (data.height !== undefined && data.width !== undefined) {
 243                setAttributes(attrs, {
 244                  width: data.width,
 245                  height: data.height
 246                });
 247              }
 248              break;
 249            }
 250            if (updateAll) {
 251              switch (name) {
 252              case 'video':
 253                setAttributes(attrs, {
 254                  poster: data.poster,
 255                  src: ''
 256                });
 257                if (data.source2) {
 258                  setAttributes(attrs, { src: '' });
 259                }
 260                break;
 261              case 'iframe':
 262                setAttributes(attrs, { src: data.source1 });
 263                break;
 264              case 'source':
 265                sourceCount++;
 266                if (sourceCount <= 2) {
 267                  setAttributes(attrs, {
 268                    src: data['source' + sourceCount],
 269                    type: data['source' + sourceCount + 'mime']
 270                  });
 271                  if (!data['source' + sourceCount]) {
 272                    return;
 273                  }
 274                }
 275                break;
 276              case 'img':
 277                if (!data.poster) {
 278                  return;
 279                }
 280                hasImage = true;
 281                break;
 282              }
 283            }
 284            writer.start(name, attrs, empty);
 285          },
 286          end: function (name) {
 287            if (name === 'video' && updateAll) {
 288              for (var index = 1; index <= 2; index++) {
 289                if (data['source' + index]) {
 290                  var attrs = [];
 291                  attrs.map = {};
 292                  if (sourceCount < index) {
 293                    setAttributes(attrs, {
 294                      src: data['source' + index],
 295                      type: data['source' + index + 'mime']
 296                    });
 297                    writer.start('source', attrs, true);
 298                  }
 299                }
 300              }
 301            }
 302            if (data.poster && name === 'object' && updateAll && !hasImage) {
 303              var imgAttrs = [];
 304              imgAttrs.map = {};
 305              setAttributes(imgAttrs, {
 306                src: data.poster,
 307                width: data.width,
 308                height: data.height
 309              });
 310              writer.start('img', imgAttrs, true);
 311            }
 312            writer.end(name);
 313          }
 314        }, global$7({})).parse(html);
 315        return writer.getContent();
 316      };
 317      var isEphoxEmbed$1 = function (html) {
 318        var fragment = DOM$1.createFragment(html);
 319        return DOM$1.getAttrib(fragment.firstChild, 'data-ephox-embed-iri') !== '';
 320      };
 321      var updateEphoxEmbed = function (html, data) {
 322        var fragment = DOM$1.createFragment(html);
 323        var div = fragment.firstChild;
 324        Size.setMaxWidth(div, data.width);
 325        Size.setMaxHeight(div, data.height);
 326        return normalizeHtml(div.outerHTML);
 327      };
 328      var updateHtml = function (html, data, updateAll) {
 329        return isEphoxEmbed$1(html) ? updateEphoxEmbed(html, data) : updateHtmlSax(html, data, updateAll);
 330      };
 331      var UpdateHtml = { updateHtml: updateHtml };
 332  
 333      var urlPatterns = [
 334        {
 335          regex: /youtu\.be\/([\w\-_\?&=.]+)/i,
 336          type: 'iframe',
 337          w: 560,
 338          h: 314,
 339          url: '//www.youtube.com/embed/$1',
 340          allowFullscreen: true
 341        },
 342        {
 343          regex: /youtube\.com(.+)v=([^&]+)(&([a-z0-9&=\-_]+))?/i,
 344          type: 'iframe',
 345          w: 560,
 346          h: 314,
 347          url: '//www.youtube.com/embed/$2?$4',
 348          allowFullscreen: true
 349        },
 350        {
 351          regex: /youtube.com\/embed\/([a-z0-9\?&=\-_]+)/i,
 352          type: 'iframe',
 353          w: 560,
 354          h: 314,
 355          url: '//www.youtube.com/embed/$1',
 356          allowFullscreen: true
 357        },
 358        {
 359          regex: /vimeo\.com\/([0-9]+)/,
 360          type: 'iframe',
 361          w: 425,
 362          h: 350,
 363          url: '//player.vimeo.com/video/$1?title=0&byline=0&portrait=0&color=8dc7dc',
 364          allowFullscreen: true
 365        },
 366        {
 367          regex: /vimeo\.com\/(.*)\/([0-9]+)/,
 368          type: 'iframe',
 369          w: 425,
 370          h: 350,
 371          url: '//player.vimeo.com/video/$2?title=0&amp;byline=0',
 372          allowFullscreen: true
 373        },
 374        {
 375          regex: /maps\.google\.([a-z]{2,3})\/maps\/(.+)msid=(.+)/,
 376          type: 'iframe',
 377          w: 425,
 378          h: 350,
 379          url: '//maps.google.com/maps/ms?msid=$2&output=embed"',
 380          allowFullscreen: false
 381        },
 382        {
 383          regex: /dailymotion\.com\/video\/([^_]+)/,
 384          type: 'iframe',
 385          w: 480,
 386          h: 270,
 387          url: '//www.dailymotion.com/embed/video/$1',
 388          allowFullscreen: true
 389        },
 390        {
 391          regex: /dai\.ly\/([^_]+)/,
 392          type: 'iframe',
 393          w: 480,
 394          h: 270,
 395          url: '//www.dailymotion.com/embed/video/$1',
 396          allowFullscreen: true
 397        }
 398      ];
 399      var getUrl = function (pattern, url) {
 400        var match = pattern.regex.exec(url);
 401        var newUrl = pattern.url;
 402        var _loop_1 = function (i) {
 403          newUrl = newUrl.replace('$' + i, function () {
 404            return match[i] ? match[i] : '';
 405          });
 406        };
 407        for (var i = 0; i < match.length; i++) {
 408          _loop_1(i);
 409        }
 410        return newUrl.replace(/\?$/, '');
 411      };
 412      var matchPattern = function (url) {
 413        var pattern = urlPatterns.filter(function (pattern) {
 414          return pattern.regex.test(url);
 415        });
 416        if (pattern.length > 0) {
 417          return global$2.extend({}, pattern[0], { url: getUrl(pattern[0], url) });
 418        } else {
 419          return null;
 420        }
 421      };
 422  
 423      var getIframeHtml = function (data) {
 424        var allowFullscreen = data.allowFullscreen ? ' allowFullscreen="1"' : '';
 425        return '<iframe src="' + data.source1 + '" width="' + data.width + '" height="' + data.height + '"' + allowFullscreen + '></iframe>';
 426      };
 427      var getFlashHtml = function (data) {
 428        var html = '<object data="' + data.source1 + '" width="' + data.width + '" height="' + data.height + '" type="application/x-shockwave-flash">';
 429        if (data.poster) {
 430          html += '<img src="' + data.poster + '" width="' + data.width + '" height="' + data.height + '" />';
 431        }
 432        html += '</object>';
 433        return html;
 434      };
 435      var getAudioHtml = function (data, audioTemplateCallback) {
 436        if (audioTemplateCallback) {
 437          return audioTemplateCallback(data);
 438        } else {
 439          return '<audio controls="controls" src="' + data.source1 + '">' + (data.source2 ? '\n<source src="' + data.source2 + '"' + (data.source2mime ? ' type="' + data.source2mime + '"' : '') + ' />\n' : '') + '</audio>';
 440        }
 441      };
 442      var getVideoHtml = function (data, videoTemplateCallback) {
 443        if (videoTemplateCallback) {
 444          return videoTemplateCallback(data);
 445        } else {
 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        }
 448      };
 449      var getScriptHtml = function (data) {
 450        return '<script src="' + data.source1 + '"></script>';
 451      };
 452      var dataToHtml = function (editor, dataIn) {
 453        var data = global$2.extend({}, dataIn);
 454        if (!data.source1) {
 455          global$2.extend(data, HtmlToData.htmlToData(Settings.getScripts(editor), data.embed));
 456          if (!data.source1) {
 457            return '';
 458          }
 459        }
 460        if (!data.source2) {
 461          data.source2 = '';
 462        }
 463        if (!data.poster) {
 464          data.poster = '';
 465        }
 466        data.source1 = editor.convertURL(data.source1, 'source');
 467        data.source2 = editor.convertURL(data.source2, 'source');
 468        data.source1mime = Mime.guess(data.source1);
 469        data.source2mime = Mime.guess(data.source2);
 470        data.poster = editor.convertURL(data.poster, 'poster');
 471        var pattern = matchPattern(data.source1);
 472        if (pattern) {
 473          data.source1 = pattern.url;
 474          data.type = pattern.type;
 475          data.allowFullscreen = pattern.allowFullscreen;
 476          data.width = data.width || pattern.w;
 477          data.height = data.height || pattern.h;
 478        }
 479        if (data.embed) {
 480          return UpdateHtml.updateHtml(data.embed, data, true);
 481        } else {
 482          var videoScript = VideoScript.getVideoScriptMatch(Settings.getScripts(editor), data.source1);
 483          if (videoScript) {
 484            data.type = 'script';
 485            data.width = videoScript.width;
 486            data.height = videoScript.height;
 487          }
 488          var audioTemplateCallback = Settings.getAudioTemplateCallback(editor);
 489          var videoTemplateCallback = Settings.getVideoTemplateCallback(editor);
 490          data.width = data.width || 300;
 491          data.height = data.height || 150;
 492          global$2.each(data, function (value, key) {
 493            data[key] = editor.dom.encode(value);
 494          });
 495          if (data.type === 'iframe') {
 496            return getIframeHtml(data);
 497          } else if (data.source1mime === 'application/x-shockwave-flash') {
 498            return getFlashHtml(data);
 499          } else if (data.source1mime.indexOf('audio') !== -1) {
 500            return getAudioHtml(data, audioTemplateCallback);
 501          } else if (data.type === 'script') {
 502            return getScriptHtml(data);
 503          } else {
 504            return getVideoHtml(data, videoTemplateCallback);
 505          }
 506        }
 507      };
 508      var DataToHtml = { dataToHtml: dataToHtml };
 509  
 510      var cache = {};
 511      var embedPromise = function (data, dataToHtml, handler) {
 512        return new global$5(function (res, rej) {
 513          var wrappedResolve = function (response) {
 514            if (response.html) {
 515              cache[data.source1] = response;
 516            }
 517            return res({
 518              url: data.source1,
 519              html: response.html ? response.html : dataToHtml(data)
 520            });
 521          };
 522          if (cache[data.source1]) {
 523            wrappedResolve(cache[data.source1]);
 524          } else {
 525            handler({ url: data.source1 }, wrappedResolve, rej);
 526          }
 527        });
 528      };
 529      var defaultPromise = function (data, dataToHtml) {
 530        return new global$5(function (res) {
 531          res({
 532            html: dataToHtml(data),
 533            url: data.source1
 534          });
 535        });
 536      };
 537      var loadedData = function (editor) {
 538        return function (data) {
 539          return DataToHtml.dataToHtml(editor, data);
 540        };
 541      };
 542      var getEmbedHtml = function (editor, data) {
 543        var embedHandler = Settings.getUrlResolver(editor);
 544        return embedHandler ? embedPromise(data, loadedData(editor), embedHandler) : defaultPromise(data, loadedData(editor));
 545      };
 546      var isCached = function (url) {
 547        return cache.hasOwnProperty(url);
 548      };
 549      var Service = {
 550        getEmbedHtml: getEmbedHtml,
 551        isCached: isCached
 552      };
 553  
 554      var doSyncSize = function (widthCtrl, heightCtrl) {
 555        widthCtrl.state.set('oldVal', widthCtrl.value());
 556        heightCtrl.state.set('oldVal', heightCtrl.value());
 557      };
 558      var doSizeControls = function (win, f) {
 559        var widthCtrl = win.find('#width')[0];
 560        var heightCtrl = win.find('#height')[0];
 561        var constrained = win.find('#constrain')[0];
 562        if (widthCtrl && heightCtrl && constrained) {
 563          f(widthCtrl, heightCtrl, constrained.checked());
 564        }
 565      };
 566      var doUpdateSize = function (widthCtrl, heightCtrl, isContrained) {
 567        var oldWidth = widthCtrl.state.get('oldVal');
 568        var oldHeight = heightCtrl.state.get('oldVal');
 569        var newWidth = widthCtrl.value();
 570        var newHeight = heightCtrl.value();
 571        if (isContrained && oldWidth && oldHeight && newWidth && newHeight) {
 572          if (newWidth !== oldWidth) {
 573            newHeight = Math.round(newWidth / oldWidth * newHeight);
 574            if (!isNaN(newHeight)) {
 575              heightCtrl.value(newHeight);
 576            }
 577          } else {
 578            newWidth = Math.round(newHeight / oldHeight * newWidth);
 579            if (!isNaN(newWidth)) {
 580              widthCtrl.value(newWidth);
 581            }
 582          }
 583        }
 584        doSyncSize(widthCtrl, heightCtrl);
 585      };
 586      var syncSize = function (win) {
 587        doSizeControls(win, doSyncSize);
 588      };
 589      var updateSize = function (win) {
 590        doSizeControls(win, doUpdateSize);
 591      };
 592      var createUi = function (onChange) {
 593        var recalcSize = function () {
 594          onChange(function (win) {
 595            updateSize(win);
 596          });
 597        };
 598        return {
 599          type: 'container',
 600          label: 'Dimensions',
 601          layout: 'flex',
 602          align: 'center',
 603          spacing: 5,
 604          items: [
 605            {
 606              name: 'width',
 607              type: 'textbox',
 608              maxLength: 5,
 609              size: 5,
 610              onchange: recalcSize,
 611              ariaLabel: 'Width'
 612            },
 613            {
 614              type: 'label',
 615              text: 'x'
 616            },
 617            {
 618              name: 'height',
 619              type: 'textbox',
 620              maxLength: 5,
 621              size: 5,
 622              onchange: recalcSize,
 623              ariaLabel: 'Height'
 624            },
 625            {
 626              name: 'constrain',
 627              type: 'checkbox',
 628              checked: true,
 629              text: 'Constrain proportions'
 630            }
 631          ]
 632        };
 633      };
 634      var SizeManager = {
 635        createUi: createUi,
 636        syncSize: syncSize,
 637        updateSize: updateSize
 638      };
 639  
 640      var embedChange = global$1.ie && global$1.ie <= 8 ? 'onChange' : 'onInput';
 641      var handleError = function (editor) {
 642        return function (error) {
 643          var errorMessage = error && error.msg ? 'Media embed handler error: ' + error.msg : 'Media embed handler threw unknown error.';
 644          editor.notificationManager.open({
 645            type: 'error',
 646            text: errorMessage
 647          });
 648        };
 649      };
 650      var getData = function (editor) {
 651        var element = editor.selection.getNode();
 652        var dataEmbed = element.getAttribute('data-ephox-embed-iri');
 653        if (dataEmbed) {
 654          return {
 655            'source1': dataEmbed,
 656            'data-ephox-embed-iri': dataEmbed,
 657            'width': Size.getMaxWidth(element),
 658            'height': Size.getMaxHeight(element)
 659          };
 660        }
 661        return element.getAttribute('data-mce-object') ? HtmlToData.htmlToData(Settings.getScripts(editor), editor.serializer.serialize(element, { selection: true })) : {};
 662      };
 663      var getSource = function (editor) {
 664        var elm = editor.selection.getNode();
 665        if (elm.getAttribute('data-mce-object') || elm.getAttribute('data-ephox-embed-iri')) {
 666          return editor.selection.getContent();
 667        }
 668      };
 669      var addEmbedHtml = function (win, editor) {
 670        return function (response) {
 671          var html = response.html;
 672          var embed = win.find('#embed')[0];
 673          var data = global$2.extend(HtmlToData.htmlToData(Settings.getScripts(editor), html), { source1: response.url });
 674          win.fromJSON(data);
 675          if (embed) {
 676            embed.value(html);
 677            SizeManager.updateSize(win);
 678          }
 679        };
 680      };
 681      var selectPlaceholder = function (editor, beforeObjects) {
 682        var i;
 683        var y;
 684        var afterObjects = editor.dom.select('img[data-mce-object]');
 685        for (i = 0; i < beforeObjects.length; i++) {
 686          for (y = afterObjects.length - 1; y >= 0; y--) {
 687            if (beforeObjects[i] === afterObjects[y]) {
 688              afterObjects.splice(y, 1);
 689            }
 690          }
 691        }
 692        editor.selection.select(afterObjects[0]);
 693      };
 694      var handleInsert = function (editor, html) {
 695        var beforeObjects = editor.dom.select('img[data-mce-object]');
 696        editor.insertContent(html);
 697        selectPlaceholder(editor, beforeObjects);
 698        editor.nodeChanged();
 699      };
 700      var submitForm = function (win, editor) {
 701        var data = win.toJSON();
 702        data.embed = UpdateHtml.updateHtml(data.embed, data);
 703        if (data.embed && Service.isCached(data.source1)) {
 704          handleInsert(editor, data.embed);
 705        } else {
 706          Service.getEmbedHtml(editor, data).then(function (response) {
 707            handleInsert(editor, response.html);
 708          }).catch(handleError(editor));
 709        }
 710      };
 711      var populateMeta = function (win, meta) {
 712        global$2.each(meta, function (value, key) {
 713          win.find('#' + key).value(value);
 714        });
 715      };
 716      var showDialog = function (editor) {
 717        var win;
 718        var data;
 719        var generalFormItems = [{
 720            name: 'source1',
 721            type: 'filepicker',
 722            filetype: 'media',
 723            size: 40,
 724            autofocus: true,
 725            label: 'Source',
 726            onpaste: function () {
 727              setTimeout(function () {
 728                Service.getEmbedHtml(editor, win.toJSON()).then(addEmbedHtml(win, editor)).catch(handleError(editor));
 729              }, 1);
 730            },
 731            onchange: function (e) {
 732              Service.getEmbedHtml(editor, win.toJSON()).then(addEmbedHtml(win, editor)).catch(handleError(editor));
 733              populateMeta(win, e.meta);
 734            },
 735            onbeforecall: function (e) {
 736              e.meta = win.toJSON();
 737            }
 738          }];
 739        var advancedFormItems = [];
 740        var reserialise = function (update) {
 741          update(win);
 742          data = win.toJSON();
 743          win.find('#embed').value(UpdateHtml.updateHtml(data.embed, data));
 744        };
 745        if (Settings.hasAltSource(editor)) {
 746          advancedFormItems.push({
 747            name: 'source2',
 748            type: 'filepicker',
 749            filetype: 'media',
 750            size: 40,
 751            label: 'Alternative source'
 752          });
 753        }
 754        if (Settings.hasPoster(editor)) {
 755          advancedFormItems.push({
 756            name: 'poster',
 757            type: 'filepicker',
 758            filetype: 'image',
 759            size: 40,
 760            label: 'Poster'
 761          });
 762        }
 763        if (Settings.hasDimensions(editor)) {
 764          var control = SizeManager.createUi(reserialise);
 765          generalFormItems.push(control);
 766        }
 767        data = getData(editor);
 768        var embedTextBox = {
 769          id: 'mcemediasource',
 770          type: 'textbox',
 771          flex: 1,
 772          name: 'embed',
 773          value: getSource(editor),
 774          multiline: true,
 775          rows: 5,
 776          label: 'Source'
 777        };
 778        var updateValueOnChange = function () {
 779          data = global$2.extend({}, HtmlToData.htmlToData(Settings.getScripts(editor), this.value()));
 780          this.parent().parent().fromJSON(data);
 781        };
 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            SizeManager.updateSize(win);
 821            submitForm(win, editor);
 822          }
 823        });
 824        SizeManager.syncSize(win);
 825      };
 826      var Dialog = { showDialog: showDialog };
 827  
 828      var get = function (editor) {
 829        var showDialog = function () {
 830          Dialog.showDialog(editor);
 831        };
 832        return { showDialog: showDialog };
 833      };
 834      var Api = { get: get };
 835  
 836      var register = function (editor) {
 837        var showDialog = function () {
 838          Dialog.showDialog(editor);
 839        };
 840        editor.addCommand('mceMedia', showDialog);
 841      };
 842      var Commands = { register: register };
 843  
 844      var global$8 = tinymce.util.Tools.resolve('tinymce.html.Node');
 845  
 846      var sanitize = function (editor, html) {
 847        if (Settings.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 Sanitize = { 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(Sanitize.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 = VideoScript.getVideoScriptMatch(Settings.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' && Settings.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 Nodes = {
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', Nodes.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 = Sanitize.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 FilterContent = { 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 ResolveName = { 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(UpdateHtml.updateHtml(html, {
1123                width: e.width,
1124                height: e.height
1125              })));
1126            }
1127          }
1128        });
1129      };
1130      var Selection = { 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 Buttons = { register: register$1 };
1151  
1152      global.add('media', function (editor) {
1153        Commands.register(editor);
1154        Buttons.register(editor);
1155        ResolveName.setup(editor);
1156        FilterContent.setup(editor);
1157        Selection.setup(editor);
1158        return Api.get(editor);
1159      });
1160      function Plugin () {
1161      }
1162  
1163      return Plugin;
1164  
1165  }());
1166  })();


Generated: Wed Sep 18 01:00:03 2019 Cross-referenced by PHPXref 0.7.1