Add diff color picker functionality to resemble mode

Change-Id: I771508fd75ecccdf1d5d42c21bb3f725d1e0a916
diff --git a/gr-resemble-diff-mode/gr-resemble-diff-mode.html b/gr-resemble-diff-mode/gr-resemble-diff-mode.html
index b94859e..0404bb5 100644
--- a/gr-resemble-diff-mode/gr-resemble-diff-mode.html
+++ b/gr-resemble-diff-mode/gr-resemble-diff-mode.html
@@ -60,6 +60,9 @@
           on-tap="_handleTransparentToggle">
       Transparent
     </label>
+    <input
+        type="color"
+        value="{{_colorValue::change}}">
   </template>
   <script src="gr-resemble-diff-mode.js"></script>
 </dom-module>
\ No newline at end of file
diff --git a/gr-resemble-diff-mode/gr-resemble-diff-mode.js b/gr-resemble-diff-mode/gr-resemble-diff-mode.js
index 3161fd9..8e706f0 100644
--- a/gr-resemble-diff-mode/gr-resemble-diff-mode.js
+++ b/gr-resemble-diff-mode/gr-resemble-diff-mode.js
@@ -20,6 +20,11 @@
     properties: {
       baseImage: Object,
       revisionImage: Object,
+      _colorValue: {
+        type: String,
+        observer: '_handleColorChange',
+        value: '#00ffff',
+      },
       _ignoreColors: {
         type: Boolean,
         value: false,
@@ -113,5 +118,31 @@
         this.reload();
       }, 1);
     },
+
+    // The wait time of 5 ms allows users to see the color change in the image
+    // diff relatively close to real time. Any larger wait time will not allow
+    // the color to show up immediately on the image diff.
+    _handleColorChange() {
+      this.debounce('color-change', () => {
+        const rgb = this._hexToRGB(this._colorValue);
+        window.resemble.outputSettings({
+          errorColor: {
+            red: rgb.r,
+            green: rgb.g,
+            blue: rgb.b,
+          },
+        });
+        this.reload();
+      }, 5);
+    },
+
+    _hexToRGB(hex) {
+      const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
+      return result ? {
+        r: parseInt(result[1], 16),
+        g: parseInt(result[2], 16),
+        b: parseInt(result[3], 16),
+      } : null;
+    },
   });
 })();
diff --git a/gr-resemble-diff-mode/gr-resemble-diff-mode_test.html b/gr-resemble-diff-mode/gr-resemble-diff-mode_test.html
index 2441ac4..ba3e9ca 100644
--- a/gr-resemble-diff-mode/gr-resemble-diff-mode_test.html
+++ b/gr-resemble-diff-mode/gr-resemble-diff-mode_test.html
@@ -97,6 +97,27 @@
       assert.isTrue(element.reload.called);
     });
 
+    test('_handleColorChange', () => {
+      sandbox.stub(element, 'reload');
+      sandbox.stub(element, '_hexToRGB')
+          .returns({r: 0, g: 0, b: 0});
+      element._colorValue = '';
+      element.flushDebouncer('color-change');
+      flushAsynchronousOperations();
+
+      assert.isTrue(element._hexToRGB.called);
+      assert.isTrue(element.reload.called);
+    });
+
+    test('_hexToRGB', () => {
+      const expected = {r: 0, g: 255, b: 255};
+      const input = '#00ffff';
+      const output = element._hexToRGB(input);
+      assert.equal(output.r, expected.r);
+      assert.equal(output.g, expected.g);
+      assert.equal(output.b, expected.b);
+    });
+
     test('calls reload', () => {
       sandbox.stub(element, 'reload');
       element.baseImage = {};