Skip to content

Commit

Permalink
Merge pull request #895 from d-i-t-a/bugfix/link-event-handler
Browse files Browse the repository at this point in the history
fixes link event handler
  • Loading branch information
aferditamuriqi authored Jul 17, 2024
2 parents a4463bb + 59b11c1 commit 74b87af
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 72 deletions.
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
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);
}
}
};
}

0 comments on commit 74b87af

Please sign in to comment.