- Standard
+ Digitale Manuskriptedition: Der späte Nietzsche - Version {{version}}Green
-
Der späte Nietzsche, Manuskripte 1885-1889 (beta version)
+
Der späte Nietzsche, Manuskripte 1885-1889
diff --git a/nietzsche-beta-app/src/app/app.component.ts b/nietzsche-beta-app/src/app/app.component.ts
index e29ef17..52ca66f 100644
--- a/nietzsche-beta-app/src/app/app.component.ts
+++ b/nietzsche-beta-app/src/app/app.component.ts
@@ -1,32 +1,35 @@
import {Component, OnInit} from '@angular/core';
import { OverlayContainer} from '@angular/cdk/overlay';
import {Subscription} from 'rxjs';
import {ActivatedRoute, Params} from '@angular/router';
+declare var require: any;
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
- title = 'nietzsche app';
+ title = 'Digitale Manuskriptedition: Der späte Nietzsche';
theme = 'standard-theme';
+ version: string;
fullScreen: string;
queryParamSub: Subscription;
constructor(private overlayContainer: OverlayContainer, private activatedRoute: ActivatedRoute) {
+ this.version = require( '../../package.json').version;
}
ngOnInit() {
this.overlayContainer.getContainerElement().classList.add(this.theme);
this.queryParamSub = this.activatedRoute.queryParams.subscribe( (queryParams: Params ) => {
this.fullScreen = queryParams.fullscreen;
});
}
onThemeChange() {
this.overlayContainer.getContainerElement().classList.add(this.theme);
}
}
diff --git a/nietzsche-beta-app/src/app/navigation-list-component/navigation-list-component.component.ts b/nietzsche-beta-app/src/app/navigation-list-component/navigation-list-component.component.ts
index a94b739..6e4398f 100644
--- a/nietzsche-beta-app/src/app/navigation-list-component/navigation-list-component.component.ts
+++ b/nietzsche-beta-app/src/app/navigation-list-component/navigation-list-component.component.ts
@@ -1,272 +1,272 @@
import {AfterViewInit, Component, ElementRef, EventEmitter, OnInit, ViewChildren} from '@angular/core';
import {NavigationServiceService} from '../services/navigation-service.service';
import {NavigationEntity, NavTreeDef, TlnQueryParams} from '../models/models';
import {Subscription} from 'rxjs/index';
import {ActivatedRoute, Params, Router} from '@angular/router';
import {QueryService} from '../services/query.service';
import {NavTree} from './navtree-directive.directive';
import * as _ from 'lodash';
@Component({
selector: 'app-navigation-list-component',
templateUrl: './navigation-list-component.component.html',
styleUrls: ['./navigation-list-component.component.scss']
})
/**
* NavigationListComponent
* Does sinply consume data coming from naviservice && activated route. triggers click event to service.
*/
export class NavigationListComponentComponent implements OnInit, AfterViewInit {
navigationTreeDefs: NavTreeDef[];
navTrees: NavTree[]; // The actual Navtrees which are displayed
oldQueryParams: Params;
queryParams: Params;
queryParamSubscription: Subscription;
navTabIndex: number;
constructor( public naviService: NavigationServiceService,
private router: Router,
private activatedRoute: ActivatedRoute,
private queryService: QueryService) {
this.navigationTreeDefs = [
{ id: 'manuscript',
idx: 0,
isActive: true,
label: 'Manuskripte',
itemQParam: 'manuscript',
entries: [],
apiDef: {
type: 0, // rdf
baseUrl: 'https://nietzsche.fuseki.services.dasch.swiss/nietzsche',//'http://fuseki.nie-ine.ch/nietzsche-rw/query',
dataArray: 'results.bindings',
query: 'manuscripts.rq',
mapping: { // maps the properties of the reponse to tha NavTabDef properties, which are displayed
id: 'manuscript.value', // Short id, iri in most cases
iri: 'manuscript.value', // iri
type: 'type.value',
label: 'title.value',
description: 'gsaSignature.value',
avatar: 'thumbImage.value'
}
}
}, {
id: 'page',
idx: 1,
isActive: false,
label: 'Seiten',
itemQParam: 'page',
entries: [],
apiDef: {
type: 0, // rdf
baseUrl: 'https://nietzsche.fuseki.services.dasch.swiss/nietzsche',//'http://fuseki.nie-ine.ch/nietzsche-rw/query',
dataArray: 'results.bindings',
query: 'getPageData.rq',
mapping: {
id: 'page.value', // Short id, iri in most cases
iri: 'page.value', // iri
label: 'pageNumber.value',
thumb: 'thumb.value',
idx: 'pageNumber.value',
svg: 'svgFileName.value',
}
}
}
];
// If url pasted or page refreshed --> resetting this.queryparams to the query params of the url;
// needed for the template hence service instances can not be accessed in the template
this.queryParamSubscription = this.activatedRoute.queryParams.subscribe( (queryParams: Params ) => {
const navTabIndex = this.getActiveNavTabIndex(queryParams.navContext);
if (this.oldQueryParams && queryParams.navContext) { // only if there are any oldParams
this.reactOnContextChange(queryParams.navContext, this.oldQueryParams.navContext, navTabIndex );
this.reactOnItemChange('page', queryParams.page, this.oldQueryParams.page);
this.reactOnItemChange('manuscript', queryParams.manuscript, this.oldQueryParams.manuscript);
}
this.oldQueryParams = queryParams;
});
}
async ngOnInit() {
await this.createTreesOnInit();
this.navTabIndex = await this.getActiveNavTabIndex();
await this.populateNavTrees();
// set selected things in url
this.navTrees.forEach(tree => {
// if there is no selected item for each tree, we have to listen to the selectedItemSet/tree population and set them per default
if (!this.activatedRoute.snapshot.queryParamMap.get(tree.qParam)) {
tree.selectedItemSet.subscribe(item => {
this.setSelectedItemAndRoute(item.itemId, item.tabId);
});
}
});
// change navTree according to chosen route per default
// set NavContext if unset according to selected component: manuscriptView, tln-page view
if (this.activatedRoute.snapshot.firstChild.url[0].path === 'tln-viewer'
&& !this.activatedRoute.snapshot.queryParamMap.get('navContext')) {
this.naviService.updateRoute({navContext: 'page'});
}
}
- ngAfterViewInit() { // TODO: Remove and scroll only after set intenally
+ ngAfterViewInit() {
const selectedItem = this.activatedRoute.snapshot.queryParamMap.get(this.activatedRoute.snapshot.queryParamMap.get('navContext'));
this.scrollOnToSelectedItem(selectedItem);
}
reactOnItemChange(param: string, itemId: string, oldItemId) {
if (itemId && itemId !== '' && oldItemId) {
if (itemId !== oldItemId) {
const tab = this.navTrees.findIndex(tree => tree.id === param);
this.setSelectedItem(itemId, tab);
if (tab === this.navTabIndex) {
window.setTimeout(() => this.scrollOnToSelectedItem(itemId), 100);
}
}
}
}
reactOnContextChange(context: string, oldContext: string, activeTab: number) {
if (context !== oldContext) {
this.navTabIndex = activeTab;
// must time out here hence document is not ready to scroll
window.setTimeout(() => this.scrollOnToSelectedItem(this.oldQueryParams[context]), 100);
}
}
scrollOnToSelectedItem(itemId: string ) {
if (document.getElementById(itemId)) {
const offSetTop = document.getElementById(itemId).offsetTop;
document.getElementById('navlist').scrollTop = offSetTop - 100;
}
}
/**
* getActiveNavTabIndexOnInit
* gets the active navTabIndex either from a passed navConText, from active qParam or or from definition
*/
getActiveNavTabIndex(con?: string) {
let navConText;
if (!con || con === '') {
navConText = this.activatedRoute.snapshot.queryParamMap.get('navContext');
} else { navConText = con; }
let navTabIndex = 0;
if (navConText && navConText !== '') {
const nIndex = this.navigationTreeDefs.findIndex(tree => tree.id === navConText);
navTabIndex = this.navigationTreeDefs[nIndex].idx;
} else { navTabIndex = 0; }
return navTabIndex;
}
createTreesOnInit() {
this.navTrees = [];
this.navigationTreeDefs.forEach( def =>
this.navTrees.push(new NavTree(def.id, def.idx, def.label, [], def.itemQParam, def.description, def.apiDef)));
}
async onSelectNavItem(item: NavigationEntity) {
// If a new item is clicked
if (this.navTrees[this.navTabIndex].selectedItem !== item.tlnEntity.id) {
// get new data for subTrees and set new params accordingly
await this.emptyChildTrees(this.navTabIndex);
await this.removeAllChildTreeQParams(this.navTabIndex);
await this.setSelectedItemAndRoute(item.tlnEntity.id, this.navTabIndex);
await this.populateChildren(this.navTabIndex, item.tlnEntity.id);
// Only if context !== 'page', e.g. view is tln-viewer), we change to the second page tab
const navContext = this.activatedRoute.snapshot.queryParamMap.get('navContext');
if (navContext !== this.navTrees[this.getActiveNavTabIndex()].qParam) {
this.changeNavTreeViaRoute(this.navTabIndex + 1);
}
} else { // if an already selected item is clicked again, it changes the tree/tab
this.changeNavTreeViaRoute(this.navTabIndex + 1); }
}
removeAllChildTreeQParams(tabId) {
this.navTrees.forEach((tree, index) => {
if (tree.idx > tabId) {
this.navTrees[index].selectedItem = null;
this.naviService.updateRoute({[tree.qParam]: null});
}
});
}
emptyChildTrees(parentIdx) {
this.navTrees.forEach((tree, index) => {
if (tree.idx > parentIdx) {
this.navTrees[index].entries = [];
}
});
}
setSelectedItem(navItemId: string, tabId: number) {
this.navTrees[tabId].selectedItem = navItemId;
}
// Will route, the qParamSubscription reacts and trees are built further
async setSelectedItemAndRoute(navItemId: string, tabId: number) {
this.navTrees[tabId].selectedItem = navItemId;
const idx = this.navigationTreeDefs.findIndex(tree => tree.idx === tabId);
// set new qParam
const newParams = {};
const qParam = this.navigationTreeDefs[idx].itemQParam;
newParams[qParam] = navItemId;
this.naviService.updateRoute(newParams);
}
populateChildren(activeTab, itemId?: string) {
if (activeTab + 1 < this.navigationTreeDefs.length) {
// if an item in a tab with sub tabs is selected, the subtree should be loaded according to that selection and the tab should change
this.populateNavTrees(activeTab + 1, itemId );
}
}
// switches tabs in navtab ov navigation bar
changeNavTreeViaRoute(idx: number) {
if (idx < this.navTrees.length) {
this.naviService.updateRoute({navContext: this.navTrees[idx].qParam}); }
}
/**
* populateNavTrees creates the first trees if no query params are available in the url:
* It ceates the manuscripNavTree and the activePageNavTreeData of the first manuscript per default.
*
*/
async populateNavTrees(tabIdx?: number, itemId?: string) {
const tabStartIndex = tabIdx || 0; // where to start refreshing navtrees
for ( const treeDef of this.navigationTreeDefs.sort(def => (def.idx ))) {
if (treeDef.idx >= tabStartIndex) { // only create trees if needed
this.queryService.getQueryfromFilename(treeDef.apiDef.query).subscribe(async query => {
let queryToRun: string;
// If there is a selectedItem we have to parametrize the query
if (treeDef.idx > 0) { // so we have to parametrize the query
if (itemId) {
queryToRun = this.queryService.parametrizeQueryWithItem(query, itemId);
this.populateNavTree(treeDef, queryToRun);
} else {
// wait for selected item of the previous tab and parametrize then the query
this.navTrees[treeDef.idx - 1].selectedItemSet.subscribe(item => {
if (item.tabId === treeDef.idx - 1) {
queryToRun = this.queryService.parametrizeQueryWithItem(query, item.itemId);
this.populateNavTree(treeDef, queryToRun); }
});
}
} else {
this.populateNavTree(treeDef, query); }
});
}
}
}
populateNavTree(def: NavTreeDef, query) {
const idx = this.navTrees.findIndex(item => item.id === def.id);
let parentLabel;
if (idx > 0) { parentLabel = this.navTrees[idx - 1].selectedItemLabel; }
if (idx !== -1) {
this.queryService.getData(def.apiDef.baseUrl, query, 'SELECT').subscribe(data => {
this.navTrees[idx].setNavTreeData(_.get(data, def.apiDef.dataArray),
this.activatedRoute.snapshot.queryParams, parentLabel); });
}
}
}
diff --git a/nietzsche-beta-app/src/app/page-view/textfield-component/textfield.component.ts b/nietzsche-beta-app/src/app/page-view/textfield-component/textfield.component.ts
index d091a4a..1783f14 100644
--- a/nietzsche-beta-app/src/app/page-view/textfield-component/textfield.component.ts
+++ b/nietzsche-beta-app/src/app/page-view/textfield-component/textfield.component.ts
@@ -1,348 +1,348 @@
import { Component, ElementRef, Input, Output, EventEmitter, OnInit, OnChanges, SimpleChanges } from '@angular/core';
import { externalAssignClass, externalAssignStyle, Configuration, Continuation, Identifier, Image, Line, Position, PositionalObject, TextByForeignHand, Word, USE_EXTERNAL_TOOLTIP} from '../models';
import { PageViewService } from '../page-view.service';
import { HIGHTLIGHT_CASES } from '../highlight_status';
import { ConfigurableComponent } from '../configurable-component';
import { Matrix } from './matrix';
/**
* This component displays an image with word hovers.
**/
@Component({
selector: 'text-field',
templateUrl: './textfield.component.html',
styleUrls: ['./textfield.component.css']
})
export class TextFieldComponent extends ConfigurableComponent implements OnInit, OnChanges {
/**
* scrollable HTML-container of this textfield
**/
@Input() container: HTMLElement;
/**
* the currently clicked word
* */
clickedWord?: Word;
/**
* Debug mode.
**/
debug: boolean = false;
/**
* the search text of words that should be highlighted as {@link /miscellaneous/enumerations.html#HIGHTLIGHT_CASES|HIGHTLIGHT_CASES.SEARCHED_WORD}.
**/
@Input() findText: string;
/**
- * texts written by foreign hand
+ * texts written by foreign hand
**/
@Input() foreign_texts: TextByForeignHand[] = [];
/**
* the currently hovered line
* */
hoveredLine?: Line;
/**
- * the currently hovered text by foreign hand
+ * the currently hovered text by foreign hand
* */
hoveredTextByForeignHand?: TextByForeignHand;
/**
* the currently hovered word
* */
hoveredWord?: Word;
/**
* the image that will be displayed.
**/
@Input() image: Image;
/**
* textfield's identity.
**/
@Input() identity: string = 'first textfield';
/**
- * The (unzoomed) height of the root svg.
+ * The (unzoomed) height of the root svg.
*
* (The actual height is 'image_height*local_zoom*zoomFactor'
* */
image_height: number = 400;
/**
* image properties for the svg-image.
* */
imageSpec = { x: 0, y: 0, height: 973.91998, width: 2038.5601, URL: null, secondaryURL: null, transform: 'matrix(1 0 0 1 0 0)' };
/**
- * The (unzoomed) width of the root svg.
+ * The (unzoomed) width of the root svg.
*
* (The actual width is 'image_width*local_zoom*zoomFactor'
* */
image_width: number = 300;
/**
* the viewBox of the root svg specifying the area of the svg that will be shown.
* */
viewBox: string = '';
/**
* the (initial) maximum height of the image.
**/
@Input() max_height: number = -1;
/**
* the (initial) maximum width of the image.
**/
@Input() max_width: number = -1;
/**
* should primary Url be used for image. Use secondary Url if false.
**/
@Input() preferPrimaryUrl: boolean = true;
/**
* Use extended tooltip.
**/
@Input() useExtendedTooltip: boolean = false;
/**
* the words that will be displayed as rects on the image.
**/
@Input() words: Word[];
/**
* global zoom factor.
**/
@Input() zoomFactor: number = 1;
/**
- * local zoom factor that sets the height and width of the image according to {@link #max_height|max_height}.
+ * local zoom factor that sets the height and width of the image according to {@link #max_height|max_height}.
* */
local_zoom: number = 1;
/**
* An optional function that can be passed to this component 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') externalAssignClassAfter?: externalAssignClass;
/**
- * An optional function that can be passed to this component in order to return a (svg-)style object
+ * An optional function that can be passed to this component in order to return a (svg-)style object
* to the word 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') extAssignStyle?: externalAssignStyle;
/**
* identifiers of selected words that should be highlighted.
**/
@Input() selectedWords: Identifier[] = [];
/**
* identifiers of selected lines that should be highlighted.
**/
@Input() selectedLines: Identifier[] = [];
/**
* @param pageViewService an information source about (un-)hovered and clicked Lines/Words.
* */
- constructor( protected pageViewService: PageViewService) {
+ constructor( protected pageViewService: PageViewService) {
super()
}
ngOnInit() {
if (this.max_height == -1 && this.max_width == -1){
this.max_height = screen.availHeight;
}
if (this.image.text_field != null) {
this.updateImageProperties();
} else if (this.imageSpec != null) {
this.image_width = this.imageSpec.width;
this.image_height = this.imageSpec.height;
this.viewBox = '0 0 ' + this.image_width + ' ' + this.image_height;
}
this.pageViewService.onClickedWord.subscribe(
(changedWord: Word ) => this.clickedWord = changedWord
);
this.pageViewService.onHoveredWord.subscribe(
(changedWord: Word) => this.hoveredWord = changedWord
);
this.pageViewService.offHoveredWord.subscribe(
(changedWord: Word) => { this.hoveredWord = null; }
);
this.pageViewService.onHoveredLine.subscribe(
(changedLine: Line) => { this.hoveredLine = changedLine}
);
this.pageViewService.offHoveredLine.subscribe(
(changedLine: Line) => { this.hoveredLine = null; }
);
this.pageViewService.onHoveredTextByForeignHand.subscribe(
(changedForeignText: TextByForeignHand) => { this.hoveredTextByForeignHand = changedForeignText;}
);
this.pageViewService.offHoveredTextByForeignHand.subscribe(
(changedForeignText: TextByForeignHand) => { this.hoveredTextByForeignHand = null; }
);
}
ngOnChanges() {
super.ngOnChanges()
if (this.image.text_field != null) {
this.updateImageProperties();
}
if(this.debug && this.findText != null && this.findText != ''){
let words = this.words.filter(word =>word.text == this.findText)
if (words.length > 0){
this.pageViewService.onHoverService(words[0], {visible: true, clientX: 100, clientY: 100, layerX: -1, layerY: -1 })
}
}
}
/**
* Update image properties: use textfield in order to specify the area of the image that will be shown.
*
* @param URL set alternative image url. This will be used on image load error (see Template)
**/
private updateImageProperties(URL?: string){
let previous_word: Word = null;
for (var i = 0; i < this.words.length; i++){
this.words[i].datatype = "Word";
if (previous_word == null || previous_word.id != this.words[i].id){
previous_word = this.words[i]
previous_word.is_top_object = true;
} else if (previous_word.top > this.words[i].top){
previous_word.is_top_object = false;
previous_word = this.words[i]
previous_word.is_top_object = true;
} else {
this.words[i].is_top_object = false;
}
}
this.foreign_texts.forEach(foreignText =>foreignText.datatype = "TextByForeignHand");
let image_left = this.image.text_field.left;
let image_top = this.image.text_field.top;
this.image_width = this.image.text_field.width;
this.image_height = this.image.text_field.height;
- this.local_zoom = (this.max_height != -1 && this.max_width == -1)
+ this.local_zoom = (this.max_height != -1 && this.max_width == -1)
? this.max_height/this.image.text_field.height : this.max_width/this.image.text_field.width;
if (this.max_width == -1 && this.image_height < this.image_width){
this.local_zoom = (window.innerWidth/2-100)/this.image.text_field.width;
}
this.imageSpec.x = this.image.x;
this.imageSpec.y = this.image.y;
this.imageSpec.height = this.image.height;
this.imageSpec.width = this.image.width;
this.imageSpec.URL = (this.preferPrimaryUrl) ? this.image.URL : this.image.secondaryURL;
this.imageSpec.secondaryURL = (this.preferPrimaryUrl) ? this.image.URL : this.image.URL;
if (URL != null){
this.imageSpec.secondaryURL = this.imageSpec.URL
this.imageSpec.URL = URL;
}
if(this.image.transform != null){
this.local_zoom = this.max_height/this.image.text_field.width;
let matrix = new Matrix(this.image.transform, this.local_zoom*this.zoomFactor);
this.imageSpec.transform = matrix.toString()
}
this.viewBox = image_left + ' ' + image_top + ' ' + this.image_width + ' ' + this.image_height;
}
/**
* Return the position (i.e. '{ x: x, y: y }') for the copyright symbol.
* @param dimension dimension of the copyright symbol.
**/
private getCopyrightPosition(dimension: number): Object {
if (this.image.text_field != null && this.image.text_field != undefined){
let positions: Position[] = [
{ x: Number(this.image.text_field.left) +10/this.zoomFactor,
y: Number(this.image.text_field.top) +10/this.zoomFactor },
{ x: Number(this.image.text_field.left),
y: Number(this.image.text_field.top)},
{ x: Number(this.image.text_field.width) + Number(this.image.text_field.left) -15/this.zoomFactor - dimension,
y: Number(this.image.text_field.height) + Number(this.image.text_field.top) -15/this.zoomFactor - dimension },
{ x: Number(this.image.text_field.width) + Number(this.image.text_field.left) - dimension,
y: Number(this.image.text_field.height) + Number(this.image.text_field.top) - dimension },
{ x: Number(this.image.text_field.left) +10/this.zoomFactor,
y: Number(this.image.text_field.height) + Number(this.image.text_field.top) -10/this.zoomFactor - dimension },
{ x: Number(this.image.text_field.width) + Number(this.image.text_field.left) -10/this.zoomFactor - dimension,
y: Number(this.image.text_field.top) +10/this.zoomFactor},
{ x: Number(this.image.text_field.width) + Number(this.image.text_field.left) - dimension,
y: Number(this.image.text_field.top)}
]
let default_index = 1
let index = 0;
let position_found = false;
while (!position_found && index < positions.length){
let left = positions[index].x
let top = positions[index].y
if(!this.doesPositionConflict(left, top, dimension, this.words)
&& !this.doesPositionConflict(left, top, dimension, this.foreign_texts)){
- position_found = true;
+ position_found = true;
} else {
- index++
+ index++
}
}
let left = (index < positions.length) ? positions[index].x : positions[default_index].x;
let top = (index < positions.length) ? positions[index].y : positions[default_index].y;
return { x: `${left}px`, y: `${top}px` }
} else {
return { x: '0px', y: '0px' }
}
}
/**
* Return whether position specified by left, top and dimension does conflict with one of the positional objects' position.
*
* @param left left of position
* @param top top of position
* @param dimension dimension of position
* @param positionalObjects Array of positions
**/
private doesPositionConflict(left: number, top: number, dimension: number, positionalObjects: PositionalObject[]): boolean {
let conflicts = positionalObjects.filter(positionalObject =>
- !(Number(positionalObject.left) + Number(positionalObject.width) < left || Number(positionalObject.left) > left + dimension
+ !(Number(positionalObject.left) + Number(positionalObject.width) < left || Number(positionalObject.left) > left + dimension
|| Number(positionalObject.top) > top + dimension || Number(positionalObject.top) + Number(positionalObject.height) < top)
)
return conflicts.length > 0
}
/**
* Get the hover status of the word as one of the {@link /miscellaneous/enumerations.html#HIGHTLIGHT_CASES|HIGHTLIGHT_CASES}.
**/
private getHoverStatus(word: Word, skipFindText: boolean = false): string {
if (this.selectedWords.indexOf(word.id) > -1
|| this.selectedLines.indexOf(word.line) > -1){
return HIGHTLIGHT_CASES.SELECTED_WORD;
}
if (!skipFindText && this.findText != null && this.findText != ''){
let findRegex = '^[^\\w]*(' + this.findText.split(' ').join('|') + ')'
- return (word.text.match(findRegex)
+ return (word.text.match(findRegex)
|| (word.edited_text != null && word.edited_text.match(findRegex))
- ) ? HIGHTLIGHT_CASES.SEARCHED_WORD : this.getHoverStatus(word, true);
+ ) ? HIGHTLIGHT_CASES.SEARCHED_WORD : this.getHoverStatus(word, true);
}
if (typeof this.hoveredLine !== 'undefined' && this.hoveredLine !== null) {
- return (this.hoveredLine.id == word.line
+ return (this.hoveredLine.id == word.line
|| (this.hoveredLine.continuesTo != undefined && this.hoveredLine.continuesTo != null && this.hoveredLine.continuesTo.line.id == word.line)
|| (this.hoveredLine.continuesFrom != undefined && this.hoveredLine.continuesFrom != null && this.hoveredLine.continuesFrom.line.id == word.line))
- ? HIGHTLIGHT_CASES.LINE_HOVERED : HIGHTLIGHT_CASES.DEFAULT;
+ ? HIGHTLIGHT_CASES.LINE_HOVERED : HIGHTLIGHT_CASES.DEFAULT;
} else if (typeof this.hoveredWord !== 'undefined' && this.hoveredWord !== null){
return (this.hoveredWord.id == word.id) ? HIGHTLIGHT_CASES.WORD_HOVERED : HIGHTLIGHT_CASES.DEFAULT;
- }
+ }
return HIGHTLIGHT_CASES.DEFAULT;
}
/**
- * Return a css class for word that will be used with [ngClass] in order to (un-)highlight the word's rect.
+ * Return a css class for word that will be used with [ngClass] in order to (un-)highlight the word's rect.
*
* If a function has been passed to Input {@link #assignClass|assignClass},
* this function will call it if {@link #getHoverStatus|getHoverStatus(word)} == {@link /miscellaneous/enumerations.html#HIGHTLIGHT_CASES|HIGHTLIGHT_CASES.DEFAULT}.
**/
private assignClass(positionalObject: PositionalObject, elementName?: string): string {
if (positionalObject.datatype == 'TextByForeignHand'){
- return (this.hoveredTextByForeignHand != null && this.hoveredTextByForeignHand.id == positionalObject.id) ?
+ return (this.hoveredTextByForeignHand != null && this.hoveredTextByForeignHand.id == positionalObject.id) ?
'text_field highlight_foreign_text' : 'text_field unhighlighted'
}
let word = positionalObject;
if (elementName != null) {
return (this.getHoverStatus(word) == HIGHTLIGHT_CASES.DEFAULT) ? `text_field unhighlighted_${elementName}` : `text_field highlight_${elementName}`;
}
switch(this.getHoverStatus(word)) {
case HIGHTLIGHT_CASES.SELECTED_WORD: {
return 'textfield highlight_magenta';
}
case HIGHTLIGHT_CASES.SEARCHED_WORD: {
return 'textfield highlight_red';
}
case HIGHTLIGHT_CASES.LINE_HOVERED: {
return (word.deleted) ? 'textfield deleted' : 'textfield highlight_yellow';
}
case HIGHTLIGHT_CASES.WORD_HOVERED: {
return (word.deleted) ? 'textfield deleted' : 'textfield highlight_yellow';
}
case HIGHTLIGHT_CASES.DEFAULT: {
return (this.externalAssignClassAfter != null) ? this.externalAssignClassAfter(word, this.hoveredWord, this.hoveredLine) : 'textfield unhighlighted';
}
}
}
/**
* Assign a style to the rects of a line.
**/
private assignStyle(word: Word, hoveredWord: Word, hoveredLine: Line, hoverStatus: string): Object {
return (this.extAssignStyle != null) ? this.extAssignStyle(word, hoveredWord, hoveredLine, hoverStatus) : {};
}
private msg(URL: string){
if(this.preferPrimaryUrl){
- console.log(URL + ' TODO: show smaller image during loading');
+ // console.log(URL + ' TODO: show smaller image during loading');
}
}
}
diff --git a/nietzsche-beta-app/src/index.html b/nietzsche-beta-app/src/index.html
index 06955f7..9292d10 100644
--- a/nietzsche-beta-app/src/index.html
+++ b/nietzsche-beta-app/src/index.html
@@ -1,18 +1,18 @@
- Nietzsche beta app
+ Der späte Nietzsche