fix: order menu items before filtering excess separators (#25563)

This commit is contained in:
Samuel Attard 2020-09-23 10:39:08 -07:00 committed by GitHub
parent a0b238a998
commit 3503d3745b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 15 deletions

View file

@ -157,9 +157,12 @@ function sortGroups<T> (groups: {id?: T}[][]) {
return sortedGroupIndexes.map(i => groups[i]); return sortedGroupIndexes.map(i => groups[i]);
} }
export function sortMenuItems (menuItems: {type?: string, id?: string}[]) { export function sortMenuItems (menuItems: (Electron.MenuItemConstructorOptions | Electron.MenuItem)[]) {
const isSeparator = (item: {type?: string}) => item.type === 'separator'; const isSeparator = (i: Electron.MenuItemConstructorOptions | Electron.MenuItem) => {
const separators = menuItems.filter(i => i.type === 'separator'); 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. // Split the items into their implicit groups based upon separators.
const groups = splitArray(menuItems, isSeparator); const groups = splitArray(menuItems, isSeparator);

View file

@ -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'); throw new TypeError('Invalid template for MenuItem: must have at least one of label, role or type');
} }
const filtered = removeExtraSeparators(template); const sorted = sortTemplate(template);
const sorted = sortTemplate(filtered); const filtered = removeExtraSeparators(sorted);
const menu = new Menu(); const menu = new Menu();
sorted.forEach(item => { filtered.forEach(item => {
if (item instanceof MenuItem) { if (item instanceof MenuItem) {
menu.append(item); menu.append(item);
} else { } else {

View file

@ -101,7 +101,7 @@ describe('Menu module', function () {
describe('Menu sorting and building', () => { describe('Menu sorting and building', () => {
describe('sorts groups', () => { describe('sorts groups', () => {
it('does a simple sort', () => { it('does a simple sort', () => {
const items = [ const items: Electron.MenuItemConstructorOptions[] = [
{ {
label: 'two', label: 'two',
id: '2', id: '2',
@ -146,7 +146,7 @@ describe('Menu module', function () {
}); });
it('resolves cycles by ignoring things that conflict', () => { it('resolves cycles by ignoring things that conflict', () => {
const items = [ const items: Electron.MenuItemConstructorOptions[] = [
{ {
id: '2', id: '2',
label: 'two', label: 'two',
@ -178,7 +178,7 @@ describe('Menu module', function () {
}); });
it('ignores references to commands that do not exist', () => { it('ignores references to commands that do not exist', () => {
const items = [ const items: Electron.MenuItemConstructorOptions[] = [
{ {
id: '1', id: '1',
label: 'one' label: 'one'
@ -208,7 +208,7 @@ describe('Menu module', function () {
}); });
it('only respects the first matching [before|after]GroupContaining rule in a given group', () => { it('only respects the first matching [before|after]GroupContaining rule in a given group', () => {
const items = [ const items: Electron.MenuItemConstructorOptions[] = [
{ {
id: '1', id: '1',
label: 'one' label: 'one'
@ -260,7 +260,7 @@ describe('Menu module', function () {
describe('moves an item to a different group by merging groups', () => { describe('moves an item to a different group by merging groups', () => {
it('can move a group of one item', () => { it('can move a group of one item', () => {
const items = [ const items: Electron.MenuItemConstructorOptions[] = [
{ {
id: '1', id: '1',
label: 'one' label: 'one'
@ -300,7 +300,7 @@ describe('Menu module', function () {
}); });
it("moves all items in the moving item's group", () => { it("moves all items in the moving item's group", () => {
const items = [ const items: Electron.MenuItemConstructorOptions[] = [
{ {
id: '1', id: '1',
label: 'one' label: 'one'
@ -348,7 +348,7 @@ describe('Menu module', function () {
}); });
it("ignores positions relative to commands that don't exist", () => { it("ignores positions relative to commands that don't exist", () => {
const items = [ const items: Electron.MenuItemConstructorOptions[] = [
{ {
id: '1', id: '1',
label: 'one' label: 'one'
@ -436,7 +436,7 @@ describe('Menu module', function () {
}); });
it('can merge multiple groups when given a list of before/after commands', () => { it('can merge multiple groups when given a list of before/after commands', () => {
const items = [ const items: Electron.MenuItemConstructorOptions[] = [
{ {
id: '1', id: '1',
label: 'one' label: 'one'
@ -474,7 +474,7 @@ describe('Menu module', function () {
}); });
it('can merge multiple groups based on both before/after commands', () => { it('can merge multiple groups based on both before/after commands', () => {
const items = [ const items: Electron.MenuItemConstructorOptions[] = [
{ {
id: '1', id: '1',
label: 'one' label: 'one'
@ -599,6 +599,32 @@ describe('Menu module', function () {
expect(menuTwo.items[2].label).to.equal('c'); 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', () => { it('should continue inserting items at next index when no specifier is present', () => {
const menu = Menu.buildFromTemplate([ const menu = Menu.buildFromTemplate([
{ {