diff --git a/components/http/http-raw-body.vue b/components/http/http-raw-body.vue index c2d009743..0df3ed5ef 100644 --- a/components/http/http-raw-body.vue +++ b/components/http/http-raw-body.vue @@ -29,18 +29,20 @@ - +
+ +
diff --git a/components/lenses/renderers/JSONLensRenderer.vue b/components/lenses/renderers/JSONLensRenderer.vue index 8273d3c42..18c0fcb9f 100644 --- a/components/lenses/renderers/JSONLensRenderer.vue +++ b/components/lenses/renderers/JSONLensRenderer.vue @@ -43,6 +43,7 @@ +
+
+
+ {{ p }} +
+ chevron_right +
+
+ {{ sib.key ? sib.key.value : i }} +
+
+
+

   
 
@@ -16,6 +34,61 @@
     @apply transition-none;
   }
 }
+
+.outline {
+  @apply flex;
+  @apply flex-no-wrap;
+  @apply w-full;
+  @apply overflow-auto;
+  @apply font-mono;
+  @apply shadow-lg;
+  @apply px-4;
+
+  .block {
+    @apply inline-flex;
+    @apply items-center;
+    @apply flex-grow-0;
+    @apply flex-shrink-0;
+    @apply text-fgLightColor;
+    @apply text-sm;
+
+    &:hover {
+      @apply text-fgColor;
+      @apply cursor-pointer;
+    }
+
+    .label {
+      @apply p-2;
+      @apply transition;
+      @apply ease-in-out;
+      @apply duration-150;
+    }
+
+    .siblings {
+      @apply absolute;
+      @apply z-50;
+      @apply top-9;
+      @apply bg-bgColor;
+      @apply max-h-60;
+      @apply overflow-auto;
+      @apply shadow-lg;
+      @apply text-fgLightColor;
+      @apply overscroll-none;
+
+      border-radius: 0 0 8px 8px;
+    }
+
+    .sib {
+      @apply px-4;
+      @apply py-1;
+
+      &:hover {
+        @apply text-fgColor;
+        @apply bg-bgLightColor;
+      }
+    }
+  }
+}
 
 
 
diff --git a/helpers/outline.js b/helpers/outline.js
new file mode 100644
index 000000000..3ea2ef91e
--- /dev/null
+++ b/helpers/outline.js
@@ -0,0 +1,126 @@
+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) {
+            let 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) {
+              let 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) => {
+    let 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,
+  }
+}