diff --git a/wp-admin/js/customize-controls.js b/wp-admin/js/customize-controls.js index 7d41d213ba..d53d951d92 100644 --- a/wp-admin/js/customize-controls.js +++ b/wp-admin/js/customize-controls.js @@ -1,8 +1,6 @@ /* globals _wpCustomizeHeader, _wpMediaViewsL10n */ (function( exports, $ ){ - var bubbleChildValueChanges, Container, focus, isKeydownButNotEnterEvent, areElementListsEqual, prioritySort, api = wp.customize; - - // @todo Move private helper functions to wp.customize.utils so they can be unit tested + var Container, focus, api = wp.customize; /** * @class @@ -32,13 +30,18 @@ } }); + /** + * Utility function namespace + */ + api.utils = {}; + /** * Watch all changes to Value properties, and bubble changes to parent Values instance * * @param {wp.customize.Class} instance * @param {Array} properties The names of the Value instances to watch. */ - bubbleChildValueChanges = function ( instance, properties ) { + api.utils.bubbleChildValueChanges = function ( instance, properties ) { $.each( properties, function ( i, key ) { instance[ key ].bind( function ( to, from ) { if ( instance.parent && to !== from ) { @@ -86,7 +89,7 @@ * @param {(wp.customize.Panel|wp.customize.Section|wp.customize.Control)} b * @returns {Number} */ - prioritySort = function ( a, b ) { + api.utils.prioritySort = function ( a, b ) { if ( a.priority() === b.priority() && typeof a.params.instanceNumber === 'number' && typeof b.params.instanceNumber === 'number' ) { return a.params.instanceNumber - b.params.instanceNumber; } else { @@ -100,7 +103,7 @@ * @param {jQuery.Event} event * @returns {boolean} */ - isKeydownButNotEnterEvent = function ( event ) { + api.utils.isKeydownButNotEnterEvent = function ( event ) { return ( 'keydown' === event.type && 13 !== event.which ); }; @@ -111,7 +114,7 @@ * @param {Array|jQuery} listB * @returns {boolean} */ - areElementListsEqual = function ( listA, listB ) { + api.utils.areElementListsEqual = function ( listA, listB ) { var equal = ( listA.length === listB.length && // if lists are different lengths, then naturally they are not equal -1 === _.map( // are there any false values in the list returned by map? @@ -142,7 +145,7 @@ container.container = $( container.params.content ); container.deferred = { - ready: new $.Deferred() + embedded: new $.Deferred() }; container.priority = new api.Value(); container.active = new api.Value(); @@ -155,22 +158,20 @@ args = $.extend( {}, container.defaultActiveArguments, args ); active = ( active && container.isContextuallyActive() ); container.onChangeActive( active, args ); - // @todo trigger 'activated' and 'deactivated' events based on the expanded param? }); container.expanded.bind( function ( expanded ) { var args = container.expandedArgumentsQueue.shift(); args = $.extend( {}, container.defaultExpandedArguments, args ); container.onChangeExpanded( expanded, args ); - // @todo trigger 'expanded' and 'collapsed' events based on the expanded param? }); container.attachEvents(); - bubbleChildValueChanges( container, [ 'priority', 'active' ] ); + api.utils.bubbleChildValueChanges( container, [ 'priority', 'active' ] ); container.priority.set( isNaN( container.params.priority ) ? 100 : container.params.priority ); container.active.set( container.params.active ); - container.expanded.set( false ); // @todo True if deeplinking? + container.expanded.set( false ); }, /** @@ -193,7 +194,7 @@ children.push( child ); } } ); - children.sort( prioritySort ); + children.sort( api.utils.prioritySort ); return children; }, @@ -202,7 +203,7 @@ * @abstract */ isContextuallyActive: function () { - throw new Error( 'Must override with subclass.' ); + throw new Error( 'Container.isContextuallyActive() must be overridden in a subclass.' ); }, /** @@ -335,10 +336,10 @@ $( section.container ).toggleClass( 'control-subsection', !! id ); }); section.panel.set( section.params.panel || '' ); - bubbleChildValueChanges( section, [ 'panel' ] ); + api.utils.bubbleChildValueChanges( section, [ 'panel' ] ); section.embed(); - section.deferred.ready.done( function () { + section.deferred.embedded.done( function () { section.ready(); }); }, @@ -356,12 +357,12 @@ // The panel has been supplied, so wait until the panel object is registered api.panel( panelId, function ( panel ) { // The panel has been registered, wait for it to become ready/initialized - panel.deferred.ready.done( function () { + panel.deferred.embedded.done( function () { parentContainer = panel.container.find( 'ul:first' ); if ( ! section.container.parent().is( parentContainer ) ) { parentContainer.append( section.container ); } - section.deferred.ready.resolve(); // @todo Better to use `embedded` instead of `ready` + section.deferred.embedded.resolve(); }); } ); } else { @@ -370,7 +371,7 @@ if ( ! section.container.parent().is( parentContainer ) ) { parentContainer.append( section.container ); } - section.deferred.ready.resolve(); + section.deferred.embedded.resolve(); } }; section.panel.bind( inject ); @@ -385,7 +386,7 @@ // Expand/Collapse accordion sections on click. section.container.find( '.accordion-section-title' ).on( 'click keydown', function( event ) { - if ( isKeydownButNotEnterEvent( event ) ) { + if ( api.utils.isKeydownButNotEnterEvent( event ) ) { return; } event.preventDefault(); // Keep this AFTER the key filter above @@ -479,7 +480,7 @@ var panel = this; Container.prototype.initialize.call( panel, id, options ); panel.embed(); - panel.deferred.ready.done( function () { + panel.deferred.embedded.done( function () { panel.ready(); }); }, @@ -494,7 +495,7 @@ if ( ! panel.container.parent().is( parentContainer ) ) { parentContainer.append( panel.container ); } - panel.deferred.ready.resolve(); + panel.deferred.embedded.resolve(); }, /** @@ -505,7 +506,7 @@ // Expand/Collapse accordion sections on click. panel.container.find( '.accordion-section-title' ).on( 'click keydown', function( event ) { - if ( isKeydownButNotEnterEvent( event ) ) { + if ( api.utils.isKeydownButNotEnterEvent( event ) ) { return; } event.preventDefault(); // Keep this AFTER the key filter above @@ -518,7 +519,7 @@ meta = panel.container.find( '.panel-meta:first' ); meta.find( '> .accordion-section-title' ).on( 'click keydown', function( event ) { - if ( isKeydownButNotEnterEvent( event ) ) { + if ( api.utils.isKeydownButNotEnterEvent( event ) ) { return; } event.preventDefault(); // Keep this AFTER the key filter above @@ -676,7 +677,7 @@ control.container = control.params.content ? $( control.params.content ) : $( control.selector ); control.deferred = { - ready: new $.Deferred() + embedded: new $.Deferred() }; control.section = new api.Value(); control.priority = new api.Value(); @@ -720,7 +721,7 @@ control.priority.set( isNaN( control.params.priority ) ? 10 : control.params.priority ); control.active.set( control.params.active ); - bubbleChildValueChanges( control, [ 'section', 'priority', 'active' ] ); + api.utils.bubbleChildValueChanges( control, [ 'section', 'priority', 'active' ] ); // Associate this control with its settings when they are created settings = $.map( control.params.settings, function( value ) { @@ -739,7 +740,7 @@ control.embed(); }) ); - control.deferred.ready.done( function () { + control.deferred.embedded.done( function () { control.ready(); }); }, @@ -760,13 +761,13 @@ // Wait for the section to be registered api.section( sectionId, function ( section ) { // Wait for the section to be ready/initialized - section.deferred.ready.done( function () { + section.deferred.embedded.done( function () { parentContainer = section.container.find( 'ul:first' ); if ( ! control.container.parent().is( parentContainer ) ) { parentContainer.append( control.container ); control.renderContent(); } - control.deferred.ready.resolve(); // @todo Better to use `embedded` instead of `ready` + control.deferred.embedded.resolve(); }); }); }; @@ -852,7 +853,7 @@ // Support the .dropdown class to open/close complex elements this.container.on( 'click keydown', '.dropdown', function( event ) { - if ( isKeydownButNotEnterEvent( event ) ) { + if ( api.utils.isKeydownButNotEnterEvent( event ) ) { return; } @@ -935,7 +936,7 @@ * When the control's DOM structure is ready, * set up internal event bindings. */ - ready: function() { + ready: function() { var control = this; // Shortcut so that we don't have to use _.bind every time we add a callback. _.bindAll( control, 'restoreDefault', 'removeFile', 'openFrame', 'select' ); @@ -954,9 +955,9 @@ * Open the media modal. */ openFrame: function( event ) { - if ( event.type === 'keydown' && 13 !== event.which ) { // enter + if ( api.utils.isKeydownButNotEnterEvent( event ) ) { return; - } + } event.preventDefault(); @@ -984,11 +985,11 @@ text: this.params.button_labels.frame_button }, multiple: false - }); + }); // When a file is selected, run a callback. this.frame.on( 'select', this.select ); - }, + }, /** * Callback handler for when an attachment is selected in the media modal. @@ -1008,7 +1009,7 @@ * Reset the setting to the default value. */ restoreDefault: function( event ) { - if ( event.type === 'keydown' && 13 !== event.which ) { // enter + if ( api.utils.isKeydownButNotEnterEvent( event ) ) { return; } event.preventDefault(); @@ -1023,22 +1024,22 @@ * @param {object} event jQuery Event object */ removeFile: function( event ) { - if ( event.type === 'keydown' && 13 !== event.which ) { // enter + if ( api.utils.isKeydownButNotEnterEvent( event ) ) { return; - } + } event.preventDefault(); this.params.attachment = {}; this.setting( '' ); this.renderContent(); // Not bound to setting change when emptying. - }, + }, // @deprecated success: function() {}, // @deprecated removerVisibility: function() {} - }); + }); /** * A control for uploading images. @@ -1742,8 +1743,9 @@ api.l10n = window._wpCustomizeControlsL10n; // Check if we can run the Customizer. - if ( ! api.settings ) + if ( ! api.settings ) { return; + } // Redirect to the fallback preview if any incompatibilities are found. if ( ! $.support.postMessage || ( ! $.support.cors && api.settings.isCrossDomain ) ) @@ -1768,7 +1770,7 @@ // Expand/Collapse the main customizer customize info $( '#customize-info' ).find( '> .accordion-section-title' ).on( 'click keydown', function( event ) { - if ( isKeydownButNotEnterEvent( event ) ) { + if ( api.utils.isKeydownButNotEnterEvent( event ) ) { return; } event.preventDefault(); // Keep this AFTER the key filter above @@ -1930,7 +1932,7 @@ if ( id && api[ type ]( id ) ) { instance = api[ type ]( id ); // Wait until the element is embedded in the DOM - instance.deferred.ready.done( function () { + instance.deferred.embedded.done( function () { // Wait until the preview has activated and so active panels, sections, controls have been set api.previewer.deferred.active.done( function () { instance.focus(); @@ -1956,7 +1958,7 @@ sectionContainers = _.pluck( sections, 'container' ); rootNodes.push( panel ); appendContainer = panel.container.find( 'ul:first' ); - if ( ! areElementListsEqual( sectionContainers, appendContainer.children( '[id]' ) ) ) { + if ( ! api.utils.areElementListsEqual( sectionContainers, appendContainer.children( '[id]' ) ) ) { _( sections ).each( function ( section ) { appendContainer.append( section.container ); } ); @@ -1972,7 +1974,7 @@ rootNodes.push( section ); } appendContainer = section.container.find( 'ul:first' ); - if ( ! areElementListsEqual( controlContainers, appendContainer.children( '[id]' ) ) ) { + if ( ! api.utils.areElementListsEqual( controlContainers, appendContainer.children( '[id]' ) ) ) { _( controls ).each( function ( control ) { appendContainer.append( control.container ); } ); @@ -1981,10 +1983,10 @@ } ); // Sort the root panels and sections - rootNodes.sort( prioritySort ); + rootNodes.sort( api.utils.prioritySort ); rootContainers = _.pluck( rootNodes, 'container' ); appendContainer = $( '#customize-theme-controls' ).children( 'ul' ); // @todo This should be defined elsewhere, and to be configurable - if ( ! areElementListsEqual( rootContainers, appendContainer.children() ) ) { + if ( ! api.utils.areElementListsEqual( rootContainers, appendContainer.children() ) ) { _( rootNodes ).each( function ( rootNode ) { appendContainer.append( rootNode.container ); } ); @@ -2080,7 +2082,7 @@ // Go back to the top-level Customizer accordion. $( '#customize-header-actions' ).on( 'click keydown', '.control-panel-back', function( event ) { - if ( isKeydownButNotEnterEvent( event ) ) { + if ( api.utils.isKeydownButNotEnterEvent( event ) ) { return; } @@ -2099,7 +2101,7 @@ }); $('.collapse-sidebar').on( 'click keydown', function( event ) { - if ( isKeydownButNotEnterEvent( event ) ) { + if ( api.utils.isKeydownButNotEnterEvent( event ) ) { return; } diff --git a/wp-admin/js/customize-controls.min.js b/wp-admin/js/customize-controls.min.js index a3c1d2faab..b7a88ff1a2 100644 --- a/wp-admin/js/customize-controls.min.js +++ b/wp-admin/js/customize-controls.min.js @@ -1 +1 @@ -!function(a,b){var c,d,e,f,g,h,i=wp.customize;i.Setting=i.Value.extend({initialize:function(a,b,c){i.Value.prototype.initialize.call(this,b,c),this.id=a,this.transport=this.transport||"refresh",this.bind(this.preview)},preview:function(){switch(this.transport){case"refresh":return this.previewer.refresh();case"postMessage":return this.previewer.send("setting",[this.id,this()])}}}),c=function(a,c){b.each(c,function(b,c){a[c].bind(function(b,c){a.parent&&b!==c&&a.parent.trigger("change",a)})})},e=function(a){var b,c,d;b=this,a=a||{},d=function(){b.container.find(":focusable:first").focus(),b.container[0].scrollIntoView(!0)},a.completeCallback?(c=a.completeCallback,a.completeCallback=function(){d(),c()}):a.completeCallback=d,b.expand?b.expand(a):a.completeCallback()},h=function(a,b){return a.priority()===b.priority()&&"number"==typeof a.params.instanceNumber&&"number"==typeof b.params.instanceNumber?a.params.instanceNumber-b.params.instanceNumber:a.priority()-b.priority()},f=function(a){return"keydown"===a.type&&13!==a.which},g=function(a,c){var d=a.length===c.length&&-1===_.map(_.zip(a,c),function(a){return b(a[0]).is(a[1])}).indexOf(!1);return d},d=i.Class.extend({defaultActiveArguments:{duration:"fast",completeCallback:b.noop},defaultExpandedArguments:{duration:"fast",completeCallback:b.noop},initialize:function(a,d){var e=this;e.id=a,e.params={},b.extend(e,d||{}),e.container=b(e.params.content),e.deferred={ready:new b.Deferred},e.priority=new i.Value,e.active=new i.Value,e.activeArgumentsQueue=[],e.expanded=new i.Value,e.expandedArgumentsQueue=[],e.active.bind(function(a){var c=e.activeArgumentsQueue.shift();c=b.extend({},e.defaultActiveArguments,c),a=a&&e.isContextuallyActive(),e.onChangeActive(a,c)}),e.expanded.bind(function(a){var c=e.expandedArgumentsQueue.shift();c=b.extend({},e.defaultExpandedArguments,c),e.onChangeExpanded(a,c)}),e.attachEvents(),c(e,["priority","active"]),e.priority.set(isNaN(e.params.priority)?100:e.params.priority),e.active.set(e.params.active),e.expanded.set(!1)},ready:function(){},_children:function(a,b){var c=this,d=[];return i[b].each(function(b){b[a].get()===c.id&&d.push(b)}),d.sort(h),d},isContextuallyActive:function(){throw new Error("Must override with subclass.")},onChangeActive:function(a,c){var d="resolved"===i.previewer.deferred.active.state()?c.duration:0;b.contains(document,this.container)?a?this.container.stop(!0,!0).slideDown(d,c.completeCallback):this.container.stop(!0,!0).slideUp(d,c.completeCallback):(this.container.toggle(a),c.completeCallback())},_toggleActive:function(a,b){var c=this;return b=b||{},a&&this.active.get()||!a&&!this.active.get()?(b.unchanged=!0,c.onChangeActive(c.active.get(),b),!1):(b.unchanged=!1,this.activeArgumentsQueue.push(b),this.active.set(a),!0)},activate:function(a){return this._toggleActive(!0,a)},deactivate:function(a){return this._toggleActive(!1,a)},onChangeExpanded:function(){throw new Error("Must override with subclass.")},_toggleExpanded:function(a,b){var c=this;return b=b||{},a&&this.expanded.get()||!a&&!this.expanded.get()?(b.unchanged=!0,c.onChangeExpanded(c.expanded.get(),b),!1):(b.unchanged=!1,this.expandedArgumentsQueue.push(b),this.expanded.set(a),!0)},expand:function(a){return this._toggleExpanded(!0,a)},collapse:function(a){return this._toggleExpanded(!1,a)},focus:e}),i.Section=d.extend({initialize:function(a,e){var f=this;d.prototype.initialize.call(f,a,e),f.id=a,f.panel=new i.Value,f.panel.bind(function(a){b(f.container).toggleClass("control-subsection",!!a)}),f.panel.set(f.params.panel||""),c(f,["panel"]),f.embed(),f.deferred.ready.done(function(){f.ready()})},embed:function(){var a,c=this;a=function(a){var d;a?i.panel(a,function(a){a.deferred.ready.done(function(){d=a.container.find("ul:first"),c.container.parent().is(d)||d.append(c.container),c.deferred.ready.resolve()})}):(d=b("#customize-theme-controls").children("ul"),c.container.parent().is(d)||d.append(c.container),c.deferred.ready.resolve())},c.panel.bind(a),a(c.panel.get())},attachEvents:function(){var a=this;a.container.find(".accordion-section-title").on("click keydown",function(b){f(b)||(b.preventDefault(),a.expanded()?a.collapse():a.expand())})},isContextuallyActive:function(){var a=this,b=a.controls(),c=0;return _(b).each(function(a){a.active()&&(c+=1)}),0!==c},controls:function(){return this._children("section","control")},onChangeExpanded:function(a,b){var c,d=this,e=d.container.find(".accordion-section-content");a?(c=b.unchanged?b.completeCallback:function(){e.stop().slideDown(b.duration,b.completeCallback),d.container.addClass("open")},b.allowMultiple||i.section.each(function(a){a!==d&&a.collapse({duration:b.duration})}),d.panel()?i.panel(d.panel()).expand({duration:b.duration,completeCallback:c}):c()):(d.container.removeClass("open"),e.slideUp(b.duration,b.completeCallback))}}),i.Panel=d.extend({initialize:function(a,b){var c=this;d.prototype.initialize.call(c,a,b),c.embed(),c.deferred.ready.done(function(){c.ready()})},embed:function(){var a=this,c=b("#customize-theme-controls > ul");a.container.parent().is(c)||c.append(a.container),a.deferred.ready.resolve()},attachEvents:function(){var a,b=this;b.container.find(".accordion-section-title").on("click keydown",function(a){f(a)||(a.preventDefault(),b.expanded()||b.expand())}),a=b.container.find(".panel-meta:first"),a.find("> .accordion-section-title").on("click keydown",function(c){if(!f(c)&&(c.preventDefault(),!a.hasClass("cannot-expand"))){var d=a.find(".accordion-section-content:first");a.hasClass("open")?(a.toggleClass("open"),d.slideUp(b.defaultExpandedArguments.duration)):(d.slideDown(b.defaultExpandedArguments.duration),a.toggleClass("open"))}})},sections:function(){return this._children("panel","section")},isContextuallyActive:function(){var a=this,b=a.sections(),c=0;return _(b).each(function(a){a.active()&&a.isContextuallyActive()&&(c+=1)}),0!==c},onChangeExpanded:function(a,b){if(b.unchanged)return void(b.completeCallback&&b.completeCallback());var c,d,e=this,f=e.container.closest(".accordion-section"),g=f.closest(".wp-full-overlay"),h=f.closest(".accordion-container"),j=h.find(".open"),k=g.find("#customize-theme-controls > ul > .accordion-section > .accordion-section-title").add("#customize-info > .accordion-section-title"),l=g.find(".control-panel-back"),m=f.find(".accordion-section-title").first(),n=f.find(".control-panel-content");a?(i.section.each(function(a){a.panel()||a.collapse({duration:0})}),i.panel.each(function(a){e!==a&&a.collapse({duration:0})}),n.show(0,function(){c=n.offset().top,d=h.scrollTop(),n.css("margin-top",45-c-d),f.addClass("current-panel"),g.addClass("in-sub-panel"),h.scrollTop(0),b.completeCallback&&b.completeCallback()}),k.attr("tabindex","-1"),l.attr("tabindex","0"),l.focus()):(j.removeClass("open"),f.removeClass("current-panel"),g.removeClass("in-sub-panel"),n.delay(180).hide(0,function(){n.css("margin-top","inherit"),b.completeCallback&&b.completeCallback()}),k.attr("tabindex","0"),l.attr("tabindex","-1"),m.focus(),h.scrollTop(0))}}),i.Control=i.Class.extend({defaultActiveArguments:{duration:"fast",completeCallback:b.noop},initialize:function(a,d){var e,f,g,h=this;h.params={},b.extend(h,d||{}),h.id=a,h.selector="#customize-control-"+a.replace(/\]/g,"").replace(/\[/g,"-"),h.templateSelector="customize-control-"+h.params.type+"-content",h.container=b(h.params.content?h.params.content:h.selector),h.deferred={ready:new b.Deferred},h.section=new i.Value,h.priority=new i.Value,h.active=new i.Value,h.activeArgumentsQueue=[],h.elements=[],e=h.container.find("[data-customize-setting-link]"),f={},e.each(function(){var a,c=b(this);if(c.is(":radio")){if(a=c.prop("name"),f[a])return;f[a]=!0,c=e.filter('[name="'+a+'"]')}i(c.data("customizeSettingLink"),function(a){var b=new i.Element(c);h.elements.push(b),b.sync(a),b.set(a())})}),h.active.bind(function(a){var c=h.activeArgumentsQueue.shift();c=b.extend({},h.defaultActiveArguments,c),h.onChangeActive(a,c)}),h.section.set(h.params.section),h.priority.set(isNaN(h.params.priority)?10:h.params.priority),h.active.set(h.params.active),c(h,["section","priority","active"]),g=b.map(h.params.settings,function(a){return a}),i.apply(i,g.concat(function(){var a;h.settings={};for(a in h.params.settings)h.settings[a]=i(h.params.settings[a]);h.setting=h.settings["default"]||null,h.embed()})),h.deferred.ready.done(function(){h.ready()})},embed:function(){var a,b=this;a=function(a){var c;a&&i.section(a,function(a){a.deferred.ready.done(function(){c=a.container.find("ul:first"),b.container.parent().is(c)||(c.append(b.container),b.renderContent()),b.deferred.ready.resolve()})})},b.section.bind(a),a(b.section.get())},ready:function(){},expand:function(a){i.section(this.section()).expand(a)},focus:e,onChangeActive:function(a,c){b.contains(document,this.container)?a?this.container.slideDown(c.duration,c.completeCallback):this.container.slideUp(c.duration,c.completeCallback):(this.container.toggle(a),c.completeCallback())},toggle:function(a){return this.onChangeActive(a,this.defaultActiveArguments)},activate:d.prototype.activate,deactivate:d.prototype.deactivate,dropdownInit:function(){var a=this,b=this.container.find(".dropdown-status"),c=this.params,d=!1,e=function(a){"string"==typeof a&&c.statuses&&c.statuses[a]?b.html(c.statuses[a]).show():b.hide()};this.container.on("click keydown",".dropdown",function(b){f(b)||(b.preventDefault(),d||a.container.toggleClass("open"),a.container.hasClass("open")&&a.container.parent().parent().find("li.library-selected").focus(),d=!0,setTimeout(function(){d=!1},400))}),this.setting.bind(e),e(this.setting())},renderContent:function(){var a,c=this;0!==b("#tmpl-"+c.templateSelector).length&&(a=wp.template(c.templateSelector),a&&c.container&&c.container.html(a(c.params)))}}),i.ColorControl=i.Control.extend({ready:function(){var a=this,b=this.container.find(".color-picker-hex");b.val(a.setting()).wpColorPicker({change:function(){a.setting.set(b.wpColorPicker("color"))},clear:function(){a.setting.set(!1)}}),this.setting.bind(function(a){b.val(a),b.wpColorPicker("color",a)})}}),i.UploadControl=i.Control.extend({ready:function(){var a=this;_.bindAll(a,"restoreDefault","removeFile","openFrame","select"),a.container.on("click keydown",".upload-button",a.openFrame),a.container.on("click keydown",".thumbnail-image img",a.openFrame),a.container.on("click keydown",".default-button",a.restoreDefault),a.container.on("click keydown",".remove-button",a.removeFile),a.setting.bind(function(){a.renderContent()})},openFrame:function(a){("keydown"!==a.type||13===a.which)&&(a.preventDefault(),this.frame||this.initFrame(),this.frame.open())},initFrame:function(){this.frame=wp.media({title:this.params.button_labels.frame_title,library:{type:this.params.mime_type},button:{text:this.params.button_labels.frame_button},multiple:!1}),this.frame.on("select",this.select)},select:function(){var a=this.frame.state().get("selection").first().toJSON();this.params.attachment=a,this.setting(a.url)},restoreDefault:function(a){("keydown"!==a.type||13===a.which)&&(a.preventDefault(),this.params.attachment=this.params.defaultAttachment,this.setting(this.params.defaultAttachment.url))},removeFile:function(a){("keydown"!==a.type||13===a.which)&&(a.preventDefault(),this.params.attachment={},this.setting(""),this.renderContent())},success:function(){},removerVisibility:function(){}}),i.ImageControl=i.UploadControl.extend({thumbnailSrc:function(){}}),i.HeaderControl=i.Control.extend({ready:function(){this.btnRemove=b("#customize-control-header_image .actions .remove"),this.btnNew=b("#customize-control-header_image .actions .new"),_.bindAll(this,"openMedia","removeImage"),this.btnNew.on("click",this.openMedia),this.btnRemove.on("click",this.removeImage),i.HeaderTool.currentHeader=new i.HeaderTool.ImageModel,new i.HeaderTool.CurrentView({model:i.HeaderTool.currentHeader,el:"#customize-control-header_image .current .container"}),new i.HeaderTool.ChoiceListView({collection:i.HeaderTool.UploadsList=new i.HeaderTool.ChoiceList,el:"#customize-control-header_image .choices .uploaded .list"}),new i.HeaderTool.ChoiceListView({collection:i.HeaderTool.DefaultsList=new i.HeaderTool.DefaultsList,el:"#customize-control-header_image .choices .default .list"}),i.HeaderTool.combinedList=i.HeaderTool.CombinedList=new i.HeaderTool.CombinedList([i.HeaderTool.UploadsList,i.HeaderTool.DefaultsList])},calculateImageSelectOptions:function(a,b){var c,d,e,f,g,h,j=parseInt(_wpCustomizeHeader.data.width,10),k=parseInt(_wpCustomizeHeader.data.height,10),l=!!parseInt(_wpCustomizeHeader.data["flex-width"],10),m=!!parseInt(_wpCustomizeHeader.data["flex-height"],10);return g=a.get("width"),f=a.get("height"),this.headerImage=new i.HeaderTool.ImageModel,this.headerImage.set({themeWidth:j,themeHeight:k,themeFlexWidth:l,themeFlexHeight:m,imageWidth:g,imageHeight:f}),b.set("canSkipCrop",!this.headerImage.shouldBeCropped()),c=j/k,d=g,e=f,d/e>c?(k=e,j=k*c):(j=d,k=j/c),h={handles:!0,keys:!0,instance:!0,persistent:!0,imageWidth:g,imageHeight:f,x1:0,y1:0,x2:j,y2:k},m===!1&&l===!1&&(h.aspectRatio=j+":"+k),m===!1&&(h.maxHeight=k),l===!1&&(h.maxWidth=j),h},openMedia:function(a){var b=_wpMediaViewsL10n;a.preventDefault(),this.frame=wp.media({button:{text:b.selectAndCrop,close:!1},states:[new wp.media.controller.Library({title:b.chooseImage,library:wp.media.query({type:"image"}),multiple:!1,priority:20,suggestedWidth:_wpCustomizeHeader.data.width,suggestedHeight:_wpCustomizeHeader.data.height}),new wp.media.controller.Cropper({imgSelectOptions:this.calculateImageSelectOptions})]}),this.frame.on("select",this.onSelect,this),this.frame.on("cropped",this.onCropped,this),this.frame.on("skippedcrop",this.onSkippedCrop,this),this.frame.open()},onSelect:function(){this.frame.setState("cropper")},onCropped:function(a){var b=a.post_content,c=a.attachment_id,d=a.width,e=a.height;this.setImageFromURL(b,c,d,e)},onSkippedCrop:function(a){var b=a.get("url"),c=a.get("width"),d=a.get("height");this.setImageFromURL(b,a.id,c,d)},setImageFromURL:function(a,b,c,d){var e,f={};f.url=a,f.thumbnail_url=a,f.timestamp=_.now(),b&&(f.attachment_id=b),c&&(f.width=c),d&&(f.height=d),e=new i.HeaderTool.ImageModel({header:f,choice:a.split("/").pop()}),i.HeaderTool.UploadsList.add(e),i.HeaderTool.currentHeader.set(e.toJSON()),e.save(),e.importImage()},removeImage:function(){i.HeaderTool.currentHeader.trigger("hide"),i.HeaderTool.CombinedList.trigger("control:removeImage")}}),i.defaultConstructor=i.Setting,i.control=new i.Values({defaultConstructor:i.Control}),i.section=new i.Values({defaultConstructor:i.Section}),i.panel=new i.Values({defaultConstructor:i.Panel}),i.PreviewFrame=i.Messenger.extend({sensitivity:2e3,initialize:function(a,c){var d=b.Deferred();d.promise(this),this.container=a.container,this.signature=a.signature,b.extend(a,{channel:i.PreviewFrame.uuid()}),i.Messenger.prototype.initialize.call(this,a,c),this.add("previewUrl",a.previewUrl),this.query=b.extend(a.query||{},{customize_messenger_channel:this.channel()}),this.run(d)},run:function(a){var c=this,d=!1,e=!1;this._ready&&this.unbind("ready",this._ready),this._ready=function(){e=!0,d&&a.resolveWith(c)},this.bind("ready",this._ready),this.bind("ready",function(a){if(a){var b={panel:a.activePanels,section:a.activeSections,control:a.activeControls};_(b).each(function(a,b){i[b].each(function(b,c){var d=!(!a||!a[c]);b.active(d)})})}}),this.request=b.ajax(this.previewUrl(),{type:"POST",data:this.query,xhrFields:{withCredentials:!0}}),this.request.fail(function(){a.rejectWith(c,["request failure"])}),this.request.done(function(f){var g,h=c.request.getResponseHeader("Location"),i=c.signature;return h&&h!==c.previewUrl()?void a.rejectWith(c,["redirect",h]):"0"===f?void c.login(a):"-1"===f?void a.rejectWith(c,["cheatin"]):(g=f.lastIndexOf(i),-1===g||g")?void a.rejectWith(c,["unsigned"]):(f=f.slice(0,g)+f.slice(g+i.length),c.iframe=b("