Skip to content

Commit

Permalink
feat: inspect page context and template state
Browse files Browse the repository at this point in the history
  • Loading branch information
weareoutman committed Oct 8, 2023
1 parent bc5c287 commit 7f311a1
Show file tree
Hide file tree
Showing 11 changed files with 165 additions and 11 deletions.
23 changes: 23 additions & 0 deletions src/hook/getContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
interface DLL {
(moduleId: "tYg3"): {
developHelper: {
getAllContextValues(options: {
tplContextId?: string;
}): Map<string, { value: unknown }>;
};
};
}

export function getContext(
tplContextId?: string
): Record<string, unknown> | null {
const { dll } = (window as unknown) as { dll?: DLL };
if (typeof dll === "function") {
return Object.fromEntries(
[...dll("tYg3").developHelper.getAllContextValues({ tplContextId })]
.map(([key, { value }]) => [key, value])
.sort(([k1], [k2]) => (k1 > k2 ? 1 : -1))
);
}
return null;
}
2 changes: 2 additions & 0 deletions src/hook/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { inspectElement, dismissInspections } from "./inspector";
import { emit } from "./emit";
import { overrideProps } from "./overrideProps";
import { restoreDehydrated } from "./dehydrate";
import { getContext } from "./getContext";

function injectHook(): void {
if (Object.prototype.hasOwnProperty.call(window, HOOK_NAME)) {
Expand All @@ -27,6 +28,7 @@ function injectHook(): void {
// Methods below are exposed to Brick Next itself, keep compatible.
emit,
restoreDehydrated,
getContext,
};

Object.defineProperty(hook, "pageHasBricks", {
Expand Down
29 changes: 24 additions & 5 deletions src/hook/traverse.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
DehydratedBrickInfo,
} from "../shared/interfaces";

customElements.define("your.awesome-tpl", class Tmp1 extends HTMLElement {});
customElements.define("your.tpl-awesome", class Tmp1 extends HTMLElement {});
customElements.define("your.inner-brick", class Tmp1 extends HTMLElement {});
customElements.define(
"your.awesome-provider",
Expand All @@ -16,6 +16,16 @@ customElements.define(
class Tmp1 extends HTMLElement {}
);

(global as any).dll = () => {
return {
developHelper: {
getAllContextValues() {
return new Map([["myState", "myStateValue"]]);
},
},
};
};

describe("traverse", () => {
beforeEach(() => {
const main = document.createElement("div");
Expand All @@ -30,7 +40,6 @@ describe("traverse", () => {

const BrickProto = {
constructor: {
// eslint-disable-next-line @typescript-eslint/camelcase
_dev_only_definedProperties: ["propA", "propB"],
},
};
Expand All @@ -48,12 +57,15 @@ describe("traverse", () => {
{
$$brick: {
element: Object.assign(Object.create(BrickProto), {
tagName: "YOUR.AWESOME-TPL",
tagName: "YOUR.TPL-AWESOME",
$$typeof: "custom-template",
propB: "b in tpl",
propA: "a in tpl",
id: "tpl-1",
$$eventListeners: [],
dataset: {
tplContextId: "tpl-context-1",
},
}),
},
children: [
Expand Down Expand Up @@ -142,7 +154,7 @@ describe("traverse", () => {
main: [
{
uid: 1,
tagName: "your.awesome-tpl",
tagName: "your.tpl-awesome",
invalid: false,
children: [
{
Expand Down Expand Up @@ -205,7 +217,7 @@ describe("traverse", () => {
repo: [],
};

expect(getBrickByUid(1).tagName).toBe("YOUR.AWESOME-TPL");
expect(getBrickByUid(1).tagName).toBe("YOUR.TPL-AWESOME");

expect(getBrickInfo(1)).toEqual({
info: {
Expand All @@ -217,6 +229,13 @@ describe("traverse", () => {
propB: "b in tpl",
},
events: [],
tplState: {
myState: {
$$brickNextDevtoolsDehydrated: {
type: "undefined",
},
},
},
},
repo: [],
});
Expand Down
16 changes: 15 additions & 1 deletion src/hook/traverse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import {
RichBrickData,
MountPointElement,
BrickNode,
BrickInfo,
} from "../shared/interfaces";
import { dehydrate } from "./dehydrate";
import { getContext } from "./getContext";

function isV3OrAbove(): boolean {
const { "brick-container": version } =
Expand Down Expand Up @@ -41,6 +43,7 @@ export function getBrickInfo(uid: number): DehydratedBrickInfo {
const nativeProperties: Record<string, any> = {};
let properties: Record<string, any> = {};
let events: [string, any][] = [];
let tplState: Record<string, unknown> | undefined;
const element = uidToBrick.get(uid);
if (element) {
if (element.id) {
Expand All @@ -52,6 +55,13 @@ export function getBrickInfo(uid: number): DehydratedBrickInfo {
if (element.slot) {
nativeProperties.slot = element.slot;
}
if (element.tagName.includes(".TPL-")) {
const tplContextId =
element.dataset[isV3OrAbove() ? "tplStateStoreId" : "tplContextId"];
if (tplContextId) {
tplState = getContext(tplContextId);
}
}
if (isBrickElement(element)) {
const props: string[] =
(element.constructor as BrickElementConstructor)
Expand All @@ -70,7 +80,11 @@ export function getBrickInfo(uid: number): DehydratedBrickInfo {
}
}
const repo: any[] = [];
const info = dehydrate({ nativeProperties, properties, events }, repo);
const originalInfo: BrickInfo = { nativeProperties, properties, events };
if (tplState) {
originalInfo.tplState = tplState;
}
const info = dehydrate(originalInfo, repo);
return { info, repo };
}

Expand Down
10 changes: 10 additions & 0 deletions src/panel/components/ContextPanel.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from "react";
import { shallow } from "enzyme";
import { ContextPanel } from "./ContextPanel";

describe("ContextPanel", () => {
it("should work", () => {
const wrapper = shallow(<ContextPanel />);
expect(wrapper.hasClass("context-panel")).toBe(true);
});
});
59 changes: 59 additions & 0 deletions src/panel/components/ContextPanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React from "react";
import { InspectContextSelector } from "./InspectContextSelector";
import { PanelSelector } from "./PanelSelector";
import { HOOK_NAME } from "../../shared/constants";
import { useEvalOptions } from "../libs/useEvalOptions";
import { PropList } from "./PropList";
import { Button, ButtonGroup, Tooltip } from "@blueprintjs/core";

export function ContextPanel(): React.ReactElement {
const [values, setValues] = React.useState<Record<string, unknown> | null>(
{}
);
const evalOptions = useEvalOptions();

const handleRefresh = React.useCallback(() => {
chrome.devtools.inspectedWindow.eval(
`window.${HOOK_NAME} && window.${HOOK_NAME}.getContext()`,
evalOptions,
function (result: Record<string, unknown>, error) {
// istanbul ignore if
if (error) {
console.error("getContext()", error);
setValues(null);
} else {
setValues(result);
}
}
);
}, [evalOptions]);

React.useEffect(() => {
handleRefresh();
}, [handleRefresh]);

return (
<div className="panel context-panel">
<div className="context-toolbar">
<div className="toolbar-group">
<InspectContextSelector />
<PanelSelector />
<ButtonGroup>
<Tooltip content="Refresh context" hoverOpenDelay={300}>
<Button icon="refresh" minimal onClick={handleRefresh} />
</Tooltip>
</ButtonGroup>
</div>
</div>
<div className="context-view source-code">
<div className="scroll-container">
{values ? (
<PropList list={values} />
) : (
<p className="error-message">Inspect context failed</p>
)}
</div>
</div>
</div>
);
}
15 changes: 12 additions & 3 deletions src/panel/components/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ import {
PANEL_CHANGE,
} from "../../shared/constants";
import { TransformationsContext } from "../libs/TransformationsContext";
import { Storage } from "../libs/Storage";
import { LocalJsonStorage, Storage } from "../libs/Storage";
import { hydrate } from "../libs/hydrate";
import { SelectedInspectContext } from "../libs/SelectedInspectContext";
import { ContextPanel } from "./ContextPanel";

let uniqueIdCounter = 0;
function getUniqueId(): number {
Expand All @@ -42,7 +43,7 @@ export function Layout(): React.ReactElement {
Record<number, Transformation[]>
>({ 0: [] });
const [logNumber, setLogNumber] = React.useState(
Storage.getItem("logNumber") ?? 50
LocalJsonStorage.getItem("logNumber") ?? 50
);
const [preserveLogs, savePreserveLogs] = React.useState(false);
const [inspectFrameIndex, setInspectFrameIndex] = React.useState<number>(
Expand Down Expand Up @@ -275,7 +276,13 @@ export function Layout(): React.ReactElement {
}
window.addEventListener("message", onMessage);
return (): void => window.removeEventListener("message", onMessage);
}, [inspectFrameIndex, selectedPanel, logNumber, setEvaluationsByFrameId]);
}, [
inspectFrameIndex,
selectedPanel,
logNumber,
setEvaluationsByFrameId,
getFrameIdByFrameIndex,
]);

React.useEffect(() => {
function onMessage(event: MessageEvent): void {
Expand Down Expand Up @@ -454,6 +461,8 @@ export function Layout(): React.ReactElement {
<TransformationsContext.Provider value={transformationsCtx}>
<TransformationsPanel />
</TransformationsContext.Provider>
) : selectedPanel === "Context" ? (
<ContextPanel />
) : (
<BricksPanel />
)}
Expand Down
2 changes: 1 addition & 1 deletion src/panel/components/PanelSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export function PanelSelector({
{
<HTMLSelect
value={selectedPanel}
options={["Bricks", "Evaluations", "Transformations"]}
options={["Bricks", "Context", "Evaluations", "Transformations"]}
onChange={handleChange}
minimal
/>
Expand Down
1 change: 1 addition & 0 deletions src/panel/components/PropView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const tagsToDisplay: [keyof BrickInfo, string][] = [
["nativeProperties", "native properties"],
["properties", "properties"],
["events", "events"],
["tplState", "template state"],
];

export function PropView(): React.ReactElement {
Expand Down
12 changes: 12 additions & 0 deletions src/panel/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ body {
box-sizing: border-box;
}

.context-panel,
.evaluations-panel,
.transformations-panel {
flex-direction: column;
Expand All @@ -74,6 +75,7 @@ body {
border-left: 1px solid var(--pane-border-color);
}

.context-toolbar,
.evaluations-toolbar,
.transformations-toolbar,
.tree-toolbar,
Expand Down Expand Up @@ -113,6 +115,7 @@ body {
}

.brick-tree,
.context-view,
.prop-view,
.table-view {
flex: 1 0 auto;
Expand All @@ -126,6 +129,10 @@ body {
height: 100%;
}

.context-view > .scroll-container {
padding: 10px 0;
}

.source-code {
font-family: Menlo, monospace;
}
Expand Down Expand Up @@ -279,3 +286,8 @@ body {
background-color: var(--root-bg-color);
border-bottom: 1px solid var(--pane-border-color);
}

.context-view > .scroll-container > .error-message {
color: #f5498b;
padding: 0 10px;
}
7 changes: 6 additions & 1 deletion src/shared/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export interface BrickInfo {
nativeProperties?: Record<string, any>;
properties?: Record<string, any>;
events?: [string, any][];
tplState?: Record<string, any>;
}

export type BrowserTheme = "dark" | "light";
Expand Down Expand Up @@ -124,4 +125,8 @@ export interface FrameData {
frameURL: string;
}

export type PanelType = "Bricks" | "Evaluations" | "Transformations";
export type PanelType =
| "Bricks"
| "Context"
| "Evaluations"
| "Transformations";

0 comments on commit 7f311a1

Please sign in to comment.