diff --git a/projects/editor/src/app/app.module.ts b/projects/editor/src/app/app.module.ts index 60aea9f31506606ce20e4748ed4de5c7ad66e1f8..5621dc791d0e2ae965019d739a325dabe0337298 100644 --- a/projects/editor/src/app/app.module.ts +++ b/projects/editor/src/app/app.module.ts @@ -53,6 +53,10 @@ import { ElementModelPropertiesComponent } from './components/unit-view/page-view/properties-panel/element-model-properties.component'; import { DropListOptionEditDialogComponent } from './components/dialogs/drop-list-option-edit-dialog.component'; +import { NodeviewToggleButtonComponent } from './text-editor/node-views/nodeview-toggle-button.component'; +import { NodeviewTextFieldComponent } from './text-editor/node-views/nodeview-text-field.component'; +import { NodeviewDropListComponent } from './text-editor/node-views/nodeview-drop-list.component'; + @NgModule({ declarations: [ AppComponent, @@ -68,6 +72,9 @@ import { DropListOptionEditDialogComponent } from './components/dialogs/drop-lis SectionStaticComponent, SectionDynamicComponent, RichTextEditorComponent, + NodeviewToggleButtonComponent, + NodeviewTextFieldComponent, + NodeviewDropListComponent, ElementStylePropertiesComponent, ElementSizingPropertiesComponent, ConfirmationDialogComponent, diff --git a/projects/editor/src/app/text-editor/bulletList-extension.ts b/projects/editor/src/app/text-editor/extensions/bullet-list.ts similarity index 96% rename from projects/editor/src/app/text-editor/bulletList-extension.ts rename to projects/editor/src/app/text-editor/extensions/bullet-list.ts index cb37f6fdf61e887ddef7b45a9a8224d6ee9811f0..59c8679e28a574a4f109672ed8d384be4e763e68 100644 --- a/projects/editor/src/app/text-editor/bulletList-extension.ts +++ b/projects/editor/src/app/text-editor/extensions/bullet-list.ts @@ -10,7 +10,7 @@ declare module '@tiptap/core' { } } -export const bulletListExtension = BulletList.extend({ +export const BulletListExtension = BulletList.extend({ addAttributes() { return { listStyle: { diff --git a/projects/editor/src/app/text-editor/font-size-extension.ts b/projects/editor/src/app/text-editor/extensions/font-size.ts similarity index 92% rename from projects/editor/src/app/text-editor/font-size-extension.ts rename to projects/editor/src/app/text-editor/extensions/font-size.ts index 94bcdaeb73e5c30ae4c9a9ca65102fefbaaf7516..6a65bfccea5c2411663b4d194d0efe154c1e1a4c 100644 --- a/projects/editor/src/app/text-editor/font-size-extension.ts +++ b/projects/editor/src/app/text-editor/extensions/font-size.ts @@ -9,7 +9,7 @@ declare module '@tiptap/core' { } } -export const fontSizeExtension = TextStyle.extend({ +export const FontSizeExtension = TextStyle.extend({ addAttributes() { return { fontSize: { diff --git a/projects/editor/src/app/text-editor/hanging-indent.ts b/projects/editor/src/app/text-editor/extensions/hanging-indent.ts similarity index 100% rename from projects/editor/src/app/text-editor/hanging-indent.ts rename to projects/editor/src/app/text-editor/extensions/hanging-indent.ts diff --git a/projects/editor/src/app/text-editor/indent.ts b/projects/editor/src/app/text-editor/extensions/indent.ts similarity index 100% rename from projects/editor/src/app/text-editor/indent.ts rename to projects/editor/src/app/text-editor/extensions/indent.ts diff --git a/projects/editor/src/app/text-editor/orderedList-extension.ts b/projects/editor/src/app/text-editor/extensions/orderedList-extension.ts similarity index 96% rename from projects/editor/src/app/text-editor/orderedList-extension.ts rename to projects/editor/src/app/text-editor/extensions/orderedList-extension.ts index cffc604f3da33645b7d92137cd0c0f401b0ce705..b3785201e96ec72a2bb47e06be62828c94ce3889 100644 --- a/projects/editor/src/app/text-editor/orderedList-extension.ts +++ b/projects/editor/src/app/text-editor/extensions/orderedList-extension.ts @@ -10,7 +10,7 @@ declare module '@tiptap/core' { } } -export const orderedListExtension = OrderedList.extend({ +export const OrderedListExtension = OrderedList.extend({ addAttributes() { return { listStyle: { diff --git a/projects/editor/src/app/text-editor/paragraph-extension.ts b/projects/editor/src/app/text-editor/extensions/paragraph-extension.ts similarity index 96% rename from projects/editor/src/app/text-editor/paragraph-extension.ts rename to projects/editor/src/app/text-editor/extensions/paragraph-extension.ts index 52415f312937196e2506895b343ec587cbcad506..a3c0f4b3ef8fd39d2848284487f736baf00347d6 100644 --- a/projects/editor/src/app/text-editor/paragraph-extension.ts +++ b/projects/editor/src/app/text-editor/extensions/paragraph-extension.ts @@ -10,7 +10,7 @@ declare module '@tiptap/core' { } } -export const customParagraph = Paragraph.extend({ +export const paragraphExtension = Paragraph.extend({ addAttributes() { return { margin: { diff --git a/projects/editor/src/app/text-editor/node-views/drop-list-component-extension.ts b/projects/editor/src/app/text-editor/node-views/drop-list-component-extension.ts new file mode 100644 index 0000000000000000000000000000000000000000..46d01fce5f836cfb49f1391634eb2d8fdb4c459e --- /dev/null +++ b/projects/editor/src/app/text-editor/node-views/drop-list-component-extension.ts @@ -0,0 +1,33 @@ +import { Injector } from '@angular/core'; +import { Node, mergeAttributes } from '@tiptap/core'; +import { AngularNodeViewRenderer } from 'ngx-tiptap'; + +import { NodeviewDropListComponent } from './nodeview-drop-list.component'; + +const DropListComponentExtension = (injector: Injector): Node => { + return Node.create({ + group: 'inline', + inline: true, + name: 'DropList', + + addAttributes() { + return { + id: { + default: 'will be generated' + } + }; + }, + + parseHTML() { + return [{ tag: 'app-nodeview-drop-list' }]; + }, + renderHTML({ HTMLAttributes }) { + return ['app-nodeview-drop-list', mergeAttributes(HTMLAttributes)]; + }, + addNodeView() { + return AngularNodeViewRenderer(NodeviewDropListComponent, { injector }); + } + }); +}; + +export default DropListComponentExtension; diff --git a/projects/editor/src/app/text-editor/node-views/nodeview-drop-list.component.ts b/projects/editor/src/app/text-editor/node-views/nodeview-drop-list.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..32dc0dc50494b0bed25b3a2ef9b9e6b9623dd697 --- /dev/null +++ b/projects/editor/src/app/text-editor/node-views/nodeview-drop-list.component.ts @@ -0,0 +1,24 @@ +import { Component } from '@angular/core'; +import { AngularNodeViewComponent } from 'ngx-tiptap'; +import { DropListSimpleElement } from '../../../../../common/ui-elements/drop-list-simple/drop-list-simple'; + +@Component({ + selector: 'app-nodeview-drop-list', + template: ` + <div [style.display]="'inline-block'" + [style.vertical-align]="'middle'" + [style.width.px]="model.width" + [style.height.px]="model.height"> + <app-drop-list-simple [elementModel]="model" + [matTooltip]="'ID: ' + node.attrs.id"> + </app-drop-list-simple> + </div> + ` +}) +export class NodeviewDropListComponent extends AngularNodeViewComponent { + model: DropListSimpleElement = new DropListSimpleElement({ + type: 'drop-list', + height: 25, + width: 100 + }); +} diff --git a/projects/editor/src/app/text-editor/node-views/nodeview-text-field.component.ts b/projects/editor/src/app/text-editor/node-views/nodeview-text-field.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..9c57cdfd52055b41d5b1606f96c9e1b6f77269a5 --- /dev/null +++ b/projects/editor/src/app/text-editor/node-views/nodeview-text-field.component.ts @@ -0,0 +1,18 @@ +import { Component } from '@angular/core'; +import { AngularNodeViewComponent } from 'ngx-tiptap'; +import { TextFieldSimpleElement } from '../../../../../common/ui-elements/textfield-simple/text-field-simple-element'; + +@Component({ + selector: 'app-nodeview-text-field', + template: ` + <app-text-field-simple [style.display]="'inline-block'" + [elementModel]="model" + [matTooltip]="'ID: ' + node.attrs.id"> + </app-text-field-simple> + ` +}) +export class NodeviewTextFieldComponent extends AngularNodeViewComponent { + model: TextFieldSimpleElement = new TextFieldSimpleElement({ + type: 'text-field' + }); +} diff --git a/projects/editor/src/app/text-editor/node-views/nodeview-toggle-button.component.ts b/projects/editor/src/app/text-editor/node-views/nodeview-toggle-button.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..91be96e9b9a5652c54601f788d53dd4ab276d044 --- /dev/null +++ b/projects/editor/src/app/text-editor/node-views/nodeview-toggle-button.component.ts @@ -0,0 +1,18 @@ +import { Component } from '@angular/core'; +import { AngularNodeViewComponent } from 'ngx-tiptap'; +import { ToggleButtonElement } from '../../../../../common/ui-elements/toggle-button/toggle-button'; + +@Component({ + selector: 'app-nodeview-toggle-button', + template: ` + <app-toggle-button [style.display]="'inline-block'" + [elementModel]="model" + [matTooltip]="'ID: ' + node.attrs.id"> + </app-toggle-button> + ` +}) +export class NodeviewToggleButtonComponent extends AngularNodeViewComponent { + model: ToggleButtonElement = new ToggleButtonElement({ + type: 'toggle-button' + }); +} diff --git a/projects/editor/src/app/text-editor/node-views/text-field-component-extension.ts b/projects/editor/src/app/text-editor/node-views/text-field-component-extension.ts new file mode 100644 index 0000000000000000000000000000000000000000..8597a2d3672f8d58fad0d3c7d4198c2be5b70fa5 --- /dev/null +++ b/projects/editor/src/app/text-editor/node-views/text-field-component-extension.ts @@ -0,0 +1,33 @@ +import { Injector } from '@angular/core'; +import { Node, mergeAttributes } from '@tiptap/core'; +import { AngularNodeViewRenderer } from 'ngx-tiptap'; + +import { NodeviewTextFieldComponent } from './nodeview-text-field.component'; + +const TextFieldComponentExtension = (injector: Injector): Node => { + return Node.create({ + group: 'inline', + inline: true, + name: 'TextField', + + addAttributes() { + return { + id: { + default: 'will be generated' + } + }; + }, + + parseHTML() { + return [{ tag: 'app-nodeview-text-field' }]; + }, + renderHTML({ HTMLAttributes }) { + return ['app-nodeview-text-field', mergeAttributes(HTMLAttributes)]; + }, + addNodeView() { + return AngularNodeViewRenderer(NodeviewTextFieldComponent, { injector }); + } + }); +}; + +export default TextFieldComponentExtension; diff --git a/projects/editor/src/app/text-editor/node-views/toggle-button-component-extension.ts b/projects/editor/src/app/text-editor/node-views/toggle-button-component-extension.ts new file mode 100644 index 0000000000000000000000000000000000000000..8c049208bf6a5b0d02fcfb64e486a65ed74f8ca1 --- /dev/null +++ b/projects/editor/src/app/text-editor/node-views/toggle-button-component-extension.ts @@ -0,0 +1,33 @@ +import { Injector } from '@angular/core'; +import { Node, mergeAttributes } from '@tiptap/core'; +import { AngularNodeViewRenderer } from 'ngx-tiptap'; + +import { NodeviewToggleButtonComponent } from './nodeview-toggle-button.component'; + +const ToggleButtonComponentExtension = (injector: Injector): Node => { + return Node.create({ + group: 'inline', + inline: true, + name: 'ToggleButton', + + addAttributes() { + return { + id: { + default: 'will be generated' + } + }; + }, + + parseHTML() { + return [{ tag: 'app-nodeview-toggle-button' }]; + }, + renderHTML({ HTMLAttributes }) { + return ['app-nodeview-toggle-button', mergeAttributes(HTMLAttributes)]; + }, + addNodeView() { + return AngularNodeViewRenderer(NodeviewToggleButtonComponent, { injector }); + } + }); +}; + +export default ToggleButtonComponentExtension; diff --git a/projects/editor/src/app/text-editor/rich-text-editor.component.html b/projects/editor/src/app/text-editor/rich-text-editor.component.html index 837b41ce08cecd9b3de92dbf057c90d5b6960f7b..869c43e66d3130a0352aa958304018d36cb7a851 100644 --- a/projects/editor/src/app/text-editor/rich-text-editor.component.html +++ b/projects/editor/src/app/text-editor/rich-text-editor.component.html @@ -245,16 +245,16 @@ </button> </div> <div *ngIf="showCloseElements" fxLayout="row" fxLayoutAlign="space-around center" > - <button mat-icon-button matTooltip="Eingabefeld (\i)" [matTooltipShowDelay]="300" - (click)="insertSpecialChar('\\i')"> + <button mat-icon-button matTooltip="Eingabefeld" [matTooltipShowDelay]="300" + (click)="insertTextField()"> <mat-icon>text_fields</mat-icon> </button> - <button mat-icon-button matTooltip="Ablegefeld (\z)" [matTooltipShowDelay]="300" - (click)="insertSpecialChar('\\z')"> + <button mat-icon-button matTooltip="Ablegefeld" [matTooltipShowDelay]="300" + (click)="insertDropList()"> <mat-icon>drag_indicator</mat-icon> </button> - <button mat-icon-button matTooltip="Optionsfeld (\r)" [matTooltipShowDelay]="300" - (click)="insertSpecialChar('\\r')"> + <button mat-icon-button matTooltip="Optionsfeld" [matTooltipShowDelay]="300" + (click)="insertToggleButton()"> <mat-icon>radio_button_checked</mat-icon> </button> </div> diff --git a/projects/editor/src/app/text-editor/rich-text-editor.component.ts b/projects/editor/src/app/text-editor/rich-text-editor.component.ts index e0038ceb306611345e19b666e42a150df96cf901..4c97b21e3f0da9712cd76b3ddd6055718cc8923d 100644 --- a/projects/editor/src/app/text-editor/rich-text-editor.component.ts +++ b/projects/editor/src/app/text-editor/rich-text-editor.component.ts @@ -1,6 +1,6 @@ import { Component, EventEmitter, Input, Output, ViewEncapsulation, - AfterViewInit + AfterViewInit, Injector } from '@angular/core'; import { Editor } from '@tiptap/core'; import StarterKit from '@tiptap/starter-kit'; @@ -14,14 +14,18 @@ import { TextAlign } from '@tiptap/extension-text-align'; import { Heading } from '@tiptap/extension-heading'; import { Image } from '@tiptap/extension-image'; import { Blockquote } from '@tiptap/extension-blockquote'; -import { Indent } from './indent'; -import { HangingIndent } from './hanging-indent'; -import { customParagraph } from './paragraph-extension'; -import { fontSizeExtension } from './font-size-extension'; -import { bulletListExtension } from './bulletList-extension'; -import { orderedListExtension } from './orderedList-extension'; +import { Indent } from './extensions/indent'; +import { HangingIndent } from './extensions/hanging-indent'; +import { paragraphExtension } from './extensions/paragraph-extension'; +import { FontSizeExtension } from './extensions/font-size'; +import { BulletListExtension } from './extensions/bullet-list'; +import { OrderedListExtension } from './extensions/orderedList-extension'; import { FileService } from '../services/file.service'; +import ToggleButtonComponentExtension from './node-views/toggle-button-component-extension'; +import DropListComponentExtension from './node-views/drop-list-component-extension'; +import TextFieldComponentExtension from './node-views/text-field-component-extension'; + @Component({ selector: 'app-rich-text-editor', templateUrl: './rich-text-editor.component.html', @@ -58,10 +62,10 @@ export class RichTextEditorComponent implements AfterViewInit { Heading.configure({ levels: [1, 2, 3, 4] }), - customParagraph, - fontSizeExtension, - bulletListExtension, - orderedListExtension, + paragraphExtension, + FontSizeExtension, + BulletListExtension, + OrderedListExtension, HangingIndent, Image.configure({ inline: true, @@ -69,10 +73,15 @@ export class RichTextEditorComponent implements AfterViewInit { style: 'display: inline-block; height: 1em; vertical-align: middle' } }), - Blockquote + Blockquote, + ToggleButtonComponentExtension(this.injector), + DropListComponentExtension(this.injector), + TextFieldComponentExtension(this.injector) ] }); + constructor(private injector: Injector) { } + ngAfterViewInit(): void { this.editor.commands.focus(); } @@ -186,4 +195,16 @@ export class RichTextEditorComponent implements AfterViewInit { toggleBlockquote(): void { this.editor.commands.toggleBlockquote(); } + + insertToggleButton(): void { + this.editor.commands.insertContent('<app-nodeview-toggle-button></app-nodeview-toggle-button>'); + } + + insertDropList(): void { + this.editor.commands.insertContent('<app-nodeview-drop-list></app-nodeview-drop-list>'); + } + + insertTextField(): void { + this.editor.commands.insertContent('<app-nodeview-text-field></app-nodeview-text-field>'); + } }