<!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>[38948] trunk/src: Customize: Improve custom background properties UI.</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 { 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/38948">38948</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/38948","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>westonruter</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2016-10-26 06:51:11 +0000 (Wed, 26 Oct 2016)</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'>Customize: Improve custom background properties UI.

Introduces new control for managing the background position. Adds control for setting the `background-size`.

Props cdog, celloexpressions, grapplerulrich, MikeHansenMe, FolioVision, afercia,?\226?\128?\130helen, melchoyce, karmatosed, westonruter, Kelderic, sebastian.pisula.
Fixes <a href="https://core.trac.wordpress.org/ticket/22058">#22058</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpadmincsscustomizecontrolscss">trunk/src/wp-admin/css/customize-controls.css</a></li>
<li><a href="#trunksrcwpadmincssthemescss">trunk/src/wp-admin/css/themes.css</a></li>
<li><a href="#trunksrcwpadmincustombackgroundphp">trunk/src/wp-admin/custom-background.php</a></li>
<li><a href="#trunksrcwpadminjscustombackgroundjs">trunk/src/wp-admin/js/custom-background.js</a></li>
<li><a href="#trunksrcwpadminjscustomizecontrolsjs">trunk/src/wp-admin/js/customize-controls.js</a></li>
<li><a href="#trunksrcwpincludesclasswpcustomizecontrolphp">trunk/src/wp-includes/class-wp-customize-control.php</a></li>
<li><a href="#trunksrcwpincludesclasswpcustomizemanagerphp">trunk/src/wp-includes/class-wp-customize-manager.php</a></li>
<li><a href="#trunksrcwpincludescustomizeclasswpcustomizebackgroundimagecontrolphp">trunk/src/wp-includes/customize/class-wp-customize-background-image-control.php</a></li>
<li><a href="#trunksrcwpincludesjscustomizepreviewjs">trunk/src/wp-includes/js/customize-preview.js</a></li>
<li><a href="#trunksrcwpincludesthemephp">trunk/src/wp-includes/theme.php</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunksrcwpincludescustomizeclasswpcustomizebackgroundpositioncontrolphp">trunk/src/wp-includes/customize/class-wp-customize-background-position-control.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcwpadmincsscustomizecontrolscss"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-admin/css/customize-controls.css</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-admin/css/customize-controls.css     2016-10-26 06:27:04 UTC (rev 38947)
+++ trunk/src/wp-admin/css/customize-controls.css       2016-10-26 06:51:11 UTC (rev 38948)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1090,6 +1090,11 @@
</span><span class="cx" style="display: block; padding: 0 10px">        float: right;
</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">+/* Background position control */
+.customize-control-background_position .background-position-control .button-group {
+       display: block;
+}
+
</ins><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px">  * Custom CSS Section
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span></span></pre></div>
<a id="trunksrcwpadmincssthemescss"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-admin/css/themes.css</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-admin/css/themes.css 2016-10-26 06:27:04 UTC (rev 38947)
+++ trunk/src/wp-admin/css/themes.css   2016-10-26 06:51:11 UTC (rev 38948)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1176,6 +1176,135 @@
</span><span class="cx" style="display: block; padding: 0 10px">        max-height: 300px;
</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">+.background-position-control input[type="radio"]:checked ~ .button {
+       background: #eee;
+       border-color: #999;
+       -webkit-box-shadow: inset 0 2px 5px -3px rgba( 0, 0, 0, .5 );
+       box-shadow: inset 0 2px 5px -3px rgba( 0, 0, 0, .5 );
+       z-index: 1;
+}
+
+.background-position-control input[type="radio"]:focus ~ .button {
+       border-color: #5b9dd9;
+       -webkit-box-shadow: inset 0 2px 5px -3px rgba( 0, 0, 0, .5 ), 0 0 3px rgba( 0, 115, 170, .8 );
+       box-shadow: inset 0 2px 5px -3px rgba( 0, 0, 0, .5 ), 0 0 3px rgba( 0, 115, 170, .8 );
+       color: #23282d;
+}
+
+.background-position-control .background-position-center-icon,
+.background-position-control .background-position-center-icon:before {
+       display: inline-block;
+       line-height: 1;
+       text-align: center;
+       -webkit-transition: background-color .1s ease-in 0;
+       transition: background-color .1s ease-in 0;
+}
+
+.background-position-control .background-position-center-icon {
+       height: 20px;
+       margin-top: 13px;
+       vertical-align: top;
+       width: 20px;
+}
+
+.background-position-control .background-position-center-icon:before {
+       background-color: #555;
+       -webkit-border-radius: 50%;
+       border-radius: 50%;
+       content: "";
+       height: 12px;
+       width: 12px;
+}
+
+.background-position-control .button:hover .background-position-center-icon:before,
+.background-position-control input[type="radio"]:focus ~ .button .background-position-center-icon:before {
+       background-color: #23282d;
+}
+
+.background-position-control .button-group {
+       display: block;
+}
+
+.background-position-control .button-group .button {
+       -webkit-border-radius: 0;
+       border-radius: 0;
+       -webkit-box-shadow: none;
+       box-shadow: none;
+       /* Following properties are overridden by buttons responsive styles (see: wp-includes/css/buttons.css). */
+       height: 40px !important;
+       line-height: 37px !important;
+       margin: 0 -1px 0 0 !important;
+       padding: 0 10px 1px !important;
+       position: relative;
+}
+
+.background-position-control .button-group .button:active,
+.background-position-control .button-group .button:hover,
+.background-position-control .button-group .button:focus {
+       z-index: 1;
+}
+
+.background-position-control .button-group:last-child .button {
+       -webkit-box-shadow: 0 1px 0 #ccc;
+       box-shadow: 0 1px 0 #ccc;
+}
+
+.background-position-control .button-group > label {
+       margin: 0 !important;
+}
+
+.background-position-control .button-group:first-child > label:first-child .button {
+       -webkit-border-radius: 3px 0 0;
+       border-radius: 3px 0 0;
+}
+
+.background-position-control .button-group:first-child > label:first-child .dashicons {
+       -webkit-transform: rotate( 45deg );
+       -ms-transform: rotate( 45deg );
+       transform: rotate( 45deg );
+}
+
+.background-position-control .button-group:first-child > label:last-child .button {
+       -webkit-border-radius: 0 3px 0 0;
+       border-radius: 0 3px 0 0;
+}
+
+.background-position-control .button-group:first-child > label:last-child .dashicons {
+       -webkit-transform: rotate( -45deg );
+       -ms-transform: rotate( -45deg );
+       transform: rotate( -45deg );
+}
+
+.background-position-control .button-group:last-child > label:first-child .button {
+       -webkit-border-radius: 0 0 0 3px;
+       border-radius: 0 0 0 3px;
+}
+
+.background-position-control .button-group:last-child > label:first-child .dashicons {
+       -webkit-transform: rotate( -45deg );
+       -ms-transform: rotate( -45deg );
+       transform: rotate( -45deg );
+}
+
+.background-position-control .button-group:last-child > label:last-child .button {
+       -webkit-border-radius: 0 0 3px 0;
+       border-radius: 0 0 3px 0;
+}
+
+.background-position-control .button-group:last-child > label:last-child .dashicons {
+       -webkit-transform: rotate( 45deg );
+       -ms-transform: rotate( 45deg );
+       transform: rotate( 45deg );
+}
+
+.background-position-control .button-group .dashicons {
+       margin-top: 9px;
+}
+
+.background-position-control .button-group + .button-group {
+       margin-top: -1px;
+}
+
</ins><span class="cx" style="display: block; padding: 0 10px"> /*------------------------------------------------------------------------------
</span><span class="cx" style="display: block; padding: 0 10px">   23.0 - Full Overlay w/ Sidebar
</span><span class="cx" style="display: block; padding: 0 10px"> ------------------------------------------------------------------------------*/
</span></span></pre></div>
<a id="trunksrcwpadmincustombackgroundphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-admin/custom-background.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-admin/custom-background.php  2016-10-26 06:27:04 UTC (rev 38947)
+++ trunk/src/wp-admin/custom-background.php    2016-10-26 06:51:11 UTC (rev 38948)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -133,33 +133,75 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        return;
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                if ( isset($_POST['background-repeat']) ) {
-                       check_admin_referer('custom-background');
-                       if ( in_array($_POST['background-repeat'], array('repeat', 'no-repeat', 'repeat-x', 'repeat-y')) )
-                               $repeat = $_POST['background-repeat'];
-                       else
-                               $repeat = 'repeat';
-                       set_theme_mod('background_repeat', $repeat);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( isset( $_POST['background-preset'] ) ) {
+                       check_admin_referer( 'custom-background' );
+
+                       if ( in_array( $_POST['background-preset'], array( 'default', 'fill', 'fit', 'repeat', 'custom' ), true ) ) {
+                               $preset = $_POST['background-preset'];
+                       } else {
+                               $preset = 'default';
+                       }
+
+                       set_theme_mod( 'background_preset', $preset );
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                if ( isset($_POST['background-position-x']) ) {
-                       check_admin_referer('custom-background');
-                       if ( in_array($_POST['background-position-x'], array('center', 'right', 'left')) )
-                               $position = $_POST['background-position-x'];
-                       else
-                               $position = 'left';
-                       set_theme_mod('background_position_x', $position);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( isset( $_POST['background-position'] ) ) {
+                       check_admin_referer( 'custom-background' );
+
+                       $position = explode( ' ', $_POST['background-position'] );
+
+                       if ( in_array( $position[0], array( 'left', 'center', 'right' ), true ) ) {
+                               $position_x = $position[0];
+                       } else {
+                               $position_x = 'left';
+                       }
+
+                       if ( in_array( $position[1], array( 'top', 'center', 'bottom' ), true ) ) {
+                               $position_y = $position[1];
+                       } else {
+                               $position_y = 'top';
+                       }
+
+                       set_theme_mod( 'background_position_x', $position_x );
+                       set_theme_mod( 'background_position_y', $position_y );
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                if ( isset($_POST['background-attachment']) ) {
-                       check_admin_referer('custom-background');
-                       if ( in_array($_POST['background-attachment'], array('fixed', 'scroll')) )
-                               $attachment = $_POST['background-attachment'];
-                       else
-                               $attachment = 'fixed';
-                       set_theme_mod('background_attachment', $attachment);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( isset( $_POST['background-size'] ) ) {
+                       check_admin_referer( 'custom-background' );
+
+                       if ( in_array( $_POST['background-size'], array( 'auto', 'contain', 'cover' ), true ) ) {
+                               $size = $_POST['background-size'];
+                       } else {
+                               $size = 'auto';
+                       }
+
+                       set_theme_mod( 'background_size', $size );
</ins><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">+                if ( isset( $_POST['background-repeat'] ) ) {
+                       check_admin_referer( 'custom-background' );
+
+                       $repeat = $_POST['background-repeat'];
+
+                       if ( 'no-repeat' !== $repeat ) {
+                               $repeat = 'repeat';
+                       }
+
+                       set_theme_mod( 'background_repeat', $repeat );
+               }
+
+               if ( isset( $_POST['background-attachment'] ) ) {
+                       check_admin_referer( 'custom-background' );
+
+                       $attachment = $_POST['background-attachment'];
+
+                       if ( 'fixed' !== $attachment ) {
+                               $attachment = 'scroll';
+                       }
+
+                       set_theme_mod( 'background_attachment', $attachment );
+               }
+
</ins><span class="cx" style="display: block; padding: 0 10px">                 if ( isset($_POST['background-color']) ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        check_admin_referer('custom-background');
</span><span class="cx" style="display: block; padding: 0 10px">                        $color = preg_replace('/[^0-9a-fA-F]/', '', $_POST['background-color']);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -219,11 +261,18 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $background_image_thumb = get_background_image();
</span><span class="cx" style="display: block; padding: 0 10px">                if ( $background_image_thumb ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        $background_image_thumb = esc_url( set_url_scheme( get_theme_mod( 'background_image_thumb', str_replace( '%', '%%', $background_image_thumb ) ) ) );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        $background_position_x = get_theme_mod( 'background_position_x', get_theme_support( 'custom-background', 'default-position-x' ) );
+                       $background_position_y = get_theme_mod( 'background_position_y', get_theme_support( 'custom-background', 'default-position-y' ) );
+                       $background_size = get_theme_mod( 'background_size', get_theme_support( 'custom-background', 'default-size' ) );
+                       $background_repeat = get_theme_mod( 'background_repeat', get_theme_support( 'custom-background', 'default-repeat' ) );
+                       $background_attachment = get_theme_mod( 'background_attachment', get_theme_support( 'custom-background', 'default-attachment' ) );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        // Background-image URL must be single quote, see below.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $background_styles .= ' background-image: url(\'' . $background_image_thumb . '\');'
-                               . ' background-repeat: ' . get_theme_mod( 'background_repeat', get_theme_support( 'custom-background', 'default-repeat' ) ) . ';'
-                               . ' background-position: top ' . get_theme_mod( 'background_position_x', get_theme_support( 'custom-background', 'default-position-x' ) );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $background_styles .= " background-image: url('$background_image_thumb');"
+                               . " background-size: $background_size;"
+                               . " background-position: $background_position_x $background_position_y;"
+                               . " background-repeat: $background_repeat;"
+                               . " background-attachment: $background_attachment;";
</ins><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">        <div id="custom-background-image" style="<?php echo $background_styles; ?>"><?php // must be double quote, see above ?>
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -287,52 +336,83 @@
</span><span class="cx" style="display: block; padding: 0 10px"> </tbody>
</span><span class="cx" style="display: block; padding: 0 10px"> </table>
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<h3><?php _e('Display Options') ?></h3>
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<h3><?php _e( 'Display Options' ); ?></h3>
</ins><span class="cx" style="display: block; padding: 0 10px"> <form method="post">
</span><span class="cx" style="display: block; padding: 0 10px"> <table class="form-table">
</span><span class="cx" style="display: block; padding: 0 10px"> <tbody>
</span><span class="cx" style="display: block; padding: 0 10px"> <?php if ( get_background_image() ) : ?>
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<input name="background-preset" type="hidden" value="custom">
+
+<?php
+$background_position = sprintf(
+       '%s %s',
+       get_theme_mod( 'background_position_x', get_theme_support( 'custom-background', 'default-position-x' ) ),
+       get_theme_mod( 'background_position_y', get_theme_support( 'custom-background', 'default-position-y' ) )
+);
+
+$background_position_options = array(
+       array(
+               'left top'   => array( 'label' => __( 'Top Left' ), 'icon' => 'dashicons dashicons-arrow-left-alt' ),
+               'center top' => array( 'label' => __( 'Top' ), 'icon' => 'dashicons dashicons-arrow-up-alt' ),
+               'right top'  => array( 'label' => __( 'Top Right' ), 'icon' => 'dashicons dashicons-arrow-right-alt' ),
+       ),
+       array(
+               'left center'   => array( 'label' => __( 'Left' ), 'icon' => 'dashicons dashicons-arrow-left-alt' ),
+               'center center' => array( 'label' => __( 'Center' ), 'icon' => 'background-position-center-icon' ),
+               'right center'  => array( 'label' => __( 'Right' ), 'icon' => 'dashicons dashicons-arrow-right-alt' ),
+       ),
+       array(
+               'left bottom'   => array( 'label' => __( 'Bottom Left' ), 'icon' => 'dashicons dashicons-arrow-left-alt' ),
+               'center bottom' => array( 'label' => __( 'Bottom' ), 'icon' => 'dashicons dashicons-arrow-down-alt' ),
+               'right bottom'  => array( 'label' => __( 'Bottom Right' ), 'icon' => 'dashicons dashicons-arrow-right-alt' ),
+       ),
+);
+?>
</ins><span class="cx" style="display: block; padding: 0 10px"> <tr>
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<th scope="row"><?php _e( 'Position' ); ?></th>
-<td><fieldset><legend class="screen-reader-text"><span><?php _e( 'Background Position' ); ?></span></legend>
-<label>
-<input name="background-position-x" type="radio" value="left"<?php checked( 'left', get_theme_mod( 'background_position_x', get_theme_support( 'custom-background', 'default-position-x' ) ) ); ?> />
-<?php _e('Left') ?>
-</label>
-<label>
-<input name="background-position-x" type="radio" value="center"<?php checked( 'center', get_theme_mod( 'background_position_x', get_theme_support( 'custom-background', 'default-position-x' ) ) ); ?> />
-<?php _e('Center') ?>
-</label>
-<label>
-<input name="background-position-x" type="radio" value="right"<?php checked( 'right', get_theme_mod( 'background_position_x', get_theme_support( 'custom-background', 'default-position-x' ) ) ); ?> />
-<?php _e('Right') ?>
-</label>
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<th scope="row"><?php _e( 'Image Position' ); ?></th>
+<td><fieldset><legend class="screen-reader-text"><span><?php _e( 'Image Position' ); ?></span></legend>
+<div class="background-position-control">
+<?php foreach ( $background_position_options as $group ) : ?>
+       <div class="button-group">
+       <?php foreach ( $group as $value => $input ) : ?>
+               <label>
+                       <input class="screen-reader-text" name="background-position" type="radio" value="<?php echo esc_attr( $value ); ?>"<?php checked( $value, $background_position ); ?>>
+                       <span class="button display-options position"><span class="<?php echo esc_attr( $input['icon'] ); ?>" aria-hidden="true"></span></span>
+                       <span class="screen-reader-text"><?php echo $input['label']; ?></span>
+               </label>
+       <?php endforeach; ?>
+       </div>
+<?php endforeach; ?>
+</div>
</ins><span class="cx" style="display: block; padding: 0 10px"> </fieldset></td>
</span><span class="cx" style="display: block; padding: 0 10px"> </tr>
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> <tr>
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<th scope="row"><?php _e( 'Repeat' ); ?></th>
-<td><fieldset><legend class="screen-reader-text"><span><?php _e( 'Background Repeat' ); ?></span></legend>
-<label><input type="radio" name="background-repeat" value="no-repeat"<?php checked( 'no-repeat', get_theme_mod( 'background_repeat', get_theme_support( 'custom-background', 'default-repeat' ) ) ); ?> /> <?php _e('No Repeat'); ?></label>
-       <label><input type="radio" name="background-repeat" value="repeat"<?php checked( 'repeat', get_theme_mod( 'background_repeat', get_theme_support( 'custom-background', 'default-repeat' ) ) ); ?> /> <?php _e('Tile'); ?></label>
-       <label><input type="radio" name="background-repeat" value="repeat-x"<?php checked( 'repeat-x', get_theme_mod( 'background_repeat', get_theme_support( 'custom-background', 'default-repeat' ) ) ); ?> /> <?php _e('Tile Horizontally'); ?></label>
-       <label><input type="radio" name="background-repeat" value="repeat-y"<?php checked( 'repeat-y', get_theme_mod( 'background_repeat', get_theme_support( 'custom-background', 'default-repeat' ) ) ); ?> /> <?php _e('Tile Vertically'); ?></label>
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<th scope="row"><label for="background-size"><?php _e( 'Image Size' ); ?></label></th>
+<td><fieldset><legend class="screen-reader-text"><span><?php _e( 'Image Size' ); ?></span></legend>
+<select id="background-size" name="background-size">
+<option value="auto"<?php selected( 'auto', get_theme_mod( 'background_size', get_theme_support( 'custom-background', 'default-size' ) ) ); ?>><?php _ex( 'Original', 'Original Size' ); ?></option>
+<option value="contain"<?php selected( 'contain', get_theme_mod( 'background_size', get_theme_support( 'custom-background', 'default-size' ) ) ); ?>><?php _e( 'Fit to Screen' ); ?></option>
+<option value="cover"<?php selected( 'cover', get_theme_mod( 'background_size', get_theme_support( 'custom-background', 'default-size' ) ) ); ?>><?php _e( 'Fill Screen' ); ?></option>
+</select>
</ins><span class="cx" style="display: block; padding: 0 10px"> </fieldset></td>
</span><span class="cx" style="display: block; padding: 0 10px"> </tr>
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> <tr>
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<th scope="row"><?php _ex( 'Attachment', 'Background Attachment' ); ?></th>
-<td><fieldset><legend class="screen-reader-text"><span><?php _e( 'Background Attachment' ); ?></span></legend>
-<label>
-<input name="background-attachment" type="radio" value="scroll" <?php checked( 'scroll', get_theme_mod( 'background_attachment', get_theme_support( 'custom-background', 'default-attachment' ) ) ); ?> />
-<?php _e( 'Scroll' ); ?>
-</label>
-<label>
-<input name="background-attachment" type="radio" value="fixed" <?php checked( 'fixed', get_theme_mod( 'background_attachment', get_theme_support( 'custom-background', 'default-attachment' ) ) ); ?> />
-<?php _e( 'Fixed' ); ?>
-</label>
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<th scope="row"><?php _ex( 'Repeat', 'Background Repeat' ); ?></th>
+<td><fieldset><legend class="screen-reader-text"><span><?php _ex( 'Repeat', 'Background Repeat' ); ?></span></legend>
+<input name="background-repeat" type="hidden" value="no-repeat">
+<label><input type="checkbox" name="background-repeat" value="repeat"<?php checked( 'repeat', get_theme_mod( 'background_repeat', get_theme_support( 'custom-background', 'default-repeat' ) ) ); ?>> <?php _e( 'Repeat Background Image' ); ?></label>
</ins><span class="cx" style="display: block; padding: 0 10px"> </fieldset></td>
</span><span class="cx" style="display: block; padding: 0 10px"> </tr>
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+<tr>
+<th scope="row"><?php _ex( 'Scroll', 'Background Scroll' ); ?></th>
+<td><fieldset><legend class="screen-reader-text"><span><?php _ex( 'Scroll', 'Background Scroll' ); ?></span></legend>
+<input name="background-attachment" type="hidden" value="fixed">
+<label><input name="background-attachment" type="checkbox" value="scroll" <?php checked( 'scroll', get_theme_mod( 'background_attachment', get_theme_support( 'custom-background', 'default-attachment' ) ) ); ?>> <?php _e( 'Scroll with Page' ); ?></label>
+</fieldset></td>
+</tr>
</ins><span class="cx" style="display: block; padding: 0 10px"> <?php endif; // get_background_image() ?>
</span><span class="cx" style="display: block; padding: 0 10px"> <tr>
</span><span class="cx" style="display: block; padding: 0 10px"> <th scope="row"><?php _e( 'Background Color' ); ?></th>
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -342,7 +422,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if ( current_theme_supports( 'custom-background', 'default-color' ) )
</span><span class="cx" style="display: block; padding: 0 10px">        $default_color = ' data-default-color="#' . esc_attr( get_theme_support( 'custom-background', 'default-color' ) ) . '"';
</span><span class="cx" style="display: block; padding: 0 10px"> ?>
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<input type="text" name="background-color" id="background-color" value="#<?php echo esc_attr( get_background_color() ); ?>"<?php echo $default_color ?> />
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<input type="text" name="background-color" id="background-color" value="#<?php echo esc_attr( get_background_color() ); ?>"<?php echo $default_color ?>>
</ins><span class="cx" style="display: block; padding: 0 10px"> </fieldset></td>
</span><span class="cx" style="display: block; padding: 0 10px"> </tr>
</span><span class="cx" style="display: block; padding: 0 10px"> </tbody>
</span></span></pre></div>
<a id="trunksrcwpadminjscustombackgroundjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-admin/js/custom-background.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-admin/js/custom-background.js        2016-10-26 06:27:04 UTC (rev 38947)
+++ trunk/src/wp-admin/js/custom-background.js  2016-10-26 06:51:11 UTC (rev 38948)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -13,14 +13,22 @@
</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><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $('input[name="background-position-x"]').change(function() {
-                       bgImage.css('background-position', $(this).val() + ' top');
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $( 'select[name="background-size"]' ).change( function() {
+                       bgImage.css( 'background-size', $( this ).val() );
</ins><span class="cx" style="display: block; padding: 0 10px">                 });
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $('input[name="background-repeat"]').change(function() {
-                       bgImage.css('background-repeat', $(this).val());
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $( 'input[name="background-position"]' ).change( function() {
+                       bgImage.css( 'background-position', $( this ).val() );
</ins><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">+                $( 'input[name="background-repeat"]' ).change( function() {
+                       bgImage.css( 'background-repeat', $( this ).is( ':checked' ) ? 'repeat' : 'no-repeat' );
+               });
+
+               $( 'input[name="background-attachment"]' ).change( function() {
+                       bgImage.css( 'background-attachment', $( this ).is( ':checked' ) ? 'scroll' : 'fixed' );
+               });
+
</ins><span class="cx" style="display: block; padding: 0 10px">                 $('#choose-from-library-link').click( function( event ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        var $el = $(this);
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span></span></pre></div>
<a id="trunksrcwpadminjscustomizecontrolsjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-admin/js/customize-controls.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-admin/js/customize-controls.js       2016-10-26 06:27:04 UTC (rev 38947)
+++ trunk/src/wp-admin/js/customize-controls.js 2016-10-26 06:51:11 UTC (rev 38948)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3158,6 +3158,46 @@
</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">+         * A control for positioning a background image.
+        *
+        * @since 4.7.0
+        *
+        * @class
+        * @augments wp.customize.Control
+        * @augments wp.customize.Class
+        */
+       api.BackgroundPositionControl = api.Control.extend( {
+
+               /**
+                * Set up control UI once embedded in DOM and settings are created.
+                *
+                * @since 4.7.0
+                */
+               ready: function() {
+                       var control = this, updateRadios;
+
+                       control.container.on( 'change', 'input[name="background-position"]', function() {
+                               var position = $( this ).val().split( ' ' );
+                               control.settings.x( position[0] );
+                               control.settings.y( position[1] );
+                       } );
+
+                       updateRadios = _.debounce( function() {
+                               var x, y, radioInput, inputValue;
+                               x = control.settings.x.get();
+                               y = control.settings.y.get();
+                               inputValue = String( x ) + ' ' + String( y );
+                               radioInput = control.container.find( 'input[name="background-position"][value="' + inputValue + '"]' );
+                               radioInput.click();
+                       } );
+                       control.settings.x.bind( updateRadios );
+                       control.settings.y.bind( updateRadios );
+
+                       updateRadios(); // Set initial UI.
+               }
+       } );
+
+       /**
</ins><span class="cx" style="display: block; padding: 0 10px">          * A control for selecting and cropping an image.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @class
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4507,15 +4547,16 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        api.settingConstructor = {};
</span><span class="cx" style="display: block; padding: 0 10px">        api.controlConstructor = {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                color:         api.ColorControl,
-               media:         api.MediaControl,
-               upload:        api.UploadControl,
-               image:         api.ImageControl,
-               cropped_image: api.CroppedImageControl,
-               site_icon:     api.SiteIconControl,
-               header:        api.HeaderControl,
-               background:    api.BackgroundControl,
-               theme:         api.ThemeControl
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         color:               api.ColorControl,
+               media:               api.MediaControl,
+               upload:              api.UploadControl,
+               image:               api.ImageControl,
+               cropped_image:       api.CroppedImageControl,
+               site_icon:           api.SiteIconControl,
+               header:              api.HeaderControl,
+               background:          api.BackgroundControl,
+               background_position: api.BackgroundPositionControl,
+               theme:               api.ThemeControl
</ins><span class="cx" style="display: block; padding: 0 10px">         };
</span><span class="cx" style="display: block; padding: 0 10px">        api.panelConstructor = {
</span><span class="cx" style="display: block; padding: 0 10px">                themes: api.ThemesPanel
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -5531,7 +5572,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                // Control visibility for default controls
</span><span class="cx" style="display: block; padding: 0 10px">                $.each({
</span><span class="cx" style="display: block; padding: 0 10px">                        'background_image': {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                controls: [ 'background_repeat', 'background_position_x', 'background_attachment' ],
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         controls: [ 'background_preset', 'background_position', 'background_size', 'background_repeat', 'background_attachment' ],
</ins><span class="cx" style="display: block; padding: 0 10px">                                 callback: function( to ) { return !! to; }
</span><span class="cx" style="display: block; padding: 0 10px">                        },
</span><span class="cx" style="display: block; padding: 0 10px">                        'show_on_front': {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -5557,6 +5598,89 @@
</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">+                api.control( 'background_preset', function( control ) {
+                       var visibility, defaultValues, values, toggleVisibility, updateSettings, preset;
+
+                       visibility = { // position, size, repeat, attachment
+                               'default': [ false, false, false, false ],
+                               'fill': [ true, false, false, false ],
+                               'fit': [ true, false, true, false ],
+                               'repeat': [ true, false, false, true ],
+                               'custom': [ true, true, true, true ]
+                       };
+
+                       defaultValues = [
+                               _wpCustomizeBackground.defaults['default-position-x'],
+                               _wpCustomizeBackground.defaults['default-position-y'],
+                               _wpCustomizeBackground.defaults['default-size'],
+                               _wpCustomizeBackground.defaults['default-repeat'],
+                               _wpCustomizeBackground.defaults['default-attachment']
+                       ];
+
+                       values = { // position_x, position_y, size, repeat, attachment
+                               'default': defaultValues,
+                               'fill': [ 'left', 'top', 'cover', 'no-repeat', 'fixed' ],
+                               'fit': [ 'left', 'top', 'contain', 'no-repeat', 'fixed' ],
+                               'repeat': [ 'left', 'top', 'auto', 'repeat', 'scroll' ]
+                       };
+
+                       // @todo These should actually toggle the active state, but without the preview overriding the state in data.activeControls.
+                       toggleVisibility = function( preset ) {
+                               api.control( 'background_position' ).container.toggle( visibility[ preset ][0] );
+                               api.control( 'background_size' ).container.toggle( visibility[ preset ][1] );
+                               api.control( 'background_repeat' ).container.toggle( visibility[ preset ][2] );
+                               api.control( 'background_attachment' ).container.toggle( visibility[ preset ][3] );
+                       };
+
+                       updateSettings = function( preset ) {
+                               api( 'background_position_x' ).set( values[ preset ][0] );
+                               api( 'background_position_y' ).set( values[ preset ][1] );
+                               api( 'background_size' ).set( values[ preset ][2] );
+                               api( 'background_repeat' ).set( values[ preset ][3] );
+                               api( 'background_attachment' ).set( values[ preset ][4] );
+                       };
+
+                       preset = control.setting.get();
+                       toggleVisibility( preset );
+
+                       control.setting.bind( 'change', function( preset ) {
+                               toggleVisibility( preset );
+                               if ( 'custom' !== preset ) {
+                                       updateSettings( preset );
+                               }
+                       } );
+               } );
+
+               api.control( 'background_repeat', function( control ) {
+                       control.elements[0].unsync( api( 'background_repeat' ) );
+
+                       control.element = new api.Element( control.container.find( 'input' ) );
+                       control.element.set( 'no-repeat' !== control.setting() );
+
+                       control.element.bind( function( to ) {
+                               control.setting.set( to ? 'repeat' : 'no-repeat' );
+                       } );
+
+                       control.setting.bind( function( to ) {
+                               control.element.set( 'no-repeat' !== to );
+                       } );
+               } );
+
+               api.control( 'background_attachment', function( control ) {
+                       control.elements[0].unsync( api( 'background_attachment' ) );
+
+                       control.element = new api.Element( control.container.find( 'input' ) );
+                       control.element.set( 'fixed' !== control.setting() );
+
+                       control.element.bind( function( to ) {
+                               control.setting.set( to ? 'scroll' : 'fixed' );
+                       } );
+
+                       control.setting.bind( function( to ) {
+                               control.element.set( 'fixed' !== to );
+                       } );
+               } );
+
</ins><span class="cx" style="display: block; padding: 0 10px">                 // Juggle the two controls that use header_textcolor
</span><span class="cx" style="display: block; padding: 0 10px">                api.control( 'display_header_text', function( control ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        var last = '';
</span></span></pre></div>
<a id="trunksrcwpincludesclasswpcustomizecontrolphp"></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/class-wp-customize-control.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/class-wp-customize-control.php      2016-10-26 06:27:04 UTC (rev 38947)
+++ trunk/src/wp-includes/class-wp-customize-control.php        2016-10-26 06:51:11 UTC (rev 38948)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -660,6 +660,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /** WP_Customize_Background_Image_Control class */
</span><span class="cx" style="display: block; padding: 0 10px"> require_once( ABSPATH . WPINC . '/customize/class-wp-customize-background-image-control.php' );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/** WP_Customize_Background_Position_Control class */
+require_once( ABSPATH . WPINC . '/customize/class-wp-customize-background-position-control.php' );
+
</ins><span class="cx" style="display: block; padding: 0 10px"> /** WP_Customize_Cropped_Image_Control class */
</span><span class="cx" style="display: block; padding: 0 10px"> require_once( ABSPATH . WPINC . '/customize/class-wp-customize-cropped-image-control.php' );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span></span></pre></div>
<a id="trunksrcwpincludesclasswpcustomizemanagerphp"></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/class-wp-customize-manager.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/class-wp-customize-manager.php      2016-10-26 06:27:04 UTC (rev 38947)
+++ trunk/src/wp-includes/class-wp-customize-manager.php        2016-10-26 06:51:11 UTC (rev 38948)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -279,6 +279,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                require_once( ABSPATH . WPINC . '/customize/class-wp-customize-upload-control.php' );
</span><span class="cx" style="display: block; padding: 0 10px">                require_once( ABSPATH . WPINC . '/customize/class-wp-customize-image-control.php' );
</span><span class="cx" style="display: block; padding: 0 10px">                require_once( ABSPATH . WPINC . '/customize/class-wp-customize-background-image-control.php' );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                require_once( ABSPATH . WPINC . '/customize/class-wp-customize-background-position-control.php' );
</ins><span class="cx" style="display: block; padding: 0 10px">                 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-cropped-image-control.php' );
</span><span class="cx" style="display: block; padding: 0 10px">                require_once( ABSPATH . WPINC . '/customize/class-wp-customize-site-icon-control.php' );
</span><span class="cx" style="display: block; padding: 0 10px">                require_once( ABSPATH . WPINC . '/customize/class-wp-customize-header-image-control.php' );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3026,6 +3027,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $this->register_control_type( 'WP_Customize_Upload_Control' );
</span><span class="cx" style="display: block; padding: 0 10px">                $this->register_control_type( 'WP_Customize_Image_Control' );
</span><span class="cx" style="display: block; padding: 0 10px">                $this->register_control_type( 'WP_Customize_Background_Image_Control' );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                $this->register_control_type( 'WP_Customize_Background_Position_Control' );
</ins><span class="cx" style="display: block; padding: 0 10px">                 $this->register_control_type( 'WP_Customize_Cropped_Image_Control' );
</span><span class="cx" style="display: block; padding: 0 10px">                $this->register_control_type( 'WP_Customize_Site_Icon_Control' );
</span><span class="cx" style="display: block; padding: 0 10px">                $this->register_control_type( 'WP_Customize_Theme_Control' );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3276,66 +3278,102 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $this->add_setting( 'background_image', array(
</span><span class="cx" style="display: block; padding: 0 10px">                        'default'        => get_theme_support( 'custom-background', 'default-image' ),
</span><span class="cx" style="display: block; padding: 0 10px">                        'theme_supports' => 'custom-background',
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        'sanitize_callback' => array( $this, '_sanitize_background_setting' ),
</ins><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">                $this->add_setting( new WP_Customize_Background_Image_Setting( $this, 'background_image_thumb', array(
</span><span class="cx" style="display: block; padding: 0 10px">                        'theme_supports' => 'custom-background',
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        'sanitize_callback' => array( $this, '_sanitize_background_setting' ),
</ins><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">                $this->add_control( new WP_Customize_Background_Image_Control( $this ) );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $this->add_setting( 'background_repeat', array(
-                       'default'        => get_theme_support( 'custom-background', 'default-repeat' ),
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $this->add_setting( 'background_preset', array(
+                       'default'        => get_theme_support( 'custom-background', 'default-preset' ),
</ins><span class="cx" style="display: block; padding: 0 10px">                         'theme_supports' => 'custom-background',
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        'sanitize_callback' => array( $this, '_sanitize_background_setting' ),
</ins><span class="cx" style="display: block; padding: 0 10px">                 ) );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $this->add_control( 'background_repeat', array(
-                       'label'      => __( 'Background Repeat' ),
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $this->add_control( 'background_preset', array(
+                       'label'      => _x( 'Preset', 'Background Preset' ),
</ins><span class="cx" style="display: block; padding: 0 10px">                         'section'    => 'background_image',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        'type'       => 'radio',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 'type'       => 'select',
</ins><span class="cx" style="display: block; padding: 0 10px">                         'choices'    => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'no-repeat'  => __('No Repeat'),
-                               'repeat'     => __('Tile'),
-                               'repeat-x'   => __('Tile Horizontally'),
-                               'repeat-y'   => __('Tile Vertically'),
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'default' => _x( 'Default', 'Default Preset' ),
+                               'fill'    => __( 'Fill Screen' ),
+                               'fit'     => __( 'Fit to Screen' ),
+                               'repeat'  => _x( 'Repeat', 'Repeat Image' ),
+                               'custom'  => _x( 'Custom', 'Custom Preset' ),
</ins><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><span class="cx" style="display: block; padding: 0 10px">                $this->add_setting( 'background_position_x', array(
</span><span class="cx" style="display: block; padding: 0 10px">                        'default'        => get_theme_support( 'custom-background', 'default-position-x' ),
</span><span class="cx" style="display: block; padding: 0 10px">                        'theme_supports' => 'custom-background',
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        'sanitize_callback' => array( $this, '_sanitize_background_setting' ),
</ins><span class="cx" style="display: block; padding: 0 10px">                 ) );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $this->add_control( 'background_position_x', array(
-                       'label'      => __( 'Background Position' ),
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $this->add_setting( 'background_position_y', array(
+                       'default'        => get_theme_support( 'custom-background', 'default-position-y' ),
+                       'theme_supports' => 'custom-background',
+                       'sanitize_callback' => array( $this, '_sanitize_background_setting' ),
+               ) );
+
+               $this->add_control( new WP_Customize_Background_Position_Control( $this, 'background_position', array(
+                       'label'    => __( 'Image Position' ),
+                       'section'  => 'background_image',
+                       'settings' => array(
+                               'x' => 'background_position_x',
+                               'y' => 'background_position_y',
+                       ),
+               ) ) );
+
+               $this->add_setting( 'background_size', array(
+                       'default'        => get_theme_support( 'custom-background', 'default-size' ),
+                       'theme_supports' => 'custom-background',
+                       'sanitize_callback' => array( $this, '_sanitize_background_setting' ),
+               ) );
+
+               $this->add_control( 'background_size', array(
+                       'label'      => __( 'Image Size' ),
</ins><span class="cx" style="display: block; padding: 0 10px">                         'section'    => 'background_image',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        'type'       => 'radio',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 'type'       => 'select',
</ins><span class="cx" style="display: block; padding: 0 10px">                         'choices'    => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'left'       => __('Left'),
-                               'center'     => __('Center'),
-                               'right'      => __('Right'),
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'auto'    => __( 'Original' ),
+                               'contain' => __( 'Fit to Screen' ),
+                               'cover'   => __( 'Fill Screen' ),
</ins><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">+                $this->add_setting( 'background_repeat', array(
+                       'default'           => get_theme_support( 'custom-background', 'default-repeat' ),
+                       'sanitize_callback' => array( $this, '_sanitize_background_setting' ),
+                       'theme_supports'    => 'custom-background',
+               ) );
+
+               $this->add_control( 'background_repeat', array(
+                       'label'    => __( 'Repeat Background Image' ),
+                       'section'  => 'background_image',
+                       'type'     => 'checkbox',
+               ) );
+
</ins><span class="cx" style="display: block; padding: 0 10px">                 $this->add_setting( 'background_attachment', array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        'default'        => get_theme_support( 'custom-background', 'default-attachment' ),
-                       'theme_supports' => 'custom-background',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 'default'           => get_theme_support( 'custom-background', 'default-attachment' ),
+                       'sanitize_callback' => array( $this, '_sanitize_background_setting' ),
+                       'theme_supports'    => 'custom-background',
</ins><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">                $this->add_control( 'background_attachment', array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        'label'      => __( 'Background Attachment' ),
-                       'section'    => 'background_image',
-                       'type'       => 'radio',
-                       'choices'    => array(
-                               'scroll'     => __('Scroll'),
-                               'fixed'      => __('Fixed'),
-                       ),
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 'label'    => __( 'Scroll with Page' ),
+                       'section'  => 'background_image',
+                       'type'     => 'checkbox',
</ins><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">+
</ins><span class="cx" style="display: block; padding: 0 10px">                 // If the theme is using the default background callback, we can update
</span><span class="cx" style="display: block; padding: 0 10px">                // the background CSS using postMessage.
</span><span class="cx" style="display: block; padding: 0 10px">                if ( get_theme_support( 'custom-background', 'wp-head-callback' ) === '_custom_background_cb' ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        foreach ( array( 'color', 'image', 'position_x', 'repeat', 'attachment' ) as $prop ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 foreach ( array( 'color', 'image', 'preset', 'position_x', 'position_y', 'size', 'repeat', 'attachment' ) as $prop ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                                 $this->get_setting( 'background_' . $prop )->transport = 'postMessage';
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3624,6 +3662,49 @@
</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">+         * Callback for validating a background setting value.
+        *
+        * @since 4.7.0
+        * @access private
+        *
+        * @param string $value Repeat value.
+        * @param WP_Customize_Setting $setting Setting.
+        * @return string|WP_Error Background value or validation error.
+        */
+       public function _sanitize_background_setting( $value, $setting ) {
+               if ( 'background_repeat' === $setting->id ) {
+                       if ( ! in_array( $value, array( 'repeat-x', 'repeat-y', 'repeat', 'no-repeat' ) ) ) {
+                               return new WP_Error( 'invalid_value', __( 'Invalid value for background repeat.' ) );
+                       }
+               } else if ( 'background_attachment' === $setting->id ) {
+                       if ( ! in_array( $value, array( 'fixed', 'scroll' ) ) ) {
+                               return new WP_Error( 'invalid_value', __( 'Invalid value for background attachment.' ) );
+                       }
+               } else if ( 'background_position_x' === $setting->id ) {
+                       if ( ! in_array( $value, array( 'left', 'center', 'right' ), true ) ) {
+                               return new WP_Error( 'invalid_value', __( 'Invalid value for background position X.' ) );
+                       }
+               } else if ( 'background_position_y' === $setting->id ) {
+                       if ( ! in_array( $value, array( 'top', 'center', 'bottom' ), true ) ) {
+                               return new WP_Error( 'invalid_value', __( 'Invalid value for background position Y.' ) );
+                       }
+               } else if ( 'background_size' === $setting->id ) {
+                       if ( ! in_array( $value, array( 'auto', 'contain', 'cover' ), true ) ) {
+                               return new WP_Error( 'invalid_value', __( 'Invalid value for background size.' ) );
+                       }
+               } else if ( 'background_preset' === $setting->id ) {
+                       if ( ! in_array( $value, array( 'default', 'fill', 'fit', 'repeat', 'custom' ), true ) ) {
+                               return new WP_Error( 'invalid_value', __( 'Invalid value for background size.' ) );
+                       }
+               } else if ( 'background_image' === $setting->id || 'background_image_thumb' === $setting->id ) {
+                       $value = empty( $value ) ? '' : esc_url_raw( $value );
+               } else {
+                       return new WP_Error( 'unrecognized_setting', __( 'Unrecognized background setting.' ) );
+               }
+               return $value;
+       }
+
+       /**
</ins><span class="cx" style="display: block; padding: 0 10px">          * Callback for rendering the custom logo, used in the custom_logo partial.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * This method exists because the partial object and context data are passed
</span></span></pre></div>
<a id="trunksrcwpincludescustomizeclasswpcustomizebackgroundimagecontrolphp"></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/customize/class-wp-customize-background-image-control.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/customize/class-wp-customize-background-image-control.php   2016-10-26 06:27:04 UTC (rev 38947)
+++ trunk/src/wp-includes/customize/class-wp-customize-background-image-control.php     2016-10-26 06:51:11 UTC (rev 38948)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -40,7 +40,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">        public function enqueue() {
</span><span class="cx" style="display: block; padding: 0 10px">                parent::enqueue();
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                $custom_background = get_theme_support( 'custom-background' );
</ins><span class="cx" style="display: block; padding: 0 10px">                 wp_localize_script( 'customize-controls', '_wpCustomizeBackground', array(
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        'defaults' => ! empty( $custom_background[0] ) ? $custom_background[0] : array(),
</ins><span class="cx" style="display: block; padding: 0 10px">                         'nonces' => array(
</span><span class="cx" style="display: block; padding: 0 10px">                                'add' => wp_create_nonce( 'background-add' ),
</span><span class="cx" style="display: block; padding: 0 10px">                        ),
</span></span></pre></div>
<a id="trunksrcwpincludescustomizeclasswpcustomizebackgroundpositioncontrolphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: trunk/src/wp-includes/customize/class-wp-customize-background-position-control.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/customize/class-wp-customize-background-position-control.php                                (rev 0)
+++ trunk/src/wp-includes/customize/class-wp-customize-background-position-control.php  2016-10-26 06:51:11 UTC (rev 38948)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,87 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * Customize API: WP_Customize_Background_Position_Control class
+ *
+ * @package WordPress
+ * @subpackage Customize
+ * @since 4.7.0
+ */
+
+/**
+ * Customize Background Position Control class.
+ *
+ * @since 4.7.0
+ *
+ * @see WP_Customize_Control
+ */
+class WP_Customize_Background_Position_Control extends WP_Customize_Control {
+
+       /**
+        * Type.
+        *
+        * @since 4.7.0
+        * @access public
+        * @var string
+        */
+       public $type = 'background_position';
+
+       /**
+        * Don't render the control content from PHP, as it's rendered via JS on load.
+        *
+        * @since 4.7.0
+        * @access public
+        */
+       public function render_content() {}
+
+       /**
+        * Render a JS template for the content of the position control.
+        *
+        * @since 4.7.0
+        * @access public
+        */
+       public function content_template() {
+               $options = array(
+                       array(
+                               'left top'   => array( 'label' => __( 'Top Left' ), 'icon' => 'dashicons dashicons-arrow-left-alt' ),
+                               'center top' => array( 'label' => __( 'Top' ), 'icon' => 'dashicons dashicons-arrow-up-alt' ),
+                               'right top'  => array( 'label' => __( 'Top Right' ), 'icon' => 'dashicons dashicons-arrow-right-alt' ),
+                       ),
+                       array(
+                               'left center'   => array( 'label' => __( 'Left' ), 'icon' => 'dashicons dashicons-arrow-left-alt' ),
+                               'center center' => array( 'label' => __( 'Center' ), 'icon' => 'background-position-center-icon' ),
+                               'right center'  => array( 'label' => __( 'Right' ), 'icon' => 'dashicons dashicons-arrow-right-alt' ),
+                       ),
+                       array(
+                               'left bottom'   => array( 'label' => __( 'Bottom Left' ), 'icon' => 'dashicons dashicons-arrow-left-alt' ),
+                               'center bottom' => array( 'label' => __( 'Bottom' ), 'icon' => 'dashicons dashicons-arrow-down-alt' ),
+                               'right bottom'  => array( 'label' => __( 'Bottom Right' ), 'icon' => 'dashicons dashicons-arrow-right-alt' ),
+                       ),
+               );
+               ?>
+               <# if ( data.label ) { #>
+                       <span class="customize-control-title">{{{ data.label }}}</span>
+               <# } #>
+               <# if ( data.description ) { #>
+                       <span class="description customize-control-description">{{{ data.description }}}</span>
+               <# } #>
+               <div class="customize-control-content">
+                       <fieldset>
+                               <legend class="screen-reader-text"><span><?php _e( 'Image Position' ); ?></span></legend>
+                               <div class="background-position-control">
+                               <?php foreach ( $options as $group ) : ?>
+                                       <div class="button-group">
+                                       <?php foreach ( $group as $value => $input ) : ?>
+                                               <label>
+                                                       <input class="screen-reader-text" name="background-position" type="radio" value="<?php echo esc_attr( $value ); ?>">
+                                                       <span class="button display-options position"><span class="<?php echo esc_attr( $input['icon'] ); ?>" aria-hidden="true"></span></span>
+                                                       <span class="screen-reader-text"><?php echo $input['label']; ?></span>
+                                               </label>
+                                       <?php endforeach; ?>
+                                       </div>
+                               <?php endforeach; ?>
+                               </div>
+                       </fieldset>
+               </div>
+               <?php
+       }
+}
</ins></span></pre></div>
<a id="trunksrcwpincludesjscustomizepreviewjs"></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/js/customize-preview.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/js/customize-preview.js     2016-10-26 06:27:04 UTC (rev 38947)
+++ trunk/src/wp-includes/js/customize-preview.js       2016-10-26 06:51:11 UTC (rev 38948)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -735,11 +735,11 @@
</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">                /* Custom Backgrounds */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                bg = $.map(['color', 'image', 'position_x', 'repeat', 'attachment'], function( prop ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         bg = $.map( ['color', 'image', 'preset', 'position_x', 'position_y', 'size', 'repeat', 'attachment'], function( prop ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                         return 'background_' + prop;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                });
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         } );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                api.when.apply( api, bg ).done( function( color, image, position_x, repeat, attachment ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         api.when.apply( api, bg ).done( function( color, image, preset, positionX, positionY, size, repeat, attachment ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                         var body = $(document.body),
</span><span class="cx" style="display: block; padding: 0 10px">                                head = $('head'),
</span><span class="cx" style="display: block; padding: 0 10px">                                style = $('#custom-background-css'),
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -759,7 +759,8 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                                if ( image() ) {
</span><span class="cx" style="display: block; padding: 0 10px">                                        css += 'background-image: url("' + image() + '");';
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        css += 'background-position: top ' + position_x() + ';';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 css += 'background-size: ' + size() + ';';
+                                       css += 'background-position: ' + positionX() + ' ' + positionY() + ';';
</ins><span class="cx" style="display: block; padding: 0 10px">                                         css += 'background-repeat: ' + repeat() + ';';
</span><span class="cx" style="display: block; padding: 0 10px">                                        css += 'background-attachment: ' + attachment() + ';';
</span><span class="cx" style="display: block; padding: 0 10px">                                }
</span></span></pre></div>
<a id="trunksrcwpincludesthemephp"></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/theme.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/theme.php   2016-10-26 06:27:04 UTC (rev 38947)
+++ trunk/src/wp-includes/theme.php     2016-10-26 06:51:11 UTC (rev 38948)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1374,24 +1374,50 @@
</span><span class="cx" style="display: block; padding: 0 10px">        $style = $color ? "background-color: #$color;" : '';
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        if ( $background ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $image = " background-image: url('$background');";
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $image = " background-image: url(" . wp_json_encode( $background ) . ");";
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                // Background Position.
+               $position_x = get_theme_mod( 'background_position_x', get_theme_support( 'custom-background', 'default-position-x' ) );
+               $position_y = get_theme_mod( 'background_position_y', get_theme_support( 'custom-background', 'default-position-y' ) );
+
+               if ( ! in_array( $position_x, array( 'left', 'center', 'right' ), true ) ) {
+                       $position_x = 'left';
+               }
+
+               if ( ! in_array( $position_y, array( 'top', 'center', 'bottom' ), true ) ) {
+                       $position_y = 'top';
+               }
+
+               $position = " background-position: $position_x $position_y;";
+
+               // Background Size.
+               $size = get_theme_mod( 'background_size', get_theme_support( 'custom-background', 'default-size' ) );
+
+               if ( ! in_array( $size, array( 'auto', 'contain', 'cover' ), true ) ) {
+                       $size = 'auto';
+               }
+
+               $size = " background-size: $size;";
+
+               // Background Repeat.
</ins><span class="cx" style="display: block; padding: 0 10px">                 $repeat = get_theme_mod( 'background_repeat', get_theme_support( 'custom-background', 'default-repeat' ) );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                if ( ! in_array( $repeat, array( 'no-repeat', 'repeat-x', 'repeat-y', 'repeat' ) ) )
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+               if ( ! in_array( $repeat, array( 'repeat-x', 'repeat-y', 'repeat', 'no-repeat' ), true ) ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                         $repeat = 'repeat';
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                }
+
</ins><span class="cx" style="display: block; padding: 0 10px">                 $repeat = " background-repeat: $repeat;";
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $position = get_theme_mod( 'background_position_x', get_theme_support( 'custom-background', 'default-position-x' ) );
-               if ( ! in_array( $position, array( 'center', 'right', 'left' ) ) )
-                       $position = 'left';
-               $position = " background-position: top $position;";
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // Background Scroll.
+               $attachment = get_theme_mod( 'background_attachment', get_theme_support( 'custom-background', 'default-attachment' ) );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $attachment = get_theme_mod( 'background_attachment', get_theme_support( 'custom-background', 'default-attachment' ) );
-               if ( ! in_array( $attachment, array( 'fixed', 'scroll' ) ) )
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( 'fixed' !== $attachment ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                         $attachment = 'scroll';
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                }
+
</ins><span class="cx" style="display: block; padding: 0 10px">                 $attachment = " background-attachment: $attachment;";
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $style .= $image . $repeat . $position . $attachment;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $style .= $image . $position . $size . $repeat . $attachment;
</ins><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"> <style type="text/css" id="custom-background-css">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1772,8 +1798,11 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        $defaults = array(
</span><span class="cx" style="display: block; padding: 0 10px">                                'default-image'          => '',
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                'default-preset'         => 'default',
+                               'default-position-x'     => 'left',
+                               'default-position-y'     => 'top',
+                               'default-size'           => 'auto',
</ins><span class="cx" style="display: block; padding: 0 10px">                                 'default-repeat'         => 'repeat',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'default-position-x'     => 'left',
</del><span class="cx" style="display: block; padding: 0 10px">                                 'default-attachment'     => 'scroll',
</span><span class="cx" style="display: block; padding: 0 10px">                                'default-color'          => '',
</span><span class="cx" style="display: block; padding: 0 10px">                                'wp-head-callback'       => '_custom_background_cb',
</span></span></pre>
</div>
</div>

</body>
</html>