diff --git a/Build/Sources/TypeScript/backend/Resources/Public/TypeScript/GridEditor.ts b/Build/Sources/TypeScript/backend/Resources/Public/TypeScript/GridEditor.ts index bb7d8de90ff121a2f09b5d9664fc0cd5ed348ed1..54be1901447f035a854072dcd81a65e6e19a5496 100644 --- a/Build/Sources/TypeScript/backend/Resources/Public/TypeScript/GridEditor.ts +++ b/Build/Sources/TypeScript/backend/Resources/Public/TypeScript/GridEditor.ts @@ -65,7 +65,8 @@ export class GridEditor { protected selectorDocHeaderSave: string = '.t3js-grideditor-savedok'; protected selectorDocHeaderSaveClose: string = '.t3js-grideditor-savedokclose'; protected selectorConfigPreview: string = '.t3js-grideditor-preview-config'; - protected selectorConfigPreviewButton: string = '.t3js-grideditor-preview-button'; + protected selectorPreviewArea: string = '.t3js-tsconfig-preview-area'; + protected selectorCodeMirror: string = '.t3js-grideditor-preview-config .CodeMirror'; /** * Remove all markup @@ -91,9 +92,6 @@ export class GridEditor { this.nameLabel = config !== null ? config.nameLabel : 'Name'; this.columnLabel = config !== null ? config.columnLabel : 'Column'; this.targetElement = $(this.selectorEditor); - $(this.selectorConfigPreview).hide(); - - $(this.selectorConfigPreviewButton).empty().append(TYPO3.lang['button.showPageTsConfig']); this.initializeEvents(); this.drawTable(); @@ -115,7 +113,6 @@ export class GridEditor { $(document).on('click', this.selectorLinkShrinkLeft, this.linkShrinkLeftHandler); $(document).on('click', this.selectorLinkExpandDown, this.linkExpandDownHandler); $(document).on('click', this.selectorLinkShrinkUp, this.linkShrinkUpHandler); - $(document).on('click', this.selectorConfigPreviewButton, this.configPreviewButtonHandler); } /** @@ -267,23 +264,6 @@ export class GridEditor { this.writeConfig(this.export2LayoutRecord()); } - /** - * - * @param {Event} e - */ - protected configPreviewButtonHandler = (e: Event) => { - e.preventDefault(); - const $preview = $(this.selectorConfigPreview); - const $button = $(this.selectorConfigPreviewButton); - if ($preview.is(':visible')) { - $button.empty().append(TYPO3.lang['button.showPageTsConfig']); - $(this.selectorConfigPreview).slideUp(); - } else { - $button.empty().append(TYPO3.lang['button.hidePageTsConfig']); - $(this.selectorConfigPreview).slideDown(); - } - } - /** * Create a new cell from defaultCell * @returns {Object} @@ -306,8 +286,8 @@ export class GridEditor { config += '\t\t\t' + line + '\n'; } } - $(this.selectorConfigPreview).find('code').empty().append( - 'mod.web_layout.BackendLayouts {\n' + + + let content = 'mod.web_layout.BackendLayouts {\n' + ' exampleKey {\n' + ' title = Example\n' + ' icon = EXT:example_extension/Resources/Public/Images/BackendLayouts/default.gif\n' + @@ -315,8 +295,17 @@ export class GridEditor { config.replace(new RegExp('\t', 'g'), ' ') + ' }\n' + ' }\n' + - '}\n', + '}\n'; + + $(this.selectorConfigPreview).find(this.selectorPreviewArea).empty().append( + content ); + + // Update CodeMirror content if instantiated + const codemirror: any = document.querySelector(this.selectorCodeMirror); + if (codemirror) { + codemirror.CodeMirror.setValue(content) + } } /** diff --git a/typo3/sysext/backend/Classes/Form/Element/BackendLayoutWizardElement.php b/typo3/sysext/backend/Classes/Form/Element/BackendLayoutWizardElement.php index 40eed8f10743454d273b9a07ae57e264165f39be..542f360da5b5afd2335616adb03797b655b57557 100644 --- a/typo3/sysext/backend/Classes/Form/Element/BackendLayoutWizardElement.php +++ b/typo3/sysext/backend/Classes/Form/Element/BackendLayoutWizardElement.php @@ -16,6 +16,7 @@ namespace TYPO3\CMS\Backend\Form\Element; use TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser; +use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; /** @@ -67,6 +68,34 @@ class BackendLayoutWizardElement extends AbstractFormElement $fieldWizardHtml = $fieldWizardResult['html']; $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldWizardResult, false); + // Use CodeMirror if available + if (ExtensionManagementUtility::isLoaded('t3editor')) { + $codeMirrorConfig = [ + 'label' => $lang->getLL('buttons.pageTsConfig'), + 'panel' => 'top', + 'mode' => 'TYPO3/CMS/T3editor/Mode/typoscript/typoscript', + 'nolazyload' => 'true', + 'options' => GeneralUtility::jsonEncodeForHtmlAttribute([ + 'height' => 'auto', + 'readOnly' => 'true' + ], false), + ]; + $editor = ' + <typo3-t3editor-codemirror class="t3js-grideditor-preview-config grideditor-preview" ' . GeneralUtility::implodeAttributes($codeMirrorConfig, true) . '> + <textarea class="t3js-tsconfig-preview-area"></textarea> + </typo3-t3editor-codemirror>'; + + $resultArray['stylesheetFiles'][] = 'EXT:t3editor/Resources/Public/JavaScript/Contrib/codemirror/lib/codemirror.css'; + $resultArray['stylesheetFiles'][] = 'EXT:t3editor/Resources/Public/Css/t3editor.css'; + $resultArray['requireJsModules'][] = ['TYPO3/CMS/T3editor/Element/CodeMirrorElement' => null]; + } else { + $editor = ' + <label>' . htmlspecialchars($lang->getLL('buttons.pageTsConfig')) . '</label> + <div class="t3js-grideditor-preview-config grideditor-preview"> + <textarea class="t3js-tsconfig-preview-area form-control" rows="25"></textarea> + </div>'; + } + $json = (string)json_encode($this->rows, JSON_HEX_QUOT | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS); $html = []; $html[] = '<div class="formengine-field-item t3js-formengine-field-item">'; @@ -135,8 +164,7 @@ class BackendLayoutWizardElement extends AbstractFormElement $html[] = '</tr>'; $html[] = '<tr>'; $html[] = '<td colspan="2">'; - $html[] = '<a href="#" class="btn btn-default btn-sm t3js-grideditor-preview-button"></a>'; - $html[] = '<pre class="t3js-grideditor-preview-config grideditor-preview"><code></code></pre>'; + $html[] = $editor; $html[] = '</td>'; $html[] = '</tr>'; $html[] = '</table>'; diff --git a/typo3/sysext/backend/Resources/Private/Language/locallang.xlf b/typo3/sysext/backend/Resources/Private/Language/locallang.xlf index aabfed846e4acf5ab6fbf6c9ece291310e9106e4..da85a5d31c939f7531700e285583a8203fd9f653 100644 --- a/typo3/sysext/backend/Resources/Private/Language/locallang.xlf +++ b/typo3/sysext/backend/Resources/Private/Language/locallang.xlf @@ -127,12 +127,6 @@ Have a nice day.</source> <trans-unit id="login.donate" resname="login.donate"> <source>Donate</source> </trans-unit> - <trans-unit id="button.showPageTsConfig" resname="button.showPageTsConfig"> - <source>Show PageTS-Config</source> - </trans-unit> - <trans-unit id="button.hidePageTsConfig" resname="button.hidePageTsConfig"> - <source>Hide PageTS-Config</source> - </trans-unit> <trans-unit id="formEngine.databaseRecordErrorInlineChildChild" resname="formEngine.databaseRecordErrorInlineChildChild"> <source>The record with uid %2$s from table %1$s could not be retrieved from the database. This data inconsistency can occur if a base record has been deleted but the intermediate record from table %3$s with uid %4$s still points to it. To fix diff --git a/typo3/sysext/backend/Resources/Private/Language/locallang_alt_doc.xlf b/typo3/sysext/backend/Resources/Private/Language/locallang_alt_doc.xlf index 7929b5b30f564ecb3162cace87b717cac1980bd5..470fe6186a9ce9b879986851ca0e897857853fe4 100644 --- a/typo3/sysext/backend/Resources/Private/Language/locallang_alt_doc.xlf +++ b/typo3/sysext/backend/Resources/Private/Language/locallang_alt_doc.xlf @@ -135,6 +135,9 @@ <trans-unit id="buttons.reviewFailedValidationFields" resname="buttons.reviewFailedValidationFields"> <source>Review fields with failed validations</source> </trans-unit> + <trans-unit id="buttons.pageTsConfig" resname="buttons.pageTsConfig"> + <source>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 c67f24eee72556a5d3413b56123aafe95cc2fb88..e46f5728c1171d50c2f519f838ac2c0049ecd6f6 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/GridEditor.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/GridEditor.js @@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -var __importDefault=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};define(["require","exports","./Enum/Severity","jquery","./Modal","bootstrap"],(function(t,e,n,o,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.GridEditor=void 0,o=__importDefault(o);class a{constructor(t=null){this.colCount=1,this.rowCount=1,this.nameLabel="name",this.columnLabel="column label",this.defaultCell={spanned:0,rowspan:1,colspan:1,name:"",colpos:"",column:void 0},this.selectorEditor=".t3js-grideditor",this.selectorAddColumn=".t3js-grideditor-addcolumn",this.selectorRemoveColumn=".t3js-grideditor-removecolumn",this.selectorAddRowTop=".t3js-grideditor-addrow-top",this.selectorRemoveRowTop=".t3js-grideditor-removerow-top",this.selectorAddRowBottom=".t3js-grideditor-addrow-bottom",this.selectorRemoveRowBottom=".t3js-grideditor-removerow-bottom",this.selectorLinkEditor=".t3js-grideditor-link-editor",this.selectorLinkExpandRight=".t3js-grideditor-link-expand-right",this.selectorLinkShrinkLeft=".t3js-grideditor-link-shrink-left",this.selectorLinkExpandDown=".t3js-grideditor-link-expand-down",this.selectorLinkShrinkUp=".t3js-grideditor-link-shrink-up",this.selectorDocHeaderSave=".t3js-grideditor-savedok",this.selectorDocHeaderSaveClose=".t3js-grideditor-savedokclose",this.selectorConfigPreview=".t3js-grideditor-preview-config",this.selectorConfigPreviewButton=".t3js-grideditor-preview-button",this.modalButtonClickHandler=t=>{const e=t.target;"cancel"===e.name?i.currentModal.trigger("modal-dismiss"):"ok"===e.name&&(this.setName(i.currentModal.find(".t3js-grideditor-field-name").val(),i.currentModal.data("col"),i.currentModal.data("row")),this.setColumn(i.currentModal.find(".t3js-grideditor-field-colpos").val(),i.currentModal.data("col"),i.currentModal.data("row")),this.drawTable(),this.writeConfig(this.export2LayoutRecord()),i.currentModal.trigger("modal-dismiss"))},this.addColumnHandler=t=>{t.preventDefault(),this.addColumn(),this.drawTable(),this.writeConfig(this.export2LayoutRecord())},this.removeColumnHandler=t=>{t.preventDefault(),this.removeColumn(),this.drawTable(),this.writeConfig(this.export2LayoutRecord())},this.addRowTopHandler=t=>{t.preventDefault(),this.addRowTop(),this.drawTable(),this.writeConfig(this.export2LayoutRecord())},this.addRowBottomHandler=t=>{t.preventDefault(),this.addRowBottom(),this.drawTable(),this.writeConfig(this.export2LayoutRecord())},this.removeRowTopHandler=t=>{t.preventDefault(),this.removeRowTop(),this.drawTable(),this.writeConfig(this.export2LayoutRecord())},this.removeRowBottomHandler=t=>{t.preventDefault(),this.removeRowBottom(),this.drawTable(),this.writeConfig(this.export2LayoutRecord())},this.linkEditorHandler=t=>{t.preventDefault();const e=o.default(t.target);this.showOptions(e.data("col"),e.data("row"))},this.linkExpandRightHandler=t=>{t.preventDefault();const e=o.default(t.target);this.addColspan(e.data("col"),e.data("row")),this.drawTable(),this.writeConfig(this.export2LayoutRecord())},this.linkShrinkLeftHandler=t=>{t.preventDefault();const e=o.default(t.target);this.removeColspan(e.data("col"),e.data("row")),this.drawTable(),this.writeConfig(this.export2LayoutRecord())},this.linkExpandDownHandler=t=>{t.preventDefault();const e=o.default(t.target);this.addRowspan(e.data("col"),e.data("row")),this.drawTable(),this.writeConfig(this.export2LayoutRecord())},this.linkShrinkUpHandler=t=>{t.preventDefault();const e=o.default(t.target);this.removeRowspan(e.data("col"),e.data("row")),this.drawTable(),this.writeConfig(this.export2LayoutRecord())},this.configPreviewButtonHandler=t=>{t.preventDefault();const e=o.default(this.selectorConfigPreview),n=o.default(this.selectorConfigPreviewButton);e.is(":visible")?(n.empty().append(TYPO3.lang["button.showPageTsConfig"]),o.default(this.selectorConfigPreview).slideUp()):(n.empty().append(TYPO3.lang["button.hidePageTsConfig"]),o.default(this.selectorConfigPreview).slideDown())};const e=o.default(this.selectorEditor);this.colCount=e.data("colcount"),this.rowCount=e.data("rowcount"),this.field=o.default('input[name="'+e.data("field")+'"]'),this.data=e.data("data"),this.nameLabel=null!==t?t.nameLabel:"Name",this.columnLabel=null!==t?t.columnLabel:"Column",this.targetElement=o.default(this.selectorEditor),o.default(this.selectorConfigPreview).hide(),o.default(this.selectorConfigPreviewButton).empty().append(TYPO3.lang["button.showPageTsConfig"]),this.initializeEvents(),this.drawTable(),this.writeConfig(this.export2LayoutRecord())}static stripMarkup(t){return t=t.replace(/<(.*)>/gi,""),o.default("<p>"+t+"</p>").text()}initializeEvents(){o.default(document).on("click",this.selectorAddColumn,this.addColumnHandler),o.default(document).on("click",this.selectorRemoveColumn,this.removeColumnHandler),o.default(document).on("click",this.selectorAddRowTop,this.addRowTopHandler),o.default(document).on("click",this.selectorAddRowBottom,this.addRowBottomHandler),o.default(document).on("click",this.selectorRemoveRowTop,this.removeRowTopHandler),o.default(document).on("click",this.selectorRemoveRowBottom,this.removeRowBottomHandler),o.default(document).on("click",this.selectorLinkEditor,this.linkEditorHandler),o.default(document).on("click",this.selectorLinkExpandRight,this.linkExpandRightHandler),o.default(document).on("click",this.selectorLinkShrinkLeft,this.linkShrinkLeftHandler),o.default(document).on("click",this.selectorLinkExpandDown,this.linkExpandDownHandler),o.default(document).on("click",this.selectorLinkShrinkUp,this.linkShrinkUpHandler),o.default(document).on("click",this.selectorConfigPreviewButton,this.configPreviewButtonHandler)}getNewCell(){return o.default.extend({},this.defaultCell)}writeConfig(t){this.field.val(t);const e=t.split("\n");let n="";for(const t of e)t&&(n+="\t\t\t"+t+"\n");o.default(this.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"+n.replace(new RegExp("\t","g")," ")+" }\n }\n}\n")}addRowTop(){const t=[];for(let e=0;e<this.colCount;e++){const n=this.getNewCell();n.name=e+"x"+this.data.length,t[e]=n}this.data.unshift(t),this.rowCount++}addRowBottom(){const t=[];for(let e=0;e<this.colCount;e++){const n=this.getNewCell();n.name=e+"x"+this.data.length,t[e]=n}this.data.push(t),this.rowCount++}removeRowTop(){if(this.rowCount<=1)return!1;const t=[];for(let e=1;e<this.rowCount;e++)t.push(this.data[e]);for(let t=0;t<this.colCount;t++)1===this.data[0][t].spanned&&this.findUpperCellWidthRowspanAndDecreaseByOne(t,0);return this.data=t,this.rowCount--,!0}removeRowBottom(){if(this.rowCount<=1)return!1;const t=[];for(let e=0;e<this.rowCount-1;e++)t.push(this.data[e]);for(let t=0;t<this.colCount;t++)1===this.data[this.rowCount-1][t].spanned&&this.findUpperCellWidthRowspanAndDecreaseByOne(t,this.rowCount-1);return this.data=t,this.rowCount--,!0}findUpperCellWidthRowspanAndDecreaseByOne(t,e){const n=this.getCell(t,e-1);return!!n&&(1===n.spanned?this.findUpperCellWidthRowspanAndDecreaseByOne(t,e-1):n.rowspan>1&&this.removeRowspan(t,e-1),!0)}removeColumn(){if(this.colCount<=1)return!1;const t=[];for(let e=0;e<this.rowCount;e++){const n=[];for(let t=0;t<this.colCount-1;t++)n.push(this.data[e][t]);1===this.data[e][this.colCount-1].spanned&&this.findLeftCellWidthColspanAndDecreaseByOne(this.colCount-1,e),t.push(n)}return this.data=t,this.colCount--,!0}findLeftCellWidthColspanAndDecreaseByOne(t,e){const n=this.getCell(t-1,e);return!!n&&(1===n.spanned?this.findLeftCellWidthColspanAndDecreaseByOne(t-1,e):n.colspan>1&&this.removeColspan(t-1,e),!0)}addColumn(){for(let t=0;t<this.rowCount;t++){const e=this.getNewCell();e.name=this.colCount+"x"+t,this.data[t].push(e)}this.colCount++}drawTable(){const t=o.default("<colgroup>");for(let e=0;e<this.colCount;e++){const e=100/this.colCount;t.append(o.default("<col>").css({width:parseInt(e.toString(),10)+"%"}))}const e=o.default('<table id="base" class="table editor">');e.append(t);for(let t=0;t<this.rowCount;t++){if(0===this.data[t].length)continue;const n=o.default("<tr>");for(let e=0;e<this.colCount;e++){const i=this.data[t][e];if(1===i.spanned)continue;const l=100/this.rowCount,s=100/this.colCount,r=o.default("<td>").css({height:parseInt(l.toString(),10)*i.rowspan+"%",width:parseInt(s.toString(),10)*i.colspan+"%"}),d=o.default('<div class="cell_container">');r.append(d);const c=o.default('<a href="#" data-col="'+e+'" data-row="'+t+'">');d.append(c.clone().attr("class","t3js-grideditor-link-editor link link_editor").attr("title",TYPO3.lang.grid_editCell)),this.cellCanSpanRight(e,t)&&d.append(c.clone().attr("class","t3js-grideditor-link-expand-right link link_expand_right").attr("title",TYPO3.lang.grid_mergeCell)),this.cellCanShrinkLeft(e,t)&&d.append(c.clone().attr("class","t3js-grideditor-link-shrink-left link link_shrink_left").attr("title",TYPO3.lang.grid_splitCell)),this.cellCanSpanDown(e,t)&&d.append(c.clone().attr("class","t3js-grideditor-link-expand-down link link_expand_down").attr("title",TYPO3.lang.grid_mergeCell)),this.cellCanShrinkUp(e,t)&&d.append(c.clone().attr("class","t3js-grideditor-link-shrink-up link link_shrink_up").attr("title",TYPO3.lang.grid_splitCell)),r.append(o.default('<div class="cell_data">').html(TYPO3.lang.grid_name+": "+(i.name?a.stripMarkup(i.name):TYPO3.lang.grid_notSet)+"<br />"+TYPO3.lang.grid_column+": "+(void 0===i.column||isNaN(i.column)?TYPO3.lang.grid_notSet:parseInt(i.column,10)))),i.colspan>1&&r.attr("colspan",i.colspan),i.rowspan>1&&r.attr("rowspan",i.rowspan),n.append(r)}e.append(n)}o.default(this.targetElement).empty().append(e)}setName(t,e,n){const o=this.getCell(e,n);return!!o&&(o.name=a.stripMarkup(t),!0)}setColumn(t,e,n){const o=this.getCell(e,n);return!!o&&(o.column=parseInt(t.toString(),10),!0)}showOptions(t,e){const l=this.getCell(t,e);if(!l)return!1;let s;s=0===l.column?0:l.column?parseInt(l.column.toString(),10):"";const r=o.default("<div>"),d=o.default('<div class="form-group">'),c=o.default("<label>"),h=o.default("<input>");r.append([d.clone().append([c.clone().text(TYPO3.lang.grid_nameHelp),h.clone().attr("type","text").attr("class","t3js-grideditor-field-name form-control").attr("name","name").val(a.stripMarkup(l.name)||"")]),d.clone().append([c.clone().text(TYPO3.lang.grid_columnHelp),h.clone().attr("type","text").attr("class","t3js-grideditor-field-colpos form-control").attr("name","column").val(s)])]);const u=i.show(TYPO3.lang.grid_windowTitle,r,n.SeverityEnum.notice,[{active:!0,btnClass:"btn-default",name:"cancel",text:o.default(this).data("button-close-text")||TYPO3.lang["button.cancel"]||"Cancel"},{btnClass:"btn-primary",name:"ok",text:o.default(this).data("button-ok-text")||TYPO3.lang["button.ok"]||"OK"}]);return u.data("col",t),u.data("row",e),u.on("button.clicked",this.modalButtonClickHandler),!0}getCell(t,e){return!(t>this.colCount-1)&&(!(e>this.rowCount-1)&&(this.data.length>e-1&&this.data[e].length>t-1?this.data[e][t]:null))}cellCanSpanRight(t,e){if(t===this.colCount-1)return!1;const n=this.getCell(t,e);let o;if(n.rowspan>1){for(let i=e;i<e+n.rowspan;i++)if(o=this.getCell(t+n.colspan,i),!o||1===o.spanned||o.colspan>1||o.rowspan>1)return!1}else if(o=this.getCell(t+n.colspan,e),!o||1===n.spanned||1===o.spanned||o.colspan>1||o.rowspan>1)return!1;return!0}cellCanSpanDown(t,e){if(e===this.rowCount-1)return!1;const n=this.getCell(t,e);let o;if(n.colspan>1){for(let i=t;i<t+n.colspan;i++)if(o=this.getCell(i,e+n.rowspan),!o||1===o.spanned||o.colspan>1||o.rowspan>1)return!1}else if(o=this.getCell(t,e+n.rowspan),!o||1===n.spanned||1===o.spanned||o.colspan>1||o.rowspan>1)return!1;return!0}cellCanShrinkLeft(t,e){return this.data[e][t].colspan>1}cellCanShrinkUp(t,e){return this.data[e][t].rowspan>1}addColspan(t,e){const n=this.getCell(t,e);if(!n||!this.cellCanSpanRight(t,e))return!1;for(let o=e;o<e+n.rowspan;o++)this.data[o][t+n.colspan].spanned=1;return n.colspan+=1,!0}addRowspan(t,e){const n=this.getCell(t,e);if(!n||!this.cellCanSpanDown(t,e))return!1;for(let o=t;o<t+n.colspan;o++)this.data[e+n.rowspan][o].spanned=1;return n.rowspan+=1,!0}removeColspan(t,e){const n=this.getCell(t,e);if(!n||!this.cellCanShrinkLeft(t,e))return!1;n.colspan-=1;for(let o=e;o<e+n.rowspan;o++)this.data[o][t+n.colspan].spanned=0;return!0}removeRowspan(t,e){const n=this.getCell(t,e);if(!n||!this.cellCanShrinkUp(t,e))return!1;n.rowspan-=1;for(let o=t;o<t+n.colspan;o++)this.data[e+n.rowspan][o].spanned=0;return!0}export2LayoutRecord(){let t="backend_layout {\n\tcolCount = "+this.colCount+"\n\trowCount = "+this.rowCount+"\n\trows {\n";for(let e=0;e<this.rowCount;e++){t+="\t\t"+(e+1)+" {\n",t+="\t\t\tcolumns {\n";let n=0;for(let o=0;o<this.colCount;o++){const i=this.getCell(o,e);i&&(i.spanned||(n++,t+="\t\t\t\t"+n+" {\n",t+="\t\t\t\t\tname = "+(i.name?i.name:o+"x"+e)+"\n",i.colspan>1&&(t+="\t\t\t\t\tcolspan = "+i.colspan+"\n"),i.rowspan>1&&(t+="\t\t\t\t\trowspan = "+i.rowspan+"\n"),"number"==typeof i.column&&(t+="\t\t\t\t\tcolPos = "+i.column+"\n"),t+="\t\t\t\t}\n"))}t+="\t\t\t}\n",t+="\t\t}\n"}return t+="\t}\n}\n",t}}e.GridEditor=a})); \ No newline at end of file +var __importDefault=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};define(["require","exports","./Enum/Severity","jquery","./Modal","bootstrap"],(function(t,e,o,n,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.GridEditor=void 0,n=__importDefault(n);class a{constructor(t=null){this.colCount=1,this.rowCount=1,this.nameLabel="name",this.columnLabel="column label",this.defaultCell={spanned:0,rowspan:1,colspan:1,name:"",colpos:"",column:void 0},this.selectorEditor=".t3js-grideditor",this.selectorAddColumn=".t3js-grideditor-addcolumn",this.selectorRemoveColumn=".t3js-grideditor-removecolumn",this.selectorAddRowTop=".t3js-grideditor-addrow-top",this.selectorRemoveRowTop=".t3js-grideditor-removerow-top",this.selectorAddRowBottom=".t3js-grideditor-addrow-bottom",this.selectorRemoveRowBottom=".t3js-grideditor-removerow-bottom",this.selectorLinkEditor=".t3js-grideditor-link-editor",this.selectorLinkExpandRight=".t3js-grideditor-link-expand-right",this.selectorLinkShrinkLeft=".t3js-grideditor-link-shrink-left",this.selectorLinkExpandDown=".t3js-grideditor-link-expand-down",this.selectorLinkShrinkUp=".t3js-grideditor-link-shrink-up",this.selectorDocHeaderSave=".t3js-grideditor-savedok",this.selectorDocHeaderSaveClose=".t3js-grideditor-savedokclose",this.selectorConfigPreview=".t3js-grideditor-preview-config",this.selectorPreviewArea=".t3js-tsconfig-preview-area",this.selectorCodeMirror=".t3js-grideditor-preview-config .CodeMirror",this.modalButtonClickHandler=t=>{const e=t.target;"cancel"===e.name?i.currentModal.trigger("modal-dismiss"):"ok"===e.name&&(this.setName(i.currentModal.find(".t3js-grideditor-field-name").val(),i.currentModal.data("col"),i.currentModal.data("row")),this.setColumn(i.currentModal.find(".t3js-grideditor-field-colpos").val(),i.currentModal.data("col"),i.currentModal.data("row")),this.drawTable(),this.writeConfig(this.export2LayoutRecord()),i.currentModal.trigger("modal-dismiss"))},this.addColumnHandler=t=>{t.preventDefault(),this.addColumn(),this.drawTable(),this.writeConfig(this.export2LayoutRecord())},this.removeColumnHandler=t=>{t.preventDefault(),this.removeColumn(),this.drawTable(),this.writeConfig(this.export2LayoutRecord())},this.addRowTopHandler=t=>{t.preventDefault(),this.addRowTop(),this.drawTable(),this.writeConfig(this.export2LayoutRecord())},this.addRowBottomHandler=t=>{t.preventDefault(),this.addRowBottom(),this.drawTable(),this.writeConfig(this.export2LayoutRecord())},this.removeRowTopHandler=t=>{t.preventDefault(),this.removeRowTop(),this.drawTable(),this.writeConfig(this.export2LayoutRecord())},this.removeRowBottomHandler=t=>{t.preventDefault(),this.removeRowBottom(),this.drawTable(),this.writeConfig(this.export2LayoutRecord())},this.linkEditorHandler=t=>{t.preventDefault();const e=n.default(t.target);this.showOptions(e.data("col"),e.data("row"))},this.linkExpandRightHandler=t=>{t.preventDefault();const e=n.default(t.target);this.addColspan(e.data("col"),e.data("row")),this.drawTable(),this.writeConfig(this.export2LayoutRecord())},this.linkShrinkLeftHandler=t=>{t.preventDefault();const e=n.default(t.target);this.removeColspan(e.data("col"),e.data("row")),this.drawTable(),this.writeConfig(this.export2LayoutRecord())},this.linkExpandDownHandler=t=>{t.preventDefault();const e=n.default(t.target);this.addRowspan(e.data("col"),e.data("row")),this.drawTable(),this.writeConfig(this.export2LayoutRecord())},this.linkShrinkUpHandler=t=>{t.preventDefault();const e=n.default(t.target);this.removeRowspan(e.data("col"),e.data("row")),this.drawTable(),this.writeConfig(this.export2LayoutRecord())};const e=n.default(this.selectorEditor);this.colCount=e.data("colcount"),this.rowCount=e.data("rowcount"),this.field=n.default('input[name="'+e.data("field")+'"]'),this.data=e.data("data"),this.nameLabel=null!==t?t.nameLabel:"Name",this.columnLabel=null!==t?t.columnLabel:"Column",this.targetElement=n.default(this.selectorEditor),this.initializeEvents(),this.drawTable(),this.writeConfig(this.export2LayoutRecord())}static stripMarkup(t){return t=t.replace(/<(.*)>/gi,""),n.default("<p>"+t+"</p>").text()}initializeEvents(){n.default(document).on("click",this.selectorAddColumn,this.addColumnHandler),n.default(document).on("click",this.selectorRemoveColumn,this.removeColumnHandler),n.default(document).on("click",this.selectorAddRowTop,this.addRowTopHandler),n.default(document).on("click",this.selectorAddRowBottom,this.addRowBottomHandler),n.default(document).on("click",this.selectorRemoveRowTop,this.removeRowTopHandler),n.default(document).on("click",this.selectorRemoveRowBottom,this.removeRowBottomHandler),n.default(document).on("click",this.selectorLinkEditor,this.linkEditorHandler),n.default(document).on("click",this.selectorLinkExpandRight,this.linkExpandRightHandler),n.default(document).on("click",this.selectorLinkShrinkLeft,this.linkShrinkLeftHandler),n.default(document).on("click",this.selectorLinkExpandDown,this.linkExpandDownHandler),n.default(document).on("click",this.selectorLinkShrinkUp,this.linkShrinkUpHandler)}getNewCell(){return n.default.extend({},this.defaultCell)}writeConfig(t){this.field.val(t);const e=t.split("\n");let o="";for(const t of e)t&&(o+="\t\t\t"+t+"\n");let i="mod.web_layout.BackendLayouts {\n exampleKey {\n title = Example\n icon = EXT:example_extension/Resources/Public/Images/BackendLayouts/default.gif\n config {\n"+o.replace(new RegExp("\t","g")," ")+" }\n }\n}\n";n.default(this.selectorConfigPreview).find(this.selectorPreviewArea).empty().append(i);const a=document.querySelector(this.selectorCodeMirror);a&&a.CodeMirror.setValue(i)}addRowTop(){const t=[];for(let e=0;e<this.colCount;e++){const o=this.getNewCell();o.name=e+"x"+this.data.length,t[e]=o}this.data.unshift(t),this.rowCount++}addRowBottom(){const t=[];for(let e=0;e<this.colCount;e++){const o=this.getNewCell();o.name=e+"x"+this.data.length,t[e]=o}this.data.push(t),this.rowCount++}removeRowTop(){if(this.rowCount<=1)return!1;const t=[];for(let e=1;e<this.rowCount;e++)t.push(this.data[e]);for(let t=0;t<this.colCount;t++)1===this.data[0][t].spanned&&this.findUpperCellWidthRowspanAndDecreaseByOne(t,0);return this.data=t,this.rowCount--,!0}removeRowBottom(){if(this.rowCount<=1)return!1;const t=[];for(let e=0;e<this.rowCount-1;e++)t.push(this.data[e]);for(let t=0;t<this.colCount;t++)1===this.data[this.rowCount-1][t].spanned&&this.findUpperCellWidthRowspanAndDecreaseByOne(t,this.rowCount-1);return this.data=t,this.rowCount--,!0}findUpperCellWidthRowspanAndDecreaseByOne(t,e){const o=this.getCell(t,e-1);return!!o&&(1===o.spanned?this.findUpperCellWidthRowspanAndDecreaseByOne(t,e-1):o.rowspan>1&&this.removeRowspan(t,e-1),!0)}removeColumn(){if(this.colCount<=1)return!1;const t=[];for(let e=0;e<this.rowCount;e++){const o=[];for(let t=0;t<this.colCount-1;t++)o.push(this.data[e][t]);1===this.data[e][this.colCount-1].spanned&&this.findLeftCellWidthColspanAndDecreaseByOne(this.colCount-1,e),t.push(o)}return this.data=t,this.colCount--,!0}findLeftCellWidthColspanAndDecreaseByOne(t,e){const o=this.getCell(t-1,e);return!!o&&(1===o.spanned?this.findLeftCellWidthColspanAndDecreaseByOne(t-1,e):o.colspan>1&&this.removeColspan(t-1,e),!0)}addColumn(){for(let t=0;t<this.rowCount;t++){const e=this.getNewCell();e.name=this.colCount+"x"+t,this.data[t].push(e)}this.colCount++}drawTable(){const t=n.default("<colgroup>");for(let e=0;e<this.colCount;e++){const e=100/this.colCount;t.append(n.default("<col>").css({width:parseInt(e.toString(),10)+"%"}))}const e=n.default('<table id="base" class="table editor">');e.append(t);for(let t=0;t<this.rowCount;t++){if(0===this.data[t].length)continue;const o=n.default("<tr>");for(let e=0;e<this.colCount;e++){const i=this.data[t][e];if(1===i.spanned)continue;const l=100/this.rowCount,r=100/this.colCount,s=n.default("<td>").css({height:parseInt(l.toString(),10)*i.rowspan+"%",width:parseInt(r.toString(),10)*i.colspan+"%"}),d=n.default('<div class="cell_container">');s.append(d);const c=n.default('<a href="#" data-col="'+e+'" data-row="'+t+'">');d.append(c.clone().attr("class","t3js-grideditor-link-editor link link_editor").attr("title",TYPO3.lang.grid_editCell)),this.cellCanSpanRight(e,t)&&d.append(c.clone().attr("class","t3js-grideditor-link-expand-right link link_expand_right").attr("title",TYPO3.lang.grid_mergeCell)),this.cellCanShrinkLeft(e,t)&&d.append(c.clone().attr("class","t3js-grideditor-link-shrink-left link link_shrink_left").attr("title",TYPO3.lang.grid_splitCell)),this.cellCanSpanDown(e,t)&&d.append(c.clone().attr("class","t3js-grideditor-link-expand-down link link_expand_down").attr("title",TYPO3.lang.grid_mergeCell)),this.cellCanShrinkUp(e,t)&&d.append(c.clone().attr("class","t3js-grideditor-link-shrink-up link link_shrink_up").attr("title",TYPO3.lang.grid_splitCell)),s.append(n.default('<div class="cell_data">').html(TYPO3.lang.grid_name+": "+(i.name?a.stripMarkup(i.name):TYPO3.lang.grid_notSet)+"<br />"+TYPO3.lang.grid_column+": "+(void 0===i.column||isNaN(i.column)?TYPO3.lang.grid_notSet:parseInt(i.column,10)))),i.colspan>1&&s.attr("colspan",i.colspan),i.rowspan>1&&s.attr("rowspan",i.rowspan),o.append(s)}e.append(o)}n.default(this.targetElement).empty().append(e)}setName(t,e,o){const n=this.getCell(e,o);return!!n&&(n.name=a.stripMarkup(t),!0)}setColumn(t,e,o){const n=this.getCell(e,o);return!!n&&(n.column=parseInt(t.toString(),10),!0)}showOptions(t,e){const l=this.getCell(t,e);if(!l)return!1;let r;r=0===l.column?0:l.column?parseInt(l.column.toString(),10):"";const s=n.default("<div>"),d=n.default('<div class="form-group">'),c=n.default("<label>"),h=n.default("<input>");s.append([d.clone().append([c.clone().text(TYPO3.lang.grid_nameHelp),h.clone().attr("type","text").attr("class","t3js-grideditor-field-name form-control").attr("name","name").val(a.stripMarkup(l.name)||"")]),d.clone().append([c.clone().text(TYPO3.lang.grid_columnHelp),h.clone().attr("type","text").attr("class","t3js-grideditor-field-colpos form-control").attr("name","column").val(r)])]);const u=i.show(TYPO3.lang.grid_windowTitle,s,o.SeverityEnum.notice,[{active:!0,btnClass:"btn-default",name:"cancel",text:n.default(this).data("button-close-text")||TYPO3.lang["button.cancel"]||"Cancel"},{btnClass:"btn-primary",name:"ok",text:n.default(this).data("button-ok-text")||TYPO3.lang["button.ok"]||"OK"}]);return u.data("col",t),u.data("row",e),u.on("button.clicked",this.modalButtonClickHandler),!0}getCell(t,e){return!(t>this.colCount-1)&&(!(e>this.rowCount-1)&&(this.data.length>e-1&&this.data[e].length>t-1?this.data[e][t]:null))}cellCanSpanRight(t,e){if(t===this.colCount-1)return!1;const o=this.getCell(t,e);let n;if(o.rowspan>1){for(let i=e;i<e+o.rowspan;i++)if(n=this.getCell(t+o.colspan,i),!n||1===n.spanned||n.colspan>1||n.rowspan>1)return!1}else if(n=this.getCell(t+o.colspan,e),!n||1===o.spanned||1===n.spanned||n.colspan>1||n.rowspan>1)return!1;return!0}cellCanSpanDown(t,e){if(e===this.rowCount-1)return!1;const o=this.getCell(t,e);let n;if(o.colspan>1){for(let i=t;i<t+o.colspan;i++)if(n=this.getCell(i,e+o.rowspan),!n||1===n.spanned||n.colspan>1||n.rowspan>1)return!1}else if(n=this.getCell(t,e+o.rowspan),!n||1===o.spanned||1===n.spanned||n.colspan>1||n.rowspan>1)return!1;return!0}cellCanShrinkLeft(t,e){return this.data[e][t].colspan>1}cellCanShrinkUp(t,e){return this.data[e][t].rowspan>1}addColspan(t,e){const o=this.getCell(t,e);if(!o||!this.cellCanSpanRight(t,e))return!1;for(let n=e;n<e+o.rowspan;n++)this.data[n][t+o.colspan].spanned=1;return o.colspan+=1,!0}addRowspan(t,e){const o=this.getCell(t,e);if(!o||!this.cellCanSpanDown(t,e))return!1;for(let n=t;n<t+o.colspan;n++)this.data[e+o.rowspan][n].spanned=1;return o.rowspan+=1,!0}removeColspan(t,e){const o=this.getCell(t,e);if(!o||!this.cellCanShrinkLeft(t,e))return!1;o.colspan-=1;for(let n=e;n<e+o.rowspan;n++)this.data[n][t+o.colspan].spanned=0;return!0}removeRowspan(t,e){const o=this.getCell(t,e);if(!o||!this.cellCanShrinkUp(t,e))return!1;o.rowspan-=1;for(let n=t;n<t+o.colspan;n++)this.data[e+o.rowspan][n].spanned=0;return!0}export2LayoutRecord(){let t="backend_layout {\n\tcolCount = "+this.colCount+"\n\trowCount = "+this.rowCount+"\n\trows {\n";for(let e=0;e<this.rowCount;e++){t+="\t\t"+(e+1)+" {\n",t+="\t\t\tcolumns {\n";let o=0;for(let n=0;n<this.colCount;n++){const i=this.getCell(n,e);i&&(i.spanned||(o++,t+="\t\t\t\t"+o+" {\n",t+="\t\t\t\t\tname = "+(i.name?i.name:n+"x"+e)+"\n",i.colspan>1&&(t+="\t\t\t\t\tcolspan = "+i.colspan+"\n"),i.rowspan>1&&(t+="\t\t\t\t\trowspan = "+i.rowspan+"\n"),"number"==typeof i.column&&(t+="\t\t\t\t\tcolPos = "+i.column+"\n"),t+="\t\t\t\t}\n"))}t+="\t\t\t}\n",t+="\t\t}\n"}return t+="\t}\n}\n",t}}e.GridEditor=a})); \ No newline at end of file