mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-10-10 13:44:39 +08:00
Move and rename files. NOAUTOREVERT=true NOPRESUBMIT=true NOTREECHECKS=true Bug: 768828 TBR=darin@chromium.org NOTRY=true Change-Id: I66d3b155808bc5bdbf237b80208e1e552bcf7f28 Reviewed-on: https://chromium-review.googlesource.com/1001153 Reviewed-by: Blink Reformat <blink-reformat@chromium.org> Commit-Queue: Blink Reformat <blink-reformat@chromium.org> Cr-Original-Commit-Position: refs/heads/master@{#549061} Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src Cr-Mirrored-Commit: 0aee4434a4dba42a42abaea9bfbc0cd196a63bc1
189 lines
5.6 KiB
JavaScript
189 lines
5.6 KiB
JavaScript
// Copyright 2016 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
/**
|
|
* @unrestricted
|
|
*/
|
|
SDK.ServerTiming = class {
|
|
/**
|
|
* @param {string} metric
|
|
* @param {?number} value
|
|
* @param {?string} description
|
|
*/
|
|
constructor(metric, value, description) {
|
|
this.metric = metric;
|
|
this.value = value;
|
|
this.description = description;
|
|
}
|
|
|
|
/**
|
|
* @param {!Array<!SDK.NetworkRequest.NameValue>} headers
|
|
* @return {?Array<!SDK.ServerTiming>}
|
|
*/
|
|
static parseHeaders(headers) {
|
|
const rawServerTimingHeaders = headers.filter(item => item.name.toLowerCase() === 'server-timing');
|
|
if (!rawServerTimingHeaders.length)
|
|
return null;
|
|
|
|
const serverTimings = rawServerTimingHeaders.reduce((memo, header) => {
|
|
const timing = this.createFromHeaderValue(header.value);
|
|
memo.pushAll(timing.map(function(entry) {
|
|
return new SDK.ServerTiming(
|
|
entry.name, entry.hasOwnProperty('dur') ? entry.dur : null, entry.hasOwnProperty('desc') ? entry.desc : '');
|
|
}));
|
|
return memo;
|
|
}, []);
|
|
serverTimings.sort((a, b) => a.metric.toLowerCase().compareTo(b.metric.toLowerCase()));
|
|
return serverTimings;
|
|
}
|
|
|
|
/**
|
|
* @param {string} valueString
|
|
* @return {?Array<!Object>}
|
|
*/
|
|
static createFromHeaderValue(valueString) {
|
|
function trimLeadingWhiteSpace() {
|
|
valueString = valueString.replace(/^\s*/, '');
|
|
}
|
|
function consumeDelimiter(char) {
|
|
console.assert(char.length === 1);
|
|
trimLeadingWhiteSpace();
|
|
if (valueString.charAt(0) !== char)
|
|
return false;
|
|
|
|
valueString = valueString.substring(1);
|
|
return true;
|
|
}
|
|
function consumeToken() {
|
|
// https://tools.ietf.org/html/rfc7230#appendix-B
|
|
const result = /^(?:\s*)([\w!#$%&'*+\-.^`|~]+)(?:\s*)(.*)/.exec(valueString);
|
|
if (!result)
|
|
return null;
|
|
|
|
valueString = result[2];
|
|
return result[1];
|
|
}
|
|
function consumeTokenOrQuotedString() {
|
|
trimLeadingWhiteSpace();
|
|
if (valueString.charAt(0) === '"')
|
|
return consumeQuotedString();
|
|
|
|
return consumeToken();
|
|
}
|
|
function consumeQuotedString() {
|
|
console.assert(valueString.charAt(0) === '"');
|
|
valueString = valueString.substring(1); // remove leading DQUOTE
|
|
|
|
let value = '';
|
|
while (valueString.length) {
|
|
// split into two parts:
|
|
// -everything before the first " or \
|
|
// -everything else
|
|
const result = /^([^"\\]*)(.*)/.exec(valueString);
|
|
value += result[1];
|
|
if (result[2].charAt(0) === '"') {
|
|
// we have found our closing "
|
|
valueString = result[2].substring(1); // strip off everything after the closing "
|
|
return value; // we are done here
|
|
}
|
|
|
|
console.assert(result[2].charAt(0) === '\\');
|
|
// special rules for \ found in quoted-string (https://tools.ietf.org/html/rfc7230#section-3.2.6)
|
|
value += result[2].charAt(1); // grab the character AFTER the \ (if there was one)
|
|
valueString = result[2].substring(2); // strip off \ and next character
|
|
}
|
|
|
|
return null; // not a valid quoted-string
|
|
}
|
|
function consumeExtraneous() {
|
|
const result = /([,;].*)/.exec(valueString);
|
|
if (result)
|
|
valueString = result[1];
|
|
}
|
|
|
|
const result = [];
|
|
let name;
|
|
while ((name = consumeToken()) !== null) {
|
|
const entry = {name};
|
|
|
|
if (valueString.charAt(0) === '=')
|
|
this.showWarning(ls`Deprecated syntax found. Please use: <name>;dur=<duration>;desc=<description>`);
|
|
|
|
while (consumeDelimiter(';')) {
|
|
let paramName;
|
|
if ((paramName = consumeToken()) === null)
|
|
continue;
|
|
|
|
paramName = paramName.toLowerCase();
|
|
const parseParameter = this.getParserForParameter(paramName);
|
|
let paramValue = null;
|
|
if (consumeDelimiter('=')) {
|
|
// always parse the value, even if we don't recognize the parameter name
|
|
paramValue = consumeTokenOrQuotedString();
|
|
consumeExtraneous();
|
|
}
|
|
|
|
if (parseParameter) {
|
|
// paramName is valid
|
|
if (entry.hasOwnProperty(paramName)) {
|
|
this.showWarning(ls`Duplicate parameter \"${paramName}\" ignored.`);
|
|
continue;
|
|
}
|
|
|
|
if (paramValue === null)
|
|
this.showWarning(ls`No value found for parameter \"${paramName}\".`);
|
|
|
|
parseParameter.call(this, entry, paramValue);
|
|
} else {
|
|
// paramName is not valid
|
|
this.showWarning(ls`Unrecognized parameter \"${paramName}\".`);
|
|
}
|
|
}
|
|
|
|
result.push(entry);
|
|
if (!consumeDelimiter(','))
|
|
break;
|
|
}
|
|
|
|
if (valueString.length)
|
|
this.showWarning(ls`Extraneous trailing characters.`);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* @param {string} paramName
|
|
* @return {?function(!Object, string)}
|
|
*/
|
|
static getParserForParameter(paramName) {
|
|
switch (paramName) {
|
|
case 'dur':
|
|
return function(entry, paramValue) {
|
|
entry.dur = 0;
|
|
if (paramValue !== null) {
|
|
const duration = parseFloat(paramValue);
|
|
if (isNaN(duration)) {
|
|
this.showWarning(ls`Unable to parse \"${paramName}\" value \"${paramValue}\".`);
|
|
return;
|
|
}
|
|
entry.dur = duration;
|
|
}
|
|
};
|
|
|
|
case 'desc':
|
|
return function(entry, paramValue) {
|
|
entry.desc = paramValue || '';
|
|
};
|
|
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {string} msg
|
|
*/
|
|
static showWarning(msg) {
|
|
Common.console.warn(Common.UIString(`ServerTiming: ${msg}`));
|
|
}
|
|
};
|