Commit e85c0b27 authored by Andreas Fernandez's avatar Andreas Fernandez Committed by Benni Mack
Browse files

[TASK] Remove jQuery from Permissions module

The Permissions backend module and its JavaScript module now ditch jQuery
in favor of native browser API and TYPO3 API.

The JavaScript has been refactored a little bit; initially checking the
permission checkboxes or writing back the calculcated permission value
is now decoupled and executed in the Permission module only.

To support for..of with NodeList collections, TypeScript now loads the
internal "dom.iterable" library.

Additionally, the interim solution to add `editform` to Document has
been removed which made another change in LinkPopup necessary.

Furthermore, a bug has been fixed, where the value of the first
visible select element was used when saving any other select element
with a completely different value.

Resolves: #93301
Releases: master
Change-Id: Iffede862a0eb36e805a5f127d7b19f32c899ce31
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/67457


Tested-by: Oliver Bartsch's avatarOliver Bartsch <bo@cedev.de>
Tested-by: default avatarTYPO3com <noreply@typo3.com>
Tested-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Reviewed-by: Oliver Bartsch's avatarOliver Bartsch <bo@cedev.de>
Reviewed-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
parent af8635db
......@@ -36,7 +36,7 @@ class LinkPopup {
const itemName = this.controlElement.dataset.itemName;
const url = this.controlElement.getAttribute('href')
+ '&P[currentValue]=' + encodeURIComponent(document.editform[itemName].value)
+ '&P[currentValue]=' + encodeURIComponent(document.forms.namedItem('editform')[itemName].value)
+ '&P[currentSelectedValues]=' + encodeURIComponent(FormEngine.getFieldElement(itemName).val());
Modal.advanced({
......
......@@ -11,13 +11,10 @@
* The TYPO3 project - inspiring people to share!
*/
import $ from 'jquery';
import {AjaxResponse} from 'TYPO3/CMS/Core/Ajax/AjaxResponse';
import RegularEvent from 'TYPO3/CMS/Core/Event/RegularEvent';
import AjaxRequest = require('TYPO3/CMS/Core/Ajax/AjaxRequest');
declare global {
interface Document { editform: any; }
}
import Tooltip = require('TYPO3/CMS/Backend/Tooltip');
/**
* Module: TYPO3/CMS/Beuser/Permissions
......@@ -31,88 +28,149 @@ class Permissions {
private ajaxUrl: string = TYPO3.settings.ajaxUrls.user_access_permissions;
constructor() {
this.initializeEvents();
/**
* Owner-related: Update the HTML view and show the original owner
*/
private static restoreOwner(element: HTMLElement): void {
let page = element.dataset.page;
let username = element.dataset.username;
let usernameHtml = username;
if (typeof username === 'undefined') {
username = '[not set]';
usernameHtml = `<span class="not_set">${username}</span>`;
}
let span = document.createElement('span');
span.id = `o_${page}`;
let aSelector = document.createElement('a');
aSelector.classList.add('ug_selector', 'changeowner');
aSelector.setAttribute('data-page', page);
aSelector.setAttribute('data-owner', element.dataset.owner);
aSelector.setAttribute('data-username', username);
aSelector.innerHTML = usernameHtml;
span.appendChild(aSelector);
// Replace content
const container = document.getElementById('o_' + page);
while (container.firstChild) {
container.firstChild.remove();
}
container.appendChild(span);
}
/**
* Group-related: Update the HTML view and show the original group
*/
private static restoreGroup(element: HTMLElement): void {
let page = element.dataset.page;
let groupname = element.dataset.groupname;
let groupnameHtml = groupname;
if (typeof groupname === 'undefined') {
groupname = '[not set]';
groupnameHtml = `<span class="not_set">${groupname}</span>`;
}
let span = document.createElement('span');
span.id = `g_${page}`;
let aSelector = document.createElement('a');
aSelector.classList.add('ug_selector', 'changegroup');
aSelector.setAttribute('data-page', page);
aSelector.setAttribute('data-group-id', element.dataset.groupId);
aSelector.setAttribute('data-groupname', groupname);
aSelector.innerHTML = groupnameHtml;
span.appendChild(aSelector);
// Replace content
const container = document.getElementById('g_' + page);
while (container.firstChild) {
container.firstChild.remove();
}
container.appendChild(span);
}
/**
* Changes the value of the permissions in the form
*/
public setCheck(checknames: string, varname: string): void {
if (document.editform[varname]) {
let res = document.editform[varname].value;
for (let a = 1; a <= 5; a++) {
document.editform[checknames + '[' + a + ']'].checked = (res & Math.pow(2, a - 1));
}
private static setPermissionCheckboxes(checknames: string, permissionValue: number): void {
const permissionCheckboxes: NodeListOf<HTMLInputElement> = document.querySelectorAll(`input[type="checkbox"][name^="${checknames}"]`);
for (let permissionCheckbox of permissionCheckboxes) {
const value = parseInt(permissionCheckbox.value, 10);
permissionCheckbox.checked = (permissionValue & value) === value;
}
}
/**
* checks for a change of the permissions in the form
*/
public checkChange(checknames: string, varname: string): void {
let res = 0;
for (let a = 1; a <= 5; a++) {
if (document.editform[checknames + '[' + a + ']'].checked) {
res |= Math.pow(2, a - 1);
}
private static updatePermissionValue(checknames: string, varname: string): void {
let permissionValue = 0;
const checkedPermissionCheckboxes: NodeListOf<HTMLInputElement> = document.querySelectorAll(`input[type="checkbox"][name^="${checknames}"]:checked`);
for (let permissionCheckbox of checkedPermissionCheckboxes) {
permissionValue |= parseInt(permissionCheckbox.value, 10);
}
document.editform[varname].value = res | (checknames === 'tx_beuser_system_beusertxpermission[check][perms_user]' ? 1 : 0);
this.setCheck(checknames, varname);
document.forms.namedItem('editform')[varname].value = permissionValue | (checknames === 'tx_beuser_system_beusertxpermission[check][perms_user]' ? 1 : 0);
}
constructor() {
this.initializeCheckboxGroups();
this.initializeEvents();
}
/**
* Changes permissions by sending an AJAX request to the server
*/
public setPermissions($element: JQuery): void {
let page = $element.data('page');
let who = $element.data('who');
let elementSelector = '#' + page + '_' + who;
private setPermissions(element: HTMLElement): void {
let page = element.dataset.page;
let who = element.dataset.who;
(new AjaxRequest(this.ajaxUrl)).post({
page: page,
who: who,
permissions: $element.data('permissions'),
mode: $element.data('mode'),
bits: $element.data('bits'),
permissions: element.dataset.permissions,
mode: element.dataset.mode,
bits: element.dataset.bits,
}).then(async (response: AjaxResponse): Promise<void> => {
const data = await response.resolve();
const element = document.getElementById(page + '_' + who);
// Replace content
$(elementSelector).replaceWith(data);
element.outerHTML = data;
// Reinitialize tooltip
$(elementSelector).find('button').tooltip();
Tooltip.initialize('[data-bs-toggle="tooltip"]');
});
}
/**
* changes the flag to lock the editing on a page by sending an AJAX request
*/
public toggleEditLock($element: JQuery): void {
let page = $element.data('page');
private toggleEditLock(element: HTMLElement): void {
let page = element.dataset.page;
(new AjaxRequest(this.ajaxUrl)).post({
action: 'toggle_edit_lock',
page: page,
editLockState: $element.data('lockstate'),
editLockState: element.dataset.lockstate,
}).then(async (response: AjaxResponse): Promise<void> => {
// Replace content
$('#el_' + page).replaceWith(await response.resolve());
document.getElementById('el_' + page).outerHTML = await response.resolve();
});
}
/**
* Owner-related: Set the new owner of a page by executing an ajax call
*/
public changeOwner($element: JQuery): void {
let page = $element.data('page');
private changeOwner(element: HTMLElement): void {
let page = element.dataset.page;
const container: HTMLElement = document.getElementById('o_' + page);
(new AjaxRequest(this.ajaxUrl)).post({
action: 'change_owner',
page: page,
ownerUid: $element.data('owner'),
newOwnerUid: $('#new_page_owner').val(),
ownerUid: element.dataset.owner,
newOwnerUid: (container.getElementsByTagName('select')[0] as HTMLSelectElement).value,
}).then(async (response: AjaxResponse): Promise<void> => {
// Replace content
$('#o_' + page).replaceWith(await response.resolve());
container.outerHTML = await response.resolve();
});
}
......@@ -120,166 +178,128 @@ class Permissions {
* Owner-related: load the selector for selecting
* the owner of a page by executing an ajax call
*/
public showChangeOwnerSelector($element: JQuery): void {
let page = $element.data('page');
private showChangeOwnerSelector(element: HTMLElement): void {
let page = element.dataset.page;
(new AjaxRequest(this.ajaxUrl)).post({
action: 'show_change_owner_selector',
page: page,
ownerUid: $element.data('owner'),
username: $element.data('username'),
ownerUid: element.dataset.owner,
username: element.dataset.username,
}).then(async (response: AjaxResponse): Promise<void> => {
// Replace content
$('#o_' + page).replaceWith(await response.resolve());
document.getElementById('o_' + page).outerHTML = await response.resolve();
});
}
/**
* Owner-related: Update the HTML view and show the original owner
*/
public restoreOwner($element: JQuery): void {
let page = $element.data('page');
let username = $element.data('username');
let usernameHtml = username;
if (typeof username === 'undefined') {
username = $('<span>', {
'class': 'not_set',
'text': '[not set]',
});
usernameHtml = username.html();
username = username.text();
}
let html = $('<span/>', {
'id': 'o_' + page,
});
let aSelector = $('<a/>', {
'class': 'ug_selector changeowner',
'data-page': page,
'data-owner': $element.data('owner'),
'data-username': usernameHtml,
'text': username,
});
html.append(aSelector);
// Replace content
$('#o_' + page).replaceWith(html);
}
/**
* Group-related: Set the new group by executing an ajax call
*/
public changeGroup($element: JQuery): void {
let page = $element.data('page');
private changeGroup(element: HTMLElement): void {
let page = element.dataset.page;
const container: HTMLElement = document.getElementById('g_' + page);
(new AjaxRequest(this.ajaxUrl)).post({
action: 'change_group',
page: page,
groupUid: $element.data('groupId'),
newGroupUid: $('#new_page_group').val(),
groupUid: element.dataset.groupId,
newGroupUid: (container.getElementsByTagName('select')[0] as HTMLSelectElement).value,
}).then(async (response: AjaxResponse): Promise<void> => {
// Replace content
$('#g_' + page).replaceWith(await response.resolve());
container.outerHTML = await response.resolve();
});
}
/**
* Group-related: Load the selector by executing an ajax call
*/
public showChangeGroupSelector($element: JQuery): void {
let page = $element.data('page');
private showChangeGroupSelector(element: HTMLElement): void {
let page = element.dataset.page;
(new AjaxRequest(this.ajaxUrl)).post({
action: 'show_change_group_selector',
page: page,
groupUid: $element.data('groupId'),
groupname: $element.data('groupname'),
groupUid: element.dataset.groupId,
groupname: element.dataset.groupname,
}).then(async (response: AjaxResponse): Promise<void> => {
// Replace content
$('#g_' + page).replaceWith(await response.resolve());
document.getElementById('g_' + page).outerHTML = await response.resolve();
});
}
/**
* Group-related: Update the HTML view and show the original group
*/
public restoreGroup($element: JQuery): void {
let page = $element.data('page');
let groupname = $element.data('groupname');
let groupnameHtml = groupname;
if (typeof groupname === 'undefined') {
groupname = $('<span>', {
'class': 'not_set',
'text': '[not set]',
});
groupnameHtml = groupname.html();
groupname = groupname.text();
}
let html = $('<span/>', {
'id': 'g_' + page,
private initializeCheckboxGroups(): void {
const checkboxGroups: NodeListOf<HTMLInputElement> = document.querySelectorAll('[data-checkbox-group]');
checkboxGroups.forEach((checkboxGroupCheckbox): void => {
const permissionGroup = checkboxGroupCheckbox.dataset.checkboxGroup;
const permissionValue = parseInt(checkboxGroupCheckbox.value, 10);
Permissions.setPermissionCheckboxes(permissionGroup, permissionValue);
});
let aSelector = $('<a/>', {
'class': 'ug_selector changegroup',
'data-page': page,
'data-group': $element.data('groupId'),
'data-groupname': groupnameHtml,
'text': groupname,
});
html.append(aSelector);
// Replace content
$('#g_' + page).replaceWith(html);
}
/**
* initializes events using deferred bound to document
* so AJAX reloads are no problem
*/
public initializeEvents(): void {
// Click events to change permissions (in template Index.html)
$(this.options.containerSelector).on('click', '.change-permission', (evt: JQueryEventObject): void => {
evt.preventDefault();
this.setPermissions($(evt.currentTarget));
}).on('click', '.editlock', (evt: JQueryEventObject): void => {
private initializeEvents(): void {
const containerSelector = document.querySelector(this.options.containerSelector);
const editControllerSelector = document.querySelector(this.options.editControllerSelector);
if (containerSelector !== null) {
new RegularEvent('click', (e: Event, currentTarget: Element): void => {
e.preventDefault();
this.setPermissions(currentTarget as HTMLElement);
}).delegateTo(containerSelector, '.change-permission');
// Click event for lock state
evt.preventDefault();
this.toggleEditLock($(evt.currentTarget));
}).on('click', '.changeowner', (evt: JQueryEventObject): void => {
new RegularEvent('click', (e: Event, currentTarget: Element): void => {
e.preventDefault();
this.toggleEditLock(currentTarget as HTMLElement);
}).delegateTo(containerSelector, '.editlock');
// Click event to change owner
evt.preventDefault();
this.showChangeOwnerSelector($(evt.currentTarget));
}).on('click', '.changegroup', (evt: JQueryEventObject): void => {
// click event to change group
evt.preventDefault();
this.showChangeGroupSelector($(evt.currentTarget));
}).on('click', '.restoreowner', (evt: JQueryEventObject): void => {
new RegularEvent('click', (e: Event, currentTarget: Element): void => {
e.preventDefault();
this.showChangeOwnerSelector(currentTarget as HTMLElement);
}).delegateTo(containerSelector, '.changeowner');
// Click event to change group
new RegularEvent('click', (e: Event, currentTarget: Element): void => {
e.preventDefault();
this.showChangeGroupSelector(currentTarget as HTMLElement);
}).delegateTo(containerSelector, '.changegroup');
// Add click handler for restoring previous owner
evt.preventDefault();
this.restoreOwner($(evt.currentTarget));
}).on('click', '.saveowner', (evt: JQueryEventObject): void => {
new RegularEvent('click', (e: Event, currentTarget: Element): void => {
e.preventDefault();
Permissions.restoreOwner(currentTarget as HTMLElement);
}).delegateTo(containerSelector, '.restoreowner');
// Add click handler for saving owner
evt.preventDefault();
this.changeOwner($(evt.currentTarget));
}).on('click', '.restoregroup', (evt: JQueryEventObject): void => {
new RegularEvent('click', (e: Event, currentTarget: Element): void => {
e.preventDefault();
this.changeOwner(currentTarget as HTMLElement);
}).delegateTo(containerSelector, '.saveowner');
// Add click handler for restoring previous group
evt.preventDefault();
this.restoreGroup($(evt.currentTarget));
}).on('click', '.savegroup', (evt: JQueryEventObject): void => {
new RegularEvent('click', (e: Event, currentTarget: Element): void => {
e.preventDefault();
Permissions.restoreGroup(currentTarget as HTMLElement);
}).delegateTo(containerSelector, '.restoregroup');
// Add click handler for saving group
evt.preventDefault();
this.changeGroup($(evt.currentTarget));
});
// Click events to change permissions (in template Edit.html)
$(this.options.editControllerSelector).on('click', '[data-check-change-permissions]', (evt: JQueryEventObject): void => {
const $target: JQuery = $(evt.currentTarget);
const args = $target.data('checkChangePermissions').split(',').map((item: string) => item.trim());
this.checkChange.apply(this, args);
});
new RegularEvent('click', (e: Event, currentTarget: Element): void => {
e.preventDefault();
this.changeGroup(currentTarget as HTMLElement);
}).delegateTo(containerSelector, '.savegroup');
}
if (editControllerSelector !== null) {
// Click events to change permissions (in template Edit.html)
new RegularEvent('click', (e: Event, currentTarget: Element): void => {
const args = (currentTarget as HTMLElement).dataset.checkChangePermissions.split(',').map((item: string) => item.trim());
Permissions.updatePermissionValue.apply(this, args);
}).delegateTo(editControllerSelector, '[data-check-change-permissions]');
}
}
}
let permissionObject: Permissions = new Permissions();
// expose to global
TYPO3.Permissions = permissionObject;
export = permissionObject;
export = new Permissions();
......@@ -3,6 +3,7 @@
"target": "es2017",
"lib": [
"dom",
"dom.iterable",
"scripthost",
"es2017",
"es2018",
......
......@@ -10,4 +10,4 @@
*
* The TYPO3 project - inspiring people to share!
*/
define(["require","exports","TYPO3/CMS/Core/DocumentService","TYPO3/CMS/Backend/FormEngine","../../Modal"],(function(e,t,n,o,r){"use strict";return class{constructor(e){this.controlElement=null,this.handleControlClick=e=>{e.preventDefault();const t=this.controlElement.dataset.itemName,n=this.controlElement.getAttribute("href")+"&P[currentValue]="+encodeURIComponent(document.editform[t].value)+"&P[currentSelectedValues]="+encodeURIComponent(o.getFieldElement(t).val());r.advanced({type:r.types.iframe,content:n,size:r.sizes.large})},n.ready().then(()=>{this.controlElement=document.querySelector(e),this.controlElement.addEventListener("click",this.handleControlClick)})}}}));
\ No newline at end of file
define(["require","exports","TYPO3/CMS/Core/DocumentService","TYPO3/CMS/Backend/FormEngine","../../Modal"],(function(e,t,n,o,r){"use strict";return class{constructor(e){this.controlElement=null,this.handleControlClick=e=>{e.preventDefault();const t=this.controlElement.dataset.itemName,n=this.controlElement.getAttribute("href")+"&P[currentValue]="+encodeURIComponent(document.forms.namedItem("editform")[t].value)+"&P[currentSelectedValues]="+encodeURIComponent(o.getFieldElement(t).val());r.advanced({type:r.types.iframe,content:n,size:r.sizes.large})},n.ready().then(()=>{this.controlElement=document.querySelector(e),this.controlElement.addEventListener("click",this.handleControlClick)})}}}));
\ No newline at end of file
......@@ -10,6 +10,9 @@
</f:section>
<f:section name="content">
<f:comment><!-- {base} is defined as it's *required* for mathematical operations in Fluid --></f:comment>
<f:variable name="base" value="2" />
<f:form action="update" name="editform" id="PermissionControllerEdit">
<div class="form-group">
......@@ -45,27 +48,27 @@
<tbody>
<tr>
<td><strong><f:translate key="LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:Owner" /></strong></td>
<td><input type="checkbox" name="check[perms_user][1]" data-check-change-permissions="check[perms_user],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_user]" /></td>
<td><input type="checkbox" name="check[perms_user][5]" data-check-change-permissions="check[perms_user],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_user]" /></td>
<td><input type="checkbox" name="check[perms_user][2]" data-check-change-permissions="check[perms_user],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_user]" /></td>
<td><input type="checkbox" name="check[perms_user][3]" data-check-change-permissions="check[perms_user],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_user]" /></td>
<td><input type="checkbox" name="check[perms_user][4]" data-check-change-permissions="check[perms_user],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_user]" /></td>
<td><input type="checkbox" name="check[perms_user][]" value="{base ^ 0}" data-check-change-permissions="check[perms_user],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_user]" /></td>
<td><input type="checkbox" name="check[perms_user][]" value="{base ^ 4}" data-check-change-permissions="check[perms_user],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_user]" /></td>
<td><input type="checkbox" name="check[perms_user][]" value="{base ^ 1}" data-check-change-permissions="check[perms_user],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_user]" /></td>
<td><input type="checkbox" name="check[perms_user][]" value="{base ^ 2}" data-check-change-permissions="check[perms_user],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_user]" /></td>
<td><input type="checkbox" name="check[perms_user][]" value="{base ^ 3}" data-check-change-permissions="check[perms_user],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_user]" /></td>
</tr>
<tr>
<td><strong><f:translate key="LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:Group" /></strong></td>
<td><input type="checkbox" name="check[perms_group][1]" data-check-change-permissions="check[perms_group],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_group]" /></td>
<td><input type="checkbox" name="check[perms_group][5]" data-check-change-permissions="check[perms_group],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_group]" /></td>
<td><input type="checkbox" name="check[perms_group][2]" data-check-change-permissions="check[perms_group],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_group]" /></td>
<td><input type="checkbox" name="check[perms_group][3]" data-check-change-permissions="check[perms_group],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_group]" /></td>
<td><input type="checkbox" name="check[perms_group][4]" data-check-change-permissions="check[perms_group],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_group]" /></td>
<td><input type="checkbox" name="check[perms_group][]" value="{base ^ 0}" data-check-change-permissions="check[perms_group],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_group]" /></td>
<td><input type="checkbox" name="check[perms_group][]" value="{base ^ 4}" data-check-change-permissions="check[perms_group],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_group]" /></td>
<td><input type="checkbox" name="check[perms_group][]" value="{base ^ 1}" data-check-change-permissions="check[perms_group],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_group]" /></td>
<td><input type="checkbox" name="check[perms_group][]" value="{base ^ 2}" data-check-change-permissions="check[perms_group],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_group]" /></td>
<td><input type="checkbox" name="check[perms_group][]" value="{base ^ 3}" data-check-change-permissions="check[perms_group],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_group]" /></td>
</tr>
<tr>
<td><strong><f:translate key="LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:Everybody" /></strong></td>
<td><input type="checkbox" name="check[perms_everybody][1]" data-check-change-permissions="check[perms_everybody],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_everybody]" /></td>
<td><input type="checkbox" name="check[perms_everybody][5]" data-check-change-permissions="check[perms_everybody],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_everybody]" /></td>
<td><input type="checkbox" name="check[perms_everybody][2]" data-check-change-permissions="check[perms_everybody],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_everybody]" /></td>
<td><input type="checkbox" name="check[perms_everybody][3]" data-check-change-permissions="check[perms_everybody],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_everybody]" /></td>
<td><input type="checkbox" name="check[perms_everybody][4]" data-check-change-permissions="check[perms_everybody],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_everybody]" /></td>
<td><input type="checkbox" name="check[perms_everybody][]" value="{base ^ 0}" data-check-change-permissions="check[perms_everybody],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_everybody]" /></td>
<td><input type="checkbox" name="check[perms_everybody][]" value="{base ^ 4}" data-check-change-permissions="check[perms_everybody],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_everybody]" /></td>
<td><input type="checkbox" name="check[perms_everybody][]" value="{base ^ 1}" data-check-change-permissions="check[perms_everybody],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_everybody]" /></td>
<td><input type="checkbox" name="check[perms_everybody][]" value="{base ^ 2}" data-check-change-permissions="check[perms_everybody],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_everybody]" /></td>
<td><input type="checkbox" name="check[perms_everybody][]" value="{base ^ 3}" data-check-change-permissions="check[perms_everybody],tx_beuser_system_beusertxpermission[data][pages][{id}][perms_everybody]" /></td>
</tr>
</tbody>
</table>
......@@ -77,9 +80,9 @@
<f:form.select id="recursionLevel" name="mirror[pages][{id}]" options="{recursiveSelectOptions}" class="form-select" />
</div>
<f:form.hidden name="data[pages][{id}][perms_user]" value="{pageInfo.perms_user}" />
<f:form.hidden name="data[pages][{id}][perms_group]" value="{pageInfo.perms_group}" />
<f:form.hidden name="data[pages][{id}][perms_everybody]" value="{pageInfo.perms_everybody}" />
<f:form.hidden name="data[pages][{id}][perms_user]" value="{pageInfo.perms_user}" data="{'checkbox-group': 'check[perms_user]'}" />
<f:form.hidden name="data[pages][{id}][perms_group]" value="{pageInfo.perms_group}" data="{'checkbox-group': 'check[perms_group]'}" />
<f:form.hidden name="data[pages][{id}][perms_everybody]" value="{pageInfo.perms_everybody}" data="{'checkbox-group': 'check[perms_everybody]'}" />
<f:form.hidden name="depth" value="{depth}" />
<f:form.hidden name="returnUrl" value="{returnUrl}" />
......@@ -95,13 +98,4 @@
<strong><f:translate key="LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:8" /></strong>: <f:translate key="LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:8_t" />
</p>
<p><f:translate key="LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:def" /></p>