Thibaut Colar avatar Thibaut Colar committed 99448e0

Reworked the helpPane to create a real html file to try to make windows/IE happy
Other helppane enhancements (slots links etc..)
bumped to 1.0.8

Comments (0)

Files changed (3)

src/brie/build.fan

                `fan/command/`,
                `fan/widget/`]
     resDirs = [`res/`]
-    version = Version("1.0.7")
+    version = Version("1.0.8")
     meta    =  ["license.name"   : "Academic License",
                 "vcs.uri"   : "https://bitbucket.org/tcolar/camembert"]
     docSrc  = true

src/brie/fan/command/Commands.fan

   override Void invoke(Event event)
   {
     selection := frame.curView?.curSelection ?: ""
-    frame.helpPane.showSearch(selection)
+    frame.helpPane.render(selection)
   }
   new make(|This| f) {f(this)}
 }

src/brie/fan/widget/HelpPane.fan

   private Frame frame
   private Sys sys
 
+  ** Unfortunately need to write html to a file rather than just in memory due to swt / IE bug
+  File file := File.createTemp("fan",".html").deleteOnExit
+
   new make(Frame frame)
   {
     this.frame = frame
         prefCols = 15
         onAction.add |Event e|
         {
-          showSearch(search.text)
+          render(search.text)
         }
       }
       top = GridPane
             if( ! pageHistory.isEmpty) pageHistory.pop()
             if( ! pageHistory.isEmpty)
             {
-              showPage(pageHistory.pop())
+              render(pageHistory.pop())
             }
           }
         },
         Button{image = gfx::Image(`fan://camembert/res/home.png`, false);
-        onAction.add |Event e| {showPage("")}},
+        onAction.add |Event e| {render("")}},
         search,
       }
       center = BorderPane
     {
       onHyperlink(e)
     }
-    showPage("")
+    render("")
   }
 
   Void updateSys(Sys newSys)
     sys = newSys
   }
 
-  internal Void onHyperlink(Event e)
-  {
-    uri := e.data.toStr
-    if(uri.contains("#goto:"))
-    {
-      // maybe support directly to a slot later (matchSlot)
-      info := sys.index.matchTypes(uri[uri.index("#goto:") + 6 .. -1], MatchKind.exact).first
-      if(info != null)
-        try{frame.goto(Item(info))}catch(Err err){}
-      e.data = null
-    }
-    if(uri.contains("://"))
-      return // let browser handle it
-    if(uri.startsWith(pageHistory.peek+"#"))
-      return // let browser handle it
-
-    showPage(uri)
-    e.data = null
-  }
-
-  internal Void showSearch(Str text)
-  {
-    if(browser == null)
-      return
-    if(visible == false)
-      show
-    if(text.contains("://"))
-    {
-      browser.load(text.toUri)
-      return
-    }
-    search.text = text.trim
-    pageHistory.clear
-    if(search.text.isEmpty)
-      showPage("")
-    else
-      browser.loadStr(find(search.text))
-  }
-
   private Void hide()
   {
     this.visible = false
   Void indexUpdated()
   {
     if(search.text.isEmpty)
-      showPage("")
+      render("")
   }
 
   Void toggle()
     }
   }
 
-  private Void showPage(Str uri)
+  ** Intercept hyperlinks so we can generate proper doc on the fly
+  internal Void onHyperlink(Event e)
   {
-    search.text = uri
-    if(browser==null)
+    uri := e.data.toStr
+    if(uri.contains("#goto:"))
+    {
+      // goto: special link to open a given type source file in the editor
+      // maybe support directly to a slot later (matchSlot)
+      info := sys.index.matchTypes(uri[uri.index("#goto:") + 6 .. -1], MatchKind.exact).first
+      if(info != null)
+        try{frame.goto(Item(info))}catch(Err err){}
+      e.data = null
       return
-    pageHistory.push(uri)
-    try
-      browser.loadStr(showDoc(uri))
-    catch(Err e) {e.trace}
+    }
+    if(uri.contains("://"))
+      return // standard web link, let browser handle it
+
+    render(uri)
+    e.data = null
   }
 
-  ** Search pods and types for items matching the query
-  private Str find(Str query, MatchKind kind := MatchKind.startsWith, Bool inclSlots := false)
+  ** Render a page for the given input text
+  ** such as "complier" -> search for items with names matching "compiler"
+  ** or "sys::Str" -> a type
+  ** or "sys::pod-doc" -> pod doc of sys
+  ** and so on
+  ** empty text returns the full pod list
+  internal Void render(Str text)
   {
-    if(query.isEmpty) {showPage(""); return ""}
-    index := sys.index
+    if(browser == null)
+      return
+    if(visible == false)
+      show
+    if(text.contains("://"))
+    {
+      browser.load(text.toUri)
+      return
+    }
+    text = text.trim
 
-    results := "<h2>Pods:</h2>"
-    index.matchPods(query, kind).each
+    search.text = text.trim
+
+    pageHistory.push(text)
+
+    if(text.isEmpty)
+      loadDoc(podList, "")
+    else if(text.contains("::"))
     {
-      results+="<a href='${it.name}::index'>$it</a> <br/>"
+      Str? anchor
+      if(text.contains("."))
+      {
+        anchor = text[text.index(".")+1 .. -1]
+        text = text[0 ..< text.index(".")] // remove slot
+      }
+      loadDoc(itemDoc(text), anchor == null ? "" : "#$anchor")
     }
-    results += "<h2>Types:</h2>"
-    index.matchTypes(query, kind).each
-    {
-      results+="<a href='${it.qname}'>$it.qname</a> <br/>"
-    }
-    if(! inclSlots)
-    {
-      results += "<h2>Slots:</h2>"
-      index.matchSlots(query, kind).each
-      {
-        results+="<a href='${it.type.qname}'>$it.qname</a> <br/>"
-      }
-    }
-
-    return results
+    else
+      loadDoc(find(text), "")
   }
 
-  ** Display doc for a qualified name: pod, type etc...
-  private Str showDoc(Str fqn)
+  ** Write to a file and then loads it in browser
+  ** as on windows/IE loadStr did not work properly
+  internal Void loadDoc(Str doc, Str anchor)
   {
-    if( fqn.isEmpty )
+    doc = "<html><body>$doc</body></html>"
+    file.create.open.print(doc).flush.close
+    dest := `${file.uri}$anchor`
+
+    browser.load(dest)
+  }
+
+  ** List all pods
+  Str podList()
+  {
+    Str pods := "<h2>Pod List</h2>"
+    sys.index.pods.each
     {
-      // home (pod list)
-      Str pods := "<h2>Pod List</h2>"
-      sys.index.pods.each
-      {
-        pods+="<a href='${it.name}::pod-doc'>$it.name</a> <br/>"
-      }
-      return pods
+      pods+="<a href='${it.name}::pod-doc'>$it.name</a> <br/>"
     }
-    if(fqn.contains("#"))
-    {
-      fqn = fqn[0 ..< fqn.index("#")] // remove anchor
-    }
+    return pods
+  }
+
+  ** Get doc for an item(pod, type etc..)
+  private Str itemDoc(Str fqn)
+  {
+    echo("itemDoc: $fqn")
     if(fqn.contains("::index")) fqn = fqn[0 ..< fqn.index("::")]
       if(fqn.contains("::pod-doc")) fqn = fqn[0 ..< fqn.index("::")]
       if(! fqn.contains("::"))
       text += readTypeDoc(info.pod.podFile, info.name)
       return text
     }
-    return ""
+  }
+
+  ** Search pods, types, slots for items matching the query
+  ** And returns a search result page
+  private Str find(Str query, MatchKind kind := MatchKind.startsWith, Bool inclSlots := false)
+  {
+    index := sys.index
+
+    results := "<h2>Pods:</h2>"
+    index.matchPods(query, kind).each
+    {
+      results+="<a href='${it.name}::index'>$it</a> <br/>"
+    }
+    results += "<h2>Types:</h2>"
+    index.matchTypes(query, kind).each
+    {
+      results+="<a href='${it.qname}'>$it.qname</a> <br/>"
+    }
+    if(! inclSlots)
+    {
+      results += "<h2>Slots:</h2>"
+      index.matchSlots(query, kind).each
+      {
+        results+="<a href='${it.type.qname}'>$it.qname</a> <br/>"
+      }
+    }
+
+    return results
   }
 
   ** Parse Fandoc into HTML
     return buf.flip.readAllStr
   }
 
+  ** Read doc of a pod
   private Str readPodDoc(File podFile)
   {
     result := "Failed to read pod doc !"
     return result
   }
 
+  ** Read doc of a type
   private Str readTypeDoc(File podFile, Str typeName)
   {
     result := "Failed to read pod doc !"
       result = summary
       if(type!=null)
       {
-        /*result="<hr/>Slots: "
+        result+="<hr/>Slots: "
         type.slots.each
         {
-          a:=anchor("#$it.name")
-          result += "<a href='$a'>$it.name</a>&nbsp"
-        }*/
-        result += "<div style='background-color:#ccccff'><b>Inheritance</b></div>"
+          result += "<a href='$it.qname'>$it.name</a>, "
+        }
+        result += "<hr/><div style='background-color:#ccccff'><b>Inheritance</b></div>"
         type.base.eachr{result += htmlType(it)+" - "}
         result += "<div style='background-color:#ccccff'><b>Local slots</b></div>"
         type.slots.each
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.