mirror of
https://github.com/phpbb/phpbb.git
synced 2025-06-07 20:08:53 +00:00
Merge b82d7d3f47
into 2fce8aeb3e
This commit is contained in:
commit
33c3dd509d
14 changed files with 4817 additions and 4261 deletions
4
.github/check-js.sh
vendored
4
.github/check-js.sh
vendored
|
@ -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
67
eslint.config.mjs
Normal 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,
|
||||||
|
];
|
1784
package-lock.json
generated
1784
package-lock.json
generated
File diff suppressed because it is too large
Load diff
63
package.json
63
package.json
|
@ -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",
|
||||||
|
|
|
@ -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() == ' ') {
|
if ($this.html() === ' ') {
|
||||||
$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"> </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"> </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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,424 +1,421 @@
|
||||||
/* 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() {
|
||||||
|
var $form = $('#acp_help_phpbb');
|
||||||
|
var $dark = $('#darkenwrapper');
|
||||||
|
var $loadingIndicator;
|
||||||
|
|
||||||
|
$form.on('submit', function(event) {
|
||||||
|
var $this = $(this);
|
||||||
|
var currentTime = Math.floor(new Date().getTime() / 1000);
|
||||||
|
var statsTime = parseInt($this.find('input[name=help_send_statistics_time]').val(), 10);
|
||||||
|
|
||||||
phpbb.prepareSendStats = function () {
|
event.preventDefault();
|
||||||
var $form = $('#acp_help_phpbb');
|
$this.unbind('submit');
|
||||||
var $dark = $('#darkenwrapper');
|
|
||||||
var $loadingIndicator;
|
|
||||||
|
|
||||||
$form.on('submit', function (event) {
|
// Skip ajax request if form is submitted too early or send stats
|
||||||
var $this = $(this),
|
// checkbox is not checked
|
||||||
currentTime = Math.floor(new Date().getTime() / 1000),
|
if (!$this.find('input[name=help_send_statistics]').is(':checked') || statsTime > currentTime) {
|
||||||
statsTime = parseInt($this.find('input[name=help_send_statistics_time]').val(), 10);
|
|
||||||
|
|
||||||
event.preventDefault();
|
|
||||||
$this.unbind('submit');
|
|
||||||
|
|
||||||
// Skip ajax request if form is submitted too early or send stats
|
|
||||||
// checkbox is not checked
|
|
||||||
if (!$this.find('input[name=help_send_statistics]').is(':checked') ||
|
|
||||||
statsTime > currentTime) {
|
|
||||||
$form.find('input[type=submit]').click();
|
|
||||||
setTimeout(function () {
|
|
||||||
$form.find('input[type=submit]').click();
|
$form.find('input[type=submit]').click();
|
||||||
}, 300);
|
setTimeout(() => {
|
||||||
|
$form.find('input[type=submit]').click();
|
||||||
|
}, 300);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for AJAX errors
|
||||||
|
*/
|
||||||
|
function errorHandler(jqXHR, textStatus, errorThrown) {
|
||||||
|
if (typeof console !== 'undefined' && console.log) {
|
||||||
|
console.log('AJAX error. status: ' + textStatus + ', message: ' + errorThrown);
|
||||||
|
}
|
||||||
|
|
||||||
|
phpbb.clearLoadingTimeout();
|
||||||
|
var errorText = '';
|
||||||
|
|
||||||
|
if (typeof errorThrown === 'string' && errorThrown.length > 0) {
|
||||||
|
errorText = errorThrown;
|
||||||
|
} else {
|
||||||
|
errorText = $dark.attr('data-ajax-error-text-' + textStatus);
|
||||||
|
if (typeof errorText !== 'string' || !errorText.length) {
|
||||||
|
errorText = $dark.attr('data-ajax-error-text');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
phpbb.alert($dark.attr('data-ajax-error-title'), errorText);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a private function used to handle the callbacks, refreshes
|
||||||
|
* and alert. It calls the callback, refreshes the page if necessary, and
|
||||||
|
* displays an alert to the user and removes it after an amount of time.
|
||||||
|
*
|
||||||
|
* It cannot be called from outside this function, and is purely here to
|
||||||
|
* avoid repetition of code.
|
||||||
|
*
|
||||||
|
* @param {object} res The object sent back by the server.
|
||||||
|
*/
|
||||||
|
function returnHandler(res) {
|
||||||
|
phpbb.clearLoadingTimeout();
|
||||||
|
|
||||||
|
// If a confirmation is not required, display an alert and call the
|
||||||
|
// callbacks.
|
||||||
|
$dark.fadeOut(phpbb.alertTime);
|
||||||
|
|
||||||
|
if ($loadingIndicator) {
|
||||||
|
$loadingIndicator.fadeOut(phpbb.alertTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
var $sendStatisticsSuccess = $('<input />', {
|
||||||
|
type: 'hidden',
|
||||||
|
name: 'send_statistics_response',
|
||||||
|
value: JSON.stringify(res),
|
||||||
|
});
|
||||||
|
$sendStatisticsSuccess.appendTo('p.submit-buttons');
|
||||||
|
|
||||||
|
// Finish actual form submission
|
||||||
|
$form.find('input[type=submit]').click();
|
||||||
|
}
|
||||||
|
|
||||||
|
$loadingIndicator = phpbb.loadingIndicator();
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: $this.attr('data-ajax-action').replace('&', '&'),
|
||||||
|
type: 'POST',
|
||||||
|
data: statsData,
|
||||||
|
success: returnHandler,
|
||||||
|
error: errorHandler,
|
||||||
|
cache: false,
|
||||||
|
}).always(() => {
|
||||||
|
if ($loadingIndicator && $loadingIndicator.is(':visible')) {
|
||||||
|
$loadingIndicator.fadeOut(phpbb.alertTime);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The following callbacks are for reording items. row_down
|
||||||
|
* 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 /
|
||||||
|
* activates any up / down icons that require it (the ones at the top or bottom).
|
||||||
|
*/
|
||||||
|
phpbb.addAjaxCallback('row_down', function(res) {
|
||||||
|
if (typeof res.success === 'undefined' || !res.success) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
var $firstTr = $(this).parents('tr');
|
||||||
* Handler for AJAX errors
|
var $secondTr = $firstTr.next();
|
||||||
*/
|
|
||||||
function errorHandler(jqXHR, textStatus, errorThrown) {
|
|
||||||
if (typeof console !== 'undefined' && console.log) {
|
|
||||||
console.log('AJAX error. status: ' + textStatus + ', message: ' + errorThrown);
|
|
||||||
}
|
|
||||||
phpbb.clearLoadingTimeout();
|
|
||||||
var errorText = '';
|
|
||||||
|
|
||||||
if (typeof errorThrown === 'string' && errorThrown.length > 0) {
|
$firstTr.insertAfter($secondTr);
|
||||||
errorText = errorThrown;
|
});
|
||||||
} else {
|
|
||||||
errorText = $dark.attr('data-ajax-error-text-' + textStatus);
|
phpbb.addAjaxCallback('row_up', function(res) {
|
||||||
if (typeof errorText !== 'string' || !errorText.length) {
|
if (typeof res.success === 'undefined' || !res.success) {
|
||||||
errorText = $dark.attr('data-ajax-error-text');
|
return;
|
||||||
}
|
|
||||||
}
|
|
||||||
phpbb.alert($dark.attr('data-ajax-error-title'), errorText);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
var $secondTr = $(this).parents('tr');
|
||||||
* This is a private function used to handle the callbacks, refreshes
|
var $firstTr = $secondTr.prev();
|
||||||
* and alert. It calls the callback, refreshes the page if necessary, and
|
|
||||||
* displays an alert to the user and removes it after an amount of time.
|
|
||||||
*
|
|
||||||
* It cannot be called from outside this function, and is purely here to
|
|
||||||
* avoid repetition of code.
|
|
||||||
*
|
|
||||||
* @param {object} res The object sent back by the server.
|
|
||||||
*/
|
|
||||||
function returnHandler(res) {
|
|
||||||
phpbb.clearLoadingTimeout();
|
|
||||||
|
|
||||||
// If a confirmation is not required, display an alert and call the
|
$secondTr.insertBefore($firstTr);
|
||||||
// callbacks.
|
});
|
||||||
$dark.fadeOut(phpbb.alertTime);
|
|
||||||
|
|
||||||
if ($loadingIndicator) {
|
/**
|
||||||
$loadingIndicator.fadeOut(phpbb.alertTime);
|
* This callback replaces activate links with deactivate links and vice versa.
|
||||||
}
|
* It does this by replacing the text, and replacing all instances of "activate"
|
||||||
|
* in the href with "deactivate", and vice versa.
|
||||||
|
*/
|
||||||
|
phpbb.addAjaxCallback('activate_deactivate', function(res) {
|
||||||
|
var $this = $(this);
|
||||||
|
var newHref = $this.attr('href');
|
||||||
|
|
||||||
var $sendStatisticsSuccess = $('<input />', {
|
$this.text(res.text);
|
||||||
type: 'hidden',
|
|
||||||
name: 'send_statistics_response',
|
|
||||||
value: JSON.stringify(res)
|
|
||||||
});
|
|
||||||
$sendStatisticsSuccess.appendTo('p.submit-buttons');
|
|
||||||
|
|
||||||
// Finish actual form submission
|
if (newHref.indexOf('deactivate') === -1) {
|
||||||
$form.find('input[type=submit]').click();
|
newHref = newHref.replace('activate', 'deactivate');
|
||||||
|
} else {
|
||||||
|
newHref = newHref.replace('deactivate', 'activate');
|
||||||
}
|
}
|
||||||
|
|
||||||
$loadingIndicator = phpbb.loadingIndicator();
|
$this.attr('href', newHref);
|
||||||
|
});
|
||||||
|
|
||||||
$.ajax({
|
/**
|
||||||
url: $this.attr('data-ajax-action').replace('&', '&'),
|
* The removes the parent row of the link or form that triggered the callback,
|
||||||
type: 'POST',
|
* and is good for stuff like the removal of forums.
|
||||||
data: statsData,
|
*/
|
||||||
success: returnHandler,
|
phpbb.addAjaxCallback('row_delete', function(res) {
|
||||||
error: errorHandler,
|
if (res.SUCCESS !== false) {
|
||||||
cache: false
|
$(this).parents('tr').remove();
|
||||||
}).always(function() {
|
}
|
||||||
if ($loadingIndicator && $loadingIndicator.is(':visible')) {
|
});
|
||||||
$loadingIndicator.fadeOut(phpbb.alertTime);
|
|
||||||
|
/**
|
||||||
|
* This callback generates the VAPID keys for the web push notification service.
|
||||||
|
*/
|
||||||
|
phpbb.addAjaxCallback('generate_vapid_keys', () => {
|
||||||
|
/**
|
||||||
|
* Generate VAPID keypair with public and private key string
|
||||||
|
*
|
||||||
|
* @returns {Promise<{privateKey: string, publicKey: string}|null>}
|
||||||
|
*/
|
||||||
|
async function generateVAPIDKeys() {
|
||||||
|
try {
|
||||||
|
// Generate a new key pair using the Subtle Crypto API
|
||||||
|
const keyPair = await crypto.subtle.generateKey(
|
||||||
|
{
|
||||||
|
name: 'ECDH',
|
||||||
|
namedCurve: 'P-256',
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
[ 'deriveKey', 'deriveBits' ],
|
||||||
|
);
|
||||||
|
|
||||||
|
const privateKeyJwk = await crypto.subtle.exportKey('jwk', keyPair.privateKey);
|
||||||
|
const privateKeyString = privateKeyJwk.d;
|
||||||
|
|
||||||
|
const publicKeyBuffer = await crypto.subtle.exportKey('raw', keyPair.publicKey);
|
||||||
|
const publicKeyString = phpbb.base64UrlEncode(phpbb.rawKeyToBase64(publicKeyBuffer));
|
||||||
|
|
||||||
|
return {
|
||||||
|
privateKey: privateKeyString,
|
||||||
|
publicKey: publicKeyString,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error generating keys with SubtleCrypto:', error);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
generateVAPIDKeys().then(keyPair => {
|
||||||
|
if (!keyPair) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const publicKeyInput = document.querySelector('#webpush_vapid_public');
|
||||||
|
const privateKeyInput = document.querySelector('#webpush_vapid_private');
|
||||||
|
publicKeyInput.value = keyPair.publicKey;
|
||||||
|
privateKeyInput.value = keyPair.privateKey;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The following callbacks are for reording items. row_down
|
|
||||||
* 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 /
|
|
||||||
* activates any up / down icons that require it (the ones at the top or bottom).
|
|
||||||
*/
|
|
||||||
phpbb.addAjaxCallback('row_down', function(res) {
|
|
||||||
if (typeof res.success === 'undefined' || !res.success) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var $firstTr = $(this).parents('tr'),
|
|
||||||
$secondTr = $firstTr.next();
|
|
||||||
|
|
||||||
$firstTr.insertAfter($secondTr);
|
|
||||||
});
|
|
||||||
|
|
||||||
phpbb.addAjaxCallback('row_up', function(res) {
|
|
||||||
if (typeof res.success === 'undefined' || !res.success) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var $secondTr = $(this).parents('tr'),
|
|
||||||
$firstTr = $secondTr.prev();
|
|
||||||
|
|
||||||
$secondTr.insertBefore($firstTr);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback replaces activate links with deactivate links and vice versa.
|
|
||||||
* It does this by replacing the text, and replacing all instances of "activate"
|
|
||||||
* in the href with "deactivate", and vice versa.
|
|
||||||
*/
|
|
||||||
phpbb.addAjaxCallback('activate_deactivate', function(res) {
|
|
||||||
var $this = $(this),
|
|
||||||
newHref = $this.attr('href');
|
|
||||||
|
|
||||||
$this.text(res.text);
|
|
||||||
|
|
||||||
if (newHref.indexOf('deactivate') !== -1) {
|
|
||||||
newHref = newHref.replace('deactivate', 'activate');
|
|
||||||
} else {
|
|
||||||
newHref = newHref.replace('activate', 'deactivate');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this.attr('href', newHref);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The removes the parent row of the link or form that triggered the callback,
|
|
||||||
* and is good for stuff like the removal of forums.
|
|
||||||
*/
|
|
||||||
phpbb.addAjaxCallback('row_delete', function(res) {
|
|
||||||
if (res.SUCCESS !== false) {
|
|
||||||
$(this).parents('tr').remove();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback generates the VAPID keys for the web push notification service.
|
|
||||||
*/
|
|
||||||
phpbb.addAjaxCallback('generate_vapid_keys', () => {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate VAPID keypair with public and private key string
|
* Handler for submitting permissions form in chunks
|
||||||
*
|
* This call will submit permissions forms in chunks of 5 fieldsets.
|
||||||
* @returns {Promise<{privateKey: string, publicKey: string}|null>}
|
*/
|
||||||
*/
|
function submitPermissions() {
|
||||||
async function generateVAPIDKeys() {
|
var $form = $('form#set-permissions');
|
||||||
try {
|
var fieldsetList = $form.find('fieldset[id^=perm]');
|
||||||
// Generate a new key pair using the Subtle Crypto API
|
var formDataSets = [];
|
||||||
const keyPair = await crypto.subtle.generateKey(
|
var dataSetIndex = 0;
|
||||||
{
|
var $submitAllButton = $form.find('input[type=submit][name^=action]')[0];
|
||||||
name: 'ECDH',
|
var $submitButton = $form.find('input[type=submit][data-clicked=true]')[0];
|
||||||
namedCurve: 'P-256',
|
|
||||||
},
|
|
||||||
true,
|
|
||||||
['deriveKey', 'deriveBits']
|
|
||||||
);
|
|
||||||
|
|
||||||
const privateKeyJwk = await crypto.subtle.exportKey('jwk', keyPair.privateKey);
|
// Set proper start values for handling refresh of page
|
||||||
const privateKeyString = privateKeyJwk.d;
|
var permissionSubmitSize = 0;
|
||||||
|
var permissionRequestCount = 0;
|
||||||
|
var forumIds = [];
|
||||||
|
var permissionSubmitFailed = false;
|
||||||
|
var clearIndicator = true;
|
||||||
|
|
||||||
const publicKeyBuffer = await crypto.subtle.exportKey('raw', keyPair.publicKey);
|
if ($submitAllButton !== $submitButton) {
|
||||||
const publicKeyString = phpbb.base64UrlEncode(phpbb.rawKeyToBase64(publicKeyBuffer));
|
fieldsetList = $form.find('fieldset#' + $submitButton.closest('fieldset.permissions').id);
|
||||||
|
|
||||||
return {
|
|
||||||
privateKey: privateKeyString,
|
|
||||||
publicKey: publicKeyString
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error generating keys with SubtleCrypto:', error);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
generateVAPIDKeys().then(keyPair => {
|
|
||||||
if (!keyPair) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const publicKeyInput = document.querySelector('#webpush_vapid_public');
|
|
||||||
const privateKeyInput = document.querySelector('#webpush_vapid_private');
|
|
||||||
publicKeyInput.value = keyPair.publicKey;
|
|
||||||
privateKeyInput.value = keyPair.privateKey;
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler for submitting permissions form in chunks
|
|
||||||
* This call will submit permissions forms in chunks of 5 fieldsets.
|
|
||||||
*/
|
|
||||||
function submitPermissions() {
|
|
||||||
var $form = $('form#set-permissions'),
|
|
||||||
fieldsetList = $form.find('fieldset[id^=perm]'),
|
|
||||||
formDataSets = [],
|
|
||||||
dataSetIndex = 0,
|
|
||||||
$submitAllButton = $form.find('input[type=submit][name^=action]')[0],
|
|
||||||
$submitButton = $form.find('input[type=submit][data-clicked=true]')[0];
|
|
||||||
|
|
||||||
// Set proper start values for handling refresh of page
|
|
||||||
var permissionSubmitSize = 0,
|
|
||||||
permissionRequestCount = 0,
|
|
||||||
forumIds = [],
|
|
||||||
permissionSubmitFailed = false,
|
|
||||||
clearIndicator = true,
|
|
||||||
$loadingIndicator;
|
|
||||||
|
|
||||||
if ($submitAllButton !== $submitButton) {
|
|
||||||
fieldsetList = $form.find('fieldset#' + $submitButton.closest('fieldset.permissions').id);
|
|
||||||
}
|
|
||||||
|
|
||||||
$.each(fieldsetList, function (key, value) {
|
|
||||||
dataSetIndex = Math.floor(key / 5);
|
|
||||||
var $fieldset = $('fieldset#' + value.id);
|
|
||||||
if (key % 5 === 0) {
|
|
||||||
formDataSets[dataSetIndex] = $fieldset.find('select:visible, input:not([data-name])').serialize();
|
|
||||||
} else {
|
|
||||||
formDataSets[dataSetIndex] += '&' + $fieldset.find('select:visible, input:not([data-name])').serialize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find proper role value
|
$.each(fieldsetList, (key, value) => {
|
||||||
var roleInput = $fieldset.find('input[name^=role][data-name]');
|
dataSetIndex = Math.floor(key / 5);
|
||||||
if (roleInput.val()) {
|
var $fieldset = $('fieldset#' + value.id);
|
||||||
formDataSets[dataSetIndex] += '&' + roleInput.attr('name') + '=' + roleInput.val();
|
if (key % 5 === 0) {
|
||||||
} else {
|
formDataSets[dataSetIndex] = $fieldset.find('select:visible, input:not([data-name])').serialize();
|
||||||
formDataSets[dataSetIndex] += '&' + roleInput.attr('name') + '=' +
|
} else {
|
||||||
$fieldset.find('select[name="' + roleInput.attr('name') + '"]').val();
|
formDataSets[dataSetIndex] += '&' + $fieldset.find('select:visible, input:not([data-name])').serialize();
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
permissionSubmitSize = formDataSets.length;
|
// Find proper role value
|
||||||
|
var roleInput = $fieldset.find('input[name^=role][data-name]');
|
||||||
|
if (roleInput.val()) {
|
||||||
|
formDataSets[dataSetIndex] += '&' + roleInput.attr('name') + '=' + roleInput.val();
|
||||||
|
} else {
|
||||||
|
formDataSets[dataSetIndex] += '&' + roleInput.attr('name') + '='
|
||||||
|
+ $fieldset.find('select[name="' + roleInput.attr('name') + '"]').val();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Add each forum ID to forum ID list to preserve selected forums
|
permissionSubmitSize = formDataSets.length;
|
||||||
$.each($form.find('input[type=hidden][name^=forum_id]'), function (key, value) {
|
|
||||||
if (value.name.match(/^forum_id\[([0-9]+)\]$/)) {
|
|
||||||
forumIds.push(value.value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$loadingIndicator = phpbb.loadingIndicator();
|
// Add each forum ID to forum ID list to preserve selected forums
|
||||||
|
$.each($form.find('input[type=hidden][name^=forum_id]'), (key, value) => {
|
||||||
|
if (value.name.match(/^forum_id\[([0-9]+)\]$/)) {
|
||||||
|
forumIds.push(value.value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
var $loadingIndicator = phpbb.loadingIndicator();
|
||||||
* Handler for submitted permissions form chunk
|
|
||||||
*
|
|
||||||
* @param {object} res Object returned by AJAX call
|
|
||||||
*/
|
|
||||||
function handlePermissionReturn(res) {
|
|
||||||
permissionRequestCount++;
|
|
||||||
var $dark = $('#darkenwrapper');
|
|
||||||
|
|
||||||
if (res.S_USER_WARNING) {
|
/**
|
||||||
phpbb.alert(res.MESSAGE_TITLE, res.MESSAGE_TEXT);
|
* Handler for submitted permissions form chunk
|
||||||
permissionSubmitFailed = true;
|
*
|
||||||
} else if (!permissionSubmitFailed && res.S_USER_NOTICE) {
|
* @param {object} res Object returned by AJAX call
|
||||||
// Display success message at the end of submitting the form
|
*/
|
||||||
if (permissionRequestCount >= permissionSubmitSize) {
|
function handlePermissionReturn(res) {
|
||||||
clearIndicator = true;
|
permissionRequestCount++;
|
||||||
|
var $dark = $('#darkenwrapper');
|
||||||
|
|
||||||
var $alert = phpbb.alert(res.MESSAGE_TITLE, res.MESSAGE_TEXT);
|
if (res.S_USER_WARNING) {
|
||||||
var $alertBoxLink = $alert.find('p.alert_text > a');
|
phpbb.alert(res.MESSAGE_TITLE, res.MESSAGE_TEXT);
|
||||||
|
permissionSubmitFailed = true;
|
||||||
|
} else if (!permissionSubmitFailed && res.S_USER_NOTICE) {
|
||||||
|
// Display success message at the end of submitting the form
|
||||||
|
if (permissionRequestCount >= permissionSubmitSize) {
|
||||||
|
clearIndicator = true;
|
||||||
|
|
||||||
// Create form to submit instead of normal "Back to previous page" link
|
var $alert = phpbb.alert(res.MESSAGE_TITLE, res.MESSAGE_TEXT);
|
||||||
if ($alertBoxLink) {
|
var $alertBoxLink = $alert.find('p.alert_text > a');
|
||||||
// Remove forum_id[] from URL
|
|
||||||
$alertBoxLink.attr('href', $alertBoxLink.attr('href').replace(/(&forum_id\[\]=[0-9]+)/g, ''));
|
|
||||||
const $previousPageForm = $('<form>').attr({
|
|
||||||
action: $alertBoxLink.attr('href'),
|
|
||||||
method: 'post'
|
|
||||||
});
|
|
||||||
|
|
||||||
$.each(forumIds, function (key, value) {
|
// Create form to submit instead of normal "Back to previous page" link
|
||||||
$previousPageForm.append($('<input>').attr({
|
if ($alertBoxLink) {
|
||||||
type: 'text',
|
// Remove forum_id[] from URL
|
||||||
name: 'forum_id[]',
|
$alertBoxLink.attr('href', $alertBoxLink.attr('href').replace(/(&forum_id\[\]=[0-9]+)/g, ''));
|
||||||
value: value
|
const $previousPageForm = $('<form>').attr({
|
||||||
}));
|
action: $alertBoxLink.attr('href'),
|
||||||
});
|
method: 'post',
|
||||||
|
|
||||||
$alertBoxLink.on('click', function (e) {
|
|
||||||
$('body').append($previousPageForm);
|
|
||||||
e.preventDefault();
|
|
||||||
$previousPageForm.submit();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do not allow closing alert
|
|
||||||
$dark.off('click');
|
|
||||||
$alert.find('.alert_close').hide();
|
|
||||||
|
|
||||||
if (typeof res.REFRESH_DATA !== 'undefined') {
|
|
||||||
setTimeout(function () {
|
|
||||||
// Create forum to submit using POST. This will prevent
|
|
||||||
// exceeding the maximum length of URLs
|
|
||||||
const $form = $('<form>').attr({
|
|
||||||
action: res.REFRESH_DATA.url.replace(/(&forum_id\[\]=[0-9]+)/g, ''),
|
|
||||||
method: 'post'
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$.each(forumIds, function (key, value) {
|
$.each(forumIds, (key, value) => {
|
||||||
$form.append($('<input>').attr({
|
$previousPageForm.append($('<input>').attr({
|
||||||
type: 'text',
|
type: 'text',
|
||||||
name: 'forum_id[]',
|
name: 'forum_id[]',
|
||||||
value: value
|
value,
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
$('body').append($form);
|
$alertBoxLink.on('click', e => {
|
||||||
|
$('body').append($previousPageForm);
|
||||||
// Hide the alert even if we refresh the page, in case the user
|
e.preventDefault();
|
||||||
// presses the back button.
|
$previousPageForm.submit();
|
||||||
$dark.fadeOut(phpbb.alertTime, function () {
|
|
||||||
if (typeof $alert !== 'undefined') {
|
|
||||||
$alert.hide();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Submit form
|
// Do not allow closing alert
|
||||||
$form.submit();
|
$dark.off('click');
|
||||||
}, res.REFRESH_DATA.time * 1000); // Server specifies time in seconds
|
$alert.find('.alert_close').hide();
|
||||||
|
|
||||||
|
if (typeof res.REFRESH_DATA !== 'undefined') {
|
||||||
|
setTimeout(() => {
|
||||||
|
// Create forum to submit using POST. This will prevent
|
||||||
|
// exceeding the maximum length of URLs
|
||||||
|
const $form = $('<form>').attr({
|
||||||
|
action: res.REFRESH_DATA.url.replace(/(&forum_id\[\]=[0-9]+)/g, ''),
|
||||||
|
method: 'post',
|
||||||
|
});
|
||||||
|
|
||||||
|
$.each(forumIds, (key, value) => {
|
||||||
|
$form.append($('<input>').attr({
|
||||||
|
type: 'text',
|
||||||
|
name: 'forum_id[]',
|
||||||
|
value,
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
$('body').append($form);
|
||||||
|
|
||||||
|
// Hide the alert even if we refresh the page, in case the user
|
||||||
|
// presses the back button.
|
||||||
|
$dark.fadeOut(phpbb.alertTime, () => {
|
||||||
|
if (typeof $alert !== 'undefined') {
|
||||||
|
$alert.hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Submit form
|
||||||
|
$form.submit();
|
||||||
|
}, res.REFRESH_DATA.time * 1000); // Server specifies time in seconds
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Still more forms to submit, so do not clear indicator
|
||||||
|
clearIndicator = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clearIndicator) {
|
||||||
|
phpbb.clearLoadingTimeout();
|
||||||
|
|
||||||
|
if ($loadingIndicator) {
|
||||||
|
$loadingIndicator.fadeOut(phpbb.alertTime);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// Still more forms to submit, so do not clear indicator
|
|
||||||
clearIndicator = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clearIndicator) {
|
// Create AJAX request for each form data set
|
||||||
phpbb.clearLoadingTimeout();
|
$.each(formDataSets, (key, formData) => {
|
||||||
|
$.ajax({
|
||||||
if ($loadingIndicator) {
|
url: $form.action,
|
||||||
$loadingIndicator.fadeOut(phpbb.alertTime);
|
type: 'POST',
|
||||||
}
|
data: formData + '&' + $submitButton.name + '=' + encodeURIComponent($submitButton.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.children('input[type=hidden]').serialize()
|
||||||
|
+ '&' + $form.find('input[type=checkbox][name^=inherit]').serialize(),
|
||||||
|
success: handlePermissionReturn,
|
||||||
|
error: handlePermissionReturn,
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create AJAX request for each form data set
|
$('[data-ajax]').each(function() {
|
||||||
$.each(formDataSets, function (key, formData) {
|
var $this = $(this);
|
||||||
$.ajax({
|
var ajax = $this.attr('data-ajax');
|
||||||
url: $form.action,
|
|
||||||
type: 'POST',
|
if (ajax !== 'false') {
|
||||||
data: formData + '&' + $submitButton.name + '=' + encodeURIComponent($submitButton.value) +
|
var fn = (ajax === 'true') ? null : ajax;
|
||||||
'&creation_time=' + $form.find('input[type=hidden][name=creation_time]')[0].value +
|
phpbb.ajaxify({
|
||||||
'&form_token=' + $form.find('input[type=hidden][name=form_token]')[0].value +
|
selector: this,
|
||||||
'&' + $form.children('input[type=hidden]').serialize() +
|
refresh: $this.attr('data-refresh') !== undefined,
|
||||||
'&' + $form.find('input[type=checkbox][name^=inherit]').serialize(),
|
callback: fn,
|
||||||
success: handlePermissionReturn,
|
});
|
||||||
error: handlePermissionReturn
|
}
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
$('[data-ajax]').each(function() {
|
/**
|
||||||
var $this = $(this),
|
* Automatically resize textarea
|
||||||
ajax = $this.attr('data-ajax');
|
*/
|
||||||
|
$(() => {
|
||||||
|
phpbb.resizeTextArea($('textarea:not(.no-auto-resize)'), { minHeight: 75 });
|
||||||
|
|
||||||
if (ajax !== 'false') {
|
var $setPermissionsForm = $('form#set-permissions');
|
||||||
var fn = (ajax !== 'true') ? ajax : null;
|
if ($setPermissionsForm.length) {
|
||||||
phpbb.ajaxify({
|
$setPermissionsForm.on('submit', e => {
|
||||||
selector: this,
|
submitPermissions();
|
||||||
refresh: $this.attr('data-refresh') !== undefined,
|
e.preventDefault();
|
||||||
callback: fn
|
});
|
||||||
});
|
$setPermissionsForm.find('input[type=submit]').click(function() {
|
||||||
}
|
$('input[type=submit]', $(this).parents($('form#set-permissions'))).removeAttr('data-clicked');
|
||||||
});
|
$(this).attr('data-clicked', true);
|
||||||
|
});
|
||||||
/**
|
}
|
||||||
* Automatically resize textarea
|
|
||||||
*/
|
|
||||||
$(function() {
|
|
||||||
phpbb.resizeTextArea($('textarea:not(.no-auto-resize)'), {minHeight: 75});
|
|
||||||
|
|
||||||
var $setPermissionsForm = $('form#set-permissions');
|
|
||||||
if ($setPermissionsForm.length) {
|
|
||||||
$setPermissionsForm.on('submit', function (e) {
|
|
||||||
submitPermissions();
|
|
||||||
e.preventDefault();
|
|
||||||
});
|
|
||||||
$setPermissionsForm.find('input[type=submit]').click(function() {
|
|
||||||
$('input[type=submit]', $(this).parents($('form#set-permissions'))).removeAttr('data-clicked');
|
|
||||||
$(this).attr('data-clicked', true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle date option changes
|
|
||||||
const dateoptionSelect = document.getElementById('dateoptions');
|
|
||||||
if (dateoptionSelect) {
|
|
||||||
dateoptionSelect.addEventListener('change', function() {
|
|
||||||
const dateoptionInput = document.getElementById(this.getAttribute('data-dateoption'));
|
|
||||||
if (this.value === 'custom') {
|
|
||||||
dateoptionInput.value = this.getAttribute('data-dateoption-default');
|
|
||||||
} else {
|
|
||||||
dateoptionInput.value = this.value;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($('#acp_help_phpbb')) {
|
|
||||||
phpbb.prepareSendStats();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
// Handle date option changes
|
||||||
|
const dateoptionSelect = document.getElementById('dateoptions');
|
||||||
|
if (dateoptionSelect) {
|
||||||
|
dateoptionSelect.addEventListener('change', function() {
|
||||||
|
const dateoptionInput = document.getElementById(this.getAttribute('data-dateoption'));
|
||||||
|
if (this.value === 'custom') {
|
||||||
|
dateoptionInput.value = this.getAttribute('data-dateoption-default');
|
||||||
|
} else {
|
||||||
|
dateoptionInput.value = this.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($('#acp_help_phpbb')) {
|
||||||
|
phpbb.prepareSendStats();
|
||||||
|
}
|
||||||
|
});
|
||||||
})(jQuery); // Avoid conflicts with other libraries
|
})(jQuery); // Avoid conflicts with other libraries
|
||||||
|
|
|
@ -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,11 +174,12 @@ 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;
|
||||||
|
|
||||||
var old_tab = document.getElementById('tab' + active_option);
|
var old_tab = document.getElementById('tab' + active_option);
|
||||||
var new_tab = document.getElementById('tab' + id);
|
var new_tab = document.getElementById('tab' + id);
|
||||||
var adv_block = document.getElementById('advanced' + pmask + fmask);
|
var adv_block = document.getElementById('advanced' + pmask + fmask);
|
||||||
|
|
||||||
|
@ -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,7 +332,9 @@ 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) {
|
||||||
mark_one_option(target_id, r, (settings[r] === 1) ? 'y' : 'n');
|
if (Object.prototype.hasOwnProperty.call(settings, r)) {
|
||||||
|
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;
|
||||||
}, {}));
|
}, {}));
|
||||||
|
|
|
@ -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,213 +14,209 @@ 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
|
||||||
|
* @param {string} id ID tag of select
|
||||||
|
* @param {string} headline Text that should appear on top of tooltip
|
||||||
|
* @param {string} [subId] Sub ID that should only be using tooltips (optional)
|
||||||
|
*/
|
||||||
|
phpbb.enableTooltipsSelect = function(id, headline, subId) {
|
||||||
|
var $links;
|
||||||
|
|
||||||
/**
|
var hold = $('<span />', {
|
||||||
* Enable tooltip replacements for selects
|
id: '_tooltip_container',
|
||||||
* @param {string} id ID tag of select
|
css: {
|
||||||
* @param {string} headline Text that should appear on top of tooltip
|
position: 'absolute',
|
||||||
* @param {string} [subId] Sub ID that should only be using tooltips (optional)
|
},
|
||||||
*/
|
});
|
||||||
phpbb.enableTooltipsSelect = function (id, headline, subId) {
|
|
||||||
var $links, hold;
|
|
||||||
|
|
||||||
hold = $('<span />', {
|
$('body').append(hold);
|
||||||
id: '_tooltip_container',
|
|
||||||
css: {
|
if (id) {
|
||||||
position: 'absolute'
|
$links = $('.roles-options li', '#' + id);
|
||||||
|
} else {
|
||||||
|
$links = $('.roles-options li');
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
$('body').append(hold);
|
$links.each(function() {
|
||||||
|
var $this = $(this);
|
||||||
|
|
||||||
if (!id) {
|
if (subId) {
|
||||||
$links = $('.roles-options li');
|
if ($this.parent().attr('id').substr(0, subId.length) === subId) {
|
||||||
} else {
|
phpbb.prepareTooltips($this, headline);
|
||||||
$links = $('.roles-options li', '#' + id);
|
}
|
||||||
}
|
} else {
|
||||||
|
|
||||||
$links.each(function () {
|
|
||||||
var $this = $(this);
|
|
||||||
|
|
||||||
if (subId) {
|
|
||||||
if ($this.parent().attr('id').substr(0, subId.length) === subId) {
|
|
||||||
phpbb.prepareTooltips($this, headline);
|
phpbb.prepareTooltips($this, headline);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare elements to replace
|
||||||
|
*
|
||||||
|
* @param {jQuery} $element Element to prepare for tooltips
|
||||||
|
* @param {string} headText Text heading to display
|
||||||
|
*/
|
||||||
|
phpbb.prepareTooltips = function($element, headText) {
|
||||||
|
var text = $element.attr('data-title');
|
||||||
|
|
||||||
|
if (text === null || text.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var $title = $('<span />', {
|
||||||
|
class: 'top',
|
||||||
|
css: {
|
||||||
|
display: 'block',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.append(document.createTextNode(headText));
|
||||||
|
|
||||||
|
var $desc = $('<span />', {
|
||||||
|
class: 'bottom',
|
||||||
|
html: text,
|
||||||
|
css: {
|
||||||
|
display: 'block',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
var $tooltip = $('<span />', {
|
||||||
|
class: 'tooltip',
|
||||||
|
css: {
|
||||||
|
display: 'block',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.append($title)
|
||||||
|
.append($desc);
|
||||||
|
|
||||||
|
tooltips[$element.attr('data-id')] = $tooltip;
|
||||||
|
$element.on('mouseover', phpbb.showTooltip);
|
||||||
|
$element.on('mouseout', phpbb.hideTooltip);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show tooltip
|
||||||
|
*
|
||||||
|
* @param {object} $element Element passed by .on()
|
||||||
|
*/
|
||||||
|
phpbb.showTooltip = function($element) {
|
||||||
|
var $this = $($element.target);
|
||||||
|
$('#_tooltip_container').append(tooltips[$this.attr('data-id')]);
|
||||||
|
phpbb.positionTooltip($this);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide tooltip
|
||||||
|
*/
|
||||||
|
phpbb.hideTooltip = function() {
|
||||||
|
var d = document.getElementById('_tooltip_container');
|
||||||
|
if (d.childNodes.length > 0) {
|
||||||
|
d.removeChild(d.firstChild);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Correct positioning of tooltip container
|
||||||
|
*
|
||||||
|
* @param {jQuery} $element Tooltip element that should be positioned
|
||||||
|
*/
|
||||||
|
phpbb.positionTooltip = function($element) {
|
||||||
|
$element = $element.parent();
|
||||||
|
var offset = $element.offset();
|
||||||
|
|
||||||
|
if ($('body').hasClass('rtl')) {
|
||||||
|
$('#_tooltip_container').css({
|
||||||
|
top: offset.top + 30,
|
||||||
|
left: offset.left + 255,
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
phpbb.prepareTooltips($this, headline);
|
$('#_tooltip_container').css({
|
||||||
}
|
top: offset.top + 30,
|
||||||
});
|
left: offset.left - 205,
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prepare elements to replace
|
|
||||||
*
|
|
||||||
* @param {jQuery} $element Element to prepare for tooltips
|
|
||||||
* @param {string} headText Text heading to display
|
|
||||||
*/
|
|
||||||
phpbb.prepareTooltips = function ($element, headText) {
|
|
||||||
var $tooltip, text, $desc, $title;
|
|
||||||
|
|
||||||
text = $element.attr('data-title');
|
|
||||||
|
|
||||||
if (text === null || text.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$title = $('<span />', {
|
|
||||||
class: 'top',
|
|
||||||
css: {
|
|
||||||
display: 'block'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.append(document.createTextNode(headText));
|
|
||||||
|
|
||||||
$desc = $('<span />', {
|
|
||||||
class: 'bottom',
|
|
||||||
html: text,
|
|
||||||
css: {
|
|
||||||
display: 'block'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$tooltip = $('<span />', {
|
|
||||||
class: 'tooltip',
|
|
||||||
css: {
|
|
||||||
display: 'block'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.append($title)
|
|
||||||
.append($desc);
|
|
||||||
|
|
||||||
tooltips[$element.attr('data-id')] = $tooltip;
|
|
||||||
$element.on('mouseover', phpbb.showTooltip);
|
|
||||||
$element.on('mouseout', phpbb.hideTooltip);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show tooltip
|
|
||||||
*
|
|
||||||
* @param {object} $element Element passed by .on()
|
|
||||||
*/
|
|
||||||
phpbb.showTooltip = function ($element) {
|
|
||||||
var $this = $($element.target);
|
|
||||||
$('#_tooltip_container').append(tooltips[$this.attr('data-id')]);
|
|
||||||
phpbb.positionTooltip($this);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hide tooltip
|
|
||||||
*/
|
|
||||||
phpbb.hideTooltip = function () {
|
|
||||||
var d = document.getElementById('_tooltip_container');
|
|
||||||
if (d.childNodes.length > 0) {
|
|
||||||
d.removeChild(d.firstChild);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Correct positioning of tooltip container
|
|
||||||
*
|
|
||||||
* @param {jQuery} $element Tooltip element that should be positioned
|
|
||||||
*/
|
|
||||||
phpbb.positionTooltip = function ($element) {
|
|
||||||
var offset;
|
|
||||||
|
|
||||||
$element = $element.parent();
|
|
||||||
offset = $element.offset();
|
|
||||||
|
|
||||||
if ($('body').hasClass('rtl')) {
|
|
||||||
$('#_tooltip_container').css({
|
|
||||||
top: offset.top + 30,
|
|
||||||
left: offset.left + 255
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
$('#_tooltip_container').css({
|
|
||||||
top: offset.top + 30,
|
|
||||||
left: offset.left - 205
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prepare roles drop down select
|
|
||||||
*/
|
|
||||||
phpbb.prepareRolesDropdown = function () {
|
|
||||||
var $options = $('.roles-options li');
|
|
||||||
|
|
||||||
// Display span and hide select
|
|
||||||
$('.roles-options > span').css('display', 'block');
|
|
||||||
$('.roles-options > select').hide();
|
|
||||||
$('.roles-options > input[type=hidden]').each(function () {
|
|
||||||
var $this = $(this);
|
|
||||||
|
|
||||||
if ($this.attr('data-name') && !$this.attr('name')) {
|
|
||||||
$this.attr('name', $this.attr('data-name'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Prepare highlighting of select options and settings update
|
|
||||||
$options.each(function () {
|
|
||||||
var $this = $(this);
|
|
||||||
var $rolesOptions = $this.closest('.roles-options');
|
|
||||||
var $span = $rolesOptions.children('span');
|
|
||||||
|
|
||||||
// Correctly show selected option
|
|
||||||
if (typeof $this.attr('data-selected') !== 'undefined') {
|
|
||||||
$rolesOptions
|
|
||||||
.children('span')
|
|
||||||
.text($this.text())
|
|
||||||
.attr('data-default', $this.text())
|
|
||||||
.attr('data-default-val', $this.attr('data-id'));
|
|
||||||
|
|
||||||
// Save default text of drop down if there is no default set yet
|
|
||||||
if (typeof $span.attr('data-default') === 'undefined') {
|
|
||||||
$span.attr('data-default', $span.text());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare resetting drop down on form reset
|
|
||||||
$this.closest('form').on('reset', function () {
|
|
||||||
$span.text($span.attr('data-default'));
|
|
||||||
$rolesOptions.children('input[type=hidden]')
|
|
||||||
.val($span.attr('data-default-val'));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
$this.on('mouseover', function () {
|
/**
|
||||||
|
* Prepare roles drop down select
|
||||||
|
*/
|
||||||
|
phpbb.prepareRolesDropdown = function() {
|
||||||
|
var $options = $('.roles-options li');
|
||||||
|
|
||||||
|
// Display span and hide select
|
||||||
|
$('.roles-options > span').css('display', 'block');
|
||||||
|
$('.roles-options > select').hide();
|
||||||
|
$('.roles-options > input[type=hidden]').each(function() {
|
||||||
var $this = $(this);
|
var $this = $(this);
|
||||||
$options.removeClass('roles-highlight');
|
|
||||||
$this.addClass('roles-highlight');
|
if ($this.attr('data-name') && !$this.attr('name')) {
|
||||||
}).on('click', function () {
|
$this.attr('name', $this.attr('data-name'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Prepare highlighting of select options and settings update
|
||||||
|
$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');
|
||||||
|
|
||||||
// Update settings
|
// Correctly show selected option
|
||||||
set_role_settings($this.attr('data-id'), $this.attr('data-target-id'));
|
if (typeof $this.attr('data-selected') !== 'undefined') {
|
||||||
init_colours($this.attr('data-target-id').replace('advanced', ''));
|
$rolesOptions
|
||||||
|
.children('span')
|
||||||
|
.text($this.text())
|
||||||
|
.attr('data-default', $this.text())
|
||||||
|
.attr('data-default-val', $this.attr('data-id'));
|
||||||
|
|
||||||
// Set selected setting
|
// Save default text of drop down if there is no default set yet
|
||||||
$rolesOptions.children('span')
|
if (typeof $span.attr('data-default') === 'undefined') {
|
||||||
.text($this.text());
|
$span.attr('data-default', $span.text());
|
||||||
$rolesOptions.children('input[type=hidden]')
|
}
|
||||||
.val($this.attr('data-id'));
|
|
||||||
|
|
||||||
// Trigger hiding of selection options
|
// Prepare resetting drop down on form reset
|
||||||
$('body').trigger('click');
|
$this.closest('form').on('reset', () => {
|
||||||
|
$span.text($span.attr('data-default'));
|
||||||
|
$rolesOptions.children('input[type=hidden]')
|
||||||
|
.val($span.attr('data-default-val'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$this.on('mouseover', function() {
|
||||||
|
var $this = $(this);
|
||||||
|
$options.removeClass('roles-highlight');
|
||||||
|
$this.addClass('roles-highlight');
|
||||||
|
}).on('click', function() {
|
||||||
|
var $this = $(this);
|
||||||
|
var $rolesOptions = $this.closest('.roles-options');
|
||||||
|
|
||||||
|
// Update settings
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
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', ''));
|
||||||
|
|
||||||
|
// Set selected setting
|
||||||
|
$rolesOptions.children('span')
|
||||||
|
.text($this.text());
|
||||||
|
$rolesOptions.children('input[type=hidden]')
|
||||||
|
.val($this.attr('data-id'));
|
||||||
|
|
||||||
|
// Trigger hiding of selection options
|
||||||
|
$('body').trigger('click');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Run onload functions for RolesDropdown and tooltips
|
||||||
|
$(() => {
|
||||||
|
// Enable tooltips
|
||||||
|
phpbb.enableTooltipsSelect('set-permissions', $('#set-permissions').attr('data-role-description'), 'role');
|
||||||
|
|
||||||
|
// Prepare dropdown
|
||||||
|
phpbb.prepareRolesDropdown();
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
|
||||||
// Run onload functions for RolesDropdown and tooltips
|
|
||||||
$(function() {
|
|
||||||
// Enable tooltips
|
|
||||||
phpbb.enableTooltipsSelect('set-permissions', $('#set-permissions').attr('data-role-description'), 'role');
|
|
||||||
|
|
||||||
// Prepare dropdown
|
|
||||||
phpbb.prepareRolesDropdown();
|
|
||||||
});
|
|
||||||
|
|
||||||
})(jQuery); // Avoid conflicts with other libraries
|
})(jQuery); // Avoid conflicts with other libraries
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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(/<\;/ig, '<');
|
theSelection = theSelection.replace(/</ig, '<');
|
||||||
theSelection = theSelection.replace(/>\;/ig, '>');
|
theSelection = theSelection.replace(/>/ig, '>');
|
||||||
theSelection = theSelection.replace(/&\;/ig, '&');
|
theSelection = theSelection.replace(/&/ig, '&');
|
||||||
theSelection = theSelection.replace(/ \;/ig, ' ');
|
theSelection = theSelection.replace(/ /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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
} else if (type === 'warning') {
|
||||||
break;
|
$msgElement.addClass('warningbox');
|
||||||
case 'warning':
|
$warningContainer.append($msgElement);
|
||||||
$msgElement.addClass('warningbox');
|
} else if (type === 'log') {
|
||||||
$warningContainer.append($msgElement);
|
$msgElement.addClass('log');
|
||||||
break;
|
$logContainer.prepend($msgElement);
|
||||||
case 'log':
|
$logContainer.addClass('show_log_container');
|
||||||
$msgElement.addClass('log');
|
} else if (type === 'success') {
|
||||||
$logContainer.prepend($msgElement);
|
$msgElement.addClass('successbox');
|
||||||
$logContainer.addClass('show_log_container');
|
$errorContainer.prepend($msgElement);
|
||||||
break;
|
|
||||||
case 'success':
|
|
||||||
$msgElement.addClass('successbox');
|
|
||||||
$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 + '">');
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,427 +1,426 @@
|
||||||
/* 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
|
var readTitle = res.NO_UNREAD_POSTS;
|
||||||
phpbb.addAjaxCallback('mark_forums_read', function(res) {
|
var unreadTitle = res.UNREAD_POSTS;
|
||||||
var readTitle = res.NO_UNREAD_POSTS;
|
var iconsArray = {
|
||||||
var unreadTitle = res.UNREAD_POSTS;
|
forum_unread: 'forum_read',
|
||||||
var iconsArray = {
|
forum_unread_subforum: 'forum_read_subforum',
|
||||||
forum_unread: 'forum_read',
|
forum_unread_locked: 'forum_read_locked',
|
||||||
forum_unread_subforum: 'forum_read_subforum',
|
|
||||||
forum_unread_locked: 'forum_read_locked'
|
|
||||||
};
|
|
||||||
|
|
||||||
$('li.row').find('dl[class*="forum_unread"]').each(function() {
|
|
||||||
var $this = $(this);
|
|
||||||
|
|
||||||
$.each(iconsArray, function(unreadClass, readClass) {
|
|
||||||
if ($this.hasClass(unreadClass)) {
|
|
||||||
$this.removeClass(unreadClass).addClass(readClass);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$this.children('dt[title="' + unreadTitle + '"]').attr('title', readTitle);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Mark subforums read
|
|
||||||
$('a.subforum[class*="unread"]').removeClass('unread').addClass('read').children('.icon.icon-red').removeClass('icon-red').addClass('icon-blue');
|
|
||||||
|
|
||||||
// Mark topics read if we are watching a category and showing active topics
|
|
||||||
if ($('#active_topics').length) {
|
|
||||||
phpbb.ajaxCallbacks.mark_topics_read.call(this, res, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update mark forums read links
|
|
||||||
$('[data-ajax="mark_forums_read"]').attr('href', res.U_MARK_FORUMS);
|
|
||||||
|
|
||||||
phpbb.closeDarkenWrapper(3000);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback will mark all topic icons read
|
|
||||||
*
|
|
||||||
* @param {bool} [update_topic_links=true] Whether "Mark topics read" links
|
|
||||||
* should be updated. Defaults to true.
|
|
||||||
*/
|
|
||||||
phpbb.addAjaxCallback('mark_topics_read', function(res, updateTopicLinks) {
|
|
||||||
var readTitle = res.NO_UNREAD_POSTS;
|
|
||||||
var unreadTitle = res.UNREAD_POSTS;
|
|
||||||
var iconsArray = {
|
|
||||||
global_unread: 'global_read',
|
|
||||||
announce_unread: 'announce_read',
|
|
||||||
sticky_unread: 'sticky_read',
|
|
||||||
topic_unread: 'topic_read'
|
|
||||||
};
|
|
||||||
var iconsState = ['', '_hot', '_hot_mine', '_locked', '_locked_mine', '_mine'];
|
|
||||||
var unreadClassSelectors;
|
|
||||||
var classMap = {};
|
|
||||||
var classNames = [];
|
|
||||||
|
|
||||||
if (typeof updateTopicLinks === 'undefined') {
|
|
||||||
updateTopicLinks = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
$.each(iconsArray, function(unreadClass, readClass) {
|
|
||||||
$.each(iconsState, function(key, value) {
|
|
||||||
// Only topics can be hot
|
|
||||||
if ((value === '_hot' || value === '_hot_mine') && unreadClass !== 'topic_unread') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
classMap[unreadClass + value] = readClass + value;
|
|
||||||
classNames.push(unreadClass + value);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
unreadClassSelectors = '.' + classNames.join(',.');
|
|
||||||
|
|
||||||
$('li.row').find(unreadClassSelectors).each(function() {
|
|
||||||
var $this = $(this);
|
|
||||||
$.each(classMap, function(unreadClass, readClass) {
|
|
||||||
if ($this.hasClass(unreadClass)) {
|
|
||||||
$this.removeClass(unreadClass).addClass(readClass);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$this.children('dt[title="' + unreadTitle + '"]').attr('title', readTitle);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Remove link to first unread post
|
|
||||||
$('a.unread').has('.icon-red').remove();
|
|
||||||
|
|
||||||
// Update mark topics read links
|
|
||||||
if (updateTopicLinks) {
|
|
||||||
$('[data-ajax="mark_topics_read"]').attr('href', res.U_MARK_TOPICS);
|
|
||||||
}
|
|
||||||
|
|
||||||
phpbb.closeDarkenWrapper(3000);
|
|
||||||
});
|
|
||||||
|
|
||||||
// This callback will mark all notifications read
|
|
||||||
phpbb.addAjaxCallback('notification.mark_all_read', function(res) {
|
|
||||||
if (typeof res.success !== 'undefined') {
|
|
||||||
phpbb.markNotifications($('[data-notification-unread="true"]'), 0);
|
|
||||||
phpbb.toggleDropdown.call($('#notification-button'));
|
|
||||||
phpbb.closeDarkenWrapper(3000);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// This callback will mark a notification read
|
|
||||||
phpbb.addAjaxCallback('notification.mark_read', function(res) {
|
|
||||||
if (typeof res.success !== 'undefined') {
|
|
||||||
var unreadCount = Number($('#notification-button strong').html()) - 1;
|
|
||||||
phpbb.markNotifications($(this).parent('[data-notification-unread="true"]'), unreadCount);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mark notification popup rows as read.
|
|
||||||
*
|
|
||||||
* @param {jQuery} $popup jQuery object(s) to mark read.
|
|
||||||
* @param {int} unreadCount The new unread notifications count.
|
|
||||||
*/
|
|
||||||
phpbb.markNotifications = function($popup, unreadCount) {
|
|
||||||
// Remove the unread status.
|
|
||||||
$popup.removeClass('bg2');
|
|
||||||
$popup.find('a.mark_read').remove();
|
|
||||||
|
|
||||||
// Update the notification link to the real URL.
|
|
||||||
$popup.each(function() {
|
|
||||||
var link = $(this).find('a');
|
|
||||||
link.attr('href', link.attr('data-real-url'));
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update the unread count.
|
|
||||||
$('strong', '#notification-button').html(unreadCount);
|
|
||||||
// Remove the Mark all read link and hide notification count if there are no unread notifications.
|
|
||||||
if (!unreadCount) {
|
|
||||||
$('#mark_all_notifications').remove();
|
|
||||||
$('#notification-button > strong').addClass('hidden');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update page title
|
|
||||||
var $title = $('title');
|
|
||||||
var originalTitle = $title.text().replace(/(\((\d+)\))/, '');
|
|
||||||
$title.text((unreadCount ? '(' + unreadCount + ')' : '') + originalTitle);
|
|
||||||
};
|
|
||||||
|
|
||||||
// This callback finds the post from the delete link, and removes it.
|
|
||||||
phpbb.addAjaxCallback('post_delete', function() {
|
|
||||||
var $this = $(this),
|
|
||||||
postId;
|
|
||||||
|
|
||||||
if ($this.attr('data-refresh') === undefined) {
|
|
||||||
postId = $this[0].href.split('&p=')[1];
|
|
||||||
var post = $this.parents('#p' + postId).css('pointer-events', 'none');
|
|
||||||
if (post.hasClass('bg1') || post.hasClass('bg2')) {
|
|
||||||
var posts1 = post.nextAll('.bg1');
|
|
||||||
post.nextAll('.bg2').removeClass('bg2').addClass('bg1');
|
|
||||||
posts1.removeClass('bg1').addClass('bg2');
|
|
||||||
}
|
|
||||||
post.fadeOut(function() {
|
|
||||||
$(this).remove();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// This callback removes the approve / disapprove div or link.
|
|
||||||
phpbb.addAjaxCallback('post_visibility', function(res) {
|
|
||||||
var remove = (res.visible) ? $(this) : $(this).parents('.post');
|
|
||||||
$(remove).css('pointer-events', 'none').fadeOut(function() {
|
|
||||||
$(this).remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (res.visible) {
|
|
||||||
// Remove the "Deleted by" message from the post on restoring.
|
|
||||||
remove.parents('.post').find('.post_deleted_msg').css('pointer-events', 'none').fadeOut(function() {
|
|
||||||
$(this).remove();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// This removes the parent row of the link or form that fired the callback.
|
|
||||||
phpbb.addAjaxCallback('row_delete', function() {
|
|
||||||
$(this).parents('tr').remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
// This handles friend / foe additions removals.
|
|
||||||
phpbb.addAjaxCallback('zebra', function(res) {
|
|
||||||
var zebra;
|
|
||||||
|
|
||||||
if (res.success) {
|
|
||||||
zebra = $('.zebra');
|
|
||||||
zebra.first().html(res.MESSAGE_TEXT);
|
|
||||||
zebra.not(':first').html(' ').prev().html(' ');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback updates the poll results after voting.
|
|
||||||
*/
|
|
||||||
phpbb.addAjaxCallback('vote_poll', function(res) {
|
|
||||||
if (typeof res.success !== 'undefined') {
|
|
||||||
var poll = $(this).closest('.topic_poll');
|
|
||||||
var panel = poll.find('.panel');
|
|
||||||
var resultsVisible = poll.find('dl:first-child .resultbar').is(':visible');
|
|
||||||
var mostVotes = 0;
|
|
||||||
|
|
||||||
// Set min-height to prevent the page from jumping when the content changes
|
|
||||||
var updatePanelHeight = function (height) {
|
|
||||||
height = (typeof height === 'undefined') ? panel.find('.inner').outerHeight() : height;
|
|
||||||
panel.css('min-height', height);
|
|
||||||
};
|
};
|
||||||
updatePanelHeight();
|
|
||||||
|
|
||||||
// Remove the View results link
|
$('li.row').find('dl[class*="forum_unread"]').each(function() {
|
||||||
if (!resultsVisible) {
|
|
||||||
poll.find('.poll_view_results').hide(500);
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
poll.find('.resultbar, .poll_option_percent, .poll_total_votes').show(500);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the votes count of the highest poll option
|
|
||||||
poll.find('[data-poll-option-id]').each(function() {
|
|
||||||
var option = $(this);
|
|
||||||
var optionId = option.attr('data-poll-option-id');
|
|
||||||
mostVotes = (res.vote_counts[optionId] >= mostVotes) ? res.vote_counts[optionId] : mostVotes;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update the total votes count
|
|
||||||
poll.find('.poll_total_vote_cnt').html(res.total_votes);
|
|
||||||
|
|
||||||
// Update each option
|
|
||||||
poll.find('[data-poll-option-id]').each(function() {
|
|
||||||
var $this = $(this);
|
var $this = $(this);
|
||||||
var optionId = $this.attr('data-poll-option-id');
|
|
||||||
var voted = (typeof res.user_votes[optionId] !== 'undefined');
|
|
||||||
var mostVoted = (res.vote_counts[optionId] === mostVotes);
|
|
||||||
var percent = (!res.total_votes) ? 0 : Math.round((res.vote_counts[optionId] / res.total_votes) * 100);
|
|
||||||
var percentRel = (mostVotes === 0) ? 0 : Math.round((res.vote_counts[optionId] / mostVotes) * 100);
|
|
||||||
var altText;
|
|
||||||
|
|
||||||
altText = $this.attr('data-alt-text');
|
$.each(iconsArray, (unreadClass, readClass) => {
|
||||||
if (voted) {
|
if ($this.hasClass(unreadClass)) {
|
||||||
$this.attr('title', $.trim(altText));
|
$this.removeClass(unreadClass).addClass(readClass);
|
||||||
} else {
|
}
|
||||||
$this.attr('title', '');
|
});
|
||||||
};
|
$this.children('dt[title="' + unreadTitle + '"]').attr('title', readTitle);
|
||||||
$this.toggleClass('voted', voted);
|
|
||||||
$this.toggleClass('most-votes', mostVoted);
|
|
||||||
|
|
||||||
// Update the bars
|
|
||||||
var bar = $this.find('.resultbar div');
|
|
||||||
var barTimeLapse = (res.can_vote) ? 500 : 1500;
|
|
||||||
var newBarClass = (percent === 100) ? 'pollbar5' : 'pollbar' + (Math.floor(percent / 20) + 1);
|
|
||||||
|
|
||||||
setTimeout(function () {
|
|
||||||
bar.animate({ width: percentRel + '%' }, 500)
|
|
||||||
.removeClass('pollbar1 pollbar2 pollbar3 pollbar4 pollbar5')
|
|
||||||
.addClass(newBarClass)
|
|
||||||
.html(res.vote_counts[optionId]);
|
|
||||||
|
|
||||||
var percentText = percent ? percent + '%' : res.NO_VOTES;
|
|
||||||
$this.find('.poll_option_percent').html(percentText);
|
|
||||||
}, barTimeLapse);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!res.can_vote) {
|
// Mark subforums read
|
||||||
poll.find('.polls').delay(400).fadeIn(500);
|
$('a.subforum[class*="unread"]').removeClass('unread').addClass('read').children('.icon.icon-red').removeClass('icon-red').addClass('icon-blue');
|
||||||
|
|
||||||
|
// Mark topics read if we are watching a category and showing active topics
|
||||||
|
if ($('#active_topics').length) {
|
||||||
|
phpbb.ajaxCallbacks.mark_topics_read.call(this, res, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display "Your vote has been cast." message. Disappears after 5 seconds.
|
// Update mark forums read links
|
||||||
var confirmationDelay = (res.can_vote) ? 300 : 900;
|
$('[data-ajax="mark_forums_read"]').attr('href', res.U_MARK_FORUMS);
|
||||||
poll.find('.vote-submitted').delay(confirmationDelay).slideDown(200, function() {
|
|
||||||
if (resultsVisible) {
|
|
||||||
updatePanelHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
$(this).delay(5000).fadeOut(500, function() {
|
phpbb.closeDarkenWrapper(3000);
|
||||||
resizePanel(300);
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This callback will mark all topic icons read
|
||||||
|
*
|
||||||
|
* @param {bool} [update_topic_links=true] Whether "Mark topics read" links
|
||||||
|
* should be updated. Defaults to true.
|
||||||
|
*/
|
||||||
|
phpbb.addAjaxCallback('mark_topics_read', (res, updateTopicLinks) => {
|
||||||
|
var readTitle = res.NO_UNREAD_POSTS;
|
||||||
|
var unreadTitle = res.UNREAD_POSTS;
|
||||||
|
var iconsArray = {
|
||||||
|
global_unread: 'global_read',
|
||||||
|
announce_unread: 'announce_read',
|
||||||
|
sticky_unread: 'sticky_read',
|
||||||
|
topic_unread: 'topic_read',
|
||||||
|
};
|
||||||
|
var iconsState = [ '', '_hot', '_hot_mine', '_locked', '_locked_mine', '_mine' ];
|
||||||
|
var classMap = {};
|
||||||
|
var classNames = [];
|
||||||
|
|
||||||
|
if (typeof updateTopicLinks === 'undefined') {
|
||||||
|
updateTopicLinks = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.each(iconsArray, (unreadClass, readClass) => {
|
||||||
|
$.each(iconsState, (key, value) => {
|
||||||
|
// Only topics can be hot
|
||||||
|
if ((value === '_hot' || value === '_hot_mine') && unreadClass !== 'topic_unread') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
classMap[unreadClass + value] = readClass + value;
|
||||||
|
classNames.push(unreadClass + value);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Remove the gap resulting from removing options
|
var unreadClassSelectors = '.' + classNames.join(',.');
|
||||||
setTimeout(function() {
|
|
||||||
resizePanel(500);
|
|
||||||
}, 1500);
|
|
||||||
|
|
||||||
var resizePanel = function (time) {
|
$('li.row').find(unreadClassSelectors).each(function() {
|
||||||
var panelHeight = panel.height();
|
var $this = $(this);
|
||||||
var innerHeight = panel.find('.inner').outerHeight();
|
$.each(classMap, (unreadClass, readClass) => {
|
||||||
|
if ($this.hasClass(unreadClass)) {
|
||||||
if (panelHeight !== innerHeight) {
|
$this.removeClass(unreadClass).addClass(readClass);
|
||||||
panel.css({ minHeight: '', height: panelHeight })
|
}
|
||||||
.animate({ height: innerHeight }, time, function () {
|
});
|
||||||
panel.css({ minHeight: innerHeight, height: '' });
|
$this.children('dt[title="' + unreadTitle + '"]').attr('title', readTitle);
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show poll results when clicking View results link.
|
|
||||||
*/
|
|
||||||
$('.poll_view_results a').click(function(e) {
|
|
||||||
// Do not follow the link
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
var $poll = $(this).parents('.topic_poll');
|
|
||||||
|
|
||||||
$poll.find('.resultbar, .poll_option_percent, .poll_total_votes').show(500);
|
|
||||||
$poll.find('.poll_view_results').hide(500);
|
|
||||||
});
|
|
||||||
|
|
||||||
$('[data-ajax]').each(function() {
|
|
||||||
var $this = $(this);
|
|
||||||
var ajax = $this.attr('data-ajax');
|
|
||||||
var filter = $this.attr('data-filter');
|
|
||||||
|
|
||||||
if (ajax !== 'false') {
|
|
||||||
var fn = (ajax !== 'true') ? ajax : null;
|
|
||||||
filter = (filter !== undefined) ? phpbb.getFunctionByName(filter) : null;
|
|
||||||
|
|
||||||
phpbb.ajaxify({
|
|
||||||
selector: this,
|
|
||||||
refresh: $this.attr('data-refresh') !== undefined,
|
|
||||||
filter: filter,
|
|
||||||
callback: fn
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
// Remove link to first unread post
|
||||||
* This simply appends #preview to the action of the
|
$('a.unread').has('.icon-red').remove();
|
||||||
* QR action when you click the Full Editor & Preview button
|
|
||||||
*/
|
// Update mark topics read links
|
||||||
$('#qr_full_editor').click(function() {
|
if (updateTopicLinks) {
|
||||||
$('#qr_postform').attr('action', function(i, val) {
|
$('[data-ajax="mark_topics_read"]').attr('href', res.U_MARK_TOPICS);
|
||||||
return val + '#preview';
|
}
|
||||||
|
|
||||||
|
phpbb.closeDarkenWrapper(3000);
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
|
// This callback will mark all notifications read
|
||||||
/**
|
phpbb.addAjaxCallback('notification.mark_all_read', res => {
|
||||||
* Make the display post links to use JS
|
if (typeof res.success !== 'undefined') {
|
||||||
*/
|
phpbb.markNotifications($('[data-notification-unread="true"]'), 0);
|
||||||
$('.display_post').click(function(e) {
|
phpbb.toggleDropdown.call($('#notification-button'));
|
||||||
// Do not follow the link
|
phpbb.closeDarkenWrapper(3000);
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
var postId = $(this).attr('data-post-id');
|
|
||||||
$('#post_content' + postId).show();
|
|
||||||
$('#profile' + postId).show();
|
|
||||||
$('#post_hidden' + postId).hide();
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display hidden post on post review page
|
|
||||||
*/
|
|
||||||
$('.display_post_review').on('click', function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
let $displayPostLink = $(this);
|
|
||||||
$displayPostLink.closest('.post-ignore').removeClass('post-ignore');
|
|
||||||
$displayPostLink.hide();
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Toggle the member search panel in memberlist.php.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
* appropriately changed based on the status of the search panel.
|
|
||||||
*/
|
|
||||||
$('#member_search').click(function () {
|
|
||||||
var $memberlistSearch = $('#memberlist_search');
|
|
||||||
|
|
||||||
$memberlistSearch.slideToggle('fast');
|
|
||||||
phpbb.ajaxCallbacks.alt_text.call(this);
|
|
||||||
|
|
||||||
// Focus on the username textbox if it's available and displayed
|
|
||||||
if ($memberlistSearch.is(':visible')) {
|
|
||||||
$('#username').focus();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show to top button if available on page
|
|
||||||
*/
|
|
||||||
const $scrollTopButton = $('.to-top-button');
|
|
||||||
|
|
||||||
if ($scrollTopButton.length) {
|
|
||||||
// Show or hide the button based on scroll position
|
|
||||||
$(window).scroll(function () {
|
|
||||||
if ($(this).scrollTop() > 300) {
|
|
||||||
$scrollTopButton.fadeIn(); // Fade in the button
|
|
||||||
} else {
|
|
||||||
$scrollTopButton.fadeOut(); // Fade out the button
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Scroll smoothly to the top when the button is clicked
|
// This callback will mark a notification read
|
||||||
$scrollTopButton.click(function (e) {
|
phpbb.addAjaxCallback('notification.mark_read', function(res) {
|
||||||
e.preventDefault(); // Prevent the default anchor link behavior
|
if (typeof res.success !== 'undefined') {
|
||||||
$('html, body').animate({scrollTop: 0}, 500); // Smooth scroll to top
|
var unreadCount = Number($('#notification-button strong').html()) - 1;
|
||||||
|
phpbb.markNotifications($(this).parent('[data-notification-unread="true"]'), unreadCount);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Automatically resize textarea
|
* Mark notification popup rows as read.
|
||||||
*/
|
*
|
||||||
$(function() {
|
* @param {jQuery} $popup jQuery object(s) to mark read.
|
||||||
var $textarea = $('textarea:not(#message-box textarea, .no-auto-resize)');
|
* @param {int} unreadCount The new unread notifications count.
|
||||||
phpbb.resizeTextArea($textarea, { minHeight: 75, maxHeight: 250 });
|
*/
|
||||||
phpbb.resizeTextArea($('textarea', '#message-box'));
|
phpbb.markNotifications = function($popup, unreadCount) {
|
||||||
});
|
// Remove the unread status.
|
||||||
|
$popup.removeClass('bg2');
|
||||||
|
$popup.find('a.mark_read').remove();
|
||||||
|
|
||||||
|
// Update the notification link to the real URL.
|
||||||
|
$popup.each(function() {
|
||||||
|
var link = $(this).find('a');
|
||||||
|
link.attr('href', link.attr('data-real-url'));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update the unread count.
|
||||||
|
$('strong', '#notification-button').html(unreadCount);
|
||||||
|
// Remove the Mark all read link and hide notification count if there are no unread notifications.
|
||||||
|
if (!unreadCount) {
|
||||||
|
$('#mark_all_notifications').remove();
|
||||||
|
$('#notification-button > strong').addClass('hidden');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update page title
|
||||||
|
var $title = $('title');
|
||||||
|
var originalTitle = $title.text().replace(/(\((\d+)\))/, '');
|
||||||
|
$title.text((unreadCount ? '(' + unreadCount + ')' : '') + originalTitle);
|
||||||
|
};
|
||||||
|
|
||||||
|
// This callback finds the post from the delete link, and removes it.
|
||||||
|
phpbb.addAjaxCallback('post_delete', function() {
|
||||||
|
var $this = $(this);
|
||||||
|
var postId;
|
||||||
|
|
||||||
|
if ($this.attr('data-refresh') === undefined) {
|
||||||
|
postId = $this[0].href.split('&p=')[1];
|
||||||
|
var post = $this.parents('#p' + postId).css('pointer-events', 'none');
|
||||||
|
if (post.hasClass('bg1') || post.hasClass('bg2')) {
|
||||||
|
var posts1 = post.nextAll('.bg1');
|
||||||
|
post.nextAll('.bg2').removeClass('bg2').addClass('bg1');
|
||||||
|
posts1.removeClass('bg1').addClass('bg2');
|
||||||
|
}
|
||||||
|
|
||||||
|
post.fadeOut(function() {
|
||||||
|
$(this).remove();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// This callback removes the approve / disapprove div or link.
|
||||||
|
phpbb.addAjaxCallback('post_visibility', function(res) {
|
||||||
|
var remove = (res.visible) ? $(this) : $(this).parents('.post');
|
||||||
|
$(remove).css('pointer-events', 'none').fadeOut(function() {
|
||||||
|
$(this).remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res.visible) {
|
||||||
|
// Remove the "Deleted by" message from the post on restoring.
|
||||||
|
remove.parents('.post').find('.post_deleted_msg').css('pointer-events', 'none').fadeOut(function() {
|
||||||
|
$(this).remove();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// This removes the parent row of the link or form that fired the callback.
|
||||||
|
phpbb.addAjaxCallback('row_delete', function() {
|
||||||
|
$(this).parents('tr').remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
// This handles friend / foe additions removals.
|
||||||
|
phpbb.addAjaxCallback('zebra', res => {
|
||||||
|
var zebra;
|
||||||
|
|
||||||
|
if (res.success) {
|
||||||
|
zebra = $('.zebra');
|
||||||
|
zebra.first().html(res.MESSAGE_TEXT);
|
||||||
|
zebra.not(':first').html(' ').prev().html(' ');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This callback updates the poll results after voting.
|
||||||
|
*/
|
||||||
|
phpbb.addAjaxCallback('vote_poll', function(res) {
|
||||||
|
if (typeof res.success !== 'undefined') {
|
||||||
|
var poll = $(this).closest('.topic_poll');
|
||||||
|
var panel = poll.find('.panel');
|
||||||
|
var resultsVisible = poll.find('dl:first-child .resultbar').is(':visible');
|
||||||
|
var mostVotes = 0;
|
||||||
|
|
||||||
|
// Set min-height to prevent the page from jumping when the content changes
|
||||||
|
var updatePanelHeight = function(height) {
|
||||||
|
height = (typeof height === 'undefined') ? panel.find('.inner').outerHeight() : height;
|
||||||
|
panel.css('min-height', height);
|
||||||
|
};
|
||||||
|
|
||||||
|
updatePanelHeight();
|
||||||
|
|
||||||
|
// Remove the View results link
|
||||||
|
if (!resultsVisible) {
|
||||||
|
poll.find('.poll_view_results').hide(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.can_vote) {
|
||||||
|
// If the user can still vote, simply slide down the results
|
||||||
|
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
|
||||||
|
poll.find('[data-poll-option-id]').each(function() {
|
||||||
|
var option = $(this);
|
||||||
|
var optionId = option.attr('data-poll-option-id');
|
||||||
|
mostVotes = (res.vote_counts[optionId] >= mostVotes) ? res.vote_counts[optionId] : mostVotes;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update the total votes count
|
||||||
|
poll.find('.poll_total_vote_cnt').html(res.total_votes);
|
||||||
|
|
||||||
|
// Update each option
|
||||||
|
poll.find('[data-poll-option-id]').each(function() {
|
||||||
|
var $this = $(this);
|
||||||
|
var optionId = $this.attr('data-poll-option-id');
|
||||||
|
var voted = (typeof res.user_votes[optionId] !== 'undefined');
|
||||||
|
var mostVoted = (res.vote_counts[optionId] === mostVotes);
|
||||||
|
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 altText = $this.attr('data-alt-text');
|
||||||
|
if (voted) {
|
||||||
|
$this.attr('title', $.trim(altText));
|
||||||
|
} else {
|
||||||
|
$this.attr('title', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this.toggleClass('voted', voted);
|
||||||
|
$this.toggleClass('most-votes', mostVoted);
|
||||||
|
|
||||||
|
// Update the bars
|
||||||
|
var bar = $this.find('.resultbar div');
|
||||||
|
var barTimeLapse = (res.can_vote) ? 500 : 1500;
|
||||||
|
var newBarClass = (percent === 100) ? 'pollbar5' : 'pollbar' + (Math.floor(percent / 20) + 1);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
bar.animate({ width: percentRel + '%' }, 500)
|
||||||
|
.removeClass('pollbar1 pollbar2 pollbar3 pollbar4 pollbar5')
|
||||||
|
.addClass(newBarClass)
|
||||||
|
.html(res.vote_counts[optionId]);
|
||||||
|
|
||||||
|
var percentText = percent ? percent + '%' : res.NO_VOTES;
|
||||||
|
$this.find('.poll_option_percent').html(percentText);
|
||||||
|
}, barTimeLapse);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!res.can_vote) {
|
||||||
|
poll.find('.polls').delay(400).fadeIn(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display "Your vote has been cast." message. Disappears after 5 seconds.
|
||||||
|
var confirmationDelay = (res.can_vote) ? 300 : 900;
|
||||||
|
poll.find('.vote-submitted').delay(confirmationDelay).slideDown(200, function() {
|
||||||
|
if (resultsVisible) {
|
||||||
|
updatePanelHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
$(this).delay(5000).fadeOut(500, () => {
|
||||||
|
resizePanel(300);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Remove the gap resulting from removing options
|
||||||
|
setTimeout(() => {
|
||||||
|
resizePanel(500);
|
||||||
|
}, 1500);
|
||||||
|
|
||||||
|
var resizePanel = function(time) {
|
||||||
|
var panelHeight = panel.height();
|
||||||
|
var innerHeight = panel.find('.inner').outerHeight();
|
||||||
|
|
||||||
|
if (panelHeight !== innerHeight) {
|
||||||
|
panel.css({ minHeight: '', height: panelHeight })
|
||||||
|
.animate({ height: innerHeight }, time, () => {
|
||||||
|
panel.css({ minHeight: innerHeight, height: '' });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show poll results when clicking View results link.
|
||||||
|
*/
|
||||||
|
$('.poll_view_results a').click(function(e) {
|
||||||
|
// Do not follow the link
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
var $poll = $(this).parents('.topic_poll');
|
||||||
|
|
||||||
|
$poll.find('.resultbar, .poll_option_percent, .poll_total_votes').show(500);
|
||||||
|
$poll.find('.poll_view_results').hide(500);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('[data-ajax]').each(function() {
|
||||||
|
var $this = $(this);
|
||||||
|
var ajax = $this.attr('data-ajax');
|
||||||
|
var filter = $this.attr('data-filter');
|
||||||
|
|
||||||
|
if (ajax !== 'false') {
|
||||||
|
var fn = ajax === 'true' ? null : ajax;
|
||||||
|
filter = filter === undefined ? null : phpbb.getFunctionByName(filter);
|
||||||
|
|
||||||
|
phpbb.ajaxify({
|
||||||
|
selector: this,
|
||||||
|
refresh: $this.attr('data-refresh') !== undefined,
|
||||||
|
filter,
|
||||||
|
callback: fn,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This simply appends #preview to the action of the
|
||||||
|
* QR action when you click the Full Editor & Preview button
|
||||||
|
*/
|
||||||
|
$('#qr_full_editor').click(() => {
|
||||||
|
$('#qr_postform').attr('action', (i, val) => val + '#preview');
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make the display post links to use JS
|
||||||
|
*/
|
||||||
|
$('.display_post').click(function(e) {
|
||||||
|
// Do not follow the link
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
var postId = $(this).attr('data-post-id');
|
||||||
|
$('#post_content' + postId).show();
|
||||||
|
$('#profile' + postId).show();
|
||||||
|
$('#post_hidden' + postId).hide();
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display hidden post on post review page
|
||||||
|
*/
|
||||||
|
$('.display_post_review').on('click', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const $displayPostLink = $(this);
|
||||||
|
$displayPostLink.closest('.post-ignore').removeClass('post-ignore');
|
||||||
|
$displayPostLink.hide();
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle the member search panel in memberlist.php.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* appropriately changed based on the status of the search panel.
|
||||||
|
*/
|
||||||
|
$('#member_search').click(function() {
|
||||||
|
var $memberlistSearch = $('#memberlist_search');
|
||||||
|
|
||||||
|
$memberlistSearch.slideToggle('fast');
|
||||||
|
phpbb.ajaxCallbacks.alt_text.call(this);
|
||||||
|
|
||||||
|
// Focus on the username textbox if it's available and displayed
|
||||||
|
if ($memberlistSearch.is(':visible')) {
|
||||||
|
$('#username').focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show to top button if available on page
|
||||||
|
*/
|
||||||
|
const $scrollTopButton = $('.to-top-button');
|
||||||
|
|
||||||
|
if ($scrollTopButton.length) {
|
||||||
|
// Show or hide the button based on scroll position
|
||||||
|
$(window).scroll(function() {
|
||||||
|
if ($(this).scrollTop() > 300) {
|
||||||
|
$scrollTopButton.fadeIn(); // Fade in the button
|
||||||
|
} else {
|
||||||
|
$scrollTopButton.fadeOut(); // Fade out the button
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Scroll smoothly to the top when the button is clicked
|
||||||
|
$scrollTopButton.click(e => {
|
||||||
|
e.preventDefault(); // Prevent the default anchor link behavior
|
||||||
|
$('html, body').animate({ scrollTop: 0 }, 500); // Smooth scroll to top
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Automatically resize textarea
|
||||||
|
*/
|
||||||
|
$(() => {
|
||||||
|
var $textarea = $('textarea:not(#message-box textarea, .no-auto-resize)');
|
||||||
|
phpbb.resizeTextArea($textarea, { minHeight: 75, maxHeight: 250 });
|
||||||
|
phpbb.resizeTextArea($('textarea', '#message-box'));
|
||||||
|
});
|
||||||
})(jQuery); // Avoid conflicts with other libraries
|
})(jQuery); // Avoid conflicts with other libraries
|
||||||
|
|
|
@ -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');
|
});
|
||||||
}),
|
var showPanel = this.getAttribute('data-show-panel');
|
||||||
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 + ' ';
|
e.innerHTML += ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
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"> </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"> </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
|
||||||
|
|
Loading…
Add table
Reference in a new issue