Skip to content

Commit

Permalink
feat: keep on looking for konva from devtool page, support multi stages
Browse files Browse the repository at this point in the history
fix: improve when long content display
  • Loading branch information
maitrungduc1410 committed Jun 7, 2023
1 parent 1711d1f commit b934e4c
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 70 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "konva-inspector",
"version": "0.0.8",
"version": "0.0.9",
"description": "Devtools for your Konva App",
"license": "MIT",
"repository": {
Expand Down
42 changes: 26 additions & 16 deletions src/pages/devtools/index.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
try {
chrome.devtools.inspectedWindow.eval(
`
!!(window.Konva && window.Konva.stages.length)
`,
(result, err) => {
if (result) {
chrome.devtools.panels.create(
"Konva",
"icon-34.png",
"src/pages/panel/index.html"
);
detectFromDevtool();

const detectFromDevtoolInterval = setInterval(detectFromDevtool, 1000);

function detectFromDevtool() {
try {
chrome.devtools.inspectedWindow.eval(
`
!!(window.Konva && window.Konva.stages.length)
`,
(result, err) => {
if (err) {
console.log(err);
} else if (result) {
clearInterval(detectFromDevtoolInterval);
chrome.devtools.panels.create(
"Konva",
"icon-34.png",
"src/pages/panel/index.html"
);
}
}
}
);
} catch (e) {
console.error(e);
);
} catch (e) {
clearInterval(detectFromDevtoolInterval);
console.error(e);
}
}
10 changes: 7 additions & 3 deletions src/pages/panel/components/Panel.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ body {
#app {
width: 100vw;
height: 100vh;
overflow: hidden;
}

.components {
Expand Down Expand Up @@ -120,7 +121,6 @@ body {
}

.tree-list {
overflow: auto;
flex: 0 0 65%;
border-top: 1px solid var(--color-border);
.search-input {
Expand Down Expand Up @@ -181,11 +181,13 @@ body {
}
}
}
.trees {
overflow-y: auto;
height: calc(100% - 42px - 3px); // add 3px as buffer for better scrollbar visibility
}
}
.inspected-element {
flex: 1 1 35%;
overflow-x: hidden;
overflow-y: auto;
border-left: 1px solid var(--color-border);
border-top: 1px solid var(--color-border);
.title-row {
Expand Down Expand Up @@ -222,6 +224,8 @@ body {
}

.inspected-element-data {
overflow-y: auto;
height: calc(100% - 42px - 3px); // add 3px as buffer for better scrollbar visibility
.header-row {
display: flex;
align-items: center;
Expand Down
61 changes: 29 additions & 32 deletions src/pages/panel/components/Panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,16 +65,9 @@ const Panel: React.FC = () => {
// handle always inspect
useEffect(() => {
if (alwaysInspect) {
// TODO: handle multi stages
// below we have && 1, to make the evaluation return a number
// otherwise it'll return a Stage instance and the bridge will fail
// we also check for window.__KONVA_DEVTOOLS_GLOBAL_HOOK__.Konva() is undefined or not to prevent the case when we reload at that time Konva is not initialized yet
bridge(`
window.__KONVA_DEVTOOLS_GLOBAL_HOOK__ &&
window.__KONVA_DEVTOOLS_GLOBAL_HOOK__.Konva() &&
window.__KONVA_DEVTOOLS_GLOBAL_HOOK__.Konva().stages[0].on("mouseover", window.__KONVA_DEVTOOLS_GLOBAL_HOOK__.selection.selectShapeAtCursor) &&
window.__KONVA_DEVTOOLS_GLOBAL_HOOK__.Konva().stages[0].on("click", window.__KONVA_DEVTOOLS_GLOBAL_HOOK__.selection.removeHoverToSelectListeners) && 1
`);
window.__KONVA_DEVTOOLS_GLOBAL_HOOK__.selection.registerMouseOverEvents()`);

const interval = setInterval(async () => {
getActiveNode();
Expand All @@ -83,16 +76,9 @@ const Panel: React.FC = () => {
return () => {
clearInterval(interval);

// TODO: handle multi stages
// below we need to assign result to a const
// otherwise it'll return a Stage instance and the bridge will fail
// we also check for window.__KONVA_DEVTOOLS_GLOBAL_HOOK__.Konva() is undefined or not to prevent the case when we reload at that time Konva is not initialized yet
bridge(`
window.__KONVA_DEVTOOLS_GLOBAL_HOOK__ &&
window.__KONVA_DEVTOOLS_GLOBAL_HOOK__.Konva() &&
window.__KONVA_DEVTOOLS_GLOBAL_HOOK__.Konva().stages[0].off("mouseover", window.__KONVA_DEVTOOLS_GLOBAL_HOOK__.selection.selectShapeAtCursor) &&
window.__KONVA_DEVTOOLS_GLOBAL_HOOK__.Konva().stages[0].off("click", window.__KONVA_DEVTOOLS_GLOBAL_HOOK__.selection.removeHoverToSelectListeners) && 1
`);
window.__KONVA_DEVTOOLS_GLOBAL_HOOK__.selection.unregisterMouseOverEvents()`);
};
}
}, [alwaysInspect]);
Expand Down Expand Up @@ -132,9 +118,13 @@ const Panel: React.FC = () => {
document.getElementById(data._id.toString()).scrollIntoView({
behavior: "smooth",
});
} else {
setAlwaysInspect(false);
}

const shouldAlwaysInspect = await bridge<boolean>(
`window.__KONVA_DEVTOOLS_GLOBAL_HOOK__ && window.__KONVA_DEVTOOLS_GLOBAL_HOOK__.selection.getAlwaysInspect()`
);

setAlwaysInspect(shouldAlwaysInspect);
};

const toggleTheme = (isDark: boolean) => {
Expand All @@ -157,7 +147,12 @@ const Panel: React.FC = () => {
<div className="v-rule"></div>
<button
className={alwaysInspect ? "toggle-on" : "toggle-off"}
onClick={() => setAlwaysInspect((cur) => !cur)}
onClick={() => {
setAlwaysInspect((cur) => !cur);
bridge(
`window.__KONVA_DEVTOOLS_GLOBAL_HOOK__ && window.__KONVA_DEVTOOLS_GLOBAL_HOOK__.selection.setAlwaysInspect(true)`
);
}}
>
<span className="toggle-content" tabIndex={-1}>
<ToggleOff />
Expand All @@ -180,19 +175,21 @@ const Panel: React.FC = () => {
</span>
</button>
</div>
{trees.map((item, index) => (
<div className="tree" key={`tree-${index}`}>
<Element
searchText={searchText}
selectedNode={selectedNode}
activeNode={activeNode}
stageIndex={index}
indent={0}
node={item}
onSelectNode={(data) => setSelectedNode(data)}
/>
</div>
))}
<div className="trees">
{trees.map((item, index) => (
<div className="tree" key={`tree-${index}`}>
<Element
searchText={searchText}
selectedNode={selectedNode}
activeNode={activeNode}
stageIndex={index}
indent={0}
node={item}
onSelectNode={(data) => setSelectedNode(data)}
/>
</div>
))}
</div>
</div>
<div className="inspected-element">
<InspectedElement selectedNode={selectedNode} />
Expand Down
4 changes: 4 additions & 0 deletions src/pages/panel/components/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ export const ATTRS = [
name: "scaleY",
type: "number",
},
{
name: "rotateEnabled",
type: "boolean",
},
{
name: "rotation",
type: "number",
Expand Down
70 changes: 52 additions & 18 deletions src/pages/panel/devtools/konvaDevtoolsSelection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { KonvaDevtools, OutlineNode } from "../types";
export default function konvaDevtoolsSelection(devtools: KonvaDevtools) {
let activeNode: Konva.Container;
let selectedNode: Konva.Container;
let alwaysInspect = false;

return {
active(serialize = false): Konva.Node | OutlineNode | undefined {
Expand Down Expand Up @@ -31,6 +32,8 @@ export default function konvaDevtoolsSelection(devtools: KonvaDevtools) {
) as Konva.Container;
activeNode = n;

// we need to clear before connect to make sure it works in case of multi stages
devtools.overlay.clear();
devtools.overlay.connect(stageIndex);
},
deactivate() {
Expand All @@ -40,31 +43,62 @@ export default function konvaDevtoolsSelection(devtools: KonvaDevtools) {
updateAttrs(attrs: any) {
selectedNode.setAttrs(attrs);
},
registerMouseOverEvents() {
// we check for window.__KONVA_DEVTOOLS_GLOBAL_HOOK__.Konva() is undefined or not to prevent the case when we reload at that time Konva is not initialized yet
if (devtools.Konva()) {
for (const stage of devtools.Konva().stages) {
stage.content.addEventListener(
"mouseleave",
devtools.selection.deactivateOnMouseLeaveWhenAlwaysInspect
);
stage.on("mouseover", devtools.selection.selectShapeAtCursor);
stage.on("click", devtools.selection.removeHoverToSelectListeners);
}
1; // add this line so that it'll be returned when evaluation, otherwise it'll throw error because the evaluation returns object class
}
},
unregisterMouseOverEvents() {
// we check for window.__KONVA_DEVTOOLS_GLOBAL_HOOK__.Konva() is undefined or not to prevent the case when we reload at that time Konva is not initialized yet
if (devtools.Konva()) {
for (const stage of devtools.Konva().stages) {
stage.content.removeEventListener(
"mouseleave",
devtools.selection.deactivateOnMouseLeaveWhenAlwaysInspect
);
stage.off("mouseover", devtools.selection.selectShapeAtCursor);
stage.off("click", devtools.selection.removeHoverToSelectListeners);
}
1; // add this line so that it'll be returned when evaluation, otherwise it'll throw error because the evaluation returns object class
}
},
deactivateOnMouseLeaveWhenAlwaysInspect(e) {
devtools.selection.deactivate();
},
selectShapeAtCursor() {
// TODO: handle multi stages
const stage = devtools.Konva().stages[0];
const pointerPosition = stage.getPointerPosition();
if (pointerPosition) {
const node = stage.getIntersection(pointerPosition);
if (node) {
devtools.selection.activate(node._id);
} else {
devtools.selection.deactivate();
for (const [index, stage] of devtools.Konva().stages.entries()) {
const pointerPosition = stage.getPointerPosition();
if (pointerPosition) {
const node = stage.getIntersection(pointerPosition);
if (node) {
devtools.selection.activate(node._id, index);
}
}
}
},
removeHoverToSelectListeners() {
if (!devtools) return;
devtools
.Konva()
.stages[0].off("mouseover", devtools.selection.selectShapeAtCursor);
devtools
.Konva()
.stages[0].off(
"click",
devtools.selection.removeHoverToSelectListeners
);
for (const stage of devtools.Konva().stages) {
stage.off("mouseover", devtools.selection.selectShapeAtCursor);
stage.off("click", devtools.selection.removeHoverToSelectListeners);
}
devtools.selection.deactivate();
devtools.selection.setAlwaysInspect(false);
},
setAlwaysInspect(value: boolean) {
alwaysInspect = value;
},
getAlwaysInspect() {
return alwaysInspect;
},
};
}

0 comments on commit b934e4c

Please sign in to comment.