Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2.4.10 #896

Merged
merged 5 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.4.9",
"version": "2.4.10",
"description": "A viewer application for EPUB files.",
"repository": "https://github.com/d-i-t-a/R2D2BC",
"license": "Apache-2.0",
Expand Down
10 changes: 10 additions & 0 deletions src/reader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,16 @@ export default class D2Reader {
addAnnotation = async (highlight: Annotation) => {
return (await this.annotationModule?.addAnnotation(highlight)) ?? false;
};
/**
* Update annotation
*
* This should be used only when the add/delete of the annotation note
* is not directly handled in the `addAnnotation`/`addCommentToAnnotation`
* callback defined in the configuration of the D2Reader.load() method
* */
updateAnnotation = async (highlight: Annotation) => {
return (await this.annotationModule?.updateAnnotation(highlight)) ?? false;
};

/** Hide Annotation Layer */
hideAnnotationLayer = () => {
Expand Down
131 changes: 62 additions & 69 deletions src/utils/EventHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,21 +54,35 @@ export default class EventHandler {

public setupEvents(element: HTMLElement | Document | null) {
if (element !== null) {
element.addEventListener(
"dblclick",
async (event: TouchEvent) => {
element.addEventListener("click", async (event: TouchEvent) => {
const link = this.checkForLink(event);
if (link) {
await this.handleLinks(event);
event.preventDefault();
event.stopPropagation();
}
if (this.clickTimeout !== null) {
clearTimeout(this.clickTimeout);
this.clickTimeout = null;
// Handle double click here
log.log("Double Click Detected");
let htmlElement = event.target as HTMLElement;
if (event.target && htmlElement.tagName.toLowerCase() === "img") {
await this.popup.showPopover(htmlElement, event);
}
},
true
);
} else {
this.clickTimeout = window.setTimeout(async () => {
// Handle single click here
log.log("Single Click Detected");
await this.handleLinks(event);
this.clickTimeout = null;
}, 200); // Adjust timeout duration as needed
}
});

// Most click handling is done in the touchend and mouseup event handlers,
// but if there's a click on an external link we need to cancel the click
// event to prevent it from opening in the iframe.
element.addEventListener("click", this.handleLinks.bind(this), true);
} else {
throw "cannot setup events for null";
}
Expand Down Expand Up @@ -127,79 +141,58 @@ export default class EventHandler {
return isEpubInternal;
};

clicks = 0;
clickTimer: any = 0;
dblClickTimeSpan = 300;
private clickTimeout: number | null = null;

private handleLinks = async (
event: MouseEvent | TouchEvent
): Promise<void> => {
log.log("R2 Click Handler");
this.clicks++;
if (this.clicks === 1) {
this.clickTimer = setTimeout(async () => {
this.clicks = 0;

const link = this.checkForLink(event);
if (link) {
// Open external links in new tabs.
const isSameOrigin =
window.location.protocol === link.protocol &&
window.location.port === link.port &&
window.location.hostname === link.hostname;

// If epub is hosted, rather than streamed, links to a resource inside the same epub should not be opened externally.
const isEpubInternal = this.isReadingOrderInternal(link);

const isResourceInternal = this.isResourceInternal(link);
if (!isResourceInternal) {
await this.popup.hidePopover();
}
const link = this.checkForLink(event);
if (link) {
const isSameOrigin =
window.location.protocol === link.protocol &&
window.location.port === link.port &&
window.location.hostname === link.hostname;

const isInternal = link.href.indexOf("#");
if (!isEpubInternal && !isResourceInternal) {
window.open(link.href, link.target ?? "_blank");
event.preventDefault();
event.stopPropagation();
} else {
(event.target as HTMLAnchorElement).href = link.href;
if ((isSameOrigin || isEpubInternal) && isInternal !== -1) {
const link = event.target as HTMLLIElement;
if (link) {
const attribute = link.getAttribute("epub:type") === "noteref";
if (attribute) {
await this.popup.handleFootnote(link, event);
} else if (isResourceInternal && !isEpubInternal) {
await this.popup.showPopover(link, event);
} else {
this.onInternalLink(event);
}
} else {
this.onInternalLink(event);
}
} else if ((isSameOrigin || isEpubInternal) && isInternal === -1) {
// TODO needs some more refactoring when handling other types of links or elements
// link.click();
const isEpubInternal = this.isReadingOrderInternal(link);
const isResourceInternal = this.isResourceInternal(link);

if (!isResourceInternal) {
await this.popup.hidePopover();
}

const isInternal = link.href.indexOf("#") !== -1;

if (!isEpubInternal && !isResourceInternal) {
window.open(link.href, link.target ?? "_blank");
event.preventDefault();
event.stopPropagation();
} else {
(event.target as HTMLAnchorElement).href = link.href;
if ((isSameOrigin || isEpubInternal) && isInternal) {
const linkElement = event.target as HTMLLIElement;
if (linkElement) {
const attribute =
linkElement.getAttribute("epub:type") === "noteref";
if (attribute) {
await this.popup.handleFootnote(linkElement, event);
} else if (isResourceInternal && !isEpubInternal) {
await this.popup.showPopover(linkElement, event);
} else {
this.onInternalLink(event);
}
} else {
this.onInternalLink(event);
}
} else {
setTimeout(() => {
console.log("event.detail", event.detail);
if (
!this.navigator.highlighter?.isSelectionMenuOpen &&
event.detail === 1
) {
this.onClickThrough(event);
}
}, 100);
} else if ((isSameOrigin || isEpubInternal) && !isInternal) {
this.onInternalLink(event);
}
}, this.dblClickTimeSpan);
}
if (this.clicks === 2) {
// it is the second click in double-click event
clearTimeout(this.clickTimer);
this.clicks = 0;
}
} else {
if (!this.navigator.highlighter?.isSelectionMenuOpen) {
this.onClickThrough(event);
}
}
};
}
Loading