mirror of
https://github.com/AykutSarac/jsoncrack.com.git
synced 2025-01-12 19:02:53 +08:00
refactor: improve parser readability
This commit is contained in:
parent
cb9365156c
commit
ec871e5fec
@ -41,10 +41,16 @@ const StyledImage = styled.img`
|
||||
`;
|
||||
|
||||
const TextNode: React.FC<CustomNodeProps> = ({ node, x, y, hasCollapse = false }) => {
|
||||
const { id, text, width, height, data } = node;
|
||||
const {
|
||||
id,
|
||||
text,
|
||||
width,
|
||||
height,
|
||||
data: { isParent, childrenCount, type },
|
||||
} = node;
|
||||
const ref = React.useRef(null);
|
||||
const hideCollapse = useStored(state => state.hideCollapse);
|
||||
const childrenCount = useStored(state => state.childrenCount);
|
||||
const showChildrenCount = useStored(state => state.childrenCount);
|
||||
const imagePreview = useStored(state => state.imagePreview);
|
||||
const expandNodes = useGraph(state => state.expandNodes);
|
||||
const collapseNodes = useGraph(state => state.collapseNodes);
|
||||
@ -66,7 +72,7 @@ const TextNode: React.FC<CustomNodeProps> = ({ node, x, y, hasCollapse = false }
|
||||
height={height}
|
||||
x={0}
|
||||
y={0}
|
||||
hasCollapse={data.parent && hasCollapse}
|
||||
hasCollapse={isParent && hasCollapse}
|
||||
ref={ref}
|
||||
>
|
||||
{isImage ? (
|
||||
@ -75,21 +81,21 @@ const TextNode: React.FC<CustomNodeProps> = ({ node, x, y, hasCollapse = false }
|
||||
</StyledImageWrapper>
|
||||
) : (
|
||||
<StyledTextNodeWrapper
|
||||
hasCollapse={data.parent && hideCollapse}
|
||||
hasCollapse={isParent && hideCollapse}
|
||||
data-x={x}
|
||||
data-y={y}
|
||||
data-key={JSON.stringify(text)}
|
||||
>
|
||||
<Styled.StyledKey parent={data.parent}>
|
||||
<Styled.StyledKey parent={isParent} type={type}>
|
||||
<Styled.StyledLinkItUrl>
|
||||
{JSON.stringify(text).replaceAll('"', "")}
|
||||
</Styled.StyledLinkItUrl>
|
||||
</Styled.StyledKey>
|
||||
{data.parent && data.childrenCount > 0 && childrenCount && (
|
||||
<Styled.StyledChildrenCount>({data.childrenCount})</Styled.StyledChildrenCount>
|
||||
{isParent && childrenCount > 0 && showChildrenCount && (
|
||||
<Styled.StyledChildrenCount>({childrenCount})</Styled.StyledChildrenCount>
|
||||
)}
|
||||
|
||||
{data.parent && hasCollapse && hideCollapse && (
|
||||
{isParent && hasCollapse && hideCollapse && (
|
||||
<StyledExpand onClick={handleExpand}>
|
||||
{isExpanded ? <MdLinkOff size={18} /> : <MdLink size={18} />}
|
||||
</StyledExpand>
|
||||
|
@ -56,9 +56,9 @@ export const StyledForeignObject = styled.foreignObject<{
|
||||
}
|
||||
`;
|
||||
|
||||
function getKeyColor(theme: DefaultTheme, parent: "array" | "object" | false, objectKey: boolean) {
|
||||
function getKeyColor(theme: DefaultTheme, parent: boolean, type: string, objectKey: boolean) {
|
||||
if (parent) {
|
||||
if (parent === "array") return theme.NODE_COLORS.PARENT_ARR;
|
||||
if (type === "array") return theme.NODE_COLORS.PARENT_ARR;
|
||||
return theme.NODE_COLORS.PARENT_OBJ;
|
||||
}
|
||||
if (objectKey) return theme.NODE_COLORS.NODE_KEY;
|
||||
@ -67,13 +67,15 @@ function getKeyColor(theme: DefaultTheme, parent: "array" | "object" | false, ob
|
||||
|
||||
export const StyledKey = styled.span<{
|
||||
objectKey?: boolean;
|
||||
parent?: "array" | "object" | false;
|
||||
type: string;
|
||||
parent: boolean;
|
||||
value?: string;
|
||||
}>`
|
||||
display: inline;
|
||||
flex: 1;
|
||||
font-weight: 500;
|
||||
color: ${({ theme, objectKey = false, parent = false }) => getKeyColor(theme, parent, objectKey)};
|
||||
color: ${({ theme, type, objectKey = false, parent }) =>
|
||||
getKeyColor(theme, parent, type, objectKey)};
|
||||
font-size: ${({ parent }) => parent && "14px"};
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
@ -149,7 +149,6 @@ export const Sidebar: React.FC = () => {
|
||||
|
||||
const collapseGraph = useGraph(state => state.collapseGraph);
|
||||
const expandGraph = useGraph(state => state.expandGraph);
|
||||
const centerView = useGraph(state => state.centerView);
|
||||
const toggleFold = useGraph(state => state.toggleFold);
|
||||
const toggleFullscreen = useGraph(state => state.toggleFullscreen);
|
||||
|
||||
|
@ -112,7 +112,7 @@ const useGraph = create<Graph & GraphActions>((set, get) => ({
|
||||
.map(edge => edge.to);
|
||||
|
||||
const collapsedParents = get()
|
||||
.nodes.filter(node => !parentNodesIds.includes(node.id) && node.data.parent)
|
||||
.nodes.filter(node => !parentNodesIds.includes(node.id) && node.data.isParent)
|
||||
.map(node => node.id);
|
||||
|
||||
const collapsedNodes = get()
|
||||
|
2
src/typings/types.d.ts
vendored
2
src/typings/types.d.ts
vendored
@ -6,7 +6,7 @@ interface NodeData<T = any> {
|
||||
text?: any;
|
||||
height?: number;
|
||||
width?: number;
|
||||
parent?: string;
|
||||
isParent?: string;
|
||||
ports?: PortData[];
|
||||
icon?: IconData;
|
||||
nodePadding?: number | [number, number] | [number, number, number, number];
|
||||
|
@ -1,27 +1,32 @@
|
||||
import { calculateNodeSize } from "./calculateNodeSize";
|
||||
import { Graph } from "./jsonParser";
|
||||
|
||||
export const addNodeToGraph = (
|
||||
graph: Graph,
|
||||
text: any,
|
||||
width: number,
|
||||
height: number,
|
||||
parent: "string" | "number" | "boolean" | "object" | "array" | "null" | false,
|
||||
isEmpty?: boolean
|
||||
) => {
|
||||
let actualId = String(graph.nodes.length + 1);
|
||||
|
||||
graph.nodes = graph.nodes.concat([
|
||||
{
|
||||
id: actualId,
|
||||
text: text,
|
||||
width: width,
|
||||
height: height,
|
||||
data: {
|
||||
parent: parent === "array" || parent === "object" ? parent : false,
|
||||
childrenCount: parent ? 1 : 0,
|
||||
isEmpty: isEmpty,
|
||||
},
|
||||
},
|
||||
]);
|
||||
return actualId;
|
||||
type Props = {
|
||||
graph: Graph;
|
||||
text: any;
|
||||
isEmpty?: boolean;
|
||||
type?: "string" | "number" | "boolean" | "object" | "array" | "null";
|
||||
};
|
||||
|
||||
export const addNodeToGraph = ({ graph, text, type = "null", isEmpty = false }: Props) => {
|
||||
let id = String(graph.nodes.length + 1);
|
||||
const isParent = type === "array" || type === "object";
|
||||
const { width, height } = calculateNodeSize(text, isParent);
|
||||
|
||||
const node = {
|
||||
id,
|
||||
text,
|
||||
width,
|
||||
height,
|
||||
data: {
|
||||
type,
|
||||
isParent,
|
||||
isEmpty,
|
||||
childrenCount: isParent ? 1 : 0,
|
||||
},
|
||||
};
|
||||
|
||||
graph.nodes = graph.nodes.concat([node]);
|
||||
|
||||
return id;
|
||||
};
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { parseTree } from "jsonc-parser";
|
||||
import { addEdgeToGraph } from "./addEdgeToGraph";
|
||||
import { addNodeToGraph } from "./addNodeToGraph";
|
||||
import { calculateNodeSize } from "./calculateNodeSize";
|
||||
import { traverse } from "./traverse";
|
||||
|
||||
export type Graph = {
|
||||
@ -23,16 +22,16 @@ export type States = {
|
||||
parentId: string | undefined;
|
||||
objectsFromArrayId: number | undefined;
|
||||
}[];
|
||||
graph: {
|
||||
nodes: NodeData[];
|
||||
edges: EdgeData[];
|
||||
};
|
||||
};
|
||||
|
||||
export const parser = (jsonStr: string) => {
|
||||
try {
|
||||
let json = parseTree(jsonStr);
|
||||
|
||||
const graph: Graph = {
|
||||
nodes: [],
|
||||
edges: [],
|
||||
};
|
||||
if (!json) throw "Invalid JSON"!;
|
||||
|
||||
const states: States = {
|
||||
parentName: "",
|
||||
@ -44,36 +43,29 @@ export const parser = (jsonStr: string) => {
|
||||
brothersParentId: undefined,
|
||||
brotherKey: "",
|
||||
brothersNodeProps: [],
|
||||
graph: {
|
||||
nodes: [],
|
||||
edges: [],
|
||||
},
|
||||
};
|
||||
|
||||
if (json) {
|
||||
traverse(graph, states, json);
|
||||
traverse(states, json);
|
||||
|
||||
if (states.notHaveParent.length > 1) {
|
||||
if (json.type !== "array") {
|
||||
const text = "";
|
||||
const { width, height } = calculateNodeSize(text, false);
|
||||
const emptyId = addNodeToGraph(graph, text, width, height, false, true);
|
||||
states.notHaveParent.forEach(children => {
|
||||
addEdgeToGraph(graph, emptyId, children);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (graph.nodes.length === 0) {
|
||||
if (json.type === "array") {
|
||||
const text = "[]";
|
||||
const { width, height } = calculateNodeSize(text, false);
|
||||
addNodeToGraph(graph, text, width, height, false);
|
||||
} else {
|
||||
const text = "{}";
|
||||
const { width, height } = calculateNodeSize(text, false);
|
||||
addNodeToGraph(graph, text, width, height, false);
|
||||
}
|
||||
if (states.notHaveParent.length > 1) {
|
||||
if (json.type !== "array") {
|
||||
const emptyId = addNodeToGraph({ graph: states.graph, text: "", isEmpty: true });
|
||||
states.notHaveParent.forEach(children => {
|
||||
addEdgeToGraph(states.graph, emptyId, children);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return graph;
|
||||
if (states.graph.nodes.length === 0) {
|
||||
if (json.type === "array") addNodeToGraph({ graph: states.graph, text: "[]" });
|
||||
else addNodeToGraph({ graph: states.graph, text: "{}" });
|
||||
}
|
||||
|
||||
return states.graph;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return {
|
||||
|
@ -2,7 +2,7 @@ import { Node, NodeType } from "jsonc-parser";
|
||||
import { addEdgeToGraph } from "./addEdgeToGraph";
|
||||
import { addNodeToGraph } from "./addNodeToGraph";
|
||||
import { calculateNodeSize } from "./calculateNodeSize";
|
||||
import { Graph, States } from "./jsonParser";
|
||||
import { States } from "./jsonParser";
|
||||
|
||||
const isPrimitiveOrNullType = (type?: NodeType) => {
|
||||
return type === "boolean" || type === "string" || type === "number" || type === "null";
|
||||
@ -19,13 +19,13 @@ const alignChildren = (a: Node, b: Node) => {
|
||||
};
|
||||
|
||||
export const traverse = (
|
||||
graph: Graph,
|
||||
states: States,
|
||||
objectToTraverse: Node,
|
||||
parentType?: string,
|
||||
myParentId?: string,
|
||||
nextType?: string
|
||||
) => {
|
||||
const graph = states.graph;
|
||||
let { type, children, value } = objectToTraverse;
|
||||
|
||||
if (!children) {
|
||||
@ -39,8 +39,7 @@ export const traverse = (
|
||||
states.brotherKey = value;
|
||||
}
|
||||
} else if (parentType === "array") {
|
||||
const { width, height } = calculateNodeSize(String(value), false);
|
||||
const nodeFromArrayId = addNodeToGraph(graph, String(value), width, height, false);
|
||||
const nodeFromArrayId = addNodeToGraph({ graph, text: String(value) });
|
||||
if (myParentId) {
|
||||
addEdgeToGraph(graph, myParentId, nodeFromArrayId);
|
||||
}
|
||||
@ -77,8 +76,7 @@ export const traverse = (
|
||||
states.brothersNode = [];
|
||||
}
|
||||
} else {
|
||||
const { width, height } = calculateNodeSize(states.brothersNode, false);
|
||||
const brothersNodeId = addNodeToGraph(graph, states.brothersNode, width, height, false);
|
||||
const brothersNodeId = addNodeToGraph({ graph, text: states.brothersNode });
|
||||
states.brothersNode = [];
|
||||
|
||||
if (states.brothersParentId) {
|
||||
@ -99,9 +97,8 @@ export const traverse = (
|
||||
}
|
||||
|
||||
// add parent node
|
||||
const { width, height } = calculateNodeSize(states.parentName, true);
|
||||
parentId = addNodeToGraph(graph, states.parentName, width, height, type);
|
||||
states.bracketOpen = [...states.bracketOpen, { id: parentId, type: type }];
|
||||
parentId = addNodeToGraph({ graph, type, text: states.parentName });
|
||||
states.bracketOpen = [...states.bracketOpen, { id: parentId, type }];
|
||||
states.parentName = "";
|
||||
|
||||
// add edges from parent node
|
||||
@ -129,7 +126,6 @@ export const traverse = (
|
||||
(branch, index, array) => {
|
||||
if (array[index + 1]) {
|
||||
traverse(
|
||||
graph,
|
||||
states,
|
||||
branch,
|
||||
type,
|
||||
@ -140,7 +136,6 @@ export const traverse = (
|
||||
);
|
||||
} else {
|
||||
traverse(
|
||||
graph,
|
||||
states,
|
||||
branch,
|
||||
type,
|
||||
@ -154,7 +149,6 @@ export const traverse = (
|
||||
|
||||
if (type !== "property") {
|
||||
// when children end
|
||||
|
||||
// add or concat brothers node when it is the last parent node
|
||||
if (states.brothersNode.length > 0) {
|
||||
let findBrothersNode = states.brothersNodeProps.find(
|
||||
@ -175,8 +169,7 @@ export const traverse = (
|
||||
states.brothersNode = [];
|
||||
}
|
||||
} else {
|
||||
const { width, height } = calculateNodeSize(states.brothersNode, false);
|
||||
const brothersNodeId = addNodeToGraph(graph, states.brothersNode, width, height, false);
|
||||
const brothersNodeId = addNodeToGraph({ graph, text: states.brothersNode });
|
||||
states.brothersNode = [];
|
||||
|
||||
if (states.brothersParentId) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user