diff --git a/nietzsche-beta-app/src/app/page-view/models.ts b/nietzsche-beta-app/src/app/page-view/models.ts index c40ed4d..6f66d01 100644 --- a/nietzsche-beta-app/src/app/page-view/models.ts +++ b/nietzsche-beta-app/src/app/page-view/models.ts @@ -1,282 +1,286 @@ /** * This interface specifies a function that returns a style class string (e.g. 'textfield unhighlighted') * that can be passed to [ngClass]. **/ export interface externalAssignClass { (currentWord: Word, hoveredWord: Word, hoveredLine: Line): string; } /** * This interface specifies a function that returns a style Object (e.g. { fill: red }) * that can be passed to [ngStyle]. **/ export interface externalAssignStyle { (currentItem: Line | Word, hoveredWord: Word, hoveredLine: Line, hoverStatus: string): Object; } /** * This interface specifies a configuration * */ export interface Configuration { [name: string]: any; } /** * a text continuation **/ export interface Continuation extends Interactable { reference: Reference; source: Reference; show?: string; } /** * Copyright information **/ export interface Copyright { text: string; licenseTextUrl?: string; license: string; originalUrl?: string; } /** * This interface specifies an object that can interact with {@link /injectables/PageViewService.html|PageViewService}. **/ export interface Interactable { /** * the string representation of the Interactable's interface type * ({@link /interfaces/Word.html|Word}|{@link /interfaces/Line.html|Line}|{@link /interfaces/TextByForeignHand.html|TextByForeignHand}). **/ datatype?: string; /** * the identity of the textfield to which this Interactable belongs. **/ textfield_identity?: string; /** * is Interactable top object **/ is_top_object?: boolean; } /** * This interface specifies the image that will be displayed by {@link /components/TextFieldComponent.html|TextFieldComponent}. **/ export interface Image { /** x coordinate of image **/ x: number; /** y coordinate of image **/ y: number; /** width of image **/ width: number; /** height of image **/ height: number; /** filename of image **/ filename: string; /** primary URL of image **/ URL: string; /** secondary URL of image **/ secondaryURL?: string; /** displayable area of image **/ text_field: TextField; /** matrix transformation string **/ transform?: string; /** * copyright information **/ copyright?: Copyright; } /** * This interface specifies a line that will be displayed by {@link /components/MarginFieldComponent.html|MarginFieldComponent}. **/ export interface LineStub extends Interactable { /** the line number **/ number: number; /** the (optional) IRI of this line **/ id: Identifier; } /** * This interface specifies a line that will be displayed by {@link /components/MarginFieldComponent.html|MarginFieldComponent}. **/ export interface Line extends LineStub { /** geometrical bottom position of this line **/ bottom: number; /** geometrical top position of this line **/ top: number; /** * reference to the line from which this line continues **/ continuesFrom?: Reference; /** * reference to the line on which this line continues **/ continuesTo?: Reference; source?: Reference; } /** * This interface specifies the area of an image that will be displayed by {@link /components/TextFieldComponent.html|TextFieldComponent}. **/ export interface TextField { /** the width of this textfield **/ width: number; /** the height of this textfield **/ height: number; /** the geometrical left position of this textfield **/ left: number; /** the geometrical top position of this textfield **/ top: number; } /** * This type specifies an identifier for words/lines (by its IRI string or its id number) **/ export type Identifier = string | number; /** * This interface specifies a page. **/ export interface Page { id: Identifier; number: string; } /** * Any svg path with an optional type. **/ export interface Path { id: Identifier; d: string; type?: string; } /** * geometrical Point **/ export interface Point { visible: boolean clientX: number; clientY: number; layerX: number; layerY: number; } /** * simple x,y-position **/ export interface Position { x: number; y: number; } /** * This interface specifies a postional object that can be displayed as a rect on the image by {@link /components/TextFieldComponent.html|TextFieldComponent}. **/ export interface PositionalObject extends Interactable { /** the identifier of a positional object (i.e. 'IRI' (string) or 'id' (number)) **/ id: Identifier; /** the geometrical left position of this word's rect. **/ left: number; /** the geometrical top position of this word's rect. **/ top: number; /** the width of this word's rect. **/ width: number; /** the height of this word's rect. **/ height: number; /** the matrix transformation string of the geometrical position of this word's rect. **/ transform?: string; } /** * This interface specifies a Line Reference that can be routed to. **/ export interface LineReference { /** * the title of the reference **/ manuscript?: Manuscript; /** * the page number of the reference **/ page?: string; /** * the line number of the reference **/ line_number?: number; /** * the line identifiaction of the reference **/ id: Identifier; } export interface Reference { /** * reference to the manuscript **/ manuscript?: Manuscript; /** * reference to the page **/ page?: Page; /** * reference to the line **/ line?: LineStub; /** * reference to the word **/ //word?: WordStub; } /** * This interface specifies a manuscript **/ export interface Manuscript { id: Identifier; title: string; type?: string; } /** * This interface specifies a text written by a foreign hand. **/ export interface TextByForeignHand extends PositionalObject { /** * pen used for writing text **/ pen: string; /** * text by foreign hand **/ text: string; + /** + * resolution of the abbrevation. + **/ + resolution?: string; } /** * This interface specifies a word that can be displayed as a rect on the image by {@link /components/TextFieldComponent.html|TextFieldComponent}. **/ export interface Word extends PositionalObject { /** the (raw) text of this word. **/ text: string; /** the text of this word as it has been edited by the editors. **/ edited_text?: string; /** the identification of the line to which this word belongs (iri or id). **/ line: string | number; /** the number of the line to which this word belongs. **/ line_number: number; /** is this word deleted. **/ deleted: boolean; /** a deletion path **/ deletion_path?: string; } export const USE_EXTERNAL_TOOLTIP: string = 'UseExternalTooltip'; diff --git a/nietzsche-beta-app/src/app/page-view/page-view.component.css b/nietzsche-beta-app/src/app/page-view/page-view.component.css index 07ffffc..2151653 100644 --- a/nietzsche-beta-app/src/app/page-view/page-view.component.css +++ b/nietzsche-beta-app/src/app/page-view/page-view.component.css @@ -1,33 +1,31 @@ #page { width: 100%; margin: 0; padding: 0; white-space: nowrap; - overflow: hidden; } .inline { display: inline-block; } .breakline { display: block; height: 50%; overflow: scroll; } .gap { display: inline-block; width: 1px; height: 100%; margin: 0; - overflow: hidden; } #margin { display: inline-block; height: 100%; margin: 0; } #textfield { display: inline-block; /*width: 95%;*/ height: 100%; margin: 0; } diff --git a/nietzsche-beta-app/src/app/page-view/page-view.component.html b/nietzsche-beta-app/src/app/page-view/page-view.component.html index d710ee2..0beeafb 100644 --- a/nietzsche-beta-app/src/app/page-view/page-view.component.html +++ b/nietzsche-beta-app/src/app/page-view/page-view.component.html @@ -1,50 +1,50 @@
-
+
diff --git a/nietzsche-beta-app/src/app/page-view/page-view.component.ts b/nietzsche-beta-app/src/app/page-view/page-view.component.ts index 049473d..9639e50 100644 --- a/nietzsche-beta-app/src/app/page-view/page-view.component.ts +++ b/nietzsche-beta-app/src/app/page-view/page-view.component.ts @@ -1,173 +1,173 @@ import { Component, Input, OnInit, OnChanges} from '@angular/core'; import { externalAssignClass, externalAssignStyle, Configuration, Identifier, Image, Line, TextField, TextByForeignHand, Word} from './models'; /** - * This component displays one or two {@link /components/TextFieldComponent.html|TextFieldComponent(s)} + * This component displays one or two {@link /components/TextFieldComponent.html|TextFieldComponent(s)} * and its or their {@link /components/MarginFieldComponent.html|MarginFieldComponent(s)}. **/ @Component({ selector: 'page-view', templateUrl: './page-view.component.html', styleUrls: ['./page-view.component.css'] }) export class PageViewComponent implements OnInit, OnChanges { @Input() configuration: Configuration; /** * the search text of words that should be highlighted as {@link /miscellaneous/enumerations.html#HIGHTLIGHT_CASES|HIGHTLIGHT_CASES.SEARCHED_WORD}. **/ @Input() findText: string; /** - * first texts written by foreign hand + * first texts written by foreign hand **/ @Input() first_foreign_texts: TextByForeignHand[] = []; /** * the first image that will be displayed by {@link /components/TextFieldComponent.html|TextFieldComponent}. **/ @Input() first_image: Image; /** * the Array of lines of the first image that will be displayed by {@link /components/MarginFieldComponent.html|MarginFieldComponent}. **/ @Input() first_lines: Line[]; /** * Identification of first textfield. **/ first_textfield_id: string = 'first textfield' /** * the Array of words of the first image that will be displayed by {@link /components/TextFieldComponent.html|TextFieldComponent}. **/ @Input() first_words: Word[]; /** * the (initial) maximum height of the image(s). **/ @Input() max_height: number = -1; /** * the (initial) maximum width of the image(s). **/ @Input() max_width: number = -1; /** * should primary Url be used for image. Use secondary Url if false. **/ @Input() preferPrimaryUrl: boolean = true; /** - * second texts written by foreign hand + * second texts written by foreign hand **/ @Input() second_foreign_texts: TextByForeignHand[] = []; /** * the second image that will be displayed by {@link /components/TextFieldComponent.html|TextFieldComponent}. **/ @Input() second_image: Image; /** * the Array of lines of the second image that will be displayed by {@link /components/MarginFieldComponent.html|MarginFieldComponent}. **/ @Input() second_lines: Line[]; /** * Identification of second textfield. **/ second_textfield_id: string = 'second textfield' /** * the Array of words of the second image that will be displayed by {@link /components/TextFieldComponent.html|TextFieldComponent}. **/ @Input() second_words: Word[]; /** - * An optional function that will be passed to {@link /components/TextFieldComponent.html|TextFieldComponent} + * An optional function that will be passed to {@link /components/TextFieldComponent.html|TextFieldComponent} * in order to return a further highlight class - * to the word rects when the internal function would return 'textfield unhighlighted'. + * to the word rects when the internal function would return 'textfield unhighlighted'. **/ @Input('assignClass') assignClass?: externalAssignClass; /** * An optional function that will be passed to {@link /components/TextFieldComponent.html|TextFieldComponent} * and {@link /components/MarginFieldComponent.html|MarginFieldComponent} - * in order to return a (svg-)style object + * in order to return a (svg-)style object * to the word and line rects. This function allows the user to extend the style of this component. * E.g. by returning { fill: blue } the function overwrites the default behaviour and sets * the default highlight color to blue. **/ @Input('assignStyle') assignStyle?: externalAssignStyle; /** * global zoom factor. **/ @Input() zoomFactor: number = 1; /** * identifiers of selected words that should be highlighted. **/ @Input() selectedWords: Identifier[] = []; /** * identifiers of selected lines that should be highlighted. **/ @Input() selectedLines: Identifier[] = []; @Input('startLine') startLineId: Identifier; @Input('endLine') endLineId: Identifier; @Input() dontShowReference: boolean; showReferenceLeft: string = 'from'; showReferenceRight: string = 'to'; constructor() {} - + /** * sets {@link /components/PageViewComponent.html#max_height|max_height} if it is unset. **/ ngOnInit() { if (this.max_height == -1 && this.max_width == -1){ this.max_height = screen.availHeight; } this.checkImages(); } ngOnChanges(){ if (this.dontShowReference != undefined && this.dontShowReference != null && this.dontShowReference){ - this.showReferenceLeft = ''; + this.showReferenceLeft = ''; this.showReferenceRight = ''; } else { - this.showReferenceLeft = 'from'; + this.showReferenceLeft = 'from'; this.showReferenceRight = 'to'; } this.checkImages(); if (this.first_image != null && this.first_image != undefined && this.first_image.transform != null){ this.updateLines(this.first_words, this.first_lines) } if (this.second_image != null && this.second_image != undefined && this.second_image.transform != null){ this.updateLines(this.second_words, this.second_lines) } } private checkImages(){ if (this.first_image != null && this.first_image != undefined && this.startLineId != null && this.startLineId != undefined){ if(this.first_lines != null && this.first_lines != undefined && this.first_lines.length > 0){ this.first_image = this.updateTextField(this.first_image, this.first_lines); } if(this.second_lines != null && this.second_lines != undefined && this.second_lines.length > 0){ this.second_image = this.updateTextField(this.second_image, this.second_lines); } } } private updateLines(words: Word[], lines: Line[]) { for (var i = 0; i < lines.length; i++){ if (words.filter(word =>word.line == lines[i].id).length > 0){ lines[i].top = words.filter(word =>word.line == lines[i].id).map(word =>Number(word.top)).sort(function(a,b){ return a-b; })[0] lines[i].bottom = words.filter(word =>word.line == lines[i].id).map(word =>Number(word.top)+Number(word.height)).sort(function(a,b){ return b-a; })[0] } } } private updateTextField(image: Image, lines: Line[]): Image { let endLineId = (this.endLineId != null && this.endLineId != undefined) ? this.endLineId : this.startLineId; let startLines = lines.filter(line =>line.id == this.startLineId) let endLines = lines.filter(line =>line.id == endLineId) if (startLines.length > 0 && endLines.length > 0){ let top = (startLines[0].top > 10) ? startLines[0].top-10 : startLines[0].top; let height = (endLines[0].bottom-top)+10; let text_field: TextField = { top: top, left: image.text_field.left, width: image.text_field.width, height: height } return { x: image.x, y: image.y, width: image.width, height: image.height, filename: image.filename, - URL: image.URL, secondaryURL: image.secondaryURL, text_field: text_field, transform: image.transform, + URL: image.URL, secondaryURL: image.secondaryURL, text_field: text_field, transform: image.transform, copyright: image.copyright } } return image; } /** * Returns whether the two images can be displayed as columns. **/ private hasColumnStyle(): boolean { if (this.zoomFactor <= 1 || this.first_image == null || this.second_image == null){ - return true; + return true } let newLeftWidth = this.max_height/this.first_image.text_field.height*this.zoomFactor*this.first_image.text_field.width; let newRightWidth = this.max_height/this.second_image.text_field.height*this.zoomFactor*this.second_image.text_field.width; return newLeftWidth + newRightWidth < screen.availWidth; } } diff --git a/nietzsche-beta-app/src/app/tln-edition/datatypes/foreign_text.ts b/nietzsche-beta-app/src/app/tln-edition/datatypes/foreign_text.ts index bf3fb1f..32eda12 100644 --- a/nietzsche-beta-app/src/app/tln-edition/datatypes/foreign_text.ts +++ b/nietzsche-beta-app/src/app/tln-edition/datatypes/foreign_text.ts @@ -1,63 +1,103 @@ +import { FusekiResults, BasicResultBindingElement } from './basic_datatype'; import { TlnPositionalObject } from './positional_object'; import { TextByForeignHand } from '../models'; +import { TlnPositionalStyleMarkup } from './positional-markup'; /** * This is the 'text by foreign hand' instantiation of an element of {@link /interfaces/FusekiResults.html|FusekiResults}. * It extends {@link /classes/BasicResultBindingElement.html|BasicResultBindingElement}. **/ export class TlnTextByForeignHand extends TlnPositionalObject implements TextByForeignHand { /** * the SPARQL-query of this datatype. **/ static readonly query: string = ` PREFIX tln: PREFIX rdf: - SELECT ?id ?text ?pen ?left ?top ?width ?height ?transform WHERE { + SELECT ?id ?text ?pen ?left ?top ?width ?height ?resolution ?transform ?markup ?cssStyleTag ?startIndex ?endIndex WHERE { ?page tln:hasMarkForeignHands/rdf:rest*/rdf:first ?id. - ?id tln:textOfForeignHands/tln:textHasContent ?text; + ?id tln:textOfForeignHands ?textOfForeignHands; tln:penOfForeignHands ?pen; tln:hasTranskriptionPosition ?tp. + ?textOfForeignHands tln:textHasContent ?text. ?tp tln:hasLeft ?left; tln:hasTop ?top; tln:hasWidth ?width; tln:hasHeight ?height. + OPTIONAl { ?id tln:resolutionOfAbbreviation ?resolution.} + OPTIONAl { ?textOfForeignHands tln:textHasMarkup ?markup. + ?markup tln:standoffTagHasEndIndex ?endIndex; + tln:standoffTagHasStartIndex ?startIndex; + tln:standoffTagHasCSS ?cssStyleTag. + } OPTIONAl { ?tp tln:hasTransform ?transform.} } `; /** * the text of this word **/ text: string; /** * the text of this word as it has been edited by the editors. **/ pen: string; - + /** + * resolution of the abbrevation + **/ + resolution?: string; + markups: TlnPositionalStyleMarkup[] = []; /** * The constructor creates a datatype from the data. * * @param id if omitted the id will be retrieved from data **/ constructor(data: any, id?: string, service?: any){ super(data, id, service) this.text = this.getData4Key('text'); this.pen = this.getData4Key('pen'); + this.resolution = this.getData4Key('resolution'); + } + public static convertData(this: T, data: FusekiResults, id?: string, service?: any): Array> { + let elements = []; + let content = this.getContent(data); + for (var i = 0; i < content.length; i++){ + let element = new TlnTextByForeignHand(content[i], id, service); + if (content[i]['markup'] != undefined && content[i]['markup']['value'] != null){ + element.markups = TlnPositionalStyleMarkup.convertData({ head: { vars: []}, results: { bindings: [ content[i] ] } }, content[i]['markup']['value']) + } + if (elements.length > 0 && elements[elements.length-1].id == element.id){ + element.markups.forEach(markup =>{elements[elements.length-1].markups.push(markup)}); + } else { + elements.push(element) + } + } + //console.log(elements) + return elements; } + } /** * This is the faksimile text by foreign hand instantiation of an element of {@link /interfaces/FusekiResults.html|FusekiResults}. * It extends {@link /classes/BasicResultBindingElement.html|BasicResultBindingElement}. **/ export class FaksimileTextByForeignHand extends TlnTextByForeignHand { /** * the SPARQL-query of this datatype. **/ static readonly query: string = ` PREFIX tln: PREFIX rdf: - SELECT ?id ?text ?pen ?left ?top ?width ?height ?transform WHERE { + SELECT ?id ?text ?pen ?left ?top ?width ?height ?resolution ?transform ?markup ?cssStyleTag ?startIndex ?endIndex WHERE { ?page tln:hasMarkForeignHands/rdf:rest*/rdf:first ?id. - ?id tln:textOfForeignHands/tln:textHasContent ?text; + ?id tln:textOfForeignHands ?textOfForeignHands; tln:penOfForeignHands ?pen; tln:hasFaksimilePosition ?fp. + ?textOfForeignHands tln:textHasContent ?text. ?fp tln:hasLeft ?left; tln:hasTop ?top; tln:hasWidth ?width; tln:hasHeight ?height. + OPTIONAl { ?id tln:resolutionOfAbbreviation ?resolution.} + OPTIONAl { ?textOfForeignHands tln:textHasMarkup ?markup. + ?markup tln:standoffTagHasEndIndex ?endIndex; + tln:standoffTagHasStartIndex ?startIndex; + tln:standoffTagHasCSS ?cssStyleTag. + } OPTIONAl { ?fp tln:hasTransform ?transform.} } `; + } diff --git a/nietzsche-beta-app/src/app/tln-edition/route-updater.ts b/nietzsche-beta-app/src/app/tln-edition/route-updater.ts index 859514c..569326c 100644 --- a/nietzsche-beta-app/src/app/tln-edition/route-updater.ts +++ b/nietzsche-beta-app/src/app/tln-edition/route-updater.ts @@ -1,54 +1,56 @@ import { Router, ActivatedRoute, Params } from '@angular/router'; import { Mapping, RouteReader } from './route-reader'; export class RouteUpdater extends RouteReader { protected mapping: Mapping; protected routerParams: Params; protected currentRoute: string; parentActivatedRoute: ActivatedRoute; constructor(protected router: Router, protected activatedRoute: ActivatedRoute ) { super(router, activatedRoute); if(this.currentRoute == undefined || this.currentRoute == null){ this.currentRoute = (this.activatedRoute.snapshot.routeConfig != null) ? this.activatedRoute.snapshot.routeConfig.path : null; } } protected updateParams(launch?: boolean) { let newRouterParam = {}; for(let key of Object.keys(this.mapping)){ let paramsKey = this.mapping[key]['param']; if(this[key] != null){ if (Array.isArray(this[key]) && this[key].length > 0){ newRouterParam[paramsKey] = JSON.stringify(this[key]); } else { newRouterParam[paramsKey] = this[key]; } } } - for(let key of Object.keys(this.routerParams)){ + /*for(let key of Object.keys(this.routerParams)){ if(newRouterParam[key] == null){ newRouterParam[key] = this.routerParams[key]; } - } + }*/ let parentActivatedRoute = (this.activatedRoute.parent != null) ? this.activatedRoute.parent : this.parentActivatedRoute; if(parentActivatedRoute != undefined && parentActivatedRoute != null){ parentActivatedRoute.url.subscribe(url=>{ let parentPath = url[0].path; if (launch != undefined && launch){ let link = this.router.createUrlTree([ parentPath + '/' + this.currentRoute], { queryParams: newRouterParam }); window.open(link.toString(), '_blank') } else { - this.router.navigate([ parentPath + '/' + this.currentRoute], { queryParams: newRouterParam }); + //this.router.navigate([ parentPath + '/' + this.currentRoute], { queryParams: newRouterParam }); + this.router.navigate([parentPath + '/' + this.currentRoute], { queryParams: newRouterParam, queryParamsHandling: 'merge' }); } }); } else { if (launch != undefined && launch){ let link = this.router.createUrlTree([ this.currentRoute], { queryParams: newRouterParam }); window.open(link.toString(), '_blank') } else { - this.router.navigate([ this.currentRoute], { queryParams: newRouterParam }); + //this.router.navigate([ this.currentRoute], { queryParams: newRouterParam }); + this.router.navigate([this.currentRoute], { queryParams: newRouterParam, queryParamsHandling: 'merge' }); } } } } diff --git a/nietzsche-beta-app/src/app/tln-edition/tln-page-view.component.html b/nietzsche-beta-app/src/app/tln-edition/tln-page-view.component.html index 43c7924..8fd3cb8 100644 --- a/nietzsche-beta-app/src/app/tln-edition/tln-page-view.component.html +++ b/nietzsche-beta-app/src/app/tln-edition/tln-page-view.component.html @@ -1,12 +1,12 @@ -
- +
diff --git a/nietzsche-beta-app/src/app/tln-edition/tln-query.service.ts b/nietzsche-beta-app/src/app/tln-edition/tln-query.service.ts index 0a99bc2..7b6906f 100644 --- a/nietzsche-beta-app/src/app/tln-edition/tln-query.service.ts +++ b/nietzsche-beta-app/src/app/tln-edition/tln-query.service.ts @@ -1,38 +1,38 @@ import { Injectable, EventEmitter } from '@angular/core'; import {HttpClient, HttpHeaders} from '@angular/common/http'; import { Observable } from 'rxjs'; import { TlnQueryServiceInterface } from './models'; /** * This is the internal query service * that communicates with the SPARQL-endpoint. * */ @Injectable() export class TlnQueryService implements TlnQueryServiceInterface { - //baseUrl = 'http://localhost:3030/nietzsche/query'; - baseUrl = 'https://nietzsche.fuseki.services.dasch.swiss/nietzsche' + // baseUrl = 'http://localhost:3030/nietzsche/query'; + baseUrl = 'https://nietzsche.fuseki.services.dasch.swiss/nietzsche' reset_data = new EventEmitter(); constructor(private http: HttpClient) { } public resetData(key: string){ this.reset_data.emit(key); } /** * Gets the data from an endpoint via http post * * @param query: The query to run. * @returns response */ public getData(query: string): Observable { let httpOptions = { headers: new HttpHeaders( { 'Content-Type': 'application/sparql-query', 'Accept': 'application/sparql-results+json; charset=UTF-8'} ) }; return this.http.post(this.baseUrl, query, httpOptions); } } diff --git a/nietzsche-beta-app/src/app/tln-edition/tln-viewer-navigation/tln-viewer-navigation.component.ts b/nietzsche-beta-app/src/app/tln-edition/tln-viewer-navigation/tln-viewer-navigation.component.ts index 676b6c1..356b103 100644 --- a/nietzsche-beta-app/src/app/tln-edition/tln-viewer-navigation/tln-viewer-navigation.component.ts +++ b/nietzsche-beta-app/src/app/tln-edition/tln-viewer-navigation/tln-viewer-navigation.component.ts @@ -1,140 +1,145 @@ -import { Component, OnInit, Input, ElementRef } from '@angular/core'; +import { Component, OnInit, OnDestroy, HostListener, Input, ElementRef } from '@angular/core'; import { Router, ActivatedRoute, Params } from '@angular/router'; import {MatBottomSheet, MatBottomSheetRef} from '@angular/material/bottom-sheet'; import { TlnQueryServiceInterface, Reference, ManuscriptUnity, NavigationPage } from '../models'; import { TlnManuscriptUnity, TlnNavigationPage} from '../datatypes/navigation'; import { DEFAULT_VIEW_OPTION, TLN_VIEWER_ROUTE, TLN_FULLSCREEN_PARAM, TLN_FIND_PARAM, TLN_NAV_BAR_OPEN_STATE_PARAM, TLN_PAGE_PARAM, TLN_MANUSCRIPT_PARAM, TLN_SELECTED_LINES_PARAM, TLN_VIEW_OPTION_PARAM, TLN_ZOOM_PARAM, VIEW_OPTIONS, ONTOLOTY_PREFIX } from '../constants'; import { IsReconstructedKonvolut } from '../datatypes/basic_datatype'; import { TlnLine} from '../datatypes/line'; import { TlnTextGeneticOrder} from '../datatypes/text_version'; import { Mapping } from '../route-reader'; import { RouteUpdater } from '../route-updater'; import { ComplexKeyIriMapping, DataHandler, KeyIriMapping } from '../data_handler'; import { PageViewService, TlnQueryService } from '../services'; import { TlnInformationComponent, ParentInformation } from '../tln-information/tln-information.component'; import { PageInformation } from '../tln-information/page-information'; @Component({ selector: 'tln-viewer-navigation', templateUrl: './tln-viewer-navigation.component.html', styleUrls: ['./tln-viewer-navigation.component.css'] }) -export class TlnViewerNavigation extends RouteUpdater { +export class TlnViewerNavigation extends RouteUpdater implements OnDestroy { /** * OPTIONAL pass a queryService with method * {@link /interfaces/TlnQueryServiceInterface.html#getData|getData} * to TlnPageViewComponent. **/ @Input() queryService: TlnQueryServiceInterface; /** * whether or not to show page view in fullscreen mode. **/ fullscreen: boolean = false; findText: string; current_iri: string; current_manuscript_iri: string; manuscript_unity: ManuscriptUnity; current_page: NavigationPage; pageInformation: PageInformation; previous_page: NavigationPage; next_page: NavigationPage; navBarOpenState: boolean; showArchivalManuscriptUnity: boolean = false; dataHandler: DataHandler = new DataHandler(this); geneticOrders: TlnTextGeneticOrder[] = []; selectedLines: string[] = []; private readonly increment: number = 0.333; private readonly decrement: number = this.increment*-1; protected currentRoute: string = TLN_VIEWER_ROUTE; protected mapping: Mapping = { findText: { param: TLN_FIND_PARAM, type: "string" }, current_iri: { param: TLN_PAGE_PARAM, type: "string" }, navBarOpenState: { param: TLN_NAV_BAR_OPEN_STATE_PARAM, type: "boolean" }, current_manuscript_iri: { param: TLN_MANUSCRIPT_PARAM, type: "string" }, fullscreen: { param: TLN_FULLSCREEN_PARAM, type: "boolean" }, selectedViewOption: { param: TLN_VIEW_OPTION_PARAM, type: "string" }, selectedLines: { param: TLN_SELECTED_LINES_PARAM, type: "string" } } routerParams: Params; selectedViewOption: string = DEFAULT_VIEW_OPTION updating: boolean = false; viewOptions: string[] = [ VIEW_OPTIONS.TRANSKRIPTION, VIEW_OPTIONS.FAKSIMILE, VIEW_OPTIONS.SYNOPSIS, VIEW_OPTIONS.SYNOPSIS_B ]; + subscriptions: any[] = []; constructor(el: ElementRef, private bottomSheet: MatBottomSheet, private pageViewService: PageViewService, private localQueryService: TlnQueryService, protected router: Router, protected activatedRoute: ActivatedRoute ) { super(router, activatedRoute); } ngOnInit() { let tlnQueryService = (this.queryService != null) ? this.queryService : this.localQueryService; this.dataHandler.addHandler('manuscript_unity', { 'handler': TlnManuscriptUnity, 'next_key': 'navigation_page'}); this.dataHandler.addHandler('navigation_page', ['current_page', 'geneticOrders'] ); this.dataHandler.addHandler('current_page', { 'handler': TlnNavigationPage }); this.dataHandler.addHandler('geneticOrders', { 'handler': TlnTextGeneticOrder}); this.dataHandler.setQueryService(tlnQueryService); - this.dataHandler.start_processing.subscribe( + this.subscriptions.push(this.dataHandler.start_processing.subscribe( (started: boolean) =>{ this.updating = true; - }); - this.dataHandler.processing_finished.subscribe( + })); + this.subscriptions.push(this.dataHandler.processing_finished.subscribe( (finished: boolean) =>{ this.updating = false; - }); + })); super.ngOnInit(); - this.pageViewService.reference.subscribe( + this.subscriptions.push(this.pageViewService.reference.subscribe( (newReference: Reference) => { + console.log(newReference); this.updatePageToReference(newReference) - }) - this.pageViewService.onClickedLine.subscribe( + })); + this.subscriptions.push(this.pageViewService.onClickedLine.subscribe( (clickedLine: TlnLine) => { let index = this.selectedLines.indexOf(clickedLine.id) if (index > -1){ this.selectedLines.splice(index, 1); } else { this.selectedLines.push(clickedLine.id); } this.updateParams(); - }); + })); + } + ngOnDestroy() { + this.subscriptions.forEach(subscription => subscription.unsubscribe()); } private clearFindText() { this.findText = ''; this.updateParams(); } private getPageTitle(page?: NavigationPage, numPages?: number): string { if (page == null){ return ''; } let indexPrefix = (numPages != null) ? page.index + '/' + numPages : page.index; return indexPrefix + ': ' + page.title + ' ' + page.number; } protected readParams(params: Params){ super.readParams(params); if (this.dataHandler.ready && (this.current_page == null || this.current_page.id != this.current_iri)){ this.dataHandler.resetData('navigation_page') if(this.current_manuscript_iri != null){ //this.dataHandler.debug = true; /*this.dataHandler.conditionalAddHandler(IsReconstructedKonvolut.getQuery(this.current_manuscript_iri), 'current_page',{ handler: TlnNavigationPage}, { handler: TlnNavigationPage});*/ this.dataHandler.getData('manuscript_unity', this.current_manuscript_iri, this.current_iri); } else { this.dataHandler.getData('current_page', this.current_iri); } } } private setCurrentIri(pageIri: string, manuscriptIir?: string){ this.dataHandler.stop_processing.emit(true); this.current_iri = pageIri; this.updateParams(); } private showInformation() { let parentData: ParentInformation = { geneticOrders: this.geneticOrders, page: this.current_page, manuscript_iri: this.current_manuscript_iri, parentActivatedRoute: this.activatedRoute.parent } this.bottomSheet.open(TlnInformationComponent, { data: parentData }); } private updatePageToReference(reference: Reference){ this.current_iri = reference.page.id; this.selectedLines = [ reference.line.id ] this.updateParams(); } } diff --git a/nietzsche-beta-app/src/app/tln-edition/tooltip/tool-tip.component.html b/nietzsche-beta-app/src/app/tln-edition/tooltip/tool-tip.component.html index a085579..c51659e 100644 --- a/nietzsche-beta-app/src/app/tln-edition/tooltip/tool-tip.component.html +++ b/nietzsche-beta-app/src/app/tln-edition/tooltip/tool-tip.component.html @@ -1,50 +1,54 @@
{{tooltipPosition.clientY+yOffset}}, {{topOffset}}
0: {{earlier_version.text}}
1:  {{word.text}}
>{{word.edited_text}}
überschreibt: {{overwrittenWord.text}}
- {{foreignHand.text}}, {{foreignHand.pen}} + {{foreignHand.text}} + + (={{foreignHand.resolution}}), {{foreignHand.pen}}
{{continuation.source.line.number}} nach  {{continuation.reference.manuscript.title}} {{continuation.reference.page.number}}, {{continuation.reference.line.number}}  nach {{continuation.source.line.number}}
{{ (word.earlier_version) ? '[0:' + word.earlier_version + '|1:' : ''}} {{ (word.earlier_version) ? ']' : ''}}