mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-09-28 13:13:37 +08:00
This adds an option `--enable-unstable-features`, which now also turns on multimodal support for Freestyler. It also adds `--enable-features` and `--disable-features`, to allow more fine-grained control over the exact feature set when necessary. Fixed: 406941932 Change-Id: I7fcecbba833a2e0a66166890aa5af218ae2a8f7e Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6404318 Reviewed-by: Nikolay Vitkov <nvitkov@chromium.org>
110 lines
3.3 KiB
JavaScript
110 lines
3.3 KiB
JavaScript
// Copyright 2025 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.
|
|
|
|
/**
|
|
* Representation of the feature set that is configured for Chrome. This
|
|
* keeps track of enabled and disabled features and generates the correct
|
|
* combination of `--enable-features` / `--disable-features` command line
|
|
* flags.
|
|
*
|
|
* There are unit tests for this in `./devtools_build.test.mjs`.
|
|
*/
|
|
export class FeatureSet {
|
|
#disabled = new Set();
|
|
#enabled = new Map();
|
|
|
|
/**
|
|
* Disables the given `feature`.
|
|
*
|
|
* @param {string} feature the name of the feature to disable.
|
|
*/
|
|
disable(feature) {
|
|
this.#disabled.add(feature);
|
|
this.#enabled.delete(feature);
|
|
}
|
|
|
|
/**
|
|
* Enables the given `feature`, and optionally adds the `parameters` to it.
|
|
* For example:
|
|
* ```js
|
|
* featureSet.enable('DevToolsFreestyler', {patching: true});
|
|
* ```
|
|
* The parameters are additive.
|
|
*
|
|
* @param {string} feature the name of the feature to enable.
|
|
* @param {object} parameters the additional parameters to pass to it, in
|
|
* the form of key/value pairs.
|
|
*/
|
|
enable(feature, parameters = {}) {
|
|
this.#disabled.delete(feature);
|
|
if (!this.#enabled.has(feature)) {
|
|
this.#enabled.set(feature, Object.create(null));
|
|
}
|
|
for (const [key, value] of Object.entries(parameters)) {
|
|
this.#enabled.get(feature)[key] = value;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Merge the other `featureSet` into this.
|
|
*
|
|
* @param featureSet the other `FeatureSet` to apply.
|
|
*/
|
|
merge(featureSet) {
|
|
for (const feature of featureSet.#disabled) {
|
|
this.disable(feature);
|
|
}
|
|
for (const [feature, parameters] of featureSet.#enabled) {
|
|
this.enable(feature, parameters);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Yields the command line parameters to pass to the invocation of
|
|
* a Chrome binary for achieving the state of the feature set.
|
|
*/
|
|
* [Symbol.iterator]() {
|
|
const disabledFeatures = [...this.#disabled];
|
|
if (disabledFeatures.length) {
|
|
yield `--disable-features=${disabledFeatures.sort().join(',')}`;
|
|
}
|
|
const enabledFeatures = [...this.#enabled].map(([feature, parameters]) => {
|
|
parameters = Object.entries(parameters);
|
|
if (parameters.length) {
|
|
parameters = parameters.map(([key, value]) => `${key}/${value}`);
|
|
feature = `${feature}:${parameters.sort().join('/')}`;
|
|
}
|
|
return feature;
|
|
});
|
|
if (enabledFeatures.length) {
|
|
yield `--enable-features=${enabledFeatures.sort().join(',')}`;
|
|
}
|
|
}
|
|
|
|
static parse(text) {
|
|
const features = [];
|
|
for (const str of text.split(',')) {
|
|
const parts = str.split(':');
|
|
if (parts.length < 1 || parts.length > 2) {
|
|
throw new Error(`Invalid feature declaration '${str}'`);
|
|
}
|
|
const feature = parts[0];
|
|
const parameters = Object.create(null);
|
|
if (parts.length > 1) {
|
|
const args = parts[1].split('/');
|
|
if (args.length % 2 !== 0) {
|
|
throw new Error(`Invalid parameters '${parts[1]}' for feature ${feature}`);
|
|
}
|
|
for (let i = 0; i < args.length; i += 2) {
|
|
const key = args[i + 0];
|
|
const value = args[i + 1];
|
|
parameters[key] = value;
|
|
}
|
|
}
|
|
features.push({feature, parameters});
|
|
}
|
|
return features;
|
|
}
|
|
}
|