From 3d6f69e05f90a52cd4897fb5b95bee0e912fc38c Mon Sep 17 00:00:00 2001
From: Jake Read <jake.read@cba.mit.edu>
Date: Tue, 10 Dec 2019 09:46:52 -0500
Subject: [PATCH] expand ok, now to try scope hierarchy

---
 LOG.md              | 10 +++++-
 core/scope.js       |  1 +
 hunks/view.js       | 76 ++++++++++++++++++++++++++--------------
 style.css           | 13 +++++++
 view/blocks.js      | 85 +++++++++++++++++++++++++++++++--------------
 view/contextmenu.js |  6 ++--
 6 files changed, 135 insertions(+), 56 deletions(-)

diff --git a/LOG.md b/LOG.md
index ae0d8e7..6db4714 100644
--- a/LOG.md
+++ b/LOG.md
@@ -1,5 +1,9 @@
 # Cuttlefish Dev Log / Scratch Notes
 
+### Dev Rebuilding 2019 12 10
+
+OK, kind of last day to pin this together. I think to start, I'll add that button back to the link, then try to run the 'expandlink' routine again. Then I can see about my two views, and how to assemble these layers. 
+
 ### Dev Rebuilding 2019 12 09
 
 I'm back up with the monster: reinstating systems. I think for big moves like this I want some brilliance in the display-of-current-state, and actions-to-be-taken.
@@ -8,7 +12,11 @@ I am also kind of doing this at a non-opportune time. I am trying to pinch it in
 
 That said, I have only really a few problems left so solve. This is the first one, the next is the hierarchy (at all) and then the third is the hierarchical moves (trace, build-route, and reinstate across hierarchy).
 
-The trouble with the log / output thing is that it assumes state as well - being out in some dialogue. This kind of means that we assume that we will always launch moves like this from ah place... Maybe that's just fine, make it brittle until it breaks. 
+The trouble with the log / output thing is that it assumes state as well - being out in some dialogue. This kind of means that we assume that we will always launch moves like this from ah place... Maybe that's just fine, make it brittle until it breaks.
+
+OK: as I suspected, getting through single-context system restore was not-problematic, until something really breaks. I should at least test it... ok, tried at least one other system. Sure.
+
+OK: here is where it becomes difficult. I used to just throw new views down, then connect them downstream, and run that hot mess that was the .GO ... so, I can imagine what I would do when I added new views previously, then could effectively retain view-match-to-hierarchy state within the top-level dom, now I need to track this more intentionally, yeah? IDK, I think I am over the ballmer peak. Ciao for today.
 
 ### Dev Rebuilding 2019 12 08
 
diff --git a/core/scope.js b/core/scope.js
index 24dc54d..7648496 100644
--- a/core/scope.js
+++ b/core/scope.js
@@ -20,6 +20,7 @@ export default function Scope(wrapper, tlv) {
   // toplevel scroll-around / playa
   let plane = $('<div>').addClass('plane').attr('id', 'NROLPLANE').get(0)
   // HEADS UP: need these / somehow
+  ok: I think we start by figuring how to navigate between views / scopes / links ... 
   tlv.plane = plane
   plane.handle = tlv
   let cs = 1 // our current scale
diff --git a/hunks/view.js b/hunks/view.js
index 69573e3..6f76cb5 100644
--- a/hunks/view.js
+++ b/hunks/view.js
@@ -134,7 +134,7 @@ function View() {
   this.hasDefPositionUpdate = false
   let setDefReposition = (index) => {
     this.hasDefPositionUpdate = true
-    if(defs[index]){
+    if (defs[index]) {
       defs[index].hasPositionUpdate = true
     } else {
       console.warn("position update flag set for nonexistent def")
@@ -841,7 +841,7 @@ function View() {
         interpreterVersion: this.interpreterVersion,
         hunks: []
       }
-      for(let df of defs){
+      for (let df of defs) {
         // want to scrape out just-the-necessary bits
         // proposal is to save minimum viable stuff
         let hnk = {
@@ -851,32 +851,32 @@ function View() {
           outputs: [],
           states: []
         }
-        for(let st of df.states){
+        for (let st of df.states) {
           hnk.states.push({
             name: st.name,
             type: st.type,
             value: st.value
           })
         }
-        for(let ip of df.inputs){
+        for (let ip of df.inputs) {
           hnk.inputs.push({
             name: ip.name,
             type: ip.type
           })
         }
-        for(let op of df.outputs){
+        for (let op of df.outputs) {
           let oph = {
             name: op.name,
             type: op.type,
             conn: []
           }
           // de-reference to indice-indice type,
-          for(let cn of op.conn){
+          for (let cn of op.conn) {
             oph.conn.push([parseInt(cn.parent.ind), parseInt(cn.ind)])
           }
           hnk.outputs.push(oph)
         }
-        if(df.position) hnk.position = df.position
+        if (df.position) hnk.position = df.position
         patch.hunks.push(hnk)
       }
       resolve(patch)
@@ -902,15 +902,15 @@ function View() {
         let spec = patch.hunks[n]
         let existing = defs[n]
         let result = null
-        if(existing !== undefined){
+        if (existing !== undefined) {
           // have one in this position already,
-          if(existing.type !== spec.type) reject('mismatched initial state')
-          for(let st in existing.states){
-            if(!spec.states[st]) break // existence check, type check ->
-            if((spec.states[st].type !== existing.states[st].type) || (spec.states[st].name !== existing.states[st].name)) continue
+          if (existing.type !== spec.type) reject('mismatched initial state')
+          for (let st in existing.states) {
+            if (!spec.states[st]) break // existence check, type check ->
+            if ((spec.states[st].type !== existing.states[st].type) || (spec.states[st].name !== existing.states[st].name)) continue
             // try to change, but continue nonetheless
             try {
-              if(debug) console.log(`hunkmerge, at ${n}, to swap in state ${st}`)
+              if (debug) console.log(`hunkmerge, at ${n}, to swap in state ${st}`)
               await this.requestStateChange(existing.states[st], spec.states[st].value)
             } catch (err) {
               console.error("couldn't swap ah state back to spec from this patch, continueing as is")
@@ -919,22 +919,22 @@ function View() {
           result = existing
         } else {
           // donot have one here yet, pls add it:
-          if(debug) console.log(`hunkmerge, at ${n}, to add new hunk ${spec.type}`)
+          if (debug) console.log(`hunkmerge, at ${n}, to add new hunk ${spec.type}`)
           await this.requestAddHunk(spec.type, spec.name, spec.states)
-          if(debug) console.log(`hunkmerge, at ${n}, def loaded, is ${defs[n].name}`)
+          if (debug) console.log(`hunkmerge, at ${n}, def loaded, is ${defs[n].name}`)
           loadedDefsList.push(defs[n])
           result = defs[n]
         }
         // ok, done w/ adding and states:
-        if(!result) reject(`something has gone wrong while merging hunks, see http://shrugguy.com for more info`)
-        if(spec.position) {
+        if (!result) reject(`something has gone wrong while merging hunks, see http://shrugguy.com for more info`)
+        if (spec.position) {
           result.position = {}
           result.position.x = parseInt(spec.position.x)
           result.position.y = parseInt(spec.position.y)
         }
         setDefReposition(n)
         // restore the position,
-        if((n ++) < nh - 1){
+        if ((n++) < nh - 1) {
           recursor(n++)
         } else {
           resolve(loadedDefsList)
@@ -950,18 +950,18 @@ function View() {
       let nh = patch.hunks.length
       let recursor = async (n) => {
         // we want to walk the list of outputs in the patch, and reconn.
-        for(let op in patch.hunks[n].outputs){
-          if(!defs[n].outputs[op]) break
-          for(let cn of patch.hunks[n].outputs[op].conn){
-            if(debug) console.log('mergeLinkList would like to conn', n, op, 'to', cn)
+        for (let op in patch.hunks[n].outputs) {
+          if (!defs[n].outputs[op]) break
+          for (let cn of patch.hunks[n].outputs[op].conn) {
+            if (debug) console.log('mergeLinkList would like to conn', n, op, 'to', cn)
             // now! we would like to see about whether / not this link already exist.
             // it's possible to double up wires, so let's try not to ...
             let existenceProof = defs[n].outputs[op].conn.find((cand) => {
               // recall: the candidate is ahn input, in this outputs' list of connections
               return ((cand.ind == cn[1]) && (cand.parent.ind == cn[0]))
             })
-            if(existenceProof){
-              if(debug) console.log('link exists, continueing')
+            if (existenceProof) {
+              if (debug) console.log('link exists, continueing')
               continue
             }
             // here is case to put error handling in the ll, at addlink,
@@ -973,8 +973,8 @@ function View() {
               console.error(err)
             }
           }
-        }// end for-each-output
-        if((n ++) < (nh - 1)){
+        } // end for-each-output
+        if ((n++) < (nh - 1)) {
           recursor(n++)
         } else {
           resolve()
@@ -1000,6 +1000,30 @@ function View() {
     })
   }
 
+  /* ---------------------------    ---------------------------- */
+  /* ------------------------- PIPING -------------------------- */
+  /* ---------------------------    ---------------------------- */
+
+  // for any link in any context, build some route up to
+  // some view that exists in the browser level
+  // and return ... ?
+  this.routelink = (link) => {
+    return new Promise(async (resolve, reject) => {
+      // *and* need to do some intelligent work to trace our way up to
+      // the top level view, where we would be able to instate a view ...
+      // *should* check if trace up exists, but basically:
+      try {
+        let view = await this.requestAddHunk('view')
+        console.log('view', view)
+        await this.requestAddLink(view.outputs[0], link.inputs[1])
+        await this.requestAddLink(link.inputs[1], view.outputs[0])
+        resolve(view)
+      } catch (err) {
+        reject(err)
+      }
+    })
+  }
+
   /* ---------------------------    ---------------------------- */
   /* --------------------- MESSAGES OUTPUT --------------------- */
   /* ---------------------------    ---------------------------- */
diff --git a/style.css b/style.css
index 12d409c..8c0ea3a 100644
--- a/style.css
+++ b/style.css
@@ -225,6 +225,19 @@ body {
 	background-color: #fff;
 }
 
+/* native elements, */
+.loosebutton{
+	position:absolute;
+	color: #fff;
+	background-color: #000;
+	padding: 5px;
+}
+
+.loosebutton:hover{
+	cursor: pointer;
+}
+
+/* depricated? much of this is... */
 .nativewrap {
 	position: absolute;
 	width: 500px; /* many sets with js */
diff --git a/view/blocks.js b/view/blocks.js
index ddfb220..c99f83e 100644
--- a/view/blocks.js
+++ b/view/blocks.js
@@ -192,7 +192,7 @@ let rebuildDef = (def, position) => {
   // need to make sure we have some position information before we draw
   if (!def.position) {
     if (position) {
-      def.position = {x: parseInt(position.x), y: parseInt(position.y)}
+      def.position = {x: position.x, y: position.y}
     } else {
       def.position = { x: 200, y: 200 }
     }
@@ -212,31 +212,6 @@ let rebuildDef = (def, position) => {
   def.block = titleblock
   def.blocks.push(titleblock)
 
-  // claim dom elements, global search
-  let native = $(def.context.plane).find('.hunk').toArray().find((cand) => {
-    return cand.handle.ind === def.ind
-  })
-  if (native) {
-    // issa block,
-    $(native).addClass('block')
-    // ok, I think I want to position this above everything else,
-    native.position = () => {
-      // this is more difficult, as we are looking @ the other blocks,
-      let y = 0
-      for (let bl of def.blocks) {
-        if ($(bl).is('.input') || $(bl).is('.output') || $(bl).is('.hunk')){
-          continue
-        } else {
-          y += bl.clientHeight + 5
-        }
-      }
-      return { x: 0, y: y }
-    }
-    // attach to title,
-    titleblock.take(native)
-    def.blocks.push(native)
-  }
-
   // build blocks for input objects,
   for (let i = 0; i < def.inputs.length; i++) {
     let inputdef = def.inputs[i]
@@ -282,6 +257,64 @@ let rebuildDef = (def, position) => {
     statedef.block = stateblock
     def.blocks.push(stateblock)
   }
+
+  // claim dom elements, global search
+  let native = $(def.context.plane).find('.hunk').toArray().find((cand) => {
+    return cand.handle.ind === def.ind
+  })
+  if (native) {
+    // issa block,
+    $(native).addClass('block')
+    // ok, I think I want to position this above everything else,
+    native.position = () => {
+      // this is more difficult, as we are looking @ the other blocks,
+      let y = 0
+      for (let bl of def.blocks) {
+        if ($(bl).is('.input') || $(bl).is('.output') || $(bl).is('.hunk')){
+          continue
+        } else {
+          y += bl.clientHeight + 5
+        }
+      }
+      return { x: 0, y: y }
+    }
+    // attach to title,
+    titleblock.take(native)
+    def.blocks.push(native)
+  }
+
+  // now the hairier work,
+  if(def.type == 'link'){
+    let squid = $('<div>').addClass('loosebutton').addClass('block').get(0)
+    squid.position = () => {
+      return {x: 0, y: - squid.clientHeight - 5}
+    }
+    squid.handle = def
+    titleblock.take(squid)
+    def.blocks.push(squid)
+    let open = (evt) =>{
+      // returns the view that connects to this link,
+      def.context.routelink(def).then((view) => {
+        console.log('route ok')
+        // we *do* want to walk these, so,
+        def.contains = view 
+        // toggle button state,
+        $(squid).html('<i class="em em-shell"></i> collapse link')
+        $(squid).one('click', close)
+      }).catch((err) => {
+        console.error(err)
+      })
+    }
+    let close = (evt) => {
+      console.error('not yet')
+      // . then->
+      $(squid).html('<i class="em em-squid"></i> expand link')
+      $(squid).one('click', open)
+    }
+    $(squid).html('<i class="em em-squid"></i> expand link')
+    $(squid).one('click', open)
+  }
+
 }
 
 // redraw all links connected to this block: inputs / outputs
diff --git a/view/contextmenu.js b/view/contextmenu.js
index 17f5f41..98b4239 100644
--- a/view/contextmenu.js
+++ b/view/contextmenu.js
@@ -425,12 +425,12 @@ function planeMenu(evt, context) {
             $(ce.target).closest('li').append(' > requested ... ')
             gg.getJson(`save/systems/${item}.json`).then((obj) => {
               // apparently, it's actually promises all the way down
-              // 2nd arg is debug state 
+              // 2nd arg is debug state
               context.reinstate(obj, true).then((yikes) => {
                 // trigger re-render? do we get heavy handed here and shut it down
                 // ... i.e. don't render anything until it's thru ?
-                console.warn('reinstate complete ? redraw ?')
-                fadeOut(500)
+                changeContextTitle("system restore OK ...")
+                fadeOut(1500)
               })
             }).catch((err) => {
               console.error("error while retrieving this patch")
-- 
GitLab