[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 <[email protected]>
Reviewed-by: Simon Zünd <[email protected]>
Commit-Queue: Simon Zünd <[email protected]>
diff --git a/docs/README.md b/docs/README.md
index 67da8df..6ca01de 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -27,12 +27,8 @@
* [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
diff --git a/docs/add_uma_metrics.md b/docs/add_uma_metrics.md
deleted file mode 100644
index e1d9a1a..0000000
--- a/docs/add_uma_metrics.md
+++ /dev/null
@@ -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<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`.
diff --git a/docs/cookbook/README.md b/docs/cookbook/README.md
new file mode 100644
index 0000000..9098690
--- /dev/null
+++ b/docs/cookbook/README.md
@@ -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)
diff --git a/docs/cookbook/create_new_issues.md b/docs/cookbook/create_new_issues.md
new file mode 100644
index 0000000..535d66a
--- /dev/null
+++ b/docs/cookbook/create_new_issues.md
@@ -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:[email protected]) (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:[email protected]) 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:[email protected]) 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:[email protected]) 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.
diff --git a/docs/cookbook/dependencies.md b/docs/cookbook/dependencies.md
new file mode 100644
index 0000000..7304e8d
--- /dev/null
+++ b/docs/cookbook/dependencies.md
@@ -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
+`[email protected]`. 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
diff --git a/docs/cookbook/localization.md b/docs/cookbook/localization.md
new file mode 100644
index 0000000..8672688
--- /dev/null
+++ b/docs/cookbook/localization.md
@@ -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...
diff --git a/docs/cookbook/navbar.md b/docs/cookbook/navbar.md
new file mode 100644
index 0000000..410901d
--- /dev/null
+++ b/docs/cookbook/navbar.md
@@ -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]
diff --git a/docs/cookbook/release_management.md b/docs/cookbook/release_management.md
new file mode 100644
index 0000000..554a6d2
--- /dev/null
+++ b/docs/cookbook/release_management.md
@@ -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).
diff --git a/docs/cookbook/uma_metrics.md b/docs/cookbook/uma_metrics.md
new file mode 100644
index 0000000..909df3a0
--- /dev/null
+++ b/docs/cookbook/uma_metrics.md
@@ -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<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`.
diff --git a/docs/dependencies.md b/docs/dependencies.md
index 823d328..8e6776d 100644
--- a/docs/dependencies.md
+++ b/docs/dependencies.md
@@ -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 `[email protected]`. 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).
diff --git a/docs/l10n.md b/docs/l10n.md
index b301496..fe4a29c 100644
--- a/docs/l10n.md
+++ b/docs/l10n.md
@@ -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).
diff --git a/docs/release_management.md b/docs/release_management.md
index 2b5e3e9..4d8182e 100644
--- a/docs/release_management.md
+++ b/docs/release_management.md
@@ -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).
diff --git a/docs/uma_metrics.md b/docs/uma_metrics.md
deleted file mode 100644
index 44ab9d8..0000000
--- a/docs/uma_metrics.md
+++ /dev/null
@@ -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.
-