PluginProbe
CSS & JavaScript Toolbox / 7.1.2
CSS & JavaScript Toolbox v7.1.2
trunk 0.3 0.8 10 10.1 11 11.2 11.3 11.4 11.5 11.6 11.7 11.8 11.9 11.9.1 12 12.0 12.0.1 12.0.3 12.0.4 12.0.5 12.0.6 12.0.7 6.0 6.0.11 All 60 releases
css-javascript-toolbox / views / blocks / manager / public / js / blocks-page / blocks-page.js

blocks-page.js in CSS & JavaScript Toolbox 7.1.2, at views/blocks/manager/public/js/blocks-page/blocks-page.js

783 lines 20.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 *
3 */
4 var CJTToolBox = {
5 forms : {templatesLookupForm : []}
6 }; // Application name spaces structure.
7
8 /*
9 *
10 *
11 */
12 var CJTBlocksPage;
13
14 /*
15 *
16 *
17 */
18 (function($){
19
20 /*
21 *
22 *
23 */
24 CJTBlocksPage = {
25
26 /*
27 *
28 *
29 *
30 */
31 blocksContainer : null,
32
33 /*
34 *
35 *
36 *
37 */
38 blocksForm : null,
39
40 /*
41 *
42 *
43 *
44 */
45 blocks : null,
46
47 /**
48 *
49 *
50 *
51 *
52 *
53 */
54 changes : [],
55
56 /*
57 *
58 *
59 *
60 */
61 deletedBlocks : [],
62
63 /*
64 *
65 *
66 *
67 */
68 loadingElement : null,
69
70 /*
71 *
72 *
73 *
74 */
75 loadingImage : null,
76
77 /**
78 *
79 *
80 *
81 */
82 pageId : 'cjtoolbox',
83
84 /**
85 *
86 *
87 *
88 */
89 server : null,
90
91 /**
92 *
93 *
94 *
95 */
96 toolboxes : {
97
98 /**
99 *
100 *
101 *
102 */
103 toolboxes : null,
104
105 /*
106 *
107 *
108 *
109 */
110 css : function(role, value) {
111 this.toolboxes.each(
112 function() {
113 $(this).css(role, value);
114 }
115 );
116 },
117
118 /**
119 * put your comment there...
120 *
121 */
122 getIButton : function(buttonName, method, params) {
123 var dispatcher = {
124 /**
125 * put your comment there...
126 *
127 */
128 dispatch : function(params) {
129 var result = {};
130 CJTBlocksPage.toolboxes.toolboxes.each(
131 function(index) {
132 // Get button object.
133 var button = this.CJTToolBox.buttons[buttonName];
134 // Dispatch button method.
135 result[index] = button[method].apply(button, params);
136 }
137 );
138 return result;
139 }
140 };
141 // When created and params is passed vall dispatch.
142 if (params != undefined) {
143 dispatcher.dispatch(params);
144 }
145 // Return dispatched handle object.
146 return dispatcher;
147 },
148
149 /**
150 *
151 *
152 *
153 */
154 enable : function(buttonName, enable) {
155 this.toolboxes.each(
156 function() {
157 var button = this.CJTToolBox.buttons[buttonName];
158 button.enable(enable);
159 }
160 );
161 },
162
163 /**
164 *
165 *
166 *
167 */
168 isEnabled : function(buttonName) {
169 var isEnabled = true;
170 this.toolboxes.each(
171 function() {
172 var button = this.CJTToolBox.buttons[buttonName];
173 isEnabled &= button.isEnabled();
174 }
175 );
176 return isEnabled;
177 },
178
179 /*
180 *
181 *
182 *
183 */
184 switchState : function(state) {
185 var buttonsToHide;
186 switch (state) {
187 case 'restore':
188 // Hide Add New Block, Save all changes, location tools and state tools buttons.
189 buttonsToHide = ['save-changes', 'add-block', 'state-tools', 'location-tools'];
190 break;
191 default:
192 // Hide Restore & Cancel Restore buttons.
193 buttonsToHide = ['restore', 'cancel-restore'];
194 break;
195 }
196 // Hide buttons.
197 this.toolboxes.each(
198 // Get all toolboxes.
199 function(tbIndex, toolbox) {
200 // Hide all buttons for each toolbox.
201 $.each(buttonsToHide,
202 function(btnIndex, buttonName) {
203 var button = toolbox.CJTToolBox.buttons[buttonName];
204 button.jButton.css('display', 'none');
205 }
206 );
207 }
208 );
209 // Display Toolboxes.
210 this.css('visibility', 'visible');
211 }
212 },
213
214 /**
215 *
216 *
217 *
218 */
219 _onaddnew : function(event, params) {
220 // Server request.
221 var requestData = {
222 // Server paramerers.
223 viewName : 'blocks/new',
224 // Thick box parameters.
225 width : 450,
226 height: 230,
227 position : params.toolbox.position,
228 TB_iframe : true // Must be last one Thickbox removes this and later params.
229 };
230 var url = CJTBlocksPage.server.getRequestURL('blocksPage', 'get_view', requestData);
231 // Popup form.
232 tb_show(CJTBlocksPageI18N.addNewBlockDialogTitle, url);
233 },
234
235 /**
236 * put your comment there...
237 *
238 */
239 _oncancelrestore : function() {
240 window.location.href = window.location.href.replace(/&backupId=\d+/, '');
241 },
242
243 /**
244 *
245 *
246 *
247 *
248 */
249 _ondeleteall : function() {
250 // Confimation message!
251 var blocksCount = CJTBlocksPage.blocks.getBlocks().length;
252 var confirmMessage = CJTBlocksPageI18N.commonDeleteMessage.replace('%d', blocksCount)
253 + "\n\n"
254 + CJTBlocksPage.blocks.toArray('name').join("\n")
255 + "\n\n"
256 + CJTBlocksPageI18N.confirmDeleteAll;
257 // Confirm deletion.
258 if (confirm(confirmMessage)) {
259 CJTBlocksPage.deleteBlocks(CJTBlocksPage.blocks.getBlocks());
260 }
261 },
262
263 /**
264 *
265 *
266 *
267 *
268 */
269 _ondeleteempty : function() {
270 // initialize blocks.
271 var blocks = CJTBlocksPage.blocks.getBlocks();
272 var emptyBlocks = [];
273 // For every block check if there is code content.
274 blocks.each(
275 function(index, block) {
276 var code = block.CJTBlock.block.get('code');
277 if (code == '') {
278 emptyBlocks.push(this);
279 }
280 }
281 );
282 // If there is at least one empty block to delete just confirm
283 // otherwise show error!
284 if (emptyBlocks.length) {
285 // Confimation message!
286 var confirmMessage = CJTBlocksPageI18N.commonDeleteMessage.replace('%d', emptyBlocks.length)
287 + "\n\n"
288 + CJTBlocksPage.blocks.toArray('name', emptyBlocks).join("\n")
289 + "\n\n"
290 + CJTBlocksPageI18N.confirmDeleteEmpty;
291 if (confirm(confirmMessage)) {
292 CJTBlocksPage.deleteBlocks(emptyBlocks);
293 }
294 }
295 else {
296 alert(CJTBlocksPageI18N.noBlocksToDelete)
297 }
298 },
299
300 /**
301 * put your comment there...
302 *
303 */
304 _onmanagesettings : function() {
305 var params = {width: 700, height: 600,TB_iframe : true};
306 var settingsFormURL = CJTBlocksPage.server.getRequestURL('settings', 'manageForm', params);
307 tb_show(CJTBlocksPageI18N.settingsFormTitle, settingsFormURL);
308 },
309
310 /**
311 * put your comment there...
312 *
313 */
314 _onmanagetemplates : function() {
315 var params = {width: '100%', height: '100%', TB_iframe : true};
316 var url = CJTBlocksPage.server.getRequestURL('templatesManager', 'display', params);
317 tb_show(CJTBlocksPageI18N.manageTemplatesFormTitle, url);
318 // Get thickbox form element.
319 var thickboxForm = $('#TB_window');
320 // Style thickbox.
321 thickboxForm.css({
322 'position' : 'fixed',
323 'left' : '0px',
324 'top' : '4px',
325 'margin-left' : '5px',
326 'margin-top': '0px',
327 'width' : '99%',
328 'height' : ((jQuery(window).height() - 40) + 'px'),
329 'z-index' : 1000000
330 });
331 // Set Iframe style.
332 thickboxForm.find('iframe').css({
333 width : '100%',
334 height : '100%'
335 });
336 },
337
338 /**
339 *
340 *
341 *
342 *
343 */
344 _onmanagebackups : function() {
345 // Server request.
346 var requestData = {
347 // Thick box parameters.
348 width : 480,
349 height: 400,
350 TB_iframe : true // Must be last one Thickbox removes this and later params.
351 };
352 var url = CJTBlocksPage.server.getRequestURL('blocksBackups', 'list', requestData);
353 tb_show(CJTBlocksPageI18N.manageBackupsDialogTitle, url);
354 },
355
356 /**
357 * put your comment there...
358 *
359 */
360 _onrestore : function() {
361 // Confirm restore.
362 var doRestore = confirm(CJTBlocksPageI18N.confirmRestoreBlocks);
363 if (doRestore) {
364 // Disable restore button for all toolboxes.
365 var ibCancelRestore = CJTBlocksPage.toolboxes.getIButton('cancel-restore', 'enable', [false]);
366 // SHow loading for restore buttons.
367 var ibRestoreLoader = CJTBlocksPage.toolboxes.getIButton('restore', 'loading', [true, false]);
368 // Send request to server.
369 var requestData = {backupId : CJTBlocksPage.isRestore()};
370 CJTBlocksPage.server.send('blocksBackups', 'restore', requestData)
371 .success(
372 function() {
373 // Refresh the page without backupId parameter.
374 CJTBlocksPage._oncancelrestore();
375 }
376 )
377 .error(
378 function() {
379 // Notify user error.
380 alert(CJTBlocksPageI18N.unableToRestoreBackup);
381 // Stop loading progress.
382 ibCancelRestore.dispatch([true]);
383 ibRestoreLoader.dispatch([false, true]);
384 }
385 );
386 }
387 },
388
389 /**
390 *
391 *
392 *
393 *
394 */
395 _onsavechanges : function() {
396 var multiOperationServer = CJTBlocksPage.server.multiOperation;
397 var data = {
398 deletedBlocks : CJTBlocksPage.deletedBlocks,
399 calculatePinPoint : 1,
400 createRevision : 1
401 };
402 // Save block data.
403 multiOperationServer.trigger('save').send('post', data).success(
404 function() {
405 // Reset deleted blocks array.
406 CJTBlocksPage.deletedBlocks = [];
407 CJTBlocksPage.changes = [];
408 CJTBlocksPage.toolboxes.enable('save-changes', false);
409 // Save blocks order.
410 CJTBlocksPage.saveBlocksOrder();
411 // Save closed postboxes.
412 postboxes.save_state(CJTBlocksPage.pageId);
413 }
414 )
415 },
416
417 /**
418 *
419 *
420 *
421 *
422 */
423 _onswitchflag : function(event, params) {
424 var multiOperationServer = CJTBlocksPage.server.multiOperation;
425 var eventName = 'switch' + params.flag.ucFirst();
426 // First queue blocks flag.
427 multiOperationServer.trigger(eventName, params)
428 // Second send all queued stack to sgerver.
429 .send('post');
430 },
431
432 /**
433 *
434 *
435 *
436 *
437 */
438 _ontoggle : function(event, params) {
439 // Show or Hide blocks.
440 var blocks = CJTBlocksPage.blocks.getBlocks();
441 switch (params.state) {
442 case false:
443 // Close postboxes.
444 blocks.addClass('closed');
445 break;
446 case true:
447 // Open postboxes.
448 blocks.removeClass('closed');
449 // Notify postbox opened.
450 blocks.each(function() {this.CJTBlock._onpostboxopened();});
451 break;
452 }
453 // Save (batch) state.
454 postboxes.save_state('cjtoolbox');
455 },
456
457 /**
458 * put your comment there...
459 *
460 */
461 _onupdateorder : function() {
462 var container = CJTBlocksPage.blocksContainer;
463 var orders = container.data('cjtOrders');
464 var newOrders = container.sortable('toArray');
465 var isChanged = (orders.join('') != newOrders.join(''));
466 // Notify changes!
467 CJTBlocksPage.blockContentChanged(0, isChanged);
468 },
469
470 /**
471 *
472 *
473 *
474 *
475 *
476 */
477 _onunload : function() {
478 // If there is any deleted blocks or any block changed
479 // notify user that there is a change need to be saved;
480 if (!CJTBlocksPage.deletedBlocks.length) {
481 // If there is no changes in any block save-changed button shouild be disabled.
482 if (!CJTBlocksPage.toolboxes.isEnabled('save-changes')) {
483 return;
484 }
485 }
486 return CJTBlocksPageI18N.confirmNotSavedChanges;
487 },
488
489 /**
490 *
491 *
492 *
493 */
494 addBlock : function(position, content) {
495 var sortable = CJTBlocksPage.blocksContainer;
496 // New Block positions to jQuery methods mapping.
497 var positions = {top : 'prepend', bottom : 'append'};
498 var positionMethod = positions[position];
499 // Apply toggling: The only way to apply postboxes it via postboxes.add_postbox_toggles method.
500 // Method finding all .postbox elements and bind to click.
501 // Exists .postbox(s) will bind to click event twice and the result is
502 // not toggling. We need to remove .postbox of exists and apply only
503 // to the newly added one.
504 var currentBlocks = CJTBlocksPage.blocks.getBlocks();
505 currentBlocks.removeClass('postbox').addClass('applying-postbox-to-new-block');
506 // Add block to the selected position.
507 sortable[positionMethod](content);
508 // Note: Only new block will be returned because its the only one with .postbox class.
509 var newAddedBlock = CJTBlocksPage.blocks.getBlocks().eq(0);
510 // Add block element.
511 var blockId =newAddedBlock.CJTBlock({}).get(0).CJTBlock.block.get('id');
512 // SET ORDER: Add the new block as first or last Block without saving the unsave orders! //
513 // JUST USE THE CURRENT HASHED (SAVED ON SERVER) + ADDING THE NEW BLOCK!
514 var newBlockOrderName = CJTBlocksPage.blocks.getSortableName(blockId);
515 var order = $.merge([], sortable.data('cjtOrders'));
516 (position == 'top') ? order.unshift(newBlockOrderName) : order.push(newBlockOrderName);
517 CJTBlocksPage.saveCustomOrder(order);
518 // If this is the first block hide the intro and show normal sortable.
519 if (!CJTBlocksPage.blocks.hasBlocks()) {
520 // Remove intro text.
521 CJTBlocksPage.intro.css({display : 'none'});
522 CJTBlocksPage.blocksContainer.css({display : 'block'});
523 // Set has block value.
524 CJTBlocksPage.blocks.hasBlocks(true);
525 }
526 // Refresh toggling.
527 postboxes.add_postbox_toggles('cjtoolbox');
528 currentBlocks.removeClass('applying-postbox-to-new-block').addClass('postbox');
529 // Put new block into focus.
530 newAddedBlock.get(0).CJTBlock.focus();
531 return newAddedBlock;
532 },
533
534 /**
535 *
536 *
537 *
538 *
539 *
540 */
541 blockContentChanged : function(id, isChanged) {
542 var enable = CJTBlocksPage.blocks.calculateChanges(CJTBlocksPage.changes, id, isChanged);
543 // Enable/Disable save button in all Toolboxes.
544 CJTBlocksPage.toolboxes.enable('save-changes', enable);
545 },
546
547 /**
548 *
549 *
550 *
551 */
552 deleteBlocks : function(blocks) {
553 // Delete block.
554 $.each(blocks,
555 function(index, block) {
556 var blockPlg = block.CJTBlock;
557 var blockId = blockPlg.block.get('id');
558 CJTBlocksPage.deletedBlocks.push(blockId);
559 // Notify Menu and Code Files Manager.
560 // Only for Loaded Blocks.
561 blockPlg.menu && blockPlg.menu.ondeleteblock();
562 blockPlg.codeFile && blockPlg.codeFile.ondeleteblock();
563 $(block).remove();
564 // Notify save change.
565 CJTBlocksPage.blockContentChanged(blockId, true);
566 }
567 );
568 // If last block call _ondeleteall.
569 var existsBlocks = CJTBlocksPage.blocks.getBlocks();
570 if (existsBlocks.length == 0) {
571 CJTBlocksPage.blocksContainer.css('display', 'none');
572 CJTBlocksPage.intro.css('display', 'block');
573 // Mark as has no blocks.
574 CJTBlocksPage.blocks.hasBlocks(false);
575 }
576 },
577
578 /*
579 *
580 *
581 *
582 */
583 getStateName : function() {
584 var stateName = this.isRestore() ? 'restore' : '';
585 return stateName;
586 },
587
588 /*
589 *
590 *
591 *
592 */
593 init : function() {
594 // Initialize object vars.
595 CJTBlocksPage.blocksForm = $('#cjtoolbox-blocks-page-form');
596 // Prevent form submission, ALL is done through AJAX.
597 // Pressing Enter in text fields might caused the whole page to be refreshed.
598 CJTBlocksPage.blocksForm.get(0).onsubmit = function() {return false;}
599 CJTBlocksPage.blocksContainer = $('div#normal-sortables');
600 CJTBlocksPage.intro = CJTBlocksPage.blocksForm.find('#cjt-noblocks-intro');
601 CJTBlocksPage.server = CJTServer;
602 CJTBlocksPage.server.multiOperation = new CJTBlocksAjaxMultiOperations('blocksPage', 'save_blocks');
603 // Initilize Global-Blocks Conponents.
604 CJTBlockMenuView.initialize();
605 CJTBlockCodeFileView.initialize();
606 // Make sure CJTBlocks is ready.
607 CJTBlocksPage.blocks = new CJTBlocks();
608 // Initialize Toolboxes.
609 CJTBlocksPage.toolboxes.toolboxes = CJTBlocksPage.blocksForm.find('.cjt-toolbox-blocks').CJTToolBox({
610 handlers : {
611 'state-tools' : {
612 type : 'Popup',
613 params : {_type : {targetElement : '.state-tools'}}
614 },
615 'location-tools' : {
616 type : 'Popup',
617 params : {_type : {targetElement : '.location-tools'}}
618 },
619 'admin-tools' : {
620 type : 'Popup',
621 params : {_type : {targetElement : '.admin-tools'}}
622 },
623 'save-changes' : {callback : CJTBlocksPage._onsavechanges, params : {enable : false}},
624 'add-block' : {callback : CJTBlocksPage._onaddnew},
625 'restore' : {callback : CJTBlocksPage._onrestore},
626 'cancel-restore' : {callback : CJTBlocksPage._oncancelrestore},
627 'delete-all' : {callback : CJTBlocksPage._ondeleteall},
628 'delete-empty' : {callback : CJTBlocksPage._ondeleteempty},
629 'reset-order' : {callback : CJTBlocksPage._onresetorder},
630 'manage-backups' : {callback : CJTBlocksPage._onmanagebackups},
631 'footer-all' : {callback : CJTBlocksPage._onswitchflag, params : {flag : 'location', newValue : 'footer'}},
632 'header-all' : {callback : CJTBlocksPage._onswitchflag, params : {flag : 'location', newValue : 'header'}},
633 'activate-all' : {callback : CJTBlocksPage._onswitchflag, params : {flag : 'state', newValue : 'active'}},
634 'deactivate-all' : {callback : CJTBlocksPage._onswitchflag, params : {flag : 'state', newValue : 'inactive'}},
635 'revert-state' : {callback : CJTBlocksPage._onswitchflag, params : {flag : 'state'}},
636 'templates-manager' : {callback : CJTBlocksPage._onmanagetemplates},
637 'global-settings' : {callback : CJTBlocksPage._onmanagesettings},
638 'close-all' : {callback : CJTBlocksPage._ontoggle, params : {state: false}},
639 'open-all' : {callback : CJTBlocksPage._ontoggle, params : {state : true}}
640 }
641 });
642 // Activate blocks.
643 CJTBlocksPage.blocks.getBlocks().CJTBlock({state : CJTBlocksPage.getStateName()});
644 // Hide loading image. #cjt-blocks-loader will be used for other loading later.
645 CJTBlocksPage.loadingImage = CJTBlocksPage.blocksForm.find('#cjt-blocks-loader');
646 CJTBlocksPage.loadingImage.find('.loading-text').remove();
647 CJTBlocksPage.loadingImage.css({
648 display : 'none',
649 position : 'absolute'
650 });
651 // If has no blocks hide normal sortable (it takes 50px as min-height).
652 if (!CJTBlocksPage.blocks.hasBlocks()) {
653 CJTBlocksPage.blocksContainer.css({display : 'none'});
654 }
655 // Show blocks.
656 CJTBlocksPage.blocksForm.find('#post-body').css('display', 'block');
657 //// Setup postboxes ////
658 postboxes.add_postbox_toggles('cjtoolbox');
659 // Cache blocks order to detect order change!
660 CJTBlocksPage.blocksContainer.data('cjtOrders', CJTBlocksPage.blocksContainer.sortable('toArray'));
661 // Detect order change.
662 CJTBlocksPage.blocksContainer.sortable('option', {update: CJTBlocksPage._onupdateorder});
663 // Stop auto save order, orders should be saved only with "Save All Changes" button.
664 // Move it to another method that allow us to save order later manually.
665 postboxes.manual_save_order = postboxes.save_order;
666 postboxes.save_order = function() {};
667 // Notify block when postbox get opened.
668 postboxes.pbshow = function(id) {
669 $('#' + id).get(0).CJTBlock._onpostboxopened();
670 };
671 // When navigating away notify saving changes.
672 window.onbeforeunload = CJTBlocksPage._onunload;
673 // Switch blocks page state.
674 CJTBlocksPage.switchState(CJTBlocksPage.getStateName());
675 },
676
677 /*
678 *
679 *
680 *
681 */
682 isRestore : function() {
683 // If there is backupId parameter then this is a restore state.
684 var regEx = /backupId=(\d+)/;
685 var backupId = false;
686 if (regEx.test(window.location.href)) {
687 backupId = parseInt(window.location.href.match(regEx)[1]);
688 }
689 return backupId;
690 },
691
692 /*
693 *
694 *
695 *
696 */
697 main : function() {
698 // Add indexOf function for IE7.
699 if (Array.indexOf == undefined) {
700 Array.prototype.indexOf = function(value) {
701 var index = -1;
702 var array = this;
703 jQuery.each(array, function(sIndex, sValue) {
704 if (sValue == value) {
705 index = sIndex;
706 return;
707 }
708 });
709 return index;
710 }
711 }
712 if (String.ucFirst == undefined) {
713 String.prototype.ucFirst = function() {
714 var newString = [];
715 var words = this.split(' ');
716 $(words).each(
717 function(index, word) {
718 newString.push(word.substr(0, 1).toUpperCase() + word.substr(1));
719 }
720 )
721 newString = newString.join(' ');
722 return newString;
723 }
724 }
725 // Initialize CJTBlocks page vars and ui.
726 jQuery(document).ready(CJTBlocksPage.init);
727 },
728
729 /**
730 *
731 */
732 saveCustomOrder : function(order) {
733 // Override jquery sortable plugin!!
734 // We need to handle toArray method when called by postboxes.save_order method!
735 var originalSortable = $.fn.sortable;
736 $.fn.sortable = function(method) {
737 if (method != 'toArray') {
738 throw 'Dummy CJT::jquery.sortable Plugin: only toArray method is supported!';
739 }
740 // Return the passed order instead of the real order!
741 return order;
742 }
743 // Save order.
744 CJTBlocksPage.saveBlocksOrder();
745 // Reset original sortable!
746 $.fn.sortable = originalSortable;
747 },
748
749 /**
750 *
751 *
752 *
753 *
754 *
755 */
756 saveBlocksOrder : function() {
757 var ordersArray = CJTBlocksPage.blocksContainer.sortable('toArray');
758 var request = {order : ordersArray.join(',')};
759 // Save Blocks order!
760 CJTBlocksPage.server.send('blocksPage', 'saveOrder', request).success($.proxy(
761 function() {
762 // Refresh local cache order!
763 CJTBlocksPage.blocksContainer.data('cjtOrders', ordersArray);
764 }, this)
765 );
766 },
767
768 /*
769 *
770 *
771 *
772 */
773 switchState : function(state) {
774 // For now only toolboxes need to switch state.
775 CJTBlocksPage.toolboxes.switchState(state);
776 }
777
778 } // End class.
779
780 // This is the entry point to all Javascript codes.
781 CJTBlocksPage.main();
782
783 })(jQuery); // Dont wait for document to be loaded.