From d8f3dec03371f846b50d5281c70ef3a5d990cbd6 Mon Sep 17 00:00:00 2001
From: Tira Odhner <pair+aodhner@pivotal.io>
Date: Mon, 20 Mar 2017 14:58:46 -0400
Subject: [PATCH 3/3] Make hiding spinner faster and more reliable

---
 web/pgadmin/static/js/hide_spinner.js          | 73 ++++++++++++--------------
 web/regression/javascript/hide_spinner_spec.js | 40 +++++++++++++-
 2 files changed, 71 insertions(+), 42 deletions(-)

diff --git a/web/pgadmin/static/js/hide_spinner.js b/web/pgadmin/static/js/hide_spinner.js
index 8ffb0d9b..d2c7d488 100644
--- a/web/pgadmin/static/js/hide_spinner.js
+++ b/web/pgadmin/static/js/hide_spinner.js
@@ -1,48 +1,41 @@
 /*************************************************************************
-*
-* pgAdmin 4 - PostgreSQL Tools
-*
-* Copyright (C) 2013 - 2017, The pgAdmin Development Team
-* This software is released under the PostgreSQL Licence
-*
-**************************************************************************/
+ *
+ * pgAdmin 4 - PostgreSQL Tools
+ *
+ * Copyright (C) 2013 - 2017, The pgAdmin Development Team
+ * This software is released under the PostgreSQL Licence
+ *
+ **************************************************************************/
 
-window.hideRequireJsLoadingSpinner = function (context, map, depMaps) {
-  var loadingStatusEl = panel = document.getElementById('pg-spinner');
-  if (loadingStatusEl) {
-    if (!context) {
-      // we will call onResourceLoad(false) by ourselves when requirejs
-      // is not loading anything hide the indicator and exit
-      setTimeout(function() {
-        if (panel != null) {
-          $(panel).remove();
-          return;
-        }
-      }, 500);
-    }
+window.hideRequireJsLoadingSpinner = function (context) {
+  var loadingStatusEl = document.getElementById('pg-spinner');
 
-    // show indicator when any module is loaded and
-    // shedule requirejs status (loading/idle) check
-    panel.style.display = "";
-    clearTimeout(panel.ttimer);
-    panel.ttimer = setTimeout(function () {
-      var context = require.s.contexts._;
-      var inited = true;
-      for (name in context.registry) {
-        var m = context.registry[name];
-        if (m.inited !== true) {
-          inited = false;
-          break;
-        }
+  function allModulesAreLoaded() {
+    var inited = true;
+
+    for (var name in context.registry) {
+      var module = context.registry[name];
+      if (!module.inited) {
+        inited = false;
+        break;
       }
+    }
+    return inited;
+  }
+
+  function showSpinner() {
+    loadingStatusEl.style.display = "";
+  }
 
-      // here the "inited" variable will be true, if requirejs is "idle",
-      // false if "loading"
-      if (inited) {
-        // will fire if module loads in 400ms. TODO: reset this timer
-        // for slow module loading
-        hideRequireJsLoadingSpinner(false);
+  if (loadingStatusEl) {
+    // show indicator when any module is loaded and
+    // schedule requirejs status (loading/idle) check
+    showSpinner();
+    var intervalId = setInterval(function () {
+      if (allModulesAreLoaded()) {
+        $(loadingStatusEl).remove();
+        clearInterval(intervalId);
       }
-    }, 400)
+    }, 40)
   }
 };
\ No newline at end of file
diff --git a/web/regression/javascript/hide_spinner_spec.js b/web/regression/javascript/hide_spinner_spec.js
index 388bd9c5..fdd3a34d 100644
--- a/web/regression/javascript/hide_spinner_spec.js
+++ b/web/regression/javascript/hide_spinner_spec.js
@@ -14,8 +14,44 @@ define(['jquery'], function ($) {
       }
     });
 
+    describe("when a module in the registry is not done loading", function () {
+      var requireJsContext;
+      beforeEach(function () {
+        requireJsContext = {registry: {'module-a': {inited: true}, 'module-b': {inited: false}}};
+
+        jasmine.clock().install()
+      });
+
+      afterEach(function () {
+        jasmine.clock().uninstall();
+      });
+
+      it("does not hide the spinner", function () {
+        hideRequireJsLoadingSpinner(requireJsContext);
+        jasmine.clock().tick(40);
+
+        expect($('#pg-spinner').length).toBe(1);
+      });
+
+      describe("and then finishes loading", function () {
+        beforeEach(function () {
+          hideRequireJsLoadingSpinner(requireJsContext);
+          jasmine.clock().tick(40);
+        });
+
+        it('hides the spinner', function () {
+          requireJsContext.registry['module-b'].inited = true;
+          jasmine.clock().tick(40);
+          expect($('#pg-spinner').length).toBe(0);
+        });
+      });
+    });
+
     describe('when all modules in the registry are done loading', function () {
+      var requireJsContext;
       beforeEach(function () {
+        requireJsContext = {registry: {'module-a': {inited: true}, 'module-b': {inited: true}}};
+
         jasmine.clock().install()
       });
 
@@ -25,8 +61,8 @@ define(['jquery'], function ($) {
 
       it('hides the spinner', function () {
         expect($('#pg-spinner').length).toBe(1);
-        hideRequireJsLoadingSpinner();
-        jasmine.clock().tick(901);
+        hideRequireJsLoadingSpinner(requireJsContext);
+        jasmine.clock().tick(40);
 
         expect($('#pg-spinner').length).toBe(0);
       });
-- 
2.12.0

