From e933bef6f331780b91acd317fafb40f25a48c3f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frank=20Na=CC=88gler?= <frank.naegler@typo3.org> Date: Mon, 18 Jan 2016 16:01:04 +0100 Subject: [PATCH] [TASK] Refactoring of BackendLayoutWizard This patch remove the usage of ExtJS and move the JavaScript logic into the new AMD module: TYPO3/CMS/Backend/GridEditor Old images has been removed and CSS moved into backend.css. Resolves: #72793 Releases: master Change-Id: I13bf37d46941c7cdd094153036cd00e20f89c8e0 Reviewed-on: https://review.typo3.org/46061 Reviewed-by: Benni Mack <benni@typo3.org> Tested-by: Benni Mack <benni@typo3.org> Reviewed-by: Georg Ringer <georg.ringer@gmail.com> Tested-by: Georg Ringer <georg.ringer@gmail.com> --- .../TYPO3/_main_backend_layout_wizard.less | 116 ++++ Build/Resources/Public/Less/backend.less | 1 + .../BackendLayoutWizardController.php | 160 +++-- .../Resources/Public/Css/grideditor.css | 241 ------- .../t3grid-edit-inactive-1.png | Bin 206 -> 0 bytes .../t3grid-edit-inactive.png | Bin 206 -> 0 bytes .../BackendLayoutWizard/t3grid-edit.png | Bin 249 -> 0 bytes .../t3grid-editor-down-inactive.png | Bin 328 -> 0 bytes .../t3grid-editor-down.png | Bin 367 -> 0 bytes .../t3grid-editor-left-inactive.png | Bin 401 -> 0 bytes .../t3grid-editor-left.png | Bin 426 -> 0 bytes .../t3grid-editor-right-inactive.png | Bin 383 -> 0 bytes .../t3grid-editor-right.png | Bin 414 -> 0 bytes .../t3grid-editor-up-inactive.png | Bin 338 -> 0 bytes .../BackendLayoutWizard/t3grid-editor-up.png | Bin 387 -> 0 bytes .../t3grid-layer-icon-close.png | Bin 165 -> 0 bytes .../t3grid-layer-icon-help.png | Bin 194 -> 0 bytes .../t3grid-layer-icon-save.png | Bin 174 -> 0 bytes .../BackendLayoutWizard/t3grid-tabledown.png | Bin 236 -> 0 bytes .../BackendLayoutWizard/t3grid-tableleft.png | Bin 207 -> 0 bytes .../BackendLayoutWizard/t3grid-tableright.png | Bin 258 -> 0 bytes .../BackendLayoutWizard/t3grid-tableup.png | Bin 219 -> 0 bytes .../Resources/Public/JavaScript/GridEditor.js | 640 ++++++++++++++++++ .../Resources/Public/JavaScript/grideditor.js | 635 ----------------- .../t3skin/Resources/Public/Css/backend.css | 101 +++ 25 files changed, 948 insertions(+), 946 deletions(-) create mode 100644 Build/Resources/Public/Less/TYPO3/_main_backend_layout_wizard.less delete mode 100644 typo3/sysext/backend/Resources/Public/Css/grideditor.css delete mode 100644 typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-edit-inactive-1.png delete mode 100644 typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-edit-inactive.png delete mode 100644 typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-edit.png delete mode 100644 typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-editor-down-inactive.png delete mode 100644 typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-editor-down.png delete mode 100644 typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-editor-left-inactive.png delete mode 100644 typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-editor-left.png delete mode 100644 typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-editor-right-inactive.png delete mode 100644 typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-editor-right.png delete mode 100644 typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-editor-up-inactive.png delete mode 100644 typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-editor-up.png delete mode 100644 typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-layer-icon-close.png delete mode 100644 typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-layer-icon-help.png delete mode 100644 typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-layer-icon-save.png delete mode 100644 typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-tabledown.png delete mode 100644 typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-tableleft.png delete mode 100644 typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-tableright.png delete mode 100644 typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-tableup.png create mode 100644 typo3/sysext/backend/Resources/Public/JavaScript/GridEditor.js delete mode 100644 typo3/sysext/backend/Resources/Public/JavaScript/grideditor.js diff --git a/Build/Resources/Public/Less/TYPO3/_main_backend_layout_wizard.less b/Build/Resources/Public/Less/TYPO3/_main_backend_layout_wizard.less new file mode 100644 index 000000000000..830d5aa65ca8 --- /dev/null +++ b/Build/Resources/Public/Less/TYPO3/_main_backend_layout_wizard.less @@ -0,0 +1,116 @@ + +.grideditor { + td { + vertical-align: middle; + &.editor_cell { + height: 100%; + } + } + + table.editor { + border-right: 1px gray dashed; + border-bottom: 1px gray dashed; + + td { + vertical-align: middle; + border-top: 1px gray dashed; + border-left: 1px gray dashed; + text-align: center; + background-color: white; + min-height: 100px; + } + } + + div#editor { + height: 100%; + } + + div.cell_container { + width: 80px; + height: 80px; + position: relative; + left: 50%; + margin-left: -30px; + opacity: 0.3; + } + + div.cell_container:hover { + opacity: 0.5; + } + + .link { + display: block; + position: absolute; + width: 20px; + height: 40px; + overflow: hidden; + opacity: 0.5; + &:hover { + text-decoration: none; + opacity: 1; + } + + &_expand_down, + &_shrink_up { + width: 40px; + height: 20px; + } + + &_expand_right { + left: 52px; + top: 0; + &:before { + font-family: FontAwesome; + content: "@{fa-var-caret-right}"; + font-size: 42px; + line-height: 42px; + } + } + + &_shrink_left { + left: -8px; + top: 0; + &:before { + font-family: FontAwesome; + content: "@{fa-var-caret-left}"; + font-size: 42px; + line-height: 42px; + } + } + + &_expand_down { + left: 12px; + top: 40px; + &:before { + font-family: FontAwesome; + content: "@{fa-var-caret-down}"; + font-size: 42px; + line-height: 19px; + } + } + + &_shrink_up { + left: 12px; + top: -20px; + &:before { + font-family: FontAwesome; + content: "@{fa-var-caret-up}"; + font-size: 42px; + line-height: 20px; + } + } + + &_editor { + width: 40px; + height: 40px; + left: 12px; + top: 0; + &:before { + font-family: FontAwesome; + content: "@{fa-var-pencil-square}"; + font-size: 42px; + line-height: 42px; + } + } + } +} diff --git a/Build/Resources/Public/Less/backend.less b/Build/Resources/Public/Less/backend.less index a8025ca8de67..f6000c8c1a1d 100644 --- a/Build/Resources/Public/Less/backend.less +++ b/Build/Resources/Public/Less/backend.less @@ -60,6 +60,7 @@ @import "TYPO3/_main_body.less"; @import "TYPO3/_main_content.less"; @import "TYPO3/_main_elementbrowser.less"; +@import "TYPO3/_main_backend_layout_wizard"; @import "TYPO3/_main_form.less"; @import "TYPO3/_main_scaffolding.less"; @import "TYPO3/_module_menu.less"; diff --git a/typo3/sysext/backend/Classes/Controller/BackendLayoutWizardController.php b/typo3/sysext/backend/Classes/Controller/BackendLayoutWizardController.php index fea863f63564..c54cc03d2f5f 100644 --- a/typo3/sysext/backend/Classes/Controller/BackendLayoutWizardController.php +++ b/typo3/sysext/backend/Classes/Controller/BackendLayoutWizardController.php @@ -22,7 +22,6 @@ 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\ExtensionManagementUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; /** @@ -30,15 +29,15 @@ use TYPO3\CMS\Core\Utility\GeneralUtility; */ class BackendLayoutWizardController extends AbstractModule { - // GET vars: - // Wizard parameters, coming from TCEforms linking to the wizard. /** + * GET vars: + * Wizard parameters, coming from TCEforms linking to the wizard. * @var array */ public $P; - // Accumulated content. /** + * Accumulated content. * @var string */ public $content; @@ -53,6 +52,21 @@ class BackendLayoutWizardController extends AbstractModule */ public $fieldName; + /** + * @var array + */ + protected $rows; + + /** + * @var int + */ + protected $colCount; + + /** + * @var int + */ + protected $rowCount; + /** * Constructor */ @@ -85,10 +99,7 @@ class BackendLayoutWizardController extends AbstractModule /** @var \TYPO3\CMS\Core\Page\PageRenderer $pageRenderer */ $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class); - $pageRenderer->loadExtJS(); - $pageRenderer->addJsFile(ExtensionManagementUtility::extRelPath('backend') - . 'Resources/Public/JavaScript/grideditor.js'); - $pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Tooltip'); + $pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/GridEditor'); $pageRenderer->addInlineSetting( 'ContextHelp', 'moduleUrl', @@ -103,24 +114,28 @@ class BackendLayoutWizardController extends AbstractModule ) ); $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); + 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' => $lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_labelSave', true), - 'title' => $lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_windowTitle', true), - 'editCell' => $lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_editCell', true), - 'mergeCell' => $lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_mergeCell', true), - 'splitCell' => $lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_splitCell', true), - 'name' => $lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_name', true), - 'column' => $lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_column', true), - 'notSet' => $lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_notSet', true), - 'nameHelp' => $lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_nameHelp', true), - 'columnHelp' => $lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_columnHelp', true) + '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 @@ -199,18 +214,9 @@ class BackendLayoutWizardController extends AbstractModule } } } - $pageRenderer->addExtOnReadyCode(' - t3Grid = new TYPO3.Backend.t3Grid({ - data: ' . json_encode($rows, JSON_HEX_QUOT | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS) . ', - colCount: ' . (int)$colCount . ', - rowCount: ' . (int)$rowCount . ', - targetElement: \'editor\' - }); - t3Grid.drawTable(); - '); - - $this->moduleTemplate->getPageRenderer()->addCssFile(ExtensionManagementUtility::extRelPath('backend') - . 'Resources/Public/Css/grideditor.css'); + $this->rows = $rows; + $this->colCount = (int)$colCount; + $this->rowCount = (int)$rowCount; } /** @@ -265,21 +271,18 @@ class BackendLayoutWizardController extends AbstractModule $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar(); $lang = $this->getLanguageService(); - $resourcePath = ExtensionManagementUtility::extRelPath('backend') - . 'Resources/Public/Images/BackendLayoutWizard/'; - $saveButton = $buttonBar->makeInputButton() ->setName('_savedok') ->setValue('1') ->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveDoc')) - ->setOnClick('storeData(t3Grid.export2LayoutRecord());return true;') + ->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')) - ->setOnClick('storeData(t3Grid.export2LayoutRecord());window.close();return true;') + ->setClasses('t3js-grideditor-savedokclose') ->setIcon( $this->moduleTemplate->getIconFactory()->getIcon('actions-document-save-close', Icon::SIZE_SMALL) ); @@ -296,34 +299,51 @@ class BackendLayoutWizardController extends AbstractModule ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-close', Icon::SIZE_SMALL)); $buttonBar->addButton($closeButton, ButtonBar::BUTTON_POSITION_LEFT, 30); - $this->content .= ' - <table border="0" width="90%" height="90%" id="outer_container"> - <tr> - <td class="editor_cell"> - <div id="editor"> - </div> - </td> - <td width="20" valign="center"> - <a class="addCol" href="#" title="' . $lang->getLL('grid_addColumn') . '" onclick="t3Grid.addColumn(); t3Grid.drawTable(\'editor\');"> - <img src="' . $resourcePath . 't3grid-tableright.png" border="0" /> - </a><br /> - <a class="removeCol" href="#" title="' . $lang->getLL('grid_removeColumn') . '" onclick="t3Grid.removeColumn(); t3Grid.drawTable(\'editor\');"> - <img src="' . $resourcePath . 't3grid-tableleft.png" border="0" /> - </a> - </td> - </tr> - <tr> - <td colspan="2" height="20" align="center"> - <a class="addCol" href="#" title="' . $lang->getLL('grid_addRow') . '" onclick="t3Grid.addRow(); t3Grid.drawTable(\'editor\');"> - <img src="' . $resourcePath . 't3grid-tabledown.png" border="0" /> - </a> - <a class="removeCol" href="#" title="' . $lang->getLL('grid_removeRow') . '" onclick="t3Grid.removeRow(); t3Grid.drawTable(\'editor\');"> - <img src="' . $resourcePath . 't3grid-tableup.png" border="0" /> - </a> - </td> - </tr> - </table> - '; + $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); } /** diff --git a/typo3/sysext/backend/Resources/Public/Css/grideditor.css b/typo3/sysext/backend/Resources/Public/Css/grideditor.css deleted file mode 100644 index ce087003a4c8..000000000000 --- a/typo3/sysext/backend/Resources/Public/Css/grideditor.css +++ /dev/null @@ -1,241 +0,0 @@ -* { - padding: 0; - margin: 0; - position: relative; -} - -body { padding: 10px; } - -table#outer_container td, table#editor td { - vertical-align: middle; -} - -table#outer_container td.editor_cell { - height: 100%; -} - -table.editor { - border-right: 1px gray dashed; - border-bottom: 1px gray dashed; -} - -table.editor td { - border-top: 1px gray dashed; - border-left: 1px gray dashed; - text-align: center; - z-index: 2000; - background-color: white; - min-height: 100px; -} - -div#editor { - height: 100%; -} - -div.cell_container { - width: 60px; - height: 60px; - position: relative; - left: 50%; - margin-left: -30px; - opacity: 0.3; -} - -div.cell_container:hover { - opacity: 1; -} - -.link_expand_right, .link_shrink_left, .link_expand_down, .link_shrink_up, .link_editor { - display: block; - position: absolute; - width: 14px; - height: 32px; - z-index: 1100; -} - -.link_expand_down, .link_shrink_up { - width: 32px; - height: 14px; -} - -.link_expand_right { - background-image: url(../Images/BackendLayoutWizard/t3grid-editor-right-inactive.png); - left: 46px; - top: 14px; -} - -.link_expand_right:hover { - background-image: url(../Images/BackendLayoutWizard/t3grid-editor-right.png); -} - - -.link_shrink_left { - background-image: url(../Images/BackendLayoutWizard/t3grid-editor-left-inactive.png); - left: 0px; - top: 14px; -} - -.link_shrink_left:hover { - background-image: url(../Images/BackendLayoutWizard/t3grid-editor-left.png); -} - -.link_expand_down { - background-image: url(../Images/BackendLayoutWizard/t3grid-editor-down-inactive.png); - left: 14px; - top: 46px; -} - -.link_expand_down:hover { - background-image: url(../Images/BackendLayoutWizard/t3grid-editor-down.png); -} - -.link_shrink_up { - background-image: url(../Images/BackendLayoutWizard/t3grid-editor-up-inactive.png); - left: 14px; - top: 0px; -} - -.link_shrink_up:hover { - background-image: url(../Images/BackendLayoutWizard/t3grid-editor-up.png); -} - -.link_editor { - background-image: url(../Images/BackendLayoutWizard/t3grid-edit-inactive.png); - width: 32px; - height: 32px; - left: 14px; - top: 14px; -} - -.link_editor:hover { - background-image: url(../Images/BackendLayoutWizard/t3grid-edit.png); -} - -.question { - background-image: url(../Images/BackendLayoutWizard/t3grid-layer-icon-help.png) !important; -} - -.save { - background-image: url(../Images/BackendLayoutWizard/t3grid-layer-icon-save.png) !important; -} - -.cancel { - background-image: url(../Images/BackendLayoutWizard/t3grid-layer-icon-close.png) !important; -} - -table#outer_container td, table#editor td { - vertical-align: middle; -} - -table#outer_container td.editor_cell { - height: 100%; -} - -table.editor { - border-right: 1px gray dashed; - border-bottom: 1px gray dashed; -} - -table.editor td { - border-top: 1px gray dashed; - border-left: 1px gray dashed; - text-align: center; - z-index: 2000; - background-color: white; - min-height: 100px; -} - -div#editor { - height: 100%; -} - -div.cell_container { - width: 60px; - height: 60px; - position: relative; - left: 50%; - margin-left: -30px; - opacity: 0.3; -} - -div.cell_container:hover { - opacity: 1; -} - -.link_expand_right, .link_shrink_left, .link_expand_down, .link_shrink_up, .link_editor { - display: block; - position: absolute; - width: 14px; - height: 32px; - z-index: 1100; -} - -.link_expand_down, .link_shrink_up { - width: 32px; - height: 14px; -} - -.link_expand_right { - background-image: url(../Images/BackendLayoutWizard/t3grid-editor-right-inactive.png); - left: 46px; - top: 14px; -} - -.link_expand_right:hover { - background-image: url(../Images/BackendLayoutWizard/t3grid-editor-right.png); -} - - -.link_shrink_left { - background-image: url(../Images/BackendLayoutWizard/t3grid-editor-left-inactive.png); - left: 0px; - top: 14px; -} - -.link_shrink_left:hover { - background-image: url(../Images/BackendLayoutWizard/t3grid-editor-left.png); -} - -.link_expand_down { - background-image: url(../Images/BackendLayoutWizard/t3grid-editor-down-inactive.png); - left: 14px; - top: 46px; -} - -.link_expand_down:hover { - background-image: url(../Images/BackendLayoutWizard/t3grid-editor-down.png); -} - -.link_shrink_up { - background-image: url(../Images/BackendLayoutWizard/t3grid-editor-up-inactive.png); - left: 14px; - top: 0px; -} - -.link_shrink_up:hover { - background-image: url(../Images/BackendLayoutWizard/t3grid-editor-up.png); -} - -.link_editor { - background-image: url(../Images/BackendLayoutWizard/t3grid-edit-inactive.png); - width: 32px; - height: 32px; - left: 14px; - top: 14px; -} - -.link_editor:hover { - background-image: url(../Images/BackendLayoutWizard/t3grid-edit.png); -} - -.question { - background-image: url(../Images/BackendLayoutWizard/t3grid-layer-icon-help.png) !important; -} - -.save { - background-image: url(../Images/BackendLayoutWizard/t3grid-layer-icon-save.png) !important; -} - -.cancel { - background-image: url(../Images/BackendLayoutWizard/t3grid-layer-icon-close.png) !important; -} diff --git a/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-edit-inactive-1.png b/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-edit-inactive-1.png deleted file mode 100644 index 077cd7718777ac5aa1ac49d481a447516dc7cf9a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 206 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UQ$1ZALp+WrYy9_@OwsuN-jh+r zG+~M41MiuP`~LTCkaAoCq<8<@o^0Br!EEzy{;&Vv>M#F~(s2_=WN`Vt^1u7P@ClEZ zTE5+V(!#i@jQ>(H<FdaRes3#y6>_ZOm^(Jg_A|=;w`VjJ-ZZy?ael{zzRL`33%<Q} zc;T3rmc-!1ue7Cqn#bXj4I-PiE^pw?Sg@q%yd49>8ZDnQ-EJ3810BfV>FVdQ&MBb@ E0M-;zkN^Mx diff --git a/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-edit-inactive.png b/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-edit-inactive.png deleted file mode 100644 index 077cd7718777ac5aa1ac49d481a447516dc7cf9a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 206 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UQ$1ZALp+WrYy9_@OwsuN-jh+r zG+~M41MiuP`~LTCkaAoCq<8<@o^0Br!EEzy{;&Vv>M#F~(s2_=WN`Vt^1u7P@ClEZ zTE5+V(!#i@jQ>(H<FdaRes3#y6>_ZOm^(Jg_A|=;w`VjJ-ZZy?ael{zzRL`33%<Q} zc;T3rmc-!1ue7Cqn#bXj4I-PiE^pw?Sg@q%yd49>8ZDnQ-EJ3810BfV>FVdQ&MBb@ E0M-;zkN^Mx diff --git a/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-edit.png b/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-edit.png deleted file mode 100644 index 98a0ab12a3437ae884a3f88c690e1d7384a49ad2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 249 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dy_5nU2uI1(B+1c4;_KbBdj6ph# z{|}S{W&VG-|Np|wl#~>ptf!~v|8;@?UtPLd$auGm@k}n`kxa%%6^#FPW&hui;koFa z0Z;=|NswP~!+~oh(+>lA>7Fi*Ar)~?FT3*{P~dTOeB|V-``tc!lk>IdXBa<x>lNhY zC^cAUR=$kQhC$~I(?0%0_6d2vHSaK%)#?{BeY<*((b|+{uYEl`!*7lPc}CT(zd0to sWJo%7vxH${#v}LWJ#kqQfBrvZKFy_-bH*-39cU$kr>mdKI;Vst08@lspa1{> diff --git a/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-editor-down-inactive.png b/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-editor-down-inactive.png deleted file mode 100644 index 72a6782a0179f42e349738521ad4dec32fe2be07..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 328 zcmV-O0k{5%P)<h;3K|Lk000e1NJLTq001BW000gM1^@s6PTU@{0003GNkl<Zc-p<r zJ4?fG6o&EtH_$;5DT-1QFHq3I$-$4+OYTMy92_hNqM$>UE*-={hfW1Y2R}}e9v{T^ zgg}}^+YZ0sEbn=Yh?uJ|yoM~;t?>IN;4%o7a06M8HkKy=7rt+>f;ME%?y(9p2?#xJ zYz=piIeEl73^d@}b(1Q1fXvu4HWGg{AaI<tO*}znq=T*04-N2bTd8eyApg`w6(&Uk zJj=>bMHeH;AM~)Bv8@4at2NCIdWazfjqrl~DZ3iraOBv-D<Vja7;iYt+tq+(vxoz{ zV+hF*p^sXDJq@rMjiPGkV+cu!Fu-xaEe){h^)ikyKm_>};{zvUw#o;nQ+y@@zHkOp aHsBljb*U93{_EcW0000<MNUMnLSTZ4YlL9{ diff --git a/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-editor-down.png b/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-editor-down.png deleted file mode 100644 index 13b5e706365085d3ea2ea48d600d891378420a6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 367 zcmV-#0g(QQP)<h;3K|Lk000e1NJLTq001BW000gM1^@s6PTU@{0003tNkl<Zc-p<w zy-LGi6vpw~fewm@C`wWMfPxNA4zBrVo7Bs4a8M9LL5D6~I*5Y~P6bB?FQ-Y4|7S>P zV-gjT4!<+xeb0Fg331HKx#;&VVGDMx>}-LheiU877UYJ^<>>;#!<C2wSi|nfTFr7* zrZ`*+!|)c?kOwl>XERmiaA~90>)pd@_QdSXe4fe=T;A$-yN|G%44AoHl%-OLrkzfw zGl0!uASwfMJwu+g%5qdn(cHoiDGX_j{bGc@s*LP6)L-C4;5+FP=nZHA*~JJ+5CoZ2 zDuPoy;{ckanVPK(WhwKI3xKeFydajDC9FV#R~)Igt_2+5_Yd)g31XzMoEYzDtEcV- zqzwg3O2WrDfz!+a@I3DrW5h5>f)AYPPSXoGuIrxR69)Ohxz7H(z&At}6{-&%dzSzJ N002ovPDHLkV1oF0qdNcq diff --git a/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-editor-left-inactive.png b/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-editor-left-inactive.png deleted file mode 100644 index 64e32a2e6877cd798ce380eac638685cd67a6475..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 401 zcmV;C0dD?@P)<h;3K|Lk000e1NJLTq000gE001Be1^@s6BJN3-00044Nkl<Zc-o!O zJ4-@w9LDjp2T>su1rZ1l6hz?A(9o+>QB(1nnwr;>dLo5_8eD2<Z0NmsOZ@c}6|cv? zI()Y0J3X3+Y(zPz8OE#~gp^^mQkk@eF#eR`OSwE^K>}@vGJGzT`VNpr3j%d$==vdY zXhMdTN0nmn7&@Ae3Fc9`P_V*43o>JI^pww^qJ}nPf%!<!X3z184#dQCRLEp5@qsR6 ziE)%qr){XC2T>SAxm4;JpO95)nPl=7-;i}^kBP)DWL;V+9+ypM$yiJ_p*=*SKah24 z@krzbUywBn?udm#Hq;@jA_Str;1%A{gQyUVMFN2fyrBzOhG1IQ?>|Eo9f%pm^MXE~ z6$V<6MHns?@On?6qY0VC$eiEfIYJf<$Rq~K`P}Y(q|ks2sY9>J)n~yy8W5<%JEwDG v7hyD^4&4sNq;2@nR)#LSebyG-CV|>N2b|P9e8v(u00000NkvXXu0mjfdeE#Q diff --git a/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-editor-left.png b/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-editor-left.png deleted file mode 100644 index b68f4d5944affd7e2695777668f76dad7ee2b6ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 426 zcmV;b0agBqP)<h;3K|Lk000e1NJLTq000gE001Be1^@s6BJN3-00009a7bBm000XU z000XU0RWnu7ytkPTuDShR5;6>)k`bHQ5?qc?=y0ll#n7yN=Z>D3k%AnkSr{exs-)z zOxgX-*b_B|)x3szK^ET6JQj15(9HS&Po2){)44srb7Y$=O|@E$oP;El%k{?4+wJxr z@X%;XN_t5J8}<6Mq-WqZ8rJXcXCyU&YhWY_CP^|EP!Sl7+GCO=^FRx@1jeEcN77<I z7eCP;xE#>=_wr)k3h)k`0wb~axE5wQ28Lq;uz~c3eFO}}CTAO|1snj1jogml4cJSQ z)qP1#?47hB|FpfHx;m=WYNoo%4l9+)hosFcaMyNIu$va*Zg<;uOK_MLVtdQb3{g`W zNY`FBv;-#uBlinpdlh&E&iaP@ABgR~wb&10dx_qj|5X1Vi0y@dFM)hC>~uPm%jMaC z3qSEd2v9DSW^BKNH#Hv(0ZPT<RKPdDSTqDE777!#pMbkm5TI~%HQu!!mGztZ0+l~4 UoZlY3t^fc407*qoM6N<$f`=!zzW@LL diff --git a/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-editor-right-inactive.png b/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-editor-right-inactive.png deleted file mode 100644 index c67ec41db010f139e392425211751424baf822e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 383 zcmV-_0f7FAP)<h;3K|Lk000e1NJLTq000gE001Be1^@s6BJN3-0003-Nkl<Zc-o!P zyK+GR5XSL+2{U@V-i%hQ*K5<I%1lZOf<YJrAue%=TwcUWU=$RmF}g3`BxjPtIv1z- zZTD|>SH2dD0Ers_C**TJKTwdwfet@rGmt?c5*s>vpH5-gQ<&re9llK_u-H<B<ctpI z<1x;xDMn(U!`Wzr3sw{-G3jtR9Kyzm5+tO<*TDb|Hk2eCj{AMM*wT#(hrJ#=*wO7t zIOulakwJHV;Y+83D;(+mC+xM`@F6PCtrmP(N~hU`AJT3#;KNd$>UH=Km1eDmD;()} ztBq<E9vSq1$9km#4|a6=Ikj>bF1Dn9^|4ffgAFA~R9Gn%VPi!J64GJ0P{0K%ij$ah zSjy*dW=$~?3mq17Iaq8dLUKljg=`k4J%vdw(BVTS12QN?Vnc_yboxL+5(hfWrcwbC d7dqtd<r`xSklfUZvS|PS002ovPDHLkV1l+#oMQk0 diff --git a/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-editor-right.png b/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-editor-right.png deleted file mode 100644 index 6bb63b25d53c4daf0accac146da035bcf3a5bfe3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 414 zcmV;P0b%}$P)<h;3K|Lk000e1NJLTq000gE001Be1^@s6BJN3-0004HNkl<Zc-ocK zy>7xV6o%n*6P3Dm?_P<ub0_`+#33QXBq98j35i?eCIZR;Ll(q#`e7kN!AYFqO(fgT z=wtd_t=^cK%8J5}!pVdtQc@5EG#-!X3eT(M^1U_$Vw5iyi;r3mfN!1V^ZBPS#9@9Y zo6TllMi2-2sXh9xgh`UHrWE~@!s&F%1*OO;gmD~mNeAR>VH8DNS{!G9$qNj_kgEbZ zqV<0$B^#ClZthS90UIaf1#qh%KCEjr8fn)7um1-5zR#KzEZPIykp?`c#iTZC=6T+Z zJlADiIG|m35nzK{$6?ckj&pH`!!00@g9Vd-a<l;?1%(h?l`X{45n>HUcWB!-SCpXy zkp98JV8A6EkPk>Nu;1@<K`B!AQ44#$9&1XGngE5+vMhdT52R*JDeQJS{7`0fyK2f+ z!cM!*w@!d+t{TC1tHme>RFm8oHk-{epn5y%LiJkJg~gzvKRg(a7G?hSeE<Le07*qo IM6N<$f+07vCjbBd diff --git a/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-editor-up-inactive.png b/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-editor-up-inactive.png deleted file mode 100644 index b9438a7cde2262599573ba932e6bd696c2dd39d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 338 zcmV-Y0j>UtP)<h;3K|Lk000e1NJLTq001BW000gM1^@s6PTU@{0003QNkl<ZNXNC* z&q@MO6vy##Owx8DK^P(=YAAuwMnod0MM027=)$0Oy+`EV?1kJ&Pvc{Z--~BpkgLrZ zr-9E#ulM}UJ=bwP&vO>@xmE+e@Wc}D5%zIhhsT6axWEiofzM7bKwr7nI)LJ-V}cvY zcX^D^(`=|Yfph8de#e>u#&}kpK!}B9DgGE@Z4pyhn}}lsXBeOp@>CP@n;9OE+-C$u z>AVA1ak)(ACAqA3IEXTWQ+(kGDedi+5EcC3cH17?0{DNc7aT??9#oYO*R~M00LK`j zi}aqweKiST-W|zZ0dmrL51E*X+g@O<EkIU^zv3w7;=TsH(cTPTihttmA3EQ3i3wW4 k0H*Vg7-#;Mri`Px0+?Z6_l)5}YybcN07*qoM6N<$g5|50!~g&Q diff --git a/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-editor-up.png b/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-editor-up.png deleted file mode 100644 index 24022ca2737de22d40d08d7e098e0b2ca569f3ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 387 zcmV-}0et?6P)<h;3K|Lk000e1NJLTq001BW000gM1^@s6PTU@{0003>Nkl<Zc-p<w zPe%lC9LMorZ9RaMhz=1EiH_+INkkG|I&|qt%%9)PZ)P7vBpnhRBBE2LE?w#p5mAbW z^a$F`(tLZ*Sjmpj&hE?}UWS?P@ALiGolzp9YGIhy9IhZOAJ~D)D=A>xwsIUtxvs0U z*2;tLdCK>FWsFflEC>>{AeiOgC8W(ew!>r&oG~CH&Pp;h*b(nac3PH|uK?jQxPWAM z!&X@Zrg0AW$166AE--~NNCzUkV1u&*MHHCCDZU{citvneGAg|knDC7`K@*ZwgeNlA z$QtUVz&MAGxqd;qMaCo7RWgUO3ZyVR#-Sr$>jtD(WId3%qAAg~D_wx0QHBpuhZN|Z z>}7s|N@f8bjxcn9Pe=*w*s;W4FqkU9%_<M~QHPZ1mR*ajy}vJEm7BY0K>FZ@oeO^p h?4b$iqieo``5%)HqVwVp^`HO%002ovPDHLkV1n2#sHp$| diff --git a/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-layer-icon-close.png b/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-layer-icon-close.png deleted file mode 100644 index 6c52209da40c99c38e52e968d2d4f93a84a53ebb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 165 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPGa3-AeX)z{aTk&$WcTM!bF`0wAp z_wT=4xqjc;-hJo3Q}-V|+uR+wAE?sF)5S4_BRV-jgoT-rO;OdrAVr{vky+uesR+lR z0Evfd1(zncxwuwqyR6!)Br=t8dXx4sgY+mV4hG3%2?-|{irE-0FH)$zEM##DXc~j3 LtDnm{r-UW|ZY4Er diff --git a/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-layer-icon-help.png b/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-layer-icon-help.png deleted file mode 100644 index b5b79e078af7c7d12ecdf61b0806675c23f6627d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 194 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!aez;VtG>Rzr>Ez`M=xb$WZu93 z5)zSk<@)`Iq{`;L1%8o5|Ni~E|LED)okyq4T2)Zd>l;y6-8}86k>CoTb}vsC$B>G+ z+VhcI2Mjn|FWQ(oKYv%hb*h7}%7eeB9hsLM(W^BV*M75Dxm;lN9|!4xOr|+SjLchD r^Y%OO-}@P?J+EUygzTp7>7VWIZDLi;<T5k@n#$nm>gTe~DWM4f!PQAb diff --git a/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-layer-icon-save.png b/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-layer-icon-save.png deleted file mode 100644 index af37bcda998fc3d9782fcc69c83ee68d00a807f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!Vt`MGtEZ=@zP`SUj7&&G;{SGr z=Dr30{{4IK`1!$O=Rbb_YHDfY_uPmPsMy2P#WAGf*4FceVhsiyE(Z^ACB3UpFyD2| zWSXDUCwbnrGxc-+Z1hbiWC^nPCHqav|Kal9hL%IGi<yt7a^9Rg&*5sf!@Ae%){Lf6 WEG8KTlRANBGI+ZBxvX<aXaWG>>pv3! diff --git a/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-tabledown.png b/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-tabledown.png deleted file mode 100644 index 674e479fba7d440d6b1aff3d51515ca16441be78..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 236 zcmV<I02BX-P)<h;3K|Lk000e1NJLTq000pH000OG1^@s6AG8#y00029Nkl<Zc-ocB zxedZV5J1rpc1R6NOe?<ksDYLM$F$;r$b>k866j$0gJj9FYyrX3NIN@ULI?*uG2s5E z2aXcF-+JdRh)cSz)468w-tUEyIOjIj+7@w+h|VRwv(^xiPlTfInACOMA}T$e8+YiN zrZGfh9ubyFS(Yv0h+~~oeN|P4h^$3~PiavUXGCa3=cs3Ih{(5y@Hx%%yhWV2!RY?i mh;Wc*S$4t;SM2nCDe?xsD%F^`NucBa0000<MNUMnLSTZckY^kK diff --git a/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-tableleft.png b/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-tableleft.png deleted file mode 100644 index 763d37023f93bf93285e3185369cd8d57080d117..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 207 zcmV;=05JcFP)<h;3K|Lk000e1NJLTq000L7000jN1^@s6C;`>J0001%Nkl<ZD9?4v zF%H5o5Jb_x>mzX)%1Bn?f|d>>D4^j0kTM72GLaD7t|=m{keKO4Z$?r|1XVNyR25a7 zy6RE>;1$@{@C=-Q*Al+~FwSufKe&W~2jIdwqqJ@N1U3Lo(-awoVU!qSN6vR3te!DO z+^oy692CUdy9^Hjtsy=QdI6~+Zk96iz`KUH*)GGaj_#QI_5-Bva^4dZF0}vv002ov JPDHLkV1k|#PtgDX diff --git a/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-tableright.png b/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-tableright.png deleted file mode 100644 index e425e73921f961b8a6ce7a1780c741c684c933f1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 258 zcmV+d0sa1oP)<h;3K|Lk000e1NJLTq000L7000jN1^@s6C;`>J0002VNkl<ZD9>$B zOAdlS3~dJzJr7qAjo<;;xG}`Lu)wg>oeSX#Z1F6v4AHi>WTHT9^71<K`p09Q7sR|* zyqOsW5P`nIkw^vr7X`x191%S<AXfi87eg!KZL1K)&htbxOFRz&&YBz2GzIS`zJ&{E zlu6ST0k&-`^FgYr8aM!v!@cX4Q53<cEJ1z!k{%FO|H}3baidG$zS9;(F$jpb)~tHI ziV3lz`5l31q5QH841#8QKIW$|+vv3hz!+9G6U3|70YoO^2M^hP=PW`Z<p2Nx07*qo IM6N<$f{Z?ACIA2c diff --git a/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-tableup.png b/typo3/sysext/backend/Resources/Public/Images/BackendLayoutWizard/t3grid-tableup.png deleted file mode 100644 index 056cf582669b4ddceeb926fe4b76e03d978a1d37..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 219 zcmV<103`p3P)<h;3K|Lk000e1NJLTq000pH000OG1^@s6AG8#y0001@Nkl<Zc-o!J zy$!-J5J2G*Ny!YRW|jQdiR~F!32@CSDX2_IsxSf@m?xx25h6e+zQVq{C(b#sZ7WUF zh}K%_x|Xsmr6`IG&bZ^iUtU$!b8d{0mK$rWc<$#S3Kyh_KqUV)qF9bdZycHD-y({o zi1a}qlFdaF!-zEMx()#EsX!!qjVL}N(gK0VYK&~1wLQ`wPDIw?z29TNb)g<N>>i$2 V%{dWF=(qp?002ovPDHLkV1g!lSXTf5 diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/GridEditor.js b/typo3/sysext/backend/Resources/Public/JavaScript/GridEditor.js new file mode 100644 index 000000000000..37783910f3e2 --- /dev/null +++ b/typo3/sysext/backend/Resources/Public/JavaScript/GridEditor.js @@ -0,0 +1,640 @@ +/* + * 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! + */ + +/** + * Module: TYPO3/CMS/Backend/GridEditor + */ +define(['jquery', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Severity', 'bootstrap'], function($, Modal, Severity) { + 'use strict'; + + /** + * The main ContextHelp object + * + * @type {{colCount: number, rowCount: number, data: {}, nameLabel: string, columnLabel: string, targetElement: null}} + * @exports TYPO3/CMS/Backend/GridEditor + */ + var GridEditor = { + selectorEditor: '.t3js-grideditor', + selectorAddColumn: '.t3js-grideditor-addcolumn', + selectorRemoveColumn: '.t3js-grideditor-removecolumn', + selectorAddRow: '.t3js-grideditor-addrow', + selectorRemoveRow: '.t3js-grideditor-removerow', + selectorLinkEditor: '.t3js-grideditor-link-editor', + selectorLinkExpandRight: '.t3js-grideditor-link-expand-right', + selectorLinkShrinkLeft: '.t3js-grideditor-link-shrink-left', + selectorLinkExpandDown: '.t3js-grideditor-link-expand-down', + selectorLinkShrinkUp: '.t3js-grideditor-link-shrink-up', + selectorDocHeaderSave: '.t3js-grideditor-savedok', + selectorDocHeaderSaveClose: '.t3js-grideditor-savedokclose', + colCount: 1, + rowCount: 1, + data: [], + nameLabel: 'name', + columnLabel: 'columen label', + targetElement: null + }; + + /** + * + * @param {Object} config + */ + GridEditor.initialize = function(config) { + config = config || {}; + var $element = $(GridEditor.selectorEditor); + GridEditor.colCount = $element.data('colcount'); + GridEditor.rowCount = $element.data('rowcount'); + GridEditor.data = $element.data('data'); + GridEditor.nameLabel = config.nameLabel || 'Name'; + GridEditor.columnLabel = config.columnLabel || 'Column'; + GridEditor.targetElement = $(GridEditor.selectorEditor); + + $(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(); + }); + $(document).on('click', GridEditor.selectorRemoveColumn, function(e) { + e.preventDefault(); + GridEditor.removeColumn(); + GridEditor.drawTable(); + }); + $(document).on('click', GridEditor.selectorAddRow, function(e) { + e.preventDefault(); + GridEditor.addRow(); + GridEditor.drawTable(); + }); + $(document).on('click', GridEditor.selectorRemoveRow, function(e) { + e.preventDefault(); + GridEditor.removeRow(); + GridEditor.drawTable(); + }); + $(document).on('click', GridEditor.selectorLinkEditor, function(e) { + e.preventDefault(); + var $element = $(this); + var col = $element.data('col'); + var row = $element.data('row'); + GridEditor.showOptions(col, row); + }); + $(document).on('click', GridEditor.selectorLinkExpandRight, function(e) { + e.preventDefault(); + var $element = $(this); + var col = $element.data('col'); + var row = $element.data('row'); + GridEditor.addColspan(col, row); + GridEditor.drawTable(); + }); + $(document).on('click', GridEditor.selectorLinkShrinkLeft, function(e) { + e.preventDefault(); + var $element = $(this); + var col = $element.data('col'); + var row = $element.data('row'); + GridEditor.removeColspan(col, row); + GridEditor.drawTable(); + }); + $(document).on('click', GridEditor.selectorLinkExpandDown, function(e) { + e.preventDefault(); + var $element = $(this); + var col = $element.data('col'); + var row = $element.data('row'); + GridEditor.addRowspan(col, row); + GridEditor.drawTable(); + }); + $(document).on('click', GridEditor.selectorLinkShrinkUp, function(e) { + e.preventDefault(); + var $element = $(this); + var col = $element.data('col'); + var row = $element.data('row'); + GridEditor.removeRowspan(col, row); + GridEditor.drawTable(); + }); + + GridEditor.drawTable(); + }; + + /** + * Add a new row + */ + GridEditor.addRow = function() { + var newRow = []; + for (var i = 0; i < GridEditor.colCount; i++) { + newRow[i] = {spanned: false, rowspan: 1, colspan: 1}; + } + GridEditor.data.push(newRow); + GridEditor.rowCount++; + }; + + /** + * Removes the last row of the grid and adjusts all cells that might be effected + * by that change. (Removing colspans) + */ + GridEditor.removeRow = function() { + if (GridEditor.rowCount <= 1) { + return false; + } + var newData = []; + for (var rowIndex = 0; rowIndex < GridEditor.rowCount - 1; rowIndex++) { + newData.push(GridEditor.data[rowIndex]); + } + + // fix rowspan in former last row + for (var colIndex = 0; colIndex < GridEditor.colCount; colIndex++) { + if (GridEditor.data[GridEditor.rowCount - 1][colIndex].spanned == true) { + GridEditor.findUpperCellWidthRowspanAndDecreaseByOne(colIndex, GridEditor.rowCount - 1); + } + } + + GridEditor.data = newData; + GridEditor.rowCount--; + }; + + /** + * Takes a cell and looks above it if there are any cells that have colspans that + * spans into the given cell. This is used when a row was removed from the grid + * to make sure that no cell with wrong colspans exists in the grid. + * + * @param {Integer} col + * @param {Integer} row integer + */ + GridEditor.findUpperCellWidthRowspanAndDecreaseByOne = function(col, row) { + var upperCell = GridEditor.getCell(col, row - 1); + if (!upperCell) { + return false; + } + + if (upperCell.spanned == true) { + GridEditor.findUpperCellWidthRowspanAndDecreaseByOne(col, row - 1); + } else { + if (upperCell.rowspan > 1) { + GridEditor.removeRowspan(col, row - 1); + } + } + }; + + /** + * Removes the outermost right column from the grid. + */ + GridEditor.removeColumn = function() { + if (GridEditor.colCount <= 1) { + return false; + } + var newData = []; + + for (var rowIndex = 0; rowIndex < GridEditor.rowCount; rowIndex++) { + var newRow = []; + for (var colIndex = 0; colIndex < GridEditor.colCount - 1; colIndex++) { + newRow.push(GridEditor.data[rowIndex][colIndex]); + } + if (GridEditor.data[rowIndex][GridEditor.colCount - 1].spanned == true) { + GridEditor.findLeftCellWidthColspanAndDecreaseByOne(GridEditor.colCount - 1, rowIndex); + } + newData.push(newRow); + } + + GridEditor.data = newData; + GridEditor.colCount--; + }; + + /** + * Checks if there are any cells on the left side of a given cell with a + * rowspan that spans over the given cell. + * + * @param {Integer} col + * @param {Integer} row + */ + GridEditor.findLeftCellWidthColspanAndDecreaseByOne = function(col, row) { + var leftCell = GridEditor.getCell(col - 1, row); + if (!leftCell) { + return false; + } + + if (leftCell.spanned == true) { + GridEditor.findLeftCellWidthColspanAndDecreaseByOne(col - 1, row); + } else { + if (leftCell.colspan > 1) { + GridEditor.removeColspan(col - 1, row); + } + } + }; + + /** + * Adds a column at the right side of the grid. + */ + GridEditor.addColumn = function() { + for (var rowIndex = 0; rowIndex < GridEditor.rowCount; rowIndex++) { + GridEditor.data[rowIndex].push({ + spanned: false, + rowspan: 1, + colspan: 1, + name: GridEditor.colCount + 'x' + rowIndex + }); + } + GridEditor.colCount++; + }; + + /** + * Draws the grid as table into a given container. + * It also adds all needed links and bindings to the cells to make it editable. + */ + GridEditor.drawTable = function() { + var col; + var $colgroup = $('<colgroup>'); + for (col = 0; col < GridEditor.colCount; col++) { + $colgroup.append($('<col>').css({ + width: parseInt(100 / GridEditor.colCount, 10) + '%' + })); + } + var $table = $('<table id="base" class="table editor">'); + $table.append($colgroup); + + for (var row = 0; row < GridEditor.rowCount; row++) { + var rowData = GridEditor.data[row]; + if (rowData.length == 0) { + continue; + } + + var $row = $('<tr>'); + + for (col = 0; col < GridEditor.colCount; col++) { + var cell = GridEditor.data[row][col]; + if (cell.spanned == true) { + continue; + } + var $cell = $('<td>').css({ + height: parseInt(100 / GridEditor.rowCount, 10) * cell.rowspan + '%', + width: parseInt(100 / GridEditor.colCount, 10) * cell.colspan + '%' + }); + 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>')); + 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>')); + } + 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>'); + } + 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>'); + } + 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>'); + } + $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>'); + + if (cell.colspan > 1) { + $cell.attr('colspan', cell.colspan); + } + if (cell.rowspan > 1) { + $cell.attr('rowspan', cell.rowspan); + } + $row.append($cell); + } + $table.append($row); + } + $(GridEditor.targetElement).empty().append($table); + }; + + /** + * Sets the name of a certain grid element. + * + * @param {String} newName + * @param {Integer} col + * @param {Integer} row + * + * @returns {Boolean} + */ + GridEditor.setName = function(newName, col, row) { + var cell = GridEditor.getCell(col, row); + if (!cell) return false; + cell.name = GridEditor.stripMarkup(newName); + return true; + }; + + /** + * Sets the column field for a certain grid element. This is NOT the column of the + * element itself. + * + * @param {Integer} newColumn + * @param {Integer} col + * @param {Integer} row + * + * @returns {Boolean} + */ + GridEditor.setColumn = function(newColumn, col, row) { + var cell = GridEditor.getCell(col, row); + if (!cell) { + return false; + } + cell.column = GridEditor.stripMarkup(newColumn); + return true; + }; + + /** + * Creates an ExtJs Window with two input fields and shows it. On save, the data + * is written into the grid element. + * + * @param {Integer} col + * @param {Integer} row + * + * @returns {Boolean} + */ + GridEditor.showOptions = function(col, row) { + var cell = GridEditor.getCell(col, row); + if (!cell) { + return false; + } + + var $markup = $('<div>'); + $markup.append( + '<div>' + + '<div class="form-group">' + + '<label>' + TYPO3.lang['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) || '') + '">' + + '</div>' + + '</div>' + ); + var $modal = Modal.show(TYPO3.lang['title'], $markup, Severity.notice, [ + { + text: $(this).data('button-close-text') || TYPO3.lang['button.cancel'] || 'Cancel', + active: true, + btnClass: 'btn-default', + name: 'cancel' + }, + { + text: $(this).data('button-ok-text') || TYPO3.lang['button.ok'] || 'OK', + btnClass: 'btn-' + Modal.getSeverityClass(Severity.notice), + name: 'ok' + } + ]); + $modal.data('col', col); + $modal.data('row', row); + $modal.on('button.clicked', function(e) { + if (e.target.name === 'cancel') { + $(this).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'); + } + }); + }; + + /** + * Returns a cell element from the grid. + * + * @param {Integer} col + * @param {Integer} row + * @returns {Object} + */ + GridEditor.getCell = function(col, row) { + if (col > GridEditor.colCount - 1) { + return false; + } + if (row > GridEditor.rowCount - 1) { + return false; + } + return GridEditor.data[row][col]; + }; + + /** + * Checks whether a cell can span to the right or not. A cell can span to the right + * if it is not in the last column and if there is no cell beside it that is + * already overspanned by some other cell. + * + * @param {Integer} col + * @param {Integer} row + * @returns {Boolean} + */ + GridEditor.cellCanSpanRight = function(col, row) { + if (col == GridEditor.colCount - 1) { + return false; + } + + var cell = GridEditor.getCell(col, row); + var checkCell; + if (cell.rowspan > 1) { + for (var rowIndex = row; rowIndex < row + cell.rowspan; rowIndex++) { + checkCell = GridEditor.getCell(col + cell.colspan, rowIndex); + if (!checkCell || checkCell.spanned == true || checkCell.colspan > 1 || checkCell.rowspan > 1) { + return false; + } + } + } else { + checkCell = GridEditor.getCell(col + cell.colspan, row); + if (!checkCell || cell.spanned == true || checkCell.spanned == true || checkCell.colspan > 1 || checkCell.rowspan > 1) { + return false; + } + } + + return true; + }; + + /** + * Checks whether a cell can span down or not. + * + * @param {Integer} col + * @param {Integer} row + * @returns {Boolean} + */ + GridEditor.cellCanSpanDown = function(col, row) { + if (row == GridEditor.rowCount - 1) { + return false; + } + + var cell = GridEditor.getCell(col, row); + var checkCell; + if (cell.colspan > 1) { + // we have to check all cells on the right side for the complete colspan + for (var colIndex = col; colIndex < col + cell.colspan; colIndex++) { + checkCell = GridEditor.getCell(colIndex, row + cell.rowspan); + if (!checkCell || checkCell.spanned == true || checkCell.colspan > 1 || checkCell.rowspan > 1) { + return false; + } + } + } else { + checkCell = GridEditor.getCell(col, row + cell.rowspan); + if (!checkCell || cell.spanned == true || checkCell.spanned == true || checkCell.colspan > 1 || checkCell.rowspan > 1) { + return false; + } + } + + return true; + }; + + /** + * Checks if a cell can shrink to the left. It can shrink if the colspan of the + * cell is bigger than 1. + * + * @param {Integer} col + * @param {Integer} row + * @returns {Boolean} + */ + GridEditor.cellCanShrinkLeft = function(col, row) { + return (GridEditor.data[row][col].colspan > 1); + }; + + /** + * Returns if a cell can shrink up. This is the case if a cell has at least + * a rowspan of 2. + * + * @param {Integer} col + * @param {Integer} row + * @returns {Boolean} + */ + GridEditor.cellCanShrinkUp = function(col, row) { + return (GridEditor.data[row][col].rowspan > 1); + }; + + /** + * Adds a colspan to a grid element. + * + * @param {Integer} col + * @param {Integer} row + * @returns {Boolean} + */ + GridEditor.addColspan = function(col, row) { + var cell = GridEditor.getCell(col, row); + if (!cell || !GridEditor.cellCanSpanRight(col, row)) { + return false; + } + + for (var rowIndex = row; rowIndex < row + cell.rowspan; rowIndex++) { + GridEditor.data[rowIndex][col + cell.colspan].spanned = true; + } + cell.colspan += 1; + }; + + /** + * Adds a rowspan to grid element. + * + * @param {Integer} col + * @param {Integer} row + * @returns {Boolean} + */ + GridEditor.addRowspan = function(col, row) { + var cell = GridEditor.getCell(col, row); + if (!cell || !GridEditor.cellCanSpanDown(col, row)) { + return false; + } + + for (var colIndex = col; colIndex < col + cell.colspan; colIndex++) { + GridEditor.data[row + cell.rowspan][colIndex].spanned = true; + } + cell.rowspan += 1; + }; + + /** + * Removes a colspan from a grid element. + * + * @param {Integer} col + * @param {Integer} row + * @returns {Boolean} + */ + GridEditor.removeColspan = function(col, row) { + var cell = GridEditor.getCell(col, row); + if (!cell || !GridEditor.cellCanShrinkLeft(col, row)) { + return false; + } + + cell.colspan -= 1; + for (var rowIndex = row; rowIndex < row + cell.rowspan; rowIndex++) { + GridEditor.data[rowIndex][col + cell.colspan].spanned = false; + } + }; + + /** + * Removes a rowspan from a grid element. + * + * @param {Integer} col + * @param {Integer} row + * @returns {Boolean} + */ + GridEditor.removeRowspan = function(col, row) { + var cell = GridEditor.getCell(col, row); + if (!cell || !GridEditor.cellCanShrinkUp(col, row)) { + return false; + } + + cell.rowspan -= 1; + for (var colIndex = col; colIndex < col + cell.colspan; colIndex++) { + GridEditor.data[row + cell.rowspan][colIndex].spanned = false; + } + }; + + /** + * Exports the current grid to a TypoScript notation that can be read by the + * page module and is human readable. + * + * @returns {String} + */ + GridEditor.export2LayoutRecord = function() { + var result = "backend_layout {\n\tcolCount = " + GridEditor.colCount + "\n\trowCount = " + GridEditor.rowCount + "\n\trows {\n"; + for (var row = 0; row < GridEditor.rowCount; row++) { + result += "\t\t" + (row + 1) + " {\n"; + result += "\t\t\tcolumns {\n"; + var colIndex = 0; + for (var col = 0; col < GridEditor.colCount; col++) { + var cell = GridEditor.getCell(col, row); + if (cell && !cell.spanned) { + colIndex++; + result += "\t\t\t\t" + (colIndex) + " {\n"; + result += "\t\t\t\t\tname = " + ((!cell.name) ? col + "x" + row : cell.name) + "\n"; + if (cell.colspan > 1) { + result += "\t\t\t\t\tcolspan = " + cell.colspan + "\n"; + } + if (cell.rowspan > 1) { + result += "\t\t\t\t\trowspan = " + cell.rowspan + "\n"; + } + if (typeof(cell.column) === 'number') { + result += "\t\t\t\t\tcolPos = " + cell.column + "\n"; + } + result += "\t\t\t\t}\n"; + } + + } + result += "\t\t\t}\n"; + result += "\t\t}\n"; + } + + result += "\t}\n}\n"; + return result; + }; + + /** + * + * @param {String} input + * @returns {*|jQuery} + */ + GridEditor.stripMarkup = function(input) { + return $('<p>' + input + '</p>').text(); + }; + + GridEditor.initialize(); + return GridEditor; +}); diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/grideditor.js b/typo3/sysext/backend/Resources/Public/JavaScript/grideditor.js deleted file mode 100644 index 79c8c3d2d715..000000000000 --- a/typo3/sysext/backend/Resources/Public/JavaScript/grideditor.js +++ /dev/null @@ -1,635 +0,0 @@ -/* - * 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! - */ - -/** - * A JavaScript object to handle, edit, draw and export a grid. The grid is basically - * a table with some colspan and rowspan. Each cell can additionally hold a name and - * column. - */ -Ext.namespace('TYPO3.Backend.t3Grid'); - -TYPO3.Backend.t3Grid = Ext.extend(Ext.Component, { - - constructor: function(config) { - - config = Ext.apply({ - colCount: config.colCount, - rowCount: config.rowCount, - data: config.data, - nameLabel: config.nameLabel, - columnLabel: config.columnLabel, - targetElement: config.targetElement - }, config); - - TYPO3.Backend.t3Grid.superclass.constructor.call(this, config); - }, - - /** - * Adds a row below the grid - */ - addRow: function() { - var newRow = []; - for (var i = 0; i < this.colCount; i++) { - newRow[i] = {spanned:false,rowspan:1,colspan:1}; - } - this.data.push(newRow); - this.rowCount++; - }, - - /** - * Removes the last row of the grid and adjusts all cells that might be effected - * by that change. (Removing colspans) - * - * @returns void - */ - removeRow: function() { - if (this.rowCount <= 1) return false; - var newData = []; - for (var rowIndex = 0; rowIndex < this.rowCount - 1; rowIndex++) { - newData.push(this.data[rowIndex]); - } - - // fix rowspan in former last row - for (var colIndex = 0; colIndex < this.colCount; colIndex++) { - if (this.data[this.rowCount - 1][colIndex].spanned == true) { - this.findUpperCellWidthRowspanAndDecreaseByOne(colIndex, this.rowCount - 1); - } - } - - this.data = newData; - this.rowCount--; - }, - - /** - * Takes a cell and looks above it if there are any cells that have colspans that - * spans into the given cell. This is used when a row was removed from the grid - * to make sure that no cell with wrong colspans exists in the grid. - * - * @param col integer - * @param row integer - * @return void - */ - findUpperCellWidthRowspanAndDecreaseByOne: function(col, row) { - var upperCell = this.getCell(col, row - 1); - if (!upperCell) return false; - - if (upperCell.spanned == true) { - this.findUpperCellWidthRowspanAndDecreaseByOne(col, row - 1); - } else { - if (upperCell.rowspan > 1) { - this.removeRowspan(col, row - 1); - } - } - }, - - /** - * Removes the outermost right column from the grid. - * - * @return void - */ - removeColumn: function() { - if (this.colCount <= 1) return false; - var newData = []; - - for (var rowIndex = 0; rowIndex < this.rowCount; rowIndex++) { - var newRow = []; - for (colIndex = 0; colIndex < this.colCount - 1; colIndex++) { - newRow.push(this.data[rowIndex][colIndex]); - } - if (this.data[rowIndex][this.colCount - 1].spanned == true) { - this.findLeftCellWidthColspanAndDecreaseByOne(this.colCount - 1, rowIndex); - } - newData.push(newRow); - } - - this.data = newData; - this.colCount--; - }, - - /** - * Checks if there are any cells on the left side of a given cell with a - * rowspan that spans over the given cell. - * - * @param col integer - * @param row integer - * @return void - */ - findLeftCellWidthColspanAndDecreaseByOne: function(col, row) { - var leftCell = this.getCell(col - 1, row); - if (!leftCell) return false; - - if (leftCell.spanned == true) { - this.findLeftCellWidthColspanAndDecreaseByOne(col - 1, row); - } else { - if (leftCell.colspan > 1) { - this.removeColspan(col - 1, row); - } - } - }, - - /** - * Adds a column at the right side of the grid. - * - * @return void - */ - addColumn: function() { - for (var rowIndex = 0; rowIndex < this.rowCount; rowIndex++) { - this.data[rowIndex].push({ - spanned: false, - rowspan: 1, - colspan: 1, - name: this.colCount + 'x' + rowIndex - }); - } - this.colCount++; - }, - - /** - * Draws the grid as table into a given container. - * It also adds all needed links and bindings to the cells to make it editable. - * - * @return void - */ - drawTable: function() { - var domHelper = Ext.DomHelper; - var newTable = { - tag: 'table', - children: [], - id: 'base', - border: '0', - width: '100%', - height: '100%', - cls: 'editor', - cellspacing: '0', - cellpadding: '0' - }; - - var colgroups = { - tag: 'colgroup', - children: [] - }; - for (var col = 0; col < this.colCount; col++) { - colgroups.children.push({ - tag: 'col', - style: 'width:' + parseInt(100 / this.colCount, 10) + '%' - }); - } - newTable.children.push(colgroups); - - for (var row = 0; row < this.rowCount; row++) { - var rowData = this.data[row]; - if (rowData.length == 0) continue; - - var rowSpec = {tag: 'tr', children:[]}; - - for (var col = 0; col < this.colCount; col++) { - var cell = this.data[row][col]; - if (cell.spanned == true) { - continue; - } - - var cellHtml = '<div class="cell_container"><a class="link_editor" id="e_' - + col + '_' + row + '" title="' + TYPO3.l10n.localize('editCell') + '" href="#"><!-- --></a>'; - if (this.cellCanSpanRight(col, row)) { - cellHtml += '<a href="#" id="r_' - + col + '_' + row + '" title="' + TYPO3.l10n.localize('mergeCell') + '" class="link_expand_right"><!-- --></a>'; - } - if (this.cellCanShrinkLeft(col, row)) { - cellHtml += '<a href="#" id="l_' - + col + '_' + row + '" title="' + TYPO3.l10n.localize('splitCell') + '" class="link_shrink_left"><!-- --></a>'; - } - if (this.cellCanSpanDown(col, row)) { - cellHtml += '<a href="#" id="d_' - + col + '_' + row + '" title="' + TYPO3.l10n.localize('mergeCell') + '" class="link_expand_down"><!-- --></a>'; - } - if (this.cellCanShrinkUp(col, row)) { - cellHtml += '<a href="#" id="u_' - + col + '_' + row + '" title="' + TYPO3.l10n.localize('splitCell') + '" class="link_shrink_up"><!-- --></a>'; - } - cellHtml += '</div>'; - - cellHtml += '<div class="cell_data">' + TYPO3.l10n.localize('name') + ': ' + (cell.name ? Ext.util.Format.htmlEncode(cell.name) : TYPO3.l10n.localize('notSet')) - + '<br />' + TYPO3.l10n.localize('column') + ': ' - + (cell.column === undefined ? TYPO3.l10n.localize('notSet') : parseInt(cell.column, 10)) + '</div>'; - - // create cells - var child = { - tag: 'td', - height: parseInt(100 / this.rowCount, 10) * cell.rowspan + '%', - width: parseInt(100 / this.colCount, 10) * cell.colspan + '%', - html: cellHtml - }; - if (cell.colspan > 1) { - child.colspan = cell.colspan; - } - if (cell.rowspan > 1) { - child.rowspan = cell.rowspan; - } - rowSpec.children.push(child); - } - - newTable.children.push(rowSpec); - - } - - domHelper.overwrite(Ext.Element.get(this.targetElement), newTable); - this.bindLinks(); - }, - - /** - * Sets the name of a certain grid element. - * - * @param newName string - * @param col integer - * @param row integer - * - * @return boolean - */ - setName: function(newName, col, row) { - var cell = this.getCell(col, row); - if (!cell) return false; - cell.name = newName; - return true; - }, - - /** - * Sets the column field for a certain grid element. This is NOT the column of the - * element itself. - * - * @param newColumn integer - * @param col integer - * @param row integer - * - * @return boolean - */ - setColumn: function(newColumn, col, row) { - var cell = this.getCell(col, row); - if (!cell) return false; - cell.column = newColumn; - return true; - }, - - /** - * Searches for all a tags with certain classes and binds some actions to them. - * - * @return void - */ - bindLinks: function() { - for (var row = 0; row < this.rowCount; row++) { - for (var col = 0; col < this.colCount; col++) { - // span right - var el = Ext.Element.get('r_' + col + '_' + row); - if (el) { - el.addListener('click', function(e, sender, params) { - this.addColspan(params.colIndex, params.rowIndex); - this.drawTable(); - }, this, {stopEvent:true, colIndex:col, rowIndex:row}); - } - - // reduce to left - var el = Ext.Element.get('l_' + col + '_' + row); - if (el) { - el.addListener('click', function(e, sender, params) { - this.removeColspan(params.colIndex, params.rowIndex); - this.drawTable(); - }, this, {stopEvent:true, colIndex:col, rowIndex:row}); - } - - // span down - var el = Ext.Element.get('d_' + col + '_' + row); - if (el) { - el.addListener('click', function(e, sender, params) { - this.addRowspan(params.colIndex, params.rowIndex); - this.drawTable(); - }, this, {stopEvent:true, colIndex:col, rowIndex:row}); - } - - // reduce up - var el = Ext.Element.get('u_' + col + '_' + row); - if (el) { - el.addListener('click', function(e, sender, params) { - this.removeRowspan(params.colIndex, params.rowIndex); - this.drawTable(); - }, this, {stopEvent:true, colIndex:col, rowIndex:row}); - } - - // edit - var el = Ext.Element.get('e_' + col + '_' + row); - if (el) { - el.addListener('click', function(e, sender, params) { - this.showOptions(sender, params.colIndex, params.rowIndex); - }, this, {stopEvent:true, colIndex:col, rowIndex:row}); - } - } - } - }, - - /** - * Creates an ExtJs Window with two input fields and shows it. On save, the data - * is written into the grid element. - * - * @param sender DOM-object (the link) - * @param col integer - * @param row integer - */ - showOptions: function(sender, col, row) { - var win; - sender = Ext.get('base'); - var cell = this.getCell(col, row); - if (!cell) return false; - - if (!win) { - var fieldName = new Ext.form.TextField({ - fieldLabel: TYPO3.l10n.localize('name'), - name: 'name', - width: 270, - value: cell.name, - tabIndex: 1, - listeners: { - render: function(c) { - c.getEl().set({ - 'data-toggle': 'tooltip', - 'data-placement': 'bottom', - 'data-title': TYPO3.l10n.localize('nameHelp') - }); - }, - afterrender: function(cmp) { - TYPO3.Tooltip.initialize('[data-toggle="tooltip"]'); - } - } - }); - - var fieldColumn = new Ext.form.NumberField({ - fieldLabel: TYPO3.l10n.localize('column'), - name: 'column', - width: 50, - value: cell.column, - tabIndex: 2, - listeners: { - render: function(c) { - c.getEl().set({ - 'data-toggle': 'tooltip', - 'data-placement': 'bottom', - 'data-title': TYPO3.l10n.localize('columnHelp') - }); - }, - afterrender: function(cmp) { - TYPO3.Tooltip.initialize('[data-toggle="tooltip"]'); - } - } - }); - - win = new Ext.Window({ - layout: 'fit', - title: TYPO3.l10n.localize('title'), - width: 400, - modal: true, - closable: true, - resizable: false, - - items: [ - { - xtype: 'fieldset', - autoHeight: true, - autoWidth: true, - labelWidth: 100, - border: false, - - items: [fieldName, fieldColumn] - } - ], - - buttons: [ - { - iconCls:'save', - text: TYPO3.l10n.localize('save'), - handler: function(fieldName, fieldColumn, col, row) { - t3Grid.setName(fieldName.getValue(), col, row); - t3Grid.setColumn(fieldColumn.getValue(), col, row); - win.close(); - t3Grid.drawTable(); - }.createDelegate(this, [fieldName, fieldColumn, col, row]) - } - ] - }); - } - win.show(this); - }, - - /** - * Returns a cell element from the grid. - * - * @param col integer - * @param row integer - * return Object - */ - getCell: function(col, row) { - if (col > this.colCount - 1) return false; - if (row > this.rowCount - 1) return false; - return this.data[row][col]; - }, - - /** - * Checks whether a cell can span to the right or not. A cell can span to the right - * if it is not in the last column and if there is no cell beside it that is - * already overspanned by some other cell. - * - * @param col integer - * @param row integer - * - * @return boolean - */ - cellCanSpanRight: function(col, row) { - if (col == this.colCount - 1) { - return false; - } - - var cell = this.getCell(col, row); - if (cell.rowspan > 1) { - for (var rowIndex = row; rowIndex < row + cell.rowspan; rowIndex++) { - var checkCell = this.getCell(col + cell.colspan, rowIndex); - if (!checkCell || checkCell.spanned == true || checkCell.colspan > 1 || checkCell.rowspan > 1) { - return false; - } - } - } else { - var checkCell = this.getCell(col + cell.colspan, row); - if (!checkCell || cell.spanned == true || checkCell.spanned == true || checkCell.colspan > 1 || checkCell.rowspan > 1) { - return false; - } - } - - return true; - }, - - /** - * Checks whether a cell can span down or not. - * - * @param col integer - * @param row integer - * - * @return boolean - */ - cellCanSpanDown: function(col, row) { - if (row == this.rowCount - 1) { - return false; - } - - var cell = this.getCell(col, row); - if (cell.colspan > 1) { - // we have to check all cells on the right side for the complete colspan - for (var colIndex = col; colIndex < col + cell.colspan; colIndex++) { - var checkCell = this.getCell(colIndex, row + cell.rowspan); - if (!checkCell || checkCell.spanned == true || checkCell.colspan > 1 || checkCell.rowspan > 1) { - return false; - } - } - } else { - var checkCell = this.getCell(col, row + cell.rowspan); - if (!checkCell || cell.spanned == true || checkCell.spanned == true || checkCell.colspan > 1 || checkCell.rowspan > 1) { - return false; - } - } - - return true; - }, - - /** - * Checks if a cell can shrink to the left. It can shrink if the colspan of the - * cell is bigger than 1. - * - * @param col integr - * @param row integer - * - * @return boolean - */ - cellCanShrinkLeft: function(col, row) { - return (this.data[row][col].colspan > 1); - }, - - /** - * Returns if a cell can shrink up. This is the case if a cell has at least - * a rowspan of 2. - * - * @param col integr - * @param row integer - * - * @return boolean - */ - cellCanShrinkUp: function(col, row) { - return (this.data[row][col].rowspan > 1); - }, - - /** - * Adds a colspan to a grid element. - * - * @param col integr - * @param row integer - */ - addColspan: function(col, row) { - var cell = this.getCell(col, row); - if (!cell || !this.cellCanSpanRight(col, row)) return false; - - for (var rowIndex = row; rowIndex < row + cell.rowspan; rowIndex++) { - this.data[rowIndex][col + cell.colspan].spanned = true; - } - cell.colspan += 1; - }, - - /** - * Adds a rowspan to grid element. - * - * @param col integr - * @param row integer - * - * @return void - */ - addRowspan: function(col, row) { - var cell = this.getCell(col, row); - if (!cell || !this.cellCanSpanDown(col, row)) return false; - - for (var colIndex = col; colIndex < col + cell.colspan; colIndex++) { - this.data[row + cell.rowspan][colIndex].spanned = true; - } - cell.rowspan += 1; - }, - - /** - * Removes a colspan from a grid element. - * - * @param col integr - * @param row integer - * - * @return void - */ - removeColspan: function(col, row) { - var cell = this.getCell(col, row); - if (!cell || !this.cellCanShrinkLeft(col, row)) return false; - - cell.colspan -= 1; - for (var rowIndex = row; rowIndex < row + cell.rowspan; rowIndex++) { - this.data[rowIndex][col + cell.colspan].spanned = false; - } - }, - - /** - * Removes a rowspan from a grid element. - * - * @param col integr - * @param row integer - * - * @return void - */ - removeRowspan: function(col, row) { - var cell = this.getCell(col, row); - if (!cell || !this.cellCanShrinkUp(col, row)) return false; - - cell.rowspan -= 1; - for (var colIndex = col; colIndex < col + cell.colspan; colIndex++) { - this.data[row + cell.rowspan][colIndex].spanned = false; - } - }, - - /** - * Exports the current grid to a TypoScript notation that can be read by the - * page module and is human readable. - * - * @return string - */ - export2LayoutRecord: function() { - var result = "backend_layout {\n\tcolCount = " + this.colCount + "\n\trowCount = " + this.rowCount + "\n\trows {\n"; - for (var row = 0; row < this.rowCount; row++) { - result += "\t\t" + (row + 1) + " {\n"; - result += "\t\t\tcolumns {\n"; - colIndex = 0; - for (var col = 0; col < this.colCount; col++) { - var cell = this.getCell(col, row); - if (cell && !cell.spanned) { - colIndex++; - result += "\t\t\t\t" + (colIndex) + " {\n"; - result += "\t\t\t\t\tname = " + ((!cell.name) ? col + "x" + row : cell.name) + "\n"; - if (cell.colspan > 1) result += "\t\t\t\t\tcolspan = " + cell.colspan + "\n"; - if (cell.rowspan > 1) result += "\t\t\t\t\trowspan = " + cell.rowspan + "\n"; - if (typeof(cell.column) === 'number') result += "\t\t\t\t\tcolPos = " + cell.column + "\n"; - result += "\t\t\t\t}\n"; - } - - } - result += "\t\t\t}\n"; - result += "\t\t}\n"; - } - - result += "\t}\n}\n"; - return result; - } -}); diff --git a/typo3/sysext/t3skin/Resources/Public/Css/backend.css b/typo3/sysext/t3skin/Resources/Public/Css/backend.css index 5b3277582134..0c7b2666d5ac 100644 --- a/typo3/sysext/t3skin/Resources/Public/Css/backend.css +++ b/typo3/sysext/t3skin/Resources/Public/Css/backend.css @@ -12029,6 +12029,107 @@ span.warningboxheader { padding-bottom: 30px; margin: 0 15px 30px 15px; } +.grideditor td { + vertical-align: middle; +} +.grideditor td.editor_cell { + height: 100%; +} +.grideditor table.editor { + border-right: 1px gray dashed; + border-bottom: 1px gray dashed; +} +.grideditor table.editor td { + vertical-align: middle; + border-top: 1px gray dashed; + border-left: 1px gray dashed; + text-align: center; + background-color: white; + min-height: 100px; +} +.grideditor div#editor { + height: 100%; +} +.grideditor div.cell_container { + width: 80px; + height: 80px; + position: relative; + left: 50%; + margin-left: -30px; + opacity: 0.3; +} +.grideditor div.cell_container:hover { + opacity: 0.5; +} +.grideditor .link { + display: block; + position: absolute; + width: 20px; + height: 40px; + overflow: hidden; + opacity: 0.5; +} +.grideditor .link:hover { + text-decoration: none; + opacity: 1; +} +.grideditor .link_expand_down, +.grideditor .link_shrink_up { + width: 40px; + height: 20px; +} +.grideditor .link_expand_right { + left: 52px; + top: 0; +} +.grideditor .link_expand_right:before { + font-family: FontAwesome; + content: "\f0da"; + font-size: 42px; + line-height: 42px; +} +.grideditor .link_shrink_left { + left: -8px; + top: 0; +} +.grideditor .link_shrink_left:before { + font-family: FontAwesome; + content: "\f0d9"; + font-size: 42px; + line-height: 42px; +} +.grideditor .link_expand_down { + left: 12px; + top: 40px; +} +.grideditor .link_expand_down:before { + font-family: FontAwesome; + content: "\f0d7"; + font-size: 42px; + line-height: 19px; +} +.grideditor .link_shrink_up { + left: 12px; + top: -20px; +} +.grideditor .link_shrink_up:before { + font-family: FontAwesome; + content: "\f0d8"; + font-size: 42px; + line-height: 20px; +} +.grideditor .link_editor { + width: 40px; + height: 40px; + left: 12px; + top: 0; +} +.grideditor .link_editor:before { + font-family: FontAwesome; + content: "\f14b"; + font-size: 42px; + line-height: 42px; +} *::-ms-clear { display: none; } -- GitLab