Source: WikiPortlet.es.js

  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. import {fetch} from 'frontend-js-web';
  15. const CONFIRM_DISCARD_IMAGES = Liferay.Language.get(
  16. 'uploads-are-in-progress-confirmation'
  17. );
  18. const CONFIRM_LOSE_FORMATTING = Liferay.Language.get(
  19. 'you-may-lose-formatting-when-switching-from-x-to-x'
  20. );
  21. /**
  22. * WikiPortlet
  23. *
  24. */
  25. class WikiPortlet {
  26. constructor({
  27. constants,
  28. currentAction,
  29. namespace,
  30. renderUrl,
  31. rootNodeId,
  32. strings = {
  33. confirmDiscardImages: CONFIRM_DISCARD_IMAGES,
  34. confirmLoseFormatting: CONFIRM_LOSE_FORMATTING,
  35. },
  36. }) {
  37. this._constants = constants;
  38. this._currentAction = currentAction;
  39. this._namespace = namespace;
  40. this._renderUrl = renderUrl;
  41. this._strings = strings;
  42. this.rootNode = document.getElementById(rootNodeId);
  43. this.workflowActionInputNode = document.getElementById(
  44. `${namespace}workflowAction`
  45. );
  46. this._events = [];
  47. this._attachEvents();
  48. }
  49. dispose() {
  50. this._events.forEach(({event, listener, target}) =>
  51. target.removeEventListener(event, listener)
  52. );
  53. this._events = [];
  54. }
  55. _addEventListener(target, event, fn) {
  56. target.addEventListener(event, fn);
  57. this._events.push({event, fn, target});
  58. }
  59. _attachEvents() {
  60. const namespace = this._namespace;
  61. const formatSelect = document.getElementById(`${namespace}format`);
  62. if (formatSelect) {
  63. this._currentFormatLabel = formatSelect.options[
  64. formatSelect.selectedIndex
  65. ].text.trim();
  66. this._currentFormatIndex = formatSelect.selectedIndex;
  67. this._addEventListener(formatSelect, 'change', (event) => {
  68. this._changeWikiFormat(event);
  69. });
  70. }
  71. const publishButton = document.getElementById(
  72. `${namespace}publishButton`
  73. );
  74. if (publishButton) {
  75. this._addEventListener(publishButton, 'click', () => {
  76. this.workflowActionInputNode.value = this._constants.ACTION_PUBLISH;
  77. this._save();
  78. });
  79. }
  80. const saveButton = document.getElementById(`${namespace}saveButton`);
  81. if (saveButton) {
  82. this._addEventListener(saveButton, 'click', () => {
  83. this.workflowActionInputNode.value = this._constants.ACTION_SAVE_DRAFT;
  84. this._save();
  85. });
  86. }
  87. const searchContainerId = `${namespace}pageAttachments`;
  88. Liferay.componentReady(searchContainerId).then((searchContainer) => {
  89. searchContainer
  90. .get('contentBox')
  91. .delegate(
  92. 'click',
  93. this._removeAttachment.bind(this),
  94. '.delete-attachment'
  95. );
  96. });
  97. this.searchContainerId = searchContainerId;
  98. }
  99. /**
  100. * Changes the wiki page format. Previously user is informed that she
  101. * may lose some formatting with a confirm dialog.
  102. *
  103. * @protected
  104. * @param {Event} event The select event that triggered the change action
  105. */
  106. _changeWikiFormat(event) {
  107. const formatSelect = event.currentTarget;
  108. const newFormat = formatSelect.options[
  109. formatSelect.selectedIndex
  110. ].text.trim();
  111. const confirmMessage = Liferay.Util.sub(
  112. this._strings.confirmLoseFormatting,
  113. this._currentFormatLabel,
  114. newFormat
  115. );
  116. if (confirm(confirmMessage)) {
  117. const form = this.rootNode.querySelector(
  118. `[name="${this._namespace}fm"]`
  119. );
  120. form.setAttribute('action', this._renderUrl);
  121. this._save();
  122. }
  123. else {
  124. formatSelect.selectedIndex = this.currentFormatIndex;
  125. }
  126. }
  127. /**
  128. * Sends a request to remove the selected attachment.
  129. *
  130. * @protected
  131. * @param {Event} event The click event that triggered the remove action
  132. */
  133. _removeAttachment(event) {
  134. const link = event.currentTarget;
  135. const deleteURL = link.getAttribute('data-url');
  136. fetch(deleteURL).then(() => {
  137. Liferay.componentReady(this.searchContainerId).then(
  138. (searchContainer) => {
  139. searchContainer.deleteRow(
  140. link.ancestor('tr'),
  141. link.getAttribute('data-rowid')
  142. );
  143. searchContainer.updateDataStore();
  144. }
  145. );
  146. });
  147. }
  148. /**
  149. * Checks if there are images that have not been uploaded yet.
  150. * In that case, it removes them after asking
  151. * confirmation to the user.
  152. *
  153. * @protected
  154. * @return {Boolean} False if there are temporal images and
  155. * user does not confirm she wants to lose them. True in other case.
  156. */
  157. _removeTempImages() {
  158. const tempImages = this.rootNode.querySelector('img[data-random-id]');
  159. let discardTempImages = true;
  160. if (tempImages && tempImages.length > 0) {
  161. if (confirm(this._strings.confirmDiscardImages)) {
  162. tempImages.forEach((node) => {
  163. node.parentElement.remove();
  164. });
  165. }
  166. else {
  167. discardTempImages = false;
  168. }
  169. }
  170. return discardTempImages;
  171. }
  172. /**
  173. * Submits the wiki page.
  174. *
  175. * @protected
  176. */
  177. _save() {
  178. const namespace = this._namespace;
  179. if (this._removeTempImages()) {
  180. document.getElementById(
  181. namespace + this._constants.CMD
  182. ).value = this._currentAction;
  183. const contentEditor = window[`${namespace}contentEditor`];
  184. if (contentEditor) {
  185. document.getElementById(
  186. `${namespace}content`
  187. ).value = contentEditor.getHTML();
  188. }
  189. submitForm(document[`${namespace}fm`]);
  190. }
  191. }
  192. }
  193. export default WikiPortlet;