diff --git a/js/common.js b/js/common.js
index 5bd674fc06..c61cd6b2cc 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();
}
@@ -74,10 +77,10 @@ var PMA_commonParams = (function () {
if (params[name] !== undefined && params[name] !== value) {
PMA_querywindow.refresh();
}
- if(name == 'db' && value !== '') {
- PMA_autoExpandDatabaseInUse(params['db'], value);
- }
params[name] = value;
+ if(name == 'db' || name == 'table') {
+ PMA_showCurrentNavigation();
+ }
return this;
},
/**
@@ -114,10 +117,8 @@ 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_showCurrentNavigation();
PMA_querywindow.refresh();
}
},
diff --git a/js/navigation.js b/js/navigation.js
index 74848515f7..31fb3c19cf 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();
});
@@ -156,54 +164,42 @@ $(function() {
event.preventDefault();
PMA_createViewDialog($(this));
});
+
+ 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');
- if($icon.siblings('.throbber').length <= 0) {
- var $throbber = $('#pma_navigation .throbber')
- .first()
- .clone()
- .css('visibility', 'visible');
- $icon.hide();
- $throbber.insertBefore($icon);
- }
+ var $throbber = $('#pma_navigation .throbber')
+ .first()
+ .clone()
+ .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')
@@ -213,18 +209,20 @@ function PMA_expandNavigationTree($expandElem) {
.find('a.expander.container')
.click();
}
+ if (callback && typeof callback == 'function') {
+ callback.call();
+ }
} else {
PMA_ajaxShowMessage(data.error, false);
}
$icon.show();
- if($icon.siblings('.throbber').length)
- $icon.siblings('.throbber').remove();
+ $throbber.remove();
});
}
$expandElem.blur();
}
-/*
+/**
* Auto-scrolls the newly chosen database
*
* @param object $element The element to set to view
@@ -242,36 +240,224 @@ 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'));
- }, 200);
+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) {
+ 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
+ );
+ }
+ }
}
/**
@@ -323,13 +509,17 @@ function PMA_reloadNavigation(callback) {
});
var url = $('#pma_navigation').find('a.navigation_url').attr('href');
$.post(url, params, function (data) {
+ // 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();
}
- PMA_autoExpandDatabaseInUse('', PMA_commonParams.get('db'));
} else {
PMA_ajaxShowMessage(data.error);
}
diff --git a/libraries/navigation/NavigationTree.class.php b/libraries/navigation/NavigationTree.class.php
index bb6e1d1d4f..24eaf93312 100644
--- a/libraries/navigation/NavigationTree.class.php
+++ b/libraries/navigation/NavigationTree.class.php
@@ -881,7 +881,6 @@ class PMA_NavigationTree
$retval .= "";
}
- $dblinkclass = ' class="dbLink"';
$linkClass = '';
$haveAjax = array(
'functions',
@@ -933,7 +932,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 45ff0c12a0..ba823dd281 100644
--- a/libraries/navigation/Nodes/Node_Database.class.php
+++ b/libraries/navigation/Nodes/Node_Database.class.php
@@ -35,6 +35,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 08d620888f..b27e0da8c8 100644
--- a/libraries/navigation/Nodes/Node_Table.class.php
+++ b/libraries/navigation/Nodes/Node_Table.class.php
@@ -38,6 +38,7 @@ class Node_Table extends Node
. '?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 3d3ef146d1..0efa9fc116 100644
--- a/libraries/navigation/Nodes/Node_Table_Container.class.php
+++ b/libraries/navigation/Nodes/Node_Table_Container.class.php
@@ -35,7 +35,8 @@ class Node_Table_Container extends Node
$this->separator = $GLOBALS['cfg']['NavigationTreeTableSeparator'];
$this->separator_depth = (int)($GLOBALS['cfg']['NavigationTreeTableLevel']);
}
- $this->real_name = 'tables';
+ $this->real_name = 'tables';
+ $this->classes = 'tableContainer';
$new = PMA_NodeFactory::getInstance('Node', _pgettext('Create new table', 'New'));
$new->isNew = true;
diff --git a/libraries/navigation/Nodes/Node_View.class.php b/libraries/navigation/Nodes/Node_View.class.php
index 3f47579a7e..f9d3cfcb6c 100644
--- a/libraries/navigation/Nodes/Node_View.class.php
+++ b/libraries/navigation/Nodes/Node_View.class.php
@@ -38,6 +38,7 @@ class Node_View extends Node
. '&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 ada9027ff4..39544fb177 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('Node', _pgettext('Create new view', 'New'));
diff --git a/themes/original/css/navigation.css.php b/themes/original/css/navigation.css.php
index 0d88478d25..fd91206d9c 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 ul {
clear: both;
padding: 0;
diff --git a/themes/pmahomme/css/navigation.css.php b/themes/pmahomme/css/navigation.css.php
index 7d30f11e14..0d747f73da 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 ul {
clear: both;
padding: 0;