From dde21c33f555462c557f32a6b74f234af102b716 Mon Sep 17 00:00:00 2001
From: Dan Clarizio <dclarizi@redhat.com>
Date: Mon, 1 May 2017 09:09:10 -0700
Subject: [PATCH] Merge pull request #1197 from eclarizio/BZ1442811

Fix for Service Catalogs: Dialogs are hanging and keeps buffering
(cherry picked from commit 27a33c9070c1dbb1ef54a8e8c204c3159fe0dde6)

https://bugzilla.redhat.com/show_bug.cgi?id=1447088
---
 .../javascripts/dialog_field_refresh.js       | 20 +++---
 .../dialogs/_dialog_provision.html.haml       |  4 ++
 spec/javascripts/dialog_field_refresh_spec.js | 61 +++++++++++++++++--
 3 files changed, 71 insertions(+), 14 deletions(-)

diff --git a/app/assets/javascripts/dialog_field_refresh.js b/app/assets/javascripts/dialog_field_refresh.js
index 14dfaa3167a..e3e5d6102f4 100644
--- a/app/assets/javascripts/dialog_field_refresh.js
+++ b/app/assets/javascripts/dialog_field_refresh.js
@@ -1,16 +1,20 @@
 /* global miqInitSelectPicker miqSelectPickerEvent miqSparkle miqSparkleOn */
 
 var dialogFieldRefresh = {
+  unbindAllPreviousListeners: function() {
+    $(document).off('dialog::autoRefresh');
+  },
+
   listenForAutoRefreshMessages: function(autoRefreshOptions, callbackFunction) {
-    var thisIsTheFieldToUpdate = function(event) {
-      var tabIndex = event.data.tabIndex;
-      var groupIndex = event.data.groupIndex;
-      var fieldIndex = event.data.fieldIndex;
+    var thisIsTheFieldToUpdate = function(data) {
+      var tabIndex = data.tabIndex;
+      var groupIndex = data.groupIndex;
+      var fieldIndex = data.fieldIndex;
       return tabIndex === autoRefreshOptions.tab_index && groupIndex === autoRefreshOptions.group_index && fieldIndex === autoRefreshOptions.field_index;
     };
 
-    window.addEventListener('message', function(event) {
-      if (thisIsTheFieldToUpdate(event)) {
+    $(document).on('dialog::autoRefresh', function(_event, data) {
+      if (thisIsTheFieldToUpdate(data)) {
         callbackFunction.call();
       }
     });
@@ -181,11 +185,11 @@ var dialogFieldRefresh = {
       nextAvailable = nextAvailable[0];
 
       if (nextAvailable !== undefined) {
-        parent.postMessage({
+        $(document).trigger('dialog::autoRefresh', {
           tabIndex: nextAvailable.tab_index,
           groupIndex: nextAvailable.group_index,
           fieldIndex: nextAvailable.field_index,
-        }, '*');
+        });
       }
     }
   },
diff --git a/app/views/shared/dialogs/_dialog_provision.html.haml b/app/views/shared/dialogs/_dialog_provision.html.haml
index 5ea50fda212..0f7cfb1da41 100644
--- a/app/views/shared/dialogs/_dialog_provision.html.haml
+++ b/app/views/shared/dialogs/_dialog_provision.html.haml
@@ -1,5 +1,9 @@
 - wf = @edit[:wf] if @edit && @edit[:wf]
 = render :partial => "layouts/flash_msg"
+
+:javascript
+  dialogFieldRefresh.unbindAllPreviousListeners();
+
 .row
   .col-md-12.col-lg-12
     #dialog_tabs
diff --git a/spec/javascripts/dialog_field_refresh_spec.js b/spec/javascripts/dialog_field_refresh_spec.js
index 54f5e59ec0d..06792d9a1e2 100644
--- a/spec/javascripts/dialog_field_refresh_spec.js
+++ b/spec/javascripts/dialog_field_refresh_spec.js
@@ -1,4 +1,53 @@
 describe('dialogFieldRefresh', function() {
+  describe('#listenForAutoRefreshMessages', function() {
+    context('when an autoRefresh event gets triggered', function() {
+      var callback;
+      var autoRefreshOptions;
+
+      beforeEach(function() {
+        callback = jasmine.createSpyObj('callback', ['call']);
+        autoRefreshOptions = {
+          tab_index: 1,
+          group_index: 2,
+          field_index: 3
+        };
+        dialogFieldRefresh.listenForAutoRefreshMessages(autoRefreshOptions, callback);
+      });
+
+      context('when the tab index, group index, and field index match the corresponding field', function() {
+        beforeEach(function() {
+          $(document).trigger('dialog::autoRefresh', {tabIndex: 1, groupIndex: 2, fieldIndex: 3});
+        });
+
+        it('executes the callback', function() {
+          expect(callback.call).toHaveBeenCalled();
+        });
+      });
+
+      context('when the tab index, group index, and field index do not match the corresponding field', function() {
+        beforeEach(function() {
+          $(document).trigger('dialog::autoRefresh', {tabIndex: 1, groupIndex: 1, fieldIndex: 3});
+        });
+
+        it('does not execute the callback', function() {
+          expect(callback.call).not.toHaveBeenCalled();
+        });
+      });
+    });
+  });
+
+  describe('#unbindAllPreviousListeners', function() {
+    beforeEach(function() {
+      spyOn($.fn, 'off');
+    });
+
+    it('unbinds all autoRefresh messages from the document', function() {
+      dialogFieldRefresh.unbindAllPreviousListeners();
+      expect($.fn.off.calls.mostRecent().object).toEqual(document);
+      expect($.fn.off).toHaveBeenCalledWith('dialog::autoRefresh');
+    });
+  });
+
   describe('#addOptionsToDropDownList', function() {
     var data = {};
 
@@ -581,13 +630,13 @@ describe('dialogFieldRefresh', function() {
 
   describe('#triggerAutoRefresh', function() {
     beforeEach(function() {
-      spyOn(parent, 'postMessage');
+      spyOn($.fn, 'trigger');
     });
 
     context('when the trigger passed in falsy', function() {
       it('does not post any messages', function() {
         dialogFieldRefresh.triggerAutoRefresh({trigger: ""});
-        expect(parent.postMessage).not.toHaveBeenCalled();
+        expect($.fn.trigger).not.toHaveBeenCalled();
       });
     });
 
@@ -602,7 +651,7 @@ describe('dialogFieldRefresh', function() {
         });
 
         it('does not post a message', function() {
-          expect(parent.postMessage).not.toHaveBeenCalled();
+          expect($.fn.trigger).not.toHaveBeenCalled();
         });
       });
 
@@ -619,7 +668,7 @@ describe('dialogFieldRefresh', function() {
         });
 
         it('posts a message', function() {
-          expect(parent.postMessage).toHaveBeenCalledWith({tabIndex: 1, groupIndex: 1, fieldIndex: 2}, '*');
+          expect($.fn.trigger).toHaveBeenCalledWith('dialog::autoRefresh', {tabIndex: 1, groupIndex: 1, fieldIndex: 2});
         });
       });
     });
@@ -635,7 +684,7 @@ describe('dialogFieldRefresh', function() {
         });
 
         it('does not post a message', function() {
-          expect(parent.postMessage).not.toHaveBeenCalled();
+          expect($.fn.trigger).not.toHaveBeenCalled();
         });
       });
 
@@ -652,7 +701,7 @@ describe('dialogFieldRefresh', function() {
         });
 
         it('posts a message', function() {
-          expect(parent.postMessage).toHaveBeenCalledWith({tabIndex: 1, groupIndex: 1, fieldIndex: 2}, '*');
+          expect($.fn.trigger).toHaveBeenCalledWith('dialog::autoRefresh', {tabIndex: 1, groupIndex: 1, fieldIndex: 2});
         });
       });
     });