mirror of
https://github.com/mathuo/dockview
synced 2025-05-06 19:48:25 +00:00
feat: further enhance view events
This commit is contained in:
parent
0ef3df76f9
commit
ee22a08b2e
@ -1,5 +1,6 @@
|
|||||||
import { GridviewComponent } from '../../gridview/gridviewComponent';
|
import { GridviewComponent } from '../../gridview/gridviewComponent';
|
||||||
import { GridviewPanel } from '../../gridview/gridviewPanel';
|
import { GridviewPanel } from '../../gridview/gridviewPanel';
|
||||||
|
import { GroupChangeEvent, GroupChangeKind } from '../../groupview/groupview';
|
||||||
import { IFrameworkPart } from '../../panel/types';
|
import { IFrameworkPart } from '../../panel/types';
|
||||||
import { Orientation } from '../../splitview/core/splitview';
|
import { Orientation } from '../../splitview/core/splitview';
|
||||||
|
|
||||||
@ -276,4 +277,94 @@ describe('gridview', () => {
|
|||||||
|
|
||||||
disposable.dispose();
|
disposable.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('gridview events', () => {
|
||||||
|
gridview.layout(800, 400);
|
||||||
|
|
||||||
|
let events: GroupChangeEvent[] = [];
|
||||||
|
const disposable = gridview.onGridEvent((e) => events.push(e));
|
||||||
|
|
||||||
|
gridview.addPanel({
|
||||||
|
id: 'panel_1',
|
||||||
|
component: 'default',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(events).toEqual([
|
||||||
|
{
|
||||||
|
kind: GroupChangeKind.ADD_GROUP,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: GroupChangeKind.GROUP_ACTIVE,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
events = [];
|
||||||
|
|
||||||
|
gridview.addPanel({
|
||||||
|
id: 'panel_2',
|
||||||
|
component: 'default',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(events).toEqual([
|
||||||
|
{
|
||||||
|
kind: GroupChangeKind.ADD_GROUP,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: GroupChangeKind.GROUP_ACTIVE,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
events = [];
|
||||||
|
|
||||||
|
gridview.addPanel({
|
||||||
|
id: 'panel_3',
|
||||||
|
component: 'default',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(events).toEqual([
|
||||||
|
{
|
||||||
|
kind: GroupChangeKind.ADD_GROUP,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: GroupChangeKind.GROUP_ACTIVE,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
events = [];
|
||||||
|
|
||||||
|
const panel1 = gridview.getPanel('panel_1');
|
||||||
|
const panel2 = gridview.getPanel('panel_2');
|
||||||
|
const panel3 = gridview.getPanel('panel_3');
|
||||||
|
|
||||||
|
gridview.removePanel(panel2);
|
||||||
|
|
||||||
|
expect(events).toEqual([
|
||||||
|
{
|
||||||
|
kind: GroupChangeKind.REMOVE_GROUP,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
events = [];
|
||||||
|
|
||||||
|
gridview.removePanel(panel3);
|
||||||
|
expect(events).toEqual([
|
||||||
|
{
|
||||||
|
kind: GroupChangeKind.REMOVE_GROUP,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: GroupChangeKind.GROUP_ACTIVE,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
events = [];
|
||||||
|
|
||||||
|
gridview.removePanel(panel1);
|
||||||
|
|
||||||
|
expect(events).toEqual([
|
||||||
|
{
|
||||||
|
kind: GroupChangeKind.REMOVE_GROUP,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: GroupChangeKind.GROUP_ACTIVE,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
events = [];
|
||||||
|
|
||||||
|
disposable.dispose();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -9,12 +9,6 @@ export abstract class DragHandler extends CompositeDisposable {
|
|||||||
private readonly _onDragStart = new Emitter<void>();
|
private readonly _onDragStart = new Emitter<void>();
|
||||||
readonly onDragStart = this._onDragStart.event;
|
readonly onDragStart = this._onDragStart.event;
|
||||||
|
|
||||||
// private activeDrag: { id: string } | undefined;
|
|
||||||
|
|
||||||
// get isDragging() {
|
|
||||||
// return !!this.activeDrag;
|
|
||||||
// }
|
|
||||||
|
|
||||||
private disposable: IDisposable | undefined;
|
private disposable: IDisposable | undefined;
|
||||||
|
|
||||||
constructor(private readonly el: HTMLElement) {
|
constructor(private readonly el: HTMLElement) {
|
||||||
@ -39,14 +33,8 @@ export abstract class DragHandler extends CompositeDisposable {
|
|||||||
this.el.classList.add('dragged');
|
this.el.classList.add('dragged');
|
||||||
setTimeout(() => this.el.classList.remove('dragged'), 0);
|
setTimeout(() => this.el.classList.remove('dragged'), 0);
|
||||||
|
|
||||||
// this.activeDrag = this.getData();
|
|
||||||
this.disposable?.dispose();
|
this.disposable?.dispose();
|
||||||
this.disposable = this.getData();
|
this.disposable = this.getData();
|
||||||
|
|
||||||
// if (event.dataTransfer) {
|
|
||||||
// event.dataTransfer.setData(DATA_KEY, stringifiedData);
|
|
||||||
// event.dataTransfer.effectAllowed = 'move';
|
|
||||||
// }
|
|
||||||
}),
|
}),
|
||||||
addDisposableListener(this.el, 'dragend', (ev) => {
|
addDisposableListener(this.el, 'dragend', (ev) => {
|
||||||
for (const iframe of this.iframes) {
|
for (const iframe of this.iframes) {
|
||||||
@ -56,43 +44,6 @@ export abstract class DragHandler extends CompositeDisposable {
|
|||||||
|
|
||||||
this.disposable?.dispose();
|
this.disposable?.dispose();
|
||||||
this.disposable = undefined;
|
this.disposable = undefined;
|
||||||
|
|
||||||
// drop events fire before dragend so we can remove this safely
|
|
||||||
// LocalSelectionTransfer.getInstance().clearData(this.activeDrag);
|
|
||||||
// this.activeDrag = undefined;
|
|
||||||
}),
|
|
||||||
addDisposableListener(this.el, 'mousedown', (event) => {
|
|
||||||
if (event.defaultPrevented) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* TODO: alternative to stopPropagation
|
|
||||||
*
|
|
||||||
* I need to stop the event propagation here since otherwise it'll be intercepted by event handlers
|
|
||||||
* on the tabs-container. I cannot use event.preventDefault() since I need the on DragStart event to occur
|
|
||||||
*/
|
|
||||||
event.stopPropagation();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* //TODO mousedown focusing with draggable element (is there a better approach?)
|
|
||||||
*
|
|
||||||
* this mousedown event wants to focus the tab itself but if we call preventDefault()
|
|
||||||
* this would also prevent the dragStart event from firing. To get around this we propagate
|
|
||||||
* the onChanged event during the next tick of the event-loop, allowing the tab element to become
|
|
||||||
* focused on this tick and ensuring the dragstart event is not interrupted
|
|
||||||
*/
|
|
||||||
|
|
||||||
const oldFocus = focusedElement.element as HTMLElement;
|
|
||||||
setTimeout(() => {
|
|
||||||
oldFocus.focus();
|
|
||||||
// this._onChanged.fire({ kind: MouseEventKind.CLICK, event });
|
|
||||||
}, 0);
|
|
||||||
}),
|
|
||||||
addDisposableListener(this.el, 'contextmenu', (event) => {
|
|
||||||
// this._onChanged.fire({
|
|
||||||
// kind: MouseEventKind.CONTEXT_MENU,
|
|
||||||
// event,
|
|
||||||
// });
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -380,7 +380,7 @@ export class DockviewComponent
|
|||||||
|
|
||||||
this.gridview.layout(this.width, this.height);
|
this.gridview.layout(this.width, this.height);
|
||||||
|
|
||||||
this._onGridEvent.fire({ kind: GroupChangeKind.NEW_LAYOUT });
|
this._onGridEvent.fire({ kind: GroupChangeKind.LAYOUT_FROM_JSON });
|
||||||
}
|
}
|
||||||
|
|
||||||
async closeAllGroups(): Promise<boolean> {
|
async closeAllGroups(): Promise<boolean> {
|
||||||
|
@ -193,9 +193,9 @@ export abstract class BaseGrid<T extends IGridPanelView>
|
|||||||
protected doAddGroup(group: T, location: number[] = [0], size?: number) {
|
protected doAddGroup(group: T, location: number[] = [0], size?: number) {
|
||||||
this.gridview.addView(group, size ?? Sizing.Distribute, location);
|
this.gridview.addView(group, size ?? Sizing.Distribute, location);
|
||||||
|
|
||||||
this.doSetGroupActive(group);
|
|
||||||
|
|
||||||
this._onGridEvent.fire({ kind: GroupChangeKind.ADD_GROUP });
|
this._onGridEvent.fire({ kind: GroupChangeKind.ADD_GROUP });
|
||||||
|
|
||||||
|
this.doSetGroupActive(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected doRemoveGroup(
|
protected doRemoveGroup(
|
||||||
@ -215,12 +215,16 @@ export abstract class BaseGrid<T extends IGridPanelView>
|
|||||||
this._groups.delete(group.id);
|
this._groups.delete(group.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!options?.skipActive && this._groups.size > 0) {
|
|
||||||
this.doSetGroupActive(Array.from(this._groups.values())[0].value);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._onGridEvent.fire({ kind: GroupChangeKind.REMOVE_GROUP });
|
this._onGridEvent.fire({ kind: GroupChangeKind.REMOVE_GROUP });
|
||||||
|
|
||||||
|
if (!options?.skipActive && this._activeGroup === group) {
|
||||||
|
const groups = Array.from(this._groups.values());
|
||||||
|
|
||||||
|
this.doSetGroupActive(
|
||||||
|
groups.length > 0 ? groups[0].value : undefined
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return view as T;
|
return view as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,7 +232,7 @@ export abstract class BaseGrid<T extends IGridPanelView>
|
|||||||
return this._groups.get(id)?.value;
|
return this._groups.get(id)?.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public doSetGroupActive(group: T, skipFocus?: boolean) {
|
public doSetGroupActive(group: T | undefined, skipFocus?: boolean) {
|
||||||
if (this._activeGroup === group) {
|
if (this._activeGroup === group) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -238,17 +242,20 @@ export abstract class BaseGrid<T extends IGridPanelView>
|
|||||||
this._activeGroup.focus();
|
this._activeGroup.focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
group.setActive(true);
|
|
||||||
if (!skipFocus) {
|
if (group) {
|
||||||
group.focus();
|
group.setActive(true);
|
||||||
|
if (!skipFocus) {
|
||||||
|
group.focus();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this._activeGroup = group;
|
this._activeGroup = group;
|
||||||
|
|
||||||
|
this._onGridEvent.fire({ kind: GroupChangeKind.GROUP_ACTIVE });
|
||||||
}
|
}
|
||||||
|
|
||||||
public removeGroup(group: T) {
|
public removeGroup(group: T) {
|
||||||
if (group === this._activeGroup) {
|
|
||||||
this._activeGroup = undefined;
|
|
||||||
}
|
|
||||||
this.doRemoveGroup(group);
|
this.doRemoveGroup(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,7 +248,7 @@ export class GridviewComponent
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this._onGridEvent.fire({ kind: GroupChangeKind.NEW_LAYOUT });
|
this._onGridEvent.fire({ kind: GroupChangeKind.LAYOUT_FROM_JSON });
|
||||||
}
|
}
|
||||||
|
|
||||||
movePanel(
|
movePanel(
|
||||||
|
@ -27,11 +27,9 @@ export enum GroupChangeKind {
|
|||||||
//
|
//
|
||||||
ADD_PANEL = 'ADD_PANEL',
|
ADD_PANEL = 'ADD_PANEL',
|
||||||
REMOVE_PANEL = 'REMOVE_PANEL',
|
REMOVE_PANEL = 'REMOVE_PANEL',
|
||||||
PANEL_OPEN = 'PANEL_OPEN',
|
|
||||||
PANEL_CLOSE = 'PANEL_CLOSE',
|
|
||||||
PANEL_ACTIVE = 'PANEL_ACTIVE',
|
PANEL_ACTIVE = 'PANEL_ACTIVE',
|
||||||
//
|
//
|
||||||
NEW_LAYOUT = 'NEW_LAYOUT',
|
LAYOUT_FROM_JSON = 'LAYOUT_FROM_JSON',
|
||||||
LAYOUT = 'LAYOUT',
|
LAYOUT = 'LAYOUT',
|
||||||
//
|
//
|
||||||
PANEL_CREATED = 'PANEL_CREATED',
|
PANEL_CREATED = 'PANEL_CREATED',
|
||||||
|
59
packages/dockview/src/paneview/defaultPaneviewHeader.ts
Normal file
59
packages/dockview/src/paneview/defaultPaneviewHeader.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import { addDisposableListener } from '../events';
|
||||||
|
import { PaneviewPanelApiImpl } from '../api/paneviewPanelApi';
|
||||||
|
import { CompositeDisposable } from '../lifecycle';
|
||||||
|
import { PanelUpdateEvent } from '../panel/types';
|
||||||
|
import { IPaneHeaderPart, PanePanelInitParameter } from './paneviewPanel';
|
||||||
|
import { MutableDisposable } from '../lifecycle';
|
||||||
|
|
||||||
|
export class DefaultHeader
|
||||||
|
extends CompositeDisposable
|
||||||
|
implements IPaneHeaderPart
|
||||||
|
{
|
||||||
|
private readonly disposable = new MutableDisposable();
|
||||||
|
private readonly _element: HTMLElement;
|
||||||
|
private readonly _content: HTMLElement;
|
||||||
|
private readonly _expander: HTMLElement;
|
||||||
|
private apiRef: { api: PaneviewPanelApiImpl | null } = { api: null };
|
||||||
|
|
||||||
|
get element() {
|
||||||
|
return this._element;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this._element = document.createElement('div');
|
||||||
|
this.element.className = 'default-header';
|
||||||
|
|
||||||
|
this._content = document.createElement('span');
|
||||||
|
this._expander = document.createElement('a');
|
||||||
|
|
||||||
|
this.element.appendChild(this._content);
|
||||||
|
this.element.appendChild(this._expander);
|
||||||
|
|
||||||
|
this.addDisposables(
|
||||||
|
addDisposableListener(this._expander, 'click', () => {
|
||||||
|
this.apiRef.api?.setExpanded(!this.apiRef.api.isExpanded);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
init(params: PanePanelInitParameter & { api: PaneviewPanelApiImpl }) {
|
||||||
|
this.apiRef.api = params.api;
|
||||||
|
|
||||||
|
this._content.textContent = params.title;
|
||||||
|
this._expander.textContent = params.api.isExpanded ? '<' : '>';
|
||||||
|
|
||||||
|
this.disposable.value = params.api.onDidExpansionChange((e) => {
|
||||||
|
this._expander.textContent = e.isExpanded ? '<' : '>';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
update(params: PanelUpdateEvent) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
dispose() {
|
||||||
|
this.disposable.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
}
|
@ -58,7 +58,6 @@ export abstract class DraggablePaneviewPanel extends PaneviewPanel {
|
|||||||
private initDragFeatures() {
|
private initDragFeatures() {
|
||||||
const id = this.id;
|
const id = this.id;
|
||||||
this.header!.draggable = true;
|
this.header!.draggable = true;
|
||||||
this.header!.tabIndex = 0;
|
|
||||||
|
|
||||||
this.handler = new (class PaneDragHandler extends DragHandler {
|
this.handler = new (class PaneDragHandler extends DragHandler {
|
||||||
getData(): IDisposable {
|
getData(): IDisposable {
|
||||||
|
@ -27,6 +27,12 @@
|
|||||||
.default-header {
|
.default-header {
|
||||||
background-color: var(--dv-group-view-background-color);
|
background-color: var(--dv-group-view-background-color);
|
||||||
color: var(--dv-activegroup-visiblepanel-tab-color);
|
color: var(--dv-activegroup-visiblepanel-tab-color);
|
||||||
|
display: flex;
|
||||||
|
padding: 0px 8px;
|
||||||
|
|
||||||
|
> span {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
import { PaneviewApi } from '../api/component.api';
|
import { PaneviewApi } from '../api/component.api';
|
||||||
import { PaneviewPanelApiImpl } from '../api/paneviewPanelApi';
|
|
||||||
import { createComponent } from '../panel/componentFactory';
|
import { createComponent } from '../panel/componentFactory';
|
||||||
import { addDisposableListener, Emitter, Event } from '../events';
|
import { Emitter, Event } from '../events';
|
||||||
import {
|
import {
|
||||||
CompositeDisposable,
|
CompositeDisposable,
|
||||||
IDisposable,
|
IDisposable,
|
||||||
MutableDisposable,
|
MutableDisposable,
|
||||||
} from '../lifecycle';
|
} from '../lifecycle';
|
||||||
import { PanelUpdateEvent } from '../panel/types';
|
|
||||||
import {
|
import {
|
||||||
LayoutPriority,
|
LayoutPriority,
|
||||||
Orientation,
|
Orientation,
|
||||||
@ -19,13 +17,13 @@ import {
|
|||||||
IPaneBodyPart,
|
IPaneBodyPart,
|
||||||
IPaneHeaderPart,
|
IPaneHeaderPart,
|
||||||
PaneviewPanel,
|
PaneviewPanel,
|
||||||
PanePanelInitParameter,
|
|
||||||
IPaneviewPanel,
|
IPaneviewPanel,
|
||||||
} from './paneviewPanel';
|
} from './paneviewPanel';
|
||||||
import {
|
import {
|
||||||
DraggablePaneviewPanel,
|
DraggablePaneviewPanel,
|
||||||
PaneviewDropEvent2,
|
PaneviewDropEvent2,
|
||||||
} from './draggablePaneviewPanel';
|
} from './draggablePaneviewPanel';
|
||||||
|
import { DefaultHeader } from './defaultPaneviewHeader';
|
||||||
|
|
||||||
export interface SerializedPaneviewPanel {
|
export interface SerializedPaneviewPanel {
|
||||||
snap?: boolean;
|
snap?: boolean;
|
||||||
@ -49,36 +47,6 @@ export interface SerializedPaneview {
|
|||||||
views: SerializedPaneviewPanel[];
|
views: SerializedPaneviewPanel[];
|
||||||
}
|
}
|
||||||
|
|
||||||
class DefaultHeader extends CompositeDisposable implements IPaneHeaderPart {
|
|
||||||
private _element: HTMLElement;
|
|
||||||
private apiRef: { api: PaneviewPanelApiImpl | null } = { api: null };
|
|
||||||
|
|
||||||
get element() {
|
|
||||||
return this._element;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this._element = document.createElement('div');
|
|
||||||
this._element.className = 'default-header';
|
|
||||||
|
|
||||||
this.addDisposables(
|
|
||||||
addDisposableListener(this.element, 'click', () => {
|
|
||||||
this.apiRef.api?.setExpanded(!this.apiRef.api.isExpanded);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
init(params: PanePanelInitParameter & { api: PaneviewPanelApiImpl }) {
|
|
||||||
this.apiRef.api = params.api;
|
|
||||||
this._element.textContent = params.title;
|
|
||||||
}
|
|
||||||
|
|
||||||
update(params: PanelUpdateEvent) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class PaneFramework extends DraggablePaneviewPanel {
|
export class PaneFramework extends DraggablePaneviewPanel {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly options: {
|
private readonly options: {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { PaneviewApi } from '../api/component.api';
|
import { PaneviewApi } from '../api/component.api';
|
||||||
import { PaneviewPanelApiImpl } from '../api/paneviewPanelApi';
|
import { PaneviewPanelApiImpl } from '../api/paneviewPanelApi';
|
||||||
|
import { addClasses, removeClasses } from '../dom';
|
||||||
import { addDisposableListener, Emitter, Event } from '../events';
|
import { addDisposableListener, Emitter, Event } from '../events';
|
||||||
import {
|
import {
|
||||||
BasePanelView,
|
BasePanelView,
|
||||||
@ -180,6 +181,16 @@ export abstract class PaneviewPanel
|
|||||||
this.api._onDidExpansionChange.fire({
|
this.api._onDidExpansionChange.fire({
|
||||||
isExpanded: isPanelExpanded,
|
isExpanded: isPanelExpanded,
|
||||||
});
|
});
|
||||||
|
}),
|
||||||
|
this.api.onDidFocusChange((e) => {
|
||||||
|
if (!this.header) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (e.isFocused) {
|
||||||
|
addClasses(this.header, 'focused');
|
||||||
|
} else {
|
||||||
|
removeClasses(this.header, 'focused');
|
||||||
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -270,7 +281,7 @@ export abstract class PaneviewPanel
|
|||||||
|
|
||||||
private renderOnce() {
|
private renderOnce() {
|
||||||
this.header = document.createElement('div');
|
this.header = document.createElement('div');
|
||||||
this.header.tabIndex = -1;
|
this.header.tabIndex = 0;
|
||||||
|
|
||||||
this.header.className = 'pane-header';
|
this.header.className = 'pane-header';
|
||||||
this.header.style.height = `${this.headerSize}px`;
|
this.header.style.height = `${this.headerSize}px`;
|
||||||
@ -281,7 +292,6 @@ export abstract class PaneviewPanel
|
|||||||
this.element.appendChild(this.header);
|
this.element.appendChild(this.header);
|
||||||
|
|
||||||
this.body = document.createElement('div');
|
this.body = document.createElement('div');
|
||||||
this.body.tabIndex = -1;
|
|
||||||
|
|
||||||
this.body.className = 'pane-body';
|
this.body.className = 'pane-body';
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user