<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[53846] trunk: Script loader: enable resource preloading with rel='preload'.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/53846">53846</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/53846","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>adamsilverstein</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2022-08-05 18:24:42 +0000 (Fri, 05 Aug 2022)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Script loader: enable resource preloading with rel='preload'.

Add a `wp_preload_resources` filter that developers can use to add resource preloading.

Preloading helps the browser discover and prioritize important resources earlier during the page load. This ensures that they are available earlier and are less likely to block the page's render.

Props nico23, swissspidy, igrigorik, westonruter, azaozz, furi3r, aristath, spacedmonkey, peterwilsoncc, mihai2u, gziolo. 
Fixes <a href="https://core.trac.wordpress.org/ticket/42438">#42438</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpincludesdefaultfiltersphp">trunk/src/wp-includes/default-filters.php</a></li>
<li><a href="#trunksrcwpincludesgeneraltemplatephp">trunk/src/wp-includes/general-template.php</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunktestsphpunittestsgeneralwpPreloadLinksphp">trunk/tests/phpunit/tests/general/wpPreloadLinks.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcwpincludesdefaultfiltersphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/default-filters.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/default-filters.php 2022-08-05 16:10:52 UTC (rev 53845)
+++ trunk/src/wp-includes/default-filters.php   2022-08-05 18:24:42 UTC (rev 53846)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -324,6 +324,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> add_action( 'wp_head', '_wp_render_title_tag', 1 );
</span><span class="cx" style="display: block; padding: 0 10px"> add_action( 'wp_head', 'wp_enqueue_scripts', 1 );
</span><span class="cx" style="display: block; padding: 0 10px"> add_action( 'wp_head', 'wp_resource_hints', 2 );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+add_action( 'wp_head', 'wp_preload_resources', 1 );
</ins><span class="cx" style="display: block; padding: 0 10px"> add_action( 'wp_head', 'feed_links', 2 );
</span><span class="cx" style="display: block; padding: 0 10px"> add_action( 'wp_head', 'feed_links_extra', 3 );
</span><span class="cx" style="display: block; padding: 0 10px"> add_action( 'wp_head', 'rsd_link' );
</span></span></pre></div>
<a id="trunksrcwpincludesgeneraltemplatephp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/general-template.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/general-template.php        2022-08-05 16:10:52 UTC (rev 53845)
+++ trunk/src/wp-includes/general-template.php  2022-08-05 18:24:42 UTC (rev 53846)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3424,6 +3424,120 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Prints resource preloads directives to browsers.
+ *
+ * Gives directive to browsers to preload specific resources that website will
+ * need very soon, this ensures that they are available earlier and are less
+ * likely to block the page's render. Preload directives should not be used for
+ * non-render-blocking elements, as then they would compete with the
+ * render-blocking ones, slowing down the render.
+ *
+ * These performance improving indicators work by using `<link rel="preload">`.
+ *
+ * @link https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/preload
+ * @link https://web.dev/preload-responsive-images/
+ *
+ * @since 6.1.0
+ */
+function wp_preload_resources() {
+       /**
+        * Filters domains and URLs for resource preloads.
+        *
+        * @since 6.1.0
+        *
+        * @param array  $preload_resources {
+        *     Array of resources and their attributes, or URLs to print for resource preloads.
+        *
+        *     @type array ...$0 {
+        *         Array of resource attributes.
+        *
+        *         @type string $href        URL to include in resource preloads. Required.
+        *         @type string $as          How the browser should treat the resource
+        *                                   (`script`, `style`, `image`, `document`, etc).
+        *         @type string $crossorigin Indicates the CORS policy of the specified resource.
+        *         @type string $type        Type of the resource (`text/html`, `text/css`, etc).
+        *         @type string $media       Accepts media types or media queries. Allows responsive preloading.
+        *         @type string $imagesizes  Responsive source size to the source Set.
+        *         @type string $imagesrcset Responsive image sources to the source set.
+        *     }
+        * }
+        */
+       $preload_resources = apply_filters( 'wp_preload_resources', array() );
+
+       if ( ! is_array( $preload_resources ) ) {
+               return;
+       }
+
+       $unique_resources = array();
+
+       // Parse the complete resource list and extract unique resources.
+       foreach ( $preload_resources as $resource ) {
+               if ( ! is_array( $resource ) ) {
+                       continue;
+               }
+
+               $attributes = $resource;
+               if ( isset( $resource['href'] ) ) {
+                       $href = $resource['href'];
+                       if ( isset( $unique_resources[ $href ] ) ) {
+                               continue;
+                       }
+                       $unique_resources[ $href ] = $attributes;
+                       // Media can use imagesrcset and not href.
+               } elseif ( ( 'image' === $resource['as'] ) &&
+                       ( isset( $resource['imagesrcset'] ) || isset( $resource['imagesizes'] ) )
+               ) {
+                       if ( isset( $unique_resources[ $resource['imagesrcset'] ] ) ) {
+                               continue;
+                       }
+                       $unique_resources[ $resource['imagesrcset'] ] = $attributes;
+               } else {
+                       continue;
+               }
+       }
+
+       // Build and output the HTML for each unique resource.
+       foreach ( $unique_resources as $unique_resource ) {
+               $html = '';
+
+               foreach ( $unique_resource as $resource_key => $resource_value ) {
+                       if ( ! is_scalar( $resource_value ) ) {
+                               continue;
+                       }
+
+                       // Ignore non-supported attributes.
+                       $non_supported_attributes = array( 'as', 'crossorigin', 'href', 'imagesrcset', 'imagesizes', 'type', 'media' );
+                       if ( ! in_array( $resource_key, $non_supported_attributes, true ) && ! is_numeric( $resource_key ) ) {
+                               continue;
+                       }
+
+                       // imagesrcset only usable when preloading image, ignore otherwise.
+                       if ( ( 'imagesrcset' === $resource_key ) && ( ! isset( $unique_resource['as'] ) || ( 'image' !== $unique_resource['as'] ) ) ) {
+                               continue;
+                       }
+
+                       // imagesizes only usable when preloading image and imagesrcset present, ignore otherwise.
+                       if ( ( 'imagesizes' === $resource_key ) &&
+                               ( ! isset( $unique_resource['as'] ) || ( 'image' !== $unique_resource['as'] ) || ! isset( $unique_resource['imagesrcset'] ) )
+                       ) {
+                               continue;
+                       }
+
+                       $resource_value = ( 'href' === $resource_key ) ? esc_url( $resource_value, array( 'http', 'https' ) ) : esc_attr( $resource_value );
+
+                       if ( ! is_string( $resource_key ) ) {
+                               $html .= " $resource_value";
+                       } else {
+                               $html .= " $resource_key='$resource_value'";
+                       }
+               }
+               $html = trim( $html );
+
+               printf( "<link rel='preload' %s />\n", $html );
+       }
+}
+
+/**
</ins><span class="cx" style="display: block; padding: 0 10px">  * Retrieves a list of unique hosts of all enqueued scripts and styles.
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @since 4.6.0
</span></span></pre></div>
<a id="trunktestsphpunittestsgeneralwpPreloadLinksphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: trunk/tests/phpunit/tests/general/wpPreloadLinks.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/general/wpPreloadLinks.php                              (rev 0)
+++ trunk/tests/phpunit/tests/general/wpPreloadLinks.php        2022-08-05 18:24:42 UTC (rev 53846)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,253 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+/**
+ * @group general
+ * @group template
+ * @ticket 42438
+ * @covers ::wp_preload_resources
+ */
+class Tests_General_wpPreloadLinks extends WP_UnitTestCase {
+
+       /**
+        * @dataProvider data_preload_resources
+        *
+        * @ticket 42438
+        */
+       public function test_preload_resources( $expected, $preload_resources ) {
+               $callback = function () use ( $preload_resources ) {
+                       return $preload_resources;
+               };
+
+               add_filter( 'wp_preload_resources', $callback, 10 );
+               $actual = get_echo( 'wp_preload_resources' );
+               remove_filter( 'wp_preload_resources', $callback );
+
+               $this->assertSame( $expected, $actual );
+       }
+
+       /**
+        * Test provider for all preload link possible combinations.
+        *
+        * @return array[]
+        */
+       public function data_preload_resources() {
+               return array(
+                       'basic_preload'          => array(
+                               'expected' => "<link rel='preload' href='https://example.com/style.css' as='style' />\n",
+                               'urls'     => array(
+                                       array(
+                                               'href' => 'https://example.com/style.css',
+                                               'as'   => 'style',
+                                       ),
+                               ),
+                       ),
+                       'multiple_links'         => array(
+                               'expected' => "<link rel='preload' href='https://example.com/style.css' as='style' />\n" .
+                                                       "<link rel='preload' href='https://example.com/main.js' as='script' />\n",
+                               'urls'     => array(
+                                       array(
+                                               'href' => 'https://example.com/style.css',
+                                               'as'   => 'style',
+                                       ),
+                                       array(
+                                               'href' => 'https://example.com/main.js',
+                                               'as'   => 'script',
+                                       ),
+                               ),
+                       ),
+                       'MIME_types'             => array(
+                               'expected' => "<link rel='preload' href='https://example.com/style.css' as='style' />\n" .
+                                                       "<link rel='preload' href='https://example.com/video.mp4' as='video' type='video/mp4' />\n" .
+                                                       "<link rel='preload' href='https://example.com/main.js' as='script' />\n",
+                               'urls'     => array(
+                                       array(
+                                               // Should ignore not valid attributes.
+                                               'not'  => 'valid',
+                                               'href' => 'https://example.com/style.css',
+                                               'as'   => 'style',
+                                       ),
+                                       array(
+                                               'href' => 'https://example.com/video.mp4',
+                                               'as'   => 'video',
+                                               'type' => 'video/mp4',
+                                       ),
+                                       array(
+                                               'href' => 'https://example.com/main.js',
+                                               'as'   => 'script',
+                                       ),
+                               ),
+                       ),
+                       'CORS'                   => array(
+                               'expected' => "<link rel='preload' href='https://example.com/style.css' as='style' crossorigin='anonymous' />\n" .
+                                                       "<link rel='preload' href='https://example.com/video.mp4' as='video' type='video/mp4' />\n" .
+                                                       "<link rel='preload' href='https://example.com/main.js' as='script' />\n" .
+                                                       "<link rel='preload' href='https://example.com/font.woff2' as='font' type='font/woff2' crossorigin />\n",
+                               'urls'     => array(
+                                       array(
+                                               'href'        => 'https://example.com/style.css',
+                                               'as'          => 'style',
+                                               'crossorigin' => 'anonymous',
+                                       ),
+                                       array(
+                                               'href' => 'https://example.com/video.mp4',
+                                               'as'   => 'video',
+                                               'type' => 'video/mp4',
+                                       ),
+                                       array(
+                                               'href' => 'https://example.com/main.js',
+                                               'as'   => 'script',
+                                       ),
+                                       array(
+                                               // Should ignore not valid attributes.
+                                               'ignore' => 'ignore',
+                                               'href'   => 'https://example.com/font.woff2',
+                                               'as'     => 'font',
+                                               'type'   => 'font/woff2',
+                                               'crossorigin',
+                                       ),
+                               ),
+                       ),
+                       'media'                  => array(
+                               'expected' => "<link rel='preload' href='https://example.com/style.css' as='style' crossorigin='anonymous' />\n" .
+                                                       "<link rel='preload' href='https://example.com/video.mp4' as='video' type='video/mp4' />\n" .
+                                                       "<link rel='preload' href='https://example.com/main.js' as='script' />\n" .
+                                                       "<link rel='preload' href='https://example.com/font.woff2' as='font' type='font/woff2' crossorigin />\n" .
+                                                       "<link rel='preload' href='https://example.com/image-narrow.png' as='image' media='(max-width: 600px)' />\n" .
+                                                       "<link rel='preload' href='https://example.com/image-wide.png' as='image' media='(min-width: 601px)' />\n",
+                               'urls'     => array(
+                                       array(
+                                               'href'        => 'https://example.com/style.css',
+                                               'as'          => 'style',
+                                               'crossorigin' => 'anonymous',
+                                       ),
+                                       array(
+                                               'href' => 'https://example.com/video.mp4',
+                                               'as'   => 'video',
+                                               'type' => 'video/mp4',
+                                       ),
+                                       // Duplicated href should be ignored.
+                                       array(
+                                               'href' => 'https://example.com/video.mp4',
+                                               'as'   => 'video',
+                                               'type' => 'video/mp4',
+                                       ),
+                                       array(
+                                               'href' => 'https://example.com/main.js',
+                                               'as'   => 'script',
+                                       ),
+                                       array(
+                                               'href' => 'https://example.com/font.woff2',
+                                               'as'   => 'font',
+                                               'type' => 'font/woff2',
+                                               'crossorigin',
+                                       ),
+                                       array(
+                                               'href'  => 'https://example.com/image-narrow.png',
+                                               'as'    => 'image',
+                                               'media' => '(max-width: 600px)',
+                                       ),
+                                       array(
+                                               'href'  => 'https://example.com/image-wide.png',
+                                               'as'    => 'image',
+                                               'media' => '(min-width: 601px)',
+                                       ),
+
+                               ),
+                       ),
+                       'media_extra_attributes' => array(
+                               'expected' => "<link rel='preload' href='https://example.com/style.css' as='style' crossorigin='anonymous' />\n" .
+                                                       "<link rel='preload' href='https://example.com/video.mp4' as='video' type='video/mp4' />\n" .
+                                                       "<link rel='preload' href='https://example.com/main.js' as='script' />\n" .
+                                                       "<link rel='preload' href='https://example.com/font.woff2' as='font' type='font/woff2' crossorigin />\n" .
+                                                       "<link rel='preload' href='https://example.com/image-640.png' as='image' imagesrcset='640.png 640w, 800.png 800w, 1024.png 1024w' imagesizes='100vw' />\n" .
+                                                       "<link rel='preload' as='image' imagesrcset='640.png 640w, 800.png 800w, 1024.png 1024w' imagesizes='100vw' />\n" .
+                                                       "<link rel='preload' href='https://example.com/image-wide.png' as='image' media='(min-width: 601px)' />\n" .
+                                                       "<link rel='preload' href='https://example.com/image-800.png' as='image' imagesrcset='640.png 640w, 800.png 800w, 1024.png 1024w' />\n",
+                               'urls'     => array(
+                                       array(
+                                               'href'        => 'https://example.com/style.css',
+                                               'as'          => 'style',
+                                               'crossorigin' => 'anonymous',
+                                       ),
+                                       array(
+                                               'href' => 'https://example.com/video.mp4',
+                                               'as'   => 'video',
+                                               'type' => 'video/mp4',
+                                       ),
+                                       array(
+                                               'href' => 'https://example.com/main.js',
+                                               'as'   => 'script',
+                                       ),
+                                       array(
+                                               'href' => 'https://example.com/font.woff2',
+                                               'as'   => 'font',
+                                               'type' => 'font/woff2',
+                                               'crossorigin',
+                                       ),
+                                       // imagesrcset only possible when using image, ignore.
+                                       array(
+                                               'href'        => 'https://example.com/font.woff2',
+                                               'as'          => 'font',
+                                               'type'        => 'font/woff2',
+                                               'imagesrcset' => '640.png 640w, 800.png 800w, 1024.png 1024w',
+                                       ),
+                                       // imagesizes only possible when using image, ignore.
+                                       array(
+                                               'href'       => 'https://example.com/font.woff2',
+                                               'as'         => 'font',
+                                               'type'       => 'font/woff2',
+                                               'imagesizes' => '100vw',
+                                       ),
+                                       // Duplicated href should be ignored.
+                                       array(
+                                               'href' => 'https://example.com/font.woff2',
+                                               'as'   => 'font',
+                                               'type' => 'font/woff2',
+                                               'crossorigin',
+                                       ),
+                                       array(
+                                               'href'        => 'https://example.com/image-640.png',
+                                               'as'          => 'image',
+                                               'imagesrcset' => '640.png 640w, 800.png 800w, 1024.png 1024w',
+                                               'imagesizes'  => '100vw',
+                                       ),
+                                       // Omit href so that unsupporting browsers won't request a useless image.
+                                       array(
+                                               'as'          => 'image',
+                                               'imagesrcset' => '640.png 640w, 800.png 800w, 1024.png 1024w',
+                                               'imagesizes'  => '100vw',
+                                       ),
+                                       // Duplicated imagesrcset should be ignored.
+                                       array(
+                                               'as'          => 'image',
+                                               'imagesrcset' => '640.png 640w, 800.png 800w, 1024.png 1024w',
+                                               'imagesizes'  => '100vw',
+                                       ),
+                                       array(
+                                               'href'  => 'https://example.com/image-wide.png',
+                                               'as'    => 'image',
+                                               'media' => '(min-width: 601px)',
+                                       ),
+                                       // No href but not imagesrcset, should be ignored.
+                                       array(
+                                               'as'    => 'image',
+                                               'media' => '(min-width: 601px)',
+                                       ),
+                                       // imagesizes is optional.
+                                       array(
+                                               'href'        => 'https://example.com/image-800.png',
+                                               'as'          => 'image',
+                                               'imagesrcset' => '640.png 640w, 800.png 800w, 1024.png 1024w',
+                                       ),
+                                       // imagesizes should be ignored since imagesrcset not present.
+                                       array(
+                                               'href'       => 'https://example.com/image-640.png',
+                                               'as'         => 'image',
+                                               'imagesizes' => '100vw',
+                                       ),
+                               ),
+                       ),
+               );
+       }
+
+}
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: trunk/tests/phpunit/tests/general/wpPreloadLinks.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span></div>

</body>
</html>