diff --git a/src/content/components/FlameChartCanvas.css b/src/content/components/FlameChartCanvas.css
index 32ee31766bb..901c228567c 100644
--- a/src/content/components/FlameChartCanvas.css
+++ b/src/content/components/FlameChartCanvas.css
@@ -8,6 +8,10 @@
left: 0;
}
+/**
+ * This tooltip is multi-line and more intense, so add additional whitespace to make it
+ * more readable.
+ */
.flameChartCanvasTooltip {
padding: 5px;
}
diff --git a/src/content/components/IntervalMarkerOverview.js b/src/content/components/IntervalMarkerOverview.js
index 33d7db2f11e..545afa4cdc6 100644
--- a/src/content/components/IntervalMarkerOverview.js
+++ b/src/content/components/IntervalMarkerOverview.js
@@ -157,7 +157,7 @@ class IntervalMarkerOverview extends PureComponent {
this._scheduleDraw();
const { className, isSelected } = this.props;
const { mouseDownItem, hoveredItem, mouseX, mouseY } = this.state;
- const tooltipText = !mouseDownItem && hoveredItem ? hoveredItem.title : null;
+ const tooltipContents = !mouseDownItem && hoveredItem ? hoveredItem.title : null;
const canvasClassName = className.split(' ').map(name => `${name}Canvas`).join(' ');
return (
@@ -169,12 +169,12 @@ class IntervalMarkerOverview extends PureComponent {
onMouseUp={this._onMouseUp}
onMouseOut={this._onMouseOut}/>
{
- tooltipText
+ tooltipContents
?
- {tooltipText}
+ {tooltipContents}
: null
}
diff --git a/src/content/components/TimelineCanvas.js b/src/content/components/TimelineCanvas.js
index 9141f2e6ff8..63183125d67 100644
--- a/src/content/components/TimelineCanvas.js
+++ b/src/content/components/TimelineCanvas.js
@@ -151,7 +151,7 @@ export default class TimelineCanvas extends Component {
hover: hoveredItem !== null,
});
- const tooltipText = this._getHoveredItemInfo();
+ const tooltipContents = this._getHoveredItemInfo();
return (
@@ -161,11 +161,10 @@ export default class TimelineCanvas extends Component {
onMouseOut={this._onMouseOut}
onDoubleClick={this._onDoubleClick} />
{
- !isDragging && tooltipText
+ !isDragging && tooltipContents
?
- {tooltipText}
+ mouseY={mouseY}>
+ {tooltipContents}
: null
}
diff --git a/src/content/components/Tooltip.css b/src/content/components/Tooltip.css
index 4ef214b9f5f..5dd1ecc8d14 100644
--- a/src/content/components/Tooltip.css
+++ b/src/content/components/Tooltip.css
@@ -13,8 +13,9 @@
.tooltip {
position: relative;
max-width: 100%;
- padding: 2px 5px;
+ box-sizing: border-box;
display: inline-block;
+ padding: 2px 5px;
border: 1px solid #ccc;
background-color: #f9f9f9;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
@@ -67,3 +68,46 @@
width: 60px;
color: var(--theme-highlight-gray);
}
+
+.tooltipTiming {
+ padding-right: 0.5em;
+ color: var(--theme-highlight-green);
+ font-weight: bold;
+}
+
+.tooltipOneLine {
+ display: flex;
+ max-width: 100%;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+
+.tooltipName {
+ flex: 1;
+ text-overflow: ellipsis;
+ overflow: hidden;
+}
+
+.tooltipSwatch {
+ width: 10px;
+ height: 10px;
+ display: inline-block;
+ border: 1px solid #888;
+ margin-right: 3px;
+}
+
+.tooltipHeader {
+ padding-bottom: 10px;
+ margin-bottom: 10px;
+ border-bottom: 1px solid var(--theme-highlight-gray);
+}
+
+.tooltipDetails {
+ margin: 5px 0;
+}
+
+.tooltipLabel {
+ display: block;
+ width: 60px;
+ color: #666;
+}
diff --git a/src/content/components/Tooltip.js b/src/content/components/Tooltip.js
index 20091eaa0be..708946441d3 100644
--- a/src/content/components/Tooltip.js
+++ b/src/content/components/Tooltip.js
@@ -22,7 +22,7 @@ export default class Tooltip extends PureComponent {
state: {
interiorElement: HTMLElement | null,
- interiorElementRAF: HTMLElement | null,
+ isNewContentLaidOut: boolean,
};
_isMounted: boolean;
@@ -30,14 +30,14 @@ export default class Tooltip extends PureComponent {
constructor(props: Props) {
super(props);
- (this: any)._getMountElement = this._getMountElement.bind(this);
+ (this: any)._setMountElement = this._setMountElement.bind(this);
this.state = {
interiorElement: null,
- interiorElementRAF: null,
+ isNewContentLaidOut: false,
};
}
- _getMountElement(el: HTMLElement) {
+ _setMountElement(el: HTMLElement) {
this.setState({ interiorElement: el });
}
@@ -67,26 +67,34 @@ export default class Tooltip extends PureComponent {
componentWillReceiveProps(nextProps: Props) {
if (nextProps.children !== this.props.children) {
- this.setState({interiorElementRAF: null });
- this._allowInteriorElementLayout();
+ // If the children are different, allow them to do an initial lay out on the DOM.
+ this.setState({isNewContentLaidOut: false });
+ this._forceUpdateAfterRAF();
}
}
componentDidUpdate() {
- this._allowInteriorElementLayout();
+ // Force an additional update to this component if the children content is
+ // different as it needs to fully lay out one time on the DOM to proper calculate
+ // sizing and positioning.
+ const { interiorElement, isNewContentLaidOut } = this.state;
+ if (interiorElement && !isNewContentLaidOut) {
+ this._forceUpdateAfterRAF();
+ }
+
this._renderTooltipContents();
}
- _allowInteriorElementLayout() {
- const { interiorElement, interiorElementRAF } = this.state;
- if (interiorElement && !interiorElementRAF) {
- // Allow the interior element to fully lay out, then update the sizing.
- requestAnimationFrame(() => {
- if (this._isMounted) {
- this.setState({ interiorElementRAF: interiorElement });
- }
- });
- }
+ /**
+ * Children content needs to be on the DOM (not just virtual DOM) in order to correctly
+ * calculate the sizing and positioning of the tooltip.
+ */
+ _forceUpdateAfterRAF() {
+ requestAnimationFrame(() => {
+ if (this._isMounted) {
+ this.setState({ isNewContentLaidOut: true });
+ }
+ });
}
/**
@@ -116,14 +124,14 @@ export default class Tooltip extends PureComponent {
};
ReactDOM.render(
-
- {children}
-
,
+
+ {children}
+
,
this._mountElement
);
}
render() {
- return
;
+ return null;
}
}