Skip to content
Snippets Groups Projects
cloze.component.ts 10.7 KiB
Newer Older
  • Learn to ignore specific revisions
  • rhenck's avatar
    rhenck committed
      Component, EventEmitter, Input, Output, QueryList, ViewChildren
    
    } from '@angular/core';
    
    rhenck's avatar
    rhenck committed
    import { ClozeElement } from './cloze-element';
    
    import { CompoundElementComponent } from '../../directives/compound-element.directive';
    
    rhenck's avatar
    rhenck committed
    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';
    
    rhenck's avatar
    rhenck committed
    
    @Component({
      selector: 'app-cloze',
      template: `
    
    rhenck's avatar
    rhenck committed
        <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'">
    
    rhenck's avatar
    rhenck committed
          <ng-container *ngFor="let part of elementModel.document.content">
    
            <ul *ngIf="part.type === 'bulletList'"
                [style.font-size]="part.attrs.fontSize"
                [style.list-style]="part.attrs.listStyle">
    
    rhenck's avatar
    rhenck committed
              <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'"
                [style.font-size]="part.attrs.fontSize"
                [style.list-style]="part.attrs.listStyle">
    
    rhenck's avatar
    rhenck committed
              <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>
    
    rhenck's avatar
    rhenck committed
            <blockquote *ngIf="part.type === 'blockquote'">
              <ng-container *ngFor="let blockquotePart of $any(part).content"
                            [ngTemplateOutlet]="paragraphs"
                            [ngTemplateOutletContext]="{ $implicit: blockquotePart }"></ng-container>
            </blockquote>
    
            <ng-container *ngIf="part.type === 'paragraph' || part.type === 'heading'"
    
    rhenck's avatar
    rhenck committed
                          [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'"
    
    rhenck's avatar
    rhenck committed
                                          [parentForm]="parentForm"
    
                                          [element]="$any(subPart).attrs.model"
    
                                          [editorMode]="editorMode"
    
                                          (elementSelected)="childElementSelected.emit($event)"
    
    rhenck's avatar
    rhenck committed
                                          (elementValueChanged)="elementValueChanged.emit($event)">
    
              </app-compound-child-overlay>
            </span>
    
    rhenck's avatar
    rhenck committed
          </ng-container>
    
    rhenck's avatar
    rhenck committed
        </ng-template>
    
        ':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%}',
    
    rhenck's avatar
    rhenck committed
        'p {margin: 0}',
    
    rhenck's avatar
    rhenck committed
        ':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;}'
    
    rhenck's avatar
    rhenck committed
    })
    export class ClozeComponent extends CompoundElementComponent {
    
    rhenck's avatar
    rhenck committed
      @Input() elementModel!: ClozeElement;
    
      @Output() childElementSelected = new EventEmitter<CompoundChildOverlayComponent>();
      @ViewChildren(CompoundChildOverlayComponent) compoundChildren!: QueryList<CompoundChildOverlayComponent>;
    
    rhenck's avatar
    rhenck committed
    
    
      editorMode: boolean = false;
    
    
    rhenck's avatar
    rhenck committed
      getFormElementModelChildren(): InputElement[] {
    
    rhenck's avatar
    rhenck committed
        return this.elementModel.getChildElements();
    
    rhenck's avatar
    rhenck committed
      }
    
    
      getFormElementChildrenComponents(): ElementComponent[] {
        return this.compoundChildren.map((child: CompoundChildOverlayComponent) => child.childComponent);
    
    rhenck's avatar
    rhenck committed
      }
    }