Skip to content

Commit

Permalink
Merge pull request #385 from d-i-t-a/bugfix/allvit-fixes-1
Browse files Browse the repository at this point in the history
Allvit and Bibliotheca Annotation fixes
  • Loading branch information
aferditamuriqi authored Sep 11, 2022
2 parents 4cd4fa9 + 69045ff commit 48474ee
Show file tree
Hide file tree
Showing 12 changed files with 547 additions and 120 deletions.
6 changes: 6 additions & 0 deletions injectables/style/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -253,3 +253,9 @@
img {
max-height: var(--USER__maxMediaHeight) !important;
}

#R2_ID_GUTTER_RIGHT_CONTAINER {
position: absolute;
top: 0;
right: -20px;
}
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@d-i-t-a/reader",
"version": "2.1.0-beta.9",
"version": "2.1.0-beta.10",
"description": "A viewer application for EPUB files.",
"repository": "https://github.com/d-i-t-a/R2D2BC",
"license": "Apache-2.0",
Expand Down
1 change: 1 addition & 0 deletions src/model/Locator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export enum AnnotationMarker {
Underline,
Bookmark,
Custom,
Comment,
}

export interface Annotation extends Locator {
Expand Down
268 changes: 254 additions & 14 deletions src/modules/AnnotationModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@ import * as HTMLUtilities from "../utils/HTMLUtilities";
import Annotator, { AnnotationType } from "../store/Annotator";
import { IFrameNavigator, ReaderRights } from "../navigator/IFrameNavigator";
import { Publication } from "../model/Publication";
import { TextHighlighter, _highlights } from "./highlight/TextHighlighter";
import {
TextHighlighter,
_highlights,
CLASS_HIGHLIGHT_AREA,
HighlightContainer,
} from "./highlight/TextHighlighter";
import { ReaderModule } from "./ReaderModule";
import { addEventListenerOptional } from "../utils/EventHandler";
import { HighlightType, IHighlight } from "./highlight/common/highlight";
Expand All @@ -31,7 +36,7 @@ import {
Bookmark,
Locator,
} from "../model/Locator";
import { icons as IconLib } from "../utils/IconLib";
import { icons as IconLib, iconTemplateColored } from "../utils/IconLib";
import { v4 as uuid } from "uuid";
import { Link } from "../model/Link";
import { convertRange } from "./highlight/renderer/iframe/selection";
Expand All @@ -50,10 +55,12 @@ export interface AnnotationModuleAPI {
deleteAnnotation: Highlight;
updateAnnotation: Highlight;
selectedAnnotation: Highlight;
addCommentToAnnotation: Highlight;
}
export interface AnnotationModuleProperties {
initialAnnotationColor?: string;
hideLayer?: boolean;
enableComments?: boolean;
}

export interface AnnotationModuleConfig extends AnnotationModuleProperties {
Expand All @@ -72,6 +79,7 @@ export class AnnotationModule implements ReaderModule {
private rights: Partial<ReaderRights>;
private publication: Publication;
private highlightsView: HTMLDivElement;
private commentGutter?: HTMLDivElement | null;
private readonly headerMenu?: HTMLElement | null;
private readonly highlighter?: TextHighlighter;
private readonly initialAnnotations: any;
Expand Down Expand Up @@ -138,6 +146,7 @@ export class AnnotationModule implements ReaderModule {
this.annotator?.initAnnotations(highlights);
}
}

setTimeout(() => {
this.properties?.hideLayer
? this.delegate.hideLayer("highlights")
Expand Down Expand Up @@ -190,7 +199,7 @@ export class AnnotationModule implements ReaderModule {
setTimeout(async () => {
await this.drawHighlights();
await this.showHighlights();
}, 100);
}, 200);
}

initialize() {
Expand Down Expand Up @@ -237,10 +246,6 @@ export class AnnotationModule implements ReaderModule {
selection.removeAllRanges();
selection.addRange(range);

// Alert result
// let str = range.toString().trim();
// alert(str);

let self = this;

function getCssSelector(element: Element): string {
Expand Down Expand Up @@ -289,11 +294,14 @@ export class AnnotationModule implements ReaderModule {

async scrollToHighlight(id: any): Promise<any> {
log.log("still need to scroll to " + id);
var position = await this.annotator?.getAnnotationPosition(
var element = await this.annotator?.getAnnotationElement(
id,
this.delegate.iframes[0].contentWindow as any
);
window.scrollTo(0, position - window.innerHeight / 3);
element.scrollIntoView({
block: "center",
behavior: "smooth",
});
}

async updateLocalHighlight(annotation: Annotation): Promise<any> {
Expand Down Expand Up @@ -446,11 +454,16 @@ export class AnnotationModule implements ReaderModule {

if (annotation) {
if (this.api?.addAnnotation) {
let result = await this.api.addAnnotation(annotation);
const saved = await this.annotator.saveAnnotation(result);
await this.showHighlights();
await this.drawHighlights();
return new Promise<Annotation>((resolve) => resolve(saved));
try {
let result = await this.api.addAnnotation(annotation);
const saved = await this.annotator.saveAnnotation(result);
await this.showHighlights();
await this.drawHighlights();
return new Promise<Annotation>((resolve) => resolve(saved));
} catch (error) {
await this.showHighlights();
await this.drawHighlights();
}
} else {
const saved = await this.annotator.saveAnnotation(annotation);
await this.showHighlights();
Expand Down Expand Up @@ -661,6 +674,114 @@ export class AnnotationModule implements ReaderModule {
if (this.properties?.initialAnnotationColor) {
this.highlighter.setColor(this.properties?.initialAnnotationColor);
}
this.repositionGutters();
}
}

repositionGutters(): any {
let doc = this.delegate.iframes[0].contentDocument;
if (doc) {
this.commentGutter = doc.getElementById(
HighlightContainer.R2_ID_GUTTER_RIGHT_CONTAINER
) as HTMLDivElement;
if (
this.delegate.view?.isScrollMode() &&
this.properties?.enableComments
) {
this.commentGutter.style.removeProperty("display");
} else {
this.commentGutter.style.setProperty("display", "none");
}
if (this.commentGutter && this.delegate.view?.isScrollMode()) {
this.commentGutter.innerHTML = "";

let highlights: Array<any> = [];
if (this.annotator) {
highlights = this.annotator.getAnnotations() as Array<any>;
if (highlights) {
highlights = highlights.filter(
(rangeRepresentation) =>
rangeRepresentation.highlight?.note?.length > 0
);
highlights = this.syncPosition(highlights);
highlights = this.reposition(highlights);

highlights.forEach((rangeRepresentation) => {
let icon: HTMLElement = document.createElement("i");
icon.innerHTML = "sticky_note_2";
icon.className = "material-icons";
icon.style.color = rangeRepresentation.highlight.color;

let container = doc!.getElementById("R2_ID_HIGHLIGHTS_CONTAINER");
let highlightArea;
let highlightIcon;
if (container) {
highlightArea = container.querySelector(
`#${rangeRepresentation.highlight.id}`
);
}

let nodeList = highlightArea.getElementsByClassName(
CLASS_HIGHLIGHT_AREA
);
highlightIcon = nodeList[0];

const size = parseInt(
highlightIcon.style.height.replace("px", "")
);

const position = rangeRepresentation.highlight.position;

const highlightAreaIcon = doc!.createElement("div");

highlightAreaIcon.setAttribute(
"style",
`position: absolute;top:${
// position - size / 2
position
}px;display: flex;max-width: 250px !important;height:${size}px;width: 200px;align-items: center;`
);

const iconSpan = doc!.createElement("div");
highlightAreaIcon.appendChild(iconSpan);

let color: any = rangeRepresentation.highlight.color;
if (TextHighlighter.isHexColor(color)) {
color = TextHighlighter.hexToRgbChannels(color);
}

highlightAreaIcon.innerHTML = iconTemplateColored(
``,
``,
`<path d="M24 24H0V0h24v24z" fill="none"/><circle cx="12" cy="12" r="8"/>`,
`icon open`,
10,
`rgba(${color.red}, ${color.green}, ${color.blue}, 1) !important`
);

const span = doc!.createElement("div");
span.innerHTML = rangeRepresentation.highlight?.note;
span.setAttribute(
"style",
`height:${size}px;overflow: hidden;padding-left: 5px;`
);

highlightAreaIcon.appendChild(span);

addEventListenerOptional(
highlightAreaIcon,
"click",
(event: MouseEvent) => {
event.preventDefault();
event.stopPropagation();
this.scrollToHighlight(rangeRepresentation.highlight.id);
}
);
this.commentGutter?.appendChild(highlightAreaIcon);
});
}
}
}
}
}

Expand Down Expand Up @@ -898,4 +1019,123 @@ export class AnnotationModule implements ReaderModule {
public async getAnnotationByID(id: string): Promise<any> {
return this.annotator?.getAnnotationByID(id);
}
syncPosition(highlights: Array<any>) {
let doc = this.delegate.iframes[0].contentDocument;

const positionAnnotations = (newArray: Array<any>, currentElement: any) => {
let container = doc!.getElementById("R2_ID_HIGHLIGHTS_CONTAINER");
let highlightArea;
let highlightIcon;
if (container) {
highlightArea = container.querySelector(
`#${currentElement.highlight.id}`
);
}

let nodeList = highlightArea.getElementsByClassName(CLASS_HIGHLIGHT_AREA);
highlightIcon = nodeList[0];

const newY = parseInt(highlightIcon.style.top.replace("px", ""));

const updatedAnnotation = {
...currentElement,
highlight: {
...currentElement.highlight,
position: newY,
},
};

return [...newArray, updatedAnnotation];
};

return highlights.reduce(positionAnnotations, []);
}

reposition(highlights: Array<any>) {
let doc = this.delegate.iframes[0].contentDocument;

const positionAnnotations = (
newArray: Array<any>,
currentElement: any,
currentIndex: number
) => {
const high = highlights[0];

let container = doc!.getElementById("R2_ID_HIGHLIGHTS_CONTAINER");
let highlightArea;
let highlightIcon;
if (container) {
highlightArea = container.querySelector(`#${high.highlight.id}`);
}

let nodeList = highlightArea.getElementsByClassName(CLASS_HIGHLIGHT_AREA);
highlightIcon = nodeList[0];

const size = parseInt(highlightIcon.style.height.replace("px", ""));

let originY = currentElement.highlight.position;

const preY =
newArray[currentIndex - 1] &&
newArray[currentIndex - 1].highlight.position;

const preHeight = size;

const preBottomY = currentIndex === 0 ? 0 : preY + preHeight + 0;
const newY = preBottomY > originY ? preBottomY : originY;

const updatedAnnotation = {
...currentElement,
highlight: {
...currentElement.highlight,
position: newY,
},
};
return [...newArray, updatedAnnotation];
};

return highlights
.sort(function (a: any, b: any) {
return a.highlight.position - b.highlight.position;
})
.reduce(positionAnnotations, []);
}
}

export function repositionHighlights(highlights: Array<any>) {
const positionAnnotations = (
newArray: Array<any>,
currentElement: any,
currentIndex: number
) => {
let originY = currentElement.position;

if (currentElement?.icon?.position === "right") {
} else {
originY = 0;
}

const preY =
newArray[currentIndex - 1] && newArray[currentIndex - 1].position;

const preHeight = newArray[currentIndex - 1] && 24;

const preBottomY = currentIndex === 0 ? 0 : preY + preHeight + 0;
const newY =
preBottomY > originY && currentElement?.icon?.position === "right"
? preBottomY
: originY;

const updatedAnnotation = {
...currentElement,
position: newY,
};
return [...newArray, updatedAnnotation];
};

return highlights
.sort(function (a: any, b: any) {
return a.position - b.position;
})
.reduce(positionAnnotations, []);
}
1 change: 0 additions & 1 deletion src/modules/TTS/TTSModule2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1206,7 +1206,6 @@ export class TTSModule2 implements ReaderModule {
const ttsQueueItem = ttsQueueItemRef.item;
let charIndexAdjusted = charIndex;


let acc = 0;
let rangeStartNode: Node | undefined;
let rangeStartOffset = -1;
Expand Down
Loading

0 comments on commit 48474ee

Please sign in to comment.