Newer
Older
Component, EventEmitter, Input, Output, QueryList, ViewChildren
import { CompoundElementComponent } from '../../directives/compound-element.directive';
import { ClozeDocumentParagraph, ClozeDocumentPart, InputElement } from '../../models/uI-element';
import { FormElementComponent } from '../../directives/form-element-component.directive';
import { CompoundChildOverlayComponent } from '../../directives/cloze-child-overlay/compound-child-overlay.component';
import { ElementComponent } from '../../directives/element-component.directive';
import { LikertRadioButtonGroupComponent } from '../likert/likert-radio-button-group.component';
<ng-container *ngIf="elementModel.document.content.length == 0">
Kein Dokument vorhanden
</ng-container>
<div [class.center-content]="elementModel.positionProps.dynamicPositioning &&
elementModel.positionProps.fixedSize"
[style.width]="elementModel.positionProps.fixedSize ? elementModel.width + 'px' : '100%'"
[style.height]="elementModel.positionProps.fixedSize ? elementModel.height + 'px' : 'auto'">
<ng-container *ngFor="let part of elementModel.document.content">
<ul *ngIf="part.type === 'bulletList'">
<li *ngFor="let listItem of part.content">
<ng-container *ngFor="let listItemPart of $any(listItem).content"
[ngTemplateOutlet]="paragraphs"
[ngTemplateOutletContext]="{ $implicit: listItemPart }"></ng-container>
</li>
</ul>
<ol *ngIf="part.type === 'orderedList'">
<li *ngFor="let listItem of part.content">
<ng-container *ngFor="let listItemPart of $any(listItem).content"
[ngTemplateOutlet]="paragraphs"
[ngTemplateOutletContext]="{ $implicit: listItemPart }"></ng-container>
</li>
</ol>
<blockquote *ngIf="part.type === 'blockquote'">
<ng-container *ngFor="let blockquotePart of $any(part).content"
[ngTemplateOutlet]="paragraphs"
[ngTemplateOutletContext]="{ $implicit: blockquotePart }"></ng-container>
</blockquote>
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
<ng-container *ngIf="part.type !== 'bulletList'"
[ngTemplateOutlet]="paragraphs"
[ngTemplateOutletContext]="{ $implicit: part }"></ng-container>
</ng-container>
</div>
<ng-template #paragraphs let-part>
<p *ngIf="part.type === 'paragraph'"
[style.line-height.%]="elementModel.fontProps.lineHeight"
[style.color]="elementModel.fontProps.fontColor"
[style.font-family]="elementModel.fontProps.font"
[style.font-size.px]="elementModel.fontProps.fontSize"
[style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''"
[style.font-style]="elementModel.fontProps.italic ? 'italic' : ''"
[style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''"
[style.margin-bottom]="part.attrs.margin + 'px'"
[style.margin-left]="part.attrs.hangingIndent ? '' :
($any(part.attrs.indentSize) * $any(part.attrs.indent)) + 'px'"
[style.text-align]="part.attrs.textAlign"
[style.text-indent]="part.attrs.hangingIndent ?
($any(part.attrs.indentSize) * $any(part.attrs.indent)) + 'px' :
''">
<ng-container [ngTemplateOutlet]="paragraphChildren"
[ngTemplateOutletContext]="{ $implicit: part }"></ng-container>
</p>
<h1 *ngIf="part.type === 'heading' && part.attrs.level === 1"
[style.display]="'inline'"
[style.line-height.%]="elementModel.fontProps.lineHeight"
[style.color]="elementModel.fontProps.fontColor"
[style.font-family]="elementModel.fontProps.font"
[style.font-size.px]="elementModel.fontProps.fontSize"
[style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''"
[style.font-style]="elementModel.fontProps.italic ? 'italic' : ''"
[style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''">
<ng-container [ngTemplateOutlet]="paragraphChildren"
[ngTemplateOutletContext]="{ $implicit: part }"></ng-container>
</h1>
<h2 *ngIf="part.type === 'heading' && part.attrs.level === 2"
[style.display]="'inline'"
[style.line-height.%]="elementModel.fontProps.lineHeight"
[style.color]="elementModel.fontProps.fontColor"
[style.font-family]="elementModel.fontProps.font"
[style.font-size.px]="elementModel.fontProps.fontSize"
[style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''"
[style.font-style]="elementModel.fontProps.italic ? 'italic' : ''"
[style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''">
<ng-container [ngTemplateOutlet]="paragraphChildren"
[ngTemplateOutletContext]="{ $implicit: part }"></ng-container>
</h2>
<h3 *ngIf="part.type === 'heading' && part.attrs.level === 3"
[style.display]="'inline'"
[style.line-height.%]="elementModel.fontProps.lineHeight"
[style.color]="elementModel.fontProps.fontColor"
[style.font-family]="elementModel.fontProps.font"
[style.font-size.px]="elementModel.fontProps.fontSize"
[style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''"
[style.font-style]="elementModel.fontProps.italic ? 'italic' : ''"
[style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''">
<ng-container [ngTemplateOutlet]="paragraphChildren"
[ngTemplateOutletContext]="{ $implicit: part }"></ng-container>
</h3>
<h4 *ngIf="part.type === 'heading' && part.attrs.level === 4"
[style.display]="'inline'"
[style.line-height.%]="elementModel.fontProps.lineHeight"
[style.color]="elementModel.fontProps.fontColor"
[style.font-family]="elementModel.fontProps.font"
[style.font-size.px]="elementModel.fontProps.fontSize"
[style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''"
[style.font-style]="elementModel.fontProps.italic ? 'italic' : ''"
[style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''">
<ng-container [ngTemplateOutlet]="paragraphChildren"
[ngTemplateOutletContext]="{ $implicit: part }"></ng-container>
</h4>
<h5 *ngIf="part.type === 'heading' && part.attrs.level === 5"
[style.display]="'inline'"
[style.line-height.%]="elementModel.fontProps.lineHeight"
[style.color]="elementModel.fontProps.fontColor"
[style.font-family]="elementModel.fontProps.font"
[style.font-size.px]="elementModel.fontProps.fontSize"
[style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''"
[style.font-style]="elementModel.fontProps.italic ? 'italic' : ''"
[style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''">
<ng-container [ngTemplateOutlet]="paragraphChildren"
[ngTemplateOutletContext]="{ $implicit: part }"></ng-container>
</h5>
<h6 *ngIf="part.type === 'heading' && part.attrs.level === 6"
[style.display]="'inline'"
[style.line-height.%]="elementModel.fontProps.lineHeight"
[style.color]="elementModel.fontProps.fontColor"
[style.font-family]="elementModel.fontProps.font"
[style.font-size.px]="elementModel.fontProps.fontSize"
[style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''"
[style.font-style]="elementModel.fontProps.italic ? 'italic' : ''"
[style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''">
<ng-container [ngTemplateOutlet]="paragraphChildren"
[ngTemplateOutletContext]="{ $implicit: part }"></ng-container>
</h6>
</ng-template>
<ng-template #paragraphChildren let-part>
<ng-container *ngFor="let subPart of part.content">
<ng-container *ngIf="$any(subPart).type === 'text'">
<span [ngStyle]="subPart.marks | styleMarks">
{{subPart.text}}
</span>
</ng-container>
<ng-container *ngIf="$any(subPart).type === 'image'">
<img [src]="subPart.attrs.src" [alt]="subPart.attrs.alt"
[style.display]="'inline-block'"
[style.height]="'1em'"
[style.vertical-align]="'middle'">
</ng-container>
<span *ngIf="['ToggleButton', 'DropList', 'TextField'].includes(subPart.type)">
<app-compound-child-overlay [style.display]="'inline-block'"
[element]="$any(subPart).attrs.model"
(elementSelected)="childElementSelected.emit($event)"
(elementValueChanged)="elementValueChanged.emit($event)">
':host ::ng-deep app-text-field {vertical-align: middle}',
':host ::ng-deep app-text-field .mat-form-field-wrapper {height: 100%; padding-bottom: 0; margin: 0}',
':host ::ng-deep app-text-field .mat-form-field {height: 100%}',
':host ::ng-deep app-text-field .mat-form-field-flex {height: 100%}',
':host ::ng-deep p strong {letter-spacing: 0.04em; font-weight: 600;}', // bold less bold
':host ::ng-deep p:empty::after {content: "\\00A0"}', // render empty p
'p span {font-size: inherit}',
'sup, sub {line-height: 0;}'
})
export class ClozeComponent extends CompoundElementComponent {
@Output() childElementSelected = new EventEmitter<CompoundChildOverlayComponent>();
@ViewChildren(CompoundChildOverlayComponent) compoundChildren!: QueryList<CompoundChildOverlayComponent>;
return this.elementModel.document.content
.filter((paragraph: ClozeDocumentParagraph) => paragraph.content) // filter empty paragraphs
.map((paragraph: ClozeDocumentParagraph) => paragraph.content // get custom paragraph parts
.filter((word: ClozeDocumentPart) => ['TextField', 'DropList', 'ToggleButton'].includes(word.type)))
.reduce((accumulator: any[], currentValue: any) => accumulator // put all collected paragraph parts into one list
.concat(currentValue.map((node: ClozeDocumentPart) => node.attrs?.model)), []); // model is in node.attrs.model
getFormElementChildrenComponents(): ElementComponent[] {
return this.compoundChildren.map((child: CompoundChildOverlayComponent) => child.childComponent);