Timeline: make prepareHighlightedEntryInfo return ?Promise<!Element>

BUG=

Review-Url: https://codereview.chromium.org/2314173003
Cr-Commit-Position: refs/heads/master@{#417475}
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileFlameChart.js b/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileFlameChart.js
index 946e5c3..09cb2555 100644
--- a/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileFlameChart.js
+++ b/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileFlameChart.js
@@ -138,7 +138,7 @@
     /**
      * @override
      * @param {number} entryIndex
-     * @return {?Array<!{title: string, value: (string|!Element)}>}
+     * @return {?Element}
      */
     prepareHighlightedEntryInfo: function(entryIndex)
     {
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileView.js b/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileView.js
index 3cdab5a..e06aef7 100644
--- a/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileView.js
+++ b/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileView.js
@@ -448,7 +448,7 @@
     /**
      * @override
      * @param {number} entryIndex
-     * @return {?Array<!{title: string, value: (string|!Element)}>}
+     * @return {?Element}
      */
     prepareHighlightedEntryInfo: function(entryIndex)
     {
@@ -494,7 +494,7 @@
         if (node.deoptReason)
             pushEntryInfoRow(WebInspector.UIString("Not optimized"), node.deoptReason);
 
-        return entryInfo;
+        return WebInspector.ProfileView.buildPopoverTable(entryInfo);
     },
 
     __proto__: WebInspector.ProfileFlameChartDataProvider.prototype
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/HeapProfileView.js b/third_party/WebKit/Source/devtools/front_end/profiler/HeapProfileView.js
index 7bd41ee..b95dc21 100644
--- a/third_party/WebKit/Source/devtools/front_end/profiler/HeapProfileView.js
+++ b/third_party/WebKit/Source/devtools/front_end/profiler/HeapProfileView.js
@@ -409,7 +409,7 @@
     /**
      * @override
      * @param {number} entryIndex
-     * @return {?Array<!{title: string, value: (string|!Element)}>}
+     * @return {?Element}
      */
     prepareHighlightedEntryInfo: function(entryIndex)
     {
@@ -433,7 +433,7 @@
         if (link)
             pushEntryInfoRow(WebInspector.UIString("URL"), link.textContent);
         linkifier.dispose();
-        return entryInfo;
+        return WebInspector.ProfileView.buildPopoverTable(entryInfo);
     },
 
     __proto__: WebInspector.ProfileFlameChartDataProvider.prototype
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/ProfileView.js b/third_party/WebKit/Source/devtools/front_end/profiler/ProfileView.js
index ba20135..39765606 100644
--- a/third_party/WebKit/Source/devtools/front_end/profiler/ProfileView.js
+++ b/third_party/WebKit/Source/devtools/front_end/profiler/ProfileView.js
@@ -72,6 +72,21 @@
     Heavy: "Heavy"
 }
 
+/**
+ * @param {!Array<!{title: string, value: string}>} entryInfo
+ * @return {!Element}
+ */
+WebInspector.ProfileView.buildPopoverTable = function(entryInfo)
+{
+    var table = createElement("table");
+    for (var entry of entryInfo) {
+        var row = table.createChild("tr");
+        row.createChild("td").textContent = entry.title;
+        row.createChild("td").textContent = entry.value;
+    }
+    return table;
+}
+
 WebInspector.ProfileView.prototype = {
     focus: function()
     {
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChart.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChart.js
index 0f098e5f..bc189fc 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChart.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChart.js
@@ -139,7 +139,7 @@
     /**
      * @override
      * @param {number} entryIndex
-     * @return {?Array.<!{title: string, value: (string|!Element)}>}
+     * @return {?Element}
      */
     prepareHighlightedEntryInfo: function(entryIndex)
     {
@@ -635,7 +635,7 @@
     /**
      * @override
      * @param {number} entryIndex
-     * @return {?Array.<!{title: string, value: (string|!Element)}>}
+     * @return {?Element}
      */
     prepareHighlightedEntryInfo: function(entryIndex)
     {
@@ -666,8 +666,8 @@
         } else {
             return null;
         }
-        var value = createElement("div");
-        var root = WebInspector.createShadowRootWithCoreStyles(value, "timeline/timelineFlamechartPopover.css");
+        var element = createElement("div");
+        var root = WebInspector.createShadowRootWithCoreStyles(element, "timeline/timelineFlamechartPopover.css");
         var contents = root.createChild("div", "timeline-flamechart-popover");
         contents.createChild("span", "timeline-info-time").textContent = time;
         contents.createChild("span", "timeline-info-title").textContent = title;
@@ -675,7 +675,7 @@
             warning.classList.add("timeline-info-warning");
             contents.appendChild(warning);
         }
-        return [{ title: "", value: value }];
+        return element;
     },
 
     /**
@@ -1136,7 +1136,7 @@
     /**
      * @override
      * @param {number} index
-     * @return {?Array<!{title: string, value: (string|!Element)}>}
+     * @return {?Element}
      */
     prepareHighlightedEntryInfo: function(index)
     {
@@ -1144,8 +1144,8 @@
         var request = /** @type {!WebInspector.TimelineModel.NetworkRequest} */ (this._requests[index]);
         if (!request.url)
             return null;
-        var value = createElement("div");
-        var root = WebInspector.createShadowRootWithCoreStyles(value, "timeline/timelineFlamechartPopover.css");
+        var element = createElement("div");
+        var root = WebInspector.createShadowRootWithCoreStyles(element, "timeline/timelineFlamechartPopover.css");
         var contents = root.createChild("div", "timeline-flamechart-popover");
         var duration = request.endTime - request.startTime;
         if (request.startTime && isFinite(duration))
@@ -1156,7 +1156,7 @@
             div.style.color = this._colorForPriority(request.priority) || "black";
         }
         contents.createChild("span").textContent = request.url.trimMiddle(maxURLChars);
-        return [{ title: "", value: value }];
+        return element;
     },
 
     /**
diff --git a/third_party/WebKit/Source/devtools/front_end/ui_lazy/FlameChart.js b/third_party/WebKit/Source/devtools/front_end/ui_lazy/FlameChart.js
index 3355cc7..2bb41eb 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui_lazy/FlameChart.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui_lazy/FlameChart.js
@@ -215,7 +215,7 @@
 
     /**
      * @param {number} entryIndex
-     * @return {?Array.<!{title: string, value: (string|!Element)}>}
+     * @return {?Element}
      */
     prepareHighlightedEntryInfo: function(entryIndex) { },
 
@@ -813,12 +813,20 @@
      */
     _updatePopover: function(entryIndex)
     {
-        if (entryIndex !== this._highlightedEntryIndex) {
-            this._entryInfo.removeChildren();
-            var entryInfo = this._dataProvider.prepareHighlightedEntryInfo(entryIndex);
-            if (entryInfo)
-                this._entryInfo.appendChild(this._buildEntryInfo(entryInfo));
+        if (entryIndex === this._highlightedEntryIndex) {
+            this._updatePopoverOffset();
+            return;
         }
+        this._entryInfo.removeChildren();
+        var popoverElement = this._dataProvider.prepareHighlightedEntryInfo(entryIndex);
+        if (popoverElement) {
+            this._entryInfo.appendChild(popoverElement);
+            this._updatePopoverOffset();
+        }
+    },
+
+    _updatePopoverOffset: function()
+    {
         var mouseX = this._lastMouseOffsetX;
         var mouseY = this._lastMouseOffsetY;
         var parentWidth = this._entryInfo.parentElement.clientWidth;
@@ -1842,24 +1850,6 @@
     },
 
     /**
-     * @param {!Array<!{title: string, value: (string|!Element)}>} entryInfo
-     * @return {!Element}
-     */
-    _buildEntryInfo: function(entryInfo)
-    {
-        var infoTable = createElementWithClass("table", "info-table");
-        for (var entry of entryInfo) {
-            var row = infoTable.createChild("tr");
-            row.createChild("td", "title").textContent = entry.title;
-            if (typeof entry.value === "string")
-                row.createChild("td").textContent = entry.value;
-            else
-                row.createChild("td").appendChild(entry.value);
-        }
-        return infoTable;
-    },
-
-    /**
      * @param {!CanvasRenderingContext2D} context
      * @param {string} text
      * @param {number} maxWidth