PageRenderTime 28ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/apps/frontend-editor/frontend-editor-ckeditor-web/src/main/resources/META-INF/resources/_diffs/plugins/itemselector/plugin.js

https://github.com/ealonso/liferay-portal
JavaScript | 489 lines | 394 code | 82 blank | 13 comment | 42 complexity | 106255548ecf7ce044ef50977da06116 MD5 | raw file
  1. /**
  2. * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
  3. *
  4. * This library is free software; you can redistribute it and/or modify it under
  5. * the terms of the GNU Lesser General Public License as published by the Free
  6. * Software Foundation; either version 2.1 of the License, or (at your option)
  7. * any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  11. * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  12. * details.
  13. */
  14. (function () {
  15. const STR_FILE_ENTRY_RETURN_TYPE =
  16. 'com.liferay.item.selector.criteria.FileEntryItemSelectorReturnType';
  17. const STR_VIDEO_HTML_RETURN_TYPE =
  18. 'com.liferay.item.selector.criteria.VideoEmbeddableHTMLItemSelectorReturnType';
  19. const TPL_AUDIO_SCRIPT =
  20. 'boundingBox: "#" + mediaId,' + 'oggUrl: "{oggUrl}",' + 'url: "{url}"';
  21. const TPL_VIDEO_SCRIPT =
  22. 'boundingBox: "#" + mediaId,' +
  23. 'height: {height},' +
  24. 'ogvUrl: "{ogvUrl}",' +
  25. 'poster: "{poster}",' +
  26. 'url: "{url}",' +
  27. 'width: {width}';
  28. const defaultVideoHeight = 300;
  29. const defaultVideoWidth = 400;
  30. CKEDITOR.plugins.add('itemselector', {
  31. _bindBrowseButton(
  32. editor,
  33. dialogDefinition,
  34. tabName,
  35. commandName,
  36. targetField
  37. ) {
  38. const tab = dialogDefinition.getContents(tabName);
  39. if (tab) {
  40. const browseButton = tab.get('browse');
  41. if (browseButton) {
  42. browseButton.onClick = function () {
  43. editor.execCommand(commandName, (newVal) => {
  44. dialogDefinition.dialog.setValueOf(
  45. tabName,
  46. targetField,
  47. newVal
  48. );
  49. });
  50. };
  51. }
  52. }
  53. },
  54. _commitAudioValue(value, node) {
  55. const instance = this;
  56. node.setAttribute('data-document-url', value);
  57. const audioUrl = Liferay.Util.addParams(
  58. 'audioPreview=1&type=mp3',
  59. value
  60. );
  61. node.setAttribute('data-audio-url', audioUrl);
  62. const audioOggUrl = Liferay.Util.addParams(
  63. 'audioPreview=1&type=ogg',
  64. value
  65. );
  66. node.setAttribute('data-audio-ogg-url', audioOggUrl);
  67. return instance._audioTPL.output({
  68. oggUrl: audioOggUrl,
  69. url: audioUrl,
  70. });
  71. },
  72. _commitMediaValue(value, editor, type) {
  73. const instance = this;
  74. const mediaPlugin = editor.plugins.media;
  75. if (mediaPlugin) {
  76. mediaPlugin.onOkCallback(
  77. {
  78. commitContent: instance._getCommitMediaValueFn(
  79. value,
  80. editor,
  81. type
  82. ),
  83. },
  84. editor,
  85. type
  86. );
  87. }
  88. },
  89. _commitVideoHtmlValue(editor, html) {
  90. const parsedHTML = new DOMParser().parseFromString(
  91. html,
  92. 'text/html'
  93. );
  94. const iFrame = parsedHTML.getElementsByTagName('iframe');
  95. const url = iFrame[0].src;
  96. editor.plugins.videoembed.onOkVideoHtml(editor, html, url);
  97. },
  98. _commitVideoValue(value, node, extraStyles) {
  99. const instance = this;
  100. node.setAttribute('data-document-url', value);
  101. const videoUrl = Liferay.Util.addParams(
  102. 'videoPreview=1&type=mp4',
  103. value
  104. );
  105. node.setAttribute('data-video-url', videoUrl);
  106. const videoOgvUrl = Liferay.Util.addParams(
  107. 'videoPreview=1&type=ogv',
  108. value
  109. );
  110. node.setAttribute('data-video-ogv-url', videoOgvUrl);
  111. const videoHeight = defaultVideoHeight;
  112. node.setAttribute('data-height', videoHeight);
  113. const videoWidth = defaultVideoWidth;
  114. node.setAttribute('data-width', videoWidth);
  115. const poster = Liferay.Util.addParams('videoThumbnail=1', value);
  116. node.setAttribute('data-poster', poster);
  117. extraStyles.backgroundImage = 'url(' + poster + ')';
  118. extraStyles.height = videoHeight + 'px';
  119. extraStyles.width = videoWidth + 'px';
  120. return instance._videoTPL.output({
  121. height: videoHeight,
  122. ogvUrl: videoOgvUrl,
  123. poster,
  124. url: videoUrl,
  125. width: videoWidth,
  126. });
  127. },
  128. _getCommitMediaValueFn(value, editor, type) {
  129. const instance = this;
  130. const commitValueFn = function (node, extraStyles) {
  131. let mediaScript;
  132. if (type === 'audio') {
  133. mediaScript = instance._commitAudioValue(
  134. value,
  135. node,
  136. extraStyles
  137. );
  138. }
  139. else if (type === 'video') {
  140. mediaScript = instance._commitVideoValue(
  141. value,
  142. node,
  143. extraStyles
  144. );
  145. }
  146. const mediaPlugin = editor.plugins.media;
  147. if (mediaPlugin) {
  148. mediaPlugin.applyMediaScript(node, type, mediaScript);
  149. }
  150. };
  151. return commitValueFn;
  152. },
  153. _getItemSrc(editor, selectedItem) {
  154. let itemSrc;
  155. try {
  156. itemSrc = JSON.parse(selectedItem.value);
  157. }
  158. catch (error) {
  159. itemSrc = selectedItem;
  160. }
  161. if (itemSrc.value && itemSrc.value.html) {
  162. itemSrc = selectedItem.value.html;
  163. }
  164. else if (itemSrc.html) {
  165. itemSrc = itemSrc.html;
  166. }
  167. else if (itemSrc.value) {
  168. itemSrc = itemSrc.value;
  169. }
  170. if (selectedItem.returnType === STR_FILE_ENTRY_RETURN_TYPE) {
  171. try {
  172. const itemValue = JSON.parse(selectedItem.value);
  173. itemSrc = editor.config.attachmentURLPrefix
  174. ? editor.config.attachmentURLPrefix +
  175. encodeURIComponent(itemValue.title)
  176. : itemValue.url;
  177. }
  178. catch (error) {}
  179. }
  180. return itemSrc;
  181. },
  182. _isEmptySelection(editor) {
  183. const selection = editor.getSelection();
  184. const ranges = selection.getRanges();
  185. return (
  186. selection.getType() === CKEDITOR.SELECTION_NONE ||
  187. (ranges.length === 1 && ranges[0].collapsed)
  188. );
  189. },
  190. _onSelectedAudioChange(editor, callback, selectedItem) {
  191. const instance = this;
  192. if (selectedItem) {
  193. const audioSrc = instance._getItemSrc(editor, selectedItem);
  194. if (audioSrc) {
  195. if (typeof callback === 'function') {
  196. callback(audioSrc);
  197. }
  198. else {
  199. instance._commitMediaValue(audioSrc, editor, 'audio');
  200. }
  201. }
  202. }
  203. },
  204. _onSelectedImageChange(editor, callback, selectedItem) {
  205. const instance = this;
  206. if (selectedItem) {
  207. const imageSrc = instance._getItemSrc(editor, selectedItem);
  208. if (imageSrc) {
  209. if (typeof callback === 'function') {
  210. callback(imageSrc, selectedItem);
  211. }
  212. else {
  213. let elementOuterHtml = '<img src="' + imageSrc + '">';
  214. if (instance._isEmptySelection(editor)) {
  215. elementOuterHtml += '<br />';
  216. }
  217. editor.insertHtml(elementOuterHtml);
  218. editor.focus();
  219. }
  220. }
  221. }
  222. },
  223. _onSelectedLinkChange(editor, callback, selectedItem) {
  224. if (selectedItem) {
  225. const linkUrl = selectedItem.value;
  226. if (typeof callback === 'function') {
  227. callback(linkUrl, selectedItem);
  228. }
  229. }
  230. },
  231. _onSelectedVideoChange(editor, callback, selectedItem) {
  232. const instance = this;
  233. if (selectedItem) {
  234. const videoSrc = instance._getItemSrc(editor, selectedItem);
  235. if (videoSrc) {
  236. if (typeof callback === 'function') {
  237. callback(videoSrc);
  238. }
  239. else {
  240. if (
  241. selectedItem.returnType ===
  242. STR_VIDEO_HTML_RETURN_TYPE
  243. ) {
  244. instance._commitVideoHtmlValue(editor, videoSrc);
  245. }
  246. else {
  247. editor.plugins.videoembed.onOkVideo(editor, {
  248. type: 'video',
  249. url: videoSrc,
  250. });
  251. }
  252. }
  253. }
  254. }
  255. },
  256. _openSelectionModal(editor, url, callback) {
  257. Liferay.Util.openSelectionModal({
  258. onSelect: callback,
  259. selectEventName: editor.name + 'selectItem',
  260. title: Liferay.Language.get('select-item'),
  261. url,
  262. zIndex: CKEDITOR.getNextZIndex(),
  263. });
  264. },
  265. init(editor) {
  266. const instance = this;
  267. instance._audioTPL = new CKEDITOR.template(TPL_AUDIO_SCRIPT);
  268. instance._videoTPL = new CKEDITOR.template(TPL_VIDEO_SCRIPT);
  269. editor.addCommand('audioselector', {
  270. canUndo: false,
  271. exec(editor, callback) {
  272. const onSelectedAudioChangeFn = AUI().bind(
  273. '_onSelectedAudioChange',
  274. instance,
  275. editor,
  276. callback
  277. );
  278. instance._openSelectionModal(
  279. editor,
  280. editor.config.filebrowserAudioBrowseUrl,
  281. onSelectedAudioChangeFn
  282. );
  283. },
  284. });
  285. editor.addCommand('imageselector', {
  286. canUndo: false,
  287. exec(editor, callback) {
  288. const onSelectedImageChangeFn = AUI().bind(
  289. '_onSelectedImageChange',
  290. instance,
  291. editor,
  292. callback
  293. );
  294. instance._openSelectionModal(
  295. editor,
  296. editor.config.filebrowserImageBrowseUrl,
  297. onSelectedImageChangeFn
  298. );
  299. },
  300. });
  301. editor.addCommand('linkselector', {
  302. canUndo: false,
  303. exec(editor, callback) {
  304. const onSelectedLinkChangeFn = AUI().bind(
  305. '_onSelectedLinkChange',
  306. instance,
  307. editor,
  308. callback
  309. );
  310. instance._openSelectionModal(
  311. editor,
  312. editor.config.filebrowserBrowseUrl,
  313. onSelectedLinkChangeFn
  314. );
  315. },
  316. });
  317. editor.addCommand('videoselector', {
  318. canUndo: false,
  319. exec(editor, callback) {
  320. const onSelectedVideoChangeFn = AUI().bind(
  321. '_onSelectedVideoChange',
  322. instance,
  323. editor,
  324. callback
  325. );
  326. instance._openSelectionModal(
  327. editor,
  328. editor.config.filebrowserVideoBrowseUrl,
  329. onSelectedVideoChangeFn
  330. );
  331. },
  332. });
  333. if (editor.ui.addButton) {
  334. editor.ui.addButton('ImageSelector', {
  335. command: 'imageselector',
  336. icon: instance.path + 'assets/image.png',
  337. label: editor.lang.common.image,
  338. });
  339. editor.ui.addButton('AudioSelector', {
  340. command: 'audioselector',
  341. icon: instance.path + 'assets/audio.png',
  342. label: Liferay.Language.get('audio'),
  343. });
  344. editor.ui.addButton('VideoSelector', {
  345. command: 'videoselector',
  346. icon: instance.path + 'assets/video.png',
  347. label: Liferay.Language.get('video'),
  348. });
  349. }
  350. CKEDITOR.on('dialogDefinition', (event) => {
  351. const dialogName = event.data.name;
  352. const dialogDefinition = event.data.definition;
  353. if (dialogName === 'audio') {
  354. instance._bindBrowseButton(
  355. event.editor,
  356. dialogDefinition,
  357. 'info',
  358. 'audioselector',
  359. 'url'
  360. );
  361. }
  362. else if (dialogName === 'image') {
  363. instance._bindBrowseButton(
  364. event.editor,
  365. dialogDefinition,
  366. 'Link',
  367. 'linkselector',
  368. 'txtUrl'
  369. );
  370. dialogDefinition.getContents('info').remove('browse');
  371. dialogDefinition.onLoad = function () {
  372. this.getContentElement('info', 'txtUrl')
  373. .getInputElement()
  374. .setAttribute('readOnly', true);
  375. };
  376. }
  377. else if (dialogName === 'image2') {
  378. instance._bindBrowseButton(
  379. event.editor,
  380. dialogDefinition,
  381. 'info',
  382. 'imageselector',
  383. 'src'
  384. );
  385. }
  386. else if (dialogName === 'video') {
  387. instance._bindBrowseButton(
  388. event.editor,
  389. dialogDefinition,
  390. 'info',
  391. 'videoselector',
  392. 'poster'
  393. );
  394. }
  395. else if (dialogName === 'link') {
  396. instance._bindBrowseButton(
  397. event.editor,
  398. dialogDefinition,
  399. 'info',
  400. 'linkselector',
  401. 'url'
  402. );
  403. }
  404. });
  405. },
  406. });
  407. })();