diff --git a/Build/Resources/Public/Less/TYPO3/_main_backend_layout_wizard.less b/Build/Resources/Public/Less/TYPO3/_main_backend_layout_wizard.less index 830d5aa65ca86980d3e5865a6a19750bbcc64ff9..7761bf2a95c61d7d4371ca0948a48d1e2cbc1b44 100644 --- a/Build/Resources/Public/Less/TYPO3/_main_backend_layout_wizard.less +++ b/Build/Resources/Public/Less/TYPO3/_main_backend_layout_wizard.less @@ -38,6 +38,10 @@ opacity: 0.5; } + .grideditor-preview { + margin-top: 5px; + } + .link { display: block; position: absolute; diff --git a/typo3/sysext/backend/Classes/Controller/BackendLayoutWizardController.php b/typo3/sysext/backend/Classes/Controller/BackendLayoutWizardController.php deleted file mode 100644 index c54cc03d2f5f4b4ca06be2185465b716d2927b14..0000000000000000000000000000000000000000 --- a/typo3/sysext/backend/Classes/Controller/BackendLayoutWizardController.php +++ /dev/null @@ -1,378 +0,0 @@ -<?php -namespace TYPO3\CMS\Backend\Controller; - -/* - * This file is part of the TYPO3 CMS project. - * - * It is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, either version 2 - * of the License, or any later version. - * - * For the full copyright and license information, please read the - * LICENSE.txt file that was distributed with this source code. - * - * The TYPO3 project - inspiring people to share! - */ - -use Psr\Http\Message\ResponseInterface; -use Psr\Http\Message\ServerRequestInterface; -use TYPO3\CMS\Backend\Module\AbstractModule; -use TYPO3\CMS\Backend\Template\Components\ButtonBar; -use TYPO3\CMS\Backend\Utility\BackendUtility; -use TYPO3\CMS\Core\Imaging\Icon; -use TYPO3\CMS\Core\Page\PageRenderer; -use TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser; -use TYPO3\CMS\Core\Utility\GeneralUtility; - -/** - * Script Class for grid wizard - */ -class BackendLayoutWizardController extends AbstractModule -{ - /** - * GET vars: - * Wizard parameters, coming from TCEforms linking to the wizard. - * @var array - */ - public $P; - - /** - * Accumulated content. - * @var string - */ - public $content; - - /** - * @var string - */ - public $formName; - - /** - * @var string - */ - public $fieldName; - - /** - * @var array - */ - protected $rows; - - /** - * @var int - */ - protected $colCount; - - /** - * @var int - */ - protected $rowCount; - - /** - * Constructor - */ - public function __construct() - { - parent::__construct(); - $this->init(); - } - - /** - * Initialises the Class - * - * @return void - * @throws \InvalidArgumentException - */ - public function init() - { - $lang = $this->getLanguageService(); - $lang->includeLLFile('EXT:lang/locallang_wizards.xlf'); - - // Setting GET vars (used in frameset script): - $this->P = GeneralUtility::_GP('P'); - $this->formName = $this->P['formName']; - $this->fieldName = $this->P['itemName']; - $hmac_validate = GeneralUtility::hmac($this->formName . $this->fieldName, 'wizard_js'); - if (!$this->P['hmac'] || ($this->P['hmac'] !== $hmac_validate)) { - throw new \InvalidArgumentException('Hmac Validation failed for backend_layout wizard', 1385811397); - } - $uid = (int)$this->P['uid']; - - /** @var \TYPO3\CMS\Core\Page\PageRenderer $pageRenderer */ - $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class); - $pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/GridEditor'); - $pageRenderer->addInlineSetting( - 'ContextHelp', - 'moduleUrl', - BackendUtility::getModuleUrl( - 'help_CshmanualCshmanual', - array( - 'tx_cshmanual_help_cshmanualcshmanual' => array( - 'controller' => 'Help', - 'action' => 'detail' - ) - ) - ) - ); - $pageRenderer->addJsInlineCode('storeData', ' - function storeData(data) { - if (parent.opener && parent.opener.document && parent.opener.document.' . $this->formName - . ' && parent.opener.document.' . $this->formName . '[' - . GeneralUtility::quoteJSvalue($this->fieldName) . ']) { - parent.opener.document.' . $this->formName . '[' - . GeneralUtility::quoteJSvalue($this->fieldName) . '].value = data; - parent.opener.TBE_EDITOR.fieldChanged("backend_layout","' . $uid . '","config",' - . '"data[backend_layout][' . $uid . '][config]"); - } - } - ', false); - $languageLabels = array( - 'save' => htmlspecialchars($lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_labelSave')), - 'title' => htmlspecialchars($lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_windowTitle')), - 'editCell' => htmlspecialchars($lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_editCell')), - 'mergeCell' => htmlspecialchars($lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_mergeCell')), - 'splitCell' => htmlspecialchars($lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_splitCell')), - 'name' => htmlspecialchars($lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_name')), - 'column' => htmlspecialchars($lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_column')), - 'notSet' => htmlspecialchars($lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_notSet')), - 'nameHelp' => htmlspecialchars($lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_nameHelp')), - 'columnHelp' => htmlspecialchars($lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_columnHelp')) - ); - $pageRenderer->addInlineLanguageLabelArray($languageLabels); - // Select record - $record = $this->getDatabaseConnection()->exec_SELECTgetRows( - $this->P['field'], - $this->P['table'], - 'uid=' . (int)$this->P['uid'] - ); - if (trim($record[0][$this->P['field']]) == '') { - $rows = array(array(array('colspan' => 1, 'rowspan' => 1, 'spanned' => false, 'name' => ''))); - $colCount = 1; - $rowCount = 1; - } else { - // load TS parser - $parser = GeneralUtility::makeInstance(TypoScriptParser::class); - $parser->parse($record[0][$this->P['field']]); - $data = $parser->setup['backend_layout.']; - $rows = array(); - $colCount = $data['colCount']; - $rowCount = $data['rowCount']; - $dataRows = $data['rows.']; - $spannedMatrix = array(); - for ($i = 1; $i <= $rowCount; $i++) { - $cells = array(); - $row = array_shift($dataRows); - $columns = $row['columns.']; - for ($j = 1; $j <= $colCount; $j++) { - $cellData = array(); - if (!$spannedMatrix[$i][$j]) { - if (is_array($columns) && !empty($columns)) { - $column = array_shift($columns); - if (isset($column['colspan'])) { - $cellData['colspan'] = (int)$column['colspan']; - $columnColSpan = (int)$column['colspan']; - if (isset($column['rowspan'])) { - $columnRowSpan = (int)$column['rowspan']; - for ($spanRow = 0; $spanRow < $columnRowSpan; $spanRow++) { - for ($spanColumn = 0; $spanColumn < $columnColSpan; $spanColumn++) { - $spannedMatrix[$i + $spanRow][$j + $spanColumn] = 1; - } - } - } else { - for ($spanColumn = 0; $spanColumn < $columnColSpan; $spanColumn++) { - $spannedMatrix[$i][$j + $spanColumn] = 1; - } - } - } else { - $cellData['colspan'] = 1; - if (isset($column['rowspan'])) { - $columnRowSpan = (int)$column['rowspan']; - for ($spanRow = 0; $spanRow < $columnRowSpan; $spanRow++) { - $spannedMatrix[$i + $spanRow][$j] = 1; - } - } - } - if (isset($column['rowspan'])) { - $cellData['rowspan'] = (int)$column['rowspan']; - } else { - $cellData['rowspan'] = 1; - } - if (isset($column['name'])) { - $cellData['name'] = $column['name']; - } - if (isset($column['colPos'])) { - $cellData['column'] = (int)$column['colPos']; - } - } - } else { - $cellData = array('colspan' => 1, 'rowspan' => 1, 'spanned' => 1); - } - $cells[] = $cellData; - } - $rows[] = $cells; - if (!empty($spannedMatrix[$i]) && is_array($spannedMatrix[$i])) { - ksort($spannedMatrix[$i]); - } - } - } - $this->rows = $rows; - $this->colCount = (int)$colCount; - $this->rowCount = (int)$rowCount; - } - - /** - * Injects the request object for the current request or subrequest - * As this controller goes only through the main() method, it is rather simple for now - * - * @param ServerRequestInterface $request - * @param ResponseInterface $response - * @return ResponseInterface - */ - public function mainAction(ServerRequestInterface $request, ResponseInterface $response) - { - $this->main(); - - $this->setPagePath($this->P['table'], $this->P['uid']); - - $this->moduleTemplate->setContent($this->content); - $response->getBody()->write($this->moduleTemplate->renderContent()); - return $response; - } - - /** - * Creates the correct path to the current record - * - * @param string $table - * @param int $uid - */ - protected function setPagePath($table, $uid) - { - $uid = (int)$uid; - - if ($table === 'pages') { - $pageId = $uid; - } else { - $record = BackendUtility::getRecord($table, $uid, '*', '', false); - $pageId = $record['pid']; - } - - $pageAccess = BackendUtility::readPageAccess($pageId, $this->getBackendUser()->getPagePermsClause(1)); - if (is_array($pageAccess)) { - $this->moduleTemplate->getDocHeaderComponent()->setMetaInformation($pageAccess); - } - } - - /** - * Main Method, rendering either colorpicker or frameset depending on ->showPicker - * - * @return void - */ - public function main() - { - $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar(); - $lang = $this->getLanguageService(); - - $saveButton = $buttonBar->makeInputButton() - ->setName('_savedok') - ->setValue('1') - ->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveDoc')) - ->setClasses('t3js-grideditor-savedok') - ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save', Icon::SIZE_SMALL)); - - $saveAndCloseButton = $buttonBar->makeInputButton() - ->setName('_savedokandclose') - ->setValue('1') - ->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveCloseDoc')) - ->setClasses('t3js-grideditor-savedokclose') - ->setIcon( - $this->moduleTemplate->getIconFactory()->getIcon('actions-document-save-close', Icon::SIZE_SMALL) - ); - - $splitButton = $buttonBar->makeSplitButton() - ->addItem($saveButton) - ->addItem($saveAndCloseButton); - $buttonBar->addButton($splitButton); - - $closeButton = $buttonBar->makeLinkButton() - ->setHref('#') - ->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.closeDoc')) - ->setOnClick('window.close();return true;') - ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-close', Icon::SIZE_SMALL)); - $buttonBar->addButton($closeButton, ButtonBar::BUTTON_POSITION_LEFT, 30); - - $markup = array(); - $markup[] = ''; - $markup[] = '<table class="grideditor table table-bordered"">'; - $markup[] = ' <tr>'; - $markup[] = ' <td class="editor_cell">'; - $markup[] = ' <div id="editor" class="t3js-grideditor" data-data="' . htmlspecialchars( - json_encode( - $this->rows, - JSON_HEX_QUOT | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS - ) - ) . '" ' - . 'data-rowcount="' . (int)$this->rowCount . '" ' - . 'data-colcount="' . (int)$this->colCount . '">'; - $markup[] = ' </div>'; - $markup[] = ' </td>'; - $markup[] = ' <td>'; - $markup[] = ' <div class="btn-group-vertical">'; - $markup[] = ' <a class="btn btn-default btn-sm t3js-grideditor-addcolumn" href="#" title="' - . htmlspecialchars($lang->getLL('grid_addColumn')) . '">'; - $markup[] = ' <i class="fa fa-fw fa-arrow-right"></i>'; - $markup[] = ' </a>'; - $markup[] = ' <a class="btn btn-default btn-sm t3js-grideditor-removecolumn" href="#" title="' - . htmlspecialchars($lang->getLL('grid_removeColumn')) . '">'; - $markup[] = ' <i class="fa fa-fw fa-arrow-left"></i>'; - $markup[] = ' </a>'; - $markup[] = ' </div>'; - $markup[] = ' </td>'; - $markup[] = ' </tr>'; - $markup[] = ' <tr>'; - $markup[] = ' <td colspan="2" align="center">'; - $markup[] = ' <div class="btn-group">'; - $markup[] = ' <a class="btn btn-default btn-sm t3js-grideditor-addrow" href="#" title="' - . htmlspecialchars($lang->getLL('grid_addRow')) . '">'; - $markup[] = ' <i class="fa fa-fw fa-arrow-down"></i>'; - $markup[] = ' </a>'; - $markup[] = ' <a class="btn btn-default btn-sm t3js-grideditor-removerow" href="#" title="' - . htmlspecialchars($lang->getLL('grid_removeRow')) . '">'; - $markup[] = ' <i class="fa fa-fw fa-arrow-up"></i>'; - $markup[] = ' </a>'; - $markup[] = ' </div>'; - $markup[] = ' </td>'; - $markup[] = ' </tr>'; - $markup[] = '</table>'; - - $this->content .= implode(LF, $markup); - } - - /** - * Returns LanguageService - * - * @return \TYPO3\CMS\Lang\LanguageService - */ - protected function getLanguageService() - { - return $GLOBALS['LANG']; - } - - /** - * Returns the database connection - * - * @return \TYPO3\CMS\Core\Database\DatabaseConnection - */ - protected function getDatabaseConnection() - { - return $GLOBALS['TYPO3_DB']; - } - - /** - * Gets the current backend user. - * - * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication - */ - protected function getBackendUser() - { - return $GLOBALS['BE_USER']; - } -} diff --git a/typo3/sysext/backend/Classes/View/Wizard/Element/BackendLayoutWizardElement.php b/typo3/sysext/backend/Classes/View/Wizard/Element/BackendLayoutWizardElement.php new file mode 100644 index 0000000000000000000000000000000000000000..fe395fbf0377e9a144087d6e3e24fb4f25cb7409 --- /dev/null +++ b/typo3/sysext/backend/Classes/View/Wizard/Element/BackendLayoutWizardElement.php @@ -0,0 +1,195 @@ +<?php +namespace TYPO3\CMS\Backend\View\Wizard\Element; + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +use TYPO3\CMS\Backend\Form\Element\AbstractFormElement; +use TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser; +use TYPO3\CMS\Core\Utility\GeneralUtility; + +/** + * Class BackendLayoutWizardElement + */ +class BackendLayoutWizardElement extends AbstractFormElement +{ + + /** + * @var array + */ + protected $resultArray = []; + + /** + * @var array + */ + protected $rows = []; + + /** + * @var int + */ + protected $colCount = 0; + + /** + * @var int + */ + protected $rowCount = 0; + + /** + * @return array + */ + public function render() + { + $this->resultArray = $this->initializeResultArray(); + $this->init(); + + $lang = $this->getLanguageService(); + + $json = json_encode($this->rows, JSON_HEX_QUOT | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS); + $markup = []; + $markup[] = '<input type="hidden" name="' . htmlspecialchars($this->data['parameterArray']['itemFormElName']) + . '" value="' . htmlspecialchars($this->data['parameterArray']['itemFormElValue']) . '" />'; + $markup[] = '<table class="grideditor table table-bordered">'; + $markup[] = ' <tr>'; + $markup[] = ' <td class="editor_cell">'; + $markup[] = ' <div id="editor" class="t3js-grideditor" data-data="' . htmlspecialchars($json) . '" ' + . 'data-rowcount="' . (int)$this->rowCount . '" ' + . 'data-colcount="' . (int)$this->colCount . '" ' + . 'data-field="' . htmlspecialchars($this->data['parameterArray']['itemFormElName']) . '" ' + . '>'; + $markup[] = ' </div>'; + $markup[] = ' </td>'; + $markup[] = ' <td>'; + $markup[] = ' <div class="btn-group-vertical">'; + $markup[] = ' <a class="btn btn-default btn-sm t3js-grideditor-addcolumn" href="#" title="' + . htmlspecialchars($lang->getLL('grid_addColumn')) . '">'; + $markup[] = ' <i class="fa fa-fw fa-arrow-right"></i>'; + $markup[] = ' </a>'; + $markup[] = ' <a class="btn btn-default btn-sm t3js-grideditor-removecolumn" href="#" title="' + . htmlspecialchars($lang->getLL('grid_removeColumn')) . '">'; + $markup[] = ' <i class="fa fa-fw fa-arrow-left"></i>'; + $markup[] = ' </a>'; + $markup[] = ' </div>'; + $markup[] = ' </td>'; + $markup[] = ' </tr>'; + $markup[] = ' <tr>'; + $markup[] = ' <td colspan="2" align="center">'; + $markup[] = ' <div class="btn-group">'; + $markup[] = ' <a class="btn btn-default btn-sm t3js-grideditor-addrow" href="#" title="' + . htmlspecialchars($lang->getLL('grid_addRow')) . '">'; + $markup[] = ' <i class="fa fa-fw fa-arrow-down"></i>'; + $markup[] = ' </a>'; + $markup[] = ' <a class="btn btn-default btn-sm t3js-grideditor-removerow" href="#" title="' + . htmlspecialchars($lang->getLL('grid_removeRow')) . '">'; + $markup[] = ' <i class="fa fa-fw fa-arrow-up"></i>'; + $markup[] = ' </a>'; + $markup[] = ' </div>'; + $markup[] = ' </td>'; + $markup[] = ' </tr>'; + $markup[] = ' <tr>'; + $markup[] = ' <td colspan="2">'; + $markup[] = ' <a href="#" class="btn btn-default btn-sm t3js-grideditor-preview-button"></a>'; + $markup[] = ' <pre class="t3js-grideditor-preview-config grideditor-preview"><code></code></pre>'; + $markup[] = ' </td>'; + $markup[] = ' </tr>'; + $markup[] = '</table>'; + + $content = implode(LF, $markup); + $this->resultArray['html'] = $content; + $this->resultArray['requireJsModules'][] = 'TYPO3/CMS/Backend/GridEditor'; + $this->resultArray['additionalInlineLanguageLabelFiles'][] = 'EXT:lang/locallang_wizards.xlf'; + $this->resultArray['additionalInlineLanguageLabelFiles'][] + = 'EXT:backend/Resources/Private/Language/locallang.xlf'; + + return $this->resultArray; + } + + /** + * Initialize wizard + */ + protected function init() + { + if (empty($this->data['databaseRow']['config'])) { + $rows = [[['colspan' => 1, 'rowspan' => 1, 'spanned' => false, 'name' => '']]]; + $colCount = 1; + $rowCount = 1; + } else { + // load TS parser + $parser = GeneralUtility::makeInstance(TypoScriptParser::class); + $parser->parse($this->data['databaseRow']['config']); + $data = $parser->setup['backend_layout.']; + $rows = []; + $colCount = $data['colCount']; + $rowCount = $data['rowCount']; + $dataRows = $data['rows.']; + $spannedMatrix = []; + for ($i = 1; $i <= $rowCount; $i++) { + $cells = []; + $row = array_shift($dataRows); + $columns = $row['columns.']; + for ($j = 1; $j <= $colCount; $j++) { + $cellData = []; + if (!$spannedMatrix[$i][$j]) { + if (is_array($columns) && !empty($columns)) { + $column = array_shift($columns); + if (isset($column['colspan'])) { + $cellData['colspan'] = (int)$column['colspan']; + $columnColSpan = (int)$column['colspan']; + if (isset($column['rowspan'])) { + $columnRowSpan = (int)$column['rowspan']; + for ($spanRow = 0; $spanRow < $columnRowSpan; $spanRow++) { + for ($spanColumn = 0; $spanColumn < $columnColSpan; $spanColumn++) { + $spannedMatrix[$i + $spanRow][$j + $spanColumn] = 1; + } + } + } else { + for ($spanColumn = 0; $spanColumn < $columnColSpan; $spanColumn++) { + $spannedMatrix[$i][$j + $spanColumn] = 1; + } + } + } else { + $cellData['colspan'] = 1; + if (isset($column['rowspan'])) { + $columnRowSpan = (int)$column['rowspan']; + for ($spanRow = 0; $spanRow < $columnRowSpan; $spanRow++) { + $spannedMatrix[$i + $spanRow][$j] = 1; + } + } + } + if (isset($column['rowspan'])) { + $cellData['rowspan'] = (int)$column['rowspan']; + } else { + $cellData['rowspan'] = 1; + } + if (isset($column['name'])) { + $cellData['name'] = $column['name']; + } + if (isset($column['colPos'])) { + $cellData['column'] = (int)$column['colPos']; + } + } + } else { + $cellData = ['colspan' => 1, 'rowspan' => 1, 'spanned' => 1]; + } + $cells[] = $cellData; + } + $rows[] = $cells; + if (!empty($spannedMatrix[$i]) && is_array($spannedMatrix[$i])) { + ksort($spannedMatrix[$i]); + } + } + } + $this->rows = $rows; + $this->colCount = (int)$colCount; + $this->rowCount = (int)$rowCount; + } +} diff --git a/typo3/sysext/backend/Configuration/Backend/Routes.php b/typo3/sysext/backend/Configuration/Backend/Routes.php index 60d1e8fc96330f79fa1c0c5be0767bb8a00f2d1c..e62278573f85b8d80ba209e193df9dbb526541af 100644 --- a/typo3/sysext/backend/Configuration/Backend/Routes.php +++ b/typo3/sysext/backend/Configuration/Backend/Routes.php @@ -38,12 +38,6 @@ return [ ], /** Wizards */ - // Register backend_layout wizard - 'wizard_backend_layout' => [ - 'path' => '/wizard/backend_layout', - 'target' => Controller\BackendLayoutWizardController::class . '::mainAction' - ], - // Register colorpicker wizard 'wizard_colorpicker' => [ 'path' => '/wizard/colorpicker', diff --git a/typo3/sysext/backend/Resources/Private/Language/locallang.xlf b/typo3/sysext/backend/Resources/Private/Language/locallang.xlf index ef6538a2f2ce9f5b1a748e7b29b7b21278b926d2..a40bd931e387c2b8132c52eff67da33fadf38f1b 100644 --- a/typo3/sysext/backend/Resources/Private/Language/locallang.xlf +++ b/typo3/sysext/backend/Resources/Private/Language/locallang.xlf @@ -85,6 +85,12 @@ Have a nice day.</source> <trans-unit id="login.donate"> <source>Donate</source> </trans-unit> + <trans-unit id="button.showPageTsConfig"> + <source>Show PageTS-Config</source> + </trans-unit> + <trans-unit id="button.hidePageTsConfig"> + <source>Hide PageTS-Config</source> + </trans-unit> </body> </file> </xliff> diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/GridEditor.js b/typo3/sysext/backend/Resources/Public/JavaScript/GridEditor.js index 8c942376167a77a561fa614f67328b17cefb6e36..a558b439b743a689a0a984047454ecbf656169b8 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/GridEditor.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/GridEditor.js @@ -20,7 +20,7 @@ define(['jquery', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Severity', 'boot /** * The main ContextHelp object * - * @type {{colCount: number, rowCount: number, data: {}, nameLabel: string, columnLabel: string, targetElement: null}} + * @type {{selectorEditor: string, selectorAddColumn: string, selectorRemoveColumn: string, selectorAddRow: string, selectorRemoveRow: string, selectorLinkEditor: string, selectorLinkExpandRight: string, selectorLinkShrinkLeft: string, selectorLinkExpandDown: string, selectorLinkShrinkUp: string, selectorDocHeaderSave: string, selectorDocHeaderSaveClose: string, selectorConfigPreview: string, selectorConfigPreviewButton: string, colCount: number, rowCount: number, field: string, data: Array, nameLabel: string, columnLabel: string, targetElement: null}} * @exports TYPO3/CMS/Backend/GridEditor */ var GridEditor = { @@ -36,8 +36,11 @@ define(['jquery', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Severity', 'boot selectorLinkShrinkUp: '.t3js-grideditor-link-shrink-up', selectorDocHeaderSave: '.t3js-grideditor-savedok', selectorDocHeaderSaveClose: '.t3js-grideditor-savedokclose', + selectorConfigPreview: '.t3js-grideditor-preview-config', + selectorConfigPreviewButton: '.t3js-grideditor-preview-button', colCount: 1, rowCount: 1, + field: '', data: [], nameLabel: 'name', columnLabel: 'columen label', @@ -53,39 +56,36 @@ define(['jquery', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Severity', 'boot var $element = $(GridEditor.selectorEditor); GridEditor.colCount = $element.data('colcount'); GridEditor.rowCount = $element.data('rowcount'); + GridEditor.field = $('input[name="' + $element.data('field') + '"]'); GridEditor.data = $element.data('data'); GridEditor.nameLabel = config.nameLabel || 'Name'; GridEditor.columnLabel = config.columnLabel || 'Column'; GridEditor.targetElement = $(GridEditor.selectorEditor); + $(GridEditor.selectorConfigPreview).hide(); - $(document).on('click', GridEditor.selectorDocHeaderSave, function(e) { - e.preventDefault(); - storeData(GridEditor.export2LayoutRecord()); - }); - $(document).on('click', GridEditor.selectorDocHeaderSaveClose, function(e) { - e.preventDefault(); - storeData(GridEditor.export2LayoutRecord()); - window.close(); - }); $(document).on('click', GridEditor.selectorAddColumn, function(e) { e.preventDefault(); GridEditor.addColumn(); GridEditor.drawTable(); + GridEditor.writeConfig(GridEditor.export2LayoutRecord()); }); $(document).on('click', GridEditor.selectorRemoveColumn, function(e) { e.preventDefault(); GridEditor.removeColumn(); GridEditor.drawTable(); + GridEditor.writeConfig(GridEditor.export2LayoutRecord()); }); $(document).on('click', GridEditor.selectorAddRow, function(e) { e.preventDefault(); GridEditor.addRow(); GridEditor.drawTable(); + GridEditor.writeConfig(GridEditor.export2LayoutRecord()); }); $(document).on('click', GridEditor.selectorRemoveRow, function(e) { e.preventDefault(); GridEditor.removeRow(); GridEditor.drawTable(); + GridEditor.writeConfig(GridEditor.export2LayoutRecord()); }); $(document).on('click', GridEditor.selectorLinkEditor, function(e) { e.preventDefault(); @@ -101,6 +101,7 @@ define(['jquery', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Severity', 'boot var row = $element.data('row'); GridEditor.addColspan(col, row); GridEditor.drawTable(); + GridEditor.writeConfig(GridEditor.export2LayoutRecord()); }); $(document).on('click', GridEditor.selectorLinkShrinkLeft, function(e) { e.preventDefault(); @@ -109,6 +110,7 @@ define(['jquery', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Severity', 'boot var row = $element.data('row'); GridEditor.removeColspan(col, row); GridEditor.drawTable(); + GridEditor.writeConfig(GridEditor.export2LayoutRecord()); }); $(document).on('click', GridEditor.selectorLinkExpandDown, function(e) { e.preventDefault(); @@ -117,6 +119,7 @@ define(['jquery', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Severity', 'boot var row = $element.data('row'); GridEditor.addRowspan(col, row); GridEditor.drawTable(); + GridEditor.writeConfig(GridEditor.export2LayoutRecord()); }); $(document).on('click', GridEditor.selectorLinkShrinkUp, function(e) { e.preventDefault(); @@ -125,9 +128,53 @@ define(['jquery', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Severity', 'boot var row = $element.data('row'); GridEditor.removeRowspan(col, row); GridEditor.drawTable(); + GridEditor.writeConfig(GridEditor.export2LayoutRecord()); + }); + + $(GridEditor.selectorConfigPreviewButton).empty().append(TYPO3.lang['button.showPageTsConfig']); + $(document).on('click', GridEditor.selectorConfigPreviewButton, function(e) { + e.preventDefault(); + var $preview = $(GridEditor.selectorConfigPreview); + var $button = $(GridEditor.selectorConfigPreviewButton); + if ($preview.is(':visible')) { + $button.empty().append(TYPO3.lang['button.showPageTsConfig']); + $(GridEditor.selectorConfigPreview).slideUp(); + } else { + $button.empty().append(TYPO3.lang['button.hidePageTsConfig']); + $(GridEditor.selectorConfigPreview).slideDown(); + } + }); GridEditor.drawTable(); + GridEditor.writeConfig(GridEditor.export2LayoutRecord()); + }; + + /** + * write data back to hidden field + * + * @param data + */ + GridEditor.writeConfig = function(data) { + GridEditor.field.val(data); + var configLines = data.split('\n'); + var config = ''; + for (var i=0; i<configLines.length; i++) { + if (configLines[i].length) { + config += '\t\t\t' + configLines[i] + '\n'; + } + } + $(GridEditor.selectorConfigPreview).find('code').empty().append( + 'mod.web_layout.BackendLayouts {\n' + + ' exampleKey {\n' + + ' title = Example\n' + + ' icon = EXT:example_extension/Resources/Public/Images/BackendLayouts/default.gif\n' + + ' config {\n' + + config.replace(new RegExp('\t', 'g'), ' ') + + ' }\n' + + ' }\n' + + '}\n' + ); }; /** @@ -285,22 +332,22 @@ define(['jquery', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Severity', 'boot var $container = $('<div class="cell_container">'); $cell.append($container); var dataString = ' data-col="' + col + '" data-row="' + row + '"'; - $container.append($('<a class="t3js-grideditor-link-editor link link_editor" title="' + TYPO3.lang['editCell'] + '" ' + dataString + ' href="#"><!-- --></a>')); + $container.append($('<a class="t3js-grideditor-link-editor link link_editor" title="' + TYPO3.lang['grid_editCell'] + '" ' + dataString + ' href="#"><!-- --></a>')); if (GridEditor.cellCanSpanRight(col, row)) { - $container.append($('<a class="t3js-grideditor-link-expand-right link link_expand_right" href="#" title="' + TYPO3.lang['mergeCell'] + '" ' + dataString + '><!-- --></a>')); + $container.append($('<a class="t3js-grideditor-link-expand-right link link_expand_right" href="#" title="' + TYPO3.lang['grid_mergeCell'] + '" ' + dataString + '><!-- --></a>')); } if (GridEditor.cellCanShrinkLeft(col, row)) { - $container.append('<a class="t3js-grideditor-link-shrink-left link link_shrink_left" href="#" title="' + TYPO3.lang['splitCell'] + '" ' + dataString + '><!-- --></a>'); + $container.append('<a class="t3js-grideditor-link-shrink-left link link_shrink_left" href="#" title="' + TYPO3.lang['grid_splitCell'] + '" ' + dataString + '><!-- --></a>'); } if (GridEditor.cellCanSpanDown(col, row)) { - $container.append('<a class="t3js-grideditor-link-expand-down link link_expand_down" href="#" title="' + TYPO3.lang['mergeCell'] + '" ' + dataString + '><!-- --></a>'); + $container.append('<a class="t3js-grideditor-link-expand-down link link_expand_down" href="#" title="' + TYPO3.lang['grid_mergeCell'] + '" ' + dataString + '><!-- --></a>'); } if (GridEditor.cellCanShrinkUp(col, row)) { - $container.append('<a class="t3js-grideditor-link-shrink-up link link_shrink_up" href="#" title="' + TYPO3.lang['splitCell'] + '" ' + dataString + '><!-- --></a>'); + $container.append('<a class="t3js-grideditor-link-shrink-up link link_shrink_up" href="#" title="' + TYPO3.lang['grid_splitCell'] + '" ' + dataString + '><!-- --></a>'); } - $cell.append('<div class="cell_data">' + TYPO3.lang['name'] + ': ' + (cell.name ? GridEditor.stripMarkup(cell.name) : TYPO3.lang['notSet']) - + '<br />' + TYPO3.lang['column'] + ': ' - + (cell.column === undefined ? TYPO3.lang['notSet'] : parseInt(cell.column, 10)) + '</div>'); + $cell.append('<div class="cell_data">' + TYPO3.lang['grid_name'] + ': ' + (cell.name ? GridEditor.stripMarkup(cell.name) : TYPO3.lang['grid_notSet']) + + '<br />' + TYPO3.lang['grid_column'] + ': ' + + (cell.column === undefined ? TYPO3.lang['grid_notSet'] : parseInt(cell.column, 10)) + '</div>'); if (cell.colspan > 1) { $cell.attr('colspan', cell.colspan); @@ -367,20 +414,29 @@ define(['jquery', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Severity', 'boot return false; } + var colPos; + if (cell.column === 0) { + colPos = 0; + } else if(parseInt(cell.column, 10)) { + colPos = parseInt(cell.column, 10); + } else { + colPos = ''; + } + var $markup = $('<div>'); $markup.append( '<div>' + '<div class="form-group">' + - '<label>' + TYPO3.lang['nameHelp'] + '</label>' + + '<label>' + TYPO3.lang['grid_nameHelp'] + '</label>' + '<input type="text" class="t3js-grideditor-field-name form-control" name="name" value="' + (GridEditor.stripMarkup(cell.name) || '') + '">' + '</div>' + '<div class="form-group">' + - '<label>' + TYPO3.lang['columnHelp'] + '</label>' + - '<input type="text" class="t3js-grideditor-field-colpos form-control" name="name" value="' + (parseInt(cell.column, 10) || '') + '">' + + '<label>' + TYPO3.lang['grid_columnHelp'] + '</label>' + + '<input type="text" class="t3js-grideditor-field-colpos form-control" name="name" value="' + colPos + '">' + '</div>' + '</div>' ); - var $modal = Modal.show(TYPO3.lang['title'], $markup, Severity.notice, [ + var $modal = Modal.show(TYPO3.lang['grid_windowTitle'], $markup, Severity.notice, [ { text: $(this).data('button-close-text') || TYPO3.lang['button.cancel'] || 'Cancel', active: true, @@ -397,12 +453,13 @@ define(['jquery', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Severity', 'boot $modal.data('row', row); $modal.on('button.clicked', function(e) { if (e.target.name === 'cancel') { - $(this).trigger('modal-dismiss'); + Modal.currentModal.trigger('modal-dismiss'); } else if (e.target.name === 'ok') { GridEditor.setName($modal.find('.t3js-grideditor-field-name').val(), $modal.data('col'), $modal.data('row')); GridEditor.setColumn($modal.find('.t3js-grideditor-field-colpos').val(), $modal.data('col'), $modal.data('row')); GridEditor.drawTable(); - $(this).trigger('modal-dismiss'); + GridEditor.writeConfig(GridEditor.export2LayoutRecord()); + Modal.currentModal.trigger('modal-dismiss'); } }); }; diff --git a/typo3/sysext/backend/ext_localconf.php b/typo3/sysext/backend/ext_localconf.php index 9535b56af6abdd198f988b7845d272fc70e66a22..3a85e44bbea054c3083020e9eaa6e2b4cb12b7e6 100644 --- a/typo3/sysext/backend/ext_localconf.php +++ b/typo3/sysext/backend/ext_localconf.php @@ -26,6 +26,12 @@ if (TYPO3_MODE === 'BE') { $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['backend']['avatarProviders']['defaultAvatarProvider'] = array( 'provider' => \TYPO3\CMS\Backend\Backend\Avatar\DefaultAvatarProvider::class ); + + $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'][1460321142] = array( + 'nodeName' => 'belayoutwizard', + 'priority' => 40, + 'class' => \TYPO3\CMS\Backend\View\Wizard\Element\BackendLayoutWizardElement::class, + ); } $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default'] = \TYPO3\CMS\Core\FrontendEditing\FrontendEditingController::class; diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-75497-InlineBackendLayoutWizard.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-75497-InlineBackendLayoutWizard.rst new file mode 100644 index 0000000000000000000000000000000000000000..ab562ec1589a494d94063db5c2edb1bd7107c6bd --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Breaking-75497-InlineBackendLayoutWizard.rst @@ -0,0 +1,28 @@ +=============================================== +Breaking: #75497 - inline backend layout wizard +=============================================== + +Description +=========== + +The ``BackendLayoutWizardController`` has been removed and a new renderType has been added to render the backend layout wizard inline in FormEngine. + +Also the backend route ``wizard_backend_layout`` has been removed. + + +Impact +====== + +Extending or using the ``BackendLayoutWizardController`` will break your installation. + + +Affected Installations +====================== + +An installation which uses an extension which make use of ``BackendLayoutWizardController`` + + +Migration +========= + +Use the renderType "belayoutwizard", which renders the backend layout wizard inline in FormEngine. diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-75497-InlineBackendLayoutWizard.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-75497-InlineBackendLayoutWizard.rst new file mode 100644 index 0000000000000000000000000000000000000000..a89a25539fd1ee56ae8c3f1be0b728862083d513 --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Feature-75497-InlineBackendLayoutWizard.rst @@ -0,0 +1,28 @@ +============================================== +Feature: #75497 - inline backend layout wizard +============================================== + +Description +=========== + +A new renderType was added to render the backend layout wizard inline in FormEngine. + + +Impact +====== + +The old ``BackendLayoutWizardController`` which has rendered the backend layout wizard in a popup has been removed. + +Use the new renderType ``belayoutwizard`` to render the backend layout wizard inline in FormEngine. + +example TCA configuration: + +.. code-block:: php + + 'config' => array( + 'label' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:backend_layout.config', + 'config' => array( + 'type' => 'text', + 'renderType' => 'belayoutwizard', + ) + ) diff --git a/typo3/sysext/frontend/Configuration/TCA/backend_layout.php b/typo3/sysext/frontend/Configuration/TCA/backend_layout.php index 20bffbb5a8140a8827bd0c860f5c708830c6f7e1..67d4374be9fe4e9cf4483dcefb2e6c50524de4ee 100644 --- a/typo3/sysext/frontend/Configuration/TCA/backend_layout.php +++ b/typo3/sysext/frontend/Configuration/TCA/backend_layout.php @@ -46,22 +46,8 @@ return array( 'label' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:backend_layout.config', 'config' => array( 'type' => 'text', - 'rows' => '10', - 'cols' => '48', - 'wrap' => 'OFF', - 'wizards' => array( - 0 => array( - 'title' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:backend_layout.wizard', - 'type' => 'popup', - 'icon' => 'wizard-backendlayout', - 'module' => array( - 'name' => 'wizard_backend_layout' - ), - 'JSopenParams' => 'height=800,width=800,status=0,menubar=0,scrollbars=0' - ) - ) - ), - 'defaultExtras' => 'fixed-font : enable-tab', + 'renderType' => 'belayoutwizard', + ) ), 'hidden' => array( 'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.disable', @@ -87,7 +73,9 @@ return array( ), 'types' => array( '1' => array( - 'showitem' => 'hidden, title, icon, description, config', + 'showitem' => 'title,icon,config, + --div--;LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:backend_layout.tabs.access, hidden, + --div--;LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:backend_layout.tabs.extended, description', ), ) ); diff --git a/typo3/sysext/frontend/Resources/Private/Language/locallang_tca.xlf b/typo3/sysext/frontend/Resources/Private/Language/locallang_tca.xlf index 8da535d560e618a8ea9c78432379ed4c7a2ef709..ede7c95ce9ad57791eb8d6e9b45f91d81d7a833a 100644 --- a/typo3/sysext/frontend/Resources/Private/Language/locallang_tca.xlf +++ b/typo3/sysext/frontend/Resources/Private/Language/locallang_tca.xlf @@ -621,6 +621,12 @@ <trans-unit id="backend_layout.icon"> <source>Icon</source> </trans-unit> + <trans-unit id="backend_layout.tabs.access"> + <source>Access</source> + </trans-unit> + <trans-unit id="backend_layout.tabs.extended"> + <source>Extended</source> + </trans-unit> </body> </file> </xliff> diff --git a/typo3/sysext/t3skin/Resources/Public/Css/backend.css b/typo3/sysext/t3skin/Resources/Public/Css/backend.css index 4656599f14066e2440181a4609f040df10ff1fec..ba4800ed70e6c72363fae48454ec34042b4fe7d1 100644 --- a/typo3/sysext/t3skin/Resources/Public/Css/backend.css +++ b/typo3/sysext/t3skin/Resources/Public/Css/backend.css @@ -11347,6 +11347,9 @@ span.warningboxheader { .grideditor div.cell_container:hover { opacity: 0.5; } +.grideditor .grideditor-preview { + margin-top: 5px; +} .grideditor .link { display: block; position: absolute;