[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

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

   1  (function () {
   2  var image = (function (domGlobals) {
   3      'use strict';
   4  
   5      var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
   6  
   7      var hasDimensions = function (editor) {
   8        return editor.settings.image_dimensions === false ? false : true;
   9      };
  10      var hasAdvTab = function (editor) {
  11        return editor.settings.image_advtab === true ? true : false;
  12      };
  13      var getPrependUrl = function (editor) {
  14        return editor.getParam('image_prepend_url', '');
  15      };
  16      var getClassList = function (editor) {
  17        return editor.getParam('image_class_list');
  18      };
  19      var hasDescription = function (editor) {
  20        return editor.settings.image_description === false ? false : true;
  21      };
  22      var hasImageTitle = function (editor) {
  23        return editor.settings.image_title === true ? true : false;
  24      };
  25      var hasImageCaption = function (editor) {
  26        return editor.settings.image_caption === true ? true : false;
  27      };
  28      var getImageList = function (editor) {
  29        return editor.getParam('image_list', false);
  30      };
  31      var hasUploadUrl = function (editor) {
  32        return editor.getParam('images_upload_url', false);
  33      };
  34      var hasUploadHandler = function (editor) {
  35        return editor.getParam('images_upload_handler', false);
  36      };
  37      var getUploadUrl = function (editor) {
  38        return editor.getParam('images_upload_url');
  39      };
  40      var getUploadHandler = function (editor) {
  41        return editor.getParam('images_upload_handler');
  42      };
  43      var getUploadBasePath = function (editor) {
  44        return editor.getParam('images_upload_base_path');
  45      };
  46      var getUploadCredentials = function (editor) {
  47        return editor.getParam('images_upload_credentials');
  48      };
  49      var Settings = {
  50        hasDimensions: hasDimensions,
  51        hasAdvTab: hasAdvTab,
  52        getPrependUrl: getPrependUrl,
  53        getClassList: getClassList,
  54        hasDescription: hasDescription,
  55        hasImageTitle: hasImageTitle,
  56        hasImageCaption: hasImageCaption,
  57        getImageList: getImageList,
  58        hasUploadUrl: hasUploadUrl,
  59        hasUploadHandler: hasUploadHandler,
  60        getUploadUrl: getUploadUrl,
  61        getUploadHandler: getUploadHandler,
  62        getUploadBasePath: getUploadBasePath,
  63        getUploadCredentials: getUploadCredentials
  64      };
  65  
  66      var Global = typeof domGlobals.window !== 'undefined' ? domGlobals.window : Function('return this;')();
  67  
  68      var path = function (parts, scope) {
  69        var o = scope !== undefined && scope !== null ? scope : Global;
  70        for (var i = 0; i < parts.length && o !== undefined && o !== null; ++i) {
  71          o = o[parts[i]];
  72        }
  73        return o;
  74      };
  75      var resolve = function (p, scope) {
  76        var parts = p.split('.');
  77        return path(parts, scope);
  78      };
  79  
  80      var unsafe = function (name, scope) {
  81        return resolve(name, scope);
  82      };
  83      var getOrDie = function (name, scope) {
  84        var actual = unsafe(name, scope);
  85        if (actual === undefined || actual === null) {
  86          throw new Error(name + ' not available on this browser');
  87        }
  88        return actual;
  89      };
  90      var Global$1 = { getOrDie: getOrDie };
  91  
  92      function FileReader () {
  93        var f = Global$1.getOrDie('FileReader');
  94        return new f();
  95      }
  96  
  97      var global$1 = tinymce.util.Tools.resolve('tinymce.util.Promise');
  98  
  99      var global$2 = tinymce.util.Tools.resolve('tinymce.util.Tools');
 100  
 101      var global$3 = tinymce.util.Tools.resolve('tinymce.util.XHR');
 102  
 103      var parseIntAndGetMax = function (val1, val2) {
 104        return Math.max(parseInt(val1, 10), parseInt(val2, 10));
 105      };
 106      var getImageSize = function (url, callback) {
 107        var img = domGlobals.document.createElement('img');
 108        function done(width, height) {
 109          if (img.parentNode) {
 110            img.parentNode.removeChild(img);
 111          }
 112          callback({
 113            width: width,
 114            height: height
 115          });
 116        }
 117        img.onload = function () {
 118          var width = parseIntAndGetMax(img.width, img.clientWidth);
 119          var height = parseIntAndGetMax(img.height, img.clientHeight);
 120          done(width, height);
 121        };
 122        img.onerror = function () {
 123          done(0, 0);
 124        };
 125        var style = img.style;
 126        style.visibility = 'hidden';
 127        style.position = 'fixed';
 128        style.bottom = style.left = '0px';
 129        style.width = style.height = 'auto';
 130        domGlobals.document.body.appendChild(img);
 131        img.src = url;
 132      };
 133      var buildListItems = function (inputList, itemCallback, startItems) {
 134        function appendItems(values, output) {
 135          output = output || [];
 136          global$2.each(values, function (item) {
 137            var menuItem = { text: item.text || item.title };
 138            if (item.menu) {
 139              menuItem.menu = appendItems(item.menu);
 140            } else {
 141              menuItem.value = item.value;
 142              itemCallback(menuItem);
 143            }
 144            output.push(menuItem);
 145          });
 146          return output;
 147        }
 148        return appendItems(inputList, startItems || []);
 149      };
 150      var removePixelSuffix = function (value) {
 151        if (value) {
 152          value = value.replace(/px$/, '');
 153        }
 154        return value;
 155      };
 156      var addPixelSuffix = function (value) {
 157        if (value.length > 0 && /^[0-9]+$/.test(value)) {
 158          value += 'px';
 159        }
 160        return value;
 161      };
 162      var mergeMargins = function (css) {
 163        if (css.margin) {
 164          var splitMargin = css.margin.split(' ');
 165          switch (splitMargin.length) {
 166          case 1:
 167            css['margin-top'] = css['margin-top'] || splitMargin[0];
 168            css['margin-right'] = css['margin-right'] || splitMargin[0];
 169            css['margin-bottom'] = css['margin-bottom'] || splitMargin[0];
 170            css['margin-left'] = css['margin-left'] || splitMargin[0];
 171            break;
 172          case 2:
 173            css['margin-top'] = css['margin-top'] || splitMargin[0];
 174            css['margin-right'] = css['margin-right'] || splitMargin[1];
 175            css['margin-bottom'] = css['margin-bottom'] || splitMargin[0];
 176            css['margin-left'] = css['margin-left'] || splitMargin[1];
 177            break;
 178          case 3:
 179            css['margin-top'] = css['margin-top'] || splitMargin[0];
 180            css['margin-right'] = css['margin-right'] || splitMargin[1];
 181            css['margin-bottom'] = css['margin-bottom'] || splitMargin[2];
 182            css['margin-left'] = css['margin-left'] || splitMargin[1];
 183            break;
 184          case 4:
 185            css['margin-top'] = css['margin-top'] || splitMargin[0];
 186            css['margin-right'] = css['margin-right'] || splitMargin[1];
 187            css['margin-bottom'] = css['margin-bottom'] || splitMargin[2];
 188            css['margin-left'] = css['margin-left'] || splitMargin[3];
 189          }
 190          delete css.margin;
 191        }
 192        return css;
 193      };
 194      var createImageList = function (editor, callback) {
 195        var imageList = Settings.getImageList(editor);
 196        if (typeof imageList === 'string') {
 197          global$3.send({
 198            url: imageList,
 199            success: function (text) {
 200              callback(JSON.parse(text));
 201            }
 202          });
 203        } else if (typeof imageList === 'function') {
 204          imageList(callback);
 205        } else {
 206          callback(imageList);
 207        }
 208      };
 209      var waitLoadImage = function (editor, data, imgElm) {
 210        function selectImage() {
 211          imgElm.onload = imgElm.onerror = null;
 212          if (editor.selection) {
 213            editor.selection.select(imgElm);
 214            editor.nodeChanged();
 215          }
 216        }
 217        imgElm.onload = function () {
 218          if (!data.width && !data.height && Settings.hasDimensions(editor)) {
 219            editor.dom.setAttribs(imgElm, {
 220              width: imgElm.clientWidth,
 221              height: imgElm.clientHeight
 222            });
 223          }
 224          selectImage();
 225        };
 226        imgElm.onerror = selectImage;
 227      };
 228      var blobToDataUri = function (blob) {
 229        return new global$1(function (resolve, reject) {
 230          var reader = FileReader();
 231          reader.onload = function () {
 232            resolve(reader.result);
 233          };
 234          reader.onerror = function () {
 235            reject(reader.error.message);
 236          };
 237          reader.readAsDataURL(blob);
 238        });
 239      };
 240      var Utils = {
 241        getImageSize: getImageSize,
 242        buildListItems: buildListItems,
 243        removePixelSuffix: removePixelSuffix,
 244        addPixelSuffix: addPixelSuffix,
 245        mergeMargins: mergeMargins,
 246        createImageList: createImageList,
 247        waitLoadImage: waitLoadImage,
 248        blobToDataUri: blobToDataUri
 249      };
 250  
 251      var global$4 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils');
 252  
 253      var hasOwnProperty = Object.prototype.hasOwnProperty;
 254      var shallow = function (old, nu) {
 255        return nu;
 256      };
 257      var baseMerge = function (merger) {
 258        return function () {
 259          var objects = new Array(arguments.length);
 260          for (var i = 0; i < objects.length; i++) {
 261            objects[i] = arguments[i];
 262          }
 263          if (objects.length === 0) {
 264            throw new Error('Can\'t merge zero objects');
 265          }
 266          var ret = {};
 267          for (var j = 0; j < objects.length; j++) {
 268            var curObject = objects[j];
 269            for (var key in curObject) {
 270              if (hasOwnProperty.call(curObject, key)) {
 271                ret[key] = merger(ret[key], curObject[key]);
 272              }
 273            }
 274          }
 275          return ret;
 276        };
 277      };
 278      var merge = baseMerge(shallow);
 279  
 280      var DOM = global$4.DOM;
 281      var getHspace = function (image) {
 282        if (image.style.marginLeft && image.style.marginRight && image.style.marginLeft === image.style.marginRight) {
 283          return Utils.removePixelSuffix(image.style.marginLeft);
 284        } else {
 285          return '';
 286        }
 287      };
 288      var getVspace = function (image) {
 289        if (image.style.marginTop && image.style.marginBottom && image.style.marginTop === image.style.marginBottom) {
 290          return Utils.removePixelSuffix(image.style.marginTop);
 291        } else {
 292          return '';
 293        }
 294      };
 295      var getBorder = function (image) {
 296        if (image.style.borderWidth) {
 297          return Utils.removePixelSuffix(image.style.borderWidth);
 298        } else {
 299          return '';
 300        }
 301      };
 302      var getAttrib = function (image, name) {
 303        if (image.hasAttribute(name)) {
 304          return image.getAttribute(name);
 305        } else {
 306          return '';
 307        }
 308      };
 309      var getStyle = function (image, name) {
 310        return image.style[name] ? image.style[name] : '';
 311      };
 312      var hasCaption = function (image) {
 313        return image.parentNode !== null && image.parentNode.nodeName === 'FIGURE';
 314      };
 315      var setAttrib = function (image, name, value) {
 316        image.setAttribute(name, value);
 317      };
 318      var wrapInFigure = function (image) {
 319        var figureElm = DOM.create('figure', { class: 'image' });
 320        DOM.insertAfter(figureElm, image);
 321        figureElm.appendChild(image);
 322        figureElm.appendChild(DOM.create('figcaption', { contentEditable: true }, 'Caption'));
 323        figureElm.contentEditable = 'false';
 324      };
 325      var removeFigure = function (image) {
 326        var figureElm = image.parentNode;
 327        DOM.insertAfter(image, figureElm);
 328        DOM.remove(figureElm);
 329      };
 330      var toggleCaption = function (image) {
 331        if (hasCaption(image)) {
 332          removeFigure(image);
 333        } else {
 334          wrapInFigure(image);
 335        }
 336      };
 337      var normalizeStyle = function (image, normalizeCss) {
 338        var attrValue = image.getAttribute('style');
 339        var value = normalizeCss(attrValue !== null ? attrValue : '');
 340        if (value.length > 0) {
 341          image.setAttribute('style', value);
 342          image.setAttribute('data-mce-style', value);
 343        } else {
 344          image.removeAttribute('style');
 345        }
 346      };
 347      var setSize = function (name, normalizeCss) {
 348        return function (image, name, value) {
 349          if (image.style[name]) {
 350            image.style[name] = Utils.addPixelSuffix(value);
 351            normalizeStyle(image, normalizeCss);
 352          } else {
 353            setAttrib(image, name, value);
 354          }
 355        };
 356      };
 357      var getSize = function (image, name) {
 358        if (image.style[name]) {
 359          return Utils.removePixelSuffix(image.style[name]);
 360        } else {
 361          return getAttrib(image, name);
 362        }
 363      };
 364      var setHspace = function (image, value) {
 365        var pxValue = Utils.addPixelSuffix(value);
 366        image.style.marginLeft = pxValue;
 367        image.style.marginRight = pxValue;
 368      };
 369      var setVspace = function (image, value) {
 370        var pxValue = Utils.addPixelSuffix(value);
 371        image.style.marginTop = pxValue;
 372        image.style.marginBottom = pxValue;
 373      };
 374      var setBorder = function (image, value) {
 375        var pxValue = Utils.addPixelSuffix(value);
 376        image.style.borderWidth = pxValue;
 377      };
 378      var setBorderStyle = function (image, value) {
 379        image.style.borderStyle = value;
 380      };
 381      var getBorderStyle = function (image) {
 382        return getStyle(image, 'borderStyle');
 383      };
 384      var isFigure = function (elm) {
 385        return elm.nodeName === 'FIGURE';
 386      };
 387      var defaultData = function () {
 388        return {
 389          src: '',
 390          alt: '',
 391          title: '',
 392          width: '',
 393          height: '',
 394          class: '',
 395          style: '',
 396          caption: false,
 397          hspace: '',
 398          vspace: '',
 399          border: '',
 400          borderStyle: ''
 401        };
 402      };
 403      var getStyleValue = function (normalizeCss, data) {
 404        var image = domGlobals.document.createElement('img');
 405        setAttrib(image, 'style', data.style);
 406        if (getHspace(image) || data.hspace !== '') {
 407          setHspace(image, data.hspace);
 408        }
 409        if (getVspace(image) || data.vspace !== '') {
 410          setVspace(image, data.vspace);
 411        }
 412        if (getBorder(image) || data.border !== '') {
 413          setBorder(image, data.border);
 414        }
 415        if (getBorderStyle(image) || data.borderStyle !== '') {
 416          setBorderStyle(image, data.borderStyle);
 417        }
 418        return normalizeCss(image.getAttribute('style'));
 419      };
 420      var create = function (normalizeCss, data) {
 421        var image = domGlobals.document.createElement('img');
 422        write(normalizeCss, merge(data, { caption: false }), image);
 423        setAttrib(image, 'alt', data.alt);
 424        if (data.caption) {
 425          var figure = DOM.create('figure', { class: 'image' });
 426          figure.appendChild(image);
 427          figure.appendChild(DOM.create('figcaption', { contentEditable: true }, 'Caption'));
 428          figure.contentEditable = 'false';
 429          return figure;
 430        } else {
 431          return image;
 432        }
 433      };
 434      var read = function (normalizeCss, image) {
 435        return {
 436          src: getAttrib(image, 'src'),
 437          alt: getAttrib(image, 'alt'),
 438          title: getAttrib(image, 'title'),
 439          width: getSize(image, 'width'),
 440          height: getSize(image, 'height'),
 441          class: getAttrib(image, 'class'),
 442          style: normalizeCss(getAttrib(image, 'style')),
 443          caption: hasCaption(image),
 444          hspace: getHspace(image),
 445          vspace: getVspace(image),
 446          border: getBorder(image),
 447          borderStyle: getStyle(image, 'borderStyle')
 448        };
 449      };
 450      var updateProp = function (image, oldData, newData, name, set) {
 451        if (newData[name] !== oldData[name]) {
 452          set(image, name, newData[name]);
 453        }
 454      };
 455      var normalized = function (set, normalizeCss) {
 456        return function (image, name, value) {
 457          set(image, value);
 458          normalizeStyle(image, normalizeCss);
 459        };
 460      };
 461      var write = function (normalizeCss, newData, image) {
 462        var oldData = read(normalizeCss, image);
 463        updateProp(image, oldData, newData, 'caption', function (image, _name, _value) {
 464          return toggleCaption(image);
 465        });
 466        updateProp(image, oldData, newData, 'src', setAttrib);
 467        updateProp(image, oldData, newData, 'alt', setAttrib);
 468        updateProp(image, oldData, newData, 'title', setAttrib);
 469        updateProp(image, oldData, newData, 'width', setSize('width', normalizeCss));
 470        updateProp(image, oldData, newData, 'height', setSize('height', normalizeCss));
 471        updateProp(image, oldData, newData, 'class', setAttrib);
 472        updateProp(image, oldData, newData, 'style', normalized(function (image, value) {
 473          return setAttrib(image, 'style', value);
 474        }, normalizeCss));
 475        updateProp(image, oldData, newData, 'hspace', normalized(setHspace, normalizeCss));
 476        updateProp(image, oldData, newData, 'vspace', normalized(setVspace, normalizeCss));
 477        updateProp(image, oldData, newData, 'border', normalized(setBorder, normalizeCss));
 478        updateProp(image, oldData, newData, 'borderStyle', normalized(setBorderStyle, normalizeCss));
 479      };
 480  
 481      var normalizeCss = function (editor, cssText) {
 482        var css = editor.dom.styles.parse(cssText);
 483        var mergedCss = Utils.mergeMargins(css);
 484        var compressed = editor.dom.styles.parse(editor.dom.styles.serialize(mergedCss));
 485        return editor.dom.styles.serialize(compressed);
 486      };
 487      var getSelectedImage = function (editor) {
 488        var imgElm = editor.selection.getNode();
 489        var figureElm = editor.dom.getParent(imgElm, 'figure.image');
 490        if (figureElm) {
 491          return editor.dom.select('img', figureElm)[0];
 492        }
 493        if (imgElm && (imgElm.nodeName !== 'IMG' || imgElm.getAttribute('data-mce-object') || imgElm.getAttribute('data-mce-placeholder'))) {
 494          return null;
 495        }
 496        return imgElm;
 497      };
 498      var splitTextBlock = function (editor, figure) {
 499        var dom = editor.dom;
 500        var textBlock = dom.getParent(figure.parentNode, function (node) {
 501          return editor.schema.getTextBlockElements()[node.nodeName];
 502        }, editor.getBody());
 503        if (textBlock) {
 504          return dom.split(textBlock, figure);
 505        } else {
 506          return figure;
 507        }
 508      };
 509      var readImageDataFromSelection = function (editor) {
 510        var image = getSelectedImage(editor);
 511        return image ? read(function (css) {
 512          return normalizeCss(editor, css);
 513        }, image) : defaultData();
 514      };
 515      var insertImageAtCaret = function (editor, data) {
 516        var elm = create(function (css) {
 517          return normalizeCss(editor, css);
 518        }, data);
 519        editor.dom.setAttrib(elm, 'data-mce-id', '__mcenew');
 520        editor.focus();
 521        editor.selection.setContent(elm.outerHTML);
 522        var insertedElm = editor.dom.select('*[data-mce-id="__mcenew"]')[0];
 523        editor.dom.setAttrib(insertedElm, 'data-mce-id', null);
 524        if (isFigure(insertedElm)) {
 525          var figure = splitTextBlock(editor, insertedElm);
 526          editor.selection.select(figure);
 527        } else {
 528          editor.selection.select(insertedElm);
 529        }
 530      };
 531      var syncSrcAttr = function (editor, image) {
 532        editor.dom.setAttrib(image, 'src', image.getAttribute('src'));
 533      };
 534      var deleteImage = function (editor, image) {
 535        if (image) {
 536          var elm = editor.dom.is(image.parentNode, 'figure.image') ? image.parentNode : image;
 537          editor.dom.remove(elm);
 538          editor.focus();
 539          editor.nodeChanged();
 540          if (editor.dom.isEmpty(editor.getBody())) {
 541            editor.setContent('');
 542            editor.selection.setCursorLocation();
 543          }
 544        }
 545      };
 546      var writeImageDataToSelection = function (editor, data) {
 547        var image = getSelectedImage(editor);
 548        write(function (css) {
 549          return normalizeCss(editor, css);
 550        }, data, image);
 551        syncSrcAttr(editor, image);
 552        if (isFigure(image.parentNode)) {
 553          var figure = image.parentNode;
 554          splitTextBlock(editor, figure);
 555          editor.selection.select(image.parentNode);
 556        } else {
 557          editor.selection.select(image);
 558          Utils.waitLoadImage(editor, data, image);
 559        }
 560      };
 561      var insertOrUpdateImage = function (editor, data) {
 562        var image = getSelectedImage(editor);
 563        if (image) {
 564          if (data.src) {
 565            writeImageDataToSelection(editor, data);
 566          } else {
 567            deleteImage(editor, image);
 568          }
 569        } else if (data.src) {
 570          insertImageAtCaret(editor, data);
 571        }
 572      };
 573  
 574      var updateVSpaceHSpaceBorder = function (editor) {
 575        return function (evt) {
 576          var dom = editor.dom;
 577          var rootControl = evt.control.rootControl;
 578          if (!Settings.hasAdvTab(editor)) {
 579            return;
 580          }
 581          var data = rootControl.toJSON();
 582          var css = dom.parseStyle(data.style);
 583          rootControl.find('#vspace').value('');
 584          rootControl.find('#hspace').value('');
 585          css = Utils.mergeMargins(css);
 586          if (css['margin-top'] && css['margin-bottom'] || css['margin-right'] && css['margin-left']) {
 587            if (css['margin-top'] === css['margin-bottom']) {
 588              rootControl.find('#vspace').value(Utils.removePixelSuffix(css['margin-top']));
 589            } else {
 590              rootControl.find('#vspace').value('');
 591            }
 592            if (css['margin-right'] === css['margin-left']) {
 593              rootControl.find('#hspace').value(Utils.removePixelSuffix(css['margin-right']));
 594            } else {
 595              rootControl.find('#hspace').value('');
 596            }
 597          }
 598          if (css['border-width']) {
 599            rootControl.find('#border').value(Utils.removePixelSuffix(css['border-width']));
 600          } else {
 601            rootControl.find('#border').value('');
 602          }
 603          if (css['border-style']) {
 604            rootControl.find('#borderStyle').value(css['border-style']);
 605          } else {
 606            rootControl.find('#borderStyle').value('');
 607          }
 608          rootControl.find('#style').value(dom.serializeStyle(dom.parseStyle(dom.serializeStyle(css))));
 609        };
 610      };
 611      var updateStyle = function (editor, win) {
 612        win.find('#style').each(function (ctrl) {
 613          var value = getStyleValue(function (css) {
 614            return normalizeCss(editor, css);
 615          }, merge(defaultData(), win.toJSON()));
 616          ctrl.value(value);
 617        });
 618      };
 619      var makeTab = function (editor) {
 620        return {
 621          title: 'Advanced',
 622          type: 'form',
 623          pack: 'start',
 624          items: [
 625            {
 626              label: 'Style',
 627              name: 'style',
 628              type: 'textbox',
 629              onchange: updateVSpaceHSpaceBorder(editor)
 630            },
 631            {
 632              type: 'form',
 633              layout: 'grid',
 634              packV: 'start',
 635              columns: 2,
 636              padding: 0,
 637              defaults: {
 638                type: 'textbox',
 639                maxWidth: 50,
 640                onchange: function (evt) {
 641                  updateStyle(editor, evt.control.rootControl);
 642                }
 643              },
 644              items: [
 645                {
 646                  label: 'Vertical space',
 647                  name: 'vspace'
 648                },
 649                {
 650                  label: 'Border width',
 651                  name: 'border'
 652                },
 653                {
 654                  label: 'Horizontal space',
 655                  name: 'hspace'
 656                },
 657                {
 658                  label: 'Border style',
 659                  type: 'listbox',
 660                  name: 'borderStyle',
 661                  width: 90,
 662                  maxWidth: 90,
 663                  onselect: function (evt) {
 664                    updateStyle(editor, evt.control.rootControl);
 665                  },
 666                  values: [
 667                    {
 668                      text: 'Select...',
 669                      value: ''
 670                    },
 671                    {
 672                      text: 'Solid',
 673                      value: 'solid'
 674                    },
 675                    {
 676                      text: 'Dotted',
 677                      value: 'dotted'
 678                    },
 679                    {
 680                      text: 'Dashed',
 681                      value: 'dashed'
 682                    },
 683                    {
 684                      text: 'Double',
 685                      value: 'double'
 686                    },
 687                    {
 688                      text: 'Groove',
 689                      value: 'groove'
 690                    },
 691                    {
 692                      text: 'Ridge',
 693                      value: 'ridge'
 694                    },
 695                    {
 696                      text: 'Inset',
 697                      value: 'inset'
 698                    },
 699                    {
 700                      text: 'Outset',
 701                      value: 'outset'
 702                    },
 703                    {
 704                      text: 'None',
 705                      value: 'none'
 706                    },
 707                    {
 708                      text: 'Hidden',
 709                      value: 'hidden'
 710                    }
 711                  ]
 712                }
 713              ]
 714            }
 715          ]
 716        };
 717      };
 718      var AdvTab = { makeTab: makeTab };
 719  
 720      var doSyncSize = function (widthCtrl, heightCtrl) {
 721        widthCtrl.state.set('oldVal', widthCtrl.value());
 722        heightCtrl.state.set('oldVal', heightCtrl.value());
 723      };
 724      var doSizeControls = function (win, f) {
 725        var widthCtrl = win.find('#width')[0];
 726        var heightCtrl = win.find('#height')[0];
 727        var constrained = win.find('#constrain')[0];
 728        if (widthCtrl && heightCtrl && constrained) {
 729          f(widthCtrl, heightCtrl, constrained.checked());
 730        }
 731      };
 732      var doUpdateSize = function (widthCtrl, heightCtrl, isContrained) {
 733        var oldWidth = widthCtrl.state.get('oldVal');
 734        var oldHeight = heightCtrl.state.get('oldVal');
 735        var newWidth = widthCtrl.value();
 736        var newHeight = heightCtrl.value();
 737        if (isContrained && oldWidth && oldHeight && newWidth && newHeight) {
 738          if (newWidth !== oldWidth) {
 739            newHeight = Math.round(newWidth / oldWidth * newHeight);
 740            if (!isNaN(newHeight)) {
 741              heightCtrl.value(newHeight);
 742            }
 743          } else {
 744            newWidth = Math.round(newHeight / oldHeight * newWidth);
 745            if (!isNaN(newWidth)) {
 746              widthCtrl.value(newWidth);
 747            }
 748          }
 749        }
 750        doSyncSize(widthCtrl, heightCtrl);
 751      };
 752      var syncSize = function (win) {
 753        doSizeControls(win, doSyncSize);
 754      };
 755      var updateSize = function (win) {
 756        doSizeControls(win, doUpdateSize);
 757      };
 758      var createUi = function () {
 759        var recalcSize = function (evt) {
 760          updateSize(evt.control.rootControl);
 761        };
 762        return {
 763          type: 'container',
 764          label: 'Dimensions',
 765          layout: 'flex',
 766          align: 'center',
 767          spacing: 5,
 768          items: [
 769            {
 770              name: 'width',
 771              type: 'textbox',
 772              maxLength: 5,
 773              size: 5,
 774              onchange: recalcSize,
 775              ariaLabel: 'Width'
 776            },
 777            {
 778              type: 'label',
 779              text: 'x'
 780            },
 781            {
 782              name: 'height',
 783              type: 'textbox',
 784              maxLength: 5,
 785              size: 5,
 786              onchange: recalcSize,
 787              ariaLabel: 'Height'
 788            },
 789            {
 790              name: 'constrain',
 791              type: 'checkbox',
 792              checked: true,
 793              text: 'Constrain proportions'
 794            }
 795          ]
 796        };
 797      };
 798      var SizeManager = {
 799        createUi: createUi,
 800        syncSize: syncSize,
 801        updateSize: updateSize
 802      };
 803  
 804      var onSrcChange = function (evt, editor) {
 805        var srcURL, prependURL, absoluteURLPattern;
 806        var meta = evt.meta || {};
 807        var control = evt.control;
 808        var rootControl = control.rootControl;
 809        var imageListCtrl = rootControl.find('#image-list')[0];
 810        if (imageListCtrl) {
 811          imageListCtrl.value(editor.convertURL(control.value(), 'src'));
 812        }
 813        global$2.each(meta, function (value, key) {
 814          rootControl.find('#' + key).value(value);
 815        });
 816        if (!meta.width && !meta.height) {
 817          srcURL = editor.convertURL(control.value(), 'src');
 818          prependURL = Settings.getPrependUrl(editor);
 819          absoluteURLPattern = new RegExp('^(?:[a-z]+:)?//', 'i');
 820          if (prependURL && !absoluteURLPattern.test(srcURL) && srcURL.substring(0, prependURL.length) !== prependURL) {
 821            srcURL = prependURL + srcURL;
 822          }
 823          control.value(srcURL);
 824          Utils.getImageSize(editor.documentBaseURI.toAbsolute(control.value()), function (data) {
 825            if (data.width && data.height && Settings.hasDimensions(editor)) {
 826              rootControl.find('#width').value(data.width);
 827              rootControl.find('#height').value(data.height);
 828              SizeManager.syncSize(rootControl);
 829            }
 830          });
 831        }
 832      };
 833      var onBeforeCall = function (evt) {
 834        evt.meta = evt.control.rootControl.toJSON();
 835      };
 836      var getGeneralItems = function (editor, imageListCtrl) {
 837        var generalFormItems = [
 838          {
 839            name: 'src',
 840            type: 'filepicker',
 841            filetype: 'image',
 842            label: 'Source',
 843            autofocus: true,
 844            onchange: function (evt) {
 845              onSrcChange(evt, editor);
 846            },
 847            onbeforecall: onBeforeCall
 848          },
 849          imageListCtrl
 850        ];
 851        if (Settings.hasDescription(editor)) {
 852          generalFormItems.push({
 853            name: 'alt',
 854            type: 'textbox',
 855            label: 'Image description'
 856          });
 857        }
 858        if (Settings.hasImageTitle(editor)) {
 859          generalFormItems.push({
 860            name: 'title',
 861            type: 'textbox',
 862            label: 'Image Title'
 863          });
 864        }
 865        if (Settings.hasDimensions(editor)) {
 866          generalFormItems.push(SizeManager.createUi());
 867        }
 868        if (Settings.getClassList(editor)) {
 869          generalFormItems.push({
 870            name: 'class',
 871            type: 'listbox',
 872            label: 'Class',
 873            values: Utils.buildListItems(Settings.getClassList(editor), function (item) {
 874              if (item.value) {
 875                item.textStyle = function () {
 876                  return editor.formatter.getCssText({
 877                    inline: 'img',
 878                    classes: [item.value]
 879                  });
 880                };
 881              }
 882            })
 883          });
 884        }
 885        if (Settings.hasImageCaption(editor)) {
 886          generalFormItems.push({
 887            name: 'caption',
 888            type: 'checkbox',
 889            label: 'Caption'
 890          });
 891        }
 892        return generalFormItems;
 893      };
 894      var makeTab$1 = function (editor, imageListCtrl) {
 895        return {
 896          title: 'General',
 897          type: 'form',
 898          items: getGeneralItems(editor, imageListCtrl)
 899        };
 900      };
 901      var MainTab = {
 902        makeTab: makeTab$1,
 903        getGeneralItems: getGeneralItems
 904      };
 905  
 906      var url = function () {
 907        return Global$1.getOrDie('URL');
 908      };
 909      var createObjectURL = function (blob) {
 910        return url().createObjectURL(blob);
 911      };
 912      var revokeObjectURL = function (u) {
 913        url().revokeObjectURL(u);
 914      };
 915      var URL = {
 916        createObjectURL: createObjectURL,
 917        revokeObjectURL: revokeObjectURL
 918      };
 919  
 920      var global$5 = tinymce.util.Tools.resolve('tinymce.ui.Factory');
 921  
 922      function XMLHttpRequest () {
 923        var f = Global$1.getOrDie('XMLHttpRequest');
 924        return new f();
 925      }
 926  
 927      var noop = function () {
 928      };
 929      var pathJoin = function (path1, path2) {
 930        if (path1) {
 931          return path1.replace(/\/$/, '') + '/' + path2.replace(/^\//, '');
 932        }
 933        return path2;
 934      };
 935      function Uploader (settings) {
 936        var defaultHandler = function (blobInfo, success, failure, progress) {
 937          var xhr, formData;
 938          xhr = XMLHttpRequest();
 939          xhr.open('POST', settings.url);
 940          xhr.withCredentials = settings.credentials;
 941          xhr.upload.onprogress = function (e) {
 942            progress(e.loaded / e.total * 100);
 943          };
 944          xhr.onerror = function () {
 945            failure('Image upload failed due to a XHR Transport error. Code: ' + xhr.status);
 946          };
 947          xhr.onload = function () {
 948            var json;
 949            if (xhr.status < 200 || xhr.status >= 300) {
 950              failure('HTTP Error: ' + xhr.status);
 951              return;
 952            }
 953            json = JSON.parse(xhr.responseText);
 954            if (!json || typeof json.location !== 'string') {
 955              failure('Invalid JSON: ' + xhr.responseText);
 956              return;
 957            }
 958            success(pathJoin(settings.basePath, json.location));
 959          };
 960          formData = new domGlobals.FormData();
 961          formData.append('file', blobInfo.blob(), blobInfo.filename());
 962          xhr.send(formData);
 963        };
 964        var uploadBlob = function (blobInfo, handler) {
 965          return new global$1(function (resolve, reject) {
 966            try {
 967              handler(blobInfo, resolve, reject, noop);
 968            } catch (ex) {
 969              reject(ex.message);
 970            }
 971          });
 972        };
 973        var isDefaultHandler = function (handler) {
 974          return handler === defaultHandler;
 975        };
 976        var upload = function (blobInfo) {
 977          return !settings.url && isDefaultHandler(settings.handler) ? global$1.reject('Upload url missing from the settings.') : uploadBlob(blobInfo, settings.handler);
 978        };
 979        settings = global$2.extend({
 980          credentials: false,
 981          handler: defaultHandler
 982        }, settings);
 983        return { upload: upload };
 984      }
 985  
 986      var onFileInput = function (editor) {
 987        return function (evt) {
 988          var Throbber = global$5.get('Throbber');
 989          var rootControl = evt.control.rootControl;
 990          var throbber = new Throbber(rootControl.getEl());
 991          var file = evt.control.value();
 992          var blobUri = URL.createObjectURL(file);
 993          var uploader = Uploader({
 994            url: Settings.getUploadUrl(editor),
 995            basePath: Settings.getUploadBasePath(editor),
 996            credentials: Settings.getUploadCredentials(editor),
 997            handler: Settings.getUploadHandler(editor)
 998          });
 999          var finalize = function () {
1000            throbber.hide();
1001            URL.revokeObjectURL(blobUri);
1002          };
1003          throbber.show();
1004          return Utils.blobToDataUri(file).then(function (dataUrl) {
1005            var blobInfo = editor.editorUpload.blobCache.create({
1006              blob: file,
1007              blobUri: blobUri,
1008              name: file.name ? file.name.replace(/\.[^\.]+$/, '') : null,
1009              base64: dataUrl.split(',')[1]
1010            });
1011            return uploader.upload(blobInfo).then(function (url) {
1012              var src = rootControl.find('#src');
1013              src.value(url);
1014              rootControl.find('tabpanel')[0].activateTab(0);
1015              src.fire('change');
1016              finalize();
1017              return url;
1018            });
1019          }).catch(function (err) {
1020            editor.windowManager.alert(err);
1021            finalize();
1022          });
1023        };
1024      };
1025      var acceptExts = '.jpg,.jpeg,.png,.gif';
1026      var makeTab$2 = function (editor) {
1027        return {
1028          title: 'Upload',
1029          type: 'form',
1030          layout: 'flex',
1031          direction: 'column',
1032          align: 'stretch',
1033          padding: '20 20 20 20',
1034          items: [
1035            {
1036              type: 'container',
1037              layout: 'flex',
1038              direction: 'column',
1039              align: 'center',
1040              spacing: 10,
1041              items: [
1042                {
1043                  text: 'Browse for an image',
1044                  type: 'browsebutton',
1045                  accept: acceptExts,
1046                  onchange: onFileInput(editor)
1047                },
1048                {
1049                  text: 'OR',
1050                  type: 'label'
1051                }
1052              ]
1053            },
1054            {
1055              text: 'Drop an image here',
1056              type: 'dropzone',
1057              accept: acceptExts,
1058              height: 100,
1059              onchange: onFileInput(editor)
1060            }
1061          ]
1062        };
1063      };
1064      var UploadTab = { makeTab: makeTab$2 };
1065  
1066      function curry(fn) {
1067        var initialArgs = [];
1068        for (var _i = 1; _i < arguments.length; _i++) {
1069          initialArgs[_i - 1] = arguments[_i];
1070        }
1071        return function () {
1072          var restArgs = [];
1073          for (var _i = 0; _i < arguments.length; _i++) {
1074            restArgs[_i] = arguments[_i];
1075          }
1076          var all = initialArgs.concat(restArgs);
1077          return fn.apply(null, all);
1078        };
1079      }
1080  
1081      var submitForm = function (editor, evt) {
1082        var win = evt.control.getRoot();
1083        SizeManager.updateSize(win);
1084        editor.undoManager.transact(function () {
1085          var data = merge(readImageDataFromSelection(editor), win.toJSON());
1086          insertOrUpdateImage(editor, data);
1087        });
1088        editor.editorUpload.uploadImagesAuto();
1089      };
1090      function Dialog (editor) {
1091        function showDialog(imageList) {
1092          var data = readImageDataFromSelection(editor);
1093          var win, imageListCtrl;
1094          if (imageList) {
1095            imageListCtrl = {
1096              type: 'listbox',
1097              label: 'Image list',
1098              name: 'image-list',
1099              values: Utils.buildListItems(imageList, function (item) {
1100                item.value = editor.convertURL(item.value || item.url, 'src');
1101              }, [{
1102                  text: 'None',
1103                  value: ''
1104                }]),
1105              value: data.src && editor.convertURL(data.src, 'src'),
1106              onselect: function (e) {
1107                var altCtrl = win.find('#alt');
1108                if (!altCtrl.value() || e.lastControl && altCtrl.value() === e.lastControl.text()) {
1109                  altCtrl.value(e.control.text());
1110                }
1111                win.find('#src').value(e.control.value()).fire('change');
1112              },
1113              onPostRender: function () {
1114                imageListCtrl = this;
1115              }
1116            };
1117          }
1118          if (Settings.hasAdvTab(editor) || Settings.hasUploadUrl(editor) || Settings.hasUploadHandler(editor)) {
1119            var body = [MainTab.makeTab(editor, imageListCtrl)];
1120            if (Settings.hasAdvTab(editor)) {
1121              body.push(AdvTab.makeTab(editor));
1122            }
1123            if (Settings.hasUploadUrl(editor) || Settings.hasUploadHandler(editor)) {
1124              body.push(UploadTab.makeTab(editor));
1125            }
1126            win = editor.windowManager.open({
1127              title: 'Insert/edit image',
1128              data: data,
1129              bodyType: 'tabpanel',
1130              body: body,
1131              onSubmit: curry(submitForm, editor)
1132            });
1133          } else {
1134            win = editor.windowManager.open({
1135              title: 'Insert/edit image',
1136              data: data,
1137              body: MainTab.getGeneralItems(editor, imageListCtrl),
1138              onSubmit: curry(submitForm, editor)
1139            });
1140          }
1141          SizeManager.syncSize(win);
1142        }
1143        function open() {
1144          Utils.createImageList(editor, showDialog);
1145        }
1146        return { open: open };
1147      }
1148  
1149      var register = function (editor) {
1150        editor.addCommand('mceImage', Dialog(editor).open);
1151      };
1152      var Commands = { register: register };
1153  
1154      var hasImageClass = function (node) {
1155        var className = node.attr('class');
1156        return className && /\bimage\b/.test(className);
1157      };
1158      var toggleContentEditableState = function (state) {
1159        return function (nodes) {
1160          var i = nodes.length, node;
1161          var toggleContentEditable = function (node) {
1162            node.attr('contenteditable', state ? 'true' : null);
1163          };
1164          while (i--) {
1165            node = nodes[i];
1166            if (hasImageClass(node)) {
1167              node.attr('contenteditable', state ? 'false' : null);
1168              global$2.each(node.getAll('figcaption'), toggleContentEditable);
1169            }
1170          }
1171        };
1172      };
1173      var setup = function (editor) {
1174        editor.on('preInit', function () {
1175          editor.parser.addNodeFilter('figure', toggleContentEditableState(true));
1176          editor.serializer.addNodeFilter('figure', toggleContentEditableState(false));
1177        });
1178      };
1179      var FilterContent = { setup: setup };
1180  
1181      var register$1 = function (editor) {
1182        editor.addButton('image', {
1183          icon: 'image',
1184          tooltip: 'Insert/edit image',
1185          onclick: Dialog(editor).open,
1186          stateSelector: 'img:not([data-mce-object],[data-mce-placeholder]),figure.image'
1187        });
1188        editor.addMenuItem('image', {
1189          icon: 'image',
1190          text: 'Image',
1191          onclick: Dialog(editor).open,
1192          context: 'insert',
1193          prependToContext: true
1194        });
1195      };
1196      var Buttons = { register: register$1 };
1197  
1198      global.add('image', function (editor) {
1199        FilterContent.setup(editor);
1200        Buttons.register(editor);
1201        Commands.register(editor);
1202      });
1203      function Plugin () {
1204      }
1205  
1206      return Plugin;
1207  
1208  }(window));
1209  })();


Generated: Thu Mar 28 01:00:02 2024 Cross-referenced by PHPXref 0.7.1