Fix template problems with gr-diff-preferences

Change-Id: Icf9a3cc893d92fe2e047fa09ba677af275cac9a8
diff --git a/polygerrit-ui/app/BUILD b/polygerrit-ui/app/BUILD
index 5f9c3c5..191d658 100644
--- a/polygerrit-ui/app/BUILD
+++ b/polygerrit-ui/app/BUILD
@@ -123,7 +123,6 @@
     "elements/shared/gr-comment/gr-comment_html.ts",
     "elements/shared/gr-confirm-delete-comment-dialog/gr-confirm-delete-comment-dialog_html.ts",
     "elements/shared/gr-dialog/gr-dialog_html.ts",
-    "elements/shared/gr-diff-preferences/gr-diff-preferences_html.ts",
     "elements/shared/gr-download-commands/gr-download-commands_html.ts",
     "elements/shared/gr-dropdown-list/gr-dropdown-list_html.ts",
     "elements/shared/gr-dropdown/gr-dropdown_html.ts",
diff --git a/polygerrit-ui/app/elements/shared/gr-diff-preferences/gr-diff-preferences.ts b/polygerrit-ui/app/elements/shared/gr-diff-preferences/gr-diff-preferences.ts
index 70a7bf3..e560773 100644
--- a/polygerrit-ui/app/elements/shared/gr-diff-preferences/gr-diff-preferences.ts
+++ b/polygerrit-ui/app/elements/shared/gr-diff-preferences/gr-diff-preferences.ts
@@ -21,18 +21,23 @@
 import {PolymerElement} from '@polymer/polymer/polymer-element';
 import {htmlTemplate} from './gr-diff-preferences_html';
 import {customElement, property} from '@polymer/decorators';
-import {DiffPreferencesInfo} from '../../../types/diff';
+import {DiffPreferencesInfo, IgnoreWhitespaceType} from '../../../types/diff';
 import {GrSelect} from '../gr-select/gr-select';
 import {appContext} from '../../../services/app-context';
 
 export interface GrDiffPreferences {
   $: {
+    contextLineSelect: HTMLInputElement;
+    columnsInput: HTMLInputElement;
+    tabSizeInput: HTMLInputElement;
+    fontSizeInput: HTMLInputElement;
     lineWrappingInput: HTMLInputElement;
     showTabsInput: HTMLInputElement;
     showTrailingWhitespaceInput: HTMLInputElement;
     automaticReviewInput: HTMLInputElement;
     syntaxHighlightInput: HTMLInputElement;
     contextSelect: GrSelect;
+    ignoreWhiteSpace: HTMLInputElement;
   };
   save(): Promise<void>;
 }
@@ -61,11 +66,31 @@
     this.hasUnsavedChanges = true;
   }
 
+  _handleDiffContextChanged() {
+    this.set('diffPrefs.context', Number(this.$.contextLineSelect.value));
+    this._handleDiffPrefsChanged();
+  }
+
   _handleLineWrappingTap() {
     this.set('diffPrefs.line_wrapping', this.$.lineWrappingInput.checked);
     this._handleDiffPrefsChanged();
   }
 
+  _handleDiffLineLengthChanged() {
+    this.set('diffPrefs.line_length', Number(this.$.columnsInput.value));
+    this._handleDiffPrefsChanged();
+  }
+
+  _handleDiffTabSizeChanged() {
+    this.set('diffPrefs.tab_size', Number(this.$.tabSizeInput.value));
+    this._handleDiffPrefsChanged();
+  }
+
+  _handleDiffFontSizeChanged() {
+    this.set('diffPrefs.font_size', Number(this.$.fontSizeInput.value));
+    this._handleDiffPrefsChanged();
+  }
+
   _handleShowTabsTap() {
     this.set('diffPrefs.show_tabs', this.$.showTabsInput.checked);
     this._handleDiffPrefsChanged();
@@ -92,6 +117,14 @@
     this._handleDiffPrefsChanged();
   }
 
+  _handleDiffIgnoreWhitespaceChanged() {
+    this.set(
+      'diffPrefs.ignore_whitespace',
+      this.$.ignoreWhiteSpace.value as IgnoreWhitespaceType
+    );
+    this._handleDiffPrefsChanged();
+  }
+
   save() {
     if (!this.diffPrefs)
       return Promise.reject(new Error('Missing diff preferences'));
@@ -99,6 +132,27 @@
       this.hasUnsavedChanges = false;
     });
   }
+
+  /**
+   * bind-value has type string so we have to convert
+   * anything inputed to string.
+   *
+   * This is so typescript checker doesn't fail.
+   */
+  _convertToString(key?: number | IgnoreWhitespaceType) {
+    return key !== undefined ? String(key) : '';
+  }
+
+  /**
+   * input 'checked' does not allow undefined,
+   * so we make sure the value is boolean
+   * by returning false if undefined.
+   *
+   * This is so typescript checker doesn't fail.
+   */
+  _convertToBoolean(key?: boolean) {
+    return key !== undefined ? key : false;
+  }
 }
 
 declare global {
diff --git a/polygerrit-ui/app/elements/shared/gr-diff-preferences/gr-diff-preferences_html.ts b/polygerrit-ui/app/elements/shared/gr-diff-preferences/gr-diff-preferences_html.ts
index ed3d695..51867c8 100644
--- a/polygerrit-ui/app/elements/shared/gr-diff-preferences/gr-diff-preferences_html.ts
+++ b/polygerrit-ui/app/elements/shared/gr-diff-preferences/gr-diff-preferences_html.ts
@@ -27,12 +27,12 @@
     <section>
       <label for="contextLineSelect" class="title">Context</label>
       <span class="value">
-        <gr-select id="contextSelect" bind-value="{{diffPrefs.context}}">
-          <select
-            id="contextLineSelect"
-            on-keypress="_handleDiffPrefsChanged"
-            on-change="_handleDiffPrefsChanged"
-          >
+        <gr-select
+          id="contextSelect"
+          bind-value="[[_convertToString(diffPrefs.context)]]"
+          on-change="_handleDiffContextChanged"
+        >
+          <select id="contextLineSelect">
             <option value="3">3 lines</option>
             <option value="10">10 lines</option>
             <option value="25">25 lines</option>
@@ -50,7 +50,7 @@
         <input
           id="lineWrappingInput"
           type="checkbox"
-          checked="[[diffPrefs.line_wrapping]]"
+          checked="[[_convertToBoolean(diffPrefs.line_wrapping)]]"
           on-change="_handleLineWrappingTap"
         />
       </span>
@@ -59,23 +59,11 @@
       <label for="columnsInput" class="title">Diff width</label>
       <span class="value">
         <iron-input
-          type="number"
-          prevent-invalid-input=""
           allowed-pattern="[0-9]"
-          bind-value="{{diffPrefs.line_length}}"
-          on-keypress="_handleDiffPrefsChanged"
-          on-change="_handleDiffPrefsChanged"
+          bind-value="[[_convertToString(diffPrefs.line_length)]]"
+          on-change="_handleDiffLineLengthChanged"
         >
-          <input
-            is="iron-input"
-            type="number"
-            id="columnsInput"
-            prevent-invalid-input=""
-            allowed-pattern="[0-9]"
-            bind-value="{{diffPrefs.line_length}}"
-            on-keypress="_handleDiffPrefsChanged"
-            on-change="_handleDiffPrefsChanged"
-          />
+          <input id="columnsInput" type="number" />
         </iron-input>
       </span>
     </section>
@@ -83,23 +71,11 @@
       <label for="tabSizeInput" class="title">Tab width</label>
       <span class="value">
         <iron-input
-          type="number"
-          prevent-invalid-input=""
           allowed-pattern="[0-9]"
-          bind-value="{{diffPrefs.tab_size}}"
-          on-keypress="_handleDiffPrefsChanged"
-          on-change="_handleDiffPrefsChanged"
+          bind-value="[[_convertToString(diffPrefs.tab_size)]]"
+          on-change="_handleDiffTabSizeChanged"
         >
-          <input
-            is="iron-input"
-            type="number"
-            id="tabSizeInput"
-            prevent-invalid-input=""
-            allowed-pattern="[0-9]"
-            bind-value="{{diffPrefs.tab_size}}"
-            on-keypress="_handleDiffPrefsChanged"
-            on-change="_handleDiffPrefsChanged"
-          />
+          <input id="tabSizeInput" type="number" />
         </iron-input>
       </span>
     </section>
@@ -107,23 +83,11 @@
       <label for="fontSizeInput" class="title">Font size</label>
       <span class="value">
         <iron-input
-          type="number"
-          prevent-invalid-input=""
           allowed-pattern="[0-9]"
-          bind-value="{{diffPrefs.font_size}}"
-          on-keypress="_handleDiffPrefsChanged"
-          on-change="_handleDiffPrefsChanged"
+          bind-value="[[_convertToString(diffPrefs.font_size)]]"
+          on-change="_handleDiffFontSizeChanged"
         >
-          <input
-            is="iron-input"
-            type="number"
-            id="fontSizeInput"
-            prevent-invalid-input=""
-            allowed-pattern="[0-9]"
-            bind-value="{{diffPrefs.font_size}}"
-            on-keypress="_handleDiffPrefsChanged"
-            on-change="_handleDiffPrefsChanged"
-          />
+          <input id="fontSizeInput" type="number" />
         </iron-input>
       </span>
     </section>
@@ -133,7 +97,7 @@
         <input
           id="showTabsInput"
           type="checkbox"
-          checked="[[diffPrefs.show_tabs]]"
+          checked="[[_convertToBoolean(diffPrefs.show_tabs)]]"
           on-change="_handleShowTabsTap"
         />
       </span>
@@ -146,7 +110,7 @@
         <input
           id="showTrailingWhitespaceInput"
           type="checkbox"
-          checked="[[diffPrefs.show_whitespace_errors]]"
+          checked="[[_convertToBoolean(diffPrefs.show_whitespace_errors)]]"
           on-change="_handleShowTrailingWhitespaceTap"
         />
       </span>
@@ -159,7 +123,7 @@
         <input
           id="syntaxHighlightInput"
           type="checkbox"
-          checked="[[diffPrefs.syntax_highlighting]]"
+          checked="[[_convertToBoolean(diffPrefs.syntax_highlighting)]]"
           on-change="_handleSyntaxHighlightTap"
         />
       </span>
@@ -172,7 +136,7 @@
         <input
           id="automaticReviewInput"
           type="checkbox"
-          checked="[[!diffPrefs.manual_review]]"
+          checked="[[!_convertToBoolean(diffPrefs.manual_review)]]"
           on-change="_handleAutomaticReviewTap"
         />
       </span>
@@ -181,12 +145,11 @@
       <div class="pref">
         <label for="ignoreWhiteSpace" class="title">Ignore Whitespace</label>
         <span class="value">
-          <gr-select bind-value="{{diffPrefs.ignore_whitespace}}">
-            <select
-              id="ignoreWhiteSpace"
-              on-keypress="_handleDiffPrefsChanged"
-              on-change="_handleDiffPrefsChanged"
-            >
+          <gr-select
+            bind-value="[[_convertToString(diffPrefs.ignore_whitespace)]]"
+            on-change="_handleDiffIgnoreWhitespaceChanged"
+          >
+            <select id="ignoreWhiteSpace">
               <option value="IGNORE_NONE">None</option>
               <option value="IGNORE_TRAILING">Trailing</option>
               <option value="IGNORE_LEADING_AND_TRAILING">