From 6e4d5111220bf57dc3e4ad09281091fa7c17c93e Mon Sep 17 00:00:00 2001
From: Romain Courteaud <romain@nexedi.com>
Date: Tue, 11 Oct 2016 13:46:06 +0000
Subject: [PATCH] [erp5_web_renderjs_ui] Update renderjs to 0.11.0

---
 .../web_page_module/rjs_renderjs_js.js        | 230 ++++++++++++++++--
 .../web_page_module/rjs_renderjs_js.xml       |   4 +-
 2 files changed, 212 insertions(+), 22 deletions(-)

diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_renderjs_js.js b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_renderjs_js.js
index 1589e94ed9..3fb77fc53a 100644
--- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_renderjs_js.js
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_renderjs_js.js
@@ -689,6 +689,66 @@ if (typeof document.contains !== 'function') {
     });
   }
 
+  function loopEventListener(target, type, useCapture, callback,
+                             prevent_default) {
+    //////////////////////////
+    // Infinite event listener (promise is never resolved)
+    // eventListener is removed when promise is cancelled/rejected
+    //////////////////////////
+    var handle_event_callback,
+      callback_promise;
+
+    if (prevent_default === undefined) {
+      prevent_default = true;
+    }
+
+    function cancelResolver() {
+      if ((callback_promise !== undefined) &&
+          (typeof callback_promise.cancel === "function")) {
+        callback_promise.cancel();
+      }
+    }
+
+    function canceller() {
+      if (handle_event_callback !== undefined) {
+        target.removeEventListener(type, handle_event_callback, useCapture);
+      }
+      cancelResolver();
+    }
+    function itsANonResolvableTrap(resolve, reject) {
+      var result;
+      handle_event_callback = function (evt) {
+        if (prevent_default) {
+          evt.stopPropagation();
+          evt.preventDefault();
+        }
+
+        cancelResolver();
+
+        try {
+          result = callback(evt);
+        } catch (e) {
+          result = RSVP.reject(e);
+        }
+
+        callback_promise = result;
+        new RSVP.Queue()
+          .push(function () {
+            return result;
+          })
+          .push(undefined, function (error) {
+            if (!(error instanceof RSVP.CancellationError)) {
+              canceller();
+              reject(error);
+            }
+          });
+      };
+
+      target.addEventListener(type, handle_event_callback, useCapture);
+    }
+    return new RSVP.Promise(itsANonResolvableTrap, canceller);
+  }
+
   function ajax(url) {
     var xhr;
     function resolver(resolve, reject) {
@@ -805,6 +865,10 @@ if (typeof document.contains !== 'function') {
     paragraph.textContent = 'User-agent: ' + navigator.userAgent;
     container.appendChild(paragraph);
 
+    paragraph = document.createElement("p");
+    paragraph.textContent = 'Date: ' + new Date(Date.now()).toISOString();
+    container.appendChild(paragraph);
+
     body.appendChild(container);
 
     for (i = 0; i < error_list.length; i += 1) {
@@ -1004,6 +1068,9 @@ if (typeof document.contains !== 'function') {
       g.__monitor.cancel();
     }
     g.__monitor = new Monitor();
+    g.__job_dict = {};
+    g.__job_list = [];
+    g.__job_triggered = false;
     g.__monitor.fail(function (error) {
       if (!(error instanceof RSVP.CancellationError)) {
         return g.aq_reportServiceError(error);
@@ -1020,7 +1087,7 @@ if (typeof document.contains !== 'function') {
   }
 
   function loadSubGadgetDOMDeclaration(g) {
-    var element_list = g.__element.querySelectorAll('[data-gadget-url]'),
+    var element_list = g.element.querySelectorAll('[data-gadget-url]'),
       element,
       promise_list = [],
       scope,
@@ -1051,25 +1118,89 @@ if (typeof document.contains !== 'function') {
     this.__ready_list.push(callback);
     return this;
   };
+  RenderJSGadget.setState = function (state_dict) {
+    var json_state = JSON.stringify(state_dict);
+    return this.ready(function () {
+      this.state = JSON.parse(json_state);
+    });
+  };
+  RenderJSGadget.onStateChange = function (callback) {
+    this.prototype.__state_change_callback = callback;
+    return this;
+  };
 
   RenderJSGadget.__service_list = [];
   RenderJSGadget.declareService = function (callback) {
     this.__service_list.push(callback);
     return this;
   };
+  RenderJSGadget.onEvent = function (type, callback, use_capture,
+                                     prevent_default) {
+    this.__service_list.push(function () {
+      return loopEventListener(this.element, type, use_capture,
+                               callback.bind(this), prevent_default);
+    });
+    return this;
+  };
+
+  function runJob(gadget, name, callback, argument_list) {
+    var job_promise = new RSVP.Queue()
+      .push(function () {
+        return callback.apply(gadget, argument_list);
+      });
+    if (gadget.__job_dict.hasOwnProperty(name)) {
+      gadget.__job_dict[name].cancel();
+    }
+    gadget.__job_dict[name] = job_promise;
+    gadget.__monitor.monitor(new RSVP.Queue()
+      .push(function () {
+        return job_promise;
+      })
+      .push(undefined, function (error) {
+        if (!(error instanceof RSVP.CancellationError)) {
+          throw error;
+        }
+      }));
+  }
 
   function startService(gadget) {
     gadget.__monitor.monitor(new RSVP.Queue()
       .push(function () {
         var i,
-          service_list = gadget.constructor.__service_list;
+          service_list = gadget.constructor.__service_list,
+          job_list = gadget.__job_list;
         for (i = 0; i < service_list.length; i += 1) {
           gadget.__monitor.monitor(service_list[i].apply(gadget));
         }
+        for (i = 0; i < job_list.length; i += 1) {
+          runJob(gadget, job_list[i][0], job_list[i][1], job_list[i][2]);
+        }
+        gadget.__job_list = [];
+        gadget.__job_triggered = true;
       })
       );
   }
 
+  /////////////////////////////////////////////////////////////////
+  // RenderJSGadget.declareJob
+  // gadget internal method, which trigger execution
+  // of a function inside a service
+  /////////////////////////////////////////////////////////////////
+  RenderJSGadget.declareJob = function (name, callback) {
+    this.prototype[name] = function () {
+      var context = this,
+        argument_list = arguments;
+
+      if (context.__job_triggered) {
+        runJob(context, name, callback, argument_list);
+      } else {
+        context.__job_list.push([name, callback, argument_list]);
+      }
+    };
+    // Allow chain
+    return this;
+  };
+
   /////////////////////////////////////////////////////////////////
   // RenderJSGadget.declareMethod
   /////////////////////////////////////////////////////////////////
@@ -1110,10 +1241,26 @@ if (typeof document.contains !== 'function') {
     })
     .declareMethod('getElement', function () {
       // Returns the DOM Element of a gadget
-      if (this.__element === undefined) {
+      // XXX Kept for compatibility. Use element property directly
+      if (this.element === undefined) {
         throw new Error("No element defined");
       }
-      return this.__element;
+      return this.element;
+    })
+    .declareMethod('changeState', function (state_dict) {
+      var key,
+        modified = false,
+        modification_dict = {};
+      for (key in state_dict) {
+        if (state_dict[key] !== this.state[key]) {
+          this.state[key] = state_dict[key];
+          modification_dict[key] = state_dict[key];
+          modified = true;
+        }
+      }
+      if (modified && this.__state_change_callback !== undefined) {
+        return this.__state_change_callback(modification_dict);
+      }
     });
 
   /////////////////////////////////////////////////////////////////
@@ -1202,8 +1349,14 @@ if (typeof document.contains !== 'function') {
     RenderJSGadget.__service_list.slice();
   RenderJSEmbeddedGadget.ready =
     RenderJSGadget.ready;
+  RenderJSEmbeddedGadget.setState =
+    RenderJSGadget.setState;
+  RenderJSEmbeddedGadget.onStateChange =
+    RenderJSGadget.onStateChange;
   RenderJSEmbeddedGadget.declareService =
     RenderJSGadget.declareService;
+  RenderJSEmbeddedGadget.onEvent =
+    RenderJSGadget.onEvent;
   RenderJSEmbeddedGadget.prototype = new RenderJSGadget();
   RenderJSEmbeddedGadget.prototype.constructor = RenderJSEmbeddedGadget;
 
@@ -1232,9 +1385,10 @@ if (typeof document.contains !== 'function') {
           template_node_list = Klass.__template_element.body.childNodes;
         gadget_loading_klass = Klass;
         gadget_instance = new Klass();
-        gadget_instance.__element = options.element;
+        gadget_instance.element = options.element;
+        gadget_instance.state = {};
         for (i = 0; i < template_node_list.length; i += 1) {
-          gadget_instance.__element.appendChild(
+          gadget_instance.element.appendChild(
             template_node_list[i].cloneNode(true)
           );
         }
@@ -1276,9 +1430,15 @@ if (typeof document.contains !== 'function') {
   RenderJSIframeGadget.__ready_list = RenderJSGadget.__ready_list.slice();
   RenderJSIframeGadget.ready =
     RenderJSGadget.ready;
+  RenderJSIframeGadget.setState =
+    RenderJSGadget.setState;
+  RenderJSIframeGadget.onStateChange =
+    RenderJSGadget.onStateChange;
   RenderJSIframeGadget.__service_list = RenderJSGadget.__service_list.slice();
   RenderJSIframeGadget.declareService =
     RenderJSGadget.declareService;
+  RenderJSIframeGadget.onEvent =
+    RenderJSGadget.onEvent;
   RenderJSIframeGadget.prototype = new RenderJSGadget();
   RenderJSIframeGadget.prototype.constructor = RenderJSIframeGadget;
 
@@ -1306,7 +1466,8 @@ if (typeof document.contains !== 'function') {
 //    gadget_instance.element.setAttribute("seamless", "seamless");
     iframe.setAttribute("src", url);
     gadget_instance.__path = url;
-    gadget_instance.__element = options.element;
+    gadget_instance.element = options.element;
+    gadget_instance.state = {};
     // Attach it to the DOM
     options.element.appendChild(iframe);
 
@@ -1475,10 +1636,17 @@ if (typeof document.contains !== 'function') {
           function ready_wrapper() {
             return gadget_instance;
           }
+          function ready_executable_wrapper(fct) {
+            return function (g) {
+              return fct.call(g, g);
+            };
+          }
           for (i = 0; i < gadget_instance.constructor.__ready_list.length;
                i += 1) {
             // Put a timeout?
-            queue.push(gadget_instance.constructor.__ready_list[i]);
+            queue.push(ready_executable_wrapper(
+              gadget_instance.constructor.__ready_list[i]
+            ));
             // Always return the gadget instance after ready function
             queue.push(ready_wrapper);
           }
@@ -1494,16 +1662,16 @@ if (typeof document.contains !== 'function') {
             }
           }
           parent_gadget.__sub_gadget_dict[scope] = gadget_instance;
-          gadget_instance.__element.setAttribute("data-gadget-scope",
-                                                 scope);
+          gadget_instance.element.setAttribute("data-gadget-scope",
+                                               scope);
 
           // Put some attribute to ease page layout comprehension
-          gadget_instance.__element.setAttribute("data-gadget-url", url);
-          gadget_instance.__element.setAttribute("data-gadget-sandbox",
-                                                 options.sandbox);
-          gadget_instance.__element._gadget = gadget_instance;
+          gadget_instance.element.setAttribute("data-gadget-url", url);
+          gadget_instance.element.setAttribute("data-gadget-sandbox",
+                                               options.sandbox);
+          gadget_instance.element._gadget = gadget_instance;
 
-          if (document.contains(gadget_instance.__element)) {
+          if (document.contains(gadget_instance.element)) {
             // Put a timeout
             queue.push(startService);
           }
@@ -1656,14 +1824,22 @@ if (typeof document.contains !== 'function') {
         tmp_constructor.__service_list = RenderJSGadget.__service_list.slice();
         tmp_constructor.declareMethod =
           RenderJSGadget.declareMethod;
+        tmp_constructor.declareJob =
+          RenderJSGadget.declareJob;
         tmp_constructor.declareAcquiredMethod =
           RenderJSGadget.declareAcquiredMethod;
         tmp_constructor.allowPublicAcquisition =
           RenderJSGadget.allowPublicAcquisition;
         tmp_constructor.ready =
           RenderJSGadget.ready;
+        tmp_constructor.setState =
+          RenderJSGadget.setState;
+        tmp_constructor.onStateChange =
+          RenderJSGadget.onStateChange;
         tmp_constructor.declareService =
           RenderJSGadget.declareService;
+        tmp_constructor.onEvent =
+          RenderJSGadget.onEvent;
         tmp_constructor.prototype = new RenderJSGadget();
         tmp_constructor.prototype.constructor = tmp_constructor;
         tmp_constructor.prototype.__path = url;
@@ -1829,15 +2005,20 @@ if (typeof document.contains !== 'function') {
           RenderJSGadget.call(this);
         };
         tmp_constructor.declareMethod = RenderJSGadget.declareMethod;
+        tmp_constructor.declareJob = RenderJSGadget.declareJob;
         tmp_constructor.declareAcquiredMethod =
           RenderJSGadget.declareAcquiredMethod;
         tmp_constructor.allowPublicAcquisition =
           RenderJSGadget.allowPublicAcquisition;
         tmp_constructor.__ready_list = RenderJSGadget.__ready_list.slice();
         tmp_constructor.ready = RenderJSGadget.ready;
+        tmp_constructor.setState = RenderJSGadget.setState;
+        tmp_constructor.onStateChange = RenderJSGadget.onStateChange;
         tmp_constructor.__service_list = RenderJSGadget.__service_list.slice();
         tmp_constructor.declareService =
           RenderJSGadget.declareService;
+        tmp_constructor.onEvent =
+          RenderJSGadget.onEvent;
         tmp_constructor.prototype = new RenderJSGadget();
         tmp_constructor.prototype.constructor = tmp_constructor;
         tmp_constructor.prototype.__path = url;
@@ -1960,6 +2141,10 @@ if (typeof document.contains !== 'function') {
 
         tmp_constructor.declareService =
           RenderJSGadget.declareService;
+        tmp_constructor.declareJob =
+          RenderJSGadget.declareJob;
+        tmp_constructor.onEvent =
+          RenderJSGadget.onEvent;
         tmp_constructor.declareAcquiredMethod =
           RenderJSGadget.declareAcquiredMethod;
         tmp_constructor.allowPublicAcquisition =
@@ -1982,10 +2167,11 @@ if (typeof document.contains !== 'function') {
           }
         }
         tmp_constructor.__template_element = document.createElement("div");
-        root_gadget.__element = document.body;
-        for (j = 0; j < root_gadget.__element.childNodes.length; j += 1) {
+        root_gadget.element = document.body;
+        root_gadget.state = {};
+        for (j = 0; j < root_gadget.element.childNodes.length; j += 1) {
           tmp_constructor.__template_element.appendChild(
-            root_gadget.__element.childNodes[j].cloneNode(true)
+            root_gadget.element.childNodes[j].cloneNode(true)
           );
         }
         RSVP.all([root_gadget.getRequiredJSList(),
@@ -2089,7 +2275,11 @@ if (typeof document.contains !== 'function') {
         function ready_wrapper() {
           return root_gadget;
         }
-
+        function ready_executable_wrapper(fct) {
+          return function (g) {
+            return fct.call(g, g);
+          };
+        }
         tmp_constructor.ready(function (g) {
           return startService(g);
         });
@@ -2098,7 +2288,7 @@ if (typeof document.contains !== 'function') {
         for (i = 0; i < tmp_constructor.__ready_list.length; i += 1) {
           // Put a timeout?
           loading_gadget_promise
-            .push(tmp_constructor.__ready_list[i])
+            .push(ready_executable_wrapper(tmp_constructor.__ready_list[i]))
             // Always return the gadget instance after ready function
             .push(ready_wrapper);
         }
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_renderjs_js.xml b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_renderjs_js.xml
index e48f8fae5d..9306c84c83 100644
--- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_renderjs_js.xml
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_renderjs_js.xml
@@ -230,7 +230,7 @@
             </item>
             <item>
                 <key> <string>serial</string> </key>
-                <value> <string>952.32884.7041.46523</string> </value>
+                <value> <string>954.33025.37475.1638</string> </value>
             </item>
             <item>
                 <key> <string>state</string> </key>
@@ -248,7 +248,7 @@
                     </tuple>
                     <state>
                       <tuple>
-                        <float>1469783555.9</float>
+                        <float>1476192938.84</float>
                         <string>UTC</string>
                       </tuple>
                     </state>
-- 
2.30.9