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
4 changes: 2 additions & 2 deletions dev/window/bwin-update-pane.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ document.querySelector('#update-pane').addEventListener('click', () => {
const content = document.querySelector('#content').value;

// Only pass fields the user actually filled in.
const props = { id };
const props = {};
if (position) props.position = position;
if (size) props.size = size;
if (title) props.title = title;
if (content) props.content = content;

bwin.updatePane(props);
bwin.updatePane(id, props);
});

window.bwin = bwin;
10 changes: 5 additions & 5 deletions src/binary-window/binary-window.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,18 @@ export class BinaryWindow extends Frame {
}

// TODO: support updating glass `actions` (rebuild the action bar/menu in place).
updatePane({ position, size, id, minWidth, minHeight, title, content }) {
const sash = this.rootSash.getById(id);
if (!sash) throw new Error(`[bwin] No sash found with id ${id} when updating pane`);
updatePane(paneSashId, { position, size, minWidth, minHeight, title, content } = {}) {
const sash = this.rootSash.getById(paneSashId);
if (!sash) throw new Error(`[bwin] No sash found with id ${paneSashId} when updating pane`);

if (position || size || minWidth || minHeight) {
super.updatePane(id, { position, size, minWidth, minHeight });
super.updatePane(paneSashId, { position, size, minWidth, minHeight });
}

if (title || content) {
const glassEl = sash.domNode.querySelector('bw-glass');
if (!glassEl)
throw new Error(`[bwin] No glass found in pane with id ${id} when updating pane`);
throw new Error(`[bwin] No glass found in pane with id ${paneSashId} when updating pane`);
updateGlass(glassEl, { title, content });
}
}
Expand Down
84 changes: 47 additions & 37 deletions src/binary-window/binary-window.test.js
Original file line number Diff line number Diff line change
@@ -1,56 +1,66 @@
import { describe, it, expect } from 'vitest';
import { normActions } from './utils';
import { DEFAULT_GLASS_ACTIONS } from './glass';
import { DEFAULT_DETACHED_GLASS_ACTIONS } from './detached-glass';

describe('normActions', () => {
it('returns the builtin actions when actions is undefined', () => {
expect(normActions(undefined)).toEqual([DEFAULT_GLASS_ACTIONS, DEFAULT_DETACHED_GLASS_ACTIONS]);
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { BinaryWindow } from './binary-window';

describe('BinaryWindow#updatePane', () => {
let containerEl;
let bwin;

beforeEach(() => {
containerEl = document.createElement('div');
document.body.append(containerEl);

bwin = new BinaryWindow({
width: 444,
height: 333,
children: [
{ position: 'left', size: '40%', id: 'a', title: 'a', content: 'Pane a' },
{ position: 'right', size: '60%', id: 'b', title: 'b', content: 'Pane b' },
],
});
bwin.mount(containerEl);
});

it('returns [[], []] when actions is null, empty, or not an array', () => {
expect(normActions(null)).toEqual([[], []]);
expect(normActions('a')).toEqual([[], []]);
expect(normActions({})).toEqual([[], []]);
expect(normActions([])).toEqual([[], []]);
afterEach(() => {
containerEl.remove();
});

it('returns [glassActions, DEFAULT_DETACHED_GLASS_ACTIONS] for a single grouped array', () => {
const a = { label: 'A' };
function getPaneEl(sashId) {
return bwin.windowElement.querySelector(`[sash-id="${sashId}"]`);
}

expect(normActions([[a]])).toEqual([[a], DEFAULT_DETACHED_GLASS_ACTIONS]);
});
it('takes the pane sash id as the first positional argument', () => {
bwin.updatePane('a', { title: 'updated a', content: 'updated content a' });

it('returns [actions, DEFAULT_DETACHED_GLASS_ACTIONS] when actions is a flat array', () => {
const a = { label: 'A' };
const b = { label: 'B' };
const titleEl = getPaneEl('a').querySelector('bw-glass-title');
const contentEl = getPaneEl('a').querySelector('bw-glass-content');

expect(normActions([a, b])).toEqual([[a, b], DEFAULT_DETACHED_GLASS_ACTIONS]);
expect(titleEl.textContent).toBe('updated a');
expect(contentEl.textContent).toBe('updated content a');
});

it('returns [[], detachedGlassActions] when first group is absent', () => {
const b = { label: 'B' };
it('updates only the targeted pane, leaving siblings untouched', () => {
bwin.updatePane('a', { title: 'updated a' });

expect(normActions([undefined, [b]])).toEqual([[], [b]]);
expect(normActions([null, [b]])).toEqual([[], [b]]);
expect(getPaneEl('a').querySelector('bw-glass-title').textContent).toBe('updated a');
expect(getPaneEl('b').querySelector('bw-glass-title').textContent).toBe('b');
});

it('returns [glassActions, []] when second group is absent', () => {
const a = { label: 'A' };
it('updates the pane size via the layout path', () => {
bwin.updatePane('a', { size: '20%' });

expect(normActions([[a], undefined])).toEqual([[a], []]);
expect(normActions([[a], null])).toEqual([[a], []]);
// The split is horizontal (left/right), so size maps to width.
const sashA = bwin.rootSash.getById('a');
const sashB = bwin.rootSash.getById('b');
expect(sashA.width).toBeLessThan(sashB.width);
});

it('returns actions as-is when both groups are arrays', () => {
const a = { label: 'A' };
const b = { label: 'B' };
const grouped = [[a], [b]];

expect(normActions(grouped)).toBe(grouped);
it('throws when no sash matches the given id', () => {
expect(() => bwin.updatePane('nope', { title: 'x' })).toThrow(
'[bwin] No sash found with id nope when updating pane'
);
});

it('throws when an array is present but neither of the first two slots is one', () => {
expect(() => normActions([null, null, []])).toThrow('[bwin] Invalid actions format');
it('does not require an options object', () => {
expect(() => bwin.updatePane('a')).not.toThrow();
});
});
56 changes: 56 additions & 0 deletions src/binary-window/utils.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { describe, it, expect } from 'vitest';
import { normActions } from './utils';
import { DEFAULT_GLASS_ACTIONS } from './glass';
import { DEFAULT_DETACHED_GLASS_ACTIONS } from './detached-glass';

describe('normActions', () => {
it('returns the builtin actions when actions is undefined', () => {
expect(normActions(undefined)).toEqual([DEFAULT_GLASS_ACTIONS, DEFAULT_DETACHED_GLASS_ACTIONS]);
});

it('returns [[], []] when actions is null, empty, or not an array', () => {
expect(normActions(null)).toEqual([[], []]);
expect(normActions('a')).toEqual([[], []]);
expect(normActions({})).toEqual([[], []]);
expect(normActions([])).toEqual([[], []]);
});

it('returns [glassActions, DEFAULT_DETACHED_GLASS_ACTIONS] for a single grouped array', () => {
const a = { label: 'A' };

expect(normActions([[a]])).toEqual([[a], DEFAULT_DETACHED_GLASS_ACTIONS]);
});

it('returns [actions, DEFAULT_DETACHED_GLASS_ACTIONS] when actions is a flat array', () => {
const a = { label: 'A' };
const b = { label: 'B' };

expect(normActions([a, b])).toEqual([[a, b], DEFAULT_DETACHED_GLASS_ACTIONS]);
});

it('returns [[], detachedGlassActions] when first group is absent', () => {
const b = { label: 'B' };

expect(normActions([undefined, [b]])).toEqual([[], [b]]);
expect(normActions([null, [b]])).toEqual([[], [b]]);
});

it('returns [glassActions, []] when second group is absent', () => {
const a = { label: 'A' };

expect(normActions([[a], undefined])).toEqual([[a], []]);
expect(normActions([[a], null])).toEqual([[a], []]);
});

it('returns actions as-is when both groups are arrays', () => {
const a = { label: 'A' };
const b = { label: 'B' };
const grouped = [[a], [b]];

expect(normActions(grouped)).toBe(grouped);
});

it('throws when an array is present but neither of the first two slots is one', () => {
expect(() => normActions([null, null, []])).toThrow('[bwin] Invalid actions format');
});
});