Skip to content
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

fix: order menu items before filtering excess separators #25599

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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 6 additions & 3 deletions lib/browser/api/menu-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,12 @@ function sortGroups<T> (groups: {id?: T}[][]) {
return sortedGroupIndexes.map(i => groups[i]);
}

export function sortMenuItems (menuItems: {type?: string, id?: string}[]) {
const isSeparator = (item: {type?: string}) => item.type === 'separator';
const separators = menuItems.filter(i => i.type === 'separator');
export function sortMenuItems (menuItems: (Electron.MenuItemConstructorOptions | Electron.MenuItem)[]) {
const isSeparator = (i: Electron.MenuItemConstructorOptions | Electron.MenuItem) => {
const opts = i as Electron.MenuItemConstructorOptions;
return i.type === 'separator' && !opts.before && !opts.after && !opts.beforeGroupContaining && !opts.afterGroupContaining;
};
const separators = menuItems.filter(isSeparator);

// Split the items into their implicit groups based upon separators.
const groups = splitArray(menuItems, isSeparator);
Expand Down
6 changes: 3 additions & 3 deletions lib/browser/api/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,11 +182,11 @@ Menu.buildFromTemplate = function (template) {
throw new TypeError('Invalid template for MenuItem: must have at least one of label, role or type');
}

const filtered = removeExtraSeparators(template);
const sorted = sortTemplate(filtered);
const sorted = sortTemplate(template);
const filtered = removeExtraSeparators(sorted);

const menu = new Menu();
sorted.forEach(item => {
filtered.forEach(item => {
if (item instanceof MenuItem) {
menu.append(item);
} else {
Expand Down
44 changes: 35 additions & 9 deletions spec-main/api-menu-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ describe('Menu module', function () {
describe('Menu sorting and building', () => {
describe('sorts groups', () => {
it('does a simple sort', () => {
const items = [
const items: Electron.MenuItemConstructorOptions[] = [
{
label: 'two',
id: '2',
Expand Down Expand Up @@ -146,7 +146,7 @@ describe('Menu module', function () {
});

it('resolves cycles by ignoring things that conflict', () => {
const items = [
const items: Electron.MenuItemConstructorOptions[] = [
{
id: '2',
label: 'two',
Expand Down Expand Up @@ -178,7 +178,7 @@ describe('Menu module', function () {
});

it('ignores references to commands that do not exist', () => {
const items = [
const items: Electron.MenuItemConstructorOptions[] = [
{
id: '1',
label: 'one'
Expand Down Expand Up @@ -208,7 +208,7 @@ describe('Menu module', function () {
});

it('only respects the first matching [before|after]GroupContaining rule in a given group', () => {
const items = [
const items: Electron.MenuItemConstructorOptions[] = [
{
id: '1',
label: 'one'
Expand Down Expand Up @@ -260,7 +260,7 @@ describe('Menu module', function () {

describe('moves an item to a different group by merging groups', () => {
it('can move a group of one item', () => {
const items = [
const items: Electron.MenuItemConstructorOptions[] = [
{
id: '1',
label: 'one'
Expand Down Expand Up @@ -300,7 +300,7 @@ describe('Menu module', function () {
});

it("moves all items in the moving item's group", () => {
const items = [
const items: Electron.MenuItemConstructorOptions[] = [
{
id: '1',
label: 'one'
Expand Down Expand Up @@ -348,7 +348,7 @@ describe('Menu module', function () {
});

it("ignores positions relative to commands that don't exist", () => {
const items = [
const items: Electron.MenuItemConstructorOptions[] = [
{
id: '1',
label: 'one'
Expand Down Expand Up @@ -436,7 +436,7 @@ describe('Menu module', function () {
});

it('can merge multiple groups when given a list of before/after commands', () => {
const items = [
const items: Electron.MenuItemConstructorOptions[] = [
{
id: '1',
label: 'one'
Expand Down Expand Up @@ -474,7 +474,7 @@ describe('Menu module', function () {
});

it('can merge multiple groups based on both before/after commands', () => {
const items = [
const items: Electron.MenuItemConstructorOptions[] = [
{
id: '1',
label: 'one'
Expand Down Expand Up @@ -599,6 +599,32 @@ describe('Menu module', function () {
expect(menuTwo.items[2].label).to.equal('c');
});

it('should only filter excess menu separators AFTER the re-ordering for before/after is done', () => {
const menuOne = Menu.buildFromTemplate([
{
type: 'separator'
},
{
type: 'normal',
label: 'Foo',
id: 'foo'
},
{
type: 'normal',
label: 'Bar',
id: 'bar'
},
{
type: 'separator',
before: ['bar']
}]);

expect(menuOne.items).to.have.length(3);
expect(menuOne.items[0].label).to.equal('Foo');
expect(menuOne.items[1].type).to.equal('separator');
expect(menuOne.items[2].label).to.equal('Bar');
});

it('should continue inserting items at next index when no specifier is present', () => {
const menu = Menu.buildFromTemplate([
{
Expand Down