Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2015 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 /** | 5 /** |
| 6 * @constructor | 6 * @constructor |
| 7 * @param {!Document} doc | 7 * @param {!Document} doc |
| 8 */ | 8 */ |
| 9 WebInspector.Tooltip = function(doc) | 9 WebInspector.Tooltip = function(doc) |
| 10 { | 10 { |
| 11 this.element = doc.body.createChild("div"); | 11 this.element = doc.body.createChild("div"); |
| 12 this._shadowRoot = WebInspector.createShadowRootWithCoreStyles(this.element) ; | 12 this._shadowRoot = WebInspector.createShadowRootWithCoreStyles(this.element) ; |
| 13 this._shadowRoot.appendChild(WebInspector.Widget.createStyleElement("ui/tool tip.css")); | 13 this._shadowRoot.appendChild(WebInspector.Widget.createStyleElement("ui/tool tip.css")); |
| 14 | 14 |
| 15 this._tooltipElement = this._shadowRoot.createChild("div", "tooltip"); | 15 this._tooltipElement = this._shadowRoot.createChild("div", "tooltip"); |
| 16 this._arrowElement = this._shadowRoot.createChild("div", "tooltip-arrow"); | |
| 17 doc.addEventListener("mousemove", this._mouseMove.bind(this), false); | 16 doc.addEventListener("mousemove", this._mouseMove.bind(this), false); |
| 17 doc.addEventListener("mousedown", this._mouseDown.bind(this), false); | |
| 18 doc.addEventListener("mouseup", this._mouseUp.bind(this), false); | |
| 18 } | 19 } |
| 19 | 20 |
| 20 WebInspector.Tooltip.Timing = { | 21 WebInspector.Tooltip.Timing = { |
| 21 // Max time between tooltips showing that no opening delay is required. | 22 // Max time between tooltips showing that no opening delay is required. |
| 22 "InstantThreshold": 300, | 23 "InstantThreshold": 300, |
| 23 // Wait time before opening a tooltip. | 24 // Wait time before opening a tooltip. |
| 24 "OpeningDelay": 400 | 25 "OpeningDelay": 600 |
| 25 } | 26 } |
| 26 | 27 |
| 27 WebInspector.Tooltip.AlignmentOverride = { | 28 WebInspector.Tooltip.AlignmentOverride = { |
| 28 Right: "Right" | 29 Right: "Right" |
| 29 } | 30 } |
| 30 | 31 |
| 31 WebInspector.Tooltip.prototype = { | 32 WebInspector.Tooltip.prototype = { |
| 32 /** | 33 /** |
| 33 * @param {!Event} event | 34 * @param {!Event} event |
| 34 */ | 35 */ |
| 35 _mouseMove: function(event) | 36 _mouseMove: function(event) |
| 36 { | 37 { |
| 37 var path = event.deepPath ? event.deepPath : event.path; | 38 var path = event.deepPath ? event.deepPath : event.path; |
| 38 if (!path) | 39 if (!path || this._mouseIsDown) |
|
dgozman
2015/08/11 00:18:00
Just check |event.buttons !== 0| and remove the fl
samli
2015/08/11 01:50:47
Done.
| |
| 39 return; | 40 return; |
| 40 | 41 |
| 41 if (this._anchorElement && path.indexOf(this._anchorElement) === -1) | 42 if (this._anchorElement && path.indexOf(this._anchorElement) === -1) |
| 42 this._hide(); | 43 this._hide(); |
| 43 | 44 |
| 44 for (var element of path) { | 45 for (var element of path) { |
| 45 if (element === this._anchorElement) { | 46 if (element === this._anchorElement || element === this._lastAnchor) { |
| 46 return; | 47 return; |
| 47 } else if (element[WebInspector.Tooltip._symbol]) { | 48 } else if (element[WebInspector.Tooltip._symbol]) { |
| 48 this._show(element); | 49 this._show(element); |
| 49 return; | 50 return; |
| 50 } | 51 } |
| 51 } | 52 } |
| 52 }, | 53 }, |
| 53 | 54 |
| 55 _mouseDown: function() | |
| 56 { | |
| 57 this._mouseIsDown = true; | |
| 58 this._lastAnchor = this._anchorElement; | |
| 59 this._hide(); | |
| 60 }, | |
| 61 | |
| 62 _mouseUp: function() | |
| 63 { | |
| 64 delete this._mouseIsDown; | |
| 65 }, | |
| 66 | |
| 54 /** | 67 /** |
| 55 * @param {!Element} anchorElement | 68 * @param {!Element} anchorElement |
| 56 */ | 69 */ |
| 57 _show: function(anchorElement) | 70 _show: function(anchorElement) |
| 58 { | 71 { |
| 59 var tooltip = anchorElement[WebInspector.Tooltip._symbol]; | 72 var tooltip = anchorElement[WebInspector.Tooltip._symbol]; |
| 60 this._anchorElement = anchorElement; | 73 this._anchorElement = anchorElement; |
| 61 this._tooltipElement.removeChildren(); | 74 this._tooltipElement.removeChildren(); |
| 62 if (typeof tooltip.content === "string") | 75 if (typeof tooltip.content === "string") |
| 63 this._tooltipElement.textContent = tooltip.content; | 76 this._tooltipElement.textContent = tooltip.content; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 84 | 97 |
| 85 // Get container element. | 98 // Get container element. |
| 86 var container = WebInspector.Dialog.modalHostView().element; | 99 var container = WebInspector.Dialog.modalHostView().element; |
| 87 if (!anchorElement.isDescendant(container)) | 100 if (!anchorElement.isDescendant(container)) |
| 88 container = this.element.parentElement; | 101 container = this.element.parentElement; |
| 89 | 102 |
| 90 // Posititon tooltip based on the anchor element. | 103 // Posititon tooltip based on the anchor element. |
| 91 var containerOffset = container.offsetRelativeToWindow(this.element.wind ow()); | 104 var containerOffset = container.offsetRelativeToWindow(this.element.wind ow()); |
| 92 var containerOffsetWidth = container.offsetWidth; | 105 var containerOffsetWidth = container.offsetWidth; |
| 93 var anchorBox = this._anchorElement.boxInWindow(this.element.window()); | 106 var anchorBox = this._anchorElement.boxInWindow(this.element.window()); |
| 94 const arrowSize = 4; | 107 const anchorOffset = 2; |
| 95 const pageMargin = 2; | 108 const pageMargin = 2; |
| 96 this._tooltipElement.style.maxWidth = (containerOffsetWidth - pageMargin * 2) + "px"; | 109 this._tooltipElement.style.maxWidth = (containerOffsetWidth - pageMargin * 2) + "px"; |
| 97 var tooltipWidth = this._tooltipElement.offsetWidth; | 110 var tooltipWidth = this._tooltipElement.offsetWidth; |
| 98 var tooltipHeight = this._tooltipElement.offsetHeight; | 111 var tooltipHeight = this._tooltipElement.offsetHeight; |
| 99 var tooltipX = anchorBox.x + anchorBox.width / 2 - tooltipWidth / 2; | 112 var tooltipX = anchorBox.x; |
| 100 if (tooltip.alignment === WebInspector.Tooltip.AlignmentOverride.Right) | |
| 101 tooltipX = anchorBox.x; | |
| 102 tooltipX = Number.constrain(tooltipX, | 113 tooltipX = Number.constrain(tooltipX, |
| 103 containerOffset.x + pageMargin, | 114 containerOffset.x + pageMargin, |
| 104 containerOffset.x + containerOffsetWidth - tooltipWidth - pageMargin ); | 115 containerOffset.x + containerOffsetWidth - tooltipWidth - pageMargin ); |
| 105 var onBottom = anchorBox.y - arrowSize - anchorBox.height < containerOff set.y; | 116 var onBottom = anchorBox.y - anchorOffset - anchorBox.height < container Offset.y; |
| 106 var tooltipY = onBottom ? anchorBox.y + anchorBox.height + arrowSize : a nchorBox.y - tooltipHeight - arrowSize; | 117 var tooltipY = onBottom ? anchorBox.y + anchorBox.height + anchorOffset : anchorBox.y - tooltipHeight - anchorOffset; |
| 107 this._tooltipElement.positionAt(tooltipX, tooltipY); | 118 this._tooltipElement.positionAt(tooltipX, tooltipY); |
| 108 | |
| 109 // Position arrow next to anchor element. | |
| 110 this._arrowElement.positionAt(anchorBox.x + anchorBox.width / 2, onBotto m ? anchorBox.y + anchorBox.height : anchorBox.y - arrowSize); | |
| 111 this._arrowElement.classList.toggle("tooltip-arrow-top", !onBottom); | |
| 112 }, | 119 }, |
| 113 | 120 |
| 114 _hide: function() | 121 _hide: function() |
| 115 { | 122 { |
| 116 delete this._anchorElement; | 123 delete this._anchorElement; |
| 117 this._tooltipElement.classList.remove("shown"); | 124 this._tooltipElement.classList.remove("shown"); |
| 118 if (Date.now() > this._tooltipLastOpened) | 125 if (Date.now() > this._tooltipLastOpened) |
| 119 this._tooltipLastClosed = Date.now(); | 126 this._tooltipLastClosed = Date.now(); |
| 120 } | 127 } |
| 121 } | 128 } |
| 122 | 129 |
| 123 WebInspector.Tooltip._symbol = Symbol("Tooltip"); | 130 WebInspector.Tooltip._symbol = Symbol("Tooltip"); |
| 124 | 131 |
| 125 /** | 132 /** |
| 126 * @param {!Document} doc | 133 * @param {!Document} doc |
| 127 */ | 134 */ |
| 128 WebInspector.Tooltip.installHandler = function(doc) | 135 WebInspector.Tooltip.installHandler = function(doc) |
| 129 { | 136 { |
| 130 new WebInspector.Tooltip(doc); | 137 new WebInspector.Tooltip(doc); |
| 131 } | 138 } |
| 132 | 139 |
| 133 /** | 140 /** |
| 134 * @param {!Element} element | 141 * @param {!Element} element |
| 135 * @param {!Element|string} tooltipContent | 142 * @param {!Element|string} tooltipContent |
| 136 * @param {string=} alignment | |
| 137 * @param {string=} actionId | 143 * @param {string=} actionId |
| 138 */ | 144 */ |
| 139 WebInspector.Tooltip.install = function(element, tooltipContent, alignment, acti onId) | 145 WebInspector.Tooltip.install = function(element, tooltipContent, actionId) |
| 140 { | 146 { |
| 141 if (Runtime.experiments.isEnabled("tooltips")) | 147 if (Runtime.experiments.isEnabled("tooltips")) |
| 142 element[WebInspector.Tooltip._symbol] = { content: tooltipContent, alig nment: alignment, actionId: actionId }; | 148 element[WebInspector.Tooltip._symbol] = { content: tooltipContent, acti onId: actionId }; |
| 143 else if (typeof tooltipContent === "string") | 149 else if (typeof tooltipContent === "string") |
| 144 element.title = tooltipContent; | 150 element.title = tooltipContent; |
| 145 else | 151 else |
| 146 console.assert("Cannot set an element without custom tooltips enabled"); | 152 console.assert("Cannot set an element without custom tooltips enabled"); |
| 147 } | 153 } |
| OLD | NEW |