plugin.js 38 KB

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