variables.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. /**
  2. * Copyright © Magento, Inc. All rights reserved.
  3. * See COPYING.txt for license details.
  4. */
  5. /* global Variables, updateElementAtCursor, MagentovariablePlugin, Base64 */
  6. define([
  7. 'jquery',
  8. 'mage/backend/notification',
  9. 'mage/translate',
  10. 'wysiwygAdapter',
  11. 'uiRegistry',
  12. 'mage/apply/main',
  13. 'mageUtils',
  14. 'Magento_Variable/js/config-directive-generator',
  15. 'Magento_Variable/js/custom-directive-generator',
  16. 'Magento_Ui/js/lib/spinner',
  17. 'jquery/ui',
  18. 'prototype'
  19. ], function (jQuery, notification, $t, wysiwyg, registry, mageApply, utils, configGenerator, customGenerator, loader) {
  20. 'use strict';
  21. window.Variables = {
  22. textareaElementId: null,
  23. variablesContent: null,
  24. dialogWindow: null,
  25. dialogWindowId: 'variables-chooser',
  26. overlayShowEffectOptions: null,
  27. overlayHideEffectOptions: null,
  28. insertFunction: 'Variables.insertVariable',
  29. selectedPlaceholder: null,
  30. isEditMode: null,
  31. editor: null,
  32. /**
  33. * Initialize Variables handler.
  34. *
  35. * @param {*} textareaElementId
  36. * @param {Function} insertFunction
  37. * @param {Object} editor
  38. * @param {Object} selectedPlaceholder
  39. */
  40. init: function (textareaElementId, insertFunction, editor, selectedPlaceholder) {
  41. if ($(textareaElementId)) {
  42. this.textareaElementId = textareaElementId;
  43. }
  44. if (insertFunction) {
  45. this.insertFunction = insertFunction;
  46. }
  47. if (selectedPlaceholder) {
  48. this.selectedPlaceholder = selectedPlaceholder;
  49. }
  50. if (editor) {
  51. this.editor = editor;
  52. }
  53. },
  54. /**
  55. * Reset data.
  56. */
  57. resetData: function () {
  58. this.variablesContent = null;
  59. this.dialogWindow = null;
  60. },
  61. /**
  62. * Open variables chooser slideout.
  63. *
  64. * @param {Object} variables
  65. */
  66. openVariableChooser: function (variables) {
  67. if (variables) {
  68. this.openDialogWindow(variables);
  69. }
  70. },
  71. /**
  72. * Close variables chooser slideout dialog window.
  73. */
  74. closeDialogWindow: function () {
  75. jQuery('#' + this.dialogWindowId).modal('closeModal');
  76. },
  77. /**
  78. * Init ui component grid on the form
  79. *
  80. * @return void
  81. */
  82. initUiGrid: function () {
  83. mageApply.apply(document.getElementById(this.dialogWindow));
  84. jQuery('#' + this.dialogWindowId).applyBindings();
  85. loader.get('variables_modal.variables_modal.variables').hide();
  86. },
  87. /**
  88. * Open slideout dialog window.
  89. *
  90. * @param {*} variablesContent
  91. * @param {Object} selectedElement
  92. */
  93. openDialogWindow: function (variablesContent, selectedElement) {
  94. var html = utils.copy(variablesContent),
  95. self = this;
  96. jQuery('<div id="' + this.dialogWindowId + '">' + html + '</div>').modal({
  97. title: self.isEditMode ? $t('Edit Variable') : $t('Insert Variable'),
  98. type: 'slide',
  99. buttons: self.getButtonsConfig(self.isEditMode),
  100. /**
  101. * @param {jQuery.Event} e
  102. * @param {Object} modal
  103. */
  104. closed: function (e, modal) {
  105. modal.modal.remove();
  106. registry.get(
  107. 'variables_modal.variables_modal.variables.variable_selector',
  108. function (radioSelect) {
  109. radioSelect.selectedVariableCode('');
  110. }
  111. );
  112. }
  113. });
  114. this.selectedPlaceholder = selectedElement;
  115. this.addNotAvailableMessage(selectedElement);
  116. jQuery('#' + this.dialogWindowId).modal('openModal');
  117. if (typeof selectedElement !== 'undefined') {
  118. registry.get(
  119. 'variables_modal.variables_modal.variables.variable_selector',
  120. function (radioSelect) {
  121. radioSelect.selectedVariableCode(MagentovariablePlugin.getElementVariablePath(selectedElement));
  122. }
  123. );
  124. }
  125. },
  126. /**
  127. * Add message to slide out that variable is no longer available
  128. *
  129. * @param {Object} selectedElement
  130. */
  131. addNotAvailableMessage: function (selectedElement) {
  132. var name,
  133. msg,
  134. variablePath,
  135. $wrapper,
  136. lostVariableClass = 'magento-placeholder-error';
  137. if (
  138. this.isEditMode &&
  139. typeof selectedElement !== 'undefined' &&
  140. jQuery(selectedElement).hasClass(lostVariableClass)
  141. ) {
  142. variablePath = MagentovariablePlugin.getElementVariablePath(selectedElement);
  143. name = variablePath.split(':');
  144. msg = $t('The variable %1 is no longer available. Select a different variable.')
  145. .replace('%1', name[1]);
  146. jQuery('body').notification('clear')
  147. .notification('add', {
  148. error: true,
  149. message: msg,
  150. /**
  151. * @param {String} message
  152. */
  153. insertMethod: function (message) {
  154. $wrapper = jQuery('<div/>').html(message);
  155. jQuery('.modal-header .page-main-actions').after($wrapper);
  156. }
  157. });
  158. }
  159. },
  160. /**
  161. * Get selected variable directive.
  162. *
  163. * @returns {*}
  164. */
  165. getVariableCode: function () {
  166. var code = registry.get('variables_modal.variables_modal.variables.variable_selector')
  167. .selectedVariableCode(),
  168. directive = code;
  169. // processing switch here as content must contain only path/code without type
  170. if (typeof code !== 'undefined') {
  171. if (code.match('^default:')) {
  172. directive = configGenerator.processConfig(code.replace('default:', ''));
  173. } else if (code.match('^custom:')) {
  174. directive = customGenerator.processConfig(code.replace('custom:', ''));
  175. }
  176. return directive;
  177. }
  178. },
  179. /**
  180. * Get buttons configuration for slideout dialog.
  181. *
  182. * @param {Boolean} isEditMode
  183. *
  184. * @returns {Array}
  185. */
  186. getButtonsConfig: function (isEditMode) {
  187. var self = this,
  188. buttonsData;
  189. buttonsData = [
  190. {
  191. text: $t('Cancel'),
  192. 'class': 'action-scalable cancel',
  193. /**
  194. * @param {jQuery.Event} event
  195. */
  196. click: function (event) {
  197. this.closeModal(event);
  198. }
  199. },
  200. {
  201. text: isEditMode ? $t('Save') : $t('Insert Variable'),
  202. class: 'action-primary ' + (isEditMode ? '' : 'disabled'),
  203. attr: {
  204. 'id': 'insert_variable'
  205. },
  206. /**
  207. * Insert Variable
  208. */
  209. click: function () {
  210. self.insertVariable(self.getVariableCode());
  211. }
  212. }
  213. ];
  214. return buttonsData;
  215. },
  216. /**
  217. * Prepare variables row.
  218. *
  219. * @param {String} varValue
  220. * @param {*} varLabel
  221. * @return {String}
  222. * @deprecated This method isn't relevant after ui changes
  223. */
  224. prepareVariableRow: function (varValue, varLabel) {
  225. var value = varValue.replace(/"/g, '&quot;').replace(/'/g, '\\&#39;');
  226. return '<a href="#" onclick="' +
  227. this.insertFunction +
  228. '(\'' +
  229. value +
  230. '\');return false;">' +
  231. varLabel +
  232. '</a>';
  233. },
  234. /**
  235. * Insert variable into WYSIWYG editor.
  236. *
  237. * @param {*} value
  238. * @return {Object}
  239. */
  240. insertVariable: function (value) {
  241. var windowId = this.dialogWindowId,
  242. textareaElm, scrollPos, wysiwygEditorFocused;
  243. jQuery('#' + windowId).modal('closeModal');
  244. textareaElm = $(this.textareaElementId);
  245. //to support switching between wysiwyg editors
  246. wysiwygEditorFocused = wysiwyg && wysiwyg.activeEditor();
  247. if (wysiwygEditorFocused && wysiwyg.get(this.textareaElementId)) {
  248. if (jQuery(this.selectedPlaceholder).hasClass('magento-placeholder')) {
  249. wysiwyg.setCaretOnElement(this.selectedPlaceholder, 1);
  250. }
  251. wysiwyg.insertContent(value, false);
  252. if (this.selectedPlaceholder && jQuery(this.selectedPlaceholder).hasClass('magento-placeholder')) {
  253. this.selectedPlaceholder.remove();
  254. }
  255. } else if (textareaElm) {
  256. scrollPos = textareaElm.scrollTop;
  257. updateElementAtCursor(textareaElm, value);
  258. textareaElm.focus();
  259. textareaElm.scrollTop = scrollPos;
  260. jQuery(textareaElm).change();
  261. textareaElm = null;
  262. }
  263. return this;
  264. }
  265. };
  266. window.MagentovariablePlugin = {
  267. editor: null,
  268. variables: null,
  269. textareaId: null,
  270. /**
  271. * Bind editor.
  272. *
  273. * @param {*} editor
  274. */
  275. setEditor: function (editor) {
  276. this.editor = editor;
  277. },
  278. /**
  279. * Load variables chooser.
  280. *
  281. * @param {String} url
  282. * @param {*} textareaId
  283. * @param {Object} selectedElement
  284. *
  285. * @return {Object}
  286. */
  287. loadChooser: function (url, textareaId, selectedElement) {
  288. this.textareaId = textareaId;
  289. new Ajax.Request(url, {
  290. parameters: {},
  291. onComplete: function (transport) {
  292. Variables.init(this.textareaId, 'MagentovariablePlugin.insertVariable', this.editor);
  293. Variables.isEditMode = !!this.getElementVariablePath(selectedElement);
  294. this.variablesContent = transport.responseText;
  295. Variables.openDialogWindow(this.variablesContent, selectedElement);
  296. Variables.initUiGrid();
  297. }.bind(this)
  298. });
  299. return this;
  300. },
  301. /**
  302. * Open variables chooser window.
  303. *
  304. * @param {*} variables
  305. * @deprecated This method isn't relevant after ui changes
  306. */
  307. openChooser: function (variables) {
  308. Variables.openVariableChooser(variables);
  309. },
  310. /**
  311. * Insert variable.
  312. *
  313. * @param {*} value
  314. *
  315. * @return {Object}
  316. */
  317. insertVariable: function (value) {
  318. if (this.textareaId) {
  319. Variables.init(this.textareaId);
  320. Variables.insertVariable(value);
  321. } else {
  322. Variables.closeDialogWindow();
  323. Variables.insertVariable(value);
  324. }
  325. return this;
  326. },
  327. /**
  328. * Get element variable path.
  329. *
  330. * @param {Object} element
  331. * @returns {String}
  332. */
  333. getElementVariablePath: function (element) {
  334. var type, code;
  335. if (!element || !jQuery(element).hasClass('magento-variable')) {
  336. return '';
  337. }
  338. type = jQuery(element).hasClass('magento-custom-var') ? 'custom' : 'default';
  339. code = Base64.idDecode(element.getAttribute('id'));
  340. return type + ':' + code;
  341. }
  342. };
  343. });