GUI2 add in support for Preferences Service

Change-Id: Icdf2165d9f638aeff1b110a64777b93295935ed2
diff --git a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/keys.service.spec.ts b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/keys.service.spec.ts
index 5f4b349..47299e7 100644
--- a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/keys.service.spec.ts
+++ b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/keys.service.spec.ts
@@ -89,7 +89,6 @@
         });
         ks = TestBed.get(KeysService);
         ks.installOn(d3Elem);
-        ks.bindQhs(qhs);
         logServiceSpy = TestBed.get(LogService);
     });
 
@@ -103,7 +102,7 @@
 
     it('should define api functions', () => {
         expect(fs.areFunctions(ks, [
-            'bindQhs', 'installOn', 'keyBindings', 'unbindKeys', 'dialogKeys',
+            'installOn', 'keyBindings', 'unbindKeys', 'dialogKeys',
             'addSeq', 'remSeq', 'gestureNotes', 'enableKeys', 'enableGlobalKeys',
             'checkNotGlobal', 'getKeyBindings',
             'matchSeq', 'whatKey', 'textFieldInput', 'keyIn', 'qhlion', 'qhlionShowHide',
diff --git a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/keys.service.ts b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/keys.service.ts
index decb87b..035037e 100644
--- a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/keys.service.ts
+++ b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/keys.service.ts
@@ -59,7 +59,7 @@
         enter: 1,
         esc: 1,
     };
-    qhs: any; // Quick Help Service ??
+    quickHelpShown: boolean = false;
 
     constructor(
         protected log: LogService,
@@ -70,10 +70,6 @@
         this.log.debug('KeyService constructed');
     }
 
-    bindQhs(_qhs_) {
-        this.qhs = _qhs_;
-    }
-
     installOn(elem) {
         this.log.debug('Installing keys handler');
         elem.on('keydown', () => { this.keyIn(); });
@@ -314,14 +310,14 @@
         if (!this.globalEnabled) {
             return false;
         }
-        this.qhs.showQuickHelp(this.keyHandler);
+        this.quickHelpShown = !this.quickHelpShown;
         return true;
     }
 
     // returns true if we 'consumed' the ESC keypress, false otherwise
     protected escapeKey(view, key, code, ev) {
+        this.quickHelpShown = false;
         return this.ns.hideNav();
-        // TODO - also hide this.qhs.hideQuickHelp();
     }
 
     protected toggleTheme(view, key, code, ev) {
diff --git a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/prefs.service.spec.ts b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/prefs.service.spec.ts
index d925ecf..13892af 100644
--- a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/prefs.service.spec.ts
+++ b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/prefs.service.spec.ts
@@ -35,6 +35,19 @@
  */
 describe('PrefsService', () => {
     let log: LogService;
+    let windowMock: Window;
+
+    windowMock = <any>{
+        location: <any> {
+            hostname: 'foo',
+            host: 'foo',
+            port: '80',
+            protocol: 'http',
+            search: { debug: 'true'},
+            href: 'ws://foo:123/onos/ui/websock/path',
+            absUrl: 'ws://foo:123/onos/ui/websock/path'
+        }
+    };
 
     beforeEach(() => {
         log = new ConsoleLoggerService();
@@ -43,6 +56,7 @@
             providers: [PrefsService,
                 { provide: LogService, useValue: log },
                 { provide: FnService, useClass: MockFnService },
+                { provide: 'Window', useFactory: (() => windowMock ) },
                 { provide: WebSocketService, useClass: MockWebSocketService },
             ]
         });
diff --git a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/prefs.service.ts b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/prefs.service.ts
index 8145921..b68b4dd 100644
--- a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/prefs.service.ts
+++ b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/prefs.service.ts
@@ -13,11 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import { Injectable } from '@angular/core';
+import {Inject, Injectable} from '@angular/core';
 import { FnService } from './fn.service';
 import { LogService } from '../log.service';
 import { WebSocketService } from '../remote/websocket.service';
 
+const UPDATE_PREFS: string = 'updatePrefs';
+const UPDATE_PREFS_REQ: string = 'updatePrefReq';
 /**
  * ONOS GUI -- Util -- User Preference Service
  */
@@ -25,32 +27,36 @@
     providedIn: 'root',
 })
 export class PrefsService {
-    protected Prefs;
     protected handlers: string[] = [];
-    cache: any;
-    listeners: any;
+    cache: Object;
+    listeners: ((data) => void)[] = [];
     constructor(
         protected fs: FnService,
         protected log: LogService,
-        protected wss: WebSocketService
+        protected wss: WebSocketService,
+        @Inject('Window') private window: any
     ) {
-        this.cache = {};
         this.wss.bindHandlers(new Map<string, (data) => void>([
-            [this.Prefs, (data) => this.updatePrefs(data)]
+            [UPDATE_PREFS, (data) => this.updatePrefs(data)]
         ]));
-        this.handlers.push(this.Prefs);
+        this.handlers.push(UPDATE_PREFS);
+
+        // When index.html is fetched it is served up by MainIndexResource.java
+        // which fetches userPrefs in to the global scope.
+        // After that updates are done through WebSocket
+        this.cache = Object.assign({}, this.window['userPrefs']);
 
         this.log.debug('PrefsService constructed');
     }
 
-    setPrefs(name: string, obj: any) {
+    setPrefs(name: string, obj: Object) {
         // keep a cached copy of the object and send an update to server
         this.cache[name] = obj;
-        this.wss.sendEvent('updatePrefReq', { key: name, value: obj });
+        this.wss.sendEvent(UPDATE_PREFS_REQ, { key: name, value: obj });
     }
     updatePrefs(data: any) {
         this.cache = data;
-        this.listeners.forEach(function (lsnr) { lsnr(); });
+        this.listeners.forEach((lsnr) => lsnr(data) );
     }
 
     asNumbers(obj: any, keys?: any, not?: any) {
@@ -101,17 +107,22 @@
     //  defined keys should overwrite the corresponding values, but any
     //  existing keys that are NOT explicitly defined here should be left
     //  alone (not deleted).
-    mergePrefs(name: string, obj: any) {
+    mergePrefs(name: string, obj: any): void {
         const merged = this.cache[name] || {};
         this.setPrefs(name, Object.assign(merged, obj));
     }
 
-    addListener(listener: any) {
+    /**
+     * Add a listener function
+     * This will get called back when an 'updatePrefs' message is received on WSS
+     * @param listener a function that can accept one param - data
+     */
+    addListener(listener: (data) => void): void {
         this.listeners.push(listener);
     }
 
-    removeListener(listener: any) {
-        this.listeners = this.listeners.filter(function (obj) { return obj === listener; });
+    removeListener(listener: (data) => void) {
+        this.listeners = this.listeners.filter((obj) => obj !== listener);
     }
 
 }