AX: AXIsolatedTree::updateChildren sometimes fails to update isolated subtrees when...
[WebKit-https.git] / Introduction.md
1 #  Introduction to WebKit
2
3 ## What is WebKit?
4
5 [WebKit](https://webkit.org/) is an open-source Web browser engine.
6 It’s a framework in macOS and iOS, and used by many first party and third party applications including Safari, Mail, Notes, Books, News, and App Store.
7
8 The WebKit codebase is mostly written in C++ with bits of C and assembly, primarily in JavaScriptCore, and some Objective-C to integrate with Cocoa platforms.
9
10 It primarily consists of the following components, each inside its own directory in [Source](https://github.com/WebKit/WebKit/tree/main/Source):
11
12 * **bmalloc** - WebKit’s malloc implementation as a bump pointer allocator. It provides an important security feature, called IsoHeap,
13     which segregates each type of object into its own page to prevent type confusion attacks upon use-after-free.
14 * **WTF** - Stands for Web Template Framework. WebKit’s template library.
15     The rest of the WebKit codebase is built using this template library in addition to, and often in place of, similar class templates in the C++ standard library.
16     It contains common container classes such as Vector, HashMap (unordered), HashSet, and smart pointer types such as Ref, RefPtr, and WeakPtr used throughout the rest of WebKit.
17 * **JavaScriptCore** - WebKit’s JavaScript engine; often abbreviated as JSC.
18     JSC parses JavaScript and generates byte code, which is then executed by one of the following four tiers.
19     Many tiers are needed to balance between compilation time and execution time.
20     Also see Phil's blog post about [Speculation in JavaScriptCore](https://webkit.org/blog/10308/speculation-in-javascriptcore/).
21     * **Interpreter** - This tier reads and executes instructions in byte code in C++.
22     * **Baseline JIT** - The first Just In Time compiler tier serves as the profiler as well as a significant speed up from the interpreter.
23     * **DFG JIT** - Data Flow Graph Just In Time compiler uses the data flow analysis to generate optimized machine code.
24     * **FTL JIT** - Faster than Light Just In Time compiler which uses [B3 backend](https://webkit.org/blog/5852/introducing-the-b3-jit-compiler/).
25         It’s the fastest tier of JSC.
26     JavaScriptCode also implements JavaScriptCore API for macOS and iOS applications.
27 * **WebCore** - The largest component of WebKit, this layer implements most of the Web APIs and their behaviors.
28     Most importantly, this component implements HTML, XML, and CSS parsers and implements HTML, SVG, and MathML elements as well as CSS.
29     It also implements [CSS JIT](https://webkit.org/blog/3271/webkit-css-selector-jit-compiler/), the only Just In Time compiler for CSS in existence.
30     It works with a few tree data structures:
31     * **Document Object Model** - This is the tree data structure we create from parsing HTML.
32     * **Render Tree** - This tree represents the visual representation of each element in DOM tree computed from CSS and also stores the geometric layout information of each element.
33 * **WebCore/PAL and WebCore/platform** - Whilst technically a part of WebCore, this is a platform abstraction layer for WebCore
34     so that the rest of WebCore code can remain platform independent / agnostic across all the platforms WebKit can run on: macOS, iOS, Windows, Linux, etc...
35     Historically, most of this code resided in WebCore/platform.
36     There is an ongoing multi-year project to slowly migrate code to PAL as we remove the reverse dependencies to WebCore.
37 * **WebKitLegacy** (a.k.a. WebKit1) - This layer interfaces WebCore with the rest of operating systems in single process and implements WebView on macOS and UIWebView on iOS.
38 * **WebKit** (a.k.a. WebKit2) - This layer implements the multi-process architecture of WebKit, and implements WKWebView on macOS and iOS.
39     WebKit’s multi-process architecture consists of the following processes:
40     * **UI process** - This is the application process. e.g. Safari and Mail
41     * **WebContent process** - This process loads & runs code loaded from websites.
42         Each tab in Safari typically has its own WebContent process.
43         This is important to keep each tab responsive and protect websites from one another.
44     * **Networking process** - This process is responsible for handling network requests as well as storage management.
45         All WebContent processes in a single session (default vs. private browsing) share a single networking session in the networking process.
46 * **WebInspector / WebDriver** - WebKit’s developer tool & automation tool for Web developers.
47
48 ## Contributing to WebKit
49
50 There are many ways to get involved and contribute to the WebKit Project.
51 Filing a new bug, fixing a bug, or adding a new feature.
52
53 There are three different kinds of contributors in the WebKit project.
54
55  * Contributor - This category encompasses everyone. Anyone who files a bug or contributes a code change or reviews a code change is considered as a contributor
56  * Committer - A committer is someone who has write access to [WebKit's subversion repository](https://svn.webkit.org/repository/webkit/).
57  * Reviewer - A reviewer is someone who has the right to review and approve code changes other contributors proposed.
58
59 See [Commit and Review Policy](https://webkit.org/commit-and-review-policy/) for more details on how to become a committer or a reviewer.
60
61 ### Staying in Touch
62
63 Before getting in touch with WebKit developers using any of the avenues below, make sure that you have checked our page on how to ask [questions about WebKit](https://webkit.org/asking-questions/).
64
65 You can find WebKit developers, testers, and other interested parties on the [#WebKit Slack workspace](https://webkit.slack.com/).
66 [Join the WebKit slack](https://join.slack.com/t/webkit/shared_invite/enQtOTU3NzQ3NTAzNjA0LTc5NmZlZWIwN2MxN2VjODVjNzEyZjBkOWQ4NTM3OTk0ZTc0ZGRjY2MyYmY2MWY1N2IzNTI2MTIwOGVjNzVhMWE),
67 and stay in touch.
68
69 ## Bug tracking in WebKit
70
71 [bugs.webkit.org](https://bugs.webkit.org/) hosted is the primary bug tracking tool we use.
72 When making a code change, we post a code change (patch) on this website.
73
74 ### Filing a bug and editing bugs
75
76 To [file a new WebKit bug](https://bugs.webkit.org/enter_bug.cgi), see [reporting bugs](https://webkit.org/reporting-bugs/).
77
78 To edit an existing bug, you may need [editbug-bits](https://webkit.org/bugzilla-bits/).
79
80 ### Code Reviews in bugs.webkit.org
81
82 We also use [bugs.webkit.org](https://bugs.webkit.org/) to upload & review code changes to WebKit.
83 You can post a code change with `Tools/Scripts/webkit-patch upload`.
84 Note that the `webkit-patch` script only looks for changes below current directory,
85 so generally you should change the current directory to the top-level directory of a WebKit first.
86
87 When a patch is posted on [bugs.webkit.org](https://bugs.webkit.org/) requesting a formal code review (r? flag is set),
88 The Early Warning System (a.k.a. EWS) will automatically build and run tests against your code change.
89 This allows contributors to find build or test failures before committing code changes to the WebKit’s primary Subversion repository.
90
91 Once a patch is approved by a reviewer (r+ flag is set),
92 then the patch can be either committed directly into the Subversion repository by a WebKit committer, 
93 who has write access to the Subversion repository,
94 or via the commit queue which can be requested by setting cq? flag and approved by any WebKit committer by setting cq+.
95
96 The Subversion commit message should be created by `Tools/Scripts/commit-log-editor` based on the change log entries.
97 `Tools/Scripts/webkit-patch land` does this automatically.
98
99 ### Security Bugs in bugs.webkit.org
100
101 Security bugs have their own components in [bugs.webkit.org](https://bugs.webkit.org/).
102 We’re also working on a new policy to delay publishing tests for security fixes until after the fixes have been widely deployed.
103
104 _***Do not post a patch or describe a security bug in a bug that is not in security component of bugs.webkit.org.***_
105
106 ## Getting started with WebKit
107
108 ### Getting Code
109
110 See [Getting the Code](https://github.com/WebKit/webkit/blob/master/ReadMe.md#getting-the-code)
111
112 ### Adding Tools to PATH
113
114 For convenience, you can add `Tools/Scripts/` to your path as follows in `~/.zshrc` like so:
115
116 ```sh
117 export PATH=$PATH:/Volumes/Data/webkit/Tools/Scripts/
118 ```
119
120 where `/Volumes/Data/webkit` is the path to a WebKit checkout.
121
122 This will allow you to run various tools you by name instead of typing the full path of the script.
123
124 ### Updating checkouts
125
126 There is a script to update a WebKit checkout: `Tools/Scripts/update-webkit`. This script will automatically merge change logs mentioned below.
127
128 ### Building WebKit
129
130 [See Building WebKit](https://github.com/WebKit/webkit/blob/master/ReadMe.md#building-webkit)
131
132 ### Fixing mysterious build or runtime errors after Xcode upgrades
133
134 If you see mysterious build failures or if you’ve switched to a new version of
135 macOS or Xcode, delete the `WebKitBuild` directory.
136 `make clean` may not delete all the relevant files,
137 and building after doing that without deleting the `WebKitBuild` directory may result in mysterious build or dyld errors.
138
139 ### Building with Address Sanitizer to investigate memory corruption bugs
140
141 To build [Address Sanitizer](https://en.wikipedia.org/wiki/AddressSanitizer) or ASan builds to analyze security bugs,
142 run `Tools/Scripts/set-webkit-configuration --asan --release`.
143 This will enable ASan build. If want to attach a debugger, you can also specify `--debug` instead of `--release`.
144 Once you don’t need to build or run ASan anymore, you can specify `--no-asan` in place of `--asan` to disable ASan.
145 Note that this configuration is saved by creating a file called Asan in the WebKitBuild directory,
146 so if you are trying to do a clean Asan build by deleting the build directory you need to rerun this command.
147
148 ### Using Xcode
149
150 You can also use Xcode to build & debug WebKit. Open `WebKit.xcworkspace` at the top level directory.
151
152 In order to make Xcode use build files built by `make` command above,
153 go to File > Workspace Settings... > Advanced... > Custom > Relative to Workspace
154 and adjust the relative paths of Products and Intermediates to point to `WebKitBuild` directory.
155 ![Screenshot of Xcode Workspace Settings](resources/xcode-workspace-settings.png)
156 ![Screenshot of Xcode Workspace Settings - Advanced Build Location](resources/xcode-workspace-build-location.png)
157 Note that debugging WebCore code typically requires attaching to the relevant WebContent process,
158 not the application process, which is mostly running code in [Source/WebKit/UIProcess](https://github.com/WebKit/WebKit/tree/main/Source/WebKit/UIProcess).
159 Depending on what you’re debugging, you’d have to attach & debug different processes in the coalition.
160
161 You may find it useful to use the debug helpers under `Tools/lldb/lldb_webkit.py`.
162 This can be added to `~/.lldbinit` for automatic loading into LLDB on launch by adding the line `command script import {Path to WebKit}/Tools/lldb/lldb_webkit.py`.
163 For more details, see the Wiki article on [lldb formatters](https://trac.webkit.org/wiki/lldb%20formatters).
164
165 When debugging a debug build in LLDB, there are also a few functions that can be called on objects that will dump debugging info.
166
167 * RenderObject
168     * showNodeTree()
169     * showLineTree()
170     * showRenderTree()
171 * Node
172     * showTree()
173     * showNodePath()
174     * showTreeForThis()
175     * showNodePathForThis()
176
177 ## Correctness Testing in WebKit
178
179 WebKit is really big on test driven development, we have many types of tests.
180
181 * **JavaScript tests** - Resides in top-level [JSTests](https://github.com/WebKit/WebKit/tree/main/JSTests) directory.
182     This is the primary method of testing JavaScriptCore. Use `Tools/Scripts/run-javascriptcore-tests` to run these tests.
183 * **Layout tests** - Resides in top-level [LayoutTests](https://github.com/WebKit/WebKit/tree/main/LayoutTests) directory.
184     This is the primary method of testing WebCore.
185     If you’re making code changes to WebCore, you typically run these tests. Use `Tools/Scripts/run-webkit-tests` to run these.
186     Pass `-1` to run tests using WebKitLegacy (a.k.a. WebKit1).
187     [WebKitTestRunner](https://github.com/WebKit/WebKit/tree/main/Tools/WebKitTestRunner) is used to run these tests for WebKit2,
188     and [DumpRenderTree](https://github.com/WebKit/WebKit/tree/main/Tools/DumpRenderTree) is used to these tests for WebKit1.
189     There are a few styles of layout tests but all of them have a test file and expected result (ends with -expected.txt),
190     and the test passes if the test file’s output matches that of the expected result.
191 * **API tests** - Reside in [Tools/TestWebKitAPI](https://github.com/WebKit/WebKit/tree/main/Tools/TestWebKitAPI),
192     these are [GTests](https://en.wikipedia.org/wiki/Google_Test) that test APIs exposed by JavaScriptCore,
193     WebKitLegacy, and WebKit layers as well as unit tests for selected WTF classes.
194     WebKit does not use [XCTests](https://developer.apple.com/documentation/xctest).
195     Use `Tools/Scripts/run-api-tests` to run these tests.
196     Because these API tests are sequentially, it’s preferable to write layout tests when possible.
197 * **Bindings tests** - Reside in [Source/WebCore/bindings/scripts/test](https://github.com/WebKit/WebKit/tree/main/Source/WebCore/bindings/scripts/test),
198     these are tests for WebCore’s binding code generator.
199     Use `Tools/Scripts/run-bindings-tests` to run these tests.
200 * **webkitpy tests** - Tests for WebKit’s various Python scripts in [Tools/Scripts/webkitpy](https://github.com/WebKit/WebKit/tree/main/Tools/Scripts/webkitpy).
201     Use `Tools/Scripts/test-webkitpy` to run these tests.
202 * **webkitperl tests** - Tests for WebKit’s various Perl scripts in [Tools/Scripts/webkitperl](https://github.com/WebKit/WebKit/tree/main/Tools/Scripts/webkitperl).
203     Use `Tools/Scripts/test-webkitperl` to run these tests.
204
205 ## Performance Testing in WebKit
206
207 The WebKit project has a "no performance regression" policy.
208 We maintain the performance of the following of the benchmarks and are located under [PerformanceTests](https://github.com/WebKit/WebKit/tree/main/PerformanceTests).
209 If your patch regresses one of these benchmarks even slightly (less than 1%), it will get reverted.
210
211 * **JetStream2** - Measures JavaScript and WASM performance.
212 * **MotionMark** - Measures graphics performance.
213 * **Speedometer 2** - Measures WebKit’s performance for complex web apps.
214
215 The following are benchmarks maintained by Apple's WebKit team but not available to other open source contributors
216 since Apple doesn't have the right to redistribute the content.
217 If your WebKit patch regresses one of these tests, your patch may still get reverted.
218
219 * **RAMification** - Apple's internal JavaScript memory benchmark.
220 * **ScrollPerf** - Apple's internal scrolling performance tests.
221 * **PLT** - Apple's internal page load time tests.
222 * **Membuster / PLUM** - Apple's internal memory tests. Membuster for macOS and PLUM for iOS and iPadOS.
223
224 ## Contributing code to WebKit
225
226 WebKit has a rigorous code contribution process and policy in place to maintain the quality of code.
227
228 ### Coding style
229
230 Code you write must follow WebKit’s [coding style guideline](https://webkit.org/contributing-code/#code-style-guidelines).
231 You can run `Tools/Scripts/check-webkit-style` to check whether your code follows the coding guidelines or not
232 (it can report false positives or false negatives).
233 If you use `Tools/Scripts/webkit-patch upload` to upload your patch,
234 it automatically runs the style checker against the code you changed so there is no need to run `check-webkit-style` separately.
235
236 Some older parts of the codebase do not follow these guidelines.
237 If you are modifying such code, it is generally best to clean it up to comply with the current guidelines.
238
239 ### Convenience Tools
240
241 `Tools/Scripts/webkit-patch` provides a lot of utility functions like applying the latest patch on [bugs.webkit.org](https://bugs.webkit.org/) (`apply-from-bug`)
242 and uploading a patch (`upload --git-commit=<commit hash>`) to a [bugs.webkit.org](https://bugs.webkit.org/) bug.
243 Use `--all-commands` to the list of all commands this tool supports.
244
245 ### Licensing
246
247 Much of the code we inherited from [KHTML](https://en.wikipedia.org/wiki/KHTML) is licensed under [LGPL](https://en.wikipedia.org/wiki/GNU_Lesser_General_Public_License).
248 New code contributed to WebKit will use the [two clause BSD license](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/LICENSE-APPLE).
249 When contributing new code, update the copyright date.
250 When moving the existing code, you need to include the original copyright notice for the moved code
251 and you should also not change the license, which may be BSD or LGPL depending on a file, without the permission of the copyright holders.
252
253 ### Regression Tests
254
255 Once you have made a code change, you need to run the aforementioned tests (layout tests, API tests, etc...)
256 to make sure your code change doesn’t break existing functionality.
257 These days, uploading a patch on [bugs.webkit.org](https://bugs.webkit.org/) triggers the Early Warning System (a.k.a. EWS)
258
259 For any bug fix or a feature addition, there should be a new test demonstrating the behavior change caused by the code change.
260 If no such test can be written in a reasonable manner (e.g. the fix for a hard-to-reproduce race condition),
261 then the reason writing a tests is impractical should be explained in the accompanying change log.
262
263 Any patch which introduces new test failures or performance regressions may be reverted.
264 It’s in your interest to wait for the Early Warning System to fully build and test your patch on all relevant platforms.
265
266 ### ChangeLog Files
267
268 ChangeLogs are simple text files which provide historical documentation for all changes to the WebKit project.
269 All patches require an entry to the ChangeLog.
270
271 The first line contains the date, your full name, and your email address.
272 Use this to write up a brief summary of the changes you’ve made.
273 Don’t worry about the “Reviewed by NOBODY (OOPS!)” line, the person landing your patch will fill this in.
274 There is one ChangeLog per top-level directory.
275 If you changed code and tests you will need to edit at least two ChangeLogs.
276 `Tools/Scripts/prepare-ChangeLog` script will create stub entries for ChangeLog files based on code changes you made in your Git or Subversion checkouts.
277
278 You should edit these stubs to describe your change, including the full URL to the bug (example entry, note that you can use `--bug` flag).
279 (You should set `EMAIL_ADDRESS` and `CHANGE_LOG_NAME` in your environment if you will be running this script frequently.)
280 A typical change log entry before being submitted to [bugs.webkit.org](https://bugs.webkit.org/) looks like this:
281
282 ```
283 2012-10-04  Enrica Casucci  <e•••••@apple.com>
284
285         Font::glyphDataAndPageForCharacter doesn't account for text orientation when using systemFallback on a cold cache.
286         https://bugs.webkit.org/show_bug.cgi?id=98452.
287
288         Reviewed by NOBODY (OOPS!).
289
290         The text orientation was considered only when there is a cache hit.
291         This change moves the logic to handle text orientation to a separate
292         inline function that is called also when the glyph is added to the cache.
293
294         Test: fast/text/vertical-rl-rtl-linebreak.html
295
296         * platform/graphics/FontFastPath.cpp:
297         (WebCore::applyTextOrientationForCharacter): Added.
298         (WebCore::Font::glyphDataAndPageForCharacter): Modified to use the new function in
299         both cases of cold and warm cache.
300 ```
301
302
303 The “No new tests. (OOPS!)” line appears if `prepare-ChangeLog` did not detect the addition of new tests.
304 If your patch does not require test cases (or test cases are not possible), remove this line and explain why you didn’t write tests.
305 Otherwise all changes require test cases which should be mentioned in the ChangeLog.
306
307 ## WebKit’s Build System
308
309 Apple’s macOS, iOS, watchOS, and tvOS ports use Xcode and the rest use [CMake](https://en.wikipedia.org/wiki/CMake) to build WebKit.
310 There is an ongoing effort to make Apple's ports also use CMake.
311
312 In order to reduce the compilation time, which used to take 40+ minutes on the fully loaded 2018 15“ MacBook Pro,
313 we bundle up multiple C++ translation units (.cpp files) and compile them as a single translation unit.
314 We call this mechanism *Unified Sources* or *Unified Builds*.
315
316 Unified sources are generated under `WebKitBuild/X/DerivedSources` where X is the name of build configuration such as `Debug` and `Release-iphonesimulator`.
317 For example, `WebKitBuild/Debug/DerivedSources/WebCore/unified-sources/UnifiedSource116.cpp` may look like this:
318
319 ```cpp
320 #include "dom/Document.cpp"
321 #include "dom/DocumentEventQueue.cpp"
322 #include "dom/DocumentFragment.cpp"
323 #include "dom/DocumentMarkerController.cpp"
324 #include "dom/DocumentParser.cpp"
325 #include "dom/DocumentSharedObjectPool.cpp"
326 #include "dom/DocumentStorageAccess.cpp"
327 #include "dom/DocumentType.cpp"
328 ```
329
330 ### How to add a new .h or .cpp file
331
332 To add a new header file or a translation unit (e.g. `.cpp`, `.m`, or `.mm`),
333 open WebKit.xcworkspace and add respective files in each directory.
334
335 Make sure to uncheck the target membership so that it’s not compiled as a part of the framework in xcodebuild.
336 Instead, add the same file in Sources.txt file that exists in each subdirectory of Source.
337 e.g. [Source/WebCore/Sources.txt](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/Sources.txt) for WebCore.
338 This will ensure the newly added file is compiled as a part of *unified sources*.
339 ![Screenshot of adding a file to Xcode](resources/xcode-add-file.png)
340 When a header file in WTF is used in WebCore, or a header file in WebCore is used in WebKit or WebKitLegacy,
341 we need to export the file to those projects.
342 To do that, turn on the target membership in respective framework as set the membership to “Private” as seen below.
343 This will ensure the relevant header file is exported from WTF / WebCore to other downstream projects like WebKitLegacy.
344 ![Screenshot of exporting a header file](resources/xcode-export-header.png)
345
346 FIXME: Mention WTF_EXPORT_PRIVATE and WEBCORE_EXPORT.
347
348 FIXME: Add instructions on how to add files to CMake.
349
350 ### Build Failures with Unified Sources
351
352 Because of Unified Sources, it’s possible that adding a new file will cause a new build failure on some platform.
353 This happens because if `UnifiedSource1.cpp` contains `a.cpp`, `b.cpp`, `c.cpp`, then `#include` in `a.cpp` could have pulled in some header files that `c.cpp` needed.
354 When you add `b2.cpp`, and `c.cpp` moves to `UnifiedSource2.cpp`, `c.cpp` no longer benefits from `a.cpp` “accidentally” satisfying `c.cpp`’s header dependency.
355 When this happens, you need to add a new `#include` to `c.cpp` as it was supposed to be done in the first place.
356
357 ### Conditional Compilation
358
359 Every translation unit in WebKit starts by including “config.h”.
360 This file defines a set of [C++ preprocessor macros](https://en.cppreference.com/w/cpp/preprocessor)
361 used to enable or disable code based on the target operating system, platform, and whether a given feature is enabled or disabled.
362
363 For example, the following `#if` condition says that the code inside of it is only compiled if
364 [SERVICE_WORKER](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API) feature is enabled:
365
366 ```cpp
367 #if ENABLE(SERVICE_WORKER)
368 ...
369 #endif
370 ```
371
372 Similarly, the following `#if` condition will enable the in-between code only on macOS:
373
374 ```cpp
375 #if PLATFORM(MAC)
376 ...
377 #endif
378 ```
379
380 For code which should be enabled in iOS, watchOS, tvOS, and Mac Catalyst we use `PLATFORM(IOS_FAMILY)`.
381 For each specific variant of iOS family, we also have `PLATFORM(IOS)`, `PLATFORM(WATCHOS)`, `PLATFORM(APPLETV)`, and `PLATFORM(MACCATALYST)`.
382
383 The following `#if` condition will enable the in-between code only if CoreGraphics is used:
384
385 ```cpp
386 #if USE(CG)
387 ...
388 #endif
389 ```
390
391 Finally, if a certain piece of code should only be enabled in an operating system newer than some version,
392 we use  `__IPHONE_OS_VERSION_MIN_REQUIRED` or `__MAC_OS_X_VERSION_MIN_REQUIRED`.
393 For example, the following #if enables the in-between code only on macOS 10.14 (macOS Mojave) or above:
394
395 ```cpp
396 #if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
397 ...
398 #endif
399 ```
400
401 ## WebKit’s Continuous Integration Infrastructure
402
403 WebKit’s CI ([continuous integration](https://en.wikipedia.org/wiki/Continuous_integration)) infrastructure is located at [build.webkit.org](http://build.webkit.org/)).
404
405 [build.webkit.org](http://build.webkit.org/) will build and test commits from WebKit in the chronological order
406 and report test results to [results.webkit.org](http://results.webkit.org/).
407 Due to the chronological ordering, results could be a few hours behind during the work week.
408
409
410 We also have a dashboard to monitor the health of [build.webkit.org](http://build.webkit.org/)
411 at [build.webkit.org/dashboard](https://build.webkit.org/dashboard/).
412 If you observe that some bots are offline, or otherwise not processing your patch,
413 please notify [webkit-dev@webkit.org](mailto:webkit-dev@webkit.org).
414
415 This dashboard isn't great for investigating individual test failures,
416 [results.webkit.org](http://results.webkit.org/) is a better tool for such investigations.
417 It keeps track of individual test status by configuration over time.
418 You can search individual tests by name or look at the historical results of entire test suites.
419 These results will link back to the test runs in Buildbot which are associated with a specific failure.
420 See layout tests section for more details on how to use these tools to investigate test failures observed on bots.
421
422 FIXME: Add a section about downloading build products from build.webkit.org.
423
424 # Memory Management in WebKit
425
426 In WebKit, when an object is owned by another object,
427 we typically use [`std::unique_ptr`](https://en.cppreference.com/w/cpp/memory/unique_ptr) to express that ownership.
428 WebKit uses two primary management strategies when objects in other cases:
429 [garbage collection](https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)) and [reference counting](https://en.wikipedia.org/wiki/Reference_counting).
430
431 ## Garbage collection in WebKit
432
433 FIXME: Write this.
434
435 ## Reference counting in WebKit
436
437 ### Overview
438
439 Most of WebCore objects are not managed by JavaScriptCore’s garbage collector.
440 Instead, we use [reference counting](https://en.wikipedia.org/wiki/Reference_counting).
441 We have two referencing counting pointer types:
442 [`RefPtr`](https://github.com/WebKit/WebKit/blob/main/Source/WTF/wtf/RefPtr.h)
443 and [`Ref`](https://github.com/WebKit/WebKit/blob/main/Source/WTF/wtf/Ref.h).
444 RefPtr is intended to behave like a C++ pointer whereas Ref is intended to behave like a C++ reference,
445 meaning that the former can be set to `nullptr` but the latter cannot.
446
447 ```cpp
448 Ref<A> a1; // This will result in compilation error.
449 RefPtr<A> a2; // This is okay.
450 Ref<A> a3 = A::create(); // This is okay.
451 a3->f(); // Calls f() on an instance of A.
452 A* a4 = a3.ptr();
453 a4 = a2.get();
454 ```
455
456
457 Unlike C++‘s[`std::shared_ptr`](https://en.cppreference.com/w/cpp/memory/shared_ptr),
458 the implementation of referencing counting is a part of a managed object.
459 The requirements for an object to be used with `RefPtr` and `Ref` is as follows:
460
461 * It implements `ref()` and `deref()` member functions
462 * Each call to `ref()` and `deref()` will increment and decrement its internal reference counter
463 * The initial call to `ref()` is implicit in `new`,
464     after the object had been allocated and the constructor has been called upon;
465     i.e. meaning that the reference count starts at 1.
466 * When `deref()` is called when its internal reference counter reaches 0, “this” object is destructed and deleted.
467
468 There is a convenience super template class,
469 [`RefCounted<T>`](https://github.com/WebKit/WebKit/blob/main/Source/WTF/wtf/RefCounted.h),
470 which implements this behavior for any inherited class T automatically.
471
472 ### How to use RefPtr and Ref
473
474 When an object which implements the semantics required by RefPtr and Ref is created via new,
475 we must immediately *adopt* it into `Ref` type using `adoptRef` as follows:
476
477 ```cpp
478 class A : public RefCounted<T> {
479 public:
480     int m_foo;
481
482     int f() { return m_foo; }
483
484     static Ref<A> create() { return adoptRef(*new A); }
485 private:
486     A() = default;
487 };
488 ```
489
490 This will create an instance of `Ref` without calling `ref()` on the newly created object, avoiding the unnecessary increment from 0 to 1.
491 WebKit’s coding convention is to make the constructor private and add a static `create` function
492 which returns an instance of a ref counted object after adopting it. 
493
494 Note that returning RefPtr or Ref is efficient thanks to [copy elision](https://en.cppreference.com/w/cpp/language/copy_elision) in C++11,
495 and the following example does not create a temporary Ref object using copy constructor):
496
497 ```cpp
498 Ref<A> a = A::create();
499 ```
500
501 When passing the ownership of a ref-counted object to a function,
502 use rvalue reference with `WTFMove` (equivalent to `std::move` with some safety checks),
503 and use a regular reference when there is a guarantee for the caller to keep the object alive as follows:
504
505 ```cpp
506 class B {
507 public:
508     void setA(Ref<A>&& a) { m_a = WTFMove(a); }
509 private:
510     Ref<A> m_a;
511 };
512
513 ...
514
515 void createA(B& b) {
516     b.setA(A::create());
517 }
518 ```
519
520 Note that there is no `WTFMove` on `A::create` due to copy elision.
521
522 ### Forwarding ref and deref
523
524 As mentioned above, objects that are managed with `RefPtr` and `Ref` do not necessarily have to inherit from `RefCounted`.
525 One common alternative is to forward `ref` and `deref` calls to another object which has the ownership.
526 For example, in the following example, `Parent` class owns `Child` class.
527 When someone stores `Child` in `Ref` or `RefPtr`, the referencing counting of `Parent` is incremented and decremented on behalf of `Child`.
528 Both `Parent` and `Child` are destructed when the last `Ref` or `RefPtr` to either object goes away.
529
530 ```cpp
531 class Parent : RefCounted<Parent> {
532 public:
533     static Ref<Parent> create() { return adoptRef(*new Parent); }
534
535     Child& child() {
536         if (!m_child)
537             m_child = makeUnique<Child>(*this);
538         return m_child
539     }
540
541 private:
542     std::unique_ptr<Child> m_child;    
543 };
544
545 class Child {
546 public:
547     ref() { m_parent.ref(); }
548     deref() { m_parent.deref(); }
549
550 private:
551     Child(Parent& parent) : m_parent(parent) { }
552     friend class Parent;
553
554     Parent& m_parent;
555 }
556 ```
557
558 ### Reference Cycles
559
560 A reference cycle occurs when an object X which holds `Ref` or `RefPtr` to another object Y which in turns owns X by `Ref` or `RefPtr`.
561 For example, the following code causes a trivial memory leak because A holds a `Ref` of B, and B in turn holds `Ref` of the A:
562
563 ```cpp
564 class A : RefCounted<A> {
565 public:
566     static Ref<A> create() { return adoptRef(*new A); }
567     B& b() {
568         if (!m_b)
569             m_b = B::create(*this);
570         return m_b.get();
571     }
572 private:
573     Ref<B> m_b;
574 };
575
576 class B : RefCounted<B> {
577 public:
578     static Ref<B> create(A& a) { return adoptRef(*new B(a)); }
579
580 private:
581     B(A& a) : m_a(a) { }
582     Ref<A> m_a;
583 };
584 ```
585
586 We need to be particularly careful in WebCore with regards to garbage collected objects
587 because they often keep other ref counted C++ objects alive without having any `Ref` or `RefPtr` in C++ code.
588 It’s almost always incorrect to strongly keep JS value alive in WebCore code because of this.
589
590 ### ProtectedThis Pattern
591
592 Because many objects in WebCore are managed by tree data structures,
593 a function that operates on a node of such a tree data structure can end up deleting itself (`this` object).
594 This is highly undesirable as such code often ends up having a use-after-free bug.
595
596 To prevent these kinds of bugs, we often employ a strategy of adding `protectedThis` local variable of `Ref` or `RefPtr` type, and store `this` object as [follows](https://github.com/WebKit/WebKit/blob/ea1a56ee11a26f292f3d2baed2a3aea95fea40f1/Source/WebCore/dom/ContainerNode.cpp#L632):
597
598 ```cpp
599 ExceptionOr<void> ContainerNode::removeChild(Node& oldChild)
600 {
601     // Check that this node is not "floating".
602     // If it is, it can be deleted as a side effect of sending mutation events.
603     ASSERT(refCount() || parentOrShadowHostNode());
604
605     Ref<ContainerNode> protectedThis(*this);
606
607     // NotFoundError: Raised if oldChild is not a child of this node.
608     if (oldChild.parentNode() != this)
609         return Exception { NotFoundError };
610
611     if (!removeNodeWithScriptAssertion(oldChild, ChildChange::Source::API))
612         return Exception { NotFoundError };
613
614     rebuildSVGExtensionsElementsIfNecessary();
615     dispatchSubtreeModifiedEvent();
616
617     return { };
618 }
619 ```
620
621 In this code, the act of removing `oldChild` can execute arbitrary JavaScript and delete `this` object.
622 As a result, `rebuildSVGExtensionsElementsIfNecessary` or `dispatchSubtreeModifiedEvent` might be called
623 after `this` object had already been free’ed if we didn’t have `protectedThis`,
624 which guarantees that this object’s reference count is at least 1
625 (because [Ref’s constructor](https://github.com/WebKit/WebKit/blob/ea1a56ee11a26f292f3d2baed2a3aea95fea40f1/Source/WTF/wtf/Ref.h#L64) increments the reference count by 1).
626
627 This pattern can be used for other objects that need to be *protected* from destruction inside a code block.
628 In the [following code](https://github.com/WebKit/WebKit/blob/ea1a56ee11a26f292f3d2baed2a3aea95fea40f1/Source/WebCore/dom/ContainerNode.cpp#L162),
629 `childToRemove` was passed in using C++ reference.
630 Because this function is going to remove this child node from `this` container node,
631 it can get destructed while the function is still running.
632 To prevent from having any chance of use-after-free bugs,
633 this function stores it in Ref (`protectedChildToRemove`) which guarantees the object to be alive until the function returns control back to the caller:
634
635 ```cpp
636 ALWAYS_INLINE bool ContainerNode::removeNodeWithScriptAssertion(Node& childToRemove, ChildChangeSource source)
637 {
638     Ref<Node> protectedChildToRemove(childToRemove);
639     ASSERT_WITH_SECURITY_IMPLICATION(childToRemove.parentNode() == this);
640     {
641         ScriptDisallowedScope::InMainThread scriptDisallowedScope;
642         ChildListMutationScope(*this).willRemoveChild(childToRemove);
643     }
644     ..
645 ```
646
647 Also see [Darin’s RefPtr Basics](https://webkit.org/blog/5381/refptr-basics/) for further reading.
648
649 ## Weak Pointers in WebKit
650
651 In some cases, it’s desirable to express a relationship between two objects without necessarily tying their lifetime.
652 In those cases, `WeakPtr` is useful. Like [std::weak_ptr](https://en.cppreference.com/w/cpp/memory/weak_ptr),
653 this class creates a non-owning reference to an object. There is a lot of legacy code which uses a raw pointer for this purpose,
654 but there is an ongoing effort to always use WeakPtr instead so do that in new code you’re writing.
655
656 To create a `WeakPtr` to an object, we need to make its class inherit from `CanMakeWeakPtr` as follows:
657
658 ```cpp
659 class A : CanMakeWeakPtr<A> { }
660
661 ...
662
663 function foo(A& a) {
664     WeakPtr<A> weakA = a;
665 }
666 ```
667
668 Dereferencing a `WeakPtr` will return `nullptr` when the referenced object is deleted.
669 Because creating a `WeakPtr` allocates an extra `WeakPtrImpl` object,
670 you’re still responsible to dispose of `WeakPtr` at appropriate time.
671
672 ### WeakHashSet
673
674 While ordinary `HashSet` does not support having `WeakPtr` as its elements,
675 there is a specialized `WeakHashSet` class, which supports referencing a set of elements weakly.
676 Because `WeakHashSet` does not get notified when the referenced object is deleted,
677 the users / owners of `WeakHashSet` are still responsible for deleting the relevant entries from the set.
678 Otherwise, WeakHashSet will hold onto `WeakPtrImpl` until `computeSize` is called or rehashing happens.
679
680 # Understanding Document Object Model
681
682 ## Introduction
683
684 [Document Object Model](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model)
685 (often abbreviated as DOM) is the tree data structured resulted from parsing HTML.
686 It consists of one or more instances of subclasses of [Node](https://developer.mozilla.org/en-US/docs/Web/API/Node)
687 and represents the document tree structure. Parsing a simple HTML like this:
688
689 ```cpp
690 <!DOCTYPE html>
691 <html>
692 <body>hi</body>
693 </html>
694 ```
695
696 Will generate the following six distinct DOM nodes:
697
698 * [Document](https://developer.mozilla.org/en-US/docs/Web/API/Document)
699     * [DocumentType](https://developer.mozilla.org/en-US/docs/Web/API/DocumentType)
700     * [HTMLHtmlElement](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/html)
701         * [HTMLHeadElement](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/head)
702         * [HTMLBodyElement](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/body)
703             * [Text](https://developer.mozilla.org/en-US/docs/Web/API/Text) with the value of “hi”
704
705 Note that HTMLHeadElement (i.e. `<head>`) is created implicitly by WebKit
706 per the way [HTML parser](https://html.spec.whatwg.org/multipage/parsing.html#parsing) is specified.
707
708 Broadly speaking, DOM node divides into the following categories:
709
710 * [Container nodes](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/ContainerNode.h) such as [Document](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/Document.h), [Element](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/Element.h), and [DocumentFragment](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/DocumentFragment.h).
711 * Leaf nodes such as [DocumentType](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/DocumentType.h), [Text](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/Text.h), and [Attr](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/Attr.h).
712
713 [Document](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/Document.h) node,
714 as the name suggests a single HTML, SVG, MathML, or other XML document,
715 and is the [owner](https://github.com/WebKit/WebKit/blob/ea1a56ee11a26f292f3d2baed2a3aea95fea40f1/Source/WebCore/dom/Node.h#L359) of every node in the document.
716 It is the very first node in any document that gets created and the very last node to be destroyed.
717
718 Note that a single web [page](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/page/Page.h) may consist of multiple documents
719 since [iframe](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe)
720 and [object](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/object) elements may contain
721 a child [frame](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/page/Frame.h),
722 and form a [frame tree](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/page/FrameTree.h).
723 Because JavaScript can [open a new window](https://developer.mozilla.org/en-US/docs/Web/API/Window/open)
724 under user gestures and have [access back to its opener](https://developer.mozilla.org/en-US/docs/Web/API/Window/opener),
725 multiple web pages across multiple tabs might be able to communicate with one another via JavaScript API
726 such as [postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage).
727
728 ## JavaScript Wrappers and IDL files
729
730 In addition to typical C++ translation units (.cpp) and C++ header files (.cpp) along with some Objective-C and Objective-C++ files,
731 [WebCore](https://github.com/WebKit/WebKit/tree/main/Source/WebCore) contains hundreds of [Web IDL](https://heycam.github.io/webidl/) (.idl) files.
732 [Web IDL](https://heycam.github.io/webidl/) is an [interface description language](https://en.wikipedia.org/wiki/Interface_description_language)
733 and it's used to define the shape and the behavior of JavaScript API implemented in WebKit.
734
735 When building WebKit, a [perl script](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm)
736 generates appropriate C++ translation units and C++ header files corresponding to these IDL files under `WebKitBuild/Debug/DerivedSources/WebCore/`
737 where `Debug` is the current build configuration (e.g. it could be `Release-iphonesimulator` for example).
738
739 These auto-generated files along with manually written files [Source/WebCore/bindings](https://github.com/WebKit/WebKit/tree/main/Source/WebCore/bindings)
740 are called **JS DOM binding code** and implements JavaScript API for objects and concepts whose underlying shape and behaviors are written in C++.
741
742 For example, C++ implementation of [Node](https://developer.mozilla.org/en-US/docs/Web/API/Node)
743 is [Node class](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/Node.h)
744 and its JavaScript interface is implemented by `JSNode` class.
745 The class declartion and most of definitions are auto-generated
746 at `WebKitBuild/Debug/DerivedSources/WebCore/JSNode.h` and `WebKitBuild/Debug/DerivedSources/WebCore/JSNode.cpp` for debug builds.
747 It also has some custom, manually written, bindings code in
748 [Source/WebCore/bindings/js/JSNodeCustom.cpp](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/bindings/js/JSNodeCustom.cpp).
749 Similarly, C++ implementation of [Range interface](https://developer.mozilla.org/en-US/docs/Web/API/Range)
750 is [Range class](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/Range.h)
751 whilst its JavaScript API is implemented by the auto-generated JSRange class
752 (located at `WebKitBuild/Debug/DerivedSources/WebCore/JSRange.h` and `WebKitBuild/Debug/DerivedSources/WebCore/JSRange.cpp` for debug builds)
753 We call instances of these JSX classes *JS wrappers* of X.
754
755 These JS wrappers exist in what we call a [`DOMWrapperWorld`](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/bindings/js/DOMWrapperWorld.h).
756 Each `DOMWrapperWorld` has its own JS wrapper for each C++ object.
757 As a result, a single C++ object may have multiple JS wrappers in distinct `DOMWrapperWorld`s.
758 The most important `DOMWrapperWorld` is the main `DOMWrapperWorld` which runs the scripts of web pages WebKit loaded
759 while other `DOMWrapperWorld`s are typically used to run code for browser extensions and other code injected by applications that embed WebKit.
760 ![Diagram of JS wrappers](resources/js-wrapper.png)
761 JSX.h provides `toJS` functions which creates a JS wrapper for X
762 in a given [global object](https://developer.mozilla.org/en-US/docs/Glossary/Global_object)’s `DOMWrapperWorld`,
763 and toWrapped function which returns the underlying C++ object.
764 For example, `toJS` function for [Node](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/Node.h)
765 is defined in [Source/WebCore/bindings/js/JSNodeCustom.h](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/bindings/js/JSNodeCustom.h).
766
767 When there is already a JS wrapper object for a given C++ object,
768 `toJS` function will find the appropriate JS wrapper in
769 a [hash map](https://github.com/WebKit/WebKit/blob/ea1a56ee11a26f292f3d2baed2a3aea95fea40f1/Source/WebCore/bindings/js/DOMWrapperWorld.h#L74)
770 of the given `DOMWrapperWorld`.
771 Because a hash map lookup is expensive, some WebCore objects inherit from
772 [ScriptWrappable](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/bindings/js/ScriptWrappable.h),
773 which has an inline pointer to the JS wrapper for the main world if one was already created.
774
775 ### Adding new JavaScript API
776
777 To introduce a new JavaScript API in [WebCore](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/), 
778 first identify the directory under which to implement this new API, and introduce corresponding Web IDL files.
779 New IDL files should be listed in [Source/WebCore/DerivedSources.make](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/DerivedSources.make)
780 so that the aforementioned perl script can generate corresponding JS*.cpp and JS*.h filies.
781 Add these newly generated JS*.cpp files to [Source/WebCore/Sources.txt](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/Sources.txt)
782 in order for them to be compiled.
783 Remember to add these files to [WebCore's Xcode project](https://github.com/WebKit/WebKit/tree/main/Source/WebCore/WebCore.xcodeproj) as well.
784
785 For example, [this commit](https://github.com/WebKit/WebKit/commit/cbda68a29beb3da90d19855882c5340ce06f1546)
786 introduced [`IdleDeadline.idl`](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/IdleDeadline.idl)
787 and added `JSIdleDeadline.cpp` to the list of derived sources to be compiled.
788
789 ## JS Wrapper Lifecycle Management
790
791 As a general rule, a JS wrapper keeps its underlying C++ object alive by means of reference counting
792 in [JSDOMWrapper](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/bindings/js/JSDOMWrapper.h) temple class
793 from which all JS wrappers in WebCore inherits.
794 However, **C++ objects do not keep their corresponding JS wrapper in each world alive** by the virtue of them staying alive
795 as such a circular dependency will result in a memory leak.
796
797 There are two primary mechanisms to keep JS wrappers alive in [WebCore](https://github.com/WebKit/WebKit/tree/main/Source/WebCore):
798
799 * **Visit Children** - When JavaScriptCore’s garbage collection visits some JS wrapper during
800     the [marking phase](https://en.wikipedia.org/wiki/Tracing_garbage_collection#Basic_algorithm),
801     visit another JS wrapper or JS object that needs to be kept alive.
802 * **Reachable from Opaque Roots** - Tell JavaScriptCore’s garbage collection that a JS wrapper is reachable
803     from an opaque root which was added to the set of opaque roots during marking phase.
804
805 ### Visit Children
806
807 *Visit Children* is the mechanism we use when a JS wrapper needs to keep another JS wrapper or
808 [JS object](https://github.com/WebKit/WebKit/blob/main/Source/JavaScriptCore/runtime/JSObject.h) alive.
809
810 For example, [`ErrorEvent` object](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/ErrorEvent.idl)
811 uses this method in
812 [Source/WebCore/bindings/js/JSErrorEventCustom.cpp](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/bindings/js/JSErrorEventCustom.cpp)
813 to keep its "error" IDL attribute as follows:
814
815 ```cpp
816 template<typename Visitor>
817 void JSErrorEvent::visitAdditionalChildren(Visitor& visitor)
818 {
819     wrapped().originalError().visit(visitor);
820 }
821
822 DEFINE_VISIT_ADDITIONAL_CHILDREN(JSErrorEvent);
823 ```
824
825 Here, `DEFINE_VISIT_ADDITIONAL_CHILDREN` macro generates template instances of visitAdditionalChildren
826 which gets called by the JavaScriptCore's garbage collector.
827 When the garbage collector visits an instance `ErrorEvent` object,
828 it also visits `wrapped().originalError()`, which is the JavaScript value of "error" attribute:
829
830 ```cpp
831 class ErrorEvent final : public Event {
832 ...
833     const JSValueInWrappedObject& originalError() const { return m_error; }
834     SerializedScriptValue* serializedError() const { return m_serializedError.get(); }
835 ...
836     JSValueInWrappedObject m_error;
837     RefPtr<SerializedScriptValue> m_serializedError;
838     bool m_triedToSerialize { false };
839 };
840 ```
841
842 Note that [`JSValueInWrappedObject`](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/bindings/js/JSValueInWrappedObject.h)
843 uses [`Weak`](https://github.com/WebKit/WebKit/blob/main/Source/JavaScriptCore/heap/Weak.h),
844 which does not keep the referenced object alive on its own.
845 We can't use a reference type such as [`Strong`](https://github.com/WebKit/WebKit/blob/main/Source/JavaScriptCore/heap/Strong.h)
846 which keeps the referenced object alive on its own since the stored JS object may also have this `ErrorEvent` object stored as its property.
847 Because the garbage collector has no way of knowing or clearing the `Strong` reference
848 or the property to `ErrorEvent` in this hypothetical version of `ErrorEvent`,
849 it would never be able to collect either object, resulting in a memory leak.
850
851 To use this method of keeping a JavaScript object or wrapper alive, add `JSCustomMarkFunction` to the IDL file,
852 then introduce JS*Custom.cpp file under [Source/WebCore/bindings/js](https://github.com/WebKit/WebKit/tree/main/Source/WebCore/bindings/js)
853 and implement `template<typename Visitor> void JS*Event::visitAdditionalChildren(Visitor& visitor)` as seen above for `ErrorEvent`.
854
855 **visitAdditionalChildren is called concurrently** while the main thread is running.
856 Any operation done in visitAdditionalChildren needs to be multi-thread safe.
857 For example, it cannot increment or decrement the reference count of a `RefCounted` object
858 or create a new `WeakPtr` from `CanMakeWeakPtr` since these WTF classes are not thread safe.
859
860 ### Opaque Roots
861
862 *Reachable from Opaque Roots* is the mechanism we use when we have an underlying C++ object and want to keep JS wrappers of other C++ objects alive.
863
864 To see why, let's consider a [`StyleSheet` object](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/css/StyleSheet.idl).
865 So long as this object is alive, we also need to keep the DOM node returned by the `ownerNode` attribute.
866 Also, the object itself needs to be kept alive so long as the owner node is alive
867 since this [`StyleSheet` object] can be accessed via [`sheet` IDL attribute](https://drafts.csswg.org/cssom/#the-linkstyle-interface)
868 of the owner node.
869 If we were to use the *visit children* mechanism,
870 we need to visit every JS wrapper of the owner node whenever this `StyleSheet` object is visited by the garbage collector,
871 and we need to visit every JS wrapper of the `StyleSheet` object whenever an owner node is visited by the garbage collector.
872 But in order to do so, we need to query every `DOMWrapperWorld`'s wrapper map to see if there is a JavaScript wrapper.
873 This is an expensive operation that needs to happen all the time,
874 and creates a tie coupling between `Node` and `StyleSheet` objects
875 since each JS wrapper objects need to be  aware of other objects' existence. 
876
877 *Opaque roots* solves these problems by letting the garbage collector know that a particular JavaScript wrapper needs to be kept alive
878 so long as the gargabe collector had encountered specific opaque root(s) this JavaScript wrapper cares about
879 even if the garbage collector didn't visit the JavaScript wrapper directly.
880 An opaque root is simply a `void*` identifier the garbage collector keeps track of during each marking phase,
881 and it does not conform to a specific interface or behavior.
882 It could have been an arbitrary integer value but `void*` is used out of convenience since pointer values of live objects are unique.
883
884 In the case of a `StyleSheet` object, `StyleSheet`'s JavaScript wrapper tells the garbage collector that it needs to be kept alive
885 because an opaque root it cares about has been encountered whenever `ownerNode` is visited by the garbage collector.
886
887 In the most simplistic model, the opaque root for this case will be the `ownerNode` itself.
888 However, each `Node` object also has to keep its parent, siblings, and children alive.
889 To this end, each `Node` designates the [root](https://dom.spec.whatwg.org/#concept-tree-root) node as its opaque root.
890 Both `Node` and `StyleSheet` objects use this unique opaque root as a way of communicating with the gargage collector.
891
892 For example, `StyleSheet` object informs the garbage collector of this opaque root when it's asked to visit its children in
893 [JSStyleSheetCustom.cpp](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/bindings/js/JSStyleSheetCustom.cpp):
894
895 ```cpp
896 template<typename Visitor>
897 void JSStyleSheet::visitAdditionalChildren(Visitor& visitor)
898 {
899     visitor.addOpaqueRoot(root(&wrapped()));
900 }
901 ```
902
903 Here, `void* root(StyleSheet*)` returns the opaque root of the `StyleSheet` object as follows:
904
905 ```cpp
906 inline void* root(StyleSheet* styleSheet)
907 {
908     if (CSSImportRule* ownerRule = styleSheet->ownerRule())
909         return root(ownerRule);
910     if (Node* ownerNode = styleSheet->ownerNode())
911         return root(ownerNode);
912     return styleSheet;
913 }
914 ```
915
916 And then in `JSStyleSheet.cpp` (located at `WebKitBuild/Debug/DerivedSources/WebCore/JSStyleSheet.cpp` for debug builds)
917 `JSStyleSheetOwner` (a helper JavaScript object to communicate with the garbage collector) tells the garbage collector
918 that `JSStyleSheet` should be kept alive so long as the garbage collector had encountered this `StyleSheet`'s opaque root:
919
920 ```cpp
921 bool JSStyleSheetOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, AbstractSlotVisitor& visitor, const char** reason)
922 {
923     auto* jsStyleSheet = jsCast<JSStyleSheet*>(handle.slot()->asCell());
924     void* root = WebCore::root(&jsStyleSheet->wrapped());
925     if (UNLIKELY(reason))
926         *reason = "Reachable from jsStyleSheet";
927     return visitor.containsOpaqueRoot(root);
928 }
929 ```
930
931 Generally, using opaque roots as a way of keeping JavaScript wrappers involve two steps:
932  1. Add opaque roots in `visitAdditionalChildren`.
933  2. Return true in `isReachableFromOpaqueRoots` when relevant opaque roots are found.
934
935 The first step can be achieved by using the aforementioned `JSCustomMarkFunction` with `visitAdditionalChildren`.
936 Alternatively and more preferably, `GenerateAddOpaqueRoot` can be added to the IDL interface to auto-generate this code.
937 For example, [AbortController.idl](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/AbortController.idl)
938 makes use of this IDL attribute as follows:
939
940 ```cpp
941 [
942     Exposed=(Window,Worker),
943     GenerateAddOpaqueRoot=signal
944 ] interface AbortController {
945     [CallWith=ScriptExecutionContext] constructor();
946
947     [SameObject] readonly attribute AbortSignal signal;
948
949     [CallWith=GlobalObject] undefined abort(optional any reason);
950 };
951 ```
952
953 Here, `signal` is a public member function funtion of
954 the [underlying C++ object](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/AbortController.h):
955
956 ```cpp
957 class AbortController final : public ScriptWrappable, public RefCounted<AbortController> {
958     WTF_MAKE_ISO_ALLOCATED(AbortController);
959 public:
960     static Ref<AbortController> create(ScriptExecutionContext&);
961     ~AbortController();
962
963     AbortSignal& signal();
964     void abort(JSDOMGlobalObject&, JSC::JSValue reason);
965
966 private:
967     explicit AbortController(ScriptExecutionContext&);
968
969     Ref<AbortSignal> m_signal;
970 };
971 ```
972
973 When `GenerateAddOpaqueRoot` is specified without any value, it automatically calls `opaqueRoot()` instead.
974
975 Like visitAdditionalChildren, **adding opaque roots happen concurrently** while the main thread is running.
976 Any operation done in visitAdditionalChildren needs to be multi-thread safe.
977 For example, it cannot increment or decrement the reference count of a `RefCounted` object
978 or create a new `WeakPtr` from `CanMakeWeakPtr` since these WTF classes are not thread safe.
979
980 The second step can be achived by adding `CustomIsReachable` to the IDL file and
981 implementing `JS*Owner::isReachableFromOpaqueRoots` in JS*Custom.cpp file.
982 Alternatively and more preferably, `GenerateIsReachable` can be added to IDL file to automatically generate this code
983 with the following values:
984  * No value - Adds the result of calling `root(T*)` on the underlying C++ object of type T as the opaque root.
985  * `Impl` - Adds the underlying C++ object as the opaque root.
986  * `ReachableFromDOMWindow` - Adds a [`DOMWindow`](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/page/DOMWindow.h)
987     returned by `window()` as the opaque root.
988  * `ReachableFromNavigator` - Adds a [`Navigator`](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/page/Navigator.h)
989     returned by `navigator()` as the opaque root.
990  * `ImplDocument` - Adds a [`Document`](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/Document.h)
991     returned by `document()` as the opaque root.
992  * `ImplElementRoot` - Adds the root node of a [`Element`](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/Element.h)
993     returned by `element()` as the opaque root.
994  * `ImplOwnerNodeRoot` - Adds the root node of a [`Node`](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/Node.h)
995     returned by `ownerNode()` as the opaque root.
996  * `ImplScriptExecutionContext` - Adds a [`ScriptExecutionContext`](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/ScriptExecutionContext.h)
997     returned by `scriptExecutionContext()` as the opaque root.
998
999 Similar to visiting children or adding opaque roots, **whether an opaque root is reachable or not is checked in parallel**.
1000 However, it happens **while the main thread is paused** unlike visiting children or adding opaque roots,
1001 which happen concurrently while the main thread is running.
1002 This means that any operation done in `JS*Owner::isReachableFromOpaqueRoots`
1003 or any function called by GenerateIsReachable cannot have thread unsafe side effects
1004 such as incrementing or decrementing the reference count of a `RefCounted` object
1005 or creating a new `WeakPtr` from `CanMakeWeakPtr` since these WTF classes' mutation operations are not thread safe.
1006
1007 ## Active DOM Objects
1008
1009 Visit children and opaque roots are great way to express lifecycle relationships between JS wrappers
1010 but there are cases in which a JS wrapper needs to be kept alive without any relation to other objects.
1011 Consider [`XMLHttpRequest`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest).
1012 In the following example, JavaScript loses all references to the `XMLHttpRequest` object and its event listener
1013 but when a new response gets received, an event will be dispatched on the object,
1014 re-introducing a new JavaScript reference to the object.
1015 That is, the object survives garbage collection's
1016 [mark and sweep cycles](https://en.wikipedia.org/wiki/Tracing_garbage_collection#Basic_algorithm)
1017 without having any ties to other ["root" objects](https://en.wikipedia.org/wiki/Tracing_garbage_collection#Reachability_of_an_object).
1018
1019 ```js
1020 function fetchURL(url, callback)
1021 {
1022     const request = new XMLHttpRequest();
1023     request.addEventListener("load", callback);
1024     request.open("GET", url);
1025     request.send();
1026 }
1027 ```
1028
1029 In WebKit, we consider such an object to have a *pending activity*.
1030 Expressing the presence of such a pending activity is a primary use case of
1031 [`ActiveDOMObject`](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/ActiveDOMObject.h).
1032
1033 By making an object inherit from [`ActiveDOMObject`](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/ActiveDOMObject.h)
1034 and [annotating IDL as such](https://github.com/WebKit/WebKit/blob/64cdede660d9eaea128fd151281f4715851c4fe2/Source/WebCore/xml/XMLHttpRequest.idl#L42),
1035 WebKit will [automatically generate `isReachableFromOpaqueRoot` function](https://github.com/WebKit/WebKit/blob/64cdede660d9eaea128fd151281f4715851c4fe2/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm#L5029)
1036 which returns true whenever `ActiveDOMObject::hasPendingActivity` returns true
1037 even though the garbage collector may not have encountered any particular opaque root to speak of in this instance.
1038
1039 In the case of [`XMLHttpRequest`](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/xml/XMLHttpRequest.h),
1040 `hasPendingActivity` [will return true](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/xml/XMLHttpRequest.cpp#L1195)
1041 so long as there is still an active network activity associated with the object.
1042 Once the resource is fully fetched or failed, it ceases to have a pending activity.
1043 This way, JS wrapper of `XMLHttpRequest` is kept alive so long as there is an active network activity.
1044
1045 There is one other related use case of active DOM objects,
1046 and that's when a document enters the [back-forward cache](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/history/BackForwardCache.h)
1047 and when the entire [page](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/page/Page.h) has to pause
1048 for [other reasons](https://github.com/WebKit/WebKit/blob/64cdede660d9eaea128fd151281f4715851c4fe2/Source/WebCore/dom/ActiveDOMObject.h#L45).
1049
1050 When this happens, each active DOM object associated with the document
1051 [gets suspended](https://github.com/WebKit/WebKit/blob/64cdede660d9eaea128fd151281f4715851c4fe2/Source/WebCore/dom/ActiveDOMObject.h#L70).
1052 Each active DOM object can use this opportunity to prepare itself to pause whatever pending activity;
1053 for example, `XMLHttpRequest` [will stop dispatching `progress` event](https://github.com/WebKit/WebKit/blob/64cdede660d9eaea128fd151281f4715851c4fe2/Source/WebCore/xml/XMLHttpRequest.cpp#L1157)
1054 and media elements [will stop playback](https://github.com/WebKit/WebKit/blob/64cdede660d9eaea128fd151281f4715851c4fe2/Source/WebCore/html/HTMLMediaElement.cpp#L6008).
1055 When a document gets out of the back-forward cache or resumes for other reasons,
1056 each active DOM object [gets resumed](https://github.com/WebKit/WebKit/blob/64cdede660d9eaea128fd151281f4715851c4fe2/Source/WebCore/dom/ActiveDOMObject.h#L71).
1057 Here, each object has the opportunity to resurrect the previously pending activity once again.
1058
1059 ### Creating a Pending Activity
1060
1061 There are a few ways to create a pending activity on an [active DOM objects](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/ActiveDOMObject.h).
1062
1063 When the relevant Web standards says to [queue a task](https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task) to do some work,
1064 one of the following member functions of [`ActiveDOMObject`](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/ActiveDOMObject.h) should be used:
1065  * [`queueTaskKeepingObjectAlive`](https://github.com/WebKit/WebKit/blob/64cdede660d9eaea128fd151281f4715851c4fe2/Source/WebCore/dom/ActiveDOMObject.h#L106)
1066  * [`queueCancellableTaskKeepingObjectAlive`](https://github.com/WebKit/WebKit/blob/64cdede660d9eaea128fd151281f4715851c4fe2/Source/WebCore/dom/ActiveDOMObject.h#L114)
1067  * [`queueTaskToDispatchEvent`](https://github.com/WebKit/WebKit/blob/64cdede660d9eaea128fd151281f4715851c4fe2/Source/WebCore/dom/ActiveDOMObject.h#L124)
1068  * [`queueCancellableTaskToDispatchEvent`](https://github.com/WebKit/WebKit/blob/64cdede660d9eaea128fd151281f4715851c4fe2/Source/WebCore/dom/ActiveDOMObject.h#L130)
1069 These functions will automatically create a pending activity until a newly enqueued task is executed.
1070
1071 Alternatively, [`makePendingActivity`](https://github.com/WebKit/WebKit/blob/64cdede660d9eaea128fd151281f4715851c4fe2/Source/WebCore/dom/ActiveDOMObject.h#L97)
1072 can be used to create a [pending activity token](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/ActiveDOMObject.h#L78)
1073 for an active DOM object.
1074 This will keep a pending activity on the active DOM object until all tokens are dead.
1075
1076 Finally, when there is a complex condition under which a pending activity exists,
1077 an active DOM object can override [`virtualHasPendingActivity`](https://github.com/WebKit/WebKit/blob/64cdede660d9eaea128fd151281f4715851c4fe2/Source/WebCore/dom/ActiveDOMObject.h#L147)
1078 member function and return true whilst such a condition holds.
1079 Note that `virtualHasPendingActivity` should return true so long as there is a possibility of dispatching an event or invoke JavaScript in any way in the future.
1080 In other words, a pending activity should exist while an object is doing some work in C++ well before any event dispatching is scheduled.
1081 Anytime there is no pending activity, JS wrappers of the object can get deleted by the garbage collector.
1082
1083 ## Reference Counting of DOM Nodes
1084
1085 [`Node`](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/Node.h) is a reference counted object but with a twist.
1086 It has a [separate boolean flag](https://github.com/WebKit/WebKit/blob/297c01a143f649b34544f0cb7a555decf6ecbbfd/Source/WebCore/dom/Node.h#L832)
1087 indicating whether it has a [parent](https://dom.spec.whatwg.org/#concept-tree-parent) node or not.
1088 A `Node` object is [not deleted](https://github.com/WebKit/WebKit/blob/297c01a143f649b34544f0cb7a555decf6ecbbfd/Source/WebCore/dom/Node.h#L801)
1089 so long as it has a reference count above 0 or this boolean flag is set.
1090 The boolean flag effectively functions as a `RefPtr` from a parent `Node`
1091 to each one of its [child](https://dom.spec.whatwg.org/#concept-tree-child) `Node`.
1092 We do this because `Node` only knows its [first child](https://dom.spec.whatwg.org/#concept-tree-first-child)
1093 and its [last child](https://dom.spec.whatwg.org/#concept-tree-last-child)
1094 and each [sibling](https://dom.spec.whatwg.org/#concept-tree-sibling) nodes are implemented
1095 as a [doubly linked list](https://en.wikipedia.org/wiki/Doubly_linked_list) to allow
1096 efficient [insertion](https://dom.spec.whatwg.org/#concept-node-insert)
1097 and [removal](https://dom.spec.whatwg.org/#concept-node-remove) and traversal of sibling nodes.
1098
1099 Conceptually, each `Node` is kept alive by its root node and external references to it,
1100 and we use the root node as an opaque root of each `Node`'s JS wrapper.
1101 Therefore the JS wrapper of each `Node` is kept alive as long as either the node itself
1102 or any other node which shares the same root node is visited by the garbage collector.
1103
1104 On the other hand, a `Node` does not keep its parent or any of its
1105 [shadow-including ancestor](https://dom.spec.whatwg.org/#concept-shadow-including-ancestor) `Node` alive
1106 either by reference counting or via the boolean flag even though the JavaScript API requires this to be the case.
1107 In order to implement this DOM API behavior,
1108 WebKit [will create](https://github.com/WebKit/WebKit/blob/297c01a143f649b34544f0cb7a555decf6ecbbfd/Source/WebCore/bindings/js/JSNodeCustom.cpp#L174)
1109 a JS wrapper for each `Node` which is being removed from its parent if there isn't already one.
1110 A `Node` which is a root node (of the newly removed [subtree](https://dom.spec.whatwg.org/#concept-tree)) is an opaque root of its JS wrapper,
1111 and the garbage collector will visit this opaque root if there is any JS wrapper in the removed subtree that needs to be kept alive.
1112 In effect, this keeps the new root node and all its [descendant](https://dom.spec.whatwg.org/#concept-tree-descendant) nodes alive
1113 if the newly removed subtree contains any node with a live JS wrapper, preserving the API contract.
1114
1115 It's important to recognize that storing a `Ref` or a `RefPtr` to another `Node` in a `Node` subclass
1116 or an object directly owned by the Node can create a [reference cycle](https://en.wikipedia.org/wiki/Reference_counting#Dealing_with_reference_cycles),
1117 or a reference that never gets cleared.
1118 It's not guaranteed that every node is [disconnected](https://dom.spec.whatwg.org/#connected)
1119 from a [`Document`](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/Document.h) at some point in the future,
1120 and some `Node` may always have a parent node or a child node so long as it exists.
1121 Only permissible circumstances in which a `Ref` or a `RefPtr` to another `Node` can be stored
1122 in a `Node` subclass or other data structures owned by it is if it's temporally limited.
1123 For example, it's okay to store a `Ref` or a `RefPtr` in
1124 an enqueued [event loop task](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/EventLoop.h#L69).
1125 In all other circumstances, `WeakPtr` should be used to reference another `Node`,
1126 and JS wrapper relationships such as opaque roots should be used to preserve the lifecycle ties between `Node` objects.
1127
1128 It's equally crucial to observe that keeping C++ Node object alive by storing `Ref` or `RefPtr`
1129 in an enqueued [event loop task](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/EventLoop.h#L69)
1130 does not keep its JS wrapper alive, and can result in the JS wrapper of a conceptually live object to be erroneously garbage collected.
1131 To avoid this problem, use [`GCReachableRef`](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/GCReachableRef.h) instead
1132 to temporarily hold a strong reference to a node over a period of time.
1133 For example, [`HTMLTextFormControlElement::scheduleSelectEvent()`](https://github.com/WebKit/WebKit/blob/297c01a143f649b34544f0cb7a555decf6ecbbfd/Source/WebCore/html/HTMLTextFormControlElement.cpp#L547)
1134 uses `GCReachableRef` to fire an event in an event loop task:
1135 ```cpp
1136 void HTMLTextFormControlElement::scheduleSelectEvent()
1137 {
1138     document().eventLoop().queueTask(TaskSource::UserInteraction, [protectedThis = GCReachableRef { *this }] {
1139         protectedThis->dispatchEvent(Event::create(eventNames().selectEvent, Event::CanBubble::Yes, Event::IsCancelable::No));
1140     });
1141 }
1142 ```
1143
1144 Alternatively, we can make it inherit from an [active DOM object](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/ActiveDOMObject.h),
1145 and use one of the following functions to enqueue a task or an event:
1146  - [`queueTaskKeepingObjectAlive`](https://github.com/WebKit/WebKit/blob/297c01a143f649b34544f0cb7a555decf6ecbbfd/Source/WebCore/dom/ActiveDOMObject.h#L107)
1147  - [`queueCancellableTaskKeepingObjectAlive`](https://github.com/WebKit/WebKit/blob/297c01a143f649b34544f0cb7a555decf6ecbbfd/Source/WebCore/dom/ActiveDOMObject.h#L115)
1148  - [`queueTaskToDispatchEvent`](https://github.com/WebKit/WebKit/blob/297c01a143f649b34544f0cb7a555decf6ecbbfd/Source/WebCore/dom/ActiveDOMObject.h#L124)
1149  - [`queueCancellableTaskToDispatchEvent`](https://github.com/WebKit/WebKit/blob/297c01a143f649b34544f0cb7a555decf6ecbbfd/Source/WebCore/dom/ActiveDOMObject.h#L130)
1150
1151 [`Document`](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/Document.h) node has one more special quirk
1152 because every [`Node`](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/dom/Node.h) can have access to a document
1153 via [`ownerDocument` property](https://developer.mozilla.org/en-US/docs/Web/API/Node/ownerDocument)
1154 whether Node is [connected](https://dom.spec.whatwg.org/#connected) to the document or not.
1155 Every document has a regular reference count used by external clients and
1156 [referencing node count](https://github.com/WebKit/WebKit/blob/297c01a143f649b34544f0cb7a555decf6ecbbfd/Source/WebCore/dom/Document.h#L2093).
1157 The referencing node count of a document is the total number of nodes whose `ownerDocument` is the document.
1158 A document is [kept alive](https://github.com/WebKit/WebKit/blob/297c01a143f649b34544f0cb7a555decf6ecbbfd/Source/WebCore/dom/Document.cpp#L749)
1159 so long as its reference count and node referencing count is above 0.
1160 In addition, when the regular reference count is to become 0,
1161 it clears various states including its internal references to owning Nodes to sever any reference cycles with them.
1162 A document is special in that sense that it can store `RefPtr` to other nodes.
1163 Note that whilst the referencing node count acts like `Ref` from each `Node` to its owner `Document`,
1164 storing a `Ref` or a `RefPtr` to the same document or any other document will create
1165 a [reference cycle](https://en.wikipedia.org/wiki/Reference_counting#Dealing_with_reference_cycles)
1166 and should be avoided unless it's temporally limited as noted above.
1167
1168 ## Inserting or Removing DOM Nodes 
1169
1170 FIXME: Talk about how a node insertion or removal works.
1171
1172 # Understanding Style and Render Tree
1173
1174 FIXME: Describe rendering/layers/compositing
1175
1176 # Security Model of Web
1177
1178 For starters, refer to https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy.
1179
1180 FIXME: Write this section.
1181
1182 # WebKit2: WebKit’s Multi-Process Architecture
1183
1184 ## Overview
1185
1186 In order to safeguard the rest of the system and allow the application to remain responsive
1187 even if the user had loaded web page that infinite loops or otherwise hangs,
1188 the modern incarnation of WebKit uses multi-process architecture.
1189 Web pages are loaded in its own *WebContent* process.
1190 Multiple WebContent processes can share a browsing session, which lives in a shared network process.
1191 In addition to handling all network accesses,
1192 this process is also responsible for managing the disk cache and Web APIs that allow websites
1193 to store structured data such as [Web Storage API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API)
1194 and [IndexedDB API](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API):
1195 ![Diagram of WebKit2's multi-process architecture](resources/webkit2-process-architecture.png)
1196 Because a WebContent process can Just-in-Time compile arbitrary JavaScript code loaded from the internet,
1197 meaning that it can write to memory that gets executed, this process is tightly sandboxed.
1198 It does not have access to any file system unless the user grants an access,
1199 and it does not have direct access to the underlying operating system’s [clipboard](https://en.wikipedia.org/wiki/Clipboard_(computing)),
1200 microphone, or video camera even though there are Web APIs that grant access to those features.
1201 Instead, UI process brokers such requests.
1202
1203 FIXME: How is IPC setup
1204
1205 FIXME: How to add / modify an IPC message
1206
1207 # Layout Tests: Tests of the Web for the Web
1208
1209 Layout tests are WebKit tests written using Web technology such as HTML, CSS, and JavaScript,
1210 and it’s the primary mechanism by which much of WebCore is tested.
1211 Relevant layout test should be ran while you’re making code changes to WebCore and before uploading a patch to [bugs.webkit.org](https://bugs.webkit.org/).
1212 While [bugs.webkit.org](https://bugs.webkit.org/)’s Early Warning System will build and run tests on a set of configurations,
1213 individual patch authors are ultimately responsible for any test failures that their patches cause.
1214
1215 ## Test Files and Expected Files
1216
1217 ### Directory Structure
1218
1219 [LayoutTests](https://github.com/WebKit/WebKit/tree/main/LayoutTests) directory is organized by the category of tests.
1220 For example, [LayoutTests/accessibility](https://github.com/WebKit/WebKit/tree/main/LayoutTests/accessibility) contains accessibility related tests,
1221 and [LayoutTests/fast/dom/HTMLAnchorElement](https://github.com/WebKit/WebKit/tree/main/LayoutTests/fast/dom/HTMLAnchorElement) contains
1222 tests for [the HTML anchor element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a).
1223
1224 Any file that ends in `.html`, `.htm`, `.shtml`, `.xhtml`, `.mht`, `.xht`, `.xml`, `.svg`, or `.php` is considered as a test
1225 unless it’s preceded with `-ref`, `-notref`, `-expected`, or `-expected-mismatch` (these are used for ref tests; explained later).
1226 It’s accompanied by another file of the same name except it ends in `-expected.txt` or `-expected.png`.
1227 These are called *expected results* and constitutes the baseline output of a given test.
1228 When layout tests are ran, the test runner generates an output in the form of a plain text file and/or an PNG image,
1229 and it is compared against these expected results.
1230
1231 In the case expected results may differ from one platform to another,
1232 the expected results for each test is stored in [LayoutTests/platform](https://github.com/WebKit/WebKit/tree/main/LayoutTests/platform).
1233 The expected result of a given test exists in the corresponding directory in
1234 each subdirectory of [LayoutTests/platform](https://github.com/WebKit/WebKit/tree/main/LayoutTests/platform).
1235 For example, the expected result of [LayoutTests/svg/W3C-SVG-1.1/animate-elem-46-t.svg](https://github.com/WebKit/WebKit/blob/main/LayoutTests/svg/W3C-SVG-1.1/animate-elem-46-t.svg)
1236 for macOS Mojave is located at [LayoutTests/platform/mac-mojave/svg/W3C-SVG-1.1/animate-elem-46-t-expected.txt](https://github.com/WebKit/WebKit/blob/main/LayoutTests/platform/mac-mojave/svg/W3C-SVG-1.1/animate-elem-46-t-expected.txt).
1237
1238 These platform directories have a fallback order.
1239 For example, running tests for WebKit2 on macOS Catalina will use the following fallback path from the most specific to most generic:
1240
1241 * platform/mac-catalina-wk2 - Results for WebKit2 on macOS Catalina.
1242 * platform/mac-catalina - Results for WebKit2 and WebKitLegacy on macOS Catalina.
1243 * platform/mac-wk2 - Results for WebKit2 on all macOS.
1244 * platform/mac - Results for all macOS.
1245 * platform/wk2 - Results for WebKit2 on every operating system.
1246 * generic - Next to the test file.
1247
1248 ### Imported Tests
1249
1250 Tests under [LayoutTests/imported](https://github.com/WebKit/WebKit/tree/main/LayoutTests/imported) are imported from other repositories.
1251 **They should not be modified by WebKit patches** unless the change is made in respective repositories first.
1252
1253 Most notable is [Web Platform Tests](https://web-platform-tests.org/),
1254 which are imported under [LayoutTests/imported/w3c/web-platform-tests](https://github.com/WebKit/WebKit/tree/main/LayoutTests/imported/w3c/web-platform-tests).
1255 These are cross browser vendor tests developed by W3C. Mozilla, Google, and Apple all contribute many tests to this shared test repository.
1256
1257 ### HTTP Tests
1258
1259 To open tests under [LayoutTests/http](https://github.com/WebKit/WebKit/tree/main/LayoutTests/http) or
1260 [LayoutTests/imported/w3c/web-platform-tests](https://github.com/WebKit/WebKit/tree/main/LayoutTests/imported/w3c/web-platform-tests),
1261 use [Tools/Scripts/open-layout-test](https://github.com/WebKit/WebKit/blob/main/Tools/Scripts/open-layout-test) with the path to a test.
1262
1263 You can also manually start HTTP servers with [`Tools/Scripts/run-webkit-httpd`](https://github.com/WebKit/WebKit/blob/main/Tools/Scripts/run-webkit-httpd).
1264 To stop the HTTP servers, exit the script (e.g. Control + C on macOS).
1265
1266 Tests under [LayoutTests/http](https://github.com/WebKit/WebKit/tree/main/LayoutTests/http) are accessible at [http://127.0.0.1:8000](http://127.0.0.1:8000)
1267 except tests in [LayoutTests/http/wpt](https://github.com/WebKit/WebKit/tree/main/LayoutTests/http/wpt),
1268 which are available at [http://localhost:8800/WebKit/](http://localhost:8800/WebKit/) instead.
1269
1270 The [Web Platform Tests](https://web-platform-tests.org/) imported under
1271 [LayoutTests/imported/w3c/web-platform-tests](https://github.com/WebKit/WebKit/tree/main/LayoutTests/imported/w3c/web-platform-tests)
1272 are accessible under HTTP at [http://localhost:8800/](http://localhost:8800/) and HTTPS at [http://localhost:9443/](http://localhost:9443/)
1273
1274 Note that it's important to use the exact host names such as `127.0.0.1` and `localhost` above verbatim
1275 since some tests rely on or test same-origin or cross-origin behaviors based on those host names.
1276
1277 ## Test Expectations
1278
1279 FIXME: Explain how test expectations work.
1280
1281 ## Running Layout Tests
1282
1283 To run layout tests, use `Tools/Scripts/run-webkit-tests`.
1284 It optionally takes file paths to a test file or directory and options on how to run a test.
1285 For example, in order to just run `LayoutTests/fast/dom/Element/element-traversal.html`, do:
1286
1287 ```sh
1288 Tools/Scripts/run-webkit-tests fast/dom/Element/element-traversal.html
1289 ```
1290
1291 Because there are 50,000+ tests in WebKit,
1292 you typically want to run a subset of tests that are relevant to your code change
1293 (e.g. `LayoutTests/storage/indexeddb/` if you’re working on IndexedDB) while developing the code change,
1294 and run all layout tests at the end on your local machine or rely on the Early Warning System on [bugs.webkit.org](https://bugs.webkit.org/) for more thorough testing.
1295
1296 Specify `--debug` or `--release` to use either release or debug build.
1297 To run tests using iOS simulator, you can specify either `--ios-simulator`, `--iphone-simulator`,
1298 or `--ipad-simulator` based on whichever simulator is desired.
1299
1300 By default, `run-webkit-tests` will run all the tests you specified once in the lexicological order of test paths
1301 relative to `LayoutTests` directory and retry any tests that have failed.
1302 If you know the test is going to fail and don’t want retries, specify `--no-retry-failures`.
1303
1304 Because there are so many tests, `run-webkit-tests` will runs tests in different directories in parallel
1305 (i.e. all tests in a single directory is ran sequentially one after another).
1306 You can control the number of parallel test runners using `--child-processes` option.
1307
1308 `run-webkit-tests` has many options.
1309 Use `--help` to enumerate all the supported options.
1310
1311 ### Repeating Layout Tests
1312
1313 When you’re investigating flaky tests or crashes, it might be desirable to adjust this.
1314 `--iterations X` option will specify the number of times the list of tests are ran.
1315 For example, if we are running tests A, B, C and `--iterations 3` is specified,
1316 `run-webkit-tests` will run: A, B, C, A, B, C, A, B, C.
1317 Similarly, `--repeat-each` option will specify the number of times each test is repeated before moving onto next test.
1318 For example, if we’re running tests A, B, C, and `--repeat-each 3` is specified, `run-webkit-tests` will run: A, A, A, B, B, B, C, C, C.
1319 `--exit-after-n-failures` option will specify the total number of test failures before `run-webkit-tests` will stop.
1320 In particular, `--exit-after-n-failures=1` is useful when investigating a flaky failure
1321 so that `run-webkit-tests` will stop when the failure actually happens for the first time.
1322
1323 ### Test Results
1324
1325 Whenever tests do fail, run-webkit-tests will store results in `WebKitBuild/Debug/layout-test-results`
1326 mirroring the same directory structure as `LayoutTests`.
1327 For example, the actual output produced for `LayoutTests/editing/inserting/typing-001.html`,
1328 if failed, will appear in `WebKitBuild/Debug/layout-test-results/editing/inserting/typing-001-actual.txt`.
1329 run-webkit-tests also generates a web page with the summary of results in
1330 `WebKitBuild/Debug/layout-test-results/results.html` and automatically tries to open it in Safari using the local build of WebKit.
1331
1332 > If Safari fails to launch, specify `--no-show-results` and open results.html file manually.
1333
1334 ### Updating Expected Results
1335
1336 If you’ve updated a test content or test’s output changes with your code change (e.g. more test case passes),
1337 then you may have to update `-expected.txt` file accompanying the test.
1338 To do that, first run the test once to make sure the diff and new output makes sense in results.html,
1339 and run the test again with `--reset-results`.
1340 This will update the matching `-expected.txt` file.
1341
1342 You may need to manually copy the new result to other -expected.txt files that exist under `LayoutTests` for other platforms and configurations.
1343 Find other `-expected.txt` files when you’re doing this.
1344
1345 When a new test is added, `run-webkit-tests` will automatically generate new `-expected.txt` file for your test.
1346 You can disable this feature by specifying `--no-new-test-results` e.g. when the test is still under development.
1347
1348 ## Different Styles of Layout Tests
1349
1350 There are multiple styles of layout tests in WebKit.
1351
1352 ### **Render tree dumps**
1353
1354 This is the oldest style of layout tests, and the default mode of layout tests.
1355 It’s a text serialization of WebKit’s render tree and its output looks like
1356 [this](https://github.com/WebKit/WebKit/blob/main/LayoutTests/platform/mac/fast/dom/anchor-text-expected.txt):
1357
1358 ```
1359 layer at (0,0) size 800x600
1360   RenderView at (0,0) size 800x600
1361 layer at (0,0) size 800x600
1362   RenderBlock {HTML} at (0,0) size 800x600
1363     RenderBody {BODY} at (8,8) size 784x584
1364       RenderInline {A} at (0,0) size 238x18 [color=#0000EE]
1365         RenderInline {B} at (0,0) size 238x18
1366           RenderText {#text} at (0,0) size 238x18
1367             text run at (0,0) width 238: "the second copy should not be bold"
1368       RenderText {#text} at (237,0) size 5x18
1369         text run at (237,0) width 5: " "
1370       RenderText {#text} at (241,0) size 227x18
1371         text run at (241,0) width 227: "the second copy should not be bold"
1372 ```
1373
1374 This style of layout tests is discouraged today because its outputs are highly dependent on each platform,
1375 and end up requiring a specific expected result in each platform.
1376 But they’re still useful when testing new rendering and layout feature or bugs thereof.
1377
1378 These tests also have accompanying `-expected.png` files but `run-webkit-tests` doesn't check the PNG output against the expected result by default.
1379 To do this check, pass `--pixel`.
1380 Unfortunately, many *pixel tests* will fail because we have not been updating the expected PNG results a good chunk of the last decade.
1381 However, these pixel results might be useful when diagnosing a new test failure.
1382 For this reason, `run-webkit-tests` will automatically generate PNG results when retrying the test,
1383 effectively enabling `--pixel` option for retries.
1384
1385 ### dumpAsText test
1386
1387 These are tests that uses the plain text serialization of the test page as the output (as if the entire page’s content is copied as plain text).
1388 All these tests call `testRunner.dumpAsText` to trigger this behavior.
1389 The output typically contains a log of text or other informative output scripts in the page produced.
1390 For example, [LayoutTests/fast/dom/anchor-toString.html](https://github.com/WebKit/WebKit/blob/main/LayoutTests/fast/dom/anchor-toString.html) is written as follows:
1391
1392 ```html
1393 <a href="http://localhost/sometestfile.html" id="anchor">
1394 A link!
1395 </a>
1396 <br>
1397 <br>
1398 <script>
1399     {
1400         if (window.testRunner)
1401             testRunner.dumpAsText();
1402
1403         var anchor = document.getElementById("anchor");
1404         document.write("Writing just the anchor object - " + anchor);
1405
1406         var anchorString = String(anchor);
1407         document.write("<br><br>Writing the result of the String(anchor) - " + anchorString);
1408
1409         var anchorToString = anchor.toString();
1410         document.write("<br><br>Writing the result of the anchor's toString() method - " + anchorToString);
1411     }
1412 </script>
1413 ```
1414
1415  and generates the following [output](https://github.com/WebKit/WebKit/blob/main/LayoutTests/fast/dom/anchor-toString-expected.txt):
1416
1417 ```
1418 A link! 
1419
1420 Writing just the anchor object - http://localhost/sometestfile.html
1421
1422 Writing the result of the String(anchor) - http://localhost/sometestfile.html
1423
1424 Writing the result of the anchor's toString() method - http://localhost/sometestfile.html
1425 ```
1426
1427 ### js-test.js and js-test-pre.js tests
1428
1429 These are variants of dumpAsText test which uses WebKit’s assertion library:
1430 [LayoutTests/resources/js-test.js](https://github.com/WebKit/WebKit/blob/main/LayoutTests/resources/js-test.js)
1431 and [LayoutTests/resources/js-test-pre.js](https://github.com/WebKit/WebKit/blob/main/LayoutTests/resources/js-test-pre.js).
1432 It consists of shouldX function calls which takes two JavaScript code snippet which are then executed and outputs of which are compared.
1433 js-test.js is simply a new variant of js-test-pre.js that doesn’t require
1434 the inclusion of [LayoutTests/resources/js-test-post.js](https://github.com/WebKit/WebKit/blob/main/LayoutTests/resources/js-test-post.js) at the end.
1435 **Use js-test.js in new tests**, not js-test-pre.js.
1436
1437 For example, [LayoutTests/fast/dom/Comment/remove.html](https://github.com/WebKit/WebKit/blob/main/LayoutTests/fast/dom/Comment/remove.html)
1438 which tests [remove()](https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove) method
1439 on [Comment node](https://developer.mozilla.org/en-US/docs/Web/API/Comment) is written as:
1440
1441 ```html
1442 <!DOCTYPE html>
1443 <script src="../../../resources/js-test-pre.js"></script>
1444 <div id="test"></div>
1445 <script>
1446
1447 description('This tests the DOM 4 remove method on a Comment.');
1448
1449 var testDiv = document.getElementById('test');
1450 var comment = document.createComment('Comment');
1451 testDiv.appendChild(comment);
1452 shouldBe('testDiv.childNodes.length', '1');
1453 comment.remove();
1454 shouldBe('testDiv.childNodes.length', '0');
1455 comment.remove();
1456 shouldBe('testDiv.childNodes.length', '0');
1457
1458 </script>
1459 <script src="../../../resources/js-test-post.js"></script>
1460 ```
1461
1462 with the following [expected result](https://github.com/WebKit/WebKit/blob/main/LayoutTests/fast/dom/Comment/remove-expected.txt) (output):
1463
1464 ```
1465 This tests the DOM 4 remove method on a Comment.
1466
1467 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
1468
1469
1470 PASS testDiv.childNodes.length is 1
1471 PASS testDiv.childNodes.length is 0
1472 PASS testDiv.childNodes.length is 0
1473 PASS successfullyParsed is true
1474
1475 TEST COMPLETE
1476 ```
1477
1478 `description` function specifies the description of this test, and subsequent shouldBe calls takes two strings,
1479 both of which are evaluated as JavaScript and then compared.
1480
1481 Some old js-test-pre.js tests may put its test code in a separate JS file but we don’t do that anymore to keep all the test code in one place.
1482
1483 [js-test.js](https://github.com/WebKit/WebKit/blob/main/LayoutTests/resources/js-test.js) and [js-test-pre.js](https://github.com/WebKit/WebKit/blob/main/LayoutTests/resources/js-test-pre.js) provide all kinds of other assertion and helper functions.
1484 Here are some examples:
1485
1486 * `debug(msg)` - Inserts a debug / log string in the output.
1487 * `evalAndLog(code)` - Similar to `debug()` but evaluates code as JavaScript.
1488 * `shouldNotBe(a, b)` - Generates `PASS` if the results of evaluating `a` and `b` differ.
1489 * `shouldBeTrue(code)` - Shorthand for `shouldBe(code, 'true')`.
1490 * `shouldBeFalse(code)` - Shorthand for `shouldBe(code, 'false')`.
1491 * `shouldBeNaN(code)` - Shorthand for `shouldBe(code, 'NaN')`.
1492 * `shouldBeNull(code)` - Shorthand for `shouldBe(code, 'null')`.
1493 * `shouldBeZero(code)` - Shorthand for `shouldBe(code, '0')`.
1494 * `shouldBeEqualToString(code, string)` - Similar to `shouldBe` but the second argument is not evaluated as string.
1495 * `finishJSTest()` - When js-test.js style test needs to do some async work, define the global variable named jsTestIsAsync and set it to true. When the test is done, call this function to notify the test runner (don’t call `testRunner.notifyDone` mentioned later directly). See [an example](https://github.com/WebKit/WebKit/blob/main/LayoutTests/fast/dom/iframe-innerWidth.html).
1496
1497 **It’s important to note that these shouldX functions only add output strings that say PASS or FAIL. If the expected result also contains the same FAIL strings, then run-webkit-tests will consider the whole test file to have passed.**
1498
1499 Another way to think about this is that `-expected.txt` files are baseline outputs, and baseline outputs can contain known failures.
1500
1501 There is a helper script to create a template for a new js-test.js test. The following will create new test named `new-test.html` in [LayoutTests/fast/dom](https://github.com/WebKit/WebKit/tree/main/LayoutTests/fast/dom):
1502
1503 ```sh
1504 Tools/Scripts/make-new-script-test fast/dom/new-test.html
1505 ```
1506
1507 ### dump-as-markup.js Tests
1508
1509 A dump-as-markup.js test is yet another variant of dumpAsText test,
1510 which uses [LayoutTests/resources/dump-as-markup.js](https://github.com/WebKit/WebKit/blob/main/LayoutTests/resources/dump-as-markup.js).
1511 This style of test is used when it’s desirable to compare the state of the DOM tree before and after some operations.
1512 For example, many tests under [LayoutTests/editing](https://github.com/WebKit/WebKit/tree/main/LayoutTests/editing)
1513 use this style of testing to test complex DOM mutation operations such as pasting HTML from the users’ clipboard.
1514 dump-as-markup.js adds `Markup` on the global object and exposes a few helper functions.
1515 Like js-test.js tests, a test description can be specified via `Markup.description`.
1516 The test then involves `Markup.dump(node, description)` to serialize the state of DOM tree as plain text
1517 where `element` is either a DOM [node](https://developer.mozilla.org/en-US/docs/Web/API/Node)
1518 under which the state should be serialized or its [id](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id).
1519
1520 For example, [LayoutTests/editing/inserting/insert-list-in-table-cell-01.html](https://github.com/WebKit/WebKit/blob/main/LayoutTests/editing/inserting/insert-list-in-table-cell-01.html) is written as follows:
1521
1522 ```html
1523 <!DOCTYPE html>
1524 <div id="container" contenteditable="true"><table border="1"><tr><td id="element">fsdf</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>
1525 <script src="../editing.js"></script>
1526 <script src="../../resources/dump-as-markup.js"></script>
1527 <script>
1528     Markup.description('Insert list items in a single table cell:');
1529
1530     var e = document.getElementById("element");
1531     setSelectionCommand(e, 0, e, 1);
1532     Markup.dump('container', 'Before');
1533
1534     document.execCommand("insertOrderedList");
1535     Markup.dump('container', 'After');
1536 </script>
1537 ```
1538
1539 with the following [expected result](https://github.com/WebKit/WebKit/blob/main/LayoutTests/editing/inserting/insert-list-in-table-cell-01-expected.txt):
1540
1541 ```
1542 Insert list items in a single table cell:
1543
1544 Before:
1545 | <table>
1546 |   border="1"
1547 |   <tbody>
1548 |     <tr>
1549 |       <td>
1550 |         id="element"
1551 |         "<#selection-anchor>fsdf<#selection-focus>"
1552 |       <td>
1553 |         "fsdf"
1554 |     <tr>
1555 |       <td>
1556 |         "gghfg"
1557 |       <td>
1558 |         "fsfg"
1559
1560 After:
1561 | <table>
1562 |   border="1"
1563 |   <tbody>
1564 |     <tr>
1565 |       <td>
1566 |         id="element"
1567 |         <ol>
1568 |           <li>
1569 |             "<#selection-anchor>fsdf<#selection-focus>"
1570 |             <br>
1571 |       <td>
1572 |         "fsdf"
1573 |     <tr>
1574 |       <td>
1575 |         "gghfg"
1576 |       <td>
1577 |         "fsfg"
1578 ```
1579
1580 ### testharness.js Tests
1581
1582 This is yet another variant of dumpAsText test which uses the test harness of [Web Platform Tests](https://web-platform-tests.org/), 
1583 which is [W3C](https://www.w3.org/)’s official tests for the Web.
1584 There is an [extensive documentation](https://web-platform-tests.org/writing-tests/testharness-api.html) on how this harness works.
1585
1586 > As mentioned above, do not modify tests in [LayoutTests/imported/w3c/web-platform-tests](https://github.com/WebKit/WebKit/tree/main/LayoutTests/imported/w3c/web-platform-tests)
1587 unless the same test changes are made in Web Platform Tests’ primary repository.
1588
1589 ### Reference Tests
1590
1591 Reference tests are special in that they don’t have accompanying `-expected.txt` files.
1592 Instead, they have a matching or mismatching expected result file.
1593 Both the test file and the accompanying matching or mismatching expected result generate PNG outputs.
1594 The test passes if the PNG outputs of the test and the matching expected result are the same; the test fails otherwise.
1595 For a test with a mismatching expected result, the test passes if the PNG outputs of the test and the mismatching expected result are not the same, and fails if they are the same.
1596
1597 A matching expected result or a mismatching expected result can be specified in a few ways:
1598
1599 * The file with the same name as the test name except it ends with  `-expected.*` or `-ref.*` is a matching expected result for the test.
1600 * The file with the same name as the test name except it ends with  `-expected-mismatch.*` or `-notref.*` is a matching expected result for the test.
1601 * The file specified by a HTML link element in the test file with `match` relation: `<link rel=match href=X>` where X is the relative file path is a matching expected result.
1602 * The file specified by a HTML link element in the test file with `mismatch` relation: `<link rel=mismatch href=X>` where X is the relative file path is a mismatching expected result.
1603
1604 For example, [LayoutTests/imported/w3c/web-platform-tests/html/rendering/replaced-elements/images/space.html](https://github.com/WebKit/WebKit/blob/main/LayoutTests/imported/w3c/web-platform-tests/html/rendering/replaced-elements/images/space.html) specifies [space-ref.html](https://github.com/WebKit/WebKit/blob/main/LayoutTests/imported/w3c/web-platform-tests/html/rendering/replaced-elements/images/space-ref.html) in the same directory as the matching expected result as follows:
1605
1606 ```html
1607 <!doctype html>
1608 <meta charset=utf-8>
1609 <title>img hspace/vspace</title>
1610 <link rel=match href=space-ref.html>
1611 <style>
1612 span { background: blue; }
1613 </style>
1614 <div style=width:400px;>
1615 <p><span><img src=/images/green.png></span>
1616 <p><span><img src=/images/green.png hspace=10></span>
1617 <p><span><img src=/images/green.png vspace=10></span>
1618 <p><span><img src=/images/green.png hspace=10%></span>
1619 <p><span><img src=/images/green.png vspace=10%></span>
1620 </div>
1621 ```
1622
1623 ## Test Runners
1624
1625 Most layout tests are designed to be runnable inside a browser but run-webkit-tests uses a special program to run them.
1626 Our continuous integration system as well as the Early Warning System uses run-webkit-tests to run layout tests.
1627 In WebKit2, this is appropriately named [WebKitTestRunner](https://github.com/WebKit/WebKit/tree/main/Tools/WebKitTestRunner).
1628 In WebKit1 or WebKitLegacy, it’s [DumpRenderTree](https://github.com/WebKit/WebKit/tree/main/Tools/DumpRenderTree),
1629 which is named after the very first type of layout tests, which generated the text representation of the render tree.
1630
1631 ### Extra Interfaces Available in Test Runners
1632
1633 Both WebKitTestRunner and DumpRenderTree expose a few extra interfaces to JavaScript on `window` (i.e. global object) in order to emulate user inputs,
1634 enable or disable a feature, or to improve the reliability of testing.
1635
1636 * **[GCController](https://github.com/WebKit/WebKit/blob/main/Tools/WebKitTestRunner/InjectedBundle/Bindings/GCController.idl)**
1637     - `GCController.collect()` triggers a synchronous full garbage collection.
1638     This function is useful for testing crashes or erroneous premature collection of JS wrappers and leaks.
1639 * **[testRunner](https://github.com/WebKit/WebKit/blob/main/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl)**
1640     - TestRunner interface exposes many methods to control the behaviors of WebKitTestRunner and DumpRenderTree.
1641     Some the most commonly used methods are as follows:
1642     * `waitUntilDone()` / `notifyDone()` - These functions are useful when writing tests that involve asynchronous tasks
1643         which may require the test to continue running beyond when it finished loading.
1644         `testRunner.waitUntilDone()` makes WebKitTestRunner and DumpRenderTree not end the test when a layout test has finished loading.
1645         The test continues until `testRunner.notifyDone()` is called.
1646     * `dumpAsText(boolean dumpPixels)` - Makes WebKitTestRunner and DumpRenderTree output the plain text of the loaded page instead of the state of the render tree.
1647     * `overridePreference(DOMString preference, DOMString value)` - Overrides WebKit’s [preferences](https://github.com/WebKit/WebKit/tree/main/Source/WTF/Scripts/Preferences).
1648         For WebKitLegacy, these are defined in [Source/WebKitLegacy/mac/WebView/WebPreferences.h](https://github.com/WebKit/WebKit/tree/main/Source/WebKitLegacy/mac/WebView/WebPreferences.h) for macOS
1649         and [Source/WebKitLegacy/win/WebPreferences.h](https://github.com/WebKit/WebKit/tree/main/Source/WebKitLegacy/win/WebPreferences.h) for Windows.
1650 * **[eventSender](https://github.com/WebKit/WebKit/blob/main/Tools/WebKitTestRunner/InjectedBundle/Bindings/EventSendingController.idl)**
1651     - Exposes methods to emulate mouse, keyboard, and touch actions.
1652     **Use [ui-helpers.js](https://github.com/WebKit/WebKit/blob/main/LayoutTests/resources/ui-helper.js) script** instead of directly calling methods on this function.
1653     This will ensure the test will be most compatible with all the test configurations we have.
1654 * [**UIScriptController**](https://github.com/WebKit/WebKit/tree/main/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl)
1655      - Exposes methods to emulate user inputs like eventSender mostly on iOS WebKit2.
1656      **Use [ui-helpers.js](https://github.com/WebKit/WebKit/blob/main/LayoutTests/resources/ui-helper.js) script** instead of directly calling methods on this function.
1657      This will ensure the test will be most compatible with all the test configurations we have.
1658 * **[textInputController](https://github.com/WebKit/WebKit/blob/main/Tools/WebKitTestRunner/InjectedBundle/Bindings/TextInputController.idl)**
1659     - Exposes methods to test [input methods](https://en.wikipedia.org/wiki/Input_method).
1660
1661 Additionally, [WebCore/testing](https://github.com/WebKit/WebKit/tree/main/Source/WebCore/testing) exposes a few testing hooks to test its internals:
1662
1663 * **[internals](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/testing/Internals.idl)**
1664     - Exposes various hooks into WebCore that shouldn’t be part of WebKit or WebKitLegacy API.
1665 * [**internals.settings**](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/testing/InternalSettings.idl)
1666     - Exposes various WebCore settings and let tests override them.
1667     Note that WebKit layer code may depend on preferences in UI process and the aforementioned `testRunner.overridePreference` may need to be used instead.
1668     It’s in fact preferable to override the equivalent preference via `testRunner.overridePreference`
1669     unless you know for sure WebKit or WebKitLegacy layer of code isn’t affected by the setting you’re overriding.
1670
1671 ### Enabling or Disabling a Feature in Test Runners
1672
1673 FIXME: Mention test-runner-options
1674
1675 ## Test Harness Scripts
1676
1677 FIXME: Write about dump-as-markup.js, and ui-helper.js
1678
1679 ## Investigating Test Failures Observed on Bots
1680
1681 There are multiple tools to investigate test failures happening on our continuous integration system
1682 ([build.webkit.org](http://build.webkit.org/)).
1683 The most notable is flakiness dashboard:
1684 [results.webkit.org](https://results.webkit.org/)
1685
1686 FIXME: Write how to investigate a test failure.
1687
1688 ## Debugging Layout Tests in Xcode
1689
1690 The easiest way to debug a layout test is with WebKitTestRunner or DumpRenderTree.
1691 In Product > Scheme, select “All Source”.
1692
1693 In Product > Scheme > Edit Scheme, open “Run” tab.
1694 Pick WebKitTestRunner or DumpRenderTree, whichever is desired in “Executable”.
1695
1696 ![Screenshot of specifying DumpRenderTree as the target of "Run" scheme](resources/xcode-scheme-dumprendertree.png)
1697 Go to Arguments and specify the path to the layout tests being debugged relative to where the build directory is located.
1698 e.g. `../../LayoutTests/fast/dom/Element/element-traversal.html` if `WebKitBuild/Debug` is the build directory.
1699 ![Screenshot of Xcode specifying a layout test in an argument to DumpRenderTree](resources/xcode-scheme-layout-test.png)
1700 You may want to specify OS_ACTIVITY_MODE environmental variable to “disable”
1701 in order to suppress all the system logging that happens during the debugging session.
1702
1703 You may also want to specify `--no-timeout` option to prevent WebKitTestRunner or DumpRenderTree
1704 to stop the test after 30 seconds if you’re stepping through code.
1705
1706 Once this is done, you can run WebKitTestRunner or DumpRenderTree by going to Product > Perform Action > Run without Building.
1707
1708 Clicking on “Run” button may be significantly slower due to Xcode re-building every project and framework each time.
1709 You can disable this behavior by going to “Build” tab and unchecking boxes for all the frameworks involved for “Run”:
1710 ![Screenshot of Xcode unchecking build options for all but DumpRenderTree for "Run" scheme](resources/xcode-build-settings-for-run.png)
1711
1712 ### Attaching to WebContent Process
1713
1714 You may find Xcode fails to attach to WebContent or Networking process in the case of WebKitTestRunner.
1715 In those cases, attach a breakpoint in UIProcess code
1716 such as [`TestController::runTest` in WebKitTestRunner right before `TestInvocation::invoke` is called](https://github.com/WebKit/WebKit/blob/5f4c01f41527547ce2f82b812ad478e12b51239d/Tools/WebKitTestRunner/TestController.cpp#L1522).
1717 Once breakpoint is hit in the UIProcess, attach to `WebContent.Development` or `Networking.Development` process manually in Xcode via Debug > Attach to Process.
1718
1719 # Dive into API tests
1720
1721 FIXME: Talk about how to debug API tests.
1722
1723 # Logging in WebKit
1724
1725 ## Setup
1726
1727 Each framework (WebCore, WebKit, WebKitLegacy, WTF) enable their own logging infrastructure independently (though the infrastructure itself is shared). If you want to log a message, `#include` the relevant framework's `Logging.h` header. Then, you can use the macros below.
1728
1729 Beware that you can't `#include` multiple framework's `Logging.h` headers at the same time - they each define a macro `LOG_CHANNEL_PREFIX` which will conflict with each other. Only `#include` the `Logging.h` header from your specific framework.
1730
1731 If you want to do more advanced operations, like searching through the list of log channels, `#include` your framework's `LogInitialization.h` header. These do not conflict across frameworks, so you can do something like
1732
1733 ```
1734 #include "LogInitialization.h"
1735 #include <WebCore/LogInitialization.h>
1736 #include <WTF/LogInitialization.h>
1737 ```
1738
1739 Indeed, WebKit does this to initialize all frameworks' log channels during Web Process startup.
1740
1741 ## Logging messages
1742
1743 There are a few relevant macros for logging messages:
1744
1745 - `LOG()`: Log a printf-style message in debug builds. Requires you to name a logging channel to output to.
1746 - `LOG_WITH_STREAM()` Log an iostream-style message in debug builds. Requires you to name a logging channel to output to.
1747 - `RELEASE_LOG()`: Just like `LOG()` but logs in both debug and release builds. Requires you to name a logging channel to output to.
1748 - `WTFLogAlways()`: Mainly for local debugging, unconditionally output a message. Does not require a logging channel to output to.
1749
1750 Here's an example invocation of `LOG()`:
1751
1752 ```
1753 LOG(MediaQueries, "HTMLMediaElement %p selectNextSourceChild evaluating media queries", this);
1754 ```
1755
1756 That first argument is a log channel. These have 2 purposes:
1757
1758 - Individual channels can be enabled/disabled independently (So you can get all the WebGL logging without getting any Loading logging)
1759 - When multiple channels are enabled, and you're viewing the logs, you can search/filter by the channel
1760
1761 Here's an example invocation of `LOG_WITH_STREAM()`:
1762
1763 ```
1764 LOG_WITH_STREAM(Scrolling, stream << "ScrollingTree::commitTreeState - removing unvisited node " << nodeID);
1765 ```
1766
1767 The macro sets up a local variable named `stream` which the second argument can direct messages to. The second argument is a collection of statements - not expressions like `LOG()` and `RELEASE_LOG()`. So, you can do things like this:
1768
1769 ```
1770 LOG_WITH_STREAM(TheLogChannel,
1771     for (const auto& something : stuffToLog)
1772         stream << " " << something;
1773 );
1774 ```
1775
1776 The reason why (most of) these use macros is so the entire thing can be compiled out when logging is disabled. Consider this:
1777
1778 ```
1779 LOG(TheLogChannel, "The result is %d", someSuperComplicatedCalculation());
1780 ```
1781
1782 If these were not macros, you'd have to pay for `someSuperComplicatedCalculation()` whether logging is enabled or not.
1783
1784 ## Enabling and disabling log channels
1785
1786 Channels are enabled/disabled at startup by passing a carefully crafted string to `initializeLogChannelsIfNecessary()`. On the macOS and iOS ports, this string comes from the _defaults_ database. On other UNIX systems and Windows, it comes from environment variables.
1787
1788 You can read the grammar of this string in `initializeLogChannelsIfNecessary()`. Here is an example:
1789
1790 ```
1791 WebGL -Loading
1792 ```
1793
1794 You can also specify the string `all` to enable all logging.
1795
1796 On macOS/iOS and Windows, each framework has its own individually supplied string that it uses to enable its own logging channels. On Linux, all frameworks share the same string.
1797
1798 ### Linux
1799
1800 Set the `WEBKIT_DEBUG` environment variable.
1801
1802 ```
1803 WEBKIT_DEBUG=Scrolling Tools/Scripts/run-minibrowser --gtk --debug
1804 ```
1805
1806 ### macOS
1807
1808 On macOS, you can, for example, enable the `Language` log channel with these terminal commands:
1809
1810 ```
1811 for identifier in com.apple.WebKit.WebContent.Development com.apple.WebKit.WebContent org.webkit.MiniBrowser com.apple.WebKit.WebKitTestRunner org.webkit.DumpRenderTree -g /Users/$USER/Library/Containers/com.apple.Safari/Data/Library/Preferences/com.apple.Safari.plist; do
1812     for key in WTFLogging WebCoreLogging WebKitLogging WebKit2Logging; do
1813         defaults write ${identifier} "${key}" "Language"
1814     done
1815 done
1816 ```
1817
1818 You may also need to specify these strings to `com.apple.WebKit.WebContent.Development`, the global domain, or the Safari container, depending on what you're running.
1819
1820 You may also pass this key and value as an argument:
1821
1822 ```
1823 Tools/Scripts/run-minibrowser --debug -WebCoreLogging Scrolling
1824 ```
1825
1826 ### Windows
1827
1828 Set the `WebCoreLogging` environment variable.
1829
1830 ## Adding a new log channel
1831
1832 Simply add a line to your framework's `Logging.h` header. Depending on how the accompanying `Logging.cpp` file is set up, you may need to add a parallel line there. That should be all you need. It is acceptable to have log channels in different frameworks with the same name - this is what `LOG_CHANNEL_PREFIX` is for.