Skip to content

#14: Link click listeners#19

Open
kostiukevych-ls wants to merge 4 commits intomainfrom
link-click-listeners
Open

#14: Link click listeners#19
kostiukevych-ls wants to merge 4 commits intomainfrom
link-click-listeners

Conversation

@kostiukevych-ls
Copy link
Copy Markdown
Contributor

No description provided.

@kostiukevych-ls kostiukevych-ls self-assigned this Jun 13, 2025
@kostiukevych-ls kostiukevych-ls linked an issue Jun 13, 2025 that may be closed by this pull request
Comment thread src/client.js Outdated
// Check if href is a relative URL
const isRelative = href &&
(href.startsWith("./") || href.startsWith("/") ||
!/^(?:[a-z]+:)?\/\//i.test(href));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this last regex probably could be simpler and just be http / https right? Is there some other protocol we need to match for?

Copy link
Copy Markdown
Member

@gabesullice gabesullice Jun 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes sense to check for more than just http, e.g. tel:3035559999or mailto:foo@example.com.

But, I agree that we could simplify. According to MDN, the href should already be parsed by the browser, so this might be all we need:

const isExternal = !href.startsWith(appDiv.baseURI);
if (isExternal) return;

(using appDiv.baseURI is intentional)

If relative href attributes are not already expanded to absolute URLs, we can normalize it ourselves with the browser's help:

const normalizedHREF = new URL(href, anchor.baseURI).href;

https://developer.mozilla.org/en-US/docs/Web/API/Node/baseURI

Comment thread src/client.js
Copy link
Copy Markdown
Member

@gabesullice gabesullice left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good so far, let's:

  1. Account for a couple other cases when a link shouldn't be following automatically (see download and target comment below).
  2. Try to simplify the isRelative check a bit

Comment thread src/client.js
Comment thread src/client.js Outdated
event.stopPropagation();

// Call the client's follow function
client.follow(href, {});
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: no need to pass the default value IMO

Suggested change
client.follow(href, {});
client.follow(href);

@kostiukevych-ls
Copy link
Copy Markdown
Contributor Author

@gabesullice @zrpnr Thank you both for your comments and suggestions. I've incorporated all your feedback as best I could. Please let me know if there's anything I missed or should improve further.

Copy link
Copy Markdown
Member

@gabesullice gabesullice left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me! Thanks @kostiukevych-ls :)

Before I merge it though, let's make a draft PR against the https://github.com/Applura/intro repo: Applura/intro#19

Comment thread src/client.js
// Check if anchor has a target attribute that is not _blank
if (
anchor.hasAttribute("target") &&
anchor.getAttribute("target") !== "_blank"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Comment thread src/client.js
Comment on lines +102 to +104
if (!(event.target instanceof HTMLAnchorElement)) return;

const anchor = event.target;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is too strict, for example the markup could be something like <a href=""><div class="title">Click me</div></a> Then the event.target would be the div.title instead of the anchor and this will return.

Suggested change
if (!(event.target instanceof HTMLAnchorElement)) return;
const anchor = event.target;
const anchor = event.target instanceof HTMLAnchorElement ? event.target : event.target.closest('a');
if (!anchor) return;

Comment thread src/client.js
if (!(event.target instanceof HTMLAnchorElement)) return;

const anchor = event.target;
const href = anchor.href; // Safe to access href directly
Copy link
Copy Markdown
Contributor

@zrpnr zrpnr Aug 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the href property seems to always be absolute, let's use

Suggested change
const href = anchor.href; // Safe to access href directly
const href = anchor.getAttribute("href");

Comment thread src/client.js
const normalizedHREF = url.href;

// Call the client's follow function
client.follow(normalizedHREF);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here normalizedHREF is now the app baseuri and not the api baseURI so follow will return early.
I think it's safe to just use the href here since we have already checked for the protocol and isExternal

Suggested change
client.follow(normalizedHREF);
client.follow(href);

Comment thread src/client.js
return;
}
const isExternal = url.protocol !== "http:" && url.protocol !== "https:" ||
url.origin !== new URL(appDiv.baseURI).origin;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not critical to change now but this could just be isKnownProtocol since we also do the isExternal check by comparing the origins inside follow

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Link click listeners

3 participants