From d2953c7d9022f41931ae1c1cdaaf3f38a506a8f7 Mon Sep 17 00:00:00 2001
From: Sergey Linev <S.Linev@gsi.de>
Date: Fri, 12 Jun 2015 11:19:55 +0200
Subject: [PATCH] jsroot: introduce _make_request and _after_request properties

This makes possible to provide special handling for remote objects,
when not the whole object should be fetched to the GUI.
Also in _after_request function one could manipulate object
or just cache results for the next request

Use _after_request in the sniffer for StreamerInfo object to
avoid special handling in JSROOT

Signed-off-by: Bertrand Bellenot <bertrand.bellenot@cern.ch>
---
 etc/http/scripts/JSRootCore.js    |  2 +-
 etc/http/scripts/JSRootPainter.js | 34 +++++++++++++++++++++++--------
 net/http/src/TRootSniffer.cxx     | 23 ++++++++++++++++++++-
 3 files changed, 49 insertions(+), 10 deletions(-)

diff --git a/etc/http/scripts/JSRootCore.js b/etc/http/scripts/JSRootCore.js
index 3e6d547c1f2..0bec4885ab6 100644
--- a/etc/http/scripts/JSRootCore.js
+++ b/etc/http/scripts/JSRootCore.js
@@ -14,7 +14,7 @@
 
    JSROOT = {};
 
-   JSROOT.version = "dev 3/06/2015";
+   JSROOT.version = "dev 12/06/2015";
 
    JSROOT.source_dir = "";
    JSROOT.source_min = false;
diff --git a/etc/http/scripts/JSRootPainter.js b/etc/http/scripts/JSRootPainter.js
index 169234373dc..42f4a0fb751 100644
--- a/etc/http/scripts/JSRootPainter.js
+++ b/etc/http/scripts/JSRootPainter.js
@@ -8019,39 +8019,57 @@
 
       return null;
    }
+   
+   JSROOT.MarkAsStreamerInfo = function(h,item,obj) {
+      // this function used on THttpServer to mark streamer infos list 
+      // as fictional TStreamerInfoList class, which has special draw function
+      if ((obj!=null) && (obj['_typename']=='TList'))
+         obj['_typename'] = 'TStreamerInfoList';
+   }
 
    JSROOT.HierarchyPainter.prototype.GetOnlineItem = function(item, itemname, callback) {
       // method used to request object from the http server
 
-      var url = itemname, h_get = false, req = 'root.json.gz?compact=3';
+      var url = itemname, h_get = false, req = '';
 
       if (item != null) {
          var top = item;
          while ((top!=null) && (!('_online' in top))) top = top._parent;
          url = this.itemFullName(item, top);
+
          if ('_doing_expand' in item) {
             h_get = true;
             req  = 'h.json?compact=3';
          } else
-         if (item._kind.indexOf("ROOT.")!=0)
-            req = 'item.json.gz?compact=3';
+         if ('_make_request' in item) {
+            var func = JSROOT.findFunction(item['_make_request']);
+            if (typeof func == 'function') req = func(this, item);
+         }
+         
+         if ((req.length==0) && (item._kind.indexOf("ROOT.")!=0))
+           req = 'item.json.gz?compact=3';
       }
-
-      if ((itemname==null) && (item!=null) && ('_cached_draw_object' in this) && (req.indexOf("root.json.gz")==0)) {
+      
+      if ((itemname==null) && (item!=null) && ('_cached_draw_object' in this) && (req.length == 0)) {
          // special handling for drawGUI when cashed
          var obj = this['_cached_draw_object'];
          delete this['_cached_draw_object'];
          return JSROOT.CallBack(callback, item, obj);
       }
 
+      if (req.length == 0) req = 'root.json.gz?compact=3';
+      
       if (url.length > 0) url += "/";
       url += req;
+      
+      var pthis = this;
 
       var itemreq = JSROOT.NewHttpRequest(url, 'object', function(obj) {
 
-         if ((item != null) && (obj != null) && !h_get &&
-             (item._name === "StreamerInfo") && (obj['_typename'] === 'TList'))
-            obj['_typename'] = 'TStreamerInfoList';
+         if ('_after_request' in item) {
+            var func = JSROOT.findFunction(item['_after_request']);
+            if (typeof func == 'function') req = func(pthis, item, obj);
+         }
 
          JSROOT.CallBack(callback, item, obj);
       });
diff --git a/net/http/src/TRootSniffer.cxx b/net/http/src/TRootSniffer.cxx
index aa74669d11d..9bc547412f1 100644
--- a/net/http/src/TRootSniffer.cxx
+++ b/net/http/src/TRootSniffer.cxx
@@ -633,10 +633,30 @@ void TRootSniffer::ScanObjectMemebers(TRootSnifferScanRec &rec, TClass *cl,
 }
 
 //_____________________________________________________________________
-void TRootSniffer::ScanObjectProperties(TRootSnifferScanRec & /*rec*/, TObject * /*obj*/)
+void TRootSniffer::ScanObjectProperties(TRootSnifferScanRec &rec, TObject *obj)
 {
    // scans object properties
    // here such fields as _autoload or _icon properties depending on class or object name could be assigned
+   // By default properties, coded in the Class title are scanned
+
+   TClass* cl = obj ? obj->IsA() : 0;
+
+   const char* title = cl ? cl->GetTitle() : "";
+
+   const char* pos = strstr(title, "*JSROOT* ");
+   if (pos==0) return;
+
+   TUrl url;
+   url.SetOptions(pos+9);
+
+   const char* opt = url.GetValueFromOptions("_autoload");
+   if (opt!=0) rec.SetField("_autoload", opt);
+
+   opt = url.GetValueFromOptions("_make_request");
+   if (opt!=0) rec.SetField("_make_request", opt);
+
+   opt = url.GetValueFromOptions("_after_request");
+   if (opt!=0) rec.SetField("_after_request", opt);
 }
 
 //_____________________________________________________________________
@@ -818,6 +838,7 @@ void TRootSniffer::ScanRoot(TRootSnifferScanRec &rec)
          chld.SetField(item_prop_kind, "ROOT.TStreamerInfoList");
          chld.SetField(item_prop_title, "List of streamer infos for binary I/O");
          chld.SetField(item_prop_hidden, "true");
+         chld.SetField("_after_request", "JSROOT.MarkAsStreamerInfo");
       }
    }
 
-- 
GitLab