diff --git a/web/pgadmin/browser/templates/browser/js/browser.js b/web/pgadmin/browser/templates/browser/js/browser.js index 3684eccec..b4d02c218 100644 --- a/web/pgadmin/browser/templates/browser/js/browser.js +++ b/web/pgadmin/browser/templates/browser/js/browser.js @@ -17,14 +17,13 @@ $(window).bind('unload', function() { // Build a regular dock panel function buildPanel(docker, name, title, width, height, showTitle, isCloseable, isPrivate, content) { docker.registerPanelType(name, { + title: title, isPrivate: isPrivate, onCreate: function(myPanel) { myPanel.initSize(width, height); if (showTitle == false) myPanel.title(false); - else - myPanel.title(title); myPanel.closeable(isCloseable); @@ -36,15 +35,14 @@ function buildPanel(docker, name, title, width, height, showTitle, isCloseable, // Build an iFrame dock panel function buildIFramePanel(docker, name, title, width, height, showTitle, isCloseable, isPrivate, url) { docker.registerPanelType(name, { + title: title, isPrivate: isPrivate, onCreate: function(myPanel) { myPanel.initSize(width, height); if (showTitle == false) myPanel.title(false); - else - myPanel.title(title); - + myPanel.closeable(isCloseable); var $frameArea = $('
'); diff --git a/web/pgadmin/browser/views.py b/web/pgadmin/browser/views.py index 29e3e9d20..93850cfeb 100644 --- a/web/pgadmin/browser/views.py +++ b/web/pgadmin/browser/views.py @@ -51,7 +51,12 @@ def index(): # Add browser stylesheets stylesheets.append(url_for('static', filename='css/codemirror/codemirror.css')) - stylesheets.append(url_for('static', filename='css/wcDocker/style.css')) + + if config.DEBUG: + stylesheets.append(url_for('static', filename='css/wcDocker/wcDocker.css')) + else: + stylesheets.append(url_for('static', filename='css/wcDocker/wcDocker.min.css')) + stylesheets.append(url_for('static', filename='css/wcDocker/theme.css')) stylesheets.append(url_for('browser.static', filename='css/browser.css')) stylesheets.append(url_for('browser.static', filename='css/aciTree/css/aciTree.css')) @@ -61,14 +66,12 @@ def index(): # Add browser scripts scripts.append(url_for('static', filename='js/codemirror/codemirror.js')) scripts.append(url_for('static', filename='js/codemirror/mode/sql.js')) - scripts.append(url_for('static', filename='js/wcDocker/docker.js')) - scripts.append(url_for('static', filename='js/wcDocker/splitter.js')) - scripts.append(url_for('static', filename='js/wcDocker/frame.js')) - scripts.append(url_for('static', filename='js/wcDocker/panel.js')) - scripts.append(url_for('static', filename='js/wcDocker/layout.js')) - scripts.append(url_for('static', filename='js/wcDocker/ghost.js')) - scripts.append(url_for('static', filename='js/wcDocker/tabframe.js')) - scripts.append(url_for('static', filename='js/wcDocker/iframe.js')) + + if config.DEBUG: + scripts.append(url_for('static', filename='js/wcDocker/wcDocker.js')) + else: + scripts.append(url_for('static', filename='js/wcDocker/wcDocker.min.js')) + scripts.append(url_for('browser.static', filename='js/aciTree/jquery.aciPlugin.min.js')) scripts.append(url_for('browser.static', filename='js/aciTree/jquery.aciTree.dom.js')) scripts.append(url_for('browser.static', filename='js/aciTree/jquery.aciTree.min.js')) diff --git a/web/pgadmin/static/css/wcDocker/style.css b/web/pgadmin/static/css/wcDocker/wcDocker.css old mode 100755 new mode 100644 similarity index 95% rename from web/pgadmin/static/css/wcDocker/style.css rename to web/pgadmin/static/css/wcDocker/wcDocker.css index fd2802565..b4ebe0db1 --- a/web/pgadmin/static/css/wcDocker/style.css +++ b/web/pgadmin/static/css/wcDocker/wcDocker.css @@ -461,6 +461,26 @@ html, body { border-radius: 6px; } +::-webkit-scrollbar { + width: 12px; + height: 12px; + background-color: #888; +} + +::-webkit-scrollbar-corner { + background-color: #888; +} + +::-webkit-scrollbar-track { + -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5); + border-radius: 10px; +} + +::-webkit-scrollbar-thumb { + border-radius: 10px; + -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.7); +} + .wcMenuList, .context-menu-list { border: 1px solid #111; } diff --git a/web/pgadmin/static/css/wcDocker/wcDocker.min.css b/web/pgadmin/static/css/wcDocker/wcDocker.min.css new file mode 100644 index 000000000..03b64dfd3 --- /dev/null +++ b/web/pgadmin/static/css/wcDocker/wcDocker.min.css @@ -0,0 +1,16 @@ +/*! + * Web Cabin Docker - Docking Layout Interface. + * + * Dependancies: + * JQuery 1.11.1 + * + * Version: git-master + * + * Author: Jeff Houde (Lochemage@gmail.com) + * Web: http://docker.webcabin.org/ + * + * Licensed under + * MIT License http://www.opensource.org/licenses/mit-license + * GPL v3 http://opensource.org/licenses/GPL-3.0 + * + */html,body{width:100%;height:100%;overflow:hidden;position:relative;margin:0}.wcDisableSelection{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:-moz-none;-ms-user-select:none;user-select:none}.wcModalBlocker{position:fixed;top:0;bottom:0;left:0;right:0;z-index:-30}.wcWide{width:100%;left:0}.wcTall{height:100%;top:0}.wcDocker{position:absolute}.wcDockerTransition{opacity:0}.wcFrame{position:relative}.wcFrameFlasher,.wcFrameShadower{border:0;margin:0;padding:0;position:absolute;top:0;left:0;right:0;bottom:0;opacity:0}.wcFrameTitle{width:100%;cursor:move;overflow:hidden;position:absolute;text-align:left;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:-moz-none;-ms-user-select:none;user-select:none}.wcFrameTitle.wcNotMoveable{cursor:default !important}.wcCustomTabTitle{cursor:default !important}.wcCustomTabMoveable{cursor:move !important}.wcCustomTab{position:relative}.wcTabScroller{height:100%;width:10000px;position:relative}.wcFrameButton,.wcFrameMiniButton{width:13px;height:13px;position:relative;float:right;border:2px outset #444;font-size:11px;cursor:pointer;text-align:center;overflow:hidden;z-index:1;background-color:#555}.wcFrameButton>div,.wcFrameMiniButton>div{width:100%}.wcFrameMiniButton{width:6px}.wcFrameButton:hover{border:2px outset #666;background-color:#686868}.wcFrameButton:active{border:2px inset #aaa;background-color:#888}.wcFrameButtonToggled,.wcFrameButtonToggled:hover{border-style:inset}.wcFrameCenter{overflow:hidden;position:absolute;top:15px;left:0;right:0;bottom:0}.wcFloating{position:fixed;z-index:10}.wcFloatingFocus{z-index:20}.wcModal{z-index:40}.wcLayout,.wcLayout tr,.wcLayout td{border:0;margin:0;padding:0;background-color:transparent;border-spacing:0}.wcLayout{top:0;left:0;right:0;bottom:0;position:absolute}.wcFrameEdge{position:absolute;z-index:2;border:2px outset #444;background-color:#222}.wcFrameEdgeV{width:2px;cursor:ew-resize;border-top:0;border-bottom:0}.wcFrameEdgeH{height:2px;cursor:ns-resize;border-left:0;border-right:0}.wcFrameCornerNW{height:2px;width:2px;cursor:nwse-resize}.wcFrameCornerNE{height:2px;width:2px;cursor:nesw-resize}.wcSplitterBar{z-index:2;position:absolute;border:1px outset darkgray}.wcSplitterBarV{width:2px;height:100%;cursor:ew-resize}.wcSplitterBarH{height:2px;width:100%;cursor:ns-resize}.wcLayoutPane{border:0;margin:0;padding:0;display:inline-block;position:absolute}.wcPanelTab{vertical-align:top;position:relative;display:inline-block;text-decoration:none;top:0}.wcPanelTabContent{width:100%;height:100%}.wcPanelTabContent.wcPanelTabContentHidden{display:none}.wcResizing .wcHideOnResize .wcPanelTabContent{display:none}.wcGhost{opacity:0;background-color:#444;position:fixed;border:0;border-radius:6px;z-index:100;cursor:move}.wcScrollableX{overflow-x:auto}.wcScrollableY{overflow-y:auto}.wcOverflowVisible{overflow:visible}.wcTabIcon{display:inline-block;width:1.28571429em;height:1em;text-align:center}.wcMenuIcon{margin-left:-24px;width:1.28571429em;font-size:1.33333333em;line-height:.75em;height:1em;display:inline-block;vertical-align:-15%;text-align:center}.fa-menu{margin-left:-24px;width:24px}.context-menu-submenu:after{content:'' !important}.wcMenuSubMenu{float:right}.wcIFrame{position:fixed;width:100%;height:100%;z-index:1;border:0;margin:0;padding:0}.wcIFrameFloating{z-index:11}.wcIFrameFloatingFocus{z-index:21}.wcIFrameHidden,.wcIFramePanelHidden{display:none}.wcIFrameMoving{pointer-events:none}.wcDocker{background-color:gray}.wcModalBlocker{background-color:black;opacity:.8}.wcPanelBackground{background-color:gray}.wcPanelBackground .wcCenter{background-color:darkgray}.wcFrameFlasher{background-color:white}.wcFrameShadower{background-color:white}.wcFrameTitle{height:17px;background-color:#555}.wcFrameCenter{top:17px}.wcLayoutGrid,.wcLayoutGrid tr,.wcLayoutGrid td{border:1px solid #555}.wcLayoutGridAlternate tr:nth-child(even),.wcLayoutGridAltColor{background-color:rgba(200,200,200,0.2) !important}.wcPanelTab{color:#42454a;background-color:#777;border:1px solid #000;border-radius:2px 2px 0 0;border-bottom:0;margin-right:1px;margin-top:3px;font-size:12px;padding-left:2px;padding-right:2px;padding-bottom:0}.wcPanelTab:hover{background-color:#AAA}.wcPanelTabActive{color:#000;background-color:gray;font-weight:bold;margin-top:1px}.wcPanelTabActive:hover{background-color:#CCC}.wcFrameEdge{position:absolute;z-index:2;border:2px outset #444;background-color:#222}.wcSplitterBar{border:1px outset darkgray;background-color:gray}.wcGhost{background-color:#444;border:0;border-radius:6px}::-webkit-scrollbar{width:12px;height:12px;background-color:#888}::-webkit-scrollbar-corner{background-color:#888}::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,0.5);border-radius:10px}::-webkit-scrollbar-thumb{border-radius:10px;-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,0.7)}.wcMenuList,.context-menu-list{border:1px solid #111}.wcMenuItem,.context-menu-item{background-color:#444}.wcMenuItemHover,.wcMenuItem:hover,.context-menu-item.hover{background-color:#666}.wcMenuItem.disabled,.context-menu-item.disabled{color:#333;background-color:#444}.wcMenuSeparator,.context-menu-separator{border:2px solid #444;background-color:#777}.wcInput,input{vertical-align:middle;border:1px solid black}.wcSelect,select{border:1px solid black}.wcButton,button{border:1px outset #777;background-color:#777;line-height:1em}.wcButtonHover,.wcButton:hover,button:hover{border:1px outset #999;background-color:#999}.wcButtonActive,.wcButton:active,button:active{border:1px inset #666;background-color:#666}.wcButtonActive.wcButtonHover,.wcButton:hover.wcButtonActive,.wcButton:active.wcButtonHover,.wcButton:active:hover,button:active:hover{border:1px inset #999;background-color:#999}.wcButtonDisabled,.wcButton.disabled,button:disabled{border:1px outset #666 !important;background-color:#666 !important;color:#555 !important}.wcButton:focus,button:focus{outline:0} \ No newline at end of file diff --git a/web/pgadmin/static/js/wcDocker/docker.js b/web/pgadmin/static/js/wcDocker/docker.js deleted file mode 100755 index 70ad74505..000000000 --- a/web/pgadmin/static/js/wcDocker/docker.js +++ /dev/null @@ -1,1862 +0,0 @@ -/*! - * Web Cabin Docker - Docking Layout Interface. - * - * Dependancies: - * JQuery 1.11.1 - * JQuery-contextMenu 1.6.6 - * font-awesome 4.2.0 - * - * Author: Jeff Houde (Lochemage@gmail.com) - * Web: http://docker.webcabin.org/ - * - * Licensed under - * MIT License http://www.opensource.org/licenses/mit-license - * GPL v3 http://opensource.org/licenses/GPL-3.0 - * - */ - -// Provide backward compatibility for IE8 and other such older browsers. -if (!Function.prototype.bind) { - Function.prototype.bind = function (oThis) { - if (typeof this !== "function") { - // closest thing possible to the ECMAScript 5 - // internal IsCallable function - throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); - } - - var aArgs = Array.prototype.slice.call(arguments, 1), - fToBind = this, - fNOP = function () {}, - fBound = function () { - return fToBind.apply(this instanceof fNOP && oThis - ? this - : oThis, - aArgs.concat(Array.prototype.slice.call(arguments))); - }; - - fNOP.prototype = this.prototype; - fBound.prototype = new fNOP(); - - return fBound; - }; -} - -if (!Array.prototype.indexOf) -{ - Array.prototype.indexOf = function(elt /*, from*/) - { - var len = this.length >>> 0; - - var from = Number(arguments[1]) || 0; - from = (from < 0) - ? Math.ceil(from) - : Math.floor(from); - if (from < 0) - from += len; - - for (; from < len; from++) - { - if (from in this && - this[from] === elt) - return from; - } - return -1; - }; -} - -/* - The main window instance. This manages all of the docking panels and user input. - There should only be one instance of this, although it is not enforced. - - options allows overriding default options for docker. The current fields are: - allowContextMenu: boolean (default true) - Create the right click menu for adding/removing panels. - hideOnResize: boolean (default false) - If true, panels will hide their content as they are being resized. -*/ -function wcDocker(container, options) { - this.$container = $(container).addClass('wcDocker'); - this.$transition = $('
'); - this.$container.append(this.$transition); - - this._events = {}; - - this._root = null; - this._frameList = []; - this._floatingList = []; - this._modalList = []; - this._focusFrame = null; - - this._splitterList = []; - this._tabList = []; - - this._dockPanelTypeList = []; - - this._draggingSplitter = null; - this._draggingFrame = null; - this._draggingFrameSizer = null; - this._draggingFrameTab = null; - this._draggingCustomTabFrame = null; - this._ghost = null; - this._menuTimer = 0; - - this._resizeData = { - time: -1, - timeout: false, - delta: 150, - }; - - this._defaultOptions = { - allowContextMenu: true - }; - - this._options = {}; - for( var prop in this._defaultOptions ) { - this._options[prop] = this._defaultOptions[prop]; - } - for( var prop in options ) { - this._options[prop] = options[prop]; - } - - this.__init(); -}; - -// Docking positions. -wcDocker.DOCK_MODAL = 'modal'; -wcDocker.DOCK_FLOAT = 'float'; -wcDocker.DOCK_TOP = 'top'; -wcDocker.DOCK_LEFT = 'left'; -wcDocker.DOCK_RIGHT = 'right'; -wcDocker.DOCK_BOTTOM = 'bottom'; -wcDocker.DOCK_STACKED = 'stacked'; - -// Internal events. -wcDocker.EVENT_INIT = 'panelInit'; -wcDocker.EVENT_UPDATED = 'panelUpdated'; -wcDocker.EVENT_VISIBILITY_CHANGED = 'panelVisibilityChanged'; -wcDocker.EVENT_BEGIN_DOCK = 'panelBeginDock'; -wcDocker.EVENT_END_DOCK = 'panelEndDock'; -wcDocker.EVENT_GAIN_FOCUS = 'panelGainFocus'; -wcDocker.EVENT_LOST_FOCUS = 'panelLostFocus'; -wcDocker.EVENT_CLOSED = 'panelClosed'; -wcDocker.EVENT_BUTTON = 'panelButton'; -wcDocker.EVENT_ATTACHED = 'panelAttached'; -wcDocker.EVENT_DETACHED = 'panelDetached'; -wcDocker.EVENT_MOVE_STARTED = 'panelMoveStarted'; -wcDocker.EVENT_MOVE_ENDED = 'panelMoveEnded'; -wcDocker.EVENT_MOVED = 'panelMoved'; -wcDocker.EVENT_RESIZE_STARTED = 'panelResizeStarted'; -wcDocker.EVENT_RESIZE_ENDED = 'panelResizeEnded'; -wcDocker.EVENT_RESIZED = 'panelResized'; -wcDocker.EVENT_SCROLLED = 'panelScrolled'; -wcDocker.EVENT_SAVE_LAYOUT = 'layoutSave'; -wcDocker.EVENT_RESTORE_LAYOUT = 'layoutRestore'; -wcDocker.EVENT_CUSTOM_TAB_CHANGED = 'customTabChanged'; -wcDocker.EVENT_CUSTOM_TAB_CLOSED = 'customTabClosed'; - -// Used for the splitter bar orientation. -wcDocker.ORIENTATION_VERTICAL = false; -wcDocker.ORIENTATION_HORIZONTAL = true; - -wcDocker.prototype = { -/////////////////////////////////////////////////////////////////////////////////////////////////////// -// Public Functions -/////////////////////////////////////////////////////////////////////////////////////////////////////// - - // Registers a new docking panel type to be used later. - // Params: - // name The name for this new type. - // options An optional object that defines various options - // to initialize the panel with. - // createFunc The function that populates the contents of - // a newly created dock panel of this type. - // Params: - // panel The dock panel to populate. - // isPrivate If true, this type will not appear to the user - // as a window type to create. - // Returns: - // true The new type has been added successfully. - // false Failure, the type name already exists. - registerPanelType: function(name, optionsOrCreateFunc, isPrivate) { - - var options = optionsOrCreateFunc; - if (typeof options === 'function') { - options = { - onCreate: optionsOrCreateFunc, - }; - } - - if (typeof isPrivate != 'undefined') { - options.isPrivate = isPrivate; - } - - if ($.isEmptyObject(options)) { - options = null; - } - - for (var i = 0; i < this._dockPanelTypeList.length; ++i) { - if (this._dockPanelTypeList[i].name === name) { - return false; - } - } - - this._dockPanelTypeList.push({ - name: name, - options: options, - }); - - var $menu = $('menu').find('menu'); - $menu.append($('')); - return true; - }, - - // Retrieves a list of all currently registered panel types. - // Params: - // includePrivate If true, panels registered as private will - // also be included with this list. - // - // Returns: - // String[] A list of panel type names. - panelTypes: function(includePrivate) { - var result = []; - for (var i = 0; i < this._dockPanelTypeList.length; ++i) { - if (includePrivate || !this._dockPanelTypeList[i].options.isPrivate) { - result.push(this._dockPanelTypeList[i].name); - } - } - return result; - }, - - // Retrieves the options data associated with a given panel type when it was registered. - // Params: - // typeName The type of the panel. - // - // Returns: - // Object An object that represents the registered info of the panel type. - // false The panel type requested was not found. - panelTypeInfo: function(typeName) { - for (var i = 0; i < this._dockPanelTypeList.length; ++i) { - if (this._dockPanelTypeList[i].name == typeName) { - return this._dockPanelTypeList[i].options; - } - } - return false; - }, - - // Add a new dock panel to the window of a given type. - // Params: - // typeName The type of panel to create. - // location The docking location of the new panel, - // as defined by wcDocker.DOCK_ values. - // targetPanel An optional target panel, providing one will cause - // the docking location to be relative to this panel. - // Must be supplied when using wcDocker.DOCK_STACKED. - // rect An object with an x, y position, and a w, h size - // used to influence the starting position and size - // of a floating or modal panel. - // - // Returns: - // wcPanel The panel that was created. - // false The panel type does not exist. - addPanel: function(typeName, location, targetPanel, rect) { - for (var i = 0; i < this._dockPanelTypeList.length; ++i) { - if (this._dockPanelTypeList[i].name === typeName) { - var panelType = this._dockPanelTypeList[i]; - var panel = new wcPanel(typeName, panelType.options); - panel._parent = this; - panel.__container(this.$transition); - var options = (panelType.options && panelType.options.options) || {}; - panel._panelObject = new panelType.options.onCreate(panel, options); - - if (location === wcDocker.DOCK_STACKED) { - this.__addPanelGrouped(panel, location, targetPanel); - } else { - this.__addPanelAlone(panel, location, targetPanel, rect); - } - - this.__update(); - return panel; - } - } - return false; - }, - - // Removes a dock panel from the window. - // Params: - // panel The panel to remove. - // Returns: - // true The panel was removed. - // false There was a problem. - removePanel: function(panel) { - if (!panel) { - return false; - } - - // Do not remove if this is the last moveable panel. - if (this.__isLastPanel(panel)) { - return false; - } - - var parentFrame = panel._parent; - if (parentFrame instanceof wcFrame) { - panel.__trigger(wcDocker.EVENT_CLOSED); - - // If no more panels remain in this frame, remove the frame. - if (!parentFrame.removePanel(panel)) { - var index = this._floatingList.indexOf(parentFrame); - if (index !== -1) { - this._floatingList.splice(index, 1); - } - index = this._frameList.indexOf(parentFrame); - if (index !== -1) { - this._frameList.splice(index, 1); - } - index = this._modalList.indexOf(parentFrame); - if (index !== -1) { - this._modalList.splice(index, 1); - } - - if (this._modalList.length) { - this.__focus(this._modalList[this._modalList.length-1]); - } else if (this._floatingList.length) { - this.__focus(this._floatingList[this._floatingList.length-1]); - } - - var parentSplitter = parentFrame._parent; - if (parentSplitter instanceof wcSplitter) { - parentSplitter.__removeChild(parentFrame); - - var other; - if (parentSplitter.pane(0)) { - other = parentSplitter.pane(0); - parentSplitter._pane[0] = null; - } else { - other = parentSplitter.pane(1); - parentSplitter._pane[1] = null; - } - - // Keep the panel in a hidden transition container so as to not - // destroy any event handlers that may be on it. - other.__container(this.$transition); - other._parent = null; - - index = this._splitterList.indexOf(parentSplitter); - if (index !== -1) { - this._splitterList.splice(index, 1); - } - - var parent = parentSplitter._parent; - parentContainer = parentSplitter.__container(); - parentSplitter.__destroy(); - - if (parent instanceof wcSplitter) { - parent.__removeChild(parentSplitter); - if (!parent.pane(0)) { - parent.pane(0, other); - } else { - parent.pane(1, other); - } - } else if (parent === this) { - this._root = other; - other._parent = this; - other.__container(parentContainer); - } - this.__update(); - } else if (parentFrame === this._root) { - this._root = null; - } - - if (this._focusFrame === parentFrame) { - this._focusFrame = null; - } - parentFrame.__destroy(); - } - panel.__destroy(); - return true; - } - return false; - }, - - // Moves a docking panel from its current location to another. - // Params: - // panel The panel to move. - // location The docking location of the new panel, - // as defined by wcDocker.DOCK_ values. - // targetPanel An optional target panel, providing one will cause - // the docking location to be relative to this panel. - // Must be supplied when using wcDocker.DOCK_STACKED. - // rect An object with an x, y position, and a w, h size - // used to influence the starting position and size - // of a floating or modal panel. - // Returns: - // wcPanel The panel that was created. - // false The panel type does not exist. - movePanel: function(panel, location, targetPanel, rect) { - if (this.__isLastPanel(panel)) { - return panel; - } - - var $elem = panel.$container; - if (panel._parent instanceof wcFrame) { - $elem = panel._parent.$frame; - } - var offset = $elem.offset(); - var width = $elem.width(); - var height = $elem.height(); - - var parentFrame = panel._parent; - var floating = false; - if (parentFrame instanceof wcFrame) { - floating = parentFrame._isFloating; - } - - if (parentFrame instanceof wcFrame) { - // Remove the panel from the frame. - for (var i = 0; i < parentFrame._panelList.length; ++i) { - if (parentFrame._panelList[i] === panel) { - if (parentFrame._curTab >= i) { - parentFrame._curTab--; - } - - // Keep the panel in a hidden transition container so as to not - // destroy any event handlers that may be on it. - panel.__container(this.$transition); - panel._parent = null; - - parentFrame._panelList.splice(i, 1); - break; - } - } - - if (parentFrame._curTab === -1 && parentFrame._panelList.length) { - parentFrame._curTab = 0; - } - - parentFrame.__updateTabs(); - - // If no more panels remain in this frame, remove the frame. - if (parentFrame._panelList.length === 0) { - var index = this._floatingList.indexOf(parentFrame); - if (index !== -1) { - this._floatingList.splice(index, 1); - } - index = this._frameList.indexOf(parentFrame); - if (index !== -1) { - this._frameList.splice(index, 1); - } - - var parentSplitter = parentFrame._parent; - if (parentSplitter instanceof wcSplitter) { - parentSplitter.__removeChild(parentFrame); - - var other; - if (parentSplitter.pane(0)) { - other = parentSplitter.pane(0); - parentSplitter._pane[0] = null; - } else { - other = parentSplitter.pane(1); - parentSplitter._pane[1] = null; - } - - // Keep the item in a hidden transition container so as to not - // destroy any event handlers that may be on it. - other.__container(this.$transition); - other._parent = null; - - index = this._splitterList.indexOf(parentSplitter); - if (index !== -1) { - this._splitterList.splice(index, 1); - } - - var parent = parentSplitter._parent; - parentContainer = parentSplitter.__container(); - parentSplitter.__destroy(); - - if (parent instanceof wcSplitter) { - parent.__removeChild(parentSplitter); - if (!parent.pane(0)) { - parent.pane(0, other); - } else { - parent.pane(1, other); - } - } else if (parent === this) { - this._root = other; - other._parent = this; - other.__container(parentContainer); - } - this.__update(); - } - - if (this._focusFrame === parentFrame) { - this._focusFrame = null; - } - - parentFrame.__destroy(); - } - } - - panel.initSize(width, height); - if (location === wcDocker.DOCK_STACKED) { - this.__addPanelGrouped(panel, location, targetPanel); - } else { - this.__addPanelAlone(panel, location, targetPanel, rect); - } - - var frame = panel._parent; - if (frame instanceof wcFrame) { - if (frame._panelList.length === 1) { - frame.pos(offset.left + width/2 + 20, offset.top + height/2 + 20, true); - } - } - - this.__update(); - - if (frame instanceof wcFrame) { - if (floating !== frame._isFloating) { - if (frame._isFloating) { - panel.__trigger(wcDocker.EVENT_DETACHED); - } else { - panel.__trigger(wcDocker.EVENT_ATTACHED); - } - } - } - - panel.__trigger(wcDocker.EVENT_MOVED); - return panel; - }, - - // Finds all instances of a given panel type. - // Params: - // typeName The type of panel. - // Returns: - // [wcPanel] A list of all panels of the given type. - findPanels: function(typeName) { - var result = []; - for (var i = 0; i < this._frameList.length; ++i) { - var frame = this._frameList[i]; - for (var a = 0; a < frame._panelList.length; ++a) { - var panel = frame._panelList[a]; - if (!typeName || panel._type === typeName) { - result.push(panel); - } - } - } - - return result; - }, - - // Registers an event. - // Params: - // eventType The event type, as defined by wcDocker.EVENT_... - // handler A handler function to be called for the event. - // Params: - // panel The panel invoking the event. - // Returns: - // true The event was added. - // false The event failed to add. - on: function(eventType, handler) { - if (!eventType) { - return false; - } - - if (!this._events[eventType]) { - this._events[eventType] = []; - } - - if (this._events[eventType].indexOf(handler) !== -1) { - return false; - } - - this._events[eventType].push(handler); - return true; - }, - - // Unregisters an event. - // Params: - // eventType The event type to remove, if omitted, all events are removed. - // handler The handler function to remove, if omitted, all events of - // the above type are removed. - off: function(eventType, handler) { - if (typeof eventType === 'undefined') { - this._events = {}; - return; - } else { - if (this._events[eventType]) { - if (typeof handler === 'undefined') { - this._events[eventType] = []; - } else { - for (var i = 0; i < this._events[eventType].length; ++i) { - if (this._events[eventType][i] === handler) { - this._events[eventType].splice(i, 1); - break; - } - } - } - } - } - }, - - // Trigger an event on all panels. - // Params: - // eventName The name of the event. - // data A custom data parameter to pass to all handlers. - trigger: function(eventName, data) { - if (!eventName) { - return false; - } - - for (var i = 0; i < this._frameList.length; ++i) { - var frame = this._frameList[i]; - for (var a = 0; a < frame._panelList.length; ++a) { - var panel = frame._panelList[a]; - panel.__trigger(eventName, data); - } - } - - this.__trigger(eventName, data); - }, - - // Assigns a basic context menu to a selector element. The context - // Menu is a simple list of options, no nesting or special options. - // - // If you wish to use a more complex context menu, you can use - // $.contextMenu directly, see - // http://medialize.github.io/jQuery-contextMenu/docs.html - // for more information. - // Params: - // selector A JQuery selector string that designates the - // elements who use this menu. - // itemListOrBuildFunc An array with each context menu item in it, each item - // is an object {name:string, callback:function(key, opts, panel)}. - // This can also be a function that dynamically builds and - // returns the item list, parameters given are the $trigger object - // of the menu and the menu event object. - // includeDefault If true, all default panel menu options will also be shown. - basicMenu: function(selector, itemListOrBuildFunc, includeDefault) { - var self = this; - $.contextMenu({ - selector: selector, - build: function($trigger, event) { - var myFrame; - for (var i = 0; i < self._frameList.length; ++i) { - var $frame = $trigger.hasClass('wcFrame') && $trigger || $trigger.parents('.wcFrame'); - if (self._frameList[i].$frame[0] === $frame[0]) { - myFrame = self._frameList[i]; - break; - } - } - - var mouse = { - x: event.clientX, - y: event.clientY, - }; - var isTitle = false; - if (mouse.y - myFrame.$frame.offset().top <= 20) { - isTitle = true; - } - - var windowTypes = {}; - for (var i = 0; i < self._dockPanelTypeList.length; ++i) { - var type = self._dockPanelTypeList[i]; - if (!type.options.isPrivate) { - if (type.options.limit > 0) { - if (self.findPanels(type.name).length >= type.options.limit) { - continue; - } - } - var icon = null; - var faicon = null; - if (type.options) { - if (type.options.faicon) { - faicon = type.options.faicon; - } - if (type.options.icon) { - icon = type.options.icon; - } - } - windowTypes[type.name] = { - name: type.name, - icon: icon, - faicon: faicon, - className: 'wcMenuCreatePanel', - }; - } - } - - var separatorIndex = 0; - var finalItems = {}; - var itemList = itemListOrBuildFunc; - if (typeof itemListOrBuildFunc === 'function') { - itemList = itemListOrBuildFunc($trigger, event); - } - - for (var i = 0; i < itemList.length; ++i) { - if ($.isEmptyObject(itemList[i])) { - finalItems['sep' + separatorIndex++] = "---------"; - continue; - } - - var callback = itemList[i].callback; - if (callback) { - (function(listItem, callback) { - listItem.callback = function(key, opts) { - var panel = null; - var $frame = opts.$trigger.parents('.wcFrame').first(); - if ($frame.length) { - for (var a = 0; a < self._frameList.length; ++a) { - if ($frame[0] === self._frameList[a].$frame[0]) { - panel = self._frameList[a].panel(); - } - } - } - - callback(key, opts, panel); - }; - })(itemList[i], callback); - } - finalItems[itemList[i].name] = itemList[i]; - } - - var items = finalItems; - - if (includeDefault) { - if (!$.isEmptyObject(finalItems)) { - items['sep' + separatorIndex++] = "---------"; - } - - if (isTitle) { - items['Close Panel'] = { - name: 'Close Tab', - faicon: 'close', - disabled: !myFrame.panel().closeable() || self.__isLastPanel(myFrame.panel()), - }; - if (!myFrame._isFloating) { - items['Detach Panel'] = { - name: 'Detach Tab', - faicon: 'level-down', - disabled: !myFrame.panel().moveable() || self.__isLastPanel(myFrame.panel()), - }; - } - - items['sep' + separatorIndex++] = "---------"; - - items.fold1 = { - name: 'Add Tab', - faicon: 'columns', - items: windowTypes, - disabled: !(myFrame.panel()._titleVisible && (!myFrame._isFloating || self._modalList.indexOf(myFrame) === -1)), - className: 'wcMenuCreatePanel', - }; - items['sep' + separatorIndex++] = "---------"; - - items['Flash Panel'] = { - name: 'Flash Panel', - faicon: 'lightbulb-o', - }; - } else { - items['Close Panel'] = { - name: 'Close Panel', - faicon: 'close', - disabled: !myFrame.panel().closeable() || self.__isLastPanel(myFrame.panel()), - }; - if (!myFrame._isFloating) { - items['Detach Panel'] = { - name: 'Detach Panel', - faicon: 'level-down', - disabled: !myFrame.panel().moveable() || self.__isLastPanel(myFrame.panel()), - }; - } - - items['sep' + separatorIndex++] = "---------"; - - items.fold1 = { - name: 'Insert Panel', - faicon: 'columns', - items: windowTypes, - disabled: !(!myFrame._isFloating && myFrame.panel().moveable()), - className: 'wcMenuCreatePanel', - }; - items['sep' + separatorIndex++] = "---------"; - - items['Flash Panel'] = { - name: 'Flash Panel', - faicon: 'lightbulb-o', - }; - } - - if (!myFrame._isFloating && myFrame.panel().moveable()) { - var rect = myFrame.__rect(); - self._ghost = new wcGhost(rect, mouse, self); - myFrame.__checkAnchorDrop(mouse, false, self._ghost, true); - self._ghost.$ghost.hide(); - } - } - - return { - callback: function(key, options) { - if (key === 'Close Panel') { - setTimeout(function() { - myFrame.panel().close(); - }, 10); - } else if (key === 'Detach Panel') { - self.movePanel(myFrame.panel(), wcDocker.DOCK_FLOAT, false); - } else if (key === 'Flash Panel') { - self.__focus(myFrame, true); - } else { - if (myFrame && self._ghost) { - var anchor = self._ghost.anchor(); - var newPanel = self.addPanel(key, anchor.loc, myFrame.panel(), self._ghost.rect()); - newPanel.focus(); - } - } - }, - events: { - show: function(opt) { - (function(items){ - - // Whenever them menu is shown, we update and add the faicons. - // Grab all those menu items, and propogate a list with them. - var menuItems = {}; - var options = opt.$menu.find('.context-menu-item'); - for (var i = 0; i < options.length; ++i) { - var $option = $(options[i]); - var $span = $option.find('span'); - if ($span.length) { - menuItems[$span[0].innerHTML] = $option; - } - } - - // function calls itself so that we get nice icons inside of menus as well. - (function recursiveIconAdd(items) { - for(var it in items) { - var item = items[it]; - var $menu = menuItems[item.name]; - - if ($menu) { - var $icon = $('
'); - $menu.prepend($icon); - - if (item.icon) { - $icon.addClass(item.icon); - } - - if (item.faicon) { - $icon.addClass('fa fa-menu fa-' + item.faicon + ' fa-lg fa-fw'); - } - - // Custom submenu arrow. - if ($menu.hasClass('context-menu-submenu')) { - var $expander = $('
'); - $menu.append($expander); - } - } - - // Iterate through sub-menus. - if (item.items) { - recursiveIconAdd(item.items); - } - } - })(items); - - })(items); - }, - hide: function(opt) { - if (self._ghost) { - self._ghost.__destroy(); - self._ghost = false; - } - }, - }, - animation: {duration: 250, show: 'fadeIn', hide: 'fadeOut'}, - reposition: false, - autoHide: true, - zIndex: 200, - items: items, - }; - }, - }); - }, - - // Bypasses the next context menu event. - // Use this during a mouse up event in which you do not want the - // context menu to appear. - bypassMenu: function() { - if (this._menuTimer) { - clearTimeout(this._menuTimer); - } - - for (var i in $.contextMenu.menus) { - var menuSelector = $.contextMenu.menus[i].selector; - $(menuSelector).contextMenu(false); - } - - var self = this; - this._menuTimer = setTimeout(function() { - for (var i in $.contextMenu.menus) { - var menuSelector = $.contextMenu.menus[i].selector; - $(menuSelector).contextMenu(true); - } - self._menuTimer = null; - }, 0); - }, - - // Saves the current panel configuration into a meta - // string that can be used later to restore it. - save: function() { - var data = {}; - - data.floating = []; - for (var i = 0; i < this._floatingList.length; ++i) { - data.floating.push(this._floatingList[i].__save()); - } - - data.root = this._root.__save(); - - return JSON.stringify(data, function(key, value) { - if (value == Infinity) { - return "Infinity"; - } - return value; - }); - }, - - // Restores a previously saved configuration. - restore: function(dataString) { - var data = JSON.parse(dataString, function(key, value) { - if (value === 'Infinity') { - return Infinity; - } - return value; - }); - - this.clear(); - - this._root = this.__create(data.root, this, this.$container); - this._root.__restore(data.root, this); - - for (var i = 0; i < data.floating.length; ++i) { - var panel = this.__create(data.floating[i], this, this.$container); - panel.__restore(data.floating[i], this); - } - - this.__update(); - }, - - // Clears out all panels. - clear: function() { - this._root = null; - - for (var i = 0; i < this._splitterList.length; ++i) { - this._splitterList[i].__destroy(); - } - - for (var i = 0; i < this._frameList.length; ++i) { - this._frameList[i].__destroy(); - } - - while (this._frameList.length) this._frameList.pop(); - while (this._floatingList.length) this._floatingList.pop(); - while (this._splitterList.length) this._splitterList.pop(); - }, - - -/////////////////////////////////////////////////////////////////////////////////////////////////////// -// Private Functions -/////////////////////////////////////////////////////////////////////////////////////////////////////// - - __init: function() { - this._root = null; - - var self = this; - $(window).resize(self.__resize.bind(self)); - - // Setup our context menus. - if ( this._options.allowContextMenu ) { - this.basicMenu('.wcFrame', [], true); - } - - var contextTimer; - $('body').on('contextmenu', 'a, img', function() { - if (contextTimer) { - clearTimeout(contextTimer); - } - - $(".wcFrame").contextMenu(false); - contextTimer = setTimeout(function() { - $(".wcFrame").contextMenu(true); - contextTimer = null; - }, 100); - return true; - }); - - $('body').on('contextmenu', '.wcSplitterBar', function() { - return false; - }); - - // Hovering over a panel creation context menu. - $('body').on('mouseenter', '.wcMenuCreatePanel', function() { - if (self._ghost) { - self._ghost.$ghost.stop().fadeIn(200); - } - }); - - $('body').on('mouseleave', '.wcMenuCreatePanel', function() { - if (self._ghost) { - self._ghost.$ghost.stop().fadeOut(200); - } - }); - - $('body').on('mousedown', '.wcModalBlocker', function(event) { - // for (var i = 0; i < self._modalList.length; ++i) { - // self._modalList[i].__focus(true); - // } - if (self._modalList.length) { - self._modalList[self._modalList.length-1].__focus(true); - } - }); - - // On some browsers, clicking and dragging a tab will drag it's graphic around. - // Here I am disabling this as it interferes with my own drag-drop. - $('body').on('mousedown', '.wcPanelTab', function(event) { - event.preventDefault(); - event.returnValue = false; - }); - - $('body').on('selectstart', '.wcFrameTitle, .wcPanelTab, .wcFrameButton', function(event) { - event.preventDefault(); - }); - - // Close button on frames should destroy those panels. - $('body').on('mousedown', '.wcFrame > .wcFrameButton', function() { - self.$container.addClass('wcDisableSelection'); - }); - - // Clicking on a panel frame button. - $('body').on('click', '.wcFrame > .wcFrameButton', function() { - self.$container.removeClass('wcDisableSelection'); - for (var i = 0; i < self._frameList.length; ++i) { - var frame = self._frameList[i]; - if (frame.$close[0] === this) { - var panel = frame.panel(); - self.removePanel(panel); - self.__update(); - return; - } - if (frame.$tabLeft[0] === this) { - frame._tabScrollPos-=frame.$title.width()/2; - if (frame._tabScrollPos < 0) { - frame._tabScrollPos = 0; - } - frame.__updateTabs(); - return; - } - if (frame.$tabRight[0] === this) { - frame._tabScrollPos+=frame.$title.width()/2; - frame.__updateTabs(); - return; - } - - for (var a = 0; a < frame._buttonList.length; ++a) { - if (frame._buttonList[a][0] === this) { - var $button = frame._buttonList[a]; - var result = { - name: $button.data('name'), - isToggled: false, - } - - if ($button.hasClass('wcFrameButtonToggler')) { - $button.toggleClass('wcFrameButtonToggled'); - if ($button.hasClass('wcFrameButtonToggled')) { - result.isToggled = true; - } - } - - var panel = frame.panel(); - panel.buttonState(result.name, result.isToggled); - panel.__trigger(wcDocker.EVENT_BUTTON, result); - return; - } - } - } - }); - - // Clicking on a custom tab button. - $('body').on('click', '.wcCustomTab > .wcFrameButton', function() { - self.$container.removeClass('wcDisableSelection'); - for (var i = 0; i < self._tabList.length; ++i) { - var customTab = self._tabList[i]; - if (customTab.$close[0] === this) { - var tabIndex = customTab.tab(); - customTab.removeTab(tabIndex); - return; - } - - if (customTab.$tabLeft[0] === this) { - customTab._tabScrollPos-=customTab.$title.width()/2; - if (customTab._tabScrollPos < 0) { - customTab._tabScrollPos = 0; - } - customTab.__updateTabs(); - return; - } - if (customTab.$tabRight[0] === this) { - customTab._tabScrollPos+=customTab.$title.width()/2; - customTab.__updateTabs(); - return; - } - } - }); - - // Middle mouse button on a panel tab to close it. - $('body').on('mouseup', '.wcPanelTab', function(event) { - if (event.which !== 2) { - return; - } - - var index = parseInt($(this).attr('id')); - - for (var i = 0; i < self._frameList.length; ++i) { - var frame = self._frameList[i]; - if (frame.$title[0] === $(this).parents('.wcFrameTitle')[0]) { - var panel = frame._panelList[index]; - if (self._removingPanel === panel) { - self.removePanel(panel); - self.__update(); - } - return; - } - } - }); - - // Mouse down on a splitter bar will allow you to resize them. - $('body').on('mousedown', '.wcSplitterBar', function(event) { - if (event.which !== 1) { - return true; - } - - self.$container.addClass('wcDisableSelection'); - for (var i = 0; i < self._splitterList.length; ++i) { - if (self._splitterList[i].$bar[0] === this) { - self._draggingSplitter = self._splitterList[i]; - self._draggingSplitter.$pane[0].addClass('wcResizing'); - self._draggingSplitter.$pane[1].addClass('wcResizing'); - break; - } - } - return true; - }); - - // Mouse down on a frame title will allow you to move them. - $('body').on('mousedown', '.wcFrameTitle', function(event) { - if (event.which === 3) { - return true; - } - if ($(event.target).hasClass('wcFrameButton')) { - return false; - } - - self.$container.addClass('wcDisableSelection'); - for (var i = 0; i < self._frameList.length; ++i) { - if (self._frameList[i].$title[0] == this) { - self._draggingFrame = self._frameList[i]; - - var mouse = { - x: event.clientX, - y: event.clientY, - }; - self._draggingFrame.__anchorMove(mouse); - - var $panelTab = $(event.target).hasClass('wcPanelTab')? $(event.target): $(event.target).parent('.wcPanelTab'); - if ($panelTab && $panelTab.length) { - var index = parseInt($panelTab.attr('id')); - self._draggingFrame.panel(index, true); - - // if (event.which === 2) { - // self._draggingFrame = null; - // return; - // } - - self._draggingFrameTab = $panelTab[0]; - } - - // If the window is able to be docked, give it a dark shadow tint and - // begin the movement process - if ((!self._draggingFrame.$title.hasClass('wcNotMoveable') && !$panelTab.hasClass('wcNotMoveable')) && - (!self._draggingFrame._isFloating || event.which !== 1 || self._draggingFrameTab)) { - var rect = self._draggingFrame.__rect(); - self._ghost = new wcGhost(rect, mouse, self); - self._draggingFrame.__checkAnchorDrop(mouse, true, self._ghost, true); - self.trigger(wcDocker.EVENT_BEGIN_DOCK); - } - break; - } - } - for (var i = 0; i < self._tabList.length; ++i) { - if (self._tabList[i].$title[0] == this) { - self._draggingCustomTabFrame = self._tabList[i]; - - var $panelTab = $(event.target).hasClass('wcPanelTab')? $(event.target): $(event.target).parent('.wcPanelTab'); - if ($panelTab && $panelTab.length) { - var index = parseInt($panelTab.attr('id')); - self._draggingCustomTabFrame.tab(index, true); - self._draggingFrameTab = $panelTab[0]; - } - break; - } - } - if (self._draggingFrame) { - self.__focus(self._draggingFrame); - } - return true; - }); - - // Mouse down on a panel will put it into focus. - $('body').on('mousedown', '.wcLayout', function(event) { - if (event.which === 3) { - return true; - } - for (var i = 0; i < self._frameList.length; ++i) { - if (self._frameList[i].panel().layout().scene()[0] == this) { - setTimeout(function() { - self.__focus(self._frameList[i]); - }, 10); - break; - } - } - return true; - }); - - // Floating frames have resizable edges. - $('body').on('mousedown', '.wcFrameEdge', function(event) { - if (event.which === 3) { - return true; - } - self.$container.addClass('wcDisableSelection'); - for (var i = 0; i < self._frameList.length; ++i) { - if (self._frameList[i]._isFloating) { - if (self._frameList[i].$top[0] == this) { - self._draggingFrame = self._frameList[i]; - self._draggingFrameSizer = ['top']; - break; - } else if (self._frameList[i].$bottom[0] == this) { - self._draggingFrame = self._frameList[i]; - self._draggingFrameSizer = ['bottom']; - break; - } else if (self._frameList[i].$left[0] == this) { - self._draggingFrame = self._frameList[i]; - self._draggingFrameSizer = ['left']; - break; - } else if (self._frameList[i].$right[0] == this) { - self._draggingFrame = self._frameList[i]; - self._draggingFrameSizer = ['right']; - break; - } else if (self._frameList[i].$corner1[0] == this) { - self._draggingFrame = self._frameList[i]; - self._draggingFrameSizer = ['top', 'left']; - break; - } else if (self._frameList[i].$corner2[0] == this) { - self._draggingFrame = self._frameList[i]; - self._draggingFrameSizer = ['top', 'right']; - break; - } else if (self._frameList[i].$corner3[0] == this) { - self._draggingFrame = self._frameList[i]; - self._draggingFrameSizer = ['bottom', 'right']; - break; - } else if (self._frameList[i].$corner4[0] == this) { - self._draggingFrame = self._frameList[i]; - self._draggingFrameSizer = ['bottom', 'left']; - break; - } - } - } - if (self._draggingFrame) { - self.__focus(self._draggingFrame); - } - return true; - }); - - // Mouse move will allow you to move an object that is being dragged. - $('body').on('mousemove', function(event) { - if (event.which === 3) { - return true; - } - if (self._draggingSplitter) { - var mouse = { - x: event.clientX, - y: event.clientY, - }; - self._draggingSplitter.__moveBar(mouse); - self._draggingSplitter.__update(); - } else if (self._draggingFrameSizer) { - var mouse = { - x: event.clientX, - y: event.clientY, - }; - - var offset = self.$container.offset(); - mouse.x += offset.left; - mouse.y += offset.top; - - self._draggingFrame.__resize(self._draggingFrameSizer, mouse); - self._draggingFrame.__update(); - } else if (self._draggingFrame) { - var mouse = { - x: event.clientX, - y: event.clientY, - }; - - if (self._ghost) { - self._ghost.__move(mouse); - - var forceFloat = !(self._draggingFrame._isFloating || event.which === 1); - var found = false; - - // Check anchoring with self. - if (!self._draggingFrame.__checkAnchorDrop(mouse, true, self._ghost, self._draggingFrame._panelList.length > 1 && self._draggingFrameTab)) { - self._draggingFrame.__shadow(true); - if (!forceFloat) { - for (var i = 0; i < self._frameList.length; ++i) { - if (self._frameList[i] !== self._draggingFrame) { - if (self._frameList[i].__checkAnchorDrop(mouse, false, self._ghost, true)) { - // self._draggingFrame.__shadow(true); - return; - } - } - } - } - - self._ghost.anchor(mouse, null); - } else { - self._draggingFrame.__shadow(false); - var $hoverTab = $(event.target).hasClass('wcPanelTab')? $(event.target): $(event.target).parent('.wcPanelTab'); - if (self._draggingFrameTab && $hoverTab && $hoverTab.length && self._draggingFrameTab !== event.target) { - self._draggingFrameTab = self._draggingFrame.__tabMove(parseInt($(self._draggingFrameTab).attr('id')), parseInt($hoverTab.attr('id'))); - } - } - } else if (!self._draggingFrameTab) { - self._draggingFrame.__move(mouse); - self._draggingFrame.__update(); - } - } else if (self._draggingCustomTabFrame) { - var $hoverTab = $(event.target).hasClass('wcPanelTab')? $(event.target): $(event.target).parent('.wcPanelTab'); - if (self._draggingFrameTab && $hoverTab && $hoverTab.length && self._draggingFrameTab !== event.target) { - self._draggingFrameTab = self._draggingCustomTabFrame.moveTab(parseInt($(self._draggingFrameTab).attr('id')), parseInt($hoverTab.attr('id'))); - } - } - return true; - }); - - // Mouse released - $('body').on('mouseup', function(event) { - if (event.which === 3) { - return true; - } - self.$container.removeClass('wcDisableSelection'); - if (self._draggingFrame) { - for (var i = 0; i < self._frameList.length; ++i) { - self._frameList[i].__shadow(false); - } - } - - if (self._ghost && self._draggingFrame) { - var anchor = self._ghost.anchor(); - - if (!anchor) { - var index = self._draggingFrame._curTab; - if (!self._draggingFrameTab) { - self._draggingFrame.panel(0); - } - - var mouse = { - x: event.clientX, - y: event.clientY, - }; - - if (self._draggingFrameTab || !self.__isLastFrame(self._draggingFrame)) { - var panel = self.movePanel(self._draggingFrame.panel(), wcDocker.DOCK_FLOAT); - // Dragging the entire frame. - if (!self._draggingFrameTab) { - while (self._draggingFrame.panel()) - self.movePanel(self._draggingFrame.panel(), wcDocker.DOCK_STACKED, panel); - } - - var frame = panel._parent; - if (frame instanceof wcFrame) { - frame.pos(mouse.x, mouse.y + self._ghost.__rect().h/2 - 10, true); - frame.panel(index); - - frame._size.x = self._ghost.__rect().w; - frame._size.y = self._ghost.__rect().h; - } - - frame.__update(); - } - } else if (!anchor.self) { - var index = self._draggingFrame._curTab; - if (!self._draggingFrameTab) { - self._draggingFrame.panel(0); - } - var panel; - if (anchor.item) { - panel = anchor.item._parent; - } - // If we are dragging a tab to split its own container, find another - // tab item within the same frame and split from there. - if (panel === self._draggingFrame.panel()) { - for (var i = 0; i < self._draggingFrame._panelList.length; ++i) { - if (panel !== self._draggingFrame._panelList[i]) { - panel = self._draggingFrame._panelList[i]; - index--; - break; - } - } - } - panel = self.movePanel(self._draggingFrame.panel(), anchor.loc, panel, self._ghost.rect()); - panel._parent.panel(panel._parent._panelList.length-1, true); - // Dragging the entire frame. - if (!self._draggingFrameTab) { - while (self._draggingFrame.panel()) { - self.movePanel(self._draggingFrame.panel(), wcDocker.DOCK_STACKED, panel, self._ghost.rect()); - } - } else { - var frame = panel._parent; - if (frame instanceof wcFrame) { - index = index + frame._panelList.length; - } - } - - var frame = panel._parent; - if (frame instanceof wcFrame) { - frame.panel(index); - } - } - self._ghost.destroy(); - self._ghost = null; - - self.trigger(wcDocker.EVENT_END_DOCK); - } - - if ( self._draggingSplitter ) { - self._draggingSplitter.$pane[0].removeClass('wcResizing'); - self._draggingSplitter.$pane[1].removeClass('wcResizing'); - } - - self._draggingSplitter = null; - self._draggingFrame = null; - self._draggingFrameSizer = null; - self._draggingFrameTab = null; - self._draggingCustomTabFrame = null; - self._removingPanel = null; - return true; - }); - - // Middle mouse button on a panel tab to close it. - $('body').on('mousedown', '.wcPanelTab', function(event) { - if (event.which !== 2) { - return; - } - - var index = parseInt($(this).attr('id')); - - for (var i = 0; i < self._frameList.length; ++i) { - var frame = self._frameList[i]; - if (frame.$title[0] === $(this).parents('.wcFrameTitle')[0]) { - var panel = frame._panelList[index]; - self._removingPanel = panel; - return; - } - } - }); - }, - - // Updates the sizing of all panels inside this window. - __update: function() { - if (this._root) { - this._root.__update(); - } - - for (var i = 0; i < this._floatingList.length; ++i) { - this._floatingList[i].__update(); - } - }, - - // On window resized event. - __resize: function(event) { - this._resizeData.time = new Date(); - if (!this._resizeData.timeout) { - this._resizeData.timeout = true; - setTimeout(this.__resizeEnd.bind(this), this._resizeData.delta); - this.__trigger(wcDocker.EVENT_RESIZE_STARTED); - } - this.__trigger(wcDocker.EVENT_RESIZED); - this.__update(); - }, - - // On window resize event ended. - __resizeEnd: function() { - if (new Date() - this._resizeData.time < this._resizeData.delta) { - setTimeout(this.__resizeEnd.bind(this), this._resizeData.delta); - } else { - this._resizeData.timeout = false; - this.__trigger(wcDocker.EVENT_RESIZE_ENDED); - } - }, - - // Brings a floating window to the top. - // Params: - // frame The frame to focus. - // flash Whether to flash the frame. - __focus: function(frame, flash) { - var reorder = this._focusFrame != frame; - if (this._focusFrame) { - if (this._focusFrame._isFloating) { - this._focusFrame.$frame.removeClass('wcFloatingFocus'); - } - - this._focusFrame.__trigger(wcDocker.EVENT_LOST_FOCUS); - this._focusFrame = null; - } - - this._focusFrame = frame; - if (this._focusFrame) { - if (this._focusFrame._isFloating) { - this._focusFrame.$frame.addClass('wcFloatingFocus'); - - if (reorder) { - $('body').append(this._focusFrame.$frame); - } - } - this._focusFrame.__focus(flash); - - this._focusFrame.__trigger(wcDocker.EVENT_GAIN_FOCUS); - } - }, - - // Triggers an event exclusively on the docker and none of its panels. - // Params: - // eventName The name of the event. - // data A custom data parameter to pass to all handlers. - __trigger: function(eventName, data) { - if (!eventName) { - return; - } - - if (this._events[eventName]) { - for (var i = 0; i < this._events[eventName].length; ++i) { - this._events[eventName][i].call(this, data); - } - } - }, - - // Checks a given panel to see if it is the final remaining - // moveable panel in the docker. - // Params: - // panel The panel. - // Returns: - // true The panel is the last. - // false The panel is not the last. - __isLastPanel: function(panel) { - for (var i = 0; i < this._frameList.length; ++i) { - var testFrame = this._frameList[i]; - if (testFrame._isFloating) { - continue; - } - for (var a = 0; a < testFrame._panelList.length; ++a) { - var testPanel = testFrame._panelList[a]; - if (testPanel !== panel && testPanel.moveable()) { - return false; - } - } - } - - return true; - }, - - // Checks a given frame to see if it is the final remaining - // moveable frame in the docker. - // Params: - // frame The frame. - // Returns: - // true The panel is the last. - // false The panel is not the last. - __isLastFrame: function(frame) { - for (var i = 0; i < this._frameList.length; ++i) { - var testFrame = this._frameList[i]; - if (testFrame._isFloating || testFrame === frame) { - continue; - } - for (var a = 0; a < testFrame._panelList.length; ++a) { - var testPanel = testFrame._panelList[a]; - if (testPanel.moveable()) { - return false; - } - } - } - - return true; - }, - - // For restore, creates the appropriate object type. - __create: function(data, parent, $container) { - switch (data.type) { - case 'wcSplitter': - var splitter = new wcSplitter($container, parent, data.horizontal); - splitter.scrollable(0, false, false); - splitter.scrollable(1, false, false); - return splitter; - - case 'wcFrame': - var frame = new wcFrame($container, parent, data.floating); - this._frameList.push(frame); - if (data.floating) { - this._floatingList.push(frame); - } - return frame; - - case 'wcPanel': - for (var i = 0; i < this._dockPanelTypeList.length; ++i) { - if (this._dockPanelTypeList[i].name === data.panelType) { - var panel = new wcPanel(data.panelType, this._dockPanelTypeList[i].options); - panel._parent = parent; - panel.__container(this.$transition); - var options = (this._dockPanelTypeList[i].options && this._dockPanelTypeList[i].options.options) || {}; - panel._panelObject = new this._dockPanelTypeList[i].options.onCreate(panel, options); - panel.__container($container); - break; - } - } - return panel; - } - - return null; - }, - - // Creates a new frame for the panel and then attaches it - // to the window. - // Params: - // panel The panel to insert. - // location The desired location for the panel. - // parentPanel An optional panel to 'split', if not supplied the - // new panel will split the center window. - __addPanelAlone: function(panel, location, parentPanel, rect) { - // Floating windows need no placement. - if (location === wcDocker.DOCK_FLOAT || location === wcDocker.DOCK_MODAL) { - var frame = new wcFrame(this.$container, this, true); - this._frameList.push(frame); - this._floatingList.push(frame); - this.__focus(frame); - frame.addPanel(panel); - frame.pos(panel._pos.x, panel._pos.y, false); - - if (location === wcDocker.DOCK_MODAL) { - frame.$modalBlocker = $('
'); - frame.$frame.prepend(frame.$modalBlocker); - - panel.moveable(false); - frame.$frame.addClass('wcModal'); - this._modalList.push(frame); - } - - if (rect) { - if (rect.hasOwnProperty('x') && rect.hasOwnProperty('y')) { - frame.pos(rect.x + rect.w/2, rect.y + rect.h/2, true); - } - frame._size = { - x: rect.w, - y: rect.h, - }; - } - return; - } - - if (parentPanel) { - var parentFrame = parentPanel._parent; - if (parentFrame instanceof wcFrame) { - var parentSplitter = parentFrame._parent; - if (parentSplitter instanceof wcSplitter) { - var splitter; - var left = parentSplitter.pane(0); - var right = parentSplitter.pane(1); - var size = { - x: -1, - y: -1, - }; - if (left === parentFrame) { - splitter = new wcSplitter(this.$transition, parentSplitter, location !== wcDocker.DOCK_BOTTOM && location !== wcDocker.DOCK_TOP); - parentSplitter.pane(0, splitter); - size.x = parentSplitter.$pane[0].width(); - size.y = parentSplitter.$pane[0].height(); - } else { - splitter = new wcSplitter(this.$transition, parentSplitter, location !== wcDocker.DOCK_BOTTOM && location !== wcDocker.DOCK_TOP); - parentSplitter.pane(1, splitter); - size.x = parentSplitter.$pane[1].width(); - size.y = parentSplitter.$pane[1].height(); - } - - if (splitter) { - splitter.scrollable(0, false, false); - splitter.scrollable(1, false, false); - frame = new wcFrame(this.$transition, splitter, false); - this._frameList.push(frame); - if (location === wcDocker.DOCK_LEFT || location === wcDocker.DOCK_TOP) { - splitter.pane(0, frame); - splitter.pane(1, parentFrame); - } else { - splitter.pane(0, parentFrame); - splitter.pane(1, frame); - } - - if (!rect) { - rect = { - w: panel._size.x, - h: panel._size.y, - }; - } - - if (rect) { - if (rect.w < 0) { - rect.w = size.x/2; - } - if (rect.h < 0) { - rect.h = size.y/2; - } - - if (location === wcDocker.DOCK_LEFT) { - splitter.pos(rect.w / size.x); - } else if (location === wcDocker.DOCK_RIGHT) { - splitter.pos(1.0 - (rect.w / size.x)); - } else if (location === wcDocker.DOCK_TOP) { - splitter.pos(rect.h / size.y); - } else { - splitter.pos(1.0 - (rect.h / size.y)); - } - } else { - splitter.pos(0.5); - } - - frame.addPanel(panel); - } - return; - } - } - } - - var frame = new wcFrame(this.$transition, this, false); - this._frameList.push(frame); - - if (!this._root) { - this._root = frame; - frame.__container(this.$container); - } else { - var splitter = new wcSplitter(this.$container, this, location !== wcDocker.DOCK_BOTTOM && location !== wcDocker.DOCK_TOP); - if (splitter) { - frame._parent = splitter; - splitter.scrollable(0, false, false); - splitter.scrollable(1, false, false); - var size = { - x: this.$container.width(), - y: this.$container.height(), - }; - - if (location === wcDocker.DOCK_LEFT || location === wcDocker.DOCK_TOP) { - splitter.pane(0, frame); - splitter.pane(1, this._root); - } else { - splitter.pane(0, this._root); - splitter.pane(1, frame); - } - - if (!rect) { - splitter.__findBestPos(); - } else { - if (rect.w < 0) { - rect.w = size.x/2; - } - if (rect.h < 0) { - rect.h = size.y/2; - } - - if (location === wcDocker.DOCK_LEFT) { - splitter.pos(rect.w / size.x); - } else if (location === wcDocker.DOCK_RIGHT) { - splitter.pos(1.0 - (rect.w / size.x)); - } else if (location === wcDocker.DOCK_TOP) { - splitter.pos(rect.h / size.y); - } else { - splitter.pos(1.0 - (rect.h / size.y)); - } - } - - this._root = splitter; - } - } - - frame.addPanel(panel); - }, - - // Attempts to insert a given dock panel into an already existing frame. - // If insertion is not possible for any reason, the panel will be - // placed in its own frame instead. - // Params: - // panel The panel to insert. - // location The desired location for the panel. - // parentPanel An optional panel to 'split', if not supplied the - // new panel will split the center window. - __addPanelGrouped: function(panel, location, parentPanel) { - if (parentPanel) { - var frame = parentPanel._parent; - if (frame instanceof wcFrame) { - frame.addPanel(panel); - return; - } - } - - // Floating windows need no placement. - if (location === wcDocker.DOCK_FLOAT) { - var frame; - if (this._floatingList.length) { - frame = this._floatingList[this._floatingList.length-1]; - } - if (!frame) { - this.__addPanelAlone(panel, location); - return; - } - frame.addPanel(panel); - return; - } - - var needsHorizontal = location !== wcDocker.DOCK_BOTTOM; - - function ___iterateParents(item) { - if (item instanceof wcSplitter) { - var left = item.pane(0); - var right = item.pane(1); - - // Check if the orientation of the splitter is one that we want. - if (item.orientation() === needsHorizontal) { - // Make sure the dock panel is on the proper side. - if (left instanceof wcFrame && (location === wcDocker.DOCK_LEFT || location === wcDocker.DOCK_TOP)) { - left.addPanel(panel); - return true; - } else if (right instanceof wcFrame && (location === wcDocker.DOCK_RIGHT || location === wcDocker.DOCK_BOTTOM)) { - right.addPanel(panel); - return true; - } - - // This splitter was not valid, continue iterating through parents. - } - - // If it isn't, iterate to which ever pane is not a dock panel. - if (!(left instanceof wcFrame)) { - return ___iterateParents.call(this, left); - } else { - return ___iterateParents.call(this, right); - } - } - return false; - }; - - if (!___iterateParents.call(this, this._root)) { - // If we did not manage to find a place for this panel, last resort is to put it in its own frame. - this.__addPanelAlone(panel, location); - } - }, -}; diff --git a/web/pgadmin/static/js/wcDocker/frame.js b/web/pgadmin/static/js/wcDocker/frame.js deleted file mode 100755 index 8d49d4fc6..000000000 --- a/web/pgadmin/static/js/wcDocker/frame.js +++ /dev/null @@ -1,843 +0,0 @@ -/* - The frame is a container for a panel, and can contain multiple panels inside it, each appearing - as a tabbed item. All docking panels have a frame, but the frame can change any time the panel - is moved. -*/ -function wcFrame(container, parent, isFloating) { - this.$container = $(container); - this._parent = parent; - this._isFloating = isFloating; - - this.$frame = null; - this.$title = null; - this.$tabScroll = null; - this.$center = null; - this.$tabLeft = null; - this.$tabRight = null; - this.$close = null; - this.$top = null; - this.$bottom = null; - this.$left = null; - this.$right = null; - this.$corner1 = null; - this.$corner2 = null; - this.$corner3 = null; - this.$corner4 = null; - - this.$shadower = null; - this.$modalBlocker = null; - - this._canScrollTabs = false; - this._tabScrollPos = 0; - this._curTab = -1; - this._panelList = []; - this._buttonList = []; - - this._resizeData = { - time: -1, - timeout: false, - delta: 150, - }; - - this._pos = { - x: 0.5, - y: 0.5, - }; - - this._size = { - x: 400, - y: 400, - }; - - this._lastSize = { - x: 400, - y: 400, - }; - - this._anchorMouse = { - x: 0, - y: 0, - }; - - this.__init(); -}; - -wcFrame.prototype = { - LEFT_TAB_BUFFER: 15, - -/////////////////////////////////////////////////////////////////////////////////////////////////////// -// Public Functions -/////////////////////////////////////////////////////////////////////////////////////////////////////// - - // Gets, or Sets the position of the frame. - // Params: - // x, y If supplied, assigns the new position. - // pixels If true, the coordinates given will be treated as a - // pixel position rather than a percentage. - pos: function(x, y, pixels) { - var width = this.$container.width(); - var height = this.$container.height(); - - if (typeof x === 'undefined') { - if (pixels) { - return {x: this._pos.x*width, y: this._pos.y*height}; - } else { - return {x: this._pos.x, y: this._pos.y}; - } - } - - if (pixels) { - this._pos.x = x/width; - this._pos.y = y/height; - } else { - this._pos.x = x; - this._pos.y = y; - } - }, - - // Gets the desired size of the panel. - initSize: function() { - var size = { - x: -1, - y: -1, - }; - - for (var i = 0; i < this._panelList.length; ++i) { - if (size.x < this._panelList[i].initSize().x) { - size.x = this._panelList[i].initSize().x; - } - if (size.y < this._panelList[i].initSize().y) { - size.y = this._panelList[i].initSize().y; - } - } - - if (size.x < 0 || size.y < 0) { - return false; - } - return size; - }, - - // Gets the minimum size of the panel. - minSize: function() { - var size = { - x: 0, - y: 0, - }; - - for (var i = 0; i < this._panelList.length; ++i) { - size.x = Math.max(size.x, this._panelList[i].minSize().x); - size.y = Math.max(size.y, this._panelList[i].minSize().y); - } - return size; - }, - - // Gets the minimum size of the panel. - maxSize: function() { - var size = { - x: Infinity, - y: Infinity, - }; - - for (var i = 0; i < this._panelList.length; ++i) { - size.x = Math.min(size.x, this._panelList[i].maxSize().x); - size.y = Math.min(size.y, this._panelList[i].maxSize().y); - } - return size; - }, - - // Adds a given panel as a new tab item. - // Params: - // panel The panel to add. - // index An optional index to insert the tab at. - addPanel: function(panel, index) { - var found = this._panelList.indexOf(panel); - if (found !== -1) { - this._panelList.splice(found, 1); - } - - if (typeof index === 'undefined') { - this._panelList.push(panel); - } else { - this._panelList.splice(index, 0, panel); - } - - if (this._curTab === -1 && this._panelList.length) { - this._curTab = 0; - this._size = this.initSize(); - } - - this.__updateTabs(); - }, - - // Removes a given panel from the tab item. - // Params: - // panel The panel to remove. - // Returns: - // bool Returns whether or not any panels still remain. - removePanel: function(panel) { - for (var i = 0; i < this._panelList.length; ++i) { - if (this._panelList[i] === panel) { - if (this._curTab >= i) { - this._curTab--; - } - - this._panelList[i].__container(null); - this._panelList[i]._parent = null; - - this._panelList.splice(i, 1); - break; - } - } - - if (this._curTab === -1 && this._panelList.length) { - this._curTab = 0; - } - - this.__updateTabs(); - return this._panelList.length > 0; - }, - - // Gets, or Sets the currently visible panel. - // Params: - // tabIndex If supplied, sets the current tab. - // Returns: - // wcPanel The currently visible panel. - panel: function(tabIndex, autoFocus) { - if (typeof tabIndex !== 'undefined') { - if (tabIndex > -1 && tabIndex < this._panelList.length) { - this.$title.find('> .wcTabScroller > .wcPanelTab[id="' + this._curTab + '"]').removeClass('wcPanelTabActive'); - this.$center.children('.wcPanelTabContent[id="' + this._curTab + '"]').addClass('wcPanelTabContentHidden'); - this._curTab = tabIndex; - this.$title.find('> .wcTabScroller > .wcPanelTab[id="' + tabIndex + '"]').addClass('wcPanelTabActive'); - this.$center.children('.wcPanelTabContent[id="' + tabIndex + '"]').removeClass('wcPanelTabContentHidden'); - this.__updateTabs(autoFocus); - } - } - - if (this._curTab > -1 && this._curTab < this._panelList.length) { - return this._panelList[this._curTab]; - } - return false; - }, - - -/////////////////////////////////////////////////////////////////////////////////////////////////////// -// Private Functions -/////////////////////////////////////////////////////////////////////////////////////////////////////// - - // Initialize - __init: function() { - this.$frame = $('
'); - this.$title = $('
'); - this.$tabScroll = $('
'); - this.$center = $('
'); - this.$tabLeft = $('
<
'); - this.$tabRight = $('
>
'); - this.$close = $('
X
'); - // this.$frame.append(this.$title); - this.$title.append(this.$tabScroll); - this.$frame.append(this.$close); - - if (this._isFloating) { - this.$top = $('
').css('top', '-6px').css('left', '0px').css('right', '0px'); - this.$bottom = $('
').css('bottom', '-6px').css('left', '0px').css('right', '0px'); - this.$left = $('
').css('left', '-6px').css('top', '0px').css('bottom', '0px'); - this.$right = $('
').css('right', '-6px').css('top', '0px').css('bottom', '0px'); - this.$corner1 = $('
').css('top', '-6px').css('left', '-6px'); - this.$corner2 = $('
').css('top', '-6px').css('right', '-6px'); - this.$corner3 = $('
').css('bottom', '-6px').css('right', '-6px'); - this.$corner4 = $('
').css('bottom', '-6px').css('left', '-6px'); - - this.$frame.append(this.$top); - this.$frame.append(this.$bottom); - this.$frame.append(this.$left); - this.$frame.append(this.$right); - this.$frame.append(this.$corner1); - this.$frame.append(this.$corner2); - this.$frame.append(this.$corner3); - this.$frame.append(this.$corner4); - } - - this.$frame.append(this.$center); - - // Floating windows have no container. - this.__container(this.$container); - - if (this._isFloating) { - this.$frame.addClass('wcFloating'); - } - - this.$center.scroll(this.__scrolled.bind(this)); - }, - - // Updates the size of the frame. - __update: function() { - var width = this.$container.width(); - var height = this.$container.height(); - - // Floating windows manage their own sizing. - if (this._isFloating) { - var left = (this._pos.x * width) - this._size.x/2; - var top = (this._pos.y * height) - this._size.y/2; - - if (top < 0) { - top = 0; - } - - if (left + this._size.x/2 < 0) { - left = -this._size.x/2; - } - - if (left + this._size.x/2 > width) { - left = width - this._size.x/2; - } - - if (top + parseInt(this.$center.css('top')) > height) { - top = height - parseInt(this.$center.css('top')); - } - - this.$frame.css('left', left + 'px'); - this.$frame.css('top', top + 'px'); - this.$frame.css('width', this._size.x + 'px'); - this.$frame.css('height', this._size.y + 'px'); - } - - if (width !== this._lastSize.x || height !== this._lastSize.y) { - this._lastSize.x = width; - this._lastSize.y = height; - - this._resizeData.time = new Date(); - if (!this._resizeData.timeout) { - this._resizeData.timeout = true; - setTimeout(this.__resizeEnd.bind(this), this._resizeData.delta); - } - } - // this.__updateTabs(); - this.__onTabChange(); - }, - - __resizeEnd: function() { - this.__updateTabs(); - if (new Date() - this._resizeData.time < this._resizeData.delta) { - setTimeout(this.__resizeEnd.bind(this), this._resizeData.delta); - } else { - this._resizeData.timeout = false; - } - }, - - // Triggers an event exclusively on the docker and none of its panels. - // Params: - // eventName The name of the event. - // data A custom data parameter to pass to all handlers. - __trigger: function(eventName, data) { - for (var i = 0; i < this._panelList.length; ++i) { - this._panelList[i].__trigger(eventName, data); - } - }, - - // Saves the current panel configuration into a meta - // object that can be used later to restore it. - __save: function() { - var data = {}; - data.type = 'wcFrame'; - data.floating = this._isFloating; - data.isFocus = this.$frame.hasClass('wcFloatingFocus') - data.pos = { - x: this._pos.x, - y: this._pos.y, - }; - data.size = { - x: this._size.x, - y: this._size.y, - }; - data.tab = this._curTab; - data.panels = []; - for (var i = 0; i < this._panelList.length; ++i) { - data.panels.push(this._panelList[i].__save()); - } - return data; - }, - - // Restores a previously saved configuration. - __restore: function(data, docker) { - this._isFloating = data.floating; - this._pos.x = data.pos.x; - this._pos.y = data.pos.y; - this._size.x = data.size.x; - this._size.y = data.size.y; - this._curTab = data.tab; - for (var i = 0; i < data.panels.length; ++i) { - var panel = docker.__create(data.panels[i], this, this.$center); - panel.__restore(data.panels[i], docker); - this._panelList.push(panel); - } - - this.__update(); - - if (data.isFocus) { - this.$frame.addClass('wcFloatingFocus'); - } - }, - - __updateTabs: function(autoFocus) { - this.$tabScroll.empty(); - - // Move all tabbed panels to a temporary element to preserve event handlers on them. - // var $tempCenter = $('
'); - // this.$frame.append($tempCenter); - // this.$center.children().appendTo($tempCenter); - - var visibilityChanged = []; - var tabPositions = []; - var totalWidth = 0; - var parentLeft = this.$tabScroll.offset().left; - var self = this; - - this.$title.removeClass('wcNotMoveable'); - - this.$center.children('.wcPanelTabContent').each(function() { - $(this).addClass('wcPanelTabContentHidden wcPanelTabUnused'); - }); - - var titleVisible = true; - - for (var i = 0; i < this._panelList.length; ++i) { - var panel = this._panelList[i]; - - var $tab = $('
' + panel.title() + '
'); - this.$tabScroll.append($tab); - if (panel.$icon) { - $tab.prepend(panel.$icon); - } - - $tab.toggleClass('wcNotMoveable', !panel.moveable()); - if (!panel.moveable()) { - this.$title.addClass('wcNotMoveable'); - } - - // - if (!panel._titleVisible) { - titleVisible = false; - } - - var $tabContent = this.$center.children('.wcPanelTabContent[id="' + i + '"]'); - if (!$tabContent.length) { - $tabContent = $('
'); - this.$center.append($tabContent); - } - - panel.__container($tabContent); - panel._parent = this; - - var isVisible = this._curTab === i; - if (panel.isVisible() !== isVisible) { - visibilityChanged.push({ - panel: panel, - isVisible: isVisible, - }); - } - - $tabContent.removeClass('wcPanelTabUnused'); - - if (isVisible) { - $tab.addClass('wcPanelTabActive'); - $tabContent.removeClass('wcPanelTabContentHidden'); - } - - totalWidth = $tab.offset().left - parentLeft; - tabPositions.push(totalWidth); - - totalWidth += $tab.outerWidth(); - } - - if (titleVisible) { - this.$frame.prepend(this.$title); - if (!this.$frame.parent()) { - this.$center.css('top', ''); - } - } else { - this.$title.remove(); - this.$center.css('top', '0px'); - } - - // Now remove all unused panel tabs. - this.$center.children('.wcPanelTabUnused').each(function() { - $(this).remove(); - }); - - // $tempCenter.remove(); - if (titleVisible) { - var buttonSize = this.__onTabChange(); - - if (autoFocus) { - for (var i = 0; i < tabPositions.length; ++i) { - if (i === this._curTab) { - var left = tabPositions[i]; - var right = totalWidth; - if (i+1 < tabPositions.length) { - right = tabPositions[i+1]; - } - - var scrollPos = -parseInt(this.$tabScroll.css('left')); - var titleWidth = this.$title.width() - buttonSize; - - // If the tab is behind the current scroll position. - if (left < scrollPos) { - this._tabScrollPos = left - this.LEFT_TAB_BUFFER; - if (this._tabScrollPos < 0) { - this._tabScrollPos = 0; - } - } - // If the tab is beyond the current scroll position. - else if (right - scrollPos > titleWidth) { - this._tabScrollPos = right - titleWidth + this.LEFT_TAB_BUFFER; - } - break; - } - } - } - - this._canScrollTabs = false; - if (totalWidth > this.$title.width() - buttonSize) { - this._canScrollTabs = titleVisible; - this.$frame.append(this.$tabRight); - this.$frame.append(this.$tabLeft); - var scrollLimit = totalWidth - (this.$title.width() - buttonSize)/2; - // If we are beyond our scroll limit, clamp it. - if (this._tabScrollPos > scrollLimit) { - var children = this.$tabScroll.children(); - for (var i = 0; i < children.length; ++i) { - var $tab = $(children[i]); - - totalWidth = $tab.offset().left - parentLeft; - if (totalWidth + $tab.outerWidth() > scrollLimit) { - this._tabScrollPos = totalWidth - this.LEFT_TAB_BUFFER; - if (this._tabScrollPos < 0) { - this._tabScrollPos = 0; - } - break; - } - } - } - } else { - this._tabScrollPos = 0; - this.$tabLeft.remove(); - this.$tabRight.remove(); - } - - this.$tabScroll.stop().animate({left: -this._tabScrollPos + 'px'}, 'fast'); - - // Update visibility on panels. - for (var i = 0; i < visibilityChanged.length; ++i) { - visibilityChanged[i].panel.__isVisible(visibilityChanged[i].isVisible); - } - } - }, - - __onTabChange: function() { - var buttonSize = 0; - var panel = this.panel(); - if (panel) { - var scrollable = panel.scrollable(); - this.$center.toggleClass('wcScrollableX', scrollable.x); - this.$center.toggleClass('wcScrollableY', scrollable.y); - - var overflowVisible = panel.overflowVisible(); - this.$center.toggleClass('wcOverflowVisible', overflowVisible); - - this.$tabLeft.remove(); - this.$tabRight.remove(); - - while (this._buttonList.length) { - this._buttonList.pop().remove(); - } - - if (panel.closeable()) { - this.$close.show(); - buttonSize += this.$close.outerWidth(); - } else { - this.$close.hide(); - } - - for (var i = 0; i < panel._buttonList.length; ++i) { - var buttonData = panel._buttonList[i]; - var $button = $('
'); - var buttonClass = buttonData.className; - $button.addClass('wcFrameButton'); - if (buttonData.isTogglable) { - $button.addClass('wcFrameButtonToggler'); - - if (buttonData.isToggled) { - $button.addClass('wcFrameButtonToggled'); - buttonClass = buttonData.toggleClassName || buttonClass; - } - } - $button.attr('title', buttonData.tip); - $button.data('name', buttonData.name); - $button.text(buttonData.text); - if (buttonClass) { - $button.prepend($('
')); - } - - this._buttonList.push($button); - this.$frame.append($button); - buttonSize += $button.outerWidth(); - } - - if (this._canScrollTabs) { - this.$frame.append(this.$tabRight); - this.$frame.append(this.$tabLeft); - - buttonSize += this.$tabRight.outerWidth() + this.$tabLeft.outerWidth(); - } - - panel.__update(); - - this.$center.scrollLeft(panel._scroll.x); - this.$center.scrollTop(panel._scroll.y); - } - return buttonSize; - }, - - // Handles scroll notifications. - __scrolled: function() { - var panel = this.panel(); - panel._scroll.x = this.$center.scrollLeft(); - panel._scroll.y = this.$center.scrollTop(); - - panel.__trigger(wcDocker.EVENT_SCROLLED); - }, - - // Brings the frame into focus. - // Params: - // flash Optional, if true will flash the window. - __focus: function(flash) { - if (flash) { - var $flasher = $('
'); - this.$frame.append($flasher); - $flasher.animate({ - opacity: 0.25, - },100) - .animate({ - opacity: 0.0, - },100) - .animate({ - opacity: 0.1, - },50) - .animate({ - opacity: 0.0, - },50) - .queue(function(next) { - $flasher.remove(); - next(); - }); - } - }, - - // Moves the panel based on mouse dragging. - // Params: - // mouse The current mouse position. - __move: function(mouse) { - var width = this.$container.width(); - var height = this.$container.height(); - - this._pos.x = (mouse.x + this._anchorMouse.x) / width; - this._pos.y = (mouse.y + this._anchorMouse.y) / height; - }, - - // Sets the anchor position for moving the panel. - // Params: - // mouse The current mouse position. - __anchorMove: function(mouse) { - var width = this.$container.width(); - var height = this.$container.height(); - - this._anchorMouse.x = (this._pos.x * width) - mouse.x; - this._anchorMouse.y = (this._pos.y * height) - mouse.y; - }, - - // Moves a tab from a given index to another index. - // Params: - // fromIndex The current tab index to move. - // toIndex The new index to move to. - // Returns: - // element The new element of the moved tab. - // false If an error occurred. - __tabMove: function(fromIndex, toIndex) { - if (fromIndex >= 0 && fromIndex < this._panelList.length && - toIndex >= 0 && toIndex < this._panelList.length) { - var panel = this._panelList.splice(fromIndex, 1); - this._panelList.splice(toIndex, 0, panel[0]); - - // Preserve the currently active tab. - if (this._curTab === fromIndex) { - this._curTab = toIndex; - } - - this.__updateTabs(); - - return this.$title.find('> .wcTabScroller > .wcPanelTab[id="' + toIndex + '"]')[0]; - } - return false; - }, - - // Checks if the mouse is in a valid anchor position for docking a panel. - // Params: - // mouse The current mouse position. - // same Whether the moving frame and this one are the same. - __checkAnchorDrop: function(mouse, same, ghost, canSplit) { - var panel = this.panel(); - if (panel && panel.moveable()) { - return panel.layout().__checkAnchorDrop(mouse, same, ghost, (!this._isFloating && canSplit), this.$frame, panel.moveable() && panel.title()); - } - return false; - }, - - // Resizes the panel based on mouse dragging. - // Params: - // edges A list of edges being moved. - // mouse The current mouse position. - __resize: function(edges, mouse) { - var width = this.$container.width(); - var height = this.$container.height(); - var offset = this.$container.offset(); - - mouse.x -= offset.left; - mouse.y -= offset.top; - - var minSize = this.minSize(); - var maxSize = this.maxSize(); - - var pos = { - x: (this._pos.x * width) - this._size.x/2, - y: (this._pos.y * height) - this._size.y/2, - }; - - for (var i = 0; i < edges.length; ++i) { - switch (edges[i]) { - case 'top': - this._size.y += pos.y - mouse.y-2; - pos.y = mouse.y+2; - if (this._size.y < minSize.y) { - pos.y += this._size.y - minSize.y; - this._size.y = minSize.y; - } - if (this._size.y > maxSize.y) { - pos.y += this._size.y - maxSize.y; - this._size.y = maxSize.y; - } - break; - case 'bottom': - this._size.y = mouse.y-4 - pos.y; - if (this._size.y < minSize.y) { - this._size.y = minSize.y; - } - if (this._size.y > maxSize.y) { - this._size.y = maxSize.y; - } - break; - case 'left': - this._size.x += pos.x - mouse.x-2; - pos.x = mouse.x+2; - if (this._size.x < minSize.x) { - pos.x += this._size.x - minSize.x; - this._size.x = minSize.x; - } - if (this._size.x > maxSize.x) { - pos.x += this._size.x - maxSize.x; - this._size.x = maxSize.x; - } - break; - case 'right': - this._size.x = mouse.x-4 - pos.x; - if (this._size.x < minSize.x) { - this._size.x = minSize.x; - } - if (this._size.x > maxSize.x) { - this._size.x = maxSize.x; - } - break; - } - - this._pos.x = (pos.x + this._size.x/2) / width; - this._pos.y = (pos.y + this._size.y/2) / height; - } - }, - - // Turn off or on a shadowing effect to signify this widget is being moved. - // Params: - // enabled Whether to enable __shadow mode. - __shadow: function(enabled) { - if (enabled) { - if (!this.$shadower) { - this.$shadower = $('
'); - this.$frame.append(this.$shadower); - this.$shadower.animate({ - opacity: 0.5, - }, 300); - } - } else { - if (this.$shadower) { - var self = this; - this.$shadower.animate({ - opacity: 0.0, - }, 300) - .queue(function(next) { - self.$shadower.remove(); - self.$shadower = null; - next(); - }); - } - } - }, - - // Retrieves the bounding rect for this frame. - __rect: function() { - var offset = this.$frame.offset(); - var width = this.$frame.width(); - var height = this.$frame.height(); - - return { - x: offset.left, - y: offset.top, - w: width, - h: height, - }; - }, - - // Gets, or Sets a new container for this layout. - // Params: - // $container If supplied, sets a new container for this layout. - // parent If supplied, sets a new parent for this layout. - // Returns: - // JQuery collection The current container. - __container: function($container) { - if (typeof $container === 'undefined') { - return this.$container; - } - - this.$container = $container; - if (this.$container) { - this.$container.append(this.$frame); - } else { - this.$frame.remove(); - } - return this.$container; - }, - - // Disconnects and prepares this widget for destruction. - __destroy: function() { - this._curTab = -1; - for (var i = 0; i < this._panelList.length; ++i) { - this._panelList[i].__destroy(); - } - - while (this._panelList.length) this._panelList.pop(); - if (this.$modalBlocker) { - this.$modalBlocker.remove(); - this.$modalBlocker = null; - } - this.__container(null); - this._parent = null; - }, -}; \ No newline at end of file diff --git a/web/pgadmin/static/js/wcDocker/ghost.js b/web/pgadmin/static/js/wcDocker/ghost.js deleted file mode 100755 index 7ffe09663..000000000 --- a/web/pgadmin/static/js/wcDocker/ghost.js +++ /dev/null @@ -1,196 +0,0 @@ -/* - A ghost object that follows the mouse around during dock movement. -*/ -function wcGhost(rect, mouse, docker) { - this.$ghost = null; - this._rect; - this._anchorMouse = false; - this._anchor = null; - this._docker = docker; - - this.__init(rect, mouse); -}; - -wcGhost.prototype = { -/////////////////////////////////////////////////////////////////////////////////////////////////////// -// Public Functions -/////////////////////////////////////////////////////////////////////////////////////////////////////// - - // -------------------------------------------------------------------------------- - // Updates the ghost based on the given screen position. - update: function(position) { - this.__move(position); - - for (var i = 0; i < this._docker._floatingList.length; ++i) { - var rect = this._docker._floatingList[i].__rect(); - if (position.x > rect.x && position.y > rect.y - && position.x < rect.x + rect.w && position.y < rect.y + rect.h) { - - if (!this._docker._floatingList[i].__checkAnchorDrop(position, false, this, true)) { - this.anchor(position, null); - } else { - this._anchor.panel = this._docker._floatingList[i].panel(); - } - return; - } - } - - for (var i = 0; i < this._docker._frameList.length; ++i) { - var rect = this._docker._frameList[i].__rect(); - if (position.x > rect.x && position.y > rect.y - && position.x < rect.x + rect.w && position.y < rect.y + rect.h) { - - if (!this._docker._frameList[i].__checkAnchorDrop(position, false, this, true)) { - this.anchor(position, null); - } else { - this._anchor.panel = this._docker._frameList[i].panel(); - } - return; - } - } - }, - - // -------------------------------------------------------------------------------- - // Get, or Sets the ghost's anchor. - // Params: - // mouse The current mouse position. - // anchor If supplied, assigns a new anchor. - anchor: function(mouse, anchor) { - if (typeof mouse === 'undefined') { - return this._anchor; - } - - if (anchor && this._anchor && anchor.loc === this._anchor.loc && anchor.item === this._anchor.item) { - return; - } - - var rect = { - x: parseInt(this.$ghost.css('left')), - y: parseInt(this.$ghost.css('top')), - w: parseInt(this.$ghost.css('width')), - h: parseInt(this.$ghost.css('height')), - }; - - this._anchorMouse = { - x: rect.x - mouse.x, - y: rect.y - mouse.y, - }; - - this._rect.x = -this._anchorMouse.x; - this._rect.y = -this._anchorMouse.y; - - if (!anchor) { - if (!this._anchor) { - return; - } - - this._anchor = null; - this.$ghost.show(); - this.$ghost.stop().animate({ - opacity: 0.3, - 'margin-left': this._rect.x - this._rect.w/2 + 'px', - 'margin-top': this._rect.y - 10 + 'px', - width: this._rect.w + 'px', - height: this._rect.h + 'px', - }, 150); - return; - } - - this._anchor = anchor; - var opacity = 0.8; - if (anchor.self && anchor.loc === wcDocker.DOCK_STACKED) { - opacity = 0; - this.$ghost.hide(); - } else { - this.$ghost.show(); - } - this.$ghost.stop().animate({ - opacity: opacity, - 'margin-left': '2px', - 'margin-top': '2px', - border: '0px', - left: anchor.x + 'px', - top: anchor.y + 'px', - width: anchor.w + 'px', - height: anchor.h + 'px', - }, 150); - }, - - // -------------------------------------------------------------------------------- - rect: function() { - return { - x: this.$ghost.offset().left, - y: this.$ghost.offset().top, - w: parseInt(this.$ghost.css('width')), - h: parseInt(this.$ghost.css('height')), - }; - }, - - // -------------------------------------------------------------------------------- - destroy: function() { - this.__destroy(); - }, - -/////////////////////////////////////////////////////////////////////////////////////////////////////// -// Private Functions -/////////////////////////////////////////////////////////////////////////////////////////////////////// - - // Initialize - __init: function(rect, mouse) { - this.$ghost = $('
') - .css('opacity', 0) - .css('top', rect.y + 'px') - .css('left', rect.x + 'px') - .css('width', rect.w + 'px') - .css('height', rect.h + 'px'); - - this._anchorMouse = { - x: rect.x - mouse.x, - y: rect.y - mouse.y, - }; - - this._rect = { - x: -this._anchorMouse.x, - y: -this._anchorMouse.y, - w: rect.w, - h: rect.h, - }; - - $('body').append(this.$ghost); - - this.anchor(mouse, rect); - }, - - // Updates the size of the layout. - __move: function(mouse) { - if (this._anchor) { - return; - } - - var x = parseInt(this.$ghost.css('left')); - var y = parseInt(this.$ghost.css('top')); - - x = mouse.x + this._anchorMouse.x; - y = mouse.y + this._anchorMouse.y; - - this.$ghost.css('left', x + 'px'); - this.$ghost.css('top', y + 'px'); - }, - - // Gets the original size of the moving widget. - __rect: function() { - return this._rect; - }, - - // Exorcise the ghost. - __destroy: function() { - this.$ghost.stop().animate({ - opacity: 0.0, - }, { - duration: 175, - complete: function() { - $(this).remove(); - }, - }); - }, -}; \ No newline at end of file diff --git a/web/pgadmin/static/js/wcDocker/iframe.js b/web/pgadmin/static/js/wcDocker/iframe.js deleted file mode 100755 index 7b39460f8..000000000 --- a/web/pgadmin/static/js/wcDocker/iframe.js +++ /dev/null @@ -1,213 +0,0 @@ -function wcIFrame(container, panel) { - - this._panel = panel; - this._layout = panel.layout(); - - this.$container = $(container); - this.$frame = null; - - this._window = null; - this._isAttached = true; - this._hasFocus = false; - - this._boundEvents = []; - - this.__init(); -}; - -wcIFrame.prototype = { - // -------------------------------------------------------------------------------- - docker: function() { - var parent = this._panel; - while (parent && !(parent instanceof wcDocker)) { - parent = parent._parent; - } - return parent; - }, - - // -------------------------------------------------------------------------------- - openURL: function(url) { - this.__clearFrame(); - - this.$frame = $('