Verzeichnisstruktur phpBB-3.1.0


Veröffentlicht
27.10.2014

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

forum_fn.js

Zuletzt modifiziert: 09.10.2024, 12:54 - Dateigröße: 22.71 KiB


001  /**
002  * phpBB3 forum functions
003  */
004   
005  /**
006  * Find a member
007  */
008  function find_username(url) {
009      'use strict';
010   
011      popup(url, 760, 570, '_usersearch');
012      return false;
013  }
014   
015  /**
016  * Window popup
017  */
018  function popup(url, width, height, name) {
019      'use strict';
020   
021      if (!name) {
022          name = '_popup';
023      }
024   
025      window.open(url.replace(/&/g, '&'), name, 'height=' + height + ',resizable=yes,scrollbars=yes, width=' + width);
026      return false;
027  }
028   
029  /**
030  * Jump to page
031  */
032  function pageJump(item) {
033      'use strict';
034   
035      var page = item.val(),
036          perPage = item.attr('data-per-page'),
037          baseUrl = item.attr('data-base-url'),
038          startName = item.attr('data-start-name');
039   
040      if (page !== null && !isNaN(page) && page == Math.floor(page) && page > 0) {
041          if (baseUrl.indexOf('?') === -1) {
042              document.location.href = baseUrl + '?' + startName + '=' + ((page - 1) * perPage);
043          } else {
044              document.location.href = baseUrl.replace(/&/g, '&') + '&' + startName + '=' + ((page - 1) * perPage);
045          }
046      }
047  }
048   
049  /**
050  * Mark/unmark checklist
051  * id = ID of parent container, name = name prefix, state = state [true/false]
052  */
053  function marklist(id, name, state) {
054      'use strict';
055   
056      jQuery('#' + id + ' input[type=checkbox][name]').each(function() {
057          var $this = jQuery(this);
058          if ($this.attr('name').substr(0, name.length) === name) {
059              $this.prop('checked', state);
060          }
061      });
062  }
063   
064  /**
065  * Resize viewable area for attached image or topic review panel (possibly others to come)
066  * e = element
067  */
068  function viewableArea(e, itself) {
069      'use strict';
070   
071      if (!e) {
072          return;
073      }
074   
075      if (!itself) {
076          e = e.parentNode;
077      }
078   
079      if (!e.vaHeight) {
080          // Store viewable area height before changing style to auto
081          e.vaHeight = e.offsetHeight;
082          e.vaMaxHeight = e.style.maxHeight;
083          e.style.height = 'auto';
084          e.style.maxHeight = 'none';
085          e.style.overflow = 'visible';
086      } else {
087          // Restore viewable area height to the default
088          e.style.height = e.vaHeight + 'px';
089          e.style.overflow = 'auto';
090          e.style.maxHeight = e.vaMaxHeight;
091          e.vaHeight = false;
092      }
093  }
094   
095  /**
096  * Alternate display of subPanels
097  */
098  jQuery(function($) {
099      'use strict';
100   
101      $('.sub-panels').each(function() {
102   
103          var $childNodes = $('a[data-subpanel]', this),
104              panels = $childNodes.map(function () {
105                  return this.getAttribute('data-subpanel');
106              }),
107              showPanel = this.getAttribute('data-show-panel');
108   
109          if (panels.length) {
110              activateSubPanel(showPanel, panels);
111              $childNodes.click(function () {
112                  activateSubPanel(this.getAttribute('data-subpanel'), panels);
113                  return false;
114              });
115          }
116      });
117  });
118   
119  /**
120  * Activate specific subPanel
121  */
122  function activateSubPanel(p, panels) {
123      'use strict';
124   
125      var i, showPanel;
126   
127      if (typeof(p) === 'string') {
128          showPanel = p;
129      }
130      $('input[name="show_panel"]').val(showPanel);
131   
132      if (typeof panels === 'undefined') {
133          panels = jQuery('.sub-panels a[data-subpanel]').map(function() {
134              return this.getAttribute('data-subpanel');
135          });
136      }
137   
138      for (i = 0; i < panels.length; i++) {
139          jQuery('#' + panels[i]).css('display', panels[i] === showPanel ? 'block' : 'none');
140          jQuery('#' + panels[i] + '-tab').toggleClass('activetab', panels[i] === showPanel);
141      }
142  }
143   
144  function selectCode(a) {
145      'use strict';
146   
147      // Get ID of code block
148      var e = a.parentNode.parentNode.getElementsByTagName('CODE')[0];
149      var s, r;
150   
151      // Not IE and IE9+
152      if (window.getSelection) {
153          s = window.getSelection();
154          // Safari and Chrome
155          if (s.setBaseAndExtent) {
156              var l = (e.innerText.length > 1) ? e.innerText.length - 1 : 1;
157              s.setBaseAndExtent(e, 0, e, l);
158          }
159          // Firefox and Opera
160          else {
161              // workaround for bug # 42885
162              if (window.opera && e.innerHTML.substring(e.innerHTML.length - 4) === '<BR>') {
163                  e.innerHTML = e.innerHTML + '&nbsp;';
164              }
165   
166              r = document.createRange();
167              r.selectNodeContents(e);
168              s.removeAllRanges();
169              s.addRange(r);
170          }
171      }
172      // Some older browsers
173      else if (document.getSelection) {
174          s = document.getSelection();
175          r = document.createRange();
176          r.selectNodeContents(e);
177          s.removeAllRanges();
178          s.addRange(r);
179      }
180      // IE
181      else if (document.selection) {
182          r = document.body.createTextRange();
183          r.moveToElementText(e);
184          r.select();
185      }
186  }
187   
188  /**
189  * Play quicktime file by determining it's width/height
190  * from the displayed rectangle area
191  */
192  function play_qt_file(obj) {
193      'use strict';
194   
195      var rectangle = obj.GetRectangle();
196      var width, height;
197   
198      if (rectangle) {
199          rectangle = rectangle.split(',');
200          var x1 = parseInt(rectangle[0], 10);
201          var x2 = parseInt(rectangle[2], 10);
202          var y1 = parseInt(rectangle[1], 10);
203          var y2 = parseInt(rectangle[3], 10);
204   
205          width = (x1 < 0) ? (x1 * -1) + x2 : x2 - x1;
206          height = (y1 < 0) ? (y1 * -1) + y2 : y2 - y1;
207      } else {
208          width = 200;
209          height = 0;
210      }
211   
212      obj.width = width;
213      obj.height = height + 16;
214   
215      obj.SetControllerVisible(true);
216      obj.Play();
217  }
218   
219  var inAutocomplete = false;
220  var lastKeyEntered = '';
221   
222  /**
223  * Check event key
224  */
225  function phpbbCheckKey(event) {
226      'use strict';
227   
228      // Keycode is array down or up?
229      if (event.keyCode && (event.keyCode === 40 || event.keyCode === 38)) {
230          inAutocomplete = true;
231      }
232   
233      // Make sure we are not within an "autocompletion" field
234      if (inAutocomplete) {
235          // If return pressed and key changed we reset the autocompletion
236          if (!lastKeyEntered || lastKeyEntered === event.which) {
237              inAutocomplete = false;
238              return true;
239          }
240      }
241   
242      // Keycode is not return, then return. ;)
243      if (event.which !== 13) {
244          lastKeyEntered = event.which;
245          return true;
246      }
247   
248      return false;
249  }
250   
251  /**
252  * Apply onkeypress event for forcing default submit button on ENTER key press
253  */
254  jQuery(function($) {
255      'use strict';
256   
257      $('form input[type=text], form input[type=password]').on('keypress', function (e) {
258          var defaultButton = $(this).parents('form').find('input[type=submit].default-submit-action');
259   
260          if (!defaultButton || defaultButton.length <= 0) {
261              return true;
262          }
263   
264          if (phpbbCheckKey(e)) {
265              return true;
266          }
267   
268          if ((e.which && e.which === 13) || (e.keyCode && e.keyCode === 13)) {
269              defaultButton.click();
270              return false;
271          }
272   
273          return true;
274      });
275  });
276   
277  /**
278  * Functions for user search popup
279  */
280  function insertUser(formId, value)
281  {
282      'use strict';
283   
284      var $form = jQuery(formId),
285          formName = $form.attr('data-form-name'),
286          fieldName = $form.attr('data-field-name'),
287          item = opener.document.forms[formName][fieldName];
288   
289      if (item.value.length && item.type == 'textarea') {
290          value = item.value + '\n' + value;
291      }
292   
293      item.value = value;
294  }
295   
296  function insert_marked_users(formId, users) {
297      'use strict';
298   
299      for (var i = 0; i < users.length; i++) {
300          if (users[i].checked) {
301              insertUser(formId, users[i].value);
302          }
303      }
304   
305      window.close();
306  }
307   
308  function insert_single_user(formId, user) {
309      'use strict';
310   
311      insertUser(formId, user);
312      window.close();
313  }
314   
315  /**
316  * Parse document block
317  */
318  function parseDocument($container) {
319      'use strict';
320   
321      var test = document.createElement('div'),
322          oldBrowser = (typeof test.style.borderRadius == 'undefined'),
323          $body = $('body');
324   
325      /**
326      * Reset avatar dimensions when changing URL or EMAIL
327      */
328      $container.find('input[data-reset-on-edit]').on('keyup', function() {
329          $(this.getAttribute('data-reset-on-edit')).val('');
330      });
331   
332      /**
333      * Pagination
334      */
335      $container.find('.pagination .page-jump-form :button').click(function() {
336          var $input = $(this).siblings('input.inputbox');
337          pageJump($input);
338      });
339   
340      $container.find('.pagination .page-jump-form input.inputbox').on('keypress', function(event) {
341          if (event.which === 13 || event.keyCode === 13) {
342              event.preventDefault();
343              pageJump($(this));
344          }
345      });
346   
347      $container.find('.pagination .dropdown-trigger').click(function() {
348          var $dropdownContainer = $(this).parent();
349          // Wait a little bit to make sure the dropdown has activated
350          setTimeout(function() {
351              if ($dropdownContainer.hasClass('dropdown-visible')) {
352                  $dropdownContainer.find('input.inputbox').focus();
353              }
354          }, 100);
355      });
356   
357      /**
358      * Adjust HTML code for IE8 and older versions
359      */
360      if (oldBrowser) {
361          // Fix .linklist.bulletin lists
362          $container.find('ul.linklist.bulletin > li:first-child, ul.linklist.bulletin > li.rightside:last-child').addClass('no-bulletin');
363      }
364   
365      /**
366      * Resize navigation (breadcrumbs) block to keep all links on same line
367      */
368      $container.find('.navlinks').each(function() {
369          var $this = $(this),
370              $left = $this.children().not('.rightside'),
371              $right = $this.children('.rightside');
372   
373          if ($left.length !== 1 || !$right.length) {
374              return;
375          }
376   
377          function resize() {
378              var width = 0,
379                  diff = $left.outerWidth(true) - $left.width();
380   
381              $right.each(function() {
382                  width += $(this).outerWidth(true);
383              });
384              $left.css('max-width', Math.floor($this.width() - width - diff) + 'px');
385          }
386   
387          resize();
388          $(window).resize(resize);
389      });
390   
391      /**
392      * Makes breadcrumbs responsive
393      */
394      $container.find('.breadcrumbs:not([data-skip-responsive])').each(function() {
395          var $this = $(this),
396              $links = $this.find('.crumb'),
397              length = $links.length,
398              classes = ['wrapped-max', 'wrapped-wide', 'wrapped-medium', 'wrapped-small', 'wrapped-tiny'],
399              classesLength = classes.length,
400              maxHeight = 0,
401              lastWidth = false,
402              wrapped = false;
403   
404          // Set tooltips
405          $this.find('a').each(function() {
406              var $link = $(this);
407              $link.attr('title', $link.text());
408          });
409   
410          // Function that checks breadcrumbs
411          function check() {
412              var height = $this.height(),
413                  width = $body.width();
414   
415              maxHeight = parseInt($this.css('line-height'));
416              $links.each(function() {
417                  if ($(this).height() > 0) {
418                      maxHeight = Math.max(maxHeight, $(this).outerHeight(true));
419                  }
420              });
421   
422              if (height <= maxHeight) {
423                  if (!wrapped || lastWidth === false || lastWidth >= width) {
424                      return;
425                  }
426              }
427              lastWidth = width;
428   
429              if (wrapped) {
430                  $this.removeClass('wrapped').find('.crumb.wrapped').removeClass('wrapped ' + classes.join(' '));
431                  if ($this.height() <= maxHeight) {
432                      return;
433                  }
434              }
435   
436              wrapped = true;
437              $this.addClass('wrapped');
438              if ($this.height() <= maxHeight) {
439                  return;
440              }
441   
442              for (var i = 0; i < classesLength; i ++) {
443                  for (var j = length - 1; j >= 0; j --) {
444                      $links.eq(j).addClass('wrapped ' + classes[i]);
445                      if ($this.height() <= maxHeight) {
446                          return;
447                      }
448                  }
449              }
450          }
451   
452          // Run function and set event
453          check();
454          $(window).resize(check);
455      });
456   
457      /**
458      * Responsive link lists
459      */
460      $container.find('.linklist:not(.navlinks, [data-skip-responsive]), .postbody .post-buttons:not([data-skip-responsive])').each(function() {
461          var $this = $(this),
462              filterSkip = '.breadcrumbs, [data-skip-responsive]',
463              filterLast = '.edit-icon, .quote-icon, [data-last-responsive]',
464              $linksAll = $this.children(),
465              $linksNotSkip = $linksAll.not(filterSkip), // All items that can potentially be hidden
466              $linksFirst = $linksNotSkip.not(filterLast), // The items that will be hidden first
467              $linksLast = $linksNotSkip.filter(filterLast), // The items that will be hidden last
468              persistent = $this.attr('id') == 'nav-main', // Does this list already have a menu (such as quick-links)?
469              html = '<li class="responsive-menu hidden"><a href="javascript:void(0);" class="responsive-menu-link">&nbsp;</a><div class="dropdown hidden"><div class="pointer"><div class="pointer-inner" /></div><ul class="dropdown-contents" /></div></li>',
470              slack = 3; // Vertical slack space (in pixels). Determines how sensitive the script is in determining whether a line-break has occured.
471   
472          // Add a hidden drop-down menu to each links list (except those that already have one)
473          if (!persistent) {
474              if ($linksNotSkip.is('.rightside')) {
475                  $linksNotSkip.filter('.rightside:first').before(html);
476                  $this.children('.responsive-menu').addClass('rightside');
477              } else {
478                  $this.append(html);
479              }
480          }
481   
482          // Set some object references and initial states
483          var $menu = $this.children('.responsive-menu'),
484              $menuContents = $menu.find('.dropdown-contents'),
485              persistentContent = $menuContents.find('li:not(.separator)').length,
486              lastWidth = false,
487              compact = false,
488              responsive1 = false,
489              responsive2 = false,
490              copied1 = false,
491              copied2 = false,
492              maxHeight = 0;
493   
494          // Find the tallest element in the list (we assume that all elements are roughly the same height)
495          $linksAll.each(function() {
496              if (!$(this).height()) {
497                  return;
498              }
499              maxHeight = Math.max(maxHeight, $(this).outerHeight(true));
500          });
501          if (maxHeight < 1) {
502              return; // Shouldn't be possible, but just in case, abort
503          } else {
504              maxHeight = maxHeight + slack;
505          }
506   
507          function check() {
508              var width = $body.width();
509              // We can't make it any smaller than this, so just skip
510              if (responsive2 && compact && (width <= lastWidth)) {
511                  return;
512              }
513              lastWidth = width;
514   
515              // Reset responsive and compact layout
516              if (responsive1 || responsive2) {
517                  $linksNotSkip.removeClass('hidden');
518                  $menuContents.children('.clone').addClass('hidden');
519                  responsive1 = responsive2 = false;
520              }
521              if (compact) {
522                  $this.removeClass('compact');
523                  compact = false;
524              }
525   
526              // Unhide the quick-links menu if it has "persistent" content
527              if (persistent && persistentContent) {
528                  $menu.removeClass('hidden');
529              } else {
530                  $menu.addClass('hidden');
531              }
532   
533              // Nothing to resize if block's height is not bigger than tallest element's height
534              if ($this.height() <= maxHeight) {
535                  return;
536              }
537   
538              // STEP 1: Compact
539              if (!compact) {
540                  $this.addClass('compact');
541                  compact = true;
542              }
543              if ($this.height() <= maxHeight) {
544                  return;
545              }
546   
547              // STEP 2: First responsive set - compact
548              if (compact) {
549                  $this.removeClass('compact');
550                  compact = false;
551              }
552              // Copy the list items to the dropdown
553              if (!copied1) {
554                  var $clones1 = $linksFirst.clone();
555                  $menuContents.prepend($clones1.addClass('clone clone-first').removeClass('leftside rightside'));
556   
557                  if ($this.hasClass('post-buttons')) {
558                      $('.button', $menuContents).removeClass('button icon-button');
559                      $('.responsive-menu-link', $menu).addClass('button icon-button').prepend('<span></span>');
560                  }
561                  copied1 = true;
562              }
563              if (!responsive1) {
564                  $linksFirst.addClass('hidden');
565                  responsive1 = true;
566                  $menuContents.children('.clone-first').removeClass('hidden');
567                  $menu.removeClass('hidden');
568              }
569              if ($this.height() <= maxHeight) {
570                  return;
571              }
572   
573              // STEP 3: First responsive set + compact
574              if (!compact) {
575                  $this.addClass('compact');
576                  compact = true;
577              }
578              if ($this.height() <= maxHeight) {
579                  return;
580              }
581   
582              // STEP 4: Last responsive set - compact
583              if (!$linksLast.length) {
584                  return; // No other links to hide, can't do more
585              }
586              if (compact) {
587                  $this.removeClass('compact');
588                  compact = false;
589              }
590              // Copy the list items to the dropdown
591              if (!copied2) {
592                  var $clones2 = $linksLast.clone();
593                  $menuContents.prepend($clones2.addClass('clone clone-last').removeClass('leftside rightside'));
594                  copied2 = true;
595              }
596              if (!responsive2) {
597                  $linksLast.addClass('hidden');
598                  responsive2 = true;
599                  $menuContents.children('.clone-last').removeClass('hidden');
600              }
601              if ($this.height() <= maxHeight) {
602                  return;
603              }
604   
605              // STEP 5: Last responsive set + compact
606              if (!compact) {
607                  $this.addClass('compact');
608                  compact = true;
609              }
610          }
611   
612          if (!persistent) {
613              phpbb.registerDropdown($menu.find('a.responsive-menu-link'), $menu.find('.dropdown'), false);
614          }
615   
616          // If there are any images in the links list, run the check again after they have loaded
617          $linksAll.find('img').each(function() {
618              $(this).load(function() {
619                  check();
620              });
621          });
622   
623          check();
624          $(window).resize(check);
625      });
626   
627      /**
628      * Do not run functions below for old browsers
629      */
630      if (oldBrowser) {
631          return;
632      }
633   
634      /**
635      * Adjust topiclist lists with check boxes
636      */
637      $container.find('ul.topiclist dd.mark').siblings('dt').children('.list-inner').addClass('with-mark');
638   
639      /**
640      * Appends contents of all extra columns to first column in
641      * .topiclist lists for mobile devices. Copies contents as is.
642      *
643      * To add that functionality to .topiclist list simply add
644      * responsive-show-all to list of classes
645      */
646      $container.find('.topiclist.responsive-show-all > li > dl').each(function() {
647          var $this = $(this),
648              $block = $this.find('dt .responsive-show:last-child'),
649              first = true;
650   
651          // Create block that is visible only on mobile devices
652          if (!$block.length) {
653              $this.find('dt > .list-inner').append('<div class="responsive-show" style="display:none;" />');
654              $block = $this.find('dt .responsive-show:last-child');
655          } else {
656              first = ($.trim($block.text()).length === 0);
657          }
658   
659          // Copy contents of each column
660          $this.find('dd').not('.mark').each(function() {
661              var column = $(this),
662                  $children = column.children(),
663                  html = column.html();
664   
665              if ($children.length == 1 && $children.text() == column.text()) {
666                  html = $children.html();
667              }
668   
669              $block.append((first ? '' : '<br />') + html);
670   
671              first = false;
672          });
673      });
674   
675      /**
676      * Same as above, but prepends text from header to each
677      * column before contents of that column.
678      *
679      * To add that functionality to .topiclist list simply add
680      * responsive-show-columns to list of classes
681      */
682      $container.find('.topiclist.responsive-show-columns').each(function() {
683          var $list = $(this),
684              headers = [],
685              headersLength = 0;
686   
687          // Find all headers, get contents
688          $list.prev('.topiclist').find('li.header dd').not('.mark').each(function() {
689              headers.push($(this).text());
690              headersLength++;
691          });
692   
693          if (!headersLength) {
694              return;
695          }
696   
697          // Parse each row
698          $list.find('dl').each(function() {
699              var $this = $(this),
700                  $block = $this.find('dt .responsive-show:last-child'),
701                  first = true;
702   
703              // Create block that is visible only on mobile devices
704              if (!$block.length) {
705                  $this.find('dt > .list-inner').append('<div class="responsive-show" style="display:none;" />');
706                  $block = $this.find('dt .responsive-show:last-child');
707              }
708              else {
709                  first = ($.trim($block.text()).length === 0);
710              }
711   
712              // Copy contents of each column
713              $this.find('dd').not('.mark').each(function(i) {
714                  var column = $(this),
715                      children = column.children(),
716                      html = column.html();
717   
718                  if (children.length == 1 && children.text() == column.text()) {
719                      html = children.html();
720                  }
721   
722                  // Prepend contents of matching header before contents of column
723                  if (i < headersLength) {
724                      html = headers[i] + ': <strong>' + html + '</strong>';
725                  }
726   
727                  $block.append((first ? '' : '<br />') + html);
728   
729                  first = false;
730              });
731          });
732      });
733   
734      /**
735      * Responsive tables
736      */
737      $container.find('table.table1').not('.not-responsive').each(function() {
738          var $this = $(this),
739              $th = $this.find('thead > tr > th'),
740              headers = [],
741              totalHeaders = 0,
742              i, headersLength;
743   
744          // Find each header
745          $th.each(function(column) {
746              var cell = $(this),
747                  colspan = parseInt(cell.attr('colspan')),
748                  dfn = cell.attr('data-dfn'),
749                  text = dfn ? dfn : cell.text();
750   
751              colspan = isNaN(colspan) || colspan < 1 ? 1 : colspan;
752   
753              for (i = 0; i < colspan; i++) {
754                  headers.push(text);
755              }
756              totalHeaders++;
757   
758              if (dfn && !column) {
759                  $this.addClass('show-header');
760              }
761          });
762   
763          headersLength = headers.length;
764   
765          // Add header text to each cell as <dfn>
766          $this.addClass('responsive');
767   
768          if (totalHeaders < 2) {
769              $this.addClass('show-header');
770              return;
771          }
772   
773          $this.find('tbody > tr').each(function() {
774              var row = $(this),
775                  cells = row.children('td'),
776                  column = 0;
777   
778              if (cells.length == 1) {
779                  row.addClass('big-column');
780                  return;
781              }
782   
783              cells.each(function() {
784                  var cell = $(this),
785                      colspan = parseInt(cell.attr('colspan')),
786                      text = $.trim(cell.text());
787   
788                  if (headersLength <= column) {
789                      return;
790                  }
791   
792                  if ((text.length && text !== '-') || cell.children().length) {
793                      cell.prepend('<dfn style="display: none;">' + headers[column] + '</dfn>');
794                  } else {
795                      cell.addClass('empty');
796                  }
797   
798                  colspan = isNaN(colspan) || colspan < 1 ? 1 : colspan;
799                  column += colspan;
800              });
801          });
802      });
803   
804      /**
805      * Hide empty responsive tables
806      */
807      $container.find('table.responsive > tbody').not('.responsive-skip-empty').each(function() {
808          var $items = $(this).children('tr');
809          if (!$items.length) {
810              $(this).parent('table:first').addClass('responsive-hide');
811          }
812      });
813   
814      /**
815      * Responsive tabs
816      */
817      $container.find('#tabs, #minitabs').not('[data-skip-responsive]').each(function() {
818          var $this = $(this),
819              $ul = $this.children(),
820              $tabs = $ul.children().not('[data-skip-responsive]'),
821              $links = $tabs.children('a'),
822              $item = $ul.append('<li class="tab responsive-tab" style="display:none;"><a href="javascript:void(0);" class="responsive-tab-link">&nbsp;</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'),
823              $menu = $item.find('.dropdown-contents'),
824              maxHeight = 0,
825              lastWidth = false,
826              responsive = false;
827   
828          $links.each(function() {
829              var $this = $(this);
830              maxHeight = Math.max(maxHeight, Math.max($this.outerHeight(true), $this.parent().outerHeight(true)));
831          });
832   
833          function check() {
834              var width = $body.width(),
835                  height = $this.height();
836   
837              if (!arguments.length && (!responsive || width <= lastWidth) && height <= maxHeight) {
838                  return;
839              }
840   
841              $tabs.show();
842              $item.hide();
843   
844              lastWidth = width;
845              height = $this.height();
846              if (height <= maxHeight) {
847                  if ($item.hasClass('dropdown-visible')) {
848                      phpbb.toggleDropdown.call($item.find('a.responsive-tab-link').get(0));
849                  }
850                  return;
851              }
852   
853              responsive = true;
854              $item.show();
855              $menu.html('');
856   
857              var $availableTabs = $tabs.filter(':not(.activetab, .responsive-tab)'),
858                  total = $availableTabs.length,
859                  i, $tab;
860   
861              for (i = total - 1; i >= 0; i --) {
862                  $tab = $availableTabs.eq(i);
863                  $menu.prepend($tab.clone(true).removeClass('tab'));
864                  $tab.hide();
865                  if ($this.height() <= maxHeight) {
866                      $menu.find('a').click(function() { check(true); });
867                      return;
868                  }
869              }
870              $menu.find('a').click(function() { check(true); });
871          }
872   
873          phpbb.registerDropdown($item.find('a.responsive-tab-link'), $item.find('.dropdown'), {visibleClass: 'activetab'});
874   
875          check(true);
876          $(window).resize(check);
877      });
878   
879      /**
880       * Hide UCP/MCP navigation if there is only 1 item
881       */
882      $container.find('#navigation').each(function() {
883          var $items = $(this).children('ol, ul').children('li');
884          if ($items.length === 1) {
885              $(this).addClass('responsive-hide');
886          }
887      });
888   
889      /**
890      * Replace responsive text
891      */
892      $container.find('[data-responsive-text]').each(function() {
893          var $this = $(this),
894              fullText = $this.text(),
895              responsiveText = $this.attr('data-responsive-text'),
896              responsive = false;
897   
898          function check() {
899              if ($(window).width() > 700) {
900                  if (!responsive) {
901                      return;
902                  }
903                  $this.text(fullText);
904                  responsive = false;
905                  return;
906              }
907              if (responsive) {
908                  return;
909              }
910              $this.text(responsiveText);
911              responsive = true;
912          }
913   
914          check();
915          $(window).resize(check);
916      });
917  }
918   
919  /**
920  * Run onload functions
921  */
922  jQuery(function($) {
923      'use strict';
924   
925      // Swap .nojs and .hasjs
926      $('#phpbb.nojs').toggleClass('nojs hasjs');
927      $('#phpbb').toggleClass('hastouch', phpbb.isTouch);
928      $('#phpbb.hastouch').removeClass('notouch');
929   
930      // Focus forms
931      $('form[data-focus]:first').each(function() {
932          $('#' + this.getAttribute('data-focus')).focus();
933      });
934   
935      parseDocument($('body'));
936  });
937