[pgAdmin][RM4756] pgAdmin does not load completely if loaded in an iframe

Aditya Toshniwal <[email protected]>
Newsgroups gmane.comp.db.postgresql.pgadmin.devel
Message-ID <CAM9w-_mE0vFVXUWeAXGLV7b-ocw8KiA+fLSwq=YBA0XGiqWATA@mail.gmail.com>
Hi Hackers,

Attached is the patch to allow pgAdmin to open in iframe. This patch also
fixes #4561 (which was rejected :P) where pgAdmin was not working when
opened using an html link and not directly.

The RM has a sample html file to test things.
Kindly review.

-- 
Thanks and Regards,
Aditya Toshniwal
Software Engineer | EnterpriseDB India | Pune
"Don't Complain about Heat, Plant a TREE"
RM4756.patch (application/octet-stream, 21.4 KB)
diff --git a/web/pgadmin/browser/static/js/browser.js b/web/pgadmin/browser/static/js/browser.js
index 38252887..f492a1f5 100644
--- a/web/pgadmin/browser/static/js/browser.js
+++ b/web/pgadmin/browser/static/js/browser.js
@@ -12,7 +12,7 @@ define('pgadmin.browser', [
   'sources/gettext', 'sources/url_for', 'require', 'jquery', 'underscore', 'underscore.string',
   'bootstrap', 'sources/pgadmin', 'pgadmin.alertifyjs', 'bundled_codemirror',
   'sources/check_node_visibility', './toolbar', 'pgadmin.help',
-  'sources/csrf', 'sources/utils', 'pgadmin.browser.utils',
+  'sources/csrf', 'sources/utils', 'sources/window', 'pgadmin.browser.utils',
   'wcdocker', 'jquery.contextmenu', 'jquery.aciplugin', 'jquery.acitree',
   'pgadmin.browser.preferences', 'pgadmin.browser.messages',
   'pgadmin.browser.menu', 'pgadmin.browser.panel', 'pgadmin.browser.layout',
@@ -24,7 +24,7 @@ define('pgadmin.browser', [
   tree,
   gettext, url_for, require, $, _, S,
   Bootstrap, pgAdmin, Alertify, codemirror,
-  checkNodeVisibility, toolBar, help, csrfToken, pgadminUtils,
+  checkNodeVisibility, toolBar, help, csrfToken, pgadminUtils, pgWindow
 ) {
   window.jQuery = window.$ = $;
   // Some scripts do export their object in the window only.
@@ -714,8 +714,7 @@ define('pgadmin.browser', [
     bind_beforeunload: function() {
       $(window).on('beforeunload', function(e) {
         /* Can open you in new tab */
-        let openerBrowser = window.opener ?
-          window.opener.pgAdmin.Browser : window.top.pgAdmin.Browser;
+        let openerBrowser = pgWindow.default.pgAdmin.Browser;
 
         let tree_save_interval = pgBrowser.get_preference('browser', 'browser_tree_state_save_interval'),
           confirm_on_refresh_close = openerBrowser.get_preference('browser', 'confirm_on_refresh_close');
diff --git a/web/pgadmin/browser/static/js/layout.js b/web/pgadmin/browser/static/js/layout.js
index a4aaa0e7..36669783 100644
--- a/web/pgadmin/browser/static/js/layout.js
+++ b/web/pgadmin/browser/static/js/layout.js
@@ -13,6 +13,7 @@ import $ from 'jquery';
 import * as Alertify from 'pgadmin.alertifyjs';
 import gettext from 'sources/gettext';
 import 'wcdocker';
+import pgWindow from 'sources/window';
 
 const pgBrowser = pgAdmin.Browser = pgAdmin.Browser || {};
 
@@ -74,8 +75,7 @@ _.extend(pgBrowser, {
     }
 
     /* preference available only with top/opener browser. */
-    let browser = window.opener ?
-      window.opener.pgAdmin.Browser : window.top.pgAdmin.Browser;
+    let browser = pgWindow.pgAdmin.Browser;
 
     /* interval required initially as preference load may take time */
     let cacheIntervalId = setInterval(()=> {
@@ -93,8 +93,7 @@ _.extend(pgBrowser, {
   },
 
   reflectLocklayoutChange: function(docker) {
-    let browser = window.opener ?
-      window.opener.pgAdmin.Browser : window.top.pgAdmin.Browser;
+    let browser = pgWindow.pgAdmin.Browser;
 
     let browserPref = browser.get_preferences_for_module('browser');
     browser.lock_layout(docker, browserPref.lock_layout);
@@ -125,8 +124,7 @@ _.extend(pgBrowser, {
   },
 
   save_lock_layout: function(op) {
-    let browser = window.opener ?
-      window.opener.pgAdmin.Browser : window.top.pgAdmin.Browser;
+    let browser = pgWindow.pgAdmin.Browser;
 
     $.ajax({
       url: url_for('browser.lock_layout'),
diff --git a/web/pgadmin/browser/static/js/preferences.js b/web/pgadmin/browser/static/js/preferences.js
index 680d18f4..00f566fc 100644
--- a/web/pgadmin/browser/static/js/preferences.js
+++ b/web/pgadmin/browser/static/js/preferences.js
@@ -12,6 +12,7 @@ import url_for from 'sources/url_for';
 import $ from 'jquery';
 import * as Alertify from 'pgadmin.alertifyjs';
 import * as SqlEditorUtils from 'sources/sqleditor_utils';
+import pgWindow from 'sources/window';
 
 var modifyAnimation = require('sources/modify_animation');
 
@@ -148,16 +149,8 @@ _.extend(pgBrowser, {
   },
 
   onPreferencesChange: function(module, eventHandler) {
-    window.parent.$(parent.document).on('prefchange:'+module, function(event) {
-      /* If a sqleditor is closed, event handler will be called
-       * but the window.top will be null. Unbind the event handler
-       */
-      if(window.top === null) {
-        window.$(document).off(event);
-      }
-      else {
-        eventHandler(event);
-      }
+    $(pgWindow).on('prefchange:'+module, function(event) {
+      eventHandler(event);
     });
   },
 
diff --git a/web/pgadmin/dashboard/static/js/dashboard.js b/web/pgadmin/dashboard/static/js/dashboard.js
index 77572618..39132dd5 100644
--- a/web/pgadmin/dashboard/static/js/dashboard.js
+++ b/web/pgadmin/dashboard/static/js/dashboard.js
@@ -11,10 +11,10 @@ define('pgadmin.dashboard', [
   'sources/url_for', 'sources/gettext', 'require', 'jquery', 'underscore',
   'sources/pgadmin', 'backbone', 'backgrid', './charting',
   'pgadmin.alertifyjs', 'pgadmin.backform', 'sources/nodes/dashboard',
-  'sources/utils', 'pgadmin.browser', 'bootstrap', 'wcdocker',
+  'sources/utils', 'sources/window', 'pgadmin.browser', 'bootstrap', 'wcdocker',
 ], function(
   url_for, gettext, r, $, _, pgAdmin, Backbone, Backgrid, charting,
-  Alertify, Backform, NodesDashboard, commonUtils
+  Alertify, Backform, NodesDashboard, commonUtils, pgWindow
 ) {
 
   pgAdmin.Browser = pgAdmin.Browser || {};
@@ -770,7 +770,7 @@ define('pgadmin.dashboard', [
        */
       let cacheIntervalId = setInterval(function() {
         try {
-          if(window.top.pgAdmin.Browser.preference_version() > 0) {
+          if(pgWindow.default.pgAdmin.Browser.preference_version() > 0) {
             clearInterval(cacheIntervalId);
             self.reflectPreferences();
           }
@@ -794,10 +794,10 @@ define('pgadmin.dashboard', [
       /* We will use old preferences for selective graph updates on preference change */
       if(self.preferences) {
         self.old_preferences = self.preferences;
-        self.preferences = window.top.pgAdmin.Browser.get_preferences_for_module('dashboards');
+        self.preferences = pgWindow.default.pgAdmin.Browser.get_preferences_for_module('dashboards');
       }
       else {
-        self.preferences = window.top.pgAdmin.Browser.get_preferences_for_module('dashboards');
+        self.preferences = pgWindow.default.pgAdmin.Browser.get_preferences_for_module('dashboards');
         self.old_preferences = self.preferences;
       }
 
diff --git a/web/pgadmin/static/js/backform.pgadmin.js b/web/pgadmin/static/js/backform.pgadmin.js
index 33d264ab..559a4dd5 100644
--- a/web/pgadmin/static/js/backform.pgadmin.js
+++ b/web/pgadmin/static/js/backform.pgadmin.js
@@ -10,10 +10,10 @@
 define([
   'sources/gettext', 'underscore', 'underscore.string', 'jquery',
   'backbone', 'backform', 'backgrid', 'codemirror', 'sources/sqleditor_utils',
-  'sources/keyboard_shortcuts',
+  'sources/keyboard_shortcuts', 'sources/window',
   'spectrum', 'pgadmin.backgrid', 'select2', 'bootstrap.toggle',
 ], function(gettext, _, S, $, Backbone, Backform, Backgrid, CodeMirror,
-  SqlEditorUtils, keyboardShortcuts) {
+  SqlEditorUtils, keyboardShortcuts, pgWindow) {
 
   var pgAdmin = (window.pgAdmin = window.pgAdmin || {}),
     pgBrowser = pgAdmin.Browser;
@@ -1303,7 +1303,7 @@ define([
 
       let tmp_browser = pgBrowser;
       if (pgBrowser.preferences_cache.length == 0)
-        tmp_browser = window.opener ? window.opener.pgAdmin.Browser : window.top.pgAdmin.Browser;
+        tmp_browser = pgWindow.default.pgAdmin.Browser;
 
       let preferences = tmp_browser.get_preferences_for_module('browser');
 
@@ -1602,7 +1602,7 @@ define([
 
       let tmp_browser = pgBrowser;
       if (pgBrowser.preferences_cache.length == 0)
-        tmp_browser = window.opener ? window.opener.pgAdmin.Browser : window.top.pgAdmin.Browser;
+        tmp_browser = pgWindow.default.pgAdmin.Browser;
 
       let preferences = tmp_browser.get_preferences_for_module('browser');
 
@@ -2383,8 +2383,7 @@ define([
         /* This control is used by filter dialog in query editor, so taking preferences from window
          * SQL Editor can be in different tab
          */
-        let browser = window.opener ?
-          window.opener.pgAdmin.Browser : window.top.pgAdmin.Browser;
+        let browser = pgWindow.default.pgAdmin.Browser;
 
         let sqlEditPreferences = browser.get_preferences_for_module('sqleditor');
 
diff --git a/web/pgadmin/static/js/modify_animation.js b/web/pgadmin/static/js/modify_animation.js
index 420c9433..8852ecd0 100644
--- a/web/pgadmin/static/js/modify_animation.js
+++ b/web/pgadmin/static/js/modify_animation.js
@@ -9,13 +9,10 @@
 
 import $ from 'jquery';
 import _ from 'underscore';
+import pgWindow from 'sources/window';
 
 function getBrowserInstance() {
-  if (!_.isUndefined(window.opener) && !_.isNull(window.opener)) {
-    return window.opener.pgAdmin.Browser;
-  } else {
-    return window.parent.pgAdmin.Browser;
-  }
+  return pgWindow.pgAdmin.Browser;
 }
 
 function modifyAcitreeAnimation(pgBrowser, tree) {
diff --git a/web/pgadmin/static/js/selection/xcell_selection_model.js b/web/pgadmin/static/js/selection/xcell_selection_model.js
index 9a9a66f3..cfb7bded 100644
--- a/web/pgadmin/static/js/selection/xcell_selection_model.js
+++ b/web/pgadmin/static/js/selection/xcell_selection_model.js
@@ -11,9 +11,9 @@ define([
   'jquery',
   'underscore',
   'sources/selection/range_selection_helper',
-
+  'sources/window',
   'slickgrid',
-], function ($, _, RangeSelectionHelper) {
+], function ($, _, RangeSelectionHelper, pgWindow) {
   var XCellSelectionModel = function (options) {
 
     var KEY_ARROW_RIGHT = 39;
@@ -50,7 +50,7 @@ define([
       grid.registerPlugin(_selector);
       _selector.onCellRangeSelected.subscribe(handleCellRangeSelected);
       _selector.onBeforeCellRangeSelected.subscribe(handleBeforeCellRangeSelected);
-      $(window.parent).on('mouseup',handleWindowMouseUp);
+      $(pgWindow.default).on('mouseup',handleWindowMouseUp);
     }
 
     function destroy() {
@@ -59,7 +59,7 @@ define([
       _selector.onCellRangeSelected.unsubscribe(handleCellRangeSelected);
       _selector.onBeforeCellRangeSelected.unsubscribe(handleBeforeCellRangeSelected);
       _grid.unregisterPlugin(_selector);
-      $(window.parent).off('mouseup', handleWindowMouseUp);
+      $(pgWindow.default).off('mouseup', handleWindowMouseUp);
     }
 
     function removeInvalidRanges(ranges) {
diff --git a/web/pgadmin/static/js/sqleditor/query_tool_actions.js b/web/pgadmin/static/js/sqleditor/query_tool_actions.js
index 34b6827a..c804ff45 100644
--- a/web/pgadmin/static/js/sqleditor/query_tool_actions.js
+++ b/web/pgadmin/static/js/sqleditor/query_tool_actions.js
@@ -8,6 +8,7 @@
 //////////////////////////////////////////////////////////////
 
 import $ from 'jquery';
+import pgWindow from 'sources/window';
 
 let queryToolActions = {
   _verbose: function () {
@@ -124,7 +125,7 @@ let queryToolActions = {
 
   focusOut: function () {
     document.activeElement.blur();
-    window.top.document.activeElement.blur();
+    pgWindow.document.activeElement.blur();
   },
 
   toggleCaseOfSelectedText: function (sqlEditorController) {
diff --git a/web/pgadmin/static/js/window.js b/web/pgadmin/static/js/window.js
new file mode 100644
index 00000000..5969b93a
--- /dev/null
+++ b/web/pgadmin/static/js/window.js
@@ -0,0 +1,28 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2019, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+let pgWindow = function() {
+  let pgWindow = null;
+  try {
+    if(window.opener && window.opener.pgAdmin) {
+      pgWindow = window.opener;
+    } else if(window.parent && window.parent.pgAdmin){
+      pgWindow = window.parent;
+    } else if(window.top && window.top.pgAdmin){
+      pgWindow = window.top;
+    } else {
+      pgWindow = window;
+    }
+  } catch (error) {
+    pgWindow = window;
+  }
+  return pgWindow;
+}();
+
+export default pgWindow;
diff --git a/web/pgadmin/tools/debugger/static/js/debugger_ui.js b/web/pgadmin/tools/debugger/static/js/debugger_ui.js
index f05a22dc..4c95d7c1 100644
--- a/web/pgadmin/tools/debugger/static/js/debugger_ui.js
+++ b/web/pgadmin/tools/debugger/static/js/debugger_ui.js
@@ -10,9 +10,9 @@
 define([
   'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'backbone',
   'pgadmin.alertifyjs', 'sources/pgadmin', 'pgadmin.browser',
-  'pgadmin.backgrid', 'wcdocker',
+  'pgadmin.backgrid', 'sources/window', 'wcdocker',
 ], function(
-  gettext, url_for, $, _, Backbone, Alertify, pgAdmin, pgBrowser, Backgrid
+  gettext, url_for, $, _, Backbone, Alertify, pgAdmin, pgBrowser, Backgrid, pgWindow
 ) {
 
   var wcDocker = window.wcDocker;
@@ -168,7 +168,7 @@ define([
       Alertify.dialog('debuggerInputArgsDialog', function factory() {
         return {
           main: function(title, debug_info, restart_debug, is_edb_proc, trans_id) {
-            this.preferences = window.top.pgAdmin.Browser.get_preferences_for_module('debugger');
+            this.preferences = pgWindow.default.pgAdmin.Browser.get_preferences_for_module('debugger');
             this.set('title', title);
 
             // setting value in alertify settings allows us to access it from
diff --git a/web/pgadmin/tools/debugger/static/js/direct.js b/web/pgadmin/tools/debugger/static/js/direct.js
index b7ee19c8..96a0eaa5 100644
--- a/web/pgadmin/tools/debugger/static/js/direct.js
+++ b/web/pgadmin/tools/debugger/static/js/direct.js
@@ -12,10 +12,11 @@ define([
   'pgadmin.alertifyjs', 'sources/pgadmin', 'pgadmin.browser', 'backbone',
   'pgadmin.backgrid', 'pgadmin.backform', 'sources/../bundle/codemirror',
   'pgadmin.tools.debugger.ui', 'sources/keyboard_shortcuts',
-  'pgadmin.tools.debugger.utils', 'wcdocker',
+  'pgadmin.tools.debugger.utils', 'sources/window', 'wcdocker',
 ], function(
   gettext, url_for, $, _, Alertify, pgAdmin, pgBrowser, Backbone, Backgrid,
-  Backform, codemirror, debug_function_again, keyboardShortcuts, debuggerUtils
+  Backform, codemirror, debug_function_again, keyboardShortcuts, debuggerUtils,
+  pgWindow
 ) {
 
   var CodeMirror = codemirror.default,
@@ -1525,8 +1526,7 @@ define([
       this.function_name_with_arguments = function_name_with_arguments;
       this.layout = layout;
 
-      let browser = window.opener ?
-        window.opener.pgAdmin.Browser : window.top.pgAdmin.Browser;
+      let browser = pgWindow.default.pgAdmin.Browser;
       this.preferences = browser.get_preferences_for_module('debugger');
 
       this.docker = new wcDocker(
@@ -1835,7 +1835,7 @@ define([
 
         let cacheIntervalId = setInterval(function() {
           try {
-            let browser = window.opener ? window.opener.pgAdmin.Browser : window.top.pgAdmin.Browser;
+            let browser = pgWindow.default.pgAdmin.Browser;
             if(browser.preference_version() > 0) {
               clearInterval(cacheIntervalId);
               self.reflectPreferences();
@@ -1846,7 +1846,7 @@ define([
               if(self.preferences.debugger_new_browser_tab) {
                 pgBrowser.bind_beforeunload();
                 let pollIntervalId = setInterval(()=>{
-                  if(window.opener && window.opener.pgAdmin) {
+                  if(pgWindow.default.pgAdmin) {
                     self.reflectPreferences();
                   }
                   else {
@@ -1888,13 +1888,13 @@ define([
       /* Register for preference changed event broadcasted in parent
        * to reload the shorcuts.
        */
-      pgBrowser.onPreferencesChange('debugger', function() {
+      pgWindow.default.pgAdmin.Browser.onPreferencesChange('debugger', function() {
         self.reflectPreferences();
       });
     },
     reflectPreferences: function() {
       let self = this,
-        browser = window.opener ? window.opener.pgAdmin.Browser : window.top.pgAdmin.Browser;
+        browser = pgWindow.default.pgAdmin.Browser;
       self.preferences = browser.get_preferences_for_module('debugger');
       self.toolbarView.preferences = self.preferences;
 
diff --git a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
index 37d15a9c..3f082b77 100644
--- a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
+++ b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
@@ -38,6 +38,7 @@ define('tools.querytool', [
   'sources/sqleditor/query_tool_preferences',
   'sources/csrf',
   'tools/datagrid/static/js/datagrid_panel_title',
+  'sources/window',
   'sources/../bundle/slickgrid',
   'pgadmin.file_manager',
   'backgrid.sizeable.columns',
@@ -52,7 +53,8 @@ define('tools.querytool', [
   XCellSelectionModel, setStagedRows, SqlEditorUtils, ExecuteQuery, httpErrorHandler, FilterHandler,
   GeometryViewer, historyColl, queryHist, querySources,
   keyboardShortcuts, queryToolActions, queryToolNotifications, Datagrid,
-  modifyAnimation, calculateQueryRunTime, callRenderAfterPoll, queryToolPref, csrfToken, panelTitleFunc) {
+  modifyAnimation, calculateQueryRunTime, callRenderAfterPoll, queryToolPref, csrfToken, panelTitleFunc,
+  pgWindow) {
   /* Return back, this has been called more than once */
   if (pgAdmin.SqlEditor)
     return pgAdmin.SqlEditor;
@@ -77,8 +79,7 @@ define('tools.querytool', [
       this.$el = opts.el;
       this.handler = opts.handler;
       this.handler['col_size'] = {};
-      let browser = window.opener ?
-        window.opener.pgAdmin.Browser : window.top.pgAdmin.Browser;
+      let browser = pgWindow.default.pgAdmin.Browser;
       this.preferences = browser.get_preferences_for_module('sqleditor');
       this.handler.preferences = this.preferences;
       this.connIntervalId = null;
@@ -142,10 +143,9 @@ define('tools.querytool', [
 
     reflectPreferences: function() {
       let self = this,
-        browser = window.opener ?
-          window.opener.pgAdmin.Browser : window.top.pgAdmin.Browser;
+        browser = pgWindow.default.pgAdmin.Browser;
 
-      /* pgBrowser is different obj from window.top.pgAdmin.Browser
+      /* pgBrowser is different obj from pgWindow.default.pgAdmin.Browser
        * Make sure to get only the latest update. Older versions will be discarded
        * if function is called by older events.
        * This works for new tab sql editor also as it polls if latest version available
@@ -405,7 +405,7 @@ define('tools.querytool', [
 
       if (!self.preferences.new_browser_tab) {
         // Listen on the panel closed event and notify user to save modifications.
-        _.each(window.top.pgAdmin.Browser.docker.findPanels('frm_datagrid'), function(p) {
+        _.each(pgWindow.default.pgAdmin.Browser.docker.findPanels('frm_datagrid'), function(p) {
           if (p.isVisible()) {
             p.on(wcDocker.EVENT.CLOSING, function() {
               return self.handler.check_needed_confirmations_before_closing_panel(true);
@@ -635,7 +635,7 @@ define('tools.querytool', [
        * to reload the shorcuts. As sqleditor is in iFrame of wcDocker
        * window parent is referred
        */
-      pgBrowser.onPreferencesChange('sqleditor', function() {
+      pgWindow.default.pgAdmin.Browser.onPreferencesChange('sqleditor', function() {
         self.reflectPreferences();
       });
 
@@ -645,7 +645,7 @@ define('tools.querytool', [
       if(self.preferences.new_browser_tab) {
         pgBrowser.bind_beforeunload();
         setInterval(()=>{
-          if(window.opener.pgAdmin) {
+          if(pgWindow.default.pgAdmin) {
             self.reflectPreferences();
           }
         }, 1000);
@@ -3270,7 +3270,7 @@ define('tools.querytool', [
         if (self.preferences.new_browser_tab) {
           window.document.title = title;
         } else {
-          _.each(window.top.pgAdmin.Browser.docker.findPanels('frm_datagrid'), function(p) {
+          _.each(pgWindow.default.pgAdmin.Browser.docker.findPanels('frm_datagrid'), function(p) {
             if (p.isVisible()) {
               panelTitleFunc.setQueryToolDockerTitle(p, self.is_query_tool, title, is_file);
             }
@@ -3431,7 +3431,7 @@ define('tools.querytool', [
               title = window.document.title + ' *';
             } else {
               // Find the title of the visible panel
-              _.each(window.top.pgAdmin.Browser.docker.findPanels('frm_datagrid'), function(p) {
+              _.each(pgWindow.default.pgAdmin.Browser.docker.findPanels('frm_datagrid'), function(p) {
                 if (p.isVisible()) {
                   self.gridView.panel_title = $(p._title).text();
                 }
@@ -3993,8 +3993,7 @@ define('tools.querytool', [
       },
 
       call_cache_preferences: function() {
-        let browser = window.opener ?
-          window.opener.pgAdmin.Browser : window.top.pgAdmin.Browser;
+        let browser = pgWindow.default.pgAdmin.Browser;
         browser.cache_preferences('sqleditor');
 
         /* This will make sure to get latest updates only and not older events */
@@ -4312,7 +4311,7 @@ define('tools.querytool', [
         var self = this;
 
         pgBrowser.Events.off('pgadmin:user:logged-in', this.initTransaction);
-        _.each(window.top.pgAdmin.Browser.docker.findPanels('frm_datagrid'), function(panel) {
+        _.each(pgWindow.default.pgAdmin.Browser.docker.findPanels('frm_datagrid'), function(panel) {
           if (panel.isVisible()) {
             window.onbeforeunload = null;
             panel.off(wcDocker.EVENT.CLOSING);
@@ -4320,7 +4319,7 @@ define('tools.querytool', [
             if (!_.isUndefined(self.col_size)) {
               delete self.col_size;
             }
-            window.top.pgAdmin.Browser.docker.removePanel(panel);
+            pgWindow.default.pgAdmin.Browser.docker.removePanel(panel);
           }
         });
       },
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.