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
75 changes: 75 additions & 0 deletions src/pages/popup/App.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,81 @@ describe("Popup 输入型 GM 菜单(对齐 v1.4:菜单名按钮即提交)"
});
});

describe("Popup 菜单展开数量为 0 时的菜单位置", () => {
const menu = { key: "k1", name: "菜单命令", groupKey: "g1" };

function buttonTexts() {
return Array.from(document.querySelectorAll("button")).map((b) => b.textContent || "");
}

it("菜单展开数量为 0:展开脚本后,菜单排在「编辑」「脚本设置」之前", () => {
const script = makeScriptMenu({ uuid: "u1", menus: [menu] });
mockData = makeData({
scriptList: [script],
allScripts: [script],
fullScriptCount: 1,
enabledScriptCount: 1,
menuExpandNum: 0,
});

render(<App />);
// 未展开时不显示菜单
expect(screen.queryByText("菜单命令")).not.toBeInTheDocument();

fireEvent.click(screen.getByText("Script A").closest("button")!);

const texts = buttonTexts();
const menuIndex = texts.findIndex((s) => s.includes("菜单命令"));
const editIndex = texts.findIndex((s) => s.includes(t("edit")));
const settingIndex = texts.findIndex((s) => s.includes(t("editor:script_setting")));
expect(menuIndex).toBeGreaterThanOrEqual(0);
expect(menuIndex).toBeLessThan(editIndex);
expect(menuIndex).toBeLessThan(settingIndex);
});

it("菜单展开数量大于 0:菜单仍常驻在折叠区之外,位于「编辑」「脚本设置」之后", () => {
const script = makeScriptMenu({ uuid: "u1", menus: [menu] });
mockData = makeData({
scriptList: [script],
allScripts: [script],
fullScriptCount: 1,
enabledScriptCount: 1,
menuExpandNum: 5,
});

render(<App />);
expect(screen.getByText("菜单命令")).toBeInTheDocument();

fireEvent.click(screen.getByText("Script A").closest("button")!);

const texts = buttonTexts();
const menuIndex = texts.findIndex((s) => s.includes("菜单命令"));
const settingIndex = texts.findIndex((s) => s.includes(t("editor:script_setting")));
expect(settingIndex).toBeGreaterThanOrEqual(0);
expect(menuIndex).toBeGreaterThan(settingIndex);
});

it("负数菜单展开数量:保留原有行为显示全部菜单", () => {
const menus = [
{ key: "k1", name: "菜单命令 1", groupKey: "g1" },
{ key: "k2", name: "菜单命令 2", groupKey: "g2" },
];
const script = makeScriptMenu({ uuid: "u1", menus });
mockData = makeData({
scriptList: [script],
allScripts: [script],
fullScriptCount: 1,
enabledScriptCount: 1,
menuExpandNum: -1,
});

render(<App />);

expect(screen.getByText("菜单命令 1")).toBeInTheDocument();
expect(screen.getByText("菜单命令 2")).toBeInTheDocument();
});
});

describe("Popup 移动端宽度适配 (#686 Edge Android)", () => {
it("popup.html 通过媒体查询在移动端(视口 >360px)将宽度切换为 100%", () => {
const html = fs.readFileSync(path.join(process.cwd(), "src/pages/popup.html"), "utf8");
Expand Down
73 changes: 36 additions & 37 deletions src/pages/popup/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -512,13 +512,11 @@ function ScriptRow({
const allVisibleMenus = getVisibleMenuItems(script.menus);
const [isActive, setIsActive] = useState(false);
const [isMenuExpanded, setIsMenuExpanded] = useState(false);
// menuExpandNum=0 时跟随折叠面板状态;>0 时按数量截断
// menuExpandNum=0 时菜单移入折叠面板并排在编辑等操作项之前(菜单比操作项更常用);>0 时常驻行下方并按数量截断
const menusInCollapsible = menuExpandNum === 0;
const shouldTruncateMenus = menuExpandNum > 0 && allVisibleMenus.length > menuExpandNum;
const visibleMenus = (() => {
if (menuExpandNum === 0) return isActive ? allVisibleMenus : [];
if (shouldTruncateMenus && !isMenuExpanded) return allVisibleMenus.slice(0, menuExpandNum);
return allVisibleMenus;
})();
const visibleMenus =
shouldTruncateMenus && !isMenuExpanded ? allVisibleMenus.slice(0, menuExpandNum) : allVisibleMenus;
const excludeSite = showSiteScopeActions
? onExcludeFromMatch
? () => onExcludeFromMatch(script.uuid)
Expand All @@ -529,6 +527,35 @@ function ScriptRow({
const statusBadge = getStatusBadge(script, isPageScript, t);
const displayName = script.name;

const menuNodes = visibleMenus.map((menuItem) =>
menuItem.options?.inputType ? (
<InputMenuItem
key={menuItem.groupKey}
menuItem={menuItem}
allMenus={script.menus}
uuid={script.uuid}
onMenuClick={onMenuClick}
/>
) : (
<ActionItem
key={menuItem.groupKey}
icon={<MenuIcon className="w-3.5 h-3.5" />}
title={menuItem.options?.title}
onClick={() => {
const sameGroup = script.menus.filter((m) => m.groupKey === menuItem.groupKey && !m.options?.inputType);
onMenuClick(script.uuid, sameGroup);
}}
>
{menuItem.name}
{menuItem.options?.accessKey && (
<span className="ml-auto text-[10px] text-muted-foreground">
{`(${menuItem.options.accessKey.toUpperCase()})`}
</span>
)}
</ActionItem>
)
);

// 运行次数 tooltip
const runTitle = !script.enable
? t("script:script_disabled")
Expand Down Expand Up @@ -570,6 +597,7 @@ function ScriptRow({
{/* 折叠区域:操作按钮(点击展开) */}
<CollapsiblePrimitive.Content className="overflow-hidden data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down">
<div className={cn("flex flex-col gap-0.5", compact ? "pl-9 pr-3 pt-0.5 pb-1" : "pl-11 pr-4 pt-1 pb-2")}>
{menusInCollapsible && menuNodes}
{/* 运行/停止(仅后台脚本) */}
{!isPageScript && onRun && onStop && (
<>
Expand Down Expand Up @@ -632,38 +660,9 @@ function ScriptRow({
</CollapsiblePrimitive.Content>

{/* 始终可见区域:GM 菜单、用户配置(与旧版一致,不在折叠内) */}
{(visibleMenus.length > 0 || script.hasUserConfig) && (
{((!menusInCollapsible && visibleMenus.length > 0) || script.hasUserConfig) && (
<div className={cn("flex flex-col gap-0.5", compact ? "pl-9 pr-3 pb-0.5" : "pl-11 pr-4 pb-1")}>
{visibleMenus.map((menuItem) =>
menuItem.options?.inputType ? (
<InputMenuItem
key={menuItem.groupKey}
menuItem={menuItem}
allMenus={script.menus}
uuid={script.uuid}
onMenuClick={onMenuClick}
/>
) : (
<ActionItem
key={menuItem.groupKey}
icon={<MenuIcon className="w-3.5 h-3.5" />}
title={menuItem.options?.title}
onClick={() => {
const sameGroup = script.menus.filter(
(m) => m.groupKey === menuItem.groupKey && !m.options?.inputType
);
onMenuClick(script.uuid, sameGroup);
}}
>
{menuItem.name}
{menuItem.options?.accessKey && (
<span className="ml-auto text-[10px] text-muted-foreground">
{`(${menuItem.options.accessKey.toUpperCase()})`}
</span>
)}
</ActionItem>
)
)}
{!menusInCollapsible && menuNodes}
{/* 菜单展开/收起 */}
{shouldTruncateMenus && (
<button
Expand Down
Loading