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

/Ip/Internal/Design/assets/optionsBox.js

https://gitlab.com/x33n/ImpressPages
JavaScript | 402 lines | 280 code | 76 blank | 46 comment | 55 complexity | eedfece92cbbfe82b88a637874deb429 MD5 | raw file
  1. var ipDesign = new function () {
  2. "use strict";
  3. var lastSerialized = null,
  4. lastSerializedArray = null,
  5. cssUpdateQueue = [], //css files that are in progress to be updated
  6. cssUpdateInProgress = false,
  7. saveButtonDown = false;
  8. /**
  9. *
  10. *
  11. * @private
  12. * @param src
  13. * @param type
  14. * @param callback_fn
  15. */
  16. var loadScript = function (src, type, id, callback_fn) {
  17. var loaded = false, scrpt, img;
  18. if (type === 'script') {
  19. scrpt = document.createElement('script');
  20. scrpt.setAttribute('type', 'text/javascript');
  21. scrpt.setAttribute('src', src);
  22. } else if (type === 'css') {
  23. scrpt = document.createElement('link');
  24. scrpt.setAttribute('rel', 'stylesheet');
  25. scrpt.setAttribute('type', 'text/css');
  26. scrpt.setAttribute('href', src);
  27. }
  28. scrpt.setAttribute('id', id);
  29. document.getElementsByTagName('head')[0].appendChild(scrpt);
  30. scrpt.onreadystatechange = function () {
  31. if (this.readyState === 'complete' || this.readyState === 'loaded') {
  32. if (loaded === false) {
  33. callback_fn();
  34. }
  35. loaded = true;
  36. }
  37. };
  38. scrpt.onload = function () {
  39. if (loaded === false) {
  40. callback_fn();
  41. }
  42. loaded = true;
  43. };
  44. /* for browsers who don't throw any event
  45. img = document.createElement('img');
  46. img.onerror = function () {
  47. if (loaded === false) {
  48. callback_fn();
  49. }
  50. loaded = true;
  51. };
  52. img.src = src;
  53. */
  54. };
  55. /*
  56. * This is the way to declare private methods.
  57. * */
  58. var processCssUpdateQueue = function () {
  59. if (cssUpdateInProgress) {
  60. return;
  61. }
  62. if (cssUpdateQueue.length) {
  63. var nextFile = cssUpdateQueue.shift();
  64. //remove files if they already are in the queue. This is to make sure the right order of loading.
  65. var filePos = $.inArray(nextFile, cssUpdateQueue);
  66. while (filePos !== -1 && cssUpdateQueue.length) {
  67. nextFile = cssUpdateQueue.shift();
  68. filePos = $.inArray(nextFile, cssUpdateQueue);
  69. }
  70. processFileReload(nextFile);
  71. }
  72. };
  73. /*
  74. * This is the way to declare private methods.
  75. * */
  76. var processFileReload = function (file) {
  77. var dataIterator, formData, data;
  78. cssUpdateInProgress = 1;
  79. formData = $('.ipModuleDesignConfig .ipsForm').serializeArray();
  80. data = 'aa=Design.realTimeLess&ipDesignPreview=1&file=' + file + '.less';
  81. $.each(formData, function (index, elem) {
  82. if (elem.name !== 'a' && elem.name !== 'aa' && elem.name !== 'm' && elem.name !== 'g') {
  83. data = data + '&ipDesign[pCfg][' + elem.name + ']=' + encodeURIComponent(elem.value);
  84. }
  85. });
  86. if (getParameterByName('theme')) {
  87. //for theme preview in market
  88. data = data + '&theme=' + encodeURIComponent(getParameterByName('theme'));
  89. }
  90. loadScript(ip.baseUrl + '?' + data, 'css', 'ipsRealTimeCss_' + file, function () {
  91. $('link[href*="' + ipThemeUrl(file) + '"]').remove();
  92. if ($('#ipsRealTimeCss_' + file).length > 1) {
  93. $('#ipsRealTimeCss_' + file).first().remove();
  94. }
  95. cssUpdateInProgress = false;
  96. processCssUpdateQueue();
  97. });
  98. };
  99. var initAccordion = function () {
  100. var firstFieldsetToShow;
  101. // wrap fields in a div so accordion would work
  102. $('.ipModuleDesignConfig .ipsBody fieldset').each(function (index, fieldset) {
  103. var $fieldset = $(fieldset);
  104. var $legend = $fieldset.find('legend');
  105. $fieldset.addClass('panel');
  106. // if legend exist it means its option group
  107. if ($legend.length) {
  108. // adding required class to make a group
  109. $fieldset.parent().attr('id', 'optionBoxCollapseGroup');
  110. firstFieldsetToShow = firstFieldsetToShow || index;
  111. // adding required attributes to make collapse() to work
  112. $legend
  113. .attr('data-toggle', 'collapse')
  114. .attr('data-target', '#optionBoxCollapse' + index)
  115. .attr('data-parent', '#optionBoxCollapseGroup');
  116. if (firstFieldsetToShow != index) {
  117. $legend.addClass('collapsed');
  118. }
  119. $fieldset.find('.form-group').wrapAll('<div class="collapse' + (firstFieldsetToShow == index ? ' in' : '') + '" id="optionBoxCollapse' + index + '" />');
  120. }
  121. });
  122. $('.ipModuleDesignConfig .ipsBody .collapse').on('shown.bs.collapse', function () {
  123. fixAccordion();
  124. });
  125. };
  126. var fixAccordion = function () {
  127. // this code is not in ipDesign.fixLayout so it would be executed only on drag
  128. var $body = $('.ipModuleDesignConfig .ipsBody');
  129. var $openPanel = $body.find('.collapse.in');
  130. if ($openPanel.length) {
  131. var bodyHeight = parseInt($body.css('max-height'));
  132. var panelHeight = parseInt($openPanel.height('auto').height());
  133. var legendHeight = 0;
  134. // calculating the height of all opened legends
  135. $body.find('legend').each(function (index, legend) {
  136. legendHeight += $(legend).outerHeight(true);
  137. });
  138. // adding the height of warning
  139. //legendHeight += $('.ipModuleDesignConfig .ipsReload').outerHeight(true); #removeReloadNote
  140. // calculating how much space is left for content
  141. var openPanelHeight = (bodyHeight > legendHeight) ? (bodyHeight - legendHeight) : 0;
  142. // fixing height only if there's not enough space
  143. if (openPanelHeight < panelHeight) {
  144. $openPanel.height(openPanelHeight);
  145. } else {
  146. $openPanel.height('auto');
  147. }
  148. }
  149. };
  150. var initLayout = function () {
  151. ipDesign.fixLayout();
  152. $('.ipModuleDesignConfig .ipsDialog').draggable({
  153. //axis: "x",
  154. //containment: "body",
  155. //containment: [0, 0, x2, y2],
  156. handle: ".ipsDragHandler",
  157. scroll: false,
  158. drag: function (event, ui) {
  159. ipDesign.fixLayout();
  160. }
  161. });
  162. $(window).bind("resize.ipModuleDesign", ipDesign.fixLayout);
  163. $(window).bind("scroll.ipModuleDesign", ipDesign.fixLayout);
  164. };
  165. this.init = function () {
  166. $('a').not('.ipWidget-Gallery a, .ipWidget-Image a, .ipWidget-File a')
  167. .off('click').on('click', function (e) {
  168. e.preventDefault();
  169. ipDesign.openLink($(e.currentTarget).attr('href'));
  170. }); //it is important to bind links before adding configuration box html to the body
  171. $('body').append(ipModuleDesignConfiguration);
  172. ipInitForms(); //reinit form controls after adding option box
  173. $('.ipModuleDesignConfig .ipsSave').off('mousedown').on('mousedown', function (e) {
  174. saveButtonDown = true;
  175. });
  176. $('.ipModuleDesignConfig .ipsSave').off('mouseup').on('mouseup', function (e) {
  177. saveButtonDown = false;
  178. });
  179. $('.ipModuleDesignConfig .ipsSave').off('click').on('click', function (e) {
  180. e.preventDefault();
  181. $(this).addClass('disabled').text(ipTranslationSaving);
  182. $('.ipModuleDesignConfig .ipsForm').submit();
  183. });
  184. $('.ipModuleDesignConfig .ipsForm').on('ipSubmitResponse', function (e, response) {
  185. if (response.result) {
  186. window.location.reload(true);
  187. }
  188. });
  189. $('.ipModuleDesignConfig .ipsCancel').off('click').on('click', function (e) {
  190. e.preventDefault();
  191. window.parent.ipDesignOptionsClose(e);
  192. });
  193. $('.ipModuleDesignConfig .ipsDefault').off('click').on('click', function (e) {
  194. e.preventDefault();
  195. var restoreDefault = 1;
  196. ipDesign.openLink(window.location.href.split('#')[0].split('?')[0], restoreDefault);
  197. });
  198. $('.ipModuleDesignConfig .ipsForm input').on('change', ipDesign.livePreviewUpdate);
  199. $('.ipModuleDesignConfig .ipsForm select').on('change', ipDesign.livePreviewUpdate);
  200. $('.ipModuleDesignConfig .ipsForm .type-repositoryFile').on('ipFieldFileAdded', ipDesign.livePreviewUpdate);
  201. $('.ipModuleDesignConfig .ipsForm .type-repositoryFile').on('ipFieldFileRemoved', ipDesign.livePreviewUpdate);
  202. initAccordion();
  203. initLayout();
  204. $('.ipModuleDesignConfig .ipsReloadButton').on('click', function (e) {
  205. e.preventDefault();
  206. ipDesign.openLink(window.location.href);
  207. });
  208. lastSerialized = $('.ipModuleDesignConfig .ipsForm').serialize();
  209. lastSerializedArray = $('.ipModuleDesignConfig .ipsForm').serializeArray();
  210. //setup config groups
  211. };
  212. this.showReloadNotice = function () {
  213. if (!saveButtonDown) { //if user is holding down the save button, don't show reload message as it will scroll save booton down and save won't happen.
  214. //$('.ipModuleDesignConfig .ipsReload').removeClass('hidden'); #removeReloadNote
  215. $('.ipModuleDesignConfig .ipsReloadButton').removeClass('hidden');
  216. //fixAccordion(); #removeReloadNote
  217. }
  218. };
  219. this.reloadLessFiles = function (files) {
  220. if (!(files instanceof Array)) {
  221. files = [files];
  222. }
  223. var i = 0,
  224. filePos = 0;
  225. //add files to the queue
  226. $.each(files, function (index, elem) {
  227. cssUpdateQueue.push(elem);
  228. });
  229. setTimeout(processCssUpdateQueue, 200);
  230. };
  231. this.openLink = function (href, restoreDefault) {
  232. var config = $('.ipModuleDesignConfig .ipsForm').serializeArray();
  233. // create preview config data
  234. var pCfg = {};
  235. var key;
  236. for (var i = 0; i < config.length; i++) {
  237. key = config[i].name;
  238. if (key != 'securityToken' && key != 'g' && key != 'm' && key != 'aa') {
  239. pCfg[key] = config[i].value;
  240. }
  241. }
  242. // create form for preview config
  243. var postForm = $('<form>', {
  244. 'method': 'POST',
  245. 'action': href.indexOf('?') == -1 ? href + '?ipDesignPreview=1' : href + '&ipDesignPreview=1'
  246. });
  247. for (var name in pCfg) {
  248. postForm.append($('<input>', {
  249. 'name': 'ipDesign[pCfg][' + name + ']',
  250. 'value': pCfg[name],
  251. 'type': 'hidden'
  252. }));
  253. }
  254. postForm.append($('<input>', {
  255. 'name': 'securityToken',
  256. 'value': ip.securityToken,
  257. 'type': 'hidden'
  258. }));
  259. if (restoreDefault) {
  260. postForm.find('[name^=ipDesign]').remove();
  261. postForm.append($('<input>', {
  262. 'name': 'restoreDefault',
  263. 'value': 1,
  264. 'type': 'hidden'
  265. }));
  266. }
  267. postForm.append($('<input>', {
  268. 'name': 'refreshPreview',
  269. 'value': 1,
  270. 'type': 'hidden'
  271. }));
  272. postForm.appendTo('body').submit();
  273. };
  274. this.livePreviewUpdate = function () {
  275. var $form = $('.ipModuleDesignConfig .ipsForm');
  276. var curSerialized = $form.serialize();
  277. var curSerializedArray = $form.serializeArray();
  278. if (curSerialized != lastSerialized) {
  279. for (var optionNameIndex in ipModuleDesignOptionNames) {
  280. var optionName = ipModuleDesignOptionNames[optionNameIndex];
  281. var curValue = getValueByName(optionName, curSerializedArray);
  282. var lastValue = getValueByName(optionName, lastSerializedArray);
  283. if (lastValue != curValue) {
  284. if (typeof(ipDesignOptions[optionName]) === 'function') {
  285. if ($('.type-repositoryFile.name-bodyBackgroundColor').length) {
  286. curValue = ipRepositoryUrl + curValue; //add base URL if we deal with RepositoryFile input
  287. }
  288. ipDesignOptions[optionName](curValue);
  289. } else {
  290. //live preview doesn't exist. Tell user to reload the page
  291. ipDesign.showReloadNotice();
  292. }
  293. }
  294. }
  295. }
  296. lastSerialized = curSerialized;
  297. lastSerializedArray = curSerializedArray;
  298. };
  299. this.fixLayout = function (e) {
  300. var x2 = $(window).width() - $('.ipModuleDesignConfig .ipsDialog').width() - 20;
  301. var y2 = $(window).height() - 150;
  302. var topOffset = parseInt($('.ipModuleDesignConfig .ipsDialog').css('top'));
  303. $('.ipModuleDesignConfig .ipsBody').css('max-height', $(window).height() - topOffset - 170);
  304. fixAccordion();
  305. };
  306. var getValueByName = function (name, values) {
  307. var results = "";
  308. $.each(values, function (key, value) {
  309. if (value && value.name && value.value) {
  310. if (value.name == name || value.name == name + '[]') { //array for RepositoryFile
  311. results = value.value;
  312. }
  313. }
  314. });
  315. return results;
  316. };
  317. var getParameterByName = function (name) {
  318. name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
  319. var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
  320. results = regex.exec(location.search);
  321. return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
  322. };
  323. };
  324. $(document).ready(function () {
  325. ipDesign.init();
  326. });