Skip to content
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
2 changes: 1 addition & 1 deletion apps/extension/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@bypass/extension",
"type": "module",
"version": "24.12.0",
"version": "24.12.1",
"private": true,
"description": "Bypass links from various sites to required links, with added functionality of Bookmarks Manager, Tagging Panel.",
"scripts": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { z } from 'zod/mini';
import { useForm } from '@tanstack/react-form';
import { useDisclosure } from '@mantine/hooks';
import { useCallback, useEffect, useMemo } from 'react';
import { useCallback, useEffect, useMemo, useRef } from 'react';
import { useLocation } from 'wouter';
import { useShallow } from 'zustand/react/shallow';
import {
Expand Down Expand Up @@ -80,6 +80,17 @@ function BookmarkAddEditDialog({ curFolderId, handleScroll }: Props) {
);
const { operation, url: bmUrl } = bookmarkOperation;
const [openDialog, dialogHandlers] = useDisclosure(false);
const titleInputRef = useRef<HTMLInputElement>(null);

const focusCaretAtTitleStart = () => {
const input = titleInputRef.current;
if (!input) {
return true; // fallback to default focus behavior
}
input.focus();
input.setSelectionRange(0, 0);
return false; // focus already handled; don't let base-ui override it
};
Comment thread
amitsingh-007 marked this conversation as resolved.

const { folderOptions, defaultFolderId } = useMemo(() => {
const decodedFolderList = getDecodedFolderList(folderList);
Expand Down Expand Up @@ -189,7 +200,11 @@ function BookmarkAddEditDialog({ curFolderId, handleScroll }: Props) {

return (
<Dialog open={openDialog} onOpenChange={closeDialog}>
<DialogContent className="sm:max-w-lg" onKeyDown={handleEscapeKey}>
<DialogContent
className="sm:max-w-lg"
initialFocus={focusCaretAtTitleStart}
onKeyDown={handleEscapeKey}
>
<DialogHeader>
<DialogTitle>{HEADING[operation]}</DialogTitle>
</DialogHeader>
Expand All @@ -208,6 +223,7 @@ function BookmarkAddEditDialog({ curFolderId, handleScroll }: Props) {
Title <span className="text-destructive">*</span>
</FieldLabel>
<Input
ref={titleInputRef}
data-testid="bookmark-title-input"
Comment thread
amitsingh-007 marked this conversation as resolved.
placeholder="Enter bookmark title"
value={field.state.value}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,26 @@ function BookmarksHeader({ onSearchChange, folderId }: Props) {
handleSave(folderId);
};

useHotkeys([
useHotkeys(
[
'mod+S',
(e) => {
e.preventDefault();
e.stopPropagation();
if (!disableSave) {
handleSaveClick();
}
},
[
'mod+S',
(e) => {
e.preventDefault();
e.stopPropagation();
// Skip when focus is inside a dialog (e.g. the add/edit bookmark
// form) so an in-progress edit isn't excluded from the saved snapshot.
if (document.activeElement?.closest('[role="dialog"]')) {
return;
}
if (!disableSave) {
handleSaveClick();
}
},
],
],
]);
[] // fire even when focus is inside an input
);
Comment thread
greptile-apps[bot] marked this conversation as resolved.

const onBackClick = () => {
if (isSaveButtonActive) {
Expand Down
41 changes: 41 additions & 0 deletions apps/extension/tests/specs/bookmarks.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,29 @@ test.describe('Bookmarks Panel', () => {
await expect(dialog).toBeHidden();
});

test('should focus the title input with caret at start when opening the edit modal', async ({
bookmarksPage,
}) => {
const panel = new BookmarksPanel(bookmarksPage);
await panel.ensureAtRoot();

const dialog = await panel.openEditBookmarkDialog(
TEST_BOOKMARKS.REACT_DOCS
);
const titleInput = dialog.getByTestId('bookmark-title-input');
await expect(titleInput).toHaveValue(TEST_BOOKMARKS.REACT_DOCS);
await expect(titleInput).toBeFocused();

const selection = await titleInput.evaluate((el) => ({
start: (el as HTMLInputElement).selectionStart,
end: (el as HTMLInputElement).selectionEnd,
}));
Comment thread
amitsingh-007 marked this conversation as resolved.
expect(selection.start).toBe(0);
expect(selection.end).toBe(0);

await panel.closeDialog();
});

test('should add and remove person tag from bookmark', async ({
bookmarksPage,
}) => {
Expand Down Expand Up @@ -420,4 +443,22 @@ test.describe('Bookmarks Panel', () => {

await panel.verifyFolderNotExists(folderName);
});

test('should save via Cmd+S while focus is in the search input', async ({
bookmarksPage,
}) => {
const panel = new BookmarksPanel(bookmarksPage);
await panel.ensureAtRoot();

// Create a pending change so the Save button is active
await panel.createFolder('Cmd S Save Test Folder');

const search = panel.getSearchInput();
await search.click();
await expect(search).toBeFocused();

await bookmarksPage.keyboard.press('ControlOrMeta+s');

await expect(bookmarksPage.getByText('Saved temporarily')).toBeVisible();
});
Comment thread
coderabbitai[bot] marked this conversation as resolved.
});