diff --git a/typo3/sysext/backend/Classes/Clipboard/Clipboard.php b/typo3/sysext/backend/Classes/Clipboard/Clipboard.php index a347102c79c324488bf4f06f42a36ff637ed7b6a..da285ad5bd45589ddc47fc60d23cc56b4684eaa4 100644 --- a/typo3/sysext/backend/Classes/Clipboard/Clipboard.php +++ b/typo3/sysext/backend/Classes/Clipboard/Clipboard.php @@ -708,6 +708,26 @@ class Clipboard * @return string JavaScript "confirm" message */ public function confirmMsg($table, $rec, $type, $clElements, $columnLabel = '') + { + $message = $this->confirmMsgText($table, $rec, $type, $clElements, $columnLabel); + if (!empty($message)) { + $message = 'confirm(' . GeneralUtility::quoteJSvalue($message) . ');'; + } + return $message; + } + + + /** + * Returns confirm JavaScript message + * + * @param string $table Table name + * @param mixed $rec For records its an array, for files its a string (path) + * @param string $type Type-code + * @param array $clElements Array of selected elements + * @param string $columnLabel Name of the content column + * @return string the text for a confirm message + */ + public function confirmMsgText($table, $rec, $type, $clElements, $columnLabel = '') { if ($this->getBackendUser()->jsConfirmation(JsConfirmation::COPY_MOVE_PASTE)) { $labelKey = 'LLL:EXT:lang/locallang_core.xlf:mess.' . ($this->currentMode() == 'copy' ? 'copy' : 'move') . ($this->current == 'normal' ? '' : 'cb') . '_' . $type; @@ -738,7 +758,12 @@ class Clipboard } // Message - $conf = 'confirm(' . GeneralUtility::quoteJSvalue(sprintf($msg, GeneralUtility::fixed_lgd_cs($selRecTitle, 30), GeneralUtility::fixed_lgd_cs($thisRecTitle, 30), GeneralUtility::fixed_lgd_cs($columnLabel, 30))) . ')'; + $conf = sprintf( + $msg, + GeneralUtility::fixed_lgd_cs($selRecTitle, 30), + GeneralUtility::fixed_lgd_cs($thisRecTitle, 30), + GeneralUtility::fixed_lgd_cs($columnLabel, 30) + ); } else { $conf = ''; } diff --git a/typo3/sysext/backend/Classes/View/PageLayoutView.php b/typo3/sysext/backend/Classes/View/PageLayoutView.php index 1dfca01e1b50c34860b697bf4560934b5b7b5c0f..f88c3f0b09020463169d602db10b97e8f72601ee 100644 --- a/typo3/sysext/backend/Classes/View/PageLayoutView.php +++ b/typo3/sysext/backend/Classes/View/PageLayoutView.php @@ -1299,12 +1299,15 @@ class PageLayoutView extends \TYPO3\CMS\Recordlist\RecordList\AbstractDatabaseRe if ($pasteParams) { $elFromTable = $this->clipboard->elFromTable('tt_content'); if (!empty($elFromTable) && $this->getPageLayoutController()->pageIsNotLockedForEditors()) { - $iconsArr['paste'] = '<a href="' - . htmlspecialchars($this->clipboard->pasteUrl('tt_content', $this->id, true, $pasteParams)) - . '" onclick="' . htmlspecialchars(('return ' - . $this->clipboard->confirmMsg('pages', $this->pageRecord, 'into', $elFromTable, $colName))) - . '" title="' . $this->getLanguageService()->getLL('pasteIntoColumn', true) . '">' - . $this->iconFactory->getIcon('actions-document-paste-into', Icon::SIZE_SMALL)->render() . '</a>'; + $iconsArr['paste'] = + '<a href="' . htmlspecialchars($this->clipboard->pasteUrl('tt_content', $this->id, true, $pasteParams)) . '"' + . ' class="t3js-modal-trigger"' + . ' data-severity="warning"' + . ' data-title="' . $this->getLanguageService()->getLL('pasteIntoColumn', true) . '"' + . ' data-content="' . htmlspecialchars($this->clipboard->confirmMsgText('pages', $this->pageRecord, 'into', $elFromTable, $colName)) . '"' + . ' title="' . $this->getLanguageService()->getLL('pasteIntoColumn', true) . '">' + . $this->iconFactory->getIcon('actions-document-paste-into', Icon::SIZE_SMALL)->render() + . '</a>'; } } } diff --git a/typo3/sysext/filelist/Classes/Controller/FileListController.php b/typo3/sysext/filelist/Classes/Controller/FileListController.php index 5c27c498021d2716e7e737714bdc970db6744c6a..4a1ddb0c14fa225734965c0b91547d710f81e726 100644 --- a/typo3/sysext/filelist/Classes/Controller/FileListController.php +++ b/typo3/sysext/filelist/Classes/Controller/FileListController.php @@ -661,11 +661,17 @@ class FileListController extends ActionController $elToConfirm[$key] = $clipBoardElement->getName(); } if ($addPasteButton) { + $confirmText = $this->filelist->clipObj + ->confirmMsgText('_FILE', $this->folderObject->getReadablePath(), 'into', $elToConfirm); $pasteButton = $buttonBar->makeLinkButton() - ->setHref($this->filelist->clipObj->pasteUrl('_FILE', - $this->folderObject->getCombinedIdentifier())) - ->setOnClick('return ' . $this->filelist->clipObj->confirmMsg('_FILE', - $this->folderObject->getReadablePath(), 'into', $elToConfirm)) + ->setHref($this->filelist->clipObj + ->pasteUrl('_FILE', $this->folderObject->getCombinedIdentifier())) + ->setClasses('t3js-modal-trigger') + ->setDataAttributes([ + 'severity' => 'warning', + 'content' => $confirmText, + 'title' => $lang->getLL('clip_paste') + ]) ->setTitle($lang->getLL('clip_paste')) ->setIcon($iconFactory->getIcon('actions-document-paste-after', Icon::SIZE_SMALL)); $buttonBar->addButton($pasteButton, ButtonBar::BUTTON_POSITION_LEFT, 2); diff --git a/typo3/sysext/filelist/Classes/FileList.php b/typo3/sysext/filelist/Classes/FileList.php index dc33f40cd6986adde2f859a22a913e4047f6c02e..72e747adff16072be8f6bfef9d3cbc666c153ee7 100644 --- a/typo3/sysext/filelist/Classes/FileList.php +++ b/typo3/sysext/filelist/Classes/FileList.php @@ -367,7 +367,23 @@ class FileList extends AbstractRecordList $elToConfirm[$key] = $clipBoardElement->getName(); } if ($addPasteButton) { - $cells[] = '<a class="btn btn-default" href="' . htmlspecialchars($this->clipObj->pasteUrl('_FILE', $this->folderObject->getCombinedIdentifier())) . '" onclick="return ' . htmlspecialchars($this->clipObj->confirmMsg('_FILE', $this->path, 'into', $elToConfirm)) . '" title="' . $this->getLanguageService()->getLL('clip_paste', 1) . '">' . $this->iconFactory->getIcon('actions-document-paste-after', Icon::SIZE_SMALL)->render() . '</a>'; + $cells[] = '<a class="btn btn-default t3js-modal-trigger"'. + ' href="' . htmlspecialchars($this->clipObj->pasteUrl( + '_FILE', + $this->folderObject->getCombinedIdentifier() + )) . '"' + . ' data-content="' . htmlspecialchars($this->clipObj->confirmMsgText( + '_FILE', + $this->path, + 'into', + $elToConfirm + )) . '"' + . ' data-severity="warning"' + . ' data-title="' . $this->getLanguageService()->getLL('clip_paste', true) . '"' + . ' title="' . $this->getLanguageService()->getLL('clip_paste', true) . '">' + . $this->iconFactory->getIcon('actions-document-paste-after', Icon::SIZE_SMALL) + ->render() + . '</a>'; } } if ($this->clipObj->current !== 'normal' && $iOut) { @@ -858,7 +874,15 @@ class FileList extends AbstractRecordList $elToConfirm[$key] = $clipBoardElement->getName(); } if ($addPasteButton) { - $cells[] = '<a class="btn btn-default" href="' . htmlspecialchars($this->clipObj->pasteUrl('_FILE', $fullIdentifier)) . '" onclick="return ' . htmlspecialchars($this->clipObj->confirmMsg('_FILE', $fullName, 'into', $elToConfirm)) . '" title="' . $this->getLanguageService()->getLL('clip_pasteInto', true) . '">' . $this->iconFactory->getIcon('actions-document-paste-into', Icon::SIZE_SMALL)->render() . '</a>'; + $cells[] = '<a class="btn btn-default t3js-modal-trigger" ' + . ' href="' . htmlspecialchars($this->clipObj->pasteUrl('_FILE', $fullIdentifier)) . '"' + . ' data-content="' . htmlspecialchars($this->clipObj->confirmMsgText('_FILE', $fullName, 'into', $elToConfirm)) . '"' + . ' data-severity="warning"' + . ' data-title="' . $this->getLanguageService()->getLL('clip_pasteInto', true) . '"' + . ' title="' . $this->getLanguageService()->getLL('clip_pasteInto', true) . '"' + .'>' + . $this->iconFactory->getIcon('actions-document-paste-into', Icon::SIZE_SMALL)->render() + . '</a>'; } } // Compile items into a DIV-element: diff --git a/typo3/sysext/recordlist/Classes/RecordList/DatabaseRecordList.php b/typo3/sysext/recordlist/Classes/RecordList/DatabaseRecordList.php index 047588412d56dfacd25e5cd9a43f00c8c1fbee43..5f0727ed721b2988720d6ca2e64106272e3a196e 100644 --- a/typo3/sysext/recordlist/Classes/RecordList/DatabaseRecordList.php +++ b/typo3/sysext/recordlist/Classes/RecordList/DatabaseRecordList.php @@ -283,10 +283,17 @@ class DatabaseRecordList extends AbstractDatabaseRecordList if (($localCalcPerms & Permission::PAGE_NEW || $localCalcPerms & Permission::CONTENT_EDIT) && $this->editLockPermissions()) { $elFromTable = $this->clipObj->elFromTable(''); if (!empty($elFromTable)) { - $onClick = htmlspecialchars(('return ' . $this->clipObj->confirmMsg('pages', $this->pageRow, 'into', $elFromTable))); - $buttons['paste'] = '<a href="' . htmlspecialchars($this->clipObj->pasteUrl('', $this->id)) - . '" onclick="' . $onClick . '" title="' . $lang->getLL('clip_paste', true) . '">' - . $this->iconFactory->getIcon('actions-document-paste-after', Icon::SIZE_SMALL)->render() . '</a>'; + $confirmText = $this->clipObj->confirmMsgText('pages', $this->pageRow, 'into', $elFromTable); + $buttons['paste'] = '<a' + . ' href="' . htmlspecialchars($this->clipObj->pasteUrl('', $this->id)) . '"' + . ' title="' . $lang->getLL('clip_paste', true) . '"' + . ' class="t3js-modal-trigger"' + . ' data-severity="warning"' + . ' data-title="' . $lang->getLL('clip_paste', true) . '"' + . ' data-content="' . htmlspecialchars($confirmText) . '"' + . '>' + . $this->iconFactory->getIcon('actions-document-paste-after', Icon::SIZE_SMALL)->render() + . '</a>'; } } // Cache @@ -407,11 +414,16 @@ class DatabaseRecordList extends AbstractDatabaseRecordList if ($this->showClipboard && ($localCalcPerms & Permission::PAGE_NEW || $localCalcPerms & Permission::CONTENT_EDIT) && $this->editLockPermissions()) { $elFromTable = $this->clipObj->elFromTable(''); if (!empty($elFromTable)) { - $onClick = 'return ' . $this->clipObj->confirmMsg('pages', $this->pageRow, 'into', $elFromTable); + $confirmMessage = $this->clipObj->confirmMsgText('pages', $this->pageRow, 'into', $elFromTable); $pasteButton = $buttonBar->makeLinkButton() ->setHref($this->clipObj->pasteUrl('', $this->id)) - ->setOnClick($onClick) ->setTitle($lang->getLL('clip_paste')) + ->setClasses('t3js-modal-trigger') + ->setDataAttributes([ + 'severity' => 'warning', + 'content' => $confirmMessage, + 'title' => $lang->getLL('clip_paste') + ]) ->setIcon($this->iconFactory->getIcon('actions-document-paste-after', Icon::SIZE_SMALL)); $buttonBar->addButton($pasteButton, ButtonBar::BUTTON_POSITION_LEFT, 40); } @@ -1063,10 +1075,15 @@ class DatabaseRecordList extends AbstractDatabaseRecordList $elFromTable = $this->clipObj->elFromTable($table); if (!empty($elFromTable) && $this->overlayEditLockPermissions($table)) { $href = htmlspecialchars($this->clipObj->pasteUrl($table, $this->id)); - $onClick = htmlspecialchars('return ' . $this->clipObj->confirmMsg('pages', $this->pageRow, 'into', $elFromTable)); - $cells['pasteAfter'] = '<a class="btn btn-default" href="' . $href . '" onclick="' . $onClick - . '" title="' . $lang->getLL('clip_paste', true) . '">' - . $this->iconFactory->getIcon('actions-document-paste-after', Icon::SIZE_SMALL)->render() . '</a>'; + $confirmMessage = $this->clipObj->confirmMsgText('pages', $this->pageRow, 'into', $elFromTable); + $cells['pasteAfter'] = '<a class="btn btn-default t3js-modal-trigger"' + . ' href="' . $href . '"' + . ' title="' . $lang->getLL('clip_paste', true) . '"' + . ' data-title="' . $lang->getLL('clip_paste', true) . '"' + . ' data-content="' . htmlspecialchars($confirmMessage) . '"' + . ' data-severity="warning">' + . $this->iconFactory->getIcon('actions-document-paste-after', Icon::SIZE_SMALL)->render() + . '</a>'; } // If the numeric clipboard pads are enabled, display the control icons for that: if ($this->clipObj->current != 'normal') { @@ -1763,17 +1780,23 @@ class DatabaseRecordList extends AbstractDatabaseRecordList // IF elements are found, they can be individually ordered and are not locked by editlock, then add a "paste after" icon: $cells['pasteAfter'] = $isL10nOverlay || !$this->overlayEditLockPermissions($table, $row) ? $this->spaceIcon - : '<a class="btn btn-default" href="' . htmlspecialchars($this->clipObj->pasteUrl($table, -$row['uid'])) . '" onclick="' - . htmlspecialchars(('return ' . $this->clipObj->confirmMsg($table, $row, 'after', $elFromTable))) - . '" title="' . $this->getLanguageService()->getLL('clip_pasteAfter', true) . '">' + : '<a class="btn btn-default t3js-modal-trigger"' + . ' href="' . htmlspecialchars($this->clipObj->pasteUrl($table, -$row['uid'])) . '"' + . ' title="' . $this->getLanguageService()->getLL('clip_pasteAfter', true) . '"' + . ' data-title="' . $this->getLanguageService()->getLL('clip_pasteAfter', true) . '"' + . ' data-content="' . htmlspecialchars($this->clipObj->confirmMsgText($table, $row, 'after', $elFromTable)) . '"' + . ' data-severity="warning">' . $this->iconFactory->getIcon('actions-document-paste-after', Icon::SIZE_SMALL)->render() . '</a>'; } // Now, looking for elements in general: $elFromTable = $this->clipObj->elFromTable(''); if ($table == 'pages' && !empty($elFromTable)) { - $cells['pasteInto'] = '<a class="btn btn-default" href="' . htmlspecialchars($this->clipObj->pasteUrl('', $row['uid'])) - . '" onclick="' . htmlspecialchars('return ' . $this->clipObj->confirmMsg($table, $row, 'into', $elFromTable)) - . '" title="' . $this->getLanguageService()->getLL('clip_pasteInto', true) . '">' + $cells['pasteInto'] = '<a class="btn btn-default t3js-modal-trigger"' + . ' href="' . htmlspecialchars($this->clipObj->pasteUrl('', $row['uid'])) . '"' + . ' title="' . $this->getLanguageService()->getLL('clip_pasteInto', true) . '"' + . ' data-title="' . $this->getLanguageService()->getLL('clip_pasteInto', true) . '"' + . ' data-content="' . htmlspecialchars($this->clipObj->confirmMsgText($table, $row, 'into', $elFromTable)) . '"' + . ' data-severity="warning">' . $this->iconFactory->getIcon('actions-document-paste-into', Icon::SIZE_SMALL)->render() . '</a>'; } /**