[Web Inspector] Port Web Inspector Style Guide from Trac#147
[Web Inspector] Port Web Inspector Style Guide from Trac#147burg wants to merge 1 commit intoWebKit:mainfrom
Conversation
The Web Inspector coding style guide lived on trac.webkit.org (now defunct) and was completely inaccessible to new contributors. Port and modernize it into docs/Deep Dive/Web Inspector/StyleGuide.md. Covers: - Formatting (indentation, strings, braces, trailing commas, semicolons) - Variable declarations (let vs const -- WI uses let-by-default) - Naming conventions (classes, properties, event handlers, localization) - Class structure and member ordering with section comments - Architecture (Manager/Model/View separation, protocol firewall) - View lifecycle (initialLayout, layout, attached/detached) - Event system (declaring, dispatching, listening, one-shot, await) - Collections and iteration patterns - Arrow function conventions - Async patterns and promise gotchas - Assertions - CSS conventions (z-index, theming, class names) The guide is structured with a Quick Reference of the most common review issues at the top, and detailed sections below. Rules were validated against the current codebase -- outdated Trac rules were dropped or updated. Resolves WebKit#144
| 3. **`_handle` prefix for event handlers**, not `on`. The `on` prefix is not used. | ||
| 4. **`let` is the default**, even if the variable is never reassigned. `const` is only for named constant parameters and true constants. | ||
| 5. **Spell things out.** `identifier` not `id`, `element` not `el`. Abbreviations are avoided. | ||
| 3. **Forgetting `this` in `addEventListener`.** The three-argument form is required. Omitting `this` triggers a `console.assert` in debug builds. |
There was a problem hiding this comment.
This should be 6., and I don't quite understand the rule—this rule should be stated positively to be parallel to the other rules, like "Use this in addEventListener" if the rule is to not forget it. Although I don't get what this rule is saying; is it suggesting we always write this.addEventListener(event, handler) rather than addEventListener(event, handler)? In that case I think we shouldn't call the this. in the front one of the arguments
There was a problem hiding this comment.
Ah, I see that this rule refers to the Listening and Dispatching section later
|
|
||
| ### Semicolons | ||
|
|
||
| Always use semicolons. No ASI reliance. |
There was a problem hiding this comment.
| Always use semicolons. No ASI reliance. | |
| Always use semicolons. No Automatic Semicolon Insertion reliance. |
| **Named functions and class methods** -- opening brace on the **next line**: | ||
|
|
||
| ```js | ||
| // From Base/Object.js |
There was a problem hiding this comment.
I think given not all of these example code snippets include a file source, perhaps we should be consistent and just not include it here. The contents of the snippet and whether it's a good or bad example should be more important to focus on. Omitting the source also protects us against moving or editing that source later
Same applies to the snippet in the Trailing Commas section
|
|
||
| The rules most likely to come up in code review: | ||
|
|
||
| 1. **Next-line braces for functions and methods.** Same-line braces only for `if`/`for`/`while`/`switch`. |
There was a problem hiding this comment.
it's really only for methods and top-level functions
nested functions (including arrow functions) are fine to have on the same line such as
class Foo {
bar()
{
function nested() {
/* ... */
}
this.baz(() => {
/* ... */
});
}
}| The rules most likely to come up in code review: | ||
|
|
||
| 1. **Next-line braces for functions and methods.** Same-line braces only for `if`/`for`/`while`/`switch`. | ||
| 2. **Views never call protocol agents.** Only Managers (`Controllers/`) talk to the backend. Views talk to Managers. |
There was a problem hiding this comment.
model objects are also allowed to call into the protocol
| 3. **`_handle` prefix for event handlers**, not `on`. The `on` prefix is not used. | ||
| 4. **`let` is the default**, even if the variable is never reassigned. `const` is only for named constant parameters and true constants. | ||
| 5. **Spell things out.** `identifier` not `id`, `element` not `el`. Abbreviations are avoided. | ||
| 3. **Forgetting `this` in `addEventListener`.** The three-argument form is required. Omitting `this` triggers a `console.assert` in debug builds. |
There was a problem hiding this comment.
i think it's worth clarifying this is only for stuff related to WI.Object
i.e. EventTarget.prototype.addEventListener does not have a thisObject 3rd parameter
|
|
||
| ### Trailing Commas | ||
|
|
||
| Use trailing commas in all multi-line object literals: |
There was a problem hiding this comment.
also multi-line array literals too
|
|
||
| ### Classes | ||
|
|
||
| All classes live on the `WI` namespace. The class expression name mirrors the property name: |
There was a problem hiding this comment.
we do have a few classes that dont live in this namespace, but they're either super generic utilities (e.g. MultiMap, Debouncer, etc.) or only exist in Worker (e.g. HTMLParser, JSFormatter, etc.)
|
|
||
| The section order is: constructor, `// Static`, `// Target`, `// Public`, `// Protected`, `// Private`, then observer sections (e.g., `// DOMObserver`). | ||
|
|
||
| When overriding a superclass method, annotate the section: `// Protected (ClassName)`. |
There was a problem hiding this comment.
i think we should also say that super should always be invoked unless there's a really good reason not to in that case
| }; | ||
| ``` | ||
|
|
||
| Some enumerations use `Symbol()` for non-serializable values: |
There was a problem hiding this comment.
i think we dont actually want to do this anymore as i dont think creating a Symbol is as cheap as just having a raw string literal
the primary benefit of Symbol is that the actual value is unique (e.g. Symbol("test") !== Symbol("test")) which is not really something we actually care about for these kinds of values
typically we only use Symbol as a way of creating a unique identifier in a loop (e.g. promiseIdentifier in Debouncer) or as an expando property on objects (e.g. WI.TabBrowser.NeedsResizeLayoutSymbol)
|
|
||
| ### Listening and Dispatching | ||
|
|
||
| Use the three-argument `addEventListener(eventType, listener, thisObject)`. Always pass `this` as the third argument -- it enables proper cleanup and `this`-binding: |
There was a problem hiding this comment.
ditto above about clarifying that this is only for WI.Object
| WI.Target.singleFireEventListener(WI.Target.Event.Removed, this._targetRemoved, this); | ||
|
|
||
| // Await as a Promise | ||
| await WI.DOMManager.awaitEvent(WI.DOMManager.Event.DocumentUpdated); |
There was a problem hiding this comment.
you also have to provide a thisObject to awaitEvent
| // Do | ||
| target.DOMAgent.getDocument() | ||
| .then((result) => { /* ... */ }) | ||
| .catch((error) => { WI.reportInternalError(error); }); |
There was a problem hiding this comment.
generally speaking we usually only have single-line arrow functions if we're using the return value, so for something like this we've usually suggested multiple lines
target.DOMAgent.getDocument()
.then((result) => {
/* ... */
})
.catch((error) => {
WI.reportInternalError(error);
});
The Web Inspector coding style guide lived on trac.webkit.org (now defunct) and was completely inaccessible to new contributors. Port and modernize it into docs/Deep Dive/Web Inspector/StyleGuide.md.
Covers:
The guide is structured with a Quick Reference of the most common review issues at the top, and detailed sections below. Rules were validated against the current codebase -- outdated Trac rules were dropped or updated.
Resolves #144