| OLD | NEW | 
|    1 // Copyright 2017 The Chromium Authors. All rights reserved. |    1 // Copyright 2017 The Chromium Authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 UI.GlassPane = class { |    5 UI.GlassPane = class { | 
|    6   constructor() { |    6   constructor() { | 
|    7     this._widget = new UI.Widget(true); |    7     this._widget = new UI.Widget(true); | 
|    8     this._widget.markAsRoot(); |    8     this._widget.markAsRoot(); | 
|    9     this.element = this._widget.element; |    9     this.element = this._widget.element; | 
|   10     this.contentElement = this._widget.contentElement; |   10     this.contentElement = this._widget.contentElement; | 
|   11     this._arrowElement = UI.Icon.create('', 'arrow hidden'); |   11     this._arrowElement = UI.Icon.create('', 'arrow hidden'); | 
|   12     this.element.shadowRoot.appendChild(this._arrowElement); |   12     this.element.shadowRoot.appendChild(this._arrowElement); | 
|   13  |   13  | 
|   14     this.registerRequiredCSS('ui/glassPane.css'); |   14     this.registerRequiredCSS('ui/glassPane.css'); | 
|   15     this.element.classList.add('no-pointer-events'); |   15     this.element.classList.add('no-pointer-events'); | 
|   16     this._onMouseDownBound = this._onMouseDown.bind(this); |   16     this._onMouseDownBound = this._onMouseDown.bind(this); | 
|   17     /** @type {?function(!Event)} */ |   17     /** @type {?function(!Event)} */ | 
|   18     this._onClickOutsideCallback = null; |   18     this._onClickOutsideCallback = null; | 
|   19     /** @type {?UI.Size} */ |   19     /** @type {?UI.Size} */ | 
|   20     this._maxSize = null; |   20     this._maxSize = null; | 
|   21     /** @type {?number} */ |   21     /** @type {?number} */ | 
|   22     this._positionX = null; |   22     this._positionX = null; | 
|   23     /** @type {?number} */ |   23     /** @type {?number} */ | 
|   24     this._positionY = null; |   24     this._positionY = null; | 
|   25     /** @type {?AnchorBox} */ |   25     /** @type {?AnchorBox} */ | 
|   26     this._anchorBox = null; |   26     this._anchorBox = null; | 
|   27     this._anchorBehavior = UI.GlassPane.AnchorBehavior.PreferTop; |   27     this._anchorBehavior = UI.GlassPane.AnchorBehavior.PreferTop; | 
|   28     this._sizeBehavior = UI.GlassPane.SizeBehavior.SetExactSize; |   28     this._sizeBehavior = UI.GlassPane.SizeBehavior.SetExactSize; | 
|   29     this._showArrow = false; |   29     this._marginBehavior = UI.GlassPane.MarginBehavior.DefaultMargin; | 
|   30   } |   30   } | 
|   31  |   31  | 
|   32   /** |   32   /** | 
|   33    * @return {boolean} |   33    * @return {boolean} | 
|   34    */ |   34    */ | 
|   35   isShowing() { |   35   isShowing() { | 
|   36     return this._widget.isShowing(); |   36     return this._widget.isShowing(); | 
|   37   } |   37   } | 
|   38  |   38  | 
|   39   /** |   39   /** | 
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  101   } |  101   } | 
|  102  |  102  | 
|  103   /** |  103   /** | 
|  104    * @param {!UI.GlassPane.AnchorBehavior} behavior |  104    * @param {!UI.GlassPane.AnchorBehavior} behavior | 
|  105    */ |  105    */ | 
|  106   setAnchorBehavior(behavior) { |  106   setAnchorBehavior(behavior) { | 
|  107     this._anchorBehavior = behavior; |  107     this._anchorBehavior = behavior; | 
|  108   } |  108   } | 
|  109  |  109  | 
|  110   /** |  110   /** | 
|  111    * @param {boolean} showArrow |  111    * @param {boolean} behavior | 
|  112    */ |  112    */ | 
|  113   setShowArrow(showArrow) { |  113   setMarginBehavior(behavior) { | 
|  114     this._showArrow = showArrow; |  114     this._marginBehavior = behavior; | 
|  115     this._arrowElement.classList.toggle('hidden', !showArrow); |  115     this._arrowElement.classList.toggle('hidden', behavior !== UI.GlassPane.Marg
     inBehavior.Arrow); | 
|  116   } |  116   } | 
|  117  |  117  | 
|  118   /** |  118   /** | 
|  119    * @param {!Document} document |  119    * @param {!Document} document | 
|  120    */ |  120    */ | 
|  121   show(document) { |  121   show(document) { | 
|  122     if (this.isShowing()) |  122     if (this.isShowing()) | 
|  123       return; |  123       return; | 
|  124     // Deliberately starts with 3000 to hide other z-indexed elements below. |  124     // Deliberately starts with 3000 to hide other z-indexed elements below. | 
|  125     this.element.style.zIndex = 3000 + 1000 * UI.GlassPane._panes.size; |  125     this.element.style.zIndex = 3000 + 1000 * UI.GlassPane._panes.size; | 
|  126     document.body.addEventListener('mousedown', this._onMouseDownBound, true); |  126     document.body.addEventListener('click', this._onMouseDownBound, true); | 
|  127     this._widget.show(document.body); |  127     this._widget.show(document.body); | 
|  128     UI.GlassPane._panes.add(this); |  128     UI.GlassPane._panes.add(this); | 
|  129     this._positionContent(); |  129     this._positionContent(); | 
|  130   } |  130   } | 
|  131  |  131  | 
|  132   hide() { |  132   hide() { | 
|  133     if (!this.isShowing()) |  133     if (!this.isShowing()) | 
|  134       return; |  134       return; | 
|  135     UI.GlassPane._panes.delete(this); |  135     UI.GlassPane._panes.delete(this); | 
|  136     this.element.ownerDocument.body.removeEventListener('mousedown', this._onMou
     seDownBound, true); |  136     this.element.ownerDocument.body.removeEventListener('click', this._onMouseDo
     wnBound, true); | 
|  137     this._widget.detach(); |  137     this._widget.detach(); | 
|  138   } |  138   } | 
|  139  |  139  | 
|  140   /** |  140   /** | 
|  141    * @param {!Event} event |  141    * @param {!Event} event | 
|  142    */ |  142    */ | 
|  143   _onMouseDown(event) { |  143   _onMouseDown(event) { | 
|  144     if (!this._onClickOutsideCallback) |  144     if (!this._onClickOutsideCallback) | 
|  145       return; |  145       return; | 
|  146     if (this.contentElement.isSelfOrAncestor(/** @type {?Node} */ (event.deepEle
     mentFromPoint()))) |  146     if (this.contentElement.isSelfOrAncestor(/** @type {?Node} */ (event.deepEle
     mentFromPoint()))) | 
|  147       return; |  147       return; | 
|  148     this._onClickOutsideCallback.call(null, event); |  148     this._onClickOutsideCallback.call(null, event); | 
|  149   } |  149   } | 
|  150  |  150  | 
|  151   _positionContent() { |  151   _positionContent() { | 
|  152     if (!this.isShowing()) |  152     if (!this.isShowing()) | 
|  153       return; |  153       return; | 
|  154  |  154  | 
|  155     var gutterSize = this._showArrow ? 8 : 3; |  155     var showArrow = this._marginBehavior === UI.GlassPane.MarginBehavior.Arrow; | 
 |  156     var gutterSize = showArrow ? 8 : (this._marginBehavior === UI.GlassPane.Marg
     inBehavior.NoMargin ? 0 : 3); | 
|  156     var scrollbarSize = 14; |  157     var scrollbarSize = 14; | 
|  157     var arrowSize = 10; |  158     var arrowSize = 10; | 
|  158  |  159  | 
|  159     var container = UI.GlassPane._containers.get(/** @type {!Document} */ (this.
     element.ownerDocument)); |  160     var container = UI.GlassPane._containers.get(/** @type {!Document} */ (this.
     element.ownerDocument)); | 
|  160     if (this._sizeBehavior === UI.GlassPane.SizeBehavior.MeasureContent) { |  161     if (this._sizeBehavior === UI.GlassPane.SizeBehavior.MeasureContent) { | 
|  161       this.contentElement.positionAt(0, 0); |  162       this.contentElement.positionAt(0, 0); | 
|  162       this.contentElement.style.width = ''; |  163       this.contentElement.style.width = ''; | 
|  163       this.contentElement.style.maxWidth = ''; |  164       this.contentElement.style.maxWidth = ''; | 
|  164       this.contentElement.style.height = ''; |  165       this.contentElement.style.height = ''; | 
|  165       this.contentElement.style.maxHeight = ''; |  166       this.contentElement.style.maxHeight = ''; | 
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  233             height = Math.min(height, spaceBottom); |  234             height = Math.min(height, spaceBottom); | 
|  234           } |  235           } | 
|  235           this._arrowElement.setIconType('mediumicon-arrow-top'); |  236           this._arrowElement.setIconType('mediumicon-arrow-top'); | 
|  236           this._arrowElement.classList.add('arrow-top'); |  237           this._arrowElement.classList.add('arrow-top'); | 
|  237           arrowY = anchorBox.y + anchorBox.height + gutterSize; |  238           arrowY = anchorBox.y + anchorBox.height + gutterSize; | 
|  238         } |  239         } | 
|  239  |  240  | 
|  240         positionX = Math.max(gutterSize, Math.min(anchorBox.x, containerWidth - 
     width - gutterSize)); |  241         positionX = Math.max(gutterSize, Math.min(anchorBox.x, containerWidth - 
     width - gutterSize)); | 
|  241         if (!enoughHeight) |  242         if (!enoughHeight) | 
|  242           positionX += arrowSize; |  243           positionX += arrowSize; | 
|  243         else if (this._showArrow && positionX - arrowSize >= gutterSize) |  244         else if (showArrow && positionX - arrowSize >= gutterSize) | 
|  244           positionX -= arrowSize; |  245           positionX -= arrowSize; | 
|  245         width = Math.min(width, containerWidth - positionX - gutterSize); |  246         width = Math.min(width, containerWidth - positionX - gutterSize); | 
|  246         if (2 * arrowSize >= width) { |  247         if (2 * arrowSize >= width) { | 
|  247           this._arrowElement.classList.add('arrow-none'); |  248           this._arrowElement.classList.add('arrow-none'); | 
|  248         } else { |  249         } else { | 
|  249           var arrowX = anchorBox.x + Math.min(50, Math.floor(anchorBox.width / 2
     )); |  250           var arrowX = anchorBox.x + Math.min(50, Math.floor(anchorBox.width / 2
     )); | 
|  250           arrowX = Number.constrain(arrowX, positionX + arrowSize, positionX + w
     idth - arrowSize); |  251           arrowX = Number.constrain(arrowX, positionX + arrowSize, positionX + w
     idth - arrowSize); | 
|  251           this._arrowElement.positionAt(arrowX, arrowY, container); |  252           this._arrowElement.positionAt(arrowX, arrowY, container); | 
|  252         } |  253         } | 
|  253       } else { |  254       } else { | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  291             width = Math.min(width, spaceRight); |  292             width = Math.min(width, spaceRight); | 
|  292           } |  293           } | 
|  293           this._arrowElement.setIconType('mediumicon-arrow-left'); |  294           this._arrowElement.setIconType('mediumicon-arrow-left'); | 
|  294           this._arrowElement.classList.add('arrow-left'); |  295           this._arrowElement.classList.add('arrow-left'); | 
|  295           arrowX = anchorBox.x + anchorBox.width + gutterSize; |  296           arrowX = anchorBox.x + anchorBox.width + gutterSize; | 
|  296         } |  297         } | 
|  297  |  298  | 
|  298         positionY = Math.max(gutterSize, Math.min(anchorBox.y, containerHeight -
      height - gutterSize)); |  299         positionY = Math.max(gutterSize, Math.min(anchorBox.y, containerHeight -
      height - gutterSize)); | 
|  299         if (!enoughWidth) |  300         if (!enoughWidth) | 
|  300           positionY += arrowSize; |  301           positionY += arrowSize; | 
|  301         else if (this._showArrow && positionY - arrowSize >= gutterSize) |  302         else if (showArrow && positionY - arrowSize >= gutterSize) | 
|  302           positionY -= arrowSize; |  303           positionY -= arrowSize; | 
|  303         height = Math.min(height, containerHeight - positionY - gutterSize); |  304         height = Math.min(height, containerHeight - positionY - gutterSize); | 
|  304         if (2 * arrowSize >= height) { |  305         if (2 * arrowSize >= height) { | 
|  305           this._arrowElement.classList.add('arrow-none'); |  306           this._arrowElement.classList.add('arrow-none'); | 
|  306         } else { |  307         } else { | 
|  307           var arrowY = anchorBox.y + Math.min(50, Math.floor(anchorBox.height / 
     2)); |  308           var arrowY = anchorBox.y + Math.min(50, Math.floor(anchorBox.height / 
     2)); | 
|  308           arrowY = Number.constrain(arrowY, positionY + arrowSize, positionY + h
     eight - arrowSize); |  309           arrowY = Number.constrain(arrowY, positionY + arrowSize, positionY + h
     eight - arrowSize); | 
|  309           this._arrowElement.positionAt(arrowX, arrowY, container); |  310           this._arrowElement.positionAt(arrowX, arrowY, container); | 
|  310         } |  311         } | 
|  311       } |  312       } | 
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  374  |  375  | 
|  375 /** |  376 /** | 
|  376  * @enum {symbol} |  377  * @enum {symbol} | 
|  377  */ |  378  */ | 
|  378 UI.GlassPane.SizeBehavior = { |  379 UI.GlassPane.SizeBehavior = { | 
|  379   SetExactSize: Symbol('SetExactSize'), |  380   SetExactSize: Symbol('SetExactSize'), | 
|  380   SetExactWidthMaxHeight: Symbol('SetExactWidthMaxHeight'), |  381   SetExactWidthMaxHeight: Symbol('SetExactWidthMaxHeight'), | 
|  381   MeasureContent: Symbol('MeasureContent') |  382   MeasureContent: Symbol('MeasureContent') | 
|  382 }; |  383 }; | 
|  383  |  384  | 
 |  385 /** | 
 |  386  * @enum {symbol} | 
 |  387  */ | 
 |  388 UI.GlassPane.MarginBehavior = { | 
 |  389   Arrow: Symbol('Arrow'), | 
 |  390   DefaultMargin: Symbol('DefaultMargin'), | 
 |  391   NoMargin: Symbol('NoMargin') | 
 |  392 }; | 
 |  393  | 
|  384 /** @type {!Map<!Document, !Element>} */ |  394 /** @type {!Map<!Document, !Element>} */ | 
|  385 UI.GlassPane._containers = new Map(); |  395 UI.GlassPane._containers = new Map(); | 
|  386 /** @type {!Set<!UI.GlassPane>} */ |  396 /** @type {!Set<!UI.GlassPane>} */ | 
|  387 UI.GlassPane._panes = new Set(); |  397 UI.GlassPane._panes = new Set(); | 
| OLD | NEW |