1 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 * Handles the resizing of a menu according to the available screen width
5 * Uses themes/original/css/resizable-menu.css.php
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
14 * To trigger a resize operation:
15 * $('#myMenu').menuResizer('resize'); // Bind this to $(window).resize()
17 * To restore the menu to a state like before it was initialized:
18 * $('#myMenu').menuResizer('destroy');
23 function MenuResizer($container, widthCalculator) {
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');
33 $(PMA_getImage('b_more.png').toString()).prependTo(link);
35 var $submenu = $('<li />', {'class': 'submenu'})
38 .mouseenter(function() {
39 if ($(this).find('ul .tabactive').length === 0) {
41 .addClass('submenuhover')
43 .addClass('tabactive');
46 .mouseleave(function() {
47 if ($(this).find('ul .tabactive').length === 0) {
49 .removeClass('submenuhover')
51 .removeClass('tabactive');
54 $container.children('.clearfloat').remove();
55 $container.append($submenu).append("<div class='clearfloat'></div>");
56 setTimeout(function () {
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;
72 for (i = 0; i < l; i++) {
73 total_len += $($li[i]).outerWidth(true);
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
80 var el_width = el.outerWidth(true);
81 el.data('width', el_width);
83 total_len -= el_width;
84 el.prependTo($submenu_ul);
85 total_len += submenu_w;
88 total_len -= el_width;
89 el.prependTo($submenu_ul);
92 // If we didn't hide any tabs, then there might be some space to show some
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)
102 $($li2[i]).insertBefore($submenu);
108 // Show/hide the "More" tab as needed
109 if ($submenu_ul.find('li').length > 0) {
110 $submenu.addClass('shown');
112 $submenu.removeClass('shown');
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');
119 // Otherwise we align the submenu to the right edge of the tab
120 $submenu_ul.removeClass().addClass('notonly');
122 if ($submenu.find('.tabactive').length) {
127 .addClass('tabactive');
130 .removeClass('active')
133 .removeClass('tabactive');
136 MenuResizer.prototype.destroy = function () {
137 var $submenu = this.$container.find('li.submenu').removeData();
138 $submenu.find('li').appendTo(this.$container);
144 init: function(widthCalculator) {
145 return this.each(function () {
147 if (! $this.data('menuResizer')) {
150 new MenuResizer($this, widthCalculator)
155 resize: function () {
156 return this.each(function () {
157 var self = $(this).data('menuResizer');
163 destroy: function () {
164 return this.each(function () {
165 var self = $(this).data('menuResizer');
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]);
180 $.error('Method ' + method + ' does not exist on jQuery.menuResizer');