Add redirection feature for plugins

Change-Id: I492eb833577aaed6b36d540dae30ead0e8dd6839
diff --git a/Changes b/Changes
index 0175b4f..aa474ca 100755
--- a/Changes
+++ b/Changes
@@ -28,6 +28,7 @@
         - Introduce legacy redirects for tutorial links.
         - Improve QueryParam response.
         - Fold all top-level navigation items.
+        - Add plugin service to redirect to a certain location.
 
 0.42 2021-06-18
         - Added GitHub based CI for perl.
diff --git a/dev/demo/plugin-client.html b/dev/demo/plugin-client.html
index 44333f8..08e6034 100644
--- a/dev/demo/plugin-client.html
+++ b/dev/demo/plugin-client.html
@@ -51,11 +51,31 @@
           }
         };
       };
+
+      function redirect() {
+
+        KorAPlugin.requestMsg({
+          "action":"get",
+          "key": 'QueryParam'
+        }, function (d) {
+
+          const par = d.value.param;
+          par.set("q",56);
+          
+          KorAPlugin.sendMsg({
+            'action':'redirect',
+            'queryParam' : par.toString()
+          })
+        });
+        
+      }
+      
       </script>
     <ul>
       <li><a onclick="KorAPlugin.log(333, 'Huhu!')">Send log!</a></li>
       <li><a onclick="KorAPlugin.resize()">Resize</a></li>
       <li><a onclick="KorAPlugin.sendMsg({'action':'pipe','service':'Glemm'})">Add Glemm</a></li>
+      <li><a onclick="redirect()">Redirect</a></li>
       <li><a onclick="flood()">Flood!</a></li>
       <li><a onclick="KorAPlugin.requestMsg({'action':'get', 'key':'KQ'}, function (d) { document.write(JSON.stringify(d.value))})">Get KQ</a></li>
     </ul>
diff --git a/dev/js/src/plugin/server.js b/dev/js/src/plugin/server.js
index 4027f8d..817c0c9 100644
--- a/dev/js/src/plugin/server.js
+++ b/dev/js/src/plugin/server.js
@@ -223,7 +223,7 @@
           }
         }
 
-        // TODO There is no possibility to add icons to an plugin toggle button right now. 
+        // TODO There is no possibility to add icons to a plugin toggle button right now. 
         else if (onClick["action"] == "toggle") {
 
           // TODO:
@@ -502,12 +502,26 @@
           v["q"] = p.get('q');
           v["ql"] = p.get('ql');
           v["cq"] = p.get('cq');
-        }
-      };
+        };
 
-      // data needs to be mirrored
-      if (d._id) {
-        service.sendMsg(d);
+        // data needs to be mirrored
+        if (d._id) {
+          service.sendMsg(d);
+        };
+
+        break;
+
+        // Redirect to a different page relative to the current
+      case 'redirect':
+        const url = new URL(window.location);
+
+        // Currently this only accepts search parameters
+        if (d["queryParam"]) {
+          url.search = new URLSearchParams(d["queryParam"]);
+        };
+
+        window.location = url.toString();
+        break;
       };
 
       // TODO: