Socket
Socket
Sign inDemoInstall

electron-dockable

Package Overview
Dependencies
93
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.9.0 to 0.9.1

CHANGELOG.md

19

index.js
'use strict';
const platform = require('electron-platform');
const pkgJson = require('./package.json');
let dockable;
let name = `__electron_dockable__`;
let msg = `Failed to require ${pkgJson.name}@${pkgJson.version}:
A different version of ${pkgJson.name} already running in the process, we will redirect to it.
Please make sure your dependencies use the same version of ${pkgJson.name}.`;
if ( platform.isMainProcess ) {
dockable = require('./lib/main');
if (global[name]) {
console.warn(msg);
dockable = global[name];
} else {
dockable = global[name] = require('./lib/main');
}
} else {
dockable = require('./lib/renderer/index');
if (window[name]) {
console.warn(msg);
dockable = window[name];
} else {
dockable = window[name] = require('./lib/renderer/index');
}
}

@@ -12,0 +27,0 @@

31

lib/main.js
'use strict';
if ( global.__electron_dockable__ ) {
const pkgJson = require('../package.json');
console.warn(`A different version of electron-dockable already running in the process: ${pkgJson.version}, redirect to it. Please make sure your dependencies use the same version of electron-dockable.`);
module.exports = global.__electron_dockable__;
return;
}
const {BrowserWindow, shell} = require('electron');

@@ -82,8 +74,17 @@ const ipcPlus = require('electron-ipc-plus');

ipcPlus.on('electron-dockable:query-default-layout', ( event ) => {
if (_layout) {
event.reply(null, _layout);
return;
}
event.reply(new Error('No default layout found for this window'));
});
ipcPlus.on('electron-dockable:query-layout', ( event ) => {
let win = BrowserWindow.fromWebContents(event.sender);
let winInfo = windowPlus.getWinInfo(win);
let userdata = windowPlus.getUserData(win);
// if the window is not managed, return default layout;
if (!winInfo) {
if (!userdata) {
event.reply(null, _layout);

@@ -94,3 +95,3 @@ return;

// if we found the layout in the dockableWin, return it
let layout = winInfo.layout;
let layout = userdata.layout;
if ( layout ) {

@@ -109,1 +110,9 @@ event.reply(null, layout);

});
ipcPlus.on('electron-dockable:save-layout', ( event, info ) => {
let win = BrowserWindow.fromWebContents( event.sender );
windowPlus.updateUserData(win, {
layout: info
});
windowPlus.save();
});

@@ -264,3 +264,3 @@ 'use strict';

// re-add elements in this dock
// re-add elements in this dock
if ( position === 'left' || position === 'top' ) {

@@ -267,0 +267,0 @@ this.appendChild(incomingEL);

@@ -127,3 +127,2 @@ 'use strict';

this._inited = true;
this._layouting = false;

@@ -156,4 +155,2 @@ // init behaviors

reset ( layoutInfo ) {
this._layouting = true;
// 1: TODO: close all panel-frame in this dockarea.

@@ -199,3 +196,2 @@

this.finalize();
this._layouting = false;

@@ -218,2 +214,29 @@ // 5. save

/**
* @method dumpLayout
*/
dumpLayout () {
let childInfos = [];
let rect = this.getBoundingClientRect();
for ( let i = 0; i < this.children.length; ++i ) {
let childEL = this.children[i];
if ( !childEL.isDockable ) {
continue;
}
childInfos.push(childEL.dumpLayout());
}
let result = {
type: this.row ? 'dock-area-h' : 'dock-area-v',
width: rect.width,
height: rect.height,
children: childInfos,
};
return result;
}
_initResizers (force) {

@@ -220,0 +243,0 @@ if ( !force && this._resizerInited ) {

@@ -40,6 +40,3 @@ 'use strict';

position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
top: 0; right: 0; bottom: 0; left: 0;
}

@@ -196,2 +193,144 @@ `;

/**
* @method outOfDate
*/
outOfDate ( idxOrFrameEL ) {
let tabbar = this.$tabbar;
if ( typeof idxOrFrameEL === 'number' ) {
tabbar.outOfDate(idxOrFrameEL);
} else {
for ( let i = 0; i < this.children.length; ++i ) {
if ( idxOrFrameEL === this.children[i] ) {
tabbar.outOfDate(i);
break;
}
}
}
}
/**
* @method select
*/
select ( idxOrFrameEL ) {
let tabbar = this.$tabbar;
if ( typeof idxOrFrameEL === 'number' ) {
tabbar.select(idxOrFrameEL);
} else {
for ( let i = 0; i < this.children.length; ++i ) {
if ( idxOrFrameEL === this.children[i] ) {
tabbar.select(i);
break;
}
}
}
}
/**
* @method insert
*/
insert ( tabEL, frameEL, insertBeforeTabEL ) {
let tabbar = this.$tabbar;
tabbar.insertTab(tabEL, insertBeforeTabEL);
tabEL.setAttribute('draggable', 'true');
// NOTE: if we just move tabbar, we must not hide frameEL
if ( tabEL.parentNode !== tabbar ) {
frameEL.style.display = 'none';
}
tabEL.frameEL = frameEL;
// tabEL.setIcon( frameEL.icon );
//
if ( insertBeforeTabEL ) {
if ( frameEL !== insertBeforeTabEL.frameEL ) {
this.insertBefore(frameEL, insertBeforeTabEL.frameEL);
}
} else {
this.appendChild(frameEL);
}
//
this._calcMinMaxByFrames();
return utils.indexOf(tabEL);
}
/**
* @method add
*/
add ( frameEL ) {
let tabbar = this.$tabbar;
let name = frameEL.name;
let tabEL = tabbar.addTab(name);
tabEL.setAttribute('draggable', 'true');
frameEL.style.display = 'none';
tabEL.frameEL = frameEL;
// tabEL.setIcon( frameEL.icon );
this.appendChild(frameEL);
//
this._calcMinMaxByFrames();
//
return this.children.length - 1;
}
/**
* @method closeNoCollapse
*/
closeNoCollapse ( tabEL ) {
let tabbar = this.$tabbar;
//
tabbar.removeTab(tabEL);
if ( tabEL.frameEL ) {
let panelGroup = tabEL.frameEL.parentNode;
panelGroup.removeChild(tabEL.frameEL);
tabEL.frameEL = null;
}
//
this._calcMinMaxByFrames();
}
/**
* @method close
*/
close ( tabEL ) {
this.closeNoCollapse(tabEL);
this._collapse();
}
/**
* @method dumpLayout
*/
dumpLayout () {
let childInfos = [];
let rect = this.getBoundingClientRect();
for ( let i = 0; i < this.children.length; ++i ) {
let childEL = this.children[i];
childInfos.push({
id: childEL.id,
src: childEL.src,
});
}
let result = {
type: 'panel-group',
width: rect.width,
height: rect.height,
active: this.activeIndex,
children: childInfos,
};
return result;
}
_getFirstFocusableElement () {

@@ -250,3 +389,3 @@ return this;

tabEL.frameEL = frameEL;
tabEL.setIcon( frameEL.icon );
// tabEL.setIcon( frameEL.icon );
}

@@ -378,100 +517,2 @@ }

}
outOfDate ( idxOrFrameEL ) {
let tabbar = this.$tabbar;
if ( typeof idxOrFrameEL === 'number' ) {
tabbar.outOfDate(idxOrFrameEL);
} else {
for ( let i = 0; i < this.children.length; ++i ) {
if ( idxOrFrameEL === this.children[i] ) {
tabbar.outOfDate(i);
break;
}
}
}
}
select ( idxOrFrameEL ) {
let tabbar = this.$tabbar;
if ( typeof idxOrFrameEL === 'number' ) {
tabbar.select(idxOrFrameEL);
} else {
for ( let i = 0; i < this.children.length; ++i ) {
if ( idxOrFrameEL === this.children[i] ) {
tabbar.select(i);
break;
}
}
}
}
insert ( tabEL, frameEL, insertBeforeTabEL ) {
let tabbar = this.$tabbar;
tabbar.insertTab(tabEL, insertBeforeTabEL);
tabEL.setAttribute('draggable', 'true');
// NOTE: if we just move tabbar, we must not hide frameEL
if ( tabEL.parentNode !== tabbar ) {
frameEL.style.display = 'none';
}
tabEL.frameEL = frameEL;
tabEL.setIcon( frameEL.icon );
//
if ( insertBeforeTabEL ) {
if ( frameEL !== insertBeforeTabEL.frameEL ) {
this.insertBefore(frameEL, insertBeforeTabEL.frameEL);
}
} else {
this.appendChild(frameEL);
}
//
this._calcMinMaxByFrames();
return utils.indexOf(tabEL);
}
add ( frameEL ) {
let tabbar = this.$tabbar;
let name = frameEL.name;
let tabEL = tabbar.addTab(name);
tabEL.setAttribute('draggable', 'true');
frameEL.style.display = 'none';
tabEL.frameEL = frameEL;
tabEL.setIcon( frameEL.icon );
this.appendChild(frameEL);
//
this._calcMinMaxByFrames();
//
return this.children.length - 1;
}
closeNoCollapse ( tabEL ) {
let tabbar = this.$tabbar;
//
tabbar.removeTab(tabEL);
if ( tabEL.frameEL ) {
let panelGroup = tabEL.frameEL.parentNode;
panelGroup.removeChild(tabEL.frameEL);
tabEL.frameEL = null;
}
//
this._calcMinMaxByFrames();
}
close ( tabEL ) {
this.closeNoCollapse(tabEL);
this._collapse();
}
}

@@ -478,0 +519,0 @@

@@ -47,3 +47,3 @@ 'use strict';

margin: 0px 10px;
/* margin: 0px 10px; */
overflow: hidden;

@@ -54,2 +54,24 @@ white-space: nowrap;

.icon {
width: 16px;
height: 16px;
margin-left: 5px;
margin-right: 5px;
background-size: 16px;
}
.icon.type {
// visibility: hidden;
background: url("${__dirname}/../media/default-file.svg") center center no-repeat;
}
.icon.close {
visibility: hidden;
cursor: pointer;
background: url("${__dirname}/../media/close.svg") center center no-repeat;
}
:host(.active) {

@@ -71,2 +93,6 @@ background: #fff;

:host(:hover) .icon.close {
visibility: visible;
}
:host([out-of-date]),

@@ -98,4 +124,5 @@ :host(.active[out-of-date]) {

<div class="title">
<div id="icon"></div>
<div class="icon type"></div>
<span id="name"></span>
<div class="icon close"></div>
</div>

@@ -112,3 +139,4 @@ `;

this.$name = this.shadowRoot.querySelector('#name');
this.$icon = this.shadowRoot.querySelector('#icon');
this.$icon = this.shadowRoot.querySelector('.icon.type');
this.$close = this.shadowRoot.querySelector('.icon.close');
}

@@ -130,3 +158,5 @@

this.setIcon(null);
if (this.$close) {
this.$close.addEventListener('click', this._onClose.bind(this));
}
}

@@ -183,2 +213,15 @@

_onClose ( event ) {
event.stopPropagation();
if (this.frameEL) {
let closed = this.frameEL.close();
if ( closed ) {
this.dispatchEvent(new window.CustomEvent('tab-closed', {
bubbles: true
}));
}
}
}
// NOTE: there is a bug on css:hover for tab,

@@ -195,24 +238,24 @@ // when we drop tab 'foo' on top of tab 'bar' to insert before it,

setIcon ( img ) {
let iconEL = this.$icon;
// setIcon ( img ) {
// let iconEL = this.$icon;
if ( img ) {
iconEL.style.display = 'inline';
if ( iconEL.children.length ) {
iconEL.removeChild(iconEL.firstChild);
}
iconEL.appendChild(img);
// NOTE: this will prevent icon been dragged
img.setAttribute( 'draggable', 'false' );
// if ( img ) {
// iconEL.style.display = 'inline';
// if ( iconEL.children.length ) {
// iconEL.removeChild(iconEL.firstChild);
// }
// iconEL.appendChild(img);
// // NOTE: this will prevent icon been dragged
// img.setAttribute( 'draggable', 'false' );
return;
}
// return;
// }
iconEL.style.display = 'none';
if ( iconEL.children.length ) {
iconEL.removeChild(iconEL.firstChild);
}
}
// iconEL.style.display = 'none';
// if ( iconEL.children.length ) {
// iconEL.removeChild(iconEL.firstChild);
// }
// }
}
module.exports = Tab;

@@ -24,7 +24,7 @@ 'use strict';

align-items: center;
justify-content: flex-start;
height: 21px;
border-left: 1px solid black;
border-right: 1px solid black;
border-top: 1px solid black;
border-bottom: 1px solid black;
border: 1px solid black;

@@ -63,4 +63,8 @@ background: #656565;

.icon {
color: #777;
margin-left: 10px;
width: 16px;
height: 16px;
margin: 0px 5px;
cursor: pointer;
background-size: 16px;
}

@@ -72,6 +76,9 @@

.icon:hover {
color: #aaa;
cursor: pointer;
.icon.close {
background: url("${__dirname}/../media/close.svg") center center no-repeat;
}
.icon.menu {
background: url("${__dirname}/../media/ellipsis.svg") center center no-repeat;
}
`;

@@ -100,9 +107,4 @@

</div>
<div id="popup" class="icon">
<i class="icon-popup"></i>
</div>
<div id="menu" class="icon">
<i class="icon-menu"></i>
</div>
<div class="icon popup"></div>
<div class="icon menu"></div>
<div id="insertLine" class="insert"></div>

@@ -118,4 +120,4 @@ `;

// query element
this.$popup = this.shadowRoot.querySelector('#popup');
this.$menu = this.shadowRoot.querySelector('#menu');
this.$popup = this.shadowRoot.querySelector('.icon.popup');
this.$menu = this.shadowRoot.querySelector('.icon.menu');
this.$insertLine = this.shadowRoot.querySelector('#insertLine');

@@ -141,6 +143,12 @@ }

this.addEventListener('tab-click', this._onTabClick.bind(this));
this.addEventListener('tab-closed', this._onTabClosed.bind(this));
this.$popup.addEventListener('click', this._onPopup.bind(this));
this.$menu.addEventListener('click', this._onMenuPopup.bind(this));
if (this.$popup) {
this.$popup.addEventListener('click', this._onPopup.bind(this));
}
if (this.$menu) {
this.$menu.addEventListener('click', this._onMenuPopup.bind(this));
}
// init droppable

@@ -299,2 +307,7 @@ this.droppable = 'dockable-tab';

_onTabClosed ( event ) {
event.stopPropagation();
this.removeTab(event.target);
}
_onDropAreaEnter ( event ) {

@@ -301,0 +314,0 @@ event.stopPropagation();

@@ -5,3 +5,2 @@ 'use strict';

const {drag} = require('electron-drag-drop');
const ipcPlus = require('electron-ipc-plus');
const utils = require('../utils');

@@ -38,7 +37,10 @@ const DockArea = require('./dock-area');

utils.root = this; // DELME???
this._loadLayout(err => {
utils.loadLayout((err,layout) => {
if ( err ) {
console.error(`Failed to load layout: ${err.stack}`);
return;
}
this.reset(layout);
// TODO: use shadow root focus???

@@ -49,2 +51,5 @@ // FocusMgr._setFocusPanelFrame(null);

/**
* @method finalize
*/
finalize () {

@@ -55,2 +60,26 @@ super.finalize();

/**
* @method dumpLayout
*/
dumpLayout () {
let childInfos = [];
for ( let i = 0; i < this.children.length; ++i ) {
let childEL = this.children[i];
if ( !childEL.isDockable ) {
continue;
}
childInfos.push(childEL.dumpLayout());
}
let result = {
type: this.row ? 'dock-area-h' : 'dock-area-v',
children: childInfos,
};
return result;
}
_finalizeStyle () {

@@ -116,17 +145,4 @@ super._finalizeStyle();

}
_loadLayout ( cb ) {
ipcPlus.sendToMain('electron-dockable:query-layout', (err, layout) => {
if ( err ) {
if (cb) {
cb (err);
}
return;
}
this.reset(layout);
});
}
}
module.exports = Workspace;
'use strict';
if ( window.__electron_dockable__ ) {
const pkgJson = require('../../package.json');
console.warn(`A different version of electron-dockable already running in the process: ${pkgJson.version}, redirect to it. Please make sure your dependencies use the same version of electron-dockable.`);
module.exports = window.__electron_dockable__;
return;
}
const {ipcRenderer} = require('electron');

@@ -12,0 +4,0 @@ const utils = require('./utils');

@@ -24,3 +24,2 @@ 'use strict';

let _dragenterCnt = 0;
let _layouting = false;

@@ -583,9 +582,8 @@ // ==========================

utils.saveLayout = function () {
// don't save layout when we are layouting
if ( _layouting ) {
return;
}
window.requestAnimationFrame ( () => {
if ( !utils.root ) {
return;
}
window.requestAnimationFrame ( () => {
ipcPlus.sendToMain('electron-dockable:save-layout', utils.dumpLayout());
ipcPlus.sendToMain('electron-dockable:save-layout', utils.root.dumpLayout());
});

@@ -595,29 +593,13 @@ };

/**
* @method dumpLayout
*
* Dump the layout of the panels in current window
* @method loadLayout
*/
utils.dumpLayout = function () {
let root = utils.root;
if ( !root ) {
return null;
}
utils.loadLayout = function (cb) {
ipcPlus.sendToMain('electron-dockable:query-layout', cb);
};
if ( root.isDockable ) {
let type = root.row ? 'dock-h': 'dock-v';
return {
'type': type,
'children': _getDocks(root),
};
} else {
let id = root.getAttribute('id');
let rect = root.getBoundingClientRect();
return {
'type': 'standalone',
'panel': id,
'width': rect.width,
'height': rect.height,
};
}
/**
* @method loadDefaultLayout
*/
utils.loadDefaultLayout = function (cb) {
ipcPlus.sendToMain('electron-dockable:query-default-layout', cb);
};

@@ -734,46 +716,2 @@

function _getPanels ( panelGroup ) {
let panels = [];
for ( let i = 0; i < panelGroup.children.length; ++i ) {
let childEL = panelGroup.children[i];
let id = childEL.id;
panels.push(id);
}
return panels;
}
function _getDocks ( dockArea ) {
let docks = [];
for ( let i = 0; i < dockArea.children.length; ++i ) {
let childEL = dockArea.children[i];
if ( !childEL.isDockable ) {
continue;
}
let rect = childEL.getBoundingClientRect();
let info = {
'width': rect.width,
'height': rect.height,
};
if ( utils.isPanelGroup(childEL) ) {
info.type = 'panel-group';
info.active = childEL.activeIndex;
info.children = _getPanels(childEL);
} else {
let type = childEL.row ? 'dock-area-h': 'dock-area-v';
info.type = type;
info.children = _getDocks(childEL);
}
docks.push(info);
}
return docks;
}
function _updateMask ( type, x, y, w, h ) {

@@ -780,0 +718,0 @@ if ( !_dockMask ) {

{
"name": "electron-dockable",
"version": "0.9.0",
"version": "0.9.1",
"description": "Dockable ui framework for Electron",
"main": "index.js",
"scripts": {
"start": "node run.js",
"start": "electron",
"test": "mocha test/*.spec.js"

@@ -25,13 +25,13 @@ },

"dependencies": {
"electron-drag-drop": "^1.0.2",
"electron-drag-drop": "^1.0.3",
"electron-ipc-plus": "^1.3.3",
"electron-panel": "^1.3.2",
"electron-profile": "^1.0.1",
"electron-window-plus": "^1.2.1"
"electron-panel": "^1.3.8",
"electron-profile": "^1.0.4",
"electron-window-plus": "^1.3.4"
},
"devDependencies": {
"electron": "^1.6.1",
"electron": "^1.6.5",
"mocha": "^3.2.0",
"spectron": "^3.6.0"
"spectron": "^3.6.1"
}
}

@@ -12,3 +12,3 @@ # electron-dockable

- [ ] pop out and dock in a panel
- [ ] save and restore dock layout
- [x] save and restore dock layout
- [ ] ui-dock-toolbar

@@ -125,3 +125,4 @@ - [ ] ui-dock-panel (single panel, no tab-bar)

TODO
- TODO
- [Known Issues](./docs/known-issues.md)

@@ -128,0 +129,0 @@ ## License

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc