electron-dockable
Advanced tools
Comparing version 0.9.0 to 0.9.1
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 @@ |
'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
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
162517
41
3420
130
0
0
Updatedelectron-drag-drop@^1.0.3
Updatedelectron-panel@^1.3.8
Updatedelectron-profile@^1.0.4
Updatedelectron-window-plus@^1.3.4