Fix SoL and KVM refresh bug

Clicking the refresh button in the app header on the SoL and
KVM pages would fail to reload because the wrong element reference
is passed to the contructor after the reload. Angular recommends
using directives for any DOM manipulation.

- Use the $element ref availble in serial-console.js directive to
  select DOM element to open the terminal
- Switch kvm controller to directive to be able to use element ref
  in the link function to select DOM element to pass as target

Signed-off-by: Yoshie Muranaka <yoshiemuranaka@gmail.com>
Change-Id: Ia7391e42bf335b8c3558d25df15c052db245ee3d
diff --git a/app/common/directives/serial-console.js b/app/common/directives/serial-console.js
index 045503d..0a821db 100644
--- a/app/common/directives/serial-console.js
+++ b/app/common/directives/serial-console.js
@@ -55,8 +55,8 @@
         'template': require('./serial-console.html'),
         'scope': {'path': '=', 'showTabBtn': '=?'},
         'controller': [
-          '$scope', '$window', 'dataService',
-          function($scope, $window, dataService) {
+          '$scope', '$window', 'dataService', '$element',
+          function($scope, $window, dataService, $element) {
             $scope.dataService = dataService;
 
             // See https://github.com/xtermjs/xterm.js/ for available xterm
@@ -67,7 +67,8 @@
 
             var border = 10;
             var term = new Terminal();
-            var terminal = document.getElementById('terminal');
+            // Should be a reference to <div id="terminal"></div>
+            var terminal = $element[0].firstElementChild.firstElementChild;
             var customConsole;
             var charSize;
             var termContainer;
diff --git a/app/index.js b/app/index.js
index 66ebdb7..fa1d017 100644
--- a/app/index.js
+++ b/app/index.js
@@ -84,8 +84,8 @@
 import power_usage_controller from './server-control/controllers/power-usage-controller.js';
 import remote_console_window_controller from './server-control/controllers/remote-console-window-controller.js';
 import server_led_controller from './server-control/controllers/server-led-controller.js';
-import kvm_controller from './server-control/controllers/kvm-controller.js';
 import vm_controller from './server-control/controllers/virtual-media-controller.js';
+import kvm_console from './server-control/directives/kvm-console.js';
 
 import server_health_index from './server-health/index.js';
 import inventory_overview_controller from './server-health/controllers/inventory-overview-controller.js';
diff --git a/app/server-control/controllers/kvm-controller.html b/app/server-control/controllers/kvm-controller.html
index 40e4d97..2b30c99 100644
--- a/app/server-control/controllers/kvm-controller.html
+++ b/app/server-control/controllers/kvm-controller.html
@@ -1,5 +1 @@
-<div id="noVNC_container">
-    <div id="noVNC_status_bar">
-        <div id="noVNC_left_dummy_elem"></div>
-    </div>
-</div>
+<kvm-console></kvm-console>
\ No newline at end of file
diff --git a/app/server-control/controllers/kvm-controller.js b/app/server-control/controllers/kvm-controller.js
deleted file mode 100644
index a43f169..0000000
--- a/app/server-control/controllers/kvm-controller.js
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * Controller for KVM (Kernel-based Virtual Machine)
- *
- * @module app/serverControl
- * @exports kvmController
- * @name kvmController
- */
-
-import RFB from '@novnc/novnc/core/rfb.js';
-
-window.angular && (function(angular) {
-  'use strict';
-
-  angular.module('app.serverControl').controller('kvmController', [
-    '$scope', '$location', '$log',
-    function($scope, $location, $log) {
-      var rfb;
-
-      $scope.$on('$destroy', function() {
-        if (rfb) {
-          rfb.disconnect();
-        }
-      });
-
-      function sendCtrlAltDel() {
-        rfb.sendCtrlAltDel();
-        return false;
-      };
-
-      function connected(e) {
-        $log.debug('RFB Connected');
-      }
-      function disconnected(e) {
-        $log.debug('RFB disconnected');
-      }
-
-      var host = $location.host();
-      var port = $location.port();
-      var target =
-          angular.element(document.querySelector('#noVNC_container'))[0];
-
-      try {
-        rfb = new RFB(target, 'wss://' + host + ':' + port + '/kvm/0', {});
-
-        rfb.addEventListener('connect', connected);
-        rfb.addEventListener('disconnect', disconnected);
-      } catch (exc) {
-        $log.error(exc);
-        updateState(
-            null, 'fatal', null, 'Unable to create RFB client -- ' + exc);
-        return;  // don't continue trying to connect
-      };
-    }
-  ]);
-})(angular);
diff --git a/app/server-control/directives/kvm-console.html b/app/server-control/directives/kvm-console.html
new file mode 100644
index 0000000..40e4d97
--- /dev/null
+++ b/app/server-control/directives/kvm-console.html
@@ -0,0 +1,5 @@
+<div id="noVNC_container">
+    <div id="noVNC_status_bar">
+        <div id="noVNC_left_dummy_elem"></div>
+    </div>
+</div>
diff --git a/app/server-control/directives/kvm-console.js b/app/server-control/directives/kvm-console.js
new file mode 100644
index 0000000..224e5d2
--- /dev/null
+++ b/app/server-control/directives/kvm-console.js
@@ -0,0 +1,60 @@
+/**
+ * Directive for KVM (Kernel-based Virtual Machine)
+ *
+ * @module app/serverControl
+ * @exports kvmConsole
+ * @name kvmConsole
+ */
+
+import RFB from '@novnc/novnc/core/rfb.js';
+
+window.angular && (function(angular) {
+  'use strict';
+
+  angular.module('app.serverControl').directive('kvmConsole', [
+    '$log', '$location',
+    function($log, $location) {
+      return {
+        restrict: 'E', template: require('./kvm-console.html'),
+            link: function(scope, element) {
+              var rfb;
+
+              element.on('$destroy', function() {
+                if (rfb) {
+                  rfb.disconnect();
+                }
+              });
+
+              function sendCtrlAltDel() {
+                rfb.sendCtrlAltDel();
+                return false;
+              };
+
+              function connected(e) {
+                $log.debug('RFB Connected');
+              }
+              function disconnected(e) {
+                $log.debug('RFB disconnected');
+              }
+
+              var host = $location.host();
+              var port = $location.port();
+              var target = element[0].firstElementChild;
+              try {
+                rfb = new RFB(
+                    target, 'wss://' + host + ':' + port + '/kvm/0', {});
+
+                rfb.addEventListener('connect', connected);
+                rfb.addEventListener('disconnect', disconnected);
+              } catch (exc) {
+                $log.error(exc);
+                updateState(
+                    null, 'fatal', null,
+                    'Unable to create RFB client -- ' + exc);
+                return;  // don't continue trying to connect
+              };
+            }
+      }
+    }
+  ]);
+})(window.angular);
diff --git a/app/server-control/index.js b/app/server-control/index.js
index 8bf03b4..8b8b215 100644
--- a/app/server-control/index.js
+++ b/app/server-control/index.js
@@ -50,7 +50,6 @@
               })
               .when('/server-control/kvm', {
                 'template': require('./controllers/kvm-controller.html'),
-                'controller': 'kvmController',
                 authenticated: true
               })
               .when('/server-control/virtual-media', {