diff --git a/js/common.js b/js/common.js index f7405b7a8e..960eede667 100644 --- a/js/common.js +++ b/js/common.js @@ -37,16 +37,19 @@ var PMA_commonParams = (function () { */ setAll: function (obj) { var reload = false; + var updateNavigation = false; for (var i in obj) { if (params[i] !== undefined && params[i] !== obj[i]) { reload = true; } - // To expand the database in use and collapse the previous one - if(i == 'db' && obj[i] !== '') { - PMA_autoExpandDatabaseInUse(params['db'], obj[i]); + if (i == 'db' || i == 'table') { + updateNavigation = true; } params[i] = obj[i]; } + if (updateNavigation) { + PMA_showCurrentNavigation(); + } if (reload) { PMA_querywindow.refresh(); } @@ -75,10 +78,10 @@ var PMA_commonParams = (function () { PMA_querywindow.refresh(); PMA_reloadNavigation(); } - if(name == 'db' && value !== '') { - PMA_autoExpandDatabaseInUse(params['db'], value); - } params[name] = value; + if (name == 'db' || name == 'table') { + PMA_showCurrentNavigation(); + } return this; }, /** @@ -115,11 +118,7 @@ var PMA_commonActions = { */ setDb: function (new_db) { if (new_db != PMA_commonParams.get('db')) { - if(new_db !== '') { - PMA_autoExpandDatabaseInUse(PMA_commonParams.get('db'), new_db); - } - PMA_commonParams.set('db', new_db); - PMA_querywindow.refresh(); + PMA_commonParams.setAll({'db': new_db, 'table': ''}); } }, /** diff --git a/js/navigation.js b/js/navigation.js index dd0821924f..bdb2b2cd7d 100644 --- a/js/navigation.js +++ b/js/navigation.js @@ -29,7 +29,12 @@ $(function () { $('#pma_navigation_tree a.expander').live('click', function (event) { event.preventDefault(); event.stopImmediatePropagation(); - PMA_expandNavigationTree($(this)); + var $icon = $(this).find('img'); + if ($icon.is('.ic_b_plus')) { + expandTreeNode($(this)); + } else { + collapseTreeNode($(this)); + } }); /** @@ -38,6 +43,9 @@ $(function () { */ $('#pma_navigation_reload').live('click', function (event) { event.preventDefault(); + $('#pma_navigation .throbber') + .first() + .css('visibility', 'visible'); PMA_reloadNavigation(); }); @@ -223,52 +231,42 @@ $(function () { } }); }); + + PMA_showCurrentNavigation(); }); /** - * Expands/collapses the navigation tree and sets to view the expanded + * Expands a node in navigation tree. * - * @param object $expandElem the element that initiated the expanding - * @return void + * @param $expandElem expander + * @param callback callback function + * + * @returns void */ -function PMA_expandNavigationTree($expandElem) { +function expandTreeNode($expandElem, callback) +{ var $children = $expandElem.closest('li').children('div.list_container'); var $icon = $expandElem.find('img'); if ($expandElem.hasClass('loaded')) { if ($icon.is('.ic_b_plus')) { $icon.removeClass('ic_b_plus').addClass('ic_b_minus'); $children.show('fast'); - } else { - $icon.removeClass('ic_b_minus').addClass('ic_b_plus'); - $children.hide('fast'); + } + if (callback && typeof callback == 'function') { + callback.call(); } } else { - var $destination = $expandElem.closest('li'); var $throbber = $('#pma_navigation .throbber') .first() .clone() - .css('visibility', 'visible'); + .css('visibility', 'visible') + .click(false); $icon.hide(); $throbber.insertBefore($icon); - var searchClause = PMA_fastFilter.getSearchClause(); - var searchClause2 = PMA_fastFilter.getSearchClause2($expandElem); - - var params = { - aPath: $expandElem.find('span.aPath').text(), - vPath: $expandElem.find('span.vPath').text(), - pos: $expandElem.find('span.pos').text(), - pos2_name: $expandElem.find('span.pos2_name').text(), - pos2_value: $expandElem.find('span.pos2_value').text(), - searchClause: searchClause, - searchClause2: searchClause2 - }; - var url = $('#pma_navigation').find('a.navigation_url').attr('href'); - $.get(url, params, function (data) { + loadChildNodes($expandElem, function(data) { if (data.success === true) { - $expandElem.addClass('loaded'); - $destination.find('div.list_container').remove(); // FIXME: Hack, there shouldn't be a list container there - $destination.append(data.message); + var $destination = $expandElem.closest('li'); $icon.removeClass('ic_b_plus').addClass('ic_b_minus'); $destination .children('div.list_container') @@ -278,6 +276,9 @@ function PMA_expandNavigationTree($expandElem) { .find('a.expander.container') .click(); } + if (callback && typeof callback == 'function') { + callback.call(); + } } else { PMA_ajaxShowMessage(data.error, false); } @@ -288,7 +289,7 @@ function PMA_expandNavigationTree($expandElem) { $expandElem.blur(); } -/* +/** * Auto-scrolls the newly chosen database * * @param object $element The element to set to view @@ -302,36 +303,227 @@ function scrollToView($element, $container) { }); } -/* - * Auto-expands the newly chosen database +/** + * Collapses a node in navigation tree. * - * @param string $oldDb The previous database - * @param string $newDb The newly chosen database + * @param $expandElem expander * + * @returns void */ -function PMA_autoExpandDatabaseInUse($oldDb, $newDb) { - var $expandElem, $icon; - //Collapse the previous database - if($oldDb !== '' && $oldDb !== $newDb) { - $expandElem = $('#pma_navigation_tree a.dbLink:contains("' + $oldDb + '")') - .parent().find('a.expander').eq(0); - $icon = $expandElem.find('img'); - if ($icon.is('.ic_b_minus')) - PMA_expandNavigationTree($expandElem); - } - //expand the newly chosen database - $expandElem = $('#pma_navigation_tree a.dbLink:contains("' + $newDb + '")') - .parent().find('a.expander').eq(0); - $icon = $expandElem.find('img'); - if ($icon.is('.ic_b_plus')) { - PMA_expandNavigationTree($expandElem); - } - //scroll to new database - if ($oldDb !== $newDb) { - setTimeout(function() { - scrollToView($expandElem.closest('li'), $('#pma_navigation_tree_content')); - }, 150); +function collapseTreeNode($expandElem) { + var $children = $expandElem.closest('li').children('div.list_container'); + var $icon = $expandElem.find('img'); + if ($expandElem.hasClass('loaded')) { + if ($icon.is('.ic_b_minus')) { + $icon.removeClass('ic_b_minus').addClass('ic_b_plus'); + $children.hide('fast'); + } } + $expandElem.blur(); +} + +/** + * Loads child items of a node and executes a given callback + * + * @param $expandElem expander + * @param callback callback function + * + * @returns void + */ +function loadChildNodes($expandElem, callback) { + var $destination = $expandElem.closest('li'); + + var searchClause = PMA_fastFilter.getSearchClause(); + var searchClause2 = PMA_fastFilter.getSearchClause2($expandElem); + + var params = { + aPath: $expandElem.find('span.aPath').text(), + vPath: $expandElem.find('span.vPath').text(), + pos: $expandElem.find('span.pos').text(), + pos2_name: $expandElem.find('span.pos2_name').text(), + pos2_value: $expandElem.find('span.pos2_value').text(), + searchClause: searchClause, + searchClause2: searchClause2 + }; + + var url = $('#pma_navigation').find('a.navigation_url').attr('href'); + $.get(url, params, function (data) { + if (data.success === true) { + $expandElem.addClass('loaded'); + $destination.find('div.list_container').remove(); // FIXME: Hack, there shouldn't be a list container there + $destination.append(data.message); + if (callback && typeof callback == 'function') { + callback(data); + } + } + }); +} + +/** + * Expand the navigation and highlight the current database or table/view + * + * @returns void + */ +function PMA_showCurrentNavigation() +{ + var db = PMA_commonParams.get('db'); + var table = PMA_commonParams.get('table'); + $('#pma_navigation_tree') + .find('li.selected') + .removeClass('selected'); + if (db && table) { // if we are at the table/view level + // open the database in the tree + var $dbItem = highlightLoadedItem( + $('#pma_navigation_tree > div'), db, 'database', false, false + ); + // open the table in the tree and select it + var $expander = $dbItem.children('div:first').children('a.expander'); + // if not loaded or loaded but collapsed + if (! $expander.hasClass('loaded') + || $expander.find('img').is('.ic_b_plus') + ) { + expandTreeNode($expander, function() { + loadAndHighlightTableOrView($dbItem, table); + }); + } else { + loadAndHighlightTableOrView($dbItem, table); + } + } else if (db) { // if we are at the database level + // open in the tree and select the database + highlightLoadedItem( + $('#pma_navigation_tree > div'), db, 'database', true, true + ); + } + + function highlightLoadedItem($container, name, clazz, doSelect, doOpen) { + var ret = false; + $container.children('ul').children('li').each(function() { + var $li = $(this); + // this is a navigation group, recurse + if ($li.is('.navGroup')) { + var $container = $li.children('div.list_container'); + var $childRet = highlightLoadedItem( + $container, name, clazz, doSelect, doOpen + ); + if ($childRet) { + ret = $childRet; + return false; + } + } else { // this is a real navigation item + // name and class matches + if ($li.is('.' + clazz) && $li.children('a').text() == name) { + if (doSelect) { + $li.addClass('selected'); + if (! doOpen) { // if the node will be opened no point scrolling now + scrollToView($li, $('#pma_navigation_tree_content')); + } + } + if (doOpen) { + var $expander = $li.find('div:first').children('a.expander'); + if ($expander.length > 0) { + expandTreeNode($expander, function() { + scrollToView($li, $('#pma_navigation_tree_content')); + }); + } + } + // taverse up and expand and parent navigation groups + $li.parents('.navGroup').each(function() { + $cont = $(this).children('div.list_container'); + if (! $cont.is(':visible')) { + $(this) + .children('div:first') + .children('a.expander') + .click(); + } + }); + ret = $li; + return false; + } + } + }); + return ret; + } + + function loadAndHighlightTableOrView($dbItem, table) { + var $container = $dbItem.children('div.list_container'); + var $tableContainer = $container + .children('ul') + .children('li.tableContainer'); + var $viewContainer = $container + .children('ul') + .children('li.viewContainer'); + + if ($tableContainer.length > 0) { + var $expander = $tableContainer + .children('div:first') + .children('a.expander'); + + if (! $expander.hasClass('loaded') ) { + loadChildNodes($expander, function(data) { + highlightTableOrView($tableContainer, $viewContainer, table); + }); + } else { + highlightTableOrView($tableContainer, $viewContainer, table); + } + } else if ($viewContainer.length > 0) { + highlightView($viewContainer, table); + } else { + // no containers, highlight the item + highlightLoadedItem($container, table, 'table', true, false); + } + } + + function highlightTableOrView($tableContainer, $viewContainer, table) + { + if (isItemInContainer($tableContainer, table, 'table')) { + var $expander = $tableContainer + .children('div:first') + .children('a.expander'); + if ($expander.find('img').is('.ic_b_plus')) { + expandTreeNode($expander); + } + highlightLoadedItem( + $tableContainer.children('div.list_container'), + table, 'table', true, false + ); + } else if ($viewContainer.length > 0) { + highlightView($viewContainer, table); + } + } + + function isItemInContainer($container, name, clazz) + { + $items = $container.find('li.' + clazz); + var found = false; + $items.each(function() { + if ($(this).children('a').text() == name) { + found = true; + return false; + } + }); + return found; + } + + function highlightView($viewContainer, view) { + var $expander = $viewContainer + .children('div:first') + .children('a.expander'); + if (! $expander.hasClass('loaded') + || $expander.find('img').is('.ic_b_plus') + ) { + expandTreeNode($expander, function() { + highlightLoadedItem( + $viewContainer.children('div.list_container'), + view, 'view', true, false + ); + }); + } else { + highlightLoadedItem( + $viewContainer.children('div.list_container'), + view, 'view', true, false + ); + } + } } /** @@ -389,12 +581,13 @@ function PMA_reloadNavigation(callback) { }); var url = $('#pma_navigation').find('a.navigation_url').attr('href'); $.post(url, params, function (data) { - $throbber.css('visibility', 'hidden').css({ - 'visibility' : 'hidden', - 'display' : 'none' - }); + // Hide throbber if it's visible + $('#pma_navigation .throbber') + .first() + .css('visibility', 'hidden'); if (data.success) { $('#pma_navigation_tree').html(data.message).children('div').show(); + PMA_showCurrentNavigation(); // Fire the callback, if any if (typeof callback === 'function') { callback.call(); diff --git a/js/sql.js b/js/sql.js index e6fbce7244..4062e8a081 100644 --- a/js/sql.js +++ b/js/sql.js @@ -296,8 +296,17 @@ AJAX.registerOnload('sql.js', function () { } else if (typeof data.reload != 'undefined') { // this happens if a USE or DROP command was typed PMA_commonActions.setDb(data.db); - PMA_reloadNavigation(); - PMA_commonActions.refreshMain(false, function () { + var url; + if (data.db) { + if (data.table) { + url = 'table_sql.php'; + } else { + url = 'db_sql.php'; + } + } else { + url = 'server_sql.php'; + } + PMA_commonActions.refreshMain(url, function () { if ($('#result_query').length) { $('#result_query').remove(); } diff --git a/libraries/navigation/NavigationTree.class.php b/libraries/navigation/NavigationTree.class.php index f6eb18b02a..ef7da34798 100644 --- a/libraries/navigation/NavigationTree.class.php +++ b/libraries/navigation/NavigationTree.class.php @@ -877,7 +877,6 @@ class PMA_NavigationTree $retval .= ""; } - $dblinkclass = ' class="dbLink"'; $linkClass = ''; $haveAjax = array( 'functions', @@ -922,7 +921,7 @@ class PMA_NavigationTree $retval .= htmlspecialchars($node->name); $retval .= ""; } else { - $retval .= ""; + $retval .= ""; $retval .= htmlspecialchars($node->real_name); $retval .= ""; } diff --git a/libraries/navigation/Nodes/Node_Database.class.php b/libraries/navigation/Nodes/Node_Database.class.php index 7501a0c843..f73cc745a8 100644 --- a/libraries/navigation/Nodes/Node_Database.class.php +++ b/libraries/navigation/Nodes/Node_Database.class.php @@ -37,6 +37,7 @@ class Node_Database extends Node 'icon' => 'db_operations.php?server=' . $GLOBALS['server'] . '&db=%1$s&token=' . $GLOBALS['token'] ); + $this->classes = 'database'; } /** diff --git a/libraries/navigation/Nodes/Node_Table.class.php b/libraries/navigation/Nodes/Node_Table.class.php index e97b526a69..84def2b2c9 100644 --- a/libraries/navigation/Nodes/Node_Table.class.php +++ b/libraries/navigation/Nodes/Node_Table.class.php @@ -56,6 +56,7 @@ class Node_Table extends Node_DatabaseChild . '?server=' . $GLOBALS['server'] . '&db=%2$s&table=%1$s&token=' . $GLOBALS['token'] ); + $this->classes = 'table'; } /** diff --git a/libraries/navigation/Nodes/Node_Table_Container.class.php b/libraries/navigation/Nodes/Node_Table_Container.class.php index af587ca90b..d4d2ccb091 100644 --- a/libraries/navigation/Nodes/Node_Table_Container.class.php +++ b/libraries/navigation/Nodes/Node_Table_Container.class.php @@ -37,7 +37,8 @@ class Node_Table_Container extends Node $GLOBALS['cfg']['NavigationTreeTableLevel'] ); } - $this->real_name = 'tables'; + $this->real_name = 'tables'; + $this->classes = 'tableContainer'; $new = PMA_NodeFactory::getInstance( 'Node', _pgettext('Create new table', 'New') diff --git a/libraries/navigation/Nodes/Node_View.class.php b/libraries/navigation/Nodes/Node_View.class.php index 581b34a59a..5feed1d5f1 100644 --- a/libraries/navigation/Nodes/Node_View.class.php +++ b/libraries/navigation/Nodes/Node_View.class.php @@ -40,6 +40,7 @@ class Node_View extends Node_DatabaseChild . '&db=%2$s&table=%1$s' . '&token=' . $GLOBALS['token'] ); + $this->classes = 'view'; } /** diff --git a/libraries/navigation/Nodes/Node_View_Container.class.php b/libraries/navigation/Nodes/Node_View_Container.class.php index b71d612c42..6289a33703 100644 --- a/libraries/navigation/Nodes/Node_View_Container.class.php +++ b/libraries/navigation/Nodes/Node_View_Container.class.php @@ -31,6 +31,7 @@ class Node_View_Container extends Node 'icon' => 'db_structure.php?server=' . $GLOBALS['server'] . '&db=%1$s&token=' . $GLOBALS['token'], ); + $this->classes = 'viewContainer'; $this->real_name = 'views'; $new = PMA_NodeFactory::getInstance( diff --git a/themes/original/css/navigation.css.php b/themes/original/css/navigation.css.php index 8b5d17753e..02147bc8a8 100644 --- a/themes/original/css/navigation.css.php +++ b/themes/original/css/navigation.css.php @@ -128,6 +128,10 @@ if (! defined('PMA_MINIMUM_COMMON') && ! defined('TESTSUITE')) { color: ; background-color: ; } +#pma_navigation_tree li.selected { + color: ; + background-color: ; +} #pma_navigation_tree li .dbItemControls { padding-left: 4px; } diff --git a/themes/pmahomme/css/navigation.css.php b/themes/pmahomme/css/navigation.css.php index 127f646c87..0217a498e6 100644 --- a/themes/pmahomme/css/navigation.css.php +++ b/themes/pmahomme/css/navigation.css.php @@ -113,6 +113,10 @@ if (! defined('PMA_MINIMUM_COMMON') && ! defined('TESTSUITE')) { color: ; background-color: ; } +#pma_navigation_tree li.selected { + color: ; + background-color: ; +} #pma_navigation_tree li .dbItemControls { padding-left: 4px; }