From f3f84d2f2112549be6e9e6bd82ef09a81e109a5c Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Mon, 21 Mar 2016 21:59:29 +0000 Subject: [PATCH] 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 #27355. Fixes #35855. Built from https://develop.svn.wordpress.org/trunk@37040 git-svn-id: http://core.svn.wordpress.org/trunk@37007 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-admin/js/customize-widgets.js | 4 +- wp-admin/js/customize-widgets.min.js | 2 +- wp-content/themes/twentyeleven/functions.php | 3 + .../themes/twentyeleven/inc/widgets.php | 1 + wp-content/themes/twentyfifteen/functions.php | 3 + .../themes/twentyfourteen/functions.php | 3 + .../themes/twentyfourteen/inc/widgets.php | 21 + .../themes/twentyfourteen/js/functions.js | 41 +- .../themes/twentythirteen/functions.php | 3 + .../themes/twentythirteen/js/functions.js | 33 +- .../twentythirteen/js/theme-customizer.js | 12 - wp-content/themes/twentytwelve/functions.php | 3 + wp-includes/class-wp-customize-manager.php | 25 +- wp-includes/class-wp-customize-nav-menus.php | 19 +- wp-includes/class-wp-customize-widgets.php | 89 +- wp-includes/class-wp-widget.php | 4 +- wp-includes/js/customize-preview-widgets.js | 827 +++++++++--------- .../js/customize-preview-widgets.min.js | 2 +- wp-includes/js/customize-selective-refresh.js | 2 +- .../js/customize-selective-refresh.min.js | 2 +- wp-includes/script-loader.php | 4 +- wp-includes/theme.php | 2 +- wp-includes/version.php | 2 +- .../widgets/class-wp-nav-menu-widget.php | 5 +- .../widgets/class-wp-widget-archives.php | 6 +- .../widgets/class-wp-widget-calendar.php | 8 +- .../widgets/class-wp-widget-categories.php | 8 +- wp-includes/widgets/class-wp-widget-links.php | 7 +- wp-includes/widgets/class-wp-widget-meta.php | 8 +- wp-includes/widgets/class-wp-widget-pages.php | 8 +- .../class-wp-widget-recent-comments.php | 13 +- .../widgets/class-wp-widget-recent-posts.php | 8 +- wp-includes/widgets/class-wp-widget-rss.php | 7 +- .../widgets/class-wp-widget-search.php | 6 +- .../widgets/class-wp-widget-tag-cloud.php | 7 +- wp-includes/widgets/class-wp-widget-text.php | 10 +- 36 files changed, 695 insertions(+), 513 deletions(-) diff --git a/wp-admin/js/customize-widgets.js b/wp-admin/js/customize-widgets.js index 91a65164e9..fee74cfe34 100644 --- a/wp-admin/js/customize-widgets.js +++ b/wp-admin/js/customize-widgets.js @@ -34,7 +34,7 @@ multi_number: null, name: null, id_base: null, - transport: api.Widgets.data.selectiveRefresh ? 'postMessage' : 'refresh', + transport: null, params: [], width: null, height: null, @@ -1982,7 +1982,7 @@ isExistingWidget = api.has( settingId ); if ( ! isExistingWidget ) { settingArgs = { - transport: api.Widgets.data.selectiveRefresh ? 'postMessage' : 'refresh', + transport: api.Widgets.data.selectiveRefreshableWidgets[ widget.get( 'id_base' ) ] ? 'postMessage' : 'refresh', previewer: this.setting.previewer }; setting = api.create( settingId, settingId, '', settingArgs ); diff --git a/wp-admin/js/customize-widgets.min.js b/wp-admin/js/customize-widgets.min.js index b8089a0a50..c0a3e8c373 100644 --- a/wp-admin/js/customize-widgets.min.js +++ b/wp-admin/js/customize-widgets.min.js @@ -1 +1 @@ -!function(a,b){function c(a){var b,c={number:null,id_base:null};return b=a.match(/^(.+)-(\d+)$/),b?(c.id_base=b[1],c.number=parseInt(b[2],10)):c.id_base=a,c}function d(a){var b,d=c(a);return b="widget_"+d.id_base,d.number&&(b+="["+d.number+"]"),b}if(a&&a.customize){var e,f=a.customize;f.Widgets=f.Widgets||{},f.Widgets.savedWidgetIds={},f.Widgets.data=_wpCustomizeWidgetsSettings||{},e=f.Widgets.data.l10n,delete f.Widgets.data.l10n,f.Widgets.WidgetModel=Backbone.Model.extend({id:null,temp_id:null,classname:null,control_tpl:null,description:null,is_disabled:null,is_multi:null,multi_number:null,name:null,id_base:null,transport:f.Widgets.data.selectiveRefresh?"postMessage":"refresh",params:[],width:null,height:null,search_matched:!0}),f.Widgets.WidgetCollection=Backbone.Collection.extend({model:f.Widgets.WidgetModel,doSearch:function(a){this.terms!==a&&(this.terms=a,this.terms.length>0&&this.search(this.terms),""===this.terms&&this.each(function(a){a.set("search_matched",!0)}))},search:function(a){var b,c;a=a.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&"),a=a.replace(/ /g,")(?=.*"),b=new RegExp("^(?=.*"+a+").+","i"),this.each(function(a){c=[a.get("name"),a.get("id"),a.get("description")].join(" "),a.set("search_matched",b.test(c))})}}),f.Widgets.availableWidgets=new f.Widgets.WidgetCollection(f.Widgets.data.availableWidgets),f.Widgets.SidebarModel=Backbone.Model.extend({after_title:null,after_widget:null,before_title:null,before_widget:null,"class":null,description:null,id:null,name:null,is_rendered:!1}),f.Widgets.SidebarCollection=Backbone.Collection.extend({model:f.Widgets.SidebarModel}),f.Widgets.registeredSidebars=new f.Widgets.SidebarCollection(f.Widgets.data.registeredSidebars),f.Widgets.AvailableWidgetsPanelView=a.Backbone.View.extend({el:"#available-widgets",events:{"input #widgets-search":"search","keyup #widgets-search":"search","change #widgets-search":"search","search #widgets-search":"search","focus .widget-tpl":"focus","click .widget-tpl":"_submit","keypress .widget-tpl":"_submit",keydown:"keyboardAccessible"},selected:null,currentSidebarControl:null,$search:null,initialize:function(){var a=this;this.$search=b("#widgets-search"),_.bindAll(this,"close"),this.listenTo(this.collection,"change",this.updateList),this.updateList(),b("#customize-controls, #available-widgets .customize-section-title").on("click keydown",function(c){var d=b(c.target).is(".add-new-widget, .add-new-widget *");b("body").hasClass("adding-widget")&&!d&&a.close()}),f.previewer.bind("url",this.close)},search:function(a){var b;this.collection.doSearch(a.target.value),this.selected&&!this.selected.is(":visible")&&(this.selected.removeClass("selected"),this.selected=null),this.selected&&!a.target.value&&(this.selected.removeClass("selected"),this.selected=null),!this.selected&&a.target.value&&(b=this.$el.find("> .widget-tpl:visible:first"),b.length&&this.select(b))},updateList:function(){this.collection.each(function(a){var c=b("#widget-tpl-"+a.id);c.toggle(a.get("search_matched")&&!a.get("is_disabled")),a.get("is_disabled")&&c.is(this.selected)&&(this.selected=null)})},select:function(a){this.selected=b(a),this.selected.siblings(".widget-tpl").removeClass("selected"),this.selected.addClass("selected")},focus:function(a){this.select(b(a.currentTarget))},_submit:function(a){("keypress"!==a.type||13===a.which||32===a.which)&&this.submit(b(a.currentTarget))},submit:function(a){var c,d,e;a||(a=this.selected),a&&this.currentSidebarControl&&(this.select(a),c=b(this.selected).data("widget-id"),d=this.collection.findWhere({id:c}),d&&(e=this.currentSidebarControl.addWidget(d.get("id_base")),e&&e.focus(),this.close()))},open:function(a){this.currentSidebarControl=a,_(this.currentSidebarControl.getWidgetFormControls()).each(function(a){a.params.is_wide&&a.collapseForm()}),b("body").addClass("adding-widget"),this.$el.find(".selected").removeClass("selected"),this.collection.doSearch(""),f.settings.browser.mobile||this.$search.focus()},close:function(a){a=a||{},a.returnFocus&&this.currentSidebarControl&&this.currentSidebarControl.container.find(".add-new-widget").focus(),this.currentSidebarControl=null,this.selected=null,b("body").removeClass("adding-widget"),this.$search.val("")},keyboardAccessible:function(a){var c=13===a.which,d=27===a.which,e=40===a.which,f=38===a.which,g=9===a.which,h=a.shiftKey,i=null,j=this.$el.find("> .widget-tpl:visible:first"),k=this.$el.find("> .widget-tpl:visible:last"),l=b(a.target).is(this.$search),m=b(a.target).is(".widget-tpl:visible:last");return e||f?(e?l?i=j:this.selected&&0!==this.selected.nextAll(".widget-tpl:visible").length&&(i=this.selected.nextAll(".widget-tpl:visible:first")):f&&(l?i=k:this.selected&&0!==this.selected.prevAll(".widget-tpl:visible").length&&(i=this.selected.prevAll(".widget-tpl:visible:first"))),this.select(i),void(i?i.focus():this.$search.focus())):void((!c||this.$search.val())&&(c?this.submit():d&&this.close({returnFocus:!0}),this.currentSidebarControl&&g&&(h&&l||!h&&m)&&(this.currentSidebarControl.container.find(".add-new-widget").focus(),a.preventDefault())))}}),f.Widgets.formSyncHandlers={rss:function(a,c,d){var e=c.find(".widget-error:first"),f=b("
"+d+"
").find(".widget-error:first");e.length&&f.length?e.replaceWith(f):e.length?e.remove():f.length&&c.find(".widget-content:first").prepend(f)}},f.Widgets.WidgetControl=f.Control.extend({defaultExpandedArguments:{duration:"fast",completeCallback:b.noop},initialize:function(a,c){var d=this;d.widgetControlEmbedded=!1,d.widgetContentEmbedded=!1,d.expanded=new f.Value(!1),d.expandedArgumentsQueue=[],d.expanded.bind(function(a){var c=d.expandedArgumentsQueue.shift();c=b.extend({},d.defaultExpandedArguments,c),d.onChangeExpanded(a,c)}),f.Control.prototype.initialize.call(d,a,c)},ready:function(){var a=this;a.section()?f.section(a.section(),function(b){var c=function(d){d&&(a.embedWidgetControl(),b.expanded.unbind(c))};b.expanded()?c(!0):b.expanded.bind(c)}):a.embedWidgetControl()},embedWidgetControl:function(){var a,c=this;c.widgetControlEmbedded||(c.widgetControlEmbedded=!0,a=b(c.params.widget_control),c.container.append(a),c._setupModel(),c._setupWideWidget(),c._setupControlToggle(),c._setupWidgetTitle(),c._setupReorderUI(),c._setupHighlightEffects(),c._setupUpdateUI(),c._setupRemoveUI())},embedWidgetContent:function(){var a,c=this;c.embedWidgetControl(),c.widgetContentEmbedded||(c.widgetContentEmbedded=!0,a=b(c.params.widget_content),c.container.find(".widget-content:first").append(a),b(document).trigger("widget-added",[c.container.find(".widget:first")]))},_setupModel:function(){var a,b=this;a=function(){f.Widgets.savedWidgetIds[b.params.widget_id]=!0},f.bind("ready",a),f.bind("saved",a),this._updateCount=0,this.isWidgetUpdating=!1,this.liveUpdateMode=!0,this.setting.bind(function(a,c){_(c).isEqual(a)||b.isWidgetUpdating||b.updateWidget({instance:a})})},_setupWideWidget:function(){var a,c,d,e,g,h=this;this.params.is_wide&&(a=this.container.find(".widget-inside"),c=a.find("> .form"),d=b(".wp-full-overlay-sidebar-content:first"),this.container.addClass("wide-widget-control"),this.container.find(".widget-content:first").css({"max-width":this.params.width,"min-height":this.params.height}),g=function(){var d,e=h.container.offset().top,f=b(window).height(),g=c.outerHeight();a.css("max-height",f),d=Math.max(0,Math.min(Math.max(e,0),f-g)),a.css("top",d)},e=b("#customize-theme-controls"),this.container.on("expand",function(){g(),d.on("scroll",g),b(window).on("resize",g),e.on("expanded collapsed",g)}),this.container.on("collapsed",function(){d.off("scroll",g),b(window).off("resize",g),e.off("expanded collapsed",g)}),f.each(function(a){0===a.id.indexOf("sidebars_widgets[")&&a.bind(function(){h.container.hasClass("expanded")&&g()})}))},_setupControlToggle:function(){var a,b=this;this.container.find(".widget-top").on("click",function(a){a.preventDefault();var c=b.getSidebarWidgetsControl();c.isReordering||b.expanded(!b.expanded())}),a=this.container.find(".widget-control-close"),a.on("click",function(a){a.preventDefault(),b.collapse(),b.container.find(".widget-top .widget-action:first").focus()})},_setupWidgetTitle:function(){var a,b=this;a=function(){var a=b.setting().title,c=b.container.find(".in-widget-title");a?c.text(": "+a):c.text("")},this.setting.bind(a),a()},_setupReorderUI:function(){var c,d,g,h,i,j=this;c=function(a){a.siblings(".selected").removeClass("selected"),a.addClass("selected");var b=a.data("id")===j.params.sidebar_id;j.container.find(".move-widget-btn").prop("disabled",b)},this.container.find(".widget-title-action").after(b(f.Widgets.data.tpl.widgetReorderNav)),i=_.template(f.Widgets.data.tpl.moveWidgetArea),d=b(i({sidebars:_(f.Widgets.registeredSidebars.toArray()).pluck("attributes")})),this.container.find(".widget-top").after(d),h=function(){var a,e=d.find("li"),g=0;a=e.filter(function(){return b(this).data("id")===j.params.sidebar_id}),e.each(function(){var d,e,h,i=b(this);d=i.data("id"),e=f.Widgets.registeredSidebars.get(d),h=e.get("is_rendered"),i.toggle(h),h&&(g+=1),i.hasClass("selected")&&!h&&c(a)}),g>1?j.container.find(".move-widget").show():j.container.find(".move-widget").hide()},h(),f.Widgets.registeredSidebars.on("change:is_rendered",h),g=this.container.find(".widget-reorder-nav"),g.find(".move-widget, .move-widget-down, .move-widget-up").each(function(){b(this).prepend(j.container.find(".widget-title").text()+": ")}).on("click keypress",function(c){if("keypress"!==c.type||13===c.which||32===c.which)if(b(this).focus(),b(this).is(".move-widget"))j.toggleWidgetMoveArea();else{var d=b(this).is(".move-widget-down"),f=b(this).is(".move-widget-up"),g=j.getWidgetSidebarPosition();if(f&&0===g||d&&g===j.getSidebarWidgetsControl().setting().length-1)return;f?(j.moveUp(),a.a11y.speak(e.widgetMovedUp)):(j.moveDown(),a.a11y.speak(e.widgetMovedDown)),b(this).focus()}}),this.container.find(".widget-area-select").on("click keypress","li",function(a){("keypress"!==a.type||13===a.which||32===a.which)&&(a.preventDefault(),c(b(this)))}),this.container.find(".move-widget-btn").click(function(){j.getSidebarWidgetsControl().toggleReordering(!1);var a,b,c,d,e,g=j.params.sidebar_id,h=j.container.find(".widget-area-select li.selected").data("id");a=f("sidebars_widgets["+g+"]"),b=f("sidebars_widgets["+h+"]"),c=Array.prototype.slice.call(a()),d=Array.prototype.slice.call(b()),e=j.getWidgetSidebarPosition(),c.splice(e,1),d.push(j.params.widget_id),a(c),b(d),j.focus()})},_setupHighlightEffects:function(){var a=this;this.container.on("mouseenter click",function(){a.setting.previewer.send("highlight-widget",a.params.widget_id)}),this.setting.bind(function(){a.setting.previewer.send("highlight-widget",a.params.widget_id)})},_setupUpdateUI:function(){var a,c,d,g,h,i=this;a=this.container.find(".widget:first"),c=a.find(".widget-content:first"),d=this.container.find(".widget-control-save"),d.val(e.saveBtnLabel),d.attr("title",e.saveBtnTooltip),d.removeClass("button-primary").addClass("button-secondary"),d.on("click",function(a){a.preventDefault(),i.updateWidget({disable_form:!0})}),g=_.debounce(function(){i.updateWidget()},250),c.on("keydown","input",function(a){13===a.which&&(a.preventDefault(),i.updateWidget({ignoreActiveElement:!0}))}),c.on("change input propertychange",":input",function(a){i.liveUpdateMode&&("change"===a.type||this.checkValidity&&this.checkValidity())&&g()}),this.setting.previewer.channel.bind("synced",function(){i.container.removeClass("previewer-loading")}),f.previewer.bind("widget-updated",function(a){a===i.params.widget_id&&i.container.removeClass("previewer-loading")}),h=f.Widgets.formSyncHandlers[this.params.widget_id_base],h&&b(document).on("widget-synced",function(b,c){a.is(c)&&h.apply(document,arguments)})},onChangeActive:function(a,b){this.container.toggleClass("widget-rendered",a),b.completeCallback&&b.completeCallback()},_setupRemoveUI:function(){var a,b,c=this;a=this.container.find("a.widget-control-remove"),a.on("click",function(a){a.preventDefault();var b;b=c.container.next().is(".customize-control-widget_form")?c.container.next().find(".widget-action:first"):c.container.prev().is(".customize-control-widget_form")?c.container.prev().find(".widget-action:first"):c.container.next(".customize-control-sidebar_widgets").find(".add-new-widget:first"),c.container.slideUp(function(){var a,d,e=f.Widgets.getSidebarWidgetControlContainingWidget(c.params.widget_id);e&&(a=e.setting().slice(),d=_.indexOf(a,c.params.widget_id),-1!==d&&(a.splice(d,1),e.setting(a),b.focus()))})}),b=function(){a.text(e.removeBtnLabel),a.attr("title",e.removeBtnTooltip)},this.params.is_new?f.bind("saved",b):b()},_getInputs:function(a){return b(a).find(":input[name]")},_getInputsSignature:function(a){var c=_(a).map(function(a){var c,d=b(a);return c=d.is(":checkbox, :radio")?[d.attr("id"),d.attr("name"),d.prop("value")]:[d.attr("id"),d.attr("name")],c.join(",")});return c.join(";")},_getInputState:function(a){return a=b(a),a.is(":radio, :checkbox")?a.prop("checked"):a.is("select[multiple]")?a.find("option:selected").map(function(){return b(this).val()}).get():a.val()},_setInputState:function(a,c){a=b(a),a.is(":radio, :checkbox")?a.prop("checked",c):a.is("select[multiple]")?(c=b.isArray(c)?_.map(c,function(a){return String(a)}):[],a.find("option").each(function(){b(this).prop("selected",-1!==_.indexOf(c,String(this.value)))})):a.val(c)},getSidebarWidgetsControl:function(){var a,b;return a="sidebars_widgets["+this.params.sidebar_id+"]",(b=f.control(a))?b:void 0},updateWidget:function(c){var d,g,h,i,j,k,l,m,n,o,p,q=this;q.embedWidgetContent(),c=b.extend({instance:null,complete:null,ignoreActiveElement:!1},c),d=c.instance,g=c.complete,this._updateCount+=1,j=this._updateCount,h=this.container.find(".widget:first"),i=h.find(".widget-content:first"),i.find(".widget-error").remove(),this.container.addClass("widget-form-loading"),this.container.addClass("previewer-loading"),n=f.state("processing"),n(n()+1),this.liveUpdateMode||this.container.addClass("widget-form-disabled"),k={},k.action="update-widget",k.wp_customize="on",k.nonce=f.settings.nonce["update-widget"],k.theme=f.settings.theme.stylesheet,k.customized=a.customize.previewer.query().customized,l=b.param(k),m=this._getInputs(i),m.each(function(){b(this).data("state"+j,q._getInputState(this))}),l+=d?"&"+b.param({sanitized_widget_setting:JSON.stringify(d)}):"&"+m.serialize(),l+="&"+i.find("~ :input").serialize(),this._previousUpdateRequest&&this._previousUpdateRequest.abort(),o=b.post(a.ajax.settings.url,l),this._previousUpdateRequest=o,o.done(function(a){var d,k,l,n,o=!1;return"0"===a?(f.previewer.preview.iframe.hide(),void f.previewer.login().done(function(){q.updateWidget(c),f.previewer.preview.iframe.show()})):"-1"===a?void f.previewer.cheatin():void(a.success?(k=b("
"+a.data.form+"
"),l=q._getInputs(k),n=q._getInputsSignature(m)===q._getInputsSignature(l),n&&!q.liveUpdateMode&&(q.liveUpdateMode=!0,q.container.removeClass("widget-form-disabled"),q.container.find('input[name="savewidget"]').hide()),n&&q.liveUpdateMode?(m.each(function(a){var d,e,f,g=b(this),h=b(l[a]);d=g.data("state"+j),e=q._getInputState(h),g.data("sanitized",e),f=!_.isEqual(d,e)&&(c.ignoreActiveElement||!g.is(document.activeElement)),f&&q._setInputState(g,e)}),b(document).trigger("widget-synced",[h,a.data.form])):q.liveUpdateMode?(q.liveUpdateMode=!1,q.container.find('input[name="savewidget"]').show(),o=!0):(i.html(a.data.form),q.container.removeClass("widget-form-disabled"),b(document).trigger("widget-updated",[h])),p=!o&&!_(q.setting()).isEqual(a.data.instance),p?(q.isWidgetUpdating=!0,q.setting(a.data.instance),q.isWidgetUpdating=!1):q.container.removeClass("previewer-loading"),g&&g.call(q,null,{noChange:!p,ajaxFinished:!0})):(d=e.error,a.data&&a.data.message&&(d=a.data.message),g?g.call(q,d):i.prepend('

'+d+"

")))}),o.fail(function(a,b){g&&g.call(q,b)}),o.always(function(){q.container.removeClass("widget-form-loading"),m.each(function(){b(this).removeData("state"+j)}),n(n()-1)})},expandControlSection:function(){f.Control.prototype.expand.call(this)},_toggleExpanded:f.Section.prototype._toggleExpanded,expand:f.Section.prototype.expand,expandForm:function(){this.expand()},collapse:f.Section.prototype.collapse,collapseForm:function(){this.collapse()},toggleForm:function(a){"undefined"==typeof a&&(a=!this.expanded()),this.expanded(a)},onChangeExpanded:function(a,b){var c,d,e,g,h=this;return h.embedWidgetControl(),a&&h.embedWidgetContent(),b.unchanged?void(a&&f.Control.prototype.expand.call(h,{completeCallback:b.completeCallback})):(c=this.container.find("div.widget:first"),d=c.find(".widget-inside:first"),void(a?(h.section()&&f.section(h.section())&&h.expandControlSection(),f.control.each(function(a){h.params.type===a.params.type&&h!==a&&a.collapse()}),e=function(){h.container.removeClass("expanding"),h.container.addClass("expanded"),h.container.trigger("expanded")},b.completeCallback&&(g=e,e=function(){g(),b.completeCallback()}),h.params.is_wide?d.fadeIn(b.duration,e):d.slideDown(b.duration,e),h.container.trigger("expand"),h.container.addClass("expanding")):(e=function(){h.container.removeClass("collapsing"),h.container.removeClass("expanded"),h.container.trigger("collapsed")},b.completeCallback&&(g=e,e=function(){g(),b.completeCallback()}),h.container.trigger("collapse"),h.container.addClass("collapsing"),h.params.is_wide?d.fadeOut(b.duration,e):d.slideUp(b.duration,function(){c.css({width:"",margin:""}),e()}))))},getWidgetSidebarPosition:function(){var a,b;return a=this.getSidebarWidgetsControl().setting(),b=_.indexOf(a,this.params.widget_id),-1!==b?b:void 0},moveUp:function(){this._moveWidgetByOne(-1)},moveDown:function(){this._moveWidgetByOne(1)},_moveWidgetByOne:function(a){var b,c,d,e;b=this.getWidgetSidebarPosition(),c=this.getSidebarWidgetsControl().setting,d=Array.prototype.slice.call(c()),e=d[b+a],d[b+a]=this.params.widget_id,d[b]=e,c(d)},toggleWidgetMoveArea:function(a){var c,d=this;c=this.container.find(".move-widget-area"),"undefined"==typeof a&&(a=!c.hasClass("active")),a&&(c.find(".selected").removeClass("selected"),c.find("li").filter(function(){return b(this).data("id")===d.params.sidebar_id}).addClass("selected"),this.container.find(".move-widget-btn").prop("disabled",!0)),c.toggleClass("active",a)},highlightSectionAndControl:function(){var a;a=this.container.is(":hidden")?this.container.closest(".control-section"):this.container,b(".highlighted").removeClass("highlighted"),a.addClass("highlighted"),setTimeout(function(){a.removeClass("highlighted")},500)}}),f.Widgets.WidgetsPanel=f.Panel.extend({ready:function(){var a=this;f.Panel.prototype.ready.call(a),a.deferred.embedded.done(function(){var c,d,g;c=a.container.find(".panel-meta"),d=b("
",{"class":"no-widget-areas-rendered-notice"}),d.append(b("",{text:e.noAreasRendered})),c.append(d),g=function(){return 0===_.filter(a.sections(),function(a){return a.active()}).length},d.toggle(g()),f.previewer.deferred.active.done(function(){d.toggle(g())}),f.bind("pane-contents-reflowed",function(){var a="resolved"===f.previewer.deferred.active.state()?"fast":0;g()?d.slideDown(a):d.slideUp(a)})})},isContextuallyActive:function(){var a=this;return a.active()}}),f.Widgets.SidebarSection=f.Section.extend({ready:function(){var a,b=this;f.Section.prototype.ready.call(this),a=f.Widgets.registeredSidebars.get(b.params.sidebarId),b.active.bind(function(b){a.set("is_rendered",b)}),a.set("is_rendered",b.active())}}),f.Widgets.SidebarControl=f.Control.extend({ready:function(){this.$controlSection=this.container.closest(".control-section"),this.$sectionContent=this.container.closest(".accordion-section-content"),this._setupModel(),this._setupSortable(),this._setupAddition(),this._applyCardinalOrderClassNames()},_setupModel:function(){var a=this;this.setting.bind(function(d,e){var g,h,i;h=_(e).difference(d),d=_(d).filter(function(a){var b=c(a);return!!f.Widgets.availableWidgets.findWhere({id_base:b.id_base})}),g=_(d).map(function(b){var c=f.Widgets.getWidgetFormControlForWidget(b);return c||(c=a.addWidget(b)),c}),g.sort(function(a,b){var c=_.indexOf(d,a.params.widget_id),e=_.indexOf(d,b.params.widget_id);return c-e}),i=0,_(g).each(function(b){b.priority(i),b.section(a.section()),i+=1}),a.priority(i),a._applyCardinalOrderClassNames(),_(g).each(function(b){b.params.sidebar_id=a.params.sidebar_id}),_(h).each(function(d){setTimeout(function(){var e,g,h,i,j,k=!1;f.each(function(b){if(b.id!==a.setting.id&&0===b.id.indexOf("sidebars_widgets[")&&"sidebars_widgets[wp_inactive_widgets]"!==b.id){var c,e=b();c=_.indexOf(e,d),-1!==c&&(k=!0)}}),k||(e=f.Widgets.getWidgetFormControlForWidget(d),g=e&&b.contains(document,e.container[0])&&!b.contains(a.$sectionContent[0],e.container[0]),e&&!g&&(f.control.remove(e.id),e.container.remove()),f.Widgets.savedWidgetIds[d]&&(h=f.value("sidebars_widgets[wp_inactive_widgets]")().slice(),h.push(d),f.value("sidebars_widgets[wp_inactive_widgets]")(_(h).unique())),i=c(d).id_base,j=f.Widgets.availableWidgets.findWhere({id_base:i}),j&&!j.get("is_multi")&&j.set("is_disabled",!1))})})})},_setupSortable:function(){var a=this;this.isReordering=!1,this.$sectionContent.sortable({items:"> .customize-control-widget_form",handle:".widget-top",axis:"y",tolerance:"pointer",connectWith:".accordion-section-content:has(.customize-control-sidebar_widgets)",update:function(){var c,d=a.$sectionContent.sortable("toArray");c=b.map(d,function(a){return b("#"+a).find(":input[name=widget-id]").val()}),a.setting(c)}}),this.$controlSection.find(".accordion-section-title").droppable({accept:".customize-control-widget_form",over:function(){var b=f.section(a.section.get());b.expand({allowMultiple:!0,completeCallback:function(){f.section.each(function(a){a.container.find(".customize-control-sidebar_widgets").length&&a.container.find(".accordion-section-content:first").sortable("refreshPositions")})}})}}),this.container.find(".reorder-toggle").on("click",function(){a.toggleReordering(!a.isReordering)})},_setupAddition:function(){var a=this;this.container.find(".add-new-widget").on("click",function(){var c=b(this);a.$sectionContent.hasClass("reordering")||(b("body").hasClass("adding-widget")?(c.attr("aria-expanded","false"),f.Widgets.availableWidgetsPanel.close()):(c.attr("aria-expanded","true"),f.Widgets.availableWidgetsPanel.open(a)))})},_applyCardinalOrderClassNames:function(){var a=[];return _.each(this.setting(),function(b){var c=f.Widgets.getWidgetFormControlForWidget(b);c&&a.push(c)}),0===a.length||1===f.Widgets.registeredSidebars.length&&a.length<=1?void this.container.find(".reorder-toggle").hide():(this.container.find(".reorder-toggle").show(),b(a).each(function(){b(this.container).removeClass("first-widget").removeClass("last-widget").find(".move-widget-down, .move-widget-up").prop("tabIndex",0)}),_.first(a).container.addClass("first-widget").find(".move-widget-up").prop("tabIndex",-1),void _.last(a).container.addClass("last-widget").find(".move-widget-down").prop("tabIndex",-1))},toggleReordering:function(b){var c=this.$sectionContent.find(".add-new-widget"),d=this.container.find(".reorder-toggle"),f=this.$sectionContent.find(".widget-title");b=Boolean(b),b!==this.$sectionContent.hasClass("reordering")&&(this.isReordering=b,this.$sectionContent.toggleClass("reordering",b),b?(_(this.getWidgetFormControls()).each(function(a){a.collapse()}),c.attr({tabindex:"-1","aria-hidden":"true"}),d.attr("aria-label",e.reorderLabelOff),a.a11y.speak(e.reorderModeOn),f.attr("aria-hidden","true")):(c.removeAttr("tabindex aria-hidden"),d.attr("aria-label",e.reorderLabelOn),a.a11y.speak(e.reorderModeOff),f.attr("aria-hidden","false")))},getWidgetFormControls:function(){var a=[];return _(this.setting()).each(function(b){var c=d(b),e=f.control(c);e&&a.push(e)}),a},addWidget:function(a){var d,e,g,h,i,j,k,l,m,n,o=this,p="widget_form",q=c(a),r=q.number,s=q.id_base,t=f.Widgets.availableWidgets.findWhere({id_base:s});return t?r&&!t.get("is_multi")?!1:(t.get("is_multi")&&!r&&(t.set("multi_number",t.get("multi_number")+1),r=t.get("multi_number")),d=b.trim(b("#widget-tpl-"+t.get("id")).html()),t.get("is_multi")?d=d.replace(/<[^<>]+>/g,function(a){return a.replace(/__i__|%i%/g,r)}):t.set("is_disabled",!0),e=b(d),g=b("
  • ").addClass("customize-control").addClass("customize-control-"+p).append(e),g.find("> .widget-icon").remove(),t.get("is_multi")&&(g.find('input[name="widget_number"]').val(r),g.find('input[name="multi_number"]').val(r)),a=g.find('[name="widget-id"]').val(),g.hide(),i="widget_"+t.get("id_base"),t.get("is_multi")&&(i+="["+r+"]"),g.attr("id","customize-control-"+i.replace(/\]/g,"").replace(/\[/g,"-")),j=f.has(i),j||(m={transport:f.Widgets.data.selectiveRefresh?"postMessage":"refresh",previewer:this.setting.previewer},n=f.create(i,i,"",m),n.set({})),h=f.controlConstructor[p],k=new h(i,{params:{settings:{"default":i},content:g,sidebar_id:o.params.sidebar_id,widget_id:a,widget_id_base:t.get("id_base"),type:p,is_new:!j,width:t.get("width"),height:t.get("height"),is_wide:t.get("is_wide"),active:!0},previewer:o.setting.previewer}),f.control.add(i,k),f.each(function(b){if(b.id!==o.setting.id&&0===b.id.indexOf("sidebars_widgets[")){var c=b().slice(),d=_.indexOf(c,a);-1!==d&&(c.splice(d),b(c))}}),l=this.setting().slice(),-1===_.indexOf(l,a)&&(l.push(a),this.setting(l)),g.slideDown(function(){j&&k.updateWidget({instance:k.setting()})}),k):!1}}),b.extend(f.panelConstructor,{widgets:f.Widgets.WidgetsPanel}),b.extend(f.sectionConstructor,{sidebar:f.Widgets.SidebarSection}),b.extend(f.controlConstructor,{widget_form:f.Widgets.WidgetControl,sidebar_widgets:f.Widgets.SidebarControl}),f.bind("ready",function(){f.Widgets.availableWidgetsPanel=new f.Widgets.AvailableWidgetsPanelView({collection:f.Widgets.availableWidgets}),f.previewer.bind("highlight-widget-control",f.Widgets.highlightWidgetFormControl),f.previewer.bind("focus-widget-control",f.Widgets.focusWidgetFormControl)}),f.Widgets.highlightWidgetFormControl=function(a){var b=f.Widgets.getWidgetFormControlForWidget(a);b&&b.highlightSectionAndControl()},f.Widgets.focusWidgetFormControl=function(a){var b=f.Widgets.getWidgetFormControlForWidget(a);b&&b.focus()},f.Widgets.getSidebarWidgetControlContainingWidget=function(a){var b=null;return f.control.each(function(c){"sidebar_widgets"===c.params.type&&-1!==_.indexOf(c.setting(),a)&&(b=c)}),b},f.Widgets.getWidgetFormControlForWidget=function(a){var b=null;return f.control.each(function(c){"widget_form"===c.params.type&&c.params.widget_id===a&&(b=c)}),b}}}(window.wp,jQuery); \ No newline at end of file +!function(a,b){function c(a){var b,c={number:null,id_base:null};return b=a.match(/^(.+)-(\d+)$/),b?(c.id_base=b[1],c.number=parseInt(b[2],10)):c.id_base=a,c}function d(a){var b,d=c(a);return b="widget_"+d.id_base,d.number&&(b+="["+d.number+"]"),b}if(a&&a.customize){var e,f=a.customize;f.Widgets=f.Widgets||{},f.Widgets.savedWidgetIds={},f.Widgets.data=_wpCustomizeWidgetsSettings||{},e=f.Widgets.data.l10n,delete f.Widgets.data.l10n,f.Widgets.WidgetModel=Backbone.Model.extend({id:null,temp_id:null,classname:null,control_tpl:null,description:null,is_disabled:null,is_multi:null,multi_number:null,name:null,id_base:null,transport:null,params:[],width:null,height:null,search_matched:!0}),f.Widgets.WidgetCollection=Backbone.Collection.extend({model:f.Widgets.WidgetModel,doSearch:function(a){this.terms!==a&&(this.terms=a,this.terms.length>0&&this.search(this.terms),""===this.terms&&this.each(function(a){a.set("search_matched",!0)}))},search:function(a){var b,c;a=a.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&"),a=a.replace(/ /g,")(?=.*"),b=new RegExp("^(?=.*"+a+").+","i"),this.each(function(a){c=[a.get("name"),a.get("id"),a.get("description")].join(" "),a.set("search_matched",b.test(c))})}}),f.Widgets.availableWidgets=new f.Widgets.WidgetCollection(f.Widgets.data.availableWidgets),f.Widgets.SidebarModel=Backbone.Model.extend({after_title:null,after_widget:null,before_title:null,before_widget:null,"class":null,description:null,id:null,name:null,is_rendered:!1}),f.Widgets.SidebarCollection=Backbone.Collection.extend({model:f.Widgets.SidebarModel}),f.Widgets.registeredSidebars=new f.Widgets.SidebarCollection(f.Widgets.data.registeredSidebars),f.Widgets.AvailableWidgetsPanelView=a.Backbone.View.extend({el:"#available-widgets",events:{"input #widgets-search":"search","keyup #widgets-search":"search","change #widgets-search":"search","search #widgets-search":"search","focus .widget-tpl":"focus","click .widget-tpl":"_submit","keypress .widget-tpl":"_submit",keydown:"keyboardAccessible"},selected:null,currentSidebarControl:null,$search:null,initialize:function(){var a=this;this.$search=b("#widgets-search"),_.bindAll(this,"close"),this.listenTo(this.collection,"change",this.updateList),this.updateList(),b("#customize-controls, #available-widgets .customize-section-title").on("click keydown",function(c){var d=b(c.target).is(".add-new-widget, .add-new-widget *");b("body").hasClass("adding-widget")&&!d&&a.close()}),f.previewer.bind("url",this.close)},search:function(a){var b;this.collection.doSearch(a.target.value),this.selected&&!this.selected.is(":visible")&&(this.selected.removeClass("selected"),this.selected=null),this.selected&&!a.target.value&&(this.selected.removeClass("selected"),this.selected=null),!this.selected&&a.target.value&&(b=this.$el.find("> .widget-tpl:visible:first"),b.length&&this.select(b))},updateList:function(){this.collection.each(function(a){var c=b("#widget-tpl-"+a.id);c.toggle(a.get("search_matched")&&!a.get("is_disabled")),a.get("is_disabled")&&c.is(this.selected)&&(this.selected=null)})},select:function(a){this.selected=b(a),this.selected.siblings(".widget-tpl").removeClass("selected"),this.selected.addClass("selected")},focus:function(a){this.select(b(a.currentTarget))},_submit:function(a){("keypress"!==a.type||13===a.which||32===a.which)&&this.submit(b(a.currentTarget))},submit:function(a){var c,d,e;a||(a=this.selected),a&&this.currentSidebarControl&&(this.select(a),c=b(this.selected).data("widget-id"),d=this.collection.findWhere({id:c}),d&&(e=this.currentSidebarControl.addWidget(d.get("id_base")),e&&e.focus(),this.close()))},open:function(a){this.currentSidebarControl=a,_(this.currentSidebarControl.getWidgetFormControls()).each(function(a){a.params.is_wide&&a.collapseForm()}),b("body").addClass("adding-widget"),this.$el.find(".selected").removeClass("selected"),this.collection.doSearch(""),f.settings.browser.mobile||this.$search.focus()},close:function(a){a=a||{},a.returnFocus&&this.currentSidebarControl&&this.currentSidebarControl.container.find(".add-new-widget").focus(),this.currentSidebarControl=null,this.selected=null,b("body").removeClass("adding-widget"),this.$search.val("")},keyboardAccessible:function(a){var c=13===a.which,d=27===a.which,e=40===a.which,f=38===a.which,g=9===a.which,h=a.shiftKey,i=null,j=this.$el.find("> .widget-tpl:visible:first"),k=this.$el.find("> .widget-tpl:visible:last"),l=b(a.target).is(this.$search),m=b(a.target).is(".widget-tpl:visible:last");return e||f?(e?l?i=j:this.selected&&0!==this.selected.nextAll(".widget-tpl:visible").length&&(i=this.selected.nextAll(".widget-tpl:visible:first")):f&&(l?i=k:this.selected&&0!==this.selected.prevAll(".widget-tpl:visible").length&&(i=this.selected.prevAll(".widget-tpl:visible:first"))),this.select(i),void(i?i.focus():this.$search.focus())):void((!c||this.$search.val())&&(c?this.submit():d&&this.close({returnFocus:!0}),this.currentSidebarControl&&g&&(h&&l||!h&&m)&&(this.currentSidebarControl.container.find(".add-new-widget").focus(),a.preventDefault())))}}),f.Widgets.formSyncHandlers={rss:function(a,c,d){var e=c.find(".widget-error:first"),f=b("
    "+d+"
    ").find(".widget-error:first");e.length&&f.length?e.replaceWith(f):e.length?e.remove():f.length&&c.find(".widget-content:first").prepend(f)}},f.Widgets.WidgetControl=f.Control.extend({defaultExpandedArguments:{duration:"fast",completeCallback:b.noop},initialize:function(a,c){var d=this;d.widgetControlEmbedded=!1,d.widgetContentEmbedded=!1,d.expanded=new f.Value(!1),d.expandedArgumentsQueue=[],d.expanded.bind(function(a){var c=d.expandedArgumentsQueue.shift();c=b.extend({},d.defaultExpandedArguments,c),d.onChangeExpanded(a,c)}),f.Control.prototype.initialize.call(d,a,c)},ready:function(){var a=this;a.section()?f.section(a.section(),function(b){var c=function(d){d&&(a.embedWidgetControl(),b.expanded.unbind(c))};b.expanded()?c(!0):b.expanded.bind(c)}):a.embedWidgetControl()},embedWidgetControl:function(){var a,c=this;c.widgetControlEmbedded||(c.widgetControlEmbedded=!0,a=b(c.params.widget_control),c.container.append(a),c._setupModel(),c._setupWideWidget(),c._setupControlToggle(),c._setupWidgetTitle(),c._setupReorderUI(),c._setupHighlightEffects(),c._setupUpdateUI(),c._setupRemoveUI())},embedWidgetContent:function(){var a,c=this;c.embedWidgetControl(),c.widgetContentEmbedded||(c.widgetContentEmbedded=!0,a=b(c.params.widget_content),c.container.find(".widget-content:first").append(a),b(document).trigger("widget-added",[c.container.find(".widget:first")]))},_setupModel:function(){var a,b=this;a=function(){f.Widgets.savedWidgetIds[b.params.widget_id]=!0},f.bind("ready",a),f.bind("saved",a),this._updateCount=0,this.isWidgetUpdating=!1,this.liveUpdateMode=!0,this.setting.bind(function(a,c){_(c).isEqual(a)||b.isWidgetUpdating||b.updateWidget({instance:a})})},_setupWideWidget:function(){var a,c,d,e,g,h=this;this.params.is_wide&&(a=this.container.find(".widget-inside"),c=a.find("> .form"),d=b(".wp-full-overlay-sidebar-content:first"),this.container.addClass("wide-widget-control"),this.container.find(".widget-content:first").css({"max-width":this.params.width,"min-height":this.params.height}),g=function(){var d,e=h.container.offset().top,f=b(window).height(),g=c.outerHeight();a.css("max-height",f),d=Math.max(0,Math.min(Math.max(e,0),f-g)),a.css("top",d)},e=b("#customize-theme-controls"),this.container.on("expand",function(){g(),d.on("scroll",g),b(window).on("resize",g),e.on("expanded collapsed",g)}),this.container.on("collapsed",function(){d.off("scroll",g),b(window).off("resize",g),e.off("expanded collapsed",g)}),f.each(function(a){0===a.id.indexOf("sidebars_widgets[")&&a.bind(function(){h.container.hasClass("expanded")&&g()})}))},_setupControlToggle:function(){var a,b=this;this.container.find(".widget-top").on("click",function(a){a.preventDefault();var c=b.getSidebarWidgetsControl();c.isReordering||b.expanded(!b.expanded())}),a=this.container.find(".widget-control-close"),a.on("click",function(a){a.preventDefault(),b.collapse(),b.container.find(".widget-top .widget-action:first").focus()})},_setupWidgetTitle:function(){var a,b=this;a=function(){var a=b.setting().title,c=b.container.find(".in-widget-title");a?c.text(": "+a):c.text("")},this.setting.bind(a),a()},_setupReorderUI:function(){var c,d,g,h,i,j=this;c=function(a){a.siblings(".selected").removeClass("selected"),a.addClass("selected");var b=a.data("id")===j.params.sidebar_id;j.container.find(".move-widget-btn").prop("disabled",b)},this.container.find(".widget-title-action").after(b(f.Widgets.data.tpl.widgetReorderNav)),i=_.template(f.Widgets.data.tpl.moveWidgetArea),d=b(i({sidebars:_(f.Widgets.registeredSidebars.toArray()).pluck("attributes")})),this.container.find(".widget-top").after(d),h=function(){var a,e=d.find("li"),g=0;a=e.filter(function(){return b(this).data("id")===j.params.sidebar_id}),e.each(function(){var d,e,h,i=b(this);d=i.data("id"),e=f.Widgets.registeredSidebars.get(d),h=e.get("is_rendered"),i.toggle(h),h&&(g+=1),i.hasClass("selected")&&!h&&c(a)}),g>1?j.container.find(".move-widget").show():j.container.find(".move-widget").hide()},h(),f.Widgets.registeredSidebars.on("change:is_rendered",h),g=this.container.find(".widget-reorder-nav"),g.find(".move-widget, .move-widget-down, .move-widget-up").each(function(){b(this).prepend(j.container.find(".widget-title").text()+": ")}).on("click keypress",function(c){if("keypress"!==c.type||13===c.which||32===c.which)if(b(this).focus(),b(this).is(".move-widget"))j.toggleWidgetMoveArea();else{var d=b(this).is(".move-widget-down"),f=b(this).is(".move-widget-up"),g=j.getWidgetSidebarPosition();if(f&&0===g||d&&g===j.getSidebarWidgetsControl().setting().length-1)return;f?(j.moveUp(),a.a11y.speak(e.widgetMovedUp)):(j.moveDown(),a.a11y.speak(e.widgetMovedDown)),b(this).focus()}}),this.container.find(".widget-area-select").on("click keypress","li",function(a){("keypress"!==a.type||13===a.which||32===a.which)&&(a.preventDefault(),c(b(this)))}),this.container.find(".move-widget-btn").click(function(){j.getSidebarWidgetsControl().toggleReordering(!1);var a,b,c,d,e,g=j.params.sidebar_id,h=j.container.find(".widget-area-select li.selected").data("id");a=f("sidebars_widgets["+g+"]"),b=f("sidebars_widgets["+h+"]"),c=Array.prototype.slice.call(a()),d=Array.prototype.slice.call(b()),e=j.getWidgetSidebarPosition(),c.splice(e,1),d.push(j.params.widget_id),a(c),b(d),j.focus()})},_setupHighlightEffects:function(){var a=this;this.container.on("mouseenter click",function(){a.setting.previewer.send("highlight-widget",a.params.widget_id)}),this.setting.bind(function(){a.setting.previewer.send("highlight-widget",a.params.widget_id)})},_setupUpdateUI:function(){var a,c,d,g,h,i=this;a=this.container.find(".widget:first"),c=a.find(".widget-content:first"),d=this.container.find(".widget-control-save"),d.val(e.saveBtnLabel),d.attr("title",e.saveBtnTooltip),d.removeClass("button-primary").addClass("button-secondary"),d.on("click",function(a){a.preventDefault(),i.updateWidget({disable_form:!0})}),g=_.debounce(function(){i.updateWidget()},250),c.on("keydown","input",function(a){13===a.which&&(a.preventDefault(),i.updateWidget({ignoreActiveElement:!0}))}),c.on("change input propertychange",":input",function(a){i.liveUpdateMode&&("change"===a.type||this.checkValidity&&this.checkValidity())&&g()}),this.setting.previewer.channel.bind("synced",function(){i.container.removeClass("previewer-loading")}),f.previewer.bind("widget-updated",function(a){a===i.params.widget_id&&i.container.removeClass("previewer-loading")}),h=f.Widgets.formSyncHandlers[this.params.widget_id_base],h&&b(document).on("widget-synced",function(b,c){a.is(c)&&h.apply(document,arguments)})},onChangeActive:function(a,b){this.container.toggleClass("widget-rendered",a),b.completeCallback&&b.completeCallback()},_setupRemoveUI:function(){var a,b,c=this;a=this.container.find("a.widget-control-remove"),a.on("click",function(a){a.preventDefault();var b;b=c.container.next().is(".customize-control-widget_form")?c.container.next().find(".widget-action:first"):c.container.prev().is(".customize-control-widget_form")?c.container.prev().find(".widget-action:first"):c.container.next(".customize-control-sidebar_widgets").find(".add-new-widget:first"),c.container.slideUp(function(){var a,d,e=f.Widgets.getSidebarWidgetControlContainingWidget(c.params.widget_id);e&&(a=e.setting().slice(),d=_.indexOf(a,c.params.widget_id),-1!==d&&(a.splice(d,1),e.setting(a),b.focus()))})}),b=function(){a.text(e.removeBtnLabel),a.attr("title",e.removeBtnTooltip)},this.params.is_new?f.bind("saved",b):b()},_getInputs:function(a){return b(a).find(":input[name]")},_getInputsSignature:function(a){var c=_(a).map(function(a){var c,d=b(a);return c=d.is(":checkbox, :radio")?[d.attr("id"),d.attr("name"),d.prop("value")]:[d.attr("id"),d.attr("name")],c.join(",")});return c.join(";")},_getInputState:function(a){return a=b(a),a.is(":radio, :checkbox")?a.prop("checked"):a.is("select[multiple]")?a.find("option:selected").map(function(){return b(this).val()}).get():a.val()},_setInputState:function(a,c){a=b(a),a.is(":radio, :checkbox")?a.prop("checked",c):a.is("select[multiple]")?(c=b.isArray(c)?_.map(c,function(a){return String(a)}):[],a.find("option").each(function(){b(this).prop("selected",-1!==_.indexOf(c,String(this.value)))})):a.val(c)},getSidebarWidgetsControl:function(){var a,b;return a="sidebars_widgets["+this.params.sidebar_id+"]",(b=f.control(a))?b:void 0},updateWidget:function(c){var d,g,h,i,j,k,l,m,n,o,p,q=this;q.embedWidgetContent(),c=b.extend({instance:null,complete:null,ignoreActiveElement:!1},c),d=c.instance,g=c.complete,this._updateCount+=1,j=this._updateCount,h=this.container.find(".widget:first"),i=h.find(".widget-content:first"),i.find(".widget-error").remove(),this.container.addClass("widget-form-loading"),this.container.addClass("previewer-loading"),n=f.state("processing"),n(n()+1),this.liveUpdateMode||this.container.addClass("widget-form-disabled"),k={},k.action="update-widget",k.wp_customize="on",k.nonce=f.settings.nonce["update-widget"],k.theme=f.settings.theme.stylesheet,k.customized=a.customize.previewer.query().customized,l=b.param(k),m=this._getInputs(i),m.each(function(){b(this).data("state"+j,q._getInputState(this))}),l+=d?"&"+b.param({sanitized_widget_setting:JSON.stringify(d)}):"&"+m.serialize(),l+="&"+i.find("~ :input").serialize(),this._previousUpdateRequest&&this._previousUpdateRequest.abort(),o=b.post(a.ajax.settings.url,l),this._previousUpdateRequest=o,o.done(function(a){var d,k,l,n,o=!1;return"0"===a?(f.previewer.preview.iframe.hide(),void f.previewer.login().done(function(){q.updateWidget(c),f.previewer.preview.iframe.show()})):"-1"===a?void f.previewer.cheatin():void(a.success?(k=b("
    "+a.data.form+"
    "),l=q._getInputs(k),n=q._getInputsSignature(m)===q._getInputsSignature(l),n&&!q.liveUpdateMode&&(q.liveUpdateMode=!0,q.container.removeClass("widget-form-disabled"),q.container.find('input[name="savewidget"]').hide()),n&&q.liveUpdateMode?(m.each(function(a){var d,e,f,g=b(this),h=b(l[a]);d=g.data("state"+j),e=q._getInputState(h),g.data("sanitized",e),f=!_.isEqual(d,e)&&(c.ignoreActiveElement||!g.is(document.activeElement)),f&&q._setInputState(g,e)}),b(document).trigger("widget-synced",[h,a.data.form])):q.liveUpdateMode?(q.liveUpdateMode=!1,q.container.find('input[name="savewidget"]').show(),o=!0):(i.html(a.data.form),q.container.removeClass("widget-form-disabled"),b(document).trigger("widget-updated",[h])),p=!o&&!_(q.setting()).isEqual(a.data.instance),p?(q.isWidgetUpdating=!0,q.setting(a.data.instance),q.isWidgetUpdating=!1):q.container.removeClass("previewer-loading"),g&&g.call(q,null,{noChange:!p,ajaxFinished:!0})):(d=e.error,a.data&&a.data.message&&(d=a.data.message),g?g.call(q,d):i.prepend('

    '+d+"

    ")))}),o.fail(function(a,b){g&&g.call(q,b)}),o.always(function(){q.container.removeClass("widget-form-loading"),m.each(function(){b(this).removeData("state"+j)}),n(n()-1)})},expandControlSection:function(){f.Control.prototype.expand.call(this)},_toggleExpanded:f.Section.prototype._toggleExpanded,expand:f.Section.prototype.expand,expandForm:function(){this.expand()},collapse:f.Section.prototype.collapse,collapseForm:function(){this.collapse()},toggleForm:function(a){"undefined"==typeof a&&(a=!this.expanded()),this.expanded(a)},onChangeExpanded:function(a,b){var c,d,e,g,h=this;return h.embedWidgetControl(),a&&h.embedWidgetContent(),b.unchanged?void(a&&f.Control.prototype.expand.call(h,{completeCallback:b.completeCallback})):(c=this.container.find("div.widget:first"),d=c.find(".widget-inside:first"),void(a?(h.section()&&f.section(h.section())&&h.expandControlSection(),f.control.each(function(a){h.params.type===a.params.type&&h!==a&&a.collapse()}),e=function(){h.container.removeClass("expanding"),h.container.addClass("expanded"),h.container.trigger("expanded")},b.completeCallback&&(g=e,e=function(){g(),b.completeCallback()}),h.params.is_wide?d.fadeIn(b.duration,e):d.slideDown(b.duration,e),h.container.trigger("expand"),h.container.addClass("expanding")):(e=function(){h.container.removeClass("collapsing"),h.container.removeClass("expanded"),h.container.trigger("collapsed")},b.completeCallback&&(g=e,e=function(){g(),b.completeCallback()}),h.container.trigger("collapse"),h.container.addClass("collapsing"),h.params.is_wide?d.fadeOut(b.duration,e):d.slideUp(b.duration,function(){c.css({width:"",margin:""}),e()}))))},getWidgetSidebarPosition:function(){var a,b;return a=this.getSidebarWidgetsControl().setting(),b=_.indexOf(a,this.params.widget_id),-1!==b?b:void 0},moveUp:function(){this._moveWidgetByOne(-1)},moveDown:function(){this._moveWidgetByOne(1)},_moveWidgetByOne:function(a){var b,c,d,e;b=this.getWidgetSidebarPosition(),c=this.getSidebarWidgetsControl().setting,d=Array.prototype.slice.call(c()),e=d[b+a],d[b+a]=this.params.widget_id,d[b]=e,c(d)},toggleWidgetMoveArea:function(a){var c,d=this;c=this.container.find(".move-widget-area"),"undefined"==typeof a&&(a=!c.hasClass("active")),a&&(c.find(".selected").removeClass("selected"),c.find("li").filter(function(){return b(this).data("id")===d.params.sidebar_id}).addClass("selected"),this.container.find(".move-widget-btn").prop("disabled",!0)),c.toggleClass("active",a)},highlightSectionAndControl:function(){var a;a=this.container.is(":hidden")?this.container.closest(".control-section"):this.container,b(".highlighted").removeClass("highlighted"),a.addClass("highlighted"),setTimeout(function(){a.removeClass("highlighted")},500)}}),f.Widgets.WidgetsPanel=f.Panel.extend({ready:function(){var a=this;f.Panel.prototype.ready.call(a),a.deferred.embedded.done(function(){var c,d,g;c=a.container.find(".panel-meta"),d=b("
    ",{"class":"no-widget-areas-rendered-notice"}),d.append(b("",{text:e.noAreasRendered})),c.append(d),g=function(){return 0===_.filter(a.sections(),function(a){return a.active()}).length},d.toggle(g()),f.previewer.deferred.active.done(function(){d.toggle(g())}),f.bind("pane-contents-reflowed",function(){var a="resolved"===f.previewer.deferred.active.state()?"fast":0;g()?d.slideDown(a):d.slideUp(a)})})},isContextuallyActive:function(){var a=this;return a.active()}}),f.Widgets.SidebarSection=f.Section.extend({ready:function(){var a,b=this;f.Section.prototype.ready.call(this),a=f.Widgets.registeredSidebars.get(b.params.sidebarId),b.active.bind(function(b){a.set("is_rendered",b)}),a.set("is_rendered",b.active())}}),f.Widgets.SidebarControl=f.Control.extend({ready:function(){this.$controlSection=this.container.closest(".control-section"),this.$sectionContent=this.container.closest(".accordion-section-content"),this._setupModel(),this._setupSortable(),this._setupAddition(),this._applyCardinalOrderClassNames()},_setupModel:function(){var a=this;this.setting.bind(function(d,e){var g,h,i;h=_(e).difference(d),d=_(d).filter(function(a){var b=c(a);return!!f.Widgets.availableWidgets.findWhere({id_base:b.id_base})}),g=_(d).map(function(b){var c=f.Widgets.getWidgetFormControlForWidget(b);return c||(c=a.addWidget(b)),c}),g.sort(function(a,b){var c=_.indexOf(d,a.params.widget_id),e=_.indexOf(d,b.params.widget_id);return c-e}),i=0,_(g).each(function(b){b.priority(i),b.section(a.section()),i+=1}),a.priority(i),a._applyCardinalOrderClassNames(),_(g).each(function(b){b.params.sidebar_id=a.params.sidebar_id}),_(h).each(function(d){setTimeout(function(){var e,g,h,i,j,k=!1;f.each(function(b){if(b.id!==a.setting.id&&0===b.id.indexOf("sidebars_widgets[")&&"sidebars_widgets[wp_inactive_widgets]"!==b.id){var c,e=b();c=_.indexOf(e,d),-1!==c&&(k=!0)}}),k||(e=f.Widgets.getWidgetFormControlForWidget(d),g=e&&b.contains(document,e.container[0])&&!b.contains(a.$sectionContent[0],e.container[0]),e&&!g&&(f.control.remove(e.id),e.container.remove()),f.Widgets.savedWidgetIds[d]&&(h=f.value("sidebars_widgets[wp_inactive_widgets]")().slice(),h.push(d),f.value("sidebars_widgets[wp_inactive_widgets]")(_(h).unique())),i=c(d).id_base,j=f.Widgets.availableWidgets.findWhere({id_base:i}),j&&!j.get("is_multi")&&j.set("is_disabled",!1))})})})},_setupSortable:function(){var a=this;this.isReordering=!1,this.$sectionContent.sortable({items:"> .customize-control-widget_form",handle:".widget-top",axis:"y",tolerance:"pointer",connectWith:".accordion-section-content:has(.customize-control-sidebar_widgets)",update:function(){var c,d=a.$sectionContent.sortable("toArray");c=b.map(d,function(a){return b("#"+a).find(":input[name=widget-id]").val()}),a.setting(c)}}),this.$controlSection.find(".accordion-section-title").droppable({accept:".customize-control-widget_form",over:function(){var b=f.section(a.section.get());b.expand({allowMultiple:!0,completeCallback:function(){f.section.each(function(a){a.container.find(".customize-control-sidebar_widgets").length&&a.container.find(".accordion-section-content:first").sortable("refreshPositions")})}})}}),this.container.find(".reorder-toggle").on("click",function(){a.toggleReordering(!a.isReordering)})},_setupAddition:function(){var a=this;this.container.find(".add-new-widget").on("click",function(){var c=b(this);a.$sectionContent.hasClass("reordering")||(b("body").hasClass("adding-widget")?(c.attr("aria-expanded","false"),f.Widgets.availableWidgetsPanel.close()):(c.attr("aria-expanded","true"),f.Widgets.availableWidgetsPanel.open(a)))})},_applyCardinalOrderClassNames:function(){var a=[];return _.each(this.setting(),function(b){var c=f.Widgets.getWidgetFormControlForWidget(b);c&&a.push(c)}),0===a.length||1===f.Widgets.registeredSidebars.length&&a.length<=1?void this.container.find(".reorder-toggle").hide():(this.container.find(".reorder-toggle").show(),b(a).each(function(){b(this.container).removeClass("first-widget").removeClass("last-widget").find(".move-widget-down, .move-widget-up").prop("tabIndex",0)}),_.first(a).container.addClass("first-widget").find(".move-widget-up").prop("tabIndex",-1),void _.last(a).container.addClass("last-widget").find(".move-widget-down").prop("tabIndex",-1))},toggleReordering:function(b){var c=this.$sectionContent.find(".add-new-widget"),d=this.container.find(".reorder-toggle"),f=this.$sectionContent.find(".widget-title");b=Boolean(b),b!==this.$sectionContent.hasClass("reordering")&&(this.isReordering=b,this.$sectionContent.toggleClass("reordering",b),b?(_(this.getWidgetFormControls()).each(function(a){a.collapse()}),c.attr({tabindex:"-1","aria-hidden":"true"}),d.attr("aria-label",e.reorderLabelOff),a.a11y.speak(e.reorderModeOn),f.attr("aria-hidden","true")):(c.removeAttr("tabindex aria-hidden"),d.attr("aria-label",e.reorderLabelOn),a.a11y.speak(e.reorderModeOff),f.attr("aria-hidden","false")))},getWidgetFormControls:function(){var a=[];return _(this.setting()).each(function(b){var c=d(b),e=f.control(c);e&&a.push(e)}),a},addWidget:function(a){var d,e,g,h,i,j,k,l,m,n,o=this,p="widget_form",q=c(a),r=q.number,s=q.id_base,t=f.Widgets.availableWidgets.findWhere({id_base:s});return t?r&&!t.get("is_multi")?!1:(t.get("is_multi")&&!r&&(t.set("multi_number",t.get("multi_number")+1),r=t.get("multi_number")),d=b.trim(b("#widget-tpl-"+t.get("id")).html()),t.get("is_multi")?d=d.replace(/<[^<>]+>/g,function(a){return a.replace(/__i__|%i%/g,r)}):t.set("is_disabled",!0),e=b(d),g=b("
  • ").addClass("customize-control").addClass("customize-control-"+p).append(e),g.find("> .widget-icon").remove(),t.get("is_multi")&&(g.find('input[name="widget_number"]').val(r),g.find('input[name="multi_number"]').val(r)),a=g.find('[name="widget-id"]').val(),g.hide(),i="widget_"+t.get("id_base"),t.get("is_multi")&&(i+="["+r+"]"),g.attr("id","customize-control-"+i.replace(/\]/g,"").replace(/\[/g,"-")),j=f.has(i),j||(m={transport:f.Widgets.data.selectiveRefreshableWidgets[t.get("id_base")]?"postMessage":"refresh",previewer:this.setting.previewer},n=f.create(i,i,"",m),n.set({})),h=f.controlConstructor[p],k=new h(i,{params:{settings:{"default":i},content:g,sidebar_id:o.params.sidebar_id,widget_id:a,widget_id_base:t.get("id_base"),type:p,is_new:!j,width:t.get("width"),height:t.get("height"),is_wide:t.get("is_wide"),active:!0},previewer:o.setting.previewer}),f.control.add(i,k),f.each(function(b){if(b.id!==o.setting.id&&0===b.id.indexOf("sidebars_widgets[")){var c=b().slice(),d=_.indexOf(c,a);-1!==d&&(c.splice(d),b(c))}}),l=this.setting().slice(),-1===_.indexOf(l,a)&&(l.push(a),this.setting(l)),g.slideDown(function(){j&&k.updateWidget({instance:k.setting()})}),k):!1}}),b.extend(f.panelConstructor,{widgets:f.Widgets.WidgetsPanel}),b.extend(f.sectionConstructor,{sidebar:f.Widgets.SidebarSection}),b.extend(f.controlConstructor,{widget_form:f.Widgets.WidgetControl,sidebar_widgets:f.Widgets.SidebarControl}),f.bind("ready",function(){f.Widgets.availableWidgetsPanel=new f.Widgets.AvailableWidgetsPanelView({collection:f.Widgets.availableWidgets}),f.previewer.bind("highlight-widget-control",f.Widgets.highlightWidgetFormControl),f.previewer.bind("focus-widget-control",f.Widgets.focusWidgetFormControl)}),f.Widgets.highlightWidgetFormControl=function(a){var b=f.Widgets.getWidgetFormControlForWidget(a);b&&b.highlightSectionAndControl()},f.Widgets.focusWidgetFormControl=function(a){var b=f.Widgets.getWidgetFormControlForWidget(a);b&&b.focus()},f.Widgets.getSidebarWidgetControlContainingWidget=function(a){var b=null;return f.control.each(function(c){"sidebar_widgets"===c.params.type&&-1!==_.indexOf(c.setting(),a)&&(b=c)}),b},f.Widgets.getWidgetFormControlForWidget=function(a){var b=null;return f.control.each(function(c){"widget_form"===c.params.type&&c.params.widget_id===a&&(b=c)}),b}}}(window.wp,jQuery); \ No newline at end of file diff --git a/wp-content/themes/twentyeleven/functions.php b/wp-content/themes/twentyeleven/functions.php index 3ae175650b..bd5fef4356 100644 --- a/wp-content/themes/twentyeleven/functions.php +++ b/wp-content/themes/twentyeleven/functions.php @@ -226,6 +226,9 @@ function twentyeleven_setup() { 'description' => __( 'Hanoi Plant', 'twentyeleven' ) ) ) ); + + // Indicate widget sidebars can use selective refresh in the Customizer. + add_theme_support( 'customize-selective-refresh-widgets' ); } endif; // twentyeleven_setup diff --git a/wp-content/themes/twentyeleven/inc/widgets.php b/wp-content/themes/twentyeleven/inc/widgets.php index 501301ebb2..979b65471f 100644 --- a/wp-content/themes/twentyeleven/inc/widgets.php +++ b/wp-content/themes/twentyeleven/inc/widgets.php @@ -21,6 +21,7 @@ class Twenty_Eleven_Ephemera_Widget extends WP_Widget { parent::__construct( 'widget_twentyeleven_ephemera', __( 'Twenty Eleven Ephemera', 'twentyeleven' ), array( 'classname' => 'widget_twentyeleven_ephemera', 'description' => __( 'Use this widget to list your recent Aside, Status, Quote, and Link posts', 'twentyeleven' ), + 'customize_selective_refresh' => true, ) ); $this->alt_option_name = 'widget_twentyeleven_ephemera'; diff --git a/wp-content/themes/twentyfifteen/functions.php b/wp-content/themes/twentyfifteen/functions.php index 7daeefae7e..618906f39b 100644 --- a/wp-content/themes/twentyfifteen/functions.php +++ b/wp-content/themes/twentyfifteen/functions.php @@ -125,6 +125,9 @@ function twentyfifteen_setup() { * specifically font, colors, icons, and column width. */ add_editor_style( array( 'css/editor-style.css', 'genericons/genericons.css', twentyfifteen_fonts_url() ) ); + + // Indicate widget sidebars can use selective refresh in the Customizer. + add_theme_support( 'customize-selective-refresh-widgets' ); } endif; // twentyfifteen_setup add_action( 'after_setup_theme', 'twentyfifteen_setup' ); diff --git a/wp-content/themes/twentyfourteen/functions.php b/wp-content/themes/twentyfourteen/functions.php index 4e65214a0f..9b7cf0b6d8 100644 --- a/wp-content/themes/twentyfourteen/functions.php +++ b/wp-content/themes/twentyfourteen/functions.php @@ -113,6 +113,9 @@ function twentyfourteen_setup() { // This theme uses its own gallery styles. add_filter( 'use_default_gallery_style', '__return_false' ); + + // Indicate widget sidebars can use selective refresh in the Customizer. + add_theme_support( 'customize-selective-refresh-widgets' ); } endif; // twentyfourteen_setup add_action( 'after_setup_theme', 'twentyfourteen_setup' ); diff --git a/wp-content/themes/twentyfourteen/inc/widgets.php b/wp-content/themes/twentyfourteen/inc/widgets.php index fee265ee3c..ee766cb308 100644 --- a/wp-content/themes/twentyfourteen/inc/widgets.php +++ b/wp-content/themes/twentyfourteen/inc/widgets.php @@ -34,7 +34,28 @@ class Twenty_Fourteen_Ephemera_Widget extends WP_Widget { parent::__construct( 'widget_twentyfourteen_ephemera', __( 'Twenty Fourteen Ephemera', 'twentyfourteen' ), array( 'classname' => 'widget_twentyfourteen_ephemera', 'description' => __( 'Use this widget to list your recent Aside, Quote, Video, Audio, Image, Gallery, and Link posts.', 'twentyfourteen' ), + 'customize_selective_refresh' => true, ) ); + + if ( is_active_widget( false, false, $this->id_base ) || is_customize_preview() ) { + add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); + } + } + + /** + * 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' ); + } } /** diff --git a/wp-content/themes/twentyfourteen/js/functions.js b/wp-content/themes/twentyfourteen/js/functions.js index 1355204308..a21849ec35 100644 --- a/wp-content/themes/twentyfourteen/js/functions.js +++ b/wp-content/themes/twentyfourteen/js/functions.js @@ -146,9 +146,13 @@ } ); _window.load( function() { + var footerSidebar, + isCustomizeSelectiveRefresh = ( 'undefined' !== typeof wp && wp.customize && wp.customize.selectiveRefresh ); + // Arrange footer widgets vertically. if ( $.isFunction( $.fn.masonry ) ) { - $( '#footer-sidebar' ).masonry( { + footerSidebar = $( '#footer-sidebar' ); + footerSidebar.masonry( { itemSelector: '.widget', columnWidth: function( containerWidth ) { return containerWidth / 4; @@ -157,6 +161,41 @@ isResizable: true, isRTL: $( 'body' ).is( '.rtl' ) } ); + + 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' ); + } + } ); + } + } + + // 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(); + } ); } // Initialize Featured Content slider. diff --git a/wp-content/themes/twentythirteen/functions.php b/wp-content/themes/twentythirteen/functions.php index 33c8efd9aa..e1f27ad09b 100644 --- a/wp-content/themes/twentythirteen/functions.php +++ b/wp-content/themes/twentythirteen/functions.php @@ -105,6 +105,9 @@ function twentythirteen_setup() { // This theme uses its own gallery styles. add_filter( 'use_default_gallery_style', '__return_false' ); + + // Indicate widget sidebars can use selective refresh in the Customizer. + add_theme_support( 'customize-selective-refresh-widgets' ); } add_action( 'after_setup_theme', 'twentythirteen_setup' ); diff --git a/wp-content/themes/twentythirteen/js/functions.js b/wp-content/themes/twentythirteen/js/functions.js index d1528557bf..e0d759b9cb 100644 --- a/wp-content/themes/twentythirteen/js/functions.js +++ b/wp-content/themes/twentythirteen/js/functions.js @@ -120,13 +120,42 @@ * Arranges footer widgets vertically. */ if ( $.isFunction( $.fn.masonry ) ) { - var columnWidth = body.is( '.sidebar' ) ? 228 : 245; + var columnWidth = body.is( '.sidebar' ) ? 228 : 245, + widgetArea = $( '#secondary .widget-area' ); - $( '#secondary .widget-area' ).masonry( { + widgetArea.masonry( { itemSelector: '.widget', columnWidth: columnWidth, gutterWidth: 20, isRTL: body.is( '.rtl' ) } ); + + 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' ); + } + } ); + } } } )( jQuery ); \ No newline at end of file diff --git a/wp-content/themes/twentythirteen/js/theme-customizer.js b/wp-content/themes/twentythirteen/js/theme-customizer.js index 8519752c90..60721045cd 100644 --- a/wp-content/themes/twentythirteen/js/theme-customizer.js +++ b/wp-content/themes/twentythirteen/js/theme-customizer.js @@ -38,16 +38,4 @@ } } ); } ); - - 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(); - } - } ); - } - } )( jQuery ); diff --git a/wp-content/themes/twentytwelve/functions.php b/wp-content/themes/twentytwelve/functions.php index e3054474ee..8ec0755e1e 100644 --- a/wp-content/themes/twentytwelve/functions.php +++ b/wp-content/themes/twentytwelve/functions.php @@ -74,6 +74,9 @@ function twentytwelve_setup() { // This theme uses a custom image size for featured images, displayed on "standard" posts. add_theme_support( 'post-thumbnails' ); set_post_thumbnail_size( 624, 9999 ); // Unlimited height, soft crop + + // Indicate widget sidebars can use selective refresh in the Customizer. + add_theme_support( 'customize-selective-refresh-widgets' ); } add_action( 'after_setup_theme', 'twentytwelve_setup' ); diff --git a/wp-includes/class-wp-customize-manager.php b/wp-includes/class-wp-customize-manager.php index ea30b935e9..9a13b6d9a2 100644 --- a/wp-includes/class-wp-customize-manager.php +++ b/wp-includes/class-wp-customize-manager.php @@ -109,7 +109,7 @@ final class WP_Customize_Manager { * @access protected * @var array */ - protected $components = array( 'widgets', 'nav_menus', 'selective_refresh' ); + protected $components = array( 'widgets', 'nav_menus' ); /** * Registered instances of WP_Customize_Section. @@ -258,6 +258,9 @@ final class WP_Customize_Manager { */ $components = apply_filters( 'customize_loaded_components', $this->components, $this ); + require_once( ABSPATH . WPINC . '/customize/class-wp-customize-selective-refresh.php' ); + $this->selective_refresh = new WP_Customize_Selective_Refresh( $this ); + if ( in_array( 'widgets', $components, true ) ) { require_once( ABSPATH . WPINC . '/class-wp-customize-widgets.php' ); $this->widgets = new WP_Customize_Widgets( $this ); @@ -268,11 +271,6 @@ final class WP_Customize_Manager { $this->nav_menus = new WP_Customize_Nav_Menus( $this ); } - 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 ); - } - add_filter( 'wp_die_handler', array( $this, 'wp_die_handler' ) ); add_action( 'setup_theme', array( $this, 'setup_theme' ) ); @@ -1730,7 +1728,6 @@ final class WP_Customize_Manager { 'autofocus' => $this->get_autofocus(), 'documentTitleTmpl' => $this->get_document_title_template(), 'previewableDevices' => $this->get_previewable_devices(), - 'selectiveRefreshEnabled' => isset( $this->selective_refresh ), ); // Prepare Customize Section objects to pass to JavaScript. @@ -1978,14 +1975,12 @@ final class WP_Customize_Manager { ), ) ) ); - 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, - ) ); - } + $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, + ) ); /* Colors */ diff --git a/wp-includes/class-wp-customize-nav-menus.php b/wp-includes/class-wp-customize-nav-menus.php index cb8994c891..778456727c 100644 --- a/wp-includes/class-wp-customize-nav-menus.php +++ b/wp-includes/class-wp-customize-nav-menus.php @@ -393,7 +393,7 @@ final class WP_Customize_Nav_Menus { 'reorderLabelOn' => esc_attr__( 'Reorder menu items' ), 'reorderLabelOff' => esc_attr__( 'Close reorder mode' ), ), - 'settingTransport' => isset( $this->manager->selective_refresh ) ? 'postMessage' : 'refresh', + 'settingTransport' => 'postMessage', 'phpIntMax' => PHP_INT_MAX, 'defaultSettingValues' => array( 'nav_menu' => $temp_nav_menu_setting->default, @@ -445,12 +445,12 @@ final class WP_Customize_Nav_Menus { if ( preg_match( WP_Customize_Nav_Menu_Setting::ID_PATTERN, $setting_id ) ) { $setting_args = array( 'type' => WP_Customize_Nav_Menu_Setting::TYPE, - 'transport' => isset( $this->manager->selective_refresh ) ? 'postMessage' : 'refresh', + 'transport' => 'postMessage', ); } elseif ( preg_match( WP_Customize_Nav_Menu_Item_Setting::ID_PATTERN, $setting_id ) ) { $setting_args = array( 'type' => WP_Customize_Nav_Menu_Item_Setting::TYPE, - 'transport' => isset( $this->manager->selective_refresh ) ? 'postMessage' : 'refresh', + 'transport' => 'postMessage', ); } return $setting_args; @@ -535,7 +535,7 @@ final class WP_Customize_Nav_Menus { $setting = $this->manager->get_setting( $setting_id ); if ( $setting ) { - $setting->transport = isset( $this->manager->selective_refresh ) ? 'postMessage' : 'refresh'; + $setting->transport = 'postMessage'; remove_filter( "customize_sanitize_{$setting_id}", 'absint' ); add_filter( "customize_sanitize_{$setting_id}", array( $this, 'intval_base10' ) ); } else { @@ -543,7 +543,7 @@ final class WP_Customize_Nav_Menus { 'sanitize_callback' => array( $this, 'intval_base10' ), 'theme_supports' => 'menus', 'type' => 'theme_mod', - 'transport' => isset( $this->manager->selective_refresh ) ? 'postMessage' : 'refresh', + 'transport' => 'postMessage', 'default' => 0, ) ); } @@ -570,7 +570,7 @@ final class WP_Customize_Nav_Menus { $nav_menu_setting_id = 'nav_menu[' . $menu_id . ']'; $this->manager->add_setting( new WP_Customize_Nav_Menu_Setting( $this->manager, $nav_menu_setting_id, array( - 'transport' => isset( $this->manager->selective_refresh ) ? 'postMessage' : 'refresh', + 'transport' => 'postMessage', ) ) ); // Add the menu contents. @@ -585,7 +585,7 @@ final class WP_Customize_Nav_Menus { $value['nav_menu_term_id'] = $menu_id; $this->manager->add_setting( new WP_Customize_Nav_Menu_Item_Setting( $this->manager, $menu_item_setting_id, array( 'value' => $value, - 'transport' => isset( $this->manager->selective_refresh ) ? 'postMessage' : 'refresh', + 'transport' => 'postMessage', ) ) ); // Create a control for each menu item. @@ -988,11 +988,6 @@ final class WP_Customize_Nav_Menus { * @access public */ public function customize_preview_enqueue_deps() { - if ( isset( $this->manager->selective_refresh ) ) { - $script = wp_scripts()->registered['customize-preview-nav-menus']; - $script->deps[] = 'customize-selective-refresh'; - } - wp_enqueue_script( 'customize-preview-nav-menus' ); // Note that we have overridden this. wp_enqueue_style( 'customize-preview' ); } diff --git a/wp-includes/class-wp-customize-widgets.php b/wp-includes/class-wp-customize-widgets.php index a417c46904..0b7b7ceac2 100644 --- a/wp-includes/class-wp-customize-widgets.php +++ b/wp-includes/class-wp-customize-widgets.php @@ -61,6 +61,15 @@ final class WP_Customize_Widgets { */ protected $old_sidebars_widgets = array(); + /** + * Mapping of widget ID base to whether it supports selective refresh. + * + * @since 4.5.0 + * @access protected + * @var array + */ + protected $selective_refreshable_widgets; + /** * Mapping of setting type to setting ID pattern. * @@ -69,8 +78,8 @@ final class WP_Customize_Widgets { * @var array */ protected $setting_id_patterns = array( - 'widget_instance' => '/^(widget_.+?)(?:\[(\d+)\])?$/', - 'sidebar_widgets' => '/^sidebars_widgets\[(.+?)\]$/', + 'widget_instance' => '/^widget_(?P.+?)(?:\[(?P\d+)\])?$/', + 'sidebar_widgets' => '/^sidebars_widgets\[(?P.+?)\]$/', ); /** @@ -111,6 +120,46 @@ final class WP_Customize_Widgets { add_action( 'customize_preview_init', array( $this, 'selective_refresh_init' ) ); } + /** + * 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 ] ); + } + /** * Retrieves the widget setting type given a setting ID. * @@ -119,7 +168,7 @@ final class WP_Customize_Widgets { * * @staticvar array $cache * - * @param $setting_id Setting ID. + * @param string $setting_id Setting ID. * @return string|void Setting type. */ protected function get_setting_type( $setting_id ) { @@ -690,7 +739,7 @@ final class WP_Customize_Widgets { 'widgetReorderNav' => $widget_reorder_nav_tpl, 'moveWidgetArea' => $move_widget_area_tpl, ), - 'selectiveRefresh' => isset( $this->manager->selective_refresh ), + 'selectiveRefreshableWidgets' => $this->get_selective_refreshable_widgets(), ); foreach ( $settings['registeredWidgets'] as &$registered_widget ) { @@ -771,16 +820,17 @@ final class WP_Customize_Widgets { $args = array( 'type' => 'option', 'capability' => 'edit_theme_options', - 'transport' => isset( $this->manager->selective_refresh ) ? 'postMessage' : 'refresh', 'default' => array(), ); if ( preg_match( $this->setting_id_patterns['sidebar_widgets'], $id, $matches ) ) { $args['sanitize_callback'] = array( $this, 'sanitize_sidebar_widgets' ); $args['sanitize_js_callback'] = array( $this, 'sanitize_sidebar_widgets_js_instance' ); + $args['transport'] = current_theme_supports( 'customize-selective-refresh-widgets' ) ? 'postMessage' : 'refresh'; } elseif ( preg_match( $this->setting_id_patterns['widget_instance'], $id, $matches ) ) { $args['sanitize_callback'] = array( $this, 'sanitize_widget_instance' ); $args['sanitize_js_callback'] = array( $this, 'sanitize_widget_js_instance' ); + $args['transport'] = $this->is_widget_selective_refreshable( $matches['id_base'] ) ? 'postMessage' : 'refresh'; } $args = array_merge( $args, $overrides ); @@ -893,7 +943,7 @@ final class WP_Customize_Widgets { 'multi_number' => ( $args['_add'] === 'multi' ) ? $args['_multi_num'] : false, 'is_disabled' => $is_disabled, 'id_base' => $id_base, - 'transport' => isset( $this->manager->selective_refresh ) ? 'postMessage' : 'refresh', + 'transport' => $this->is_widget_selective_refreshable( $id_base ) ? 'postMessage' : 'refresh', 'width' => $wp_registered_widget_controls[$widget['id']]['width'], 'height' => $wp_registered_widget_controls[$widget['id']]['height'], 'is_wide' => $this->is_wide_widget( $widget['id'] ), @@ -1025,6 +1075,7 @@ final class WP_Customize_Widgets { */ public function customize_preview_enqueue() { wp_enqueue_script( 'customize-preview-widgets' ); + wp_enqueue_style( 'customize-preview' ); } /** @@ -1060,6 +1111,7 @@ final class WP_Customize_Widgets { */ public function export_preview_data() { global $wp_registered_sidebars, $wp_registered_widgets; + // Prepare Customizer settings to pass to JavaScript. $settings = array( 'renderedSidebars' => array_fill_keys( array_unique( $this->rendered_sidebars ), true ), @@ -1069,7 +1121,7 @@ final class WP_Customize_Widgets { 'l10n' => array( 'widgetTooltip' => __( 'Shift-click to edit this widget.' ), ), - 'selectiveRefresh' => isset( $this->manager->selective_refresh ), + 'selectiveRefreshableWidgets' => $this->get_selective_refreshable_widgets(), ); foreach ( $settings['registeredWidgets'] as &$registered_widget ) { unset( $registered_widget['callback'] ); // may not be JSON-serializeable @@ -1479,6 +1531,9 @@ final class WP_Customize_Widgets { * @return array (Maybe) modified partial arguments. */ public function customize_dynamic_partial_args( $partial_args, $partial_id ) { + if ( ! current_theme_supports( 'customize-selective-refresh-widgets' ) ) { + return $partial_args; + } if ( preg_match( '/^widget\[(?P.+)\]$/', $partial_id, $matches ) ) { if ( false === $partial_args ) { @@ -1506,33 +1561,15 @@ final class WP_Customize_Widgets { * @access public */ public function selective_refresh_init() { - if ( ! isset( $this->manager->selective_refresh ) ) { + if ( ! current_theme_supports( 'customize-selective-refresh-widgets' ) ) { return; } - - add_action( 'wp_enqueue_scripts', array( $this, 'customize_preview_enqueue_deps' ) ); add_filter( 'dynamic_sidebar_params', array( $this, 'filter_dynamic_sidebar_params' ) ); add_filter( 'wp_kses_allowed_html', array( $this, 'filter_wp_kses_allowed_data_attributes' ) ); add_action( 'dynamic_sidebar_before', array( $this, 'start_dynamic_sidebar' ) ); add_action( 'dynamic_sidebar_after', array( $this, 'end_dynamic_sidebar' ) ); } - /** - * 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' ); - } - /** * Inject selective refresh data attributes into widget container elements. * diff --git a/wp-includes/class-wp-widget.php b/wp-includes/class-wp-widget.php index e8f4a1e9bf..bb0de5096e 100644 --- a/wp-includes/class-wp-widget.php +++ b/wp-includes/class-wp-widget.php @@ -155,8 +155,8 @@ class WP_Widget { $this->id_base = empty($id_base) ? preg_replace( '/(wp_)?widget_/', '', strtolower(get_class($this)) ) : strtolower($id_base); $this->name = $name; $this->option_name = 'widget_' . $this->id_base; - $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) ); + $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 ) ); } /** diff --git a/wp-includes/js/customize-preview-widgets.js b/wp-includes/js/customize-preview-widgets.js index 92e7732c83..b22087b64a 100644 --- a/wp-includes/js/customize-preview-widgets.js +++ b/wp-includes/js/customize-preview-widgets.js @@ -12,7 +12,8 @@ wp.customize.widgetsPreview = wp.customize.WidgetCustomizerPreview = (function( preview: null, l10n: { widgetTooltip: '' - } + }, + selectiveRefreshableWidgets: {} }; /** @@ -24,7 +25,7 @@ wp.customize.widgetsPreview = wp.customize.WidgetCustomizerPreview = (function( var self = this; self.preview = api.preview; - if ( api.selectiveRefresh ) { + if ( ! _.isEmpty( self.selectiveRefreshableWidgets ) ) { self.addPartials(); } @@ -38,455 +39,467 @@ wp.customize.widgetsPreview = wp.customize.WidgetCustomizerPreview = (function( } ); }; - if ( api.selectiveRefresh ) { + /** + * Partial representing a widget instance. + * + * @class + * @augments wp.customize.selectiveRefresh.Partial + * @since 4.5.0 + */ + self.WidgetPartial = api.selectiveRefresh.Partial.extend({ /** - * Partial representing a widget instance. + * Constructor. * - * @class - * @augments wp.customize.selectiveRefresh.Partial * @since 4.5.0 + * @param {string} id - Partial ID. + * @param {Object} options + * @param {Object} options.params */ - self.WidgetPartial = api.selectiveRefresh.Partial.extend({ - - /** - * 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.' ); - } - - 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 || {} - ); - - api.selectiveRefresh.Partial.prototype.initialize.call( partial, id, options ); - }, - - /** - * 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 ); - } + initialize: function( id, options ) { + var partial = this, matches; + matches = id.match( /^widget\[(.+)]$/ ); + if ( ! matches ) { + throw new Error( 'Illegal id for widget partial.' ); } - }); + + partial.widgetId = matches[1]; + partial.widgetIdParts = self.parseWidgetId( partial.widgetId ); + options = options || {}; + options.params = _.extend( + { + settings: [ self.getWidgetSettingId( partial.widgetId ) ], + containerInclusive: true + }, + options.params || {} + ); + + api.selectiveRefresh.Partial.prototype.initialize.call( partial, id, options ); + }, /** - * Partial representing a widget area. + * 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 ); + } + }, + + /** + * 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 ); + } + } + }); + + /** + * Partial representing a widget area. + * + * @class + * @augments wp.customize.selectiveRefresh.Partial + * @since 4.5.0 + */ + self.SidebarPartial = api.selectiveRefresh.Partial.extend({ + + /** + * 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]; + + options = options || {}; + options.params = _.extend( + { + settings: [ 'sidebars_widgets[' + partial.sidebarId + ']' ] + }, + options.params || {} + ); + + api.selectiveRefresh.Partial.prototype.initialize.call( partial, id, options ); + + 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' ); + } + }, + + /** + * Set up the partial. * - * @class - * @augments wp.customize.selectiveRefresh.Partial * @since 4.5.0 */ - self.SidebarPartial = api.selectiveRefresh.Partial.extend({ + ready: function() { + var sidebarPartial = this; - /** - * 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]; + // Watch for changes to the sidebar_widgets setting. + _.each( sidebarPartial.settings(), function( settingId ) { + api( settingId ).bind( _.bind( sidebarPartial.handleSettingChange, sidebarPartial ) ); + } ); - options = options || {}; - options.params = _.extend( - { - settings: [ 'sidebars_widgets[' + partial.sidebarId + ']' ] - }, - options.params || {} + // 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 ) ) ); - - api.selectiveRefresh.Partial.prototype.initialize.call( partial, id, options ); - - 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' ); - } - }, - - /** - * Set up the partial. - * - * @since 4.5.0 - */ - ready: function() { - var sidebarPartial = this; - - // Watch for changes to the sidebar_widgets setting. - _.each( sidebarPartial.settings(), function( settingId ) { - api( settingId ).bind( _.bind( sidebarPartial.handleSettingChange, sidebarPartial ) ); - } ); - - // 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.' ); - } - 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 ); - }, - - /** - * Reflow widgets in the sidebar, ensuring they have the proper position in the DOM. - * - * @since 4.5.0 - * - * @return {Array.} 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; - } - } ); - - _.each( sidebarPlacements, function( sidebarPlacement ) { - var sidebarWidgets = [], needsSort = false, thisPosition, lastPosition = -1; - - // 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 ); - } - } ); - - if ( sortedSidebarContainers.length > 0 ) { + if ( isAssignedWidgetPartial ) { api.selectiveRefresh.trigger( 'sidebar-updated', sidebarPartial ); } + } ); - return sortedSidebarContainers; - }, - - /** - * 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 ); + // 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 ); + } + } ); + }, - // 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; - - foundWidgetPlacement = _.find( widgetPartial.placements(), function( widgetPlacement ) { - return ( widgetPlacement.context.sidebar_instance_number === sidebarPlacement.context.instanceNumber ); - } ); - if ( foundWidgetPlacement ) { - return; + /** + * 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 ); } + } ); + }; - widgetContainerElement = $( - sidebarPartial.params.sidebarArgs.before_widget.replace( '%1$s', widgetId ).replace( '%2$s', 'widget' ) + - sidebarPartial.params.sidebarArgs.after_widget - ); + recursiveCommentTraversal( document.body.childNodes ); + return _.values( boundaryNodes ); + }, - widgetContainerElement.attr( 'data-customize-partial-id', widgetPartial.id ); - widgetContainerElement.attr( 'data-customize-partial-type', 'widget' ); - widgetContainerElement.attr( 'data-customize-widget-id', widgetId ); + /** + * 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 + } + } ); + } ); + }, - /* - * 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 + /** + * 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 ); + }, + + /** + * Reflow widgets in the sidebar, ensuring they have the proper position in the DOM. + * + * @since 4.5.0 + * + * @return {Array.} 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; + } + } ); + + _.each( sidebarPlacements, function( sidebarPlacement ) { + var sidebarWidgets = [], needsSort = false, thisPosition, lastPosition = -1; + + // 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; + } } ); - - sidebarPlacement.endNode.parentNode.insertBefore( widgetContainerElement[0], sidebarPlacement.endNode ); - wasInserted = true; } ); - if ( wasInserted ) { - sidebarPartial.reflowWidgets(); + 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 ); } + } ); - return widgetPartial; - }, + if ( sortedSidebarContainers.length > 0 ) { + api.selectiveRefresh.trigger( 'sidebar-updated', sidebarPartial ); + } - /** - * 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 = []; + return sortedSidebarContainers; + }, - needsRefresh = ( - ( oldWidgetIds.length > 0 && 0 === newWidgetIds.length ) || - ( newWidgetIds.length > 0 && 0 === oldWidgetIds.length ) - ); - if ( needsRefresh ) { - sidebarPartial.fallback(); + /** + * 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 ); + } + + // 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; + + foundWidgetPlacement = _.find( widgetPartial.placements(), function( widgetPlacement ) { + return ( widgetPlacement.context.sidebar_instance_number === sidebarPlacement.context.instanceNumber ); + } ); + if ( foundWidgetPlacement ) { 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(); - } - } ); - } + widgetContainerElement = $( + sidebarPartial.params.sidebarArgs.before_widget.replace( '%1$s', widgetId ).replace( '%2$s', 'widget' ) + + sidebarPartial.params.sidebarArgs.after_widget + ); + + 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 } ); - // Handle insertion of widgets. - widgetsAdded = _.difference( newWidgetIds, oldWidgetIds ); - _.each( widgetsAdded, function( addedWidgetId ) { - var widgetPartial = sidebarPartial.ensureWidgetPlacementContainers( addedWidgetId ); - addedWidgetPartials.push( widgetPartial ); - } ); + sidebarPlacement.endNode.parentNode.insertBefore( widgetContainerElement[0], sidebarPlacement.endNode ); + wasInserted = true; + } ); - _.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(); + if ( wasInserted ) { + sidebarPartial.reflowWidgets(); } - }); - api.selectiveRefresh.partialConstructor.sidebar = self.SidebarPartial; - api.selectiveRefresh.partialConstructor.widget = self.WidgetPartial; + return widgetPartial; + }, /** - * Add partials for the registered widget areas (sidebars). + * 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 = []; + + 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(); + } + } ); + } + } ); + + // Handle insertion of widgets. + widgetsAdded = _.difference( newWidgetIds, oldWidgetIds ); + _.each( widgetsAdded, function( addedWidgetId ) { + var widgetPartial = sidebarPartial.ensureWidgetPlacementContainers( addedWidgetId ); + addedWidgetPartials.push( widgetPartial ); + } ); + + _.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 */ - 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 ); - } - } ); - }; + 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; + + /** + * 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 ); + } + } ); + }; /** * Calculate the selector for the sidebar's widgets based on the registered sidebar's info. diff --git a/wp-includes/js/customize-preview-widgets.min.js b/wp-includes/js/customize-preview-widgets.min.js index 923f20d086..05197425b4 100644 --- a/wp-includes/js/customize-preview-widgets.min.js +++ b/wp-includes/js/customize-preview-widgets.min.js @@ -1 +1 @@ -wp.customize.widgetsPreview=wp.customize.WidgetCustomizerPreview=function(a,b,c,d){var e;return e={renderedSidebars:{},renderedWidgets:{},registeredSidebars:[],registeredWidgets:{},widgetSelectors:[],preview:null,l10n:{widgetTooltip:""}},e.init=function(){var a=this;a.preview=d.preview,d.selectiveRefresh&&a.addPartials(),a.buildWidgetSelectors(),a.highlightControls(),a.preview.bind("highlight-widget",a.highlightWidget),d.preview.bind("active",function(){a.highlightControls()})},d.selectiveRefresh&&(e.WidgetPartial=d.selectiveRefresh.Partial.extend({initialize:function(a,c){var f,g=this;if(f=a.match(/^widget\[(.+)]$/),!f)throw new Error("Illegal id for widget partial.");g.widgetId=f[1],c=c||{},c.params=b.extend({selector:'[id="'+g.widgetId+'"]',settings:[e.getWidgetSettingId(g.widgetId)],containerInclusive:!0},c.params||{}),d.selectiveRefresh.Partial.prototype.initialize.call(g,a,c)},renderContent:function(a){var b=this;d.selectiveRefresh.Partial.prototype.renderContent.call(b,a)&&(d.preview.send("widget-updated",b.widgetId),d.selectiveRefresh.trigger("widget-updated",b))}}),e.SidebarPartial=d.selectiveRefresh.Partial.extend({initialize:function(a,c){var e,f=this;if(e=a.match(/^sidebar\[(.+)]$/),!e)throw new Error("Illegal id for sidebar partial.");if(f.sidebarId=e[1],c=c||{},c.params=b.extend({settings:["sidebars_widgets["+f.sidebarId+"]"]},c.params||{}),d.selectiveRefresh.Partial.prototype.initialize.call(f,a,c),!f.params.sidebarArgs)throw new Error("The sidebarArgs param was not provided.");if(f.params.settings.length>1)throw new Error("Expected SidebarPartial to only have one associated setting")},ready:function(){var a=this;b.each(a.settings(),function(c){d(c).bind(b.bind(a.handleSettingChange,a))}),d.selectiveRefresh.bind("partial-content-rendered",function(c){var f=c.partial.extended(e.WidgetPartial)&&-1!==b.indexOf(a.getWidgetIds(),c.partial.widgetId);f&&d.selectiveRefresh.trigger("sidebar-updated",a)}),d.bind("change",function(c){var d,f;f=e.parseWidgetSettingId(c.id),f&&(d=f.idBase,f.number&&(d+="-"+String(f.number)),-1!==b.indexOf(a.getWidgetIds(),d)&&a.ensureWidgetPlacementContainers(d))})},findDynamicSidebarBoundaryNodes:function(){var a,c,d=this,e={};return a=/^(dynamic_sidebar_before|dynamic_sidebar_after):(.+):(\d+)$/,c=function(f){b.each(f,function(f){var g;if(8===f.nodeType){if(g=f.nodeValue.match(a),!g||g[2]!==d.sidebarId)return;b.isUndefined(e[g[3]])&&(e[g[3]]={before:null,after:null,instanceNumber:parseInt(g[3],10)}),"dynamic_sidebar_before"===g[1]?e[g[3]].before=f:e[g[3]].after=f}else 1===f.nodeType&&c(f.childNodes)})},c(document.body.childNodes),b.values(e)},placements:function(){var a=this;return b.map(a.findDynamicSidebarBoundaryNodes(),function(b){return new d.selectiveRefresh.Placement({partial:a,container:null,startNode:b.before,endNode:b.after,context:{instanceNumber:b.instanceNumber}})})},getWidgetIds:function(){var a,c,e=this;if(a=e.settings()[0],!a)throw new Error("Missing associated setting.");if(!d.has(a))throw new Error("Setting does not exist.");if(c=d(a).get(),!b.isArray(c))throw new Error("Expected setting to be array of widget IDs");return c.slice(0)},reflowWidgets:function(){var a,c,e,f=this,g=[];return c=f.getWidgetIds(),a=f.placements(),e={},b.each(c,function(a){var b=d.selectiveRefresh.partial("widget["+a+"]");b&&(e[a]=b)}),b.each(a,function(a){var c,f=[],h=!1,i=-1;b.each(e,function(d){b.each(d.placements(),function(b){a.context.instanceNumber===b.context.sidebar_instance_number&&(c=b.container.index(),f.push({partial:d,placement:b,position:c}),i>c&&(h=!0),i=c)})}),h&&(b.each(f,function(b){a.endNode.parentNode.insertBefore(b.placement.container[0],a.endNode),d.selectiveRefresh.trigger("partial-content-moved",b.placement)}),g.push(a))}),g.length>0&&d.selectiveRefresh.trigger("sidebar-updated",f),g},ensureWidgetPlacementContainers:function(c){var f,g=this,h=!1,i="widget["+c+"]";return f=d.selectiveRefresh.partial(i),f||(f=new e.WidgetPartial(i,{params:{}}),d.selectiveRefresh.partial.add(f.id,f)),b.each(g.placements(),function(d){var e,i;e=b.find(f.placements(),function(a){return a.context.sidebar_instance_number===d.context.instanceNumber}),e||(i=a(g.params.sidebarArgs.before_widget.replace("%1$s",c).replace("%2$s","widget")+g.params.sidebarArgs.after_widget),i.attr("data-customize-partial-id",f.id),i.attr("data-customize-partial-type","widget"),i.attr("data-customize-widget-id",c),i.data("customize-partial-placement-context",{sidebar_id:g.sidebarId,sidebar_instance_number:d.context.instanceNumber}),d.endNode.parentNode.insertBefore(i[0],d.endNode),h=!0)}),h&&g.reflowWidgets(),f},handleSettingChange:function(a,c){var e,f,g,h=this,i=[];return(e=c.length>0&&0===a.length||a.length>0&&0===c.length)?void h.fallback():(f=b.difference(c,a),b.each(f,function(a){var c=d.selectiveRefresh.partial("widget["+a+"]");c&&b.each(c.placements(),function(a){var b=a.context.sidebar_id===h.sidebarId||a.context.sidebar_args&&a.context.sidebar_args.id===h.sidebarId;b&&a.container.remove()})}),g=b.difference(a,c),b.each(g,function(a){var b=h.ensureWidgetPlacementContainers(a);i.push(b)}),b.each(i,function(a){a.refresh()}),void d.selectiveRefresh.trigger("sidebar-updated",h))},refresh:function(){var c=this,e=a.Deferred();return e.fail(function(){c.fallback()}),0===c.placements().length?e.reject():(b.each(c.reflowWidgets(),function(a){d.selectiveRefresh.trigger("partial-content-rendered",a)}),e.resolve()),e.promise()}}),d.selectiveRefresh.partialConstructor.sidebar=e.SidebarPartial,d.selectiveRefresh.partialConstructor.widget=e.WidgetPartial,e.addPartials=function(){b.each(e.registeredSidebars,function(a){var b,c="sidebar["+a.id+"]";b=d.selectiveRefresh.partial(c),b||(b=new e.SidebarPartial(c,{params:{sidebarArgs:a}}),d.selectiveRefresh.partial.add(b.id,b))})}),e.buildWidgetSelectors=function(){var b=this;a.each(b.registeredSidebars,function(c,d){var e,f,g,h=[d.before_widget.replace("%1$s","").replace("%2$s",""),d.before_title,d.after_title,d.after_widget].join("");e=a(h),f=e.prop("tagName"),g=e.prop("className"),g&&(g=g.replace(/^\s+|\s+$/g,""),g&&(f+="."+g.split(/\s+/).join(".")),b.widgetSelectors.push(f))})},e.highlightWidget=function(b){var c=a(document.body),d=a("#"+b);c.find(".widget-customizer-highlighted-widget").removeClass("widget-customizer-highlighted-widget"),d.addClass("widget-customizer-highlighted-widget"),setTimeout(function(){d.removeClass("widget-customizer-highlighted-widget")},500)},e.highlightControls=function(){var b=this,c=this.widgetSelectors.join(",");a(c).attr("title",this.l10n.widgetTooltip),a(document).on("mouseenter",c,function(){b.preview.send("highlight-widget-control",a(this).prop("id"))}),a(document).on("click",c,function(c){c.shiftKey&&(c.preventDefault(),b.preview.send("focus-widget-control",a(this).prop("id")))})},e.parseWidgetId=function(a){var b,c={idBase:"",number:null};return b=a.match(/^(.+)-(\d+)$/),b?(c.idBase=b[1],c.number=parseInt(b[2],10)):c.idBase=a,c},e.parseWidgetSettingId=function(a){var b,c={idBase:"",number:null};return(b=a.match(/^widget_([^\[]+?)(?:\[(\d+)])?$/))?(c.idBase=b[1],b[2]&&(c.number=parseInt(b[2],10)),c):null},e.getWidgetSettingId=function(a){var b,c=this.parseWidgetId(a);return b="widget_"+c.idBase,c.number&&(b+="["+String(c.number)+"]"),b},d.bind("preview-ready",function(){a.extend(e,_wpWidgetCustomizerPreviewSettings),e.init()}),e}(jQuery,_,wp,wp.customize); \ No newline at end of file +wp.customize.widgetsPreview=wp.customize.WidgetCustomizerPreview=function(a,b,c,d){var e;return e={renderedSidebars:{},renderedWidgets:{},registeredSidebars:[],registeredWidgets:{},widgetSelectors:[],preview:null,l10n:{widgetTooltip:""},selectiveRefreshableWidgets:{}},e.init=function(){var a=this;a.preview=d.preview,b.isEmpty(a.selectiveRefreshableWidgets)||a.addPartials(),a.buildWidgetSelectors(),a.highlightControls(),a.preview.bind("highlight-widget",a.highlightWidget),d.preview.bind("active",function(){a.highlightControls()})},e.WidgetPartial=d.selectiveRefresh.Partial.extend({initialize:function(a,c){var f,g=this;if(f=a.match(/^widget\[(.+)]$/),!f)throw new Error("Illegal id for widget partial.");g.widgetId=f[1],g.widgetIdParts=e.parseWidgetId(g.widgetId),c=c||{},c.params=b.extend({settings:[e.getWidgetSettingId(g.widgetId)],containerInclusive:!0},c.params||{}),d.selectiveRefresh.Partial.prototype.initialize.call(g,a,c)},refresh:function(){var b,c=this;return e.selectiveRefreshableWidgets[c.widgetIdParts.idBase]?d.selectiveRefresh.Partial.prototype.refresh.call(c):(b=a.Deferred(),b.reject(),c.fallback(),b.promise())},renderContent:function(a){var b=this;d.selectiveRefresh.Partial.prototype.renderContent.call(b,a)&&(d.preview.send("widget-updated",b.widgetId),d.selectiveRefresh.trigger("widget-updated",b))}}),e.SidebarPartial=d.selectiveRefresh.Partial.extend({initialize:function(a,c){var e,f=this;if(e=a.match(/^sidebar\[(.+)]$/),!e)throw new Error("Illegal id for sidebar partial.");if(f.sidebarId=e[1],c=c||{},c.params=b.extend({settings:["sidebars_widgets["+f.sidebarId+"]"]},c.params||{}),d.selectiveRefresh.Partial.prototype.initialize.call(f,a,c),!f.params.sidebarArgs)throw new Error("The sidebarArgs param was not provided.");if(f.params.settings.length>1)throw new Error("Expected SidebarPartial to only have one associated setting")},ready:function(){var a=this;b.each(a.settings(),function(c){d(c).bind(b.bind(a.handleSettingChange,a))}),d.selectiveRefresh.bind("partial-content-rendered",function(c){var f=c.partial.extended(e.WidgetPartial)&&-1!==b.indexOf(a.getWidgetIds(),c.partial.widgetId);f&&d.selectiveRefresh.trigger("sidebar-updated",a)}),d.bind("change",function(c){var d,f;f=e.parseWidgetSettingId(c.id),f&&(d=f.idBase,f.number&&(d+="-"+String(f.number)),-1!==b.indexOf(a.getWidgetIds(),d)&&a.ensureWidgetPlacementContainers(d))})},findDynamicSidebarBoundaryNodes:function(){var a,c,d=this,e={};return a=/^(dynamic_sidebar_before|dynamic_sidebar_after):(.+):(\d+)$/,c=function(f){b.each(f,function(f){var g;if(8===f.nodeType){if(g=f.nodeValue.match(a),!g||g[2]!==d.sidebarId)return;b.isUndefined(e[g[3]])&&(e[g[3]]={before:null,after:null,instanceNumber:parseInt(g[3],10)}),"dynamic_sidebar_before"===g[1]?e[g[3]].before=f:e[g[3]].after=f}else 1===f.nodeType&&c(f.childNodes)})},c(document.body.childNodes),b.values(e)},placements:function(){var a=this;return b.map(a.findDynamicSidebarBoundaryNodes(),function(b){return new d.selectiveRefresh.Placement({partial:a,container:null,startNode:b.before,endNode:b.after,context:{instanceNumber:b.instanceNumber}})})},getWidgetIds:function(){var a,c,e=this;if(a=e.settings()[0],!a)throw new Error("Missing associated setting.");if(!d.has(a))throw new Error("Setting does not exist.");if(c=d(a).get(),!b.isArray(c))throw new Error("Expected setting to be array of widget IDs");return c.slice(0)},reflowWidgets:function(){var a,c,e,f=this,g=[];return c=f.getWidgetIds(),a=f.placements(),e={},b.each(c,function(a){var b=d.selectiveRefresh.partial("widget["+a+"]");b&&(e[a]=b)}),b.each(a,function(a){var c,f=[],h=!1,i=-1;b.each(e,function(d){b.each(d.placements(),function(b){a.context.instanceNumber===b.context.sidebar_instance_number&&(c=b.container.index(),f.push({partial:d,placement:b,position:c}),i>c&&(h=!0),i=c)})}),h&&(b.each(f,function(b){a.endNode.parentNode.insertBefore(b.placement.container[0],a.endNode),d.selectiveRefresh.trigger("partial-content-moved",b.placement)}),g.push(a))}),g.length>0&&d.selectiveRefresh.trigger("sidebar-updated",f),g},ensureWidgetPlacementContainers:function(c){var f,g=this,h=!1,i="widget["+c+"]";return f=d.selectiveRefresh.partial(i),f||(f=new e.WidgetPartial(i,{params:{}}),d.selectiveRefresh.partial.add(f.id,f)),b.each(g.placements(),function(d){var e,i;e=b.find(f.placements(),function(a){return a.context.sidebar_instance_number===d.context.instanceNumber}),e||(i=a(g.params.sidebarArgs.before_widget.replace("%1$s",c).replace("%2$s","widget")+g.params.sidebarArgs.after_widget),i.attr("data-customize-partial-id",f.id),i.attr("data-customize-partial-type","widget"),i.attr("data-customize-widget-id",c),i.data("customize-partial-placement-context",{sidebar_id:g.sidebarId,sidebar_instance_number:d.context.instanceNumber}),d.endNode.parentNode.insertBefore(i[0],d.endNode),h=!0)}),h&&g.reflowWidgets(),f},handleSettingChange:function(a,c){var e,f,g,h=this,i=[];return(e=c.length>0&&0===a.length||a.length>0&&0===c.length)?void h.fallback():(f=b.difference(c,a),b.each(f,function(a){var c=d.selectiveRefresh.partial("widget["+a+"]");c&&b.each(c.placements(),function(a){var b=a.context.sidebar_id===h.sidebarId||a.context.sidebar_args&&a.context.sidebar_args.id===h.sidebarId;b&&a.container.remove()})}),g=b.difference(a,c),b.each(g,function(a){var b=h.ensureWidgetPlacementContainers(a);i.push(b)}),b.each(i,function(a){a.refresh()}),void d.selectiveRefresh.trigger("sidebar-updated",h))},refresh:function(){var c=this,e=a.Deferred();return e.fail(function(){c.fallback()}),0===c.placements().length?e.reject():(b.each(c.reflowWidgets(),function(a){d.selectiveRefresh.trigger("partial-content-rendered",a)}),e.resolve()),e.promise()}}),d.selectiveRefresh.partialConstructor.sidebar=e.SidebarPartial,d.selectiveRefresh.partialConstructor.widget=e.WidgetPartial,e.addPartials=function(){b.each(e.registeredSidebars,function(a){var b,c="sidebar["+a.id+"]";b=d.selectiveRefresh.partial(c),b||(b=new e.SidebarPartial(c,{params:{sidebarArgs:a}}),d.selectiveRefresh.partial.add(b.id,b))})},e.buildWidgetSelectors=function(){var b=this;a.each(b.registeredSidebars,function(c,d){var e,f,g,h=[d.before_widget.replace("%1$s","").replace("%2$s",""),d.before_title,d.after_title,d.after_widget].join("");e=a(h),f=e.prop("tagName"),g=e.prop("className"),g&&(g=g.replace(/^\s+|\s+$/g,""),g&&(f+="."+g.split(/\s+/).join(".")),b.widgetSelectors.push(f))})},e.highlightWidget=function(b){var c=a(document.body),d=a("#"+b);c.find(".widget-customizer-highlighted-widget").removeClass("widget-customizer-highlighted-widget"),d.addClass("widget-customizer-highlighted-widget"),setTimeout(function(){d.removeClass("widget-customizer-highlighted-widget")},500)},e.highlightControls=function(){var b=this,c=this.widgetSelectors.join(",");a(c).attr("title",this.l10n.widgetTooltip),a(document).on("mouseenter",c,function(){b.preview.send("highlight-widget-control",a(this).prop("id"))}),a(document).on("click",c,function(c){c.shiftKey&&(c.preventDefault(),b.preview.send("focus-widget-control",a(this).prop("id")))})},e.parseWidgetId=function(a){var b,c={idBase:"",number:null};return b=a.match(/^(.+)-(\d+)$/),b?(c.idBase=b[1],c.number=parseInt(b[2],10)):c.idBase=a,c},e.parseWidgetSettingId=function(a){var b,c={idBase:"",number:null};return(b=a.match(/^widget_([^\[]+?)(?:\[(\d+)])?$/))?(c.idBase=b[1],b[2]&&(c.number=parseInt(b[2],10)),c):null},e.getWidgetSettingId=function(a){var b,c=this.parseWidgetId(a);return b="widget_"+c.idBase,c.number&&(b+="["+String(c.number)+"]"),b},d.bind("preview-ready",function(){a.extend(e,_wpWidgetCustomizerPreviewSettings),e.init()}),e}(jQuery,_,wp,wp.customize); \ No newline at end of file diff --git a/wp-includes/js/customize-selective-refresh.js b/wp-includes/js/customize-selective-refresh.js index 89277160cb..7efee3d5f2 100644 --- a/wp-includes/js/customize-selective-refresh.js +++ b/wp-includes/js/customize-selective-refresh.js @@ -109,7 +109,7 @@ wp.customize.selectiveRefresh = ( function( $, api ) { placements: function() { var partial = this, selector; - selector = partial.params.selector; + selector = partial.params.selector || ''; if ( selector ) { selector += ', '; } diff --git a/wp-includes/js/customize-selective-refresh.min.js b/wp-includes/js/customize-selective-refresh.min.js index ed79a08f8a..43ed02f496 100644 --- a/wp-includes/js/customize-selective-refresh.min.js +++ b/wp-includes/js/customize-selective-refresh.min.js @@ -1 +1 @@ -wp.customize.selectiveRefresh=function(a,b){"use strict";var c,d,e;return c={ready:a.Deferred(),data:{partials:{},renderQueryVar:"",l10n:{shiftClickToEdit:""},refreshBuffer:250},currentRequest:null},_.extend(c,b.Events),d=c.Partial=b.Class.extend({id:null,initialize:function(b,c){var d=this;c=c||{},d.id=b,d.params=_.extend({selector:null,settings:[],primarySetting:null,containerInclusive:!1,fallbackRefresh:!0},c.params||{}),d.deferred={},d.deferred.ready=a.Deferred(),d.deferred.ready.done(function(){d.ready()})},ready:function(){var b=this;_.each(_.pluck(b.placements(),"container"),function(b){a(b).attr("title",c.data.l10n.shiftClickToEdit)}),a(document).on("click",b.params.selector,function(c){c.shiftKey&&(c.preventDefault(),_.each(b.placements(),function(d){a(d.container).is(c.currentTarget)&&b.showControl()}))})},placements:function(){var b,c=this;return b=c.params.selector,b&&(b+=", "),b+='[data-customize-partial-id="'+c.id+'"]',a(b).map(function(){var b,d=a(this);if(b=d.data("customize-partial-placement-context"),_.isString(b)&&"{"===b.substr(0,1))throw new Error("context JSON parse error");return new e({partial:c,container:d,context:b})}).get()},settings:function(){var a=this;return a.params.settings&&0!==a.params.settings.length?a.params.settings:a.params.primarySetting?[a.params.primarySetting]:[a.id]},isRelatedSetting:function(a){var c=this;return _.isString(a)&&(a=b(a)),a?-1!==_.indexOf(c.settings(),a.id):!1},showControl:function(){var a=this,c=a.params.primarySetting;c||(c=_.first(a.settings())),b.preview.send("focus-control-for-setting",c)},preparePlacement:function(b){a(b.container).addClass("customize-partial-refreshing")},_pendingRefreshPromise:null,refresh:function(){var a,b=this;return a=c.requestPartial(b),b._pendingRefreshPromise||(_.each(b.placements(),function(a){b.preparePlacement(a)}),a.done(function(a){_.each(a,function(a){b.renderContent(a)})}),a.fail(function(a,c){b.fallback(a,c)}),b._pendingRefreshPromise=a,a.always(function(){b._pendingRefreshPromise=null})),a},renderContent:function(b){var d,e,f=this;if(!b.container)return f.fallback(new Error("no_container"),[b]),!1;if(b.container=a(b.container),!1===b.addedContent)return f.fallback(new Error("missing_render"),[b]),!1;if(!_.isString(b.addedContent))return f.fallback(new Error("non_string_content"),[b]),!1;c.orginalDocumentWrite=document.write,document.write=function(){throw new Error(c.data.l10n.badDocumentWrite)};try{if(d=b.addedContent,wp.emoji&&wp.emoji.parse&&!a.contains(document.head,b.container[0])&&(d=wp.emoji.parse(d)),f.params.containerInclusive)e=a(d),b.context=_.extend(b.context,e.data("customize-partial-placement-context")||{}),e.data("customize-partial-placement-context",b.context),b.removedNodes=b.container,b.container=e,b.removedNodes.replaceWith(b.container),b.container.attr("title",c.data.l10n.shiftClickToEdit);else{for(b.removedNodes=document.createDocumentFragment();b.container[0].firstChild;)b.removedNodes.appendChild(b.container[0].firstChild);b.container.html(d)}b.container.removeClass("customize-render-content-error")}catch(g){"undefined"!=typeof console&&console.error&&console.error(f.id,g)}return document.write=c.orginalDocumentWrite,c.orginalDocumentWrite=null,b.container.removeClass("customize-partial-refreshing"),b.container.data("customize-partial-content-rendered",!0),c.trigger("partial-content-rendered",b),!0},fallback:function(){var a=this;a.params.fallbackRefresh&&c.requestFullRefresh()}}),c.Placement=e=b.Class.extend({partial:null,container:null,startNode:null,endNode:null,context:null,addedContent:null,removedNodes:null,initialize:function(b){var c=this;if(b=_.extend({},b||{}),!b.partial||!b.partial.extended(d))throw new Error("Missing partial");b.context=b.context||{},b.container&&(b.container=a(b.container)),_.extend(c,b)}}),c.partialConstructor={},c.partial=new b.Values({defaultConstructor:d}),c.getCustomizeQuery=function(){var a={};return b.each(function(b,c){b._dirty&&(a[c]=b())}),{wp_customize:"on",nonce:b.settings.nonce.preview,theme:b.settings.theme.stylesheet,customized:JSON.stringify(a)}},c._pendingPartialRequests={},c._debouncedTimeoutId=null,c._currentRequest=null,c.requestFullRefresh=function(){b.preview.send("refresh")},c.requestPartial=function(d){var f;return c._debouncedTimeoutId&&(clearTimeout(c._debouncedTimeoutId),c._debouncedTimeoutId=null),c._currentRequest&&(c._currentRequest.abort(),c._currentRequest=null),f=c._pendingPartialRequests[d.id],f&&"pending"===f.deferred.state()||(f={deferred:a.Deferred(),partial:d},c._pendingPartialRequests[d.id]=f),d=null,c._debouncedTimeoutId=setTimeout(function(){var a,d,f,g;c._debouncedTimeoutId=null,a=c.getCustomizeQuery(),f={},d={},_.each(c._pendingPartialRequests,function(a,b){f[b]=a.partial.placements(),c.partial.has(b)?d[b]=_.map(f[b],function(a){return a.context||{}}):a.deferred.rejectWith(a.partial,[new Error("partial_removed"),f[b]])}),a.partials=JSON.stringify(d),a[c.data.renderQueryVar]="1",g=c._currentRequest=wp.ajax.send(null,{data:a,url:b.settings.url.self}),g.done(function(a){c.trigger("render-partials-response",a),a.errors&&"undefined"!=typeof console&&console.warn&&_.each(a.errors,function(a){console.warn(a)}),_.each(c._pendingPartialRequests,function(b,c){var d;_.isArray(a.contents[c])?(d=_.map(a.contents[c],function(a,d){var g=f[c][d];return g?g.addedContent=a:g=new e({partial:b.partial,addedContent:a}),g}),b.deferred.resolveWith(b.partial,[d])):b.deferred.rejectWith(b.partial,[new Error("unrecognized_partial"),f[c]])}),c._pendingPartialRequests={}}),g.fail(function(a,b){"abort"!==b&&(_.each(c._pendingPartialRequests,function(b,c){b.deferred.rejectWith(b.partial,[a,f[c]])}),c._pendingPartialRequests={})})},c.data.refreshBuffer),f.deferred.promise()},c.addPartials=function(b,d){var f;b||(b=document.documentElement),b=a(b),d=_.extend({triggerRendered:!0},d||{}),f=b.find("[data-customize-partial-id]"),b.is("[data-customize-partial-id]")&&(f=f.add(b)),f.each(function(){var b,f,g,h,i,j=a(this);f=j.data("customize-partial-id"),f&&(i=j.data("customize-partial-placement-context")||{},b=c.partial(f),b||(h=j.data("customize-partial-options")||{},h.constructingContainerContext=j.data("customize-partial-placement-context")||{},g=c.partialConstructor[j.data("customize-partial-type")]||c.Partial,b=new g(f,h),c.partial.add(b.id,b)),d.triggerRendered&&!j.data("customize-partial-content-rendered")&&c.trigger("partial-content-rendered",new e({partial:b,context:i,container:j})),j.data("customize-partial-content-rendered",!0))})},b.bind("preview-ready",function(){var d,e,f;document.head||(document.head=a("head:first")[0]),_.extend(c.data,_customizePartialRefreshExports),_.each(c.data.partials,function(a,b){var d,e=c.partial(b);e?_.extend(e.params,a):(d=c.partialConstructor[a.type]||c.Partial,e=new d(b,{params:a}),c.partial.add(b,e))}),d=function(a,b){var d=this;c.partial.each(function(c){c.isRelatedSetting(d,a,b)&&c.refresh()})},e=function(a){d.call(a,a(),null),a.bind(d)},f=function(a){d.call(a,null,a()),a.unbind(d)},b.bind("add",e),b.bind("remove",f),b.each(function(a){a.bind(d)}),c.addPartials(document.documentElement,{triggerRendered:!1}),"undefined"!=typeof MutationObserver&&(c.mutationObserver=new MutationObserver(function(b){_.each(b,function(b){c.addPartials(a(b.target))})}),c.mutationObserver.observe(document.documentElement,{childList:!0,subtree:!0})),b.selectiveRefresh.bind("partial-content-rendered",function(a){a.container&&c.addPartials(a.container)}),b.preview.bind("active",function(){c.partial.each(function(a){a.deferred.ready.resolve()}),c.partial.bind("add",function(a){a.deferred.ready.resolve()})})}),c}(jQuery,wp.customize); \ No newline at end of file +wp.customize.selectiveRefresh=function(a,b){"use strict";var c,d,e;return c={ready:a.Deferred(),data:{partials:{},renderQueryVar:"",l10n:{shiftClickToEdit:""},refreshBuffer:250},currentRequest:null},_.extend(c,b.Events),d=c.Partial=b.Class.extend({id:null,initialize:function(b,c){var d=this;c=c||{},d.id=b,d.params=_.extend({selector:null,settings:[],primarySetting:null,containerInclusive:!1,fallbackRefresh:!0},c.params||{}),d.deferred={},d.deferred.ready=a.Deferred(),d.deferred.ready.done(function(){d.ready()})},ready:function(){var b=this;_.each(_.pluck(b.placements(),"container"),function(b){a(b).attr("title",c.data.l10n.shiftClickToEdit)}),a(document).on("click",b.params.selector,function(c){c.shiftKey&&(c.preventDefault(),_.each(b.placements(),function(d){a(d.container).is(c.currentTarget)&&b.showControl()}))})},placements:function(){var b,c=this;return b=c.params.selector||"",b&&(b+=", "),b+='[data-customize-partial-id="'+c.id+'"]',a(b).map(function(){var b,d=a(this);if(b=d.data("customize-partial-placement-context"),_.isString(b)&&"{"===b.substr(0,1))throw new Error("context JSON parse error");return new e({partial:c,container:d,context:b})}).get()},settings:function(){var a=this;return a.params.settings&&0!==a.params.settings.length?a.params.settings:a.params.primarySetting?[a.params.primarySetting]:[a.id]},isRelatedSetting:function(a){var c=this;return _.isString(a)&&(a=b(a)),a?-1!==_.indexOf(c.settings(),a.id):!1},showControl:function(){var a=this,c=a.params.primarySetting;c||(c=_.first(a.settings())),b.preview.send("focus-control-for-setting",c)},preparePlacement:function(b){a(b.container).addClass("customize-partial-refreshing")},_pendingRefreshPromise:null,refresh:function(){var a,b=this;return a=c.requestPartial(b),b._pendingRefreshPromise||(_.each(b.placements(),function(a){b.preparePlacement(a)}),a.done(function(a){_.each(a,function(a){b.renderContent(a)})}),a.fail(function(a,c){b.fallback(a,c)}),b._pendingRefreshPromise=a,a.always(function(){b._pendingRefreshPromise=null})),a},renderContent:function(b){var d,e,f=this;if(!b.container)return f.fallback(new Error("no_container"),[b]),!1;if(b.container=a(b.container),!1===b.addedContent)return f.fallback(new Error("missing_render"),[b]),!1;if(!_.isString(b.addedContent))return f.fallback(new Error("non_string_content"),[b]),!1;c.orginalDocumentWrite=document.write,document.write=function(){throw new Error(c.data.l10n.badDocumentWrite)};try{if(d=b.addedContent,wp.emoji&&wp.emoji.parse&&!a.contains(document.head,b.container[0])&&(d=wp.emoji.parse(d)),f.params.containerInclusive)e=a(d),b.context=_.extend(b.context,e.data("customize-partial-placement-context")||{}),e.data("customize-partial-placement-context",b.context),b.removedNodes=b.container,b.container=e,b.removedNodes.replaceWith(b.container),b.container.attr("title",c.data.l10n.shiftClickToEdit);else{for(b.removedNodes=document.createDocumentFragment();b.container[0].firstChild;)b.removedNodes.appendChild(b.container[0].firstChild);b.container.html(d)}b.container.removeClass("customize-render-content-error")}catch(g){"undefined"!=typeof console&&console.error&&console.error(f.id,g)}return document.write=c.orginalDocumentWrite,c.orginalDocumentWrite=null,b.container.removeClass("customize-partial-refreshing"),b.container.data("customize-partial-content-rendered",!0),c.trigger("partial-content-rendered",b),!0},fallback:function(){var a=this;a.params.fallbackRefresh&&c.requestFullRefresh()}}),c.Placement=e=b.Class.extend({partial:null,container:null,startNode:null,endNode:null,context:null,addedContent:null,removedNodes:null,initialize:function(b){var c=this;if(b=_.extend({},b||{}),!b.partial||!b.partial.extended(d))throw new Error("Missing partial");b.context=b.context||{},b.container&&(b.container=a(b.container)),_.extend(c,b)}}),c.partialConstructor={},c.partial=new b.Values({defaultConstructor:d}),c.getCustomizeQuery=function(){var a={};return b.each(function(b,c){b._dirty&&(a[c]=b())}),{wp_customize:"on",nonce:b.settings.nonce.preview,theme:b.settings.theme.stylesheet,customized:JSON.stringify(a)}},c._pendingPartialRequests={},c._debouncedTimeoutId=null,c._currentRequest=null,c.requestFullRefresh=function(){b.preview.send("refresh")},c.requestPartial=function(d){var f;return c._debouncedTimeoutId&&(clearTimeout(c._debouncedTimeoutId),c._debouncedTimeoutId=null),c._currentRequest&&(c._currentRequest.abort(),c._currentRequest=null),f=c._pendingPartialRequests[d.id],f&&"pending"===f.deferred.state()||(f={deferred:a.Deferred(),partial:d},c._pendingPartialRequests[d.id]=f),d=null,c._debouncedTimeoutId=setTimeout(function(){var a,d,f,g;c._debouncedTimeoutId=null,a=c.getCustomizeQuery(),f={},d={},_.each(c._pendingPartialRequests,function(a,b){f[b]=a.partial.placements(),c.partial.has(b)?d[b]=_.map(f[b],function(a){return a.context||{}}):a.deferred.rejectWith(a.partial,[new Error("partial_removed"),f[b]])}),a.partials=JSON.stringify(d),a[c.data.renderQueryVar]="1",g=c._currentRequest=wp.ajax.send(null,{data:a,url:b.settings.url.self}),g.done(function(a){c.trigger("render-partials-response",a),a.errors&&"undefined"!=typeof console&&console.warn&&_.each(a.errors,function(a){console.warn(a)}),_.each(c._pendingPartialRequests,function(b,c){var d;_.isArray(a.contents[c])?(d=_.map(a.contents[c],function(a,d){var g=f[c][d];return g?g.addedContent=a:g=new e({partial:b.partial,addedContent:a}),g}),b.deferred.resolveWith(b.partial,[d])):b.deferred.rejectWith(b.partial,[new Error("unrecognized_partial"),f[c]])}),c._pendingPartialRequests={}}),g.fail(function(a,b){"abort"!==b&&(_.each(c._pendingPartialRequests,function(b,c){b.deferred.rejectWith(b.partial,[a,f[c]])}),c._pendingPartialRequests={})})},c.data.refreshBuffer),f.deferred.promise()},c.addPartials=function(b,d){var f;b||(b=document.documentElement),b=a(b),d=_.extend({triggerRendered:!0},d||{}),f=b.find("[data-customize-partial-id]"),b.is("[data-customize-partial-id]")&&(f=f.add(b)),f.each(function(){var b,f,g,h,i,j=a(this);f=j.data("customize-partial-id"),f&&(i=j.data("customize-partial-placement-context")||{},b=c.partial(f),b||(h=j.data("customize-partial-options")||{},h.constructingContainerContext=j.data("customize-partial-placement-context")||{},g=c.partialConstructor[j.data("customize-partial-type")]||c.Partial,b=new g(f,h),c.partial.add(b.id,b)),d.triggerRendered&&!j.data("customize-partial-content-rendered")&&c.trigger("partial-content-rendered",new e({partial:b,context:i,container:j})),j.data("customize-partial-content-rendered",!0))})},b.bind("preview-ready",function(){var d,e,f;document.head||(document.head=a("head:first")[0]),_.extend(c.data,_customizePartialRefreshExports),_.each(c.data.partials,function(a,b){var d,e=c.partial(b);e?_.extend(e.params,a):(d=c.partialConstructor[a.type]||c.Partial,e=new d(b,{params:a}),c.partial.add(b,e))}),d=function(a,b){var d=this;c.partial.each(function(c){c.isRelatedSetting(d,a,b)&&c.refresh()})},e=function(a){d.call(a,a(),null),a.bind(d)},f=function(a){d.call(a,null,a()),a.unbind(d)},b.bind("add",e),b.bind("remove",f),b.each(function(a){a.bind(d)}),c.addPartials(document.documentElement,{triggerRendered:!1}),"undefined"!=typeof MutationObserver&&(c.mutationObserver=new MutationObserver(function(b){_.each(b,function(b){c.addPartials(a(b.target))})}),c.mutationObserver.observe(document.documentElement,{childList:!0,subtree:!0})),b.selectiveRefresh.bind("partial-content-rendered",function(a){a.container&&c.addPartials(a.container)}),b.preview.bind("active",function(){c.partial.each(function(a){a.deferred.ready.resolve()}),c.partial.bind("add",function(a){a.deferred.ready.resolve()})})}),c}(jQuery,wp.customize); \ No newline at end of file diff --git a/wp-includes/script-loader.php b/wp-includes/script-loader.php index 9b4643fc2d..63bbab2110 100644 --- a/wp-includes/script-loader.php +++ b/wp-includes/script-loader.php @@ -455,10 +455,10 @@ function wp_default_scripts( &$scripts ) { $scripts->add( 'customize-selective-refresh', "/wp-includes/js/customize-selective-refresh$suffix.js", array( 'jquery', 'wp-util', 'customize-preview' ), false, 1 ); $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 ); - $scripts->add( 'customize-preview-widgets', "/wp-includes/js/customize-preview-widgets$suffix.js", array( 'jquery', 'wp-util', 'customize-preview' ), false, 1 ); + $scripts->add( 'customize-preview-widgets', "/wp-includes/js/customize-preview-widgets$suffix.js", array( 'jquery', 'wp-util', 'customize-preview', 'customize-selective-refresh' ), false, 1 ); $scripts->add( 'customize-nav-menus', "/wp-admin/js/customize-nav-menus$suffix.js", array( 'jquery', 'wp-backbone', 'customize-controls', 'accordion', 'nav-menu' ), false, 1 ); - $scripts->add( 'customize-preview-nav-menus', "/wp-includes/js/customize-preview-nav-menus$suffix.js", array( 'jquery', 'wp-util', 'customize-preview' ), false, 1 ); + $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 ); $scripts->add( 'accordion', "/wp-admin/js/accordion$suffix.js", array( 'jquery' ), false, 1 ); diff --git a/wp-includes/theme.php b/wp-includes/theme.php index 15681e5a39..1ad720c4f6 100644 --- a/wp-includes/theme.php +++ b/wp-includes/theme.php @@ -1914,7 +1914,7 @@ function current_theme_supports( $feature ) { * * The dynamic portion of the hook name, `$feature`, refers to the specific theme * feature. Possible values include 'post-formats', 'post-thumbnails', 'custom-background', - * 'custom-header', 'menus', 'automatic-feed-links', and 'html5'. + * 'custom-header', 'menus', 'automatic-feed-links', 'html5', and `customize-selective-refresh-widgets`. * * @since 3.4.0 * diff --git a/wp-includes/version.php b/wp-includes/version.php index fc1f29a4f9..330e4176af 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -4,7 +4,7 @@ * * @global string $wp_version */ -$wp_version = '4.5-beta4-37039'; +$wp_version = '4.5-beta4-37040'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema. diff --git a/wp-includes/widgets/class-wp-nav-menu-widget.php b/wp-includes/widgets/class-wp-nav-menu-widget.php index d6ac26c948..d465525913 100644 --- a/wp-includes/widgets/class-wp-nav-menu-widget.php +++ b/wp-includes/widgets/class-wp-nav-menu-widget.php @@ -23,7 +23,10 @@ * @access public */ public function __construct() { - $widget_ops = array( 'description' => __('Add a custom menu to your sidebar.') ); + $widget_ops = array( + 'description' => __( 'Add a custom menu to your sidebar.' ), + 'customize_selective_refresh' => true, + ); parent::__construct( 'nav_menu', __('Custom Menu'), $widget_ops ); } diff --git a/wp-includes/widgets/class-wp-widget-archives.php b/wp-includes/widgets/class-wp-widget-archives.php index 30e4ee0db2..ba12572bcb 100644 --- a/wp-includes/widgets/class-wp-widget-archives.php +++ b/wp-includes/widgets/class-wp-widget-archives.php @@ -23,7 +23,11 @@ class WP_Widget_Archives extends WP_Widget { * @access public */ public function __construct() { - $widget_ops = array('classname' => 'widget_archive', 'description' => __( 'A monthly archive of your site’s Posts.') ); + $widget_ops = array( + 'classname' => 'widget_archive', + 'description' => __( 'A monthly archive of your site’s Posts.' ), + 'customize_selective_refresh' => true, + ); parent::__construct('archives', __('Archives'), $widget_ops); } diff --git a/wp-includes/widgets/class-wp-widget-calendar.php b/wp-includes/widgets/class-wp-widget-calendar.php index 2a8911ad2b..99696780f1 100644 --- a/wp-includes/widgets/class-wp-widget-calendar.php +++ b/wp-includes/widgets/class-wp-widget-calendar.php @@ -33,8 +33,12 @@ class WP_Widget_Calendar extends WP_Widget { * @access public */ public function __construct() { - $widget_ops = array('classname' => 'widget_calendar', 'description' => __( 'A calendar of your site’s Posts.') ); - parent::__construct('calendar', __('Calendar'), $widget_ops); + $widget_ops = array( + 'classname' => 'widget_calendar', + 'description' => __( 'A calendar of your site’s Posts.' ), + 'customize_selective_refresh' => true, + ); + parent::__construct( 'calendar', __( 'Calendar' ), $widget_ops ); } /** diff --git a/wp-includes/widgets/class-wp-widget-categories.php b/wp-includes/widgets/class-wp-widget-categories.php index 058fd9007a..2fbc62a2e8 100644 --- a/wp-includes/widgets/class-wp-widget-categories.php +++ b/wp-includes/widgets/class-wp-widget-categories.php @@ -23,8 +23,12 @@ class WP_Widget_Categories extends WP_Widget { * @access public */ public function __construct() { - $widget_ops = array( 'classname' => 'widget_categories', 'description' => __( "A list or dropdown of categories." ) ); - parent::__construct('categories', __('Categories'), $widget_ops); + $widget_ops = array( + 'classname' => 'widget_categories', + 'description' => __( 'A list or dropdown of categories.' ), + 'customize_selective_refresh' => true, + ); + parent::__construct( 'categories', __( 'Categories' ), $widget_ops ); } /** diff --git a/wp-includes/widgets/class-wp-widget-links.php b/wp-includes/widgets/class-wp-widget-links.php index 96ecc77998..68d86f16d7 100644 --- a/wp-includes/widgets/class-wp-widget-links.php +++ b/wp-includes/widgets/class-wp-widget-links.php @@ -23,8 +23,11 @@ class WP_Widget_Links extends WP_Widget { * @access public */ public function __construct() { - $widget_ops = array('description' => __( "Your blogroll" ) ); - parent::__construct('links', __('Links'), $widget_ops); + $widget_ops = array( + 'description' => __( 'Your blogroll' ), + 'customize_selective_refresh' => true, + ); + parent::__construct( 'links', __( 'Links' ), $widget_ops ); } /** diff --git a/wp-includes/widgets/class-wp-widget-meta.php b/wp-includes/widgets/class-wp-widget-meta.php index c12238f9ab..2de9844a52 100644 --- a/wp-includes/widgets/class-wp-widget-meta.php +++ b/wp-includes/widgets/class-wp-widget-meta.php @@ -25,8 +25,12 @@ class WP_Widget_Meta extends WP_Widget { * @access public */ public function __construct() { - $widget_ops = array('classname' => 'widget_meta', 'description' => __( "Login, RSS, & WordPress.org links.") ); - parent::__construct('meta', __('Meta'), $widget_ops); + $widget_ops = array( + 'classname' => 'widget_meta', + 'description' => __( 'Login, RSS, & WordPress.org links.' ), + 'customize_selective_refresh' => true, + ); + parent::__construct( 'meta', __( 'Meta' ), $widget_ops ); } /** diff --git a/wp-includes/widgets/class-wp-widget-pages.php b/wp-includes/widgets/class-wp-widget-pages.php index e8737acb85..165f33487d 100644 --- a/wp-includes/widgets/class-wp-widget-pages.php +++ b/wp-includes/widgets/class-wp-widget-pages.php @@ -23,8 +23,12 @@ class WP_Widget_Pages extends WP_Widget { * @access public */ public function __construct() { - $widget_ops = array('classname' => 'widget_pages', 'description' => __( 'A list of your site’s Pages.') ); - parent::__construct('pages', __('Pages'), $widget_ops); + $widget_ops = array( + 'classname' => 'widget_pages', + 'description' => __( 'A list of your site’s Pages.' ), + 'customize_selective_refresh' => true, + ); + parent::__construct( 'pages', __( 'Pages' ), $widget_ops ); } /** diff --git a/wp-includes/widgets/class-wp-widget-recent-comments.php b/wp-includes/widgets/class-wp-widget-recent-comments.php index 0f1a3b53e9..71fb4d2f5a 100644 --- a/wp-includes/widgets/class-wp-widget-recent-comments.php +++ b/wp-includes/widgets/class-wp-widget-recent-comments.php @@ -23,12 +23,17 @@ class WP_Widget_Recent_Comments extends WP_Widget { * @access public */ public function __construct() { - $widget_ops = array('classname' => 'widget_recent_comments', 'description' => __( 'Your site’s most recent comments.' ) ); - parent::__construct('recent-comments', __('Recent Comments'), $widget_ops); + $widget_ops = array( + 'classname' => 'widget_recent_comments', + 'description' => __( 'Your site’s most recent comments.' ), + 'customize_selective_refresh' => true, + ); + parent::__construct( 'recent-comments', __( 'Recent Comments' ), $widget_ops ); $this->alt_option_name = 'widget_recent_comments'; - if ( is_active_widget(false, false, $this->id_base) ) - add_action( 'wp_head', array($this, 'recent_comments_style') ); + if ( is_active_widget( false, false, $this->id_base ) || is_customize_preview() ) { + add_action( 'wp_head', array( $this, 'recent_comments_style' ) ); + } } /** diff --git a/wp-includes/widgets/class-wp-widget-recent-posts.php b/wp-includes/widgets/class-wp-widget-recent-posts.php index 8f92bf36cd..fdb54a0ff2 100644 --- a/wp-includes/widgets/class-wp-widget-recent-posts.php +++ b/wp-includes/widgets/class-wp-widget-recent-posts.php @@ -23,8 +23,12 @@ class WP_Widget_Recent_Posts extends WP_Widget { * @access public */ public function __construct() { - $widget_ops = array('classname' => 'widget_recent_entries', 'description' => __( "Your site’s most recent Posts.") ); - parent::__construct('recent-posts', __('Recent Posts'), $widget_ops); + $widget_ops = array( + 'classname' => 'widget_recent_entries', + 'description' => __( 'Your site’s most recent Posts.' ), + 'customize_selective_refresh' => true, + ); + parent::__construct( 'recent-posts', __( 'Recent Posts' ), $widget_ops ); $this->alt_option_name = 'widget_recent_entries'; } diff --git a/wp-includes/widgets/class-wp-widget-rss.php b/wp-includes/widgets/class-wp-widget-rss.php index b477a6e42e..a2548c4e1a 100644 --- a/wp-includes/widgets/class-wp-widget-rss.php +++ b/wp-includes/widgets/class-wp-widget-rss.php @@ -23,9 +23,12 @@ class WP_Widget_RSS extends WP_Widget { * @access public */ public function __construct() { - $widget_ops = array( 'description' => __('Entries from any RSS or Atom feed.') ); + $widget_ops = array( + 'description' => __( 'Entries from any RSS or Atom feed.' ), + 'customize_selective_refresh' => true, + ); $control_ops = array( 'width' => 400, 'height' => 200 ); - parent::__construct( 'rss', __('RSS'), $widget_ops, $control_ops ); + parent::__construct( 'rss', __( 'RSS' ), $widget_ops, $control_ops ); } /** diff --git a/wp-includes/widgets/class-wp-widget-search.php b/wp-includes/widgets/class-wp-widget-search.php index 29bbbf8a5d..f7d67bb5b4 100644 --- a/wp-includes/widgets/class-wp-widget-search.php +++ b/wp-includes/widgets/class-wp-widget-search.php @@ -23,7 +23,11 @@ class WP_Widget_Search extends WP_Widget { * @access public */ public function __construct() { - $widget_ops = array('classname' => 'widget_search', 'description' => __( "A search form for your site.") ); + $widget_ops = array( + 'classname' => 'widget_search', + 'description' => __( 'A search form for your site.' ), + 'customize_selective_refresh' => true, + ); parent::__construct( 'search', _x( 'Search', 'Search widget' ), $widget_ops ); } diff --git a/wp-includes/widgets/class-wp-widget-tag-cloud.php b/wp-includes/widgets/class-wp-widget-tag-cloud.php index 4115c79387..1251e1d29e 100644 --- a/wp-includes/widgets/class-wp-widget-tag-cloud.php +++ b/wp-includes/widgets/class-wp-widget-tag-cloud.php @@ -23,8 +23,11 @@ class WP_Widget_Tag_Cloud extends WP_Widget { * @access public */ public function __construct() { - $widget_ops = array( 'description' => __( "A cloud of your most used tags.") ); - parent::__construct('tag_cloud', __('Tag Cloud'), $widget_ops); + $widget_ops = array( + 'description' => __( 'A cloud of your most used tags.' ), + 'customize_selective_refresh' => true, + ); + parent::__construct( 'tag_cloud', __( 'Tag Cloud' ), $widget_ops ); } /** diff --git a/wp-includes/widgets/class-wp-widget-text.php b/wp-includes/widgets/class-wp-widget-text.php index 5a1a056a54..a8ec3d4fd8 100644 --- a/wp-includes/widgets/class-wp-widget-text.php +++ b/wp-includes/widgets/class-wp-widget-text.php @@ -23,9 +23,13 @@ class WP_Widget_Text extends WP_Widget { * @access public */ public function __construct() { - $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); + $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 ); } /**