1/* global phpbb */ 2 3/** 4* phpBB3 forum functions 5*/ 6var styleConfig = { 7 staticNavigation: true, 8 staticNavigationMinWidth: 500, 9 staticNavigationMinHeight: 400, 10 extendPosterProfile: true, 11 collapseForums: true 12}; 13 14/** 15* Find a member 16*/ 17function find_username(url) { 18 'use strict'; 19 20 popup(url, 760, 570, '_usersearch'); 21 return false; 22} 23 24/** 25* Window popup 26*/ 27function popup(url, width, height, name) { 28 'use strict'; 29 30 if (!name) { 31 name = '_popup'; 32 } 33 34 window.open(url.replace(/&/g, '&'), name, 'height=' + height + ',resizable=yes,scrollbars=yes, width=' + width); 35 return false; 36} 37 38/** 39* Jump to page 40*/ 41function pageJump(item) { 42 'use strict'; 43 44 var page = parseInt(item.val(), 10), 45 perPage = item.attr('data-per-page'), 46 baseUrl = item.attr('data-base-url'), 47 startName = item.attr('data-start-name'); 48 49 if (page !== null && !isNaN(page) && page === Math.floor(page) && page > 0) { 50 if (baseUrl.indexOf('?') === -1) { 51 document.location.href = baseUrl + '?' + startName + '=' + ((page - 1) * perPage); 52 } else { 53 document.location.href = baseUrl.replace(/&/g, '&') + '&' + startName + '=' + ((page - 1) * perPage); 54 } 55 } 56} 57 58/** 59* Mark/unmark checklist 60* id = ID of parent container, name = name prefix, state = state [true/false] 61*/ 62function marklist(id, name, state) { 63 'use strict'; 64 65 jQuery('#' + id + ' input[type=checkbox][name]').each(function() { 66 var $this = jQuery(this); 67 if ($this.attr('name').substr(0, name.length) === name && !$this.prop('disabled')) { 68 $this.prop('checked', state); 69 } 70 }); 71} 72 73/** 74* Resize viewable area for attached image or topic review panel (possibly others to come) 75* e = element 76*/ 77function viewableArea(e, itself) { 78 'use strict'; 79 80 if (!e) { 81 return; 82 } 83 84 if (!itself) { 85 e = e.parentNode; 86 } 87 88 if (!e.vaHeight) { 89 // Store viewable area height before changing style to auto 90 e.vaHeight = e.offsetHeight; 91 e.vaMaxHeight = e.style.maxHeight; 92 e.style.height = 'auto'; 93 e.style.maxHeight = 'none'; 94 e.style.overflow = 'visible'; 95 } else { 96 // Restore viewable area height to the default 97 e.style.height = e.vaHeight + 'px'; 98 e.style.overflow = 'auto'; 99 e.style.maxHeight = e.vaMaxHeight; 100 e.vaHeight = false; 101 } 102} 103 104/** 105* Alternate display of subPanels 106*/ 107jQuery(function($) { 108 'use strict'; 109 110 $('.sub-panels').each(function() { 111 112 var $childNodes = $('a[data-subpanel]', this), 113 panels = $childNodes.map(function () { 114 return this.getAttribute('data-subpanel'); 115 }), 116 showPanel = this.getAttribute('data-show-panel'); 117 118 if (panels.length) { 119 activateSubPanel(showPanel, panels); 120 $childNodes.click(function () { 121 activateSubPanel(this.getAttribute('data-subpanel'), panels); 122 return false; 123 }); 124 } 125 }); 126}); 127 128/** 129* Activate specific subPanel 130*/ 131function activateSubPanel(p, panels) { 132 'use strict'; 133 134 var i, showPanel; 135 136 if (typeof p === 'string') { 137 showPanel = p; 138 } 139 $('input[name="show_panel"]').val(showPanel); 140 141 if (typeof panels === 'undefined') { 142 panels = jQuery('.sub-panels a[data-subpanel]').map(function() { 143 return this.getAttribute('data-subpanel'); 144 }); 145 } 146 147 for (i = 0; i < panels.length; i++) { 148 jQuery('#' + panels[i]).css('display', panels[i] === showPanel ? 'block' : 'none'); 149 jQuery('#' + panels[i] + '-tab').toggleClass('activetab', panels[i] === showPanel); 150 } 151} 152 153function selectCode(a) { 154 'use strict'; 155 156 // Get ID of code block 157 var e = a.parentNode.parentNode.getElementsByTagName('CODE')[0]; 158 var s, r; 159 160 // Not IE and IE9+ 161 if (window.getSelection) { 162 s = window.getSelection(); 163 // Safari and Chrome 164 if (s.setBaseAndExtent) { 165 var l = (e.innerText.length > 1) ? e.innerText.length - 1 : 1; 166 try { 167 s.setBaseAndExtent(e, 0, e, l); 168 } catch (error) { 169 r = document.createRange(); 170 r.selectNodeContents(e); 171 s.removeAllRanges(); 172 s.addRange(r); 173 } 174 } 175 // Firefox and Opera 176 else { 177 // workaround for bug # 42885 178 if (window.opera && e.innerHTML.substring(e.innerHTML.length - 4) === '<BR>') { 179 e.innerHTML = e.innerHTML + ' '; 180 } 181 182 r = document.createRange(); 183 r.selectNodeContents(e); 184 s.removeAllRanges(); 185 s.addRange(r); 186 } 187 } 188 // Some older browsers 189 else if (document.getSelection) { 190 s = document.getSelection(); 191 r = document.createRange(); 192 r.selectNodeContents(e); 193 s.removeAllRanges(); 194 s.addRange(r); 195 } 196 // IE 197 else if (document.selection) { 198 r = document.body.createTextRange(); 199 r.moveToElementText(e); 200 r.select(); 201 } 202} 203 204var inAutocomplete = false;
205var lastKeyEntered = ''; 206 207/** 208* Check event key 209*/ 210function phpbbCheckKey(event) { 211 'use strict'; 212 213 // Keycode is array down or up? 214 if (event.keyCode && (event.keyCode === 40 || event.keyCode === 38)) { 215 inAutocomplete = true; 216 } 217 218 // Make sure we are not within an "autocompletion" field 219 if (inAutocomplete) { 220 // If return pressed and key changed we reset the autocompletion 221 if (!lastKeyEntered || lastKeyEntered === event.which) { 222 inAutocomplete = false; 223 return true; 224 } 225 } 226 227 // Keycode is not return, then return. ;) 228 if (event.which !== 13) { 229 lastKeyEntered = event.which; 230 return true; 231 } 232 233 return false; 234} 235 236/** 237* Apply onkeypress event for forcing default submit button on ENTER key press 238*/ 239jQuery(function($) { 240 'use strict'; 241 242 $('form input[type=text], form input[type=password]').on('keypress', function (e) { 243 var defaultButton = $(this).parents('form').find('input[type=submit].default-submit-action'); 244 245 if (!defaultButton || defaultButton.length <= 0) { 246 return true; 247 } 248 249 if (phpbbCheckKey(e)) { 250 return true; 251 } 252 253 if ((e.which && e.which === 13) || (e.keyCode && e.keyCode === 13)) { 254 defaultButton.click(); 255 return false; 256 } 257 258 return true; 259 }); 260}); 261 262/** 263* Functions for user search popup 264*/ 265function insertUser(formId, value) { 266 'use strict'; 267 268 var $form = jQuery(formId), 269 formName = $form.attr('data-form-name'), 270 fieldName = $form.attr('data-field-name'), 271 item = opener.document.forms[formName][fieldName]; 272 273 if (item.value.length && item.type === 'textarea') { 274 value = item.value + '\n' + value; 275 } 276 277 item.value = value; 278} 279 280function insert_marked_users(formId, users) { 281 'use strict'; 282 283 for (var i = 0; i < users.length; i++) { 284 if (users[i].checked) { 285 insertUser(formId, users[i].value); 286 } 287 } 288 289 window.close(); 290} 291 292function insert_single_user(formId, user) { 293 'use strict'; 294 295 insertUser(formId, user); 296 window.close(); 297} 298 299/** 300* Resize poster profile block 301*/ 302function adjustPosterProfile(postbody) { 303 var profile = postbody.parent().prev(), 304 post = profile.parent(), 305 resized = profile.hasClass('resized'); 306 307 function unresize() { 308 profile.removeClass('resized').css('min-height', ''); 309 } 310 311 if (post.width() < (profile.width() + postbody.width())) { 312 if (resized) { 313 unresize(); 314 } 315 return false; 316 } 317 318 if (resized) { 319 profile.css('min-height', ''); 320 } 321 profile.css('min-height', Math.floor(postbody.height()) + 'px').addClass('resized'); 322} 323 324/** 325* Responsive navigation 326*/ 327function checkNavigation(force) 328{ 329 function init(nav) 330 { 331 nav.responsive = false; 332 nav.lastWidth = 0; 333 nav.itemCount = 0; 334 335 // Copy children items 336 nav.contents = nav.menu.find('.dropdown-contents:first'); 337 nav.canToggle = $(); 338 nav.noToggle = $(); 339 nav.contents.children('.separator:last-child').hide(); 340 nav.items = nav.lists.children().not(nav.menu).each(function(i) { 341 var $this = $(this), 342 cloneClass; 343 344 if ($this.is('.not-responsive, .responsive-menu, .dropdown-container, .selected') || $this.attr('data-skip-responsive') == 'true') { 345 $this.attr('data-responsive-index', -1); 346 nav.noToggle = nav.noToggle.add($this); 347 return; 348 } 349 350 cloneClass = ( 351 $this.attr('data-responsive-class') === undefined ? 352 ($this.hasClass('small-icon') ? $this.attr('class') : '') : 353 $this.attr('data-responsive-class') 354 ) + ' responsive-index-' + i; 355 356 nav.contents.append( 357 $this.clone(true).attr('class', cloneClass).addClass('responsive-clone').removeClass('tab') 358 ); 359 360 $this.addClass('responsive-cloned-item').attr('data-clone-index', i); 361 nav.canToggle = nav.canToggle.add($this); 362 nav.itemCount ++; 363 }); 364 nav.contents.find('a.nav-link').removeClass('nav-link'); 365 nav.responsiveClones = nav.contents.children('.responsive-clone').hide(); 366 367 nav.initialized = true; 368 } 369 370 function check(nav, force) 371 { 372 var containerWidth, total, width, menuWidth, hiding; 373 374 // Setup navigation 375 if (!nav.initialized) { 376 init(nav); 377 force = true; 378 } 379 380 if (!nav.itemCount) { 381 // Nothing to hide 382 return; 383 } 384 385 // Check width 386 containerWidth = nav.container.width(); 387 if (!force && containerWidth == nav.lastWidth) { 388 return; 389 } 390 nav.lastWidth = containerWidth; 391 392 // Show all items 393 if (nav.responsive) { 394 nav.canToggle.show(); 395 nav.responsiveClones.hide(); 396 nav.menu.removeClass('showing-responsive-menu'); 397 if (!nav.alwaysShowMenu) { 398 nav.menu.show(); 399 } 400 } 401 nav.responsive = false;
402 menuWidth = nav.menu.outerWidth(true); 403 width = menuWidth; 404 405 // Count width of all items that cannot be hidden 406 nav.noToggle.each(function() { 407 var $this = $(this); 408 if ($this.is(':visible')) { 409 width += $this.outerWidth(true); 410 } 411 }); 412 413 // Test all other items 414 hiding = (width >= containerWidth); 415 nav.canToggle.each(function() { 416 var $this = $(this), 417 itemWidth, margin; 418 419 if (!$this.is(':visible')) { 420 return; 421 } 422 423 if (!hiding) { 424 itemWidth = $this.outerWidth(true); 425 if (!itemWidth) { 426 $this.hide(); 427 return; 428 } 429 430 width += itemWidth; 431 if (width >= containerWidth) { 432 hiding = true; 433 } 434 } 435 436 if (hiding) { 437 $this.hide(); 438 nav.responsiveClones.filter('.responsive-index-' + $this.attr('data-clone-index')).show(); 439 } 440 }); 441 442 nav.responsive = hiding; 443 if (!hiding && !nav.alwaysShowMenu) { 444 nav.menu.hide(); 445 } 446 else if (hiding) { 447 nav.menu.addClass('showing-responsive-menu'); 448 } 449 } 450 451 for (var i=0; i<styleConfig._responsiveNavigation.length; i++) { 452 check(styleConfig._responsiveNavigation[i], force); 453 } 454} 455 456function initResponsiveNavigation() 457{ 458 styleConfig._responsiveNavigation = []; 459 460 $('.nav-tabs, .navbar.secondary').each(function() { 461 var $this = $(this), 462 lists = $this.children('ul'), 463 menu = lists.children('.responsive-menu:first'), 464 alwaysShowMenu = (menu.length > 0); 465 466 // Create empty hidden menu 467 if (!menu.length) { 468 if ($this.is('.nav-tabs')) { 469 // Something went wrong - main menu must have responsive menu 470 return; 471 } 472 // Secondary menu 473 lists.eq(0).prepend('<li class="responsive-menu dropdown-container" style="display: none;"><a href="#" class="dropdown-trigger dropdown-toggle">...</a>' + 474 '<div class="dropdown hidden">' + 475 '<div class="pointer"><div class="pointer-inner"></div></div>' + 476 '<ul class="dropdown-contents" /></ul>' + 477 '</div>' + 478 '</li>'); 479 menu = lists.children('.responsive-menu:first'); 480 phpbb.registerDropdown(menu.find('.dropdown-toggle'), menu.find('.dropdown')); 481 } 482 483 styleConfig._responsiveNavigation.push({ 484 container: $this, 485 lists: lists, 486 menu: menu, 487 initialized: false, 488 alwaysShowMenu: alwaysShowMenu 489 }); 490 }); 491} 492 493/** 494* Parse document block 495*/ 496function parseDocument($container) { 497 'use strict'; 498 499 var test = document.createElement('div'), 500 oldBrowser = (typeof test.style.borderRadius === 'undefined'), 501 $body = $('body'); 502 503 /** 504 * Change stuff for extensions 505 */ 506 $('#top_five.forabg').removeClass('forabg').addClass('forumbg'); 507 508 /** 509 * Adjust navigation tabs 510 */ 511 $container.find('.nav-tabs').each(function() { 512 var tabs = $(this).children().children(); 513 514 // Fix tabs structure 515 tabs.not('.tab').each(function() { 516 var tab = $(this), 517 className = tab.attr('class'), 518 i; 519 520 className = className ? className.split(' ') : ''; 521 tab.attr('class', 'tab'); 522 for (i=0; i<className.length; i++) { 523 if (className[i].substr(0, 5) == 'icon-') { 524 tab.addClass(className[i].substr(5)); 525 } 526 } 527 }).children(':first-child').addClass('nav-link'); 528 529 // Tooltips for tabs 530 tabs.each(function() { 531 var $this = $(this), 532 title = ''; 533 if (!$this.attr('title')) { 534 title = $this.children('.nav-link').text().trim(); 535 if (!title.length) return; 536 537 $this.children('.nav-link + strong').each(function() { 538 title += ' (' + $(this).text().trim() + ')'; 539 }); 540 $this.attr('title', title); 541 } 542 }); 543 }); 544 545 /** 546 * Switch selected tab 547 */ 548 $container.find('.nav-tabs[data-current-page]').each(function() { 549 var tabs = $(this), 550 current = tabs.attr('data-current-page'), 551 found = false, 552 content, classes, i, key; 553 554 $('.tab[data-select-match]', this).each(function() { 555 var matches = $(this).attr('data-select-match').split(','), 556 i, match, item; 557 558 for (i=0; i<matches.length; i++) { 559 match = matches[i].trim(); 560 if (current.indexOf(match) != -1) { 561 // Found a match! 562 item = $(this); 563 if (!item.hasClass('selected')) { 564 tabs.find('.tab.selected').removeClass('selected'); 565 item.addClass('selected'); 566 } 567 found = true; 568 return false;
569 } 570 } 571 }); 572 573 // Check for known extensions 574 if (found) { 575 return; 576 } 577 578 content = $container.find('.content.pages-content'); 579 if (content.length) { 580 // Get page content class, try to find matching link 581 classes = content.prop('class').split(' '); 582 for (i = 0; i < classes.length && !found; i++) { 583 key = classes[i].trim(); 584 if (key !== 'content' && key !== 'pages-content') { 585 $container.find('.tab.pages.' + key).each(function() { 586 tabs.find('.tab.selected').removeClass('selected'); 587 $(this).addClass('selected'); 588 found = true; 589 }); 590 } 591 } 592 if (found) { 593 return; 594 } 595 596 // Get first page link 597 $container.find('.tab.pages:first').each(function() { 598 tabs.find('.tab.selected').removeClass('selected'); 599 $(this).addClass('selected'); 600 found = true; 601 }); 602 } 603 }); 604 605 /** 606 * Reset avatar dimensions when changing URL or EMAIL 607 */ 608 $container.find('input[data-reset-on-edit]').on('keyup', function() { 609 $(this.getAttribute('data-reset-on-edit')).val(''); 610 }); 611 612 /** 613 * Pagination 614 */ 615 $container.find('.pagination .page-jump-form :button').click(function() { 616 var $input = $(this).siblings('input.inputbox'); 617 pageJump($input); 618 }); 619 620 $container.find('.pagination .page-jump-form input.inputbox').on('keypress', function(event) { 621 if (event.which === 13 || event.keyCode === 13) { 622 event.preventDefault(); 623 pageJump($(this)); 624 } 625 }); 626 627 $container.find('.pagination .dropdown-trigger').click(function() { 628 var $dropdownContainer = $(this).parent(); 629 // Wait a little bit to make sure the dropdown has activated 630 setTimeout(function() { 631 if ($dropdownContainer.hasClass('dropdown-visible')) { 632 $dropdownContainer.find('input.inputbox').focus(); 633 } 634 }, 100); 635 }); 636 637 /** 638 * Adjust HTML code for IE8 and older versions 639 */ 640 // if (oldBrowser) { 641 // // Fix .linklist.bulletin lists 642 // $container 643 // .find('ul.linklist.bulletin > li') 644 // .filter(':first-child, .rightside:last-child') 645 // .addClass('no-bulletin'); 646 // } 647 648 /** 649 * Resize navigation (breadcrumbs) block to keep all links on same line 650 */ 651 $container.find('.navlinks').each(function() { 652 var $this = $(this), 653 $left = $this.children().not('.rightside'), 654 $right = $this.children('.rightside'), 655 queued = false, 656 throttled = false; 657 658 if ($left.length !== 1 || !$right.length) { 659 return; 660 } 661 662 function resize() { 663 var width = 0, 664 diff = $left.outerWidth(true) - $left.width(), 665 minWidth = Math.max($this.width() / 3, 240), 666 maxWidth; 667 668 throttled = false; 669 $right.each(function() { 670 var $this = $(this); 671 if ($this.is(':visible')) { 672 width += $this.outerWidth(true); 673 } 674 }); 675 676 maxWidth = $this.width() - width - diff; 677 $left.css('max-width', Math.floor(Math.max(maxWidth, minWidth)) + 'px'); 678 } 679 680 resize(); 681 $(window).resize(function() { 682 if (throttled) { 683 queued = true; 684 } 685 else { 686 resize(); 687 throttled = true; 688 queued = false; 689 setTimeout(function() { 690 throttled = false; 691 if (queued) { 692 resize(); 693 } 694 }, 250); 695 } 696 }); 697 }); 698 699 /** 700 * Makes breadcrumbs responsive 701 */ 702 $container.find('.breadcrumbs:not([data-skip-responsive])').each(function() { 703 var $this = $(this), 704 $links = $this.find('.crumb'), 705 length = $links.length, 706 classes = ['wrapped-max', 'wrapped-wide', 'wrapped-medium', 'wrapped-small', 'wrapped-tiny'], 707 classesLength = classes.length, 708 maxHeight = 0, 709 lastWidth = false, 710 wrapped = false, 711 queued = false, 712 throttled = false; 713 714 // Set tooltips 715 $this.find('a').each(function() { 716 var $link = $(this); 717 $link.attr('title', $link.text()); 718 }); 719 720 // Function that checks breadcrumbs 721 function check() { 722 var height = $this.height(), 723 width; 724 725 // Test max-width set in code for .navlinks above 726 width = parseInt($this.css('max-width'), 10); 727 if (!width) { 728 width = $body.width(); 729 } 730 731 throttled = false; 732 maxHeight = parseInt($this.css('line-height'), 10); 733 $links.each(function() { 734 if ($(this).height() > 0) { 735 maxHeight = Math.max(maxHeight, $(this).outerHeight(true)); 736 } 737 }); 738 739 if (height <= maxHeight) { 740 if (!wrapped || lastWidth === false || lastWidth >= width) { 741 return; 742 } 743 } 744 lastWidth = width; 745 746 if (wrapped) { 747 $this.removeClass('wrapped').find('.crumb.wrapped').removeClass('wrapped ' + classes.join(' ')); 748 if ($this.height() <= maxHeight) { 749 return; 750 } 751 } 752 753 wrapped = true; 754 $this.addClass('wrapped'); 755 if ($this.height() <= maxHeight) { 756 return; 757 } 758 759 for (var i = 0; i < classesLength; i++) { 760 for (var j = length - 1; j >= 0; j--) { 761 $links.eq(j).addClass('wrapped ' + classes[i]); 762 if ($this.height() <= maxHeight) { 763 return; 764 } 765 } 766 } 767 } 768 769 // Run function and set event 770 check(); 771 $(window).resize(function() { 772 if (throttled) { 773 queued = true; 774 } 775 else { 776 check(); 777 throttled = true; 778 queued = false;
779 setTimeout(function() { 780 throttled = false; 781 if (queued) { 782 check(); 783 } 784 }, 250); 785 } 786 }); 787 }); 788 789 /** 790 * Responsive link lists 791 */ 792 var selector = '.linklist:not(.navlinks, [data-skip-responsive]),' + 793 '.postbody .post-buttons:not([data-skip-responsive])'; 794 $container.find(selector).each(function() { 795 var $this = $(this), 796 filterSkip = '.breadcrumbs, [data-skip-responsive]', 797 filterLast = '.edit-icon, .quote-icon, [data-last-responsive]', 798 $linksAll = $this.children(), 799 $linksNotSkip = $linksAll.not(filterSkip), // All items that can potentially be hidden 800 $linksFirst = $linksNotSkip.not(filterLast), // The items that will be hidden first 801 $linksLast = $linksNotSkip.filter(filterLast), // The items that will be hidden last 802 persistent = $this.attr('id') === 'nav-main', // Does this list already have a menu (such as quick-links)? 803 html = '<li class="responsive-menu hidden"><a href="javascript:void(0);" class="js-responsive-menu-link responsive-menu-link"><i class="icon fa-bars fa-fw" aria-hidden="true"></i></a><div class="dropdown"><div class="pointer"><div class="pointer-inner" /></div><ul class="dropdown-contents" /></div></li>', 804 slack = 3; // Vertical slack space (in pixels). Determines how sensitive the script is in determining whether a line-break has occured. 805 806 // Add a hidden drop-down menu to each links list (except those that already have one) 807 if (!persistent) { 808 if ($linksNotSkip.is('.rightside')) { 809 $linksNotSkip.filter('.rightside:first').before(html); 810 $this.children('.responsive-menu').addClass('rightside'); 811 } else { 812 $this.append(html); 813 } 814 } 815 816 // Set some object references and initial states 817 var $menu = $this.children('.responsive-menu'), 818 $menuContents = $menu.find('.dropdown-contents'), 819 persistentContent = $menuContents.find('li:not(.separator)').length, 820 lastWidth = false, 821 compact = false, 822 responsive1 = false, 823 responsive2 = false, 824 copied1 = false, 825 copied2 = false, 826 maxHeight = 0; 827 828 // Find the tallest element in the list (we assume that all elements are roughly the same height) 829 $linksAll.each(function() { 830 if (!$(this).height()) { 831 return; 832 } 833 maxHeight = Math.max(maxHeight, $(this).outerHeight(true)); 834 }); 835 if (maxHeight < 1) { 836 return; // Shouldn't be possible, but just in case, abort 837 } else { 838 maxHeight = maxHeight + slack; 839 } 840 841 function check() { 842 var width = $body.width(); 843 // We can't make it any smaller than this, so just skip 844 if (responsive2 && compact && (width <= lastWidth)) { 845 return; 846 } 847 lastWidth = width; 848 849 // Reset responsive and compact layout 850 if (responsive1 || responsive2) { 851 $linksNotSkip.removeClass('hidden'); 852 $menuContents.children('.clone').addClass('hidden'); 853 responsive1 = responsive2 = false;
854 } 855 if (compact) { 856 $this.removeClass('compact'); 857 compact = false; 858 } 859 860 // Unhide the quick-links menu if it has "persistent" content 861 if (persistent && persistentContent) { 862 $menu.removeClass('hidden'); 863 } else { 864 $menu.addClass('hidden'); 865 } 866 867 // Nothing to resize if block's height is not bigger than tallest element's height 868 if ($this.height() <= maxHeight) { 869 return; 870 } 871 872 // STEP 1: Compact 873 if (!compact) { 874 $this.addClass('compact'); 875 compact = true; 876 } 877 if ($this.height() <= maxHeight) { 878 return; 879 } 880 881 // STEP 2: First responsive set - compact 882 if (compact) { 883 $this.removeClass('compact'); 884 compact = false; 885 } 886 // Copy the list items to the dropdown 887 if (!copied1) { 888 var $clones1 = $linksFirst.clone(); 889 $menuContents.prepend($clones1.addClass('clone clone-first').removeClass('leftside rightside')); 890 891 if ($this.hasClass('post-buttons')) { 892 $('.button', $menuContents).removeClass('button'); 893 $('.sr-only', $menuContents).removeClass('sr-only'); 894 $('.js-responsive-menu-link').addClass('button').addClass('button-icon-only'); 895 $('.js-responsive-menu-link .icon').removeClass('fa-bars').addClass('fa-ellipsis-h'); 896 } 897 copied1 = true; 898 } 899 if (!responsive1) { 900 $linksFirst.addClass('hidden'); 901 responsive1 = true; 902 $menuContents.children('.clone-first').removeClass('hidden'); 903 $menu.removeClass('hidden'); 904 } 905 if ($this.height() <= maxHeight) { 906 return; 907 } 908 909 // STEP 3: First responsive set + compact 910 if (!compact) { 911 $this.addClass('compact'); 912 compact = true; 913 } 914 if ($this.height() <= maxHeight) { 915 return; 916 } 917 918 // STEP 4: Last responsive set - compact 919 if (!$linksLast.length) { 920 return; // No other links to hide, can't do more 921 } 922 if (compact) { 923 $this.removeClass('compact'); 924 compact = false; 925 } 926 // Copy the list items to the dropdown 927 if (!copied2) { 928 var $clones2 = $linksLast.clone(); 929 $menuContents.prepend($clones2.addClass('clone clone-last').removeClass('leftside rightside')); 930 copied2 = true; 931 } 932 if (!responsive2) { 933 $linksLast.addClass('hidden'); 934 responsive2 = true; 935 $menuContents.children('.clone-last').removeClass('hidden'); 936 } 937 if ($this.height() <= maxHeight) { 938 return; 939 } 940 941 // STEP 5: Last responsive set + compact 942 if (!compact) { 943 $this.addClass('compact'); 944 compact = true; 945 } 946 } 947 948 if (!persistent) { 949 phpbb.registerDropdown($menu.find('a.js-responsive-menu-link'), $menu.find('.dropdown'), false); 950 } 951 952 // If there are any images in the links list, run the check again after they have loaded 953 $linksAll.find('img').each(function() { 954 $(this).load(function() { 955 check(); 956 }); 957 }); 958 959 check(); 960 $(window).resize(check); 961 }); 962 963 /** 964 * Fix container for messages 965 */ 966 $container.find('.postbody').each(function() { 967 var $this = $(this), 968 children = $this.children(); 969 970 if (children.length == 1 && children.is('div')) { 971 return; 972 } 973 974 $this.wrapInner('<div class="postbody-inner" />'); 975 }); 976 977 /** 978 * Adjust post z-index for post profiles for all posts 979 */ 980 $('.postprofile').each(function(i) { 981 var z = Math.max(28 - i, 2); 982 $(this).css('z-index', z); 983 }); 984 985 /** 986 * Do not run functions below for old browsers 987 */ 988 if (oldBrowser) { 989 return; 990 } 991 992 /** 993 * Adjust topiclist lists with check boxes 994 */ 995 $container.find('ul.topiclist dd.mark').siblings('dt').children('.list-inner').addClass('with-mark'); 996 997 /** 998 * Appends contents of all extra columns to first column in 999 * .topiclist lists for mobile devices. Copies contents as is. 1000 * 1001 * To add that functionality to .topiclist list simply add 1002 * responsive-show-all to list of classes 1003 */ 1004 $container.find('.topiclist.responsive-show-all > li > dl').each(function() { 1005 var $this = $(this), 1006 $block = $this.find('dt .responsive-show:last-child'), 1007 first = true; 1008 1009 // Create block that is visible only on mobile devices 1010 if (!$block.length) { 1011 $this.find('dt > .list-inner').append('<div class="responsive-show" style="display:none;" />'); 1012 $block = $this.find('dt .responsive-show:last-child'); 1013 } else { 1014 first = ($.trim($block.text()).length === 0); 1015 } 1016 1017 // Copy contents of each column 1018 $this.find('dd').not('.mark').each(function() { 1019 var column = $(this), 1020 $children = column.children(), 1021 html = column.html(); 1022 1023 if ($children.length === 1 && $children.text() === column.text()) { 1024 html = $children.html(); 1025 } 1026 1027 $block.append((first ? '' : '<br />') + html); 1028 1029 first = false;
1030 }); 1031 }); 1032 1033 /** 1034 * Same as above, but prepends text from header to each 1035 * column before contents of that column. 1036 * 1037 * To add that functionality to .topiclist list simply add 1038 * responsive-show-columns to list of classes 1039 */ 1040 $container.find('.topiclist.responsive-show-columns').each(function() { 1041 var $list = $(this), 1042 headers = [], 1043 headersLength = 0; 1044 1045 // Find all headers, get contents 1046 $list.prev('.topiclist').find('li.header dd').not('.mark').each(function() { 1047 headers.push($(this).text()); 1048 headersLength++; 1049 }); 1050 1051 if (!headersLength) { 1052 return; 1053 } 1054 1055 // Parse each row 1056 $list.find('dl').each(function() { 1057 var $this = $(this), 1058 $block = $this.find('dt .responsive-show:last-child'), 1059 first = true; 1060 1061 // Create block that is visible only on mobile devices 1062 if (!$block.length) { 1063 $this.find('dt > .list-inner').append('<div class="responsive-show" style="display:none;" />'); 1064 $block = $this.find('dt .responsive-show:last-child'); 1065 } else { 1066 first = ($.trim($block.text()).length === 0); 1067 } 1068 1069 // Copy contents of each column 1070 $this.find('dd').not('.mark').each(function(i) { 1071 var column = $(this), 1072 children = column.children(), 1073 html = column.html(); 1074 1075 if (children.length === 1 && children.text() === column.text()) { 1076 html = children.html(); 1077 } 1078 1079 // Prepend contents of matching header before contents of column 1080 if (i < headersLength) { 1081 html = headers[i] + ': <strong>' + html + '</strong>'; 1082 } 1083 1084 $block.append((first ? '' : '<br />') + html); 1085 1086 first = false; 1087 }); 1088 }); 1089 }); 1090 1091 /** 1092 * Responsive tables 1093 */ 1094 $container.find('table.table1').not('.not-responsive').each(function() { 1095 var $this = $(this), 1096 $th = $this.find('thead > tr > th'), 1097 headers = [], 1098 totalHeaders = 0, 1099 i, headersLength; 1100 1101 // Find each header 1102 $th.each(function(column) { 1103 var cell = $(this), 1104 colspan = parseInt(cell.attr('colspan'), 10), 1105 dfn = cell.attr('data-dfn'), 1106 text = dfn ? dfn : cell.text(); 1107 1108 colspan = isNaN(colspan) || colspan < 1 ? 1 : colspan; 1109 1110 for (i = 0; i < colspan; i++) { 1111 headers.push(text); 1112 } 1113 totalHeaders++; 1114 1115 if (dfn && !column) { 1116 $this.addClass('show-header'); 1117 } 1118 }); 1119 1120 headersLength = headers.length; 1121 1122 // Add header text to each cell as <dfn> 1123 $this.addClass('responsive'); 1124 1125 if (totalHeaders < 2) { 1126 $this.addClass('show-header'); 1127 return; 1128 } 1129 1130 $this.find('tbody > tr').each(function() { 1131 var row = $(this), 1132 cells = row.children('td'), 1133 column = 0; 1134 1135 if (cells.length === 1) { 1136 row.addClass('big-column'); 1137 return; 1138 } 1139 1140 cells.each(function() { 1141 var cell = $(this), 1142 colspan = parseInt(cell.attr('colspan'), 10), 1143 text = $.trim(cell.text()); 1144 1145 if (headersLength <= column) { 1146 return; 1147 } 1148 1149 if ((text.length && text !== '-') || cell.children().length) { 1150 cell.prepend('<dfn style="display: none;">' + headers[column] + '</dfn>'); 1151 } else { 1152 cell.addClass('empty'); 1153 } 1154 1155 colspan = isNaN(colspan) || colspan < 1 ? 1 : colspan; 1156 column += colspan; 1157 }); 1158 }); 1159 }); 1160 1161 /** 1162 * Hide empty responsive tables 1163 */ 1164 $container.find('table.responsive > tbody').not('.responsive-skip-empty').each(function() { 1165 var $items = $(this).children('tr'); 1166 if (!$items.length) { 1167 $(this).parent('table:first').addClass('responsive-hide'); 1168 } 1169 }); 1170 1171 /** 1172 * Responsive tabs 1173 */ 1174 $container.find('#tabs, #minitabs').not('[data-skip-responsive]').each(function() { 1175 var $this = $(this), 1176 $ul = $this.children(), 1177 $tabs = $ul.children().not('[data-skip-responsive]'), 1178 $links = $tabs.children('a'), 1179 $item = $ul.append('<li class="tab responsive-tab" style="display:none;"><a href="javascript:void(0);" class="responsive-tab-link"> </a><div class="dropdown tab-dropdown" style="display: none;"><div class="pointer"><div class="pointer-inner" /></div><ul class="dropdown-contents" /></div></li>').find('li.responsive-tab'), 1180 $menu = $item.find('.dropdown-contents'), 1181 maxHeight = 0, 1182 lastWidth = false, 1183 responsive = false; 1184 1185 $links.each(function() { 1186 var $this = $(this); 1187 maxHeight = Math.max(maxHeight, Math.max($this.outerHeight(true), $this.parent().outerHeight(true))); 1188 }); 1189 1190 function check() { 1191 var width = $body.width(), 1192 height = $this.height(); 1193 1194 if (!arguments.length && (!responsive || width <= lastWidth) && height <= maxHeight) { 1195 return; 1196 } 1197 1198 $tabs.show(); 1199 $item.hide(); 1200 1201 lastWidth = width; 1202 height = $this.height(); 1203 if (height <= maxHeight) { 1204 if ($item.hasClass('dropdown-visible')) { 1205 phpbb.toggleDropdown.call($item.find('a.responsive-tab-link').get(0)); 1206 } 1207 return; 1208 } 1209 1210 responsive = true; 1211 $item.show(); 1212 $menu.html(''); 1213 1214 var $availableTabs = $tabs.filter(':not(.activetab, .responsive-tab)'), 1215 total = $availableTabs.length, 1216 i, $tab; 1217 1218 for (i = total - 1; i >= 0; i--) { 1219 $tab = $availableTabs.eq(i); 1220 $menu.prepend($tab.clone(true).removeClass('tab')); 1221 $tab.hide(); 1222 if ($this.height() <= maxHeight) { 1223 $menu.find('a').click(function() { 1224 check(true); 1225 }); 1226 return; 1227 } 1228 } 1229 $menu.find('a').click(function() { 1230 check(true); 1231 }); 1232 } 1233 1234 var $tabLink = $item.find('a.responsive-tab-link'); 1235 phpbb.registerDropdown($tabLink, $item.find('.dropdown'), { 1236 visibleClass: 'activetab' 1237 }); 1238 1239 check(true); 1240 $(window).resize(check); 1241 }); 1242 1243 /** 1244 * Hide UCP/MCP navigation if there is only 1 item 1245 */
1246 $container.find('#navigation').each(function() { 1247 var $items = $(this).children('ol, ul').children('li'); 1248 if ($items.length === 1) { 1249 $(this).addClass('responsive-hide'); 1250 } 1251 }); 1252 1253 /** 1254 * Replace responsive text 1255 */ 1256 $container.find('[data-responsive-text]').each(function() { 1257 var $this = $(this), 1258 fullText = $this.text(), 1259 responsiveText = $this.attr('data-responsive-text'), 1260 responsive = false; 1261 1262 function check() { 1263 if ($(window).width() > 700) { 1264 if (!responsive) { 1265 return; 1266 } 1267 $this.text(fullText); 1268 responsive = false; 1269 return; 1270 } 1271 if (responsive) { 1272 return; 1273 } 1274 $this.text(responsiveText); 1275 responsive = true; 1276 } 1277 1278 check(); 1279 $(window).resize(check); 1280 }); 1281 1282 /** 1283 * Static navigation 1284 */ 1285 if (styleConfig.staticNavigation) { 1286 $container.find('.navbar.tabbed > .inner').each(function(i) { 1287 var nav = this, 1288 navigation = $(nav), 1289 isStatic = false, 1290 parent = navigation.parent(), 1291 dummy, 1292 inner, 1293 $w = $(window), 1294 minTopPosition = 0, 1295 minWidth = styleConfig.staticNavigationMinWidth, 1296 minHeight = styleConfig.staticNavigationMinHeight, 1297 windowWidth, navHeight, 1298 queued = false, 1299 throttled = false; 1300 1301 navigation.before('<div class="static-nav-dummy inner" style="display:none;" />'); 1302 dummy = navigation.prev(); 1303 1304 navigation.wrapInner('<div class="static-inner" />'); 1305 inner = navigation.children(); 1306 1307 function enableStatic() 1308 { 1309 dummy.css('height', Math.floor(navigation.height()) + 'px').show(); 1310 navigation.addClass('static'); 1311 parent.removeClass('not-static'); 1312 isStatic = true; 1313 checkNavigation(true); 1314 } 1315 1316 function disableStatic() 1317 { 1318 dummy.hide(); 1319 navigation.removeClass('static'); 1320 parent.addClass('not-static'); 1321 isStatic = false; 1322 checkNavigation(true); 1323 } 1324 1325 function testHash() 1326 { 1327 var hash = (window.location.hash) ? window.location.hash : ''; 1328 if (!hash) 1329 { 1330 return; 1331 } 1332 window.scrollTo($w.scrollLeft(), $w.scrollTop() - navigation.height()); 1333 } 1334 1335 function check(checkHash) 1336 { 1337 var windowTop = 0, 1338 windowWidth = Math.floor($w.width()), 1339 top; 1340 1341 if (windowWidth < minWidth || $w.height() < minHeight) { 1342 if (isStatic) { 1343 disableStatic(); 1344 } 1345 return; 1346 } 1347 if (!isStatic) 1348 { 1349 navHeight = navigation.height(); 1350 top = nav.getBoundingClientRect().top; 1351 if (top > 0) { 1352 return; 1353 } 1354 minTopPosition = $w.scrollTop() + top; 1355 enableStatic(); 1356 if (checkHash) { 1357 testHash(); 1358 } 1359 return; 1360 } 1361 if ($w.scrollTop() < minTopPosition) { 1362 disableStatic(); 1363 } else if (checkHash) { 1364 testHash(); 1365 } 1366 } 1367 1368 $w.on('scroll resize', function() { 1369 if (!isStatic) { 1370 check(false); 1371 } 1372 else { 1373 if (!throttled) { 1374 check(false); 1375 throttled = true; 1376 queued = false; 1377 setTimeout(function() { 1378 throttled = false; 1379 if (queued) { 1380 check(false); 1381 } 1382 }, 250); 1383 } 1384 else { 1385 queued = true; 1386 } 1387 } 1388 }); 1389 $w.on('load', function() { check(true); }); 1390 $w.on('hashchange', function() { check(true); }); 1391 }); 1392 } 1393 1394 /** 1395 * Empty last post column 1396 */ 1397 $container.find('dd.lastpost > span:only-child > br:only-child').parents('dd.lastpost').addClass('empty'); 1398 1399 /** 1400 * Forum descriptions 1401 */ 1402 var animatedDescription = false; 1403 $container.find('.forabg').each(function(i) { 1404 var $b = $('body'), 1405 $w = $(window), 1406 rtl = $('#phpbb').hasClass('rtl'), 1407 hide = $(this).attr('data-hide-description') == '1'; 1408 1409 $('a.forumtitle + .forum-description', this).each(function(j) { 1410 var $this = $(this); 1411 1412 if (!hide) { 1413 $this.parents('dl.icon').addClass('with-description'); 1414 return; 1415 } 1416 1417 var title = $this.prev(), 1418 id = 'forumdesc-' + i + '-' + j, 1419 item, top, left, width, rect, rectWidth; 1420 1421 $b.append($this); 1422 $this.attr('id', id).append('<span class="arrow" />'); 1423 1424 title.attr('title', '').hover(function() { 1425 // Hide previous animation 1426 if (animatedDescription !== false) { 1427 animatedDescription.item.stop(true, true).hide(); 1428 } 1429 animatedDescription = { 1430 item: $this, 1431 i: i, 1432 j: j, 1433 fading: false 1434 }; 1435 1436 // Calculate position 1437 rect = this.getBoundingClientRect(); 1438 rectWidth = rect.width ? rect.width : $(this).width(); 1439 // $this.attr('data-rect', 'top: ' + rect.top + ', left: ' + rect.left + ', width: ' + rectWidth + ', window: ' + $w.width()); 1440 top = Math.floor($w.scrollTop() + rect.top); 1441 if ((rect.left + rectWidth + 300) > $w.width()) { 1442 $this.addClass('no-arrow'); 1443 top += Math.floor(rect.height ? rect.height : $(this).height()); 1444 1445 if (!rtl) { 1446 left = Math.floor($w.scrollLeft() + rect.left); 1447 $this.css({ 1448 position: 'absolute', 1449 top: top + 'px', 1450 left: left + 'px' 1451 }); 1452 } 1453 else { 1454 left = Math.floor($w.scrollLeft() + rect.left + rectWidth); 1455 $this.css({ 1456 position: 'absolute', 1457 top: top + 'px', 1458 right: left + 'px' 1459 }); 1460 } 1461 } 1462 else if (!rtl) { 1463 $this.removeClass('no-arrow'); 1464 left = Math.floor($w.scrollLeft() + rect.left + rectWidth + 10); 1465 $this.css({ 1466 position: 'absolute', 1467 top: top + 'px', 1468 left: left + 'px' 1469 }); 1470 } 1471 else { 1472 $this.removeClass('no-arrow'); 1473 left = Math.floor($w.scrollLeft() + rect.left - 10); 1474 $this.css({ 1475 position: 'absolute', 1476 top: top + 'px', 1477 right: left + 'px' 1478 }); 1479 } 1480 1481 // Show 1482 $this.stop(true, true).fadeIn(200); 1483 }, function() { 1484 // Hide 1485 animatedDescription.fading = true; 1486 setTimeout(700, function() { 1487 if (animatedDescription !== false && animatedDescription.i == i && animatedDescription.j == j && animatedDescription.fading) { 1488 animatedDescription = false;
1489 } 1490 }); 1491 $this.delay(500).fadeOut(200); 1492 }); 1493 1494 $this.addClass('toggle').click(function() { 1495 // Hide 1496 $this.stop(true, true).fadeOut(100); 1497 if (animatedDescription !== false && animatedDescription.i == i && animatedDescription.j == j) { 1498 animatedDescription = false; 1499 } 1500 }); 1501 }); 1502 }); 1503 1504 /** 1505 * HD images 1506 */ 1507 if (window.matchMedia && window.matchMedia('(-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi), (min-resolution: 1.5dppx)').matches) { 1508 $container.find('img[data-src-hd]').each(function() { 1509 var img = this, 1510 $this = $(this), 1511 hdImage = new Image(), 1512 hdLoaded = false, 1513 normalLoaded = false; 1514 1515 function replaceImage() 1516 { 1517 $this.css('width', (img.naturalWidth ? img.naturalWidth : img.width) + 'px'); 1518 img.setAttribute('src', img.getAttribute('data-src-hd')); 1519 } 1520 1521 if (img.complete) { 1522 normalLoaded = true; 1523 } 1524 else { 1525 img.onload = function() { 1526 if (normalLoaded) { 1527 return; 1528 } 1529 normalLoaded = true; 1530 if (hdLoaded) { 1531 replaceImage(); 1532 } 1533 }; 1534 } 1535 1536 hdImage.onload = function() { 1537 hdLoaded = true; 1538 if (normalLoaded) { 1539 replaceImage(); 1540 } 1541 }; 1542 hdImage.src = img.getAttribute('data-src-hd'); 1543 }); 1544 } 1545 1546 /** 1547 * Split buttons 1548 */ 1549 $container.find('div.buttons a.button.icon-button').each(function() { 1550 var $this = $(this), 1551 words; 1552 1553 if ($this.children().length) return; 1554 1555 words = $this.text().trim().split(' '); 1556 if (words.length > 1) { 1557 $this.text(words.shift() + ' ').append('<strong />'); 1558 $this.find('strong').text(words.join(' ')); 1559 } 1560 }); 1561 1562 /** 1563 * Add online status 1564 */ 1565 $('#phpbb.can-transform[data-online-text]').each(function() { 1566 var text = $(this).attr('data-online-text'); 1567 1568 $container.find('.online').each(function() { 1569 var $this = $(this); 1570 1571 $this.css('position', 'relative').append('<span class="online-ribbon"><span>' + text + '</span><span>' + text + '</span></span>'); 1572 }); 1573 }); 1574 1575 /** 1576 * Extend poster profile 1577 */ 1578 if (styleConfig._loaded) { 1579 $container.find('.postprofile + .postbody > div:only-child').each(function() { 1580 adjustPosterProfile($(this)); 1581 }); 1582 } 1583 1584 /** 1585 * Collapse forums 1586 */ 1587 if (styleConfig.collapseForums) { 1588 $container.find('.forabg li.header').each(function() { 1589 var $this = $(this), 1590 forum = $this.parent().next('ul.forums'), 1591 id = 0, 1592 toggled = false, 1593 toggle; 1594 1595 if (forum.length != 1) { 1596 return; 1597 } 1598 1599 // Find category id 1600 $('a[data-id]', $this).each(function() { 1601 id = parseInt(this.getAttribute('data-id')); 1602 }); 1603 if (!id) { 1604 forum.find('.forumtitle[data-id]:first').each(function() { 1605 id = parseInt(this.getAttribute('data-id')); 1606 if (!isNaN(id)) { 1607 id = 'f' + id; 1608 } 1609 }); 1610 } 1611 if (!id) { 1612 return; 1613 } 1614 1615 // Add toggle code 1616 $this.append('<a class="forum-toggle" href="#"></a>'); 1617 toggle = $this.find('.forum-toggle'); 1618 toggle.click(function(event) { 1619 event.preventDefault(); 1620 if (toggled) { 1621 forum.stop(true, true).slideDown(200); 1622 toggled = false; 1623 toggle.removeClass('toggled'); 1624 phpbb.deleteCookie('toggled-' + id, styleConfig.cookieConfig); 1625 return; 1626 } 1627 forum.stop(true, true).slideUp(200); 1628 toggled = true; 1629 toggle.addClass('toggled'); 1630 phpbb.setCookie('toggled-' + id, '1', styleConfig.cookieConfig); 1631 }); 1632 1633 // Check default state 1634 if (phpbb.getCookie('toggled-' + id, styleConfig.cookieConfig) == '1') { 1635 forum.stop(true, true).slideUp(0); 1636 toggled = true; 1637 toggle.addClass('toggled'); 1638 } 1639 }); 1640 } 1641} 1642 1643/** 1644* Run onload functions 1645*/ 1646jQuery(function($) { 1647 'use strict'; 1648 1649 function processResizeEvent() 1650 { 1651 styleConfig._resizeThrottled = false; 1652 1653 checkNavigation(false); 1654 1655 if (styleConfig.extendPosterProfile) { 1656 $('.postprofile + .postbody > div:only-child').each(function() { 1657 adjustPosterProfile($(this)); 1658 }); 1659 } 1660 } 1661 1662 var transforms = ['transform', 'webkitTransform', 'msTransform'], 1663 i, test; 1664 1665 // Cookie configuration 1666 styleConfig.cookieConfig = { 1667 prefix: '', 1668 path: '/', 1669 expires: new Date() 1670 }; 1671 styleConfig.cookieConfig.expires.setFullYear(styleConfig.cookieConfig.expires.getFullYear() + 1); 1672 1673 // Swap .nojs and .hasjs 1674 $('#phpbb.nojs').toggleClass('nojs hasjs'); 1675 $('#phpbb').toggleClass('hastouch', phpbb.isTouch); 1676 $('#phpbb.hastouch').removeClass('notouch'); 1677 1678 // Focus forms 1679 $('form[data-focus]:first').each(function() { 1680 $('#' + this.getAttribute('data-focus')).focus(); 1681 }); 1682 1683 // Check for transformations 1684 test = $('#phpbb').get(0); 1685 for (i=0; i<transforms.length; i++) { 1686 if (typeof(test.style[transforms[i]]) != 'undefined') { 1687 $('#phpbb').addClass('can-transform'); 1688 break; 1689 } 1690 } 1691 1692 // Cookies 1693 phpbb.setCookie = function(name, value, config) { 1694 config = $.extend({ 1695 prefix: '', 1696 path: '/' 1697 }, typeof config === 'object' ? config : {}); 1698 1699 document.cookie = config.prefix + name + '=' + encodeURIComponent(value) 1700 + (config.expires === undefined ? '' : ';expires=' + config.expires.toUTCString()) 1701 + (config.path ? ';path=' + config.path : '') 1702 + (config.domain ? ';domain=' + config.domain : ''); 1703 1704 return value; 1705 }; 1706 1707 phpbb.getCookie = function(name, config) { 1708 var expr, cookie; 1709 1710 config = $.extend({ 1711 prefix: '', 1712 path: '/' 1713 }, typeof config === 'object' ? config : {}); 1714 1715 expr = new RegExp('(^| )' + config.prefix + name + '=([^;]+)(;|$)'); 1716 cookie = expr.exec(document.cookie); 1717 1718 if (cookie) 1719 { 1720 return decodeURIComponent(cookie[2]); 1721 } 1722 else 1723 { 1724 return null; 1725 } 1726 }; 1727 1728 phpbb.deleteCookie = function(name, config) { 1729 config = $.extend({ 1730 prefix: '', 1731 path: '/' 1732 }, typeof config === 'object' ? config : {}); 1733 1734 document.cookie = config.prefix + name + '=' 1735 + (config.path ? '; path=' + config.path : '') 1736 + (config.domain ? '; domain=' + config.domain : '') 1737 + '; expires=Thu, 01-Jan-70 00:00:01 GMT'; 1738 1739 return null; 1740 }; 1741 1742 // Responsive navigation 1743 initResponsiveNavigation(); 1744 1745 // Parse body 1746 parseDocument($('body')); 1747 1748 // Check responsive navigation 1749 checkNavigation(true); 1750 1751 // Events 1752 styleConfig._loaded = true; 1753 styleConfig._resizeThrottled = false;
1754 styleConfig._resizeQueued = false; 1755 1756 $(window).load(function() { 1757 checkNavigation(true); 1758 if (styleConfig.extendPosterProfile) { 1759 $('.postprofile + .postbody > div:only-child').each(function() { 1760 adjustPosterProfile($(this)); 1761 }); 1762 } 1763 }); 1764 1765 $(window).resize(function() { 1766 if (!styleConfig._resizeThrottled) { 1767 processResizeEvent(); 1768 styleConfig._resizeThrottled = true; 1769 styleConfig._resizeQueued = false; 1770 setTimeout(function() { 1771 styleConfig._resizeThrottled = false; 1772 if (styleConfig._resizeQueued) { 1773 processResizeEvent(); 1774 } 1775 }, 500); 1776 } else { 1777 styleConfig._resizeQueued = true; 1778 } 1779 }); 1780});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.