Translated using Weblate (Bulgarian)
[phpmyadmin.git] / js / menu-resizer.js
blob68a3c8fd9fa25ef4e111231476c77d2185e43b2e
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').before($submenu);
55         setTimeout(function () {
56             self.resize();
57         }, 4);
58     }
59     MenuResizer.prototype.resize = function () {
60         var wmax = this.widthCalculator.call(this.$container);
61         var $submenu = this.$container.find('.submenu:last');
62         var submenu_w = $submenu.outerWidth(true);
63         var $submenu_ul = $submenu.find('ul');
64         var $li = this.$container.find('> li');
65         var $li2 = $submenu_ul.find('li');
66         var more_shown = $li2.length > 0;
67         // Calculate the total width used by all the shown tabs
68         var total_len = more_shown ? submenu_w : 0;
69         var l = $li.length - 1;
70         for (var i = 0; i < l; i++) {
71             total_len += $($li[i]).outerWidth(true);
72         }
73         // Now hide menu elements that don't fit into the menubar
74         var hidden = false; // Whether we have hidden any tabs
75         while (total_len >= wmax && --l >= 0) { // Process the tabs backwards
76             hidden = true;
77             var el = $($li[l]);
78             var el_width = el.outerWidth(true);
79             el.data('width', el_width);
80             if (! more_shown) {
81                 total_len -= el_width;
82                 el.prependTo($submenu_ul);
83                 total_len += submenu_w;
84                 more_shown = true;
85             } else {
86                 total_len -= el_width;
87                 el.prependTo($submenu_ul);
88             }
89         }
90         // If we didn't hide any tabs, then there might be some space to show some
91         if (! hidden) {
92             // Show menu elements that do fit into the menubar
93             for (var i = 0, l = $li2.length; i < l; i++) {
94                 total_len += $($li2[i]).data('width');
95                 // item fits or (it is the last item
96                 // and it would fit if More got removed)
97                 if (total_len < wmax ||
98                     (i == $li2.length - 1 && total_len - submenu_w < wmax)
99                 ) {
100                     $($li2[i]).insertBefore($submenu);
101                 } else {
102                     break;
103                 }
104             }
105         }
106         // Show/hide the "More" tab as needed
107         if ($submenu_ul.find('li').length > 0) {
108             $submenu.addClass('shown');
109         } else {
110             $submenu.removeClass('shown');
111         }
112         if (this.$container.find('> li').length == 1) {
113             // If there is only the "More" tab left, then we need
114             // to align the submenu to the left edge of the tab
115             $submenu_ul.removeClass().addClass('only');
116         } else {
117             // Otherwise we align the submenu to the right edge of the tab
118             $submenu_ul.removeClass().addClass('notonly');
119         }
120         if ($submenu.find('.tabactive').length) {
121             $submenu
122             .addClass('active')
123             .find('> a')
124             .removeClass('tab')
125             .addClass('tabactive');
126         } else {
127             $submenu
128             .removeClass('active')
129             .find('> a')
130             .addClass('tab')
131             .removeClass('tabactive');
132         }
133     };
134     MenuResizer.prototype.destroy = function () {
135         var $submenu = this.$container.find('li.submenu').removeData();
136         $submenu.find('li').appendTo(this.$container);
137         $submenu.remove();
138     };
140     /** Public API */
141     var methods = {
142         init: function(widthCalculator) {
143             return this.each(function () {
144                 var $this = $(this);
145                 if (! $this.data('menuResizer')) {
146                     $this.data(
147                         'menuResizer',
148                         new MenuResizer($this, widthCalculator)
149                     );
150                 }
151             });
152         },
153         resize: function () {
154             return this.each(function () {
155                 var self = $(this).data('menuResizer');
156                 if (self) {
157                     self.resize();
158                 }
159             });
160         },
161         destroy: function () {
162             return this.each(function () {
163                 var self = $(this).data('menuResizer');
164                 if (self) {
165                     self.destroy();
166                 }
167             });
168         }
169     };
171     /** Extend jQuery */
172     $.fn.menuResizer = function(method) {
173         if (methods[method]) {
174             return methods[method].call(this);
175         } else if (typeof method === 'function') {
176             return methods.init.apply(this, [method]);
177         } else {
178             $.error('Method ' +  method + ' does not exist on jQuery.menuResizer');
179         }
180     };
181 })(jQuery);