1
var AJAX={active:false,source:null,_callback:function(){},_debug:false,$msgbox:null,hash:function(c){c+="";var a=c.length,d=0,b=0;for(;b<a;++b){d+=c.charCodeAt(b);d+=(d<<10);d^=(d>>6)}d+=(d<<3);d^=(d>>11);d+=(d<<15);return Math.abs(d)},registerOnload:function(b,c){var a="onload_"+AJAX.hash(b);$(document).bind(a,c);this._debug&&console.log("Registered event "+a+" for file "+b);return this},registerTeardown:function(b,c){var a="teardown_"+AJAX.hash(b);$(document).bind(a,c);this._debug&&console.log("Registered event "+a+" for file "+b);return this},fireOnload:function(b){var a="onload_"+AJAX.hash(b);$(document).trigger(a);this._debug&&console.log("Fired event "+a+" for file "+b)},fireTeardown:function(b){var a="teardown_"+AJAX.hash(b);$(document).triggerHandler(a);this._debug&&console.log("Fired event "+a+" for file "+b)},requestHandler:function(d){var b=$(this).attr("href");if(d.shiftKey||d.ctrlKey){return true}else{if($(this).attr("target")){return true}else{if($(this).hasClass("ajax")||$(this).hasClass("disableAjax")){return true}else{if(b&&b.match(/^#/)){return true}else{if(b&&b.match(/^mailto/)){return true}else{if($(this).hasClass("ui-datepicker-next")||$(this).hasClass("ui-datepicker-prev")){return true}}}}}}if(typeof d!="undefined"){d.preventDefault();d.stopImmediatePropagation()}if(AJAX.active==true){return false}AJAX.source=$(this);$("html, body").animate({scrollTop:0},"fast");var e=!!b||false;var c=e?b:$(this).attr("action");var f="ajax_request=true&ajax_page_request=true";if(!e){f+="&"+$(this).serialize()}f+=AJAX.cache.menus.getRequestParam();AJAX._debug&&console.log("Loading: "+c);if(e){AJAX.active=true;AJAX.$msgbox=PMA_ajaxShowMessage();$.get(c,f,AJAX.responseHandler)}else{var a=$(this).data("onsubmit");if(typeof a!=="function"||a.apply(this,[d])){AJAX.active=true;AJAX.$msgbox=PMA_ajaxShowMessage();$.post(c,f,AJAX.responseHandler)}}},responseHandler:function(a){if(a.success){$table_clone=false;PMA_ajaxRemoveMessage(AJAX.$msgbox);if(a._redirect){PMA_ajaxShowMessage(a._redirect,false);AJAX.active=false;return}AJAX.scriptHandler.reset(function(){if(a._reloadNavigation){PMA_reloadNavigation()}if(a._reloadQuerywindow){var b=a._reloadQuerywindow;PMA_querywindow.reload(b.db,b.table,b.sql_query)}if(a._focusQuerywindow){PMA_querywindow.focus(a._focusQuerywindow)}if(a._title){$("title").replaceWith(a._title)}if(a._menu){AJAX.cache.menus.replace(a._menu);AJAX.cache.menus.add(a._menuHash,a._menu)}else{if(a._menuHash){AJAX.cache.menus.replace(AJAX.cache.menus.get(a._menuHash))}}$("body").children().not("#pma_navigation").not("#floating_menubar").not("#goto_pagetop").not("#page_content").not("#selflink").not("#session_debug").remove();if(a.message&&a.message.length>0){$("#page_content").replaceWith("<div id='page_content'>"+a.message+"</div>")}if(a._selflink){$("#selflink > a").attr("href",a._selflink)}if(a._scripts){AJAX.scriptHandler.load(a._scripts)}if(a._selflink&&a._scripts&&a._menuHash&&a._params){AJAX.cache.add(a._selflink,a._scripts,a._menuHash,a._params,AJAX.source.attr("rel"))}if(a._params){PMA_commonParams.setAll(a._params)}if(a._displayMessage){$("#page_content").prepend(a._displayMessage)}$("#pma_errors").remove();if(a._errors){$("<div/>",{id:"pma_errors"}).insertAfter("#selflink").append(a._errors)}if(typeof AJAX._callback==="function"){AJAX._callback.call()}AJAX._callback=function(){}})}else{PMA_ajaxShowMessage(a.error,false);AJAX.active=false}},scriptHandler:{_scripts:[],_scriptsToBeLoaded:[],_scriptsToBeFired:[],add:function(a,b){this._scripts.push(a);if(b){this._scriptsToBeFired.push(a)}return this},load:function(g){var b=this;b._scriptsToBeLoaded=[];b._scriptsToBeFired=[];for(var d in g){b._scriptsToBeLoaded.push(g[d].name);if(g[d].fire){b._scriptsToBeFired.push(g[d].name)}}var f=[];var e=false;for(var c in b._scriptsToBeLoaded){var a=b._scriptsToBeLoaded[c];if($.inArray(a,b._scripts)==-1){e=true;this.add(a);f.push("scripts[]="+a)}}if(e){$.ajax({url:"js/get_scripts.js.php?"+f.join("&"),cache:true,success:function(){b.done()},dataType:"script"})}else{b.done()}},done:function(){for(var a in this._scriptsToBeFired){AJAX.fireOnload(this._scriptsToBeFired[a])}AJAX.active=false},reset:function(b){for(var a in this._scriptsToBeFired){AJAX.fireTeardown(this._scriptsToBeFired[a])}this._scriptsToBeFired=[];$("a").die("click").live("click",AJAX.requestHandler);$("form").die("submit").live("submit",AJAX.requestHandler);AJAX.cache.update();b()}}};AJAX.registerOnload("functions.js",function(){$("form").not(".ajax").not(".disableAjax").each(function(){if($(this).attr("onsubmit")){$(this).data("onsubmit",this.onsubmit).attr("onsubmit","")}})});AJAX.cache={MAX:6,primer:{},pages:[],current:0,add:function(d,b,f,e,a){if(this.pages.length>AJAX.cache.MAX){for(var c=0;c<this.pages.length-this.MAX;c++){delete this.pages[c]}}while(this.current<this.pages.length){this.pages.pop()}if(a==="newpage"||(typeof a==="undefined"&&(typeof this.pages[this.current-1]==="undefined"||this.pages[this.current-1].hash!==d))){this.pages.push({hash:d,content:$("#page_content").html(),scripts:b,selflink:$("#selflink").html(),menu:f,params:e});AJAX.setUrlHash(this.current,d);this.current++}},navigate:function(b){if(typeof this.pages[b]==="undefined"){PMA_ajaxShowMessage('<div class="error">'+PMA_messages.strInvalidPage+"</div>",false)}else{AJAX.active=true;var a=this.pages[b];AJAX.scriptHandler.reset(function(){$("#page_content").html(a.content);$("#selflink").html(a.selflink);AJAX.cache.menus.replace(AJAX.cache.menus.get(a.menu));PMA_commonParams.setAll(a.params);AJAX.scriptHandler.load(a.scripts);AJAX.cache.current=++b})}},update:function(){var a=this.pages[this.current-1];if(a){a.content=$("#page_content").html()}},menus:{size:function(c){var b=0,a;for(a in c){if(c.hasOwnProperty(a)){b++}}return b},data:{},add:function(e,d){if(this.size(this.data)>AJAX.cache.MAX){var a,c,f=0;for(var b in this.data){if(this.data[b]){if(!f||this.data[b].timestamp.getTime()<a.getTime()){a=this.data[b].timestamp;c=b;f=1}}}delete this.data[c]}this.data[e]={content:d,timestamp:new Date()}},get:function(a){if(this.data[a]){return this.data[a].content}else{return""}},getRequestParam:function(){var d="";var a=[];for(var b in this.data){a.push(b)}var c=a.join("-");if(c){d="&menuHashes="+c}return d},replace:function(a){$("#floating_menubar").html(a).children().first().remove();$("#topmenu").menuResizer(PMA_mainMenuResizerCallback)}}};AJAX.setUrlHash=(function(f,d){var c=false;var g="";var a=true;function e(){if(f.browser.mozilla){$("head > link[href=favicon\\.ico]").appendTo("head")}}function b(h,i){a=false;if(c){d.location.hash="PMAURL-"+h+":"+i;e()}else{g="PMAURL-"+h+":"+i}}if(d.location.hash.substring(0,8)=="#PMAURL-"){d.location=d.location.hash.substring(d.location.hash.indexOf(":")+1)}else{f(function(){if(g!=""){d.location.hash=g;g="";e()}c=true})}f(function(){f(d).hashchange(function(){if(a===false){a=true}else{if(/^#PMAURL-\d+:/.test(d.location.hash)){var h=d.location.hash.substring(8,d.location.hash.indexOf(":"));AJAX.cache.navigate(h)}}})});return b})(jQuery,window);$(function(){if(AJAX.cache.primer.url){AJAX.cache.menus.add(AJAX.cache.primer.menuHash,$("<div></div>").append("<div></div>").append($("#serverinfo").clone()).append($("#topmenucontainer").clone()).html())}$(function(){if(AJAX.cache.primer.url){AJAX.cache.add(AJAX.cache.primer.url,AJAX.cache.primer.scripts,AJAX.cache.primer.menuHash)}})});$("a").live("click",AJAX.requestHandler);$("form").live("submit",AJAX.requestHandler);$(document).ajaxError(function(d,c,b){if(c.status!==0){var e=$.sprintf(PMA_messages.strErrorCode,c.status);var a=$.sprintf(PMA_messages.strErrorText,c.statusText);PMA_ajaxShowMessage('<div class="error">'+PMA_messages.strErrorProcessingRequest+"<div>"+e+"</div><div>"+a+"</div></div>",false);AJAX.active=false}});
b'\\ No newline at end of file'
1
/* vim: set expandtab sw=4 ts=4 sts=4: */
3
* This object handles ajax requests for pages. It also
4
* handles the reloading of the main menu and scripts.
8
* @var bool active Whether we are busy
12
* @var object source The object whose event initialized the request
16
* @var function Callback to execute after a successful request
17
* Used by PMA_commonFunctions from common.js
19
_callback: function () {},
21
* @var bool _debug Makes noise in your Firebug console
25
* @var object $msgbox A reference to a jQuery object that links to a message
26
* box that is generated by PMA_ajaxShowMessage()
30
* Given the filename of a script, returns a hash to be
31
* used to refer to all the events registered for the file
33
* @param string key The filename for which to get the event name
38
/* http://burtleburtle.net/bob/hash/doobs.html#one */
40
var len = key.length, hash=0, i=0;
42
hash += key.charCodeAt(i);
49
return Math.abs(hash);
52
* Registers an onload event for a file
54
* @param string file The filename for which to register the event
55
* @param function func The function to execute when the page is ready
57
* @return self For chaining
59
registerOnload: function (file, func) {
60
var eventName = 'onload_' + AJAX.hash(file);
61
$(document).bind(eventName, func);
62
this._debug && console.log(
63
// no need to translate
64
"Registered event " + eventName + " for file " + file
69
* Registers a teardown event for a file. This is useful to execute functions
70
* that unbind events for page elements that are about to be removed.
72
* @param string file The filename for which to register the event
73
* @param function func The function to execute when
74
* the page is about to be torn down
76
* @return self For chaining
78
registerTeardown: function (file, func) {
79
var eventName = 'teardown_' + AJAX.hash(file);
80
$(document).bind(eventName, func);
81
this._debug && console.log(
82
// no need to translate
83
"Registered event " + eventName + " for file " + file
88
* Called when a page has finished loading, once for every
89
* file that registered to the onload event of that file.
91
* @param string file The filename for which to fire the event
95
fireOnload: function (file) {
96
var eventName = 'onload_' + AJAX.hash(file);
97
$(document).trigger(eventName);
98
this._debug && console.log(
99
// no need to translate
100
"Fired event " + eventName + " for file " + file
104
* Called just before a page is torn down, once for every
105
* file that registered to the teardown event of that file.
107
* @param string file The filename for which to fire the event
111
fireTeardown: function (file) {
112
var eventName = 'teardown_' + AJAX.hash(file);
113
$(document).triggerHandler(eventName);
114
this._debug && console.log(
115
// no need to translate
116
"Fired event " + eventName + " for file " + file
120
* Event handler for clicks on links and form submissions
122
* @param object e Event data
126
requestHandler: function (event) {
127
// In some cases we don't want to handle the request here and either
128
// leave the browser deal with it natively (e.g: file download)
129
// or leave an existing ajax event handler present elsewhere deal with it
130
var href = $(this).attr('href');
131
if (event.shiftKey || event.ctrlKey) {
133
} else if ($(this).attr('target')) {
135
} else if ($(this).hasClass('ajax') || $(this).hasClass('disableAjax')) {
137
} else if (href && href.match(/^#/)) {
139
} else if (href && href.match(/^mailto/)) {
141
} else if ($(this).hasClass('ui-datepicker-next') ||
142
$(this).hasClass('ui-datepicker-prev')
147
if (typeof event != 'undefined') {
148
event.preventDefault();
149
event.stopImmediatePropagation();
151
if (AJAX.active == true) {
152
// Silently bail out, there is already a request in progress.
153
// TODO: save a reference to the request and cancel the old request
154
// when the user requests something else. Something like this is
155
// already implemented in the PMA_fastFilter object in navigation.js
159
AJAX.source = $(this);
161
$('html, body').animate({scrollTop: 0}, 'fast');
163
var isLink = !! href || false;
164
var url = isLink ? href : $(this).attr('action');
165
var params = 'ajax_request=true&ajax_page_request=true';
167
params += '&' + $(this).serialize();
169
// Add a list of menu hashes that we have in the cache to the request
170
params += AJAX.cache.menus.getRequestParam();
172
AJAX._debug && console.log("Loading: " + url); // no need to translate
176
AJAX.$msgbox = PMA_ajaxShowMessage();
177
$.get(url, params, AJAX.responseHandler);
180
* Manually fire the onsubmit event for the form, if any.
181
* The event was saved in the jQuery data object by an onload
182
* handler defined below. Workaround for bug #3583316
184
var onsubmit = $(this).data('onsubmit');
185
// Submit the request if there is no onsubmit handler
186
// or if it returns a value that evaluates to true
187
if (typeof onsubmit !== 'function' || onsubmit.apply(this, [event])) {
189
AJAX.$msgbox = PMA_ajaxShowMessage();
190
$.post(url, params, AJAX.responseHandler);
195
* Called after the request that was initiated by this.requestHandler()
196
* has completed successfully or with a caught error. For completely
197
* failed requests or requests with uncaught errors, see the .ajaxError
198
* handler at the bottom of this file.
200
* To refer to self use 'AJAX', instead of 'this' as this function
201
* is called in the jQuery context.
203
* @param object e Event data
207
responseHandler: function (data) {
209
$table_clone = false;
210
PMA_ajaxRemoveMessage(AJAX.$msgbox);
212
if (data._redirect) {
213
PMA_ajaxShowMessage(data._redirect, false);
218
AJAX.scriptHandler.reset(function () {
219
if (data._reloadNavigation) {
220
PMA_reloadNavigation();
222
if (data._reloadQuerywindow) {
223
var params = data._reloadQuerywindow;
224
PMA_querywindow.reload(
230
if (data._focusQuerywindow) {
231
PMA_querywindow.focus(
232
data._focusQuerywindow
236
$('title').replaceWith(data._title);
239
AJAX.cache.menus.replace(data._menu);
240
AJAX.cache.menus.add(data._menuHash, data._menu);
241
} else if (data._menuHash) {
242
AJAX.cache.menus.replace(AJAX.cache.menus.get(data._menuHash));
245
// Remove all containers that may have
246
// been added outside of #page_content
248
.not('#pma_navigation')
249
.not('#floating_menubar')
250
.not('#goto_pagetop')
251
.not('#page_content')
253
.not('#session_debug')
255
// Replace #page_content with new content
256
if (data.message && data.message.length > 0) {
257
$('#page_content').replaceWith(
258
"<div id='page_content'>" + data.message + "</div>"
262
if (data._selflink) {
263
$('#selflink > a').attr('href', data._selflink);
266
AJAX.scriptHandler.load(data._scripts);
268
if (data._selflink && data._scripts && data._menuHash && data._params) {
274
AJAX.source.attr('rel')
278
PMA_commonParams.setAll(data._params);
280
if (data._displayMessage) {
281
$('#page_content').prepend(data._displayMessage);
284
$('#pma_errors').remove();
286
$('<div/>', {id:'pma_errors'})
287
.insertAfter('#selflink')
288
.append(data._errors);
291
if (typeof AJAX._callback === 'function') {
292
AJAX._callback.call();
294
AJAX._callback = function () {};
297
PMA_ajaxShowMessage(data.error, false);
302
* This object is in charge of downloading scripts,
303
* keeping track of what's downloaded and firing
304
* the onload event for them when the page is ready.
308
* @var array _scripts The list of files already downloaded
312
* @var array _scriptsToBeLoaded The list of files that
313
* need to be downloaded
315
_scriptsToBeLoaded: [],
317
* @var array _scriptsToBeFired The list of files for which
318
* to fire the onload event
320
_scriptsToBeFired: [],
322
* Records that a file has been downloaded
324
* @param string file The filename
325
* @param string fire Whether this file will be registering
326
* onload/teardown events
328
* @return self For chaining
330
add: function (file, fire) {
331
this._scripts.push(file);
333
// Record whether to fire any events for the file
334
// This is necessary to correctly tear down the initial page
335
this._scriptsToBeFired.push(file);
340
* Download a list of js files in one request
342
* @param array files An array of filenames and flags
346
load: function (files) {
348
self._scriptsToBeLoaded = [];
349
self._scriptsToBeFired = [];
350
for (var i in files) {
351
self._scriptsToBeLoaded.push(files[i].name);
353
self._scriptsToBeFired.push(files[i].name);
356
// Generate a request string
358
var needRequest = false;
359
for (var index in self._scriptsToBeLoaded) {
360
var script = self._scriptsToBeLoaded[index];
361
// Only for scripts that we don't already have
362
if ($.inArray(script, self._scripts) == -1) {
365
request.push("scripts[]=" + script);
368
// Download the composite js file, if necessary
371
url: "js/get_scripts.js.php?" + request.join("&"),
373
success: function () {
383
* Called whenever all files are loaded
388
for (var i in this._scriptsToBeFired) {
389
AJAX.fireOnload(this._scriptsToBeFired[i]);
394
* Fires all the teardown event handlers for the current page
395
* and rebinds all forms and links to the request handler
397
* @param function callback The callback to call after resetting
401
reset: function (callback) {
402
for (var i in this._scriptsToBeFired) {
403
AJAX.fireTeardown(this._scriptsToBeFired[i]);
405
this._scriptsToBeFired = [];
407
* Re-attach a generic event handler to clicks
408
* on pages and submissions of forms
410
$('a').die('click').live('click', AJAX.requestHandler);
411
$('form').die('submit').live('submit', AJAX.requestHandler);
419
* Here we register a function that will remove the onsubmit event from all
420
* forms that will be handled by the generic page loader. We then save this
421
* event handler in the "jQuery data", so that we can fire it up later in
422
* AJAX.requestHandler().
426
AJAX.registerOnload('functions.js', function () {
427
// Registering the onload event for functions.js
428
// ensures that it will be fired for all pages
429
$('form').not('.ajax').not('.disableAjax').each(function () {
430
if ($(this).attr('onsubmit')) {
431
$(this).data('onsubmit', this.onsubmit).attr('onsubmit', '');
437
* An implementation of a client-side page cache.
438
* This object also uses the cache to provide a simple microhistory,
439
* that is the ability to use the back and forward buttons in the browser
443
* @var int The maximum number of pages to keep in the cache
447
* @var object A hash used to prime the cache with data about the initially
448
* loaded page. This is set in the footer, and then loaded
449
* by a double-queued event further down this file.
453
* @var array Stores the content of the cached pages
457
* @var int The index of the currently loaded page
458
* This is used to know at which point in the history we are
462
* Saves a new page in the cache
464
* @param string hash The hash part of the url that is being loaded
465
* @param array scripts A list of scripts that is requured for the page
466
* @param string menu A hash that links to a menu stored
467
* in a dedicated menu cache
468
* @param array params A list of parameters used by PMA_commonParams()
469
* @param string rel A relationship to the current page:
470
* 'samepage': Forces the response to be treated as
471
* the same page as the current one
472
* 'newpage': Forces the response to be treated as
474
* undefined: Default behaviour, 'samepage' if the
475
* selflinks of the two pages are the same.
476
* 'newpage' otherwise
480
add: function (hash, scripts, menu, params, rel) {
481
if (this.pages.length > AJAX.cache.MAX) {
482
// Trim the cache, to the maximum number of allowed entries
483
// This way we will have a cached menu for every page
484
for (var i=0; i<this.pages.length-this.MAX; i++) {
485
delete this.pages[i];
488
while (this.current < this.pages.length) {
489
// trim the cache if we went back in the history
490
// and are now going forward again
493
if (rel === 'newpage' ||
495
typeof rel === 'undefined' && (
496
typeof this.pages[this.current - 1] === 'undefined'
498
this.pages[this.current - 1].hash !== hash
504
content: $('#page_content').html(),
506
selflink: $('#selflink').html(),
510
AJAX.setUrlHash(this.current, hash);
515
* Restores a page from the cache. This is called when the hash
516
* part of the url changes and it's structure appears to be valid
518
* @param string index Which page from the history to load
522
navigate: function (index) {
523
if (typeof this.pages[index] === 'undefined') {
525
'<div class="error">' + PMA_messages['strInvalidPage'] + '</div>',
530
var record = this.pages[index];
531
AJAX.scriptHandler.reset(function () {
532
$('#page_content').html(record.content);
533
$('#selflink').html(record.selflink);
534
AJAX.cache.menus.replace(AJAX.cache.menus.get(record.menu));
535
PMA_commonParams.setAll(record.params);
536
AJAX.scriptHandler.load(record.scripts);
537
AJAX.cache.current = ++index;
542
* Resaves the content of the current page in the cache.
543
* Necessary in order not to show the user some outdated version of the page
547
update: function () {
548
var page = this.pages[this.current - 1];
550
page.content = $('#page_content').html();
554
* @var object Dedicated menu cache
558
* Returns the number of items in an associative array
562
size: function(obj) {
565
if (obj.hasOwnProperty(key)) {
572
* @var hash Stores the content of the cached menus
576
* Saves a new menu in the cache
578
* @param string hash The hash (trimmed md5) of the menu to be saved
579
* @param string content The HTML code of the menu to be saved
583
add: function (hash, content) {
584
if (this.size(this.data) > AJAX.cache.MAX) {
585
// when the cache grows, we remove the oldest entry
586
var oldest, key, init = 0;
587
for (var i in this.data) {
589
if (! init || this.data[i].timestamp.getTime() < oldest.getTime()) {
590
oldest = this.data[i].timestamp;
596
delete this.data[key];
600
timestamp: new Date()
604
* Retrieves a menu given its hash
606
* @param string hash The hash of the menu to be retrieved
610
get: function (hash) {
611
if (this.data[hash]) {
612
return this.data[hash].content;
614
// This should never happen as long as the number of stored menus
615
// is larger or equal to the number of pages in the page cache
620
* Prepares part of the parameter string used during page requests,
621
* this is necessary to tell the server which menus we have in the cache
625
getRequestParam: function () {
628
for (var i in this.data) {
631
var menuHashesParam = menuHashes.join('-');
632
if (menuHashesParam) {
633
param = '&menuHashes=' + menuHashesParam;
638
* Replaces the menu with new content
642
replace: function (content) {
643
$('#floating_menubar').html(content)
644
// Remove duplicate wrapper
645
// TODO: don't send it in the response
646
.children().first().remove();
647
$('#topmenu').menuResizer(PMA_mainMenuResizerCallback);
653
* URL hash management module.
654
* Allows direct bookmarking and microhistory.
656
AJAX.setUrlHash = (function (jQuery, window) {
659
* Indictaes whether we have already completed
660
* the initialisation of the hash
666
* Stores a hash that needed to be set when we were not ready
672
* Flag to indicate if the change of hash was triggered
673
* by a user pressing the back/forward button or if
674
* the change was triggered internally
678
var userChange = true;
680
// Fix favicon disappearing in Firefox when setting location.hash
681
function resetFavicon() {
682
if (jQuery.browser.mozilla) {
683
// Move the link tags for the favicon to the bottom
684
// of the head element to force a reload of the favicon
685
$('head > link[href=favicon\\.ico]').appendTo('head');
690
* Sets the hash part of the URL
694
function setUrlHash(index, hash) {
697
* Setting hash leads to reload in webkit:
698
* http://www.quirksmode.org/bugreports/archives/2005/05/Safari_13_visual_anomaly_with_windowlocationhref.html
700
* so we expect that users are not running an ancient Safari version
705
window.location.hash = "PMAURL-" + index + ":" + hash;
708
savedHash = "PMAURL-" + index + ":" + hash;
712
* Start initialisation
714
if (window.location.hash.substring(0, 8) == '#PMAURL-') {
715
// We have a valid hash, let's redirect the user
716
// to the page that it's pointing to
717
window.location = window.location.hash.substring(
718
window.location.hash.indexOf(':') + 1
721
// We don't have a valid hash, so we'll set it up
722
// when the page finishes loading
724
/* Check if we should set URL */
725
if (savedHash != "") {
726
window.location.hash = savedHash;
730
// Indicate that we're done initialising
735
* Register an event handler for when the url hash changes
738
jQuery(window).hashchange(function () {
739
if (userChange === false) {
740
// Ignore internally triggered hash changes
742
} else if (/^#PMAURL-\d+:/.test(window.location.hash)) {
743
// Change page if the hash changed was triggered by a user action
744
var index = window.location.hash.substring(
745
8, window.location.hash.indexOf(':')
747
AJAX.cache.navigate(index);
752
* Publicly exposes a reference to the otherwise private setUrlHash function
758
* Page load event handler
761
// Add the menu from the initial page into the cache
762
// The cache primer is set by the footer class
763
if (AJAX.cache.primer.url) {
764
AJAX.cache.menus.add(
765
AJAX.cache.primer.menuHash,
767
.append('<div></div>')
768
.append($('#serverinfo').clone())
769
.append($('#topmenucontainer').clone())
774
// Queue up this event twice to make sure that we get a copy
775
// of the page after all other onload events have been fired
776
if (AJAX.cache.primer.url) {
778
AJAX.cache.primer.url,
779
AJAX.cache.primer.scripts,
780
AJAX.cache.primer.menuHash
787
* Attach a generic event handler to clicks
788
* on pages and submissions of forms
790
$('a').live('click', AJAX.requestHandler);
791
$('form').live('submit', AJAX.requestHandler);
794
* Gracefully handle fatal server errors
795
* (e.g: 500 - Internal server error)
797
$(document).ajaxError(function(event, request, settings){
798
if (request.status !== 0) { // Don't handle aborted requests
799
var errorCode = $.sprintf(PMA_messages['strErrorCode'], request.status);
800
var errorText = $.sprintf(PMA_messages['strErrorText'], request.statusText);
802
'<div class="error">'
803
+ PMA_messages['strErrorProcessingRequest']
804
+ '<div>' + errorCode + '</div>'
805
+ '<div>' + errorText + '</div>'