[ Index ] |
PHP Cross Reference of WordPress |
[Summary view] [Print] [Text view]
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 })();
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Nov 21 01:00:03 2024 | Cross-referenced by PHPXref 0.7.1 |