<!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>[37040] trunk: Customize: Require opt-in for selective refresh of widgets.</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/37040">37040</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/37040","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-03-21 21:58:02 +0000 (Mon, 21 Mar 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: Require opt-in for selective refresh of widgets.

* Introduces `customize-selective-refresh-widgets` theme support feature and adds to themes.
* Introduces `customize_selective_refresh` arg for `WP_Widget::$widget_options` and adds to all core widgets.
* Remove `selective_refresh` from being a component that can be removed via `customize_loaded_components` filter.
* Add `WP_Customize_Widgets::get_selective_refreshable_widgets()` and `WP_Customize_Widgets::is_widget_selective_refreshable()`.
* Fix default `selector` for `Partial` instances.
* Implement and improve Masronry sidebar refresh logic in Twenty Thirteen and Twenty Fourteen, including preservation of initial widget position after refresh.
* Re-initialize ME.js when refreshing `Twenty_Fourteen_Ephemera_Widget`.

See <a href="https://core.trac.wordpress.org/ticket/27355">#27355</a>.
Fixes <a href="https://core.trac.wordpress.org/ticket/35855">#35855</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpadminjscustomizewidgetsjs">trunk/src/wp-admin/js/customize-widgets.js</a></li>
<li><a href="#trunksrcwpcontentthemestwentyelevenfunctionsphp">trunk/src/wp-content/themes/twentyeleven/functions.php</a></li>
<li><a href="#trunksrcwpcontentthemestwentyelevenincwidgetsphp">trunk/src/wp-content/themes/twentyeleven/inc/widgets.php</a></li>
<li><a href="#trunksrcwpcontentthemestwentyfifteenfunctionsphp">trunk/src/wp-content/themes/twentyfifteen/functions.php</a></li>
<li><a href="#trunksrcwpcontentthemestwentyfourteenfunctionsphp">trunk/src/wp-content/themes/twentyfourteen/functions.php</a></li>
<li><a href="#trunksrcwpcontentthemestwentyfourteenincwidgetsphp">trunk/src/wp-content/themes/twentyfourteen/inc/widgets.php</a></li>
<li><a href="#trunksrcwpcontentthemestwentyfourteenjsfunctionsjs">trunk/src/wp-content/themes/twentyfourteen/js/functions.js</a></li>
<li><a href="#trunksrcwpcontentthemestwentythirteenfunctionsphp">trunk/src/wp-content/themes/twentythirteen/functions.php</a></li>
<li><a href="#trunksrcwpcontentthemestwentythirteenjsfunctionsjs">trunk/src/wp-content/themes/twentythirteen/js/functions.js</a></li>
<li><a href="#trunksrcwpcontentthemestwentythirteenjsthemecustomizerjs">trunk/src/wp-content/themes/twentythirteen/js/theme-customizer.js</a></li>
<li><a href="#trunksrcwpcontentthemestwentytwelvefunctionsphp">trunk/src/wp-content/themes/twentytwelve/functions.php</a></li>
<li><a href="#trunksrcwpincludesclasswpcustomizemanagerphp">trunk/src/wp-includes/class-wp-customize-manager.php</a></li>
<li><a href="#trunksrcwpincludesclasswpcustomizenavmenusphp">trunk/src/wp-includes/class-wp-customize-nav-menus.php</a></li>
<li><a href="#trunksrcwpincludesclasswpcustomizewidgetsphp">trunk/src/wp-includes/class-wp-customize-widgets.php</a></li>
<li><a href="#trunksrcwpincludesclasswpwidgetphp">trunk/src/wp-includes/class-wp-widget.php</a></li>
<li><a href="#trunksrcwpincludesjscustomizepreviewwidgetsjs">trunk/src/wp-includes/js/customize-preview-widgets.js</a></li>
<li><a href="#trunksrcwpincludesjscustomizeselectiverefreshjs">trunk/src/wp-includes/js/customize-selective-refresh.js</a></li>
<li><a href="#trunksrcwpincludesscriptloaderphp">trunk/src/wp-includes/script-loader.php</a></li>
<li><a href="#trunksrcwpincludesthemephp">trunk/src/wp-includes/theme.php</a></li>
<li><a href="#trunksrcwpincludeswidgetsclasswpnavmenuwidgetphp">trunk/src/wp-includes/widgets/class-wp-nav-menu-widget.php</a></li>
<li><a href="#trunksrcwpincludeswidgetsclasswpwidgetarchivesphp">trunk/src/wp-includes/widgets/class-wp-widget-archives.php</a></li>
<li><a href="#trunksrcwpincludeswidgetsclasswpwidgetcalendarphp">trunk/src/wp-includes/widgets/class-wp-widget-calendar.php</a></li>
<li><a href="#trunksrcwpincludeswidgetsclasswpwidgetcategoriesphp">trunk/src/wp-includes/widgets/class-wp-widget-categories.php</a></li>
<li><a href="#trunksrcwpincludeswidgetsclasswpwidgetlinksphp">trunk/src/wp-includes/widgets/class-wp-widget-links.php</a></li>
<li><a href="#trunksrcwpincludeswidgetsclasswpwidgetmetaphp">trunk/src/wp-includes/widgets/class-wp-widget-meta.php</a></li>
<li><a href="#trunksrcwpincludeswidgetsclasswpwidgetpagesphp">trunk/src/wp-includes/widgets/class-wp-widget-pages.php</a></li>
<li><a href="#trunksrcwpincludeswidgetsclasswpwidgetrecentcommentsphp">trunk/src/wp-includes/widgets/class-wp-widget-recent-comments.php</a></li>
<li><a href="#trunksrcwpincludeswidgetsclasswpwidgetrecentpostsphp">trunk/src/wp-includes/widgets/class-wp-widget-recent-posts.php</a></li>
<li><a href="#trunksrcwpincludeswidgetsclasswpwidgetrssphp">trunk/src/wp-includes/widgets/class-wp-widget-rss.php</a></li>
<li><a href="#trunksrcwpincludeswidgetsclasswpwidgetsearchphp">trunk/src/wp-includes/widgets/class-wp-widget-search.php</a></li>
<li><a href="#trunksrcwpincludeswidgetsclasswpwidgettagcloudphp">trunk/src/wp-includes/widgets/class-wp-widget-tag-cloud.php</a></li>
<li><a href="#trunksrcwpincludeswidgetsclasswpwidgettextphp">trunk/src/wp-includes/widgets/class-wp-widget-text.php</a></li>
<li><a href="#trunktestsphpunittestscustomizemanagerphp">trunk/tests/phpunit/tests/customize/manager.php</a></li>
<li><a href="#trunktestsphpunittestscustomizewidgetsphp">trunk/tests/phpunit/tests/customize/widgets.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcwpadminjscustomizewidgetsjs"></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-widgets.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-admin/js/customize-widgets.js        2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-admin/js/customize-widgets.js  2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -34,7 +34,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                multi_number: null,
</span><span class="cx" style="display: block; padding: 0 10px">                name: null,
</span><span class="cx" style="display: block; padding: 0 10px">                id_base: null,
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                transport: api.Widgets.data.selectiveRefresh ? 'postMessage' : 'refresh',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         transport: null,
</ins><span class="cx" style="display: block; padding: 0 10px">                 params: [],
</span><span class="cx" style="display: block; padding: 0 10px">                width: null,
</span><span class="cx" style="display: block; padding: 0 10px">                height: null,
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1982,7 +1982,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        isExistingWidget = api.has( settingId );
</span><span class="cx" style="display: block; padding: 0 10px">                        if ( ! isExistingWidget ) {
</span><span class="cx" style="display: block; padding: 0 10px">                                settingArgs = {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        transport: api.Widgets.data.selectiveRefresh ? 'postMessage' : 'refresh',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 transport: api.Widgets.data.selectiveRefreshableWidgets[ widget.get( 'id_base' ) ] ? 'postMessage' : 'refresh',
</ins><span class="cx" style="display: block; padding: 0 10px">                                         previewer: this.setting.previewer
</span><span class="cx" style="display: block; padding: 0 10px">                                };
</span><span class="cx" style="display: block; padding: 0 10px">                                setting = api.create( settingId, settingId, '', settingArgs );
</span></span></pre></div>
<a id="trunksrcwpcontentthemestwentyelevenfunctionsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-content/themes/twentyeleven/functions.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-content/themes/twentyeleven/functions.php    2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-content/themes/twentyeleven/functions.php      2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -226,6 +226,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        'description' => __( 'Hanoi Plant', 'twentyeleven' )
</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">+
+       // Indicate widget sidebars can use selective refresh in the Customizer.
+       add_theme_support( 'customize-selective-refresh-widgets' );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> endif; // twentyeleven_setup
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span></span></pre></div>
<a id="trunksrcwpcontentthemestwentyelevenincwidgetsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-content/themes/twentyeleven/inc/widgets.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-content/themes/twentyeleven/inc/widgets.php  2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-content/themes/twentyeleven/inc/widgets.php    2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -21,6 +21,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                parent::__construct( 'widget_twentyeleven_ephemera', __( 'Twenty Eleven Ephemera', 'twentyeleven' ), array(
</span><span class="cx" style="display: block; padding: 0 10px">                        'classname'   => 'widget_twentyeleven_ephemera',
</span><span class="cx" style="display: block; padding: 0 10px">                        'description' => __( 'Use this widget to list your recent Aside, Status, Quote, and Link posts', 'twentyeleven' ),
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        'customize_selective_refresh' => true,
</ins><span class="cx" style="display: block; padding: 0 10px">                 ) );
</span><span class="cx" style="display: block; padding: 0 10px">                $this->alt_option_name = 'widget_twentyeleven_ephemera';
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span></span></pre></div>
<a id="trunksrcwpcontentthemestwentyfifteenfunctionsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-content/themes/twentyfifteen/functions.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-content/themes/twentyfifteen/functions.php   2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-content/themes/twentyfifteen/functions.php     2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -125,6 +125,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * specifically font, colors, icons, and column width.
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        add_editor_style( array( 'css/editor-style.css', 'genericons/genericons.css', twentyfifteen_fonts_url() ) );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+       // Indicate widget sidebars can use selective refresh in the Customizer.
+       add_theme_support( 'customize-selective-refresh-widgets' );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> endif; // twentyfifteen_setup
</span><span class="cx" style="display: block; padding: 0 10px"> add_action( 'after_setup_theme', 'twentyfifteen_setup' );
</span></span></pre></div>
<a id="trunksrcwpcontentthemestwentyfourteenfunctionsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-content/themes/twentyfourteen/functions.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-content/themes/twentyfourteen/functions.php  2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-content/themes/twentyfourteen/functions.php    2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -113,6 +113,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        // This theme uses its own gallery styles.
</span><span class="cx" style="display: block; padding: 0 10px">        add_filter( 'use_default_gallery_style', '__return_false' );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+       // Indicate widget sidebars can use selective refresh in the Customizer.
+       add_theme_support( 'customize-selective-refresh-widgets' );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> endif; // twentyfourteen_setup
</span><span class="cx" style="display: block; padding: 0 10px"> add_action( 'after_setup_theme', 'twentyfourteen_setup' );
</span></span></pre></div>
<a id="trunksrcwpcontentthemestwentyfourteenincwidgetsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-content/themes/twentyfourteen/inc/widgets.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-content/themes/twentyfourteen/inc/widgets.php        2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-content/themes/twentyfourteen/inc/widgets.php  2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -34,10 +34,31 @@
</span><span class="cx" style="display: block; padding: 0 10px">                parent::__construct( 'widget_twentyfourteen_ephemera', __( 'Twenty Fourteen Ephemera', 'twentyfourteen' ), array(
</span><span class="cx" style="display: block; padding: 0 10px">                        'classname'   => 'widget_twentyfourteen_ephemera',
</span><span class="cx" style="display: block; padding: 0 10px">                        'description' => __( 'Use this widget to list your recent Aside, Quote, Video, Audio, Image, Gallery, and Link posts.', 'twentyfourteen' ),
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        'customize_selective_refresh' => true,
</ins><span class="cx" style="display: block; padding: 0 10px">                 ) );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+               if ( is_active_widget( false, false, $this->id_base ) || is_customize_preview() ) {
+                       add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
+               }
</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">+         * Enqueue scripts.
+        *
+        * @since Twenty Fourteen 1.7
+        */
+       public function enqueue_scripts() {
+               /** This filter is documented in wp-includes/media.php */
+               $audio_library = apply_filters( 'wp_audio_shortcode_library', 'mediaelement' );
+               /** This filter is documented in wp-includes/media.php */
+               $video_library = apply_filters( 'wp_video_shortcode_library', 'mediaelement' );
+               if ( in_array( 'mediaelement', array( $video_library, $audio_library ), true ) ) {
+                       wp_enqueue_style( 'wp-mediaelement' );
+                       wp_enqueue_script( 'wp-mediaelement' );
+               }
+       }
+
+       /**
</ins><span class="cx" style="display: block; padding: 0 10px">          * Output the HTML for this widget.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @access public
</span></span></pre></div>
<a id="trunksrcwpcontentthemestwentyfourteenjsfunctionsjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-content/themes/twentyfourteen/js/functions.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-content/themes/twentyfourteen/js/functions.js        2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-content/themes/twentyfourteen/js/functions.js  2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -146,9 +146,13 @@
</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">        _window.load( function() {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                var footerSidebar,
+                       isCustomizeSelectiveRefresh = ( 'undefined' !== typeof wp && wp.customize && wp.customize.selectiveRefresh );
+
</ins><span class="cx" style="display: block; padding: 0 10px">                 // Arrange footer widgets vertically.
</span><span class="cx" style="display: block; padding: 0 10px">                if ( $.isFunction( $.fn.masonry ) ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $( '#footer-sidebar' ).masonry( {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 footerSidebar = $( '#footer-sidebar' );
+                       footerSidebar.masonry( {
</ins><span class="cx" style="display: block; padding: 0 10px">                                 itemSelector: '.widget',
</span><span class="cx" style="display: block; padding: 0 10px">                                columnWidth: function( containerWidth ) {
</span><span class="cx" style="display: block; padding: 0 10px">                                        return containerWidth / 4;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -157,8 +161,43 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                isResizable: true,
</span><span class="cx" style="display: block; padding: 0 10px">                                isRTL: $( 'body' ).is( '.rtl' )
</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 ( isCustomizeSelectiveRefresh ) {
+
+                               // Retain previous masonry-brick initial position.
+                               wp.customize.selectiveRefresh.bind( 'partial-content-rendered', function( placement ) {
+                                       var copyPosition = (
+                                               placement.partial.extended( wp.customize.widgetsPreview.WidgetPartial ) &&
+                                               placement.removedNodes instanceof jQuery &&
+                                               placement.removedNodes.is( '.masonry-brick' ) &&
+                                               placement.container instanceof jQuery
+                                       );
+                                       if ( copyPosition ) {
+                                               placement.container.css( {
+                                                       position: placement.removedNodes.css( 'position' ),
+                                                       top: placement.removedNodes.css( 'top' ),
+                                                       left: placement.removedNodes.css( 'left' )
+                                               } );
+                                       }
+                               } );
+
+                               // Re-arrange footer widgets after selective refresh event.
+                               wp.customize.selectiveRefresh.bind( 'sidebar-updated', function( sidebarPartial ) {
+                                       if ( 'sidebar-3' === sidebarPartial.sidebarId ) {
+                                               footerSidebar.masonry( 'reloadItems' );
+                                               footerSidebar.masonry( 'layout' );
+                                       }
+                               } );
+                       }
</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">+                // Initialize audio and video players in Twenty_Fourteen_Ephemera_Widget widget when selectively refreshed in Customizer.
+               if ( isCustomizeSelectiveRefresh && wp.mediaelement ) {
+                       wp.customize.selectiveRefresh.bind( 'partial-content-rendered', function() {
+                               wp.mediaelement.initialize();
+                       } );
+               }
+
</ins><span class="cx" style="display: block; padding: 0 10px">                 // Initialize Featured Content slider.
</span><span class="cx" style="display: block; padding: 0 10px">                if ( body.is( '.slider' ) ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        $( '.featured-content' ).featuredslider( {
</span></span></pre></div>
<a id="trunksrcwpcontentthemestwentythirteenfunctionsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-content/themes/twentythirteen/functions.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-content/themes/twentythirteen/functions.php  2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-content/themes/twentythirteen/functions.php    2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -105,6 +105,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        // This theme uses its own gallery styles.
</span><span class="cx" style="display: block; padding: 0 10px">        add_filter( 'use_default_gallery_style', '__return_false' );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+       // Indicate widget sidebars can use selective refresh in the Customizer.
+       add_theme_support( 'customize-selective-refresh-widgets' );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> add_action( 'after_setup_theme', 'twentythirteen_setup' );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span></span></pre></div>
<a id="trunksrcwpcontentthemestwentythirteenjsfunctionsjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-content/themes/twentythirteen/js/functions.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-content/themes/twentythirteen/js/functions.js        2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-content/themes/twentythirteen/js/functions.js  2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -120,13 +120,42 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * Arranges footer widgets vertically.
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        if ( $.isFunction( $.fn.masonry ) ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                var columnWidth = body.is( '.sidebar' ) ? 228 : 245;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         var columnWidth = body.is( '.sidebar' ) ? 228 : 245,
+                       widgetArea = $( '#secondary .widget-area' );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $( '#secondary .widget-area' ).masonry( {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         widgetArea.masonry( {
</ins><span class="cx" style="display: block; padding: 0 10px">                         itemSelector: '.widget',
</span><span class="cx" style="display: block; padding: 0 10px">                        columnWidth: columnWidth,
</span><span class="cx" style="display: block; padding: 0 10px">                        gutterWidth: 20,
</span><span class="cx" style="display: block; padding: 0 10px">                        isRTL: body.is( '.rtl' )
</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 ( 'undefined' !== typeof wp && wp.customize && wp.customize.selectiveRefresh ) {
+
+                       // Retain previous masonry-brick initial position.
+                       wp.customize.selectiveRefresh.bind( 'partial-content-rendered', function( placement ) {
+                               var copyPosition = (
+                                       placement.partial.extended( wp.customize.widgetsPreview.WidgetPartial ) &&
+                                       placement.removedNodes instanceof jQuery &&
+                                       placement.removedNodes.is( '.masonry-brick' ) &&
+                                       placement.container instanceof jQuery
+                               );
+                               if ( copyPosition ) {
+                                       placement.container.css( {
+                                               position: placement.removedNodes.css( 'position' ),
+                                               top: placement.removedNodes.css( 'top' ),
+                                               left: placement.removedNodes.css( 'left' )
+                                       } );
+                               }
+                       } );
+
+                       // Re-arrange footer widgets when sidebar is updated via selective refresh in the Customizer.
+                       wp.customize.selectiveRefresh.bind( 'sidebar-updated', function( sidebarPartial ) {
+                               if ( 'sidebar-1' === sidebarPartial.sidebarId ) {
+                                       widgetArea.masonry( 'reloadItems' );
+                                       widgetArea.masonry( 'layout' );
+                               }
+                       } );
+               }
</ins><span class="cx" style="display: block; padding: 0 10px">         }
</span><span class="cx" style="display: block; padding: 0 10px"> } )( jQuery );
</span><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of file
</span></span></pre></div>
<a id="trunksrcwpcontentthemestwentythirteenjsthemecustomizerjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-content/themes/twentythirteen/js/theme-customizer.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-content/themes/twentythirteen/js/theme-customizer.js 2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-content/themes/twentythirteen/js/theme-customizer.js   2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -38,16 +38,4 @@
</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">-
-       if ( wp.customize.selectiveRefresh ) {
-               wp.customize.selectiveRefresh.bind( 'sidebar-updated', function( sidebarPartial ) {
-                       var widgetArea;
-                       if ( 'sidebar-1' === sidebarPartial.sidebarId && $.isFunction( $.fn.masonry ) ) {
-                               widgetArea = $( '#secondary .widget-area' );
-                               widgetArea.masonry( 'destroy' );
-                               widgetArea.masonry();
-                       }
-               } );
-       }
-
</del><span class="cx" style="display: block; padding: 0 10px"> } )( jQuery );
</span></span></pre></div>
<a id="trunksrcwpcontentthemestwentytwelvefunctionsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-content/themes/twentytwelve/functions.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-content/themes/twentytwelve/functions.php    2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-content/themes/twentytwelve/functions.php      2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -74,6 +74,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">        // This theme uses a custom image size for featured images, displayed on "standard" posts.
</span><span class="cx" style="display: block; padding: 0 10px">        add_theme_support( 'post-thumbnails' );
</span><span class="cx" style="display: block; padding: 0 10px">        set_post_thumbnail_size( 624, 9999 ); // Unlimited height, soft crop
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+       // Indicate widget sidebars can use selective refresh in the Customizer.
+       add_theme_support( 'customize-selective-refresh-widgets' );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> add_action( 'after_setup_theme', 'twentytwelve_setup' );
</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-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-includes/class-wp-customize-manager.php        2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -109,7 +109,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @access protected
</span><span class="cx" style="display: block; padding: 0 10px">         * @var array
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        protected $components = array( 'widgets', 'nav_menus', 'selective_refresh' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ protected $components = array( 'widgets', 'nav_menus' );
</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">         * Registered instances of WP_Customize_Section.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -258,6 +258,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">                 */
</span><span class="cx" style="display: block; padding: 0 10px">                $components = apply_filters( 'customize_loaded_components', $this->components, $this );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                require_once( ABSPATH . WPINC . '/customize/class-wp-customize-selective-refresh.php' );
+               $this->selective_refresh = new WP_Customize_Selective_Refresh( $this );
+
</ins><span class="cx" style="display: block; padding: 0 10px">                 if ( in_array( 'widgets', $components, true ) ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        require_once( ABSPATH . WPINC . '/class-wp-customize-widgets.php' );
</span><span class="cx" style="display: block; padding: 0 10px">                        $this->widgets = new WP_Customize_Widgets( $this );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -268,11 +271,6 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        $this->nav_menus = new WP_Customize_Nav_Menus( $this );
</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 ( in_array( 'selective_refresh', $components, true ) ) {
-                       require_once( ABSPATH . WPINC . '/customize/class-wp-customize-selective-refresh.php' );
-                       $this->selective_refresh = new WP_Customize_Selective_Refresh( $this );
-               }
-
</del><span class="cx" style="display: block; padding: 0 10px">                 add_filter( 'wp_die_handler', array( $this, 'wp_die_handler' ) );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                add_action( 'setup_theme', array( $this, 'setup_theme' ) );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1730,7 +1728,6 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        'autofocus' => $this->get_autofocus(),
</span><span class="cx" style="display: block; padding: 0 10px">                        'documentTitleTmpl' => $this->get_document_title_template(),
</span><span class="cx" style="display: block; padding: 0 10px">                        'previewableDevices' => $this->get_previewable_devices(),
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        'selectiveRefreshEnabled' => isset( $this->selective_refresh ),
</del><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">                // Prepare Customize Section objects to pass to JavaScript.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1978,14 +1975,12 @@
</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">-                if ( isset( $this->selective_refresh ) ) {
-                       $this->selective_refresh->add_partial( 'custom_logo', array(
-                               'settings'            => array( 'custom_logo' ),
-                               'selector'            => '.custom-logo-link',
-                               'render_callback'     => array( $this, '_render_custom_logo_partial' ),
-                               'container_inclusive' => true,
-                       ) );
-               }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $this->selective_refresh->add_partial( 'site_logo', array(
+                       'settings'            => array( 'site_logo' ),
+                       'selector'            => '.site-logo-link',
+                       'render_callback'     => array( $this, '_render_site_logo_partial' ),
+                       'container_inclusive' => true,
+               ) );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                /* Colors */
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span></span></pre></div>
<a id="trunksrcwpincludesclasswpcustomizenavmenusphp"></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-nav-menus.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/class-wp-customize-nav-menus.php    2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-includes/class-wp-customize-nav-menus.php      2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -393,7 +393,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                'reorderLabelOn'    => esc_attr__( 'Reorder menu items' ),
</span><span class="cx" style="display: block; padding: 0 10px">                                'reorderLabelOff'   => esc_attr__( 'Close reorder mode' ),
</span><span class="cx" style="display: block; padding: 0 10px">                        ),
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        'settingTransport'     => isset( $this->manager->selective_refresh ) ? 'postMessage' : 'refresh',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 'settingTransport'     => 'postMessage',
</ins><span class="cx" style="display: block; padding: 0 10px">                         'phpIntMax'            => PHP_INT_MAX,
</span><span class="cx" style="display: block; padding: 0 10px">                        'defaultSettingValues' => array(
</span><span class="cx" style="display: block; padding: 0 10px">                                'nav_menu'      => $temp_nav_menu_setting->default,
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -445,12 +445,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">                if ( preg_match( WP_Customize_Nav_Menu_Setting::ID_PATTERN, $setting_id ) ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        $setting_args = array(
</span><span class="cx" style="display: block; padding: 0 10px">                                'type'      => WP_Customize_Nav_Menu_Setting::TYPE,
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'transport' => isset( $this->manager->selective_refresh ) ? 'postMessage' : 'refresh',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'transport' => 'postMessage',
</ins><span class="cx" style="display: block; padding: 0 10px">                         );
</span><span class="cx" style="display: block; padding: 0 10px">                } elseif ( preg_match( WP_Customize_Nav_Menu_Item_Setting::ID_PATTERN, $setting_id ) ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        $setting_args = array(
</span><span class="cx" style="display: block; padding: 0 10px">                                'type'      => WP_Customize_Nav_Menu_Item_Setting::TYPE,
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'transport' => isset( $this->manager->selective_refresh ) ? 'postMessage' : 'refresh',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'transport' => 'postMessage',
</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">                return $setting_args;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -535,7 +535,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        $setting = $this->manager->get_setting( $setting_id );
</span><span class="cx" style="display: block; padding: 0 10px">                        if ( $setting ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                $setting->transport = isset( $this->manager->selective_refresh ) ? 'postMessage' : 'refresh';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         $setting->transport = 'postMessage';
</ins><span class="cx" style="display: block; padding: 0 10px">                                 remove_filter( "customize_sanitize_{$setting_id}", 'absint' );
</span><span class="cx" style="display: block; padding: 0 10px">                                add_filter( "customize_sanitize_{$setting_id}", array( $this, 'intval_base10' ) );
</span><span class="cx" style="display: block; padding: 0 10px">                        } else {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -543,7 +543,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                        'sanitize_callback' => array( $this, 'intval_base10' ),
</span><span class="cx" style="display: block; padding: 0 10px">                                        'theme_supports'    => 'menus',
</span><span class="cx" style="display: block; padding: 0 10px">                                        'type'              => 'theme_mod',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        'transport'         => isset( $this->manager->selective_refresh ) ? 'postMessage' : 'refresh',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 'transport'         => 'postMessage',
</ins><span class="cx" style="display: block; padding: 0 10px">                                         'default'           => 0,
</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">@@ -570,7 +570,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        $nav_menu_setting_id = 'nav_menu[' . $menu_id . ']';
</span><span class="cx" style="display: block; padding: 0 10px">                        $this->manager->add_setting( new WP_Customize_Nav_Menu_Setting( $this->manager, $nav_menu_setting_id, array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'transport' => isset( $this->manager->selective_refresh ) ? 'postMessage' : 'refresh',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'transport' => 'postMessage',
</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">                        // Add the menu contents.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -585,7 +585,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                $value['nav_menu_term_id'] = $menu_id;
</span><span class="cx" style="display: block; padding: 0 10px">                                $this->manager->add_setting( new WP_Customize_Nav_Menu_Item_Setting( $this->manager, $menu_item_setting_id, array(
</span><span class="cx" style="display: block; padding: 0 10px">                                        'value'     => $value,
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        'transport' => isset( $this->manager->selective_refresh ) ? 'postMessage' : 'refresh',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 'transport' => 'postMessage',
</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">                                // Create a control for each menu item.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -988,11 +988,6 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @access public
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function customize_preview_enqueue_deps() {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                if ( isset( $this->manager->selective_refresh ) ) {
-                       $script = wp_scripts()->registered['customize-preview-nav-menus'];
-                       $script->deps[] = 'customize-selective-refresh';
-               }
-
</del><span class="cx" style="display: block; padding: 0 10px">                 wp_enqueue_script( 'customize-preview-nav-menus' ); // Note that we have overridden this.
</span><span class="cx" style="display: block; padding: 0 10px">                wp_enqueue_style( 'customize-preview' );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span></span></pre></div>
<a id="trunksrcwpincludesclasswpcustomizewidgetsphp"></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-widgets.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/class-wp-customize-widgets.php      2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-includes/class-wp-customize-widgets.php        2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -62,6 +62,15 @@
</span><span class="cx" style="display: block; padding: 0 10px">        protected $old_sidebars_widgets = array();
</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">+         * Mapping of widget ID base to whether it supports selective refresh.
+        *
+        * @since 4.5.0
+        * @access protected
+        * @var array
+        */
+       protected $selective_refreshable_widgets;
+
+       /**
</ins><span class="cx" style="display: block; padding: 0 10px">          * Mapping of setting type to setting ID pattern.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @since 4.2.0
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -69,8 +78,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @var array
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        protected $setting_id_patterns = array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                'widget_instance' => '/^(widget_.+?)(?:\[(\d+)\])?$/',
-               'sidebar_widgets' => '/^sidebars_widgets\[(.+?)\]$/',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         'widget_instance' => '/^widget_(?P<id_base>.+?)(?:\[(?P<widget_number>\d+)\])?$/',
+               'sidebar_widgets' => '/^sidebars_widgets\[(?P<sidebar_id>.+?)\]$/',
</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="lines" style="display: block; padding: 0 10px; color: #888">@@ -112,6 +121,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">+         * List whether each registered widget can be use selective refresh.
+        *
+        * If the theme does not support the customize-selective-refresh-widgets feature,
+        * then this will always return an empty array.
+        *
+        * @since 4.5.0
+        * @access public
+        *
+        * @return array Mapping of id_base to support. If theme doesn't support
+        *               selective refresh, an empty array is returned.
+        */
+       public function get_selective_refreshable_widgets() {
+               global $wp_widget_factory;
+               if ( ! current_theme_supports( 'customize-selective-refresh-widgets' ) ) {
+                       return array();
+               }
+               if ( ! isset( $this->selective_refreshable_widgets ) ) {
+                       $this->selective_refreshable_widgets = array();
+                       foreach ( $wp_widget_factory->widgets as $wp_widget ) {
+                               $this->selective_refreshable_widgets[ $wp_widget->id_base ] = ! empty( $wp_widget->widget_options['customize_selective_refresh'] );
+                       }
+               }
+               return $this->selective_refreshable_widgets;
+       }
+
+       /**
+        * Determines if a widget supports selective refresh.
+        *
+        * @since 4.5.0
+        * @access public
+        *
+        * @param string $id_base Widget ID Base.
+        * @return bool Whether the widget can be selective refreshed.
+        */
+       public function is_widget_selective_refreshable( $id_base ) {
+               $selective_refreshable_widgets = $this->get_selective_refreshable_widgets();
+               return ! empty( $selective_refreshable_widgets[ $id_base ] );
+       }
+
+       /**
</ins><span class="cx" style="display: block; padding: 0 10px">          * Retrieves the widget setting type given a setting ID.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @since 4.2.0
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -119,7 +168,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @staticvar array $cache
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * @param $setting_id Setting ID.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * @param string $setting_id Setting ID.
</ins><span class="cx" style="display: block; padding: 0 10px">          * @return string|void Setting type.
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        protected function get_setting_type( $setting_id ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -690,7 +739,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                'widgetReorderNav' => $widget_reorder_nav_tpl,
</span><span class="cx" style="display: block; padding: 0 10px">                                'moveWidgetArea'   => $move_widget_area_tpl,
</span><span class="cx" style="display: block; padding: 0 10px">                        ),
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        'selectiveRefresh'     => isset( $this->manager->selective_refresh ),
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 'selectiveRefreshableWidgets' => $this->get_selective_refreshable_widgets(),
</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">                foreach ( $settings['registeredWidgets'] as &$registered_widget ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -771,16 +820,17 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $args = array(
</span><span class="cx" style="display: block; padding: 0 10px">                        'type'       => 'option',
</span><span class="cx" style="display: block; padding: 0 10px">                        'capability' => 'edit_theme_options',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        'transport'  => isset( $this->manager->selective_refresh ) ? 'postMessage' : 'refresh',
</del><span class="cx" style="display: block; padding: 0 10px">                         'default'    => array(),
</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">                if ( preg_match( $this->setting_id_patterns['sidebar_widgets'], $id, $matches ) ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        $args['sanitize_callback'] = array( $this, 'sanitize_sidebar_widgets' );
</span><span class="cx" style="display: block; padding: 0 10px">                        $args['sanitize_js_callback'] = array( $this, 'sanitize_sidebar_widgets_js_instance' );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        $args['transport'] = current_theme_supports( 'customize-selective-refresh-widgets' ) ? 'postMessage' : 'refresh';
</ins><span class="cx" style="display: block; padding: 0 10px">                 } elseif ( preg_match( $this->setting_id_patterns['widget_instance'], $id, $matches ) ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        $args['sanitize_callback'] = array( $this, 'sanitize_widget_instance' );
</span><span class="cx" style="display: block; padding: 0 10px">                        $args['sanitize_js_callback'] = array( $this, 'sanitize_widget_js_instance' );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        $args['transport'] = $this->is_widget_selective_refreshable( $matches['id_base'] ) ? 'postMessage' : 'refresh';
</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">                $args = array_merge( $args, $overrides );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -893,7 +943,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                'multi_number' => ( $args['_add'] === 'multi' ) ? $args['_multi_num'] : false,
</span><span class="cx" style="display: block; padding: 0 10px">                                'is_disabled'  => $is_disabled,
</span><span class="cx" style="display: block; padding: 0 10px">                                'id_base'      => $id_base,
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'transport'    => isset( $this->manager->selective_refresh ) ? 'postMessage' : 'refresh',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'transport'    => $this->is_widget_selective_refreshable( $id_base ) ? 'postMessage' : 'refresh',
</ins><span class="cx" style="display: block; padding: 0 10px">                                 'width'        => $wp_registered_widget_controls[$widget['id']]['width'],
</span><span class="cx" style="display: block; padding: 0 10px">                                'height'       => $wp_registered_widget_controls[$widget['id']]['height'],
</span><span class="cx" style="display: block; padding: 0 10px">                                'is_wide'      => $this->is_wide_widget( $widget['id'] ),
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1025,6 +1075,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function customize_preview_enqueue() {
</span><span class="cx" style="display: block; padding: 0 10px">                wp_enqueue_script( 'customize-preview-widgets' );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                wp_enqueue_style( 'customize-preview' );
</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="lines" style="display: block; padding: 0 10px; color: #888">@@ -1060,6 +1111,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function export_preview_data() {
</span><span class="cx" style="display: block; padding: 0 10px">                global $wp_registered_sidebars, $wp_registered_widgets;
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
</ins><span class="cx" style="display: block; padding: 0 10px">                 // Prepare Customizer settings to pass to JavaScript.
</span><span class="cx" style="display: block; padding: 0 10px">                $settings = array(
</span><span class="cx" style="display: block; padding: 0 10px">                        'renderedSidebars'   => array_fill_keys( array_unique( $this->rendered_sidebars ), true ),
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1069,7 +1121,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        'l10n'               => array(
</span><span class="cx" style="display: block; padding: 0 10px">                                'widgetTooltip'  => __( 'Shift-click to edit this widget.' ),
</span><span class="cx" style="display: block; padding: 0 10px">                        ),
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        'selectiveRefresh'   => isset( $this->manager->selective_refresh ),
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 'selectiveRefreshableWidgets' => $this->get_selective_refreshable_widgets(),
</ins><span class="cx" style="display: block; padding: 0 10px">                 );
</span><span class="cx" style="display: block; padding: 0 10px">                foreach ( $settings['registeredWidgets'] as &$registered_widget ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        unset( $registered_widget['callback'] ); // may not be JSON-serializeable
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1479,6 +1531,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @return array (Maybe) modified partial arguments.
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function customize_dynamic_partial_args( $partial_args, $partial_id ) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                if ( ! current_theme_supports( 'customize-selective-refresh-widgets' ) ) {
+                       return $partial_args;
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                if ( preg_match( '/^widget\[(?P<widget_id>.+)\]$/', $partial_id, $matches ) ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        if ( false === $partial_args ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1506,11 +1561,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @access public
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function selective_refresh_init() {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                if ( ! isset( $this->manager->selective_refresh ) ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( ! current_theme_supports( 'customize-selective-refresh-widgets' ) ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                         return;
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-
-               add_action( 'wp_enqueue_scripts', array( $this, 'customize_preview_enqueue_deps' ) );
</del><span class="cx" style="display: block; padding: 0 10px">                 add_filter( 'dynamic_sidebar_params', array( $this, 'filter_dynamic_sidebar_params' ) );
</span><span class="cx" style="display: block; padding: 0 10px">                add_filter( 'wp_kses_allowed_html', array( $this, 'filter_wp_kses_allowed_data_attributes' ) );
</span><span class="cx" style="display: block; padding: 0 10px">                add_action( 'dynamic_sidebar_before', array( $this, 'start_dynamic_sidebar' ) );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1518,22 +1571,6 @@
</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">-         * Enqueues scripts for the Customizer preview.
-        *
-        * @since 4.5.0
-        * @access public
-        */
-       public function customize_preview_enqueue_deps() {
-               if ( isset( $this->manager->selective_refresh ) ) {
-                       $script = wp_scripts()->registered['customize-preview-widgets'];
-                       $script->deps[] = 'customize-selective-refresh';
-               }
-
-               wp_enqueue_script( 'customize-preview-widgets' );
-               wp_enqueue_style( 'customize-preview' );
-       }
-
-       /**
</del><span class="cx" style="display: block; padding: 0 10px">          * Inject selective refresh data attributes into widget container elements.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @param array $params {
</span></span></pre></div>
<a id="trunksrcwpincludesclasswpwidgetphp"></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-widget.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/class-wp-widget.php 2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-includes/class-wp-widget.php   2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -155,8 +155,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $this->id_base = empty($id_base) ? preg_replace( '/(wp_)?widget_/', '', strtolower(get_class($this)) ) : strtolower($id_base);
</span><span class="cx" style="display: block; padding: 0 10px">                $this->name = $name;
</span><span class="cx" style="display: block; padding: 0 10px">                $this->option_name = 'widget_' . $this->id_base;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $this->widget_options = wp_parse_args( $widget_options, array('classname' => $this->option_name) );
-               $this->control_options = wp_parse_args( $control_options, array('id_base' => $this->id_base) );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $this->widget_options = wp_parse_args( $widget_options, array( 'classname' => $this->option_name, 'customize_selective_refresh' => false ) );
+               $this->control_options = wp_parse_args( $control_options, array( 'id_base' => $this->id_base ) );
</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></pre></div>
<a id="trunksrcwpincludesjscustomizepreviewwidgetsjs"></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-widgets.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/js/customize-preview-widgets.js     2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-includes/js/customize-preview-widgets.js       2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -12,7 +12,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">                preview: null,
</span><span class="cx" style="display: block; padding: 0 10px">                l10n: {
</span><span class="cx" style="display: block; padding: 0 10px">                        widgetTooltip: ''
</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">+         },
+               selectiveRefreshableWidgets: {}
</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="lines" style="display: block; padding: 0 10px; color: #888">@@ -24,7 +25,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                var self = this;
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                self.preview = api.preview;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                if ( api.selectiveRefresh ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( ! _.isEmpty( self.selectiveRefreshableWidgets ) ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                         self.addPartials();
</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">@@ -38,457 +39,469 @@
</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">-        if ( api.selectiveRefresh ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+        * Partial representing a widget instance.
+        *
+        * @class
+        * @augments wp.customize.selectiveRefresh.Partial
+        * @since 4.5.0
+        */
+       self.WidgetPartial = api.selectiveRefresh.Partial.extend({
</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">-                 * Partial representing a widget instance.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+          * Constructor.
</ins><span class="cx" style="display: block; padding: 0 10px">                  *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                 * @class
-                * @augments wp.customize.selectiveRefresh.Partial
</del><span class="cx" style="display: block; padding: 0 10px">                  * @since 4.5.0
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 * @param {string} id - Partial ID.
+                * @param {Object} options
+                * @param {Object} options.params
</ins><span class="cx" style="display: block; padding: 0 10px">                  */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                self.WidgetPartial = api.selectiveRefresh.Partial.extend({
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         initialize: function( id, options ) {
+                       var partial = this, matches;
+                       matches = id.match( /^widget\[(.+)]$/ );
+                       if ( ! matches ) {
+                               throw new Error( 'Illegal id for widget partial.' );
+                       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        /**
-                        * Constructor.
-                        *
-                        * @since 4.5.0
-                        * @param {string} id - Partial ID.
-                        * @param {Object} options
-                        * @param {Object} options.params
-                        */
-                       initialize: function( id, options ) {
-                               var partial = this, matches;
-                               matches = id.match( /^widget\[(.+)]$/ );
-                               if ( ! matches ) {
-                                       throw new Error( 'Illegal id for widget partial.' );
-                               }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 partial.widgetId = matches[1];
+                       partial.widgetIdParts = self.parseWidgetId( partial.widgetId );
+                       options = options || {};
+                       options.params = _.extend(
+                               {
+                                       settings: [ self.getWidgetSettingId( partial.widgetId ) ],
+                                       containerInclusive: true
+                               },
+                               options.params || {}
+                       );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                partial.widgetId = matches[1];
-                               options = options || {};
-                               options.params = _.extend(
-                                       {
-                                               /* Note that a selector of ('#' + partial.widgetId) is faster, but jQuery will only return the one result. */
-                                               selector: '[id="' + partial.widgetId + '"]', // Alternatively, '[data-customize-widget-id="' + partial.widgetId + '"]'
-                                               settings: [ self.getWidgetSettingId( partial.widgetId ) ],
-                                               containerInclusive: true
-                                       },
-                                       options.params || {}
-                               );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 api.selectiveRefresh.Partial.prototype.initialize.call( partial, id, options );
+               },
</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.selectiveRefresh.Partial.prototype.initialize.call( partial, id, options );
-                       },
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         /**
+                * Refresh widget partial.
+                *
+                * @returns {Promise}
+                */
+               refresh: function() {
+                       var partial = this, refreshDeferred;
+                       if ( ! self.selectiveRefreshableWidgets[ partial.widgetIdParts.idBase ] ) {
+                               refreshDeferred = $.Deferred();
+                               refreshDeferred.reject();
+                               partial.fallback();
+                               return refreshDeferred.promise();
+                       } else {
+                               return api.selectiveRefresh.Partial.prototype.refresh.call( partial );
+                       }
+               },
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        /**
-                        * Send widget-updated message to parent so spinner will get removed from widget control.
-                        *
-                        * @inheritdoc
-                        * @param {wp.customize.selectiveRefresh.Placement} placement
-                        */
-                       renderContent: function( placement ) {
-                               var partial = this;
-                               if ( api.selectiveRefresh.Partial.prototype.renderContent.call( partial, placement ) ) {
-                                       api.preview.send( 'widget-updated', partial.widgetId );
-                                       api.selectiveRefresh.trigger( 'widget-updated', partial );
-                               }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         /**
+                * Send widget-updated message to parent so spinner will get removed from widget control.
+                *
+                * @inheritdoc
+                * @param {wp.customize.selectiveRefresh.Placement} placement
+                */
+               renderContent: function( placement ) {
+                       var partial = this;
+                       if ( api.selectiveRefresh.Partial.prototype.renderContent.call( partial, placement ) ) {
+                               api.preview.send( 'widget-updated', partial.widgetId );
+                               api.selectiveRefresh.trigger( 'widget-updated', partial );
</ins><span class="cx" style="display: block; padding: 0 10px">                         }
</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><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        /**
+        * Partial representing a widget area.
+        *
+        * @class
+        * @augments wp.customize.selectiveRefresh.Partial
+        * @since 4.5.0
+        */
+       self.SidebarPartial = api.selectiveRefresh.Partial.extend({
+
</ins><span class="cx" style="display: block; padding: 0 10px">                 /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                 * Partial representing a widget area.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+          * Constructor.
</ins><span class="cx" style="display: block; padding: 0 10px">                  *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                 * @class
-                * @augments wp.customize.selectiveRefresh.Partial
</del><span class="cx" style="display: block; padding: 0 10px">                  * @since 4.5.0
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 * @param {string} id - Partial ID.
+                * @param {Object} options
+                * @param {Object} options.params
</ins><span class="cx" style="display: block; padding: 0 10px">                  */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                self.SidebarPartial = api.selectiveRefresh.Partial.extend({
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         initialize: function( id, options ) {
+                       var partial = this, matches;
+                       matches = id.match( /^sidebar\[(.+)]$/ );
+                       if ( ! matches ) {
+                               throw new Error( 'Illegal id for sidebar partial.' );
+                       }
+                       partial.sidebarId = matches[1];
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        /**
-                        * Constructor.
-                        *
-                        * @since 4.5.0
-                        * @param {string} id - Partial ID.
-                        * @param {Object} options
-                        * @param {Object} options.params
-                        */
-                       initialize: function( id, options ) {
-                               var partial = this, matches;
-                               matches = id.match( /^sidebar\[(.+)]$/ );
-                               if ( ! matches ) {
-                                       throw new Error( 'Illegal id for sidebar partial.' );
-                               }
-                               partial.sidebarId = matches[1];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 options = options || {};
+                       options.params = _.extend(
+                               {
+                                       settings: [ 'sidebars_widgets[' + partial.sidebarId + ']' ]
+                               },
+                               options.params || {}
+                       );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                options = options || {};
-                               options.params = _.extend(
-                                       {
-                                               settings: [ 'sidebars_widgets[' + partial.sidebarId + ']' ]
-                                       },
-                                       options.params || {}
-                               );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 api.selectiveRefresh.Partial.prototype.initialize.call( partial, id, options );
</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.selectiveRefresh.Partial.prototype.initialize.call( partial, id, options );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 if ( ! partial.params.sidebarArgs ) {
+                               throw new Error( 'The sidebarArgs param was not provided.' );
+                       }
+                       if ( partial.params.settings.length > 1 ) {
+                               throw new Error( 'Expected SidebarPartial to only have one associated setting' );
+                       }
+               },
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                if ( ! partial.params.sidebarArgs ) {
-                                       throw new Error( 'The sidebarArgs param was not provided.' );
-                               }
-                               if ( partial.params.settings.length > 1 ) {
-                                       throw new Error( 'Expected SidebarPartial to only have one associated setting' );
-                               }
-                       },
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         /**
+                * Set up the partial.
+                *
+                * @since 4.5.0
+                */
+               ready: function() {
+                       var sidebarPartial = this;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        /**
-                        * Set up the partial.
-                        *
-                        * @since 4.5.0
-                        */
-                       ready: function() {
-                               var sidebarPartial = this;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 // Watch for changes to the sidebar_widgets setting.
+                       _.each( sidebarPartial.settings(), function( settingId ) {
+                               api( settingId ).bind( _.bind( sidebarPartial.handleSettingChange, sidebarPartial ) );
+                       } );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                // Watch for changes to the sidebar_widgets setting.
-                               _.each( sidebarPartial.settings(), function( settingId ) {
-                                       api( settingId ).bind( _.bind( sidebarPartial.handleSettingChange, sidebarPartial ) );
-                               } );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 // Trigger an event for this sidebar being updated whenever a widget inside is rendered.
+                       api.selectiveRefresh.bind( 'partial-content-rendered', function( placement ) {
+                               var isAssignedWidgetPartial = (
+                                       placement.partial.extended( self.WidgetPartial ) &&
+                                       ( -1 !== _.indexOf( sidebarPartial.getWidgetIds(), placement.partial.widgetId ) )
+                               );
+                               if ( isAssignedWidgetPartial ) {
+                                       api.selectiveRefresh.trigger( 'sidebar-updated', sidebarPartial );
+                               }
+                       } );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                // Trigger an event for this sidebar being updated whenever a widget inside is rendered.
-                               api.selectiveRefresh.bind( 'partial-content-rendered', function( placement ) {
-                                       var isAssignedWidgetPartial = (
-                                               placement.partial.extended( self.WidgetPartial ) &&
-                                               ( -1 !== _.indexOf( sidebarPartial.getWidgetIds(), placement.partial.widgetId ) )
-                                       );
-                                       if ( isAssignedWidgetPartial ) {
-                                               api.selectiveRefresh.trigger( 'sidebar-updated', sidebarPartial );
-                                       }
-                               } );
-
-                               // Make sure that a widget partial has a container in the DOM prior to a refresh.
-                               api.bind( 'change', function( widgetSetting ) {
-                                       var widgetId, parsedId;
-                                       parsedId = self.parseWidgetSettingId( widgetSetting.id );
-                                       if ( ! parsedId ) {
-                                               return;
-                                       }
-                                       widgetId = parsedId.idBase;
-                                       if ( parsedId.number ) {
-                                               widgetId += '-' + String( parsedId.number );
-                                       }
-                                       if ( -1 !== _.indexOf( sidebarPartial.getWidgetIds(), widgetId ) ) {
-                                               sidebarPartial.ensureWidgetPlacementContainers( widgetId );
-                                       }
-                               } );
-                       },
-
-                       /**
-                        * Get the before/after boundary nodes for all instances of this sidebar (usually one).
-                        *
-                        * Note that TreeWalker is not implemented in IE8.
-                        *
-                        * @since 4.5.0
-                        * @returns {Array.<{before: Comment, after: Comment, instanceNumber: number}>}
-                        */
-                       findDynamicSidebarBoundaryNodes: function() {
-                               var partial = this, regExp, boundaryNodes = {}, recursiveCommentTraversal;
-                               regExp = /^(dynamic_sidebar_before|dynamic_sidebar_after):(.+):(\d+)$/;
-                               recursiveCommentTraversal = function( childNodes ) {
-                                       _.each( childNodes, function( node ) {
-                                               var matches;
-                                               if ( 8 === node.nodeType ) {
-                                                       matches = node.nodeValue.match( regExp );
-                                                       if ( ! matches || matches[2] !== partial.sidebarId ) {
-                                                               return;
-                                                       }
-                                                       if ( _.isUndefined( boundaryNodes[ matches[3] ] ) ) {
-                                                               boundaryNodes[ matches[3] ] = {
-                                                                       before: null,
-                                                                       after: null,
-                                                                       instanceNumber: parseInt( matches[3], 10 )
-                                                               };
-                                                       }
-                                                       if ( 'dynamic_sidebar_before' === matches[1] ) {
-                                                               boundaryNodes[ matches[3] ].before = node;
-                                                       } else {
-                                                               boundaryNodes[ matches[3] ].after = node;
-                                                       }
-                                               } else if ( 1 === node.nodeType ) {
-                                                       recursiveCommentTraversal( node.childNodes );
-                                               }
-                                       } );
-                               };
-
-                               recursiveCommentTraversal( document.body.childNodes );
-                               return _.values( boundaryNodes );
-                       },
-
-                       /**
-                        * Get the placements for this partial.
-                        *
-                        * @since 4.5.0
-                        * @returns {Array}
-                        */
-                       placements: function() {
-                               var partial = this;
-                               return _.map( partial.findDynamicSidebarBoundaryNodes(), function( boundaryNodes ) {
-                                       return new api.selectiveRefresh.Placement( {
-                                               partial: partial,
-                                               container: null,
-                                               startNode: boundaryNodes.before,
-                                               endNode: boundaryNodes.after,
-                                               context: {
-                                                       instanceNumber: boundaryNodes.instanceNumber
-                                               }
-                                       } );
-                               } );
-                       },
-
-                       /**
-                        * Get the list of widget IDs associated with this widget area.
-                        *
-                        * @since 4.5.0
-                        *
-                        * @returns {Array}
-                        */
-                       getWidgetIds: function() {
-                               var sidebarPartial = this, settingId, widgetIds;
-                               settingId = sidebarPartial.settings()[0];
-                               if ( ! settingId ) {
-                                       throw new Error( 'Missing associated setting.' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 // Make sure that a widget partial has a container in the DOM prior to a refresh.
+                       api.bind( 'change', function( widgetSetting ) {
+                               var widgetId, parsedId;
+                               parsedId = self.parseWidgetSettingId( widgetSetting.id );
+                               if ( ! parsedId ) {
+                                       return;
</ins><span class="cx" style="display: block; padding: 0 10px">                                 }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                if ( ! api.has( settingId ) ) {
-                                       throw new Error( 'Setting does not exist.' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         widgetId = parsedId.idBase;
+                               if ( parsedId.number ) {
+                                       widgetId += '-' + String( parsedId.number );
</ins><span class="cx" style="display: block; padding: 0 10px">                                 }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                widgetIds = api( settingId ).get();
-                               if ( ! _.isArray( widgetIds ) ) {
-                                       throw new Error( 'Expected setting to be array of widget IDs' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         if ( -1 !== _.indexOf( sidebarPartial.getWidgetIds(), widgetId ) ) {
+                                       sidebarPartial.ensureWidgetPlacementContainers( widgetId );
</ins><span class="cx" style="display: block; padding: 0 10px">                                 }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                return widgetIds.slice( 0 );
-                       },
</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">-                        /**
-                        * Reflow widgets in the sidebar, ensuring they have the proper position in the DOM.
-                        *
-                        * @since 4.5.0
-                        *
-                        * @return {Array.<wp.customize.selectiveRefresh.Placement>} List of placements that were reflowed.
-                        */
-                       reflowWidgets: function() {
-                               var sidebarPartial = this, sidebarPlacements, widgetIds, widgetPartials, sortedSidebarContainers = [];
-                               widgetIds = sidebarPartial.getWidgetIds();
-                               sidebarPlacements = sidebarPartial.placements();
-
-                               widgetPartials = {};
-                               _.each( widgetIds, function( widgetId ) {
-                                       var widgetPartial = api.selectiveRefresh.partial( 'widget[' + widgetId + ']' );
-                                       if ( widgetPartial ) {
-                                               widgetPartials[ widgetId ] = widgetPartial;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         /**
+                * Get the before/after boundary nodes for all instances of this sidebar (usually one).
+                *
+                * Note that TreeWalker is not implemented in IE8.
+                *
+                * @since 4.5.0
+                * @returns {Array.<{before: Comment, after: Comment, instanceNumber: number}>}
+                */
+               findDynamicSidebarBoundaryNodes: function() {
+                       var partial = this, regExp, boundaryNodes = {}, recursiveCommentTraversal;
+                       regExp = /^(dynamic_sidebar_before|dynamic_sidebar_after):(.+):(\d+)$/;
+                       recursiveCommentTraversal = function( childNodes ) {
+                               _.each( childNodes, function( node ) {
+                                       var matches;
+                                       if ( 8 === node.nodeType ) {
+                                               matches = node.nodeValue.match( regExp );
+                                               if ( ! matches || matches[2] !== partial.sidebarId ) {
+                                                       return;
+                                               }
+                                               if ( _.isUndefined( boundaryNodes[ matches[3] ] ) ) {
+                                                       boundaryNodes[ matches[3] ] = {
+                                                               before: null,
+                                                               after: null,
+                                                               instanceNumber: parseInt( matches[3], 10 )
+                                                       };
+                                               }
+                                               if ( 'dynamic_sidebar_before' === matches[1] ) {
+                                                       boundaryNodes[ matches[3] ].before = node;
+                                               } else {
+                                                       boundaryNodes[ matches[3] ].after = node;
+                                               }
+                                       } else if ( 1 === node.nodeType ) {
+                                               recursiveCommentTraversal( node.childNodes );
</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"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                _.each( sidebarPlacements, function( sidebarPlacement ) {
-                                       var sidebarWidgets = [], needsSort = false, thisPosition, lastPosition = -1;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 recursiveCommentTraversal( document.body.childNodes );
+                       return _.values( boundaryNodes );
+               },
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        // Gather list of widget partial containers in this sidebar, and determine if a sort is needed.
-                                       _.each( widgetPartials, function( widgetPartial ) {
-                                               _.each( widgetPartial.placements(), function( widgetPlacement ) {
-
-                                                       if ( sidebarPlacement.context.instanceNumber === widgetPlacement.context.sidebar_instance_number ) {
-                                                               thisPosition = widgetPlacement.container.index();
-                                                               sidebarWidgets.push( {
-                                                                       partial: widgetPartial,
-                                                                       placement: widgetPlacement,
-                                                                       position: thisPosition
-                                                               } );
-                                                               if ( thisPosition < lastPosition ) {
-                                                                       needsSort = true;
-                                                               }
-                                                               lastPosition = thisPosition;
-                                                       }
-                                               } );
-                                       } );
-
-                                       if ( needsSort ) {
-                                               _.each( sidebarWidgets, function( sidebarWidget ) {
-                                                       sidebarPlacement.endNode.parentNode.insertBefore(
-                                                               sidebarWidget.placement.container[0],
-                                                               sidebarPlacement.endNode
-                                                       );
-
-                                                       // @todo Rename partial-placement-moved?
-                                                       api.selectiveRefresh.trigger( 'partial-content-moved', sidebarWidget.placement );
-                                               } );
-
-                                               sortedSidebarContainers.push( sidebarPlacement );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         /**
+                * Get the placements for this partial.
+                *
+                * @since 4.5.0
+                * @returns {Array}
+                */
+               placements: function() {
+                       var partial = this;
+                       return _.map( partial.findDynamicSidebarBoundaryNodes(), function( boundaryNodes ) {
+                               return new api.selectiveRefresh.Placement( {
+                                       partial: partial,
+                                       container: null,
+                                       startNode: boundaryNodes.before,
+                                       endNode: boundaryNodes.after,
+                                       context: {
+                                               instanceNumber: boundaryNodes.instanceNumber
</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"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                if ( sortedSidebarContainers.length > 0 ) {
-                                       api.selectiveRefresh.trigger( 'sidebar-updated', sidebarPartial );
-                               }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         /**
+                * Get the list of widget IDs associated with this widget area.
+                *
+                * @since 4.5.0
+                *
+                * @returns {Array}
+                */
+               getWidgetIds: function() {
+                       var sidebarPartial = this, settingId, widgetIds;
+                       settingId = sidebarPartial.settings()[0];
+                       if ( ! settingId ) {
+                               throw new Error( 'Missing associated setting.' );
+                       }
+                       if ( ! api.has( settingId ) ) {
+                               throw new Error( 'Setting does not exist.' );
+                       }
+                       widgetIds = api( settingId ).get();
+                       if ( ! _.isArray( widgetIds ) ) {
+                               throw new Error( 'Expected setting to be array of widget IDs' );
+                       }
+                       return widgetIds.slice( 0 );
+               },
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                return sortedSidebarContainers;
-                       },
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         /**
+                * Reflow widgets in the sidebar, ensuring they have the proper position in the DOM.
+                *
+                * @since 4.5.0
+                *
+                * @return {Array.<wp.customize.selectiveRefresh.Placement>} List of placements that were reflowed.
+                */
+               reflowWidgets: function() {
+                       var sidebarPartial = this, sidebarPlacements, widgetIds, widgetPartials, sortedSidebarContainers = [];
+                       widgetIds = sidebarPartial.getWidgetIds();
+                       sidebarPlacements = sidebarPartial.placements();
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        /**
-                        * Make sure there is a widget instance container in this sidebar for the given widget ID.
-                        *
-                        * @since 4.5.0
-                        *
-                        * @param {string} widgetId
-                        * @returns {wp.customize.selectiveRefresh.Partial} Widget instance partial.
-                        */
-                       ensureWidgetPlacementContainers: function( widgetId ) {
-                               var sidebarPartial = this, widgetPartial, wasInserted = false, partialId = 'widget[' + widgetId + ']';
-                               widgetPartial = api.selectiveRefresh.partial( partialId );
-                               if ( ! widgetPartial ) {
-                                       widgetPartial = new self.WidgetPartial( partialId, {
-                                               params: {}
-                                       } );
-                                       api.selectiveRefresh.partial.add( widgetPartial.id, widgetPartial );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 widgetPartials = {};
+                       _.each( widgetIds, function( widgetId ) {
+                               var widgetPartial = api.selectiveRefresh.partial( 'widget[' + widgetId + ']' );
+                               if ( widgetPartial ) {
+                                       widgetPartials[ widgetId ] = widgetPartial;
</ins><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"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                // Make sure that there is a container element for the widget in the sidebar, if at least a placeholder.
-                               _.each( sidebarPartial.placements(), function( sidebarPlacement ) {
-                                       var foundWidgetPlacement, widgetContainerElement;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 _.each( sidebarPlacements, function( sidebarPlacement ) {
+                               var sidebarWidgets = [], needsSort = false, thisPosition, lastPosition = -1;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        foundWidgetPlacement = _.find( widgetPartial.placements(), function( widgetPlacement ) {
-                                               return ( widgetPlacement.context.sidebar_instance_number === sidebarPlacement.context.instanceNumber );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         // Gather list of widget partial containers in this sidebar, and determine if a sort is needed.
+                               _.each( widgetPartials, function( widgetPartial ) {
+                                       _.each( widgetPartial.placements(), function( widgetPlacement ) {
+
+                                               if ( sidebarPlacement.context.instanceNumber === widgetPlacement.context.sidebar_instance_number ) {
+                                                       thisPosition = widgetPlacement.container.index();
+                                                       sidebarWidgets.push( {
+                                                               partial: widgetPartial,
+                                                               placement: widgetPlacement,
+                                                               position: thisPosition
+                                                       } );
+                                                       if ( thisPosition < lastPosition ) {
+                                                               needsSort = true;
+                                                       }
+                                                       lastPosition = thisPosition;
+                                               }
</ins><span class="cx" style="display: block; padding: 0 10px">                                         } );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        if ( foundWidgetPlacement ) {
-                                               return;
-                                       }
</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">-                                        widgetContainerElement = $(
-                                               sidebarPartial.params.sidebarArgs.before_widget.replace( '%1$s', widgetId ).replace( '%2$s', 'widget' ) +
-                                               sidebarPartial.params.sidebarArgs.after_widget
-                                       );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         if ( needsSort ) {
+                                       _.each( sidebarWidgets, function( sidebarWidget ) {
+                                               sidebarPlacement.endNode.parentNode.insertBefore(
+                                                       sidebarWidget.placement.container[0],
+                                                       sidebarPlacement.endNode
+                                               );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        widgetContainerElement.attr( 'data-customize-partial-id', widgetPartial.id );
-                                       widgetContainerElement.attr( 'data-customize-partial-type', 'widget' );
-                                       widgetContainerElement.attr( 'data-customize-widget-id', widgetId );
-
-                                       /*
-                                        * Make sure the widget container element has the customize-container context data.
-                                        * The sidebar_instance_number is used to disambiguate multiple instances of the
-                                        * same sidebar are rendered onto the template, and so the same widget is embedded
-                                        * multiple times.
-                                        */
-                                       widgetContainerElement.data( 'customize-partial-placement-context', {
-                                               'sidebar_id': sidebarPartial.sidebarId,
-                                               'sidebar_instance_number': sidebarPlacement.context.instanceNumber
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                         // @todo Rename partial-placement-moved?
+                                               api.selectiveRefresh.trigger( 'partial-content-moved', sidebarWidget.placement );
</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">-                                        sidebarPlacement.endNode.parentNode.insertBefore( widgetContainerElement[0], sidebarPlacement.endNode );
-                                       wasInserted = true;
-                               } );
-
-                               if ( wasInserted ) {
-                                       sidebarPartial.reflowWidgets();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 sortedSidebarContainers.push( sidebarPlacement );
</ins><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"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                return widgetPartial;
-                       },
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 if ( sortedSidebarContainers.length > 0 ) {
+                               api.selectiveRefresh.trigger( 'sidebar-updated', sidebarPartial );
+                       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        /**
-                        * Handle change to the sidebars_widgets[] setting.
-                        *
-                        * @since 4.5.0
-                        *
-                        * @param {Array} newWidgetIds New widget ids.
-                        * @param {Array} oldWidgetIds Old widget ids.
-                        */
-                       handleSettingChange: function( newWidgetIds, oldWidgetIds ) {
-                               var sidebarPartial = this, needsRefresh, widgetsRemoved, widgetsAdded, addedWidgetPartials = [];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 return sortedSidebarContainers;
+               },
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                needsRefresh = (
-                                       ( oldWidgetIds.length > 0 && 0 === newWidgetIds.length ) ||
-                                       ( newWidgetIds.length > 0 && 0 === oldWidgetIds.length )
-                               );
-                               if ( needsRefresh ) {
-                                       sidebarPartial.fallback();
-                                       return;
-                               }
-
-                               // Handle removal of widgets.
-                               widgetsRemoved = _.difference( oldWidgetIds, newWidgetIds );
-                               _.each( widgetsRemoved, function( removedWidgetId ) {
-                                       var widgetPartial = api.selectiveRefresh.partial( 'widget[' + removedWidgetId + ']' );
-                                       if ( widgetPartial ) {
-                                               _.each( widgetPartial.placements(), function( placement ) {
-                                                       var isRemoved = (
-                                                               placement.context.sidebar_id === sidebarPartial.sidebarId ||
-                                                               ( placement.context.sidebar_args && placement.context.sidebar_args.id === sidebarPartial.sidebarId )
-                                                       );
-                                                       if ( isRemoved ) {
-                                                               placement.container.remove();
-                                                       }
-                                               } );
-                                       }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         /**
+                * Make sure there is a widget instance container in this sidebar for the given widget ID.
+                *
+                * @since 4.5.0
+                *
+                * @param {string} widgetId
+                * @returns {wp.customize.selectiveRefresh.Partial} Widget instance partial.
+                */
+               ensureWidgetPlacementContainers: function( widgetId ) {
+                       var sidebarPartial = this, widgetPartial, wasInserted = false, partialId = 'widget[' + widgetId + ']';
+                       widgetPartial = api.selectiveRefresh.partial( partialId );
+                       if ( ! widgetPartial ) {
+                               widgetPartial = new self.WidgetPartial( partialId, {
+                                       params: {}
</ins><span class="cx" style="display: block; padding: 0 10px">                                 } );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                api.selectiveRefresh.partial.add( widgetPartial.id, widgetPartial );
+                       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                // Handle insertion of widgets.
-                               widgetsAdded = _.difference( newWidgetIds, oldWidgetIds );
-                               _.each( widgetsAdded, function( addedWidgetId ) {
-                                       var widgetPartial = sidebarPartial.ensureWidgetPlacementContainers( addedWidgetId );
-                                       addedWidgetPartials.push( widgetPartial );
-                               } );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 // Make sure that there is a container element for the widget in the sidebar, if at least a placeholder.
+                       _.each( sidebarPartial.placements(), function( sidebarPlacement ) {
+                               var foundWidgetPlacement, widgetContainerElement;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                _.each( addedWidgetPartials, function( widgetPartial ) {
-                                       widgetPartial.refresh();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         foundWidgetPlacement = _.find( widgetPartial.placements(), function( widgetPlacement ) {
+                                       return ( widgetPlacement.context.sidebar_instance_number === sidebarPlacement.context.instanceNumber );
</ins><span class="cx" style="display: block; padding: 0 10px">                                 } );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                if ( foundWidgetPlacement ) {
+                                       return;
+                               }
</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.selectiveRefresh.trigger( 'sidebar-updated', sidebarPartial );
-                       },
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         widgetContainerElement = $(
+                                       sidebarPartial.params.sidebarArgs.before_widget.replace( '%1$s', widgetId ).replace( '%2$s', 'widget' ) +
+                                       sidebarPartial.params.sidebarArgs.after_widget
+                               );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        /**
-                        * Note that the meat is handled in handleSettingChange because it has the context of which widgets were removed.
-                        *
-                        * @since 4.5.0
-                        */
-                       refresh: function() {
-                               var partial = this, deferred = $.Deferred();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         widgetContainerElement.attr( 'data-customize-partial-id', widgetPartial.id );
+                               widgetContainerElement.attr( 'data-customize-partial-type', 'widget' );
+                               widgetContainerElement.attr( 'data-customize-widget-id', widgetId );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                deferred.fail( function() {
-                                       partial.fallback();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         /*
+                                * Make sure the widget container element has the customize-container context data.
+                                * The sidebar_instance_number is used to disambiguate multiple instances of the
+                                * same sidebar are rendered onto the template, and so the same widget is embedded
+                                * multiple times.
+                                */
+                               widgetContainerElement.data( 'customize-partial-placement-context', {
+                                       'sidebar_id': sidebarPartial.sidebarId,
+                                       'sidebar_instance_number': sidebarPlacement.context.instanceNumber
</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 ( 0 === partial.placements().length ) {
-                                       deferred.reject();
-                               } else {
-                                       _.each( partial.reflowWidgets(), function( sidebarPlacement ) {
-                                               api.selectiveRefresh.trigger( 'partial-content-rendered', sidebarPlacement );
-                                       } );
-                                       deferred.resolve();
-                               }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         sidebarPlacement.endNode.parentNode.insertBefore( widgetContainerElement[0], sidebarPlacement.endNode );
+                               wasInserted = true;
+                       } );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                return deferred.promise();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 if ( wasInserted ) {
+                               sidebarPartial.reflowWidgets();
</ins><span class="cx" style="display: block; padding: 0 10px">                         }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                });
</del><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                api.selectiveRefresh.partialConstructor.sidebar = self.SidebarPartial;
-               api.selectiveRefresh.partialConstructor.widget = self.WidgetPartial;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 return widgetPartial;
+               },
</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">-                 * Add partials for the registered widget areas (sidebars).
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+          * Handle change to the sidebars_widgets[] setting.
</ins><span class="cx" style="display: block; padding: 0 10px">                  *
</span><span class="cx" style="display: block; padding: 0 10px">                 * @since 4.5.0
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 *
+                * @param {Array} newWidgetIds New widget ids.
+                * @param {Array} oldWidgetIds Old widget ids.
</ins><span class="cx" style="display: block; padding: 0 10px">                  */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                self.addPartials = function() {
-                       _.each( self.registeredSidebars, function( registeredSidebar ) {
-                               var partial, partialId = 'sidebar[' + registeredSidebar.id + ']';
-                               partial = api.selectiveRefresh.partial( partialId );
-                               if ( ! partial ) {
-                                       partial = new self.SidebarPartial( partialId, {
-                                               params: {
-                                                       sidebarArgs: registeredSidebar
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         handleSettingChange: function( newWidgetIds, oldWidgetIds ) {
+                       var sidebarPartial = this, needsRefresh, widgetsRemoved, widgetsAdded, addedWidgetPartials = [];
+
+                       needsRefresh = (
+                               ( oldWidgetIds.length > 0 && 0 === newWidgetIds.length ) ||
+                               ( newWidgetIds.length > 0 && 0 === oldWidgetIds.length )
+                       );
+                       if ( needsRefresh ) {
+                               sidebarPartial.fallback();
+                               return;
+                       }
+
+                       // Handle removal of widgets.
+                       widgetsRemoved = _.difference( oldWidgetIds, newWidgetIds );
+                       _.each( widgetsRemoved, function( removedWidgetId ) {
+                               var widgetPartial = api.selectiveRefresh.partial( 'widget[' + removedWidgetId + ']' );
+                               if ( widgetPartial ) {
+                                       _.each( widgetPartial.placements(), function( placement ) {
+                                               var isRemoved = (
+                                                       placement.context.sidebar_id === sidebarPartial.sidebarId ||
+                                                       ( placement.context.sidebar_args && placement.context.sidebar_args.id === sidebarPartial.sidebarId )
+                                               );
+                                               if ( isRemoved ) {
+                                                       placement.container.remove();
</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">-                                        api.selectiveRefresh.partial.add( partial.id, partial );
</del><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">-                };
</del><span class="cx" style="display: block; padding: 0 10px"> 
</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">+                 // Handle insertion of widgets.
+                       widgetsAdded = _.difference( newWidgetIds, oldWidgetIds );
+                       _.each( widgetsAdded, function( addedWidgetId ) {
+                               var widgetPartial = sidebarPartial.ensureWidgetPlacementContainers( addedWidgetId );
+                               addedWidgetPartials.push( widgetPartial );
+                       } );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        _.each( addedWidgetPartials, function( widgetPartial ) {
+                               widgetPartial.refresh();
+                       } );
+
+                       api.selectiveRefresh.trigger( 'sidebar-updated', sidebarPartial );
+               },
+
+               /**
+                * Note that the meat is handled in handleSettingChange because it has the context of which widgets were removed.
+                *
+                * @since 4.5.0
+                */
+               refresh: function() {
+                       var partial = this, deferred = $.Deferred();
+
+                       deferred.fail( function() {
+                               partial.fallback();
+                       } );
+
+                       if ( 0 === partial.placements().length ) {
+                               deferred.reject();
+                       } else {
+                               _.each( partial.reflowWidgets(), function( sidebarPlacement ) {
+                                       api.selectiveRefresh.trigger( 'partial-content-rendered', sidebarPlacement );
+                               } );
+                               deferred.resolve();
+                       }
+
+                       return deferred.promise();
+               }
+       });
+
+       api.selectiveRefresh.partialConstructor.sidebar = self.SidebarPartial;
+       api.selectiveRefresh.partialConstructor.widget = self.WidgetPartial;
+
</ins><span class="cx" style="display: block; padding: 0 10px">         /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * Add partials for the registered widget areas (sidebars).
+        *
+        * @since 4.5.0
+        */
+       self.addPartials = function() {
+               _.each( self.registeredSidebars, function( registeredSidebar ) {
+                       var partial, partialId = 'sidebar[' + registeredSidebar.id + ']';
+                       partial = api.selectiveRefresh.partial( partialId );
+                       if ( ! partial ) {
+                               partial = new self.SidebarPartial( partialId, {
+                                       params: {
+                                               sidebarArgs: registeredSidebar
+                                       }
+                               } );
+                               api.selectiveRefresh.partial.add( partial.id, partial );
+                       }
+               } );
+       };
+
+       /**
</ins><span class="cx" style="display: block; padding: 0 10px">          * Calculate the selector for the sidebar's widgets based on the registered sidebar's info.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @since 3.9.0
</span></span></pre></div>
<a id="trunksrcwpincludesjscustomizeselectiverefreshjs"></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-selective-refresh.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/js/customize-selective-refresh.js   2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-includes/js/customize-selective-refresh.js     2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -109,7 +109,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                placements: function() {
</span><span class="cx" style="display: block; padding: 0 10px">                        var partial = this, selector;
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        selector = partial.params.selector;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 selector = partial.params.selector || '';
</ins><span class="cx" style="display: block; padding: 0 10px">                         if ( selector ) {
</span><span class="cx" style="display: block; padding: 0 10px">                                selector += ', ';
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span></span></pre></div>
<a id="trunksrcwpincludesscriptloaderphp"></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/script-loader.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/script-loader.php   2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-includes/script-loader.php     2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -455,10 +455,10 @@
</span><span class="cx" style="display: block; padding: 0 10px">        $scripts->add( 'customize-selective-refresh', "/wp-includes/js/customize-selective-refresh$suffix.js", array( 'jquery', 'wp-util', 'customize-preview' ), false, 1 );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        $scripts->add( 'customize-widgets', "/wp-admin/js/customize-widgets$suffix.js", array( 'jquery', 'jquery-ui-sortable', 'jquery-ui-droppable', 'wp-backbone', 'customize-controls' ), false, 1 );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        $scripts->add( 'customize-preview-widgets', "/wp-includes/js/customize-preview-widgets$suffix.js", array( 'jquery', 'wp-util', 'customize-preview' ), false, 1 );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $scripts->add( 'customize-preview-widgets', "/wp-includes/js/customize-preview-widgets$suffix.js", array( 'jquery', 'wp-util', 'customize-preview', 'customize-selective-refresh' ), false, 1 );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        $scripts->add( 'customize-nav-menus', "/wp-admin/js/customize-nav-menus$suffix.js", array( 'jquery', 'wp-backbone', 'customize-controls', 'accordion', 'nav-menu' ), false, 1 );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        $scripts->add( 'customize-preview-nav-menus', "/wp-includes/js/customize-preview-nav-menus$suffix.js", array( 'jquery', 'wp-util', 'customize-preview' ), false, 1 );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $scripts->add( 'customize-preview-nav-menus', "/wp-includes/js/customize-preview-nav-menus$suffix.js", array( 'jquery', 'wp-util', 'customize-preview', 'customize-selective-refresh' ), false, 1 );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        $scripts->add( 'accordion', "/wp-admin/js/accordion$suffix.js", array( 'jquery' ), false, 1 );
</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-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-includes/theme.php     2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1914,7 +1914,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * The dynamic portion of the hook name, `$feature`, refers to the specific theme
</span><span class="cx" style="display: block; padding: 0 10px">         * feature. Possible values include 'post-formats', 'post-thumbnails', 'custom-background',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * 'custom-header', 'menus', 'automatic-feed-links', and 'html5'.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * 'custom-header', 'menus', 'automatic-feed-links', 'html5', and `customize-selective-refresh-widgets`.
</ins><span class="cx" style="display: block; padding: 0 10px">          *
</span><span class="cx" style="display: block; padding: 0 10px">         * @since 3.4.0
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span></span></pre></div>
<a id="trunksrcwpincludeswidgetsclasswpnavmenuwidgetphp"></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/widgets/class-wp-nav-menu-widget.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/widgets/class-wp-nav-menu-widget.php        2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-includes/widgets/class-wp-nav-menu-widget.php  2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -23,7 +23,10 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @access public
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function __construct() {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $widget_ops = array( 'description' => __('Add a custom menu to your sidebar.') );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $widget_ops = array(
+                       'description' => __( 'Add a custom menu to your sidebar.' ),
+                       'customize_selective_refresh' => true,
+               );
</ins><span class="cx" style="display: block; padding: 0 10px">                 parent::__construct( 'nav_menu', __('Custom Menu'), $widget_ops );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span></span></pre></div>
<a id="trunksrcwpincludeswidgetsclasswpwidgetarchivesphp"></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/widgets/class-wp-widget-archives.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/widgets/class-wp-widget-archives.php        2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-includes/widgets/class-wp-widget-archives.php  2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -23,7 +23,11 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @access public
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function __construct() {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $widget_ops = array('classname' => 'widget_archive', 'description' => __( 'A monthly archive of your site&#8217;s Posts.') );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $widget_ops = array(
+                       'classname' => 'widget_archive',
+                       'description' => __( 'A monthly archive of your site&#8217;s Posts.' ),
+                       'customize_selective_refresh' => true,
+               );
</ins><span class="cx" style="display: block; padding: 0 10px">                 parent::__construct('archives', __('Archives'), $widget_ops);
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span></span></pre></div>
<a id="trunksrcwpincludeswidgetsclasswpwidgetcalendarphp"></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/widgets/class-wp-widget-calendar.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/widgets/class-wp-widget-calendar.php        2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-includes/widgets/class-wp-widget-calendar.php  2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -33,8 +33,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @access public
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function __construct() {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $widget_ops = array('classname' => 'widget_calendar', 'description' => __( 'A calendar of your site&#8217;s Posts.') );
-               parent::__construct('calendar', __('Calendar'), $widget_ops);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $widget_ops = array(
+                       'classname' => 'widget_calendar',
+                       'description' => __( 'A calendar of your site&#8217;s Posts.' ),
+                       'customize_selective_refresh' => true,
+               );
+               parent::__construct( 'calendar', __( 'Calendar' ), $widget_ops );
</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></pre></div>
<a id="trunksrcwpincludeswidgetsclasswpwidgetcategoriesphp"></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/widgets/class-wp-widget-categories.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/widgets/class-wp-widget-categories.php      2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-includes/widgets/class-wp-widget-categories.php        2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -23,8 +23,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @access public
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function __construct() {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $widget_ops = array( 'classname' => 'widget_categories', 'description' => __( "A list or dropdown of categories." ) );
-               parent::__construct('categories', __('Categories'), $widget_ops);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $widget_ops = array(
+                       'classname' => 'widget_categories',
+                       'description' => __( 'A list or dropdown of categories.' ),
+                       'customize_selective_refresh' => true,
+               );
+               parent::__construct( 'categories', __( 'Categories' ), $widget_ops );
</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></pre></div>
<a id="trunksrcwpincludeswidgetsclasswpwidgetlinksphp"></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/widgets/class-wp-widget-links.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/widgets/class-wp-widget-links.php   2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-includes/widgets/class-wp-widget-links.php     2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -23,8 +23,11 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @access public
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function __construct() {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $widget_ops = array('description' => __( "Your blogroll" ) );
-               parent::__construct('links', __('Links'), $widget_ops);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $widget_ops = array(
+                       'description' => __( 'Your blogroll' ),
+                       'customize_selective_refresh' => true,
+               );
+               parent::__construct( 'links', __( 'Links' ), $widget_ops );
</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></pre></div>
<a id="trunksrcwpincludeswidgetsclasswpwidgetmetaphp"></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/widgets/class-wp-widget-meta.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/widgets/class-wp-widget-meta.php    2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-includes/widgets/class-wp-widget-meta.php      2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -25,8 +25,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @access public
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function __construct() {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $widget_ops = array('classname' => 'widget_meta', 'description' => __( "Login, RSS, &amp; WordPress.org links.") );
-               parent::__construct('meta', __('Meta'), $widget_ops);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $widget_ops = array(
+                       'classname' => 'widget_meta',
+                       'description' => __( 'Login, RSS, &amp; WordPress.org links.' ),
+                       'customize_selective_refresh' => true,
+               );
+               parent::__construct( 'meta', __( 'Meta' ), $widget_ops );
</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></pre></div>
<a id="trunksrcwpincludeswidgetsclasswpwidgetpagesphp"></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/widgets/class-wp-widget-pages.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/widgets/class-wp-widget-pages.php   2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-includes/widgets/class-wp-widget-pages.php     2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -23,8 +23,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @access public
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function __construct() {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $widget_ops = array('classname' => 'widget_pages', 'description' => __( 'A list of your site&#8217;s Pages.') );
-               parent::__construct('pages', __('Pages'), $widget_ops);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $widget_ops = array(
+                       'classname' => 'widget_pages',
+                       'description' => __( 'A list of your site&#8217;s Pages.' ),
+                       'customize_selective_refresh' => true,
+               );
+               parent::__construct( 'pages', __( 'Pages' ), $widget_ops );
</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></pre></div>
<a id="trunksrcwpincludeswidgetsclasswpwidgetrecentcommentsphp"></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/widgets/class-wp-widget-recent-comments.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/widgets/class-wp-widget-recent-comments.php 2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-includes/widgets/class-wp-widget-recent-comments.php   2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -23,12 +23,17 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @access public
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function __construct() {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $widget_ops = array('classname' => 'widget_recent_comments', 'description' => __( 'Your site&#8217;s most recent comments.' ) );
-               parent::__construct('recent-comments', __('Recent Comments'), $widget_ops);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $widget_ops = array(
+                       'classname' => 'widget_recent_comments',
+                       'description' => __( 'Your site&#8217;s most recent comments.' ),
+                       'customize_selective_refresh' => true,
+               );
+               parent::__construct( 'recent-comments', __( 'Recent Comments' ), $widget_ops );
</ins><span class="cx" style="display: block; padding: 0 10px">                 $this->alt_option_name = 'widget_recent_comments';
</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 ( is_active_widget(false, false, $this->id_base) )
-                       add_action( 'wp_head', array($this, 'recent_comments_style') );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( is_active_widget( false, false, $this->id_base ) || is_customize_preview() ) {
+                       add_action( 'wp_head', array( $this, 'recent_comments_style' ) );
+               }
</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></pre></div>
<a id="trunksrcwpincludeswidgetsclasswpwidgetrecentpostsphp"></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/widgets/class-wp-widget-recent-posts.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/widgets/class-wp-widget-recent-posts.php    2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-includes/widgets/class-wp-widget-recent-posts.php      2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -23,8 +23,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @access public
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function __construct() {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $widget_ops = array('classname' => 'widget_recent_entries', 'description' => __( "Your site&#8217;s most recent Posts.") );
-               parent::__construct('recent-posts', __('Recent Posts'), $widget_ops);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $widget_ops = array(
+                       'classname' => 'widget_recent_entries',
+                       'description' => __( 'Your site&#8217;s most recent Posts.' ),
+                       'customize_selective_refresh' => true,
+               );
+               parent::__construct( 'recent-posts', __( 'Recent Posts' ), $widget_ops );
</ins><span class="cx" style="display: block; padding: 0 10px">                 $this->alt_option_name = 'widget_recent_entries';
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span></span></pre></div>
<a id="trunksrcwpincludeswidgetsclasswpwidgetrssphp"></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/widgets/class-wp-widget-rss.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/widgets/class-wp-widget-rss.php     2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-includes/widgets/class-wp-widget-rss.php       2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -23,9 +23,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @access public
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function __construct() {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $widget_ops = array( 'description' => __('Entries from any RSS or Atom feed.') );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $widget_ops = array(
+                       'description' => __( 'Entries from any RSS or Atom feed.' ),
+                       'customize_selective_refresh' => true,
+               );
</ins><span class="cx" style="display: block; padding: 0 10px">                 $control_ops = array( 'width' => 400, 'height' => 200 );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                parent::__construct( 'rss', __('RSS'), $widget_ops, $control_ops );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         parent::__construct( 'rss', __( 'RSS' ), $widget_ops, $control_ops );
</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></pre></div>
<a id="trunksrcwpincludeswidgetsclasswpwidgetsearchphp"></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/widgets/class-wp-widget-search.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/widgets/class-wp-widget-search.php  2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-includes/widgets/class-wp-widget-search.php    2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -23,7 +23,11 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @access public
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function __construct() {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $widget_ops = array('classname' => 'widget_search', 'description' => __( "A search form for your site.") );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $widget_ops = array(
+                       'classname' => 'widget_search',
+                       'description' => __( 'A search form for your site.' ),
+                       'customize_selective_refresh' => true,
+               );
</ins><span class="cx" style="display: block; padding: 0 10px">                 parent::__construct( 'search', _x( 'Search', 'Search widget' ), $widget_ops );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span></span></pre></div>
<a id="trunksrcwpincludeswidgetsclasswpwidgettagcloudphp"></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/widgets/class-wp-widget-tag-cloud.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/widgets/class-wp-widget-tag-cloud.php       2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-includes/widgets/class-wp-widget-tag-cloud.php 2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -23,8 +23,11 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @access public
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function __construct() {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $widget_ops = array( 'description' => __( "A cloud of your most used tags.") );
-               parent::__construct('tag_cloud', __('Tag Cloud'), $widget_ops);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $widget_ops = array(
+                       'description' => __( 'A cloud of your most used tags.' ),
+                       'customize_selective_refresh' => true,
+               );
+               parent::__construct( 'tag_cloud', __( 'Tag Cloud' ), $widget_ops );
</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></pre></div>
<a id="trunksrcwpincludeswidgetsclasswpwidgettextphp"></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/widgets/class-wp-widget-text.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/widgets/class-wp-widget-text.php    2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/src/wp-includes/widgets/class-wp-widget-text.php      2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -23,9 +23,13 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @access public
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function __construct() {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $widget_ops = array('classname' => 'widget_text', 'description' => __('Arbitrary text or HTML.'));
-               $control_ops = array('width' => 400, 'height' => 350);
-               parent::__construct('text', __('Text'), $widget_ops, $control_ops);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $widget_ops = array(
+                       'classname' => 'widget_text',
+                       'description' => __( 'Arbitrary text or HTML.' ),
+                       'customize_selective_refresh' => true,
+               );
+               $control_ops = array( 'width' => 400, 'height' => 350 );
+               parent::__construct( 'text', __( 'Text' ), $widget_ops, $control_ops );
</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></pre></div>
<a id="trunktestsphpunittestscustomizemanagerphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/tests/customize/manager.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/customize/manager.php   2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/tests/phpunit/tests/customize/manager.php     2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -425,7 +425,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $data = json_decode( $json, true );
</span><span class="cx" style="display: block; padding: 0 10px">                $this->assertNotEmpty( $data );
</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->assertEqualSets( array( 'theme', 'url', 'browser', 'panels', 'sections', 'nonce', 'autofocus', 'documentTitleTmpl', 'previewableDevices', 'selectiveRefreshEnabled' ), array_keys( $data ) );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $this->assertEqualSets( array( 'theme', 'url', 'browser', 'panels', 'sections', 'nonce', 'autofocus', 'documentTitleTmpl', 'previewableDevices' ), array_keys( $data ) );
</ins><span class="cx" style="display: block; padding: 0 10px">                 $this->assertEquals( $autofocus, $data['autofocus'] );
</span><span class="cx" style="display: block; padding: 0 10px">                $this->assertArrayHasKey( 'save', $data['nonce'] );
</span><span class="cx" style="display: block; padding: 0 10px">                $this->assertArrayHasKey( 'preview', $data['nonce'] );
</span></span></pre></div>
<a id="trunktestsphpunittestscustomizewidgetsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/tests/customize/widgets.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/customize/widgets.php   2016-03-21 00:57:45 UTC (rev 37039)
+++ trunk/tests/phpunit/tests/customize/widgets.php     2016-03-21 21:58:02 UTC (rev 37040)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -24,6 +24,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                parent::setUp();
</span><span class="cx" style="display: block; padding: 0 10px">                require_once( ABSPATH . WPINC . '/class-wp-customize-manager.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">+                add_theme_support( 'customize-selective-refresh-widgets' );
</ins><span class="cx" style="display: block; padding: 0 10px">                 $user_id = self::factory()->user->create( array( 'role' => 'administrator' ) );
</span><span class="cx" style="display: block; padding: 0 10px">                wp_set_current_user( $user_id );
</span><span class="cx" style="display: block; padding: 0 10px">                $GLOBALS['wp_customize'] = new WP_Customize_Manager();
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -47,6 +48,18 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $this->backup_registered_sidebars = $GLOBALS['wp_registered_sidebars'];
</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">+        function clean_up_global_scope() {
+               global $wp_widget_factory, $wp_registered_sidebars, $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_widget_updates;
+
+               $wp_registered_sidebars = array();
+               $wp_registered_widgets = array();
+               $wp_registered_widget_controls = array();
+               $wp_registered_widget_updates = array();
+               $wp_widget_factory->widgets = array();
+
+               parent::clean_up_global_scope();
+       }
+
</ins><span class="cx" style="display: block; padding: 0 10px">         function tearDown() {
</span><span class="cx" style="display: block; padding: 0 10px">                $this->manager = null;
</span><span class="cx" style="display: block; padding: 0 10px">                unset( $GLOBALS['wp_customize'] );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -78,6 +91,65 @@
</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">+         * Tests WP_Customize_Widgets::get_selective_refreshable_widgets().
+        *
+        * @see WP_Customize_Widgets::get_selective_refreshable_widgets()
+        */
+       function test_get_selective_refreshable_widgets_when_theme_supports() {
+               global $wp_widget_factory;
+               add_action( 'widgets_init', array( $this, 'override_search_widget_customize_selective_refresh' ), 90 );
+               add_theme_support( 'customize-selective-refresh-widgets' );
+               $this->do_customize_boot_actions();
+
+               $selective_refreshable_widgets = $this->manager->widgets->get_selective_refreshable_widgets();
+               $this->assertInternalType( 'array', $selective_refreshable_widgets );
+               $this->assertEquals( count( $wp_widget_factory->widgets ), count( $selective_refreshable_widgets ) );
+               $this->assertArrayHasKey( 'text', $selective_refreshable_widgets );
+               $this->assertTrue( $selective_refreshable_widgets['text'] );
+               $this->assertArrayHasKey( 'search', $selective_refreshable_widgets );
+               $this->assertFalse( $selective_refreshable_widgets['search'] );
+       }
+
+       /**
+        * Tests WP_Customize_Widgets::get_selective_refreshable_widgets().
+        *
+        * @see WP_Customize_Widgets::get_selective_refreshable_widgets()
+        */
+       function test_get_selective_refreshable_widgets_when_no_theme_supports() {
+               add_action( 'widgets_init', array( $this, 'override_search_widget_customize_selective_refresh' ), 90 );
+               remove_theme_support( 'customize-selective-refresh-widgets' );
+               $this->do_customize_boot_actions();
+               $selective_refreshable_widgets = $this->manager->widgets->get_selective_refreshable_widgets();
+               $this->assertEmpty( $selective_refreshable_widgets );
+       }
+
+       /**
+        * Hook into widgets_init to override the search widget's customize_selective_refresh widget option.
+        *
+        * @see Tests_WP_Customize_Widgets::test_get_selective_refreshable_widgets_when_theme_supports()
+        * @see Tests_WP_Customize_Widgets::test_get_selective_refreshable_widgets_when_no_theme_supports()
+        */
+       function override_search_widget_customize_selective_refresh() {
+               global $wp_widget_factory;
+               $wp_widget_factory->widgets['WP_Widget_Search']->widget_options['customize_selective_refresh'] = false;
+       }
+
+       /**
+        * Tests WP_Customize_Widgets::is_widget_selective_refreshable().
+        *
+        * @see WP_Customize_Widgets::is_widget_selective_refreshable()
+        */
+       function test_is_widget_selective_refreshable() {
+               add_action( 'widgets_init', array( $this, 'override_search_widget_customize_selective_refresh' ), 90 );
+               add_theme_support( 'customize-selective-refresh-widgets' );
+               $this->do_customize_boot_actions();
+               $this->assertFalse( $this->manager->widgets->is_widget_selective_refreshable( 'search' ) );
+               $this->assertTrue( $this->manager->widgets->is_widget_selective_refreshable( 'text' ) );
+               remove_theme_support( 'customize-selective-refresh-widgets' );
+               $this->assertFalse( $this->manager->widgets->is_widget_selective_refreshable( 'text' ) );
+       }
+
+       /**
</ins><span class="cx" style="display: block; padding: 0 10px">          * Test WP_Customize_Widgets::register_settings()
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @ticket 30988
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -116,24 +188,43 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * Test WP_Customize_Widgets::get_setting_args()
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        function test_get_setting_args() {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                add_theme_support( 'customize-selective-refresh-widgets' );
+               $this->do_customize_boot_actions();
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                add_filter( 'widget_customizer_setting_args', array( $this, 'filter_widget_customizer_setting_args' ), 10, 2 );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $default_args = array(
</span><span class="cx" style="display: block; padding: 0 10px">                        'type' => 'option',
</span><span class="cx" style="display: block; padding: 0 10px">                        'capability' => 'edit_theme_options',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        'transport' => 'postMessage',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 'transport' => 'refresh',
</ins><span class="cx" style="display: block; padding: 0 10px">                         'default' => array(),
</span><span class="cx" style="display: block; padding: 0 10px">                        'sanitize_callback' => array( $this->manager->widgets, 'sanitize_widget_instance' ),
</span><span class="cx" style="display: block; padding: 0 10px">                        'sanitize_js_callback' => array( $this->manager->widgets, 'sanitize_widget_js_instance' ),
</span><span class="cx" style="display: block; padding: 0 10px">                );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-
</del><span class="cx" style="display: block; padding: 0 10px">                 $args = $this->manager->widgets->get_setting_args( 'widget_foo[2]' );
</span><span class="cx" style="display: block; padding: 0 10px">                foreach ( $default_args as $key => $default_value ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        $this->assertEquals( $default_value, $args[ $key ] );
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px">                $this->assertEquals( 'WIDGET_FOO[2]', $args['uppercase_id_set_by_filter'] );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                $default_args = array(
+                       'type' => 'option',
+                       'capability' => 'edit_theme_options',
+                       'transport' => 'postMessage',
+                       'default' => array(),
+                       'sanitize_callback' => array( $this->manager->widgets, 'sanitize_widget_instance' ),
+                       'sanitize_js_callback' => array( $this->manager->widgets, 'sanitize_widget_js_instance' ),
+               );
+               $args = $this->manager->widgets->get_setting_args( 'widget_search[2]' );
+               foreach ( $default_args as $key => $default_value ) {
+                       $this->assertEquals( $default_value, $args[ $key ] );
+               }
+
+               remove_theme_support( 'customize-selective-refresh-widgets' );
+               $args = $this->manager->widgets->get_setting_args( 'widget_search[2]' );
+               $this->assertEquals( 'refresh', $args['transport'] );
+               add_theme_support( 'customize-selective-refresh-widgets' );
+
</ins><span class="cx" style="display: block; padding: 0 10px">                 $override_args = array(
</span><span class="cx" style="display: block; padding: 0 10px">                        'type' => 'theme_mod',
</span><span class="cx" style="display: block; padding: 0 10px">                        'capability' => 'edit_posts',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -368,6 +459,10 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $this->assertEquals( array( $this->manager->widgets, 'render_widget_partial' ), $args['render_callback'] );
</span><span class="cx" style="display: block; padding: 0 10px">                $this->assertTrue( $args['container_inclusive'] );
</span><span class="cx" style="display: block; padding: 0 10px">                $this->assertFalse( $args['fallback_refresh'] );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+               remove_theme_support( 'customize-selective-refresh-widgets' );
+               $args = apply_filters( 'customize_dynamic_partial_args', false, 'widget[search-2]' );
+               $this->assertFalse( $args );
</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="lines" style="display: block; padding: 0 10px; color: #888">@@ -375,9 +470,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @see WP_Customize_Widgets::selective_refresh_init()
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        function test_selective_refresh_init() {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ function test_selective_refresh_init_with_theme_support() {
+               add_theme_support( 'customize-selective-refresh-widgets' );
</ins><span class="cx" style="display: block; padding: 0 10px">                 $this->manager->widgets->selective_refresh_init();
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $this->assertEquals( 10, has_action( 'wp_enqueue_scripts', array( $this->manager->widgets, 'customize_preview_enqueue_deps' ) ) );
</del><span class="cx" style="display: block; padding: 0 10px">                 $this->assertEquals( 10, has_action( 'dynamic_sidebar_before', array( $this->manager->widgets, 'start_dynamic_sidebar' ) ) );
</span><span class="cx" style="display: block; padding: 0 10px">                $this->assertEquals( 10, has_action( 'dynamic_sidebar_after', array( $this->manager->widgets, 'end_dynamic_sidebar' ) ) );
</span><span class="cx" style="display: block; padding: 0 10px">                $this->assertEquals( 10, has_filter( 'dynamic_sidebar_params', array( $this->manager->widgets, 'filter_dynamic_sidebar_params' ) ) );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -385,12 +480,26 @@
</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">-         * Test WP_Customize_Widgets::customize_preview_enqueue_deps().
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * Test WP_Customize_Widgets::selective_refresh_init().
</ins><span class="cx" style="display: block; padding: 0 10px">          *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * @see WP_Customize_Widgets::customize_preview_enqueue_deps()
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * @see WP_Customize_Widgets::selective_refresh_init()
</ins><span class="cx" style="display: block; padding: 0 10px">          */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        function test_customize_preview_enqueue_deps() {
-               $this->manager->widgets->customize_preview_enqueue_deps();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ function test_selective_refresh_init_without_theme_support() {
+               remove_theme_support( 'customize-selective-refresh-widgets' );
+               $this->manager->widgets->selective_refresh_init();
+               $this->assertFalse( has_action( 'dynamic_sidebar_before', array( $this->manager->widgets, 'start_dynamic_sidebar' ) ) );
+               $this->assertFalse( has_action( 'dynamic_sidebar_after', array( $this->manager->widgets, 'end_dynamic_sidebar' ) ) );
+               $this->assertFalse( has_filter( 'dynamic_sidebar_params', array( $this->manager->widgets, 'filter_dynamic_sidebar_params' ) ) );
+               $this->assertFalse( has_filter( 'wp_kses_allowed_html', array( $this->manager->widgets, 'filter_wp_kses_allowed_data_attributes' ) ) );
+       }
+
+       /**
+        * Test WP_Customize_Widgets::customize_preview_enqueue().
+        *
+        * @see WP_Customize_Widgets::customize_preview_enqueue()
+        */
+       function test_customize_preview_enqueue() {
+               $this->manager->widgets->customize_preview_enqueue();
</ins><span class="cx" style="display: block; padding: 0 10px">                 $this->assertTrue( wp_script_is( 'customize-preview-widgets', 'enqueued' ) );
</span><span class="cx" style="display: block; padding: 0 10px">                $this->assertTrue( wp_style_is( 'customize-preview', 'enqueued' ) );
</span><span class="cx" style="display: block; padding: 0 10px">                $script = wp_scripts()->registered['customize-preview-widgets'];
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -458,6 +567,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @see WP_Customize_Widgets::render_widget_partial()
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        function test_render_widget_partial() {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                add_theme_support( 'customize-selective-refresh-widgets' );
+               $this->do_customize_boot_actions();
</ins><span class="cx" style="display: block; padding: 0 10px">                 $this->manager->widgets->selective_refresh_init();
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $partial_id = 'widget[search-2]';
</span></span></pre>
</div>
</div>

</body>
</html>