Skip to content

Add repo file tree item link behavior #34730

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

Open
wants to merge 17 commits into
base: main
Choose a base branch
from

Conversation

bytedream
Copy link
Contributor

@bytedream bytedream commented Jun 15, 2025

Converts the repo file tree items into <a> elements to have default link behavior. Dynamic content load is still done when no special key is pressed while clicking on an item.

@GiteaBot GiteaBot added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Jun 15, 2025
@lunny lunny added type/enhancement An improvement of existing functionality topic/ui Change the appearance of the Gitea UI labels Jun 15, 2025
@lunny lunny added this to the 1.25.0 milestone Jun 15, 2025
@wxiaoguang
Copy link
Contributor

It should also follow the browser's default behavior: Ctrl+Click / Command+Click means "Open in New Window"

@bytedream
Copy link
Contributor Author

Done, thanks for pointing this out

@wxiaoguang
Copy link
Contributor

By doing some searches, I think "middle key" is not a widely used approach to "open a new window". I do not see browsers officially support it.

The widely supported approach is "Ctrl+LeftClick"

@wxiaoguang
Copy link
Contributor

If you'd like to support "middle click", the ideal approach can be like this:

  • make the items to be real <a> links, then middle-click works for users by default.
  • use our @click handler to handle ctrl/meta keys, and stop the default link's behavior.

@silverwind
Copy link
Member

silverwind commented Jun 17, 2025

I think we should just render a native <a> element and only preventDefault the click event with button 0, while letting the browser handle all other interactions.

This way, stuff like middle click, ctrl+click, cmd+click will all work natively and don't even need explicit handlers.

@wxiaoguang
Copy link
Contributor

I think we should just render a native <a> element and only preventDefault the click event with button 0, while letting the browser handle all other interactions.

This way, stuff like middle click, ctrl+click, cmd+click will all work natively and don't even need explicit handlers.

The same as #34730 (comment) ? Or is there something I missed?

@silverwind
Copy link
Member

silverwind commented Jun 17, 2025

I think we should just render a native <a> element and only preventDefault the click event with button 0, while letting the browser handle all other interactions.
This way, stuff like middle click, ctrl+click, cmd+click will all work natively and don't even need explicit handlers.

The same as #34730 (comment) ? Or is there something I missed?

Basically the same, but I guess the code still need to check whether any modifier key is held, and only e.preventDefault when none are because deciding only on e.button is not enough.

@wxiaoguang
Copy link
Contributor

I see, maybe ideally it could be like this:

  • use <a> for tree items with real links.
  • if no ctrl/meta/alt key, then use our "fetch" to load the file view content without reload, and preventDefault.
  • otherwise, we do nothing and leave the work to the browser.

@silverwind
Copy link
Member

silverwind commented Jun 17, 2025

Yes, so basically:

if (e.button !== 0 || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey) {
  return; // let browser handle the click
}

e.preventDefault();
// update view to clicked file

Maybe shiftKey can be removed, I'm not aware of any special functionality tied to it. altKey is useful for text selection within a link.

@bytedream bytedream changed the title Add repo file tree middle click open Add repo file tree item link behavior Jun 18, 2025
@bytedream
Copy link
Contributor Author

Thanks for the suggestions, I've updated the PR accordingly by using <a> tags.

By doing some searches, I think "middle key" is not a widely used approach to "open a new window". I do not see browsers officially support it.

Interesting, I almost exclusively use the middle click to open links and such in a new tab.

Maybe shiftKey can be removed, I'm not aware of any special functionality tied to it. altKey is useful for text selection within a link.

Shift+LeftClick opens the link in a new browser window, so I've kept it.

@silverwind
Copy link
Member

Yes, we need to keep all modifiers, they all have a purpose and mine opens new window on shift+click too. middle click and ctrl+click are both known to me, so they are not so obscure :)

@@ -131,6 +142,8 @@ const doGotoSubModule = () => {
}

.tree-item {
color: inherit;
text-decoration: inherit;
Copy link
Member

Choose a reason for hiding this comment

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

You can add one of our link classes from here instead:

gitea/web_src/css/base.css

Lines 253 to 256 in a2ae7c6

/* a = always colored, underlined on hover */
/* a.muted = colored on hover, underlined on hover */
/* a.suppressed = never colored, underlined on hover */
/* a.silenced = never colored, never underlined */

I guess silenced may be the best fit if you never want to highlight.

props.navigateViewContent(props.item.fullPath);
};
const doLoadFileContent = (e: MouseEvent) => {
if (e.button !== 0 || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey) return;
Copy link
Member

@silverwind silverwind Jun 18, 2025

Choose a reason for hiding this comment

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

Would extract this into a function in web_src/js/utils/dom.ts:

/** Returns whether a click event is a left-click without any modifiers held */
export function isPlainClick(e: MouseEvent) {
  return e.button === 0 && !e.ctrlKey && !e.metaKey && !e.altKey && !e.shiftKey;
}

selectedItem?: string,
}>();

const isLoading = ref(false);
const children = ref(props.item.children);
const collapsed = ref(!props.item.children);

const doLoadChildren = async () => {
const doLoadChildren = async (e?: MouseEvent) => {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
const doLoadChildren = async (e?: MouseEvent) => {
const doLoadChildren = async (e: MouseEvent | null) => {

I guess I would prefer if you pass explicit null here to indicate the absence of a event.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. modifies/frontend topic/ui Change the appearance of the Gitea UI type/enhancement An improvement of existing functionality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants