This commit is contained in:
Matt Friedman 2025-06-01 18:46:06 +02:00 committed by GitHub
commit 33c3dd509d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 4817 additions and 4261 deletions

4
.github/check-js.sh vendored
View file

@ -14,6 +14,6 @@ set +x
sudo npm install -g > /dev/null sudo npm install -g > /dev/null
npm ci > /dev/null npm ci > /dev/null
set -x set -x
node_modules/eslint/bin/eslint.js "phpBB/**/*.js" node_modules/eslint/bin/eslint.js "phpBB/**/*.js" --ignore-pattern "phpBB/ext/"
node_modules/eslint/bin/eslint.js "phpBB/**/*.js.twig" node_modules/eslint/bin/eslint.js "phpBB/**/*.js.twig" --ignore-pattern "phpBB/ext/"
node_modules/eslint/bin/eslint.js "gulpfile.js" node_modules/eslint/bin/eslint.js "gulpfile.js"

67
eslint.config.mjs Normal file
View file

@ -0,0 +1,67 @@
const { browser: browserGlobals, node: nodeGlobals, jquery: jqueryGlobals } = (await import('globals')).default;
// File patterns to ignore
const IGNORED_FILES = [
'phpBB/assets/javascript/cropper.js',
'phpBB/assets/javascript/hermite.js',
'phpBB/assets/javascript/jquery-cropper.js',
'phpBB/**/*.min.js',
'phpBB/vendor/**/*.js',
'phpBB/vendor-ext/**/*.js',
'phpBB/phpbb/**/*.js',
'phpBB/tests/**/*.js',
];
// ESLint rule configurations
const FORMATTING_RULES = {
'quotes': ['error', 'single'],
'comma-dangle': ['error', 'always-multiline'],
'block-spacing': 'error',
'array-bracket-spacing': ['error', 'always'],
'object-curly-spacing': ['error', 'always'],
'space-before-function-paren': ['error', 'never'],
'space-in-parens': 'off',
};
const CODE_QUALITY_RULES = {
'semi': ['error', 'always'],
'eqeqeq': ['error', 'always'],
'curly': ['error', 'multi-line'],
'no-var': 'error',
'prefer-const': 'error',
'no-console': 'off',
'no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
};
const DISABLED_STYLE_RULES = {
'multiline-comment-style': 'off',
'computed-property-spacing': 'off',
'capitalized-comments': 'off',
'no-lonely-if': 'off',
};
const mainConfig = {
files: ['**/*.js', '**/*.js.twig'],
linterOptions: {
reportUnusedDisableDirectives: false,
},
languageOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
globals: {
...browserGlobals,
...nodeGlobals,
...jqueryGlobals,
},
},
rules: {
...FORMATTING_RULES,
...CODE_QUALITY_RULES,
...DISABLED_STYLE_RULES,
},
};
export default [
{ ignores: IGNORED_FILES },
mainConfig,
];

1780
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -6,65 +6,6 @@
"directories": { "directories": {
"doc": "docs" "doc": "docs"
}, },
"eslintConfig": {
"extends": "xo",
"ignorePatterns": [
"phpBB/adm/style/admin.js",
"phpBB/adm/style/ajax.js",
"phpBB/adm/style/permissions.js",
"phpBB/adm/style/tooltip.js",
"phpBB/assets/javascript/core.js",
"phpBB/assets/javascript/cropper.js",
"phpBB/assets/javascript/editor.js",
"phpBB/assets/javascript/hermite.js",
"phpBB/assets/javascript/installer.js",
"phpBB/assets/javascript/jquery-cropper.js",
"phpBB/assets/javascript/plupload.js",
"phpBB/ext/**/*.js",
"phpBB/styles/prosilver/template/ajax.js",
"phpBB/styles/prosilver/template/forum_fn.js",
"phpBB/**/*.min.js",
"phpBB/vendor/**/*.js",
"phpBB/vendor-ext/**/*.js",
"phpBB/phpbb/**/*.js",
"phpBB/tests/**/*.js"
],
"rules": {
"quotes": [
"error",
"single"
],
"comma-dangle": [
"error",
"always-multiline"
],
"block-spacing": "error",
"array-bracket-spacing": [
"error",
"always"
],
"multiline-comment-style": "off",
"computed-property-spacing": "off",
"space-before-function-paren": [
"error",
"never"
],
"space-in-parens": "off",
"capitalized-comments": "off",
"object-curly-spacing": [
"error",
"always"
],
"no-lonely-if": "off",
"unicorn/prefer-module": "off"
},
"env": {
"es6": true,
"browser": true,
"node": true,
"jquery": true
}
},
"browserslist": [ "browserslist": [
"> 1%", "> 1%",
"not ie 11", "not ie 11",
@ -101,8 +42,8 @@
"devDependencies": { "devDependencies": {
"autoprefixer": "^10.4.4", "autoprefixer": "^10.4.4",
"cssnano": "^5.1.7", "cssnano": "^5.1.7",
"eslint": "^8.13.0", "eslint": "^9.28.0",
"eslint-config-xo": "^0.40.0", "globals": "^16.2.0",
"gulp": "^5.0.0", "gulp": "^5.0.0",
"gulp-concat": "^2.6.1", "gulp-concat": "^2.6.1",
"gulp-postcss": "^9.0.1", "gulp-postcss": "^9.0.1",

View file

@ -1,4 +1,5 @@
/* global phpbb */ /* global phpbb */
/* eslint no-var: 0 */
/** /**
* phpBB ACP functions * phpBB ACP functions
@ -7,19 +8,16 @@
/** /**
* Parse document block * Parse document block
*/ */
function parse_document(container) function parseDocument(container) {
{ var test = document.createElement('div');
var test = document.createElement('div'),
oldBrowser = (typeof test.style.borderRadius == 'undefined');
test.remove(); test.remove();
/** /**
* Navigation * Navigation
*/ */
container.find('#menu').each(function() { container.find('#menu').each(function() {
var menu = $(this), var menu = $(this);
blocks = menu.children('.menu-block'); var blocks = menu.children('.menu-block');
if (!blocks.length) { if (!blocks.length) {
return; return;
@ -31,6 +29,7 @@ function parse_document(container)
if (!parent.hasClass('active')) { if (!parent.hasClass('active')) {
parent.siblings().removeClass('active'); parent.siblings().removeClass('active');
} }
parent.toggleClass('active'); parent.toggleClass('active');
}); });
@ -47,12 +46,11 @@ function parse_document(container)
* Responsive tables * Responsive tables
*/ */
container.find('table').not('.not-responsive').each(function() { container.find('table').not('.not-responsive').each(function() {
var $this = $(this), var $this = $(this);
th = $this.find('thead > tr > th'), var th = $this.find('thead > tr > th');
columns = th.length, var headers = [];
headers = [], var totalHeaders = 0;
totalHeaders = 0, var i;
i, headersLength;
// Find columns // Find columns
$this.find('colgroup:first').children().each(function(i) { $this.find('colgroup:first').children().each(function(i) {
@ -71,21 +69,24 @@ function parse_document(container)
} }
// Find each header // Find each header
if (!$this.data('no-responsive-header')) if (!$this.data('no-responsive-header')) {
{
th.each(function(column) { th.each(function(column) {
var cell = $(this), var cell = $(this);
colspan = parseInt(cell.attr('colspan')), var colspan = parseInt(cell.attr('colspan'), 10);
dfn = cell.attr('data-dfn'), var dfn = cell.attr('data-dfn');
text = dfn ? dfn : $.trim(cell.text()); var text = dfn ? dfn : $.trim(cell.text());
if (text === ' ') {
text = '';
}
if (text == ' ') text = '';
colspan = isNaN(colspan) || colspan < 1 ? 1 : colspan; colspan = isNaN(colspan) || colspan < 1 ? 1 : colspan;
for (i=0; i<colspan; i++) { for (i = 0; i < colspan; i++) {
headers.push(text); headers.push(text);
} }
totalHeaders ++;
totalHeaders++;
if (dfn && !column) { if (dfn && !column) {
$this.addClass('show-header'); $this.addClass('show-header');
@ -104,19 +105,19 @@ function parse_document(container)
} }
$this.find('tbody > tr').each(function() { $this.find('tbody > tr').each(function() {
var row = $(this), var row = $(this);
cells = row.children('td'), var cells = row.children('td');
column = 0; var column = 0;
if (cells.length == 1) { if (cells.length === 1) {
row.addClass('big-column'); row.addClass('big-column');
return; return;
} }
cells.each(function() { cells.each(function() {
var cell = $(this), var cell = $(this);
colspan = parseInt(cell.attr('colspan')), var colspan = parseInt(cell.attr('colspan'), 10);
text = $.trim(cell.text()); var text = $.trim(cell.text());
if (headersLength <= column) { if (headersLength <= column) {
return; return;
@ -124,10 +125,9 @@ function parse_document(container)
if ((text.length && text !== '-') || cell.children().length) { if ((text.length && text !== '-') || cell.children().length) {
if (headers[column].length) { if (headers[column].length) {
cell.prepend($("<dfn>").css('display', 'none').text(headers[column])); cell.prepend($('<dfn>').css('display', 'none').text(headers[column]));
} }
} } else {
else {
cell.addClass('empty'); cell.addClass('empty');
} }
@ -145,8 +145,7 @@ function parse_document(container)
*/ */
container.find('table.responsive > tbody').each(function() { container.find('table.responsive > tbody').each(function() {
var items = $(this).children('tr'); var items = $(this).children('tr');
if (!items.length) if (!items.length) {
{
$(this).parent('table:first').addClass('responsive-hide'); $(this).parent('table:first').addClass('responsive-hide');
} }
}); });
@ -156,7 +155,7 @@ function parse_document(container)
*/ */
container.find('fieldset dt > span:last-child').each(function() { container.find('fieldset dt > span:last-child').each(function() {
var $this = $(this); var $this = $(this);
if ($this.html() == '&nbsp;') { if ($this.html() === '&nbsp;') {
$this.addClass('responsive-hide'); $this.addClass('responsive-hide');
} }
}); });
@ -180,25 +179,25 @@ function parse_document(container)
* Responsive tabs * Responsive tabs
*/ */
container.find('#tabs').not('[data-skip-responsive]').each(function() { container.find('#tabs').not('[data-skip-responsive]').each(function() {
var $this = $(this), var $this = $(this);
$body = $('body'), var $body = $('body');
ul = $this.children(), var ul = $this.children();
tabs = ul.children().not('[data-skip-responsive]'), var tabs = ul.children().not('[data-skip-responsive]');
links = tabs.children('a'), var links = tabs.children('a');
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></div><ul class="dropdown-contents" /></div></li>').find('li.responsive-tab'), var 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></div><ul class="dropdown-contents" /></div></li>').find('li.responsive-tab');
menu = item.find('.dropdown-contents'), var menu = item.find('.dropdown-contents');
maxHeight = 0, var maxHeight = 0;
lastWidth = false, var lastWidth = false;
responsive = false; var responsive = false;
links.each(function() { links.each(function() {
var link = $(this); var link = $(this);
maxHeight = Math.max(maxHeight, Math.max(link.outerHeight(true), link.parent().outerHeight(true))); maxHeight = Math.max(maxHeight, Math.max(link.outerHeight(true), link.parent().outerHeight(true)));
}) });
function check() { function check() {
var width = $body.width(), var width = $body.width();
height = $this.height(); var height = $this.height();
if (!arguments.length && (!responsive || width <= lastWidth) && height <= maxHeight) { if (!arguments.length && (!responsive || width <= lastWidth) && height <= maxHeight) {
return; return;
@ -214,6 +213,7 @@ function parse_document(container)
if (item.hasClass('dropdown-visible')) { if (item.hasClass('dropdown-visible')) {
phpbb.toggleDropdown.call(item.find('a.responsive-tab-link').get(0)); phpbb.toggleDropdown.call(item.find('a.responsive-tab-link').get(0));
} }
return; return;
} }
@ -221,23 +221,29 @@ function parse_document(container)
item.show(); item.show();
menu.html(''); menu.html('');
var availableTabs = tabs.filter(':not(.activetab, .responsive-tab)'), var availableTabs = tabs.filter(':not(.activetab, .responsive-tab)');
total = availableTabs.length, var total = availableTabs.length;
i, tab; var i;
var tab;
for (i = total - 1; i >= 0; i --) { for (i = total - 1; i >= 0; i--) {
tab = availableTabs.eq(i); tab = availableTabs.eq(i);
menu.prepend(tab.clone(true).removeClass('tab')); menu.prepend(tab.clone(true).removeClass('tab'));
tab.hide(); tab.hide();
if ($this.height() <= maxHeight) { if ($this.height() <= maxHeight) {
menu.find('a').click(function() { check(true); }); menu.find('a').click(() => {
check(true);
});
return; return;
} }
} }
menu.find('a').click(function() { check(true); });
menu.find('a').click(() => {
check(true);
});
} }
phpbb.registerDropdown(item.find('a.responsive-tab-link'), item.find('.dropdown'), {visibleClass: 'activetab', verticalDirection: 'down'}); phpbb.registerDropdown(item.find('a.responsive-tab-link'), item.find('.dropdown'), { visibleClass: 'activetab', verticalDirection: 'down' });
check(true); check(true);
$(window).resize(check); $(window).resize(check);
@ -248,7 +254,7 @@ function parse_document(container)
* Run onload functions * Run onload functions
*/ */
(function($) { (function($) {
$(document).ready(function() { $(document).ready(() => {
// Swap .nojs and .hasjs // Swap .nojs and .hasjs
$('body.nojs').toggleClass('nojs hasjs'); $('body.nojs').toggleClass('nojs hasjs');
@ -257,12 +263,12 @@ function parse_document(container)
$('#' + this.getAttribute('data-focus')).focus(); $('#' + this.getAttribute('data-focus')).focus();
}); });
parse_document($('body')); parseDocument($('body'));
$('#questionnaire-form').css('display', 'none'); $('#questionnaire-form').css('display', 'none');
var $triggerConfiglist = $('#trigger-configlist'); var $triggerConfiglist = $('#trigger-configlist');
$triggerConfiglist.on('click', function () { $triggerConfiglist.on('click', function() {
var $configlist = $('#configlist'); var $configlist = $('#configlist');
$configlist.closest('.send-stats-data-row').toggleClass('send-stats-data-hidden'); $configlist.closest('.send-stats-data-row').toggleClass('send-stats-data-hidden');
$configlist.closest('.send-stats-row').find('.send-stats-data-row:first-child').toggleClass('send-stats-data-only-row'); $configlist.closest('.send-stats-row').find('.send-stats-data-row:first-child').toggleClass('send-stats-data-only-row');
@ -272,8 +278,8 @@ function parse_document(container)
$('#configlist').closest('.send-stats-data-row').addClass('send-stats-data-hidden'); $('#configlist').closest('.send-stats-data-row').addClass('send-stats-data-hidden');
// Do not underline actions icons on hover (could not be done via CSS) // Do not underline actions icons on hover (could not be done via CSS)
$('.actions a:has(i.acp-icon)').mouseover(function () { $('.actions a:has(i.acp-icon)').mouseover(function() {
$(this).css("text-decoration", "none"); $(this).css('text-decoration', 'none');
}); });
// Live update BBCode font icon preview // Live update BBCode font icon preview
@ -296,11 +302,11 @@ function parse_document(container)
const pageIconFont = document.getElementById('bbcode_font_icon'); const pageIconFont = document.getElementById('bbcode_font_icon');
if (pageIconFont) { if (pageIconFont) {
pageIconFont.addEventListener('keyup', function () { pageIconFont.addEventListener('keyup', function() {
updateIconClass(this.nextElementSibling, this.value); updateIconClass(this.nextElementSibling, this.value);
}); });
pageIconFont.addEventListener('blur', function () { pageIconFont.addEventListener('blur', function() {
updateIconClass(this.nextElementSibling, this.value); updateIconClass(this.nextElementSibling, this.value);
}); });
} }

View file

@ -1,29 +1,27 @@
/* global phpbb, statsData */ /* global phpbb, statsData */
/* eslint no-var: 0 */
(function($) { // Avoid conflicts with other libraries (function($) { // Avoid conflicts with other libraries
'use strict';
'use strict'; phpbb.prepareSendStats = function() {
phpbb.prepareSendStats = function () {
var $form = $('#acp_help_phpbb'); var $form = $('#acp_help_phpbb');
var $dark = $('#darkenwrapper'); var $dark = $('#darkenwrapper');
var $loadingIndicator; var $loadingIndicator;
$form.on('submit', function (event) { $form.on('submit', function(event) {
var $this = $(this), var $this = $(this);
currentTime = Math.floor(new Date().getTime() / 1000), var currentTime = Math.floor(new Date().getTime() / 1000);
statsTime = parseInt($this.find('input[name=help_send_statistics_time]').val(), 10); var statsTime = parseInt($this.find('input[name=help_send_statistics_time]').val(), 10);
event.preventDefault(); event.preventDefault();
$this.unbind('submit'); $this.unbind('submit');
// Skip ajax request if form is submitted too early or send stats // Skip ajax request if form is submitted too early or send stats
// checkbox is not checked // checkbox is not checked
if (!$this.find('input[name=help_send_statistics]').is(':checked') || if (!$this.find('input[name=help_send_statistics]').is(':checked') || statsTime > currentTime) {
statsTime > currentTime) {
$form.find('input[type=submit]').click(); $form.find('input[type=submit]').click();
setTimeout(function () { setTimeout(() => {
$form.find('input[type=submit]').click(); $form.find('input[type=submit]').click();
}, 300); }, 300);
return; return;
@ -36,6 +34,7 @@ phpbb.prepareSendStats = function () {
if (typeof console !== 'undefined' && console.log) { if (typeof console !== 'undefined' && console.log) {
console.log('AJAX error. status: ' + textStatus + ', message: ' + errorThrown); console.log('AJAX error. status: ' + textStatus + ', message: ' + errorThrown);
} }
phpbb.clearLoadingTimeout(); phpbb.clearLoadingTimeout();
var errorText = ''; var errorText = '';
@ -47,6 +46,7 @@ phpbb.prepareSendStats = function () {
errorText = $dark.attr('data-ajax-error-text'); errorText = $dark.attr('data-ajax-error-text');
} }
} }
phpbb.alert($dark.attr('data-ajax-error-title'), errorText); phpbb.alert($dark.attr('data-ajax-error-title'), errorText);
} }
@ -74,7 +74,7 @@ phpbb.prepareSendStats = function () {
var $sendStatisticsSuccess = $('<input />', { var $sendStatisticsSuccess = $('<input />', {
type: 'hidden', type: 'hidden',
name: 'send_statistics_response', name: 'send_statistics_response',
value: JSON.stringify(res) value: JSON.stringify(res),
}); });
$sendStatisticsSuccess.appendTo('p.submit-buttons'); $sendStatisticsSuccess.appendTo('p.submit-buttons');
@ -90,78 +90,77 @@ phpbb.prepareSendStats = function () {
data: statsData, data: statsData,
success: returnHandler, success: returnHandler,
error: errorHandler, error: errorHandler,
cache: false cache: false,
}).always(function() { }).always(() => {
if ($loadingIndicator && $loadingIndicator.is(':visible')) { if ($loadingIndicator && $loadingIndicator.is(':visible')) {
$loadingIndicator.fadeOut(phpbb.alertTime); $loadingIndicator.fadeOut(phpbb.alertTime);
} }
}); });
}); });
}; };
/** /**
* The following callbacks are for reording items. row_down * The following callbacks are for reording items. row_down
* is triggered when an item is moved down, and row_up is triggered when * is triggered when an item is moved down, and row_up is triggered when
* an item is moved up. It moves the row up or down, and deactivates / * an item is moved up. It moves the row up or down, and deactivates /
* activates any up / down icons that require it (the ones at the top or bottom). * activates any up / down icons that require it (the ones at the top or bottom).
*/ */
phpbb.addAjaxCallback('row_down', function(res) { phpbb.addAjaxCallback('row_down', function(res) {
if (typeof res.success === 'undefined' || !res.success) { if (typeof res.success === 'undefined' || !res.success) {
return; return;
} }
var $firstTr = $(this).parents('tr'), var $firstTr = $(this).parents('tr');
$secondTr = $firstTr.next(); var $secondTr = $firstTr.next();
$firstTr.insertAfter($secondTr); $firstTr.insertAfter($secondTr);
}); });
phpbb.addAjaxCallback('row_up', function(res) { phpbb.addAjaxCallback('row_up', function(res) {
if (typeof res.success === 'undefined' || !res.success) { if (typeof res.success === 'undefined' || !res.success) {
return; return;
} }
var $secondTr = $(this).parents('tr'), var $secondTr = $(this).parents('tr');
$firstTr = $secondTr.prev(); var $firstTr = $secondTr.prev();
$secondTr.insertBefore($firstTr); $secondTr.insertBefore($firstTr);
}); });
/** /**
* This callback replaces activate links with deactivate links and vice versa. * This callback replaces activate links with deactivate links and vice versa.
* It does this by replacing the text, and replacing all instances of "activate" * It does this by replacing the text, and replacing all instances of "activate"
* in the href with "deactivate", and vice versa. * in the href with "deactivate", and vice versa.
*/ */
phpbb.addAjaxCallback('activate_deactivate', function(res) { phpbb.addAjaxCallback('activate_deactivate', function(res) {
var $this = $(this), var $this = $(this);
newHref = $this.attr('href'); var newHref = $this.attr('href');
$this.text(res.text); $this.text(res.text);
if (newHref.indexOf('deactivate') !== -1) { if (newHref.indexOf('deactivate') === -1) {
newHref = newHref.replace('deactivate', 'activate');
} else {
newHref = newHref.replace('activate', 'deactivate'); newHref = newHref.replace('activate', 'deactivate');
} else {
newHref = newHref.replace('deactivate', 'activate');
} }
$this.attr('href', newHref); $this.attr('href', newHref);
}); });
/** /**
* The removes the parent row of the link or form that triggered the callback, * The removes the parent row of the link or form that triggered the callback,
* and is good for stuff like the removal of forums. * and is good for stuff like the removal of forums.
*/ */
phpbb.addAjaxCallback('row_delete', function(res) { phpbb.addAjaxCallback('row_delete', function(res) {
if (res.SUCCESS !== false) { if (res.SUCCESS !== false) {
$(this).parents('tr').remove(); $(this).parents('tr').remove();
} }
}); });
/** /**
* This callback generates the VAPID keys for the web push notification service. * This callback generates the VAPID keys for the web push notification service.
*/ */
phpbb.addAjaxCallback('generate_vapid_keys', () => { phpbb.addAjaxCallback('generate_vapid_keys', () => {
/** /**
* Generate VAPID keypair with public and private key string * Generate VAPID keypair with public and private key string
* *
@ -176,7 +175,7 @@ phpbb.addAjaxCallback('generate_vapid_keys', () => {
namedCurve: 'P-256', namedCurve: 'P-256',
}, },
true, true,
['deriveKey', 'deriveBits'] [ 'deriveKey', 'deriveBits' ],
); );
const privateKeyJwk = await crypto.subtle.exportKey('jwk', keyPair.privateKey); const privateKeyJwk = await crypto.subtle.exportKey('jwk', keyPair.privateKey);
@ -187,7 +186,7 @@ phpbb.addAjaxCallback('generate_vapid_keys', () => {
return { return {
privateKey: privateKeyString, privateKey: privateKeyString,
publicKey: publicKeyString publicKey: publicKeyString,
}; };
} catch (error) { } catch (error) {
console.error('Error generating keys with SubtleCrypto:', error); console.error('Error generating keys with SubtleCrypto:', error);
@ -199,38 +198,38 @@ phpbb.addAjaxCallback('generate_vapid_keys', () => {
if (!keyPair) { if (!keyPair) {
return; return;
} }
const publicKeyInput = document.querySelector('#webpush_vapid_public'); const publicKeyInput = document.querySelector('#webpush_vapid_public');
const privateKeyInput = document.querySelector('#webpush_vapid_private'); const privateKeyInput = document.querySelector('#webpush_vapid_private');
publicKeyInput.value = keyPair.publicKey; publicKeyInput.value = keyPair.publicKey;
privateKeyInput.value = keyPair.privateKey; privateKeyInput.value = keyPair.privateKey;
}) });
}) });
/** /**
* Handler for submitting permissions form in chunks * Handler for submitting permissions form in chunks
* This call will submit permissions forms in chunks of 5 fieldsets. * This call will submit permissions forms in chunks of 5 fieldsets.
*/ */
function submitPermissions() { function submitPermissions() {
var $form = $('form#set-permissions'), var $form = $('form#set-permissions');
fieldsetList = $form.find('fieldset[id^=perm]'), var fieldsetList = $form.find('fieldset[id^=perm]');
formDataSets = [], var formDataSets = [];
dataSetIndex = 0, var dataSetIndex = 0;
$submitAllButton = $form.find('input[type=submit][name^=action]')[0], var $submitAllButton = $form.find('input[type=submit][name^=action]')[0];
$submitButton = $form.find('input[type=submit][data-clicked=true]')[0]; var $submitButton = $form.find('input[type=submit][data-clicked=true]')[0];
// Set proper start values for handling refresh of page // Set proper start values for handling refresh of page
var permissionSubmitSize = 0, var permissionSubmitSize = 0;
permissionRequestCount = 0, var permissionRequestCount = 0;
forumIds = [], var forumIds = [];
permissionSubmitFailed = false, var permissionSubmitFailed = false;
clearIndicator = true, var clearIndicator = true;
$loadingIndicator;
if ($submitAllButton !== $submitButton) { if ($submitAllButton !== $submitButton) {
fieldsetList = $form.find('fieldset#' + $submitButton.closest('fieldset.permissions').id); fieldsetList = $form.find('fieldset#' + $submitButton.closest('fieldset.permissions').id);
} }
$.each(fieldsetList, function (key, value) { $.each(fieldsetList, (key, value) => {
dataSetIndex = Math.floor(key / 5); dataSetIndex = Math.floor(key / 5);
var $fieldset = $('fieldset#' + value.id); var $fieldset = $('fieldset#' + value.id);
if (key % 5 === 0) { if (key % 5 === 0) {
@ -244,21 +243,21 @@ function submitPermissions() {
if (roleInput.val()) { if (roleInput.val()) {
formDataSets[dataSetIndex] += '&' + roleInput.attr('name') + '=' + roleInput.val(); formDataSets[dataSetIndex] += '&' + roleInput.attr('name') + '=' + roleInput.val();
} else { } else {
formDataSets[dataSetIndex] += '&' + roleInput.attr('name') + '=' + formDataSets[dataSetIndex] += '&' + roleInput.attr('name') + '='
$fieldset.find('select[name="' + roleInput.attr('name') + '"]').val(); + $fieldset.find('select[name="' + roleInput.attr('name') + '"]').val();
} }
}); });
permissionSubmitSize = formDataSets.length; permissionSubmitSize = formDataSets.length;
// Add each forum ID to forum ID list to preserve selected forums // Add each forum ID to forum ID list to preserve selected forums
$.each($form.find('input[type=hidden][name^=forum_id]'), function (key, value) { $.each($form.find('input[type=hidden][name^=forum_id]'), (key, value) => {
if (value.name.match(/^forum_id\[([0-9]+)\]$/)) { if (value.name.match(/^forum_id\[([0-9]+)\]$/)) {
forumIds.push(value.value); forumIds.push(value.value);
} }
}); });
$loadingIndicator = phpbb.loadingIndicator(); var $loadingIndicator = phpbb.loadingIndicator();
/** /**
* Handler for submitted permissions form chunk * Handler for submitted permissions form chunk
@ -286,18 +285,18 @@ function submitPermissions() {
$alertBoxLink.attr('href', $alertBoxLink.attr('href').replace(/(&forum_id\[\]=[0-9]+)/g, '')); $alertBoxLink.attr('href', $alertBoxLink.attr('href').replace(/(&forum_id\[\]=[0-9]+)/g, ''));
const $previousPageForm = $('<form>').attr({ const $previousPageForm = $('<form>').attr({
action: $alertBoxLink.attr('href'), action: $alertBoxLink.attr('href'),
method: 'post' method: 'post',
}); });
$.each(forumIds, function (key, value) { $.each(forumIds, (key, value) => {
$previousPageForm.append($('<input>').attr({ $previousPageForm.append($('<input>').attr({
type: 'text', type: 'text',
name: 'forum_id[]', name: 'forum_id[]',
value: value value,
})); }));
}); });
$alertBoxLink.on('click', function (e) { $alertBoxLink.on('click', e => {
$('body').append($previousPageForm); $('body').append($previousPageForm);
e.preventDefault(); e.preventDefault();
$previousPageForm.submit(); $previousPageForm.submit();
@ -309,19 +308,19 @@ function submitPermissions() {
$alert.find('.alert_close').hide(); $alert.find('.alert_close').hide();
if (typeof res.REFRESH_DATA !== 'undefined') { if (typeof res.REFRESH_DATA !== 'undefined') {
setTimeout(function () { setTimeout(() => {
// Create forum to submit using POST. This will prevent // Create forum to submit using POST. This will prevent
// exceeding the maximum length of URLs // exceeding the maximum length of URLs
const $form = $('<form>').attr({ const $form = $('<form>').attr({
action: res.REFRESH_DATA.url.replace(/(&forum_id\[\]=[0-9]+)/g, ''), action: res.REFRESH_DATA.url.replace(/(&forum_id\[\]=[0-9]+)/g, ''),
method: 'post' method: 'post',
}); });
$.each(forumIds, function (key, value) { $.each(forumIds, (key, value) => {
$form.append($('<input>').attr({ $form.append($('<input>').attr({
type: 'text', type: 'text',
name: 'forum_id[]', name: 'forum_id[]',
value: value value,
})); }));
}); });
@ -329,7 +328,7 @@ function submitPermissions() {
// Hide the alert even if we refresh the page, in case the user // Hide the alert even if we refresh the page, in case the user
// presses the back button. // presses the back button.
$dark.fadeOut(phpbb.alertTime, function () { $dark.fadeOut(phpbb.alertTime, () => {
if (typeof $alert !== 'undefined') { if (typeof $alert !== 'undefined') {
$alert.hide(); $alert.hide();
} }
@ -355,44 +354,44 @@ function submitPermissions() {
} }
// Create AJAX request for each form data set // Create AJAX request for each form data set
$.each(formDataSets, function (key, formData) { $.each(formDataSets, (key, formData) => {
$.ajax({ $.ajax({
url: $form.action, url: $form.action,
type: 'POST', type: 'POST',
data: formData + '&' + $submitButton.name + '=' + encodeURIComponent($submitButton.value) + data: formData + '&' + $submitButton.name + '=' + encodeURIComponent($submitButton.value)
'&creation_time=' + $form.find('input[type=hidden][name=creation_time]')[0].value + + '&creation_time=' + $form.find('input[type=hidden][name=creation_time]')[0].value
'&form_token=' + $form.find('input[type=hidden][name=form_token]')[0].value + + '&form_token=' + $form.find('input[type=hidden][name=form_token]')[0].value
'&' + $form.children('input[type=hidden]').serialize() + + '&' + $form.children('input[type=hidden]').serialize()
'&' + $form.find('input[type=checkbox][name^=inherit]').serialize(), + '&' + $form.find('input[type=checkbox][name^=inherit]').serialize(),
success: handlePermissionReturn, success: handlePermissionReturn,
error: handlePermissionReturn error: handlePermissionReturn,
}); });
}); });
} }
$('[data-ajax]').each(function() { $('[data-ajax]').each(function() {
var $this = $(this), var $this = $(this);
ajax = $this.attr('data-ajax'); var ajax = $this.attr('data-ajax');
if (ajax !== 'false') { if (ajax !== 'false') {
var fn = (ajax !== 'true') ? ajax : null; var fn = (ajax === 'true') ? null : ajax;
phpbb.ajaxify({ phpbb.ajaxify({
selector: this, selector: this,
refresh: $this.attr('data-refresh') !== undefined, refresh: $this.attr('data-refresh') !== undefined,
callback: fn callback: fn,
}); });
} }
}); });
/** /**
* Automatically resize textarea * Automatically resize textarea
*/ */
$(function() { $(() => {
phpbb.resizeTextArea($('textarea:not(.no-auto-resize)'), {minHeight: 75}); phpbb.resizeTextArea($('textarea:not(.no-auto-resize)'), { minHeight: 75 });
var $setPermissionsForm = $('form#set-permissions'); var $setPermissionsForm = $('form#set-permissions');
if ($setPermissionsForm.length) { if ($setPermissionsForm.length) {
$setPermissionsForm.on('submit', function (e) { $setPermissionsForm.on('submit', e => {
submitPermissions(); submitPermissions();
e.preventDefault(); e.preventDefault();
}); });
@ -412,13 +411,11 @@ $(function() {
} else { } else {
dateoptionInput.value = this.value; dateoptionInput.value = this.value;
} }
}) });
} }
if ($('#acp_help_phpbb')) { if ($('#acp_help_phpbb')) {
phpbb.prepareSendStats(); phpbb.prepareSendStats();
} }
}); });
})(jQuery); // Avoid conflicts with other libraries })(jQuery); // Avoid conflicts with other libraries

View file

@ -1,4 +1,8 @@
/* global phpbb */ /* global phpbb */
/* eslint camelcase: 0 */
/* eslint no-undef: 0 */
/* eslint no-unused-vars: 0 */
/* eslint no-var: 0 */
/** /**
* Hide and show all checkboxes * Hide and show all checkboxes
@ -9,12 +13,11 @@ function display_checkboxes(status) {
var cb = document.getElementsByTagName('input'); var cb = document.getElementsByTagName('input');
var display; var display;
//show
if (status) { if (status) {
// show
display = 'inline'; display = 'inline';
} } else {
//hide // hide
else {
display = 'none'; display = 'none';
} }
@ -31,10 +34,10 @@ function display_checkboxes(status) {
* value = 0 (hidden) till 10 (fully visible) * value = 0 (hidden) till 10 (fully visible)
*/ */
function set_opacity(e, value) { function set_opacity(e, value) {
e.style.opacity = value/10; e.style.opacity = value / 10;
//IE opacity currently turned off, because of its astronomical stupidity // IE opacity currently turned off, because of its astronomical stupidity
//e.style.filter = 'alpha(opacity=' + value*10 + ')'; // e.style.filter = 'alpha(opacity=' + value*10 + ')';
} }
/** /**
@ -72,11 +75,11 @@ function reset_opacity(status, except_id) {
} }
} }
if (typeof(except_id) !== 'undefined') { if (typeof (except_id) !== 'undefined') {
set_opacity(document.getElementById('perm' + except_id), 10); set_opacity(document.getElementById('perm' + except_id), 10);
} }
//reset checkboxes too // reset checkboxes too
marklist('set-permissions', 'inherit', !status); marklist('set-permissions', 'inherit', !status);
} }
@ -86,13 +89,14 @@ function reset_opacity(status, except_id) {
* rb = array of radiobuttons * rb = array of radiobuttons
*/ */
function get_radio_status(index, rb) { function get_radio_status(index, rb) {
for (var i = index; i < rb.length; i = i + 3 ) { for (var i = index; i < rb.length; i += 3 ) {
if (rb[i].checked !== true) { if (rb[i].checked !== true) {
if (i > index) { if (i > index) {
//at least one is true, but not all (custom) // at least one is true, but not all (custom)
return 2; return 2;
} }
//first one is not true
// first one is not true
return 0; return 0;
} }
} }
@ -111,7 +115,7 @@ function set_colours(id, init, quick) {
var table = document.getElementById('table' + id); var table = document.getElementById('table' + id);
var tab = document.getElementById('tab' + id); var tab = document.getElementById('tab' + id);
if (typeof(quick) !== 'undefined') { if (typeof (quick) !== 'undefined') {
tab.className = 'permissions-preset-' + quick + ' activetab'; tab.className = 'permissions-preset-' + quick + ' activetab';
return; return;
} }
@ -161,7 +165,7 @@ function init_colours(block_id) {
} }
} }
tab.className = tab.className + ' activetab'; tab.className += ' activetab';
} }
/** /**
@ -170,6 +174,7 @@ function init_colours(block_id) {
* adv = we are opening advanced permissions * adv = we are opening advanced permissions
* view = called from view permissions * view = called from view permissions
*/ */
// eslint-disable-next-line max-params
function swap_options(pmask, fmask, cat, adv, view) { function swap_options(pmask, fmask, cat, adv, view) {
id = pmask + fmask + cat; id = pmask + fmask + cat;
active_option = active_pmask + active_fmask + active_cat; active_option = active_pmask + active_fmask + active_cat;
@ -196,14 +201,14 @@ function swap_options(pmask, fmask, cat, adv, view) {
display_checkboxes(true); display_checkboxes(true);
reset_opacity(1); reset_opacity(1);
} else if (adv) { } else if (adv) {
//Checkbox might have been clicked, but we need full visibility // Checkbox might have been clicked, but we need full visibility
display_checkboxes(true); display_checkboxes(true);
reset_opacity(1); reset_opacity(1);
} }
// set active tab // set active tab
old_tab.className = old_tab.className.replace(/\ activetab/g, ''); old_tab.className = old_tab.className.replace(/ activetab/g, '');
new_tab.className = new_tab.className + ' activetab'; new_tab.className += ' activetab';
if (id === active_option && adv !== true) { if (id === active_option && adv !== true) {
return; return;
@ -211,7 +216,7 @@ function swap_options(pmask, fmask, cat, adv, view) {
phpbb.toggleDisplay('options' + active_option, -1); phpbb.toggleDisplay('options' + active_option, -1);
//hiding and showing the checkbox // hiding and showing the checkbox
if (document.getElementById('checkbox' + active_pmask + active_fmask)) { if (document.getElementById('checkbox' + active_pmask + active_fmask)) {
phpbb.toggleDisplay('checkbox' + pmask + fmask, -1); phpbb.toggleDisplay('checkbox' + pmask + fmask, -1);
@ -227,6 +232,7 @@ function swap_options(pmask, fmask, cat, adv, view) {
if (!view) { if (!view) {
phpbb.toggleDisplay('advanced' + pmask + fmask, 1); phpbb.toggleDisplay('advanced' + pmask + fmask, 1);
} }
phpbb.toggleDisplay('options' + id, 1); phpbb.toggleDisplay('options' + id, 1);
active_pmask = pmask; active_pmask = pmask;
@ -248,7 +254,7 @@ function mark_options(id, s) {
var rb = t.getElementsByTagName('input'); var rb = t.getElementsByTagName('input');
for (var r = 0; r < rb.length; r++) { for (var r = 0; r < rb.length; r++) {
if (rb[r].id.substr(rb[r].id.length-1) === s) { if (rb[r].id.substr(rb[r].id.length - 1) === s) {
rb[r].checked = true; rb[r].checked = true;
} }
} }
@ -264,7 +270,7 @@ function mark_one_option(id, field_name, s) {
var rb = t.getElementsByTagName('input'); var rb = t.getElementsByTagName('input');
for (var r = 0; r < rb.length; r++) { for (var r = 0; r < rb.length; r++) {
if (rb[r].id.substr(rb[r].id.length-field_name.length-3, field_name.length) === field_name && rb[r].id.substr(rb[r].id.length-1) === s) { if (rb[r].id.substr(rb[r].id.length - field_name.length - 3, field_name.length) === field_name && rb[r].id.substr(rb[r].id.length - 1) === s) {
rb[r].checked = true; rb[r].checked = true;
} }
} }
@ -287,10 +293,10 @@ function reset_role(id) {
} }
// Before resetting the role dropdown, try and match any permission role // Before resetting the role dropdown, try and match any permission role
var parent = t.parentNode, var parent = t.parentNode;
roleId = match_role_settings(id.replace('role', 'perm')), var roleId = match_role_settings(id.replace('role', 'perm'));
text = no_role_assigned, var text = no_role_assigned;
index = 0; var index = 0;
// If a role permissions was matched, grab that option's value and index // If a role permissions was matched, grab that option's value and index
if (roleId) { if (roleId) {
@ -326,8 +332,10 @@ function set_role_settings(role_id, target_id) {
mark_options(target_id, 'u'); mark_options(target_id, 'u');
for (var r in settings) { for (var r in settings) {
if (Object.prototype.hasOwnProperty.call(settings, r)) {
mark_one_option(target_id, r, (settings[r] === 1) ? 'y' : 'n'); mark_one_option(target_id, r, (settings[r] === 1) ? 'y' : 'n');
} }
}
} }
/** /**
@ -337,9 +345,9 @@ function set_role_settings(role_id, target_id) {
* @return {number} The permission role identifier * @return {number} The permission role identifier
*/ */
function match_role_settings(id) { function match_role_settings(id) {
var fieldset = document.getElementById(id), var fieldset = document.getElementById(id);
radios = fieldset.getElementsByTagName('input'), var radios = fieldset.getElementsByTagName('input');
set = {}; var set = {};
// Iterate over all the radio buttons // Iterate over all the radio buttons
for (var i = 0; i < radios.length; i++) { for (var i = 0; i < radios.length; i++) {
@ -355,8 +363,7 @@ function match_role_settings(id) {
set = sort_and_stringify(set); set = sort_and_stringify(set);
// Iterate over the available role options and return the first match // Iterate over the available role options and return the first match
for (var r in role_options) for (var r in role_options) {
{
if (sort_and_stringify(role_options[r]) === set) { if (sort_and_stringify(role_options[r]) === set) {
return parseInt(r, 10); return parseInt(r, 10);
} }
@ -372,7 +379,7 @@ function match_role_settings(id) {
* @return {string} The sorted object as a string * @return {string} The sorted object as a string
*/ */
function sort_and_stringify(obj) { function sort_and_stringify(obj) {
return JSON.stringify(Object.keys(obj).sort().reduce(function (result, key) { return JSON.stringify(Object.keys(obj).sort().reduce((result, key) => {
result[key] = obj[key]; result[key] = obj[key];
return result; return result;
}, {})); }, {}));

View file

@ -1,4 +1,5 @@
/* global phpbb */ /* global phpbb */
/* eslint no-var: 0 */
/* /*
javascript for Bubble Tooltips by Alessandro Fulciniti javascript for Bubble Tooltips by Alessandro Fulciniti
@ -13,36 +14,35 @@ phpBB Development Team:
*/ */
(function($) { // Avoid conflicts with other libraries (function($) { // Avoid conflicts with other libraries
'use strict';
'use strict'; var tooltips = [];
var tooltips = []; /**
/**
* Enable tooltip replacements for selects * Enable tooltip replacements for selects
* @param {string} id ID tag of select * @param {string} id ID tag of select
* @param {string} headline Text that should appear on top of tooltip * @param {string} headline Text that should appear on top of tooltip
* @param {string} [subId] Sub ID that should only be using tooltips (optional) * @param {string} [subId] Sub ID that should only be using tooltips (optional)
*/ */
phpbb.enableTooltipsSelect = function (id, headline, subId) { phpbb.enableTooltipsSelect = function(id, headline, subId) {
var $links, hold; var $links;
hold = $('<span />', { var hold = $('<span />', {
id: '_tooltip_container', id: '_tooltip_container',
css: { css: {
position: 'absolute' position: 'absolute',
} },
}); });
$('body').append(hold); $('body').append(hold);
if (!id) { if (id) {
$links = $('.roles-options li');
} else {
$links = $('.roles-options li', '#' + id); $links = $('.roles-options li', '#' + id);
} else {
$links = $('.roles-options li');
} }
$links.each(function () { $links.each(function() {
var $this = $(this); var $this = $(this);
if (subId) { if (subId) {
@ -53,44 +53,42 @@ phpbb.enableTooltipsSelect = function (id, headline, subId) {
phpbb.prepareTooltips($this, headline); phpbb.prepareTooltips($this, headline);
} }
}); });
}; };
/** /**
* Prepare elements to replace * Prepare elements to replace
* *
* @param {jQuery} $element Element to prepare for tooltips * @param {jQuery} $element Element to prepare for tooltips
* @param {string} headText Text heading to display * @param {string} headText Text heading to display
*/ */
phpbb.prepareTooltips = function ($element, headText) { phpbb.prepareTooltips = function($element, headText) {
var $tooltip, text, $desc, $title; var text = $element.attr('data-title');
text = $element.attr('data-title');
if (text === null || text.length === 0) { if (text === null || text.length === 0) {
return; return;
} }
$title = $('<span />', { var $title = $('<span />', {
class: 'top', class: 'top',
css: { css: {
display: 'block' display: 'block',
} },
}) })
.append(document.createTextNode(headText)); .append(document.createTextNode(headText));
$desc = $('<span />', { var $desc = $('<span />', {
class: 'bottom', class: 'bottom',
html: text, html: text,
css: { css: {
display: 'block' display: 'block',
} },
}); });
$tooltip = $('<span />', { var $tooltip = $('<span />', {
class: 'tooltip', class: 'tooltip',
css: { css: {
display: 'block' display: 'block',
} },
}) })
.append($title) .append($title)
.append($desc); .append($desc);
@ -98,63 +96,61 @@ phpbb.prepareTooltips = function ($element, headText) {
tooltips[$element.attr('data-id')] = $tooltip; tooltips[$element.attr('data-id')] = $tooltip;
$element.on('mouseover', phpbb.showTooltip); $element.on('mouseover', phpbb.showTooltip);
$element.on('mouseout', phpbb.hideTooltip); $element.on('mouseout', phpbb.hideTooltip);
}; };
/** /**
* Show tooltip * Show tooltip
* *
* @param {object} $element Element passed by .on() * @param {object} $element Element passed by .on()
*/ */
phpbb.showTooltip = function ($element) { phpbb.showTooltip = function($element) {
var $this = $($element.target); var $this = $($element.target);
$('#_tooltip_container').append(tooltips[$this.attr('data-id')]); $('#_tooltip_container').append(tooltips[$this.attr('data-id')]);
phpbb.positionTooltip($this); phpbb.positionTooltip($this);
}; };
/** /**
* Hide tooltip * Hide tooltip
*/ */
phpbb.hideTooltip = function () { phpbb.hideTooltip = function() {
var d = document.getElementById('_tooltip_container'); var d = document.getElementById('_tooltip_container');
if (d.childNodes.length > 0) { if (d.childNodes.length > 0) {
d.removeChild(d.firstChild); d.removeChild(d.firstChild);
} }
}; };
/** /**
* Correct positioning of tooltip container * Correct positioning of tooltip container
* *
* @param {jQuery} $element Tooltip element that should be positioned * @param {jQuery} $element Tooltip element that should be positioned
*/ */
phpbb.positionTooltip = function ($element) { phpbb.positionTooltip = function($element) {
var offset;
$element = $element.parent(); $element = $element.parent();
offset = $element.offset(); var offset = $element.offset();
if ($('body').hasClass('rtl')) { if ($('body').hasClass('rtl')) {
$('#_tooltip_container').css({ $('#_tooltip_container').css({
top: offset.top + 30, top: offset.top + 30,
left: offset.left + 255 left: offset.left + 255,
}); });
} else { } else {
$('#_tooltip_container').css({ $('#_tooltip_container').css({
top: offset.top + 30, top: offset.top + 30,
left: offset.left - 205 left: offset.left - 205,
}); });
} }
}; };
/** /**
* Prepare roles drop down select * Prepare roles drop down select
*/ */
phpbb.prepareRolesDropdown = function () { phpbb.prepareRolesDropdown = function() {
var $options = $('.roles-options li'); var $options = $('.roles-options li');
// Display span and hide select // Display span and hide select
$('.roles-options > span').css('display', 'block'); $('.roles-options > span').css('display', 'block');
$('.roles-options > select').hide(); $('.roles-options > select').hide();
$('.roles-options > input[type=hidden]').each(function () { $('.roles-options > input[type=hidden]').each(function() {
var $this = $(this); var $this = $(this);
if ($this.attr('data-name') && !$this.attr('name')) { if ($this.attr('data-name') && !$this.attr('name')) {
@ -163,7 +159,7 @@ phpbb.prepareRolesDropdown = function () {
}); });
// Prepare highlighting of select options and settings update // Prepare highlighting of select options and settings update
$options.each(function () { $options.each(function() {
var $this = $(this); var $this = $(this);
var $rolesOptions = $this.closest('.roles-options'); var $rolesOptions = $this.closest('.roles-options');
var $span = $rolesOptions.children('span'); var $span = $rolesOptions.children('span');
@ -182,23 +178,25 @@ phpbb.prepareRolesDropdown = function () {
} }
// Prepare resetting drop down on form reset // Prepare resetting drop down on form reset
$this.closest('form').on('reset', function () { $this.closest('form').on('reset', () => {
$span.text($span.attr('data-default')); $span.text($span.attr('data-default'));
$rolesOptions.children('input[type=hidden]') $rolesOptions.children('input[type=hidden]')
.val($span.attr('data-default-val')); .val($span.attr('data-default-val'));
}); });
} }
$this.on('mouseover', function () { $this.on('mouseover', function() {
var $this = $(this); var $this = $(this);
$options.removeClass('roles-highlight'); $options.removeClass('roles-highlight');
$this.addClass('roles-highlight'); $this.addClass('roles-highlight');
}).on('click', function () { }).on('click', function() {
var $this = $(this); var $this = $(this);
var $rolesOptions = $this.closest('.roles-options'); var $rolesOptions = $this.closest('.roles-options');
// Update settings // Update settings
// eslint-disable-next-line no-undef
set_role_settings($this.attr('data-id'), $this.attr('data-target-id')); set_role_settings($this.attr('data-id'), $this.attr('data-target-id'));
// eslint-disable-next-line no-undef
init_colours($this.attr('data-target-id').replace('advanced', '')); init_colours($this.attr('data-target-id').replace('advanced', ''));
// Set selected setting // Set selected setting
@ -211,15 +209,14 @@ phpbb.prepareRolesDropdown = function () {
$('body').trigger('click'); $('body').trigger('click');
}); });
}); });
}; };
// Run onload functions for RolesDropdown and tooltips // Run onload functions for RolesDropdown and tooltips
$(function() { $(() => {
// Enable tooltips // Enable tooltips
phpbb.enableTooltipsSelect('set-permissions', $('#set-permissions').attr('data-role-description'), 'role'); phpbb.enableTooltipsSelect('set-permissions', $('#set-permissions').attr('data-role-description'), 'role');
// Prepare dropdown // Prepare dropdown
phpbb.prepareRolesDropdown(); phpbb.prepareRolesDropdown();
}); });
})(jQuery); // Avoid conflicts with other libraries })(jQuery); // Avoid conflicts with other libraries

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,11 @@
/* global phpbb */ /* global phpbb */
/* eslint camelcase: 0 */
/* eslint no-undef: 0 */
/* eslint no-unused-vars: 0 */
/* eslint no-var: 0 */
var form_name = 'postform';
var text_name = 'message';
/** /**
* bbCode control by subBlue design [ www.subBlue.com ] * bbCode control by subBlue design [ www.subBlue.com ]
@ -34,7 +41,7 @@ function initInsertions() {
var textarea = doc.forms[form_name].elements[text_name]; var textarea = doc.forms[form_name].elements[text_name];
if (is_ie && typeof(baseHeight) !== 'number') { if (is_ie && typeof (baseHeight) !== 'number') {
textarea.focus(); textarea.focus();
baseHeight = doc.selection.createRange().duplicate().boundingHeight; baseHeight = doc.selection.createRange().duplicate().boundingHeight;
@ -48,11 +55,11 @@ function initInsertions() {
* bbstyle * bbstyle
*/ */
function bbstyle(bbnumber) { function bbstyle(bbnumber) {
if (bbnumber !== -1) { if (bbnumber === -1) {
bbfontstyle(bbtags[bbnumber], bbtags[bbnumber+1]);
} else {
insert_text('[*]'); insert_text('[*]');
document.forms[form_name].elements[text_name].focus(); document.forms[form_name].elements[text_name].focus();
} else {
bbfontstyle(bbtags[bbnumber], bbtags[bbnumber + 1]);
} }
} }
@ -84,7 +91,7 @@ function bbfontstyle(bbopen, bbclose) {
return; return;
} }
//The new position for the cursor after adding the bbcode // The new position for the cursor after adding the bbcode
var caret_pos = getCaretPosition(textarea).start; var caret_pos = getCaretPosition(textarea).start;
var new_pos = caret_pos + bbopen.length; var new_pos = caret_pos + bbopen.length;
@ -96,11 +103,10 @@ function bbfontstyle(bbopen, bbclose) {
if (!isNaN(textarea.selectionStart)) { if (!isNaN(textarea.selectionStart)) {
textarea.selectionStart = new_pos; textarea.selectionStart = new_pos;
textarea.selectionEnd = new_pos; textarea.selectionEnd = new_pos;
} } else if (document.selection) {
// IE // IE
else if (document.selection) {
var range = textarea.createTextRange(); var range = textarea.createTextRange();
range.move("character", new_pos); range.move('character', new_pos);
range.select(); range.select();
storeCaret(textarea); storeCaret(textarea);
} }
@ -114,10 +120,10 @@ function bbfontstyle(bbopen, bbclose) {
function insert_text(text, spaces, popup) { function insert_text(text, spaces, popup) {
var textarea; var textarea;
if (!popup) { if (popup) {
textarea = document.forms[form_name].elements[text_name];
} else {
textarea = opener.document.forms[form_name].elements[text_name]; textarea = opener.document.forms[form_name].elements[text_name];
} else {
textarea = document.forms[form_name].elements[text_name];
} }
if (spaces) { if (spaces) {
@ -142,7 +148,7 @@ function insert_text(text, spaces, popup) {
var caret_pos = textarea.caretPos; var caret_pos = textarea.caretPos;
caret_pos.text = caret_pos.text.charAt(caret_pos.text.length - 1) === ' ' ? caret_pos.text + text + ' ' : caret_pos.text + text; caret_pos.text = caret_pos.text.charAt(caret_pos.text.length - 1) === ' ' ? caret_pos.text + text + ' ' : caret_pos.text + text;
} else { } else {
textarea.value = textarea.value + text; textarea.value += text;
} }
if (!popup) { if (!popup) {
@ -171,6 +177,7 @@ function addquote(post_id, username, l_wrote, attributes) {
// Backwards compatibility // Backwards compatibility
l_wrote = 'wrote'; l_wrote = 'wrote';
} }
if (typeof attributes !== 'object') { if (typeof attributes !== 'object') {
attributes = {}; attributes = {};
} }
@ -195,10 +202,10 @@ function addquote(post_id, username, l_wrote, attributes) {
if (divarea.innerHTML) { if (divarea.innerHTML) {
theSelection = divarea.innerHTML.replace(/<br>/ig, '\n'); theSelection = divarea.innerHTML.replace(/<br>/ig, '\n');
theSelection = theSelection.replace(/<br\/>/ig, '\n'); theSelection = theSelection.replace(/<br\/>/ig, '\n');
theSelection = theSelection.replace(/&lt\;/ig, '<'); theSelection = theSelection.replace(/&lt;/ig, '<');
theSelection = theSelection.replace(/&gt\;/ig, '>'); theSelection = theSelection.replace(/&gt;/ig, '>');
theSelection = theSelection.replace(/&amp\;/ig, '&'); theSelection = theSelection.replace(/&amp;/ig, '&');
theSelection = theSelection.replace(/&nbsp\;/ig, ' '); theSelection = theSelection.replace(/&nbsp;/ig, ' ');
} else if (document.all) { } else if (document.all) {
theSelection = divarea.innerText; theSelection = divarea.innerText;
} else if (divarea.textContent) { } else if (divarea.textContent) {
@ -213,7 +220,7 @@ function addquote(post_id, username, l_wrote, attributes) {
attributes.author = username; attributes.author = username;
insert_text(generateQuote(theSelection, attributes)); insert_text(generateQuote(theSelection, attributes));
} else { } else {
insert_text(username + ' ' + l_wrote + ':' + '\n'); insert_text(username + ' ' + l_wrote + ':\n');
var lines = split_lines(theSelection); var lines = split_lines(theSelection);
for (i = 0; i < lines.length; i++) { for (i = 0; i < lines.length; i++) {
insert_text('> ' + lines[i] + '\n'); insert_text('> ' + lines[i] + '\n');
@ -243,12 +250,14 @@ function generateQuote(text, attributes) {
quote += '=' + formatAttributeValue(attributes.author); quote += '=' + formatAttributeValue(attributes.author);
delete attributes.author; delete attributes.author;
} }
for (var name in attributes) { for (var name in attributes) {
if (attributes.hasOwnProperty(name)) { if (Object.hasOwn(attributes, name)) {
var value = attributes[name]; var value = attributes[name];
quote += ' ' + name + '=' + formatAttributeValue(value.toString()); quote += ' ' + name + '=' + formatAttributeValue(value.toString());
} }
} }
quote += ']'; quote += ']';
var newline = ((quote + text + '[/quote]').length > 80 || text.indexOf('\n') > -1) ? '\n' : ''; var newline = ((quote + text + '[/quote]').length > 80 || text.indexOf('\n') > -1) ? '\n' : '';
quote += newline + text + newline + '[/quote]'; quote += newline + text + newline + '[/quote]';
@ -271,19 +280,20 @@ function formatAttributeValue(str) {
// Return as-is if it contains none of: space, ' " \ or ] // Return as-is if it contains none of: space, ' " \ or ]
return str; return str;
} }
var singleQuoted = "'" + str.replace(/[\\']/g, '\\$&') + "'",
doubleQuoted = '"' + str.replace(/[\\"]/g, '\\$&') + '"'; var singleQuoted = '\'' + str.replace(/[\\']/g, '\\$&') + '\'';
var doubleQuoted = '"' + str.replace(/[\\"]/g, '\\$&') + '"';
return (singleQuoted.length < doubleQuoted.length) ? singleQuoted : doubleQuoted; return (singleQuoted.length < doubleQuoted.length) ? singleQuoted : doubleQuoted;
} }
function split_lines(text) { function split_lines(text) {
var lines = text.split('\n'); var lines = text.split('\n');
var splitLines = new Array(); var splitLines = [];
var j = 0; var j = 0;
var i; var i;
for(i = 0; i < lines.length; i++) { for (i = 0; i < lines.length; i++) {
if (lines[i].length <= 80) { if (lines[i].length <= 80) {
splitLines[j] = lines[i]; splitLines[j] = lines[i];
j++; j++;
@ -302,9 +312,10 @@ function split_lines(text) {
j++; j++;
} }
} }
while(splitAt !== -1); while (splitAt !== -1);
} }
} }
return splitLines; return splitLines;
} }
@ -312,12 +323,12 @@ function split_lines(text) {
* From http://www.massless.org/mozedit/ * From http://www.massless.org/mozedit/
*/ */
function mozWrap(txtarea, open, close) { function mozWrap(txtarea, open, close) {
var selLength = (typeof(txtarea.textLength) === 'undefined') ? txtarea.value.length : txtarea.textLength; var selLength = (typeof (txtarea.textLength) === 'undefined') ? txtarea.value.length : txtarea.textLength;
var selStart = txtarea.selectionStart; var selStart = txtarea.selectionStart;
var selEnd = txtarea.selectionEnd; var selEnd = txtarea.selectionEnd;
var scrollTop = txtarea.scrollTop; var scrollTop = txtarea.scrollTop;
var s1 = (txtarea.value).substring(0,selStart); var s1 = (txtarea.value).substring(0, selStart);
var s2 = (txtarea.value).substring(selStart, selEnd); var s2 = (txtarea.value).substring(selStart, selEnd);
var s3 = (txtarea.value).substring(selEnd, selLength); var s3 = (txtarea.value).substring(selEnd, selLength);
@ -326,8 +337,6 @@ function mozWrap(txtarea, open, close) {
txtarea.selectionEnd = selEnd + open.length; txtarea.selectionEnd = selEnd + open.length;
txtarea.focus(); txtarea.focus();
txtarea.scrollTop = scrollTop; txtarea.scrollTop = scrollTop;
return;
} }
/** /**
@ -358,9 +367,8 @@ function getCaretPosition(txtarea) {
if (txtarea.selectionStart || txtarea.selectionStart === 0) { if (txtarea.selectionStart || txtarea.selectionStart === 0) {
caretPos.start = txtarea.selectionStart; caretPos.start = txtarea.selectionStart;
caretPos.end = txtarea.selectionEnd; caretPos.end = txtarea.selectionEnd;
} } else if (document.selection) {
// dirty and slow IE way // dirty and slow IE way
else if (document.selection) {
// get current selection // get current selection
var range = document.selection.createRange(); var range = document.selection.createRange();
@ -404,7 +412,7 @@ function getCaretPosition(txtarea) {
phpbb.showDragNDrop(textarea); phpbb.showDragNDrop(textarea);
} }
$('textarea').on('keydown', function (e) { $('textarea').on('keydown', function(e) {
if (e.which === 13 && (e.metaKey || e.ctrlKey)) { if (e.which === 13 && (e.metaKey || e.ctrlKey)) {
$(this).closest('form').find(':submit').click(); $(this).closest('form').find(':submit').click();
} }

View file

@ -2,6 +2,9 @@
* Installer's AJAX frontend handler * Installer's AJAX frontend handler
*/ */
/* eslint no-prototype-builtins: 0 */
/* eslint no-var: 0 */
(function($) { // Avoid conflicts with other libraries (function($) { // Avoid conflicts with other libraries
'use strict'; 'use strict';
@ -46,7 +49,10 @@
var $warningContainer = $('#warning-container'); var $warningContainer = $('#warning-container');
var $logContainer = $('#log-container'); var $logContainer = $('#log-container');
var $title, $description, $msgElement, arraySize = messages.length; var $title;
var $description;
var $msgElement;
var arraySize = messages.length;
for (var i = 0; i < arraySize; i++) { for (var i = 0; i < arraySize; i++) {
$msgElement = $('<div />'); $msgElement = $('<div />');
$title = $('<strong />'); $title = $('<strong />');
@ -59,24 +65,19 @@
$msgElement.append($description); $msgElement.append($description);
} }
switch (type) { if (type === 'error') {
case 'error':
$msgElement.addClass('errorbox'); $msgElement.addClass('errorbox');
$errorContainer.append($msgElement); $errorContainer.append($msgElement);
break; } else if (type === 'warning') {
case 'warning':
$msgElement.addClass('warningbox'); $msgElement.addClass('warningbox');
$warningContainer.append($msgElement); $warningContainer.append($msgElement);
break; } else if (type === 'log') {
case 'log':
$msgElement.addClass('log'); $msgElement.addClass('log');
$logContainer.prepend($msgElement); $logContainer.prepend($msgElement);
$logContainer.addClass('show_log_container'); $logContainer.addClass('show_log_container');
break; } else if (type === 'success') {
case 'success':
$msgElement.addClass('successbox'); $msgElement.addClass('successbox');
$errorContainer.prepend($msgElement); $errorContainer.prepend($msgElement);
break;
} }
} }
} }
@ -84,10 +85,12 @@
/** /**
* Render a download box * Render a download box
*/ */
function addDownloadBox(downloadArray) function addDownloadBox(downloadArray) {
{
var $downloadContainer = $('#download-wrapper'); var $downloadContainer = $('#download-wrapper');
var $downloadBox, $title, $content, $link; var $downloadBox;
var $title;
var $content;
var $link;
for (var i = 0; i < downloadArray.length; i++) { for (var i = 0; i < downloadArray.length; i++) {
$downloadBox = $('<div />'); $downloadBox = $('<div />');
@ -116,8 +119,7 @@
/** /**
* Render update files' status * Render update files' status
*/ */
function addUpdateFileStatus(fileStatus) function addUpdateFileStatus(fileStatus) {
{
var $statusContainer = $('#file-status-wrapper'); var $statusContainer = $('#file-status-wrapper');
$statusContainer.html(fileStatus); $statusContainer.html(fileStatus);
} }
@ -140,8 +142,10 @@
* @param navObj * @param navObj
*/ */
function updateNavbarStatus(navObj) { function updateNavbarStatus(navObj) {
var navID, $stage, $stageListItem, $active; var navID;
$active = $('#activemenu'); var $stage;
var $stageListItem;
var $active = $('#activemenu');
if (navObj.hasOwnProperty('finished')) { if (navObj.hasOwnProperty('finished')) {
// This should be an Array // This should be an Array
@ -179,7 +183,11 @@
* @param progressObject * @param progressObject
*/ */
function setProgress(progressObject) { function setProgress(progressObject) {
var $statusText, $progressBar, $progressText, $progressFiller, $progressFillerText; var $statusText;
var $progressBar;
var $progressText;
var $progressFiller;
var $progressFillerText;
if (progressObject.task_name.length) { if (progressObject.task_name.length) {
if (!progressBarTriggered) { if (!progressBarTriggered) {
@ -246,8 +254,8 @@
} }
// Redirects user // Redirects user
function redirect(url, use_ajax) { function redirect(url, useAjax) {
if (use_ajax) { if (useAjax) {
resetPolling(); resetPolling();
var xhReq = createXhrObject(); var xhReq = createXhrObject();
@ -276,6 +284,7 @@
if (window.console) { if (window.console) {
console.log('Failed to parse JSON object\n\nMessage: ' + err.message + '\n\nServer Response: ' + messageJSON); console.log('Failed to parse JSON object\n\nMessage: ' + err.message + '\n\nServer Response: ' + messageJSON);
} else { } else {
// eslint-disable-next-line no-alert
alert('Failed to parse JSON object\n\nMessage: ' + err.message + '\n\nServer Response: ' + messageJSON); alert('Failed to parse JSON object\n\nMessage: ' + err.message + '\n\nServer Response: ' + messageJSON);
} }
@ -358,12 +367,14 @@
setTimeout(queryInstallerStatus, 5000); setTimeout(queryInstallerStatus, 5000);
} else { } else {
$('#loading_indicator').css('display', 'none'); $('#loading_indicator').css('display', 'none');
addMessage('error', addMessage('error', [
[{ {
// eslint-disable-next-line no-undef
title: installLang.title, title: installLang.title,
description: installLang.msg // eslint-disable-next-line no-undef
}] description: installLang.msg,
); },
]);
} }
} }
@ -385,7 +396,7 @@
} }
url = url.substring(0, position) + lookUp + '/installer/status'; url = url.substring(0, position) + lookUp + '/installer/status';
$.getJSON(url, function(data) { $.getJSON(url, data => {
processTimeoutResponse(data.status); processTimeoutResponse(data.status);
}); });
} }
@ -398,7 +409,10 @@
function pollContent(xhReq) { function pollContent(xhReq) {
var messages = xhReq.responseText; var messages = xhReq.responseText;
var msgSeparator = '}\n\n'; var msgSeparator = '}\n\n';
var unprocessed, messageEndIndex, endOfMessageIndex, message; var unprocessed;
var messageEndIndex;
var endOfMessageIndex;
var message;
do { do {
unprocessed = messages.substring(nextReadPosition); unprocessed = messages.substring(nextReadPosition);
@ -466,7 +480,7 @@
currentProgress = Math.floor(progressStart); currentProgress = Math.floor(progressStart);
clearInterval(progressTimer); clearInterval(progressTimer);
progressTimer = setInterval(function() { progressTimer = setInterval(() => {
incrementFiller($progressText, $progressFiller, $progressFillerText, progressLimit); incrementFiller($progressText, $progressFiller, $progressFillerText, progressLimit);
}, 10); }, 10);
} }
@ -487,7 +501,7 @@
function startPolling(xhReq) { function startPolling(xhReq) {
resetPolling(); resetPolling();
transmissionOver = false; transmissionOver = false;
pollTimer = setInterval(function () { pollTimer = setInterval(() => {
pollContent(xhReq); pollContent(xhReq);
}, 250); }, 250);
} }
@ -605,11 +619,13 @@
function interceptFormSubmit($form) { function interceptFormSubmit($form) {
if (!$form.length) { if (!$form.length) {
return; return;
} else if ($form.find('input[name="admin_name"]').length > 0) { }
if ($form.find('input[name="admin_name"]').length > 0) {
setAdminTimezone($form); setAdminTimezone($form);
} }
$form.find(':submit').bind('click', function (event) { $form.find(':submit').bind('click', function(event) {
event.preventDefault(); event.preventDefault();
submitForm($form, $(this)); submitForm($form, $(this));
}); });
@ -623,7 +639,8 @@
function setAdminTimezone($form) { function setAdminTimezone($form) {
// Set admin timezone if it does not exist yet // Set admin timezone if it does not exist yet
if ($form.find('input[name="admin_timezone"]').length === 0) { if ($form.find('input[name="admin_timezone"]').length === 0) {
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone; // eslint-disable-next-line new-cap
const { timeZone } = Intl.DateTimeFormat().resolvedOptions();
// Add timezone as form entry // Add timezone as form entry
const timezoneEntry = $('<input type="hidden" name="admin_timezone" value="' + timeZone + '">'); const timezoneEntry = $('<input type="hidden" name="admin_timezone" value="' + timeZone + '">');

View file

@ -1,16 +1,17 @@
/* global phpbb, plupload, attachInline */ /* global phpbb, plupload, attachInline, activateSubPanel */
/* eslint camelcase: 0 */
/* eslint no-var: 0 */
plupload.addI18n(phpbb.plupload.i18n); plupload.addI18n(phpbb.plupload.i18n);
phpbb.plupload.ids = []; phpbb.plupload.ids = [];
(function($) { // Avoid conflicts with other libraries (function($) { // Avoid conflicts with other libraries
'use strict';
'use strict'; /**
/**
* Set up the uploader. * Set up the uploader.
*/ */
phpbb.plupload.initialize = function() { phpbb.plupload.initialize = function() {
// Initialize the Plupload uploader. // Initialize the Plupload uploader.
phpbb.plupload.uploader.init(); phpbb.plupload.uploader.init();
@ -19,9 +20,9 @@ phpbb.plupload.initialize = function() {
phpbb.plupload.updateMultipartParams(phpbb.plupload.getSerializedData()); phpbb.plupload.updateMultipartParams(phpbb.plupload.getSerializedData());
// Only execute if Plupload initialized successfully. // Only execute if Plupload initialized successfully.
phpbb.plupload.uploader.bind('Init', function() { phpbb.plupload.uploader.bind('Init', () => {
phpbb.plupload.form = $(phpbb.plupload.config.form_hook)[0]; phpbb.plupload.form = $(phpbb.plupload.config.form_hook)[0];
let $attachRowTemplate = $('#attach-row-tpl'); const $attachRowTemplate = $('#attach-row-tpl');
$attachRowTemplate.removeClass('attach-row-tpl'); $attachRowTemplate.removeClass('attach-row-tpl');
phpbb.plupload.rowTpl = $attachRowTemplate[0].outerHTML; phpbb.plupload.rowTpl = $attachRowTemplate[0].outerHTML;
@ -31,7 +32,7 @@ phpbb.plupload.initialize = function() {
$('#attach-panel-multi').show(); $('#attach-panel-multi').show();
}); });
phpbb.plupload.uploader.bind('PostInit', function() { phpbb.plupload.uploader.bind('PostInit', () => {
// Point out the drag-and-drop zone if it's supported. // Point out the drag-and-drop zone if it's supported.
if (phpbb.plupload.uploader.features.dragdrop) { if (phpbb.plupload.uploader.features.dragdrop) {
$('#drag-n-drop-message').show(); $('#drag-n-drop-message').show();
@ -41,49 +42,50 @@ phpbb.plupload.initialize = function() {
if ($('#attach-panel-multi').is(':visible')) { if ($('#attach-panel-multi').is(':visible')) {
phpbb.plupload.uploader.refresh(); phpbb.plupload.uploader.refresh();
} }
$('[data-subpanel="attach-panel"]').one('click', function() {
$('[data-subpanel="attach-panel"]').one('click', () => {
phpbb.plupload.uploader.refresh(); phpbb.plupload.uploader.refresh();
}); });
}); });
}; };
/** /**
* Unsets all elements in the object uploader.settings.multipart_params whose keys * Unsets all elements in the object uploader.settings.multipart_params whose keys
* begin with 'attachment_data[' * begin with 'attachment_data['
*/ */
phpbb.plupload.clearParams = function() { phpbb.plupload.clearParams = function() {
var obj = phpbb.plupload.uploader.settings.multipart_params; var obj = phpbb.plupload.uploader.settings.multipart_params;
for (var key in obj) { for (var key in obj) {
if (!obj.hasOwnProperty(key) || key.indexOf('attachment_data[') !== 0) { if (!Object.prototype.hasOwnProperty.call(obj, key) || key.indexOf('attachment_data[') !== 0) {
continue; continue;
} }
delete phpbb.plupload.uploader.settings.multipart_params[key]; delete phpbb.plupload.uploader.settings.multipart_params[key];
} }
}; };
/** /**
* Update uploader.settings.multipart_params object with new data. * Update uploader.settings.multipart_params object with new data.
* *
* @param {object} obj * @param {object} obj
*/ */
phpbb.plupload.updateMultipartParams = function(obj) { phpbb.plupload.updateMultipartParams = function(obj) {
var settings = phpbb.plupload.uploader.settings; var { settings } = phpbb.plupload.uploader;
settings.multipart_params = $.extend(settings.multipart_params, obj); settings.multipart_params = $.extend(settings.multipart_params, obj);
}; };
/** /**
* Convert the array of attachment objects into an object that PHP would expect as POST data. * Convert the array of attachment objects into an object that PHP would expect as POST data.
* *
* @returns {object} An object in the form 'attachment_data[i][key]': value as * @returns {object} An object in the form 'attachment_data[i][key]': value as
* expected by the server * expected by the server
*/ */
phpbb.plupload.getSerializedData = function() { phpbb.plupload.getSerializedData = function() {
var obj = {}; var obj = {};
for (var i = 0; i < phpbb.plupload.data.length; i++) { for (var i = 0; i < phpbb.plupload.data.length; i++) {
var datum = phpbb.plupload.data[i]; var datum = phpbb.plupload.data[i];
for (var key in datum) { for (var key in datum) {
if (!datum.hasOwnProperty(key)) { if (!Object.prototype.hasOwnProperty.call(datum, key)) {
continue; continue;
} }
@ -97,37 +99,38 @@ phpbb.plupload.getSerializedData = function() {
obj.form_token = $pluploadForm.find('input[type=hidden][name="form_token"]').val(); obj.form_token = $pluploadForm.find('input[type=hidden][name="form_token"]').val();
return obj; return obj;
}; };
/** /**
* Get the index from the phpbb.plupload.data array where the given * Get the index from the phpbb.plupload.data array where the given
* attachment id appears. * attachment id appears.
* *
* @param {int} attachId The attachment id of the file. * @param {int} attachId The attachment id of the file.
* @returns {bool|int} Index of the file if exists, otherwise false. * @returns {bool|int} Index of the file if exists, otherwise false.
*/ */
phpbb.plupload.getIndex = function(attachId) { phpbb.plupload.getIndex = function(attachId) {
var index = $.inArray(Number(attachId), phpbb.plupload.ids); var index = $.inArray(Number(attachId), phpbb.plupload.ids);
return (index !== -1) ? index : false; return index === -1 ? false : index;
}; };
/** /**
* Set the data in phpbb.plupload.data and phpbb.plupload.ids arrays. * Set the data in phpbb.plupload.data and phpbb.plupload.ids arrays.
* *
* @param {Array} data Array containing the new data to use. In the form of * @param {Array} data Array containing the new data to use. In the form of
* array(index => object(property: value). Requires attach_id to be one of the object properties. * array(index => object(property: value). Requires attach_id to be one of the object properties.
*/ */
phpbb.plupload.setData = function(data) { phpbb.plupload.setData = function(data) {
// Make sure that the array keys are reset. // Make sure that the array keys are reset.
phpbb.plupload.ids = phpbb.plupload.data = []; phpbb.plupload.ids = [];
phpbb.plupload.data = [];
phpbb.plupload.data = data; phpbb.plupload.data = data;
for (var i = 0; i < data.length; i++) { for (var i = 0; i < data.length; i++) {
phpbb.plupload.ids.push(Number(data[i].attach_id)); phpbb.plupload.ids.push(Number(data[i].attach_id));
} }
}; };
/** /**
* Update the attachment data in the HTML and the phpbb & phpbb.plupload objects. * Update the attachment data in the HTML and the phpbb & phpbb.plupload objects.
* *
* @param {Array} data Array containing the new data to use. * @param {Array} data Array containing the new data to use.
@ -135,27 +138,26 @@ phpbb.plupload.setData = function(data) {
* @param {int} index The index from phpbb.plupload_ids that was affected by the action. * @param {int} index The index from phpbb.plupload_ids that was affected by the action.
* @param {Array} downloadUrl Optional array of download urls to update. * @param {Array} downloadUrl Optional array of download urls to update.
*/ */
phpbb.plupload.update = function(data, action, index, downloadUrl) { phpbb.plupload.update = function(data, action, index, downloadUrl) {
phpbb.plupload.updateBbcode(action, index); phpbb.plupload.updateBbcode(action, index);
phpbb.plupload.setData(data); phpbb.plupload.setData(data);
phpbb.plupload.updateRows(downloadUrl); phpbb.plupload.updateRows(downloadUrl);
phpbb.plupload.clearParams(); phpbb.plupload.clearParams();
phpbb.plupload.updateMultipartParams(phpbb.plupload.getSerializedData()); phpbb.plupload.updateMultipartParams(phpbb.plupload.getSerializedData());
}; };
/** /**
* Update the relevant elements and hidden data for all attachments. * Update the relevant elements and hidden data for all attachments.
* *
* @param {Array} downloadUrl Optional array of download urls to update. * @param {Array} downloadUrl Optional array of download urls to update.
*/ */
phpbb.plupload.updateRows = function(downloadUrl) { phpbb.plupload.updateRows = function(downloadUrl) {
for (var i = 0; i < phpbb.plupload.ids.length; i++) { for (var i = 0; i < phpbb.plupload.ids.length; i++) {
phpbb.plupload.updateRow(i, downloadUrl); phpbb.plupload.updateRow(i, downloadUrl);
} }
}; };
/** /**
* Insert a row for a new attachment. This expects an HTML snippet in the HTML * Insert a row for a new attachment. This expects an HTML snippet in the HTML
* using the id "attach-row-tpl" to be present. This snippet is cloned and the * using the id "attach-row-tpl" to be present. This snippet is cloned and the
* data for the file inserted into it. The row is then appended or prepended to * data for the file inserted into it. The row is then appended or prepended to
@ -163,7 +165,7 @@ phpbb.plupload.updateRows = function(downloadUrl) {
* *
* @param {object} file Plupload file object for the new attachment. * @param {object} file Plupload file object for the new attachment.
*/ */
phpbb.plupload.insertRow = function(file) { phpbb.plupload.insertRow = function(file) {
var row = $(phpbb.plupload.rowTpl); var row = $(phpbb.plupload.rowTpl);
row.attr('id', file.id); row.attr('id', file.id);
@ -175,22 +177,22 @@ phpbb.plupload.insertRow = function(file) {
} else { } else {
$('#file-list').append(row); $('#file-list').append(row);
} }
}; };
/** /**
* Update the relevant elements and hidden data for an attachment. * Update the relevant elements and hidden data for an attachment.
* *
* @param {int} index The index from phpbb.plupload.ids of the attachment to edit. * @param {int} index The index from phpbb.plupload.ids of the attachment to edit.
* @param {Array} downloadUrl Optional array of download urls to update. * @param {Array} downloadUrl Optional array of download urls to update.
*/ */
phpbb.plupload.updateRow = function(index, downloadUrl) { phpbb.plupload.updateRow = function(index, downloadUrl) {
var attach = phpbb.plupload.data[index], var attach = phpbb.plupload.data[index];
row = $('[data-attach-id="' + attach.attach_id + '"]'); var row = $('[data-attach-id="' + attach.attach_id + '"]');
// Add the link to the file // Add the link to the file
if (typeof downloadUrl !== 'undefined' && typeof downloadUrl[index] !== 'undefined') { if (typeof downloadUrl !== 'undefined' && typeof downloadUrl[index] !== 'undefined') {
var url = downloadUrl[index].replace('&amp;', '&'), var url = downloadUrl[index].replace('&amp;', '&');
link = $('<a></a>'); var link = $('<a></a>');
link.attr('href', url).html(attach.real_filename); link.attr('href', url).html(attach.real_filename);
row.find('.file-name').html(link); row.find('.file-name').html(link);
@ -198,21 +200,21 @@ phpbb.plupload.updateRow = function(index, downloadUrl) {
row.find('textarea').attr('name', 'comment_list[' + index + ']'); row.find('textarea').attr('name', 'comment_list[' + index + ']');
phpbb.plupload.updateHiddenData(row, attach, index); phpbb.plupload.updateHiddenData(row, attach, index);
}; };
/** /**
* Update hidden input data for an attachment. * Update hidden input data for an attachment.
* *
* @param {object} row jQuery object for the attachment row. * @param {object} row jQuery object for the attachment row.
* @param {object} attach Attachment data object from phpbb.plupload.data * @param {object} attach Attachment data object from phpbb.plupload.data
* @param {int} index Attachment index from phpbb.plupload.ids * @param {int} index Attachment index from phpbb.plupload.ids
*/ */
phpbb.plupload.updateHiddenData = function(row, attach, index) { phpbb.plupload.updateHiddenData = function(row, attach, index) {
row.find('input[type="hidden"]').remove(); row.find('input[type="hidden"]').remove();
for (var key in attach) { for (var key in attach) {
if (!attach.hasOwnProperty(key)) { if (!Object.prototype.hasOwnProperty.call(attach, key)) {
return; continue;
} }
var input = $('<input />') var input = $('<input />')
@ -221,9 +223,9 @@ phpbb.plupload.updateHiddenData = function(row, attach, index) {
.attr('value', attach[key]); .attr('value', attach[key]);
$(row).append(input); $(row).append(input);
} }
}; };
/** /**
* Deleting a file removes it from the queue and fires an AJAX event to the * Deleting a file removes it from the queue and fires an AJAX event to the
* server to tell it to remove the temporary attachment. The server * server to tell it to remove the temporary attachment. The server
* responds with the updated attachment data list so that any future * responds with the updated attachment data list so that any future
@ -232,13 +234,13 @@ phpbb.plupload.updateHiddenData = function(row, attach, index) {
* @param {object} row jQuery object for the attachment row. * @param {object} row jQuery object for the attachment row.
* @param {int} attachId Attachment id of the file to be removed. * @param {int} attachId Attachment id of the file to be removed.
*/ */
phpbb.plupload.deleteFile = function(row, attachId) { phpbb.plupload.deleteFile = function(row, attachId) {
// If there's no attach id, then the file hasn't been uploaded. Simply delete the row. // If there's no attach id, then the file hasn't been uploaded. Simply delete the row.
if (typeof attachId === 'undefined') { if (typeof attachId === 'undefined') {
var file = phpbb.plupload.uploader.getFile(row.attr('id')); var file = phpbb.plupload.uploader.getFile(row.attr('id'));
phpbb.plupload.uploader.removeFile(file); phpbb.plupload.uploader.removeFile(file);
row.slideUp(100, function() { row.slideUp(100, () => {
row.remove(); row.remove();
phpbb.plupload.hideEmptyList(); phpbb.plupload.hideEmptyList();
}); });
@ -250,6 +252,7 @@ phpbb.plupload.deleteFile = function(row, attachId) {
if (index === false) { if (index === false) {
return; return;
} }
var fields = {}; var fields = {};
fields['delete_file[' + index + ']'] = 1; fields['delete_file[' + index + ']'] = 1;
@ -289,7 +292,8 @@ phpbb.plupload.deleteFile = function(row, attachId) {
var file = phpbb.plupload.uploader.getFile(row.attr('id')); var file = phpbb.plupload.uploader.getFile(row.attr('id'));
phpbb.plupload.uploader.removeFile(file); phpbb.plupload.uploader.removeFile(file);
} }
row.slideUp(100, function() {
row.slideUp(100, () => {
row.remove(); row.remove();
// Hide the file list if it's empty now. // Hide the file list if it's empty now.
phpbb.plupload.hideEmptyList(); phpbb.plupload.hideEmptyList();
@ -300,22 +304,22 @@ phpbb.plupload.deleteFile = function(row, attachId) {
$.ajax(phpbb.plupload.config.url, { $.ajax(phpbb.plupload.config.url, {
type: 'POST', type: 'POST',
data: $.extend(fields, phpbb.plupload.getSerializedData()), data: $.extend(fields, phpbb.plupload.getSerializedData()),
headers: phpbb.plupload.config.headers headers: phpbb.plupload.config.headers,
}) })
.always(always) .always(always)
.done(done); .done(done);
}; };
/** /**
* Check the attachment list and hide its container if it's empty. * Check the attachment list and hide its container if it's empty.
*/ */
phpbb.plupload.hideEmptyList = function() { phpbb.plupload.hideEmptyList = function() {
if (!$('#file-list').children().length) { if (!$('#file-list').children().length) {
$('#file-list-container').slideUp(100); $('#file-list-container').slideUp(100);
} }
}; };
/** /**
* Update the indices used in inline attachment bbcodes. This ensures that the * Update the indices used in inline attachment bbcodes. This ensures that the
* bbcodes correspond to the correct file after a file is added or removed. * bbcodes correspond to the correct file after a file is added or removed.
* This should be called before the phpbb.plupload,data and phpbb.plupload.ids * This should be called before the phpbb.plupload,data and phpbb.plupload.ids
@ -324,10 +328,10 @@ phpbb.plupload.hideEmptyList = function() {
* @param {string} action The action that occurred -- either "addition" or "removal" * @param {string} action The action that occurred -- either "addition" or "removal"
* @param {int} index The index of the attachment from phpbb.plupload.ids that was affected. * @param {int} index The index of the attachment from phpbb.plupload.ids that was affected.
*/ */
phpbb.plupload.updateBbcode = function(action, index) { phpbb.plupload.updateBbcode = function(action, index) {
var textarea = $('#message', phpbb.plupload.form), const textarea = $('#message', phpbb.plupload.form);
text = textarea.val(), var text = textarea.val();
removal = (action === 'removal'); var removal = (action === 'removal');
// Return if the bbcode isn't used at all. // Return if the bbcode isn't used at all.
if (text.indexOf('[attachment=') === -1) { if (text.indexOf('[attachment=') === -1) {
@ -336,11 +340,12 @@ phpbb.plupload.updateBbcode = function(action, index) {
function runUpdate(i) { function runUpdate(i) {
var regex = new RegExp('\\[attachment=' + i + '\\](.*?)\\[\\/attachment\\]', 'g'); var regex = new RegExp('\\[attachment=' + i + '\\](.*?)\\[\\/attachment\\]', 'g');
text = text.replace(regex, function updateBbcode(_, fileName) { text = text.replace(regex, (_, fileName) => {
// Remove the bbcode if the file was removed. // Remove the bbcode if the file was removed.
if (removal && index === i) { if (removal && index === i) {
return ''; return '';
} }
var newIndex = i + ((removal) ? -1 : 1); var newIndex = i + ((removal) ? -1 : 1);
return '[attachment=' + newIndex + ']' + fileName + '[/attachment]'; return '[attachment=' + newIndex + ']' + fileName + '[/attachment]';
}); });
@ -360,9 +365,9 @@ phpbb.plupload.updateBbcode = function(action, index) {
} }
textarea.val(text); textarea.val(text);
}; };
/** /**
* Get Plupload file objects based on their upload status. * Get Plupload file objects based on their upload status.
* *
* @param {int} status Plupload status - plupload.DONE, plupload.FAILED, * @param {int} status Plupload status - plupload.DONE, plupload.FAILED,
@ -370,25 +375,25 @@ phpbb.plupload.updateBbcode = function(action, index) {
* *
* @returns {Array} The Plupload file objects matching the status. * @returns {Array} The Plupload file objects matching the status.
*/ */
phpbb.plupload.getFilesByStatus = function(status) { phpbb.plupload.getFilesByStatus = function(status) {
var files = []; var files = [];
$.each(phpbb.plupload.uploader.files, function(i, file) { $.each(phpbb.plupload.uploader.files, (i, file) => {
if (file.status === status) { if (file.status === status) {
files.push(file); files.push(file);
} }
}); });
return files; return files;
}; };
/** /**
* Check whether the user has reached the maximun number of files that he's allowed * Check whether the user has reached the maximun number of files that he's allowed
* to upload. If so, disables the uploader and marks the queued files as failed. Otherwise * to upload. If so, disables the uploader and marks the queued files as failed. Otherwise
* makes sure that the uploader is enabled. * makes sure that the uploader is enabled.
* *
* @returns {bool} True if the limit has been reached. False if otherwise. * @returns {bool} True if the limit has been reached. False if otherwise.
*/ */
phpbb.plupload.handleMaxFilesReached = function() { phpbb.plupload.handleMaxFilesReached = function() {
// If there is no limit, the user is an admin or moderator. // If there is no limit, the user is an admin or moderator.
if (!phpbb.plupload.maxFiles) { if (!phpbb.plupload.maxFiles) {
return false; return false;
@ -402,81 +407,87 @@ phpbb.plupload.handleMaxFilesReached = function() {
phpbb.plupload.uploader.trigger('Error', { message: phpbb.plupload.lang.TOO_MANY_ATTACHMENTS }); phpbb.plupload.uploader.trigger('Error', { message: phpbb.plupload.lang.TOO_MANY_ATTACHMENTS });
return true; return true;
} else if (phpbb.plupload.maxFiles > phpbb.plupload.ids.length) { }
if (phpbb.plupload.maxFiles > phpbb.plupload.ids.length) {
// Enable the uploader if the user is under the limit // Enable the uploader if the user is under the limit
phpbb.plupload.enableUploader(); phpbb.plupload.enableUploader();
} }
return false;
};
/** return false;
};
/**
* Disable the uploader * Disable the uploader
*/ */
phpbb.plupload.disableUploader = function() { phpbb.plupload.disableUploader = function() {
$('#add_files').addClass('disabled'); $('#add_files').addClass('disabled');
phpbb.plupload.uploader.disableBrowse(); phpbb.plupload.uploader.disableBrowse();
}; };
/** /**
* Enable the uploader * Enable the uploader
*/ */
phpbb.plupload.enableUploader = function() { phpbb.plupload.enableUploader = function() {
$('#add_files').removeClass('disabled'); $('#add_files').removeClass('disabled');
phpbb.plupload.uploader.disableBrowse(false); phpbb.plupload.uploader.disableBrowse(false);
}; };
/** /**
* Mark all queued files as failed. * Mark all queued files as failed.
* *
* @param {string} error Error message to present to the user. * @param {string} error Error message to present to the user.
*/ */
phpbb.plupload.markQueuedFailed = function(error) { phpbb.plupload.markQueuedFailed = function(error) {
var files = phpbb.plupload.getFilesByStatus(plupload.QUEUED); var files = phpbb.plupload.getFilesByStatus(plupload.QUEUED);
$.each(files, function(i, file) { $.each(files, (i, file) => {
$('#' + file.id).find('.file-progress').hide(); $('#' + file.id).find('.file-progress').hide();
phpbb.plupload.fileError(file, error); phpbb.plupload.fileError(file, error);
}); });
}; };
/** /**
* Marks a file as failed and sets the error message for it. * Marks a file as failed and sets the error message for it.
* *
* @param {object} file Plupload file object that failed. * @param {object} file Plupload file object that failed.
* @param {string} error Error message to present to the user. * @param {string} error Error message to present to the user.
*/ */
phpbb.plupload.fileError = function(file, error) { phpbb.plupload.fileError = function(file, error) {
file.status = plupload.FAILED; file.status = plupload.FAILED;
file.error = error; file.error = error;
$('#' + file.id).find('.file-status') $('#' + file.id).find('.file-status')
.addClass('file-error') .addClass('file-error')
.attr({ .attr({
'data-error-title': phpbb.plupload.lang.ERROR, 'data-error-title': phpbb.plupload.lang.ERROR,
'data-error-message': error 'data-error-message': error,
}); });
}; };
/**
/**
* Set up the Plupload object and get some basic data. * Set up the Plupload object and get some basic data.
*/ */
phpbb.plupload.uploader = new plupload.Uploader(phpbb.plupload.config); phpbb.plupload.uploader = new plupload.Uploader(phpbb.plupload.config);
phpbb.plupload.initialize(); phpbb.plupload.initialize();
/** /**
* Add a file filter to check for max file sizes per mime type. * Add a file filter to check for max file sizes per mime type.
*/ */
plupload.addFileFilter('mime_types_max_file_size', function(types, file, callback) { plupload.addFileFilter('mime_types_max_file_size', (types, file, callback) => {
if (file.size !== 'undefined') { if (file.size !== 'undefined') {
$(types).each(function(i, type) { $(types).each((i, type) => {
let extensions = [], const extensions = [];
extsArray = type.extensions.split(','); const extsArray = type.extensions.split(',');
$(extsArray).each(function(i, extension) { $(extsArray).each((i, extension) => {
/^\s*\*\s*$/.test(extension) ? extensions.push("\\.*") : extensions.push("\\." + extension.replace(new RegExp("[" + "/^$.*+?|()[]{}\\".replace(/./g, "\\$&") + "]", "g"), "\\$&")); if (/^\s*\*\s*$/.test(extension)) {
extensions.push('\\.*');
} else {
extensions.push('\\.' + extension.replace(new RegExp('[' + '/^$.*+?|()[]{}\\'.replace(/./g, '\\$&') + ']', 'g'), '\\$&'));
}
}); });
let regex = new RegExp("(" + extensions.join("|") + ")$", "i"); const regex = new RegExp('(' + extensions.join('|') + ')$', 'i');
if (regex.test(file.name)) { if (regex.test(file.name)) {
if (type.max_file_size !== 'undefined' && type.max_file_size) { if (type.max_file_size !== 'undefined' && type.max_file_size) {
@ -484,7 +495,7 @@ plupload.addFileFilter('mime_types_max_file_size', function(types, file, callbac
phpbb.plupload.uploader.trigger('Error', { phpbb.plupload.uploader.trigger('Error', {
code: plupload.FILE_SIZE_ERROR, code: plupload.FILE_SIZE_ERROR,
message: plupload.translate('File size error.'), message: plupload.translate('File size error.'),
file: file file,
}); });
callback(false); callback(false);
@ -499,44 +510,44 @@ plupload.addFileFilter('mime_types_max_file_size', function(types, file, callbac
} }
}); });
} }
}); });
var $fileList = $('#file-list'); var $fileList = $('#file-list');
/** /**
* Insert inline attachment bbcode. * Insert inline attachment bbcode.
*/ */
$fileList.on('click', '.file-inline-bbcode', function(e) { $fileList.on('click', '.file-inline-bbcode', function(e) {
var attachId = $(this).parents('.attach-row').attr('data-attach-id'), var attachId = $(this).parents('.attach-row').attr('data-attach-id');
index = phpbb.plupload.getIndex(attachId); var index = phpbb.plupload.getIndex(attachId);
attachInline(index, phpbb.plupload.data[index].real_filename); attachInline(index, phpbb.plupload.data[index].real_filename);
e.preventDefault(); e.preventDefault();
}); });
/** /**
* Delete a file. * Delete a file.
*/ */
$fileList.on('click', '.file-delete', function(e) { $fileList.on('click', '.file-delete', function(e) {
var row = $(this).parents('.attach-row'), var row = $(this).parents('.attach-row');
attachId = row.attr('data-attach-id'); var attachId = row.attr('data-attach-id');
phpbb.plupload.deleteFile(row, attachId); phpbb.plupload.deleteFile(row, attachId);
e.preventDefault(); e.preventDefault();
}); });
/** /**
* Display the error message for a particular file when the error icon is clicked. * Display the error message for a particular file when the error icon is clicked.
*/ */
$fileList.on('click', '.file-error', function(e) { $fileList.on('click', '.file-error', function(e) {
phpbb.alert($(this).attr('data-error-title'), $(this).attr('data-error-message')); phpbb.alert($(this).attr('data-error-title'), $(this).attr('data-error-message'));
e.preventDefault(); e.preventDefault();
}); });
/** /**
* Fires when an error occurs. * Fires when an error occurs.
*/ */
phpbb.plupload.uploader.bind('Error', function(up, error) { phpbb.plupload.uploader.bind('Error', (up, error) => {
error.file.name = plupload.xmlEncode(error.file.name); error.file.name = plupload.xmlEncode(error.file.name);
// The error message that Plupload provides for these is vague, so we'll be more specific. // The error message that Plupload provides for these is vague, so we'll be more specific.
@ -545,10 +556,11 @@ phpbb.plupload.uploader.bind('Error', function(up, error) {
} else if (error.code === plupload.FILE_SIZE_ERROR) { } else if (error.code === plupload.FILE_SIZE_ERROR) {
error.message = plupload.translate('File too large:') + ' ' + error.file.name; error.message = plupload.translate('File too large:') + ' ' + error.file.name;
} }
phpbb.alert(phpbb.plupload.lang.ERROR, error.message);
});
/** phpbb.alert(phpbb.plupload.lang.ERROR, error.message);
});
/**
* Fires before a given file is about to be uploaded. This allows us to * Fires before a given file is about to be uploaded. This allows us to
* send the real filename along with the chunk. This is necessary because * send the real filename along with the chunk. This is necessary because
* for some reason the filename is set to 'blob' whenever a file is chunked * for some reason the filename is set to 'blob' whenever a file is chunked
@ -556,15 +568,15 @@ phpbb.plupload.uploader.bind('Error', function(up, error) {
* @param {object} up The plupload.Uploader object * @param {object} up The plupload.Uploader object
* @param {object} file The plupload.File object that is about to be uploaded * @param {object} file The plupload.File object that is about to be uploaded
*/ */
phpbb.plupload.uploader.bind('BeforeUpload', function(up, file) { phpbb.plupload.uploader.bind('BeforeUpload', (up, file) => {
if (phpbb.plupload.handleMaxFilesReached()) { if (phpbb.plupload.handleMaxFilesReached()) {
return; return;
} }
phpbb.plupload.updateMultipartParams({ real_filename: file.name }); phpbb.plupload.updateMultipartParams({ real_filename: file.name });
}); });
/** /**
* Fired when a single chunk of any given file is uploaded. This parses the * Fired when a single chunk of any given file is uploaded. This parses the
* response from the server and checks for an error. If an error occurs it * response from the server and checks for an error. If an error occurs it
* is reported to the user and the upload of this particular file is halted * is reported to the user and the upload of this particular file is halted
@ -574,7 +586,7 @@ phpbb.plupload.uploader.bind('BeforeUpload', function(up, file) {
* been uploaded * been uploaded
* @param {object} response The response object from the server * @param {object} response The response object from the server
*/ */
phpbb.plupload.uploader.bind('ChunkUploaded', function(up, file, response) { phpbb.plupload.uploader.bind('ChunkUploaded', (up, file, response) => {
if (response.chunk >= response.chunks - 1) { if (response.chunk >= response.chunks - 1) {
return; return;
} }
@ -582,14 +594,14 @@ phpbb.plupload.uploader.bind('ChunkUploaded', function(up, file, response) {
var json = {}; var json = {};
try { try {
json = $.parseJSON(response.response); json = $.parseJSON(response.response);
} catch (e) { } catch {
file.status = plupload.FAILED; file.status = plupload.FAILED;
up.trigger('FileUploaded', file, { up.trigger('FileUploaded', file, {
response: JSON.stringify({ response: JSON.stringify({
error: { error: {
message: 'Error parsing server response.' message: 'Error parsing server response.',
} },
}) }),
}); });
} }
@ -603,17 +615,17 @@ phpbb.plupload.uploader.bind('ChunkUploaded', function(up, file, response) {
up.trigger('FileUploaded', file, { up.trigger('FileUploaded', file, {
response: JSON.stringify({ response: JSON.stringify({
error: { error: {
message: json.error.message message: json.error.message,
} },
}) }),
}); });
} }
}); });
/** /**
* Fires when files are added to the queue. * Fires when files are added to the queue.
*/ */
phpbb.plupload.uploader.bind('FilesAdded', function(up, files) { phpbb.plupload.uploader.bind('FilesAdded', (up, files) => {
// Prevent unnecessary requests to the server if the user already uploaded // Prevent unnecessary requests to the server if the user already uploaded
// the maximum number of files allowed. // the maximum number of files allowed.
if (phpbb.plupload.handleMaxFilesReached()) { if (phpbb.plupload.handleMaxFilesReached()) {
@ -631,11 +643,11 @@ phpbb.plupload.uploader.bind('FilesAdded', function(up, files) {
$fileListContainer.show(100); $fileListContainer.show(100);
} }
$.each(files, function(i, file) { $.each(files, (i, file) => {
phpbb.plupload.insertRow(file); phpbb.plupload.insertRow(file);
}); });
up.bind('UploadProgress', function(up, file) { up.bind('UploadProgress', (up, file) => {
$('.file-progress-bar', '#' + file.id).css('width', file.percent + '%'); $('.file-progress-bar', '#' + file.id).css('width', file.percent + '%');
$('#file-total-progress-bar').css('width', up.total.percent + '%'); $('#file-total-progress-bar').css('width', up.total.percent + '%');
}); });
@ -645,10 +657,9 @@ phpbb.plupload.uploader.bind('FilesAdded', function(up, files) {
// Start uploading the files once the user has selected them. // Start uploading the files once the user has selected them.
up.start(); up.start();
}); });
/**
/**
* Fires when an entire file has been uploaded. It checks for errors * Fires when an entire file has been uploaded. It checks for errors
* returned by the server otherwise parses the list of attachment data and * returned by the server otherwise parses the list of attachment data and
* appends it to the next file upload so that the server can maintain state * appends it to the next file upload so that the server can maintain state
@ -659,17 +670,17 @@ phpbb.plupload.uploader.bind('FilesAdded', function(up, files) {
* uploaded * uploaded
* @param {string} response The response string from the server * @param {string} response The response string from the server
*/ */
phpbb.plupload.uploader.bind('FileUploaded', function(up, file, response) { phpbb.plupload.uploader.bind('FileUploaded', (up, file, response) => {
var json = {}, var json = {};
row = $('#' + file.id), var row = $('#' + file.id);
error; var error;
// Hide the progress indicator. // Hide the progress indicator.
row.find('.file-progress').hide(); row.find('.file-progress').hide();
try { try {
json = JSON.parse(response.response); json = JSON.parse(response.response);
} catch (e) { } catch {
error = 'Error parsing server response.'; error = 'Error parsing server response.';
} }
@ -692,16 +703,16 @@ phpbb.plupload.uploader.bind('FileUploaded', function(up, file, response) {
row.attr('data-attach-id', file.attachment_data.attach_id); row.attr('data-attach-id', file.attachment_data.attach_id);
row.find('.file-inline-bbcode').show(); row.find('.file-inline-bbcode').show();
row.find('.file-status').addClass('file-uploaded'); row.find('.file-status').addClass('file-uploaded');
phpbb.plupload.update(json.data, 'addition', 0, [json.download_url]); phpbb.plupload.update(json.data, 'addition', 0, [ json.download_url ]);
} }
}); });
/** /**
* Fires when the entire queue of files have been uploaded. * Fires when the entire queue of files have been uploaded.
*/ */
phpbb.plupload.uploader.bind('UploadComplete', function() { phpbb.plupload.uploader.bind('UploadComplete', () => {
// Hide the progress bar // Hide the progress bar
setTimeout(function() { setTimeout(() => {
$('#file-total-progress-bar').fadeOut(500, function() { $('#file-total-progress-bar').fadeOut(500, function() {
$(this).css('width', 0).show(); $(this).css('width', 0).show();
}); });
@ -709,6 +720,5 @@ phpbb.plupload.uploader.bind('UploadComplete', function() {
// Re-enable the uploader // Re-enable the uploader
phpbb.plupload.enableUploader(); phpbb.plupload.enableUploader();
}); });
})(jQuery); // Avoid conflicts with other libraries })(jQuery); // Avoid conflicts with other libraries

View file

@ -1,23 +1,24 @@
/* global phpbb */ /* global phpbb */
/* eslint camelcase: 0 */
/* eslint no-var: 0 */
(function($) { // Avoid conflicts with other libraries (function($) { // Avoid conflicts with other libraries
'use strict';
'use strict'; // This callback will mark all forum icons read
phpbb.addAjaxCallback('mark_forums_read', function(res) {
// This callback will mark all forum icons read
phpbb.addAjaxCallback('mark_forums_read', function(res) {
var readTitle = res.NO_UNREAD_POSTS; var readTitle = res.NO_UNREAD_POSTS;
var unreadTitle = res.UNREAD_POSTS; var unreadTitle = res.UNREAD_POSTS;
var iconsArray = { var iconsArray = {
forum_unread: 'forum_read', forum_unread: 'forum_read',
forum_unread_subforum: 'forum_read_subforum', forum_unread_subforum: 'forum_read_subforum',
forum_unread_locked: 'forum_read_locked' forum_unread_locked: 'forum_read_locked',
}; };
$('li.row').find('dl[class*="forum_unread"]').each(function() { $('li.row').find('dl[class*="forum_unread"]').each(function() {
var $this = $(this); var $this = $(this);
$.each(iconsArray, function(unreadClass, readClass) { $.each(iconsArray, (unreadClass, readClass) => {
if ($this.hasClass(unreadClass)) { if ($this.hasClass(unreadClass)) {
$this.removeClass(unreadClass).addClass(readClass); $this.removeClass(unreadClass).addClass(readClass);
} }
@ -37,25 +38,24 @@ phpbb.addAjaxCallback('mark_forums_read', function(res) {
$('[data-ajax="mark_forums_read"]').attr('href', res.U_MARK_FORUMS); $('[data-ajax="mark_forums_read"]').attr('href', res.U_MARK_FORUMS);
phpbb.closeDarkenWrapper(3000); phpbb.closeDarkenWrapper(3000);
}); });
/** /**
* This callback will mark all topic icons read * This callback will mark all topic icons read
* *
* @param {bool} [update_topic_links=true] Whether "Mark topics read" links * @param {bool} [update_topic_links=true] Whether "Mark topics read" links
* should be updated. Defaults to true. * should be updated. Defaults to true.
*/ */
phpbb.addAjaxCallback('mark_topics_read', function(res, updateTopicLinks) { phpbb.addAjaxCallback('mark_topics_read', (res, updateTopicLinks) => {
var readTitle = res.NO_UNREAD_POSTS; var readTitle = res.NO_UNREAD_POSTS;
var unreadTitle = res.UNREAD_POSTS; var unreadTitle = res.UNREAD_POSTS;
var iconsArray = { var iconsArray = {
global_unread: 'global_read', global_unread: 'global_read',
announce_unread: 'announce_read', announce_unread: 'announce_read',
sticky_unread: 'sticky_read', sticky_unread: 'sticky_read',
topic_unread: 'topic_read' topic_unread: 'topic_read',
}; };
var iconsState = ['', '_hot', '_hot_mine', '_locked', '_locked_mine', '_mine']; var iconsState = [ '', '_hot', '_hot_mine', '_locked', '_locked_mine', '_mine' ];
var unreadClassSelectors;
var classMap = {}; var classMap = {};
var classNames = []; var classNames = [];
@ -63,22 +63,23 @@ phpbb.addAjaxCallback('mark_topics_read', function(res, updateTopicLinks) {
updateTopicLinks = true; updateTopicLinks = true;
} }
$.each(iconsArray, function(unreadClass, readClass) { $.each(iconsArray, (unreadClass, readClass) => {
$.each(iconsState, function(key, value) { $.each(iconsState, (key, value) => {
// Only topics can be hot // Only topics can be hot
if ((value === '_hot' || value === '_hot_mine') && unreadClass !== 'topic_unread') { if ((value === '_hot' || value === '_hot_mine') && unreadClass !== 'topic_unread') {
return true; return true;
} }
classMap[unreadClass + value] = readClass + value; classMap[unreadClass + value] = readClass + value;
classNames.push(unreadClass + value); classNames.push(unreadClass + value);
}); });
}); });
unreadClassSelectors = '.' + classNames.join(',.'); var unreadClassSelectors = '.' + classNames.join(',.');
$('li.row').find(unreadClassSelectors).each(function() { $('li.row').find(unreadClassSelectors).each(function() {
var $this = $(this); var $this = $(this);
$.each(classMap, function(unreadClass, readClass) { $.each(classMap, (unreadClass, readClass) => {
if ($this.hasClass(unreadClass)) { if ($this.hasClass(unreadClass)) {
$this.removeClass(unreadClass).addClass(readClass); $this.removeClass(unreadClass).addClass(readClass);
} }
@ -95,32 +96,32 @@ phpbb.addAjaxCallback('mark_topics_read', function(res, updateTopicLinks) {
} }
phpbb.closeDarkenWrapper(3000); phpbb.closeDarkenWrapper(3000);
}); });
// This callback will mark all notifications read // This callback will mark all notifications read
phpbb.addAjaxCallback('notification.mark_all_read', function(res) { phpbb.addAjaxCallback('notification.mark_all_read', res => {
if (typeof res.success !== 'undefined') { if (typeof res.success !== 'undefined') {
phpbb.markNotifications($('[data-notification-unread="true"]'), 0); phpbb.markNotifications($('[data-notification-unread="true"]'), 0);
phpbb.toggleDropdown.call($('#notification-button')); phpbb.toggleDropdown.call($('#notification-button'));
phpbb.closeDarkenWrapper(3000); phpbb.closeDarkenWrapper(3000);
} }
}); });
// This callback will mark a notification read // This callback will mark a notification read
phpbb.addAjaxCallback('notification.mark_read', function(res) { phpbb.addAjaxCallback('notification.mark_read', function(res) {
if (typeof res.success !== 'undefined') { if (typeof res.success !== 'undefined') {
var unreadCount = Number($('#notification-button strong').html()) - 1; var unreadCount = Number($('#notification-button strong').html()) - 1;
phpbb.markNotifications($(this).parent('[data-notification-unread="true"]'), unreadCount); phpbb.markNotifications($(this).parent('[data-notification-unread="true"]'), unreadCount);
} }
}); });
/** /**
* Mark notification popup rows as read. * Mark notification popup rows as read.
* *
* @param {jQuery} $popup jQuery object(s) to mark read. * @param {jQuery} $popup jQuery object(s) to mark read.
* @param {int} unreadCount The new unread notifications count. * @param {int} unreadCount The new unread notifications count.
*/ */
phpbb.markNotifications = function($popup, unreadCount) { phpbb.markNotifications = function($popup, unreadCount) {
// Remove the unread status. // Remove the unread status.
$popup.removeClass('bg2'); $popup.removeClass('bg2');
$popup.find('a.mark_read').remove(); $popup.find('a.mark_read').remove();
@ -143,12 +144,12 @@ phpbb.markNotifications = function($popup, unreadCount) {
var $title = $('title'); var $title = $('title');
var originalTitle = $title.text().replace(/(\((\d+)\))/, ''); var originalTitle = $title.text().replace(/(\((\d+)\))/, '');
$title.text((unreadCount ? '(' + unreadCount + ')' : '') + originalTitle); $title.text((unreadCount ? '(' + unreadCount + ')' : '') + originalTitle);
}; };
// This callback finds the post from the delete link, and removes it. // This callback finds the post from the delete link, and removes it.
phpbb.addAjaxCallback('post_delete', function() { phpbb.addAjaxCallback('post_delete', function() {
var $this = $(this), var $this = $(this);
postId; var postId;
if ($this.attr('data-refresh') === undefined) { if ($this.attr('data-refresh') === undefined) {
postId = $this[0].href.split('&p=')[1]; postId = $this[0].href.split('&p=')[1];
@ -158,14 +159,15 @@ phpbb.addAjaxCallback('post_delete', function() {
post.nextAll('.bg2').removeClass('bg2').addClass('bg1'); post.nextAll('.bg2').removeClass('bg2').addClass('bg1');
posts1.removeClass('bg1').addClass('bg2'); posts1.removeClass('bg1').addClass('bg2');
} }
post.fadeOut(function() { post.fadeOut(function() {
$(this).remove(); $(this).remove();
}); });
} }
}); });
// This callback removes the approve / disapprove div or link. // This callback removes the approve / disapprove div or link.
phpbb.addAjaxCallback('post_visibility', function(res) { phpbb.addAjaxCallback('post_visibility', function(res) {
var remove = (res.visible) ? $(this) : $(this).parents('.post'); var remove = (res.visible) ? $(this) : $(this).parents('.post');
$(remove).css('pointer-events', 'none').fadeOut(function() { $(remove).css('pointer-events', 'none').fadeOut(function() {
$(this).remove(); $(this).remove();
@ -177,15 +179,15 @@ phpbb.addAjaxCallback('post_visibility', function(res) {
$(this).remove(); $(this).remove();
}); });
} }
}); });
// This removes the parent row of the link or form that fired the callback. // This removes the parent row of the link or form that fired the callback.
phpbb.addAjaxCallback('row_delete', function() { phpbb.addAjaxCallback('row_delete', function() {
$(this).parents('tr').remove(); $(this).parents('tr').remove();
}); });
// This handles friend / foe additions removals. // This handles friend / foe additions removals.
phpbb.addAjaxCallback('zebra', function(res) { phpbb.addAjaxCallback('zebra', res => {
var zebra; var zebra;
if (res.success) { if (res.success) {
@ -193,12 +195,12 @@ phpbb.addAjaxCallback('zebra', function(res) {
zebra.first().html(res.MESSAGE_TEXT); zebra.first().html(res.MESSAGE_TEXT);
zebra.not(':first').html('&nbsp;').prev().html('&nbsp;'); zebra.not(':first').html('&nbsp;').prev().html('&nbsp;');
} }
}); });
/** /**
* This callback updates the poll results after voting. * This callback updates the poll results after voting.
*/ */
phpbb.addAjaxCallback('vote_poll', function(res) { phpbb.addAjaxCallback('vote_poll', function(res) {
if (typeof res.success !== 'undefined') { if (typeof res.success !== 'undefined') {
var poll = $(this).closest('.topic_poll'); var poll = $(this).closest('.topic_poll');
var panel = poll.find('.panel'); var panel = poll.find('.panel');
@ -206,10 +208,11 @@ phpbb.addAjaxCallback('vote_poll', function(res) {
var mostVotes = 0; var mostVotes = 0;
// Set min-height to prevent the page from jumping when the content changes // Set min-height to prevent the page from jumping when the content changes
var updatePanelHeight = function (height) { var updatePanelHeight = function(height) {
height = (typeof height === 'undefined') ? panel.find('.inner').outerHeight() : height; height = (typeof height === 'undefined') ? panel.find('.inner').outerHeight() : height;
panel.css('min-height', height); panel.css('min-height', height);
}; };
updatePanelHeight(); updatePanelHeight();
// Remove the View results link // Remove the View results link
@ -217,13 +220,13 @@ phpbb.addAjaxCallback('vote_poll', function(res) {
poll.find('.poll_view_results').hide(500); poll.find('.poll_view_results').hide(500);
} }
if (!res.can_vote) { if (res.can_vote) {
poll.find('.polls, .poll_max_votes, .poll_vote, .poll_option_select').fadeOut(500, function () {
poll.find('.resultbar, .poll_option_percent, .poll_total_votes').show();
});
} else {
// If the user can still vote, simply slide down the results // If the user can still vote, simply slide down the results
poll.find('.resultbar, .poll_option_percent, .poll_total_votes').show(500); poll.find('.resultbar, .poll_option_percent, .poll_total_votes').show(500);
} else {
poll.find('.polls, .poll_max_votes, .poll_vote, .poll_option_select').fadeOut(500, () => {
poll.find('.resultbar, .poll_option_percent, .poll_total_votes').show();
});
} }
// Get the votes count of the highest poll option // Get the votes count of the highest poll option
@ -242,16 +245,16 @@ phpbb.addAjaxCallback('vote_poll', function(res) {
var optionId = $this.attr('data-poll-option-id'); var optionId = $this.attr('data-poll-option-id');
var voted = (typeof res.user_votes[optionId] !== 'undefined'); var voted = (typeof res.user_votes[optionId] !== 'undefined');
var mostVoted = (res.vote_counts[optionId] === mostVotes); var mostVoted = (res.vote_counts[optionId] === mostVotes);
var percent = (!res.total_votes) ? 0 : Math.round((res.vote_counts[optionId] / res.total_votes) * 100); var percent = res.total_votes ? Math.round((res.vote_counts[optionId] / res.total_votes) * 100) : 0;
var percentRel = (mostVotes === 0) ? 0 : Math.round((res.vote_counts[optionId] / mostVotes) * 100); var percentRel = (mostVotes === 0) ? 0 : Math.round((res.vote_counts[optionId] / mostVotes) * 100);
var altText;
altText = $this.attr('data-alt-text'); var altText = $this.attr('data-alt-text');
if (voted) { if (voted) {
$this.attr('title', $.trim(altText)); $this.attr('title', $.trim(altText));
} else { } else {
$this.attr('title', ''); $this.attr('title', '');
}; }
$this.toggleClass('voted', voted); $this.toggleClass('voted', voted);
$this.toggleClass('most-votes', mostVoted); $this.toggleClass('most-votes', mostVoted);
@ -260,7 +263,7 @@ phpbb.addAjaxCallback('vote_poll', function(res) {
var barTimeLapse = (res.can_vote) ? 500 : 1500; var barTimeLapse = (res.can_vote) ? 500 : 1500;
var newBarClass = (percent === 100) ? 'pollbar5' : 'pollbar' + (Math.floor(percent / 20) + 1); var newBarClass = (percent === 100) ? 'pollbar5' : 'pollbar' + (Math.floor(percent / 20) + 1);
setTimeout(function () { setTimeout(() => {
bar.animate({ width: percentRel + '%' }, 500) bar.animate({ width: percentRel + '%' }, 500)
.removeClass('pollbar1 pollbar2 pollbar3 pollbar4 pollbar5') .removeClass('pollbar1 pollbar2 pollbar3 pollbar4 pollbar5')
.addClass(newBarClass) .addClass(newBarClass)
@ -282,34 +285,34 @@ phpbb.addAjaxCallback('vote_poll', function(res) {
updatePanelHeight(); updatePanelHeight();
} }
$(this).delay(5000).fadeOut(500, function() { $(this).delay(5000).fadeOut(500, () => {
resizePanel(300); resizePanel(300);
}); });
}); });
// Remove the gap resulting from removing options // Remove the gap resulting from removing options
setTimeout(function() { setTimeout(() => {
resizePanel(500); resizePanel(500);
}, 1500); }, 1500);
var resizePanel = function (time) { var resizePanel = function(time) {
var panelHeight = panel.height(); var panelHeight = panel.height();
var innerHeight = panel.find('.inner').outerHeight(); var innerHeight = panel.find('.inner').outerHeight();
if (panelHeight !== innerHeight) { if (panelHeight !== innerHeight) {
panel.css({ minHeight: '', height: panelHeight }) panel.css({ minHeight: '', height: panelHeight })
.animate({ height: innerHeight }, time, function () { .animate({ height: innerHeight }, time, () => {
panel.css({ minHeight: innerHeight, height: '' }); panel.css({ minHeight: innerHeight, height: '' });
}); });
} }
}; };
} }
}); });
/** /**
* Show poll results when clicking View results link. * Show poll results when clicking View results link.
*/ */
$('.poll_view_results a').click(function(e) { $('.poll_view_results a').click(function(e) {
// Do not follow the link // Do not follow the link
e.preventDefault(); e.preventDefault();
@ -317,41 +320,38 @@ $('.poll_view_results a').click(function(e) {
$poll.find('.resultbar, .poll_option_percent, .poll_total_votes').show(500); $poll.find('.resultbar, .poll_option_percent, .poll_total_votes').show(500);
$poll.find('.poll_view_results').hide(500); $poll.find('.poll_view_results').hide(500);
}); });
$('[data-ajax]').each(function() { $('[data-ajax]').each(function() {
var $this = $(this); var $this = $(this);
var ajax = $this.attr('data-ajax'); var ajax = $this.attr('data-ajax');
var filter = $this.attr('data-filter'); var filter = $this.attr('data-filter');
if (ajax !== 'false') { if (ajax !== 'false') {
var fn = (ajax !== 'true') ? ajax : null; var fn = ajax === 'true' ? null : ajax;
filter = (filter !== undefined) ? phpbb.getFunctionByName(filter) : null; filter = filter === undefined ? null : phpbb.getFunctionByName(filter);
phpbb.ajaxify({ phpbb.ajaxify({
selector: this, selector: this,
refresh: $this.attr('data-refresh') !== undefined, refresh: $this.attr('data-refresh') !== undefined,
filter: filter, filter,
callback: fn callback: fn,
}); });
} }
}); });
/** /**
* This simply appends #preview to the action of the * This simply appends #preview to the action of the
* QR action when you click the Full Editor & Preview button * QR action when you click the Full Editor & Preview button
*/ */
$('#qr_full_editor').click(function() { $('#qr_full_editor').click(() => {
$('#qr_postform').attr('action', function(i, val) { $('#qr_postform').attr('action', (i, val) => val + '#preview');
return val + '#preview';
}); });
});
/**
/**
* Make the display post links to use JS * Make the display post links to use JS
*/ */
$('.display_post').click(function(e) { $('.display_post').click(function(e) {
// Do not follow the link // Do not follow the link
e.preventDefault(); e.preventDefault();
@ -359,27 +359,27 @@ $('.display_post').click(function(e) {
$('#post_content' + postId).show(); $('#post_content' + postId).show();
$('#profile' + postId).show(); $('#profile' + postId).show();
$('#post_hidden' + postId).hide(); $('#post_hidden' + postId).hide();
}); });
/** /**
* Display hidden post on post review page * Display hidden post on post review page
*/ */
$('.display_post_review').on('click', function(e) { $('.display_post_review').on('click', function(e) {
e.preventDefault(); e.preventDefault();
let $displayPostLink = $(this); const $displayPostLink = $(this);
$displayPostLink.closest('.post-ignore').removeClass('post-ignore'); $displayPostLink.closest('.post-ignore').removeClass('post-ignore');
$displayPostLink.hide(); $displayPostLink.hide();
}); });
/** /**
* Toggle the member search panel in memberlist.php. * Toggle the member search panel in memberlist.php.
* *
* If user returns to search page after viewing results the search panel is automatically displayed. * If user returns to search page after viewing results the search panel is automatically displayed.
* In any case the link will toggle the display status of the search panel and link text will be * In any case the link will toggle the display status of the search panel and link text will be
* appropriately changed based on the status of the search panel. * appropriately changed based on the status of the search panel.
*/ */
$('#member_search').click(function () { $('#member_search').click(function() {
var $memberlistSearch = $('#memberlist_search'); var $memberlistSearch = $('#memberlist_search');
$memberlistSearch.slideToggle('fast'); $memberlistSearch.slideToggle('fast');
@ -389,17 +389,18 @@ $('#member_search').click(function () {
if ($memberlistSearch.is(':visible')) { if ($memberlistSearch.is(':visible')) {
$('#username').focus(); $('#username').focus();
} }
return false;
});
/** return false;
});
/**
* Show to top button if available on page * Show to top button if available on page
*/ */
const $scrollTopButton = $('.to-top-button'); const $scrollTopButton = $('.to-top-button');
if ($scrollTopButton.length) { if ($scrollTopButton.length) {
// Show or hide the button based on scroll position // Show or hide the button based on scroll position
$(window).scroll(function () { $(window).scroll(function() {
if ($(this).scrollTop() > 300) { if ($(this).scrollTop() > 300) {
$scrollTopButton.fadeIn(); // Fade in the button $scrollTopButton.fadeIn(); // Fade in the button
} else { } else {
@ -408,20 +409,18 @@ if ($scrollTopButton.length) {
}); });
// Scroll smoothly to the top when the button is clicked // Scroll smoothly to the top when the button is clicked
$scrollTopButton.click(function (e) { $scrollTopButton.click(e => {
e.preventDefault(); // Prevent the default anchor link behavior e.preventDefault(); // Prevent the default anchor link behavior
$('html, body').animate({scrollTop: 0}, 500); // Smooth scroll to top $('html, body').animate({ scrollTop: 0 }, 500); // Smooth scroll to top
}); });
} }
/** /**
* Automatically resize textarea * Automatically resize textarea
*/ */
$(function() { $(() => {
var $textarea = $('textarea:not(#message-box textarea, .no-auto-resize)'); var $textarea = $('textarea:not(#message-box textarea, .no-auto-resize)');
phpbb.resizeTextArea($textarea, { minHeight: 75, maxHeight: 250 }); phpbb.resizeTextArea($textarea, { minHeight: 75, maxHeight: 250 });
phpbb.resizeTextArea($('textarea', '#message-box')); phpbb.resizeTextArea($('textarea', '#message-box'));
}); });
})(jQuery); // Avoid conflicts with other libraries })(jQuery); // Avoid conflicts with other libraries

View file

@ -1,4 +1,7 @@
/* global phpbb */ /* global phpbb */
/* eslint camelcase: 0 */
/* eslint no-unused-vars: 0 */
/* eslint no-var:0 */
/** /**
* phpBB forum functions * phpBB forum functions
@ -34,10 +37,10 @@ function popup(url, width, height, name) {
function pageJump(item) { function pageJump(item) {
'use strict'; 'use strict';
var page = parseInt(item.val(), 10), var page = parseInt(item.val(), 10);
perPage = item.attr('data-per-page'), var perPage = item.attr('data-per-page');
baseUrl = item.attr('data-base-url'), var baseUrl = item.attr('data-base-url');
startName = item.attr('data-start-name'); var startName = item.attr('data-start-name');
if (page !== null && !isNaN(page) && page === Math.floor(page) && page > 0) { if (page !== null && !isNaN(page) && page === Math.floor(page) && page > 0) {
if (baseUrl.indexOf('?') === -1) { if (baseUrl.indexOf('?') === -1) {
@ -78,39 +81,38 @@ function viewableArea(e, itself) {
e = e.parentNode; e = e.parentNode;
} }
if (!e.vaHeight) { if (e.vaHeight) {
// Restore viewable area height to the default
e.style.height = e.vaHeight + 'px';
e.style.overflow = 'auto';
e.style.maxHeight = e.vaMaxHeight;
e.vaHeight = false;
} else {
// Store viewable area height before changing style to auto // Store viewable area height before changing style to auto
e.vaHeight = e.offsetHeight; e.vaHeight = e.offsetHeight;
e.vaMaxHeight = e.style.maxHeight; e.vaMaxHeight = e.style.maxHeight;
e.style.height = 'auto'; e.style.height = 'auto';
e.style.maxHeight = 'none'; e.style.maxHeight = 'none';
e.style.overflow = 'visible'; e.style.overflow = 'visible';
} else {
// Restore viewable area height to the default
e.style.height = e.vaHeight + 'px';
e.style.overflow = 'auto';
e.style.maxHeight = e.vaMaxHeight;
e.vaHeight = false;
} }
} }
/** /**
* Alternate display of subPanels * Alternate display of subPanels
*/ */
jQuery(function($) { jQuery($ => {
'use strict'; 'use strict';
$('.sub-panels').each(function() { $('.sub-panels').each(function() {
var $childNodes = $('a[data-subpanel]', this);
var $childNodes = $('a[data-subpanel]', this), var panels = $childNodes.map(function() {
panels = $childNodes.map(function () {
return this.getAttribute('data-subpanel'); return this.getAttribute('data-subpanel');
}), });
showPanel = this.getAttribute('data-show-panel'); var showPanel = this.getAttribute('data-show-panel');
if (panels.length) { if (panels.length) {
activateSubPanel(showPanel, panels); activateSubPanel(showPanel, panels);
$childNodes.click(function () { $childNodes.click(function() {
activateSubPanel(this.getAttribute('data-subpanel'), panels); activateSubPanel(this.getAttribute('data-subpanel'), panels);
return false; return false;
}); });
@ -124,11 +126,13 @@ jQuery(function($) {
function activateSubPanel(p, panels) { function activateSubPanel(p, panels) {
'use strict'; 'use strict';
var i, showPanel; var i;
var showPanel;
if (typeof p === 'string') { if (typeof p === 'string') {
showPanel = p; showPanel = p;
} }
$('input[name="show_panel"]').val(showPanel); $('input[name="show_panel"]').val(showPanel);
if (typeof panels === 'undefined') { if (typeof panels === 'undefined') {
@ -148,7 +152,8 @@ function selectCode(a) {
// Get ID of code block // Get ID of code block
var e = a.parentNode.parentNode.getElementsByTagName('CODE')[0]; var e = a.parentNode.parentNode.getElementsByTagName('CODE')[0];
var s, r; var s;
var r;
// Not IE and IE9+ // Not IE and IE9+
if (window.getSelection) { if (window.getSelection) {
@ -164,12 +169,11 @@ function selectCode(a) {
s.removeAllRanges(); s.removeAllRanges();
s.addRange(r); s.addRange(r);
} }
} } else {
// Firefox and Opera // Firefox and Opera
else {
// workaround for bug # 42885 // workaround for bug # 42885
if (window.opera && e.innerHTML.substring(e.innerHTML.length - 4) === '<BR>') { if (window.opera && e.innerHTML.substring(e.innerHTML.length - 4) === '<BR>') {
e.innerHTML = e.innerHTML + '&nbsp;'; e.innerHTML += '&nbsp;';
} }
r = document.createRange(); r = document.createRange();
@ -177,17 +181,15 @@ function selectCode(a) {
s.removeAllRanges(); s.removeAllRanges();
s.addRange(r); s.addRange(r);
} }
} } else if (document.getSelection) {
// Some older browsers // Some older browsers
else if (document.getSelection) {
s = document.getSelection(); s = document.getSelection();
r = document.createRange(); r = document.createRange();
r.selectNodeContents(e); r.selectNodeContents(e);
s.removeAllRanges(); s.removeAllRanges();
s.addRange(r); s.addRange(r);
} } else if (document.selection) {
// IE // IE
else if (document.selection) {
r = document.body.createTextRange(); r = document.body.createTextRange();
r.moveToElementText(e); r.moveToElementText(e);
r.select(); r.select();
@ -229,10 +231,10 @@ function phpbbCheckKey(event) {
/** /**
* Apply onkeypress event for forcing default submit button on ENTER key press * Apply onkeypress event for forcing default submit button on ENTER key press
*/ */
jQuery(function($) { jQuery($ => {
'use strict'; 'use strict';
$('form input[type=text], form input[type=password]').on('keypress', function (e) { $('form input[type=text], form input[type=password]').on('keypress', function(e) {
var defaultButton = $(this).parents('form').find('input[type=submit].default-submit-action'); var defaultButton = $(this).parents('form').find('input[type=submit].default-submit-action');
if (!defaultButton || defaultButton.length <= 0) { if (!defaultButton || defaultButton.length <= 0) {
@ -258,10 +260,10 @@ jQuery(function($) {
function insertUser(formId, value) { function insertUser(formId, value) {
'use strict'; 'use strict';
var $form = jQuery(formId), var $form = jQuery(formId);
formName = $form.attr('data-form-name'), var formName = $form.attr('data-form-name');
fieldName = $form.attr('data-field-name'), var fieldName = $form.attr('data-field-name');
item = opener.document.forms[formName][fieldName]; var item = opener.document.forms[formName][fieldName];
if (item.value.length && item.type === 'textarea') { if (item.value.length && item.type === 'textarea') {
value = item.value + '\n' + value; value = item.value + '\n' + value;
@ -293,9 +295,9 @@ function insert_single_user(formId, user) {
function parseDocument($container) { function parseDocument($container) {
'use strict'; 'use strict';
var test = document.createElement('div'), var test = document.createElement('div');
oldBrowser = (typeof test.style.borderRadius === 'undefined'), var oldBrowser = (typeof test.style.borderRadius === 'undefined');
$body = $('body'); var $body = $('body');
/** /**
* Reset avatar dimensions when changing URL or EMAIL * Reset avatar dimensions when changing URL or EMAIL
@ -322,7 +324,7 @@ function parseDocument($container) {
$container.find('.pagination .dropdown-trigger').click(function() { $container.find('.pagination .dropdown-trigger').click(function() {
var $dropdownContainer = $(this).parent(); var $dropdownContainer = $(this).parent();
// Wait a little bit to make sure the dropdown has activated // Wait a little bit to make sure the dropdown has activated
setTimeout(function() { setTimeout(() => {
if ($dropdownContainer.hasClass('dropdown-visible')) { if ($dropdownContainer.hasClass('dropdown-visible')) {
$dropdownContainer.find('input.inputbox').focus(); $dropdownContainer.find('input.inputbox').focus();
} }
@ -333,19 +335,18 @@ function parseDocument($container) {
* Resize navigation (breadcrumbs) block to keep all links on same line * Resize navigation (breadcrumbs) block to keep all links on same line
*/ */
$container.find('.navlinks').each(function() { $container.find('.navlinks').each(function() {
var $this = $(this), var $this = $(this);
$left = $this.children().not('.rightside'), var $left = $this.children().not('.rightside');
$right = $this.children('.rightside'); var $right = $this.children('.rightside');
if ($left.length !== 1 || !$right.length) { if ($left.length !== 1 || !$right.length) {
return; return;
} }
function resize() { function resize() {
var width = 0, var width = 0;
diff = $left.outerWidth(true) - $left.width(), var diff = $left.outerWidth(true) - $left.width();
minWidth = Math.max($this.width() / 3, 240), var minWidth = Math.max($this.width() / 3, 240);
maxWidth;
$right.each(function() { $right.each(function() {
var $this = $(this); var $this = $(this);
@ -354,7 +355,7 @@ function parseDocument($container) {
} }
}); });
maxWidth = $this.width() - width - diff; var maxWidth = $this.width() - width - diff;
$left.css('max-width', Math.floor(Math.max(maxWidth, minWidth)) + 'px'); $left.css('max-width', Math.floor(Math.max(maxWidth, minWidth)) + 'px');
} }
@ -366,14 +367,14 @@ function parseDocument($container) {
* Makes breadcrumbs responsive * Makes breadcrumbs responsive
*/ */
$container.find('.breadcrumbs:not([data-skip-responsive])').each(function() { $container.find('.breadcrumbs:not([data-skip-responsive])').each(function() {
var $this = $(this), var $this = $(this);
$links = $this.find('.crumb'), var $links = $this.find('.crumb');
length = $links.length, var { length } = $links;
classes = ['wrapped-max', 'wrapped-wide', 'wrapped-medium', 'wrapped-small', 'wrapped-tiny'], var classes = [ 'wrapped-max', 'wrapped-wide', 'wrapped-medium', 'wrapped-small', 'wrapped-tiny' ];
classesLength = classes.length, var classesLength = classes.length;
maxHeight = 0, var maxHeight = 0;
lastWidth = false, var lastWidth = false;
wrapped = false; var wrapped = false;
// Set tooltips // Set tooltips
$this.find('a').each(function() { $this.find('a').each(function() {
@ -383,8 +384,8 @@ function parseDocument($container) {
// Function that checks breadcrumbs // Function that checks breadcrumbs
function check() { function check() {
var height = $this.height(), var height = $this.height();
width; var width;
// Test max-width set in code for .navlinks above // Test max-width set in code for .navlinks above
width = parseInt($this.css('max-width'), 10); width = parseInt($this.css('max-width'), 10);
@ -404,6 +405,7 @@ function parseDocument($container) {
return; return;
} }
} }
lastWidth = width; lastWidth = width;
if (wrapped) { if (wrapped) {
@ -454,23 +456,23 @@ function parseDocument($container) {
* responsive-show-all to list of classes * responsive-show-all to list of classes
*/ */
$container.find('.topiclist.responsive-show-all > li > dl').each(function() { $container.find('.topiclist.responsive-show-all > li > dl').each(function() {
var $this = $(this), var $this = $(this);
$block = $this.find('dt .responsive-show:last-child'), var $block = $this.find('dt .responsive-show:last-child');
first = true; var first = true;
// Create block that is visible only on mobile devices // Create block that is visible only on mobile devices
if (!$block.length) { if ($block.length) {
first = ($.trim($block.text()).length === 0);
} else {
$this.find('dt > .list-inner').append('<div class="responsive-show" style="display:none;" />'); $this.find('dt > .list-inner').append('<div class="responsive-show" style="display:none;" />');
$block = $this.find('dt .responsive-show:last-child'); $block = $this.find('dt .responsive-show:last-child');
} else {
first = ($.trim($block.text()).length === 0);
} }
// Copy contents of each column // Copy contents of each column
$this.find('dd').not('.mark').each(function() { $this.find('dd').not('.mark').each(function() {
var column = $(this), var column = $(this);
$children = column.children(), var $children = column.children();
html = column.html(); var html = column.html();
if ($children.length === 1 && $children.text() === column.text()) { if ($children.length === 1 && $children.text() === column.text()) {
html = $children.html(); html = $children.html();
@ -490,13 +492,13 @@ function parseDocument($container) {
* responsive-show-columns to list of classes * responsive-show-columns to list of classes
*/ */
$container.find('.topiclist.responsive-show-columns').each(function() { $container.find('.topiclist.responsive-show-columns').each(function() {
var $list = $(this), var $list = $(this);
headers = [], var headers = [];
headersLength = 0; var headersLength = 0;
// Find all headers, get contents // Find all headers, get contents
$list.prev('.topiclist').find('li.header dd').not('.mark').each(function() { $list.prev('.topiclist').find('li.header dd').not('.mark').each(function() {
headers.push($("<div>").text($(this).text()).html()); headers.push($('<div>').text($(this).text()).html());
headersLength++; headersLength++;
}); });
@ -506,23 +508,23 @@ function parseDocument($container) {
// Parse each row // Parse each row
$list.find('dl').each(function() { $list.find('dl').each(function() {
var $this = $(this), var $this = $(this);
$block = $this.find('dt .responsive-show:last-child'), var $block = $this.find('dt .responsive-show:last-child');
first = true; var first = true;
// Create block that is visible only on mobile devices // Create block that is visible only on mobile devices
if (!$block.length) { if ($block.length) {
first = ($.trim($block.text()).length === 0);
} else {
$this.find('dt > .list-inner').append('<div class="responsive-show" style="display:none;" />'); $this.find('dt > .list-inner').append('<div class="responsive-show" style="display:none;" />');
$block = $this.find('dt .responsive-show:last-child'); $block = $this.find('dt .responsive-show:last-child');
} else {
first = ($.trim($block.text()).length === 0);
} }
// Copy contents of each column // Copy contents of each column
$this.find('dd').not('.mark').each(function(i) { $this.find('dd').not('.mark').each(function(i) {
var column = $(this), var column = $(this);
children = column.children(), var children = column.children();
html = column.html(); var html = column.html();
if (children.length === 1 && children.text() === column.text()) { if (children.length === 1 && children.text() === column.text()) {
html = children.html(); html = children.html();
@ -544,24 +546,25 @@ function parseDocument($container) {
* Responsive tables * Responsive tables
*/ */
$container.find('table.table1').not('.not-responsive').each(function() { $container.find('table.table1').not('.not-responsive').each(function() {
var $this = $(this), var $this = $(this);
$th = $this.find('thead > tr > th'), var $th = $this.find('thead > tr > th');
headers = [], var headers = [];
totalHeaders = 0, var totalHeaders = 0;
i, headersLength; var i;
// Find each header // Find each header
$th.each(function(column) { $th.each(function(column) {
var cell = $(this), var cell = $(this);
colspan = parseInt(cell.attr('colspan'), 10), var colspan = parseInt(cell.attr('colspan'), 10);
dfn = cell.attr('data-dfn'), var dfn = cell.attr('data-dfn');
text = dfn ? dfn : cell.text(); var text = dfn ? dfn : cell.text();
colspan = isNaN(colspan) || colspan < 1 ? 1 : colspan; colspan = isNaN(colspan) || colspan < 1 ? 1 : colspan;
for (i = 0; i < colspan; i++) { for (i = 0; i < colspan; i++) {
headers.push(text); headers.push(text);
} }
totalHeaders++; totalHeaders++;
if (dfn && !column) { if (dfn && !column) {
@ -569,7 +572,7 @@ function parseDocument($container) {
} }
}); });
headersLength = headers.length; var headersLength = headers.length;
// Add header text to each cell as <dfn> // Add header text to each cell as <dfn>
$this.addClass('responsive'); $this.addClass('responsive');
@ -580,9 +583,9 @@ function parseDocument($container) {
} }
$this.find('tbody > tr').each(function() { $this.find('tbody > tr').each(function() {
var row = $(this), var row = $(this);
cells = row.children('td'), var cells = row.children('td');
column = 0; var column = 0;
if (cells.length === 1) { if (cells.length === 1) {
row.addClass('big-column'); row.addClass('big-column');
@ -590,9 +593,9 @@ function parseDocument($container) {
} }
cells.each(function() { cells.each(function() {
var cell = $(this), var cell = $(this);
colspan = parseInt(cell.attr('colspan'), 10), var colspan = parseInt(cell.attr('colspan'), 10);
text = $.trim(cell.text()); var text = $.trim(cell.text());
if (headersLength <= column) { if (headersLength <= column) {
return; return;
@ -600,7 +603,7 @@ function parseDocument($container) {
if ((text.length && text !== '-') || cell.children().length) { if ((text.length && text !== '-') || cell.children().length) {
if (headers[column].length) { if (headers[column].length) {
cell.prepend($("<dfn>").css('display', 'none').text(headers[column])); cell.prepend($('<dfn>').css('display', 'none').text(headers[column]));
} }
} else { } else {
cell.addClass('empty'); cell.addClass('empty');
@ -626,15 +629,15 @@ function parseDocument($container) {
* Responsive tabs * Responsive tabs
*/ */
$container.find('#tabs, #minitabs').not('[data-skip-responsive]').each(function() { $container.find('#tabs, #minitabs').not('[data-skip-responsive]').each(function() {
var $this = $(this), var $this = $(this);
$ul = $this.children(), var $ul = $this.children();
$tabs = $ul.children().not('[data-skip-responsive]'), var $tabs = $ul.children().not('[data-skip-responsive]');
$links = $tabs.children('a'), var $links = $tabs.children('a');
$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></div><ul class="dropdown-contents" /></div></li>').find('li.responsive-tab'), var $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></div><ul class="dropdown-contents" /></div></li>').find('li.responsive-tab');
$menu = $item.find('.dropdown-contents'), var $menu = $item.find('.dropdown-contents');
maxHeight = 0, var maxHeight = 0;
lastWidth = false, var lastWidth = false;
responsive = false; var responsive = false;
$links.each(function() { $links.each(function() {
var $this = $(this); var $this = $(this);
@ -642,8 +645,8 @@ function parseDocument($container) {
}); });
function check() { function check() {
var width = $body.width(), var width = $body.width();
height = $this.height(); var height = $this.height();
if (!arguments.length && (!responsive || width <= lastWidth) && height <= maxHeight) { if (!arguments.length && (!responsive || width <= lastWidth) && height <= maxHeight) {
return; return;
@ -658,6 +661,7 @@ function parseDocument($container) {
if ($item.hasClass('dropdown-visible')) { if ($item.hasClass('dropdown-visible')) {
phpbb.toggleDropdown.call($item.find('a.responsive-tab-link').get(0)); phpbb.toggleDropdown.call($item.find('a.responsive-tab-link').get(0));
} }
return; return;
} }
@ -665,29 +669,31 @@ function parseDocument($container) {
$item.show(); $item.show();
$menu.html(''); $menu.html('');
var $availableTabs = $tabs.filter(':not(.activetab, .responsive-tab)'), var $availableTabs = $tabs.filter(':not(.activetab, .responsive-tab)');
total = $availableTabs.length, var total = $availableTabs.length;
i, $tab; var i;
var $tab;
for (i = total - 1; i >= 0; i--) { for (i = total - 1; i >= 0; i--) {
$tab = $availableTabs.eq(i); $tab = $availableTabs.eq(i);
$menu.prepend($tab.clone(true).removeClass('tab')); $menu.prepend($tab.clone(true).removeClass('tab'));
$tab.hide(); $tab.hide();
if ($this.height() <= maxHeight) { if ($this.height() <= maxHeight) {
$menu.find('a').click(function() { $menu.find('a').click(() => {
check(true); check(true);
}); });
return; return;
} }
} }
$menu.find('a').click(function() {
$menu.find('a').click(() => {
check(true); check(true);
}); });
} }
var $tabLink = $item.find('a.responsive-tab-link'); var $tabLink = $item.find('a.responsive-tab-link');
phpbb.registerDropdown($tabLink, $item.find('.dropdown'), { phpbb.registerDropdown($tabLink, $item.find('.dropdown'), {
visibleClass: 'activetab' visibleClass: 'activetab',
}); });
check(true); check(true);
@ -708,23 +714,26 @@ function parseDocument($container) {
* Replace responsive text * Replace responsive text
*/ */
$container.find('[data-responsive-text]').each(function() { $container.find('[data-responsive-text]').each(function() {
var $this = $(this), var $this = $(this);
fullText = $this.text(), var fullText = $this.text();
responsiveText = $this.attr('data-responsive-text'), var responsiveText = $this.attr('data-responsive-text');
responsive = false; var responsive = false;
function check() { function check() {
if ($(window).width() > 700) { if ($(window).width() > 700) {
if (!responsive) { if (!responsive) {
return; return;
} }
$this.text(fullText); $this.text(fullText);
responsive = false; responsive = false;
return; return;
} }
if (responsive) { if (responsive) {
return; return;
} }
$this.text(responsiveText); $this.text(responsiveText);
responsive = true; responsive = true;
} }
@ -737,7 +746,7 @@ function parseDocument($container) {
/** /**
* Run onload functions * Run onload functions
*/ */
jQuery(function($) { jQuery($ => {
'use strict'; 'use strict';
// Swap .nojs and .hasjs // Swap .nojs and .hasjs