Web Inspector: HTML Formatter - XML mode
authorjoepeck@webkit.org <joepeck@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 14 Sep 2019 02:16:00 +0000 (02:16 +0000)
committerjoepeck@webkit.org <joepeck@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 14 Sep 2019 02:16:00 +0000 (02:16 +0000)
https://bugs.webkit.org/show_bug.cgi?id=201758

Reviewed by Devin Rousso.

Source/WebInspectorUI:

* Tools/HTMLFormatter/index.html:
* Tools/SourceMaps/index.html:
Update Tools to more easily test XML.

* UserInterface/Proxies/FormatterWorkerProxy.js:
(WI.FormatterWorkerProxy.prototype.formatXML):
* UserInterface/Views/TextEditor.js:
(WI.TextEditor.prototype.hasFormatter):
(WI.TextEditor.prototype._startWorkerPrettyPrint):
Allow formatting XML content.

* UserInterface/Workers/Formatter/FormatterWorker.js:
(FormatterWorker.prototype.formatHTML):
(FormatterWorker.prototype.formatXML):
Expose "formatXML".

* UserInterface/Workers/Formatter/HTMLFormatter.js:
(HTMLFormatter.let.dom):
(HTMLFormatter):
(HTMLFormatter.prototype._shouldHaveNoChildren):
(HTMLFormatter.prototype._before):
(HTMLFormatter.prototype._after):
* UserInterface/Workers/Formatter/HTMLParser.js:
(HTMLParser.prototype.parseDocument):
* UserInterface/Workers/Formatter/HTMLTreeBuilderFormatter.js:
(HTMLTreeBuilderFormatter.prototype._isEmptyNode):
Give the HTMLFormatter and related classes an XML mode that
has less of the smarts of XML.

LayoutTests:

* inspector/formatting/formatting-xml-expected.txt: Added.
* inspector/formatting/formatting-xml.html: Added.
* inspector/formatting/resources/formatting-utilities.js:
(TestPage.registerInitializer.async.runFormattingTest):
* inspector/formatting/resources/xml-tests/atom-expected.xml: Added.
* inspector/formatting/resources/xml-tests/atom.xml: Added.
* inspector/formatting/resources/xml-tests/basic-expected.xml: Added.
* inspector/formatting/resources/xml-tests/basic.xml: Added.
* inspector/formatting/resources/xml-tests/rss-expected.xml: Added.
* inspector/formatting/resources/xml-tests/rss.xml: Added.
* inspector/formatting/resources/xml-tests/valid-html-invalid-xml-expected.xml: Added.
* inspector/formatting/resources/xml-tests/valid-html-invalid-xml.xml: Added.
* inspector/formatting/resources/xml-tests/xslt-expected.xml: Added.
* inspector/formatting/resources/xml-tests/xslt.xml: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@249867 268f45cc-cd09-0410-ab3c-d52691b4dbfc

23 files changed:
LayoutTests/ChangeLog
LayoutTests/inspector/formatting/formatting-xml-expected.txt [new file with mode: 0644]
LayoutTests/inspector/formatting/formatting-xml.html [new file with mode: 0644]
LayoutTests/inspector/formatting/resources/formatting-utilities.js
LayoutTests/inspector/formatting/resources/xml-tests/atom-expected.xml [new file with mode: 0644]
LayoutTests/inspector/formatting/resources/xml-tests/atom.xml [new file with mode: 0644]
LayoutTests/inspector/formatting/resources/xml-tests/basic-expected.xml [new file with mode: 0644]
LayoutTests/inspector/formatting/resources/xml-tests/basic.xml [new file with mode: 0644]
LayoutTests/inspector/formatting/resources/xml-tests/rss-expected.xml [new file with mode: 0644]
LayoutTests/inspector/formatting/resources/xml-tests/rss.xml [new file with mode: 0644]
LayoutTests/inspector/formatting/resources/xml-tests/valid-html-invalid-xml-expected.xml [new file with mode: 0644]
LayoutTests/inspector/formatting/resources/xml-tests/valid-html-invalid-xml.xml [new file with mode: 0644]
LayoutTests/inspector/formatting/resources/xml-tests/xslt-expected.xml [new file with mode: 0644]
LayoutTests/inspector/formatting/resources/xml-tests/xslt.xml [new file with mode: 0644]
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/Tools/HTMLFormatter/index.html
Source/WebInspectorUI/Tools/SourceMaps/index.html
Source/WebInspectorUI/UserInterface/Proxies/FormatterWorkerProxy.js
Source/WebInspectorUI/UserInterface/Views/TextEditor.js
Source/WebInspectorUI/UserInterface/Workers/Formatter/FormatterWorker.js
Source/WebInspectorUI/UserInterface/Workers/Formatter/HTMLFormatter.js
Source/WebInspectorUI/UserInterface/Workers/Formatter/HTMLParser.js
Source/WebInspectorUI/UserInterface/Workers/Formatter/HTMLTreeBuilderFormatter.js

index 48ff800..1c724b1 100644 (file)
@@ -1,5 +1,27 @@
 2019-09-13  Joseph Pecoraro  <pecoraro@apple.com>
 
+        Web Inspector: HTML Formatter - XML mode
+        https://bugs.webkit.org/show_bug.cgi?id=201758
+
+        Reviewed by Devin Rousso.
+
+        * inspector/formatting/formatting-xml-expected.txt: Added.
+        * inspector/formatting/formatting-xml.html: Added.
+        * inspector/formatting/resources/formatting-utilities.js:
+        (TestPage.registerInitializer.async.runFormattingTest):
+        * inspector/formatting/resources/xml-tests/atom-expected.xml: Added.
+        * inspector/formatting/resources/xml-tests/atom.xml: Added.
+        * inspector/formatting/resources/xml-tests/basic-expected.xml: Added.
+        * inspector/formatting/resources/xml-tests/basic.xml: Added.
+        * inspector/formatting/resources/xml-tests/rss-expected.xml: Added.
+        * inspector/formatting/resources/xml-tests/rss.xml: Added.
+        * inspector/formatting/resources/xml-tests/valid-html-invalid-xml-expected.xml: Added.
+        * inspector/formatting/resources/xml-tests/valid-html-invalid-xml.xml: Added.
+        * inspector/formatting/resources/xml-tests/xslt-expected.xml: Added.
+        * inspector/formatting/resources/xml-tests/xslt.xml: Added.
+
+2019-09-13  Joseph Pecoraro  <pecoraro@apple.com>
+
         Web Inspector: HTML Formatting: Handle infinite loop for incomplete script data
         https://bugs.webkit.org/show_bug.cgi?id=201769
 
diff --git a/LayoutTests/inspector/formatting/formatting-xml-expected.txt b/LayoutTests/inspector/formatting/formatting-xml-expected.txt
new file mode 100644 (file)
index 0000000..f06e748
--- /dev/null
@@ -0,0 +1,11 @@
+Test XML formatting.
+
+
+== Running test suite: HTMLFormatter.XML
+-- Running test case: HTMLFormatter.XML
+PASS: atom.xml
+PASS: basic.xml
+PASS: rss.xml
+PASS: valid-html-invalid-xml.xml
+PASS: xslt.xml
+
diff --git a/LayoutTests/inspector/formatting/formatting-xml.html b/LayoutTests/inspector/formatting/formatting-xml.html
new file mode 100644 (file)
index 0000000..855f044
--- /dev/null
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
+<script src="resources/formatting-utilities.js"></script>
+<script>
+function test()
+{
+    let suite = InspectorTest.createAsyncSuite("HTMLFormatter.XML");
+
+    addFormattingTests(suite, "text/xml", [
+        "resources/xml-tests/atom.xml",
+        "resources/xml-tests/basic.xml",
+        "resources/xml-tests/rss.xml",
+        "resources/xml-tests/valid-html-invalid-xml.xml",
+        "resources/xml-tests/xslt.xml",
+    ]);
+
+    suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body onload="runTest()">
+<p>Test XML formatting.</p>
+</body>
+</html>
index 2480612..d726b16 100644 (file)
@@ -51,6 +51,9 @@ TestPage.registerInitializer(function() {
             case "text/html":
                 workerProxy.formatHTML(testText, indentString, callback);
                 break;
+            case "text/xml":
+                workerProxy.formatXML(testText, indentString, callback);
+                break;
             }
         });
     }
diff --git a/LayoutTests/inspector/formatting/resources/xml-tests/atom-expected.xml b/LayoutTests/inspector/formatting/resources/xml-tests/atom-expected.xml
new file mode 100644 (file)
index 0000000..f6fa164
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<service xmlns="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom">
+    <atom:generator version="1.0-bcv3" uri="http://www.ibm.com/xmlns/prod/sn">
+        Example
+      </atom:generator>
+    <workspace xml:lang="en-US" xmlns:xml="http://www.w3.org/XML/1998/namespace">
+        <atom:title type="text">Moleskin</atom:title>
+
+        <collection href="http://example.com/weblogs/services/atom/joepeck/entries">
+            <atom:title type="text">Weblog Entries</atom:title>
+            <accept>application/atom+xml; type=entry</accept>
+            <categories href="http://example.com/weblogs/services/atom/joepeck/categories"/>
+        </collection>
+
+        <collection href="http://example.com/weblogs/services/atom/joepeck/media">
+            <atom:title type="text">Media Entries</atom:title>
+            <accept>video/x-msvideo</accept>
+            <accept>application/octet-stream</accept>
+            <accept>image/gif</accept>
+            <accept>text/html</accept>
+            <accept>image/jpeg</accept>
+            <accept>image/png</accept>
+            <accept>text/plain</accept>
+            <categories fixed="yes"/>
+        </collection>
+
+        <collection href="http://example.com/weblogs/services/atom/joepeck/comments">
+            <atom:title type="text">Comment Entries</atom:title>
+            <accept>application/atom+xml; type=entry</accept>
+            <categories fixed="yes"/>
+        </collection>
+    </workspace>
+</service>
diff --git a/LayoutTests/inspector/formatting/resources/xml-tests/atom.xml b/LayoutTests/inspector/formatting/resources/xml-tests/atom.xml
new file mode 100644 (file)
index 0000000..0429b89
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<service xmlns="http://www.w3.org/2007/app"
+         xmlns:atom="http://www.w3.org/2005/Atom">
+  <atom:generator version="1.0-bcv3" uri="http://www.ibm.com/xmlns/prod/sn">
+    Example
+  </atom:generator>
+  <workspace xml:lang="en-US" xmlns:xml="http://www.w3.org/XML/1998/namespace">
+    <atom:title type="text">Moleskin</atom:title>
+
+    <collection
+      href="http://example.com/weblogs/services/atom/joepeck/entries">
+      <atom:title type="text">Weblog Entries</atom:title>
+      <accept>application/atom+xml; type=entry</accept>
+      <categories
+        href="http://example.com/weblogs/services/atom/joepeck/categories" />
+    </collection>
+
+    <collection
+      href="http://example.com/weblogs/services/atom/joepeck/media">
+      <atom:title type="text">Media Entries</atom:title>
+      <accept>video/x-msvideo</accept>
+      <accept>application/octet-stream</accept>
+      <accept>image/gif</accept><accept>text/html</accept>
+      <accept>image/jpeg</accept><accept>image/png</accept>
+      <accept>text/plain</accept>
+      <categories fixed="yes" />
+    </collection>
+
+    <collection
+      href="http://example.com/weblogs/services/atom/joepeck/comments">
+      <atom:title type="text">Comment Entries</atom:title>
+      <accept>application/atom+xml; type=entry</accept>
+      <categories fixed="yes" />
+    </collection>
+  </workspace>
+</service>
diff --git a/LayoutTests/inspector/formatting/resources/xml-tests/basic-expected.xml b/LayoutTests/inspector/formatting/resources/xml-tests/basic-expected.xml
new file mode 100644 (file)
index 0000000..08c4f88
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<outer>
+    <inner>
+        <!--Comment-->
+    </inner>
+    <INNER attr="value"></INNER>
+    <INNER attr="value">content</INNER>
+    <INNER attr="value">
+        <empty/>
+        <empty/>
+    </INNER>
+</outer>
diff --git a/LayoutTests/inspector/formatting/resources/xml-tests/basic.xml b/LayoutTests/inspector/formatting/resources/xml-tests/basic.xml
new file mode 100644 (file)
index 0000000..da7167c
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><outer><inner><!--Comment--></inner><INNER attr="value"></INNER><INNER attr="value">content</INNER><INNER attr="value"><empty/> <empty /></INNER></outer>
diff --git a/LayoutTests/inspector/formatting/resources/xml-tests/rss-expected.xml b/LayoutTests/inspector/formatting/resources/xml-tests/rss-expected.xml
new file mode 100644 (file)
index 0000000..dad7f3b
--- /dev/null
@@ -0,0 +1,808 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
+
+    <channel>
+        <title>WebKit</title>
+        <atom:link href="https://webkit.org/feed/" rel="self" type="application/rss+xml"/>
+        <link>https://webkit.org</link>
+        <description>Open Source Web Browser Engine</description>
+        <lastBuildDate>Fri, 13 Sep 2019 02:46:20 +0000</lastBuildDate>
+        <language>en-US</language>
+        <sy:updatePeriod>
+               hourly  </sy:updatePeriod>
+        <sy:updateFrequency>
+               1       </sy:updateFrequency>
+        <generator>https://wordpress.org/?v=5.2.2</generator>
+        <item>
+            <title>WebGPU and WSL in Safari</title>
+            <link>https://webkit.org/blog/9528/webgpu-and-wsl-in-safari/</link>
+            <pubDate>Thu, 12 Sep 2019 17:00:42 +0000</pubDate>
+            <dc:creator>
+                <![CDATA[]]>
+            </dc:creator>
+            <category>
+                <![CDATA[Performance]]>
+            </category>
+
+            <guid isPermaLink="false">https://webkit.org/?p=9528</guid>
+            <description>
+                <![CDATA[WebGPU is a new API being developed by Apple and others in the W3C which enables high-performance 3D graphics and data-parallel computation on the Web.]]>
+            </description>
+            <content:encoded>
+                <![CDATA[<p>WebGPU is a new API <a href="https://github.com/gpuweb/gpuweb">being developed</a> by Apple and others in the W3C which enables high-performance 3D graphics and <a href="https://en.wikipedia.org/wiki/Data_parallelism">data-parallel computation</a> on the Web. This API represents a significant improvement over the existing WebGL API in both performance and ease of use. Starting in <a href="https://developer.apple.com/safari/technology-preview/">Safari Technology Preview</a> release 91, beta support is available for WebGPU API and WSL, our proposal for the WebGPU shading language.</p>
+                <p>A few months ago we discussed a <a href="https://webkit.org/blog/8482/web-high-level-shading-language/">proposal</a> for a new shading language called Web High-Level Shading Language, and began implementation as a proof of concept. Since then, we’ve shifted our approach to this new language, which I will discuss a little later in this post. With help from our friends at <a href="https://www.babylonjs.com/">Babylon.js</a> we were able to adapt a demo to work with WebGPU and Web Shading Language (WSL):</p>
+                <figure><video autoplay loop src="https://webkit.org/wp-content/uploads/WebGPUDemoVideo.mp4" style="width: 100%"></video></figure>
+                <p>You can <a href="https://webkit.org/demos/webgpu/babylon/oneHelmetWebGPU.html">see the demo in action</a> with Safari Technology Preview 91 or later, and with the WebGPU experimental feature enabled.<a name="footnoteOne" href="#footnotes" class="footnote">1</a> The demo utilizes many of the best features of WebGPU. Let&#8217;s dig in to see what make WebGPU work so well, and why we think WSL is a great choice for WebGPU.</p>
+                <h2>WebGPU JavaScript API</h2>
+                <p>Just like WebGL, the WebGPU API is accessed through JavaScript because most Web developers are already familiar with working in JavaScript. We expect to create a WebGPU API that is accessed through WebAssembly in the future.</p>
+                <h3>Pipeline State Objects and Bind Groups</h3>
+                <p>Most 3D applications render more than a single object. In WebGL, each of those objects requires a collection of state-changing calls before that object could be rendered. For example, rendering a single object in WebGL might look like:</p>
+                <pre><code class="js"><span class="identifier">gl</span>.<span class="identifier">UseProgram</span>(<span class="identifier">program1</span>);
+                <span class="identifier">gl</span>.<span class="identifier">frontFace</span>(<span class="identifier">gl</span>.<span class="identifier">CW</span>);
+                <span class="identifier">gl</span>.<span class="identifier">cullFace</span>(<span class="identifier">gl</span>.<span class="identifier">FRONT</span>);
+                <span class="identifier">gl</span>.<span class="identifier">blendEquationSeparate</span>(<span class="identifier">gl</span>.<span class="identifier">FUNC_ADD</span>, <span class="identifier">gl</span>.<span class="identifier">FUNC_MIN</span>);
+                <span class="identifier">gl</span>.<span class="identifier">blendFuncSeparate</span>(<span class="identifier">gl</span>.<span class="identifier">SRC_COLOR</span>, <span class="identifier">gl</span>.<span class="identifier">ZERO</span>, <span class="identifier">gl</span>.<span class="identifier">SRC_ALPHA</span>, <span class="identifier">gl</span>.<span class="identifier">ZERO</span>);
+                <span class="identifier">gl</span>.<span class="identifier">colorMask</span>(<span class="keyword literal">true</span>, <span class="keyword literal">false</span>, <span class="keyword literal">true</span>, <span class="keyword literal">true</span>);
+                <span class="identifier">gl</span>.<span class="identifier">depthMask</span>(<span class="keyword literal">true</span>);
+                <span class="identifier">gl</span>.<span class="identifier">stencilMask</span>(<span class="number">1</span>);
+                <span class="identifier">gl</span>.<span class="identifier">depthFunc</span>(<span class="identifier">gl</span>.<span class="identifier">GREATER</span>);
+                <span class="identifier">gl</span>.<span class="identifier">drawArrays</span>(<span class="identifier">gl</span>.<span class="identifier">TRIANGLES</span>, <span class="number">0</span>, <span class="identifier">count</span>);
+                </code></pre>
+                <p>On the other hand, rendering a single object in WebGPU might look like:</p>
+                <pre><code class="js"><span class="identifier">encoder</span>.<span class="identifier">setPipeline</span>(<span class="identifier">renderPipeline</span>);
+                <span class="identifier">encoder</span>.<span class="identifier">draw</span>(<span class="identifier">count</span>, <span class="number">1</span>, <span class="number">0</span>, <span class="number">0</span>);
+                </code></pre>
+                <p>All the pieces of state in the WebGL example are wrapped up into a single object in WebGPU, named a &#8220;<a href="https://github.com/gpuweb/gpuweb/blob/master/spec/index.bs#L664">pipeline state object</a>.&#8221; Though validating state is expensive, with WebGPU it is done once when the pipeline is created, outside of the core rendering loop. As a result, we can avoid performing expensive state analysis inside the draw call. Also, setting an entire pipeline state is a single function call, reducing the amount of &#8220;chatting&#8221; between Javascript and WebKit’s C++ browser engine.</p>
+                <p>Resources have a similar story. Most rendering algorithms require a set of resources in order to draw a particular material. In WebGL, each resource would be bound one-by-one, leading to code that looks like:</p>
+                <pre><code class="js"><span class="identifier">gl</span>.<span class="identifier">bindBufferRange</span>(<span class="identifier">gl</span>.<span class="identifier">UNIFORM_BUFFER</span>, <span class="number">0</span>, <span class="identifier">materialBuffer1</span>, <span class="number">0</span>, <span class="identifier">size1</span>);
+                <span class="identifier">gl</span>.<span class="identifier">bindBufferRange</span>(<span class="identifier">gl</span>.<span class="identifier">UNIFORM_BUFFER</span>, <span class="number">1</span>, <span class="identifier">materialBuffer2</span>, <span class="number">0</span>, <span class="identifier">size2</span>);
+                <span class="identifier">gl</span>.<span class="identifier">activeTexture</span>(<span class="number">0</span>);
+                <span class="identifier">gl</span>.<span class="identifier">bindTexture</span>(<span class="identifier">gl</span>.<span class="identifier">TEXTURE_2D</span>, <span class="identifier">materialTexture1</span>);
+                <span class="identifier">gl</span>.<span class="identifier">activeTexture</span>(<span class="number">1</span>);
+                <span class="identifier">gl</span>.<span class="identifier">bindTexture</span>(<span class="identifier">gl</span>.<span class="identifier">TEXTURE_2D</span>, <span class="identifier">materialTexture2</span>);
+                </code></pre>
+                <p>However, in WebGPU, resources are batched up into &#8220;<a href="https://github.com/gpuweb/gpuweb/blob/master/spec/index.bs#L572">bind groups</a>.&#8221; When using WebGPU, the behavior of the above code is represented as simply:</p>
+                <pre><code class="js"><span class="identifier">encoder</span>.<span class="identifier">setBindGroup</span>(<span class="number">0</span>, <span class="identifier">bindGroup</span>);
+                </code></pre>
+                <p>In both of these examples, multiple objects are gathered up together and baked into a hardware-dependent format, which is when the browser performs validation. Being able to separate object validation from object use means the application author has more control over when expensive operations occur in the lifecycle of their application.</p>
+                <h3>Run-time Performance</h3>
+                <p>We expect WebGPU to perform faster and handle larger workloads than WebGL. To measure performance, we adopted the test harness from our 2D graphics benchmark <a href="https://browserbench.org/MotionMark1.1/">MotionMark</a> and wrote two versions of a performance test that had a simple yet realistic workload, one in <a href="https://browserbench.org/MotionMark1.1/developer.html?test-interval=30&amp;display=minimal&amp;tiles=big&amp;controller=ramp&amp;frame-rate=50&amp;kalman-process-error=1&amp;kalman-measurement-error=4&amp;time-measurement=performance&amp;suite-name=3DGraphics&amp;test-name=TrianglesWebGL">WebGL</a> and the other in <a href="https://browserbench.org/MotionMark1.1/developer.html?test-interval=10&amp;display=minimal&amp;tiles=big&amp;controller=ramp&amp;frame-rate=50&amp;kalman-process-error=1&amp;kalman-measurement-error=4&amp;time-measurement=performance&amp;suite-name=3DGraphics&amp;test-name=TrianglesWebGPU">WebGPU</a>.</p>
+                <p>The test measures how many triangles with different properties can be drawn while maintaining 60 frames per second. Each triangle renders with a different draw call and bind group; this mimics the way many games render objects (like characters, explosions, bullets, or environment objects) in different draw calls with different resources. Because much of the validation logic in WebGPU is performed during the creation of the bind group instead of inside the draw call, both of these calls execute much faster than the equivalent calls in WebGL.</p>
+                <figure class="widescreen mattewhite"><img src="https://webkit.org/wp-content/uploads/WSLTrianglesBenchmark.png" alt=""  class="wp-image-9534" srcset="https://webkit.org/wp-content/uploads/WSLTrianglesBenchmark.png 1210w, https://webkit.org/wp-content/uploads/WSLTrianglesBenchmark-300x125.png 300w, https://webkit.org/wp-content/uploads/WSLTrianglesBenchmark-768x321.png 768w, https://webkit.org/wp-content/uploads/WSLTrianglesBenchmark-1024x428.png 1024w" sizes="(max-width: 1210px) 100vw, 1210px" /></figure>
+                <h2>Web Shading Language</h2>
+                <p>The WebGPU community group is actively discussing which shading language or languages should be supported by the specification. Last year, we <a href="https://webkit.org/blog/8482/web-high-level-shading-language/">proposed</a> a new shading language for WebGPU. We are pleased to announce that a beta version of this language is available in Safari Technology Preview 91.</p>
+                <p>Because of community feedback, our approach toward designing the language has evolved. Previously, we designed the language to be source-compatible with HLSL, but we realized this compatibility was not what the community was asking for. Many wanted the shading language to be as simple and as low-level as possible. That would make it an easier compile target for whichever language their development shop uses.</p>
+                <p>There are many Web developers using GLSL today in WebGL, so a potential browser accepting a different high level language, like HLSL, wouldn&#8217;t suit their needs well. In addition, a high-level language such as HLSL can&#8217;t be executed faithfully on every platform and graphics API that WebGPU is designed to execute on.</p>
+                <p>So, we decided to make the language more simple, low-level, and fast to compile, and renamed the language to Web Shading Language to match this pursuit.<a name="footnoteTwo" href="#footnotes" class="footnote">2</a></p>
+                <p>The name change reflects a shift in our approach, but the major tenets of WSL have not changed. It&#8217;s still a language that is high-performance. It&#8217;s still text-based, which integrates well with existing web technologies and culture. WSL&#8217;s semantics still bake in safety and portability. It still works great as a compile target. As expected for every web technology, the language is well-defined with a <a href="https://gpuweb.github.io/WSL/">robust specification</a>. And because the WebGPU Community Group owns the language, it matures in concert with the WebGPU API.</p>
+                <p>In an upcoming post, we’ll talk more about the technical details of this language update. Here, let’s discuss further about WSL’s performance characteristics.</p>
+                <h3>Wire Size</h3>
+                <p>The Babylon.js demo above demonstrates an area where WSL really shines. The shaders in the demo use complex <a href="https://en.wikipedia.org/wiki/Physically_based_rendering">physically-based</a> algorithms to draw with the highest realism possible. Babylon.js creates these complex shading algorithms by stitching together snippets of shader source code at run-time. This way, Babylon&#8217;s shaders are tuned at run-time to the specific type of content the application contains. Since WSL is a textual language like GLSL, this kind of workflow can be accomplished simply with string concatenation.</p>
+                <p>Building shaders by string concatenation and compiling them directly is a dramatic improvement over languages which cannot do this kind of manipulation easily, like bytecode-based languages. For these other languages, generation of shaders at run-time requires the execution of an additional compiler, written in JavaScript or WebAssembly, to compile the generated source text into the bytecode form.</p>
+                <p>This extra step slows down performance in two ways. First, the execution of the additional compiler takes time. Second, the compiler source would have to be served with the rest of the web page’s resources, which increases the page size and lengthens the loading time of the web page. On the other hand, since WSL’s format is textual, there’s no additional compile step; you can just write it and run it!</p>
+                <p>As a point of comparison, let’s take the Babylon.js demo shown above. Babylon.js renders scenes by joining GLSL shader snippets at runtime. When using WSL, Babylon.js would simply serve the WSL snippets just like they’re serving GLSL snippets today. To do the same with SPIR-V, Babylon.js would serve their shader snippets along with a compiler that compiles these textual snippets down to SPIR-V. Chrome recently <a href="https://www.youtube.com/watch?v=K2JzIUIHIhc">announced</a> their support for WebGPU with SPIR-V using the same demo. Here is a comparison of the gzipped wire sizes for the shaders as WSL, and that of the shaders as GLSL and the SPIR-V compiler:</p>
+                <figure class="widescreen mattewhite"><img src="https://webkit.org/wp-content/uploads/WSLGzippedWireSize.png" alt="" class="wp-image-9535" srcset="https://webkit.org/wp-content/uploads/WSLGzippedWireSize.png 1132w, https://webkit.org/wp-content/uploads/WSLGzippedWireSize-300x128.png 300w, https://webkit.org/wp-content/uploads/WSLGzippedWireSize-768x328.png 768w, https://webkit.org/wp-content/uploads/WSLGzippedWireSize-1024x438.png 1024w" sizes="(max-width: 1132px) 100vw, 1132px" /></figure>
+                <p>The top bar shows the wire size if Babylon.js used WSL directly. The middle bar shows the wire size of the GLSL source, plus the compiler that Babylon.js uses to compile their snippets into SPIR-V. The bottom bar shows the wire size if Babylon.js simply served the results of their SPIR-V compilation. Because of the dynamic nature of Babylon.js’s shaders, they assemble their shaders at runtime and compile them dynamically, so they require the SPIR-V compiler. However, other websites’ shaders may be more static, in which case they wouldn’t need the compiler and could serve the SPIR-V directly, like in the bottom bar in the graph above.</p>
+                <h3>Compilation Performance</h3>
+                <p>We&#8217;ve heard from developers that shader compilation performance is extremely important. One way the community group addressed this was designing WebGPU to support asynchronous compilation, which avoids blocking successive rendering commands. Asynchronous compilation isn’t a magic bullet, though. If the next rendering command uses a shader currently being compiled, that rendering command must wait for the compilation complete. So, we&#8217;ve put significant effort into making WSL compilation times fast.</p>
+                <p>The WebGPU community created a compute shader to demonstrate the flocking characteristics of &#8220;boids,&#8221; and we turned that sample into a <a href="https://webkit.org/demos/webgpu/compute-boids-compile.html">compiler performance benchmark</a>. Here we compare the compilation time of WSL with the run-time of the GLSL compiler to SPIR-V running as a WebAssembly library:</p>
+                <figure class="widescreen mattewhite"><img src="https://webkit.org/wp-content/uploads/WSLCompilationTime.png" alt="" class="wp-image-9536" srcset="https://webkit.org/wp-content/uploads/WSLCompilationTime.png 1082w, https://webkit.org/wp-content/uploads/WSLCompilationTime-300x131.png 300w, https://webkit.org/wp-content/uploads/WSLCompilationTime-768x335.png 768w, https://webkit.org/wp-content/uploads/WSLCompilationTime-1024x447.png 1024w" sizes="(max-width: 1082px) 100vw, 1082px" /></figure>
+                <p>As you can see, we’re continuing to optimize compilation performance, and it’s been increasing both throughout and after STP 91’s release.</p>
+                <h2>Give WebGPU a try!</h2>
+                <p>We&#8217;re very excited to have implemented a beta version of WebGPU and WSL in the latest version of Safari Technology Preview. Try it out and let us know how well it works for you! We&#8217;re interested in feedback so we can evolve the WebGPU and WSL language to better suit everyone&#8217;s needs.</p>
+                <p>And be sure to check out our <a href="https://webkit.org/demos/webgpu/">gallery of WebGPU samples</a>. We&#8217;ll be keeping this page updated with the latest demos. Many thanks to Sebastien Vandenberghe and David Catuhe from Babylon.js for their help with Babylon.js in Safari.</p>
+                <p>For more information, you can contact me at <a href="mailto:mmaxfield@apple.com">mmaxfield@apple.com</a> or <a href="http://twitter.com/Litherum">@Litherum</a>, or you can contact our evangelist, <a href="mailto:jond@apple.com">Jonathan Davis</a>.</p>
+                <p><a name="footnotes" class="footnote"></a><br />
+                <a href="#footnoteOne">1</a> To enable WebGPU beta support, in Develop menu, select Experimental Features > WebGPU.<br />
+                <a href="#footnoteTwo">2</a> We still pronounce it “whistle”, though.</p>
+                ]]>
+            </content:encoded>
+            <enclosure url="https://webkit.org/wp-content/uploads/WebGPUDemoVideo.mp4" length="2410187" type="video/mp4"/>
+        </item>
+        <item>
+            <title>Release Notes for Safari Technology Preview 91</title>
+            <link>https://webkit.org/blog/9526/release-notes-for-safari-technology-preview-91/</link>
+            <pubDate>Wed, 04 Sep 2019 17:00:52 +0000</pubDate>
+            <dc:creator>
+                <![CDATA[]]>
+            </dc:creator>
+            <category>
+                <![CDATA[Safari Technology Preview]]>
+            </category>
+
+            <guid isPermaLink="false">https://webkit.org/?p=9526</guid>
+            <description>
+                <![CDATA[Safari Technology Preview Release 91 is now available for download for macOS Mojave and the macOS Catalina beta.]]>
+            </description>
+            <content:encoded>
+                <![CDATA[<p><a href="https://webkit.org/blog/6017/introducing-safari-technology-preview/">Safari Technology Preview</a> Release 91 is now <a href="https://webkit.org/downloads/">available for download</a> for macOS Mojave and the macOS Catalina beta. If you already have Safari Technology Preview installed, you can update in the Software Update pane of System Preferences on macOS.</p>
+                <p>This release covers WebKit revisions <a href="https://trac.webkit.org/log?stop_rev=248705&amp;&amp;rev=249190&amp;limit=999">248705-249190</a>.</p>
+                <h3>Security</h3>
+                <ul>
+                <li>Disabled legacy TLS 1.0 and TLS 1.1 (<a href="https://trac.webkit.org/changeset/249019/webkit/">r249019</a>)</li>
+                </ul>
+                <h3>JavaScript API</h3>
+                <ul>
+                <li>Added a public API for unhandled promise rejections (<a href="https://trac.webkit.org/changeset/249058/webkit/">r249058</a>)</li>
+                <li>Added support for hashbang in ESNext (<a href="https://trac.webkit.org/changeset/248826/webkit/">r248826</a>)</li>
+                <li>Implemented optional chaining in ESNext (<a href="https://trac.webkit.org/changeset/248829/webkit/">r248829</a>)</li>
+                <li>Implemented <code>StaticRange</code> constructor (<a href="https://trac.webkit.org/changeset/249079/webkit/">r249079</a>)</li>
+                <li>Fixed <code>Date.prototype.toJSON</code> to not throw an exception if <code>toISOString</code> returns an object (<a href="https://trac.webkit.org/changeset/248876/webkit/">r248876</a>)</li>
+                <li>Fixed more missing exception checks in <code>String.prototype</code> (<a href="https://trac.webkit.org/changeset/248716/webkit/">r248716</a>)</li>
+                <li>Fixed a bad error message when <code>for-await-of</code> is used in a non-async function (<a href="https://trac.webkit.org/changeset/248711/webkit/">r248711</a>)</li>
+                <li>Fixed ProxyObject to not allow access to its target&#8217;s private properties (<a href="https://trac.webkit.org/changeset/248796/webkit/">r248796</a>)</li>
+                <li>Updated the Promise constructor to check argument before `Construct?&#8220; (<a href="https://trac.webkit.org/changeset/248787/webkit/">r248787</a>)</li>
+                <li>Updated <code>Promise.prototype.finally</code> to accept non-promise objects (<a href="https://trac.webkit.org/changeset/248793/webkit/">r248793</a>)</li>
+                </ul>
+                <h3>JavaScript Performance</h3>
+                <ul>
+                <li>Changed to avoid looking up the <code>join</code> function each time <code>Array.prototype.toString</code> is called (<a href="https://trac.webkit.org/changeset/248906/webkit/">r248906</a>)</li>
+                <li>Ensured <code>x?.y ?? z</code> is fast (<a href="https://trac.webkit.org/changeset/249117/webkit/">r249117</a>)</li>
+                </ul>
+                <h3>Media</h3>
+                <ul>
+                <li>Fixed firing <code>webkitpresentationmodechanged</code> twice when exiting picture-in-picture (<a href="https://trac.webkit.org/changeset/249141/webkit/">r249141</a>)</li>
+                <li>Updated to stop <code>MediaDevices</code> timer when stopping <code>MediaDevices</code> (<a href="https://trac.webkit.org/changeset/248853/webkit/">r248853</a>)</li>
+                <li>Fixed removing fullscreen element in a <code>requestAnimationFrame()</code> callback after <code>requestFullscreen()</code> leaving fullscreen in an inconsistent state (<a href="https://trac.webkit.org/changeset/249147/webkit/">r249147</a>)</li>
+                <li>Disabled devices should not be taken into account when searching for a capture device (<a href="https://trac.webkit.org/changeset/249154/webkit/">r249154</a>)</li>
+                </ul>
+                <h3>Web API</h3>
+                <ul>
+                <li>Started to expose Geolocation interfaces (<code>GeolocationPosition</code>, <code>GeolocationPositionError, and</code> <code>GeolocationCoordinates</code>) on the global <code>Window</code> object (<a href="https://trac.webkit.org/changeset/249066/webkit/">r249066</a>)</li>
+                <li>Fixed Emoji with variation selectors to be rendered in emoji style, not text style (<a href="https://trac.webkit.org/changeset/248815/webkit/">r248815</a>)</li>
+                <li>Changed SVG elements to become focusable when <code>focus</code> and <code>key</code> event listeners are added (<a href="https://trac.webkit.org/changeset/248983/webkit/">r248983</a>)</li>
+                <li>Changed the default tab index of <code>output</code> and <code>fieldset</code> to be -1 (<a href="https://trac.webkit.org/changeset/248914/webkit/">r248914</a>)</li>
+                </ul>
+                <h3>Rendering</h3>
+                <ul>
+                <li>Fixed drawing an animated image to a canvas via <code>drawImage</code> to draw the first frame (<a href="https://trac.webkit.org/changeset/249162/webkit/">r249162</a>)</li>
+                </ul>
+                <h3>Pointer Events</h3>
+                <ul>
+                <li>Fixed removing the capture element preventing future pointer events from being dispatched on macOS (<a href="https://trac.webkit.org/changeset/248855/webkit/">r248855</a>)</li>
+                </ul>
+                <h3>WebDriver</h3>
+                <ul>
+                <li>Fixed mouse buttons to be correctly printed in <code>SimulatedInputDispatcher</code> logging (<a href="https://trac.webkit.org/changeset/248715/webkit/">r248715</a>)</li>
+                </ul>
+                <h3>Web Inspector</h3>
+                <ul>
+                <li>Elements
+                <ul>
+                <li>Fixed issue where &#8220;Copy Rule&#8221; menu item copied commented out properties incorrectly (<a href="https://trac.webkit.org/changeset/249089/webkit/">r249089</a>)</li>
+                <li>Changed to automatically enable the event listener when setting a breakpoint on it in the Node details sidebar (<a href="https://trac.webkit.org/changeset/248765/webkit/">r248765</a>)</li>
+                <li>Changed the DOM tree to always be LTR, even in RTL mode (<a href="https://trac.webkit.org/changeset/248991/webkit/">r248991</a>)</li>
+                </ul>
+                </li>
+                <li>Network
+                <ul>
+                <li>Changed the Headers pane to always be LTR, even in RTL mode (<a href="https://trac.webkit.org/changeset/248889/webkit/">r248889</a>)</li>
+                </ul>
+                </li>
+                <li>Resources
+                <ul>
+                <li>Added syntax highlighting for more CSS media queries (<a href="https://trac.webkit.org/changeset/248810/webkit/">r248810</a>)</li>
+                <li>Added syntax highlighting for JavaScript <code>BigInt</code> (<a href="https://trac.webkit.org/changeset/248898/webkit/">r248898</a>, <a href="https://trac.webkit.org/changeset/248908/webkit/">r248908</a>)</li>
+                <li>Added pretty printing support for more modern JavaScript language features (<a href="https://trac.webkit.org/changeset/248760/webkit/">r248760</a>, <a href="https://trac.webkit.org/changeset/248785/webkit/">r248785</a>, <a href="https://trac.webkit.org/changeset/248922/webkit/">r248922</a>, <a href="https://trac.webkit.org/changeset/248923/webkit/">r248923</a>)</li>
+                <li>Fixed a CodeMirror issue where tabs were still used even when the &#8220;Prefer indent using&#8221; setting is set to &#8220;Spaces&#8221; (<a href="https://trac.webkit.org/changeset/248739/webkit/">r248739</a>)</li>
+                </ul>
+                </li>
+                <li>Debugger
+                <ul>
+                <li>Added a global breakpoint for pausing in the next microtask (<a href="https://trac.webkit.org/changeset/248894/webkit/">r248894</a>)</li>
+                <li>Fixed an issue where the Assertion Failures breakpoint didn’t work when inspecting a JSContext (<a href="https://trac.webkit.org/changeset/248891/webkit/">r248891</a>)</li>
+                </ul>
+                </li>
+                <li>Console
+                <ul>
+                <li>Implemented <code>queryHolders</code> Command Line API function (<a href="https://trac.webkit.org/changeset/248925/webkit/">r248925</a>)</li>
+                <li>Updated <code>console.dir</code> to start out expanded when given an object (<a href="https://trac.webkit.org/changeset/249034/webkit/">r249034</a>)</li>
+                <li>Created additional Command Line API functions for other <code>console</code> methods (<a href="https://trac.webkit.org/changeset/249078/webkit/">r249078</a>)</li>
+                <li>Changed the Console to always be LTR, even in RTL mode (<a href="https://trac.webkit.org/changeset/248766/webkit/">r248766</a>)</li>
+                </ul>
+                </li>
+                <li>Sources (Experimental)
+                <ul>
+                <li>Fixed an issue where the gear icon would move to the second line when the navigation sidebar is narrow (<a href="https://trac.webkit.org/changeset/248818/webkit/">r248818</a>)</li>
+                <li>Fixed an issue where the &#8220;No Filter Results&#8221; message was displayed on top of all of the other content, preventing any interaction (<a href="https://trac.webkit.org/changeset/248737/webkit/">r248737</a>)</li>
+                <li>Gave Origins their own icon in the navigation sidebar (<a href="https://trac.webkit.org/changeset/248912/webkit/">r248912</a>)</li>
+                <li>Moved the resource type scope bar to be next to the filter in the navigation sidebar (<a href="https://trac.webkit.org/changeset/248916/webkit/">r248916</a>, <a href="https://trac.webkit.org/changeset/248940/webkit/">r248940</a>)</li>
+                <li>Provided a way to create an arbitrary Inspector Style Sheet (<a href="https://trac.webkit.org/changeset/248753/webkit/">r248753</a>)</li>
+                </ul>
+                </li>
+                <li>Layers (Experimental)
+                <ul>
+                <li>Fixed the background of the 3D area not updating when transitioning to/from Dark Mode (<a href="https://trac.webkit.org/changeset/248735/webkit/">r248735</a>)</li>
+                </ul>
+                </li>
+                </ul>
+                <h3>WebGPU</h3>
+                <ul>
+                <li>Added unary plus (<a href="https://trac.webkit.org/changeset/248756/webkit/">r248756</a>)</li>
+                <li>Changed enums to not be shadowed by local variables (<a href="https://trac.webkit.org/changeset/248812/webkit/">r248812</a>)</li>
+                <li>Fixed WebGPU layers not showing up sometimes (<a href="https://trac.webkit.org/changeset/248879/webkit/">r248879</a>)</li>
+                <li>Implemented GPUErrors for and relax GPUBuffer validation rules (<a href="https://trac.webkit.org/changeset/249183/webkit/">r249183</a>)</li>
+                <li>Made <code>operator==</code> native and added bool matrices (<a href="https://trac.webkit.org/changeset/248795/webkit/">r248795</a>)</li>
+                <li>Updated matrices to have constructors that take a flattened list of scalars (<a href="https://trac.webkit.org/changeset/248754/webkit/">r248754</a>)</li>
+                <li>Updated vertex shader and fragment shader to be able to come from two different programs (<a href="https://trac.webkit.org/changeset/248993/webkit/">r248993</a>)</li>
+                </ul>
+                ]]>
+            </content:encoded>
+        </item>
+        <item>
+            <title>How Web Content Can Affect Power Usage</title>
+            <link>https://webkit.org/blog/8970/how-web-content-can-affect-power-usage/</link>
+            <pubDate>Tue, 27 Aug 2019 17:00:58 +0000</pubDate>
+            <dc:creator>
+                <![CDATA[]]>
+            </dc:creator>
+            <category>
+                <![CDATA[Performance]]>
+            </category>
+            <category>
+                <![CDATA[Web Inspector]]>
+            </category>
+
+            <guid isPermaLink="false">https://webkit.org/?p=8970</guid>
+            <description>
+                <![CDATA[Users spend a large proportion of their online time on mobile devices, and a significant fraction of the rest is users on untethered laptop computers.]]>
+            </description>
+            <content:encoded>
+                <![CDATA[<style>@media (prefers-color-scheme:dark) { figure picture img { filter: none; } }</style>
+                <p>Users spend a large proportion of their online time on mobile devices, and a significant fraction of the rest is users on untethered laptop computers. For both, battery life is critical. In this post, we&#8217;ll talk about factors that affect battery life, and how you, as a web developer, can make your pages more power efficient so that users can spend more time engaged with your content.</p>
+                <h2>What Draws Power?</h2>
+                <p>Most of the energy on mobile devices is consumed by a few major components:</p>
+                <ul>
+                <li>CPU (Main processor)</li>
+                <li>GPU (Graphics processing)</li>
+                <li>Networking (Wi-Fi and cellular radio chips)</li>
+                <li>Screen</li>
+                </ul>
+                <p>Screen power consumption is relatively constant and mostly under the user&#8217;s control (via screen on-time and brightness), but the other components, the CPU, GPU and networking hardware have high dynamic range when it comes to power consumption.</p>
+                <p>The system adapts the CPU and GPU performance based on the current tasks being processed, including, of course, rendering web pages that the user is interacting with in their web browser and other apps using web content. This is done through turning some components on or off, and by changing their <a href="https://en.wikipedia.org/wiki/Clock_rate">clock frequency</a>. In broad terms, the more performance that is required from the chips, the lower their power-efficiency. The hardware can ramp up to high performance very quickly (but at a large power cost), then rapidly go back to a more efficient <a href="https://software.intel.com/en-us/articles/power-management-states-p-states-c-states-and-package-c-states">low-power state</a>.</p>
+                <h2>General Principles for Good Power Usage</h2>
+                <p>To maximize battery life, you therefore want to reduce the amount of time spent in high-power states, and let the hardware go back to idle as much as possible.</p>
+                <p>For web developers, there are three states of interaction to think about:</p>
+                <ul>
+                <li>When the user is actively interacting with the content.</li>
+                <li>When the page is the frontmost, but the user is not interacting with it.</li>
+                <li>When the page is not the frontmost content.</li>
+                </ul>
+                <h3>Efficient user interaction</h3>
+                <p>Obviously it&#8217;s good to expend power at times when the user is interacting with the page. You want the page to load fast and respond quickly to touch. In many cases, the same optimizations that reduce time to first paint and time to user interactive will also reduce power usage. However, be cautious about continuing to load resources and to run script after the initial page load. The goal should be to get back to idle as fast as possible. In general, the less JavaScript that runs, the more power-efficient the page will be, because script is work on top of what the browser has already done to layout and paint the page.</p>
+                <p>Once the page has loaded, user interactions like scrolling and tapping will also ramp up the hardware power (mainly the CPU and GPU), which again makes sense, but make sure to go back to idle as soon as the user stops interacting. Also, try to stay on the browser &#8220;fast paths&#8221; — for example, normal page scrolling will be much more power-efficient than custom scrolling implemented in JavaScript.</p>
+                <h3>Drive idle power usage towards zero</h3>
+                <p>When the user is not interacting with the page, try to make the page use as little power as possible. For example:</p>
+                <ul>
+                <li>Minimize the use of timers to avoid waking up the CPU. Try to coalesce timer-based work into a few, infrequent timers. Lots of uncoordinated timers which trigger frequent CPU wake-ups are much worse than gathering that work into fewer chunks.</li>
+                <li>Minimize continually animating content, like animated images and auto-playing video. Be particularly vigilant to avoid &#8220;loading&#8221; spinner GIFs or CSS animations that continually trigger painting, even if you can&#8217;t see them. <a href="https://webkit.org/blog/8582/intersectionobserver-in-webkit/">IntersectionObserver</a> can be used to runs animations only when they are visible.</li>
+                <li>Use declarative animations (CSS <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/animation">Animations</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions">Transitions</a>) where possible. The browser can optimize these away when the animating content is not visible, and they are more efficient than script-driven animation.</li>
+                <li>Avoid network polling to obtain periodic updates from a server. Use <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API">WebSockets</a> or <a href="https://webkit.org/blog/7521/a-few-words-on-fetching-bytes/">Fetch</a> with a persistent connection, instead of polling.</li>
+                </ul>
+                <p>A page that is doing work when it should be idle will also be less responsive to user interaction, so minimizing background activity also improves responsiveness as well as battery life.</p>
+                <h3>Zero CPU usage while in the background</h3>
+                <p>There are various scenarios where a page becomes inactive (not the user&#8217;s primary focus), for instance:</p>
+                <ul>
+                <li>The user switches to a different tab.</li>
+                <li>The user switches to a different app.</li>
+                <li>The browser window is minimized.</li>
+                <li>The browser window is visible but is not the focused window.</li>
+                <li>The browser window is behind another window.</li>
+                <li>The space the window is on is not the current space.</li>
+                </ul>
+                <p>When a page becomes inactive, WebKit automatically takes steps to save power:</p>
+                <ul>
+                <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame"><code>requestAnimationFrame</code></a> is stopped.</li>
+                <li>CSS and SVG Animations are suspended.</li>
+                <li>Timers are throttled.</li>
+                </ul>
+                <p>In addition, WebKit takes advantage of features provided by the operating system to maximize efficiency:</p>
+                <ul>
+                <li>on iOS, tabs are completely suspended when possible.</li>
+                <li>on macOS, tabs participate in <a href="https://developer.apple.com/library/archive/documentation/Performance/Conceptual/power_efficiency_guidelines_osx/AppNap.html">App Nap</a>, which means that the web process for a tab that is not visually updating gets lower priority and has its timers throttled.</li>
+                </ul>
+                <p>However, pages can trigger CPU wake-ups via timers (<code>setTimeout</code> and <code>setInterval</code>), messages, network events, etc. You should avoid these when in the background as much as possible. There are two APIs that are useful for this:</p>
+                <ul>
+                <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API" target="_blank" rel="noopener noreferrer">Page Visibility API</a> provides a way to respond to a page transitioning to be in the background or foreground. This is a good way to avoid updating the UI while the page is in the background, then using the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/visibilitychange_event"><code>visibilitychange</code> event</a> to update the content when the page becomes visible.</li>
+                <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/blur_event" target="_blank" rel="noopener noreferrer"><code>blur</code> events</a> are sent whenever the page is no longer focused. In that case, a page may still be visible but it is not the currently focused window. Depending on the page, it can be a good idea to stop animations.</li>
+                </ul>
+                <p>The easiest way to find problems is Web Inspector’s Timelines. The recording should not show any event happening while the page is in the background.</p>
+                <h2>Hunting Power Inefficiencies</h2>
+                <p>Now that we know the main causes of power use by web pages and have given some general rules about creating power-efficient content, let&#8217;s talk about how to identify and fix issues that cause excessive power drain.</p>
+                <h3>Scripting</h3>
+                <p>As mentioned above, modern CPUs can ramp power use from very low, when the device is idle, to very high to meet the demands of user interaction and other tasks. Because of this, the CPU is a leading cause of battery life variance. CPU usage during page loading is a combination of work the browser engine does to load, parse and render resources, and in executing JavaScript. On many modern web pages, time spent executing JavaScript far exceeds the time spent by the browser in the rest of the loading process, so minimizing JavaScript execution time will have the biggest benefits for power.</p>
+                <p>The best way to measure CPU usage is with Web Inspector. As we showed in a previous post, the <a href="https://webkit.org/blog/8993/cpu-timeline-in-web-inspector/">timeline now shows</a> the CPU activity for any selected time range:</p>
+                <figure class="widescreen mattewhite"><picture><source srcset="https://webkit.org/wp-content/uploads/Web-Inspector-CPU-Timeline-Overview-Dark.png" media="(prefers-color-scheme: dark)" /><img style="width: 100%; max-width: 1189px;" src="https://webkit.org/wp-content/uploads/Web-Inspector-CPU-Timeline-Overview-Light.png" /></picture></figure>
+                <p>To use the CPU efficiently, WebKit distributes work over multiple cores when possible (and pages using Workers will also be able to make use of multiple cores). Web Inspector provides a breakdown of the threads running concurrently with the page&#8217;s main thread. For example, the following screenshot shows the threads while scrolling a page with complex rendering and video playback:</p>
+                <figure class="widescreen mattewhite"><picture><source srcset="https://webkit.org/wp-content/uploads/Power-heavy-website-dark.png" media="(prefers-color-scheme: dark)" /><img style="width: 100%; max-width: 1086px;" src="https://webkit.org/wp-content/uploads/Power-heavy-website-light.png" /></picture></figure>
+                <p>When looking for things to optimize, focus on the main thread, since that&#8217;s where your JavaScript is running (unless you&#8217;re using Workers), and use the &#8220;JavaScript and Events&#8221; timeline to understand what&#8217;s triggering your script. Perhaps you&#8217;re doing too much work in response to user or scroll events, or triggering updates of hidden elements from requestAnimationFrame. Be cognizant of work done by JavaScript libraries and third party scripts that you use on your page. To dig deeper, you can use Web Inspector&#8217;s <a href="https://webkit.org/blog/6539/introducing-jscs-new-sampling-profiler/">JavaScript profiler</a> to see where time is being spent.</p>
+                <p>Activity in &#8220;WebKit Threads&#8221; is mostly triggered by work related to JavaScript: JIT compilation and garbage collection, so reducing the amount of script that runs, and reducing the churn of JavaScript objects should lower this.</p>
+                <p>Various other system frameworks invoked by WebKit make use of threads, so &#8220;Other threads&#8221; include work done by those; the largest contributor to &#8220;Other thread&#8221; activity is painting, which we&#8217;ll talk about next.</p>
+                <h3>Painting</h3>
+                <p>Main thread CPU usage can also be triggered by lots of layout and painting; these are usually triggered by script, but a CSS animation of a property other than <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/transform"><code>transform</code></a>, <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/opacity"><code>opacity</code></a> and <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/filter"><code>filter</code></a> can also cause them. Looking at the “Layout and Rendering” timeline will help you understand what’s causing activity.</p>
+                <p>If the &#8220;Layout and Rendering&#8221; timeline shows painting but you can&#8217;t figure out what&#8217;s changing, turn on Paint Flashing:</p>
+                <figure>
+                <picture><source srcset="https://webkit.org/wp-content/uploads/Enable-Paint-Flashing-dark.png" media="(prefers-color-scheme: dark)" /><img style="width: 100%; max-width: 350px;" src="https://webkit.org/wp-content/uploads/Enable-Paint-Flashing-light.png" /></picture>
+                </figure>
+                <p>This will cause those paints to be briefly highlighted with a red overlay; you might have to scroll the page to see them. Be aware that WebKit keeps some &#8220;overdraw&#8221; tiles to allow for smooth scrolling, so paints that are not visible in the viewport can still be doing work to keep offscreen tiles up-to-date. If a paint shows in the timeline, it&#8217;s doing actual work.</p>
+                <p>In addition to causing power usage by the CPU, painting usually also triggers GPU work. WebKit on macOS and iOS uses the GPU for painting, and so triggering painting can cause significant increases in power. The additional CPU usage will often show under &#8220;Other threads&#8221; in the CPU Usage timeline.</p>
+                <p>The GPU is also used for <a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API"><code>&lt;canvas&gt;</code></a> rendering, both 2D canvas and WebGL/WebGPU. To minimize drawing, don&#8217;t call into the <code>&lt;canvas&gt;</code> APIs if the canvas content isn&#8217;t changing, and try to optimize your canvas drawing commands.</p>
+                <p>Many Mac laptops have two GPUs, an &#8220;integrated&#8221; GPU which is on the same die as the CPU, and is less powerful but more power-efficient, and a more powerful, but more power-hungry &#8220;discrete&#8221; GPU. WebKit will default to using the integrated GPU by default; you can request the discrete GPU using the <a href="https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.2.1"><code>powerPreference</code></a> context creation parameter, but only do this if you can justify the power cost.</p>
+                <h3>Networking</h3>
+                <p>Wireless networking can affect battery life in unexpected ways. Phones are the most affected due to their combination of powerful radios (the WiFi and cellular network chips) with a smaller battery. Unfortunately, measuring the power impact of networking is not easy outside of a lab, but can be reduced by following some simple rules.</p>
+                <p>The most direct way to reduce networking power usage is to maximize the use of the browser&#8217;s cache. All of the best practices for minimizing page load time also benefit the battery by reducing how long the radios need to be powered on.</p>
+                <p>Another important aspect is to group network requests together temporally. Any time a new request comes, the operating system needs to power on the radio, connect to the base station or cell tower, and transmit the bytes. After transmitting the packets, the radio remains powered for a small amount of time in case more packets are transmitted.</p>
+                <p>If a page transmits small amounts of data infrequently, the overhead can become larger than the energy required to transmit the data:</p>
+                <figure class="mattewhite"><img class="wp-image-8984" src="https://webkit.org/wp-content/uploads/Networking-Power-Overhead-of-two-small-transmissions.png" alt="Networking Power Overhead of transmitting 2 packets with a delay between them" srcset="https://webkit.org/wp-content/uploads/Networking-Power-Overhead-of-two-small-transmissions.png 1162w, https://webkit.org/wp-content/uploads/Networking-Power-Overhead-of-two-small-transmissions-300x137.png 300w, https://webkit.org/wp-content/uploads/Networking-Power-Overhead-of-two-small-transmissions-768x350.png 768w, https://webkit.org/wp-content/uploads/Networking-Power-Overhead-of-two-small-transmissions-1024x467.png 1024w" sizes="(max-width: 1162px) 100vw, 1162px" /></figure>
+                <p>Such issues can be discovered from Web Inspector in the <em>Network Requests</em> Timeline. For example, the following screenshot shows four separate requests (probably analytics) being sent over several seconds:</p>
+                <figure class="widescreen mattewhite"><picture><source srcset="https://webkit.org/wp-content/uploads/Network-requests-should-be-grouped-dark.png" media="(prefers-color-scheme: dark)" /><img style="width: 100%; max-width: 1076px;" src="https://webkit.org/wp-content/uploads/Network-requests-should-be-grouped-light.png" /></picture></figure>
+                <p>Sending all the requests at the same time would improve network power efficiency.</p>
+                <h2>Conclusion</h2>
+                <p>Webpages can be good citizens of battery life.</p>
+                <p>It’s important to measure the battery impact in Web Inspector and drive those costs down. Doing so improves the user experience and battery life.</p>
+                <p>The most direct way to improve battery life is to minimize CPU usage. The new Web Inspector provides a tool to monitor that over time.</p>
+                <p>To achieve great battery life the goals are:</p>
+                <ul>
+                <li>Drive CPU usage to zero in idle</li>
+                <li>Maximize performance during user interaction to quickly get back to idle</li>
+                </ul>
+                <p>If you have any questions, feel free to reach <a href="http://twitter.com/awfulben">me</a>, <a href="https://twitter.com/JosephPecoraro">Joseph Pecoraro</a>, <a href="https://twitter.com/dcrousso">Devin Rousso</a>, and of course <a href="https://twitter.com/jonathandavis">Jon Davis</a>.</p>
+                ]]>
+            </content:encoded>
+        </item>
+        <item>
+            <title>Release Notes for Safari Technology Preview 90</title>
+            <link>https://webkit.org/blog/9515/release-notes-for-safari-technology-preview-90/</link>
+            <pubDate>Wed, 21 Aug 2019 20:00:45 +0000</pubDate>
+            <dc:creator>
+                <![CDATA[]]>
+            </dc:creator>
+            <category>
+                <![CDATA[Safari Technology Preview]]>
+            </category>
+
+            <guid isPermaLink="false">https://webkit.org/?p=9515</guid>
+            <description>
+                <![CDATA[Safari Technology Preview Release 90 is now available for download for macOS Mojave and the macOS Catalina beta.]]>
+            </description>
+            <content:encoded>
+                <![CDATA[<p><a href="https://webkit.org/blog/6017/introducing-safari-technology-preview/">Safari Technology Preview</a> Release 90 is now <a href="https://webkit.org/downloads/">available for download</a> for macOS Mojave and the macOS Catalina beta. If you already have Safari Technology Preview installed, you can update in the Software Update pane of System Preferences on macOS.</p>
+                <p>This release covers WebKit revisions <a href="https://trac.webkit.org/log?stop_rev=248024&amp;&amp;rev=248705&amp;limit=999">248024-248705</a>.</p>
+                <h3>Web API</h3>
+                <ul>
+                <li>Fixed ping loads to not prevent page caching (<a href="https://trac.webkit.org/changeset/248265/webkit/">r248265</a>)</li>
+                <li>Prevented <code>autofocus</code> for cross-origin iframes (<a href="https://trac.webkit.org/changeset/248491/webkit/">r248491</a>)</li>
+                <li>Prevented navigations of frames about to get replaced by the result of evaluating javascript: URLs (<a href="https://trac.webkit.org/changeset/248410/webkit/">r248410</a>)</li>
+                <li>Updated <code>Element.outerHTML</code> to link missing attribute prefixes in some cases in HTML documents (<a href="https://trac.webkit.org/changeset/248042/webkit/">r248042</a>)</li>
+                <li>Updated the wrapper for <code>navigator.geolocation</code> to not become GC-collectable once its frame is detached (<a href="https://trac.webkit.org/changeset/248276/webkit/">r248276</a>)</li>
+                </ul>
+                <h3>Media</h3>
+                <ul>
+                <li>Fixed an issue where muted <code>&lt;video&gt;</code> elements could block the display from sleeping (<a href="https://trac.webkit.org/changeset/248387/webkit/">r248387</a>)</li>
+                </ul>
+                <h3>WebRTC</h3>
+                <ul>
+                <li>Fixed incorrect <code>this</code> in <code>negotiationneeded</code> event (<a href="https://trac.webkit.org/changeset/248267/webkit/">r248267</a>)</li>
+                </ul>
+                <h3>WebGPU</h3>
+                <ul>
+                <li>Changed WebGPU to not force discrete GPU (<a href="https://trac.webkit.org/changeset/248704/webkit/">r248704</a>)</li>
+                <li>Improved WHLSL compile-time performance (<a href="https://trac.webkit.org/changeset/248025/webkit/">r248025,</a><a href="https://trac.webkit.org/changeset/248141/webkit/">r248141</a>, <a href="https://trac.webkit.org/changeset/248280/webkit/">r248280</a>, <a href="https://trac.webkit.org/changeset/248310/webkit/">r248310</a>, <a href="https://trac.webkit.org/changeset/248083/webkit/">r248083</a>)</li>
+                <li>Removed <code>char</code>, <code>short</code>, and <code>half</code> types (<a href="https://trac.webkit.org/changeset/248078/webkit/">r248078</a>)</li>
+                </ul>
+                <h3>Web Inspector</h3>
+                <ul>
+                <li>Elements
+                <ul>
+                <li>Added a way to disable or set a breakpoint on all event listeners for a given DOM node or event type in the Node details sidebar panel (<a href="https://trac.webkit.org/changeset/248052/webkit/">r248052</a>)</li>
+                <li>Added showing <code>@supports</code> CSS groupings in the Styles details sidebar panel (<a href="https://trac.webkit.org/changeset/248602/webkit/">r248602</a>)</li>
+                <li>Added experimental quick-action icon buttons to each CSS rule in the Styles details sidebar panel (<a href="https://trac.webkit.org/changeset/248202/webkit/">r248202</a>)</li>
+                <li>Added display of radius values in Box Model section of the Computed details sidebar panel (<a href="https://trac.webkit.org/changeset/248328/webkit/">r248328</a>)</li>
+                <li>Fixed an issue where CSS variable swatches were not shown for <code>var()</code> with a fallback in the Styles details sidebar panel (<a href="https://trac.webkit.org/changeset/248279/webkit/">r248279</a>)</li>
+                <li>Fixed some RTL issues in the Computed details sidebar panel (<a href="https://trac.webkit.org/changeset/248390/webkit/">r248390</a>, <a href="https://trac.webkit.org/changeset/248311/webkit/">r248311</a>)</li>
+                <li>Moved psuedo-selector rules before inherited rules in the Styles details sidebar panel (<a href="https://trac.webkit.org/changeset/248204/webkit/">r248204</a>)</li>
+                <li>Moved the Box Model section to the top of the Computed details sidebar panel (<a href="https://trac.webkit.org/changeset/248683/webkit/">r248683</a>)</li>
+                </ul>
+                </li>
+                <li>Resources
+                <ul>
+                <li>Fixed brotli-compressed resources to correctly show as being compressed in the Resources details sidebar (<a href="https://trac.webkit.org/changeset/248284/webkit/">r248284</a>)</li>
+                <li>Fixed to properly handle CSS comments with an escape character when pretty printing (<a href="https://trac.webkit.org/changeset/248197/webkit/">r248197</a>)</li>
+                </ul>
+                </li>
+                <li>Debugger
+                <ul>
+                <li>Added a global breakpoint for &#8220;All Events&#8221; which will pause whenever any event listener is about to be fired (<a href="https://trac.webkit.org/changeset/248201/webkit/">r248201</a>)</li>
+                </ul>
+                </li>
+                <li>Timelines
+                <ul>
+                <li>Made Heap Snapshots searchable (<a href="https://trac.webkit.org/changeset/248198/webkit/">r248198</a>)</li>
+                <li>Fixed an issue where <strong>Develop</strong> > <strong>Start Timeline Recording</strong> didn’t work when focused on a detached Web Inspector window (<a href="https://trac.webkit.org/changeset/248177/webkit/">r248177</a>)</li>
+                </ul>
+                </li>
+                <li>Console
+                <ul>
+                <li>Changed to always show all navigation items in the header area of the split console (<a href="https://trac.webkit.org/changeset/248180/webkit/">r248180</a>)</li>
+                <li>Fixed issue where the execution context picker didn’t update when switching to the inferred context from <code>auto</code> (<a href="https://trac.webkit.org/changeset/248196/webkit/">r248196</a>)</li>
+                <li>Provided a way to set an alias for previous console evaluation values (e.g. <code>$0</code>, <code>$1</code>, &#8230;,  <code>$99</code>) in case the inspected page has variables with the same name (<a href="https://trac.webkit.org/changeset/248287/webkit/">r248287</a>)</li>
+                <li>Renamed <code>queryObjects</code> console command line API to <code>queryInstances</code> for clarity (<a href="https://trac.webkit.org/changeset/248434/webkit/">r248434</a>)</li>
+                <li>Supported <code>console.screenshot</code> with dataURL strings (<a href="https://trac.webkit.org/changeset/248688/webkit/">r248688</a>)</li>
+                </ul>
+                </li>
+                <li>Overlay
+                <ul>
+                <li>Changed to show page width and height information (<a href="https://trac.webkit.org/changeset/248053/webkit/">r248053</a>)</li>
+                </ul>
+                </li>
+                <li>Settings
+                <ul>
+                <li>Added an Engineering pane to expose useful settings for WebKit engineers (<a href="https://trac.webkit.org/changeset/248391/webkit/">r248391</a>)</li>
+                </ul>
+                </li>
+                </ul>
+                <h3>Bug Fixes</h3>
+                <ul>
+                <li>Fixed dragging an image from Safari to Notes to correctly appear (<a href="https://trac.webkit.org/changeset/248166/webkit/">r248166</a>)</li>
+                </ul>
+                ]]>
+            </content:encoded>
+        </item>
+        <item>
+            <title>Announcing the WebKit Tracking Prevention Policy</title>
+            <link>https://webkit.org/blog/9507/announcing-the-webkit-tracking-prevention-policy/</link>
+            <pubDate>Wed, 14 Aug 2019 22:44:55 +0000</pubDate>
+            <dc:creator>
+                <![CDATA[]]>
+            </dc:creator>
+            <category>
+                <![CDATA[News]]>
+            </category>
+            <category>
+                <![CDATA[Privacy]]>
+            </category>
+
+            <guid isPermaLink="false">https://webkit.org/?p=9507</guid>
+            <description>
+                <![CDATA[Today we are publishing the WebKit Tracking Prevention Policy, covering: What types of tracking WebKit will prevent.]]>
+            </description>
+            <content:encoded>
+                <![CDATA[<p>Today we are publishing the <a href="https://webkit.org/tracking-prevention-policy">WebKit Tracking Prevention Policy</a>, covering:</p>
+                <ul>
+                <li>What types of tracking WebKit will prevent.</li>
+                <li>When other tracking countermeasures come into play such as limiting capabilities and informed user consent.</li>
+                <li>How WebKit handles unintended impact of our tracking prevention.</li>
+                </ul>
+                <p>We’d like to thank Mozilla for their <a href="https://wiki.mozilla.org/Security/Anti_tracking_policy">anti-tracking policy</a> which served as inspiration for ours.</p>
+                <p>Please send us your comments or questions about this policy to <a href="https://twitter.com/webkit">@webkit</a> on Twitter.</p>
+                ]]>
+            </content:encoded>
+        </item>
+        <item>
+            <title>Release Notes for Safari Technology Preview 89</title>
+            <link>https://webkit.org/blog/9497/release-notes-for-safari-technology-preview-89/</link>
+            <pubDate>Wed, 07 Aug 2019 17:00:11 +0000</pubDate>
+            <dc:creator>
+                <![CDATA[]]>
+            </dc:creator>
+            <category>
+                <![CDATA[Safari Technology Preview]]>
+            </category>
+
+            <guid isPermaLink="false">https://webkit.org/?p=9497</guid>
+            <description>
+                <![CDATA[Safari Technology Preview Release 89 is now available for download for macOS Mojave and the macOS Catalina beta.]]>
+            </description>
+            <content:encoded>
+                <![CDATA[<p><a href="https://webkit.org/blog/6017/introducing-safari-technology-preview/">Safari Technology Preview</a> Release 89 is now <a href="https://webkit.org/downloads/">available for download</a> for macOS Mojave and the macOS Catalina beta. If you already have Safari Technology Preview installed, you can update in the Software Update pane of System Preferences on macOS.</p>
+                <p>This release covers WebKit revisions <a href="https://trac.webkit.org/log?stop_rev=247433&amp;&amp;rev=248024&amp;limit=999">247433-248024</a>.</p>
+                <h3>JavaScript</h3>
+                <ul>
+                <li>Implemented nullish coalescing with the <code>??</code> operator for ESNext (<a href="https://trac.webkit.org/changeset/247819/webkit/">r247819</a>)</li>
+                </ul>
+                <h3>Web API</h3>
+                <ul>
+                <li>Added <code>referrerpolicy</code> attribute support for <code>&lt;script&gt;</code> elements (<a href="https://trac.webkit.org/changeset/247509/webkit/">r247509</a>)</li>
+                <li>Changed <code>window.openDatabase</code> to be overridable (<a href="https://trac.webkit.org/changeset/247434/webkit/">r247434</a>)</li>
+                <li>Fixed an IndexedDB error where the starting version change transaction may be neglected (<a href="https://trac.webkit.org/changeset/247649/webkit/">r247649</a>)</li>
+                <li>Fixed the ability to unbold selected text when the system font is used (<a href="https://trac.webkit.org/changeset/247439/webkit/">r247439</a>)</li>
+                <li>Made storing cross-origin top-level prefetches in HTTP cache optional (<a href="https://trac.webkit.org/changeset/247860/webkit/">r247860</a>)</li>
+                <li>Moving right by word boundary right before an object element followed by a <code>&lt;br&gt;</code> element hangs (<a href="https://trac.webkit.org/changeset/247881/webkit/">r247881</a>)</li>
+                <li>Removed support for <code>beforeload</code> on <code>link=prefetch</code> (<a href="https://trac.webkit.org/changeset/247481/webkit/">r247481</a>)</li>
+                </ul>
+                <h3>Compatibility</h3>
+                <ul>
+                <li>Fixed Daring Fireball long press highlights that were unnecessarily inflated due to false illegibility (<a href="https://trac.webkit.org/changeset/247792/webkit/">r247792</a>)</li>
+                <li>Fixed contextual menu actions for YouTube videos (<a href="https://trac.webkit.org/changeset/247901/webkit/">r247901</a>)</li>
+                </ul>
+                <h3>Accessibility</h3>
+                <ul>
+                <li>Exposed the <code>aria-label</code> attribute for <code>&lt;video&gt;</code> elements (<a href="https://trac.webkit.org/changeset/247891/webkit/">r247891</a>)</li>
+                </ul>
+                <h3>Media</h3>
+                <ul>
+                <li>Enabled a WebRTC debug mode without encryption (<a href="https://trac.webkit.org/changeset/247438/webkit/">r247438</a>)</li>
+                <li>Fixed support for FLAC-in-MP4 (<a href="https://trac.webkit.org/changeset/247934/webkit/">r247934</a>)</li>
+                </ul>
+                <h3>Web Inspector</h3>
+                <ul>
+                <li>Added support for <code>console.screenshot</code> with detached (not in main DOM tree) <code>&lt;img&gt;</code> and <code>&lt;picture&gt;</code> elements (<a href="https://trac.webkit.org/changeset/247814/webkit/">r247814</a>)</li>
+                <li>Added support for <code>console.screenshot</code> with <code>ImageData</code> and <code>ImageBitmap</code> (<a href="https://trac.webkit.org/changeset/247812/webkit/">r247812</a>)</li>
+                <li>Added a &#8220;Show Grid&#8221; navigation item for the Images collection in the Resources tab (<a href="https://trac.webkit.org/changeset/248004/webkit/">r248004</a>)</li>
+                <li>Added an indicator/separator around items in the Images collection in the Resources tab (<a href="https://trac.webkit.org/changeset/248019/webkit/">r248019</a>)</li>
+                <li>Add special case for <code>about:blank</code> resources to show &#8220;Resource has no content&#8221; message (<a href="https://trac.webkit.org/changeset/247747/webkit/">r247747</a>)</li>
+                <li>Fixed display of <code>application/xml</code> content for XHR requests (<a href="https://trac.webkit.org/changeset/247533/webkit/">r247533</a>)</li>
+                <li>Fixed issues toggling multiple breakpoints when they&#8217;re collapsed into one line (<a href="https://trac.webkit.org/changeset/247639/webkit/">r247639</a>)</li>
+                <li>Fixed Command-X (⌘X) to cut selected properties in the Styles sidebar (<a href="https://trac.webkit.org/changeset/247760/webkit/">r247760</a>)</li>
+                <li>Made the Changes panel in the Elements Tab render with LTR text direction (<a href="https://trac.webkit.org/changeset/247492/webkit/">r247492</a>)</li>
+                </ul>
+                <h3>WebGPU</h3>
+                <ul>
+                <li>Implemented errors for GPURenderPipeline creation (<a href="https://trac.webkit.org/changeset/247764/webkit/">r247764</a>)</li>
+                <li>Added descriptive error messages in WHLSL (<a href="https://trac.webkit.org/changeset/247834/webkit/">r247834</a>)</li>
+                <li>Changed checker to <code>setError()</code> when a property access node can&#8217;t commit its base type in WHLSL (<a href="https://trac.webkit.org/changeset/247676/webkit/">r247676</a>)</li>
+                <li>Changed to return the zero-value enum in the enum-from-integer constructor when the integer is not a valid enum value in WHLSL (<a href="https://trac.webkit.org/changeset/247675/webkit/">r247675</a>)</li>
+                <li>Made enums work in WHLSL (<a href="https://trac.webkit.org/changeset/247666/webkit/">r247666</a>)</li>
+                <li>Updated matrix memory layout to match HLSL by laying out columns linearly in WHLSL (<a href="https://trac.webkit.org/changeset/247468/webkit/">r247468</a>)</li>
+                </ul>
+                ]]>
+            </content:encoded>
+        </item>
+        <item>
+            <title>Changing Page Settings on iOS Using Web Inspector</title>
+            <link>https://webkit.org/blog/9454/changing-page-settings-on-ios-using-web-inspector/</link>
+            <pubDate>Fri, 02 Aug 2019 05:56:25 +0000</pubDate>
+            <dc:creator>
+                <![CDATA[]]>
+            </dc:creator>
+            <category>
+                <![CDATA[Web Inspector]]>
+            </category>
+
+            <guid isPermaLink="false">https://webkit.org/?p=9454</guid>
+            <description>
+                <![CDATA[If you&#8217;ve ever used Web Inspector before, chances are you&#8217;ve used (or are at least familiar with) the Develop menu.]]>
+            </description>
+            <content:encoded>
+                <![CDATA[<style>figure picture img { width: 100%; }</style>
+                <style>@media (prefers-color-scheme:dark) { figure picture img { filter: none; } }</style>
+                <p>If you&#8217;ve ever used Web Inspector before, chances are you&#8217;ve used (or are at least familiar with) the <strong>Develop</strong> menu.  It holds action items and toggles for various settings of the browser, like whether local files (e.g. URLs beginning with <code>file://</code>) can be loaded or whether CSS is applied to each page.</p>
+                <figure class="widescreen mattewhite">
+                  <picture title="Develop Menu"><source srcset="https://webkit.org/wp-content/uploads/Develop_Menu_Dark.png" media="(prefers-color-scheme: dark)"><img src="https://webkit.org/wp-content/uploads/Develop_Menu_Light.png" style="max-width: 431px">
+                  </picture>
+                </figure>
+                <p>All of these items apply to the entire browser, meaning that if you <strong>Disable Styles</strong> on one page, every other page will be affected.</p>
+                <p>Additionally, these items have no effect when using Web Inspector to inspect a remote target, like an iOS device or simulator. Checking <strong>Disable Styles</strong> in the <strong>Develop</strong> menu will not have any affect on the remote target.</p>
+                <p>In order to support this development workflow, Web Inspector has added a device settings menu that allows these settings to be toggled per-page when being remotely inspected.</p>
+                <p>Clicking on the device settings menu icon will show a popover with many of the same settings as the <strong>Develop</strong> menu.</p>
+                <figure class="widescreen mattewhite">
+                  <picture title="Device Settings Menu"><source srcset="https://webkit.org/wp-content/uploads/Device_Settings_Menu_Dark.png" media="(prefers-color-scheme: dark)"><img src="https://webkit.org/wp-content/uploads/Device_Settings_Menu_Light.png" style="max-width: 1000px">
+                  </picture>
+                </figure>
+                <p>Since these settings apply per-page and only on the remote target, the corresponding actions in the <strong>Develop</strong> menu are disabled, as they have no effect on a remote target:</p>
+                <ul>
+                <li><strong>Disable Images</strong></li>
+                <li><strong>Disable Styles</strong></li>
+                <li><strong>Disable JavaScript</strong></li>
+                <li><strong>Disable Site-specific Hacks</strong></li>
+                <li><strong>Disable Cross-Origin Restrictions</strong></li>
+                <li>WebRTC
+                <ul>
+                <li><strong>Allow Media Capture on Insecure Sites</strong></li>
+                <li><strong>Disable ICE Candidate Restrictions</strong></li>
+                <li><strong>Use Mock Capture Devices</strong></li>
+                </ul>
+                </li>
+                </ul>
+                <p>Along these lines, the device settings menu is only shown when using Web Inspector to inspect a remote target.</p>
+                <p>Device settings are <em>not</em> preserved between Web Inspector sessions.  Closing Web Inspector (or disconnecting the inspected device) will cause all previously set device settings for the inspected page to reset.</p>
+                <p>Device settings are preserved across navigations, however, so long as Web Inspector stays open/connected.</p>
+                <h2 id="UserAgent">User Agent</h2>
+                <p>The first item in the device settings menu is the <strong>User Agent</strong> editor.  It contains a list of <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent">common user agents</a>, as well as an option to input a <a href="https://en.wikipedia.org/wiki/User_agent#Use_in_HTTP">custom user agent</a> (<strong>Other…</strong>).</p>
+                <p>Each time the <strong>User Agent</strong> is modified, the inspected page will automatically reload so that the new <strong>User Agent</strong> is applied.</p>
+                <h2 id="Disable">Disable Toggles</h2>
+                <p>Each of these toggles, when checked, disables a specific piece of functionality in the inspected page.</p>
+                <ul>
+                <li><strong>Images</strong> will prevent any not-yet loaded images from loading, but will have no effect on any already loaded images.</li>
+                <li><strong>Styles</strong> will immediately disable all CSS on the page, including inline <code>&lt;style&gt;</code>s and any <code>style</code> DOM attributes.</li>
+                <li><strong>JavaScript</strong> will cause the page to ignore any <em>future</em> JavaScript from being run, including new <code>&lt;script&gt;</code> elements (the underlying resource isn&#8217;t even requested) and callbacks for previously added event listeners.</li>
+                <li><strong>Site-specific Hacks</strong> controls whether workarounds are made by WebKit to support compatibility on certain sites.
+                <ul>
+                <li>A list of these sites can be found in <a href="https://trac.webkit.org/browser/webkit/trunk/Source/WebCore/page/Quirks.cpp">Source/WebCore/page/Quirks.cpp</a>.</li>
+                <li>If you develop a site that is found in that list, we <em>strongly</em> encourage developing and testing with <strong>Site-specific Hacks</strong> <em>disabled</em>.</li>
+                </ul>
+                </li>
+                <li><strong>Cross-Origin Restrictions</strong> controls whether <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS">CORS</a> rules/restrictions are active for any <em>future</em> network requests.</li>
+                </ul>
+                <h2 id="WebRTC">WebRTC Toggles</h2>
+                <p>These toggles focus specifically on functionality related to <a href="https://webrtc.org/">WebRTC</a>.</p>
+                <ul>
+                <li><strong>Allow Media Capture on Insecure Sites</strong> will allow <a href="https://webkit.org/blog/7726/announcing-webrtc-and-media-capture/">WebRTC media capture</a> to be used/tested on insecure (e.g. non-https) pages for any <em>future</em> calls of <code>getUserMedia</code>.</li>
+                <li><strong>Disable ICE Candidate Restrictions</strong> will prevent <a href="https://webkit.org/blog/7763/a-closer-look-into-webrtc/">host ICE candidates from being filtered</a> for <em>new</em> connection attempts.</li>
+                <li><strong>Use Mock Capture Devices</strong> will replace all <a href="https://webkit.org/blog/7726/announcing-webrtc-and-media-capture/">capture devices</a> with a mock &#8220;Bip-Bop&#8221; device for any <em>future</em> calls of <code>getUserMedia</code>.<br />
+                <figure style="margin: 0.5em"><img class="preserve-color wp-image-9459" src="https://webkit.org/wp-content/uploads/Mock_Capture_Device.png" title="Mock Capture Device" srcset="https://webkit.org/wp-content/uploads/Mock_Capture_Device.png 2580w, https://webkit.org/wp-content/uploads/Mock_Capture_Device-300x113.png 300w, https://webkit.org/wp-content/uploads/Mock_Capture_Device-768x290.png 768w, https://webkit.org/wp-content/uploads/Mock_Capture_Device-1024x387.png 1024w" sizes="(max-width: 2580px) 100vw, 2580px" /></figure>
+                </li>
+                <li><strong>Disable Encryption</strong> will cause <em>future</em> connections to be established and <em>future</em> streams (from those connections) to be transmitted <em>without</em> any form of encryption.</li>
+                </ul>
+                <h2>Feedback</h2>
+                <p>You can try out changing device settings with iOS 12.2 or later. Let us know how it works for you. Send feedback on Twitter (<a href="https://twitter.com/webkit">@webkit</a>, <a href="https://twitter.com/dcrousso">@dcrousso</a>) or by <a href="https://feedbackassistant.apple.com/">filing a bug</a>.</p>
+                ]]>
+            </content:encoded>
+        </item>
+        <item>
+            <title>Release Notes for Safari Technology Preview 88</title>
+            <link>https://webkit.org/blog/9445/release-notes-for-safari-technology-preview-88/</link>
+            <pubDate>Wed, 24 Jul 2019 17:00:59 +0000</pubDate>
+            <dc:creator>
+                <![CDATA[]]>
+            </dc:creator>
+            <category>
+                <![CDATA[Safari Technology Preview]]>
+            </category>
+
+            <guid isPermaLink="false">https://webkit.org/?p=9445</guid>
+            <description>
+                <![CDATA[Safari Technology Preview Release 88 is now available for download for macOS Mojave and the macOS Catalina beta.]]>
+            </description>
+            <content:encoded>
+                <![CDATA[<p><a href="https://webkit.org/blog/6017/introducing-safari-technology-preview/">Safari Technology Preview</a> Release 88 is now <a href="https://webkit.org/downloads/">available for download</a> for macOS Mojave and the macOS Catalina beta. If you already have Safari Technology Preview installed, you can update in the Software Update pane of System Preferences on macOS.</p>
+                <p>This release covers WebKit revisions <a href="https://trac.webkit.org/log?stop_rev=247047&amp;&amp;rev=247433&amp;limit=999">247047-247433</a>.</p>
+                <h3>JavaScript</h3>
+                <ul>
+                <li>Enabled <code>Intl.PluralRules</code> and <code>Intl.NumberFormatToParts</code> by default (<a href="https://trac.webkit.org/changeset/247247/webkit/">r247247</a>)</li>
+                </ul>
+                <h3>WebRTC</h3>
+                <ul>
+                <li>Registered a MediaStreamTrack as media producer only if it is a capture track (<a href="https://trac.webkit.org/changeset/247208/webkit/">r247208</a>, <a href="https://trac.webkit.org/changeset/247382/webkit/">r247382</a>)</li>
+                </ul>
+                <h3>Web API</h3>
+                <ul>
+                <li>Fixed XHR CORS requests getting logged twice on the server (<a href="https://trac.webkit.org/changeset/247276/webkit/">r247276</a>)</li>
+                </ul>
+                <h3>Pointer Events</h3>
+                <ul>
+                <li>Updated to respect pointer capture when dispatching mouse boundary events and updating <code>:hover</code> (<a href="https://trac.webkit.org/changeset/247148/webkit/">r247148</a>)</li>
+                </ul>
+                <h3>Rendering</h3>
+                <ul>
+                <li>Changed to avoid extra backing store on elements with <code>overflow: scroll</code> and <code>visibility: hidden</code> (<a href="https://trac.webkit.org/changeset/247420/webkit/">r247420</a>)</li>
+                <li>Changed to trigger a compositing update when a video element is changing (<a href="https://trac.webkit.org/changeset/247187/webkit/">r247187</a>)</li>
+                </ul>
+                <h3>Accessibility</h3>
+                <ul>
+                <li>Added accessibility announcement notifications to show, dismiss and selection change for the datalist suggestions view (<a href="https://trac.webkit.org/changeset/247418/webkit/">r247418</a>)</li>
+                <li>Exposed HTML datalist accessibility (<a href="https://trac.webkit.org/changeset/247295/webkit/">r247295</a>)</li>
+                <li>Enhanced support of <code>aria-haspopup</code> per ARIA 1.1 specification. (<a href="https://trac.webkit.org/changeset/247071/webkit/">r247071</a>)</li>
+                <li>Implemented support for ARIA roles: insertion, deletion, subscript, superscript, and time (<a href="https://trac.webkit.org/changeset/247349/webkit/">r247349</a>)</li>
+                <li>Fixed ignored <code>role="presentation"</code> on HTML <code>&lt;table&gt;</code> elements for VoiceOver (<a href="https://trac.webkit.org/changeset/247330/webkit/">r247330</a>)</li>
+                </ul>
+                <h3>WebGL</h3>
+                <ul>
+                <li>Hooked up WebGL&#8217;s back buffer in ANGLE backend on macOS (<a href="https://trac.webkit.org/changeset/247315/webkit/">r247315</a>)</li>
+                </ul>
+                <h3>WebGPU</h3>
+                <ul>
+                <li>Added most of the remainder of the standard library (<a href="https://trac.webkit.org/changeset/247174/webkit/">r247174</a>)</li>
+                <li>Implemented GPUError and error scopes (<a href="https://trac.webkit.org/changeset/247366/webkit/">r247366</a>)</li>
+                <li>Made the destructor of VariableDeclaration non-virtual (<a href="https://trac.webkit.org/changeset/247124/webkit/">r247124</a>)</li>
+                <li>Optimized the lexer (<a href="https://trac.webkit.org/changeset/247171/webkit/">r247171</a>)</li>
+                <li>Removed the phase resolveCallsInFunctions (<a href="https://trac.webkit.org/changeset/247170/webkit/">r247170</a>)</li>
+                </ul>
+                <h3>Web Inspector</h3>
+                <ul>
+                <li>Added support for pasting copied DOM nodes in the Elements tab (<a href="https://trac.webkit.org/changeset/247054/webkit/">r247054</a>)</li>
+                <li>Fixed dismissing a blank property to no longer cause the rule to appear in the Changes panel (<a href="https://trac.webkit.org/changeset/247406/webkit/">r247406</a>)</li>
+                <li>Fixed an issue where unbalanced quotes or parenthesis weren’t displayed as properly closed after editing values (<a href="https://trac.webkit.org/changeset/247196/webkit/">r247196</a>)</li>
+                <li>Updated descendant DOM breakpoints be enabled, disabled, or deleted from a collapsed parent (<a href="https://trac.webkit.org/changeset/247053/webkit/">r247053</a>)</li>
+                </ul>
+                <h3>Bug Fixes</h3>
+                <ul>
+                <li>Fixed paste from Notes into Excel 365 spreadsheet (<a href="https://trac.webkit.org/changeset/247222/webkit/">r247222</a>)</li>
+                <li>Fixed video playback on xfinity.com/stream on macOS Catalina (<a href="https://trac.webkit.org/changeset/247213/webkit/">r247213</a>)</li>
+                </ul>
+                ]]>
+            </content:encoded>
+        </item>
+        <item>
+            <title>Release Notes for Safari Technology Preview 87</title>
+            <link>https://webkit.org/blog/9414/release-notes-for-safari-technology-preview-87/</link>
+            <pubDate>Wed, 10 Jul 2019 17:00:51 +0000</pubDate>
+            <dc:creator>
+                <![CDATA[]]>
+            </dc:creator>
+            <category>
+                <![CDATA[Safari Technology Preview]]>
+            </category>
+
+            <guid isPermaLink="false">https://webkit.org/?p=9414</guid>
+            <description>
+                <![CDATA[Safari Technology Preview Release 87 is now available for download for macOS Mojave and the macOS Catalina beta.]]>
+            </description>
+            <content:encoded>
+                <![CDATA[<p><a href="https://webkit.org/blog/6017/introducing-safari-technology-preview/">Safari Technology Preview</a> Release 87 is now <a href="https://webkit.org/downloads/">available for download</a> for macOS Mojave and the macOS Catalina beta. If you already have Safari Technology Preview installed, you can update in the Software Update pane of System Preferences on macOS.</p>
+                <p>This release covers WebKit revisions <a href="https://trac.webkit.org/log?stop_rev=246691&amp;&amp;rev=247047&amp;limit=999">246691-247047</a>.</p>
+                <h3>Web API</h3>
+                <ul>
+                <li>Changed <code>openDatabase</code> to return an empty object when WebSQL is disabled (<a href="https://trac.webkit.org/changeset/246707/webkit/">r246707</a>)</li>
+                <li>Added an experimental behavior to prevent a 5 second delay for initial paint on pages that are using Google&#8217;s anti-flicker optimization when content blockers are enabled (<a href="https://trac.webkit.org/changeset/246764/webkit/">r246764</a>)</li>
+                </ul>
+                <h3>Web Sockets</h3>
+                <ul>
+                <li>Added support for sending blob messages when using web sockets platform APIs (<a href="https://trac.webkit.org/changeset/246964/webkit/">r246964</a>)</li>
+                </ul>
+                <h3>Payment Request</h3>
+                <ul>
+                <li>Changed to set state to Closed when <code>show()</code> is called during an active session (<a href="https://trac.webkit.org/changeset/246863/webkit/">r246863</a>)</li>
+                </ul>
+                <h3>Experimental Web Shading Language (WHLSL)</h3>
+                <ul>
+                <li>Implemented arrays (<a href="https://trac.webkit.org/changeset/246875/webkit/">r246875</a>)</li>
+                </ul>
+                <h3>Rendering</h3>
+                <ul>
+                <li>Fixed incorrect clipping with <code>overflow: scroll</code> inside <code>overflow: hidden</code> with <code>border-radius</code> (<a href="https://trac.webkit.org/changeset/246845/webkit/">r246845</a>)</li>
+                <li>Fixed the preview of a <code>&lt;picture&gt;</code> element to match the element bounds (<a href="https://trac.webkit.org/changeset/246695/webkit/">r246695</a>)</li>
+                </ul>
+                <h3>WebGPU</h3>
+                <ul>
+                <li>Made WebGPU enabled only on Mojave and later (<a href="https://trac.webkit.org/changeset/246888/webkit/">r246888</a>)</li>
+                </ul>
+                <h3>Web Inspector</h3>
+                <ul>
+                <li>Implemented <code>console.countReset</code> (<a href="https://trac.webkit.org/changeset/246850/webkit/">r246850</a>)</li>
+                <li>Implemented <code>console.timeLog</code> (<a href="https://trac.webkit.org/changeset/246798/webkit/">r246798</a>)</li>
+                <li>Added additional demo audits for other <code>WebInspectorAudit</code> functions (<a href="https://trac.webkit.org/changeset/247042/webkit/">r247042</a>)</li>
+                <li>Enable the Show Shadow DOM navigation item by default in the Elements tab (<a href="https://trac.webkit.org/changeset/246821/webkit/">r246821</a>)</li>
+                </ul>
+                <h3>Known Issues</h3>
+                <ul>
+                <li>Open tabs are blank on initial launch after upgrading to Safari Technology Preview 87 and loading all tabs from the last session. To correct this behavior, reload open tabs or relaunch Safari Technology Preview.</li>
+                </ul>
+                ]]>
+            </content:encoded>
+        </item>
+        <item>
+            <title>WebDriver is Coming to Safari in iOS 13</title>
+            <link>https://webkit.org/blog/9395/webdriver-is-coming-to-safari-in-ios-13/</link>
+            <pubDate>Mon, 08 Jul 2019 17:00:58 +0000</pubDate>
+            <dc:creator>
+                <![CDATA[]]>
+            </dc:creator>
+            <category>
+                <![CDATA[Web Inspector]]>
+            </category>
+
+            <guid isPermaLink="false">https://webkit.org/?p=9395</guid>
+            <description>
+                <![CDATA[As anyone who has developed a mobile-friendly site can tell you, mobile browsers and desktop browsers are different.]]>
+            </description>
+            <content:encoded>
+                <![CDATA[<p>As anyone who has developed a mobile-friendly site can tell you, mobile browsers and desktop browsers are different. As device capabilities continue to evolve and users move more of their browsing to mobile browsers, web developers are facing an increasing need to write automated tests for the mobile web in the same way that desktop-oriented site content is tested.</p>
+                <p>Starting in iOS 13, Safari now includes native support for the <a href="https://www.w3.org/TR/webdriver/">W3C WebDriver</a> standard. This feature builds on existing support for WebDriver in desktop Safari, first introduced in Safari 10 and macOS Sierra. This blog post explains how to get started with WebDriver for iOS, how to port your existing desktop-oriented tests, and a few details regarding safeguards and changes in behavior.</p>
+                <h2>Getting Started</h2>
+                <p>Control via WebDriver is exposed to developers via the <code>/usr/bin/safaridriver</code> executable, which hosts a driver that handles REST API requests sent by WebDriver test clients. In order to run WebDriver tests on an iOS device, it must be plugged into a macOS host that has a new enough version of safaridriver. Support for hosting iOS-based WebDriver sessions is available in safaridriver included with Safari 13 and later. Older versions of safaridriver do not support iOS WebDriver sessions.</p>
+                <p>If you&#8217;ve never used safaridriver on macOS before, you&#8217;ll first need to run <code>safaridriver --enable</code> and authenticate as an administrator. Then, you must enable Remote Automation on every device that you intend to use for WebDriver. To do this, toggle the setting in Settings → Safari → Advanced → Remote Automation.</p>
+                <figure class="widescreen"><picture><source srcset="https://webkit.org/wp-content/uploads/IMG_0010.png" media="(prefers-color-scheme: dark)" /><img class="wp-image-9396" src="https://webkit.org/wp-content/uploads/IMG_0009.png" alt="Remote Automation Setting on iOS" srcset="https://webkit.org/wp-content/uploads/IMG_0009.png 2732w, https://webkit.org/wp-content/uploads/IMG_0009-300x225.png 300w, https://webkit.org/wp-content/uploads/IMG_0009-768x576.png 768w, https://webkit.org/wp-content/uploads/IMG_0009-1024x768.png 1024w" sizes="(max-width: 2732px) 100vw, 2732px" /></picture></figure>
+                <p>Lastly, to run tests on the device, you&#8217;ll need to plug it into the macOS machine, <a href="https://support.apple.com/en-us/HT202778">trust the host</a>, and ensure that it is unlocked when you try to start the WebDriver session.</p>
+                <p>Since safaridriver is capable of starting WebDriver sessions using Safari on the macOS host or Safari on an attached iOS device, it needs a little extra hint to know that you want to use a device or a desktop machine. To facilitate this, safaridriver supports many new capabilities that may be provided with a new session request. The most important new capability to use is <strong>&#8216;platformName&#8217;: &#8216;ios&#8217;;</strong> this tells the driver you want an iOS host instead of a macOS host. You can also specify the host(s) you wish to use by specifying device type, device UDID, device name, OS version, OS build, and browser version via standardized and extension capabilities. Lastly, safaridriver supports running WebDriver tests on iOS Simulator devices whose runtime is iOS 13 or later. To use a simulator for testing, add the capability <strong>&#8216;safari:useSimulator&#8217;: true</strong>. For a full list of supported capabilities and their semantics, please consult the safaridriver(1) man page by executing <code>man safaridriver.</code></p>
+                <h2>Safeguards</h2>
+                <p>While it’s awesome to be able to write automated tests that run in Safari, a REST API for browser automation introduces a potential vector for malicious software. To support a valuable automation API without sacrificing a user’s privacy or security, Safari’s driver implementation introduces extra safeguards that further restrict browsing in WebDriver sessions. These safeguards also double as extra insurance against “<a href="http://martinfowler.com/articles/nonDeterminism.html">flaky tests</a>” by providing enhanced test isolation. Some of these safeguards are described below.</p>
+                <p>Just like on macOS, Safari on iOS isolates WebDriver tests by using a separate set of windows, tabs, preferences, and persistent storage. When a WebDriver session is active, existing tabs are hidden and a distinctively-colored WebDriver window is shown instead. Automation windows are easy to recognize by their orange Smart Search field. Similar to browsing in a Private Browsing window, WebDriver tests that run in an Automation window always start from a clean slate and cannot access Safari’s normal browsing history, AutoFill data, or other sensitive information. Aside from the obvious privacy benefits, this restriction also helps to ensure that tests are not affected by a previous test session’s persistent state such as local storage or cookies. When the WebDriver session terminates, the orange window goes away, preexisting tabs are restored, and any state accumulated during the WebDriver session is destroyed.</p>
+                <p>As a WebDriver test is executing in an Automation window, any attempts to interact with the window or web content could derail the test by unexpectedly changing the state of the page. To prevent this from happening, Safari installs a “glass pane” over the Automation window while the test is running. This blocks any stray interactions (mouse, keyboard, resizing, and so on) from affecting the Automation window. If a running test gets stuck or fails, it’s possible to interrupt the running test by tapping on the screen and choosing to end the session. When an automation session is interrupted, the test’s connection to the browser is permanently severed and cannot be resumed. Notifications and system gestures (i.e., slide in from top/bottom) are also suppressed while WebDriver tests are running in order to avoid flakiness.</p>
+                <figure><img class="preserve-color wp-image-9410" src="https://webkit.org/wp-content/uploads/webdriver-ios13beta.jpg" alt="Glass Pane" srcset="https://webkit.org/wp-content/uploads/webdriver-ios13beta.jpg 1125w, https://webkit.org/wp-content/uploads/webdriver-ios13beta-139x300.jpg 139w, https://webkit.org/wp-content/uploads/webdriver-ios13beta-768x1663.jpg 768w, https://webkit.org/wp-content/uploads/webdriver-ios13beta-473x1024.jpg 473w" sizes="(max-width: 1125px) 100vw, 1125px" /></figure>
+                <p>A non-goal of this release is to support general-purpose device automation via the WebDriver API. The W3C WebDriver API focuses on automating interactions with web content, and that is also the focus of the WebDriver support added in iOS 13. Other means exist to change system-level configuration with the <a href="https://developer.apple.com/documentation/xctest">XCTest Framework</a>, and are complimentary to WebDriver. There are other ways in which web content interacts with the rest of iOS, and most of these are suppressed in order to provide a stable testing environment. Safari for iOS does not allow WebDriver-initiated navigations to be handled outside of Safari. In other words, clicking a <code>tel://</code> link will not offer to place a phone call, and clicking an app store link will not redirect the user to the App Store. Similarly, non-Safari content displayed by the system–such as update dialogs, app notifications, incoming calls, etc.–are suppressed while a WebDriver session is active. Lastly, the software keyboard is suppressed when focusing text fields in WebDriver sessions. To simulate text input with WebDriver, use the existing <a href="https://w3c.github.io/webdriver/#perform-actions">Perform Actions endpoint</a> or <a href="https://w3c.github.io/webdriver/#element-send-keys">Element Send Keys endpoint</a>.</p>
+                <h2>Porting Tests</h2>
+                <p>A major goal of iOS 13 is to make it easier to develop and consume desktop-like web experiences on mobile devices. Towards that end, a major goal for WebDriver on iOS is to make it easy to port existing desktop-oriented WebDriver tests to work with Desktop-class browsing in Safari on iPadOS. As much as we&#8217;d like to treat macOS and iOS devices the same in our tests, there are important differences that affect how you may want to use WebDriver.</p>
+                <p>The first notable difference is handling of user input, namely touch and clicks. In this initial version of WebDriver on iOS, simulated input sources include keyboard, mouse, and single-finger touches. The Perform Actions command and <a href="https://w3c.github.io/webdriver/#element-click">Element Click command</a> synthesize touches using mouse inputs. If your existing test uses mouse clicks, double, clicks, and drags, safaridriver converts these interactions into equivalent single finger touches; no code needs to be changed. <em>Multiple touch input sources (i.e., fingers) are not supported in this release</em>. We experimented with offering this via the existing Perform Actions endpoint, but found that it was difficult to author WebDriver commands that performed well-known gestures such as flick, pinch, pan, and so on. This is partly due to the low-level nature of the Actions API, and partly due to the timing-sensitive nature of gesture recognizers used by Safari and WebKit. Apple is working within the W3C WebDriver working group to define a more expressive, intuitive, and stable API for performing gestures in WebDriver tests.</p>
+                <p>A less surprising difference between macOS and iOS WebDriver is that endpoints to manipulate the OS window are generally not supported by Safari on iOS. Specifically, the Set Window Rect, Minimize Window, and Maximize Window endpoints will return <em>&#8220;unsupported operation&#8221;</em>. For more detailed information concerning which endpoints are supported, see the <a href="https://developer.apple.com/documentation/webkit/about_webdriver_for_safari">W3C WebDriver Commands reference</a>.</p>
+                <h2>Summary</h2>
+                <p>With the introduction of native WebDriver support in Safari on iOS 13, it’s now possible to run the same automated tests of desktop-oriented web content on desktop and mobile devices equally. Safari’s support comes with new, exclusive safeguards to simultaneously protect user security and privacy and also help you write more stable and consistent tests. You can try out Safari’s WebDriver support today by installing a beta of <a href="https://developer.apple.com/macos/">macOS Catalina</a> and <a href="https://developer.apple.com/ios/">iOS 13</a>.</p>
+                <p>If you encounter unexpected behavior in Safari’s WebDriver support, or have other suggestions for improvement, please file a bug at <a href="https://bugreport.apple.com/">https://bugreport.apple.com/</a>. For quick questions or feedback, email <a href="mailto:web-evangelist@apple.com">web-evangelist@apple.com</a> or tweet <a href="https://www.twitter.com/webkit">@webkit</a> on Twitter. Happy testing!</p>
+                ]]>
+            </content:encoded>
+        </item>
+    </channel>
+</rss>
+
+<!-- Dynamic page generated in 0.246 seconds. -->
+<!-- Cached page generated by WP-Super-Cache on 2019-09-13 13:00:20 -->
diff --git a/LayoutTests/inspector/formatting/resources/xml-tests/rss.xml b/LayoutTests/inspector/formatting/resources/xml-tests/rss.xml
new file mode 100644 (file)
index 0000000..42b1e54
--- /dev/null
@@ -0,0 +1,730 @@
+<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
+       xmlns:content="http://purl.org/rss/1.0/modules/content/"
+       xmlns:wfw="http://wellformedweb.org/CommentAPI/"
+       xmlns:dc="http://purl.org/dc/elements/1.1/"
+       xmlns:atom="http://www.w3.org/2005/Atom"
+       xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
+       xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
+       >
+
+<channel>
+       <title>WebKit</title>
+       <atom:link href="https://webkit.org/feed/" rel="self" type="application/rss+xml" />
+       <link>https://webkit.org</link>
+       <description>Open Source Web Browser Engine</description>
+       <lastBuildDate>Fri, 13 Sep 2019 02:46:20 +0000</lastBuildDate>
+       <language>en-US</language>
+       <sy:updatePeriod>
+       hourly  </sy:updatePeriod>
+       <sy:updateFrequency>
+       1       </sy:updateFrequency>
+       <generator>https://wordpress.org/?v=5.2.2</generator>
+       <item>
+               <title>WebGPU and WSL in Safari</title>
+               <link>https://webkit.org/blog/9528/webgpu-and-wsl-in-safari/</link>
+                               <pubDate>Thu, 12 Sep 2019 17:00:42 +0000</pubDate>
+               <dc:creator><![CDATA[]]></dc:creator>
+                               <category><![CDATA[Performance]]></category>
+
+               <guid isPermaLink="false">https://webkit.org/?p=9528</guid>
+                               <description><![CDATA[WebGPU is a new API being developed by Apple and others in the W3C which enables high-performance 3D graphics and data-parallel computation on the Web.]]></description>
+                                                               <content:encoded><![CDATA[<p>WebGPU is a new API <a href="https://github.com/gpuweb/gpuweb">being developed</a> by Apple and others in the W3C which enables high-performance 3D graphics and <a href="https://en.wikipedia.org/wiki/Data_parallelism">data-parallel computation</a> on the Web. This API represents a significant improvement over the existing WebGL API in both performance and ease of use. Starting in <a href="https://developer.apple.com/safari/technology-preview/">Safari Technology Preview</a> release 91, beta support is available for WebGPU API and WSL, our proposal for the WebGPU shading language.</p>
+<p>A few months ago we discussed a <a href="https://webkit.org/blog/8482/web-high-level-shading-language/">proposal</a> for a new shading language called Web High-Level Shading Language, and began implementation as a proof of concept. Since then, we’ve shifted our approach to this new language, which I will discuss a little later in this post. With help from our friends at <a href="https://www.babylonjs.com/">Babylon.js</a> we were able to adapt a demo to work with WebGPU and Web Shading Language (WSL):</p>
+<figure><video autoplay loop src="https://webkit.org/wp-content/uploads/WebGPUDemoVideo.mp4" style="width: 100%"></video></figure>
+<p>You can <a href="https://webkit.org/demos/webgpu/babylon/oneHelmetWebGPU.html">see the demo in action</a> with Safari Technology Preview 91 or later, and with the WebGPU experimental feature enabled.<a name="footnoteOne" href="#footnotes" class="footnote">1</a> The demo utilizes many of the best features of WebGPU. Let&#8217;s dig in to see what make WebGPU work so well, and why we think WSL is a great choice for WebGPU.</p>
+<h2>WebGPU JavaScript API</h2>
+<p>Just like WebGL, the WebGPU API is accessed through JavaScript because most Web developers are already familiar with working in JavaScript. We expect to create a WebGPU API that is accessed through WebAssembly in the future.</p>
+<h3>Pipeline State Objects and Bind Groups</h3>
+<p>Most 3D applications render more than a single object. In WebGL, each of those objects requires a collection of state-changing calls before that object could be rendered. For example, rendering a single object in WebGL might look like:</p>
+<pre><code class="js"><span class="identifier">gl</span>.<span class="identifier">UseProgram</span>(<span class="identifier">program1</span>);
+<span class="identifier">gl</span>.<span class="identifier">frontFace</span>(<span class="identifier">gl</span>.<span class="identifier">CW</span>);
+<span class="identifier">gl</span>.<span class="identifier">cullFace</span>(<span class="identifier">gl</span>.<span class="identifier">FRONT</span>);
+<span class="identifier">gl</span>.<span class="identifier">blendEquationSeparate</span>(<span class="identifier">gl</span>.<span class="identifier">FUNC_ADD</span>, <span class="identifier">gl</span>.<span class="identifier">FUNC_MIN</span>);
+<span class="identifier">gl</span>.<span class="identifier">blendFuncSeparate</span>(<span class="identifier">gl</span>.<span class="identifier">SRC_COLOR</span>, <span class="identifier">gl</span>.<span class="identifier">ZERO</span>, <span class="identifier">gl</span>.<span class="identifier">SRC_ALPHA</span>, <span class="identifier">gl</span>.<span class="identifier">ZERO</span>);
+<span class="identifier">gl</span>.<span class="identifier">colorMask</span>(<span class="keyword literal">true</span>, <span class="keyword literal">false</span>, <span class="keyword literal">true</span>, <span class="keyword literal">true</span>);
+<span class="identifier">gl</span>.<span class="identifier">depthMask</span>(<span class="keyword literal">true</span>);
+<span class="identifier">gl</span>.<span class="identifier">stencilMask</span>(<span class="number">1</span>);
+<span class="identifier">gl</span>.<span class="identifier">depthFunc</span>(<span class="identifier">gl</span>.<span class="identifier">GREATER</span>);
+<span class="identifier">gl</span>.<span class="identifier">drawArrays</span>(<span class="identifier">gl</span>.<span class="identifier">TRIANGLES</span>, <span class="number">0</span>, <span class="identifier">count</span>);
+</code></pre>
+<p>On the other hand, rendering a single object in WebGPU might look like:</p>
+<pre><code class="js"><span class="identifier">encoder</span>.<span class="identifier">setPipeline</span>(<span class="identifier">renderPipeline</span>);
+<span class="identifier">encoder</span>.<span class="identifier">draw</span>(<span class="identifier">count</span>, <span class="number">1</span>, <span class="number">0</span>, <span class="number">0</span>);
+</code></pre>
+<p>All the pieces of state in the WebGL example are wrapped up into a single object in WebGPU, named a &#8220;<a href="https://github.com/gpuweb/gpuweb/blob/master/spec/index.bs#L664">pipeline state object</a>.&#8221; Though validating state is expensive, with WebGPU it is done once when the pipeline is created, outside of the core rendering loop. As a result, we can avoid performing expensive state analysis inside the draw call. Also, setting an entire pipeline state is a single function call, reducing the amount of &#8220;chatting&#8221; between Javascript and WebKit’s C++ browser engine.</p>
+<p>Resources have a similar story. Most rendering algorithms require a set of resources in order to draw a particular material. In WebGL, each resource would be bound one-by-one, leading to code that looks like:</p>
+<pre><code class="js"><span class="identifier">gl</span>.<span class="identifier">bindBufferRange</span>(<span class="identifier">gl</span>.<span class="identifier">UNIFORM_BUFFER</span>, <span class="number">0</span>, <span class="identifier">materialBuffer1</span>, <span class="number">0</span>, <span class="identifier">size1</span>);
+<span class="identifier">gl</span>.<span class="identifier">bindBufferRange</span>(<span class="identifier">gl</span>.<span class="identifier">UNIFORM_BUFFER</span>, <span class="number">1</span>, <span class="identifier">materialBuffer2</span>, <span class="number">0</span>, <span class="identifier">size2</span>);
+<span class="identifier">gl</span>.<span class="identifier">activeTexture</span>(<span class="number">0</span>);
+<span class="identifier">gl</span>.<span class="identifier">bindTexture</span>(<span class="identifier">gl</span>.<span class="identifier">TEXTURE_2D</span>, <span class="identifier">materialTexture1</span>);
+<span class="identifier">gl</span>.<span class="identifier">activeTexture</span>(<span class="number">1</span>);
+<span class="identifier">gl</span>.<span class="identifier">bindTexture</span>(<span class="identifier">gl</span>.<span class="identifier">TEXTURE_2D</span>, <span class="identifier">materialTexture2</span>);
+</code></pre>
+<p>However, in WebGPU, resources are batched up into &#8220;<a href="https://github.com/gpuweb/gpuweb/blob/master/spec/index.bs#L572">bind groups</a>.&#8221; When using WebGPU, the behavior of the above code is represented as simply:</p>
+<pre><code class="js"><span class="identifier">encoder</span>.<span class="identifier">setBindGroup</span>(<span class="number">0</span>, <span class="identifier">bindGroup</span>);
+</code></pre>
+<p>In both of these examples, multiple objects are gathered up together and baked into a hardware-dependent format, which is when the browser performs validation. Being able to separate object validation from object use means the application author has more control over when expensive operations occur in the lifecycle of their application.</p>
+<h3>Run-time Performance</h3>
+<p>We expect WebGPU to perform faster and handle larger workloads than WebGL. To measure performance, we adopted the test harness from our 2D graphics benchmark <a href="https://browserbench.org/MotionMark1.1/">MotionMark</a> and wrote two versions of a performance test that had a simple yet realistic workload, one in <a href="https://browserbench.org/MotionMark1.1/developer.html?test-interval=30&amp;display=minimal&amp;tiles=big&amp;controller=ramp&amp;frame-rate=50&amp;kalman-process-error=1&amp;kalman-measurement-error=4&amp;time-measurement=performance&amp;suite-name=3DGraphics&amp;test-name=TrianglesWebGL">WebGL</a> and the other in <a href="https://browserbench.org/MotionMark1.1/developer.html?test-interval=10&amp;display=minimal&amp;tiles=big&amp;controller=ramp&amp;frame-rate=50&amp;kalman-process-error=1&amp;kalman-measurement-error=4&amp;time-measurement=performance&amp;suite-name=3DGraphics&amp;test-name=TrianglesWebGPU">WebGPU</a>.</p>
+<p>The test measures how many triangles with different properties can be drawn while maintaining 60 frames per second. Each triangle renders with a different draw call and bind group; this mimics the way many games render objects (like characters, explosions, bullets, or environment objects) in different draw calls with different resources. Because much of the validation logic in WebGPU is performed during the creation of the bind group instead of inside the draw call, both of these calls execute much faster than the equivalent calls in WebGL.</p>
+<figure class="widescreen mattewhite"><img src="https://webkit.org/wp-content/uploads/WSLTrianglesBenchmark.png" alt=""  class="wp-image-9534" srcset="https://webkit.org/wp-content/uploads/WSLTrianglesBenchmark.png 1210w, https://webkit.org/wp-content/uploads/WSLTrianglesBenchmark-300x125.png 300w, https://webkit.org/wp-content/uploads/WSLTrianglesBenchmark-768x321.png 768w, https://webkit.org/wp-content/uploads/WSLTrianglesBenchmark-1024x428.png 1024w" sizes="(max-width: 1210px) 100vw, 1210px" /></figure>
+<h2>Web Shading Language</h2>
+<p>The WebGPU community group is actively discussing which shading language or languages should be supported by the specification. Last year, we <a href="https://webkit.org/blog/8482/web-high-level-shading-language/">proposed</a> a new shading language for WebGPU. We are pleased to announce that a beta version of this language is available in Safari Technology Preview 91.</p>
+<p>Because of community feedback, our approach toward designing the language has evolved. Previously, we designed the language to be source-compatible with HLSL, but we realized this compatibility was not what the community was asking for. Many wanted the shading language to be as simple and as low-level as possible. That would make it an easier compile target for whichever language their development shop uses.</p>
+<p>There are many Web developers using GLSL today in WebGL, so a potential browser accepting a different high level language, like HLSL, wouldn&#8217;t suit their needs well. In addition, a high-level language such as HLSL can&#8217;t be executed faithfully on every platform and graphics API that WebGPU is designed to execute on.</p>
+<p>So, we decided to make the language more simple, low-level, and fast to compile, and renamed the language to Web Shading Language to match this pursuit.<a name="footnoteTwo" href="#footnotes" class="footnote">2</a></p>
+<p>The name change reflects a shift in our approach, but the major tenets of WSL have not changed. It&#8217;s still a language that is high-performance. It&#8217;s still text-based, which integrates well with existing web technologies and culture. WSL&#8217;s semantics still bake in safety and portability. It still works great as a compile target. As expected for every web technology, the language is well-defined with a <a href="https://gpuweb.github.io/WSL/">robust specification</a>. And because the WebGPU Community Group owns the language, it matures in concert with the WebGPU API.</p>
+<p>In an upcoming post, we’ll talk more about the technical details of this language update. Here, let’s discuss further about WSL’s performance characteristics.</p>
+<h3>Wire Size</h3>
+<p>The Babylon.js demo above demonstrates an area where WSL really shines. The shaders in the demo use complex <a href="https://en.wikipedia.org/wiki/Physically_based_rendering">physically-based</a> algorithms to draw with the highest realism possible. Babylon.js creates these complex shading algorithms by stitching together snippets of shader source code at run-time. This way, Babylon&#8217;s shaders are tuned at run-time to the specific type of content the application contains. Since WSL is a textual language like GLSL, this kind of workflow can be accomplished simply with string concatenation.</p>
+<p>Building shaders by string concatenation and compiling them directly is a dramatic improvement over languages which cannot do this kind of manipulation easily, like bytecode-based languages. For these other languages, generation of shaders at run-time requires the execution of an additional compiler, written in JavaScript or WebAssembly, to compile the generated source text into the bytecode form.</p>
+<p>This extra step slows down performance in two ways. First, the execution of the additional compiler takes time. Second, the compiler source would have to be served with the rest of the web page’s resources, which increases the page size and lengthens the loading time of the web page. On the other hand, since WSL’s format is textual, there’s no additional compile step; you can just write it and run it!</p>
+<p>As a point of comparison, let’s take the Babylon.js demo shown above. Babylon.js renders scenes by joining GLSL shader snippets at runtime. When using WSL, Babylon.js would simply serve the WSL snippets just like they’re serving GLSL snippets today. To do the same with SPIR-V, Babylon.js would serve their shader snippets along with a compiler that compiles these textual snippets down to SPIR-V. Chrome recently <a href="https://www.youtube.com/watch?v=K2JzIUIHIhc">announced</a> their support for WebGPU with SPIR-V using the same demo. Here is a comparison of the gzipped wire sizes for the shaders as WSL, and that of the shaders as GLSL and the SPIR-V compiler:</p>
+<figure class="widescreen mattewhite"><img src="https://webkit.org/wp-content/uploads/WSLGzippedWireSize.png" alt="" class="wp-image-9535" srcset="https://webkit.org/wp-content/uploads/WSLGzippedWireSize.png 1132w, https://webkit.org/wp-content/uploads/WSLGzippedWireSize-300x128.png 300w, https://webkit.org/wp-content/uploads/WSLGzippedWireSize-768x328.png 768w, https://webkit.org/wp-content/uploads/WSLGzippedWireSize-1024x438.png 1024w" sizes="(max-width: 1132px) 100vw, 1132px" /></figure>
+<p>The top bar shows the wire size if Babylon.js used WSL directly. The middle bar shows the wire size of the GLSL source, plus the compiler that Babylon.js uses to compile their snippets into SPIR-V. The bottom bar shows the wire size if Babylon.js simply served the results of their SPIR-V compilation. Because of the dynamic nature of Babylon.js’s shaders, they assemble their shaders at runtime and compile them dynamically, so they require the SPIR-V compiler. However, other websites’ shaders may be more static, in which case they wouldn’t need the compiler and could serve the SPIR-V directly, like in the bottom bar in the graph above.</p>
+<h3>Compilation Performance</h3>
+<p>We&#8217;ve heard from developers that shader compilation performance is extremely important. One way the community group addressed this was designing WebGPU to support asynchronous compilation, which avoids blocking successive rendering commands. Asynchronous compilation isn’t a magic bullet, though. If the next rendering command uses a shader currently being compiled, that rendering command must wait for the compilation complete. So, we&#8217;ve put significant effort into making WSL compilation times fast.</p>
+<p>The WebGPU community created a compute shader to demonstrate the flocking characteristics of &#8220;boids,&#8221; and we turned that sample into a <a href="https://webkit.org/demos/webgpu/compute-boids-compile.html">compiler performance benchmark</a>. Here we compare the compilation time of WSL with the run-time of the GLSL compiler to SPIR-V running as a WebAssembly library:</p>
+<figure class="widescreen mattewhite"><img src="https://webkit.org/wp-content/uploads/WSLCompilationTime.png" alt="" class="wp-image-9536" srcset="https://webkit.org/wp-content/uploads/WSLCompilationTime.png 1082w, https://webkit.org/wp-content/uploads/WSLCompilationTime-300x131.png 300w, https://webkit.org/wp-content/uploads/WSLCompilationTime-768x335.png 768w, https://webkit.org/wp-content/uploads/WSLCompilationTime-1024x447.png 1024w" sizes="(max-width: 1082px) 100vw, 1082px" /></figure>
+<p>As you can see, we’re continuing to optimize compilation performance, and it’s been increasing both throughout and after STP 91’s release.</p>
+<h2>Give WebGPU a try!</h2>
+<p>We&#8217;re very excited to have implemented a beta version of WebGPU and WSL in the latest version of Safari Technology Preview. Try it out and let us know how well it works for you! We&#8217;re interested in feedback so we can evolve the WebGPU and WSL language to better suit everyone&#8217;s needs.</p>
+<p>And be sure to check out our <a href="https://webkit.org/demos/webgpu/">gallery of WebGPU samples</a>. We&#8217;ll be keeping this page updated with the latest demos. Many thanks to Sebastien Vandenberghe and David Catuhe from Babylon.js for their help with Babylon.js in Safari.</p>
+<p>For more information, you can contact me at <a href="mailto:mmaxfield@apple.com">mmaxfield@apple.com</a> or <a href="http://twitter.com/Litherum">@Litherum</a>, or you can contact our evangelist, <a href="mailto:jond@apple.com">Jonathan Davis</a>.</p>
+<p><a name="footnotes" class="footnote"></a><br />
+<a href="#footnoteOne">1</a> To enable WebGPU beta support, in Develop menu, select Experimental Features > WebGPU.<br />
+<a href="#footnoteTwo">2</a> We still pronounce it “whistle”, though.</p>
+]]></content:encoded>
+                                                       <enclosure url="https://webkit.org/wp-content/uploads/WebGPUDemoVideo.mp4" length="2410187" type="video/mp4" />
+                       </item>
+               <item>
+               <title>Release Notes for Safari Technology Preview 91</title>
+               <link>https://webkit.org/blog/9526/release-notes-for-safari-technology-preview-91/</link>
+                               <pubDate>Wed, 04 Sep 2019 17:00:52 +0000</pubDate>
+               <dc:creator><![CDATA[]]></dc:creator>
+                               <category><![CDATA[Safari Technology Preview]]></category>
+
+               <guid isPermaLink="false">https://webkit.org/?p=9526</guid>
+                               <description><![CDATA[Safari Technology Preview Release 91 is now available for download for macOS Mojave and the macOS Catalina beta.]]></description>
+                                                               <content:encoded><![CDATA[<p><a href="https://webkit.org/blog/6017/introducing-safari-technology-preview/">Safari Technology Preview</a> Release 91 is now <a href="https://webkit.org/downloads/">available for download</a> for macOS Mojave and the macOS Catalina beta. If you already have Safari Technology Preview installed, you can update in the Software Update pane of System Preferences on macOS.</p>
+<p>This release covers WebKit revisions <a href="https://trac.webkit.org/log?stop_rev=248705&amp;&amp;rev=249190&amp;limit=999">248705-249190</a>.</p>
+<h3>Security</h3>
+<ul>
+<li>Disabled legacy TLS 1.0 and TLS 1.1 (<a href="https://trac.webkit.org/changeset/249019/webkit/">r249019</a>)</li>
+</ul>
+<h3>JavaScript API</h3>
+<ul>
+<li>Added a public API for unhandled promise rejections (<a href="https://trac.webkit.org/changeset/249058/webkit/">r249058</a>)</li>
+<li>Added support for hashbang in ESNext (<a href="https://trac.webkit.org/changeset/248826/webkit/">r248826</a>)</li>
+<li>Implemented optional chaining in ESNext (<a href="https://trac.webkit.org/changeset/248829/webkit/">r248829</a>)</li>
+<li>Implemented <code>StaticRange</code> constructor (<a href="https://trac.webkit.org/changeset/249079/webkit/">r249079</a>)</li>
+<li>Fixed <code>Date.prototype.toJSON</code> to not throw an exception if <code>toISOString</code> returns an object (<a href="https://trac.webkit.org/changeset/248876/webkit/">r248876</a>)</li>
+<li>Fixed more missing exception checks in <code>String.prototype</code> (<a href="https://trac.webkit.org/changeset/248716/webkit/">r248716</a>)</li>
+<li>Fixed a bad error message when <code>for-await-of</code> is used in a non-async function (<a href="https://trac.webkit.org/changeset/248711/webkit/">r248711</a>)</li>
+<li>Fixed ProxyObject to not allow access to its target&#8217;s private properties (<a href="https://trac.webkit.org/changeset/248796/webkit/">r248796</a>)</li>
+<li>Updated the Promise constructor to check argument before `Construct?&#8220; (<a href="https://trac.webkit.org/changeset/248787/webkit/">r248787</a>)</li>
+<li>Updated <code>Promise.prototype.finally</code> to accept non-promise objects (<a href="https://trac.webkit.org/changeset/248793/webkit/">r248793</a>)</li>
+</ul>
+<h3>JavaScript Performance</h3>
+<ul>
+<li>Changed to avoid looking up the <code>join</code> function each time <code>Array.prototype.toString</code> is called (<a href="https://trac.webkit.org/changeset/248906/webkit/">r248906</a>)</li>
+<li>Ensured <code>x?.y ?? z</code> is fast (<a href="https://trac.webkit.org/changeset/249117/webkit/">r249117</a>)</li>
+</ul>
+<h3>Media</h3>
+<ul>
+<li>Fixed firing <code>webkitpresentationmodechanged</code> twice when exiting picture-in-picture (<a href="https://trac.webkit.org/changeset/249141/webkit/">r249141</a>)</li>
+<li>Updated to stop <code>MediaDevices</code> timer when stopping <code>MediaDevices</code> (<a href="https://trac.webkit.org/changeset/248853/webkit/">r248853</a>)</li>
+<li>Fixed removing fullscreen element in a <code>requestAnimationFrame()</code> callback after <code>requestFullscreen()</code> leaving fullscreen in an inconsistent state (<a href="https://trac.webkit.org/changeset/249147/webkit/">r249147</a>)</li>
+<li>Disabled devices should not be taken into account when searching for a capture device (<a href="https://trac.webkit.org/changeset/249154/webkit/">r249154</a>)</li>
+</ul>
+<h3>Web API</h3>
+<ul>
+<li>Started to expose Geolocation interfaces (<code>GeolocationPosition</code>, <code>GeolocationPositionError, and</code> <code>GeolocationCoordinates</code>) on the global <code>Window</code> object (<a href="https://trac.webkit.org/changeset/249066/webkit/">r249066</a>)</li>
+<li>Fixed Emoji with variation selectors to be rendered in emoji style, not text style (<a href="https://trac.webkit.org/changeset/248815/webkit/">r248815</a>)</li>
+<li>Changed SVG elements to become focusable when <code>focus</code> and <code>key</code> event listeners are added (<a href="https://trac.webkit.org/changeset/248983/webkit/">r248983</a>)</li>
+<li>Changed the default tab index of <code>output</code> and <code>fieldset</code> to be -1 (<a href="https://trac.webkit.org/changeset/248914/webkit/">r248914</a>)</li>
+</ul>
+<h3>Rendering</h3>
+<ul>
+<li>Fixed drawing an animated image to a canvas via <code>drawImage</code> to draw the first frame (<a href="https://trac.webkit.org/changeset/249162/webkit/">r249162</a>)</li>
+</ul>
+<h3>Pointer Events</h3>
+<ul>
+<li>Fixed removing the capture element preventing future pointer events from being dispatched on macOS (<a href="https://trac.webkit.org/changeset/248855/webkit/">r248855</a>)</li>
+</ul>
+<h3>WebDriver</h3>
+<ul>
+<li>Fixed mouse buttons to be correctly printed in <code>SimulatedInputDispatcher</code> logging (<a href="https://trac.webkit.org/changeset/248715/webkit/">r248715</a>)</li>
+</ul>
+<h3>Web Inspector</h3>
+<ul>
+<li>Elements
+<ul>
+<li>Fixed issue where &#8220;Copy Rule&#8221; menu item copied commented out properties incorrectly (<a href="https://trac.webkit.org/changeset/249089/webkit/">r249089</a>)</li>
+<li>Changed to automatically enable the event listener when setting a breakpoint on it in the Node details sidebar (<a href="https://trac.webkit.org/changeset/248765/webkit/">r248765</a>)</li>
+<li>Changed the DOM tree to always be LTR, even in RTL mode (<a href="https://trac.webkit.org/changeset/248991/webkit/">r248991</a>)</li>
+</ul>
+</li>
+<li>Network
+<ul>
+<li>Changed the Headers pane to always be LTR, even in RTL mode (<a href="https://trac.webkit.org/changeset/248889/webkit/">r248889</a>)</li>
+</ul>
+</li>
+<li>Resources
+<ul>
+<li>Added syntax highlighting for more CSS media queries (<a href="https://trac.webkit.org/changeset/248810/webkit/">r248810</a>)</li>
+<li>Added syntax highlighting for JavaScript <code>BigInt</code> (<a href="https://trac.webkit.org/changeset/248898/webkit/">r248898</a>, <a href="https://trac.webkit.org/changeset/248908/webkit/">r248908</a>)</li>
+<li>Added pretty printing support for more modern JavaScript language features (<a href="https://trac.webkit.org/changeset/248760/webkit/">r248760</a>, <a href="https://trac.webkit.org/changeset/248785/webkit/">r248785</a>, <a href="https://trac.webkit.org/changeset/248922/webkit/">r248922</a>, <a href="https://trac.webkit.org/changeset/248923/webkit/">r248923</a>)</li>
+<li>Fixed a CodeMirror issue where tabs were still used even when the &#8220;Prefer indent using&#8221; setting is set to &#8220;Spaces&#8221; (<a href="https://trac.webkit.org/changeset/248739/webkit/">r248739</a>)</li>
+</ul>
+</li>
+<li>Debugger
+<ul>
+<li>Added a global breakpoint for pausing in the next microtask (<a href="https://trac.webkit.org/changeset/248894/webkit/">r248894</a>)</li>
+<li>Fixed an issue where the Assertion Failures breakpoint didn’t work when inspecting a JSContext (<a href="https://trac.webkit.org/changeset/248891/webkit/">r248891</a>)</li>
+</ul>
+</li>
+<li>Console
+<ul>
+<li>Implemented <code>queryHolders</code> Command Line API function (<a href="https://trac.webkit.org/changeset/248925/webkit/">r248925</a>)</li>
+<li>Updated <code>console.dir</code> to start out expanded when given an object (<a href="https://trac.webkit.org/changeset/249034/webkit/">r249034</a>)</li>
+<li>Created additional Command Line API functions for other <code>console</code> methods (<a href="https://trac.webkit.org/changeset/249078/webkit/">r249078</a>)</li>
+<li>Changed the Console to always be LTR, even in RTL mode (<a href="https://trac.webkit.org/changeset/248766/webkit/">r248766</a>)</li>
+</ul>
+</li>
+<li>Sources (Experimental)
+<ul>
+<li>Fixed an issue where the gear icon would move to the second line when the navigation sidebar is narrow (<a href="https://trac.webkit.org/changeset/248818/webkit/">r248818</a>)</li>
+<li>Fixed an issue where the &#8220;No Filter Results&#8221; message was displayed on top of all of the other content, preventing any interaction (<a href="https://trac.webkit.org/changeset/248737/webkit/">r248737</a>)</li>
+<li>Gave Origins their own icon in the navigation sidebar (<a href="https://trac.webkit.org/changeset/248912/webkit/">r248912</a>)</li>
+<li>Moved the resource type scope bar to be next to the filter in the navigation sidebar (<a href="https://trac.webkit.org/changeset/248916/webkit/">r248916</a>, <a href="https://trac.webkit.org/changeset/248940/webkit/">r248940</a>)</li>
+<li>Provided a way to create an arbitrary Inspector Style Sheet (<a href="https://trac.webkit.org/changeset/248753/webkit/">r248753</a>)</li>
+</ul>
+</li>
+<li>Layers (Experimental)
+<ul>
+<li>Fixed the background of the 3D area not updating when transitioning to/from Dark Mode (<a href="https://trac.webkit.org/changeset/248735/webkit/">r248735</a>)</li>
+</ul>
+</li>
+</ul>
+<h3>WebGPU</h3>
+<ul>
+<li>Added unary plus (<a href="https://trac.webkit.org/changeset/248756/webkit/">r248756</a>)</li>
+<li>Changed enums to not be shadowed by local variables (<a href="https://trac.webkit.org/changeset/248812/webkit/">r248812</a>)</li>
+<li>Fixed WebGPU layers not showing up sometimes (<a href="https://trac.webkit.org/changeset/248879/webkit/">r248879</a>)</li>
+<li>Implemented GPUErrors for and relax GPUBuffer validation rules (<a href="https://trac.webkit.org/changeset/249183/webkit/">r249183</a>)</li>
+<li>Made <code>operator==</code> native and added bool matrices (<a href="https://trac.webkit.org/changeset/248795/webkit/">r248795</a>)</li>
+<li>Updated matrices to have constructors that take a flattened list of scalars (<a href="https://trac.webkit.org/changeset/248754/webkit/">r248754</a>)</li>
+<li>Updated vertex shader and fragment shader to be able to come from two different programs (<a href="https://trac.webkit.org/changeset/248993/webkit/">r248993</a>)</li>
+</ul>
+]]></content:encoded>
+                                                                               </item>
+               <item>
+               <title>How Web Content Can Affect Power Usage</title>
+               <link>https://webkit.org/blog/8970/how-web-content-can-affect-power-usage/</link>
+                               <pubDate>Tue, 27 Aug 2019 17:00:58 +0000</pubDate>
+               <dc:creator><![CDATA[]]></dc:creator>
+                               <category><![CDATA[Performance]]></category>
+               <category><![CDATA[Web Inspector]]></category>
+
+               <guid isPermaLink="false">https://webkit.org/?p=8970</guid>
+                               <description><![CDATA[Users spend a large proportion of their online time on mobile devices, and a significant fraction of the rest is users on untethered laptop computers.]]></description>
+                                                               <content:encoded><![CDATA[<style>@media (prefers-color-scheme:dark) { figure picture img { filter: none; } }</style>
+<p>Users spend a large proportion of their online time on mobile devices, and a significant fraction of the rest is users on untethered laptop computers. For both, battery life is critical. In this post, we&#8217;ll talk about factors that affect battery life, and how you, as a web developer, can make your pages more power efficient so that users can spend more time engaged with your content.</p>
+<h2>What Draws Power?</h2>
+<p>Most of the energy on mobile devices is consumed by a few major components:</p>
+<ul>
+<li>CPU (Main processor)</li>
+<li>GPU (Graphics processing)</li>
+<li>Networking (Wi-Fi and cellular radio chips)</li>
+<li>Screen</li>
+</ul>
+<p>Screen power consumption is relatively constant and mostly under the user&#8217;s control (via screen on-time and brightness), but the other components, the CPU, GPU and networking hardware have high dynamic range when it comes to power consumption.</p>
+<p>The system adapts the CPU and GPU performance based on the current tasks being processed, including, of course, rendering web pages that the user is interacting with in their web browser and other apps using web content. This is done through turning some components on or off, and by changing their <a href="https://en.wikipedia.org/wiki/Clock_rate">clock frequency</a>. In broad terms, the more performance that is required from the chips, the lower their power-efficiency. The hardware can ramp up to high performance very quickly (but at a large power cost), then rapidly go back to a more efficient <a href="https://software.intel.com/en-us/articles/power-management-states-p-states-c-states-and-package-c-states">low-power state</a>.</p>
+<h2>General Principles for Good Power Usage</h2>
+<p>To maximize battery life, you therefore want to reduce the amount of time spent in high-power states, and let the hardware go back to idle as much as possible.</p>
+<p>For web developers, there are three states of interaction to think about:</p>
+<ul>
+<li>When the user is actively interacting with the content.</li>
+<li>When the page is the frontmost, but the user is not interacting with it.</li>
+<li>When the page is not the frontmost content.</li>
+</ul>
+<h3>Efficient user interaction</h3>
+<p>Obviously it&#8217;s good to expend power at times when the user is interacting with the page. You want the page to load fast and respond quickly to touch. In many cases, the same optimizations that reduce time to first paint and time to user interactive will also reduce power usage. However, be cautious about continuing to load resources and to run script after the initial page load. The goal should be to get back to idle as fast as possible. In general, the less JavaScript that runs, the more power-efficient the page will be, because script is work on top of what the browser has already done to layout and paint the page.</p>
+<p>Once the page has loaded, user interactions like scrolling and tapping will also ramp up the hardware power (mainly the CPU and GPU), which again makes sense, but make sure to go back to idle as soon as the user stops interacting. Also, try to stay on the browser &#8220;fast paths&#8221; — for example, normal page scrolling will be much more power-efficient than custom scrolling implemented in JavaScript.</p>
+<h3>Drive idle power usage towards zero</h3>
+<p>When the user is not interacting with the page, try to make the page use as little power as possible. For example:</p>
+<ul>
+<li>Minimize the use of timers to avoid waking up the CPU. Try to coalesce timer-based work into a few, infrequent timers. Lots of uncoordinated timers which trigger frequent CPU wake-ups are much worse than gathering that work into fewer chunks.</li>
+<li>Minimize continually animating content, like animated images and auto-playing video. Be particularly vigilant to avoid &#8220;loading&#8221; spinner GIFs or CSS animations that continually trigger painting, even if you can&#8217;t see them. <a href="https://webkit.org/blog/8582/intersectionobserver-in-webkit/">IntersectionObserver</a> can be used to runs animations only when they are visible.</li>
+<li>Use declarative animations (CSS <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/animation">Animations</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions">Transitions</a>) where possible. The browser can optimize these away when the animating content is not visible, and they are more efficient than script-driven animation.</li>
+<li>Avoid network polling to obtain periodic updates from a server. Use <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API">WebSockets</a> or <a href="https://webkit.org/blog/7521/a-few-words-on-fetching-bytes/">Fetch</a> with a persistent connection, instead of polling.</li>
+</ul>
+<p>A page that is doing work when it should be idle will also be less responsive to user interaction, so minimizing background activity also improves responsiveness as well as battery life.</p>
+<h3>Zero CPU usage while in the background</h3>
+<p>There are various scenarios where a page becomes inactive (not the user&#8217;s primary focus), for instance:</p>
+<ul>
+<li>The user switches to a different tab.</li>
+<li>The user switches to a different app.</li>
+<li>The browser window is minimized.</li>
+<li>The browser window is visible but is not the focused window.</li>
+<li>The browser window is behind another window.</li>
+<li>The space the window is on is not the current space.</li>
+</ul>
+<p>When a page becomes inactive, WebKit automatically takes steps to save power:</p>
+<ul>
+<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame"><code>requestAnimationFrame</code></a> is stopped.</li>
+<li>CSS and SVG Animations are suspended.</li>
+<li>Timers are throttled.</li>
+</ul>
+<p>In addition, WebKit takes advantage of features provided by the operating system to maximize efficiency:</p>
+<ul>
+<li>on iOS, tabs are completely suspended when possible.</li>
+<li>on macOS, tabs participate in <a href="https://developer.apple.com/library/archive/documentation/Performance/Conceptual/power_efficiency_guidelines_osx/AppNap.html">App Nap</a>, which means that the web process for a tab that is not visually updating gets lower priority and has its timers throttled.</li>
+</ul>
+<p>However, pages can trigger CPU wake-ups via timers (<code>setTimeout</code> and <code>setInterval</code>), messages, network events, etc. You should avoid these when in the background as much as possible. There are two APIs that are useful for this:</p>
+<ul>
+<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API" target="_blank" rel="noopener noreferrer">Page Visibility API</a> provides a way to respond to a page transitioning to be in the background or foreground. This is a good way to avoid updating the UI while the page is in the background, then using the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/visibilitychange_event"><code>visibilitychange</code> event</a> to update the content when the page becomes visible.</li>
+<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/blur_event" target="_blank" rel="noopener noreferrer"><code>blur</code> events</a> are sent whenever the page is no longer focused. In that case, a page may still be visible but it is not the currently focused window. Depending on the page, it can be a good idea to stop animations.</li>
+</ul>
+<p>The easiest way to find problems is Web Inspector’s Timelines. The recording should not show any event happening while the page is in the background.</p>
+<h2>Hunting Power Inefficiencies</h2>
+<p>Now that we know the main causes of power use by web pages and have given some general rules about creating power-efficient content, let&#8217;s talk about how to identify and fix issues that cause excessive power drain.</p>
+<h3>Scripting</h3>
+<p>As mentioned above, modern CPUs can ramp power use from very low, when the device is idle, to very high to meet the demands of user interaction and other tasks. Because of this, the CPU is a leading cause of battery life variance. CPU usage during page loading is a combination of work the browser engine does to load, parse and render resources, and in executing JavaScript. On many modern web pages, time spent executing JavaScript far exceeds the time spent by the browser in the rest of the loading process, so minimizing JavaScript execution time will have the biggest benefits for power.</p>
+<p>The best way to measure CPU usage is with Web Inspector. As we showed in a previous post, the <a href="https://webkit.org/blog/8993/cpu-timeline-in-web-inspector/">timeline now shows</a> the CPU activity for any selected time range:</p>
+<figure class="widescreen mattewhite"><picture><source srcset="https://webkit.org/wp-content/uploads/Web-Inspector-CPU-Timeline-Overview-Dark.png" media="(prefers-color-scheme: dark)" /><img style="width: 100%; max-width: 1189px;" src="https://webkit.org/wp-content/uploads/Web-Inspector-CPU-Timeline-Overview-Light.png" /></picture></figure>
+<p>To use the CPU efficiently, WebKit distributes work over multiple cores when possible (and pages using Workers will also be able to make use of multiple cores). Web Inspector provides a breakdown of the threads running concurrently with the page&#8217;s main thread. For example, the following screenshot shows the threads while scrolling a page with complex rendering and video playback:</p>
+<figure class="widescreen mattewhite"><picture><source srcset="https://webkit.org/wp-content/uploads/Power-heavy-website-dark.png" media="(prefers-color-scheme: dark)" /><img style="width: 100%; max-width: 1086px;" src="https://webkit.org/wp-content/uploads/Power-heavy-website-light.png" /></picture></figure>
+<p>When looking for things to optimize, focus on the main thread, since that&#8217;s where your JavaScript is running (unless you&#8217;re using Workers), and use the &#8220;JavaScript and Events&#8221; timeline to understand what&#8217;s triggering your script. Perhaps you&#8217;re doing too much work in response to user or scroll events, or triggering updates of hidden elements from requestAnimationFrame. Be cognizant of work done by JavaScript libraries and third party scripts that you use on your page. To dig deeper, you can use Web Inspector&#8217;s <a href="https://webkit.org/blog/6539/introducing-jscs-new-sampling-profiler/">JavaScript profiler</a> to see where time is being spent.</p>
+<p>Activity in &#8220;WebKit Threads&#8221; is mostly triggered by work related to JavaScript: JIT compilation and garbage collection, so reducing the amount of script that runs, and reducing the churn of JavaScript objects should lower this.</p>
+<p>Various other system frameworks invoked by WebKit make use of threads, so &#8220;Other threads&#8221; include work done by those; the largest contributor to &#8220;Other thread&#8221; activity is painting, which we&#8217;ll talk about next.</p>
+<h3>Painting</h3>
+<p>Main thread CPU usage can also be triggered by lots of layout and painting; these are usually triggered by script, but a CSS animation of a property other than <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/transform"><code>transform</code></a>, <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/opacity"><code>opacity</code></a> and <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/filter"><code>filter</code></a> can also cause them. Looking at the “Layout and Rendering” timeline will help you understand what’s causing activity.</p>
+<p>If the &#8220;Layout and Rendering&#8221; timeline shows painting but you can&#8217;t figure out what&#8217;s changing, turn on Paint Flashing:</p>
+<figure>
+<picture><source srcset="https://webkit.org/wp-content/uploads/Enable-Paint-Flashing-dark.png" media="(prefers-color-scheme: dark)" /><img style="width: 100%; max-width: 350px;" src="https://webkit.org/wp-content/uploads/Enable-Paint-Flashing-light.png" /></picture>
+</figure>
+<p>This will cause those paints to be briefly highlighted with a red overlay; you might have to scroll the page to see them. Be aware that WebKit keeps some &#8220;overdraw&#8221; tiles to allow for smooth scrolling, so paints that are not visible in the viewport can still be doing work to keep offscreen tiles up-to-date. If a paint shows in the timeline, it&#8217;s doing actual work.</p>
+<p>In addition to causing power usage by the CPU, painting usually also triggers GPU work. WebKit on macOS and iOS uses the GPU for painting, and so triggering painting can cause significant increases in power. The additional CPU usage will often show under &#8220;Other threads&#8221; in the CPU Usage timeline.</p>
+<p>The GPU is also used for <a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API"><code>&lt;canvas&gt;</code></a> rendering, both 2D canvas and WebGL/WebGPU. To minimize drawing, don&#8217;t call into the <code>&lt;canvas&gt;</code> APIs if the canvas content isn&#8217;t changing, and try to optimize your canvas drawing commands.</p>
+<p>Many Mac laptops have two GPUs, an &#8220;integrated&#8221; GPU which is on the same die as the CPU, and is less powerful but more power-efficient, and a more powerful, but more power-hungry &#8220;discrete&#8221; GPU. WebKit will default to using the integrated GPU by default; you can request the discrete GPU using the <a href="https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.2.1"><code>powerPreference</code></a> context creation parameter, but only do this if you can justify the power cost.</p>
+<h3>Networking</h3>
+<p>Wireless networking can affect battery life in unexpected ways. Phones are the most affected due to their combination of powerful radios (the WiFi and cellular network chips) with a smaller battery. Unfortunately, measuring the power impact of networking is not easy outside of a lab, but can be reduced by following some simple rules.</p>
+<p>The most direct way to reduce networking power usage is to maximize the use of the browser&#8217;s cache. All of the best practices for minimizing page load time also benefit the battery by reducing how long the radios need to be powered on.</p>
+<p>Another important aspect is to group network requests together temporally. Any time a new request comes, the operating system needs to power on the radio, connect to the base station or cell tower, and transmit the bytes. After transmitting the packets, the radio remains powered for a small amount of time in case more packets are transmitted.</p>
+<p>If a page transmits small amounts of data infrequently, the overhead can become larger than the energy required to transmit the data:</p>
+<figure class="mattewhite"><img class="wp-image-8984" src="https://webkit.org/wp-content/uploads/Networking-Power-Overhead-of-two-small-transmissions.png" alt="Networking Power Overhead of transmitting 2 packets with a delay between them" srcset="https://webkit.org/wp-content/uploads/Networking-Power-Overhead-of-two-small-transmissions.png 1162w, https://webkit.org/wp-content/uploads/Networking-Power-Overhead-of-two-small-transmissions-300x137.png 300w, https://webkit.org/wp-content/uploads/Networking-Power-Overhead-of-two-small-transmissions-768x350.png 768w, https://webkit.org/wp-content/uploads/Networking-Power-Overhead-of-two-small-transmissions-1024x467.png 1024w" sizes="(max-width: 1162px) 100vw, 1162px" /></figure>
+<p>Such issues can be discovered from Web Inspector in the <em>Network Requests</em> Timeline. For example, the following screenshot shows four separate requests (probably analytics) being sent over several seconds:</p>
+<figure class="widescreen mattewhite"><picture><source srcset="https://webkit.org/wp-content/uploads/Network-requests-should-be-grouped-dark.png" media="(prefers-color-scheme: dark)" /><img style="width: 100%; max-width: 1076px;" src="https://webkit.org/wp-content/uploads/Network-requests-should-be-grouped-light.png" /></picture></figure>
+<p>Sending all the requests at the same time would improve network power efficiency.</p>
+<h2>Conclusion</h2>
+<p>Webpages can be good citizens of battery life.</p>
+<p>It’s important to measure the battery impact in Web Inspector and drive those costs down. Doing so improves the user experience and battery life.</p>
+<p>The most direct way to improve battery life is to minimize CPU usage. The new Web Inspector provides a tool to monitor that over time.</p>
+<p>To achieve great battery life the goals are:</p>
+<ul>
+<li>Drive CPU usage to zero in idle</li>
+<li>Maximize performance during user interaction to quickly get back to idle</li>
+</ul>
+<p>If you have any questions, feel free to reach <a href="http://twitter.com/awfulben">me</a>, <a href="https://twitter.com/JosephPecoraro">Joseph Pecoraro</a>, <a href="https://twitter.com/dcrousso">Devin Rousso</a>, and of course <a href="https://twitter.com/jonathandavis">Jon Davis</a>.</p>
+]]></content:encoded>
+                                                                               </item>
+               <item>
+               <title>Release Notes for Safari Technology Preview 90</title>
+               <link>https://webkit.org/blog/9515/release-notes-for-safari-technology-preview-90/</link>
+                               <pubDate>Wed, 21 Aug 2019 20:00:45 +0000</pubDate>
+               <dc:creator><![CDATA[]]></dc:creator>
+                               <category><![CDATA[Safari Technology Preview]]></category>
+
+               <guid isPermaLink="false">https://webkit.org/?p=9515</guid>
+                               <description><![CDATA[Safari Technology Preview Release 90 is now available for download for macOS Mojave and the macOS Catalina beta.]]></description>
+                                                               <content:encoded><![CDATA[<p><a href="https://webkit.org/blog/6017/introducing-safari-technology-preview/">Safari Technology Preview</a> Release 90 is now <a href="https://webkit.org/downloads/">available for download</a> for macOS Mojave and the macOS Catalina beta. If you already have Safari Technology Preview installed, you can update in the Software Update pane of System Preferences on macOS.</p>
+<p>This release covers WebKit revisions <a href="https://trac.webkit.org/log?stop_rev=248024&amp;&amp;rev=248705&amp;limit=999">248024-248705</a>.</p>
+<h3>Web API</h3>
+<ul>
+<li>Fixed ping loads to not prevent page caching (<a href="https://trac.webkit.org/changeset/248265/webkit/">r248265</a>)</li>
+<li>Prevented <code>autofocus</code> for cross-origin iframes (<a href="https://trac.webkit.org/changeset/248491/webkit/">r248491</a>)</li>
+<li>Prevented navigations of frames about to get replaced by the result of evaluating javascript: URLs (<a href="https://trac.webkit.org/changeset/248410/webkit/">r248410</a>)</li>
+<li>Updated <code>Element.outerHTML</code> to link missing attribute prefixes in some cases in HTML documents (<a href="https://trac.webkit.org/changeset/248042/webkit/">r248042</a>)</li>
+<li>Updated the wrapper for <code>navigator.geolocation</code> to not become GC-collectable once its frame is detached (<a href="https://trac.webkit.org/changeset/248276/webkit/">r248276</a>)</li>
+</ul>
+<h3>Media</h3>
+<ul>
+<li>Fixed an issue where muted <code>&lt;video&gt;</code> elements could block the display from sleeping (<a href="https://trac.webkit.org/changeset/248387/webkit/">r248387</a>)</li>
+</ul>
+<h3>WebRTC</h3>
+<ul>
+<li>Fixed incorrect <code>this</code> in <code>negotiationneeded</code> event (<a href="https://trac.webkit.org/changeset/248267/webkit/">r248267</a>)</li>
+</ul>
+<h3>WebGPU</h3>
+<ul>
+<li>Changed WebGPU to not force discrete GPU (<a href="https://trac.webkit.org/changeset/248704/webkit/">r248704</a>)</li>
+<li>Improved WHLSL compile-time performance (<a href="https://trac.webkit.org/changeset/248025/webkit/">r248025,</a><a href="https://trac.webkit.org/changeset/248141/webkit/">r248141</a>, <a href="https://trac.webkit.org/changeset/248280/webkit/">r248280</a>, <a href="https://trac.webkit.org/changeset/248310/webkit/">r248310</a>, <a href="https://trac.webkit.org/changeset/248083/webkit/">r248083</a>)</li>
+<li>Removed <code>char</code>, <code>short</code>, and <code>half</code> types (<a href="https://trac.webkit.org/changeset/248078/webkit/">r248078</a>)</li>
+</ul>
+<h3>Web Inspector</h3>
+<ul>
+<li>Elements
+<ul>
+<li>Added a way to disable or set a breakpoint on all event listeners for a given DOM node or event type in the Node details sidebar panel (<a href="https://trac.webkit.org/changeset/248052/webkit/">r248052</a>)</li>
+<li>Added showing <code>@supports</code> CSS groupings in the Styles details sidebar panel (<a href="https://trac.webkit.org/changeset/248602/webkit/">r248602</a>)</li>
+<li>Added experimental quick-action icon buttons to each CSS rule in the Styles details sidebar panel (<a href="https://trac.webkit.org/changeset/248202/webkit/">r248202</a>)</li>
+<li>Added display of radius values in Box Model section of the Computed details sidebar panel (<a href="https://trac.webkit.org/changeset/248328/webkit/">r248328</a>)</li>
+<li>Fixed an issue where CSS variable swatches were not shown for <code>var()</code> with a fallback in the Styles details sidebar panel (<a href="https://trac.webkit.org/changeset/248279/webkit/">r248279</a>)</li>
+<li>Fixed some RTL issues in the Computed details sidebar panel (<a href="https://trac.webkit.org/changeset/248390/webkit/">r248390</a>, <a href="https://trac.webkit.org/changeset/248311/webkit/">r248311</a>)</li>
+<li>Moved psuedo-selector rules before inherited rules in the Styles details sidebar panel (<a href="https://trac.webkit.org/changeset/248204/webkit/">r248204</a>)</li>
+<li>Moved the Box Model section to the top of the Computed details sidebar panel (<a href="https://trac.webkit.org/changeset/248683/webkit/">r248683</a>)</li>
+</ul>
+</li>
+<li>Resources
+<ul>
+<li>Fixed brotli-compressed resources to correctly show as being compressed in the Resources details sidebar (<a href="https://trac.webkit.org/changeset/248284/webkit/">r248284</a>)</li>
+<li>Fixed to properly handle CSS comments with an escape character when pretty printing (<a href="https://trac.webkit.org/changeset/248197/webkit/">r248197</a>)</li>
+</ul>
+</li>
+<li>Debugger
+<ul>
+<li>Added a global breakpoint for &#8220;All Events&#8221; which will pause whenever any event listener is about to be fired (<a href="https://trac.webkit.org/changeset/248201/webkit/">r248201</a>)</li>
+</ul>
+</li>
+<li>Timelines
+<ul>
+<li>Made Heap Snapshots searchable (<a href="https://trac.webkit.org/changeset/248198/webkit/">r248198</a>)</li>
+<li>Fixed an issue where <strong>Develop</strong> > <strong>Start Timeline Recording</strong> didn’t work when focused on a detached Web Inspector window (<a href="https://trac.webkit.org/changeset/248177/webkit/">r248177</a>)</li>
+</ul>
+</li>
+<li>Console
+<ul>
+<li>Changed to always show all navigation items in the header area of the split console (<a href="https://trac.webkit.org/changeset/248180/webkit/">r248180</a>)</li>
+<li>Fixed issue where the execution context picker didn’t update when switching to the inferred context from <code>auto</code> (<a href="https://trac.webkit.org/changeset/248196/webkit/">r248196</a>)</li>
+<li>Provided a way to set an alias for previous console evaluation values (e.g. <code>$0</code>, <code>$1</code>, &#8230;,  <code>$99</code>) in case the inspected page has variables with the same name (<a href="https://trac.webkit.org/changeset/248287/webkit/">r248287</a>)</li>
+<li>Renamed <code>queryObjects</code> console command line API to <code>queryInstances</code> for clarity (<a href="https://trac.webkit.org/changeset/248434/webkit/">r248434</a>)</li>
+<li>Supported <code>console.screenshot</code> with dataURL strings (<a href="https://trac.webkit.org/changeset/248688/webkit/">r248688</a>)</li>
+</ul>
+</li>
+<li>Overlay
+<ul>
+<li>Changed to show page width and height information (<a href="https://trac.webkit.org/changeset/248053/webkit/">r248053</a>)</li>
+</ul>
+</li>
+<li>Settings
+<ul>
+<li>Added an Engineering pane to expose useful settings for WebKit engineers (<a href="https://trac.webkit.org/changeset/248391/webkit/">r248391</a>)</li>
+</ul>
+</li>
+</ul>
+<h3>Bug Fixes</h3>
+<ul>
+<li>Fixed dragging an image from Safari to Notes to correctly appear (<a href="https://trac.webkit.org/changeset/248166/webkit/">r248166</a>)</li>
+</ul>
+]]></content:encoded>
+                                                                               </item>
+               <item>
+               <title>Announcing the WebKit Tracking Prevention Policy</title>
+               <link>https://webkit.org/blog/9507/announcing-the-webkit-tracking-prevention-policy/</link>
+                               <pubDate>Wed, 14 Aug 2019 22:44:55 +0000</pubDate>
+               <dc:creator><![CDATA[]]></dc:creator>
+                               <category><![CDATA[News]]></category>
+               <category><![CDATA[Privacy]]></category>
+
+               <guid isPermaLink="false">https://webkit.org/?p=9507</guid>
+                               <description><![CDATA[Today we are publishing the WebKit Tracking Prevention Policy, covering: What types of tracking WebKit will prevent.]]></description>
+                                                               <content:encoded><![CDATA[<p>Today we are publishing the <a href="https://webkit.org/tracking-prevention-policy">WebKit Tracking Prevention Policy</a>, covering:</p>
+<ul>
+<li>What types of tracking WebKit will prevent.</li>
+<li>When other tracking countermeasures come into play such as limiting capabilities and informed user consent.</li>
+<li>How WebKit handles unintended impact of our tracking prevention.</li>
+</ul>
+<p>We’d like to thank Mozilla for their <a href="https://wiki.mozilla.org/Security/Anti_tracking_policy">anti-tracking policy</a> which served as inspiration for ours.</p>
+<p>Please send us your comments or questions about this policy to <a href="https://twitter.com/webkit">@webkit</a> on Twitter.</p>
+]]></content:encoded>
+                                                                               </item>
+               <item>
+               <title>Release Notes for Safari Technology Preview 89</title>
+               <link>https://webkit.org/blog/9497/release-notes-for-safari-technology-preview-89/</link>
+                               <pubDate>Wed, 07 Aug 2019 17:00:11 +0000</pubDate>
+               <dc:creator><![CDATA[]]></dc:creator>
+                               <category><![CDATA[Safari Technology Preview]]></category>
+
+               <guid isPermaLink="false">https://webkit.org/?p=9497</guid>
+                               <description><![CDATA[Safari Technology Preview Release 89 is now available for download for macOS Mojave and the macOS Catalina beta.]]></description>
+                                                               <content:encoded><![CDATA[<p><a href="https://webkit.org/blog/6017/introducing-safari-technology-preview/">Safari Technology Preview</a> Release 89 is now <a href="https://webkit.org/downloads/">available for download</a> for macOS Mojave and the macOS Catalina beta. If you already have Safari Technology Preview installed, you can update in the Software Update pane of System Preferences on macOS.</p>
+<p>This release covers WebKit revisions <a href="https://trac.webkit.org/log?stop_rev=247433&amp;&amp;rev=248024&amp;limit=999">247433-248024</a>.</p>
+<h3>JavaScript</h3>
+<ul>
+<li>Implemented nullish coalescing with the <code>??</code> operator for ESNext (<a href="https://trac.webkit.org/changeset/247819/webkit/">r247819</a>)</li>
+</ul>
+<h3>Web API</h3>
+<ul>
+<li>Added <code>referrerpolicy</code> attribute support for <code>&lt;script&gt;</code> elements (<a href="https://trac.webkit.org/changeset/247509/webkit/">r247509</a>)</li>
+<li>Changed <code>window.openDatabase</code> to be overridable (<a href="https://trac.webkit.org/changeset/247434/webkit/">r247434</a>)</li>
+<li>Fixed an IndexedDB error where the starting version change transaction may be neglected (<a href="https://trac.webkit.org/changeset/247649/webkit/">r247649</a>)</li>
+<li>Fixed the ability to unbold selected text when the system font is used (<a href="https://trac.webkit.org/changeset/247439/webkit/">r247439</a>)</li>
+<li>Made storing cross-origin top-level prefetches in HTTP cache optional (<a href="https://trac.webkit.org/changeset/247860/webkit/">r247860</a>)</li>
+<li>Moving right by word boundary right before an object element followed by a <code>&lt;br&gt;</code> element hangs (<a href="https://trac.webkit.org/changeset/247881/webkit/">r247881</a>)</li>
+<li>Removed support for <code>beforeload</code> on <code>link=prefetch</code> (<a href="https://trac.webkit.org/changeset/247481/webkit/">r247481</a>)</li>
+</ul>
+<h3>Compatibility</h3>
+<ul>
+<li>Fixed Daring Fireball long press highlights that were unnecessarily inflated due to false illegibility (<a href="https://trac.webkit.org/changeset/247792/webkit/">r247792</a>)</li>
+<li>Fixed contextual menu actions for YouTube videos (<a href="https://trac.webkit.org/changeset/247901/webkit/">r247901</a>)</li>
+</ul>
+<h3>Accessibility</h3>
+<ul>
+<li>Exposed the <code>aria-label</code> attribute for <code>&lt;video&gt;</code> elements (<a href="https://trac.webkit.org/changeset/247891/webkit/">r247891</a>)</li>
+</ul>
+<h3>Media</h3>
+<ul>
+<li>Enabled a WebRTC debug mode without encryption (<a href="https://trac.webkit.org/changeset/247438/webkit/">r247438</a>)</li>
+<li>Fixed support for FLAC-in-MP4 (<a href="https://trac.webkit.org/changeset/247934/webkit/">r247934</a>)</li>
+</ul>
+<h3>Web Inspector</h3>
+<ul>
+<li>Added support for <code>console.screenshot</code> with detached (not in main DOM tree) <code>&lt;img&gt;</code> and <code>&lt;picture&gt;</code> elements (<a href="https://trac.webkit.org/changeset/247814/webkit/">r247814</a>)</li>
+<li>Added support for <code>console.screenshot</code> with <code>ImageData</code> and <code>ImageBitmap</code> (<a href="https://trac.webkit.org/changeset/247812/webkit/">r247812</a>)</li>
+<li>Added a &#8220;Show Grid&#8221; navigation item for the Images collection in the Resources tab (<a href="https://trac.webkit.org/changeset/248004/webkit/">r248004</a>)</li>
+<li>Added an indicator/separator around items in the Images collection in the Resources tab (<a href="https://trac.webkit.org/changeset/248019/webkit/">r248019</a>)</li>
+<li>Add special case for <code>about:blank</code> resources to show &#8220;Resource has no content&#8221; message (<a href="https://trac.webkit.org/changeset/247747/webkit/">r247747</a>)</li>
+<li>Fixed display of <code>application/xml</code> content for XHR requests (<a href="https://trac.webkit.org/changeset/247533/webkit/">r247533</a>)</li>
+<li>Fixed issues toggling multiple breakpoints when they&#8217;re collapsed into one line (<a href="https://trac.webkit.org/changeset/247639/webkit/">r247639</a>)</li>
+<li>Fixed Command-X (⌘X) to cut selected properties in the Styles sidebar (<a href="https://trac.webkit.org/changeset/247760/webkit/">r247760</a>)</li>
+<li>Made the Changes panel in the Elements Tab render with LTR text direction (<a href="https://trac.webkit.org/changeset/247492/webkit/">r247492</a>)</li>
+</ul>
+<h3>WebGPU</h3>
+<ul>
+<li>Implemented errors for GPURenderPipeline creation (<a href="https://trac.webkit.org/changeset/247764/webkit/">r247764</a>)</li>
+<li>Added descriptive error messages in WHLSL (<a href="https://trac.webkit.org/changeset/247834/webkit/">r247834</a>)</li>
+<li>Changed checker to <code>setError()</code> when a property access node can&#8217;t commit its base type in WHLSL (<a href="https://trac.webkit.org/changeset/247676/webkit/">r247676</a>)</li>
+<li>Changed to return the zero-value enum in the enum-from-integer constructor when the integer is not a valid enum value in WHLSL (<a href="https://trac.webkit.org/changeset/247675/webkit/">r247675</a>)</li>
+<li>Made enums work in WHLSL (<a href="https://trac.webkit.org/changeset/247666/webkit/">r247666</a>)</li>
+<li>Updated matrix memory layout to match HLSL by laying out columns linearly in WHLSL (<a href="https://trac.webkit.org/changeset/247468/webkit/">r247468</a>)</li>
+</ul>
+]]></content:encoded>
+                                                                               </item>
+               <item>
+               <title>Changing Page Settings on iOS Using Web Inspector</title>
+               <link>https://webkit.org/blog/9454/changing-page-settings-on-ios-using-web-inspector/</link>
+                               <pubDate>Fri, 02 Aug 2019 05:56:25 +0000</pubDate>
+               <dc:creator><![CDATA[]]></dc:creator>
+                               <category><![CDATA[Web Inspector]]></category>
+
+               <guid isPermaLink="false">https://webkit.org/?p=9454</guid>
+                               <description><![CDATA[If you&#8217;ve ever used Web Inspector before, chances are you&#8217;ve used (or are at least familiar with) the Develop menu.]]></description>
+                                                               <content:encoded><![CDATA[<style>figure picture img { width: 100%; }</style>
+<style>@media (prefers-color-scheme:dark) { figure picture img { filter: none; } }</style>
+<p>If you&#8217;ve ever used Web Inspector before, chances are you&#8217;ve used (or are at least familiar with) the <strong>Develop</strong> menu.  It holds action items and toggles for various settings of the browser, like whether local files (e.g. URLs beginning with <code>file://</code>) can be loaded or whether CSS is applied to each page.</p>
+<figure class="widescreen mattewhite">
+  <picture title="Develop Menu"><source srcset="https://webkit.org/wp-content/uploads/Develop_Menu_Dark.png" media="(prefers-color-scheme: dark)"><img src="https://webkit.org/wp-content/uploads/Develop_Menu_Light.png" style="max-width: 431px">
+  </picture>
+</figure>
+<p>All of these items apply to the entire browser, meaning that if you <strong>Disable Styles</strong> on one page, every other page will be affected.</p>
+<p>Additionally, these items have no effect when using Web Inspector to inspect a remote target, like an iOS device or simulator. Checking <strong>Disable Styles</strong> in the <strong>Develop</strong> menu will not have any affect on the remote target.</p>
+<p>In order to support this development workflow, Web Inspector has added a device settings menu that allows these settings to be toggled per-page when being remotely inspected.</p>
+<p>Clicking on the device settings menu icon will show a popover with many of the same settings as the <strong>Develop</strong> menu.</p>
+<figure class="widescreen mattewhite">
+  <picture title="Device Settings Menu"><source srcset="https://webkit.org/wp-content/uploads/Device_Settings_Menu_Dark.png" media="(prefers-color-scheme: dark)"><img src="https://webkit.org/wp-content/uploads/Device_Settings_Menu_Light.png" style="max-width: 1000px">
+  </picture>
+</figure>
+<p>Since these settings apply per-page and only on the remote target, the corresponding actions in the <strong>Develop</strong> menu are disabled, as they have no effect on a remote target:</p>
+<ul>
+<li><strong>Disable Images</strong></li>
+<li><strong>Disable Styles</strong></li>
+<li><strong>Disable JavaScript</strong></li>
+<li><strong>Disable Site-specific Hacks</strong></li>
+<li><strong>Disable Cross-Origin Restrictions</strong></li>
+<li>WebRTC
+<ul>
+<li><strong>Allow Media Capture on Insecure Sites</strong></li>
+<li><strong>Disable ICE Candidate Restrictions</strong></li>
+<li><strong>Use Mock Capture Devices</strong></li>
+</ul>
+</li>
+</ul>
+<p>Along these lines, the device settings menu is only shown when using Web Inspector to inspect a remote target.</p>
+<p>Device settings are <em>not</em> preserved between Web Inspector sessions.  Closing Web Inspector (or disconnecting the inspected device) will cause all previously set device settings for the inspected page to reset.</p>
+<p>Device settings are preserved across navigations, however, so long as Web Inspector stays open/connected.</p>
+<h2 id="UserAgent">User Agent</h2>
+<p>The first item in the device settings menu is the <strong>User Agent</strong> editor.  It contains a list of <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent">common user agents</a>, as well as an option to input a <a href="https://en.wikipedia.org/wiki/User_agent#Use_in_HTTP">custom user agent</a> (<strong>Other…</strong>).</p>
+<p>Each time the <strong>User Agent</strong> is modified, the inspected page will automatically reload so that the new <strong>User Agent</strong> is applied.</p>
+<h2 id="Disable">Disable Toggles</h2>
+<p>Each of these toggles, when checked, disables a specific piece of functionality in the inspected page.</p>
+<ul>
+<li><strong>Images</strong> will prevent any not-yet loaded images from loading, but will have no effect on any already loaded images.</li>
+<li><strong>Styles</strong> will immediately disable all CSS on the page, including inline <code>&lt;style&gt;</code>s and any <code>style</code> DOM attributes.</li>
+<li><strong>JavaScript</strong> will cause the page to ignore any <em>future</em> JavaScript from being run, including new <code>&lt;script&gt;</code> elements (the underlying resource isn&#8217;t even requested) and callbacks for previously added event listeners.</li>
+<li><strong>Site-specific Hacks</strong> controls whether workarounds are made by WebKit to support compatibility on certain sites.
+<ul>
+<li>A list of these sites can be found in <a href="https://trac.webkit.org/browser/webkit/trunk/Source/WebCore/page/Quirks.cpp">Source/WebCore/page/Quirks.cpp</a>.</li>
+<li>If you develop a site that is found in that list, we <em>strongly</em> encourage developing and testing with <strong>Site-specific Hacks</strong> <em>disabled</em>.</li>
+</ul>
+</li>
+<li><strong>Cross-Origin Restrictions</strong> controls whether <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS">CORS</a> rules/restrictions are active for any <em>future</em> network requests.</li>
+</ul>
+<h2 id="WebRTC">WebRTC Toggles</h2>
+<p>These toggles focus specifically on functionality related to <a href="https://webrtc.org/">WebRTC</a>.</p>
+<ul>
+<li><strong>Allow Media Capture on Insecure Sites</strong> will allow <a href="https://webkit.org/blog/7726/announcing-webrtc-and-media-capture/">WebRTC media capture</a> to be used/tested on insecure (e.g. non-https) pages for any <em>future</em> calls of <code>getUserMedia</code>.</li>
+<li><strong>Disable ICE Candidate Restrictions</strong> will prevent <a href="https://webkit.org/blog/7763/a-closer-look-into-webrtc/">host ICE candidates from being filtered</a> for <em>new</em> connection attempts.</li>
+<li><strong>Use Mock Capture Devices</strong> will replace all <a href="https://webkit.org/blog/7726/announcing-webrtc-and-media-capture/">capture devices</a> with a mock &#8220;Bip-Bop&#8221; device for any <em>future</em> calls of <code>getUserMedia</code>.<br />
+<figure style="margin: 0.5em"><img class="preserve-color wp-image-9459" src="https://webkit.org/wp-content/uploads/Mock_Capture_Device.png" title="Mock Capture Device" srcset="https://webkit.org/wp-content/uploads/Mock_Capture_Device.png 2580w, https://webkit.org/wp-content/uploads/Mock_Capture_Device-300x113.png 300w, https://webkit.org/wp-content/uploads/Mock_Capture_Device-768x290.png 768w, https://webkit.org/wp-content/uploads/Mock_Capture_Device-1024x387.png 1024w" sizes="(max-width: 2580px) 100vw, 2580px" /></figure>
+</li>
+<li><strong>Disable Encryption</strong> will cause <em>future</em> connections to be established and <em>future</em> streams (from those connections) to be transmitted <em>without</em> any form of encryption.</li>
+</ul>
+<h2>Feedback</h2>
+<p>You can try out changing device settings with iOS 12.2 or later. Let us know how it works for you. Send feedback on Twitter (<a href="https://twitter.com/webkit">@webkit</a>, <a href="https://twitter.com/dcrousso">@dcrousso</a>) or by <a href="https://feedbackassistant.apple.com/">filing a bug</a>.</p>
+]]></content:encoded>
+                                                                               </item>
+               <item>
+               <title>Release Notes for Safari Technology Preview 88</title>
+               <link>https://webkit.org/blog/9445/release-notes-for-safari-technology-preview-88/</link>
+                               <pubDate>Wed, 24 Jul 2019 17:00:59 +0000</pubDate>
+               <dc:creator><![CDATA[]]></dc:creator>
+                               <category><![CDATA[Safari Technology Preview]]></category>
+
+               <guid isPermaLink="false">https://webkit.org/?p=9445</guid>
+                               <description><![CDATA[Safari Technology Preview Release 88 is now available for download for macOS Mojave and the macOS Catalina beta.]]></description>
+                                                               <content:encoded><![CDATA[<p><a href="https://webkit.org/blog/6017/introducing-safari-technology-preview/">Safari Technology Preview</a> Release 88 is now <a href="https://webkit.org/downloads/">available for download</a> for macOS Mojave and the macOS Catalina beta. If you already have Safari Technology Preview installed, you can update in the Software Update pane of System Preferences on macOS.</p>
+<p>This release covers WebKit revisions <a href="https://trac.webkit.org/log?stop_rev=247047&amp;&amp;rev=247433&amp;limit=999">247047-247433</a>.</p>
+<h3>JavaScript</h3>
+<ul>
+<li>Enabled <code>Intl.PluralRules</code> and <code>Intl.NumberFormatToParts</code> by default (<a href="https://trac.webkit.org/changeset/247247/webkit/">r247247</a>)</li>
+</ul>
+<h3>WebRTC</h3>
+<ul>
+<li>Registered a MediaStreamTrack as media producer only if it is a capture track (<a href="https://trac.webkit.org/changeset/247208/webkit/">r247208</a>, <a href="https://trac.webkit.org/changeset/247382/webkit/">r247382</a>)</li>
+</ul>
+<h3>Web API</h3>
+<ul>
+<li>Fixed XHR CORS requests getting logged twice on the server (<a href="https://trac.webkit.org/changeset/247276/webkit/">r247276</a>)</li>
+</ul>
+<h3>Pointer Events</h3>
+<ul>
+<li>Updated to respect pointer capture when dispatching mouse boundary events and updating <code>:hover</code> (<a href="https://trac.webkit.org/changeset/247148/webkit/">r247148</a>)</li>
+</ul>
+<h3>Rendering</h3>
+<ul>
+<li>Changed to avoid extra backing store on elements with <code>overflow: scroll</code> and <code>visibility: hidden</code> (<a href="https://trac.webkit.org/changeset/247420/webkit/">r247420</a>)</li>
+<li>Changed to trigger a compositing update when a video element is changing (<a href="https://trac.webkit.org/changeset/247187/webkit/">r247187</a>)</li>
+</ul>
+<h3>Accessibility</h3>
+<ul>
+<li>Added accessibility announcement notifications to show, dismiss and selection change for the datalist suggestions view (<a href="https://trac.webkit.org/changeset/247418/webkit/">r247418</a>)</li>
+<li>Exposed HTML datalist accessibility (<a href="https://trac.webkit.org/changeset/247295/webkit/">r247295</a>)</li>
+<li>Enhanced support of <code>aria-haspopup</code> per ARIA 1.1 specification. (<a href="https://trac.webkit.org/changeset/247071/webkit/">r247071</a>)</li>
+<li>Implemented support for ARIA roles: insertion, deletion, subscript, superscript, and time (<a href="https://trac.webkit.org/changeset/247349/webkit/">r247349</a>)</li>
+<li>Fixed ignored <code>role="presentation"</code> on HTML <code>&lt;table&gt;</code> elements for VoiceOver (<a href="https://trac.webkit.org/changeset/247330/webkit/">r247330</a>)</li>
+</ul>
+<h3>WebGL</h3>
+<ul>
+<li>Hooked up WebGL&#8217;s back buffer in ANGLE backend on macOS (<a href="https://trac.webkit.org/changeset/247315/webkit/">r247315</a>)</li>
+</ul>
+<h3>WebGPU</h3>
+<ul>
+<li>Added most of the remainder of the standard library (<a href="https://trac.webkit.org/changeset/247174/webkit/">r247174</a>)</li>
+<li>Implemented GPUError and error scopes (<a href="https://trac.webkit.org/changeset/247366/webkit/">r247366</a>)</li>
+<li>Made the destructor of VariableDeclaration non-virtual (<a href="https://trac.webkit.org/changeset/247124/webkit/">r247124</a>)</li>
+<li>Optimized the lexer (<a href="https://trac.webkit.org/changeset/247171/webkit/">r247171</a>)</li>
+<li>Removed the phase resolveCallsInFunctions (<a href="https://trac.webkit.org/changeset/247170/webkit/">r247170</a>)</li>
+</ul>
+<h3>Web Inspector</h3>
+<ul>
+<li>Added support for pasting copied DOM nodes in the Elements tab (<a href="https://trac.webkit.org/changeset/247054/webkit/">r247054</a>)</li>
+<li>Fixed dismissing a blank property to no longer cause the rule to appear in the Changes panel (<a href="https://trac.webkit.org/changeset/247406/webkit/">r247406</a>)</li>
+<li>Fixed an issue where unbalanced quotes or parenthesis weren’t displayed as properly closed after editing values (<a href="https://trac.webkit.org/changeset/247196/webkit/">r247196</a>)</li>
+<li>Updated descendant DOM breakpoints be enabled, disabled, or deleted from a collapsed parent (<a href="https://trac.webkit.org/changeset/247053/webkit/">r247053</a>)</li>
+</ul>
+<h3>Bug Fixes</h3>
+<ul>
+<li>Fixed paste from Notes into Excel 365 spreadsheet (<a href="https://trac.webkit.org/changeset/247222/webkit/">r247222</a>)</li>
+<li>Fixed video playback on xfinity.com/stream on macOS Catalina (<a href="https://trac.webkit.org/changeset/247213/webkit/">r247213</a>)</li>
+</ul>
+]]></content:encoded>
+                                                                               </item>
+               <item>
+               <title>Release Notes for Safari Technology Preview 87</title>
+               <link>https://webkit.org/blog/9414/release-notes-for-safari-technology-preview-87/</link>
+                               <pubDate>Wed, 10 Jul 2019 17:00:51 +0000</pubDate>
+               <dc:creator><![CDATA[]]></dc:creator>
+                               <category><![CDATA[Safari Technology Preview]]></category>
+
+               <guid isPermaLink="false">https://webkit.org/?p=9414</guid>
+                               <description><![CDATA[Safari Technology Preview Release 87 is now available for download for macOS Mojave and the macOS Catalina beta.]]></description>
+                                                               <content:encoded><![CDATA[<p><a href="https://webkit.org/blog/6017/introducing-safari-technology-preview/">Safari Technology Preview</a> Release 87 is now <a href="https://webkit.org/downloads/">available for download</a> for macOS Mojave and the macOS Catalina beta. If you already have Safari Technology Preview installed, you can update in the Software Update pane of System Preferences on macOS.</p>
+<p>This release covers WebKit revisions <a href="https://trac.webkit.org/log?stop_rev=246691&amp;&amp;rev=247047&amp;limit=999">246691-247047</a>.</p>
+<h3>Web API</h3>
+<ul>
+<li>Changed <code>openDatabase</code> to return an empty object when WebSQL is disabled (<a href="https://trac.webkit.org/changeset/246707/webkit/">r246707</a>)</li>
+<li>Added an experimental behavior to prevent a 5 second delay for initial paint on pages that are using Google&#8217;s anti-flicker optimization when content blockers are enabled (<a href="https://trac.webkit.org/changeset/246764/webkit/">r246764</a>)</li>
+</ul>
+<h3>Web Sockets</h3>
+<ul>
+<li>Added support for sending blob messages when using web sockets platform APIs (<a href="https://trac.webkit.org/changeset/246964/webkit/">r246964</a>)</li>
+</ul>
+<h3>Payment Request</h3>
+<ul>
+<li>Changed to set state to Closed when <code>show()</code> is called during an active session (<a href="https://trac.webkit.org/changeset/246863/webkit/">r246863</a>)</li>
+</ul>
+<h3>Experimental Web Shading Language (WHLSL)</h3>
+<ul>
+<li>Implemented arrays (<a href="https://trac.webkit.org/changeset/246875/webkit/">r246875</a>)</li>
+</ul>
+<h3>Rendering</h3>
+<ul>
+<li>Fixed incorrect clipping with <code>overflow: scroll</code> inside <code>overflow: hidden</code> with <code>border-radius</code> (<a href="https://trac.webkit.org/changeset/246845/webkit/">r246845</a>)</li>
+<li>Fixed the preview of a <code>&lt;picture&gt;</code> element to match the element bounds (<a href="https://trac.webkit.org/changeset/246695/webkit/">r246695</a>)</li>
+</ul>
+<h3>WebGPU</h3>
+<ul>
+<li>Made WebGPU enabled only on Mojave and later (<a href="https://trac.webkit.org/changeset/246888/webkit/">r246888</a>)</li>
+</ul>
+<h3>Web Inspector</h3>
+<ul>
+<li>Implemented <code>console.countReset</code> (<a href="https://trac.webkit.org/changeset/246850/webkit/">r246850</a>)</li>
+<li>Implemented <code>console.timeLog</code> (<a href="https://trac.webkit.org/changeset/246798/webkit/">r246798</a>)</li>
+<li>Added additional demo audits for other <code>WebInspectorAudit</code> functions (<a href="https://trac.webkit.org/changeset/247042/webkit/">r247042</a>)</li>
+<li>Enable the Show Shadow DOM navigation item by default in the Elements tab (<a href="https://trac.webkit.org/changeset/246821/webkit/">r246821</a>)</li>
+</ul>
+<h3>Known Issues</h3>
+<ul>
+<li>Open tabs are blank on initial launch after upgrading to Safari Technology Preview 87 and loading all tabs from the last session. To correct this behavior, reload open tabs or relaunch Safari Technology Preview.</li>
+</ul>
+]]></content:encoded>
+                                                                               </item>
+               <item>
+               <title>WebDriver is Coming to Safari in iOS 13</title>
+               <link>https://webkit.org/blog/9395/webdriver-is-coming-to-safari-in-ios-13/</link>
+                               <pubDate>Mon, 08 Jul 2019 17:00:58 +0000</pubDate>
+               <dc:creator><![CDATA[]]></dc:creator>
+                               <category><![CDATA[Web Inspector]]></category>
+
+               <guid isPermaLink="false">https://webkit.org/?p=9395</guid>
+                               <description><![CDATA[As anyone who has developed a mobile-friendly site can tell you, mobile browsers and desktop browsers are different.]]></description>
+                                                               <content:encoded><![CDATA[<p>As anyone who has developed a mobile-friendly site can tell you, mobile browsers and desktop browsers are different. As device capabilities continue to evolve and users move more of their browsing to mobile browsers, web developers are facing an increasing need to write automated tests for the mobile web in the same way that desktop-oriented site content is tested.</p>
+<p>Starting in iOS 13, Safari now includes native support for the <a href="https://www.w3.org/TR/webdriver/">W3C WebDriver</a> standard. This feature builds on existing support for WebDriver in desktop Safari, first introduced in Safari 10 and macOS Sierra. This blog post explains how to get started with WebDriver for iOS, how to port your existing desktop-oriented tests, and a few details regarding safeguards and changes in behavior.</p>
+<h2>Getting Started</h2>
+<p>Control via WebDriver is exposed to developers via the <code>/usr/bin/safaridriver</code> executable, which hosts a driver that handles REST API requests sent by WebDriver test clients. In order to run WebDriver tests on an iOS device, it must be plugged into a macOS host that has a new enough version of safaridriver. Support for hosting iOS-based WebDriver sessions is available in safaridriver included with Safari 13 and later. Older versions of safaridriver do not support iOS WebDriver sessions.</p>
+<p>If you&#8217;ve never used safaridriver on macOS before, you&#8217;ll first need to run <code>safaridriver --enable</code> and authenticate as an administrator. Then, you must enable Remote Automation on every device that you intend to use for WebDriver. To do this, toggle the setting in Settings → Safari → Advanced → Remote Automation.</p>
+<figure class="widescreen"><picture><source srcset="https://webkit.org/wp-content/uploads/IMG_0010.png" media="(prefers-color-scheme: dark)" /><img class="wp-image-9396" src="https://webkit.org/wp-content/uploads/IMG_0009.png" alt="Remote Automation Setting on iOS" srcset="https://webkit.org/wp-content/uploads/IMG_0009.png 2732w, https://webkit.org/wp-content/uploads/IMG_0009-300x225.png 300w, https://webkit.org/wp-content/uploads/IMG_0009-768x576.png 768w, https://webkit.org/wp-content/uploads/IMG_0009-1024x768.png 1024w" sizes="(max-width: 2732px) 100vw, 2732px" /></picture></figure>
+<p>Lastly, to run tests on the device, you&#8217;ll need to plug it into the macOS machine, <a href="https://support.apple.com/en-us/HT202778">trust the host</a>, and ensure that it is unlocked when you try to start the WebDriver session.</p>
+<p>Since safaridriver is capable of starting WebDriver sessions using Safari on the macOS host or Safari on an attached iOS device, it needs a little extra hint to know that you want to use a device or a desktop machine. To facilitate this, safaridriver supports many new capabilities that may be provided with a new session request. The most important new capability to use is <strong>&#8216;platformName&#8217;: &#8216;ios&#8217;;</strong> this tells the driver you want an iOS host instead of a macOS host. You can also specify the host(s) you wish to use by specifying device type, device UDID, device name, OS version, OS build, and browser version via standardized and extension capabilities. Lastly, safaridriver supports running WebDriver tests on iOS Simulator devices whose runtime is iOS 13 or later. To use a simulator for testing, add the capability <strong>&#8216;safari:useSimulator&#8217;: true</strong>. For a full list of supported capabilities and their semantics, please consult the safaridriver(1) man page by executing <code>man safaridriver.</code></p>
+<h2>Safeguards</h2>
+<p>While it’s awesome to be able to write automated tests that run in Safari, a REST API for browser automation introduces a potential vector for malicious software. To support a valuable automation API without sacrificing a user’s privacy or security, Safari’s driver implementation introduces extra safeguards that further restrict browsing in WebDriver sessions. These safeguards also double as extra insurance against “<a href="http://martinfowler.com/articles/nonDeterminism.html">flaky tests</a>” by providing enhanced test isolation. Some of these safeguards are described below.</p>
+<p>Just like on macOS, Safari on iOS isolates WebDriver tests by using a separate set of windows, tabs, preferences, and persistent storage. When a WebDriver session is active, existing tabs are hidden and a distinctively-colored WebDriver window is shown instead. Automation windows are easy to recognize by their orange Smart Search field. Similar to browsing in a Private Browsing window, WebDriver tests that run in an Automation window always start from a clean slate and cannot access Safari’s normal browsing history, AutoFill data, or other sensitive information. Aside from the obvious privacy benefits, this restriction also helps to ensure that tests are not affected by a previous test session’s persistent state such as local storage or cookies. When the WebDriver session terminates, the orange window goes away, preexisting tabs are restored, and any state accumulated during the WebDriver session is destroyed.</p>
+<p>As a WebDriver test is executing in an Automation window, any attempts to interact with the window or web content could derail the test by unexpectedly changing the state of the page. To prevent this from happening, Safari installs a “glass pane” over the Automation window while the test is running. This blocks any stray interactions (mouse, keyboard, resizing, and so on) from affecting the Automation window. If a running test gets stuck or fails, it’s possible to interrupt the running test by tapping on the screen and choosing to end the session. When an automation session is interrupted, the test’s connection to the browser is permanently severed and cannot be resumed. Notifications and system gestures (i.e., slide in from top/bottom) are also suppressed while WebDriver tests are running in order to avoid flakiness.</p>
+<figure><img class="preserve-color wp-image-9410" src="https://webkit.org/wp-content/uploads/webdriver-ios13beta.jpg" alt="Glass Pane" srcset="https://webkit.org/wp-content/uploads/webdriver-ios13beta.jpg 1125w, https://webkit.org/wp-content/uploads/webdriver-ios13beta-139x300.jpg 139w, https://webkit.org/wp-content/uploads/webdriver-ios13beta-768x1663.jpg 768w, https://webkit.org/wp-content/uploads/webdriver-ios13beta-473x1024.jpg 473w" sizes="(max-width: 1125px) 100vw, 1125px" /></figure>
+<p>A non-goal of this release is to support general-purpose device automation via the WebDriver API. The W3C WebDriver API focuses on automating interactions with web content, and that is also the focus of the WebDriver support added in iOS 13. Other means exist to change system-level configuration with the <a href="https://developer.apple.com/documentation/xctest">XCTest Framework</a>, and are complimentary to WebDriver. There are other ways in which web content interacts with the rest of iOS, and most of these are suppressed in order to provide a stable testing environment. Safari for iOS does not allow WebDriver-initiated navigations to be handled outside of Safari. In other words, clicking a <code>tel://</code> link will not offer to place a phone call, and clicking an app store link will not redirect the user to the App Store. Similarly, non-Safari content displayed by the system–such as update dialogs, app notifications, incoming calls, etc.–are suppressed while a WebDriver session is active. Lastly, the software keyboard is suppressed when focusing text fields in WebDriver sessions. To simulate text input with WebDriver, use the existing <a href="https://w3c.github.io/webdriver/#perform-actions">Perform Actions endpoint</a> or <a href="https://w3c.github.io/webdriver/#element-send-keys">Element Send Keys endpoint</a>.</p>
+<h2>Porting Tests</h2>
+<p>A major goal of iOS 13 is to make it easier to develop and consume desktop-like web experiences on mobile devices. Towards that end, a major goal for WebDriver on iOS is to make it easy to port existing desktop-oriented WebDriver tests to work with Desktop-class browsing in Safari on iPadOS. As much as we&#8217;d like to treat macOS and iOS devices the same in our tests, there are important differences that affect how you may want to use WebDriver.</p>
+<p>The first notable difference is handling of user input, namely touch and clicks. In this initial version of WebDriver on iOS, simulated input sources include keyboard, mouse, and single-finger touches. The Perform Actions command and <a href="https://w3c.github.io/webdriver/#element-click">Element Click command</a> synthesize touches using mouse inputs. If your existing test uses mouse clicks, double, clicks, and drags, safaridriver converts these interactions into equivalent single finger touches; no code needs to be changed. <em>Multiple touch input sources (i.e., fingers) are not supported in this release</em>. We experimented with offering this via the existing Perform Actions endpoint, but found that it was difficult to author WebDriver commands that performed well-known gestures such as flick, pinch, pan, and so on. This is partly due to the low-level nature of the Actions API, and partly due to the timing-sensitive nature of gesture recognizers used by Safari and WebKit. Apple is working within the W3C WebDriver working group to define a more expressive, intuitive, and stable API for performing gestures in WebDriver tests.</p>
+<p>A less surprising difference between macOS and iOS WebDriver is that endpoints to manipulate the OS window are generally not supported by Safari on iOS. Specifically, the Set Window Rect, Minimize Window, and Maximize Window endpoints will return <em>&#8220;unsupported operation&#8221;</em>. For more detailed information concerning which endpoints are supported, see the <a href="https://developer.apple.com/documentation/webkit/about_webdriver_for_safari">W3C WebDriver Commands reference</a>.</p>
+<h2>Summary</h2>
+<p>With the introduction of native WebDriver support in Safari on iOS 13, it’s now possible to run the same automated tests of desktop-oriented web content on desktop and mobile devices equally. Safari’s support comes with new, exclusive safeguards to simultaneously protect user security and privacy and also help you write more stable and consistent tests. You can try out Safari’s WebDriver support today by installing a beta of <a href="https://developer.apple.com/macos/">macOS Catalina</a> and <a href="https://developer.apple.com/ios/">iOS 13</a>.</p>
+<p>If you encounter unexpected behavior in Safari’s WebDriver support, or have other suggestions for improvement, please file a bug at <a href="https://bugreport.apple.com/">https://bugreport.apple.com/</a>. For quick questions or feedback, email <a href="mailto:web-evangelist@apple.com">web-evangelist@apple.com</a> or tweet <a href="https://www.twitter.com/webkit">@webkit</a> on Twitter. Happy testing!</p>
+]]></content:encoded>
+                                                                               </item>
+       </channel>
+</rss>
+
+<!-- Dynamic page generated in 0.246 seconds. -->
+<!-- Cached page generated by WP-Super-Cache on 2019-09-13 13:00:20 -->
diff --git a/LayoutTests/inspector/formatting/resources/xml-tests/valid-html-invalid-xml-expected.xml b/LayoutTests/inspector/formatting/resources/xml-tests/valid-html-invalid-xml-expected.xml
new file mode 100644 (file)
index 0000000..cff4fcc
--- /dev/null
@@ -0,0 +1,4 @@
+<outer>
+    <img src="1">
+        <img src="2">
+</outer>
diff --git a/LayoutTests/inspector/formatting/resources/xml-tests/valid-html-invalid-xml.xml b/LayoutTests/inspector/formatting/resources/xml-tests/valid-html-invalid-xml.xml
new file mode 100644 (file)
index 0000000..b9c1de1
--- /dev/null
@@ -0,0 +1 @@
+<outer><img src="1"><img src="2"></outer>
diff --git a/LayoutTests/inspector/formatting/resources/xml-tests/xslt-expected.xml b/LayoutTests/inspector/formatting/resources/xml-tests/xslt-expected.xml
new file mode 100644 (file)
index 0000000..2748760
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="iso8859-5"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+    <xsl:output method="html" encoding="KOI8-R"/>
+    <xsl:template match="TEST">
+        <html>
+            <body>
+                <script>
+                if (window.testRunner)
+                    testRunner.dumpAsText();
+                document.write("Encoding: " + document.characterSet);
+                </script>
+            </body>
+        </html>
+    </xsl:template>
+</xsl:stylesheet>
diff --git a/LayoutTests/inspector/formatting/resources/xml-tests/xslt.xml b/LayoutTests/inspector/formatting/resources/xml-tests/xslt.xml
new file mode 100644 (file)
index 0000000..826c8df
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="iso8859-5"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+<xsl:output method="html" encoding="KOI8-R"/>
+<xsl:template match="TEST"><html><body>
+<script>
+if (window.testRunner) testRunner.dumpAsText();                
+document.write("Encoding: " + document.characterSet);
+</script></body></html></xsl:template></xsl:stylesheet>
index ef59f8f..0da6931 100644 (file)
@@ -1,5 +1,41 @@
 2019-09-13  Joseph Pecoraro  <pecoraro@apple.com>
 
+        Web Inspector: HTML Formatter - XML mode
+        https://bugs.webkit.org/show_bug.cgi?id=201758
+
+        Reviewed by Devin Rousso.
+
+        * Tools/HTMLFormatter/index.html:
+        * Tools/SourceMaps/index.html:
+        Update Tools to more easily test XML.
+
+        * UserInterface/Proxies/FormatterWorkerProxy.js:
+        (WI.FormatterWorkerProxy.prototype.formatXML):
+        * UserInterface/Views/TextEditor.js:
+        (WI.TextEditor.prototype.hasFormatter):
+        (WI.TextEditor.prototype._startWorkerPrettyPrint):
+        Allow formatting XML content.
+
+        * UserInterface/Workers/Formatter/FormatterWorker.js:
+        (FormatterWorker.prototype.formatHTML):
+        (FormatterWorker.prototype.formatXML):
+        Expose "formatXML".
+
+        * UserInterface/Workers/Formatter/HTMLFormatter.js:
+        (HTMLFormatter.let.dom):
+        (HTMLFormatter):
+        (HTMLFormatter.prototype._shouldHaveNoChildren):
+        (HTMLFormatter.prototype._before):
+        (HTMLFormatter.prototype._after):
+        * UserInterface/Workers/Formatter/HTMLParser.js:
+        (HTMLParser.prototype.parseDocument):
+        * UserInterface/Workers/Formatter/HTMLTreeBuilderFormatter.js:
+        (HTMLTreeBuilderFormatter.prototype._isEmptyNode):
+        Give the HTMLFormatter and related classes an XML mode that
+        has less of the smarts of XML.
+
+2019-09-13  Joseph Pecoraro  <pecoraro@apple.com>
+
         Web Inspector: HTML Formatting: Handle infinite loop for incomplete script data
         https://bugs.webkit.org/show_bug.cgi?id=201769
 
index 35e34b6..580ffe5 100644 (file)
         <option value="html-css-js">HTML with Styles and Script</option>
         <option value="self">Self</option>
     </select>
+    <select id="source-type">
+        <option value="text/html">HTML</option>
+        <option value="text/xml">XML</option>
+    </select>
     <button id="format">Format</button>
     <button id="select-output">Select Output</button>
     <button id="save-as-url">Save URL</button>
@@ -60,6 +64,7 @@
     <script>
     // Elements.
     const populatePicker = document.getElementById("populate");
+    const sourceTypePicker = document.getElementById("source-type");
     const timeOutput = document.getElementById("time");
     const prettyPre = document.getElementById("pretty");
     const debugPre = document.getElementById("debug");
             clearTimeout(timer);
 
         // Time the formatter.
+        let sourceType = sourceTypePicker.value === "text/html" ? HTMLFormatter.SourceType.HTML : HTMLFormatter.SourceType.XML;
         let startTime = Date.now();
-        let formatter = new HTMLFormatter(cm.getValue());
+        let formatter = new HTMLFormatter(cm.getValue(), sourceType);
         let endTime = Date.now();
 
         // Show debug parser info.
         let debugText = "";
         try {
+            let options = {isXML: sourceType === HTMLFormatter.SourceType.XML};
             let parser = new HTMLParser;
             let treeBuilder = new HTMLTreeBuilderDebug;
-            parser.parseDocument(cm.getValue(), treeBuilder);
+            parser.parseDocument(cm.getValue(), treeBuilder, options);
             debugText = treeBuilder.debugText;
         } catch (error) {
             debugText = "Parse error: " + JSON.stringify(error, null, 2);
     document.getElementById("save-as-url").addEventListener("click", (event) => {
         let content = cm.getValue();
         let populate = populatePicker.value;
-        window.location.search = `?content=${encodeURIComponent(content)}&populate=${encodeURIComponent(populate)}`;
+        let sourceType = sourceTypePicker.value;
+        window.location.search = `?content=${encodeURIComponent(content)}&populate=${encodeURIComponent(populate)}&sourceType=${encodeURIComponent(sourceType)}`;
     });
 
     const simpleHTML = `<!DOCTYPE html>
         updateContentFromPicker();
     });
 
+    // Parser mode picker.
+    sourceTypePicker.addEventListener("change", (event) => {
+        cm.setOption("mode", sourceTypePicker.value);
+        refresh();
+    });
+
     // Restore better initial value from query string.
     (function() {
         let queryParams = {};
             populatePicker.value = queryParams.populate;
             updateContentFromPicker();
         }
+        if (queryParams.sourceType) {
+            sourceTypePicker.value = queryParams.sourceType;
+            cm.setOption("mode", sourceTypePicker.value);
+        }
         if (queryParams.content)
             cm.setValue(queryParams.content);
     })();
index 3f033f7..ddafa40 100644 (file)
@@ -33,6 +33,7 @@
         <option>html</option>
         <option>javascript</option>
         <option>css</option>
+        <option>xml</option>
     </select>
     <button id="format">Format</button>
     <button id="save-as-url">Save URL</button>
         case "css":
             workerProxy.formatCSS(inputCM.getValue(), indentString, includeSourceMapData, formatResult);
             break;
+        case "xml":
+            workerProxy.formatXML(inputCM.getValue(), indentString, includeSourceMapData, formatResult);
+            break;
         }
 
         function formatResult({formattedText, sourceMapData}) {
 <input type=text><br><p>Test</p></div><p><![CDATA[ Test ]]></p></body></html>`;
     const simpleJS = `(function(){let a=1;return a+1;})();`;
     const simpleCSS = `body{color:red;background:blue}*{color:green}`;
+    const simpleXML = `<?xml version="1.0" encoding="iso8859-5"?><outer><inner attr="value">1</inner></outer>`;
 
     // Populate picker
     function updateContentFromPicker() {
             mode = "text/css";
             content = simpleCSS;
             break;
+        case "xml":
+            mode = "text/xml";
+            content = simpleXML;
+            break;
         default:
             console.assert();
             break;
index 1876baf..c303867 100644 (file)
@@ -60,6 +60,11 @@ WI.FormatterWorkerProxy = class FormatterWorkerProxy
         this.performAction("formatHTML", ...arguments);
     }
 
+    formatXML(sourceText, indentString, includeSourceMapData)
+    {
+        this.performAction("formatXML", ...arguments);
+    }
+
     // Public
 
     performAction(actionName)
index 92d9437..e52cb22 100644 (file)
@@ -182,7 +182,7 @@ WI.TextEditor = class TextEditor extends WI.View
     hasFormatter()
     {
         let mode = this._codeMirror.getMode().name;
-        return mode === "javascript" || mode === "css" || mode === "htmlmixed";
+        return mode === "javascript" || mode === "css" || mode === "htmlmixed" || mode === "xml";
     }
 
     canBeFormatted()
@@ -906,6 +906,9 @@ WI.TextEditor = class TextEditor extends WI.View
         case "htmlmixed":
             workerProxy.formatHTML(sourceText, indentString, includeSourceMapData, formatCallback);
             break;
+        case "xml":
+            workerProxy.formatXML(sourceText, indentString, includeSourceMapData, formatCallback);
+            break;
         default:
             console.assert(false, "Unexpected mode attempted to pretty print.");
             break;
index c27d78a..9a20fa9 100644 (file)
@@ -110,7 +110,22 @@ FormatterWorker = class FormatterWorker
     {
         let result = {formattedText: null};
         const builder = null;
-        let formatter = new HTMLFormatter(sourceText, builder, indentString);
+        const sourceType = HTMLFormatter.SourceType.HTML;
+        let formatter = new HTMLFormatter(sourceText, sourceType, builder, indentString);
+        if (formatter.success) {
+            result.formattedText = formatter.formattedText;
+            if (includeSourceMapData)
+                result.sourceMapData = formatter.sourceMapData;
+        }
+        return result;
+    }
+
+    formatXML(sourceText, indentString, includeSourceMapData)
+    {
+        let result = {formattedText: null};
+        const builder = null;
+        const sourceType = HTMLFormatter.SourceType.XML;
+        let formatter = new HTMLFormatter(sourceText, sourceType, builder, indentString);
         if (formatter.success) {
             result.formattedText = formatter.formattedText;
             if (includeSourceMapData)
index f74767d..db28d7d 100644 (file)
 
 HTMLFormatter = class HTMLFormatter
 {
-    constructor(sourceText, builder, indentString = "    ")
+    constructor(sourceText, sourceType, builder, indentString = "    ")
     {
+        console.assert(typeof sourceText === "string");
+        console.assert(Object.values(HTMLFormatter.SourceType).includes(sourceType));
+
+        this._sourceType = sourceType;
+
         this._success = false;
 
         let dom = (function() {
             try {
+                let options = {
+                    isXML: sourceType === HTMLFormatter.SourceType.XML,
+                };
                 let parser = new HTMLParser;
-                let treeBuilder = new HTMLTreeBuilderFormatter;
-                parser.parseDocument(sourceText, treeBuilder);
+                let treeBuilder = new HTMLTreeBuilderFormatter(options);
+                parser.parseDocument(sourceText, treeBuilder, options);
                 return treeBuilder.dom;
             } catch (e) {
                 console.error("Unexpected HTMLFormatter Error", e);
@@ -105,7 +113,15 @@ HTMLFormatter = class HTMLFormatter
 
     _shouldHaveNoChildren(node)
     {
-        return HTMLTreeBuilderFormatter.TagNamesWithoutChildren.has(node.lowercaseName);
+        switch (this._sourceType) {
+        case HTMLFormatter.SourceType.HTML:
+            return HTMLTreeBuilderFormatter.TagNamesWithoutChildren.has(node.lowercaseName);
+        case HTMLFormatter.SourceType.XML:
+            return false;
+        }
+
+        console.assert(false, "Unknown source type", this._sourceType);
+        return false;
     }
 
     _shouldHaveInlineContent(node)
@@ -196,7 +212,7 @@ HTMLFormatter = class HTMLFormatter
                 this._builder.appendNewline();
 
             if (!node.__inlineContent) {
-                if (node.lowercaseName !== "html")
+                if (node.lowercaseName !== "html" || this._sourceType === HTMLFormatter.SourceType.XML)
                     this._builder.indent();
                 this._builder.appendNewline();
             }
@@ -268,7 +284,7 @@ HTMLFormatter = class HTMLFormatter
             if (node.__shouldHaveNoChildren)
                 return;
             if (!node.__inlineContent) {
-                if (node.lowercaseName !== "html")
+                if (node.lowercaseName !== "html" || this._sourceType === HTMLFormatter.SourceType.XML)
                     this._builder.dedent();
                 this._builder.appendNewline();
             }
@@ -357,3 +373,8 @@ HTMLFormatter = class HTMLFormatter
         });
     }
 };
+
+HTMLFormatter.SourceType = {
+    HTML: "html",
+    XML: "xml",
+};
index 7cb2d2b..3aec94b 100644 (file)
@@ -27,7 +27,7 @@ HTMLParser = class HTMLParser {
 
     // Public
 
-    parseDocument(sourceText, treeBuilder)
+    parseDocument(sourceText, treeBuilder, {isXML} = {})
     {
         console.assert(typeof sourceText === "string");
         console.assert(treeBuilder);
@@ -39,6 +39,7 @@ HTMLParser = class HTMLParser {
         this._mode = HTMLParser.Mode.Data;
         this._data = sourceText;
         this._bogusCommentOpener = null;
+        this._isXML = !!isXML;
 
         if (this._treeBuilder.begin)
             this._treeBuilder.begin();
@@ -448,7 +449,7 @@ HTMLParser = class HTMLParser {
     {
         // Custom mode for some elements.
         if (node.type === HTMLParser.NodeType.OpenTag) {
-            if (node.name.toLowerCase() === "script")
+            if (!this._isXML && node.name.toLowerCase() === "script")
                 this._mode = HTMLParser.Mode.ScriptData;
         }
 
index ec52131..c93b191 100644 (file)
 // it only does basic auto-closing. In general this tries to be a
 // whitespace reformatter for input text and not generate the ultimate
 // html tree that a browser would generate.
+//
+// When run with the XML option, all HTML specific cases are disabled.
 
 HTMLTreeBuilderFormatter = class HTMLTreeBuilderFormatter
 {
+    constructor({isXML} = {})
+    {
+        this._isXML = !!isXML;
+    }
+
     // Public
 
     get dom() { return this._dom; }
@@ -130,7 +137,7 @@ HTMLTreeBuilderFormatter = class HTMLTreeBuilderFormatter
         if (parserNode.closed)
             return true;
 
-        if (HTMLTreeBuilderFormatter.TagNamesWithoutChildren.has(node.lowercaseName))
+        if (!this._isXML && HTMLTreeBuilderFormatter.TagNamesWithoutChildren.has(node.lowercaseName))
             return true;
 
         return false;