Buttons for table editing.

pull/10/head
Jens Pelzetter 2021-08-30 15:15:33 +02:00
parent 05862f81eb
commit f136f75e11
3 changed files with 309 additions and 93 deletions

View File

@ -551,11 +551,76 @@
</div> </div>
</div> </div>
<button <button
class="btn btn-outline-dark tiptap-insert-table-row" class="btn btn-outline-dark tiptap-remove-table"
title="#{CmsAdminMessage['cms_editor.buttons.insert_table_row']}" title="#{CmsAdminMessage['cms_editor.buttons.remove_table']}"
type="button" type="button"
> >
Insert row Remove table
</button>
<button
class="btn btn-outline-dark tiptap-insert-table-row-before"
title="#{CmsAdminMessage['cms_editor.buttons.insert_table_row_before']}"
type="button"
>
Insert row before
</button>
<button
class="btn btn-outline-dark tiptap-insert-table-row-after"
title="#{CmsAdminMessage['cms_editor.buttons.insert_table_row_after']}"
type="button"
>
Insert row after
</button>
<button
class="btn btn-outline-dark tiptap-table-remove-row"
title="#{CmsAdminMessages['cms_editor.buttons.remove_table_row']}"
type="button">
Remove row
</button>
<button
class="btn btn-outline-dark tiptap-insert-table-column-before"
title="#{CmsAdminMessage['cms_editor.buttons.insert_table_column_before']}"
type="button"
>
Insert column before
</button>
<button
class="btn btn-outline-dark tiptap-insert-table-column-after"
title="#{CmsAdminMessage['cms_editor.buttons.insert_table_column_after']}"
type="button"
>
Insert column after
</button>
<button
class="btn btn-outline-dark tiptap-remove-table-column"
title="#{CmsAdminMessage['cms_editor.buttons.remove_table_column']}"
type="button"
>
Remove column
</button>
<button
class="btn btn-outline-dark tiptap-toggle-table-header-row"
title="#{CmsAdminMessage['cms_editor.buttons.toggle_header_rowy']}"
type="button">
Toggle Header row
</button>
<button
class="btn btn-outline-dark tiptap-toggle-table-header-column"
title="#{CmsAdminMessage['cms_editor.buttons.toggle_header_column']}"
type="button">
Toggle Header column
</button>
<button
class="btn btn-outline-dark tiptap-merge-table-cells"
title="#{CmsAdminMessage['cms_editor.buttons.merge-table-cells']}"
type="button">
Merge cells
</button>
<button
class="btn btn-outline-dark tiptap-split-table-cell"
title="#{CmsAdminMessage['cms_editor.buttons.split-table-cell']}"
type="button">
Split cell
</button> </button>
</div> </div>
</div> </div>

View File

@ -18,7 +18,7 @@
border: 1px solid #000; border: 1px solid #000;
margin-left: 0.2em; margin-left: 0.2em;
margin-right: 0.2em; margin-right: 0.2em;
width: 100%; // width: 100%;
td, th, tr { td, th, tr {
border: 1px solid #000; border: 1px solid #000;

View File

@ -13,10 +13,10 @@ import TableHeader from "@tiptap/extension-table-header";
const BUTTONS: CmsEditorButton[] = [ const BUTTONS: CmsEditorButton[] = [
{ {
selector: ".tiptap-emph", selector: ".tiptap-emph",
command: cmsEditor => { command: (cmsEditor) => {
return cmsEditor.getEditor().chain().focus().toggleItalic().run(); return cmsEditor.getEditor().chain().focus().toggleItalic().run();
}, },
can: cmsEditor => { can: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.can() .can()
@ -24,14 +24,14 @@ const BUTTONS: CmsEditorButton[] = [
.focus() .focus()
.toggleItalic() .toggleItalic()
.run(); .run();
} },
}, },
{ {
selector: ".tiptap-strong-emph", selector: ".tiptap-strong-emph",
command: cmsEditor => { command: (cmsEditor) => {
return cmsEditor.getEditor().chain().focus().toggleBold().run(); return cmsEditor.getEditor().chain().focus().toggleBold().run();
}, },
can: cmsEditor => { can: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.can() .can()
@ -39,14 +39,14 @@ const BUTTONS: CmsEditorButton[] = [
.focus() .focus()
.toggleBold() .toggleBold()
.run(); .run();
} },
}, },
{ {
selector: ".tiptap-code", selector: ".tiptap-code",
command: cmsEditor => { command: (cmsEditor) => {
return cmsEditor.getEditor().chain().focus().toggleCode().run(); return cmsEditor.getEditor().chain().focus().toggleCode().run();
}, },
can: cmsEditor => { can: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.can() .can()
@ -54,14 +54,14 @@ const BUTTONS: CmsEditorButton[] = [
.focus() .focus()
.toggleCode() .toggleCode()
.run(); .run();
} },
}, },
{ {
selector: ".tiptap-strikethrough", selector: ".tiptap-strikethrough",
command: cmsEditor => { command: (cmsEditor) => {
return cmsEditor.getEditor().chain().focus().toggleStrike().run(); return cmsEditor.getEditor().chain().focus().toggleStrike().run();
}, },
can: cmsEditor => { can: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.can() .can()
@ -69,11 +69,11 @@ const BUTTONS: CmsEditorButton[] = [
.focus() .focus()
.toggleStrike() .toggleStrike()
.run(); .run();
} },
}, },
{ {
selector: ".tiptap-subscript", selector: ".tiptap-subscript",
command: cmsEditor => { command: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.chain() .chain()
@ -81,7 +81,7 @@ const BUTTONS: CmsEditorButton[] = [
.toggleSubscript() .toggleSubscript()
.run(); .run();
}, },
can: cmsEditor => { can: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.can() .can()
@ -89,11 +89,11 @@ const BUTTONS: CmsEditorButton[] = [
.focus() .focus()
.toggleSubscript() .toggleSubscript()
.run(); .run();
} },
}, },
{ {
selector: ".tiptap-superscript", selector: ".tiptap-superscript",
command: cmsEditor => { command: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.chain() .chain()
@ -101,7 +101,7 @@ const BUTTONS: CmsEditorButton[] = [
.toggleSuperscript() .toggleSuperscript()
.run(); .run();
}, },
can: cmsEditor => { can: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.can() .can()
@ -109,11 +109,11 @@ const BUTTONS: CmsEditorButton[] = [
.focus() .focus()
.toggleSuperscript() .toggleSuperscript()
.run(); .run();
} },
}, },
{ {
selector: ".tiptap-h1", selector: ".tiptap-h1",
command: cmsEditor => { command: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.chain() .chain()
@ -121,7 +121,7 @@ const BUTTONS: CmsEditorButton[] = [
.toggleHeading({ level: 1 }) .toggleHeading({ level: 1 })
.run(); .run();
}, },
can: cmsEditor => { can: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.can() .can()
@ -129,11 +129,11 @@ const BUTTONS: CmsEditorButton[] = [
.focus() .focus()
.toggleHeading({ level: 1 }) .toggleHeading({ level: 1 })
.run(); .run();
} },
}, },
{ {
selector: ".tiptap-h2", selector: ".tiptap-h2",
command: cmsEditor => { command: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.chain() .chain()
@ -141,7 +141,7 @@ const BUTTONS: CmsEditorButton[] = [
.toggleHeading({ level: 2 }) .toggleHeading({ level: 2 })
.run(); .run();
}, },
can: cmsEditor => { can: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.can() .can()
@ -149,11 +149,11 @@ const BUTTONS: CmsEditorButton[] = [
.focus() .focus()
.toggleHeading({ level: 2 }) .toggleHeading({ level: 2 })
.run(); .run();
} },
}, },
{ {
selector: ".tiptap-h3", selector: ".tiptap-h3",
command: cmsEditor => { command: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.chain() .chain()
@ -161,7 +161,7 @@ const BUTTONS: CmsEditorButton[] = [
.toggleHeading({ level: 3 }) .toggleHeading({ level: 3 })
.run(); .run();
}, },
can: cmsEditor => { can: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.can() .can()
@ -169,11 +169,11 @@ const BUTTONS: CmsEditorButton[] = [
.focus() .focus()
.toggleHeading({ level: 3 }) .toggleHeading({ level: 3 })
.run(); .run();
} },
}, },
{ {
selector: ".tiptap-h5", selector: ".tiptap-h5",
command: cmsEditor => { command: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.chain() .chain()
@ -181,7 +181,7 @@ const BUTTONS: CmsEditorButton[] = [
.toggleHeading({ level: 5 }) .toggleHeading({ level: 5 })
.run(); .run();
}, },
can: cmsEditor => { can: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.can() .can()
@ -189,11 +189,11 @@ const BUTTONS: CmsEditorButton[] = [
.focus() .focus()
.toggleHeading({ level: 5 }) .toggleHeading({ level: 5 })
.run(); .run();
} },
}, },
{ {
selector: ".tiptap-h6", selector: ".tiptap-h6",
command: cmsEditor => { command: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.chain() .chain()
@ -201,7 +201,7 @@ const BUTTONS: CmsEditorButton[] = [
.toggleHeading({ level: 6 }) .toggleHeading({ level: 6 })
.run(); .run();
}, },
can: cmsEditor => { can: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.can() .can()
@ -209,14 +209,14 @@ const BUTTONS: CmsEditorButton[] = [
.focus() .focus()
.toggleHeading({ level: 6 }) .toggleHeading({ level: 6 })
.run(); .run();
} },
}, },
{ {
selector: ".tiptap-paragraph", selector: ".tiptap-paragraph",
command: cmsEditor => { command: (cmsEditor) => {
return cmsEditor.getEditor().chain().focus().clearNodes().run(); return cmsEditor.getEditor().chain().focus().clearNodes().run();
}, },
can: cmsEditor => { can: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.can() .can()
@ -224,11 +224,11 @@ const BUTTONS: CmsEditorButton[] = [
.focus() .focus()
.clearNodes() .clearNodes()
.run(); .run();
} },
}, },
{ {
selector: ".tiptap-blockquote", selector: ".tiptap-blockquote",
command: cmsEditor => { command: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.chain() .chain()
@ -236,7 +236,7 @@ const BUTTONS: CmsEditorButton[] = [
.toggleBlockquote() .toggleBlockquote()
.run(); .run();
}, },
can: cmsEditor => { can: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.can() .can()
@ -244,11 +244,11 @@ const BUTTONS: CmsEditorButton[] = [
.focus() .focus()
.toggleBlockquote() .toggleBlockquote()
.run(); .run();
} },
}, },
{ {
selector: ".tiptap-codeblock", selector: ".tiptap-codeblock",
command: cmsEditor => { command: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.chain() .chain()
@ -256,7 +256,7 @@ const BUTTONS: CmsEditorButton[] = [
.toggleCodeBlock() .toggleCodeBlock()
.run(); .run();
}, },
can: cmsEditor => { can: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.can() .can()
@ -264,11 +264,11 @@ const BUTTONS: CmsEditorButton[] = [
.focus() .focus()
.toggleCodeBlock() .toggleCodeBlock()
.run(); .run();
} },
}, },
{ {
selector: ".tiptap-ul", selector: ".tiptap-ul",
command: cmsEditor => { command: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.chain() .chain()
@ -276,7 +276,7 @@ const BUTTONS: CmsEditorButton[] = [
.toggleBulletList() .toggleBulletList()
.run(); .run();
}, },
can: cmsEditor => { can: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.can() .can()
@ -284,11 +284,11 @@ const BUTTONS: CmsEditorButton[] = [
.focus() .focus()
.toggleBulletList() .toggleBulletList()
.run(); .run();
} },
}, },
{ {
selector: ".tiptap-ol", selector: ".tiptap-ol",
command: cmsEditor => { command: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.chain() .chain()
@ -296,7 +296,7 @@ const BUTTONS: CmsEditorButton[] = [
.toggleOrderedList() .toggleOrderedList()
.run(); .run();
}, },
can: cmsEditor => { can: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.can() .can()
@ -304,14 +304,14 @@ const BUTTONS: CmsEditorButton[] = [
.focus() .focus()
.toggleOrderedList() .toggleOrderedList()
.run(); .run();
} },
}, },
{ {
selector: ".cms-editor-insert-table-dialog", selector: ".cms-editor-insert-table-dialog",
command: cmsEditor => { command: (cmsEditor) => {
return true; return true;
}, },
can: cmsEditor => { can: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.can() .can()
@ -319,11 +319,11 @@ const BUTTONS: CmsEditorButton[] = [
.focus() .focus()
.insertTable() .insertTable()
.run(); .run();
} },
}, },
{ {
selector: ".cms-editor-insert-table-dialog .btn-success", selector: ".cms-editor-insert-table-dialog .btn-success",
command: cmsEditor => { command: (cmsEditor) => {
const dialog = cmsEditor const dialog = cmsEditor
.getEditorElem() .getEditorElem()
.querySelector(".cms-editor-insert-table-dialog"); .querySelector(".cms-editor-insert-table-dialog");
@ -351,19 +351,41 @@ const BUTTONS: CmsEditorButton[] = [
.getEditor() .getEditor()
.chain() .chain()
.focus() .focus()
.insertTable({ cols: cols, rows: rows, headerRow: headerRow }) .insertTable({
allowTableNodeSelection: true,
cellMinWidth: 150,
cols: cols,
headerRow: headerRow,
resizable: true,
rows: rows,
})
.run(); .run();
}, },
can: cmsEditor => { can: (cmsEditor) => {
return true; return true;
} },
}, },
{ {
selector: ".tiptap-insert-table-row", selector: ".tiptap-insert-table-row-before",
command: cmsEditor => { command: (cmsEditor) => {
return cmsEditor.getEditor().chain().focus().addRowBefore().run();
},
can: (cmsEditor) => {
return cmsEditor
.getEditor()
.can()
.chain()
.focus()
.addRowBefore()
.run();
},
},
{
selector: ".tiptap-insert-table-row-after",
command: (cmsEditor) => {
return cmsEditor.getEditor().chain().focus().addRowAfter().run(); return cmsEditor.getEditor().chain().focus().addRowAfter().run();
}, },
can: cmsEditor => { can: (cmsEditor) => {
return cmsEditor return cmsEditor
.getEditor() .getEditor()
.can() .can()
@ -371,29 +393,158 @@ const BUTTONS: CmsEditorButton[] = [
.focus() .focus()
.addRowAfter() .addRowAfter()
.run(); .run();
} },
} },
// , {
// { selector: ".tiptap-insert-table-column-before",
// selector: "", command: (cmsEditor) => {
// command: cmsEditor => {}, return cmsEditor
// can: cmsEditor => {} .getEditor()
// }, .chain()
// { .focus()
// selector: "", .addColumnBefore()
// command: cmsEditor => {}, .run();
// can: cmsEditor => {} },
// }, can: (cmsEditor) => {
// { return cmsEditor
// selector: "", .getEditor()
// command: cmsEditor => {}, .can()
// can: cmsEditor => {} .chain()
// }, .focus()
// { .addColumnBefore()
// selector: "", .run();
// command: cmsEditor => {}, },
// can: cmsEditor => {} },
// }, {
selector: ".tiptap-insert-table-column-after",
command: (cmsEditor) => {
return cmsEditor.getEditor().chain().focus().addColumnAfter().run();
},
can: (cmsEditor) => {
return cmsEditor
.getEditor()
.can()
.chain()
.focus()
.addColumnAfter()
.run();
},
},
{
selector: ".tiptap-remove-table-row",
command: (cmsEditor) => {
return cmsEditor.getEditor().chain().focus().deleteRow().run();
},
can: (cmsEditor) => {
return cmsEditor
.getEditor()
.can()
.chain()
.focus()
.deleteRow()
.run();
},
},
{
selector: ".tiptap-remove-table-column",
command: (cmsEditor) => {
return cmsEditor.getEditor().chain().focus().deleteColumn().run();
},
can: (cmsEditor) => {
return cmsEditor
.getEditor()
.can()
.chain()
.focus()
.deleteColumn()
.run();
},
},
{
selector: ".tiptap-remove-table",
command: (cmsEditor) => {
return cmsEditor.getEditor().chain().focus().deleteTable().run();
},
can: (cmsEditor) => {
return cmsEditor
.getEditor()
.can()
.chain()
.focus()
.deleteTable()
.run();
},
},
{
selector: ".tiptap-toggle-table-header-row",
command: (cmsEditor) => {
return cmsEditor
.getEditor()
.chain()
.focus()
.toggleHeaderRow()
.run();
},
can: (cmsEditor) => {
return cmsEditor
.getEditor()
.can()
.chain()
.focus()
.toggleHeaderRow()
.run();
},
},
{
selector: ".tiptap-toggle-table-header-column",
command: (cmsEditor) => {
return cmsEditor
.getEditor()
.chain()
.focus()
.toggleHeaderColumn()
.run();
},
can: (cmsEditor) => {
return cmsEditor
.getEditor()
.can()
.chain()
.focus()
.toggleHeaderColumn()
.run();
},
},
{
selector: ".tiptap-merge-table-cells",
command: (cmsEditor) => {
return cmsEditor.getEditor().chain().focus().mergeCells().run();
},
can: (cmsEditor) => {
return cmsEditor
.getEditor()
.can()
.chain()
.focus()
.mergeCells()
.run();
},
},
{
selector: ".tiptap-split-table-cell",
command: (cmsEditor) => {
return cmsEditor.getEditor().chain().focus().splitCell().run();
},
can: (cmsEditor) => {
return cmsEditor
.getEditor()
.can()
.chain()
.focus()
.splitCell()
.run();
},
},
// { // {
// selector: "", // selector: "",
// command: cmsEditor => {}, // command: cmsEditor => {},
@ -438,7 +589,7 @@ class CmsEditor {
for (const button of BUTTONS) { for (const button of BUTTONS) {
const buttonElem = buttonsElem.querySelector(button.selector); const buttonElem = buttonsElem.querySelector(button.selector);
if (buttonElem) { if (buttonElem) {
buttonElem.addEventListener("click", event => { buttonElem.addEventListener("click", (event) => {
event.preventDefault(); event.preventDefault();
button.command(this); button.command(this);
}); });
@ -477,7 +628,7 @@ class CmsEditor {
console.log(`editorElem = ${editorElem}`); console.log(`editorElem = ${editorElem}`);
const saveButton = editorElem.querySelector(".cms-editor-save-button"); const saveButton = editorElem.querySelector(".cms-editor-save-button");
saveButton?.addEventListener("click", event => this.save(event)); saveButton?.addEventListener("click", (event) => this.save(event));
} }
protected async save(event: Event) { protected async save(event: Event) {
@ -491,9 +642,9 @@ class CmsEditor {
method: "POST", method: "POST",
credentials: "include", credentials: "include",
headers: { headers: {
"Content-Type": "application/x-www-form-urlencoded" "Content-Type": "application/x-www-form-urlencoded",
}, },
body: params body: params,
}); });
if (response.ok) { if (response.ok) {
} else { } else {
@ -569,9 +720,9 @@ class CmsEditorBuilder {
Table.configure({ resizable: true }), Table.configure({ resizable: true }),
TableRow, TableRow,
TableHeader, TableHeader,
TableCell TableCell,
], ],
content: variant content: variant,
}); });
return new CmsEditor(editor, this.editorElem, this.saveUrl); return new CmsEditor(editor, this.editorElem, this.saveUrl);
@ -581,7 +732,7 @@ class CmsEditorBuilder {
try { try {
const response = await fetch(variantUrl, { const response = await fetch(variantUrl, {
method: "GET", method: "GET",
credentials: "include" credentials: "include",
}); });
if (response.ok) { if (response.ok) {