| Index: third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js
|
| diff --git a/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js b/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js
|
| index 761de07779098e95cd0b34f0d20fe90ee7f11d04..6221c8fe1e84f6d146bb821d3699fab06e7801b3 100644
|
| --- a/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js
|
| +++ b/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js
|
| @@ -155,19 +155,12 @@
|
| this._updateStatus(Common.UIString('Loading\u2026'));
|
| })
|
| .then(_ => this._protocolService.startLighthouse(this._inspectedURL, categoryIDs))
|
| - .then(lighthouseResult => {
|
| - if (lighthouseResult && lighthouseResult.fatal) {
|
| - const error = new Error(lighthouseResult.message);
|
| - error.stack = lighthouseResult.stack;
|
| - throw error;
|
| - }
|
| -
|
| - return this._stopAndReattach().then(() => this._buildReportUI(lighthouseResult));
|
| - })
|
| - .catch(err => {
|
| + .then(lighthouseResult =>
|
| + this._stopAndReattach().then(() => this._buildReportUI(lighthouseResult))
|
| + ).catch(err => {
|
| if (err instanceof Error)
|
| this._renderBugReport(err);
|
| - });
|
| + });
|
| }
|
|
|
| _hideDialog() {
|
| @@ -260,8 +253,7 @@
|
| console.error(err);
|
| this._statusElement.textContent = '';
|
| this._statusIcon.classList.add('error');
|
| - this._statusElement.createTextChild(Common.UIString('Ah, sorry! We ran into an error: '));
|
| - this._statusElement.createChild('em').createTextChild(err.message);
|
| + this._statusElement.createTextChild(Common.UIString('We ran into an error. '));
|
| this._createBugReportLink(err, this._statusElement);
|
| }
|
|
|
| @@ -273,16 +265,10 @@
|
| var baseURI = 'https://github.com/GoogleChrome/lighthouse/issues/new?';
|
| var title = encodeURI('title=DevTools Error: ' + err.message.substring(0, 60));
|
|
|
| - var issueBody = `
|
| -**Initial URL**: ${this._inspectedURL}
|
| -**Chrome Version**: ${navigator.userAgent.match(/Chrome\/(\S+)/)[1]}
|
| -**Error Message**: ${err.message}
|
| -**Stack Trace**:
|
| -\`\`\`
|
| -${err.stack}
|
| -\`\`\`
|
| - `;
|
| - var body = '&body=' + encodeURI(issueBody.trim());
|
| + var qsBody = '';
|
| + qsBody += '**Error Message**: ' + err.message + '\n';
|
| + qsBody += '**Stack Trace**:\n ```' + err.stack + '```';
|
| + var body = '&body=' + encodeURI(qsBody);
|
|
|
| var reportErrorEl = parentElem.createChild('a', 'audits2-link audits2-report-error');
|
| reportErrorEl.href = baseURI + title + body;
|
| @@ -554,7 +540,7 @@
|
| return;
|
| }
|
|
|
| - this._reportContainer = this._resultsView.createChild('div', 'report-container lh-vars lh-root lh-devtools');
|
| + this._reportContainer = this._resultsView.createChild('div', 'report-container lh-vars lh-root');
|
|
|
| var dom = new DOM(/** @type {!Document} */ (this._resultsView.ownerDocument));
|
| var detailsRenderer = new Audits2.DetailsRenderer(dom);
|
| @@ -568,6 +554,77 @@
|
|
|
| renderer.setTemplateContext(templatesDOM);
|
| renderer.renderReport(this._lighthouseResult, this._reportContainer);
|
| +
|
| + var performanceScoreElement = this._reportContainer.querySelector('.lh-category[id=performance] .lh-score');
|
| + var artifacts = this._lighthouseResult['artifacts'];
|
| + if (!performanceScoreElement || !artifacts)
|
| + return;
|
| + var tracePass = artifacts['traces'] ? artifacts['traces']['defaultPass'] : null;
|
| + if (!tracePass)
|
| + return;
|
| +
|
| + var fmp = this._lighthouseResult['audits']['first-meaningful-paint'];
|
| + if (!fmp || !fmp['extendedInfo'])
|
| + return;
|
| +
|
| + var tti = this._lighthouseResult['audits']['time-to-interactive'];
|
| + if (!tti || !tti['extendedInfo'])
|
| + return;
|
| +
|
| + var navStart = fmp['extendedInfo']['value']['timestamps']['navStart'];
|
| + var markers = [
|
| + {
|
| + title: Common.UIString('First contentful paint'),
|
| + value: (fmp['extendedInfo']['value']['timestamps']['fCP'] - navStart) / 1000
|
| + },
|
| + {
|
| + title: Common.UIString('First meaningful paint'),
|
| + value: (fmp['extendedInfo']['value']['timestamps']['fMP'] - navStart) / 1000
|
| + },
|
| + {
|
| + title: Common.UIString('Time to interactive'),
|
| + value: (tti['extendedInfo']['value']['timestamps']['timeToInteractive'] - navStart) / 1000
|
| + },
|
| + {
|
| + title: Common.UIString('Visually ready'),
|
| + value: (tti['extendedInfo']['value']['timestamps']['visuallyReady'] - navStart) / 1000
|
| + }
|
| + ];
|
| +
|
| + var timeSpan = Math.max(...markers.map(marker => marker.value));
|
| + var screenshots = tracePass.traceEvents.filter(e => e.cat === 'disabled-by-default-devtools.screenshot');
|
| + var timelineElement = createElementWithClass('div', 'audits2-timeline');
|
| + var filmStripElement = timelineElement.createChild('div', 'audits2-filmstrip');
|
| +
|
| + var numberOfFrames = 8;
|
| + var roundToMs = 100;
|
| + var timeStep = (Math.ceil(timeSpan / numberOfFrames / roundToMs)) * roundToMs;
|
| +
|
| + for (var time = 0; time < timeSpan; time += timeStep) {
|
| + var frameForTime = null;
|
| + for (var e of screenshots) {
|
| + if ((e.ts - navStart) / 1000 < time + timeStep)
|
| + frameForTime = e.args.snapshot;
|
| + }
|
| + var frame = filmStripElement.createChild('div', 'frame');
|
| + frame.createChild('div', 'time').textContent = Number.millisToString(time + timeStep);
|
| +
|
| + var thumbnail = frame.createChild('div', 'thumbnail');
|
| + if (frameForTime) {
|
| + var img = thumbnail.createChild('img');
|
| + img.src = 'data:image/jpg;base64,' + frameForTime;
|
| + }
|
| + }
|
| +
|
| + for (var marker of markers) {
|
| + var markerElement = timelineElement.createChild('div', 'audits2-timeline-marker');
|
| + markerElement.createChild('div', 'audits2-timeline-bar').style.width =
|
| + (100 * (marker.value / timeSpan) | 0) + '%';
|
| + markerElement.createChild('span').textContent = Common.UIString('%s: ', marker.title);
|
| + markerElement.createChild('span', 'audits2-timeline-subtitle').textContent = Number.millisToString(marker.value);
|
| + }
|
| +
|
| + performanceScoreElement.parentElement.insertBefore(timelineElement, performanceScoreElement.nextSibling);
|
| }
|
| };
|
|
|
|
|