125 lines
3.2 KiB
JavaScript
125 lines
3.2 KiB
JavaScript
import jsonParse from "./jsonParse"
|
|
|
|
export default () => {
|
|
let jsonAST = {}
|
|
let path = []
|
|
|
|
const init = (jsonStr) => {
|
|
jsonAST = jsonParse(jsonStr)
|
|
linkParents(jsonAST)
|
|
}
|
|
|
|
const setNewText = (jsonStr) => {
|
|
init(jsonStr)
|
|
path = []
|
|
}
|
|
|
|
const linkParents = (node) => {
|
|
if (node.kind === "Object") {
|
|
if (node.members) {
|
|
node.members.forEach((m) => {
|
|
m.parent = node
|
|
linkParents(m)
|
|
})
|
|
}
|
|
} else if (node.kind === "Array") {
|
|
if (node.values) {
|
|
node.values.forEach((v) => {
|
|
v.parent = node
|
|
linkParents(v)
|
|
})
|
|
}
|
|
} else if (node.kind === "Member") {
|
|
if (node.value) {
|
|
node.value.parent = node
|
|
linkParents(node.value)
|
|
}
|
|
}
|
|
}
|
|
|
|
const genPath = (index) => {
|
|
let output = {}
|
|
path = []
|
|
let current = jsonAST
|
|
if (current.kind === "Object") {
|
|
path.push({ label: "{}", obj: "root" })
|
|
} else if (current.kind === "Array") {
|
|
path.push({ label: "[]", obj: "root" })
|
|
}
|
|
let over = false
|
|
|
|
try {
|
|
while (!over) {
|
|
if (current.kind === "Object") {
|
|
let i = 0
|
|
let found = false
|
|
while (i < current.members.length) {
|
|
const m = current.members[i]
|
|
if (m.start <= index && m.end >= index) {
|
|
path.push({ label: m.key.value, obj: m })
|
|
current = current.members[i]
|
|
found = true
|
|
break
|
|
}
|
|
i++
|
|
}
|
|
if (!found) over = true
|
|
} else if (current.kind === "Array") {
|
|
if (current.values) {
|
|
let i = 0
|
|
let found = false
|
|
while (i < current.values.length) {
|
|
const m = current.values[i]
|
|
if (m.start <= index && m.end >= index) {
|
|
path.push({ label: `[${i.toString()}]`, obj: m })
|
|
current = current.values[i]
|
|
found = true
|
|
break
|
|
}
|
|
i++
|
|
}
|
|
if (!found) over = true
|
|
} else over = true
|
|
} else if (current.kind === "Member") {
|
|
if (current.value) {
|
|
if (current.value.start <= index && current.value.end >= index) {
|
|
current = current.value
|
|
} else over = true
|
|
} else over = true
|
|
} else if (
|
|
current.kind === "String" ||
|
|
current.kind === "Number" ||
|
|
current.kind === "Boolean" ||
|
|
current.kind === "Null"
|
|
) {
|
|
if (current.start <= index && current.end >= index) {
|
|
path.push({ label: `${current.value}`, obj: current })
|
|
}
|
|
over = true
|
|
}
|
|
}
|
|
output = { success: true, res: path.map((p) => p.label) }
|
|
} catch (e) {
|
|
output = { success: false, res: e }
|
|
}
|
|
return output
|
|
}
|
|
|
|
const getSiblings = (index) => {
|
|
const parent = path[index]?.obj?.parent
|
|
if (!parent) return []
|
|
else if (parent.kind === "Object") {
|
|
return parent.members
|
|
} else if (parent.kind === "Array") {
|
|
return parent.values
|
|
} else return []
|
|
}
|
|
|
|
return {
|
|
init,
|
|
genPath,
|
|
getSiblings,
|
|
setNewText,
|
|
}
|
|
}
|