-
-
Notifications
You must be signed in to change notification settings - Fork 7
feat(DocView): bump dockview v4.4.0 #481
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
7c48c51
552026c
4282204
d5fbd53
db80d5f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -317,9 +317,25 @@ const saveConfig = dockview => { | |
| const json = dockview.toJSON(); | ||
| if (dockview.floatingGroups && dockview.floatingGroups.length > 0) { | ||
| json.floatingGroups.forEach((fg, index) => { | ||
| const width = dockview.floatingGroups[index].group.width | ||
| fg.position.width = fg.position.width || (width ? width + 2 : 300) | ||
| fg.position.height = fg.position.height || dockview.floatingGroups[index].group.height | ||
| const group = dockview.floatingGroups[index].group | ||
| if (fg.position.width > 0) { | ||
| group.panels.forEach(panel => { | ||
| !panel.params.currentPosition && (panel.params.currentPosition = {}) | ||
| panel.params.currentPosition.width = fg.position.width | ||
| }) | ||
| } | ||
| else { | ||
| fg.position.width = group.params.currentPosition.width || 500 | ||
|
Comment on lines
+321
to
+328
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue (bug_risk): Possible undefined 'group.params.currentPosition' access. Accessing 'width' or 'height' on an undefined 'currentPosition' will cause a runtime error. Please add a check to ensure 'currentPosition' is defined before accessing its properties. |
||
| } | ||
| if (fg.position.height > 0) { | ||
| group.panels.forEach(panel => { | ||
| !panel.params.currentPosition && (panel.params.currentPosition = {}) | ||
| panel.params.currentPosition.height = fg.position.height | ||
| }) | ||
| } | ||
| else { | ||
| fg.position.height = group.params.currentPosition.height || 350 | ||
| } | ||
| }) | ||
| } | ||
| localStorage.setItem(dockview.params.options.localStorageKey, JSON.stringify(json)); | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -167,6 +167,13 @@ const createGroupActions = (group, groupType) => { | |||||||||||||||||||||||||||||||
| if (item.name !== 'bar') { | ||||||||||||||||||||||||||||||||
| const icon = getIcon(item.name); | ||||||||||||||||||||||||||||||||
| actionContainer.append(icon); | ||||||||||||||||||||||||||||||||
| if(icon.classList.contains('bb-dockview-control-icon-dropdown')){ | ||||||||||||||||||||||||||||||||
| setTimeout(() => { | ||||||||||||||||||||||||||||||||
| if (group.model.location.type == 'floating' && group.panels.some(panel => panel.renderer == 'always')) { | ||||||||||||||||||||||||||||||||
| observeDisplayChange(icon, group) | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| }, 0) | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||
| setTimeout(() => { | ||||||||||||||||||||||||||||||||
|
|
@@ -178,13 +185,47 @@ const createGroupActions = (group, groupType) => { | |||||||||||||||||||||||||||||||
| }, 0) | ||||||||||||||||||||||||||||||||
| addActionEvent(group, actionContainer); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| const observeDisplayChange = (icon, group) => { | ||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue (complexity): Consider replacing the MutationObserver logic with Bootstrap dropdown event listeners and extracting the panel move logic into two helper functions. You can simplify/remove the MutationObserver boilerplate by listening to the dropdown’s built-in events (e.g. Bootstrap’s `show.bs.dropdown`/`hide.bs.dropdown`) and extracting the “portal” logic into two small helpers. This keeps the same functionality but is far more declarative and easier to follow.
```js
// 1) In createGroupActions, replace observeDisplayChange(…) with two event listeners:
if (icon.classList.contains('bb-dockview-control-icon-dropdown')) {
// bootstrap dropdown events
icon.addEventListener('show.bs.dropdown', () => portalPanelIntoDropdown(group));
icon.addEventListener('hide.bs.dropdown', () => restorePanelFromDropdown(group));
}// 2) Move all the move/unwrap logic into two focused functions:
function portalPanelIntoDropdown(group) {
const panelEle = group.activePanel.view.content.element;
const wrapper = panelEle.parentElement;
const container = group.element.querySelector(':scope > .dv-content-container');
// “portal” the panel into dropdown
wrapper.style.zIndex = '-1';
panelEle.__wrapper = wrapper; // temp link back to wrapper
container.appendChild(panelEle);
}
function restorePanelFromDropdown(group) {
const container = group.element.querySelector(':scope > .dv-content-container');
Array.from(container.children).forEach(child => {
const wrapper = child.__wrapper;
delete child.__wrapper;
// move child back into its original wrapper, reset z-index
wrapper.style.zIndex = '';
wrapper.appendChild(child);
});
// re-attach wrappers back into the dockview DOM
const panels = Array.from(group.element.querySelector(':scope > .dv-content-container').children)
.map(c => c.__wrapper);
group.element.parentElement.parentElement.append(...panels);
}Benefits:
|
||||||||||||||||||||||||||||||||
| const dockview = group.api.accessor | ||||||||||||||||||||||||||||||||
| const element = icon.querySelector('.dropdown-menu') | ||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue (bug_risk): Potential null reference if '.dropdown-menu' is not found. Add a null check for 'element' before creating the MutationObserver to prevent runtime errors. |
||||||||||||||||||||||||||||||||
| const mutationObserver = new MutationObserver((mutations) => { | ||||||||||||||||||||||||||||||||
| mutations.forEach(mutation => { | ||||||||||||||||||||||||||||||||
| if (mutation.attributeName == 'class') { | ||||||||||||||||||||||||||||||||
| if(mutation.target.classList.contains('show')) { | ||||||||||||||||||||||||||||||||
| const currentPanelEle = group.activePanel.view.content.element.parentElement | ||||||||||||||||||||||||||||||||
| const childEle = currentPanelEle.children[0] | ||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue (bug_risk): No check for existence of 'currentPanelEle' or its children. Accessing properties of a null 'currentPanelEle' or missing children will cause a runtime error. Please add null and existence checks before using these elements. |
||||||||||||||||||||||||||||||||
| group.element.querySelector('&>.dv-content-container').append(childEle) | ||||||||||||||||||||||||||||||||
| currentPanelEle.style.zIndex = -1 | ||||||||||||||||||||||||||||||||
| childEle.wrapperEle = currentPanelEle | ||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion (bug_risk): Attaching custom properties to DOM elements can cause memory leaks. Instead of assigning 'wrapperEle' directly to the DOM node, use a WeakMap or similar structure to store metadata and avoid potential memory leaks. |
||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| else { | ||||||||||||||||||||||||||||||||
| const panelEleList = [...group.element.querySelector('&>.dv-content-container').children].map(item => { | ||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue (bug_risk): Repeated use of non-standard selector '&>.dv-content-container'. This selector may not function as expected, which could cause 'panelEleList' to be empty or undefined and lead to errors. |
||||||||||||||||||||||||||||||||
| const wrapperEle = item.wrapperEle | ||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion (code-quality): Prefer object destructuring when accessing and using properties. (
Suggested change
ExplanationObject destructuring can often remove an unnecessary temporary reference, as well as making your code more succinct.From the Airbnb Javascript Style Guide |
||||||||||||||||||||||||||||||||
| delete item.wrapperEle | ||||||||||||||||||||||||||||||||
| wrapperEle.append(item) | ||||||||||||||||||||||||||||||||
| return wrapperEle | ||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||
| group.element.parentElement.parentElement.append(...panelEleList) | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||
| group.mutationObserver = mutationObserver | ||||||||||||||||||||||||||||||||
| mutationObserver.observe(element, { | ||||||||||||||||||||||||||||||||
| attributes: true, | ||||||||||||||||||||||||||||||||
| attributeFilter: ["class"], | ||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
Comment on lines
+213
to
+218
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion (bug_risk): Potential for multiple observers if 'observeDisplayChange' is called multiple times. Disconnect any existing observer before assigning a new one to prevent resource leaks.
Suggested change
|
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| const disposeGroup = group => { | ||||||||||||||||||||||||||||||||
| const { observer } = group.api.accessor.params; | ||||||||||||||||||||||||||||||||
| if (observer) { | ||||||||||||||||||||||||||||||||
| observer.unobserve(group.header.element); | ||||||||||||||||||||||||||||||||
| observer.unobserve(group.header.tabs._tabsList); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| if (group.mutationObserver) { | ||||||||||||||||||||||||||||||||
| group.mutationObserver.disconnect(); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| removeActionEvent(group); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (code-quality): Prefer object destructuring when accessing and using properties. (
use-object-destructuring)Explanation
Object destructuring can often remove an unnecessary temporary reference, as well as making your code more succinct.From the Airbnb Javascript Style Guide