Translated using Weblate (Slovenian)
[phpmyadmin.git] / js / menu-resizer.js
blob392f94be34909a750ebcf47450b56e3dcf78a1a5
1 /* vim: set expandtab sw=4 ts=4 sts=4: */
2 /**
3  * Handles the resizing of a menu according to the available screen width
4  *
5  * Uses themes/original/css/resizable-menu.css.php
6  *
7  * To initialise:
8  * $('#myMenu').menuResizer(function () {
9  *     // This function will be called to find out how much
10  *     // available horizontal space there is for the menu
11  *     return $('body').width() - 5; // Some extra margin for good measure
12  * });
13  *
14  * To trigger a resize operation:
15  * $('#myMenu').menuResizer('resize'); // Bind this to $(window).resize()
16  *
17  * To restore the menu to a state like before it was initialized:
18  * $('#myMenu').menuResizer('destroy');
19  *
20  * @package PhpMyAdmin
21  */
22 (function ($) {
23     function MenuResizer($container, widthCalculator) {
24         var self = this;
25         self.$container = $container;
26         self.widthCalculator = widthCalculator;
27         // create submenu container
28         var link = $('<a />', {href: '#', 'class': 'tab nowrap'})
29             .text(PMA_messages.strMore)
30             .bind('click', false); // same as event.preventDefault()
31         var img = $container.find('li img');
32         if (img.length) {
33             $(PMA_getImage('b_more.png').toString()).prependTo(link);
34         }
35         var $submenu = $('<li />', {'class': 'submenu'})
36             .append(link)
37             .append($('<ul />'))
38             .mouseenter(function() {
39                 if ($(this).find('ul .tabactive').length === 0) {
40                     $(this)
41                     .addClass('submenuhover')
42                     .find('> a')
43                     .addClass('tabactive');
44                 }
45             })
46             .mouseleave(function() {
47                 if ($(this).find('ul .tabactive').length === 0) {
48                     $(this)
49                     .removeClass('submenuhover')
50                     .find('> a')
51                     .removeClass('tabactive');
52                 }
53             });
54         $container.children('.clearfloat').remove();
55         $container.append($submenu).append("<div class='clearfloat'></div>");
56         setTimeout(function () {
57             self.resize();
58         }, 4);
59     }
60     MenuResizer.prototype.resize = function () {
61         var wmax = this.widthCalculator.call(this.$container);
62         var $submenu = this.$container.find('.submenu:last');
63         var submenu_w = $submenu.outerWidth(true);
64         var $submenu_ul = $submenu.find('ul');
65         var $li = this.$container.find('> li');
66         var $li2 = $submenu_ul.find('li');
67         var more_shown = $li2.length > 0;
68         // Calculate the total width used by all the shown tabs
69         var total_len = more_shown ? submenu_w : 0;
70         var l = $li.length - 1;
71         var i;
72         for (i = 0; i < l; i++) {
73             total_len += $($li[i]).outerWidth(true);
74         }
75         // Now hide menu elements that don't fit into the menubar
76         var hidden = false; // Whether we have hidden any tabs
77         while (total_len >= wmax && --l >= 0) { // Process the tabs backwards
78             hidden = true;
79             var el = $($li[l]);
80             var el_width = el.outerWidth(true);
81             el.data('width', el_width);
82             if (! more_shown) {
83                 total_len -= el_width;
84                 el.prependTo($submenu_ul);
85                 total_len += submenu_w;
86                 more_shown = true;
87             } else {
88                 total_len -= el_width;
89                 el.prependTo($submenu_ul);
90             }
91         }
92         // If we didn't hide any tabs, then there might be some space to show some
93         if (! hidden) {
94             // Show menu elements that do fit into the menubar
95             for (i = 0, l = $li2.length; i < l; i++) {
96                 total_len += $($li2[i]).data('width');
97                 // item fits or (it is the last item
98                 // and it would fit if More got removed)
99                 if (total_len < wmax ||
100                     (i == $li2.length - 1 && total_len - submenu_w < wmax)
101                 ) {
102                     $($li2[i]).insertBefore($submenu);
103                 } else {
104                     break;
105                 }
106             }
107         }
108         // Show/hide the "More" tab as needed
109         if ($submenu_ul.find('li').length > 0) {
110             $submenu.addClass('shown');
111         } else {
112             $submenu.removeClass('shown');
113         }
114         if (this.$container.find('> li').length == 1) {
115             // If there is only the "More" tab left, then we need
116             // to align the submenu to the left edge of the tab
117             $submenu_ul.removeClass().addClass('only');
118         } else {
119             // Otherwise we align the submenu to the right edge of the tab
120             $submenu_ul.removeClass().addClass('notonly');
121         }
122         if ($submenu.find('.tabactive').length) {
123             $submenu
124             .addClass('active')
125             .find('> a')
126             .removeClass('tab')
127             .addClass('tabactive');
128         } else {
129             $submenu
130             .removeClass('active')
131             .find('> a')
132             .addClass('tab')
133             .removeClass('tabactive');
134         }
135     };
136     MenuResizer.prototype.destroy = function () {
137         var $submenu = this.$container.find('li.submenu').removeData();
138         $submenu.find('li').appendTo(this.$container);
139         $submenu.remove();
140     };
142     /** Public API */
143     var methods = {
144         init: function(widthCalculator) {
145             return this.each(function () {
146                 var $this = $(this);
147                 if (! $this.data('menuResizer')) {
148                     $this.data(
149                         'menuResizer',
150                         new MenuResizer($this, widthCalculator)
151                     );
152                 }
153             });
154         },
155         resize: function () {
156             return this.each(function () {
157                 var self = $(this).data('menuResizer');
158                 if (self) {
159                     self.resize();
160                 }
161             });
162         },
163         destroy: function () {
164             return this.each(function () {
165                 var self = $(this).data('menuResizer');
166                 if (self) {
167                     self.destroy();
168                 }
169             });
170         }
171     };
173     /** Extend jQuery */
174     $.fn.menuResizer = function(method) {
175         if (methods[method]) {
176             return methods[method].call(this);
177         } else if (typeof method === 'function') {
178             return methods.init.apply(this, [method]);
179         } else {
180             $.error('Method ' +  method + ' does not exist on jQuery.menuResizer');
181         }
182     };
183 })(jQuery);