/* vim: set expandtab sw=4 ts=4 sts=4: */ /** * Used in or for console * * @package phpMyAdmin-Console */ /** * 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").find(">.toolbar"); PMA_console.$consoleContent = $("#pma_console").find(">.content"); PMA_console.$consoleAllContents = $('#pma_console').find('.content'); PMA_console.$consoleTemplates = $('#pma_console').find('>.templates'); // Generate a from for post PMA_console.$requestForm = $('
' ); 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]').prop('checked', true); } if (tempConfig.startHistory === true) { $('#pma_console_options').find('input[name=start_history]').prop('checked', true); } if (tempConfig.currentQuery === true) { $('#pma_console_options').find('input[name=current_query]').prop('checked', true); } if (ConsoleEnterExecutes === true) { $('#pma_console_options').find('input[name=enter_executes]').prop('checked', true); } if (tempConfig.darkTheme === true) { $('#pma_console_options').find('input[name=dark_theme]').prop('checked', true); $('#pma_console').find('>.content').addClass('console_dark_theme'); } } else { $('#pma_console_options').find('input[name=current_query]').prop('checked', true); } PMA_console.updateConfig(); PMA_consoleResizer.initialize(); PMA_consoleInput.initialize(); PMA_consoleMessages.initialize(); PMA_consoleBookmarks.initialize(); PMA_consoleDebug.initialize(); PMA_console.$consoleToolbar.children('.console_switch').click(PMA_console.toggle); $(document).keydown(function(event) { // Ctrl + Alt + C if (event.ctrlKey && event.altKey && event.keyCode === 67) { PMA_console.toggle(); } }); $('#pma_console').find('.toolbar').children().mousedown(function(event) { event.preventDefault(); event.stopImmediatePropagation(); }); $('#pma_console').find('.button.clear').click(function() { PMA_consoleMessages.clear(); }); $('#pma_console').find('.button.history').click(function() { PMA_consoleMessages.showHistory(); }); $('#pma_console').find('.button.options').click(function() { PMA_console.showCard('#pma_console_options'); }); $('#pma_console').find('.button.debug').click(function() { PMA_console.showCard('#debug_console'); }); PMA_console.$consoleContent.click(function(event) { if (event.target == this) { PMA_consoleInput.focus(); } }); $('#pma_console').find('.mid_layer').click(function() { PMA_console.hideCard($(this).parent().children('.card')); }); $('#debug_console').find('.switch_button').click(function() { PMA_console.hideCard($(this).closest('.card')); }); $('#pma_bookmarks').find('.switch_button').click(function() { PMA_console.hideCard($(this).closest('.card')); }); $('#pma_console_options').find('.switch_button').click(function() { PMA_console.hideCard($(this).closest('.card')); }); $('#pma_console_options').find('input[type=checkbox]').change(function() { PMA_console.updateConfig(); }); $('#pma_console_options').find('.button.default').click(function() { $('#pma_console_options input[name=always_expand]').prop('checked', false); $('#pma_console_options').find('input[name=start_history]').prop('checked', false); $('#pma_console_options').find('input[name=current_query]').prop('checked', true); $('#pma_console_options').find('input[name=enter_executes]').prop('checked', false); $('#pma_console_options').find('input[name=dark_theme]').prop('checked', false); PMA_console.updateConfig(); }); $('#pma_console_options').find('input[name=enter_executes]').change(function() { PMA_consoleMessages.showInstructions(PMA_console.config.enterExecutes); }); $(document).ajaxComplete(function (event, xhr, ajaxOptions) { if (ajaxOptions.dataType != 'json') { return; } try { var data = $.parseJSON(xhr.responseText); PMA_console.ajaxCallback(data); } catch (e) { console.log("Invalid JSON!" + e.message); if (AJAX.xhr && AJAX.xhr.status === 0 && AJAX.xhr.statusText !== 'abort') { PMA_ajaxShowMessage($('',{'class':'error','html':PMA_messages.strRequestFailed+' ( '+escapeHtml(AJAX.xhr.statusText)+' )'})); AJAX.active = false; AJAX.xhr = null; } } }); PMA_console.isInitialized = true; } // Change console mode from cookie switch($.cookie('pma_console_mode')) { case 'collapse': PMA_console.collapse(); break; /* jshint -W086 */// no break needed in default section default: $.cookie('pma_console_mode', 'info'); case 'info': /* jshint +W086 */ PMA_console.info(); break; case 'show': PMA_console.show(true); PMA_console.scrollBottom(); break; } }, /** * Execute query and show results in console * * @return void */ execute: function(queryString, options) { if (typeof(queryString) != 'string' || ! /[a-z]|[A-Z]/.test(queryString)) { return; } PMA_console.$requestForm.children('textarea').val(queryString); PMA_console.$requestForm.children('[name=server]').attr('value', PMA_commonParams.get('server')); if (options && options.db) { PMA_console.$requestForm.children('[name=db]').val(options.db); if (options.table) { PMA_console.$requestForm.children('[name=table]').val(options.table); } else { PMA_console.$requestForm.children('[name=table]').val(''); } } else { PMA_console.$requestForm.children('[name=db]').val( (PMA_commonParams.get('db').length > 0 ? PMA_commonParams.get('db') : '')); } PMA_console.$requestForm.find('[name=profiling]').remove(); if (options && options.profiling === true) { PMA_console.$requestForm.append(''); } if (! confirmQuery(PMA_console.$requestForm[0], PMA_console.$requestForm.children('textarea')[0])) { return; } PMA_console.$requestForm.children('[name=console_message_id]') .val(PMA_consoleMessages.appendQuery({sql_query: queryString}).message_id); PMA_console.$requestForm.trigger('submit'); PMA_consoleInput.clear(); PMA_reloadNavigation(); }, ajaxCallback: function(data) { if (data && data.console_message_id) { PMA_consoleMessages.updateQuery(data.console_message_id, data.success, (data._reloadQuerywindow ? data._reloadQuerywindow : false)); } else if ( data && data._reloadQuerywindow) { if (data._reloadQuerywindow.sql_query.length > 0) { PMA_consoleMessages.appendQuery(data._reloadQuerywindow, 'successed') .$message.addClass(PMA_console.config.currentQuery ? '' : 'hide'); } } }, /** * 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 collapse/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').find('.mid_layer').fadeOut(140); $('#pma_console').find('.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').find('input[name=start_history]').prop('checked'), currentQuery: $('#pma_console_options').find('input[name=current_query]').prop('checked'), enterExecutes: $('#pma_console_options').find('input[name=enter_executes]').prop('checked'), darkTheme: $('#pma_console_options').find('input[name=dark_theme]').prop('checked') }; $.cookie('pma_console_config', JSON.stringify(PMA_console.config)); /*Setting the dark theme of the console*/ if (PMA_console.config.darkTheme) { $('#pma_console').find('>.content').addClass('console_dark_theme'); } else { $('#pma_console').find('>.content').removeClass('console_dark_theme'); } }, isSelect: function (queryString) { var reg_exp = /^SELECT\s+/i; return reg_exp.test(queryString); } }; /** * 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) { if (event.pageY < 35) { event.pageY = 35 } 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').find('.toolbar').unbind('mousedown'); $('#pma_console').find('.toolbar').mousedown(PMA_consoleResizer._mousedown); } }; /** * Console input object */ var PMA_consoleInput = { /** * @var array, contains Codemirror objects or input jQuery objects * @access private */ _inputs: null, /** * @var bool, if codemirror enabled * @access private */ _codemirror: false, /** * @var int, count for history navigation, 0 for current input * @access private */ _historyCount: 0, /** * @var string, current input when navigating through history * @access private */ _historyPreserveCurrent: null, /** * Used for console input initialize * * @return void */ initialize: function() { // _cm object can't be reinitialize if (PMA_consoleInput._inputs !== null) { return; } if (typeof CodeMirror !== 'undefined') { PMA_consoleInput._codemirror = true; } PMA_consoleInput._inputs = []; if (PMA_consoleInput._codemirror) { PMA_consoleInput._inputs.console = CodeMirror($('#pma_console').find('.console_query_input')[0], { theme: 'pma', mode: 'text/x-sql', lineWrapping: true, extraKeys: {"Ctrl-Space": "autocomplete"}, hintOptions: {"completeSingle": false, "completeOnSingleClick": true}, gutters: ["CodeMirror-lint-markers"], lint: { "getAnnotations": CodeMirror.sqlLint, "async": true, } }); PMA_consoleInput._inputs.console.on("inputRead", codemirrorAutocompleteOnInputRead); PMA_consoleInput._inputs.console.on("keydown", function(instance, event) { PMA_consoleInput._historyNavigate(event); }); if ($('#pma_bookmarks').length !== 0) { PMA_consoleInput._inputs.bookmark = CodeMirror($('#pma_console').find('.bookmark_add_input')[0], { theme: 'pma', mode: 'text/x-sql', lineWrapping: true, extraKeys: {"Ctrl-Space": "autocomplete"}, hintOptions: {"completeSingle": false, "completeOnSingleClick": true}, gutters: ["CodeMirror-lint-markers"], lint: { "getAnnotations": CodeMirror.sqlLint, "async": true, } }); PMA_consoleInput._inputs.bookmark.on("inputRead", codemirrorAutocompleteOnInputRead); } } else { PMA_consoleInput._inputs.console = $('