diff options
24 files changed, 1638 insertions, 65 deletions
diff --git a/browse_foreigners.php b/browse_foreigners.php index daeaf47efe..444d01f5d0 100644 --- a/browse_foreigners.php +++ b/browse_foreigners.php @@ -29,7 +29,7 @@ PMA_Util::checkParameters(array('db', 'table', 'field')); $response = PMA_Response::getInstance(); $response->getFooter()->setMinimal(); $header = $response->getHeader(); -$header->disableMenu(); +$header->disableMenuAndConsole(); $header->setBodyId('body_browse_foreigners'); /** diff --git a/import.php b/import.php index c77059acaf..89bb710ed5 100644 --- a/import.php +++ b/import.php @@ -12,6 +12,7 @@ require_once 'libraries/common.inc.php'; require_once 'libraries/sql.lib.php'; require_once 'libraries/bookmark.lib.php'; +require_once 'libraries/Console.class.php'; //require_once 'libraries/display_import_functions.lib.php'; if (isset($_REQUEST['show_as_php'])) { @@ -27,6 +28,13 @@ if (isset($_REQUEST['simulate_dml'])) { exit; } +// If it's a refresh console bookmarks request +if(isset($_GET['console_bookmark_refresh'])) { + $response = PMA_Response::getInstance(); + $response->addJSON('console_message_bookmark', PMA_Console::getBookmarkContent()); + exit; +} + /** * Sets globals from $_POST */ @@ -124,7 +132,6 @@ if (! empty($sql_query)) { // If we didn't get any parameters, either user called this directly, or // upload limit has been reached, let's assume the second possibility. -; if ($_POST == array() && $_GET == array()) { $message = PMA_Message::error( __('You probably tried to upload a file that is too large. Please refer to %sdocumentation%s for a workaround for this limit.') @@ -140,6 +147,12 @@ if ($_POST == array() && $_GET == array()) { exit; // the footer is displayed automatically } +// Add console message id to response output +if(isset($_POST['console_message_id'])) { + $response = PMA_Response::getInstance(); + $response->addJSON('console_message_id', $_POST['console_message_id']); +} + /** * Sets globals from $_POST patterns, for import plugins * We only need to load the selected plugin diff --git a/js/ajax.js b/js/ajax.js index e81eb8419c..7831448979 100644 --- a/js/ajax.js +++ b/js/ajax.js @@ -347,6 +347,7 @@ var AJAX = { .not('#pma_header') .not('#pma_footer') .not('#pma_demo') + .not('#pma_console_container') .remove(); // Replace #page_content with new content if (data.message && data.message.length > 0) { @@ -459,6 +460,9 @@ var AJAX = { $('#'+data.fieldWithError).addClass("error"); } } + if(PMA_console && PMA_console.isEnabled) { + PMA_console.ajaxCallback(data); + } }, /** * This object is in charge of downloading scripts, diff --git a/js/console.js b/js/console.js new file mode 100644 index 0000000000..02e0309f0c --- /dev/null +++ b/js/console.js @@ -0,0 +1,724 @@ +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Used in or for console + * + * @package phpMyAdmin-Console + */ + +/** + * Executed on page load + */ +$(function () { + PMA_console.initialize(); +}); + + +/** + * Console object + */ +var PMA_console = { + /** + * @var object, jQuery object, selector is '#pma_console>.content' + * @access private + */ + $consoleContent: null, + /** + * @var object, jQuery object, selector is '#pma_console .content', + * used for resizer + * @access private + */ + $consoleAllContents: null, + /** + * @var object, jQuery object, selector is '#pma_console .toolbar' + * @access private + */ + $consoleToolbar: null, + /** + * @var object, jQuery object, selector is '#pma_console .template' + * @access private + */ + $consoleTemplates: null, + /** + * @var object, jQuery object, form for submit + * @access private + */ + $requestForm: null, + /** + * @var object, contain console config + * @access private + */ + config: null, + /** + * @var bool, if console element exist, it'll be true + * @access public + */ + isEnabled: false, + /** + * @var bool, make sure console events bind only once + * @access private + */ + isInitialized: false, + /** + * Used for console initialize, reinit is ok, just some variable assignment + * + * @return void + */ + initialize: function() { + + if($('#pma_console').length === 0) { + return; + } + + PMA_console.isEnabled = true; + + // Cookie var checks and init + if(! $.cookie('pma_console_height')) { + $.cookie('pma_console_height', 92); + } + if(! $.cookie('pma_console_mode')) { + $.cookie('pma_console_mode', 'info'); + } + + // Vars init + PMA_console.$consoleToolbar = $('#pma_console>.toolbar'); + PMA_console.$consoleContent = $('#pma_console>.content'); + PMA_console.$consoleAllContents = $('#pma_console .content'); + PMA_console.$consoleTemplates = $('#pma_console>.templates'); + + // Generate a from for post + PMA_console.$requestForm = $('<form method="post" action="import.php">' + + '<input name="is_js_confirmed" value="0">' + + '<textarea name="sql_query"></textarea>' + + '<input name="console_message_id" value="0">' + + '<input name="db" value="">' + + '<input name="table" value="">' + + '<input name="token" value="' + + PMA_commonParams.get('token') + '">' + + '</form>'); + PMA_console.$requestForm.bind('submit', AJAX.requestHandler); + + // Event binds shouldn't run again + if(PMA_console.isInitialized === false) { + + // Load config first + var tempConfig = JSON.parse($.cookie('pma_console_config')); + if(tempConfig) { + if(tempConfig.alwaysExpand === true) { + $('#pma_console_options input[name=always_expand]').attr('checked', true); + } + if(tempConfig.startHistory === true) { + $('#pma_console_options input[name=start_history]').attr('checked', true); + } + if(tempConfig.currentQuery === true) { + $('#pma_console_options input[name=current_query]').attr('checked', true); + } + } else { + $('#pma_console_options input[name=current_query]').attr('checked', true); + } + + PMA_console.updateConfig(); + + PMA_consoleResizer.initialize(); + PMA_consoleInput.initialize(); + PMA_consoleMessages.initialize(); + PMA_consoleBookmarks.initialize(); + + PMA_console.$consoleToolbar.children('.console_switch').click(PMA_console.toggle); + $(document).keydown(function(event) { + // 27 keycode is ESC + if(event.keyCode === 27) + PMA_console.toggle(); + }); + + $('#pma_console .toolbar').children().mousedown(function(event) { + event.preventDefault(); + event.stopImmediatePropagation(); + }); + + $('#pma_console .button.clear').click(function() { + PMA_consoleMessages.clear(); + }); + + $('#pma_console .button.history').click(function() { + PMA_consoleMessages.showHistory(); + }); + + $('#pma_console .button.options').click(function() { + PMA_console.showCard('#pma_console_options'); + }); + + $('#pma_console .mid_layer').click(function() { + PMA_console.hideCard($(this).parent().children('.card')); + }); + $('#pma_bookmarks .switch_button').click(function() { + PMA_console.hideCard($(this).closest('.card')); + }); + + $('#pma_console_options input[type=checkbox]').change(function() { + PMA_console.updateConfig(); + }); + + $('#pma_console_options .button.default').click(function() { + $('#pma_console_options input[name=always_expand]').prop('checked', false); + $('#pma_console_options input[name=start_history]').prop('checked', false); + $('#pma_console_options input[name=current_query]').prop('checked', true); + PMA_console.updateConfig(); + }); + + PMA_console.isInitialized = true; + } + + // Change console mode from cookie + switch($.cookie('pma_console_mode')) { + case 'collapse': + PMA_console.collapse(); + break; + default: + $.cookie('pma_console_mode', 'info'); + case 'info': + PMA_console.info(); + break; + case 'show': + PMA_console.show(true); + PMA_console.scrollBottom(); + break; + } + }, + /** + * Excute query and show results in console + * + * @return void + */ + execute: function(queryString, target) { + if(typeof(queryString) != 'string' || ! /[a-z]|[A-Z]/.test(queryString)){ + return; + } + PMA_console.$requestForm.children('textarea').val(queryString); + if(target && target.db) { + PMA_console.$requestForm.children('[name=db]').attr('value', target.db); + if(target.table) { + PMA_console.$requestForm.children('[name=table]').attr('value', target.table); + } else { + PMA_console.$requestForm.children('[name=table]').attr('value', ''); + } + } else { + PMA_console.$requestForm.children('[name=db]').attr('value', + (PMA_commonParams.get('db').length > 0 ? PMA_commonParams.get('db') : '')); + } + if (! confirmQuery(PMA_console.$requestForm[0], PMA_console.$requestForm.children('textarea')[0])) { + return; + } + PMA_console.$requestForm.children('[name=console_message_id]') + .attr('value', PMA_consoleMessages.appendQuery({sql_query: queryString})); + PMA_console.$requestForm.trigger('submit'); + PMA_consoleInput.clear(); + }, + ajaxCallback: function(data) { + if(data.console_message_id) { + PMA_consoleMessages.updateQuery(data.console_message_id, data.success, + (data._reloadQuerywindow ? data._reloadQuerywindow : false)); + } else if(data._reloadQuerywindow) { + if(data._reloadQuerywindow.sql_query.length > 0) { + PMA_consoleMessages.appendQuery(data._reloadQuerywindow, 'successed'); + } + } + }, + /** + * Change console to collapse mode + * + * @return void + */ + collapse: function() { + $.cookie('pma_console_mode', 'collapse'); + var pmaConsoleHeight = $.cookie('pma_console_height'); + + if(pmaConsoleHeight < 32) { + $.cookie('pma_console_height', 92); + } + PMA_console.$consoleToolbar.addClass('collapsed'); + PMA_console.$consoleAllContents.height(pmaConsoleHeight); + PMA_console.$consoleContent.stop(); + PMA_console.$consoleContent.animate({'margin-bottom': -1 * PMA_console.$consoleContent.outerHeight() + 'px'}, + 'fast', 'easeOutQuart', function() { + PMA_console.$consoleContent.css({display:'none'}); + $(window).trigger('resize'); + }); + PMA_console.hideCard(); + }, + /** + * Show console + * + * @param bool inputFocus If true, focus the input line after show() + * @return void + */ + show: function(inputFocus) { + $.cookie('pma_console_mode', 'show'); + + var pmaConsoleHeight = $.cookie('pma_console_height'); + + if(pmaConsoleHeight < 32) { + $.cookie('pma_console_height', 32); + PMA_console.collapse(); + return; + } + PMA_console.$consoleContent.css({display:'block'}); + if(PMA_console.$consoleToolbar.hasClass('collapsed')) + PMA_console.$consoleToolbar.removeClass('collapsed'); + PMA_console.$consoleAllContents.height(pmaConsoleHeight); + PMA_console.$consoleContent.stop(); + PMA_console.$consoleContent.animate({'margin-bottom': 0}, + 'fast', 'easeOutQuart', function() { + $(window).trigger('resize'); + }); + if(inputFocus) { + PMA_consoleInput.focus(); + } + }, + /** + * Change console to SQL information mode + * this mode shows current SQL query + * This mode is the default mode + * + * @return void + */ + info: function() { + // Under construction + PMA_console.collapse(); + }, + /** + * Toggle console mode between collsapse/show + * Used for toggle buttons and shortcuts + * + * @return void + */ + toggle: function() { + switch($.cookie('pma_console_mode')) { + case 'collapse': + case 'info': + PMA_console.show(true); + break; + case 'show': + PMA_console.collapse(); + break; + default: + PMA_consoleInitialize(); + } + }, + /** + * Scroll console to bottom + * + * @return void + */ + scrollBottom: function() { + PMA_console.$consoleContent.scrollTop(PMA_console.$consoleContent.prop("scrollHeight")); + }, + /** + * Show card + * + * @param string cardSelector Selector, select string will be "#pma_console " + cardSelector + * this param also can be JQuery object, if you need. + * + * @return void + */ + showCard: function(cardSelector) { + var $card = null; + if(typeof(cardSelector) !== 'string') { + if (cardSelector.length > 0) { + $card = cardSelector; + } else { + return; + } + } else { + $card = $("#pma_console " + cardSelector); + } + if($card.length === 0) { + return; + } + $card.parent().children('.mid_layer').show().fadeTo(0, 0.15); + $card.addClass('show'); + PMA_consoleInput.blur(); + if($card.parents('.card').length > 0) { + PMA_console.showCard($card.parents('.card')); + } + }, + /** + * Scroll console to bottom + * + * @param object $targetCard Target card JQuery object, if it's empty, function will hide all cards + * @return void + */ + hideCard: function($targetCard) { + if(! $targetCard) { + $('#pma_console .mid_layer').fadeOut(140); + $('#pma_console .card').removeClass('show'); + } else if($targetCard.length > 0) { + $targetCard.parent().find('.mid_layer').fadeOut(140); + $targetCard.find('.card').removeClass('show'); + $targetCard.removeClass('show'); + } + }, + /** + * Used for update console config + * + * @return void + */ + updateConfig: function() { + PMA_console.config = { + alwaysExpand: $('#pma_console_options input[name=always_expand]').prop('checked'), + startHistory: $('#pma_console_options input[name=start_history]').prop('checked'), + currentQuery: $('#pma_console_options input[name=current_query]').prop('checked') + }; + $.cookie('pma_console_config', JSON.stringify(PMA_console.config)); + } +}; + +/** + * Resizer object + * Careful: this object UI logics highly related with functions under PMA_console + * Resizing min-height is 32, if small than it, console will collapse + */ +var PMA_consoleResizer = { + _posY: 0, + _height: 0, + _resultHeight: 0, + /** + * Mousedown event handler for bind to resizer + * + * @return void + */ + _mousedown: function(event) { + if($.cookie('pma_console_mode') !== 'show') + return; + PMA_consoleResizer._posY = event.pageY; + PMA_consoleResizer._height = PMA_console.$consoleContent.height(); + $(document).mousemove(PMA_consoleResizer._mousemove); + $(document).mouseup(PMA_consoleResizer._mouseup); + // Disable text selection while resizing + $(document).bind('selectstart', function(){ return false; }); + }, + /** + * Mousemove event handler for bind to resizer + * + * @return void + */ + _mousemove: function(event) { + PMA_consoleResizer._resultHeight = PMA_consoleResizer._height + (PMA_consoleResizer._posY -event.pageY); + // Content min-height is 32, if adjusting height small than it we'll move it out of the page + if(PMA_consoleResizer._resultHeight <= 32) { + PMA_console.$consoleAllContents.height(32); + PMA_console.$consoleContent.css('margin-bottom', PMA_consoleResizer._resultHeight - 32); + } + else { + // Logic below makes viewable area always at bottom when adjusting height and content already at bottom + if(PMA_console.$consoleContent.scrollTop() + PMA_console.$consoleContent.innerHeight() + 16 + >= PMA_console.$consoleContent.prop('scrollHeight')) { + PMA_console.$consoleAllContents.height(PMA_consoleResizer._resultHeight); + PMA_console.scrollBottom(); + } else { + PMA_console.$consoleAllContents.height(PMA_consoleResizer._resultHeight); + } + } + }, + /** + * Mouseup event handler for bind to resizer + * + * @return void + */ + _mouseup: function() { + $.cookie('pma_console_height', PMA_consoleResizer._resultHeight); + PMA_console.show(); + $(document).unbind('mousemove'); + $(document).unbind('mouseup'); + $(document).unbind('selectstart'); + }, + /** + * Used for console resizer initialize + * + * @return void + */ + initialize: function() { + $('#pma_console .toolbar').unbind('mousedown'); + $('#pma_console .toolbar').mousedown(PMA_consoleResizer._mousedown); + } +}; + + +/** + * Console input object + */ +var PMA_consoleInput = { + /** + * @var CodeMirror object + * @access private + */ + _cm: null, + /** + * Used for console input initialize + * + * @return void + */ + initialize: function() { + // _cm object can't be reinitialize + if(PMA_consoleInput._cm !== null) { + return; + } + PMA_consoleInput._cm = CodeMirror($('#query_input')[0], { + theme: 'pma', + mode: 'text/x-sql', + lineWrapping: true + }); + $('#pma_console .CodeMirror.cm-s-pma').keydown(PMA_consoleInput._keydown); + }, + /** + * Mousedown event handler for bind to input + * Shortcut is ESC key + * + * @return void + */ + _keydown: function(event) { + if(event.ctrlKey && event.keyCode === 13) { + PMA_consoleInput.execute(); + } + }, + /** + * Used for send text to PMA_console.execute() + * + * @return void + */ + execute: function() { + PMA_console.execute(PMA_consoleInput._cm.getValue()); + }, + /** + * Used for clear the input + * + * @param bool clearHistory if true, clear type history + * @return void + */ + clear: function(clearHistory) { + PMA_consoleInput._cm.setValue(''); + if(clearHistory){ + PMA_consoleInput._cm.clearHistory(); + } + }, + /** + * Used for set focus to input + * + * @return void + */ + focus: function() { + PMA_consoleInput._cm.focus(); + }, + /** + * Used for blur input + * + * @return void + */ + blur: function() { + PMA_consoleInput._cm.getInputField().blur(); + }, + /** + * Used for set text in input + * + * @return void + */ + setText: function(text) { + PMA_consoleInput._cm.setValue(text); + } + +}; + + +/** + * Console messages, and message items management object + */ +var PMA_consoleMessages = { + /** + * Used for clear the messages + * + * @return void + */ + clear: function() { + $('#pma_console .content .console_message_container .message:not(.welcome)').addClass('hide'); + $('#pma_console .content .console_message_container .message.failed').remove(); + }, + /** + * Used for show history messages + * + * @return void + */ + showHistory: function() { + $('#pma_console .content .console_message_container .message.hide').removeClass('hide'); + }, + /** + * Used for log new message + * + * @param string msgString Message to show + * @param string msgType Message type + * @return object, {message_id, $message} + */ + append: function(msgString, msgType) { + if(typeof(msgString) !== 'string') { + return false; + } + // Generate an ID for each message, we can find them later + var msgId = Math.round(Math.random()*(899999999999)+100000000000); + var $newMessage = + $('<div class="message ' + + (PMA_console.config.alwaysExpand ? 'expanded' : 'collapsed') + +'" msgid="' + msgId + '"><div class="action_content"></div></div>'); + switch(msgType) { + case 'query': + $newMessage.append('<div class="query highlighted"></div>'); + CodeMirror.runMode(msgString, + 'text/x-sql', $newMessage.children('.query')[0]); + $newMessage.children('.action_content') + .append(PMA_console.$consoleTemplates.children('.query_actions').html()); + break; + default: + case 'normal': + $newMessage.append('<div>' + msgString + '</div>'); + } + PMA_consoleMessages._msgEventBinds($newMessage); + $newMessage.find('span.text.query_time span').text(Date()); + return {message_id: msgId, + $message: $newMessage.appendTo('#pma_console .content .console_message_container')}; + }, + /** + * Used for log new query + * + * @param string queryData Struct should be + * {sql_query: "Query string", db: "Target DB", table: "Target Table"} + * @param string state Message state + * @return object, {message_id: string message id, $message: JQuery object} + */ + appendQuery: function(queryData, state) { + var targetMessage = PMA_consoleMessages.append(queryData.sql_query, 'query'); + if(! targetMessage) { + return false; + } + if(queryData.db && queryData.table) { + targetMessage.$message.attr('targetdb', queryData.db); + targetMessage.$message.attr('targettable', queryData.table); + targetMessage.$message.find('.text.targetdb span').text(queryData.db); + } + switch(state) { + case 'failed': + targetMessage.$message.addClass('failed'); + break; + case 'successed': + console.dir(targetMessage.$message); + targetMessage.$message.addClass('successed'); + break; + default: + case 'pending': + targetMessage.$message.addClass('pending'); + } + return targetMessage.message_id; + }, + _msgEventBinds: function($targetMessage) { + // Leave unbinded elements, remove binded. + var $targetMessage = $targetMessage.filter(':not(.binded)'); + if($targetMessage.length === 0) { + return; + } + $targetMessage.addClass('binded'); + + $targetMessage.find('.action.expand').click(function () { + $(this).closest('.message').removeClass('collapsed'); + $(this).closest('.message').addClass('expanded'); + }); + $targetMessage.find('.action.collapse').click(function () { + $(this).closest('.message').addClass('collapsed'); + $(this).closest('.message').removeClass('expanded'); + }); + $targetMessage.find('.action.reedit').click(function () { + PMA_consoleInput.setText($(this).parent().siblings('.query').text()); + PMA_consoleInput.focus(); + }); + $targetMessage.find('.action.requery').click(function () { + var query = $(this).parent().siblings('.query').text(); + var $message = $(this).closest('.message'); + if(confirm(PMA_messages.strConsoleRequeryConfirm + '\n' + + (query.length<100 ? query : query.slice(0, 100) + '...'))) { + PMA_console.execute(query, {db: $message.attr('targetdb'), table: $message.attr('targettable')}); + } + }); + }, + msgAppend: function(msgId, msgString, msgType) { + var $targetMessage = $('#pma_console .content .console_message_container .message[msgid=' + msgId +']'); + if($targetMessage.length === 0 || isNaN(parseInt(msgId)) || typeof(msgString) !== 'string') { + return false; + } + $targetMessage.append('<div>' + msgString + '</div>'); + }, + updateQuery: function(msgId, isSuccessed, queryData) { + var $targetMessage = $('#pma_console .console_message_container .message[msgid=' + parseInt(msgId) +']'); + if($targetMessage.length === 0 || isNaN(parseInt(msgId))) { + return false; + } + $targetMessage.removeClass('pending failed successed'); + if(isSuccessed) { + $targetMessage.addClass('successed'); + if(queryData) { + $targetMessage.children('.query').text(''); + CodeMirror.runMode(queryData.sql_query, 'text/x-sql', $targetMessage.children('.query')[0]); + $targetMessage.attr('targetdb', queryData.db); + $targetMessage.attr('targettable', queryData.table); + $targetMessage.find('.text.targetdb span').text(queryData.db); + } + } else { + $targetMessage.addClass('failed'); + } + }, + /** + * Used for console messages initialize + * + * @return void + */ + initialize: function() { + PMA_consoleMessages._msgEventBinds($('#pma_console .message:not(.binded)')); + $('#pma_console .message .query:not(.highlighted)').each(function(index, elem) { + CodeMirror.runMode(elem.innerHTML, + 'text/x-sql', elem); + $(this).addClass('highlighted'); + }); + if(PMA_console.config.startHistory) { + PMA_consoleMessages.showHistory(); + } + } +}; + + +/** + * Console bookmarks card, and bookmarks items management object + */ +var PMA_consoleBookmarks = { + /** + * Used for console bookmarks initialize + * message events are already binded by PMA_consoleMsg._msgEventBinds + * + * @return void + */ + initialize: function() { + if($('#pma_bookmarks').length === 0) { + return; + } + $('#pma_console .button.bookmarks').click(function() { + PMA_console.showCard('#pma_bookmarks'); + }); + $('#pma_bookmarks .button.add').click(function() { + PMA_console.showCard('#pma_bookmarks .card.add'); + }); + $('#pma_console .button.refresh').click(function() { + $.get('import.php?console_bookmark_refresh=refresh&token=' + PMA_commonParams.get('token'), + {'ajax_request': true}, + function(data) { + if(data.console_message_bookmark) { + $('#pma_bookmarks .content.bookmark').html(data.console_message_bookmark); + PMA_consoleMessages._msgEventBinds($('#pma_bookmarks .message:not(.binded)')); + } + }); + }); + } + +}
\ No newline at end of file diff --git a/js/messages.php b/js/messages.php index 0f7a7097b7..e527fb65ef 100644 --- a/js/messages.php +++ b/js/messages.php @@ -468,6 +468,8 @@ $js_messages['phpErrorsBeingSubmitted'] = '<div class="error">' . '" width="16" height="16" alt="ajax clock"/>' . '</div>'; +$js_messages['strConsoleRequeryConfirm'] = __('Execute this query again?'); + echo "var PMA_messages = new Array();\n"; foreach ($js_messages as $name => $js_message) { PMA_printJsValue("PMA_messages['" . $name . "']", $js_message); diff --git a/js/navigation.js b/js/navigation.js index b7b037e61a..6b46f2222e 100644 --- a/js/navigation.js +++ b/js/navigation.js @@ -727,10 +727,6 @@ function PMA_navigationTreePagination($this) { */ var ResizeHandler = function () { /** - * Whether the user has initiated a resize operation - */ - this.active = false; - /** * @var int panel_width Used by the collapser to know where to go * back to when uncollapsing the panel */ @@ -752,7 +748,7 @@ var ResizeHandler = function () { var $collapser = $('#pma_navigation_collapser'); $('#pma_navigation').width(pos); $('body').css('margin-' + this.left, pos + 'px'); - $("#floating_menubar") + $("#floating_menubar, #pma_console") .css('margin-' + this.left, (pos + resizer_width) + 'px'); $resizer.css(this.left, pos + 'px'); if (pos === 0) { @@ -826,7 +822,11 @@ var ResizeHandler = function () { */ this.mousedown = function (event) { event.preventDefault(); - event.data.resize_handler.active = true; + $(document) + .bind('mousemove', {'resize_handler': event.data.resize_handler}, + $.throttle(event.data.resize_handler.mousemove, 4)) + .bind('mouseup', {'resize_handler': event.data.resize_handler}, + event.data.resize_handler.mouseup); $('body').css('cursor', 'col-resize'); }; /** @@ -837,12 +837,11 @@ var ResizeHandler = function () { * @return void */ this.mouseup = function (event) { - if (event.data.resize_handler.active) { - event.data.resize_handler.active = false; - $('body').css('cursor', ''); - $.cookie('pma_navi_width', event.data.resize_handler.getPos(event)); - $('#topmenu').menuResizer('resize'); - } + $('body').css('cursor', ''); + $.cookie('pma_navi_width', event.data.resize_handler.getPos(event)); + $('#topmenu').menuResizer('resize'); + $(document) + .unbind('mousemove'); }; /** * Event handler for updating the panel during a resize operation @@ -852,11 +851,9 @@ var ResizeHandler = function () { * @return void */ this.mousemove = function (event) { - if (event.data && event.data.resize_handler && event.data.resize_handler.active) { - event.preventDefault(); - var pos = event.data.resize_handler.getPos(event); - event.data.resize_handler.setWidth(pos); - } + event.preventDefault(); + var pos = event.data.resize_handler.getPos(event); + event.data.resize_handler.setWidth(pos); if($('#sticky_columns').length !== 0) { handleStickyColumns(); } @@ -870,7 +867,6 @@ var ResizeHandler = function () { */ this.collapse = function (event) { event.preventDefault(); - event.data.active = false; var panel_width = event.data.resize_handler.panel_width; var width = $('#pma_navigation').width(); if (width === 0 && panel_width === 0) { @@ -898,6 +894,9 @@ var ResizeHandler = function () { 'overflow-y': 'auto' }); } + // Set content bottom space beacuse of console + $('body').css('margin-bottom', + $(window).height() + $(document).scrollTop() - $('#pma_console').offset().top + 'px'); }; /* Initialisation section begins here */ if ($.cookie('pma_navi_width')) { @@ -909,9 +908,6 @@ var ResizeHandler = function () { // Register the events for the resizer and the collapser $('#pma_navigation_resizer') .live('mousedown', {'resize_handler': this}, this.mousedown); - $(document) - .bind('mouseup', {'resize_handler': this}, this.mouseup) - .bind('mousemove', {'resize_handler': this}, $.throttle(this.mousemove, 4)); var $collapser = $('#pma_navigation_collapser'); $collapser.live('click', {'resize_handler': this}, this.collapse); // Add the correct arrow symbol to the collapser @@ -375,6 +375,9 @@ AJAX.registerOnload('sql.js', function () { } } } + if(PMA_console && PMA_console.isEnabled) { + PMA_console.ajaxCallback(data); + } } else if (data.success === false) { // show an error message that stays on screen $('#sqlqueryform').before(data.error); diff --git a/libraries/Console.class.php b/libraries/Console.class.php new file mode 100644 index 0000000000..fa9e538208 --- /dev/null +++ b/libraries/Console.class.php @@ -0,0 +1,265 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Used to render the console of PMA's pages + * + * @package PhpMyAdmin + */ +if (! defined('PHPMYADMIN')) { + exit; +} + +require_once 'libraries/Scripts.class.php'; +require_once 'libraries/Util.class.php'; +require_once 'libraries/bookmark.lib.php'; + +/** + * Class used to output the console + * + * @package PhpMyAdmin + */ +class PMA_Console +{ + /** + * PMA_Scripts instance + * + * @access private + * @var PMA_Scripts + */ + private $_scripts; + /** + * Whether to display anything + * + * @access private + * @var bool + */ + private $_isEnabled; + + /** + * Creates a new class instance + */ + public function __construct() + { + $this->_isEnabled = true; + $this->_scripts = new PMA_Scripts(); + } + + /** + * Whether we are servicing an ajax request. + * We can't simply use $GLOBALS['is_ajax_request'] + * here since it may have not been initialised yet. + * + * @access private + * @var bool + */ + private $_isAjax; + + /** + * Set the ajax flag to indicate whether + * we are sevicing an ajax request + * + * @param bool $isAjax Whether we are sevicing an ajax request + * + * @return void + */ + public function setAjax($isAjax) + { + $this->_isAjax = ($isAjax == true); + } + + /** + * Disables the rendering of the footer + * + * @return void + */ + public function disable() + { + $this->_isEnabled = false; + } + + /** + * Renders the bookmark content + * + * @access public + * @return string + */ + public static function getBookmarkContent() + { + $output = ''; + $cfgBookmark = PMA_Bookmark_getParams(); + if($cfgBookmark) { + + $tpl_bookmark_actions = + '<span class="action collapse">' . __('Collapse') . '</span> ' + . '<span class="action expand">' . __('Expand') . '</span> ' + . '<span class="action requery">' . __('Requery') . '</span> ' + . '<span class="action reedit">' . __('Reedit') . '</span> ' + // . '<span class="action bookmark">' . __('Delete') . '</span> ' + . '<span class="text targetdb">' . __('Database') . ': <span>%s</span></span>'; + + $bookmarks = PMA_Bookmark_getList(); + $output .= '<div class="message welcome"><span>' + . (count($bookmarks) > 0 ? __('Total ') . count($bookmarks) . __(' bookmarks, ') + . '<span class="bookmark_label">' . __('private') + . '</span> and <span class="bookmark_label shared">' . __('shared') + . '</span>' . __(' bookmarks included.') + : __('No bookmarks')) + . '</span></div>'; + foreach ($bookmarks as $key => $val) { + $output .= '<div class="message collapsed bookmark" bookmarkid="' + . $val['id'] . '" bookmarkdb="' . $val['db'] + . '"><div class="action_content">' + . sprintf($tpl_bookmark_actions, $val['db']) + . '</div><span class="bookmark_label ' . ($val['shared'] ? 'shared' : '') . '">' + . $val['label'] + . '</span> <span class="query">' + . $val['query'] + . '</span></div>'; + } + } + return $output; + } + + /** + * Renders the console + * + * @access public + * @return string + */ + public function getDisplay() + { + $output = ''; + if((! $this->_isAjax) && $this->_isEnabled) { + $cfgBookmark = PMA_Bookmark_getParams(); + $this->_scripts->addFile('codemirror/lib/codemirror.js'); + $this->_scripts->addFile('codemirror/mode/sql/sql.js'); + $this->_scripts->addFile('codemirror/addon/runmode/runmode.js'); + $this->_scripts->addFile('console.js'); + $output .= $this->_scripts->getDisplay(); + $output .= '<div id="pma_console_container"><div id="pma_console">'; + + // The templates, use sprintf() to output them + // There're white space at the end of every <span>, + // for double-click selection + $tpl_query_actions = + '<span class="action collapse">' . __('Collapse') . '</span> ' + . '<span class="action expand">' . __('Expand') . '</span> ' + . '<span class="action requery">' . __('Requery') . '</span> ' + . '<span class="action reedit">' . __('Reedit') . '</span> ' + // . ($cfgBookmark ? '<span class="action bookmark">' . __('Bookmark') . '</span> ' : '') + . '<span class="text failed">' . __('Query failed') . '</span> ' + . '<span class="text targetdb">' . __('Database') . ': <span>%s</span></span> ' + . '<span class="text query_time">' . __('Queried time') . ': <span>%s</span></span> '; + + // Console toolbar + $output .= '<div class="toolbar collapsed">'; + + $output .= '<div class="switch_button console_switch">'; + $output .= PMA_Util::getImage('console.png', __('SQL Query Console')); + $output .= '<span>' . __('Console') . '</span></div>'; + + $output .= '<div class="button clear"><span>' + . __('Clear') . '</span></div>'; + + $output .= '<div class="button history"><span>' + . __('History') . '</span></div>'; + + $output .= '<div class="button options"><span>' + . __('Options') . '</span></div>'; + + if($cfgBookmark) { + $output .= '<div class="button bookmarks"><span>' + . __('Bookmarks') . '</span></div>'; + } + + $output .= '</div>'; // Toolbar end + + // Console messages + $output .= '<div class="content">'; + $output .= '<div class="console_message_container">' + . '<div class="message welcome"><span>' + . __('Press') . ' Ctrl+Enter ' . __('to Execute query') + . '</span></div>'; + + // History support + $_sql_history = PMA_getHistory($GLOBALS['cfg']['Server']['user']); + if($_sql_history) { + foreach (array_reverse($_sql_history) as $record) { + $output .= '<div class="message history collapsed hide" targetdb="' + . $record['db'] . '" targettable="' . $record['table'] + . '""><div class="action_content">' + . sprintf($tpl_query_actions, $record['db'], + (isset($record['timevalue']) ? $record['timevalue'] : __('During current session'))) + . '</div><span class="query">' + . $record['sqlquery'] + . '</span></div>'; + } + } + + $output .= '</div>'; // .console_message_container + $output .= '<div class="query_input"><span id="query_input"></span></div>' + . '</div>'; // Messages end + + // Dark the console while other cards cover it + $output .= '<div class="mid_layer"></div>'; + + // Bookmarks card: + + if($cfgBookmark) { + $output .= '<div class="card" id="pma_bookmarks">'; + $output .= '<div class="toolbar">' + . '<div class="switch_button"><span>' . __('Bookmarks') + . '</span></div>'; + + $output .= '<div class="button refresh"><span>' + . __('Refresh') . '</span></div>'; + + // $output .= '<div class="button add"><span>' + // . __('Add') . '</span></div>'; + + $output .= '</div><div class="content bookmark">'; + $output .= $this->getBookmarkContent(); + $output .= '</div>'; + $output .= '<div class="mid_layer"></div>'; + $output .= '<div class="card add">'; + $output .= '<div class="toolbar">' + . '<div class="switch_button"><span>' . __('Add bookmark') + . '</span></div>'; + $output .= '</div><div class="content add_bookmark">' + . '<label>'. __('Label') . ':<input type="text" name="label"></label> ' + . '<label>'. __('Target database') . ':<input type="text" name="targetdb"></label> ' + . '<label><input type="checkbox" name="shared">'. __('Share this bookmark') . '</label>'; + $output .= '</div>'; + $output .= '</div></div>'; // Bookmarks card + } + + // Options card: + $output .= '<div class="card" id="pma_console_options">'; + $output .= '<div class="toolbar">' + . '<div class="switch_button"><span>' . __('Options') . '</span></div>'; + + $output .= '<div class="button default"><span>' + . __('Set default') . '</span></div>'; + + $output .= '</div><div class="content">' + . '<label><input type="checkbox" name="always_expand">' + . __('Always expand queried messages') . '</label><br>' + . '<label><input type="checkbox" name="start_history">' + . __('Show query history at start') . '</label><br>' + . '<label><input type="checkbox" name="current_query">' + . __('Show current browsing query') . '</label><br>' + . '</div>'; + $output .= '</div>'; // Options card + + $output .= '<div class="templates">' + // Templates for console message actions + . '<div class="query_actions">' + . sprintf($tpl_query_actions, '', '') + . '</div>' + . '</div>'; + $output .= '</div></div>'; // #console and #pma_console_container ends + } + return $output; + } + +} diff --git a/libraries/Header.class.php b/libraries/Header.class.php index af3f2d22b5..0097e7993d 100644 --- a/libraries/Header.class.php +++ b/libraries/Header.class.php @@ -12,6 +12,7 @@ if (! defined('PHPMYADMIN')) { require_once 'libraries/Scripts.class.php'; require_once 'libraries/RecentFavoriteTable.class.php'; require_once 'libraries/Menu.class.php'; +require_once 'libraries/Console.class.php'; require_once 'libraries/navigation/Navigation.class.php'; require_once 'libraries/url_generating.lib.php'; @@ -31,6 +32,13 @@ class PMA_Header */ private $_scripts; /** + * PMA_Console instance + * + * @access private + * @var PMA_Console + */ + private $_console; + /** * PMA_Menu instance * * @access private @@ -113,6 +121,7 @@ class PMA_Header $this->_isAjax = false; $this->_bodyId = ''; $this->_title = ''; + $this->_console = new PMA_Console(); $db = ! empty($GLOBALS['db']) ? $GLOBALS['db'] : ''; $table = ! empty($GLOBALS['table']) ? $GLOBALS['table'] : ''; $this->_menu = new PMA_Menu( @@ -270,6 +279,7 @@ class PMA_Header public function setAjax($isAjax) { $this->_isAjax = ($isAjax == true); + $this->_console->setAjax($isAjax); } /** @@ -321,9 +331,10 @@ class PMA_Header * * @return void */ - public function disableMenu() + public function disableMenuAndConsole() { $this->_menuEnabled = false; + $this->_console->disable(); } /** @@ -343,7 +354,7 @@ class PMA_Header */ public function enablePrintView() { - $this->disableMenu(); + $this->disableMenuAndConsole(); $this->setTitle(__('Print view') . ' - phpMyAdmin ' . PMA_VERSION); $this->_isPrintView = true; } @@ -409,6 +420,7 @@ class PMA_Header PMA_Util::getImage('s_top.png') ); } + $retval .= $this->_console->getDisplay(); $retval .= '<div id="page_content">'; $retval .= $this->getMessage(); } diff --git a/libraries/bookmark.lib.php b/libraries/bookmark.lib.php index e5ae629ffc..fba3a798d0 100644 --- a/libraries/bookmark.lib.php +++ b/libraries/bookmark.lib.php @@ -45,13 +45,16 @@ function PMA_Bookmark_getParams() * * @param string $db the current database name * - * @return array the bookmarks list (key as index, label as value) + * @return array the bookmarks list (key as index, label as value), + * or if param is empty, function will give more information, + * array will be unindexed, + * each struct: [db, id, label, shared, query] * * @access public * * @global resource $controllink the controluser db connection handle */ -function PMA_Bookmark_getList($db) +function PMA_Bookmark_getList($db = false) { global $controllink; @@ -61,31 +64,80 @@ function PMA_Bookmark_getList($db) return array(); } - $query = 'SELECT label, id FROM ' . PMA_Util::backquote($cfgBookmark['db']) - . '.' . PMA_Util::backquote($cfgBookmark['table']) - . ' WHERE dbase = \'' . PMA_Util::sqlAddSlashes($db) . '\'' - . ' AND user = \'' . PMA_Util::sqlAddSlashes($cfgBookmark['user']) . '\'' - . ' ORDER BY label'; - $per_user = $GLOBALS['dbi']->fetchResult( - $query, 'id', 'label', $controllink, PMA_DatabaseInterface::QUERY_STORE - ); - - $query = 'SELECT label, id FROM ' . PMA_Util::backquote($cfgBookmark['db']) - . '.' . PMA_Util::backquote($cfgBookmark['table']) - . ' WHERE dbase = \'' . PMA_Util::sqlAddSlashes($db) . '\'' - . ' AND user = \'\'' - . ' ORDER BY label'; - $global = $GLOBALS['dbi']->fetchResult( - $query, 'id', 'label', $controllink, PMA_DatabaseInterface::QUERY_STORE - ); - - foreach ($global as $key => $val) { - $global[$key] = $val . ' (' . __('shared') . ')'; - } + $ret = Array(); + if($db !== false) { + $query = 'SELECT label, id FROM ' . PMA_Util::backquote($cfgBookmark['db']) + . '.' . PMA_Util::backquote($cfgBookmark['table']) + . ' WHERE dbase = \'' . PMA_Util::sqlAddSlashes($db) . '\'' + . ' AND user = \'' . PMA_Util::sqlAddSlashes($cfgBookmark['user']) . '\'' + . ' ORDER BY label'; + $per_user = $GLOBALS['dbi']->fetchResult( + $query, 'id', 'label', $controllink, PMA_DatabaseInterface::QUERY_STORE + ); - $ret = $global + $per_user; + $query = 'SELECT label, id FROM ' . PMA_Util::backquote($cfgBookmark['db']) + . '.' . PMA_Util::backquote($cfgBookmark['table']) + . ' WHERE dbase = \'' . PMA_Util::sqlAddSlashes($db) . '\'' + . ' AND user = \'\'' + . ' ORDER BY label'; + $global = $GLOBALS['dbi']->fetchResult( + $query, 'id', 'label', $controllink, PMA_DatabaseInterface::QUERY_STORE + ); - asort($ret); + foreach ($global as $key => $val) { + $global[$key] = $val . ' (' . __('shared') . ')'; + } + + $ret = $global + $per_user; + + asort($ret); + } else { + $query = 'SELECT label, id, query, dbase FROM ' . PMA_Util::backquote($cfgBookmark['db']) + . '.' . PMA_Util::backquote($cfgBookmark['table']) + . ' WHERE user = \'' . PMA_Util::sqlAddSlashes($cfgBookmark['user']) . '\'' + . ' ORDER BY label'; + $per_user = $GLOBALS['dbi']->fetchResult( + $query, Array('id', 'label', 'dbase'), 'query', $controllink, PMA_DatabaseInterface::QUERY_STORE + ); + + $query = 'SELECT label, id, query, dbase FROM ' . PMA_Util::backquote($cfgBookmark['db']) + . '.' . PMA_Util::backquote($cfgBookmark['table']) + . ' WHERE user = \'\'' + . ' ORDER BY label'; + $global = $GLOBALS['dbi']->fetchResult( + $query, Array('id', 'label', 'dbase'), 'query', $controllink, PMA_DatabaseInterface::QUERY_STORE + ); + + $ret = Array(); + + foreach ($global as $id => $val) { + foreach ($val as $label => $val2) { + foreach ($val2 as $dbase => $query) { + $ret[] = Array( + 'db' => $dbase, + 'id' => $id, + 'label' => $label, + 'query' => $query, + 'shared' => true + ); + } + } + } + + foreach ($per_user as $id => $val) { + foreach ($val as $label => $val2) { + foreach ($val2 as $dbase => $query) { + $ret[] = Array( + 'db' => $dbase, + 'id' => $id, + 'label' => $label, + 'query' => $query, + 'shared' => false + ); + } + } + } + } return $ret; } // end of the 'PMA_Bookmark_getList()' function diff --git a/libraries/plugins/auth/AuthenticationConfig.class.php b/libraries/plugins/auth/AuthenticationConfig.class.php index 53bbdc5671..857ea3e3f2 100644 --- a/libraries/plugins/auth/AuthenticationConfig.class.php +++ b/libraries/plugins/auth/AuthenticationConfig.class.php @@ -83,7 +83,7 @@ class AuthenticationConfig extends AuthenticationPlugin $header = $response->getHeader(); $header->setBodyId('loginform'); $header->setTitle(__('Access denied!')); - $header->disableMenu(); + $header->disableMenuAndConsole(); echo '<br /><br /> <center> <h1>'; diff --git a/libraries/plugins/auth/AuthenticationCookie.class.php b/libraries/plugins/auth/AuthenticationCookie.class.php index 96771075a0..0fb4f6ff39 100644 --- a/libraries/plugins/auth/AuthenticationCookie.class.php +++ b/libraries/plugins/auth/AuthenticationCookie.class.php @@ -105,7 +105,7 @@ class AuthenticationCookie extends AuthenticationPlugin $header = $response->getHeader(); $header->setBodyId('loginform'); $header->setTitle('phpMyAdmin'); - $header->disableMenu(); + $header->disableMenuAndConsole(); $header->disableWarnings(); if (file_exists(CUSTOM_HEADER_FILE)) { diff --git a/libraries/plugins/auth/AuthenticationHttp.class.php b/libraries/plugins/auth/AuthenticationHttp.class.php index 16838472e6..0ac40f026c 100644 --- a/libraries/plugins/auth/AuthenticationHttp.class.php +++ b/libraries/plugins/auth/AuthenticationHttp.class.php @@ -67,7 +67,7 @@ class AuthenticationHttp extends AuthenticationPlugin $response->getFooter()->setMinimal(); $header = $response->getHeader(); $header->setTitle(__('Access denied!')); - $header->disableMenu(); + $header->disableMenuAndConsole(); $header->setBodyId('loginform'); $response->addHTML('<h1>'); diff --git a/libraries/relation.lib.php b/libraries/relation.lib.php index 9461105e84..7d1c027820 100644 --- a/libraries/relation.lib.php +++ b/libraries/relation.lib.php @@ -949,22 +949,26 @@ function PMA_getHistory($username) { $cfgRelation = PMA_getRelationsParam(); + if (! $cfgRelation['historywork']) { + return false; + } + /** * if db-based history is disabled but there exists a session-based * history, use it */ - if (! $GLOBALS['cfg']['QueryHistoryDB'] && isset($_SESSION['sql_history'])) { + if (! $GLOBALS['cfg']['QueryHistoryDB']) { + if(isset($_SESSION['sql_history'])) { return array_reverse($_SESSION['sql_history']); - } - - if (! $cfgRelation['historywork']) { + } return false; } $hist_query = ' SELECT `db`, `table`, - `sqlquery` + `sqlquery`, + `timevalue` FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['history']) . ' WHERE `username` = \'' . PMA_Util::sqlAddSlashes($username) . '\' diff --git a/querywindow.php b/querywindow.php index f14f600e66..6bc6600dbe 100644 --- a/querywindow.php +++ b/querywindow.php @@ -121,7 +121,7 @@ $sql_query = ''; $response = PMA_Response::getInstance(); $response->getFooter()->setMinimal(); $header = $response->getHeader(); -$header->disableMenu(); +$header->disableMenuAndConsole(); $header->setBodyId('bodyquerywindow'); $scripts = $header->getScripts(); $scripts->addFile('common.js'); diff --git a/test/classes/PMA_Header_test.php b/test/classes/PMA_Header_test.php index 6befa89cee..cb7c8b63f9 100644 --- a/test/classes/PMA_Header_test.php +++ b/test/classes/PMA_Header_test.php @@ -56,6 +56,7 @@ class PMA_Header_Test extends PHPUnit_Framework_TestCase $GLOBALS['PMA_Config']->enableBc(); $GLOBALS['cfg']['Server']['verbose'] = 'verbose host'; $GLOBALS['cfg']['Server']['pmadb'] = ''; + $GLOBALS['cfg']['Server']['user'] = ''; } /** diff --git a/test/classes/plugin/auth/PMA_AuthenticationCookie_test.php b/test/classes/plugin/auth/PMA_AuthenticationCookie_test.php index 6b9304c5ec..a327a07ef2 100644 --- a/test/classes/plugin/auth/PMA_AuthenticationCookie_test.php +++ b/test/classes/plugin/auth/PMA_AuthenticationCookie_test.php @@ -137,7 +137,7 @@ class PMA_AuthenticationCookie_Test extends PHPUnit_Framework_TestCase $mockHeader = $this->getMockBuilder('PMA_Header') ->disableOriginalConstructor() ->setMethods( - array('setBodyId', 'setTitle', 'disableMenu', 'disableWarnings') + array('setBodyId', 'setTitle', 'disableMenuAndConsole', 'disableWarnings') ) ->getMock(); @@ -150,7 +150,7 @@ class PMA_AuthenticationCookie_Test extends PHPUnit_Framework_TestCase ->with('phpMyAdmin'); $mockHeader->expects($this->once()) - ->method('disableMenu') + ->method('disableMenuAndConsole') ->with(); $mockHeader->expects($this->once()) diff --git a/test/classes/plugin/auth/PMA_AuthenticationHttp_test.php b/test/classes/plugin/auth/PMA_AuthenticationHttp_test.php index 3c53728b57..20c38f5c3d 100644 --- a/test/classes/plugin/auth/PMA_AuthenticationHttp_test.php +++ b/test/classes/plugin/auth/PMA_AuthenticationHttp_test.php @@ -101,7 +101,7 @@ class PMA_AuthenticationHttp_Test extends PHPUnit_Framework_TestCase $mockHeader = $this->getMockBuilder('PMA_Header') ->disableOriginalConstructor() ->setMethods( - array('setBodyId', 'setTitle', 'disableMenu', 'addHTML') + array('setBodyId', 'setTitle', 'disableMenuAndConsole', 'addHTML') ) ->getMock(); @@ -114,7 +114,7 @@ class PMA_AuthenticationHttp_Test extends PHPUnit_Framework_TestCase ->with('Access denied!'); $mockHeader->expects($this->once()) - ->method('disableMenu') + ->method('disableMenuAndConsole') ->with(); // set mocked headers and footers diff --git a/themes.php b/themes.php index aed65f97dd..f0d1be6f09 100644 --- a/themes.php +++ b/themes.php @@ -15,7 +15,7 @@ $response->getFooter()->setMinimal(); $header = $response->getHeader(); $header->setBodyId('bodythemes'); $header->setTitle('phpMyAdmin - ' . __('Theme')); -$header->disableMenu(); +$header->disableMenuAndConsole(); $hash = '#pma_' . preg_replace('/([0-9]*)\.([0-9]*)\..*/', '\1_\2', PMA_VERSION); $url = PMA_linkURL('http://www.phpmyadmin.net/home_page/themes.php') . $hash; diff --git a/themes/original/css/common.css.php b/themes/original/css/common.css.php index ae15cde699..b7ec2ce4ca 100644 --- a/themes/original/css/common.css.php +++ b/themes/original/css/common.css.php @@ -2706,3 +2706,251 @@ table.show_create td { .small_font { font-size: smaller; } + +/* Console styles */ +#pma_console_container { + width: 100%; + position: fixed; + bottom: 0; + <?php echo $left; ?>: 0; + z-index: 100; +} +#pma_console { + position: relative; + margin-<?php echo $left; ?>: 240px; +} +#pma_console>.templates { + display: none; +} +#pma_console .mid_text, +#pma_console .toolbar span { + vertical-align: middle; +} +#pma_console .toolbar { + position: relative; + background: #ccc; + border-top: solid 1px #aaa; + cursor: n-resize; +} +#pma_console .toolbar.collapsed:not(:hover) { + display: inline-block; + border-top-<?php echo $right; ?>-radius: 3px; + border-<?php echo $right; ?>: solid 1px #aaa; +} +#pma_console .toolbar.collapsed { + cursor: default; +} +#pma_console .toolbar.collapsed>.button { + display: none; +} +#pma_console .message span.text, +#pma_console .message span.action, +#pma_console .toolbar .button, +#pma_console .switch_button { + padding: 0 3px; + display: inline-block; +} +#pma_console .message span.action, +#pma_console .toolbar .button, +#pma_console .switch_button { + cursor: pointer; +} +#pma_console .message span.action:hover, +#pma_console .toolbar .button:hover, +#pma_console .switch_button:hover { + background: #ddd; +} +#pma_console .toolbar .button { + margin-<?php echo $right; ?>: .4em; +} +#pma_console .toolbar .button { + float: <?php echo $right; ?>; +} +#pma_console .content { + overflow-x: hidden; + overflow-y: auto; + margin-bottom: -65px; + border-top: solid 1px #aaa; + background: #fff; + padding-top: .4em; +} +#pma_console .message, +#pma_console .query_input { + position: relative; + font-family: Monaco, Consolas, monospace; + cursor: text; + margin: 0 10px .2em 1.4em; +} +#pma_console .message { + border-bottom: solid 1px #ccc; + padding-bottom: .2em; +} +#pma_console .message.expanded .action_content { + position: relative; +} +#pma_console .message:before, +#pma_console .query_input:before { + left: -0.7em; + position: absolute; + content: ">"; +} +#pma_console .query_input:before { + top: -2px; +} +#pma_console .message:hover:before { + color: #7cf; + font-weight: bold; +} +#pma_console .message.expanded:before { + content: "]"; +} +#pma_console .message.welcome:before { + display: none; +} +#pma_console .message.failed:before, +#pma_console .message.failed.expanded:before, +#pma_console .message.failed:hover:before { + content: "="; + color: #944; +} +#pma_console .message.pending:before { + opacity: .3; +} +#pma_console .message.collapsed>.query { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; +} +#pma_console .message.expanded>.query { + display: block; + white-space: pre; + word-wrap: break-word; +} +#pma_console .message .text.targetdb, +#pma_console .message.collapsed .action.collapse, +#pma_console .message.expanded .action.expand, +#pma_console .message .action.requery, +#pma_console .message .action.bookmark { + display: none; +} +#pma_console .message.history .text.targetdb, +#pma_console .message.successed .text.targetdb, +#pma_console .message.history .action.requery, +#pma_console .message.history .action.bookmark, +#pma_console .message.bookmark .action.requery, +#pma_console .message.bookmark .action.bookmark, +#pma_console .message.successed .action.requery, +#pma_console .message.successed .action.bookmark { + display: inline-block; +} +#pma_console .message .action_content { + position: absolute; + bottom: 100%; + background: #ccc; + border: solid 1px #aaa; + border-top-<?php echo $left; ?>-radius: 3px; +} +html.ie8 #pma_console .message .action_content { + position: relative!important; +} +#pma_console .message.bookmark .text.targetdb, +#pma_console .message .text.query_time { + margin: 0; + display: inline-block; +} +#pma_console .message.failed .text.query_time, +#pma_console .message .text.failed { + display: none; +} +#pma_console .message.failed .text.failed { + display: inline-block; +} +#pma_console .message .text { + background: #fff; +} +#pma_console .message.collapsed:not(:hover) .action_content { + display: none; +} +#pma_console .message .bookmark_label { + padding: 0 4px; + top: 0; + background: #369; + color: #fff; + border-radius: 3px; +} +#pma_console .message .bookmark_label.shared { + background: #396; +} +#pma_console .message.expanded .bookmark_label { + border-top-left-radius: 0; + border-top-right-radius: 0; +} +#pma_console .query_input { + position: relative; +} +#pma_console .mid_layer { + height: 100%; + width: 100%; + position: absolute; + top: 0; + /* For support IE8, this layer doesn't use filter:opacity or opacity, + js code will fade this layer opacity to 0.18(using animation) */ + background: #666; + display: none; + cursor: pointer; + z-index: 200; +} +#pma_console .card { + position: absolute; + width: 94%; + height: 100%; + min-height: 48px; + <?php echo $left; ?>: 100%; + top: 0; + border-<?php echo $left; ?>: solid 1px #999; + z-index: 300; + transition: <?php echo $left; ?> 0.2s; + -ms-transition: <?php echo $left; ?> 0.2s; + -webkit-transition: <?php echo $left; ?> 0.2s; + -moz-transition: <?php echo $left; ?> 0.2s; +} +#pma_console .card.show { + <?php echo $left; ?>: 6%; + box-shadow: -2px 1px 4px -1px #999; +} + +html.ie7 #pma_console .query_input { + display: none; +} + +#pma_bookmarks .content.add_bookmark, +#pma_console_options .content { + padding: 4px 6px; +} +#pma_bookmarks .content.add_bookmark input[type=text] { + margin: 0; + padding: 2px 4px; +} + +/* Code mirror console style*/ + +.cm-s-pma .CodeMirror-code pre, +.cm-s-pma .CodeMirror-code { + font-family: Monaco, Consolas, monospace; +} +.cm-s-pma .CodeMirror-measure>pre, +.cm-s-pma .CodeMirror-code>pre, +.cm-s-pma .CodeMirror-lines { + padding: 0; +} +.cm-s-pma.CodeMirror { + resize: none; + height: auto; + width: 100%; + min-height: initial; + max-height: initial; +} +.cm-s-pma .CodeMirror-scroll { + padding-bottom: 2em; + cursor: text; +} diff --git a/themes/original/img/console.png b/themes/original/img/console.png Binary files differnew file mode 100755 index 0000000000..94bae15eb5 --- /dev/null +++ b/themes/original/img/console.png diff --git a/themes/pmahomme/css/common.css.php b/themes/pmahomme/css/common.css.php index 8aab88e613..527e623429 100644 --- a/themes/pmahomme/css/common.css.php +++ b/themes/pmahomme/css/common.css.php @@ -2999,6 +2999,255 @@ table.show_create td { position: fixed; } + .small_font { font-size: smaller; } + +/* Console styles */ +#pma_console_container { + width: 100%; + position: fixed; + bottom: 0; + <?php echo $left; ?>: 0; + z-index: 100; +} +#pma_console { + position: relative; + margin-<?php echo $left; ?>: 240px; +} +#pma_console>.templates { + display: none; +} +#pma_console .mid_text, +#pma_console .toolbar span { + vertical-align: middle; +} +#pma_console .toolbar { + position: relative; + background: #ccc; + border-top: solid 1px #aaa; + cursor: n-resize; +} +#pma_console .toolbar.collapsed:not(:hover) { + display: inline-block; + border-top-<?php echo $right; ?>-radius: 3px; + border-<?php echo $right; ?>: solid 1px #aaa; +} +#pma_console .toolbar.collapsed { + cursor: default; +} +#pma_console .toolbar.collapsed>.button { + display: none; +} +#pma_console .message span.text, +#pma_console .message span.action, +#pma_console .toolbar .button, +#pma_console .switch_button { + padding: 0 3px; + display: inline-block; +} +#pma_console .message span.action, +#pma_console .toolbar .button, +#pma_console .switch_button { + cursor: pointer; +} +#pma_console .message span.action:hover, +#pma_console .toolbar .button:hover, +#pma_console .switch_button:hover { + background: #ddd; +} +#pma_console .toolbar .button { + margin-<?php echo $right; ?>: .4em; +} +#pma_console .toolbar .button { + float: <?php echo $right; ?>; +} +#pma_console .content { + overflow-x: hidden; + overflow-y: auto; + margin-bottom: -65px; + border-top: solid 1px #aaa; + background: #fff; + padding-top: .4em; +} +#pma_console .message, +#pma_console .query_input { + position: relative; + font-family: Monaco, Consolas, monospace; + cursor: text; + margin: 0 10px .2em 1.4em; +} +#pma_console .message { + border-bottom: solid 1px #ccc; + padding-bottom: .2em; +} +#pma_console .message.expanded .action_content { + position: relative; +} +#pma_console .message:before, +#pma_console .query_input:before { + left: -0.7em; + position: absolute; + content: ">"; +} +#pma_console .query_input:before { + top: -2px; +} +#pma_console .message:hover:before { + color: #7cf; + font-weight: bold; +} +#pma_console .message.expanded:before { + content: "]"; +} +#pma_console .message.welcome:before { + display: none; +} +#pma_console .message.failed:before, +#pma_console .message.failed.expanded:before, +#pma_console .message.failed:hover:before { + content: "="; + color: #944; +} +#pma_console .message.pending:before { + opacity: .3; +} +#pma_console .message.collapsed>.query { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; +} +#pma_console .message.expanded>.query { + display: block; + white-space: pre; + word-wrap: break-word; +} +#pma_console .message .text.targetdb, +#pma_console .message.collapsed .action.collapse, +#pma_console .message.expanded .action.expand, +#pma_console .message .action.requery, +#pma_console .message .action.bookmark { + display: none; +} +#pma_console .message.history .text.targetdb, +#pma_console .message.successed .text.targetdb, +#pma_console .message.history .action.requery, +#pma_console .message.history .action.bookmark, +#pma_console .message.bookmark .action.requery, +#pma_console .message.bookmark .action.bookmark, +#pma_console .message.successed .action.requery, +#pma_console .message.successed .action.bookmark { + display: inline-block; +} +#pma_console .message .action_content { + position: absolute; + bottom: 100%; + background: #ccc; + border: solid 1px #aaa; + border-top-<?php echo $left; ?>-radius: 3px; +} +html.ie8 #pma_console .message .action_content { + position: relative!important; +} +#pma_console .message.bookmark .text.targetdb, +#pma_console .message .text.query_time { + margin: 0; + display: inline-block; +} +#pma_console .message.failed .text.query_time, +#pma_console .message .text.failed { + display: none; +} +#pma_console .message.failed .text.failed { + display: inline-block; +} +#pma_console .message .text { + background: #fff; +} +#pma_console .message.collapsed:not(:hover) .action_content { + display: none; +} +#pma_console .message .bookmark_label { + padding: 0 4px; + top: 0; + background: #369; + color: #fff; + border-radius: 3px; +} +#pma_console .message .bookmark_label.shared { + background: #396; +} +#pma_console .message.expanded .bookmark_label { + border-top-left-radius: 0; + border-top-right-radius: 0; +} +#pma_console .query_input { + position: relative; +} +#pma_console .mid_layer { + height: 100%; + width: 100%; + position: absolute; + top: 0; + /* For support IE8, this layer doesn't use filter:opacity or opacity, + js code will fade this layer opacity to 0.18(using animation) */ + background: #666; + display: none; + cursor: pointer; + z-index: 200; +} +#pma_console .card { + position: absolute; + width: 94%; + height: 100%; + min-height: 48px; + <?php echo $left; ?>: 100%; + top: 0; + border-<?php echo $left; ?>: solid 1px #999; + z-index: 300; + transition: <?php echo $left; ?> 0.2s; + -ms-transition: <?php echo $left; ?> 0.2s; + -webkit-transition: <?php echo $left; ?> 0.2s; + -moz-transition: <?php echo $left; ?> 0.2s; +} +#pma_console .card.show { + <?php echo $left; ?>: 6%; + box-shadow: -2px 1px 4px -1px #999; +} + +html.ie7 #pma_console .query_input { + display: none; +} + +#pma_bookmarks .content.add_bookmark, +#pma_console_options .content { + padding: 4px 6px; +} +#pma_bookmarks .content.add_bookmark input[type=text] { + margin: 0; + padding: 2px 4px; +} + +/* Code mirror console style*/ + +.cm-s-pma .CodeMirror-code pre, +.cm-s-pma .CodeMirror-code { + font-family: Monaco, Consolas, monospace; +} +.cm-s-pma .CodeMirror-measure>pre, +.cm-s-pma .CodeMirror-code>pre, +.cm-s-pma .CodeMirror-lines { + padding: 0; +} +.cm-s-pma.CodeMirror { + resize: none; + height: auto; + width: 100%; + min-height: initial; + max-height: initial; +} +.cm-s-pma .CodeMirror-scroll { + padding-bottom: 2em; + cursor: text; +} diff --git a/themes/pmahomme/img/console.png b/themes/pmahomme/img/console.png Binary files differnew file mode 100755 index 0000000000..94bae15eb5 --- /dev/null +++ b/themes/pmahomme/img/console.png diff --git a/transformation_overview.php b/transformation_overview.php index 119436e3c0..23a917c859 100644 --- a/transformation_overview.php +++ b/transformation_overview.php @@ -14,7 +14,7 @@ require_once './libraries/transformations.lib.php'; $response = PMA_Response::getInstance(); $header = $response->getHeader(); -$header->disableMenu(); +$header->disableMenuAndConsole(); $types = PMA_getAvailableMIMEtypes(); ?> |