1528 if ( section.container.hasClass( 'cannot-expand' ) ) { |
1528 if ( section.container.hasClass( 'cannot-expand' ) ) { |
1529 return; |
1529 return; |
1530 } |
1530 } |
1531 |
1531 |
1532 // Expand/Collapse accordion sections on click. |
1532 // Expand/Collapse accordion sections on click. |
1533 section.container.find( '.accordion-section-title, .customize-section-back' ).on( 'click keydown', function( event ) { |
1533 section.container.find( '.accordion-section-title button, .customize-section-back, .accordion-section-title[tabindex]' ).on( 'click keydown', function( event ) { |
1534 if ( api.utils.isKeydownButNotEnterEvent( event ) ) { |
1534 if ( api.utils.isKeydownButNotEnterEvent( event ) ) { |
1535 return; |
1535 return; |
1536 } |
1536 } |
1537 event.preventDefault(); // Keep this AFTER the key filter above. |
1537 event.preventDefault(); // Keep this AFTER the key filter above. |
1538 |
1538 |
1603 var section = this, |
1603 var section = this, |
1604 container = section.headContainer.closest( '.wp-full-overlay-sidebar-content' ), |
1604 container = section.headContainer.closest( '.wp-full-overlay-sidebar-content' ), |
1605 content = section.contentContainer, |
1605 content = section.contentContainer, |
1606 overlay = section.headContainer.closest( '.wp-full-overlay' ), |
1606 overlay = section.headContainer.closest( '.wp-full-overlay' ), |
1607 backBtn = content.find( '.customize-section-back' ), |
1607 backBtn = content.find( '.customize-section-back' ), |
1608 sectionTitle = section.headContainer.find( '.accordion-section-title' ).first(), |
1608 sectionTitle = section.headContainer.find( '.accordion-section-title button, .accordion-section-title[tabindex]' ).first(), |
1609 expand, panel; |
1609 expand, panel; |
1610 |
1610 |
1611 if ( expanded && ! content.hasClass( 'open' ) ) { |
1611 if ( expanded && ! content.hasClass( 'open' ) ) { |
1612 |
1612 |
1613 if ( args.unchanged ) { |
1613 if ( args.unchanged ) { |
1614 expand = args.completeCallback; |
1614 expand = args.completeCallback; |
1615 } else { |
1615 } else { |
1616 expand = function() { |
1616 expand = function() { |
1617 section._animateChangeExpanded( function() { |
1617 section._animateChangeExpanded( function() { |
1618 sectionTitle.attr( 'tabindex', '-1' ); |
|
1619 backBtn.attr( 'tabindex', '0' ); |
|
1620 |
|
1621 backBtn.trigger( 'focus' ); |
1618 backBtn.trigger( 'focus' ); |
1622 content.css( 'top', '' ); |
1619 content.css( 'top', '' ); |
1623 container.scrollTop( 0 ); |
1620 container.scrollTop( 0 ); |
1624 |
1621 |
1625 if ( args.completeCallback ) { |
1622 if ( args.completeCallback ) { |
1661 if ( panel.contentContainer.hasClass( 'skip-transition' ) ) { |
1658 if ( panel.contentContainer.hasClass( 'skip-transition' ) ) { |
1662 panel.collapse(); |
1659 panel.collapse(); |
1663 } |
1660 } |
1664 } |
1661 } |
1665 section._animateChangeExpanded( function() { |
1662 section._animateChangeExpanded( function() { |
1666 backBtn.attr( 'tabindex', '-1' ); |
|
1667 sectionTitle.attr( 'tabindex', '0' ); |
|
1668 |
1663 |
1669 sectionTitle.trigger( 'focus' ); |
1664 sectionTitle.trigger( 'focus' ); |
1670 content.css( 'top', '' ); |
1665 content.css( 'top', '' ); |
1671 |
1666 |
1672 if ( args.completeCallback ) { |
1667 if ( args.completeCallback ) { |
2697 onChangeExpanded: function( expanded, args ) { |
2692 onChangeExpanded: function( expanded, args ) { |
2698 var section = this, |
2693 var section = this, |
2699 container = section.headContainer.closest( '.wp-full-overlay-sidebar-content' ), |
2694 container = section.headContainer.closest( '.wp-full-overlay-sidebar-content' ), |
2700 content = section.contentContainer, |
2695 content = section.contentContainer, |
2701 backBtn = content.find( '.customize-section-back' ), |
2696 backBtn = content.find( '.customize-section-back' ), |
2702 sectionTitle = section.headContainer.find( '.accordion-section-title' ).first(), |
2697 sectionTitle = section.headContainer.find( '.accordion-section-title button, .accordion-section-title[tabindex]' ).first(), |
2703 body = $( document.body ), |
2698 body = $( document.body ), |
2704 expand, panel; |
2699 expand, panel; |
2705 |
2700 |
2706 body.toggleClass( 'outer-section-open', expanded ); |
2701 body.toggleClass( 'outer-section-open', expanded ); |
2707 section.container.toggleClass( 'open', expanded ); |
2702 section.container.toggleClass( 'open', expanded ); |
2717 if ( args.unchanged ) { |
2712 if ( args.unchanged ) { |
2718 expand = args.completeCallback; |
2713 expand = args.completeCallback; |
2719 } else { |
2714 } else { |
2720 expand = function() { |
2715 expand = function() { |
2721 section._animateChangeExpanded( function() { |
2716 section._animateChangeExpanded( function() { |
2722 sectionTitle.attr( 'tabindex', '-1' ); |
|
2723 backBtn.attr( 'tabindex', '0' ); |
|
2724 |
|
2725 backBtn.trigger( 'focus' ); |
2717 backBtn.trigger( 'focus' ); |
2726 content.css( 'top', '' ); |
2718 content.css( 'top', '' ); |
2727 container.scrollTop( 0 ); |
2719 container.scrollTop( 0 ); |
2728 |
2720 |
2729 if ( args.completeCallback ) { |
2721 if ( args.completeCallback ) { |
2750 if ( panel.contentContainer.hasClass( 'skip-transition' ) ) { |
2742 if ( panel.contentContainer.hasClass( 'skip-transition' ) ) { |
2751 panel.collapse(); |
2743 panel.collapse(); |
2752 } |
2744 } |
2753 } |
2745 } |
2754 section._animateChangeExpanded( function() { |
2746 section._animateChangeExpanded( function() { |
2755 backBtn.attr( 'tabindex', '-1' ); |
|
2756 sectionTitle.attr( 'tabindex', '0' ); |
|
2757 |
2747 |
2758 sectionTitle.trigger( 'focus' ); |
2748 sectionTitle.trigger( 'focus' ); |
2759 content.css( 'top', '' ); |
2749 content.css( 'top', '' ); |
2760 |
2750 |
2761 if ( args.completeCallback ) { |
2751 if ( args.completeCallback ) { |
2841 */ |
2831 */ |
2842 attachEvents: function () { |
2832 attachEvents: function () { |
2843 var meta, panel = this; |
2833 var meta, panel = this; |
2844 |
2834 |
2845 // Expand/Collapse accordion sections on click. |
2835 // Expand/Collapse accordion sections on click. |
2846 panel.headContainer.find( '.accordion-section-title' ).on( 'click keydown', function( event ) { |
2836 panel.headContainer.find( '.accordion-section-title button, .accordion-section-title[tabindex]' ).on( 'click keydown', function( event ) { |
2847 if ( api.utils.isKeydownButNotEnterEvent( event ) ) { |
2837 if ( api.utils.isKeydownButNotEnterEvent( event ) ) { |
2848 return; |
2838 return; |
2849 } |
2839 } |
2850 event.preventDefault(); // Keep this AFTER the key filter above. |
2840 event.preventDefault(); // Keep this AFTER the key filter above. |
2851 |
2841 |
2945 // Note: there is a second argument 'args' passed. |
2935 // Note: there is a second argument 'args' passed. |
2946 var panel = this, |
2936 var panel = this, |
2947 accordionSection = panel.contentContainer, |
2937 accordionSection = panel.contentContainer, |
2948 overlay = accordionSection.closest( '.wp-full-overlay' ), |
2938 overlay = accordionSection.closest( '.wp-full-overlay' ), |
2949 container = accordionSection.closest( '.wp-full-overlay-sidebar-content' ), |
2939 container = accordionSection.closest( '.wp-full-overlay-sidebar-content' ), |
2950 topPanel = panel.headContainer.find( '.accordion-section-title' ), |
2940 topPanel = panel.headContainer.find( '.accordion-section-title button, .accordion-section-title[tabindex]' ), |
2951 backBtn = accordionSection.find( '.customize-panel-back' ), |
2941 backBtn = accordionSection.find( '.customize-panel-back' ), |
2952 childSections = panel.sections(), |
2942 childSections = panel.sections(), |
2953 skipTransition; |
2943 skipTransition; |
2954 |
2944 |
2955 if ( expanded && ! accordionSection.hasClass( 'current-panel' ) ) { |
2945 if ( expanded && ! accordionSection.hasClass( 'current-panel' ) ) { |
2972 childSections[0].expand( { |
2962 childSections[0].expand( { |
2973 completeCallback: args.completeCallback |
2963 completeCallback: args.completeCallback |
2974 } ); |
2964 } ); |
2975 } else { |
2965 } else { |
2976 panel._animateChangeExpanded( function() { |
2966 panel._animateChangeExpanded( function() { |
2977 topPanel.attr( 'tabindex', '-1' ); |
|
2978 backBtn.attr( 'tabindex', '0' ); |
|
2979 |
|
2980 backBtn.trigger( 'focus' ); |
2967 backBtn.trigger( 'focus' ); |
2981 accordionSection.css( 'top', '' ); |
2968 accordionSection.css( 'top', '' ); |
2982 container.scrollTop( 0 ); |
2969 container.scrollTop( 0 ); |
2983 |
2970 |
2984 if ( args.completeCallback ) { |
2971 if ( args.completeCallback ) { |
2994 |
2981 |
2995 } else if ( ! expanded && accordionSection.hasClass( 'current-panel' ) ) { |
2982 } else if ( ! expanded && accordionSection.hasClass( 'current-panel' ) ) { |
2996 skipTransition = accordionSection.hasClass( 'skip-transition' ); |
2983 skipTransition = accordionSection.hasClass( 'skip-transition' ); |
2997 if ( ! skipTransition ) { |
2984 if ( ! skipTransition ) { |
2998 panel._animateChangeExpanded( function() { |
2985 panel._animateChangeExpanded( function() { |
2999 topPanel.attr( 'tabindex', '0' ); |
|
3000 backBtn.attr( 'tabindex', '-1' ); |
|
3001 |
2986 |
3002 topPanel.focus(); |
2987 topPanel.focus(); |
3003 accordionSection.css( 'top', '' ); |
2988 accordionSection.css( 'top', '' ); |
3004 |
2989 |
3005 if ( args.completeCallback ) { |
2990 if ( args.completeCallback ) { |
4600 * @param {wp.media.model.Attachment} attachment |
4585 * @param {wp.media.model.Attachment} attachment |
4601 * @param {wp.media.controller.Cropper} controller |
4586 * @param {wp.media.controller.Cropper} controller |
4602 * @return {Object} Options |
4587 * @return {Object} Options |
4603 */ |
4588 */ |
4604 calculateImageSelectOptions: function( attachment, controller ) { |
4589 calculateImageSelectOptions: function( attachment, controller ) { |
4605 var control = controller.get( 'control' ), |
4590 var control = controller.get( 'control' ), |
4606 flexWidth = !! parseInt( control.params.flex_width, 10 ), |
4591 flexWidth = !! parseInt( control.params.flex_width, 10 ), |
4607 flexHeight = !! parseInt( control.params.flex_height, 10 ), |
4592 flexHeight = !! parseInt( control.params.flex_height, 10 ), |
4608 realWidth = attachment.get( 'width' ), |
4593 realWidth = attachment.get( 'width' ), |
4609 realHeight = attachment.get( 'height' ), |
4594 realHeight = attachment.get( 'height' ), |
4610 xInit = parseInt( control.params.width, 10 ), |
4595 xInit = parseInt( control.params.width, 10 ), |
4611 yInit = parseInt( control.params.height, 10 ), |
4596 yInit = parseInt( control.params.height, 10 ), |
4612 ratio = xInit / yInit, |
4597 requiredRatio = xInit / yInit, |
4613 xImg = xInit, |
4598 realRatio = realWidth / realHeight, |
4614 yImg = yInit, |
4599 xImg = xInit, |
|
4600 yImg = yInit, |
4615 x1, y1, imgSelectOptions; |
4601 x1, y1, imgSelectOptions; |
4616 |
4602 |
|
4603 controller.set( 'hasRequiredAspectRatio', control.hasRequiredAspectRatio( requiredRatio, realRatio ) ); |
|
4604 controller.set( 'suggestedCropSize', { width: realWidth, height: realHeight, x1: 0, y1: 0, x2: xInit, y2: yInit } ); |
4617 controller.set( 'canSkipCrop', ! control.mustBeCropped( flexWidth, flexHeight, xInit, yInit, realWidth, realHeight ) ); |
4605 controller.set( 'canSkipCrop', ! control.mustBeCropped( flexWidth, flexHeight, xInit, yInit, realWidth, realHeight ) ); |
4618 |
4606 |
4619 if ( realWidth / realHeight > ratio ) { |
4607 if ( realRatio > requiredRatio ) { |
4620 yInit = realHeight; |
4608 yInit = realHeight; |
4621 xInit = yInit * ratio; |
4609 xInit = yInit * requiredRatio; |
4622 } else { |
4610 } else { |
4623 xInit = realWidth; |
4611 xInit = realWidth; |
4624 yInit = xInit / ratio; |
4612 yInit = xInit / requiredRatio; |
4625 } |
4613 } |
4626 |
4614 |
4627 x1 = ( realWidth - xInit ) / 2; |
4615 x1 = ( realWidth - xInit ) / 2; |
4628 y1 = ( realHeight - yInit ) / 2; |
4616 y1 = ( realHeight - yInit ) / 2; |
4629 |
4617 |
4660 }, |
4648 }, |
4661 |
4649 |
4662 /** |
4650 /** |
4663 * Return whether the image must be cropped, based on required dimensions. |
4651 * Return whether the image must be cropped, based on required dimensions. |
4664 * |
4652 * |
4665 * @param {boolean} flexW |
4653 * @param {boolean} flexW Width is flexible. |
4666 * @param {boolean} flexH |
4654 * @param {boolean} flexH Height is flexible. |
4667 * @param {number} dstW |
4655 * @param {number} dstW Required width. |
4668 * @param {number} dstH |
4656 * @param {number} dstH Required height. |
4669 * @param {number} imgW |
4657 * @param {number} imgW Provided image's width. |
4670 * @param {number} imgH |
4658 * @param {number} imgH Provided image's height. |
4671 * @return {boolean} |
4659 * @return {boolean} Whether cropping is required. |
4672 */ |
4660 */ |
4673 mustBeCropped: function( flexW, flexH, dstW, dstH, imgW, imgH ) { |
4661 mustBeCropped: function( flexW, flexH, dstW, dstH, imgW, imgH ) { |
4674 if ( true === flexW && true === flexH ) { |
4662 if ( true === flexW && true === flexH ) { |
4675 return false; |
4663 return false; |
4676 } |
4664 } |
4690 if ( imgW <= dstW ) { |
4678 if ( imgW <= dstW ) { |
4691 return false; |
4679 return false; |
4692 } |
4680 } |
4693 |
4681 |
4694 return true; |
4682 return true; |
|
4683 }, |
|
4684 |
|
4685 /** |
|
4686 * Check if the image's aspect ratio essentially matches the required aspect ratio. |
|
4687 * |
|
4688 * Floating point precision is low, so this allows a small tolerance. This |
|
4689 * tolerance allows for images over 100,000 px on either side to still trigger |
|
4690 * the cropping flow. |
|
4691 * |
|
4692 * @param {number} requiredRatio Required image ratio. |
|
4693 * @param {number} realRatio Provided image ratio. |
|
4694 * @return {boolean} Whether the image has the required aspect ratio. |
|
4695 */ |
|
4696 hasRequiredAspectRatio: function ( requiredRatio, realRatio ) { |
|
4697 if ( Math.abs( requiredRatio - realRatio ) < 0.000001 ) { |
|
4698 return true; |
|
4699 } |
|
4700 |
|
4701 return false; |
4695 }, |
4702 }, |
4696 |
4703 |
4697 /** |
4704 /** |
4698 * If cropping was skipped, apply the image data directly to the setting. |
4705 * If cropping was skipped, apply the image data directly to the setting. |
4699 */ |
4706 */ |