~ubuntu-branches/ubuntu/saucy/phpmyadmin/saucy-proposed

« back to all changes in this revision

Viewing changes to js/functions.js

  • Committer: Package Import Robot
  • Author(s): Thijs Kinkhorst
  • Date: 2013-08-04 13:24:37 UTC
  • mfrom: (1.2.44)
  • Revision ID: package-import@ubuntu.com-20130804132437-jznw8efwy4hr1nms
Tags: 4:4.0.5-1
* New upstream release.
  - Fixes security issue PMASA-2013-10.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
var $table_clone=false;var sql_box_locked=false;var only_once_elements=[];var ajax_message_count=0;var codemirror_editor=false;var codemirror_inline_editor=false;var chart_activeTimeouts={};$.ajaxPrefilter(function(a,d,c){var b=new Date().getTime()+""+Math.floor(Math.random()*1000000);if(typeof a.data=="string"){a.data+="&_nocache="+b}else{if(typeof a.data=="object"){a.data=$.extend(d.data,{_nocache:b})}}});function PMA_prepareForAjaxRequest(a){if(!a.find("input:hidden").is("#ajax_request_hidden")){a.append('<input type="hidden" id="ajax_request_hidden" name="ajax_request" value="true" />')}}function suggestPassword(a){var d="abcdefhjmnpqrstuvwxyz23456789ABCDEFGHJKLMNPQRSTUVWYXZ";var e=16;var b=a.generated_pw;b.value="";for(var c=0;c<e;c++){b.value+=d.charAt(Math.floor(Math.random()*d.length))}a.text_pma_pw.value=b.value;a.text_pma_pw2.value=b.value;return true}function parseVersionString(h){if(typeof(h)!="string"){return false}var g=0;var f=h.split("-");if(f.length>=2){if(f[1].substr(0,2)=="rc"){g=-20-parseInt(f[1].substr(2))}else{if(f[1].substr(0,4)=="beta"){g=-40-parseInt(f[1].substr(4))}else{if(f[1].substr(0,5)=="alpha"){g=-60-parseInt(f[1].substr(5))}else{if(f[1].substr(0,3)=="dev"){g=0}}}}}var a=h.split(".");var c=parseInt(a[0])||0;var d=parseInt(a[1])||0;var b=parseInt(a[2])||0;var e=parseInt(a[3])||0;return c*100000000+d*1000000+b*10000+e*100+g}function PMA_current_version(d){if(d&&d.version&&d.date){var e=parseVersionString(pmaversion);var b=parseVersionString(d.version);var f=PMA_messages.strLatestAvailable+" "+escapeHtml(d.version);if(b>e){var c=$.sprintf(PMA_messages.strNewerVersion,escapeHtml(d.version),escapeHtml(d.date));if(Math.floor(b/10000)===Math.floor(e/10000)){var a="error"}else{var a="notice"}$("#maincontainer").after('<div class="'+a+'">'+c+"</div>")}if(b===e){f=" ("+PMA_messages.strUpToDate+")"}$("#li_pma_version").append(f)}}function PMA_display_git_revision(){$("#is_git_revision").remove();$.get("index.php",{server:PMA_commonParams.get("server"),token:PMA_commonParams.get("token"),git_revision:true,ajax_request:true},function(a){if(a.success==true){$(a.message).insertAfter("#li_pma_version")}})}function displayPasswordGenerateButton(){$("#tr_element_before_generate_password").parent().append('<tr class="vmiddle"><td>'+PMA_messages.strGeneratePassword+'</td><td><input type="button" class="button" id="button_generate_password" value="'+PMA_messages.strGenerate+'" onclick="suggestPassword(this.form)" /><input type="text" name="generated_pw" id="generated_pw" /></td></tr>');$("#div_element_before_generate_password").parent().append('<div class="item"><label for="button_generate_password">'+PMA_messages.strGeneratePassword+':</label><span class="options"><input type="button" class="button" id="button_generate_password" value="'+PMA_messages.strGenerate+'" onclick="suggestPassword(this.form)" /></span><input type="text" name="generated_pw" id="generated_pw" /></div>')}function PMA_addDatepicker(d,b){var c=false;if(d.is(".datetimefield")){c=true}var a={showOn:"button",buttonImage:themeCalendarImage,buttonImageOnly:true,stepMinutes:1,stepHours:1,showSecond:true,showTimepicker:c,showButtonPanel:false,dateFormat:"yy-mm-dd",timeFormat:"HH:mm:ss",altFieldTimeOnly:false,showAnim:"",beforeShow:function(e,f){d.data("comes_from","datepicker");setTimeout(function(){$("#ui-timepicker-div").css("z-index",$("#ui-datepicker-div").css("z-index"))},0)},onClose:function(f,e){d.data("comes_from","")}};if(c||(typeof(b)!="undefined"&&b.showTimepicker)){d.datetimepicker($.extend(a,b))}else{d.datepicker($.extend(a,b))}}function selectContent(b,a,c){if(c&&only_once_elements[b.name]){return}only_once_elements[b.name]=true;if(a){return}b.select()}function confirmLink(d,b){if(PMA_messages.strDoYouReally==""||typeof(window.opera)!="undefined"){return true}var a=confirm($.sprintf(PMA_messages.strDoYouReally,b));if(a){if($(d).hasClass("formLinkSubmit")){var c="is_js_confirmed";if($(d).attr("href").indexOf("usesubform")!=-1){c="subform["+$(d).attr("href").substr("#").match(/usesubform\[(\d+)\]/i)[1]+"][is_js_confirmed]"}$(d).parents("form").append('<input type="hidden" name="'+c+'" value="1" />')}else{if(typeof(d.href)!="undefined"){d.href+="&is_js_confirmed=1"}else{if(typeof(d.form)!="undefined"){d.form.action+="?is_js_confirmed=1"}}}}return a}function confirmQuery(d,e){if(PMA_messages.strDoYouReally==""){return true}if(PMA_messages.strNoDropDatabases!=""){var f=new RegExp("(^|;)\\s*DROP\\s+(IF EXISTS\\s+)?DATABASE\\s","i");if(f.test(e.value)){alert(PMA_messages.strNoDropDatabases);d.reset();e.focus();return false}}var b=new RegExp("^\\s*DROP\\s+(IF EXISTS\\s+)?(TABLE|DATABASE|PROCEDURE)\\s","i");var a=new RegExp("^\\s*ALTER\\s+TABLE\\s+((`[^`]+`)|([A-Za-z0-9_$]+))\\s+DROP\\s","i");var h=new RegExp("^\\s*DELETE\\s+FROM\\s","i");var g=new RegExp("^\\s*TRUNCATE\\s","i");if(b.test(e.value)||a.test(e.value)||h.test(e.value)||g.test(e.value)){var i=(e.value.length>100)?e.value.substr(0,100)+"\n    ...":e.value;var c=confirm($.sprintf(PMA_messages.strDoYouReally,i));if(c){d.elements.is_js_confirmed.value=1;return true}else{window.focus();e.focus();return false}}return true}function checkSqlQuery(d){if(codemirror_editor){d.elements.sql_query.value=codemirror_editor.getValue()}var b=d.elements.sql_query;var c=1;var a=new RegExp("\\s+");if(typeof(d.elements.sql_file)!="undefined"&&d.elements.sql_file.value.replace(a,"")!=""){return true}if(typeof(d.elements.sql_localfile)!="undefined"&&d.elements.sql_localfile.value.replace(a,"")!=""){return true}if(c&&typeof(d.elements.id_bookmark)!="undefined"&&(d.elements.id_bookmark.value!=null||d.elements.id_bookmark.value!="")&&d.elements.id_bookmark.selectedIndex!=0){return true}if(b.value.replace(a,"")!=""){if(confirmQuery(d,b)){return true}else{return false}}d.reset();c=1;if(c){b.select();alert(PMA_messages.strFormEmpty);b.focus();return false}return true}function emptyCheckTheField(d,b){var a=d.elements[b];var c=new RegExp("\\s+");return(a.value.replace(c,"")=="")?1:0}function emptyFormElements(d,b){var a=d.elements[b];var c=emptyCheckTheField(d,b);return c}function checkFormElementInRange(g,d,e,c,b){var a=g.elements[d];var f=parseInt(a.value);if(typeof(c)=="undefined"){c=0}if(typeof(b)=="undefined"){b=Number.MAX_VALUE}if(isNaN(f)){a.select();alert(PMA_messages.strNotNumber);a.focus();return false}else{if(f<c||f>b){a.select();alert($.sprintf(e,f));a.focus();return false}else{a.value=f}}return true}function checkTableEditForm(g,j){var f=0;var e,h,a,k,d,c;for(e=0;e<j;e++){c="#field_"+e+"_2";h=$(c);d=h.val();if(d=="VARCHAR"||d=="CHAR"||d=="BIT"||d=="VARBINARY"||d=="BINARY"){a=$("#field_"+e+"_3");d=parseInt(a.val());k=$("#field_"+e+"_1");if(isNaN(d)&&k.val()!=""){a.select();alert(PMA_messages.strNotNumber);a.focus();return false}}if(f==0){c="field_"+e+"_1";if(!emptyCheckTheField(g,c)){f=1}}}if(f==0){var b=g.elements.field_0_1;alert(PMA_messages.strFormEmpty);b.focus();return false}if($("input.textfield[name='table']").val()==""){alert(PMA_messages.strFormEmpty);$("input.textfield[name='table']").focus();return false}return true}AJAX.registerTeardown("functions.js",function(){$("input:checkbox.checkall").die("click")});AJAX.registerOnload("functions.js",function(){$("input:checkbox.checkall").live("click",function(g){var d=$(this).closest("tr");if(!g.shiftKey||last_clicked_row==-1){var b=d.find(":checkbox");if(b.length){var c=b.prop("checked");if(!$(g.target).is(":checkbox, label")){c=!c;b.prop("checked",c).trigger("change")}if(c){d.addClass("marked")}else{d.removeClass("marked")}last_click_checked=c}else{d.toggleClass("marked");last_click_checked=false}last_clicked_row=last_click_checked?$("tr.odd:not(.noclick), tr.even:not(.noclick)").index(d):-1;last_shift_clicked_row=-1}else{PMA_clearSelection();var h,a;if(last_shift_clicked_row>=0){if(last_shift_clicked_row>=last_clicked_row){h=last_clicked_row;a=last_shift_clicked_row}else{h=last_shift_clicked_row;a=last_clicked_row}d.parent().find("tr.odd:not(.noclick), tr.even:not(.noclick)").slice(h,a+1).removeClass("marked").find(":checkbox").prop("checked",false).trigger("change")}var f=$("tr.odd:not(.noclick), tr.even:not(.noclick)").index(d);if(f>=last_clicked_row){h=last_clicked_row;a=f}else{h=f;a=last_clicked_row}d.parent().find("tr.odd:not(.noclick), tr.even:not(.noclick)").slice(h,a+1).addClass("marked").find(":checkbox").prop("checked",true).trigger("change");last_shift_clicked_row=f}});addDateTimePicker();if(navigator.userAgent.match(/(iphone|ipod|ipad)/i)){$("input[type=text]").attr("autocapitalize","off").attr("autocorrect","off")}});var last_click_checked=false;var last_clicked_row=-1;var last_shift_clicked_row=-1;var marked_row=[];function markAllRows(a){$("#"+a).find("input:checkbox:enabled").prop("checked",true).trigger("change").parents("tr").addClass("marked");return true}function unMarkAllRows(a){$("#"+a).find("input:checkbox:enabled").prop("checked",false).trigger("change").parents("tr").removeClass("marked");return true}function setCheckboxes(b,a){$("#"+b).find("input:checkbox").prop("checked",a);return true}function setSelectOptions(b,a,c){$("form[name='"+b+"'] select[name='"+a+"']").find("option").prop("selected",c);return true}function setQuery(a){if(codemirror_editor){codemirror_editor.setValue(a);codemirror_editor.focus()}else{document.sqlform.sql_query.value=a;document.sqlform.sql_query.focus()}}function insertQuery(c){if(c=="clear"){setQuery("");return}var f="";var a=document.sqlform.dummy;var h=document.sqlform.table.value;if(a.options.length>0){sql_box_locked=true;var b="";var g="";var e="";var j=0;for(var d=0;d<a.options.length;d++){j++;if(j>1){b+=", ";g+=",";e+=","}b+=a.options[d].value;g+="[value-"+j+"]";e+=a.options[d].value+"=[value-"+j+"]"}if(c=="selectall"){f="SELECT * FROM `"+h+"` WHERE 1"}else{if(c=="select"){f="SELECT "+b+" FROM `"+h+"` WHERE 1"}else{if(c=="insert"){f="INSERT INTO `"+h+"`("+b+") VALUES ("+g+")"}else{if(c=="update"){f="UPDATE `"+h+"` SET "+e+" WHERE 1"}else{if(c=="delete"){f="DELETE FROM `"+h+"` WHERE 1"}}}}}setQuery(f);sql_box_locked=false}}function insertValueQuery(){var h=document.sqlform.sql_query;var d=document.sqlform.dummy;if(d.options.length>0){sql_box_locked=true;var e="";var j=0;for(var f=0;f<d.options.length;f++){if(d.options[f].selected){j++;if(j>1){e+=", "}e+=d.options[f].value}}if(codemirror_editor){codemirror_editor.replaceSelection(e)}else{if(document.selection){h.focus();var c=document.selection.createRange();c.text=e;document.sqlform.insert.focus()}else{if(document.sqlform.sql_query.selectionStart||document.sqlform.sql_query.selectionStart=="0"){var g=document.sqlform.sql_query.selectionStart;var b=document.sqlform.sql_query.selectionEnd;var a=document.sqlform.sql_query.value;h.value=a.substring(0,g)+e+a.substring(b,a.length)}else{h.value+=e}}}sql_box_locked=false}}function addDateTimePicker(){if($.timepicker!=undefined){$("input.datefield, input.datetimefield").each(function(){PMA_addDatepicker($(this))})}}function refreshLayout(){var c=$("#pdflayout");var d=$("#orientation_opt").val();if($("#paper_opt").length==1){var e=$("#paper_opt").val()}else{var e="A4"}if(d=="P"){var b="x";var a="y"}else{var b="y";var a="x"}c.css("width",pdfPaperSize(e,b)+"px");c.css("height",pdfPaperSize(e,a)+"px")}function TableDragInit(){$(".pdflayout_table").each(function(){var c=$(this);var b=c.data("number");var a=$("#c_table_"+b+"_x").val();var d=$("#c_table_"+b+"_y").val();c.css("left",a+"px");c.css("top",d+"px");c.draggable({containment:"parent",drag:function(e,g){var f=c.data("number");$("#c_table_"+f+"_x").val(parseInt(g.position.left));$("#c_table_"+f+"_y").val(parseInt(g.position.top))}})})}function resetDrag(){$(".pdflayout_table").each(function(){var b=$(this);var a=b.data("x");var c=b.data("y");b.css("left",a+"px");b.css("top",c+"px")})}$(function(){$(".position-change").live("change",function(){var b=$(this);var a=$("#table_"+b.data("number"));a.css(b.data("axis"),b.val()+"px")});$(".paper-change").live("change",function(){var a=$("#pdflayout");if(a.css("visibility")=="visible"){refreshLayout();TableDragInit()}});$("#toggle-dragdrop").live("click",function(){var a=$("#pdflayout");if(a.css("visibility")=="hidden"){refreshLayout();TableDragInit();a.css("visibility","visible");a.css("display","block");$("#showwysiwyg").val("1")}else{a.css("visibility","hidden");a.css("display","none");$("#showwysiwyg").val("0")}});$("#reset-dragdrop").live("click",function(){resetDrag()})});function pdfPaperSize(b,a){switch(b.toUpperCase()){case"4A0":if(a=="x"){return 4767.87}else{return 6740.79}break;case"2A0":if(a=="x"){return 3370.39}else{return 4767.87}break;case"A0":if(a=="x"){return 2383.94}else{return 3370.39}break;case"A1":if(a=="x"){return 1683.78}else{return 2383.94}break;case"A2":if(a=="x"){return 1190.55}else{return 1683.78}break;case"A3":if(a=="x"){return 841.89}else{return 1190.55}break;case"A4":if(a=="x"){return 595.28}else{return 841.89}break;case"A5":if(a=="x"){return 419.53}else{return 595.28}break;case"A6":if(a=="x"){return 297.64}else{return 419.53}break;case"A7":if(a=="x"){return 209.76}else{return 297.64}break;case"A8":if(a=="x"){return 147.4}else{return 209.76}break;case"A9":if(a=="x"){return 104.88}else{return 147.4}break;case"A10":if(a=="x"){return 73.7}else{return 104.88}break;case"B0":if(a=="x"){return 2834.65}else{return 4008.19}break;case"B1":if(a=="x"){return 2004.09}else{return 2834.65}break;case"B2":if(a=="x"){return 1417.32}else{return 2004.09}break;case"B3":if(a=="x"){return 1000.63}else{return 1417.32}break;case"B4":if(a=="x"){return 708.66}else{return 1000.63}break;case"B5":if(a=="x"){return 498.9}else{return 708.66}break;case"B6":if(a=="x"){return 354.33}else{return 498.9}break;case"B7":if(a=="x"){return 249.45}else{return 354.33}break;case"B8":if(a=="x"){return 175.75}else{return 249.45}break;case"B9":if(a=="x"){return 124.72}else{return 175.75}break;case"B10":if(a=="x"){return 87.87}else{return 124.72}break;case"C0":if(a=="x"){return 2599.37}else{return 3676.54}break;case"C1":if(a=="x"){return 1836.85}else{return 2599.37}break;case"C2":if(a=="x"){return 1298.27}else{return 1836.85}break;case"C3":if(a=="x"){return 918.43}else{return 1298.27}break;case"C4":if(a=="x"){return 649.13}else{return 918.43}break;case"C5":if(a=="x"){return 459.21}else{return 649.13}break;case"C6":if(a=="x"){return 323.15}else{return 459.21}break;case"C7":if(a=="x"){return 229.61}else{return 323.15}break;case"C8":if(a=="x"){return 161.57}else{return 229.61}break;case"C9":if(a=="x"){return 113.39}else{return 161.57}break;case"C10":if(a=="x"){return 79.37}else{return 113.39}break;case"RA0":if(a=="x"){return 2437.8}else{return 3458.27}break;case"RA1":if(a=="x"){return 1729.13}else{return 2437.8}break;case"RA2":if(a=="x"){return 1218.9}else{return 1729.13}break;case"RA3":if(a=="x"){return 864.57}else{return 1218.9}break;case"RA4":if(a=="x"){return 609.45}else{return 864.57}break;case"SRA0":if(a=="x"){return 2551.18}else{return 3628.35}break;case"SRA1":if(a=="x"){return 1814.17}else{return 2551.18}break;case"SRA2":if(a=="x"){return 1275.59}else{return 1814.17}break;case"SRA3":if(a=="x"){return 907.09}else{return 1275.59}break;case"SRA4":if(a=="x"){return 637.8}else{return 907.09}break;case"LETTER":if(a=="x"){return 612}else{return 792}break;case"LEGAL":if(a=="x"){return 612}else{return 1008}break;case"EXECUTIVE":if(a=="x"){return 521.86}else{return 756}break;case"FOLIO":if(a=="x"){return 612}else{return 936}break}return 0}AJAX.registerTeardown("functions.js",function(){$("a.inline_edit_sql").die("click");$("input#sql_query_edit_save").die("click");$("input#sql_query_edit_discard").die("click");$("input.sqlbutton").unbind("click");$("#export_type").unbind("change");$("#sqlquery").unbind("keydown");$("#sql_query_edit").unbind("keydown");if(codemirror_inline_editor){$("#sql_query_edit").text(codemirror_inline_editor.getValue());$(codemirror_inline_editor.getWrapperElement()).unbind("keydown");codemirror_inline_editor.toTextArea();codemirror_inline_editor=false}if(codemirror_editor){$(codemirror_editor.getWrapperElement()).unbind("keydown")}});AJAX.registerOnload("functions.js",function(){bindCodeMirrorToInlineEditor();$("a.inline_edit_sql").live("click",function(){if($("#sql_query_edit").length){return false}var a=$(this).prev("form");var f=a.find("input[name='sql_query']").val();var e=$(this).parent().prev().find(".inner_sql");var d=e.html();var c='<textarea name="sql_query_edit" id="sql_query_edit">'+f+"</textarea>\n";c+='<input type="submit" id="sql_query_edit_save" class="button btnSave" value="'+PMA_messages.strGo+'"/>\n';c+='<input type="button" id="sql_query_edit_discard" class="button btnDiscard" value="'+PMA_messages.strCancel+'"/>\n';var b=$("div#inline_editor");if(b.length==0){b=$('<div id="inline_editor_outer"></div>');b.insertBefore(e)}b.html(c);e.hide();bindCodeMirrorToInlineEditor();return false});$("input#sql_query_edit_save").live("click",function(){if(codemirror_inline_editor){var b=codemirror_inline_editor.getValue()}else{var b=$(this).prev().val()}var a=$("a.inline_edit_sql").prev("form");var c=$("<form>",{action:"import.php",method:"post"}).append(a.find("input[name=server], input[name=db], input[name=table], input[name=token]").clone()).append($("<input/>",{type:"hidden",name:"show_query",value:1})).append($("<input/>",{type:"hidden",name:"sql_query",value:b}));c.appendTo($("body")).submit()});$("input#sql_query_edit_discard").live("click",function(){$("div#inline_editor_outer").empty().siblings(".inner_sql").show()});$("input.sqlbutton").click(function(a){insertQuery(a.target.id);return false});$("#export_type").change(function(){if($("#export_type").val()=="svg"){$("#show_grid_opt").prop("disabled",true);$("#orientation_opt").prop("disabled",true);$("#with_doc").prop("disabled",true);$("#show_table_dim_opt").removeProp("disabled");$("#all_tables_same_width").removeProp("disabled");$("#paper_opt").removeProp("disabled");$("#show_color_opt").removeProp("disabled")}else{if($("#export_type").val()=="dia"){$("#show_grid_opt").prop("disabled",true);$("#with_doc").prop("disabled",true);$("#show_table_dim_opt").prop("disabled",true);$("#all_tables_same_width").prop("disabled",true);$("#paper_opt").removeProp("disabled");$("#show_color_opt").removeProp("disabled");$("#orientation_opt").removeProp("disabled")}else{if($("#export_type").val()=="eps"){$("#show_grid_opt").prop("disabled",true);$("#orientation_opt").removeProp("disabled");$("#with_doc").prop("disabled",true);$("#show_table_dim_opt").prop("disabled",true);$("#all_tables_same_width").prop("disabled",true);$("#paper_opt").prop("disabled",true);$("#show_color_opt").prop("disabled",true)}else{if($("#export_type").val()=="pdf"){$("#show_grid_opt").removeProp("disabled");$("#orientation_opt").removeProp("disabled");$("#with_doc").removeProp("disabled");$("#show_table_dim_opt").removeProp("disabled");$("#all_tables_same_width").removeProp("disabled");$("#paper_opt").removeProp("disabled");$("#show_color_opt").removeProp("disabled")}else{}}}}});if($("#input_username")){if($("#input_username").val()==""){$("#input_username").focus()}else{$("#input_password").focus()}}});function bindCodeMirrorToInlineEditor(){var b=$("#sql_query_edit");if(b.length>0){if(typeof CodeMirror!=="undefined"){var a=$("#sql_query_edit").css("height");codemirror_inline_editor=CodeMirror.fromTextArea(b[0],{lineNumbers:true,matchBrackets:true,indentUnit:4,mode:"text/x-mysql",lineWrapping:true});codemirror_inline_editor.getScrollerElement().style.height=a;codemirror_inline_editor.refresh();codemirror_inline_editor.focus();$(codemirror_inline_editor.getWrapperElement()).bind("keydown",catchKeypressesFromSqlTextboxes)}else{b.focus().bind("keydown",catchKeypressesFromSqlTextboxes)}}}function catchKeypressesFromSqlTextboxes(a){if(a.ctrlKey&&(a.keyCode==13||a.keyCode==10)){if($("#sql_query_edit").length>0){$("#sql_query_edit_save").trigger("click")}else{if($("#sqlquery").length>0){$("#button_submit_query").trigger("click")}}}}function PMA_ajaxShowMessage(c,d){var b=true;var e=true;if(c==""){return true}else{if(!c){c=PMA_messages.strLoading;e=false;b=false}else{if(c==PMA_messages.strProcessingRequest){e=false;b=false}}}if(d==undefined){d=5000}else{if(d===false){b=false}}if($("#loading_parent").length==0){$('<div id="loading_parent"></div>').prependTo("body")}ajax_message_count++;$("span.ajax_notification[id^=ajax_message_num]").remove();var a=$('<span class="ajax_notification" id="ajax_message_num_'+ajax_message_count+'"></span>').hide().appendTo("#loading_parent").html(c).show();if(b){a.delay(d).fadeOut("medium",function(){if($(this).is(".dismissable")){$(this).tooltip("destroy")}$(this).remove()})}if(e){a.addClass("dismissable").css("cursor","pointer");PMA_tooltip(a,"span",PMA_messages.strDismiss)}return a}function PMA_ajaxRemoveMessage(a){if(a!=undefined&&a instanceof jQuery){a.stop(true,true).fadeOut("medium");if(a.is(".dismissable")){if($.isFunction(a.tooltip)){a.tooltip("destroy")}}else{a.remove()}}}$(function(){$("span.ajax_notification.dismissable").live("click",function(){PMA_ajaxRemoveMessage($(this))});$("span.ajax_notification a, span.ajax_notification button, span.ajax_notification input").live("mouseover",function(){$(this).parents("span.ajax_notification").tooltip("disable")}).live("mouseout",function(){$(this).parents("span.ajax_notification").tooltip("enable")})});function PMA_showNoticeForEnum(a){var b=a.attr("id").split("_")[1];b+="_"+(parseInt(a.attr("id").split("_")[2])+1);var c=a.val();if(c=="ENUM"||c=="SET"){$("p#enum_notice_"+b).show()}else{$("p#enum_notice_"+b).hide()}}function PMA_createProfilingChartJqplot(b,a){return $.jqplot(b,[a],{seriesDefaults:{renderer:$.jqplot.PieRenderer,rendererOptions:{showDataLabels:true}},legend:{show:true,location:"e"},seriesColors:["#fce94f","#fcaf3e","#e9b96e","#8ae234","#729fcf","#ad7fa8","#ef2929","#eeeeec","#888a85","#c4a000","#ce5c00","#8f5902","#4e9a06","#204a87","#5c3566","#a40000","#babdb6","#2e3436"]})}function PMA_prettyProfilingNum(a,b){if(!b){b=2}b=Math.pow(10,b);if(a*1000<0.1){a=Math.round(b*(a*1000*1000))/b+"µ"}else{if(a<0.1){a=Math.round(b*(a*1000))/b+"m"}else{a=Math.round(b*a)/b}}return a+"s"}function PMA_SQLPrettyPrint(a){if(typeof CodeMirror=="undefined"){return a}var l=CodeMirror.getMode({},"text/x-mysql");var e=new CodeMirror.StringStream(a);var d=l.startState();var g,m=[];var h="";var t=function(y){var w="";for(var x=0;x<4*y;x++){w+=" "}return w};var u={select:["select","from","on","where","having","limit","order by","group by"],update:["update","set","where"],"insert into":["insert into","values"]};var k={";":true,",":true,".":true,"(":true};var n={".":true};var o="";while(!e.eol()){e.start=e.pos;g=l.token(e,d);if(g!=null){m.push([g,e.current().toLowerCase()])}}var q=m[0][1];if(!u[q]){return a}var s=[];var f;var b,c;var p=0;var j,v=u[q][0];s.unshift("statement");for(var r=0;r<m.length;r++){f=s[0];if(m[r][1]=="("){if(r<m.length-1&&m[r+1][0]=="statement-verb"){s.unshift(b="statement")}else{if(r>0&&m[r-1][0]=="builtin"){s.unshift(b="function")}else{s.unshift(b="generic")}}}else{b=null}if(m[r][1]==")"){c=s[0];s.shift()}else{c=null}if(r>0&&b=="statement"){p++;h+="\n"+t(p)+m[r][1]+" "+m[r+1][1].toUpperCase()+"\n"+t(p+1);q=m[r+1][1];r++;continue}if(c=="statement"&&p>0){h+="\n"+t(p);p--}j=u[q].indexOf(m[r][1]);if(j!=-1){if(r>0){h+="\n"}h+=t(p)+m[r][1].toUpperCase();h+="\n"+t(p+1);v=m[r][1]}else{if(!k[m[r][1]]&&!(r>0&&n[m[r-1][1]])&&h.charAt(h.length-1)!=" "){h+=" "}if(m[r][0]=="keyword"){h+=m[r][1].toUpperCase()}else{h+=m[r][1]}}if((v=="select"||v=="where"||v=="set")&&m[r][1]==","&&s[0]=="statement"){h+="\n"+t(p+1)}if(v=="where"&&(m[r][1]=="and"||m[r][1]=="or"||m[r][1]=="xor")){if(s[0]=="statement"){h+="\n"+t(p+1)}}}return h}jQuery.fn.PMA_confirm=function(b,d,a){var e=PMA_commonParams.get("confirm");if(e===""||e==="1"){if($.isFunction(a)){a.call(this,d);return true}}if(PMA_messages.strDoYouReally==""){return true}var c={};c[PMA_messages.strOK]=function(){$(this).dialog("close");if($.isFunction(a)){a.call(this,d)}};c[PMA_messages.strCancel]=function(){$(this).dialog("close")};$("<div/>",{id:"confirm_dialog"}).prepend(b).dialog({buttons:c,close:function(){$(this).remove()},modal:true})};jQuery.fn.PMA_sort_table=function(a){return this.each(function(){var c=$(this);var b=$(this).find("tr").get();$.each(b,function(d,e){e.sortKey=$.trim($(e).find(a).text().toLowerCase())});b.sort(function(e,d){if(e.sortKey<d.sortKey){return -1}if(e.sortKey>d.sortKey){return 1}return 0});$.each(b,function(d,e){$(c).append(e);e.sortKey=null});$(this).find("tr:odd").removeClass("even").addClass("odd").end().find("tr:even").removeClass("odd").addClass("even")})};AJAX.registerTeardown("functions.js",function(){$("#create_table_form_minimal.ajax").die("submit");$("form.create_table_form.ajax").die("submit");$("form.create_table_form.ajax input[name=submit_num_fields]").die("click");$("form.create_table_form.ajax input").die("keyup")});AJAX.registerOnload("functions.js",function(){$("form.create_table_form.ajax").live("submit",function(b){b.preventDefault();var a=$(this);if(checkTableEditForm(a[0],a.find("input[name=orig_num_fields]").val())){PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);PMA_prepareForAjaxRequest(a);$.post(a.attr("action"),a.serialize()+"&do_save_data=1",function(i){if(i.success==true){$("#properties_message").removeClass("error").html("");PMA_ajaxShowMessage(i.message);if($("#create_table_dialog").length>0){$("#create_table_dialog").dialog("close").remove()}$("#tableslistcontainer").before(i.formatted_sql);var f=$("#tablesForm").find("tbody").not("#tbl_summary_row");if(f.length==0){PMA_commonActions.refreshMain(PMA_commonParams.get("opendb_url"))}else{var h=$(f).find("tr:last");var g=$(h).find("input:checkbox").attr("id").match(/\d+/)[0];var d=parseFloat(g);var c=d+1;var e="checkbox_tbl_"+c;i.new_table_string=i.new_table_string.replace(/checkbox_tbl_/,e);$(i.new_table_string).appendTo(f);$(f).PMA_sort_table("th");PMA_adjustTotals()}PMA_reloadNavigation()}else{PMA_ajaxShowMessage('<div class="error">'+i.error+"</div>",false)}})}});$("form.create_table_form.ajax input[name=submit_num_fields]").live("click",function(b){b.preventDefault();var a=$(this).closest("form");var c=PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);PMA_prepareForAjaxRequest(a);$.post(a.attr("action"),a.serialize()+"&submit_num_fields=1",function(d){if(d.success){$("#page_content").html(d.message);PMA_verifyColumnsProperties();PMA_ajaxRemoveMessage(c)}else{PMA_ajaxShowMessage(d.error)}})});$("form.create_table_form.ajax input").live("keydown",function(a){if(a.keyCode==13){a.preventDefault();a.stopImmediatePropagation();$(this).closest("form").append('<input type="hidden" name="do_save_data" value="1" />').submit()}})});AJAX.registerTeardown("functions.js",function(){$("#copyTable.ajax").die("submit");$("#moveTableForm").die("submit");$("#tableOptionsForm").die("submit");$("#tbl_maintenance li a.maintain_action.ajax").die("click")});AJAX.registerOnload("functions.js",function(){$("#copyTable.ajax").live("submit",function(b){b.preventDefault();var a=$(this);PMA_prepareForAjaxRequest(a);$.post(a.attr("action"),a.serialize()+"&submit_copy=Go",function(c){if(c.success==true){if(a.find("input[name='switch_to_new']").prop("checked")){PMA_commonParams.set("db",c.db);PMA_commonParams.set("table",a.find("input[name='new_name']").val());PMA_commonActions.refreshMain(false,function(){PMA_ajaxShowMessage(c.message)})}else{PMA_ajaxShowMessage(c.message)}PMA_reloadNavigation()}else{PMA_ajaxShowMessage(c.error,false)}})});$("#moveTableForm").live("submit",function(c){c.preventDefault();var b=$(this);var a=b.find("select[name=target_db]").val();var d=b.find("input[name=new_name]").val();PMA_prepareForAjaxRequest(b);$.post(b.attr("action"),b.serialize()+"&submit_move=1",function(e){if(e.success==true){PMA_commonParams.set("db",a);PMA_commonParams.set("table",d);PMA_commonActions.refreshMain(false,function(){PMA_ajaxShowMessage(e.message)});PMA_reloadNavigation()}else{PMA_ajaxShowMessage(e.error,false)}})});$("#tableOptionsForm").live("submit",function(c){c.preventDefault();c.stopPropagation();var b=$(this);var a=b.find("input[name=new_name]");if(a.val()!==a[0].defaultValue){PMA_prepareForAjaxRequest(b);var d=a.val();$.post(b.attr("action"),b.serialize(),function(e){if(e.success==true){PMA_commonParams.set("table",d);PMA_commonActions.refreshMain(false,function(){$("#page_content").html(e.message)})}else{PMA_ajaxShowMessage(e.error,false)}})}else{b.removeClass("ajax").submit().addClass("ajax")}});$("#tbl_maintenance li a.maintain_action.ajax").live("click",function(a){a.preventDefault();if($("#sqlqueryresults").length!=0){$("#sqlqueryresults").remove()}if($("#result_query").length!=0){$("#result_query").remove()}$.post($(this).attr("href"),{ajax_request:1},function(f){function d(){$("html, body").animate({scrollTop:0})}if(f.success==true&&f.sql_query!=undefined){PMA_ajaxShowMessage(f.message);$("<div id='sqlqueryresults' class='ajax'></div>").prependTo("#page_content");$("#sqlqueryresults").html(f.sql_query);d()}else{if(f.success==true){var c=$("<div id='temp_div'></div>");c.html(f.message);var e=c.find("#result_query .success");PMA_ajaxShowMessage(e);$("<div id='sqlqueryresults' class='ajax'></div>").prependTo("#page_content");$("#sqlqueryresults").html(f.message);PMA_init_slider();$("#sqlqueryresults").children("fieldset,br").remove();d()}else{var c=$("<div id='temp_div'></div>");c.html(f.error);var b=c.find("code").addClass("error");PMA_ajaxShowMessage(b,false)}}})})});AJAX.registerTeardown("functions.js",function(){$("#drop_db_anchor.ajax").die("click")});AJAX.registerOnload("functions.js",function(){$("#drop_db_anchor.ajax").live("click",function(b){b.preventDefault();var a=PMA_messages.strDropDatabaseStrongWarning+" ";a+=$.sprintf(PMA_messages.strDoYouReally,"DROP DATABASE "+escapeHtml(PMA_commonParams.get("db")));$(this).PMA_confirm(a,$(this).attr("href"),function(c){PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);$.get(c,{is_js_confirmed:"1",ajax_request:true},function(d){if(d.success){PMA_reloadNavigation();PMA_commonParams.set("db","");PMA_commonActions.refreshMain("server_databases.php",function(){PMA_ajaxShowMessage(d.message)})}else{PMA_ajaxShowMessage(d.error,false)}})})})});function PMA_checkPassword(e){if(e.find("#nopass_1").is(":checked")){return true}else{var d=e.find("#select_pred_password");if(d.length&&(d.val()=="none"||d.val()=="keep")){return true}}var a=e.find("input[name=pma_pw]");var c=e.find("input[name=pma_pw2]");var b=false;if(a.val()==""){b=PMA_messages.strPasswordEmpty}else{if(a.val()!=c.val()){b=PMA_messages.strPasswordNotSame}}if(b){alert(b);a.val("");c.val("");a.focus();return false}return true}AJAX.registerTeardown("functions.js",function(){$("#change_password_anchor.ajax").die("click")});AJAX.registerOnload("functions.js",function(){$("#change_password_anchor.ajax").live("click",function(b){b.preventDefault();var c=PMA_ajaxShowMessage();var a={};a[PMA_messages.strGo]=function(){b.preventDefault();var f=$("#change_password_form");if(!PMA_checkPassword(f)){return false}var d=$(this).val();var e=PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);f.append('<input type="hidden" name="ajax_request" value="true" />');$.post(f.attr("action"),f.serialize()+"&change_pw="+d,function(g){if(g.success==true){$("#page_content").prepend(g.message);$("#change_password_dialog").hide().remove();$("#edit_user_dialog").dialog("close").remove();PMA_ajaxRemoveMessage(e)}else{PMA_ajaxShowMessage(g.error,false)}})};a[PMA_messages.strCancel]=function(){$(this).dialog("close")};$.get($(this).attr("href"),{ajax_request:true},function(d){if(d.success){$('<div id="change_password_dialog"></div>').dialog({title:PMA_messages.strChangePassword,width:600,close:function(e,f){$(this).remove()},buttons:a,modal:true}).append(d.message);$("fieldset#fieldset_change_password").find("legend").remove().end().find("table.noclick").unwrap().addClass("some-margin").find("input#text_pma_pw").focus();displayPasswordGenerateButton();$("#fieldset_change_password_footer").hide();PMA_ajaxRemoveMessage(c);$("#change_password_form").bind("submit",function(f){f.preventDefault();$(this).closest(".ui-dialog").find(".ui-dialog-buttonpane .ui-button").first().click()})}else{PMA_ajaxShowMessage(d.error,false)}})})});AJAX.registerTeardown("functions.js",function(){$("select.column_type").die("change");$("select.default_type").die("change");$("input.allow_null").die("change")});AJAX.registerOnload("functions.js",function(){PMA_verifyColumnsProperties();$("select.column_type").live("change",function(){PMA_showNoticeForEnum($(this))});$("select.default_type").live("change",function(){PMA_hideShowDefaultValue($(this))});$("input.allow_null").live("change",function(){PMA_validateDefaultValue($(this))})});function PMA_verifyColumnsProperties(){$("select.column_type").each(function(){PMA_showNoticeForEnum($(this))});$("select.default_type").each(function(){PMA_hideShowDefaultValue($(this))})}function PMA_hideShowDefaultValue(b){if(b.val()=="USER_DEFINED"){b.siblings(".default_value").show().focus()}else{b.siblings(".default_value").hide();if(b.val()=="NULL"){var a=b.closest("tr").find(".allow_null");a.prop("checked",true)}}}function PMA_validateDefaultValue(b){if(!b.prop("checked")){var a=b.closest("tr").find(".default_type");if(a.val()=="NULL"){a.val("NONE")}}}AJAX.registerTeardown("functions.js",function(){$("a.open_enum_editor").die("click");$("input.add_value").die("click");$("#enum_editor td.drop").die("click")});var $enum_editor_dialog=null;AJAX.registerOnload("functions.js",function(){$("a.open_enum_editor").live("click",function(){var e=$(this).closest("tr").find("input:first").val();if(e.length<1){var m=PMA_messages.enum_newColumnVals}else{var m=PMA_messages.enum_columnVals.replace(/%s/,'"'+decodeURIComponent(e)+'"')}var k=$(this).closest("td").find("input").val();k=$("<div/>").text(k).html();var n=[];var j=false;var o,f,c="";for(var d=0;d<k.length;d++){o=k.charAt(d);f=d==k.length?"":k.charAt(d+1);if(!j&&o=="'"){j=true}else{if(j&&o=="\\"&&f=="\\"){c+="&#92;";d++}else{if(j&&f=="'"&&(o=="'"||o=="\\")){c+="&#39;";d++}else{if(j&&o=="'"){j=false;n.push(c);c=""}else{if(j){c+=o}}}}}}if(c.length>0){n.push(c)}var g="";if(n.length==0){n.push("","","","")}var l=PMA_getImage("b_drop.png");for(var d=0;d<n.length;d++){g+="<tr><td><input type='text' value='"+n[d]+"'/></td><td class='drop'>"+l+"</td></tr>"}var h="<div id='enum_editor'><fieldset><legend>"+m+"</legend><p>"+PMA_getImage("s_notice.png")+PMA_messages.enum_hint+"</p><table class='values'>"+g+"</table></fieldset><fieldset class='tblFooters'><table class='add'><tr><td><div class='slider'></div></td><td><form><div><input type='submit' class='add_value' value='"+$.sprintf(PMA_messages.enum_addValue,1)+"'/></div></form></td></tr></table><input type='hidden' value='"+$(this).closest("td").find("input").attr("id")+"' /></fieldset></div>";var b={};b[PMA_messages.strGo]=function(){var i=[];$(this).find(".values input").each(function(q,s){var r=s.value.replace(/\\/g,"\\\\").replace(/'/g,"''");i.push("'"+r+"'")});var p=$(this).find("input[type='hidden']").val();$("input#"+p).val(i.join(","));$(this).dialog("close")};b[PMA_messages.strClose]=function(){$(this).dialog("close")};var a=parseInt((parseInt($("html").css("font-size"),10)/13)*340,10);if(!a){a=340}$enum_editor_dialog=$(h).dialog({minWidth:a,modal:true,title:PMA_messages.enum_editor,buttons:b,open:function(){$(this).closest(".ui-dialog").find(".ui-dialog-buttonpane button:first").focus()},close:function(){$(this).remove()}});$enum_editor_dialog.find(".slider").slider({animate:true,range:"min",value:1,min:1,max:9,slide:function(i,p){$(this).closest("table").find("input[type=submit]").val($.sprintf(PMA_messages.enum_addValue,p.value))}});$("a.ui-slider-handle").addClass("ui-state-focus");return false});$("input.add_value").live("click",function(a){a.preventDefault();var b=$enum_editor_dialog.find("div.slider").slider("value");while(b--){$enum_editor_dialog.find(".values").append("<tr style='display: none;'><td><input type='text' /></td><td class='drop'>"+PMA_getImage("b_drop.png")+"</td></tr>").find("tr:last").show("fast")}});$("#enum_editor td.drop").live("click",function(){$(this).closest("tr").hide("fast",function(){$(this).remove()})})});function checkIndexName(b){if($("#"+b).length==0){return false}var a=$("#input_index_name");var c=$("#select_index_type");if(c.find("option:selected").val()=="PRIMARY"){a.val("PRIMARY");a.prop("disabled",true)}else{if(a.val()=="PRIMARY"){a.val("")}a.prop("disabled",false)}return true}AJAX.registerTeardown("functions.js",function(){$("#index_frm input[type=submit]").die("click")});AJAX.registerOnload("functions.js",function(){$("#index_frm input[type=submit]").live("click",function(a){a.preventDefault();var b=$(this).closest("fieldset").find(".slider").slider("value");while(b--){var c=$("#index_columns").find("tbody > tr:first").clone().appendTo($("#index_columns").find("tbody"));c.find(":input").each(function(){$(this).val("")});c.find("select").change(function(){if($(this).find("option:selected").val()==""){return true}$(this).closest("tr").find("input").focus()})}})});function indexEditorDialog(d,g,f,b){if($("#edit_index_dialog").length!=0){$("#edit_index_dialog").remove()}var a=$('<div id="edit_index_dialog"></div>');var c={};c[PMA_messages.strGo]=function(){var h=$("#index_frm");PMA_prepareForAjaxRequest(h);$.post(h.attr("action"),h.serialize()+"&do_save_data=1",function(k){if($("#sqlqueryresults").length!=0){$("#sqlqueryresults").remove()}if(k.success==true){PMA_ajaxShowMessage(k.message);if($("#result_query").length){$("#result_query").remove()}if(k.sql_query){$('<div id="result_query"></div>').html(k.sql_query).prependTo("#page_content")}$("#result_query .notice").remove();$("#result_query").prepend(k.message);$("#table_index").remove();var j=$("<div id='temp_div'><div>").append(k.index_table);j.find("#table_index").insertAfter("#index_header");if($("#edit_index_dialog").length>0){$("#edit_index_dialog").dialog("close")}$("div.no_indexes_defined").hide();if(f){f()}PMA_reloadNavigation()}else{var j=$("<div id='temp_div'><div>").append(k.error);if(j.find(".error code").length!=0){var i=j.find(".error code").addClass("error")}else{var i=j}if(b){b()}PMA_ajaxShowMessage(i,false)}})};c[PMA_messages.strCancel]=function(){$(this).dialog("close")};var e=PMA_ajaxShowMessage();$.get("tbl_indexes.php",d,function(i){if(i.success==false){PMA_ajaxShowMessage(i.error,false)}else{PMA_ajaxRemoveMessage(e);a.append(i.message).dialog({title:g,width:450,open:PMA_verifyColumnsProperties,modal:true,buttons:c,close:function(){$(this).remove()}});checkIndexType();checkIndexName("index_frm");PMA_showHints(a);a.find(".slider").slider({animate:true,value:1,min:1,max:16,slide:function(j,k){$(this).closest("fieldset").find("input[type=submit]").val($.sprintf(PMA_messages.strAddToIndex,k.value))}});a.find("table#index_columns select").change(function(){if($(this).find("option:selected").val()==""){return true}$(this).closest("tr").find("input").focus()});$("a.ui-slider-handle").addClass("ui-state-focus");var h=a.find("input#input_index_name");h.val()||h.focus()}})}function PMA_showHints(a){if(a==undefined||!a instanceof jQuery||a.length==0){a=$("body")}a.find(".pma_hint").each(function(){PMA_tooltip($(this).children("img"),"img",$(this).children("span").html())})}AJAX.registerOnload("functions.js",function(){PMA_showHints()});function PMA_mainMenuResizerCallback(){return $(document.body).width()-5}$(function(){$("#topmenu").menuResizer(PMA_mainMenuResizerCallback);$(window).resize(function(){$("#topmenu").menuResizer("resize")})});function PMA_getRowNumber(a){return parseInt(a.split(/\s+row_/)[1])}function PMA_set_status_label(a){var b=a.css("display")=="none"?"+ ":"- ";a.closest(".slide-wrapper").prev().find("span").text(b)}var toggleButton=function($obj){if($("span.text_direction",$obj).text()=="ltr"){var right="right"}else{var right="left"}var h=$obj.height();$("img",$obj).height(h);$("table",$obj).css("bottom",h-1);var on=$("td.toggleOn",$obj).width();var off=$("td.toggleOff",$obj).width();$("td.toggleOn > div",$obj).width(Math.max(on,off)+2);$("td.toggleOff > div",$obj).width(Math.max(on,off)+2);var w=parseInt(($("img",$obj).height()/16)*22,10);$("table td:nth-child(2) > div",$obj).width(w);var imgw=$("img",$obj).width();var tblw=$("table",$obj).width();var offset=parseInt(((imgw-tblw)/2),10);$obj.find("img").css(right,offset);var offw=$("td.toggleOff",$obj).outerWidth();var btnw=$("table td:nth-child(2)",$obj).outerWidth();$obj.width(offw+btnw+2);var move=$("td.toggleOff",$obj).outerWidth();if($("div.container",$obj).hasClass("off")){if(right=="right"){$("div.container",$obj).animate({left:"-="+move+"px"},0)}else{$("div.container",$obj).animate({left:"+="+move+"px"},0)}}$("div.container",$obj).click(function(){if($(this).hasClass("isActive")){return false}else{$(this).addClass("isActive")}var $msg=PMA_ajaxShowMessage();var $container=$(this);var callback=$("span.callback",this).text();if($(this).hasClass("on")){if(right=="right"){var operator="-="}else{var operator="+="}var url=$(this).find("td.toggleOff > span").text();var removeClass="on";var addClass="off"}else{if(right=="right"){var operator="+="}else{var operator="-="}var url=$(this).find("td.toggleOn > span").text();var removeClass="off";var addClass="on"}$.post(url,{ajax_request:true},function(data){if(data.success==true){PMA_ajaxRemoveMessage($msg);$container.removeClass(removeClass).addClass(addClass).animate({left:operator+move+"px"},function(){$container.removeClass("isActive")});eval(callback)}else{PMA_ajaxShowMessage(data.error,false);$container.removeClass("isActive")}})})};AJAX.registerTeardown("functions.js",function(){$("div.container").unbind("click")});AJAX.registerOnload("functions.js",function(){$("div.toggleAjax").each(function(){var a=$(this).show();a.find("img").each(function(){if(this.complete){toggleButton(a)}else{$(this).load(function(){toggleButton(a)})}})})});AJAX.registerTeardown("functions.js",function(){$(".vpointer").die("hover");$(".vmarker").die("click");$("#pageselector").die("change");$("a.formLinkSubmit").die("click");$("#update_recent_tables").unbind("ready")});AJAX.registerOnload("functions.js",function(){$(".vpointer").live("hover",function(c){var a=$(this);var b=PMA_getRowNumber(a.attr("class"));$(".vpointer").filter(".row_"+b).toggleClass("hover")});$(".vmarker").live("click",function(f){if($(f.target).is("a, img, a *")){return}var c=$(this);var d=PMA_getRowNumber(c.attr("class"));var a=$(".vmarker").filter(".row_"+d+":first").find(":checkbox");if(a.length){var b=a.prop("checked");if(!$(f.target).is(":checkbox, label")){b=!b;a.prop("checked",b)}if(b){$(".vmarker").filter(".row_"+d).addClass("marked")}else{$(".vmarker").filter(".row_"+d).removeClass("marked")}}else{$(".vmarker").filter(".row_"+d).toggleClass("marked")}});$("select.pageselector").live("change",function(a){a.stopPropagation();if($(this).closest("#pma_navigation").length==0){$(this).closest("form").submit()}else{PMA_navigationTreePagination($(this))}});if($("li.jsversioncheck").length>0){$.getJSON("version_check.php",{},PMA_current_version)}if($("#is_git_revision").length>0){setTimeout(PMA_display_git_revision,10)}PMA_init_slider();$("a.formLinkSubmit").live("click",function(b){if($(this).attr("href").indexOf("=")!=-1){var a=$(this).attr("href").substr($(this).attr("href").indexOf("#")+1).split("=",2);$(this).parents("form").append('<input type="hidden" name="'+a[0]+'" value="'+a[1]+'"/>')}$(this).parents("form").submit();return false});if($("#update_recent_tables").length){$.get($("#update_recent_tables").attr("href"),function(a){if(a.success==true){$("#recentTable").html(a.options)}})}});function PMA_init_slider(){$("div.pma_auto_slider").each(function(){var b=$(this);if(b.data("slider_init_done")){return}var a=$("<div>",{"class":"slide-wrapper"});a.toggle(b.is(":visible"));$("<a>",{href:"#"+this.id,"class":"ajax"}).text(this.title).prepend($("<span>")).insertBefore(b).click(function(){var c=b.closest(".slide-wrapper");var d=b.is(":visible");if(!d){c.show()}b[d?"hide":"show"]("blind",function(){c.toggle(!d);PMA_set_status_label(b)});return false});b.wrap(a);PMA_set_status_label(b);b.data("slider_init_done",1)})}AJAX.registerOnload("functions.js",function(){PMA_init_slider()});AJAX.registerTeardown("functions.js",function(){$("div.pma_auto_slider").each(function(){var a=$(this);a.removeData();a.parent().replaceWith(a);a.parent().children("a").remove()})});function PMA_slidingMessage(b,c){if(b==undefined||b.length==0){return false}if(c==undefined||!c instanceof jQuery||c.length==0){if($("#PMA_slidingMessage").length==0){$("#page_content").prepend('<span id="PMA_slidingMessage" style="display: inline-block;"></span>')}c=$("#PMA_slidingMessage")}if(c.has("div").length>0){c.find("div").first().fadeOut(function(){c.children().remove();c.append('<div style="display: none;">'+b+"</div>").animate({height:c.find("div").first().height()}).find("div").first().fadeIn()})}else{var a=c.width("100%").html('<div style="display: none;">'+b+"</div>").find("div").first().height();c.find("div").first().css("height",0).show().animate({height:a},function(){c.height(c.find("div").first().height())})}return true}AJAX.registerTeardown("functions.js",function(){$("#drop_tbl_anchor.ajax").die("click");$("#truncate_tbl_anchor.ajax").die("click")});AJAX.registerOnload("functions.js",function(){$("#drop_tbl_anchor.ajax").live("click",function(b){b.preventDefault();var a=PMA_messages.strDropTableStrongWarning+" ";a+=$.sprintf(PMA_messages.strDoYouReally,"DROP TABLE "+PMA_commonParams.get("table"));$(this).PMA_confirm(a,$(this).attr("href"),function(c){var d=PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);$.get(c,{is_js_confirmed:"1",ajax_request:true},function(e){if(e.success==true){PMA_ajaxRemoveMessage(d);PMA_reloadNavigation();PMA_commonParams.set("table","");PMA_commonActions.refreshMain(PMA_commonParams.get("opendb_url"),function(){PMA_ajaxShowMessage(e.message)})}else{PMA_ajaxShowMessage(e.error,false)}})})});$("#truncate_tbl_anchor.ajax").live("click",function(b){b.preventDefault();var a=PMA_messages.strTruncateTableStrongWarning+" ";a+=$.sprintf(PMA_messages.strDoYouReally,"TRUNCATE "+PMA_commonParams.get("table"));$(this).PMA_confirm(a,$(this).attr("href"),function(c){PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);$.get(c,{is_js_confirmed:"1",ajax_request:true},function(d){if($("#sqlqueryresults").length!=0){$("#sqlqueryresults").remove()}if($("#result_query").length!=0){$("#result_query").remove()}if(d.success==true){PMA_ajaxShowMessage(d.message);$("<div id='sqlqueryresults'></div>").prependTo("#page_content");$("#sqlqueryresults").html(d.sql_query)}else{PMA_ajaxShowMessage(d.error,false)}})})})});AJAX.registerOnload("functions.js",function(){var a=$("#sqlquery");if(a.length>0){if(typeof CodeMirror!="undefined"){codemirror_editor=CodeMirror.fromTextArea(a[0],{lineNumbers:true,matchBrackets:true,indentUnit:4,mode:"text/x-mysql",lineWrapping:true});codemirror_editor.focus();$(codemirror_editor.getWrapperElement()).bind("keydown",catchKeypressesFromSqlTextboxes)}else{a.focus().bind("keydown",catchKeypressesFromSqlTextboxes)}}});AJAX.registerTeardown("functions.js",function(){if(codemirror_editor){$("#sqlquery").text(codemirror_editor.getValue());codemirror_editor.toTextArea();codemirror_editor=false}});(function(a){a.fn.noSelect=function(c){var b=(c==null)?true:c;if(b){return this.each(function(){if(a.browser.msie||a.browser.safari){a(this).bind("selectstart",function(){return false})}else{if(a.browser.mozilla){a(this).css("MozUserSelect","none");a("body").trigger("focus")}else{if(a.browser.opera){a(this).bind("mousedown",function(){return false})}else{a(this).attr("unselectable","on")}}}})}else{return this.each(function(){if(a.browser.msie||a.browser.safari){a(this).unbind("selectstart")}else{if(a.browser.mozilla){a(this).css("MozUserSelect","inherit")}else{if(a.browser.opera){a(this).unbind("mousedown")}else{a(this).removeAttr("unselectable")}}}})}}})(jQuery);(function(a){a.fn.filterByValue=function(b){return this.filter(function(){return a(this).val()===b})}})(jQuery);function PMA_tooltip(d,e,c,b){if($("#no_hint").length>0){return}var a={content:c,items:e,tooltipClass:"tooltip",track:true,show:false,hide:false};d.tooltip($.extend(true,a,b))}function PMA_getCellValue(b){var a=$(b);if(a.is(".null")){return""}else{if(!a.is(".to_be_saved")&&a.data("original_data")){return a.data("original_data")}else{return a.text()}}}AJAX.registerTeardown("functions.js",function(){$("a.themeselect").die("click");$(".autosubmit").die("change");$("a.take_theme").unbind("click")});AJAX.registerOnload("functions.js",function(){$("a.themeselect").live("click",function(a){window.open(a.target,"themes","left=10,top=20,width=510,height=350,scrollbars=yes,status=yes,resizable=yes");return false});$(".autosubmit").live("change",function(a){$(this).closest("form").submit()});$("a.take_theme").click(function(b){var a=this.name;if(window.opener&&window.opener.document.forms.setTheme.elements.set_theme){window.opener.document.forms.setTheme.elements.set_theme.value=a;window.opener.document.forms.setTheme.submit();window.close();return false}return true})});function PMA_clearSelection(){if(document.selection&&document.selection.empty){document.selection.empty()}else{if(window.getSelection){var a=window.getSelection();if(a.empty){a.empty()}if(a.removeAllRanges){a.removeAllRanges()}}}}function escapeHtml(a){return a.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}function printPage(){if(typeof(window.print)!="undefined"){window.print()}}AJAX.registerTeardown("functions.js",function(){$("input#print").unbind("click");$("span a.create_view.ajax").die("click");$("#createViewDialog").find("input, select").die("keydown")});AJAX.registerOnload("functions.js",function(){$("input#print").click(printPage);$("span a.create_view.ajax").live("click",function(a){a.preventDefault();PMA_createViewDialog($(this))});$("#createViewDialog").find("input, select").live("keydown",function(a){if(a.which===13){a.preventDefault();$(this).closest(".ui-dialog").find(".ui-button:first").click()}})});function PMA_createViewDialog(c){var a=PMA_ajaxShowMessage();var b=null;$.get(c.attr("href")+"&ajax_request=1",function(g){if(g.success==true){PMA_ajaxRemoveMessage(a);var h={};h[PMA_messages.strGo]=function(){if(typeof CodeMirror!=="undefined"){b.save()}a=PMA_ajaxShowMessage();$.get("view_create.php",$("#createViewDialog").find("form").serialize(),function(i){PMA_ajaxRemoveMessage(a);if(i.success===true){$("#createViewDialog").dialog("close");$("#result_query").html(i.message);PMA_reloadNavigation()}else{PMA_ajaxShowMessage(i.error,false)}})};h[PMA_messages.strClose]=function(){$(this).dialog("close")};var f=$("<div/>").attr("id","createViewDialog").append(g.message).dialog({width:500,minWidth:300,maxWidth:620,modal:true,buttons:h,title:$("legend",$(g.message)).html(),close:function(){$(this).remove()}});f.find("legend").remove();if(typeof CodeMirror!=="undefined"){var d=f.find("textarea");var e={lineNumbers:true,matchBrackets:true,indentUnit:4,mode:"text/x-mysql"};b=CodeMirror.fromTextArea(d[0],e)}$("input:visible[type=text]",f).first().focus()}else{PMA_ajaxShowMessage(g.error)}})}$(function(){if($("#floating_menubar").length&&$("#PMA_disable_floating_menubar").length==0){var a=$("html").attr("dir")=="ltr"?"left":"right";$("#floating_menubar").css("margin-"+a,$("#pma_navigation").width()+$("#pma_navigation_resizer").width()).css(a,0).css({position:"fixed",top:0,width:"100%","z-index":500}).append($("#serverinfo")).append($("#topmenucontainer"));setTimeout(function(){$("body").css("padding-top",$("#floating_menubar").outerHeight(true));$("#topmenu").menuResizer("resize")},4)}});$(function(){$(document).delegate("#serverinfo, #goto_pagetop","click",function(a){a.preventDefault();$("html, body").animate({scrollTop:0},"fast")})});var checkboxes_sel="input.checkall:checkbox:enabled";$(checkboxes_sel).live("change",function(){var a=$(this.form);var c=a.find(checkboxes_sel).length;var d=a.find(checkboxes_sel+":checked").length;var b=a.find("input#checkall");if(c==d){b.prop({checked:true,indeterminate:false})}else{if(d>0){b.prop({checked:true,indeterminate:true})}else{b.prop({checked:false,indeterminate:false})}}});$("input#checkall").live("change",function(){var a=$(this).is(":checked");$(this.form).find(checkboxes_sel).prop("checked",a).parents("tr").toggleClass("marked",a)});function toggleRowColors(b){for(var a=b;a.length>0;a=a.next()){if(a.hasClass("odd")){a.removeClass("odd").addClass("even")}else{if(a.hasClass("even")){a.removeClass("even").addClass("odd")}}}}function formatBytes(b,f,a){if(!f){var f=0}if(!a){var a="."}var c=["B","KiB","MiB","GiB"];for(var e=0;b>1024&&e<c.length;e++){b/=1024}var d=Math.pow(10,f);b=Math.round(b*d)/d;b=b.toString().split(".").join(a);return b+" "+c[e]}AJAX.registerOnload("functions.js",function(){$("a._blank").prop("target","_blank");var a=$("#loginform");if(a.length){a.find(".js-show").show();if($("#input_username").val()){$("#input_password").focus()}else{$("#input_username").focus()}}});$("a.login-link").live("click",function(a){a.preventDefault();window.location.reload(true)});
 
 
b'\\ No newline at end of file'
 
1
/* vim: set expandtab sw=4 ts=4 sts=4: */
 
2
/**
 
3
 * general function, usually for data manipulation pages
 
4
 *
 
5
 */
 
6
 
 
7
/**
 
8
 * @var $table_clone reference to the action links on the tbl_structure page
 
9
 */
 
10
var $table_clone = false;
 
11
 
 
12
/**
 
13
 * @var sql_box_locked lock for the sqlbox textarea in the querybox/querywindow
 
14
 */
 
15
var sql_box_locked = false;
 
16
 
 
17
/**
 
18
 * @var array holds elements which content should only selected once
 
19
 */
 
20
var only_once_elements = [];
 
21
 
 
22
/**
 
23
 * @var   int   ajax_message_count   Number of AJAX messages shown since page load
 
24
 */
 
25
var ajax_message_count = 0;
 
26
 
 
27
/**
 
28
 * @var codemirror_editor object containing CodeMirror editor of the query editor in SQL tab
 
29
 */
 
30
var codemirror_editor = false;
 
31
 
 
32
/**
 
33
 * @var codemirror_editor object containing CodeMirror editor of the inline query editor
 
34
 */
 
35
var codemirror_inline_editor = false;
 
36
 
 
37
/**
 
38
 * @var chart_activeTimeouts object active timeouts that refresh the charts. When disabling a realtime chart, this can be used to stop the continuous ajax requests
 
39
 */
 
40
var chart_activeTimeouts = {};
 
41
 
 
42
/**
 
43
 * Make sure that ajax requests will not be cached
 
44
 * by appending a random variable to their parameters
 
45
 */
 
46
$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
 
47
    var nocache = new Date().getTime() + "" + Math.floor(Math.random() * 1000000);
 
48
    if (typeof options.data == "string") {
 
49
        options.data += "&_nocache=" + nocache;
 
50
    } else if (typeof options.data == "object") {
 
51
        options.data = $.extend(originalOptions.data, {'_nocache':nocache});
 
52
    }
 
53
});
 
54
 
 
55
/**
 
56
 * Add a hidden field to the form to indicate that this will be an
 
57
 * Ajax request (only if this hidden field does not exist)
 
58
 *
 
59
 * @param object   the form
 
60
 */
 
61
function PMA_prepareForAjaxRequest($form)
 
62
{
 
63
    if (! $form.find('input:hidden').is('#ajax_request_hidden')) {
 
64
        $form.append('<input type="hidden" id="ajax_request_hidden" name="ajax_request" value="true" />');
 
65
    }
 
66
}
 
67
 
 
68
/**
 
69
 * Generate a new password and copy it to the password input areas
 
70
 *
 
71
 * @param object   the form that holds the password fields
 
72
 *
 
73
 * @return boolean  always true
 
74
 */
 
75
function suggestPassword(passwd_form)
 
76
{
 
77
    // restrict the password to just letters and numbers to avoid problems:
 
78
    // "editors and viewers regard the password as multiple words and
 
79
    // things like double click no longer work"
 
80
    var pwchars = "abcdefhjmnpqrstuvwxyz23456789ABCDEFGHJKLMNPQRSTUVWYXZ";
 
81
    var passwordlength = 16;    // do we want that to be dynamic?  no, keep it simple :)
 
82
    var passwd = passwd_form.generated_pw;
 
83
    passwd.value = '';
 
84
 
 
85
    for (var i = 0; i < passwordlength; i++ ) {
 
86
        passwd.value += pwchars.charAt( Math.floor( Math.random() * pwchars.length ) );
 
87
    }
 
88
    passwd_form.text_pma_pw.value = passwd.value;
 
89
    passwd_form.text_pma_pw2.value = passwd.value;
 
90
    return true;
 
91
}
 
92
 
 
93
/**
 
94
 * Version string to integer conversion.
 
95
 */
 
96
function parseVersionString (str)
 
97
{
 
98
    if (typeof(str) != 'string') { return false; }
 
99
    var add = 0;
 
100
    // Parse possible alpha/beta/rc/
 
101
    var state = str.split('-');
 
102
    if (state.length >= 2) {
 
103
        if (state[1].substr(0, 2) == 'rc') {
 
104
            add = - 20 - parseInt(state[1].substr(2));
 
105
        } else if (state[1].substr(0, 4) == 'beta') {
 
106
            add =  - 40 - parseInt(state[1].substr(4));
 
107
        } else if (state[1].substr(0, 5) == 'alpha') {
 
108
            add =  - 60 - parseInt(state[1].substr(5));
 
109
        } else if (state[1].substr(0, 3) == 'dev') {
 
110
            /* We don't handle dev, it's git snapshot */
 
111
            add = 0;
 
112
        }
 
113
    }
 
114
    // Parse version
 
115
    var x = str.split('.');
 
116
    // Use 0 for non existing parts
 
117
    var maj = parseInt(x[0]) || 0;
 
118
    var min = parseInt(x[1]) || 0;
 
119
    var pat = parseInt(x[2]) || 0;
 
120
    var hotfix = parseInt(x[3]) || 0;
 
121
    return  maj * 100000000 + min * 1000000 + pat * 10000 + hotfix * 100 + add;
 
122
}
 
123
 
 
124
/**
 
125
 * Indicates current available version on main page.
 
126
 */
 
127
function PMA_current_version(data)
 
128
{
 
129
    if (data && data.version && data.date) {
 
130
        var current = parseVersionString(pmaversion);
 
131
        var latest = parseVersionString(data['version']);
 
132
        var version_information_message = PMA_messages['strLatestAvailable'] + ' ' + escapeHtml(data['version']);
 
133
        if (latest > current) {
 
134
            var message = $.sprintf(
 
135
                PMA_messages['strNewerVersion'],
 
136
                escapeHtml(data['version']),
 
137
                escapeHtml(data['date'])
 
138
            );
 
139
            if (Math.floor(latest / 10000) === Math.floor(current / 10000)) {
 
140
                /* Security update */
 
141
                var klass = 'error';
 
142
            } else {
 
143
                var klass = 'notice';
 
144
            }
 
145
            $('#maincontainer').after('<div class="' + klass + '">' + message + '</div>');
 
146
        }
 
147
        if (latest === current) {
 
148
            version_information_message = ' (' + PMA_messages['strUpToDate'] + ')';
 
149
        }
 
150
        $('#li_pma_version').append(version_information_message);
 
151
    }
 
152
}
 
153
 
 
154
/**
 
155
 * Loads Git revision data from ajax for index.php
 
156
 */
 
157
function PMA_display_git_revision()
 
158
{
 
159
    $('#is_git_revision').remove();
 
160
    $.get(
 
161
        "index.php",
 
162
        {
 
163
            "server": PMA_commonParams.get('server'),
 
164
            "token": PMA_commonParams.get('token'),
 
165
            "git_revision": true,
 
166
            "ajax_request": true
 
167
        },
 
168
        function (data) {
 
169
            if (data.success == true) {
 
170
                $(data.message).insertAfter('#li_pma_version');
 
171
            }
 
172
        }
 
173
    );
 
174
}
 
175
 
 
176
/**
 
177
 * for libraries/display_change_password.lib.php
 
178
 *     libraries/user_password.php
 
179
 *
 
180
 */
 
181
 
 
182
function displayPasswordGenerateButton()
 
183
{
 
184
    $('#tr_element_before_generate_password').parent().append('<tr class="vmiddle"><td>' + PMA_messages['strGeneratePassword'] + '</td><td><input type="button" class="button" id="button_generate_password" value="' + PMA_messages['strGenerate'] + '" onclick="suggestPassword(this.form)" /><input type="text" name="generated_pw" id="generated_pw" /></td></tr>');
 
185
    $('#div_element_before_generate_password').parent().append('<div class="item"><label for="button_generate_password">' + PMA_messages['strGeneratePassword'] + ':</label><span class="options"><input type="button" class="button" id="button_generate_password" value="' + PMA_messages['strGenerate'] + '" onclick="suggestPassword(this.form)" /></span><input type="text" name="generated_pw" id="generated_pw" /></div>');
 
186
}
 
187
 
 
188
/*
 
189
 * Adds a date/time picker to an element
 
190
 *
 
191
 * @param object  $this_element   a jQuery object pointing to the element
 
192
 */
 
193
function PMA_addDatepicker($this_element, options)
 
194
{
 
195
    var showTimeOption = false;
 
196
    if ($this_element.is('.datetimefield')) {
 
197
        showTimeOption = true;
 
198
    }
 
199
 
 
200
    var defaultOptions = {
 
201
        showOn: 'button',
 
202
        buttonImage: themeCalendarImage, // defined in js/messages.php
 
203
        buttonImageOnly: true,
 
204
        stepMinutes: 1,
 
205
        stepHours: 1,
 
206
        showSecond: true,
 
207
        showTimepicker: showTimeOption,
 
208
        showButtonPanel: false,
 
209
        dateFormat: 'yy-mm-dd', // yy means year with four digits
 
210
        timeFormat: 'HH:mm:ss',
 
211
        altFieldTimeOnly: false,
 
212
        showAnim: '',
 
213
        beforeShow: function(input, inst) {
 
214
            // Remember that we came from the datepicker; this is used
 
215
            // in tbl_change.js by verificationsAfterFieldChange()
 
216
            $this_element.data('comes_from', 'datepicker');
 
217
 
 
218
            // Fix wrong timepicker z-index, doesn't work without timeout
 
219
            setTimeout(function() {
 
220
                $('#ui-timepicker-div').css('z-index',$('#ui-datepicker-div').css('z-index'));
 
221
            }, 0);
 
222
        },
 
223
        onClose: function(dateText, dp_inst) {
 
224
            // The value is no more from the date picker
 
225
            $this_element.data('comes_from', '');
 
226
        }
 
227
    };
 
228
    if ( showTimeOption || (typeof(options) != 'undefined'  && options.showTimepicker) ) {
 
229
        $this_element.datetimepicker($.extend(defaultOptions, options));
 
230
    } else {
 
231
        $this_element.datepicker($.extend(defaultOptions, options));
 
232
    }
 
233
}
 
234
 
 
235
/**
 
236
 * selects the content of a given object, f.e. a textarea
 
237
 *
 
238
 * @param object  element     element of which the content will be selected
 
239
 * @param var     lock        variable which holds the lock for this element
 
240
 *                              or true, if no lock exists
 
241
 * @param boolean only_once   if true this is only done once
 
242
 *                              f.e. only on first focus
 
243
 */
 
244
function selectContent( element, lock, only_once )
 
245
{
 
246
    if ( only_once && only_once_elements[element.name] ) {
 
247
        return;
 
248
    }
 
249
 
 
250
    only_once_elements[element.name] = true;
 
251
 
 
252
    if ( lock  ) {
 
253
        return;
 
254
    }
 
255
 
 
256
    element.select();
 
257
}
 
258
 
 
259
/**
 
260
 * Displays a confirmation box before submitting a "DROP/DELETE/ALTER" query.
 
261
 * This function is called while clicking links
 
262
 *
 
263
 * @param object   the link
 
264
 * @param object   the sql query to submit
 
265
 *
 
266
 * @return boolean  whether to run the query or not
 
267
 */
 
268
function confirmLink(theLink, theSqlQuery)
 
269
{
 
270
    // Confirmation is not required in the configuration file
 
271
    // or browser is Opera (crappy js implementation)
 
272
    if (PMA_messages['strDoYouReally'] == '' || typeof(window.opera) != 'undefined') {
 
273
        return true;
 
274
    }
 
275
 
 
276
    var is_confirmed = confirm($.sprintf(PMA_messages['strDoYouReally'], theSqlQuery));
 
277
    if (is_confirmed) {
 
278
        if ( $(theLink).hasClass('formLinkSubmit') ) {
 
279
            var name = 'is_js_confirmed';
 
280
            if ($(theLink).attr('href').indexOf('usesubform') != -1) {
 
281
                name = 'subform[' + $(theLink).attr('href').substr('#').match(/usesubform\[(\d+)\]/i)[1] + '][is_js_confirmed]';
 
282
            }
 
283
 
 
284
            $(theLink).parents('form').append('<input type="hidden" name="' + name + '" value="1" />');
 
285
        } else if ( typeof(theLink.href) != 'undefined' ) {
 
286
            theLink.href += '&is_js_confirmed=1';
 
287
        } else if ( typeof(theLink.form) != 'undefined' ) {
 
288
            theLink.form.action += '?is_js_confirmed=1';
 
289
        }
 
290
    }
 
291
 
 
292
    return is_confirmed;
 
293
} // end of the 'confirmLink()' function
 
294
 
 
295
/**
 
296
 * Displays an error message if a "DROP DATABASE" statement is submitted
 
297
 * while it isn't allowed, else confirms a "DROP/DELETE/ALTER" query before
 
298
 * sumitting it if required.
 
299
 * This function is called by the 'checkSqlQuery()' js function.
 
300
 *
 
301
 * @param object   the form
 
302
 * @param object   the sql query textarea
 
303
 *
 
304
 * @return boolean  whether to run the query or not
 
305
 *
 
306
 * @see     checkSqlQuery()
 
307
 */
 
308
function confirmQuery(theForm1, sqlQuery1)
 
309
{
 
310
    // Confirmation is not required in the configuration file
 
311
    if (PMA_messages['strDoYouReally'] == '') {
 
312
        return true;
 
313
    }
 
314
 
 
315
    // "DROP DATABASE" statement isn't allowed
 
316
    if (PMA_messages['strNoDropDatabases'] != '') {
 
317
        var drop_re = new RegExp('(^|;)\\s*DROP\\s+(IF EXISTS\\s+)?DATABASE\\s', 'i');
 
318
        if (drop_re.test(sqlQuery1.value)) {
 
319
            alert(PMA_messages['strNoDropDatabases']);
 
320
            theForm1.reset();
 
321
            sqlQuery1.focus();
 
322
            return false;
 
323
        } // end if
 
324
    } // end if
 
325
 
 
326
    // Confirms a "DROP/DELETE/ALTER/TRUNCATE" statement
 
327
    //
 
328
    // TODO: find a way (if possible) to use the parser-analyser
 
329
    // for this kind of verification
 
330
    // For now, I just added a ^ to check for the statement at
 
331
    // beginning of expression
 
332
 
 
333
    var do_confirm_re_0 = new RegExp('^\\s*DROP\\s+(IF EXISTS\\s+)?(TABLE|DATABASE|PROCEDURE)\\s', 'i');
 
334
    var do_confirm_re_1 = new RegExp('^\\s*ALTER\\s+TABLE\\s+((`[^`]+`)|([A-Za-z0-9_$]+))\\s+DROP\\s', 'i');
 
335
    var do_confirm_re_2 = new RegExp('^\\s*DELETE\\s+FROM\\s', 'i');
 
336
    var do_confirm_re_3 = new RegExp('^\\s*TRUNCATE\\s', 'i');
 
337
 
 
338
    if (do_confirm_re_0.test(sqlQuery1.value)
 
339
        || do_confirm_re_1.test(sqlQuery1.value)
 
340
        || do_confirm_re_2.test(sqlQuery1.value)
 
341
        || do_confirm_re_3.test(sqlQuery1.value)) {
 
342
        var message      = (sqlQuery1.value.length > 100)
 
343
                         ? sqlQuery1.value.substr(0, 100) + '\n    ...'
 
344
                         : sqlQuery1.value;
 
345
        var is_confirmed = confirm($.sprintf(PMA_messages['strDoYouReally'], message));
 
346
        // statement is confirmed -> update the
 
347
        // "is_js_confirmed" form field so the confirm test won't be
 
348
        // run on the server side and allows to submit the form
 
349
        if (is_confirmed) {
 
350
            theForm1.elements['is_js_confirmed'].value = 1;
 
351
            return true;
 
352
        }
 
353
        // statement is rejected -> do not submit the form
 
354
        else {
 
355
            window.focus();
 
356
            sqlQuery1.focus();
 
357
            return false;
 
358
        } // end if (handle confirm box result)
 
359
    } // end if (display confirm box)
 
360
 
 
361
    return true;
 
362
} // end of the 'confirmQuery()' function
 
363
 
 
364
/**
 
365
 * Displays an error message if the user submitted the sql query form with no
 
366
 * sql query, else checks for "DROP/DELETE/ALTER" statements
 
367
 *
 
368
 * @param object   the form
 
369
 *
 
370
 * @return boolean  always false
 
371
 *
 
372
 * @see     confirmQuery()
 
373
 */
 
374
function checkSqlQuery(theForm)
 
375
{
 
376
 
 
377
    // First check if codemirror is active.
 
378
    if (codemirror_editor) {
 
379
        theForm.elements['sql_query'].value = codemirror_editor.getValue();
 
380
    }
 
381
 
 
382
    var sqlQuery = theForm.elements['sql_query'];
 
383
 
 
384
    var isEmpty  = 1;
 
385
 
 
386
    var space_re = new RegExp('\\s+');
 
387
    if (typeof(theForm.elements['sql_file']) != 'undefined' &&
 
388
            theForm.elements['sql_file'].value.replace(space_re, '') != '') {
 
389
        return true;
 
390
    }
 
391
    if (typeof(theForm.elements['sql_localfile']) != 'undefined' &&
 
392
            theForm.elements['sql_localfile'].value.replace(space_re, '') != '') {
 
393
        return true;
 
394
    }
 
395
    if (isEmpty && typeof(theForm.elements['id_bookmark']) != 'undefined' &&
 
396
            (theForm.elements['id_bookmark'].value != null || theForm.elements['id_bookmark'].value != '') &&
 
397
            theForm.elements['id_bookmark'].selectedIndex != 0
 
398
            ) {
 
399
        return true;
 
400
    }
 
401
    // Checks for "DROP/DELETE/ALTER" statements
 
402
    if (sqlQuery.value.replace(space_re, '') != '') {
 
403
        if (confirmQuery(theForm, sqlQuery)) {
 
404
            return true;
 
405
        } else {
 
406
            return false;
 
407
        }
 
408
    }
 
409
    theForm.reset();
 
410
    isEmpty = 1;
 
411
 
 
412
    if (isEmpty) {
 
413
        sqlQuery.select();
 
414
        alert(PMA_messages['strFormEmpty']);
 
415
        sqlQuery.focus();
 
416
        return false;
 
417
    }
 
418
 
 
419
    return true;
 
420
} // end of the 'checkSqlQuery()' function
 
421
 
 
422
/**
 
423
 * Check if a form's element is empty.
 
424
 * An element containing only spaces is also considered empty
 
425
 *
 
426
 * @param object   the form
 
427
 * @param string   the name of the form field to put the focus on
 
428
 *
 
429
 * @return boolean  whether the form field is empty or not
 
430
 */
 
431
function emptyCheckTheField(theForm, theFieldName)
 
432
{
 
433
    var theField = theForm.elements[theFieldName];
 
434
    var space_re = new RegExp('\\s+');
 
435
    return (theField.value.replace(space_re, '') == '') ? 1 : 0;
 
436
} // end of the 'emptyCheckTheField()' function
 
437
 
 
438
 
 
439
/**
 
440
 * Check whether a form field is empty or not
 
441
 *
 
442
 * @param object   the form
 
443
 * @param string   the name of the form field to put the focus on
 
444
 *
 
445
 * @return boolean  whether the form field is empty or not
 
446
 */
 
447
function emptyFormElements(theForm, theFieldName)
 
448
{
 
449
    var theField = theForm.elements[theFieldName];
 
450
    var isEmpty = emptyCheckTheField(theForm, theFieldName);
 
451
 
 
452
 
 
453
    return isEmpty;
 
454
} // end of the 'emptyFormElements()' function
 
455
 
 
456
 
 
457
/**
 
458
 * Ensures a value submitted in a form is numeric and is in a range
 
459
 *
 
460
 * @param object   the form
 
461
 * @param string   the name of the form field to check
 
462
 * @param integer  the minimum authorized value
 
463
 * @param integer  the maximum authorized value
 
464
 *
 
465
 * @return boolean  whether a valid number has been submitted or not
 
466
 */
 
467
function checkFormElementInRange(theForm, theFieldName, message, min, max)
 
468
{
 
469
    var theField         = theForm.elements[theFieldName];
 
470
    var val              = parseInt(theField.value);
 
471
 
 
472
    if (typeof(min) == 'undefined') {
 
473
        min = 0;
 
474
    }
 
475
    if (typeof(max) == 'undefined') {
 
476
        max = Number.MAX_VALUE;
 
477
    }
 
478
 
 
479
    // It's not a number
 
480
    if (isNaN(val)) {
 
481
        theField.select();
 
482
        alert(PMA_messages['strNotNumber']);
 
483
        theField.focus();
 
484
        return false;
 
485
    }
 
486
    // It's a number but it is not between min and max
 
487
    else if (val < min || val > max) {
 
488
        theField.select();
 
489
        alert($.sprintf(message, val));
 
490
        theField.focus();
 
491
        return false;
 
492
    }
 
493
    // It's a valid number
 
494
    else {
 
495
        theField.value = val;
 
496
    }
 
497
    return true;
 
498
 
 
499
} // end of the 'checkFormElementInRange()' function
 
500
 
 
501
 
 
502
function checkTableEditForm(theForm, fieldsCnt)
 
503
{
 
504
    // TODO: avoid sending a message if user just wants to add a line
 
505
    // on the form but has not completed at least one field name
 
506
 
 
507
    var atLeastOneField = 0;
 
508
    var i, elm, elm2, elm3, val, id;
 
509
 
 
510
    for (i=0; i<fieldsCnt; i++)
 
511
    {
 
512
        id = "#field_" + i + "_2";
 
513
        elm = $(id);
 
514
        val = elm.val();
 
515
        if (val == 'VARCHAR' || val == 'CHAR' || val == 'BIT' || val == 'VARBINARY' || val == 'BINARY') {
 
516
            elm2 = $("#field_" + i + "_3");
 
517
            val = parseInt(elm2.val());
 
518
            elm3 = $("#field_" + i + "_1");
 
519
            if (isNaN(val) && elm3.val() != "") {
 
520
                elm2.select();
 
521
                alert(PMA_messages['strNotNumber']);
 
522
                elm2.focus();
 
523
                return false;
 
524
            }
 
525
        }
 
526
 
 
527
        if (atLeastOneField == 0) {
 
528
            id = "field_" + i + "_1";
 
529
            if (!emptyCheckTheField(theForm, id)) {
 
530
                atLeastOneField = 1;
 
531
            }
 
532
        }
 
533
    }
 
534
    if (atLeastOneField == 0) {
 
535
        var theField = theForm.elements["field_0_1"];
 
536
        alert(PMA_messages['strFormEmpty']);
 
537
        theField.focus();
 
538
        return false;
 
539
    }
 
540
 
 
541
    // at least this section is under jQuery
 
542
    if ($("input.textfield[name='table']").val() == "") {
 
543
        alert(PMA_messages['strFormEmpty']);
 
544
        $("input.textfield[name='table']").focus();
 
545
        return false;
 
546
    }
 
547
 
 
548
 
 
549
    return true;
 
550
} // enf of the 'checkTableEditForm()' function
 
551
 
 
552
/**
 
553
 * Unbind all event handlers before tearing down a page
 
554
 */
 
555
AJAX.registerTeardown('functions.js', function() {
 
556
    $('input:checkbox.checkall').die('click');
 
557
});
 
558
AJAX.registerOnload('functions.js', function() {
 
559
    /**
 
560
     * Row marking in horizontal mode (use "live" so that it works also for
 
561
     * next pages reached via AJAX); a tr may have the class noclick to remove
 
562
     * this behavior.
 
563
     */
 
564
 
 
565
    $('input:checkbox.checkall').live('click', function(e) {
 
566
        var $tr = $(this).closest('tr');
 
567
 
 
568
        // make the table unselectable (to prevent default highlighting when shift+click)
 
569
        //$tr.parents('table').noSelect();
 
570
 
 
571
        if (!e.shiftKey || last_clicked_row == -1) {
 
572
            // usual click
 
573
 
 
574
            // XXX: FF fires two click events for <label> (label and checkbox), so we need to handle this differently
 
575
            var $checkbox = $tr.find(':checkbox');
 
576
            if ($checkbox.length) {
 
577
                // checkbox in a row, add or remove class depending on checkbox state
 
578
                var checked = $checkbox.prop('checked');
 
579
                if (!$(e.target).is(':checkbox, label')) {
 
580
                    checked = !checked;
 
581
                    $checkbox.prop('checked', checked).trigger('change');
 
582
                }
 
583
                if (checked) {
 
584
                    $tr.addClass('marked');
 
585
                } else {
 
586
                    $tr.removeClass('marked');
 
587
                }
 
588
                last_click_checked = checked;
 
589
            } else {
 
590
                // normal data table, just toggle class
 
591
                $tr.toggleClass('marked');
 
592
                last_click_checked = false;
 
593
            }
 
594
 
 
595
            // remember the last clicked row
 
596
            last_clicked_row = last_click_checked ? $('tr.odd:not(.noclick), tr.even:not(.noclick)').index($tr) : -1;
 
597
            last_shift_clicked_row = -1;
 
598
        } else {
 
599
            // handle the shift click
 
600
            PMA_clearSelection();
 
601
            var start, end;
 
602
 
 
603
            // clear last shift click result
 
604
            if (last_shift_clicked_row >= 0) {
 
605
                if (last_shift_clicked_row >= last_clicked_row) {
 
606
                    start = last_clicked_row;
 
607
                    end = last_shift_clicked_row;
 
608
                } else {
 
609
                    start = last_shift_clicked_row;
 
610
                    end = last_clicked_row;
 
611
                }
 
612
                $tr.parent().find('tr.odd:not(.noclick), tr.even:not(.noclick)')
 
613
                    .slice(start, end + 1)
 
614
                    .removeClass('marked')
 
615
                    .find(':checkbox')
 
616
                    .prop('checked', false)
 
617
                    .trigger('change');
 
618
            }
 
619
 
 
620
            // handle new shift click
 
621
            var curr_row = $('tr.odd:not(.noclick), tr.even:not(.noclick)').index($tr);
 
622
            if (curr_row >= last_clicked_row) {
 
623
                start = last_clicked_row;
 
624
                end = curr_row;
 
625
            } else {
 
626
                start = curr_row;
 
627
                end = last_clicked_row;
 
628
            }
 
629
            $tr.parent().find('tr.odd:not(.noclick), tr.even:not(.noclick)')
 
630
                .slice(start, end + 1)
 
631
                .addClass('marked')
 
632
                .find(':checkbox')
 
633
                .prop('checked', true)
 
634
                .trigger('change');
 
635
 
 
636
            // remember the last shift clicked row
 
637
            last_shift_clicked_row = curr_row;
 
638
        }
 
639
    });
 
640
 
 
641
    addDateTimePicker();
 
642
 
 
643
    /**
 
644
     * Add attribute to text boxes for iOS devices (based on bugID: 3508912)
 
645
     */
 
646
    if (navigator.userAgent.match(/(iphone|ipod|ipad)/i)) {
 
647
        $('input[type=text]').attr('autocapitalize','off').attr('autocorrect','off');
 
648
    }
 
649
});
 
650
 
 
651
/**
 
652
 * True if last click is to check a row.
 
653
 */
 
654
var last_click_checked = false;
 
655
 
 
656
/**
 
657
 * Zero-based index of last clicked row.
 
658
 * Used to handle the shift + click event in the code above.
 
659
 */
 
660
var last_clicked_row = -1;
 
661
 
 
662
/**
 
663
 * Zero-based index of last shift clicked row.
 
664
 */
 
665
var last_shift_clicked_row = -1;
 
666
 
 
667
/**
 
668
 * Row highlighting in horizontal mode (use "live"
 
669
 * so that it works also for pages reached via AJAX)
 
670
 */
 
671
/*AJAX.registerOnload('functions.js', function() {
 
672
    $('tr.odd, tr.even').live('hover',function(event) {
 
673
        var $tr = $(this);
 
674
        $tr.toggleClass('hover',event.type=='mouseover');
 
675
        $tr.children().toggleClass('hover',event.type=='mouseover');
 
676
    });
 
677
})*/
 
678
 
 
679
/**
 
680
 * This array is used to remember mark status of rows in browse mode
 
681
 */
 
682
var marked_row = [];
 
683
 
 
684
/**
 
685
 * marks all rows and selects its first checkbox inside the given element
 
686
 * the given element is usaly a table or a div containing the table or tables
 
687
 *
 
688
 * @param container    DOM element
 
689
 */
 
690
function markAllRows(container_id)
 
691
{
 
692
 
 
693
    $("#" + container_id).find("input:checkbox:enabled").prop('checked', true)
 
694
    .trigger("change")
 
695
    .parents("tr").addClass("marked");
 
696
    return true;
 
697
}
 
698
 
 
699
/**
 
700
 * marks all rows and selects its first checkbox inside the given element
 
701
 * the given element is usaly a table or a div containing the table or tables
 
702
 *
 
703
 * @param container    DOM element
 
704
 */
 
705
function unMarkAllRows(container_id)
 
706
{
 
707
 
 
708
    $("#" + container_id).find("input:checkbox:enabled").prop('checked', false)
 
709
    .trigger("change")
 
710
    .parents("tr").removeClass("marked");
 
711
    return true;
 
712
}
 
713
 
 
714
/**
 
715
 * Checks/unchecks all checkbox in given conainer (f.e. a form, fieldset or div)
 
716
 *
 
717
 * @param string   container_id  the container id
 
718
 * @param boolean  state         new value for checkbox (true or false)
 
719
 * @return boolean  always true
 
720
 */
 
721
function setCheckboxes(container_id, state)
 
722
{
 
723
 
 
724
    $("#" + container_id).find("input:checkbox").prop('checked', state);
 
725
    return true;
 
726
} // end of the 'setCheckboxes()' function
 
727
 
 
728
/**
 
729
  * Checks/unchecks all options of a <select> element
 
730
  *
 
731
  * @param string   the form name
 
732
  * @param string   the element name
 
733
  * @param boolean  whether to check or to uncheck options
 
734
  *
 
735
  * @return boolean  always true
 
736
  */
 
737
function setSelectOptions(the_form, the_select, do_check)
 
738
{
 
739
    $("form[name='"+ the_form +"'] select[name='"+the_select+"']").find("option").prop('selected', do_check);
 
740
    return true;
 
741
} // end of the 'setSelectOptions()' function
 
742
 
 
743
/**
 
744
 * Sets current value for query box.
 
745
 */
 
746
function setQuery(query)
 
747
{
 
748
    if (codemirror_editor) {
 
749
        codemirror_editor.setValue(query);
 
750
        codemirror_editor.focus();
 
751
    } else {
 
752
        document.sqlform.sql_query.value = query;
 
753
        document.sqlform.sql_query.focus();
 
754
    }
 
755
}
 
756
 
 
757
 
 
758
/**
 
759
  * Create quick sql statements.
 
760
  *
 
761
  */
 
762
function insertQuery(queryType)
 
763
{
 
764
    if (queryType == "clear") {
 
765
        setQuery('');
 
766
        return;
 
767
    }
 
768
 
 
769
    var query = "";
 
770
    var myListBox = document.sqlform.dummy;
 
771
    var table = document.sqlform.table.value;
 
772
 
 
773
    if (myListBox.options.length > 0) {
 
774
        sql_box_locked = true;
 
775
        var chaineAj = "";
 
776
        var valDis = "";
 
777
        var editDis = "";
 
778
        var NbSelect = 0;
 
779
        for (var i=0; i < myListBox.options.length; i++) {
 
780
            NbSelect++;
 
781
            if (NbSelect > 1) {
 
782
                chaineAj += ", ";
 
783
                valDis += ",";
 
784
                editDis += ",";
 
785
            }
 
786
            chaineAj += myListBox.options[i].value;
 
787
            valDis += "[value-" + NbSelect + "]";
 
788
            editDis += myListBox.options[i].value + "=[value-" + NbSelect + "]";
 
789
        }
 
790
        if (queryType == "selectall") {
 
791
            query = "SELECT * FROM `" + table + "` WHERE 1";
 
792
        } else if (queryType == "select") {
 
793
            query = "SELECT " + chaineAj + " FROM `" + table + "` WHERE 1";
 
794
        } else if (queryType == "insert") {
 
795
               query = "INSERT INTO `" + table + "`(" + chaineAj + ") VALUES (" + valDis + ")";
 
796
        } else if (queryType == "update") {
 
797
            query = "UPDATE `" + table + "` SET " + editDis + " WHERE 1";
 
798
        } else if (queryType == "delete") {
 
799
            query = "DELETE FROM `" + table + "` WHERE 1";
 
800
        }
 
801
        setQuery(query);
 
802
        sql_box_locked = false;
 
803
    }
 
804
}
 
805
 
 
806
 
 
807
/**
 
808
  * Inserts multiple fields.
 
809
  *
 
810
  */
 
811
function insertValueQuery()
 
812
{
 
813
    var myQuery = document.sqlform.sql_query;
 
814
    var myListBox = document.sqlform.dummy;
 
815
 
 
816
    if (myListBox.options.length > 0) {
 
817
        sql_box_locked = true;
 
818
        var chaineAj = "";
 
819
        var NbSelect = 0;
 
820
        for (var i=0; i<myListBox.options.length; i++) {
 
821
            if (myListBox.options[i].selected) {
 
822
                NbSelect++;
 
823
                if (NbSelect > 1) {
 
824
                    chaineAj += ", ";
 
825
                }
 
826
                chaineAj += myListBox.options[i].value;
 
827
            }
 
828
        }
 
829
 
 
830
        /* CodeMirror support */
 
831
        if (codemirror_editor) {
 
832
            codemirror_editor.replaceSelection(chaineAj);
 
833
        //IE support
 
834
        } else if (document.selection) {
 
835
            myQuery.focus();
 
836
            var sel = document.selection.createRange();
 
837
            sel.text = chaineAj;
 
838
            document.sqlform.insert.focus();
 
839
        }
 
840
        //MOZILLA/NETSCAPE support
 
841
        else if (document.sqlform.sql_query.selectionStart || document.sqlform.sql_query.selectionStart == "0") {
 
842
            var startPos = document.sqlform.sql_query.selectionStart;
 
843
            var endPos = document.sqlform.sql_query.selectionEnd;
 
844
            var chaineSql = document.sqlform.sql_query.value;
 
845
 
 
846
            myQuery.value = chaineSql.substring(0, startPos) + chaineAj + chaineSql.substring(endPos, chaineSql.length);
 
847
        } else {
 
848
            myQuery.value += chaineAj;
 
849
        }
 
850
        sql_box_locked = false;
 
851
    }
 
852
}
 
853
 
 
854
/**
 
855
 * Add a date/time picker to each element that needs it
 
856
 * (only when jquery-ui-timepicker-addon.js is loaded)
 
857
 */
 
858
function addDateTimePicker() {
 
859
    if ($.timepicker != undefined) {
 
860
        $('input.datefield, input.datetimefield').each(function() {
 
861
            PMA_addDatepicker($(this));
 
862
        });
 
863
    }
 
864
}
 
865
 
 
866
/**
 
867
  * Refresh/resize the WYSIWYG scratchboard
 
868
  */
 
869
function refreshLayout()
 
870
{
 
871
    var $elm = $('#pdflayout');
 
872
    var orientation = $('#orientation_opt').val();
 
873
    if ($('#paper_opt').length==1) {
 
874
        var paper = $('#paper_opt').val();
 
875
    }else{
 
876
        var paper = 'A4';
 
877
    }
 
878
    if (orientation == 'P') {
 
879
        var posa = 'x';
 
880
        var posb = 'y';
 
881
    } else {
 
882
        var posa = 'y';
 
883
        var posb = 'x';
 
884
    }
 
885
    $elm.css('width', pdfPaperSize(paper, posa) + 'px');
 
886
    $elm.css('height', pdfPaperSize(paper, posb) + 'px');
 
887
}
 
888
 
 
889
/**
 
890
 * Initializes positions of elements.
 
891
 */
 
892
function TableDragInit() {
 
893
    $('.pdflayout_table').each(function () {
 
894
        var $this = $(this);
 
895
        var number = $this.data('number');
 
896
        var x = $('#c_table_' + number + '_x').val();
 
897
        var y = $('#c_table_' + number + '_y').val();
 
898
        $this.css('left', x + 'px');
 
899
        $this.css('top', y + 'px');
 
900
        /* Make elements draggable */
 
901
        $this.draggable({
 
902
            containment: "parent",
 
903
            drag: function (evt, ui) {
 
904
                var number = $this.data('number');
 
905
                $('#c_table_' + number + '_x').val(parseInt(ui.position.left));
 
906
                $('#c_table_' + number + '_y').val(parseInt(ui.position.top));
 
907
            }
 
908
        });
 
909
    });
 
910
}
 
911
 
 
912
/**
 
913
 * Resets drag and drop positions.
 
914
 */
 
915
function resetDrag() {
 
916
    $('.pdflayout_table').each(function () {
 
917
        var $this = $(this);
 
918
        var x = $this.data('x');
 
919
        var y = $this.data('y');
 
920
        $this.css('left', x + 'px');
 
921
        $this.css('top', y + 'px');
 
922
    });
 
923
}
 
924
 
 
925
/**
 
926
 * User schema handlers.
 
927
 */
 
928
$(function () {
 
929
    /* Move in scratchboard on manual change */
 
930
    $('.position-change').live('change', function () {
 
931
        var $this = $(this);
 
932
        var $elm = $('#table_' + $this.data('number'));
 
933
        $elm.css($this.data('axis'), $this.val() + 'px');
 
934
    });
 
935
    /* Refresh on paper size/orientation change */
 
936
    $('.paper-change').live('change', function () {
 
937
        var $elm = $('#pdflayout');
 
938
        if ($elm.css('visibility') == 'visible') {
 
939
            refreshLayout();
 
940
            TableDragInit();
 
941
        }
 
942
    });
 
943
    /* Show/hide the WYSIWYG scratchboard */
 
944
    $('#toggle-dragdrop').live('click', function () {
 
945
        var $elm = $('#pdflayout');
 
946
        if ($elm.css('visibility') == 'hidden') {
 
947
            refreshLayout();
 
948
            TableDragInit();
 
949
            $elm.css('visibility', 'visible');
 
950
            $elm.css('display', 'block');
 
951
            $('#showwysiwyg').val('1');
 
952
        } else {
 
953
            $elm.css('visibility', 'hidden');
 
954
            $elm.css('display', 'none');
 
955
            $('#showwysiwyg').val('0');
 
956
        }
 
957
    });
 
958
    /* Reset scratchboard */
 
959
    $('#reset-dragdrop').live('click', function () {
 
960
        resetDrag();
 
961
    });
 
962
});
 
963
 
 
964
/**
 
965
 * Returns paper sizes for a given format
 
966
 */
 
967
function pdfPaperSize(format, axis)
 
968
{
 
969
    switch (format.toUpperCase()) {
 
970
        case '4A0':
 
971
            if (axis == 'x') {
 
972
                return 4767.87;
 
973
            } else {
 
974
                return 6740.79;
 
975
            }
 
976
            break;
 
977
        case '2A0':
 
978
            if (axis == 'x') {
 
979
                return 3370.39;
 
980
            } else {
 
981
                return 4767.87;
 
982
            }
 
983
            break;
 
984
        case 'A0':
 
985
            if (axis == 'x') {
 
986
                return 2383.94;
 
987
            } else {
 
988
                return 3370.39;
 
989
            }
 
990
            break;
 
991
        case 'A1':
 
992
            if (axis == 'x') {
 
993
                return 1683.78;
 
994
            } else {
 
995
                return 2383.94;
 
996
            }
 
997
            break;
 
998
        case 'A2':
 
999
            if (axis == 'x') {
 
1000
                return 1190.55;
 
1001
            } else {
 
1002
                return 1683.78;
 
1003
            }
 
1004
            break;
 
1005
        case 'A3':
 
1006
            if (axis == 'x') {
 
1007
                return 841.89;
 
1008
            } else {
 
1009
                return 1190.55;
 
1010
            }
 
1011
            break;
 
1012
        case 'A4':
 
1013
            if (axis == 'x') {
 
1014
                return 595.28;
 
1015
            } else {
 
1016
                return 841.89;
 
1017
            }
 
1018
            break;
 
1019
        case 'A5':
 
1020
            if (axis == 'x') {
 
1021
                return 419.53;
 
1022
            } else {
 
1023
                return 595.28;
 
1024
            }
 
1025
            break;
 
1026
        case 'A6':
 
1027
            if (axis == 'x') {
 
1028
                return 297.64;
 
1029
            } else {
 
1030
                return 419.53;
 
1031
            }
 
1032
            break;
 
1033
        case 'A7':
 
1034
            if (axis == 'x') {
 
1035
                return 209.76;
 
1036
            } else {
 
1037
                return 297.64;
 
1038
            }
 
1039
            break;
 
1040
        case 'A8':
 
1041
            if (axis == 'x') {
 
1042
                return 147.40;
 
1043
            } else {
 
1044
                return 209.76;
 
1045
            }
 
1046
            break;
 
1047
        case 'A9':
 
1048
            if (axis == 'x') {
 
1049
                return 104.88;
 
1050
            } else {
 
1051
                return 147.40;
 
1052
            }
 
1053
            break;
 
1054
        case 'A10':
 
1055
            if (axis == 'x') {
 
1056
                return 73.70;
 
1057
            } else {
 
1058
                return 104.88;
 
1059
            }
 
1060
            break;
 
1061
        case 'B0':
 
1062
            if (axis == 'x') {
 
1063
                return 2834.65;
 
1064
            } else {
 
1065
                return 4008.19;
 
1066
            }
 
1067
            break;
 
1068
        case 'B1':
 
1069
            if (axis == 'x') {
 
1070
                return 2004.09;
 
1071
            } else {
 
1072
                return 2834.65;
 
1073
            }
 
1074
            break;
 
1075
        case 'B2':
 
1076
            if (axis == 'x') {
 
1077
                return 1417.32;
 
1078
            } else {
 
1079
                return 2004.09;
 
1080
            }
 
1081
            break;
 
1082
        case 'B3':
 
1083
            if (axis == 'x') {
 
1084
                return 1000.63;
 
1085
            } else {
 
1086
                return 1417.32;
 
1087
            }
 
1088
            break;
 
1089
        case 'B4':
 
1090
            if (axis == 'x') {
 
1091
                return 708.66;
 
1092
            } else {
 
1093
                return 1000.63;
 
1094
            }
 
1095
            break;
 
1096
        case 'B5':
 
1097
            if (axis == 'x') {
 
1098
                return 498.90;
 
1099
            } else {
 
1100
                return 708.66;
 
1101
            }
 
1102
            break;
 
1103
        case 'B6':
 
1104
            if (axis == 'x') {
 
1105
                return 354.33;
 
1106
            } else {
 
1107
                return 498.90;
 
1108
            }
 
1109
            break;
 
1110
        case 'B7':
 
1111
            if (axis == 'x') {
 
1112
                return 249.45;
 
1113
            } else {
 
1114
                return 354.33;
 
1115
            }
 
1116
            break;
 
1117
        case 'B8':
 
1118
            if (axis == 'x') {
 
1119
                return 175.75;
 
1120
            } else {
 
1121
                return 249.45;
 
1122
            }
 
1123
            break;
 
1124
        case 'B9':
 
1125
            if (axis == 'x') {
 
1126
                return 124.72;
 
1127
            } else {
 
1128
                return 175.75;
 
1129
            }
 
1130
            break;
 
1131
        case 'B10':
 
1132
            if (axis == 'x') {
 
1133
                return 87.87;
 
1134
            } else {
 
1135
                return 124.72;
 
1136
            }
 
1137
            break;
 
1138
        case 'C0':
 
1139
            if (axis == 'x') {
 
1140
                return 2599.37;
 
1141
            } else {
 
1142
                return 3676.54;
 
1143
            }
 
1144
            break;
 
1145
        case 'C1':
 
1146
            if (axis == 'x') {
 
1147
                return 1836.85;
 
1148
            } else {
 
1149
                return 2599.37;
 
1150
            }
 
1151
            break;
 
1152
        case 'C2':
 
1153
            if (axis == 'x') {
 
1154
                return 1298.27;
 
1155
            } else {
 
1156
                return 1836.85;
 
1157
            }
 
1158
            break;
 
1159
        case 'C3':
 
1160
            if (axis == 'x') {
 
1161
                return 918.43;
 
1162
            } else {
 
1163
                return 1298.27;
 
1164
            }
 
1165
            break;
 
1166
        case 'C4':
 
1167
            if (axis == 'x') {
 
1168
                return 649.13;
 
1169
            } else {
 
1170
                return 918.43;
 
1171
            }
 
1172
            break;
 
1173
        case 'C5':
 
1174
            if (axis == 'x') {
 
1175
                return 459.21;
 
1176
            } else {
 
1177
                return 649.13;
 
1178
            }
 
1179
            break;
 
1180
        case 'C6':
 
1181
            if (axis == 'x') {
 
1182
                return 323.15;
 
1183
            } else {
 
1184
                return 459.21;
 
1185
            }
 
1186
            break;
 
1187
        case 'C7':
 
1188
            if (axis == 'x') {
 
1189
                return 229.61;
 
1190
            } else {
 
1191
                return 323.15;
 
1192
            }
 
1193
            break;
 
1194
        case 'C8':
 
1195
            if (axis == 'x') {
 
1196
                return 161.57;
 
1197
            } else {
 
1198
                return 229.61;
 
1199
            }
 
1200
            break;
 
1201
        case 'C9':
 
1202
            if (axis == 'x') {
 
1203
                return 113.39;
 
1204
            } else {
 
1205
                return 161.57;
 
1206
            }
 
1207
            break;
 
1208
        case 'C10':
 
1209
            if (axis == 'x') {
 
1210
                return 79.37;
 
1211
            } else {
 
1212
                return 113.39;
 
1213
            }
 
1214
            break;
 
1215
        case 'RA0':
 
1216
            if (axis == 'x') {
 
1217
                return 2437.80;
 
1218
            } else {
 
1219
                return 3458.27;
 
1220
            }
 
1221
            break;
 
1222
        case 'RA1':
 
1223
            if (axis == 'x') {
 
1224
                return 1729.13;
 
1225
            } else {
 
1226
                return 2437.80;
 
1227
            }
 
1228
            break;
 
1229
        case 'RA2':
 
1230
            if (axis == 'x') {
 
1231
                return 1218.90;
 
1232
            } else {
 
1233
                return 1729.13;
 
1234
            }
 
1235
            break;
 
1236
        case 'RA3':
 
1237
            if (axis == 'x') {
 
1238
                return 864.57;
 
1239
            } else {
 
1240
                return 1218.90;
 
1241
            }
 
1242
            break;
 
1243
        case 'RA4':
 
1244
            if (axis == 'x') {
 
1245
                return 609.45;
 
1246
            } else {
 
1247
                return 864.57;
 
1248
            }
 
1249
            break;
 
1250
        case 'SRA0':
 
1251
            if (axis == 'x') {
 
1252
                return 2551.18;
 
1253
            } else {
 
1254
                return 3628.35;
 
1255
            }
 
1256
            break;
 
1257
        case 'SRA1':
 
1258
            if (axis == 'x') {
 
1259
                return 1814.17;
 
1260
            } else {
 
1261
                return 2551.18;
 
1262
            }
 
1263
            break;
 
1264
        case 'SRA2':
 
1265
            if (axis == 'x') {
 
1266
                return 1275.59;
 
1267
            } else {
 
1268
                return 1814.17;
 
1269
            }
 
1270
            break;
 
1271
        case 'SRA3':
 
1272
            if (axis == 'x') {
 
1273
                return 907.09;
 
1274
            } else {
 
1275
                return 1275.59;
 
1276
            }
 
1277
            break;
 
1278
        case 'SRA4':
 
1279
            if (axis == 'x') {
 
1280
                return 637.80;
 
1281
            } else {
 
1282
                return 907.09;
 
1283
            }
 
1284
            break;
 
1285
        case 'LETTER':
 
1286
            if (axis == 'x') {
 
1287
                return 612.00;
 
1288
            } else {
 
1289
                return 792.00;
 
1290
            }
 
1291
            break;
 
1292
        case 'LEGAL':
 
1293
            if (axis == 'x') {
 
1294
                return 612.00;
 
1295
            } else {
 
1296
                return 1008.00;
 
1297
            }
 
1298
            break;
 
1299
        case 'EXECUTIVE':
 
1300
            if (axis == 'x') {
 
1301
                return 521.86;
 
1302
            } else {
 
1303
                return 756.00;
 
1304
            }
 
1305
            break;
 
1306
        case 'FOLIO':
 
1307
            if (axis == 'x') {
 
1308
                return 612.00;
 
1309
            } else {
 
1310
                return 936.00;
 
1311
            }
 
1312
            break;
 
1313
    } // end switch
 
1314
 
 
1315
    return 0;
 
1316
}
 
1317
 
 
1318
/**
 
1319
 * Unbind all event handlers before tearing down a page
 
1320
 */
 
1321
AJAX.registerTeardown('functions.js', function() {
 
1322
    $("a.inline_edit_sql").die('click');
 
1323
    $("input#sql_query_edit_save").die('click');
 
1324
    $("input#sql_query_edit_discard").die('click');
 
1325
    $('input.sqlbutton').unbind('click');
 
1326
    $("#export_type").unbind('change');
 
1327
    $('#sqlquery').unbind('keydown');
 
1328
    $('#sql_query_edit').unbind('keydown');
 
1329
 
 
1330
    if (codemirror_inline_editor) {
 
1331
        // Copy the sql query to the text area to preserve it.
 
1332
        $('#sql_query_edit').text(codemirror_inline_editor.getValue());
 
1333
        $(codemirror_inline_editor.getWrapperElement()).unbind('keydown');
 
1334
        codemirror_inline_editor.toTextArea();
 
1335
        codemirror_inline_editor = false;
 
1336
    }
 
1337
    if (codemirror_editor) {
 
1338
        $(codemirror_editor.getWrapperElement()).unbind('keydown');
 
1339
    }
 
1340
});
 
1341
 
 
1342
/**
 
1343
 * Jquery Coding for inline editing SQL_QUERY
 
1344
 */
 
1345
AJAX.registerOnload('functions.js', function() {
 
1346
    // If we are coming back to the page by clicking forward button
 
1347
    // of the browser, bind the code mirror to inline query editor.
 
1348
    bindCodeMirrorToInlineEditor();
 
1349
    $("a.inline_edit_sql").live('click', function() {
 
1350
        if ($('#sql_query_edit').length) {
 
1351
            // An inline query editor is already open,
 
1352
            // we don't want another copy of it
 
1353
            return false;
 
1354
        }
 
1355
 
 
1356
        var $form = $(this).prev('form');
 
1357
        var sql_query  = $form.find("input[name='sql_query']").val();
 
1358
        var $inner_sql = $(this).parent().prev().find('.inner_sql');
 
1359
        var old_text   = $inner_sql.html();
 
1360
 
 
1361
        var new_content = "<textarea name=\"sql_query_edit\" id=\"sql_query_edit\">" + sql_query + "</textarea>\n";
 
1362
        new_content    += "<input type=\"submit\" id=\"sql_query_edit_save\" class=\"button btnSave\" value=\"" + PMA_messages['strGo'] + "\"/>\n";
 
1363
        new_content    += "<input type=\"button\" id=\"sql_query_edit_discard\" class=\"button btnDiscard\" value=\"" + PMA_messages['strCancel'] + "\"/>\n";
 
1364
        var $editor_area = $('div#inline_editor');
 
1365
        if ($editor_area.length == 0) {
 
1366
            $editor_area = $('<div id="inline_editor_outer"></div>');
 
1367
            $editor_area.insertBefore($inner_sql);
 
1368
        }
 
1369
        $editor_area.html(new_content);
 
1370
        $inner_sql.hide();
 
1371
 
 
1372
        bindCodeMirrorToInlineEditor();
 
1373
        return false;
 
1374
    });
 
1375
 
 
1376
    $("input#sql_query_edit_save").live('click', function() {
 
1377
        if (codemirror_inline_editor) {
 
1378
            var sql_query = codemirror_inline_editor.getValue();
 
1379
        } else {
 
1380
            var sql_query = $(this).prev().val();
 
1381
        }
 
1382
 
 
1383
        var $form = $("a.inline_edit_sql").prev('form');
 
1384
        var $fake_form = $('<form>', {action: 'import.php', method: 'post'})
 
1385
                .append($form.find("input[name=server], input[name=db], input[name=table], input[name=token]").clone())
 
1386
                .append($('<input/>', {type: 'hidden', name: 'show_query', value: 1}))
 
1387
                .append($('<input/>', {type: 'hidden', name: 'sql_query', value: sql_query}));
 
1388
        $fake_form.appendTo($('body')).submit();
 
1389
    });
 
1390
 
 
1391
    $("input#sql_query_edit_discard").live('click', function() {
 
1392
        $('div#inline_editor_outer')
 
1393
            .empty()
 
1394
            .siblings('.inner_sql').show();
 
1395
    });
 
1396
 
 
1397
    $('input.sqlbutton').click(function(evt) {
 
1398
        insertQuery(evt.target.id);
 
1399
        return false;
 
1400
    });
 
1401
 
 
1402
    $("#export_type").change(function() {
 
1403
        if ($("#export_type").val()=='svg') {
 
1404
            $("#show_grid_opt").prop("disabled",true);
 
1405
            $("#orientation_opt").prop("disabled",true);
 
1406
            $("#with_doc").prop("disabled",true);
 
1407
            $("#show_table_dim_opt").removeProp("disabled");
 
1408
            $("#all_tables_same_width").removeProp("disabled");
 
1409
            $("#paper_opt").removeProp("disabled");
 
1410
            $("#show_color_opt").removeProp("disabled");
 
1411
            //$(this).css("background-color","yellow");
 
1412
        } else if ($("#export_type").val()=='dia') {
 
1413
            $("#show_grid_opt").prop("disabled",true);
 
1414
            $("#with_doc").prop("disabled",true);
 
1415
            $("#show_table_dim_opt").prop("disabled",true);
 
1416
            $("#all_tables_same_width").prop("disabled",true);
 
1417
            $("#paper_opt").removeProp("disabled");
 
1418
            $("#show_color_opt").removeProp("disabled");
 
1419
            $("#orientation_opt").removeProp("disabled");
 
1420
        } else if ($("#export_type").val()=='eps') {
 
1421
            $("#show_grid_opt").prop("disabled",true);
 
1422
            $("#orientation_opt").removeProp("disabled");
 
1423
            $("#with_doc").prop("disabled",true);
 
1424
            $("#show_table_dim_opt").prop("disabled",true);
 
1425
            $("#all_tables_same_width").prop("disabled",true);
 
1426
            $("#paper_opt").prop("disabled",true);
 
1427
            $("#show_color_opt").prop("disabled",true);
 
1428
        } else if ($("#export_type").val()=='pdf') {
 
1429
            $("#show_grid_opt").removeProp("disabled");
 
1430
            $("#orientation_opt").removeProp("disabled");
 
1431
            $("#with_doc").removeProp("disabled");
 
1432
            $("#show_table_dim_opt").removeProp("disabled");
 
1433
            $("#all_tables_same_width").removeProp("disabled");
 
1434
            $("#paper_opt").removeProp("disabled");
 
1435
            $("#show_color_opt").removeProp("disabled");
 
1436
        } else {
 
1437
            // nothing
 
1438
        }
 
1439
    });
 
1440
 
 
1441
    if ($('#input_username')) {
 
1442
        if ($('#input_username').val() == '') {
 
1443
            $('#input_username').focus();
 
1444
        } else {
 
1445
            $('#input_password').focus();
 
1446
        }
 
1447
    }
 
1448
});
 
1449
 
 
1450
/**
 
1451
 * Binds the CodeMirror to the text area used to inline edit a query.
 
1452
 */
 
1453
function bindCodeMirrorToInlineEditor() {
 
1454
    var $inline_editor = $('#sql_query_edit');
 
1455
    if ($inline_editor.length > 0) {
 
1456
        if (typeof CodeMirror !== 'undefined') {
 
1457
            var height = $('#sql_query_edit').css('height');
 
1458
            codemirror_inline_editor = CodeMirror.fromTextArea($inline_editor[0], {
 
1459
                lineNumbers: true,
 
1460
                matchBrackets: true,
 
1461
                indentUnit: 4,
 
1462
                mode: "text/x-mysql",
 
1463
                lineWrapping: true
 
1464
            });
 
1465
            codemirror_inline_editor.getScrollerElement().style.height = height;
 
1466
            codemirror_inline_editor.refresh();
 
1467
            codemirror_inline_editor.focus();
 
1468
            $(codemirror_inline_editor.getWrapperElement()).bind(
 
1469
                'keydown',
 
1470
                catchKeypressesFromSqlTextboxes
 
1471
            );
 
1472
        } else {
 
1473
            $inline_editor.focus().bind(
 
1474
                'keydown',
 
1475
                catchKeypressesFromSqlTextboxes
 
1476
            );
 
1477
        }
 
1478
    }
 
1479
}
 
1480
 
 
1481
function catchKeypressesFromSqlTextboxes(event) {
 
1482
    // ctrl-enter is 10 in chrome and ie, but 13 in ff
 
1483
    if (event.ctrlKey && (event.keyCode == 13 || event.keyCode == 10)) {
 
1484
        if ($('#sql_query_edit').length > 0) {
 
1485
            $("#sql_query_edit_save").trigger('click');
 
1486
        } else if ($('#sqlquery').length > 0) {
 
1487
            $("#button_submit_query").trigger('click');
 
1488
        }
 
1489
    }
 
1490
}
 
1491
 
 
1492
/**
 
1493
 * Show a message on the top of the page for an Ajax request
 
1494
 *
 
1495
 * Sample usage:
 
1496
 *
 
1497
 * 1) var $msg = PMA_ajaxShowMessage();
 
1498
 * This will show a message that reads "Loading...". Such a message will not
 
1499
 * disappear automatically and cannot be dismissed by the user. To remove this
 
1500
 * message either the PMA_ajaxRemoveMessage($msg) function must be called or
 
1501
 * another message must be show with PMA_ajaxShowMessage() function.
 
1502
 *
 
1503
 * 2) var $msg = PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']);
 
1504
 * This is a special case. The behaviour is same as above,
 
1505
 * just with a different message
 
1506
 *
 
1507
 * 3) var $msg = PMA_ajaxShowMessage('The operation was successful');
 
1508
 * This will show a message that will disappear automatically and it can also
 
1509
 * be dismissed by the user.
 
1510
 *
 
1511
 * 4) var $msg = PMA_ajaxShowMessage('Some error', false);
 
1512
 * This will show a message that will not disappear automatically, but it
 
1513
 * can be dismissed by the user after he has finished reading it.
 
1514
 *
 
1515
 * @param string  message     string containing the message to be shown.
 
1516
 *                              optional, defaults to 'Loading...'
 
1517
 * @param mixed   timeout     number of milliseconds for the message to be visible
 
1518
 *                              optional, defaults to 5000. If set to 'false', the
 
1519
 *                              notification will never disappear
 
1520
 * @return jQuery object       jQuery Element that holds the message div
 
1521
 *                              this object can be passed to PMA_ajaxRemoveMessage()
 
1522
 *                              to remove the notification
 
1523
 */
 
1524
function PMA_ajaxShowMessage(message, timeout)
 
1525
{
 
1526
    /**
 
1527
     * @var self_closing Whether the notification will automatically disappear
 
1528
     */
 
1529
    var self_closing = true;
 
1530
    /**
 
1531
     * @var dismissable Whether the user will be able to remove
 
1532
     *                  the notification by clicking on it
 
1533
     */
 
1534
    var dismissable = true;
 
1535
    // Handle the case when a empty data.message is passed.
 
1536
    // We don't want the empty message
 
1537
    if (message == '') {
 
1538
        return true;
 
1539
    } else if (! message) {
 
1540
        // If the message is undefined, show the default
 
1541
        message = PMA_messages['strLoading'];
 
1542
        dismissable = false;
 
1543
        self_closing = false;
 
1544
    } else if (message == PMA_messages['strProcessingRequest']) {
 
1545
        // This is another case where the message should not disappear
 
1546
        dismissable = false;
 
1547
        self_closing = false;
 
1548
    }
 
1549
    // Figure out whether (or after how long) to remove the notification
 
1550
    if (timeout == undefined) {
 
1551
        timeout = 5000;
 
1552
    } else if (timeout === false) {
 
1553
        self_closing = false;
 
1554
    }
 
1555
    // Create a parent element for the AJAX messages, if necessary
 
1556
    if ($('#loading_parent').length == 0) {
 
1557
        $('<div id="loading_parent"></div>')
 
1558
        .prependTo("body");
 
1559
    }
 
1560
    // Update message count to create distinct message elements every time
 
1561
    ajax_message_count++;
 
1562
    // Remove all old messages, if any
 
1563
    $("span.ajax_notification[id^=ajax_message_num]").remove();
 
1564
    /**
 
1565
     * @var    $retval    a jQuery object containing the reference
 
1566
     *                    to the created AJAX message
 
1567
     */
 
1568
    var $retval = $(
 
1569
            '<span class="ajax_notification" id="ajax_message_num_'
 
1570
            + ajax_message_count +
 
1571
            '"></span>'
 
1572
    )
 
1573
    .hide()
 
1574
    .appendTo("#loading_parent")
 
1575
    .html(message)
 
1576
    .show();
 
1577
    // If the notification is self-closing we should create a callback to remove it
 
1578
    if (self_closing) {
 
1579
        $retval
 
1580
        .delay(timeout)
 
1581
        .fadeOut('medium', function() {
 
1582
            if ($(this).is('.dismissable')) {
 
1583
                $(this).tooltip('destroy');
 
1584
            }
 
1585
            // Remove the notification
 
1586
            $(this).remove();
 
1587
        });
 
1588
    }
 
1589
    // If the notification is dismissable we need to add the relevant class to it
 
1590
    // and add a tooltip so that the users know that it can be removed
 
1591
    if (dismissable) {
 
1592
        $retval.addClass('dismissable').css('cursor', 'pointer');
 
1593
        /**
 
1594
         * Add a tooltip to the notification to let the user know that (s)he
 
1595
         * can dismiss the ajax notification by clicking on it.
 
1596
         */
 
1597
        PMA_tooltip(
 
1598
            $retval,
 
1599
            'span',
 
1600
            PMA_messages['strDismiss']
 
1601
        );
 
1602
    }
 
1603
 
 
1604
    return $retval;
 
1605
}
 
1606
 
 
1607
/**
 
1608
 * Removes the message shown for an Ajax operation when it's completed
 
1609
 *
 
1610
 * @param jQuery object   jQuery Element that holds the notification
 
1611
 *
 
1612
 * @return nothing
 
1613
 */
 
1614
function PMA_ajaxRemoveMessage($this_msgbox)
 
1615
{
 
1616
    if ($this_msgbox != undefined && $this_msgbox instanceof jQuery) {
 
1617
        $this_msgbox
 
1618
        .stop(true, true)
 
1619
        .fadeOut('medium');
 
1620
        if ($this_msgbox.is('.dismissable')) {
 
1621
            if ($.isFunction($this_msgbox.tooltip)) {
 
1622
                $this_msgbox.tooltip('destroy');
 
1623
            }
 
1624
        } else {
 
1625
            $this_msgbox.remove();
 
1626
        }
 
1627
    }
 
1628
}
 
1629
 
 
1630
// This event only need to be fired once after the initial page load
 
1631
$(function() {
 
1632
    /**
 
1633
     * Allows the user to dismiss a notification
 
1634
     * created with PMA_ajaxShowMessage()
 
1635
     */
 
1636
    $('span.ajax_notification.dismissable').live('click', function () {
 
1637
        PMA_ajaxRemoveMessage($(this));
 
1638
    });
 
1639
    /**
 
1640
     * The below two functions hide the "Dismiss notification" tooltip when a user
 
1641
     * is hovering a link or button that is inside an ajax message
 
1642
     */
 
1643
    $('span.ajax_notification a, span.ajax_notification button, span.ajax_notification input')
 
1644
    .live('mouseover', function () {
 
1645
        $(this).parents('span.ajax_notification').tooltip('disable');
 
1646
    })
 
1647
    .live('mouseout', function () {
 
1648
        $(this).parents('span.ajax_notification').tooltip('enable');
 
1649
    });
 
1650
});
 
1651
 
 
1652
/**
 
1653
 * Hides/shows the "Open in ENUM/SET editor" message, depending on the data type of the column currently selected
 
1654
 */
 
1655
function PMA_showNoticeForEnum(selectElement)
 
1656
{
 
1657
    var enum_notice_id = selectElement.attr("id").split("_")[1];
 
1658
    enum_notice_id += "_" + (parseInt(selectElement.attr("id").split("_")[2]) + 1);
 
1659
    var selectedType = selectElement.val();
 
1660
    if (selectedType == "ENUM" || selectedType == "SET") {
 
1661
        $("p#enum_notice_" + enum_notice_id).show();
 
1662
    } else {
 
1663
        $("p#enum_notice_" + enum_notice_id).hide();
 
1664
    }
 
1665
}
 
1666
 
 
1667
/*
 
1668
 * Creates a Profiling Chart with jqplot. Used in sql.js
 
1669
 * and in server_status_monitor.js
 
1670
 */
 
1671
function PMA_createProfilingChartJqplot(target, data)
 
1672
{
 
1673
    return $.jqplot(target, [data],
 
1674
        {
 
1675
            seriesDefaults: {
 
1676
                renderer: $.jqplot.PieRenderer,
 
1677
                rendererOptions: {
 
1678
                    showDataLabels:  true
 
1679
                }
 
1680
            },
 
1681
            legend: {
 
1682
                show: true,
 
1683
                location: 'e'
 
1684
            },
 
1685
            // from http://tango.freedesktop.org/Tango_Icon_Theme_Guidelines#Color_Palette
 
1686
            seriesColors: [
 
1687
             '#fce94f',
 
1688
             '#fcaf3e',
 
1689
             '#e9b96e',
 
1690
             '#8ae234',
 
1691
             '#729fcf',
 
1692
             '#ad7fa8',
 
1693
             '#ef2929',
 
1694
             '#eeeeec',
 
1695
             '#888a85',
 
1696
             '#c4a000',
 
1697
             '#ce5c00',
 
1698
             '#8f5902',
 
1699
             '#4e9a06',
 
1700
             '#204a87',
 
1701
             '#5c3566',
 
1702
             '#a40000',
 
1703
             '#babdb6',
 
1704
             '#2e3436'
 
1705
            ]
 
1706
        }
 
1707
    );
 
1708
}
 
1709
 
 
1710
/**
 
1711
 * Formats a profiling duration nicely (in us and ms time). Used in server_status.js
 
1712
 *
 
1713
 * @param  integer    Number to be formatted, should be in the range of microsecond to second
 
1714
 * @param  integer    Accuracy, how many numbers right to the comma should be
 
1715
 * @return string     The formatted number
 
1716
 */
 
1717
function PMA_prettyProfilingNum(num, acc)
 
1718
{
 
1719
    if (!acc) {
 
1720
        acc = 2;
 
1721
    }
 
1722
    acc = Math.pow(10, acc);
 
1723
    if (num * 1000 < 0.1) {
 
1724
        num = Math.round(acc * (num * 1000 * 1000)) / acc + 'µ';
 
1725
    } else if (num < 0.1) {
 
1726
        num = Math.round(acc * (num * 1000)) / acc + 'm';
 
1727
    } else {
 
1728
        num = Math.round(acc * num) / acc;
 
1729
    }
 
1730
 
 
1731
    return num + 's';
 
1732
}
 
1733
 
 
1734
 
 
1735
/**
 
1736
 * Formats a SQL Query nicely with newlines and indentation. Depends on Codemirror and MySQL Mode!
 
1737
 *
 
1738
 * @param string      Query to be formatted
 
1739
 * @return string      The formatted query
 
1740
 */
 
1741
function PMA_SQLPrettyPrint(string)
 
1742
{
 
1743
    if (typeof CodeMirror == 'undefined') {
 
1744
        return string;
 
1745
    }
 
1746
 
 
1747
    var mode = CodeMirror.getMode({},"text/x-mysql");
 
1748
    var stream = new CodeMirror.StringStream(string);
 
1749
    var state = mode.startState();
 
1750
    var token, tokens = [];
 
1751
    var output = '';
 
1752
    var tabs = function(cnt) {
 
1753
        var ret = '';
 
1754
        for (var i=0; i<4*cnt; i++) {
 
1755
            ret += " ";
 
1756
        }
 
1757
        return ret;
 
1758
    };
 
1759
 
 
1760
    // "root-level" statements
 
1761
    var statements = {
 
1762
        'select': ['select', 'from','on','where','having','limit','order by','group by'],
 
1763
        'update': ['update', 'set','where'],
 
1764
        'insert into': ['insert into', 'values']
 
1765
    };
 
1766
    // don't put spaces before these tokens
 
1767
    var spaceExceptionsBefore = { ';':true, ',': true, '.': true, '(': true };
 
1768
    // don't put spaces after these tokens
 
1769
    var spaceExceptionsAfter = { '.': true };
 
1770
 
 
1771
    // Populate tokens array
 
1772
    var str='';
 
1773
    while (! stream.eol()) {
 
1774
        stream.start = stream.pos;
 
1775
        token = mode.token(stream, state);
 
1776
        if (token != null) {
 
1777
            tokens.push([token, stream.current().toLowerCase()]);
 
1778
        }
 
1779
    }
 
1780
 
 
1781
    var currentStatement = tokens[0][1];
 
1782
 
 
1783
    if (! statements[currentStatement]) {
 
1784
        return string;
 
1785
    }
 
1786
    // Holds all currently opened code blocks (statement, function or generic)
 
1787
    var blockStack = [];
 
1788
    // Holds the type of block from last iteration (the current is in blockStack[0])
 
1789
    var previousBlock;
 
1790
    // If a new code block is found, newBlock contains its type for one iteration and vice versa for endBlock
 
1791
    var newBlock, endBlock;
 
1792
    // How much to indent in the current line
 
1793
    var indentLevel = 0;
 
1794
    // Holds the "root-level" statements
 
1795
    var statementPart, lastStatementPart = statements[currentStatement][0];
 
1796
 
 
1797
    blockStack.unshift('statement');
 
1798
 
 
1799
    // Iterate through every token and format accordingly
 
1800
    for (var i = 0; i < tokens.length; i++) {
 
1801
        previousBlock = blockStack[0];
 
1802
 
 
1803
        // New block => push to stack
 
1804
        if (tokens[i][1] == '(') {
 
1805
            if (i < tokens.length - 1 && tokens[i+1][0] == 'statement-verb') {
 
1806
                blockStack.unshift(newBlock = 'statement');
 
1807
            } else if (i > 0 && tokens[i-1][0] == 'builtin') {
 
1808
                blockStack.unshift(newBlock = 'function');
 
1809
            } else {
 
1810
                blockStack.unshift(newBlock = 'generic');
 
1811
            }
 
1812
        } else {
 
1813
            newBlock = null;
 
1814
        }
 
1815
 
 
1816
        // Block end => pop from stack
 
1817
        if (tokens[i][1] == ')') {
 
1818
            endBlock = blockStack[0];
 
1819
            blockStack.shift();
 
1820
        } else {
 
1821
            endBlock = null;
 
1822
        }
 
1823
 
 
1824
        // A subquery is starting
 
1825
        if (i > 0 && newBlock == 'statement') {
 
1826
            indentLevel++;
 
1827
            output += "\n" + tabs(indentLevel) + tokens[i][1] + ' ' + tokens[i+1][1].toUpperCase() + "\n" + tabs(indentLevel + 1);
 
1828
            currentStatement = tokens[i+1][1];
 
1829
            i++;
 
1830
            continue;
 
1831
        }
 
1832
 
 
1833
        // A subquery is ending
 
1834
        if (endBlock == 'statement' && indentLevel > 0) {
 
1835
            output += "\n" + tabs(indentLevel);
 
1836
            indentLevel--;
 
1837
        }
 
1838
 
 
1839
        // One less indentation for statement parts (from, where, order by, etc.) and a newline
 
1840
        statementPart = statements[currentStatement].indexOf(tokens[i][1]);
 
1841
        if (statementPart != -1) {
 
1842
            if (i > 0) {
 
1843
                output += "\n";
 
1844
            }
 
1845
            output += tabs(indentLevel) + tokens[i][1].toUpperCase();
 
1846
            output += "\n" + tabs(indentLevel + 1);
 
1847
            lastStatementPart = tokens[i][1];
 
1848
        }
 
1849
        // Normal indentatin and spaces for everything else
 
1850
        else {
 
1851
            if (! spaceExceptionsBefore[tokens[i][1]]
 
1852
               && ! (i > 0 && spaceExceptionsAfter[tokens[i-1][1]])
 
1853
               && output.charAt(output.length -1) != ' ' ) {
 
1854
                    output += " ";
 
1855
            }
 
1856
            if (tokens[i][0] == 'keyword') {
 
1857
                output += tokens[i][1].toUpperCase();
 
1858
            } else {
 
1859
                output += tokens[i][1];
 
1860
            }
 
1861
        }
 
1862
 
 
1863
        // split columns in select and 'update set' clauses, but only inside statements blocks
 
1864
        if (( lastStatementPart == 'select' || lastStatementPart == 'where'  || lastStatementPart == 'set')
 
1865
            && tokens[i][1]==',' && blockStack[0] == 'statement') {
 
1866
 
 
1867
            output += "\n" + tabs(indentLevel + 1);
 
1868
        }
 
1869
 
 
1870
        // split conditions in where clauses, but only inside statements blocks
 
1871
        if (lastStatementPart == 'where'
 
1872
            && (tokens[i][1]=='and' || tokens[i][1]=='or' || tokens[i][1]=='xor')) {
 
1873
 
 
1874
            if (blockStack[0] == 'statement') {
 
1875
                output += "\n" + tabs(indentLevel + 1);
 
1876
            }
 
1877
            // Todo: Also split and or blocks in newlines & identation++
 
1878
            //if (blockStack[0] == 'generic')
 
1879
             //   output += ...
 
1880
        }
 
1881
    }
 
1882
    return output;
 
1883
}
 
1884
 
 
1885
/**
 
1886
 * jQuery function that uses jQueryUI's dialogs to confirm with user. Does not
 
1887
 *  return a jQuery object yet and hence cannot be chained
 
1888
 *
 
1889
 * @param string      question
 
1890
 * @param string      url         URL to be passed to the callbackFn to make
 
1891
 *                                  an Ajax call to
 
1892
 * @param function    callbackFn  callback to execute after user clicks on OK
 
1893
 */
 
1894
 
 
1895
jQuery.fn.PMA_confirm = function(question, url, callbackFn) {
 
1896
    var confirmState = PMA_commonParams.get('confirm');
 
1897
    // when the Confirm directive is set to false in config.inc.php
 
1898
    // and not changed in user prefs, confirmState is ""
 
1899
    // when it's unticked in user prefs, confirmState is 1
 
1900
    if (confirmState === "" || confirmState === "1") {
 
1901
        // user does not want to confirm
 
1902
        if ($.isFunction(callbackFn)) {
 
1903
            callbackFn.call(this, url);
 
1904
            return true;
 
1905
        }
 
1906
    }
 
1907
    if (PMA_messages['strDoYouReally'] == '') {
 
1908
        return true;
 
1909
    }
 
1910
 
 
1911
    /**
 
1912
     * @var    button_options  Object that stores the options passed to jQueryUI
 
1913
     *                          dialog
 
1914
     */
 
1915
    var button_options = {};
 
1916
    button_options[PMA_messages['strOK']] = function() {
 
1917
        $(this).dialog("close");
 
1918
 
 
1919
        if ($.isFunction(callbackFn)) {
 
1920
            callbackFn.call(this, url);
 
1921
        }
 
1922
    };
 
1923
    button_options[PMA_messages['strCancel']] = function() {
 
1924
        $(this).dialog("close");
 
1925
    };
 
1926
 
 
1927
    $('<div/>', {'id':'confirm_dialog'})
 
1928
    .prepend(question)
 
1929
    .dialog({
 
1930
        buttons: button_options,
 
1931
        close: function () {
 
1932
            $(this).remove();
 
1933
        },
 
1934
        modal: true
 
1935
    });
 
1936
};
 
1937
 
 
1938
/**
 
1939
 * jQuery function to sort a table's body after a new row has been appended to it.
 
1940
 * Also fixes the even/odd classes of the table rows at the end.
 
1941
 *
 
1942
 * @param string      text_selector   string to select the sortKey's text
 
1943
 *
 
1944
 * @return jQuery Object for chaining purposes
 
1945
 */
 
1946
jQuery.fn.PMA_sort_table = function(text_selector) {
 
1947
    return this.each(function() {
 
1948
 
 
1949
        /**
 
1950
         * @var table_body  Object referring to the table's <tbody> element
 
1951
         */
 
1952
        var table_body = $(this);
 
1953
        /**
 
1954
         * @var rows    Object referring to the collection of rows in {@link table_body}
 
1955
         */
 
1956
        var rows = $(this).find('tr').get();
 
1957
 
 
1958
        //get the text of the field that we will sort by
 
1959
        $.each(rows, function(index, row) {
 
1960
            row.sortKey = $.trim($(row).find(text_selector).text().toLowerCase());
 
1961
        });
 
1962
 
 
1963
        //get the sorted order
 
1964
        rows.sort(function(a, b) {
 
1965
            if (a.sortKey < b.sortKey) {
 
1966
                return -1;
 
1967
            }
 
1968
            if (a.sortKey > b.sortKey) {
 
1969
                return 1;
 
1970
            }
 
1971
            return 0;
 
1972
        });
 
1973
 
 
1974
        //pull out each row from the table and then append it according to it's order
 
1975
        $.each(rows, function(index, row) {
 
1976
            $(table_body).append(row);
 
1977
            row.sortKey = null;
 
1978
        });
 
1979
 
 
1980
        //Re-check the classes of each row
 
1981
        $(this).find('tr:odd')
 
1982
        .removeClass('even').addClass('odd')
 
1983
        .end()
 
1984
        .find('tr:even')
 
1985
        .removeClass('odd').addClass('even');
 
1986
    });
 
1987
};
 
1988
 
 
1989
/**
 
1990
 * Unbind all event handlers before tearing down a page
 
1991
 */
 
1992
AJAX.registerTeardown('functions.js', function() {
 
1993
    $("#create_table_form_minimal.ajax").die('submit');
 
1994
    $("form.create_table_form.ajax").die('submit');
 
1995
    $("form.create_table_form.ajax input[name=submit_num_fields]").die('click');
 
1996
    $("form.create_table_form.ajax input").die('keyup');
 
1997
});
 
1998
 
 
1999
/**
 
2000
 * jQuery coding for 'Create Table'.  Used on db_operations.php,
 
2001
 * db_structure.php and db_tracking.php (i.e., wherever
 
2002
 * libraries/display_create_table.lib.php is used)
 
2003
 *
 
2004
 * Attach Ajax Event handlers for Create Table
 
2005
 */
 
2006
AJAX.registerOnload('functions.js', function() {
 
2007
    /**
 
2008
     * Attach event handler for submission of create table form (save)
 
2009
     */
 
2010
    $("form.create_table_form.ajax").live('submit', function(event) {
 
2011
        event.preventDefault();
 
2012
 
 
2013
        /**
 
2014
         * @var    the_form    object referring to the create table form
 
2015
         */
 
2016
        var $form = $(this);
 
2017
 
 
2018
        /*
 
2019
         * First validate the form; if there is a problem, avoid submitting it
 
2020
         *
 
2021
         * checkTableEditForm() needs a pure element and not a jQuery object,
 
2022
         * this is why we pass $form[0] as a parameter (the jQuery object
 
2023
         * is actually an array of DOM elements)
 
2024
         */
 
2025
 
 
2026
        if (checkTableEditForm($form[0], $form.find('input[name=orig_num_fields]').val())) {
 
2027
            PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']);
 
2028
            PMA_prepareForAjaxRequest($form);
 
2029
            //User wants to submit the form
 
2030
            $.post($form.attr('action'), $form.serialize() + "&do_save_data=1", function(data) {
 
2031
                if (data.success == true) {
 
2032
                    $('#properties_message')
 
2033
                     .removeClass('error')
 
2034
                     .html('');
 
2035
                    PMA_ajaxShowMessage(data.message);
 
2036
                    // Only if the create table dialog (distinct panel) exists
 
2037
                    if ($("#create_table_dialog").length > 0) {
 
2038
                        $("#create_table_dialog").dialog("close").remove();
 
2039
                    }
 
2040
                    $('#tableslistcontainer').before(data.formatted_sql);
 
2041
 
 
2042
                    /**
 
2043
                     * @var tables_table    Object referring to the <tbody> element that holds the list of tables
 
2044
                     */
 
2045
                    var tables_table = $("#tablesForm").find("tbody").not("#tbl_summary_row");
 
2046
                    // this is the first table created in this db
 
2047
                    if (tables_table.length == 0) {
 
2048
                        PMA_commonActions.refreshMain(
 
2049
                            PMA_commonParams.get('opendb_url')
 
2050
                        );
 
2051
                    } else {
 
2052
                        /**
 
2053
                         * @var curr_last_row   Object referring to the last <tr> element in {@link tables_table}
 
2054
                         */
 
2055
                        var curr_last_row = $(tables_table).find('tr:last');
 
2056
                        /**
 
2057
                         * @var curr_last_row_index_string   String containing the index of {@link curr_last_row}
 
2058
                         */
 
2059
                        var curr_last_row_index_string = $(curr_last_row).find('input:checkbox').attr('id').match(/\d+/)[0];
 
2060
                        /**
 
2061
                         * @var curr_last_row_index Index of {@link curr_last_row}
 
2062
                         */
 
2063
                        var curr_last_row_index = parseFloat(curr_last_row_index_string);
 
2064
                        /**
 
2065
                         * @var new_last_row_index   Index of the new row to be appended to {@link tables_table}
 
2066
                         */
 
2067
                        var new_last_row_index = curr_last_row_index + 1;
 
2068
                        /**
 
2069
                         * @var new_last_row_id String containing the id of the row to be appended to {@link tables_table}
 
2070
                         */
 
2071
                        var new_last_row_id = 'checkbox_tbl_' + new_last_row_index;
 
2072
 
 
2073
                        data.new_table_string = data.new_table_string.replace(/checkbox_tbl_/, new_last_row_id);
 
2074
                        //append to table
 
2075
                        $(data.new_table_string)
 
2076
                         .appendTo(tables_table);
 
2077
 
 
2078
                        //Sort the table
 
2079
                        $(tables_table).PMA_sort_table('th');
 
2080
 
 
2081
                        // Adjust summary row
 
2082
                        PMA_adjustTotals();
 
2083
                    }
 
2084
 
 
2085
                    //Refresh navigation as a new table has been added
 
2086
                    PMA_reloadNavigation();
 
2087
                } else {
 
2088
                    PMA_ajaxShowMessage(
 
2089
                        '<div class="error">' + data.error + '</div>',
 
2090
                        false
 
2091
                    );
 
2092
                }
 
2093
            }); // end $.post()
 
2094
        } // end if (checkTableEditForm() )
 
2095
    }); // end create table form (save)
 
2096
 
 
2097
    /**
 
2098
     * Attach event handler for create table form (add fields)
 
2099
     */
 
2100
    $("form.create_table_form.ajax input[name=submit_num_fields]").live('click', function(event) {
 
2101
        event.preventDefault();
 
2102
        /**
 
2103
         * @var    the_form    object referring to the create table form
 
2104
         */
 
2105
        var $form = $(this).closest('form');
 
2106
 
 
2107
        var $msgbox = PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']);
 
2108
        PMA_prepareForAjaxRequest($form);
 
2109
 
 
2110
        //User wants to add more fields to the table
 
2111
        $.post($form.attr('action'), $form.serialize() + "&submit_num_fields=1", function(data) {
 
2112
            if (data.success) {
 
2113
                $("#page_content").html(data.message);
 
2114
                PMA_verifyColumnsProperties();
 
2115
                PMA_ajaxRemoveMessage($msgbox);
 
2116
            } else {
 
2117
                PMA_ajaxShowMessage(data.error);
 
2118
            }
 
2119
        }); //end $.post()
 
2120
    }); // end create table form (add fields)
 
2121
 
 
2122
    $("form.create_table_form.ajax input").live('keydown', function (event) {
 
2123
        if (event.keyCode == 13) {
 
2124
            event.preventDefault();
 
2125
            event.stopImmediatePropagation();
 
2126
            $(this)
 
2127
                .closest('form')
 
2128
                .append('<input type="hidden" name="do_save_data" value="1" />')
 
2129
                .submit();
 
2130
        }
 
2131
    });
 
2132
});
 
2133
 
 
2134
 
 
2135
/**
 
2136
 * Unbind all event handlers before tearing down a page
 
2137
 */
 
2138
AJAX.registerTeardown('functions.js', function() {
 
2139
    $("#copyTable.ajax").die('submit');
 
2140
    $("#moveTableForm").die('submit');
 
2141
    $("#tableOptionsForm").die('submit');
 
2142
    $("#tbl_maintenance li a.maintain_action.ajax").die('click');
 
2143
});
 
2144
/**
 
2145
 * jQuery coding for 'Table operations'.  Used on tbl_operations.php
 
2146
 * Attach Ajax Event handlers for Table operations
 
2147
 */
 
2148
AJAX.registerOnload('functions.js', function() {
 
2149
    /**
 
2150
     *Ajax action for submitting the "Copy table"
 
2151
    **/
 
2152
    $("#copyTable.ajax").live('submit', function(event) {
 
2153
        event.preventDefault();
 
2154
        var $form = $(this);
 
2155
        PMA_prepareForAjaxRequest($form);
 
2156
        $.post($form.attr('action'), $form.serialize()+"&submit_copy=Go", function(data) {
 
2157
            if (data.success == true) {
 
2158
                if ($form.find("input[name='switch_to_new']").prop('checked')) {
 
2159
                    PMA_commonParams.set(
 
2160
                        'db',
 
2161
                        data.db
 
2162
                    );
 
2163
                    PMA_commonParams.set(
 
2164
                        'table',
 
2165
                        $form.find("input[name='new_name']").val()
 
2166
                    );
 
2167
                    PMA_commonActions.refreshMain(false, function () {
 
2168
                        PMA_ajaxShowMessage(data.message);
 
2169
                    });
 
2170
                } else {
 
2171
                    PMA_ajaxShowMessage(data.message);
 
2172
                }
 
2173
                // Refresh navigation when the table is copied
 
2174
                PMA_reloadNavigation();
 
2175
            } else {
 
2176
                PMA_ajaxShowMessage(data.error, false);
 
2177
            }
 
2178
        }); // end $.post()
 
2179
    });//end of copyTable ajax submit
 
2180
 
 
2181
    /**
 
2182
     *Ajax action for submitting the "Move table"
 
2183
     */
 
2184
    $("#moveTableForm").live('submit', function(event) {
 
2185
        event.preventDefault();
 
2186
        var $form = $(this);
 
2187
        var db = $form.find('select[name=target_db]').val();
 
2188
        var tbl = $form.find('input[name=new_name]').val();
 
2189
        PMA_prepareForAjaxRequest($form);
 
2190
        $.post($form.attr('action'), $form.serialize()+"&submit_move=1", function(data) {
 
2191
            if (data.success == true) {
 
2192
                PMA_commonParams.set('db', db);
 
2193
                PMA_commonParams.set('table', tbl);
 
2194
                PMA_commonActions.refreshMain(false, function () {
 
2195
                    PMA_ajaxShowMessage(data.message);
 
2196
                });
 
2197
                // Refresh navigation when the table is copied
 
2198
                PMA_reloadNavigation();
 
2199
            } else {
 
2200
                PMA_ajaxShowMessage(data.error, false);
 
2201
            }
 
2202
        }); // end $.post()
 
2203
    });
 
2204
 
 
2205
    /**
 
2206
     * Ajax action for submitting the "Table options"
 
2207
     */
 
2208
    $("#tableOptionsForm").live('submit', function(event) {
 
2209
        event.preventDefault();
 
2210
        event.stopPropagation();
 
2211
        var $form = $(this);
 
2212
        var $tblNameField = $form.find('input[name=new_name]');
 
2213
        if ($tblNameField.val() !== $tblNameField[0].defaultValue) {
 
2214
            // reload page and navigation if the table has been renamed
 
2215
            PMA_prepareForAjaxRequest($form);
 
2216
            var tbl = $tblNameField.val();
 
2217
            $.post($form.attr('action'), $form.serialize(), function(data) {
 
2218
                if (data.success == true) {
 
2219
                    PMA_commonParams.set('table', tbl);
 
2220
                    PMA_commonActions.refreshMain(false, function() {
 
2221
                        $('#page_content').html(data.message);
 
2222
                    });
 
2223
                } else {
 
2224
                    PMA_ajaxShowMessage(data.error, false);
 
2225
                }
 
2226
            }); // end $.post()
 
2227
        } else {
 
2228
            $form.removeClass('ajax').submit().addClass('ajax');
 
2229
        }
 
2230
    });
 
2231
 
 
2232
    /**
 
2233
     *Ajax events for actions in the "Table maintenance"
 
2234
    **/
 
2235
    $("#tbl_maintenance li a.maintain_action.ajax").live('click', function(event) {
 
2236
        event.preventDefault();
 
2237
        if ($("#sqlqueryresults").length != 0) {
 
2238
            $("#sqlqueryresults").remove();
 
2239
        }
 
2240
        if ($("#result_query").length != 0) {
 
2241
            $("#result_query").remove();
 
2242
        }
 
2243
        //variables which stores the common attributes
 
2244
        $.post($(this).attr('href'), { ajax_request: 1 }, function(data) {
 
2245
            function scrollToTop() {
 
2246
                $('html, body').animate({ scrollTop: 0 });
 
2247
            }
 
2248
            if (data.success == true && data.sql_query != undefined) {
 
2249
                PMA_ajaxShowMessage(data.message);
 
2250
                $("<div id='sqlqueryresults' class='ajax'></div>").prependTo("#page_content");
 
2251
                $("#sqlqueryresults").html(data.sql_query);
 
2252
                scrollToTop();
 
2253
            } else if (data.success == true) {
 
2254
                var $temp_div = $("<div id='temp_div'></div>");
 
2255
                $temp_div.html(data.message);
 
2256
                var $success = $temp_div.find("#result_query .success");
 
2257
                PMA_ajaxShowMessage($success);
 
2258
                $("<div id='sqlqueryresults' class='ajax'></div>").prependTo("#page_content");
 
2259
                $("#sqlqueryresults").html(data.message);
 
2260
                PMA_init_slider();
 
2261
                $("#sqlqueryresults").children("fieldset,br").remove();
 
2262
                scrollToTop();
 
2263
            } else {
 
2264
                var $temp_div = $("<div id='temp_div'></div>");
 
2265
                $temp_div.html(data.error);
 
2266
                var $error = $temp_div.find("code").addClass("error");
 
2267
                PMA_ajaxShowMessage($error, false);
 
2268
            }
 
2269
        }); // end $.post()
 
2270
    });//end of table maintanance ajax click
 
2271
}); //end $(document).ready for 'Table operations'
 
2272
 
 
2273
/**
 
2274
 * Unbind all event handlers before tearing down a page
 
2275
 */
 
2276
AJAX.registerTeardown('functions.js', function() {
 
2277
    $("#drop_db_anchor.ajax").die('click');
 
2278
});
 
2279
/**
 
2280
 * Attach Ajax event handlers for Drop Database. Moved here from db_structure.js
 
2281
 * as it was also required on db_create.php
 
2282
 */
 
2283
AJAX.registerOnload('functions.js', function() {
 
2284
    $("#drop_db_anchor.ajax").live('click', function(event) {
 
2285
        event.preventDefault();
 
2286
        /**
 
2287
         * @var question    String containing the question to be asked for confirmation
 
2288
         */
 
2289
        var question = PMA_messages.strDropDatabaseStrongWarning + ' ';
 
2290
        question += $.sprintf(
 
2291
            PMA_messages.strDoYouReally,
 
2292
            'DROP DATABASE ' + escapeHtml(PMA_commonParams.get('db'))
 
2293
        );
 
2294
        $(this).PMA_confirm(question, $(this).attr('href'), function(url) {
 
2295
            PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']);
 
2296
            $.get(url, {'is_js_confirmed': '1', 'ajax_request': true}, function(data) {
 
2297
                if (data.success) {
 
2298
                    //Database deleted successfully, refresh both the frames
 
2299
                    PMA_reloadNavigation();
 
2300
                    PMA_commonParams.set('db', '');
 
2301
                    PMA_commonActions.refreshMain(
 
2302
                        'server_databases.php',
 
2303
                        function () {
 
2304
                            PMA_ajaxShowMessage(data.message);
 
2305
                        }
 
2306
                    );
 
2307
                } else {
 
2308
                    PMA_ajaxShowMessage(data.error, false);
 
2309
                }
 
2310
            });
 
2311
        });
 
2312
    });
 
2313
}); // end of $() for Drop Database
 
2314
 
 
2315
/**
 
2316
 * Validates the password field in a form
 
2317
 *
 
2318
 * @see    PMA_messages['strPasswordEmpty']
 
2319
 * @see    PMA_messages['strPasswordNotSame']
 
2320
 * @param  object $the_form The form to be validated
 
2321
 * @return bool
 
2322
 */
 
2323
function PMA_checkPassword($the_form)
 
2324
{
 
2325
    // Did the user select 'no password'?
 
2326
    if ($the_form.find('#nopass_1').is(':checked')) {
 
2327
        return true;
 
2328
    } else {
 
2329
        var $pred = $the_form.find('#select_pred_password');
 
2330
        if ($pred.length && ($pred.val() == 'none' || $pred.val() == 'keep')) {
 
2331
            return true;
 
2332
        }
 
2333
    }
 
2334
 
 
2335
    var $password = $the_form.find('input[name=pma_pw]');
 
2336
    var $password_repeat = $the_form.find('input[name=pma_pw2]');
 
2337
    var alert_msg = false;
 
2338
 
 
2339
    if ($password.val() == '') {
 
2340
        alert_msg = PMA_messages['strPasswordEmpty'];
 
2341
    } else if ($password.val() != $password_repeat.val()) {
 
2342
        alert_msg = PMA_messages['strPasswordNotSame'];
 
2343
    }
 
2344
 
 
2345
    if (alert_msg) {
 
2346
        alert(alert_msg);
 
2347
        $password.val('');
 
2348
        $password_repeat.val('');
 
2349
        $password.focus();
 
2350
         return false;
 
2351
    }
 
2352
    return true;
 
2353
}
 
2354
 
 
2355
/**
 
2356
 * Unbind all event handlers before tearing down a page
 
2357
 */
 
2358
AJAX.registerTeardown('functions.js', function() {
 
2359
    $('#change_password_anchor.ajax').die('click');
 
2360
});
 
2361
/**
 
2362
 * Attach Ajax event handlers for 'Change Password' on index.php
 
2363
 */
 
2364
AJAX.registerOnload('functions.js', function() {
 
2365
 
 
2366
    /**
 
2367
     * Attach Ajax event handler on the change password anchor
 
2368
     */
 
2369
    $('#change_password_anchor.ajax').live('click', function(event) {
 
2370
        event.preventDefault();
 
2371
 
 
2372
        var $msgbox = PMA_ajaxShowMessage();
 
2373
 
 
2374
        /**
 
2375
         * @var button_options  Object containing options to be passed to jQueryUI's dialog
 
2376
         */
 
2377
        var button_options = {};
 
2378
        button_options[PMA_messages['strGo']] = function() {
 
2379
 
 
2380
            event.preventDefault();
 
2381
 
 
2382
            /**
 
2383
             * @var $the_form    Object referring to the change password form
 
2384
             */
 
2385
            var $the_form = $("#change_password_form");
 
2386
 
 
2387
            if (! PMA_checkPassword($the_form)) {
 
2388
                return false;
 
2389
            }
 
2390
 
 
2391
            /**
 
2392
             * @var this_value  String containing the value of the submit button.
 
2393
             * Need to append this for the change password form on Server Privileges
 
2394
             * page to work
 
2395
             */
 
2396
            var this_value = $(this).val();
 
2397
 
 
2398
            var $msgbox = PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']);
 
2399
            $the_form.append('<input type="hidden" name="ajax_request" value="true" />');
 
2400
 
 
2401
            $.post($the_form.attr('action'), $the_form.serialize() + '&change_pw='+ this_value, function(data) {
 
2402
                if (data.success == true) {
 
2403
                    $("#page_content").prepend(data.message);
 
2404
                    $("#change_password_dialog").hide().remove();
 
2405
                    $("#edit_user_dialog").dialog("close").remove();
 
2406
                    PMA_ajaxRemoveMessage($msgbox);
 
2407
                }
 
2408
                else {
 
2409
                    PMA_ajaxShowMessage(data.error, false);
 
2410
                }
 
2411
            }); // end $.post()
 
2412
        };
 
2413
 
 
2414
        button_options[PMA_messages['strCancel']] = function() {
 
2415
            $(this).dialog('close');
 
2416
        };
 
2417
        $.get($(this).attr('href'), {'ajax_request': true}, function(data) {
 
2418
            if (data.success) {
 
2419
                $('<div id="change_password_dialog"></div>')
 
2420
                .dialog({
 
2421
                    title: PMA_messages['strChangePassword'],
 
2422
                    width: 600,
 
2423
                    close: function(ev, ui) {
 
2424
                        $(this).remove();
 
2425
                    },
 
2426
                    buttons : button_options,
 
2427
                    modal: true
 
2428
                })
 
2429
                .append(data.message);
 
2430
                // for this dialog, we remove the fieldset wrapping due to double headings
 
2431
                $("fieldset#fieldset_change_password")
 
2432
                .find("legend").remove().end()
 
2433
                .find("table.noclick").unwrap().addClass("some-margin")
 
2434
                .find("input#text_pma_pw").focus();
 
2435
                displayPasswordGenerateButton();
 
2436
                $('#fieldset_change_password_footer').hide();
 
2437
                PMA_ajaxRemoveMessage($msgbox);
 
2438
                $('#change_password_form').bind('submit', function (e) {
 
2439
                    e.preventDefault();
 
2440
                    $(this)
 
2441
                        .closest('.ui-dialog')
 
2442
                        .find('.ui-dialog-buttonpane .ui-button')
 
2443
                        .first()
 
2444
                        .click();
 
2445
                });
 
2446
            } else {
 
2447
                PMA_ajaxShowMessage(data.error, false);
 
2448
            }
 
2449
        }); // end $.get()
 
2450
    }); // end handler for change password anchor
 
2451
}); // end $() for Change Password
 
2452
 
 
2453
/**
 
2454
 * Unbind all event handlers before tearing down a page
 
2455
 */
 
2456
AJAX.registerTeardown('functions.js', function() {
 
2457
    $("select.column_type").die('change');
 
2458
    $("select.default_type").die('change');
 
2459
    $('input.allow_null').die('change');
 
2460
});
 
2461
/**
 
2462
 * Toggle the hiding/showing of the "Open in ENUM/SET editor" message when
 
2463
 * the page loads and when the selected data type changes
 
2464
 */
 
2465
AJAX.registerOnload('functions.js', function() {
 
2466
    // is called here for normal page loads and also when opening
 
2467
    // the Create table dialog
 
2468
    PMA_verifyColumnsProperties();
 
2469
    //
 
2470
    // needs live() to work also in the Create Table dialog
 
2471
    $("select.column_type").live('change', function() {
 
2472
        PMA_showNoticeForEnum($(this));
 
2473
    });
 
2474
    $("select.default_type").live('change', function() {
 
2475
        PMA_hideShowDefaultValue($(this));
 
2476
    });
 
2477
    $('input.allow_null').live('change', function() {
 
2478
        PMA_validateDefaultValue($(this));
 
2479
    });
 
2480
});
 
2481
 
 
2482
function PMA_verifyColumnsProperties()
 
2483
{
 
2484
    $("select.column_type").each(function() {
 
2485
        PMA_showNoticeForEnum($(this));
 
2486
    });
 
2487
    $("select.default_type").each(function() {
 
2488
        PMA_hideShowDefaultValue($(this));
 
2489
    });
 
2490
}
 
2491
 
 
2492
/**
 
2493
 * Hides/shows the default value input field, depending on the default type
 
2494
 * Ticks the NULL checkbox if NULL is chosen as default value.
 
2495
 */
 
2496
function PMA_hideShowDefaultValue($default_type)
 
2497
{
 
2498
    if ($default_type.val() == 'USER_DEFINED') {
 
2499
        $default_type.siblings('.default_value').show().focus();
 
2500
    } else {
 
2501
        $default_type.siblings('.default_value').hide();
 
2502
        if ($default_type.val() == 'NULL') {
 
2503
            var $null_checkbox = $default_type.closest('tr').find('.allow_null');
 
2504
            $null_checkbox.prop('checked', true);
 
2505
        }
 
2506
    }
 
2507
}
 
2508
 
 
2509
/**
 
2510
 * If the column does not allow NULL values, makes sure that default is not NULL
 
2511
 */
 
2512
function PMA_validateDefaultValue($null_checkbox)
 
2513
{
 
2514
    if (! $null_checkbox.prop('checked')) {
 
2515
        var $default = $null_checkbox.closest('tr').find('.default_type');
 
2516
        if ($default.val() == 'NULL') {
 
2517
            $default.val('NONE');
 
2518
        }
 
2519
    }
 
2520
}
 
2521
 
 
2522
 
 
2523
/**
 
2524
 * Unbind all event handlers before tearing down a page
 
2525
 */
 
2526
AJAX.registerTeardown('functions.js', function() {
 
2527
    $("a.open_enum_editor").die('click');
 
2528
    $("input.add_value").die('click');
 
2529
    $("#enum_editor td.drop").die('click');
 
2530
});
 
2531
/**
 
2532
 * @var $enum_editor_dialog An object that points to the jQuery
 
2533
 *                          dialog of the ENUM/SET editor
 
2534
 */
 
2535
var $enum_editor_dialog = null;
 
2536
/**
 
2537
 * Opens the ENUM/SET editor and controls its functions
 
2538
 */
 
2539
AJAX.registerOnload('functions.js', function() {
 
2540
    $("a.open_enum_editor").live('click', function() {
 
2541
        // Get the name of the column that is being edited
 
2542
        var colname = $(this).closest('tr').find('input:first').val();
 
2543
        // And use it to make up a title for the page
 
2544
        if (colname.length < 1) {
 
2545
            var title = PMA_messages['enum_newColumnVals'];
 
2546
        } else {
 
2547
            var title = PMA_messages['enum_columnVals'].replace(
 
2548
                /%s/,
 
2549
                '"' + decodeURIComponent(colname) + '"'
 
2550
            );
 
2551
        }
 
2552
        // Get the values as a string
 
2553
        var inputstring = $(this)
 
2554
            .closest('td')
 
2555
            .find("input")
 
2556
            .val();
 
2557
        // Escape html entities
 
2558
        inputstring = $('<div/>')
 
2559
            .text(inputstring)
 
2560
            .html();
 
2561
        // Parse the values, escaping quotes and
 
2562
        // slashes on the fly, into an array
 
2563
        var values = [];
 
2564
        var in_string = false;
 
2565
        var curr, next, buffer = '';
 
2566
        for (var i=0; i<inputstring.length; i++) {
 
2567
            curr = inputstring.charAt(i);
 
2568
            next = i == inputstring.length ? '' : inputstring.charAt(i+1);
 
2569
            if (! in_string && curr == "'") {
 
2570
                in_string = true;
 
2571
            } else if (in_string && curr == "\\" && next == "\\") {
 
2572
                buffer += "&#92;";
 
2573
                i++;
 
2574
            } else if (in_string && next == "'" && (curr == "'" || curr == "\\")) {
 
2575
                buffer += "&#39;";
 
2576
                i++;
 
2577
            } else if (in_string && curr == "'") {
 
2578
                in_string = false;
 
2579
                values.push(buffer);
 
2580
                buffer = '';
 
2581
            } else if (in_string) {
 
2582
                 buffer += curr;
 
2583
            }
 
2584
        }
 
2585
        if (buffer.length > 0) {
 
2586
            // The leftovers in the buffer are the last value (if any)
 
2587
            values.push(buffer);
 
2588
        }
 
2589
        var fields = '';
 
2590
        // If there are no values, maybe the user is about to make a
 
2591
        // new list so we add a few for him/her to get started with.
 
2592
        if (values.length == 0) {
 
2593
            values.push('','','','');
 
2594
        }
 
2595
        // Add the parsed values to the editor
 
2596
        var drop_icon = PMA_getImage('b_drop.png');
 
2597
        for (var i=0; i<values.length; i++) {
 
2598
            fields += "<tr><td>"
 
2599
                   + "<input type='text' value='" + values[i] + "'/>"
 
2600
                   + "</td><td class='drop'>"
 
2601
                   + drop_icon
 
2602
                   + "</td></tr>";
 
2603
        }
 
2604
        /**
 
2605
         * @var dialog HTML code for the ENUM/SET dialog
 
2606
         */
 
2607
        var dialog = "<div id='enum_editor'>"
 
2608
                   + "<fieldset>"
 
2609
                   + "<legend>" + title + "</legend>"
 
2610
                   + "<p>" + PMA_getImage('s_notice.png')
 
2611
                   + PMA_messages['enum_hint'] + "</p>"
 
2612
                   + "<table class='values'>" + fields + "</table>"
 
2613
                   + "</fieldset><fieldset class='tblFooters'>"
 
2614
                   + "<table class='add'><tr><td>"
 
2615
                   + "<div class='slider'></div>"
 
2616
                   + "</td><td>"
 
2617
                   + "<form><div><input type='submit' class='add_value' value='"
 
2618
                   + $.sprintf(PMA_messages['enum_addValue'], 1)
 
2619
                   + "'/></div></form>"
 
2620
                   + "</td></tr></table>"
 
2621
                   + "<input type='hidden' value='" // So we know which column's data is being edited
 
2622
                   + $(this).closest('td').find("input").attr("id")
 
2623
                   + "' />"
 
2624
                   + "</fieldset>"
 
2625
                   + "</div>";
 
2626
        /**
 
2627
         * @var  Defines functions to be called when the buttons in
 
2628
         * the buttonOptions jQuery dialog bar are pressed
 
2629
         */
 
2630
        var buttonOptions = {};
 
2631
        buttonOptions[PMA_messages['strGo']] = function () {
 
2632
            // When the submit button is clicked,
 
2633
            // put the data back into the original form
 
2634
            var value_array = [];
 
2635
            $(this).find(".values input").each(function(index, elm) {
 
2636
                var val = elm.value.replace(/\\/g, '\\\\').replace(/'/g, "''");
 
2637
                value_array.push("'" + val + "'");
 
2638
            });
 
2639
            // get the Length/Values text field where this value belongs
 
2640
            var values_id = $(this).find("input[type='hidden']").val();
 
2641
            $("input#" + values_id).val(value_array.join(","));
 
2642
            $(this).dialog("close");
 
2643
        };
 
2644
        buttonOptions[PMA_messages['strClose']] = function () {
 
2645
            $(this).dialog("close");
 
2646
        };
 
2647
        // Show the dialog
 
2648
        var width = parseInt(
 
2649
            (parseInt($('html').css('font-size'), 10)/13)*340,
 
2650
            10
 
2651
        );
 
2652
        if (! width) {
 
2653
            width = 340;
 
2654
        }
 
2655
        $enum_editor_dialog = $(dialog).dialog({
 
2656
            minWidth: width,
 
2657
            modal: true,
 
2658
            title: PMA_messages['enum_editor'],
 
2659
            buttons: buttonOptions,
 
2660
            open: function() {
 
2661
                // Focus the "Go" button after opening the dialog
 
2662
                $(this).closest('.ui-dialog').find('.ui-dialog-buttonpane button:first').focus();
 
2663
            },
 
2664
            close: function() {
 
2665
                $(this).remove();
 
2666
            }
 
2667
        });
 
2668
        // slider for choosing how many fields to add
 
2669
        $enum_editor_dialog.find(".slider").slider({
 
2670
            animate: true,
 
2671
            range: "min",
 
2672
            value: 1,
 
2673
            min: 1,
 
2674
            max: 9,
 
2675
            slide: function( event, ui ) {
 
2676
                $(this).closest('table').find('input[type=submit]').val(
 
2677
                    $.sprintf(PMA_messages['enum_addValue'], ui.value)
 
2678
                );
 
2679
            }
 
2680
        });
 
2681
        // Focus the slider, otherwise it looks nearly transparent
 
2682
        $('a.ui-slider-handle').addClass('ui-state-focus');
 
2683
        return false;
 
2684
    });
 
2685
 
 
2686
    // When "add a new value" is clicked, append an empty text field
 
2687
    $("input.add_value").live('click', function(e) {
 
2688
        e.preventDefault();
 
2689
        var num_new_rows = $enum_editor_dialog.find("div.slider").slider('value');
 
2690
        while (num_new_rows--) {
 
2691
            $enum_editor_dialog.find('.values')
 
2692
                .append(
 
2693
                    "<tr style='display: none;'><td>"
 
2694
                  + "<input type='text' />"
 
2695
                  + "</td><td class='drop'>"
 
2696
                  + PMA_getImage('b_drop.png')
 
2697
                  + "</td></tr>"
 
2698
                )
 
2699
                .find('tr:last')
 
2700
                .show('fast');
 
2701
        }
 
2702
    });
 
2703
 
 
2704
    // Removes the specified row from the enum editor
 
2705
    $("#enum_editor td.drop").live('click', function() {
 
2706
        $(this).closest('tr').hide('fast', function () {
 
2707
            $(this).remove();
 
2708
        });
 
2709
    });
 
2710
});
 
2711
 
 
2712
/**
 
2713
 * Ensures indexes names are valid according to their type and, for a primary
 
2714
 * key, lock index name to 'PRIMARY'
 
2715
 * @param string   form_id  Variable which parses the form name as
 
2716
 *                            the input
 
2717
 * @return boolean  false    if there is no index form, true else
 
2718
 */
 
2719
function checkIndexName(form_id)
 
2720
{
 
2721
    if ($("#"+form_id).length == 0) {
 
2722
        return false;
 
2723
    }
 
2724
 
 
2725
    // Gets the elements pointers
 
2726
    var $the_idx_name = $("#input_index_name");
 
2727
    var $the_idx_type = $("#select_index_type");
 
2728
 
 
2729
    // Index is a primary key
 
2730
    if ($the_idx_type.find("option:selected").val() == 'PRIMARY') {
 
2731
        $the_idx_name.val('PRIMARY');
 
2732
        $the_idx_name.prop("disabled", true);
 
2733
    }
 
2734
 
 
2735
    // Other cases
 
2736
    else {
 
2737
        if ($the_idx_name.val() == 'PRIMARY') {
 
2738
            $the_idx_name.val("");
 
2739
        }
 
2740
        $the_idx_name.prop("disabled", false);
 
2741
    }
 
2742
 
 
2743
    return true;
 
2744
} // end of the 'checkIndexName()' function
 
2745
 
 
2746
AJAX.registerTeardown('functions.js', function() {
 
2747
    $('#index_frm input[type=submit]').die('click');
 
2748
});
 
2749
AJAX.registerOnload('functions.js', function() {
 
2750
    /**
 
2751
     * Handler for adding more columns to an index in the editor
 
2752
     */
 
2753
    $('#index_frm input[type=submit]').live('click', function(event) {
 
2754
        event.preventDefault();
 
2755
        var rows_to_add = $(this)
 
2756
            .closest('fieldset')
 
2757
            .find('.slider')
 
2758
            .slider('value');
 
2759
        while (rows_to_add--) {
 
2760
            var $newrow = $('#index_columns')
 
2761
                .find('tbody > tr:first')
 
2762
                .clone()
 
2763
                .appendTo(
 
2764
                    $('#index_columns').find('tbody')
 
2765
                );
 
2766
            $newrow.find(':input').each(function() {
 
2767
                $(this).val('');
 
2768
            });
 
2769
            // focus index size input on column picked
 
2770
            $newrow.find('select').change(function() {
 
2771
                if ($(this).find("option:selected").val() == '') {
 
2772
                    return true;
 
2773
                }
 
2774
                $(this).closest("tr").find("input").focus();
 
2775
            });
 
2776
        }
 
2777
    });
 
2778
});
 
2779
 
 
2780
function indexEditorDialog(url, title, callback_success, callback_failure)
 
2781
{
 
2782
    /*Remove the hidden dialogs if there are*/
 
2783
    if ($('#edit_index_dialog').length != 0) {
 
2784
        $('#edit_index_dialog').remove();
 
2785
    }
 
2786
    var $div = $('<div id="edit_index_dialog"></div>');
 
2787
 
 
2788
    /**
 
2789
     * @var button_options Object that stores the options
 
2790
     *                     passed to jQueryUI dialog
 
2791
     */
 
2792
    var button_options = {};
 
2793
    button_options[PMA_messages['strGo']] = function() {
 
2794
        /**
 
2795
         * @var    the_form    object referring to the export form
 
2796
         */
 
2797
        var $form = $("#index_frm");
 
2798
        PMA_prepareForAjaxRequest($form);
 
2799
        //User wants to submit the form
 
2800
        $.post($form.attr('action'), $form.serialize()+"&do_save_data=1", function(data) {
 
2801
            if ($("#sqlqueryresults").length != 0) {
 
2802
                $("#sqlqueryresults").remove();
 
2803
            }
 
2804
            if (data.success == true) {
 
2805
                PMA_ajaxShowMessage(data.message);
 
2806
                if ($('#result_query').length) {
 
2807
                    $('#result_query').remove();
 
2808
                }
 
2809
                if (data.sql_query) {
 
2810
                    $('<div id="result_query"></div>')
 
2811
                        .html(data.sql_query)
 
2812
                        .prependTo('#page_content');
 
2813
                }
 
2814
                $("#result_query .notice").remove();
 
2815
                $("#result_query").prepend(data.message);
 
2816
                /*Reload the field form*/
 
2817
                $("#table_index").remove();
 
2818
                var $temp_div = $("<div id='temp_div'><div>").append(data.index_table);
 
2819
                $temp_div.find("#table_index").insertAfter("#index_header");
 
2820
                if ($("#edit_index_dialog").length > 0) {
 
2821
                    $("#edit_index_dialog").dialog("close");
 
2822
                }
 
2823
                $('div.no_indexes_defined').hide();
 
2824
                if (callback_success) {
 
2825
                    callback_success();
 
2826
                }
 
2827
                PMA_reloadNavigation();
 
2828
            } else {
 
2829
                var $temp_div = $("<div id='temp_div'><div>").append(data.error);
 
2830
                if ($temp_div.find(".error code").length != 0) {
 
2831
                    var $error = $temp_div.find(".error code").addClass("error");
 
2832
                } else {
 
2833
                    var $error = $temp_div;
 
2834
                }
 
2835
                if (callback_failure) {
 
2836
                    callback_failure();
 
2837
                }
 
2838
                PMA_ajaxShowMessage($error, false);
 
2839
            }
 
2840
        }); // end $.post()
 
2841
    };
 
2842
    button_options[PMA_messages['strCancel']] = function() {
 
2843
        $(this).dialog('close');
 
2844
    };
 
2845
    var $msgbox = PMA_ajaxShowMessage();
 
2846
    $.get("tbl_indexes.php", url, function(data) {
 
2847
        if (data.success == false) {
 
2848
            //in the case of an error, show the error message returned.
 
2849
            PMA_ajaxShowMessage(data.error, false);
 
2850
        } else {
 
2851
            PMA_ajaxRemoveMessage($msgbox);
 
2852
            // Show dialog if the request was successful
 
2853
            $div
 
2854
            .append(data.message)
 
2855
            .dialog({
 
2856
                title: title,
 
2857
                width: 450,
 
2858
                open: PMA_verifyColumnsProperties,
 
2859
                modal: true,
 
2860
                buttons: button_options,
 
2861
                close: function () {
 
2862
                    $(this).remove();
 
2863
                }
 
2864
            });
 
2865
            checkIndexType();
 
2866
            checkIndexName("index_frm");
 
2867
            PMA_showHints($div);
 
2868
            // Add a slider for selecting how many columns to add to the index
 
2869
            $div.find('.slider').slider({
 
2870
                animate: true,
 
2871
                value: 1,
 
2872
                min: 1,
 
2873
                max: 16,
 
2874
                slide: function( event, ui ) {
 
2875
                    $(this).closest('fieldset').find('input[type=submit]').val(
 
2876
                        $.sprintf(PMA_messages['strAddToIndex'], ui.value)
 
2877
                    );
 
2878
                }
 
2879
            });
 
2880
            // focus index size input on column picked
 
2881
            $div.find('table#index_columns select').change(function() {
 
2882
                if ($(this).find("option:selected").val() == '') {
 
2883
                    return true;
 
2884
                }
 
2885
                $(this).closest("tr").find("input").focus();
 
2886
            });
 
2887
            // Focus the slider, otherwise it looks nearly transparent
 
2888
            $('a.ui-slider-handle').addClass('ui-state-focus');
 
2889
            // set focus on index name input, if empty
 
2890
            var input = $div.find('input#input_index_name');
 
2891
            input.val() || input.focus();
 
2892
        }
 
2893
    }); // end $.get()
 
2894
}
 
2895
 
 
2896
/**
 
2897
 * Function to display tooltips that were
 
2898
 * generated on the PHP side by PMA_Util::showHint()
 
2899
 *
 
2900
 * @param object $div a div jquery object which specifies the
 
2901
 *                    domain for searching for tooltips. If we
 
2902
 *                    omit this parameter the function searches
 
2903
 *                    in the whole body
 
2904
 **/
 
2905
function PMA_showHints($div)
 
2906
{
 
2907
    if ($div == undefined || ! $div instanceof jQuery || $div.length == 0) {
 
2908
        $div = $("body");
 
2909
    }
 
2910
    $div.find('.pma_hint').each(function () {
 
2911
        PMA_tooltip(
 
2912
            $(this).children('img'),
 
2913
            'img',
 
2914
            $(this).children('span').html()
 
2915
        );
 
2916
    });
 
2917
}
 
2918
 
 
2919
AJAX.registerOnload('functions.js', function() {
 
2920
    PMA_showHints();
 
2921
});
 
2922
 
 
2923
function PMA_mainMenuResizerCallback() {
 
2924
    // 5 px margin for jumping menu in Chrome
 
2925
    return $(document.body).width() - 5;
 
2926
}
 
2927
// This must be fired only once after the inital page load
 
2928
$(function() {
 
2929
    // Initialise the menu resize plugin
 
2930
    $('#topmenu').menuResizer(PMA_mainMenuResizerCallback);
 
2931
    // register resize event
 
2932
    $(window).resize(function (){
 
2933
        $('#topmenu').menuResizer('resize');
 
2934
    });
 
2935
});
 
2936
 
 
2937
/**
 
2938
 * Get the row number from the classlist (for example, row_1)
 
2939
 */
 
2940
function PMA_getRowNumber(classlist)
 
2941
{
 
2942
    return parseInt(classlist.split(/\s+row_/)[1]);
 
2943
}
 
2944
 
 
2945
/**
 
2946
 * Changes status of slider
 
2947
 */
 
2948
function PMA_set_status_label($element)
 
2949
{
 
2950
    var text = $element.css('display') == 'none'
 
2951
        ? '+ '
 
2952
        : '- ';
 
2953
    $element.closest('.slide-wrapper').prev().find('span').text(text);
 
2954
}
 
2955
 
 
2956
/**
 
2957
 * var  toggleButton  This is a function that creates a toggle
 
2958
 *                    sliding button given a jQuery reference
 
2959
 *                    to the correct DOM element
 
2960
 */
 
2961
var toggleButton = function ($obj) {
 
2962
    // In rtl mode the toggle switch is flipped horizontally
 
2963
    // so we need to take that into account
 
2964
    if ($('span.text_direction', $obj).text() == 'ltr') {
 
2965
        var right = 'right';
 
2966
    } else {
 
2967
        var right = 'left';
 
2968
    }
 
2969
    /**
 
2970
     *  var  h  Height of the button, used to scale the
 
2971
     *          background image and position the layers
 
2972
     */
 
2973
    var h = $obj.height();
 
2974
    $('img', $obj).height(h);
 
2975
    $('table', $obj).css('bottom', h-1);
 
2976
    /**
 
2977
     *  var  on   Width of the "ON" part of the toggle switch
 
2978
     *  var  off  Width of the "OFF" part of the toggle switch
 
2979
     */
 
2980
    var on  = $('td.toggleOn', $obj).width();
 
2981
    var off = $('td.toggleOff', $obj).width();
 
2982
    // Make the "ON" and "OFF" parts of the switch the same size
 
2983
    // + 2 pixels to avoid overflowed
 
2984
    $('td.toggleOn > div', $obj).width(Math.max(on, off) + 2);
 
2985
    $('td.toggleOff > div', $obj).width(Math.max(on, off) + 2);
 
2986
    /**
 
2987
     *  var  w  Width of the central part of the switch
 
2988
     */
 
2989
    var w = parseInt(($('img', $obj).height() / 16) * 22, 10);
 
2990
    // Resize the central part of the switch on the top
 
2991
    // layer to match the background
 
2992
    $('table td:nth-child(2) > div', $obj).width(w);
 
2993
    /**
 
2994
     *  var  imgw    Width of the background image
 
2995
     *  var  tblw    Width of the foreground layer
 
2996
     *  var  offset  By how many pixels to move the background
 
2997
     *               image, so that it matches the top layer
 
2998
     */
 
2999
    var imgw = $('img', $obj).width();
 
3000
    var tblw = $('table', $obj).width();
 
3001
    var offset = parseInt(((imgw - tblw) / 2), 10);
 
3002
    // Move the background to match the layout of the top layer
 
3003
    $obj.find('img').css(right, offset);
 
3004
    /**
 
3005
     *  var  offw    Outer width of the "ON" part of the toggle switch
 
3006
     *  var  btnw    Outer width of the central part of the switch
 
3007
     */
 
3008
    var offw = $('td.toggleOff', $obj).outerWidth();
 
3009
    var btnw = $('table td:nth-child(2)', $obj).outerWidth();
 
3010
    // Resize the main div so that exactly one side of
 
3011
    // the switch plus the central part fit into it.
 
3012
    $obj.width(offw + btnw + 2);
 
3013
    /**
 
3014
     *  var  move  How many pixels to move the
 
3015
     *             switch by when toggling
 
3016
     */
 
3017
    var move = $('td.toggleOff', $obj).outerWidth();
 
3018
    // If the switch is initialized to the
 
3019
    // OFF state we need to move it now.
 
3020
    if ($('div.container', $obj).hasClass('off')) {
 
3021
        if (right == 'right') {
 
3022
            $('div.container', $obj).animate({'left': '-=' + move + 'px'}, 0);
 
3023
        } else {
 
3024
            $('div.container', $obj).animate({'left': '+=' + move + 'px'}, 0);
 
3025
        }
 
3026
    }
 
3027
    // Attach an 'onclick' event to the switch
 
3028
    $('div.container', $obj).click(function () {
 
3029
        if ($(this).hasClass('isActive')) {
 
3030
            return false;
 
3031
        } else {
 
3032
            $(this).addClass('isActive');
 
3033
        }
 
3034
        var $msg = PMA_ajaxShowMessage();
 
3035
        var $container = $(this);
 
3036
        var callback = $('span.callback', this).text();
 
3037
        // Perform the actual toggle
 
3038
        if ($(this).hasClass('on')) {
 
3039
            if (right == 'right') {
 
3040
                var operator = '-=';
 
3041
            } else {
 
3042
                var operator = '+=';
 
3043
            }
 
3044
            var url = $(this).find('td.toggleOff > span').text();
 
3045
            var removeClass = 'on';
 
3046
            var addClass = 'off';
 
3047
        } else {
 
3048
            if (right == 'right') {
 
3049
                var operator = '+=';
 
3050
            } else {
 
3051
                var operator = '-=';
 
3052
            }
 
3053
            var url = $(this).find('td.toggleOn > span').text();
 
3054
            var removeClass = 'off';
 
3055
            var addClass = 'on';
 
3056
        }
 
3057
        $.post(url, {'ajax_request': true}, function(data) {
 
3058
            if (data.success == true) {
 
3059
                PMA_ajaxRemoveMessage($msg);
 
3060
                $container
 
3061
                .removeClass(removeClass)
 
3062
                .addClass(addClass)
 
3063
                .animate({'left': operator + move + 'px'}, function () {
 
3064
                    $container.removeClass('isActive');
 
3065
                });
 
3066
                eval(callback);
 
3067
            } else {
 
3068
                PMA_ajaxShowMessage(data.error, false);
 
3069
                $container.removeClass('isActive');
 
3070
            }
 
3071
        });
 
3072
    });
 
3073
};
 
3074
 
 
3075
/**
 
3076
 * Unbind all event handlers before tearing down a page
 
3077
 */
 
3078
AJAX.registerTeardown('functions.js', function() {
 
3079
    $('div.container').unbind('click');
 
3080
});
 
3081
/**
 
3082
 * Initialise all toggle buttons
 
3083
 */
 
3084
AJAX.registerOnload('functions.js', function () {
 
3085
    $('div.toggleAjax').each(function () {
 
3086
        var $button = $(this).show();
 
3087
        $button.find('img').each(function() {
 
3088
            if (this.complete) {
 
3089
                toggleButton($button);
 
3090
            } else {
 
3091
                $(this).load(function () {
 
3092
                    toggleButton($button);
 
3093
                });
 
3094
            }
 
3095
        });
 
3096
    });
 
3097
});
 
3098
 
 
3099
/**
 
3100
 * Unbind all event handlers before tearing down a page
 
3101
 */
 
3102
AJAX.registerTeardown('functions.js', function() {
 
3103
    $('.vpointer').die('hover');
 
3104
    $('.vmarker').die('click');
 
3105
    $('#pageselector').die('change');
 
3106
    $('a.formLinkSubmit').die('click');
 
3107
    $('#update_recent_tables').unbind('ready');
 
3108
});
 
3109
/**
 
3110
 * Vertical pointer
 
3111
 */
 
3112
AJAX.registerOnload('functions.js', function() {
 
3113
    $('.vpointer').live('hover',
 
3114
        //handlerInOut
 
3115
        function(e) {
 
3116
            var $this_td = $(this);
 
3117
            var row_num = PMA_getRowNumber($this_td.attr('class'));
 
3118
            // for all td of the same vertical row, toggle hover
 
3119
            $('.vpointer').filter('.row_' + row_num).toggleClass('hover');
 
3120
        }
 
3121
    );
 
3122
 
 
3123
 
 
3124
    /**
 
3125
     * Vertical marker
 
3126
     */
 
3127
    $('.vmarker').live('click', function(e) {
 
3128
        // do not trigger when clicked on anchor
 
3129
        if ($(e.target).is('a, img, a *')) {
 
3130
            return;
 
3131
        }
 
3132
 
 
3133
        var $this_td = $(this);
 
3134
        var row_num = PMA_getRowNumber($this_td.attr('class'));
 
3135
 
 
3136
        // XXX: FF fires two click events for <label> (label and checkbox), so we need to handle this differently
 
3137
        var $checkbox = $('.vmarker').filter('.row_' + row_num + ':first').find(':checkbox');
 
3138
        if ($checkbox.length) {
 
3139
            // checkbox in a row, add or remove class depending on checkbox state
 
3140
            var checked = $checkbox.prop('checked');
 
3141
            if (!$(e.target).is(':checkbox, label')) {
 
3142
                checked = !checked;
 
3143
                $checkbox.prop('checked', checked);
 
3144
            }
 
3145
            // for all td of the same vertical row, toggle the marked class
 
3146
            if (checked) {
 
3147
                $('.vmarker').filter('.row_' + row_num).addClass('marked');
 
3148
            } else {
 
3149
                $('.vmarker').filter('.row_' + row_num).removeClass('marked');
 
3150
            }
 
3151
        } else {
 
3152
            // normaln data table, just toggle class
 
3153
            $('.vmarker').filter('.row_' + row_num).toggleClass('marked');
 
3154
        }
 
3155
    });
 
3156
 
 
3157
    /**
 
3158
     * Autosubmit page selector
 
3159
     */
 
3160
    $('select.pageselector').live('change', function(event) {
 
3161
        event.stopPropagation();
 
3162
        // Check where to load the new content
 
3163
        if ($(this).closest("#pma_navigation").length == 0) {
 
3164
            // For the main page we don't need to do anything,
 
3165
            $(this).closest("form").submit();
 
3166
        } else {
 
3167
            // but for the navigation we need to manually replace the content
 
3168
            PMA_navigationTreePagination($(this));
 
3169
        }
 
3170
    });
 
3171
 
 
3172
    /**
 
3173
     * Load version information asynchronously.
 
3174
     */
 
3175
    if ($('li.jsversioncheck').length > 0) {
 
3176
        $.getJSON('version_check.php', {}, PMA_current_version);
 
3177
    }
 
3178
 
 
3179
    if ($('#is_git_revision').length > 0) {
 
3180
        setTimeout(PMA_display_git_revision, 10);
 
3181
    }
 
3182
 
 
3183
    /**
 
3184
     * Slider effect.
 
3185
     */
 
3186
    PMA_init_slider();
 
3187
 
 
3188
    /**
 
3189
     * Enables the text generated by PMA_Util::linkOrButton() to be clickable
 
3190
     */
 
3191
    $('a.formLinkSubmit').live('click', function(e) {
 
3192
 
 
3193
        if ($(this).attr('href').indexOf('=') != -1) {
 
3194
            var data = $(this).attr('href').substr($(this).attr('href').indexOf('#')+1).split('=', 2);
 
3195
            $(this).parents('form').append('<input type="hidden" name="' + data[0] + '" value="' + data[1] + '"/>');
 
3196
        }
 
3197
        $(this).parents('form').submit();
 
3198
        return false;
 
3199
    });
 
3200
 
 
3201
    if ($('#update_recent_tables').length) {
 
3202
        $.get(
 
3203
            $('#update_recent_tables').attr('href'),
 
3204
            function (data) {
 
3205
                if (data.success == true) {
 
3206
                    $('#recentTable').html(data.options);
 
3207
                }
 
3208
            }
 
3209
        );
 
3210
    }
 
3211
 
 
3212
}); // end of $()
 
3213
 
 
3214
 
 
3215
/**
 
3216
 * Initializes slider effect.
 
3217
 */
 
3218
function PMA_init_slider()
 
3219
{
 
3220
    $('div.pma_auto_slider').each(function() {
 
3221
        var $this = $(this);
 
3222
        if ($this.data('slider_init_done')) {
 
3223
            return;
 
3224
        }
 
3225
        var $wrapper = $('<div>', {'class': 'slide-wrapper'});
 
3226
        $wrapper.toggle($this.is(':visible'));
 
3227
        $('<a>', {href: '#'+this.id, "class":'ajax'})
 
3228
            .text(this.title)
 
3229
            .prepend($('<span>'))
 
3230
            .insertBefore($this)
 
3231
            .click(function() {
 
3232
                var $wrapper = $this.closest('.slide-wrapper');
 
3233
                var visible = $this.is(':visible');
 
3234
                if (!visible) {
 
3235
                    $wrapper.show();
 
3236
                }
 
3237
                $this[visible ? 'hide' : 'show']('blind', function() {
 
3238
                    $wrapper.toggle(!visible);
 
3239
                    PMA_set_status_label($this);
 
3240
                });
 
3241
                return false;
 
3242
            });
 
3243
        $this.wrap($wrapper);
 
3244
        PMA_set_status_label($this);
 
3245
        $this.data('slider_init_done', 1);
 
3246
    });
 
3247
}
 
3248
 
 
3249
/**
 
3250
 * Initializes slider effect.
 
3251
 */
 
3252
AJAX.registerOnload('functions.js', function() {
 
3253
    PMA_init_slider();
 
3254
});
 
3255
 
 
3256
/**
 
3257
 * Restores sliders to the state they were in before initialisation.
 
3258
 */
 
3259
AJAX.registerTeardown('functions.js', function() {
 
3260
    $('div.pma_auto_slider').each(function() {
 
3261
        var $this = $(this);
 
3262
        $this.removeData();
 
3263
        $this.parent().replaceWith($this);
 
3264
        $this.parent().children('a').remove();
 
3265
    });
 
3266
});
 
3267
 
 
3268
/**
 
3269
 * Creates a message inside an object with a sliding effect
 
3270
 *
 
3271
 * @param msg    A string containing the text to display
 
3272
 * @param $obj   a jQuery object containing the reference
 
3273
 *                 to the element where to put the message
 
3274
 *                 This is optional, if no element is
 
3275
 *                 provided, one will be created below the
 
3276
 *                 navigation links at the top of the page
 
3277
 *
 
3278
 * @return bool   True on success, false on failure
 
3279
 */
 
3280
function PMA_slidingMessage(msg, $obj)
 
3281
{
 
3282
    if (msg == undefined || msg.length == 0) {
 
3283
        // Don't show an empty message
 
3284
        return false;
 
3285
    }
 
3286
    if ($obj == undefined || ! $obj instanceof jQuery || $obj.length == 0) {
 
3287
        // If the second argument was not supplied,
 
3288
        // we might have to create a new DOM node.
 
3289
        if ($('#PMA_slidingMessage').length == 0) {
 
3290
            $('#page_content').prepend(
 
3291
                '<span id="PMA_slidingMessage" '
 
3292
                 + 'style="display: inline-block;"></span>'
 
3293
            );
 
3294
        }
 
3295
        $obj = $('#PMA_slidingMessage');
 
3296
    }
 
3297
    if ($obj.has('div').length > 0) {
 
3298
        // If there already is a message inside the
 
3299
        // target object, we must get rid of it
 
3300
        $obj
 
3301
        .find('div')
 
3302
        .first()
 
3303
        .fadeOut(function () {
 
3304
            $obj
 
3305
            .children()
 
3306
            .remove();
 
3307
            $obj
 
3308
            .append('<div style="display: none;">' + msg + '</div>')
 
3309
            .animate({
 
3310
                height: $obj.find('div').first().height()
 
3311
            })
 
3312
            .find('div')
 
3313
            .first()
 
3314
            .fadeIn();
 
3315
        });
 
3316
    } else {
 
3317
        // Object does not already have a message
 
3318
        // inside it, so we simply slide it down
 
3319
        var h = $obj
 
3320
                .width('100%')
 
3321
                .html('<div style="display: none;">' + msg + '</div>')
 
3322
                .find('div')
 
3323
                .first()
 
3324
                .height();
 
3325
        $obj
 
3326
        .find('div')
 
3327
        .first()
 
3328
        .css('height', 0)
 
3329
        .show()
 
3330
        .animate({
 
3331
                height: h
 
3332
            }, function() {
 
3333
            // Set the height of the parent
 
3334
            // to the height of the child
 
3335
            $obj
 
3336
            .height(
 
3337
                $obj
 
3338
                .find('div')
 
3339
                .first()
 
3340
                .height()
 
3341
            );
 
3342
        });
 
3343
    }
 
3344
    return true;
 
3345
} // end PMA_slidingMessage()
 
3346
 
 
3347
/**
 
3348
 * Unbind all event handlers before tearing down a page
 
3349
 */
 
3350
AJAX.registerTeardown('functions.js', function() {
 
3351
    $("#drop_tbl_anchor.ajax").die('click');
 
3352
    $("#truncate_tbl_anchor.ajax").die('click');
 
3353
});
 
3354
/**
 
3355
 * Attach Ajax event handlers for Drop Table.
 
3356
 */
 
3357
AJAX.registerOnload('functions.js', function() {
 
3358
    $("#drop_tbl_anchor.ajax").live('click', function(event) {
 
3359
        event.preventDefault();
 
3360
        /**
 
3361
         * @var question    String containing the question to be asked for confirmation
 
3362
         */
 
3363
        var question = PMA_messages.strDropTableStrongWarning + ' ';
 
3364
        question += $.sprintf(
 
3365
            PMA_messages.strDoYouReally,
 
3366
            'DROP TABLE ' + PMA_commonParams.get('table')
 
3367
        );
 
3368
 
 
3369
        $(this).PMA_confirm(question, $(this).attr('href'), function(url) {
 
3370
 
 
3371
            var $msgbox = PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']);
 
3372
            $.get(url, {'is_js_confirmed': '1', 'ajax_request': true}, function(data) {
 
3373
                if (data.success == true) {
 
3374
                    PMA_ajaxRemoveMessage($msgbox);
 
3375
                    // Table deleted successfully, refresh both the frames
 
3376
                    PMA_reloadNavigation();
 
3377
                    PMA_commonParams.set('table', '');
 
3378
                    PMA_commonActions.refreshMain(
 
3379
                        PMA_commonParams.get('opendb_url'),
 
3380
                        function () {
 
3381
                            PMA_ajaxShowMessage(data.message);
 
3382
                        }
 
3383
                    );
 
3384
                } else {
 
3385
                    PMA_ajaxShowMessage(data.error, false);
 
3386
                }
 
3387
            }); // end $.get()
 
3388
        }); // end $.PMA_confirm()
 
3389
    }); //end of Drop Table Ajax action
 
3390
 
 
3391
    $("#truncate_tbl_anchor.ajax").live('click', function(event) {
 
3392
        event.preventDefault();
 
3393
        /**
 
3394
         * @var question    String containing the question to be asked for confirmation
 
3395
         */
 
3396
        var question = PMA_messages.strTruncateTableStrongWarning + ' ';
 
3397
        question += $.sprintf(
 
3398
            PMA_messages.strDoYouReally,
 
3399
            'TRUNCATE ' + PMA_commonParams.get('table')
 
3400
        );
 
3401
        $(this).PMA_confirm(question, $(this).attr('href'), function(url) {
 
3402
            PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']);
 
3403
            $.get(url, {'is_js_confirmed': '1', 'ajax_request': true}, function(data) {
 
3404
                if ($("#sqlqueryresults").length != 0) {
 
3405
                    $("#sqlqueryresults").remove();
 
3406
                }
 
3407
                if ($("#result_query").length != 0) {
 
3408
                    $("#result_query").remove();
 
3409
                }
 
3410
                if (data.success == true) {
 
3411
                    PMA_ajaxShowMessage(data.message);
 
3412
                    $("<div id='sqlqueryresults'></div>").prependTo("#page_content");
 
3413
                    $("#sqlqueryresults").html(data.sql_query);
 
3414
                } else {
 
3415
                    PMA_ajaxShowMessage(data.error, false);
 
3416
                }
 
3417
            }); // end $.get()
 
3418
        }); // end $.PMA_confirm()
 
3419
    }); //end of Truncate Table Ajax action
 
3420
}); // end of $() for Truncate Table
 
3421
 
 
3422
/**
 
3423
 * Attach CodeMirror2 editor to SQL edit area.
 
3424
 */
 
3425
AJAX.registerOnload('functions.js', function() {
 
3426
    var $elm = $('#sqlquery');
 
3427
    if ($elm.length > 0) {
 
3428
        if (typeof CodeMirror != 'undefined') {
 
3429
            // for codemirror
 
3430
            codemirror_editor = CodeMirror.fromTextArea($elm[0], {
 
3431
                lineNumbers: true,
 
3432
                matchBrackets: true,
 
3433
                indentUnit: 4,
 
3434
                mode: "text/x-mysql",
 
3435
                lineWrapping: true
 
3436
            });
 
3437
            codemirror_editor.focus();
 
3438
            $(codemirror_editor.getWrapperElement()).bind(
 
3439
                'keydown',
 
3440
                catchKeypressesFromSqlTextboxes
 
3441
            );
 
3442
        } else {
 
3443
            // without codemirror
 
3444
            $elm.focus().bind('keydown', catchKeypressesFromSqlTextboxes);
 
3445
        }
 
3446
    }
 
3447
});
 
3448
AJAX.registerTeardown('functions.js', function() {
 
3449
    if (codemirror_editor) {
 
3450
        $('#sqlquery').text(codemirror_editor.getValue());
 
3451
        codemirror_editor.toTextArea();
 
3452
        codemirror_editor = false;
 
3453
    }
 
3454
});
 
3455
 
 
3456
/**
 
3457
 * jQuery plugin to cancel selection in HTML code.
 
3458
 */
 
3459
(function ($) {
 
3460
    $.fn.noSelect = function (p) { //no select plugin by Paulo P.Marinas
 
3461
        var prevent = (p == null) ? true : p;
 
3462
        if (prevent) {
 
3463
            return this.each(function () {
 
3464
                if ($.browser.msie || $.browser.safari) {
 
3465
                    $(this).bind('selectstart', function () {
 
3466
                        return false;
 
3467
                    });
 
3468
                } else if ($.browser.mozilla) {
 
3469
                    $(this).css('MozUserSelect', 'none');
 
3470
                    $('body').trigger('focus');
 
3471
                } else if ($.browser.opera) {
 
3472
                    $(this).bind('mousedown', function () {
 
3473
                        return false;
 
3474
                    });
 
3475
                } else {
 
3476
                    $(this).attr('unselectable', 'on');
 
3477
                }
 
3478
            });
 
3479
        } else {
 
3480
            return this.each(function () {
 
3481
                if ($.browser.msie || $.browser.safari) {
 
3482
                    $(this).unbind('selectstart');
 
3483
                } else if ($.browser.mozilla) {
 
3484
                    $(this).css('MozUserSelect', 'inherit');
 
3485
                } else if ($.browser.opera) {
 
3486
                    $(this).unbind('mousedown');
 
3487
                } else {
 
3488
                    $(this).removeAttr('unselectable');
 
3489
                }
 
3490
            });
 
3491
        }
 
3492
    }; //end noSelect
 
3493
})(jQuery);
 
3494
 
 
3495
/**
 
3496
 * jQuery plugin to correctly filter input fields by value, needed
 
3497
 * because some nasty values may break selector syntax
 
3498
 */
 
3499
(function ($) {
 
3500
    $.fn.filterByValue = function (value) {
 
3501
        return this.filter(function () {
 
3502
            return $(this).val() === value;
 
3503
        });
 
3504
    };
 
3505
})(jQuery);
 
3506
 
 
3507
/**
 
3508
 * Create a jQuery UI tooltip
 
3509
 *
 
3510
 * @param $elements     jQuery object representing the elements
 
3511
 * @param item          the item
 
3512
 *                      (see http://api.jqueryui.com/tooltip/#option-items)
 
3513
 * @param myContent     content of the tooltip
 
3514
 * @param additionalOptions to override the default options
 
3515
 *
 
3516
 */
 
3517
function PMA_tooltip($elements, item, myContent, additionalOptions)
 
3518
{
 
3519
    if ($('#no_hint').length > 0) {
 
3520
        return;
 
3521
    }
 
3522
 
 
3523
    var defaultOptions = {
 
3524
        content: myContent,
 
3525
        items:  item,
 
3526
        tooltipClass: "tooltip",
 
3527
        track: true,
 
3528
        show: false,
 
3529
        hide: false
 
3530
    };
 
3531
 
 
3532
    $elements.tooltip($.extend(true, defaultOptions, additionalOptions));
 
3533
}
 
3534
 
 
3535
/**
 
3536
 * Return value of a cell in a table.
 
3537
 */
 
3538
function PMA_getCellValue(td) {
 
3539
    var $td = $(td);
 
3540
    if ($td.is('.null')) {
 
3541
        return '';
 
3542
    } else if (! $td.is('.to_be_saved') && $td.data('original_data')) {
 
3543
        return $td.data('original_data');
 
3544
    } else {
 
3545
        return $td.text();
 
3546
    }
 
3547
}
 
3548
 
 
3549
/**
 
3550
 * Unbind all event handlers before tearing down a page
 
3551
 */
 
3552
AJAX.registerTeardown('functions.js', function() {
 
3553
    $('a.themeselect').die('click');
 
3554
    $('.autosubmit').die('change');
 
3555
    $('a.take_theme').unbind('click');
 
3556
});
 
3557
 
 
3558
AJAX.registerOnload('functions.js', function() {
 
3559
    /**
 
3560
     * Theme selector.
 
3561
     */
 
3562
    $('a.themeselect').live('click', function(e) {
 
3563
        window.open(
 
3564
            e.target,
 
3565
            'themes',
 
3566
            'left=10,top=20,width=510,height=350,scrollbars=yes,status=yes,resizable=yes'
 
3567
            );
 
3568
        return false;
 
3569
    });
 
3570
 
 
3571
    /**
 
3572
     * Automatic form submission on change.
 
3573
     */
 
3574
    $('.autosubmit').live('change', function(e) {
 
3575
        $(this).closest('form').submit();
 
3576
    });
 
3577
 
 
3578
    /**
 
3579
     * Theme changer.
 
3580
     */
 
3581
    $('a.take_theme').click(function(e) {
 
3582
        var what = this.name;
 
3583
        if (window.opener && window.opener.document.forms['setTheme'].elements['set_theme']) {
 
3584
            window.opener.document.forms['setTheme'].elements['set_theme'].value = what;
 
3585
            window.opener.document.forms['setTheme'].submit();
 
3586
            window.close();
 
3587
            return false;
 
3588
        }
 
3589
        return true;
 
3590
    });
 
3591
});
 
3592
 
 
3593
/**
 
3594
 * Clear text selection
 
3595
 */
 
3596
function PMA_clearSelection() {
 
3597
    if (document.selection && document.selection.empty) {
 
3598
        document.selection.empty();
 
3599
    } else if (window.getSelection) {
 
3600
        var sel = window.getSelection();
 
3601
        if (sel.empty) {
 
3602
            sel.empty();
 
3603
        }
 
3604
        if (sel.removeAllRanges) {
 
3605
            sel.removeAllRanges();
 
3606
        }
 
3607
    }
 
3608
}
 
3609
 
 
3610
/**
 
3611
 * HTML escaping
 
3612
 */
 
3613
function escapeHtml(unsafe) {
 
3614
    return unsafe
 
3615
        .replace(/&/g, "&amp;")
 
3616
        .replace(/</g, "&lt;")
 
3617
        .replace(/>/g, "&gt;")
 
3618
        .replace(/"/g, "&quot;")
 
3619
        .replace(/'/g, "&#039;");
 
3620
}
 
3621
 
 
3622
/**
 
3623
 * Print button
 
3624
 */
 
3625
function printPage()
 
3626
{
 
3627
    // Do print the page
 
3628
    if (typeof(window.print) != 'undefined') {
 
3629
        window.print();
 
3630
    }
 
3631
}
 
3632
 
 
3633
/**
 
3634
 * Unbind all event handlers before tearing down a page
 
3635
 */
 
3636
AJAX.registerTeardown('functions.js', function() {
 
3637
    $('input#print').unbind('click');
 
3638
    $('span a.create_view.ajax').die('click');
 
3639
    $('#createViewDialog').find('input, select').die('keydown');
 
3640
});
 
3641
 
 
3642
AJAX.registerOnload('functions.js', function() {
 
3643
    $('input#print').click(printPage);
 
3644
    /**
 
3645
     * Ajaxification for the "Create View" action
 
3646
     */
 
3647
    $('span a.create_view.ajax').live('click', function (e) {
 
3648
        e.preventDefault();
 
3649
        PMA_createViewDialog($(this));
 
3650
    });
 
3651
    /**
 
3652
     * Attach Ajax event handlers for input fields in the editor
 
3653
     * and used to submit the Ajax request when the ENTER key is pressed.
 
3654
     */
 
3655
    $('#createViewDialog').find('input, select').live('keydown', function (e) {
 
3656
        if (e.which === 13) { // 13 is the ENTER key
 
3657
            e.preventDefault();
 
3658
            $(this).closest('.ui-dialog').find('.ui-button:first').click();
 
3659
        }
 
3660
    }); // end $.live()
 
3661
});
 
3662
 
 
3663
function PMA_createViewDialog($this)
 
3664
{
 
3665
    var $msg = PMA_ajaxShowMessage();
 
3666
    var syntaxHighlighter = null;
 
3667
    $.get($this.attr('href') + '&ajax_request=1', function (data) {
 
3668
        if (data.success == true) {
 
3669
            PMA_ajaxRemoveMessage($msg);
 
3670
            var buttonOptions = {};
 
3671
            buttonOptions[PMA_messages['strGo']] = function () {
 
3672
                if (typeof CodeMirror !== 'undefined') {
 
3673
                    syntaxHighlighter.save();
 
3674
                }
 
3675
                $msg = PMA_ajaxShowMessage();
 
3676
                $.get('view_create.php', $('#createViewDialog').find('form').serialize(), function (data) {
 
3677
                    PMA_ajaxRemoveMessage($msg);
 
3678
                    if (data.success === true) {
 
3679
                        $('#createViewDialog').dialog("close");
 
3680
                        $('#result_query').html(data.message);
 
3681
                        PMA_reloadNavigation();
 
3682
                    } else {
 
3683
                        PMA_ajaxShowMessage(data.error, false);
 
3684
                    }
 
3685
                });
 
3686
            };
 
3687
            buttonOptions[PMA_messages['strClose']] = function () {
 
3688
                $(this).dialog("close");
 
3689
            };
 
3690
            var $dialog = $('<div/>').attr('id', 'createViewDialog').append(data.message).dialog({
 
3691
                width: 500,
 
3692
                minWidth: 300,
 
3693
                maxWidth: 620,
 
3694
                modal: true,
 
3695
                buttons: buttonOptions,
 
3696
                title: $('legend', $(data.message)).html(),
 
3697
                close: function () {
 
3698
                    $(this).remove();
 
3699
                }
 
3700
            });
 
3701
            $dialog.find('legend').remove();
 
3702
            // Attach syntax highlited editor
 
3703
            if (typeof CodeMirror !== 'undefined') {
 
3704
                var $elm = $dialog.find('textarea');
 
3705
                var opts = {lineNumbers: true, matchBrackets: true, indentUnit: 4, mode: "text/x-mysql"};
 
3706
                syntaxHighlighter = CodeMirror.fromTextArea($elm[0], opts);
 
3707
            }
 
3708
            $('input:visible[type=text]', $dialog).first().focus();
 
3709
        } else {
 
3710
            PMA_ajaxShowMessage(data.error);
 
3711
        }
 
3712
    });
 
3713
}
 
3714
 
 
3715
/**
 
3716
 * Makes the breadcrumbs and the menu bar float at the top of the viewport
 
3717
 */
 
3718
$(function () {
 
3719
    if ($("#floating_menubar").length && $('#PMA_disable_floating_menubar').length == 0) {
 
3720
        var left = $('html').attr('dir') == 'ltr' ? 'left' : 'right';
 
3721
        $("#floating_menubar")
 
3722
            .css('margin-' + left, $('#pma_navigation').width() + $('#pma_navigation_resizer').width())
 
3723
            .css(left, 0)
 
3724
            .css({
 
3725
                'position': 'fixed',
 
3726
                'top': 0,
 
3727
                'width': '100%',
 
3728
                'z-index': 500
 
3729
            })
 
3730
            .append($('#serverinfo'))
 
3731
            .append($('#topmenucontainer'));
 
3732
        // Allow the DOM to render, then adjust the padding on the body
 
3733
        setTimeout(function () {
 
3734
            $('body').css(
 
3735
                'padding-top',
 
3736
                $('#floating_menubar').outerHeight(true)
 
3737
            );
 
3738
            $('#topmenu').menuResizer('resize');
 
3739
        }, 4);
 
3740
    }
 
3741
});
 
3742
 
 
3743
/**
 
3744
 * Scrolls the page to the top if clicking the serverinfo bar
 
3745
 */
 
3746
$(function () {
 
3747
    $(document).delegate("#serverinfo, #goto_pagetop", "click", function (event) {
 
3748
        event.preventDefault();
 
3749
        $('html, body').animate({scrollTop: 0}, 'fast');
 
3750
    });
 
3751
});
 
3752
 
 
3753
/**
 
3754
 * Watches checkboxes in a form to set the checkall box accordingly
 
3755
 */
 
3756
var checkboxes_sel = "input.checkall:checkbox:enabled";
 
3757
$(checkboxes_sel).live("change", function () {
 
3758
    var $form = $(this.form);
 
3759
    // total number of checkboxes in current form
 
3760
    var total_boxes = $form.find(checkboxes_sel).length;
 
3761
    // number of checkboxes checked in current form
 
3762
    var checked_boxes = $form.find(checkboxes_sel + ":checked").length;
 
3763
    var $checkall = $form.find("input#checkall");
 
3764
    if (total_boxes == checked_boxes) {
 
3765
        $checkall.prop({checked: true, indeterminate: false});
 
3766
    }
 
3767
    else if (checked_boxes > 0) {
 
3768
        $checkall.prop({checked: true, indeterminate: true});
 
3769
    }
 
3770
    else {
 
3771
        $checkall.prop({checked: false, indeterminate: false});
 
3772
    }
 
3773
});
 
3774
$("input#checkall").live("change", function() {
 
3775
    var is_checked = $(this).is(":checked");
 
3776
    $(this.form).find(checkboxes_sel).prop("checked", is_checked)
 
3777
    .parents("tr").toggleClass("marked", is_checked);
 
3778
});
 
3779
 
 
3780
/**
 
3781
 * Toggles row colors of a set of 'tr' elements starting from a given element
 
3782
 *
 
3783
 * @param $start Starting element
 
3784
 */
 
3785
function toggleRowColors($start)
 
3786
{
 
3787
    for (var $curr_row = $start; $curr_row.length > 0; $curr_row = $curr_row.next()) {
 
3788
        if ($curr_row.hasClass('odd')) {
 
3789
            $curr_row.removeClass('odd').addClass('even');
 
3790
        } else if ($curr_row.hasClass('even')) {
 
3791
            $curr_row.removeClass('even').addClass('odd');
 
3792
        }
 
3793
    }
 
3794
}
 
3795
 
 
3796
/**
 
3797
 * Formats a byte number to human-readable form
 
3798
 *
 
3799
 * @param bytes the bytes to format
 
3800
 * @param optional subdecimals the number of digits after the point
 
3801
 * @param optional pointchar the char to use as decimal point
 
3802
 */
 
3803
function formatBytes(bytes, subdecimals, pointchar) {
 
3804
    if (!subdecimals) {
 
3805
        var subdecimals = 0;
 
3806
    }
 
3807
    if (!pointchar) {
 
3808
        var pointchar = '.';
 
3809
    }
 
3810
    var units = ['B', 'KiB', 'MiB', 'GiB'];
 
3811
    for (var i = 0; bytes > 1024 && i < units.length; i++) {
 
3812
        bytes /= 1024;
 
3813
    }
 
3814
    var factor = Math.pow(10, subdecimals);
 
3815
    bytes = Math.round(bytes * factor) / factor;
 
3816
    bytes = bytes.toString().split('.').join(pointchar);
 
3817
    return bytes + ' ' + units[i];
 
3818
}
 
3819
 
 
3820
AJAX.registerOnload('functions.js', function () {
 
3821
    /**
 
3822
     * Opens pma more themes link in themes browser, in new window instead of popup
 
3823
     * This way, we don't break HTML validity
 
3824
     */
 
3825
    $("a._blank").prop("target", "_blank");
 
3826
    /**
 
3827
     * Reveal the login form to users with JS enabled
 
3828
     * and focus the appropriate input field
 
3829
     */
 
3830
    var $loginform = $('#loginform');
 
3831
    if ($loginform.length) {
 
3832
        $loginform.find('.js-show').show();
 
3833
        if ($('#input_username').val()) {
 
3834
            $('#input_password').focus();
 
3835
        } else {
 
3836
            $('#input_username').focus();
 
3837
        }
 
3838
    }
 
3839
});
 
3840
 
 
3841
/**
 
3842
 * When user gets an ajax session expiry message, we show a login link
 
3843
 */
 
3844
$('a.login-link').live('click', function(e) {
 
3845
    e.preventDefault();
 
3846
    window.location.reload(true);
 
3847
});
 
3848
 
 
3849
/**
 
3850
 * Formats timestamp for display
 
3851
 */
 
3852
function PMA_formatDateTime(date, seconds) {
 
3853
    var result = $.datepicker.formatDate('yy-mm-dd', date);
 
3854
    var timefmt = 'HH:mm';
 
3855
    if (seconds) {
 
3856
        timefmt = 'HH:mm:ss';
 
3857
    }
 
3858
    return result + ' ' + $.datepicker.formatTime(
 
3859
        timefmt, {
 
3860
            hour: date.getHours(),
 
3861
            minute: date.getMinutes(),
 
3862
            second: date.getSeconds()
 
3863
        }
 
3864
    );
 
3865
}