fl-builder-ui-settings-copy-paste.js 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. ( function( $ ) {
  2. FLBuilderSettingsCopyPaste = {
  3. init: function() {
  4. // window.addEventListener( 'storage', this._storageListener );
  5. FLBuilder.addHook( 'settings-form-init', this.initExportButton );
  6. FLBuilder.addHook( 'settings-form-init', this.initImportButton );
  7. },
  8. _getClipboard: function () {
  9. return window.localStorage.getItem('clipboard') || '';
  10. },
  11. _getClipboardType: function(e) {
  12. const clipboard = this._getClipboard();
  13. const type = clipboard.match(/{type:([_a-z0-9-]+)}/);
  14. if (null !== type && 'undefined' !== type[1]) {
  15. return type[1];
  16. }
  17. return '';
  18. },
  19. _setClipboard: function (data, win = false) {
  20. // set to localStorage.
  21. window.localStorage.setItem('clipboard', data);
  22. // set to clipboard.
  23. if (win) {
  24. this._copyToClipboard(data);
  25. }
  26. },
  27. _copyToClipboard: function (data) {
  28. if (0 === data.length) {
  29. return;
  30. }
  31. if ('undefined' === typeof navigator.clipboard) {
  32. // create temp el
  33. const tempEl = document.createElement('textarea');
  34. // hide temp el
  35. tempEl.style.position = 'absolute';
  36. tempEl.style.left = '-100%';
  37. // set content of temp el
  38. tempEl.value = data;
  39. // insert temp el in page
  40. document.body.appendChild(tempEl);
  41. // select temp el
  42. tempEl.select();
  43. // copy temp el content
  44. document.execCommand('copy');
  45. // remove temp el
  46. document.body.removeChild(tempEl);
  47. } else {
  48. window.parent.navigator.clipboard.writeText(data);
  49. }
  50. },
  51. _copySettings: function (type, nodeId, win = false, filterStyle = false) {
  52. let settings = {};
  53. let selector = type;
  54. const form = $('.fl-builder-settings[data-node=' + nodeId + ']');
  55. const date = new Date().toDateString();
  56. const wrap = '/// {type:' + type + '} ' + date + ' ///';
  57. if ('row' !== selector) {
  58. if ('column' === selector) {
  59. selector = 'col';
  60. } else {
  61. selector = 'module';
  62. }
  63. }
  64. if (form.length > 0) {
  65. // settings panel is open
  66. settings = FLBuilder._getSettings(form)
  67. } else {
  68. // settings panel is closed
  69. settings = FLBuilderSettingsConfig.nodes[nodeId];
  70. }
  71. // filter style
  72. if (form.length > 0 && filterStyle) {
  73. for (let key in settings) {
  74. let isStyle = false;
  75. let singleInput = null;
  76. let arrayInput = null;
  77. if ( 'connections' === key ) {
  78. const styleConnections = {};
  79. for ( subkey in settings[ key ] ) {
  80. singleInput = form.find('[name="' + subkey + '"]');
  81. arrayInput = form.find('[name*="' + subkey + '["]');
  82. if (singleInput.length) {
  83. isStyle = singleInput.closest('.fl-field').data('is-style');
  84. } else if (arrayInput.length) {
  85. isStyle = arrayInput.closest('.fl-field').data('is-style');
  86. }
  87. if (isStyle) {
  88. styleConnections[ subkey ] = settings[ key ][ subkey ];
  89. }
  90. }
  91. settings[ key ] = styleConnections;
  92. } else {
  93. singleInput = form.find('[name="' + key + '"]');
  94. arrayInput = form.find('[name*="' + key + '["]');
  95. if (singleInput.length) {
  96. isStyle = singleInput.closest('.fl-field').data('is-style');
  97. } else if (arrayInput.length) {
  98. isStyle = arrayInput.closest('.fl-field').data('is-style');
  99. }
  100. if (!isStyle) {
  101. delete settings[key];
  102. }
  103. }
  104. }
  105. }
  106. // copy data to fl-builder clipboard
  107. this._setClipboard(wrap + "\n" + JSON.stringify(settings), win);
  108. // set body attr
  109. $('body').attr('data-clipboard', type);
  110. // remove active class
  111. $('.fl-quick-paste-active').removeClass('fl-quick-paste-active');
  112. // add active class
  113. $('[data-node="' + nodeId + '"]')
  114. .find('.fl-' + selector + '-quick-paste')
  115. .addClass('fl-quick-paste-active');
  116. return this._getClipboard();
  117. },
  118. _importSettings: function (type, nodeId, data) {
  119. const dataType = data.match(/{type:([_a-z0-9-]+)}/);
  120. if ('undefined' !== dataType[1] && type === dataType[1]) {
  121. try {
  122. const jsonData = JSON.parse(data.replace(/\/\/\/.+\/\/\//, ''));
  123. // remove width settings from column
  124. if ('column' === type) {
  125. if ('size' in jsonData) {
  126. delete jsonData.size;
  127. }
  128. if ('size_large' in jsonData) {
  129. delete jsonData.size_large;
  130. }
  131. if ('size_medium' in jsonData) {
  132. delete jsonData.size_medium;
  133. }
  134. if ('size_responsive' in jsonData) {
  135. delete jsonData.size_responsive;
  136. }
  137. }
  138. // merge copied data with existing node
  139. const mergedData = $.extend({}, FLBuilderSettingsConfig.nodes[nodeId], jsonData);
  140. // set node data
  141. FLBuilderSettingsConfig.nodes[nodeId] = mergedData;
  142. // dispatch to store
  143. FL.Builder.data
  144. .getLayoutActions()
  145. .updateNodeSettings(
  146. nodeId,
  147. mergedData,
  148. FLBuilder._saveSettingsComplete.bind(this, true)
  149. );
  150. // trigger hook
  151. FLBuilder.triggerHook('didSaveNodeSettings', {
  152. nodeId: nodeId,
  153. settings: mergedData
  154. });
  155. // close panel
  156. FLBuilder._lightbox.close();
  157. return true;
  158. } catch {
  159. return false;
  160. }
  161. }
  162. return false;
  163. },
  164. _importFromClipboard: function (type, nodeId) {
  165. if (0 < this._getClipboard().length) {
  166. return FLBuilderSettingsCopyPaste._importSettings(type, nodeId, this._getClipboard());
  167. }
  168. return false;
  169. },
  170. _importFromJSON: function (type, nodeId, data) {
  171. if ('undefined' !== typeof data && null !== data && 0 < data.length) {
  172. return FLBuilderSettingsCopyPaste._importSettings(type, nodeId, data);
  173. }
  174. return false;
  175. },
  176. _bindCopyToElement: function ($el, type, nodeId, win = false, filterStyle = false) {
  177. const text = $el.text();
  178. // copy data to clipboard
  179. FLBuilderSettingsCopyPaste._copySettings(type, nodeId, win, filterStyle);
  180. // set button text
  181. $el.text(FLBuilderStrings.module_import.copied);
  182. // restore button text
  183. setTimeout(() => {
  184. $el.text(text);
  185. }, 1000);
  186. },
  187. initExportButton: function() {
  188. // row - all
  189. $('button.row-export-all').on('click', function () {
  190. const nodeId = $('.fl-builder-row-settings').data('node');
  191. // bind copy to the el
  192. FLBuilderSettingsCopyPaste._bindCopyToElement($(this), 'row', nodeId, true);
  193. });
  194. // row - style
  195. $('button.row-export-style').on('click', function () {
  196. const nodeId = $('.fl-builder-row-settings').data('node');
  197. // bind copy to the el
  198. FLBuilderSettingsCopyPaste._bindCopyToElement($(this), 'row', nodeId, true, true);
  199. });
  200. // col - all
  201. $('button.col-export-all').on('click', function () {
  202. const nodeId = $('.fl-builder-col-settings').data('node');
  203. // bind copy to the el
  204. FLBuilderSettingsCopyPaste._bindCopyToElement($(this), 'column', nodeId, true);
  205. });
  206. // col - style
  207. $('button.col-export-style').on('click', function () {
  208. const nodeId = $('.fl-builder-col-settings').data('node');
  209. // bind copy to the el
  210. FLBuilderSettingsCopyPaste._bindCopyToElement($(this), 'column', nodeId, true, true);
  211. });
  212. // module - all
  213. $('button.module-export-all').on('click', function () {
  214. const nodeId = $('.fl-builder-module-settings').data('node');
  215. const type = $('.fl-builder-module-settings').data('type');
  216. // bind copy to the el
  217. FLBuilderSettingsCopyPaste._bindCopyToElement($(this), type, nodeId, true);
  218. });
  219. // module - style
  220. $('button.module-export-style').on('click', function () {
  221. const nodeId = $('.fl-builder-module-settings').data('node');
  222. const type = $('.fl-builder-module-settings').data('type');
  223. // bind copy to the el
  224. FLBuilderSettingsCopyPaste._bindCopyToElement($(this), type, nodeId, true, true);
  225. });
  226. },
  227. initImportButton: function() {
  228. // row
  229. $('button.row-import-apply').on('click', function () {
  230. const nodeId = $('.fl-builder-row-settings').data('node');
  231. const data = $('.row-import-input').val();
  232. const success = FLBuilderSettingsCopyPaste._importFromJSON('row', nodeId, data);
  233. if (!success) {
  234. $('.row-import-error').html(FLBuilderStrings.module_import.error).show();
  235. }
  236. });
  237. // col
  238. $('button.col-import-apply').on('click', function () {
  239. const nodeId = $('.fl-builder-col-settings').data('node');
  240. const data = $('.col-import-input').val();
  241. const success = FLBuilderSettingsCopyPaste._importFromJSON('column', nodeId, data);
  242. if (!success) {
  243. $('.col-import-error').html(FLBuilderStrings.module_import.error).show();
  244. }
  245. });
  246. // module
  247. $('button.module-import-apply').on('click', function () {
  248. const type = $('.fl-builder-module-settings').data('type');
  249. const nodeId = $('.fl-builder-module-settings').data('node');
  250. const data = $('.module-import-input').val();
  251. const success = FLBuilderSettingsCopyPaste._importFromJSON(type, nodeId, data);
  252. if (!success) {
  253. $('.module-import-error').html(FLBuilderStrings.module_import.error).show();
  254. }
  255. });
  256. },
  257. };
  258. $( function() {
  259. FLBuilderSettingsCopyPaste.init();
  260. } );
  261. } )( jQuery );