Store imagare user preferences in a browser cookie

This avoids making a call to the server to fetch the preferences
everytime a change or diff screen is viewed.

The cookie expires once a day so that new defaults will be picked up.

Change-Id: I73871efa32f3c8b6b7b84aa6b41864c766eb537c
Signed-off-by: Edwin Kempin <ekempin@google.com>
diff --git a/src/main/java/com/googlesource/gerrit/plugins/imagare/client/ImagareConfigScreen.java b/src/main/java/com/googlesource/gerrit/plugins/imagare/client/ImagareConfigScreen.java
index 0a4f83d..f0a2faf 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/imagare/client/ImagareConfigScreen.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/imagare/client/ImagareConfigScreen.java
@@ -136,6 +136,7 @@
         @Override
         public void onSuccess(JavaScriptObject result) {
           saveButton.setEnabled(false);
+          onSave();
         }
 
         @Override
@@ -144,4 +145,7 @@
         }
       });
   }
+
+  protected void onSave() {
+  }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/imagare/client/ImagarePreferenceScreen.java b/src/main/java/com/googlesource/gerrit/plugins/imagare/client/ImagarePreferenceScreen.java
index bae87be..5922452 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/imagare/client/ImagarePreferenceScreen.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/imagare/client/ImagarePreferenceScreen.java
@@ -17,6 +17,7 @@
 import com.google.gerrit.plugin.client.Plugin;
 import com.google.gerrit.plugin.client.rpc.RestApi;
 import com.google.gerrit.plugin.client.screen.Screen;
+import com.google.gwt.user.client.Cookies;
 import com.google.gwt.user.client.ui.Anchor;
 import com.google.gwt.user.client.ui.HorizontalPanel;
 import com.google.gwt.user.client.ui.ImageResourceRenderer;
@@ -58,4 +59,10 @@
 
     super.display(info);
   }
+
+  @Override
+  protected void onSave() {
+    super.onSave();
+    Cookies.removeCookie(Plugin.get().getPluginName() + "~prefs");
+  }
 }
diff --git a/src/main/resources/static/imagare.js b/src/main/resources/static/imagare.js
index f55087e..acf14cf 100644
--- a/src/main/resources/static/imagare.js
+++ b/src/main/resources/static/imagare.js
@@ -18,23 +18,64 @@
         return;
       }
 
-      Gerrit.get('/accounts/self/preference', function(r) {
-        if (!r.pattern) {
-          return;
-        }
-
-        if ('TOOLTIP' === r.link_decoration) {
-          addTooltips(r.pattern);
-        } else if ('INLINE' === r.link_decoration) {
-          inlineImages(r.pattern);
-        }
-      });
+      var prefs = getPrefsFromCookie();
+      if (prefs !== null) {
+        convertImageLinks(prefs);
+      } else {
+        Gerrit.get('/accounts/self/preference', function(prefs) {
+          storePrefsInCookie(prefs);
+          convertImageLinks(prefs);
+        });
+      }
     }
 
     function startsWith(s, p) {
       return s.slice(0, p.length) == p;
     }
 
+    function storePrefsInCookie(prefs) {
+      var date = new Date();
+      date.setTime(date.getTime() + (1 * 24 * 60 * 60 * 1000)); // 1 day
+      document.cookie = getCookieName()
+          + "="
+          + JSON.stringify(prefs)
+          + "; expires=" + date.toGMTString()
+          + "; path=/";
+    }
+
+    function getPrefsFromCookie() {
+      var cookie = document.cookie;
+      if (cookie.length > 0) {
+        var cookieName = getCookieName();
+        var start = cookie.indexOf(cookieName + "=");
+        if (start != -1) {
+            start = start + cookieName.length + 1;
+            var end = document.cookie.indexOf(";", start);
+            if (end == -1) {
+                end = document.cookie.length;
+            }
+            return JSON.parse(unescape(document.cookie.substring(start, end)));
+        }
+      }
+      return null;
+    }
+
+    function getCookieName() {
+      return self.getPluginName() + "~prefs";
+    }
+
+    function convertImageLinks(prefs) {
+      if (!prefs.pattern) {
+        return;
+      }
+
+      if ('TOOLTIP' === prefs.link_decoration) {
+        addTooltips(prefs.pattern);
+      } else if ('INLINE' === prefs.link_decoration) {
+        inlineImages(prefs.pattern);
+      }
+    }
+
     function inlineImages(pattern) {
       var l = document.links;
       for(var i = 0; i < l.length; i++) {