| /** |
| * Copyright (c) 2006-2015, JGraph Ltd |
| * Copyright (c) 2006-2015, Gaudenz Alder |
| */ |
| /** |
| * Class: mxWindow |
| * |
| * Basic window inside a document. |
| * |
| * Examples: |
| * |
| * Creating a simple window. |
| * |
| * (code) |
| * var tb = document.createElement('div'); |
| * var wnd = new mxWindow('Title', tb, 100, 100, 200, 200, true, true); |
| * wnd.setVisible(true); |
| * (end) |
| * |
| * Creating a window that contains an iframe. |
| * |
| * (code) |
| * var frame = document.createElement('iframe'); |
| * frame.setAttribute('width', '192px'); |
| * frame.setAttribute('height', '172px'); |
| * frame.setAttribute('src', 'http://www.example.com/'); |
| * frame.style.backgroundColor = 'white'; |
| * |
| * var w = document.body.clientWidth; |
| * var h = (document.body.clientHeight || document.documentElement.clientHeight); |
| * var wnd = new mxWindow('Title', frame, (w-200)/2, (h-200)/3, 200, 200); |
| * wnd.setVisible(true); |
| * (end) |
| * |
| * To limit the movement of a window, eg. to keep it from being moved beyond |
| * the top, left corner the following method can be overridden (recommended): |
| * |
| * (code) |
| * wnd.setLocation = function(x, y) |
| * { |
| * x = Math.max(0, x); |
| * y = Math.max(0, y); |
| * mxWindow.prototype.setLocation.apply(this, arguments); |
| * }; |
| * (end) |
| * |
| * Or the following event handler can be used: |
| * |
| * (code) |
| * wnd.addListener(mxEvent.MOVE, function(e) |
| * { |
| * wnd.setLocation(Math.max(0, wnd.getX()), Math.max(0, wnd.getY())); |
| * }); |
| * (end) |
| * |
| * To keep a window inside the current window: |
| * |
| * (code) |
| * mxEvent.addListener(window, 'resize', mxUtils.bind(this, function() |
| * { |
| * var iw = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; |
| * var ih = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; |
| * |
| * var x = this.window.getX(); |
| * var y = this.window.getY(); |
| * |
| * if (x + this.window.table.clientWidth > iw) |
| * { |
| * x = Math.max(0, iw - this.window.table.clientWidth); |
| * } |
| * |
| * if (y + this.window.table.clientHeight > ih) |
| * { |
| * y = Math.max(0, ih - this.window.table.clientHeight); |
| * } |
| * |
| * if (this.window.getX() != x || this.window.getY() != y) |
| * { |
| * this.window.setLocation(x, y); |
| * } |
| * })); |
| * (end) |
| * |
| * Event: mxEvent.MOVE_START |
| * |
| * Fires before the window is moved. The <code>event</code> property contains |
| * the corresponding mouse event. |
| * |
| * Event: mxEvent.MOVE |
| * |
| * Fires while the window is being moved. The <code>event</code> property |
| * contains the corresponding mouse event. |
| * |
| * Event: mxEvent.MOVE_END |
| * |
| * Fires after the window is moved. The <code>event</code> property contains |
| * the corresponding mouse event. |
| * |
| * Event: mxEvent.RESIZE_START |
| * |
| * Fires before the window is resized. The <code>event</code> property contains |
| * the corresponding mouse event. |
| * |
| * Event: mxEvent.RESIZE |
| * |
| * Fires while the window is being resized. The <code>event</code> property |
| * contains the corresponding mouse event. |
| * |
| * Event: mxEvent.RESIZE_END |
| * |
| * Fires after the window is resized. The <code>event</code> property contains |
| * the corresponding mouse event. |
| * |
| * Event: mxEvent.MAXIMIZE |
| * |
| * Fires after the window is maximized. The <code>event</code> property |
| * contains the corresponding mouse event. |
| * |
| * Event: mxEvent.MINIMIZE |
| * |
| * Fires after the window is minimized. The <code>event</code> property |
| * contains the corresponding mouse event. |
| * |
| * Event: mxEvent.NORMALIZE |
| * |
| * Fires after the window is normalized, that is, it returned from |
| * maximized or minimized state. The <code>event</code> property contains the |
| * corresponding mouse event. |
| * |
| * Event: mxEvent.ACTIVATE |
| * |
| * Fires after a window is activated. The <code>previousWindow</code> property |
| * contains the previous window. The event sender is the active window. |
| * |
| * Event: mxEvent.SHOW |
| * |
| * Fires after the window is shown. This event has no properties. |
| * |
| * Event: mxEvent.HIDE |
| * |
| * Fires after the window is hidden. This event has no properties. |
| * |
| * Event: mxEvent.CLOSE |
| * |
| * Fires before the window is closed. The <code>event</code> property contains |
| * the corresponding mouse event. |
| * |
| * Event: mxEvent.DESTROY |
| * |
| * Fires before the window is destroyed. This event has no properties. |
| * |
| * Constructor: mxWindow |
| * |
| * Constructs a new window with the given dimension and title to display |
| * the specified content. The window elements use the given style as a |
| * prefix for the classnames of the respective window elements, namely, |
| * the window title and window pane. The respective postfixes are appended |
| * to the given stylename as follows: |
| * |
| * style - Base style for the window. |
| * style+Title - Style for the window title. |
| * style+Pane - Style for the window pane. |
| * |
| * The default value for style is mxWindow, resulting in the following |
| * classnames for the window elements: mxWindow, mxWindowTitle and |
| * mxWindowPane. |
| * |
| * If replaceNode is given then the window replaces the given DOM node in |
| * the document. |
| * |
| * Parameters: |
| * |
| * title - String that represents the title of the new window. |
| * content - DOM node that is used as the window content. |
| * x - X-coordinate of the window location. |
| * y - Y-coordinate of the window location. |
| * width - Width of the window. |
| * height - Optional height of the window. Default is to match the height |
| * of the content at the specified width. |
| * minimizable - Optional boolean indicating if the window is minimizable. |
| * Default is true. |
| * movable - Optional boolean indicating if the window is movable. Default |
| * is true. |
| * replaceNode - Optional DOM node that the window should replace. |
| * style - Optional base classname for the window elements. Default is |
| * mxWindow. |
| */ |
| function mxWindow(title, content, x, y, width, height, minimizable, movable, replaceNode, style) |
| { |
| if (content != null) |
| { |
| minimizable = (minimizable != null) ? minimizable : true; |
| this.content = content; |
| this.init(x, y, width, height, style); |
| |
| this.installMaximizeHandler(); |
| this.installMinimizeHandler(); |
| this.installCloseHandler(); |
| this.setMinimizable(minimizable); |
| this.setTitle(title); |
| |
| if (movable == null || movable) |
| { |
| this.installMoveHandler(); |
| } |
| |
| if (replaceNode != null && replaceNode.parentNode != null) |
| { |
| replaceNode.parentNode.replaceChild(this.div, replaceNode); |
| } |
| else |
| { |
| document.body.appendChild(this.div); |
| } |
| } |
| }; |
| |
| /** |
| * Extends mxEventSource. |
| */ |
| mxWindow.prototype = new mxEventSource(); |
| mxWindow.prototype.constructor = mxWindow; |
| |
| /** |
| * Variable: closeImage |
| * |
| * URL of the image to be used for the close icon in the titlebar. |
| */ |
| mxWindow.prototype.closeImage = mxClient.imageBasePath + '/close.gif'; |
| |
| /** |
| * Variable: minimizeImage |
| * |
| * URL of the image to be used for the minimize icon in the titlebar. |
| */ |
| mxWindow.prototype.minimizeImage = mxClient.imageBasePath + '/minimize.gif'; |
| |
| /** |
| * Variable: normalizeImage |
| * |
| * URL of the image to be used for the normalize icon in the titlebar. |
| */ |
| mxWindow.prototype.normalizeImage = mxClient.imageBasePath + '/normalize.gif'; |
| |
| /** |
| * Variable: maximizeImage |
| * |
| * URL of the image to be used for the maximize icon in the titlebar. |
| */ |
| mxWindow.prototype.maximizeImage = mxClient.imageBasePath + '/maximize.gif'; |
| |
| /** |
| * Variable: normalizeImage |
| * |
| * URL of the image to be used for the resize icon. |
| */ |
| mxWindow.prototype.resizeImage = mxClient.imageBasePath + '/resize.gif'; |
| |
| /** |
| * Variable: visible |
| * |
| * Boolean flag that represents the visible state of the window. |
| */ |
| mxWindow.prototype.visible = false; |
| |
| /** |
| * Variable: minimumSize |
| * |
| * <mxRectangle> that specifies the minimum width and height of the window. |
| * Default is (50, 40). |
| */ |
| mxWindow.prototype.minimumSize = new mxRectangle(0, 0, 50, 40); |
| |
| /** |
| * Variable: destroyOnClose |
| * |
| * Specifies if the window should be destroyed when it is closed. If this |
| * is false then the window is hidden using <setVisible>. Default is true. |
| */ |
| mxWindow.prototype.destroyOnClose = true; |
| |
| /** |
| * Variable: contentHeightCorrection |
| * |
| * Defines the correction factor for computing the height of the contentWrapper. |
| * Default is 6 for IE 7/8 standards mode and 2 for all other browsers and modes. |
| */ |
| mxWindow.prototype.contentHeightCorrection = (document.documentMode == 8 || document.documentMode == 7) ? 6 : 2; |
| |
| /** |
| * Variable: title |
| * |
| * Reference to the DOM node (TD) that contains the title. |
| */ |
| mxWindow.prototype.title = null; |
| |
| /** |
| * Variable: content |
| * |
| * Reference to the DOM node that represents the window content. |
| */ |
| mxWindow.prototype.content = null; |
| |
| /** |
| * Function: init |
| * |
| * Initializes the DOM tree that represents the window. |
| */ |
| mxWindow.prototype.init = function(x, y, width, height, style) |
| { |
| style = (style != null) ? style : 'mxWindow'; |
| |
| this.div = document.createElement('div'); |
| this.div.className = style; |
| |
| this.div.style.left = x + 'px'; |
| this.div.style.top = y + 'px'; |
| this.table = document.createElement('table'); |
| this.table.className = style; |
| |
| // Disables built-in pan and zoom in IE10 and later |
| if (mxClient.IS_POINTER) |
| { |
| this.div.style.touchAction = 'none'; |
| } |
| |
| // Workaround for table size problems in FF |
| if (width != null) |
| { |
| if (!mxClient.IS_QUIRKS) |
| { |
| this.div.style.width = width + 'px'; |
| } |
| |
| this.table.style.width = width + 'px'; |
| } |
| |
| if (height != null) |
| { |
| if (!mxClient.IS_QUIRKS) |
| { |
| this.div.style.height = height + 'px'; |
| } |
| |
| this.table.style.height = height + 'px'; |
| } |
| |
| // Creates title row |
| var tbody = document.createElement('tbody'); |
| var tr = document.createElement('tr'); |
| |
| this.title = document.createElement('td'); |
| this.title.className = style + 'Title'; |
| |
| this.buttons = document.createElement('div'); |
| this.buttons.style.position = 'absolute'; |
| this.buttons.style.display = 'inline-block'; |
| this.buttons.style.right = '4px'; |
| this.buttons.style.top = '5px'; |
| this.title.appendChild(this.buttons); |
| |
| tr.appendChild(this.title); |
| tbody.appendChild(tr); |
| |
| // Creates content row and table cell |
| tr = document.createElement('tr'); |
| this.td = document.createElement('td'); |
| this.td.className = style + 'Pane'; |
| |
| if (document.documentMode == 7) |
| { |
| this.td.style.height = '100%'; |
| } |
| |
| this.contentWrapper = document.createElement('div'); |
| this.contentWrapper.className = style + 'Pane'; |
| this.contentWrapper.style.width = '100%'; |
| this.contentWrapper.appendChild(this.content); |
| |
| // Workaround for div around div restricts height |
| // of inner div if outerdiv has hidden overflow |
| if (mxClient.IS_QUIRKS || this.content.nodeName.toUpperCase() != 'DIV') |
| { |
| this.contentWrapper.style.height = '100%'; |
| } |
| |
| // Puts all content into the DOM |
| this.td.appendChild(this.contentWrapper); |
| tr.appendChild(this.td); |
| tbody.appendChild(tr); |
| this.table.appendChild(tbody); |
| this.div.appendChild(this.table); |
| |
| // Puts the window on top of other windows when clicked |
| var activator = mxUtils.bind(this, function(evt) |
| { |
| this.activate(); |
| }); |
| |
| mxEvent.addGestureListeners(this.title, activator); |
| mxEvent.addGestureListeners(this.table, activator); |
| |
| this.hide(); |
| }; |
| |
| /** |
| * Function: setTitle |
| * |
| * Sets the window title to the given string. HTML markup inside the title |
| * will be escaped. |
| */ |
| mxWindow.prototype.setTitle = function(title) |
| { |
| // Removes all text content nodes (normally just one) |
| var child = this.title.firstChild; |
| |
| while (child != null) |
| { |
| var next = child.nextSibling; |
| |
| if (child.nodeType == mxConstants.NODETYPE_TEXT) |
| { |
| child.parentNode.removeChild(child); |
| } |
| |
| child = next; |
| } |
| |
| mxUtils.write(this.title, title || ''); |
| this.title.appendChild(this.buttons); |
| }; |
| |
| /** |
| * Function: setScrollable |
| * |
| * Sets if the window contents should be scrollable. |
| */ |
| mxWindow.prototype.setScrollable = function(scrollable) |
| { |
| // Workaround for hang in Presto 2.5.22 (Opera 10.5) |
| if (navigator.userAgent.indexOf('Presto/2.5') < 0) |
| { |
| if (scrollable) |
| { |
| this.contentWrapper.style.overflow = 'auto'; |
| } |
| else |
| { |
| this.contentWrapper.style.overflow = 'hidden'; |
| } |
| } |
| }; |
| |
| /** |
| * Function: activate |
| * |
| * Puts the window on top of all other windows. |
| */ |
| mxWindow.prototype.activate = function() |
| { |
| if (mxWindow.activeWindow != this) |
| { |
| var style = mxUtils.getCurrentStyle(this.getElement()); |
| var index = (style != null) ? style.zIndex : 3; |
| |
| if (mxWindow.activeWindow) |
| { |
| var elt = mxWindow.activeWindow.getElement(); |
| |
| if (elt != null && elt.style != null) |
| { |
| elt.style.zIndex = index; |
| } |
| } |
| |
| var previousWindow = mxWindow.activeWindow; |
| this.getElement().style.zIndex = parseInt(index) + 1; |
| mxWindow.activeWindow = this; |
| |
| this.fireEvent(new mxEventObject(mxEvent.ACTIVATE, 'previousWindow', previousWindow)); |
| } |
| }; |
| |
| /** |
| * Function: getElement |
| * |
| * Returuns the outermost DOM node that makes up the window. |
| */ |
| mxWindow.prototype.getElement = function() |
| { |
| return this.div; |
| }; |
| |
| /** |
| * Function: fit |
| * |
| * Makes sure the window is inside the client area of the window. |
| */ |
| mxWindow.prototype.fit = function() |
| { |
| mxUtils.fit(this.div); |
| }; |
| |
| /** |
| * Function: isResizable |
| * |
| * Returns true if the window is resizable. |
| */ |
| mxWindow.prototype.isResizable = function() |
| { |
| if (this.resize != null) |
| { |
| return this.resize.style.display != 'none'; |
| } |
| |
| return false; |
| }; |
| |
| /** |
| * Function: setResizable |
| * |
| * Sets if the window should be resizable. To avoid interference with some |
| * built-in features of IE10 and later, the use of the following code is |
| * recommended if there are resizable <mxWindow>s in the page: |
| * |
| * (code) |
| * if (mxClient.IS_POINTER) |
| * { |
| * document.body.style.msTouchAction = 'none'; |
| * } |
| * (end) |
| */ |
| mxWindow.prototype.setResizable = function(resizable) |
| { |
| if (resizable) |
| { |
| if (this.resize == null) |
| { |
| this.resize = document.createElement('img'); |
| this.resize.style.position = 'absolute'; |
| this.resize.style.bottom = '2px'; |
| this.resize.style.right = '2px'; |
| |
| this.resize.setAttribute('src', mxClient.imageBasePath + '/resize.gif'); |
| this.resize.style.cursor = 'nw-resize'; |
| |
| var startX = null; |
| var startY = null; |
| var width = null; |
| var height = null; |
| |
| var start = mxUtils.bind(this, function(evt) |
| { |
| // LATER: pointerdown starting on border of resize does start |
| // the drag operation but does not fire consecutive events via |
| // one of the listeners below (does pan instead). |
| // Workaround: document.body.style.msTouchAction = 'none' |
| this.activate(); |
| startX = mxEvent.getClientX(evt); |
| startY = mxEvent.getClientY(evt); |
| width = this.div.offsetWidth; |
| height = this.div.offsetHeight; |
| |
| mxEvent.addGestureListeners(document, null, dragHandler, dropHandler); |
| this.fireEvent(new mxEventObject(mxEvent.RESIZE_START, 'event', evt)); |
| mxEvent.consume(evt); |
| }); |
| |
| // Adds a temporary pair of listeners to intercept |
| // the gesture event in the document |
| var dragHandler = mxUtils.bind(this, function(evt) |
| { |
| if (startX != null && startY != null) |
| { |
| var dx = mxEvent.getClientX(evt) - startX; |
| var dy = mxEvent.getClientY(evt) - startY; |
| |
| this.setSize(width + dx, height + dy); |
| |
| this.fireEvent(new mxEventObject(mxEvent.RESIZE, 'event', evt)); |
| mxEvent.consume(evt); |
| } |
| }); |
| |
| var dropHandler = mxUtils.bind(this, function(evt) |
| { |
| if (startX != null && startY != null) |
| { |
| startX = null; |
| startY = null; |
| mxEvent.removeGestureListeners(document, null, dragHandler, dropHandler); |
| this.fireEvent(new mxEventObject(mxEvent.RESIZE_END, 'event', evt)); |
| mxEvent.consume(evt); |
| } |
| }); |
| |
| mxEvent.addGestureListeners(this.resize, start, dragHandler, dropHandler); |
| this.div.appendChild(this.resize); |
| } |
| else |
| { |
| this.resize.style.display = 'inline'; |
| } |
| } |
| else if (this.resize != null) |
| { |
| this.resize.style.display = 'none'; |
| } |
| }; |
| |
| /** |
| * Function: setSize |
| * |
| * Sets the size of the window. |
| */ |
| mxWindow.prototype.setSize = function(width, height) |
| { |
| width = Math.max(this.minimumSize.width, width); |
| height = Math.max(this.minimumSize.height, height); |
| |
| // Workaround for table size problems in FF |
| if (!mxClient.IS_QUIRKS) |
| { |
| this.div.style.width = width + 'px'; |
| this.div.style.height = height + 'px'; |
| } |
| |
| this.table.style.width = width + 'px'; |
| this.table.style.height = height + 'px'; |
| |
| if (!mxClient.IS_QUIRKS) |
| { |
| this.contentWrapper.style.height = (this.div.offsetHeight - |
| this.title.offsetHeight - this.contentHeightCorrection) + 'px'; |
| } |
| }; |
| |
| /** |
| * Function: setMinimizable |
| * |
| * Sets if the window is minimizable. |
| */ |
| mxWindow.prototype.setMinimizable = function(minimizable) |
| { |
| this.minimize.style.display = (minimizable) ? '' : 'none'; |
| }; |
| |
| /** |
| * Function: getMinimumSize |
| * |
| * Returns an <mxRectangle> that specifies the size for the minimized window. |
| * A width or height of 0 means keep the existing width or height. This |
| * implementation returns the height of the window title and keeps the width. |
| */ |
| mxWindow.prototype.getMinimumSize = function() |
| { |
| return new mxRectangle(0, 0, 0, this.title.offsetHeight); |
| }; |
| |
| /** |
| * Function: installMinimizeHandler |
| * |
| * Installs the event listeners required for minimizing the window. |
| */ |
| mxWindow.prototype.installMinimizeHandler = function() |
| { |
| this.minimize = document.createElement('img'); |
| |
| this.minimize.setAttribute('src', this.minimizeImage); |
| this.minimize.setAttribute('title', 'Minimize'); |
| this.minimize.style.cursor = 'pointer'; |
| this.minimize.style.marginLeft = '2px'; |
| this.minimize.style.display = 'none'; |
| |
| this.buttons.appendChild(this.minimize); |
| |
| var minimized = false; |
| var maxDisplay = null; |
| var height = null; |
| |
| var funct = mxUtils.bind(this, function(evt) |
| { |
| this.activate(); |
| |
| if (!minimized) |
| { |
| minimized = true; |
| |
| this.minimize.setAttribute('src', this.normalizeImage); |
| this.minimize.setAttribute('title', 'Normalize'); |
| this.contentWrapper.style.display = 'none'; |
| maxDisplay = this.maximize.style.display; |
| |
| this.maximize.style.display = 'none'; |
| height = this.table.style.height; |
| |
| var minSize = this.getMinimumSize(); |
| |
| if (minSize.height > 0) |
| { |
| if (!mxClient.IS_QUIRKS) |
| { |
| this.div.style.height = minSize.height + 'px'; |
| } |
| |
| this.table.style.height = minSize.height + 'px'; |
| } |
| |
| if (minSize.width > 0) |
| { |
| if (!mxClient.IS_QUIRKS) |
| { |
| this.div.style.width = minSize.width + 'px'; |
| } |
| |
| this.table.style.width = minSize.width + 'px'; |
| } |
| |
| if (this.resize != null) |
| { |
| this.resize.style.visibility = 'hidden'; |
| } |
| |
| this.fireEvent(new mxEventObject(mxEvent.MINIMIZE, 'event', evt)); |
| } |
| else |
| { |
| minimized = false; |
| |
| this.minimize.setAttribute('src', this.minimizeImage); |
| this.minimize.setAttribute('title', 'Minimize'); |
| this.contentWrapper.style.display = ''; // default |
| this.maximize.style.display = maxDisplay; |
| |
| if (!mxClient.IS_QUIRKS) |
| { |
| this.div.style.height = height; |
| } |
| |
| this.table.style.height = height; |
| |
| if (this.resize != null) |
| { |
| this.resize.style.visibility = ''; |
| } |
| |
| this.fireEvent(new mxEventObject(mxEvent.NORMALIZE, 'event', evt)); |
| } |
| |
| mxEvent.consume(evt); |
| }); |
| |
| mxEvent.addGestureListeners(this.minimize, funct); |
| }; |
| |
| /** |
| * Function: setMaximizable |
| * |
| * Sets if the window is maximizable. |
| */ |
| mxWindow.prototype.setMaximizable = function(maximizable) |
| { |
| this.maximize.style.display = (maximizable) ? '' : 'none'; |
| }; |
| |
| /** |
| * Function: installMaximizeHandler |
| * |
| * Installs the event listeners required for maximizing the window. |
| */ |
| mxWindow.prototype.installMaximizeHandler = function() |
| { |
| this.maximize = document.createElement('img'); |
| |
| this.maximize.setAttribute('src', this.maximizeImage); |
| this.maximize.setAttribute('title', 'Maximize'); |
| this.maximize.style.cursor = 'default'; |
| this.maximize.style.marginLeft = '2px'; |
| this.maximize.style.cursor = 'pointer'; |
| this.maximize.style.display = 'none'; |
| |
| this.buttons.appendChild(this.maximize); |
| |
| var maximized = false; |
| var x = null; |
| var y = null; |
| var height = null; |
| var width = null; |
| var minDisplay = null; |
| |
| var funct = mxUtils.bind(this, function(evt) |
| { |
| this.activate(); |
| |
| if (this.maximize.style.display != 'none') |
| { |
| if (!maximized) |
| { |
| maximized = true; |
| |
| this.maximize.setAttribute('src', this.normalizeImage); |
| this.maximize.setAttribute('title', 'Normalize'); |
| this.contentWrapper.style.display = ''; |
| minDisplay = this.minimize.style.display; |
| this.minimize.style.display = 'none'; |
| |
| // Saves window state |
| x = parseInt(this.div.style.left); |
| y = parseInt(this.div.style.top); |
| height = this.table.style.height; |
| width = this.table.style.width; |
| |
| this.div.style.left = '0px'; |
| this.div.style.top = '0px'; |
| var docHeight = Math.max(document.body.clientHeight || 0, document.documentElement.clientHeight || 0); |
| |
| if (!mxClient.IS_QUIRKS) |
| { |
| this.div.style.width = (document.body.clientWidth - 2) + 'px'; |
| this.div.style.height = (docHeight - 2) + 'px'; |
| } |
| |
| this.table.style.width = (document.body.clientWidth - 2) + 'px'; |
| this.table.style.height = (docHeight - 2) + 'px'; |
| |
| if (this.resize != null) |
| { |
| this.resize.style.visibility = 'hidden'; |
| } |
| |
| if (!mxClient.IS_QUIRKS) |
| { |
| var style = mxUtils.getCurrentStyle(this.contentWrapper); |
| |
| if (style.overflow == 'auto' || this.resize != null) |
| { |
| this.contentWrapper.style.height = (this.div.offsetHeight - |
| this.title.offsetHeight - this.contentHeightCorrection) + 'px'; |
| } |
| } |
| |
| this.fireEvent(new mxEventObject(mxEvent.MAXIMIZE, 'event', evt)); |
| } |
| else |
| { |
| maximized = false; |
| |
| this.maximize.setAttribute('src', this.maximizeImage); |
| this.maximize.setAttribute('title', 'Maximize'); |
| this.contentWrapper.style.display = ''; |
| this.minimize.style.display = minDisplay; |
| |
| // Restores window state |
| this.div.style.left = x+'px'; |
| this.div.style.top = y+'px'; |
| |
| if (!mxClient.IS_QUIRKS) |
| { |
| this.div.style.height = height; |
| this.div.style.width = width; |
| |
| var style = mxUtils.getCurrentStyle(this.contentWrapper); |
| |
| if (style.overflow == 'auto' || this.resize != null) |
| { |
| this.contentWrapper.style.height = (this.div.offsetHeight - |
| this.title.offsetHeight - this.contentHeightCorrection) + 'px'; |
| } |
| } |
| |
| this.table.style.height = height; |
| this.table.style.width = width; |
| |
| if (this.resize != null) |
| { |
| this.resize.style.visibility = ''; |
| } |
| |
| this.fireEvent(new mxEventObject(mxEvent.NORMALIZE, 'event', evt)); |
| } |
| |
| mxEvent.consume(evt); |
| } |
| }); |
| |
| mxEvent.addGestureListeners(this.maximize, funct); |
| mxEvent.addListener(this.title, 'dblclick', funct); |
| }; |
| |
| /** |
| * Function: installMoveHandler |
| * |
| * Installs the event listeners required for moving the window. |
| */ |
| mxWindow.prototype.installMoveHandler = function() |
| { |
| this.title.style.cursor = 'move'; |
| |
| mxEvent.addGestureListeners(this.title, |
| mxUtils.bind(this, function(evt) |
| { |
| var startX = mxEvent.getClientX(evt); |
| var startY = mxEvent.getClientY(evt); |
| var x = this.getX(); |
| var y = this.getY(); |
| |
| // Adds a temporary pair of listeners to intercept |
| // the gesture event in the document |
| var dragHandler = mxUtils.bind(this, function(evt) |
| { |
| var dx = mxEvent.getClientX(evt) - startX; |
| var dy = mxEvent.getClientY(evt) - startY; |
| this.setLocation(x + dx, y + dy); |
| this.fireEvent(new mxEventObject(mxEvent.MOVE, 'event', evt)); |
| mxEvent.consume(evt); |
| }); |
| |
| var dropHandler = mxUtils.bind(this, function(evt) |
| { |
| mxEvent.removeGestureListeners(document, null, dragHandler, dropHandler); |
| this.fireEvent(new mxEventObject(mxEvent.MOVE_END, 'event', evt)); |
| mxEvent.consume(evt); |
| }); |
| |
| mxEvent.addGestureListeners(document, null, dragHandler, dropHandler); |
| this.fireEvent(new mxEventObject(mxEvent.MOVE_START, 'event', evt)); |
| mxEvent.consume(evt); |
| })); |
| |
| // Disables built-in pan and zoom in IE10 and later |
| if (mxClient.IS_POINTER) |
| { |
| this.title.style.touchAction = 'none'; |
| } |
| }; |
| |
| /** |
| * Function: setLocation |
| * |
| * Sets the upper, left corner of the window. |
| */ |
| mxWindow.prototype.setLocation = function(x, y) |
| { |
| this.div.style.left = x + 'px'; |
| this.div.style.top = y + 'px'; |
| }; |
| |
| /** |
| * Function: getX |
| * |
| * Returns the current position on the x-axis. |
| */ |
| mxWindow.prototype.getX = function() |
| { |
| return parseInt(this.div.style.left); |
| }; |
| |
| /** |
| * Function: getY |
| * |
| * Returns the current position on the y-axis. |
| */ |
| mxWindow.prototype.getY = function() |
| { |
| return parseInt(this.div.style.top); |
| }; |
| |
| /** |
| * Function: installCloseHandler |
| * |
| * Adds the <closeImage> as a new image node in <closeImg> and installs the |
| * <close> event. |
| */ |
| mxWindow.prototype.installCloseHandler = function() |
| { |
| this.closeImg = document.createElement('img'); |
| |
| this.closeImg.setAttribute('src', this.closeImage); |
| this.closeImg.setAttribute('title', 'Close'); |
| this.closeImg.style.marginLeft = '2px'; |
| this.closeImg.style.cursor = 'pointer'; |
| this.closeImg.style.display = 'none'; |
| |
| this.buttons.appendChild(this.closeImg); |
| |
| mxEvent.addGestureListeners(this.closeImg, |
| mxUtils.bind(this, function(evt) |
| { |
| this.fireEvent(new mxEventObject(mxEvent.CLOSE, 'event', evt)); |
| |
| if (this.destroyOnClose) |
| { |
| this.destroy(); |
| } |
| else |
| { |
| this.setVisible(false); |
| } |
| |
| mxEvent.consume(evt); |
| })); |
| }; |
| |
| /** |
| * Function: setImage |
| * |
| * Sets the image associated with the window. |
| * |
| * Parameters: |
| * |
| * image - URL of the image to be used. |
| */ |
| mxWindow.prototype.setImage = function(image) |
| { |
| this.image = document.createElement('img'); |
| this.image.setAttribute('src', image); |
| this.image.setAttribute('align', 'left'); |
| this.image.style.marginRight = '4px'; |
| this.image.style.marginLeft = '0px'; |
| this.image.style.marginTop = '-2px'; |
| |
| this.title.insertBefore(this.image, this.title.firstChild); |
| }; |
| |
| /** |
| * Function: setClosable |
| * |
| * Sets the image associated with the window. |
| * |
| * Parameters: |
| * |
| * closable - Boolean specifying if the window should be closable. |
| */ |
| mxWindow.prototype.setClosable = function(closable) |
| { |
| this.closeImg.style.display = (closable) ? '' : 'none'; |
| }; |
| |
| /** |
| * Function: isVisible |
| * |
| * Returns true if the window is visible. |
| */ |
| mxWindow.prototype.isVisible = function() |
| { |
| if (this.div != null) |
| { |
| return this.div.style.display != 'none'; |
| } |
| |
| return false; |
| }; |
| |
| /** |
| * Function: setVisible |
| * |
| * Shows or hides the window depending on the given flag. |
| * |
| * Parameters: |
| * |
| * visible - Boolean indicating if the window should be made visible. |
| */ |
| mxWindow.prototype.setVisible = function(visible) |
| { |
| if (this.div != null && this.isVisible() != visible) |
| { |
| if (visible) |
| { |
| this.show(); |
| } |
| else |
| { |
| this.hide(); |
| } |
| } |
| }; |
| |
| /** |
| * Function: show |
| * |
| * Shows the window. |
| */ |
| mxWindow.prototype.show = function() |
| { |
| this.div.style.display = ''; |
| this.activate(); |
| |
| var style = mxUtils.getCurrentStyle(this.contentWrapper); |
| |
| if (!mxClient.IS_QUIRKS && (style.overflow == 'auto' || this.resize != null)) |
| { |
| this.contentWrapper.style.height = (this.div.offsetHeight - |
| this.title.offsetHeight - this.contentHeightCorrection) + 'px'; |
| } |
| |
| this.fireEvent(new mxEventObject(mxEvent.SHOW)); |
| }; |
| |
| /** |
| * Function: hide |
| * |
| * Hides the window. |
| */ |
| mxWindow.prototype.hide = function() |
| { |
| this.div.style.display = 'none'; |
| this.fireEvent(new mxEventObject(mxEvent.HIDE)); |
| }; |
| |
| /** |
| * Function: destroy |
| * |
| * Destroys the window and removes all associated resources. Fires a |
| * <destroy> event prior to destroying the window. |
| */ |
| mxWindow.prototype.destroy = function() |
| { |
| this.fireEvent(new mxEventObject(mxEvent.DESTROY)); |
| |
| if (this.div != null) |
| { |
| mxEvent.release(this.div); |
| this.div.parentNode.removeChild(this.div); |
| this.div = null; |
| } |
| |
| this.title = null; |
| this.content = null; |
| this.contentWrapper = null; |
| }; |