Files
react-native-devtools-frontend/front_end/emulation/UserAgentMetadata.ts
T
Maks Orlovich 41545839b3 Add ability to edit UA-CH for custom devices.
User-Agent Client Hints are an alternative to the UA String that's
more structured (no ad-hoc parsing!) and has better privacy control
(explicit control over which bits of more identifying information are
 sent).

Devtools has already supported emulating the sent client hints of the
bundled in devices; this also lets the user configure them for any new
custom devices they may add.

Screenshots:
current look, before any changes:
https://imgur.com/OHq1GMS

new, UA-CH section folded:
https://imgur.com/Eufp0VE

new section open and empty:
https://imgur.com/5uvxewJ

entering data:
https://imgur.com/ygIqS9z

all done:
https://imgur.com/5BH1Pse


Bug: 1073909
Change-Id: Id79e5eaae5d1f690d22635ca5f27566b982776b1
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2543693
Commit-Queue: Maksim Orlovich <morlovich@chromium.org>
Reviewed-by: Simon Zünd <szuend@chromium.org>
2020-12-15 16:49:09 +00:00

84 lines
3.1 KiB
TypeScript

// Copyright 2020 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.
//
// Helper functions for working with UserAgentMetadata protocol objects, in
// particular their plain string representation.
import * as UI from '../ui/ui.js';
import {Item, List, Parameters, ParamName, parseList, ResultKind, serializeItem, serializeList, String as SHString} from './StructuredHeaders.js';
/* Returned string is for error, either parseErrorString or structErrorString.
*/
export function parseBrandsList(stringForm: string, parseErrorString: string, structErrorString: string):
Protocol.Emulation.UserAgentBrandVersion[]|string {
const brandList: Protocol.Emulation.UserAgentBrandVersion[] = [];
const parseResult = parseList(stringForm);
if (parseResult.kind === ResultKind.ERROR) {
return parseErrorString;
}
for (const listItem of parseResult.items) {
if (listItem.kind !== ResultKind.ITEM) {
return structErrorString;
}
const bareItem = listItem.value;
if (bareItem.kind !== ResultKind.STRING) {
return structErrorString;
}
if (listItem.parameters.items.length !== 1) {
return structErrorString;
}
const param = listItem.parameters.items[0];
if (param.name.value !== 'v') {
return structErrorString;
}
const paramValue = param.value;
if (paramValue.kind !== ResultKind.STRING) {
return structErrorString;
}
brandList.push({brand: bareItem.value, version: paramValue.value});
}
return brandList;
}
export function serializeBrandsList(brands: Protocol.Emulation.UserAgentBrandVersion[]): string {
const shList: List = {kind: ResultKind.LIST, items: []};
const vParamName: ParamName = {kind: ResultKind.PARAM_NAME, value: 'v'};
for (const brand of brands) {
const nameString: SHString = {kind: ResultKind.STRING, value: brand.brand};
const verString: SHString = {kind: ResultKind.STRING, value: brand.version};
const verParams: Parameters = {
kind: ResultKind.PARAMETERS,
items: [{kind: ResultKind.PARAMETER, name: vParamName, value: verString}],
};
const shItem: Item = {kind: ResultKind.ITEM, value: nameString, parameters: verParams};
shList.items.push(shItem);
}
const serializeResult = serializeList(shList);
return serializeResult.kind === ResultKind.ERROR ? '' : serializeResult.value;
}
/*
* This checks whether the value provided is representable as a structured headers string,
* which is the validity requirement for the fields in UserAgentMetadata that are not the brand list
* or mobile bool.
*
* errorMessage will be passed through on failure.
*/
export function validateAsStructuredHeadersString(value: string, errorString: string): UI.ListWidget.ValidatorResult {
const parsedResult = serializeItem({
kind: ResultKind.ITEM,
value: {kind: ResultKind.STRING, value: value},
parameters: {kind: ResultKind.PARAMETERS, items: []},
});
if (parsedResult.kind === ResultKind.ERROR) {
return {valid: false, errorMessage: errorString};
}
return {valid: true, errorMessage: undefined};
}