From c2df5d4e13e9ab63e8f152d638eec35284efdf2f Mon Sep 17 00:00:00 2001
From: Aleksander Machniak <alec@alec.pl>
Date: Mon, 09 Mar 2015 09:24:05 -0400
Subject: [PATCH] Unified request* event arguments handling, added support for _unlock and _action parameters

---
 CHANGELOG            |    1 
 program/js/common.js |   28 ++++++++++++++
 program/js/app.js    |   72 ++++++++++++++++++++++--------------
 3 files changed, 73 insertions(+), 28 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 19c5ed4..1ae0a3a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -9,6 +9,7 @@
 - Add possibility to configure max_allowed_packet value for all database engines (#1490283)
 - Improved handling of storage errors after message is sent
 - Update to TinyMCE 4.1.8
+- Unified request* event arguments handling, added support for _unlock and _action parameters
 - Fix refreshing of drafts list when sending a message which was saved in meantime (#1490238)
 - Fix saving/sending emoticon images when assets_dir is set
 - Fix PHP fatal error when visiting Vacation interface and there's no sieve script yet (#1490292)
diff --git a/program/js/app.js b/program/js/app.js
index 223606e..b8e6e77 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -7287,22 +7287,32 @@
   };
 
   // send a http request to the server
-  this.http_request = function(action, query, lock)
+  this.http_request = function(action, data, lock)
   {
-    var url = this.url(action, query);
+    if (typeof data !== 'object')
+      data = rcube_parse_query(data);
+
+    data._remote = 1;
+    data._unlock = lock ? lock : 0;
 
     // trigger plugin hook
-    var result = this.triggerEvent('request'+action, query);
+    var result = this.triggerEvent('request' + action, data);
 
-    if (result !== undefined) {
-      // abort if one the handlers returned false
-      if (result === false)
-        return false;
-      else
-        url = this.url(action, result);
+    // abort if one of the handlers returned false
+    if (result === false) {
+      if (data._unlock)
+        this.set_busy(false, null, data._unlock);
+      return false;
+    }
+    else if (result !== undefined) {
+      data = result;
+      if (data._action) {
+        action = data._action;
+        delete data._action;
+      }
     }
 
-    url += '&_remote=1';
+    var url = this.url(action, data);
 
     // send request
     this.log('HTTP GET: ' + url);
@@ -7311,33 +7321,39 @@
     this.start_keepalive();
 
     return $.ajax({
-      type: 'GET', url: url, data: { _unlock:(lock?lock:0) }, dataType: 'json',
-      success: function(data){ ref.http_response(data); },
+      type: 'GET', url: url, dataType: 'json',
+      success: function(data) { ref.http_response(data); },
       error: function(o, status, err) { ref.http_error(o, status, err, lock, action); }
     });
   };
 
   // send a http POST request to the server
-  this.http_post = function(action, postdata, lock)
+  this.http_post = function(action, data, lock)
   {
-    var url = this.url(action);
+    if (typeof data !== 'object')
+      data = rcube_parse_query(data);
 
-    if (postdata && typeof postdata === 'object') {
-      postdata._remote = 1;
-      postdata._unlock = (lock ? lock : 0);
-    }
-    else
-      postdata += (postdata ? '&' : '') + '_remote=1' + (lock ? '&_unlock='+lock : '');
+    data._remote = 1;
+    data._unlock = lock ? lock : 0;
 
     // trigger plugin hook
-    var result = this.triggerEvent('request'+action, postdata);
-    if (result !== undefined) {
-      // abort if one of the handlers returned false
-      if (result === false)
-        return false;
-      else
-        postdata = result;
+    var result = this.triggerEvent('request'+action, data);
+
+    // abort if one of the handlers returned false
+    if (result === false) {
+      if (data._unlock)
+        this.set_busy(false, null, data._unlock);
+      return false;
     }
+    else if (result !== undefined) {
+      data = result;
+      if (data._action) {
+        action = data._action;
+        delete data._action;
+      }
+    }
+
+    var url = this.url(action);
 
     // send request
     this.log('HTTP POST: ' + url);
@@ -7346,7 +7362,7 @@
     this.start_keepalive();
 
     return $.ajax({
-      type: 'POST', url: url, data: postdata, dataType: 'json',
+      type: 'POST', url: url, data: data, dataType: 'json',
       success: function(data){ ref.http_response(data); },
       error: function(o, status, err) { ref.http_error(o, status, err, lock, action); }
     });
diff --git a/program/js/common.js b/program/js/common.js
index e60a14e..3babf1e 100644
--- a/program/js/common.js
+++ b/program/js/common.js
@@ -654,6 +654,34 @@
   });
 };
 
+// function to parse query string into an object
+rcube_parse_query = function(query)
+{
+  if (!query)
+    return {};
+
+  var params = {}, e, k, v,
+    re = /([^&=]+)=?([^&]*)/g,
+    decodeRE = /\+/g, // Regex for replacing addition symbol with a space
+    decode = function (str) { return decodeURIComponent(str.replace(decodeRE, ' ')); };
+
+  query = query.replace(/\?/, '');
+
+  while (e = re.exec(query)) {
+    k = decode(e[1]);
+    v = decode(e[2]);
+
+    if (k.substring(k.length - 2) === '[]') {
+      k = k.substring(0, k.length - 2);
+      (params[k] || (params[k] = [])).push(v);
+    }
+    else
+      params[k] = v;
+  }
+
+  return params;
+};
+
 
 // This code was written by Tyler Akins and has been placed in the
 // public domain.  It would be nice if you left this header intact.

--
Gitblit v1.9.1