[ Index ] |
PHP Cross Reference of phpBB-3.3.14-deutsch |
[Summary view] [Print] [Text view]
1 /** 2 * Installer's AJAX frontend handler 3 */ 4 5 (function($) { // Avoid conflicts with other libraries 6 'use strict'; 7 8 // Installer variables 9 var pollTimer = null; 10 var nextReadPosition = 0; 11 var progressBarTriggered = false; 12 var progressTimer = null; 13 var currentProgress = 0; 14 var refreshRequested = false; 15 var transmissionOver = false; 16 var statusCount = 0; 17 18 // Template related variables 19 var $contentWrapper = $('.install-body').find('.main'); 20 21 // Intercept form submits 22 interceptFormSubmit($('#install_install')); 23 24 /** 25 * Creates an XHR object 26 * 27 * jQuery cannot be used as the response is streamed, and 28 * as of now, jQuery does not provide access to the response until 29 * the connection is not closed. 30 * 31 * @return XMLHttpRequest 32 */ 33 function createXhrObject() { 34 return new XMLHttpRequest(); 35 } 36 37 /** 38 * Displays error, warning and log messages 39 * 40 * @param type 41 * @param messages 42 */ 43 function addMessage(type, messages) { 44 // Get message containers 45 var $errorContainer = $('#error-container'); 46 var $warningContainer = $('#warning-container'); 47 var $logContainer = $('#log-container'); 48 49 var $title, $description, $msgElement, arraySize = messages.length; 50 for (var i = 0; i < arraySize; i++) { 51 $msgElement = $('<div />'); 52 $title = $('<strong />'); 53 $title.text(messages[i].title); 54 $msgElement.append($title); 55 56 if (messages[i].hasOwnProperty('description')) { 57 $description = $('<p />'); 58 $description.html(messages[i].description); 59 $msgElement.append($description); 60 } 61 62 switch (type) { 63 case 'error': 64 $msgElement.addClass('errorbox'); 65 $errorContainer.append($msgElement); 66 break; 67 case 'warning': 68 $msgElement.addClass('warningbox'); 69 $warningContainer.append($msgElement); 70 break; 71 case 'log': 72 $msgElement.addClass('log'); 73 $logContainer.prepend($msgElement); 74 $logContainer.addClass('show_log_container'); 75 break; 76 case 'success': 77 $msgElement.addClass('successbox'); 78 $errorContainer.prepend($msgElement); 79 break; 80 } 81 } 82 } 83 84 /** 85 * Render a download box 86 */ 87 function addDownloadBox(downloadArray) 88 { 89 var $downloadContainer = $('#download-wrapper'); 90 var $downloadBox, $title, $content, $link; 91 92 for (var i = 0; i < downloadArray.length; i++) { 93 $downloadBox = $('<div />'); 94 $downloadBox.addClass('download-box'); 95 96 $title = $('<strong />'); 97 $title.text(downloadArray[i].title); 98 $downloadBox.append($title); 99 100 if (downloadArray[i].hasOwnProperty('msg')) { 101 $content = $('<p />'); 102 $content.text(downloadArray[i].msg); 103 $downloadBox.append($content); 104 } 105 106 $link = $('<a />'); 107 $link.addClass('button1'); 108 $link.attr('href', downloadArray[i].href); 109 $link.text(downloadArray[i].download); 110 $downloadBox.append($link); 111 112 $downloadContainer.append($downloadBox); 113 } 114 } 115 116 /** 117 * Render update files' status 118 */ 119 function addUpdateFileStatus(fileStatus) 120 { 121 var $statusContainer = $('#file-status-wrapper'); 122 $statusContainer.html(fileStatus); 123 } 124 125 /** 126 * Displays a form from the response 127 * 128 * @param formHtml 129 */ 130 function addForm(formHtml) { 131 var $formContainer = $('#form-wrapper'); 132 $formContainer.html(formHtml); 133 var $form = $('#install_install'); 134 interceptFormSubmit($form); 135 } 136 137 /** 138 * Handles navigation status updates 139 * 140 * @param navObj 141 */ 142 function updateNavbarStatus(navObj) { 143 var navID, $stage, $stageListItem, $active; 144 $active = $('#activemenu'); 145 146 if (navObj.hasOwnProperty('finished')) { 147 // This should be an Array 148 var navItems = navObj.finished; 149 150 for (var i = 0; i < navItems.length; i++) { 151 navID = 'installer-stage-' + navItems[i]; 152 $stage = $('#' + navID); 153 $stageListItem = $stage.parent(); 154 155 if ($active.length && $active.is($stageListItem)) { 156 $active.removeAttr('id'); 157 } 158 159 $stage.addClass('completed'); 160 } 161 } 162 163 if (navObj.hasOwnProperty('active')) { 164 navID = 'installer-stage-' + navObj.active; 165 $stage = $('#' + navID); 166 $stageListItem = $stage.parent(); 167 168 if ($active.length && !$active.is($stageListItem)) { 169 $active.removeAttr('id'); 170 } 171 172 $stageListItem.attr('id', 'activemenu'); 173 } 174 } 175 176 /** 177 * Renders progress bar 178 * 179 * @param progressObject 180 */ 181 function setProgress(progressObject) { 182 var $statusText, $progressBar, $progressText, $progressFiller, $progressFillerText; 183 184 if (progressObject.task_name.length) { 185 if (!progressBarTriggered) { 186 // Create progress bar 187 var $progressBarWrapper = $('#progress-bar-container'); 188 189 // Create progress bar elements 190 $progressBar = $('<div />'); 191 $progressBar.attr('id', 'progress-bar'); 192 $progressText = $('<p />'); 193 $progressText.attr('id', 'progress-bar-text'); 194 $progressFiller = $('<div />'); 195 $progressFiller.attr('id', 'progress-bar-filler'); 196 $progressFillerText = $('<p />'); 197 $progressFillerText.attr('id', 'progress-bar-filler-text'); 198 199 $statusText = $('<p />'); 200 $statusText.attr('id', 'progress-status-text'); 201 202 $progressFiller.append($progressFillerText); 203 $progressBar.append($progressText); 204 $progressBar.append($progressFiller); 205 206 $progressBarWrapper.append($statusText); 207 $progressBarWrapper.append($progressBar); 208 209 $progressFillerText.css('width', $progressBar.width()); 210 211 progressBarTriggered = true; 212 } else if (progressObject.hasOwnProperty('restart')) { 213 clearInterval(progressTimer); 214 215 $progressFiller = $('#progress-bar-filler'); 216 $progressFillerText = $('#progress-bar-filler-text'); 217 $progressText = $('#progress-bar-text'); 218 $statusText = $('#progress-status-text'); 219 220 $progressText.text('0%'); 221 $progressFillerText.text('0%'); 222 $progressFiller.css('width', '0%'); 223 224 currentProgress = 0; 225 } else { 226 $statusText = $('#progress-status-text'); 227 } 228 229 // Update progress bar 230 $statusText.text(progressObject.task_name + '…'); 231 incrementProgressBar(Math.round(progressObject.task_num / progressObject.task_count * 100)); 232 } 233 } 234 235 // Set cookies 236 function setCookies(cookies) { 237 var cookie; 238 239 for (var i = 0; i < cookies.length; i++) { 240 // Set cookie name and value 241 cookie = encodeURIComponent(cookies[i].name) + '=' + encodeURIComponent(cookies[i].value); 242 // Set path 243 cookie += '; path=/'; 244 document.cookie = cookie; 245 } 246 } 247 248 // Redirects user 249 function redirect(url, use_ajax) { 250 if (use_ajax) { 251 resetPolling(); 252 253 var xhReq = createXhrObject(); 254 xhReq.open('GET', url, true); 255 xhReq.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); 256 xhReq.send(); 257 258 startPolling(xhReq); 259 } else { 260 window.location.href = url; 261 } 262 } 263 264 /** 265 * Parse messages from the response object 266 * 267 * @param messageJSON 268 */ 269 function parseMessage(messageJSON) { 270 $('#loading_indicator').css('display', 'none'); 271 var responseObject; 272 273 try { 274 responseObject = JSON.parse(messageJSON); 275 } catch (err) { 276 if (window.console) { 277 console.log('Failed to parse JSON object\n\nMessage: ' + err.message + '\n\nServer Response: ' + messageJSON); 278 } else { 279 alert('Failed to parse JSON object\n\nMessage: ' + err.message + '\n\nServer Response: ' + messageJSON); 280 } 281 282 resetPolling(); 283 return; 284 } 285 286 // Parse object 287 if (responseObject.hasOwnProperty('errors')) { 288 addMessage('error', responseObject.errors); 289 } 290 291 if (responseObject.hasOwnProperty('warnings')) { 292 addMessage('warning', responseObject.warnings); 293 } 294 295 if (responseObject.hasOwnProperty('logs')) { 296 addMessage('log', responseObject.logs); 297 } 298 299 if (responseObject.hasOwnProperty('success')) { 300 addMessage('success', responseObject.success); 301 } 302 303 if (responseObject.hasOwnProperty('form')) { 304 addForm(responseObject.form); 305 } 306 307 if (responseObject.hasOwnProperty('progress')) { 308 setProgress(responseObject.progress); 309 } 310 311 if (responseObject.hasOwnProperty('download')) { 312 addDownloadBox(responseObject.download); 313 } 314 315 if (responseObject.hasOwnProperty('file_status')) { 316 addUpdateFileStatus(responseObject.file_status); 317 } 318 319 if (responseObject.hasOwnProperty('nav')) { 320 updateNavbarStatus(responseObject.nav); 321 } 322 323 if (responseObject.hasOwnProperty('cookies')) { 324 setCookies(responseObject.cookies); 325 } 326 327 if (responseObject.hasOwnProperty('refresh')) { 328 refreshRequested = true; 329 } 330 331 if (responseObject.hasOwnProperty('redirect')) { 332 redirect(responseObject.redirect.url, responseObject.redirect.use_ajax); 333 } 334 335 if (responseObject.hasOwnProperty('over')) { 336 if (responseObject.over) { 337 transmissionOver = true; 338 } 339 } 340 } 341 342 /** 343 * Processes status data 344 * 345 * @param status 346 */ 347 function processTimeoutResponse(status) { 348 if (statusCount === 12) { // 1 minute hard cap 349 status = 'fail'; 350 } 351 352 if (status === 'continue') { 353 refreshRequested = false; 354 doRefresh(); 355 } else if (status === 'running') { 356 statusCount++; 357 $('#loading_indicator').css('display', 'block'); 358 setTimeout(queryInstallerStatus, 5000); 359 } else { 360 $('#loading_indicator').css('display', 'none'); 361 addMessage('error', 362 [{ 363 title: installLang.title, 364 description: installLang.msg 365 }] 366 ); 367 } 368 } 369 370 /** 371 * Queries the installer's status 372 */ 373 function queryInstallerStatus() { 374 var url = $(location).attr('pathname'); 375 var lookUp = 'install/app.php'; 376 var position = url.indexOf(lookUp); 377 378 if (position === -1) { 379 lookUp = 'install'; 380 position = url.indexOf(lookUp); 381 382 if (position === -1) { 383 return false; 384 } 385 } 386 387 url = url.substring(0, position) + lookUp + '/installer/status'; 388 $.getJSON(url, function(data) { 389 processTimeoutResponse(data.status); 390 }); 391 } 392 393 /** 394 * Process updates in streamed response 395 * 396 * @param xhReq XHR object 397 */ 398 function pollContent(xhReq) { 399 var messages = xhReq.responseText; 400 var msgSeparator = '}\n\n'; 401 var unprocessed, messageEndIndex, endOfMessageIndex, message; 402 403 do { 404 unprocessed = messages.substring(nextReadPosition); 405 messageEndIndex = unprocessed.indexOf(msgSeparator); 406 407 if (messageEndIndex !== -1) { 408 endOfMessageIndex = messageEndIndex + msgSeparator.length; 409 message = unprocessed.substring(0, endOfMessageIndex); 410 parseMessage($.trim(message)); 411 nextReadPosition += endOfMessageIndex; 412 } 413 } while (messageEndIndex !== -1); 414 415 if (xhReq.readyState === 4) { 416 $('#loading_indicator').css('display', 'none'); 417 resetPolling(); 418 419 var timeoutDetected = !transmissionOver; 420 421 if (refreshRequested) { 422 refreshRequested = false; 423 doRefresh(); 424 } 425 426 if (timeoutDetected) { 427 statusCount = 0; 428 queryInstallerStatus(); 429 } 430 } 431 } 432 433 /** 434 * Animates the progress bar 435 * 436 * @param $progressText 437 * @param $progressFiller 438 * @param $progressFillerText 439 * @param progressLimit 440 */ 441 function incrementFiller($progressText, $progressFiller, $progressFillerText, progressLimit) { 442 if (currentProgress >= progressLimit || currentProgress >= 100) { 443 clearInterval(progressTimer); 444 return; 445 } 446 447 var $progressBar = $('#progress-bar'); 448 449 currentProgress++; 450 $progressFillerText.css('width', $progressBar.width()); 451 $progressFillerText.text(currentProgress + '%'); 452 $progressText.text(currentProgress + '%'); 453 $progressFiller.css('width', currentProgress + '%'); 454 } 455 456 /** 457 * Wrapper function for progress bar rendering and animating 458 * 459 * @param progressLimit 460 */ 461 function incrementProgressBar(progressLimit) { 462 var $progressFiller = $('#progress-bar-filler'); 463 var $progressFillerText = $('#progress-bar-filler-text'); 464 var $progressText = $('#progress-bar-text'); 465 var progressStart = $progressFiller.width() / $progressFiller.offsetParent().width() * 100; 466 currentProgress = Math.floor(progressStart); 467 468 clearInterval(progressTimer); 469 progressTimer = setInterval(function() { 470 incrementFiller($progressText, $progressFiller, $progressFillerText, progressLimit); 471 }, 10); 472 } 473 474 /** 475 * Resets the polling timer 476 */ 477 function resetPolling() { 478 clearInterval(pollTimer); 479 nextReadPosition = 0; 480 } 481 482 /** 483 * Sets up timer for processing the streamed HTTP response 484 * 485 * @param xhReq 486 */ 487 function startPolling(xhReq) { 488 resetPolling(); 489 transmissionOver = false; 490 pollTimer = setInterval(function () { 491 pollContent(xhReq); 492 }, 250); 493 } 494 495 /** 496 * Refresh page 497 */ 498 function doRefresh() { 499 resetPolling(); 500 501 var xhReq = createXhrObject(); 502 xhReq.open('GET', $(location).attr('pathname'), true); 503 xhReq.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); 504 xhReq.send(); 505 506 startPolling(xhReq); 507 } 508 509 /** 510 * Renders the AJAX UI layout 511 */ 512 function setupAjaxLayout() { 513 progressBarTriggered = false; 514 515 // Clear content 516 $contentWrapper.html(''); 517 518 var $header = $('<div />'); 519 $header.attr('id', 'header-container'); 520 $contentWrapper.append($header); 521 522 var $description = $('<div />'); 523 $description.attr('id', 'description-container'); 524 $contentWrapper.append($description); 525 526 var $errorContainer = $('<div />'); 527 $errorContainer.attr('id', 'error-container'); 528 $contentWrapper.append($errorContainer); 529 530 var $warningContainer = $('<div />'); 531 $warningContainer.attr('id', 'warning-container'); 532 $contentWrapper.append($warningContainer); 533 534 var $progressContainer = $('<div />'); 535 $progressContainer.attr('id', 'progress-bar-container'); 536 $contentWrapper.append($progressContainer); 537 538 var $logContainer = $('<div />'); 539 $logContainer.attr('id', 'log-container'); 540 $contentWrapper.append($logContainer); 541 542 var $installerContentWrapper = $('<div />'); 543 $installerContentWrapper.attr('id', 'content-container'); 544 $contentWrapper.append($installerContentWrapper); 545 546 var $installerDownloadWrapper = $('<div />'); 547 $installerDownloadWrapper.attr('id', 'download-wrapper'); 548 $installerContentWrapper.append($installerDownloadWrapper); 549 550 var $updaterFileStatusWrapper = $('<div />'); 551 $updaterFileStatusWrapper.attr('id', 'file-status-wrapper'); 552 $installerContentWrapper.append($updaterFileStatusWrapper); 553 554 var $formWrapper = $('<div />'); 555 $formWrapper.attr('id', 'form-wrapper'); 556 $installerContentWrapper.append($formWrapper); 557 558 var $spinner = $('<div />'); 559 $spinner.attr('id', 'loading_indicator'); 560 $spinner.html(' '); 561 $contentWrapper.append($spinner); 562 } 563 564 // Submits a form 565 function submitForm($form, $submitBtn) { 566 $form.css('display', 'none'); 567 568 var xhReq = createXhrObject(); 569 xhReq.open('POST', $form.attr('action'), true); 570 xhReq.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); 571 xhReq.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); 572 xhReq.send(getFormFields($form, $submitBtn)); 573 574 // Disable language selector 575 $('#language_selector :input, label').css('display', 'none'); 576 577 // Clear content 578 setupAjaxLayout(); 579 $('#loading_indicator').css('display', 'block'); 580 581 startPolling(xhReq); 582 } 583 584 /** 585 * Add submit button to the POST information 586 * 587 * @param $form 588 * @param $submitBtn 589 * 590 * @returns {*} 591 */ 592 function getFormFields($form, $submitBtn) { 593 var formData = $form.serialize(); 594 formData += ((formData.length) ? '&' : '') + encodeURIComponent($submitBtn.attr('name')) + '='; 595 formData += encodeURIComponent($submitBtn.attr('value')); 596 597 return formData; 598 } 599 600 /** 601 * Intercept form submit events and determine the submit button used 602 * 603 * @param $form 604 */ 605 function interceptFormSubmit($form) { 606 if (!$form.length) { 607 return; 608 } 609 610 $form.find(':submit').bind('click', function (event) { 611 event.preventDefault(); 612 submitForm($form, $(this)); 613 }); 614 } 615 })(jQuery); // Avoid conflicts with other libraries
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Mon Nov 25 19:05:08 2024 | Cross-referenced by PHPXref 0.7.1 |