[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

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 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&amp;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  })();


Generated : Sat Dec 21 08:20:01 2024 Cross-referenced by PHPXref