Low-level helper plugin API for data binding

Utility wrapper for tracking Polymer element properties updates.

Usage example:

``` js
Gerrit.install(plugin => {
  plugin.getDomHook('change-view').onAttached(element => {
    if (!element.content) { return; }
    plugin.attributeHelper(element.content)
      .get('change')
      .then(change => {
        // Is executed once on switching to change view.
      });
    });

  plugin.getDomHook('reply-text').onAttached(element => {
    if (!element.content) { return; }
    plugin.attributeHelper(element.content)
      .bind('text', replyText => {
        // Is called every time reply text changes.
      });
    });

  });
```

Change-Id: Ia95364df58489f71ea1fd591a160b73ac1d60e96
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.html b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.html
index f73f731..f6e2b64 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.html
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.html
@@ -17,6 +17,7 @@
 <link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
 <link rel="import" href="../../../behaviors/gr-patch-set-behavior/gr-patch-set-behavior.html">
 <link rel="import" href="../../core/gr-reporting/gr-reporting.html">
+<link rel="import" href="../../plugins/gr-attribute-helper/gr-attribute-helper.html">
 <link rel="import" href="../../plugins/gr-dom-hooks/gr-dom-hooks.html">
 <link rel="import" href="../../plugins/gr-theme-api/gr-theme-api.html">
 <link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface_test.html b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface_test.html
index 1236ca4..ca0f372 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface_test.html
@@ -318,6 +318,10 @@
       }
     });
 
+    test('attributeHelper', () => {
+      assert.isOk(plugin.attributeHelper());
+    });
+
     suite('test plugin with base url', () => {
       setup(() => {
         sandbox.stub(Gerrit.BaseUrlBehavior, 'getBaseUrl').returns('/r');
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-public-js-api.js b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-public-js-api.js
index 97b67ae..a631c2f 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-public-js-api.js
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-public-js-api.js
@@ -158,6 +158,10 @@
     return new GrThemeApi(this);
   };
 
+  Plugin.prototype.attributeHelper = function(element) {
+    return new GrAttributeHelper(element);
+  };
+
   Plugin.prototype.getDomHook = function(endpointName, opt_options) {
     const hook = this._domHooks.getDomHook(endpointName);
     const moduleName = hook.getModuleName();