|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +tags: blog |
| 4 | +title: "Reviving the devtools support in Servo" |
| 5 | +date: 2024-09-20 |
| 6 | +summary: "You can now inspect the DOM tree, view styles, evaluate JavaScript, and read console messages in Servo!" |
| 7 | +categories: |
| 8 | +--- |
| 9 | + |
| 10 | +<figure class="_figr"><a href="{{ '/img/blog/devtools-inspector.png' | url }}"><img src="{{ '/img/blog/devtools-inspector.png' | url }}" |
| 11 | + alt="On the left, it shows the DOM inspector with the tree view, CSS list and computed properties views. On the right is servoshell with servo.org opened."></a> |
| 12 | +<figcaption>The HTML and CSS inspector is able to display the DOM elements and their attributes and CSS properties.</figcaption></figure> |
| 13 | + |
| 14 | +<span class=_floatmin></span>Servo has been working on improving our [Firefox devtools](https://firefox-source-docs.mozilla.org/devtools-user) support as part of the [Outreachy](https://www.outreachy.org) internship program since June, and we're thrilled to share significant progress. |
| 15 | + |
| 16 | +Devtools are a set of **browser web developer tools** that allows you to examine, edit, and debug HTML, CSS, and JavaScript. |
| 17 | +Servo leverages existing work from the Firefox devtools to inspect its own websites, employing the same open protocol that is used for connecting to other Firefox instances. |
| 18 | + |
| 19 | +While relying on a third party API allows us to offer this functionality without building it from scratch, it doesn't come without downsides. |
| 20 | +Back in June last year, with the release of Firefox 110, changes to the protocol **broke our previous implementation**. |
| 21 | +The core issue was that the message structure sent between Servo and Firefox for the devtools functionality had changed. |
| 22 | + |
| 23 | +To address this, we first updated an existing patch to fix the connection and list the webviews running in Servo ([@fabricedesre](https://github.com/fabricedesre), [@eerii](https://github.com/eerii), [@mrobinson](https://github.com/mrobinson), [#32475](https://github.com/servo/servo/pull/32475)). |
| 24 | +We also had to update the structure of some [actors](https://firefox-source-docs.mozilla.org/devtools/backend/actor-hierarchy.html) (pieces of code that respond to messages sent by Firefox with relevant information), since they changed significantly ([@eerii](https://github.com/eerii), [#32509](https://github.com/servo/servo/pull/32509)). |
| 25 | + |
| 26 | +One of the main challenges was figuring out the messages we needed to send back to Firefox. |
| 27 | +The [source code](https://searchfox.org/mozilla-central/source/devtools/server/actors) for their devtools implementation is very well commented and proved to be invaluable. |
| 28 | +However, it was also helpful to see the actual messages being sent. |
| 29 | +While Servo can show the ones it sends and receives, **debugging another instance of Firefox** to observe its messages was very useful. |
| 30 | +To facilitate this, we made a helper script ([@eerii](https://github.com/eerii), [#32684](https://github.com/servo/servo/pull/32684)) using [Wireshark](https://www.wireshark.org) to inspect the connection between the devtools client and server, allowing us to view the contents of each packet and search through them. |
| 31 | + |
| 32 | +**Support for the console** was fixed, enabling the execution of JavaScript code directly in Servo's webviews and displaying any warnings or errors that the page emits ([@eerii](https://github.com/eerii), [@mrobinson](https://github.com/mrobinson), [#32727](https://github.com/servo/servo/pull/32727)). |
| 33 | + |
| 34 | +<figure class="_figr"><a href="{{ '/img/blog/devtools-console.png' | url }}"><img src="{{ '/img/blog/devtools-console.png' | url }}" |
| 35 | + alt="Developer JavaScript console that shows commands and their results"></a> |
| 36 | +<figcaption>The JavaScript developer console now displays page logs. |
| 37 | +It can also run commands.</figcaption></figure> |
| 38 | + |
| 39 | +<span class=_floatmin></span>Finally, the most significant changes involved the **DOM inspector**. |
| 40 | +Tighter integration with Servo's script module was required to retrieve the properties of each element. |
| 41 | +Viewing CSS styles was particularly challenging, since they can come from many places, including the `style` attribute, a stylesheet, or from ancestors, but [@emilio](https://github.com/emilio) had great insight into where to look. |
| 42 | +As a result, it’s now possible to view the HTML tree, and add, remove, or modify any attribute or CSS property ([@eerii](https://github.com/eerii), [@mrobinson](https://github.com/mrobinson), [#32655](https://github.com/servo/servo/pull/32655), [#32884](https://github.com/servo/servo/pull/32884), [#32888](https://github.com/servo/servo/pull/32888), [#33025](https://github.com/servo/servo/pull/33025)). |
| 43 | + |
| 44 | +There is still work to be done. |
| 45 | +Some valuable features like the Network and Storage tabs are still not functional, and parts of the DOM inspector are still barebones. |
| 46 | +For example, now that flexbox is enabled by default ([@mrobinson](https://github.com/mrobinson), [#33186](https://github.com/servo/servo/pull/33186)), it would be a good idea to support it in the Layout panel. |
| 47 | +We’re working on **developer documentation** that will be available in the [Servo book](https://book.servo.org) to make future contributions easier. |
| 48 | + |
| 49 | +That said, the **Console** and **Inspector** support has largely landed, and you can enable them with the `--devtools` flag in servoshell. |
| 50 | +For a step-by-step guide on how to use Servo’s devtools, check out the new [devtools chapter](https://book.servo.org/hacking/using-devtools.html) in the Servo book. |
| 51 | +We'd love to hear your feedback on how these work and what additional features you'd find helpful in your workflow. |
| 52 | + |
| 53 | +Many thanks to [@eerii](https://github.com/eerii) and Outreachy for the internship that made this possible! |
| 54 | + |
| 55 | +<style> |
| 56 | + /* guaranteed minimum width for first paragraph after a float */ |
| 57 | + ._floatmin { |
| 58 | + display: block; |
| 59 | + width: 13em; |
| 60 | + overflow: hidden; |
| 61 | + } |
| 62 | + ._none { |
| 63 | + display: none; |
| 64 | + } |
| 65 | + ._fig:not(#specificity) { |
| 66 | + width: 33em; |
| 67 | + max-width: 100%; |
| 68 | + margin: 1em auto; |
| 69 | + } |
| 70 | + ._fig > ._flex { |
| 71 | + display: flex; |
| 72 | + } |
| 73 | + ._fig table { |
| 74 | + text-align: initial; |
| 75 | + } |
| 76 | + ._fig figcaption._notes { |
| 77 | + text-align: left; |
| 78 | + width: max-content; |
| 79 | + max-width: 100%; |
| 80 | + } |
| 81 | + ._figl:not(#specificity), |
| 82 | + ._figr:not(#specificity) { |
| 83 | + margin: 0 1em 1em; |
| 84 | + } |
| 85 | + ._figl { |
| 86 | + float: left; |
| 87 | + max-width: 100%; |
| 88 | + } |
| 89 | + ._figr { |
| 90 | + float: right; |
| 91 | + clear: right; |
| 92 | + max-width: 100%; |
| 93 | + } |
| 94 | + ._figl > figcaption, |
| 95 | + ._figr > figcaption, |
| 96 | + ._figl > iframe, |
| 97 | + ._figr > iframe, |
| 98 | + ._figl > video, |
| 99 | + ._figr > video, |
| 100 | + ._figl > a > img, |
| 101 | + ._figr > a > img { |
| 102 | + width: 33em; |
| 103 | + max-width: 100%; |
| 104 | + } |
| 105 | + ._runin { |
| 106 | + margin-bottom: 1em; |
| 107 | + } |
| 108 | + ._runin > p, |
| 109 | + ._runin > h2 { |
| 110 | + display: inline; |
| 111 | + } |
| 112 | + ._correction { |
| 113 | + max-width: 33em; |
| 114 | + margin: 1em auto; |
| 115 | + border-bottom: 1px solid; |
| 116 | + padding-bottom: 1em; |
| 117 | + } |
| 118 | + ._note { |
| 119 | + margin: 1em 1em; |
| 120 | + border-left: 1px solid; |
| 121 | + padding-left: 1em; |
| 122 | + opacity: 0.75; |
| 123 | + } |
| 124 | +</style> |
0 commit comments