[docs] Collect unstructured docs in a cookbook.

Also include the process for creating new issues in the Issues panel
in here.

Bug: 354102605
Change-Id: Ia69ae8141878f62749caffd69d774d0d36baec07
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/5939823
Auto-Submit: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Simon Zünd <szuend@chromium.org>
Commit-Queue: Simon Zünd <szuend@chromium.org>
This commit is contained in:
Benedikt Meurer
2024-10-18 09:29:15 +00:00
committed by Devtools-frontend LUCI CQ
parent 6f3095b1d1
commit 52d9f11ff8
13 changed files with 716 additions and 517 deletions
+1 -5
View File
@@ -27,12 +27,8 @@ below.**
* [Contribution Guide](./contributing/README.md)
* [UX Style Guide](./styleguide/ux/README.md)
* [Testing Guide](../test/README.md)
* [Release Management](release_management.md)
* [Dependencies](dependencies.md)
* [Localization](l10n.md)
* [Cookbook](./cookbook/README.md)
* [Visual logging in DevTools](../front_end/ui/visual_logging/README.md)
* [UMA metrics in DevTools](uma_metrics.md)
* [How to add UMA metrics in DevTools frontend](add_uma_metrics.md)
* [Style Guides](./styleguide/README.md)
### Architectural Documentation
-41
View File
@@ -1,41 +0,0 @@
# How to add UMA metrics in DevTools frontend
Decide on the metric (an [enumerated histogram](https://chromium.googlesource.com/chromium/src/tools/+/HEAD/metrics/histograms/README.md#enum-histograms) or an [action](https://source.chromium.org/chromium/chromium/src/+/main:third_party/devtools-frontend/src/front_end/core/host/UserMetrics.ts;l=380) to be logged to generic `DevTools.ActionTaken` histogram)
1. For enumerated histogram (We use this when there are multiple related states that should be analyzed jointly. For example, we might want to know the source of an action like where it is performed from)
1. Choose a name for the new histogram prefixed with `DevTools`, for example, `DevTools.ColorPickerOpenedFrom`.
2. Decide on the values for the different enums you want to log, for example, `StylesPane` and `SourcesPanel` for `DevTools.ColorPickerOpenedFrom` histogram.
2. For actions
1. Decide on the name of the action, for example, `DeviceModeEnabled`.
## Tracking an enumerated histogram
1. Implement metric collection in devtools-frontend and create a CL. (Example [CL](https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/3998783))
1. Add the new histogram name to the <code>[EnumeratedHistogram](https://source.chromium.org/chromium/chromium/src/+/main:third_party/devtools-frontend/src/front_end/core/host/InspectorFrontendHostAPI.ts;l=351?q=InspectorFrontendHostAPI.ts)</code> enum.
2. Add the same histogram name to the EnumeratedHistogram object in <code>[devtools_compatibility.js](https://source.chromium.org/chromium/chromium/src/+/main:third_party/devtools-frontend/src/front_end/devtools_compatibility.js;l=396?q=devtools_compatibil)</code> file.
3. Create a new function in <code>[UserMetrics.ts](https://source.chromium.org/chromium/chromium/src/+/main:third_party/devtools-frontend/src/front_end/core/host/UserMetrics.ts;l=351)</code> with an enum parameter that corresponds to the possible values like <code>colorPickerOpenedFrom(type: ColorPickerOpenedFrom): void</code> that calls <code>InspectorFrontendHostInstance.recordEnumeratedHistogram</code>.
4. Call the new function from <code>Host.userMetrics</code> in the places that you want to log the event.
5. Create the CL.
2. Update [histograms.xml](https://source.corp.google.com/h/chromium/chromium/src/+/main:tools/metrics/histograms/metadata/dev/histograms.xml) and [enums.xml](https://source.chromium.org/chromium/chromium/src/+/main:tools/metrics/histograms/enums.xml;l=26267?q=tools%2Fmetrics%2Fhistograms%2Fenums.xml) in the Chromium codebase.
1. Add a new enum in [enums.xml](https://source.chromium.org/chromium/chromium/src/+/main:tools/metrics/histograms/enums.xml;l=26267?q=tools%2Fmetrics%2Fhistograms%2Fenums.xml) with values corresponding to the values in the frontend with name <code>DevTools&lt;HISTOGRAM_NAME></code> and make sure that enum values 1-1 map to the values you’ve defined in the frontend.
2. Add the new histogram definition in [histograms.xml](https://source.corp.google.com/h/chromium/chromium/src/+/main:tools/metrics/histograms/metadata/dev/histograms.xml) and set enum name to be the enum you've defined in the 1st step. Make sure that histogram name is the same with the name you've used in the frontend change.
3. Create the CL.
## Tracking an action
1. Implement metric collection in devtools-frontend and create a CL. (Example [CL](https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/3998783))
1. Add the action you want to track to the <code>[Action](https://source.chromium.org/chromium/chromium/src/+/main:third_party/devtools-frontend/src/front_end/core/host/UserMetrics.ts;l=379)</code> enum in <code>UserMetrics.ts.</code>
2. Call <code>Host.userMetrics.actionTaken(Action.YOUR_ACTION)</code> in the places you want to the event.
3. Create the CL.
2. Update enums in the Chromium side in <code>[tools/metrics/histograms/enums.xml](https://source.chromium.org/chromium/chromium/src/+/main:tools/metrics/histograms/enums.xml;l=26267?q=tools%2Fmetrics%2Fhistograms%2Fenums.xml)</code>.
1. Add the new action to the <code>DevToolsAction</code> enum.
2. Create the CL.
## Metrics Dashboard
After the both CLs are landed we expect your histogram or action data to be available in [UMA](http://uma/p/chrome/timeline_v2). For seeing them:
* Select the channel you want to dive into.
* Select the platforms you are interested in (for us, it is Linux, MacOS, Windows, ChromeOS and Lacros)
* Add the metric you want to see: either the histogram name you’ve newly added `DevTools.ColorPickerOpenedFrom` or the generic histogram for action tracking, `DevTools.ActionTaken`.
+12
View File
@@ -0,0 +1,12 @@
# Chromium DevTools Cookbook
[goo.gle/devtools-cookbook](http://goo.gle/devtools-cookbook)
The cookbook provides *recipes* for common workflows / tasks during development
of Chromium DevTools itself.
* [Create new Issues in DevTools](create_new_issues.md)
* [Dependencies](dependencies.md)
* [Localization](localization.md)
* [Release Management](release_management.md)
* [UMA metrics in DevTools](uma_metrics.md)
+88
View File
@@ -0,0 +1,88 @@
# Create new Issues in DevTools
[TOC]
The goal of this doc is to guide you through the necessary steps to send
messages to the new
[Issues panel](https://developers.google.com/web/updates/2020/05/devtools#issues)
([Design Doc](https://docs.google.com/document/u/1/d/1F6R5Bpb3qHNzGPNBSXwEJ_eP8L-anIj0WinxOIyAh54)).
This will help reduce the console fatigue and will give more context to
developers on what the problem is, why it should be fixed and how it can be
fixed.
## Why the Issues Panel?
If there is an existing console log that for some reason you want to edit, this
is a good opportunity to re-think how actionable this message is for developers.
If you are working on a feature and you have in mind throwing a new console log
to notify developers of an unexpected behavior, think about showing an Issue
instead.
Developers could be missing your warning due to the clutter in the console
caused by the many different messages. By creating a new Issue type, you will
give more context on the problem and make the debugging experience more
actionable for them.
## Create new or move existing console messages to the Issues panel
To do so, follow the next steps:
* Reach-out to [dsv@](mailto:dsv@chromium.org) (DevTools TL) and share the
related design doc. Every Issue should be actionable and have at least one
straightforward solution. With the addition of more context and external
documentation, it will support the developer across the whole debugging
story, making the message more actionable than in the console.
* Pipe your message into DevTools. First you need to decide where to report
the issue. Issues can be reported on the browser side (choose this if the
issue is raised in content/browser and/or has information that should not be
shared with the renderer). Otherwise you can report it in the renderer.
* For Browser-side reporting, use
[`devtools_instrumentation::ReportBrowserInitiatedIssue`](https://source.chromium.org/chromium/chromium/src/+/17746910d8707d35a0a072f1bdee9d440946d6f3:content/browser/devtools/devtools_instrumentation.cc;l=962)
to report the issue.
* For renderer-side reporting, use an `AddInspectorIssue` method, those
are available at every execution context, plus some more classes.
([example](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/bindings/core/v8/isolated_world_csp.cc;l=106;drc=63d89d5a9eea0fbacc933a5a8e34f5b3c2908c51)).
* In both cases, you need to define the structure of the issue in
*browser\_protocol.pdl* \[example cl pending, since we want to show a CL
that doesn't also add the deprecated mojo definitions\].
* See
[here](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/public/devtools_protocol/browser_protocol.pdl;l=666;drc=bc268cf81e62349e0f283107d70a5f742476ef4e)
how other issues are defined. You need to add an issue code and an issue
details definition. The issue details should hold all the information
that is required for reporting the issue in the front-end.
* An example of how to create the data-structure can be found
* [here](https://source.chromium.org/chromium/chromium/src/+/3564e4bcc7d53aa60350794fc1348792cc33c80d:content/browser/devtools/devtools_instrumentation.cc;drc=d6edf4bb211798b0aa0b656dfb06614cfea043e3;l=181)
for the browser side
* [here](https://source.chromium.org/chromium/chromium/src/+/3564e4bcc7d53aa60350794fc1348792cc33c80d:third_party/blink/renderer/core/inspector/inspector_audits_agent.cc;drc=2decd986a617ab2556ac268e4c2ef156ac8f7361;l=431)
for the renderer side
* Please add the corresponding backend and frontend test for your changes.
* [Example](https://chromium-review.googlesource.com/c/chromium/src/+/2485937)
of a CL introducing backend web\_tests.
* [Example](https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2485086)
of a CL introducing frontend E2E tests.
* Please CC [szuend@](mailto:szuend@chromium.org) in your CL, and/or add them
as reviewers. You should aim at landing your CL at least 2 weeks before the
Branch cut. Feel free to send out the CL even if it is in an early stage.
The DevTools team can point you in the right direction, and this will avoid
last minute surprises.
* Draft the issue strings (find a template below) and share them with
[dsv@](mailto:dsv@chromium.org) and the rest of your team for approval.
* Once the issue strings are reviewed, implement the front-end CL following
[this example](https://crrev.com/c/2308536). Please add
[szuend@](mailto:szuend@chromium.org) as reviewers to your CL, and send it
out early to get quick feedback. We are happy to help you iterate.
* Please add UMA tracking for your new issue types. This is as easy as adding
the issue types to an enum
([frontend example CL](https://crrev.com/c/2692913),
[backend example CL](https://crrev.com/c/2694408)).
## Draft Issue strings
To create the UX strings the best approach is to draft an initial proposal and
then share it with the broader team for polishing
([existing issue descriptions](https://source.chromium.org/chromium/chromium/src/+/main:third_party/devtools-frontend/src/front_end/issues/descriptions/)
for reference). To do so, make a copy of
[this template](https://docs.google.com/document/d/1OCHRh0A9ERX19DvyI-AuvMLMRuOkljJmj6fn_Vb3Zck)
and fill the information for each type of message you want to show. Iterate to
define the most appropriate message and once you get the approvals, implement
them.
+103
View File
@@ -0,0 +1,103 @@
# Dependencies
[TOC]
## Managing dependencies
If you need to manually roll a git dependency, it's not sufficient to update the
revision in the DEPS file. Instead, use the gclient tool: `bash gclient setdep
-r DEP@REV # for example build@afe0125ef9e10b400d9ec145aa18fca932369346` This
will simultaneously update both the DEPS entry as well as the gitlink entry for
the corresponding git submodule.
To sync dependencies from Chromium to DevTools frontend, use
`scripts/deps/roll_deps.py`. Note that this may: - Introduce unneeded
whitespace/formatting changes. Presubmit scripts (e.g. invoked via `git cl
upload`) will automatically fix these locally, so just apply the changes
directly to your change (e.g. with `git commit --amend`) afterwards. - Introduce
breaking changes to the devtools protocol, causing compilation failures.
Unfortunately these need to be handled manually as there are some changes (e.g.
removing an enum value) that cannot fail gracefully.
The following scripts run as AutoRollers, but can be manually invoked if
desired:
- To roll the `HEAD` commit of DevTools frontend into Chromium, use
`scripts/deps/roll_to_chromium.py`.
- To update DevTools frontend's DEPS, use `roll-dep`.
## Third-party Guidelines
When you want to integrate or use third-party content in DevTools, there are a
couple of different ways to do so. Most of the time, we have to make a
distinction between "third-party code we use as part of DevTools implementation"
and "third-party code we use to build DevTools itself, but is not included in
the product".
### Third-party code included in DevTools bundle
All third-party content that you want to ship as part of the DevTools bundle
must be included in `front_end/third_party`. The typical way to update these
packages is to download the relevant packages from [npm]. Since DevTools does
not use a `package.json` to handle its dependencies (to make it possible to
review third-party changes by legal), most packages bundles are fetched with
`wget`.
For all these packages, the [Chromium third-party guidelines] apply.
Since DevTools ships as part of the Chrome binary, bundle size limitations
apply. To make integration feasible, focus on small packages that (preferably)
have no dependencies. This will make licensing checks feasible for Chromium
reviewers and typically avoids inflating the bundle size.
### Third-party tooling packages
For all third-party packages that are used either as part of the DevTools build
process or to augment engineers workflows (for example linters), we add them to
`scripts/deps/manage_node_deps.py`. This Python script has been approved by
Chromium licensing to be used, on the basis that it enforces all packages have a
license that is compatible with a set of pre-defined licensees.
If you want to use a new package as tooling process in engineer workflows, you
can add the package to the `package.json` and run `npm run install-deps` to
check in the new contents.
Only add new license types to `LICENSES` after you received approval from
`opensource-licensing@google.com`. Their response time is typically within 24
hours, so this typically is not a big hurdle.
To avoid excessive package updates, it is typically easiest to update all
packages in `manage_node_deps.py` once a month. Since NPM packages can have a
lot of (shared) transitive dependencies, updating the packages on a specific day
increases the chances that shared dependencies are deduplicated and thus result
in smaller repository sizes.
> **WARNING:** Updating tools such as Rollup and TypeScript will cause all build
> cache output to be purged, as they are part of all DevTools modules. Whenever
> you are updating either of these tools, update these at the end of a working
> day to avoid full rebuilds for other engineers.
### Chromium third-party DEPS
Some packages related to infrastructure are maintained by Chromium infra teams.
These packages are typically uploaded to cloud storage buckets or are explicitly
mirrored to a repository on https://chromium.googlesource.com. Examples include
[GN][] (Chromium/DevTools build system) or [clang-format][] (multi-language
formatter).
The packages in `DEPS` are typically kept automatically up-to-date with
autorollers. These autorollers will periodically update packages, which
engineers can fetch with running `gclient sync`.
These `DEPS` are checked out on all bots, which includes Chromium and
DevTools-specific bots. To avoid excessive network bandwidth usage, by default
do not check out packages if they are only used in specific situations.
Only include packages that are maintained by Chromium infrastructure teams and
are used to build DevTools in `DEPS`. For packages that are DevTools-specific,
prefer adding them to `scripts/deps/manage_node_deps.py` instead.
[npm]: https://www.npmjs.com/
[Chromium third-party guidelines]: https://chromium.googlesource.com/chromium/src/+/HEAD/docs/adding_to_third_party.md
[GN]: https://gn.googlesource.com/gn/+/master/docs/reference.md
[clang-format]: https://clang.llvm.org/docs/ClangFormat.html
+320
View File
@@ -0,0 +1,320 @@
# Localization
## How to add a localizable string
When you introduce a new UI string or modify an existing one that will be
displayed to the users, or remove a string that is localized, follow these steps
so that it can be localized.
[TOC]
### Adding a string
Before proceeding, make sure you know the different
[localization APIs](#what-are-the-l10n-apis) and know which one you should use.
Code example:
```js
import * as i18n from '../i18n/i18n.js';
// at the top of example.js file, after import statements
const UIStrings = {
/**
* @description A string that is already added
*/
alreadyAddedString: 'Someone already created a "UIStrings = {}" and added this string',
/**
* @description This is an example description for my new string
*/
addThisString: 'The new string I want to add',
/**
* @description This is an example description for my new string with placeholder
* @example {example for placeholder} PH1
*/
addAnotherString: 'Another new string I want to add, with {PH1}',
};
const str_ = i18n.i18n.registerUIStrings('example.js', UIStrings);
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
// ....
// in example.js file, where you want to call the string
const message1 = i18nString(UIStrings.addThisString);
console.log(message1); // The new string I want to add
const message2 = i18nString(UIStrings.addAnotherString, {PH1: 'a placeholder'});
console.log(message2); // Another new string I want to add, with a placeholder
```
1. If there is already `UIStrings = {}` declared in the file, add your string
to it. If there isn't `UIStrings = {}` in the file, create one and add your
string, also register the new UIStrings into the `en-US.json` by adding:
1. `const str_ = i18n.i18n.registerUIStrings({the current fileName.js,
relative to front_end}, UIStrings);`
1. `const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);`
2. Add description and examples for placeholder(if any):
1. To specify the description, use `@description …` `@description This is
an example description for my new string`
2. To specify an example for placeholder, use `@example {…} …` `@example
{example for placeholder} PH1`
3. To distinguish messages with the same content, use `@meaning …`
`@meaning This is an example meaning to differentiate this message from
the other message with same content`
3. Make sure your string is localizable:
1. Do not assume word order by using concatenation. Use the whole string. ❌
`javascript 'Add' + 'breakpoint'` ✔️ `javascript 'Add breakpoint'` or ❌
`javascript let description = 'first part' if (condition) description +=
' second part'` ✔️ `javascript let description if (condition)
description = 'first part second part' else description = 'first part'`
2. Use placeholder over concatenation. This is so that the translators can
adjust variable order based on what works in another language. For
example: ❌ `javascript 'Check ' + title + ' for more information.'` ✔️
`javascript 'Check {PH1} for more information.', {PH1: title}`
3. If your string contains <b>leading or trailing white space</b>, it's
usually an indication that it's half of a sentence. This decreases
localizability as it's essentially concatenating. Modify it so that it
doesn't contain leading or trailing white space anymore if you can.
4. <b>Backticks</b> are only used for the text that should not be
localized. They cannot be escaped as part of the string. Check if there
are something should not be localized (see
[locked terms](#phrases-that-are-fully-locked) for more details).
❌ Not localized
- Numbers: 1, 1.23, 1.2e3, etc.
- Application data: error codes, enums, database names, rgba, urls,
etc.
✔️ Can be localized
- Words and sentences
- Punctuation
- Units of measurement: kb/s, mph, etc.
4. The following commands would add the new strings to `en-US.json`:
- `git cl presubmit --upload`, or
- `node third_party/i18n/collect-strings.js` under the DevTools src folder
5. Strings containing possible plurals have a special format in ICU. This is
because plurals work quite differently in other languages, e.g. special
forms for two or three items.
❌ `javascript if (count === 1) { str = '1 breakpoint'; } else { str = '{n}
breakpoints', {n: count}; }`
✔️ `javascript '{n, plural, =1 {# breakpoint} other {# breakpoints}}', {n:
count};`
- '#' is replaced with the value of `n`
- 'n' is a naming convention, but any name can be used
- Nesting placeholders inside of plurals is allowed
- Put the entire string within the plural switch, e.g. `{# breakpoints
were found}`, not `{# breakpoints} were found`
- Always provide the `=1` and the `other` case, even if they are the same
for English.
### Modifying a string
1. Update the string you want to modify in `UIStrings`
2. Update the description and placeholders of the string if necessary
### Removing a string
1. Remove your string and the metadata from `UIStrings`
## What are the l10n APIs?
Access localized strings in the DevTools frontend using the following
localization calls.
### i18nString
The basic API to make a string (with or without placeholder) localizable. The
first argument is the string reference in `UIStrings` The second argument is an
object for placeholders (if any)
```js
// at the top of example.js file, after import statements
const UIStrings = {
/**
* @description This is an example description for my new string with placeholder
* @example {example for placeholder} PH1
* @example {example 2 for placeholder 2} PH2
*/
addAnotherString: 'Another new string I want to add, with {PH1} and {PH2}',
};
message = i18nString(UIStrings.addAnotherString, {PH1: 'a placeholder', PH2: 'another placeholder'});
```
### i18nLazyString
The `i18nString` function returns the translated string, with placeholders
resolved. To do this, it needs access to the translated strings for the user's
locale, which are not available until after DevTools has finished starting up.
Calls to `i18nString` in the module scope will therefore fail when the module is
imported.
```js
// Fails because i18nString runs at module-import time.
Common.Settings.registerSettingExtension({
category: Common.Settings.SettingCategory.CONSOLE,
title: i18nString(UIStrings.groupSimilarMessagesInConsole),
...
function notTopLevel() {
console.log(extension.title);
}
```
`i18nLazyString` fixes this problem by providing the same API, but returning a
closure that returns a `LocalizedString`. It can be used in top-level calls;
just make sure use-sites know it's a function now.
```js
// Works because i18nLazyString defers the loading of the translated string until later.
Common.Settings.registerSettingExtension({
category: Common.Settings.SettingCategory.CONSOLE,
title: i18nLazyString(UIStrings.groupSimilarMessagesInConsole),
...
// Note we need to call title() now.
function notTopLevel() {
console.log(extension.title());
}
```
### i18n.i18n.getFormatLocalizedString
This call returns a **span element**, not a string. It is used when you want to
construct a DOM element with a localizable string, or localizable content that
contains some other DOM element.
```js
// Create the string in UIString
/**
*@description Message in Coverage View of the Coverage tab
*@example {reload button icon} PH1
*@example {record button icon} PH2
*/
clickTheRecordButtonSToStart: 'Click the reload button {PH1} to reload or record button {PH2} start capturing coverage.',
// Element with localizable content containing two DOM elements that are buttons
const reloadButton = UI.createInlineButton(UI.Toolbar.createActionButtonForId('coverage.start-with-reload'));
const recordButton = UI.createInlineButton(UI.Toolbar.createActionButton(this._toggleRecordAction));
message = i18n.i18n.getFormatLocalizedString(str_, UIStrings.clickTheReloadButtonSToReloadAnd, {PH1: reloadButton, PH2:recordButton });
```
### i18n.i18n.lockedString
This call is a named cast. Use it in places where a localized string is expected
but the term you want to use does not require translation. Instead of locking
the whole phrase or using a placeholder-only phrase, use `lockedString`.
```javascript
someFunctionRequiringALocalizedString(i18n.i18n.lockedString('HTTP'));
```
## How to write good descriptions
Good descriptions can improve localizability by providing more context to the
translators. There are some details that are very important to have in other
languages!
**Good description**:
```js
const UIStrings = {
/**
* @description Tooltip text that appears when hovering over the 'Focusable' attribute name under the Computed Properties section in the Accessibility pane of the Elements pane.
*/
computedPropertyTooltip: 'If true, this element can receive focus.',
};
```
**Bad description**:
```js
const UIStrings = {
/**
* @description Elements pane 'Focusable' tooltip.
*/
computedPropertyTooltip: 'If true, this element can receive focus.',
};
```
### What information should I provide in the message description?
- The type of UI element where the text is displayed. Is it regular text, a
label, button text, a tooltip, a link, or an accessible label? Button text
is often imperative i.e. a command to do something, which is important to
know in some languages.
- *When*: What triggers the string and/or what is the result? What page or
text comes before and after? e.g. "Status text while waiting for X", "Shown
when the audit is finished and X error was encountered".
- What do the placeholders stand for? Placeholder examples are sent to
translators, but extra information in the description will help too. e.g.
"Total time in ms that the profile took to complete", "The CSS property name
that is being edited"
- Is this a verb or a noun? Many words in English can be both, e.g. 'request',
'address', 'change', 'display', 'increase'. Particularly if the string is
short, this can be hard to guess. If it's an adjective, what does it refer
to? This is important for inflection in some languages, where the ending of
the adjective must change for gender or case.
- Explain or name any complex terms, e.g. "Trust Tokens are a web API -
https://web.dev/trust-tokens/"
- Where is the text located? e.g. A table header in the Sources panel, a
context-menu item in the Network panel. Many strings in the code base have
*only* the location, which is not the most important context.
## How to prevent a term being localized
Any text within the backticks will not be translated. For example, if the
'robots.txt' in string 'Requesting for robots.txt ...' should not be translated:
```javascript
// in example.js file
import * as i18n from '../i18n/i18n.js';
const UIStrings = {
/**
* @description Example description. Note: "robots.txt" is a canonical filename and should not be translated.
*/
requestMessage: 'Requesting for `robots.txt` ...',
};
const str_ = i18n.i18n.registerUIStrings('example.js', UIStrings);
const message = i18nString(UIStrings.requestMessage);
```
The string will rendered with robots.txt not translated and without the
backticks around it `js 'Requesting for robots.txt ...'`
### Phrases that are fully locked
Any text that is fully locked should not go into the UIStrings object. To make
your intention clear or to make TypeScript happy, there are two methods
`i18n.i18n.lockedString` and `i18n.i18n.lockedLazyString` that can be used
instead of having fully locked phrases via `i18nString`.
### What should not be localized?
In general, branding related terms and code snippets are the ones to look for,
and Sometimes some technical terms. Some examples:
**Brandings:** Lighthouse, GitHub, DevTools, Chrome Data Saver, Safari,
BlackBerry Z30, Kindle Fire HDX, Pixel 2, Microsoft Lumia 550
**Code snippets:** localhost:9229, console.clear(), --memlog=all, url:a.com
**Technical terms:** DOM, DIV, aria...
+8
View File
@@ -0,0 +1,8 @@
# Chromium DevTools Cookbook
[logo]: https://github.com/ChromeDevTools/devtools-logo/raw/master/logos/png/devtools-circle-48.png
[home]: README.md
[devtools]: ../README.md
* [Chromium DevTools Cookbook][home]
* [Chromium DevTools Documentation][devtools]
+60
View File
@@ -0,0 +1,60 @@
# Release Management
## Merges and Cherry-Picks
The documentation on cherry-picks and merges (including backmerges and
backports) can be found in the
[Chromium DevTools Contribution Guidelines](../contributing/changes.md#Merges-and-cherry-picks).
## Versioning
There is no explicit versioning being done. At the time of writing no compelling
use case was found that would require version numbers. Commits are identified by
their commit hash, which should suffice for the projected future.
## What happens when Chromium cuts a new Canary branch
For each Chromium release branch, we create a mirror branch with the same name
on our repo. Rough outline:
1. Chromium cuts a branch e.g. 3879
1. Bots create Chromium/3879 branch on the DevTools frontend repo
1. The end
## Handling of Beta/Stable branches
Generally speaking, beta/stable branches are the same as Canary branches. There
is a special waterfall though, that runs tests on the beta/stable branches.
When Chromium updates to a new major version we need to update the branch number
in
[infra/config](https://chromium.googlesource.com/devtools/devtools-frontend/+/refs/heads/infra/config)
branch of devtools-frontend. Specifically, in file buckets/ci.start, promote the
existing beta branch to stable section and modify beta section with the
corresponding branch number for the new Chromium milestone.
```python
generate_ci_configs(
configurations = [
...
config_section(
name="beta",
branch='refs/heads/chromium/4044',
),
config_section(
name="stable",
branch='refs/heads/chromium/3987',
),
...
```
After editing the above mentioned file run `lucicfg generate main.star` to have
the change propagated to the cfg files. Example:
[CL](https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2104476)
## Rolling/Integrating into Chromium
The
[Skia autoroller](https://skia.googlesource.com/buildbot/+/main/autoroll/README.md)
is used. The DevTools-Frontend auto-roller state can be seen and controlled
[here](https://autoroll.skia.org/r/devtools-frontend-chromium?tab=status).
+121
View File
@@ -0,0 +1,121 @@
# UMA metrics in DevTools frontend
[TOC]
It is highly recommended to use
[Visual Logging](../../front_end/ui/visual_logging/README.md) for anything
related to the DevTools front-end, and use use counters or UMA histograms for
anything related to the DevTools back-end (Chromium, Blink, and V8). In some
rare cases that require complex analysis of behavior that is not reflected in
the UI you might need to also use UMA histograms in the DevTools front-end.
(Googlers only) Generally, the histogram or action data is available in the
Timeline category of the [UMA](http://uma/) page.
* Select the channel you want to dive into.
* Select the platforms you are interested in (for us, it is Linux, MacOS,
Windows, ChromeOS and Lacros)
* Add the metric you want to see, for example the generic histogram for action
tracking, `DevTools.ActionTaken`.
## General histograms
* `DevTools.ActionTaken` is a generic histogram for tracking actions performed
via the DevTools front-end.
* `DevTools.PanelShown` counts how often a given panel or tab is shown in the
DevTools front-end.
## Histograms for the Workspaces feature
* `DevTools.ActionTaken` records `AddFileSystemToWorkspace` (*Add Filesystem
to Workspace*), `RemoveFileSystemFromWorkspace` (*Remove Filesystem from
Workspace*) and `FileSystemSourceSelected` (*Filesystem source selected*)
according to developer interactions with the *Filesystem* tab in the
*Sources* panels sidebar.
* `DevTools.Workspaces.PopulateWallClockTime` records the wall clock time in
milliseconds elapsed while populating a project folder in the workspace.
* `DevTools.SidebarPaneShown` records the `navigator-files` (*Sources -
Filesystem*) enum whenever the *Filesystem* tab is revealed in the *Sources*
panels sidebar.
## How to add UMA metrics in DevTools frontend
Decide on the metric (an
[enumerated histogram](https://chromium.googlesource.com/chromium/src/tools/+/HEAD/metrics/histograms/README.md#enum-histograms)
or an
[action](https://source.chromium.org/chromium/chromium/src/+/main:third_party/devtools-frontend/src/front_end/core/host/UserMetrics.ts;l=380)
to be logged to generic `DevTools.ActionTaken` histogram)
1. For enumerated histogram (We use this when there are multiple related states
that should be analyzed jointly. For example, we might want to know the
source of an action like where it is performed from)
1. Choose a name for the new histogram prefixed with `DevTools`, for
example, `DevTools.ColorPickerOpenedFrom`.
2. Decide on the values for the different enums you want to log, for
example, `StylesPane` and `SourcesPanel` for
`DevTools.ColorPickerOpenedFrom` histogram.
2. For actions
1. Decide on the name of the action, for example, `DeviceModeEnabled`.
### Tracking an enumerated histogram
1. Implement metric collection in devtools-frontend and create a CL. (Example
[CL](https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/3998783))
1. Add the new histogram name to the
<code>[EnumeratedHistogram](https://source.chromium.org/chromium/chromium/src/+/main:third_party/devtools-frontend/src/front_end/core/host/InspectorFrontendHostAPI.ts;l=351?q=InspectorFrontendHostAPI.ts)</code>
enum.
2. Add the same histogram name to the EnumeratedHistogram object in
<code>[devtools_compatibility.js](https://source.chromium.org/chromium/chromium/src/+/main:third_party/devtools-frontend/src/front_end/devtools_compatibility.js;l=396?q=devtools_compatibil)</code>
file.
3. Create a new function in
<code>[UserMetrics.ts](https://source.chromium.org/chromium/chromium/src/+/main:third_party/devtools-frontend/src/front_end/core/host/UserMetrics.ts;l=351)</code>
with an enum parameter that corresponds to the possible values like
<code>colorPickerOpenedFrom(type: ColorPickerOpenedFrom): void</code>
that calls
<code>InspectorFrontendHostInstance.recordEnumeratedHistogram</code>.
4. Call the new function from <code>Host.userMetrics</code> in the places
that you want to log the event.
5. Create the CL.
2. Update
[histograms.xml](https://source.corp.google.com/h/chromium/chromium/src/+/main:tools/metrics/histograms/metadata/dev/histograms.xml)
and
[enums.xml](https://source.chromium.org/chromium/chromium/src/+/main:tools/metrics/histograms/enums.xml;l=26267?q=tools%2Fmetrics%2Fhistograms%2Fenums.xml)
in the Chromium codebase.
1. Add a new enum in
[enums.xml](https://source.chromium.org/chromium/chromium/src/+/main:tools/metrics/histograms/enums.xml;l=26267?q=tools%2Fmetrics%2Fhistograms%2Fenums.xml)
with values corresponding to the values in the frontend with name
<code>DevTools&lt;HISTOGRAM_NAME></code> and make sure that enum values
1-1 map to the values you’ve defined in the frontend.
2. Add the new histogram definition in
[histograms.xml](https://source.corp.google.com/h/chromium/chromium/src/+/main:tools/metrics/histograms/metadata/dev/histograms.xml)
and set enum name to be the enum you've defined in the 1st step. Make
sure that histogram name is the same with the name you've used in the
frontend change.
3. Create the CL.
### Tracking an action
1. Implement metric collection in devtools-frontend and create a CL. (Example
[CL](https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/3998783))
1. Add the action you want to track to the
<code>[Action](https://source.chromium.org/chromium/chromium/src/+/main:third_party/devtools-frontend/src/front_end/core/host/UserMetrics.ts;l=379)</code>
enum in <code>UserMetrics.ts.</code>
2. Call <code>Host.userMetrics.actionTaken(Action.YOUR_ACTION)</code> in
the places you want to the event.
3. Create the CL.
2. Update enums in the Chromium side in
<code>[tools/metrics/histograms/enums.xml](https://source.chromium.org/chromium/chromium/src/+/main:tools/metrics/histograms/enums.xml;l=26267?q=tools%2Fmetrics%2Fhistograms%2Fenums.xml)</code>.
1. Add the new action to the <code>DevToolsAction</code> enum.
2. Create the CL.
### Metrics Dashboard
After the both CLs are landed we expect your histogram or action data to be
available in [UMA](http://uma/p/chrome/timeline_v2). For seeing them:
* Select the channel you want to dive into.
* Select the platforms you are interested in (for us, it is Linux, MacOS,
Windows, ChromeOS and Lacros)
* Add the metric you want to see: either the histogram name you’ve newly added
`DevTools.ColorPickerOpenedFrom` or the generic histogram for action
tracking, `DevTools.ActionTaken`.
+1 -100
View File
@@ -1,100 +1 @@
# Dependencies
[TOC]
## Managing dependencies
If you need to manually roll a git dependency, it's not sufficient to update the revision in the DEPS file. Instead, use
the gclient tool:
```bash
gclient setdep -r DEP@REV # for example build@afe0125ef9e10b400d9ec145aa18fca932369346
```
This will simultaneously update both the DEPS entry as well as the gitlink entry for the corresponding git submodule.
To sync dependencies from Chromium to DevTools frontend, use `scripts/deps/roll_deps.py`.
Note that this may:
- Introduce unneeded whitespace/formatting changes. Presubmit scripts (e.g. invoked via `git cl upload`) will automatically fix these locally, so just apply the changes directly to your change (e.g. with `git commit --amend`) afterwards.
- Introduce breaking changes to the devtools protocol, causing compilation failures. Unfortunately these need to be handled manually as there are some changes (e.g. removing an enum value) that cannot fail gracefully.
The following scripts run as AutoRollers, but can be manually invoked if desired:
- To roll the `HEAD` commit of DevTools frontend into Chromium, use `scripts/deps/roll_to_chromium.py`.
- To update DevTools frontend's DEPS, use `roll-dep`.
## Third-party Guidelines
When you want to integrate or use third-party content in DevTools, there are a
couple of different ways to do so. Most of the time, we have to make a
distinction between "third-party code we use as part of DevTools implementation"
and "third-party code we use to build DevTools itself, but is not included in
the product".
### Third-party code included in DevTools bundle
All third-party content that you want to ship as part of the DevTools bundle
must be included in `front_end/third_party`. The typical way to update these
packages is to download the relevant packages from [npm]. Since DevTools does
not use a `package.json` to handle its dependencies (to make it possible to
review third-party changes by legal), most packages bundles are fetched with
`wget`.
For all these packages, the [Chromium third-party guidelines] apply.
Since DevTools ships as part of the Chrome binary, bundle size
limitations apply. To make integration feasible, focus on small packages that
(preferably) have no dependencies. This will make licensing checks feasible for
Chromium reviewers and typically avoids inflating the bundle size.
### Third-party tooling packages
For all third-party packages that are used either as part of the DevTools build
process or to augment engineers workflows (for example linters), we add them to
`scripts/deps/manage_node_deps.py`. This Python script has been approved by
Chromium licensing to be used, on the basis that it enforces all packages have a
license that is compatible with a set of pre-defined licensees.
If you want to use a new package as tooling process in engineer workflows, you
can add the package to the `package.json` and run `npm run install-deps`
to check in the new contents.
Only add new license types to `LICENSES` after you received approval
from `opensource-licensing@google.com`. Their response time is typically within
24 hours, so this typically is not a big hurdle.
To avoid excessive package updates, it is typically easiest to
update all packages in `manage_node_deps.py` once a month. Since NPM packages
can have a lot of (shared) transitive dependencies, updating the packages on a
specific day increases the chances that shared dependencies are deduplicated and
thus result in smaller repository sizes.
> **WARNING:** Updating tools such as Rollup and TypeScript will cause all build cache
> output to be purged, as they are part of all DevTools modules. Whenever you are
> updating either of these tools, update these at the end of a working day to
> avoid full rebuilds for other engineers.
### Chromium third-party DEPS
Some packages related to infrastructure are maintained by Chromium infra teams.
These packages are typically uploaded to cloud storage buckets or are explicitly
mirrored to a repository on https://chromium.googlesource.com. Examples include
[GN][] (Chromium/DevTools build system) or [clang-format][] (multi-language
formatter).
The packages in `DEPS` are typically kept automatically up-to-date with
autorollers. These autorollers will periodically update packages, which
engineers can fetch with running `gclient sync`.
These `DEPS` are checked out on all bots, which includes Chromium and
DevTools-specific bots. To avoid excessive network bandwidth usage, by default
do not check out packages if they are only used in specific situations.
Only include packages that are maintained by Chromium
infrastructure teams and are used to build DevTools in `DEPS`. For packages that
are DevTools-specific, prefer adding them to `scripts/deps/manage_node_deps.py`
instead.
[npm]: https://www.npmjs.com/
[Chromium third-party guidelines]: https://chromium.googlesource.com/chromium/src/+/HEAD/docs/adding_to_third_party.md
[GN]: https://gn.googlesource.com/gn/+/master/docs/reference.md
[clang-format]: https://clang.llvm.org/docs/ClangFormat.html
This file has moved [here](./cookbook/dependencies.md).
+1 -295
View File
@@ -1,295 +1 @@
# Localization
## How to add a localizable string
When you introduce a new UI string or modify an existing one that will be displayed to the users, or remove a string that is localized, follow these steps so that it can be localized.
**Table of Contents**
- [Adding a string](#adding-a-string)
- [Modifying a string](#modifying-a-string)
- [Removing a string](#removing-a-string)
### Adding a string
Before proceeding, make sure you know the different [localization APIs](#what-are-the-l10n-apis) and know which one you should use.
Code example:
```javascript
import * as i18n from '../i18n/i18n.js';
// at the top of example.js file, after import statements
const UIStrings = {
/**
* @description A string that is already added
*/
alreadyAddedString: 'Someone already created a "UIStrings = {}" and added this string',
/**
* @description This is an example description for my new string
*/
addThisString: 'The new string I want to add',
/**
* @description This is an example description for my new string with placeholder
* @example {example for placeholder} PH1
*/
addAnotherString: 'Another new string I want to add, with {PH1}',
};
const str_ = i18n.i18n.registerUIStrings('example.js', UIStrings);
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
```
```javascript
// in example.js file, where you want to call the string
const message1 = i18nString(UIStrings.addThisString);
console.log(message1); // The new string I want to add
const message2 = i18nString(UIStrings.addAnotherString, {PH1: 'a placeholder'});
console.log(message2); // Another new string I want to add, with a placeholder
```
1. If there is already `UIStrings = {}` declared in the file, add your string to it.
If there isn't `UIStrings = {}` in the file, create one and add your string, also register the new UIStrings into the `en-US.json` by adding:
1. `const str_ = i18n.i18n.registerUIStrings({the current fileName.js, relative to front_end}, UIStrings);`
1. `const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);`
2. Add description and examples for placeholder(if any):
1. To specify the description, use `@description …`
`@description This is an example description for my new string`
2. To specify an example for placeholder, use `@example {…} …`
`@example {example for placeholder} PH1`
3. To distinguish messages with the same content, use `@meaning …`
`@meaning This is an example meaning to differentiate this message from the other message with same content`
3. Make sure your string is localizable:
1. Do not assume word order by using concatenation. Use the whole string.
❌
```javascript
'Add' + 'breakpoint'
```
✔️
```javascript
'Add breakpoint'
```
or
❌
```javascript
let description = 'first part'
if (condition)
description += ' second part'
```
✔️
```javascript
let description
if (condition)
description = 'first part second part'
else
description = 'first part'
```
2. Use placeholder over concatenation. This is so that the translators can adjust variable order based on what works in another language. For example:
❌
```javascript
'Check ' + title + ' for more information.'
```
✔️
```javascript
'Check {PH1} for more information.', {PH1: title}
```
3. If your string contains <b>leading or trailing white space</b>, it's usually an indication that it's half of a sentence. This decreases localizability as it's essentially concatenating. Modify it so that it doesn't contain leading or trailing white space anymore if you can.
4. <b>Backticks</b> are only used for the text that should not be localized. They cannot be escaped as part of the string. Check if there are something should not be localized (see [locked terms](#phrases-that-are-fully-locked) for more details).
❌ Not localized
- Numbers: 1, 1.23, 1.2e3, etc.
- Application data: error codes, enums, database names, rgba, urls, etc.
✔️ Can be localized
- Words and sentences
- Punctuation
- Units of measurement: kb/s, mph, etc.
4. The following commands would add the new strings to `en-US.json`:
- `git cl presubmit --upload`, or
- `node third_party/i18n/collect-strings.js` under the DevTools src folder
5. Strings containing possible plurals have a special format in ICU. This is because plurals work quite differently in other languages, e.g. special forms for two or three items.
❌
```javascript
if (count === 1) {
str = '1 breakpoint';
} else {
str = '{n} breakpoints', {n: count};
}
```
✔️
```javascript
'{n, plural, =1 {# breakpoint} other {# breakpoints}}', {n: count};
```
- '#' is replaced with the value of `n`
- 'n' is a naming convention, but any name can be used
- Nesting placeholders inside of plurals is allowed
- Put the entire string within the plural switch, e.g. `{# breakpoints were found}`, not `{# breakpoints} were found`
- Always provide the `=1` and the `other` case, even if they are the same for English.
### Modifying a string
1. Update the string you want to modify in `UIStrings`
2. Update the description and placeholders of the string if necessary
### Removing a string
1. Remove your string and the metadata from `UIStrings`
## What are the l10n APIs?
Access localized strings in the DevTools frontend using the following localization calls.
### i18nString
The basic API to make a string (with or without placeholder) localizable.
The first argument is the string reference in `UIStrings`
The second argument is an object for placeholders (if any)
```javascript
// at the top of example.js file, after import statements
const UIStrings = {
/**
* @description This is an example description for my new string with placeholder
* @example {example for placeholder} PH1
* @example {example 2 for placeholder 2} PH2
*/
addAnotherString: 'Another new string I want to add, with {PH1} and {PH2}',
};
message = i18nString(UIStrings.addAnotherString, {PH1: 'a placeholder', PH2: 'another placeholder'});
```
### i18nLazyString
The `i18nString` function returns the translated string, with placeholders resolved. To do this, it needs access to the translated strings for the user's locale, which are not available until after DevTools has finished starting up.
Calls to `i18nString` in the module scope will therefore fail when the module is imported.
```javascript
// Fails because i18nString runs at module-import time.
Common.Settings.registerSettingExtension({
category: Common.Settings.SettingCategory.CONSOLE,
title: i18nString(UIStrings.groupSimilarMessagesInConsole),
...
function notTopLevel() {
console.log(extension.title);
}
```
`i18nLazyString` fixes this problem by providing the same API, but returning a closure that returns a `LocalizedString`.
It can be used in top-level calls; just make sure use-sites know it's a function now.
```javascript
// Works because i18nLazyString defers the loading of the translated string until later.
Common.Settings.registerSettingExtension({
category: Common.Settings.SettingCategory.CONSOLE,
title: i18nLazyString(UIStrings.groupSimilarMessagesInConsole),
...
// Note we need to call title() now.
function notTopLevel() {
console.log(extension.title());
}
```
### i18n.i18n.getFormatLocalizedString
This call returns a **span element**, not a string. It is used when you want to construct a DOM element with a localizable string, or localizable content that contains some other DOM element.
```javascript
// Create the string in UIString
/**
*@description Message in Coverage View of the Coverage tab
*@example {reload button icon} PH1
*@example {record button icon} PH2
*/
clickTheRecordButtonSToStart: 'Click the reload button {PH1} to reload or record button {PH2} start capturing coverage.',
// Element with localizable content containing two DOM elements that are buttons
const reloadButton = UI.createInlineButton(UI.Toolbar.createActionButtonForId('coverage.start-with-reload'));
const recordButton = UI.createInlineButton(UI.Toolbar.createActionButton(this._toggleRecordAction));
message = i18n.i18n.getFormatLocalizedString(str_, UIStrings.clickTheReloadButtonSToReloadAnd, {PH1: reloadButton, PH2:recordButton });
```
### i18n.i18n.lockedString
This call is a named cast. Use it in places where a localized string is expected but the
term you want to use does not require translation. Instead of locking the whole phrase or using
a placeholder-only phrase, use `lockedString`.
```javascript
someFunctionRequiringALocalizedString(i18n.i18n.lockedString('HTTP'));
```
## How to write good descriptions
Good descriptions can improve localizability by providing more context to the translators.
There are some details that are very important to have in other languages!
**Good description**:
```javascript
const UIStrings = {
/**
* @description Tooltip text that appears when hovering over the 'Focusable' attribute name under the Computed Properties section in the Accessibility pane of the Elements pane.
*/
computedPropertyTooltip: 'If true, this element can receive focus.',
};
```
**Bad description**:
```javascript
const UIStrings = {
/**
* @description Elements pane 'Focusable' tooltip.
*/
computedPropertyTooltip: 'If true, this element can receive focus.',
};
```
### What information should I provide in the message description?
- The type of UI element where the text is displayed. Is it regular text, a label, button text, a tooltip, a link, or an accessible label? Button text is often imperative i.e. a command to do something, which is important to know in some languages.
- _When_: What triggers the string and/or what is the result? What page or text comes before and after? e.g. "Status text while waiting for X", "Shown when the audit is finished and X error was encountered".
- What do the placeholders stand for? Placeholder examples are sent to translators, but extra information in the description will help too. e.g. "Total time in ms that the profile took to complete", "The CSS property name that is being edited"
- Is this a verb or a noun? Many words in English can be both, e.g. 'request', 'address', 'change', 'display', 'increase'. Particularly if the string is short, this can be hard to guess. If it's an adjective, what does it refer to? This is important for inflection in some languages, where the ending of the adjective must change for gender or case.
- Explain or name any complex terms, e.g. "Trust Tokens are a web API - https://web.dev/trust-tokens/"
- Where is the text located? e.g. A table header in the Sources panel, a context-menu item in the Network panel. Many strings in the code base have _only_ the location, which is not the most important context.
## How to prevent a term being localized
Any text within the backticks will not be translated.
For example, if the 'robots.txt' in string 'Requesting for robots.txt ...' should not be translated:
```javascript
// in example.js file
import * as i18n from '../i18n/i18n.js';
const UIStrings = {
/**
* @description Example description. Note: "robots.txt" is a canonical filename and should not be translated.
*/
requestMessage: 'Requesting for `robots.txt` ...',
};
const str_ = i18n.i18n.registerUIStrings('example.js', UIStrings);
const message = i18nString(UIStrings.requestMessage);
```
The string will rendered with robots.txt not translated and without the backticks around it
```javascript
'Requesting for robots.txt ...'
```
### Phrases that are fully locked
Any text that is fully locked should not go into the UIStrings object. To make your intention clear
or to make TypeScript happy, there are two methods `i18n.i18n.lockedString` and `i18n.i18n.lockedLazyString`
that can be used instead of having fully locked phrases via `i18nString`.
### What should not be localized?
In general, branding related terms and code snippets are the ones to look for, and Sometimes some technical terms. Some examples:
**Brandings:**
Lighthouse, GitHub, DevTools, Chrome Data Saver, Safari, BlackBerry Z30, Kindle Fire HDX, Pixel 2, Microsoft Lumia 550
**Code snippets:**
localhost:9229, console.clear(), --memlog=all, url:a.com
**Technical terms:**
DOM, DIV, aria...
This file has moved [here](./cookbook/localization.md).
+1 -53
View File
@@ -1,53 +1 @@
# Release Management
## Merges and Cherry-Picks
The documentation on cherry-picks and merges (including backmerges and backports) can be found in [`contributing_changes.md`](contributing_changes.md#merges-and-cherry_picks).
## Versioning
There is no explicit versioning being done. At the time of writing no compelling
use case was found that would require version numbers. Commits are identified by their commit hash, which should suffice for the projected future.
## What happens when Chromium cuts a new Canary branch
For each Chromium release branch, we create a mirror branch with the same name on our repo. Rough
outline:
1. Chromium cuts a branch e.g. 3879
1. Bots create Chromium/3879 branch on the DevTools frontend repo
1. The end
## Handling of Beta/Stable branches
Generally speaking, beta/stable branches are the same as Canary branches. There
is a special waterfall though, that runs tests on the beta/stable branches.
When Chromium updates to a new major version we need to update the branch number
in [infra/config](https://chromium.googlesource.com/devtools/devtools-frontend/+/refs/heads/infra/config)
branch of devtools-frontend. Specifically, in file buckets/ci.start, promote
the existing beta branch to stable section and modify beta section with the
corresponding branch number for the new Chromium milestone.
```python
generate_ci_configs(
configurations = [
...
config_section(
name="beta",
branch='refs/heads/chromium/4044',
),
config_section(
name="stable",
branch='refs/heads/chromium/3987',
),
...
```
After editing the above mentioned file run `lucicfg generate main.star` to have the change propagated to the cfg files.
Example: [CL](https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2104476)
## Rolling/Integrating into Chromium
The [Skia
autoroller](https://skia.googlesource.com/buildbot/+/main/autoroll/README.md) is used. The DevTools-Frontend auto-roller state can be seen and controlled [here](https://autoroll.skia.org/r/devtools-frontend-chromium?tab=status).
This file has moved [here](./cookbook/release_management.md).
-23
View File
@@ -1,23 +0,0 @@
# UMA metrics in DevTools frontend
(Googlers only) Generally, the histogram or action data is available in the Timeline category of the [UMA](http://uma/) page.
* Select the channel you want to dive into.
* Select the platforms you are interested in (for us, it is Linux, MacOS, Windows, ChromeOS and Lacros)
* Add the metric you want to see, for example the generic histogram for action tracking, `DevTools.ActionTaken`.
## General histograms
* `DevTools.ActionTaken` is a generic histogram for tracking actions performed via the DevTools front-end.
* `DevTools.PanelShown` counts how often a given panel or tab is shown in the DevTools front-end.
## Histograms for the Workspaces feature
* `DevTools.ActionTaken` records `AddFileSystemToWorkspace` (_Add Filesystem to Workspace_), `RemoveFileSystemFromWorkspace`
(_Remove Filesystem from Workspace_) and `FileSystemSourceSelected` (_Filesystem source selected_) according to developer
interactions with the _Filesystem_ tab in the _Sources_ panels sidebar.
* `DevTools.Workspaces.PopulateWallClockTime` records the wall clock time in milliseconds elapsed while populating a project
folder in the workspace.
* `DevTools.SidebarPaneShown` records the `navigator-files` (_Sources - Filesystem_) enum whenever the _Filesystem_ tab is
revealed in the _Sources_ panels sidebar.