Skip to content

Commit

Permalink
Fixes an issue where content would not load when internal links are c…
Browse files Browse the repository at this point in the history
…licked
  • Loading branch information
aferditamuriqi committed Jul 17, 2024
1 parent a4463bb commit 3a23d28
Showing 1 changed file with 62 additions and 69 deletions.
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 3a23d28

Please sign in to comment.